Merge FFMpeg for M33.
Merged from 9186343787c9fe2af1a3b0350ac556508dfbaaf6.
Conflicts:
configure
libavcodec/mpeg4video_parser.c
diff --git a/.gitignore b/.gitignore
index 0dada46..dafce52 100644
--- a/.gitignore
+++ b/.gitignore
@@ -27,7 +27,6 @@
/ffserver
/config.*
/coverage.info
-/version.h
/doc/*.1
/doc/*.3
/doc/*.html
@@ -36,7 +35,7 @@
/doc/avoptions_codec.texi
/doc/avoptions_format.texi
/doc/examples/decoding_encoding
-/doc/examples/demuxing
+/doc/examples/demuxing_decoding
/doc/examples/filtering_audio
/doc/examples/filtering_video
/doc/examples/metadata
@@ -44,14 +43,18 @@
/doc/examples/pc-uninstalled
/doc/examples/resampling_audio
/doc/examples/scaling_video
+/doc/examples/transcode_aac
/doc/fate.txt
/doc/doxy/html/
+/doc/examples/output
+/doc/examples/transcode_aac
/doc/print_options
/lcov/
/libavcodec/*_tablegen
/libavcodec/*_tables.c
/libavcodec/*_tables.h
/libavutil/avconfig.h
+/libavutil/ffversion.h
/tests/audiogen
/tests/base64
/tests/data/
diff --git a/Changelog b/Changelog
index ee58336..45c0ddc 100644
--- a/Changelog
+++ b/Changelog
@@ -3,6 +3,21 @@
version <next>
+- HNM version 4 demuxer and video decoder
+- Live HDS muxer
+- setsar/setdar filters now support variables in ratio expressions
+- elbg filter
+- string validation in ffprobe
+- support for decoding through VDPAU in ffmpeg (the -hwaccel option)
+- complete Voxware MetaSound decoder
+- remove mp3_header_compress bitstream filters
+- Windows resource files for shared libraries
+- aeval filter
+- stereoscopic 3d metadata handling
+
+
+version 2.1:
+
- aecho filter
- perspective filter ported from libmpcodecs
- ffprobe -show_programs option
@@ -40,6 +55,12 @@
- dpx parser
- max_error_rate parameter in ffmpeg
- PulseAudio output device
+- ReplayGain scanner
+- Enhanced Low Delay AAC (ER AAC ELD) decoding (no LD SBR support)
+- Linux framebuffer output device
+- HEVC decoder
+- raw HEVC, HEVC in MOV/MP4, HEVC in Matroska, HEVC in MPEG-TS demuxing
+- mergeplanes filter
version 2.0:
diff --git a/LICENSE b/LICENSE
index 6e56e3b..1840d69 100644
--- a/LICENSE
+++ b/LICENSE
@@ -36,7 +36,6 @@
- vf_kerndeint.c
- vf_mcdeint.c
- vf_mp.c
- - vf_noise.c
- vf_owdenoise.c
- vf_perspective.c
- vf_phase.c
diff --git a/MAINTAINERS b/MAINTAINERS
index 597dc95..847d1d6 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -43,7 +43,7 @@
Miscellaneous Areas
===================
-documentation Mike Melanson
+documentation Stefano Sabatini, Mike Melanson, Timothy Gu
build system (configure,Makefiles) Diego Biurrun, Mans Rullgard
project server Árpád Gereöffy, Michael Niedermayer, Reimar Döffinger, Alexander Strasser
presets Robert Swain
@@ -58,6 +58,7 @@
mailinglists Michael Niedermayer, Baptiste Coudurier, Lou Logan
Google+ Paul B Mahol, Michael Niedermayer, Alexander Strasser
Twitter Lou Logan
+Launchpad Timothy Gu
libavutil
@@ -196,8 +197,10 @@
libtheoraenc.c David Conrad
libutvideo* Derek Buitenhuis
libvorbis.c David Conrad
+ libvpx* James Zern
libx264.c Mans Rullgard, Jason Garrett-Glaser
libxavs.c Stefan Gehrer
+ libzvbi-teletextdec.c Marton Balint
loco.c Kostya Shishkov
lzo.h, lzo.c Reimar Doeffinger
mdec.c Michael Niedermayer
@@ -265,6 +268,7 @@
vp5 Aurelien Jacobs
vp6 Aurelien Jacobs
vp8 David Conrad, Jason Garrett-Glaser, Ronald Bultje
+ vp9 Ronald Bultje, Clément Bœsch
vqavideo.c Mike Melanson
wavpack.c Kostya Shishkov
wmaprodec.c Sascha Sommer
@@ -273,6 +277,7 @@
wnv1.c Kostya Shishkov
xan.c Mike Melanson
xbm* Paul B Mahol
+ xface Stefano Sabatini
xl.c Kostya Shishkov
xvmc.c Ivan Kalvachev
xwd* Paul B Mahol
@@ -295,9 +300,12 @@
dshow.c Roger Pack
+ fbdev_enc.c Lukasz Marek
iec61883.c Georg Lippitsch
+ lavfi Stefano Sabatini
libdc1394.c Roman Shaposhnik
pulse_audio_enc.c Lukasz Marek
+ sdl Stefano Sabatini
v4l2.c Luca Abeni
vfwcap.c Ramiro Polla
@@ -308,14 +316,33 @@
graphdump.c Nicolas George
Filters:
+ af_adelay.c Paul B Mahol
+ af_aecho.c Paul B Mahol
+ af_afade.c Paul B Mahol
af_amerge.c Nicolas George
+ af_aphaser.c Paul B Mahol
af_aresample.c Michael Niedermayer
+ af_astats.c Paul B Mahol
af_astreamsync.c Nicolas George
af_atempo.c Pavel Koshevoy
+ af_biquads.c Paul B Mahol
+ af_compand.c Paul B Mahol
+ af_ladspa.c Paul B Mahol
af_pan.c Nicolas George
+ avf_avectorscope.c Paul B Mahol
+ vf_blend.c Paul B Mahol
+ vf_colorbalance.c Paul B Mahol
vf_delogo.c Jean Delvare (CC <khali@linux-fr.org>)
vf_drawbox.c/drawgrid Andrey Utkin
+ vf_extractplanes.c Paul B Mahol
+ vf_histogram.c Paul B Mahol
+ vf_il.c Paul B Mahol
+ vf_mergeplanes.c Paul B Mahol
+ vf_psnr.c Paul B Mahol
vf_scale.c Michael Niedermayer
+ vf_separatefields.c Paul B Mahol
+ vf_stereo3d.c Paul B Mahol
+ vf_telecine.c Paul B Mahol
vf_yadif.c Michael Niedermayer
Sources:
@@ -477,6 +504,7 @@
Releases
========
+2.1 Michael Niedermayer
2.0 Michael Niedermayer
1.2 Michael Niedermayer
diff --git a/Makefile b/Makefile
index 46d4d52..7317f25 100644
--- a/Makefile
+++ b/Makefile
@@ -6,29 +6,34 @@
vpath %.h $(SRC_PATH)
vpath %.S $(SRC_PATH)
vpath %.asm $(SRC_PATH)
+vpath %.rc $(SRC_PATH)
vpath %.v $(SRC_PATH)
vpath %.texi $(SRC_PATH)
vpath %/fate_config.sh.template $(SRC_PATH)
-PROGS-$(CONFIG_FFMPEG) += ffmpeg
-PROGS-$(CONFIG_FFPLAY) += ffplay
-PROGS-$(CONFIG_FFPROBE) += ffprobe
-PROGS-$(CONFIG_FFSERVER) += ffserver
+AVPROGS-$(CONFIG_FFMPEG) += ffmpeg
+AVPROGS-$(CONFIG_FFPLAY) += ffplay
+AVPROGS-$(CONFIG_FFPROBE) += ffprobe
+AVPROGS-$(CONFIG_FFSERVER) += ffserver
-PROGS := $(PROGS-yes:%=%$(PROGSSUF)$(EXESUF))
-INSTPROGS = $(PROGS-yes:%=%$(PROGSSUF)$(EXESUF))
+AVPROGS := $(AVPROGS-yes:%=%$(PROGSSUF)$(EXESUF))
+INSTPROGS = $(AVPROGS-yes:%=%$(PROGSSUF)$(EXESUF))
+PROGS += $(AVPROGS)
-OBJS = cmdutils.o $(EXEOBJS)
-OBJS-ffmpeg = ffmpeg_opt.o ffmpeg_filter.o
+AVBASENAMES = ffmpeg ffplay ffprobe ffserver
+ALLAVPROGS = $(AVBASENAMES:%=%$(PROGSSUF)$(EXESUF))
+ALLAVPROGS_G = $(AVBASENAMES:%=%$(PROGSSUF)_g$(EXESUF))
+
+$(foreach prog,$(AVBASENAMES),$(eval OBJS-$(prog) += cmdutils.o))
+$(foreach prog,$(AVBASENAMES),$(eval OBJS-$(prog)-$(CONFIG_OPENCL) += cmdutils_opencl.o))
+
+OBJS-ffmpeg += ffmpeg_opt.o ffmpeg_filter.o
+OBJS-ffmpeg-$(HAVE_VDPAU_X11) += ffmpeg_vdpau.o
TESTTOOLS = audiogen videogen rotozoom tiny_psnr tiny_ssim base64
HOSTPROGS := $(TESTTOOLS:%=tests/%) doc/print_options
TOOLS = qt-faststart trasher
TOOLS-$(CONFIG_ZLIB) += cws2fws
-BASENAMES = ffmpeg ffplay ffprobe ffserver
-ALLPROGS = $(BASENAMES:%=%$(PROGSSUF)$(EXESUF))
-ALLPROGS_G = $(BASENAMES:%=%$(PROGSSUF)_g$(EXESUF))
-
FFLIBS-$(CONFIG_AVDEVICE) += avdevice
FFLIBS-$(CONFIG_AVFILTER) += avfilter
FFLIBS-$(CONFIG_AVFORMAT) += avformat
@@ -50,11 +55,7 @@
FF_EXTRALIBS := $(FFEXTRALIBS)
FF_DEP_LIBS := $(DEP_LIBS)
-all: $(PROGS)
-
-$(PROGS): %$(EXESUF): %_g$(EXESUF)
- $(CP) $< $@
- $(STRIP) $@
+all: $(AVPROGS)
$(TOOLS): %$(EXESUF): %.o $(EXEOBJS)
$(LD) $(LDFLAGS) $(LD_O) $^ $(ELIBS)
@@ -73,7 +74,7 @@
ALTIVEC-OBJS VIS-OBJS \
MMX-OBJS YASM-OBJS \
MIPSFPU-OBJS MIPSDSPR2-OBJS MIPSDSPR1-OBJS MIPS32R2-OBJS \
- OBJS HOSTOBJS TESTOBJS
+ OBJS SLIBOBJS HOSTOBJS TESTOBJS
define RESET
$(1) :=
@@ -90,8 +91,10 @@
$(foreach D,$(FFLIBS),$(eval $(call DOSUBDIR,lib$(D))))
+include $(SRC_PATH)/doc/Makefile
+
define DOPROG
-OBJS-$(1) += $(1).o cmdutils.o $(EXEOBJS)
+OBJS-$(1) += $(1).o $(EXEOBJS) $(OBJS-$(1)-yes)
$(1)$(PROGSSUF)_g$(EXESUF): $$(OBJS-$(1))
$$(OBJS-$(1)): CFLAGS += $(CFLAGS-$(1))
$(1)$(PROGSSUF)_g$(EXESUF): LDFLAGS += $(LDFLAGS-$(1))
@@ -99,7 +102,13 @@
-include $$(OBJS-$(1):.o=.d)
endef
-$(foreach P,$(PROGS-yes),$(eval $(call DOPROG,$(P))))
+$(foreach P,$(PROGS),$(eval $(call DOPROG,$(P:$(PROGSSUF)$(EXESUF)=))))
+
+ffprobe.o cmdutils.o : libavutil/ffversion.h
+
+$(PROGS): %$(PROGSSUF)$(EXESUF): %$(PROGSSUF)_g$(EXESUF)
+ $(CP) $< $@
+ $(STRIP) $@
%$(PROGSSUF)_g$(EXESUF): %.o $(FF_DEP_LIBS)
$(LD) $(LDFLAGS) $(LD_O) $(OBJS-$*) $(FF_EXTRALIBS)
@@ -114,14 +123,14 @@
.version: $(wildcard $(GIT_LOG)) $(VERSION_SH) config.mak
.version: M=@
-version.h .version:
- $(M)$(VERSION_SH) $(SRC_PATH) version.h $(EXTRA_VERSION)
+libavutil/ffversion.h .version:
+ $(M)$(VERSION_SH) $(SRC_PATH) libavutil/ffversion.h $(EXTRA_VERSION)
$(Q)touch .version
# force version.sh to run whenever version might have changed
-include .version
-ifdef PROGS
+ifdef AVPROGS
install: install-progs install-data
endif
@@ -132,7 +141,7 @@
install-progs-yes:
install-progs-$(CONFIG_SHARED): install-libs
-install-progs: install-progs-yes $(PROGS)
+install-progs: install-progs-yes $(AVPROGS)
$(Q)mkdir -p "$(BINDIR)"
$(INSTALL) -c -m 755 $(INSTPROGS) "$(BINDIR)"
@@ -144,13 +153,13 @@
uninstall: uninstall-libs uninstall-headers uninstall-progs uninstall-data
uninstall-progs:
- $(RM) $(addprefix "$(BINDIR)/", $(ALLPROGS))
+ $(RM) $(addprefix "$(BINDIR)/", $(ALLAVPROGS))
uninstall-data:
$(RM) -r "$(DATADIR)"
clean::
- $(RM) $(ALLPROGS) $(ALLPROGS_G)
+ $(RM) $(ALLAVPROGS) $(ALLAVPROGS_G)
$(RM) $(CLEANSUFFIXES)
$(RM) $(CLEANSUFFIXES:%=tools/%)
$(RM) -r coverage-html
@@ -158,14 +167,13 @@
distclean::
$(RM) $(DISTCLEANSUFFIXES)
- $(RM) config.* .config libavutil/avconfig.h .version version.h libavcodec/codec_names.h
+ $(RM) config.* .config libavutil/avconfig.h .version version.h libavutil/ffversion.h libavcodec/codec_names.h
config:
$(SRC_PATH)/configure $(value FFMPEG_CONFIGURATION)
check: all alltools examples testprogs fate
-include $(SRC_PATH)/doc/Makefile
include $(SRC_PATH)/tests/Makefile
$(sort $(OBJDIRS)):
diff --git a/RELEASE b/RELEASE
index cd5ac03..7f9e2dc 100644
--- a/RELEASE
+++ b/RELEASE
@@ -1 +1 @@
-2.0
+2.1.git
diff --git a/cmdutils.c b/cmdutils.c
index aea02c0..fc4b424 100644
--- a/cmdutils.c
+++ b/cmdutils.c
@@ -20,6 +20,7 @@
*/
#include <string.h>
+#include <stdint.h>
#include <stdlib.h>
#include <errno.h>
#include <math.h>
@@ -47,8 +48,9 @@
#include "libavutil/eval.h"
#include "libavutil/dict.h"
#include "libavutil/opt.h"
+#include "libavutil/cpu.h"
+#include "libavutil/ffversion.h"
#include "cmdutils.h"
-#include "version.h"
#if CONFIG_NETWORK
#include "libavformat/network.h"
#endif
@@ -56,10 +58,6 @@
#include <sys/time.h>
#include <sys/resource.h>
#endif
-#if CONFIG_OPENCL
-#include "libavutil/opencl.h"
-#endif
-
static int init_report(const char *env);
@@ -67,8 +65,6 @@
AVDictionary *swr_opts;
AVDictionary *format_opts, *codec_opts, *resample_opts;
-const int this_year = 2013;
-
static FILE *report_file;
void init_opts(void)
@@ -808,6 +804,18 @@
return 0;
}
+int opt_cpuflags(void *optctx, const char *opt, const char *arg)
+{
+ int ret;
+ unsigned flags = av_get_cpu_flags();
+
+ if ((ret = av_parse_cpu_caps(&flags, arg)) < 0)
+ return ret;
+
+ av_force_cpu_flags(flags);
+ return 0;
+}
+
int opt_loglevel(void *optctx, const char *opt, const char *arg)
{
const struct { const char *name; int level; } log_levels[] = {
@@ -960,18 +968,6 @@
return 0;
}
-int opt_cpuflags(void *optctx, const char *opt, const char *arg)
-{
- int ret;
- unsigned flags = av_get_cpu_flags();
-
- if ((ret = av_parse_cpu_caps(&flags, arg)) < 0)
- return ret;
-
- av_force_cpu_flags(flags);
- return 0;
-}
-
int opt_timelimit(void *optctx, const char *opt, const char *arg)
{
#if HAVE_SETRLIMIT
@@ -985,26 +981,6 @@
return 0;
}
-#if CONFIG_OPENCL
-int opt_opencl(void *optctx, const char *opt, const char *arg)
-{
- char *key, *value;
- const char *opts = arg;
- int ret = 0;
- while (*opts) {
- ret = av_opt_get_key_value(&opts, "=", ":", 0, &key, &value);
- if (ret < 0)
- return ret;
- ret = av_opencl_set_option(key, value);
- if (ret < 0)
- return ret;
- if (*opts)
- opts++;
- }
- return ret;
-}
-#endif
-
void print_error(const char *filename, int err)
{
char errbuf[128];
@@ -1070,7 +1046,7 @@
av_log(NULL, level, "%s version " FFMPEG_VERSION, program_name);
if (flags & SHOW_COPYRIGHT)
av_log(NULL, level, " Copyright (c) %d-%d the FFmpeg developers",
- program_birth_year, this_year);
+ program_birth_year, CONFIG_THIS_YEAR);
av_log(NULL, level, "\n");
av_log(NULL, level, "%sbuilt on %s %s with %s\n",
indent, __DATE__, __TIME__, CC_IDENT);
@@ -1078,6 +1054,32 @@
av_log(NULL, level, "%sconfiguration: " FFMPEG_CONFIGURATION "\n", indent);
}
+static void print_buildconf(int flags, int level)
+{
+ const char *indent = flags & INDENT ? " " : "";
+ char str[] = { FFMPEG_CONFIGURATION };
+ char *conflist, *remove_tilde, *splitconf;
+
+ // Change all the ' --' strings to '~--' so that
+ // they can be identified as tokens.
+ while ((conflist = strstr(str, " --")) != NULL) {
+ strncpy(conflist, "~--", 3);
+ }
+
+ // Compensate for the weirdness this would cause
+ // when passing 'pkg-config --static'.
+ while ((remove_tilde = strstr(str, "pkg-config~")) != NULL) {
+ strncpy(remove_tilde, "pkg-config ", 11);
+ }
+
+ splitconf = strtok(str, "~");
+ av_log(NULL, level, "\n%sconfiguration:\n", indent);
+ while (splitconf != NULL) {
+ av_log(NULL, level, "%s%s%s\n", indent, indent, splitconf);
+ splitconf = strtok(NULL, "~");
+ }
+}
+
void show_banner(int argc, char **argv, const OptionDef *options)
{
int idx = locate_option(argc, argv, options, "version");
@@ -1098,6 +1100,14 @@
return 0;
}
+int show_buildconf(void *optctx, const char *opt, const char *arg)
+{
+ av_log_set_callback(log_callback_help);
+ print_buildconf (INDENT|0, AV_LOG_INFO);
+
+ return 0;
+}
+
int show_license(void *optctx, const char *opt, const char *arg)
{
#if CONFIG_NONFREE
@@ -1517,6 +1527,20 @@
return 0;
}
+int show_colors(void *optctx, const char *opt, const char *arg)
+{
+ const char *name;
+ const uint8_t *rgb;
+ int i;
+
+ printf("%-32s #RRGGBB\n", "name");
+
+ for (i = 0; name = av_get_known_color_name(i, &rgb); i++)
+ printf("%-32s #%02x%02x%02x\n", name, rgb[0], rgb[1], rgb[2]);
+
+ return 0;
+}
+
int show_pix_fmts(void *optctx, const char *opt, const char *arg)
{
const AVPixFmtDescriptor *pix_desc = NULL;
@@ -1776,7 +1800,7 @@
int cmdutils_read_file(const char *filename, char **bufptr, size_t *size)
{
int ret;
- FILE *f = fopen(filename, "rb");
+ FILE *f = av_fopen_utf8(filename, "rb");
if (!f) {
av_log(NULL, AV_LOG_ERROR, "Cannot read file '%s': %s\n", filename,
diff --git a/cmdutils.h b/cmdutils.h
index 3af4476..f4f23ef 100644
--- a/cmdutils.h
+++ b/cmdutils.h
@@ -43,11 +43,6 @@
*/
extern const int program_birth_year;
-/**
- * this year, defined by the program for show_banner()
- */
-extern const int this_year;
-
extern AVCodecContext *avcodec_opts[AVMEDIA_TYPE_NB];
extern AVFormatContext *avformat_opts;
extern struct SwsContext *sws_opts;
@@ -82,6 +77,11 @@
void log_callback_help(void* ptr, int level, const char* fmt, va_list vl);
/**
+ * Override the cpuflags.
+ */
+int opt_cpuflags(void *optctx, const char *opt, const char *arg);
+
+/**
* Fallback for options that are not explicitly handled, these will be
* parsed through AVOptions.
*/
@@ -96,12 +96,14 @@
int opt_max_alloc(void *optctx, const char *opt, const char *arg);
-int opt_cpuflags(void *optctx, const char *opt, const char *arg);
-
int opt_codec_debug(void *optctx, const char *opt, const char *arg);
+#if CONFIG_OPENCL
int opt_opencl(void *optctx, const char *opt, const char *arg);
+int opt_opencl_bench(void *optctx, const char *opt, const char *arg);
+#endif
+
/**
* Limit the execution time.
*/
@@ -412,6 +414,13 @@
int show_version(void *optctx, const char *opt, const char *arg);
/**
+ * Print the build configuration of the program to stdout. The contents
+ * depend on the definition of FFMPEG_CONFIGURATION.
+ * This option processing function does not utilize the arguments.
+ */
+int show_buildconf(void *optctx, const char *opt, const char *arg);
+
+/**
* Print the license of the program to stdout. The license depends on
* the license of the libraries compiled into the program.
* This option processing function does not utilize the arguments.
@@ -486,6 +495,12 @@
int show_sample_fmts(void *optctx, const char *opt, const char *arg);
/**
+ * Print a listing containing all the color names and values recognized
+ * by the program.
+ */
+int show_colors(void *optctx, const char *opt, const char *arg);
+
+/**
* Return a positive value if a line read from standard input
* starts with [yY], otherwise return 0.
*/
@@ -498,7 +513,7 @@
* @param filename file to read from
* @param bufptr location where pointer to buffer is returned
* @param size location where size of buffer is returned
- * @return 0 in case of success, a negative value corresponding to an
+ * @return >= 0 in case of success, a negative value corresponding to an
* AVERROR error code in case of failure.
*/
int cmdutils_read_file(const char *filename, char **bufptr, size_t *size);
diff --git a/cmdutils_common_opts.h b/cmdutils_common_opts.h
index b57abaf..685163e 100644
--- a/cmdutils_common_opts.h
+++ b/cmdutils_common_opts.h
@@ -4,6 +4,7 @@
{ "help" , OPT_EXIT, {.func_arg = show_help}, "show help", "topic" },
{ "-help" , OPT_EXIT, {.func_arg = show_help}, "show help", "topic" },
{ "version" , OPT_EXIT, {.func_arg = show_version}, "show version" },
+ { "buildconf" , OPT_EXIT, {.func_arg = show_buildconf}, "show build configuration" },
{ "formats" , OPT_EXIT, {.func_arg = show_formats }, "show available formats" },
{ "codecs" , OPT_EXIT, {.func_arg = show_codecs }, "show available codecs" },
{ "decoders" , OPT_EXIT, {.func_arg = show_decoders }, "show available decoders" },
@@ -14,11 +15,13 @@
{ "pix_fmts" , OPT_EXIT, {.func_arg = show_pix_fmts }, "show available pixel formats" },
{ "layouts" , OPT_EXIT, {.func_arg = show_layouts }, "show standard channel layouts" },
{ "sample_fmts", OPT_EXIT, {.func_arg = show_sample_fmts }, "show available audio sample formats" },
+ { "colors" , OPT_EXIT, {.func_arg = show_colors }, "show available color names" },
{ "loglevel" , HAS_ARG, {.func_arg = opt_loglevel}, "set logging level", "loglevel" },
{ "v", HAS_ARG, {.func_arg = opt_loglevel}, "set logging level", "loglevel" },
{ "report" , 0, {(void*)opt_report}, "generate a report" },
{ "max_alloc" , HAS_ARG, {.func_arg = opt_max_alloc}, "set maximum size of a single allocated block", "bytes" },
- { "cpuflags" , HAS_ARG | OPT_EXPERT, {.func_arg = opt_cpuflags}, "force specific cpu flags", "flags" },
+ { "cpuflags" , HAS_ARG | OPT_EXPERT, { .func_arg = opt_cpuflags }, "force specific cpu flags", "flags" },
#if CONFIG_OPENCL
+ { "opencl_bench", OPT_EXIT, {.func_arg = opt_opencl_bench}, "run benchmark on all OpenCL devices and show results" },
{ "opencl_options", HAS_ARG, {.func_arg = opt_opencl}, "set OpenCL environment options" },
#endif
diff --git a/cmdutils_opencl.c b/cmdutils_opencl.c
new file mode 100644
index 0000000..2a04db9
--- /dev/null
+++ b/cmdutils_opencl.c
@@ -0,0 +1,274 @@
+/*
+ * Copyright (C) 2013 Lenny Wang
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "libavutil/opt.h"
+#include "libavutil/time.h"
+#include "libavutil/log.h"
+#include "libavutil/opencl.h"
+#include "cmdutils.h"
+
+typedef struct {
+ int platform_idx;
+ int device_idx;
+ char device_name[64];
+ int64_t runtime;
+} OpenCLDeviceBenchmark;
+
+const char *ocl_bench_source = AV_OPENCL_KERNEL(
+inline unsigned char clip_uint8(int a)
+{
+ if (a & (~0xFF))
+ return (-a)>>31;
+ else
+ return a;
+}
+
+kernel void unsharp_bench(
+ global unsigned char *src,
+ global unsigned char *dst,
+ global int *mask,
+ int width,
+ int height)
+{
+ int i, j, local_idx, lc_idx, sum = 0;
+ int2 thread_idx, block_idx, global_idx, lm_idx;
+ thread_idx.x = get_local_id(0);
+ thread_idx.y = get_local_id(1);
+ block_idx.x = get_group_id(0);
+ block_idx.y = get_group_id(1);
+ global_idx.x = get_global_id(0);
+ global_idx.y = get_global_id(1);
+ local uchar data[32][32];
+ local int lc[128];
+
+ for (i = 0; i <= 1; i++) {
+ lm_idx.y = -8 + (block_idx.y + i) * 16 + thread_idx.y;
+ lm_idx.y = lm_idx.y < 0 ? 0 : lm_idx.y;
+ lm_idx.y = lm_idx.y >= height ? height - 1: lm_idx.y;
+ for (j = 0; j <= 1; j++) {
+ lm_idx.x = -8 + (block_idx.x + j) * 16 + thread_idx.x;
+ lm_idx.x = lm_idx.x < 0 ? 0 : lm_idx.x;
+ lm_idx.x = lm_idx.x >= width ? width - 1: lm_idx.x;
+ data[i*16 + thread_idx.y][j*16 + thread_idx.x] = src[lm_idx.y*width + lm_idx.x];
+ }
+ }
+ local_idx = thread_idx.y*16 + thread_idx.x;
+ if (local_idx < 128)
+ lc[local_idx] = mask[local_idx];
+ barrier(CLK_LOCAL_MEM_FENCE);
+
+ \n#pragma unroll\n
+ for (i = -4; i <= 4; i++) {
+ lm_idx.y = 8 + i + thread_idx.y;
+ \n#pragma unroll\n
+ for (j = -4; j <= 4; j++) {
+ lm_idx.x = 8 + j + thread_idx.x;
+ lc_idx = (i + 4)*8 + j + 4;
+ sum += (int)data[lm_idx.y][lm_idx.x] * lc[lc_idx];
+ }
+ }
+ int temp = (int)data[thread_idx.y + 8][thread_idx.x + 8];
+ int res = temp + (((temp - (int)((sum + 1<<15) >> 16))) >> 16);
+ if (global_idx.x < width && global_idx.y < height)
+ dst[global_idx.x + global_idx.y*width] = clip_uint8(res);
+}
+);
+
+#define OCLCHECK(method, ... ) \
+do { \
+ status = method(__VA_ARGS__); \
+ if (status != CL_SUCCESS) { \
+ av_log(NULL, AV_LOG_ERROR, # method " error '%s'\n", \
+ av_opencl_errstr(status)); \
+ ret = AVERROR_EXTERNAL; \
+ goto end; \
+ } \
+} while (0)
+
+#define CREATEBUF(out, flags, size) \
+do { \
+ out = clCreateBuffer(ext_opencl_env->context, flags, size, NULL, &status); \
+ if (status != CL_SUCCESS) { \
+ av_log(NULL, AV_LOG_ERROR, "Could not create OpenCL buffer\n"); \
+ ret = AVERROR_EXTERNAL; \
+ goto end; \
+ } \
+} while (0)
+
+static void fill_rand_int(int *data, int n)
+{
+ int i;
+ srand(av_gettime());
+ for (i = 0; i < n; i++)
+ data[i] = rand();
+}
+
+#define OPENCL_NB_ITER 5
+static int64_t run_opencl_bench(AVOpenCLExternalEnv *ext_opencl_env)
+{
+ int i, arg = 0, width = 1920, height = 1088;
+ int64_t start, ret = 0;
+ cl_int status;
+ size_t kernel_len;
+ char *inbuf;
+ int *mask;
+ int buf_size = width * height * sizeof(char);
+ int mask_size = sizeof(uint32_t) * 128;
+
+ cl_mem cl_mask, cl_inbuf, cl_outbuf;
+ cl_kernel kernel = NULL;
+ cl_program program = NULL;
+ size_t local_work_size_2d[2] = {16, 16};
+ size_t global_work_size_2d[2] = {(size_t)width, (size_t)height};
+
+ if (!(inbuf = av_malloc(buf_size)) || !(mask = av_malloc(mask_size))) {
+ av_log(NULL, AV_LOG_ERROR, "Out of memory\n");
+ ret = AVERROR(ENOMEM);
+ goto end;
+ }
+ fill_rand_int((int*)inbuf, buf_size/4);
+ fill_rand_int(mask, mask_size/4);
+
+ CREATEBUF(cl_mask, CL_MEM_READ_ONLY, mask_size);
+ CREATEBUF(cl_inbuf, CL_MEM_READ_ONLY, buf_size);
+ CREATEBUF(cl_outbuf, CL_MEM_READ_WRITE, buf_size);
+
+ kernel_len = strlen(ocl_bench_source);
+ program = clCreateProgramWithSource(ext_opencl_env->context, 1, &ocl_bench_source,
+ &kernel_len, &status);
+ if (status != CL_SUCCESS || !program) {
+ av_log(NULL, AV_LOG_ERROR, "OpenCL unable to create benchmark program\n");
+ ret = AVERROR_EXTERNAL;
+ goto end;
+ }
+ status = clBuildProgram(program, 1, &(ext_opencl_env->device_id), NULL, NULL, NULL);
+ if (status != CL_SUCCESS) {
+ av_log(NULL, AV_LOG_ERROR, "OpenCL unable to build benchmark program\n");
+ ret = AVERROR_EXTERNAL;
+ goto end;
+ }
+ kernel = clCreateKernel(program, "unsharp_bench", &status);
+ if (status != CL_SUCCESS) {
+ av_log(NULL, AV_LOG_ERROR, "OpenCL unable to create benchmark kernel\n");
+ ret = AVERROR_EXTERNAL;
+ goto end;
+ }
+
+ OCLCHECK(clEnqueueWriteBuffer, ext_opencl_env->command_queue, cl_inbuf, CL_TRUE, 0,
+ buf_size, inbuf, 0, NULL, NULL);
+ OCLCHECK(clEnqueueWriteBuffer, ext_opencl_env->command_queue, cl_mask, CL_TRUE, 0,
+ mask_size, mask, 0, NULL, NULL);
+ OCLCHECK(clSetKernelArg, kernel, arg++, sizeof(cl_mem), &cl_inbuf);
+ OCLCHECK(clSetKernelArg, kernel, arg++, sizeof(cl_mem), &cl_outbuf);
+ OCLCHECK(clSetKernelArg, kernel, arg++, sizeof(cl_mem), &cl_mask);
+ OCLCHECK(clSetKernelArg, kernel, arg++, sizeof(cl_int), &width);
+ OCLCHECK(clSetKernelArg, kernel, arg++, sizeof(cl_int), &height);
+
+ start = av_gettime();
+ for (i = 0; i < OPENCL_NB_ITER; i++)
+ OCLCHECK(clEnqueueNDRangeKernel, ext_opencl_env->command_queue, kernel, 2, NULL,
+ global_work_size_2d, local_work_size_2d, 0, NULL, NULL);
+ clFinish(ext_opencl_env->command_queue);
+ ret = (av_gettime() - start)/OPENCL_NB_ITER;
+end:
+ if (kernel)
+ clReleaseKernel(kernel);
+ if (program)
+ clReleaseProgram(program);
+ if (cl_inbuf)
+ clReleaseMemObject(cl_inbuf);
+ if (cl_outbuf)
+ clReleaseMemObject(cl_outbuf);
+ if (cl_mask)
+ clReleaseMemObject(cl_mask);
+ av_free(inbuf);
+ av_free(mask);
+ return ret;
+}
+
+static int compare_ocl_device_desc(const void *a, const void *b)
+{
+ return ((OpenCLDeviceBenchmark*)a)->runtime - ((OpenCLDeviceBenchmark*)b)->runtime;
+}
+
+int opt_opencl_bench(void *optctx, const char *opt, const char *arg)
+{
+ int i, j, nb_devices = 0, count = 0;
+ int64_t score = 0;
+ AVOpenCLDeviceList *device_list;
+ AVOpenCLDeviceNode *device_node = NULL;
+ OpenCLDeviceBenchmark *devices = NULL;
+ cl_platform_id platform;
+
+ av_opencl_get_device_list(&device_list);
+ for (i = 0; i < device_list->platform_num; i++)
+ nb_devices += device_list->platform_node[i]->device_num;
+ if (!nb_devices) {
+ av_log(NULL, AV_LOG_ERROR, "No OpenCL device detected!\n");
+ return AVERROR(EINVAL);
+ }
+ if (!(devices = av_malloc(sizeof(OpenCLDeviceBenchmark) * nb_devices))) {
+ av_log(NULL, AV_LOG_ERROR, "Could not allocate buffer\n");
+ return AVERROR(ENOMEM);
+ }
+
+ for (i = 0; i < device_list->platform_num; i++) {
+ for (j = 0; j < device_list->platform_node[i]->device_num; j++) {
+ device_node = device_list->platform_node[i]->device_node[j];
+ platform = device_list->platform_node[i]->platform_id;
+ score = av_opencl_benchmark(device_node, platform, run_opencl_bench);
+ if (score > 0) {
+ devices[count].platform_idx = i;
+ devices[count].device_idx = j;
+ devices[count].runtime = score;
+ strcpy(devices[count].device_name, device_node->device_name);
+ count++;
+ }
+ }
+ }
+ qsort(devices, count, sizeof(OpenCLDeviceBenchmark), compare_ocl_device_desc);
+ fprintf(stderr, "platform_idx\tdevice_idx\tdevice_name\truntime\n");
+ for (i = 0; i < count; i++)
+ fprintf(stdout, "%d\t%d\t%s\t%"PRId64"\n",
+ devices[i].platform_idx, devices[i].device_idx,
+ devices[i].device_name, devices[i].runtime);
+
+ av_opencl_free_device_list(&device_list);
+ av_free(devices);
+ return 0;
+}
+
+int opt_opencl(void *optctx, const char *opt, const char *arg)
+{
+ char *key, *value;
+ const char *opts = arg;
+ int ret = 0;
+ while (*opts) {
+ ret = av_opt_get_key_value(&opts, "=", ":", 0, &key, &value);
+ if (ret < 0)
+ return ret;
+ ret = av_opencl_set_option(key, value);
+ if (ret < 0)
+ return ret;
+ if (*opts)
+ opts++;
+ }
+ return ret;
+}
diff --git a/common.mak b/common.mak
index 6479b08..50469a1 100644
--- a/common.mak
+++ b/common.mak
@@ -10,7 +10,7 @@
ifndef V
Q = @
ECHO = printf "$(1)\t%s\n" $(2)
-BRIEF = CC CXX HOSTCC HOSTLD AS YASM AR LD STRIP CP
+BRIEF = CC CXX HOSTCC HOSTLD AS YASM AR LD STRIP CP WINDRES
SILENT = DEPCC DEPHOSTCC DEPAS DEPYASM RANLIB RM
MSG = $@
@@ -43,6 +43,7 @@
COMPILE_C = $(call COMPILE,CC)
COMPILE_CXX = $(call COMPILE,CXX)
COMPILE_S = $(call COMPILE,AS)
+COMPILE_HOSTC = $(call COMPILE,HOSTCC)
%.o: %.c
$(COMPILE_C)
@@ -56,6 +57,12 @@
%.o: %.S
$(COMPILE_S)
+%_host.o: %.c
+ $(COMPILE_HOSTC)
+
+%.o: %.rc
+ $(WINDRES) $(IFLAGS) --preprocessor "$(DEPWINDRES) -E -xc-header -DRC_INVOKED $(CC_DEPFLAGS)" -o $@ $<
+
%.i: %.c
$(CC) $(CCFLAGS) $(CC_E) $<
@@ -82,6 +89,7 @@
include $(SRC_PATH)/arch.mak
OBJS += $(OBJS-yes)
+SLIBOBJS += $(SLIBOBJS-yes)
FFLIBS := $(FFLIBS-yes) $(FFLIBS)
TESTPROGS += $(TESTPROGS-yes)
@@ -90,6 +98,7 @@
EXAMPLES := $(EXAMPLES:%=$(SUBDIR)%-example$(EXESUF))
OBJS := $(sort $(OBJS:%=$(SUBDIR)%))
+SLIBOBJS := $(sort $(SLIBOBJS:%=$(SUBDIR)%))
TESTOBJS := $(TESTOBJS:%=$(SUBDIR)%) $(TESTPROGS:%=$(SUBDIR)%-test.o)
TESTPROGS := $(TESTPROGS:%=$(SUBDIR)%-test$(EXESUF))
HOSTOBJS := $(HOSTPROGS:%=$(SUBDIR)%.o)
@@ -113,18 +122,19 @@
alltools: $(TOOLS)
$(HOSTOBJS): %.o: %.c
- $(call COMPILE,HOSTCC)
+ $(COMPILE_HOSTC)
$(HOSTPROGS): %$(HOSTEXESUF): %.o
- $(HOSTLD) $(HOSTLDFLAGS) $(HOSTLD_O) $< $(HOSTLIBS)
+ $(HOSTLD) $(HOSTLDFLAGS) $(HOSTLD_O) $^ $(HOSTLIBS)
$(OBJS): | $(sort $(dir $(OBJS)))
$(HOBJS): | $(sort $(dir $(HOBJS)))
$(HOSTOBJS): | $(sort $(dir $(HOSTOBJS)))
+$(SLIBOBJS): | $(sort $(dir $(SLIBOBJS)))
$(TESTOBJS): | $(sort $(dir $(TESTOBJS)))
$(TOOLOBJS): | tools
-OBJDIRS := $(OBJDIRS) $(dir $(OBJS) $(HOBJS) $(HOSTOBJS) $(TESTOBJS))
+OBJDIRS := $(OBJDIRS) $(dir $(OBJS) $(HOBJS) $(HOSTOBJS) $(SLIBOBJS) $(TESTOBJS))
CLEANSUFFIXES = *.d *.o *~ *.h.c *.map *.ver *.ho *.gcno *.gcda
DISTCLEANSUFFIXES = *.pc
@@ -139,4 +149,4 @@
$(eval $(RULES))
--include $(wildcard $(OBJS:.o=.d) $(HOSTOBJS:.o=.d) $(TESTOBJS:.o=.d) $(HOBJS:.o=.d))
+-include $(wildcard $(OBJS:.o=.d) $(HOSTOBJS:.o=.d) $(TESTOBJS:.o=.d) $(HOBJS:.o=.d) $(SLIBOBJS:.o=.d))
diff --git a/compat/getopt.c b/compat/getopt.c
index dd082ea..9a9c542 100644
--- a/compat/getopt.c
+++ b/compat/getopt.c
@@ -38,8 +38,6 @@
static int optopt;
static char *optarg;
-#undef fprintf
-
static int getopt(int argc, char *argv[], char *opts)
{
static int sp = 1;
diff --git a/compat/os2threads.h b/compat/os2threads.h
index b816bff..441ac43 100644
--- a/compat/os2threads.h
+++ b/compat/os2threads.h
@@ -32,6 +32,8 @@
#undef __STRICT_ANSI__ /* for _beginthread() */
#include <stdlib.h>
+#include "libavutil/mem.h"
+
typedef TID pthread_t;
typedef void pthread_attr_t;
diff --git a/compat/windows/makedef b/compat/windows/makedef
new file mode 100755
index 0000000..fcaf108
--- /dev/null
+++ b/compat/windows/makedef
@@ -0,0 +1,132 @@
+#!/bin/sh
+
+# Copyright (c) 2013, Derek Buitenhuis
+#
+# 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.
+
+# mktemp isn't POSIX, so supply an implementation
+mktemp() {
+ echo "${2%%XXX*}.${HOSTNAME}.${UID}.$$"
+}
+
+if [ $# -lt 2 ]; then
+ echo "Usage: makedef <version_script> <objects>" >&2
+ exit 0
+fi
+
+vscript=$1
+shift
+
+if [ ! -f "$vscript" ]; then
+ echo "Version script does not exist" >&2
+ exit 1
+fi
+
+for object in "$@"; do
+ if [ ! -f "$object" ]; then
+ echo "Object does not exist: ${object}" >&2
+ exit 1
+ fi
+done
+
+# Create a lib temporarily to dump symbols from.
+# It's just much easier to do it this way
+libname=$(mktemp -u "library").lib
+
+trap 'rm -f -- $libname' EXIT
+
+lib -out:${libname} $@ >/dev/null
+if [ $? != 0 ]; then
+ echo "Could not create temporary library." >&2
+ exit 1
+fi
+
+IFS='
+'
+
+# Determine if we're building for x86 or x86_64 and
+# set the symbol prefix accordingly.
+prefix=""
+arch=$(dumpbin -headers ${libname} |
+ tr '\t' ' ' |
+ grep '^ \+.\+machine \+(.\+)' |
+ head -1 |
+ sed -e 's/^ \{1,\}.\{1,\} \{1,\}machine \{1,\}(\(...\)).*/\1/')
+
+if [ "${arch}" = "x86" ]; then
+ prefix="_"
+else
+ if [ "${arch}" != "ARM" ] && [ "${arch}" != "x64" ]; then
+ echo "Unknown machine type." >&2
+ exit 1
+ fi
+fi
+
+started=0
+regex="none"
+
+for line in $(cat ${vscript} | tr '\t' ' '); do
+ # We only care about global symbols
+ echo "${line}" | grep -q '^ \+global:'
+ if [ $? = 0 ]; then
+ started=1
+ line=$(echo "${line}" | sed -e 's/^ \{1,\}global: *//')
+ else
+ echo "${line}" | grep -q '^ \+local:'
+ if [ $? = 0 ]; then
+ started=0
+ fi
+ fi
+
+ if [ ${started} = 0 ]; then
+ continue
+ fi
+
+ # Handle multiple symbols on one line
+ IFS=';'
+
+ # Work around stupid expansion to filenames
+ line=$(echo "${line}" | sed -e 's/\*/.\\+/g')
+ for exp in ${line}; do
+ # Remove leading and trailing whitespace
+ exp=$(echo "${exp}" | sed -e 's/^ *//' -e 's/ *$//')
+
+ if [ "${regex}" = "none" ]; then
+ regex="${exp}"
+ else
+ regex="${regex};${exp}"
+ fi
+ done
+
+ IFS='
+'
+done
+
+dump=$(dumpbin -linkermember:1 ${libname})
+
+rm ${libname}
+
+IFS=';'
+list=""
+for exp in ${regex}; do
+ list="${list}"'
+'$(echo "${dump}" |
+ sed -e '/public symbols/,$!d' -e '/^ \{1,\}Summary/,$d' -e "s/ \{1,\}${prefix}/ /" -e 's/ \{1,\}/ /g' |
+ tail -n +2 |
+ cut -d' ' -f3 |
+ grep "^${exp}" |
+ sed -e 's/^/ /')
+done
+
+echo "EXPORTS"
+echo "${list}" | sort | uniq | tail -n +2
diff --git a/configure b/configure
index 7cf276d..742233d 100755
--- a/configure
+++ b/configure
@@ -87,6 +87,8 @@
--shlibdir=DIR install shared libs in DIR [PREFIX/lib]
--incdir=DIR install includes in DIR [PREFIX/include]
--mandir=DIR install man page in DIR [PREFIX/share/man]
+ --enable-rpath use rpath to allow installing libraries in paths
+ not part of the dynamic linker search path
Licensing options:
--enable-gpl allow use of GPL code, the resulting libs
@@ -265,6 +267,7 @@
--nm=NM use nm tool NM [$nm_default]
--ar=AR use archive tool AR [$ar_default]
--as=AS use assembler AS [$as_default]
+ --windres=WINDRES use windows resource compiler WINDRES [$windres_default]
--yasmexe=EXE use yasm-compatible assembler EXE [$yasmexe_default]
--cc=CC use C compiler CC [$cc_default]
--cxx=CXX use C compiler CXX [$cxx_default]
@@ -315,6 +318,7 @@
--disable-sse42 disable SSE4.2 optimizations
--disable-avx disable AVX optimizations
--disable-fma4 disable FMA4 optimizations
+ --disable-avx2 disable AVX2 optimizations
--disable-armv5te disable armv5te optimizations
--disable-armv6 disable armv6 optimizations
--disable-armv6t2 disable armv6t2 optimizations
@@ -424,7 +428,7 @@
}
cleanws(){
- echo "$@" | sed 's/^ *//;s/ */ /g;s/ *$//'
+ echo "$@" | sed 's/^ *//;s/ */ /g;s/ *$//;s/\r//g'
}
filter(){
@@ -727,6 +731,10 @@
append LDFLAGS $($ldflags_filter "$@")
}
+add_stripflags(){
+ append ASMSTRIPFLAGS "$@"
+}
+
add_extralibs(){
prepend extralibs $($ldflags_filter "$@")
}
@@ -856,14 +864,19 @@
EOF
}
-check_cflags(){
- log check_cflags "$@"
+test_cflags(){
+ log test_cflags "$@"
set -- $($cflags_filter "$@")
- check_cc "$@" <<EOF && append CFLAGS "$@"
+ check_cc "$@" <<EOF
int x;
EOF
}
+check_cflags(){
+ log check_cflags "$@"
+ test_cflags "$@" && add_cflags "$@"
+}
+
check_cxxflags(){
log check_cxxflags "$@"
set -- $($cflags_filter "$@")
@@ -884,6 +897,20 @@
test_ldflags "$@" && add_ldflags "$@"
}
+test_stripflags(){
+ log test_stripflags "$@"
+ # call check_cc to get a fresh TMPO
+ check_cc <<EOF
+int main(void) { return 0; }
+EOF
+ check_cmd $strip $ASMSTRIPFLAGS "$@" $TMPO
+}
+
+check_stripflags(){
+ log check_stripflags "$@"
+ test_stripflags "$@" && add_stripflags "$@"
+}
+
check_header(){
log check_header "$@"
header=$1
@@ -1101,6 +1128,26 @@
add_extralibs $(get_safe ${pkg}_libs)
}
+require_libfreetype(){
+ log require_libfreetype "$@"
+ pkg="freetype2"
+ check_cmd $pkg_config --exists --print-errors $pkg \
+ || die "ERROR: $pkg not found"
+ pkg_cflags=$($pkg_config --cflags $pkg)
+ pkg_libs=$($pkg_config --libs $pkg)
+ {
+ echo "#include <ft2build.h>"
+ echo "#include FT_FREETYPE_H"
+ echo "long check_func(void) { return (long) FT_Init_FreeType; }"
+ echo "int main(void) { return 0; }"
+ } | check_ld "cc" $pkg_cflags $pkg_libs \
+ && set_safe ${pkg}_cflags $pkg_cflags \
+ && set_safe ${pkg}_libs $pkg_libs \
+ || die "ERROR: $pkg not found"
+ add_cflags $(get_safe ${pkg}_cflags)
+ add_extralibs $(get_safe ${pkg}_libs)
+}
+
hostcc_o(){
eval printf '%s\\n' $HOSTCC_O
}
@@ -1156,6 +1203,18 @@
protocols
"
+EXAMPLE_LIST="
+ decoding_encoding_example
+ demuxing_decoding_example
+ filtering_audio_example
+ filtering_video_example
+ metadata_example
+ muxing_example
+ resampling_audio_example
+ scaling_video_example
+ transcode_aac_example
+"
+
EXTERNAL_LIBRARY_LIST="
avisynth
bzlib
@@ -1256,6 +1315,7 @@
CONFIG_LIST="
$COMPONENT_LIST
$DOCUMENT_LIST
+ $EXAMPLE_LIST
$EXTERNAL_LIBRARY_LIST
$HWACCEL_LIST
$LIBRARY_LIST
@@ -1344,6 +1404,7 @@
amd3dnow
amd3dnowext
avx
+ avx2
fma4
i686
mmx
@@ -1469,6 +1530,7 @@
gettimeofday
glob
gnu_as
+ gnu_windres
gsm_h
ibm_asm
inet_aton
@@ -1478,6 +1540,7 @@
jack_port_get_latency_range
kbhit
ldbrx
+ libc_msvcrt
libdc1394_1
libdc1394_2
local_aligned_16
@@ -1497,7 +1560,6 @@
mm_empty
mmap
mprotect
- msvcrt
nanosleep
openjpeg_1_5_openjpeg_h
PeekNamedPipe
@@ -1550,11 +1612,13 @@
threads
unistd_h
usleep
+ vdpau_x11
vfp_args
VirtualAlloc
windows_h
winsock2_h
xform_asm
+ xlib
xmm_clobbers
"
@@ -1569,6 +1633,7 @@
gcrypt
golomb
gplv3
+ h263dsp
h264chroma
h264dsp
h264pred
@@ -1604,6 +1669,7 @@
logging
lto
optimizations
+ rpath
stripping
"
@@ -1705,6 +1771,7 @@
sse42_deps="sse4"
avx_deps="sse42"
fma4_deps="avx"
+avx2_deps="avx"
mmx_external_deps="yasm"
mmx_inline_deps="inline_asm"
@@ -1727,7 +1794,7 @@
symver_if_any="symver_asm_label symver_gnu_asm"
-log2_deps="!msvcrt"
+log2_deps="!libc_msvcrt"
# subsystems
dct_select="rdft"
@@ -1803,12 +1870,13 @@
g729_decoder_select="dsputil"
h261_decoder_select="error_resilience mpegvideo"
h261_encoder_select="aandcttables mpegvideoenc"
-h263_decoder_select="error_resilience h263_parser mpegvideo"
-h263_encoder_select="aandcttables mpegvideoenc"
+h263_decoder_select="error_resilience h263_parser h263dsp mpegvideo"
+h263_encoder_select="aandcttables h263dsp mpegvideoenc"
h263i_decoder_select="h263_decoder"
h263p_encoder_select="h263_encoder"
h264_decoder_select="golomb h264chroma h264dsp h264pred h264qpel videodsp"
h264_decoder_suggest="error_resilience"
+hevc_decoder_select="dsputil golomb videodsp"
huffyuv_decoder_select="dsputil"
huffyuv_encoder_select="dsputil huffman"
iac_decoder_select="dsputil fft mdct sinewin"
@@ -1868,9 +1936,9 @@
ra_144_encoder_select="audio_frame_queue lpc"
ralf_decoder_select="golomb"
rtjpeg_decoder_select="dsputil"
-rv10_decoder_select="error_resilience h263_decoder"
+rv10_decoder_select="error_resilience h263_decoder h263dsp"
rv10_encoder_select="h263_encoder"
-rv20_decoder_select="error_resilience h263_decoder"
+rv20_decoder_select="error_resilience h263_decoder h263dsp"
rv20_encoder_select="h263_encoder"
rv30_decoder_select="error_resilience golomb h264chroma h264pred h264qpel mpegvideo videodsp"
rv40_decoder_select="error_resilience golomb h264chroma h264pred h264qpel mpegvideo videodsp"
@@ -1992,6 +2060,7 @@
# parsers
h264_parser_select="golomb h264chroma h264dsp h264pred h264qpel videodsp"
+hevc_parser_select="hevc_decoder"
mpeg4video_parser_select="error_resilience mpegvideo"
mpegvideo_parser_select="error_resilience mpegvideo"
vc1_parser_select="mpegvideo"
@@ -2070,6 +2139,7 @@
eac3_demuxer_select="ac3_parser"
f4v_muxer_select="mov_muxer"
flac_demuxer_select="flac_parser"
+hds_muxer_select="flv_muxer"
hls_muxer_select="mpegts_muxer"
ipod_muxer_select="mov_muxer"
ismv_muxer_select="mov_muxer"
@@ -2124,6 +2194,7 @@
dv1394_indev_deps="dv1394"
dv1394_indev_select="dv_demuxer"
fbdev_indev_deps="linux_fb_h"
+fbdev_outdev_deps="linux_fb_h"
iec61883_indev_deps="libiec61883"
jack_indev_deps="jack_jack_h sem_timedwait"
lavfi_indev_deps="avfilter"
@@ -2223,7 +2294,6 @@
mpdecimate_filter_deps="gpl avcodec"
mptestsrc_filter_deps="gpl"
negate_filter_deps="lut_filter"
-noise_filter_deps="gpl"
perspective_filter_deps="gpl"
resample_filter_deps="avresample"
ocv_filter_deps="libopencv"
@@ -2252,6 +2322,17 @@
tinterlace_pad_test_deps="tinterlace_filter"
zmq_filter_deps="libzmq"
+# examples
+decoding_encoding_example_deps="avcodec avutil"
+demuxing_decoding_example_deps="avcodec avformat avutil"
+filtering_audio_example_deps="avfilter avcodec avformat avutil"
+filtering_video_example_deps="avfilter avcodec avformat avutil"
+metadata_example_deps="avformat avutil"
+muxing_example_deps="avcodec avformat avutil swscale"
+resampling_audio_example_deps="avutil swresample"
+scaling_video_example_deps="avutil swscale"
+transcode_aac_example_deps="avcodec avformat swresample"
+
# libraries
avcodec_deps="avutil"
avdevice_deps="avutil avcodec avformat"
@@ -2262,7 +2343,7 @@
swscale_deps="avutil"
# programs
-ffmpeg_deps="avcodec avfilter avformat swscale swresample"
+ffmpeg_deps="avcodec avfilter avformat swresample"
ffmpeg_select="aformat_filter anull_filter atrim_filter format_filter
null_filter
setpts_filter trim_filter"
@@ -2276,8 +2357,8 @@
# documentation
podpages_deps="perl"
manpages_deps="perl pod2man"
-htmlpages_deps="texi2html"
-txtpages_deps="makeinfo"
+htmlpages_deps="perl texi2html"
+txtpages_deps="perl makeinfo"
doc_deps_any="manpages htmlpages podpages txtpages"
# default parameters
@@ -2308,6 +2389,7 @@
ranlib="ranlib"
strip_default="strip"
yasmexe_default="yasm"
+windres_default="windres"
nogas=":"
@@ -2322,6 +2404,7 @@
# configurable options
enable $PROGRAM_LIST
enable $DOCUMENT_LIST
+enable $EXAMPLE_LIST
enable $(filter_out avresample $LIBRARY_LIST)
enable stripping
@@ -2577,6 +2660,7 @@
pkg_config_default="${cross_prefix}${pkg_config_default}"
ranlib="${cross_prefix}${ranlib}"
strip_default="${cross_prefix}${strip_default}"
+windres_default="${cross_prefix}${windres_default}"
sysinclude_default="${sysroot}/usr/include"
@@ -2612,30 +2696,44 @@
target_exec_args="--error-exitcode=1 --malloc-fill=0x2a --track-origins=yes --leak-check=full --gen-suppressions=all --suppressions=$source_path/tests/fate-valgrind.supp"
;;
msvc)
- cc_default="c99wrap cl"
- ld_default="c99wrap link"
- nm_default="dumpbin -symbols"
- ar_default="lib"
- target_os_default="win32"
- ;;
- msvc2013)
- cc_default="cl"
+ # Check whether the current MSVC version needs the C99 converter.
+ # From MSVC 2013 (compiler major version 18) onwards, it does actually
+ # support enough of C99 to build ffmpeg. Default to the new
+ # behaviour if the regexp was unable to match anything, since this
+ # successfully parses the version number of existing supported
+ # versions that require the converter (MSVC 2010 and 2012).
+ cl_major_ver=$(cl 2>&1 | sed -n 's/.*Version \([[:digit:]]\{1,\}\)\..*/\1/p')
+ if [ -z "$cl_major_ver" ] || [ $cl_major_ver -ge 18 ]; then
+ cc_default="cl"
+ else
+ cc_default="c99wrap cl"
+ fi
ld_default="link"
nm_default="dumpbin -symbols"
ar_default="lib"
target_os_default="win32"
+ # Use a relative path for TMPDIR. This makes sure all the
+ # ffconf temp files are written with a relative path, avoiding
+ # issues with msys/win32 path conversion for MSVC parameters
+ # such as -Fo<file> or -out:<file>.
+ TMPDIR=.
;;
icl)
- cc_default="c99wrap -noconv icl"
- ld_default="c99wrap xilink"
+ cc_default="icl"
+ ld_default="xilink"
nm_default="dumpbin -symbols"
ar_default="xilib"
target_os_default="win32"
+ TMPDIR=.
;;
gcov)
add_cflags -fprofile-arcs -ftest-coverage
add_ldflags -fprofile-arcs -ftest-coverage
;;
+ hardened)
+ add_cflags -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -fno-strict-overflow -fstack-protector-all
+ add_ldflags -Wl,-z,relro -Wl,-z,now
+ ;;
?*)
die "Unknown toolchain $toolchain"
;;
@@ -2881,7 +2979,9 @@
unset _depflags _DEPCMD _DEPFLAGS
_flags_filter=echo
- if $_cc -v 2>&1 | grep -q '^gcc.*LLVM'; then
+ if $_cc --version 2>&1 | grep -q '^GNU assembler'; then
+ true # no-op to avoid reading stdin in following checks
+ elif $_cc -v 2>&1 | grep -q '^gcc.*LLVM'; then
_type=llvm_gcc
gcc_extra_ver=$(expr "$($_cc --version | head -n1)" : '.*\((.*)\)')
_ident="llvm-gcc $($_cc -dumpversion) $gcc_extra_ver"
@@ -2989,14 +3089,12 @@
_DEPFLAGS='$(CPPFLAGS) $(CFLAGS) -showIncludes -Zs'
_cflags_speed="-O2"
_cflags_size="-O1"
- # Nonstandard output options, to avoid msys path conversion issues.
- # Relies on wrapper to remap it.
if $_cc 2>&1 | grep -q Linker; then
_ld_o='-out:$@'
else
_ld_o='-Fe$@'
fi
- _cc_o='-Fo$@'
+ _cc_o='-Fo $@'
_cc_e='-P -Fi $@'
_flags_filter=msvc_flags
_ld_lib='lib%.a'
@@ -3015,14 +3113,12 @@
# versions (tested) as well.
_cflags_speed="-O2"
_cflags_size="-O1 -Oi" # -O1 without -Oi miscompiles stuff
- # Nonstandard output options, to avoid msys path conversion issues.
- # Relies on wrapper to remap it.
if $_cc 2>&1 | grep -q Linker; then
- _ld_o='-out $@'
+ _ld_o='-out:$@'
else
_ld_o='-Fe$@'
fi
- _cc_o='-Fo $@'
+ _cc_o='-Fo$@'
_cc_e='-P'
_flags_filter=icl_flags
_ld_lib='lib%.a'
@@ -3083,7 +3179,7 @@
: ${dep_cc_default:=$cc}
: ${ld_default:=$cc}
: ${host_ld_default:=$host_cc}
-set_default ar as dep_cc ld host_ld
+set_default ar as dep_cc ld host_ld windres
probe_cc as "$as"
asflags_filter=$_flags_filter
@@ -3504,7 +3600,6 @@
SHFLAGS='-shared -Wl,-h,$$(@F)'
enabled x86 && SHFLAGS="-mimpure-text $SHFLAGS"
network_extralibs="-lsocket -lnsl"
- add_cppflags -D__EXTENSIONS__ -D_XOPEN_SOURCE=600
# 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
@@ -3565,6 +3660,7 @@
elif enabled arm; then
LIBTARGET=arm-wince
fi
+ enabled shared && ! enabled small && check_cmd $windres --version && enable gnu_windres
check_ldflags -Wl,--nxcompat
check_ldflags -Wl,--dynamicbase
shlibdir_default="$bindir_default"
@@ -3591,6 +3687,7 @@
enable dos_paths
;;
win32|win64)
+ disable symver
if enabled shared; then
# Link to the import library instead of the normal static library
# for shared libs.
@@ -3603,7 +3700,7 @@
SLIBSUF=".dll"
SLIBNAME_WITH_VERSION='$(SLIBPREF)$(FULLNAME)-$(LIBVERSION)$(SLIBSUF)'
SLIBNAME_WITH_MAJOR='$(SLIBPREF)$(FULLNAME)-$(LIBMAJOR)$(SLIBSUF)'
- SLIB_CREATE_DEF_CMD='makedef $(SUBDIR)lib$(NAME).ver $(OBJS) > $$(@:$(SLIBSUF)=.def)'
+ SLIB_CREATE_DEF_CMD='$(SRC_PATH)/compat/windows/makedef $(SUBDIR)lib$(NAME).ver $(OBJS) > $$(@:$(SLIBSUF)=.def)'
SLIB_INSTALL_NAME='$(SLIBNAME_WITH_MAJOR)'
SLIB_INSTALL_LINKS=
SLIB_INSTALL_EXTRA_SHLIB='$(SLIBNAME:$(SLIBSUF)=.lib)'
@@ -3626,6 +3723,7 @@
SHFLAGS='-shared -Wl,--out-implib,$(SUBDIR)lib$(FULLNAME).dll.a'
objformat="win32"
enable dos_paths
+ enabled shared && ! enabled small && check_cmd $windres --version && enable gnu_windres
;;
*-dos|freedos|opendos)
network_extralibs="-lsocket"
@@ -3722,26 +3820,24 @@
elif check_cpp_condition newlib.h "defined _NEWLIB_VERSION"; then
libc_type=newlib
add_cppflags -U__STRICT_ANSI__
-elif check_header _mingw.h; then
- libc_type=mingw
- check_cpp_condition _mingw.h \
- "defined (__MINGW64_VERSION_MAJOR) || (__MINGW32_MAJOR_VERSION > 3) || \
- (__MINGW32_MAJOR_VERSION == 3 && __MINGW32_MINOR_VERSION >= 15)" ||
- die "ERROR: MinGW runtime version must be >= 3.15."
- add_cppflags -U__STRICT_ANSI__
- if check_cpp_condition _mingw.h "defined(__MINGW64_VERSION_MAJOR) && \
- __MINGW64_VERSION_MAJOR < 3"; then
+# MinGW64 is backwards compatible with MinGW32, so check for it first.
+elif check_cpp_condition _mingw.h "defined __MINGW64_VERSION_MAJOR"; then
+ libc_type=mingw64
+ if check_cpp_condition _mingw.h "__MINGW64_VERSION_MAJOR < 3"; then
add_compat msvcrt/snprintf.o
add_cflags "-include $source_path/compat/msvcrt/snprintf.h"
else
add_cppflags -D__USE_MINGW_ANSI_STDIO=1
fi
-elif check_func_headers stdlib.h _get_doserrno; then
+ add_cppflags -U__STRICT_ANSI__
+elif check_cpp_condition _mingw.h "defined __MINGW32_VERSION"; then
+ libc_type=mingw32
+ check_cpp_condition _mingw.h "__MINGW32_MAJOR_VERSION > 3 || \
+ (__MINGW32_MAJOR_VERSION == 3 && __MINGW32_MINOR_VERSION >= 15)" ||
+ die "ERROR: MinGW32 runtime version must be >= 3.15."
+ add_cppflags -U__STRICT_ANSI__
+elif check_cpp_condition crtversion.h "defined _VC_CRT_MAJOR_VERSION"; then
libc_type=msvcrt
- add_compat strtod.o strtod=avpriv_strtod
- add_compat msvcrt/snprintf.o snprintf=avpriv_snprintf \
- _snprintf=avpriv_snprintf \
- vsnprintf=avpriv_vsnprintf
# The MSVC 2010 headers (Win 7.0 SDK) set _WIN32_WINNT to
# 0x601 by default unless something else is set by the user.
# This can easily lead to us detecting functions only present
@@ -3753,14 +3849,28 @@
libc_type=klibc
elif check_cpp_condition sys/cdefs.h "defined __BIONIC__"; then
libc_type=bionic
- add_compat strtod.o strtod=avpriv_strtod
+elif check_cpp_condition sys/brand.h "defined SOLARIS_BRAND_NAME"; then
+ libc_type=solaris
+ add_cppflags -D__EXTENSIONS__ -D_XOPEN_SOURCE=600
fi
-test -n "$libc_type" && enable $libc_type
+test -n "$libc_type" && enable libc_$libc_type
+
+case $libc_type in
+ bionic)
+ add_compat strtod.o strtod=avpriv_strtod
+ ;;
+ msvcrt)
+ add_compat strtod.o strtod=avpriv_strtod
+ add_compat msvcrt/snprintf.o snprintf=avpriv_snprintf \
+ _snprintf=avpriv_snprintf \
+ vsnprintf=avpriv_vsnprintf
+ ;;
+esac
# hacks for compiler/libc/os combinations
-if enabled_all tms470 glibc; then
+if enabled_all tms470 libc_glibc; then
CPPFLAGS="-I${source_path}/compat/tms470 ${CPPFLAGS}"
add_cppflags -D__USER_LABEL_PREFIX__=
add_cppflags -D__builtin_memset=memset
@@ -3768,7 +3878,7 @@
add_cflags -pds=48 # incompatible redefinition of macro
fi
-if enabled_all ccc glibc; then
+if enabled_all ccc libc_glibc; then
add_ldflags -Wl,-z,now # calls to libots crash without this
fi
@@ -4181,17 +4291,17 @@
# do this before the optional library checks as some of them require pthreads
if ! disabled pthreads && ! enabled w32threads && ! enabled os2threads; then
enable pthreads
- if check_func pthread_create; then
+ if check_func pthread_join && check_func pthread_create; then
:
- elif check_func pthread_create -pthread; then
+ elif check_func pthread_join -pthread && check_func pthread_create -pthread; then
add_cflags -pthread
add_extralibs -pthread
- elif check_func pthread_create -pthreads; then
+ elif check_func pthread_join -pthreads && check_func pthread_create -pthreads; then
add_cflags -pthreads
add_extralibs -pthreads
- elif check_func pthread_create -lpthreadGC2; then
+ elif check_func pthread_join -lpthreadGC2 && check_func pthread_create -lpthreadGC2; then
add_extralibs -lpthreadGC2
- elif ! check_lib pthread.h pthread_create -lpthread; then
+ elif ! check_lib pthread.h pthread_join -lpthread && ! check_lib pthread.h pthread_create -lpthread; then
disable pthreads
fi
fi
@@ -4243,7 +4353,7 @@
enabled libfdk_aac && require libfdk_aac fdk-aac/aacenc_lib.h aacEncOpen -lfdk-aac
flite_libs="-lflite_cmu_time_awb -lflite_cmu_us_awb -lflite_cmu_us_kal -lflite_cmu_us_kal16 -lflite_cmu_us_rms -lflite_cmu_us_slt -lflite_usenglish -lflite_cmulex -lflite"
enabled libflite && require2 libflite "flite/flite.h" flite_init $flite_libs
-enabled libfreetype && require_pkg_config freetype2 "ft2build.h freetype/freetype.h" FT_Init_FreeType
+enabled libfreetype && require_libfreetype
enabled libgme && require libgme gme/gme.h gme_new_emu -lgme -lstdc++
enabled libgsm && { for gsm_hdr in "gsm.h" "gsm/gsm.h"; do
check_lib "${gsm_hdr}" gsm_create -lgsm && break;
@@ -4346,8 +4456,8 @@
texi2html --help 2> /dev/null | grep -q 'init-file' && enable texi2html || disable texi2html
makeinfo --version > /dev/null 2>&1 && enable makeinfo || disable makeinfo
-perl --version > /dev/null 2>&1 && enable perl || disable perl
-pod2man --help > /dev/null 2>&1 && enable pod2man || disable pod2man
+perl -v > /dev/null 2>&1 && enable perl || disable perl
+pod2man --help > /dev/null 2>&1 && enable pod2man || disable pod2man
rsync --help 2> /dev/null | grep -q 'contimeout' && enable rsync_contimeout || disable rsync_contimeout
check_header linux/fb.h
@@ -4398,10 +4508,12 @@
die "ERROR: libcdio-paranoia not found"
fi
+check_lib X11/Xlib.h XOpenDisplay -lX11 && enable xlib
+
enabled x11grab &&
-require X11 X11/Xlib.h XOpenDisplay -lX11 &&
require Xext X11/extensions/XShm.h XShmCreateImage -lXext &&
-require Xfixes X11/extensions/Xfixes.h XFixesGetCursorImage -lXfixes
+require Xfixes X11/extensions/Xfixes.h XFixesGetCursorImage -lXfixes &&
+{ enabled xlib || die "ERROR: Xlib not found"; }
enabled vaapi &&
check_lib va/va.h vaInitialize -lva ||
@@ -4411,6 +4523,10 @@
check_cpp_condition vdpau/vdpau.h "defined VDP_DECODER_PROFILE_MPEG4_PART2_ASP" ||
disable vdpau
+enabled vdpau && enabled xlib &&
+ check_lib2 "vdpau/vdpau.h vdpau/vdpau_x11.h" vdp_device_create_x11 -lvdpau &&
+ enable vdpau_x11
+
# Funny iconv installations are not unusual, so check it after all flags have been set
disabled iconv || check_func_headers iconv.h iconv || check_lib2 iconv.h iconv -liconv || disable iconv
@@ -4419,13 +4535,9 @@
# add some useful compiler flags if supported
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
-check_cflags -Wno-pointer-sign
check_cflags -Wwrite-strings
check_cflags -Wtype-limits
check_cflags -Wundef
@@ -4434,11 +4546,26 @@
check_cflags -Wstrict-prototypes
enabled extra_warnings && check_cflags -Winline
+check_disable_warning(){
+ warning_flag=-W${1#-Wno-}
+ test_cflags $warning_flag && add_cflags $1
+}
+
+check_disable_warning -Wno-parentheses
+check_disable_warning -Wno-switch
+check_disable_warning -Wno-format-zero-length
+check_disable_warning -Wno-pointer-sign
+
# add some linker flags
check_ldflags -Wl,--warn-common
check_ldflags -Wl,-rpath-link=libpostproc:libswresample:libswscale:libavfilter:libavdevice:libavformat:libavcodec:libavutil:libavresample
+enabled rpath && add_ldflags -Wl,-rpath=$libdir
test_ldflags -Wl,-Bsymbolic && append SHFLAGS -Wl,-Bsymbolic
+# add some strip flags
+# -wN '..@*' is more selective than -x, but not available everywhere.
+check_stripflags -wN \'..@*\' || check_stripflags -x
+
enabled xmm_clobber_test &&
check_ldflags -Wl,--wrap,avcodec_open2 \
-Wl,--wrap,avcodec_decode_audio4 \
@@ -4532,6 +4659,7 @@
check_cflags -Werror=missing-prototypes
check_cflags -Werror=return-type
check_cflags -Werror=vla
+ enabled extra_warnings || check_disable_warning -Wno-maybe-uninitialized
elif enabled llvm_gcc; then
check_cflags -mllvm -stack-alignment=16
elif enabled clang; then
@@ -4555,7 +4683,7 @@
add_cflags -pds=824 -pds=837
elif enabled pathscale; then
add_cflags -fstrict-overflow -OPT:wrap_around_unsafe_opt=OFF
-elif enabled_any msvc msvc2013 icl; then
+elif enabled_any msvc icl; then
enabled x86_32 && disable aligned_stack
enabled_all x86_32 debug && add_cflags -Oy-
enabled debug && add_ldflags -debug
@@ -4585,6 +4713,8 @@
enabled_any $THREADS_LIST && enable threads
enabled_any $ATOMICS_LIST && enable atomics_native
+enabled threads && ! enabled pthreads && ! enabled atomics_native && die "non pthread threading without atomics not supported, try adding --enable-pthreads or --cpu=i486 or higher if you are on x86"
+
enabled asm || { arch=c; disable $ARCH_LIST $ARCH_EXT_LIST; }
check_deps $CONFIG_LIST \
@@ -4631,6 +4761,10 @@
echo "install prefix $prefix"
echo "source path $source_path"
echo "C compiler $cc"
+if test "$host_cc" != "$cc"; then
+ echo "host C compiler $host_cc"
+fi
+echo "C library $libc_type"
echo "ARCH $arch ($cpu)"
if test "$build_suffix" != ""; then
echo "build suffix $build_suffix"
@@ -4728,7 +4862,7 @@
echo "Creating config.mak, config.h, and doc/config.texi..."
-test -e Makefile || $ln_s "$source_path/Makefile" .
+test -e Makefile || echo "include $source_path/Makefile" > Makefile
enabled stripping || strip="echo skipping strip"
@@ -4785,8 +4919,11 @@
LD_LIB=$LD_LIB
LD_PATH=$LD_PATH
DLLTOOL=$dlltool
+WINDRES=$windres
+DEPWINDRES=$dep_cc
LDFLAGS=$LDFLAGS
SHFLAGS=$(echo $($ldflags_filter $SHFLAGS))
+ASMSTRIPFLAGS=$ASMSTRIPFLAGS
YASMFLAGS=$YASMFLAGS
BUILDSUF=$build_suffix
PROGSSUF=$progs_suffix
@@ -4864,12 +5001,14 @@
#define FFMPEG_CONFIG_H
#define FFMPEG_CONFIGURATION "$(c_escape $FFMPEG_CONFIGURATION)"
#define FFMPEG_LICENSE "$(c_escape $license)"
+#define CONFIG_THIS_YEAR 2013
#define FFMPEG_DATADIR "$(eval c_escape $datadir)"
#define AVCONV_DATADIR "$(eval c_escape $datadir)"
#define CC_IDENT "$(c_escape ${cc_ident:-Unknown compiler})"
#define av_restrict $_restrict
#define EXTERN_PREFIX "${extern_prefix}"
#define EXTERN_ASM ${extern_prefix}
+#define BUILDSUF "$build_suffix"
#define SLIBSUF "$SLIBSUF"
#define HAVE_MMX2 HAVE_MMXEXT
EOF
@@ -4946,7 +5085,7 @@
Requires: $(enabled shared || echo $requires)
Requires.private: $(enabled shared && echo $requires)
Conflicts:
-Libs: -L\${libdir} -l${shortname} $(enabled shared || echo $libs)
+Libs: -L\${libdir} $(enabled rpath && echo "-Wl,-rpath,\${libdir}") -l${shortname} $(enabled shared || echo $libs)
Libs.private: $(enabled shared && echo $libs)
Cflags: -I\${includedir}
EOF
@@ -4965,7 +5104,7 @@
Version: $version
Requires: $requires
Conflicts:
-Libs: -L\${libdir} -l${shortname} $(enabled shared || echo $libs)
+Libs: -L\${libdir} -Wl,-rpath,\${libdir} -l${shortname} $(enabled shared || echo $libs)
Cflags: -I\${includedir}
EOF
}
diff --git a/doc/APIchanges b/doc/APIchanges
index f45c663..c3f4c6b 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -14,6 +14,61 @@
API changes, most recent first:
+2013-12-xx - xxxxxxx - lavu 52.57.100 - opencl.h
+ Add av_opencl_benchmark() function.
+
+2013-11-xx - xxxxxxx - lavu 52.56.100 - ffversion.h
+ Moves version.h to libavutil/ffversion.h.
+ Install ffversion.h and make it public.
+
+2013-11-xx - xxxxxxx- - lavu 52.20.0 - frame.h
+ Add AV_FRAME_DATA_STEREO3D value to the AVFrameSideDataType enum and
+ stereo3d.h API, that identify codec-independent stereo3d information.
+
+2013-11-xx - xxxxxxx- - lavu 52.19.0 - frame.h
+ Add AV_FRAME_DATA_A53_CC value to the AVFrameSideDataType enum, which
+ identifies ATSC A53 Part 4 Closed Captions data.
+
+2013-11-XX - xxxxxxx - lavu 52.54.100 - avstring.h
+ Add av_utf8_decode() function.
+
+2013-11-xx - xxxxxxx - lavc 55.44.100 - avcodec.h
+ Add av_packet_{un,}pack_dictionary()
+ Add AV_PKT_METADATA_UPDATE side data type, used to transmit key/value
+ strings between a stream and the application.
+
+2013-11-xx - xxxxxxx - lavu 52.18.0 - mem.h
+ Move av_fast_malloc() and av_fast_realloc() for libavcodec to libavutil.
+
+2013-10-xx - xxxxxxx - lavc 55.27.0 - avcodec.h
+ Deprecate AVCodecContext.error_rate, it is replaced by the 'error_rate'
+ private option of the mpegvideo encoder family.
+
+2013-11-xx - xxxxxxx - lavc 55.26.0 - vdpau.h
+ Add av_vdpau_get_profile().
+ Add av_vdpau_alloc_context(). This function must from now on be
+ used for allocating AVVDPAUContext.
+
+2013-11-xx - xxxxxxx - lavc 55.41.100 / 55.25.0 - avcodec.h
+ lavu 52.51.100 - frame.h
+ Add ITU-R BT.2020 and other not yet included values to color primaries,
+ transfer characteristics and colorspaces.
+
+2013-11-04 - xxxxxxx - lavu 52.50.100 - avutil.h
+ Add av_fopen_utf8()
+
+2013-08-xx - xxxxxxx - lavu 52.17.0 - avframe.h
+ Add AVFrame.flags and AV_FRAME_FLAG_CORRUPT.
+
+2013-10-27 - xxxxxxx - lavc 55.39.100 - avcodec.h
+ Add CODEC_CAP_DELAY support to avcodec_decode_subtitle2.
+
+2013-10-27 - xxxxxxx - lavu 52.48.100 - parseutils.h
+ Add av_get_known_color_name().
+
+2013-10-17 - xxxxxxx - lavu 52.47.100 - opt.h
+ Add AV_OPT_TYPE_CHANNEL_LAYOUT and channel layout option handlers
+ av_opt_get_channel_layout() and av_opt_set_channel_layout().
2013-10-xx - xxxxxxx -libswscale 2.5.101 - options.c
Change default scaler to bicubic
@@ -84,7 +139,7 @@
2013-06-24 - af5f9c0 / 95d5246 - lavc 55.17.100 / 55.10.0 - avcodec.h
Add MPEG-2 AAC profiles
-2013-06-25 - 95d5246 - lavf 55.10.100 - avformat.h
+2013-06-25 - af5f9c0 / 95d5246 - lavf 55.10.100 - avformat.h
Add AV_DISPOSITION_* flags to indicate text track kind.
2013-06-15 - 99b8cd0 - lavu 52.36.100
@@ -452,7 +507,7 @@
2012-07-29 - 7c26761 / 681ed00 - lavf 54.22.100 / 54.13.0 - avformat.h
Add AVFMT_FLAG_NOBUFFER for low latency use cases.
-2012-07-10 - f3e5e6f - lavu 51.37.0
+2012-07-10 - fbe0245 / f3e5e6f - lavu 51.65.100 / 51.37.0
Add av_malloc_array() and av_mallocz_array()
2012-06-22 - e847f41 / d3d3a32 - lavu 51.61.100 / 51.34.0
diff --git a/doc/Makefile b/doc/Makefile
index 7415899..26bd9f5 100644
--- a/doc/Makefile
+++ b/doc/Makefile
@@ -14,11 +14,11 @@
COMPONENTS-$(CONFIG_AVDEVICE) += ffmpeg-devices
COMPONENTS-$(CONFIG_AVFILTER) += ffmpeg-filters
-MANPAGES1 = $(PROGS-yes:%=doc/%.1) $(PROGS-yes:%=doc/%-all.1) $(COMPONENTS-yes:%=doc/%.1)
+MANPAGES1 = $(AVPROGS-yes:%=doc/%.1) $(AVPROGS-yes:%=doc/%-all.1) $(COMPONENTS-yes:%=doc/%.1)
MANPAGES3 = $(LIBRARIES-yes:%=doc/%.3)
MANPAGES = $(MANPAGES1) $(MANPAGES3)
-PODPAGES = $(PROGS-yes:%=doc/%.pod) $(PROGS-yes:%=doc/%-all.pod) $(COMPONENTS-yes:%=doc/%.pod) $(LIBRARIES-yes:%=doc/%.pod)
-HTMLPAGES = $(PROGS-yes:%=doc/%.html) $(PROGS-yes:%=doc/%-all.html) $(COMPONENTS-yes:%=doc/%.html) $(LIBRARIES-yes:%=doc/%.html) \
+PODPAGES = $(AVPROGS-yes:%=doc/%.pod) $(AVPROGS-yes:%=doc/%-all.pod) $(COMPONENTS-yes:%=doc/%.pod) $(LIBRARIES-yes:%=doc/%.pod)
+HTMLPAGES = $(AVPROGS-yes:%=doc/%.html) $(AVPROGS-yes:%=doc/%-all.html) $(COMPONENTS-yes:%=doc/%.html) $(LIBRARIES-yes:%=doc/%.html) \
doc/developer.html \
doc/faq.html \
doc/fate.html \
@@ -36,6 +36,22 @@
DOCS-$(CONFIG_TXTPAGES) += $(TXTPAGES)
DOCS = $(DOCS-yes)
+DOC_EXAMPLES-$(CONFIG_DECODING_ENCODING_EXAMPLE) += decoding_encoding
+DOC_EXAMPLES-$(CONFIG_DEMUXING_DECODING_EXAMPLE) += demuxing_decoding
+DOC_EXAMPLES-$(CONFIG_FILTERING_AUDIO_EXAMPLE) += filtering_audio
+DOC_EXAMPLES-$(CONFIG_FILTERING_VIDEO_EXAMPLE) += filtering_video
+DOC_EXAMPLES-$(CONFIG_METADATA_EXAMPLE) += metadata
+DOC_EXAMPLES-$(CONFIG_MUXING_EXAMPLE) += muxing
+DOC_EXAMPLES-$(CONFIG_RESAMPLING_AUDIO_EXAMPLE) += resampling_audio
+DOC_EXAMPLES-$(CONFIG_SCALING_VIDEO_EXAMPLE) += scaling_video
+DOC_EXAMPLES-$(CONFIG_TRANSCODE_AAC_EXAMPLE) += transcode_aac
+ALL_DOC_EXAMPLES_LIST = $(DOC_EXAMPLES-) $(DOC_EXAMPLES-yes)
+
+DOC_EXAMPLES := $(DOC_EXAMPLES-yes:%=doc/examples/%$(PROGSSUF)$(EXESUF))
+ALL_DOC_EXAMPLES := $(ALL_DOC_EXAMPLES_LIST:%=doc/examples/%$(PROGSSUF)$(EXESUF))
+ALL_DOC_EXAMPLES_G := $(ALL_DOC_EXAMPLES_LIST:%=doc/examples/%$(PROGSSUF)_g$(EXESUF))
+PROGS += $(DOC_EXAMPLES)
+
all-$(CONFIG_DOC): doc
doc: documentation
@@ -43,7 +59,9 @@
apidoc: doc/doxy/html
documentation: $(DOCS)
-TEXIDEP = awk '/^@(verbatim)?include/ { printf "$@: $(@D)/%s\n", $$2 }' <$< >$(@:%=%.d)
+examples: $(DOC_EXAMPLES)
+
+TEXIDEP = perl $(SRC_PATH)/doc/texidep.pl $(SRC_PATH) $< $@ >$(@:%=%.d)
doc/%.txt: TAG = TXT
doc/%.txt: doc/%.texi
@@ -84,6 +102,8 @@
$(M)pod2man --section=3 --center=" " --release=" " $< > $@
$(DOCS) doc/doxy/html: | doc/
+$(DOC_EXAMPLES:%=%.o): | doc/examples
+OBJDIRS += doc/examples
doc/doxy/html: $(SRC_PATH)/doc/Doxyfile $(INSTHEADERS)
$(M)$(SRC_PATH)/doc/doxy-wrapper.sh $(SRC_PATH) $^
@@ -120,16 +140,21 @@
$(RM) -r "$(DOCDIR)"
uninstall-man:
- $(RM) $(addprefix "$(MANDIR)/man1/",$(MANPAGES1))
- $(RM) $(addprefix "$(MANDIR)/man3/",$(MANPAGES3))
+ $(RM) $(addprefix "$(MANDIR)/man1/",$(AVPROGS-yes:%=%.1) $(AVPROGS-yes:%=%-all.1) $(COMPONENTS-yes:%=%.1))
+ $(RM) $(addprefix "$(MANDIR)/man3/",$(LIBRARIES-yes:%=%.3))
clean:: docclean
distclean:: docclean
$(RM) doc/config.texi
-docclean:
- $(RM) $(TXTPAGES) doc/*.html doc/*.pod doc/*.1 doc/*.3 $(CLEANSUFFIXES:%=doc/%) doc/avoptions_*.texi
+examplesclean:
+ $(RM) $(ALL_DOC_EXAMPLES) $(ALL_DOC_EXAMPLES_G)
+ $(RM) $(CLEANSUFFIXES:%=doc/examples/%)
+
+docclean: examplesclean
+ $(RM) $(CLEANSUFFIXES:%=doc/%)
+ $(RM) $(TXTPAGES) doc/*.html doc/*.pod doc/*.1 doc/*.3 doc/avoptions_*.texi
$(RM) -r doc/doxy/html
-include $(wildcard $(DOCS:%=%.d))
diff --git a/doc/RELEASE_NOTES b/doc/RELEASE_NOTES
index 28a1c05..fae3a2b 100644
--- a/doc/RELEASE_NOTES
+++ b/doc/RELEASE_NOTES
@@ -1,7 +1,7 @@
Release Notes
=============
-* 2.0 "Nameless" July, 2013
+* 2.1 "Fourier" October, 2013
General notes
diff --git a/doc/avutil.txt b/doc/avutil.txt
deleted file mode 100644
index 0847683..0000000
--- a/doc/avutil.txt
+++ /dev/null
@@ -1,36 +0,0 @@
-AVUtil
-======
-libavutil is a small lightweight library of generally useful functions.
-It is not a library for code needed by both libavcodec and libavformat.
-
-
-Overview:
-=========
-adler32.c adler32 checksum
-aes.c AES encryption and decryption
-fifo.c resizeable first in first out buffer
-intfloat_readwrite.c portable reading and writing of floating point values
-log.c "printf" with context and level
-md5.c MD5 Message-Digest Algorithm
-rational.c code to perform exact calculations with rational numbers
-tree.c generic AVL tree
-crc.c generic CRC checksumming code
-integer.c 128bit integer math
-lls.c
-mathematics.c greatest common divisor, integer sqrt, integer log2, ...
-mem.c memory allocation routines with guaranteed alignment
-
-Headers:
-bswap.h big/little/native-endian conversion code
-x86_cpu.h a few useful macros for unifying x86-64 and x86-32 code
-avutil.h
-common.h
-intreadwrite.h reading and writing of unaligned big/little/native-endian integers
-
-
-Goals:
-======
-* Modular (few interdependencies and the possibility of disabling individual parts during ./configure)
-* Small (source and object)
-* Efficient (low CPU and memory usage)
-* Useful (avoid useless features almost no one needs)
diff --git a/doc/codecs.texi b/doc/codecs.texi
index 74dd775..1606f6c 100644
--- a/doc/codecs.texi
+++ b/doc/codecs.texi
@@ -172,7 +172,13 @@
Set max difference between the quantizer scale (VBR).
@item bf @var{integer} (@emph{encoding,video})
-Set max number of B frames.
+Set max number of B frames between non-B-frames.
+
+Must be an integer between -1 and 16. 0 means that B-frames are
+disabled. If a value of -1 is used, it will choose an automatic value
+depending on the encoder.
+
+Default value is 0.
@item b_qfactor @var{float} (@emph{encoding,video})
Set qp factor between P and B frames.
@@ -1076,7 +1082,9 @@
@end table
@item skip_alpha @var{integer} (@emph{decoding,video})
-causes alpha plane not to be decoded, like "gray" which skips chroma.
+Set to 1 to disable processing alpha (transparency). This works like the
+@samp{gray} flag in the @option{flags} option which skips chroma information
+instead of alpha. Default is 0.
@end table
@c man end CODEC OPTIONS
diff --git a/doc/default.css b/doc/default.css
index e6c6cfe..bf50200 100644
--- a/doc/default.css
+++ b/doc/default.css
@@ -17,8 +17,8 @@
}
#banner img {
- padding-bottom: 1px;
- padding-top: 5px;
+ margin-bottom: 1px;
+ margin-top: 5px;
}
#body {
diff --git a/doc/developer.texi b/doc/developer.texi
index 71f4978..9c72c44 100644
--- a/doc/developer.texi
+++ b/doc/developer.texi
@@ -386,6 +386,12 @@
be changed to not generate a warning unless that causes a slowdown
or obfuscates the code.
+@item
+Make sure that no parts of the codebase that you maintain are missing from the
+@file{MAINTAINERS} file. If something that you want to maintain is missing add it with
+your name after it.
+If at some point you no longer want to maintain some code, then please help
+finding a new maintainer and also don't forget updating the @file{MAINTAINERS} file.
@end enumerate
We think our rules are not too hard. If you have comments, contact us.
diff --git a/doc/doxy-wrapper.sh b/doc/doxy-wrapper.sh
index 6650e38..a6c54dd 100755
--- a/doc/doxy-wrapper.sh
+++ b/doc/doxy-wrapper.sh
@@ -8,7 +8,4 @@
doxygen - <<EOF
@INCLUDE = ${DOXYFILE}
INPUT = $@
-HTML_HEADER = ${SRC_PATH}/doc/doxy/header.html
-HTML_FOOTER = ${SRC_PATH}/doc/doxy/footer.html
-HTML_STYLESHEET = ${SRC_PATH}/doc/doxy/doxy_stylesheet.css
EOF
diff --git a/doc/encoders.texi b/doc/encoders.texi
index a96c1fc..a93edb4 100644
--- a/doc/encoders.texi
+++ b/doc/encoders.texi
@@ -38,8 +38,8 @@
time. For a more stable AAC encoder, see @ref{libvo-aacenc}. However, be warned
that it has a worse quality reported by some users.
-@c Comment this out until somebody writes the respective documentation.
-@c See also @ref{libfaac}, @ref{libaacplus}, and @ref{libfdk-aac-enc}.
+@c todo @ref{libaacplus}
+See also @ref{libfdk-aac-enc,,libfdk_aac} and @ref{libfaac}.
@subsection Options
@@ -494,6 +494,283 @@
@end table
+@anchor{libfaac}
+@section libfaac
+
+libfaac AAC (Advanced Audio Coding) encoder wrapper.
+
+Requires the presence of the libfaac headers and library during
+configuration. You need to explicitly configure the build with
+@code{--enable-libfaac --enable-nonfree}.
+
+This encoder is considered to be of higher quality with respect to the
+@ref{aacenc,,the native experimental FFmpeg AAC encoder}.
+
+For more information see the libfaac project at
+@url{http://www.audiocoding.com/faac.html/}.
+
+@subsection Options
+
+The following shared FFmpeg codec options are recognized.
+
+The following options are supported by the libfaac wrapper. The
+@command{faac}-equivalent of the options are listed in parentheses.
+
+@table @option
+@item b (@emph{-b})
+Set bit rate in bits/s for ABR (Average Bit Rate) mode. If the bit rate
+is not explicitly specified, it is automatically set to a suitable
+value depending on the selected profile. @command{faac} bitrate is
+expressed in kilobits/s.
+
+Note that libfaac does not support CBR (Constant Bit Rate) but only
+ABR (Average Bit Rate).
+
+If VBR mode is enabled this option is ignored.
+
+@item ar (@emph{-R})
+Set audio sampling rate (in Hz).
+
+@item ac (@emph{-c})
+Set the number of audio channels.
+
+@item cutoff (@emph{-C})
+Set cutoff frequency. If not specified (or explicitly set to 0) it
+will use a value automatically computed by the library. Default value
+is 0.
+
+@item profile
+Set audio profile.
+
+The following profiles are recognized:
+@table @samp
+@item aac_main
+Main AAC (Main)
+
+@item aac_low
+Low Complexity AAC (LC)
+
+@item aac_ssr
+Scalable Sample Rate (SSR)
+
+@item aac_ltp
+Long Term Prediction (LTP)
+@end table
+
+If not specified it is set to @samp{aac_low}.
+
+@item flags +qscale
+Set constant quality VBR (Variable Bit Rate) mode.
+
+@item global_quality
+Set quality in VBR mode as an integer number of lambda units.
+
+Only relevant when VBR mode is enabled with @code{flags +qscale}. The
+value is converted to QP units by dividing it by @code{FF_QP2LAMBDA},
+and used to set the quality value used by libfaac. A reasonable range
+for the option value in QP units is [10-500], the higher the value the
+higher the quality.
+
+@item q (@emph{-q})
+Enable VBR mode when set to a non-negative value, and set constant
+quality value as a double floating point value in QP units.
+
+The value sets the quality value used by libfaac. A reasonable range
+for the option value is [10-500], the higher the value the higher the
+quality.
+
+This option is valid only using the @command{ffmpeg} command-line
+tool. For library interface users, use @option{global_quality}.
+@end table
+
+@subsection Examples
+
+@itemize
+@item
+Use @command{ffmpeg} to convert an audio file to ABR 128 kbps AAC in an M4A (MP4)
+container:
+@example
+ffmpeg -i input.wav -codec:a libfaac -b:a 128k -output.m4a
+@end example
+
+@item
+Use @command{ffmpeg} to convert an audio file to VBR AAC, using the
+LTP AAC profile:
+@example
+ffmpeg -i input.wav -c:a libfaac -profile:a aac_ltp -q:a 100 output.m4a
+@end example
+@end itemize
+
+@anchor{libfdk-aac-enc}
+@section libfdk_aac
+
+libfdk-aac AAC (Advanced Audio Coding) encoder wrapper.
+
+The libfdk-aac library is based on the Fraunhofer FDK AAC code from
+the Android project.
+
+Requires the presence of the libfdk-aac headers and library during
+configuration. You need to explicitly configure the build with
+@code{--enable-libfdk-aac}. The library is also incompatible with GPL,
+so if you allow the use of GPL, you should configure with
+@code{--enable-gpl --enable-nonfree --enable-libfdk-aac}.
+
+This encoder is considered to be of higher quality with respect to
+both @ref{aacenc,,the native experimental FFmpeg AAC encoder} and
+@ref{libfaac}.
+
+VBR encoding, enabled through the @option{vbr} or @option{flags
++qscale} options, is experimental and only works with some
+combinations of parameters.
+
+For more information see the fdk-aac project at
+@url{http://sourceforge.net/p/opencore-amr/fdk-aac/}.
+
+@subsection Options
+
+The following options are mapped on the shared FFmpeg codec options.
+
+@table @option
+@item b
+Set bit rate in bits/s. If the bitrate is not explicitly specified, it
+is automatically set to a suitable value depending on the selected
+profile.
+
+In case VBR mode is enabled the option is ignored.
+
+@item ar
+Set audio sampling rate (in Hz).
+
+@item channels
+Set the number of audio channels.
+
+@item flags +qscale
+Enable fixed quality, VBR (Variable Bit Rate) mode.
+Note that VBR is implicitly enabled when the @option{vbr} value is
+positive.
+
+@item cutoff
+Set cutoff frequency. If not specified (or explicitly set to 0) it
+will use a value automatically computed by the library. Default value
+is 0.
+
+@item profile
+Set audio profile.
+
+The following profiles are recognized:
+@table @samp
+@item aac_low
+Low Complexity AAC (LC)
+
+@item aac_he
+High Efficiency AAC (HE-AAC)
+
+@item aac_he_v2
+High Efficiency AAC version 2 (HE-AACv2)
+
+@item aac_ld
+Low Delay AAC (LD)
+
+@item aac_eld
+Enhanced Low Delay AAC (ELD)
+@end table
+
+If not specified it is set to @samp{aac_low}.
+@end table
+
+The following are private options of the libfdk_aac encoder.
+
+@table @option
+@item afterburner
+Enable afterburner feature if set to 1, disabled if set to 0. This
+improves the quality but also the required processing power.
+
+Default value is 1.
+
+@item eld_sbr
+Enable SBR (Spectral Band Replication) for ELD if set to 1, disabled
+if set to 0.
+
+Default value is 0.
+
+@item signaling
+Set SBR/PS signaling style.
+
+It can assume one of the following values:
+@table @samp
+@item default
+choose signaling implicitly (explicit hierarchical by default,
+implicit if global header is disabled)
+
+@item implicit
+implicit backwards compatible signaling
+
+@item explicit_sbr
+explicit SBR, implicit PS signaling
+
+@item explicit_hierarchical
+explicit hierarchical signaling
+@end table
+
+Default value is @samp{default}.
+
+@item latm
+Output LATM/LOAS encapsulated data if set to 1, disabled if set to 0.
+
+Default value is 0.
+
+@item header_period
+Set StreamMuxConfig and PCE repetition period (in frames) for sending
+in-band configuration buffers within LATM/LOAS transport layer.
+
+Must be a 16-bits non-negative integer.
+
+Default value is 0.
+
+@item vbr
+Set VBR mode, from 1 to 5. 1 is lowest quality (though still pretty
+good) and 5 is highest quality. A value of 0 will disable VBR, and CBR
+(Constant Bit Rate) is enabled.
+
+Currently only the @samp{aac_low} profile supports VBR encoding.
+
+VBR modes 1-5 correspond to roughly the following average bit rates:
+
+@table @samp
+@item 1
+32 kbps/channel
+@item 2
+40 kbps/channel
+@item 3
+48-56 kbps/channel
+@item 4
+64 kbps/channel
+@item 5
+about 80-96 kbps/channel
+@end table
+
+Default value is 0.
+@end table
+
+@subsection Examples
+
+@itemize
+@item
+Use @command{ffmpeg} to convert an audio file to VBR AAC in an M4A (MP4)
+container:
+@example
+ffmpeg -i input.wav -codec:a libfdk_aac -vbr 3 output.m4a
+@end example
+
+@item
+Use @command{ffmpeg} to convert an audio file to CBR 64k kbps AAC, using the
+High-Efficiency AAC profile:
+@example
+ffmpeg -i input.wav -c:a libfdk_aac -profile:a aac_he -b:a 64k output.m4a
+@end example
+@end itemize
+
+@anchor{libmp3lame}
@section libmp3lame
LAME (Lame Ain't an MP3 Encoder) MP3 encoder wrapper.
@@ -502,6 +779,9 @@
configuration. You need to explicitly configure the build with
@code{--enable-libmp3lame}.
+See @ref{libshine} for a fixed-point MP3 encoder, although with a
+lower quality.
+
@subsection Options
The following options are supported by the libmp3lame wrapper. The
@@ -509,7 +789,7 @@
@table @option
@item b (@emph{-b})
-Set bitrate expressed in bits/s for CBR. LAME @code{bitrate} is
+Set bitrate expressed in bits/s for CBR or ABR. LAME @code{bitrate} is
expressed in kilobits/s.
@item q (@emph{-V})
@@ -531,6 +811,11 @@
Enable the encoder to use (on a frame by frame basis) either L/R
stereo or mid/side stereo. Default value is 1.
+@item abr (@emph{--abr})
+Enable the encoder to use ABR when set to 1. The @command{lame}
+@option{--abr} sets the target bitrate, while this options only
+tells FFmpeg to use ABR still relies on @option{b} to set bitrate.
+
@end table
@section libopencore-amrnb
@@ -570,6 +855,42 @@
@end table
+@anchor{libshine}
+@section libshine
+
+Shine Fixed-Point MP3 encoder wrapper.
+
+Shine is a fixed-point MP3 encoder. It has a far better performance on
+platforms without an FPU, e.g. armel CPUs, and some phones and tablets.
+However, as it is more targeted on performance than quality, it is not on par
+with LAME and other production-grade encoders quality-wise. Also, according to
+the project's homepage, this encoder may not be free of bugs as the code was
+written a long time ago and the project was dead for at least 5 years.
+
+This encoder only supports stereo and mono input. This is also CBR-only.
+
+The original project (last updated in early 2007) is at
+@url{http://sourceforge.net/projects/libshine-fxp/}. We only support the
+updated fork by the Savonet/Liquidsoap project at @url{https://github.com/savonet/shine}.
+
+Requires the presence of the libshine headers and library during
+configuration. You need to explicitly configure the build with
+@code{--enable-libshine}.
+
+See also @ref{libmp3lame}.
+
+@subsection Options
+
+The following options are supported by the libshine wrapper. The
+@command{shineenc}-equivalent of the options are listed in parentheses.
+
+@table @option
+@item b (@emph{-b})
+Set bitrate expressed in bits/s for CBR. @command{shineenc} @option{-b} option
+is expressed in kilobits/s.
+
+@end table
+
@section libtwolame
TwoLAME MP2 encoder wrapper.
@@ -746,7 +1067,7 @@
argument must be exactly the following: 2.5, 5, 10, 20, 40, 60. Smaller
frame sizes achieve lower latency but less quality at a given bitrate.
Sizes greater than 20ms are only interesting at fairly low bitrates.
-The default of FFmpeg is 10ms, but is 20ms in @command{opusenc}.
+The default is 20ms.
@item packet_loss (@emph{expect-loss})
Set expected packet loss percentage. The default is 0.
@@ -771,6 +1092,58 @@
@end table
+@section libvorbis
+
+libvorbis encoder wrapper.
+
+Requires the presence of the libvorbisenc headers and library during
+configuration. You need to explicitly configure the build with
+@code{--enable-libvorbis}.
+
+@subsection Options
+
+The following options are supported by the libvorbis wrapper. The
+@command{oggenc}-equivalent of the options are listed in parentheses.
+
+To get a more accurate and extensive documentation of the libvorbis
+options, consult the libvorbisenc's and @command{oggenc}'s documentations.
+See @url{http://xiph.org/vorbis/},
+@url{http://wiki.xiph.org/Vorbis-tools}, and oggenc(1).
+
+@table @option
+@item b (@emph{-b})
+Set bitrate expressed in bits/s for ABR. @command{oggenc} @option{-b} is
+expressed in kilobits/s.
+
+@item q (@emph{-q})
+Set constant quality setting for VBR. The value should be a float
+number in the range of -1.0 to 10.0. The higher the value, the better
+the quality. The default value is @samp{3.0}.
+
+This option is valid only using the @command{ffmpeg} command-line tool.
+For library interface users, use @option{global_quality}.
+
+@item cutoff (@emph{--advanced-encode-option lowpass_frequency=N})
+Set cutoff bandwidth in Hz, a value of 0 disables cutoff. @command{oggenc}'s
+related option is expressed in kHz. The default value is @samp{0} (cutoff
+disabled).
+
+@item minrate (@emph{-m})
+Set minimum bitrate expressed in bits/s. @command{oggenc} @option{-m} is
+expressed in kilobits/s.
+
+@item maxrate (@emph{-M})
+Set maximum bitrate expressed in bits/s. @command{oggenc} @option{-M} is
+expressed in kilobits/s. This only has effect on ABR mode.
+
+@item iblock (@emph{--advanced-encode-option impulse_noisetune=N})
+Set noise floor bias for impulse blocks. The value is a float number from
+-15.0 to 0.0. A negative bias instructs the encoder to pay special attention
+to the crispness of transients in the encoded audio. The tradeoff for better
+transient response is a higher bitrate.
+
+@end table
+
@section libwavpack
A wrapper providing WavPack encoding through libwavpack.
@@ -810,12 +1183,15 @@
@section libtheora
-Theora format supported through libtheora.
+libtheora Theora encoder wrapper.
Requires the presence of the libtheora headers and library during
configuration. You need to explicitly configure the build with
@code{--enable-libtheora}.
+For more informations about the libtheora project see
+@url{http://www.theora.org/}.
+
@subsection Options
The following global options are mapped to internal libtheora options
@@ -823,11 +1199,11 @@
@table @option
@item b
-Set the video bitrate, only works if the @code{qscale} flag in
-@option{flags} is not enabled.
+Set the video bitrate in bit/s for CBR (Constant Bit Rate) mode. In
+case VBR (Variable Bit Rate) mode is enabled this option is ignored.
@item flags
-Used to enable constant quality mode encoding through the
+Used to enable constant quality mode (VBR) encoding through the
@option{qscale} flag, and to enable the @code{pass1} and @code{pass2}
modes.
@@ -835,19 +1211,41 @@
Set the GOP size.
@item global_quality
-Set the global quality in lambda units, only works if the
-@code{qscale} flag in @option{flags} is enabled. The value is clipped
-in the [0 - 10*@code{FF_QP2LAMBDA}] range, and then multiplied for 6.3
-to get a value in the native libtheora range [0-63]. A higher value
-corresponds to a higher quality.
+Set the global quality as an integer in lambda units.
-For example, to set maximum constant quality encoding with
-@command{ffmpeg}:
-@example
-ffmpeg -i INPUT -flags:v qscale -global_quality:v "10*QP2LAMBDA" -codec:v libtheora OUTPUT.ogg
-@end example
+Only relevant when VBR mode is enabled with @code{flags +qscale}. The
+value is converted to QP units by dividing it by @code{FF_QP2LAMBDA},
+clipped in the [0 - 10] range, and then multiplied by 6.3 to get a
+value in the native libtheora range [0-63]. A higher value corresponds
+to a higher quality.
+
+@item q
+Enable VBR mode when set to a non-negative value, and set constant
+quality value as a double floating point value in QP units.
+
+The value is clipped in the [0-10] range, and then multiplied by 6.3
+to get a value in the native libtheora range [0-63].
+
+This option is valid only using the @command{ffmpeg} command-line
+tool. For library interface users, use @option{global_quality}.
@end table
+@subsection Examples
+
+@itemize
+@item
+Set maximum constant quality (VBR) encoding with @command{ffmpeg}:
+@example
+ffmpeg -i INPUT -codec:v libtheora -q:v 10 OUTPUT.ogg
+@end example
+
+@item
+Use @command{ffmpeg} to convert a CBR 1000 kbps Theora video stream:
+@example
+ffmpeg -i INPUT -codec:v libtheora -b:v 1000k OUTPUT.ogg
+@end example
+@end itemize
+
@section libvpx
VP8 format supported through libvpx.
diff --git a/doc/examples/Makefile b/doc/examples/Makefile
index 3d698cc..f085532 100644
--- a/doc/examples/Makefile
+++ b/doc/examples/Makefile
@@ -12,13 +12,14 @@
LDLIBS := $(shell pkg-config --libs $(FFMPEG_LIBS)) $(LDLIBS)
EXAMPLES= decoding_encoding \
- demuxing \
+ demuxing_decoding \
filtering_video \
filtering_audio \
metadata \
muxing \
resampling_audio \
scaling_video \
+ transcode_aac \
OBJS=$(addsuffix .o,$(EXAMPLES))
diff --git a/doc/examples/README b/doc/examples/README
index cb40881..c1ce619 100644
--- a/doc/examples/README
+++ b/doc/examples/README
@@ -5,14 +5,19 @@
that you have them installed and working on your system.
-1) Build the installed examples in a generic read/write user directory
+Method 1: build the installed examples in a generic read/write user directory
Copy to a read/write user directory and just use "make", it will link
to the libraries on your system, assuming the PKG_CONFIG_PATH is
correctly configured.
-2) Build the examples in-tree
+Method 2: build the examples in-tree
Assuming you are in the source FFmpeg checkout directory, you need to build
-FFmpeg (no need to make install in any prefix). Then you can go into
-doc/examples and run a command such as PKG_CONFIG_PATH=pc-uninstalled make.
+FFmpeg (no need to make install in any prefix). Then just run "make examples".
+This will build the examples using the FFmpeg build system. You can clean those
+examples using "make examplesclean"
+
+If you want to try the dedicated Makefile examples (to emulate the first
+method), go into doc/examples and run a command such as
+PKG_CONFIG_PATH=pc-uninstalled make.
diff --git a/doc/examples/decoding_encoding.c b/doc/examples/decoding_encoding.c
index 976b611..99aeb1c 100644
--- a/doc/examples/decoding_encoding.c
+++ b/doc/examples/decoding_encoding.c
@@ -156,7 +156,7 @@
}
/* frame containing input raw audio */
- frame = avcodec_alloc_frame();
+ frame = av_frame_alloc();
if (!frame) {
fprintf(stderr, "Could not allocate audio frame\n");
exit(1);
@@ -287,7 +287,7 @@
int got_frame = 0;
if (!decoded_frame) {
- if (!(decoded_frame = avcodec_alloc_frame())) {
+ if (!(decoded_frame = av_frame_alloc())) {
fprintf(stderr, "Could not allocate audio frame\n");
exit(1);
}
@@ -386,7 +386,7 @@
exit(1);
}
- frame = avcodec_alloc_frame();
+ frame = av_frame_alloc();
if (!frame) {
fprintf(stderr, "Could not allocate video frame\n");
exit(1);
@@ -565,7 +565,7 @@
exit(1);
}
- frame = avcodec_alloc_frame();
+ frame = av_frame_alloc();
if (!frame) {
fprintf(stderr, "Could not allocate video frame\n");
exit(1);
diff --git a/doc/examples/demuxing.c b/doc/examples/demuxing_decoding.c
similarity index 81%
rename from doc/examples/demuxing.c
rename to doc/examples/demuxing_decoding.c
index e459cf0..1b5a989 100644
--- a/doc/examples/demuxing.c
+++ b/doc/examples/demuxing_decoding.c
@@ -22,11 +22,11 @@
/**
* @file
- * libavformat demuxing API use example.
+ * Demuxing and decoding example.
*
* Show how to use the libavformat and libavcodec API to demux and
* decode audio and video data.
- * @example doc/examples/demuxing.c
+ * @example doc/examples/demuxing_decoding.c
*/
#include <libavutil/imgutils.h>
@@ -53,11 +53,25 @@
static int video_frame_count = 0;
static int audio_frame_count = 0;
+/* The different ways of decoding and managing data memory. You are not
+ * supposed to support all the modes in your application but pick the one most
+ * appropriate to your needs. Look for the use of api_mode in this example to
+ * see what are the differences of API usage between them */
+enum {
+ API_MODE_OLD = 0, /* old method, deprecated */
+ API_MODE_NEW_API_REF_COUNT = 1, /* new method, using the frame reference counting */
+ API_MODE_NEW_API_NO_REF_COUNT = 2, /* new method, without reference counting */
+};
+
+static int api_mode = API_MODE_OLD;
+
static int decode_packet(int *got_frame, int cached)
{
int ret = 0;
int decoded = pkt.size;
+ *got_frame = 0;
+
if (pkt.stream_index == video_stream_idx) {
/* decode video frame */
ret = avcodec_decode_video2(video_dec_ctx, frame, got_frame, &pkt);
@@ -113,6 +127,11 @@
}
}
+ /* If we use the new API with reference counting, we own the data and need
+ * to de-reference it when we don't use it anymore */
+ if (*got_frame && api_mode == API_MODE_NEW_API_REF_COUNT)
+ av_frame_unref(frame);
+
return decoded;
}
@@ -123,6 +142,7 @@
AVStream *st;
AVCodecContext *dec_ctx = NULL;
AVCodec *dec = NULL;
+ AVDictionary *opts = NULL;
ret = av_find_best_stream(fmt_ctx, type, -1, -1, NULL, 0);
if (ret < 0) {
@@ -142,7 +162,10 @@
return ret;
}
- if ((ret = avcodec_open2(dec_ctx, dec, NULL)) < 0) {
+ /* Init the decoders, with or without reference counting */
+ if (api_mode == API_MODE_NEW_API_REF_COUNT)
+ av_dict_set(&opts, "refcounted_frames", "1", 0);
+ if ((ret = avcodec_open2(dec_ctx, dec, &opts)) < 0) {
fprintf(stderr, "Failed to open %s codec\n",
av_get_media_type_string(type));
return ret;
@@ -185,15 +208,31 @@
{
int ret = 0, got_frame;
- if (argc != 4) {
- fprintf(stderr, "usage: %s input_file video_output_file audio_output_file\n"
+ if (argc != 4 && argc != 5) {
+ fprintf(stderr, "usage: %s [-refcount=<old|new_norefcount|new_refcount>] "
+ "input_file video_output_file audio_output_file\n"
"API example program to show how to read frames from an input file.\n"
"This program reads frames from a file, decodes them, and writes decoded\n"
"video frames to a rawvideo file named video_output_file, and decoded\n"
- "audio frames to a rawaudio file named audio_output_file.\n"
+ "audio frames to a rawaudio file named audio_output_file.\n\n"
+ "If the -refcount option is specified, the program use the\n"
+ "reference counting frame system which allows keeping a copy of\n"
+ "the data for longer than one decode call. If unset, it's using\n"
+ "the classic old method.\n"
"\n", argv[0]);
exit(1);
}
+ if (argc == 5) {
+ const char *mode = argv[1] + strlen("-refcount=");
+ if (!strcmp(mode, "old")) api_mode = API_MODE_OLD;
+ else if (!strcmp(mode, "new_norefcount")) api_mode = API_MODE_NEW_API_NO_REF_COUNT;
+ else if (!strcmp(mode, "new_refcount")) api_mode = API_MODE_NEW_API_REF_COUNT;
+ else {
+ fprintf(stderr, "unknow mode '%s'\n", mode);
+ exit(1);
+ }
+ argv++;
+ }
src_filename = argv[1];
video_dst_filename = argv[2];
audio_dst_filename = argv[3];
@@ -255,7 +294,12 @@
goto end;
}
- frame = avcodec_alloc_frame();
+ /* When using the new API, you need to use the libavutil/frame.h API, while
+ * the classic frame management is available in libavcodec */
+ if (api_mode == API_MODE_OLD)
+ frame = avcodec_alloc_frame();
+ else
+ frame = av_frame_alloc();
if (!frame) {
fprintf(stderr, "Could not allocate frame\n");
ret = AVERROR(ENOMEM);
@@ -325,16 +369,17 @@
}
end:
- if (video_dec_ctx)
- avcodec_close(video_dec_ctx);
- if (audio_dec_ctx)
- avcodec_close(audio_dec_ctx);
+ avcodec_close(video_dec_ctx);
+ avcodec_close(audio_dec_ctx);
avformat_close_input(&fmt_ctx);
if (video_dst_file)
fclose(video_dst_file);
if (audio_dst_file)
fclose(audio_dst_file);
- av_free(frame);
+ if (api_mode == API_MODE_OLD)
+ avcodec_free_frame(&frame);
+ else
+ av_frame_free(&frame);
av_free(video_dst_data[0]);
return ret < 0;
diff --git a/doc/examples/filtering_audio.c b/doc/examples/filtering_audio.c
index 35dd4e7..1d66ca3 100644
--- a/doc/examples/filtering_audio.c
+++ b/doc/examples/filtering_audio.c
@@ -85,7 +85,7 @@
static int init_filters(const char *filters_descr)
{
char args[512];
- int ret;
+ int ret = 0;
AVFilter *abuffersrc = avfilter_get_by_name("abuffer");
AVFilter *abuffersink = avfilter_get_by_name("abuffersink");
AVFilterInOut *outputs = avfilter_inout_alloc();
@@ -97,6 +97,10 @@
AVRational time_base = fmt_ctx->streams[audio_stream_index]->time_base;
filter_graph = avfilter_graph_alloc();
+ if (!outputs || !inputs || !filter_graph) {
+ ret = AVERROR(ENOMEM);
+ goto end;
+ }
/* buffer audio source: the decoded frames from the decoder will be inserted here. */
if (!dec_ctx->channel_layout)
@@ -109,7 +113,7 @@
args, NULL, filter_graph);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Cannot create audio buffer source\n");
- return ret;
+ goto end;
}
/* buffer audio sink: to terminate the filter chain. */
@@ -117,28 +121,28 @@
NULL, NULL, filter_graph);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Cannot create audio buffer sink\n");
- return ret;
+ goto end;
}
ret = av_opt_set_int_list(buffersink_ctx, "sample_fmts", out_sample_fmts, -1,
AV_OPT_SEARCH_CHILDREN);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Cannot set output sample format\n");
- return ret;
+ goto end;
}
ret = av_opt_set_int_list(buffersink_ctx, "channel_layouts", out_channel_layouts, -1,
AV_OPT_SEARCH_CHILDREN);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Cannot set output channel layout\n");
- return ret;
+ goto end;
}
ret = av_opt_set_int_list(buffersink_ctx, "sample_rates", out_sample_rates, -1,
AV_OPT_SEARCH_CHILDREN);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Cannot set output sample rate\n");
- return ret;
+ goto end;
}
/* Endpoints for the filter graph. */
@@ -153,11 +157,11 @@
inputs->next = NULL;
if ((ret = avfilter_graph_parse_ptr(filter_graph, filters_descr,
- &inputs, &outputs, NULL)) < 0)
- return ret;
+ &inputs, &outputs, NULL)) < 0)
+ goto end;
if ((ret = avfilter_graph_config(filter_graph, NULL)) < 0)
- return ret;
+ goto end;
/* Print summary of the sink buffer
* Note: args buffer is reused to store channel layout string */
@@ -168,7 +172,11 @@
(char *)av_x_if_null(av_get_sample_fmt_name(outlink->format), "?"),
args);
- return 0;
+end:
+ avfilter_inout_free(&inputs);
+ avfilter_inout_free(&outputs);
+
+ return ret;
}
static void print_frame(const AVFrame *frame)
@@ -188,7 +196,7 @@
int main(int argc, char **argv)
{
int ret;
- AVPacket packet;
+ AVPacket packet0, packet;
AVFrame *frame = av_frame_alloc();
AVFrame *filt_frame = av_frame_alloc();
int got_frame;
@@ -212,9 +220,14 @@
goto end;
/* read all packets */
+ packet0.data = NULL;
+ packet.data = NULL;
while (1) {
- if ((ret = av_read_frame(fmt_ctx, &packet)) < 0)
- break;
+ if (!packet0.data) {
+ if ((ret = av_read_frame(fmt_ctx, &packet)) < 0)
+ break;
+ packet0 = packet;
+ }
if (packet.stream_index == audio_stream_index) {
avcodec_get_frame_defaults(frame);
@@ -224,6 +237,8 @@
av_log(NULL, AV_LOG_ERROR, "Error decoding audio\n");
continue;
}
+ packet.size -= ret;
+ packet.data += ret;
if (got_frame) {
/* push the audio data from decoded frame into the filtergraph */
@@ -235,29 +250,31 @@
/* pull filtered audio from the filtergraph */
while (1) {
ret = av_buffersink_get_frame(buffersink_ctx, filt_frame);
- if(ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
+ if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
break;
- if(ret < 0)
+ if (ret < 0)
goto end;
print_frame(filt_frame);
av_frame_unref(filt_frame);
}
}
+
+ if (packet.size <= 0)
+ av_free_packet(&packet0);
+ } else {
+ /* discard non-wanted packets */
+ av_free_packet(&packet0);
}
- av_free_packet(&packet);
}
end:
avfilter_graph_free(&filter_graph);
- if (dec_ctx)
- avcodec_close(dec_ctx);
+ avcodec_close(dec_ctx);
avformat_close_input(&fmt_ctx);
av_frame_free(&frame);
av_frame_free(&filt_frame);
if (ret < 0 && ret != AVERROR_EOF) {
- char buf[1024];
- av_strerror(ret, buf, sizeof(buf));
- fprintf(stderr, "Error occurred: %s\n", buf);
+ fprintf(stderr, "Error occurred: %s\n", av_err2str(ret));
exit(1);
}
diff --git a/doc/examples/filtering_video.c b/doc/examples/filtering_video.c
index d3c33df..790c641 100644
--- a/doc/examples/filtering_video.c
+++ b/doc/examples/filtering_video.c
@@ -36,6 +36,7 @@
#include <libavfilter/avcodec.h>
#include <libavfilter/buffersink.h>
#include <libavfilter/buffersrc.h>
+#include <libavutil/opt.h>
const char *filter_descr = "scale=78:24";
@@ -70,6 +71,7 @@
}
video_stream_index = ret;
dec_ctx = fmt_ctx->streams[video_stream_index]->codec;
+ av_opt_set_int(dec_ctx, "refcounted_frames", 1, 0);
/* init the video decoder */
if ((ret = avcodec_open2(dec_ctx, dec, NULL)) < 0) {
@@ -83,15 +85,18 @@
static int init_filters(const char *filters_descr)
{
char args[512];
- int ret;
+ int ret = 0;
AVFilter *buffersrc = avfilter_get_by_name("buffer");
AVFilter *buffersink = avfilter_get_by_name("buffersink");
AVFilterInOut *outputs = avfilter_inout_alloc();
AVFilterInOut *inputs = avfilter_inout_alloc();
enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_GRAY8, AV_PIX_FMT_NONE };
- AVBufferSinkParams *buffersink_params;
filter_graph = avfilter_graph_alloc();
+ if (!outputs || !inputs || !filter_graph) {
+ ret = AVERROR(ENOMEM);
+ goto end;
+ }
/* buffer video source: the decoded frames from the decoder will be inserted here. */
snprintf(args, sizeof(args),
@@ -104,18 +109,22 @@
args, NULL, filter_graph);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Cannot create buffer source\n");
- return ret;
+ goto end;
}
/* buffer video sink: to terminate the filter chain. */
- buffersink_params = av_buffersink_params_alloc();
- buffersink_params->pixel_fmts = pix_fmts;
ret = avfilter_graph_create_filter(&buffersink_ctx, buffersink, "out",
- NULL, buffersink_params, filter_graph);
- av_free(buffersink_params);
+ NULL, NULL, filter_graph);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Cannot create buffer sink\n");
- return ret;
+ goto end;
+ }
+
+ ret = av_opt_set_int_list(buffersink_ctx, "pix_fmts", pix_fmts,
+ AV_PIX_FMT_NONE, AV_OPT_SEARCH_CHILDREN);
+ if (ret < 0) {
+ av_log(NULL, AV_LOG_ERROR, "Cannot set output pixel format\n");
+ goto end;
}
/* Endpoints for the filter graph. */
@@ -131,11 +140,16 @@
if ((ret = avfilter_graph_parse_ptr(filter_graph, filters_descr,
&inputs, &outputs, NULL)) < 0)
- return ret;
+ goto end;
if ((ret = avfilter_graph_config(filter_graph, NULL)) < 0)
- return ret;
- return 0;
+ goto end;
+
+end:
+ avfilter_inout_free(&inputs);
+ avfilter_inout_free(&outputs);
+
+ return ret;
}
static void display_frame(const AVFrame *frame, AVRational time_base)
@@ -228,22 +242,20 @@
display_frame(filt_frame, buffersink_ctx->inputs[0]->time_base);
av_frame_unref(filt_frame);
}
+ av_frame_unref(frame);
}
}
av_free_packet(&packet);
}
end:
avfilter_graph_free(&filter_graph);
- if (dec_ctx)
- avcodec_close(dec_ctx);
+ avcodec_close(dec_ctx);
avformat_close_input(&fmt_ctx);
av_frame_free(&frame);
av_frame_free(&filt_frame);
if (ret < 0 && ret != AVERROR_EOF) {
- char buf[1024];
- av_strerror(ret, buf, sizeof(buf));
- fprintf(stderr, "Error occurred: %s\n", buf);
+ fprintf(stderr, "Error occurred: %s\n", av_err2str(ret));
exit(1);
}
diff --git a/doc/examples/muxing.c b/doc/examples/muxing.c
index a8f979f..4276114 100644
--- a/doc/examples/muxing.c
+++ b/doc/examples/muxing.c
@@ -221,7 +221,7 @@
{
AVCodecContext *c;
AVPacket pkt = { 0 }; // data and size must be 0;
- AVFrame *frame = avcodec_alloc_frame();
+ AVFrame *frame = av_frame_alloc();
int got_packet, ret, dst_nb_samples;
av_init_packet(&pkt);
@@ -310,7 +310,7 @@
}
/* allocate and init a re-usable frame */
- frame = avcodec_alloc_frame();
+ frame = av_frame_alloc();
if (!frame) {
fprintf(stderr, "Could not allocate video frame\n");
exit(1);
diff --git a/doc/examples/resampling_audio.c b/doc/examples/resampling_audio.c
index 70db9ef..f9bfb92 100644
--- a/doc/examples/resampling_audio.c
+++ b/doc/examples/resampling_audio.c
@@ -62,7 +62,7 @@
/**
* Fill dst buffer with nb_samples, generated starting from t.
*/
-void fill_samples(double *dst, int nb_samples, int nb_channels, int sample_rate, double *t)
+static void fill_samples(double *dst, int nb_samples, int nb_channels, int sample_rate, double *t)
{
int i, j;
double tincr = 1.0 / sample_rate, *dstp = dst;
diff --git a/doc/examples/transcode_aac.c b/doc/examples/transcode_aac.c
new file mode 100644
index 0000000..35deb4c
--- /dev/null
+++ b/doc/examples/transcode_aac.c
@@ -0,0 +1,752 @@
+/*
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file simple audio converter
+ * Convert an input audio file to AAC in an MP4 container using FFmpeg.
+ * @author Andreas Unterweger (dustsigns@gmail.com)
+ */
+
+#include <stdio.h>
+
+#include "libavformat/avformat.h"
+#include "libavformat/avio.h"
+
+#include "libavcodec/avcodec.h"
+
+#include "libavutil/audio_fifo.h"
+#include "libavutil/avassert.h"
+#include "libavutil/avstring.h"
+#include "libavutil/frame.h"
+#include "libavutil/opt.h"
+
+#include "libswresample/swresample.h"
+
+/** The output bit rate in kbit/s */
+#define OUTPUT_BIT_RATE 48000
+/** The number of output channels */
+#define OUTPUT_CHANNELS 2
+/** The audio sample output format */
+#define OUTPUT_SAMPLE_FORMAT AV_SAMPLE_FMT_S16
+
+/**
+ * Convert an error code into a text message.
+ * @param error Error code to be converted
+ * @return Corresponding error text (not thread-safe)
+ */
+static char *const get_error_text(const int error)
+{
+ static char error_buffer[255];
+ av_strerror(error, error_buffer, sizeof(error_buffer));
+ return error_buffer;
+}
+
+/** Open an input file and the required decoder. */
+static int open_input_file(const char *filename,
+ AVFormatContext **input_format_context,
+ AVCodecContext **input_codec_context)
+{
+ AVCodec *input_codec;
+ int error;
+
+ /** Open the input file to read from it. */
+ if ((error = avformat_open_input(input_format_context, filename, NULL,
+ NULL)) < 0) {
+ fprintf(stderr, "Could not open input file '%s' (error '%s')\n",
+ filename, get_error_text(error));
+ *input_format_context = NULL;
+ return error;
+ }
+
+ /** Get information on the input file (number of streams etc.). */
+ if ((error = avformat_find_stream_info(*input_format_context, NULL)) < 0) {
+ fprintf(stderr, "Could not open find stream info (error '%s')\n",
+ get_error_text(error));
+ avformat_close_input(input_format_context);
+ return error;
+ }
+
+ /** Make sure that there is only one stream in the input file. */
+ if ((*input_format_context)->nb_streams != 1) {
+ fprintf(stderr, "Expected one audio input stream, but found %d\n",
+ (*input_format_context)->nb_streams);
+ avformat_close_input(input_format_context);
+ return AVERROR_EXIT;
+ }
+
+ /** Find a decoder for the audio stream. */
+ if (!(input_codec = avcodec_find_decoder((*input_format_context)->streams[0]->codec->codec_id))) {
+ fprintf(stderr, "Could not find input codec\n");
+ avformat_close_input(input_format_context);
+ return AVERROR_EXIT;
+ }
+
+ /** Open the decoder for the audio stream to use it later. */
+ if ((error = avcodec_open2((*input_format_context)->streams[0]->codec,
+ input_codec, NULL)) < 0) {
+ fprintf(stderr, "Could not open input codec (error '%s')\n",
+ get_error_text(error));
+ avformat_close_input(input_format_context);
+ return error;
+ }
+
+ /** Save the decoder context for easier access later. */
+ *input_codec_context = (*input_format_context)->streams[0]->codec;
+
+ return 0;
+}
+
+/**
+ * Open an output file and the required encoder.
+ * Also set some basic encoder parameters.
+ * Some of these parameters are based on the input file's parameters.
+ */
+static int open_output_file(const char *filename,
+ AVCodecContext *input_codec_context,
+ AVFormatContext **output_format_context,
+ AVCodecContext **output_codec_context)
+{
+ AVIOContext *output_io_context = NULL;
+ AVStream *stream = NULL;
+ AVCodec *output_codec = NULL;
+ int error;
+
+ /** Open the output file to write to it. */
+ if ((error = avio_open(&output_io_context, filename,
+ AVIO_FLAG_WRITE)) < 0) {
+ fprintf(stderr, "Could not open output file '%s' (error '%s')\n",
+ filename, get_error_text(error));
+ return error;
+ }
+
+ /** Create a new format context for the output container format. */
+ if (!(*output_format_context = avformat_alloc_context())) {
+ fprintf(stderr, "Could not allocate output format context\n");
+ return AVERROR(ENOMEM);
+ }
+
+ /** Associate the output file (pointer) with the container format context. */
+ (*output_format_context)->pb = output_io_context;
+
+ /** Guess the desired container format based on the file extension. */
+ if (!((*output_format_context)->oformat = av_guess_format(NULL, filename,
+ NULL))) {
+ fprintf(stderr, "Could not find output file format\n");
+ goto cleanup;
+ }
+
+ av_strlcpy((*output_format_context)->filename, filename,
+ sizeof((*output_format_context)->filename));
+
+ /** Find the encoder to be used by its name. */
+ if (!(output_codec = avcodec_find_encoder(AV_CODEC_ID_AAC))) {
+ fprintf(stderr, "Could not find an AAC encoder.\n");
+ goto cleanup;
+ }
+
+ /** Create a new audio stream in the output file container. */
+ if (!(stream = avformat_new_stream(*output_format_context, output_codec))) {
+ fprintf(stderr, "Could not create new stream\n");
+ error = AVERROR(ENOMEM);
+ goto cleanup;
+ }
+
+ /** Save the encoder context for easiert access later. */
+ *output_codec_context = stream->codec;
+
+ /**
+ * Set the basic encoder parameters.
+ * The input file's sample rate is used to avoid a sample rate conversion.
+ */
+ (*output_codec_context)->channels = OUTPUT_CHANNELS;
+ (*output_codec_context)->channel_layout = av_get_default_channel_layout(OUTPUT_CHANNELS);
+ (*output_codec_context)->sample_rate = input_codec_context->sample_rate;
+ (*output_codec_context)->sample_fmt = AV_SAMPLE_FMT_S16;
+ (*output_codec_context)->bit_rate = OUTPUT_BIT_RATE;
+
+ /**
+ * Some container formats (like MP4) require global headers to be present
+ * Mark the encoder so that it behaves accordingly.
+ */
+ if ((*output_format_context)->oformat->flags & AVFMT_GLOBALHEADER)
+ (*output_codec_context)->flags |= CODEC_FLAG_GLOBAL_HEADER;
+
+ /** Open the encoder for the audio stream to use it later. */
+ if ((error = avcodec_open2(*output_codec_context, output_codec, NULL)) < 0) {
+ fprintf(stderr, "Could not open output codec (error '%s')\n",
+ get_error_text(error));
+ goto cleanup;
+ }
+
+ return 0;
+
+cleanup:
+ avio_close((*output_format_context)->pb);
+ avformat_free_context(*output_format_context);
+ *output_format_context = NULL;
+ return error < 0 ? error : AVERROR_EXIT;
+}
+
+/** Initialize one data packet for reading or writing. */
+static void init_packet(AVPacket *packet)
+{
+ av_init_packet(packet);
+ /** Set the packet data and size so that it is recognized as being empty. */
+ packet->data = NULL;
+ packet->size = 0;
+}
+
+/** Initialize one audio frame for reading from the input file */
+static int init_input_frame(AVFrame **frame)
+{
+ if (!(*frame = av_frame_alloc())) {
+ fprintf(stderr, "Could not allocate input frame\n");
+ return AVERROR(ENOMEM);
+ }
+ return 0;
+}
+
+/**
+ * Initialize the audio resampler based on the input and output codec settings.
+ * If the input and output sample formats differ, a conversion is required
+ * libswresample takes care of this, but requires initialization.
+ */
+static int init_resampler(AVCodecContext *input_codec_context,
+ AVCodecContext *output_codec_context,
+ SwrContext **resample_context)
+{
+ int error;
+
+ /**
+ * Create a resampler context for the conversion.
+ * Set the conversion parameters.
+ * Default channel layouts based on the number of channels
+ * are assumed for simplicity (they are sometimes not detected
+ * properly by the demuxer and/or decoder).
+ */
+ *resample_context = swr_alloc_set_opts(NULL,
+ av_get_default_channel_layout(output_codec_context->channels),
+ output_codec_context->sample_fmt,
+ output_codec_context->sample_rate,
+ av_get_default_channel_layout(input_codec_context->channels),
+ input_codec_context->sample_fmt,
+ input_codec_context->sample_rate,
+ 0, NULL);
+ if (!*resample_context) {
+ fprintf(stderr, "Could not allocate resample context\n");
+ return AVERROR(ENOMEM);
+ }
+ /**
+ * Perform a sanity check so that the number of converted samples is
+ * not greater than the number of samples to be converted.
+ * If the sample rates differ, this case has to be handled differently
+ */
+ av_assert0(output_codec_context->sample_rate == input_codec_context->sample_rate);
+
+ /** Open the resampler with the specified parameters. */
+ if ((error = swr_init(*resample_context)) < 0) {
+ fprintf(stderr, "Could not open resample context\n");
+ swr_free(resample_context);
+ return error;
+ }
+ return 0;
+}
+
+/** Initialize a FIFO buffer for the audio samples to be encoded. */
+static int init_fifo(AVAudioFifo **fifo)
+{
+ /** Create the FIFO buffer based on the specified output sample format. */
+ if (!(*fifo = av_audio_fifo_alloc(OUTPUT_SAMPLE_FORMAT, OUTPUT_CHANNELS, 1))) {
+ fprintf(stderr, "Could not allocate FIFO\n");
+ return AVERROR(ENOMEM);
+ }
+ return 0;
+}
+
+/** Write the header of the output file container. */
+static int write_output_file_header(AVFormatContext *output_format_context)
+{
+ int error;
+ if ((error = avformat_write_header(output_format_context, NULL)) < 0) {
+ fprintf(stderr, "Could not write output file header (error '%s')\n",
+ get_error_text(error));
+ return error;
+ }
+ return 0;
+}
+
+/** Decode one audio frame from the input file. */
+static int decode_audio_frame(AVFrame *frame,
+ AVFormatContext *input_format_context,
+ AVCodecContext *input_codec_context,
+ int *data_present, int *finished)
+{
+ /** Packet used for temporary storage. */
+ AVPacket input_packet;
+ int error;
+ init_packet(&input_packet);
+
+ /** Read one audio frame from the input file into a temporary packet. */
+ if ((error = av_read_frame(input_format_context, &input_packet)) < 0) {
+ /** If we are the the end of the file, flush the decoder below. */
+ if (error == AVERROR_EOF)
+ *finished = 1;
+ else {
+ fprintf(stderr, "Could not read frame (error '%s')\n",
+ get_error_text(error));
+ return error;
+ }
+ }
+
+ /**
+ * Decode the audio frame stored in the temporary packet.
+ * The input audio stream decoder is used to do this.
+ * If we are at the end of the file, pass an empty packet to the decoder
+ * to flush it.
+ */
+ if ((error = avcodec_decode_audio4(input_codec_context, frame,
+ data_present, &input_packet)) < 0) {
+ fprintf(stderr, "Could not decode frame (error '%s')\n",
+ get_error_text(error));
+ av_free_packet(&input_packet);
+ return error;
+ }
+
+ /**
+ * If the decoder has not been flushed completely, we are not finished,
+ * so that this function has to be called again.
+ */
+ if (*finished && *data_present)
+ *finished = 0;
+ av_free_packet(&input_packet);
+ return 0;
+}
+
+/**
+ * Initialize a temporary storage for the specified number of audio samples.
+ * The conversion requires temporary storage due to the different format.
+ * The number of audio samples to be allocated is specified in frame_size.
+ */
+static int init_converted_samples(uint8_t ***converted_input_samples,
+ AVCodecContext *output_codec_context,
+ int frame_size)
+{
+ int error;
+
+ /**
+ * Allocate as many pointers as there are audio channels.
+ * Each pointer will later point to the audio samples of the corresponding
+ * channels (although it may be NULL for interleaved formats).
+ */
+ if (!(*converted_input_samples = calloc(output_codec_context->channels,
+ sizeof(**converted_input_samples)))) {
+ fprintf(stderr, "Could not allocate converted input sample pointers\n");
+ return AVERROR(ENOMEM);
+ }
+
+ /**
+ * Allocate memory for the samples of all channels in one consecutive
+ * block for convenience.
+ */
+ if ((error = av_samples_alloc(*converted_input_samples, NULL,
+ output_codec_context->channels,
+ frame_size,
+ output_codec_context->sample_fmt, 0)) < 0) {
+ fprintf(stderr,
+ "Could not allocate converted input samples (error '%s')\n",
+ get_error_text(error));
+ av_freep(&(*converted_input_samples)[0]);
+ free(*converted_input_samples);
+ return error;
+ }
+ return 0;
+}
+
+/**
+ * Convert the input audio samples into the output sample format.
+ * The conversion happens on a per-frame basis, the size of which is specified
+ * by frame_size.
+ */
+static int convert_samples(const uint8_t **input_data,
+ uint8_t **converted_data, const int frame_size,
+ SwrContext *resample_context)
+{
+ int error;
+
+ /** Convert the samples using the resampler. */
+ if ((error = swr_convert(resample_context,
+ converted_data, frame_size,
+ input_data , frame_size)) < 0) {
+ fprintf(stderr, "Could not convert input samples (error '%s')\n",
+ get_error_text(error));
+ return error;
+ }
+
+ return 0;
+}
+
+/** Add converted input audio samples to the FIFO buffer for later processing. */
+static int add_samples_to_fifo(AVAudioFifo *fifo,
+ uint8_t **converted_input_samples,
+ const int frame_size)
+{
+ int error;
+
+ /**
+ * Make the FIFO as large as it needs to be to hold both,
+ * the old and the new samples.
+ */
+ if ((error = av_audio_fifo_realloc(fifo, av_audio_fifo_size(fifo) + frame_size)) < 0) {
+ fprintf(stderr, "Could not reallocate FIFO\n");
+ return error;
+ }
+
+ /** Store the new samples in the FIFO buffer. */
+ if (av_audio_fifo_write(fifo, (void **)converted_input_samples,
+ frame_size) < frame_size) {
+ fprintf(stderr, "Could not write data to FIFO\n");
+ return AVERROR_EXIT;
+ }
+ return 0;
+}
+
+/**
+ * Read one audio frame from the input file, decodes, converts and stores
+ * it in the FIFO buffer.
+ */
+static int read_decode_convert_and_store(AVAudioFifo *fifo,
+ AVFormatContext *input_format_context,
+ AVCodecContext *input_codec_context,
+ AVCodecContext *output_codec_context,
+ SwrContext *resampler_context,
+ int *finished)
+{
+ /** Temporary storage of the input samples of the frame read from the file. */
+ AVFrame *input_frame = NULL;
+ /** Temporary storage for the converted input samples. */
+ uint8_t **converted_input_samples = NULL;
+ int data_present;
+ int ret = AVERROR_EXIT;
+
+ /** Initialize temporary storage for one input frame. */
+ if (init_input_frame(&input_frame))
+ goto cleanup;
+ /** Decode one frame worth of audio samples. */
+ if (decode_audio_frame(input_frame, input_format_context,
+ input_codec_context, &data_present, finished))
+ goto cleanup;
+ /**
+ * If we are at the end of the file and there are no more samples
+ * in the decoder which are delayed, we are actually finished.
+ * This must not be treated as an error.
+ */
+ if (*finished && !data_present) {
+ ret = 0;
+ goto cleanup;
+ }
+ /** If there is decoded data, convert and store it */
+ if (data_present) {
+ /** Initialize the temporary storage for the converted input samples. */
+ if (init_converted_samples(&converted_input_samples, output_codec_context,
+ input_frame->nb_samples))
+ goto cleanup;
+
+ /**
+ * Convert the input samples to the desired output sample format.
+ * This requires a temporary storage provided by converted_input_samples.
+ */
+ if (convert_samples((const uint8_t**)input_frame->extended_data, converted_input_samples,
+ input_frame->nb_samples, resampler_context))
+ goto cleanup;
+
+ /** Add the converted input samples to the FIFO buffer for later processing. */
+ if (add_samples_to_fifo(fifo, converted_input_samples,
+ input_frame->nb_samples))
+ goto cleanup;
+ ret = 0;
+ }
+ ret = 0;
+
+cleanup:
+ if (converted_input_samples) {
+ av_freep(&converted_input_samples[0]);
+ free(converted_input_samples);
+ }
+ av_frame_free(&input_frame);
+
+ return ret;
+}
+
+/**
+ * Initialize one input frame for writing to the output file.
+ * The frame will be exactly frame_size samples large.
+ */
+static int init_output_frame(AVFrame **frame,
+ AVCodecContext *output_codec_context,
+ int frame_size)
+{
+ int error;
+
+ /** Create a new frame to store the audio samples. */
+ if (!(*frame = av_frame_alloc())) {
+ fprintf(stderr, "Could not allocate output frame\n");
+ return AVERROR_EXIT;
+ }
+
+ /**
+ * Set the frame's parameters, especially its size and format.
+ * av_frame_get_buffer needs this to allocate memory for the
+ * audio samples of the frame.
+ * Default channel layouts based on the number of channels
+ * are assumed for simplicity.
+ */
+ (*frame)->nb_samples = frame_size;
+ (*frame)->channel_layout = output_codec_context->channel_layout;
+ (*frame)->format = output_codec_context->sample_fmt;
+ (*frame)->sample_rate = output_codec_context->sample_rate;
+
+ /**
+ * Allocate the samples of the created frame. This call will make
+ * sure that the audio frame can hold as many samples as specified.
+ */
+ if ((error = av_frame_get_buffer(*frame, 0)) < 0) {
+ fprintf(stderr, "Could allocate output frame samples (error '%s')\n",
+ get_error_text(error));
+ av_frame_free(frame);
+ return error;
+ }
+
+ return 0;
+}
+
+/** Encode one frame worth of audio to the output file. */
+static int encode_audio_frame(AVFrame *frame,
+ AVFormatContext *output_format_context,
+ AVCodecContext *output_codec_context,
+ int *data_present)
+{
+ /** Packet used for temporary storage. */
+ AVPacket output_packet;
+ int error;
+ init_packet(&output_packet);
+
+ /**
+ * Encode the audio frame and store it in the temporary packet.
+ * The output audio stream encoder is used to do this.
+ */
+ if ((error = avcodec_encode_audio2(output_codec_context, &output_packet,
+ frame, data_present)) < 0) {
+ fprintf(stderr, "Could not encode frame (error '%s')\n",
+ get_error_text(error));
+ av_free_packet(&output_packet);
+ return error;
+ }
+
+ /** Write one audio frame from the temporary packet to the output file. */
+ if (*data_present) {
+ if ((error = av_write_frame(output_format_context, &output_packet)) < 0) {
+ fprintf(stderr, "Could not write frame (error '%s')\n",
+ get_error_text(error));
+ av_free_packet(&output_packet);
+ return error;
+ }
+
+ av_free_packet(&output_packet);
+ }
+
+ return 0;
+}
+
+/**
+ * Load one audio frame from the FIFO buffer, encode and write it to the
+ * output file.
+ */
+static int load_encode_and_write(AVAudioFifo *fifo,
+ AVFormatContext *output_format_context,
+ AVCodecContext *output_codec_context)
+{
+ /** Temporary storage of the output samples of the frame written to the file. */
+ AVFrame *output_frame;
+ /**
+ * Use the maximum number of possible samples per frame.
+ * If there is less than the maximum possible frame size in the FIFO
+ * buffer use this number. Otherwise, use the maximum possible frame size
+ */
+ const int frame_size = FFMIN(av_audio_fifo_size(fifo),
+ output_codec_context->frame_size);
+ int data_written;
+
+ /** Initialize temporary storage for one output frame. */
+ if (init_output_frame(&output_frame, output_codec_context, frame_size))
+ return AVERROR_EXIT;
+
+ /**
+ * Read as many samples from the FIFO buffer as required to fill the frame.
+ * The samples are stored in the frame temporarily.
+ */
+ if (av_audio_fifo_read(fifo, (void **)output_frame->data, frame_size) < frame_size) {
+ fprintf(stderr, "Could not read data from FIFO\n");
+ av_frame_free(&output_frame);
+ return AVERROR_EXIT;
+ }
+
+ /** Encode one frame worth of audio samples. */
+ if (encode_audio_frame(output_frame, output_format_context,
+ output_codec_context, &data_written)) {
+ av_frame_free(&output_frame);
+ return AVERROR_EXIT;
+ }
+ av_frame_free(&output_frame);
+ return 0;
+}
+
+/** Write the trailer of the output file container. */
+static int write_output_file_trailer(AVFormatContext *output_format_context)
+{
+ int error;
+ if ((error = av_write_trailer(output_format_context)) < 0) {
+ fprintf(stderr, "Could not write output file trailer (error '%s')\n",
+ get_error_text(error));
+ return error;
+ }
+ return 0;
+}
+
+/** Convert an audio file to an AAC file in an MP4 container. */
+int main(int argc, char **argv)
+{
+ AVFormatContext *input_format_context = NULL, *output_format_context = NULL;
+ AVCodecContext *input_codec_context = NULL, *output_codec_context = NULL;
+ SwrContext *resample_context = NULL;
+ AVAudioFifo *fifo = NULL;
+ int ret = AVERROR_EXIT;
+
+ if (argc < 3) {
+ fprintf(stderr, "Usage: %s <input file> <output file>\n", argv[0]);
+ exit(1);
+ }
+
+ /** Register all codecs and formats so that they can be used. */
+ av_register_all();
+ /** Open the input file for reading. */
+ if (open_input_file(argv[1], &input_format_context,
+ &input_codec_context))
+ goto cleanup;
+ /** Open the output file for writing. */
+ if (open_output_file(argv[2], input_codec_context,
+ &output_format_context, &output_codec_context))
+ goto cleanup;
+ /** Initialize the resampler to be able to convert audio sample formats. */
+ if (init_resampler(input_codec_context, output_codec_context,
+ &resample_context))
+ goto cleanup;
+ /** Initialize the FIFO buffer to store audio samples to be encoded. */
+ if (init_fifo(&fifo))
+ goto cleanup;
+ /** Write the header of the output file container. */
+ if (write_output_file_header(output_format_context))
+ goto cleanup;
+
+ /**
+ * Loop as long as we have input samples to read or output samples
+ * to write; abort as soon as we have neither.
+ */
+ while (1) {
+ /** Use the encoder's desired frame size for processing. */
+ const int output_frame_size = output_codec_context->frame_size;
+ int finished = 0;
+
+ /**
+ * Make sure that there is one frame worth of samples in the FIFO
+ * buffer so that the encoder can do its work.
+ * Since the decoder's and the encoder's frame size may differ, we
+ * need to FIFO buffer to store as many frames worth of input samples
+ * that they make up at least one frame worth of output samples.
+ */
+ while (av_audio_fifo_size(fifo) < output_frame_size) {
+ /**
+ * Decode one frame worth of audio samples, convert it to the
+ * output sample format and put it into the FIFO buffer.
+ */
+ if (read_decode_convert_and_store(fifo, input_format_context,
+ input_codec_context,
+ output_codec_context,
+ resample_context, &finished))
+ goto cleanup;
+
+ /**
+ * If we are at the end of the input file, we continue
+ * encoding the remaining audio samples to the output file.
+ */
+ if (finished)
+ break;
+ }
+
+ /**
+ * If we have enough samples for the encoder, we encode them.
+ * At the end of the file, we pass the remaining samples to
+ * the encoder.
+ */
+ while (av_audio_fifo_size(fifo) >= output_frame_size ||
+ (finished && av_audio_fifo_size(fifo) > 0))
+ /**
+ * Take one frame worth of audio samples from the FIFO buffer,
+ * encode it and write it to the output file.
+ */
+ if (load_encode_and_write(fifo, output_format_context,
+ output_codec_context))
+ goto cleanup;
+
+ /**
+ * If we are at the end of the input file and have encoded
+ * all remaining samples, we can exit this loop and finish.
+ */
+ if (finished) {
+ int data_written;
+ /** Flush the encoder as it may have delayed frames. */
+ do {
+ if (encode_audio_frame(NULL, output_format_context,
+ output_codec_context, &data_written))
+ goto cleanup;
+ } while (data_written);
+ break;
+ }
+ }
+
+ /** Write the trailer of the output file container. */
+ if (write_output_file_trailer(output_format_context))
+ goto cleanup;
+ ret = 0;
+
+cleanup:
+ if (fifo)
+ av_audio_fifo_free(fifo);
+ swr_free(&resample_context);
+ if (output_codec_context)
+ avcodec_close(output_codec_context);
+ if (output_format_context) {
+ avio_close(output_format_context->pb);
+ avformat_free_context(output_format_context);
+ }
+ if (input_codec_context)
+ avcodec_close(input_codec_context);
+ if (input_format_context)
+ avformat_close_input(&input_format_context);
+
+ return ret;
+}
diff --git a/doc/ffmpeg.texi b/doc/ffmpeg.texi
index 2bb65d5..0a930ce 100644
--- a/doc/ffmpeg.texi
+++ b/doc/ffmpeg.texi
@@ -348,8 +348,13 @@
@item -q[:@var{stream_specifier}] @var{q} (@emph{output,per-stream})
@itemx -qscale[:@var{stream_specifier}] @var{q} (@emph{output,per-stream})
-Use fixed quality scale (VBR). The meaning of @var{q} is
+Use fixed quality scale (VBR). The meaning of @var{q}/@var{qscale} is
codec-dependent.
+If @var{qscale} is used without a @var{stream_specifier} then it applies only
+to the video stream, this is to maintain compatibility with previous behavior
+and as specifying the same codec specific value to 2 different codecs that is
+audio and video generally is not what is intended when no stream_specifier is
+used.
@anchor{filter_option}
@item -filter[:@var{stream_specifier}] @var{filtergraph} (@emph{output,per-stream})
@@ -616,6 +621,42 @@
@item -copyinkf[:@var{stream_specifier}] (@emph{output,per-stream})
When doing stream copy, copy also non-key frames found at the
beginning.
+
+@item -hwaccel[:@var{stream_specifier}] @var{hwaccel} (@emph{input,per-stream})
+Use hardware acceleration to decode the matching stream(s). The allowed values
+of @var{hwaccel} are:
+@table @option
+@item none
+Do not use any hardware acceleration (the default).
+
+@item auto
+Automatically select the hardware acceleration method.
+
+@item vdpau
+Use VDPAU (Video Decode and Presentation API for Unix) hardware acceleration.
+@end table
+
+This option has no effect if the selected hwaccel is not available or not
+supported by the chosen decoder.
+
+Note that most acceleration methods are intended for playback and will not be
+faster than software decoding on modern CPUs. Additionally, @command{ffmpeg}
+will usually need to copy the decoded frames from the GPU memory into the system
+memory, resulting in further performance loss. This option is thus mainly
+useful for testing.
+
+@item -hwaccel_device[:@var{stream_specifier}] @var{hwaccel_device} (@emph{input,per-stream})
+Select a device to use for hardware acceleration.
+
+This option only makes sense when the @option{-hwaccel} option is also
+specified. Its exact meaning depends on the specific hardware acceleration
+method chosen.
+
+@table @option
+@item vdpau
+For VDPAU, this option specifies the X11 display/screen to use. If this option
+is not specified, the value of the @var{DISPLAY} environment variable is used
+@end table
@end table
@section Audio Options
@@ -1072,12 +1113,14 @@
e.g. when copying some streams and transcoding the others.
@item -override_ffserver (@emph{global})
-Overrides the input specifications from ffserver. Using this option you can
-map any input stream to ffserver and control many aspects of the encoding from
-ffmpeg. Without this option ffmpeg will transmit to ffserver what is requested by
-ffserver.
+Overrides the input specifications from @command{ffserver}. Using this
+option you can map any input stream to @command{ffserver} and control
+many aspects of the encoding from @command{ffmpeg}. Without this
+option @command{ffmpeg} will transmit to @command{ffserver} what is
+requested by @command{ffserver}.
+
The option is intended for cases where features are needed that cannot be
-specified to ffserver but can be to ffmpeg.
+specified to @command{ffserver} but can be to @command{ffmpeg}.
@end table
diff --git a/doc/ffplay.texi b/doc/ffplay.texi
index c465af7..54b6f19 100644
--- a/doc/ffplay.texi
+++ b/doc/ffplay.texi
@@ -174,13 +174,16 @@
Pause.
@item a
-Cycle audio channel.
+Cycle audio channel in the curret program.
@item v
Cycle video channel.
@item t
-Cycle subtitle channel.
+Cycle subtitle channel in the current program.
+
+@item c
+Cycle program.
@item w
Show audio waves.
diff --git a/doc/ffprobe.texi b/doc/ffprobe.texi
index 777dbe7..75d1e72 100644
--- a/doc/ffprobe.texi
+++ b/doc/ffprobe.texi
@@ -197,11 +197,11 @@
section with name "PACKET".
@item -show_frames
-Show information about each frame contained in the input multimedia
-stream.
+Show information about each frame and subtitle contained in the input
+multimedia stream.
The information for each single frame is printed within a dedicated
-section with name "FRAME".
+section with name "FRAME" or "SUBTITLE".
@item -show_streams
Show information about each media stream contained in the input
@@ -337,6 +337,39 @@
to adopt. The options are specified as a list of @var{key}=@var{value}
pairs, separated by ":".
+All writers support the following options:
+
+@table @option
+@item string_validation, sv
+Set string validation mode.
+
+The following values are accepted.
+@table @samp
+@item fail
+The writer will fail immediately in case an invalid string (UTF-8)
+sequence or code point is found in the input. This is especially
+useful to validate input metadata.
+
+@item ignore
+Any validation error will be ignored. This will result in possibly
+broken output, especially with the json or xml writer.
+
+@item replace
+The writer will substitute invalid UTF-8 sequences or code points with
+the string specified with the @option{string_validation_replacement}.
+@end table
+
+Default value is @samp{replace}.
+
+@item string_validation_replacement, svr
+Set replacement string to use in case @option{string_validation} is
+set to @samp{replace}.
+
+In case the option is not specified, the writer will assume the empty
+string, that is it will remove the invalid sequences from the input
+strings.
+@end table
+
A description of the currently available writers follows.
@section default
diff --git a/doc/ffprobe.xsd b/doc/ffprobe.xsd
index 6a48ff4..cc3d1b6 100644
--- a/doc/ffprobe.xsd
+++ b/doc/ffprobe.xsd
@@ -28,7 +28,10 @@
<xsd:complexType name="framesType">
<xsd:sequence>
- <xsd:element name="frame" type="ffprobe:frameType" minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:choice minOccurs="0" maxOccurs="unbounded">
+ <xsd:element name="frame" type="ffprobe:frameType" minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element name="subtitle" type="ffprobe:subtitleType" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:choice>
</xsd:sequence>
</xsd:complexType>
@@ -82,6 +85,16 @@
<xsd:attribute name="repeat_pict" type="xsd:int" />
</xsd:complexType>
+ <xsd:complexType name="subtitleType">
+ <xsd:attribute name="media_type" type="xsd:string" fixed="subtitle" use="required"/>
+ <xsd:attribute name="pts" type="xsd:long" />
+ <xsd:attribute name="pts_time" type="xsd:float"/>
+ <xsd:attribute name="format" type="xsd:int" />
+ <xsd:attribute name="start_display_time" type="xsd:int" />
+ <xsd:attribute name="end_display_time" type="xsd:int" />
+ <xsd:attribute name="num_rects" type="xsd:int" />
+ </xsd:complexType>
+
<xsd:complexType name="streamsType">
<xsd:sequence>
<xsd:element name="stream" type="ffprobe:streamType" minOccurs="0" maxOccurs="unbounded"/>
diff --git a/doc/ffserver.texi b/doc/ffserver.texi
index 14443e6..3f7a98d 100644
--- a/doc/ffserver.texi
+++ b/doc/ffserver.texi
@@ -16,11 +16,14 @@
@chapter Description
@c man begin DESCRIPTION
-@command{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
-@file{ffserver.conf}).
+@command{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.
+
+@command{ffserver} is configured through a configuration file, which
+is read at startup. If not explicitly specified, it will read from
+@file{/etc/ffserver.conf}.
@command{ffserver} receives prerecorded files or FFM streams from some
@command{ffmpeg} instance as input, then streams them over
@@ -39,10 +42,118 @@
formats, each one specified by a @code{<Stream>} section in the
configuration file.
+@chapter Detailed description
+
+@command{ffserver} works by forwarding streams encoded by
+@command{ffmpeg}, or pre-recorded streams which are read from disk.
+
+Precisely, @command{ffserver} acts as an HTTP server, accepting POST
+requests from @command{ffmpeg} to acquire the stream to publish, and
+serving HTTP clients GET requests with the stream media content.
+
+A feed is an @ref{FFM} stream created by @command{ffmpeg}, and sent to
+a port where @command{ffserver} is listening.
+
+Each feed is identified by a unique name, corresponding to the name
+of the resource published on @command{ffserver}, and is configured by
+a dedicated @code{Feed} section in the configuration file.
+
+The feed publish URL is given by:
+@example
+http://@var{ffserver_ip_address}:@var{http_port}/@var{feed_name}
+@end example
+
+where @var{ffserver_ip_address} is the IP address of the machine where
+@command{ffserver} is installed, @var{http_port} is the port number of
+the HTTP server (configured through the @option{Port} option), and
+@var{feed_name} is the name of the corresponding feed defined in the
+configuration file.
+
+Each feed is associated to a file which is stored on disk. This stored
+file is used to allow to send pre-recorded data to a player as fast as
+possible when new content is added in real-time to the stream.
+
+A "live-stream" or "stream" is a resource published by
+@command{ffserver}, and made accessible through the HTTP protocol to
+clients.
+
+A stream can be connected to a feed, or to a file. In the first case,
+the published stream is forwarded from the corresponding feed
+generated by a running instance of @command{ffmpeg}, in the second
+case the stream is read from a pre-recorded file.
+
+Each stream is identified by a unique name, corresponding to the name
+of the resource served by @command{ffserver}, and is configured by
+a dedicated @code{Stream} section in the configuration file.
+
+The stream access URL is given by:
+@example
+http://@var{ffserver_ip_address}:@var{http_port}/@var{stream_name}[@var{options}]
+@end example
+
+@var{stream_name} is the name of the corresponding stream defined in
+the configuration file. @var{options} is a list of options specified
+after the URL which affects how the stream is served by
+@command{ffserver}.
+
+In case the stream is associated to a feed, the encoding parameters
+must be configured in the stream configuration. They are sent to
+@command{ffmpeg} when setting up the encoding. This allows
+@command{ffserver} to define the encoding parameters used by
+the @command{ffmpeg} encoders.
+
+The @command{ffmpeg} @option{override_ffserver} commandline option
+allows to override the encoding parameters set by the server.
+
+Multiple streams can be connected to the same feed.
+
+For example, you can have a situation described by the following
+graph:
+@example
+ _________ __________
+ | | | |
+ffmpeg 1 -----| feed 1 |-----| stream 1 |
+ \ |_________|\ |__________|
+ \ \
+ \ \ __________
+ \ \ | |
+ \ \| stream 2 |
+ \ |__________|
+ \
+ \ _________ __________
+ \ | | | |
+ \| feed 2 |-----| stream 3 |
+ |_________| |__________|
+
+ _________ __________
+ | | | |
+ffmpeg 2 -----| feed 3 |-----| stream 4 |
+ |_________| |__________|
+
+ _________ __________
+ | | | |
+ | file 1 |-----| stream 5 |
+ |_________| |__________|
+@end example
+
+@anchor{FFM}
+@section FFM, FFM2 formats
+
+FFM and FFM2 are formats used by ffserver. They allow storing a wide variety of
+video and audio streams and encoding options, and can store a moving time segment
+of an infinite movie or a whole movie.
+
+FFM is version specific, and there is limited compatibility of FFM files
+generated by one version of ffmpeg/ffserver and another version of
+ffmpeg/ffserver. It may work but it is not guaranteed to work.
+
+FFM2 is extensible while maintaining compatibility and should work between
+differing versions of tools. FFM2 is the default.
+
@section Status stream
-ffserver supports an HTTP interface which exposes the current status
-of the server.
+@command{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.
@@ -61,27 +172,8 @@
then the server will post a page with the status information when
the special stream @file{status.html} is requested.
-@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.
-
@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
-@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:
@@ -109,35 +201,6 @@
frame rates etc). Then install ffserver and ffmpeg, write a script to start
them up, and off you go.
-@section Troubleshooting
-
-@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.
-
-@subsection The audio and video lose sync after a while.
-
-Yes, they do.
-
-@subsection After a long while, the video update rate goes way down in WMP.
-
-Yes, it does. Who knows why?
-
-@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].
-
@section What else can it do?
You can replay video from .ffm files that was recorded earlier.
@@ -177,9 +240,6 @@
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.
-
@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
@@ -213,19 +273,6 @@
For example: @samp{http://localhost:8080/test.asf?date=2002-07-26T23:05:00}.
@c man end
-@section What is FFM, FFM2
-
-FFM and FFM2 are formats used by ffserver. They allow storing a wide variety of
-video and audio streams and encoding options, and can store a moving time segment
-of an infinite movie or a whole movie.
-
-FFM is version specific, and there is limited compatibility of FFM files
-generated by one version of ffmpeg/ffserver and another version of
-ffmpeg/ffserver. It may work but it is not guaranteed to work.
-
-FFM2 is extensible while maintaining compatibility and should work between
-differing versions of tools. FFM2 is the default.
-
@chapter Options
@c man begin OPTIONS
@@ -235,15 +282,536 @@
@table @option
@item -f @var{configfile}
-Use @file{configfile} instead of @file{/etc/ffserver.conf}.
+Read configuration file @file{configfile}. If not specified it will
+read by default from @file{/etc/ffserver.conf}.
+
@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.
+Enable no-launch mode. This option disables all the @code{Launch}
+directives within the various @code{<Feed>} sections. Since
+@command{ffserver} will not launch any @command{ffmpeg} instances, you
+will have to launch them manually.
+
@item -d
-Enable debug mode. This option increases log verbosity, directs log
-messages to stdout.
+Enable debug mode. This option increases log verbosity, and directs
+log messages to stdout. When specified, the @option{CustomLog} option
+is ignored.
@end table
+
+@chapter Configuration file syntax
+
+@command{ffserver} reads a configuration file containing global
+options and settings for each stream and feed.
+
+The configuration file consists of global options and dedicated
+sections, which must be introduced by "<@var{SECTION_NAME}
+@var{ARGS}>" on a separate line and must be terminated by a line in
+the form "</@var{SECTION_NAME}>". @var{ARGS} is optional.
+
+Currently the following sections are recognized: @samp{Feed},
+@samp{Stream}, @samp{Redirect}.
+
+A line starting with @code{#} is ignored and treated as a comment.
+
+Name of options and sections are case-insensitive.
+
+@section ACL syntax
+An ACL (Access Control List) specifies the address which are allowed
+to access a given stream, or to write a given feed.
+
+It accepts the folling forms
+@itemize
+@item
+Allow/deny access to @var{address}.
+@example
+ACL ALLOW <address>
+ACL DENY <address>
+@end example
+
+@item
+Allow/deny access to ranges of addresses from @var{first_address} to
+@var{last_address}.
+@example
+ACL ALLOW <first_address> <last_address>
+ACL DENY <first_address> <last_address>
+@end example
+@end itemize
+
+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.
+
+@section Global options
+@table @option
+@item Port @var{port_number}
+@item RTSPPort @var{port_number}
+
+Set TCP port number on which the HTTP/RTSP server is listening. You
+must select a different port from your standard HTTP web server if it
+is running on the same computer.
+
+If not specified, no corresponding server will be created.
+
+@item BindAddress @var{ip_address}
+@item RTSPBindAddress @var{ip_address}
+Set address on which the HTTP/RTSP server is bound. Only useful if you
+have several network interfaces.
+
+@item MaxHTTPConnections @var{n}
+Set number of simultaneous HTTP connections that can be handled. It
+has to be defined @emph{before} the @option{MaxClients} parameter,
+since it defines the @option{MaxClients} maximum limit.
+
+Default value is 2000.
+
+@item MaxClients @var{n}
+Set number of simultaneous requests that can be handled. Since
+@command{ffserver} is very fast, it is more likely that you will want
+to leave this high and use @option{MaxBandwidth}.
+
+Default value is 5.
+
+@item MaxBandwidth @var{kbps}
+Set the maximum amount of kbit/sec that you are prepared to consume
+when streaming to clients.
+
+Default value is 1000.
+
+@item CustomLog @var{filename}
+Set access log file (uses standard Apache log file format). '-' is the
+standard output.
+
+If not specified @command{ffserver} will produce no log.
+
+In case the commandline option @option{-d} is specified this option is
+ignored, and the log is written to standard output.
+
+@item NoDaemon
+Set no-daemon mode. This option is currently ignored since now
+@command{ffserver} will always work in no-daemon mode, and is
+deprecated.
+@end table
+
+@section Feed section
+
+A Feed section defines a feed provided to @command{ffserver}.
+
+Each live feed contains one video and/or audio sequence coming from an
+@command{ffmpeg} encoder or another @command{ffserver}. This sequence
+may be encoded simultaneously with several codecs at several
+resolutions.
+
+A feed instance specification is introduced by a line in the form:
+@example
+<Feed FEED_FILENAME>
+@end example
+
+where @var{FEED_FILENAME} specifies the unique name of the FFM stream.
+
+The following options are recognized within a Feed section.
+
+@table @option
+@item File @var{filename}
+@item ReadOnlyFile @var{filename}
+Set the path where the feed file is stored on disk.
+
+If not specified, the @file{/tmp/FEED.ffm} is assumed, where
+@var{FEED} is the feed name.
+
+If @option{ReadOnlyFile} is used the file is marked as read-only and
+it will not be deleted or updated.
+
+@item Truncate
+Truncate the feed file, rather than appending to it. By default
+@command{ffserver} will append data to the file, until the maximum
+file size value is reached (see @option{FileMaxSize} option).
+
+@item FileMaxSize @var{size}
+Set maximum size of the feed file in bytes. 0 means unlimited. The
+postfixes @code{K} (2^10), @code{M} (2^20), and @code{G} (2^30) are
+recognized.
+
+Default value is 5M.
+
+@item Launch @var{args}
+Launch an @command{ffmpeg} command when creating @command{ffserver}.
+
+@var{args} must be a sequence of arguments to be provided to an
+@command{ffmpeg} instance. The first provided argument is ignored, and
+it is replaced by a path with the same dirname of the @command{ffserver}
+instance, followed by the remaining argument and terminated with a
+path corresponding to the feed.
+
+When the launched process exits, @command{ffserver} will launch
+another program instance.
+
+In case you need a more complex @command{ffmpeg} configuration,
+e.g. if you need to generate multiple FFM feeds with a single
+@command{ffmpeg} instance, you should launch @command{ffmpeg} by hand.
+
+This option is ignored in case the commandline option @option{-n} is
+specified.
+
+@item ACL @var{spec}
+Specify the list of IP address which are allowed or denied to write
+the feed. Multiple ACL options can be specified.
+@end table
+
+@section Stream section
+
+A Stream section defines a stream provided by @command{ffserver}, and
+identified by a single name.
+
+The stream is sent when answering a request containing the stream
+name.
+
+A stream section must be introduced by the line:
+@example
+<Stream STREAM_NAME>
+@end example
+
+where @var{STREAM_NAME} specifies the unique name of the stream.
+
+The following options are recognized within a Stream section.
+
+Encoding options are marked with the @emph{encoding} tag, and they are
+used to set the encoding parameters, and are mapped to libavcodec
+encoding options. Not all encoding options are supported, in
+particular it is not possible to set encoder private options. In order
+to override the encoding options specified by @command{ffserver}, you
+can use the @command{ffmpeg} @option{override_ffserver} commandline
+option.
+
+Only one of the @option{Feed} and @option{File} options should be set.
+
+@table @option
+@item Feed @var{feed_name}
+Set the input feed. @var{feed_name} must correspond to an existing
+feed defined in a @code{Feed} section.
+
+When this option is set, encoding options are used to setup the
+encoding operated by the remote @command{ffmpeg} process.
+
+@item File @var{filename}
+Set the filename of the pre-recorded input file to stream.
+
+When this option is set, encoding options are ignored and the input
+file content is re-streamed as is.
+
+@item Format @var{format_name}
+Set the format of the output stream.
+
+Must be the name of a format recognized by FFmpeg. If set to
+@samp{status}, it is treated as a status stream.
+
+@item InputFormat @var{format_name}
+Set input format. If not specified, it is automatically guessed.
+
+@item Preroll @var{n}
+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.
+
+Default value is 0.
+
+@item StartSendOnKey
+Do not send stream until it gets the first key frame. By default
+@command{ffserver} will send data immediately.
+
+@item MaxTime @var{n}
+Set the number of seconds to run. This value set the maximum duration
+of the stream a client will be able to receive.
+
+A value of 0 means that no limit is set on the stream duration.
+
+@item ACL @var{spec}
+Set ACL for the stream.
+
+@item DynamicACL @var{spec}
+
+@item RTSPOption @var{option}
+
+@item MulticastAddress @var{address}
+
+@item MulticastPort @var{port}
+
+@item MulticastTTL @var{integer}
+
+@item NoLoop
+
+@item FaviconURL @var{url}
+Set favicon (favourite icon) for the server status page. It is ignored
+for regular streams.
+
+@item Author @var{value}
+@item Comment @var{value}
+@item Copyright @var{value}
+@item Title @var{value}
+Set metadata corresponding to the option.
+
+@item NoAudio
+@item NoVideo
+Suppress audio/video.
+
+@item AudioCodec @var{codec_name} (@emph{encoding,audio})
+Set audio codec.
+
+@item AudioBitRate @var{rate} (@emph{encoding,audio})
+Set bitrate for the audio stream in kbits per second.
+
+@item AudioChannels @var{n} (@emph{encoding,audio})
+Set number of audio channels.
+
+@item AudioSampleRate @var{n} (@emph{encoding,audio})
+Set 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.
+
+@item AVOptionAudio @var{option} @var{value} (@emph{encoding,audio})
+Set generic option for audio stream.
+
+@item AVPresetAudio @var{preset} (@emph{encoding,audio})
+Set preset for audio stream.
+
+@item VideoCodec @var{codec_name} (@emph{encoding,video})
+Set video codec.
+
+@item VideoBitRate @var{n} (@emph{encoding,video})
+Set bitrate for the video stream in kbits per second.
+
+@item VideoBitRateRange @var{range} (@emph{encoding,video})
+Set video bitrate range.
+
+A range must be specified in the form @var{minrate}-@var{maxrate}, and
+specifies the @option{minrate} and @option{maxrate} encoding options
+expressed in kbits per second.
+
+@item VideoBitRateRangeTolerance @var{n} (@emph{encoding,video})
+Set video bitrate tolerance in kbits per second.
+
+@item PixelFormat @var{pixel_format} (@emph{encoding,video})
+Set video pixel format.
+
+@item Debug @var{integer} (@emph{encoding,video})
+Set video @option{debug} encoding option.
+
+@item Strict @var{integer} (@emph{encoding,video})
+Set video @option{strict} encoding option.
+
+@item VideoBufferSize @var{n} (@emph{encoding,video})
+Set ratecontrol buffer size, expressed in KB.
+
+@item VideoFrameRate @var{n} (@emph{encoding,video})
+Set number of video frames per second.
+
+@item VideoSize (@emph{encoding,video})
+Set size of the video frame, must be an abbreviation or in the form
+@var{W}x@var{H}. See @ref{video size syntax,,the Video size section
+in the ffmpeg-utils(1) manual,ffmpeg-utils}.
+
+Default value is @code{160x128}.
+
+@item VideoIntraOnly (@emph{encoding,video})
+Transmit only intra frames (useful for low bitrates, but kills frame rate).
+
+@item VideoGopSize @var{n} (@emph{encoding,video})
+If non-intra only, an intra frame is transmitted every VideoGopSize
+frames. Video synchronization can only begin at an intra frame.
+
+@item VideoTag @var{tag} (@emph{encoding,video})
+Set video tag.
+
+@item VideoHighQuality (@emph{encoding,video})
+@item Video4MotionVector (@emph{encoding,video})
+
+@item BitExact (@emph{encoding,video})
+Set bitexact encoding flag.
+
+@item IdctSimple (@emph{encoding,video})
+Set simple IDCT algorithm.
+
+@item Qscale @var{n} (@emph{encoding,video})
+Enable constant quality encoding, and set video qscale (quantization
+scale) value, expressed in @var{n} QP units.
+
+@item VideoQMin @var{n} (@emph{encoding,video})
+@item VideoQMax @var{n} (@emph{encoding,video})
+Set video qmin/qmax.
+
+@item VideoQDiff @var{integer} (@emph{encoding,video})
+Set video @option{qdiff} encoding option.
+
+@item LumiMask @var{float} (@emph{encoding,video})
+@item DarkMask @var{float} (@emph{encoding,video})
+Set @option{lumi_mask}/@option{dark_mask} encoding options.
+
+@item AVOptionVideo @var{option} @var{value} (@emph{encoding,video})
+Set generic option for video stream.
+
+@item AVPresetVideo @var{preset} (@emph{encoding,video})
+Set preset for video stream.
+
+@var{preset} must be the path of a preset file.
+@end table
+
+@subsection Server status stream
+
+A server status stream is a special stream which is used to show
+statistics about the @command{ffserver} operations.
+
+It must be specified setting the option @option{Format} to
+@samp{status}.
+
+@section Redirect section
+
+A redirect section specifies where to redirect the requested URL to
+another page.
+
+A redirect section must be introduced by the line:
+@example
+<Redirect NAME>
+@end example
+
+where @var{NAME} is the name of the page which should be redirected.
+
+It only accepts the option @option{URL}, which specify the redirection
+URL.
+
+@chapter Stream examples
+
+@itemize
+@item
+Multipart JPEG
+@example
+<Stream test.mjpg>
+Feed feed1.ffm
+Format mpjpeg
+VideoFrameRate 2
+VideoIntraOnly
+NoAudio
+Strict -1
+</Stream>
+@end example
+
+@item
+Single JPEG
+@example
+<Stream test.jpg>
+Feed feed1.ffm
+Format jpeg
+VideoFrameRate 2
+VideoIntraOnly
+VideoSize 352x240
+NoAudio
+Strict -1
+</Stream>
+@end example
+
+@item
+Flash
+@example
+<Stream test.swf>
+Feed feed1.ffm
+Format swf
+VideoFrameRate 2
+VideoIntraOnly
+NoAudio
+</Stream>
+@end example
+
+@item
+ASF compatible
+@example
+<Stream test.asf>
+Feed feed1.ffm
+Format asf
+VideoFrameRate 15
+VideoSize 352x240
+VideoBitRate 256
+VideoBufferSize 40
+VideoGopSize 30
+AudioBitRate 64
+StartSendOnKey
+</Stream>
+@end example
+
+@item
+MP3 audio
+@example
+<Stream test.mp3>
+Feed feed1.ffm
+Format mp2
+AudioCodec mp3
+AudioBitRate 64
+AudioChannels 1
+AudioSampleRate 44100
+NoVideo
+</Stream>
+@end example
+
+@item
+Ogg Vorbis audio
+@example
+<Stream test.ogg>
+Feed feed1.ffm
+Title "Stream title"
+AudioBitRate 64
+AudioChannels 2
+AudioSampleRate 44100
+NoVideo
+</Stream>
+@end example
+
+@item
+Real with audio only at 32 kbits
+@example
+<Stream test.ra>
+Feed feed1.ffm
+Format rm
+AudioBitRate 32
+NoVideo
+</Stream>
+@end example
+
+@item
+Real with audio and video at 64 kbits
+@example
+<Stream test.rm>
+Feed feed1.ffm
+Format rm
+AudioBitRate 32
+VideoBitRate 128
+VideoFrameRate 25
+VideoGopSize 25
+</Stream>
+@end example
+
+@item
+For stream coming from a file: you only need to set the input filename
+and optionally a new format.
+
+@example
+<Stream file.rm>
+File "/usr/local/httpd/htdocs/tlive.rm"
+NoAudio
+</Stream>
+@end example
+
+@example
+<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>
+@end example
+@end itemize
+
@c man end
@include config.texi
diff --git a/doc/fftools-common-opts.texi b/doc/fftools-common-opts.texi
index 6d453ed..ff6478a 100644
--- a/doc/fftools-common-opts.texi
+++ b/doc/fftools-common-opts.texi
@@ -128,6 +128,9 @@
@item -layouts
Show channel names and standard channel layouts.
+@item -colors
+Show recognized color names.
+
@item -loglevel [repeat+]@var{loglevel} | -v [repeat+]@var{loglevel}
Set the logging level used by the library.
Adding "repeat+" indicates that repeated log output should not be compressed
@@ -247,6 +250,10 @@
@end table
@end table
+@item -opencl_bench
+Benchmark all available OpenCL devices and show the results. This option
+is only available when FFmpeg has been compiled with @code{--enable-opencl}.
+
@item -opencl_options options (@emph{global})
Set OpenCL environment options. This option is only available when
FFmpeg has been compiled with @code{--enable-opencl}.
diff --git a/doc/filters.texi b/doc/filters.texi
index fe4ad36..f3d698f 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -198,7 +198,7 @@
pads must be connected. A filtergraph is considered valid if all the
filter input and output pads of all the filterchains are connected.
-Libavfilter will automatically insert scale filters where format
+Libavfilter will automatically insert @ref{scale} filters where format
conversion is required. It is possible to specify swscale flags
for those automatically inserted scalers by prepending
@code{sws_flags=@var{flags};}
@@ -435,6 +435,70 @@
@end example
@end itemize
+@section aeval
+
+Modify an audio signal according to the specified expressions.
+
+This filter accepts one or more expressions (one for each channel),
+which are evaluated and used to modify a corresponding audio signal.
+
+This filter accepts the following options:
+
+@table @option
+@item exprs
+Set the '|'-separated expressions list for each separate channel. If
+the number of input channels is greater than the number of
+expressions, the last specified expression is used for the remaining
+output channels.
+
+@item channel_layout, c
+Set output channel layout. If not specified, the channel layout is
+specified by the number of expressions. If set to @samp{same}, it will
+use by default the same input channel layout.
+@end table
+
+Each expression in @var{exprs} can contain the following constants and functions:
+
+@table @option
+@item ch
+channel number of the current expression
+
+@item n
+number of the evaluated sample, starting from 0
+
+@item s
+sample rate
+
+@item t
+time of the evaluated sample expressed in seconds
+
+@item nb_in_channels
+@item nb_out_channels
+input and output number of channels
+
+@item val(CH)
+the value of input channel with number @var{CH}
+@end table
+
+Note: this filter is slow. For faster processing you should use a
+dedicated filter.
+
+@subsection Examples
+
+@itemize
+@item
+Half volume:
+@example
+aeval=val(ch)/2:c=same
+@end example
+
+@item
+Invert phase of the second channel:
+@example
+eval=val(0)|-val(1)
+@end example
+@end itemize
+
@section afade
Apply fade-in/out effect to input audio.
@@ -541,6 +605,8 @@
@item channel_layouts
A '|'-separated list of requested channel layouts.
+See @ref{channel layout syntax,,the Channel Layout section in the ffmpeg-utils(1) manual,ffmpeg-utils}
+for the required syntax.
@end table
If a parameter is omitted, all values are allowed.
@@ -1636,6 +1702,12 @@
pan="stereo: c0=FR : c1=FR"
@end example
+@section replaygain
+
+ReplayGain scanner filter. This filter takes an audio stream as an input and
+outputs it unchanged.
+At end of filtering it displays @code{track_gain} and @code{track_peak}.
+
@section resample
Convert the audio sample format, sample rate and channel layout. This filter is
@@ -1888,7 +1960,8 @@
@item exprs
Set the '|'-separated expressions list for each separate channel. In case the
@option{channel_layout} option is not specified, the selected channel layout
-depends on the number of provided expressions.
+depends on the number of provided expressions. Otherwise the last
+specified expression is applied to the remaining output channels.
@item channel_layout, c
Set the channel layout. The number of channels in the specified layout
@@ -2404,6 +2477,24 @@
@example
blend=all_expr='if(eq(mod(X,2),mod(Y,2)),A,B)'
@end example
+
+@item
+Apply uncover left effect:
+@example
+blend=all_expr='if(gte(N*SW+X,W),A,B)'
+@end example
+
+@item
+Apply uncover down effect:
+@example
+blend=all_expr='if(gte(Y-N*SH,0),A,B)'
+@end example
+
+@item
+Apply uncover up-left effect:
+@example
+blend=all_expr='if(gte(T*SH*40+Y,H)*gte((T*40*SW+X)*W/H,W),A,B)'
+@end example
@end itemize
@section boxblur
@@ -3191,8 +3282,8 @@
the input width and height. Default to 0.
@item color, c
-Specify the color of the box to write, it can be the name of a color
-(case insensitive match) or a 0xRRGGBB[AA] sequence. If the special
+Specify the color of the box to write. For the general syntax of this option,
+check the "Color" section in the ffmpeg-utils manual. If the special
value @code{invert} is used, the box edge color is the same as the
video with inverted luma.
@@ -3288,12 +3379,10 @@
framed. Default to 0.
@item color, c
-Specify the color of the grid, it can be the name of a color
-(case insensitive match) or a 0xRRGGBB[AA] sequence. If the special
+Specify the color of the grid. For the general syntax of this option,
+check the "Color" section in the ffmpeg-utils manual. If the special
value @code{invert} is used, the grid color is the same as the
video with inverted luma.
-Note that you can append opacity value (in range of 0.0 - 1.0)
-to color name after @@ sign.
@item thickness, t
The expression which sets the thickness of the grid line. Default value is @code{1}.
@@ -3373,9 +3462,9 @@
The default value of @var{box} is 0.
@item boxcolor
-The color to be used for drawing box around text.
-Either a string (e.g. "yellow") or in 0xRRGGBB[AA] format
-(e.g. "0xff00ff"), possibly followed by an alpha specifier.
+The color to be used for drawing box around text. For the syntax of this
+option, check the "Color" section in the ffmpeg-utils manual.
+
The default value of @var{boxcolor} is "white".
@item expansion
@@ -3388,9 +3477,9 @@
If true, check and fix text coords to avoid clipping.
@item fontcolor
-The color to be used for drawing fonts.
-Either a string (e.g. "red") or in 0xRRGGBB[AA] format
-(e.g. "0xff000033"), possibly followed by an alpha specifier.
+The color to be used for drawing fonts. For the syntax of this option, check
+the "Color" section in the ffmpeg-utils manual.
+
The default value of @var{fontcolor} is "black".
@item fontfile
@@ -3430,9 +3519,9 @@
libfreetype flags.
@item shadowcolor
-The color to be used for drawing a shadow behind the drawn text. It
-can be a color name (e.g. "yellow") or a string in the 0xRRGGBB[AA]
-form (e.g. "0xff00ff"), possibly followed by an alpha specifier.
+The color to be used for drawing a shadow behind the drawn text. For the
+syntax of this option, check the "Color" section in the ffmpeg-utils manual.
+
The default value of @var{shadowcolor} is "black".
@item shadowx
@@ -3766,6 +3855,32 @@
@end example
@end itemize
+@section elbg
+
+Apply a posterize effect using the ELBG (Enhanced LBG) algorithm.
+
+For each input image, the filter will compute the optimal mapping from
+the input to the output given the codebook length, that is the number
+of distinct output colors.
+
+This filter accepts the following options.
+
+@table @option
+@item codebook_length, l
+Set codebook length. The value must be a positive integer, and
+represents the number of distinct output colors. Default value is 256.
+
+@item nb_steps, n
+Set the maximum number of iterations to apply for computing the optimal
+mapping. The higher the value the better the result and the higher the
+computation time. Default value is 1.
+
+@item seed, s
+Set a random seed, must be an integer included between 0 and
+UINT32_MAX. If not specified, or if explicitly set to -1, the filter
+will try to use a good random seed on a best effort basis.
+@end table
+
@section fade
Apply fade-in/out effect to input video.
@@ -3785,7 +3900,8 @@
@item nb_frames, n
The number of frames for which the fade effect has to last. At the end of the
fade-in effect the output video will have the same intensity as the input video,
-at the end of the fade-out transition the output video will be completely black.
+at the end of the fade-out transition the output video will be filled with the
+selected @option{color}.
Default is 25.
@item alpha
@@ -3800,8 +3916,12 @@
@item duration, d
The number of seconds for which the fade effect has to last. At the end of the
fade-in effect the output video will have the same intensity as the input video,
-at the end of the fade-out transition the output video will be completely black.
+at the end of the fade-out transition the output video will be filled with the
+selected @option{color}.
If both duration and nb_frames are specified, duration is used. Default is 0.
+
+@item color, c
+Specify the color of the fade. Default is "black".
@end table
@subsection Examples
@@ -3832,9 +3952,9 @@
@end example
@item
-Make first 5 frames black, then fade in from frame 5-24:
+Make first 5 frames yellow, then fade in from frame 5-24:
@example
-fade=in:5:20
+fade=in:5:20:color=yellow
@end example
@item
@@ -4259,6 +4379,7 @@
@end example
@end itemize
+@anchor{fps}
@section fps
Convert the video to specified constant frame rate by duplicating or dropping
@@ -4357,9 +4478,9 @@
A frei0r effect parameter can be a boolean (whose values are specified
with "y" and "n"), a double, a color (specified by the syntax
-@var{R}/@var{G}/@var{B}, @var{R}, @var{G}, and @var{B} being float
-numbers from 0.0 to 1.0) or by an @code{av_parse_color()} color
-description), a position (specified by the syntax @var{X}/@var{Y},
+@var{R}/@var{G}/@var{B}, (@var{R}, @var{G}, and @var{B} being float
+numbers from 0.0 to 1.0) or by a color description specified in the "Color"
+section in the ffmpeg-utils manual), a position (specified by the syntax @var{X}/@var{Y},
@var{X} and @var{Y} being float numbers) and a string.
The number and kind of parameters depend on the loaded effect. If an
@@ -5254,6 +5375,65 @@
@end example
@end itemize
+@section mergeplanes
+
+Merge color channel components from several video streams.
+
+The filter accepts up to 4 input streams, and merge selected input
+planes to the output video.
+
+This filter accepts the following options:
+@table @option
+@item mapping
+Set input to output plane mapping. Default is @code{0}.
+
+The mappings is specified as a bitmap. It should be specified as a
+hexadecimal number in the form 0xAa[Bb[Cc[Dd]]]. 'Aa' describes the
+mapping for the first plane of the output stream. 'A' sets the number of
+the input stream to use (from 0 to 3), and 'a' the plane number of the
+corresponding input to use (from 0 to 3). The rest of the mappings is
+similar, 'Bb' describes the mapping for the output stream second
+plane, 'Cc' describes the mapping for the output stream third plane and
+'Dd' describes the mapping for the output stream fourth plane.
+
+@item format
+Set output pixel format. Default is @code{yuva444p}.
+@end table
+
+@subsection Examples
+
+@itemize
+@item
+Merge three gray video streams of same width and height into single video stream:
+@example
+[a0][a1][a2]mergeplanes=0x001020:yuv444p
+@end example
+
+@item
+Merge 1st yuv444p stream and 2nd gray video stream into yuva444p video stream:
+@example
+[a0][a1]mergeplanes=0x00010210:yuva444p
+@end example
+
+@item
+Swap Y and A plane in yuva444p stream:
+@example
+format=yuva444p,mergeplanes=0x03010200:yuva444p
+@end example
+
+@item
+Swap U and V plane in yuv420p stream:
+@example
+format=yuv420p,mergeplanes=0x000201:yuv420p
+@end example
+
+@item
+Cast a rgb24 clip to yuv444p:
+@example
+format=rgb24,mergeplanes=0x000102:yuv444p
+@end example
+@end itemize
+
@section mcdeint
Apply motion-compensation deinterlacing.
@@ -5840,8 +6020,8 @@
The default value of @var{x} and @var{y} is 0.
@item color
-Specify the color of the padded area, it can be the name of a color
-(case insensitive match) or a 0xRRGGBB[AA] sequence.
+Specify the color of the padded area. For the syntax of this option,
+check the "Color" section in the ffmpeg-utils manual.
The default value of @var{color} is "black".
@end table
@@ -6357,9 +6537,11 @@
load and make pullup usable in realtime on slow machines.
@end table
-For example to inverse telecined NTSC input:
+For best results (without duplicated frames in the output file) it is
+necessary to change the output frame rate. For example, to inverse
+telecine NTSC input:
@example
-pullup,fps=24000/1001
+ffmpeg -i input -vf pullup -r 24000/1001 ...
@end example
@section removelogo
@@ -6421,9 +6603,11 @@
@item fillcolor, c
Set the color used to fill the output area not covered by the rotated
-image. If the special value "none" is selected then no background is
-printed (useful for example if the background is never shown). Default
-value is "black".
+image. For the generalsyntax of this option, check the "Color" section in the
+ffmpeg-utils manual. If the special value "none" is selected then no
+background is printed (useful for example if the background is never shown).
+
+Default value is "black".
@end table
The expressions for the angle and the output size can contain the
@@ -6553,6 +6737,7 @@
Each chroma option value, if not explicitly specified, is set to the
corresponding luma option value.
+@anchor{scale}
@section scale
Scale (resize) the input video, using the libswscale library.
@@ -6611,8 +6796,8 @@
the default flags.
@item size, s
-Set the video size, the value must be a valid abbreviation or in the
-form @var{width}x@var{height}.
+Set the video size. For the syntax of this option, check the "Video size"
+section in the ffmpeg-utils manual.
@item in_color_matrix
@item out_color_matrix
@@ -6735,7 +6920,12 @@
@item hsub
@item vsub
-horizontal and vertical chroma subsample values. For example for the
+horizontal and vertical input chroma subsample values. For example for the
+pixel format "yuv422p" @var{hsub} is 2 and @var{vsub} is 1.
+
+@item ohsub
+@item ovsub
+horizontal and vertical output chroma subsample values. For example for the
pixel format "yuv422p" @var{hsub} is 2 and @var{vsub} is 1.
@end table
@@ -6885,6 +7075,31 @@
@end table
+The parameter @var{sar} is an expression containing
+the following constants:
+
+@table @option
+@item E, PI, PHI
+the corresponding mathematical approximated values for e
+(euler number), pi (greek PI), phi (golden ratio)
+
+@item w, h
+the input width and height
+
+@item a
+same as @var{w} / @var{h}
+
+@item sar
+input sample aspect ratio
+
+@item dar
+input display aspect ratio, it is the same as (@var{w} / @var{h}) * @var{sar}
+
+@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.
+@end table
+
@subsection Examples
@itemize
@@ -6978,8 +7193,8 @@
@var{num}/@var{den}
@item s
-size of the input frame, expressed in the form
-@var{width}x@var{height}
+size of the input frame. For the syntax of this option, check the "Video size"
+section in the ffmpeg-utils manual.
@item i
interlaced mode ("P" for "progressive", "T" for top field first, "B"
@@ -7247,8 +7462,10 @@
@item original_size
Specify the size of the original video, the video for which the ASS file
-was composed. Due to a misdesign in ASS aspect ratio arithmetic, this is
-necessary to correctly scale the fonts if the aspect ratio has been changed.
+was composed. For the syntax of this option, check the "Video size" section in
+the ffmpeg-utils manual. Due to a misdesign in ASS aspect ratio arithmetic,
+this is necessary to correctly scale the fonts if the aspect ratio has been
+changed.
@item charenc
Set subtitles input character encoding. @code{subtitles} filter only. Only
@@ -7358,8 +7575,8 @@
@table @option
@item layout
-Set the grid size (i.e. the number of lines and columns) in the form
-"@var{w}x@var{h}".
+Set the grid size (i.e. the number of lines and columns). For the syntax of
+this option, check the "Video size" section in the ffmpeg-utils manual.
@item nb_frames
Set the maximum number of frames to render in the given area. It must be less
@@ -7375,9 +7592,9 @@
refer to the pad video filter.
@item color
-Specify the color of the unused area, it can be the name of a color
-(case insensitive match) or a 0xRRGGBB[AA] sequence.
-The default value of @var{color} is "black".
+Specify the color of the unused areaFor the syntax of this option, check the
+"Color" section in the ffmpeg-utils manual. The default value of @var{color}
+is "black".
@end table
@subsection Examples
@@ -8145,7 +8362,9 @@
@table @option
@item video_size
-Specify the size (width and height) of the buffered video frames.
+Specify the size (width and height) of the buffered video frames. For the
+syntax of this option, check the "Video size" section in the ffmpeg-utils
+manual.
@item width
Input video width.
@@ -8245,7 +8464,8 @@
Default value is 110.
@item size, s
-Set the size of the output video.
+Set the size of the output video. For the syntax of this option, check
+the "Video size" section in the ffmpeg-utils manual.
If @option{filename} or @option{pattern} is specified, the size is set
by default to the width of the specified initial state row, and the
@@ -8363,7 +8583,8 @@
value is "25".
@item size, s
-Set frame size. Default value is "640x480".
+Set frame size. For the syntax of this option, check the "Video
+size" section in the ffmpeg-utils manual. Default value is "640x480".
@item start_scale
Set the initial scale value. Default value is 3.0.
@@ -8445,8 +8666,8 @@
@table @option
@item size
-The size of the video to generate, may be a string of the form
-@var{width}x@var{height} or a frame size abbreviation.
+The size of the video to generate. For the syntax of this option, check the
+"Video size" section in the ffmpeg-utils manual.
@item framerate
Framerate of the generated video, may be a string of the form
@@ -8534,7 +8755,8 @@
a dead cell.
@item size, s
-Set the size of the output video.
+Set the size of the output video. For the syntax of this option, check the
+"Video size" section in the ffmpeg-utils manual.
If @option{filename} is specified, the size is set by default to the
same size of the input file. If @option{size} is set, it must contain
@@ -8562,6 +8784,9 @@
@item mold_color
Set mold color, for definitely dead and moldy cells.
+
+For the syntax of these 3 color options, check the "Color" section in the
+ffmpeg-utils manual.
@end table
@subsection Examples
@@ -8631,9 +8856,8 @@
@item color, c
Specify the color of the source, only available in the @code{color}
-source. It can be the name of a color (case insensitive match) or a
-0xRRGGBB[AA] sequence, possibly followed by an alpha specifier. The
-default value is "black".
+source. For the syntax of this option, check the "Color" section in the
+ffmpeg-utils manual.
@item level
Specify the level of the Hald CLUT, only available in the @code{haldclutsrc}
@@ -8642,9 +8866,9 @@
coded on a @code{1/(N*N)} scale.
@item size, s
-Specify the size of the sourced video, it may be a string of the form
-@var{width}x@var{height}, or the name of a size abbreviation. The
-default value is "320x240".
+Specify the size of the sourced video. For the syntax of this option, check the
+"Video size" section in the ffmpeg-utils manual. The default value is
+"320x240".
This option is not available with the @code{haldclutsrc} filter.
@@ -8773,7 +8997,8 @@
Default value is @samp{lissajous}.
@item size, s
-Set the video size for the output. Default value is @code{400x400}.
+Set the video size for the output. For the syntax of this option, check the "Video size"
+section in the ffmpeg-utils manual. Default value is @code{400x400}.
@item rate, r
Set the output frame rate. Default value is @code{25}.
@@ -8912,8 +9137,9 @@
activated. Default is @code{0}.
@item size
-Set the video size. This option is for video only. Default and minimum
-resolution is @code{640x480}.
+Set the video size. This option is for video only. For the syntax of this
+option, check the "Video size" section in the ffmpeg-utils manual. Default
+and minimum resolution is @code{640x480}.
@item meter
Set the EBU scale meter. Default is @code{9}. Common values are @code{9} and
@@ -9555,7 +9781,9 @@
@table @option
@item size, s
-Specify the video size for the output. Default value is @code{640x512}.
+Specify the video size for the output. For the syntax of this option, check
+the "Video size" section in the ffmpeg-utils manual. Default value is
+@code{640x512}.
@item slide
Specify if the spectrum should slide along the window. Default value is
@@ -9609,6 +9837,23 @@
alternative color scheme. @code{0} is no saturation at all.
Saturation must be in [-10.0, 10.0] range.
Default value is @code{1}.
+
+@item win_func
+Set window function.
+
+It accepts the following values:
+@table @samp
+@item none
+No samples pre-processing (do not expect this to be faster)
+@item hann
+Hann window
+@item hamming
+Hamming window
+@item blackman
+Blackman window
+@end table
+
+Default value is @code{hann}.
@end table
The usage is very similar to the showwaves filter; see the examples in that
@@ -9639,7 +9884,9 @@
@table @option
@item size, s
-Specify the video size for the output. Default value is "600x240".
+Specify the video size for the output. For the syntax of this option, check
+the "Video size" section in the ffmpeg-utils manual. Default value
+is "600x240".
@item mode
Set display mode.
diff --git a/doc/general.texi b/doc/general.texi
index 647c5e2..a3221d5 100644
--- a/doc/general.texi
+++ b/doc/general.texi
@@ -249,6 +249,8 @@
@item GXF @tab X @tab X
@tab General eXchange Format SMPTE 360M, used by Thomson Grass Valley
playout servers.
+@item HNM @tab @tab X
+ @tab Only version 4 supported, used in some games from Cryo Interactive
@item iCEDraw File @tab @tab X
@item ICO @tab X @tab X
@tab Microsoft Windows ICO
@@ -338,6 +340,7 @@
@item raw H.261 @tab X @tab X
@item raw H.263 @tab X @tab X
@item raw H.264 @tab X @tab X
+@item raw HEVC @tab @tab X
@item raw Ingenient MJPEG @tab @tab X
@item raw MJPEG @tab X @tab X
@item raw MLP @tab @tab X
@@ -607,6 +610,8 @@
@item H.263+ / H.263-1998 / H.263 version 2 @tab X @tab X
@item H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 @tab E @tab X
@tab encoding supported through external library libx264
+@item HEVC @tab @tab X
+@item HNM version 4 @tab @tab X
@item HuffYUV @tab X @tab X
@item HuffYUV FFmpeg variant @tab X @tab X
@item IBM Ultimotion @tab @tab X
@@ -658,7 +663,6 @@
@item Mobotix MxPEG video @tab @tab X
@item Motion Pixels video @tab @tab X
@item MPEG-1 video @tab X @tab X
-@item MPEG-1/2 video XvMC (X-Video Motion Compensation) @tab @tab X
@item MPEG-2 video @tab X @tab X
@item MPEG-4 part 2 @tab X @tab X
@tab libxvidcore can be used alternatively for encoding.
@@ -939,7 +943,6 @@
@item Vorbis @tab E @tab X
@tab A native but very primitive encoder exists.
@item Voxware MetaSound @tab @tab X
- @tab imperfect and incomplete support
@item WavPack @tab X @tab X
@item Westwood Audio (SND1) @tab @tab X
@item Windows Media Audio 1 @tab X @tab X
diff --git a/doc/git-howto.txt b/doc/git-howto.txt
deleted file mode 100644
index 5ba72ee..0000000
--- a/doc/git-howto.txt
+++ /dev/null
@@ -1,273 +0,0 @@
-
-About Git write access:
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Before everything else, you should know how to use GIT properly.
-Luckily Git comes with excellent documentation.
-
- git --help
- man git
-
-shows you the available subcommands,
-
- git <command> --help
- man git-<command>
-
-shows information about the subcommand <command>.
-
-The most comprehensive manual is the website Git Reference
-
-http://gitref.org/
-
-For more information about the Git project, visit
-
-http://git-scm.com/
-
-Consult these resources whenever you have problems, they are quite exhaustive.
-
-You do not need a special username or password.
-All you need is to provide a ssh public key to the Git server admin.
-
-What follows now is a basic introduction to Git and some FFmpeg-specific
-guidelines. Read it at least once, if you are granted commit privileges to the
-FFmpeg project you are expected to be familiar with these rules.
-
-
-
-I. BASICS:
-==========
-
-0. Get GIT:
-
- Most distributions have a git package, if not
- You can get git from http://git-scm.com/
-
-
-1. Cloning the source tree:
-
- git clone git://source.ffmpeg.org/ffmpeg <target>
-
- This will put the FFmpeg sources into the directory <target>.
-
- git clone git@source.ffmpeg.org:ffmpeg <target>
-
- This will put the FFmpeg sources into the directory <target> and let
- you push back your changes to the remote repository.
-
-
-2. Updating the source tree to the latest revision:
-
- git pull (--ff-only)
-
- 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.
- Caveat: Since merge commits are forbidden at least for the initial
- months of git --ff-only or --rebase (see below) are recommended.
- --ff-only will fail and not create merge commits if your branch
- has diverged (has a different history) from the tracked branch.
-
-2.a Rebasing your local branches:
-
- git pull --rebase
-
- 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
- FFmpeg's master tree. The master tree will reject pushes with merge commits.
-
-
-3. Adding/removing files/directories:
-
- git add [-A] <filename/dirname>
- git rm [-r] <filename/dirname>
-
- 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.
-
-
-4. Showing modifications:
-
- git diff <filename(s)>
-
- will show all local modifications in your working directory as unified diff.
-
-
-5. Inspecting the changelog:
-
- git log <filename(s)>
-
- You may also use the graphical tools like gitview or gitk or the web
- interface available at http://source.ffmpeg.org
-
-6. Checking source tree status:
-
- git status
-
- detects all the changes you made and lists what actions will be taken in case
- of a commit (additions, modifications, deletions, etc.).
-
-
-7. Committing:
-
- git diff --check
-
- 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
-
- git diff -w -b <filename(s)>
-
- Also check the output of
-
- git status
-
- to make sure you don't have untracked files or deletions.
-
- git add [-i|-p|-A] <filenames/dirnames>
-
- Make sure you have told git your name and email address, e.g. by running
- git config --global user.name "My Name"
- git config --global user.email my@email.invalid
- (--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.
-
- git commit
-
- 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
-
- git config core.editor
-
- or set by one of the following environment variables:
- GIT_EDITOR, VISUAL or 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.
-
-
-8. Renaming/moving/copying files or contents of files:
-
- Git automatically tracks such changes, making those normal commits.
-
- mv/cp path/file otherpath/otherfile
-
- git add [-A] .
-
- git commit
-
- Do not move, rename or copy files of which you are not the maintainer without
- discussing it on the mailing list first!
-
-9. Reverting broken commits
-
- git revert <commit>
-
- git revert will generate a revert commit. This will not make the faulty
- commit disappear from the history.
-
- git reset <commit>
-
- git reset will uncommit the changes till <commit> rewriting the current
- branch history.
-
- git commit --amend
-
- allows to amend the last commit details quickly.
-
- git rebase -i origin/master
-
- will replay local commits over the main repository allowing to edit,
- merge or remove some of them in the process.
-
- Note that the reset, commit --amend and rebase rewrite history, so you
- should use them ONLY on your local or topic branches.
-
- The main repository will reject those changes.
-
-10. Preparing a patchset.
-
- git format-patch <commit> [-o 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
-
- git send-email <commit list|directory>
-
- 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
-
- git push
-
- Will push the changes to the default remote (origin).
- Git will prevent you from pushing changes if the local and remote trees are
- out of sync. Refer to 2 and 2.a to sync the local tree.
-
- git remote add <name> <url>
-
- 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.
-
- git push <remote> <refspec>
-
- Will push the changes to the remote repository. Omitting refspec makes git
- push update all the remote branches matching the local ones.
-
-13. Finding a specific svn revision
-
- Since version 1.7.1 git supports ':/foo' syntax for specifying commits
- based on a regular expression. see man gitrevisions
-
- git show :/'as revision 23456'
-
- will show the svn changeset r23456. With older git versions searching in
- the git log output is the easiest option (especially if a pager with
- search capabilities is used).
- This commit can be checked out with
-
- git checkout -b svn_23456 :/'as revision 23456'
-
- or for git < 1.7.1 with
-
- git checkout -b svn_23456 $SHA1
-
- where $SHA1 is the commit SHA1 from the 'git log' output.
-
-
-Contact the project admins <root at ffmpeg dot org> if you have technical
-problems with the GIT server.
diff --git a/doc/indevs.texi b/doc/indevs.texi
index 1d70138..72b1493 100644
--- a/doc/indevs.texi
+++ b/doc/indevs.texi
@@ -495,10 +495,13 @@
To list the PulseAudio source devices and their properties you can invoke
the command @command{pactl list sources}.
+More information about PulseAudio can be found on @url{http://www.pulseaudio.org}.
+
@subsection Options
@table @option
@item server
-Connect to a specific server. Default server is used when not provided.
+Connect to a specific PulseAudio server, specified by an IP address.
+Default server is used when not provided.
@item name
Specify the application name PulseAudio will use when showing active clients,
diff --git a/doc/issue_tracker.txt b/doc/issue_tracker.txt
index 27b0009..33b3535 100644
--- a/doc/issue_tracker.txt
+++ b/doc/issue_tracker.txt
@@ -1,4 +1,4 @@
-FFmpeg's bug/patch/feature request tracker manual
+FFmpeg's bug/feature request tracker manual
=================================================
NOTE: This is a draft.
@@ -11,7 +11,7 @@
Issues can be different kinds of things we want to keep track of
but that do not belong into the source tree itself. This includes
-bug reports, patches, feature requests and license violations. We
+bug reports, feature requests and license violations. We
might add more items to this list in the future, so feel free to
propose a new `type of issue' on the ffmpeg-devel mailing list if
you feel it is worth tracking.
@@ -28,6 +28,9 @@
Type:
-----
+art
+ Artwork such as photos, music, banners, and logos.
+
bug / defect
An error, flaw, mistake, failure, or fault in FFmpeg or libav* that
prevents it from behaving as intended.
@@ -41,20 +44,18 @@
license violation
ticket to keep track of (L)GPL violations of ffmpeg by others
-patch
- A patch as generated by diff which conforms to the patch submission and
- development policy.
-
+sponsoring request
+ Developer requests for hardware, software, specifications, money,
+ refunds, etc.
Priority:
---------
critical
- Bugs and patches which deal with data loss and security issues.
+ Bugs about data loss and security issues.
No feature request can be critical.
important
- Bugs which make FFmpeg unusable for a significant number of users, and
- patches fixing them.
+ Bugs which make FFmpeg unusable for a significant number of users.
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,
@@ -68,7 +69,7 @@
minor
- Bugs and patches about things like spelling errors, "mp2" instead of
+ Bugs 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.
@@ -103,13 +104,13 @@
reproduction is not needed as the bug is already understood.
-Type/Status/Substatus:
+Type/Status:
----------
-*/new/new
- Initial state of new bugs, patches and feature requests submitted by
+*/new
+ Initial state of new bugs and feature requests submitted by
users.
-*/open/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,
@@ -117,9 +118,7 @@
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.
+ Bugs or feature requests which are duplicates.
Note, if you mark something as duplicate, do not forget setting the
superseder so bug reports are properly linked.
@@ -134,7 +133,7 @@
bug/closed/fixed
Bugs which have to the best of our knowledge been fixed.
-bug/closed/wont_fix
+bug/closed/wontfix
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.
@@ -148,33 +147,15 @@
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/closed/implemented
+feature_request/closed/fixed
Feature requests which have been implemented.
-feature_request/closed/wont_implement
+feature_request/closed/wontfix
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 ffmpeg-dev first!
-
Note2, if you provide the requested info do not forget to remove the
-needs_more_info substatus.
+needs_more_info resolution.
Component:
----------
diff --git a/doc/libavutil.texi b/doc/libavutil.texi
index 50b0d0e..5ec7e84 100644
--- a/doc/libavutil.texi
+++ b/doc/libavutil.texi
@@ -16,7 +16,25 @@
multimedia programming. It contains safe portable string functions,
random number generators, data structures, additional mathematics
functions, cryptography and multimedia related functionality (like
-enumerations for pixel and sample formats).
+enumerations for pixel and sample formats). It is not a library for
+code needed by both libavcodec and libavformat.
+
+The goals for this library is to be:
+
+@table @strong
+@item Modular
+It should have few interdependencies and the possibility of disabling individual
+parts during @command{./configure}.
+
+@item Small
+Both sources and objects should be small.
+
+@item Efficient
+It should have low CPU and memory usage.
+
+@item Useful
+It should avoid useless features that almost no one needs.
+@end table
@c man end DESCRIPTION
diff --git a/doc/muxers.texi b/doc/muxers.texi
index bd7088b..dbb52e8 100644
--- a/doc/muxers.texi
+++ b/doc/muxers.texi
@@ -146,6 +146,40 @@
See also the @ref{md5} muxer.
+@anchor{gif}
+@section gif
+
+Animated GIF muxer.
+
+It accepts the following options:
+
+@table @option
+@item loop
+Set the number of times to loop the output. Use @code{-1} for no loop, @code{0}
+for looping indefinitely (default).
+
+@item final_delay
+Force the delay (expressed in centiseconds) after the last frame. Each frame
+ends with a delay until the next frame. The default is @code{-1}, which is a
+special value to tell the muxer to re-use the previous delay. In case of a
+loop, you might want to customize this value to mark a pause for instance.
+@end table
+
+For example, to encode a gif looping 10 times, with a 5 seconds delay between
+the loops:
+@example
+ffmpeg -i INPUT -loop 10 -final_delay 500 out.gif
+@end example
+
+Note 1: if you wish to extract the frames in separate GIF files, you need to
+force the @ref{image2} muxer:
+@example
+ffmpeg -i INPUT -c:v gif -f image2 "out%d.gif"
+@end example
+
+Note 2: the GIF format has a very small time base: the delay between two frames
+can not be smaller than one centi second.
+
@anchor{hls}
@section hls
@@ -386,7 +420,9 @@
See also the @ref{framemd5} muxer.
-@section MOV/MP4/ISMV
+@section mov/mp4/ismv
+
+MOV/MP4/ISMV (Smooth Streaming) muxer.
The mov/mp4/ismv muxer supports fragmentation. Normally, a MOV/MP4
file has all the metadata about all packets stored in one location
@@ -638,7 +674,9 @@
Optionally it can generate a list of the created segments, by setting
the option @var{segment_list}. The list type is specified by the
-@var{segment_list_type} option.
+@var{segment_list_type} option. The entry filenames in the segment
+list are set by default to the basename of the corresponding segment
+files.
The segment muxer supports the following options:
@@ -670,13 +708,15 @@
Allow live-friendly file generation.
@end table
-Default value is @code{samp}.
-
@item segment_list_size @var{size}
Update the list file so that it contains at most the last @var{size}
segments. If 0 the list file will contain all the segments. Default
value is 0.
+@item segment_list_entry_prefix @var{prefix}
+Set @var{prefix} to prepend to the name of each entry filename. By
+default no prefix is applied.
+
@item segment_list_type @var{type}
Specify the format for the segment list file.
diff --git a/doc/outdevs.texi b/doc/outdevs.texi
index 55c9110..f189823 100644
--- a/doc/outdevs.texi
+++ b/doc/outdevs.texi
@@ -104,6 +104,35 @@
@end example
@end itemize
+@section fbdev
+
+Linux framebuffer output device.
+
+The Linux framebuffer is a graphic hardware-independent abstraction
+layer to show graphics on a computer monitor, typically on the
+console. It is accessed through a file device node, usually
+@file{/dev/fb0}.
+
+For more detailed information read the file
+@file{Documentation/fb/framebuffer.txt} included in the Linux source tree.
+
+@subsection Options
+@table @option
+
+@item xoffset
+@item yoffset
+Set x/y coordinate of top left corner. Default is 0.
+@end table
+
+@subsection Examples
+Play a file on framebuffer device @file{/dev/fb0}.
+Required pixel format depends on current framebuffer settings.
+@example
+ffmpeg -re -i INPUT -vcodec rawvideo -pix_fmt bgra -f fbdev /dev/fb0
+@end example
+
+See also @url{http://linux-fbdev.sourceforge.net/}, and fbset(1).
+
@section oss
OSS (Open Sound System) output device.
@@ -135,6 +164,19 @@
Specify the device to use. Default device is used when not provided.
List of output devices can be obtained with command @command{pactl list sinks}.
+@item buffer_size
+@item buffer_duration
+Control the size and duration of the PulseAudio buffer. A small buffer
+gives more control, but requires more frequent updates.
+
+@option{buffer_size} specifies size in bytes while
+@option{buffer_duration} specifies duration in milliseconds.
+
+When both options are provided then the highest value is used
+(duration is recalculated to bytes using stream parameters). If they
+are set to 0 (which is default), the device will use the default
+PulseAudio duration value. By default PulseAudio set buffer duration
+to around 2 seconds.
@end table
@subsection Examples
@@ -177,7 +219,17 @@
@item window_fullscreen
Set fullscreen mode when non-zero value is provided.
-Zero is a default.
+Default value is zero.
+@end table
+
+@subsection Interactive commands
+
+The window created by the device can be controlled through the
+following interactive commands.
+
+@table @key
+@item q, ESC
+Quit the device immediately.
@end table
@subsection Examples
diff --git a/doc/platform.texi b/doc/platform.texi
index 6d01e0e..934a3ae 100644
--- a/doc/platform.texi
+++ b/doc/platform.texi
@@ -108,14 +108,16 @@
@section Microsoft Visual C++ or Intel C++ Compiler for Windows
-FFmpeg can be built with MSVC or ICL using a C99-to-C89 conversion utility and
-wrapper. For ICL, only the wrapper is used, since ICL supports C99.
+FFmpeg can be built with MSVC 2012 or earlier using a C99-to-C89 conversion utility
+and wrapper, or with MSVC 2013 and ICL natively.
You will need the following prerequisites:
@itemize
-@item @uref{http://download.videolan.org/pub/contrib/c99-to-c89/, C99-to-C89 Converter & Wrapper}
+@item @uref{https://github.com/libav/c99-to-c89/, C99-to-C89 Converter & Wrapper}
+(if using MSVC 2012 or earlier)
@item @uref{http://code.google.com/p/msinttypes/, msinttypes}
+(if using MSVC 2012 or earlier)
@item @uref{http://www.mingw.org/, MSYS}
@item @uref{http://yasm.tortall.net/, YASM}
@item @uref{http://gnuwin32.sourceforge.net/packages/bc.htm, bc for Windows} if
@@ -125,14 +127,16 @@
To set up a proper environment in MSYS, you need to run @code{msys.bat} from
the Visual Studio or Intel Compiler command prompt.
-Place @code{makedef}, @code{c99wrap.exe}, @code{c99conv.exe}, and @code{yasm.exe}
-somewhere in your @code{PATH}.
+Place @code{yasm.exe} somewhere in your @code{PATH}. If using MSVC 2012 or
+earlier, place @code{c99wrap.exe} and @code{c99conv.exe} somewhere in your
+@code{PATH} as well.
-Next, make sure @code{inttypes.h} and any other headers and libs you want to use
-are located in a spot that the compiler can see. Do so by modifying the @code{LIB}
-and @code{INCLUDE} environment variables to include the @strong{Windows} paths to
-these directories. Alternatively, you can try and use the
-@code{--extra-cflags}/@code{--extra-ldflags} configure options.
+Next, make sure any other headers and libs you want to use, such as zlib, are
+located in a spot that the compiler can see. Do so by modifying the @code{LIB}
+and @code{INCLUDE} environment variables to include the @strong{Windows-style}
+paths to these directories. Alternatively, you can try and use the
+@code{--extra-cflags}/@code{--extra-ldflags} configure options. If using MSVC
+2012 or earlier, place @code{inttypes.h} somewhere the compiler can see too.
Finally, run:
@@ -182,7 +186,9 @@
@itemize
@item Visual Studio 2010 Pro and Express
@item Visual Studio 2012 Pro and Express
+@item Visual Studio 2013 Pro and Express
@item Intel Composer XE 2013
+@item Intel Composer XE 2013 SP1
@end itemize
Anything else is not officially supported.
diff --git a/doc/protocols.texi b/doc/protocols.texi
index 5022cbe..3f3844d 100644
--- a/doc/protocols.texi
+++ b/doc/protocols.texi
@@ -594,7 +594,70 @@
@section rtp
-Real-Time Protocol.
+Real-time Transport Protocol.
+
+The required syntax for an RTP URL is:
+rtp://@var{hostname}[:@var{port}][?@var{option}=@var{val}...]
+
+@var{port} specifies the RTP port to use.
+
+The following URL options are supported:
+
+@table @option
+
+@item ttl=@var{n}
+Set the TTL (Time-To-Live) value (for multicast only).
+
+@item rtcpport=@var{n}
+Set the remote RTCP port to @var{n}.
+
+@item localrtpport=@var{n}
+Set the local RTP port to @var{n}.
+
+@item localrtcpport=@var{n}'
+Set the local RTCP port to @var{n}.
+
+@item pkt_size=@var{n}
+Set max packet size (in bytes) to @var{n}.
+
+@item connect=0|1
+Do a @code{connect()} on the UDP socket (if set to 1) or not (if set
+to 0).
+
+@item sources=@var{ip}[,@var{ip}]
+List allowed source IP addresses.
+
+@item block=@var{ip}[,@var{ip}]
+List disallowed (blocked) source IP addresses.
+
+@item write_to_source=0|1
+Send packets to the source address of the latest received packet (if
+set to 1) or to a default remote address (if set to 0).
+
+@item localport=@var{n}
+Set the local RTP port to @var{n}.
+
+This is a deprecated option. Instead, @option{localrtpport} should be
+used.
+
+@end table
+
+Important notes:
+
+@enumerate
+
+@item
+If @option{rtcpport} is not set the RTCP port will be set to the RTP
+port value plus 1.
+
+@item
+If @option{localrtpport} (the local RTP port) is not set any available
+port will be used for the local RTP and RTCP ports.
+
+@item
+If @option{localrtcpport} (the local RTCP port) is not set it will be
+set to the the local RTP port value plus 1.
+@end enumerate
@section rtsp
diff --git a/doc/resampler.texi b/doc/resampler.texi
index 6a7e559..f9eef03 100644
--- a/doc/resampler.texi
+++ b/doc/resampler.texi
@@ -42,10 +42,11 @@
This will automatically be chosen when it is not explicitly set.
@item icl, in_channel_layout
-Set the input channel layout.
-
@item ocl, out_channel_layout
-Set the output channel layout.
+Set the input/output channel layout.
+
+See @ref{channel layout syntax,,the Channel Layout section in the ffmpeg-utils(1) manual,ffmpeg-utils}
+for the required syntax.
@item clev, center_mix_level
Set the center mix level. It is a value expressed in deciBel, and must be
diff --git a/doc/soc.txt b/doc/soc.txt
deleted file mode 100644
index 2504dba..0000000
--- a/doc/soc.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-Google Summer of Code and similar project guidelines
-
-Summer of Code is a project by Google in which students are paid to implement
-some nice new features for various participating open source projects ...
-
-This text is a collection of things to take care of for the next soc as
-it's a little late for this year's soc (2006).
-
-The Goal:
-Our goal in respect to soc is and must be of course exactly one thing and
-that is to improve FFmpeg, to reach this goal, code must
-* conform to the development policy and patch submission guidelines
-* must improve FFmpeg somehow (faster, smaller, "better",
- more codecs supported, fewer bugs, cleaner, ...)
-
-for mentors and other developers to help students to reach that goal it is
-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 surprise
- when the code will be reviewed at the end before a possible inclusion in
- FFmpeg, individual changes were generally not reviewable due to cosmetics).
-* frequent commits, so that comments can be provided early
diff --git a/doc/texi2pod.pl b/doc/texi2pod.pl
index 610f349..6cf78d8 100755
--- a/doc/texi2pod.pl
+++ b/doc/texi2pod.pl
@@ -1,4 +1,4 @@
-#! /usr/bin/perl
+#!/usr/bin/env perl
# Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
diff --git a/doc/texidep.pl b/doc/texidep.pl
new file mode 100644
index 0000000..0996903
--- /dev/null
+++ b/doc/texidep.pl
@@ -0,0 +1,32 @@
+#! /usr/bin/env perl
+
+# This script will print the dependency of a Texinfo file to stdout.
+# texidep.pl <src-path> <input.texi> <output.ext>
+
+use warnings;
+use strict;
+
+die unless @ARGV == 3;
+
+my ($src_path, $root, $target) = @ARGV;
+
+sub print_deps {
+ my ($file, $deps) = @_;
+ $deps->{$file} = 1;
+
+ open(my $fh, "<", "$file") or die "Cannot open file '$file': $!";
+ while (<$fh>) {
+ if (my ($i) = /^\@(?:verbatim)?include\s+(\S+)/) {
+ die "Circular dependency found in file $root\n" if exists $deps->{"doc/$1"};
+ print "$target: doc/$1\n";
+
+ # skip looking for config.texi dependencies, since it has
+ # none, and is not located in the source tree
+ if ("$1" ne "config.texi") {
+ print_deps("$src_path/doc/$1", {%$deps});
+ }
+ }
+ }
+}
+
+print_deps($root, {});
diff --git a/doc/utils.texi b/doc/utils.texi
index 243973d..3055662 100644
--- a/doc/utils.texi
+++ b/doc/utils.texi
@@ -96,14 +96,42 @@
@anchor{time duration syntax}
@section Time duration
-The accepted syntax is:
+There are two accepted syntaxes for expressing time duration.
+
@example
-[-][HH:]MM:SS[.m...]
-[-]S+[.m...]
+[-][@var{HH}:]@var{MM}:@var{SS}[.@var{m}...]
@end example
-@var{HH} expresses the number of hours, @var{MM} the number a of minutes
-and @var{SS} the number of seconds.
+@var{HH} expresses the number of hours, @var{MM} the number of minutes
+for a maximum of 2 digits, and @var{SS} the number of seconds for a
+maximum of 2 digits. The @var{m} at the end expresses decimal value for
+@var{SS}.
+
+@emph{or}
+
+@example
+[-]@var{S}+[.@var{m}...]
+@end example
+
+@var{S} expresses the number of seconds, with the optional decimal part
+@var{m}.
+
+In both expressions, the optional @samp{-} indicates negative duration.
+
+@subsection Examples
+
+The following examples are all valid time duration:
+
+@table @samp
+@item 55
+55 seconds
+
+@item 12:03:45
+12 hours, 03 minutes and 45 seconds
+
+@item 23.189
+23.189 seconds
+@end table
@anchor{video size syntax}
@section Video size
@@ -255,18 +283,450 @@
@anchor{color syntax}
@section Color
-It can be the name of a color (case insensitive match) or a
-[0x|#]RRGGBB[AA] sequence, possibly followed by "@@" and a string
+It can be the name of a color as defined below (case insensitive match) or a
+@code{[0x|#]RRGGBB[AA]} sequence, possibly followed by @@ and a string
representing the alpha component.
The alpha component may be a string composed by "0x" followed by an
hexadecimal number or a decimal number between 0.0 and 1.0, which
-represents the opacity value (0x00/0.0 means completely transparent,
-0xff/1.0 completely opaque).
-If the alpha component is not specified then 0xff is assumed.
+represents the opacity value (@samp{0x00} or @samp{0.0} means completely
+transparent, @samp{0xff} or @samp{1.0} completely opaque). If the alpha
+component is not specified then @samp{0xff} is assumed.
-The string "random" will result in a random color.
+The string @samp{random} will result in a random color.
+The following names of colors are recognized:
+@table @samp
+@item AliceBlue
+0xF0F8FF
+@item AntiqueWhite
+0xFAEBD7
+@item Aqua
+0x00FFFF
+@item Aquamarine
+0x7FFFD4
+@item Azure
+0xF0FFFF
+@item Beige
+0xF5F5DC
+@item Bisque
+0xFFE4C4
+@item Black
+0x000000
+@item BlanchedAlmond
+0xFFEBCD
+@item Blue
+0x0000FF
+@item BlueViolet
+0x8A2BE2
+@item Brown
+0xA52A2A
+@item BurlyWood
+0xDEB887
+@item CadetBlue
+0x5F9EA0
+@item Chartreuse
+0x7FFF00
+@item Chocolate
+0xD2691E
+@item Coral
+0xFF7F50
+@item CornflowerBlue
+0x6495ED
+@item Cornsilk
+0xFFF8DC
+@item Crimson
+0xDC143C
+@item Cyan
+0x00FFFF
+@item DarkBlue
+0x00008B
+@item DarkCyan
+0x008B8B
+@item DarkGoldenRod
+0xB8860B
+@item DarkGray
+0xA9A9A9
+@item DarkGreen
+0x006400
+@item DarkKhaki
+0xBDB76B
+@item DarkMagenta
+0x8B008B
+@item DarkOliveGreen
+0x556B2F
+@item Darkorange
+0xFF8C00
+@item DarkOrchid
+0x9932CC
+@item DarkRed
+0x8B0000
+@item DarkSalmon
+0xE9967A
+@item DarkSeaGreen
+0x8FBC8F
+@item DarkSlateBlue
+0x483D8B
+@item DarkSlateGray
+0x2F4F4F
+@item DarkTurquoise
+0x00CED1
+@item DarkViolet
+0x9400D3
+@item DeepPink
+0xFF1493
+@item DeepSkyBlue
+0x00BFFF
+@item DimGray
+0x696969
+@item DodgerBlue
+0x1E90FF
+@item FireBrick
+0xB22222
+@item FloralWhite
+0xFFFAF0
+@item ForestGreen
+0x228B22
+@item Fuchsia
+0xFF00FF
+@item Gainsboro
+0xDCDCDC
+@item GhostWhite
+0xF8F8FF
+@item Gold
+0xFFD700
+@item GoldenRod
+0xDAA520
+@item Gray
+0x808080
+@item Green
+0x008000
+@item GreenYellow
+0xADFF2F
+@item HoneyDew
+0xF0FFF0
+@item HotPink
+0xFF69B4
+@item IndianRed
+0xCD5C5C
+@item Indigo
+0x4B0082
+@item Ivory
+0xFFFFF0
+@item Khaki
+0xF0E68C
+@item Lavender
+0xE6E6FA
+@item LavenderBlush
+0xFFF0F5
+@item LawnGreen
+0x7CFC00
+@item LemonChiffon
+0xFFFACD
+@item LightBlue
+0xADD8E6
+@item LightCoral
+0xF08080
+@item LightCyan
+0xE0FFFF
+@item LightGoldenRodYellow
+0xFAFAD2
+@item LightGreen
+0x90EE90
+@item LightGrey
+0xD3D3D3
+@item LightPink
+0xFFB6C1
+@item LightSalmon
+0xFFA07A
+@item LightSeaGreen
+0x20B2AA
+@item LightSkyBlue
+0x87CEFA
+@item LightSlateGray
+0x778899
+@item LightSteelBlue
+0xB0C4DE
+@item LightYellow
+0xFFFFE0
+@item Lime
+0x00FF00
+@item LimeGreen
+0x32CD32
+@item Linen
+0xFAF0E6
+@item Magenta
+0xFF00FF
+@item Maroon
+0x800000
+@item MediumAquaMarine
+0x66CDAA
+@item MediumBlue
+0x0000CD
+@item MediumOrchid
+0xBA55D3
+@item MediumPurple
+0x9370D8
+@item MediumSeaGreen
+0x3CB371
+@item MediumSlateBlue
+0x7B68EE
+@item MediumSpringGreen
+0x00FA9A
+@item MediumTurquoise
+0x48D1CC
+@item MediumVioletRed
+0xC71585
+@item MidnightBlue
+0x191970
+@item MintCream
+0xF5FFFA
+@item MistyRose
+0xFFE4E1
+@item Moccasin
+0xFFE4B5
+@item NavajoWhite
+0xFFDEAD
+@item Navy
+0x000080
+@item OldLace
+0xFDF5E6
+@item Olive
+0x808000
+@item OliveDrab
+0x6B8E23
+@item Orange
+0xFFA500
+@item OrangeRed
+0xFF4500
+@item Orchid
+0xDA70D6
+@item PaleGoldenRod
+0xEEE8AA
+@item PaleGreen
+0x98FB98
+@item PaleTurquoise
+0xAFEEEE
+@item PaleVioletRed
+0xD87093
+@item PapayaWhip
+0xFFEFD5
+@item PeachPuff
+0xFFDAB9
+@item Peru
+0xCD853F
+@item Pink
+0xFFC0CB
+@item Plum
+0xDDA0DD
+@item PowderBlue
+0xB0E0E6
+@item Purple
+0x800080
+@item Red
+0xFF0000
+@item RosyBrown
+0xBC8F8F
+@item RoyalBlue
+0x4169E1
+@item SaddleBrown
+0x8B4513
+@item Salmon
+0xFA8072
+@item SandyBrown
+0xF4A460
+@item SeaGreen
+0x2E8B57
+@item SeaShell
+0xFFF5EE
+@item Sienna
+0xA0522D
+@item Silver
+0xC0C0C0
+@item SkyBlue
+0x87CEEB
+@item SlateBlue
+0x6A5ACD
+@item SlateGray
+0x708090
+@item Snow
+0xFFFAFA
+@item SpringGreen
+0x00FF7F
+@item SteelBlue
+0x4682B4
+@item Tan
+0xD2B48C
+@item Teal
+0x008080
+@item Thistle
+0xD8BFD8
+@item Tomato
+0xFF6347
+@item Turquoise
+0x40E0D0
+@item Violet
+0xEE82EE
+@item Wheat
+0xF5DEB3
+@item White
+0xFFFFFF
+@item WhiteSmoke
+0xF5F5F5
+@item Yellow
+0xFFFF00
+@item YellowGreen
+0x9ACD32
+@end table
+
+@anchor{channel layout syntax}
+@section Channel Layout
+
+A channel layout specifies the spatial disposition of the channels in
+a multi-channel audio stream. To specify a channel layout, FFmpeg
+makes use of a special syntax.
+
+Individual channels are identified by an id, as given by the table
+below:
+@table @samp
+@item FL
+front left
+@item FR
+front right
+@item FC
+front center
+@item LFE
+low frequency
+@item BL
+back left
+@item BR
+back right
+@item FLC
+front left-of-center
+@item FRC
+front right-of-center
+@item BC
+back center
+@item SL
+side left
+@item SR
+side right
+@item TC
+top center
+@item TFL
+top front left
+@item TFC
+top front center
+@item TFR
+top front right
+@item TBL
+top back left
+@item TBC
+top back center
+@item TBR
+top back right
+@item DL
+downmix left
+@item DR
+downmix right
+@item WL
+wide left
+@item WR
+wide right
+@item SDL
+surround direct left
+@item SDR
+surround direct right
+@item LFE2
+low frequency 2
+@end table
+
+Standard channel layout compositions can be specified by using the
+following identifiers:
+@table @samp
+@item mono
+FC
+@item stereo
+FL+FR
+@item 2.1
+FL+FR+LFE
+@item 3.0
+FL+FR+FC
+@item 3.0(back)
+FL+FR+BC
+@item 4.0
+FL+FR+FC+BC
+@item quad
+FL+FR+BL+BR
+@item quad(side)
+FL+FR+SL+SR
+@item 3.1
+FL+FR+FC+LFE
+@item 5.0
+FL+FR+FC+BL+BR
+@item 5.0(side)
+FL+FR+FC+SL+SR
+@item 4.1
+FL+FR+FC+LFE+BC
+@item 5.1
+FL+FR+FC+LFE+BL+BR
+@item 5.1(side)
+FL+FR+FC+LFE+SL+SR
+@item 6.0
+FL+FR+FC+BC+SL+SR
+@item 6.0(front)
+FL+FR+FLC+FRC+SL+SR
+@item hexagonal
+FL+FR+FC+BL+BR+BC
+@item 6.1
+FL+FR+FC+LFE+BC+SL+SR
+@item 6.1
+FL+FR+FC+LFE+BL+BR+BC
+@item 6.1(front)
+FL+FR+LFE+FLC+FRC+SL+SR
+@item 7.0
+FL+FR+FC+BL+BR+SL+SR
+@item 7.0(front)
+FL+FR+FC+FLC+FRC+SL+SR
+@item 7.1
+FL+FR+FC+LFE+BL+BR+SL+SR
+@item 7.1(wide)
+FL+FR+FC+LFE+BL+BR+FLC+FRC
+@item 7.1(wide-side)
+FL+FR+FC+LFE+FLC+FRC+SL+SR
+@item octagonal
+FL+FR+FC+BL+BR+BC+SL+SR
+@item downmix
+DL+DR
+@end table
+
+A custom channel layout can be specified as a sequence of terms, separated by
+'+' or '|'. Each term can be:
+@itemize
+@item
+the name of a standard channel layout (e.g. @samp{mono},
+@samp{stereo}, @samp{4.0}, @samp{quad}, @samp{5.0}, etc.)
+
+@item
+the name of a single channel (e.g. @samp{FL}, @samp{FR}, @samp{FC}, @samp{LFE}, etc.)
+
+@item
+a number of channels, in decimal, optionally followed by 'c', yielding
+the default channel layout for that number of channels (see the
+function @code{av_get_default_channel_layout})
+
+@item
+a channel layout mask, in hexadecimal starting with "0x" (see the
+@code{AV_CH_*} macros in @file{libavutil/channel_layout.h}.
+@end itemize
+
+Starting from libavutil version 53 the trailing character "c" to
+specify a number of channels will be required, while a channel layout
+mask could also be specified as a decimal number (if and only if not
+followed by "c").
+
+See also the function @code{av_get_channel_layout} defined in
+@file{libavutil/channel_layout.h}.
@c man end SYNTAX
@chapter Expression Evaluation
@@ -591,13 +1051,13 @@
Select the index of the platform to run OpenCL code.
The specified index must be one of the indexes in the device list
-which can be obtained with @code{av_opencl_get_device_list()}.
+which can be obtained with @code{ffmpeg -opencl_bench} or @code{av_opencl_get_device_list()}.
@item device_idx
Select the index of the device used to run OpenCL code.
The specifed index must be one of the indexes in the device list which
-can be obtained with @code{av_opencl_get_device_list()}.
+can be obtained with @code{ffmpeg -opencl_bench} or @code{av_opencl_get_device_list()}.
@end table
diff --git a/doc/viterbi.txt b/doc/viterbi.txt
deleted file mode 100644
index 9782546..0000000
--- a/doc/viterbi.txt
+++ /dev/null
@@ -1,109 +0,0 @@
-This is a quick description of the viterbi aka dynamic programing
-algorthm.
-
-Its reason for existence is that wikipedia has become very poor on
-describing algorithms in a way that makes it useable for understanding
-them or anything else actually. It tends now to describe the very same
-algorithm under 50 different names and pages with few understandable
-by even people who fully understand the algorithm and the theory behind.
-
-Problem description: (that is what it can solve)
-assume we have a 2d table, or you could call it a graph or matrix if you
-prefer
-
- O O O O O O O
-
- O O O O O O O
-
- O O O O O O O
-
- O O O O O O O
-
-
-That table has edges connecting points from each column to the next column
-and each edge has a score like: (only some edge and scores shown to keep it
-readable)
-
-
- O--5--O-----O-----O-----O-----O
- 2 / 7 / \ / \ / \ /
- \ / \ / \ / \ / \ /
- O7-/--O--/--O--/--O--/--O--/--O
- \/ \/ 1/ \/ \/ \/ \/ \/ \/ \/
- /\ /\ 2\ /\ /\ /\ /\ /\ /\ /\
- O3-/--O--/--O--/--O--/--O--/--O
- / \ / \ / \ / \ / \
- 1 \ 9 \ / \ / \ / \
- O--2--O--1--O--5--O--3--O--8--O
-
-
-
-Our goal is to find a path from left to right through it which
-minimizes the sum of the score of all edges.
-(and of course left/right is just a convention here it could be top down too)
-Similarly the minimum could be the maximum by just fliping the sign,
-Example of a path with scores:
-
- O O O O O O O
-
->---O. O O .O-2-O O O
- 5. .7 .
- O O-1-O O O 8 O O
- .
- O O O O O O-1-O---> (sum here is 24)
-
-
-The viterbi algorthm now solves this simply column by column
-For the previous column each point has a best path and a associated
-score:
-
- O-----5 O
- \
- \
- O \ 1 O
- \/
- /\
- O / 2 O
- /
- /
- O-----2 O
-
-
-To move one column forward we just need to find the best path and associated
-scores for the next column
-here are some edges we could choose from:
-
-
- O-----5--3--O
- \ \8
- \ \
- O \ 1--9--O
- \/ \3
- /\ \
- O / 2--1--O
- / \2
- / \
- O-----2--4--O
-
-Finding the new best paths and scores for each point of our new column is
-trivial given we know the previous column best paths and scores:
-
- O-----0-----8
- \
- \
- O \ 0----10
- \/
- /\
- O / 0-----3
- / \
- / \
- O 0 4
-
-
-the viterbi algorthm continues exactly like this column for column until the
-end and then just picks the path with the best score (above that would be the
-one with score 3)
-
-
-Author: Michael niedermayer
-Copyright LGPL
diff --git a/ffmpeg.c b/ffmpeg.c
index 86b7162..6411ce3 100644
--- a/ffmpeg.c
+++ b/ffmpeg.c
@@ -30,6 +30,8 @@
#include <stdlib.h>
#include <errno.h>
#include <limits.h>
+#include <stdint.h>
+
#if HAVE_ISATTY
#if HAVE_IO_H
#include <io.h>
@@ -38,9 +40,9 @@
#include <unistd.h>
#endif
#endif
+
#include "libavformat/avformat.h"
#include "libavdevice/avdevice.h"
-#include "libswscale/swscale.h"
#include "libswresample/swresample.h"
#include "libavutil/opt.h"
#include "libavutil/channel_layout.h"
@@ -468,6 +470,8 @@
output_streams[i]->bitstream_filters = NULL;
avcodec_free_frame(&output_streams[i]->filtered_frame);
+ av_parser_close(output_streams[i]->parser);
+
av_freep(&output_streams[i]->forced_keyframes);
av_expr_free(output_streams[i]->forced_keyframes_pexpr);
av_freep(&output_streams[i]->avfilter);
@@ -488,6 +492,7 @@
avsubtitle_free(&input_streams[i]->prev_sub.subtitle);
av_frame_free(&input_streams[i]->sub2video.frame);
av_freep(&input_streams[i]->filters);
+ av_freep(&input_streams[i]->hwaccel_device);
av_freep(&input_streams[i]);
}
@@ -817,10 +822,29 @@
nb_frames = 1;
format_video_sync = video_sync_method;
- if (format_video_sync == VSYNC_AUTO)
- format_video_sync = (s->oformat->flags & AVFMT_VARIABLE_FPS) ? ((s->oformat->flags & AVFMT_NOTIMESTAMPS) ? VSYNC_PASSTHROUGH : VSYNC_VFR) : VSYNC_CFR;
+ if (format_video_sync == VSYNC_AUTO) {
+ if(!strcmp(s->oformat->name, "avi")) {
+ format_video_sync = VSYNC_VFR;
+ } else
+ format_video_sync = (s->oformat->flags & AVFMT_VARIABLE_FPS) ? ((s->oformat->flags & AVFMT_NOTIMESTAMPS) ? VSYNC_PASSTHROUGH : VSYNC_VFR) : VSYNC_CFR;
+ if ( ist
+ && format_video_sync == VSYNC_CFR
+ && input_files[ist->file_index]->ctx->nb_streams == 1
+ && input_files[ist->file_index]->input_ts_offset == 0) {
+ format_video_sync = VSYNC_VSCFR;
+ }
+ if (format_video_sync == VSYNC_CFR && copy_ts) {
+ format_video_sync = VSYNC_VSCFR;
+ }
+ }
switch (format_video_sync) {
+ case VSYNC_VSCFR:
+ if (ost->frame_number == 0 && delta - duration >= 0.5) {
+ av_log(NULL, AV_LOG_DEBUG, "Not duplicating %d initial frames\n", (int)lrintf(delta - duration));
+ delta = duration;
+ ost->sync_opts = lrint(sync_ipts);
+ }
case VSYNC_CFR:
// FIXME set to 0.5 after we fix some dts/pts bugs like in avidec.c
if (delta < -1.1)
@@ -1054,7 +1078,7 @@
if (!ost->filter)
continue;
- if (!ost->filtered_frame && !(ost->filtered_frame = avcodec_alloc_frame())) {
+ if (!ost->filtered_frame && !(ost->filtered_frame = av_frame_alloc())) {
return AVERROR(ENOMEM);
} else
avcodec_get_frame_defaults(ost->filtered_frame);
@@ -1467,7 +1491,10 @@
&& ost->st->codec->codec_id != AV_CODEC_ID_MPEG2VIDEO
&& ost->st->codec->codec_id != AV_CODEC_ID_VC1
) {
- if (av_parser_change(ist->st->parser, ost->st->codec, &opkt.data, &opkt.size, pkt->data, pkt->size, pkt->flags & AV_PKT_FLAG_KEY)) {
+ if (av_parser_change(ost->parser, ost->st->codec,
+ &opkt.data, &opkt.size,
+ pkt->data, pkt->size,
+ pkt->flags & AV_PKT_FLAG_KEY)) {
opkt.buf = av_buffer_create(opkt.data, opkt.size, av_buffer_default_free, NULL, 0);
if (!opkt.buf)
exit_program(1);
@@ -1476,6 +1503,7 @@
opkt.data = pkt->data;
opkt.size = pkt->size;
}
+ av_copy_packet_side_data(&opkt, pkt);
if (ost->st->codec->codec_type == AVMEDIA_TYPE_VIDEO && (of->ctx->oformat->flags & AVFMT_RAWPICTURE)) {
/* store AVPicture in AVPacket, as expected by the output format */
@@ -1516,7 +1544,7 @@
int i, ret, err = 0, resample_changed;
AVRational decoded_frame_tb;
- if (!ist->decoded_frame && !(ist->decoded_frame = avcodec_alloc_frame()))
+ if (!ist->decoded_frame && !(ist->decoded_frame = av_frame_alloc()))
return AVERROR(ENOMEM);
if (!ist->filter_frame && !(ist->filter_frame = av_frame_alloc()))
return AVERROR(ENOMEM);
@@ -1652,7 +1680,6 @@
static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output)
{
AVFrame *decoded_frame, *f;
- void *buffer_to_free = NULL;
int i, ret = 0, err = 0, resample_changed;
int64_t best_effort_timestamp;
AVRational *frame_sample_aspect;
@@ -1687,6 +1714,13 @@
if(ist->top_field_first>=0)
decoded_frame->top_field_first = ist->top_field_first;
+ if (ist->hwaccel_retrieve_data && decoded_frame->format == ist->hwaccel_pix_fmt) {
+ err = ist->hwaccel_retrieve_data(ist->st->codec, decoded_frame);
+ if (err < 0)
+ goto fail;
+ }
+ ist->hwaccel_retrieved_pix_fmt = decoded_frame->format;
+
best_effort_timestamp= av_frame_get_best_effort_timestamp(decoded_frame);
if(best_effort_timestamp != AV_NOPTS_VALUE)
ist->next_pts = ist->pts = av_rescale_q(decoded_frame->pts = best_effort_timestamp, ist->st->time_base, AV_TIME_BASE_Q);
@@ -1751,9 +1785,9 @@
}
}
+fail:
av_frame_unref(ist->filter_frame);
av_frame_unref(decoded_frame);
- av_free(buffer_to_free);
return err < 0 ? err : ret;
}
@@ -1773,25 +1807,32 @@
}
if (ist->fix_sub_duration) {
+ int end = 1;
if (ist->prev_sub.got_output) {
- int end = av_rescale(subtitle.pts - ist->prev_sub.subtitle.pts,
- 1000, AV_TIME_BASE);
+ end = av_rescale(subtitle.pts - ist->prev_sub.subtitle.pts,
+ 1000, AV_TIME_BASE);
if (end < ist->prev_sub.subtitle.end_display_time) {
av_log(ist->st->codec, AV_LOG_DEBUG,
- "Subtitle duration reduced from %d to %d\n",
- ist->prev_sub.subtitle.end_display_time, end);
+ "Subtitle duration reduced from %d to %d%s\n",
+ ist->prev_sub.subtitle.end_display_time, end,
+ end <= 0 ? ", dropping it" : "");
ist->prev_sub.subtitle.end_display_time = end;
}
}
FFSWAP(int, *got_output, ist->prev_sub.got_output);
FFSWAP(int, ret, ist->prev_sub.ret);
FFSWAP(AVSubtitle, subtitle, ist->prev_sub.subtitle);
+ if (end <= 0)
+ goto out;
}
+ if (!*got_output)
+ return ret;
+
sub2video_update(ist, &subtitle);
- if (!*got_output || !subtitle.num_rects)
- return ret;
+ if (!subtitle.num_rects)
+ goto out;
for (i = 0; i < nb_output_streams; i++) {
OutputStream *ost = output_streams[i];
@@ -1802,6 +1843,7 @@
do_subtitle_out(output_files[ost->file_index]->ctx, ost, ist, &subtitle);
}
+out:
avsubtitle_free(&subtitle);
return ret;
}
@@ -1963,6 +2005,63 @@
av_freep(&avc);
}
+static const HWAccel *get_hwaccel(enum AVPixelFormat pix_fmt)
+{
+ int i;
+ for (i = 0; hwaccels[i].name; i++)
+ if (hwaccels[i].pix_fmt == pix_fmt)
+ return &hwaccels[i];
+ return NULL;
+}
+
+static enum AVPixelFormat get_format(AVCodecContext *s, const enum AVPixelFormat *pix_fmts)
+{
+ InputStream *ist = s->opaque;
+ const enum AVPixelFormat *p;
+ int ret;
+
+ for (p = pix_fmts; *p != -1; p++) {
+ const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(*p);
+ const HWAccel *hwaccel;
+
+ if (!(desc->flags & AV_PIX_FMT_FLAG_HWACCEL))
+ break;
+
+ hwaccel = get_hwaccel(*p);
+ if (!hwaccel ||
+ (ist->active_hwaccel_id && ist->active_hwaccel_id != hwaccel->id) ||
+ (ist->hwaccel_id != HWACCEL_AUTO && ist->hwaccel_id != hwaccel->id))
+ continue;
+
+ ret = hwaccel->init(s);
+ if (ret < 0) {
+ if (ist->hwaccel_id == hwaccel->id) {
+ av_log(NULL, AV_LOG_FATAL,
+ "%s hwaccel requested for input stream #%d:%d, "
+ "but cannot be initialized.\n", hwaccel->name,
+ ist->file_index, ist->st->index);
+ exit_program(1);
+ }
+ continue;
+ }
+ ist->active_hwaccel_id = hwaccel->id;
+ ist->hwaccel_pix_fmt = *p;
+ break;
+ }
+
+ return *p;
+}
+
+static int get_buffer(AVCodecContext *s, AVFrame *frame, int flags)
+{
+ InputStream *ist = s->opaque;
+
+ if (ist->hwaccel_get_buffer && frame->format == ist->hwaccel_pix_fmt)
+ return ist->hwaccel_get_buffer(s, frame, flags);
+
+ return avcodec_default_get_buffer2(s, frame, flags);
+}
+
static int init_input_stream(int ist_index, char *error, int error_len)
{
int ret;
@@ -1976,6 +2075,11 @@
return AVERROR(EINVAL);
}
+ ist->st->codec->opaque = ist;
+ ist->st->codec->get_format = get_format;
+ ist->st->codec->get_buffer2 = get_buffer;
+ ist->st->codec->thread_safe_callbacks = 1;
+
av_opt_set_int(ist->st->codec, "refcounted_frames", 1, 0);
if (!av_dict_get(ist->opts, "threads", NULL, 0))
@@ -2108,7 +2212,7 @@
FilterGraph *fg = filtergraphs[i];
for (j = 0; j < fg->nb_outputs; j++) {
OutputFilter *ofilter = fg->outputs[j];
- if (ofilter->ost->source_index >= 0)
+ if (!ofilter->ost || ofilter->ost->source_index >= 0)
continue;
if (fg->nb_inputs != 1)
continue;
@@ -2160,6 +2264,15 @@
ost->st->disposition = ist->st->disposition;
codec->bits_per_raw_sample = icodec->bits_per_raw_sample;
codec->chroma_sample_location = icodec->chroma_sample_location;
+ } else {
+ for (j=0; j<oc->nb_streams; j++) {
+ AVStream *st = oc->streams[j];
+ if (st != ost->st && st->codec->codec_type == codec->codec_type)
+ break;
+ }
+ if (j == oc->nb_streams)
+ if (codec->codec_type == AVMEDIA_TYPE_AUDIO || codec->codec_type == AVMEDIA_TYPE_VIDEO)
+ ost->st->disposition = AV_DISPOSITION_DEFAULT;
}
if (ost->stream_copy) {
@@ -2249,6 +2362,8 @@
av_reduce(&codec->time_base.num, &codec->time_base.den,
codec->time_base.num, codec->time_base.den, INT_MAX);
+ ost->parser = av_parser_init(codec->codec_id);
+
switch (codec->codec_type) {
case AVMEDIA_TYPE_AUDIO:
if (audio_volume != 256) {
@@ -2348,7 +2463,7 @@
if (ost->filter && !(codec->time_base.num && codec->time_base.den))
codec->time_base = ost->filter->filter->inputs[0]->time_base;
if ( av_q2d(codec->time_base) < 0.001 && video_sync_method != VSYNC_PASSTHROUGH
- && (video_sync_method == VSYNC_CFR || (video_sync_method == VSYNC_AUTO && !(oc->oformat->flags & AVFMT_VARIABLE_FPS)))){
+ && (video_sync_method == VSYNC_CFR || video_sync_method == VSYNC_VSCFR || (video_sync_method == VSYNC_AUTO && !(oc->oformat->flags & AVFMT_VARIABLE_FPS)))){
av_log(oc, AV_LOG_WARNING, "Frame rate very high for a muxer not efficiently supporting it.\n"
"Please consider specifying a lower framerate, a different muxer or -vsync 2\n");
}
@@ -2438,7 +2553,7 @@
codec->stats_in = logbuffer;
}
if (codec->flags & CODEC_FLAG_PASS1) {
- f = fopen(logfilename, "wb");
+ f = av_fopen_utf8(logfilename, "wb");
if (!f) {
av_log(NULL, AV_LOG_FATAL, "Cannot write log file '%s' for pass-1 encoding: %s\n",
logfilename, strerror(errno));
@@ -2488,9 +2603,6 @@
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;
} else {
av_opt_set_dict(ost->st->codec, &ost->opts);
}
@@ -3299,6 +3411,8 @@
ist = input_streams[i];
if (ist->decoding_needed) {
avcodec_close(ist->st->codec);
+ if (ist->hwaccel_uninit)
+ ist->hwaccel_uninit(ist->st->codec);
}
}
diff --git a/ffmpeg.h b/ffmpeg.h
index 054e718..433baf8 100644
--- a/ffmpeg.h
+++ b/ffmpeg.h
@@ -51,10 +51,24 @@
#define VSYNC_PASSTHROUGH 0
#define VSYNC_CFR 1
#define VSYNC_VFR 2
+#define VSYNC_VSCFR 0xfe
#define VSYNC_DROP 0xff
#define MAX_STREAMS 1024 /* arbitrary sanity check value */
+enum HWAccelID {
+ HWACCEL_NONE = 0,
+ HWACCEL_AUTO,
+ HWACCEL_VDPAU,
+};
+
+typedef struct HWAccel {
+ const char *name;
+ int (*init)(AVCodecContext *s);
+ enum HWAccelID id;
+ enum AVPixelFormat pix_fmt;
+} HWAccel;
+
/* select an input stream for an output stream */
typedef struct StreamMap {
int disabled; /* 1 is this mapping is disabled by a negative map */
@@ -99,6 +113,10 @@
int nb_ts_scale;
SpecifierOpt *dump_attachment;
int nb_dump_attachment;
+ SpecifierOpt *hwaccels;
+ int nb_hwaccels;
+ SpecifierOpt *hwaccel_devices;
+ int nb_hwaccel_devices;
/* output options */
StreamMap *stream_maps;
@@ -274,6 +292,19 @@
int nb_filters;
int reinit_filters;
+
+ /* hwaccel options */
+ enum HWAccelID hwaccel_id;
+ char *hwaccel_device;
+
+ /* hwaccel context */
+ enum HWAccelID active_hwaccel_id;
+ void *hwaccel_ctx;
+ void (*hwaccel_uninit)(AVCodecContext *s);
+ int (*hwaccel_get_buffer)(AVCodecContext *s, AVFrame *frame, int flags);
+ int (*hwaccel_retrieve_data)(AVCodecContext *s, AVFrame *frame);
+ enum AVPixelFormat hwaccel_pix_fmt;
+ enum AVPixelFormat hwaccel_retrieved_pix_fmt;
} InputStream;
typedef struct InputFile {
@@ -281,6 +312,7 @@
int eof_reached; /* true if eof reached */
int eagain; /* true if last read attempt returned EAGAIN */
int ist_index; /* index of first stream in input_streams */
+ int64_t input_ts_offset;
int64_t ts_offset;
int64_t last_ts;
int64_t start_time; /* user-specified start time in AV_TIME_BASE or AV_NOPTS_VALUE */
@@ -357,6 +389,8 @@
OutputFilter *filter;
char *avfilter;
+ char *filters; ///< filtergraph associated to the -filter option
+ char *filters_script; ///< filtergraph script associated to the -filter_script option
int64_t sws_flags;
AVDictionary *opts;
@@ -371,6 +405,8 @@
int copy_prior_start;
int keep_pix_fmt;
+
+ AVCodecParserContext *parser;
} OutputStream;
typedef struct OutputFile {
@@ -425,6 +461,8 @@
extern const AVIOInterruptCB int_cb;
extern const OptionDef options[];
+extern const HWAccel hwaccels[];
+
void term_init(void);
void term_exit(void);
@@ -448,4 +486,6 @@
int ffmpeg_parse_options(int argc, char **argv);
+int vdpau_init(AVCodecContext *s);
+
#endif /* FFMPEG_H */
diff --git a/ffmpeg_filter.c b/ffmpeg_filter.c
index 80089ff..9d945fc 100644
--- a/ffmpeg_filter.c
+++ b/ffmpeg_filter.c
@@ -18,6 +18,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <stdint.h>
+
#include "ffmpeg.h"
#include "libavfilter/avfilter.h"
@@ -92,6 +94,11 @@
static char *choose_pix_fmts(OutputStream *ost)
{
+ AVDictionaryEntry *strict_dict = av_dict_get(ost->opts, "strict", NULL, 0);
+ if (strict_dict)
+ // used by choose_pixel_fmt() and below
+ av_opt_set(ost->st->codec, "strict", strict_dict->value, 0);
+
if (ost->keep_pix_fmt) {
if (ost->filter)
avfilter_graph_set_auto_convert(ost->filter->graph->graph,
@@ -649,7 +656,8 @@
av_bprintf(&args,
"video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:"
"pixel_aspect=%d/%d:sws_param=flags=%d", ist->resample_width,
- ist->resample_height, ist->resample_pix_fmt,
+ ist->resample_height,
+ ist->hwaccel_retrieve_data ? ist->hwaccel_retrieved_pix_fmt : ist->resample_pix_fmt,
tb.num, tb.den, sar.num, sar.den,
SWS_BILINEAR + ((ist->st->codec->flags&CODEC_FLAG_BITEXACT) ? SWS_BITEXACT:0));
if (fr.num && fr.den)
@@ -860,6 +868,10 @@
if (strlen(args))
args[strlen(args) - 1] = '\0';
fg->graph->resample_lavr_opts = av_strdup(args);
+
+ e = av_dict_get(ost->opts, "threads", NULL, 0);
+ if (e)
+ av_opt_set(fg->graph, "threads", e->value, 0);
}
if ((ret = avfilter_graph_parse2(fg->graph, graph_desc, &inputs, &outputs)) < 0)
diff --git a/ffmpeg_opt.c b/ffmpeg_opt.c
index 738d612..e6ac3ee 100644
--- a/ffmpeg_opt.c
+++ b/ffmpeg_opt.c
@@ -62,6 +62,14 @@
outvar = o->name[i].u.type;\
}\
}
+
+const HWAccel hwaccels[] = {
+#if HAVE_VDPAU_X11
+ { "vdpau", vdpau_init, HWACCEL_VDPAU, AV_PIX_FMT_VDPAU },
+#endif
+ { 0 },
+};
+
char *vstats_filename;
float audio_drift_threshold = 0.1;
@@ -557,7 +565,7 @@
AVStream *st = ic->streams[i];
AVCodecContext *dec = st->codec;
InputStream *ist = av_mallocz(sizeof(*ist));
- char *framerate = NULL;
+ char *framerate = NULL, *hwaccel = NULL, *hwaccel_device = NULL;
if (!ist)
exit_program(1);
@@ -612,6 +620,41 @@
ist->top_field_first = -1;
MATCH_PER_STREAM_OPT(top_field_first, i, ist->top_field_first, ic, st);
+ MATCH_PER_STREAM_OPT(hwaccels, str, hwaccel, ic, st);
+ if (hwaccel) {
+ if (!strcmp(hwaccel, "none"))
+ ist->hwaccel_id = HWACCEL_NONE;
+ else if (!strcmp(hwaccel, "auto"))
+ ist->hwaccel_id = HWACCEL_AUTO;
+ else {
+ int i;
+ for (i = 0; hwaccels[i].name; i++) {
+ if (!strcmp(hwaccels[i].name, hwaccel)) {
+ ist->hwaccel_id = hwaccels[i].id;
+ break;
+ }
+ }
+
+ if (!ist->hwaccel_id) {
+ av_log(NULL, AV_LOG_FATAL, "Unrecognized hwaccel: %s.\n",
+ hwaccel);
+ av_log(NULL, AV_LOG_FATAL, "Supported hwaccels: ");
+ for (i = 0; hwaccels[i].name; i++)
+ av_log(NULL, AV_LOG_FATAL, "%s ", hwaccels[i].name);
+ av_log(NULL, AV_LOG_FATAL, "\n");
+ exit_program(1);
+ }
+ }
+ }
+
+ MATCH_PER_STREAM_OPT(hwaccel_devices, str, hwaccel_device, ic, st);
+ if (hwaccel_device) {
+ ist->hwaccel_device = av_strdup(hwaccel_device);
+ if (!ist->hwaccel_device)
+ exit_program(1);
+ }
+ ist->hwaccel_pix_fmt = AV_PIX_FMT_NONE;
+
break;
case AVMEDIA_TYPE_AUDIO:
ist->guess_layout_max = INT_MAX;
@@ -852,6 +895,7 @@
f->ist_index = nb_input_streams - ic->nb_streams;
f->start_time = o->start_time;
f->recording_time = o->recording_time;
+ f->input_ts_offset = o->input_ts_offset;
f->ts_offset = o->input_ts_offset - (copy_ts ? 0 : timestamp);
f->nb_streams = ic->nb_streams;
f->rate_emu = o->rate_emu;
@@ -1151,26 +1195,36 @@
OutputStream *ost)
{
AVStream *st = ost->st;
- char *filter = NULL, *filter_script = NULL;
- MATCH_PER_STREAM_OPT(filter_scripts, str, filter_script, oc, st);
- MATCH_PER_STREAM_OPT(filters, str, filter, oc, st);
-
- if (filter_script && filter) {
+ if (ost->filters_script && ost->filters) {
av_log(NULL, AV_LOG_ERROR, "Both -filter and -filter_script set for "
"output stream #%d:%d.\n", nb_output_files, st->index);
exit_program(1);
}
- if (filter_script)
- return read_file(filter_script);
- else if (filter)
- return av_strdup(filter);
+ if (ost->filters_script)
+ return read_file(ost->filters_script);
+ else if (ost->filters)
+ return av_strdup(ost->filters);
return av_strdup(st->codec->codec_type == AVMEDIA_TYPE_VIDEO ?
"null" : "anull");
}
+static void check_streamcopy_filters(OptionsContext *o, AVFormatContext *oc,
+ const OutputStream *ost, enum AVMediaType type)
+{
+ if (ost->filters_script || ost->filters) {
+ av_log(NULL, AV_LOG_ERROR,
+ "%s '%s' was defined for %s output stream %d:%d but codec copy was selected.\n"
+ "Filtering and streamcopy cannot be used together.\n",
+ ost->filters ? "Filtergraph" : "Filtergraph script",
+ ost->filters ? ost->filters : ost->filters_script,
+ av_get_media_type_string(type), ost->file_index, ost->index);
+ exit_program(1);
+ }
+}
+
static OutputStream *new_video_stream(OptionsContext *o, AVFormatContext *oc, int source_index)
{
AVStream *st;
@@ -1199,6 +1253,9 @@
ost->frame_aspect_ratio = q;
}
+ MATCH_PER_STREAM_OPT(filter_scripts, str, ost->filters_script, oc, st);
+ MATCH_PER_STREAM_OPT(filters, str, ost->filters, oc, st);
+
if (!ost->stream_copy) {
const char *p = NULL;
char *frame_size = NULL;
@@ -1311,6 +1368,9 @@
MATCH_PER_STREAM_OPT(copy_initial_nonkeyframes, i, ost->copy_initial_nonkeyframes, oc ,st);
}
+ if (ost->stream_copy)
+ check_streamcopy_filters(o, oc, ost, AVMEDIA_TYPE_VIDEO);
+
return ost;
}
@@ -1327,6 +1387,9 @@
audio_enc = st->codec;
audio_enc->codec_type = AVMEDIA_TYPE_AUDIO;
+ MATCH_PER_STREAM_OPT(filter_scripts, str, ost->filters_script, oc, st);
+ MATCH_PER_STREAM_OPT(filters, str, ost->filters, oc, st);
+
if (!ost->stream_copy) {
char *sample_fmt = NULL;
@@ -1364,6 +1427,9 @@
}
}
+ if (ost->stream_copy)
+ check_streamcopy_filters(o, oc, ost, AVMEDIA_TYPE_AUDIO);
+
return ost;
}
@@ -1548,6 +1614,18 @@
exit_program(1);
}
+ if (ost->avfilter && (ost->filters || ost->filters_script)) {
+ const char *opt = ost->filters ? "-vf/-af/-filter" : "-filter_script";
+ av_log(NULL, AV_LOG_ERROR,
+ "%s '%s' was specified through the %s option "
+ "for output stream %d:%d, which is fed from a complex filtergraph.\n"
+ "%s and -filter_complex cannot be used together for the same stream.\n",
+ ost->filters ? "Filtergraph" : "Filtergraph script",
+ ost->filters ? ost->filters : ost->filters_script,
+ opt, ost->file_index, ost->index, opt);
+ exit_program(1);
+ }
+
if (configure_output_filter(ofilter->graph, ofilter, ofilter->out_tmp) < 0) {
av_log(NULL, AV_LOG_FATAL, "Error configuring filter.\n");
exit_program(1);
@@ -2055,23 +2133,23 @@
opt_video_codec(o, "c:v", "mpeg1video");
opt_audio_codec(o, "c:a", "mp2");
parse_option(o, "f", "vcd", options);
- av_dict_set(&o->g->codec_opts, "b:v", arg, 0);
+ av_dict_set(&o->g->codec_opts, "b:v", arg, AV_DICT_DONT_OVERWRITE);
parse_option(o, "s", norm == PAL ? "352x288" : "352x240", options);
parse_option(o, "r", frame_rates[norm], options);
- av_dict_set(&o->g->codec_opts, "g", norm == PAL ? "15" : "18", 0);
+ av_dict_set(&o->g->codec_opts, "g", norm == PAL ? "15" : "18", AV_DICT_DONT_OVERWRITE);
- av_dict_set(&o->g->codec_opts, "b:v", "1150000", 0);
- av_dict_set(&o->g->codec_opts, "maxrate", "1150000", 0);
- av_dict_set(&o->g->codec_opts, "minrate", "1150000", 0);
- av_dict_set(&o->g->codec_opts, "bufsize", "327680", 0); // 40*1024*8;
+ av_dict_set(&o->g->codec_opts, "b:v", "1150000", AV_DICT_DONT_OVERWRITE);
+ av_dict_set(&o->g->codec_opts, "maxrate", "1150000", AV_DICT_DONT_OVERWRITE);
+ av_dict_set(&o->g->codec_opts, "minrate", "1150000", AV_DICT_DONT_OVERWRITE);
+ av_dict_set(&o->g->codec_opts, "bufsize", "327680", AV_DICT_DONT_OVERWRITE); // 40*1024*8;
- av_dict_set(&o->g->codec_opts, "b:a", "224000", 0);
+ av_dict_set(&o->g->codec_opts, "b:a", "224000", AV_DICT_DONT_OVERWRITE);
parse_option(o, "ar", "44100", options);
parse_option(o, "ac", "2", options);
- av_dict_set(&o->g->format_opts, "packetsize", "2324", 0);
- av_dict_set(&o->g->format_opts, "muxrate", "1411200", 0); // 2352 * 75 * 8;
+ av_dict_set(&o->g->format_opts, "packetsize", "2324", AV_DICT_DONT_OVERWRITE);
+ av_dict_set(&o->g->format_opts, "muxrate", "1411200", AV_DICT_DONT_OVERWRITE); // 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
@@ -2088,18 +2166,18 @@
parse_option(o, "s", norm == PAL ? "480x576" : "480x480", options);
parse_option(o, "r", frame_rates[norm], options);
parse_option(o, "pix_fmt", "yuv420p", options);
- av_dict_set(&o->g->codec_opts, "g", norm == PAL ? "15" : "18", 0);
+ av_dict_set(&o->g->codec_opts, "g", norm == PAL ? "15" : "18", AV_DICT_DONT_OVERWRITE);
- av_dict_set(&o->g->codec_opts, "b:v", "2040000", 0);
- av_dict_set(&o->g->codec_opts, "maxrate", "2516000", 0);
- av_dict_set(&o->g->codec_opts, "minrate", "0", 0); // 1145000;
- av_dict_set(&o->g->codec_opts, "bufsize", "1835008", 0); // 224*1024*8;
- av_dict_set(&o->g->codec_opts, "scan_offset", "1", 0);
+ av_dict_set(&o->g->codec_opts, "b:v", "2040000", AV_DICT_DONT_OVERWRITE);
+ av_dict_set(&o->g->codec_opts, "maxrate", "2516000", AV_DICT_DONT_OVERWRITE);
+ av_dict_set(&o->g->codec_opts, "minrate", "0", AV_DICT_DONT_OVERWRITE); // 1145000;
+ av_dict_set(&o->g->codec_opts, "bufsize", "1835008", AV_DICT_DONT_OVERWRITE); // 224*1024*8;
+ av_dict_set(&o->g->codec_opts, "scan_offset", "1", AV_DICT_DONT_OVERWRITE);
- av_dict_set(&o->g->codec_opts, "b:a", "224000", 0);
+ av_dict_set(&o->g->codec_opts, "b:a", "224000", AV_DICT_DONT_OVERWRITE);
parse_option(o, "ar", "44100", options);
- av_dict_set(&o->g->format_opts, "packetsize", "2324", 0);
+ av_dict_set(&o->g->format_opts, "packetsize", "2324", AV_DICT_DONT_OVERWRITE);
} else if (!strcmp(arg, "dvd")) {
@@ -2110,17 +2188,17 @@
parse_option(o, "s", norm == PAL ? "720x576" : "720x480", options);
parse_option(o, "r", frame_rates[norm], options);
parse_option(o, "pix_fmt", "yuv420p", options);
- av_dict_set(&o->g->codec_opts, "g", norm == PAL ? "15" : "18", 0);
+ av_dict_set(&o->g->codec_opts, "g", norm == PAL ? "15" : "18", AV_DICT_DONT_OVERWRITE);
- av_dict_set(&o->g->codec_opts, "b:v", "6000000", 0);
- av_dict_set(&o->g->codec_opts, "maxrate", "9000000", 0);
- av_dict_set(&o->g->codec_opts, "minrate", "0", 0); // 1500000;
- av_dict_set(&o->g->codec_opts, "bufsize", "1835008", 0); // 224*1024*8;
+ av_dict_set(&o->g->codec_opts, "b:v", "6000000", AV_DICT_DONT_OVERWRITE);
+ av_dict_set(&o->g->codec_opts, "maxrate", "9000000", AV_DICT_DONT_OVERWRITE);
+ av_dict_set(&o->g->codec_opts, "minrate", "0", AV_DICT_DONT_OVERWRITE); // 1500000;
+ av_dict_set(&o->g->codec_opts, "bufsize", "1835008", AV_DICT_DONT_OVERWRITE); // 224*1024*8;
- av_dict_set(&o->g->format_opts, "packetsize", "2048", 0); // from www.mpucoder.com: DVD sectors contain 2048 bytes of data, this is also the size of one pack.
- av_dict_set(&o->g->format_opts, "muxrate", "10080000", 0); // from mplex project: data_rate = 1260000. mux_rate = data_rate * 8
+ av_dict_set(&o->g->format_opts, "packetsize", "2048", AV_DICT_DONT_OVERWRITE); // from www.mpucoder.com: DVD sectors contain 2048 bytes of data, this is also the size of one pack.
+ av_dict_set(&o->g->format_opts, "muxrate", "10080000", AV_DICT_DONT_OVERWRITE); // from mplex project: data_rate = 1260000. mux_rate = data_rate * 8
- av_dict_set(&o->g->codec_opts, "b:a", "448000", 0);
+ av_dict_set(&o->g->codec_opts, "b:a", "448000", AV_DICT_DONT_OVERWRITE);
parse_option(o, "ar", "48000", options);
} else if (!strncmp(arg, "dv", 2)) {
@@ -2457,7 +2535,9 @@
int flags = AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_ENCODING_PARAM;
show_help_children(avcodec_get_class(), flags);
show_help_children(avformat_get_class(), flags);
+#if CONFIG_SWSCALE
show_help_children(sws_get_class(), flags);
+#endif
show_help_children(swr_get_class(), AV_OPT_FLAG_AUDIO_PARAM);
show_help_children(avfilter_get_class(), AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_FILTERING_PARAM);
}
@@ -2798,6 +2878,12 @@
"force key frames at specified timestamps", "timestamps" },
{ "b", OPT_VIDEO | HAS_ARG | OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_bitrate },
"video bitrate (please use -b:v)", "bitrate" },
+ { "hwaccel", OPT_VIDEO | OPT_STRING | HAS_ARG | OPT_EXPERT |
+ OPT_SPEC | OPT_INPUT, { .off = OFFSET(hwaccels) },
+ "use HW accelerated decoding", "hwaccel name" },
+ { "hwaccel_device", OPT_VIDEO | OPT_STRING | HAS_ARG | OPT_EXPERT |
+ OPT_SPEC | OPT_INPUT, { .off = OFFSET(hwaccel_devices) },
+ "select a device for HW acceleration" "devicename" },
/* audio options */
{ "aframes", OPT_AUDIO | HAS_ARG | OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_audio_frames },
diff --git a/ffmpeg_vdpau.c b/ffmpeg_vdpau.c
new file mode 100644
index 0000000..fe09306
--- /dev/null
+++ b/ffmpeg_vdpau.c
@@ -0,0 +1,335 @@
+/*
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdint.h>
+
+#include <vdpau/vdpau.h>
+#include <vdpau/vdpau_x11.h>
+
+#include <X11/Xlib.h>
+
+#include "ffmpeg.h"
+
+#include "libavcodec/vdpau.h"
+
+#include "libavutil/avassert.h"
+#include "libavutil/buffer.h"
+#include "libavutil/frame.h"
+#include "libavutil/pixfmt.h"
+
+typedef struct VDPAUContext {
+ Display *dpy;
+
+ VdpDevice device;
+ VdpDecoder decoder;
+ VdpGetProcAddress *get_proc_address;
+
+ VdpGetErrorString *get_error_string;
+ VdpGetInformationString *get_information_string;
+ VdpDeviceDestroy *device_destroy;
+ VdpDecoderCreate *decoder_create;
+ VdpDecoderDestroy *decoder_destroy;
+ VdpDecoderRender *decoder_render;
+ VdpVideoSurfaceCreate *video_surface_create;
+ VdpVideoSurfaceDestroy *video_surface_destroy;
+ VdpVideoSurfaceGetBitsYCbCr *video_surface_get_bits;
+ VdpVideoSurfaceGetParameters *video_surface_get_parameters;
+ VdpVideoSurfaceQueryGetPutBitsYCbCrCapabilities *video_surface_query;
+
+ AVFrame *tmp_frame;
+
+ enum AVPixelFormat pix_fmt;
+ VdpYCbCrFormat vdpau_format;
+} VDPAUContext;
+
+static void vdpau_uninit(AVCodecContext *s)
+{
+ InputStream *ist = s->opaque;
+ VDPAUContext *ctx = ist->hwaccel_ctx;
+
+ ist->hwaccel_uninit = NULL;
+ ist->hwaccel_get_buffer = NULL;
+ ist->hwaccel_retrieve_data = NULL;
+
+ if (ctx->decoder_destroy)
+ ctx->decoder_destroy(ctx->decoder);
+
+ if (ctx->device_destroy)
+ ctx->device_destroy(ctx->device);
+
+ if (ctx->dpy)
+ XCloseDisplay(ctx->dpy);
+
+ av_frame_free(&ctx->tmp_frame);
+
+ av_freep(&ist->hwaccel_ctx);
+ av_freep(&s->hwaccel_context);
+}
+
+static void vdpau_release_buffer(void *opaque, uint8_t *data)
+{
+ VdpVideoSurface surface = *(VdpVideoSurface*)data;
+ VDPAUContext *ctx = opaque;
+
+ ctx->video_surface_destroy(surface);
+ av_freep(&data);
+}
+
+static int vdpau_get_buffer(AVCodecContext *s, AVFrame *frame, int flags)
+{
+ InputStream *ist = s->opaque;
+ VDPAUContext *ctx = ist->hwaccel_ctx;
+ VdpVideoSurface *surface;
+ VdpStatus err;
+
+ av_assert0(frame->format == AV_PIX_FMT_VDPAU);
+
+ surface = av_malloc(sizeof(*surface));
+ if (!surface)
+ return AVERROR(ENOMEM);
+
+ frame->buf[0] = av_buffer_create((uint8_t*)surface, sizeof(*surface),
+ vdpau_release_buffer, ctx,
+ AV_BUFFER_FLAG_READONLY);
+ if (!frame->buf[0]) {
+ av_freep(&surface);
+ return AVERROR(ENOMEM);
+ }
+
+ // properly we should keep a pool of surfaces instead of creating
+ // them anew for each frame, but since we don't care about speed
+ // much in this code, we don't bother
+ err = ctx->video_surface_create(ctx->device, VDP_CHROMA_TYPE_420,
+ frame->width, frame->height, surface);
+ if (err != VDP_STATUS_OK) {
+ av_log(NULL, AV_LOG_ERROR, "Error allocating a VDPAU video surface: %s\n",
+ ctx->get_error_string(err));
+ av_buffer_unref(&frame->buf[0]);
+ return AVERROR_UNKNOWN;
+ }
+
+ frame->data[3] = (uint8_t*)(uintptr_t)*surface;
+
+ return 0;
+}
+
+static int vdpau_retrieve_data(AVCodecContext *s, AVFrame *frame)
+{
+ VdpVideoSurface surface = (VdpVideoSurface)(uintptr_t)frame->data[3];
+ InputStream *ist = s->opaque;
+ VDPAUContext *ctx = ist->hwaccel_ctx;
+ VdpStatus err;
+ int ret, chroma_type;
+
+ err = ctx->video_surface_get_parameters(surface, &chroma_type,
+ &ctx->tmp_frame->width,
+ &ctx->tmp_frame->height);
+ if (err != VDP_STATUS_OK) {
+ av_log(NULL, AV_LOG_ERROR, "Error getting surface parameters: %s\n",
+ ctx->get_error_string(err));
+ return AVERROR_UNKNOWN;
+ }
+ ctx->tmp_frame->format = ctx->pix_fmt;
+
+ ret = av_frame_get_buffer(ctx->tmp_frame, 32);
+ if (ret < 0)
+ return ret;
+
+ ctx->tmp_frame->width = frame->width;
+ ctx->tmp_frame->height = frame->height;
+
+ err = ctx->video_surface_get_bits(surface, ctx->vdpau_format,
+ (void * const *)ctx->tmp_frame->data,
+ ctx->tmp_frame->linesize);
+ if (err != VDP_STATUS_OK) {
+ av_log(NULL, AV_LOG_ERROR, "Error retrieving frame data from VDPAU: %s\n",
+ ctx->get_error_string(err));
+ ret = AVERROR_UNKNOWN;
+ goto fail;
+ }
+
+ if (ctx->vdpau_format == VDP_YCBCR_FORMAT_YV12)
+ FFSWAP(uint8_t*, ctx->tmp_frame->data[1], ctx->tmp_frame->data[2]);
+
+ ret = av_frame_copy_props(ctx->tmp_frame, frame);
+ if (ret < 0)
+ goto fail;
+
+ av_frame_unref(frame);
+ av_frame_move_ref(frame, ctx->tmp_frame);
+ return 0;
+
+fail:
+ av_frame_unref(ctx->tmp_frame);
+ return ret;
+}
+
+static const int vdpau_formats[][2] = {
+ { VDP_YCBCR_FORMAT_YV12, AV_PIX_FMT_YUV420P },
+ { VDP_YCBCR_FORMAT_NV12, AV_PIX_FMT_NV12 },
+ { VDP_YCBCR_FORMAT_YUYV, AV_PIX_FMT_YUYV422 },
+ { VDP_YCBCR_FORMAT_UYVY, AV_PIX_FMT_UYVY422 },
+};
+
+static int vdpau_alloc(AVCodecContext *s)
+{
+ InputStream *ist = s->opaque;
+ int loglevel = (ist->hwaccel_id == HWACCEL_AUTO) ? AV_LOG_VERBOSE : AV_LOG_ERROR;
+ AVVDPAUContext *vdpau_ctx;
+ VDPAUContext *ctx;
+ const char *display, *vendor;
+ VdpStatus err;
+ int i;
+
+ ctx = av_mallocz(sizeof(*ctx));
+ if (!ctx)
+ return AVERROR(ENOMEM);
+
+ ist->hwaccel_ctx = ctx;
+ ist->hwaccel_uninit = vdpau_uninit;
+ ist->hwaccel_get_buffer = vdpau_get_buffer;
+ ist->hwaccel_retrieve_data = vdpau_retrieve_data;
+
+ ctx->tmp_frame = av_frame_alloc();
+ if (!ctx->tmp_frame)
+ goto fail;
+
+ ctx->dpy = XOpenDisplay(ist->hwaccel_device);
+ if (!ctx->dpy) {
+ av_log(NULL, loglevel, "Cannot open the X11 display %s.\n",
+ XDisplayName(ist->hwaccel_device));
+ goto fail;
+ }
+ display = XDisplayString(ctx->dpy);
+
+ err = vdp_device_create_x11(ctx->dpy, XDefaultScreen(ctx->dpy), &ctx->device,
+ &ctx->get_proc_address);
+ if (err != VDP_STATUS_OK) {
+ av_log(NULL, loglevel, "VDPAU device creation on X11 display %s failed.\n",
+ display);
+ goto fail;
+ }
+
+#define GET_CALLBACK(id, result) \
+do { \
+ void *tmp; \
+ err = ctx->get_proc_address(ctx->device, id, &tmp); \
+ if (err != VDP_STATUS_OK) { \
+ av_log(NULL, loglevel, "Error getting the " #id " callback.\n"); \
+ goto fail; \
+ } \
+ ctx->result = tmp; \
+} while (0)
+
+ GET_CALLBACK(VDP_FUNC_ID_GET_ERROR_STRING, get_error_string);
+ GET_CALLBACK(VDP_FUNC_ID_GET_INFORMATION_STRING, get_information_string);
+ GET_CALLBACK(VDP_FUNC_ID_DEVICE_DESTROY, device_destroy);
+ GET_CALLBACK(VDP_FUNC_ID_DECODER_CREATE, decoder_create);
+ GET_CALLBACK(VDP_FUNC_ID_DECODER_DESTROY, decoder_destroy);
+ GET_CALLBACK(VDP_FUNC_ID_DECODER_RENDER, decoder_render);
+ GET_CALLBACK(VDP_FUNC_ID_VIDEO_SURFACE_CREATE, video_surface_create);
+ GET_CALLBACK(VDP_FUNC_ID_VIDEO_SURFACE_DESTROY, video_surface_destroy);
+ GET_CALLBACK(VDP_FUNC_ID_VIDEO_SURFACE_GET_BITS_Y_CB_CR, video_surface_get_bits);
+ GET_CALLBACK(VDP_FUNC_ID_VIDEO_SURFACE_GET_PARAMETERS, video_surface_get_parameters);
+ GET_CALLBACK(VDP_FUNC_ID_VIDEO_SURFACE_QUERY_GET_PUT_BITS_Y_CB_CR_CAPABILITIES,
+ video_surface_query);
+
+ for (i = 0; i < FF_ARRAY_ELEMS(vdpau_formats); i++) {
+ VdpBool supported;
+ err = ctx->video_surface_query(ctx->device, VDP_CHROMA_TYPE_420,
+ vdpau_formats[i][0], &supported);
+ if (err != VDP_STATUS_OK) {
+ av_log(NULL, loglevel,
+ "Error querying VDPAU surface capabilities: %s\n",
+ ctx->get_error_string(err));
+ goto fail;
+ }
+ if (supported)
+ break;
+ }
+ if (i == FF_ARRAY_ELEMS(vdpau_formats)) {
+ av_log(NULL, loglevel,
+ "No supported VDPAU format for retrieving the data.\n");
+ return AVERROR(EINVAL);
+ }
+ ctx->vdpau_format = vdpau_formats[i][0];
+ ctx->pix_fmt = vdpau_formats[i][1];
+
+ vdpau_ctx = av_vdpau_alloc_context();
+ if (!vdpau_ctx)
+ goto fail;
+ vdpau_ctx->render = ctx->decoder_render;
+
+ s->hwaccel_context = vdpau_ctx;
+
+ ctx->get_information_string(&vendor);
+ av_log(NULL, AV_LOG_VERBOSE, "Using VDPAU -- %s -- on X11 display %s, "
+ "to decode input stream #%d:%d.\n", vendor,
+ display, ist->file_index, ist->st->index);
+
+ return 0;
+
+fail:
+ av_log(NULL, loglevel, "VDPAU init failed for stream #%d:%d.\n",
+ ist->file_index, ist->st->index);
+ vdpau_uninit(s);
+ return AVERROR(EINVAL);
+}
+
+int vdpau_init(AVCodecContext *s)
+{
+ InputStream *ist = s->opaque;
+ int loglevel = (ist->hwaccel_id == HWACCEL_AUTO) ? AV_LOG_VERBOSE : AV_LOG_ERROR;
+ AVVDPAUContext *vdpau_ctx;
+ VDPAUContext *ctx;
+ VdpStatus err;
+ int profile, ret;
+
+ if (!ist->hwaccel_ctx) {
+ ret = vdpau_alloc(s);
+ if (ret < 0)
+ return ret;
+ }
+ ctx = ist->hwaccel_ctx;
+ vdpau_ctx = s->hwaccel_context;
+
+ ret = av_vdpau_get_profile(s, &profile);
+ if (ret < 0) {
+ av_log(NULL, loglevel, "No known VDPAU decoder profile for this stream.\n");
+ return AVERROR(EINVAL);
+ }
+
+ if (ctx->decoder)
+ ctx->decoder_destroy(ctx->decoder);
+
+ err = ctx->decoder_create(ctx->device, profile,
+ s->coded_width, s->coded_height,
+ 16, &ctx->decoder);
+ if (err != VDP_STATUS_OK) {
+ av_log(NULL, loglevel, "Error creating the VDPAU decoder: %s\n",
+ ctx->get_error_string(err));
+ return AVERROR_UNKNOWN;
+ }
+
+ vdpau_ctx->decoder = ctx->decoder;
+
+ ist->hwaccel_get_buffer = vdpau_get_buffer;
+ ist->hwaccel_retrieve_data = vdpau_retrieve_data;
+
+ return 0;
+}
diff --git a/ffplay.c b/ffplay.c
index 8c0c415..4893ebc 100644
--- a/ffplay.c
+++ b/ffplay.c
@@ -28,6 +28,8 @@
#include <math.h>
#include <limits.h>
#include <signal.h>
+#include <stdint.h>
+
#include "libavutil/avstring.h"
#include "libavutil/colorspace.h"
#include "libavutil/mathematics.h"
@@ -121,6 +123,7 @@
typedef struct VideoPicture {
double pts; // presentation timestamp for this picture
+ double duration; // estimated duration based on frame rate
int64_t pos; // byte position in file
SDL_Overlay *bmp;
int width, height; /* source height & width */
@@ -242,13 +245,8 @@
SDL_cond *subpq_cond;
double frame_timer;
- double frame_last_pts;
- double frame_last_duration;
- double frame_last_dropped_pts;
double frame_last_returned_time;
double frame_last_filter_delay;
- int64_t frame_last_dropped_pos;
- int frame_last_dropped_serial;
int video_stream;
AVStream *video_st;
PacketQueue videoq;
@@ -785,6 +783,14 @@
}
}
+static void free_picture(VideoPicture *vp)
+{
+ if (vp->bmp) {
+ SDL_FreeYUVOverlay(vp->bmp);
+ vp->bmp = NULL;
+ }
+}
+
static void free_subpicture(SubPicture *sp)
{
avsubtitle_free(&sp->sub);
@@ -1013,7 +1019,6 @@
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;
@@ -1023,13 +1028,8 @@
packet_queue_destroy(&is->subtitleq);
/* free all pictures */
- for (i = 0; i < VIDEO_PICTURE_QUEUE_SIZE; i++) {
- vp = &is->pictq[i];
- if (vp->bmp) {
- SDL_FreeYUVOverlay(vp->bmp);
- vp->bmp = NULL;
- }
- }
+ for (i = 0; i < VIDEO_PICTURE_QUEUE_SIZE; i++)
+ free_picture(&is->pictq[i]);
for (i = 0; i < SUBPICTURE_QUEUE_SIZE; i++)
free_subpicture(&is->subpq[i]);
SDL_DestroyMutex(is->pictq_mutex);
@@ -1066,20 +1066,24 @@
exit(123);
}
+static void set_default_window_size(VideoPicture *vp)
+{
+ SDL_Rect rect;
+ calculate_display_rect(&rect, 0, 0, INT_MAX, vp->height, vp);
+ default_width = rect.w;
+ default_height = rect.h;
+}
+
static int video_open(VideoState *is, int force_set_video_mode, VideoPicture *vp)
{
int flags = SDL_HWSURFACE | SDL_ASYNCBLIT | SDL_HWACCEL;
int w,h;
- SDL_Rect rect;
if (is_full_screen) flags |= SDL_FULLSCREEN;
else flags |= SDL_RESIZABLE;
- if (vp && vp->width) {
- calculate_display_rect(&rect, 0, 0, INT_MAX, vp->height, vp);
- default_width = rect.w;
- default_height = rect.h;
- }
+ if (vp && vp->width)
+ set_default_window_size(vp);
if (is_full_screen && fs_screen_width) {
w = fs_screen_width;
@@ -1290,6 +1294,18 @@
return delay;
}
+static double vp_duration(VideoState *is, VideoPicture *vp, VideoPicture *nextvp) {
+ if (vp->serial == nextvp->serial) {
+ double duration = nextvp->pts - vp->pts;
+ if (isnan(duration) || duration <= 0 || duration > is->max_frame_duration)
+ return vp->duration;
+ else
+ return duration;
+ } else {
+ return 0.0;
+ }
+}
+
static void pictq_next_picture(VideoState *is) {
/* update queue size and signal for next picture */
if (++is->pictq_rindex == VIDEO_PICTURE_QUEUE_SIZE)
@@ -1325,14 +1341,12 @@
set_clock(&is->vidclk, pts, serial);
sync_clock_to_slave(&is->extclk, &is->vidclk);
is->video_current_pos = pos;
- is->frame_last_pts = pts;
}
/* called to display each frame */
static void video_refresh(void *opaque, double *remaining_time)
{
VideoState *is = opaque;
- VideoPicture *vp;
double time;
SubPicture *sp, *sp2;
@@ -1355,37 +1369,34 @@
redisplay = pictq_prev_picture(is);
retry:
if (is->pictq_size == 0) {
- SDL_LockMutex(is->pictq_mutex);
- if (is->frame_last_dropped_pts != AV_NOPTS_VALUE && is->frame_last_dropped_pts > is->frame_last_pts) {
- update_video_pts(is, is->frame_last_dropped_pts, is->frame_last_dropped_pos, is->frame_last_dropped_serial);
- is->frame_last_dropped_pts = AV_NOPTS_VALUE;
- }
- SDL_UnlockMutex(is->pictq_mutex);
// nothing to do, no picture to display in the queue
} else {
double last_duration, duration, delay;
+ VideoPicture *vp, *lastvp;
+
/* dequeue the picture */
vp = &is->pictq[is->pictq_rindex];
+ lastvp = &is->pictq[(is->pictq_rindex + VIDEO_PICTURE_QUEUE_SIZE - 1) % VIDEO_PICTURE_QUEUE_SIZE];
if (vp->serial != is->videoq.serial) {
pictq_next_picture(is);
+ is->video_current_pos = -1;
redisplay = 0;
goto retry;
}
+ if (lastvp->serial != vp->serial && !redisplay)
+ is->frame_timer = av_gettime() / 1000000.0;
+
if (is->paused)
goto display;
/* compute nominal last_duration */
- last_duration = vp->pts - is->frame_last_pts;
- if (!isnan(last_duration) && last_duration > 0 && last_duration < is->max_frame_duration) {
- /* if duration of the last frame was sane, update last_duration in video state */
- is->frame_last_duration = last_duration;
- }
+ last_duration = vp_duration(is, lastvp, vp);
if (redisplay)
delay = 0.0;
else
- delay = compute_target_delay(is->frame_last_duration, is);
+ delay = compute_target_delay(last_duration, is);
time= av_gettime()/1000000.0;
if (time < is->frame_timer + delay && !redisplay) {
@@ -1404,7 +1415,7 @@
if (is->pictq_size > 1) {
VideoPicture *nextvp = &is->pictq[(is->pictq_rindex + 1) % VIDEO_PICTURE_QUEUE_SIZE];
- duration = nextvp->pts - vp->pts;
+ duration = vp_duration(is, vp, nextvp);
if(!is->step && (redisplay || framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) && time > is->frame_timer + duration){
if (!redisplay)
is->frame_drops_late++;
@@ -1505,8 +1516,7 @@
vp = &is->pictq[is->pictq_windex];
- if (vp->bmp)
- SDL_FreeYUVOverlay(vp->bmp);
+ free_picture(vp);
video_open(is, 0, vp);
@@ -1548,7 +1558,7 @@
}
}
-static int queue_picture(VideoState *is, AVFrame *src_frame, double pts, int64_t pos, int serial)
+static int queue_picture(VideoState *is, AVFrame *src_frame, double pts, double duration, int64_t pos, int serial)
{
VideoPicture *vp;
@@ -1645,6 +1655,7 @@
SDL_UnlockYUVOverlay(vp->bmp);
vp->pts = pts;
+ vp->duration = duration;
vp->pos = pos;
vp->serial = serial;
@@ -1667,18 +1678,6 @@
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 queue but that's harder)
- while (is->pictq_size && !is->videoq.abort_request) {
- SDL_CondWait(is->pictq_cond, is->pictq_mutex);
- }
- is->video_current_pos = -1;
- is->frame_last_pts = AV_NOPTS_VALUE;
- is->frame_last_duration = 0;
- is->frame_timer = (double)av_gettime() / 1000000.0;
- is->frame_last_dropped_pts = AV_NOPTS_VALUE;
- SDL_UnlockMutex(is->pictq_mutex);
return 0;
}
@@ -1706,23 +1705,17 @@
frame->sample_aspect_ratio = av_guess_sample_aspect_ratio(is->ic, is->video_st, frame);
if (framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) {
- SDL_LockMutex(is->pictq_mutex);
- if (is->frame_last_pts != AV_NOPTS_VALUE && frame->pts != AV_NOPTS_VALUE) {
- double clockdiff = get_clock(&is->vidclk) - get_master_clock(is);
- double ptsdiff = dpts - is->frame_last_pts;
- if (!isnan(clockdiff) && fabs(clockdiff) < AV_NOSYNC_THRESHOLD &&
- !isnan(ptsdiff) && ptsdiff > 0 && ptsdiff < AV_NOSYNC_THRESHOLD &&
- clockdiff + ptsdiff - is->frame_last_filter_delay < 0 &&
+ if (frame->pts != AV_NOPTS_VALUE) {
+ double diff = dpts - get_master_clock(is);
+ if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD &&
+ diff - is->frame_last_filter_delay < 0 &&
+ *serial == is->vidclk.serial &&
is->videoq.nb_packets) {
- is->frame_last_dropped_pos = pkt->pos;
- is->frame_last_dropped_pts = dpts;
- is->frame_last_dropped_serial = *serial;
is->frame_drops_early++;
av_frame_unref(frame);
ret = 0;
}
}
- SDL_UnlockMutex(is->pictq_mutex);
}
return ret;
@@ -1832,6 +1825,8 @@
int64_t channel_layouts[2] = { 0, -1 };
int channels[2] = { 0, -1 };
AVFilterContext *filt_asrc = NULL, *filt_asink = NULL;
+ char aresample_swr_opts[512] = "";
+ AVDictionaryEntry *e = NULL;
char asrc_args[256];
int ret;
@@ -1839,6 +1834,12 @@
if (!(is->agraph = avfilter_graph_alloc()))
return AVERROR(ENOMEM);
+ while ((e = av_dict_get(swr_opts, "", e, AV_DICT_IGNORE_SUFFIX)))
+ av_strlcatf(aresample_swr_opts, sizeof(aresample_swr_opts), "%s=%s:", e->key, e->value);
+ if (strlen(aresample_swr_opts))
+ aresample_swr_opts[strlen(aresample_swr_opts)-1] = '\0';
+ av_opt_set(is->agraph, "aresample_swr_opts", aresample_swr_opts, 0);
+
ret = snprintf(asrc_args, sizeof(asrc_args),
"sample_rate=%d:sample_fmt=%s:channels=%d:time_base=%d/%d",
is->audio_filter_src.freq, av_get_sample_fmt_name(is->audio_filter_src.fmt),
@@ -1900,8 +1901,11 @@
VideoState *is = arg;
AVFrame *frame = av_frame_alloc();
double pts;
+ double duration;
int ret;
int serial = 0;
+ AVRational tb = is->video_st->time_base;
+ AVRational frame_rate = av_guess_frame_rate(is->ic, is->video_st, NULL);
#if CONFIG_AVFILTER
AVFilterGraph *graph = avfilter_graph_alloc();
@@ -1952,6 +1956,7 @@
last_h = frame->height;
last_format = frame->format;
last_serial = serial;
+ frame_rate = filt_out->inputs[0]->frame_rate;
}
ret = av_buffersrc_add_frame(filt_in, frame);
@@ -1975,22 +1980,20 @@
is->frame_last_filter_delay = av_gettime() / 1000000.0 - is->frame_last_returned_time;
if (fabs(is->frame_last_filter_delay) > AV_NOSYNC_THRESHOLD / 10.0)
is->frame_last_filter_delay = 0;
-
- pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(filt_out->inputs[0]->time_base);
- ret = queue_picture(is, frame, pts, av_frame_get_pkt_pos(frame), serial);
+ tb = filt_out->inputs[0]->time_base;
+#endif
+ duration = (frame_rate.num && frame_rate.den ? av_q2d((AVRational){frame_rate.den, frame_rate.num}) : 0);
+ pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
+ ret = queue_picture(is, frame, pts, duration, av_frame_get_pkt_pos(frame), serial);
av_frame_unref(frame);
+#if CONFIG_AVFILTER
}
-#else
- pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(is->video_st->time_base);
- ret = queue_picture(is, frame, pts, pkt.pos, serial);
- av_frame_unref(frame);
#endif
if (ret < 0)
goto the_end;
}
the_end:
- avcodec_flush_buffers(is->video_st->codec);
#if CONFIG_AVFILTER
avfilter_graph_free(&graph);
#endif
@@ -2160,7 +2163,7 @@
/* NOTE: the audio packet can contain several frames */
while (pkt_temp->stream_index != -1 || is->audio_buf_frames_pending) {
if (!is->frame) {
- if (!(is->frame = avcodec_alloc_frame()))
+ if (!(is->frame = av_frame_alloc()))
return AVERROR(ENOMEM);
} else {
av_frame_unref(is->frame);
@@ -2815,6 +2818,13 @@
}
is->show_mode = show_mode;
+ if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
+ AVStream *st = ic->streams[st_index[AVMEDIA_TYPE_VIDEO]];
+ AVCodecContext *avctx = st->codec;
+ VideoPicture vp = {.width = avctx->width, .height = avctx->height, .sar = av_guess_sample_aspect_ratio(ic, st, NULL)};
+ if (vp.width)
+ set_default_window_size(&vp);
+ }
/* open the streams */
if (st_index[AVMEDIA_TYPE_AUDIO] >= 0) {
@@ -3500,9 +3510,9 @@
"q, ESC quit\n"
"f toggle full screen\n"
"p, SPC pause\n"
- "a cycle audio channel\n"
+ "a cycle audio channel in the current program\n"
"v cycle video channel\n"
- "t cycle subtitle channel\n"
+ "t cycle subtitle channel in the current program\n"
"c cycle program\n"
"w show audio waves\n"
"s activate frame-step mode\n"
@@ -3543,7 +3553,6 @@
parse_loglevel(argc, argv, options);
/* register all codecs, demux and protocols */
- avcodec_register_all();
#if CONFIG_AVDEVICE
avdevice_register_all();
#endif
diff --git a/ffprobe.c b/ffprobe.c
index b7f287c..46c232e 100644
--- a/ffprobe.c
+++ b/ffprobe.c
@@ -24,7 +24,7 @@
*/
#include "config.h"
-#include "version.h"
+#include "libavutil/ffversion.h"
#include <string.h>
@@ -135,6 +135,7 @@
SECTION_ID_STREAM_DISPOSITION,
SECTION_ID_STREAMS,
SECTION_ID_STREAM_TAGS,
+ SECTION_ID_SUBTITLE,
} SectionID;
static struct section sections[] = {
@@ -144,7 +145,7 @@
[SECTION_ID_ERROR] = { SECTION_ID_ERROR, "error", 0, { -1 } },
[SECTION_ID_FORMAT] = { SECTION_ID_FORMAT, "format", 0, { SECTION_ID_FORMAT_TAGS, -1 } },
[SECTION_ID_FORMAT_TAGS] = { SECTION_ID_FORMAT_TAGS, "tags", SECTION_FLAG_HAS_VARIABLE_FIELDS, { -1 }, .element_name = "tag", .unique_name = "format_tags" },
- [SECTION_ID_FRAMES] = { SECTION_ID_FRAMES, "frames", SECTION_FLAG_IS_ARRAY, { SECTION_ID_FRAME, -1 } },
+ [SECTION_ID_FRAMES] = { SECTION_ID_FRAMES, "frames", SECTION_FLAG_IS_ARRAY, { SECTION_ID_FRAME, SECTION_ID_SUBTITLE, -1 } },
[SECTION_ID_FRAME] = { SECTION_ID_FRAME, "frame", 0, { SECTION_ID_FRAME_TAGS, -1 } },
[SECTION_ID_FRAME_TAGS] = { SECTION_ID_FRAME_TAGS, "tags", SECTION_FLAG_HAS_VARIABLE_FIELDS, { -1 }, .element_name = "tag", .unique_name = "frame_tags" },
[SECTION_ID_LIBRARY_VERSIONS] = { SECTION_ID_LIBRARY_VERSIONS, "library_versions", SECTION_FLAG_IS_ARRAY, { SECTION_ID_LIBRARY_VERSION, -1 } },
@@ -167,6 +168,7 @@
[SECTION_ID_STREAM] = { SECTION_ID_STREAM, "stream", 0, { SECTION_ID_STREAM_DISPOSITION, SECTION_ID_STREAM_TAGS, -1 } },
[SECTION_ID_STREAM_DISPOSITION] = { SECTION_ID_STREAM_DISPOSITION, "disposition", 0, { -1 }, .unique_name = "stream_disposition" },
[SECTION_ID_STREAM_TAGS] = { SECTION_ID_STREAM_TAGS, "tags", SECTION_FLAG_HAS_VARIABLE_FIELDS, { -1 }, .element_name = "tag", .unique_name = "stream_tags" },
+ [SECTION_ID_SUBTITLE] = { SECTION_ID_SUBTITLE, "subtitle", 0, { -1 } },
};
static const OptionDef *options;
@@ -258,6 +260,13 @@
#define WRITER_FLAG_DISPLAY_OPTIONAL_FIELDS 1
#define WRITER_FLAG_PUT_PACKETS_AND_FRAMES_IN_SAME_CHAPTER 2
+typedef enum {
+ WRITER_STRING_VALIDATION_FAIL,
+ WRITER_STRING_VALIDATION_REPLACE,
+ WRITER_STRING_VALIDATION_IGNORE,
+ WRITER_STRING_VALIDATION_NB
+} StringValidation;
+
typedef struct Writer {
const AVClass *priv_class; ///< private class of the writer, if any
int priv_size; ///< private size for the writer context
@@ -298,6 +307,10 @@
unsigned int nb_section_packet; ///< number of the packet section in case we are in "packets_and_frames" section
unsigned int nb_section_frame; ///< number of the frame section in case we are in "packets_and_frames" section
unsigned int nb_section_packet_frame; ///< nb_section_packet or nb_section_frame according if is_packets_and_frames
+
+ StringValidation string_validation;
+ char *string_validation_replacement;
+ unsigned int string_validation_utf8_flags;
};
static const char *writer_get_name(void *p)
@@ -306,11 +319,35 @@
return wctx->writer->name;
}
+#define OFFSET(x) offsetof(WriterContext, x)
+
+static const AVOption writer_options[] = {
+ { "string_validation", "set string validation mode",
+ OFFSET(string_validation), AV_OPT_TYPE_INT, {.i64=WRITER_STRING_VALIDATION_REPLACE}, 0, WRITER_STRING_VALIDATION_NB-1, .unit = "sv" },
+ { "sv", "set string validation mode",
+ OFFSET(string_validation), AV_OPT_TYPE_INT, {.i64=WRITER_STRING_VALIDATION_REPLACE}, 0, WRITER_STRING_VALIDATION_NB-1, .unit = "sv" },
+ { "ignore", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = WRITER_STRING_VALIDATION_IGNORE}, .unit = "sv" },
+ { "replace", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = WRITER_STRING_VALIDATION_REPLACE}, .unit = "sv" },
+ { "fail", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = WRITER_STRING_VALIDATION_FAIL}, .unit = "sv" },
+ { "string_validation_replacement", "set string validation replacement string", OFFSET(string_validation_replacement), AV_OPT_TYPE_STRING, {.str=""}},
+ { "svr", "set string validation replacement string", OFFSET(string_validation_replacement), AV_OPT_TYPE_STRING, {.str=""}},
+ { NULL }
+};
+
+static void *writer_child_next(void *obj, void *prev)
+{
+ WriterContext *ctx = obj;
+ if (!prev && ctx->writer && ctx->writer->priv_class && ctx->priv)
+ return ctx->priv;
+ return NULL;
+}
+
static const AVClass writer_class = {
- "Writer",
- writer_get_name,
- NULL,
- LIBAVUTIL_VERSION_INT,
+ .class_name = "Writer",
+ .item_name = writer_get_name,
+ .option = writer_options,
+ .version = LIBAVUTIL_VERSION_INT,
+ .child_next = writer_child_next,
};
static void writer_close(WriterContext **wctx)
@@ -327,9 +364,19 @@
if ((*wctx)->writer->priv_class)
av_opt_free((*wctx)->priv);
av_freep(&((*wctx)->priv));
+ av_opt_free(*wctx);
av_freep(wctx);
}
+static void bprint_bytes(AVBPrint *bp, const uint8_t *ubuf, size_t ubuf_size)
+{
+ int i;
+ av_bprintf(bp, "0X");
+ for (i = 0; i < ubuf_size; i++)
+ av_bprintf(bp, "%02X", ubuf[i]);
+}
+
+
static int writer_open(WriterContext **wctx, const Writer *writer, const char *args,
const struct section *sections, int nb_sections)
{
@@ -351,14 +398,55 @@
(*wctx)->sections = sections;
(*wctx)->nb_sections = nb_sections;
+ av_opt_set_defaults(*wctx);
+
if (writer->priv_class) {
void *priv_ctx = (*wctx)->priv;
*((const AVClass **)priv_ctx) = writer->priv_class;
av_opt_set_defaults(priv_ctx);
+ }
- if (args &&
- (ret = av_set_options_string(priv_ctx, args, "=", ":")) < 0)
+ /* convert options to dictionary */
+ if (args) {
+ AVDictionary *opts = NULL;
+ AVDictionaryEntry *opt = NULL;
+
+ if ((ret = av_dict_parse_string(&opts, args, "=", ":", 0)) < 0) {
+ av_log(*wctx, AV_LOG_ERROR, "Failed to parse option string '%s' provided to writer context\n", args);
+ av_dict_free(&opts);
goto fail;
+ }
+
+ while ((opt = av_dict_get(opts, "", opt, AV_DICT_IGNORE_SUFFIX))) {
+ if ((ret = av_opt_set(*wctx, opt->key, opt->value, AV_OPT_SEARCH_CHILDREN)) < 0) {
+ av_log(*wctx, AV_LOG_ERROR, "Failed to set option '%s' with value '%s' provided to writer context\n",
+ opt->key, opt->value);
+ av_dict_free(&opts);
+ goto fail;
+ }
+ }
+
+ av_dict_free(&opts);
+ }
+
+ /* validate replace string */
+ {
+ const uint8_t *p = (*wctx)->string_validation_replacement;
+ const uint8_t *endp = p + strlen(p);
+ while (*p) {
+ const uint8_t *p0 = p;
+ int32_t code;
+ ret = av_utf8_decode(&code, &p, endp, (*wctx)->string_validation_utf8_flags);
+ if (ret < 0) {
+ AVBPrint bp;
+ av_bprint_init(&bp, 0, AV_BPRINT_SIZE_AUTOMATIC);
+ bprint_bytes(&bp, p0, p-p0),
+ av_log(wctx, AV_LOG_ERROR,
+ "Invalid UTF8 sequence %s found in string validation replace '%s'\n",
+ bp.str, (*wctx)->string_validation_replacement);
+ return ret;
+ }
+ }
}
for (i = 0; i < SECTION_MAX_NB_LEVELS; i++)
@@ -428,18 +516,98 @@
}
}
-static inline void writer_print_string(WriterContext *wctx,
- const char *key, const char *val, int opt)
+static inline int validate_string(WriterContext *wctx, char **dstp, const char *src)
+{
+ const uint8_t *p, *endp;
+ AVBPrint dstbuf;
+ int invalid_chars_nb = 0, ret = 0;
+
+ av_bprint_init(&dstbuf, 0, AV_BPRINT_SIZE_UNLIMITED);
+
+ endp = src + strlen(src);
+ for (p = (uint8_t *)src; *p;) {
+ uint32_t code;
+ int invalid = 0;
+ const uint8_t *p0 = p;
+
+ if (av_utf8_decode(&code, &p, endp, wctx->string_validation_utf8_flags) < 0) {
+ AVBPrint bp;
+ av_bprint_init(&bp, 0, AV_BPRINT_SIZE_AUTOMATIC);
+ bprint_bytes(&bp, p0, p-p0);
+ av_log(wctx, AV_LOG_DEBUG,
+ "Invalid UTF-8 sequence %s found in string '%s'\n", bp.str, src);
+ invalid = 1;
+ }
+
+ if (invalid) {
+ invalid_chars_nb++;
+
+ switch (wctx->string_validation) {
+ case WRITER_STRING_VALIDATION_FAIL:
+ av_log(wctx, AV_LOG_ERROR,
+ "Invalid UTF-8 sequence found in string '%s'\n", src);
+ ret = AVERROR_INVALIDDATA;
+ goto end;
+ break;
+
+ case WRITER_STRING_VALIDATION_REPLACE:
+ av_bprintf(&dstbuf, "%s", wctx->string_validation_replacement);
+ break;
+ }
+ }
+
+ if (!invalid || wctx->string_validation == WRITER_STRING_VALIDATION_IGNORE)
+ av_bprint_append_data(&dstbuf, p0, p-p0);
+ }
+
+ if (invalid_chars_nb && wctx->string_validation == WRITER_STRING_VALIDATION_REPLACE) {
+ av_log(wctx, AV_LOG_WARNING,
+ "%d invalid UTF-8 sequence(s) found in string '%s', replaced with '%s'\n",
+ invalid_chars_nb, src, wctx->string_validation_replacement);
+ }
+
+end:
+ av_bprint_finalize(&dstbuf, dstp);
+ return ret;
+}
+
+#define PRINT_STRING_OPT 1
+#define PRINT_STRING_VALIDATE 2
+
+static inline int writer_print_string(WriterContext *wctx,
+ const char *key, const char *val, int flags)
{
const struct section *section = wctx->section[wctx->level];
+ int ret = 0;
- if (opt && !(wctx->writer->flags & WRITER_FLAG_DISPLAY_OPTIONAL_FIELDS))
- return;
+ if ((flags & PRINT_STRING_OPT)
+ && !(wctx->writer->flags & WRITER_FLAG_DISPLAY_OPTIONAL_FIELDS))
+ return 0;
if (section->show_all_entries || av_dict_get(section->entries_to_show, key, NULL, 0)) {
- wctx->writer->print_string(wctx, key, val);
+ if (flags & PRINT_STRING_VALIDATE) {
+ char *key1 = NULL, *val1 = NULL;
+ ret = validate_string(wctx, &key1, key);
+ if (ret < 0) goto end;
+ ret = validate_string(wctx, &val1, val);
+ if (ret < 0) goto end;
+ wctx->writer->print_string(wctx, key1, val1);
+ end:
+ if (ret < 0) {
+ av_log(wctx, AV_LOG_ERROR,
+ "Invalid key=value string combination %s=%s in section %s\n",
+ key, val, section->unique_name);
+ }
+ av_free(key1);
+ av_free(val1);
+ } else {
+ wctx->writer->print_string(wctx, key, val);
+ }
+
wctx->nb_item[wctx->level]++;
}
+
+ return ret;
}
static inline void writer_print_rational(WriterContext *wctx,
@@ -457,7 +625,7 @@
char buf[128];
if ((!is_duration && ts == AV_NOPTS_VALUE) || (is_duration && ts == 0)) {
- writer_print_string(wctx, key, "N/A", 1);
+ writer_print_string(wctx, key, "N/A", PRINT_STRING_OPT);
} else {
double d = ts * av_q2d(*time_base);
struct unit_value uv;
@@ -471,7 +639,7 @@
static void writer_print_ts(WriterContext *wctx, const char *key, int64_t ts, int is_duration)
{
if ((!is_duration && ts == AV_NOPTS_VALUE) || (is_duration && ts == 0)) {
- writer_print_string(wctx, key, "N/A", 1);
+ writer_print_string(wctx, key, "N/A", PRINT_STRING_OPT);
} else {
writer_print_integer(wctx, key, ts);
}
@@ -540,9 +708,9 @@
return #name ; \
} \
static const AVClass name##_class = { \
- #name, \
- name##_get_name, \
- name##_options \
+ .class_name = #name, \
+ .item_name = name##_get_name, \
+ .option = name##_options \
}
/* Default output */
@@ -554,6 +722,7 @@
int nested_section[SECTION_MAX_NB_LEVELS];
} DefaultContext;
+#undef OFFSET
#define OFFSET(x) offsetof(DefaultContext, x)
static const AVOption default_options[] = {
@@ -1440,7 +1609,8 @@
#define print_int(k, v) writer_print_integer(w, k, v)
#define print_q(k, v, s) writer_print_rational(w, k, v, s)
#define print_str(k, v) writer_print_string(w, k, v, 0)
-#define print_str_opt(k, v) writer_print_string(w, k, v, 1)
+#define print_str_opt(k, v) writer_print_string(w, k, v, PRINT_STRING_OPT)
+#define print_str_validate(k, v) writer_print_string(w, k, v, PRINT_STRING_VALIDATE)
#define print_time(k, v, tb) writer_print_time(w, k, v, tb, 0)
#define print_ts(k, v) writer_print_ts(w, k, v, 0)
#define print_duration_time(k, v, tb) writer_print_time(w, k, v, tb, 1)
@@ -1455,16 +1625,22 @@
#define print_section_header(s) writer_print_section_header(w, s)
#define print_section_footer(s) writer_print_section_footer(w, s)
-static inline void show_tags(WriterContext *wctx, AVDictionary *tags, int section_id)
+static inline int show_tags(WriterContext *w, AVDictionary *tags, int section_id)
{
AVDictionaryEntry *tag = NULL;
+ int ret = 0;
if (!tags)
- return;
- writer_print_section_header(wctx, section_id);
- while ((tag = av_dict_get(tags, "", tag, AV_DICT_IGNORE_SUFFIX)))
- writer_print_string(wctx, tag->key, tag->value, 0);
- writer_print_section_footer(wctx);
+ return 0;
+ writer_print_section_header(w, section_id);
+
+ while ((tag = av_dict_get(tags, "", tag, AV_DICT_IGNORE_SUFFIX))) {
+ if ((ret = print_str_validate(tag->key, tag->value)) < 0)
+ break;
+ }
+ writer_print_section_footer(w);
+
+ return ret;
}
static void show_packet(WriterContext *w, AVFormatContext *fmt_ctx, AVPacket *pkt, int packet_idx)
@@ -1502,6 +1678,29 @@
fflush(stdout);
}
+static void show_subtitle(WriterContext *w, AVSubtitle *sub, AVStream *stream,
+ AVFormatContext *fmt_ctx)
+{
+ AVBPrint pbuf;
+
+ av_bprint_init(&pbuf, 1, AV_BPRINT_SIZE_UNLIMITED);
+
+ writer_print_section_header(w, SECTION_ID_SUBTITLE);
+
+ print_str ("media_type", "subtitle");
+ print_ts ("pts", sub->pts);
+ print_time("pts_time", sub->pts, &AV_TIME_BASE_Q);
+ print_int ("format", sub->format);
+ print_int ("start_display_time", sub->start_display_time);
+ print_int ("end_display_time", sub->end_display_time);
+ print_int ("num_rects", sub->num_rects);
+
+ writer_print_section_footer(w);
+
+ av_bprint_finalize(&pbuf, NULL);
+ fflush(stdout);
+}
+
static void show_frame(WriterContext *w, AVFrame *frame, AVStream *stream,
AVFormatContext *fmt_ctx)
{
@@ -1578,6 +1777,7 @@
AVFrame *frame, AVPacket *pkt)
{
AVCodecContext *dec_ctx = fmt_ctx->streams[pkt->stream_index]->codec;
+ AVSubtitle sub;
int ret = 0, got_frame = 0;
avcodec_get_frame_defaults(frame);
@@ -1590,6 +1790,10 @@
case AVMEDIA_TYPE_AUDIO:
ret = avcodec_decode_audio4(dec_ctx, frame, &got_frame, pkt);
break;
+
+ case AVMEDIA_TYPE_SUBTITLE:
+ ret = avcodec_decode_subtitle2(dec_ctx, &sub, &got_frame, pkt);
+ break;
}
}
@@ -1599,9 +1803,15 @@
pkt->data += ret;
pkt->size -= ret;
if (got_frame) {
+ int is_sub = (dec_ctx->codec_type == AVMEDIA_TYPE_SUBTITLE);
nb_streams_frames[pkt->stream_index]++;
if (do_show_frames)
- show_frame(w, frame, fmt_ctx->streams[pkt->stream_index], fmt_ctx);
+ if (is_sub)
+ show_subtitle(w, &sub, fmt_ctx->streams[pkt->stream_index], fmt_ctx);
+ else
+ show_frame(w, frame, fmt_ctx->streams[pkt->stream_index], fmt_ctx);
+ if (is_sub)
+ avsubtitle_free(&sub);
}
return got_frame;
}
@@ -1723,7 +1933,7 @@
return ret;
}
-static void read_packets(WriterContext *w, AVFormatContext *fmt_ctx)
+static int read_packets(WriterContext *w, AVFormatContext *fmt_ctx)
{
int i, ret = 0;
int64_t cur_ts = fmt_ctx->start_time;
@@ -1738,9 +1948,11 @@
break;
}
}
+
+ return ret;
}
-static void show_stream(WriterContext *w, AVFormatContext *fmt_ctx, int stream_idx, int in_program)
+static int show_stream(WriterContext *w, AVFormatContext *fmt_ctx, int stream_idx, int in_program)
{
AVStream *stream = fmt_ctx->streams[stream_idx];
AVCodecContext *dec_ctx;
@@ -1749,6 +1961,7 @@
const char *s;
AVRational sar, dar;
AVBPrint pbuf;
+ int ret = 0;
av_bprint_init(&pbuf, 1, AV_BPRINT_SIZE_UNLIMITED);
@@ -1903,26 +2116,34 @@
writer_print_section_footer(w);
}
- show_tags(w, stream->metadata, in_program ? SECTION_ID_PROGRAM_STREAM_TAGS : SECTION_ID_STREAM_TAGS);
+ ret = show_tags(w, stream->metadata, in_program ? SECTION_ID_PROGRAM_STREAM_TAGS : SECTION_ID_STREAM_TAGS);
writer_print_section_footer(w);
av_bprint_finalize(&pbuf, NULL);
fflush(stdout);
+
+ return ret;
}
-static void show_streams(WriterContext *w, AVFormatContext *fmt_ctx)
+static int show_streams(WriterContext *w, AVFormatContext *fmt_ctx)
{
- int i;
+ int i, ret = 0;
+
writer_print_section_header(w, SECTION_ID_STREAMS);
for (i = 0; i < fmt_ctx->nb_streams; i++)
- if (selected_streams[i])
- show_stream(w, fmt_ctx, i, 0);
+ if (selected_streams[i]) {
+ ret = show_stream(w, fmt_ctx, i, 0);
+ if (ret < 0)
+ break;
+ }
writer_print_section_footer(w);
+
+ return ret;
}
-static void show_program(WriterContext *w, AVFormatContext *fmt_ctx, AVProgram *program)
+static int show_program(WriterContext *w, AVFormatContext *fmt_ctx, AVProgram *program)
{
- int i;
+ int i, ret = 0;
writer_print_section_header(w, SECTION_ID_PROGRAM);
print_int("program_id", program->id);
@@ -1934,35 +2155,45 @@
print_time("start_time", program->start_time, &AV_TIME_BASE_Q);
print_ts("end_pts", program->end_time);
print_time("end_time", program->end_time, &AV_TIME_BASE_Q);
- show_tags(w, program->metadata, SECTION_ID_PROGRAM_TAGS);
+ ret = show_tags(w, program->metadata, SECTION_ID_PROGRAM_TAGS);
+ if (ret < 0)
+ goto end;
writer_print_section_header(w, SECTION_ID_PROGRAM_STREAMS);
for (i = 0; i < program->nb_stream_indexes; i++) {
- if (selected_streams[program->stream_index[i]])
- show_stream(w, fmt_ctx, program->stream_index[i], 1);
+ if (selected_streams[program->stream_index[i]]) {
+ ret = show_stream(w, fmt_ctx, program->stream_index[i], 1);
+ if (ret < 0)
+ break;
+ }
}
writer_print_section_footer(w);
+end:
writer_print_section_footer(w);
+ return ret;
}
-static void show_programs(WriterContext *w, AVFormatContext *fmt_ctx)
+static int show_programs(WriterContext *w, AVFormatContext *fmt_ctx)
{
- int i;
+ int i, ret = 0;
writer_print_section_header(w, SECTION_ID_PROGRAMS);
for (i = 0; i < fmt_ctx->nb_programs; i++) {
AVProgram *program = fmt_ctx->programs[i];
if (!program)
continue;
- show_program(w, fmt_ctx, program);
+ ret = show_program(w, fmt_ctx, program);
+ if (ret < 0)
+ break;
}
writer_print_section_footer(w);
+ return ret;
}
-static void show_chapters(WriterContext *w, AVFormatContext *fmt_ctx)
+static int show_chapters(WriterContext *w, AVFormatContext *fmt_ctx)
{
- int i;
+ int i, ret = 0;
writer_print_section_header(w, SECTION_ID_CHAPTERS);
for (i = 0; i < fmt_ctx->nb_chapters; i++) {
@@ -1975,19 +2206,22 @@
print_time("start_time", chapter->start, &chapter->time_base);
print_int("end", chapter->end);
print_time("end_time", chapter->end, &chapter->time_base);
- show_tags(w, chapter->metadata, SECTION_ID_CHAPTER_TAGS);
+ ret = show_tags(w, chapter->metadata, SECTION_ID_CHAPTER_TAGS);
writer_print_section_footer(w);
}
writer_print_section_footer(w);
+
+ return ret;
}
-static void show_format(WriterContext *w, AVFormatContext *fmt_ctx)
+static int show_format(WriterContext *w, AVFormatContext *fmt_ctx)
{
char val_str[128];
int64_t size = fmt_ctx->pb ? avio_size(fmt_ctx->pb) : -1;
+ int ret = 0;
writer_print_section_header(w, SECTION_ID_FORMAT);
- print_str("filename", fmt_ctx->filename);
+ print_str_validate("filename", fmt_ctx->filename);
print_int("nb_streams", fmt_ctx->nb_streams);
print_int("nb_programs", fmt_ctx->nb_programs);
print_str("format_name", fmt_ctx->iformat->name);
@@ -2002,10 +2236,11 @@
if (fmt_ctx->bit_rate > 0) print_val ("bit_rate", fmt_ctx->bit_rate, unit_bit_per_second_str);
else print_str_opt("bit_rate", "N/A");
print_int("probe_score", av_format_get_probe_score(fmt_ctx));
- show_tags(w, fmt_ctx->metadata, SECTION_ID_FORMAT_TAGS);
+ ret = show_tags(w, fmt_ctx->metadata, SECTION_ID_FORMAT_TAGS);
writer_print_section_footer(w);
fflush(stdout);
+ return ret;
}
static void show_error(WriterContext *w, int err)
@@ -2111,6 +2346,8 @@
if (ret < 0)
return ret;
+#define CHECK_END if (ret < 0) goto end
+
nb_streams_frames = av_calloc(fmt_ctx->nb_streams, sizeof(*nb_streams_frames));
nb_streams_packets = av_calloc(fmt_ctx->nb_streams, sizeof(*nb_streams_packets));
selected_streams = av_calloc(fmt_ctx->nb_streams, sizeof(*selected_streams));
@@ -2120,8 +2357,7 @@
ret = avformat_match_stream_specifier(fmt_ctx,
fmt_ctx->streams[i],
stream_specifier);
- if (ret < 0)
- goto end;
+ CHECK_END;
else
selected_streams[i] = ret;
ret = 0;
@@ -2140,18 +2376,28 @@
section_id = SECTION_ID_FRAMES;
if (do_show_frames || do_show_packets)
writer_print_section_header(wctx, section_id);
- read_packets(wctx, fmt_ctx);
+ ret = read_packets(wctx, fmt_ctx);
if (do_show_frames || do_show_packets)
writer_print_section_footer(wctx);
+ CHECK_END;
}
- if (do_show_programs)
- show_programs(wctx, fmt_ctx);
- if (do_show_streams)
- show_streams(wctx, fmt_ctx);
- if (do_show_chapters)
- show_chapters(wctx, fmt_ctx);
- if (do_show_format)
- show_format(wctx, fmt_ctx);
+ if (do_show_programs) {
+ ret = show_programs(wctx, fmt_ctx);
+ CHECK_END;
+ }
+
+ if (do_show_streams) {
+ ret = show_streams(wctx, fmt_ctx);
+ CHECK_END;
+ }
+ if (do_show_chapters) {
+ ret = show_chapters(wctx, fmt_ctx);
+ CHECK_END;
+ }
+ if (do_show_format) {
+ ret = show_format(wctx, fmt_ctx);
+ CHECK_END;
+ }
end:
close_input_file(&fmt_ctx);
@@ -2177,7 +2423,7 @@
writer_print_section_header(w, SECTION_ID_PROGRAM_VERSION);
print_str("version", FFMPEG_VERSION);
print_fmt("copyright", "Copyright (c) %d-%d the FFmpeg developers",
- program_birth_year, this_year);
+ program_birth_year, CONFIG_THIS_YEAR);
print_str("build_date", __DATE__);
print_str("build_time", __TIME__);
print_str("compiler_ident", CC_IDENT);
@@ -2460,8 +2706,11 @@
/* parse intervals */
p = spec;
- for (i = 0; i < n; i++) {
- char *next = strchr(p, ',');
+ for (i = 0; p; i++) {
+ char *next;
+
+ av_assert0(i < read_intervals_nb);
+ next = strchr(p, ',');
if (next)
*next++ = 0;
@@ -2475,7 +2724,6 @@
av_log(NULL, AV_LOG_VERBOSE, "Parsed log interval ");
log_read_interval(&read_intervals[i], NULL, AV_LOG_VERBOSE);
p = next;
- av_assert0(i <= read_intervals_nb);
}
av_assert0(i == read_intervals_nb);
@@ -2674,6 +2922,9 @@
if ((ret = writer_open(&wctx, w, w_args,
sections, FF_ARRAY_ELEMS(sections))) >= 0) {
+ if (w == &xml_writer)
+ wctx->string_validation_utf8_flags |= AV_UTF8_FLAG_EXCLUDE_XML_INVALID_CONTROL_CODES;
+
writer_print_section_header(wctx, SECTION_ID_ROOT);
if (do_show_program_version)
diff --git a/ffserver.c b/ffserver.c
index 5ecdb08..4d656b0 100644
--- a/ffserver.c
+++ b/ffserver.c
@@ -509,8 +509,9 @@
char *slash;
int i;
+ /* replace "ffserver" with "ffmpeg" in the path of current program,
+ * ignore user provided path */
av_strlcpy(pathname, my_program_name, sizeof(pathname));
-
slash = strrchr(pathname, '/');
if (!slash)
slash = pathname;
@@ -2183,8 +2184,10 @@
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)
+ if ((ret = av_parse_time(&stream_pos, buf, 0)) < 0) {
+ http_log("Invalid date specification '%s' for stream\n", buf);
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;
@@ -2195,18 +2198,22 @@
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)
+ if ((ret = av_parse_time(&stream_pos, buf, 1)) < 0) {
+ http_log("Invalid date specification '%s' for stream\n", buf);
return ret;
+ }
} else
stream_pos = 0;
}
- if (input_filename[0] == '\0')
- return -1;
+ if (!input_filename[0]) {
+ http_log("No filename was specified for stream\n");
+ return AVERROR(EINVAL);
+ }
/* 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;
+ http_log("Could not open input '%s': %s\n", input_filename, av_err2str(ret));
+ return ret;
}
/* set buffer size */
@@ -2214,10 +2221,11 @@
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);
+ if (strcmp(s->iformat->name, "ffm") &&
+ (ret = avformat_find_stream_info(c->fmt_in, NULL)) < 0) {
+ http_log("Could not find stream info for input '%s'\n", input_filename);
avformat_close_input(&s);
- return -1;
+ return ret;
}
/* choose stream as clock source (we favorize video stream if
@@ -2313,9 +2321,10 @@
*/
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;
+ if ((ret = avformat_write_header(&c->fmt_ctx, NULL)) < 0) {
+ http_log("Error writing output header for stream '%s': %s\n",
+ c->stream->filename, av_err2str(ret));
+ return ret;
}
av_dict_free(&c->fmt_ctx.metadata);
@@ -2614,19 +2623,26 @@
static int http_start_receive_data(HTTPContext *c)
{
int fd;
+ int ret;
- if (c->stream->feed_opened)
- return -1;
+ if (c->stream->feed_opened) {
+ http_log("Stream feed '%s' was not opened\n", c->stream->feed_filename);
+ return AVERROR(EINVAL);
+ }
/* Don't permit writing to this one */
- if (c->stream->readonly)
- return -1;
+ if (c->stream->readonly) {
+ http_log("Cannot write to read-only file '%s'\n", c->stream->feed_filename);
+ return AVERROR(EINVAL);
+ }
/* 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;
+ ret = AVERROR(errno);
+ http_log("Could not open feed file '%s':%s \n",
+ c->stream->feed_filename, strerror(errno));
+ return ret;
}
c->feed_fd = fd;
@@ -2635,13 +2651,19 @@
ffm_write_write_index(c->feed_fd, FFM_PACKET_SIZE);
http_log("Truncating feed file '%s'\n", c->stream->feed_filename);
if (ftruncate(c->feed_fd, FFM_PACKET_SIZE) < 0) {
- http_log("Error truncating feed file: %s\n", strerror(errno));
- return -1;
+ ret = AVERROR(errno);
+ http_log("Error truncating feed file '%s': %s\n",
+ c->stream->feed_filename, strerror(errno));
+ return ret;
}
} 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;
+ ret = ffm_read_write_index(fd);
+ if (ret < 0) {
+ http_log("Error reading write index from feed file '%s': %s\n",
+ c->stream->feed_filename, strerror(errno));
+ return ret;
+ } else {
+ c->stream->feed_write_index = ret;
}
}
@@ -3669,9 +3691,14 @@
av_dict_set(&stream->in_opts, "mpeg2ts_compute_pcr", "1", 0);
}
- http_log("Opening file '%s'\n", stream->feed_filename);
+ if (!stream->feed_filename[0]) {
+ http_log("Unspecified feed file for stream '%s'\n", stream->filename);
+ goto fail;
+ }
+
+ http_log("Opening feed file '%s' for stream '%s'\n", stream->feed_filename, stream->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);
+ http_log("Could not open '%s': %s\n", stream->feed_filename, av_err2str(ret));
/* remove stream (no need to spend more time on it) */
fail:
remove_stream(stream);
@@ -3942,24 +3969,13 @@
memcpy(st->codec, av, sizeof(AVCodecContext));
}
-static enum AVCodecID opt_audio_codec(const char *arg)
+static enum AVCodecID opt_codec(const char *name, enum AVMediaType type)
{
- AVCodec *p= avcodec_find_encoder_by_name(arg);
+ AVCodec *codec = avcodec_find_encoder_by_name(name);
- if (p == NULL || p->type != AVMEDIA_TYPE_AUDIO)
+ if (!codec || codec->type != type)
return AV_CODEC_ID_NONE;
-
- return p->id;
-}
-
-static enum AVCodecID opt_video_codec(const char *arg)
-{
- AVCodec *p= avcodec_find_encoder_by_name(arg);
-
- if (p == NULL || p->type != AVMEDIA_TYPE_VIDEO)
- return AV_CODEC_ID_NONE;
-
- return p->id;
+ return codec->id;
}
static int ffserver_opt_default(const char *opt, const char *arg,
@@ -3998,9 +4014,9 @@
break;
}
if(!strcmp(tmp, "acodec")){
- *audio_id = opt_audio_codec(tmp2);
+ *audio_id = opt_codec(tmp2, AVMEDIA_TYPE_AUDIO);
}else if(!strcmp(tmp, "vcodec")){
- *video_id = opt_video_codec(tmp2);
+ *video_id = opt_codec(tmp2, AVMEDIA_TYPE_VIDEO);
}else if(!strcmp(tmp, "scodec")){
/* opt_subtitle_codec(tmp2); */
}else if(ffserver_opt_default(tmp, tmp2, avctx, type) < 0){
@@ -4057,11 +4073,13 @@
FFStream **last_feed, *feed, *s;
AVCodecContext audio_enc, video_enc;
enum AVCodecID audio_id, video_id;
+ int ret = 0;
f = fopen(filename, "r");
if (!f) {
- perror(filename);
- return -1;
+ ret = AVERROR(errno);
+ av_log(NULL, AV_LOG_ERROR, "Could not open the configuration file '%s'\n", filename);
+ return ret;
}
errors = 0;
@@ -4149,6 +4167,10 @@
ERROR("Already in a tag\n");
} else {
feed = av_mallocz(sizeof(FFStream));
+ if (!feed) {
+ ret = AVERROR(ENOMEM);
+ goto end;
+ }
get_arg(feed->filename, sizeof(feed->filename), &p);
q = strrchr(feed->filename, '>');
if (*q)
@@ -4161,7 +4183,7 @@
}
feed->fmt = av_guess_format("ffm", NULL, NULL);
- /* defaut feed file */
+ /* default feed file */
snprintf(feed->feed_filename, sizeof(feed->feed_filename),
"/tmp/%s.ffm", feed->filename);
feed->feed_max_size = 5 * 1024 * 1024;
@@ -4180,36 +4202,51 @@
int i;
feed->child_argv = av_mallocz(64 * sizeof(char *));
-
+ if (!feed->child_argv) {
+ ret = AVERROR(ENOMEM);
+ goto end;
+ }
for (i = 0; i < 62; i++) {
get_arg(arg, sizeof(arg), &p);
if (!arg[0])
break;
feed->child_argv[i] = av_strdup(arg);
+ if (!feed->child_argv[i]) {
+ ret = AVERROR(ENOMEM);
+ goto end;
+ }
}
- feed->child_argv[i] = av_asprintf("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);
+ feed->child_argv[i] =
+ av_asprintf("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);
+ if (!feed->child_argv[i]) {
+ ret = AVERROR(ENOMEM);
+ goto end;
+ }
}
- } else if (!av_strcasecmp(cmd, "ReadOnlyFile")) {
+ } else if (!av_strcasecmp(cmd, "File") || !av_strcasecmp(cmd, "ReadOnlyFile")) {
if (feed) {
get_arg(feed->feed_filename, sizeof(feed->feed_filename), &p);
- feed->readonly = 1;
+ feed->readonly = !av_strcasecmp(cmd, "ReadOnlyFile");
} 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);
+ /* assume Truncate is true in case no argument is specified */
+ if (!arg[0]) {
+ feed->truncate = 1;
+ } else {
+ av_log(NULL, AV_LOG_WARNING,
+ "Truncate N syntax in configuration file is deprecated, "
+ "use Truncate alone with no arguments\n");
+ feed->truncate = strtod(arg, NULL);
+ }
}
} else if (!av_strcasecmp(cmd, "FileMaxSize")) {
if (feed) {
@@ -4249,6 +4286,10 @@
} else {
FFStream *s;
stream = av_mallocz(sizeof(FFStream));
+ if (!stream) {
+ ret = AVERROR(ENOMEM);
+ goto end;
+ }
get_arg(stream->filename, sizeof(stream->filename), &p);
q = strrchr(stream->filename, '>');
if (q)
@@ -4286,7 +4327,7 @@
sfeed = sfeed->next_feed;
}
if (!sfeed)
- ERROR("feed '%s' not defined\n", arg);
+ ERROR("Feed with name '%s' for stream '%s' is not defined\n", arg, stream->filename);
else
stream->feed = sfeed;
}
@@ -4346,13 +4387,13 @@
stream->send_on_key = 1;
} else if (!av_strcasecmp(cmd, "AudioCodec")) {
get_arg(arg, sizeof(arg), &p);
- audio_id = opt_audio_codec(arg);
+ audio_id = opt_codec(arg, AVMEDIA_TYPE_AUDIO);
if (audio_id == AV_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);
+ video_id = opt_codec(arg, AVMEDIA_TYPE_VIDEO);
if (video_id == AV_CODEC_ID_NONE) {
ERROR("Unknown VideoCodec: %s\n", arg);
}
@@ -4372,11 +4413,6 @@
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;
@@ -4418,10 +4454,14 @@
} 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");
+ ret = av_parse_video_size(&video_enc.width, &video_enc.height, arg);
+ if (ret < 0) {
+ ERROR("Invalid video size '%s'\n", arg);
+ } else {
+ 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")) {
@@ -4473,7 +4513,7 @@
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);
+ ERROR("Error setting %s option to %s %s\n", cmd, arg, arg2);
}
} else if (!av_strcasecmp(cmd, "AVPresetVideo") ||
!av_strcasecmp(cmd, "AVPresetAudio")) {
@@ -4604,6 +4644,10 @@
ERROR("Already in a tag\n");
} else {
redirect = av_mallocz(sizeof(FFStream));
+ if (!redirect) {
+ ret = AVERROR(ENOMEM);
+ goto end;
+ }
*last_stream = redirect;
last_stream = &redirect->next;
@@ -4633,9 +4677,12 @@
}
#undef ERROR
+end:
fclose(f);
+ if (ret < 0)
+ return ret;
if (errors)
- return -1;
+ return AVERROR(EINVAL);
else
return 0;
}
@@ -4690,6 +4737,7 @@
int main(int argc, char **argv)
{
struct sigaction sigact = { { 0 } };
+ int ret = 0;
config_filename = av_strdup("/etc/ffserver.conf");
@@ -4711,8 +4759,9 @@
sigact.sa_flags = SA_NOCLDSTOP | SA_RESTART;
sigaction(SIGCHLD, &sigact, 0);
- if (parse_ffconfig(config_filename) < 0) {
- fprintf(stderr, "Incorrect config file - exiting.\n");
+ if ((ret = parse_ffconfig(config_filename)) < 0) {
+ fprintf(stderr, "Error reading configuration file '%s': %s\n",
+ config_filename, av_err2str(ret));
exit(1);
}
av_freep(&config_filename);
diff --git a/libavcodec/4xm.c b/libavcodec/4xm.c
index a73f8d5..eb07cc3 100644
--- a/libavcodec/4xm.c
+++ b/libavcodec/4xm.c
@@ -461,14 +461,12 @@
return AVERROR_INVALIDDATA;
}
- av_fast_malloc(&f->bitstream_buffer, &f->bitstream_buffer_size,
- bitstream_size + FF_INPUT_BUFFER_PADDING_SIZE);
+ av_fast_padded_malloc(&f->bitstream_buffer, &f->bitstream_buffer_size,
+ bitstream_size);
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);
wordstream_offset = extra + bitstream_size;
@@ -803,14 +801,12 @@
prestream_size = length + buf - prestream;
- av_fast_malloc(&f->bitstream_buffer, &f->bitstream_buffer_size,
- prestream_size + FF_INPUT_BUFFER_PADDING_SIZE);
+ av_fast_padded_malloc(&f->bitstream_buffer, &f->bitstream_buffer_size,
+ prestream_size);
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;
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 230c3f3..0f6f881 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -31,8 +31,6 @@
resample2.o \
utils.o \
-OBJS-$(HAVE_MSVCRT) += file_open.o
-
# parts needed for many different codecs
OBJS-$(CONFIG_AANDCTTABLES) += aandcttab.o
OBJS-$(CONFIG_AC3DSP) += ac3dsp.o
@@ -50,6 +48,7 @@
fft_fixed_32.o fft_init_table.o \
$(FFT-OBJS-yes)
OBJS-$(CONFIG_GOLOMB) += golomb.o
+OBJS-$(CONFIG_H263DSP) += h263dsp.o
OBJS-$(CONFIG_H264CHROMA) += h264chroma.o
OBJS-$(CONFIG_H264DSP) += h264dsp.o h264idct.o
OBJS-$(CONFIG_H264PRED) += h264pred.o
@@ -178,7 +177,7 @@
OBJS-$(CONFIG_DVDSUB_DECODER) += dvdsubdec.o
OBJS-$(CONFIG_DVDSUB_ENCODER) += dvdsubenc.o
OBJS-$(CONFIG_DVVIDEO_DECODER) += dvdec.o dv.o dvdata.o dv_profile.o
-OBJS-$(CONFIG_DVVIDEO_ENCODER) += dv.o dvdata.o dv_profile.o
+OBJS-$(CONFIG_DVVIDEO_ENCODER) += dvenc.o dv.o dvdata.o dv_profile.o
OBJS-$(CONFIG_DXA_DECODER) += dxa.o
OBJS-$(CONFIG_DXTORY_DECODER) += dxtory.o
OBJS-$(CONFIG_EAC3_DECODER) += eac3dec.o eac3_data.o
@@ -233,6 +232,10 @@
cabac.o h264_sei.o h264_ps.o \
h264_refs.o h264_cavlc.o h264_cabac.o
OBJS-$(CONFIG_H264_VDA_DECODER) += vda_h264_dec.o
+OBJS-$(CONFIG_HEVC_DECODER) += hevc.o hevc_mvs.o hevc_ps.o hevc_sei.o \
+ hevc_cabac.o hevc_refs.o hevcpred.o \
+ hevcdsp.o hevc_filter.o cabac.o
+OBJS-$(CONFIG_HNM4_VIDEO_DECODER) += hnm4video.o
OBJS-$(CONFIG_HUFFYUV_DECODER) += huffyuv.o huffyuvdec.o
OBJS-$(CONFIG_HUFFYUV_ENCODER) += huffyuv.o huffyuvenc.o
OBJS-$(CONFIG_IAC_DECODER) += imc.o
@@ -276,17 +279,19 @@
OBJS-$(CONFIG_MOTIONPIXELS_DECODER) += motionpixels.o
OBJS-$(CONFIG_MOVTEXT_DECODER) += movtextdec.o ass.o
OBJS-$(CONFIG_MOVTEXT_ENCODER) += movtextenc.o ass_split.o
-OBJS-$(CONFIG_MP1_DECODER) += mpegaudiodec.o
+OBJS-$(CONFIG_MP1_DECODER) += mpegaudiodec_fixed.o
OBJS-$(CONFIG_MP1FLOAT_DECODER) += mpegaudiodec_float.o
-OBJS-$(CONFIG_MP2_DECODER) += mpegaudiodec.o
-OBJS-$(CONFIG_MP2_ENCODER) += mpegaudioenc.o mpegaudio.o \
+OBJS-$(CONFIG_MP2_DECODER) += mpegaudiodec_fixed.o
+OBJS-$(CONFIG_MP2_ENCODER) += mpegaudioenc_float.o mpegaudio.o \
+ mpegaudiodata.o mpegaudiodsp_data.o
+OBJS-$(CONFIG_MP2FIXED_ENCODER) += mpegaudioenc_fixed.o mpegaudio.o \
mpegaudiodata.o mpegaudiodsp_data.o
OBJS-$(CONFIG_MP2FLOAT_DECODER) += mpegaudiodec_float.o
-OBJS-$(CONFIG_MP3_DECODER) += mpegaudiodec.o
-OBJS-$(CONFIG_MP3ADU_DECODER) += mpegaudiodec.o
+OBJS-$(CONFIG_MP3_DECODER) += mpegaudiodec_fixed.o
+OBJS-$(CONFIG_MP3ADU_DECODER) += mpegaudiodec_fixed.o
OBJS-$(CONFIG_MP3ADUFLOAT_DECODER) += mpegaudiodec_float.o
OBJS-$(CONFIG_MP3FLOAT_DECODER) += mpegaudiodec_float.o
-OBJS-$(CONFIG_MP3ON4_DECODER) += mpegaudiodec.o mpeg4audio.o
+OBJS-$(CONFIG_MP3ON4_DECODER) += mpegaudiodec_fixed.o mpeg4audio.o
OBJS-$(CONFIG_MP3ON4FLOAT_DECODER) += mpegaudiodec_float.o mpeg4audio.o
OBJS-$(CONFIG_MPC7_DECODER) += mpc7.o mpc.o
OBJS-$(CONFIG_MPC8_DECODER) += mpc8.o mpc.o
@@ -296,8 +301,7 @@
OBJS-$(CONFIG_MPEG1VIDEO_DECODER) += mpeg12dec.o mpeg12.o mpeg12data.o
OBJS-$(CONFIG_MPEG1VIDEO_ENCODER) += mpeg12enc.o mpeg12.o
OBJS-$(CONFIG_MPEG2VIDEO_DECODER) += mpeg12dec.o mpeg12.o mpeg12data.o
-OBJS-$(CONFIG_MPEG2VIDEO_ENCODER) += mpeg12enc.o mpeg12.o \
- timecode.o
+OBJS-$(CONFIG_MPEG2VIDEO_ENCODER) += mpeg12enc.o mpeg12.o
OBJS-$(CONFIG_MPL2_DECODER) += mpl2dec.o ass.o
OBJS-$(CONFIG_MSMPEG4V1_DECODER) += msmpeg4dec.o msmpeg4.o msmpeg4data.o
OBJS-$(CONFIG_MSMPEG4V2_DECODER) += msmpeg4dec.o msmpeg4.o msmpeg4data.o \
@@ -327,22 +331,22 @@
OBJS-$(CONFIG_PAF_VIDEO_DECODER) += paf.o
OBJS-$(CONFIG_PAF_AUDIO_DECODER) += paf.o
OBJS-$(CONFIG_PAM_DECODER) += pnmdec.o pnm.o
-OBJS-$(CONFIG_PAM_ENCODER) += pamenc.o pnm.o
+OBJS-$(CONFIG_PAM_ENCODER) += pamenc.o
OBJS-$(CONFIG_PBM_DECODER) += pnmdec.o pnm.o
-OBJS-$(CONFIG_PBM_ENCODER) += pnmenc.o pnm.o
+OBJS-$(CONFIG_PBM_ENCODER) += pnmenc.o
OBJS-$(CONFIG_PCX_DECODER) += pcx.o
OBJS-$(CONFIG_PCX_ENCODER) += pcxenc.o
OBJS-$(CONFIG_PGM_DECODER) += pnmdec.o pnm.o
-OBJS-$(CONFIG_PGM_ENCODER) += pnmenc.o pnm.o
+OBJS-$(CONFIG_PGM_ENCODER) += pnmenc.o
OBJS-$(CONFIG_PGMYUV_DECODER) += pnmdec.o pnm.o
-OBJS-$(CONFIG_PGMYUV_ENCODER) += pnmenc.o pnm.o
+OBJS-$(CONFIG_PGMYUV_ENCODER) += pnmenc.o
OBJS-$(CONFIG_PGSSUB_DECODER) += pgssubdec.o
OBJS-$(CONFIG_PICTOR_DECODER) += pictordec.o cga_data.o
OBJS-$(CONFIG_PJS_DECODER) += textdec.o ass.o
OBJS-$(CONFIG_PNG_DECODER) += png.o pngdec.o pngdsp.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_PPM_ENCODER) += pnmenc.o
OBJS-$(CONFIG_PRORES_DECODER) += proresdec2.o proresdsp.o proresdata.o
OBJS-$(CONFIG_PRORES_LGPL_DECODER) += proresdec_lgpl.o proresdsp.o proresdata.o
OBJS-$(CONFIG_PRORES_ENCODER) += proresenc_anatoliy.o
@@ -594,6 +598,7 @@
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_G726LE_DECODER) += g726.o
OBJS-$(CONFIG_ADPCM_IMA_AMV_DECODER) += adpcm.o adpcm_data.o
OBJS-$(CONFIG_ADPCM_IMA_APC_DECODER) += adpcm.o adpcm_data.o
OBJS-$(CONFIG_ADPCM_IMA_DK3_DECODER) += adpcm.o adpcm_data.o
@@ -645,7 +650,7 @@
OBJS-$(CONFIG_CAF_DEMUXER) += mpeg4audio.o mpegaudiodata.o \
ac3tab.o
OBJS-$(CONFIG_DV_DEMUXER) += dv_profile.o
-OBJS-$(CONFIG_DV_MUXER) += dv_profile.o timecode.o
+OBJS-$(CONFIG_DV_MUXER) += dv_profile.o
OBJS-$(CONFIG_FLAC_DEMUXER) += flac.o flacdata.o vorbis_data.o \
vorbis_parser.o xiph.o
OBJS-$(CONFIG_FLAC_MUXER) += flac.o flacdata.o vorbis_data.o
@@ -661,11 +666,11 @@
flac.o flacdata.o vorbis_data.o xiph.o
OBJS-$(CONFIG_MP2_MUXER) += mpegaudiodata.o mpegaudiodecheader.o
OBJS-$(CONFIG_MP3_MUXER) += mpegaudiodata.o mpegaudiodecheader.o
-OBJS-$(CONFIG_MOV_DEMUXER) += mpeg4audio.o mpegaudiodata.o ac3tab.o timecode.o
+OBJS-$(CONFIG_MOV_DEMUXER) += mpeg4audio.o mpegaudiodata.o ac3tab.o
OBJS-$(CONFIG_MOV_MUXER) += mpeg4audio.o mpegaudiodata.o
OBJS-$(CONFIG_MPEGTS_MUXER) += mpeg4audio.o
OBJS-$(CONFIG_MPEGTS_DEMUXER) += mpeg4audio.o mpegaudiodata.o
-OBJS-$(CONFIG_MXF_MUXER) += timecode.o dnxhddata.o
+OBJS-$(CONFIG_MXF_MUXER) += dnxhddata.o
OBJS-$(CONFIG_NUT_MUXER) += mpegaudiodata.o
OBJS-$(CONFIG_OGG_DEMUXER) += xiph.o flac.o flacdata.o \
mpeg12data.o vorbis_parser.o \
@@ -682,6 +687,9 @@
vorbis_data.o
OBJS-$(CONFIG_WTV_DEMUXER) += mpeg4audio.o mpegaudiodata.o
+# libavfilter dependencies
+OBJS-$(CONFIG_ELBG_FILTER) += elbg.o
+
# external codec libraries
OBJS-$(CONFIG_LIBAACPLUS_ENCODER) += libaacplus.o
OBJS-$(CONFIG_LIBCELT_DECODER) += libcelt_dec.o
@@ -723,8 +731,8 @@
vorbis_data.o vorbis_parser.o xiph.o
OBJS-$(CONFIG_LIBVPX_VP8_DECODER) += libvpxdec.o
OBJS-$(CONFIG_LIBVPX_VP8_ENCODER) += libvpxenc.o
-OBJS-$(CONFIG_LIBVPX_VP9_DECODER) += libvpxdec.o
-OBJS-$(CONFIG_LIBVPX_VP9_ENCODER) += libvpxenc.o
+OBJS-$(CONFIG_LIBVPX_VP9_DECODER) += libvpxdec.o libvpx.o
+OBJS-$(CONFIG_LIBVPX_VP9_ENCODER) += libvpxenc.o libvpx.o
OBJS-$(CONFIG_LIBWAVPACK_ENCODER) += libwavpackenc.o
OBJS-$(CONFIG_LIBX264_ENCODER) += libx264.o
OBJS-$(CONFIG_LIBXAVS_ENCODER) += libxavs.o
@@ -758,6 +766,7 @@
h264_refs.o h264_sei.o h264_direct.o \
h264_loopfilter.o h264_cabac.o \
h264_cavlc.o h264_ps.o
+OBJS-$(CONFIG_HEVC_PARSER) += hevc_parser.o
OBJS-$(CONFIG_MJPEG_PARSER) += mjpeg_parser.o
OBJS-$(CONFIG_MLP_PARSER) += mlp_parser.o mlp.o
OBJS-$(CONFIG_MPEG4VIDEO_PARSER) += mpeg4video_parser.o h263.o \
@@ -778,6 +787,7 @@
OBJS-$(CONFIG_VORBIS_PARSER) += vorbis_parser.o xiph.o
OBJS-$(CONFIG_VP3_PARSER) += vp3_parser.o
OBJS-$(CONFIG_VP8_PARSER) += vp8_parser.o
+OBJS-$(CONFIG_VP9_PARSER) += vp9_parser.o
# bitstream filters
OBJS-$(CONFIG_AAC_ADTSTOASC_BSF) += aac_adtstoasc_bsf.o aacadtsdec.o \
@@ -789,7 +799,6 @@
OBJS-$(CONFIG_MJPEG2JPEG_BSF) += mjpeg2jpeg_bsf.o mjpeg.o
OBJS-$(CONFIG_MJPEGA_DUMP_HEADER_BSF) += mjpega_dump_header_bsf.o
OBJS-$(CONFIG_MOV2TEXTSUB_BSF) += movsub_bsf.o
-OBJS-$(CONFIG_MP3_HEADER_COMPRESS_BSF) += mp3_header_compress_bsf.o
OBJS-$(CONFIG_MP3_HEADER_DECOMPRESS_BSF) += mp3_header_decompress_bsf.o \
mpegaudiodata.o
OBJS-$(CONFIG_NOISE_BSF) += noise_bsf.o
@@ -797,12 +806,16 @@
OBJS-$(CONFIG_TEXT2MOVSUB_BSF) += movsub_bsf.o
# thread libraries
-OBJS-$(HAVE_PTHREADS) += pthread.o
-OBJS-$(HAVE_W32THREADS) += pthread.o
-OBJS-$(HAVE_OS2THREADS) += pthread.o
+OBJS-$(HAVE_LIBC_MSVCRT) += file_open.o
+OBJS-$(HAVE_PTHREADS) += pthread.o pthread_slice.o pthread_frame.o
+OBJS-$(HAVE_W32THREADS) += pthread.o pthread_slice.o pthread_frame.o
+OBJS-$(HAVE_OS2THREADS) += pthread.o pthread_slice.o pthread_frame.o
OBJS-$(CONFIG_FRAME_THREAD_ENCODER) += frame_thread_encoder.o
+# Windows resource file
+SLIBOBJS-$(HAVE_GNU_WINDRES) += avcodecres.o
+
SKIPHEADERS += %_tablegen.h \
%_tables.h \
aac_tablegen_decl.h \
@@ -849,6 +862,7 @@
CLEANFILES = *_tables.c *_tables.h *_tablegen$(HOSTEXESUF)
$(SUBDIR)dct-test$(EXESUF): $(SUBDIR)dctref.o $(SUBDIR)aandcttab.o
+$(SUBDIR)dv_tablegen$(HOSTEXESUF): $(SUBDIR)dvdata_host.o
TRIG_TABLES = cos cos_fixed sin
TRIG_TABLES := $(TRIG_TABLES:%=$(SUBDIR)%_tables.c)
@@ -874,9 +888,9 @@
$(SUBDIR)aacdec.o: $(SUBDIR)cbrt_tables.h
$(SUBDIR)aacps.o: $(SUBDIR)aacps_tables.h
$(SUBDIR)aactab.o: $(SUBDIR)aac_tables.h
-$(SUBDIR)dv.o: $(SUBDIR)dv_tables.h
+$(SUBDIR)dvenc.o: $(SUBDIR)dv_tables.h
$(SUBDIR)sinewin.o: $(SUBDIR)sinewin_tables.h
-$(SUBDIR)mpegaudiodec.o: $(SUBDIR)mpegaudio_tables.h
+$(SUBDIR)mpegaudiodec_fixed.o: $(SUBDIR)mpegaudio_tables.h
$(SUBDIR)mpegaudiodec_float.o: $(SUBDIR)mpegaudio_tables.h
$(SUBDIR)motionpixels.o: $(SUBDIR)motionpixels_tables.h
$(SUBDIR)pcm.o: $(SUBDIR)pcm_tables.h
diff --git a/libavcodec/a64multienc.c b/libavcodec/a64multienc.c
index e5c0fa7..6dd5c2c 100644
--- a/libavcodec/a64multienc.c
+++ b/libavcodec/a64multienc.c
@@ -40,9 +40,6 @@
#define C64YRES 200
typedef struct A64Context {
- /* general variables */
- AVFrame picture;
-
/* variables for multicolor modes */
AVLFG randctx;
int mc_lifetime;
@@ -189,6 +186,7 @@
static av_cold int a64multi_close_encoder(AVCodecContext *avctx)
{
A64Context *c = avctx->priv_data;
+ av_frame_free(&avctx->coded_frame);
av_free(c->mc_meta_charset);
av_free(c->mc_best_cb);
av_free(c->mc_charset);
@@ -240,8 +238,12 @@
AV_WB32(avctx->extradata, c->mc_lifetime);
AV_WB32(avctx->extradata + 16, INTERLACED);
- avcodec_get_frame_defaults(&c->picture);
- avctx->coded_frame = &c->picture;
+ avctx->coded_frame = av_frame_alloc();
+ if (!avctx->coded_frame) {
+ a64multi_close_encoder(avctx);
+ return AVERROR(ENOMEM);
+ }
+
avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
avctx->coded_frame->key_frame = 1;
if (!avctx->codec_tag)
@@ -271,7 +273,7 @@
const AVFrame *pict, int *got_packet)
{
A64Context *c = avctx->priv_data;
- AVFrame *const p = &c->picture;
+ AVFrame *const p = avctx->coded_frame;
int frame;
int x, y;
@@ -338,8 +340,8 @@
buf = pkt->data;
/* calc optimal new charset + charmaps */
- ff_init_elbg(meta, 32, 1000 * c->mc_lifetime, best_cb, CHARSET_CHARS, 50, charmap, &c->randctx);
- ff_do_elbg (meta, 32, 1000 * c->mc_lifetime, best_cb, CHARSET_CHARS, 50, charmap, &c->randctx);
+ avpriv_init_elbg(meta, 32, 1000 * c->mc_lifetime, best_cb, CHARSET_CHARS, 50, charmap, &c->randctx);
+ avpriv_do_elbg (meta, 32, 1000 * c->mc_lifetime, best_cb, CHARSET_CHARS, 50, charmap, &c->randctx);
/* create colorram map and a c64 readable charset */
render_charset(avctx, charset, colram);
diff --git a/libavcodec/aac.h b/libavcodec/aac.h
index cda1477..89f463e 100644
--- a/libavcodec/aac.h
+++ b/libavcodec/aac.h
@@ -234,7 +234,7 @@
int sf_idx[128]; ///< scalefactor indices (used by encoder)
uint8_t zeroes[128]; ///< band is not coded (used by encoder)
DECLARE_ALIGNED(32, float, coeffs)[1024]; ///< coefficients for IMDCT
- DECLARE_ALIGNED(32, float, saved)[1024]; ///< overlap
+ DECLARE_ALIGNED(32, float, saved)[1536]; ///< overlap
DECLARE_ALIGNED(32, float, ret_buf)[2048]; ///< PCM output buffer
DECLARE_ALIGNED(16, float, ltp_state)[3072]; ///< time signal for LTP
PredictorState predictor_state[MAX_PREDICTORS];
diff --git a/libavcodec/aac_ac3_parser.c b/libavcodec/aac_ac3_parser.c
index 6f1e188..7fefda5 100644
--- a/libavcodec/aac_ac3_parser.c
+++ b/libavcodec/aac_ac3_parser.c
@@ -20,6 +20,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include "libavutil/channel_layout.h"
#include "libavutil/common.h"
#include "parser.h"
#include "aac_ac3_parser.h"
@@ -82,14 +83,23 @@
if (avctx->codec_id != AV_CODEC_ID_AAC) {
avctx->sample_rate = s->sample_rate;
- /* allow downmixing to stereo (or mono for AC-3) */
- if(avctx->request_channels > 0 &&
- avctx->request_channels < s->channels &&
- (avctx->request_channels <= 2 ||
- (avctx->request_channels == 1 &&
- (avctx->codec_id == AV_CODEC_ID_AC3 ||
- avctx->codec_id == AV_CODEC_ID_EAC3)))) {
- avctx->channels = avctx->request_channels;
+ /* (E-)AC-3: allow downmixing to stereo or mono */
+#if FF_API_REQUEST_CHANNELS
+FF_DISABLE_DEPRECATION_WARNINGS
+ if (avctx->request_channels == 1)
+ avctx->request_channel_layout = AV_CH_LAYOUT_MONO;
+ else if (avctx->request_channels == 2)
+ avctx->request_channel_layout = AV_CH_LAYOUT_STEREO;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+ if (s->channels > 1 &&
+ avctx->request_channel_layout == AV_CH_LAYOUT_MONO) {
+ avctx->channels = 1;
+ avctx->channel_layout = AV_CH_LAYOUT_MONO;
+ } else if (s->channels > 2 &&
+ avctx->request_channel_layout == AV_CH_LAYOUT_STEREO) {
+ avctx->channels = 2;
+ avctx->channel_layout = AV_CH_LAYOUT_STEREO;
} else {
avctx->channels = s->channels;
avctx->channel_layout = s->channel_layout;
diff --git a/libavcodec/aacdec.c b/libavcodec/aacdec.c
index 63a7fd1..1fb9185 100644
--- a/libavcodec/aacdec.c
+++ b/libavcodec/aacdec.c
@@ -2,6 +2,7 @@
* AAC decoder
* Copyright (c) 2005-2006 Oded Shimon ( ods15 ods15 dyndns org )
* Copyright (c) 2006-2007 Maxim Gavrilov ( maxim.gavrilov gmail com )
+ * Copyright (c) 2008-2013 Alex Converse <alex.converse@gmail.com>
*
* AAC LATM decoder
* Copyright (c) 2008-2010 Paul Kendall <paul@kcbbs.gen.nz>
@@ -73,6 +74,7 @@
* N SinuSoidal Coding (Transient, Sinusoid, Noise)
* Y Parametric Stereo
* N Direct Stream Transfer
+ * Y Enhanced AAC Low Delay (ER AAC ELD)
*
* Note: - HE AAC v1 comprises LC AAC with Spectral Band Replication.
* - HE AAC v2 comprises LC AAC with Spectral Band Replication and
@@ -103,6 +105,7 @@
#include <assert.h>
#include <errno.h>
#include <math.h>
+#include <stdint.h>
#include <string.h>
#if ARCH_ARM
@@ -793,9 +796,9 @@
case AOT_ER_AAC_LD:
res_flags = get_bits(gb, 3);
if (res_flags) {
- av_log(avctx, AV_LOG_ERROR,
- "AAC data resilience not supported (flags %x)\n",
- res_flags);
+ avpriv_report_missing_feature(avctx,
+ "AAC data resilience (flags %x)",
+ res_flags);
return AVERROR_PATCHWELCOME;
}
break;
@@ -809,15 +812,75 @@
case AOT_ER_AAC_LD:
ep_config = get_bits(gb, 2);
if (ep_config) {
- av_log(avctx, AV_LOG_ERROR,
- "epConfig %d is not supported.\n",
- ep_config);
+ avpriv_report_missing_feature(avctx,
+ "epConfig %d", ep_config);
return AVERROR_PATCHWELCOME;
}
}
return 0;
}
+static int decode_eld_specific_config(AACContext *ac, AVCodecContext *avctx,
+ GetBitContext *gb,
+ MPEG4AudioConfig *m4ac,
+ int channel_config)
+{
+ int ret, ep_config, res_flags;
+ uint8_t layout_map[MAX_ELEM_ID*4][3];
+ int tags = 0;
+ const int ELDEXT_TERM = 0;
+
+ m4ac->ps = 0;
+ m4ac->sbr = 0;
+
+ if (get_bits1(gb)) { // frameLengthFlag
+ avpriv_request_sample(avctx, "960/120 MDCT window");
+ return AVERROR_PATCHWELCOME;
+ }
+
+ res_flags = get_bits(gb, 3);
+ if (res_flags) {
+ avpriv_report_missing_feature(avctx,
+ "AAC data resilience (flags %x)",
+ res_flags);
+ return AVERROR_PATCHWELCOME;
+ }
+
+ if (get_bits1(gb)) { // ldSbrPresentFlag
+ avpriv_report_missing_feature(avctx,
+ "Low Delay SBR");
+ return AVERROR_PATCHWELCOME;
+ }
+
+ while (get_bits(gb, 4) != ELDEXT_TERM) {
+ int len = get_bits(gb, 4);
+ if (len == 15)
+ len += get_bits(gb, 8);
+ if (len == 15 + 255)
+ len += get_bits(gb, 16);
+ if (get_bits_left(gb) < len * 8 + 4) {
+ av_log(ac->avctx, AV_LOG_ERROR, overread_err);
+ return AVERROR_INVALIDDATA;
+ }
+ skip_bits_long(gb, 8 * len);
+ }
+
+ if ((ret = set_default_channel_config(avctx, layout_map,
+ &tags, channel_config)))
+ return ret;
+
+ if (ac && (ret = output_configure(ac, layout_map, tags, OC_GLOBAL_HDR, 0)))
+ return ret;
+
+ ep_config = get_bits(gb, 2);
+ if (ep_config) {
+ avpriv_report_missing_feature(avctx,
+ "epConfig %d", ep_config);
+ return AVERROR_PATCHWELCOME;
+ }
+ return 0;
+}
+
/**
* Decode audio specific configuration; reference: table 1.13.
*
@@ -876,11 +939,16 @@
m4ac, m4ac->chan_config)) < 0)
return ret;
break;
+ case AOT_ER_AAC_ELD:
+ if ((ret = decode_eld_specific_config(ac, avctx, &gb,
+ m4ac, m4ac->chan_config)) < 0)
+ return ret;
+ break;
default:
- av_log(avctx, AV_LOG_ERROR,
- "Audio object type %s%d is not supported.\n",
- m4ac->sbr == 1 ? "SBR+" : "",
- m4ac->object_type);
+ avpriv_report_missing_feature(avctx,
+ "Audio object type %s%d",
+ m4ac->sbr == 1 ? "SBR+" : "",
+ m4ac->object_type);
return AVERROR(ENOSYS);
}
@@ -1116,22 +1184,25 @@
static int decode_ics_info(AACContext *ac, IndividualChannelStream *ics,
GetBitContext *gb)
{
- if (get_bits1(gb)) {
- av_log(ac->avctx, AV_LOG_ERROR, "Reserved bit set.\n");
- return AVERROR_INVALIDDATA;
+ int aot = ac->oc[1].m4ac.object_type;
+ if (aot != AOT_ER_AAC_ELD) {
+ if (get_bits1(gb)) {
+ av_log(ac->avctx, AV_LOG_ERROR, "Reserved bit set.\n");
+ return AVERROR_INVALIDDATA;
+ }
+ ics->window_sequence[1] = ics->window_sequence[0];
+ ics->window_sequence[0] = get_bits(gb, 2);
+ if (aot == AOT_ER_AAC_LD &&
+ ics->window_sequence[0] != ONLY_LONG_SEQUENCE) {
+ av_log(ac->avctx, AV_LOG_ERROR,
+ "AAC LD is only defined for ONLY_LONG_SEQUENCE but "
+ "window sequence %d found.\n", ics->window_sequence[0]);
+ ics->window_sequence[0] = ONLY_LONG_SEQUENCE;
+ return AVERROR_INVALIDDATA;
+ }
+ ics->use_kb_window[1] = ics->use_kb_window[0];
+ ics->use_kb_window[0] = get_bits1(gb);
}
- ics->window_sequence[1] = ics->window_sequence[0];
- ics->window_sequence[0] = get_bits(gb, 2);
- if (ac->oc[1].m4ac.object_type == AOT_ER_AAC_LD &&
- ics->window_sequence[0] != ONLY_LONG_SEQUENCE) {
- av_log(ac->avctx, AV_LOG_ERROR,
- "AAC LD is only defined for ONLY_LONG_SEQUENCE but "
- "window sequence %d found.\n", ics->window_sequence[0]);
- ics->window_sequence[0] = ONLY_LONG_SEQUENCE;
- return AVERROR_INVALIDDATA;
- }
- ics->use_kb_window[1] = ics->use_kb_window[0];
- ics->use_kb_window[0] = get_bits1(gb);
ics->num_window_groups = 1;
ics->group_len[0] = 1;
if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
@@ -1153,7 +1224,7 @@
} else {
ics->max_sfb = get_bits(gb, 6);
ics->num_windows = 1;
- if (ac->oc[1].m4ac.object_type == AOT_ER_AAC_LD) {
+ if (aot == AOT_ER_AAC_LD || aot == AOT_ER_AAC_ELD) {
ics->swb_offset = ff_swb_offset_512[ac->oc[1].m4ac.sampling_index];
ics->num_swb = ff_aac_num_swb_512[ac->oc[1].m4ac.sampling_index];
if (!ics->num_swb || !ics->swb_offset)
@@ -1163,20 +1234,22 @@
ics->num_swb = ff_aac_num_swb_1024[ac->oc[1].m4ac.sampling_index];
}
ics->tns_max_bands = ff_tns_max_bands_1024[ac->oc[1].m4ac.sampling_index];
- ics->predictor_present = get_bits1(gb);
- ics->predictor_reset_group = 0;
+ if (aot != AOT_ER_AAC_ELD) {
+ ics->predictor_present = get_bits1(gb);
+ ics->predictor_reset_group = 0;
+ }
if (ics->predictor_present) {
- if (ac->oc[1].m4ac.object_type == AOT_AAC_MAIN) {
+ if (aot == AOT_AAC_MAIN) {
if (decode_prediction(ac, ics, gb)) {
goto fail;
}
- } else if (ac->oc[1].m4ac.object_type == AOT_AAC_LC ||
- ac->oc[1].m4ac.object_type == AOT_ER_AAC_LC) {
+ } else if (aot == AOT_AAC_LC ||
+ aot == AOT_ER_AAC_LC) {
av_log(ac->avctx, AV_LOG_ERROR,
"Prediction is not allowed in AAC-LC.\n");
goto fail;
} else {
- if (ac->oc[1].m4ac.object_type == AOT_ER_AAC_LD) {
+ if (aot == AOT_ER_AAC_LD) {
av_log(ac->avctx, AV_LOG_ERROR,
"LTP in ER AAC LD not yet implemented.\n");
return AVERROR_PATCHWELCOME;
@@ -1801,9 +1874,15 @@
TemporalNoiseShaping *tns = &sce->tns;
IndividualChannelStream *ics = &sce->ics;
float *out = sce->coeffs;
- int global_gain, er_syntax, pulse_present = 0;
+ int global_gain, eld_syntax, er_syntax, pulse_present = 0;
int ret;
+ eld_syntax = ac->oc[1].m4ac.object_type == AOT_ER_AAC_ELD;
+ er_syntax = ac->oc[1].m4ac.object_type == AOT_ER_AAC_LC ||
+ ac->oc[1].m4ac.object_type == AOT_ER_AAC_LTP ||
+ ac->oc[1].m4ac.object_type == AOT_ER_AAC_LD ||
+ ac->oc[1].m4ac.object_type == AOT_ER_AAC_ELD;
+
/* This assignment is to silence a GCC warning about the variable being used
* uninitialized when in fact it always is.
*/
@@ -1824,11 +1903,8 @@
return ret;
pulse_present = 0;
- er_syntax = ac->oc[1].m4ac.object_type == AOT_ER_AAC_LC ||
- ac->oc[1].m4ac.object_type == AOT_ER_AAC_LTP ||
- ac->oc[1].m4ac.object_type == AOT_ER_AAC_LD;
if (!scale_flag) {
- if ((pulse_present = get_bits1(gb))) {
+ if (!eld_syntax && (pulse_present = get_bits1(gb))) {
if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
av_log(ac->avctx, AV_LOG_ERROR,
"Pulse tool not allowed in eight short sequence.\n");
@@ -1844,7 +1920,7 @@
if (tns->present && !er_syntax)
if (decode_tns(ac, tns, gb, ics) < 0)
return AVERROR_INVALIDDATA;
- if (get_bits1(gb)) {
+ if (!eld_syntax && get_bits1(gb)) {
avpriv_request_sample(ac->avctx, "SSR");
return AVERROR_PATCHWELCOME;
}
@@ -1944,8 +2020,9 @@
static int decode_cpe(AACContext *ac, GetBitContext *gb, ChannelElement *cpe)
{
int i, ret, common_window, ms_present = 0;
+ int eld_syntax = ac->oc[1].m4ac.object_type == AOT_ER_AAC_ELD;
- common_window = get_bits1(gb);
+ common_window = eld_syntax || get_bits1(gb);
if (common_window) {
if (decode_ics_info(ac, &cpe->ch[0].ics, gb))
return AVERROR_INVALIDDATA;
@@ -2187,10 +2264,12 @@
} else if (ac->oc[1].m4ac.ps == -1 && ac->oc[1].status < OC_LOCKED && ac->avctx->channels == 1) {
ac->oc[1].m4ac.sbr = 1;
ac->oc[1].m4ac.ps = 1;
+ ac->avctx->profile = FF_PROFILE_AAC_HE_V2;
output_configure(ac, ac->oc[1].layout_map, ac->oc[1].layout_map_tags,
ac->oc[1].status, 1);
} else {
ac->oc[1].m4ac.sbr = 1;
+ ac->avctx->profile = FF_PROFILE_AAC_HE;
}
res = ff_decode_sbr_extension(ac, &che->sbr, gb, crc_flag, cnt, elem_type);
break;
@@ -2443,6 +2522,62 @@
memcpy(saved, buf + 256, 256 * sizeof(float));
}
+static void imdct_and_windowing_eld(AACContext *ac, SingleChannelElement *sce)
+{
+ float *in = sce->coeffs;
+ float *out = sce->ret;
+ float *saved = sce->saved;
+ const float *const window = ff_aac_eld_window;
+ float *buf = ac->buf_mdct;
+ int i;
+ const int n = 512;
+ const int n2 = n >> 1;
+ const int n4 = n >> 2;
+
+ // Inverse transform, mapped to the conventional IMDCT by
+ // Chivukula, R.K.; Reznik, Y.A.; Devarajan, V.,
+ // "Efficient algorithms for MPEG-4 AAC-ELD, AAC-LD and AAC-LC filterbanks,"
+ // International Conference on Audio, Language and Image Processing, ICALIP 2008.
+ // URL: http://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=4590245&isnumber=4589950
+ for (i = 0; i < n2; i+=2) {
+ float temp;
+ temp = in[i ]; in[i ] = -in[n - 1 - i]; in[n - 1 - i] = temp;
+ temp = -in[i + 1]; in[i + 1] = in[n - 2 - i]; in[n - 2 - i] = temp;
+ }
+ ac->mdct.imdct_half(&ac->mdct_ld, buf, in);
+ for (i = 0; i < n; i+=2) {
+ buf[i] = -buf[i];
+ }
+ // Like with the regular IMDCT at this point we still have the middle half
+ // of a transform but with even symmetry on the left and odd symmetry on
+ // the right
+
+ // window overlapping
+ // The spec says to use samples [0..511] but the reference decoder uses
+ // samples [128..639].
+ for (i = n4; i < n2; i ++) {
+ out[i - n4] = buf[n2 - 1 - i] * window[i - n4] +
+ saved[ i + n2] * window[i + n - n4] +
+ -saved[ n + n2 - 1 - i] * window[i + 2*n - n4] +
+ -saved[2*n + n2 + i] * window[i + 3*n - n4];
+ }
+ for (i = 0; i < n2; i ++) {
+ out[n4 + i] = buf[i] * window[i + n2 - n4] +
+ -saved[ n - 1 - i] * window[i + n2 + n - n4] +
+ -saved[ n + i] * window[i + n2 + 2*n - n4] +
+ saved[2*n + n - 1 - i] * window[i + n2 + 3*n - n4];
+ }
+ for (i = 0; i < n4; i ++) {
+ out[n2 + n4 + i] = buf[ i + n2] * window[i + n - n4] +
+ -saved[ n2 - 1 - i] * window[i + 2*n - n4] +
+ -saved[ n + n2 + i] * window[i + 3*n - n4];
+ }
+
+ // buffer update
+ memmove(saved + n, saved, 2 * n * sizeof(float));
+ memcpy( saved, buf, n * sizeof(float));
+}
+
/**
* Apply dependent channel coupling (applied before IMDCT).
*
@@ -2540,10 +2675,16 @@
{
int i, type;
void (*imdct_and_window)(AACContext *ac, SingleChannelElement *sce);
- if (ac->oc[1].m4ac.object_type == AOT_ER_AAC_LD)
+ switch (ac->oc[1].m4ac.object_type) {
+ case AOT_ER_AAC_LD:
imdct_and_window = imdct_and_windowing_ld;
- else
+ break;
+ case AOT_ER_AAC_ELD:
+ imdct_and_window = imdct_and_windowing_eld;
+ break;
+ default:
imdct_and_window = ac->imdct_and_windowing;
+ }
for (type = 3; type >= 0; type--) {
for (i = 0; i < MAX_ELEM_ID; i++) {
ChannelElement *che = ac->che[type][i];
@@ -2653,8 +2794,9 @@
int err, i;
int samples = 1024;
int chan_config = ac->oc[1].m4ac.chan_config;
+ int aot = ac->oc[1].m4ac.object_type;
- if (ac->oc[1].m4ac.object_type == AOT_ER_AAC_LD)
+ if (aot == AOT_ER_AAC_LD || aot == AOT_ER_AAC_ELD)
samples >>= 1;
ac->frame = data;
@@ -2662,6 +2804,10 @@
if ((err = frame_configure_elements(avctx)) < 0)
return err;
+ // The FF_PROFILE_AAC_* defines are all object_type - 1
+ // This may lead to an undefined profile being signaled
+ ac->avctx->profile = ac->oc[1].m4ac.object_type - 1;
+
ac->tags_mapped = 0;
if (chan_config < 0 || chan_config >= 8) {
@@ -2678,7 +2824,8 @@
elem_type, elem_id);
return AVERROR_INVALIDDATA;
}
- skip_bits(gb, 4);
+ if (aot != AOT_ER_AAC_ELD)
+ skip_bits(gb, 4);
switch (elem_type) {
case TYPE_SCE:
err = decode_ics(ac, &che->ch[0], gb, 0, 0);
@@ -2730,6 +2877,10 @@
if ((err = frame_configure_elements(avctx)) < 0)
goto fail;
+ // The FF_PROFILE_AAC_* defines are all object_type - 1
+ // This may lead to an undefined profile being signaled
+ ac->avctx->profile = ac->oc[1].m4ac.object_type - 1;
+
ac->tags_mapped = 0;
// parse
while ((elem_type = get_bits(gb, 3)) != TYPE_END) {
@@ -2914,6 +3065,7 @@
case AOT_ER_AAC_LC:
case AOT_ER_AAC_LTP:
case AOT_ER_AAC_LD:
+ case AOT_ER_AAC_ELD:
err = aac_decode_er_frame(avctx, data, got_frame_ptr, &gb);
break;
default:
diff --git a/libavcodec/aacps.c b/libavcodec/aacps.c
index 9abc296..9b7bdae 100644
--- a/libavcodec/aacps.c
+++ b/libavcodec/aacps.c
@@ -322,14 +322,15 @@
}
/** Split one subband into 6 subsubbands with a complex filter */
-static void hybrid6_cx(PSDSPContext *dsp, float (*in)[2], float (*out)[32][2], const float (*filter)[8][2], int len)
+static void hybrid6_cx(PSDSPContext *dsp, float (*in)[2], float (*out)[32][2],
+ TABLE_CONST float (*filter)[8][2], int len)
{
int i;
int N = 8;
LOCAL_ALIGNED_16(float, temp, [8], [2]);
for (i = 0; i < len; i++, in++) {
- dsp->hybrid_analysis(temp, in, filter, 1, N);
+ dsp->hybrid_analysis(temp, in, (const float (*)[8][2]) filter, 1, N);
out[0][i][0] = temp[6][0];
out[0][i][1] = temp[6][1];
out[1][i][0] = temp[7][0];
@@ -345,12 +346,14 @@
}
}
-static void hybrid4_8_12_cx(PSDSPContext *dsp, float (*in)[2], float (*out)[32][2], const float (*filter)[8][2], int N, int len)
+static void hybrid4_8_12_cx(PSDSPContext *dsp,
+ float (*in)[2], float (*out)[32][2],
+ TABLE_CONST float (*filter)[8][2], int N, int len)
{
int i;
for (i = 0; i < len; i++, in++) {
- dsp->hybrid_analysis(out[0] + i, in, filter, 32, N);
+ dsp->hybrid_analysis(out[0] + i, in, (const float (*)[8][2]) filter, 32, N);
}
}
@@ -685,7 +688,8 @@
memcpy(ap_delay[k][m], ap_delay[k][m]+numQMFSlots, 5*sizeof(ap_delay[k][m][0]));
}
ps->dsp.decorrelate(out[k], delay[k] + PS_MAX_DELAY - 2, ap_delay[k],
- phi_fract[is34][k], Q_fract_allpass[is34][k],
+ phi_fract[is34][k],
+ (const float (*)[2]) Q_fract_allpass[is34][k],
transient_gain[b], g_decay_slope, nL - n0);
}
for (; k < SHORT_DELAY_BAND[is34]; k++) {
@@ -763,7 +767,7 @@
int8_t (*ipd_mapped)[PS_MAX_NR_IIDICC] = ipd_mapped_buf;
int8_t (*opd_mapped)[PS_MAX_NR_IIDICC] = opd_mapped_buf;
const int8_t *k_to_i = is34 ? k_to_i_34 : k_to_i_20;
- const float (*H_LUT)[8][4] = (PS_BASELINE || ps->icc_mode < 3) ? HA : HB;
+ TABLE_CONST float (*H_LUT)[8][4] = (PS_BASELINE || ps->icc_mode < 3) ? HA : HB;
//Remapping
if (ps->num_env_old) {
@@ -914,7 +918,7 @@
memset(ps->ap_delay + top, 0, (NR_ALLPASS_BANDS[is34] - top)*sizeof(ps->ap_delay[0]));
hybrid_analysis(&ps->dsp, Lbuf, ps->in_buf, L, is34, len);
- decorrelation(ps, Rbuf, Lbuf, is34);
+ decorrelation(ps, Rbuf, (const float (*)[32][2]) Lbuf, is34);
stereo_processing(ps, Lbuf, Rbuf, is34);
hybrid_synthesis(&ps->dsp, L, Lbuf, is34, len);
hybrid_synthesis(&ps->dsp, R, Rbuf, is34, len);
diff --git a/libavcodec/aacps_tablegen.c b/libavcodec/aacps_tablegen.c
index f56930b..47d4205 100644
--- a/libavcodec/aacps_tablegen.c
+++ b/libavcodec/aacps_tablegen.c
@@ -82,7 +82,7 @@
write_float_3d_array(f34_2_4, 4, 8, 2);
printf("};\n");
- printf("static const DECLARE_ALIGNED(16, float, Q_fract_allpass)[2][50][3][2] = {\n");
+ printf("static TABLE_CONST DECLARE_ALIGNED(16, float, Q_fract_allpass)[2][50][3][2] = {\n");
write_float_4d_array(Q_fract_allpass, 2, 50, 3, 2);
printf("};\n");
printf("static const DECLARE_ALIGNED(16, float, phi_fract)[2][50][2] = {\n");
diff --git a/libavcodec/aacps_tablegen.h b/libavcodec/aacps_tablegen.h
index 05a2af6..9df38ff 100644
--- a/libavcodec/aacps_tablegen.h
+++ b/libavcodec/aacps_tablegen.h
@@ -28,6 +28,7 @@
#if CONFIG_HARDCODED_TABLES
#define ps_tableinit()
+#define TABLE_CONST const
#include "libavcodec/aacps_tables.h"
#else
#include "libavutil/common.h"
@@ -37,6 +38,7 @@
#define NR_ALLPASS_BANDS20 30
#define NR_ALLPASS_BANDS34 50
#define PS_AP_LINKS 3
+#define TABLE_CONST
static float pd_re_smooth[8*8*8];
static float pd_im_smooth[8*8*8];
static float HA[46][8][4];
@@ -45,7 +47,7 @@
static DECLARE_ALIGNED(16, float, f34_0_12)[12][8][2];
static DECLARE_ALIGNED(16, float, f34_1_8) [ 8][8][2];
static DECLARE_ALIGNED(16, float, f34_2_4) [ 4][8][2];
-static DECLARE_ALIGNED(16, float, Q_fract_allpass)[2][50][3][2];
+static TABLE_CONST DECLARE_ALIGNED(16, float, Q_fract_allpass)[2][50][3][2];
static DECLARE_ALIGNED(16, float, phi_fract)[2][50][2];
static const float g0_Q8[] = {
diff --git a/libavcodec/aacpsdsp.c b/libavcodec/aacpsdsp.c
index 9f628441..5dc1a6a 100644
--- a/libavcodec/aacpsdsp.c
+++ b/libavcodec/aacpsdsp.c
@@ -93,7 +93,7 @@
static void ps_decorrelate_c(float (*out)[2], float (*delay)[2],
float (*ap_delay)[PS_QMF_TIME_SLOTS + PS_MAX_AP_DELAY][2],
- const float phi_fract[2], float (*Q_fract)[2],
+ const float phi_fract[2], const float (*Q_fract)[2],
const float *transient_gain,
float g_decay_slope,
int len)
diff --git a/libavcodec/aacpsdsp.h b/libavcodec/aacpsdsp.h
index 74a8af6..0ef3023 100644
--- a/libavcodec/aacpsdsp.h
+++ b/libavcodec/aacpsdsp.h
@@ -38,7 +38,7 @@
int i, int len);
void (*decorrelate)(float (*out)[2], float (*delay)[2],
float (*ap_delay)[PS_QMF_TIME_SLOTS+PS_MAX_AP_DELAY][2],
- const float phi_fract[2], float (*Q_fract)[2],
+ const float phi_fract[2], const float (*Q_fract)[2],
const float *transient_gain,
float g_decay_slope,
int len);
diff --git a/libavcodec/aacsbr.c b/libavcodec/aacsbr.c
index 0b6779c..290fb81 100644
--- a/libavcodec/aacsbr.c
+++ b/libavcodec/aacsbr.c
@@ -932,6 +932,7 @@
} else {
#if 1
*num_bits_left -= ff_ps_read_data(ac->avctx, gb, &sbr->ps, *num_bits_left);
+ ac->avctx->profile = FF_PROFILE_AAC_HE_V2;
#else
avpriv_report_missing_feature(ac->avctx, "Parametric Stereo");
skip_bits_long(gb, *num_bits_left); // bs_fill_bits
@@ -1701,12 +1702,18 @@
sbr_qmf_analysis(&ac->fdsp, &sbr->mdct_ana, &sbr->dsp, ch ? R : L, sbr->data[ch].analysis_filterbank_samples,
(float*)sbr->qmf_filter_scratch,
sbr->data[ch].W, sbr->data[ch].Ypos);
- sbr->c.sbr_lf_gen(ac, sbr, sbr->X_low, sbr->data[ch].W, sbr->data[ch].Ypos);
+ sbr->c.sbr_lf_gen(ac, sbr, sbr->X_low,
+ (const float (*)[32][32][2]) sbr->data[ch].W,
+ sbr->data[ch].Ypos);
sbr->data[ch].Ypos ^= 1;
if (sbr->start) {
- sbr->c.sbr_hf_inverse_filter(&sbr->dsp, sbr->alpha0, sbr->alpha1, sbr->X_low, sbr->k[0]);
+ sbr->c.sbr_hf_inverse_filter(&sbr->dsp, sbr->alpha0, sbr->alpha1,
+ (const float (*)[40][2]) sbr->X_low, sbr->k[0]);
sbr_chirp(sbr, &sbr->data[ch]);
- sbr_hf_gen(ac, sbr, sbr->X_high, sbr->X_low, sbr->alpha0, sbr->alpha1,
+ sbr_hf_gen(ac, sbr, sbr->X_high,
+ (const float (*)[40][2]) sbr->X_low,
+ (const float (*)[2]) sbr->alpha0,
+ (const float (*)[2]) sbr->alpha1,
sbr->data[ch].bw_array, sbr->data[ch].t_env,
sbr->data[ch].bs_num_env);
@@ -1716,16 +1723,17 @@
sbr_env_estimate(sbr->e_curr, sbr->X_high, sbr, &sbr->data[ch]);
sbr_gain_calc(ac, sbr, &sbr->data[ch], sbr->data[ch].e_a);
sbr->c.sbr_hf_assemble(sbr->data[ch].Y[sbr->data[ch].Ypos],
- sbr->X_high, sbr, &sbr->data[ch],
+ (const float (*)[40][2]) sbr->X_high,
+ sbr, &sbr->data[ch],
sbr->data[ch].e_a);
}
}
/* synthesis */
sbr->c.sbr_x_gen(sbr, sbr->X[ch],
- sbr->data[ch].Y[1-sbr->data[ch].Ypos],
- sbr->data[ch].Y[ sbr->data[ch].Ypos],
- sbr->X_low, ch);
+ (const float (*)[64][2]) sbr->data[ch].Y[1-sbr->data[ch].Ypos],
+ (const float (*)[64][2]) sbr->data[ch].Y[ sbr->data[ch].Ypos],
+ (const float (*)[40][2]) sbr->X_low, ch);
}
if (ac->oc[1].m4ac.ps == 1) {
diff --git a/libavcodec/aactab.c b/libavcodec/aactab.c
index 08c44e5..7ec8374 100644
--- a/libavcodec/aactab.c
+++ b/libavcodec/aactab.c
@@ -1241,3 +1241,486 @@
9, 9, 10, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14
};
// @}
+
+const DECLARE_ALIGNED(32, float, ff_aac_eld_window)[1920] = {
+ 0.00338834, 0.00567745, 0.00847677, 0.01172641,
+ 0.01532555, 0.01917664, 0.02318809, 0.02729259,
+ 0.03144503, 0.03560261, 0.03972499, 0.04379783,
+ 0.04783094, 0.05183357, 0.05581342, 0.05977723,
+ 0.06373173, 0.06768364, 0.07163937, 0.07559976,
+ 0.07956096, 0.08352024, 0.08747623, 0.09143035,
+ 0.09538618, 0.09934771, 0.10331917, 0.10730456,
+ 0.11130697, 0.11532867, 0.11937133, 0.12343922,
+ 0.12753911, 0.13167705, 0.13585812, 0.14008529,
+ 0.14435986, 0.14868291, 0.15305531, 0.15747594,
+ 0.16194193, 0.16645070, 0.17099991, 0.17558633,
+ 0.18020600, 0.18485548, 0.18953191, 0.19423322,
+ 0.19895800, 0.20370512, 0.20847374, 0.21326312,
+ 0.21807244, 0.22290083, 0.22774742, 0.23261210,
+ 0.23749542, 0.24239767, 0.24731889, 0.25225887,
+ 0.25721719, 0.26219330, 0.26718648, 0.27219630,
+ 0.27722262, 0.28226514, 0.28732336, 0.29239628,
+ 0.29748247, 0.30258055, 0.30768914, 0.31280508,
+ 0.31792385, 0.32304172, 0.32815579, 0.33326397,
+ 0.33836470, 0.34345661, 0.34853868, 0.35361188,
+ 0.35867865, 0.36374072, 0.36879900, 0.37385347,
+ 0.37890349, 0.38394836, 0.38898730, 0.39401912,
+ 0.39904236, 0.40405575, 0.40905820, 0.41404819,
+ 0.41902398, 0.42398423, 0.42892805, 0.43385441,
+ 0.43876210, 0.44365014, 0.44851786, 0.45336632,
+ 0.45819759, 0.46301302, 0.46781309, 0.47259722,
+ 0.47736435, 0.48211365, 0.48684450, 0.49155594,
+ 0.49624679, 0.50091636, 0.50556440, 0.51019132,
+ 0.51479771, 0.51938391, 0.52394998, 0.52849587,
+ 0.53302151, 0.53752680, 0.54201160, 0.54647575,
+ 0.55091916, 0.55534181, 0.55974376, 0.56412513,
+ 0.56848615, 0.57282710, 0.57714834, 0.58145030,
+ 0.58492489, 0.58918511, 0.59342326, 0.59763936,
+ 0.60183347, 0.60600561, 0.61015581, 0.61428412,
+ 0.61839056, 0.62247517, 0.62653799, 0.63057912,
+ 0.63459872, 0.63859697, 0.64257403, 0.64653001,
+ 0.65046495, 0.65437887, 0.65827181, 0.66214383,
+ 0.66599499, 0.66982535, 0.67363499, 0.67742394,
+ 0.68119219, 0.68493972, 0.68866653, 0.69237258,
+ 0.69605778, 0.69972207, 0.70336537, 0.70698758,
+ 0.71058862, 0.71416837, 0.71772674, 0.72126361,
+ 0.72477889, 0.72827246, 0.73174419, 0.73519392,
+ 0.73862141, 0.74202643, 0.74540874, 0.74876817,
+ 0.75210458, 0.75541785, 0.75870785, 0.76197437,
+ 0.76521709, 0.76843570, 0.77162988, 0.77479939,
+ 0.77794403, 0.78106359, 0.78415789, 0.78722670,
+ 0.79026979, 0.79328694, 0.79627791, 0.79924244,
+ 0.80218027, 0.80509112, 0.80797472, 0.81083081,
+ 0.81365915, 0.81645949, 0.81923160, 0.82197528,
+ 0.82469037, 0.82737673, 0.83003419, 0.83266262,
+ 0.83526186, 0.83783176, 0.84037217, 0.84288297,
+ 0.84536401, 0.84781517, 0.85023632, 0.85262739,
+ 0.85498836, 0.85731921, 0.85961993, 0.86189052,
+ 0.86413101, 0.86634140, 0.86852173, 0.87067211,
+ 0.87279275, 0.87488384, 0.87694559, 0.87897824,
+ 0.88098206, 0.88295729, 0.88490423, 0.88682332,
+ 0.88871519, 0.89058048, 0.89241983, 0.89423391,
+ 0.89602338, 0.89778893, 0.89953126, 0.90125142,
+ 0.90295086, 0.90463104, 0.90629341, 0.90793946,
+ 0.90957067, 0.91118856, 0.91279464, 0.91439073,
+ 0.91597898, 0.91756153, 0.91914049, 0.92071690,
+ 0.92229070, 0.92386182, 0.92542993, 0.92698946,
+ 0.92852960, 0.93003929, 0.93150727, 0.93291739,
+ 0.93424863, 0.93547974, 0.93658982, 0.93756587,
+ 0.93894072, 0.93922780, 0.93955477, 0.93991290,
+ 0.94029104, 0.94067794, 0.94106258, 0.94144084,
+ 0.94181549, 0.94218963, 0.94256628, 0.94294662,
+ 0.94332998, 0.94371562, 0.94410280, 0.94449122,
+ 0.94488106, 0.94527249, 0.94566568, 0.94606074,
+ 0.94645772, 0.94685665, 0.94725759, 0.94766054,
+ 0.94806547, 0.94847234, 0.94888115, 0.94929190,
+ 0.94970469, 0.95011960, 0.95053672, 0.95095604,
+ 0.95137751, 0.95180105, 0.95222658, 0.95265413,
+ 0.95308380, 0.95351571, 0.95394994, 0.95438653,
+ 0.95482538, 0.95526643, 0.95570958, 0.95615486,
+ 0.95660234, 0.95705214, 0.95750433, 0.95795892,
+ 0.95841582, 0.95887493, 0.95933616, 0.95979949,
+ 0.96026500, 0.96073277, 0.96120286, 0.96167526,
+ 0.96214986, 0.96262655, 0.96310522, 0.96358586,
+ 0.96406853, 0.96455330, 0.96504026, 0.96552936,
+ 0.96602051, 0.96651360, 0.96700850, 0.96750520,
+ 0.96800376, 0.96850424, 0.96900670, 0.96951112,
+ 0.97001738, 0.97052533, 0.97103488, 0.97154597,
+ 0.97205867, 0.97257304, 0.97308915, 0.97360694,
+ 0.97412631, 0.97464711, 0.97516923, 0.97569262,
+ 0.97621735, 0.97674350, 0.97727111, 0.97780016,
+ 0.97833051, 0.97886205, 0.97939463, 0.97992823,
+ 0.98046291, 0.98099875, 0.98153580, 0.98207405,
+ 0.98261337, 0.98315364, 0.98369474, 0.98423664,
+ 0.98477941, 0.98532311, 0.98586780, 0.98641348,
+ 0.98696003, 0.98750734, 0.98805530, 0.98860389,
+ 0.98915320, 0.98970328, 0.99025423, 0.99080602,
+ 0.99135855, 0.99191171, 0.99246541, 0.99301962,
+ 0.99357443, 0.99412992, 0.99468617, 0.99524320,
+ 0.99580092, 0.99635926, 0.99691814, 0.99747748,
+ 0.99803721, 0.99859725, 0.99915752, 0.99971793,
+ 1.00028215, 1.00084319, 1.00140472, 1.00196665,
+ 1.00252889, 1.00309139, 1.00365404, 1.00421679,
+ 1.00477954, 1.00534221, 1.00590474, 1.00646713,
+ 1.00702945, 1.00759179, 1.00815424, 1.00871678,
+ 1.00927930, 1.00984169, 1.01040384, 1.01096575,
+ 1.01152747, 1.01208910, 1.01265070, 1.01321226,
+ 1.01377365, 1.01433478, 1.01489551, 1.01545584,
+ 1.01601582, 1.01657553, 1.01713502, 1.01769427,
+ 1.01825316, 1.01881154, 1.01936929, 1.01992639,
+ 1.02048289, 1.02103888, 1.02159441, 1.02214945,
+ 1.02270387, 1.02325751, 1.02381025, 1.02436204,
+ 1.02491295, 1.02546304, 1.02601238, 1.02656092,
+ 1.02710853, 1.02765508, 1.02820041, 1.02874449,
+ 1.02928737, 1.02982913, 1.03036981, 1.03090937,
+ 1.03144768, 1.03198460, 1.03252000, 1.03305384,
+ 1.03358617, 1.03411707, 1.03464659, 1.03517470,
+ 1.03570128, 1.03622620, 1.03674934, 1.03727066,
+ 1.03779024, 1.03830815, 1.03882446, 1.03933914,
+ 1.03985206, 1.04036312, 1.04087217, 1.04137920,
+ 1.04188428, 1.04238748, 1.04288888, 1.04338845,
+ 1.04388610, 1.04438170, 1.04487515, 1.04536645,
+ 1.04585569, 1.04634297, 1.04682838, 1.04731192,
+ 1.04779350, 1.04827303, 1.04875042, 1.04922568,
+ 1.04969891, 1.05017022, 1.05063974, 1.05110746,
+ 1.05157332, 1.05203721, 1.05249907, 1.05295889,
+ 1.05341676, 1.05387277, 1.05432700, 1.05477948,
+ 1.05523018, 1.05567906, 1.05612608, 1.05657124,
+ 1.05701459, 1.05745616, 1.05789601, 1.05833426,
+ 1.05877109, 1.05920669, 1.05964125, 1.06007444,
+ 1.06050542, 1.06093335, 1.06135746, 1.06177909,
+ 1.06220164, 1.06262858, 1.06306309, 1.06350050,
+ 1.06392837, 1.06433391, 1.06470443, 1.06502996,
+ 1.06481076, 1.06469765, 1.06445004, 1.06408002,
+ 1.06361382, 1.06307719, 1.06249453, 1.06188365,
+ 1.06125612, 1.06062291, 1.05999418, 1.05937132,
+ 1.05874726, 1.05811486, 1.05746728, 1.05680000,
+ 1.05611070, 1.05539715, 1.05465735, 1.05389329,
+ 1.05311083, 1.05231578, 1.05151372, 1.05070811,
+ 1.04990044, 1.04909210, 1.04828434, 1.04747647,
+ 1.04666590, 1.04585003, 1.04502628, 1.04419009,
+ 1.04333499, 1.04245452, 1.04154244, 1.04059452,
+ 1.03960846, 1.03858207, 1.03751326, 1.03640189,
+ 1.03524976, 1.03405868, 1.03283047, 1.03156812,
+ 1.03027574, 1.02895743, 1.02761717, 1.02625804,
+ 1.02488222, 1.02349184, 1.02208892, 1.02067450,
+ 1.01924861, 1.01781123, 1.01636229, 1.01490045,
+ 1.01342315, 1.01192778, 1.01041175, 1.00887284,
+ 1.00730915, 1.00571882, 1.00409996, 1.00245032,
+ 1.00076734, 0.99904842, 0.99729101, 0.99549380,
+ 0.99365664, 0.99177946, 0.98986234, 0.98791024,
+ 0.98593294, 0.98394037, 0.98194226, 0.97994532,
+ 0.97795324, 0.97596955, 0.97399748, 0.97203326,
+ 0.97006624, 0.96808546, 0.96608018, 0.96404416,
+ 0.96197556, 0.95987276, 0.95773420, 0.95556018,
+ 0.95335291, 0.95111462, 0.94884764, 0.94655663,
+ 0.94424858, 0.94193055, 0.93960953, 0.93729154,
+ 0.93498157, 0.93268456, 0.93040503, 0.92813771,
+ 0.92586755, 0.92357910, 0.92125731, 0.91889642,
+ 0.91649998, 0.91407191, 0.91161623, 0.90913975,
+ 0.90665202, 0.90416271, 0.90168115, 0.89920934,
+ 0.89674189, 0.89427312, 0.89179743, 0.88931147,
+ 0.88681415, 0.88430445, 0.88178141, 0.87924528,
+ 0.87669753, 0.87413966, 0.87157318, 0.86899958,
+ 0.86642037, 0.86383703, 0.86125106, 0.85866393,
+ 0.85604236, 0.85344385, 0.85083093, 0.84820550,
+ 0.84556943, 0.84292458, 0.84027278, 0.83761586,
+ 0.83495565, 0.83229393, 0.82963243, 0.82697135,
+ 0.82430933, 0.82164496, 0.81897669, 0.81630017,
+ 0.81360822, 0.81089355, 0.80814924, 0.80537741,
+ 0.80258920, 0.79979611, 0.79700954, 0.79423813,
+ 0.79148780, 0.78876432, 0.78607290, 0.78340590,
+ 0.78074288, 0.77806279, 0.77534514, 0.77258187,
+ 0.76977737, 0.76693654, 0.76406441, 0.76116851,
+ 0.75825892, 0.75534582, 0.75243924, 0.74954634,
+ 0.74667135, 0.74381840, 0.74099145, 0.73819147,
+ 0.73541641, 0.73266408, 0.72993193, 0.72720913,
+ 0.72447661, 0.72171494, 0.71890515, 0.71603932,
+ 0.71312056, 0.71015250, 0.70713900, 0.70409084,
+ 0.70102565, 0.69796137, 0.69491556, 0.69189772,
+ 0.68890931, 0.68595141, 0.68302498, 0.68012852,
+ 0.67725801, 0.67440936, 0.67157841, 0.66876081,
+ 0.66595195, 0.66314722, 0.66034194, 0.65753027,
+ 0.65470525, 0.65185984, 0.64898709, 0.64608214,
+ 0.64314221, 0.64016460, 0.63714680, 0.63409034,
+ 0.63100082, 0.62788400, 0.62474577, 0.62159473,
+ 0.61844225, 0.61529977, 0.61217866, 0.60908811,
+ 0.60603510, 0.60302654, 0.60006916, 0.59716588,
+ 0.59431580, 0.59151787, 0.58877068, 0.58606495,
+ 0.58338353, 0.58070891, 0.57802356, 0.57530864,
+ 0.57254404, 0.56970958, 0.56678577, 0.56376860,
+ 0.56066951, 0.55750064, 0.55427451, 0.55101301,
+ 0.54774732, 0.54450907, 0.54132936, 0.53822744,
+ 0.53521072, 0.53228613, 0.52945979, 0.52671997,
+ 0.52403708, 0.52138072, 0.51872085, 0.51603570,
+ 0.51331170, 0.51053560, 0.50769466, 0.50478931,
+ 0.50183308, 0.49884001, 0.49582406, 0.49279905,
+ 0.48985748, 0.48679641, 0.48379429, 0.48085363,
+ 0.47796576, 0.47512151, 0.47231151, 0.46952402,
+ 0.46674486, 0.46395978, 0.46115496, 0.45832607,
+ 0.45547830, 0.45261727, 0.44974866, 0.44688011,
+ 0.44402125, 0.44118178, 0.43837094, 0.43558772,
+ 0.43282082, 0.43005847, 0.42728913, 0.42450572,
+ 0.42170567, 0.41888658, 0.41604633, 0.41318897,
+ 0.41032472, 0.40746405, 0.40461724, 0.40178943,
+ 0.39898066, 0.39619073, 0.39341940, 0.39066519,
+ 0.38792536, 0.38519713, 0.38247773, 0.37976476,
+ 0.37705620, 0.37435006, 0.37164438, 0.36893869,
+ 0.36623396, 0.36353124, 0.36083153, 0.35813533,
+ 0.35544262, 0.35275338, 0.35006755, 0.34738530,
+ 0.34470699, 0.34203296, 0.33936359, 0.33669922,
+ 0.33404027, 0.33138711, 0.32874013, 0.32609944,
+ 0.32346493, 0.32083645, 0.31821388, 0.31559703,
+ 0.31298573, 0.31037987, 0.30777941, 0.30518446,
+ 0.30259525, 0.30001202, 0.29743499, 0.29486428,
+ 0.29229989, 0.28974179, 0.28718997, 0.28464452,
+ 0.28210562, 0.27957346, 0.27704820, 0.27452992,
+ 0.27201854, 0.26951399, 0.26701622, 0.26452533,
+ 0.26204158, 0.25956526, 0.25709662, 0.25463583,
+ 0.25218294, 0.24973798, 0.24730100, 0.24487207,
+ 0.24245133, 0.24003893, 0.23763500, 0.23523959,
+ 0.23285262, 0.23047401, 0.22810369, 0.22574170,
+ 0.22338818, 0.22104329, 0.21870719, 0.21637986,
+ 0.21406117, 0.21175095, 0.20944904, 0.20715535,
+ 0.20486987, 0.20259261, 0.20032356, 0.19806259,
+ 0.19580944, 0.19356385, 0.19132556, 0.18909442,
+ 0.18687040, 0.18465350, 0.18244372, 0.18024164,
+ 0.17804841, 0.17586521, 0.17369322, 0.17153360,
+ 0.16938755, 0.16725622, 0.16514081, 0.16304247,
+ 0.16098974, 0.15896561, 0.15696026, 0.15497259,
+ 0.15300151, 0.15104590, 0.14910466, 0.14717666,
+ 0.14526081, 0.14335599, 0.14146111, 0.13957570,
+ 0.13769993, 0.13583399, 0.13397806, 0.13213229,
+ 0.13029682, 0.12847178, 0.12665729, 0.12485353,
+ 0.12306074, 0.12127916, 0.11950900, 0.11775043,
+ 0.11600347, 0.11426820, 0.11254464, 0.11083292,
+ 0.10913318, 0.10744559, 0.10577028, 0.10410733,
+ 0.10245672, 0.10081842, 0.09919240, 0.09757872,
+ 0.09597750, 0.09438884, 0.09281288, 0.09124964,
+ 0.08969907, 0.08816111, 0.08663570, 0.08512288,
+ 0.08362274, 0.08213540, 0.08066096, 0.07919944,
+ 0.07775076, 0.07631484, 0.07489161, 0.07348108,
+ 0.07208335, 0.07069851, 0.06932666, 0.06796781,
+ 0.06662187, 0.06528874, 0.06396833, 0.06266065,
+ 0.06136578, 0.06008380, 0.05881480, 0.05755876,
+ 0.05631557, 0.05508511, 0.05386728, 0.05266206,
+ 0.05146951, 0.05028971, 0.04912272, 0.04796855,
+ 0.04682709, 0.04569825, 0.04458194, 0.04347817,
+ 0.04238704, 0.04130868, 0.04024318, 0.03919056,
+ 0.03815071, 0.03712352, 0.03610890, 0.03510679,
+ 0.03411720, 0.03314013, 0.03217560, 0.03122343,
+ 0.03028332, 0.02935494, 0.02843799, 0.02753230,
+ 0.02663788, 0.02575472, 0.02488283, 0.02402232,
+ 0.02317341, 0.02233631, 0.02151124, 0.02069866,
+ 0.01989922, 0.01911359, 0.01834241, 0.01758563,
+ 0.01684248, 0.01611219, 0.01539397, 0.01468726,
+ 0.01399167, 0.01330687, 0.01263250, 0.01196871,
+ 0.01131609, 0.01067527, 0.01004684, 0.00943077,
+ 0.00882641, 0.00823307, 0.00765011, 0.00707735,
+ 0.00651513, 0.00596377, 0.00542364, 0.00489514,
+ 0.00437884, 0.00387530, 0.00338509, 0.00290795,
+ 0.00244282, 0.00198860, 0.00154417, 0.00110825,
+ 0.00067934, 0.00025589, -0.00016357, -0.00057897,
+ -0.00098865, -0.00139089, -0.00178397, -0.00216547,
+ -0.00253230, -0.00288133, -0.00320955, -0.00351626,
+ -0.00380315, -0.00407198, -0.00432457, -0.00456373,
+ -0.00479326, -0.00501699, -0.00523871, -0.00546066,
+ -0.00568360, -0.00590821, -0.00613508, -0.00636311,
+ -0.00658944, -0.00681117, -0.00702540, -0.00722982,
+ -0.00742268, -0.00760226, -0.00776687, -0.00791580,
+ -0.00804933, -0.00816774, -0.00827139, -0.00836122,
+ -0.00843882, -0.00850583, -0.00856383, -0.00861430,
+ -0.00865853, -0.00869781, -0.00873344, -0.00876633,
+ -0.00879707, -0.00882622, -0.00885433, -0.00888132,
+ -0.00890652, -0.00892925, -0.00894881, -0.00896446,
+ -0.00897541, -0.00898088, -0.00898010, -0.00897234,
+ -0.00895696, -0.00893330, -0.00890076, -0.00885914,
+ -0.00880875, -0.00874987, -0.00868282, -0.00860825,
+ -0.00852716, -0.00844055, -0.00834941, -0.00825485,
+ -0.00815807, -0.00806025, -0.00796253, -0.00786519,
+ -0.00776767, -0.00766937, -0.00756971, -0.00746790,
+ -0.00736305, -0.00725422, -0.00714055, -0.00702161,
+ -0.00689746, -0.00676816, -0.00663381, -0.00649489,
+ -0.00635230, -0.00620694, -0.00605969, -0.00591116,
+ -0.00576167, -0.00561155, -0.00546110, -0.00531037,
+ -0.00515917, -0.00500732, -0.00485462, -0.00470075,
+ -0.00454530, -0.00438786, -0.00422805, -0.00406594,
+ -0.00390204, -0.00373686, -0.00357091, -0.00340448,
+ -0.00323770, -0.00307066, -0.00290344, -0.00273610,
+ -0.00256867, -0.00240117, -0.00223365, -0.00206614,
+ -0.00189866, -0.00173123, -0.00156390, -0.00139674,
+ -0.00122989, -0.00106351, -0.00089772, -0.00073267,
+ -0.00056849, -0.00040530, -0.00024324, -0.00008241,
+ 0.00008214, 0.00024102, 0.00039922, 0.00055660,
+ 0.00071299, 0.00086826, 0.00102224, 0.00117480,
+ 0.00132579, 0.00147507, 0.00162252, 0.00176804,
+ 0.00191161, 0.00205319, 0.00219277, 0.00233029,
+ 0.00246567, 0.00259886, 0.00272975, 0.00285832,
+ 0.00298453, 0.00310839, 0.00322990, 0.00334886,
+ 0.00346494, 0.00357778, 0.00368706, 0.00379273,
+ 0.00389501, 0.00399411, 0.00409020, 0.00418350,
+ 0.00427419, 0.00436249, 0.00444858, 0.00453250,
+ 0.00461411, 0.00469328, 0.00476988, 0.00484356,
+ 0.00491375, 0.00497987, 0.00504139, 0.00509806,
+ 0.00514990, 0.00519693, 0.00523920, 0.00527700,
+ 0.00531083, 0.00534122, 0.00536864, 0.00539357,
+ 0.00541649, 0.00543785, 0.00545809, 0.00547713,
+ 0.00549441, 0.00550936, 0.00552146, 0.00553017,
+ 0.00553494, 0.00553524, 0.00553058, 0.00552065,
+ 0.00550536, 0.00548459, 0.00545828, 0.00542662,
+ 0.00539007, 0.00534910, 0.00530415, 0.00525568,
+ 0.00520417, 0.00515009, 0.00509387, 0.00503595,
+ 0.00497674, 0.00491665, 0.00485605, 0.00479503,
+ 0.00473336, 0.00467082, 0.00460721, 0.00454216,
+ 0.00447517, 0.00440575, 0.00433344, 0.00425768,
+ 0.00417786, 0.00409336, 0.00400363, 0.00390837,
+ 0.00380759, 0.00370130, 0.00358952, 0.00347268,
+ 0.00335157, 0.00322699, 0.00309975, 0.00297088,
+ 0.00284164, 0.00271328, 0.00258700, 0.00246328,
+ 0.00234195, 0.00222281, 0.00210562, 0.00198958,
+ 0.00187331, 0.00175546, 0.00163474, 0.00151020,
+ 0.00138130, 0.00124750, 0.00110831, 0.00096411,
+ 0.00081611, 0.00066554, 0.00051363, 0.00036134,
+ 0.00020940, 0.00005853, -0.00009058, -0.00023783,
+ -0.00038368, -0.00052861, -0.00067310, -0.00081757,
+ -0.00096237, -0.00110786, -0.00125442, -0.00140210,
+ -0.00155065, -0.00169984, -0.00184940, -0.00199910,
+ -0.00214872, -0.00229798, -0.00244664, -0.00259462,
+ -0.00274205, -0.00288912, -0.00303596, -0.00318259,
+ -0.00332890, -0.00347480, -0.00362024, -0.00376519,
+ -0.00390962, -0.00405345, -0.00419658, -0.00433902,
+ -0.00448085, -0.00462219, -0.00476309, -0.00490357,
+ -0.00504361, -0.00518321, -0.00532243, -0.00546132,
+ -0.00559988, -0.00573811, -0.00587602, -0.00601363,
+ -0.00615094, -0.00628795, -0.00642466, -0.00656111,
+ -0.00669737, -0.00683352, -0.00696963, -0.00710578,
+ -0.00724208, -0.00737862, -0.00751554, -0.00765295,
+ -0.00779098, -0.00792976, -0.00806941, -0.00821006,
+ -0.00835183, -0.00849485, -0.00863926, -0.00878522,
+ -0.00893293, -0.00908260, -0.00923444, -0.00938864,
+ -0.00954537, -0.00970482, -0.00986715, -0.01003173,
+ -0.01019711, -0.01036164, -0.01052357, -0.01068184,
+ -0.01083622, -0.01098652, -0.01113252, -0.01127409,
+ -0.01141114, -0.01154358, -0.01167135, -0.01179439,
+ -0.01191268, -0.01202619, -0.01213493, -0.01223891,
+ -0.01233817, -0.01243275, -0.01252272, -0.01260815,
+ -0.01268915, -0.01276583, -0.01283832, -0.01290685,
+ -0.01297171, -0.01303320, -0.01309168, -0.01314722,
+ -0.01319969, -0.01324889, -0.01329466, -0.01333693,
+ -0.01337577, -0.01341125, -0.01344345, -0.01347243,
+ -0.01349823, -0.01352089, -0.01354045, -0.01355700,
+ -0.01357068, -0.01358164, -0.01359003, -0.01359587,
+ -0.01359901, -0.01359931, -0.01359661, -0.01359087,
+ -0.01358219, -0.01357065, -0.01355637, -0.01353935,
+ -0.01351949, -0.01349670, -0.01347088, -0.01344214,
+ -0.01341078, -0.01337715, -0.01334158, -0.01330442,
+ -0.01326601, -0.01322671, -0.01318689, -0.01314692,
+ -0.01310123, -0.01306470, -0.01302556, -0.01298381,
+ -0.01293948, -0.01289255, -0.01284305, -0.01279095,
+ -0.01273625, -0.01267893, -0.01261897, -0.01255632,
+ -0.01249096, -0.01242283, -0.01235190, -0.01227827,
+ -0.01220213, -0.01212366, -0.01204304, -0.01196032,
+ -0.01187543, -0.01178829, -0.01169884, -0.01160718,
+ -0.01151352, -0.01141809, -0.01132111, -0.01122272,
+ -0.01112304, -0.01102217, -0.01092022, -0.01081730,
+ -0.01071355, -0.01060912, -0.01050411, -0.01039854,
+ -0.01029227, -0.01018521, -0.01007727, -0.00996859,
+ -0.00985959, -0.00975063, -0.00964208, -0.00953420,
+ -0.00942723, -0.00932135, -0.00921677, -0.00911364,
+ -0.00901208, -0.00891220, -0.00881412, -0.00871792,
+ -0.00862369, -0.00853153, -0.00844149, -0.00835360,
+ -0.00826785, -0.00818422, -0.00810267, -0.00802312,
+ -0.00794547, -0.00786959, -0.00779533, -0.00772165,
+ -0.00764673, -0.00756886, -0.00748649, -0.00739905,
+ -0.00730681, -0.00721006, -0.00710910, -0.00700419,
+ -0.00689559, -0.00678354, -0.00666829, -0.00655007,
+ -0.00642916, -0.00630579, -0.00618022, -0.00605267,
+ -0.00592333, -0.00579240, -0.00566006, -0.00552651,
+ -0.00539194, -0.00525653, -0.00512047, -0.00498390,
+ -0.00484693, -0.00470969, -0.00457228, -0.00443482,
+ -0.00429746, -0.00416034, -0.00402359, -0.00388738,
+ -0.00375185, -0.00361718, -0.00348350, -0.00335100,
+ -0.00321991, -0.00309043, -0.00296276, -0.00283698,
+ -0.00271307, -0.00259098, -0.00247066, -0.00235210,
+ -0.00223531, -0.00212030, -0.00200709, -0.00189576,
+ -0.00178647, -0.00167936, -0.00157457, -0.00147216,
+ -0.00137205, -0.00127418, -0.00117849, -0.00108498,
+ -0.00099375, -0.00090486, -0.00081840, -0.00073444,
+ -0.00065309, -0.00057445, -0.00049860, -0.00042551,
+ -0.00035503, -0.00028700, -0.00022125, -0.00015761,
+ -0.00009588, -0.00003583, 0.00002272, 0.00007975,
+ 0.00013501, 0.00018828, 0.00023933, 0.00028784,
+ 0.00033342, 0.00037572, 0.00041438, 0.00044939,
+ 0.00048103, 0.00050958, 0.00053533, 0.00055869,
+ 0.00058015, 0.00060022, 0.00061935, 0.00063781,
+ 0.00065568, 0.00067303, 0.00068991, 0.00070619,
+ 0.00072155, 0.00073567, 0.00074826, 0.00075912,
+ 0.00076811, 0.00077509, 0.00077997, 0.00078275,
+ 0.00078351, 0.00078237, 0.00077943, 0.00077484,
+ 0.00076884, 0.00076160, 0.00075335, 0.00074423,
+ 0.00073442, 0.00072404, 0.00071323, 0.00070209,
+ 0.00069068, 0.00067906, 0.00066728, 0.00065534,
+ 0.00064321, 0.00063086, 0.00061824, 0.00060534,
+ 0.00059211, 0.00057855, 0.00056462, 0.00055033,
+ 0.00053566, 0.00052063, 0.00050522, 0.00048949,
+ 0.00047349, 0.00045728, 0.00044092, 0.00042447,
+ 0.00040803, 0.00039166, 0.00037544, 0.00035943,
+ 0.00034371, 0.00032833, 0.00031333, 0.00029874,
+ 0.00028452, 0.00027067, 0.00025715, 0.00024395,
+ 0.00023104, 0.00021842, 0.00020606, 0.00019398,
+ 0.00018218, 0.00017069, 0.00015953, 0.00014871,
+ 0.00013827, 0.00012823, 0.00011861, 0.00010942,
+ 0.00010067, 0.00009236, 0.00008448, 0.00007703,
+ 0.00006999, 0.00006337, 0.00005714, 0.00005129,
+ 0.00004583, 0.00004072, 0.00003597, 0.00003157,
+ 0.00002752, 0.00002380, 0.00002042, 0.00001736,
+ 0.00001461, 0.00001215, 0.00000998, 0.00000807,
+ 0.00000641, 0.00000499, 0.00000378, 0.00000278,
+ 0.00000196, 0.00000132, 0.00000082, 0.00000046,
+ 0.00000020, 0.00000005, -0.00000003, -0.00000006,
+ -0.00000004, -0.00000001, 0.00000001, 0.00000001,
+ 0.00000001, 0.00000001, -0.00000001, -0.00000004,
+ -0.00000005, -0.00000003, 0.00000005, 0.00000020,
+ 0.00000043, 0.00000077, 0.00000123, 0.00000183,
+ 0.00000257, 0.00000348, 0.00000455, 0.00000581,
+ 0.00000727, 0.00000893, 0.00001080, 0.00001290,
+ 0.00001522, 0.00001778, 0.00002057, 0.00002362,
+ 0.00002691, 0.00003044, 0.00003422, 0.00003824,
+ 0.00004250, 0.00004701, 0.00005176, 0.00005676,
+ 0.00006200, 0.00006749, 0.00007322, 0.00007920,
+ 0.00008541, 0.00009186, 0.00009854, 0.00010543,
+ 0.00011251, 0.00011975, 0.00012714, 0.00013465,
+ 0.00014227, 0.00014997, 0.00015775, 0.00016558,
+ 0.00017348, 0.00018144, 0.00018947, 0.00019756,
+ 0.00020573, 0.00021399, 0.00022233, 0.00023076,
+ 0.00023924, 0.00024773, 0.00025621, 0.00026462,
+ 0.00027293, 0.00028108, 0.00028904, 0.00029675,
+ 0.00030419, 0.00031132, 0.00031810, 0.00032453,
+ 0.00033061, 0.00033632, 0.00034169, 0.00034672,
+ 0.00035142, 0.00035580, 0.00035988, 0.00036369,
+ 0.00036723, 0.00037053, 0.00037361, 0.00037647,
+ 0.00037909, 0.00038145, 0.00038352, 0.00038527,
+ 0.00038663, 0.00038757, 0.00038801, 0.00038790,
+ 0.00038717, 0.00038572, 0.00038350, 0.00038044,
+ 0.00037651, 0.00037170, 0.00036597, 0.00035936,
+ 0.00035191, 0.00034370, 0.00033480, 0.00032531,
+ 0.00031537, 0.00030512, 0.00029470, 0.00028417,
+ 0.00027354, 0.00026279, 0.00025191, 0.00024081,
+ 0.00022933, 0.00021731, 0.00020458, 0.00019101,
+ 0.00017654, 0.00016106, 0.00014452, 0.00012694,
+ 0.00010848, 0.00008929, 0.00006953, 0.00004935,
+ 0.00002884, 0.00000813, -0.00001268, -0.00003357,
+ -0.00005457, -0.00007574, -0.00009714, -0.00011882,
+ -0.00014082, -0.00016318, -0.00018595, -0.00020912,
+ -0.00023265, -0.00025650, -0.00028060, -0.00030492,
+ -0.00032941, -0.00035400, -0.00037865, -0.00040333,
+ -0.00042804, -0.00045279, -0.00047759, -0.00050243,
+ -0.00052728, -0.00055209, -0.00057685, -0.00060153,
+ -0.00062611, -0.00065056, -0.00067485, -0.00069895,
+ -0.00072287, -0.00074660, -0.00077013, -0.00079345,
+ -0.00081653, -0.00083936, -0.00086192, -0.00088421,
+ -0.00090619, -0.00092786, -0.00094919, -0.00097017,
+ -0.00099077, -0.00101098, -0.00103077, -0.00105012,
+ -0.00106904, -0.00108750, -0.00110549, -0.00112301,
+ -0.00114005, -0.00115660, -0.00117265, -0.00118821,
+ -0.00120325, -0.00121779, -0.00123180, -0.00124528,
+ -0.00125822, -0.00127061, -0.00128243, -0.00129368,
+ -0.00130435, -0.00131445, -0.00132395, -0.00133285,
+ -0.00134113, -0.00134878, -0.00135577, -0.00136215,
+ -0.00136797, -0.00137333, -0.00137834, -0.00138305,
+ -0.00138748, -0.00139163, -0.00139551, -0.00139913,
+ -0.00140249, -0.00140559, -0.00140844, -0.00141102,
+ -0.00141334, -0.00141538, -0.00141714, -0.00141861,
+ -0.00141978, -0.00142064, -0.00142117, -0.00142138,
+ -0.00142125, -0.00142077, -0.00141992, -0.00141870,
+ -0.00141710, -0.00141510, -0.00141268, -0.00140986,
+ -0.00140663, -0.00140301, -0.00139900, -0.00139460,
+ -0.00138981, -0.00138464, -0.00137908, -0.00137313,
+ -0.00136680, -0.00136010, -0.00135301, -0.00134555,
+ -0.00133772, -0.00132952, -0.00132095, -0.00131201,
+ -0.00130272, -0.00129307, -0.00128309, -0.00127277,
+ -0.00126211, -0.00125113, -0.00123981, -0.00122817,
+ -0.00121622, -0.00120397, -0.00119141, -0.00117859,
+ -0.00116552, -0.00115223, -0.00113877, -0.00112517,
+ -0.00111144, -0.00109764, -0.00108377, -0.00106989,
+};
diff --git a/libavcodec/aactab.h b/libavcodec/aactab.h
index e06f682..699d99d 100644
--- a/libavcodec/aactab.h
+++ b/libavcodec/aactab.h
@@ -47,6 +47,7 @@
DECLARE_ALIGNED(32, extern float, ff_aac_kbd_long_1024)[1024];
DECLARE_ALIGNED(32, extern float, ff_aac_kbd_long_512 )[512];
DECLARE_ALIGNED(32, extern float, ff_aac_kbd_short_128)[128];
+const DECLARE_ALIGNED(32, extern float, ff_aac_eld_window)[1920];
// @}
/* @name number of scalefactor window bands for long and short transform windows respectively
diff --git a/libavcodec/ac3dec.c b/libavcodec/ac3dec.c
index f91ded0..1995412 100644
--- a/libavcodec/ac3dec.c
+++ b/libavcodec/ac3dec.c
@@ -29,6 +29,7 @@
#include <math.h>
#include <string.h>
+#include "libavutil/channel_layout.h"
#include "libavutil/crc.h"
#include "libavutil/opt.h"
#include "internal.h"
@@ -178,11 +179,20 @@
avctx->sample_fmt = AV_SAMPLE_FMT_FLTP;
/* allow downmixing to stereo or mono */
- if (avctx->channels > 0 && avctx->request_channels > 0 &&
- avctx->request_channels < avctx->channels &&
- avctx->request_channels <= 2) {
- avctx->channels = avctx->request_channels;
- }
+#if FF_API_REQUEST_CHANNELS
+FF_DISABLE_DEPRECATION_WARNINGS
+ if (avctx->request_channels == 1)
+ avctx->request_channel_layout = AV_CH_LAYOUT_MONO;
+ else if (avctx->request_channels == 2)
+ avctx->request_channel_layout = AV_CH_LAYOUT_STEREO;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+ if (avctx->channels > 1 &&
+ avctx->request_channel_layout == AV_CH_LAYOUT_MONO)
+ avctx->channels = 1;
+ else if (avctx->channels > 2 &&
+ avctx->request_channel_layout == AV_CH_LAYOUT_STEREO)
+ avctx->channels = 2;
s->downmixed = 1;
for (i = 0; i < AC3_MAX_CHANNELS; i++) {
@@ -251,7 +261,6 @@
s->bit_alloc_params.sr_code = hdr.sr_code;
s->bitstream_mode = hdr.bitstream_mode;
s->channel_mode = hdr.channel_mode;
- s->channel_layout = hdr.channel_layout;
s->lfe_on = hdr.lfe_on;
s->bit_alloc_params.sr_shift = hdr.sr_shift;
s->sample_rate = hdr.sample_rate;
@@ -488,6 +497,10 @@
break;
default: /* 6 to 15 */
/* Shift mantissa and sign-extend it. */
+ if (bap > 15) {
+ av_log(s->avctx, AV_LOG_ERROR, "bap %d is invalid in plain AC-3\n", bap);
+ bap = 15;
+ }
mantissa = get_sbits(gbc, quantization_tab[bap]);
mantissa <<= 24 - quantization_tab[bap];
break;
@@ -747,8 +760,8 @@
i = !s->channel_mode;
do {
if (get_bits1(gbc)) {
- s->dynamic_range[i] = ((dynamic_range_tab[get_bits(gbc, 8)] - 1.0) *
- s->drc_scale) + 1.0;
+ s->dynamic_range[i] = powf(dynamic_range_tab[get_bits(gbc, 8)],
+ s->drc_scale);
} else if (blk == 0) {
s->dynamic_range[i] = 1.0f;
}
@@ -1330,6 +1343,8 @@
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");
+ if (avctx->err_recognition & AV_EF_EXPLODE)
+ return AVERROR_INVALIDDATA;
err = AAC_AC3_PARSE_ERROR_CRC;
}
}
@@ -1347,14 +1362,15 @@
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) {
- s->out_channels = avctx->request_channels;
- s->output_mode = avctx->request_channels == 1 ? AC3_CHMODE_MONO : AC3_CHMODE_STEREO;
- s->channel_layout = avpriv_ac3_channel_layout_tab[s->output_mode];
+ if (s->channels > 1 &&
+ avctx->request_channel_layout == AV_CH_LAYOUT_MONO) {
+ s->out_channels = 1;
+ s->output_mode = AC3_CHMODE_MONO;
+ } else if (s->channels > 2 &&
+ avctx->request_channel_layout == AV_CH_LAYOUT_STEREO) {
+ s->out_channels = 2;
+ s->output_mode = AC3_CHMODE_STEREO;
}
- avctx->channels = s->out_channels;
- avctx->channel_layout = s->channel_layout;
s->loro_center_mix_level = gain_levels[s-> center_mix_level];
s->loro_surround_mix_level = gain_levels[s->surround_mix_level];
@@ -1370,6 +1386,9 @@
return AVERROR_INVALIDDATA;
}
avctx->channels = s->out_channels;
+ avctx->channel_layout = avpriv_ac3_channel_layout_tab[s->output_mode & ~AC3_OUTPUT_LFEON];
+ if (s->output_mode & AC3_OUTPUT_LFEON)
+ avctx->channel_layout |= AV_CH_LOW_FREQUENCY;
/* set audio service type based on bitstream mode for AC-3 */
avctx->audio_service_type = s->bitstream_mode;
diff --git a/libavcodec/ac3dec.h b/libavcodec/ac3dec.h
index ae72d80..fa447c4 100644
--- a/libavcodec/ac3dec.h
+++ b/libavcodec/ac3dec.h
@@ -81,7 +81,6 @@
int num_blocks; ///< number of audio blocks
int bitstream_mode; ///< bitstream mode (bsmod)
int channel_mode; ///< channel mode (acmod)
- int channel_layout; ///< channel layout
int lfe_on; ///< lfe channel in use
int channel_map; ///< custom channel map
int center_mix_level; ///< Center mix level index
diff --git a/libavcodec/ac3dsp.c b/libavcodec/ac3dsp.c
index 6df3a68..feda6dd 100644
--- a/libavcodec/ac3dsp.c
+++ b/libavcodec/ac3dsp.c
@@ -239,6 +239,19 @@
}
}
+static void apply_window_int16_c(int16_t *output, const int16_t *input,
+ const int16_t *window, unsigned int len)
+{
+ int i;
+ int len2 = len >> 1;
+
+ for (i = 0; i < len2; i++) {
+ int16_t w = window[i];
+ output[i] = (MUL16(input[i], w) + (1 << 14)) >> 15;
+ output[len-i-1] = (MUL16(input[len-i-1], w) + (1 << 14)) >> 15;
+ }
+}
+
av_cold void ff_ac3dsp_init(AC3DSPContext *c, int bit_exact)
{
c->ac3_exponent_min = ac3_exponent_min_c;
@@ -253,6 +266,7 @@
c->sum_square_butterfly_int32 = ac3_sum_square_butterfly_int32_c;
c->sum_square_butterfly_float = ac3_sum_square_butterfly_float_c;
c->downmix = ac3_downmix_c;
+ c->apply_window_int16 = apply_window_int16_c;
if (ARCH_ARM)
ff_ac3dsp_init_arm(c, bit_exact);
diff --git a/libavcodec/ac3dsp.h b/libavcodec/ac3dsp.h
index bafbc89..bced597 100644
--- a/libavcodec/ac3dsp.h
+++ b/libavcodec/ac3dsp.h
@@ -134,6 +134,20 @@
void (*downmix)(float **samples, float (*matrix)[2], int out_ch,
int in_ch, int len);
+
+ /**
+ * Apply symmetric window in 16-bit fixed-point.
+ * @param output destination array
+ * constraints: 16-byte aligned
+ * @param input source array
+ * constraints: 16-byte aligned
+ * @param window window array
+ * constraints: 16-byte aligned, at least len/2 elements
+ * @param len full window length
+ * constraints: multiple of ? greater than zero
+ */
+ void (*apply_window_int16)(int16_t *output, const int16_t *input,
+ const int16_t *window, unsigned int len);
} AC3DSPContext;
void ff_ac3dsp_init (AC3DSPContext *c, int bit_exact);
diff --git a/libavcodec/ac3enc_fixed.c b/libavcodec/ac3enc_fixed.c
index b1f9c21..5194d42 100644
--- a/libavcodec/ac3enc_fixed.c
+++ b/libavcodec/ac3enc_fixed.c
@@ -71,17 +71,6 @@
/*
- * Apply KBD window to input samples prior to MDCT.
- */
-static void apply_window(void *dsp, int16_t *output, const int16_t *input,
- const int16_t *window, unsigned int len)
-{
- DSPContext *dsp0 = dsp;
- dsp0->apply_window_int16(output, input, window, len);
-}
-
-
-/*
* Normalize the input samples to use the maximum available precision.
* This assumes signed 16-bit input samples.
*/
diff --git a/libavcodec/ac3enc_float.c b/libavcodec/ac3enc_float.c
index 532c56c..35fb418 100644
--- a/libavcodec/ac3enc_float.c
+++ b/libavcodec/ac3enc_float.c
@@ -88,18 +88,6 @@
/*
- * Apply KBD window to input samples prior to MDCT.
- */
-static void apply_window(void *dsp, float *output,
- const float *input, const float *window,
- unsigned int len)
-{
- AVFloatDSPContext *fdsp = dsp;
- fdsp->vector_fmul(output, input, window, len);
-}
-
-
-/*
* Normalize the input samples.
* Not needed for the floating-point encoder.
*/
diff --git a/libavcodec/ac3enc_template.c b/libavcodec/ac3enc_template.c
index 354be53..4689f70 100644
--- a/libavcodec/ac3enc_template.c
+++ b/libavcodec/ac3enc_template.c
@@ -34,10 +34,6 @@
static void scale_coefficients(AC3EncodeContext *s);
-static void apply_window(void *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);
@@ -105,11 +101,11 @@
const SampleType *input_samples = &s->planar_samples[ch][blk * AC3_BLOCK_SIZE];
#if CONFIG_AC3ENC_FLOAT
- apply_window(&s->fdsp, s->windowed_samples, input_samples,
- s->mdct_window, AC3_WINDOW_SIZE);
+ s->fdsp.vector_fmul(s->windowed_samples, input_samples,
+ s->mdct_window, AC3_WINDOW_SIZE);
#else
- apply_window(&s->dsp, s->windowed_samples, input_samples,
- s->mdct_window, AC3_WINDOW_SIZE);
+ s->ac3dsp.apply_window_int16(s->windowed_samples, input_samples,
+ s->mdct_window, AC3_WINDOW_SIZE);
#endif
if (s->fixed_point)
diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
index 8e08a23..6d084ac 100644
--- a/libavcodec/allcodecs.c
+++ b/libavcodec/allcodecs.c
@@ -24,8 +24,9 @@
* Provide registration of all codecs, parsers and bitstream filters for libavcodec.
*/
-#include "avcodec.h"
#include "config.h"
+#include "avcodec.h"
+#include "version.h"
#define REGISTER_HWACCEL(X, x) \
{ \
@@ -164,6 +165,8 @@
REGISTER_DECODER(H264_CRYSTALHD, h264_crystalhd);
REGISTER_DECODER(H264_VDA, h264_vda);
REGISTER_DECODER(H264_VDPAU, h264_vdpau);
+ REGISTER_DECODER(HEVC, hevc);
+ REGISTER_DECODER(HNM4_VIDEO, hnm4_video);
REGISTER_ENCDEC (HUFFYUV, huffyuv);
REGISTER_DECODER(IDCIN, idcin);
REGISTER_DECODER(IFF_BYTERUN1, iff_byterun1);
@@ -187,7 +190,9 @@
REGISTER_DECODER(MJPEGB, mjpegb);
REGISTER_DECODER(MMVIDEO, mmvideo);
REGISTER_DECODER(MOTIONPIXELS, motionpixels);
+#if FF_API_XVMC
REGISTER_DECODER(MPEG_XVMC, mpeg_xvmc);
+#endif /* FF_API_XVMC */
REGISTER_ENCDEC (MPEG1VIDEO, mpeg1video);
REGISTER_ENCDEC (MPEG2VIDEO, mpeg2video);
REGISTER_ENCDEC (MPEG4, mpeg4);
@@ -345,6 +350,7 @@
REGISTER_DECODER(MP1FLOAT, mp1float);
REGISTER_ENCDEC (MP2, mp2);
REGISTER_DECODER(MP2FLOAT, mp2float);
+ REGISTER_ENCODER(MP2FIXED, mp2fixed);
REGISTER_DECODER(MP3, mp3);
REGISTER_DECODER(MP3FLOAT, mp3float);
REGISTER_DECODER(MP3ADU, mp3adu);
@@ -432,6 +438,7 @@
REGISTER_DECODER(ADPCM_EA_XAS, adpcm_ea_xas);
REGISTER_ENCDEC (ADPCM_G722, adpcm_g722);
REGISTER_ENCDEC (ADPCM_G726, adpcm_g726);
+ REGISTER_DECODER(ADPCM_G726LE, adpcm_g726le);
REGISTER_DECODER(ADPCM_IMA_AMV, adpcm_ima_amv);
REGISTER_DECODER(ADPCM_IMA_APC, adpcm_ima_apc);
REGISTER_DECODER(ADPCM_IMA_DK3, adpcm_ima_dk3);
@@ -534,6 +541,7 @@
REGISTER_PARSER(H261, h261);
REGISTER_PARSER(H263, h263);
REGISTER_PARSER(H264, h264);
+ REGISTER_PARSER(HEVC, hevc);
REGISTER_PARSER(MJPEG, mjpeg);
REGISTER_PARSER(MLP, mlp);
REGISTER_PARSER(MPEG4VIDEO, mpeg4video);
@@ -548,6 +556,7 @@
REGISTER_PARSER(VORBIS, vorbis);
REGISTER_PARSER(VP3, vp3);
REGISTER_PARSER(VP8, vp8);
+ REGISTER_PARSER(VP9, vp9);
/* bitstream filters */
REGISTER_BSF(AAC_ADTSTOASC, aac_adtstoasc);
@@ -557,7 +566,6 @@
REGISTER_BSF(IMX_DUMP_HEADER, imx_dump_header);
REGISTER_BSF(MJPEG2JPEG, mjpeg2jpeg);
REGISTER_BSF(MJPEGA_DUMP_HEADER, mjpega_dump_header);
- REGISTER_BSF(MP3_HEADER_COMPRESS, mp3_header_compress);
REGISTER_BSF(MP3_HEADER_DECOMPRESS, mp3_header_decompress);
REGISTER_BSF(MOV2TEXTSUB, mov2textsub);
REGISTER_BSF(NOISE, noise);
diff --git a/libavcodec/alsdec.c b/libavcodec/alsdec.c
index 7b99d86..825949f 100644
--- a/libavcodec/alsdec.c
+++ b/libavcodec/alsdec.c
@@ -1565,6 +1565,8 @@
if (ctx->cur_frame_length != sconf->frame_length &&
ctx->crc_org != ctx->crc) {
av_log(avctx, AV_LOG_ERROR, "CRC error.\n");
+ if (avctx->err_recognition & AV_EF_EXPLODE)
+ return AVERROR_INVALIDDATA;
}
}
diff --git a/libavcodec/ansi.c b/libavcodec/ansi.c
index 8dce61a..143b0aa 100644
--- a/libavcodec/ansi.c
+++ b/libavcodec/ansi.c
@@ -91,7 +91,7 @@
s->bg = DEFAULT_BG_COLOR;
if (!avctx->width || !avctx->height)
- avcodec_set_dimensions(avctx, 80<<3, 25<<4);
+ ff_set_dimensions(avctx, 80 << 3, 25 << 4);
return 0;
}
@@ -182,7 +182,10 @@
static int execute_code(AVCodecContext * avctx, int c)
{
AnsiContext *s = avctx->priv_data;
- int ret, i, width, height;
+ int ret, i;
+ int width = avctx->width;
+ int height = avctx->height;
+
switch(c) {
case 'A': //Cursor Up
s->y = FFMAX(s->y - (s->nb_args > 0 ? s->args[0]*s->font_height : s->font_height), 0);
@@ -205,8 +208,6 @@
case 'l': //reset screen mode
if (s->nb_args < 2)
s->args[0] = DEFAULT_SCREEN_MODE;
- width = avctx->width;
- height = avctx->height;
switch(s->args[0]) {
case 0: case 1: case 4: case 5: case 13: case 19: //320x200 (25 rows)
s->font = avpriv_cga_font;
@@ -247,7 +248,9 @@
s->y = av_clip(s->y, 0, height - s->font_height);
if (width != avctx->width || height != avctx->height) {
av_frame_unref(s->frame);
- avcodec_set_dimensions(avctx, width, height);
+ ret = ff_set_dimensions(avctx, width, height);
+ if (ret < 0)
+ return ret;
if ((ret = ff_get_buffer(avctx, s->frame,
AV_GET_BUFFER_FLAG_REF)) < 0)
return ret;
diff --git a/libavcodec/apedec.c b/libavcodec/apedec.c
index ea71ea0..6ec502b 100644
--- a/libavcodec/apedec.c
+++ b/libavcodec/apedec.c
@@ -1456,7 +1456,8 @@
}
s->ptr += offset;
} else {
- init_get_bits(&s->gb, s->ptr, (s->data_end - s->ptr) * 8);
+ if ((ret = init_get_bits8(&s->gb, s->ptr, s->data_end - s->ptr)) < 0)
+ return ret;
if (s->fileversion > 3800)
skip_bits_long(&s->gb, offset * 8);
else
diff --git a/libavcodec/arm/ac3dsp_init_arm.c b/libavcodec/arm/ac3dsp_init_arm.c
index ffe0747..a3c32ff 100644
--- a/libavcodec/arm/ac3dsp_init_arm.c
+++ b/libavcodec/arm/ac3dsp_init_arm.c
@@ -31,6 +31,8 @@
void ff_ac3_rshift_int32_neon(int32_t *src, unsigned len, unsigned shift);
void ff_float_to_fixed24_neon(int32_t *dst, const float *src, unsigned int len);
void ff_ac3_extract_exponents_neon(uint8_t *exp, int32_t *coef, int nb_coefs);
+void ff_apply_window_int16_neon(int16_t *dst, const int16_t *src,
+ const int16_t *window, unsigned n);
void ff_ac3_sum_square_butterfly_int32_neon(int64_t sum[4],
const int32_t *coef0,
const int32_t *coef1,
@@ -64,6 +66,7 @@
c->ac3_rshift_int32 = ff_ac3_rshift_int32_neon;
c->float_to_fixed24 = ff_float_to_fixed24_neon;
c->extract_exponents = ff_ac3_extract_exponents_neon;
+ c->apply_window_int16 = ff_apply_window_int16_neon;
c->sum_square_butterfly_int32 = ff_ac3_sum_square_butterfly_int32_neon;
c->sum_square_butterfly_float = ff_ac3_sum_square_butterfly_float_neon;
}
diff --git a/libavcodec/arm/ac3dsp_neon.S b/libavcodec/arm/ac3dsp_neon.S
index 381f158..89d0ae8 100644
--- a/libavcodec/arm/ac3dsp_neon.S
+++ b/libavcodec/arm/ac3dsp_neon.S
@@ -109,6 +109,29 @@
bx lr
endfunc
+function ff_apply_window_int16_neon, export=1
+ push {r4,lr}
+ add r4, r1, r3, lsl #1
+ add lr, r0, r3, lsl #1
+ sub r4, r4, #16
+ sub lr, lr, #16
+ mov r12, #-16
+1:
+ vld1.16 {q0}, [r1,:128]!
+ vld1.16 {q2}, [r2,:128]!
+ vld1.16 {q1}, [r4,:128], r12
+ vrev64.16 q3, q2
+ vqrdmulh.s16 q0, q0, q2
+ vqrdmulh.s16 d2, d2, d7
+ vqrdmulh.s16 d3, d3, d6
+ vst1.16 {q0}, [r0,:128]!
+ vst1.16 {q1}, [lr,:128], r12
+ subs r3, r3, #16
+ bgt 1b
+
+ pop {r4,pc}
+endfunc
+
function ff_ac3_sum_square_butterfly_int32_neon, export=1
vmov.i64 q0, #0
vmov.i64 q1, #0
diff --git a/libavcodec/arm/dsputil_init_neon.c b/libavcodec/arm/dsputil_init_neon.c
index 6d19af7..c1f250a 100644
--- a/libavcodec/arm/dsputil_init_neon.c
+++ b/libavcodec/arm/dsputil_init_neon.c
@@ -45,9 +45,6 @@
int32_t ff_scalarproduct_and_madd_int16_neon(int16_t *v1, const int16_t *v2,
const int16_t *v3, int len, int mul);
-void ff_apply_window_int16_neon(int16_t *dst, const int16_t *src,
- const int16_t *window, unsigned n);
-
av_cold void ff_dsputil_init_neon(DSPContext *c, AVCodecContext *avctx)
{
const int high_bit_depth = avctx->bits_per_raw_sample > 8;
@@ -76,6 +73,4 @@
c->scalarproduct_int16 = ff_scalarproduct_int16_neon;
c->scalarproduct_and_madd_int16 = ff_scalarproduct_and_madd_int16_neon;
-
- c->apply_window_int16 = ff_apply_window_int16_neon;
}
diff --git a/libavcodec/arm/dsputil_neon.S b/libavcodec/arm/dsputil_neon.S
index 307e122..6c8231e 100644
--- a/libavcodec/arm/dsputil_neon.S
+++ b/libavcodec/arm/dsputil_neon.S
@@ -169,29 +169,6 @@
bx lr
endfunc
-function ff_apply_window_int16_neon, export=1
- push {r4,lr}
- add r4, r1, r3, lsl #1
- add lr, r0, r3, lsl #1
- sub r4, r4, #16
- sub lr, lr, #16
- mov r12, #-16
-1:
- vld1.16 {q0}, [r1,:128]!
- vld1.16 {q2}, [r2,:128]!
- vld1.16 {q1}, [r4,:128], r12
- vrev64.16 q3, q2
- vqrdmulh.s16 q0, q0, q2
- vqrdmulh.s16 d2, d2, d7
- vqrdmulh.s16 d3, d3, d6
- vst1.16 {q0}, [r0,:128]!
- vst1.16 {q1}, [lr,:128], r12
- subs r3, r3, #16
- bgt 1b
-
- pop {r4,pc}
-endfunc
-
function ff_vector_clip_int32_neon, export=1
vdup.32 q0, r2
vdup.32 q1, r3
diff --git a/libavcodec/ass.c b/libavcodec/ass.c
index 6fe18f5..ccc9570 100644
--- a/libavcodec/ass.c
+++ b/libavcodec/ass.c
@@ -77,14 +77,11 @@
}
}
-int ff_ass_add_rect(AVSubtitle *sub, const char *dialog,
- int ts_start, int duration, int raw)
+int ff_ass_bprint_dialog(AVBPrint *buf, const char *dialog,
+ int ts_start, int duration, int raw)
{
- AVBPrint buf;
- int ret, dlen;
- AVSubtitleRect **rects;
+ int dlen;
- av_bprint_init(&buf, 0, AV_BPRINT_SIZE_UNLIMITED);
if (!raw || raw == 2) {
long int layer = 0;
@@ -101,32 +98,92 @@
return AVERROR_INVALIDDATA;
dialog++;
}
- av_bprintf(&buf, "Dialogue: %ld,", layer);
- insert_ts(&buf, ts_start);
- insert_ts(&buf, duration == -1 ? -1 : ts_start + duration);
+ av_bprintf(buf, "Dialogue: %ld,", layer);
+ insert_ts(buf, ts_start);
+ insert_ts(buf, duration == -1 ? -1 : ts_start + duration);
if (raw != 2)
- av_bprintf(&buf, "Default,");
+ av_bprintf(buf, "Default,");
}
dlen = strcspn(dialog, "\n");
dlen += dialog[dlen] == '\n';
- av_bprintf(&buf, "%.*s", dlen, dialog);
+ av_bprintf(buf, "%.*s", dlen, dialog);
if (raw == 2)
- av_bprintf(&buf, "\r\n");
+ av_bprintf(buf, "\r\n");
+
+ return dlen;
+}
+
+int ff_ass_add_rect(AVSubtitle *sub, const char *dialog,
+ int ts_start, int duration, int raw)
+{
+ AVBPrint buf;
+ int ret, dlen;
+ AVSubtitleRect **rects;
+
+ av_bprint_init(&buf, 0, AV_BPRINT_SIZE_UNLIMITED);
+ if ((ret = ff_ass_bprint_dialog(&buf, dialog, ts_start, duration, raw)) < 0)
+ goto err;
+ dlen = ret;
if (!av_bprint_is_complete(&buf))
- return AVERROR(ENOMEM);
+ goto errnomem;
rects = av_realloc(sub->rects, (sub->num_rects+1) * sizeof(*sub->rects));
if (!rects)
- return AVERROR(ENOMEM);
+ goto errnomem;
sub->rects = rects;
sub->end_display_time = FFMAX(sub->end_display_time, 10 * duration);
rects[sub->num_rects] = av_mallocz(sizeof(*rects[0]));
rects[sub->num_rects]->type = SUBTITLE_ASS;
ret = av_bprint_finalize(&buf, &rects[sub->num_rects]->ass);
if (ret < 0)
- return ret;
+ goto err;
sub->num_rects++;
return dlen;
+
+errnomem:
+ ret = AVERROR(ENOMEM);
+err:
+ av_bprint_finalize(&buf, NULL);
+ return ret;
+}
+
+void ff_ass_bprint_text_event(AVBPrint *buf, const char *p, int size,
+ const char *linebreaks, int keep_ass_markup)
+{
+ const char *p_end = p + size;
+
+ for (; p < p_end && *p; p++) {
+
+ /* forced custom line breaks, not accounted as "normal" EOL */
+ if (linebreaks && strchr(linebreaks, *p)) {
+ av_bprintf(buf, "\\N");
+
+ /* standard ASS escaping so random characters don't get mis-interpreted
+ * as ASS */
+ } else if (!keep_ass_markup && strchr("{}\\", *p)) {
+ av_bprintf(buf, "\\%c", *p);
+
+ /* some packets might end abruptly (no \0 at the end, like for example
+ * in some cases of demuxing from a classic video container), some
+ * might be terminated with \n or \r\n which we have to remove (for
+ * consistency with those who haven't), and we also have to deal with
+ * evil cases such as \r at the end of the buffer (and no \0 terminated
+ * character) */
+ } else if (p[0] == '\n') {
+ /* some stuff left so we can insert a line break */
+ if (p < p_end - 1)
+ av_bprintf(buf, "\\N");
+ } else if (p[0] == '\r' && p < p_end - 1 && p[1] == '\n') {
+ /* \r followed by a \n, we can skip it. We don't insert the \N yet
+ * because we don't know if it is followed by more text */
+ continue;
+
+ /* finally, a sane character */
+ } else {
+ av_bprint_chars(buf, *p, 1);
+ }
+ }
+ av_bprintf(buf, "\r\n");
}
diff --git a/libavcodec/ass.h b/libavcodec/ass.h
index ef99b58..2df38e6 100644
--- a/libavcodec/ass.h
+++ b/libavcodec/ass.h
@@ -23,6 +23,7 @@
#define AVCODEC_ASS_H
#include "avcodec.h"
+#include "libavutil/bprint.h"
/**
* @name Default values for ASS style
@@ -90,4 +91,38 @@
int ff_ass_add_rect(AVSubtitle *sub, const char *dialog,
int ts_start, int duration, int raw);
+/**
+ * Add an ASS dialog line to an AVBPrint buffer.
+ *
+ * @param buf pointer to an initialized AVBPrint buffer
+ * @param dialog ASS dialog to add to sub
+ * @param ts_start start timestamp for this dialog (in 1/100 second unit)
+ * @param duration duration for this dialog (in 1/100 second unit), can be -1
+ * to last until the end of the presentation
+ * @param raw when set to 2, it indicates that dialog contains an ASS
+ * dialog line as muxed in Matroska
+ * when set to 1, it indicates that dialog contains a whole SSA
+ * dialog line which should be copied as is.
+ * when set to 0, it indicates that dialog contains only the Text
+ * part of the ASS dialog line, the rest of the line
+ * will be generated.
+ * @return number of characters read from dialog. It can be less than the whole
+ * length of dialog, if dialog contains several lines of text.
+ * A negative value indicates an error.
+ */
+int ff_ass_bprint_dialog(AVBPrint *buf, const char *dialog,
+ int ts_start, int duration, int raw);
+
+/**
+ * Escape a text subtitle using ASS syntax into an AVBPrint buffer.
+ * Newline characters will be escaped to \N.
+ *
+ * @param buf pointer to an initialized AVBPrint buffer
+ * @param p source text
+ * @param size size of the source text
+ * @param linebreaks additional newline chars, which will be escaped to \N
+ * @param keep_ass_markup braces and backslash will not be escaped if set
+ */
+void ff_ass_bprint_text_event(AVBPrint *buf, const char *p, int size,
+ const char *linebreaks, int keep_ass_markup);
#endif /* AVCODEC_ASS_H */
diff --git a/libavcodec/asv.c b/libavcodec/asv.c
index 21f179b..58d2a89 100644
--- a/libavcodec/asv.c
+++ b/libavcodec/asv.c
@@ -89,6 +89,5 @@
a->mb_width2 = (avctx->width + 0) / 16;
a->mb_height2 = (avctx->height + 0) / 16;
- avctx->coded_frame= &a->picture;
a->avctx= avctx;
}
diff --git a/libavcodec/asv.h b/libavcodec/asv.h
index ca67c67..ce3c73a 100644
--- a/libavcodec/asv.h
+++ b/libavcodec/asv.h
@@ -38,7 +38,6 @@
typedef struct ASV1Context{
AVCodecContext *avctx;
DSPContext dsp;
- AVFrame picture;
PutBitContext pb;
GetBitContext gb;
ScanTable scantable;
diff --git a/libavcodec/asvenc.c b/libavcodec/asvenc.c
index 38d971a..dd3d4f5 100644
--- a/libavcodec/asvenc.c
+++ b/libavcodec/asvenc.c
@@ -148,14 +148,16 @@
return 0;
}
-static inline void dct_get(ASV1Context *a, int mb_x, int mb_y){
+static inline void dct_get(ASV1Context *a, const AVFrame *frame,
+ int mb_x, int mb_y)
+{
int16_t (*block)[64]= a->block;
- int linesize= a->picture.linesize[0];
+ int linesize = frame->linesize[0];
int i;
- uint8_t *ptr_y = a->picture.data[0] + (mb_y * 16* linesize ) + mb_x * 16;
- uint8_t *ptr_cb = a->picture.data[1] + (mb_y * 8 * a->picture.linesize[1]) + mb_x * 8;
- uint8_t *ptr_cr = a->picture.data[2] + (mb_y * 8 * a->picture.linesize[2]) + mb_x * 8;
+ uint8_t *ptr_y = frame->data[0] + (mb_y * 16* linesize ) + mb_x * 16;
+ uint8_t *ptr_cb = frame->data[1] + (mb_y * 8 * frame->linesize[1]) + mb_x * 8;
+ uint8_t *ptr_cr = frame->data[2] + (mb_y * 8 * frame->linesize[2]) + mb_x * 8;
a->dsp.get_pixels(block[0], ptr_y , linesize);
a->dsp.get_pixels(block[1], ptr_y + 8, linesize);
@@ -165,8 +167,8 @@
a->dsp.fdct(block[i]);
if(!(a->avctx->flags&CODEC_FLAG_GRAY)){
- a->dsp.get_pixels(block[4], ptr_cb, a->picture.linesize[1]);
- a->dsp.get_pixels(block[5], ptr_cr, a->picture.linesize[2]);
+ a->dsp.get_pixels(block[4], ptr_cb, frame->linesize[1]);
+ a->dsp.get_pixels(block[5], ptr_cr, frame->linesize[2]);
for(i=4; i<6; i++)
a->dsp.fdct(block[i]);
}
@@ -176,7 +178,6 @@
const AVFrame *pict, int *got_packet)
{
ASV1Context * const a = avctx->priv_data;
- AVFrame * const p= &a->picture;
int size, ret;
int mb_x, mb_y;
@@ -186,13 +187,9 @@
init_put_bits(&a->pb, pkt->data, pkt->size);
- *p = *pict;
- p->pict_type= AV_PICTURE_TYPE_I;
- p->key_frame= 1;
-
for(mb_y=0; mb_y<a->mb_height2; mb_y++){
for(mb_x=0; mb_x<a->mb_width2; mb_x++){
- dct_get(a, mb_x, mb_y);
+ dct_get(a, pict, mb_x, mb_y);
encode_mb(a, a->block);
}
}
@@ -200,7 +197,7 @@
if(a->mb_width2 != a->mb_width){
mb_x= a->mb_width2;
for(mb_y=0; mb_y<a->mb_height2; mb_y++){
- dct_get(a, mb_x, mb_y);
+ dct_get(a, pict, mb_x, mb_y);
encode_mb(a, a->block);
}
}
@@ -208,7 +205,7 @@
if(a->mb_height2 != a->mb_height){
mb_y= a->mb_height2;
for(mb_x=0; mb_x<a->mb_width; mb_x++){
- dct_get(a, mb_x, mb_y);
+ dct_get(a, pict, mb_x, mb_y);
encode_mb(a, a->block);
}
}
diff --git a/libavcodec/audioconvert.c b/libavcodec/audioconvert.c
index 5d8a348..5e46fae 100644
--- a/libavcodec/audioconvert.c
+++ b/libavcodec/audioconvert.c
@@ -32,6 +32,8 @@
#include "avcodec.h"
#include "audioconvert.h"
+#if FF_API_AUDIO_CONVERT
+
struct AVAudioConvert {
int in_channels, out_channels;
int fmt_pair;
@@ -114,3 +116,5 @@
}
return 0;
}
+
+#endif /* FF_API_AUDIO_CONVERT */
diff --git a/libavcodec/audioconvert.h b/libavcodec/audioconvert.h
index 61124b3..556ab31 100644
--- a/libavcodec/audioconvert.h
+++ b/libavcodec/audioconvert.h
@@ -26,8 +26,11 @@
/**
* @file
* Audio format conversion routines
+ * This interface is deprecated and will be dropped in a future
+ * version. You should use the libswresample library instead.
*/
+#if FF_API_AUDIO_CONVERT
#include "libavutil/cpu.h"
#include "avcodec.h"
@@ -45,14 +48,20 @@
* @param[in] matrix Channel mixing matrix (of dimension in_channel*out_channels). Set to NULL to ignore.
* @param flags See AV_CPU_FLAG_xx
* @return NULL on error
+ * @deprecated See libswresample
*/
+
+attribute_deprecated
AVAudioConvert *av_audio_convert_alloc(enum AVSampleFormat out_fmt, int out_channels,
enum AVSampleFormat in_fmt, int in_channels,
const float *matrix, int flags);
/**
* Free audio sample format converter context
+ * @deprecated See libswresample
*/
+
+attribute_deprecated
void av_audio_convert_free(AVAudioConvert *ctx);
/**
@@ -62,9 +71,14 @@
* @param[in] in array of input buffers for each channel
* @param[in] in_stride distance between consecutive input samples (measured in bytes)
* @param len length of audio frame size (measured in samples)
+ * @deprecated See libswresample
*/
+
+attribute_deprecated
int av_audio_convert(AVAudioConvert *ctx,
void * const out[6], const int out_stride[6],
const void * const in[6], const int in_stride[6], int len);
+#endif /* FF_API_AUDIO_CONVERT */
+
#endif /* AVCODEC_AUDIOCONVERT_H */
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 2392174..132c4ce 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -42,6 +42,11 @@
#include "version.h"
+#if FF_API_FAST_MALLOC
+// to provide fast_*alloc
+#include "libavutil/mem.h"
+#endif
+
/**
* @defgroup libavc Encoding/Decoding Library
* @{
@@ -105,7 +110,9 @@
/* video codecs */
AV_CODEC_ID_MPEG1VIDEO,
AV_CODEC_ID_MPEG2VIDEO, ///< preferred ID for MPEG-1/2 video decoding
+#if FF_API_XVMC
AV_CODEC_ID_MPEG2VIDEO_XVMC,
+#endif /* FF_API_XVMC */
AV_CODEC_ID_H261,
AV_CODEC_ID_H263,
AV_CODEC_ID_RV10,
@@ -277,6 +284,8 @@
AV_CODEC_ID_ESCAPE130_DEPRECATED,
AV_CODEC_ID_G2M_DEPRECATED,
AV_CODEC_ID_WEBP_DEPRECATED,
+ AV_CODEC_ID_HNM4_VIDEO,
+ AV_CODEC_ID_HEVC_DEPRECATED,
AV_CODEC_ID_BRENDER_PIX= MKBETAG('B','P','I','X'),
AV_CODEC_ID_Y41P = MKBETAG('Y','4','1','P'),
@@ -378,6 +387,7 @@
AV_CODEC_ID_ADPCM_IMA_OKI = MKBETAG('O','K','I',' '),
AV_CODEC_ID_ADPCM_DTK = MKBETAG('D','T','K',' '),
AV_CODEC_ID_ADPCM_IMA_RAD = MKBETAG('R','A','D',' '),
+ AV_CODEC_ID_ADPCM_G726LE = MKBETAG('6','2','7','G'),
/* AMR */
AV_CODEC_ID_AMR_NB = 0x12000,
@@ -626,16 +636,26 @@
AVCOL_PRI_SMPTE170M = 6, ///< also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC
AVCOL_PRI_SMPTE240M = 7, ///< functionally identical to above
AVCOL_PRI_FILM = 8,
+ AVCOL_PRI_BT2020 = 9, ///< ITU-R BT2020
AVCOL_PRI_NB , ///< Not part of ABI
};
enum AVColorTransferCharacteristic{
- AVCOL_TRC_BT709 = 1, ///< also ITU-R BT1361
- AVCOL_TRC_UNSPECIFIED = 2,
- AVCOL_TRC_GAMMA22 = 4, ///< also ITU-R BT470M / ITU-R BT1700 625 PAL & SECAM
- AVCOL_TRC_GAMMA28 = 5, ///< also ITU-R BT470BG
- AVCOL_TRC_SMPTE240M = 7,
- AVCOL_TRC_NB , ///< Not part of ABI
+ AVCOL_TRC_BT709 = 1, ///< also ITU-R BT1361
+ AVCOL_TRC_UNSPECIFIED = 2,
+ AVCOL_TRC_GAMMA22 = 4, ///< also ITU-R BT470M / ITU-R BT1700 625 PAL & SECAM
+ AVCOL_TRC_GAMMA28 = 5, ///< also ITU-R BT470BG
+ AVCOL_TRC_SMPTE170M = 6, ///< also ITU-R BT601-6 525 or 625 / ITU-R BT1358 525 or 625 / ITU-R BT1700 NTSC
+ AVCOL_TRC_SMPTE240M = 7,
+ AVCOL_TRC_LINEAR = 8, ///< "Linear transfer characteristics"
+ AVCOL_TRC_LOG = 9, ///< "Logarithmic transfer characteristic (100:1 range)"
+ AVCOL_TRC_LOG_SQRT = 10, ///< "Logarithmic transfer characteristic (100 * Sqrt( 10 ) : 1 range)"
+ AVCOL_TRC_IEC61966_2_4 = 11, ///< IEC 61966-2-4
+ AVCOL_TRC_BT1361_ECG = 12, ///< ITU-R BT1361 Extended Colour Gamut
+ AVCOL_TRC_IEC61966_2_1 = 13, ///< IEC 61966-2-1 (sRGB or sYCC)
+ AVCOL_TRC_BT2020_10 = 14, ///< ITU-R BT2020 for 10 bit system
+ AVCOL_TRC_BT2020_12 = 15, ///< ITU-R BT2020 for 12 bit system
+ AVCOL_TRC_NB , ///< Not part of ABI
};
/**
@@ -677,7 +697,12 @@
float quality_factor;
} RcOverride;
+#if FF_API_MAX_BFRAMES
+/**
+ * @deprecated there is no libavcodec-wide limit on the number of B-frames
+ */
#define FF_MAX_B_FRAMES 16
+#endif
/* encoding support
These flags can be passed in AVCodecContext.flags before initialization.
@@ -691,6 +716,7 @@
#define CODEC_FLAG_UNALIGNED 0x0001
#define CODEC_FLAG_QSCALE 0x0002 ///< Use fixed qscale.
#define CODEC_FLAG_4MV 0x0004 ///< 4 MV per MB allowed / advanced prediction for H.263.
+#define CODEC_FLAG_OUTPUT_CORRUPT 0x0008 ///< Output even those frames that might be corrupted
#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>.
@@ -741,8 +767,10 @@
*/
#define CODEC_CAP_DR1 0x0002
#define CODEC_CAP_TRUNCATED 0x0008
+#if FF_API_XVMC
/* Codec can export data for HW decoding (XvMC). */
#define CODEC_CAP_HWACCEL 0x0010
+#endif /* FF_API_XVMC */
/**
* Encoder or decoder requires flushing with NULL input at the end in order to
* give the complete and correct output.
@@ -799,12 +827,12 @@
* Codec should fill in channel configuration and samplerate instead of container
*/
#define CODEC_CAP_CHANNEL_CONF 0x0400
-
+#if FF_API_NEG_LINESIZES
/**
- * Codec is able to deal with negative linesizes
+ * @deprecated no codecs use this capability
*/
#define CODEC_CAP_NEG_LINESIZES 0x0800
-
+#endif
/**
* Codec supports frame-level multithreading.
*/
@@ -834,6 +862,7 @@
*/
#define CODEC_CAP_LOSSLESS 0x80000000
+#if FF_API_MB_TYPE
//The following defines may change, don't expect compatibility if you use them.
#define MB_TYPE_INTRA4x4 0x0001
#define MB_TYPE_INTRA16x16 0x0002 //FIXME H.264-specific
@@ -857,6 +886,7 @@
#define MB_TYPE_QUANT 0x00010000
#define MB_TYPE_CBP 0x00020000
//Note bits 24-31 are reserved for codec specific use (h264 ref0, mpeg1 0mv, ...)
+#endif
/**
* Pan Scan area.
@@ -887,10 +917,12 @@
int16_t position[3][2];
}AVPanScan;
+#if FF_API_QSCALE_TYPE
#define FF_QSCALE_TYPE_MPEG1 0
#define FF_QSCALE_TYPE_MPEG2 1
#define FF_QSCALE_TYPE_H264 2
#define FF_QSCALE_TYPE_VP56 3
+#endif
#if FF_API_GET_BUFFER
#define FF_BUFFER_TYPE_INTERNAL 1
@@ -1013,6 +1045,13 @@
* follow the timestamp specifier of a WebVTT cue.
*/
AV_PKT_DATA_WEBVTT_SETTINGS,
+
+ /**
+ * A list of zero terminated key/value strings. There is no end marker for
+ * the list, so it is required to rely on the side data size to stop. This
+ * side data includes updated metadata which appeared in the stream.
+ */
+ AV_PKT_DATA_METADATA_UPDATE,
};
/**
@@ -1325,7 +1364,9 @@
*/
int coded_width, coded_height;
+#if FF_API_ASPECT_EXTENDED
#define FF_ASPECT_EXTENDED 15
+#endif
/**
* the number of pictures in a group of pictures, or 0 for intra_only
@@ -1652,12 +1693,15 @@
#define SLICE_FLAG_ALLOW_FIELD 0x0002 ///< allow draw_horiz_band() with field slices (MPEG2 field pics)
#define SLICE_FLAG_ALLOW_PLANE 0x0004 ///< allow draw_horiz_band() with 1 component at a time (SVQ1)
+#if FF_API_XVMC
/**
* XVideo Motion Acceleration
* - encoding: forbidden
* - decoding: set by decoder
+ * @deprecated XvMC support is slated for removal.
*/
- int xvmc_acceleration;
+ attribute_deprecated int xvmc_acceleration;
+#endif /* FF_API_XVMC */
/**
* macroblock decision mode
@@ -2394,12 +2438,16 @@
*/
int workaround_bugs;
#define FF_BUG_AUTODETECT 1 ///< autodetection
+#if FF_API_OLD_MSMPEG4
#define FF_BUG_OLD_MSMPEG4 2
+#endif
#define FF_BUG_XVID_ILACE 4
#define FF_BUG_UMP4 8
#define FF_BUG_NO_PADDING 16
#define FF_BUG_AMV 32
+#if FF_API_AC_VLC
#define FF_BUG_AC_VLC 0 ///< Will be removed, libavcodec can now handle these non-compliant files by default.
+#endif
#define FF_BUG_QPEL_CHROMA 64
#define FF_BUG_STD_QPEL 128
#define FF_BUG_QPEL_CHROMA2 256
@@ -2449,7 +2497,12 @@
#define FF_DEBUG_BITSTREAM 4
#define FF_DEBUG_MB_TYPE 8
#define FF_DEBUG_QP 16
+#if FF_API_DEBUG_MV
+/**
+ * @deprecated this option does nothing
+ */
#define FF_DEBUG_MV 32
+#endif
#define FF_DEBUG_DCT_COEFF 0x00000040
#define FF_DEBUG_SKIP 0x00000080
#define FF_DEBUG_STARTCODE 0x00000100
@@ -2457,13 +2510,17 @@
#define FF_DEBUG_ER 0x00000400
#define FF_DEBUG_MMCO 0x00000800
#define FF_DEBUG_BUGS 0x00001000
-#define FF_DEBUG_VIS_QP 0x00002000
-#define FF_DEBUG_VIS_MB_TYPE 0x00004000
+#if FF_API_DEBUG_MV
+#define FF_DEBUG_VIS_QP 0x00002000 ///< only access through AVOptions from outside libavcodec
+#define FF_DEBUG_VIS_MB_TYPE 0x00004000 ///< only access through AVOptions from outside libavcodec
+#endif
#define FF_DEBUG_BUFFERS 0x00008000
#define FF_DEBUG_THREADS 0x00010000
+#if FF_API_DEBUG_MV
/**
* debug
+ * Code outside libavcodec should access this field using AVOptions
* - encoding: Set by user.
* - decoding: Set by user.
*/
@@ -2471,6 +2528,7 @@
#define FF_DEBUG_VIS_MV_P_FOR 0x00000001 //visualize forward predicted MVs of P frames
#define FF_DEBUG_VIS_MV_B_FOR 0x00000002 //visualize forward predicted MVs of B frames
#define FF_DEBUG_VIS_MV_B_BACK 0x00000004 //visualize backward predicted MVs of B frames
+#endif
/**
* Error recognition; may misdetect some more or less valid parts as errors.
@@ -2478,14 +2536,21 @@
* - 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)
-#define AV_EF_CAREFUL (1<<16)
-#define AV_EF_COMPLIANT (1<<17)
-#define AV_EF_AGGRESSIVE (1<<18)
+/**
+ * Verify checksums embedded in the bitstream (could be of either encoded or
+ * decoded data, depending on the codec) and print an error message on mismatch.
+ * If AV_EF_EXPLODE is also set, a mismatching checksum will result in the
+ * decoder returning an error.
+ */
+#define AV_EF_CRCCHECK (1<<0)
+#define AV_EF_BITSTREAM (1<<1) ///< detect bitstream specification deviations
+#define AV_EF_BUFFER (1<<2) ///< detect improper bitstream length
+#define AV_EF_EXPLODE (1<<3) ///< abort decoding on minor error detection
+
+#define AV_EF_CAREFUL (1<<16) ///< consider things that violate the spec, are fast to calculate and have not been seen in the wild as errors
+#define AV_EF_COMPLIANT (1<<17) ///< consider all spec non compliancies as errors
+#define AV_EF_AGGRESSIVE (1<<18) ///< consider things that a sane encoder should not do as an error
/**
@@ -2557,7 +2622,9 @@
#define FF_IDCT_SIMPLEVIS 18
#define FF_IDCT_FAAN 20
#define FF_IDCT_SIMPLENEON 22
+#if FF_API_ARCH_ALPHA
#define FF_IDCT_SIMPLEALPHA 23
+#endif
/**
* bits per sample/pixel from the demuxer (needed for huffyuv).
@@ -2587,7 +2654,7 @@
/**
* the picture in the bitstream
* - encoding: Set by libavcodec.
- * - decoding: Set by libavcodec.
+ * - decoding: unused
*/
AVFrame *coded_frame;
@@ -2659,13 +2726,13 @@
*/
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_THREAD_OPAQUE
/**
- * thread opaque
- * Can be used by execute() to store some per AVCodecContext stuff.
- * - encoding: set by execute()
- * - decoding: set by execute()
+ * @deprecated this field should not be used from outside of lavc
*/
+ attribute_deprecated
void *thread_opaque;
+#endif
/**
* noise vs. sse weight for the nsse comparsion function
@@ -2752,6 +2819,11 @@
#define FF_PROFILE_JPEG2000_DCINEMA_2K 3
#define FF_PROFILE_JPEG2000_DCINEMA_4K 4
+
+#define FF_PROFILE_HEVC_MAIN 1
+#define FF_PROFILE_HEVC_MAIN_10 2
+#define FF_PROFILE_HEVC_MAIN_STILL_PICTURE 3
+
/**
* level
* - encoding: Set by user.
@@ -2792,21 +2864,22 @@
uint8_t *subtitle_header;
int subtitle_header_size;
+#if FF_API_ERROR_RATE
/**
- * Simulates errors in the bitstream to test error concealment.
- * - encoding: Set by user.
- * - decoding: unused
+ * @deprecated use the 'error_rate' private AVOption of the mpegvideo
+ * encoders
*/
+ attribute_deprecated
int error_rate;
+#endif
+#if FF_API_CODEC_PKT
/**
- * Current packet as passed into the decoder, to avoid having
- * to pass the packet into every function. Currently only valid
- * inside lavc and get/release_buffer callbacks.
- * - decoding: set by avcodec_decode_*, read by get_buffer() for setting pkt_pts
- * - encoding: unused
+ * @deprecated this field is not supposed to be accessed from outside lavc
*/
+ attribute_deprecated
AVPacket *pkt;
+#endif
/**
* VBV delay coded in the last frame (in periods of a 27 MHz clock).
@@ -2894,6 +2967,19 @@
* - encoding: set by libavcodec
*/
int seek_preroll;
+
+#if !FF_API_DEBUG_MV
+ /**
+ * debug motion vectors
+ * Code outside libavcodec should access this field using AVOptions
+ * - encoding: Set by user.
+ * - decoding: Set by user.
+ */
+ int debug_mv;
+#define FF_DEBUG_VIS_MV_P_FOR 0x00000001 //visualize forward predicted MVs of P frames
+#define FF_DEBUG_VIS_MV_B_FOR 0x00000002 //visualize forward predicted MVs of B frames
+#define FF_DEBUG_VIS_MV_B_BACK 0x00000004 //visualize backward predicted MVs of B frames
+#endif
} AVCodecContext;
AVRational av_codec_get_pkt_timebase (const AVCodecContext *avctx);
@@ -3230,40 +3316,6 @@
*/
void avcodec_register_all(void);
-
-#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);
-
-/**
- * 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
-
/**
* Allocate an AVCodecContext and set its fields to default values. The
* resulting struct can be deallocated by calling avcodec_close() on it followed
@@ -3329,14 +3381,13 @@
*/
int avcodec_copy_context(AVCodecContext *dest, const AVCodecContext *src);
+#if FF_API_AVFRAME_LAVC
/**
- * Allocate an AVFrame and set its fields to default values. The resulting
- * struct must be freed using avcodec_free_frame().
- *
- * @return An AVFrame filled with default values or NULL on failure.
- * @see avcodec_get_frame_defaults
+ * @deprecated use av_frame_alloc()
*/
+attribute_deprecated
AVFrame *avcodec_alloc_frame(void);
+#endif
/**
* Set the fields of the given AVFrame to default values.
@@ -3357,40 +3408,6 @@
*/
void avcodec_free_frame(AVFrame **frame);
-#if FF_API_AVCODEC_OPEN
-/**
- * Initialize the AVCodecContext to use the given AVCodec. Prior to using this
- * function the context has to be allocated.
- *
- * The functions avcodec_find_decoder_by_name(), avcodec_find_encoder_by_name(),
- * avcodec_find_decoder() and avcodec_find_encoder() provide an easy way for
- * retrieving a codec.
- *
- * @warning This function is not thread safe!
- *
- * @code
- * avcodec_register_all();
- * codec = avcodec_find_decoder(AV_CODEC_ID_H264);
- * if (!codec)
- * exit(1);
- *
- * context = avcodec_alloc_context3(codec);
- *
- * if (avcodec_open(context, codec) < 0)
- * exit(1);
- * @endcode
- *
- * @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_context3, avcodec_find_decoder, avcodec_find_encoder, avcodec_close
- *
- * @deprecated use avcodec_open2
- */
-attribute_deprecated
-int avcodec_open(AVCodecContext *avctx, AVCodec *codec);
-#endif
-
/**
* Initialize the AVCodecContext to use the given AVCodec. Prior to using this
* function the context has to be allocated with avcodec_alloc_context3().
@@ -3581,6 +3598,24 @@
int av_packet_split_side_data(AVPacket *pkt);
+/**
+ * Pack a dictionary for use in side_data.
+ *
+ * @param dict The dictionary to pack.
+ * @param size pointer to store the size of the returned data
+ * @return pointer to data if successful, NULL otherwise
+ */
+uint8_t *av_packet_pack_dictionary(AVDictionary *dict, int *size);
+/**
+ * Unpack a dictionary from side_data.
+ *
+ * @param data data from side_data
+ * @param size size of the data
+ * @param dict the metadata storage dictionary
+ * @return 0 on success, < 0 on failure
+ */
+int av_packet_unpack_dictionary(const uint8_t *data, int size, AVDictionary **dict);
+
/**
* Convenience function to free all the side data stored.
@@ -3899,6 +3934,14 @@
* and reusing a get_buffer written for video codecs would probably perform badly
* due to a potentially very different allocation pattern.
*
+ * Some decoders (those marked with CODEC_CAP_DELAY) have a delay between input
+ * and output. This means that for some packets they will not immediately
+ * produce decoded output and need to be flushed at the end of decoding to get
+ * all the decoded data. Flushing is done by calling this function with packets
+ * with avpkt->data set to NULL and avpkt->size set to 0 until it stops
+ * returning subtitles. It is safe to flush even those decoders that are not
+ * marked with CODEC_CAP_DELAY, then no subtitles will be returned.
+ *
* @param avctx the codec context
* @param[out] sub The AVSubtitle in which the decoded subtitle will be stored, must be
freed with avsubtitle_free if *got_sub_ptr is set.
@@ -4663,7 +4706,13 @@
* @}
*/
+#if FF_API_SET_DIMENSIONS
+/**
+ * @deprecated this function is not supposed to be used from outside of lavc
+ */
+attribute_deprecated
void avcodec_set_dimensions(AVCodecContext *s, int width, int height);
+#endif
/**
* Put a string representing the codec tag codec_tag in buf.
@@ -4860,27 +4909,6 @@
/* memory */
/**
- * Reallocate the given block if it is not large enough, otherwise do nothing.
- *
- * @see av_realloc
- */
-void *av_fast_realloc(void *ptr, unsigned int *size, size_t min_size);
-
-/**
- * Allocate a buffer, reusing the given one if large enough.
- *
- * Contrary to av_fast_realloc the current buffer contents might not be
- * preserved and on error the old buffer is freed, thus no special
- * handling to avoid memleaks is necessary.
- *
- * @param ptr pointer to pointer to already allocated buffer, overwritten with pointer to new buffer
- * @param size size of the buffer *ptr points to
- * @param min_size minimum size of *ptr buffer after returning, *ptr will be NULL and
- * *size 0 if an error occurred.
- */
-void av_fast_malloc(void *ptr, unsigned int *size, size_t min_size);
-
-/**
* Same behaviour av_fast_malloc but the buffer has additional
* FF_INPUT_BUFFER_PADDING_SIZE at the end which will always be 0.
*
diff --git a/libavcodec/avcodecres.rc b/libavcodec/avcodecres.rc
new file mode 100644
index 0000000..4b69686
--- /dev/null
+++ b/libavcodec/avcodecres.rc
@@ -0,0 +1,55 @@
+/*
+ * Windows resource file for libavcodec
+ *
+ * Copyright (C) 2012 James Almer
+ * Copyright (C) 2013 Tiancheng "Timothy" Gu
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <windows.h>
+#include "libavcodec/version.h"
+#include "libavutil/ffversion.h"
+#include "config.h"
+
+1 VERSIONINFO
+FILEVERSION LIBAVCODEC_VERSION_MAJOR, LIBAVCODEC_VERSION_MINOR, LIBAVCODEC_VERSION_MICRO, 0
+PRODUCTVERSION LIBAVCODEC_VERSION_MAJOR, LIBAVCODEC_VERSION_MINOR, LIBAVCODEC_VERSION_MICRO, 0
+FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+FILEOS VOS_NT_WINDOWS32
+FILETYPE VFT_DLL
+{
+ BLOCK "StringFileInfo"
+ {
+ BLOCK "040904B0"
+ {
+ VALUE "CompanyName", "FFmpeg Project"
+ VALUE "FileDescription", "FFmpeg codec library"
+ VALUE "FileVersion", AV_STRINGIFY(LIBAVCODEC_VERSION)
+ VALUE "InternalName", "libavcodec"
+ VALUE "LegalCopyright", "Copyright (C) 2000-" AV_STRINGIFY(CONFIG_THIS_YEAR) " FFmpeg Project"
+ VALUE "OriginalFilename", "avcodec" BUILDSUF "-" AV_STRINGIFY(LIBAVCODEC_VERSION_MAJOR) SLIBSUF
+ VALUE "ProductName", "FFmpeg"
+ VALUE "ProductVersion", FFMPEG_VERSION
+ }
+ }
+
+ BLOCK "VarFileInfo"
+ {
+ VALUE "Translation", 0x0409, 0x04B0
+ }
+}
diff --git a/libavcodec/avpacket.c b/libavcodec/avpacket.c
index bee159d..f966bfe 100644
--- a/libavcodec/avpacket.c
+++ b/libavcodec/avpacket.c
@@ -237,6 +237,7 @@
pkt->side_data[i].type = src->side_data[i].type;
}
}
+ pkt->side_data_elems = src->side_data_elems;
return 0;
failed_alloc:
@@ -380,7 +381,7 @@
int av_packet_split_side_data(AVPacket *pkt){
if (!pkt->side_data_elems && pkt->size >12 && AV_RB64(pkt->data + pkt->size - 8) == FF_MERGE_MARKER){
int i;
- unsigned int size, orig_pktsize = pkt->size;
+ unsigned int size;
uint8_t *p;
p = pkt->data + pkt->size - 8 - 5;
@@ -401,7 +402,7 @@
for (i=0; ; i++){
size= AV_RB32(p);
av_assert0(size<=INT_MAX && p - pkt->data >= size);
- pkt->side_data[i].data = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE);
+ pkt->side_data[i].data = av_mallocz(size + FF_INPUT_BUFFER_PADDING_SIZE);
pkt->side_data[i].size = size;
pkt->side_data[i].type = p[4]&127;
if (!pkt->side_data[i].data)
@@ -413,19 +414,72 @@
p-= size+5;
}
pkt->size -= 8;
- /* FFMIN() prevents overflow in case the packet wasn't allocated with
- * proper padding.
- * If the side data is smaller than the buffer padding size, the
- * remaining bytes should have already been filled with zeros by the
- * original packet allocation anyway. */
- memset(pkt->data + pkt->size, 0,
- FFMIN(orig_pktsize - pkt->size, FF_INPUT_BUFFER_PADDING_SIZE));
pkt->side_data_elems = i+1;
return 1;
}
return 0;
}
+uint8_t *av_packet_pack_dictionary(AVDictionary *dict, int *size)
+{
+ AVDictionaryEntry *t = NULL;
+ uint8_t *data = NULL;
+ *size = 0;
+
+ if (!dict)
+ return NULL;
+
+ while ((t = av_dict_get(dict, "", t, AV_DICT_IGNORE_SUFFIX))) {
+ const size_t keylen = strlen(t->key);
+ const size_t valuelen = strlen(t->value);
+ const size_t new_size = *size + keylen + 1 + valuelen + 1;
+ uint8_t *const new_data = av_realloc(data, new_size);
+
+ if (!new_data)
+ goto fail;
+ data = new_data;
+ if (new_size > INT_MAX)
+ goto fail;
+
+ memcpy(data + *size, t->key, keylen + 1);
+ memcpy(data + *size + keylen + 1, t->value, valuelen + 1);
+
+ *size = new_size;
+ }
+
+ return data;
+
+fail:
+ av_freep(&data);
+ *size = 0;
+ return NULL;
+}
+
+int av_packet_unpack_dictionary(const uint8_t *data, int size, AVDictionary **dict)
+{
+ const uint8_t *end = data + size;
+ int ret = 0;
+
+ if (!dict || !data || !size)
+ return ret;
+ if (size && end[-1])
+ return AVERROR_INVALIDDATA;
+ while (data < end) {
+ const uint8_t *key = data;
+ const uint8_t *val = data + strlen(key) + 1;
+
+ if (val >= end)
+ return AVERROR_INVALIDDATA;
+
+ ret = av_dict_set(dict, key, val, 0);
+ if (ret < 0)
+ break;
+ data = val + strlen(val) + 1;
+ }
+
+ return ret;
+}
+
int av_packet_shrink_side_data(AVPacket *pkt, enum AVPacketSideDataType type,
int size)
{
diff --git a/libavcodec/avs.c b/libavcodec/avs.c
index 065345b..c4eaf20 100644
--- a/libavcodec/avs.c
+++ b/libavcodec/avs.c
@@ -25,7 +25,7 @@
typedef struct {
- AVFrame picture;
+ AVFrame *frame;
} AvsContext;
typedef enum {
@@ -52,7 +52,7 @@
int buf_size = avpkt->size;
AvsContext *const avs = avctx->priv_data;
AVFrame *picture = data;
- AVFrame *const p = &avs->picture;
+ AVFrame *const p = avs->frame;
const uint8_t *table, *vect;
uint8_t *out;
int i, j, x, y, stride, ret, vect_w = 3, vect_h = 3;
@@ -65,8 +65,8 @@
p->pict_type = AV_PICTURE_TYPE_P;
p->key_frame = 0;
- out = avs->picture.data[0];
- stride = avs->picture.linesize[0];
+ out = p->data[0];
+ stride = p->linesize[0];
if (buf_end - buf < 4)
return AVERROR_INVALIDDATA;
@@ -76,7 +76,7 @@
if (type == AVS_PALETTE) {
int first, last;
- uint32_t *pal = (uint32_t *) avs->picture.data[1];
+ uint32_t *pal = (uint32_t *) p->data[1];
first = AV_RL16(buf);
last = first + AV_RL16(buf + 2);
@@ -149,7 +149,7 @@
align_get_bits(&change_map);
}
- if ((ret = av_frame_ref(picture, &avs->picture)) < 0)
+ if ((ret = av_frame_ref(picture, p)) < 0)
return ret;
*got_frame = 1;
@@ -159,16 +159,21 @@
static av_cold int avs_decode_init(AVCodecContext * avctx)
{
AvsContext *s = avctx->priv_data;
+
+ s->frame = av_frame_alloc();
+ if (!s->frame)
+ return AVERROR(ENOMEM);
+
avctx->pix_fmt = AV_PIX_FMT_PAL8;
- avcodec_set_dimensions(avctx, 318, 198);
- avcodec_get_frame_defaults(&s->picture);
+ ff_set_dimensions(avctx, 318, 198);
+
return 0;
}
static av_cold int avs_decode_end(AVCodecContext *avctx)
{
AvsContext *s = avctx->priv_data;
- av_frame_unref(&s->picture);
+ av_frame_free(&s->frame);
return 0;
}
diff --git a/libavcodec/avuienc.c b/libavcodec/avuienc.c
index 9276935..eb0046c 100644
--- a/libavcodec/avuienc.c
+++ b/libavcodec/avuienc.c
@@ -25,7 +25,7 @@
static av_cold int avui_encode_init(AVCodecContext *avctx)
{
- avctx->coded_frame = avcodec_alloc_frame();
+ avctx->coded_frame = av_frame_alloc();
if (avctx->width != 720 || avctx->height != 486 && avctx->height != 576) {
av_log(avctx, AV_LOG_ERROR, "Only 720x486 and 720x576 are supported.\n");
diff --git a/libavcodec/bethsoftvideo.c b/libavcodec/bethsoftvideo.c
index 71d111f..37cd22e 100644
--- a/libavcodec/bethsoftvideo.c
+++ b/libavcodec/bethsoftvideo.c
@@ -34,21 +34,25 @@
#include "internal.h"
typedef struct BethsoftvidContext {
- AVFrame frame;
+ AVFrame *frame;
GetByteContext g;
} BethsoftvidContext;
static av_cold int bethsoftvid_decode_init(AVCodecContext *avctx)
{
BethsoftvidContext *vid = avctx->priv_data;
- avcodec_get_frame_defaults(&vid->frame);
avctx->pix_fmt = AV_PIX_FMT_PAL8;
+
+ vid->frame = av_frame_alloc();
+ if (!vid->frame)
+ return AVERROR(ENOMEM);
+
return 0;
}
static int set_palette(BethsoftvidContext *ctx)
{
- uint32_t *palette = (uint32_t *)ctx->frame.data[1];
+ uint32_t *palette = (uint32_t *)ctx->frame->data[1];
int a;
if (bytestream2_get_bytes_left(&ctx->g) < 256*3)
@@ -58,7 +62,7 @@
palette[a] = 0xFFU << 24 | bytestream2_get_be24u(&ctx->g) * 4;
palette[a] |= palette[a] >> 6 & 0x30303;
}
- ctx->frame.palette_has_changed = 1;
+ ctx->frame->palette_has_changed = 1;
return 0;
}
@@ -75,9 +79,9 @@
int code, ret;
int yoffset;
- if ((ret = ff_reget_buffer(avctx, &vid->frame)) < 0)
+ if ((ret = ff_reget_buffer(avctx, vid->frame)) < 0)
return ret;
- wrap_to_next_line = vid->frame.linesize[0] - avctx->width;
+ wrap_to_next_line = vid->frame->linesize[0] - avctx->width;
if (avpkt->side_data_elems > 0 &&
avpkt->side_data[0].type == AV_PKT_DATA_PALETTE) {
@@ -88,8 +92,8 @@
}
bytestream2_init(&vid->g, avpkt->data, avpkt->size);
- dst = vid->frame.data[0];
- frame_end = vid->frame.data[0] + vid->frame.linesize[0] * avctx->height;
+ dst = vid->frame->data[0];
+ frame_end = vid->frame->data[0] + vid->frame->linesize[0] * avctx->height;
switch(block_type = bytestream2_get_byte(&vid->g)){
case PALETTE_BLOCK: {
@@ -104,7 +108,7 @@
yoffset = bytestream2_get_le16(&vid->g);
if(yoffset >= avctx->height)
return AVERROR_INVALIDDATA;
- dst += vid->frame.linesize[0] * yoffset;
+ dst += vid->frame->linesize[0] * yoffset;
}
// main code
@@ -134,7 +138,7 @@
}
end:
- if ((ret = av_frame_ref(data, &vid->frame)) < 0)
+ if ((ret = av_frame_ref(data, vid->frame)) < 0)
return ret;
*got_frame = 1;
@@ -145,7 +149,7 @@
static av_cold int bethsoftvid_decode_end(AVCodecContext *avctx)
{
BethsoftvidContext * vid = avctx->priv_data;
- av_frame_unref(&vid->frame);
+ av_frame_free(&vid->frame);
return 0;
}
diff --git a/libavcodec/bink.c b/libavcodec/bink.c
index 8878694..8f8a036 100644
--- a/libavcodec/bink.c
+++ b/libavcodec/bink.c
@@ -120,6 +120,7 @@
int version; ///< internal Bink file version
int has_alpha;
int swap_planes;
+ unsigned frame_num;
Bundle bundle[BINKB_NB_SRC]; ///< bundles for decoding all data types
Tree col_high[16]; ///< trees for decoding high nibble in "colours" data type
@@ -1206,6 +1207,8 @@
if (c->version >= 'i')
skip_bits_long(&gb, 32);
+ c->frame_num++;
+
for (plane = 0; plane < 3; plane++) {
plane_idx = (!plane || !c->swap_planes) ? plane : (plane ^ 3);
@@ -1214,7 +1217,7 @@
return ret;
} else {
if ((ret = binkb_decode_plane(c, frame, &gb, plane_idx,
- !avctx->frame_number, !!plane)) < 0)
+ c->frame_num == 1, !!plane)) < 0)
return ret;
}
if (get_bits_count(&gb) >= bits_count)
@@ -1332,6 +1335,13 @@
return 0;
}
+static void flush(AVCodecContext *avctx)
+{
+ BinkContext * const c = avctx->priv_data;
+
+ c->frame_num = 0;
+}
+
AVCodec ff_bink_decoder = {
.name = "binkvideo",
.long_name = NULL_IF_CONFIG_SMALL("Bink video"),
@@ -1341,5 +1351,6 @@
.init = decode_init,
.close = decode_end,
.decode = decode_frame,
+ .flush = flush,
.capabilities = CODEC_CAP_DR1,
};
diff --git a/libavcodec/binkaudio.c b/libavcodec/binkaudio.c
index b7ad418..8db4533 100644
--- a/libavcodec/binkaudio.c
+++ b/libavcodec/binkaudio.c
@@ -308,7 +308,8 @@
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);
+ if ((ret = init_get_bits8(gb, s->packet_buffer, avpkt->size)) < 0)
+ return ret;
consumed = avpkt->size;
/* skip reported size */
diff --git a/libavcodec/bitstream.c b/libavcodec/bitstream.c
index 299ee23..1a34626 100644
--- a/libavcodec/bitstream.c
+++ b/libavcodec/bitstream.c
@@ -108,12 +108,16 @@
vlc->table_size += size;
if (vlc->table_size > vlc->table_allocated) {
+ int err;
if (use_static)
abort(); // cannot do anything, init_vlc() is used with too little memory
vlc->table_allocated += (1 << vlc->bits);
vlc->table = av_realloc_f(vlc->table, vlc->table_allocated, sizeof(VLC_TYPE) * 2);
- if (!vlc->table)
+ if (!vlc->table) {
+ vlc->table_allocated = 0;
+ vlc->table_size = 0;
return AVERROR(ENOMEM);
+ }
}
return index;
}
diff --git a/libavcodec/bmpenc.c b/libavcodec/bmpenc.c
index ad02a6b..2a1956d 100644
--- a/libavcodec/bmpenc.c
+++ b/libavcodec/bmpenc.c
@@ -60,22 +60,26 @@
return AVERROR(EINVAL);
}
+ avctx->coded_frame = av_frame_alloc();
+ if (!avctx->coded_frame)
+ return AVERROR(ENOMEM);
+
return 0;
}
static int bmp_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
const AVFrame *pict, int *got_packet)
{
+ const AVFrame * const p = pict;
int n_bytes_image, n_bytes_per_row, n_bytes, i, n, hsize, ret;
const uint32_t *pal = NULL;
uint32_t palette256[256];
int pad_bytes_per_row, pal_entries = 0, compression = BMP_RGB;
int bit_count = avctx->bits_per_coded_sample;
uint8_t *ptr, *buf;
- AVFrame * const p = (AVFrame *)pict;
- p->pict_type= AV_PICTURE_TYPE_I;
- p->key_frame= 1;
+ avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
+ avctx->coded_frame->key_frame = 1;
switch (avctx->pix_fmt) {
case AV_PIX_FMT_RGB444:
compression = BMP_BITFIELDS;
@@ -159,6 +163,12 @@
return 0;
}
+static av_cold int bmp_encode_close(AVCodecContext *avctx)
+{
+ av_frame_free(&avctx->coded_frame);
+ return 0;
+}
+
AVCodec ff_bmp_encoder = {
.name = "bmp",
.long_name = NULL_IF_CONFIG_SMALL("BMP (Windows and OS/2 bitmap)"),
@@ -166,6 +176,7 @@
.id = AV_CODEC_ID_BMP,
.init = bmp_encode_init,
.encode2 = bmp_encode_frame,
+ .close = bmp_encode_close,
.pix_fmts = (const enum AVPixelFormat[]){
AV_PIX_FMT_BGRA, AV_PIX_FMT_BGR24,
AV_PIX_FMT_RGB565, AV_PIX_FMT_RGB555, AV_PIX_FMT_RGB444,
diff --git a/libavcodec/brender_pix.c b/libavcodec/brender_pix.c
index e1f5d48..23a46cc 100644
--- a/libavcodec/brender_pix.c
+++ b/libavcodec/brender_pix.c
@@ -128,11 +128,8 @@
return AVERROR_PATCHWELCOME;
}
- if (av_image_check_size(hdr.width, hdr.height, 0, avctx) < 0)
- return AVERROR_INVALIDDATA;
-
- if (hdr.width != avctx->width || hdr.height != avctx->height)
- avcodec_set_dimensions(avctx, hdr.width, hdr.height);
+ if ((ret = ff_set_dimensions(avctx, hdr.width, hdr.height)) < 0)
+ return ret;
if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
return ret;
diff --git a/libavcodec/c93.c b/libavcodec/c93.c
index f25368b..ad3fa3b 100644
--- a/libavcodec/c93.c
+++ b/libavcodec/c93.c
@@ -24,7 +24,7 @@
#include "internal.h"
typedef struct {
- AVFrame pictures[2];
+ AVFrame *pictures[2];
int currentpic;
} C93DecoderContext;
@@ -46,21 +46,27 @@
#define C93_HAS_PALETTE 0x01
#define C93_FIRST_FRAME 0x02
-static av_cold int decode_init(AVCodecContext *avctx)
-{
- C93DecoderContext *s = avctx->priv_data;
- avctx->pix_fmt = AV_PIX_FMT_PAL8;
- avcodec_get_frame_defaults(&s->pictures[0]);
- avcodec_get_frame_defaults(&s->pictures[1]);
- return 0;
-}
-
static av_cold int decode_end(AVCodecContext *avctx)
{
C93DecoderContext * const c93 = avctx->priv_data;
- av_frame_unref(&c93->pictures[0]);
- av_frame_unref(&c93->pictures[1]);
+ av_frame_free(&c93->pictures[0]);
+ av_frame_free(&c93->pictures[1]);
+
+ return 0;
+}
+
+static av_cold int decode_init(AVCodecContext *avctx)
+{
+ C93DecoderContext *s = avctx->priv_data;
+ avctx->pix_fmt = AV_PIX_FMT_PAL8;
+
+ s->pictures[0] = av_frame_alloc();
+ s->pictures[1] = av_frame_alloc();
+ if (!s->pictures[0] || !s->pictures[1]) {
+ decode_end(avctx);
+ return AVERROR(ENOMEM);
+ }
return 0;
}
@@ -121,13 +127,14 @@
const uint8_t *buf = avpkt->data;
int buf_size = avpkt->size;
C93DecoderContext * const c93 = avctx->priv_data;
- AVFrame * const newpic = &c93->pictures[c93->currentpic];
- AVFrame * const oldpic = &c93->pictures[c93->currentpic^1];
+ AVFrame * const newpic = c93->pictures[c93->currentpic];
+ AVFrame * const oldpic = c93->pictures[c93->currentpic^1];
GetByteContext gb;
uint8_t *out;
int stride, ret, i, x, y, b, bt = 0;
- avcodec_set_dimensions(avctx, WIDTH, HEIGHT);
+ if ((ret = ff_set_dimensions(avctx, WIDTH, HEIGHT)) < 0)
+ return ret;
c93->currentpic ^= 1;
diff --git a/libavcodec/cabac.c b/libavcodec/cabac.c
index 29b188b..dff0a91 100644
--- a/libavcodec/cabac.c
+++ b/libavcodec/cabac.c
@@ -301,7 +301,7 @@
for(i=0; i<SIZE; i++){
START_TIMER
- if( (r[i]&1) != get_cabac(&c, state) )
+ if( (r[i]&1) != get_cabac_noinline(&c, state) )
av_log(NULL, AV_LOG_ERROR, "CABAC failure at %d\n", i);
STOP_TIMER("get_cabac")
}
diff --git a/libavcodec/cabac_functions.h b/libavcodec/cabac_functions.h
index 8a7275d..7e22064 100644
--- a/libavcodec/cabac_functions.h
+++ b/libavcodec/cabac_functions.h
@@ -49,7 +49,10 @@
c->low+= c->bytestream[0]<<1;
#endif
c->low -= CABAC_MASK;
- c->bytestream += CABAC_BITS / 8;
+#if !UNCHECKED_BITSTREAM_READER
+ if (c->bytestream < c->bytestream_end)
+#endif
+ c->bytestream += CABAC_BITS / 8;
}
static inline void renorm_cabac_decoder_once(CABACContext *c){
@@ -76,7 +79,10 @@
#endif
c->low += x<<i;
- c->bytestream += CABAC_BITS/8;
+#if !UNCHECKED_BITSTREAM_READER
+ if (c->bytestream < c->bytestream_end)
+#endif
+ c->bytestream += CABAC_BITS/8;
}
static av_always_inline int get_cabac_inline(CABACContext *c, uint8_t * const state){
@@ -160,4 +166,24 @@
}
}
+/**
+ * Skip @p n bytes and reset the decoder.
+ * @return the address of the first skipped byte or NULL if there's less than @p n bytes left
+ */
+static av_unused const uint8_t* skip_bytes(CABACContext *c, int n) {
+ const uint8_t *ptr = c->bytestream;
+
+ if (c->low & 0x1)
+ ptr--;
+#if CABAC_BITS == 16
+ if (c->low & 0x1FF)
+ ptr--;
+#endif
+ if ((int) (c->bytestream_end - ptr) < n)
+ return NULL;
+ ff_init_cabac_decoder(c, ptr + n, c->bytestream_end - ptr - n);
+
+ return ptr;
+}
+
#endif /* AVCODEC_CABAC_FUNCTIONS_H */
diff --git a/libavcodec/cavs.c b/libavcodec/cavs.c
index 13e32f2..cc54429 100644
--- a/libavcodec/cavs.c
+++ b/libavcodec/cavs.c
@@ -33,28 +33,28 @@
#include "cavs.h"
static const uint8_t alpha_tab[64] = {
- 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 3, 3,
- 4, 4, 5, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 16, 18, 20,
- 22, 24, 26, 28, 30, 33, 33, 35, 35, 36, 37, 37, 39, 39, 42, 44,
- 46, 48, 50, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64
+ 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 3, 3,
+ 4, 4, 5, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 16, 18, 20,
+ 22, 24, 26, 28, 30, 33, 33, 35, 35, 36, 37, 37, 39, 39, 42, 44,
+ 46, 48, 50, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64
};
static const uint8_t beta_tab[64] = {
- 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2,
- 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6,
- 6, 7, 7, 7, 8, 8, 8, 9, 9, 10, 10, 11, 11, 12, 13, 14,
- 15, 16, 17, 18, 19, 20, 21, 22, 23, 23, 24, 24, 25, 25, 26, 27
+ 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2,
+ 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6,
+ 6, 7, 7, 7, 8, 8, 8, 9, 9, 10, 10, 11, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 23, 24, 24, 25, 25, 26, 27
};
static const uint8_t tc_tab[64] = {
- 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, 2, 2,
- 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4,
- 5, 5, 5, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9
+ 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, 2, 2,
+ 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4,
+ 5, 5, 5, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9
};
/** mark block as unavailable, i.e. out of picture
- or not yet decoded */
+ * or not yet decoded */
static const cavs_vector un_mv = { 0, 0, 1, NOT_AVAIL };
static const int8_t left_modifier_l[8] = { 0, -1, 6, -1, -1, 7, 6, 7 };
@@ -126,7 +126,7 @@
/* determine bs */
if (mb_type == I_8X8)
memset(bs, 2, 8);
- else{
+ else {
memset(bs, 0, 8);
if (ff_cavs_partition_flags[mb_type] & SPLITV) {
bs[2] = get_bs(&h->mv[MV_FWD_X0], &h->mv[MV_FWD_X1], mb_type > P_8X8);
@@ -229,31 +229,30 @@
void ff_cavs_load_intra_pred_chroma(AVSContext *h)
{
/* extend borders by one pixel */
- h->left_border_u[9] = h->left_border_u[8];
- h->left_border_v[9] = h->left_border_v[8];
+ h->left_border_u[9] = h->left_border_u[8];
+ h->left_border_v[9] = h->left_border_v[8];
h->top_border_u[h->mbx * 10 + 9] = h->top_border_u[h->mbx * 10 + 8];
h->top_border_v[h->mbx * 10 + 9] = h->top_border_v[h->mbx * 10 + 8];
if (h->mbx && h->mby) {
h->top_border_u[h->mbx * 10] = h->left_border_u[0] = h->topleft_border_u;
h->top_border_v[h->mbx * 10] = h->left_border_v[0] = h->topleft_border_v;
} else {
- h->left_border_u[0] = h->left_border_u[1];
- h->left_border_v[0] = h->left_border_v[1];
+ h->left_border_u[0] = h->left_border_u[1];
+ h->left_border_v[0] = h->left_border_v[1];
h->top_border_u[h->mbx * 10] = h->top_border_u[h->mbx * 10 + 1];
h->top_border_v[h->mbx * 10] = h->top_border_v[h->mbx * 10 + 1];
}
}
-static void intra_pred_vert(uint8_t *d,uint8_t *top,uint8_t *left,int stride)
+static void intra_pred_vert(uint8_t *d, uint8_t *top, uint8_t *left, int stride)
{
int y;
uint64_t a = AV_RN64(&top[1]);
- for (y = 0; y < 8; y++) {
+ for (y = 0; y < 8; y++)
*((uint64_t *)(d + y * stride)) = a;
- }
}
-static void intra_pred_horiz(uint8_t *d,uint8_t *top,uint8_t *left,int stride)
+static void intra_pred_horiz(uint8_t *d, uint8_t *top, uint8_t *left, int stride)
{
int y;
uint64_t a;
@@ -263,7 +262,7 @@
}
}
-static void intra_pred_dc_128(uint8_t *d,uint8_t *top,uint8_t *left,int stride)
+static void intra_pred_dc_128(uint8_t *d, uint8_t *top, uint8_t *left, int stride)
{
int y;
uint64_t a = 0x8080808080808080ULL;
@@ -271,7 +270,7 @@
*((uint64_t *)(d + y * stride)) = a;
}
-static void intra_pred_plane(uint8_t *d,uint8_t *top,uint8_t *left,int stride)
+static void intra_pred_plane(uint8_t *d, uint8_t *top, uint8_t *left, int stride)
{
int x, y, ia;
int ih = 0;
@@ -279,7 +278,7 @@
const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
for (x = 0; x < 4; x++) {
- ih += (x + 1) * (top [5 + x] - top [3 - x]);
+ ih += (x + 1) * (top[5 + x] - top[3 - x]);
iv += (x + 1) * (left[5 + x] - left[3 - x]);
}
ia = (top[8] + left[8]) << 4;
@@ -290,10 +289,10 @@
d[y * stride + x] = cm[(ia + (x - 3) * ih + (y - 3) * iv + 16) >> 5];
}
-#define LOWPASS(ARRAY,INDEX) \
+#define LOWPASS(ARRAY, INDEX) \
((ARRAY[(INDEX) - 1] + 2 * ARRAY[(INDEX)] + ARRAY[(INDEX) + 1] + 2) >> 2)
-static void intra_pred_lp(uint8_t *d,uint8_t *top,uint8_t *left,int stride)
+static void intra_pred_lp(uint8_t *d, uint8_t *top, uint8_t *left, int stride)
{
int x, y;
for (y = 0; y < 8; y++)
@@ -301,7 +300,7 @@
d[y * stride + x] = (LOWPASS(top, x + 1) + LOWPASS(left, y + 1)) >> 1;
}
-static void intra_pred_down_left(uint8_t *d,uint8_t *top,uint8_t *left,int stride)
+static void intra_pred_down_left(uint8_t *d, uint8_t *top, uint8_t *left, int stride)
{
int x, y;
for (y = 0; y < 8; y++)
@@ -309,7 +308,7 @@
d[y * stride + x] = (LOWPASS(top, x + y + 2) + LOWPASS(left, x + y + 2)) >> 1;
}
-static void intra_pred_down_right(uint8_t *d,uint8_t *top,uint8_t *left,int stride)
+static void intra_pred_down_right(uint8_t *d, uint8_t *top, uint8_t *left, int stride)
{
int x, y;
for (y = 0; y < 8; y++)
@@ -322,7 +321,7 @@
d[y * stride + x] = LOWPASS(left, y - x);
}
-static void intra_pred_lp_left(uint8_t *d,uint8_t *top,uint8_t *left,int stride)
+static void intra_pred_lp_left(uint8_t *d, uint8_t *top, uint8_t *left, int stride)
{
int x, y;
for (y = 0; y < 8; y++)
@@ -330,7 +329,7 @@
d[y * stride + x] = LOWPASS(left, y + 1);
}
-static void intra_pred_lp_top(uint8_t *d,uint8_t *top,uint8_t *left,int stride)
+static void intra_pred_lp_top(uint8_t *d, uint8_t *top, uint8_t *left, int stride)
{
int x, y;
for (y = 0; y < 8; y++)
@@ -352,8 +351,8 @@
void ff_cavs_modify_mb_i(AVSContext *h, int *pred_mode_uv)
{
/* save pred modes before they get modified */
- h->pred_mode_Y[3] = h->pred_mode_Y[5];
- h->pred_mode_Y[6] = h->pred_mode_Y[8];
+ h->pred_mode_Y[3] = h->pred_mode_Y[5];
+ h->pred_mode_Y[6] = h->pred_mode_Y[8];
h->top_pred_Y[h->mbx * 2 + 0] = h->pred_mode_Y[7];
h->top_pred_Y[h->mbx * 2 + 1] = h->pred_mode_Y[8];
@@ -383,8 +382,8 @@
qpel_mc_func *qpix_op,
h264_chroma_mc_func chroma_op, cavs_vector *mv)
{
- const int mx = mv->x + src_x_offset*8;
- const int my = mv->y + src_y_offset*8;
+ 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;
@@ -408,21 +407,22 @@
full_my < 0 - extra_height ||
full_mx + 16 /* FIXME */ > pic_width + extra_width ||
full_my + 16 /* FIXME */ > pic_height + extra_height) {
- h->vdsp.emulated_edge_mc(h->edge_emu_buffer, h->l_stride,
- src_y - 2 - 2 * h->l_stride, h->l_stride,
+ h->vdsp.emulated_edge_mc(h->edge_emu_buffer,
+ src_y - 2 - 2 * h->l_stride,
+ h->l_stride, h->l_stride,
16 + 5, 16 + 5 /* FIXME */,
full_mx - 2, full_my - 2,
pic_width, pic_height);
src_y = h->edge_emu_buffer + 2 + 2 * h->l_stride;
- emu = 1;
+ emu = 1;
}
// FIXME try variable height perhaps?
qpix_op[luma_xy](dest_y, src_y, h->l_stride);
if (emu) {
- h->vdsp.emulated_edge_mc(h->edge_emu_buffer, h->c_stride, src_cb,
- h->c_stride,
+ h->vdsp.emulated_edge_mc(h->edge_emu_buffer, src_cb,
+ h->c_stride, h->c_stride,
9, 9 /* FIXME */,
mx >> 3, my >> 3,
pic_width >> 1, pic_height >> 1);
@@ -431,8 +431,8 @@
chroma_op(dest_cb, src_cb, h->c_stride, chroma_height, mx & 7, my & 7);
if (emu) {
- h->vdsp.emulated_edge_mc(h->edge_emu_buffer, h->c_stride, src_cr,
- h->c_stride,
+ h->vdsp.emulated_edge_mc(h->edge_emu_buffer, src_cr,
+ h->c_stride, h->c_stride,
9, 9 /* FIXME */,
mx >> 3, my >> 3,
pic_width >> 1, pic_height >> 1);
@@ -455,9 +455,9 @@
qpel_mc_func *qpix_op = qpix_put;
h264_chroma_mc_func chroma_op = chroma_put;
- dest_y += 2 * x_offset + 2 * y_offset*h->l_stride;
- dest_cb += x_offset + y_offset*h->c_stride;
- dest_cr += x_offset + y_offset*h->c_stride;
+ dest_y += x_offset * 2 + y_offset * h->l_stride * 2;
+ dest_cb += x_offset + y_offset * h->c_stride;
+ dest_cr += x_offset + y_offset * h->c_stride;
x_offset += 8 * h->mbx;
y_offset += 8 * h->mby;
@@ -475,7 +475,7 @@
AVFrame *ref = h->DPB[0].f;
mc_dir_part(h, ref, chroma_height, delta, 1,
dest_y, dest_cb, dest_cr, x_offset, y_offset,
- qpix_op, chroma_op, mv+MV_BWD_OFFS);
+ qpix_op, chroma_op, mv + MV_BWD_OFFS);
}
}
@@ -545,9 +545,9 @@
scale_mv(h, &bx, &by, mvB, mvP->dist);
scale_mv(h, &cx, &cy, mvC, mvP->dist);
/* find the geometrical median of the three candidates */
- len_ab = abs(ax - bx) + abs(ay - by);
- len_bc = abs(bx - cx) + abs(by - cy);
- len_ca = abs(cx - ax) + abs(cy - ay);
+ len_ab = abs(ax - bx) + abs(ay - by);
+ len_bc = abs(bx - cx) + abs(by - cy);
+ len_ca = abs(cx - ax) + abs(cy - ay);
len_mid = mid_pred(len_ab, len_bc, len_ca);
if (len_mid == len_ab) {
mvP->x = cx;
@@ -573,7 +573,7 @@
mvP->ref = ref;
mvP->dist = h->dist[mvP->ref];
if (mvC->ref == NOT_AVAIL)
- mvC = &h->mv[nP-5]; // set to top-left (mvD)
+ mvC = &h->mv[nP - 5]; // set to top-left (mvD)
if (mode == MV_PRED_PSKIP &&
(mvA->ref == NOT_AVAIL ||
mvB->ref == NOT_AVAIL ||
@@ -604,7 +604,7 @@
mvP->x += get_se_golomb(&h->gb);
mvP->y += get_se_golomb(&h->gb);
}
- set_mvs(mvP,size);
+ set_mvs(mvP, size);
}
/*****************************************************************************
diff --git a/libavcodec/cavsdec.c b/libavcodec/cavsdec.c
index 74983a7..44d0ec0 100644
--- a/libavcodec/cavsdec.c
+++ b/libavcodec/cavsdec.c
@@ -565,8 +565,10 @@
level_code = get_ue_code(gb, r->golomb_order);
if (level_code >= ESCAPE_CODE) {
run = ((level_code - ESCAPE_CODE) >> 1) + 1;
- if(run > 64)
- return -1;
+ if(run > 64) {
+ av_log(h->avctx, AV_LOG_ERROR, "run %d is too large\n", run);
+ return AVERROR_INVALIDDATA;
+ }
esc_code = get_ue_code(gb, esc_golomb_order);
level = esc_code + (run > r->max_run ? 1 : r->level_add[run]);
while (level > r->inc_limit)
@@ -892,8 +894,10 @@
if (h->stc > 0xAF)
av_log(h->avctx, AV_LOG_ERROR, "unexpected start code 0x%02x\n", h->stc);
- if (h->stc >= h->mb_height)
- return -1;
+ if (h->stc >= h->mb_height) {
+ av_log(h->avctx, AV_LOG_ERROR, "stc 0x%02x is too large\n", h->stc);
+ return AVERROR_INVALIDDATA;
+ }
h->mby = h->stc;
h->mbidx = h->mby * h->mb_width;
@@ -1161,12 +1165,17 @@
return 0;
}
+ h->stc = 0;
+
buf_ptr = buf;
buf_end = buf + buf_size;
for(;;) {
buf_ptr = avpriv_find_start_code(buf_ptr, buf_end, &stc);
- if ((stc & 0xFFFFFE00) || buf_ptr == buf_end)
+ if ((stc & 0xFFFFFE00) || buf_ptr == buf_end) {
+ if (!h->stc)
+ av_log(h->avctx, AV_LOG_WARNING, "no frame decoded\n");
return FFMAX(0, buf_ptr - buf);
+ }
input_size = (buf_end - buf_ptr) * 8;
switch (stc) {
case CAVS_START_CODE:
diff --git a/libavcodec/cdxl.c b/libavcodec/cdxl.c
index 93a5537..13ad57c 100644
--- a/libavcodec/cdxl.c
+++ b/libavcodec/cdxl.c
@@ -245,10 +245,8 @@
return AVERROR_PATCHWELCOME;
}
- if ((ret = av_image_check_size(w, h, 0, avctx)) < 0)
+ if ((ret = ff_set_dimensions(avctx, w, h)) < 0)
return ret;
- if (w != avctx->width || h != avctx->height)
- avcodec_set_dimensions(avctx, w, h);
aligned_width = FFALIGN(c->avctx->width, 16);
c->padded_bits = aligned_width - c->avctx->width;
diff --git a/libavcodec/cljr.c b/libavcodec/cljr.c
index 51ac106..7e0773b 100644
--- a/libavcodec/cljr.c
+++ b/libavcodec/cljr.c
@@ -99,16 +99,21 @@
#if CONFIG_CLJR_ENCODER
typedef struct CLJRContext {
AVClass *avclass;
- AVFrame picture;
int dither_type;
} CLJRContext;
static av_cold int encode_init(AVCodecContext *avctx)
{
- CLJRContext * const a = avctx->priv_data;
+ avctx->coded_frame = av_frame_alloc();
+ if (!avctx->coded_frame)
+ return AVERROR(ENOMEM);
- avctx->coded_frame = &a->picture;
+ return 0;
+}
+static av_cold int encode_close(AVCodecContext *avctx)
+{
+ av_frame_free(&avctx->coded_frame);
return 0;
}
@@ -183,6 +188,7 @@
.priv_data_size = sizeof(CLJRContext),
.init = encode_init,
.encode2 = encode_frame,
+ .close = encode_close,
.pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV411P,
AV_PIX_FMT_NONE },
.priv_class = &cljr_class,
diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c
index bb5f92a..c62734f 100644
--- a/libavcodec/codec_desc.c
+++ b/libavcodec/codec_desc.c
@@ -21,10 +21,10 @@
#include <string.h>
-#include "avcodec.h"
-
#include "libavutil/common.h"
#include "libavutil/internal.h"
+#include "avcodec.h"
+#include "version.h"
static const AVCodecDescriptor codec_descriptors[] = {
/* video codecs */
@@ -42,6 +42,7 @@
.long_name = NULL_IF_CONFIG_SMALL("MPEG-2 video"),
.props = AV_CODEC_PROP_LOSSY,
},
+#if FF_API_XVMC
{
.id = AV_CODEC_ID_MPEG2VIDEO_XVMC,
.type = AVMEDIA_TYPE_VIDEO,
@@ -49,6 +50,7 @@
.long_name = NULL_IF_CONFIG_SMALL("MPEG-1/2 video XvMC (X-Video Motion Compensation)"),
.props = AV_CODEC_PROP_LOSSY,
},
+#endif /* FF_API_XVMC */
{
.id = AV_CODEC_ID_H261,
.type = AVMEDIA_TYPE_VIDEO,
@@ -226,13 +228,6 @@
.props = AV_CODEC_PROP_LOSSY | AV_CODEC_PROP_LOSSLESS,
},
{
- .id = AV_CODEC_ID_HEVC,
- .type = AVMEDIA_TYPE_VIDEO,
- .name = "hevc",
- .long_name = NULL_IF_CONFIG_SMALL("H.265 / HEVC"),
- .props = AV_CODEC_PROP_LOSSY | AV_CODEC_PROP_LOSSLESS,
- },
- {
.id = AV_CODEC_ID_INDEO3,
.type = AVMEDIA_TYPE_VIDEO,
.name = "indeo3",
@@ -1394,6 +1389,20 @@
.props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY |
AV_CODEC_PROP_LOSSLESS,
},
+ {
+ .id = AV_CODEC_ID_HNM4_VIDEO,
+ .type = AVMEDIA_TYPE_VIDEO,
+ .name = "hnm4video",
+ .long_name = NULL_IF_CONFIG_SMALL("HNM 4 video"),
+ .props = AV_CODEC_PROP_LOSSY,
+ },
+ {
+ .id = AV_CODEC_ID_HEVC,
+ .type = AVMEDIA_TYPE_VIDEO,
+ .name = "hevc",
+ .long_name = NULL_IF_CONFIG_SMALL("H.265 / HEVC (High Efficiency Video Coding)"),
+ .props = AV_CODEC_PROP_LOSSY,
+ },
/* various PCM "codecs" */
{
@@ -1853,6 +1862,13 @@
.long_name = NULL_IF_CONFIG_SMALL("ADPCM IMA Radical"),
.props = AV_CODEC_PROP_LOSSY,
},
+ {
+ .id = AV_CODEC_ID_ADPCM_G726LE,
+ .type = AVMEDIA_TYPE_AUDIO,
+ .name = "adpcm_g726le",
+ .long_name = NULL_IF_CONFIG_SMALL("G.726 ADPCM little-endian"),
+ .props = AV_CODEC_PROP_LOSSY,
+ },
/* AMR */
{
diff --git a/libavcodec/cook.c b/libavcodec/cook.c
index 083d26b..402093c 100644
--- a/libavcodec/cook.c
+++ b/libavcodec/cook.c
@@ -51,6 +51,7 @@
#include "fft.h"
#include "internal.h"
#include "sinewin.h"
+#include "unary.h"
#include "cookdata.h"
@@ -228,7 +229,7 @@
/* Initialize the MDCT. */
if ((ret = ff_mdct_init(&q->mdct_ctx, av_log2(mlt_size) + 1, 1, 1.0 / 32768.0))) {
- av_free(q->mlt_window);
+ av_freep(&q->mlt_window);
return ret;
}
av_log(q->avctx, AV_LOG_DEBUG, "MDCT initialized, order = %d.\n",
@@ -302,8 +303,8 @@
av_log(avctx, AV_LOG_DEBUG, "Deallocating memory.\n");
/* Free allocated memory buffers. */
- av_free(q->mlt_window);
- av_free(q->decoded_bytes_buffer);
+ av_freep(&q->mlt_window);
+ av_freep(&q->decoded_bytes_buffer);
/* Free the transform. */
ff_mdct_end(&q->mdct_ctx);
@@ -331,11 +332,7 @@
{
int i, n;
- while (get_bits1(gb)) {
- /* NOTHING */
- }
-
- n = get_bits_count(gb) - 1; // amount of elements*2 to update
+ n = get_unary(gb, 0, get_bits_left(gb)); // amount of elements*2 to update
i = 0;
while (n--) {
diff --git a/libavcodec/cook_parser.c b/libavcodec/cook_parser.c
index f17f56e..6dbbfd8 100644
--- a/libavcodec/cook_parser.c
+++ b/libavcodec/cook_parser.c
@@ -40,11 +40,12 @@
{
CookParseContext *s = s1->priv_data;
- if (s->duration)
- s1->duration = s->duration;
- else if (avctx->extradata && avctx->extradata_size >= 8 && avctx->channels)
+ if (!s->duration &&
+ avctx->extradata && avctx->extradata_size >= 8 && avctx->channels)
s->duration = AV_RB16(avctx->extradata + 4) / avctx->channels;
+ s1->duration = s->duration;
+
/* always return the full packet. this parser isn't doing any splitting or
combining, only setting packet duration */
*poutbuf = buf;
diff --git a/libavcodec/crystalhd.c b/libavcodec/crystalhd.c
index 94f8c85..12a8f8e 100644
--- a/libavcodec/crystalhd.c
+++ b/libavcodec/crystalhd.c
@@ -915,8 +915,8 @@
H264Context *h = priv->parser->priv_data;
index = av_parser_parse2(priv->parser, avctx, &pout, &psize,
- in_data, len, avctx->pkt->pts,
- avctx->pkt->dts, 0);
+ in_data, len, avctx->internal->pkt->pts,
+ avctx->internal->pkt->dts, 0);
if (index < 0) {
av_log(avctx, AV_LOG_WARNING,
"CrystalHD: Failed to parse h.264 packet to "
@@ -950,7 +950,7 @@
* avoiding mangling so we need to build a mapping to values
* we know will not be mangled.
*/
- uint64_t pts = opaque_list_push(priv, avctx->pkt->pts, pic_type);
+ uint64_t pts = opaque_list_push(priv, avctx->internal->pkt->pts, pic_type);
if (!pts) {
if (free_data) {
av_freep(&in_data);
diff --git a/libavcodec/dcadata.h b/libavcodec/dcadata.h
index 15df49e..5154fbc 100644
--- a/libavcodec/dcadata.h
+++ b/libavcodec/dcadata.h
@@ -7505,24 +7505,19 @@
0.01724460535, 0.47964480519, 0.48503074050, 0.01805862412,
};
-/* 10^-(dB/20), with dB being a list of dB values ranging from 0 to -72 */
-/* do a 20*log10(dca_downmix_coeffs) to reconvert the values */
-
-static const float dca_downmix_coeffs[65] = {
- 1.000000000000000, 0.988553094656939, 0.971627951577106, 0.944060876285923, 0.917275935389780, 0.891250938133746,
- 0.865964323360065, 0.841395141645195, 0.817523037943650, 0.794328234724281, 0.771791515585012, 0.749894209332456,
- 0.728618174513228, 0.707945784384138, 0.687859912308808, 0.668343917568615, 0.649381631576211, 0.630957344480193,
- 0.613055792149821, 0.595662143529010, 0.578761988349121, 0.562341325190349, 0.546386549881854, 0.530884444230988,
- 0.515822165072306, 0.501187233627272, 0.446683592150963, 0.398107170553497, 0.354813389233575, 0.316227766016838,
- 0.281838293126445, 0.251188643150958, 0.223872113856834, 0.199526231496888, 0.177827941003892, 0.158489319246111,
- 0.141253754462275, 0.125892541179417, 0.112201845430196, 0.100000000000000, 0.089125093813374, 0.079432823472428,
- 0.070794578438414, 0.063095734448019, 0.053088444423099, 0.044668359215096, 0.037583740428844, 0.031622776601684,
- 0.026607250597988, 0.022387211385683, 0.018836490894898, 0.015848931924611, 0.013335214321633, 0.011220184543020,
- 0.009440608762859, 0.007943282347243, 0.005623413251903, 0.003981071705535, 0.002818382931264, 0.001995262314969,
- 0.001412537544623, 0.001000000000000, 0.000501187233627, 0.000251188643151, 0.000000000000000,
-};
-
-static const float dca_downmix_scale_factors[241] = {
+/*
+ * D.11 Look-up Table for Downmix Scale Factors
+ *
+ * Note that the range of the entries in DmixTable[] is between -60 dB and 0 dB
+ * with addition of -inf (|DMixCoeff| = 0), which is coded with a DmixCode = 0.
+ * Furthermore, the range [-60 to 0] is subdivided into 3 regions, each with a
+ * different grid resolution:
+ *
+ * 1) [-60.000 to -30] with resolution of 0.500 dB
+ * 2) [-29.750 to -15] with resolution of 0.250 dB
+ * 3) [-14.875 to 0] with resolution of 0.125 dB
+ */
+static const float dca_dmixtable[241] = {
0.001000, 0.001059, 0.001122, 0.001189, 0.001259, 0.001334, 0.001413, 0.001496,
0.001585, 0.001679, 0.001778, 0.001884, 0.001995, 0.002113, 0.002239, 0.002371,
0.002512, 0.002661, 0.002818, 0.002985, 0.003162, 0.003350, 0.003548, 0.003758,
@@ -7553,20 +7548,20 @@
0.707107, 0.718208, 0.728618, 0.739180, 0.749894, 0.760764, 0.771792, 0.782979,
0.794328, 0.805842, 0.817523, 0.829373, 0.841395, 0.853591, 0.865964, 0.878517,
0.891251, 0.904170, 0.917276, 0.930572, 0.944061, 0.957745, 0.971628, 0.985712,
- 1.000000
+ 1.000000,
};
-static const uint8_t dca_default_coeffs[10][5][2] = {
- { { 13, 13 }, },
- { { 0, 64 }, { 64, 0 }, },
- { { 0, 64 }, { 64, 0 }, },
- { { 0, 64 }, { 64, 0 }, },
- { { 0, 64 }, { 64, 0 }, },
- { { 6, 6 }, { 0, 25 }, { 25, 0 }, },
- { { 0, 25 }, { 25, 0 }, { 13, 13 }, },
- { { 6, 6 }, { 0, 25 }, { 25, 0 }, { 13, 13 }, },
- { { 0, 25 }, { 25, 0 }, { 0, 13 }, { 13, 0 }, },
- { { 6, 6 }, { 0, 25 }, { 25, 0 }, { 0, 13 }, { 13, 0 }, },
+static const float dca_default_coeffs[10][6][2] = {
+ { { 0.707107, 0.707107 }, { 0.000000, 0.000000 }, }, // A [LFE]
+ { { 1.000000, 0.000000 }, { 0.000000, 1.000000 }, { 0.000000, 0.000000 }, }, // A + B (dual mono) [LFE]
+ { { 1.000000, 0.000000 }, { 0.000000, 1.000000 }, { 0.000000, 0.000000 }, }, // L + R (stereo) [LFE]
+ { { 1.000000, 0.000000 }, { 0.000000, 1.000000 }, { 0.000000, 0.000000 }, }, // (L+R) + (L-R) (sum-difference) [LFE]
+ { { 1.000000, 0.000000 }, { 0.000000, 1.000000 }, { 0.000000, 0.000000 }, }, // LT + RT (left and right total) [LFE]
+ { { 0.501187, 0.501187 }, { 0.707107, 0.000000 }, { 0.000000, 0.707107 }, { 0.000000, 0.000000 }, }, // C + L + R [LFE]
+ { { 0.707107, 0.000000 }, { 0.000000, 0.707107 }, { 0.501187, 0.501187 }, { 0.000000, 0.000000 }, }, // L + R + S [LFE]
+ { { 0.501187, 0.501187 }, { 0.707107, 0.000000 }, { 0.000000, 0.707107 }, { 0.501187, 0.501187 }, { 0.000000, 0.000000 }, }, // C + L + R + S [LFE]
+ { { 0.707107, 0.000000 }, { 0.000000, 0.707107 }, { 0.501187, 0.000000 }, { 0.000000, 0.501187 }, { 0.000000, 0.000000 }, }, // L + R + SL + SR [LFE]
+ { { 0.501187, 0.501187 }, { 0.707107, 0.000000 }, { 0.000000, 0.707107 }, { 0.501187, 0.000000 }, { 0.000000, 0.501187 }, { 0.000000, 0.000000 }, }, // C + L + R + SL + SR [LFE]
};
/* downmix coeffs
diff --git a/libavcodec/dcadec.c b/libavcodec/dcadec.c
index 613e60b..cc2fa0a 100644
--- a/libavcodec/dcadec.c
+++ b/libavcodec/dcadec.c
@@ -32,6 +32,7 @@
#include "libavutil/internal.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/mathematics.h"
+#include "libavutil/opt.h"
#include "libavutil/samplefmt.h"
#include "avcodec.h"
#include "fft.h"
@@ -325,6 +326,8 @@
#define DCA_BUFFER_PADDING_SIZE 1024
+#define DCA_NSYNCAUX 0x9A1105A0
+
/** Bit allocation */
typedef struct {
int offset; ///< code values offset
@@ -346,6 +349,7 @@
}
typedef struct {
+ const AVClass *class; ///< class for AVOptions
AVCodecContext *avctx;
/* Frame header */
int frame_type; ///< type of the current frame
@@ -358,7 +362,6 @@
int bit_rate; ///< transmission bit rate
int bit_rate_index; ///< transmission bit rate index
- int downmix; ///< embedded downmix enabled
int dynrange; ///< embedded dynamic range flag
int timestamp; ///< embedded time stamp flag
int aux_data; ///< auxiliary data flag
@@ -400,9 +403,16 @@
int scale_factor[DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS][2]; ///< scale factors (2 if transient)
int joint_huff[DCA_PRIM_CHANNELS_MAX]; ///< joint subband scale factors codebook
int joint_scale_factor[DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS]; ///< joint subband scale factors
- int downmix_coef[DCA_PRIM_CHANNELS_MAX][2]; ///< stereo downmix coefficients
+ float downmix_coef[DCA_PRIM_CHANNELS_MAX + 1][2]; ///< stereo downmix coefficients
int dynrange_coef; ///< dynamic range coefficient
+ /* Core substream's embedded downmix coefficients (cf. ETSI TS 102 114 V1.4.1)
+ * Input: primary audio channels (incl. LFE if present)
+ * Output: downmix audio channels (up to 4, no LFE) */
+ uint8_t core_downmix; ///< embedded downmix coefficients available
+ uint8_t core_downmix_amode; ///< audio channel arrangement of embedded downmix
+ uint16_t core_downmix_codes[DCA_PRIM_CHANNELS_MAX + 1][4]; ///< embedded downmix coefficients (9-bit codes)
+
int high_freq_vq[DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS]; ///< VQ encoded high frequency subbands
float lfe_data[2 * DCA_LFE_MAX * (DCA_BLOCKS_MAX + 4)]; ///< Low frequency effect data
@@ -437,6 +447,7 @@
/* XCh extension information */
int xch_present; ///< XCh extension present and valid
int xch_base_channel; ///< index of first (only) channel containing XCH data
+ int xch_disable; ///< whether the XCh extension should be decoded or not
/* XXCH extension information */
int xxch_chset;
@@ -589,7 +600,7 @@
if (get_bits1(&s->gb)) {
embedded_downmix = get_bits1(&s->gb);
scale_factor =
- 1.0f / dca_downmix_scale_factors[(get_bits(&s->gb, 6) - 1) << 2];
+ 1.0f / dca_dmixtable[(get_bits(&s->gb, 6) - 1) << 2];
s->xxch_dmix_sf[s->xxch_chset] = scale_factor;
@@ -610,7 +621,7 @@
coeff = get_bits(&s->gb, 7);
sign = (coeff & 64) ? 1.0 : -1.0;
- mag = dca_downmix_scale_factors[((coeff & 63) - 1) << 2];
+ mag = dca_dmixtable[((coeff & 63) - 1) << 2];
ichan = dca_xxch2index(s, 1 << i);
s->xxch_dmix_coeff[j][ichan] = sign * mag;
}
@@ -724,7 +735,7 @@
if (!s->bit_rate)
return AVERROR_INVALIDDATA;
- s->downmix = get_bits(&s->gb, 1); /* note: this is FixedBit == 0 */
+ skip_bits1(&s->gb); // always 0 (reserved, cf. ETSI TS 102 114 V1.4.1)
s->dynrange = get_bits(&s->gb, 1);
s->timestamp = get_bits(&s->gb, 1);
s->aux_data = get_bits(&s->gb, 1);
@@ -771,7 +782,6 @@
s->sample_rate);
av_log(s->avctx, AV_LOG_DEBUG, "bit rate: %i bits/s\n",
s->bit_rate);
- av_log(s->avctx, AV_LOG_DEBUG, "downmix: %i\n", s->downmix);
av_log(s->avctx, AV_LOG_DEBUG, "dynrange: %i\n", s->dynrange);
av_log(s->avctx, AV_LOG_DEBUG, "timestamp: %i\n", s->timestamp);
av_log(s->avctx, AV_LOG_DEBUG, "aux_data: %i\n", s->aux_data);
@@ -954,33 +964,6 @@
}
}
- /* Stereo downmix coefficients */
- if (!base_channel && s->prim_channels > 2) {
- if (s->downmix) {
- for (j = base_channel; j < s->prim_channels; j++) {
- s->downmix_coef[j][0] = get_bits(&s->gb, 7);
- s->downmix_coef[j][1] = get_bits(&s->gb, 7);
- }
- } else {
- int am = s->amode & DCA_CHANNEL_MASK;
- if (am >= FF_ARRAY_ELEMS(dca_default_coeffs)) {
- av_log(s->avctx, AV_LOG_ERROR,
- "Invalid channel mode %d\n", am);
- return AVERROR_INVALIDDATA;
- }
- if (s->prim_channels > FF_ARRAY_ELEMS(dca_default_coeffs[0])) {
- avpriv_request_sample(s->avctx, "Downmixing %d channels",
- s->prim_channels);
- return AVERROR_PATCHWELCOME;
- }
-
- for (j = base_channel; j < s->prim_channels; j++) {
- s->downmix_coef[j][0] = dca_default_coeffs[am][j][0];
- s->downmix_coef[j][1] = dca_default_coeffs[am][j][1];
- }
- }
- }
-
/* Dynamic range coefficient */
if (!base_channel && s->dynrange)
s->dynrange_coef = get_bits(&s->gb, 8);
@@ -1080,16 +1063,6 @@
av_log(s->avctx, AV_LOG_DEBUG, "\n");
}
}
- if (!base_channel && s->prim_channels > 2 && s->downmix) {
- av_log(s->avctx, AV_LOG_DEBUG, "Downmix coeffs:\n");
- for (j = 0; j < s->prim_channels; j++) {
- av_log(s->avctx, AV_LOG_DEBUG, "Channel 0, %d = %f\n", j,
- dca_downmix_coeffs[s->downmix_coef[j][0]]);
- av_log(s->avctx, AV_LOG_DEBUG, "Channel 1, %d = %f\n", j,
- dca_downmix_coeffs[s->downmix_coef[j][1]]);
- }
- av_log(s->avctx, AV_LOG_DEBUG, "\n");
- }
for (j = base_channel; j < s->prim_channels; j++)
for (k = s->vq_start_subband[j]; k < s->subband_activity[j]; k++)
av_log(s->avctx, AV_LOG_DEBUG, "VQ index: %i\n", s->high_freq_vq[j][k]);
@@ -1184,29 +1157,23 @@
op2 \
}
-static void dca_downmix(float **samples, int srcfmt,
- int downmix_coef[DCA_PRIM_CHANNELS_MAX][2],
+static void dca_downmix(float **samples, int srcfmt, int lfe_present,
+ float coef[DCA_PRIM_CHANNELS_MAX + 1][2],
const int8_t *channel_mapping)
{
int c, l, r, sl, sr, s;
int i;
float t, u, v;
- float coef[DCA_PRIM_CHANNELS_MAX][2];
-
- for (i = 0; i < DCA_PRIM_CHANNELS_MAX; i++) {
- coef[i][0] = dca_downmix_coeffs[downmix_coef[i][0]];
- coef[i][1] = dca_downmix_coeffs[downmix_coef[i][1]];
- }
switch (srcfmt) {
case DCA_MONO:
- case DCA_CHANNEL:
- case DCA_STEREO_TOTAL:
- case DCA_STEREO_SUMDIFF:
case DCA_4F2R:
av_log(NULL, AV_LOG_ERROR, "Not implemented!\n");
break;
+ case DCA_CHANNEL:
case DCA_STEREO:
+ case DCA_STEREO_TOTAL:
+ case DCA_STEREO_SUMDIFF:
break;
case DCA_3F:
c = channel_mapping[0];
@@ -1241,6 +1208,14 @@
MIX_REAR2(samples, sl, sr, 3, coef));
break;
}
+ if (lfe_present) {
+ int lf_buf = dca_lfe_index[srcfmt];
+ int lf_idx = dca_channels [srcfmt];
+ for (i = 0; i < 256; i++) {
+ samples[0][i] += samples[lf_buf][i] * coef[lf_idx][0];
+ samples[1][i] += samples[lf_buf][i] * coef[lf_idx][1];
+ }
+ }
}
@@ -1448,13 +1423,8 @@
M_SQRT1_2 / 32768.0 /* pcm_to_double[s->source_pcm_res] */);
}
- /* Down mixing */
- if (s->avctx->request_channels == 2 && s->prim_channels > 2) {
- dca_downmix(s->samples_chanptr, s->amode, s->downmix_coef, s->channel_order_tab);
- }
-
/* Generate LFE samples for this subsubframe FIXME!!! */
- if (s->output & DCA_LFE) {
+ if (s->lfe) {
lfe_interpolation_fir(s, s->lfe, 2 * s->lfe,
s->lfe_data + 2 * s->lfe * (block_index + 4),
s->samples_chanptr[s->lfe_index],
@@ -1462,13 +1432,21 @@
/* Outputs 20bits pcm samples */
}
+ /* Downmixing to Stereo */
+ if (s->prim_channels + !!s->lfe > 2 &&
+ s->avctx->request_channel_layout == AV_CH_LAYOUT_STEREO) {
+ dca_downmix(s->samples_chanptr, s->amode, !!s->lfe, s->downmix_coef,
+ s->channel_order_tab);
+ }
+
return 0;
}
static int dca_subframe_footer(DCAContext *s, int base_channel)
{
- int aux_data_count = 0, i;
+ int in, out, aux_data_count, aux_data_end, reserved;
+ uint32_t nsyncaux;
/*
* Unpack optional information
@@ -1479,13 +1457,89 @@
if (s->timestamp)
skip_bits_long(&s->gb, 32);
- if (s->aux_data)
+ if (s->aux_data) {
aux_data_count = get_bits(&s->gb, 6);
- for (i = 0; i < aux_data_count; i++)
- get_bits(&s->gb, 8);
+ // align (32-bit)
+ skip_bits_long(&s->gb, (-get_bits_count(&s->gb)) & 31);
- if (s->crc_present && (s->downmix || s->dynrange))
+ aux_data_end = 8 * aux_data_count + get_bits_count(&s->gb);
+
+ if ((nsyncaux = get_bits_long(&s->gb, 32)) != DCA_NSYNCAUX) {
+ av_log(s->avctx, AV_LOG_ERROR, "nSYNCAUX mismatch %#"PRIx32"\n",
+ nsyncaux);
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (get_bits1(&s->gb)) { // bAUXTimeStampFlag
+ avpriv_request_sample(s->avctx,
+ "Auxiliary Decode Time Stamp Flag");
+ // align (4-bit)
+ skip_bits(&s->gb, (-get_bits_count(&s->gb)) & 4);
+ // 44 bits: nMSByte (8), nMarker (4), nLSByte (28), nMarker (4)
+ skip_bits_long(&s->gb, 44);
+ }
+
+ if ((s->core_downmix = get_bits1(&s->gb))) {
+ int am = get_bits(&s->gb, 3);
+ switch (am) {
+ case 0:
+ s->core_downmix_amode = DCA_MONO;
+ break;
+ case 1:
+ s->core_downmix_amode = DCA_STEREO;
+ break;
+ case 2:
+ s->core_downmix_amode = DCA_STEREO_TOTAL;
+ break;
+ case 3:
+ s->core_downmix_amode = DCA_3F;
+ break;
+ case 4:
+ s->core_downmix_amode = DCA_2F1R;
+ break;
+ case 5:
+ s->core_downmix_amode = DCA_2F2R;
+ break;
+ case 6:
+ s->core_downmix_amode = DCA_3F1R;
+ break;
+ default:
+ av_log(s->avctx, AV_LOG_ERROR,
+ "Invalid mode %d for embedded downmix coefficients\n",
+ am);
+ return AVERROR_INVALIDDATA;
+ }
+ for (out = 0; out < dca_channels[s->core_downmix_amode]; out++) {
+ for (in = 0; in < s->prim_channels + !!s->lfe; in++) {
+ uint16_t tmp = get_bits(&s->gb, 9);
+ if ((tmp & 0xFF) > 241) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "Invalid downmix coefficient code %"PRIu16"\n",
+ tmp);
+ return AVERROR_INVALIDDATA;
+ }
+ s->core_downmix_codes[in][out] = tmp;
+ }
+ }
+ }
+
+ align_get_bits(&s->gb); // byte align
+ skip_bits(&s->gb, 16); // nAUXCRC16
+
+ // additional data (reserved, cf. ETSI TS 102 114 V1.4.1)
+ if ((reserved = (aux_data_end - get_bits_count(&s->gb))) < 0) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "Overread auxiliary data by %d bits\n", -reserved);
+ return AVERROR_INVALIDDATA;
+ } else if (reserved) {
+ avpriv_request_sample(s->avctx,
+ "Core auxiliary data reserved content");
+ skip_bits_long(&s->gb, reserved);
+ }
+ }
+
+ if (s->crc_present && s->dynrange)
get_bits(&s->gb, 16);
}
@@ -2116,6 +2170,54 @@
/* record number of core channels incase less than max channels are requested */
num_core_channels = s->prim_channels;
+ if (s->prim_channels + !!s->lfe > 2 &&
+ avctx->request_channel_layout == AV_CH_LAYOUT_STEREO) {
+ /* Stereo downmix coefficients
+ *
+ * The decoder can only downmix to 2-channel, so we need to ensure
+ * embedded downmix coefficients are actually targeting 2-channel.
+ */
+ if (s->core_downmix && (s->core_downmix_amode == DCA_STEREO ||
+ s->core_downmix_amode == DCA_STEREO_TOTAL)) {
+ int sign, code;
+ for (i = 0; i < s->prim_channels + !!s->lfe; i++) {
+ sign = s->core_downmix_codes[i][0] & 0x100 ? 1 : -1;
+ code = s->core_downmix_codes[i][0] & 0x0FF;
+ s->downmix_coef[i][0] = (!code ? 0.0f :
+ sign * dca_dmixtable[code - 1]);
+ sign = s->core_downmix_codes[i][1] & 0x100 ? 1 : -1;
+ code = s->core_downmix_codes[i][1] & 0x0FF;
+ s->downmix_coef[i][1] = (!code ? 0.0f :
+ sign * dca_dmixtable[code - 1]);
+ }
+ } else {
+ int am = s->amode & DCA_CHANNEL_MASK;
+ if (am >= FF_ARRAY_ELEMS(dca_default_coeffs)) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "Invalid channel mode %d\n", am);
+ return AVERROR_INVALIDDATA;
+ }
+ if (s->prim_channels + !!s->lfe >
+ FF_ARRAY_ELEMS(dca_default_coeffs[0])) {
+ avpriv_request_sample(s->avctx, "Downmixing %d channels",
+ s->prim_channels + !!s->lfe);
+ return AVERROR_PATCHWELCOME;
+ }
+ for (i = 0; i < s->prim_channels + !!s->lfe; i++) {
+ s->downmix_coef[i][0] = dca_default_coeffs[am][i][0];
+ s->downmix_coef[i][1] = dca_default_coeffs[am][i][1];
+ }
+ }
+ av_dlog(s->avctx, "Stereo downmix coeffs:\n");
+ for (i = 0; i < s->prim_channels + !!s->lfe; i++) {
+ av_dlog(s->avctx, "L, input channel %d = %f\n", i,
+ s->downmix_coef[i][0]);
+ av_dlog(s->avctx, "R, input channel %d = %f\n", i,
+ s->downmix_coef[i][1]);
+ }
+ av_dlog(s->avctx, "\n");
+ }
+
if (s->ext_coding)
s->core_ext_mask = dca_ext_audio_descr_mask[s->ext_descr];
else
@@ -2233,10 +2335,15 @@
{ /* xxx should also do MA extensions */
if (s->amode < 16) {
avctx->channel_layout = dca_core_channel_layout[s->amode];
-
- if (s->xch_present && (!avctx->request_channels ||
- avctx->request_channels
- > num_core_channels + !!s->lfe)) {
+#if FF_API_REQUEST_CHANNELS
+FF_DISABLE_DEPRECATION_WARNINGS
+ if (s->xch_present && !s->xch_disable &&
+ (!avctx->request_channels ||
+ avctx->request_channels > num_core_channels + !!s->lfe)) {
+FF_ENABLE_DEPRECATION_WARNINGS
+#else
+ if (s->xch_present && !s->xch_disable) {
+#endif
avctx->channel_layout |= AV_CH_BACK_CENTER;
if (s->lfe) {
avctx->channel_layout |= AV_CH_LOW_FREQUENCY;
@@ -2265,7 +2372,8 @@
return AVERROR_INVALIDDATA;
}
- if (avctx->request_channels == 2 && s->prim_channels > 2) {
+ if (s->prim_channels + !!s->lfe > 2 &&
+ avctx->request_channel_layout == AV_CH_LAYOUT_STEREO) {
channels = 2;
s->output = DCA_STEREO;
avctx->channel_layout = AV_CH_LAYOUT_STEREO;
@@ -2480,10 +2588,15 @@
avctx->sample_fmt = AV_SAMPLE_FMT_FLTP;
/* allow downmixing to stereo */
- if (avctx->channels > 0 && avctx->request_channels < avctx->channels &&
- avctx->request_channels == 2) {
- avctx->channels = avctx->request_channels;
- }
+#if FF_API_REQUEST_CHANNELS
+FF_DISABLE_DEPRECATION_WARNINGS
+ if (avctx->request_channels == 2)
+ avctx->request_channel_layout = AV_CH_LAYOUT_STEREO;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+ if (avctx->channels > 2 &&
+ avctx->request_channel_layout == AV_CH_LAYOUT_STEREO)
+ avctx->channels = 2;
return 0;
}
@@ -2505,6 +2618,19 @@
{ FF_PROFILE_UNKNOWN },
};
+static const AVOption options[] = {
+ { "disable_xch", "disable decoding of the XCh extension", offsetof(DCAContext, xch_disable), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, AV_OPT_FLAG_DECODING_PARAM|AV_OPT_FLAG_AUDIO_PARAM },
+ { NULL },
+};
+
+static const AVClass dca_decoder_class = {
+ .class_name = "DCA decoder",
+ .item_name = av_default_item_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+ .category = AV_CLASS_CATEGORY_DECODER,
+};
+
AVCodec ff_dca_decoder = {
.name = "dca",
.long_name = NULL_IF_CONFIG_SMALL("DCA (DTS Coherent Acoustics)"),
@@ -2518,4 +2644,5 @@
.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
AV_SAMPLE_FMT_NONE },
.profiles = NULL_IF_CONFIG_SMALL(profiles),
+ .priv_class = &dca_decoder_class,
};
diff --git a/libavcodec/dct-test.c b/libavcodec/dct-test.c
index 4809124..547ea02 100644
--- a/libavcodec/dct-test.c
+++ b/libavcodec/dct-test.c
@@ -47,8 +47,6 @@
#include "x86/idct_xvid.h"
#include "dctref.h"
-#undef printf
-
// BFIN
void ff_bfin_idct(int16_t *block);
void ff_bfin_fdct(int16_t *block);
@@ -63,8 +61,6 @@
void ff_simple_idct_armv6(int16_t *data);
void ff_simple_idct_neon(int16_t *data);
-void ff_simple_idct_axp(int16_t *data);
-
struct algo {
const char *name;
void (*func)(int16_t *block);
@@ -158,10 +154,6 @@
{ "SIMPLE-NEON", ff_simple_idct_neon, PARTTRANS_PERM, AV_CPU_FLAG_NEON },
#endif
-#if ARCH_ALPHA
- { "SIMPLE-ALPHA", ff_simple_idct_axp, NO_PERM },
-#endif
-
{ 0 }
};
@@ -580,5 +572,8 @@
}
}
- return err;
+ if (err)
+ printf("Error: %d.\n", err);
+
+ return !!err;
}
diff --git a/libavcodec/dct32_fixed.c b/libavcodec/dct32_fixed.c
index 1a5528d..9025d5e 100644
--- a/libavcodec/dct32_fixed.c
+++ b/libavcodec/dct32_fixed.c
@@ -17,4 +17,4 @@
*/
#define DCT32_FLOAT 0
-#include "dct32.c"
+#include "dct32_template.c"
diff --git a/libavcodec/dct32_float.c b/libavcodec/dct32_float.c
index 70168f5..597c9bb 100644
--- a/libavcodec/dct32_float.c
+++ b/libavcodec/dct32_float.c
@@ -17,4 +17,4 @@
*/
#define DCT32_FLOAT 1
-#include "dct32.c"
+#include "dct32_template.c"
diff --git a/libavcodec/dct32.c b/libavcodec/dct32_template.c
similarity index 100%
rename from libavcodec/dct32.c
rename to libavcodec/dct32_template.c
diff --git a/libavcodec/dirac.c b/libavcodec/dirac.c
index e132acc..3dad75a 100644
--- a/libavcodec/dirac.c
+++ b/libavcodec/dirac.c
@@ -30,6 +30,7 @@
#include "dirac.h"
#include "avcodec.h"
#include "golomb.h"
+#include "internal.h"
#include "mpeg12data.h"
/* defaults for source parameters */
@@ -317,11 +318,10 @@
if (ret = parse_source_parameters(avctx, gb, source))
return ret;
- if (ret = av_image_check_size(source->width, source->height, 0, avctx))
+ ret = ff_set_dimensions(avctx, source->width, source->height);
+ if (ret < 0)
return ret;
- avcodec_set_dimensions(avctx, source->width, source->height);
-
/* [DIRAC_STD] picture_coding_mode shall be 0 for fields and 1 for frames
* currently only used to signal field coding */
picture_coding_mode = svq3_get_ue_golomb(gb);
diff --git a/libavcodec/diracdec.c b/libavcodec/diracdec.c
index 15baf75..dbc2aab 100644
--- a/libavcodec/diracdec.c
+++ b/libavcodec/diracdec.c
@@ -1414,8 +1414,8 @@
y + p->yblen > p->height+EDGE_WIDTH/2 ||
x < 0 || y < 0) {
for (i = 0; i < nplanes; i++) {
- ff_emulated_edge_mc(s->edge_emu_buffer[i], p->stride,
- src[i], p->stride,
+ ff_emulated_edge_mc(s->edge_emu_buffer[i], src[i],
+ p->stride, p->stride,
p->xblen, p->yblen, x, y,
p->width+EDGE_WIDTH/2, p->height+EDGE_WIDTH/2);
src[i] = s->edge_emu_buffer[i];
diff --git a/libavcodec/dnxhddec.c b/libavcodec/dnxhddec.c
index 15e6c67..42775df 100644
--- a/libavcodec/dnxhddec.c
+++ b/libavcodec/dnxhddec.c
@@ -377,9 +377,9 @@
first_field = 1;
}
- if (av_image_check_size(ctx->width, ctx->height, 0, avctx))
- return -1;
- avcodec_set_dimensions(avctx, ctx->width, ctx->height);
+ ret = ff_set_dimensions(avctx, ctx->width, ctx->height);
+ if (ret < 0)
+ return ret;
if (first_field) {
if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
diff --git a/libavcodec/dnxhdenc.c b/libavcodec/dnxhdenc.c
index 5cf6d8b..c2fbd5c 100644
--- a/libavcodec/dnxhdenc.c
+++ b/libavcodec/dnxhdenc.c
@@ -329,9 +329,12 @@
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);
- ctx->frame.key_frame = 1;
- ctx->frame.pict_type = AV_PICTURE_TYPE_I;
- ctx->m.avctx->coded_frame = &ctx->frame;
+ avctx->coded_frame = av_frame_alloc();
+ if (!avctx->coded_frame)
+ return AVERROR(ENOMEM);
+
+ avctx->coded_frame->key_frame = 1;
+ avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
if (avctx->thread_count > MAX_THREADS) {
av_log(avctx, AV_LOG_ERROR, "too many threads\n");
@@ -922,19 +925,14 @@
{
int i;
- for (i = 0; i < 3; i++) {
- ctx->frame.data[i] = frame->data[i];
- ctx->frame.linesize[i] = frame->linesize[i];
- }
-
for (i = 0; i < ctx->m.avctx->thread_count; i++) {
- ctx->thread[i]->m.linesize = ctx->frame.linesize[0]<<ctx->interlaced;
- ctx->thread[i]->m.uvlinesize = ctx->frame.linesize[1]<<ctx->interlaced;
+ ctx->thread[i]->m.linesize = frame->linesize[0] << ctx->interlaced;
+ ctx->thread[i]->m.uvlinesize = frame->linesize[1] << ctx->interlaced;
ctx->thread[i]->dct_y_offset = ctx->m.linesize *8;
ctx->thread[i]->dct_uv_offset = ctx->m.uvlinesize*8;
}
- ctx->frame.interlaced_frame = frame->interlaced_frame;
+ ctx->m.avctx->coded_frame->interlaced_frame = frame->interlaced_frame;
ctx->cur_field = frame->interlaced_frame && !frame->top_field_first;
}
@@ -954,9 +952,9 @@
encode_coding_unit:
for (i = 0; i < 3; i++) {
- ctx->src[i] = ctx->frame.data[i];
+ ctx->src[i] = frame->data[i];
if (ctx->interlaced && ctx->cur_field)
- ctx->src[i] += ctx->frame.linesize[i];
+ ctx->src[i] += frame->linesize[i];
}
dnxhd_write_header(avctx, buf);
@@ -994,7 +992,7 @@
goto encode_coding_unit;
}
- ctx->frame.quality = ctx->qscale*FF_QP2LAMBDA;
+ avctx->coded_frame->quality = ctx->qscale * FF_QP2LAMBDA;
pkt->flags |= AV_PKT_FLAG_KEY;
*got_packet = 1;
@@ -1027,6 +1025,8 @@
for (i = 1; i < avctx->thread_count; i++)
av_freep(&ctx->thread[i]);
+ av_frame_free(&avctx->coded_frame);
+
return 0;
}
diff --git a/libavcodec/dnxhdenc.h b/libavcodec/dnxhdenc.h
index 9b59b96..110b0ad 100644
--- a/libavcodec/dnxhdenc.h
+++ b/libavcodec/dnxhdenc.h
@@ -43,7 +43,6 @@
AVClass *class;
MpegEncContext m; ///< Used for quantization dsp functions
- AVFrame frame;
int cid;
const CIDEntry *cid_table;
uint8_t *msip; ///< Macroblock Scan Indexes Payload
diff --git a/libavcodec/dpx.c b/libavcodec/dpx.c
index 8468720..5c3c3e8 100644
--- a/libavcodec/dpx.c
+++ b/libavcodec/dpx.c
@@ -111,11 +111,9 @@
buf = avpkt->data + 0x304;
w = read32(&buf, endian);
h = read32(&buf, endian);
- if ((ret = av_image_check_size(w, h, 0, avctx)) < 0)
- return ret;
- if (w != avctx->width || h != avctx->height)
- avcodec_set_dimensions(avctx, w, h);
+ if ((ret = ff_set_dimensions(avctx, w, h)) < 0)
+ return ret;
// Need to end in 0x320 to read the descriptor
buf += 20;
diff --git a/libavcodec/dsicinav.c b/libavcodec/dsicinav.c
index 14bba55..2d06ad8 100644
--- a/libavcodec/dsicinav.c
+++ b/libavcodec/dsicinav.c
@@ -39,7 +39,7 @@
typedef struct CinVideoContext {
AVCodecContext *avctx;
- AVFrame frame;
+ AVFrame *frame;
unsigned int bitmap_size;
uint32_t palette[256];
uint8_t *bitmap_table[3];
@@ -118,7 +118,9 @@
cin->avctx = avctx;
avctx->pix_fmt = AV_PIX_FMT_PAL8;
- avcodec_get_frame_defaults(&cin->frame);
+ cin->frame = av_frame_alloc();
+ if (!cin->frame)
+ return AVERROR(ENOMEM);
cin->bitmap_size = avctx->width * avctx->height;
if (allocate_buffers(cin))
@@ -315,20 +317,20 @@
break;
}
- if ((res = ff_reget_buffer(avctx, &cin->frame)) < 0)
+ if ((res = ff_reget_buffer(avctx, cin->frame)) < 0)
return res;
- memcpy(cin->frame.data[1], cin->palette, sizeof(cin->palette));
- cin->frame.palette_has_changed = 1;
+ memcpy(cin->frame->data[1], cin->palette, sizeof(cin->palette));
+ cin->frame->palette_has_changed = 1;
for (y = 0; y < cin->avctx->height; ++y)
- memcpy(cin->frame.data[0] + (cin->avctx->height - 1 - y) * cin->frame.linesize[0],
+ memcpy(cin->frame->data[0] + (cin->avctx->height - 1 - y) * cin->frame->linesize[0],
cin->bitmap_table[CIN_CUR_BMP] + y * cin->avctx->width,
cin->avctx->width);
FFSWAP(uint8_t *, cin->bitmap_table[CIN_CUR_BMP],
cin->bitmap_table[CIN_PRE_BMP]);
- if ((res = av_frame_ref(data, &cin->frame)) < 0)
+ if ((res = av_frame_ref(data, cin->frame)) < 0)
return res;
*got_frame = 1;
@@ -340,7 +342,7 @@
{
CinVideoContext *cin = avctx->priv_data;
- av_frame_unref(&cin->frame);
+ av_frame_free(&cin->frame);
destroy_buffers(cin);
diff --git a/libavcodec/dsputil.c b/libavcodec/dsputil.c
index 17de1d4..0e9e347 100644
--- a/libavcodec/dsputil.c
+++ b/libavcodec/dsputil.c
@@ -69,9 +69,6 @@
53, 61, 54, 62, 39, 47, 55, 63,
};
-/* not permutated inverse zigzag_direct + 1 for MMX quantizer */
-DECLARE_ALIGNED(16, uint16_t, ff_inv_zigzag_direct16)[64];
-
const uint8_t ff_alternate_horizontal_scan[64] = {
0, 1, 2, 3, 8, 9, 16, 17,
10, 11, 4, 5, 6, 7, 15, 14,
@@ -1516,80 +1513,6 @@
wmv2_mspel8_v_lowpass(dst, halfH+8, stride, 8, 8);
}
-static void h263_v_loop_filter_c(uint8_t *src, int stride, int qscale){
- if(CONFIG_H263_DECODER || CONFIG_H263_ENCODER) {
- int x;
- const int strength= ff_h263_loop_filter_strength[qscale];
-
- for(x=0; x<8; x++){
- int d1, d2, ad1;
- int p0= src[x-2*stride];
- int p1= src[x-1*stride];
- int p2= src[x+0*stride];
- int p3= src[x+1*stride];
- int d = (p0 - p3 + 4*(p2 - p1)) / 8;
-
- if (d<-2*strength) d1= 0;
- else if(d<- strength) d1=-2*strength - d;
- else if(d< strength) d1= d;
- else if(d< 2*strength) d1= 2*strength - d;
- else d1= 0;
-
- p1 += d1;
- p2 -= d1;
- if(p1&256) p1= ~(p1>>31);
- if(p2&256) p2= ~(p2>>31);
-
- src[x-1*stride] = p1;
- src[x+0*stride] = p2;
-
- ad1= FFABS(d1)>>1;
-
- d2= av_clip((p0-p3)/4, -ad1, ad1);
-
- src[x-2*stride] = p0 - d2;
- src[x+ stride] = p3 + d2;
- }
- }
-}
-
-static void h263_h_loop_filter_c(uint8_t *src, int stride, int qscale){
- if(CONFIG_H263_DECODER || CONFIG_H263_ENCODER) {
- int y;
- const int strength= ff_h263_loop_filter_strength[qscale];
-
- for(y=0; y<8; y++){
- int d1, d2, ad1;
- int p0= src[y*stride-2];
- int p1= src[y*stride-1];
- int p2= src[y*stride+0];
- int p3= src[y*stride+1];
- int d = (p0 - p3 + 4*(p2 - p1)) / 8;
-
- if (d<-2*strength) d1= 0;
- else if(d<- strength) d1=-2*strength - d;
- else if(d< strength) d1= d;
- else if(d< 2*strength) d1= 2*strength - d;
- else d1= 0;
-
- p1 += d1;
- p2 -= d1;
- if(p1&256) p1= ~(p1>>31);
- if(p2&256) p2= ~(p2>>31);
-
- src[y*stride-1] = p1;
- src[y*stride+0] = p2;
-
- ad1= FFABS(d1)>>1;
-
- d2= av_clip((p0-p3)/4, -ad1, ad1);
-
- src[y*stride-2] = p0 - d2;
- src[y*stride+1] = p3 + d2;
- }
- }
-}
-
static inline int pix_abs16_c(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h)
{
int s, i;
@@ -1931,7 +1854,7 @@
static void add_bytes_c(uint8_t *dst, uint8_t *src, int w){
long i;
- for(i=0; i<=w-(int)sizeof(long); i+=sizeof(long)){
+ for (i = 0; i <= w - (int)sizeof(long); i += sizeof(long)) {
long a = *(long*)(src+i);
long b = *(long*)(dst+i);
*(long*)(dst+i) = ((a&pb_7f) + (b&pb_7f)) ^ ((a^b)&pb_80);
@@ -1956,7 +1879,7 @@
}
}else
#endif
- for(i=0; i<=w-(int)sizeof(long); i+=sizeof(long)){
+ for (i = 0; i <= w - (int)sizeof(long); i += sizeof(long)) {
long a = *(long*)(src1+i);
long b = *(long*)(src2+i);
*(long*)(dst+i) = ((a|pb_80) - (b&pb_7f)) ^ ((a^b^pb_80)&pb_80);
@@ -2572,19 +2495,6 @@
return res;
}
-static void apply_window_int16_c(int16_t *output, const int16_t *input,
- const int16_t *window, unsigned int len)
-{
- int i;
- int len2 = len >> 1;
-
- for (i = 0; i < len2; i++) {
- int16_t w = window[i];
- output[i] = (MUL16(input[i], w) + (1 << 14)) >> 15;
- output[len-i-1] = (MUL16(input[len-i-1], w) + (1 << 14)) >> 15;
- }
-}
-
static void vector_clip_int32_c(int32_t *dst, const int32_t *src, int32_t min,
int32_t max, unsigned int len)
{
@@ -2651,8 +2561,6 @@
for(i=0;i<512;i++) {
ff_squareTbl[i] = (i - 256) * (i - 256);
}
-
- for(i=0; i<64; i++) ff_inv_zigzag_direct16[ff_zigzag_direct[i]]= i+1;
}
int ff_check_alignment(void){
@@ -2872,18 +2780,12 @@
c->bswap_buf= bswap_buf;
c->bswap16_buf = bswap16_buf;
- if (CONFIG_H263_DECODER || CONFIG_H263_ENCODER) {
- c->h263_h_loop_filter= h263_h_loop_filter_c;
- c->h263_v_loop_filter= h263_v_loop_filter_c;
- }
-
c->try_8x8basis= try_8x8basis_c;
c->add_8x8basis= add_8x8basis_c;
c->vector_clipf = vector_clipf_c;
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->shrink[0]= av_image_copy_plane;
diff --git a/libavcodec/dsputil.h b/libavcodec/dsputil.h
index b9f8bde..0897c56 100644
--- a/libavcodec/dsputil.h
+++ b/libavcodec/dsputil.h
@@ -205,9 +205,6 @@
void (*bswap_buf)(uint32_t *dst, const uint32_t *src, int w);
void (*bswap16_buf)(uint16_t *dst, const uint16_t *src, int len);
- void (*h263_v_loop_filter)(uint8_t *src, int stride, int qscale);
- void (*h263_h_loop_filter)(uint8_t *src, int stride, int qscale);
-
/* assume len is a multiple of 8, and arrays are 16-byte aligned */
void (*vector_clipf)(float *dst /* align 16 */, const float *src /* align 16 */, float min, float max, int len /* align 16 */);
@@ -278,20 +275,6 @@
int32_t (*scalarproduct_and_madd_int16)(int16_t *v1/*align 16*/, const int16_t *v2, const int16_t *v3, int len, int mul);
/**
- * Apply symmetric window in 16-bit fixed-point.
- * @param output destination array
- * constraints: 16-byte aligned
- * @param input source array
- * constraints: 16-byte aligned
- * @param window window array
- * constraints: 16-byte aligned, at least len/2 elements
- * @param len full window length
- * constraints: multiple of ? greater than zero
- */
- void (*apply_window_int16)(int16_t *output, const int16_t *input,
- const int16_t *window, unsigned int len);
-
- /**
* Clip each element in an array of int32_t to a given minimum and maximum value.
* @param dst destination array
* constraints: 16-byte aligned
diff --git a/libavcodec/dv.c b/libavcodec/dv.c
index ba07c71..ea05e9d 100644
--- a/libavcodec/dv.c
+++ b/libavcodec/dv.c
@@ -46,7 +46,7 @@
#include "put_bits.h"
#include "simple_idct.h"
#include "dvdata.h"
-#include "dv_tablegen.h"
+#include "dv.h"
/* XXX: also include quantization */
RL_VLC_ELEM ff_dv_rl_vlc[1184];
@@ -254,20 +254,20 @@
/* it's faster to include sign bit in a generic VLC parsing scheme */
for (i = 0, j = 0; i < NB_DV_VLC; i++, j++) {
- new_dv_vlc_bits[j] = dv_vlc_bits[i];
- new_dv_vlc_len[j] = dv_vlc_len[i];
- new_dv_vlc_run[j] = dv_vlc_run[i];
- new_dv_vlc_level[j] = dv_vlc_level[i];
+ new_dv_vlc_bits[j] = ff_dv_vlc_bits[i];
+ new_dv_vlc_len[j] = ff_dv_vlc_len[i];
+ new_dv_vlc_run[j] = ff_dv_vlc_run[i];
+ new_dv_vlc_level[j] = ff_dv_vlc_level[i];
- if (dv_vlc_level[i]) {
+ if (ff_dv_vlc_level[i]) {
new_dv_vlc_bits[j] <<= 1;
new_dv_vlc_len[j]++;
j++;
- new_dv_vlc_bits[j] = (dv_vlc_bits[i] << 1) | 1;
- new_dv_vlc_len[j] = dv_vlc_len[i] + 1;
- new_dv_vlc_run[j] = dv_vlc_run[i];
- new_dv_vlc_level[j] = -dv_vlc_level[i];
+ new_dv_vlc_bits[j] = (ff_dv_vlc_bits[i] << 1) | 1;
+ new_dv_vlc_len[j] = ff_dv_vlc_len[i] + 1;
+ new_dv_vlc_run[j] = ff_dv_vlc_run[i];
+ new_dv_vlc_level[j] = -ff_dv_vlc_level[i];
}
}
@@ -320,679 +320,9 @@
}else
memcpy(s->dv_zigzag[1], ff_zigzag248_direct, 64);
- avcodec_get_frame_defaults(&s->picture);
- avctx->coded_frame = &s->picture;
s->avctx = avctx;
avctx->chroma_sample_location = AVCHROMA_LOC_TOPLEFT;
return 0;
}
-static av_cold int dvvideo_init_encoder(AVCodecContext *avctx)
-{
- if (!avpriv_dv_codec_profile(avctx)) {
- av_log(avctx, AV_LOG_ERROR, "Found no DV profile for %ix%i %s video. "
- "Valid DV profiles are:\n",
- avctx->width, avctx->height, av_get_pix_fmt_name(avctx->pix_fmt));
- ff_dv_print_profiles(avctx, AV_LOG_ERROR);
- return AVERROR(EINVAL);
- }
- if (avctx->height > 576) {
- av_log(avctx, AV_LOG_ERROR, "DVCPRO HD encoding is not supported.\n");
- return AVERROR_PATCHWELCOME;
- }
-
- dv_vlc_map_tableinit();
-
- return ff_dvvideo_init(avctx);
-}
-
-/* bit budget for AC only in 5 MBs */
-static const int vs_total_ac_bits = (100 * 4 + 68*2) * 5;
-static const int mb_area_start[5] = { 1, 6, 21, 43, 64 };
-
-#if CONFIG_SMALL
-/* 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;
- if (run < DV_VLC_MAP_RUN_SIZE && level < DV_VLC_MAP_LEV_SIZE) {
- *vlc = dv_vlc_map[run][level].vlc | sign;
- size = dv_vlc_map[run][level].size;
- }
- else {
- if (level < DV_VLC_MAP_LEV_SIZE) {
- *vlc = dv_vlc_map[0][level].vlc | sign;
- size = dv_vlc_map[0][level].size;
- } else {
- *vlc = 0xfe00 | (level << 1) | sign;
- size = 16;
- }
- if (run) {
- *vlc |= ((run < 16) ? dv_vlc_map[run-1][0].vlc :
- (0x1f80 | (run - 1))) << size;
- size += (run < 16) ? dv_vlc_map[run-1][0].size : 13;
- }
- }
-
- return size;
-}
-
-static av_always_inline int dv_rl2vlc_size(int run, int level)
-{
- int size;
-
- if (run < DV_VLC_MAP_RUN_SIZE && level < DV_VLC_MAP_LEV_SIZE) {
- size = dv_vlc_map[run][level].size;
- }
- else {
- size = (level < DV_VLC_MAP_LEV_SIZE) ? dv_vlc_map[0][level].size : 16;
- if (run) {
- size += (run < 16) ? dv_vlc_map[run-1][0].size : 13;
- }
- }
- return size;
-}
-#else
-static av_always_inline int dv_rl2vlc(int run, int l, int sign, uint32_t* vlc)
-{
- *vlc = dv_vlc_map[run][l].vlc | sign;
- return dv_vlc_map[run][l].size;
-}
-
-static av_always_inline int dv_rl2vlc_size(int run, int l)
-{
- return dv_vlc_map[run][l].size;
-}
-#endif
-
-typedef struct EncBlockInfo {
- int area_q[4];
- int bit_size[4];
- int prev[5];
- int cur_ac;
- int cno;
- int dct_mode;
- int16_t mb[64];
- uint8_t next[64];
- uint8_t sign[64];
- uint8_t partial_bit_count;
- uint32_t partial_bit_buffer; /* we can't use uint16_t here */
-} EncBlockInfo;
-
-static av_always_inline PutBitContext* dv_encode_ac(EncBlockInfo* bi,
- PutBitContext* pb_pool,
- PutBitContext* pb_end)
-{
- int prev, bits_left;
- PutBitContext* pb = pb_pool;
- int size = bi->partial_bit_count;
- uint32_t vlc = bi->partial_bit_buffer;
-
- bi->partial_bit_count = bi->partial_bit_buffer = 0;
- for (;;){
- /* Find suitable storage space */
- for (; size > (bits_left = put_bits_left(pb)); pb++) {
- if (bits_left) {
- size -= bits_left;
- put_bits(pb, bits_left, vlc >> size);
- vlc = vlc & ((1 << size) - 1);
- }
- if (pb + 1 >= pb_end) {
- bi->partial_bit_count = size;
- bi->partial_bit_buffer = vlc;
- return pb;
- }
- }
-
- /* Store VLC */
- put_bits(pb, size, vlc);
-
- if (bi->cur_ac >= 64)
- break;
-
- /* Construct the next VLC */
- prev = bi->cur_ac;
- bi->cur_ac = bi->next[prev];
- if (bi->cur_ac < 64){
- size = dv_rl2vlc(bi->cur_ac - prev - 1, bi->mb[bi->cur_ac], bi->sign[bi->cur_ac], &vlc);
- } else {
- size = 4; vlc = 6; /* End Of Block stamp */
- }
- }
- return pb;
-}
-
-static av_always_inline int dv_guess_dct_mode(DVVideoContext *s, uint8_t *data, int linesize) {
- if (s->avctx->flags & CODEC_FLAG_INTERLACED_DCT) {
- int ps = s->ildct_cmp(NULL, data, NULL, linesize, 8) - 400;
- if (ps > 0) {
- int is = s->ildct_cmp(NULL, data , NULL, linesize<<1, 4) +
- s->ildct_cmp(NULL, data + linesize, NULL, linesize<<1, 4);
- return ps > is;
- }
- }
-
- return 0;
-}
-
-static const int dv_weight_bits = 18;
-static const int dv_weight_88[64] = {
- 131072, 257107, 257107, 242189, 252167, 242189, 235923, 237536,
- 237536, 235923, 229376, 231390, 223754, 231390, 229376, 222935,
- 224969, 217965, 217965, 224969, 222935, 200636, 218652, 211916,
- 212325, 211916, 218652, 200636, 188995, 196781, 205965, 206433,
- 206433, 205965, 196781, 188995, 185364, 185364, 200636, 200704,
- 200636, 185364, 185364, 174609, 180568, 195068, 195068, 180568,
- 174609, 170091, 175557, 189591, 175557, 170091, 165371, 170627,
- 170627, 165371, 160727, 153560, 160727, 144651, 144651, 136258,
-};
-static const int dv_weight_248[64] = {
- 131072, 242189, 257107, 237536, 229376, 200636, 242189, 223754,
- 224969, 196781, 262144, 242189, 229376, 200636, 257107, 237536,
- 211916, 185364, 235923, 217965, 229376, 211916, 206433, 180568,
- 242189, 223754, 224969, 196781, 211916, 185364, 235923, 217965,
- 200704, 175557, 222935, 205965, 200636, 185364, 195068, 170627,
- 229376, 211916, 206433, 180568, 200704, 175557, 222935, 205965,
- 175557, 153560, 188995, 174609, 165371, 144651, 200636, 185364,
- 195068, 170627, 175557, 153560, 188995, 174609, 165371, 144651,
-};
-
-static av_always_inline int dv_init_enc_block(EncBlockInfo* bi, uint8_t *data, int linesize, DVVideoContext *s, int bias)
-{
- const int *weight;
- const uint8_t* zigzag_scan;
- LOCAL_ALIGNED_16(int16_t, blk, [64]);
- int i, area;
- /* We offer two different methods for class number assignment: the
- method suggested in SMPTE 314M Table 22, and an improved
- method. The SMPTE method is very conservative; it assigns class
- 3 (i.e. severe quantization) to any block where the largest AC
- component is greater than 36. FFmpeg's DV encoder tracks AC bit
- consumption precisely, so there is no need to bias most blocks
- towards strongly lossy compression. Instead, we assign class 2
- to most blocks, and use class 3 only when strictly necessary
- (for blocks whose largest AC component exceeds 255). */
-
-#if 0 /* SMPTE spec method */
- static const int classes[] = {12, 24, 36, 0xffff};
-#else /* improved FFmpeg method */
- static const int classes[] = {-1, -1, 255, 0xffff};
-#endif
- int max = classes[0];
- int prev = 0;
-
- av_assert2((((int)blk) & 15) == 0);
-
- bi->area_q[0] = bi->area_q[1] = bi->area_q[2] = bi->area_q[3] = 0;
- bi->partial_bit_count = 0;
- bi->partial_bit_buffer = 0;
- bi->cur_ac = 0;
- if (data) {
- bi->dct_mode = dv_guess_dct_mode(s, data, linesize);
- s->get_pixels(blk, data, linesize);
- s->fdct[bi->dct_mode](blk);
- } else {
- /* We rely on the fact that encoding all zeros leads to an immediate EOB,
- which is precisely what the spec calls for in the "dummy" blocks. */
- memset(blk, 0, 64*sizeof(*blk));
- bi->dct_mode = 0;
- }
- bi->mb[0] = blk[0];
-
- zigzag_scan = bi->dct_mode ? ff_zigzag248_direct : ff_zigzag_direct;
- weight = bi->dct_mode ? dv_weight_248 : dv_weight_88;
-
- for (area = 0; area < 4; area++) {
- bi->prev[area] = prev;
- bi->bit_size[area] = 1; // 4 areas 4 bits for EOB :)
- for (i = mb_area_start[area]; i < mb_area_start[area+1]; i++) {
- int level = blk[zigzag_scan[i]];
-
- if (level + 15 > 30U) {
- bi->sign[i] = (level >> 31) & 1;
- /* weight it 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);
- bi->mb[i] = level;
- if (level > max)
- max = level;
- bi->bit_size[area] += dv_rl2vlc_size(i - prev - 1, level);
- bi->next[prev]= i;
- prev = i;
- }
- }
- }
- bi->next[prev]= i;
- for (bi->cno = 0; max > classes[bi->cno]; bi->cno++);
-
- bi->cno += bias;
-
- if (bi->cno >= 3) {
- bi->cno = 3;
- prev = 0;
- i = bi->next[prev];
- for (area = 0; area < 4; area++) {
- bi->prev[area] = prev;
- bi->bit_size[area] = 1; // 4 areas 4 bits for EOB :)
- for (; i < mb_area_start[area+1]; i = bi->next[i]) {
- bi->mb[i] >>= 1;
-
- if (bi->mb[i]) {
- bi->bit_size[area] += dv_rl2vlc_size(i - prev - 1, bi->mb[i]);
- bi->next[prev]= i;
- prev = i;
- }
- }
- }
- bi->next[prev]= i;
- }
-
- return bi->bit_size[0] + bi->bit_size[1] + bi->bit_size[2] + bi->bit_size[3];
-}
-
-static inline void dv_guess_qnos(EncBlockInfo* blks, int* qnos)
-{
- int size[5];
- int i, j, k, a, prev, a2;
- EncBlockInfo* b;
-
- size[0] = size[1] = size[2] = size[3] = size[4] = 1 << 24;
- do {
- b = blks;
- for (i = 0; i < 5; i++) {
- if (!qnos[i])
- continue;
-
- qnos[i]--;
- size[i] = 0;
- for (j = 0; j < 6; j++, b++) {
- for (a = 0; a < 4; a++) {
- if (b->area_q[a] != ff_dv_quant_shifts[qnos[i] + ff_dv_quant_offset[b->cno]][a]) {
- b->bit_size[a] = 1; // 4 areas 4 bits for EOB :)
- b->area_q[a]++;
- prev = b->prev[a];
- av_assert2(b->next[prev] >= mb_area_start[a+1] || b->mb[prev]);
- for (k = b->next[prev] ; k < mb_area_start[a+1]; k = b->next[k]) {
- b->mb[k] >>= 1;
- if (b->mb[k]) {
- b->bit_size[a] += dv_rl2vlc_size(k - prev - 1, b->mb[k]);
- prev = k;
- } else {
- if (b->next[k] >= mb_area_start[a+1] && b->next[k]<64){
- for (a2 = a + 1; b->next[k] >= mb_area_start[a2+1]; a2++)
- b->prev[a2] = prev;
- av_assert2(a2 < 4);
- av_assert2(b->mb[b->next[k]]);
- b->bit_size[a2] += dv_rl2vlc_size(b->next[k] - prev - 1, b->mb[b->next[k]])
- -dv_rl2vlc_size(b->next[k] - k - 1, b->mb[b->next[k]]);
- av_assert2(b->prev[a2] == k && (a2 + 1 >= 4 || b->prev[a2+1] != k));
- b->prev[a2] = prev;
- }
- b->next[prev] = b->next[k];
- }
- }
- b->prev[a+1]= prev;
- }
- size[i] += b->bit_size[a];
- }
- }
- if (vs_total_ac_bits >= size[0] + size[1] + size[2] + size[3] + size[4])
- return;
- }
- } while (qnos[0]|qnos[1]|qnos[2]|qnos[3]|qnos[4]);
-
-
- for (a = 2; a == 2 || vs_total_ac_bits < size[0]; a += a){
- b = blks;
- size[0] = 5 * 6 * 4; //EOB
- for (j = 0; j < 6 *5; j++, b++) {
- prev = b->prev[0];
- for (k = b->next[prev]; k < 64; k = b->next[k]) {
- if (b->mb[k] < a && b->mb[k] > -a){
- b->next[prev] = b->next[k];
- }else{
- size[0] += dv_rl2vlc_size(k - prev - 1, b->mb[k]);
- prev = k;
- }
- }
- }
- }
-}
-
-static int dv_encode_video_segment(AVCodecContext *avctx, void *arg)
-{
- DVVideoContext *s = avctx->priv_data;
- DVwork_chunk *work_chunk = arg;
- int mb_index, i, j;
- int mb_x, mb_y, c_offset, linesize, y_stride;
- uint8_t* y_ptr;
- uint8_t* dif;
- LOCAL_ALIGNED_8(uint8_t, scratch, [128]);
- EncBlockInfo enc_blks[5*DV_MAX_BPM];
- PutBitContext pbs[5*DV_MAX_BPM];
- PutBitContext* pb;
- EncBlockInfo* enc_blk;
- int vs_bit_size = 0;
- int qnos[5] = {15, 15, 15, 15, 15}; /* No quantization */
- int* qnosp = &qnos[0];
-
- dif = &s->buf[work_chunk->buf_offset*80];
- enc_blk = &enc_blks[0];
- for (mb_index = 0; mb_index < 5; mb_index++) {
- dv_calculate_mb_xy(s, work_chunk, mb_index, &mb_x, &mb_y);
-
- /* initializing luminance blocks */
- if ((s->sys->pix_fmt == AV_PIX_FMT_YUV420P) ||
- (s->sys->pix_fmt == AV_PIX_FMT_YUV411P && mb_x >= (704 / 8)) ||
- (s->sys->height >= 720 && mb_y != 134)) {
- y_stride = s->picture.linesize[0] << 3;
- } else {
- y_stride = 16;
- }
- y_ptr = s->picture.data[0] + ((mb_y * s->picture.linesize[0] + mb_x) << 3);
- linesize = s->picture.linesize[0];
-
- if (s->sys->video_stype == 4) { /* SD 422 */
- vs_bit_size +=
- dv_init_enc_block(enc_blk+0, y_ptr , linesize, s, 0) +
- dv_init_enc_block(enc_blk+1, NULL , linesize, s, 0) +
- dv_init_enc_block(enc_blk+2, y_ptr + 8 , linesize, s, 0) +
- dv_init_enc_block(enc_blk+3, NULL , linesize, s, 0);
- } else {
- vs_bit_size +=
- dv_init_enc_block(enc_blk+0, y_ptr , linesize, s, 0) +
- dv_init_enc_block(enc_blk+1, y_ptr + 8 , linesize, s, 0) +
- dv_init_enc_block(enc_blk+2, y_ptr + y_stride, linesize, s, 0) +
- dv_init_enc_block(enc_blk+3, y_ptr + 8 + y_stride, linesize, s, 0);
- }
- enc_blk += 4;
-
- /* initializing chrominance blocks */
- c_offset = (((mb_y >> (s->sys->pix_fmt == AV_PIX_FMT_YUV420P)) * s->picture.linesize[1] +
- (mb_x >> ((s->sys->pix_fmt == AV_PIX_FMT_YUV411P) ? 2 : 1))) << 3);
- for (j = 2; j; j--) {
- uint8_t *c_ptr = s->picture.data[j] + c_offset;
- linesize = s->picture.linesize[j];
- y_stride = (mb_y == 134) ? 8 : (s->picture.linesize[j] << 3);
- if (s->sys->pix_fmt == AV_PIX_FMT_YUV411P && mb_x >= (704 / 8)) {
- uint8_t* d;
- uint8_t* b = scratch;
- for (i = 0; i < 8; i++) {
- d = c_ptr + (linesize << 3);
- b[0] = c_ptr[0]; b[1] = c_ptr[1]; b[2] = c_ptr[2]; b[3] = c_ptr[3];
- b[4] = d[0]; b[5] = d[1]; b[6] = d[2]; b[7] = d[3];
- c_ptr += linesize;
- b += 16;
- }
- c_ptr = scratch;
- linesize = 16;
- }
-
- vs_bit_size += dv_init_enc_block( enc_blk++, c_ptr , linesize, s, 1);
- if (s->sys->bpm == 8) {
- vs_bit_size += dv_init_enc_block(enc_blk++, c_ptr + y_stride, linesize, s, 1);
- }
- }
- }
-
- if (vs_total_ac_bits < vs_bit_size)
- dv_guess_qnos(&enc_blks[0], qnosp);
-
- /* DIF encoding process */
- for (j=0; j<5*s->sys->bpm;) {
- int start_mb = j;
-
- dif[3] = *qnosp++;
- dif += 4;
-
- /* First pass over individual cells only */
- for (i=0; i<s->sys->bpm; i++, j++) {
- int sz = s->sys->block_sizes[i]>>3;
-
- init_put_bits(&pbs[j], dif, sz);
- put_sbits(&pbs[j], 9, ((enc_blks[j].mb[0] >> 3) - 1024 + 2) >> 2);
- put_bits(&pbs[j], 1, enc_blks[j].dct_mode);
- put_bits(&pbs[j], 2, enc_blks[j].cno);
-
- dv_encode_ac(&enc_blks[j], &pbs[j], &pbs[j+1]);
- dif += sz;
- }
-
- /* Second pass over each MB space */
- pb = &pbs[start_mb];
- for (i=0; i<s->sys->bpm; i++) {
- if (enc_blks[start_mb+i].partial_bit_count)
- pb = dv_encode_ac(&enc_blks[start_mb+i], pb, &pbs[start_mb+s->sys->bpm]);
- }
- }
-
- /* Third and final pass over the whole video segment space */
- pb = &pbs[0];
- for (j=0; j<5*s->sys->bpm; j++) {
- if (enc_blks[j].partial_bit_count)
- pb = dv_encode_ac(&enc_blks[j], pb, &pbs[s->sys->bpm*5]);
- if (enc_blks[j].partial_bit_count)
- av_log(avctx, AV_LOG_ERROR, "ac bitstream overflow\n");
- }
-
- for (j=0; j<5*s->sys->bpm; j++) {
- int pos;
- int size = pbs[j].size_in_bits >> 3;
- flush_put_bits(&pbs[j]);
- pos = put_bits_count(&pbs[j]) >> 3;
- if (pos > size) {
- av_log(avctx, AV_LOG_ERROR, "bitstream written beyond buffer size\n");
- return -1;
- }
- memset(pbs[j].buf + pos, 0xff, size - pos);
- }
-
- return 0;
-}
-
-static inline int dv_write_pack(enum dv_pack_type pack_id, DVVideoContext *c,
- uint8_t* buf)
-{
- /*
- * Here's what SMPTE314M says about these two:
- * (page 6) APTn, AP1n, AP2n, AP3n: These data shall be identical
- * as track application IDs (APTn = 001, AP1n =
- * 001, AP2n = 001, AP3n = 001), if the source signal
- * comes from a digital VCR. If the signal source is
- * unknown, all bits for these data shall be set to 1.
- * (page 12) STYPE: STYPE defines a signal type of video signal
- * 00000b = 4:1:1 compression
- * 00100b = 4:2:2 compression
- * XXXXXX = Reserved
- * Now, I've got two problems with these statements:
- * 1. it looks like APT == 111b should be a safe bet, but it isn't.
- * It seems that for PAL as defined in IEC 61834 we have to set
- * APT to 000 and for SMPTE314M to 001.
- * 2. It is not at all clear what STYPE is used for 4:2:0 PAL
- * compression scheme (if any).
- */
- int apt = (c->sys->pix_fmt == AV_PIX_FMT_YUV420P ? 0 : 1);
- int fs = c->picture.top_field_first ? 0x00 : 0x40;
-
- uint8_t aspect = 0;
- if ((int)(av_q2d(c->avctx->sample_aspect_ratio) * c->avctx->width / c->avctx->height * 10) >= 17) /* 16:9 */
- aspect = 0x02;
-
- buf[0] = (uint8_t)pack_id;
- switch (pack_id) {
- case dv_header525: /* I can't imagine why these two weren't defined as real */
- case dv_header625: /* packs in SMPTE314M -- they definitely look like ones */
- buf[1] = 0xf8 | /* reserved -- always 1 */
- (apt & 0x07); /* APT: Track application ID */
- buf[2] = (0 << 7) | /* TF1: audio data is 0 - valid; 1 - invalid */
- (0x0f << 3) | /* reserved -- always 1 */
- (apt & 0x07); /* AP1: Audio application ID */
- buf[3] = (0 << 7) | /* TF2: video data is 0 - valid; 1 - invalid */
- (0x0f << 3) | /* reserved -- always 1 */
- (apt & 0x07); /* AP2: Video application ID */
- buf[4] = (0 << 7) | /* TF3: subcode(SSYB) is 0 - valid; 1 - invalid */
- (0x0f << 3) | /* reserved -- always 1 */
- (apt & 0x07); /* AP3: Subcode application ID */
- break;
- case dv_video_source:
- buf[1] = 0xff; /* reserved -- always 1 */
- buf[2] = (1 << 7) | /* B/W: 0 - b/w, 1 - color */
- (1 << 6) | /* following CLF is valid - 0, invalid - 1 */
- (3 << 4) | /* CLF: color frames ID (see ITU-R BT.470-4) */
- 0xf; /* reserved -- always 1 */
- buf[3] = (3 << 6) | /* reserved -- always 1 */
- (c->sys->dsf << 5) | /* system: 60fields/50fields */
- c->sys->video_stype; /* signal type video compression */
- buf[4] = 0xff; /* VISC: 0xff -- no information */
- break;
- case dv_video_control:
- buf[1] = (0 << 6) | /* Copy generation management (CGMS) 0 -- free */
- 0x3f; /* reserved -- always 1 */
- buf[2] = 0xc8 | /* reserved -- always b11001xxx */
- aspect;
- buf[3] = (1 << 7) | /* frame/field flag 1 -- frame, 0 -- field */
- fs | /* first/second field flag 0 -- field 2, 1 -- field 1 */
- (1 << 5) | /* frame change flag 0 -- same picture as before, 1 -- different */
- (1 << 4) | /* 1 - interlaced, 0 - noninterlaced */
- 0xc; /* reserved -- always b1100 */
- buf[4] = 0xff; /* reserved -- always 1 */
- break;
- default:
- buf[1] = buf[2] = buf[3] = buf[4] = 0xff;
- }
- return 5;
-}
-
-#if CONFIG_DVVIDEO_ENCODER
-static inline int dv_write_dif_id(enum dv_section_type t, uint8_t chan_num,
- uint8_t seq_num, uint8_t dif_num,
- uint8_t* buf)
-{
- buf[0] = (uint8_t)t; /* Section type */
- buf[1] = (seq_num << 4) | /* DIF seq number 0-9 for 525/60; 0-11 for 625/50 */
- (chan_num << 3) | /* FSC: for 50Mb/s 0 - first channel; 1 - second */
- 7; /* reserved -- always 1 */
- buf[2] = dif_num; /* DIF block number Video: 0-134, Audio: 0-8 */
- return 3;
-}
-
-
-static inline int dv_write_ssyb_id(uint8_t syb_num, uint8_t fr, uint8_t* buf)
-{
- if (syb_num == 0 || syb_num == 6) {
- buf[0] = (fr << 7) | /* FR ID 1 - first half of each channel; 0 - second */
- (0 << 4) | /* AP3 (Subcode application ID) */
- 0x0f; /* reserved -- always 1 */
- }
- else if (syb_num == 11) {
- buf[0] = (fr << 7) | /* FR ID 1 - first half of each channel; 0 - second */
- 0x7f; /* reserved -- always 1 */
- }
- else {
- buf[0] = (fr << 7) | /* FR ID 1 - first half of each channel; 0 - second */
- (0 << 4) | /* APT (Track application ID) */
- 0x0f; /* reserved -- always 1 */
- }
- buf[1] = 0xf0 | /* reserved -- always 1 */
- (syb_num & 0x0f); /* SSYB number 0 - 11 */
- buf[2] = 0xff; /* reserved -- always 1 */
- return 3;
-}
-
-static void dv_format_frame(DVVideoContext* c, uint8_t* buf)
-{
- int chan, i, j, k;
-
- for (chan = 0; chan < c->sys->n_difchan; chan++) {
- for (i = 0; i < c->sys->difseg_size; i++) {
- memset(buf, 0xff, 80 * 6); /* first 6 DIF blocks are for control data */
-
- /* DV header: 1DIF */
- buf += dv_write_dif_id(dv_sect_header, chan, i, 0, buf);
- buf += dv_write_pack((c->sys->dsf ? dv_header625 : dv_header525), c, buf);
- buf += 72; /* unused bytes */
-
- /* DV subcode: 2DIFs */
- for (j = 0; j < 2; j++) {
- buf += dv_write_dif_id(dv_sect_subcode, chan, i, j, buf);
- for (k = 0; k < 6; k++)
- buf += dv_write_ssyb_id(k, (i < c->sys->difseg_size/2), buf) + 5;
- buf += 29; /* unused bytes */
- }
-
- /* DV VAUX: 3DIFS */
- for (j = 0; j < 3; j++) {
- buf += dv_write_dif_id(dv_sect_vaux, chan, i, j, buf);
- buf += dv_write_pack(dv_video_source, c, buf);
- buf += dv_write_pack(dv_video_control, c, buf);
- buf += 7*5;
- buf += dv_write_pack(dv_video_source, c, buf);
- buf += dv_write_pack(dv_video_control, c, buf);
- buf += 4*5 + 2; /* unused bytes */
- }
-
- /* DV Audio/Video: 135 Video DIFs + 9 Audio DIFs */
- for (j = 0; j < 135; j++) {
- if (j%15 == 0) {
- memset(buf, 0xff, 80);
- buf += dv_write_dif_id(dv_sect_audio, chan, i, j/15, buf);
- buf += 77; /* audio control & shuffled PCM audio */
- }
- buf += dv_write_dif_id(dv_sect_video, chan, i, j, buf);
- buf += 77; /* 1 video macroblock: 1 bytes control
- 4 * 14 bytes Y 8x8 data
- 10 bytes Cr 8x8 data
- 10 bytes Cb 8x8 data */
- }
- }
- }
-}
-
-
-static int dvvideo_encode_frame(AVCodecContext *c, AVPacket *pkt,
- const AVFrame *frame, int *got_packet)
-{
- DVVideoContext *s = c->priv_data;
- int ret;
-
- s->sys = avpriv_dv_codec_profile(c);
- if (!s->sys || ff_dv_init_dynamic_tables(s->sys))
- return -1;
- if ((ret = ff_alloc_packet2(c, pkt, s->sys->frame_size)) < 0)
- return ret;
-
- c->pix_fmt = s->sys->pix_fmt;
- s->picture = *frame;
- s->picture.key_frame = 1;
- s->picture.pict_type = AV_PICTURE_TYPE_I;
-
- s->buf = pkt->data;
- c->execute(c, dv_encode_video_segment, s->sys->work_chunks, NULL,
- dv_work_pool_size(s->sys), sizeof(DVwork_chunk));
-
- emms_c();
-
- dv_format_frame(s, pkt->data);
-
- pkt->flags |= AV_PKT_FLAG_KEY;
- *got_packet = 1;
-
- return 0;
-}
-
-AVCodec ff_dvvideo_encoder = {
- .name = "dvvideo",
- .long_name = NULL_IF_CONFIG_SMALL("DV (Digital Video)"),
- .type = AVMEDIA_TYPE_VIDEO,
- .id = AV_CODEC_ID_DVVIDEO,
- .priv_data_size = sizeof(DVVideoContext),
- .init = dvvideo_init_encoder,
- .encode2 = dvvideo_encode_frame,
- .capabilities = CODEC_CAP_SLICE_THREADS,
- .pix_fmts = (const enum AVPixelFormat[]) {
- AV_PIX_FMT_YUV411P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE
- },
-};
-#endif // CONFIG_DVVIDEO_ENCODER
diff --git a/libavcodec/dv.h b/libavcodec/dv.h
new file mode 100644
index 0000000..73ceb7f
--- /dev/null
+++ b/libavcodec/dv.h
@@ -0,0 +1,115 @@
+/*
+ * Constants for DV codec
+ * Copyright (c) 2002 Fabrice Bellard
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * Constants for DV codec.
+ */
+
+#ifndef AVCODEC_DV_H
+#define AVCODEC_DV_H
+
+#include "avcodec.h"
+#include "dsputil.h"
+#include "get_bits.h"
+#include "dv_profile.h"
+
+typedef struct DVVideoContext {
+ const DVprofile *sys;
+ AVFrame *frame;
+ AVCodecContext *avctx;
+ uint8_t *buf;
+
+ uint8_t dv_zigzag[2][64];
+
+ void (*get_pixels)(int16_t *block, const uint8_t *pixels, int line_size);
+ void (*fdct[2])(int16_t *block);
+ void (*idct_put[2])(uint8_t *dest, int line_size, int16_t *block);
+ me_cmp_func ildct_cmp;
+} DVVideoContext;
+
+enum dv_section_type {
+ dv_sect_header = 0x1f,
+ dv_sect_subcode = 0x3f,
+ dv_sect_vaux = 0x56,
+ dv_sect_audio = 0x76,
+ dv_sect_video = 0x96,
+};
+
+enum dv_pack_type {
+ dv_header525 = 0x3f, /* see dv_write_pack for important details on */
+ dv_header625 = 0xbf, /* these two packs */
+ dv_timecode = 0x13,
+ dv_audio_source = 0x50,
+ dv_audio_control = 0x51,
+ dv_audio_recdate = 0x52,
+ dv_audio_rectime = 0x53,
+ dv_video_source = 0x60,
+ dv_video_control = 0x61,
+ dv_video_recdate = 0x62,
+ dv_video_rectime = 0x63,
+ dv_unknown_pack = 0xff,
+};
+
+#define DV_PROFILE_IS_HD(p) ((p)->video_stype & 0x10)
+#define DV_PROFILE_IS_1080i50(p) (((p)->video_stype == 0x14) && ((p)->dsf == 1))
+#define DV_PROFILE_IS_720p50(p) (((p)->video_stype == 0x18) && ((p)->dsf == 1))
+
+
+/**
+ * largest possible DV frame, in bytes (1080i50)
+ */
+#define DV_MAX_FRAME_SIZE 576000
+
+/**
+ * maximum number of blocks per macroblock in any DV format
+ */
+#define DV_MAX_BPM 8
+
+#define TEX_VLC_BITS 9
+
+extern RL_VLC_ELEM ff_dv_rl_vlc[1184];
+
+int ff_dv_init_dynamic_tables(const DVprofile *d);
+int ff_dvvideo_init(AVCodecContext *avctx);
+
+static inline int dv_work_pool_size(const DVprofile *d)
+{
+ int size = d->n_difchan*d->difseg_size*27;
+ if (DV_PROFILE_IS_1080i50(d))
+ size -= 3*27;
+ if (DV_PROFILE_IS_720p50(d))
+ size -= 4*27;
+ return size;
+}
+
+static inline void dv_calculate_mb_xy(DVVideoContext *s, DVwork_chunk *work_chunk, int m, int *mb_x, int *mb_y)
+{
+ *mb_x = work_chunk->mb_coordinates[m] & 0xff;
+ *mb_y = work_chunk->mb_coordinates[m] >> 8;
+
+ /* We work with 720p frames split in half. The odd half-frame (chan==2,3) is displaced :-( */
+ if (s->sys->height == 720 && !(s->buf[1]&0x0C)) {
+ *mb_y -= (*mb_y>17)?18:-72; /* shifting the Y coordinate down by 72/2 macro blocks */
+ }
+}
+
+#endif /* AVCODEC_DV_H */
diff --git a/libavcodec/dv_tablegen.c b/libavcodec/dv_tablegen.c
index 5d3793e..2579341 100644
--- a/libavcodec/dv_tablegen.c
+++ b/libavcodec/dv_tablegen.c
@@ -22,9 +22,6 @@
#include <stdlib.h>
#define CONFIG_HARDCODED_TABLES 0
-#ifndef CONFIG_SMALL
-#error CONFIG_SMALL must be defined to generate tables
-#endif
#include "dv_tablegen.h"
#include "tableprint.h"
#include <inttypes.h>
diff --git a/libavcodec/dv_tablegen.h b/libavcodec/dv_tablegen.h
index e8cdc21..c04b802 100644
--- a/libavcodec/dv_tablegen.h
+++ b/libavcodec/dv_tablegen.h
@@ -25,7 +25,7 @@
#include <stdint.h>
-#include "dv_vlc_data.h"
+#include "dvdata.h"
#if CONFIG_SMALL
#define DV_VLC_MAP_RUN_SIZE 15
@@ -51,20 +51,20 @@
{
int i, j;
for (i = 0; i < NB_DV_VLC - 1; i++) {
- if (dv_vlc_run[i] >= DV_VLC_MAP_RUN_SIZE)
+ if (ff_dv_vlc_run[i] >= DV_VLC_MAP_RUN_SIZE)
continue;
#if CONFIG_SMALL
- if (dv_vlc_level[i] >= DV_VLC_MAP_LEV_SIZE)
+ if (ff_dv_vlc_level[i] >= DV_VLC_MAP_LEV_SIZE)
continue;
#endif
- if (dv_vlc_map[dv_vlc_run[i]][dv_vlc_level[i]].size != 0)
+ if (dv_vlc_map[ff_dv_vlc_run[i]][ff_dv_vlc_level[i]].size != 0)
continue;
- dv_vlc_map[dv_vlc_run[i]][dv_vlc_level[i]].vlc =
- dv_vlc_bits[i] << (!!dv_vlc_level[i]);
- dv_vlc_map[dv_vlc_run[i]][dv_vlc_level[i]].size =
- dv_vlc_len[i] + (!!dv_vlc_level[i]);
+ dv_vlc_map[ff_dv_vlc_run[i]][ff_dv_vlc_level[i]].vlc =
+ ff_dv_vlc_bits[i] << (!!ff_dv_vlc_level[i]);
+ dv_vlc_map[ff_dv_vlc_run[i]][ff_dv_vlc_level[i]].size =
+ ff_dv_vlc_len[i] + (!!ff_dv_vlc_level[i]);
}
for (i = 0; i < DV_VLC_MAP_RUN_SIZE; i++) {
#if CONFIG_SMALL
diff --git a/libavcodec/dv_vlc_data.h b/libavcodec/dv_vlc_data.h
deleted file mode 100644
index be768e6..0000000
--- a/libavcodec/dv_vlc_data.h
+++ /dev/null
@@ -1,259 +0,0 @@
-/*
- * VLC constants for DV codec
- * Copyright (c) 2002 Fabrice Bellard
- *
- * This file is part of FFmpeg.
- *
- * FFmpeg is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * FFmpeg is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with FFmpeg; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/**
- * @file
- * VLC constants for DV codec.
- */
-
-#ifndef AVCODEC_DV_VLC_DATA_H
-#define AVCODEC_DV_VLC_DATA_H
-
-#include <stdint.h>
-
-#define NB_DV_VLC 409
-
-/*
- * There's a catch about the following three tables: the mapping they establish
- * between (run, level) and vlc is not 1-1. So you have to watch out for that
- * when building misc. tables. E.g. (1, 0) can be either 0x7cf or 0x1f82.
- */
-static const uint16_t dv_vlc_bits[NB_DV_VLC] = {
- 0x0000, 0x0002, 0x0007, 0x0008, 0x0009, 0x0014, 0x0015, 0x0016,
- 0x0017, 0x0030, 0x0031, 0x0032, 0x0033, 0x0068, 0x0069, 0x006a,
- 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0x00e0, 0x00e1, 0x00e2,
- 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, 0x00e8, 0x00e9, 0x00ea,
- 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, 0x01e0, 0x01e1, 0x01e2,
- 0x01e3, 0x01e4, 0x01e5, 0x01e6, 0x01e7, 0x01e8, 0x01e9, 0x01ea,
- 0x01eb, 0x01ec, 0x01ed, 0x01ee, 0x01ef, 0x03e0, 0x03e1, 0x03e2,
- 0x03e3, 0x03e4, 0x03e5, 0x03e6, 0x07ce, 0x07cf, 0x07d0, 0x07d1,
- 0x07d2, 0x07d3, 0x07d4, 0x07d5, 0x0fac, 0x0fad, 0x0fae, 0x0faf,
- 0x0fb0, 0x0fb1, 0x0fb2, 0x0fb3, 0x0fb4, 0x0fb5, 0x0fb6, 0x0fb7,
- 0x0fb8, 0x0fb9, 0x0fba, 0x0fbb, 0x0fbc, 0x0fbd, 0x0fbe, 0x0fbf,
- 0x1f80, 0x1f81, 0x1f82, 0x1f83, 0x1f84, 0x1f85, 0x1f86, 0x1f87,
- 0x1f88, 0x1f89, 0x1f8a, 0x1f8b, 0x1f8c, 0x1f8d, 0x1f8e, 0x1f8f,
- 0x1f90, 0x1f91, 0x1f92, 0x1f93, 0x1f94, 0x1f95, 0x1f96, 0x1f97,
- 0x1f98, 0x1f99, 0x1f9a, 0x1f9b, 0x1f9c, 0x1f9d, 0x1f9e, 0x1f9f,
- 0x1fa0, 0x1fa1, 0x1fa2, 0x1fa3, 0x1fa4, 0x1fa5, 0x1fa6, 0x1fa7,
- 0x1fa8, 0x1fa9, 0x1faa, 0x1fab, 0x1fac, 0x1fad, 0x1fae, 0x1faf,
- 0x1fb0, 0x1fb1, 0x1fb2, 0x1fb3, 0x1fb4, 0x1fb5, 0x1fb6, 0x1fb7,
- 0x1fb8, 0x1fb9, 0x1fba, 0x1fbb, 0x1fbc, 0x1fbd, 0x1fbe, 0x1fbf,
- 0x7f00, 0x7f01, 0x7f02, 0x7f03, 0x7f04, 0x7f05, 0x7f06, 0x7f07,
- 0x7f08, 0x7f09, 0x7f0a, 0x7f0b, 0x7f0c, 0x7f0d, 0x7f0e, 0x7f0f,
- 0x7f10, 0x7f11, 0x7f12, 0x7f13, 0x7f14, 0x7f15, 0x7f16, 0x7f17,
- 0x7f18, 0x7f19, 0x7f1a, 0x7f1b, 0x7f1c, 0x7f1d, 0x7f1e, 0x7f1f,
- 0x7f20, 0x7f21, 0x7f22, 0x7f23, 0x7f24, 0x7f25, 0x7f26, 0x7f27,
- 0x7f28, 0x7f29, 0x7f2a, 0x7f2b, 0x7f2c, 0x7f2d, 0x7f2e, 0x7f2f,
- 0x7f30, 0x7f31, 0x7f32, 0x7f33, 0x7f34, 0x7f35, 0x7f36, 0x7f37,
- 0x7f38, 0x7f39, 0x7f3a, 0x7f3b, 0x7f3c, 0x7f3d, 0x7f3e, 0x7f3f,
- 0x7f40, 0x7f41, 0x7f42, 0x7f43, 0x7f44, 0x7f45, 0x7f46, 0x7f47,
- 0x7f48, 0x7f49, 0x7f4a, 0x7f4b, 0x7f4c, 0x7f4d, 0x7f4e, 0x7f4f,
- 0x7f50, 0x7f51, 0x7f52, 0x7f53, 0x7f54, 0x7f55, 0x7f56, 0x7f57,
- 0x7f58, 0x7f59, 0x7f5a, 0x7f5b, 0x7f5c, 0x7f5d, 0x7f5e, 0x7f5f,
- 0x7f60, 0x7f61, 0x7f62, 0x7f63, 0x7f64, 0x7f65, 0x7f66, 0x7f67,
- 0x7f68, 0x7f69, 0x7f6a, 0x7f6b, 0x7f6c, 0x7f6d, 0x7f6e, 0x7f6f,
- 0x7f70, 0x7f71, 0x7f72, 0x7f73, 0x7f74, 0x7f75, 0x7f76, 0x7f77,
- 0x7f78, 0x7f79, 0x7f7a, 0x7f7b, 0x7f7c, 0x7f7d, 0x7f7e, 0x7f7f,
- 0x7f80, 0x7f81, 0x7f82, 0x7f83, 0x7f84, 0x7f85, 0x7f86, 0x7f87,
- 0x7f88, 0x7f89, 0x7f8a, 0x7f8b, 0x7f8c, 0x7f8d, 0x7f8e, 0x7f8f,
- 0x7f90, 0x7f91, 0x7f92, 0x7f93, 0x7f94, 0x7f95, 0x7f96, 0x7f97,
- 0x7f98, 0x7f99, 0x7f9a, 0x7f9b, 0x7f9c, 0x7f9d, 0x7f9e, 0x7f9f,
- 0x7fa0, 0x7fa1, 0x7fa2, 0x7fa3, 0x7fa4, 0x7fa5, 0x7fa6, 0x7fa7,
- 0x7fa8, 0x7fa9, 0x7faa, 0x7fab, 0x7fac, 0x7fad, 0x7fae, 0x7faf,
- 0x7fb0, 0x7fb1, 0x7fb2, 0x7fb3, 0x7fb4, 0x7fb5, 0x7fb6, 0x7fb7,
- 0x7fb8, 0x7fb9, 0x7fba, 0x7fbb, 0x7fbc, 0x7fbd, 0x7fbe, 0x7fbf,
- 0x7fc0, 0x7fc1, 0x7fc2, 0x7fc3, 0x7fc4, 0x7fc5, 0x7fc6, 0x7fc7,
- 0x7fc8, 0x7fc9, 0x7fca, 0x7fcb, 0x7fcc, 0x7fcd, 0x7fce, 0x7fcf,
- 0x7fd0, 0x7fd1, 0x7fd2, 0x7fd3, 0x7fd4, 0x7fd5, 0x7fd6, 0x7fd7,
- 0x7fd8, 0x7fd9, 0x7fda, 0x7fdb, 0x7fdc, 0x7fdd, 0x7fde, 0x7fdf,
- 0x7fe0, 0x7fe1, 0x7fe2, 0x7fe3, 0x7fe4, 0x7fe5, 0x7fe6, 0x7fe7,
- 0x7fe8, 0x7fe9, 0x7fea, 0x7feb, 0x7fec, 0x7fed, 0x7fee, 0x7fef,
- 0x7ff0, 0x7ff1, 0x7ff2, 0x7ff3, 0x7ff4, 0x7ff5, 0x7ff6, 0x7ff7,
- 0x7ff8, 0x7ff9, 0x7ffa, 0x7ffb, 0x7ffc, 0x7ffd, 0x7ffe, 0x7fff,
- 0x0006,
-};
-
-static const uint8_t dv_vlc_len[NB_DV_VLC] = {
- 2, 3, 4, 4, 4, 5, 5, 5,
- 5, 6, 6, 6, 6, 7, 7, 7,
- 7, 7, 7, 7, 7, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 10, 10, 10,
- 10, 10, 10, 10, 11, 11, 11, 11,
- 11, 11, 11, 11, 12, 12, 12, 12,
- 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, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13,
- 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, 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, 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, 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, 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, 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, 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, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 4,
-};
-
-static const uint8_t dv_vlc_run[NB_DV_VLC] = {
- 0, 0, 1, 0, 0, 2, 1, 0,
- 0, 3, 4, 0, 0, 5, 6, 2,
- 1, 1, 0, 0, 0, 7, 8, 9,
- 10, 3, 4, 2, 1, 1, 1, 0,
- 0, 0, 0, 0, 0, 11, 12, 13,
- 14, 5, 6, 3, 4, 2, 2, 1,
- 0, 0, 0, 0, 0, 5, 3, 3,
- 2, 1, 1, 1, 0, 1, 6, 4,
- 3, 1, 1, 1, 2, 3, 4, 5,
- 7, 8, 9, 10, 7, 8, 4, 3,
- 2, 2, 2, 2, 2, 1, 1, 1,
- 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,
- 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,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
-127,
-};
-
-static const uint8_t dv_vlc_level[NB_DV_VLC] = {
- 1, 2, 1, 3, 4, 1, 2, 5,
- 6, 1, 1, 7, 8, 1, 1, 2,
- 3, 4, 9, 10, 11, 1, 1, 1,
- 1, 2, 2, 3, 5, 6, 7, 12,
- 13, 14, 15, 16, 17, 1, 1, 1,
- 1, 2, 2, 3, 3, 4, 5, 8,
- 18, 19, 20, 21, 22, 3, 4, 5,
- 6, 9, 10, 11, 0, 0, 3, 4,
- 6, 12, 13, 14, 0, 0, 0, 0,
- 2, 2, 2, 2, 3, 3, 5, 7,
- 7, 8, 9, 10, 11, 15, 16, 17,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 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, 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, 65, 66, 67, 68, 69, 70, 71,
- 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87,
- 88, 89, 90, 91, 92, 93, 94, 95,
- 96, 97, 98, 99, 100, 101, 102, 103,
- 104, 105, 106, 107, 108, 109, 110, 111,
- 112, 113, 114, 115, 116, 117, 118, 119,
- 120, 121, 122, 123, 124, 125, 126, 127,
- 128, 129, 130, 131, 132, 133, 134, 135,
- 136, 137, 138, 139, 140, 141, 142, 143,
- 144, 145, 146, 147, 148, 149, 150, 151,
- 152, 153, 154, 155, 156, 157, 158, 159,
- 160, 161, 162, 163, 164, 165, 166, 167,
- 168, 169, 170, 171, 172, 173, 174, 175,
- 176, 177, 178, 179, 180, 181, 182, 183,
- 184, 185, 186, 187, 188, 189, 190, 191,
- 192, 193, 194, 195, 196, 197, 198, 199,
- 200, 201, 202, 203, 204, 205, 206, 207,
- 208, 209, 210, 211, 212, 213, 214, 215,
- 216, 217, 218, 219, 220, 221, 222, 223,
- 224, 225, 226, 227, 228, 229, 230, 231,
- 232, 233, 234, 235, 236, 237, 238, 239,
- 240, 241, 242, 243, 244, 245, 246, 247,
- 248, 249, 250, 251, 252, 253, 254, 255,
- 0,
-};
-
-#endif /* AVCODEC_DV_VLC_DATA_H */
diff --git a/libavcodec/dvbsubdec.c b/libavcodec/dvbsubdec.c
index 4ce40aa..b8b4143 100644
--- a/libavcodec/dvbsubdec.c
+++ b/libavcodec/dvbsubdec.c
@@ -34,8 +34,6 @@
#define cm (ff_cropTbl + MAX_NEG_CROP)
#ifdef DEBUG
-#undef fprintf
-#undef perror
#if 0
static void png_save(const char *filename, uint8_t *bitmap, int w, int h,
uint32_t *rgba_palette)
diff --git a/libavcodec/dvdata.c b/libavcodec/dvdata.c
index a7e3d59..a3be7fd 100644
--- a/libavcodec/dvdata.c
+++ b/libavcodec/dvdata.c
@@ -24,7 +24,8 @@
* Constants for DV codec.
*/
-#include "avcodec.h"
+#include <stdint.h>
+
#include "dvdata.h"
/* unquant tables (not used directly) */
@@ -120,3 +121,227 @@
394, 406, 418, 438, 418, 464, 464, 492,
};
+/*
+ * There's a catch about the following three tables: the mapping they establish
+ * between (run, level) and vlc is not 1-1. So you have to watch out for that
+ * when building misc. tables. E.g. (1, 0) can be either 0x7cf or 0x1f82.
+ */
+const uint16_t ff_dv_vlc_bits[NB_DV_VLC] = {
+ 0x0000, 0x0002, 0x0007, 0x0008, 0x0009, 0x0014, 0x0015, 0x0016,
+ 0x0017, 0x0030, 0x0031, 0x0032, 0x0033, 0x0068, 0x0069, 0x006a,
+ 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0x00e0, 0x00e1, 0x00e2,
+ 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, 0x00e8, 0x00e9, 0x00ea,
+ 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, 0x01e0, 0x01e1, 0x01e2,
+ 0x01e3, 0x01e4, 0x01e5, 0x01e6, 0x01e7, 0x01e8, 0x01e9, 0x01ea,
+ 0x01eb, 0x01ec, 0x01ed, 0x01ee, 0x01ef, 0x03e0, 0x03e1, 0x03e2,
+ 0x03e3, 0x03e4, 0x03e5, 0x03e6, 0x07ce, 0x07cf, 0x07d0, 0x07d1,
+ 0x07d2, 0x07d3, 0x07d4, 0x07d5, 0x0fac, 0x0fad, 0x0fae, 0x0faf,
+ 0x0fb0, 0x0fb1, 0x0fb2, 0x0fb3, 0x0fb4, 0x0fb5, 0x0fb6, 0x0fb7,
+ 0x0fb8, 0x0fb9, 0x0fba, 0x0fbb, 0x0fbc, 0x0fbd, 0x0fbe, 0x0fbf,
+ 0x1f80, 0x1f81, 0x1f82, 0x1f83, 0x1f84, 0x1f85, 0x1f86, 0x1f87,
+ 0x1f88, 0x1f89, 0x1f8a, 0x1f8b, 0x1f8c, 0x1f8d, 0x1f8e, 0x1f8f,
+ 0x1f90, 0x1f91, 0x1f92, 0x1f93, 0x1f94, 0x1f95, 0x1f96, 0x1f97,
+ 0x1f98, 0x1f99, 0x1f9a, 0x1f9b, 0x1f9c, 0x1f9d, 0x1f9e, 0x1f9f,
+ 0x1fa0, 0x1fa1, 0x1fa2, 0x1fa3, 0x1fa4, 0x1fa5, 0x1fa6, 0x1fa7,
+ 0x1fa8, 0x1fa9, 0x1faa, 0x1fab, 0x1fac, 0x1fad, 0x1fae, 0x1faf,
+ 0x1fb0, 0x1fb1, 0x1fb2, 0x1fb3, 0x1fb4, 0x1fb5, 0x1fb6, 0x1fb7,
+ 0x1fb8, 0x1fb9, 0x1fba, 0x1fbb, 0x1fbc, 0x1fbd, 0x1fbe, 0x1fbf,
+ 0x7f00, 0x7f01, 0x7f02, 0x7f03, 0x7f04, 0x7f05, 0x7f06, 0x7f07,
+ 0x7f08, 0x7f09, 0x7f0a, 0x7f0b, 0x7f0c, 0x7f0d, 0x7f0e, 0x7f0f,
+ 0x7f10, 0x7f11, 0x7f12, 0x7f13, 0x7f14, 0x7f15, 0x7f16, 0x7f17,
+ 0x7f18, 0x7f19, 0x7f1a, 0x7f1b, 0x7f1c, 0x7f1d, 0x7f1e, 0x7f1f,
+ 0x7f20, 0x7f21, 0x7f22, 0x7f23, 0x7f24, 0x7f25, 0x7f26, 0x7f27,
+ 0x7f28, 0x7f29, 0x7f2a, 0x7f2b, 0x7f2c, 0x7f2d, 0x7f2e, 0x7f2f,
+ 0x7f30, 0x7f31, 0x7f32, 0x7f33, 0x7f34, 0x7f35, 0x7f36, 0x7f37,
+ 0x7f38, 0x7f39, 0x7f3a, 0x7f3b, 0x7f3c, 0x7f3d, 0x7f3e, 0x7f3f,
+ 0x7f40, 0x7f41, 0x7f42, 0x7f43, 0x7f44, 0x7f45, 0x7f46, 0x7f47,
+ 0x7f48, 0x7f49, 0x7f4a, 0x7f4b, 0x7f4c, 0x7f4d, 0x7f4e, 0x7f4f,
+ 0x7f50, 0x7f51, 0x7f52, 0x7f53, 0x7f54, 0x7f55, 0x7f56, 0x7f57,
+ 0x7f58, 0x7f59, 0x7f5a, 0x7f5b, 0x7f5c, 0x7f5d, 0x7f5e, 0x7f5f,
+ 0x7f60, 0x7f61, 0x7f62, 0x7f63, 0x7f64, 0x7f65, 0x7f66, 0x7f67,
+ 0x7f68, 0x7f69, 0x7f6a, 0x7f6b, 0x7f6c, 0x7f6d, 0x7f6e, 0x7f6f,
+ 0x7f70, 0x7f71, 0x7f72, 0x7f73, 0x7f74, 0x7f75, 0x7f76, 0x7f77,
+ 0x7f78, 0x7f79, 0x7f7a, 0x7f7b, 0x7f7c, 0x7f7d, 0x7f7e, 0x7f7f,
+ 0x7f80, 0x7f81, 0x7f82, 0x7f83, 0x7f84, 0x7f85, 0x7f86, 0x7f87,
+ 0x7f88, 0x7f89, 0x7f8a, 0x7f8b, 0x7f8c, 0x7f8d, 0x7f8e, 0x7f8f,
+ 0x7f90, 0x7f91, 0x7f92, 0x7f93, 0x7f94, 0x7f95, 0x7f96, 0x7f97,
+ 0x7f98, 0x7f99, 0x7f9a, 0x7f9b, 0x7f9c, 0x7f9d, 0x7f9e, 0x7f9f,
+ 0x7fa0, 0x7fa1, 0x7fa2, 0x7fa3, 0x7fa4, 0x7fa5, 0x7fa6, 0x7fa7,
+ 0x7fa8, 0x7fa9, 0x7faa, 0x7fab, 0x7fac, 0x7fad, 0x7fae, 0x7faf,
+ 0x7fb0, 0x7fb1, 0x7fb2, 0x7fb3, 0x7fb4, 0x7fb5, 0x7fb6, 0x7fb7,
+ 0x7fb8, 0x7fb9, 0x7fba, 0x7fbb, 0x7fbc, 0x7fbd, 0x7fbe, 0x7fbf,
+ 0x7fc0, 0x7fc1, 0x7fc2, 0x7fc3, 0x7fc4, 0x7fc5, 0x7fc6, 0x7fc7,
+ 0x7fc8, 0x7fc9, 0x7fca, 0x7fcb, 0x7fcc, 0x7fcd, 0x7fce, 0x7fcf,
+ 0x7fd0, 0x7fd1, 0x7fd2, 0x7fd3, 0x7fd4, 0x7fd5, 0x7fd6, 0x7fd7,
+ 0x7fd8, 0x7fd9, 0x7fda, 0x7fdb, 0x7fdc, 0x7fdd, 0x7fde, 0x7fdf,
+ 0x7fe0, 0x7fe1, 0x7fe2, 0x7fe3, 0x7fe4, 0x7fe5, 0x7fe6, 0x7fe7,
+ 0x7fe8, 0x7fe9, 0x7fea, 0x7feb, 0x7fec, 0x7fed, 0x7fee, 0x7fef,
+ 0x7ff0, 0x7ff1, 0x7ff2, 0x7ff3, 0x7ff4, 0x7ff5, 0x7ff6, 0x7ff7,
+ 0x7ff8, 0x7ff9, 0x7ffa, 0x7ffb, 0x7ffc, 0x7ffd, 0x7ffe, 0x7fff,
+ 0x0006,
+};
+
+const uint8_t ff_dv_vlc_len[NB_DV_VLC] = {
+ 2, 3, 4, 4, 4, 5, 5, 5,
+ 5, 6, 6, 6, 6, 7, 7, 7,
+ 7, 7, 7, 7, 7, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 10, 10, 10,
+ 10, 10, 10, 10, 11, 11, 11, 11,
+ 11, 11, 11, 11, 12, 12, 12, 12,
+ 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, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 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, 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, 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, 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, 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, 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, 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, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 4,
+};
+
+const uint8_t ff_dv_vlc_run[NB_DV_VLC] = {
+ 0, 0, 1, 0, 0, 2, 1, 0,
+ 0, 3, 4, 0, 0, 5, 6, 2,
+ 1, 1, 0, 0, 0, 7, 8, 9,
+ 10, 3, 4, 2, 1, 1, 1, 0,
+ 0, 0, 0, 0, 0, 11, 12, 13,
+ 14, 5, 6, 3, 4, 2, 2, 1,
+ 0, 0, 0, 0, 0, 5, 3, 3,
+ 2, 1, 1, 1, 0, 1, 6, 4,
+ 3, 1, 1, 1, 2, 3, 4, 5,
+ 7, 8, 9, 10, 7, 8, 4, 3,
+ 2, 2, 2, 2, 2, 1, 1, 1,
+ 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,
+ 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,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+127,
+};
+
+const uint8_t ff_dv_vlc_level[NB_DV_VLC] = {
+ 1, 2, 1, 3, 4, 1, 2, 5,
+ 6, 1, 1, 7, 8, 1, 1, 2,
+ 3, 4, 9, 10, 11, 1, 1, 1,
+ 1, 2, 2, 3, 5, 6, 7, 12,
+ 13, 14, 15, 16, 17, 1, 1, 1,
+ 1, 2, 2, 3, 3, 4, 5, 8,
+ 18, 19, 20, 21, 22, 3, 4, 5,
+ 6, 9, 10, 11, 0, 0, 3, 4,
+ 6, 12, 13, 14, 0, 0, 0, 0,
+ 2, 2, 2, 2, 3, 3, 5, 7,
+ 7, 8, 9, 10, 11, 15, 16, 17,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 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, 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, 65, 66, 67, 68, 69, 70, 71,
+ 72, 73, 74, 75, 76, 77, 78, 79,
+ 80, 81, 82, 83, 84, 85, 86, 87,
+ 88, 89, 90, 91, 92, 93, 94, 95,
+ 96, 97, 98, 99, 100, 101, 102, 103,
+ 104, 105, 106, 107, 108, 109, 110, 111,
+ 112, 113, 114, 115, 116, 117, 118, 119,
+ 120, 121, 122, 123, 124, 125, 126, 127,
+ 128, 129, 130, 131, 132, 133, 134, 135,
+ 136, 137, 138, 139, 140, 141, 142, 143,
+ 144, 145, 146, 147, 148, 149, 150, 151,
+ 152, 153, 154, 155, 156, 157, 158, 159,
+ 160, 161, 162, 163, 164, 165, 166, 167,
+ 168, 169, 170, 171, 172, 173, 174, 175,
+ 176, 177, 178, 179, 180, 181, 182, 183,
+ 184, 185, 186, 187, 188, 189, 190, 191,
+ 192, 193, 194, 195, 196, 197, 198, 199,
+ 200, 201, 202, 203, 204, 205, 206, 207,
+ 208, 209, 210, 211, 212, 213, 214, 215,
+ 216, 217, 218, 219, 220, 221, 222, 223,
+ 224, 225, 226, 227, 228, 229, 230, 231,
+ 232, 233, 234, 235, 236, 237, 238, 239,
+ 240, 241, 242, 243, 244, 245, 246, 247,
+ 248, 249, 250, 251, 252, 253, 254, 255,
+ 0,
+};
diff --git a/libavcodec/dvdata.h b/libavcodec/dvdata.h
index 97c20e3..8c120df 100644
--- a/libavcodec/dvdata.h
+++ b/libavcodec/dvdata.h
@@ -1,7 +1,4 @@
/*
- * Constants for DV codec
- * Copyright (c) 2002 Fabrice Bellard
- *
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
@@ -19,55 +16,10 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-/**
- * @file
- * Constants for DV codec.
- */
-
#ifndef AVCODEC_DVDATA_H
#define AVCODEC_DVDATA_H
-#include "avcodec.h"
-#include "dsputil.h"
-#include "get_bits.h"
-#include "dv_profile.h"
-
-typedef struct DVVideoContext {
- const DVprofile *sys;
- AVFrame picture;
- AVCodecContext *avctx;
- uint8_t *buf;
-
- uint8_t dv_zigzag[2][64];
-
- void (*get_pixels)(int16_t *block, const uint8_t *pixels, int line_size);
- void (*fdct[2])(int16_t *block);
- void (*idct_put[2])(uint8_t *dest, int line_size, int16_t *block);
- me_cmp_func ildct_cmp;
-} DVVideoContext;
-
-enum dv_section_type {
- dv_sect_header = 0x1f,
- dv_sect_subcode = 0x3f,
- dv_sect_vaux = 0x56,
- dv_sect_audio = 0x76,
- dv_sect_video = 0x96,
-};
-
-enum dv_pack_type {
- dv_header525 = 0x3f, /* see dv_write_pack for important details on */
- dv_header625 = 0xbf, /* these two packs */
- dv_timecode = 0x13,
- dv_audio_source = 0x50,
- dv_audio_control = 0x51,
- dv_audio_recdate = 0x52,
- dv_audio_rectime = 0x53,
- dv_video_source = 0x60,
- dv_video_control = 0x61,
- dv_video_recdate = 0x62,
- dv_video_rectime = 0x63,
- dv_unknown_pack = 0xff,
-};
+#include <stdint.h>
extern const uint8_t ff_dv_quant_shifts[22][4];
extern const uint8_t ff_dv_quant_offset[4];
@@ -79,46 +31,11 @@
extern const int ff_dv_iweight_720_y[64];
extern const int ff_dv_iweight_720_c[64];
-#define DV_PROFILE_IS_HD(p) ((p)->video_stype & 0x10)
-#define DV_PROFILE_IS_1080i50(p) (((p)->video_stype == 0x14) && ((p)->dsf == 1))
-#define DV_PROFILE_IS_720p50(p) (((p)->video_stype == 0x18) && ((p)->dsf == 1))
+#define NB_DV_VLC 409
-/**
- * largest possible DV frame, in bytes (1080i50)
- */
-#define DV_MAX_FRAME_SIZE 576000
-
-/**
- * maximum number of blocks per macroblock in any DV format
- */
-#define DV_MAX_BPM 8
-
-#define TEX_VLC_BITS 9
-
-extern RL_VLC_ELEM ff_dv_rl_vlc[1184];
-
-int ff_dv_init_dynamic_tables(const DVprofile *d);
-int ff_dvvideo_init(AVCodecContext *avctx);
-
-static inline int dv_work_pool_size(const DVprofile *d)
-{
- int size = d->n_difchan*d->difseg_size*27;
- if (DV_PROFILE_IS_1080i50(d))
- size -= 3*27;
- if (DV_PROFILE_IS_720p50(d))
- size -= 4*27;
- return size;
-}
-
-static inline void dv_calculate_mb_xy(DVVideoContext *s, DVwork_chunk *work_chunk, int m, int *mb_x, int *mb_y)
-{
- *mb_x = work_chunk->mb_coordinates[m] & 0xff;
- *mb_y = work_chunk->mb_coordinates[m] >> 8;
-
- /* We work with 720p frames split in half. The odd half-frame (chan==2,3) is displaced :-( */
- if (s->sys->height == 720 && !(s->buf[1]&0x0C)) {
- *mb_y -= (*mb_y>17)?18:-72; /* shifting the Y coordinate down by 72/2 macro blocks */
- }
-}
+extern const uint16_t ff_dv_vlc_bits[NB_DV_VLC];
+extern const uint8_t ff_dv_vlc_len[NB_DV_VLC];
+extern const uint8_t ff_dv_vlc_run[NB_DV_VLC];
+extern const uint8_t ff_dv_vlc_level[NB_DV_VLC];
#endif /* AVCODEC_DVDATA_H */
diff --git a/libavcodec/dvdec.c b/libavcodec/dvdec.c
index b86926a..727f91d 100644
--- a/libavcodec/dvdec.c
+++ b/libavcodec/dvdec.c
@@ -44,6 +44,7 @@
#include "put_bits.h"
#include "simple_idct.h"
#include "dvdata.h"
+#include "dv.h"
typedef struct BlockInfo {
const uint32_t *factor_table;
@@ -237,7 +238,7 @@
flush_put_bits(&vs_pb);
for (mb_index = 0; mb_index < 5; mb_index++) {
for (j = 0; j < s->sys->bpm; j++) {
- if (mb->pos < 64) {
+ if (mb->pos < 64 && get_bits_left(&gb) > 0) {
av_dlog(avctx, "start %d:%d\n", mb_index, j);
dv_decode_ac(&gb, mb, block);
}
@@ -258,12 +259,12 @@
if ((s->sys->pix_fmt == AV_PIX_FMT_YUV420P) ||
(s->sys->pix_fmt == AV_PIX_FMT_YUV411P && mb_x >= (704 / 8)) ||
(s->sys->height >= 720 && mb_y != 134)) {
- y_stride = (s->picture.linesize[0] << ((!is_field_mode[mb_index]) * log2_blocksize));
+ y_stride = (s->frame->linesize[0] << ((!is_field_mode[mb_index]) * log2_blocksize));
} else {
y_stride = (2 << log2_blocksize);
}
- y_ptr = s->picture.data[0] + ((mb_y * s->picture.linesize[0] + mb_x) << log2_blocksize);
- linesize = s->picture.linesize[0] << is_field_mode[mb_index];
+ y_ptr = s->frame->data[0] + ((mb_y * s->frame->linesize[0] + mb_x) << log2_blocksize);
+ linesize = s->frame->linesize[0] << is_field_mode[mb_index];
mb[0] .idct_put(y_ptr , linesize, block + 0*64);
if (s->sys->video_stype == 4) { /* SD 422 */
mb[2].idct_put(y_ptr + (1 << log2_blocksize) , linesize, block + 2*64);
@@ -276,19 +277,19 @@
block += 4*64;
/* idct_put'ting chrominance */
- c_offset = (((mb_y >> (s->sys->pix_fmt == AV_PIX_FMT_YUV420P)) * s->picture.linesize[1] +
+ c_offset = (((mb_y >> (s->sys->pix_fmt == AV_PIX_FMT_YUV420P)) * s->frame->linesize[1] +
(mb_x >> ((s->sys->pix_fmt == AV_PIX_FMT_YUV411P) ? 2 : 1))) << log2_blocksize);
for (j = 2; j; j--) {
- uint8_t *c_ptr = s->picture.data[j] + c_offset;
+ uint8_t *c_ptr = s->frame->data[j] + c_offset;
if (s->sys->pix_fmt == AV_PIX_FMT_YUV411P && mb_x >= (704 / 8)) {
uint64_t aligned_pixels[64/8];
uint8_t *pixels = (uint8_t*)aligned_pixels;
uint8_t *c_ptr1, *ptr1;
int x, y;
mb->idct_put(pixels, 8, block);
- for (y = 0; y < (1 << log2_blocksize); y++, c_ptr += s->picture.linesize[j], pixels += 8) {
+ for (y = 0; y < (1 << log2_blocksize); y++, c_ptr += s->frame->linesize[j], pixels += 8) {
ptr1 = pixels + ((1 << (log2_blocksize))>>1);
- c_ptr1 = c_ptr + (s->picture.linesize[j] << log2_blocksize);
+ c_ptr1 = c_ptr + (s->frame->linesize[j] << log2_blocksize);
for (x = 0; x < (1 << FFMAX(log2_blocksize - 1, 0)); x++) {
c_ptr[x] = pixels[x];
c_ptr1[x] = ptr1[x];
@@ -297,8 +298,8 @@
block += 64; mb++;
} else {
y_stride = (mb_y == 134) ? (1 << log2_blocksize) :
- s->picture.linesize[j] << ((!is_field_mode[mb_index]) * log2_blocksize);
- linesize = s->picture.linesize[j] << is_field_mode[mb_index];
+ s->frame->linesize[j] << ((!is_field_mode[mb_index]) * log2_blocksize);
+ linesize = s->frame->linesize[j] << is_field_mode[mb_index];
(mb++)-> idct_put(c_ptr , linesize, block); block += 64;
if (s->sys->bpm == 8) {
(mb++)->idct_put(c_ptr + y_stride, linesize, block); block += 64;
@@ -319,7 +320,7 @@
int buf_size = avpkt->size;
DVVideoContext *s = avctx->priv_data;
const uint8_t* vsc_pack;
- int ret, apt, is16_9;
+ int apt, is16_9, ret;
s->sys = avpriv_dv_frame_profile2(avctx, s->sys, buf, buf_size);
if (!s->sys || buf_size < s->sys->frame_size || ff_dv_init_dynamic_tables(s->sys)) {
@@ -327,15 +328,20 @@
return -1; /* NOTE: we only accept several full frames */
}
- s->picture.key_frame = 1;
- s->picture.pict_type = AV_PICTURE_TYPE_I;
+ s->frame = data;
+ s->frame->key_frame = 1;
+ s->frame->pict_type = AV_PICTURE_TYPE_I;
avctx->pix_fmt = s->sys->pix_fmt;
avctx->time_base = s->sys->time_base;
- avcodec_set_dimensions(avctx, s->sys->width, s->sys->height);
- if ((ret = ff_get_buffer(avctx, &s->picture, 0)) < 0)
+
+ ret = ff_set_dimensions(avctx, s->sys->width, s->sys->height);
+ if (ret < 0)
return ret;
- s->picture.interlaced_frame = 1;
- s->picture.top_field_first = 0;
+
+ if ((ret = ff_get_buffer(avctx, s->frame, 0)) < 0)
+ return ret;
+ s->frame->interlaced_frame = 1;
+ s->frame->top_field_first = 0;
/* Determine the codec's sample_aspect ratio and field order from the packet */
vsc_pack = buf + 80*5 + 48 + 5;
@@ -343,7 +349,7 @@
apt = buf[4] & 0x07;
is16_9 = (vsc_pack[2] & 0x07) == 0x02 || (!apt && (vsc_pack[2] & 0x07) == 0x07);
avctx->sample_aspect_ratio = s->sys->sar[is16_9];
- s->picture.top_field_first = !(vsc_pack[3] & 0x40);
+ s->frame->top_field_first = !(vsc_pack[3] & 0x40);
}
s->buf = buf;
@@ -354,20 +360,10 @@
/* return image */
*got_frame = 1;
- av_frame_move_ref(data, &s->picture);
return s->sys->frame_size;
}
-static int dvvideo_close(AVCodecContext *c)
-{
- DVVideoContext *s = c->priv_data;
-
- av_frame_unref(&s->picture);
-
- return 0;
-}
-
AVCodec ff_dvvideo_decoder = {
.name = "dvvideo",
.long_name = NULL_IF_CONFIG_SMALL("DV (Digital Video)"),
@@ -375,7 +371,6 @@
.id = AV_CODEC_ID_DVVIDEO,
.priv_data_size = sizeof(DVVideoContext),
.init = ff_dvvideo_init,
- .close = dvvideo_close,
.decode = dvvideo_decode_frame,
.capabilities = CODEC_CAP_DR1 | CODEC_CAP_SLICE_THREADS,
.max_lowres = 3,
diff --git a/libavcodec/dvdsubdec.c b/libavcodec/dvdsubdec.c
index f0dd289..31ce0ac 100644
--- a/libavcodec/dvdsubdec.c
+++ b/libavcodec/dvdsubdec.c
@@ -21,6 +21,8 @@
#include "avcodec.h"
#include "get_bits.h"
#include "dsputil.h"
+#include "internal.h"
+
#include "libavutil/attributes.h"
#include "libavutil/colorspace.h"
#include "libavutil/opt.h"
@@ -460,9 +462,6 @@
}
#ifdef DEBUG
-#undef fprintf
-#undef perror
-#undef exit
static void ppm_save(const char *filename, uint8_t *bitmap, int w, int h,
uint32_t *rgba_palette)
{
@@ -472,7 +471,7 @@
f = fopen(filename, "w");
if (!f) {
perror(filename);
- exit(1);
+ return;
}
fprintf(f, "P6\n"
"%d %d\n"
@@ -598,9 +597,11 @@
parse_palette(ctx, data + 8);
} else if (strncmp("size:", data, 5) == 0) {
int w, h;
- if (sscanf(data + 5, "%dx%d", &w, &h) == 2 &&
- av_image_check_size(w, h, 0, avctx) >= 0)
- avcodec_set_dimensions(avctx, w, h);
+ if (sscanf(data + 5, "%dx%d", &w, &h) == 2) {
+ int ret = ff_set_dimensions(avctx, w, h);
+ if (ret < 0)
+ return ret;
+ }
}
data += pos;
diff --git a/libavcodec/dvenc.c b/libavcodec/dvenc.c
new file mode 100644
index 0000000..6e887dc
--- /dev/null
+++ b/libavcodec/dvenc.c
@@ -0,0 +1,712 @@
+/*
+ * DV encoder
+ * Copyright (c) 2003 Roman Shaposhnik
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * DV encoder
+ */
+
+#include "libavutil/attributes.h"
+#include "libavutil/pixdesc.h"
+#include "config.h"
+#include "avcodec.h"
+#include "internal.h"
+#include "put_bits.h"
+#include "dv.h"
+#include "dv_tablegen.h"
+
+static av_cold int dvvideo_init_encoder(AVCodecContext *avctx)
+{
+ if (!avpriv_dv_codec_profile(avctx)) {
+ av_log(avctx, AV_LOG_ERROR, "Found no DV profile for %ix%i %s video. "
+ "Valid DV profiles are:\n",
+ avctx->width, avctx->height, av_get_pix_fmt_name(avctx->pix_fmt));
+ ff_dv_print_profiles(avctx, AV_LOG_ERROR);
+ return AVERROR(EINVAL);
+ }
+ if (avctx->height > 576) {
+ av_log(avctx, AV_LOG_ERROR, "DVCPRO HD encoding is not supported.\n");
+ return AVERROR_PATCHWELCOME;
+ }
+
+ avctx->coded_frame = av_frame_alloc();
+ if (!avctx->coded_frame)
+ return AVERROR(ENOMEM);
+
+ dv_vlc_map_tableinit();
+
+ return ff_dvvideo_init(avctx);
+}
+
+/* bit budget for AC only in 5 MBs */
+static const int vs_total_ac_bits = (100 * 4 + 68*2) * 5;
+static const int mb_area_start[5] = { 1, 6, 21, 43, 64 };
+
+#if CONFIG_SMALL
+/* 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;
+ if (run < DV_VLC_MAP_RUN_SIZE && level < DV_VLC_MAP_LEV_SIZE) {
+ *vlc = dv_vlc_map[run][level].vlc | sign;
+ size = dv_vlc_map[run][level].size;
+ }
+ else {
+ if (level < DV_VLC_MAP_LEV_SIZE) {
+ *vlc = dv_vlc_map[0][level].vlc | sign;
+ size = dv_vlc_map[0][level].size;
+ } else {
+ *vlc = 0xfe00 | (level << 1) | sign;
+ size = 16;
+ }
+ if (run) {
+ *vlc |= ((run < 16) ? dv_vlc_map[run-1][0].vlc :
+ (0x1f80 | (run - 1))) << size;
+ size += (run < 16) ? dv_vlc_map[run-1][0].size : 13;
+ }
+ }
+
+ return size;
+}
+
+static av_always_inline int dv_rl2vlc_size(int run, int level)
+{
+ int size;
+
+ if (run < DV_VLC_MAP_RUN_SIZE && level < DV_VLC_MAP_LEV_SIZE) {
+ size = dv_vlc_map[run][level].size;
+ }
+ else {
+ size = (level < DV_VLC_MAP_LEV_SIZE) ? dv_vlc_map[0][level].size : 16;
+ if (run) {
+ size += (run < 16) ? dv_vlc_map[run-1][0].size : 13;
+ }
+ }
+ return size;
+}
+#else
+static av_always_inline int dv_rl2vlc(int run, int l, int sign, uint32_t* vlc)
+{
+ *vlc = dv_vlc_map[run][l].vlc | sign;
+ return dv_vlc_map[run][l].size;
+}
+
+static av_always_inline int dv_rl2vlc_size(int run, int l)
+{
+ return dv_vlc_map[run][l].size;
+}
+#endif
+
+typedef struct EncBlockInfo {
+ int area_q[4];
+ int bit_size[4];
+ int prev[5];
+ int cur_ac;
+ int cno;
+ int dct_mode;
+ int16_t mb[64];
+ uint8_t next[64];
+ uint8_t sign[64];
+ uint8_t partial_bit_count;
+ uint32_t partial_bit_buffer; /* we can't use uint16_t here */
+} EncBlockInfo;
+
+static av_always_inline PutBitContext* dv_encode_ac(EncBlockInfo* bi,
+ PutBitContext* pb_pool,
+ PutBitContext* pb_end)
+{
+ int prev, bits_left;
+ PutBitContext* pb = pb_pool;
+ int size = bi->partial_bit_count;
+ uint32_t vlc = bi->partial_bit_buffer;
+
+ bi->partial_bit_count = bi->partial_bit_buffer = 0;
+ for (;;){
+ /* Find suitable storage space */
+ for (; size > (bits_left = put_bits_left(pb)); pb++) {
+ if (bits_left) {
+ size -= bits_left;
+ put_bits(pb, bits_left, vlc >> size);
+ vlc = vlc & ((1 << size) - 1);
+ }
+ if (pb + 1 >= pb_end) {
+ bi->partial_bit_count = size;
+ bi->partial_bit_buffer = vlc;
+ return pb;
+ }
+ }
+
+ /* Store VLC */
+ put_bits(pb, size, vlc);
+
+ if (bi->cur_ac >= 64)
+ break;
+
+ /* Construct the next VLC */
+ prev = bi->cur_ac;
+ bi->cur_ac = bi->next[prev];
+ if (bi->cur_ac < 64){
+ size = dv_rl2vlc(bi->cur_ac - prev - 1, bi->mb[bi->cur_ac], bi->sign[bi->cur_ac], &vlc);
+ } else {
+ size = 4; vlc = 6; /* End Of Block stamp */
+ }
+ }
+ return pb;
+}
+
+static av_always_inline int dv_guess_dct_mode(DVVideoContext *s, uint8_t *data, int linesize) {
+ if (s->avctx->flags & CODEC_FLAG_INTERLACED_DCT) {
+ int ps = s->ildct_cmp(NULL, data, NULL, linesize, 8) - 400;
+ if (ps > 0) {
+ int is = s->ildct_cmp(NULL, data , NULL, linesize<<1, 4) +
+ s->ildct_cmp(NULL, data + linesize, NULL, linesize<<1, 4);
+ return ps > is;
+ }
+ }
+
+ return 0;
+}
+
+static const int dv_weight_bits = 18;
+static const int dv_weight_88[64] = {
+ 131072, 257107, 257107, 242189, 252167, 242189, 235923, 237536,
+ 237536, 235923, 229376, 231390, 223754, 231390, 229376, 222935,
+ 224969, 217965, 217965, 224969, 222935, 200636, 218652, 211916,
+ 212325, 211916, 218652, 200636, 188995, 196781, 205965, 206433,
+ 206433, 205965, 196781, 188995, 185364, 185364, 200636, 200704,
+ 200636, 185364, 185364, 174609, 180568, 195068, 195068, 180568,
+ 174609, 170091, 175557, 189591, 175557, 170091, 165371, 170627,
+ 170627, 165371, 160727, 153560, 160727, 144651, 144651, 136258,
+};
+static const int dv_weight_248[64] = {
+ 131072, 242189, 257107, 237536, 229376, 200636, 242189, 223754,
+ 224969, 196781, 262144, 242189, 229376, 200636, 257107, 237536,
+ 211916, 185364, 235923, 217965, 229376, 211916, 206433, 180568,
+ 242189, 223754, 224969, 196781, 211916, 185364, 235923, 217965,
+ 200704, 175557, 222935, 205965, 200636, 185364, 195068, 170627,
+ 229376, 211916, 206433, 180568, 200704, 175557, 222935, 205965,
+ 175557, 153560, 188995, 174609, 165371, 144651, 200636, 185364,
+ 195068, 170627, 175557, 153560, 188995, 174609, 165371, 144651,
+};
+
+static av_always_inline int dv_init_enc_block(EncBlockInfo* bi, uint8_t *data, int linesize, DVVideoContext *s, int bias)
+{
+ const int *weight;
+ const uint8_t* zigzag_scan;
+ LOCAL_ALIGNED_16(int16_t, blk, [64]);
+ int i, area;
+ /* We offer two different methods for class number assignment: the
+ method suggested in SMPTE 314M Table 22, and an improved
+ method. The SMPTE method is very conservative; it assigns class
+ 3 (i.e. severe quantization) to any block where the largest AC
+ component is greater than 36. FFmpeg's DV encoder tracks AC bit
+ consumption precisely, so there is no need to bias most blocks
+ towards strongly lossy compression. Instead, we assign class 2
+ to most blocks, and use class 3 only when strictly necessary
+ (for blocks whose largest AC component exceeds 255). */
+
+#if 0 /* SMPTE spec method */
+ static const int classes[] = {12, 24, 36, 0xffff};
+#else /* improved FFmpeg method */
+ static const int classes[] = {-1, -1, 255, 0xffff};
+#endif
+ int max = classes[0];
+ int prev = 0;
+
+ av_assert2((((int)blk) & 15) == 0);
+
+ bi->area_q[0] = bi->area_q[1] = bi->area_q[2] = bi->area_q[3] = 0;
+ bi->partial_bit_count = 0;
+ bi->partial_bit_buffer = 0;
+ bi->cur_ac = 0;
+ if (data) {
+ bi->dct_mode = dv_guess_dct_mode(s, data, linesize);
+ s->get_pixels(blk, data, linesize);
+ s->fdct[bi->dct_mode](blk);
+ } else {
+ /* We rely on the fact that encoding all zeros leads to an immediate EOB,
+ which is precisely what the spec calls for in the "dummy" blocks. */
+ memset(blk, 0, 64*sizeof(*blk));
+ bi->dct_mode = 0;
+ }
+ bi->mb[0] = blk[0];
+
+ zigzag_scan = bi->dct_mode ? ff_zigzag248_direct : ff_zigzag_direct;
+ weight = bi->dct_mode ? dv_weight_248 : dv_weight_88;
+
+ for (area = 0; area < 4; area++) {
+ bi->prev[area] = prev;
+ bi->bit_size[area] = 1; // 4 areas 4 bits for EOB :)
+ for (i = mb_area_start[area]; i < mb_area_start[area+1]; i++) {
+ int level = blk[zigzag_scan[i]];
+
+ if (level + 15 > 30U) {
+ bi->sign[i] = (level >> 31) & 1;
+ /* weight it 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);
+ bi->mb[i] = level;
+ if (level > max)
+ max = level;
+ bi->bit_size[area] += dv_rl2vlc_size(i - prev - 1, level);
+ bi->next[prev]= i;
+ prev = i;
+ }
+ }
+ }
+ bi->next[prev]= i;
+ for (bi->cno = 0; max > classes[bi->cno]; bi->cno++);
+
+ bi->cno += bias;
+
+ if (bi->cno >= 3) {
+ bi->cno = 3;
+ prev = 0;
+ i = bi->next[prev];
+ for (area = 0; area < 4; area++) {
+ bi->prev[area] = prev;
+ bi->bit_size[area] = 1; // 4 areas 4 bits for EOB :)
+ for (; i < mb_area_start[area+1]; i = bi->next[i]) {
+ bi->mb[i] >>= 1;
+
+ if (bi->mb[i]) {
+ bi->bit_size[area] += dv_rl2vlc_size(i - prev - 1, bi->mb[i]);
+ bi->next[prev]= i;
+ prev = i;
+ }
+ }
+ }
+ bi->next[prev]= i;
+ }
+
+ return bi->bit_size[0] + bi->bit_size[1] + bi->bit_size[2] + bi->bit_size[3];
+}
+
+static inline void dv_guess_qnos(EncBlockInfo* blks, int* qnos)
+{
+ int size[5];
+ int i, j, k, a, prev, a2;
+ EncBlockInfo* b;
+
+ size[0] = size[1] = size[2] = size[3] = size[4] = 1 << 24;
+ do {
+ b = blks;
+ for (i = 0; i < 5; i++) {
+ if (!qnos[i])
+ continue;
+
+ qnos[i]--;
+ size[i] = 0;
+ for (j = 0; j < 6; j++, b++) {
+ for (a = 0; a < 4; a++) {
+ if (b->area_q[a] != ff_dv_quant_shifts[qnos[i] + ff_dv_quant_offset[b->cno]][a]) {
+ b->bit_size[a] = 1; // 4 areas 4 bits for EOB :)
+ b->area_q[a]++;
+ prev = b->prev[a];
+ av_assert2(b->next[prev] >= mb_area_start[a+1] || b->mb[prev]);
+ for (k = b->next[prev] ; k < mb_area_start[a+1]; k = b->next[k]) {
+ b->mb[k] >>= 1;
+ if (b->mb[k]) {
+ b->bit_size[a] += dv_rl2vlc_size(k - prev - 1, b->mb[k]);
+ prev = k;
+ } else {
+ if (b->next[k] >= mb_area_start[a+1] && b->next[k]<64){
+ for (a2 = a + 1; b->next[k] >= mb_area_start[a2+1]; a2++)
+ b->prev[a2] = prev;
+ av_assert2(a2 < 4);
+ av_assert2(b->mb[b->next[k]]);
+ b->bit_size[a2] += dv_rl2vlc_size(b->next[k] - prev - 1, b->mb[b->next[k]])
+ -dv_rl2vlc_size(b->next[k] - k - 1, b->mb[b->next[k]]);
+ av_assert2(b->prev[a2] == k && (a2 + 1 >= 4 || b->prev[a2+1] != k));
+ b->prev[a2] = prev;
+ }
+ b->next[prev] = b->next[k];
+ }
+ }
+ b->prev[a+1]= prev;
+ }
+ size[i] += b->bit_size[a];
+ }
+ }
+ if (vs_total_ac_bits >= size[0] + size[1] + size[2] + size[3] + size[4])
+ return;
+ }
+ } while (qnos[0]|qnos[1]|qnos[2]|qnos[3]|qnos[4]);
+
+
+ for (a = 2; a == 2 || vs_total_ac_bits < size[0]; a += a){
+ b = blks;
+ size[0] = 5 * 6 * 4; //EOB
+ for (j = 0; j < 6 *5; j++, b++) {
+ prev = b->prev[0];
+ for (k = b->next[prev]; k < 64; k = b->next[k]) {
+ if (b->mb[k] < a && b->mb[k] > -a){
+ b->next[prev] = b->next[k];
+ }else{
+ size[0] += dv_rl2vlc_size(k - prev - 1, b->mb[k]);
+ prev = k;
+ }
+ }
+ }
+ }
+}
+
+static int dv_encode_video_segment(AVCodecContext *avctx, void *arg)
+{
+ DVVideoContext *s = avctx->priv_data;
+ DVwork_chunk *work_chunk = arg;
+ int mb_index, i, j;
+ int mb_x, mb_y, c_offset, linesize, y_stride;
+ uint8_t* y_ptr;
+ uint8_t* dif;
+ LOCAL_ALIGNED_8(uint8_t, scratch, [128]);
+ EncBlockInfo enc_blks[5*DV_MAX_BPM];
+ PutBitContext pbs[5*DV_MAX_BPM];
+ PutBitContext* pb;
+ EncBlockInfo* enc_blk;
+ int vs_bit_size = 0;
+ int qnos[5] = {15, 15, 15, 15, 15}; /* No quantization */
+ int* qnosp = &qnos[0];
+
+ dif = &s->buf[work_chunk->buf_offset*80];
+ enc_blk = &enc_blks[0];
+ for (mb_index = 0; mb_index < 5; mb_index++) {
+ dv_calculate_mb_xy(s, work_chunk, mb_index, &mb_x, &mb_y);
+
+ /* initializing luminance blocks */
+ if ((s->sys->pix_fmt == AV_PIX_FMT_YUV420P) ||
+ (s->sys->pix_fmt == AV_PIX_FMT_YUV411P && mb_x >= (704 / 8)) ||
+ (s->sys->height >= 720 && mb_y != 134)) {
+ y_stride = s->frame->linesize[0] << 3;
+ } else {
+ y_stride = 16;
+ }
+ y_ptr = s->frame->data[0] + ((mb_y * s->frame->linesize[0] + mb_x) << 3);
+ linesize = s->frame->linesize[0];
+
+ if (s->sys->video_stype == 4) { /* SD 422 */
+ vs_bit_size +=
+ dv_init_enc_block(enc_blk+0, y_ptr , linesize, s, 0) +
+ dv_init_enc_block(enc_blk+1, NULL , linesize, s, 0) +
+ dv_init_enc_block(enc_blk+2, y_ptr + 8 , linesize, s, 0) +
+ dv_init_enc_block(enc_blk+3, NULL , linesize, s, 0);
+ } else {
+ vs_bit_size +=
+ dv_init_enc_block(enc_blk+0, y_ptr , linesize, s, 0) +
+ dv_init_enc_block(enc_blk+1, y_ptr + 8 , linesize, s, 0) +
+ dv_init_enc_block(enc_blk+2, y_ptr + y_stride, linesize, s, 0) +
+ dv_init_enc_block(enc_blk+3, y_ptr + 8 + y_stride, linesize, s, 0);
+ }
+ enc_blk += 4;
+
+ /* initializing chrominance blocks */
+ c_offset = (((mb_y >> (s->sys->pix_fmt == AV_PIX_FMT_YUV420P)) * s->frame->linesize[1] +
+ (mb_x >> ((s->sys->pix_fmt == AV_PIX_FMT_YUV411P) ? 2 : 1))) << 3);
+ for (j = 2; j; j--) {
+ uint8_t *c_ptr = s->frame->data[j] + c_offset;
+ linesize = s->frame->linesize[j];
+ y_stride = (mb_y == 134) ? 8 : (s->frame->linesize[j] << 3);
+ if (s->sys->pix_fmt == AV_PIX_FMT_YUV411P && mb_x >= (704 / 8)) {
+ uint8_t* d;
+ uint8_t* b = scratch;
+ for (i = 0; i < 8; i++) {
+ d = c_ptr + (linesize << 3);
+ b[0] = c_ptr[0]; b[1] = c_ptr[1]; b[2] = c_ptr[2]; b[3] = c_ptr[3];
+ b[4] = d[0]; b[5] = d[1]; b[6] = d[2]; b[7] = d[3];
+ c_ptr += linesize;
+ b += 16;
+ }
+ c_ptr = scratch;
+ linesize = 16;
+ }
+
+ vs_bit_size += dv_init_enc_block( enc_blk++, c_ptr , linesize, s, 1);
+ if (s->sys->bpm == 8) {
+ vs_bit_size += dv_init_enc_block(enc_blk++, c_ptr + y_stride, linesize, s, 1);
+ }
+ }
+ }
+
+ if (vs_total_ac_bits < vs_bit_size)
+ dv_guess_qnos(&enc_blks[0], qnosp);
+
+ /* DIF encoding process */
+ for (j=0; j<5*s->sys->bpm;) {
+ int start_mb = j;
+
+ dif[3] = *qnosp++;
+ dif += 4;
+
+ /* First pass over individual cells only */
+ for (i=0; i<s->sys->bpm; i++, j++) {
+ int sz = s->sys->block_sizes[i]>>3;
+
+ init_put_bits(&pbs[j], dif, sz);
+ put_sbits(&pbs[j], 9, ((enc_blks[j].mb[0] >> 3) - 1024 + 2) >> 2);
+ put_bits(&pbs[j], 1, enc_blks[j].dct_mode);
+ put_bits(&pbs[j], 2, enc_blks[j].cno);
+
+ dv_encode_ac(&enc_blks[j], &pbs[j], &pbs[j+1]);
+ dif += sz;
+ }
+
+ /* Second pass over each MB space */
+ pb = &pbs[start_mb];
+ for (i=0; i<s->sys->bpm; i++) {
+ if (enc_blks[start_mb+i].partial_bit_count)
+ pb = dv_encode_ac(&enc_blks[start_mb+i], pb, &pbs[start_mb+s->sys->bpm]);
+ }
+ }
+
+ /* Third and final pass over the whole video segment space */
+ pb = &pbs[0];
+ for (j=0; j<5*s->sys->bpm; j++) {
+ if (enc_blks[j].partial_bit_count)
+ pb = dv_encode_ac(&enc_blks[j], pb, &pbs[s->sys->bpm*5]);
+ if (enc_blks[j].partial_bit_count)
+ av_log(avctx, AV_LOG_ERROR, "ac bitstream overflow\n");
+ }
+
+ for (j=0; j<5*s->sys->bpm; j++) {
+ int pos;
+ int size = pbs[j].size_in_bits >> 3;
+ flush_put_bits(&pbs[j]);
+ pos = put_bits_count(&pbs[j]) >> 3;
+ if (pos > size) {
+ av_log(avctx, AV_LOG_ERROR, "bitstream written beyond buffer size\n");
+ return -1;
+ }
+ memset(pbs[j].buf + pos, 0xff, size - pos);
+ }
+
+ return 0;
+}
+
+static inline int dv_write_pack(enum dv_pack_type pack_id, DVVideoContext *c,
+ uint8_t* buf)
+{
+ /*
+ * Here's what SMPTE314M says about these two:
+ * (page 6) APTn, AP1n, AP2n, AP3n: These data shall be identical
+ * as track application IDs (APTn = 001, AP1n =
+ * 001, AP2n = 001, AP3n = 001), if the source signal
+ * comes from a digital VCR. If the signal source is
+ * unknown, all bits for these data shall be set to 1.
+ * (page 12) STYPE: STYPE defines a signal type of video signal
+ * 00000b = 4:1:1 compression
+ * 00100b = 4:2:2 compression
+ * XXXXXX = Reserved
+ * Now, I've got two problems with these statements:
+ * 1. it looks like APT == 111b should be a safe bet, but it isn't.
+ * It seems that for PAL as defined in IEC 61834 we have to set
+ * APT to 000 and for SMPTE314M to 001.
+ * 2. It is not at all clear what STYPE is used for 4:2:0 PAL
+ * compression scheme (if any).
+ */
+ int apt = (c->sys->pix_fmt == AV_PIX_FMT_YUV420P ? 0 : 1);
+ int fs = c->frame->top_field_first ? 0x00 : 0x40;
+
+ uint8_t aspect = 0;
+ if ((int)(av_q2d(c->avctx->sample_aspect_ratio) * c->avctx->width / c->avctx->height * 10) >= 17) /* 16:9 */
+ aspect = 0x02;
+
+ buf[0] = (uint8_t)pack_id;
+ switch (pack_id) {
+ case dv_header525: /* I can't imagine why these two weren't defined as real */
+ case dv_header625: /* packs in SMPTE314M -- they definitely look like ones */
+ buf[1] = 0xf8 | /* reserved -- always 1 */
+ (apt & 0x07); /* APT: Track application ID */
+ buf[2] = (0 << 7) | /* TF1: audio data is 0 - valid; 1 - invalid */
+ (0x0f << 3) | /* reserved -- always 1 */
+ (apt & 0x07); /* AP1: Audio application ID */
+ buf[3] = (0 << 7) | /* TF2: video data is 0 - valid; 1 - invalid */
+ (0x0f << 3) | /* reserved -- always 1 */
+ (apt & 0x07); /* AP2: Video application ID */
+ buf[4] = (0 << 7) | /* TF3: subcode(SSYB) is 0 - valid; 1 - invalid */
+ (0x0f << 3) | /* reserved -- always 1 */
+ (apt & 0x07); /* AP3: Subcode application ID */
+ break;
+ case dv_video_source:
+ buf[1] = 0xff; /* reserved -- always 1 */
+ buf[2] = (1 << 7) | /* B/W: 0 - b/w, 1 - color */
+ (1 << 6) | /* following CLF is valid - 0, invalid - 1 */
+ (3 << 4) | /* CLF: color frames ID (see ITU-R BT.470-4) */
+ 0xf; /* reserved -- always 1 */
+ buf[3] = (3 << 6) | /* reserved -- always 1 */
+ (c->sys->dsf << 5) | /* system: 60fields/50fields */
+ c->sys->video_stype; /* signal type video compression */
+ buf[4] = 0xff; /* VISC: 0xff -- no information */
+ break;
+ case dv_video_control:
+ buf[1] = (0 << 6) | /* Copy generation management (CGMS) 0 -- free */
+ 0x3f; /* reserved -- always 1 */
+ buf[2] = 0xc8 | /* reserved -- always b11001xxx */
+ aspect;
+ buf[3] = (1 << 7) | /* frame/field flag 1 -- frame, 0 -- field */
+ fs | /* first/second field flag 0 -- field 2, 1 -- field 1 */
+ (1 << 5) | /* frame change flag 0 -- same picture as before, 1 -- different */
+ (1 << 4) | /* 1 - interlaced, 0 - noninterlaced */
+ 0xc; /* reserved -- always b1100 */
+ buf[4] = 0xff; /* reserved -- always 1 */
+ break;
+ default:
+ buf[1] = buf[2] = buf[3] = buf[4] = 0xff;
+ }
+ return 5;
+}
+
+static inline int dv_write_dif_id(enum dv_section_type t, uint8_t chan_num,
+ uint8_t seq_num, uint8_t dif_num,
+ uint8_t* buf)
+{
+ buf[0] = (uint8_t)t; /* Section type */
+ buf[1] = (seq_num << 4) | /* DIF seq number 0-9 for 525/60; 0-11 for 625/50 */
+ (chan_num << 3) | /* FSC: for 50Mb/s 0 - first channel; 1 - second */
+ 7; /* reserved -- always 1 */
+ buf[2] = dif_num; /* DIF block number Video: 0-134, Audio: 0-8 */
+ return 3;
+}
+
+
+static inline int dv_write_ssyb_id(uint8_t syb_num, uint8_t fr, uint8_t* buf)
+{
+ if (syb_num == 0 || syb_num == 6) {
+ buf[0] = (fr << 7) | /* FR ID 1 - first half of each channel; 0 - second */
+ (0 << 4) | /* AP3 (Subcode application ID) */
+ 0x0f; /* reserved -- always 1 */
+ }
+ else if (syb_num == 11) {
+ buf[0] = (fr << 7) | /* FR ID 1 - first half of each channel; 0 - second */
+ 0x7f; /* reserved -- always 1 */
+ }
+ else {
+ buf[0] = (fr << 7) | /* FR ID 1 - first half of each channel; 0 - second */
+ (0 << 4) | /* APT (Track application ID) */
+ 0x0f; /* reserved -- always 1 */
+ }
+ buf[1] = 0xf0 | /* reserved -- always 1 */
+ (syb_num & 0x0f); /* SSYB number 0 - 11 */
+ buf[2] = 0xff; /* reserved -- always 1 */
+ return 3;
+}
+
+static void dv_format_frame(DVVideoContext* c, uint8_t* buf)
+{
+ int chan, i, j, k;
+
+ for (chan = 0; chan < c->sys->n_difchan; chan++) {
+ for (i = 0; i < c->sys->difseg_size; i++) {
+ memset(buf, 0xff, 80 * 6); /* first 6 DIF blocks are for control data */
+
+ /* DV header: 1DIF */
+ buf += dv_write_dif_id(dv_sect_header, chan, i, 0, buf);
+ buf += dv_write_pack((c->sys->dsf ? dv_header625 : dv_header525), c, buf);
+ buf += 72; /* unused bytes */
+
+ /* DV subcode: 2DIFs */
+ for (j = 0; j < 2; j++) {
+ buf += dv_write_dif_id(dv_sect_subcode, chan, i, j, buf);
+ for (k = 0; k < 6; k++)
+ buf += dv_write_ssyb_id(k, (i < c->sys->difseg_size/2), buf) + 5;
+ buf += 29; /* unused bytes */
+ }
+
+ /* DV VAUX: 3DIFS */
+ for (j = 0; j < 3; j++) {
+ buf += dv_write_dif_id(dv_sect_vaux, chan, i, j, buf);
+ buf += dv_write_pack(dv_video_source, c, buf);
+ buf += dv_write_pack(dv_video_control, c, buf);
+ buf += 7*5;
+ buf += dv_write_pack(dv_video_source, c, buf);
+ buf += dv_write_pack(dv_video_control, c, buf);
+ buf += 4*5 + 2; /* unused bytes */
+ }
+
+ /* DV Audio/Video: 135 Video DIFs + 9 Audio DIFs */
+ for (j = 0; j < 135; j++) {
+ if (j%15 == 0) {
+ memset(buf, 0xff, 80);
+ buf += dv_write_dif_id(dv_sect_audio, chan, i, j/15, buf);
+ buf += 77; /* audio control & shuffled PCM audio */
+ }
+ buf += dv_write_dif_id(dv_sect_video, chan, i, j, buf);
+ buf += 77; /* 1 video macroblock: 1 bytes control
+ 4 * 14 bytes Y 8x8 data
+ 10 bytes Cr 8x8 data
+ 10 bytes Cb 8x8 data */
+ }
+ }
+ }
+}
+
+
+static int dvvideo_encode_frame(AVCodecContext *c, AVPacket *pkt,
+ const AVFrame *frame, int *got_packet)
+{
+ DVVideoContext *s = c->priv_data;
+ int ret;
+
+ s->sys = avpriv_dv_codec_profile(c);
+ if (!s->sys || ff_dv_init_dynamic_tables(s->sys))
+ return -1;
+ if ((ret = ff_alloc_packet2(c, pkt, s->sys->frame_size)) < 0)
+ return ret;
+
+ c->pix_fmt = s->sys->pix_fmt;
+ s->frame = frame;
+ c->coded_frame->key_frame = 1;
+ c->coded_frame->pict_type = AV_PICTURE_TYPE_I;
+
+ s->buf = pkt->data;
+ c->execute(c, dv_encode_video_segment, s->sys->work_chunks, NULL,
+ dv_work_pool_size(s->sys), sizeof(DVwork_chunk));
+
+ emms_c();
+
+ dv_format_frame(s, pkt->data);
+
+ pkt->flags |= AV_PKT_FLAG_KEY;
+ *got_packet = 1;
+
+ return 0;
+}
+
+static int dvvideo_encode_close(AVCodecContext *avctx)
+{
+ av_frame_free(&avctx->coded_frame);
+ return 0;
+}
+
+AVCodec ff_dvvideo_encoder = {
+ .name = "dvvideo",
+ .long_name = NULL_IF_CONFIG_SMALL("DV (Digital Video)"),
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = AV_CODEC_ID_DVVIDEO,
+ .priv_data_size = sizeof(DVVideoContext),
+ .init = dvvideo_init_encoder,
+ .encode2 = dvvideo_encode_frame,
+ .close = dvvideo_encode_close,
+ .capabilities = CODEC_CAP_SLICE_THREADS,
+ .pix_fmts = (const enum AVPixelFormat[]) {
+ AV_PIX_FMT_YUV411P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE
+ },
+};
diff --git a/libavcodec/dxa.c b/libavcodec/dxa.c
index 2704852..1d96f10 100644
--- a/libavcodec/dxa.c
+++ b/libavcodec/dxa.c
@@ -321,12 +321,12 @@
{
DxaDecContext * const c = avctx->priv_data;
- avctx->pix_fmt = AV_PIX_FMT_PAL8;
-
c->prev = av_frame_alloc();
if (!c->prev)
return AVERROR(ENOMEM);
+ avctx->pix_fmt = AV_PIX_FMT_PAL8;
+
c->dsize = avctx->width * avctx->height * 2;
c->decomp_buf = av_malloc(c->dsize);
if (!c->decomp_buf) {
diff --git a/libavcodec/dxva2_mpeg2.c b/libavcodec/dxva2_mpeg2.c
index 542f17c..1827dd5 100644
--- a/libavcodec/dxva2_mpeg2.c
+++ b/libavcodec/dxva2_mpeg2.c
@@ -139,8 +139,7 @@
init_get_bits(&gb, &buffer[4], 8 * (size - 4));
slice->wQuantizerScaleCode = get_bits(&gb, 5);
- while (get_bits1(&gb))
- skip_bits(&gb, 8);
+ skip_1stop_8data_bits(&gb);
slice->wMBbitOffset = 4 * 8 + get_bits_count(&gb);
}
diff --git a/libavcodec/dxva2_vc1.c b/libavcodec/dxva2_vc1.c
index 92c78fd..2e9a00e 100644
--- a/libavcodec/dxva2_vc1.c
+++ b/libavcodec/dxva2_vc1.c
@@ -97,7 +97,7 @@
(v->vstransform );
pp->bPicOverflowBlocks = (v->quantizer_mode << 6) |
(v->multires << 5) |
- (s->resync_marker << 4) |
+ (v->resync_marker << 4) |
(v->rangered << 3) |
(s->max_b_frames );
pp->bPicExtrapolation = (!v->interlace || v->fcm == PROGRESSIVE) ? 1 : 2;
diff --git a/libavcodec/eacmv.c b/libavcodec/eacmv.c
index 3f22c74..b3ffb3f 100644
--- a/libavcodec/eacmv.c
+++ b/libavcodec/eacmv.c
@@ -130,21 +130,23 @@
}
}
-static void cmv_process_header(CmvContext *s, const uint8_t *buf, const uint8_t *buf_end)
+static int cmv_process_header(CmvContext *s, const uint8_t *buf, const uint8_t *buf_end)
{
- int pal_start, pal_count, i;
+ int pal_start, pal_count, i, ret;
if(buf_end - buf < 16) {
av_log(s->avctx, AV_LOG_WARNING, "truncated header\n");
- return;
+ return AVERROR_INVALIDDATA;
}
s->width = AV_RL16(&buf[4]);
s->height = AV_RL16(&buf[6]);
if (s->avctx->width!=s->width || s->avctx->height!=s->height) {
- avcodec_set_dimensions(s->avctx, s->width, s->height);
av_frame_unref(s->last_frame);
av_frame_unref(s->last2_frame);
+ ret = ff_set_dimensions(s->avctx, s->width, s->height);
+ if (ret < 0)
+ return ret;
}
s->avctx->time_base.num = 1;
@@ -158,6 +160,8 @@
s->palette[i] = 0xFFU << 24 | AV_RB24(buf);
buf += 3;
}
+
+ return 0;
}
#define EA_PREAMBLE_SIZE 8
@@ -179,7 +183,9 @@
if (AV_RL32(buf)==MVIh_TAG||AV_RB32(buf)==MVIh_TAG) {
unsigned size = AV_RL32(buf + 4);
- cmv_process_header(s, buf+EA_PREAMBLE_SIZE, buf_end);
+ ret = cmv_process_header(s, buf+EA_PREAMBLE_SIZE, buf_end);
+ if (ret < 0)
+ return ret;
if (size > buf_end - buf - EA_PREAMBLE_SIZE)
return -1;
buf += size;
diff --git a/libavcodec/eamad.c b/libavcodec/eamad.c
index 6d8291e..2d34d35 100644
--- a/libavcodec/eamad.c
+++ b/libavcodec/eamad.c
@@ -45,7 +45,7 @@
typedef struct MadContext {
AVCodecContext *avctx;
DSPContext dsp;
- AVFrame last_frame;
+ AVFrame *last_frame;
GetBitContext gb;
void *bitstream_buf;
unsigned int bitstream_buf_size;
@@ -65,6 +65,11 @@
ff_init_scantable_permutation(s->dsp.idct_permutation, FF_NO_IDCT_PERM);
ff_init_scantable(s->dsp.idct_permutation, &s->scantable, ff_zigzag_direct);
ff_mpeg12_init_vlcs();
+
+ s->last_frame = av_frame_alloc();
+ if (!s->last_frame)
+ return AVERROR(ENOMEM);
+
return 0;
}
@@ -82,22 +87,22 @@
int j, int mv_x, int mv_y, int add)
{
if (j < 4) {
- unsigned offset = (mb_y*16 + ((j&2)<<2) + mv_y)*t->last_frame.linesize[0] + mb_x*16 + ((j&1)<<3) + mv_x;
- if (offset >= (t->avctx->height - 7) * t->last_frame.linesize[0] - 7)
+ unsigned offset = (mb_y*16 + ((j&2)<<2) + mv_y)*t->last_frame->linesize[0] + mb_x*16 + ((j&1)<<3) + mv_x;
+ if (offset >= (t->avctx->height - 7) * t->last_frame->linesize[0] - 7)
return;
comp(frame->data[0] + (mb_y*16 + ((j&2)<<2))*frame->linesize[0] + mb_x*16 + ((j&1)<<3),
frame->linesize[0],
- t->last_frame.data[0] + offset,
- t->last_frame.linesize[0], add);
+ t->last_frame->data[0] + offset,
+ t->last_frame->linesize[0], add);
} else if (!(t->avctx->flags & CODEC_FLAG_GRAY)) {
int index = j - 3;
- unsigned offset = (mb_y * 8 + (mv_y/2))*t->last_frame.linesize[index] + mb_x * 8 + (mv_x/2);
- if (offset >= (t->avctx->height/2 - 7) * t->last_frame.linesize[index] - 7)
+ unsigned offset = (mb_y * 8 + (mv_y/2))*t->last_frame->linesize[index] + mb_x * 8 + (mv_x/2);
+ if (offset >= (t->avctx->height/2 - 7) * t->last_frame->linesize[index] - 7)
return;
comp(frame->data[index] + (mb_y*8)*frame->linesize[index] + mb_x * 8,
frame->linesize[index],
- t->last_frame.data[index] + offset,
- t->last_frame.linesize[index], add);
+ t->last_frame->data[index] + offset,
+ t->last_frame->linesize[index], add);
}
}
@@ -205,7 +210,7 @@
for (j=0; j<6; j++) {
if (mv_map & (1<<j)) { // mv_x and mv_y are guarded by mv_map
int add = 2*decode_motion(&s->gb);
- if (s->last_frame.data[0])
+ if (s->last_frame->data[0])
comp_block(s, frame, s->mb_x, s->mb_y, j, mv_x, mv_y, add);
} else {
s->dsp.clear_block(s->block);
@@ -263,28 +268,27 @@
}
if (avctx->width != width || avctx->height != height) {
+ av_frame_unref(s->last_frame);
if((width * height)/2048*7 > buf_end-buf)
return AVERROR_INVALIDDATA;
- if ((ret = av_image_check_size(width, height, 0, avctx)) < 0)
+ if ((ret = ff_set_dimensions(avctx, width, height)) < 0)
return ret;
- avcodec_set_dimensions(avctx, width, height);
- av_frame_unref(&s->last_frame);
}
if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0)
return ret;
- if (inter && !s->last_frame.data[0]) {
+ if (inter && !s->last_frame->data[0]) {
av_log(avctx, AV_LOG_WARNING, "Missing reference frame.\n");
- ret = ff_get_buffer(avctx, &s->last_frame, AV_GET_BUFFER_FLAG_REF);
+ ret = ff_get_buffer(avctx, s->last_frame, AV_GET_BUFFER_FLAG_REF);
if (ret < 0)
return ret;
- memset(s->last_frame.data[0], 0, s->last_frame.height *
- s->last_frame.linesize[0]);
- memset(s->last_frame.data[1], 0x80, s->last_frame.height / 2 *
- s->last_frame.linesize[1]);
- memset(s->last_frame.data[2], 0x80, s->last_frame.height / 2 *
- s->last_frame.linesize[2]);
+ memset(s->last_frame->data[0], 0, s->last_frame->height *
+ s->last_frame->linesize[0]);
+ memset(s->last_frame->data[1], 0x80, s->last_frame->height / 2 *
+ s->last_frame->linesize[1]);
+ memset(s->last_frame->data[2], 0x80, s->last_frame->height / 2 *
+ s->last_frame->linesize[2]);
}
av_fast_padded_malloc(&s->bitstream_buf, &s->bitstream_buf_size,
@@ -303,8 +307,8 @@
*got_frame = 1;
if (chunk_type != MADe_TAG) {
- av_frame_unref(&s->last_frame);
- if ((ret = av_frame_ref(&s->last_frame, frame)) < 0)
+ av_frame_unref(s->last_frame);
+ if ((ret = av_frame_ref(s->last_frame, frame)) < 0)
return ret;
}
@@ -314,7 +318,7 @@
static av_cold int decode_end(AVCodecContext *avctx)
{
MadContext *t = avctx->priv_data;
- av_frame_unref(&t->last_frame);
+ av_frame_free(&t->last_frame);
av_free(t->bitstream_buf);
return 0;
}
diff --git a/libavcodec/eatgq.c b/libavcodec/eatgq.c
index a24550b..2950d05 100644
--- a/libavcodec/eatgq.c
+++ b/libavcodec/eatgq.c
@@ -219,9 +219,10 @@
s->height = bytestream2_get_le16u(&s->gb);
}
- if (s->avctx->width!=s->width || s->avctx->height!=s->height) {
- avcodec_set_dimensions(s->avctx, s->width, s->height);
- }
+ ret = ff_set_dimensions(s->avctx, s->width, s->height);
+ if (ret < 0)
+ return ret;
+
tgq_calculate_qtable(s, bytestream2_get_byteu(&s->gb));
bytestream2_skip(&s->gb, 3);
diff --git a/libavcodec/eatgv.c b/libavcodec/eatgv.c
index bfdfb76..952ebb3 100644
--- a/libavcodec/eatgv.c
+++ b/libavcodec/eatgv.c
@@ -40,7 +40,7 @@
typedef struct TgvContext {
AVCodecContext *avctx;
- AVFrame last_frame;
+ AVFrame *last_frame;
uint8_t *frame_buffer;
int width,height;
uint32_t palette[AVPALETTE_COUNT];
@@ -57,7 +57,11 @@
s->avctx = avctx;
avctx->time_base = (AVRational){1, 15};
avctx->pix_fmt = AV_PIX_FMT_PAL8;
- avcodec_get_frame_defaults(&s->last_frame);
+
+ s->last_frame = av_frame_alloc();
+ if (!s->last_frame)
+ return AVERROR(ENOMEM);
+
return 0;
}
@@ -177,9 +181,10 @@
}
if (num_blocks_packed > s->num_blocks_packed) {
- if (av_reallocp_array(&s->block_codebook, num_blocks_packed, sizeof(*s->block_codebook))) {
+ int err;
+ if ((err = av_reallocp(&s->block_codebook, num_blocks_packed * 16)) < 0) {
s->num_blocks_packed = 0;
- return AVERROR(ENOMEM);
+ return err;
}
s->num_blocks_packed = num_blocks_packed;
}
@@ -232,8 +237,8 @@
continue;
}
- src = s->last_frame.data[0] + mx + my * s->last_frame.linesize[0];
- src_stride = s->last_frame.linesize[0];
+ src = s->last_frame->data[0] + mx + my * s->last_frame->linesize[0];
+ src_stride = s->last_frame->linesize[0];
} else {
int offset = vector - num_mvs;
if (offset < num_blocks_raw)
@@ -281,9 +286,10 @@
s->width = AV_RL16(&buf[0]);
s->height = AV_RL16(&buf[2]);
if (s->avctx->width != s->width || s->avctx->height != s->height) {
- avcodec_set_dimensions(s->avctx, s->width, s->height);
av_freep(&s->frame_buffer);
- av_frame_unref(&s->last_frame);
+ av_frame_unref(s->last_frame);
+ if ((ret = ff_set_dimensions(s->avctx, s->width, s->height)) < 0)
+ return ret;
}
pal_count = AV_RL16(&buf[6]);
@@ -294,9 +300,6 @@
}
}
- if ((ret = av_image_check_size(s->width, s->height, 0, avctx)) < 0)
- return ret;
-
if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0)
return ret;
@@ -320,7 +323,7 @@
s->frame_buffer + y * s->width,
s->width);
} else {
- if (!s->last_frame.data[0]) {
+ if (!s->last_frame->data[0]) {
av_log(avctx, AV_LOG_WARNING, "inter frame without corresponding intra frame\n");
return buf_size;
}
@@ -332,8 +335,8 @@
}
}
- av_frame_unref(&s->last_frame);
- if ((ret = av_frame_ref(&s->last_frame, frame)) < 0)
+ av_frame_unref(s->last_frame);
+ if ((ret = av_frame_ref(s->last_frame, frame)) < 0)
return ret;
*got_frame = 1;
@@ -344,7 +347,7 @@
static av_cold int tgv_decode_end(AVCodecContext *avctx)
{
TgvContext *s = avctx->priv_data;
- av_frame_unref(&s->last_frame);
+ av_frame_free(&s->last_frame);
av_freep(&s->frame_buffer);
av_free(s->mv_codebook);
av_free(s->block_codebook);
diff --git a/libavcodec/eatqi.c b/libavcodec/eatqi.c
index 262deb1..387456a 100644
--- a/libavcodec/eatqi.c
+++ b/libavcodec/eatqi.c
@@ -111,8 +111,9 @@
tqi_calculate_qtable(s, buf[4]);
buf += 8;
- if (s->avctx->width!=s->width || s->avctx->height!=s->height)
- avcodec_set_dimensions(s->avctx, s->width, s->height);
+ ret = ff_set_dimensions(s->avctx, s->width, s->height);
+ if (ret < 0)
+ return ret;
if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
return ret;
diff --git a/libavcodec/elbg.c b/libavcodec/elbg.c
index 2707599..5c7018b 100644
--- a/libavcodec/elbg.c
+++ b/libavcodec/elbg.c
@@ -324,7 +324,7 @@
#define BIG_PRIME 433494437LL
-void ff_init_elbg(int *points, int dim, int numpoints, int *codebook,
+void avpriv_init_elbg(int *points, int dim, int numpoints, int *codebook,
int numCB, int max_steps, int *closest_cb,
AVLFG *rand_state)
{
@@ -339,8 +339,8 @@
memcpy(temp_points + i*dim, points + k*dim, dim*sizeof(int));
}
- ff_init_elbg(temp_points, dim, numpoints/8, codebook, numCB, 2*max_steps, closest_cb, rand_state);
- ff_do_elbg(temp_points, dim, numpoints/8, codebook, numCB, 2*max_steps, closest_cb, rand_state);
+ avpriv_init_elbg(temp_points, dim, numpoints/8, codebook, numCB, 2*max_steps, closest_cb, rand_state);
+ avpriv_do_elbg(temp_points, dim, numpoints/8, codebook, numCB, 2*max_steps, closest_cb, rand_state);
av_free(temp_points);
@@ -351,7 +351,7 @@
}
-void ff_do_elbg(int *points, int dim, int numpoints, int *codebook,
+void avpriv_do_elbg(int *points, int dim, int numpoints, int *codebook,
int numCB, int max_steps, int *closest_cb,
AVLFG *rand_state)
{
diff --git a/libavcodec/elbg.h b/libavcodec/elbg.h
index e6f577e..22fb53f 100644
--- a/libavcodec/elbg.h
+++ b/libavcodec/elbg.h
@@ -37,7 +37,7 @@
* @param closest_cb Return the closest codebook to each point. Must be allocated.
* @param rand_state A random number generator state. Should be already initialized by av_lfg_init().
*/
-void ff_do_elbg(int *points, int dim, int numpoints, int *codebook,
+void avpriv_do_elbg(int *points, int dim, int numpoints, int *codebook,
int numCB, int num_steps, int *closest_cb,
AVLFG *rand_state);
@@ -45,10 +45,10 @@
* Initialize the **codebook vector for the elbg algorithm. If you have already
* a codebook and you want to refine it, you shouldn't call this function.
* If numpoints < 8*numCB this function fills **codebook with random numbers.
- * If not, it calls ff_do_elbg for a (smaller) random sample of the points in
- * **points. Get the same parameters as ff_do_elbg.
+ * If not, it calls avpriv_do_elbg for a (smaller) random sample of the points in
+ * **points. Get the same parameters as avpriv_do_elbg.
*/
-void ff_init_elbg(int *points, int dim, int numpoints, int *codebook,
+void avpriv_init_elbg(int *points, int dim, int numpoints, int *codebook,
int numCB, int num_steps, int *closest_cb,
AVLFG *rand_state);
diff --git a/libavcodec/error_resilience.c b/libavcodec/error_resilience.c
index b9924a6..8e3fb61 100644
--- a/libavcodec/error_resilience.c
+++ b/libavcodec/error_resilience.c
@@ -27,11 +27,13 @@
#include <limits.h>
+#include "libavutil/internal.h"
#include "avcodec.h"
#include "error_resilience.h"
#include "mpegvideo.h"
#include "rectangle.h"
#include "thread.h"
+#include "version.h"
/**
* @param stride the number of MVs to get to the next row
@@ -697,11 +699,15 @@
if (undamaged_count < 5)
return 0; // almost all MBs damaged -> use temporal prediction
+#if FF_API_XVMC
+FF_DISABLE_DEPRECATION_WARNINGS
// prevent dsp.sad() check, that requires access to the image
if (CONFIG_MPEG_XVMC_DECODER &&
s->avctx->xvmc_acceleration &&
s->cur_pic->f.pict_type == AV_PICTURE_TYPE_I)
return 1;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif /* FF_API_XVMC */
skip_amount = FFMAX(undamaged_count / 50, 1); // check only up to 50 MBs
is_intra_likely = 0;
@@ -753,7 +759,7 @@
void ff_er_frame_start(ERContext *s)
{
- if (!s->avctx->err_recognition)
+ if (!s->avctx->error_concealment)
return;
memset(s->error_status_table, ER_MB_ERROR | VP_START | ER_MB_END,
@@ -762,6 +768,17 @@
s->error_occurred = 0;
}
+static int er_supported(ERContext *s)
+{
+ if(s->avctx->hwaccel ||
+ s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU ||
+ !s->cur_pic ||
+ s->cur_pic->field_picture
+ )
+ return 0;
+ return 1;
+}
+
/**
* Add a slice.
* @param endx x component of the last macroblock, can be -1
@@ -787,7 +804,7 @@
return;
}
- if (!s->avctx->err_recognition)
+ if (!s->avctx->error_concealment)
return;
mask &= ~VP_START;
@@ -828,7 +845,7 @@
s->error_status_table[start_xy] |= VP_START;
if (start_xy > 0 && !(s->avctx->active_thread_type & FF_THREAD_SLICE) &&
- s->avctx->skip_top * s->mb_width < start_i) {
+ er_supported(s) && s->avctx->skip_top * s->mb_width < start_i) {
int prev_status = s->error_status_table[s->mb_index2xy[start_i - 1]];
prev_status &= ~ VP_START;
@@ -851,11 +868,9 @@
/* We do not support ER of field pictures yet,
* though it should not crash if enabled. */
- if (!s->avctx->err_recognition || s->error_count == 0 ||
+ if (!s->avctx->error_concealment || s->error_count == 0 ||
s->avctx->lowres ||
- s->avctx->hwaccel ||
- s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU ||
- !s->cur_pic || s->cur_pic->field_picture ||
+ !er_supported(s) ||
s->error_count == 3 * s->mb_width *
(s->avctx->skip_top + s->avctx->skip_bottom)) {
return;
@@ -1173,9 +1188,13 @@
} else
guess_mv(s);
+#if FF_API_XVMC
+FF_DISABLE_DEPRECATION_WARNINGS
/* the filters below are not XvMC compatible, skip them */
if (CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration)
goto ec_clean;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif /* FF_API_XVMC */
/* fill DC for inter blocks */
for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
diff --git a/libavcodec/escape124.c b/libavcodec/escape124.c
index a050fcb..bed1efb 100644
--- a/libavcodec/escape124.c
+++ b/libavcodec/escape124.c
@@ -42,7 +42,7 @@
} CodeBook;
typedef struct Escape124Context {
- AVFrame frame;
+ AVFrame *frame;
unsigned num_superblocks;
@@ -58,12 +58,15 @@
{
Escape124Context *s = avctx->priv_data;
- avcodec_get_frame_defaults(&s->frame);
avctx->pix_fmt = AV_PIX_FMT_RGB555;
s->num_superblocks = ((unsigned)avctx->width / 8) *
((unsigned)avctx->height / 8);
+ s->frame = av_frame_alloc();
+ if (!s->frame)
+ return AVERROR(ENOMEM);
+
return 0;
}
@@ -75,7 +78,7 @@
for (i = 0; i < 3; i++)
av_free(s->codebooks[i].blocks);
- av_frame_unref(&s->frame);
+ av_frame_free(&s->frame);
return 0;
}
@@ -227,13 +230,13 @@
// Leave last frame unchanged
// FIXME: Is this necessary? I haven't seen it in any real samples
if (!(frame_flags & 0x114) || !(frame_flags & 0x7800000)) {
- if (!s->frame.data[0])
+ if (!s->frame->data[0])
return AVERROR_INVALIDDATA;
av_log(avctx, AV_LOG_DEBUG, "Skipping frame\n");
*got_frame = 1;
- if ((ret = av_frame_ref(frame, &s->frame)) < 0)
+ if ((ret = av_frame_ref(frame, s->frame)) < 0)
return ret;
return frame_size;
@@ -272,8 +275,8 @@
new_frame_data = (uint16_t*)frame->data[0];
new_stride = frame->linesize[0] / 2;
- old_frame_data = (uint16_t*)s->frame.data[0];
- old_stride = s->frame.linesize[0] / 2;
+ old_frame_data = (uint16_t*)s->frame->data[0];
+ old_stride = s->frame->linesize[0] / 2;
for (superblock_index = 0; superblock_index < s->num_superblocks;
superblock_index++) {
@@ -350,8 +353,8 @@
"Escape sizes: %i, %i, %i\n",
frame_size, buf_size, get_bits_count(&gb) / 8);
- av_frame_unref(&s->frame);
- if ((ret = av_frame_ref(&s->frame, frame)) < 0)
+ av_frame_unref(s->frame);
+ if ((ret = av_frame_ref(s->frame, frame)) < 0)
return ret;
*got_frame = 1;
diff --git a/libavcodec/exr.c b/libavcodec/exr.c
index 021d5a4..f231b70 100644
--- a/libavcodec/exr.c
+++ b/libavcodec/exr.c
@@ -32,8 +32,10 @@
#include <zlib.h>
+#include "get_bits.h"
#include "avcodec.h"
#include "bytestream.h"
+#include "internal.h"
#include "mathops.h"
#include "thread.h"
#include "libavutil/imgutils.h"
@@ -67,6 +69,9 @@
uint8_t *tmp;
int tmp_size;
+
+ uint8_t *bitmap;
+ uint16_t *lut;
} EXRThreadData;
typedef struct EXRContext {
@@ -277,6 +282,461 @@
return 0;
}
+#define USHORT_RANGE (1 << 16)
+#define BITMAP_SIZE (1 << 13)
+
+static uint16_t reverse_lut(const uint8_t *bitmap, uint16_t *lut)
+{
+ int i, k = 0;
+
+ for (i = 0; i < USHORT_RANGE; i++) {
+ if ((i == 0) || (bitmap[i >> 3] & (1 << (i & 7))))
+ lut[k++] = i;
+ }
+
+ i = k - 1;
+
+ memset(lut + k, 0, (USHORT_RANGE - k) * 2);
+
+ return i;
+}
+
+static void apply_lut(const uint16_t *lut, uint16_t *dst, int dsize)
+{
+ int i;
+
+ for (i = 0; i < dsize; ++i)
+ dst[i] = lut[dst[i]];
+}
+
+#define HUF_ENCBITS 16 // literal (value) bit length
+#define HUF_DECBITS 14 // decoding bit size (>= 8)
+
+#define HUF_ENCSIZE ((1 << HUF_ENCBITS) + 1) // encoding table size
+#define HUF_DECSIZE (1 << HUF_DECBITS) // decoding table size
+#define HUF_DECMASK (HUF_DECSIZE - 1)
+
+typedef struct HufDec {
+ int len;
+ int lit;
+ int *p;
+} HufDec;
+
+static void huf_canonical_code_table(uint64_t *hcode)
+{
+ uint64_t c, n[59] = { 0 };
+ int i;
+
+ for (i = 0; i < HUF_ENCSIZE; ++i)
+ n[hcode[i]] += 1;
+
+ c = 0;
+ for (i = 58; i > 0; --i) {
+ uint64_t nc = ((c + n[i]) >> 1);
+ n[i] = c;
+ c = nc;
+ }
+
+ for (i = 0; i < HUF_ENCSIZE; ++i) {
+ int l = hcode[i];
+
+ if (l > 0)
+ hcode[i] = l | (n[l]++ << 6);
+ }
+}
+
+#define SHORT_ZEROCODE_RUN 59
+#define LONG_ZEROCODE_RUN 63
+#define SHORTEST_LONG_RUN (2 + LONG_ZEROCODE_RUN - SHORT_ZEROCODE_RUN)
+#define LONGEST_LONG_RUN (255 + SHORTEST_LONG_RUN)
+
+static int huf_unpack_enc_table(GetByteContext *gb,
+ int32_t im, int32_t iM, uint64_t *hcode)
+{
+ GetBitContext gbit;
+
+ init_get_bits8(&gbit, gb->buffer, bytestream2_get_bytes_left(gb));
+
+ for (; im <= iM; im++) {
+ uint64_t l = hcode[im] = get_bits(&gbit, 6);
+
+ if (l == LONG_ZEROCODE_RUN) {
+ int zerun = get_bits(&gbit, 8) + SHORTEST_LONG_RUN;
+
+ if (im + zerun > iM + 1)
+ return AVERROR_INVALIDDATA;
+
+ while (zerun--)
+ hcode[im++] = 0;
+
+ im--;
+ } else if (l >= (uint64_t) SHORT_ZEROCODE_RUN) {
+ int zerun = l - SHORT_ZEROCODE_RUN + 2;
+
+ if (im + zerun > iM + 1)
+ return AVERROR_INVALIDDATA;
+
+ while (zerun--)
+ hcode[im++] = 0;
+
+ im--;
+ }
+ }
+
+ bytestream2_skip(gb, (get_bits_count(&gbit) + 7) / 8);
+ huf_canonical_code_table(hcode);
+
+ return 0;
+}
+
+static int huf_build_dec_table(const uint64_t *hcode, int im,
+ int iM, HufDec *hdecod)
+{
+ for (; im <= iM; im++) {
+ uint64_t c = hcode[im] >> 6;
+ int i, l = hcode[im] & 63;
+
+ if (c >> l)
+ return AVERROR_INVALIDDATA;
+
+ if (l > HUF_DECBITS) {
+ HufDec *pl = hdecod + (c >> (l - HUF_DECBITS));
+ if (pl->len)
+ return AVERROR_INVALIDDATA;
+
+ pl->lit++;
+
+ pl->p = av_realloc_f(pl->p, pl->lit, sizeof(int));
+ if (!pl->p)
+ return AVERROR(ENOMEM);
+
+ pl->p[pl->lit - 1] = im;
+ } else if (l) {
+ HufDec *pl = hdecod + (c << (HUF_DECBITS - l));
+
+ for (i = 1 << (HUF_DECBITS - l); i > 0; i--, pl++) {
+ if (pl->len || pl->p)
+ return AVERROR_INVALIDDATA;
+ pl->len = l;
+ pl->lit = im;
+ }
+ }
+ }
+
+ return 0;
+}
+
+#define get_char(c, lc, gb) { \
+ c = (c << 8) | bytestream2_get_byte(gb); \
+ lc += 8; \
+}
+
+#define get_code(po, rlc, c, lc, gb, out, oe) { \
+ if (po == rlc) { \
+ if (lc < 8) \
+ get_char(c, lc, gb); \
+ lc -= 8; \
+ \
+ cs = c >> lc; \
+ \
+ if (out + cs > oe) \
+ return AVERROR_INVALIDDATA; \
+ \
+ s = out[-1]; \
+ \
+ while (cs-- > 0) \
+ *out++ = s; \
+ } else if (out < oe) { \
+ *out++ = po; \
+ } else { \
+ return AVERROR_INVALIDDATA; \
+ } \
+}
+
+static int huf_decode(const uint64_t *hcode, const HufDec *hdecod,
+ GetByteContext *gb, int nbits,
+ int rlc, int no, uint16_t *out)
+{
+ uint64_t c = 0;
+ uint16_t *outb = out;
+ uint16_t *oe = out + no;
+ const uint8_t *ie = gb->buffer + (nbits + 7) / 8; // input byte size
+ uint8_t cs, s;
+ int i, lc = 0;
+
+ while (gb->buffer < ie) {
+ get_char(c, lc, gb);
+
+ while (lc >= HUF_DECBITS) {
+ const HufDec pl = hdecod[(c >> (lc-HUF_DECBITS)) & HUF_DECMASK];
+
+ if (pl.len) {
+ lc -= pl.len;
+ get_code(pl.lit, rlc, c, lc, gb, out, oe);
+ } else {
+ int j;
+
+ if (!pl.p)
+ return AVERROR_INVALIDDATA;
+
+ for (j = 0; j < pl.lit; j++) {
+ int l = hcode[pl.p[j]] & 63;
+
+ while (lc < l && bytestream2_get_bytes_left(gb) > 0)
+ get_char(c, lc, gb);
+
+ if (lc >= l) {
+ if ((hcode[pl.p[j]] >> 6) ==
+ ((c >> (lc - l)) & ((1LL << l) - 1))) {
+ lc -= l;
+ get_code(pl.p[j], rlc, c, lc, gb, out, oe);
+ break;
+ }
+ }
+ }
+
+ if (j == pl.lit)
+ return AVERROR_INVALIDDATA;
+ }
+ }
+ }
+
+ i = (8 - nbits) & 7;
+ c >>= i;
+ lc -= i;
+
+ while (lc > 0) {
+ const HufDec pl = hdecod[(c << (HUF_DECBITS - lc)) & HUF_DECMASK];
+
+ if (pl.len) {
+ lc -= pl.len;
+ get_code(pl.lit, rlc, c, lc, gb, out, oe);
+ } else {
+ return AVERROR_INVALIDDATA;
+ }
+ }
+
+ if (out - outb != no)
+ return AVERROR_INVALIDDATA;
+ return 0;
+}
+
+static int huf_uncompress(GetByteContext *gb,
+ uint16_t *dst, int dst_size)
+{
+ int32_t src_size, im, iM;
+ uint32_t nBits;
+ uint64_t *freq;
+ HufDec *hdec;
+ int ret, i;
+
+ src_size = bytestream2_get_le32(gb);
+ im = bytestream2_get_le32(gb);
+ iM = bytestream2_get_le32(gb);
+ bytestream2_skip(gb, 4);
+ nBits = bytestream2_get_le32(gb);
+ if (im < 0 || im >= HUF_ENCSIZE ||
+ iM < 0 || iM >= HUF_ENCSIZE ||
+ src_size < 0)
+ return AVERROR_INVALIDDATA;
+
+ bytestream2_skip(gb, 4);
+
+ freq = av_calloc(HUF_ENCSIZE, sizeof(*freq));
+ hdec = av_calloc(HUF_DECSIZE, sizeof(*hdec));
+ if (!freq || !hdec) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+
+ if ((ret = huf_unpack_enc_table(gb, im, iM, freq)) < 0)
+ goto fail;
+
+ if (nBits > 8 * bytestream2_get_bytes_left(gb)) {
+ ret = AVERROR_INVALIDDATA;
+ goto fail;
+ }
+
+ if ((ret = huf_build_dec_table(freq, im, iM, hdec)) < 0)
+ goto fail;
+ ret = huf_decode(freq, hdec, gb, nBits, iM, dst_size, dst);
+
+fail:
+ for (i = 0; i < HUF_DECSIZE; i++) {
+ if (hdec)
+ av_freep(&hdec[i].p);
+ }
+
+ av_free(freq);
+ av_free(hdec);
+
+ return ret;
+}
+
+static inline void wdec14(uint16_t l, uint16_t h, uint16_t *a, uint16_t *b)
+{
+ int16_t ls = l;
+ int16_t hs = h;
+ int hi = hs;
+ int ai = ls + (hi & 1) + (hi >> 1);
+ int16_t as = ai;
+ int16_t bs = ai - hi;
+
+ *a = as;
+ *b = bs;
+}
+
+#define NBITS 16
+#define A_OFFSET (1 << (NBITS - 1))
+#define MOD_MASK ((1 << NBITS) - 1)
+
+static inline void wdec16(uint16_t l, uint16_t h, uint16_t *a, uint16_t *b)
+{
+ int m = l;
+ int d = h;
+ int bb = (m - (d >> 1)) & MOD_MASK;
+ int aa = (d + bb - A_OFFSET) & MOD_MASK;
+ *b = bb;
+ *a = aa;
+}
+
+static void wav_decode(uint16_t *in, int nx, int ox,
+ int ny, int oy, uint16_t mx)
+{
+ int w14 = (mx < (1 << 14));
+ int n = (nx > ny) ? ny: nx;
+ int p = 1;
+ int p2;
+
+ while (p <= n)
+ p <<= 1;
+
+ p >>= 1;
+ p2 = p;
+ p >>= 1;
+
+ while (p >= 1) {
+ uint16_t *py = in;
+ uint16_t *ey = in + oy * (ny - p2);
+ uint16_t i00, i01, i10, i11;
+ int oy1 = oy * p;
+ int oy2 = oy * p2;
+ int ox1 = ox * p;
+ int ox2 = ox * p2;
+
+ for (; py <= ey; py += oy2) {
+ uint16_t *px = py;
+ uint16_t *ex = py + ox * (nx - p2);
+
+ for (; px <= ex; px += ox2) {
+ uint16_t *p01 = px + ox1;
+ uint16_t *p10 = px + oy1;
+ uint16_t *p11 = p10 + ox1;
+
+ if (w14) {
+ wdec14(*px, *p10, &i00, &i10);
+ wdec14(*p01, *p11, &i01, &i11);
+ wdec14(i00, i01, px, p01);
+ wdec14(i10, i11, p10, p11);
+ } else {
+ wdec16(*px, *p10, &i00, &i10);
+ wdec16(*p01, *p11, &i01, &i11);
+ wdec16(i00, i01, px, p01);
+ wdec16(i10, i11, p10, p11);
+ }
+ }
+
+ if (nx & p) {
+ uint16_t *p10 = px + oy1;
+
+ if (w14)
+ wdec14(*px, *p10, &i00, p10);
+ else
+ wdec16(*px, *p10, &i00, p10);
+
+ *px = i00;
+ }
+ }
+
+ if (ny & p) {
+ uint16_t *px = py;
+ uint16_t *ex = py + ox * (nx - p2);
+
+ for (; px <= ex; px += ox2) {
+ uint16_t *p01 = px + ox1;
+
+ if (w14)
+ wdec14(*px, *p01, &i00, p01);
+ else
+ wdec16(*px, *p01, &i00, p01);
+
+ *px = i00;
+ }
+ }
+
+ p2 = p;
+ p >>= 1;
+ }
+}
+
+static int piz_uncompress(EXRContext *s, const uint8_t *src, int ssize, int dsize, EXRThreadData *td)
+{
+ GetByteContext gb;
+ uint16_t maxval, min_non_zero, max_non_zero;
+ uint16_t *ptr, *tmp = (uint16_t *)td->tmp;
+ int8_t *out;
+ int ret, i, j;
+
+ if (!td->bitmap)
+ td->bitmap = av_malloc(BITMAP_SIZE);
+ if (!td->lut)
+ td->lut = av_malloc(1 << 17);
+ if (!td->bitmap || !td->lut)
+ return AVERROR(ENOMEM);
+
+ bytestream2_init(&gb, src, ssize);
+ min_non_zero = bytestream2_get_le16(&gb);
+ max_non_zero = bytestream2_get_le16(&gb);
+
+ if (max_non_zero >= BITMAP_SIZE)
+ return AVERROR_INVALIDDATA;
+
+ memset(td->bitmap, 0, FFMIN(min_non_zero, BITMAP_SIZE));
+ if (min_non_zero <= max_non_zero)
+ bytestream2_get_buffer(&gb, td->bitmap + min_non_zero,
+ max_non_zero - min_non_zero + 1);
+ memset(td->bitmap + max_non_zero, 0, BITMAP_SIZE - max_non_zero);
+
+ maxval = reverse_lut(td->bitmap, td->lut);
+
+ ret = huf_uncompress(&gb, tmp, dsize / sizeof(int16_t));
+ if (ret)
+ return ret;
+
+ ptr = tmp;
+ for (i = 0; i < s->nb_channels; i++) {
+ EXRChannel *channel = &s->channels[i];
+ int size = channel->pixel_type;
+
+ for (j = 0; j < size; j++)
+ wav_decode(ptr + j, s->xdelta, size, s->ysize, s->xdelta * size, maxval);
+ ptr += s->xdelta * s->ysize * size;
+ }
+
+ apply_lut(td->lut, tmp, dsize / sizeof(int16_t));
+
+ out = td->uncompressed_data;
+ for (i = 0; i < s->ysize; i++) {
+ for (j = 0; j < s->nb_channels; j++) {
+ uint16_t *in = tmp + j * s->xdelta * s->ysize + i * s->xdelta;
+ memcpy(out, in, s->xdelta * 2);
+ out += s->xdelta * 2;
+ }
+ }
+
+ return 0;
+}
+
static int pxr24_uncompress(EXRContext *s, const uint8_t *src,
int compressed_size, int uncompressed_size,
EXRThreadData *td)
@@ -385,6 +845,9 @@
case EXR_ZIP16:
ret = zip_uncompress(src, data_size, uncompressed_size, td);
break;
+ case EXR_PIZ:
+ ret = piz_uncompress(s, src, data_size, uncompressed_size, td);
+ break;
case EXR_PXR24:
ret = pxr24_uncompress(s, src, data_size, uncompressed_size, td);
break;
@@ -714,14 +1177,14 @@
case EXR_ZIP16:
s->scan_lines_per_block = 16;
break;
+ case EXR_PIZ:
+ s->scan_lines_per_block = 32;
+ break;
default:
avpriv_report_missing_feature(avctx, "Compression %d", s->compr);
return AVERROR_PATCHWELCOME;
}
- if (av_image_check_size(w, h, 0, avctx))
- return AVERROR_INVALIDDATA;
-
// Verify the xmin, xmax, ymin, ymax and xdelta before setting the actual image size
if (s->xmin > s->xmax ||
s->ymin > s->ymax ||
@@ -731,9 +1194,8 @@
return AVERROR_INVALIDDATA;
}
- if (w != avctx->width || h != avctx->height) {
- avcodec_set_dimensions(avctx, w, h);
- }
+ if ((ret = ff_set_dimensions(avctx, w, h)) < 0)
+ return ret;
s->desc = av_pix_fmt_desc_get(avctx->pix_fmt);
out_line_size = avctx->width * 2 * s->desc->nb_components;
@@ -791,8 +1253,10 @@
for (i = 0; i < s->thread_data_size / sizeof(EXRThreadData); i++) {
EXRThreadData *td = &s->thread_data[i];
- av_free(td->uncompressed_data);
- av_free(td->tmp);
+ av_freep(&td->uncompressed_data);
+ av_freep(&td->tmp);
+ av_freep(&td->bitmap);
+ av_freep(&td->lut);
}
av_freep(&s->thread_data);
diff --git a/libavcodec/fft-test.c b/libavcodec/fft-test.c
index eee8cb2..d650a10 100644
--- a/libavcodec/fft-test.c
+++ b/libavcodec/fft-test.c
@@ -37,6 +37,7 @@
#if HAVE_UNISTD_H
#include <unistd.h>
#endif
+#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -499,5 +500,8 @@
av_free(tab_ref);
av_free(exptab);
- return err;
+ if (err)
+ printf("Error: %d.\n", err);
+
+ return !!err;
}
diff --git a/libavcodec/fft_fixed.c b/libavcodec/fft_fixed.c
index 153b7d8..9e74b8c 100644
--- a/libavcodec/fft_fixed.c
+++ b/libavcodec/fft_fixed.c
@@ -18,4 +18,4 @@
#define CONFIG_FFT_FLOAT 0
#define CONFIG_FFT_FIXED_32 0
-#include "fft.c"
+#include "fft_template.c"
diff --git a/libavcodec/fft_fixed_32.c b/libavcodec/fft_fixed_32.c
index f2954d7..18e6da9 100644
--- a/libavcodec/fft_fixed_32.c
+++ b/libavcodec/fft_fixed_32.c
@@ -49,4 +49,4 @@
#define CONFIG_FFT_FLOAT 0
#define CONFIG_FFT_FIXED_32 1
-#include "fft.c"
+#include "fft_template.c"
diff --git a/libavcodec/fft_float.c b/libavcodec/fft_float.c
index 011dc45..93d3607 100644
--- a/libavcodec/fft_float.c
+++ b/libavcodec/fft_float.c
@@ -18,4 +18,4 @@
#define CONFIG_FFT_FLOAT 1
#define CONFIG_FFT_FIXED_32 0
-#include "fft.c"
+#include "fft_template.c"
diff --git a/libavcodec/fft.c b/libavcodec/fft_template.c
similarity index 100%
rename from libavcodec/fft.c
rename to libavcodec/fft_template.c
diff --git a/libavcodec/ffv1.c b/libavcodec/ffv1.c
index 9f3206f..f8556b0 100644
--- a/libavcodec/ffv1.c
+++ b/libavcodec/ffv1.c
@@ -49,10 +49,11 @@
s->avctx = avctx;
s->flags = avctx->flags;
- s->picture.f = avcodec_alloc_frame();
+ s->picture.f = av_frame_alloc();
s->last_picture.f = av_frame_alloc();
if (!s->picture.f || !s->last_picture.f)
return AVERROR(ENOMEM);
+
ff_dsputil_init(&s->dsp, avctx);
s->width = avctx->width;
diff --git a/libavcodec/ffv1.h b/libavcodec/ffv1.h
index bdc7b86..2c3e6e4 100644
--- a/libavcodec/ffv1.h
+++ b/libavcodec/ffv1.h
@@ -130,6 +130,7 @@
int slice_y;
int slice_reset_contexts;
int slice_coding_mode;
+ int slice_rct_y_coef;
} FFV1Context;
int ffv1_common_init(AVCodecContext *avctx);
diff --git a/libavcodec/ffv1dec.c b/libavcodec/ffv1dec.c
index 0add4ff..6c01ebf 100644
--- a/libavcodec/ffv1dec.c
+++ b/libavcodec/ffv1dec.c
@@ -260,7 +260,7 @@
if (s->slice_coding_mode != 1) {
b -= offset;
r -= offset;
- g -= (b + r) >> 2;
+ g -= ((b + r) * s->slice_rct_y_coef) >> 2;
b += g;
r += g;
}
@@ -333,6 +333,13 @@
if (fs->version > 3) {
fs->slice_reset_contexts = get_rac(c, state);
fs->slice_coding_mode = get_symbol(c, state, 0);
+ if (fs->slice_coding_mode != 1) {
+ fs->slice_rct_y_coef = get_symbol(c, state, 0);
+ if (fs->slice_rct_y_coef > 2U) {
+ av_log(f->avctx, AV_LOG_ERROR, "slice_rct_y_coef out of range\n");
+ return AVERROR_INVALIDDATA;
+ }
+ }
}
return 0;
}
@@ -381,6 +388,8 @@
}
}
+ fs->slice_rct_y_coef = 1;
+
if (f->version > 2) {
if (ffv1_init_slice_state(f, fs) < 0)
return AVERROR(ENOMEM);
@@ -938,12 +947,12 @@
uint8_t *dst[4];
ff_thread_await_progress(&f->last_picture, INT_MAX, 0);
for (j = 0; j < 4; j++) {
- int sh = (j==1 || j==2) ? f->chroma_h_shift : 0;
- int sv = (j==1 || j==2) ? f->chroma_v_shift : 0;
- dst[j] = p->data[j] + p->linesize[j]*
- (fs->slice_y>>sv) + (fs->slice_x>>sh);
- src[j] = f->last_picture.f->data[j] + f->last_picture.f->linesize[j]*
- (fs->slice_y>>sv) + (fs->slice_x>>sh);
+ int sh = (j == 1 || j == 2) ? f->chroma_h_shift : 0;
+ int sv = (j == 1 || j == 2) ? f->chroma_v_shift : 0;
+ dst[j] = p->data[j] + p->linesize[j] *
+ (fs->slice_y >> sv) + (fs->slice_x >> sh);
+ src[j] = f->last_picture.f->data[j] + f->last_picture.f->linesize[j] *
+ (fs->slice_y >> sv) + (fs->slice_x >> sh);
}
av_image_copy(dst, p->linesize, (const uint8_t **)src,
f->last_picture.f->linesize,
diff --git a/libavcodec/ffv1enc.c b/libavcodec/ffv1enc.c
index d3eb118..25a69bf 100644
--- a/libavcodec/ffv1enc.c
+++ b/libavcodec/ffv1enc.c
@@ -441,7 +441,7 @@
if (s->slice_coding_mode != 1) {
b -= g;
r -= g;
- g += (b + r) >> 2;
+ g += ((b + r) * s->slice_rct_y_coef) >> 2;
b += offset;
r += offset;
}
@@ -557,8 +557,10 @@
put_symbol(c, state, f->version, 0);
if (f->version > 2) {
- if (f->version == 3)
+ if (f->version == 3) {
f->micro_version = 4;
+ } else if (f->version == 4)
+ f->micro_version = 1;
put_symbol(c, state, f->micro_version, 0);
}
@@ -672,9 +674,11 @@
if ((avctx->flags & (CODEC_FLAG_PASS1|CODEC_FLAG_PASS2)) || avctx->slices>1)
s->version = FFMAX(s->version, 2);
- if (avctx->level == 3 || (avctx->level <= 0 && s->version == 2)) {
+ if (avctx->level <= 0 && s->version == 2) {
s->version = 3;
}
+ if (avctx->level >= 0 && avctx->level <= 4)
+ s->version = FFMAX(s->version, avctx->level);
if (s->ec < 0) {
s->ec = (s->version >= 3);
@@ -771,6 +775,10 @@
s->colorspace = 1;
s->chroma_planes = 1;
s->version = FFMAX(s->version, 1);
+ if (!s->ac) {
+ av_log(avctx, AV_LOG_ERROR, "bits_per_raw_sample of more than 8 needs -coder 1 currently\n");
+ return AVERROR(ENOSYS);
+ }
break;
default:
av_log(avctx, AV_LOG_ERROR, "format not supported\n");
@@ -826,6 +834,12 @@
if ((ret = ffv1_allocate_initial_states(s)) < 0)
return ret;
+ avctx->coded_frame = av_frame_alloc();
+ if (!avctx->coded_frame)
+ return AVERROR(ENOMEM);
+
+ avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
+
if (!s->transparency)
s->plane_count = 2;
if (!s->chroma_planes && s->version > 3)
@@ -985,9 +999,71 @@
if (fs->slice_coding_mode == 1)
ffv1_clear_slice_state(f, fs);
put_symbol(c, state, fs->slice_coding_mode, 0);
+ if (fs->slice_coding_mode != 1)
+ put_symbol(c, state, fs->slice_rct_y_coef, 0);
}
}
+static void choose_rct_params(FFV1Context *fs, uint8_t *src[3], const int stride[3], int w, int h)
+{
+ int stat[3] = {0};
+ int x, y, i, p, best;
+ int16_t *sample[3];
+ int lbd = fs->bits_per_raw_sample <= 8;
+
+ for (y = 0; y < h; y++) {
+ int lastr=0, lastg=0, lastb=0;
+ for (p = 0; p < 3; p++)
+ sample[p] = fs->sample_buffer + p*w;
+
+ for (x = 0; x < w; x++) {
+ int b, g, r;
+ if (lbd) {
+ unsigned v = *((uint32_t*)(src[0] + x*4 + stride[0]*y));
+ b = v & 0xFF;
+ g = (v >> 8) & 0xFF;
+ r = (v >> 16) & 0xFF;
+ } else {
+ b = *((uint16_t*)(src[0] + x*2 + stride[0]*y));
+ g = *((uint16_t*)(src[1] + x*2 + stride[1]*y));
+ r = *((uint16_t*)(src[2] + x*2 + stride[2]*y));
+ }
+
+ if (x && y) {
+ int ar = r - lastr;
+ int ag = g - lastg;
+ int ab = b - lastb;
+ int bg = ag - sample[0][x];
+ int bb = ab - sample[1][x];
+ int br = ar - sample[2][x];
+
+ br -= bg;
+ bb -= bg;
+
+ stat[0] += FFABS(bg);
+ stat[1] += FFABS(bg + ((br+bb)>>2));
+ stat[2] += FFABS(bg + ((br+bb)>>1));
+
+ sample[0][x] = ag;
+ sample[1][x] = ab;
+ sample[2][x] = ar;
+ }
+
+ lastr = r;
+ lastg = g;
+ lastb = b;
+ }
+ }
+
+ best = 0;
+ for (i=1; i<=2; i++) {
+ if (stat[i] < stat[best])
+ best = i;
+ }
+
+ fs->slice_rct_y_coef = best;
+}
+
static int encode_slice(AVCodecContext *c, void *arg)
{
FFV1Context *fs = *(void **)arg;
@@ -996,15 +1072,23 @@
int height = fs->slice_height;
int x = fs->slice_x;
int y = fs->slice_y;
- AVFrame *const p = f->picture.f;
+ const AVFrame *const p = f->picture.f;
const int ps = av_pix_fmt_desc_get(c->pix_fmt)->comp[0].step_minus1 + 1;
int ret;
RangeCoder c_bak = fs->c;
+ uint8_t *planes[3] = {p->data[0] + ps*x + y*p->linesize[0],
+ p->data[1] + ps*x + y*p->linesize[1],
+ p->data[2] + ps*x + y*p->linesize[2]};
fs->slice_coding_mode = 0;
+ if (f->version > 3) {
+ choose_rct_params(fs, planes, p->linesize, width, height);
+ } else {
+ fs->slice_rct_y_coef = 1;
+ }
retry:
- if (p->key_frame)
+ if (c->coded_frame->key_frame)
ffv1_clear_slice_state(f, fs);
if (f->version > 2) {
encode_slice_header(f, fs);
@@ -1033,9 +1117,6 @@
if (fs->transparency)
ret |= encode_plane(fs, p->data[3] + ps*x + y*p->linesize[3], width, height, p->linesize[3], 2);
} else {
- uint8_t *planes[3] = {p->data[0] + ps*x + y*p->linesize[0],
- p->data[1] + ps*x + y*p->linesize[1],
- p->data[2] + ps*x + y*p->linesize[2]};
ret = encode_rgb_frame(fs, planes, width, height, p->linesize);
}
emms_c();
@@ -1068,8 +1149,53 @@
int64_t maxsize = FF_MIN_BUFFER_SIZE
+ avctx->width*avctx->height*35LL*4;
+ if(!pict) {
+ if (avctx->flags & CODEC_FLAG_PASS1) {
+ int j, k, m;
+ char *p = avctx->stats_out;
+ char *end = p + STATS_OUT_SIZE;
+
+ memset(f->rc_stat, 0, sizeof(f->rc_stat));
+ for (i = 0; i < f->quant_table_count; i++)
+ memset(f->rc_stat2[i], 0, f->context_count[i] * sizeof(*f->rc_stat2[i]));
+
+ for (j = 0; j < f->slice_count; j++) {
+ FFV1Context *fs = f->slice_context[j];
+ for (i = 0; i < 256; i++) {
+ f->rc_stat[i][0] += fs->rc_stat[i][0];
+ f->rc_stat[i][1] += fs->rc_stat[i][1];
+ }
+ for (i = 0; i < f->quant_table_count; i++) {
+ for (k = 0; k < f->context_count[i]; k++)
+ for (m = 0; m < 32; m++) {
+ f->rc_stat2[i][k][m][0] += fs->rc_stat2[i][k][m][0];
+ f->rc_stat2[i][k][m][1] += fs->rc_stat2[i][k][m][1];
+ }
+ }
+ }
+
+ for (j = 0; j < 256; j++) {
+ snprintf(p, end - p, "%" PRIu64 " %" PRIu64 " ",
+ f->rc_stat[j][0], f->rc_stat[j][1]);
+ p += strlen(p);
+ }
+ snprintf(p, end - p, "\n");
+
+ for (i = 0; i < f->quant_table_count; i++) {
+ for (j = 0; j < f->context_count[i]; j++)
+ for (m = 0; m < 32; m++) {
+ snprintf(p, end - p, "%" PRIu64 " %" PRIu64 " ",
+ f->rc_stat2[i][j][m][0], f->rc_stat2[i][j][m][1]);
+ p += strlen(p);
+ }
+ }
+ snprintf(p, end - p, "%d\n", f->gob_count);
+ }
+ return 0;
+ }
+
if (f->version > 3)
- maxsize = FF_MIN_BUFFER_SIZE + avctx->width*avctx->height*3*4;
+ maxsize = FF_MIN_BUFFER_SIZE + avctx->width*avctx->height*3LL*4;
if ((ret = ff_alloc_packet2(avctx, pkt, maxsize)) < 0)
return ret;
@@ -1080,16 +1206,16 @@
av_frame_unref(p);
if ((ret = av_frame_ref(p, pict)) < 0)
return ret;
- p->pict_type = AV_PICTURE_TYPE_I;
+ avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
if (avctx->gop_size == 0 || f->picture_number % avctx->gop_size == 0) {
put_rac(c, &keystate, 1);
- p->key_frame = 1;
+ avctx->coded_frame->key_frame = 1;
f->gob_count++;
write_header(f);
} else {
put_rac(c, &keystate, 0);
- p->key_frame = 0;
+ avctx->coded_frame->key_frame = 0;
}
if (f->ac > 1) {
@@ -1139,57 +1265,26 @@
buf_p += bytes;
}
- if ((avctx->flags & CODEC_FLAG_PASS1) && (f->picture_number & 31) == 0) {
- int j, k, m;
- char *p = avctx->stats_out;
- char *end = p + STATS_OUT_SIZE;
-
- memset(f->rc_stat, 0, sizeof(f->rc_stat));
- for (i = 0; i < f->quant_table_count; i++)
- memset(f->rc_stat2[i], 0, f->context_count[i] * sizeof(*f->rc_stat2[i]));
-
- for (j = 0; j < f->slice_count; j++) {
- FFV1Context *fs = f->slice_context[j];
- for (i = 0; i < 256; i++) {
- f->rc_stat[i][0] += fs->rc_stat[i][0];
- f->rc_stat[i][1] += fs->rc_stat[i][1];
- }
- for (i = 0; i < f->quant_table_count; i++) {
- for (k = 0; k < f->context_count[i]; k++)
- for (m = 0; m < 32; m++) {
- f->rc_stat2[i][k][m][0] += fs->rc_stat2[i][k][m][0];
- f->rc_stat2[i][k][m][1] += fs->rc_stat2[i][k][m][1];
- }
- }
- }
-
- for (j = 0; j < 256; j++) {
- snprintf(p, end - p, "%" PRIu64 " %" PRIu64 " ",
- f->rc_stat[j][0], f->rc_stat[j][1]);
- p += strlen(p);
- }
- snprintf(p, end - p, "\n");
-
- for (i = 0; i < f->quant_table_count; i++) {
- for (j = 0; j < f->context_count[i]; j++)
- for (m = 0; m < 32; m++) {
- snprintf(p, end - p, "%" PRIu64 " %" PRIu64 " ",
- f->rc_stat2[i][j][m][0], f->rc_stat2[i][j][m][1]);
- p += strlen(p);
- }
- }
- snprintf(p, end - p, "%d\n", f->gob_count);
- } else if (avctx->flags & CODEC_FLAG_PASS1)
+ if (avctx->flags & CODEC_FLAG_PASS1)
avctx->stats_out[0] = '\0';
f->picture_number++;
pkt->size = buf_p - pkt->data;
- pkt->flags |= AV_PKT_FLAG_KEY * p->key_frame;
+ pkt->pts =
+ pkt->dts = pict->pts;
+ pkt->flags |= AV_PKT_FLAG_KEY * avctx->coded_frame->key_frame;
*got_packet = 1;
return 0;
}
+static av_cold int encode_close(AVCodecContext *avctx)
+{
+ av_frame_free(&avctx->coded_frame);
+ ffv1_close(avctx);
+ return 0;
+}
+
#define OFFSET(x) offsetof(FFV1Context, x)
#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
static const AVOption options[] = {
@@ -1217,8 +1312,8 @@
.priv_data_size = sizeof(FFV1Context),
.init = encode_init,
.encode2 = encode_frame,
- .close = ffv1_close,
- .capabilities = CODEC_CAP_SLICE_THREADS,
+ .close = encode_close,
+ .capabilities = CODEC_CAP_SLICE_THREADS | CODEC_CAP_DELAY,
.pix_fmts = (const enum AVPixelFormat[]) {
AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUVA420P, AV_PIX_FMT_YUVA422P, AV_PIX_FMT_YUV444P,
AV_PIX_FMT_YUVA444P, AV_PIX_FMT_YUV440P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV411P,
diff --git a/libavcodec/flacdec.c b/libavcodec/flacdec.c
index 85f5202..596b24d 100644
--- a/libavcodec/flacdec.c
+++ b/libavcodec/flacdec.c
@@ -45,6 +45,8 @@
#include "flacdata.h"
#include "flacdsp.h"
#include "thread.h"
+#include "unary.h"
+
typedef struct FLACContext {
FLACSTREAMINFO
@@ -357,7 +359,6 @@
if (get_bits1(&s->gb)) {
int left = get_bits_left(&s->gb);
- wasted = 1;
if ( left < 0 ||
(left < bps && !show_bits_long(&s->gb, left)) ||
!show_bits_long(&s->gb, bps)) {
@@ -366,8 +367,7 @@
bps, left);
return AVERROR_INVALIDDATA;
}
- while (!get_bits1(&s->gb))
- wasted++;
+ wasted = 1 + get_unary(&s->gb, 1, get_bits_left(&s->gb));
bps -= wasted;
}
if (bps > 32) {
@@ -539,7 +539,7 @@
}
bytes_read = get_bits_count(&s->gb)/8;
- if ((s->avctx->err_recognition & AV_EF_CRCCHECK) &&
+ if ((s->avctx->err_recognition & (AV_EF_CRCCHECK|AV_EF_COMPLIANT)) &&
av_crc(av_crc_get_table(AV_CRC_16_ANSI),
0, buf, bytes_read)) {
av_log(s->avctx, AV_LOG_ERROR, "CRC error at PTS %"PRId64"\n", avpkt->pts);
diff --git a/libavcodec/flashsv.c b/libavcodec/flashsv.c
index 3d185d5..981d774 100644
--- a/libavcodec/flashsv.c
+++ b/libavcodec/flashsv.c
@@ -50,7 +50,7 @@
typedef struct FlashSVContext {
AVCodecContext *avctx;
- AVFrame frame;
+ AVFrame *frame;
int image_width, image_height;
int block_width, block_height;
uint8_t *tmpblock;
@@ -69,14 +69,13 @@
int diff_start, diff_height;
} FlashSVContext;
-
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 x, y;
const uint8_t *orig_src = sptr;
- for (y = dx+h; y > dx; y--) {
+ for (y = dx + h; y > dx; y--) {
uint8_t *dst = dptr + (y * stride) + dy * 3;
for (x = 0; x < w; x++) {
if (*sptr & 0x80) {
@@ -100,6 +99,19 @@
return sptr - orig_src;
}
+static av_cold int flashsv_decode_end(AVCodecContext *avctx)
+{
+ FlashSVContext *s = avctx->priv_data;
+ inflateEnd(&s->zstream);
+ /* release the frame if needed */
+ av_frame_free(&s->frame);
+
+ /* free the tmpblock */
+ av_freep(&s->tmpblock);
+
+ return 0;
+}
+
static av_cold int flashsv_decode_init(AVCodecContext *avctx)
{
FlashSVContext *s = avctx->priv_data;
@@ -115,12 +127,16 @@
return 1;
}
avctx->pix_fmt = AV_PIX_FMT_BGR24;
- avcodec_get_frame_defaults(&s->frame);
+
+ s->frame = av_frame_alloc();
+ if (!s->frame) {
+ flashsv_decode_end(avctx);
+ return AVERROR(ENOMEM);
+ }
return 0;
}
-
static int flashsv2_prime(FlashSVContext *s, uint8_t *src, int size)
{
z_stream zs;
@@ -198,25 +214,28 @@
}
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].pos = s->keyframedata + (get_bits_count(gb) / 8);
+ s->blocks[blk_idx].size = block_size;
}
+
+ y_pos += s->diff_start;
+
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],
+ memcpy(s->frame->data[0] + x_pos * 3 +
+ (s->image_height - y_pos - 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),
+ decode_hybrid(s->tmpblock, s->frame->data[0],
+ s->image_height - (y_pos + 1 + s->diff_height),
x_pos, s->diff_height, width,
- s->frame.linesize[0], s->pal);
+ s->frame->linesize[0], s->pal);
}
skip_bits_long(gb, 8 * block_size); /* skip the consumed bits */
return 0;
@@ -241,8 +260,8 @@
static int flashsv_decode_frame(AVCodecContext *avctx, void *data,
int *got_frame, AVPacket *avpkt)
{
- int buf_size = avpkt->size;
- FlashSVContext *s = avctx->priv_data;
+ int buf_size = avpkt->size;
+ FlashSVContext *s = avctx->priv_data;
int h_blocks, v_blocks, h_part, v_part, i, j, ret;
GetBitContext gb;
int last_blockwidth = s->block_width;
@@ -254,13 +273,14 @@
if (buf_size < 4)
return -1;
- init_get_bits(&gb, avpkt->data, buf_size * 8);
+ if ((ret = init_get_bits8(&gb, avpkt->data, buf_size)) < 0)
+ return ret;
/* start to parse the bitstream */
- s->block_width = 16 * (get_bits(&gb, 4) + 1);
- s->image_width = get_bits(&gb, 12);
- s->block_height = 16 * (get_bits(&gb, 4) + 1);
- s->image_height = get_bits(&gb, 12);
+ s->block_width = 16 * (get_bits(&gb, 4) + 1);
+ s->image_width = get_bits(&gb, 12);
+ s->block_height = 16 * (get_bits(&gb, 4) + 1);
+ s->image_height = get_bits(&gb, 12);
if ( last_blockwidth != s->block_width
|| last_blockheight!= s->block_height)
@@ -287,23 +307,25 @@
/* 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) {
- int tmpblock_size = 3 * s->block_width * s->block_height;
+ int tmpblock_size = 3 * s->block_width * s->block_height, err;
- 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 ((err = av_reallocp(&s->tmpblock, tmpblock_size)) < 0) {
+ s->block_size = 0;
+ av_log(avctx, AV_LOG_ERROR,
+ "Cannot allocate decompression buffer.\n");
+ return err;
}
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");
+ av_log(avctx, AV_LOG_ERROR,
+ "Cannot 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);
+ if ((err = av_reallocp(&s->deflate_block, s->deflate_block_size)) < 0) {
+ s->block_size = 0;
+ av_log(avctx, AV_LOG_ERROR, "Cannot allocate deflate buffer.\n");
+ return err;
}
}
}
@@ -311,7 +333,8 @@
/* initialize the image size once */
if (avctx->width == 0 && avctx->height == 0) {
- avcodec_set_dimensions(avctx, s->image_width, s->image_height);
+ if ((ret = ff_set_dimensions(avctx, s->image_width, s->image_height)) < 0)
+ return ret;
}
/* check for changes of image width and image height */
@@ -326,18 +349,20 @@
/* 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);
+ int err;
+ if ((err = av_reallocp(&s->keyframedata, avpkt->size)) < 0)
+ return err;
memcpy(s->keyframedata, avpkt->data, avpkt->size);
}
if(s->ver == 2 && !s->blocks)
- s->blocks = av_mallocz((v_blocks + !!v_part) * (h_blocks + !!h_part)
- * sizeof(s->blocks[0]));
+ s->blocks = av_mallocz((v_blocks + !!v_part) * (h_blocks + !!h_part) *
+ sizeof(s->blocks[0]));
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);
- if ((ret = ff_reget_buffer(avctx, &s->frame)) < 0)
+ if ((ret = ff_reget_buffer(avctx, s->frame)) < 0)
return ret;
/* loop over all block columns */
@@ -362,7 +387,7 @@
s->diff_height = cur_blk_height;
if (8 * size > get_bits_left(&gb)) {
- av_frame_unref(&s->frame);
+ av_frame_unref(s->frame);
return AVERROR_INVALIDDATA;
}
@@ -375,20 +400,23 @@
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);
+ "%dx%d invalid color depth %d\n",
+ i, j, s->color_depth);
return AVERROR_INVALIDDATA;
}
if (has_diff) {
if (!s->keyframe) {
av_log(avctx, AV_LOG_ERROR,
- "inter frame without keyframe\n");
+ "Inter frame without keyframe\n");
return AVERROR_INVALIDDATA;
}
s->diff_start = get_bits(&gb, 8);
s->diff_height = get_bits(&gb, 8);
if (s->diff_start + s->diff_height > cur_blk_height) {
- av_log(avctx, AV_LOG_ERROR, "Block parameters invalid\n");
+ av_log(avctx, AV_LOG_ERROR,
+ "Block parameters invalid: %d + %d > %d\n",
+ s->diff_start, s->diff_height, cur_blk_height);
return AVERROR_INVALIDDATA;
}
av_log(avctx, AV_LOG_DEBUG,
@@ -403,14 +431,15 @@
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);
+ av_log(avctx, AV_LOG_DEBUG, "%dx%d zlibprime_curr %dx%d\n",
+ i, j, col, row);
size -= 2;
avpriv_request_sample(avctx, "zlibprime_curr");
return AVERROR_PATCHWELCOME;
}
if (!s->blocks && (s->zlibprime_curr || s->zlibprime_prev)) {
- av_log(avctx, AV_LOG_ERROR, "no data available for zlib "
- "priming\n");
+ av_log(avctx, AV_LOG_ERROR,
+ "no data available for zlib priming\n");
return AVERROR_INVALIDDATA;
}
size--; // account for flags byte
@@ -418,12 +447,13 @@
if (has_diff) {
int k;
- int off = (s->image_height - y_pos - 1) * s->frame.linesize[0];
+ 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,
+ for (k = 0; k < cur_blk_height; k++) {
+ int x = off - k * s->frame->linesize[0] + x_pos * 3;
+ memcpy(s->frame->data[0] + x, s->keyframe + x,
cur_blk_width * 3);
+ }
}
/* skip unchanged blocks, which have size 0 */
@@ -439,16 +469,17 @@
}
if (s->is_keyframe && s->ver == 2) {
if (!s->keyframe) {
- s->keyframe = av_malloc(s->frame.linesize[0] * avctx->height);
+ 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);
+ memcpy(s->keyframe, s->frame->data[0],
+ s->frame->linesize[0] * avctx->height);
}
- if ((ret = av_frame_ref(data, &s->frame)) < 0)
+ if ((ret = av_frame_ref(data, s->frame)) < 0)
return ret;
*got_frame = 1;
@@ -461,21 +492,6 @@
return buf_size;
}
-
-static av_cold int flashsv_decode_end(AVCodecContext *avctx)
-{
- FlashSVContext *s = avctx->priv_data;
- inflateEnd(&s->zstream);
- /* release the frame if needed */
- av_frame_unref(&s->frame);
-
- /* free the tmpblock */
- av_free(s->tmpblock);
-
- return 0;
-}
-
-
#if CONFIG_FLASHSV_DECODER
AVCodec ff_flashsv_decoder = {
.name = "flashsv",
@@ -487,7 +503,7 @@
.close = flashsv_decode_end,
.decode = flashsv_decode_frame,
.capabilities = CODEC_CAP_DR1,
- .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_BGR24, AV_PIX_FMT_NONE },
+ .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_BGR24, AV_PIX_FMT_NONE },
};
#endif /* CONFIG_FLASHSV_DECODER */
@@ -550,6 +566,6 @@
.close = flashsv2_decode_end,
.decode = flashsv_decode_frame,
.capabilities = CODEC_CAP_DR1,
- .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_BGR24, AV_PIX_FMT_NONE },
+ .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_BGR24, AV_PIX_FMT_NONE },
};
#endif /* CONFIG_FLASHSV2_DECODER */
diff --git a/libavcodec/flashsvenc.c b/libavcodec/flashsvenc.c
index ee67652..7ad15f1 100644
--- a/libavcodec/flashsvenc.c
+++ b/libavcodec/flashsvenc.c
@@ -57,7 +57,6 @@
typedef struct FlashSVContext {
AVCodecContext *avctx;
uint8_t *previous_frame;
- AVFrame frame;
int image_width, image_height;
int block_width, block_height;
uint8_t *tmpblock;
@@ -89,6 +88,21 @@
return 0;
}
+static av_cold int flashsv_encode_end(AVCodecContext *avctx)
+{
+ FlashSVContext *s = avctx->priv_data;
+
+ deflateEnd(&s->zstream);
+
+ av_free(s->encbuffer);
+ av_free(s->previous_frame);
+ av_free(s->tmpblock);
+
+ av_frame_free(&avctx->coded_frame);
+
+ return 0;
+}
+
static av_cold int flashsv_encode_init(AVCodecContext *avctx)
{
FlashSVContext *s = avctx->priv_data;
@@ -117,11 +131,17 @@
return AVERROR(ENOMEM);
}
+ avctx->coded_frame = av_frame_alloc();
+ if (!avctx->coded_frame) {
+ flashsv_encode_end(avctx);
+ return AVERROR(ENOMEM);
+ }
+
return 0;
}
-static int encode_bitstream(FlashSVContext *s, AVFrame *p, uint8_t *buf,
+static int encode_bitstream(FlashSVContext *s, const AVFrame *p, uint8_t *buf,
int buf_size, int block_width, int block_height,
uint8_t *previous_frame, int *I_frame)
{
@@ -199,14 +219,12 @@
const AVFrame *pict, int *got_packet)
{
FlashSVContext * const s = avctx->priv_data;
- AVFrame * const p = &s->frame;
+ const AVFrame * const p = pict;
uint8_t *pfptr;
int res;
int I_frame = 0;
int opt_w = 4, opt_h = 4;
- *p = *pict;
-
/* First frame needs to be a keyframe */
if (avctx->frame_number == 0) {
s->previous_frame = av_mallocz(FFABS(p->linesize[0]) * s->image_height);
@@ -244,37 +262,22 @@
//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;
+ avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
+ avctx->coded_frame->key_frame = 1;
s->last_key_frame = 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;
+ avctx->coded_frame->pict_type = AV_PICTURE_TYPE_P;
+ avctx->coded_frame->key_frame = 0;
}
- avctx->coded_frame = p;
-
- if (p->key_frame)
+ if (avctx->coded_frame->key_frame)
pkt->flags |= AV_PKT_FLAG_KEY;
*got_packet = 1;
return 0;
}
-static av_cold int flashsv_encode_end(AVCodecContext *avctx)
-{
- FlashSVContext *s = avctx->priv_data;
-
- deflateEnd(&s->zstream);
-
- av_free(s->encbuffer);
- av_free(s->previous_frame);
- av_free(s->tmpblock);
-
- return 0;
-}
-
AVCodec ff_flashsv_encoder = {
.name = "flashsv",
.long_name = NULL_IF_CONFIG_SMALL("Flash Screen Video"),
diff --git a/libavcodec/flicvideo.c b/libavcodec/flicvideo.c
index 35b3b60..a2d59e8 100644
--- a/libavcodec/flicvideo.c
+++ b/libavcodec/flicvideo.c
@@ -71,7 +71,7 @@
typedef struct FlicDecodeContext {
AVCodecContext *avctx;
- AVFrame frame;
+ AVFrame *frame;
unsigned int palette[256];
int new_palette;
@@ -134,14 +134,17 @@
case 15 : avctx->pix_fmt = AV_PIX_FMT_RGB555; break;
case 16 : avctx->pix_fmt = AV_PIX_FMT_RGB565; break;
case 24 : avctx->pix_fmt = AV_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");
+ avpriv_request_sample(avctx, "24Bpp FLC/FLX");
return AVERROR_PATCHWELCOME;
default :
av_log(avctx, AV_LOG_ERROR, "Unknown FLC/FLX depth of %d Bpp is unsupported.\n",depth);
return AVERROR_INVALIDDATA;
}
- avcodec_get_frame_defaults(&s->frame);
+ s->frame = av_frame_alloc();
+ if (!s->frame)
+ return AVERROR(ENOMEM);
+
s->new_palette = 0;
return 0;
@@ -185,11 +188,11 @@
bytestream2_init(&g2, buf, buf_size);
- if ((ret = ff_reget_buffer(avctx, &s->frame)) < 0)
+ if ((ret = ff_reget_buffer(avctx, s->frame)) < 0)
return ret;
- pixels = s->frame.data[0];
- pixel_limit = s->avctx->height * s->frame.linesize[0];
+ pixels = s->frame->data[0];
+ pixel_limit = s->avctx->height * s->frame->linesize[0];
if (buf_size < 16 || buf_size > INT_MAX - (3 * 256 + FF_INPUT_BUFFER_PADDING_SIZE))
return AVERROR_INVALIDDATA;
frame_size = bytestream2_get_le32(&g2);
@@ -273,12 +276,12 @@
if ((line_packets & 0xC000) == 0xC000) {
// line skip opcode
line_packets = -line_packets;
- y_ptr += line_packets * s->frame.linesize[0];
+ y_ptr += line_packets * s->frame->linesize[0];
} else if ((line_packets & 0xC000) == 0x4000) {
av_log(avctx, AV_LOG_ERROR, "Undefined opcode (%x) in DELTA_FLI\n", line_packets);
} else if ((line_packets & 0xC000) == 0x8000) {
// "last byte" opcode
- pixel_ptr= y_ptr + s->frame.linesize[0] - 1;
+ pixel_ptr= y_ptr + s->frame->linesize[0] - 1;
CHECK_PIXEL_PTR(0);
pixels[pixel_ptr] = line_packets & 0xff;
} else {
@@ -313,7 +316,7 @@
}
}
- y_ptr += s->frame.linesize[0];
+ y_ptr += s->frame->linesize[0];
}
}
break;
@@ -322,7 +325,7 @@
/* line compressed */
starting_line = bytestream2_get_le16(&g2);
y_ptr = 0;
- y_ptr += starting_line * s->frame.linesize[0];
+ y_ptr += starting_line * s->frame->linesize[0];
compressed_lines = bytestream2_get_le16(&g2);
while (compressed_lines > 0) {
@@ -359,7 +362,7 @@
}
}
- y_ptr += s->frame.linesize[0];
+ y_ptr += s->frame->linesize[0];
compressed_lines--;
}
break;
@@ -367,7 +370,7 @@
case FLI_BLACK:
/* set the whole frame to color 0 (which is usually black) */
memset(pixels, 0,
- s->frame.linesize[0] * s->avctx->height);
+ s->frame->linesize[0] * s->avctx->height);
break;
case FLI_BRUN:
@@ -414,7 +417,7 @@
}
}
- y_ptr += s->frame.linesize[0];
+ y_ptr += s->frame->linesize[0];
}
break;
@@ -425,8 +428,8 @@
"has incorrect size, skipping chunk\n", chunk_size - 6);
bytestream2_skip(&g2, chunk_size - 6);
} else {
- for (y_ptr = 0; y_ptr < s->frame.linesize[0] * s->avctx->height;
- y_ptr += s->frame.linesize[0]) {
+ for (y_ptr = 0; y_ptr < s->frame->linesize[0] * s->avctx->height;
+ y_ptr += s->frame->linesize[0]) {
bytestream2_get_buffer(&g2, &pixels[y_ptr],
s->avctx->width);
}
@@ -457,13 +460,13 @@
buf_size - bytestream2_get_bytes_left(&g2));
/* make the palette available on the way out */
- memcpy(s->frame.data[1], s->palette, AVPALETTE_SIZE);
+ memcpy(s->frame->data[1], s->palette, AVPALETTE_SIZE);
if (s->new_palette) {
- s->frame.palette_has_changed = 1;
+ s->frame->palette_has_changed = 1;
s->new_palette = 0;
}
- if ((ret = av_frame_ref(data, &s->frame)) < 0)
+ if ((ret = av_frame_ref(data, s->frame)) < 0)
return ret;
*got_frame = 1;
@@ -504,11 +507,11 @@
bytestream2_init(&g2, buf, buf_size);
- if ((ret = ff_reget_buffer(avctx, &s->frame)) < 0)
+ if ((ret = ff_reget_buffer(avctx, s->frame)) < 0)
return ret;
- pixels = s->frame.data[0];
- pixel_limit = s->avctx->height * s->frame.linesize[0];
+ pixels = s->frame->data[0];
+ pixel_limit = s->avctx->height * s->frame->linesize[0];
frame_size = bytestream2_get_le32(&g2);
bytestream2_skip(&g2, 2); /* skip the magic number */
@@ -556,7 +559,7 @@
line_packets = bytestream2_get_le16(&g2);
if (line_packets < 0) {
line_packets = -line_packets;
- y_ptr += line_packets * s->frame.linesize[0];
+ y_ptr += line_packets * s->frame->linesize[0];
} else {
compressed_lines--;
pixel_ptr = y_ptr;
@@ -589,7 +592,7 @@
}
}
- y_ptr += s->frame.linesize[0];
+ y_ptr += s->frame->linesize[0];
}
}
break;
@@ -602,7 +605,7 @@
case FLI_BLACK:
/* set the whole frame to 0x0000 which is black in both 15Bpp and 16Bpp modes. */
memset(pixels, 0x0000,
- s->frame.linesize[0] * s->avctx->height);
+ s->frame->linesize[0] * s->avctx->height);
break;
case FLI_BRUN:
@@ -657,7 +660,7 @@
pixel_ptr += 2;
}
#endif
- y_ptr += s->frame.linesize[0];
+ y_ptr += s->frame->linesize[0];
}
break;
@@ -701,7 +704,7 @@
}
}
- y_ptr += s->frame.linesize[0];
+ y_ptr += s->frame->linesize[0];
}
break;
@@ -714,8 +717,8 @@
bytestream2_skip(&g2, chunk_size - 6);
} else {
- for (y_ptr = 0; y_ptr < s->frame.linesize[0] * s->avctx->height;
- y_ptr += s->frame.linesize[0]) {
+ for (y_ptr = 0; y_ptr < s->frame->linesize[0] * s->avctx->height;
+ y_ptr += s->frame->linesize[0]) {
pixel_countdown = s->avctx->width;
pixel_ptr = 0;
@@ -748,7 +751,7 @@
av_log(avctx, AV_LOG_ERROR, "Processed FLI chunk where chunk size = %d " \
"and final chunk ptr = %d\n", buf_size, bytestream2_tell(&g2));
- if ((ret = av_frame_ref(data, &s->frame)) < 0)
+ if ((ret = av_frame_ref(data, s->frame)) < 0)
return ret;
*got_frame = 1;
@@ -797,7 +800,7 @@
{
FlicDecodeContext *s = avctx->priv_data;
- av_frame_unref(&s->frame);
+ av_frame_free(&s->frame);
return 0;
}
diff --git a/libavcodec/flvdec.c b/libavcodec/flvdec.c
index 3e55aaf..f425f00 100644
--- a/libavcodec/flvdec.c
+++ b/libavcodec/flvdec.c
@@ -102,9 +102,8 @@
s->h263_long_vectors = 0;
/* PEI */
- while (get_bits1(&s->gb) != 0) {
- skip_bits(&s->gb, 8);
- }
+ if (skip_1stop_8data_bits(&s->gb) < 0)
+ return AVERROR_INVALIDDATA;
s->f_code = 1;
if (s->ehc_mode)
diff --git a/libavcodec/g2meet.c b/libavcodec/g2meet.c
index 1667149..8f8e880 100644
--- a/libavcodec/g2meet.c
+++ b/libavcodec/g2meet.c
@@ -236,16 +236,14 @@
int swapuv)
{
GetBitContext gb;
- uint8_t *tmp;
int mb_w, mb_h, mb_x, mb_y, i, j;
int bx, by;
int unesc_size;
int ret;
- tmp = av_realloc(c->buf, src_size + FF_INPUT_BUFFER_PADDING_SIZE);
- if (!tmp)
- return AVERROR(ENOMEM);
- c->buf = tmp;
+ if ((ret = av_reallocp(&c->buf,
+ src_size + FF_INPUT_BUFFER_PADDING_SIZE)) < 0)
+ return ret;
jpg_unescape(src, src_size, c->buf, &unesc_size);
memset(c->buf + unesc_size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
init_get_bits(&gb, c->buf, unesc_size * 8);
@@ -375,6 +373,8 @@
src += 3;
}
npal = *src++ + 1;
+ if (src_end - src < npal * 3)
+ return AVERROR_INVALIDDATA;
memcpy(pal, src, npal * 3); src += npal * 3;
if (sub_type != 2) {
for (i = 0; i < npal; i++) {
@@ -480,8 +480,7 @@
uint32_t bits;
uint32_t cur_size, cursor_w, cursor_h, cursor_stride;
uint32_t cursor_hot_x, cursor_hot_y;
- int cursor_fmt;
- uint8_t *tmp;
+ int cursor_fmt, err;
cur_size = bytestream2_get_be32(gb);
cursor_w = bytestream2_get_byte(gb);
@@ -490,7 +489,7 @@
cursor_hot_y = bytestream2_get_byte(gb);
cursor_fmt = bytestream2_get_byte(gb);
- cursor_stride = FFALIGN(cursor_w, c->cursor_fmt==1 ? 32 : 1) * 4;
+ cursor_stride = FFALIGN(cursor_w, cursor_fmt==1 ? 32 : 1) * 4;
if (cursor_w < 1 || cursor_w > 256 ||
cursor_h < 1 || cursor_h > 256) {
@@ -516,13 +515,11 @@
return AVERROR_PATCHWELCOME;
}
- tmp = av_realloc(c->cursor, cursor_stride * cursor_h);
- if (!tmp) {
+ if ((err = av_reallocp(&c->cursor, cursor_stride * cursor_h)) < 0) {
av_log(avctx, AV_LOG_ERROR, "Cannot allocate cursor buffer\n");
- return AVERROR(ENOMEM);
+ return err;
}
- c->cursor = tmp;
c->cursor_w = cursor_w;
c->cursor_h = cursor_h;
c->cursor_hot_x = cursor_hot_x;
@@ -701,7 +698,7 @@
goto header_fail;
}
if (c->width != avctx->width || c->height != avctx->height)
- avcodec_set_dimensions(avctx, c->width, c->height);
+ ff_set_dimensions(avctx, c->width, c->height);
c->compression = bytestream2_get_be32(&bc);
if (c->compression != 2 && c->compression != 3) {
av_log(avctx, AV_LOG_ERROR,
@@ -711,7 +708,8 @@
}
c->tile_width = bytestream2_get_be32(&bc);
c->tile_height = bytestream2_get_be32(&bc);
- if (!c->tile_width || !c->tile_height) {
+ if (!c->tile_width || !c->tile_height ||
+ ((c->tile_width | c->tile_height) & 0xF)) {
av_log(avctx, AV_LOG_ERROR,
"Invalid tile dimensions %dx%d\n",
c->tile_width, c->tile_height);
diff --git a/libavcodec/g722dec.c b/libavcodec/g722dec.c
index d3b89ff..470fbbf 100644
--- a/libavcodec/g722dec.c
+++ b/libavcodec/g722dec.c
@@ -44,7 +44,7 @@
#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, { .i64 = 8 }, 6, 8, AD },
+ { "bits_per_codeword", "Bits per G722 codeword", OFFSET(bits_per_codeword), AV_OPT_TYPE_INT, { .i64 = 8 }, 6, 8, AD },
{ NULL }
};
diff --git a/libavcodec/g726.c b/libavcodec/g726.c
index a16c0ef..b0331d8 100644
--- a/libavcodec/g726.c
+++ b/libavcodec/g726.c
@@ -96,6 +96,7 @@
int sez; /**< estimated second order prediction */
int y; /**< quantizer scaling factor for the next iteration */
int code_size;
+ int little_endian; /**< little-endian bitstream as used in aiff and Sun AU */
} G726Context;
static const int quant_tbl16[] = /**< 16kbit/s 2bits per sample */
@@ -396,7 +397,7 @@
};
#endif
-#if CONFIG_ADPCM_G726_DECODER
+#if CONFIG_ADPCM_G726_DECODER || CONFIG_ADPCM_G726LE_DECODER
static av_cold int g726_decode_init(AVCodecContext *avctx)
{
G726Context* c = avctx->priv_data;
@@ -408,6 +409,8 @@
avctx->channels = 1;
avctx->channel_layout = AV_CH_LAYOUT_MONO;
+ c->little_endian = !strcmp(avctx->codec->name, "g726le");
+
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);
@@ -442,7 +445,9 @@
init_get_bits(&gb, buf, buf_size * 8);
while (out_samples--)
- *samples++ = g726_decode(c, get_bits(&gb, c->code_size));
+ *samples++ = g726_decode(c, c->little_endian ?
+ get_bits_le(&gb, c->code_size) :
+ get_bits(&gb, c->code_size));
if (get_bits_left(&gb) > 0)
av_log(avctx, AV_LOG_ERROR, "Frame invalidly split, missing parser?\n");
@@ -457,7 +462,9 @@
G726Context *c = avctx->priv_data;
g726_reset(c);
}
+#endif
+#if CONFIG_ADPCM_G726_DECODER
AVCodec ff_adpcm_g726_decoder = {
.name = "g726",
.long_name = NULL_IF_CONFIG_SMALL("G.726 ADPCM"),
@@ -470,3 +477,17 @@
.capabilities = CODEC_CAP_DR1,
};
#endif
+
+#if CONFIG_ADPCM_G726LE_DECODER
+AVCodec ff_adpcm_g726le_decoder = {
+ .name = "g726le",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = AV_CODEC_ID_ADPCM_G726LE,
+ .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 little-endian"),
+};
+#endif
diff --git a/libavcodec/get_bits.h b/libavcodec/get_bits.h
index 4ddb088..7824e5a 100644
--- a/libavcodec/get_bits.h
+++ b/libavcodec/get_bits.h
@@ -585,6 +585,20 @@
return gb->size_in_bits - get_bits_count(gb);
}
+static inline int skip_1stop_8data_bits(GetBitContext *gb)
+{
+ if (get_bits_left(gb) <= 0)
+ return AVERROR_INVALIDDATA;
+
+ while (get_bits1(gb)) {
+ skip_bits(gb, 8);
+ if (get_bits_left(gb) <= 0)
+ return AVERROR_INVALIDDATA;
+ }
+
+ return 0;
+}
+
//#define TRACE
#ifdef TRACE
diff --git a/libavcodec/gif.c b/libavcodec/gif.c
index 8b9d95f..27d054e 100644
--- a/libavcodec/gif.c
+++ b/libavcodec/gif.c
@@ -216,6 +216,13 @@
return AVERROR(EINVAL);
}
+ avctx->coded_frame = av_frame_alloc();
+ if (!avctx->coded_frame)
+ return AVERROR(ENOMEM);
+
+ avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
+ avctx->coded_frame->key_frame = 1;
+
s->lzw = av_mallocz(ff_lzw_encode_state_size);
s->buf = av_malloc(avctx->width*avctx->height*2);
s->tmpl = av_malloc(avctx->width);
@@ -232,7 +239,6 @@
const AVFrame *pict, int *got_packet)
{
GIFContext *s = avctx->priv_data;
- AVFrame *const p = (AVFrame *)pict;
uint8_t *outbuf_ptr, *end;
const uint32_t *palette = NULL;
int ret;
@@ -242,15 +248,12 @@
outbuf_ptr = pkt->data;
end = pkt->data + pkt->size;
- p->pict_type = AV_PICTURE_TYPE_I;
- p->key_frame = 1;
-
if (avctx->pix_fmt == AV_PIX_FMT_PAL8) {
uint8_t *pal_exdata = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, AVPALETTE_SIZE);
if (!pal_exdata)
return AVERROR(ENOMEM);
- memcpy(pal_exdata, p->data[1], AVPALETTE_SIZE);
- palette = (uint32_t*)p->data[1];
+ memcpy(pal_exdata, pict->data[1], AVPALETTE_SIZE);
+ palette = (uint32_t*)pict->data[1];
}
gif_image_write_image(avctx, &outbuf_ptr, end, palette,
@@ -276,6 +279,8 @@
{
GIFContext *s = avctx->priv_data;
+ av_frame_free(&avctx->coded_frame);
+
av_freep(&s->lzw);
av_freep(&s->buf);
av_frame_free(&s->last_frame);
diff --git a/libavcodec/gifdec.c b/libavcodec/gifdec.c
index 4151b88..c7b9ac8 100644
--- a/libavcodec/gifdec.c
+++ b/libavcodec/gifdec.c
@@ -64,7 +64,6 @@
int stored_bg_color;
GetByteContext gb;
- /* LZW compatible decoder */
LZWState *lzw;
/* aux buffers */
@@ -140,11 +139,11 @@
if (bytestream2_get_bytes_left(&s->gb) < 9)
return AVERROR_INVALIDDATA;
- left = bytestream2_get_le16u(&s->gb);
- top = bytestream2_get_le16u(&s->gb);
- width = bytestream2_get_le16u(&s->gb);
+ left = bytestream2_get_le16u(&s->gb);
+ top = bytestream2_get_le16u(&s->gb);
+ width = bytestream2_get_le16u(&s->gb);
height = bytestream2_get_le16u(&s->gb);
- flags = bytestream2_get_byteu(&s->gb);
+ flags = bytestream2_get_byteu(&s->gb);
is_interleaved = flags & 0x40;
has_local_palette = flags & 0x80;
bits_per_pixel = (flags & 0x07) + 1;
@@ -181,10 +180,14 @@
/* verify that all the image is inside the screen dimensions */
if (left + width > s->screen_width ||
- top + height > s->screen_height)
+ top + height > s->screen_height) {
+ av_log(s->avctx, AV_LOG_ERROR, "image is outside the screen dimensions.\n");
return AVERROR_INVALIDDATA;
- if (width <= 0 || height <= 0)
+ }
+ if (width <= 0 || height <= 0) {
+ av_log(s->avctx, AV_LOG_ERROR, "Invalid image dimensions.\n");
return AVERROR_INVALIDDATA;
+ }
/* process disposal method */
if (s->gce_prev_disposal == GCE_DISPOSAL_BACKGROUND) {
@@ -298,7 +301,7 @@
return AVERROR_INVALIDDATA;
ext_code = bytestream2_get_byteu(&s->gb);
- ext_len = bytestream2_get_byteu(&s->gb);
+ ext_len = bytestream2_get_byteu(&s->gb);
av_dlog(s->avctx, "ext_code=0x%x len=%d\n", ext_code, ext_len);
@@ -312,7 +315,7 @@
if (bytestream2_get_bytes_left(&s->gb) < 5)
return AVERROR_INVALIDDATA;
- gce_flags = bytestream2_get_byteu(&s->gb);
+ gce_flags = bytestream2_get_byteu(&s->gb);
bytestream2_skipu(&s->gb, 2); // delay during which the frame is shown
gce_transparent_index = bytestream2_get_byteu(&s->gb);
if (gce_flags & 0x01)
@@ -366,7 +369,7 @@
/* read screen header */
s->transparent_color_index = -1;
- s->screen_width = bytestream2_get_le16u(&s->gb);
+ s->screen_width = bytestream2_get_le16u(&s->gb);
s->screen_height = bytestream2_get_le16u(&s->gb);
v = bytestream2_get_byteu(&s->gb);
@@ -400,7 +403,7 @@
static int gif_parse_next_image(GifState *s, AVFrame *frame)
{
- while (bytestream2_get_bytes_left(&s->gb)) {
+ while (bytestream2_get_bytes_left(&s->gb) > 0) {
int code = bytestream2_get_byte(&s->gb);
int ret;
@@ -463,9 +466,8 @@
if ((ret = gif_read_header1(s)) < 0)
return ret;
- if ((ret = av_image_check_size(s->screen_width, s->screen_height, 0, avctx)) < 0)
+ if ((ret = ff_set_dimensions(avctx, s->screen_width, s->screen_height)) < 0)
return ret;
- avcodec_set_dimensions(avctx, s->screen_width, s->screen_height);
av_frame_unref(s->frame);
if ((ret = ff_get_buffer(avctx, s->frame, 0)) < 0)
@@ -499,7 +501,7 @@
return ret;
*got_frame = 1;
- return avpkt->size;
+ return bytestream2_tell(&s->gb);
}
static av_cold int gif_decode_close(AVCodecContext *avctx)
diff --git a/libavcodec/golomb.h b/libavcodec/golomb.h
index 66607ad..43875dc 100644
--- a/libavcodec/golomb.h
+++ b/libavcodec/golomb.h
@@ -31,6 +31,7 @@
#define AVCODEC_GOLOMB_H
#include <stdint.h>
+
#include "get_bits.h"
#include "put_bits.h"
@@ -46,33 +47,32 @@
extern const int8_t ff_interleaved_se_golomb_vlc_code[256];
extern const uint8_t ff_interleaved_dirac_golomb_vlc_code[256];
-
- /**
+/**
* read unsigned exp golomb code.
*/
-static inline int get_ue_golomb(GetBitContext *gb){
+static inline int get_ue_golomb(GetBitContext *gb)
+{
unsigned int buf;
- int log;
OPEN_READER(re, gb);
UPDATE_CACHE(re, gb);
- buf=GET_CACHE(re, gb);
+ buf = GET_CACHE(re, gb);
- if(buf >= (1<<27)){
+ if (buf >= (1 << 27)) {
buf >>= 32 - 9;
LAST_SKIP_BITS(re, gb, ff_golomb_vlc_len[buf]);
CLOSE_READER(re, gb);
return ff_ue_golomb_vlc_code[buf];
- }else{
- log= 2*av_log2(buf) - 31;
+ } else {
+ int log = 2 * av_log2(buf) - 31;
LAST_SKIP_BITS(re, gb, 32 - log);
CLOSE_READER(re, gb);
if (CONFIG_FTRAPV && log < 0) {
av_log(0, AV_LOG_ERROR, "Invalid UE golomb code\n");
return AVERROR_INVALIDDATA;
}
- buf>>= log;
+ buf >>= log;
buf--;
return buf;
@@ -93,16 +93,17 @@
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.
*/
-static inline int get_ue_golomb_31(GetBitContext *gb){
+static inline int get_ue_golomb_31(GetBitContext *gb)
+{
unsigned int buf;
OPEN_READER(re, gb);
UPDATE_CACHE(re, gb);
- buf=GET_CACHE(re, gb);
+ buf = GET_CACHE(re, gb);
buf >>= 32 - 9;
LAST_SKIP_BITS(re, gb, ff_golomb_vlc_len[buf]);
@@ -117,24 +118,25 @@
OPEN_READER(re, gb);
UPDATE_CACHE(re, gb);
- buf=GET_CACHE(re, gb);
+ buf = GET_CACHE(re, gb);
- if(buf&0xAA800000){
+ if (buf & 0xAA800000) {
buf >>= 32 - 8;
LAST_SKIP_BITS(re, gb, ff_interleaved_golomb_vlc_len[buf]);
CLOSE_READER(re, gb);
return ff_interleaved_ue_golomb_vlc_code[buf];
- }else{
+ } else {
unsigned ret = 1;
do {
buf >>= 32 - 8;
- LAST_SKIP_BITS(re, gb, FFMIN(ff_interleaved_golomb_vlc_len[buf], 8));
+ LAST_SKIP_BITS(re, gb,
+ FFMIN(ff_interleaved_golomb_vlc_len[buf], 8));
- if (ff_interleaved_golomb_vlc_len[buf] != 9){
+ if (ff_interleaved_golomb_vlc_len[buf] != 9) {
ret <<= (ff_interleaved_golomb_vlc_len[buf] - 1) >> 1;
- ret |= ff_interleaved_dirac_golomb_vlc_code[buf];
+ ret |= ff_interleaved_dirac_golomb_vlc_code[buf];
break;
}
ret = (ret << 4) | ff_interleaved_dirac_golomb_vlc_code[buf];
@@ -150,100 +152,107 @@
/**
* read unsigned truncated exp golomb code.
*/
-static inline int get_te0_golomb(GetBitContext *gb, int range){
+static inline int get_te0_golomb(GetBitContext *gb, int range)
+{
av_assert2(range >= 1);
- if(range==1) return 0;
- else if(range==2) return get_bits1(gb)^1;
- else return get_ue_golomb(gb);
+ if (range == 1)
+ return 0;
+ else if (range == 2)
+ return get_bits1(gb) ^ 1;
+ else
+ return get_ue_golomb(gb);
}
/**
* read unsigned truncated exp golomb code.
*/
-static inline int get_te_golomb(GetBitContext *gb, int range){
+static inline int get_te_golomb(GetBitContext *gb, int range)
+{
av_assert2(range >= 1);
- if(range==2) return get_bits1(gb)^1;
- else return get_ue_golomb(gb);
+ if (range == 2)
+ return get_bits1(gb) ^ 1;
+ else
+ return get_ue_golomb(gb);
}
-
/**
* read signed exp golomb code.
*/
-static inline int get_se_golomb(GetBitContext *gb){
+static inline int get_se_golomb(GetBitContext *gb)
+{
unsigned int buf;
- int log;
OPEN_READER(re, gb);
UPDATE_CACHE(re, gb);
- buf=GET_CACHE(re, gb);
+ buf = GET_CACHE(re, gb);
- if(buf >= (1<<27)){
+ if (buf >= (1 << 27)) {
buf >>= 32 - 9;
LAST_SKIP_BITS(re, gb, ff_golomb_vlc_len[buf]);
CLOSE_READER(re, gb);
return ff_se_golomb_vlc_code[buf];
- }else{
- log = av_log2(buf);
+ } else {
+ int log = av_log2(buf);
LAST_SKIP_BITS(re, gb, 31 - log);
UPDATE_CACHE(re, gb);
buf = GET_CACHE(re, gb);
- buf>>= log;
+ buf >>= log;
LAST_SKIP_BITS(re, gb, 32 - log);
CLOSE_READER(re, gb);
- if(buf&1) buf= -(buf>>1);
- else buf= (buf>>1);
+ if (buf & 1)
+ buf = -(buf >> 1);
+ else
+ buf = (buf >> 1);
return buf;
}
}
-static inline int svq3_get_se_golomb(GetBitContext *gb){
+static inline int svq3_get_se_golomb(GetBitContext *gb)
+{
unsigned int buf;
- int log;
OPEN_READER(re, gb);
UPDATE_CACHE(re, gb);
- buf=GET_CACHE(re, gb);
+ buf = GET_CACHE(re, gb);
- if(buf&0xAA800000){
+ if (buf & 0xAA800000) {
buf >>= 32 - 8;
LAST_SKIP_BITS(re, gb, ff_interleaved_golomb_vlc_len[buf]);
CLOSE_READER(re, gb);
return ff_interleaved_se_golomb_vlc_code[buf];
- }else{
+ } else {
+ int log;
LAST_SKIP_BITS(re, gb, 8);
UPDATE_CACHE(re, gb);
buf |= 1 | (GET_CACHE(re, gb) >> 8);
- if((buf & 0xAAAAAAAA) == 0)
+ if ((buf & 0xAAAAAAAA) == 0)
return INVALID_VLC;
- for(log=31; (buf & 0x80000000) == 0; log--){
+ for (log = 31; (buf & 0x80000000) == 0; log--)
buf = (buf << 2) - ((buf << log) >> (log - 1)) + (buf >> 30);
- }
- LAST_SKIP_BITS(re, gb, 63 - 2*log - 8);
+ LAST_SKIP_BITS(re, gb, 63 - 2 * log - 8);
CLOSE_READER(re, gb);
return (signed) (((((buf << log) >> log) - 1) ^ -(buf & 0x1)) + 1) >> 1;
}
}
-static inline int dirac_get_se_golomb(GetBitContext *gb){
- uint32_t buf;
- uint32_t ret;
-
- ret = svq3_get_ue_golomb(gb);
+static inline int dirac_get_se_golomb(GetBitContext *gb)
+{
+ uint32_t ret = svq3_get_ue_golomb(gb);
if (ret) {
+ uint32_t buf;
OPEN_READER(re, gb);
UPDATE_CACHE(re, gb);
buf = SHOW_SBITS(re, gb, 1);
@@ -258,24 +267,26 @@
/**
* read unsigned golomb rice code (ffv1).
*/
-static inline int get_ur_golomb(GetBitContext *gb, int k, int limit, int esc_len){
+static inline int get_ur_golomb(GetBitContext *gb, int k, int limit,
+ int esc_len)
+{
unsigned int buf;
int log;
OPEN_READER(re, gb);
UPDATE_CACHE(re, gb);
- buf=GET_CACHE(re, gb);
+ buf = GET_CACHE(re, gb);
- log= av_log2(buf);
+ log = av_log2(buf);
- if(log > 31-limit){
+ if (log > 31 - limit) {
buf >>= log - k;
- buf += (30-log)<<k;
+ buf += (30 - log) << k;
LAST_SKIP_BITS(re, gb, 32 + k - log);
CLOSE_READER(re, gb);
return buf;
- }else{
+ } else {
LAST_SKIP_BITS(re, gb, limit);
UPDATE_CACHE(re, gb);
@@ -291,24 +302,27 @@
/**
* read unsigned golomb rice code (jpegls).
*/
-static inline int get_ur_golomb_jpegls(GetBitContext *gb, int k, int limit, int esc_len){
+static inline int get_ur_golomb_jpegls(GetBitContext *gb, int k, int limit,
+ int esc_len)
+{
unsigned int buf;
int log;
OPEN_READER(re, gb);
UPDATE_CACHE(re, gb);
- buf=GET_CACHE(re, gb);
+ buf = GET_CACHE(re, gb);
- log= av_log2(buf);
+ log = av_log2(buf);
- if(log - k >= 32-MIN_CACHE_BITS+(MIN_CACHE_BITS==32) && 32-log < limit){
+ if (log - k >= 32 - MIN_CACHE_BITS + (MIN_CACHE_BITS == 32) &&
+ 32 - log < limit) {
buf >>= log - k;
- buf += (30-log)<<k;
+ buf += (30 - log) << k;
LAST_SKIP_BITS(re, gb, 32 + k - log);
CLOSE_READER(re, gb);
return buf;
- }else{
+ } else {
int i;
for (i = 0; i < limit && SHOW_UBITS(re, gb, 1) == 0; i++) {
if (gb->size_in_bits <= re_index)
@@ -318,23 +332,23 @@
}
SKIP_BITS(re, gb, 1);
- if(i < limit - 1){
- if(k){
+ if (i < limit - 1) {
+ if (k) {
buf = SHOW_UBITS(re, gb, k);
LAST_SKIP_BITS(re, gb, k);
- }else{
- buf=0;
+ } else {
+ buf = 0;
}
CLOSE_READER(re, gb);
- return buf + (i<<k);
- }else if(i == limit - 1){
+ return buf + (i << k);
+ } else if (i == limit - 1) {
buf = SHOW_UBITS(re, gb, esc_len);
LAST_SKIP_BITS(re, gb, esc_len);
CLOSE_READER(re, gb);
return buf + 1;
- }else
+ } else
return -1;
}
}
@@ -342,12 +356,16 @@
/**
* read signed golomb rice code (ffv1).
*/
-static inline int get_sr_golomb(GetBitContext *gb, int k, int limit, int esc_len){
- int v= get_ur_golomb(gb, k, limit, esc_len);
+static inline int get_sr_golomb(GetBitContext *gb, int k, int limit,
+ int esc_len)
+{
+ int v = get_ur_golomb(gb, k, limit, esc_len);
v++;
- if (v&1) return v>>1;
- else return -(v>>1);
+ if (v & 1)
+ return v >> 1;
+ else
+ return -(v >> 1);
// return (v>>1) ^ -(v&1);
}
@@ -355,22 +373,25 @@
/**
* read signed golomb rice code (flac).
*/
-static inline int get_sr_golomb_flac(GetBitContext *gb, int k, int limit, int esc_len){
- int v= get_ur_golomb_jpegls(gb, k, limit, esc_len);
- return (v>>1) ^ -(v&1);
+static inline int get_sr_golomb_flac(GetBitContext *gb, int k, int limit,
+ int esc_len)
+{
+ int v = get_ur_golomb_jpegls(gb, k, limit, esc_len);
+ return (v >> 1) ^ -(v & 1);
}
/**
* read unsigned golomb rice code (shorten).
*/
-static inline unsigned int get_ur_golomb_shorten(GetBitContext *gb, int k){
- return get_ur_golomb_jpegls(gb, k, INT_MAX, 0);
+static inline unsigned int get_ur_golomb_shorten(GetBitContext *gb, int k)
+{
+ return get_ur_golomb_jpegls(gb, k, INT_MAX, 0);
}
/**
* read signed golomb rice code (shorten).
*/
-static inline int get_sr_golomb_shorten(GetBitContext* gb, int k)
+static inline int get_sr_golomb_shorten(GetBitContext *gb, int k)
{
int uvar = get_ur_golomb_jpegls(gb, k + 1, INT_MAX, 0);
if (uvar & 1)
@@ -379,22 +400,21 @@
return uvar >> 1;
}
-
-
#ifdef TRACE
static inline int get_ue(GetBitContext *s, const char *file, const char *func,
int line)
{
- int show= show_bits(s, 24);
- int pos= get_bits_count(s);
- int i= get_ue_golomb(s);
- int len= get_bits_count(s) - pos;
- int bits= show>>(24-len);
+ int show = show_bits(s, 24);
+ int pos = get_bits_count(s);
+ int i = get_ue_golomb(s);
+ int len = get_bits_count(s) - pos;
+ int bits = show >> (24 - len);
print_bin(bits, len);
- av_log(NULL, AV_LOG_DEBUG, "%5d %2d %3d ue @%5d in %s %s:%d\n", bits, len, i, pos, file, func, line);
+ av_log(NULL, AV_LOG_DEBUG, "%5d %2d %3d ue @%5d in %s %s:%d\n",
+ bits, len, i, pos, file, func, line);
return i;
}
@@ -402,87 +422,96 @@
static inline int get_se(GetBitContext *s, const char *file, const char *func,
int line)
{
- int show= show_bits(s, 24);
- int pos= get_bits_count(s);
- int i= get_se_golomb(s);
- int len= get_bits_count(s) - pos;
- int bits= show>>(24-len);
+ int show = show_bits(s, 24);
+ int pos = get_bits_count(s);
+ int i = get_se_golomb(s);
+ int len = get_bits_count(s) - pos;
+ int bits = show >> (24 - len);
print_bin(bits, len);
- av_log(NULL, AV_LOG_DEBUG, "%5d %2d %3d se @%5d in %s %s:%d\n", bits, len, i, pos, file, func, line);
+ av_log(NULL, AV_LOG_DEBUG, "%5d %2d %3d se @%5d in %s %s:%d\n",
+ bits, len, i, pos, file, func, line);
return i;
}
-static inline int get_te(GetBitContext *s, int r, char *file, const char *func, int line){
- int show= show_bits(s, 24);
- int pos= get_bits_count(s);
- int i= get_te0_golomb(s, r);
- int len= get_bits_count(s) - pos;
- int bits= show>>(24-len);
+static inline int get_te(GetBitContext *s, int r, char *file, const char *func,
+ int line)
+{
+ int show = show_bits(s, 24);
+ int pos = get_bits_count(s);
+ int i = get_te0_golomb(s, r);
+ int len = get_bits_count(s) - pos;
+ int bits = show >> (24 - len);
print_bin(bits, len);
- av_log(NULL, AV_LOG_DEBUG, "%5d %2d %3d te @%5d in %s %s:%d\n", bits, len, i, pos, file, func, line);
+ av_log(NULL, AV_LOG_DEBUG, "%5d %2d %3d te @%5d in %s %s:%d\n",
+ bits, len, i, pos, file, func, line);
return i;
}
#define get_ue_golomb(a) get_ue(a, __FILE__, __PRETTY_FUNCTION__, __LINE__)
#define get_se_golomb(a) get_se(a, __FILE__, __PRETTY_FUNCTION__, __LINE__)
-#define get_te_golomb(a, r) get_te(a, r, __FILE__, __PRETTY_FUNCTION__, __LINE__)
+#define get_te_golomb(a, r) get_te(a, r, __FILE__, __PRETTY_FUNCTION__, __LINE__)
#define get_te0_golomb(a, r) get_te(a, r, __FILE__, __PRETTY_FUNCTION__, __LINE__)
-#endif
+#endif /* TRACE */
/**
* write unsigned exp golomb code.
*/
-static inline void set_ue_golomb(PutBitContext *pb, int i){
- int e;
-
- av_assert2(i>=0);
+static inline void set_ue_golomb(PutBitContext *pb, int i)
+{
+ av_assert2(i >= 0);
#if 0
- if(i=0){
+ if (i = 0) {
put_bits(pb, 1, 1);
return;
}
#endif
- if(i<256)
- put_bits(pb, ff_ue_golomb_len[i], i+1);
- else{
- e= av_log2(i+1);
-
- put_bits(pb, 2*e+1, i+1);
+ if (i < 256)
+ put_bits(pb, ff_ue_golomb_len[i], i + 1);
+ else {
+ int e = av_log2(i + 1);
+ put_bits(pb, 2 * e + 1, i + 1);
}
}
/**
* write truncated unsigned exp golomb code.
*/
-static inline void set_te_golomb(PutBitContext *pb, int i, int range){
+static inline void set_te_golomb(PutBitContext *pb, int i, int range)
+{
av_assert2(range >= 1);
- av_assert2(i<=range);
+ av_assert2(i <= range);
- if(range==2) put_bits(pb, 1, i^1);
- else set_ue_golomb(pb, i);
+ if (range == 2)
+ put_bits(pb, 1, i ^ 1);
+ else
+ set_ue_golomb(pb, i);
}
/**
* write signed exp golomb code. 16 bits at most.
*/
-static inline void set_se_golomb(PutBitContext *pb, int i){
+static inline void set_se_golomb(PutBitContext *pb, int i)
+{
#if 0
- if(i<=0) i= -2*i;
- else i= 2*i-1;
+ if (i <= 0)
+ i = -2 * i;
+ else
+ i = 2 * i - 1;
#elif 1
- i= 2*i-1;
- if(i<0) i^= -1; //FIXME check if gcc does the right thing
+ i = 2 * i - 1;
+ if (i < 0)
+ i ^= -1; //FIXME check if gcc does the right thing
#else
- i= 2*i-1;
- i^= (i>>31);
+ i = 2 * i - 1;
+ i ^= (i >> 31);
#endif
set_ue_golomb(pb, i);
}
@@ -490,42 +519,45 @@
/**
* write unsigned golomb rice code (ffv1).
*/
-static inline void set_ur_golomb(PutBitContext *pb, int i, int k, int limit, int esc_len){
+static inline void set_ur_golomb(PutBitContext *pb, int i, int k, int limit,
+ int esc_len)
+{
int e;
- av_assert2(i>=0);
+ av_assert2(i >= 0);
- e= i>>k;
- if(e<limit){
- put_bits(pb, e + k + 1, (1<<k) + (i&((1<<k)-1)));
- }else{
+ e = i >> k;
+ if (e < limit)
+ put_bits(pb, e + k + 1, (1 << k) + (i & ((1 << k) - 1)));
+ else
put_bits(pb, limit + esc_len, i - limit + 1);
- }
}
/**
* write unsigned golomb rice code (jpegls).
*/
-static inline void set_ur_golomb_jpegls(PutBitContext *pb, int i, int k, int limit, int esc_len){
+static inline void set_ur_golomb_jpegls(PutBitContext *pb, int i, int k,
+ int limit, int esc_len)
+{
int e;
- av_assert2(i>=0);
+ av_assert2(i >= 0);
- e= (i>>k) + 1;
- if(e<limit){
- while(e > 31) {
+ e = (i >> k) + 1;
+ if (e < limit) {
+ while (e > 31) {
put_bits(pb, 31, 0);
e -= 31;
}
put_bits(pb, e, 1);
- if(k)
+ if (k)
put_sbits(pb, k, i);
- }else{
- while(limit > 31) {
+ } else {
+ while (limit > 31) {
put_bits(pb, 31, 0);
limit -= 31;
}
- put_bits(pb, limit , 1);
+ put_bits(pb, limit, 1);
put_bits(pb, esc_len, i - 1);
}
}
@@ -533,11 +565,13 @@
/**
* write signed golomb rice code (ffv1).
*/
-static inline void set_sr_golomb(PutBitContext *pb, int i, int k, int limit, int esc_len){
+static inline void set_sr_golomb(PutBitContext *pb, int i, int k, int limit,
+ int esc_len)
+{
int v;
- v = -2*i-1;
- v ^= (v>>31);
+ v = -2 * i - 1;
+ v ^= (v >> 31);
set_ur_golomb(pb, v, k, limit, esc_len);
}
@@ -545,11 +579,13 @@
/**
* write signed golomb rice code (flac).
*/
-static inline void set_sr_golomb_flac(PutBitContext *pb, int i, int k, int limit, int esc_len){
+static inline void set_sr_golomb_flac(PutBitContext *pb, int i, int k,
+ int limit, int esc_len)
+{
int v;
- v = -2*i-1;
- v ^= (v>>31);
+ v = -2 * i - 1;
+ v ^= (v >> 31);
set_ur_golomb_jpegls(pb, v, k, limit, esc_len);
}
diff --git a/libavcodec/gsm.h b/libavcodec/gsm.h
index e56f4cd..53d65c4 100644
--- a/libavcodec/gsm.h
+++ b/libavcodec/gsm.h
@@ -22,10 +22,24 @@
#define AVCODEC_GSM_H
/* bytes per block */
-#define GSM_BLOCK_SIZE 33
-#define GSM_MS_BLOCK_SIZE 65
+#define GSM_BLOCK_SIZE 33
+#define GSM_MS_BLOCK_SIZE 65
+#define MSN_MIN_BLOCK_SIZE 41
/* samples per block */
#define GSM_FRAME_SIZE 160
+enum GSMModes {
+ GSM_13000 = 0,
+ MSN_12400,
+ MSN_11800,
+ MSN_11200,
+ MSN_10600,
+ MSN_10000,
+ MSN_9400,
+ MSN_8800,
+ MSN_8200,
+ NUM_GSM_MODES
+};
+
#endif /* AVCODEC_GSM_H */
diff --git a/libavcodec/gsm_parser.c b/libavcodec/gsm_parser.c
index f76bbef..9a3b94e 100644
--- a/libavcodec/gsm_parser.c
+++ b/libavcodec/gsm_parser.c
@@ -50,7 +50,8 @@
s->duration = GSM_FRAME_SIZE;
break;
case AV_CODEC_ID_GSM_MS:
- s->block_size = GSM_MS_BLOCK_SIZE;
+ s->block_size = avctx->block_align ? avctx->block_align
+ : GSM_MS_BLOCK_SIZE;
s->duration = GSM_FRAME_SIZE * 2;
break;
default:
diff --git a/libavcodec/gsmdec.c b/libavcodec/gsmdec.c
index 7ca9677..c4cde92 100644
--- a/libavcodec/gsmdec.c
+++ b/libavcodec/gsmdec.c
@@ -34,14 +34,6 @@
static av_cold int gsm_init(AVCodecContext *avctx)
{
- if (avctx->codec_tag == 0x0032 &&
- avctx->bit_rate != 13000 &&
- avctx->bit_rate != 17912 &&
- avctx->bit_rate != 35824 &&
- avctx->bit_rate != 71656) {
- av_log(avctx, AV_LOG_ERROR, "Unsupported audio mode\n");
- return AVERROR_PATCHWELCOME;
- }
avctx->channels = 1;
avctx->channel_layout = AV_CH_LAYOUT_MONO;
if (!avctx->sample_rate)
@@ -55,7 +47,16 @@
break;
case AV_CODEC_ID_GSM_MS:
avctx->frame_size = 2 * GSM_FRAME_SIZE;
- avctx->block_align = GSM_MS_BLOCK_SIZE;
+ if (!avctx->block_align)
+ avctx->block_align = GSM_MS_BLOCK_SIZE;
+ else
+ if (avctx->block_align < MSN_MIN_BLOCK_SIZE ||
+ avctx->block_align > GSM_MS_BLOCK_SIZE ||
+ (avctx->block_align - MSN_MIN_BLOCK_SIZE) % 3) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid block alignment %d\n",
+ avctx->block_align);
+ return AVERROR_INVALIDDATA;
+ }
}
return 0;
@@ -87,12 +88,13 @@
init_get_bits(&gb, buf, buf_size * 8);
if (get_bits(&gb, 4) != 0xd)
av_log(avctx, AV_LOG_WARNING, "Missing GSM magic!\n");
- res = gsm_decode_block(avctx, samples, &gb);
+ res = gsm_decode_block(avctx, samples, &gb, GSM_13000);
if (res < 0)
return res;
break;
case AV_CODEC_ID_GSM_MS:
- res = ff_msgsm_decode_block(avctx, samples, buf);
+ res = ff_msgsm_decode_block(avctx, samples, buf,
+ (GSM_MS_BLOCK_SIZE - avctx->block_align) / 3);
if (res < 0)
return res;
}
diff --git a/libavcodec/gsmdec_data.c b/libavcodec/gsmdec_data.c
index 4324ea2..d90c69b 100644
--- a/libavcodec/gsmdec_data.c
+++ b/libavcodec/gsmdec_data.c
@@ -92,3 +92,29 @@
{-26879, -19199, -11520, -3840, 3840, 11520, 19199, 26879},
{-28671, -20479, -12288, -4096, 4096, 12288, 20479, 28671}
};
+
+static const int apcm_bits[11][13] = {
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
+ { 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1 },
+ { 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1 },
+ { 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1 },
+ { 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1 },
+ { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
+ { 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
+ { 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
+ { 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
+ { 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
+ { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }
+};
+
+const int* const ff_gsm_apcm_bits[][4] = {
+ { apcm_bits[10], apcm_bits[10], apcm_bits[10], apcm_bits[10] }, // 13000
+ { apcm_bits[10], apcm_bits[10], apcm_bits[10], apcm_bits[ 6] }, // 12400
+ { apcm_bits[10], apcm_bits[10], apcm_bits[ 7], apcm_bits[ 5] }, // 11800
+ { apcm_bits[10], apcm_bits[ 8], apcm_bits[ 5], apcm_bits[ 5] }, // 11200
+ { apcm_bits[ 9], apcm_bits[ 5], apcm_bits[ 5], apcm_bits[ 5] }, // 10600
+ { apcm_bits[ 5], apcm_bits[ 5], apcm_bits[ 5], apcm_bits[ 1] }, // 10000
+ { apcm_bits[ 5], apcm_bits[ 5], apcm_bits[ 2], apcm_bits[ 0] }, // 9400
+ { apcm_bits[ 5], apcm_bits[ 3], apcm_bits[ 0], apcm_bits[ 0] }, // 8800
+ { apcm_bits[ 4], apcm_bits[ 0], apcm_bits[ 0], apcm_bits[ 0] }, // 8200
+};
diff --git a/libavcodec/gsmdec_data.h b/libavcodec/gsmdec_data.h
index fd89ed6..b57194b 100644
--- a/libavcodec/gsmdec_data.h
+++ b/libavcodec/gsmdec_data.h
@@ -40,4 +40,6 @@
extern const uint16_t ff_gsm_long_term_gain_tab[4];
extern const int16_t ff_gsm_dequant_tab[64][8];
+extern const int* const ff_gsm_apcm_bits[][4];
+
#endif /* AVCODEC_GSMDEC_DATA_H */
diff --git a/libavcodec/gsmdec_template.c b/libavcodec/gsmdec_template.c
index 0f55953..0c60813 100644
--- a/libavcodec/gsmdec_template.c
+++ b/libavcodec/gsmdec_template.c
@@ -28,13 +28,22 @@
#include "gsm.h"
#include "gsmdec_data.h"
-static void apcm_dequant_add(GetBitContext *gb, int16_t *dst)
+static const int requant_tab[4][8] = {
+ { 0 },
+ { 0, 7 },
+ { 0, 2, 5, 7 },
+ { 0, 1, 2, 3, 4, 5, 6, 7 }
+};
+
+static void apcm_dequant_add(GetBitContext *gb, int16_t *dst, const int *frame_bits)
{
- int i;
+ int i, val;
int maxidx = get_bits(gb, 6);
const int16_t *tab = ff_gsm_dequant_tab[maxidx];
- for (i = 0; i < 13; i++)
- dst[3*i] += tab[get_bits(gb, 3)];
+ for (i = 0; i < 13; i++) {
+ val = get_bits(gb, frame_bits[i]);
+ dst[3*i] += tab[requant_tab[frame_bits[i]][val]];
+ }
}
static inline int gsm_mult(int a, int b)
@@ -118,7 +127,7 @@
}
static int gsm_decode_block(AVCodecContext *avctx, int16_t *samples,
- GetBitContext *gb)
+ GetBitContext *gb, int mode)
{
GSMContext *ctx = avctx->priv_data;
int i;
@@ -139,7 +148,7 @@
int offset = get_bits(gb, 2);
lag = av_clip(lag, 40, 120);
long_term_synth(ref_dst, lag, gain_idx);
- apcm_dequant_add(gb, ref_dst + offset);
+ apcm_dequant_add(gb, ref_dst + offset, ff_gsm_apcm_bits[mode][i]);
ref_dst += 40;
}
memcpy(ctx->ref_buf, ctx->ref_buf + 160, 120 * sizeof(*ctx->ref_buf));
diff --git a/libavcodec/h261.h b/libavcodec/h261.h
index 597bf7e..5586462 100644
--- a/libavcodec/h261.h
+++ b/libavcodec/h261.h
@@ -38,7 +38,6 @@
MpegEncContext s;
int current_mba;
- int previous_mba;
int mba_diff;
int mtype;
int current_mv_x;
diff --git a/libavcodec/h261dec.c b/libavcodec/h261dec.c
index 50bfec9..49f1b4a 100644
--- a/libavcodec/h261dec.c
+++ b/libavcodec/h261dec.c
@@ -30,6 +30,7 @@
#include "mpegvideo.h"
#include "h263.h"
#include "h261.h"
+#include "internal.h"
#define H261_MBA_VLC_BITS 9
#define H261_MTYPE_VLC_BITS 6
@@ -125,8 +126,8 @@
}
/* GEI */
- while (get_bits1(&s->gb) != 0)
- skip_bits(&s->gb, 8);
+ if (skip_1stop_8data_bits(&s->gb) < 0)
+ return AVERROR_INVALIDDATA;
if (s->qscale == 0) {
av_log(s->avctx, AV_LOG_ERROR, "qscale has forbidden 0 value\n");
@@ -478,7 +479,6 @@
s->picture_number = (s->picture_number & ~31) + i;
s->avctx->time_base = (AVRational) { 1001, 30000 };
- s->current_picture.f.pts = s->picture_number;
/* PTYPE starts here */
skip_bits1(&s->gb); /* split screen off */
@@ -506,8 +506,8 @@
skip_bits1(&s->gb); /* Reserved */
/* PEI */
- while (get_bits1(&s->gb) != 0)
- skip_bits(&s->gb, 8);
+ if (skip_1stop_8data_bits(&s->gb) < 0)
+ return AVERROR_INVALIDDATA;
/* H.261 has no I-frames, but if we pass AV_PICTURE_TYPE_I for the first
* frame, the codec crashes if it does not contain all I-blocks
@@ -586,15 +586,6 @@
if (ff_MPV_common_init(s) < 0)
return -1;
- /* 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)
- return i;
- s->current_picture_ptr = &s->picture[i];
- }
-
ret = h261_decode_picture_header(h);
/* skip if the header was thrashed */
@@ -610,7 +601,9 @@
s->parse_context = pc;
}
if (!s->context_initialized) {
- avcodec_set_dimensions(avctx, s->width, s->height);
+ ret = ff_set_dimensions(avctx, s->width, s->height);
+ if (ret < 0)
+ return ret;
goto retry;
}
diff --git a/libavcodec/h261enc.c b/libavcodec/h261enc.c
index d7f40de..e185f5e 100644
--- a/libavcodec/h261enc.c
+++ b/libavcodec/h261enc.c
@@ -32,6 +32,9 @@
#include "h263.h"
#include "h261.h"
+static uint8_t uni_h261_rl_len [64*64*2*2];
+#define UNI_ENC_INDEX(last,run,level) ((last)*128*64 + (run)*128 + (level))
+
int ff_h261_get_picture_format(int width, int height)
{
// QCIF
@@ -77,7 +80,7 @@
h->gob_number = -1;
else
h->gob_number = 0;
- h->current_mba = 0;
+ s->mb_skip_run = 0;
}
/**
@@ -95,18 +98,21 @@
put_bits(&s->pb, 4, h->gob_number); /* GN */
put_bits(&s->pb, 5, s->qscale); /* GQUANT */
put_bits(&s->pb, 1, 0); /* no GEI */
- h->current_mba = 0;
- h->previous_mba = 0;
- h->current_mv_x = 0;
- h->current_mv_y = 0;
+ s->mb_skip_run = 0;
+ s->last_mv[0][0][0] = 0;
+ s->last_mv[0][0][1] = 0;
}
void ff_h261_reorder_mb_index(MpegEncContext *s)
{
int index = s->mb_x + s->mb_y * s->mb_width;
- if (index % 33 == 0)
- h261_encode_gob_header(s, 0);
+ if (index % 11 == 0) {
+ if (index % 33 == 0)
+ h261_encode_gob_header(s, 0);
+ s->last_mv[0][0][0] = 0;
+ s->last_mv[0][0][1] = 0;
+ }
/* for CIF the GOB's are fragmented in the middle of a scanline
* that's why we need to adjust the x and y index of the macroblocks */
@@ -234,7 +240,6 @@
cbp = 63; // avoid warning
mvd = 0;
- h->current_mba++;
h->mtype = 0;
if (!s->mb_intra) {
@@ -247,16 +252,18 @@
if ((cbp | mvd | s->dquant) == 0) {
/* skip macroblock */
s->skip_count++;
- h->current_mv_x = 0;
- h->current_mv_y = 0;
+ s->mb_skip_run++;
+ s->last_mv[0][0][0] = 0;
+ s->last_mv[0][0][1] = 0;
return;
}
}
/* MB is not skipped, encode MBA */
put_bits(&s->pb,
- ff_h261_mba_bits[(h->current_mba - h->previous_mba) - 1],
- ff_h261_mba_code[(h->current_mba - h->previous_mba) - 1]);
+ ff_h261_mba_bits[s->mb_skip_run],
+ ff_h261_mba_code[s->mb_skip_run]);
+ s->mb_skip_run = 0;
/* calculate MTYPE */
if (!s->mb_intra) {
@@ -286,16 +293,14 @@
}
if (IS_16X16(h->mtype)) {
- mv_diff_x = (motion_x >> 1) - h->current_mv_x;
- mv_diff_y = (motion_y >> 1) - h->current_mv_y;
- h->current_mv_x = (motion_x >> 1);
- h->current_mv_y = (motion_y >> 1);
+ mv_diff_x = (motion_x >> 1) - s->last_mv[0][0][0];
+ mv_diff_y = (motion_y >> 1) - s->last_mv[0][0][1];
+ s->last_mv[0][0][0] = (motion_x >> 1);
+ s->last_mv[0][0][1] = (motion_y >> 1);
h261_encode_motion(h, mv_diff_x);
h261_encode_motion(h, mv_diff_y);
}
- h->previous_mba = h->current_mba;
-
if (HAS_CBP(h->mtype)) {
av_assert1(cbp > 0);
put_bits(&s->pb,
@@ -306,10 +311,49 @@
/* encode each block */
h261_encode_block(h, block[i], i);
- if ((h->current_mba == 11) || (h->current_mba == 22) ||
- (h->current_mba == 33) || (!IS_16X16(h->mtype))) {
- h->current_mv_x = 0;
- h->current_mv_y = 0;
+ if (!IS_16X16(h->mtype)) {
+ s->last_mv[0][0][0] = 0;
+ s->last_mv[0][0][1] = 0;
+ }
+}
+
+static av_cold void init_uni_h261_rl_tab(RLTable *rl, uint32_t *bits_tab,
+ uint8_t *len_tab)
+{
+ int slevel, run, last;
+
+ av_assert0(MAX_LEVEL >= 64);
+ av_assert0(MAX_RUN >= 63);
+
+ for(slevel=-64; slevel<64; slevel++){
+ if(slevel==0) continue;
+ for(run=0; run<64; run++){
+ for(last=0; last<=1; last++){
+ const int index= UNI_ENC_INDEX(last, run, slevel+64);
+ int level= slevel < 0 ? -slevel : slevel;
+ int len, code;
+
+ len_tab[index]= 100;
+
+ /* ESC0 */
+ code= get_rl_index(rl, 0, run, level);
+ len= rl->table_vlc[code][1] + 1;
+ if(last)
+ len += 2;
+
+ if(code!=rl->n && len < len_tab[index]){
+ len_tab [index]= len;
+ }
+ /* ESC */
+ len = rl->table_vlc[rl->n][1];
+ if(last)
+ len += 2;
+
+ if(len < len_tab[index]){
+ len_tab [index]= len;
+ }
+ }
+ }
}
}
@@ -321,6 +365,12 @@
s->max_qcoeff = 127;
s->y_dc_scale_table =
s->c_dc_scale_table = ff_mpeg1_dc_scale_table;
+ s->ac_esc_length = 6+6+8;
+
+ init_uni_h261_rl_tab(&ff_h261_rl_tcoeff, NULL, uni_h261_rl_len);
+
+ s->intra_ac_vlc_length = s->inter_ac_vlc_length = uni_h261_rl_len;
+ s->intra_ac_vlc_last_length = s->inter_ac_vlc_last_length = uni_h261_rl_len + 128*64;
}
FF_MPV_GENERIC_CLASS(h261)
diff --git a/libavcodec/h263.c b/libavcodec/h263.c
index eda61f6..dafc4ec 100644
--- a/libavcodec/h263.c
+++ b/libavcodec/h263.c
@@ -152,8 +152,8 @@
*/
if (!IS_SKIP(s->current_picture.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);
+ s->h263dsp.h263_v_loop_filter(dest_y + 8 * linesize, linesize, qp_c);
+ s->h263dsp.h263_v_loop_filter(dest_y + 8 * linesize + 8, linesize, qp_c);
}else
qp_c= 0;
@@ -172,15 +172,15 @@
if(qp_tc){
const int chroma_qp= s->chroma_qscale_table[qp_tc];
- s->dsp.h263_v_loop_filter(dest_y , linesize, qp_tc);
- s->dsp.h263_v_loop_filter(dest_y+8, linesize, qp_tc);
+ s->h263dsp.h263_v_loop_filter(dest_y, linesize, qp_tc);
+ s->h263dsp.h263_v_loop_filter(dest_y + 8, linesize, qp_tc);
- s->dsp.h263_v_loop_filter(dest_cb , uvlinesize, chroma_qp);
- s->dsp.h263_v_loop_filter(dest_cr , uvlinesize, chroma_qp);
+ s->h263dsp.h263_v_loop_filter(dest_cb, uvlinesize, chroma_qp);
+ s->h263dsp.h263_v_loop_filter(dest_cr, uvlinesize, chroma_qp);
}
if(qp_tt)
- s->dsp.h263_h_loop_filter(dest_y-8*linesize+8 , linesize, qp_tt);
+ s->h263dsp.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]))
@@ -190,17 +190,17 @@
if(qp_dt){
const int chroma_qp= s->chroma_qscale_table[qp_dt];
- s->dsp.h263_h_loop_filter(dest_y -8*linesize , linesize, qp_dt);
- s->dsp.h263_h_loop_filter(dest_cb-8*uvlinesize, uvlinesize, chroma_qp);
- s->dsp.h263_h_loop_filter(dest_cr-8*uvlinesize, uvlinesize, chroma_qp);
+ s->h263dsp.h263_h_loop_filter(dest_y - 8 * linesize, linesize, qp_dt);
+ s->h263dsp.h263_h_loop_filter(dest_cb - 8 * uvlinesize, uvlinesize, chroma_qp);
+ s->h263dsp.h263_h_loop_filter(dest_cr - 8 * uvlinesize, uvlinesize, chroma_qp);
}
}
}
if(qp_c){
- s->dsp.h263_h_loop_filter(dest_y +8, linesize, qp_c);
+ s->h263dsp.h263_h_loop_filter(dest_y + 8, linesize, qp_c);
if(s->mb_y + 1 == s->mb_height)
- s->dsp.h263_h_loop_filter(dest_y+8*linesize+8, linesize, qp_c);
+ s->h263dsp.h263_h_loop_filter(dest_y + 8 * linesize + 8, linesize, qp_c);
}
if(s->mb_x){
@@ -211,12 +211,12 @@
qp_lc = s->current_picture.qscale_table[xy - 1];
if(qp_lc){
- s->dsp.h263_h_loop_filter(dest_y, linesize, qp_lc);
+ s->h263dsp.h263_h_loop_filter(dest_y, linesize, qp_lc);
if(s->mb_y + 1 == s->mb_height){
const int chroma_qp= s->chroma_qscale_table[qp_lc];
- s->dsp.h263_h_loop_filter(dest_y +8* linesize, linesize, qp_lc);
- s->dsp.h263_h_loop_filter(dest_cb , uvlinesize, chroma_qp);
- s->dsp.h263_h_loop_filter(dest_cr , uvlinesize, chroma_qp);
+ s->h263dsp.h263_h_loop_filter(dest_y + 8 * linesize, linesize, qp_lc);
+ s->h263dsp.h263_h_loop_filter(dest_cb, uvlinesize, chroma_qp);
+ s->h263dsp.h263_h_loop_filter(dest_cr, uvlinesize, chroma_qp);
}
}
}
diff --git a/libavcodec/h263.h b/libavcodec/h263.h
index 0995494..962d44c 100644
--- a/libavcodec/h263.h
+++ b/libavcodec/h263.h
@@ -26,6 +26,10 @@
#include "mpegvideo.h"
#include "rl.h"
+#if !FF_API_ASPECT_EXTENDED
+#define FF_ASPECT_EXTENDED 15
+#endif
+
// The defines below define the number of bits that are read at once for
// reading vlc values. Changing these may improve speed and data cache needs
// be aware though that decreasing them may need the number of stages that is
@@ -116,7 +120,6 @@
void ff_clean_h263_qscales(MpegEncContext *s);
int ff_h263_resync(MpegEncContext *s);
-const uint8_t *ff_h263_find_resync_marker(MpegEncContext *s, const uint8_t *p, const uint8_t *end);
int ff_h263_get_gob_height(MpegEncContext *s);
void ff_h263_encode_motion(MpegEncContext * s, int val, int f_code);
diff --git a/libavcodec/h263data.h b/libavcodec/h263data.h
index e245e2f..1cd965f 100644
--- a/libavcodec/h263data.h
+++ b/libavcodec/h263data.h
@@ -272,11 +272,6 @@
6, 7, 9, 11, 13, 14, 14
};
-const uint8_t ff_h263_loop_filter_strength[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, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9,10,10,10,11,11,11,12,12,12
-};
-
const AVRational ff_h263_pixel_aspect[16]={
{0, 1},
{1, 1},
diff --git a/libavcodec/h263dec.c b/libavcodec/h263dec.c
index acb08ec..1fbc08a 100644
--- a/libavcodec/h263dec.c
+++ b/libavcodec/h263dec.c
@@ -26,78 +26,77 @@
*/
#include "libavutil/cpu.h"
-#include "internal.h"
#include "avcodec.h"
#include "error_resilience.h"
-#include "mpegvideo.h"
+#include "flv.h"
#include "h263.h"
#include "h263_parser.h"
+#include "internal.h"
+#include "mpeg4video.h"
#include "mpeg4video_parser.h"
+#include "mpegvideo.h"
#include "msmpeg4.h"
#include "vdpau_internal.h"
#include "thread.h"
-#include "flv.h"
-#include "mpeg4video.h"
av_cold int ff_h263_decode_init(AVCodecContext *avctx)
{
MpegEncContext *s = avctx->priv_data;
int ret;
- s->avctx = avctx;
- s->out_format = FMT_H263;
-
- s->width = avctx->coded_width;
- s->height = avctx->coded_height;
- s->workaround_bugs= avctx->workaround_bugs;
+ s->avctx = avctx;
+ s->out_format = FMT_H263;
+ s->width = avctx->coded_width;
+ s->height = avctx->coded_height;
+ s->workaround_bugs = avctx->workaround_bugs;
// set defaults
ff_MPV_decode_defaults(s);
- s->quant_precision=5;
- s->decode_mb= ff_h263_decode_mb;
- s->low_delay= 1;
+ s->quant_precision = 5;
+ s->decode_mb = ff_h263_decode_mb;
+ s->low_delay = 1;
if (avctx->codec->id == AV_CODEC_ID_MSS2)
avctx->pix_fmt = AV_PIX_FMT_YUV420P;
else
avctx->pix_fmt = avctx->get_format(avctx, avctx->codec->pix_fmts);
- s->unrestricted_mv= 1;
+ s->unrestricted_mv = 1;
/* select sub codec */
- switch(avctx->codec->id) {
+ switch (avctx->codec->id) {
case AV_CODEC_ID_H263:
case AV_CODEC_ID_H263P:
- s->unrestricted_mv= 0;
+ s->unrestricted_mv = 0;
avctx->chroma_sample_location = AVCHROMA_LOC_CENTER;
break;
case AV_CODEC_ID_MPEG4:
break;
case AV_CODEC_ID_MSMPEG4V1:
- s->h263_pred = 1;
- s->msmpeg4_version=1;
+ s->h263_pred = 1;
+ s->msmpeg4_version = 1;
break;
case AV_CODEC_ID_MSMPEG4V2:
- s->h263_pred = 1;
- s->msmpeg4_version=2;
+ s->h263_pred = 1;
+ s->msmpeg4_version = 2;
break;
case AV_CODEC_ID_MSMPEG4V3:
- s->h263_pred = 1;
- s->msmpeg4_version=3;
+ s->h263_pred = 1;
+ s->msmpeg4_version = 3;
break;
case AV_CODEC_ID_WMV1:
- s->h263_pred = 1;
- s->msmpeg4_version=4;
+ s->h263_pred = 1;
+ s->msmpeg4_version = 4;
break;
case AV_CODEC_ID_WMV2:
- s->h263_pred = 1;
- s->msmpeg4_version=5;
+ s->h263_pred = 1;
+ s->msmpeg4_version = 5;
break;
case AV_CODEC_ID_VC1:
case AV_CODEC_ID_WMV3:
case AV_CODEC_ID_VC1IMAGE:
case AV_CODEC_ID_WMV3IMAGE:
case AV_CODEC_ID_MSS2:
- s->h263_pred = 1;
- s->msmpeg4_version=6;
+ s->h263_pred = 1;
+ s->msmpeg4_version = 6;
avctx->chroma_sample_location = AVCHROMA_LOC_LEFT;
break;
case AV_CODEC_ID_H263I:
@@ -106,20 +105,25 @@
s->h263_flv = 1;
break;
default:
- return AVERROR(EINVAL);
+ av_log(avctx, AV_LOG_ERROR, "Unsupported codec %d\n",
+ avctx->codec->id);
+ return AVERROR(ENOSYS);
}
- s->codec_id= avctx->codec->id;
- avctx->hwaccel= ff_find_hwaccel(avctx->codec->id, avctx->pix_fmt);
+ s->codec_id = avctx->codec->id;
+ avctx->hwaccel = ff_find_hwaccel(avctx);
if (avctx->stream_codec_tag == AV_RL32("l263") && avctx->extradata_size == 56 && avctx->extradata[0] == 1)
s->ehc_mode = 1;
/* for h263, we allocate the images after having read the header */
- if (avctx->codec->id != AV_CODEC_ID_H263 && avctx->codec->id != AV_CODEC_ID_H263P && avctx->codec->id != AV_CODEC_ID_MPEG4)
+ if (avctx->codec->id != AV_CODEC_ID_H263 &&
+ avctx->codec->id != AV_CODEC_ID_H263P &&
+ avctx->codec->id != AV_CODEC_ID_MPEG4)
if ((ret = ff_MPV_common_init(s)) < 0)
return ret;
- ff_h263_decode_init_vlc();
+ ff_h263dsp_init(&s->h263dsp);
+ ff_h263_decode_init_vlc();
return 0;
}
@@ -135,235 +139,251 @@
/**
* 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;
+static int get_consumed_bytes(MpegEncContext *s, int buf_size)
+{
+ int pos = (get_bits_count(&s->gb) + 7) >> 3;
- if(s->divx_packed || s->avctx->hwaccel){
- //we would have to scan through the whole buf to handle the weird reordering ...
+ if (s->divx_packed || s->avctx->hwaccel) {
+ /* We would have to scan through the whole buf to handle the weird
+ * reordering ... */
return buf_size;
- }else if(s->flags&CODEC_FLAG_TRUNCATED){
+ } else if (s->flags & CODEC_FLAG_TRUNCATED) {
pos -= s->parse_context.last_index;
- if(pos<0) pos=0; // padding is not really read so this might be -1
+ // padding is not really read so this might be -1
+ if (pos < 0)
+ pos = 0;
return pos;
- }else{
- if(pos==0) pos=1; //avoid infinite loops (i doubt that is needed but ...)
- if(pos+10>buf_size) pos=buf_size; // oops ;)
+ } else {
+ // avoid infinite loops (maybe not needed...)
+ if (pos == 0)
+ pos = 1;
+ // oops ;)
+ if (pos + 10 > buf_size)
+ pos = buf_size;
return pos;
}
}
-static int decode_slice(MpegEncContext *s){
- const int part_mask= s->partitioned_frame ? (ER_AC_END|ER_AC_ERROR) : 0x7F;
- const int mb_size= 16>>s->avctx->lowres;
+static int decode_slice(MpegEncContext *s)
+{
+ const int part_mask = s->partitioned_frame
+ ? (ER_AC_END | ER_AC_ERROR) : 0x7F;
+ const int mb_size = 16 >> s->avctx->lowres;
int ret;
- s->last_resync_gb= s->gb;
- s->first_slice_line= 1;
-
- s->resync_mb_x= s->mb_x;
- s->resync_mb_y= s->mb_y;
+ s->last_resync_gb = s->gb;
+ s->first_slice_line = 1;
+ s->resync_mb_x = s->mb_x;
+ s->resync_mb_y = s->mb_y;
ff_set_qscale(s, s->qscale);
if (s->avctx->hwaccel) {
- const uint8_t *start= s->gb.buffer + get_bits_count(&s->gb)/8;
+ const uint8_t *start = s->gb.buffer + get_bits_count(&s->gb) / 8;
ret = s->avctx->hwaccel->decode_slice(s->avctx, start, s->gb.buffer_end - start);
// ensure we exit decode loop
s->mb_y = s->mb_height;
return ret;
}
- if(s->partitioned_frame){
- const int qscale= s->qscale;
+ if (s->partitioned_frame) {
+ const int qscale = s->qscale;
- if(CONFIG_MPEG4_DECODER && s->codec_id==AV_CODEC_ID_MPEG4){
- if ((ret = ff_mpeg4_decode_partitions(s)) < 0)
+ if (CONFIG_MPEG4_DECODER && s->codec_id == AV_CODEC_ID_MPEG4)
+ if ((ret = ff_mpeg4_decode_partitions(s->avctx->priv_data)) < 0)
return ret;
- }
/* restore variables which were modified */
- s->first_slice_line=1;
- s->mb_x= s->resync_mb_x;
- s->mb_y= s->resync_mb_y;
+ s->first_slice_line = 1;
+ s->mb_x = s->resync_mb_x;
+ s->mb_y = s->resync_mb_y;
ff_set_qscale(s, qscale);
}
- for(; s->mb_y < s->mb_height; s->mb_y++) {
+ for (; s->mb_y < s->mb_height; s->mb_y++) {
/* 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->er, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, ER_MB_END);
+ if (s->msmpeg4_version) {
+ if (s->resync_mb_y + s->slice_height == s->mb_y) {
+ ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y,
+ s->mb_x - 1, s->mb_y, ER_MB_END);
return 0;
}
}
- if(s->msmpeg4_version==1){
- s->last_dc[0]=
- s->last_dc[1]=
- s->last_dc[2]= 128;
+ if (s->msmpeg4_version == 1) {
+ s->last_dc[0] =
+ s->last_dc[1] =
+ s->last_dc[2] = 128;
}
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++) {
int ret;
ff_update_block_index(s);
- if(s->resync_mb_x == s->mb_x && s->resync_mb_y+1 == s->mb_y){
- s->first_slice_line=0;
- }
+ if (s->resync_mb_x == s->mb_x && s->resync_mb_y + 1 == s->mb_y)
+ s->first_slice_line = 0;
/* DCT & quantize */
- s->mv_dir = MV_DIR_FORWARD;
+ s->mv_dir = MV_DIR_FORWARD;
s->mv_type = MV_TYPE_16X16;
-// s->mb_skipped = 0;
av_dlog(s, "%d %d %06X\n",
ret, get_bits_count(&s->gb), show_bits(&s->gb, 24));
- ret= s->decode_mb(s, s->block);
+ ret = s->decode_mb(s, s->block);
- if (s->pict_type!=AV_PICTURE_TYPE_B)
+ if (s->pict_type != AV_PICTURE_TYPE_B)
ff_h263_update_motion_val(s);
- if(ret<0){
- const int xy= s->mb_x + s->mb_y*s->mb_stride;
- if(ret==SLICE_END){
+ if (ret < 0) {
+ const int xy = s->mb_x + s->mb_y * s->mb_stride;
+ if (ret == SLICE_END) {
ff_MPV_decode_mb(s, s->block);
- if(s->loop_filter)
+ if (s->loop_filter)
ff_h263_loop_filter(s);
- ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, ER_MB_END&part_mask);
+ ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y,
+ s->mb_x, s->mb_y, ER_MB_END & part_mask);
s->padding_bug_score--;
- if(++s->mb_x >= s->mb_width){
- s->mb_x=0;
- ff_mpeg_draw_horiz_band(s, s->mb_y*mb_size, mb_size);
+ if (++s->mb_x >= s->mb_width) {
+ s->mb_x = 0;
+ ff_mpeg_draw_horiz_band(s, s->mb_y * mb_size, mb_size);
ff_MPV_report_decode_progress(s);
s->mb_y++;
}
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->er, s->resync_mb_x, s->resync_mb_y, s->mb_x+1, s->mb_y, ER_MB_END&part_mask);
+ } else if (ret == SLICE_NOEND) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "Slice mismatch at MB: %d\n", xy);
+ ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y,
+ s->mb_x + 1, s->mb_y,
+ ER_MB_END & part_mask);
return AVERROR_INVALIDDATA;
}
av_log(s->avctx, AV_LOG_ERROR, "Error at MB: %d\n", xy);
- ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, ER_MB_ERROR&part_mask);
+ ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y,
+ s->mb_x, s->mb_y, ER_MB_ERROR & part_mask);
return AVERROR_INVALIDDATA;
}
ff_MPV_decode_mb(s, s->block);
- if(s->loop_filter)
+ if (s->loop_filter)
ff_h263_loop_filter(s);
}
- ff_mpeg_draw_horiz_band(s, s->mb_y*mb_size, mb_size);
+ ff_mpeg_draw_horiz_band(s, s->mb_y * mb_size, mb_size);
ff_MPV_report_decode_progress(s);
- s->mb_x= 0;
+ s->mb_x = 0;
}
- av_assert1(s->mb_x==0 && s->mb_y==s->mb_height);
+ av_assert1(s->mb_x == 0 && s->mb_y == s->mb_height);
- if(s->codec_id==AV_CODEC_ID_MPEG4
- && (s->workaround_bugs&FF_BUG_AUTODETECT)
- && get_bits_left(&s->gb) >= 48
- && show_bits(&s->gb, 24)==0x4010
- && !s->data_partitioning)
- s->padding_bug_score+=32;
+ if (s->codec_id == AV_CODEC_ID_MPEG4 &&
+ (s->workaround_bugs & FF_BUG_AUTODETECT) &&
+ get_bits_left(&s->gb) >= 48 &&
+ show_bits(&s->gb, 24) == 0x4010 &&
+ !s->data_partitioning)
+ s->padding_bug_score += 32;
/* try to detect the padding bug */
- if( s->codec_id==AV_CODEC_ID_MPEG4
- && (s->workaround_bugs&FF_BUG_AUTODETECT)
- && get_bits_left(&s->gb) >=0
- && get_bits_left(&s->gb) < 137
-// && !s->resync_marker
- && !s->data_partitioning){
+ if (s->codec_id == AV_CODEC_ID_MPEG4 &&
+ (s->workaround_bugs & FF_BUG_AUTODETECT) &&
+ get_bits_left(&s->gb) >= 0 &&
+ get_bits_left(&s->gb) < 137 &&
+ !s->data_partitioning) {
+ const int bits_count = get_bits_count(&s->gb);
+ const int bits_left = s->gb.size_in_bits - bits_count;
- const int bits_count= get_bits_count(&s->gb);
- const int bits_left = s->gb.size_in_bits - bits_count;
+ if (bits_left == 0) {
+ s->padding_bug_score += 16;
+ } else if (bits_left != 1) {
+ int v = show_bits(&s->gb, 8);
+ v |= 0x7F >> (7 - (bits_count & 7));
- if(bits_left==0){
- s->padding_bug_score+=16;
- } else if(bits_left != 1){
- int v= show_bits(&s->gb, 8);
- v|= 0x7F >> (7-(bits_count&7));
-
- if(v==0x7F && bits_left<=8)
+ if (v == 0x7F && bits_left <= 8)
s->padding_bug_score--;
- else if(v==0x7F && ((get_bits_count(&s->gb)+8)&8) && bits_left<=16)
- s->padding_bug_score+= 4;
+ else if (v == 0x7F && ((get_bits_count(&s->gb) + 8) & 8) &&
+ bits_left <= 16)
+ s->padding_bug_score += 4;
else
s->padding_bug_score++;
}
}
- if(s->workaround_bugs&FF_BUG_AUTODETECT){
- if(s->padding_bug_score > -2 && !s->data_partitioning /*&& (s->divx_version>=0 || !s->resync_marker)*/)
- s->workaround_bugs |= FF_BUG_NO_PADDING;
+ if (s->workaround_bugs & FF_BUG_AUTODETECT) {
+ if (s->padding_bug_score > -2 && !s->data_partitioning)
+ s->workaround_bugs |= FF_BUG_NO_PADDING;
else
s->workaround_bugs &= ~FF_BUG_NO_PADDING;
}
// handle formats which don't have unique end markers
- if(s->msmpeg4_version || (s->workaround_bugs&FF_BUG_NO_PADDING)){ //FIXME perhaps solve this more cleanly
- int left= get_bits_left(&s->gb);
- int max_extra=7;
+ if (s->msmpeg4_version || (s->workaround_bugs & FF_BUG_NO_PADDING)) { // FIXME perhaps solve this more cleanly
+ int left = get_bits_left(&s->gb);
+ int max_extra = 7;
/* no markers in M$ crap */
- if(s->msmpeg4_version && s->pict_type==AV_PICTURE_TYPE_I)
- max_extra+= 17;
+ if (s->msmpeg4_version && s->pict_type == AV_PICTURE_TYPE_I)
+ 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->err_recognition&(AV_EF_BUFFER|AV_EF_AGGRESSIVE)))
- max_extra+= 48;
- else if((s->workaround_bugs&FF_BUG_NO_PADDING))
- max_extra+= 256*256*256*64;
+ /* buggy padding but the frame should still end approximately at
+ * the bitstream end */
+ if ((s->workaround_bugs & FF_BUG_NO_PADDING) &&
+ (s->err_recognition & (AV_EF_BUFFER|AV_EF_AGGRESSIVE)))
+ max_extra += 48;
+ else if ((s->workaround_bugs & FF_BUG_NO_PADDING))
+ max_extra += 256 * 256 * 256 * 64;
- if(left>max_extra){
- av_log(s->avctx, AV_LOG_ERROR, "discarding %d junk bits at end, next would be %X\n", left, show_bits(&s->gb, 24));
- }
- else if(left<0){
+ if (left > max_extra)
+ av_log(s->avctx, AV_LOG_ERROR,
+ "discarding %d junk bits at end, next would be %X\n",
+ left, show_bits(&s->gb, 24));
+ else if (left < 0)
av_log(s->avctx, AV_LOG_ERROR, "overreading %d bits\n", -left);
- }else
- ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, ER_MB_END);
+ else
+ ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y,
+ s->mb_x - 1, s->mb_y, ER_MB_END);
return 0;
}
- av_log(s->avctx, AV_LOG_ERROR, "slice end not reached but screenspace end (%d left %06X, score= %d)\n",
- get_bits_left(&s->gb),
- show_bits(&s->gb, 24), s->padding_bug_score);
+ av_log(s->avctx, AV_LOG_ERROR,
+ "slice end not reached but screenspace end (%d left %06X, score= %d)\n",
+ get_bits_left(&s->gb), show_bits(&s->gb, 24), s->padding_bug_score);
- ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, ER_MB_END&part_mask);
+ ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y,
+ ER_MB_END & part_mask);
return AVERROR_INVALIDDATA;
}
-int ff_h263_decode_frame(AVCodecContext *avctx,
- void *data, int *got_frame,
- AVPacket *avpkt)
+int ff_h263_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
+ AVPacket *avpkt)
{
const uint8_t *buf = avpkt->data;
- int buf_size = avpkt->size;
- MpegEncContext *s = avctx->priv_data;
+ int buf_size = avpkt->size;
+ MpegEncContext *s = avctx->priv_data;
int ret;
+ int slice_ret = 0;
AVFrame *pict = data;
- s->flags= avctx->flags;
- s->flags2= avctx->flags2;
+ s->flags = avctx->flags;
+ s->flags2 = avctx->flags2;
/* no supplementary picture */
if (buf_size == 0) {
/* special case for last picture */
- if (s->low_delay==0 && s->next_picture_ptr) {
+ if (s->low_delay == 0 && s->next_picture_ptr) {
if ((ret = av_frame_ref(pict, &s->next_picture_ptr->f)) < 0)
return ret;
- s->next_picture_ptr= NULL;
+ s->next_picture_ptr = NULL;
*got_frame = 1;
}
@@ -371,72 +391,77 @@
return 0;
}
- if(s->flags&CODEC_FLAG_TRUNCATED){
+ if (s->flags & CODEC_FLAG_TRUNCATED) {
int next;
- if(CONFIG_MPEG4_DECODER && s->codec_id==AV_CODEC_ID_MPEG4){
- next= ff_mpeg4_find_frame_end(&s->parse_context, buf, buf_size);
- }else if(CONFIG_H263_DECODER && s->codec_id==AV_CODEC_ID_H263){
- next= ff_h263_find_frame_end(&s->parse_context, buf, buf_size);
- }else if(CONFIG_H263P_DECODER && s->codec_id==AV_CODEC_ID_H263P){
- next= ff_h263_find_frame_end(&s->parse_context, buf, buf_size);
- }else{
- av_log(s->avctx, AV_LOG_ERROR, "this codec does not support truncated bitstreams\n");
- return AVERROR(EINVAL);
+ if (CONFIG_MPEG4_DECODER && s->codec_id == AV_CODEC_ID_MPEG4) {
+ next = ff_mpeg4_find_frame_end(&s->parse_context, buf, buf_size);
+ } else if (CONFIG_H263_DECODER && s->codec_id == AV_CODEC_ID_H263) {
+ next = ff_h263_find_frame_end(&s->parse_context, buf, buf_size);
+ } else if (CONFIG_H263P_DECODER && s->codec_id == AV_CODEC_ID_H263P) {
+ next = ff_h263_find_frame_end(&s->parse_context, buf, buf_size);
+ } else {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "this codec does not support truncated bitstreams\n");
+ return AVERROR(ENOSYS);
}
- if( ff_combine_frame(&s->parse_context, next, (const uint8_t **)&buf, &buf_size) < 0 )
+ if (ff_combine_frame(&s->parse_context, next, (const uint8_t **)&buf,
+ &buf_size) < 0)
return buf_size;
}
-
retry:
- if(s->divx_packed && s->bitstream_buffer_size){
+ if (s->divx_packed && s->bitstream_buffer_size) {
int i;
- for(i=0; i<buf_size-3; i++){
- if(buf[i]==0 && buf[i+1]==0 && buf[i+2]==1){
- if(buf[i+3]==0xB0){
+ for(i=0; i < buf_size-3; i++) {
+ if (buf[i]==0 && buf[i+1]==0 && buf[i+2]==1) {
+ if (buf[i+3]==0xB0) {
av_log(s->avctx, AV_LOG_WARNING, "Discarding excessive bitstream in packed xvid\n");
- s->bitstream_buffer_size=0;
+ s->bitstream_buffer_size = 0;
}
break;
}
}
}
- if(s->bitstream_buffer_size && (s->divx_packed || buf_size<20)){ //divx 5.01+/xvid frame reorder
- init_get_bits(&s->gb, s->bitstream_buffer, s->bitstream_buffer_size*8);
- }else
- init_get_bits(&s->gb, buf, buf_size*8);
- s->bitstream_buffer_size=0;
+ if (s->bitstream_buffer_size && (s->divx_packed || buf_size < 20)) // divx 5.01+/xvid frame reorder
+ ret = init_get_bits8(&s->gb, s->bitstream_buffer,
+ s->bitstream_buffer_size);
+ else
+ ret = init_get_bits8(&s->gb, buf, buf_size);
- if (!s->context_initialized) {
- if ((ret = ff_MPV_common_init(s)) < 0) //we need the idct permutaton for reading a custom matrix
+ s->bitstream_buffer_size = 0;
+ if (ret < 0)
+ return ret;
+
+ if (!s->context_initialized)
+ // we need the idct permutaton for reading a custom matrix
+ if ((ret = ff_MPV_common_init(s)) < 0)
return ret;
- }
/* 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->f.data[0]) {
- int i= ff_find_unused_picture(s, 0);
+ int i = ff_find_unused_picture(s, 0);
if (i < 0)
return i;
- s->current_picture_ptr= &s->picture[i];
+ s->current_picture_ptr = &s->picture[i];
}
/* let's go :-) */
- if (CONFIG_WMV2_DECODER && s->msmpeg4_version==5) {
- ret= ff_wmv2_decode_picture_header(s);
+ if (CONFIG_WMV2_DECODER && s->msmpeg4_version == 5) {
+ ret = ff_wmv2_decode_picture_header(s);
} else if (CONFIG_MSMPEG4_DECODER && s->msmpeg4_version) {
ret = ff_msmpeg4_decode_picture_header(s);
- } else if (CONFIG_MPEG4_DECODER && s->h263_pred) {
- if(s->avctx->extradata_size && s->picture_number==0){
+ } else if (CONFIG_MPEG4_DECODER && avctx->codec_id == AV_CODEC_ID_MPEG4) {
+ if (s->avctx->extradata_size && s->picture_number == 0) {
GetBitContext gb;
- init_get_bits(&gb, s->avctx->extradata, s->avctx->extradata_size*8);
- ret = ff_mpeg4_decode_picture_header(s, &gb);
+ if (init_get_bits8(&gb, s->avctx->extradata, s->avctx->extradata_size) >= 0 )
+ ff_mpeg4_decode_picture_header(avctx->priv_data, &gb);
}
- ret = ff_mpeg4_decode_picture_header(s, &s->gb);
+ ret = ff_mpeg4_decode_picture_header(avctx->priv_data, &s->gb);
} else if (CONFIG_H263I_DECODER && s->codec_id == AV_CODEC_ID_H263I) {
ret = ff_intel_h263_decode_picture_header(s);
} else if (CONFIG_FLV_DECODER && s->h263_flv) {
@@ -445,7 +470,7 @@
ret = ff_h263_decode_picture_header(s);
}
- if (ret < 0 || ret==FRAME_SKIPPED) {
+ if (ret < 0 || ret == FRAME_SKIPPED) {
if ( s->width != avctx->coded_width
|| s->height != avctx->coded_height) {
av_log(s->avctx, AV_LOG_WARNING, "Reverting picture dimensions change due to header decoding failure\n");
@@ -453,160 +478,43 @@
s->height= avctx->coded_height;
}
}
- if(ret==FRAME_SKIPPED) return get_consumed_bytes(s, buf_size);
+ if (ret == FRAME_SKIPPED)
+ return get_consumed_bytes(s, buf_size);
/* skip if the header was thrashed */
- if (ret < 0){
+ if (ret < 0) {
av_log(s->avctx, AV_LOG_ERROR, "header damaged\n");
return ret;
}
- avctx->has_b_frames= !s->low_delay;
+ avctx->has_b_frames = !s->low_delay;
- if(s->xvid_build==-1 && s->divx_version==-1 && s->lavc_build==-1){
- if(s->stream_codec_tag == AV_RL32("XVID") ||
- s->codec_tag == AV_RL32("XVID") || s->codec_tag == AV_RL32("XVIX") ||
- s->codec_tag == AV_RL32("RMP4") || s->codec_tag == AV_RL32("ZMP4") ||
- s->codec_tag == AV_RL32("SIPP")
- )
- s->xvid_build= 0;
-#if 0
- if(s->codec_tag == AV_RL32("DIVX") && s->vo_type==0 && s->vol_control_parameters==1
- && s->padding_bug_score > 0 && s->low_delay) // XVID with modified fourcc
- s->xvid_build= 0;
-#endif
+ if (CONFIG_MPEG4_DECODER && avctx->codec_id == AV_CODEC_ID_MPEG4) {
+ if (ff_mpeg4_workaround_bugs(avctx) == 1)
+ goto retry;
}
- if(s->xvid_build==-1 && s->divx_version==-1 && s->lavc_build==-1){
- if(s->codec_tag == AV_RL32("DIVX") && s->vo_type==0 && s->vol_control_parameters==0)
- s->divx_version= 400; //divx 4
- }
-
- if(s->xvid_build>=0 && s->divx_version>=0){
- s->divx_version=
- s->divx_build= -1;
- }
-
- if(s->workaround_bugs&FF_BUG_AUTODETECT){
- if(s->codec_tag == AV_RL32("XVIX"))
- s->workaround_bugs|= FF_BUG_XVID_ILACE;
-
- if(s->codec_tag == AV_RL32("UMP4")){
- s->workaround_bugs|= FF_BUG_UMP4;
- }
-
- if(s->divx_version>=500 && s->divx_build<1814){
- s->workaround_bugs|= FF_BUG_QPEL_CHROMA;
- }
-
- if(s->divx_version>502 && s->divx_build<1814){
- s->workaround_bugs|= FF_BUG_QPEL_CHROMA2;
- }
-
- if(s->xvid_build<=3U)
- s->padding_bug_score= 256*256*256*64;
-
- if(s->xvid_build<=1U)
- s->workaround_bugs|= FF_BUG_QPEL_CHROMA;
-
- if(s->xvid_build<=12U)
- s->workaround_bugs|= FF_BUG_EDGE;
-
- if(s->xvid_build<=32U)
- s->workaround_bugs|= FF_BUG_DC_CLIP;
-
-#define SET_QPEL_FUNC(postfix1, postfix2) \
- s->dsp.put_ ## postfix1 = ff_put_ ## postfix2;\
- s->dsp.put_no_rnd_ ## postfix1 = ff_put_no_rnd_ ## postfix2;\
- s->dsp.avg_ ## postfix1 = ff_avg_ ## postfix2;
-
- if(s->lavc_build<4653U)
- s->workaround_bugs|= FF_BUG_STD_QPEL;
-
- if(s->lavc_build<4655U)
- s->workaround_bugs|= FF_BUG_DIRECT_BLOCKSIZE;
-
- if(s->lavc_build<4670U){
- s->workaround_bugs|= FF_BUG_EDGE;
- }
-
- if(s->lavc_build<=4712U)
- s->workaround_bugs|= FF_BUG_DC_CLIP;
-
- if(s->divx_version>=0)
- s->workaround_bugs|= FF_BUG_DIRECT_BLOCKSIZE;
- if(s->divx_version==501 && s->divx_build==20020416)
- s->padding_bug_score= 256*256*256*64;
-
- if(s->divx_version<500U){
- s->workaround_bugs|= FF_BUG_EDGE;
- }
-
- if(s->divx_version>=0)
- s->workaround_bugs|= FF_BUG_HPEL_CHROMA;
-#if 0
- if(s->divx_version==500)
- s->padding_bug_score= 256*256*256*64;
-
- /* very ugly XVID padding bug detection FIXME/XXX solve this differently
- * Let us hope this at least works.
- */
- if( s->resync_marker==0 && s->data_partitioning==0 && s->divx_version==-1
- && s->codec_id==AV_CODEC_ID_MPEG4 && s->vo_type==0)
- s->workaround_bugs|= FF_BUG_NO_PADDING;
-
- if(s->lavc_build<4609U) //FIXME not sure about the version num but a 4609 file seems ok
- s->workaround_bugs|= FF_BUG_NO_PADDING;
-#endif
- }
-
- if(s->workaround_bugs& FF_BUG_STD_QPEL){
- SET_QPEL_FUNC(qpel_pixels_tab[0][ 5], qpel16_mc11_old_c)
- SET_QPEL_FUNC(qpel_pixels_tab[0][ 7], qpel16_mc31_old_c)
- SET_QPEL_FUNC(qpel_pixels_tab[0][ 9], qpel16_mc12_old_c)
- SET_QPEL_FUNC(qpel_pixels_tab[0][11], qpel16_mc32_old_c)
- SET_QPEL_FUNC(qpel_pixels_tab[0][13], qpel16_mc13_old_c)
- SET_QPEL_FUNC(qpel_pixels_tab[0][15], qpel16_mc33_old_c)
-
- SET_QPEL_FUNC(qpel_pixels_tab[1][ 5], qpel8_mc11_old_c)
- SET_QPEL_FUNC(qpel_pixels_tab[1][ 7], qpel8_mc31_old_c)
- SET_QPEL_FUNC(qpel_pixels_tab[1][ 9], qpel8_mc12_old_c)
- SET_QPEL_FUNC(qpel_pixels_tab[1][11], qpel8_mc32_old_c)
- SET_QPEL_FUNC(qpel_pixels_tab[1][13], qpel8_mc13_old_c)
- SET_QPEL_FUNC(qpel_pixels_tab[1][15], qpel8_mc33_old_c)
- }
-
- if(avctx->debug & FF_DEBUG_BUGS)
- av_log(s->avctx, AV_LOG_DEBUG, "bugs: %X lavc_build:%d xvid_build:%d divx_version:%d divx_build:%d %s\n",
- s->workaround_bugs, s->lavc_build, s->xvid_build, s->divx_version, s->divx_build,
- s->divx_packed ? "p" : "");
-
-#if HAVE_MMX
- if (s->codec_id == AV_CODEC_ID_MPEG4 && s->xvid_build>=0 && avctx->idct_algo == FF_IDCT_AUTO && (av_get_cpu_flags() & AV_CPU_FLAG_MMX)) {
- avctx->idct_algo= FF_IDCT_XVIDMMX;
- ff_dct_common_init(s);
- goto retry;
- }
-#endif
-
- /* After H263 & mpeg4 header decode we have the height, width,*/
- /* and other parameters. So then we could init the picture */
- /* FIXME: By the way H263 decoder is evolving it should have */
- /* an H263EncContext */
-
+ /* After H263 & mpeg4 header decode we have the height, width,
+ * and other parameters. So then we could init the picture.
+ * FIXME: By the way H263 decoder is evolving it should have
+ * an H263EncContext */
if (s->width != avctx->coded_width ||
s->height != avctx->coded_height ||
s->context_reinit) {
/* H.263 could change picture size any time */
s->context_reinit = 0;
- avcodec_set_dimensions(avctx, s->width, s->height);
+ ret = ff_set_dimensions(avctx, s->width, s->height);
+ if (ret < 0)
+ return ret;
if ((ret = ff_MPV_common_frame_size_change(s)))
return ret;
}
- if((s->codec_id==AV_CODEC_ID_H263 || s->codec_id==AV_CODEC_ID_H263P || s->codec_id == AV_CODEC_ID_H263I))
+ if (s->codec_id == AV_CODEC_ID_H263 ||
+ s->codec_id == AV_CODEC_ID_H263P ||
+ s->codec_id == AV_CODEC_ID_H263I)
s->gob_index = ff_h263_get_gob_height(s);
// for skipping the frame
@@ -617,24 +525,26 @@
if (s->last_picture_ptr == NULL &&
(s->pict_type == AV_PICTURE_TYPE_B || s->droppable))
return get_consumed_bytes(s, buf_size);
- 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)
return get_consumed_bytes(s, buf_size);
- 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)
return get_consumed_bytes(s, buf_size);
else
- s->next_p_frame_damaged=0;
+ s->next_p_frame_damaged = 0;
}
- if((!s->no_rounding) || s->pict_type==AV_PICTURE_TYPE_B){
- s->me.qpel_put= s->dsp.put_qpel_pixels_tab;
- s->me.qpel_avg= s->dsp.avg_qpel_pixels_tab;
- }else{
- s->me.qpel_put= s->dsp.put_no_rnd_qpel_pixels_tab;
- s->me.qpel_avg= s->dsp.avg_qpel_pixels_tab;
+ if ((!s->no_rounding) || s->pict_type == AV_PICTURE_TYPE_B) {
+ s->me.qpel_put = s->dsp.put_qpel_pixels_tab;
+ s->me.qpel_avg = s->dsp.avg_qpel_pixels_tab;
+ } else {
+ s->me.qpel_put = s->dsp.put_no_rnd_qpel_pixels_tab;
+ s->me.qpel_avg = s->dsp.avg_qpel_pixels_tab;
}
if ((ret = ff_MPV_frame_start(s, avctx)) < 0)
@@ -649,87 +559,70 @@
}
if (avctx->hwaccel) {
- if ((ret = avctx->hwaccel->start_frame(avctx, s->gb.buffer, s->gb.buffer_end - s->gb.buffer)) < 0)
+ ret = avctx->hwaccel->start_frame(avctx, s->gb.buffer,
+ s->gb.buffer_end - s->gb.buffer);
+ if (ret < 0 )
return ret;
}
ff_mpeg_er_frame_start(s);
- //the second part of the wmv2 header contains the MB skip bits which are stored in current_picture->mb_type
- //which is not available before ff_MPV_frame_start()
- if (CONFIG_WMV2_DECODER && s->msmpeg4_version==5){
+ /* the second part of the wmv2 header contains the MB skip bits which
+ * are stored in current_picture->mb_type which is not available before
+ * ff_MPV_frame_start() */
+ if (CONFIG_WMV2_DECODER && s->msmpeg4_version == 5) {
ret = ff_wmv2_decode_secondary_picture_header(s);
- if(ret<0) return ret;
- if(ret==1) goto frame_end;
+ if (ret < 0)
+ return ret;
+ if (ret == 1)
+ goto frame_end;
}
/* decode each macroblock */
- s->mb_x=0;
- s->mb_y=0;
+ s->mb_x = 0;
+ s->mb_y = 0;
- 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_left(&s->gb)<0)
+ slice_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_left(&s->gb) < 0)
break;
- }else{
- int prev_x=s->mb_x, prev_y=s->mb_y;
- if(ff_h263_resync(s)<0)
+ } else {
+ int prev_x = s->mb_x, prev_y = s->mb_y;
+ if (ff_h263_resync(s) < 0)
break;
if (prev_y * s->mb_width + prev_x < s->mb_y * s->mb_width + s->mb_x)
s->er.error_occurred = 1;
}
- if(s->msmpeg4_version<4 && s->h263_pred)
+ if (s->msmpeg4_version < 4 && s->h263_pred)
ff_mpeg4_clean_buffers(s);
- if (decode_slice(s) < 0) ret = AVERROR_INVALIDDATA;
+ if (decode_slice(s) < 0)
+ slice_ret = AVERROR_INVALIDDATA;
}
- if (s->msmpeg4_version && s->msmpeg4_version<4 && s->pict_type==AV_PICTURE_TYPE_I)
- if(!CONFIG_MSMPEG4_DECODER || ff_msmpeg4_decode_ext_header(s, buf_size) < 0){
+ if (s->msmpeg4_version && s->msmpeg4_version < 4 &&
+ s->pict_type == AV_PICTURE_TYPE_I)
+ if (!CONFIG_MSMPEG4_DECODER ||
+ ff_msmpeg4_decode_ext_header(s, buf_size) < 0)
s->er.error_status_table[s->mb_num - 1] = ER_MB_ERROR;
- }
- av_assert1(s->bitstream_buffer_size==0);
+ av_assert1(s->bitstream_buffer_size == 0);
frame_end:
ff_er_frame_end(&s->er);
if (avctx->hwaccel) {
- if ((ret = avctx->hwaccel->end_frame(avctx)) < 0)
+ ret = avctx->hwaccel->end_frame(avctx);
+ if (ret < 0)
return ret;
}
ff_MPV_frame_end(s);
- /* divx 5.01+ bitstream reorder stuff */
- /* Since this clobbers the input buffer and hwaccel codecs still need the
- * data during hwaccel->end_frame we should not do this any earlier */
- if(s->codec_id==AV_CODEC_ID_MPEG4 && s->divx_packed){
- int current_pos= s->gb.buffer == s->bitstream_buffer ? 0 : (get_bits_count(&s->gb)>>3);
- int startcode_found=0;
-
- if(buf_size - current_pos > 7){
- int i;
- for(i=current_pos; i<buf_size-4; i++){
- if(buf[i]==0 && buf[i+1]==0 && buf[i+2]==1 && buf[i+3]==0xB6){
- startcode_found=!(buf[i+4]&0x40);
- break;
- }
- }
- }
-
- if(startcode_found){
- av_fast_malloc(
- &s->bitstream_buffer,
- &s->allocated_bitstream_buffer_size,
- buf_size - current_pos + FF_INPUT_BUFFER_PADDING_SIZE);
- if (!s->bitstream_buffer)
- return AVERROR(ENOMEM);
- memcpy(s->bitstream_buffer, buf + current_pos, buf_size - current_pos);
- s->bitstream_buffer_size= buf_size - current_pos;
- }
- }
+ if (CONFIG_MPEG4_DECODER && avctx->codec_id == AV_CODEC_ID_MPEG4)
+ ff_mpeg4_frame_end(avctx, buf, buf_size);
if (!s->divx_packed && avctx->hwaccel)
ff_thread_finish_setup(avctx);
@@ -748,7 +641,7 @@
ff_mpv_export_qp_table(s, pict, s->last_picture_ptr, FF_QSCALE_TYPE_MPEG1);
}
- if(s->last_picture_ptr || s->low_delay){
+ if (s->last_picture_ptr || s->low_delay) {
if ( pict->format == AV_PIX_FMT_YUV420P
&& (s->codec_tag == AV_RL32("GEOV") || s->codec_tag == AV_RL32("GEOX"))) {
int x, y, p;
@@ -767,7 +660,10 @@
*got_frame = 1;
}
- return (ret && (avctx->err_recognition & AV_EF_EXPLODE))?ret:get_consumed_bytes(s, buf_size);
+ if (slice_ret < 0 && (avctx->err_recognition & AV_EF_EXPLODE))
+ return ret;
+ else
+ return get_consumed_bytes(s, buf_size);
}
const enum AVPixelFormat ff_h263_hwaccel_pixfmt_list_420[] = {
diff --git a/libavcodec/h263dsp.c b/libavcodec/h263dsp.c
new file mode 100644
index 0000000..a70ff24
--- /dev/null
+++ b/libavcodec/h263dsp.c
@@ -0,0 +1,124 @@
+/*
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdint.h>
+
+#include "libavutil/attributes.h"
+#include "libavutil/common.h"
+#include "config.h"
+#include "h263dsp.h"
+
+const uint8_t ff_h263_loop_filter_strength[32] = {
+ 0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 7,
+ 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 11, 12, 12, 12
+};
+
+static void h263_h_loop_filter_c(uint8_t *src, int stride, int qscale)
+{
+ int y;
+ const int strength = ff_h263_loop_filter_strength[qscale];
+
+ for (y = 0; y < 8; y++) {
+ int d1, d2, ad1;
+ int p0 = src[y * stride - 2];
+ int p1 = src[y * stride - 1];
+ int p2 = src[y * stride + 0];
+ int p3 = src[y * stride + 1];
+ int d = (p0 - p3 + 4 * (p2 - p1)) / 8;
+
+ if (d < -2 * strength)
+ d1 = 0;
+ else if (d < -strength)
+ d1 = -2 * strength - d;
+ else if (d < strength)
+ d1 = d;
+ else if (d < 2 * strength)
+ d1 = 2 * strength - d;
+ else
+ d1 = 0;
+
+ p1 += d1;
+ p2 -= d1;
+ if (p1 & 256)
+ p1 = ~(p1 >> 31);
+ if (p2 & 256)
+ p2 = ~(p2 >> 31);
+
+ src[y * stride - 1] = p1;
+ src[y * stride + 0] = p2;
+
+ ad1 = FFABS(d1) >> 1;
+
+ d2 = av_clip((p0 - p3) / 4, -ad1, ad1);
+
+ src[y * stride - 2] = p0 - d2;
+ src[y * stride + 1] = p3 + d2;
+ }
+}
+
+static void h263_v_loop_filter_c(uint8_t *src, int stride, int qscale)
+{
+ int x;
+ const int strength = ff_h263_loop_filter_strength[qscale];
+
+ for (x = 0; x < 8; x++) {
+ int d1, d2, ad1;
+ int p0 = src[x - 2 * stride];
+ int p1 = src[x - 1 * stride];
+ int p2 = src[x + 0 * stride];
+ int p3 = src[x + 1 * stride];
+ int d = (p0 - p3 + 4 * (p2 - p1)) / 8;
+
+ if (d < -2 * strength)
+ d1 = 0;
+ else if (d < -strength)
+ d1 = -2 * strength - d;
+ else if (d < strength)
+ d1 = d;
+ else if (d < 2 * strength)
+ d1 = 2 * strength - d;
+ else
+ d1 = 0;
+
+ p1 += d1;
+ p2 -= d1;
+ if (p1 & 256)
+ p1 = ~(p1 >> 31);
+ if (p2 & 256)
+ p2 = ~(p2 >> 31);
+
+ src[x - 1 * stride] = p1;
+ src[x + 0 * stride] = p2;
+
+ ad1 = FFABS(d1) >> 1;
+
+ d2 = av_clip((p0 - p3) / 4, -ad1, ad1);
+
+ src[x - 2 * stride] = p0 - d2;
+ src[x + stride] = p3 + d2;
+ }
+}
+
+av_cold void ff_h263dsp_init(H263DSPContext *ctx)
+{
+ ctx->h263_h_loop_filter = h263_h_loop_filter_c;
+ ctx->h263_v_loop_filter = h263_v_loop_filter_c;
+
+ if (ARCH_X86)
+ ff_h263dsp_init_x86(ctx);
+}
diff --git a/libavcodec/h263dsp.h b/libavcodec/h263dsp.h
new file mode 100644
index 0000000..d2cc2ff
--- /dev/null
+++ b/libavcodec/h263dsp.h
@@ -0,0 +1,34 @@
+/*
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVCODEC_H263DSP_H
+#define AVCODEC_H263DSP_H
+
+#include <stdint.h>
+
+extern const uint8_t ff_h263_loop_filter_strength[32];
+
+typedef struct H263DSPContext {
+ void (*h263_h_loop_filter)(uint8_t *src, int stride, int qscale);
+ void (*h263_v_loop_filter)(uint8_t *src, int stride, int qscale);
+} H263DSPContext;
+
+void ff_h263dsp_init(H263DSPContext *ctx);
+void ff_h263dsp_init_x86(H263DSPContext *ctx);
+
+#endif /* AVCODEC_H263DSP_H */
diff --git a/libavcodec/h264.c b/libavcodec/h264.c
index a47e83e..a621853 100644
--- a/libavcodec/h264.c
+++ b/libavcodec/h264.c
@@ -279,7 +279,7 @@
int off = offsetof(Picture, tf) + sizeof(pic->tf);
int i;
- if (!pic->f.data[0])
+ if (!pic->f.buf[0])
return;
ff_thread_release_buffer(h->avctx, &pic->tf);
@@ -301,7 +301,7 @@
/* release non reference frames */
for (i = 0; i < MAX_PICTURE_COUNT; i++) {
- if (h->DPB[i].f.data[0] && !h->DPB[i].reference &&
+ if (h->DPB[i].f.buf[0] && !h->DPB[i].reference &&
(remove_current || &h->DPB[i] != h->cur_pic_ptr)) {
unref_picture(h, &h->DPB[i]);
}
@@ -359,10 +359,10 @@
dst->field_picture = src->field_picture;
dst->needs_realloc = src->needs_realloc;
dst->reference = src->reference;
- dst->sync = src->sync;
dst->crop = src->crop;
dst->crop_left = src->crop_left;
dst->crop_top = src->crop_top;
+ dst->recovered = src->recovered;
return 0;
fail:
@@ -483,7 +483,7 @@
static inline int pic_is_unused(H264Context *h, Picture *pic)
{
- if (pic->f.data[0] == NULL)
+ if (!pic->f.buf[0])
return 1;
if (pic->needs_realloc && !(pic->reference & DELAYED_PIC_REF))
return 1;
@@ -932,9 +932,9 @@
full_my < 0 - extra_height ||
full_mx + 16 /*FIXME*/ > pic_width + extra_width ||
full_my + 16 /*FIXME*/ > pic_height + extra_height) {
- h->vdsp.emulated_edge_mc(h->edge_emu_buffer, h->mb_linesize,
+ h->vdsp.emulated_edge_mc(h->edge_emu_buffer,
src_y - (2 << pixel_shift) - 2 * h->mb_linesize,
- h->mb_linesize,
+ h->mb_linesize, h->mb_linesize,
16 + 5, 16 + 5 /*FIXME*/, full_mx - 2,
full_my - 2, pic_width, pic_height);
src_y = h->edge_emu_buffer + (2 << pixel_shift) + 2 * h->mb_linesize;
@@ -951,9 +951,9 @@
if (chroma_idc == 3 /* yuv444 */) {
src_cb = pic->f.data[1] + offset;
if (emu) {
- h->vdsp.emulated_edge_mc(h->edge_emu_buffer, h->mb_linesize,
+ h->vdsp.emulated_edge_mc(h->edge_emu_buffer,
src_cb - (2 << pixel_shift) - 2 * h->mb_linesize,
- h->mb_linesize,
+ h->mb_linesize, h->mb_linesize,
16 + 5, 16 + 5 /*FIXME*/,
full_mx - 2, full_my - 2,
pic_width, pic_height);
@@ -965,9 +965,9 @@
src_cr = pic->f.data[2] + offset;
if (emu) {
- h->vdsp.emulated_edge_mc(h->edge_emu_buffer, h->mb_linesize,
+ h->vdsp.emulated_edge_mc(h->edge_emu_buffer,
src_cr - (2 << pixel_shift) - 2 * h->mb_linesize,
- h->mb_linesize,
+ h->mb_linesize, h->mb_linesize,
16 + 5, 16 + 5 /*FIXME*/,
full_mx - 2, full_my - 2,
pic_width, pic_height);
@@ -992,7 +992,8 @@
(my >> ysh) * h->mb_uvlinesize;
if (emu) {
- h->vdsp.emulated_edge_mc(h->edge_emu_buffer, h->mb_uvlinesize, src_cb, h->mb_uvlinesize,
+ h->vdsp.emulated_edge_mc(h->edge_emu_buffer, src_cb,
+ h->mb_uvlinesize, h->mb_uvlinesize,
9, 8 * chroma_idc + 1, (mx >> 3), (my >> ysh),
pic_width >> 1, pic_height >> (chroma_idc == 1 /* yuv420 */));
src_cb = h->edge_emu_buffer;
@@ -1002,7 +1003,8 @@
mx & 7, (my << (chroma_idc == 2 /* yuv422 */)) & 7);
if (emu) {
- h->vdsp.emulated_edge_mc(h->edge_emu_buffer, h->mb_uvlinesize, src_cr, h->mb_uvlinesize,
+ h->vdsp.emulated_edge_mc(h->edge_emu_buffer, src_cr,
+ h->mb_uvlinesize, h->mb_uvlinesize,
9, 8 * chroma_idc + 1, (mx >> 3), (my >> ysh),
pic_width >> 1, pic_height >> (chroma_idc == 1 /* yuv420 */));
src_cr = h->edge_emu_buffer;
@@ -1660,19 +1662,24 @@
}
}
-static void copy_parameter_set(void **to, void **from, int count, int size)
+static int copy_parameter_set(void **to, void **from, int count, int size)
{
int i;
for (i = 0; i < count; i++) {
- if (to[i] && !from[i])
+ if (to[i] && !from[i]) {
av_freep(&to[i]);
- else if (from[i] && !to[i])
+ } else if (from[i] && !to[i]) {
to[i] = av_malloc(size);
+ if (!to[i])
+ return AVERROR(ENOMEM);
+ }
if (from[i])
memcpy(to[i], from[i], size);
}
+
+ return 0;
}
static int decode_init_thread_copy(AVCodecContext *avctx)
@@ -1736,11 +1743,15 @@
h->mb_stride = h1->mb_stride;
h->b_stride = h1->b_stride;
// SPS/PPS
- copy_parameter_set((void **)h->sps_buffers, (void **)h1->sps_buffers,
- MAX_SPS_COUNT, sizeof(SPS));
+ if ((ret = copy_parameter_set((void **)h->sps_buffers,
+ (void **)h1->sps_buffers,
+ MAX_SPS_COUNT, sizeof(SPS))) < 0)
+ return ret;
h->sps = h1->sps;
- copy_parameter_set((void **)h->pps_buffers, (void **)h1->pps_buffers,
- MAX_PPS_COUNT, sizeof(PPS));
+ if ((ret = copy_parameter_set((void **)h->pps_buffers,
+ (void **)h1->pps_buffers,
+ MAX_PPS_COUNT, sizeof(PPS))) < 0)
+ return ret;
h->pps = h1->pps;
if ((err = h264_slice_header_init(h, 1)) < 0) {
@@ -1837,7 +1848,7 @@
for (i = 0; h->DPB && i < MAX_PICTURE_COUNT; i++) {
unref_picture(h, &h->DPB[i]);
- if (h1->DPB[i].f.data[0] &&
+ if (h1->DPB[i].f.buf[0] &&
(ret = ref_picture(h, &h->DPB[i], &h1->DPB[i])) < 0)
return ret;
}
@@ -1855,11 +1866,15 @@
h->is_avc = h1->is_avc;
// SPS/PPS
- copy_parameter_set((void **)h->sps_buffers, (void **)h1->sps_buffers,
- MAX_SPS_COUNT, sizeof(SPS));
+ if ((ret = copy_parameter_set((void **)h->sps_buffers,
+ (void **)h1->sps_buffers,
+ MAX_SPS_COUNT, sizeof(SPS))) < 0)
+ return ret;
h->sps = h1->sps;
- copy_parameter_set((void **)h->pps_buffers, (void **)h1->pps_buffers,
- MAX_PPS_COUNT, sizeof(PPS));
+ if ((ret = copy_parameter_set((void **)h->pps_buffers,
+ (void **)h1->pps_buffers,
+ MAX_PPS_COUNT, sizeof(PPS))) < 0)
+ return ret;
h->pps = h1->pps;
// Dequantization matrices
@@ -1887,7 +1902,7 @@
copy_picture_range(h->delayed_pic, h1->delayed_pic,
MAX_DELAYED_PIC_COUNT + 2, h, h1);
- h->sync = h1->sync;
+ h->frame_recovered = h1->frame_recovered;
if (context_reinitialized)
h264_set_parameter_from_sps(h);
@@ -1904,6 +1919,8 @@
h->prev_frame_num = h->frame_num;
h->outputed_poc = h->next_outputed_poc;
+ h->recovery_frame = h1->recovery_frame;
+
return err;
}
@@ -1944,12 +1961,12 @@
* See decode_nal_units().
*/
pic->f.key_frame = 0;
- pic->sync = 0;
pic->mmco_reset = 0;
+ pic->recovered = 0;
if ((ret = alloc_picture(h, pic)) < 0)
return ret;
- if(!h->sync && !h->avctx->hwaccel &&
+ if(!h->frame_recovered && !h->avctx->hwaccel &&
!(h->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU))
avpriv_color_frame(&pic->f, c);
@@ -2142,7 +2159,7 @@
if (cur->reference == 0)
cur->reference = DELAYED_PIC_REF;
- out = h->delayed_pic[0];
+ out = h->delayed_pic[0];
out_idx = 0;
for (i = 1; h->delayed_pic[i] &&
!h->delayed_pic[i]->f.key_frame &&
@@ -2174,8 +2191,13 @@
av_log(h->avctx, AV_LOG_DEBUG, "no picture %s\n", out_of_order ? "ooo" : "");
}
- if (h->next_output_pic && h->next_output_pic->sync) {
- h->sync |= 2;
+ if (h->next_output_pic) {
+ if (h->next_output_pic->recovered) {
+ // We have reached an recovery point and all frames after it in
+ // display order are "recovered".
+ h->frame_recovered |= FRAME_RECOVERED_SEI;
+ }
+ h->next_output_pic->recovered |= !!(h->frame_recovered & FRAME_RECOVERED_SEI);
}
if (setup_finished && !h->avctx->hwaccel)
@@ -2600,7 +2622,7 @@
hl_decode_mb_simple_8(h);
}
-static int pred_weight_table(H264Context *h)
+int ff_pred_weight_table(H264Context *h)
{
int list, i;
int luma_def, chroma_def;
@@ -2766,10 +2788,11 @@
memset(h->default_ref_list[0], 0, sizeof(h->default_ref_list[0]));
memset(h->default_ref_list[1], 0, sizeof(h->default_ref_list[1]));
ff_h264_reset_sei(h);
- h->recovery_frame= -1;
- h->sync= 0;
+ h->recovery_frame = -1;
+ h->frame_recovered = 0;
h->list_count = 0;
h->current_slice = 0;
+ h->mmco_reset = 1;
}
/* forget old pics after a seek */
@@ -2800,6 +2823,9 @@
h->parse_context.overread_index = 0;
h->parse_context.index = 0;
h->parse_context.last_index = 0;
+
+ free_tables(h, 1);
+ h->context_initialized = 0;
}
int ff_init_poc(H264Context *h, int pic_field_poc[2], int *pic_poc)
@@ -2960,8 +2986,7 @@
* past end by one (callers fault) and resync_mb_y != 0
* causes problems for the first MB line, too.
*/
- if (CONFIG_ERROR_RESILIENCE &&
- !FIELD_PICTURE(h) && h->current_slice && !h->sps.new) {
+ if (CONFIG_ERROR_RESILIENCE && !FIELD_PICTURE(h) && h->current_slice && !h->sps.new) {
h->er.cur_pic = h->cur_pic_ptr;
ff_er_frame_end(&h->er);
}
@@ -3224,7 +3249,7 @@
h->sps.num_units_in_tick, den, 1 << 30);
}
- h->avctx->hwaccel = ff_find_hwaccel(h->avctx->codec->id, h->avctx->pix_fmt);
+ h->avctx->hwaccel = ff_find_hwaccel(h->avctx);
if (reinit)
free_tables(h, 0);
@@ -3261,6 +3286,8 @@
for (i = 1; i < h->slice_context_count; i++) {
H264Context *c;
c = h->thread_context[i] = av_mallocz(sizeof(H264Context));
+ if (!c)
+ return AVERROR(ENOMEM);
c->avctx = h->avctx;
if (CONFIG_ERROR_RESILIENCE) {
c->dsp = h->dsp;
@@ -3277,8 +3304,8 @@
c->height = h->height;
c->linesize = h->linesize;
c->uvlinesize = h->uvlinesize;
- c->chroma_x_shift = h->chroma_x_shift;
- c->chroma_y_shift = h->chroma_y_shift;
+ c->chroma_x_shift = h->chroma_x_shift;
+ c->chroma_y_shift = h->chroma_y_shift;
c->qscale = h->qscale;
c->droppable = h->droppable;
c->data_partitioning = h->data_partitioning;
@@ -3308,6 +3335,49 @@
return 0;
}
+int ff_set_ref_count(H264Context *h)
+{
+ int num_ref_idx_active_override_flag;
+
+ // set defaults, might be overridden a few lines later
+ h->ref_count[0] = h->pps.ref_count[0];
+ h->ref_count[1] = h->pps.ref_count[1];
+
+ if (h->slice_type_nos != AV_PICTURE_TYPE_I) {
+ unsigned max[2];
+ max[0] = max[1] = h->picture_structure == PICT_FRAME ? 15 : 31;
+
+ if (h->slice_type_nos == AV_PICTURE_TYPE_B)
+ h->direct_spatial_mv_pred = get_bits1(&h->gb);
+ num_ref_idx_active_override_flag = get_bits1(&h->gb);
+
+ if (num_ref_idx_active_override_flag) {
+ h->ref_count[0] = get_ue_golomb(&h->gb) + 1;
+ if (h->slice_type_nos == AV_PICTURE_TYPE_B) {
+ h->ref_count[1] = get_ue_golomb(&h->gb) + 1;
+ } else
+ // full range is spec-ok in this case, even for frames
+ h->ref_count[1] = 1;
+ }
+
+ if (h->ref_count[0]-1 > max[0] || h->ref_count[1]-1 > max[1]){
+ av_log(h->avctx, AV_LOG_ERROR, "reference overflow %u > %u or %u > %u\n", h->ref_count[0]-1, max[0], h->ref_count[1]-1, max[1]);
+ h->ref_count[0] = h->ref_count[1] = 0;
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (h->slice_type_nos == AV_PICTURE_TYPE_B)
+ h->list_count = 2;
+ else
+ h->list_count = 1;
+ } else {
+ h->list_count = 0;
+ h->ref_count[0] = h->ref_count[1] = 0;
+ }
+
+ return 0;
+}
+
/**
* Decode a slice header.
* This will also call ff_MPV_common_init() and frame_start() as needed.
@@ -3322,7 +3392,7 @@
{
unsigned int first_mb_in_slice;
unsigned int pps_id;
- int num_ref_idx_active_override_flag, ret;
+ int ret;
unsigned int slice_type, tmp, i, j;
int last_pic_structure, last_pic_droppable;
int must_reinit;
@@ -3549,7 +3619,7 @@
} else {
/* Shorten frame num gaps so we don't have to allocate reference
* frames just to throw them away */
- if (h->frame_num != h->prev_frame_num && h->prev_frame_num >= 0) {
+ if (h->frame_num != h->prev_frame_num) {
int unwrap_prev_frame_num = h->prev_frame_num;
int max_frame_num = 1 << h->sps.log2_max_frame_num;
@@ -3572,11 +3642,11 @@
* since that can modify h->cur_pic_ptr. */
if (h0->first_field) {
assert(h0->cur_pic_ptr);
- assert(h0->cur_pic_ptr->f.data[0]);
+ assert(h0->cur_pic_ptr->f.buf[0]);
assert(h0->cur_pic_ptr->reference != DELAYED_PIC_REF);
/* Mark old field/frame as completed */
- if (!last_pic_droppable && h0->cur_pic_ptr->tf.owner == h0->avctx) {
+ if (h0->cur_pic_ptr->tf.owner == h0->avctx) {
ff_thread_report_progress(&h0->cur_pic_ptr->tf, INT_MAX,
last_pic_structure == PICT_BOTTOM_FIELD);
}
@@ -3585,7 +3655,7 @@
if (!FIELD_PICTURE(h) || h->picture_structure == last_pic_structure) {
/* Previous field is unmatched. Don't display it, but let it
* remain for reference if marked as such. */
- if (!last_pic_droppable && last_pic_structure != PICT_FRAME) {
+ if (last_pic_structure != PICT_FRAME) {
ff_thread_report_progress(&h0->cur_pic_ptr->tf, INT_MAX,
last_pic_structure == PICT_TOP_FIELD);
}
@@ -3595,7 +3665,7 @@
* different frame_nums. Consider this field first in
* pair. Throw away previous field except for reference
* purposes. */
- if (!last_pic_droppable && last_pic_structure != PICT_FRAME) {
+ if (last_pic_structure != PICT_FRAME) {
ff_thread_report_progress(&h0->cur_pic_ptr->tf, INT_MAX,
last_pic_structure == PICT_TOP_FIELD);
}
@@ -3622,7 +3692,7 @@
}
}
- while (h->frame_num != h->prev_frame_num && h->prev_frame_num >= 0 && !h0->first_field &&
+ while (h->frame_num != h->prev_frame_num && !h0->first_field &&
h->frame_num != (h->prev_frame_num + 1) % (1 << h->sps.log2_max_frame_num)) {
Picture *prev = h->short_ref_count ? h->short_ref[0] : NULL;
av_log(h->avctx, AV_LOG_DEBUG, "Frame num gap %d %d\n",
@@ -3671,7 +3741,7 @@
* frame, or to allocate a new one. */
if (h0->first_field) {
assert(h0->cur_pic_ptr);
- assert(h0->cur_pic_ptr->f.data[0]);
+ assert(h0->cur_pic_ptr->f.buf[0]);
assert(h0->cur_pic_ptr->reference != DELAYED_PIC_REF);
/* figure out if we have a complementary field pair */
@@ -3775,45 +3845,15 @@
if (h->pps.redundant_pic_cnt_present)
h->redundant_pic_count = get_ue_golomb(&h->gb);
- // set defaults, might be overridden a few lines later
- h->ref_count[0] = h->pps.ref_count[0];
- h->ref_count[1] = h->pps.ref_count[1];
+ ret = ff_set_ref_count(h);
+ if (ret < 0)
+ return ret;
- if (h->slice_type_nos != AV_PICTURE_TYPE_I) {
- unsigned max[2];
- max[0] = max[1] = h->picture_structure == PICT_FRAME ? 15 : 31;
-
- if (h->slice_type_nos == AV_PICTURE_TYPE_B)
- h->direct_spatial_mv_pred = get_bits1(&h->gb);
- num_ref_idx_active_override_flag = get_bits1(&h->gb);
-
- if (num_ref_idx_active_override_flag) {
- h->ref_count[0] = get_ue_golomb(&h->gb) + 1;
- if (h->slice_type_nos == AV_PICTURE_TYPE_B) {
- h->ref_count[1] = get_ue_golomb(&h->gb) + 1;
- } else
- // full range is spec-ok in this case, even for frames
- h->ref_count[1] = 1;
- }
-
- if (h->ref_count[0]-1 > max[0] || h->ref_count[1]-1 > max[1]){
- av_log(h->avctx, AV_LOG_ERROR, "reference overflow %u > %u or %u > %u\n", h->ref_count[0]-1, max[0], h->ref_count[1]-1, max[1]);
- h->ref_count[0] = h->ref_count[1] = 0;
- return AVERROR_INVALIDDATA;
- }
-
- if (h->slice_type_nos == AV_PICTURE_TYPE_B)
- h->list_count = 2;
- else
- h->list_count = 1;
- } else {
- h->list_count = 0;
- h->ref_count[0] = h->ref_count[1] = 0;
- }
if (slice_type != AV_PICTURE_TYPE_I &&
(h0->current_slice == 0 ||
slice_type != h0->last_slice_type ||
memcmp(h0->last_ref_count, h0->ref_count, sizeof(h0->ref_count)))) {
+
ff_h264_fill_default_ref_list(h);
}
@@ -3828,7 +3868,7 @@
if ((h->pps.weighted_pred && h->slice_type_nos == AV_PICTURE_TYPE_P) ||
(h->pps.weighted_bipred_idc == 1 &&
h->slice_type_nos == AV_PICTURE_TYPE_B))
- pred_weight_table(h);
+ ff_pred_weight_table(h);
else if (h->pps.weighted_bipred_idc == 2 &&
h->slice_type_nos == AV_PICTURE_TYPE_B) {
implicit_weight_table(h, -1);
@@ -4713,14 +4753,16 @@
h->workaround_bugs |= FF_BUG_TRUNCATED;
if (!(h->workaround_bugs & FF_BUG_TRUNCATED))
- while(dst_length > 0 && ptr[dst_length - 1] == 0)
+ while (dst_length > 0 && ptr[dst_length - 1] == 0)
dst_length--;
bit_length = !dst_length ? 0
: (8 * dst_length -
decode_rbsp_trailing(h, ptr + dst_length - 1));
if (h->avctx->debug & FF_DEBUG_STARTCODE)
- av_log(h->avctx, AV_LOG_DEBUG, "NAL %d/%d at %d/%d length %d pass %d\n", hx->nal_unit_type, hx->nal_ref_idc, buf_index, buf_size, dst_length, pass);
+ av_log(h->avctx, AV_LOG_DEBUG,
+ "NAL %d/%d at %d/%d length %d pass %d\n",
+ hx->nal_unit_type, hx->nal_ref_idc, buf_index, buf_size, dst_length, pass);
if (h->is_avc && (nalsize != consumed) && nalsize)
av_log(h->avctx, AV_LOG_DEBUG,
@@ -4807,30 +4849,39 @@
if ((err = decode_slice_header(hx, h)))
break;
- if (h->sei_recovery_frame_cnt >= 0 && (h->frame_num != h->sei_recovery_frame_cnt || hx->slice_type_nos != AV_PICTURE_TYPE_I))
- h->valid_recovery_point = 1;
+ if (h->sei_recovery_frame_cnt >= 0) {
+ if (h->frame_num != h->sei_recovery_frame_cnt || hx->slice_type_nos != AV_PICTURE_TYPE_I)
+ h->valid_recovery_point = 1;
- if ( h->sei_recovery_frame_cnt >= 0
- && ( h->recovery_frame<0
- || ((h->recovery_frame - h->frame_num) & ((1 << h->sps.log2_max_frame_num)-1)) > h->sei_recovery_frame_cnt)) {
- h->recovery_frame = (h->frame_num + h->sei_recovery_frame_cnt) %
- (1 << h->sps.log2_max_frame_num);
+ if ( h->recovery_frame < 0
+ || ((h->recovery_frame - h->frame_num) & ((1 << h->sps.log2_max_frame_num)-1)) > h->sei_recovery_frame_cnt) {
+ h->recovery_frame = (h->frame_num + h->sei_recovery_frame_cnt) &
+ ((1 << h->sps.log2_max_frame_num) - 1);
- if (!h->valid_recovery_point)
- h->recovery_frame = h->frame_num;
+ if (!h->valid_recovery_point)
+ h->recovery_frame = h->frame_num;
+ }
}
h->cur_pic_ptr->f.key_frame |=
- (hx->nal_unit_type == NAL_IDR_SLICE);
+ (hx->nal_unit_type == NAL_IDR_SLICE);
- if (h->recovery_frame == h->frame_num) {
- h->cur_pic_ptr->sync |= 1;
- h->recovery_frame = -1;
+ if (hx->nal_unit_type == NAL_IDR_SLICE ||
+ h->recovery_frame == h->frame_num) {
+ h->recovery_frame = -1;
+ h->cur_pic_ptr->recovered = 1;
}
-
- h->sync |= !!h->cur_pic_ptr->f.key_frame;
- h->sync |= 3*!!(avctx->flags2 & CODEC_FLAG2_SHOW_ALL);
- h->cur_pic_ptr->sync |= h->sync;
+ // If we have an IDR, all frames after it in decoded order are
+ // "recovered".
+ if (hx->nal_unit_type == NAL_IDR_SLICE)
+ h->frame_recovered |= FRAME_RECOVERED_IDR;
+ h->frame_recovered |= 3*!!(avctx->flags2 & CODEC_FLAG2_SHOW_ALL);
+ h->frame_recovered |= 3*!!(avctx->flags & CODEC_FLAG_OUTPUT_CORRUPT);
+#if 1
+ h->cur_pic_ptr->recovered |= h->frame_recovered;
+#else
+ h->cur_pic_ptr->recovered |= !!(h->frame_recovered & FRAME_RECOVERED_IDR);
+#endif
if (h->current_slice == 1) {
if (!(avctx->flags2 & CODEC_FLAG2_CHUNKS))
@@ -5104,7 +5155,11 @@
/* Wait for second field. */
*got_frame = 0;
- if (h->next_output_pic && (h->next_output_pic->sync || h->sync>1)) {
+ if (h->next_output_pic && (
+ h->next_output_pic->recovered)) {
+ if (!h->next_output_pic->recovered)
+ h->next_output_pic->f.flags |= AV_FRAME_FLAG_CORRUPT;
+
ret = output_frame(h, pict, h->next_output_pic);
if (ret < 0)
return ret;
@@ -5117,7 +5172,7 @@
}
}
- assert(pict->data[0] || !*got_frame);
+ assert(pict->buf[0] || !*got_frame);
return get_consumed_bytes(buf_index, buf_size);
}
diff --git a/libavcodec/h264.h b/libavcodec/h264.h
index f1db519..b7e1214 100644
--- a/libavcodec/h264.h
+++ b/libavcodec/h264.h
@@ -379,7 +379,7 @@
uint32_t *mb2br_xy;
int b_stride; // FIXME use s->b4_stride
- ptrdiff_t mb_linesize; ///< may be equal to s->linesize or s->linesize * 2, for mbaff
+ ptrdiff_t mb_linesize; ///< may be equal to s->linesize or s->linesize * 2, for mbaff
ptrdiff_t mb_uvlinesize;
unsigned current_sps_id; ///< id of the current SPS
@@ -641,6 +641,14 @@
* frames.
*/
int sei_recovery_frame_cnt;
+
+ /**
+ * Are the SEI recovery points looking valid.
+ */
+ int valid_recovery_point;
+
+ FPA sei_fpa;
+
/**
* recovery_frame is the frame_num at which the next frame should
* be fully constructed.
@@ -649,12 +657,18 @@
*/
int recovery_frame;
- /**
- * Are the SEI recovery points looking valid.
- */
- int valid_recovery_point;
+/**
+ * We have seen an IDR, so all the following frames in coded order are correctly
+ * decodable.
+ */
+#define FRAME_RECOVERED_IDR (1 << 0)
+/**
+ * Sufficient number of frames have been decoded since a SEI recovery point,
+ * so all the following frames in presentation order are correct.
+ */
+#define FRAME_RECOVERED_SEI (1 << 1)
- FPA sei_fpa;
+ int frame_recovered; ///< Initial frame has been completely recovered
int luma_weight_flag[2]; ///< 7.4.3.2 luma_weight_lX_flag
int chroma_weight_flag[2]; ///< 7.4.3.2 chroma_weight_lX_flag
@@ -668,8 +682,6 @@
int16_t slice_row[MAX_SLICES]; ///< to detect when MAX_SLICES is too low
- int sync; ///< did we had a keyframe or recovery point
-
uint8_t parse_history[4];
int parse_history_count;
int parse_last_mb;
@@ -1011,5 +1023,7 @@
void ff_h264_draw_horiz_band(H264Context *h, int y, int height);
int ff_init_poc(H264Context *h, int pic_field_poc[2], int *pic_poc);
+int ff_pred_weight_table(H264Context *h);
+int ff_set_ref_count(H264Context *h);
#endif /* AVCODEC_H264_H */
diff --git a/libavcodec/h264_cabac.c b/libavcodec/h264_cabac.c
index 81da5f8..d092ba6 100644
--- a/libavcodec/h264_cabac.c
+++ b/libavcodec/h264_cabac.c
@@ -1683,7 +1683,6 @@
}
}
-
#define STORE_BLOCK(type) \
do { \
uint8_t *ctx = coeff_abs_level1_ctx[node_ctx] + abs_level_m1_ctx_base; \
@@ -1727,11 +1726,11 @@
} \
} while ( coeff_count );
- if (h->pixel_shift) {
- STORE_BLOCK(int32_t)
- } else {
- STORE_BLOCK(int16_t)
- }
+ if (h->pixel_shift) {
+ STORE_BLOCK(int32_t)
+ } else {
+ STORE_BLOCK(int16_t)
+ }
#ifdef CABAC_ON_STACK
h->cabac.range = cc.range ;
h->cabac.low = cc.low ;
diff --git a/libavcodec/h264_cavlc.c b/libavcodec/h264_cavlc.c
index ad902b8..87ae17c 100644
--- a/libavcodec/h264_cavlc.c
+++ b/libavcodec/h264_cavlc.c
@@ -772,6 +772,10 @@
// We assume these blocks are very rare so we do not optimize it.
h->intra_pcm_ptr = align_get_bits(&h->gb);
+ if (get_bits_left(&h->gb) < mb_size) {
+ av_log(h->avctx, AV_LOG_ERROR, "Not enough data for an intra PCM block.\n");
+ return AVERROR_INVALIDDATA;
+ }
skip_bits_long(&h->gb, mb_size);
// In deblocking, the quantizer is 0
@@ -865,7 +869,7 @@
}
for(list=0; list<h->list_count; list++){
- int ref_count= IS_REF0(mb_type) ? 1 : local_ref_count[list];
+ int ref_count = IS_REF0(mb_type) ? 1 : local_ref_count[list];
for(i=0; i<4; i++){
if(IS_DIRECT(h->sub_mb_type[i])) continue;
if(IS_DIR(h->sub_mb_type[i], 0, list)){
@@ -947,11 +951,11 @@
if(IS_DIR(mb_type, 0, list)){
if(local_ref_count[list]==1){
val= 0;
- }else if(local_ref_count[list]==2){
+ } else if(local_ref_count[list]==2){
val= get_bits1(&h->gb)^1;
}else{
val= get_ue_golomb_31(&h->gb);
- if(val >= local_ref_count[list]){
+ if (val >= local_ref_count[list]){
av_log(h->avctx, AV_LOG_ERROR, "ref %u overflow\n", val);
return -1;
}
@@ -975,13 +979,13 @@
for(i=0; i<2; i++){
unsigned int val;
if(IS_DIR(mb_type, i, list)){
- if(local_ref_count[list] == 1){
+ if(local_ref_count[list] == 1) {
val= 0;
- }else if(local_ref_count[list] == 2){
+ } else if(local_ref_count[list] == 2) {
val= get_bits1(&h->gb)^1;
}else{
val= get_ue_golomb_31(&h->gb);
- if(val >= local_ref_count[list]){
+ if (val >= local_ref_count[list]){
av_log(h->avctx, AV_LOG_ERROR, "ref %u overflow\n", val);
return -1;
}
@@ -1014,11 +1018,11 @@
if(IS_DIR(mb_type, i, list)){ //FIXME optimize
if(local_ref_count[list]==1){
val= 0;
- }else if(local_ref_count[list]==2){
+ } else if(local_ref_count[list]==2){
val= get_bits1(&h->gb)^1;
}else{
val= get_ue_golomb_31(&h->gb);
- if(val >= local_ref_count[list]){
+ if (val >= local_ref_count[list]){
av_log(h->avctx, AV_LOG_ERROR, "ref %u overflow\n", val);
return -1;
}
@@ -1141,12 +1145,12 @@
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]];
int16_t *mb = h->mb + (16*(16 + 16*chroma_idx) << pixel_shift);
- for (i8x8=0; i8x8<num_c8x8; i8x8++) {
- for (i4x4=0; i4x4<4; i4x4++) {
- const int index= 16 + 16*chroma_idx + 8*i8x8 + i4x4;
+ for (i8x8 = 0; i8x8<num_c8x8; 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;
+ mb += 16 << pixel_shift;
}
}
}
diff --git a/libavcodec/h264_mb_template.c b/libavcodec/h264_mb_template.c
index 15cb3c9..da3a926 100644
--- a/libavcodec/h264_mb_template.c
+++ b/libavcodec/h264_mb_template.c
@@ -138,8 +138,8 @@
if (SIMPLE || !CONFIG_GRAY || !(h->flags & CODEC_FLAG_GRAY)) {
if (!h->sps.chroma_format_idc) {
for (i = 0; i < 8; i++) {
- memset(dest_cb + i*uvlinesize, 1 << (bit_depth - 1), 8);
- memset(dest_cr + i*uvlinesize, 1 << (bit_depth - 1), 8);
+ memset(dest_cb + i * uvlinesize, 1 << (bit_depth - 1), 8);
+ memset(dest_cr + i * uvlinesize, 1 << (bit_depth - 1), 8);
}
} else {
const uint8_t *src_cb = h->intra_pcm_ptr + 256;
diff --git a/libavcodec/h264_mp4toannexb_bsf.c b/libavcodec/h264_mp4toannexb_bsf.c
index 58568a7..8c0fbb3 100644
--- a/libavcodec/h264_mp4toannexb_bsf.c
+++ b/libavcodec/h264_mp4toannexb_bsf.c
@@ -37,13 +37,14 @@
{
uint32_t offset = *poutbuf_size;
uint8_t nal_header_size = offset ? 3 : 4;
- void *tmp;
+ int err;
*poutbuf_size += sps_pps_size + in_size + nal_header_size;
- tmp = av_realloc(*poutbuf, *poutbuf_size + FF_INPUT_BUFFER_PADDING_SIZE);
- if (!tmp)
- return AVERROR(ENOMEM);
- *poutbuf = tmp;
+ if ((err = av_reallocp(poutbuf,
+ *poutbuf_size + FF_INPUT_BUFFER_PADDING_SIZE)) < 0) {
+ *poutbuf_size = 0;
+ return err;
+ }
if (sps_pps)
memcpy(*poutbuf + offset, sps_pps, sps_pps_size);
memcpy(*poutbuf + sps_pps_size + nal_header_size + offset, in, in_size);
@@ -77,7 +78,7 @@
}
while (unit_nb--) {
- void *tmp;
+ int err;
unit_size = AV_RB16(extradata);
total_size += unit_size + 4;
@@ -93,12 +94,8 @@
av_free(out);
return AVERROR(EINVAL);
}
- tmp = av_realloc(out, total_size + padding);
- if (!tmp) {
- av_free(out);
- return AVERROR(ENOMEM);
- }
- out = tmp;
+ if ((err = av_reallocp(&out, total_size + padding)) < 0)
+ return err;
memcpy(out + total_size - unit_size - 4, nalu_header, 4);
memcpy(out + total_size - unit_size, extradata + 2, unit_size);
extradata += 2 + unit_size;
diff --git a/libavcodec/h264_mvpred.h b/libavcodec/h264_mvpred.h
index 7015d8c..afe327c 100644
--- a/libavcodec/h264_mvpred.h
+++ b/libavcodec/h264_mvpred.h
@@ -663,7 +663,7 @@
ref_cache[4 - 1 * 8] = topright_type ? LIST_NOT_USED
: PART_NOT_AVAILABLE;
}
- if(ref_cache[2 - 1*8] < 0 || ref_cache[4 - 1*8] < 0){
+ if(ref_cache[2 - 1*8] < 0 || 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);
diff --git a/libavcodec/h264_parser.c b/libavcodec/h264_parser.c
index 85b0f9c..e718a3b 100644
--- a/libavcodec/h264_parser.c
+++ b/libavcodec/h264_parser.c
@@ -118,6 +118,75 @@
return i - (state & 5) - 3 * (state > 7);
}
+static int scan_mmco_reset(AVCodecParserContext *s)
+{
+ H264Context *h = s->priv_data;
+
+ h->slice_type_nos = s->pict_type & 3;
+
+ if (h->pps.redundant_pic_cnt_present)
+ get_ue_golomb(&h->gb); // redundant_pic_count
+
+ if (ff_set_ref_count(h) < 0)
+ return AVERROR_INVALIDDATA;
+
+ if (h->slice_type_nos != AV_PICTURE_TYPE_I) {
+ int list;
+ for (list = 0; list < h->list_count; list++) {
+ if (get_bits1(&h->gb)) {
+ int index;
+ for (index = 0; ; index++) {
+ unsigned int reordering_of_pic_nums_idc = get_ue_golomb_31(&h->gb);
+
+ if (reordering_of_pic_nums_idc < 3)
+ get_ue_golomb(&h->gb);
+ else if (reordering_of_pic_nums_idc > 3) {
+ av_log(h->avctx, AV_LOG_ERROR,
+ "illegal reordering_of_pic_nums_idc %d\n",
+ reordering_of_pic_nums_idc);
+ return AVERROR_INVALIDDATA;
+ } else
+ break;
+
+ if (index >= h->ref_count[list]) {
+ av_log(h->avctx, AV_LOG_ERROR, "reference count overflow\n");
+ return AVERROR_INVALIDDATA;
+ }
+ }
+ }
+ }
+ }
+
+ if ((h->pps.weighted_pred && h->slice_type_nos == AV_PICTURE_TYPE_P) ||
+ (h->pps.weighted_bipred_idc == 1 && h->slice_type_nos == AV_PICTURE_TYPE_B))
+ ff_pred_weight_table(h);
+
+ if (get_bits1(&h->gb)) { // adaptive_ref_pic_marking_mode_flag
+ int i;
+ for (i = 0; i < MAX_MMCO_COUNT; i++) {
+ MMCOOpcode opcode = get_ue_golomb_31(&h->gb);
+ if (opcode > (unsigned) MMCO_LONG) {
+ av_log(h->avctx, AV_LOG_ERROR,
+ "illegal memory management control operation %d\n",
+ opcode);
+ return AVERROR_INVALIDDATA;
+ }
+ if (opcode == MMCO_END)
+ return 0;
+ else if (opcode == MMCO_RESET)
+ return 1;
+
+ if (opcode == MMCO_SHORT2UNUSED || opcode == MMCO_SHORT2LONG)
+ get_ue_golomb(&h->gb);
+ if (opcode == MMCO_SHORT2LONG || opcode == MMCO_LONG2UNUSED ||
+ opcode == MMCO_LONG || opcode == MMCO_SET_MAX_LONG)
+ get_ue_golomb_31(&h->gb);
+ }
+ }
+
+ return 0;
+}
+
/**
* Parse NAL units of found picture and decode some basic information.
*
@@ -134,7 +203,7 @@
const uint8_t *buf_end = buf + buf_size;
unsigned int pps_id;
unsigned int slice_type;
- int state = -1;
+ int state = -1, got_reset = 0;
const uint8_t *ptr;
int q264 = buf_size >=4 && !memcmp("Q264", buf, 4);
int field_poc[2];
@@ -144,11 +213,8 @@
s->key_frame = 0;
s->picture_structure = AV_PICTURE_STRUCTURE_UNKNOWN;
- h->avctx = avctx;
- h->sei_recovery_frame_cnt = -1;
- h->sei_dpb_output_delay = 0;
- h->sei_cpb_removal_delay = -1;
- h->sei_buffering_period_present = 0;
+ h->avctx = avctx;
+ ff_h264_reset_sei(h);
h->sei_fpa.frame_packing_arrangement_cancel_flag = -1;
if (!buf_size)
@@ -178,8 +244,16 @@
case NAL_SLICE:
case NAL_IDR_SLICE:
// Do not walk the whole buffer just to decode slice header
- if (src_length > 20)
- src_length = 20;
+ if ((state & 0x1f) == NAL_IDR_SLICE || ((state >> 5) & 0x3) == 0) {
+ /* IDR or disposable slice
+ * No need to decode many bytes because MMCOs shall not be present. */
+ if (src_length > 60)
+ src_length = 60;
+ } else {
+ /* To decode up to MMCOs */
+ if (src_length > 1000)
+ src_length = 1000;
+ }
break;
}
ptr = ff_h264_decode_nal(h, buf, &dst_length, &consumed, src_length);
@@ -233,6 +307,9 @@
h->sps = *h->sps_buffers[h->pps.sps_id];
h->frame_num = get_bits(&h->gb, h->sps.log2_max_frame_num);
+ if(h->sps.ref_frame_count <= 1 && h->pps.ref_count[0] <= 1 && s->pict_type == AV_PICTURE_TYPE_I)
+ s->key_frame = 1;
+
avctx->profile = ff_h264_get_profile(&h->sps);
avctx->level = h->sps.level_idc;
@@ -265,8 +342,35 @@
h->delta_poc[1] = get_se_golomb(&h->gb);
}
+ /* Decode POC of this picture.
+ * The prev_ values needed for decoding POC of the next picture are not set here. */
+ field_poc[0] = field_poc[1] = INT_MAX;
ff_init_poc(h, field_poc, &s->output_picture_number);
+ /* Continue parsing to check if MMCO_RESET is present.
+ * FIXME: MMCO_RESET could appear in non-first slice.
+ * Maybe, we should parse all undisposable non-IDR slice of this
+ * picture until encountering MMCO_RESET in a slice of it. */
+ if (h->nal_ref_idc && h->nal_unit_type != NAL_IDR_SLICE) {
+ got_reset = scan_mmco_reset(s);
+ if (got_reset < 0)
+ return got_reset;
+ }
+
+ /* Set up the prev_ values for decoding POC of the next picture. */
+ h->prev_frame_num = got_reset ? 0 : h->frame_num;
+ h->prev_frame_num_offset = got_reset ? 0 : h->frame_num_offset;
+ if (h->nal_ref_idc != 0) {
+ if (!got_reset) {
+ h->prev_poc_msb = h->poc_msb;
+ h->prev_poc_lsb = h->poc_lsb;
+ } else {
+ h->prev_poc_msb = 0;
+ h->prev_poc_lsb =
+ h->picture_structure == PICT_BOTTOM_FIELD ? 0 : field_poc[0];
+ }
+ }
+
if (h->sps.pic_struct_present_flag) {
switch (h->sei_pic_struct) {
case SEI_PIC_STRUCT_TOP_FIELD:
diff --git a/libavcodec/h264_ps.c b/libavcodec/h264_ps.c
index e667359..a06e3dd 100644
--- a/libavcodec/h264_ps.c
+++ b/libavcodec/h264_ps.c
@@ -520,9 +520,11 @@
}
sps->vui_parameters_present_flag = get_bits1(&h->gb);
- if (sps->vui_parameters_present_flag)
- if (decode_vui_parameters(h, sps) < 0)
+ if (sps->vui_parameters_present_flag) {
+ int ret = decode_vui_parameters(h, sps);
+ if (ret < 0)
goto fail;
+ }
if (!sps->sar.den)
sps->sar.den = 1;
diff --git a/libavcodec/h264_refs.c b/libavcodec/h264_refs.c
index 42316b4..7eb1f9e 100644
--- a/libavcodec/h264_refs.c
+++ b/libavcodec/h264_refs.c
@@ -68,7 +68,8 @@
return match;
}
-static int build_def_list(Picture *def, Picture **in, int len, int is_long, int sel)
+static int build_def_list(Picture *def, int def_len,
+ Picture **in, int len, int is_long, int sel)
{
int i[2] = { 0 };
int index = 0;
@@ -79,10 +80,12 @@
while (i[1] < len && !(in[i[1]] && (in[i[1]]->reference & (sel ^ 3))))
i[1]++;
if (i[0] < len) {
+ av_assert0(index < def_len);
in[i[0]]->pic_id = is_long ? i[0] : in[i[0]]->frame_num;
split_field_copy(&def[index++], in[i[0]++], sel, 1);
}
if (i[1] < len) {
+ av_assert0(index < def_len);
in[i[1]]->pic_id = is_long ? i[1] : in[i[1]]->frame_num;
split_field_copy(&def[index++], in[i[1]++], sel ^ 3, 0);
}
@@ -131,8 +134,12 @@
len = add_sorted(sorted, h->short_ref, h->short_ref_count, cur_poc, 1 ^ list);
len += add_sorted(sorted + len, h->short_ref, h->short_ref_count, cur_poc, 0 ^ list);
av_assert0(len <= 32);
- len = build_def_list(h->default_ref_list[list], sorted, len, 0, h->picture_structure);
- len += build_def_list(h->default_ref_list[list] + len, h->long_ref, 16, 1, h->picture_structure);
+
+ len = build_def_list(h->default_ref_list[list], FF_ARRAY_ELEMS(h->default_ref_list[0]),
+ sorted, len, 0, h->picture_structure);
+ len += build_def_list(h->default_ref_list[list] + len,
+ FF_ARRAY_ELEMS(h->default_ref_list[0]) - len,
+ h->long_ref, 16, 1, h->picture_structure);
av_assert0(len <= 32);
if (len < h->ref_count[list])
@@ -141,7 +148,9 @@
}
if (lens[0] == lens[1] && lens[1] > 1) {
- 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++);
+ for (i = 0; i < lens[0] &&
+ h->default_ref_list[0][i].f.buf[0]->buffer ==
+ h->default_ref_list[1][i].f.buf[0]->buffer; i++);
if (i == lens[0]) {
Picture tmp;
COPY_PICTURE(&tmp, &h->default_ref_list[1][0]);
@@ -150,9 +159,13 @@
}
}
} else {
- len = build_def_list(h->default_ref_list[0], h->short_ref, h->short_ref_count, 0, h->picture_structure);
- len += build_def_list(h->default_ref_list[0] + len, h-> long_ref, 16, 1, h->picture_structure);
+ len = build_def_list(h->default_ref_list[0], FF_ARRAY_ELEMS(h->default_ref_list[0]),
+ h->short_ref, h->short_ref_count, 0, h->picture_structure);
+ len += build_def_list(h->default_ref_list[0] + len,
+ FF_ARRAY_ELEMS(h->default_ref_list[0]) - len,
+ h-> long_ref, 16, 1, h->picture_structure);
av_assert0(len <= 32);
+
if (len < h->ref_count[0])
memset(&h->default_ref_list[0][len], 0, sizeof(Picture) * (h->ref_count[0] - len));
}
@@ -304,13 +317,13 @@
}
for (list = 0; list < h->list_count; list++) {
for (index = 0; index < h->ref_count[list]; index++) {
- if ( !h->ref_list[list][index].f.data[0]
+ if ( !h->ref_list[list][index].f.buf[0]
|| (!FIELD_PICTURE(h) && (h->ref_list[list][index].reference&3) != 3)) {
int i;
av_log(h->avctx, AV_LOG_ERROR, "Missing reference picture, default is %d\n", h->default_ref_list[list][0].poc);
for (i = 0; i < FF_ARRAY_ELEMS(h->last_pocs); i++)
h->last_pocs[i] = INT_MIN;
- if (h->default_ref_list[list][0].f.data[0]
+ if (h->default_ref_list[list][0].f.buf[0]
&& !(!FIELD_PICTURE(h) && (h->default_ref_list[list][0].reference&3) != 3))
COPY_PICTURE(&h->ref_list[list][index], &h->default_ref_list[list][0]);
else
@@ -562,6 +575,7 @@
int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count)
{
int i, av_uninit(j);
+ int pps_count;
int current_ref_assigned = 0, err = 0;
Picture *av_uninit(pic);
@@ -582,7 +596,7 @@
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->avctx, AV_LOG_ERROR, "mmco: unref short failure\n");
+ av_log(h->avctx, h->short_ref_count ? AV_LOG_ERROR : AV_LOG_DEBUG, "mmco: unref short failure\n");
err = AVERROR_INVALIDDATA;
}
continue;
@@ -732,10 +746,18 @@
print_short_term(h);
print_long_term(h);
- if(err >= 0 && h->long_ref_count==0 && h->short_ref_count<=2 && h->pps.ref_count[0]<=2 + (h->picture_structure != PICT_FRAME) && h->cur_pic_ptr->f.pict_type == AV_PICTURE_TYPE_I){
- h->cur_pic_ptr->sync |= 1;
+ pps_count = 0;
+ for (i = 0; i < FF_ARRAY_ELEMS(h->pps_buffers); i++)
+ pps_count += !!h->pps_buffers[i];
+
+ if ( err >= 0
+ && h->long_ref_count==0
+ && (h->short_ref_count<=2 || h->pps.ref_count[0] <= 1 && h->pps.ref_count[1] <= 1 && pps_count == 1)
+ && h->pps.ref_count[0]<=2 + (h->picture_structure != PICT_FRAME)
+ && h->cur_pic_ptr->f.pict_type == AV_PICTURE_TYPE_I){
+ h->cur_pic_ptr->recovered |= 1;
if(!h->avctx->has_b_frames)
- h->sync = 2;
+ h->frame_recovered |= FRAME_RECOVERED_SEI;
}
return (h->avctx->err_recognition & AV_EF_EXPLODE) ? err : 0;
diff --git a/libavcodec/h264dsp.c b/libavcodec/h264dsp.c
index 72f699f..1606e11 100644
--- a/libavcodec/h264dsp.c
+++ b/libavcodec/h264dsp.c
@@ -26,6 +26,7 @@
*/
#include <stdint.h>
+
#include "libavutil/attributes.h"
#include "libavutil/avassert.h"
diff --git a/libavcodec/hevc.c b/libavcodec/hevc.c
new file mode 100644
index 0000000..4294760
--- /dev/null
+++ b/libavcodec/hevc.c
@@ -0,0 +1,2970 @@
+/*
+ * HEVC video Decoder
+ *
+ * Copyright (C) 2012 - 2013 Guillaume Martres
+ * Copyright (C) 2012 - 2013 Mickael Raulet
+ * Copyright (C) 2012 - 2013 Gildas Cocherel
+ * Copyright (C) 2012 - 2013 Wassim Hamidouche
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "libavutil/atomic.h"
+#include "libavutil/attributes.h"
+#include "libavutil/common.h"
+#include "libavutil/internal.h"
+#include "libavutil/md5.h"
+#include "libavutil/opt.h"
+#include "libavutil/pixdesc.h"
+
+#include "bytestream.h"
+#include "cabac_functions.h"
+#include "dsputil.h"
+#include "golomb.h"
+#include "hevc.h"
+
+const uint8_t ff_hevc_qpel_extra_before[4] = { 0, 3, 3, 2 };
+const uint8_t ff_hevc_qpel_extra_after[4] = { 0, 3, 4, 4 };
+const uint8_t ff_hevc_qpel_extra[4] = { 0, 6, 7, 6 };
+
+/**
+ * NOTE: Each function hls_foo correspond to the function foo in the
+ * specification (HLS stands for High Level Syntax).
+ */
+
+/**
+ * Section 5.7
+ */
+
+/* free everything allocated by pic_arrays_init() */
+static void pic_arrays_free(HEVCContext *s)
+{
+ av_freep(&s->sao);
+ av_freep(&s->deblock);
+ av_freep(&s->split_cu_flag);
+
+ av_freep(&s->skip_flag);
+ av_freep(&s->tab_ct_depth);
+
+ av_freep(&s->tab_ipm);
+ av_freep(&s->cbf_luma);
+ av_freep(&s->is_pcm);
+
+ av_freep(&s->qp_y_tab);
+ av_freep(&s->tab_slice_address);
+ av_freep(&s->filter_slice_edges);
+
+ av_freep(&s->horizontal_bs);
+ av_freep(&s->vertical_bs);
+
+ av_freep(&s->sh.entry_point_offset);
+ av_freep(&s->sh.size);
+ av_freep(&s->sh.offset);
+
+ av_buffer_pool_uninit(&s->tab_mvf_pool);
+ av_buffer_pool_uninit(&s->rpl_tab_pool);
+}
+
+/* allocate arrays that depend on frame dimensions */
+static int pic_arrays_init(HEVCContext *s, const HEVCSPS *sps)
+{
+ int log2_min_cb_size = sps->log2_min_cb_size;
+ int width = sps->width;
+ int height = sps->height;
+ int pic_size = width * height;
+ int pic_size_in_ctb = ((width >> log2_min_cb_size) + 1) *
+ ((height >> log2_min_cb_size) + 1);
+ int ctb_count = sps->ctb_width * sps->ctb_height;
+ int min_pu_size = sps->min_pu_width * sps->min_pu_height;
+
+ s->bs_width = width >> 3;
+ s->bs_height = height >> 3;
+
+ s->sao = av_mallocz_array(ctb_count, sizeof(*s->sao));
+ s->deblock = av_mallocz_array(ctb_count, sizeof(*s->deblock));
+ s->split_cu_flag = av_malloc(pic_size);
+ if (!s->sao || !s->deblock || !s->split_cu_flag)
+ goto fail;
+
+ s->skip_flag = av_malloc(pic_size_in_ctb);
+ s->tab_ct_depth = av_malloc(sps->min_cb_height * sps->min_cb_width);
+ if (!s->skip_flag || !s->tab_ct_depth)
+ goto fail;
+
+ s->cbf_luma = av_malloc(sps->min_tb_width * sps->min_tb_height);
+ s->tab_ipm = av_malloc(min_pu_size);
+ s->is_pcm = av_malloc(min_pu_size);
+ if (!s->tab_ipm || !s->cbf_luma || !s->is_pcm)
+ goto fail;
+
+ s->filter_slice_edges = av_malloc(ctb_count);
+ s->tab_slice_address = av_malloc(pic_size_in_ctb *
+ sizeof(*s->tab_slice_address));
+ s->qp_y_tab = av_malloc(pic_size_in_ctb *
+ sizeof(*s->qp_y_tab));
+ if (!s->qp_y_tab || !s->filter_slice_edges || !s->tab_slice_address)
+ goto fail;
+
+ s->horizontal_bs = av_mallocz(2 * s->bs_width * (s->bs_height + 1));
+ s->vertical_bs = av_mallocz(2 * s->bs_width * (s->bs_height + 1));
+ if (!s->horizontal_bs || !s->vertical_bs)
+ goto fail;
+
+ s->tab_mvf_pool = av_buffer_pool_init(min_pu_size * sizeof(MvField),
+ av_buffer_alloc);
+ s->rpl_tab_pool = av_buffer_pool_init(ctb_count * sizeof(RefPicListTab),
+ av_buffer_allocz);
+ if (!s->tab_mvf_pool || !s->rpl_tab_pool)
+ goto fail;
+
+ return 0;
+
+fail:
+ pic_arrays_free(s);
+ return AVERROR(ENOMEM);
+}
+
+static void pred_weight_table(HEVCContext *s, GetBitContext *gb)
+{
+ int i = 0;
+ int j = 0;
+ uint8_t luma_weight_l0_flag[16];
+ uint8_t chroma_weight_l0_flag[16];
+ uint8_t luma_weight_l1_flag[16];
+ uint8_t chroma_weight_l1_flag[16];
+
+ s->sh.luma_log2_weight_denom = get_ue_golomb_long(gb);
+ if (s->sps->chroma_format_idc != 0) {
+ int delta = get_se_golomb(gb);
+ s->sh.chroma_log2_weight_denom = av_clip_c(s->sh.luma_log2_weight_denom + delta, 0, 7);
+ }
+
+ for (i = 0; i < s->sh.nb_refs[L0]; i++) {
+ luma_weight_l0_flag[i] = get_bits1(gb);
+ if (!luma_weight_l0_flag[i]) {
+ s->sh.luma_weight_l0[i] = 1 << s->sh.luma_log2_weight_denom;
+ s->sh.luma_offset_l0[i] = 0;
+ }
+ }
+ if (s->sps->chroma_format_idc != 0) { // FIXME: invert "if" and "for"
+ for (i = 0; i < s->sh.nb_refs[L0]; i++)
+ chroma_weight_l0_flag[i] = get_bits1(gb);
+ } else {
+ for (i = 0; i < s->sh.nb_refs[L0]; i++)
+ chroma_weight_l0_flag[i] = 0;
+ }
+ for (i = 0; i < s->sh.nb_refs[L0]; i++) {
+ if (luma_weight_l0_flag[i]) {
+ int delta_luma_weight_l0 = get_se_golomb(gb);
+ s->sh.luma_weight_l0[i] = (1 << s->sh.luma_log2_weight_denom) + delta_luma_weight_l0;
+ s->sh.luma_offset_l0[i] = get_se_golomb(gb);
+ }
+ if (chroma_weight_l0_flag[i]) {
+ for (j = 0; j < 2; j++) {
+ int delta_chroma_weight_l0 = get_se_golomb(gb);
+ int delta_chroma_offset_l0 = get_se_golomb(gb);
+ s->sh.chroma_weight_l0[i][j] = (1 << s->sh.chroma_log2_weight_denom) + delta_chroma_weight_l0;
+ s->sh.chroma_offset_l0[i][j] = av_clip_c((delta_chroma_offset_l0 - ((128 * s->sh.chroma_weight_l0[i][j])
+ >> s->sh.chroma_log2_weight_denom) + 128), -128, 127);
+ }
+ } else {
+ s->sh.chroma_weight_l0[i][0] = 1 << s->sh.chroma_log2_weight_denom;
+ s->sh.chroma_offset_l0[i][0] = 0;
+ s->sh.chroma_weight_l0[i][1] = 1 << s->sh.chroma_log2_weight_denom;
+ s->sh.chroma_offset_l0[i][1] = 0;
+ }
+ }
+ if (s->sh.slice_type == B_SLICE) {
+ for (i = 0; i < s->sh.nb_refs[L1]; i++) {
+ luma_weight_l1_flag[i] = get_bits1(gb);
+ if (!luma_weight_l1_flag[i]) {
+ s->sh.luma_weight_l1[i] = 1 << s->sh.luma_log2_weight_denom;
+ s->sh.luma_offset_l1[i] = 0;
+ }
+ }
+ if (s->sps->chroma_format_idc != 0) {
+ for (i = 0; i < s->sh.nb_refs[L1]; i++)
+ chroma_weight_l1_flag[i] = get_bits1(gb);
+ } else {
+ for (i = 0; i < s->sh.nb_refs[L1]; i++)
+ chroma_weight_l1_flag[i] = 0;
+ }
+ for (i = 0; i < s->sh.nb_refs[L1]; i++) {
+ if (luma_weight_l1_flag[i]) {
+ int delta_luma_weight_l1 = get_se_golomb(gb);
+ s->sh.luma_weight_l1[i] = (1 << s->sh.luma_log2_weight_denom) + delta_luma_weight_l1;
+ s->sh.luma_offset_l1[i] = get_se_golomb(gb);
+ }
+ if (chroma_weight_l1_flag[i]) {
+ for (j = 0; j < 2; j++) {
+ int delta_chroma_weight_l1 = get_se_golomb(gb);
+ int delta_chroma_offset_l1 = get_se_golomb(gb);
+ s->sh.chroma_weight_l1[i][j] = (1 << s->sh.chroma_log2_weight_denom) + delta_chroma_weight_l1;
+ s->sh.chroma_offset_l1[i][j] = av_clip_c((delta_chroma_offset_l1 - ((128 * s->sh.chroma_weight_l1[i][j])
+ >> s->sh.chroma_log2_weight_denom) + 128), -128, 127);
+ }
+ } else {
+ s->sh.chroma_weight_l1[i][0] = 1 << s->sh.chroma_log2_weight_denom;
+ s->sh.chroma_offset_l1[i][0] = 0;
+ s->sh.chroma_weight_l1[i][1] = 1 << s->sh.chroma_log2_weight_denom;
+ s->sh.chroma_offset_l1[i][1] = 0;
+ }
+ }
+ }
+}
+
+static int decode_lt_rps(HEVCContext *s, LongTermRPS *rps, GetBitContext *gb)
+{
+ const HEVCSPS *sps = s->sps;
+ int max_poc_lsb = 1 << sps->log2_max_poc_lsb;
+ int prev_delta_msb = 0;
+ int nb_sps = 0, nb_sh;
+ int i;
+
+ rps->nb_refs = 0;
+ if (!sps->long_term_ref_pics_present_flag)
+ return 0;
+
+ if (sps->num_long_term_ref_pics_sps > 0)
+ nb_sps = get_ue_golomb_long(gb);
+ nb_sh = get_ue_golomb_long(gb);
+
+ if (nb_sh + nb_sps > FF_ARRAY_ELEMS(rps->poc))
+ return AVERROR_INVALIDDATA;
+
+ rps->nb_refs = nb_sh + nb_sps;
+
+ for (i = 0; i < rps->nb_refs; i++) {
+ uint8_t delta_poc_msb_present;
+
+ if (i < nb_sps) {
+ uint8_t lt_idx_sps = 0;
+
+ if (sps->num_long_term_ref_pics_sps > 1)
+ lt_idx_sps = get_bits(gb, av_ceil_log2(sps->num_long_term_ref_pics_sps));
+
+ rps->poc[i] = sps->lt_ref_pic_poc_lsb_sps[lt_idx_sps];
+ rps->used[i] = sps->used_by_curr_pic_lt_sps_flag[lt_idx_sps];
+ } else {
+ rps->poc[i] = get_bits(gb, sps->log2_max_poc_lsb);
+ rps->used[i] = get_bits1(gb);
+ }
+
+ delta_poc_msb_present = get_bits1(gb);
+ if (delta_poc_msb_present) {
+ int delta = get_ue_golomb_long(gb);
+
+ if (i && i != nb_sps)
+ delta += prev_delta_msb;
+
+ rps->poc[i] += s->poc - delta * max_poc_lsb - s->sh.pic_order_cnt_lsb;
+ prev_delta_msb = delta;
+ }
+ }
+
+ return 0;
+}
+
+static int set_sps(HEVCContext *s, const HEVCSPS *sps)
+{
+ int ret;
+
+ pic_arrays_free(s);
+ ret = pic_arrays_init(s, sps);
+ if (ret < 0)
+ goto fail;
+
+ s->avctx->coded_width = sps->width;
+ s->avctx->coded_height = sps->height;
+ s->avctx->width = sps->output_width;
+ s->avctx->height = sps->output_height;
+ s->avctx->pix_fmt = sps->pix_fmt;
+ s->avctx->sample_aspect_ratio = sps->vui.sar;
+ s->avctx->has_b_frames = sps->temporal_layer[sps->max_sub_layers - 1].num_reorder_pics;
+
+ if (sps->vui.video_signal_type_present_flag)
+ s->avctx->color_range = sps->vui.video_full_range_flag ? AVCOL_RANGE_JPEG
+ : AVCOL_RANGE_MPEG;
+ else
+ s->avctx->color_range = AVCOL_RANGE_MPEG;
+
+ if (sps->vui.colour_description_present_flag) {
+ s->avctx->color_primaries = sps->vui.colour_primaries;
+ s->avctx->color_trc = sps->vui.transfer_characteristic;
+ s->avctx->colorspace = sps->vui.matrix_coeffs;
+ } else {
+ s->avctx->color_primaries = AVCOL_PRI_UNSPECIFIED;
+ s->avctx->color_trc = AVCOL_TRC_UNSPECIFIED;
+ s->avctx->colorspace = AVCOL_SPC_UNSPECIFIED;
+ }
+
+ ff_hevc_pred_init(&s->hpc, sps->bit_depth);
+ ff_hevc_dsp_init (&s->hevcdsp, sps->bit_depth);
+ ff_videodsp_init (&s->vdsp, sps->bit_depth);
+
+ if (sps->sao_enabled) {
+ av_frame_unref(s->tmp_frame);
+ ret = ff_get_buffer(s->avctx, s->tmp_frame, AV_GET_BUFFER_FLAG_REF);
+ if (ret < 0)
+ goto fail;
+ s->frame = s->tmp_frame;
+ }
+
+ s->sps = sps;
+ s->vps = (HEVCVPS*) s->vps_list[s->sps->vps_id]->data;
+ return 0;
+
+fail:
+ pic_arrays_free(s);
+ s->sps = NULL;
+ return ret;
+}
+
+static int hls_slice_header(HEVCContext *s)
+{
+ GetBitContext *gb = &s->HEVClc->gb;
+ SliceHeader *sh = &s->sh;
+ int i, j, ret;
+
+ // Coded parameters
+ sh->first_slice_in_pic_flag = get_bits1(gb);
+ if ((IS_IDR(s) || IS_BLA(s)) && sh->first_slice_in_pic_flag) {
+ s->seq_decode = (s->seq_decode + 1) & 0xff;
+ s->max_ra = INT_MAX;
+ if (IS_IDR(s))
+ ff_hevc_clear_refs(s);
+ }
+ if (s->nal_unit_type >= 16 && s->nal_unit_type <= 23)
+ sh->no_output_of_prior_pics_flag = get_bits1(gb);
+
+ sh->pps_id = get_ue_golomb_long(gb);
+ if (sh->pps_id >= MAX_PPS_COUNT || !s->pps_list[sh->pps_id]) {
+ av_log(s->avctx, AV_LOG_ERROR, "PPS id out of range: %d\n", sh->pps_id);
+ return AVERROR_INVALIDDATA;
+ }
+ if (!sh->first_slice_in_pic_flag &&
+ s->pps != (HEVCPPS*)s->pps_list[sh->pps_id]->data) {
+ av_log(s->avctx, AV_LOG_ERROR, "PPS changed between slices.\n");
+ return AVERROR_INVALIDDATA;
+ }
+ s->pps = (HEVCPPS*)s->pps_list[sh->pps_id]->data;
+
+ if (s->sps != (HEVCSPS*)s->sps_list[s->pps->sps_id]->data) {
+ s->sps = (HEVCSPS*)s->sps_list[s->pps->sps_id]->data;
+ ff_hevc_clear_refs(s);
+ ret = set_sps(s, s->sps);
+ if (ret < 0)
+ return ret;
+
+ s->seq_decode = (s->seq_decode + 1) & 0xff;
+ s->max_ra = INT_MAX;
+ }
+
+ s->avctx->profile = s->sps->ptl.general_PTL.profile_idc;
+ s->avctx->level = s->sps->ptl.general_PTL.level_idc;
+
+ sh->dependent_slice_segment_flag = 0;
+ if (!sh->first_slice_in_pic_flag) {
+ int slice_address_length;
+
+ if (s->pps->dependent_slice_segments_enabled_flag)
+ sh->dependent_slice_segment_flag = get_bits1(gb);
+
+ slice_address_length = av_ceil_log2(s->sps->ctb_width *
+ s->sps->ctb_height);
+ sh->slice_segment_addr = get_bits(gb, slice_address_length);
+ if (sh->slice_segment_addr >= s->sps->ctb_width * s->sps->ctb_height) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "Invalid slice segment address: %u.\n",
+ sh->slice_segment_addr);
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (!sh->dependent_slice_segment_flag) {
+ sh->slice_addr = sh->slice_segment_addr;
+ s->slice_idx++;
+ }
+ } else {
+ sh->slice_segment_addr = sh->slice_addr = 0;
+ s->slice_idx = 0;
+ s->slice_initialized = 0;
+ }
+
+ if (!sh->dependent_slice_segment_flag) {
+ s->slice_initialized = 0;
+
+ for (i = 0; i < s->pps->num_extra_slice_header_bits; i++)
+ skip_bits(gb, 1); // slice_reserved_undetermined_flag[]
+
+ sh->slice_type = get_ue_golomb_long(gb);
+ if (!(sh->slice_type == I_SLICE ||
+ sh->slice_type == P_SLICE ||
+ sh->slice_type == B_SLICE)) {
+ av_log(s->avctx, AV_LOG_ERROR, "Unknown slice type: %d.\n",
+ sh->slice_type);
+ return AVERROR_INVALIDDATA;
+ }
+ if (IS_IRAP(s) && sh->slice_type != I_SLICE) {
+ av_log(s->avctx, AV_LOG_ERROR, "Inter slices in an IRAP frame.\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (s->pps->output_flag_present_flag)
+ sh->pic_output_flag = get_bits1(gb);
+
+ if (s->sps->separate_colour_plane_flag)
+ sh->colour_plane_id = get_bits(gb, 2);
+
+ if (!IS_IDR(s)) {
+ int short_term_ref_pic_set_sps_flag, poc;
+
+ sh->pic_order_cnt_lsb = get_bits(gb, s->sps->log2_max_poc_lsb);
+ poc = ff_hevc_compute_poc(s, sh->pic_order_cnt_lsb);
+ if (!sh->first_slice_in_pic_flag && poc != s->poc) {
+ av_log(s->avctx, AV_LOG_WARNING,
+ "Ignoring POC change between slices: %d -> %d\n", s->poc, poc);
+ if (s->avctx->err_recognition & AV_EF_EXPLODE)
+ return AVERROR_INVALIDDATA;
+ poc = s->poc;
+ }
+ s->poc = poc;
+
+ short_term_ref_pic_set_sps_flag = get_bits1(gb);
+ if (!short_term_ref_pic_set_sps_flag) {
+ ret = ff_hevc_decode_short_term_rps(s, &sh->slice_rps, s->sps, 1);
+ if (ret < 0)
+ return ret;
+
+ sh->short_term_rps = &sh->slice_rps;
+ } else {
+ int numbits, rps_idx;
+
+ if (!s->sps->nb_st_rps) {
+ av_log(s->avctx, AV_LOG_ERROR, "No ref lists in the SPS.\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ numbits = av_ceil_log2(s->sps->nb_st_rps);
+ rps_idx = numbits > 0 ? get_bits(gb, numbits) : 0;
+ sh->short_term_rps = &s->sps->st_rps[rps_idx];
+ }
+
+ ret = decode_lt_rps(s, &sh->long_term_rps, gb);
+ if (ret < 0) {
+ av_log(s->avctx, AV_LOG_WARNING, "Invalid long term RPS.\n");
+ if (s->avctx->err_recognition & AV_EF_EXPLODE)
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (s->sps->sps_temporal_mvp_enabled_flag)
+ sh->slice_temporal_mvp_enabled_flag = get_bits1(gb);
+ else
+ sh->slice_temporal_mvp_enabled_flag = 0;
+ } else {
+ s->sh.short_term_rps = NULL;
+ s->poc = 0;
+ }
+
+ /* 8.3.1 */
+ if (s->temporal_id == 0 &&
+ s->nal_unit_type != NAL_TRAIL_N &&
+ s->nal_unit_type != NAL_TSA_N &&
+ s->nal_unit_type != NAL_STSA_N &&
+ s->nal_unit_type != NAL_RADL_N &&
+ s->nal_unit_type != NAL_RADL_R &&
+ s->nal_unit_type != NAL_RASL_N &&
+ s->nal_unit_type != NAL_RASL_R)
+ s->pocTid0 = s->poc;
+
+ if (s->sps->sao_enabled) {
+ sh->slice_sample_adaptive_offset_flag[0] = get_bits1(gb);
+ sh->slice_sample_adaptive_offset_flag[1] =
+ sh->slice_sample_adaptive_offset_flag[2] = get_bits1(gb);
+ } else {
+ sh->slice_sample_adaptive_offset_flag[0] = 0;
+ sh->slice_sample_adaptive_offset_flag[1] = 0;
+ sh->slice_sample_adaptive_offset_flag[2] = 0;
+ }
+
+ sh->nb_refs[L0] = sh->nb_refs[L1] = 0;
+ if (sh->slice_type == P_SLICE || sh->slice_type == B_SLICE) {
+ int nb_refs;
+
+ sh->nb_refs[L0] = s->pps->num_ref_idx_l0_default_active;
+ if (sh->slice_type == B_SLICE)
+ sh->nb_refs[L1] = s->pps->num_ref_idx_l1_default_active;
+
+ if (get_bits1(gb)) { // num_ref_idx_active_override_flag
+ sh->nb_refs[L0] = get_ue_golomb_long(gb) + 1;
+ if (sh->slice_type == B_SLICE)
+ sh->nb_refs[L1] = get_ue_golomb_long(gb) + 1;
+ }
+ if (sh->nb_refs[L0] > MAX_REFS || sh->nb_refs[L1] > MAX_REFS) {
+ av_log(s->avctx, AV_LOG_ERROR, "Too many refs: %d/%d.\n",
+ sh->nb_refs[L0], sh->nb_refs[L1]);
+ return AVERROR_INVALIDDATA;
+ }
+
+ sh->rpl_modification_flag[0] = 0;
+ sh->rpl_modification_flag[1] = 0;
+ nb_refs = ff_hevc_frame_nb_refs(s);
+ if (!nb_refs) {
+ av_log(s->avctx, AV_LOG_ERROR, "Zero refs for a frame with P or B slices.\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (s->pps->lists_modification_present_flag && nb_refs > 1) {
+ sh->rpl_modification_flag[0] = get_bits1(gb);
+ if (sh->rpl_modification_flag[0]) {
+ for (i = 0; i < sh->nb_refs[L0]; i++)
+ sh->list_entry_lx[0][i] = get_bits(gb, av_ceil_log2(nb_refs));
+ }
+
+ if (sh->slice_type == B_SLICE) {
+ sh->rpl_modification_flag[1] = get_bits1(gb);
+ if (sh->rpl_modification_flag[1] == 1)
+ for (i = 0; i < sh->nb_refs[L1]; i++)
+ sh->list_entry_lx[1][i] = get_bits(gb, av_ceil_log2(nb_refs));
+ }
+ }
+
+ if (sh->slice_type == B_SLICE)
+ sh->mvd_l1_zero_flag = get_bits1(gb);
+
+ if (s->pps->cabac_init_present_flag)
+ sh->cabac_init_flag = get_bits1(gb);
+ else
+ sh->cabac_init_flag = 0;
+
+ sh->collocated_ref_idx = 0;
+ if (sh->slice_temporal_mvp_enabled_flag) {
+ sh->collocated_list = L0;
+ if (sh->slice_type == B_SLICE)
+ sh->collocated_list = !get_bits1(gb);
+
+ if (sh->nb_refs[sh->collocated_list] > 1) {
+ sh->collocated_ref_idx = get_ue_golomb_long(gb);
+ if (sh->collocated_ref_idx >= sh->nb_refs[sh->collocated_list]) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "Invalid collocated_ref_idx: %d.\n",
+ sh->collocated_ref_idx);
+ return AVERROR_INVALIDDATA;
+ }
+ }
+ }
+
+ if ((s->pps->weighted_pred_flag && sh->slice_type == P_SLICE) ||
+ (s->pps->weighted_bipred_flag && sh->slice_type == B_SLICE)) {
+ pred_weight_table(s, gb);
+ }
+
+ sh->max_num_merge_cand = 5 - get_ue_golomb_long(gb);
+ if (sh->max_num_merge_cand < 1 || sh->max_num_merge_cand > 5) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "Invalid number of merging MVP candidates: %d.\n",
+ sh->max_num_merge_cand);
+ return AVERROR_INVALIDDATA;
+ }
+ }
+
+ sh->slice_qp_delta = get_se_golomb(gb);
+ if (s->pps->pic_slice_level_chroma_qp_offsets_present_flag) {
+ sh->slice_cb_qp_offset = get_se_golomb(gb);
+ sh->slice_cr_qp_offset = get_se_golomb(gb);
+ } else {
+ sh->slice_cb_qp_offset = 0;
+ sh->slice_cr_qp_offset = 0;
+ }
+
+ if (s->pps->deblocking_filter_control_present_flag) {
+ int deblocking_filter_override_flag = 0;
+
+ if (s->pps->deblocking_filter_override_enabled_flag)
+ deblocking_filter_override_flag = get_bits1(gb);
+
+ if (deblocking_filter_override_flag) {
+ sh->disable_deblocking_filter_flag = get_bits1(gb);
+ if (!sh->disable_deblocking_filter_flag) {
+ sh->beta_offset = get_se_golomb(gb) * 2;
+ sh->tc_offset = get_se_golomb(gb) * 2;
+ }
+ } else {
+ sh->disable_deblocking_filter_flag = s->pps->disable_dbf;
+ sh->beta_offset = s->pps->beta_offset;
+ sh->tc_offset = s->pps->tc_offset;
+ }
+ } else {
+ sh->disable_deblocking_filter_flag = 0;
+ sh->beta_offset = 0;
+ sh->tc_offset = 0;
+ }
+
+ if (s->pps->seq_loop_filter_across_slices_enabled_flag &&
+ (sh->slice_sample_adaptive_offset_flag[0] ||
+ sh->slice_sample_adaptive_offset_flag[1] ||
+ !sh->disable_deblocking_filter_flag)) {
+ sh->slice_loop_filter_across_slices_enabled_flag = get_bits1(gb);
+ } else {
+ sh->slice_loop_filter_across_slices_enabled_flag = s->pps->seq_loop_filter_across_slices_enabled_flag;
+ }
+ } else if (!s->slice_initialized) {
+ av_log(s->avctx, AV_LOG_ERROR, "Independent slice segment missing.\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ sh->num_entry_point_offsets = 0;
+ if (s->pps->tiles_enabled_flag || s->pps->entropy_coding_sync_enabled_flag) {
+ sh->num_entry_point_offsets = get_ue_golomb_long(gb);
+ if (sh->num_entry_point_offsets > 0) {
+ int offset_len = get_ue_golomb_long(gb) + 1;
+ int segments = offset_len >> 4;
+ int rest = (offset_len & 15);
+ av_freep(&sh->entry_point_offset);
+ av_freep(&sh->offset);
+ av_freep(&sh->size);
+ sh->entry_point_offset = av_malloc(sh->num_entry_point_offsets * sizeof(int));
+ sh->offset = av_malloc(sh->num_entry_point_offsets * sizeof(int));
+ sh->size = av_malloc(sh->num_entry_point_offsets * sizeof(int));
+ for (i = 0; i < sh->num_entry_point_offsets; i++) {
+ int val = 0;
+ for (j = 0; j < segments; j++) {
+ val <<= 16;
+ val += get_bits(gb, 16);
+ }
+ if (rest) {
+ val <<= rest;
+ val += get_bits(gb, rest);
+ }
+ sh->entry_point_offset[i] = val + 1; // +1; // +1 to get the size
+ }
+ if (s->threads_number > 1 && (s->pps->num_tile_rows > 1 || s->pps->num_tile_columns > 1)) {
+ s->enable_parallel_tiles = 0; // TODO: you can enable tiles in parallel here
+ s->threads_number = 1;
+ } else
+ s->enable_parallel_tiles = 0;
+ } else
+ s->enable_parallel_tiles = 0;
+ }
+
+ if (s->pps->slice_header_extension_present_flag) {
+ int length = get_ue_golomb_long(gb);
+ for (i = 0; i < length; i++)
+ skip_bits(gb, 8); // slice_header_extension_data_byte
+ }
+
+ // Inferred parameters
+ sh->slice_qp = 26 + s->pps->pic_init_qp_minus26 + sh->slice_qp_delta;
+ sh->slice_ctb_addr_rs = sh->slice_segment_addr;
+
+ s->HEVClc->first_qp_group = !s->sh.dependent_slice_segment_flag;
+
+ if (!s->pps->cu_qp_delta_enabled_flag)
+ s->HEVClc->qp_y = ((s->sh.slice_qp + 52 + 2 * s->sps->qp_bd_offset) %
+ (52 + s->sps->qp_bd_offset)) - s->sps->qp_bd_offset;
+
+ s->slice_initialized = 1;
+
+ return 0;
+}
+
+#define CTB(tab, x, y) ((tab)[(y) * s->sps->ctb_width + (x)])
+
+#define SET_SAO(elem, value) \
+do { \
+ if (!sao_merge_up_flag && !sao_merge_left_flag) \
+ sao->elem = value; \
+ else if (sao_merge_left_flag) \
+ sao->elem = CTB(s->sao, rx-1, ry).elem; \
+ else if (sao_merge_up_flag) \
+ sao->elem = CTB(s->sao, rx, ry-1).elem; \
+ else \
+ sao->elem = 0; \
+} while (0)
+
+static void hls_sao_param(HEVCContext *s, int rx, int ry)
+{
+ HEVCLocalContext *lc = s->HEVClc;
+ int sao_merge_left_flag = 0;
+ int sao_merge_up_flag = 0;
+ int shift = s->sps->bit_depth - FFMIN(s->sps->bit_depth, 10);
+ SAOParams *sao = &CTB(s->sao, rx, ry);
+ int c_idx, i;
+
+ if (s->sh.slice_sample_adaptive_offset_flag[0] ||
+ s->sh.slice_sample_adaptive_offset_flag[1]) {
+ if (rx > 0) {
+ if (lc->ctb_left_flag)
+ sao_merge_left_flag = ff_hevc_sao_merge_flag_decode(s);
+ }
+ if (ry > 0 && !sao_merge_left_flag) {
+ if (lc->ctb_up_flag)
+ sao_merge_up_flag = ff_hevc_sao_merge_flag_decode(s);
+ }
+ }
+
+ for (c_idx = 0; c_idx < 3; c_idx++) {
+ if (!s->sh.slice_sample_adaptive_offset_flag[c_idx]) {
+ sao->type_idx[c_idx] = SAO_NOT_APPLIED;
+ continue;
+ }
+
+ if (c_idx == 2) {
+ sao->type_idx[2] = sao->type_idx[1];
+ sao->eo_class[2] = sao->eo_class[1];
+ } else {
+ SET_SAO(type_idx[c_idx], ff_hevc_sao_type_idx_decode(s));
+ }
+
+ if (sao->type_idx[c_idx] == SAO_NOT_APPLIED)
+ continue;
+
+ for (i = 0; i < 4; i++)
+ SET_SAO(offset_abs[c_idx][i], ff_hevc_sao_offset_abs_decode(s));
+
+ if (sao->type_idx[c_idx] == SAO_BAND) {
+ for (i = 0; i < 4; i++) {
+ if (sao->offset_abs[c_idx][i]) {
+ SET_SAO(offset_sign[c_idx][i],
+ ff_hevc_sao_offset_sign_decode(s));
+ } else {
+ sao->offset_sign[c_idx][i] = 0;
+ }
+ }
+ SET_SAO(band_position[c_idx], ff_hevc_sao_band_position_decode(s));
+ } else if (c_idx != 2) {
+ SET_SAO(eo_class[c_idx], ff_hevc_sao_eo_class_decode(s));
+ }
+
+ // Inferred parameters
+ sao->offset_val[c_idx][0] = 0;
+ for (i = 0; i < 4; i++) {
+ sao->offset_val[c_idx][i + 1] = sao->offset_abs[c_idx][i] << shift;
+ if (sao->type_idx[c_idx] == SAO_EDGE) {
+ if (i > 1)
+ sao->offset_val[c_idx][i + 1] = -sao->offset_val[c_idx][i + 1];
+ } else if (sao->offset_sign[c_idx][i]) {
+ sao->offset_val[c_idx][i + 1] = -sao->offset_val[c_idx][i + 1];
+ }
+ }
+ }
+}
+
+#undef SET_SAO
+#undef CTB
+
+static void hls_transform_unit(HEVCContext *s, int x0, int y0,
+ int xBase, int yBase, int cb_xBase, int cb_yBase,
+ int log2_cb_size, int log2_trafo_size,
+ int trafo_depth, int blk_idx)
+{
+ HEVCLocalContext *lc = s->HEVClc;
+
+ if (lc->cu.pred_mode == MODE_INTRA) {
+ int trafo_size = 1 << log2_trafo_size;
+ ff_hevc_set_neighbour_available(s, x0, y0, trafo_size, trafo_size);
+
+ s->hpc.intra_pred(s, x0, y0, log2_trafo_size, 0);
+ if (log2_trafo_size > 2) {
+ trafo_size = trafo_size << (s->sps->hshift[1] - 1);
+ ff_hevc_set_neighbour_available(s, x0, y0, trafo_size, trafo_size);
+ s->hpc.intra_pred(s, x0, y0, log2_trafo_size - 1, 1);
+ s->hpc.intra_pred(s, x0, y0, log2_trafo_size - 1, 2);
+ } else if (blk_idx == 3) {
+ trafo_size = trafo_size << s->sps->hshift[1];
+ ff_hevc_set_neighbour_available(s, xBase, yBase,
+ trafo_size, trafo_size);
+ s->hpc.intra_pred(s, xBase, yBase, log2_trafo_size, 1);
+ s->hpc.intra_pred(s, xBase, yBase, log2_trafo_size, 2);
+ }
+ }
+
+ if (lc->tt.cbf_luma ||
+ SAMPLE_CBF(lc->tt.cbf_cb[trafo_depth], x0, y0) ||
+ SAMPLE_CBF(lc->tt.cbf_cr[trafo_depth], x0, y0)) {
+ int scan_idx = SCAN_DIAG;
+ int scan_idx_c = SCAN_DIAG;
+
+ if (s->pps->cu_qp_delta_enabled_flag && !lc->tu.is_cu_qp_delta_coded) {
+ lc->tu.cu_qp_delta = ff_hevc_cu_qp_delta_abs(s);
+ if (lc->tu.cu_qp_delta != 0)
+ if (ff_hevc_cu_qp_delta_sign_flag(s) == 1)
+ lc->tu.cu_qp_delta = -lc->tu.cu_qp_delta;
+ lc->tu.is_cu_qp_delta_coded = 1;
+ ff_hevc_set_qPy(s, x0, y0, cb_xBase, cb_yBase, log2_cb_size);
+ }
+
+ if (lc->cu.pred_mode == MODE_INTRA && log2_trafo_size < 4) {
+ if (lc->tu.cur_intra_pred_mode >= 6 &&
+ lc->tu.cur_intra_pred_mode <= 14) {
+ scan_idx = SCAN_VERT;
+ } else if (lc->tu.cur_intra_pred_mode >= 22 &&
+ lc->tu.cur_intra_pred_mode <= 30) {
+ scan_idx = SCAN_HORIZ;
+ }
+
+ if (lc->pu.intra_pred_mode_c >= 6 &&
+ lc->pu.intra_pred_mode_c <= 14) {
+ scan_idx_c = SCAN_VERT;
+ } else if (lc->pu.intra_pred_mode_c >= 22 &&
+ lc->pu.intra_pred_mode_c <= 30) {
+ scan_idx_c = SCAN_HORIZ;
+ }
+ }
+
+ if (lc->tt.cbf_luma)
+ ff_hevc_hls_residual_coding(s, x0, y0, log2_trafo_size, scan_idx, 0);
+ if (log2_trafo_size > 2) {
+ if (SAMPLE_CBF(lc->tt.cbf_cb[trafo_depth], x0, y0))
+ ff_hevc_hls_residual_coding(s, x0, y0, log2_trafo_size - 1, scan_idx_c, 1);
+ if (SAMPLE_CBF(lc->tt.cbf_cr[trafo_depth], x0, y0))
+ ff_hevc_hls_residual_coding(s, x0, y0, log2_trafo_size - 1, scan_idx_c, 2);
+ } else if (blk_idx == 3) {
+ if (SAMPLE_CBF(lc->tt.cbf_cb[trafo_depth], xBase, yBase))
+ ff_hevc_hls_residual_coding(s, xBase, yBase, log2_trafo_size, scan_idx_c, 1);
+ if (SAMPLE_CBF(lc->tt.cbf_cr[trafo_depth], xBase, yBase))
+ ff_hevc_hls_residual_coding(s, xBase, yBase, log2_trafo_size, scan_idx_c, 2);
+ }
+ }
+}
+
+static void set_deblocking_bypass(HEVCContext *s, int x0, int y0, int log2_cb_size)
+{
+ int cb_size = 1 << log2_cb_size;
+ int log2_min_pu_size = s->sps->log2_min_pu_size;
+
+ int min_pu_width = s->sps->min_pu_width;
+ int x_end = FFMIN(x0 + cb_size, s->sps->width);
+ int y_end = FFMIN(y0 + cb_size, s->sps->height);
+ int i, j;
+
+ for (j = (y0 >> log2_min_pu_size); j < (y_end >> log2_min_pu_size); j++)
+ for (i = (x0 >> log2_min_pu_size); i < (x_end >> log2_min_pu_size); i++)
+ s->is_pcm[i + j * min_pu_width] = 2;
+}
+
+static void hls_transform_tree(HEVCContext *s, int x0, int y0,
+ int xBase, int yBase, int cb_xBase, int cb_yBase,
+ int log2_cb_size, int log2_trafo_size,
+ int trafo_depth, int blk_idx)
+{
+ HEVCLocalContext *lc = s->HEVClc;
+ uint8_t split_transform_flag;
+
+ if (trafo_depth > 0 && log2_trafo_size == 2) {
+ SAMPLE_CBF(lc->tt.cbf_cb[trafo_depth], x0, y0) =
+ SAMPLE_CBF(lc->tt.cbf_cb[trafo_depth - 1], xBase, yBase);
+ SAMPLE_CBF(lc->tt.cbf_cr[trafo_depth], x0, y0) =
+ SAMPLE_CBF(lc->tt.cbf_cr[trafo_depth - 1], xBase, yBase);
+ } else {
+ SAMPLE_CBF(lc->tt.cbf_cb[trafo_depth], x0, y0) =
+ SAMPLE_CBF(lc->tt.cbf_cr[trafo_depth], x0, y0) = 0;
+ }
+
+ if (lc->cu.intra_split_flag) {
+ if (trafo_depth == 1)
+ lc->tu.cur_intra_pred_mode = lc->pu.intra_pred_mode[blk_idx];
+ } else {
+ lc->tu.cur_intra_pred_mode = lc->pu.intra_pred_mode[0];
+ }
+
+ lc->tt.cbf_luma = 1;
+
+ lc->tt.inter_split_flag = s->sps->max_transform_hierarchy_depth_inter == 0 &&
+ lc->cu.pred_mode == MODE_INTER &&
+ lc->cu.part_mode != PART_2Nx2N &&
+ trafo_depth == 0;
+
+ if (log2_trafo_size <= s->sps->log2_max_trafo_size &&
+ log2_trafo_size > s->sps->log2_min_tb_size &&
+ trafo_depth < lc->cu.max_trafo_depth &&
+ !(lc->cu.intra_split_flag && trafo_depth == 0)) {
+ split_transform_flag = ff_hevc_split_transform_flag_decode(s, log2_trafo_size);
+ } else {
+ split_transform_flag = log2_trafo_size > s->sps->log2_max_trafo_size ||
+ (lc->cu.intra_split_flag && trafo_depth == 0) ||
+ lc->tt.inter_split_flag;
+ }
+
+ if (log2_trafo_size > 2) {
+ if (trafo_depth == 0 ||
+ SAMPLE_CBF(lc->tt.cbf_cb[trafo_depth - 1], xBase, yBase)) {
+ SAMPLE_CBF(lc->tt.cbf_cb[trafo_depth], x0, y0) =
+ ff_hevc_cbf_cb_cr_decode(s, trafo_depth);
+ }
+
+ if (trafo_depth == 0 ||
+ SAMPLE_CBF(lc->tt.cbf_cr[trafo_depth - 1], xBase, yBase)) {
+ SAMPLE_CBF(lc->tt.cbf_cr[trafo_depth], x0, y0) =
+ ff_hevc_cbf_cb_cr_decode(s, trafo_depth);
+ }
+ }
+
+ if (split_transform_flag) {
+ int x1 = x0 + ((1 << log2_trafo_size) >> 1);
+ int y1 = y0 + ((1 << log2_trafo_size) >> 1);
+
+ hls_transform_tree(s, x0, y0, x0, y0, cb_xBase, cb_yBase, log2_cb_size,
+ log2_trafo_size - 1, trafo_depth + 1, 0);
+ hls_transform_tree(s, x1, y0, x0, y0, cb_xBase, cb_yBase, log2_cb_size,
+ log2_trafo_size - 1, trafo_depth + 1, 1);
+ hls_transform_tree(s, x0, y1, x0, y0, cb_xBase, cb_yBase, log2_cb_size,
+ log2_trafo_size - 1, trafo_depth + 1, 2);
+ hls_transform_tree(s, x1, y1, x0, y0, cb_xBase, cb_yBase, log2_cb_size,
+ log2_trafo_size - 1, trafo_depth + 1, 3);
+ } else {
+ int min_tu_size = 1 << s->sps->log2_min_tb_size;
+ int log2_min_tu_size = s->sps->log2_min_tb_size;
+ int min_tu_width = s->sps->min_tb_width;
+
+ if (lc->cu.pred_mode == MODE_INTRA || trafo_depth != 0 ||
+ SAMPLE_CBF(lc->tt.cbf_cb[trafo_depth], x0, y0) ||
+ SAMPLE_CBF(lc->tt.cbf_cr[trafo_depth], x0, y0)) {
+ lc->tt.cbf_luma = ff_hevc_cbf_luma_decode(s, trafo_depth);
+ }
+
+ hls_transform_unit(s, x0, y0, xBase, yBase, cb_xBase, cb_yBase,
+ log2_cb_size, log2_trafo_size, trafo_depth, blk_idx);
+
+ // TODO: store cbf_luma somewhere else
+ if (lc->tt.cbf_luma) {
+ int i, j;
+ for (i = 0; i < (1 << log2_trafo_size); i += min_tu_size)
+ for (j = 0; j < (1 << log2_trafo_size); j += min_tu_size) {
+ int x_tu = (x0 + j) >> log2_min_tu_size;
+ int y_tu = (y0 + i) >> log2_min_tu_size;
+ s->cbf_luma[y_tu * min_tu_width + x_tu] = 1;
+ }
+ }
+ if (!s->sh.disable_deblocking_filter_flag) {
+ ff_hevc_deblocking_boundary_strengths(s, x0, y0, log2_trafo_size,
+ lc->slice_or_tiles_up_boundary,
+ lc->slice_or_tiles_left_boundary);
+ if (s->pps->transquant_bypass_enable_flag &&
+ lc->cu.cu_transquant_bypass_flag)
+ set_deblocking_bypass(s, x0, y0, log2_trafo_size);
+ }
+ }
+}
+
+static int hls_pcm_sample(HEVCContext *s, int x0, int y0, int log2_cb_size)
+{
+ //TODO: non-4:2:0 support
+ HEVCLocalContext *lc = s->HEVClc;
+ GetBitContext gb;
+ int cb_size = 1 << log2_cb_size;
+ int stride0 = s->frame->linesize[0];
+ uint8_t *dst0 = &s->frame->data[0][y0 * stride0 + (x0 << s->sps->pixel_shift)];
+ int stride1 = s->frame->linesize[1];
+ uint8_t *dst1 = &s->frame->data[1][(y0 >> s->sps->vshift[1]) * stride1 + ((x0 >> s->sps->hshift[1]) << s->sps->pixel_shift)];
+ int stride2 = s->frame->linesize[2];
+ uint8_t *dst2 = &s->frame->data[2][(y0 >> s->sps->vshift[2]) * stride2 + ((x0 >> s->sps->hshift[2]) << s->sps->pixel_shift)];
+
+ int length = cb_size * cb_size * s->sps->pcm.bit_depth + ((cb_size * cb_size) >> 1) * s->sps->pcm.bit_depth_chroma;
+ const uint8_t *pcm = skip_bytes(&s->HEVClc->cc, (length + 7) >> 3);
+ int ret;
+
+ ff_hevc_deblocking_boundary_strengths(s, x0, y0, log2_cb_size,
+ lc->slice_or_tiles_up_boundary,
+ lc->slice_or_tiles_left_boundary);
+
+ ret = init_get_bits(&gb, pcm, length);
+ if (ret < 0)
+ return ret;
+
+ s->hevcdsp.put_pcm(dst0, stride0, cb_size, &gb, s->sps->pcm.bit_depth);
+ s->hevcdsp.put_pcm(dst1, stride1, cb_size / 2, &gb, s->sps->pcm.bit_depth_chroma);
+ s->hevcdsp.put_pcm(dst2, stride2, cb_size / 2, &gb, s->sps->pcm.bit_depth_chroma);
+ return 0;
+}
+
+/**
+ * 8.5.3.2.2.1 Luma sample interpolation process
+ *
+ * @param s HEVC decoding context
+ * @param dst target buffer for block data at block position
+ * @param dststride stride of the dst buffer
+ * @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)
+ * @param block_w width of block
+ * @param block_h height of block
+ */
+static void luma_mc(HEVCContext *s, int16_t *dst, ptrdiff_t dststride,
+ AVFrame *ref, const Mv *mv, int x_off, int y_off,
+ int block_w, int block_h)
+{
+ HEVCLocalContext *lc = s->HEVClc;
+ uint8_t *src = ref->data[0];
+ ptrdiff_t srcstride = ref->linesize[0];
+ int pic_width = s->sps->width;
+ int pic_height = s->sps->height;
+
+ int mx = mv->x & 3;
+ int my = mv->y & 3;
+ int extra_left = ff_hevc_qpel_extra_before[mx];
+ int extra_top = ff_hevc_qpel_extra_before[my];
+
+ x_off += mv->x >> 2;
+ y_off += mv->y >> 2;
+ src += y_off * srcstride + (x_off << s->sps->pixel_shift);
+
+ if (x_off < extra_left || y_off < extra_top ||
+ x_off >= pic_width - block_w - ff_hevc_qpel_extra_after[mx] ||
+ y_off >= pic_height - block_h - ff_hevc_qpel_extra_after[my]) {
+ int offset = extra_top * srcstride + (extra_left << s->sps->pixel_shift);
+
+ s->vdsp.emulated_edge_mc(lc->edge_emu_buffer, src - offset,
+ srcstride, srcstride,
+ block_w + ff_hevc_qpel_extra[mx],
+ block_h + ff_hevc_qpel_extra[my],
+ x_off - extra_left, y_off - extra_top,
+ pic_width, pic_height);
+ src = lc->edge_emu_buffer + offset;
+ }
+ s->hevcdsp.put_hevc_qpel[my][mx](dst, dststride, src, srcstride, block_w,
+ block_h, lc->mc_buffer);
+}
+
+/**
+ * 8.5.3.2.2.2 Chroma sample interpolation process
+ *
+ * @param s HEVC decoding context
+ * @param dst1 target buffer for block data at block position (U plane)
+ * @param dst2 target buffer for block data at block position (V plane)
+ * @param dststride stride of the dst1 and dst2 buffers
+ * @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)
+ * @param block_w width of block
+ * @param block_h height of block
+ */
+static void chroma_mc(HEVCContext *s, int16_t *dst1, int16_t *dst2,
+ ptrdiff_t dststride, AVFrame *ref, const Mv *mv,
+ int x_off, int y_off, int block_w, int block_h)
+{
+ HEVCLocalContext *lc = s->HEVClc;
+ uint8_t *src1 = ref->data[1];
+ uint8_t *src2 = ref->data[2];
+ ptrdiff_t src1stride = ref->linesize[1];
+ ptrdiff_t src2stride = ref->linesize[2];
+ int pic_width = s->sps->width >> 1;
+ int pic_height = s->sps->height >> 1;
+
+ int mx = mv->x & 7;
+ int my = mv->y & 7;
+
+ x_off += mv->x >> 3;
+ y_off += mv->y >> 3;
+ src1 += y_off * src1stride + (x_off << s->sps->pixel_shift);
+ src2 += y_off * src2stride + (x_off << s->sps->pixel_shift);
+
+ if (x_off < EPEL_EXTRA_BEFORE || y_off < EPEL_EXTRA_AFTER ||
+ x_off >= pic_width - block_w - EPEL_EXTRA_AFTER ||
+ y_off >= pic_height - block_h - EPEL_EXTRA_AFTER) {
+ int offset1 = EPEL_EXTRA_BEFORE * (src1stride + (1 << s->sps->pixel_shift));
+ int offset2 = EPEL_EXTRA_BEFORE * (src2stride + (1 << s->sps->pixel_shift));
+
+ s->vdsp.emulated_edge_mc(lc->edge_emu_buffer, src1 - offset1,
+ src1stride, src1stride,
+ block_w + EPEL_EXTRA, block_h + EPEL_EXTRA,
+ x_off - EPEL_EXTRA_BEFORE,
+ y_off - EPEL_EXTRA_BEFORE,
+ pic_width, pic_height);
+
+ src1 = lc->edge_emu_buffer + offset1;
+ s->hevcdsp.put_hevc_epel[!!my][!!mx](dst1, dststride, src1, src1stride,
+ block_w, block_h, mx, my, lc->mc_buffer);
+
+ s->vdsp.emulated_edge_mc(lc->edge_emu_buffer, src2 - offset2,
+ src2stride, src2stride,
+ block_w + EPEL_EXTRA, block_h + EPEL_EXTRA,
+ x_off - EPEL_EXTRA_BEFORE,
+ y_off - EPEL_EXTRA_BEFORE,
+ pic_width, pic_height);
+ src2 = lc->edge_emu_buffer + offset2;
+ s->hevcdsp.put_hevc_epel[!!my][!!mx](dst2, dststride, src2, src2stride,
+ block_w, block_h, mx, my,
+ lc->mc_buffer);
+ } else {
+ s->hevcdsp.put_hevc_epel[!!my][!!mx](dst1, dststride, src1, src1stride,
+ block_w, block_h, mx, my,
+ lc->mc_buffer);
+ s->hevcdsp.put_hevc_epel[!!my][!!mx](dst2, dststride, src2, src2stride,
+ block_w, block_h, mx, my,
+ lc->mc_buffer);
+ }
+}
+
+static void hevc_await_progress(HEVCContext *s, HEVCFrame *ref,
+ const Mv *mv, int y0, int height)
+{
+ int y = (mv->y >> 2) + y0 + height + 9;
+
+ if (s->threads_type == FF_THREAD_FRAME )
+ ff_thread_await_progress(&ref->tf, y, 0);
+}
+
+static void hls_prediction_unit(HEVCContext *s, int x0, int y0,
+ int nPbW, int nPbH,
+ int log2_cb_size, int partIdx)
+{
+#define POS(c_idx, x, y) \
+ &s->frame->data[c_idx][((y) >> s->sps->vshift[c_idx]) * s->frame->linesize[c_idx] + \
+ (((x) >> s->sps->hshift[c_idx]) << s->sps->pixel_shift)]
+ HEVCLocalContext *lc = s->HEVClc;
+ int merge_idx = 0;
+ struct MvField current_mv = {{{ 0 }}};
+
+ int min_pu_width = s->sps->min_pu_width;
+
+ MvField *tab_mvf = s->ref->tab_mvf;
+ RefPicList *refPicList = s->ref->refPicList;
+ HEVCFrame *ref0, *ref1;
+
+ int tmpstride = MAX_PB_SIZE;
+
+ uint8_t *dst0 = POS(0, x0, y0);
+ uint8_t *dst1 = POS(1, x0, y0);
+ uint8_t *dst2 = POS(2, x0, y0);
+ int log2_min_cb_size = s->sps->log2_min_cb_size;
+ int min_cb_width = s->sps->min_cb_width;
+ int x_cb = x0 >> log2_min_cb_size;
+ int y_cb = y0 >> log2_min_cb_size;
+ int ref_idx[2];
+ int mvp_flag[2];
+ int x_pu, y_pu;
+ int i, j;
+
+ if (SAMPLE_CTB(s->skip_flag, x_cb, y_cb)) {
+ if (s->sh.max_num_merge_cand > 1)
+ merge_idx = ff_hevc_merge_idx_decode(s);
+ else
+ merge_idx = 0;
+
+ ff_hevc_luma_mv_merge_mode(s, x0, y0,
+ 1 << log2_cb_size,
+ 1 << log2_cb_size,
+ log2_cb_size, partIdx,
+ merge_idx, ¤t_mv);
+ x_pu = x0 >> s->sps->log2_min_pu_size;
+ y_pu = y0 >> s->sps->log2_min_pu_size;
+
+ for (i = 0; i < nPbW >> s->sps->log2_min_pu_size; i++)
+ for (j = 0; j < nPbH >> s->sps->log2_min_pu_size; j++)
+ tab_mvf[(y_pu + j) * min_pu_width + x_pu + i] = current_mv;
+ } else { /* MODE_INTER */
+ lc->pu.merge_flag = ff_hevc_merge_flag_decode(s);
+ if (lc->pu.merge_flag) {
+ if (s->sh.max_num_merge_cand > 1)
+ merge_idx = ff_hevc_merge_idx_decode(s);
+ else
+ merge_idx = 0;
+
+ ff_hevc_luma_mv_merge_mode(s, x0, y0, nPbW, nPbH, log2_cb_size,
+ partIdx, merge_idx, ¤t_mv);
+ x_pu = x0 >> s->sps->log2_min_pu_size;
+ y_pu = y0 >> s->sps->log2_min_pu_size;
+
+ for (i = 0; i < nPbW >> s->sps->log2_min_pu_size; i++)
+ for (j = 0; j < nPbH >> s->sps->log2_min_pu_size; j++)
+ tab_mvf[(y_pu + j) * min_pu_width + x_pu + i] = current_mv;
+ } else {
+ enum InterPredIdc inter_pred_idc = PRED_L0;
+ ff_hevc_set_neighbour_available(s, x0, y0, nPbW, nPbH);
+ if (s->sh.slice_type == B_SLICE)
+ inter_pred_idc = ff_hevc_inter_pred_idc_decode(s, nPbW, nPbH);
+
+ if (inter_pred_idc != PRED_L1) {
+ if (s->sh.nb_refs[L0]) {
+ ref_idx[0] = ff_hevc_ref_idx_lx_decode(s, s->sh.nb_refs[L0]);
+ current_mv.ref_idx[0] = ref_idx[0];
+ }
+ current_mv.pred_flag[0] = 1;
+ ff_hevc_hls_mvd_coding(s, x0, y0, 0);
+ mvp_flag[0] = ff_hevc_mvp_lx_flag_decode(s);
+ ff_hevc_luma_mv_mvp_mode(s, x0, y0, nPbW, nPbH, log2_cb_size,
+ partIdx, merge_idx, ¤t_mv,
+ mvp_flag[0], 0);
+ current_mv.mv[0].x += lc->pu.mvd.x;
+ current_mv.mv[0].y += lc->pu.mvd.y;
+ }
+
+ if (inter_pred_idc != PRED_L0) {
+ if (s->sh.nb_refs[L1]) {
+ ref_idx[1] = ff_hevc_ref_idx_lx_decode(s, s->sh.nb_refs[L1]);
+ current_mv.ref_idx[1] = ref_idx[1];
+ }
+
+ if (s->sh.mvd_l1_zero_flag == 1 && inter_pred_idc == PRED_BI) {
+ lc->pu.mvd.x = 0;
+ lc->pu.mvd.y = 0;
+ } else {
+ ff_hevc_hls_mvd_coding(s, x0, y0, 1);
+ }
+
+ current_mv.pred_flag[1] = 1;
+ mvp_flag[1] = ff_hevc_mvp_lx_flag_decode(s);
+ ff_hevc_luma_mv_mvp_mode(s, x0, y0, nPbW, nPbH, log2_cb_size,
+ partIdx, merge_idx, ¤t_mv,
+ mvp_flag[1], 1);
+ current_mv.mv[1].x += lc->pu.mvd.x;
+ current_mv.mv[1].y += lc->pu.mvd.y;
+ }
+
+ x_pu = x0 >> s->sps->log2_min_pu_size;
+ y_pu = y0 >> s->sps->log2_min_pu_size;
+
+ for (i = 0; i < nPbW >> s->sps->log2_min_pu_size; i++)
+ for(j = 0; j < nPbH >> s->sps->log2_min_pu_size; j++)
+ tab_mvf[(y_pu + j) * min_pu_width + x_pu + i] = current_mv;
+ }
+ }
+
+ if (current_mv.pred_flag[0]) {
+ ref0 = refPicList[0].ref[current_mv.ref_idx[0]];
+ if (!ref0)
+ return;
+ hevc_await_progress(s, ref0, ¤t_mv.mv[0], y0, nPbH);
+ }
+ if (current_mv.pred_flag[1]) {
+ ref1 = refPicList[1].ref[current_mv.ref_idx[1]];
+ if (!ref1)
+ return;
+ hevc_await_progress(s, ref1, ¤t_mv.mv[1], y0, nPbH);
+ }
+
+ if (current_mv.pred_flag[0] && !current_mv.pred_flag[1]) {
+ DECLARE_ALIGNED(16, int16_t, tmp[MAX_PB_SIZE * MAX_PB_SIZE]);
+ DECLARE_ALIGNED(16, int16_t, tmp2[MAX_PB_SIZE * MAX_PB_SIZE]);
+
+ luma_mc(s, tmp, tmpstride, ref0->frame,
+ ¤t_mv.mv[0], x0, y0, nPbW, nPbH);
+
+ if ((s->sh.slice_type == P_SLICE && s->pps->weighted_pred_flag) ||
+ (s->sh.slice_type == B_SLICE && s->pps->weighted_bipred_flag)) {
+ s->hevcdsp.weighted_pred(s->sh.luma_log2_weight_denom,
+ s->sh.luma_weight_l0[current_mv.ref_idx[0]],
+ s->sh.luma_offset_l0[current_mv.ref_idx[0]],
+ dst0, s->frame->linesize[0], tmp,
+ tmpstride, nPbW, nPbH);
+ } else {
+ s->hevcdsp.put_unweighted_pred(dst0, s->frame->linesize[0], tmp, tmpstride, nPbW, nPbH);
+ }
+ chroma_mc(s, tmp, tmp2, tmpstride, ref0->frame,
+ ¤t_mv.mv[0], x0 / 2, y0 / 2, nPbW / 2, nPbH / 2);
+
+ if ((s->sh.slice_type == P_SLICE && s->pps->weighted_pred_flag) ||
+ (s->sh.slice_type == B_SLICE && s->pps->weighted_bipred_flag)) {
+ s->hevcdsp.weighted_pred(s->sh.chroma_log2_weight_denom,
+ s->sh.chroma_weight_l0[current_mv.ref_idx[0]][0],
+ s->sh.chroma_offset_l0[current_mv.ref_idx[0]][0],
+ dst1, s->frame->linesize[1], tmp, tmpstride,
+ nPbW / 2, nPbH / 2);
+ s->hevcdsp.weighted_pred(s->sh.chroma_log2_weight_denom,
+ s->sh.chroma_weight_l0[current_mv.ref_idx[0]][1],
+ s->sh.chroma_offset_l0[current_mv.ref_idx[0]][1],
+ dst2, s->frame->linesize[2], tmp2, tmpstride,
+ nPbW / 2, nPbH / 2);
+ } else {
+ s->hevcdsp.put_unweighted_pred(dst1, s->frame->linesize[1], tmp, tmpstride, nPbW/2, nPbH/2);
+ s->hevcdsp.put_unweighted_pred(dst2, s->frame->linesize[2], tmp2, tmpstride, nPbW/2, nPbH/2);
+ }
+ } else if (!current_mv.pred_flag[0] && current_mv.pred_flag[1]) {
+ DECLARE_ALIGNED(16, int16_t, tmp [MAX_PB_SIZE * MAX_PB_SIZE]);
+ DECLARE_ALIGNED(16, int16_t, tmp2[MAX_PB_SIZE * MAX_PB_SIZE]);
+
+ if (!ref1)
+ return;
+
+ luma_mc(s, tmp, tmpstride, ref1->frame,
+ ¤t_mv.mv[1], x0, y0, nPbW, nPbH);
+
+ if ((s->sh.slice_type == P_SLICE && s->pps->weighted_pred_flag) ||
+ (s->sh.slice_type == B_SLICE && s->pps->weighted_bipred_flag)) {
+ s->hevcdsp.weighted_pred(s->sh.luma_log2_weight_denom,
+ s->sh.luma_weight_l1[current_mv.ref_idx[1]],
+ s->sh.luma_offset_l1[current_mv.ref_idx[1]],
+ dst0, s->frame->linesize[0], tmp, tmpstride,
+ nPbW, nPbH);
+ } else {
+ s->hevcdsp.put_unweighted_pred(dst0, s->frame->linesize[0], tmp, tmpstride, nPbW, nPbH);
+ }
+
+ chroma_mc(s, tmp, tmp2, tmpstride, ref1->frame,
+ ¤t_mv.mv[1], x0/2, y0/2, nPbW/2, nPbH/2);
+
+ if ((s->sh.slice_type == P_SLICE && s->pps->weighted_pred_flag) ||
+ (s->sh.slice_type == B_SLICE && s->pps->weighted_bipred_flag)) {
+ s->hevcdsp.weighted_pred(s->sh.chroma_log2_weight_denom,
+ s->sh.chroma_weight_l1[current_mv.ref_idx[1]][0],
+ s->sh.chroma_offset_l1[current_mv.ref_idx[1]][0],
+ dst1, s->frame->linesize[1], tmp, tmpstride, nPbW/2, nPbH/2);
+ s->hevcdsp.weighted_pred(s->sh.chroma_log2_weight_denom,
+ s->sh.chroma_weight_l1[current_mv.ref_idx[1]][1],
+ s->sh.chroma_offset_l1[current_mv.ref_idx[1]][1],
+ dst2, s->frame->linesize[2], tmp2, tmpstride, nPbW/2, nPbH/2);
+ } else {
+ s->hevcdsp.put_unweighted_pred(dst1, s->frame->linesize[1], tmp, tmpstride, nPbW/2, nPbH/2);
+ s->hevcdsp.put_unweighted_pred(dst2, s->frame->linesize[2], tmp2, tmpstride, nPbW/2, nPbH/2);
+ }
+ } else if (current_mv.pred_flag[0] && current_mv.pred_flag[1]) {
+ DECLARE_ALIGNED(16, int16_t, tmp [MAX_PB_SIZE * MAX_PB_SIZE]);
+ DECLARE_ALIGNED(16, int16_t, tmp2[MAX_PB_SIZE * MAX_PB_SIZE]);
+ DECLARE_ALIGNED(16, int16_t, tmp3[MAX_PB_SIZE * MAX_PB_SIZE]);
+ DECLARE_ALIGNED(16, int16_t, tmp4[MAX_PB_SIZE * MAX_PB_SIZE]);
+ HEVCFrame *ref0 = refPicList[0].ref[current_mv.ref_idx[0]];
+ HEVCFrame *ref1 = refPicList[1].ref[current_mv.ref_idx[1]];
+
+ if (!ref0 || !ref1)
+ return;
+
+ luma_mc(s, tmp, tmpstride, ref0->frame,
+ ¤t_mv.mv[0], x0, y0, nPbW, nPbH);
+ luma_mc(s, tmp2, tmpstride, ref1->frame,
+ ¤t_mv.mv[1], x0, y0, nPbW, nPbH);
+
+ if ((s->sh.slice_type == P_SLICE && s->pps->weighted_pred_flag) ||
+ (s->sh.slice_type == B_SLICE && s->pps->weighted_bipred_flag)) {
+ s->hevcdsp.weighted_pred_avg(s->sh.luma_log2_weight_denom,
+ s->sh.luma_weight_l0[current_mv.ref_idx[0]],
+ s->sh.luma_weight_l1[current_mv.ref_idx[1]],
+ s->sh.luma_offset_l0[current_mv.ref_idx[0]],
+ s->sh.luma_offset_l1[current_mv.ref_idx[1]],
+ dst0, s->frame->linesize[0],
+ tmp, tmp2, tmpstride, nPbW, nPbH);
+ } else {
+ s->hevcdsp.put_weighted_pred_avg(dst0, s->frame->linesize[0],
+ tmp, tmp2, tmpstride, nPbW, nPbH);
+ }
+
+ chroma_mc(s, tmp, tmp2, tmpstride, ref0->frame,
+ ¤t_mv.mv[0], x0 / 2, y0 / 2, nPbW / 2, nPbH / 2);
+ chroma_mc(s, tmp3, tmp4, tmpstride, ref1->frame,
+ ¤t_mv.mv[1], x0 / 2, y0 / 2, nPbW / 2, nPbH / 2);
+
+ if ((s->sh.slice_type == P_SLICE && s->pps->weighted_pred_flag) ||
+ (s->sh.slice_type == B_SLICE && s->pps->weighted_bipred_flag)) {
+ s->hevcdsp.weighted_pred_avg(s->sh.chroma_log2_weight_denom,
+ s->sh.chroma_weight_l0[current_mv.ref_idx[0]][0],
+ s->sh.chroma_weight_l1[current_mv.ref_idx[1]][0],
+ s->sh.chroma_offset_l0[current_mv.ref_idx[0]][0],
+ s->sh.chroma_offset_l1[current_mv.ref_idx[1]][0],
+ dst1, s->frame->linesize[1], tmp, tmp3,
+ tmpstride, nPbW / 2, nPbH / 2);
+ s->hevcdsp.weighted_pred_avg(s->sh.chroma_log2_weight_denom,
+ s->sh.chroma_weight_l0[current_mv.ref_idx[0]][1],
+ s->sh.chroma_weight_l1[current_mv.ref_idx[1]][1],
+ s->sh.chroma_offset_l0[current_mv.ref_idx[0]][1],
+ s->sh.chroma_offset_l1[current_mv.ref_idx[1]][1],
+ dst2, s->frame->linesize[2], tmp2, tmp4,
+ tmpstride, nPbW / 2, nPbH / 2);
+ } else {
+ s->hevcdsp.put_weighted_pred_avg(dst1, s->frame->linesize[1], tmp, tmp3, tmpstride, nPbW/2, nPbH/2);
+ s->hevcdsp.put_weighted_pred_avg(dst2, s->frame->linesize[2], tmp2, tmp4, tmpstride, nPbW/2, nPbH/2);
+ }
+ }
+}
+
+/**
+ * 8.4.1
+ */
+static int luma_intra_pred_mode(HEVCContext *s, int x0, int y0, int pu_size,
+ int prev_intra_luma_pred_flag)
+{
+ HEVCLocalContext *lc = s->HEVClc;
+ int x_pu = x0 >> s->sps->log2_min_pu_size;
+ int y_pu = y0 >> s->sps->log2_min_pu_size;
+ int min_pu_width = s->sps->min_pu_width;
+ int size_in_pus = pu_size >> s->sps->log2_min_pu_size;
+ int x0b = x0 & ((1 << s->sps->log2_ctb_size) - 1);
+ int y0b = y0 & ((1 << s->sps->log2_ctb_size) - 1);
+
+ int cand_up = (lc->ctb_up_flag || y0b) ?
+ s->tab_ipm[(y_pu - 1) * min_pu_width + x_pu] : INTRA_DC;
+ int cand_left = (lc->ctb_left_flag || x0b) ?
+ s->tab_ipm[y_pu * min_pu_width + x_pu - 1] : INTRA_DC;
+
+ int y_ctb = (y0 >> (s->sps->log2_ctb_size)) << (s->sps->log2_ctb_size);
+
+ MvField *tab_mvf = s->ref->tab_mvf;
+ int intra_pred_mode;
+ int candidate[3];
+ int i, j;
+
+ // intra_pred_mode prediction does not cross vertical CTB boundaries
+ if ((y0 - 1) < y_ctb)
+ cand_up = INTRA_DC;
+
+ if (cand_left == cand_up) {
+ if (cand_left < 2) {
+ candidate[0] = INTRA_PLANAR;
+ candidate[1] = INTRA_DC;
+ candidate[2] = INTRA_ANGULAR_26;
+ } else {
+ candidate[0] = cand_left;
+ candidate[1] = 2 + ((cand_left - 2 - 1 + 32) & 31);
+ candidate[2] = 2 + ((cand_left - 2 + 1) & 31);
+ }
+ } else {
+ candidate[0] = cand_left;
+ candidate[1] = cand_up;
+ if (candidate[0] != INTRA_PLANAR && candidate[1] != INTRA_PLANAR) {
+ candidate[2] = INTRA_PLANAR;
+ } else if (candidate[0] != INTRA_DC && candidate[1] != INTRA_DC) {
+ candidate[2] = INTRA_DC;
+ } else {
+ candidate[2] = INTRA_ANGULAR_26;
+ }
+ }
+
+ if (prev_intra_luma_pred_flag) {
+ intra_pred_mode = candidate[lc->pu.mpm_idx];
+ } else {
+ if (candidate[0] > candidate[1])
+ FFSWAP(uint8_t, candidate[0], candidate[1]);
+ if (candidate[0] > candidate[2])
+ FFSWAP(uint8_t, candidate[0], candidate[2]);
+ if (candidate[1] > candidate[2])
+ FFSWAP(uint8_t, candidate[1], candidate[2]);
+
+ intra_pred_mode = lc->pu.rem_intra_luma_pred_mode;
+ for (i = 0; i < 3; i++)
+ if (intra_pred_mode >= candidate[i])
+ intra_pred_mode++;
+ }
+
+ /* write the intra prediction units into the mv array */
+ if (!size_in_pus)
+ size_in_pus = 1;
+ for (i = 0; i < size_in_pus; i++) {
+ memset(&s->tab_ipm[(y_pu + i) * min_pu_width + x_pu],
+ intra_pred_mode, size_in_pus);
+
+ for (j = 0; j < size_in_pus; j++) {
+ tab_mvf[(y_pu + j) * min_pu_width + x_pu + i].is_intra = 1;
+ tab_mvf[(y_pu + j) * min_pu_width + x_pu + i].pred_flag[0] = 0;
+ tab_mvf[(y_pu + j) * min_pu_width + x_pu + i].pred_flag[1] = 0;
+ tab_mvf[(y_pu + j) * min_pu_width + x_pu + i].ref_idx[0] = 0;
+ tab_mvf[(y_pu + j) * min_pu_width + x_pu + i].ref_idx[1] = 0;
+ tab_mvf[(y_pu + j) * min_pu_width + x_pu + i].mv[0].x = 0;
+ tab_mvf[(y_pu + j) * min_pu_width + x_pu + i].mv[0].y = 0;
+ tab_mvf[(y_pu + j) * min_pu_width + x_pu + i].mv[1].x = 0;
+ tab_mvf[(y_pu + j) * min_pu_width + x_pu + i].mv[1].y = 0;
+ }
+ }
+
+ return intra_pred_mode;
+}
+
+static av_always_inline void set_ct_depth(HEVCContext *s, int x0, int y0,
+ int log2_cb_size, int ct_depth)
+{
+ int length = (1 << log2_cb_size) >> s->sps->log2_min_cb_size;
+ int x_cb = x0 >> s->sps->log2_min_cb_size;
+ int y_cb = y0 >> s->sps->log2_min_cb_size;
+ int y;
+
+ for (y = 0; y < length; y++)
+ memset(&s->tab_ct_depth[(y_cb + y) * s->sps->min_cb_width + x_cb],
+ ct_depth, length);
+}
+
+static void intra_prediction_unit(HEVCContext *s, int x0, int y0,
+ int log2_cb_size)
+{
+ HEVCLocalContext *lc = s->HEVClc;
+ static const uint8_t intra_chroma_table[4] = { 0, 26, 10, 1 };
+ uint8_t prev_intra_luma_pred_flag[4];
+ int split = lc->cu.part_mode == PART_NxN;
+ int pb_size = (1 << log2_cb_size) >> split;
+ int side = split + 1;
+ int chroma_mode;
+ int i, j;
+
+ for (i = 0; i < side; i++)
+ for (j = 0; j < side; j++)
+ prev_intra_luma_pred_flag[2 * i + j] = ff_hevc_prev_intra_luma_pred_flag_decode(s);
+
+ for (i = 0; i < side; i++) {
+ for (j = 0; j < side; j++) {
+ if (prev_intra_luma_pred_flag[2 * i + j])
+ lc->pu.mpm_idx = ff_hevc_mpm_idx_decode(s);
+ else
+ lc->pu.rem_intra_luma_pred_mode = ff_hevc_rem_intra_luma_pred_mode_decode(s);
+
+ lc->pu.intra_pred_mode[2 * i + j] =
+ luma_intra_pred_mode(s, x0 + pb_size * j, y0 + pb_size * i, pb_size,
+ prev_intra_luma_pred_flag[2 * i + j]);
+ }
+ }
+
+ chroma_mode = ff_hevc_intra_chroma_pred_mode_decode(s);
+ if (chroma_mode != 4) {
+ if (lc->pu.intra_pred_mode[0] == intra_chroma_table[chroma_mode])
+ lc->pu.intra_pred_mode_c = 34;
+ else
+ lc->pu.intra_pred_mode_c = intra_chroma_table[chroma_mode];
+ } else {
+ lc->pu.intra_pred_mode_c = lc->pu.intra_pred_mode[0];
+ }
+}
+
+static void intra_prediction_unit_default_value(HEVCContext *s,
+ int x0, int y0,
+ int log2_cb_size)
+{
+ HEVCLocalContext *lc = s->HEVClc;
+ int pb_size = 1 << log2_cb_size;
+ int size_in_pus = pb_size >> s->sps->log2_min_pu_size;
+ int min_pu_width = s->sps->min_pu_width;
+ MvField *tab_mvf = s->ref->tab_mvf;
+ int x_pu = x0 >> s->sps->log2_min_pu_size;
+ int y_pu = y0 >> s->sps->log2_min_pu_size;
+ int j, k;
+
+ if (size_in_pus == 0)
+ size_in_pus = 1;
+ for (j = 0; j < size_in_pus; j++) {
+ memset(&s->tab_ipm[(y_pu + j) * min_pu_width + x_pu], INTRA_DC, size_in_pus);
+ for (k = 0; k < size_in_pus; k++)
+ tab_mvf[(y_pu + j) * min_pu_width + x_pu + k].is_intra = lc->cu.pred_mode == MODE_INTRA;
+ }
+}
+
+static int hls_coding_unit(HEVCContext *s, int x0, int y0, int log2_cb_size)
+{
+ int cb_size = 1 << log2_cb_size;
+ HEVCLocalContext *lc = s->HEVClc;
+ int log2_min_cb_size = s->sps->log2_min_cb_size;
+ int length = cb_size >> log2_min_cb_size;
+ int min_cb_width = s->sps->min_cb_width;
+ int x_cb = x0 >> log2_min_cb_size;
+ int y_cb = y0 >> log2_min_cb_size;
+ int x, y;
+
+ lc->cu.x = x0;
+ lc->cu.y = y0;
+ lc->cu.rqt_root_cbf = 1;
+ lc->cu.pred_mode = MODE_INTRA;
+ lc->cu.part_mode = PART_2Nx2N;
+ lc->cu.intra_split_flag = 0;
+ lc->cu.pcm_flag = 0;
+
+ SAMPLE_CTB(s->skip_flag, x_cb, y_cb) = 0;
+ for (x = 0; x < 4; x++)
+ lc->pu.intra_pred_mode[x] = 1;
+ if (s->pps->transquant_bypass_enable_flag) {
+ lc->cu.cu_transquant_bypass_flag = ff_hevc_cu_transquant_bypass_flag_decode(s);
+ if (lc->cu.cu_transquant_bypass_flag)
+ set_deblocking_bypass(s, x0, y0, log2_cb_size);
+ } else
+ lc->cu.cu_transquant_bypass_flag = 0;
+
+ if (s->sh.slice_type != I_SLICE) {
+ uint8_t skip_flag = ff_hevc_skip_flag_decode(s, x0, y0, x_cb, y_cb);
+
+ lc->cu.pred_mode = MODE_SKIP;
+ x = y_cb * min_cb_width + x_cb;
+ for (y = 0; y < length; y++) {
+ memset(&s->skip_flag[x], skip_flag, length);
+ x += min_cb_width;
+ }
+ lc->cu.pred_mode = skip_flag ? MODE_SKIP : MODE_INTER;
+ }
+
+ if (SAMPLE_CTB(s->skip_flag, x_cb, y_cb)) {
+ hls_prediction_unit(s, x0, y0, cb_size, cb_size, log2_cb_size, 0);
+ intra_prediction_unit_default_value(s, x0, y0, log2_cb_size);
+
+ if (!s->sh.disable_deblocking_filter_flag)
+ ff_hevc_deblocking_boundary_strengths(s, x0, y0, log2_cb_size,
+ lc->slice_or_tiles_up_boundary,
+ lc->slice_or_tiles_left_boundary);
+ } else {
+ if (s->sh.slice_type != I_SLICE)
+ lc->cu.pred_mode = ff_hevc_pred_mode_decode(s);
+ if (lc->cu.pred_mode != MODE_INTRA ||
+ log2_cb_size == s->sps->log2_min_cb_size) {
+ lc->cu.part_mode = ff_hevc_part_mode_decode(s, log2_cb_size);
+ lc->cu.intra_split_flag = lc->cu.part_mode == PART_NxN &&
+ lc->cu.pred_mode == MODE_INTRA;
+ }
+
+ if (lc->cu.pred_mode == MODE_INTRA) {
+ if (lc->cu.part_mode == PART_2Nx2N && s->sps->pcm_enabled_flag &&
+ log2_cb_size >= s->sps->pcm.log2_min_pcm_cb_size &&
+ log2_cb_size <= s->sps->pcm.log2_max_pcm_cb_size) {
+ lc->cu.pcm_flag = ff_hevc_pcm_flag_decode(s);
+ }
+ if (lc->cu.pcm_flag) {
+ int ret;
+ intra_prediction_unit_default_value(s, x0, y0, log2_cb_size);
+ ret = hls_pcm_sample(s, x0, y0, log2_cb_size);
+ if (s->sps->pcm.loop_filter_disable_flag)
+ set_deblocking_bypass(s, x0, y0, log2_cb_size);
+
+ if (ret < 0)
+ return ret;
+ } else {
+ intra_prediction_unit(s, x0, y0, log2_cb_size);
+ }
+ } else {
+ intra_prediction_unit_default_value(s, x0, y0, log2_cb_size);
+ switch (lc->cu.part_mode) {
+ case PART_2Nx2N:
+ hls_prediction_unit(s, x0, y0, cb_size, cb_size, log2_cb_size, 0);
+ break;
+ case PART_2NxN:
+ hls_prediction_unit(s, x0, y0, cb_size, cb_size / 2, log2_cb_size, 0);
+ hls_prediction_unit(s, x0, y0 + cb_size / 2, cb_size, cb_size / 2, log2_cb_size, 1);
+ break;
+ case PART_Nx2N:
+ hls_prediction_unit(s, x0, y0, cb_size / 2, cb_size, log2_cb_size, 0);
+ hls_prediction_unit(s, x0 + cb_size / 2, y0, cb_size / 2, cb_size, log2_cb_size, 1);
+ break;
+ case PART_2NxnU:
+ hls_prediction_unit(s, x0, y0, cb_size, cb_size / 4, log2_cb_size, 0);
+ hls_prediction_unit(s, x0, y0 + cb_size / 4, cb_size, cb_size * 3 / 4, log2_cb_size, 1);
+ break;
+ case PART_2NxnD:
+ hls_prediction_unit(s, x0, y0, cb_size, cb_size * 3 / 4, log2_cb_size, 0);
+ hls_prediction_unit(s, x0, y0 + cb_size * 3 / 4, cb_size, cb_size / 4, log2_cb_size, 1);
+ break;
+ case PART_nLx2N:
+ hls_prediction_unit(s, x0, y0, cb_size / 4, cb_size, log2_cb_size, 0);
+ hls_prediction_unit(s, x0 + cb_size / 4, y0, cb_size * 3 / 4, cb_size, log2_cb_size, 1);
+ break;
+ case PART_nRx2N:
+ hls_prediction_unit(s, x0, y0, cb_size * 3 / 4, cb_size, log2_cb_size, 0);
+ hls_prediction_unit(s, x0 + cb_size * 3 / 4, y0, cb_size / 4, cb_size, log2_cb_size, 1);
+ break;
+ case PART_NxN:
+ hls_prediction_unit(s, x0, y0, cb_size / 2, cb_size / 2, log2_cb_size, 0);
+ hls_prediction_unit(s, x0 + cb_size / 2, y0, cb_size / 2, cb_size / 2, log2_cb_size, 1);
+ hls_prediction_unit(s, x0, y0 + cb_size / 2, cb_size / 2, cb_size / 2, log2_cb_size, 2);
+ hls_prediction_unit(s, x0 + cb_size / 2, y0 + cb_size / 2, cb_size / 2, cb_size / 2, log2_cb_size, 3);
+ break;
+ }
+ }
+
+ if (!lc->cu.pcm_flag) {
+ if (lc->cu.pred_mode != MODE_INTRA &&
+ !(lc->cu.part_mode == PART_2Nx2N && lc->pu.merge_flag)) {
+ lc->cu.rqt_root_cbf = ff_hevc_no_residual_syntax_flag_decode(s);
+ }
+ if (lc->cu.rqt_root_cbf) {
+ lc->cu.max_trafo_depth = lc->cu.pred_mode == MODE_INTRA ?
+ s->sps->max_transform_hierarchy_depth_intra + lc->cu.intra_split_flag :
+ s->sps->max_transform_hierarchy_depth_inter;
+ hls_transform_tree(s, x0, y0, x0, y0, x0, y0, log2_cb_size,
+ log2_cb_size, 0, 0);
+ } else {
+ if (!s->sh.disable_deblocking_filter_flag)
+ ff_hevc_deblocking_boundary_strengths(s, x0, y0, log2_cb_size,
+ lc->slice_or_tiles_up_boundary,
+ lc->slice_or_tiles_left_boundary);
+ }
+ }
+ }
+
+ if (s->pps->cu_qp_delta_enabled_flag && lc->tu.is_cu_qp_delta_coded == 0)
+ ff_hevc_set_qPy(s, x0, y0, x0, y0, log2_cb_size);
+
+ x = y_cb * min_cb_width + x_cb;
+ for (y = 0; y < length; y++) {
+ memset(&s->qp_y_tab[x], lc->qp_y, length);
+ x += min_cb_width;
+ }
+
+ set_ct_depth(s, x0, y0, log2_cb_size, lc->ct.depth);
+
+ return 0;
+}
+
+static int hls_coding_quadtree(HEVCContext *s, int x0, int y0,
+ int log2_cb_size, int cb_depth)
+{
+ HEVCLocalContext *lc = s->HEVClc;
+ const int cb_size = 1 << log2_cb_size;
+ int ret;
+
+ lc->ct.depth = cb_depth;
+ if (x0 + cb_size <= s->sps->width &&
+ y0 + cb_size <= s->sps->height &&
+ log2_cb_size > s->sps->log2_min_cb_size) {
+ SAMPLE(s->split_cu_flag, x0, y0) =
+ ff_hevc_split_coding_unit_flag_decode(s, cb_depth, x0, y0);
+ } else {
+ SAMPLE(s->split_cu_flag, x0, y0) =
+ (log2_cb_size > s->sps->log2_min_cb_size);
+ }
+ if (s->pps->cu_qp_delta_enabled_flag &&
+ log2_cb_size >= s->sps->log2_ctb_size - s->pps->diff_cu_qp_delta_depth) {
+ lc->tu.is_cu_qp_delta_coded = 0;
+ lc->tu.cu_qp_delta = 0;
+ }
+
+ if (SAMPLE(s->split_cu_flag, x0, y0)) {
+ const int cb_size_split = cb_size >> 1;
+ const int x1 = x0 + cb_size_split;
+ const int y1 = y0 + cb_size_split;
+
+ int more_data = 0;
+
+ more_data = hls_coding_quadtree(s, x0, y0, log2_cb_size - 1, cb_depth + 1);
+ if (more_data < 0)
+ return more_data;
+
+ if (more_data && x1 < s->sps->width)
+ more_data = hls_coding_quadtree(s, x1, y0, log2_cb_size - 1, cb_depth + 1);
+ if (more_data && y1 < s->sps->height)
+ more_data = hls_coding_quadtree(s, x0, y1, log2_cb_size - 1, cb_depth + 1);
+ if (more_data && x1 < s->sps->width &&
+ y1 < s->sps->height) {
+ return hls_coding_quadtree(s, x1, y1, log2_cb_size - 1, cb_depth + 1);
+ }
+ if (more_data)
+ return ((x1 + cb_size_split) < s->sps->width ||
+ (y1 + cb_size_split) < s->sps->height);
+ else
+ return 0;
+ } else {
+ ret = hls_coding_unit(s, x0, y0, log2_cb_size);
+ if (ret < 0)
+ return ret;
+ if ((!((x0 + cb_size) %
+ (1 << (s->sps->log2_ctb_size))) ||
+ (x0 + cb_size >= s->sps->width)) &&
+ (!((y0 + cb_size) %
+ (1 << (s->sps->log2_ctb_size))) ||
+ (y0 + cb_size >= s->sps->height))) {
+ int end_of_slice_flag = ff_hevc_end_of_slice_flag_decode(s);
+ return !end_of_slice_flag;
+ } else {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+static void hls_decode_neighbour(HEVCContext *s, int x_ctb, int y_ctb,
+ int ctb_addr_ts)
+{
+ HEVCLocalContext *lc = s->HEVClc;
+ int ctb_size = 1 << s->sps->log2_ctb_size;
+ int ctb_addr_rs = s->pps->ctb_addr_ts_to_rs[ctb_addr_ts];
+ int ctb_addr_in_slice = ctb_addr_rs - s->sh.slice_addr;
+
+ int tile_left_boundary, tile_up_boundary;
+ int slice_left_boundary, slice_up_boundary;
+
+ s->tab_slice_address[ctb_addr_rs] = s->sh.slice_addr;
+
+ if (s->pps->entropy_coding_sync_enabled_flag) {
+ if (x_ctb == 0 && (y_ctb & (ctb_size - 1)) == 0)
+ lc->first_qp_group = 1;
+ lc->end_of_tiles_x = s->sps->width;
+ } else if (s->pps->tiles_enabled_flag) {
+ if (ctb_addr_ts && s->pps->tile_id[ctb_addr_ts] != s->pps->tile_id[ctb_addr_ts - 1]) {
+ int idxX = s->pps->col_idxX[x_ctb >> s->sps->log2_ctb_size];
+ lc->start_of_tiles_x = x_ctb;
+ lc->end_of_tiles_x = x_ctb + (s->pps->column_width[idxX] << s->sps->log2_ctb_size);
+ lc->first_qp_group = 1;
+ }
+ } else {
+ lc->end_of_tiles_x = s->sps->width;
+ }
+
+ lc->end_of_tiles_y = FFMIN(y_ctb + ctb_size, s->sps->height);
+
+ if (s->pps->tiles_enabled_flag) {
+ tile_left_boundary = x_ctb > 0 &&
+ s->pps->tile_id[ctb_addr_ts] != s->pps->tile_id[s->pps->ctb_addr_rs_to_ts[ctb_addr_rs-1]];
+ slice_left_boundary = x_ctb > 0 &&
+ s->tab_slice_address[ctb_addr_rs] != s->tab_slice_address[ctb_addr_rs - 1];
+ tile_up_boundary = y_ctb > 0 &&
+ s->pps->tile_id[ctb_addr_ts] != s->pps->tile_id[s->pps->ctb_addr_rs_to_ts[ctb_addr_rs - s->sps->ctb_width]];
+ slice_up_boundary = y_ctb > 0 &&
+ s->tab_slice_address[ctb_addr_rs] != s->tab_slice_address[ctb_addr_rs - s->sps->ctb_width];
+ } else {
+ tile_left_boundary =
+ tile_up_boundary = 0;
+ slice_left_boundary = ctb_addr_in_slice <= 0;
+ slice_up_boundary = ctb_addr_in_slice < s->sps->ctb_width;
+ }
+ lc->slice_or_tiles_left_boundary = slice_left_boundary + (tile_left_boundary << 1);
+ lc->slice_or_tiles_up_boundary = slice_up_boundary + (tile_up_boundary << 1);
+ lc->ctb_left_flag = ((x_ctb > 0) && (ctb_addr_in_slice > 0) && !tile_left_boundary);
+ lc->ctb_up_flag = ((y_ctb > 0) && (ctb_addr_in_slice >= s->sps->ctb_width) && !tile_up_boundary);
+ lc->ctb_up_right_flag = ((y_ctb > 0) && (ctb_addr_in_slice+1 >= s->sps->ctb_width) && (s->pps->tile_id[ctb_addr_ts] == s->pps->tile_id[s->pps->ctb_addr_rs_to_ts[ctb_addr_rs+1 - s->sps->ctb_width]]));
+ lc->ctb_up_left_flag = ((x_ctb > 0) && (y_ctb > 0) && (ctb_addr_in_slice-1 >= s->sps->ctb_width) && (s->pps->tile_id[ctb_addr_ts] == s->pps->tile_id[s->pps->ctb_addr_rs_to_ts[ctb_addr_rs-1 - s->sps->ctb_width]]));
+}
+
+static int hls_decode_entry(AVCodecContext *avctxt, void *isFilterThread)
+{
+ HEVCContext *s = avctxt->priv_data;
+ int ctb_size = 1 << s->sps->log2_ctb_size;
+ int more_data = 1;
+ int x_ctb = 0;
+ int y_ctb = 0;
+ int ctb_addr_ts = s->pps->ctb_addr_rs_to_ts[s->sh.slice_ctb_addr_rs];
+
+ while (more_data && ctb_addr_ts < s->sps->ctb_size) {
+ int ctb_addr_rs = s->pps->ctb_addr_ts_to_rs[ctb_addr_ts];
+
+ x_ctb = (ctb_addr_rs % ((s->sps->width + ctb_size - 1) >> s->sps->log2_ctb_size)) << s->sps->log2_ctb_size;
+ y_ctb = (ctb_addr_rs / ((s->sps->width + ctb_size - 1) >> s->sps->log2_ctb_size)) << s->sps->log2_ctb_size;
+ hls_decode_neighbour(s, x_ctb, y_ctb, ctb_addr_ts);
+
+ ff_hevc_cabac_init(s, ctb_addr_ts);
+
+ hls_sao_param(s, x_ctb >> s->sps->log2_ctb_size, y_ctb >> s->sps->log2_ctb_size);
+
+ s->deblock[ctb_addr_rs].beta_offset = s->sh.beta_offset;
+ s->deblock[ctb_addr_rs].tc_offset = s->sh.tc_offset;
+ s->filter_slice_edges[ctb_addr_rs] = s->sh.slice_loop_filter_across_slices_enabled_flag;
+
+ more_data = hls_coding_quadtree(s, x_ctb, y_ctb, s->sps->log2_ctb_size, 0);
+ if (more_data < 0)
+ return more_data;
+
+ ctb_addr_ts++;
+ ff_hevc_save_states(s, ctb_addr_ts);
+ ff_hevc_hls_filters(s, x_ctb, y_ctb, ctb_size);
+ }
+
+ if (x_ctb + ctb_size >= s->sps->width &&
+ y_ctb + ctb_size >= s->sps->height)
+ ff_hevc_hls_filter(s, x_ctb, y_ctb);
+
+ return ctb_addr_ts;
+}
+
+static int hls_slice_data(HEVCContext *s)
+{
+ int arg[2];
+ int ret[2];
+
+ arg[0] = 0;
+ arg[1] = 1;
+
+ s->avctx->execute(s->avctx, hls_decode_entry, arg, ret , 1, sizeof(int));
+ return ret[0];
+}
+static int hls_decode_entry_wpp(AVCodecContext *avctxt, void *input_ctb_row, int job, int self_id)
+{
+ HEVCContext *s1 = avctxt->priv_data, *s;
+ HEVCLocalContext *lc;
+ int ctb_size = 1<< s1->sps->log2_ctb_size;
+ int more_data = 1;
+ int *ctb_row_p = input_ctb_row;
+ int ctb_row = ctb_row_p[job];
+ int ctb_addr_rs = s1->sh.slice_ctb_addr_rs + ctb_row * ((s1->sps->width + ctb_size - 1) >> s1->sps->log2_ctb_size);
+ int ctb_addr_ts = s1->pps->ctb_addr_rs_to_ts[ctb_addr_rs];
+ int thread = ctb_row % s1->threads_number;
+ int ret;
+
+ s = s1->sList[self_id];
+ lc = s->HEVClc;
+
+ if(ctb_row) {
+ ret = init_get_bits8(&lc->gb, s->data + s->sh.offset[ctb_row - 1], s->sh.size[ctb_row - 1]);
+
+ if (ret < 0)
+ return ret;
+ ff_init_cabac_decoder(&lc->cc, s->data + s->sh.offset[(ctb_row)-1], s->sh.size[ctb_row - 1]);
+ }
+
+ while(more_data && ctb_addr_ts < s->sps->ctb_size) {
+ int x_ctb = (ctb_addr_rs % s->sps->ctb_width) << s->sps->log2_ctb_size;
+ int y_ctb = (ctb_addr_rs / s->sps->ctb_width) << s->sps->log2_ctb_size;
+
+ hls_decode_neighbour(s, x_ctb, y_ctb, ctb_addr_ts);
+
+ ff_thread_await_progress2(s->avctx, ctb_row, thread, SHIFT_CTB_WPP);
+
+ if (avpriv_atomic_int_get(&s1->wpp_err)){
+ ff_thread_report_progress2(s->avctx, ctb_row , thread, SHIFT_CTB_WPP);
+ return 0;
+ }
+
+ ff_hevc_cabac_init(s, ctb_addr_ts);
+ hls_sao_param(s, x_ctb >> s->sps->log2_ctb_size, y_ctb >> s->sps->log2_ctb_size);
+ more_data = hls_coding_quadtree(s, x_ctb, y_ctb, s->sps->log2_ctb_size, 0);
+
+ if (more_data < 0)
+ return more_data;
+
+ ctb_addr_ts++;
+
+ ff_hevc_save_states(s, ctb_addr_ts);
+ ff_thread_report_progress2(s->avctx, ctb_row, thread, 1);
+ ff_hevc_hls_filters(s, x_ctb, y_ctb, ctb_size);
+
+ if (!more_data && (x_ctb+ctb_size) < s->sps->width && ctb_row != s->sh.num_entry_point_offsets) {
+ avpriv_atomic_int_set(&s1->wpp_err, 1);
+ ff_thread_report_progress2(s->avctx, ctb_row ,thread, SHIFT_CTB_WPP);
+ return 0;
+ }
+
+ if ((x_ctb+ctb_size) >= s->sps->width && (y_ctb+ctb_size) >= s->sps->height ) {
+ ff_hevc_hls_filter(s, x_ctb, y_ctb);
+ ff_thread_report_progress2(s->avctx, ctb_row , thread, SHIFT_CTB_WPP);
+ return ctb_addr_ts;
+ }
+ ctb_addr_rs = s->pps->ctb_addr_ts_to_rs[ctb_addr_ts];
+ x_ctb+=ctb_size;
+
+ if(x_ctb >= s->sps->width) {
+ break;
+ }
+ }
+ ff_thread_report_progress2(s->avctx, ctb_row ,thread, SHIFT_CTB_WPP);
+
+ return 0;
+}
+
+static int hls_slice_data_wpp(HEVCContext *s, const uint8_t *nal, int length)
+{
+ HEVCLocalContext *lc = s->HEVClc;
+ int *ret = av_malloc((s->sh.num_entry_point_offsets + 1) * sizeof(int));
+ int *arg = av_malloc((s->sh.num_entry_point_offsets + 1) * sizeof(int));
+ int offset;
+ int startheader, cmpt = 0;
+ int i, j, res = 0;
+
+
+ if (!s->sList[1]) {
+ ff_alloc_entries(s->avctx, s->sh.num_entry_point_offsets + 1);
+
+
+ for (i = 1; i < s->threads_number; i++) {
+ s->sList[i] = av_malloc(sizeof(HEVCContext));
+ memcpy(s->sList[i], s, sizeof(HEVCContext));
+ s->HEVClcList[i] = av_malloc(sizeof(HEVCLocalContext));
+ s->HEVClcList[i]->edge_emu_buffer = av_malloc((MAX_PB_SIZE + 7) * s->frame->linesize[0]);
+ s->sList[i]->HEVClc = s->HEVClcList[i];
+ }
+ }
+
+ offset = (lc->gb.index >> 3);
+
+ for (j = 0, cmpt = 0, startheader = offset + s->sh.entry_point_offset[0]; j < s->skipped_bytes; j++) {
+ if (s->skipped_bytes_pos[j] >= offset && s->skipped_bytes_pos[j] < startheader) {
+ startheader--;
+ cmpt++;
+ }
+ }
+
+ for (i = 1; i < s->sh.num_entry_point_offsets; i++) {
+ offset += (s->sh.entry_point_offset[i - 1] - cmpt);
+ for (j = 0, cmpt = 0, startheader = offset
+ + s->sh.entry_point_offset[i]; j < s->skipped_bytes; j++) {
+ if (s->skipped_bytes_pos[j] >= offset && s->skipped_bytes_pos[j] < startheader) {
+ startheader--;
+ cmpt++;
+ }
+ }
+ s->sh.size[i - 1] = s->sh.entry_point_offset[i] - cmpt;
+ s->sh.offset[i - 1] = offset;
+
+ }
+ if (s->sh.num_entry_point_offsets != 0) {
+ offset += s->sh.entry_point_offset[s->sh.num_entry_point_offsets - 1] - cmpt;
+ s->sh.size[s->sh.num_entry_point_offsets - 1] = length - offset;
+ s->sh.offset[s->sh.num_entry_point_offsets - 1] = offset;
+
+ }
+ s->data = nal;
+
+ for (i = 1; i < s->threads_number; i++) {
+ s->sList[i]->HEVClc->first_qp_group = 1;
+ s->sList[i]->HEVClc->qp_y = s->sList[0]->HEVClc->qp_y;
+ memcpy(s->sList[i], s, sizeof(HEVCContext));
+ s->sList[i]->HEVClc = s->HEVClcList[i];
+ }
+
+ avpriv_atomic_int_set(&s->wpp_err, 0);
+ ff_reset_entries(s->avctx);
+
+ for (i = 0; i <= s->sh.num_entry_point_offsets; i++) {
+ arg[i] = i;
+ ret[i] = 0;
+ }
+
+ if (s->pps->entropy_coding_sync_enabled_flag)
+ s->avctx->execute2(s->avctx, (void *) hls_decode_entry_wpp, arg, ret, s->sh.num_entry_point_offsets + 1);
+
+ for (i = 0; i <= s->sh.num_entry_point_offsets; i++)
+ res += ret[i];
+ av_free(ret);
+ av_free(arg);
+ return res;
+}
+
+/**
+ * @return AVERROR_INVALIDDATA if the packet is not a valid NAL unit,
+ * 0 if the unit should be skipped, 1 otherwise
+ */
+static int hls_nal_unit(HEVCContext *s)
+{
+ GetBitContext *gb = &s->HEVClc->gb;
+ int nuh_layer_id;
+
+ if (get_bits1(gb) != 0)
+ return AVERROR_INVALIDDATA;
+
+ s->nal_unit_type = get_bits(gb, 6);
+
+ nuh_layer_id = get_bits(gb, 6);
+ s->temporal_id = get_bits(gb, 3) - 1;
+ if (s->temporal_id < 0)
+ return AVERROR_INVALIDDATA;
+
+ av_log(s->avctx, AV_LOG_DEBUG,
+ "nal_unit_type: %d, nuh_layer_id: %dtemporal_id: %d\n",
+ s->nal_unit_type, nuh_layer_id, s->temporal_id);
+
+ return nuh_layer_id == 0;
+}
+
+static void restore_tqb_pixels(HEVCContext *s)
+{
+ int min_pu_size = 1 << s->sps->log2_min_pu_size;
+ int x, y, c_idx;
+
+ for (c_idx = 0; c_idx < 3; c_idx++) {
+ ptrdiff_t stride = s->frame->linesize[c_idx];
+ int hshift = s->sps->hshift[c_idx];
+ int vshift = s->sps->vshift[c_idx];
+ for (y = 0; y < s->sps->min_pu_height; y++) {
+ for (x = 0; x < s->sps->min_pu_width; x++) {
+ if (s->is_pcm[y * s->sps->min_pu_width + x]) {
+ int n;
+ int len = min_pu_size >> hshift;
+ uint8_t *src = &s->frame->data[c_idx][((y << s->sps->log2_min_pu_size) >> vshift) * stride + (((x << s->sps->log2_min_pu_size) >> hshift) << s->sps->pixel_shift)];
+ uint8_t *dst = &s->sao_frame->data[c_idx][((y << s->sps->log2_min_pu_size) >> vshift) * stride + (((x << s->sps->log2_min_pu_size) >> hshift) << s->sps->pixel_shift)];
+ for (n = 0; n < (min_pu_size >> vshift); n++) {
+ memcpy(dst, src, len);
+ src += stride;
+ dst += stride;
+ }
+ }
+ }
+ }
+ }
+}
+
+static int hevc_frame_start(HEVCContext *s)
+{
+ HEVCLocalContext *lc = s->HEVClc;
+ int ret;
+
+ memset(s->horizontal_bs, 0, 2 * s->bs_width * (s->bs_height + 1));
+ memset(s->vertical_bs, 0, 2 * s->bs_width * (s->bs_height + 1));
+ memset(s->cbf_luma, 0, s->sps->min_tb_width * s->sps->min_tb_height);
+ memset(s->is_pcm, 0, s->sps->min_pu_width * s->sps->min_pu_height);
+
+ lc->start_of_tiles_x = 0;
+ s->is_decoded = 0;
+
+ if (s->pps->tiles_enabled_flag)
+ lc->end_of_tiles_x = s->pps->column_width[0] << s->sps->log2_ctb_size;
+
+ ret = ff_hevc_set_new_ref(s, s->sps->sao_enabled ? &s->sao_frame : &s->frame,
+ s->poc);
+ if (ret < 0)
+ goto fail;
+
+ av_fast_malloc(&lc->edge_emu_buffer, &lc->edge_emu_buffer_size,
+ (MAX_PB_SIZE + 7) * s->ref->frame->linesize[0]);
+ if (!lc->edge_emu_buffer) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+
+ ret = ff_hevc_frame_rps(s);
+ if (ret < 0) {
+ av_log(s->avctx, AV_LOG_ERROR, "Error constructing the frame RPS.\n");
+ goto fail;
+ }
+
+ av_frame_unref(s->output_frame);
+ ret = ff_hevc_output_frame(s, s->output_frame, 0);
+ if (ret < 0)
+ goto fail;
+
+ ff_thread_finish_setup(s->avctx);
+
+ return 0;
+
+fail:
+ if (s->ref && s->threads_type == FF_THREAD_FRAME)
+ ff_thread_report_progress(&s->ref->tf, INT_MAX, 0);
+ s->ref = NULL;
+ return ret;
+}
+
+static int decode_nal_unit(HEVCContext *s, const uint8_t *nal, int length)
+{
+ HEVCLocalContext *lc = s->HEVClc;
+ GetBitContext *gb = &lc->gb;
+ int ctb_addr_ts, ret;
+
+ ret = init_get_bits8(gb, nal, length);
+ if (ret < 0)
+ return ret;
+
+ ret = hls_nal_unit(s);
+ if (ret < 0) {
+ av_log(s->avctx, AV_LOG_ERROR, "Invalid NAL unit %d, skipping.\n",
+ s->nal_unit_type);
+ if (s->avctx->err_recognition & AV_EF_EXPLODE)
+ return ret;
+ return 0;
+ } else if (!ret)
+ return 0;
+
+ switch (s->nal_unit_type) {
+ case NAL_VPS:
+ ret = ff_hevc_decode_nal_vps(s);
+ if (ret < 0)
+ return ret;
+ break;
+ case NAL_SPS:
+ ret = ff_hevc_decode_nal_sps(s);
+ if (ret < 0)
+ return ret;
+ break;
+ case NAL_PPS:
+ ret = ff_hevc_decode_nal_pps(s);
+ if (ret < 0)
+ return ret;
+ break;
+ case NAL_SEI_PREFIX:
+ case NAL_SEI_SUFFIX:
+ ret = ff_hevc_decode_nal_sei(s);
+ if (ret < 0)
+ return ret;
+ break;
+ case NAL_TRAIL_R:
+ case NAL_TRAIL_N:
+ case NAL_TSA_N:
+ case NAL_TSA_R:
+ case NAL_STSA_N:
+ case NAL_STSA_R:
+ case NAL_BLA_W_LP:
+ case NAL_BLA_W_RADL:
+ case NAL_BLA_N_LP:
+ case NAL_IDR_W_RADL:
+ case NAL_IDR_N_LP:
+ case NAL_CRA_NUT:
+ case NAL_RADL_N:
+ case NAL_RADL_R:
+ case NAL_RASL_N:
+ case NAL_RASL_R:
+ ret = hls_slice_header(s);
+ if (ret < 0)
+ return ret;
+
+ if (s->max_ra == INT_MAX) {
+ if (s->nal_unit_type == NAL_CRA_NUT || IS_BLA(s)) {
+ s->max_ra = s->poc;
+ } else {
+ if (IS_IDR(s))
+ s->max_ra = INT_MIN;
+ }
+ }
+
+ if ((s->nal_unit_type == NAL_RASL_R || s->nal_unit_type == NAL_RASL_N) &&
+ s->poc <= s->max_ra) {
+ s->is_decoded = 0;
+ break;
+ } else {
+ if (s->nal_unit_type == NAL_RASL_R && s->poc > s->max_ra)
+ s->max_ra = INT_MIN;
+ }
+
+ if (s->sh.first_slice_in_pic_flag) {
+ ret = hevc_frame_start(s);
+ if (ret < 0)
+ return ret;
+ } else if (!s->ref) {
+ av_log(s->avctx, AV_LOG_ERROR, "First slice in a frame missing.\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (!s->sh.dependent_slice_segment_flag &&
+ s->sh.slice_type != I_SLICE) {
+ ret = ff_hevc_slice_rpl(s);
+ if (ret < 0) {
+ av_log(s->avctx, AV_LOG_WARNING,
+ "Error constructing the reference lists for the current slice.\n");
+ if (s->avctx->err_recognition & AV_EF_EXPLODE)
+ return ret;
+ }
+ }
+
+ if (s->threads_number > 1 && s->sh.num_entry_point_offsets > 0)
+ ctb_addr_ts = hls_slice_data_wpp(s, nal, length);
+ else
+ ctb_addr_ts = hls_slice_data(s);
+ if (ctb_addr_ts >= (s->sps->ctb_width * s->sps->ctb_height)) {
+ s->is_decoded = 1;
+ if ((s->pps->transquant_bypass_enable_flag ||
+ (s->sps->pcm.loop_filter_disable_flag && s->sps->pcm_enabled_flag)) &&
+ s->sps->sao_enabled)
+ restore_tqb_pixels(s);
+ }
+
+ if (ctb_addr_ts < 0)
+ return ctb_addr_ts;
+ break;
+ case NAL_EOS_NUT:
+ case NAL_EOB_NUT:
+ s->seq_decode = (s->seq_decode + 1) & 0xff;
+ s->max_ra = INT_MAX;
+ break;
+ case NAL_AUD:
+ case NAL_FD_NUT:
+ break;
+ default:
+ av_log(s->avctx, AV_LOG_INFO,
+ "Skipping NAL unit %d\n", s->nal_unit_type);
+ }
+
+ return 0;
+}
+
+/* FIXME: This is adapted from ff_h264_decode_nal, avoiding duplication
+ between these functions would be nice. */
+int ff_hevc_extract_rbsp(HEVCContext *s, const uint8_t *src, int length,
+ HEVCNAL *nal)
+{
+ int i, si, di;
+ uint8_t *dst;
+
+ s->skipped_bytes = 0;
+#define STARTCODE_TEST \
+ if (i + 2 < length && src[i + 1] == 0 && src[i + 2] <= 3) { \
+ if (src[i + 2] != 3) { \
+ /* startcode, so we must be past the end */ \
+ length = i; \
+ } \
+ break; \
+ }
+#if HAVE_FAST_UNALIGNED
+#define FIND_FIRST_ZERO \
+ if (i > 0 && !src[i]) \
+ i--; \
+ while (src[i]) \
+ i++
+#if HAVE_FAST_64BIT
+ for (i = 0; i + 1 < length; i += 9) {
+ if (!((~AV_RN64A(src + i) &
+ (AV_RN64A(src + i) - 0x0100010001000101ULL)) &
+ 0x8000800080008080ULL))
+ continue;
+ FIND_FIRST_ZERO;
+ STARTCODE_TEST;
+ i -= 7;
+ }
+#else
+ for (i = 0; i + 1 < length; i += 5) {
+ if (!((~AV_RN32A(src + i) &
+ (AV_RN32A(src + i) - 0x01000101U)) &
+ 0x80008080U))
+ continue;
+ FIND_FIRST_ZERO;
+ STARTCODE_TEST;
+ i -= 3;
+ }
+#endif /* HAVE_FAST_64BIT */
+#else
+ for (i = 0; i + 1 < length; i += 2) {
+ if (src[i])
+ continue;
+ if (i > 0 && src[i - 1] == 0)
+ i--;
+ STARTCODE_TEST;
+ }
+#endif /* HAVE_FAST_UNALIGNED */
+
+ if (i >= length - 1) { // no escaped 0
+ nal->data = src;
+ nal->size = length;
+ return length;
+ }
+
+ av_fast_malloc(&nal->rbsp_buffer, &nal->rbsp_buffer_size,
+ length + FF_INPUT_BUFFER_PADDING_SIZE);
+ if (!nal->rbsp_buffer)
+ return AVERROR(ENOMEM);
+
+ dst = nal->rbsp_buffer;
+
+ memcpy(dst, src, i);
+ si = di = i;
+ while (si + 2 < length) {
+ // remove escapes (very rare 1:2^22)
+ if (src[si + 2] > 3) {
+ dst[di++] = src[si++];
+ dst[di++] = src[si++];
+ } else if (src[si] == 0 && src[si + 1] == 0) {
+ if (src[si + 2] == 3) { // escape
+ dst[di++] = 0;
+ dst[di++] = 0;
+ si += 3;
+
+ s->skipped_bytes++;
+ if (s->skipped_bytes_pos_size < s->skipped_bytes) {
+ s->skipped_bytes_pos_size *= 2;
+ av_reallocp_array(&s->skipped_bytes_pos,
+ s->skipped_bytes_pos_size,
+ sizeof(*s->skipped_bytes_pos));
+ if (!s->skipped_bytes_pos)
+ return AVERROR(ENOMEM);
+ }
+ if (s->skipped_bytes_pos)
+ s->skipped_bytes_pos[s->skipped_bytes-1] = di - 1;
+ continue;
+ } else // next start code
+ goto nsc;
+ }
+
+ dst[di++] = src[si++];
+ }
+ while (si < length)
+ dst[di++] = src[si++];
+
+nsc:
+ memset(dst + di, 0, FF_INPUT_BUFFER_PADDING_SIZE);
+
+ nal->data = dst;
+ nal->size = di;
+ return si;
+}
+
+static int decode_nal_units(HEVCContext *s, const uint8_t *buf, int length)
+{
+ int i, consumed, ret = 0;
+
+ s->ref = NULL;
+ s->eos = 0;
+
+ /* split the input packet into NAL units, so we know the upper bound on the
+ * number of slices in the frame */
+ s->nb_nals = 0;
+ while (length >= 4) {
+ HEVCNAL *nal;
+ int extract_length = 0;
+
+ if (s->is_nalff) {
+ int i;
+ for (i = 0; i < s->nal_length_size; i++)
+ extract_length = (extract_length << 8) | buf[i];
+ buf += s->nal_length_size;
+ length -= s->nal_length_size;
+
+ if (extract_length > length) {
+ av_log(s->avctx, AV_LOG_ERROR, "Invalid NAL unit size.\n");
+ ret = AVERROR_INVALIDDATA;
+ goto fail;
+ }
+ } else {
+ /* search start code */
+ while (buf[0] != 0 || buf[1] != 0 || buf[2] != 1) {
+ ++buf;
+ --length;
+ if (length < 4) {
+ av_log(s->avctx, AV_LOG_ERROR, "No start code is found.\n");
+ ret = AVERROR_INVALIDDATA;
+ goto fail;
+ }
+ }
+
+ buf += 3;
+ length -= 3;
+ }
+
+ if (!s->is_nalff)
+ extract_length = length;
+
+ if (s->nals_allocated < s->nb_nals + 1) {
+ int new_size = s->nals_allocated + 1;
+ HEVCNAL *tmp = av_realloc_array(s->nals, new_size, sizeof(*tmp));
+ if (!tmp) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+ s->nals = tmp;
+ memset(s->nals + s->nals_allocated, 0,
+ (new_size - s->nals_allocated) * sizeof(*tmp));
+ av_reallocp_array(&s->skipped_bytes_nal, new_size, sizeof(*s->skipped_bytes_nal));
+ av_reallocp_array(&s->skipped_bytes_pos_size_nal, new_size, sizeof(*s->skipped_bytes_pos_size_nal));
+ av_reallocp_array(&s->skipped_bytes_pos_nal, new_size, sizeof(*s->skipped_bytes_pos_nal));
+ s->skipped_bytes_pos_size_nal[s->nals_allocated] = 1024; // initial buffer size
+ s->skipped_bytes_pos_nal[s->nals_allocated] = av_malloc_array(s->skipped_bytes_pos_size_nal[s->nals_allocated], sizeof(*s->skipped_bytes_pos));
+ s->nals_allocated = new_size;
+ }
+ s->skipped_bytes_pos_size = s->skipped_bytes_pos_size_nal[s->nb_nals];
+ s->skipped_bytes_pos = s->skipped_bytes_pos_nal[s->nb_nals];
+ nal = &s->nals[s->nb_nals];
+
+ consumed = ff_hevc_extract_rbsp(s, buf, extract_length, nal);
+
+ s->skipped_bytes_nal[s->nb_nals] = s->skipped_bytes;
+ s->skipped_bytes_pos_size_nal[s->nb_nals] = s->skipped_bytes_pos_size;
+ s->skipped_bytes_pos_nal[s->nb_nals++] = s->skipped_bytes_pos;
+
+
+ if (consumed < 0) {
+ ret = consumed;
+ goto fail;
+ }
+
+ ret = init_get_bits8(&s->HEVClc->gb, nal->data, nal->size);
+ if (ret < 0)
+ goto fail;
+ hls_nal_unit(s);
+
+ if (s->nal_unit_type == NAL_EOB_NUT ||
+ s->nal_unit_type == NAL_EOS_NUT)
+ s->eos = 1;
+
+ buf += consumed;
+ length -= consumed;
+ }
+
+ /* parse the NAL units */
+ for (i = 0; i < s->nb_nals; i++) {
+ int ret;
+ s->skipped_bytes = s->skipped_bytes_nal[i];
+ s->skipped_bytes_pos = s->skipped_bytes_pos_nal[i];
+
+ ret = decode_nal_unit(s, s->nals[i].data, s->nals[i].size);
+ if (ret < 0) {
+ av_log(s->avctx, AV_LOG_WARNING,
+ "Error parsing NAL unit #%d.\n", i);
+ if (s->avctx->err_recognition & AV_EF_EXPLODE)
+ goto fail;
+ }
+ }
+
+fail:
+ if (s->ref && s->threads_type == FF_THREAD_FRAME)
+ ff_thread_report_progress(&s->ref->tf, INT_MAX, 0);
+
+ return ret;
+}
+
+static void print_md5(void *log_ctx, int level, uint8_t md5[16])
+{
+ int i;
+ for (i = 0; i < 16; i++)
+ av_log(log_ctx, level, "%02"PRIx8, md5[i]);
+}
+
+static int verify_md5(HEVCContext *s, AVFrame *frame)
+{
+ const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(frame->format);
+ int pixel_shift;
+ int i, j;
+
+ if (!desc)
+ return AVERROR(EINVAL);
+
+ pixel_shift = desc->comp[0].depth_minus1 > 7;
+
+ av_log(s->avctx, AV_LOG_DEBUG, "Verifying checksum for frame with POC %d: ",
+ s->poc);
+
+ /* the checksums are LE, so we have to byteswap for >8bpp formats
+ * on BE arches */
+#if HAVE_BIGENDIAN
+ if (pixel_shift && !s->checksum_buf) {
+ av_fast_malloc(&s->checksum_buf, &s->checksum_buf_size,
+ FFMAX3(frame->linesize[0], frame->linesize[1],
+ frame->linesize[2]));
+ if (!s->checksum_buf)
+ return AVERROR(ENOMEM);
+ }
+#endif
+
+ for (i = 0; frame->data[i]; i++) {
+ int width = s->avctx->coded_width;
+ int height = s->avctx->coded_height;
+ int w = (i == 1 || i == 2) ? (width >> desc->log2_chroma_w) : width;
+ int h = (i == 1 || i == 2) ? (height >> desc->log2_chroma_h) : height;
+ uint8_t md5[16];
+
+ av_md5_init(s->md5_ctx);
+ for (j = 0; j < h; j++) {
+ const uint8_t *src = frame->data[i] + j * frame->linesize[i];
+#if HAVE_BIGENDIAN
+ if (pixel_shift) {
+ s->dsp.bswap16_buf((uint16_t*)s->checksum_buf,
+ (const uint16_t*)src, w);
+ src = s->checksum_buf;
+ }
+#endif
+ av_md5_update(s->md5_ctx, src, w << pixel_shift);
+ }
+ av_md5_final(s->md5_ctx, md5);
+
+ if (!memcmp(md5, s->md5[i], 16)) {
+ av_log (s->avctx, AV_LOG_DEBUG, "plane %d - correct ", i);
+ print_md5(s->avctx, AV_LOG_DEBUG, md5);
+ av_log (s->avctx, AV_LOG_DEBUG, "; ");
+ } else {
+ av_log (s->avctx, AV_LOG_ERROR, "mismatching checksum of plane %d - ", i);
+ print_md5(s->avctx, AV_LOG_ERROR, md5);
+ av_log (s->avctx, AV_LOG_ERROR, " != ");
+ print_md5(s->avctx, AV_LOG_ERROR, s->md5[i]);
+ av_log (s->avctx, AV_LOG_ERROR, "\n");
+ return AVERROR_INVALIDDATA;
+ }
+ }
+
+ av_log(s->avctx, AV_LOG_DEBUG, "\n");
+
+ return 0;
+}
+
+static int hevc_decode_frame(AVCodecContext *avctx, void *data, int *got_output,
+ AVPacket *avpkt)
+{
+ int ret;
+ HEVCContext *s = avctx->priv_data;
+
+ if (!avpkt->size) {
+ ret = ff_hevc_output_frame(s, data, 1);
+ if (ret < 0)
+ return ret;
+
+ *got_output = ret;
+ return 0;
+ }
+
+ s->ref = NULL;
+ ret = decode_nal_units(s, avpkt->data, avpkt->size);
+ if (ret < 0)
+ return ret;
+
+ /* verify the SEI checksum */
+ if (avctx->err_recognition & AV_EF_CRCCHECK && s->is_decoded &&
+ s->is_md5) {
+ ret = verify_md5(s, s->ref->frame);
+ if (ret < 0 && avctx->err_recognition & AV_EF_EXPLODE) {
+ ff_hevc_unref_frame(s, s->ref, ~0);
+ return ret;
+ }
+ }
+ s->is_md5 = 0;
+
+ if (s->is_decoded) {
+ av_log(avctx, AV_LOG_DEBUG, "Decoded frame with POC %d.\n", s->poc);
+ s->is_decoded = 0;
+ }
+
+ if (s->output_frame->buf[0]) {
+ av_frame_move_ref(data, s->output_frame);
+ *got_output = 1;
+ }
+
+ return avpkt->size;
+}
+
+static int hevc_ref_frame(HEVCContext *s, HEVCFrame *dst, HEVCFrame *src)
+{
+ int ret;
+
+ ret = ff_thread_ref_frame(&dst->tf, &src->tf);
+ if (ret < 0)
+ return ret;
+
+ dst->tab_mvf_buf = av_buffer_ref(src->tab_mvf_buf);
+ if (!dst->tab_mvf_buf)
+ goto fail;
+ dst->tab_mvf = src->tab_mvf;
+
+ dst->rpl_tab_buf = av_buffer_ref(src->rpl_tab_buf);
+ if (!dst->rpl_tab_buf)
+ goto fail;
+ dst->rpl_tab = src->rpl_tab;
+
+ dst->rpl_buf = av_buffer_ref(src->rpl_buf);
+ if (!dst->rpl_buf)
+ goto fail;
+
+ dst->poc = src->poc;
+ dst->ctb_count = src->ctb_count;
+ dst->window = src->window;
+ dst->flags = src->flags;
+ dst->sequence = src->sequence;
+
+ return 0;
+fail:
+ ff_hevc_unref_frame(s, dst, ~0);
+ return AVERROR(ENOMEM);
+}
+
+static av_cold int hevc_decode_free(AVCodecContext *avctx)
+{
+ HEVCContext *s = avctx->priv_data;
+ HEVCLocalContext *lc = s->HEVClc;
+ int i;
+
+ pic_arrays_free(s);
+
+ if (lc)
+ av_freep(&lc->edge_emu_buffer);
+ av_freep(&s->md5_ctx);
+
+ for(i=0; i < s->nals_allocated; i++) {
+ av_freep(&s->skipped_bytes_pos_nal[i]);
+ }
+ av_freep(&s->skipped_bytes_pos_size_nal);
+ av_freep(&s->skipped_bytes_nal);
+ av_freep(&s->skipped_bytes_pos_nal);
+
+ av_freep(&s->cabac_state);
+
+ av_frame_free(&s->tmp_frame);
+ av_frame_free(&s->output_frame);
+
+ for (i = 0; i < FF_ARRAY_ELEMS(s->DPB); i++) {
+ ff_hevc_unref_frame(s, &s->DPB[i], ~0);
+ av_frame_free(&s->DPB[i].frame);
+ }
+
+ for (i = 0; i < FF_ARRAY_ELEMS(s->vps_list); i++)
+ av_buffer_unref(&s->vps_list[i]);
+ for (i = 0; i < FF_ARRAY_ELEMS(s->sps_list); i++)
+ av_buffer_unref(&s->sps_list[i]);
+ for (i = 0; i < FF_ARRAY_ELEMS(s->pps_list); i++)
+ av_buffer_unref(&s->pps_list[i]);
+
+ av_freep(&s->sh.entry_point_offset);
+ av_freep(&s->sh.offset);
+ av_freep(&s->sh.size);
+
+ for (i = 1; i < s->threads_number; i++) {
+ lc = s->HEVClcList[i];
+ if (lc) {
+ av_freep(&lc->edge_emu_buffer);
+ av_freep(&s->HEVClcList[i]);
+ av_freep(&s->sList[i]);
+ }
+ }
+ av_freep(&s->HEVClcList[0]);
+
+ for (i = 0; i < s->nals_allocated; i++)
+ av_freep(&s->nals[i].rbsp_buffer);
+ av_freep(&s->nals);
+ s->nals_allocated = 0;
+
+ return 0;
+}
+
+static av_cold int hevc_init_context(AVCodecContext *avctx)
+{
+ HEVCContext *s = avctx->priv_data;
+ int i;
+
+ s->avctx = avctx;
+
+ s->HEVClc = av_mallocz(sizeof(HEVCLocalContext));
+ if (!s->HEVClc)
+ goto fail;
+ s->HEVClcList[0] = s->HEVClc;
+ s->sList[0] = s;
+
+ s->cabac_state = av_malloc(HEVC_CONTEXTS);
+ if (!s->cabac_state)
+ goto fail;
+
+ s->tmp_frame = av_frame_alloc();
+ if (!s->tmp_frame)
+ goto fail;
+
+ s->output_frame = av_frame_alloc();
+ if (!s->output_frame)
+ goto fail;
+
+ for (i = 0; i < FF_ARRAY_ELEMS(s->DPB); i++) {
+ s->DPB[i].frame = av_frame_alloc();
+ if (!s->DPB[i].frame)
+ goto fail;
+ s->DPB[i].tf.f = s->DPB[i].frame;
+ }
+
+ s->max_ra = INT_MAX;
+
+ s->md5_ctx = av_md5_alloc();
+ if (!s->md5_ctx)
+ goto fail;
+
+ ff_dsputil_init(&s->dsp, avctx);
+
+ s->context_initialized = 1;
+
+ return 0;
+
+fail:
+ hevc_decode_free(avctx);
+ return AVERROR(ENOMEM);
+}
+
+static int hevc_update_thread_context(AVCodecContext *dst,
+ const AVCodecContext *src)
+{
+ HEVCContext *s = dst->priv_data;
+ HEVCContext *s0 = src->priv_data;
+ int i, ret;
+
+ if (!s->context_initialized) {
+ ret = hevc_init_context(dst);
+ if (ret < 0)
+ return ret;
+ }
+
+ for (i = 0; i < FF_ARRAY_ELEMS(s->DPB); i++) {
+ ff_hevc_unref_frame(s, &s->DPB[i], ~0);
+ if (s0->DPB[i].frame->buf[0]) {
+ ret = hevc_ref_frame(s, &s->DPB[i], &s0->DPB[i]);
+ if (ret < 0)
+ return ret;
+ }
+ }
+
+ for (i = 0; i < FF_ARRAY_ELEMS(s->vps_list); i++) {
+ av_buffer_unref(&s->vps_list[i]);
+ if (s0->vps_list[i]) {
+ s->vps_list[i] = av_buffer_ref(s0->vps_list[i]);
+ if (!s->vps_list[i])
+ return AVERROR(ENOMEM);
+ }
+ }
+
+ for (i = 0; i < FF_ARRAY_ELEMS(s->sps_list); i++) {
+ av_buffer_unref(&s->sps_list[i]);
+ if (s0->sps_list[i]) {
+ s->sps_list[i] = av_buffer_ref(s0->sps_list[i]);
+ if (!s->sps_list[i])
+ return AVERROR(ENOMEM);
+ }
+ }
+
+ for (i = 0; i < FF_ARRAY_ELEMS(s->pps_list); i++) {
+ av_buffer_unref(&s->pps_list[i]);
+ if (s0->pps_list[i]) {
+ s->pps_list[i] = av_buffer_ref(s0->pps_list[i]);
+ if (!s->pps_list[i])
+ return AVERROR(ENOMEM);
+ }
+ }
+
+ if (s->sps != s0->sps)
+ ret = set_sps(s, s0->sps);
+
+ s->seq_decode = s0->seq_decode;
+ s->seq_output = s0->seq_output;
+ s->pocTid0 = s0->pocTid0;
+ s->max_ra = s0->max_ra;
+
+ s->is_nalff = s0->is_nalff;
+ s->nal_length_size = s0->nal_length_size;
+
+ s->threads_number = s0->threads_number;
+ s->threads_type = s0->threads_type;
+
+ if (s0->eos) {
+ s->seq_decode = (s->seq_decode + 1) & 0xff;
+ s->max_ra = INT_MAX;
+ }
+
+ return 0;
+}
+
+static int hevc_decode_extradata(HEVCContext *s)
+{
+ AVCodecContext *avctx = s->avctx;
+ GetByteContext gb;
+ int ret;
+
+ bytestream2_init(&gb, avctx->extradata, avctx->extradata_size);
+
+ if (avctx->extradata_size > 3 &&
+ (avctx->extradata[0] || avctx->extradata[1] ||
+ avctx->extradata[2] > 1)) {
+ /* It seems the extradata is encoded as hvcC format.
+ * Temporarily, we support configurationVersion==0 until 14496-15 3rd
+ * finalized. When finalized, configurationVersion will be 1 and we
+ * can recognize hvcC by checking if avctx->extradata[0]==1 or not. */
+ int i, j, num_arrays, nal_len_size;
+
+ s->is_nalff = 1;
+
+ bytestream2_skip(&gb, 21);
+ nal_len_size = (bytestream2_get_byte(&gb) & 3) + 1;
+ num_arrays = bytestream2_get_byte(&gb);
+
+ /* nal units in the hvcC always have length coded with 2 bytes,
+ * so put a fake nal_length_size = 2 while parsing them */
+ s->nal_length_size = 2;
+
+ /* Decode nal units from hvcC. */
+ for (i = 0; i < num_arrays; i++) {
+ int type = bytestream2_get_byte(&gb) & 0x3f;
+ int cnt = bytestream2_get_be16(&gb);
+
+ for (j = 0; j < cnt; j++) {
+ // +2 for the nal size field
+ int nalsize = bytestream2_peek_be16(&gb) + 2;
+ if (bytestream2_get_bytes_left(&gb) < nalsize) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "Invalid NAL unit size in extradata.\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ ret = decode_nal_units(s, gb.buffer, nalsize);
+ if (ret < 0) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Decoding nal unit %d %d from hvcC failed\n",
+ type, i);
+ return ret;
+ }
+ bytestream2_skip(&gb, nalsize);
+ }
+ }
+
+ /* Now store right nal length size, that will be used to parse
+ * all other nals */
+ s->nal_length_size = nal_len_size;
+ } else {
+ s->is_nalff = 0;
+ ret = decode_nal_units(s, avctx->extradata, avctx->extradata_size);
+ if (ret < 0)
+ return ret;
+ }
+ return 0;
+}
+
+static av_cold int hevc_decode_init(AVCodecContext *avctx)
+{
+ HEVCContext *s = avctx->priv_data;
+ int ret;
+
+ ff_init_cabac_states();
+
+ avctx->internal->allocate_progress = 1;
+
+ ret = hevc_init_context(avctx);
+ if (ret < 0)
+ return ret;
+
+ s->enable_parallel_tiles = 0;
+ s->picture_struct = 0;
+
+ if(avctx->active_thread_type & FF_THREAD_SLICE)
+ s->threads_number = avctx->thread_count;
+ else
+ s->threads_number = 1;
+
+ if (avctx->extradata_size > 0 && avctx->extradata) {
+ ret = hevc_decode_extradata(s);
+ if (ret < 0) {
+ hevc_decode_free(avctx);
+ return ret;
+ }
+ }
+
+ if((avctx->active_thread_type & FF_THREAD_FRAME) && avctx->thread_count > 1)
+ s->threads_type = FF_THREAD_FRAME;
+ else
+ s->threads_type = FF_THREAD_SLICE;
+
+ return 0;
+}
+
+static av_cold int hevc_init_thread_copy(AVCodecContext *avctx)
+{
+ HEVCContext *s = avctx->priv_data;
+ int ret;
+
+ memset(s, 0, sizeof(*s));
+
+ ret = hevc_init_context(avctx);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+static void hevc_decode_flush(AVCodecContext *avctx)
+{
+ HEVCContext *s = avctx->priv_data;
+ ff_hevc_flush_dpb(s);
+ s->max_ra = INT_MAX;
+}
+
+#define OFFSET(x) offsetof(HEVCContext, x)
+#define PAR (AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM)
+
+static const AVProfile profiles[] = {
+ { FF_PROFILE_HEVC_MAIN, "Main" },
+ { FF_PROFILE_HEVC_MAIN_10, "Main10" },
+ { FF_PROFILE_HEVC_MAIN_STILL_PICTURE, "MainStillPicture" },
+ { FF_PROFILE_UNKNOWN },
+};
+
+static const AVOption options[] = {
+ { "apply_defdispwin", "Apply default display window from VUI", OFFSET(apply_defdispwin),
+ AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, PAR },
+ { "strict-displaywin", "stricly apply default display window size", OFFSET(apply_defdispwin),
+ AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, PAR },
+ { NULL },
+};
+
+static const AVClass hevc_decoder_class = {
+ .class_name = "HEVC decoder",
+ .item_name = av_default_item_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
+AVCodec ff_hevc_decoder = {
+ .name = "hevc",
+ .long_name = NULL_IF_CONFIG_SMALL("HEVC (High Efficiency Video Coding)"),
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = AV_CODEC_ID_HEVC,
+ .priv_data_size = sizeof(HEVCContext),
+ .priv_class = &hevc_decoder_class,
+ .init = hevc_decode_init,
+ .close = hevc_decode_free,
+ .decode = hevc_decode_frame,
+ .flush = hevc_decode_flush,
+ .update_thread_context = hevc_update_thread_context,
+ .init_thread_copy = hevc_init_thread_copy,
+ .capabilities = CODEC_CAP_DR1 | CODEC_CAP_DELAY |
+ CODEC_CAP_SLICE_THREADS | CODEC_CAP_FRAME_THREADS,
+ .profiles = NULL_IF_CONFIG_SMALL(profiles),
+};
diff --git a/libavcodec/hevc.h b/libavcodec/hevc.h
new file mode 100644
index 0000000..74673a9
--- /dev/null
+++ b/libavcodec/hevc.h
@@ -0,0 +1,1012 @@
+/*
+ * HEVC video decoder
+ *
+ * Copyright (C) 2012 - 2013 Guillaume Martres
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVCODEC_HEVC_H
+#define AVCODEC_HEVC_H
+
+#include "libavutil/buffer.h"
+#include "libavutil/md5.h"
+
+#include "avcodec.h"
+#include "cabac.h"
+#include "dsputil.h"
+#include "get_bits.h"
+#include "hevcpred.h"
+#include "hevcdsp.h"
+#include "internal.h"
+#include "thread.h"
+#include "videodsp.h"
+
+#define MAX_DPB_SIZE 16 // A.4.1
+#define MAX_REFS 16
+
+#define MAX_NB_THREADS 16
+#define SHIFT_CTB_WPP 2
+
+/**
+ * 7.4.2.1
+ */
+#define MAX_SUB_LAYERS 7
+#define MAX_VPS_COUNT 16
+#define MAX_SPS_COUNT 32
+#define MAX_PPS_COUNT 256
+#define MAX_SHORT_TERM_RPS_COUNT 64
+#define MAX_CU_SIZE 128
+
+//TODO: check if this is really the maximum
+#define MAX_TRANSFORM_DEPTH 5
+
+#define MAX_TB_SIZE 32
+#define MAX_PB_SIZE 64
+#define MAX_LOG2_CTB_SIZE 6
+#define MAX_QP 51
+#define DEFAULT_INTRA_TC_OFFSET 2
+
+#define HEVC_CONTEXTS 183
+
+#define MRG_MAX_NUM_CANDS 5
+
+#define L0 0
+#define L1 1
+
+#define EPEL_EXTRA_BEFORE 1
+#define EPEL_EXTRA_AFTER 2
+#define EPEL_EXTRA 3
+
+/**
+ * Value of the luma sample at position (x, y) in the 2D array tab.
+ */
+#define SAMPLE(tab, x, y) ((tab)[(y) * s->sps->width + (x)])
+#define SAMPLE_CTB(tab, x, y) ((tab)[(y) * min_cb_width + (x)])
+#define SAMPLE_CBF(tab, x, y) ((tab)[((y) & ((1<<log2_trafo_size)-1)) * MAX_CU_SIZE + ((x) & ((1<<log2_trafo_size)-1))])
+
+#define IS_IDR(s) (s->nal_unit_type == NAL_IDR_W_RADL || s->nal_unit_type == NAL_IDR_N_LP)
+#define IS_BLA(s) (s->nal_unit_type == NAL_BLA_W_RADL || s->nal_unit_type == NAL_BLA_W_LP || \
+ s->nal_unit_type == NAL_BLA_N_LP)
+#define IS_IRAP(s) (s->nal_unit_type >= 16 && s->nal_unit_type <= 23)
+
+/**
+ * Table 7-3: NAL unit type codes
+ */
+enum NALUnitType {
+ NAL_TRAIL_N = 0,
+ NAL_TRAIL_R = 1,
+ NAL_TSA_N = 2,
+ NAL_TSA_R = 3,
+ NAL_STSA_N = 4,
+ NAL_STSA_R = 5,
+ NAL_RADL_N = 6,
+ NAL_RADL_R = 7,
+ NAL_RASL_N = 8,
+ NAL_RASL_R = 9,
+ NAL_BLA_W_LP = 16,
+ NAL_BLA_W_RADL = 17,
+ NAL_BLA_N_LP = 18,
+ NAL_IDR_W_RADL = 19,
+ NAL_IDR_N_LP = 20,
+ NAL_CRA_NUT = 21,
+ NAL_VPS = 32,
+ NAL_SPS = 33,
+ NAL_PPS = 34,
+ NAL_AUD = 35,
+ NAL_EOS_NUT = 36,
+ NAL_EOB_NUT = 37,
+ NAL_FD_NUT = 38,
+ NAL_SEI_PREFIX = 39,
+ NAL_SEI_SUFFIX = 40,
+};
+
+enum RPSType {
+ ST_CURR_BEF = 0,
+ ST_CURR_AFT,
+ ST_FOLL,
+ LT_CURR,
+ LT_FOLL,
+ NB_RPS_TYPE,
+};
+
+enum SliceType {
+ B_SLICE = 0,
+ P_SLICE = 1,
+ I_SLICE = 2,
+};
+
+enum SyntaxElement {
+ SAO_MERGE_FLAG = 0,
+ SAO_TYPE_IDX,
+ SAO_EO_CLASS,
+ SAO_BAND_POSITION,
+ SAO_OFFSET_ABS,
+ SAO_OFFSET_SIGN,
+ END_OF_SLICE_FLAG,
+ SPLIT_CODING_UNIT_FLAG,
+ CU_TRANSQUANT_BYPASS_FLAG,
+ SKIP_FLAG,
+ CU_QP_DELTA,
+ PRED_MODE_FLAG,
+ PART_MODE,
+ PCM_FLAG,
+ PREV_INTRA_LUMA_PRED_FLAG,
+ MPM_IDX,
+ REM_INTRA_LUMA_PRED_MODE,
+ INTRA_CHROMA_PRED_MODE,
+ MERGE_FLAG,
+ MERGE_IDX,
+ INTER_PRED_IDC,
+ REF_IDX_L0,
+ REF_IDX_L1,
+ ABS_MVD_GREATER0_FLAG,
+ ABS_MVD_GREATER1_FLAG,
+ ABS_MVD_MINUS2,
+ MVD_SIGN_FLAG,
+ MVP_LX_FLAG,
+ NO_RESIDUAL_DATA_FLAG,
+ SPLIT_TRANSFORM_FLAG,
+ CBF_LUMA,
+ CBF_CB_CR,
+ TRANSFORM_SKIP_FLAG,
+ LAST_SIGNIFICANT_COEFF_X_PREFIX,
+ LAST_SIGNIFICANT_COEFF_Y_PREFIX,
+ LAST_SIGNIFICANT_COEFF_X_SUFFIX,
+ LAST_SIGNIFICANT_COEFF_Y_SUFFIX,
+ SIGNIFICANT_COEFF_GROUP_FLAG,
+ SIGNIFICANT_COEFF_FLAG,
+ COEFF_ABS_LEVEL_GREATER1_FLAG,
+ COEFF_ABS_LEVEL_GREATER2_FLAG,
+ COEFF_ABS_LEVEL_REMAINING,
+ COEFF_SIGN_FLAG,
+};
+
+enum PartMode {
+ PART_2Nx2N = 0,
+ PART_2NxN = 1,
+ PART_Nx2N = 2,
+ PART_NxN = 3,
+ PART_2NxnU = 4,
+ PART_2NxnD = 5,
+ PART_nLx2N = 6,
+ PART_nRx2N = 7,
+};
+
+enum PredMode {
+ MODE_INTER = 0,
+ MODE_INTRA,
+ MODE_SKIP,
+};
+
+enum InterPredIdc {
+ PRED_L0 = 0,
+ PRED_L1,
+ PRED_BI,
+};
+
+enum IntraPredMode {
+ INTRA_PLANAR = 0,
+ INTRA_DC,
+ INTRA_ANGULAR_2,
+ INTRA_ANGULAR_3,
+ INTRA_ANGULAR_4,
+ INTRA_ANGULAR_5,
+ INTRA_ANGULAR_6,
+ INTRA_ANGULAR_7,
+ INTRA_ANGULAR_8,
+ INTRA_ANGULAR_9,
+ INTRA_ANGULAR_10,
+ INTRA_ANGULAR_11,
+ INTRA_ANGULAR_12,
+ INTRA_ANGULAR_13,
+ INTRA_ANGULAR_14,
+ INTRA_ANGULAR_15,
+ INTRA_ANGULAR_16,
+ INTRA_ANGULAR_17,
+ INTRA_ANGULAR_18,
+ INTRA_ANGULAR_19,
+ INTRA_ANGULAR_20,
+ INTRA_ANGULAR_21,
+ INTRA_ANGULAR_22,
+ INTRA_ANGULAR_23,
+ INTRA_ANGULAR_24,
+ INTRA_ANGULAR_25,
+ INTRA_ANGULAR_26,
+ INTRA_ANGULAR_27,
+ INTRA_ANGULAR_28,
+ INTRA_ANGULAR_29,
+ INTRA_ANGULAR_30,
+ INTRA_ANGULAR_31,
+ INTRA_ANGULAR_32,
+ INTRA_ANGULAR_33,
+ INTRA_ANGULAR_34,
+};
+
+enum SAOType {
+ SAO_NOT_APPLIED = 0,
+ SAO_BAND,
+ SAO_EDGE,
+};
+
+enum SAOEOClass {
+ SAO_EO_HORIZ = 0,
+ SAO_EO_VERT,
+ SAO_EO_135D,
+ SAO_EO_45D,
+};
+
+enum ScanType {
+ SCAN_DIAG = 0,
+ SCAN_HORIZ,
+ SCAN_VERT,
+};
+
+typedef struct ShortTermRPS {
+ int num_negative_pics;
+ int num_delta_pocs;
+ int32_t delta_poc[32];
+ uint8_t used[32];
+} ShortTermRPS;
+
+typedef struct LongTermRPS {
+ int poc[32];
+ uint8_t used[32];
+ uint8_t nb_refs;
+} LongTermRPS;
+
+typedef struct RefPicList {
+ struct HEVCFrame *ref[MAX_REFS];
+ int list[MAX_REFS];
+ int isLongTerm[MAX_REFS];
+ int nb_refs;
+} RefPicList;
+
+typedef struct RefPicListTab {
+ RefPicList refPicList[2];
+} RefPicListTab;
+
+typedef struct HEVCWindow {
+ int left_offset;
+ int right_offset;
+ int top_offset;
+ int bottom_offset;
+} HEVCWindow;
+
+typedef struct VUI {
+ AVRational sar;
+
+ int overscan_info_present_flag;
+ int overscan_appropriate_flag;
+
+ int video_signal_type_present_flag;
+ int video_format;
+ int video_full_range_flag;
+ int colour_description_present_flag;
+ uint8_t colour_primaries;
+ uint8_t transfer_characteristic;
+ uint8_t matrix_coeffs;
+
+ int chroma_loc_info_present_flag;
+ int chroma_sample_loc_type_top_field;
+ int chroma_sample_loc_type_bottom_field;
+ int neutra_chroma_indication_flag;
+
+ int field_seq_flag;
+ int frame_field_info_present_flag;
+
+ int default_display_window_flag;
+ HEVCWindow def_disp_win;
+
+ int vui_timing_info_present_flag;
+ uint32_t vui_num_units_in_tick;
+ uint32_t vui_time_scale;
+ int vui_poc_proportional_to_timing_flag;
+ int vui_num_ticks_poc_diff_one_minus1;
+ int vui_hrd_parameters_present_flag;
+
+ int bitstream_restriction_flag;
+ int tiles_fixed_structure_flag;
+ int motion_vectors_over_pic_boundaries_flag;
+ int restricted_ref_pic_lists_flag;
+ int min_spatial_segmentation_idc;
+ int max_bytes_per_pic_denom;
+ int max_bits_per_min_cu_denom;
+ int log2_max_mv_length_horizontal;
+ int log2_max_mv_length_vertical;
+} VUI;
+
+typedef struct ProfileTierLevel {
+ int profile_space;
+ uint8_t tier_flag;
+ int profile_idc;
+ int profile_compatibility_flag[32];
+ int level_idc;
+ int progressive_source_flag;
+ int interlaced_source_flag;
+ int non_packed_constraint_flag;
+ int frame_only_constraint_flag;
+} ProfileTierLevel;
+
+typedef struct PTL {
+ ProfileTierLevel general_PTL;
+ ProfileTierLevel sub_layer_PTL[MAX_SUB_LAYERS];
+
+ uint8_t sub_layer_profile_present_flag[MAX_SUB_LAYERS];
+ uint8_t sub_layer_level_present_flag[MAX_SUB_LAYERS];
+
+ int sub_layer_profile_space[MAX_SUB_LAYERS];
+ uint8_t sub_layer_tier_flag[MAX_SUB_LAYERS];
+ int sub_layer_profile_idc[MAX_SUB_LAYERS];
+ uint8_t sub_layer_profile_compatibility_flags[MAX_SUB_LAYERS][32];
+ int sub_layer_level_idc[MAX_SUB_LAYERS];
+} PTL;
+
+typedef struct HEVCVPS {
+ uint8_t vps_temporal_id_nesting_flag;
+ int vps_max_layers;
+ int vps_max_sub_layers; ///< vps_max_temporal_layers_minus1 + 1
+
+ PTL ptl;
+ int vps_sub_layer_ordering_info_present_flag;
+ unsigned int vps_max_dec_pic_buffering[MAX_SUB_LAYERS];
+ unsigned int vps_num_reorder_pics[MAX_SUB_LAYERS];
+ unsigned int vps_max_latency_increase[MAX_SUB_LAYERS];
+ int vps_max_layer_id;
+ int vps_num_layer_sets; ///< vps_num_layer_sets_minus1 + 1
+ uint8_t vps_timing_info_present_flag;
+ uint32_t vps_num_units_in_tick;
+ uint32_t vps_time_scale;
+ uint8_t vps_poc_proportional_to_timing_flag;
+ int vps_num_ticks_poc_diff_one; ///< vps_num_ticks_poc_diff_one_minus1 + 1
+ int vps_num_hrd_parameters;
+
+ int vps_extension_flag;
+} HEVCVPS;
+
+typedef struct ScalingList {
+ /* This is a little wasteful, since sizeID 0 only needs 8 coeffs,
+ * and size ID 3 only has 2 arrays, not 6. */
+ uint8_t sl[4][6][64];
+ uint8_t sl_dc[2][6];
+} ScalingList;
+
+typedef struct HEVCSPS {
+ int vps_id;
+ int chroma_format_idc;
+ uint8_t separate_colour_plane_flag;
+
+ ///< output (i.e. cropped) values
+ int output_width, output_height;
+ HEVCWindow output_window;
+
+ HEVCWindow pic_conf_win;
+
+ int bit_depth;
+ int pixel_shift;
+ enum AVPixelFormat pix_fmt;
+
+ unsigned int log2_max_poc_lsb;
+ int pcm_enabled_flag;
+
+ int max_sub_layers;
+ struct {
+ int max_dec_pic_buffering;
+ int num_reorder_pics;
+ int max_latency_increase;
+ } temporal_layer[MAX_SUB_LAYERS];
+
+ VUI vui;
+ PTL ptl;
+
+ uint8_t scaling_list_enable_flag;
+ ScalingList scaling_list;
+
+ unsigned int nb_st_rps;
+ ShortTermRPS st_rps[MAX_SHORT_TERM_RPS_COUNT];
+
+ uint8_t amp_enabled_flag;
+ uint8_t sao_enabled;
+
+ uint8_t long_term_ref_pics_present_flag;
+ uint16_t lt_ref_pic_poc_lsb_sps[32];
+ uint8_t used_by_curr_pic_lt_sps_flag[32];
+ uint8_t num_long_term_ref_pics_sps;
+
+ struct {
+ uint8_t bit_depth;
+ uint8_t bit_depth_chroma;
+ unsigned int log2_min_pcm_cb_size;
+ unsigned int log2_max_pcm_cb_size;
+ uint8_t loop_filter_disable_flag;
+ } pcm;
+ uint8_t sps_temporal_mvp_enabled_flag;
+ uint8_t sps_strong_intra_smoothing_enable_flag;
+
+ unsigned int log2_min_cb_size;
+ unsigned int log2_diff_max_min_coding_block_size;
+ unsigned int log2_min_tb_size;
+ unsigned int log2_max_trafo_size;
+ unsigned int log2_ctb_size;
+ unsigned int log2_min_pu_size;
+
+ int max_transform_hierarchy_depth_inter;
+ int max_transform_hierarchy_depth_intra;
+
+ ///< coded frame dimension in various units
+ int width;
+ int height;
+ int ctb_width;
+ int ctb_height;
+ int ctb_size;
+ int min_cb_width;
+ int min_cb_height;
+ int min_tb_width;
+ int min_tb_height;
+ int min_pu_width;
+ int min_pu_height;
+
+ int hshift[3];
+ int vshift[3];
+
+ int qp_bd_offset;
+} HEVCSPS;
+
+typedef struct HEVCPPS {
+ int sps_id; ///< seq_parameter_set_id
+
+ uint8_t sign_data_hiding_flag;
+
+ uint8_t cabac_init_present_flag;
+
+ int num_ref_idx_l0_default_active; ///< num_ref_idx_l0_default_active_minus1 + 1
+ int num_ref_idx_l1_default_active; ///< num_ref_idx_l1_default_active_minus1 + 1
+ int pic_init_qp_minus26;
+
+ uint8_t constrained_intra_pred_flag;
+ uint8_t transform_skip_enabled_flag;
+
+ uint8_t cu_qp_delta_enabled_flag;
+ int diff_cu_qp_delta_depth;
+
+ int cb_qp_offset;
+ int cr_qp_offset;
+ uint8_t pic_slice_level_chroma_qp_offsets_present_flag;
+ uint8_t weighted_pred_flag;
+ uint8_t weighted_bipred_flag;
+ uint8_t output_flag_present_flag;
+ uint8_t transquant_bypass_enable_flag;
+
+ uint8_t dependent_slice_segments_enabled_flag;
+ uint8_t tiles_enabled_flag;
+ uint8_t entropy_coding_sync_enabled_flag;
+
+ int num_tile_columns; ///< num_tile_columns_minus1 + 1
+ int num_tile_rows; ///< num_tile_rows_minus1 + 1
+ uint8_t uniform_spacing_flag;
+ uint8_t loop_filter_across_tiles_enabled_flag;
+
+ uint8_t seq_loop_filter_across_slices_enabled_flag;
+
+ uint8_t deblocking_filter_control_present_flag;
+ uint8_t deblocking_filter_override_enabled_flag;
+ uint8_t disable_dbf;
+ int beta_offset; ///< beta_offset_div2 * 2
+ int tc_offset; ///< tc_offset_div2 * 2
+
+ int scaling_list_data_present_flag;
+ ScalingList scaling_list;
+
+ uint8_t lists_modification_present_flag;
+ int log2_parallel_merge_level; ///< log2_parallel_merge_level_minus2 + 2
+ int num_extra_slice_header_bits;
+ uint8_t slice_header_extension_present_flag;
+
+ uint8_t pps_extension_flag;
+ uint8_t pps_extension_data_flag;
+
+ // Inferred parameters
+ int *column_width; ///< ColumnWidth
+ int *row_height; ///< RowHeight
+ int *col_bd; ///< ColBd
+ int *row_bd; ///< RowBd
+ int *col_idxX;
+
+ int *ctb_addr_rs_to_ts; ///< CtbAddrRSToTS
+ int *ctb_addr_ts_to_rs; ///< CtbAddrTSToRS
+ int *tile_id; ///< TileId
+ int *tile_pos_rs; ///< TilePosRS
+ int *min_cb_addr_zs; ///< MinCbAddrZS
+ int *min_tb_addr_zs; ///< MinTbAddrZS
+} HEVCPPS;
+
+typedef struct SliceHeader {
+ int pps_id;
+
+ ///< address (in raster order) of the first block in the current slice segment
+ unsigned int slice_segment_addr;
+ ///< address (in raster order) of the first block in the current slice
+ unsigned int slice_addr;
+
+ enum SliceType slice_type;
+
+ int pic_order_cnt_lsb;
+
+ uint8_t first_slice_in_pic_flag;
+ uint8_t dependent_slice_segment_flag;
+ uint8_t pic_output_flag;
+ uint8_t colour_plane_id;
+
+ ///< RPS coded in the slice header itself is stored here
+ ShortTermRPS slice_rps;
+ const ShortTermRPS *short_term_rps;
+ LongTermRPS long_term_rps;
+ unsigned int list_entry_lx[2][32];
+
+ uint8_t rpl_modification_flag[2];
+ uint8_t no_output_of_prior_pics_flag;
+ uint8_t slice_temporal_mvp_enabled_flag;
+
+ unsigned int nb_refs[2];
+
+ uint8_t slice_sample_adaptive_offset_flag[3];
+ uint8_t mvd_l1_zero_flag;
+
+ uint8_t cabac_init_flag;
+ uint8_t disable_deblocking_filter_flag; ///< slice_header_disable_deblocking_filter_flag
+ uint8_t slice_loop_filter_across_slices_enabled_flag;
+ uint8_t collocated_list;
+
+ unsigned int collocated_ref_idx;
+
+ int slice_qp_delta;
+ int slice_cb_qp_offset;
+ int slice_cr_qp_offset;
+
+ int beta_offset; ///< beta_offset_div2 * 2
+ int tc_offset; ///< tc_offset_div2 * 2
+
+ int max_num_merge_cand; ///< 5 - 5_minus_max_num_merge_cand
+
+
+ int *entry_point_offset;
+ int * offset;
+ int * size;
+ int num_entry_point_offsets;
+
+ int8_t slice_qp;
+
+ uint8_t luma_log2_weight_denom;
+ int16_t chroma_log2_weight_denom;
+
+ int16_t luma_weight_l0[16];
+ int16_t chroma_weight_l0[16][2];
+ int16_t chroma_weight_l1[16][2];
+ int16_t luma_weight_l1[16];
+
+ int16_t luma_offset_l0[16];
+ int16_t chroma_offset_l0[16][2];
+
+ int16_t luma_offset_l1[16];
+ int16_t chroma_offset_l1[16][2];
+
+ int slice_ctb_addr_rs;
+} SliceHeader;
+
+typedef struct CodingTree {
+ int depth; ///< ctDepth
+} CodingTree;
+
+typedef struct CodingUnit {
+ int x;
+ int y;
+
+ enum PredMode pred_mode; ///< PredMode
+ enum PartMode part_mode; ///< PartMode
+
+ uint8_t rqt_root_cbf;
+
+ uint8_t pcm_flag;
+
+ // Inferred parameters
+ uint8_t intra_split_flag; ///< IntraSplitFlag
+ uint8_t max_trafo_depth; ///< MaxTrafoDepth
+ uint8_t cu_transquant_bypass_flag;
+} CodingUnit;
+
+typedef struct Mv {
+ int16_t x; ///< horizontal component of motion vector
+ int16_t y; ///< vertical component of motion vector
+} Mv;
+
+typedef struct MvField {
+ Mv mv[2];
+ int8_t ref_idx[2];
+ int8_t pred_flag[2];
+ uint8_t is_intra;
+} MvField;
+
+typedef struct NeighbourAvailable {
+ int cand_bottom_left;
+ int cand_left;
+ int cand_up;
+ int cand_up_left;
+ int cand_up_right;
+ int cand_up_right_sap;
+} NeighbourAvailable;
+
+typedef struct PredictionUnit {
+ int mpm_idx;
+ int rem_intra_luma_pred_mode;
+ uint8_t intra_pred_mode[4];
+ Mv mvd;
+ uint8_t merge_flag;
+ uint8_t intra_pred_mode_c;
+} PredictionUnit;
+
+typedef struct TransformTree {
+ uint8_t cbf_cb[MAX_TRANSFORM_DEPTH][MAX_CU_SIZE * MAX_CU_SIZE];
+ uint8_t cbf_cr[MAX_TRANSFORM_DEPTH][MAX_CU_SIZE * MAX_CU_SIZE];
+ uint8_t cbf_luma;
+
+ // Inferred parameters
+ uint8_t inter_split_flag;
+} TransformTree;
+
+typedef struct TransformUnit {
+ int cu_qp_delta;
+
+ // Inferred parameters;
+ int cur_intra_pred_mode;
+ uint8_t is_cu_qp_delta_coded;
+} TransformUnit;
+
+typedef struct SAOParams {
+ int offset_abs[3][4]; ///< sao_offset_abs
+ int offset_sign[3][4]; ///< sao_offset_sign
+
+ int band_position[3]; ///< sao_band_position
+
+ int eo_class[3]; ///< sao_eo_class
+
+ int offset_val[3][5]; ///<SaoOffsetVal
+
+ uint8_t type_idx[3]; ///< sao_type_idx
+} SAOParams;
+
+typedef struct DBParams {
+ int beta_offset;
+ int tc_offset;
+} DBParams;
+
+#define HEVC_FRAME_FLAG_OUTPUT (1 << 0)
+#define HEVC_FRAME_FLAG_SHORT_REF (1 << 1)
+#define HEVC_FRAME_FLAG_LONG_REF (1 << 2)
+
+typedef struct HEVCFrame {
+ AVFrame *frame;
+ ThreadFrame tf;
+ MvField *tab_mvf;
+ RefPicList *refPicList;
+ RefPicListTab **rpl_tab;
+ int ctb_count;
+ int poc;
+ struct HEVCFrame *collocated_ref;
+
+ HEVCWindow window;
+
+ AVBufferRef *tab_mvf_buf;
+ AVBufferRef *rpl_tab_buf;
+ AVBufferRef *rpl_buf;
+
+ /**
+ * A sequence counter, so that old frames are output first
+ * after a POC reset
+ */
+ uint16_t sequence;
+
+ /**
+ * A combination of HEVC_FRAME_FLAG_*
+ */
+ uint8_t flags;
+} HEVCFrame;
+
+typedef struct HEVCNAL {
+ uint8_t *rbsp_buffer;
+ int rbsp_buffer_size;
+
+ int size;
+ const uint8_t *data;
+} HEVCNAL;
+
+typedef struct HEVCLocalContext {
+ DECLARE_ALIGNED(16, int16_t, mc_buffer[(MAX_PB_SIZE + 7) * MAX_PB_SIZE]);
+ uint8_t cabac_state[HEVC_CONTEXTS];
+
+ uint8_t first_qp_group;
+
+ GetBitContext gb;
+ CABACContext cc;
+ TransformTree tt;
+
+ int8_t qp_y;
+ int8_t curr_qp_y;
+
+ TransformUnit tu;
+
+ uint8_t ctb_left_flag;
+ uint8_t ctb_up_flag;
+ uint8_t ctb_up_right_flag;
+ uint8_t ctb_up_left_flag;
+ int start_of_tiles_x;
+ int end_of_tiles_x;
+ int end_of_tiles_y;
+ uint8_t *edge_emu_buffer;
+ int edge_emu_buffer_size;
+ CodingTree ct;
+ CodingUnit cu;
+ PredictionUnit pu;
+ NeighbourAvailable na;
+
+ uint8_t slice_or_tiles_left_boundary;
+ uint8_t slice_or_tiles_up_boundary;
+} HEVCLocalContext;
+
+typedef struct HEVCContext {
+ const AVClass *c; // needed by private avoptions
+ AVCodecContext *avctx;
+
+ struct HEVCContext *sList[MAX_NB_THREADS];
+
+ HEVCLocalContext *HEVClcList[MAX_NB_THREADS];
+ HEVCLocalContext *HEVClc;
+
+ uint8_t threads_type;
+ uint8_t threads_number;
+
+ int width;
+ int height;
+
+ uint8_t *cabac_state;
+
+ /** 1 if the independent slice segment header was successfully parsed */
+ uint8_t slice_initialized;
+
+ AVFrame *frame;
+ AVFrame *sao_frame;
+ AVFrame *tmp_frame;
+ AVFrame *output_frame;
+
+ HEVCVPS *vps;
+ const HEVCSPS *sps;
+ HEVCPPS *pps;
+ AVBufferRef *vps_list[MAX_VPS_COUNT];
+ AVBufferRef *sps_list[MAX_SPS_COUNT];
+ AVBufferRef *pps_list[MAX_PPS_COUNT];
+
+ AVBufferPool *tab_mvf_pool;
+ AVBufferPool *rpl_tab_pool;
+
+ ///< candidate references for the current frame
+ RefPicList rps[5];
+
+ SliceHeader sh;
+ SAOParams *sao;
+ DBParams *deblock;
+ enum NALUnitType nal_unit_type;
+ int temporal_id; ///< temporal_id_plus1 - 1
+ HEVCFrame *ref;
+ HEVCFrame DPB[32];
+ int poc;
+ int pocTid0;
+ int slice_idx; ///< number of the slice being currently decoded
+ int eos; ///< current packet contains an EOS/EOB NAL
+ int max_ra;
+ int bs_width;
+ int bs_height;
+
+ int is_decoded;
+
+ HEVCPredContext hpc;
+ HEVCDSPContext hevcdsp;
+ VideoDSPContext vdsp;
+ DSPContext dsp;
+ int8_t *qp_y_tab;
+ uint8_t *split_cu_flag;
+ uint8_t *horizontal_bs;
+ uint8_t *vertical_bs;
+
+ int32_t *tab_slice_address;
+
+ // CU
+ uint8_t *skip_flag;
+ uint8_t *tab_ct_depth;
+ // PU
+ uint8_t *tab_ipm;
+
+ uint8_t *cbf_luma; // cbf_luma of colocated TU
+ uint8_t *is_pcm;
+
+ // CTB-level flags affecting loop filter operation
+ uint8_t *filter_slice_edges;
+
+ /** used on BE to byteswap the lines for checksumming */
+ uint8_t *checksum_buf;
+ int checksum_buf_size;
+
+ /**
+ * Sequence counters for decoded and output frames, so that old
+ * frames are output first after a POC reset
+ */
+ uint16_t seq_decode;
+ uint16_t seq_output;
+
+ int enable_parallel_tiles;
+ int wpp_err;
+ int skipped_bytes;
+ int *skipped_bytes_pos;
+ int skipped_bytes_pos_size;
+
+ int *skipped_bytes_nal;
+ int **skipped_bytes_pos_nal;
+ int *skipped_bytes_pos_size_nal;
+
+ uint8_t *data;
+
+ HEVCNAL *nals;
+ int nb_nals;
+ int nals_allocated;
+
+ // for checking the frame checksums
+ struct AVMD5 *md5_ctx;
+ uint8_t md5[3][16];
+ uint8_t is_md5;
+
+ int context_initialized;
+ int is_nalff; ///< this flag is != 0 if bitstream is encapsulated
+ ///< as a format defined in 14496-15
+ int apply_defdispwin;
+
+ int active_seq_parameter_set_id;
+
+ int nal_length_size; ///< Number of bytes used for nal length (1, 2 or 4)
+ int nuh_layer_id;
+
+ int picture_struct;
+} HEVCContext;
+
+int ff_hevc_decode_short_term_rps(HEVCContext *s, ShortTermRPS *rps,
+ const HEVCSPS *sps, int is_slice_header);
+int ff_hevc_decode_nal_vps(HEVCContext *s);
+int ff_hevc_decode_nal_sps(HEVCContext *s);
+int ff_hevc_decode_nal_pps(HEVCContext *s);
+int ff_hevc_decode_nal_sei(HEVCContext *s);
+
+int ff_hevc_extract_rbsp(HEVCContext *s, const uint8_t *src, int length,
+ HEVCNAL *nal);
+
+/**
+ * Mark all frames in DPB as unused for reference.
+ */
+void ff_hevc_clear_refs(HEVCContext *s);
+
+/**
+ * Drop all frames currently in DPB.
+ */
+void ff_hevc_flush_dpb(HEVCContext *s);
+
+/**
+ * Compute POC of the current frame and return it.
+ */
+int ff_hevc_compute_poc(HEVCContext *s, int poc_lsb);
+
+RefPicList *ff_hevc_get_ref_list(HEVCContext *s, HEVCFrame *frame,
+ int x0, int y0);
+
+/**
+ * Construct the reference picture sets for the current frame.
+ */
+int ff_hevc_frame_rps(HEVCContext *s);
+
+/**
+ * Construct the reference picture list(s) for the current slice.
+ */
+int ff_hevc_slice_rpl(HEVCContext *s);
+
+void ff_hevc_save_states(HEVCContext *s, int ctb_addr_ts);
+void ff_hevc_cabac_init(HEVCContext *s, int ctb_addr_ts);
+int ff_hevc_sao_merge_flag_decode(HEVCContext *s);
+int ff_hevc_sao_type_idx_decode(HEVCContext *s);
+int ff_hevc_sao_band_position_decode(HEVCContext *s);
+int ff_hevc_sao_offset_abs_decode(HEVCContext *s);
+int ff_hevc_sao_offset_sign_decode(HEVCContext *s);
+int ff_hevc_sao_eo_class_decode(HEVCContext *s);
+int ff_hevc_end_of_slice_flag_decode(HEVCContext *s);
+int ff_hevc_cu_transquant_bypass_flag_decode(HEVCContext *s);
+int ff_hevc_skip_flag_decode(HEVCContext *s, int x0, int y0,
+ int x_cb, int y_cb);
+int ff_hevc_pred_mode_decode(HEVCContext *s);
+int ff_hevc_split_coding_unit_flag_decode(HEVCContext *s, int ct_depth,
+ int x0, int y0);
+int ff_hevc_part_mode_decode(HEVCContext *s, int log2_cb_size);
+int ff_hevc_pcm_flag_decode(HEVCContext *s);
+int ff_hevc_prev_intra_luma_pred_flag_decode(HEVCContext *s);
+int ff_hevc_mpm_idx_decode(HEVCContext *s);
+int ff_hevc_rem_intra_luma_pred_mode_decode(HEVCContext *s);
+int ff_hevc_intra_chroma_pred_mode_decode(HEVCContext *s);
+int ff_hevc_merge_idx_decode(HEVCContext *s);
+int ff_hevc_merge_flag_decode(HEVCContext *s);
+int ff_hevc_inter_pred_idc_decode(HEVCContext *s, int nPbW, int nPbH);
+int ff_hevc_ref_idx_lx_decode(HEVCContext *s, int num_ref_idx_lx);
+int ff_hevc_mvp_lx_flag_decode(HEVCContext *s);
+int ff_hevc_no_residual_syntax_flag_decode(HEVCContext *s);
+int ff_hevc_split_transform_flag_decode(HEVCContext *s, int log2_trafo_size);
+int ff_hevc_cbf_cb_cr_decode(HEVCContext *s, int trafo_depth);
+int ff_hevc_cbf_luma_decode(HEVCContext *s, int trafo_depth);
+int ff_hevc_transform_skip_flag_decode(HEVCContext *s, int c_idx);
+
+/**
+ * Get the number of candidate references for the current frame.
+ */
+int ff_hevc_frame_nb_refs(HEVCContext *s);
+
+int ff_hevc_set_new_ref(HEVCContext *s, AVFrame **frame, int poc);
+
+/**
+ * Find next frame in output order and put a reference to it in frame.
+ * @return 1 if a frame was output, 0 otherwise
+ */
+int ff_hevc_output_frame(HEVCContext *s, AVFrame *frame, int flush);
+
+void ff_hevc_unref_frame(HEVCContext *s, HEVCFrame *frame, int flags);
+
+void ff_hevc_set_neighbour_available(HEVCContext *s, int x0, int y0,
+ int nPbW, int nPbH);
+void ff_hevc_luma_mv_merge_mode(HEVCContext *s, int x0, int y0,
+ int nPbW, int nPbH, int log2_cb_size,
+ int part_idx, int merge_idx, MvField *mv);
+void ff_hevc_luma_mv_mvp_mode(HEVCContext *s, int x0, int y0,
+ int nPbW, int nPbH, int log2_cb_size,
+ int part_idx, int merge_idx,
+ MvField *mv, int mvp_lx_flag, int LX);
+void ff_hevc_set_qPy(HEVCContext *s, int xC, int yC, int xBase, int yBase,
+ int log2_cb_size);
+void ff_hevc_deblocking_boundary_strengths(HEVCContext *s, int x0, int y0,
+ int log2_trafo_size,
+ int slice_or_tiles_up_boundary,
+ int slice_or_tiles_left_boundary);
+int ff_hevc_cu_qp_delta_sign_flag(HEVCContext *s);
+int ff_hevc_cu_qp_delta_abs(HEVCContext *s);
+void ff_hevc_hls_filter(HEVCContext *s, int x, int y);
+void ff_hevc_hls_filters(HEVCContext *s, int x_ctb, int y_ctb, int ctb_size);
+void ff_hevc_hls_residual_coding(HEVCContext *s, int x0, int y0,
+ int log2_trafo_size, enum ScanType scan_idx,
+ int c_idx);
+
+void ff_hevc_hls_mvd_coding(HEVCContext *s, int x0, int y0, int log2_cb_size);
+
+
+extern const uint8_t ff_hevc_qpel_extra_before[4];
+extern const uint8_t ff_hevc_qpel_extra_after[4];
+extern const uint8_t ff_hevc_qpel_extra[4];
+
+extern const uint8_t ff_hevc_diag_scan4x4_x[16];
+extern const uint8_t ff_hevc_diag_scan4x4_y[16];
+extern const uint8_t ff_hevc_diag_scan8x8_x[64];
+extern const uint8_t ff_hevc_diag_scan8x8_y[64];
+
+#endif /* AVCODEC_HEVC_H */
diff --git a/libavcodec/hevc_cabac.c b/libavcodec/hevc_cabac.c
new file mode 100644
index 0000000..da7a213
--- /dev/null
+++ b/libavcodec/hevc_cabac.c
@@ -0,0 +1,1419 @@
+/*
+ * HEVC CABAC decoding
+ *
+ * Copyright (C) 2012 - 2013 Guillaume Martres
+ * Copyright (C) 2012 - 2013 Gildas Cocherel
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "libavutil/attributes.h"
+#include "libavutil/common.h"
+
+#include "cabac_functions.h"
+#include "hevc.h"
+
+#define CABAC_MAX_BIN 100
+
+/**
+ * number of bin by SyntaxElement.
+ */
+static const int8_t num_bins_in_se[] = {
+ 1, // sao_merge_flag
+ 1, // sao_type_idx
+ 0, // sao_eo_class
+ 0, // sao_band_position
+ 0, // sao_offset_abs
+ 0, // sao_offset_sign
+ 0, // end_of_slice_flag
+ 3, // split_coding_unit_flag
+ 1, // cu_transquant_bypass_flag
+ 3, // skip_flag
+ 3, // cu_qp_delta
+ 1, // pred_mode
+ 4, // part_mode
+ 0, // pcm_flag
+ 1, // prev_intra_luma_pred_mode
+ 0, // mpm_idx
+ 0, // rem_intra_luma_pred_mode
+ 2, // intra_chroma_pred_mode
+ 1, // merge_flag
+ 1, // merge_idx
+ 5, // inter_pred_idc
+ 2, // ref_idx_l0
+ 2, // ref_idx_l1
+ 2, // abs_mvd_greater0_flag
+ 2, // abs_mvd_greater1_flag
+ 0, // abs_mvd_minus2
+ 0, // mvd_sign_flag
+ 1, // mvp_lx_flag
+ 1, // no_residual_data_flag
+ 3, // split_transform_flag
+ 2, // cbf_luma
+ 4, // cbf_cb, cbf_cr
+ 2, // transform_skip_flag[][]
+ 18, // last_significant_coeff_x_prefix
+ 18, // last_significant_coeff_y_prefix
+ 0, // last_significant_coeff_x_suffix
+ 0, // last_significant_coeff_y_suffix
+ 4, // significant_coeff_group_flag
+ 42, // significant_coeff_flag
+ 24, // coeff_abs_level_greater1_flag
+ 6, // coeff_abs_level_greater2_flag
+ 0, // coeff_abs_level_remaining
+ 0, // coeff_sign_flag
+};
+
+/**
+ * Offset to ctxIdx 0 in init_values and states, indexed by SyntaxElement.
+ */
+static const int elem_offset[sizeof(num_bins_in_se)] = {
+ 0,
+ 1,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 5,
+ 6,
+ 9,
+ 12,
+ 13,
+ 17,
+ 17,
+ 18,
+ 18,
+ 18,
+ 20,
+ 21,
+ 22,
+ 27,
+ 29,
+ 31,
+ 33,
+ 35,
+ 35,
+ 35,
+ 36,
+ 37,
+ 40,
+ 42,
+ 46,
+ 48,
+ 66,
+ 84,
+ 84,
+ 84,
+ 88,
+ 130,
+ 154,
+ 160,
+ 160,
+};
+
+#define CNU 154
+/**
+ * Indexed by init_type
+ */
+static const uint8_t init_values[3][HEVC_CONTEXTS] = {
+ { // sao_merge_flag
+ 153,
+ // sao_type_idx
+ 200,
+ // split_coding_unit_flag
+ 139, 141, 157,
+ // cu_transquant_bypass_flag
+ 154,
+ // skip_flag
+ CNU, CNU, CNU,
+ // cu_qp_delta
+ 154, 154, 154,
+ // pred_mode
+ CNU,
+ // part_mode
+ 184, CNU, CNU, CNU,
+ // prev_intra_luma_pred_mode
+ 184,
+ // intra_chroma_pred_mode
+ 63, 139,
+ // merge_flag
+ CNU,
+ // merge_idx
+ CNU,
+ // inter_pred_idc
+ CNU, CNU, CNU, CNU, CNU,
+ // ref_idx_l0
+ CNU, CNU,
+ // ref_idx_l1
+ CNU, CNU,
+ // abs_mvd_greater1_flag
+ CNU, CNU,
+ // abs_mvd_greater1_flag
+ CNU, CNU,
+ // mvp_lx_flag
+ CNU,
+ // no_residual_data_flag
+ CNU,
+ // split_transform_flag
+ 153, 138, 138,
+ // cbf_luma
+ 111, 141,
+ // cbf_cb, cbf_cr
+ 94, 138, 182, 154,
+ // transform_skip_flag
+ 139, 139,
+ // last_significant_coeff_x_prefix
+ 110, 110, 124, 125, 140, 153, 125, 127, 140, 109, 111, 143, 127, 111,
+ 79, 108, 123, 63,
+ // last_significant_coeff_y_prefix
+ 110, 110, 124, 125, 140, 153, 125, 127, 140, 109, 111, 143, 127, 111,
+ 79, 108, 123, 63,
+ // significant_coeff_group_flag
+ 91, 171, 134, 141,
+ // significant_coeff_flag
+ 111, 111, 125, 110, 110, 94, 124, 108, 124, 107, 125, 141, 179, 153,
+ 125, 107, 125, 141, 179, 153, 125, 107, 125, 141, 179, 153, 125, 140,
+ 139, 182, 182, 152, 136, 152, 136, 153, 136, 139, 111, 136, 139, 111,
+ // coeff_abs_level_greater1_flag
+ 140, 92, 137, 138, 140, 152, 138, 139, 153, 74, 149, 92, 139, 107,
+ 122, 152, 140, 179, 166, 182, 140, 227, 122, 197,
+ // coeff_abs_level_greater2_flag
+ 138, 153, 136, 167, 152, 152, },
+ { // sao_merge_flag
+ 153,
+ // sao_type_idx
+ 185,
+ // split_coding_unit_flag
+ 107, 139, 126,
+ // cu_transquant_bypass_flag
+ 154,
+ // skip_flag
+ 197, 185, 201,
+ // cu_qp_delta
+ 154, 154, 154,
+ // pred_mode
+ 149,
+ // part_mode
+ 154, 139, 154, 154,
+ // prev_intra_luma_pred_mode
+ 154,
+ // intra_chroma_pred_mode
+ 152, 139,
+ // merge_flag
+ 110,
+ // merge_idx
+ 122,
+ // inter_pred_idc
+ 95, 79, 63, 31, 31,
+ // ref_idx_l0
+ 153, 153,
+ // ref_idx_l1
+ 153, 153,
+ // abs_mvd_greater1_flag
+ 140, 198,
+ // abs_mvd_greater1_flag
+ 140, 198,
+ // mvp_lx_flag
+ 168,
+ // no_residual_data_flag
+ 79,
+ // split_transform_flag
+ 124, 138, 94,
+ // cbf_luma
+ 153, 111,
+ // cbf_cb, cbf_cr
+ 149, 107, 167, 154,
+ // transform_skip_flag
+ 139, 139,
+ // last_significant_coeff_x_prefix
+ 125, 110, 94, 110, 95, 79, 125, 111, 110, 78, 110, 111, 111, 95,
+ 94, 108, 123, 108,
+ // last_significant_coeff_y_prefix
+ 125, 110, 94, 110, 95, 79, 125, 111, 110, 78, 110, 111, 111, 95,
+ 94, 108, 123, 108,
+ // significant_coeff_group_flag
+ 121, 140, 61, 154,
+ // significant_coeff_flag
+ 155, 154, 139, 153, 139, 123, 123, 63, 153, 166, 183, 140, 136, 153,
+ 154, 166, 183, 140, 136, 153, 154, 166, 183, 140, 136, 153, 154, 170,
+ 153, 123, 123, 107, 121, 107, 121, 167, 151, 183, 140, 151, 183, 140,
+ // coeff_abs_level_greater1_flag
+ 154, 196, 196, 167, 154, 152, 167, 182, 182, 134, 149, 136, 153, 121,
+ 136, 137, 169, 194, 166, 167, 154, 167, 137, 182,
+ // coeff_abs_level_greater2_flag
+ 107, 167, 91, 122, 107, 167, },
+ { // sao_merge_flag
+ 153,
+ // sao_type_idx
+ 160,
+ // split_coding_unit_flag
+ 107, 139, 126,
+ // cu_transquant_bypass_flag
+ 154,
+ // skip_flag
+ 197, 185, 201,
+ // cu_qp_delta
+ 154, 154, 154,
+ // pred_mode
+ 134,
+ // part_mode
+ 154, 139, 154, 154,
+ // prev_intra_luma_pred_mode
+ 183,
+ // intra_chroma_pred_mode
+ 152, 139,
+ // merge_flag
+ 154,
+ // merge_idx
+ 137,
+ // inter_pred_idc
+ 95, 79, 63, 31, 31,
+ // ref_idx_l0
+ 153, 153,
+ // ref_idx_l1
+ 153, 153,
+ // abs_mvd_greater1_flag
+ 169, 198,
+ // abs_mvd_greater1_flag
+ 169, 198,
+ // mvp_lx_flag
+ 168,
+ // no_residual_data_flag
+ 79,
+ // split_transform_flag
+ 224, 167, 122,
+ // cbf_luma
+ 153, 111,
+ // cbf_cb, cbf_cr
+ 149, 92, 167, 154,
+ // transform_skip_flag
+ 139, 139,
+ // last_significant_coeff_x_prefix
+ 125, 110, 124, 110, 95, 94, 125, 111, 111, 79, 125, 126, 111, 111,
+ 79, 108, 123, 93,
+ // last_significant_coeff_y_prefix
+ 125, 110, 124, 110, 95, 94, 125, 111, 111, 79, 125, 126, 111, 111,
+ 79, 108, 123, 93,
+ // significant_coeff_group_flag
+ 121, 140, 61, 154,
+ // significant_coeff_flag
+ 170, 154, 139, 153, 139, 123, 123, 63, 124, 166, 183, 140, 136, 153,
+ 154, 166, 183, 140, 136, 153, 154, 166, 183, 140, 136, 153, 154, 170,
+ 153, 138, 138, 122, 121, 122, 121, 167, 151, 183, 140, 151, 183, 140,
+ // coeff_abs_level_greater1_flag
+ 154, 196, 167, 167, 154, 152, 167, 182, 182, 134, 149, 136, 153, 121,
+ 136, 122, 169, 208, 166, 167, 154, 152, 167, 182,
+ // coeff_abs_level_greater2_flag
+ 107, 167, 91, 107, 107, 167, },
+};
+
+static const uint8_t scan_1x1[1] = {
+ 0,
+};
+
+static const uint8_t horiz_scan2x2_x[4] = {
+ 0, 1, 0, 1,
+};
+
+static const uint8_t horiz_scan2x2_y[4] = {
+ 0, 0, 1, 1
+};
+
+static const uint8_t horiz_scan4x4_x[16] = {
+ 0, 1, 2, 3,
+ 0, 1, 2, 3,
+ 0, 1, 2, 3,
+ 0, 1, 2, 3,
+};
+
+static const uint8_t horiz_scan4x4_y[16] = {
+ 0, 0, 0, 0,
+ 1, 1, 1, 1,
+ 2, 2, 2, 2,
+ 3, 3, 3, 3,
+};
+
+static const uint8_t horiz_scan8x8_inv[8][8] = {
+ { 0, 1, 2, 3, 16, 17, 18, 19, },
+ { 4, 5, 6, 7, 20, 21, 22, 23, },
+ { 8, 9, 10, 11, 24, 25, 26, 27, },
+ { 12, 13, 14, 15, 28, 29, 30, 31, },
+ { 32, 33, 34, 35, 48, 49, 50, 51, },
+ { 36, 37, 38, 39, 52, 53, 54, 55, },
+ { 40, 41, 42, 43, 56, 57, 58, 59, },
+ { 44, 45, 46, 47, 60, 61, 62, 63, },
+};
+
+static const uint8_t diag_scan4x1_x[4] = {
+ 0, 1, 2, 3,
+};
+
+static const uint8_t diag_scan1x4_y[4] = {
+ 0, 1, 2, 3,
+};
+
+static const uint8_t diag_scan2x2_x[4] = {
+ 0, 0, 1, 1,
+};
+
+static const uint8_t diag_scan2x2_y[4] = {
+ 0, 1, 0, 1,
+};
+
+static const uint8_t diag_scan2x2_inv[2][2] = {
+ { 0, 2, },
+ { 1, 3, },
+};
+
+static const uint8_t diag_scan8x2_x[16] = {
+ 0, 0, 1, 1,
+ 2, 2, 3, 3,
+ 4, 4, 5, 5,
+ 6, 6, 7, 7,
+};
+
+static const uint8_t diag_scan8x2_y[16] = {
+ 0, 1, 0, 1,
+ 0, 1, 0, 1,
+ 0, 1, 0, 1,
+ 0, 1, 0, 1,
+};
+
+static const uint8_t diag_scan8x2_inv[2][8] = {
+ { 0, 2, 4, 6, 8, 10, 12, 14, },
+ { 1, 3, 5, 7, 9, 11, 13, 15, },
+};
+
+static const uint8_t diag_scan2x8_x[16] = {
+ 0, 0, 1, 0,
+ 1, 0, 1, 0,
+ 1, 0, 1, 0,
+ 1, 0, 1, 1,
+};
+
+static const uint8_t diag_scan2x8_y[16] = {
+ 0, 1, 0, 2,
+ 1, 3, 2, 4,
+ 3, 5, 4, 6,
+ 5, 7, 6, 7,
+};
+
+static const uint8_t diag_scan2x8_inv[8][2] = {
+ { 0, 2, },
+ { 1, 4, },
+ { 3, 6, },
+ { 5, 8, },
+ { 7, 10, },
+ { 9, 12, },
+ { 11, 14, },
+ { 13, 15, },
+};
+
+const uint8_t ff_hevc_diag_scan4x4_x[16] = {
+ 0, 0, 1, 0,
+ 1, 2, 0, 1,
+ 2, 3, 1, 2,
+ 3, 2, 3, 3,
+};
+
+const uint8_t ff_hevc_diag_scan4x4_y[16] = {
+ 0, 1, 0, 2,
+ 1, 0, 3, 2,
+ 1, 0, 3, 2,
+ 1, 3, 2, 3,
+};
+
+static const uint8_t diag_scan4x4_inv[4][4] = {
+ { 0, 2, 5, 9, },
+ { 1, 4, 8, 12, },
+ { 3, 7, 11, 14, },
+ { 6, 10, 13, 15, },
+};
+
+const uint8_t ff_hevc_diag_scan8x8_x[64] = {
+ 0, 0, 1, 0,
+ 1, 2, 0, 1,
+ 2, 3, 0, 1,
+ 2, 3, 4, 0,
+ 1, 2, 3, 4,
+ 5, 0, 1, 2,
+ 3, 4, 5, 6,
+ 0, 1, 2, 3,
+ 4, 5, 6, 7,
+ 1, 2, 3, 4,
+ 5, 6, 7, 2,
+ 3, 4, 5, 6,
+ 7, 3, 4, 5,
+ 6, 7, 4, 5,
+ 6, 7, 5, 6,
+ 7, 6, 7, 7,
+};
+
+const uint8_t ff_hevc_diag_scan8x8_y[64] = {
+ 0, 1, 0, 2,
+ 1, 0, 3, 2,
+ 1, 0, 4, 3,
+ 2, 1, 0, 5,
+ 4, 3, 2, 1,
+ 0, 6, 5, 4,
+ 3, 2, 1, 0,
+ 7, 6, 5, 4,
+ 3, 2, 1, 0,
+ 7, 6, 5, 4,
+ 3, 2, 1, 7,
+ 6, 5, 4, 3,
+ 2, 7, 6, 5,
+ 4, 3, 7, 6,
+ 5, 4, 7, 6,
+ 5, 7, 6, 7,
+};
+
+static const uint8_t diag_scan8x8_inv[8][8] = {
+ { 0, 2, 5, 9, 14, 20, 27, 35, },
+ { 1, 4, 8, 13, 19, 26, 34, 42, },
+ { 3, 7, 12, 18, 25, 33, 41, 48, },
+ { 6, 11, 17, 24, 32, 40, 47, 53, },
+ { 10, 16, 23, 31, 39, 46, 52, 57, },
+ { 15, 22, 30, 38, 45, 51, 56, 60, },
+ { 21, 29, 37, 44, 50, 55, 59, 62, },
+ { 28, 36, 43, 49, 54, 58, 61, 63, },
+};
+
+void ff_hevc_save_states(HEVCContext *s, int ctb_addr_ts)
+{
+ if (s->pps->entropy_coding_sync_enabled_flag &&
+ (ctb_addr_ts % s->sps->ctb_width == 2 ||
+ (s->sps->ctb_width == 2 &&
+ ctb_addr_ts % s->sps->ctb_width == 0))) {
+ memcpy(s->cabac_state, s->HEVClc->cabac_state, HEVC_CONTEXTS);
+ }
+}
+
+static void load_states(HEVCContext *s)
+{
+ memcpy(s->HEVClc->cabac_state, s->cabac_state, HEVC_CONTEXTS);
+}
+
+static void cabac_reinit(HEVCLocalContext *lc)
+{
+ skip_bytes(&lc->cc, 0);
+}
+
+static void cabac_init_decoder(HEVCContext *s)
+{
+ GetBitContext *gb = &s->HEVClc->gb;
+ skip_bits(gb, 1);
+ align_get_bits(gb);
+ ff_init_cabac_decoder(&s->HEVClc->cc,
+ gb->buffer + get_bits_count(gb) / 8,
+ (get_bits_left(gb) + 7) / 8);
+}
+
+static void cabac_init_state(HEVCContext *s)
+{
+ int init_type = 2 - s->sh.slice_type;
+ int i;
+
+ if (s->sh.cabac_init_flag && s->sh.slice_type != I_SLICE)
+ init_type ^= 3;
+
+ for (i = 0; i < HEVC_CONTEXTS; i++) {
+ int init_value = init_values[init_type][i];
+ int m = (init_value >> 4) * 5 - 45;
+ int n = ((init_value & 15) << 3) - 16;
+ int pre = 2 * (((m * av_clip_c(s->sh.slice_qp, 0, 51)) >> 4) + n) - 127;
+
+ pre ^= pre >> 31;
+ if (pre > 124)
+ pre = 124 + (pre & 1);
+ s->HEVClc->cabac_state[i] = pre;
+ }
+}
+
+void ff_hevc_cabac_init(HEVCContext *s, int ctb_addr_ts)
+{
+ if (ctb_addr_ts == s->pps->ctb_addr_rs_to_ts[s->sh.slice_ctb_addr_rs]) {
+ cabac_init_decoder(s);
+ if (s->sh.dependent_slice_segment_flag == 0 ||
+ (s->pps->tiles_enabled_flag &&
+ s->pps->tile_id[ctb_addr_ts] != s->pps->tile_id[ctb_addr_ts - 1]))
+ cabac_init_state(s);
+
+ if (!s->sh.first_slice_in_pic_flag &&
+ s->pps->entropy_coding_sync_enabled_flag) {
+ if (ctb_addr_ts % s->sps->ctb_width == 0) {
+ if (s->sps->ctb_width == 1)
+ cabac_init_state(s);
+ else if (s->sh.dependent_slice_segment_flag == 1)
+ load_states(s);
+ }
+ }
+ } else {
+ if (s->pps->tiles_enabled_flag &&
+ s->pps->tile_id[ctb_addr_ts] != s->pps->tile_id[ctb_addr_ts - 1]) {
+ if (s->threads_number == 1)
+ cabac_reinit(s->HEVClc);
+ else
+ cabac_init_decoder(s);
+ cabac_init_state(s);
+ }
+ if (s->pps->entropy_coding_sync_enabled_flag) {
+ if (ctb_addr_ts % s->sps->ctb_width == 0) {
+ get_cabac_terminate(&s->HEVClc->cc);
+ if (s->threads_number == 1)
+ cabac_reinit(s->HEVClc);
+ else
+ cabac_init_decoder(s);
+
+ if (s->sps->ctb_width == 1)
+ cabac_init_state(s);
+ else
+ load_states(s);
+ }
+ }
+ }
+}
+
+#define GET_CABAC(ctx) get_cabac(&s->HEVClc->cc, &s->HEVClc->cabac_state[ctx])
+
+int ff_hevc_sao_merge_flag_decode(HEVCContext *s)
+{
+ return GET_CABAC(elem_offset[SAO_MERGE_FLAG]);
+}
+
+int ff_hevc_sao_type_idx_decode(HEVCContext *s)
+{
+ if (!GET_CABAC(elem_offset[SAO_TYPE_IDX]))
+ return 0;
+
+ if (!get_cabac_bypass(&s->HEVClc->cc))
+ return SAO_BAND;
+ return SAO_EDGE;
+}
+
+int ff_hevc_sao_band_position_decode(HEVCContext *s)
+{
+ int i;
+ int value = get_cabac_bypass(&s->HEVClc->cc);
+
+ for (i = 0; i < 4; i++)
+ value = (value << 1) | get_cabac_bypass(&s->HEVClc->cc);
+ return value;
+}
+
+int ff_hevc_sao_offset_abs_decode(HEVCContext *s)
+{
+ int i = 0;
+ int length = (1 << (FFMIN(s->sps->bit_depth, 10) - 5)) - 1;
+
+ while (i < length && get_cabac_bypass(&s->HEVClc->cc))
+ i++;
+ return i;
+}
+
+int ff_hevc_sao_offset_sign_decode(HEVCContext *s)
+{
+ return get_cabac_bypass(&s->HEVClc->cc);
+}
+
+int ff_hevc_sao_eo_class_decode(HEVCContext *s)
+{
+ int ret = get_cabac_bypass(&s->HEVClc->cc) << 1;
+ ret |= get_cabac_bypass(&s->HEVClc->cc);
+ return ret;
+}
+
+int ff_hevc_end_of_slice_flag_decode(HEVCContext *s)
+{
+ return get_cabac_terminate(&s->HEVClc->cc);
+}
+
+int ff_hevc_cu_transquant_bypass_flag_decode(HEVCContext *s)
+{
+ return GET_CABAC(elem_offset[CU_TRANSQUANT_BYPASS_FLAG]);
+}
+
+int ff_hevc_skip_flag_decode(HEVCContext *s, int x0, int y0, int x_cb, int y_cb)
+{
+ int min_cb_width = s->sps->min_cb_width;
+ int inc = 0;
+ int x0b = x0 & ((1 << s->sps->log2_ctb_size) - 1);
+ int y0b = y0 & ((1 << s->sps->log2_ctb_size) - 1);
+
+ if (s->HEVClc->ctb_left_flag || x0b)
+ inc = !!SAMPLE_CTB(s->skip_flag, x_cb - 1, y_cb);
+ if (s->HEVClc->ctb_up_flag || y0b)
+ inc += !!SAMPLE_CTB(s->skip_flag, x_cb, y_cb - 1);
+
+ return GET_CABAC(elem_offset[SKIP_FLAG] + inc);
+}
+
+int ff_hevc_cu_qp_delta_abs(HEVCContext *s)
+{
+ int prefix_val = 0;
+ int suffix_val = 0;
+ int inc = 0;
+
+ while (prefix_val < 5 && GET_CABAC(elem_offset[CU_QP_DELTA] + inc)) {
+ prefix_val++;
+ inc = 1;
+ }
+ if (prefix_val >= 5) {
+ int k = 0;
+ while (k < CABAC_MAX_BIN && get_cabac_bypass(&s->HEVClc->cc)) {
+ suffix_val += 1 << k;
+ k++;
+ }
+ if (k == CABAC_MAX_BIN)
+ av_log(s->avctx, AV_LOG_ERROR, "CABAC_MAX_BIN : %d\n", k);
+
+ while (k--)
+ suffix_val += get_cabac_bypass(&s->HEVClc->cc) << k;
+ }
+ return prefix_val + suffix_val;
+}
+
+int ff_hevc_cu_qp_delta_sign_flag(HEVCContext *s)
+{
+ return get_cabac_bypass(&s->HEVClc->cc);
+}
+
+int ff_hevc_pred_mode_decode(HEVCContext *s)
+{
+ return GET_CABAC(elem_offset[PRED_MODE_FLAG]);
+}
+
+int ff_hevc_split_coding_unit_flag_decode(HEVCContext *s, int ct_depth, int x0, int y0)
+{
+ int inc = 0, depth_left = 0, depth_top = 0;
+ int x0b = x0 & ((1 << s->sps->log2_ctb_size) - 1);
+ int y0b = y0 & ((1 << s->sps->log2_ctb_size) - 1);
+ int x_cb = x0 >> s->sps->log2_min_cb_size;
+ int y_cb = y0 >> s->sps->log2_min_cb_size;
+
+ if (s->HEVClc->ctb_left_flag || x0b)
+ depth_left = s->tab_ct_depth[(y_cb) * s->sps->min_cb_width + x_cb - 1];
+ if (s->HEVClc->ctb_up_flag || y0b)
+ depth_top = s->tab_ct_depth[(y_cb - 1) * s->sps->min_cb_width + x_cb];
+
+ inc += (depth_left > ct_depth);
+ inc += (depth_top > ct_depth);
+
+ return GET_CABAC(elem_offset[SPLIT_CODING_UNIT_FLAG] + inc);
+}
+
+int ff_hevc_part_mode_decode(HEVCContext *s, int log2_cb_size)
+{
+ if (GET_CABAC(elem_offset[PART_MODE])) // 1
+ return PART_2Nx2N;
+ if (log2_cb_size == s->sps->log2_min_cb_size) {
+ if (s->HEVClc->cu.pred_mode == MODE_INTRA) // 0
+ return PART_NxN;
+ if (GET_CABAC(elem_offset[PART_MODE] + 1)) // 01
+ return PART_2NxN;
+ if (log2_cb_size == 3) // 00
+ return PART_Nx2N;
+ if (GET_CABAC(elem_offset[PART_MODE] + 2)) // 001
+ return PART_Nx2N;
+ return PART_NxN; // 000
+ }
+
+ if (!s->sps->amp_enabled_flag) {
+ if (GET_CABAC(elem_offset[PART_MODE] + 1)) // 01
+ return PART_2NxN;
+ return PART_Nx2N;
+ }
+
+ if (GET_CABAC(elem_offset[PART_MODE] + 1)) { // 01X, 01XX
+ if (GET_CABAC(elem_offset[PART_MODE] + 3)) // 011
+ return PART_2NxN;
+ if (get_cabac_bypass(&s->HEVClc->cc)) // 0101
+ return PART_2NxnD;
+ return PART_2NxnU; // 0100
+ }
+
+ if (GET_CABAC(elem_offset[PART_MODE] + 3)) // 001
+ return PART_Nx2N;
+ if (get_cabac_bypass(&s->HEVClc->cc)) // 0001
+ return PART_nRx2N;
+ return PART_nLx2N; // 0000
+}
+
+int ff_hevc_pcm_flag_decode(HEVCContext *s)
+{
+ return get_cabac_terminate(&s->HEVClc->cc);
+}
+
+int ff_hevc_prev_intra_luma_pred_flag_decode(HEVCContext *s)
+{
+ return GET_CABAC(elem_offset[PREV_INTRA_LUMA_PRED_FLAG]);
+}
+
+int ff_hevc_mpm_idx_decode(HEVCContext *s)
+{
+ int i = 0;
+ while (i < 2 && get_cabac_bypass(&s->HEVClc->cc))
+ i++;
+ return i;
+}
+
+int ff_hevc_rem_intra_luma_pred_mode_decode(HEVCContext *s)
+{
+ int i;
+ int value = get_cabac_bypass(&s->HEVClc->cc);
+
+ for (i = 0; i < 4; i++)
+ value = (value << 1) | get_cabac_bypass(&s->HEVClc->cc);
+ return value;
+}
+
+int ff_hevc_intra_chroma_pred_mode_decode(HEVCContext *s)
+{
+ int ret;
+ if (!GET_CABAC(elem_offset[INTRA_CHROMA_PRED_MODE]))
+ return 4;
+
+ ret = get_cabac_bypass(&s->HEVClc->cc) << 1;
+ ret |= get_cabac_bypass(&s->HEVClc->cc);
+ return ret;
+}
+
+int ff_hevc_merge_idx_decode(HEVCContext *s)
+{
+ int i = GET_CABAC(elem_offset[MERGE_IDX]);
+
+ if (i != 0) {
+ while (i < s->sh.max_num_merge_cand-1 && get_cabac_bypass(&s->HEVClc->cc))
+ i++;
+ }
+ return i;
+}
+
+int ff_hevc_merge_flag_decode(HEVCContext *s)
+{
+ return GET_CABAC(elem_offset[MERGE_FLAG]);
+}
+
+int ff_hevc_inter_pred_idc_decode(HEVCContext *s, int nPbW, int nPbH)
+{
+ if (nPbW + nPbH == 12)
+ return GET_CABAC(elem_offset[INTER_PRED_IDC] + 4);
+ if (GET_CABAC(elem_offset[INTER_PRED_IDC] + s->HEVClc->ct.depth))
+ return PRED_BI;
+
+ return GET_CABAC(elem_offset[INTER_PRED_IDC] + 4);
+}
+
+int ff_hevc_ref_idx_lx_decode(HEVCContext *s, int num_ref_idx_lx)
+{
+ int i = 0;
+ int max = num_ref_idx_lx - 1;
+ int max_ctx = FFMIN(max, 2);
+
+ while (i < max_ctx && GET_CABAC(elem_offset[REF_IDX_L0] + i))
+ i++;
+ if (i == 2) {
+ while (i < max && get_cabac_bypass(&s->HEVClc->cc))
+ i++;
+ }
+
+ return i;
+}
+
+int ff_hevc_mvp_lx_flag_decode(HEVCContext *s)
+{
+ return GET_CABAC(elem_offset[MVP_LX_FLAG]);
+}
+
+int ff_hevc_no_residual_syntax_flag_decode(HEVCContext *s)
+{
+ return GET_CABAC(elem_offset[NO_RESIDUAL_DATA_FLAG]);
+}
+
+static av_always_inline int abs_mvd_greater0_flag_decode(HEVCContext *s)
+{
+ return GET_CABAC(elem_offset[ABS_MVD_GREATER0_FLAG]);
+}
+
+static av_always_inline int abs_mvd_greater1_flag_decode(HEVCContext *s)
+{
+ return GET_CABAC(elem_offset[ABS_MVD_GREATER1_FLAG] + 1);
+}
+
+static av_always_inline int mvd_decode(HEVCContext *s)
+{
+ int ret = 2;
+ int k = 1;
+
+ while (k < CABAC_MAX_BIN && get_cabac_bypass(&s->HEVClc->cc)) {
+ ret += 1 << k;
+ k++;
+ }
+ if (k == CABAC_MAX_BIN)
+ av_log(s->avctx, AV_LOG_ERROR, "CABAC_MAX_BIN : %d\n", k);
+ while (k--)
+ ret += get_cabac_bypass(&s->HEVClc->cc) << k;
+ return get_cabac_bypass_sign(&s->HEVClc->cc, -ret);
+}
+
+static av_always_inline int mvd_sign_flag_decode(HEVCContext *s)
+{
+ return get_cabac_bypass_sign(&s->HEVClc->cc, -1);
+}
+
+int ff_hevc_split_transform_flag_decode(HEVCContext *s, int log2_trafo_size)
+{
+ return GET_CABAC(elem_offset[SPLIT_TRANSFORM_FLAG] + 5 - log2_trafo_size);
+}
+
+int ff_hevc_cbf_cb_cr_decode(HEVCContext *s, int trafo_depth)
+{
+ return GET_CABAC(elem_offset[CBF_CB_CR] + trafo_depth);
+}
+
+int ff_hevc_cbf_luma_decode(HEVCContext *s, int trafo_depth)
+{
+ return GET_CABAC(elem_offset[CBF_LUMA] + !trafo_depth);
+}
+
+int ff_hevc_transform_skip_flag_decode(HEVCContext *s, int c_idx)
+{
+ return GET_CABAC(elem_offset[TRANSFORM_SKIP_FLAG] + !!c_idx);
+}
+
+#define LAST_SIG_COEFF(elem) \
+ int i = 0; \
+ int max = (log2_size << 1) - 1; \
+ int ctx_offset, ctx_shift; \
+ \
+ if (c_idx == 0) { \
+ ctx_offset = 3 * (log2_size - 2) + ((log2_size - 1) >> 2); \
+ ctx_shift = (log2_size + 1) >> 2; \
+ } else { \
+ ctx_offset = 15; \
+ ctx_shift = log2_size - 2; \
+ } \
+ while (i < max && \
+ GET_CABAC(elem_offset[elem] + (i >> ctx_shift) + ctx_offset)) \
+ i++; \
+ return i;
+
+static av_always_inline int last_significant_coeff_x_prefix_decode(HEVCContext *s, int c_idx,
+ int log2_size)
+{
+ LAST_SIG_COEFF(LAST_SIGNIFICANT_COEFF_X_PREFIX)
+}
+
+static av_always_inline int last_significant_coeff_y_prefix_decode(HEVCContext *s, int c_idx,
+ int log2_size)
+{
+ LAST_SIG_COEFF(LAST_SIGNIFICANT_COEFF_Y_PREFIX)
+}
+
+static av_always_inline int last_significant_coeff_suffix_decode(HEVCContext *s,
+ int last_significant_coeff_prefix)
+{
+ int i;
+ int length = (last_significant_coeff_prefix >> 1) - 1;
+ int value = get_cabac_bypass(&s->HEVClc->cc);
+
+ for (i = 1; i < length; i++)
+ value = (value << 1) | get_cabac_bypass(&s->HEVClc->cc);
+ return value;
+}
+
+static av_always_inline int significant_coeff_group_flag_decode(HEVCContext *s, int c_idx, int ctx_cg)
+{
+ int inc;
+
+ inc = FFMIN(ctx_cg, 1) + (c_idx>0 ? 2 : 0);
+
+ return GET_CABAC(elem_offset[SIGNIFICANT_COEFF_GROUP_FLAG] + inc);
+}
+
+static av_always_inline int significant_coeff_flag_decode(HEVCContext *s, int c_idx, int x_c, int y_c,
+ int log2_trafo_size, int scan_idx, int prev_sig)
+{
+ static const uint8_t ctx_idx_map[] = {
+ 0, 1, 4, 5, 2, 3, 4, 5, 6, 6, 8, 8, 7, 7, 8, 8
+ };
+ int x_cg = x_c >> 2;
+ int y_cg = y_c >> 2;
+ int sig_ctx;
+ int inc;
+
+ if (x_c + y_c == 0) {
+ sig_ctx = 0;
+ } else if (log2_trafo_size == 2) {
+ sig_ctx = ctx_idx_map[(y_c << 2) + x_c];
+ } else {
+ switch (prev_sig) {
+ case 0: {
+ int x_off = x_c & 3;
+ int y_off = y_c & 3;
+ sig_ctx = ((x_off + y_off) == 0) ? 2 : ((x_off + y_off) <= 2) ? 1 : 0;
+ }
+ break;
+ case 1:
+ sig_ctx = 2 - FFMIN(y_c & 3, 2);
+ break;
+ case 2:
+ sig_ctx = 2 - FFMIN(x_c & 3, 2);
+ break;
+ default:
+ sig_ctx = 2;
+ }
+
+ if (c_idx == 0 && (x_cg > 0 || y_cg > 0))
+ sig_ctx += 3;
+
+ if (log2_trafo_size == 3) {
+ sig_ctx += (scan_idx == SCAN_DIAG) ? 9 : 15;
+ } else {
+ sig_ctx += c_idx ? 12 : 21;
+ }
+ }
+
+ if (c_idx == 0)
+ inc = sig_ctx;
+ else
+ inc = sig_ctx + 27;
+
+ return GET_CABAC(elem_offset[SIGNIFICANT_COEFF_FLAG] + inc);
+}
+
+static av_always_inline int coeff_abs_level_greater1_flag_decode(HEVCContext *s, int c_idx, int inc)
+{
+
+ if (c_idx > 0)
+ inc += 16;
+
+ return GET_CABAC(elem_offset[COEFF_ABS_LEVEL_GREATER1_FLAG] + inc);
+}
+
+static av_always_inline int coeff_abs_level_greater2_flag_decode(HEVCContext *s, int c_idx, int inc)
+{
+ if (c_idx > 0)
+ inc += 4;
+
+ return GET_CABAC(elem_offset[COEFF_ABS_LEVEL_GREATER2_FLAG] + inc);
+}
+
+static av_always_inline int coeff_abs_level_remaining_decode(HEVCContext *s, int base_level, int rc_rice_param)
+{
+ int prefix = 0;
+ int suffix = 0;
+ int last_coeff_abs_level_remaining;
+ int i;
+
+ while (prefix < CABAC_MAX_BIN && get_cabac_bypass(&s->HEVClc->cc))
+ prefix++;
+ if (prefix == CABAC_MAX_BIN)
+ av_log(s->avctx, AV_LOG_ERROR, "CABAC_MAX_BIN : %d\n", prefix);
+ if (prefix < 3) {
+ for (i = 0; i < rc_rice_param; i++)
+ suffix = (suffix << 1) | get_cabac_bypass(&s->HEVClc->cc);
+ last_coeff_abs_level_remaining = (prefix << rc_rice_param) + suffix;
+ } else {
+ int prefix_minus3 = prefix - 3;
+ for (i = 0; i < prefix_minus3 + rc_rice_param; i++)
+ suffix = (suffix << 1) | get_cabac_bypass(&s->HEVClc->cc);
+ last_coeff_abs_level_remaining = (((1 << prefix_minus3) + 3 - 1)
+ << rc_rice_param) + suffix;
+ }
+ return last_coeff_abs_level_remaining;
+}
+
+static av_always_inline int coeff_sign_flag_decode(HEVCContext *s, uint8_t nb)
+{
+ int i;
+ int ret = 0;
+
+ for (i = 0; i < nb; i++)
+ ret = (ret << 1) | get_cabac_bypass(&s->HEVClc->cc);
+ return ret;
+}
+
+void ff_hevc_hls_residual_coding(HEVCContext *s, int x0, int y0,
+ int log2_trafo_size, enum ScanType scan_idx,
+ int c_idx)
+{
+#define GET_COORD(offset, n) \
+ do { \
+ x_c = (scan_x_cg[offset >> 4] << 2) + scan_x_off[n]; \
+ y_c = (scan_y_cg[offset >> 4] << 2) + scan_y_off[n]; \
+ } while (0)
+ HEVCLocalContext *lc = s->HEVClc;
+ int transform_skip_flag = 0;
+
+ int last_significant_coeff_x, last_significant_coeff_y;
+ int last_scan_pos;
+ int n_end;
+ int num_coeff = 0;
+ int greater1_ctx = 1;
+
+ int num_last_subset;
+ int x_cg_last_sig, y_cg_last_sig;
+
+ const uint8_t *scan_x_cg, *scan_y_cg, *scan_x_off, *scan_y_off;
+
+ ptrdiff_t stride = s->frame->linesize[c_idx];
+ int hshift = s->sps->hshift[c_idx];
+ int vshift = s->sps->vshift[c_idx];
+ uint8_t *dst = &s->frame->data[c_idx][(y0 >> vshift) * stride +
+ ((x0 >> hshift) << s->sps->pixel_shift)];
+ DECLARE_ALIGNED(16, int16_t, coeffs[MAX_TB_SIZE * MAX_TB_SIZE]) = {0};
+ DECLARE_ALIGNED(8, uint8_t, significant_coeff_group_flag[8][8]) = {{0}};
+
+ int trafo_size = 1 << log2_trafo_size;
+ int i;
+ int qp,shift,add,scale,scale_m;
+ const uint8_t level_scale[] = { 40, 45, 51, 57, 64, 72 };
+ const uint8_t *scale_matrix;
+ uint8_t dc_scale;
+
+ // Derive QP for dequant
+ if (!lc->cu.cu_transquant_bypass_flag) {
+ static const int qp_c[] = { 29, 30, 31, 32, 33, 33, 34, 34, 35, 35, 36, 36, 37, 37 };
+ static const uint8_t rem6[51 + 2 * 6 + 1] = {
+ 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2,
+ 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5,
+ 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3,
+ };
+
+ static const uint8_t div6[51 + 2 * 6 + 1] = {
+ 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3,
+ 3, 3, 3, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6,
+ 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10,
+ };
+ int qp_y = lc->qp_y;
+
+ if (c_idx == 0) {
+ qp = qp_y + s->sps->qp_bd_offset;
+ } else {
+ int qp_i, offset;
+
+ if (c_idx == 1)
+ offset = s->pps->cb_qp_offset + s->sh.slice_cb_qp_offset;
+ else
+ offset = s->pps->cr_qp_offset + s->sh.slice_cr_qp_offset;
+
+ qp_i = av_clip_c(qp_y + offset, - s->sps->qp_bd_offset, 57);
+ if (qp_i < 30)
+ qp = qp_i;
+ else if (qp_i > 43)
+ qp = qp_i - 6;
+ else
+ qp = qp_c[qp_i - 30];
+
+ qp += s->sps->qp_bd_offset;
+ }
+
+ shift = s->sps->bit_depth + log2_trafo_size - 5;
+ add = 1 << (shift-1);
+ scale = level_scale[rem6[qp]] << (div6[qp]);
+ scale_m = 16; // default when no custom scaling lists.
+ dc_scale = 16;
+
+ if (s->sps->scaling_list_enable_flag) {
+ const ScalingList *sl = s->pps->scaling_list_data_present_flag ?
+ &s->pps->scaling_list : &s->sps->scaling_list;
+ int matrix_id = lc->cu.pred_mode != MODE_INTRA;
+
+ if (log2_trafo_size != 5)
+ matrix_id = 3 * matrix_id + c_idx;
+
+ scale_matrix = sl->sl[log2_trafo_size - 2][matrix_id];
+ if (log2_trafo_size >= 4)
+ dc_scale = sl->sl_dc[log2_trafo_size - 4][matrix_id];
+ }
+ }
+
+ if (s->pps->transform_skip_enabled_flag && !lc->cu.cu_transquant_bypass_flag &&
+ log2_trafo_size == 2) {
+ transform_skip_flag = ff_hevc_transform_skip_flag_decode(s, c_idx);
+ }
+
+ last_significant_coeff_x =
+ last_significant_coeff_x_prefix_decode(s, c_idx, log2_trafo_size);
+ last_significant_coeff_y =
+ last_significant_coeff_y_prefix_decode(s, c_idx, log2_trafo_size);
+
+ if (last_significant_coeff_x > 3) {
+ int suffix = last_significant_coeff_suffix_decode(s, last_significant_coeff_x);
+ last_significant_coeff_x = (1 << ((last_significant_coeff_x >> 1) - 1)) *
+ (2 + (last_significant_coeff_x & 1)) +
+ suffix;
+ }
+
+ if (last_significant_coeff_y > 3) {
+ int suffix = last_significant_coeff_suffix_decode(s, last_significant_coeff_y);
+ last_significant_coeff_y = (1 << ((last_significant_coeff_y >> 1) - 1)) *
+ (2 + (last_significant_coeff_y & 1)) +
+ suffix;
+ }
+
+ if (scan_idx == SCAN_VERT)
+ FFSWAP(int, last_significant_coeff_x, last_significant_coeff_y);
+
+ x_cg_last_sig = last_significant_coeff_x >> 2;
+ y_cg_last_sig = last_significant_coeff_y >> 2;
+
+ switch (scan_idx) {
+ case SCAN_DIAG: {
+ int last_x_c = last_significant_coeff_x & 3;
+ int last_y_c = last_significant_coeff_y & 3;
+
+ scan_x_off = ff_hevc_diag_scan4x4_x;
+ scan_y_off = ff_hevc_diag_scan4x4_y;
+ num_coeff = diag_scan4x4_inv[last_y_c][last_x_c];
+ if (trafo_size == 4) {
+ scan_x_cg = scan_1x1;
+ scan_y_cg = scan_1x1;
+ } else if (trafo_size == 8) {
+ num_coeff += diag_scan2x2_inv[y_cg_last_sig][x_cg_last_sig] << 4;
+ scan_x_cg = diag_scan2x2_x;
+ scan_y_cg = diag_scan2x2_y;
+ } else if (trafo_size == 16) {
+ num_coeff += diag_scan4x4_inv[y_cg_last_sig][x_cg_last_sig] << 4;
+ scan_x_cg = ff_hevc_diag_scan4x4_x;
+ scan_y_cg = ff_hevc_diag_scan4x4_y;
+ } else { // trafo_size == 32
+ num_coeff += diag_scan8x8_inv[y_cg_last_sig][x_cg_last_sig] << 4;
+ scan_x_cg = ff_hevc_diag_scan8x8_x;
+ scan_y_cg = ff_hevc_diag_scan8x8_y;
+ }
+ break;
+ }
+ case SCAN_HORIZ:
+ scan_x_cg = horiz_scan2x2_x;
+ scan_y_cg = horiz_scan2x2_y;
+ scan_x_off = horiz_scan4x4_x;
+ scan_y_off = horiz_scan4x4_y;
+ num_coeff = horiz_scan8x8_inv[last_significant_coeff_y][last_significant_coeff_x];
+ break;
+ default: //SCAN_VERT
+ scan_x_cg = horiz_scan2x2_y;
+ scan_y_cg = horiz_scan2x2_x;
+ scan_x_off = horiz_scan4x4_y;
+ scan_y_off = horiz_scan4x4_x;
+ num_coeff = horiz_scan8x8_inv[last_significant_coeff_x][last_significant_coeff_y];
+ break;
+ }
+ num_coeff++;
+ num_last_subset = (num_coeff - 1) >> 4;
+
+ for (i = num_last_subset; i >= 0; i--) {
+ int n, m;
+ int x_cg, y_cg, x_c, y_c, pos;
+ int implicit_non_zero_coeff = 0;
+ int64_t trans_coeff_level;
+ int prev_sig = 0;
+ int offset = i << 4;
+
+ uint8_t significant_coeff_flag_idx[16];
+ uint8_t nb_significant_coeff_flag = 0;
+
+ x_cg = scan_x_cg[i];
+ y_cg = scan_y_cg[i];
+
+ if ((i < num_last_subset) && (i > 0)) {
+ int ctx_cg = 0;
+ if (x_cg < (1 << (log2_trafo_size - 2)) - 1)
+ ctx_cg += significant_coeff_group_flag[x_cg + 1][y_cg];
+ if (y_cg < (1 << (log2_trafo_size - 2)) - 1)
+ ctx_cg += significant_coeff_group_flag[x_cg][y_cg + 1];
+
+ significant_coeff_group_flag[x_cg][y_cg] =
+ significant_coeff_group_flag_decode(s, c_idx, ctx_cg);
+ implicit_non_zero_coeff = 1;
+ } else {
+ significant_coeff_group_flag[x_cg][y_cg] =
+ ((x_cg == x_cg_last_sig && y_cg == y_cg_last_sig) ||
+ (x_cg == 0 && y_cg == 0));
+ }
+
+ last_scan_pos = num_coeff - offset - 1;
+
+ if (i == num_last_subset) {
+ n_end = last_scan_pos - 1;
+ significant_coeff_flag_idx[0] = last_scan_pos;
+ nb_significant_coeff_flag = 1;
+ } else {
+ n_end = 15;
+ }
+
+ if (x_cg < ((1 << log2_trafo_size) - 1) >> 2)
+ prev_sig = significant_coeff_group_flag[x_cg + 1][y_cg];
+ if (y_cg < ((1 << log2_trafo_size) - 1) >> 2)
+ prev_sig += (significant_coeff_group_flag[x_cg][y_cg + 1] << 1);
+
+ for (n = n_end; n >= 0; n--) {
+ GET_COORD(offset, n);
+
+ if (significant_coeff_group_flag[x_cg][y_cg] &&
+ (n > 0 || implicit_non_zero_coeff == 0)) {
+ if (significant_coeff_flag_decode(s, c_idx, x_c, y_c, log2_trafo_size, scan_idx, prev_sig) == 1) {
+ significant_coeff_flag_idx[nb_significant_coeff_flag] = n;
+ nb_significant_coeff_flag++;
+ implicit_non_zero_coeff = 0;
+ }
+ } else {
+ int last_cg = (x_c == (x_cg << 2) && y_c == (y_cg << 2));
+ if (last_cg && implicit_non_zero_coeff && significant_coeff_group_flag[x_cg][y_cg]) {
+ significant_coeff_flag_idx[nb_significant_coeff_flag] = n;
+ nb_significant_coeff_flag++;
+ }
+ }
+ }
+
+ n_end = nb_significant_coeff_flag;
+
+
+ if (n_end) {
+ int first_nz_pos_in_cg = 16;
+ int last_nz_pos_in_cg = -1;
+ int c_rice_param = 0;
+ int first_greater1_coeff_idx = -1;
+ uint8_t coeff_abs_level_greater1_flag[16] = {0};
+ uint16_t coeff_sign_flag;
+ int sum_abs = 0;
+ int sign_hidden = 0;
+
+ // initialize first elem of coeff_bas_level_greater1_flag
+ int ctx_set = (i > 0 && c_idx == 0) ? 2 : 0;
+
+ if (!(i == num_last_subset) && greater1_ctx == 0)
+ ctx_set++;
+ greater1_ctx = 1;
+ last_nz_pos_in_cg = significant_coeff_flag_idx[0];
+
+ for (m = 0; m < (n_end > 8 ? 8 : n_end); m++) {
+ int n_idx = significant_coeff_flag_idx[m];
+ int inc = (ctx_set << 2) + greater1_ctx;
+ coeff_abs_level_greater1_flag[n_idx] =
+ coeff_abs_level_greater1_flag_decode(s, c_idx, inc);
+ if (coeff_abs_level_greater1_flag[n_idx]) {
+ greater1_ctx = 0;
+ } else if (greater1_ctx > 0 && greater1_ctx < 3) {
+ greater1_ctx++;
+ }
+
+ if (coeff_abs_level_greater1_flag[n_idx] &&
+ first_greater1_coeff_idx == -1)
+ first_greater1_coeff_idx = n_idx;
+ }
+ first_nz_pos_in_cg = significant_coeff_flag_idx[n_end - 1];
+ sign_hidden = (last_nz_pos_in_cg - first_nz_pos_in_cg >= 4 &&
+ !lc->cu.cu_transquant_bypass_flag);
+
+ if (first_greater1_coeff_idx != -1) {
+ coeff_abs_level_greater1_flag[first_greater1_coeff_idx] += coeff_abs_level_greater2_flag_decode(s, c_idx, ctx_set);
+ }
+ if (!s->pps->sign_data_hiding_flag || !sign_hidden ) {
+ coeff_sign_flag = coeff_sign_flag_decode(s, nb_significant_coeff_flag) << (16 - nb_significant_coeff_flag);
+ } else {
+ coeff_sign_flag = coeff_sign_flag_decode(s, nb_significant_coeff_flag - 1) << (16 - (nb_significant_coeff_flag - 1));
+ }
+
+ for (m = 0; m < n_end; m++) {
+ n = significant_coeff_flag_idx[m];
+ GET_COORD(offset, n);
+ trans_coeff_level = 1 + coeff_abs_level_greater1_flag[n];
+ if (trans_coeff_level == ((m < 8) ?
+ ((n == first_greater1_coeff_idx) ? 3 : 2) : 1)) {
+ int last_coeff_abs_level_remaining = coeff_abs_level_remaining_decode(s, trans_coeff_level, c_rice_param);
+
+ trans_coeff_level += last_coeff_abs_level_remaining;
+ if (trans_coeff_level > (3 << c_rice_param))
+ c_rice_param = FFMIN(c_rice_param + 1, 4);
+
+ }
+ if (s->pps->sign_data_hiding_flag && sign_hidden) {
+ sum_abs += trans_coeff_level;
+ if (n == first_nz_pos_in_cg && (sum_abs&1))
+ trans_coeff_level = -trans_coeff_level;
+ }
+ if (coeff_sign_flag >> 15)
+ trans_coeff_level = -trans_coeff_level;
+ coeff_sign_flag <<= 1;
+ if(!lc->cu.cu_transquant_bypass_flag) {
+ if(s->sps->scaling_list_enable_flag) {
+ if(y_c || x_c || log2_trafo_size < 4) {
+ switch(log2_trafo_size) {
+ case 3: pos = (y_c << 3) + x_c; break;
+ case 4: pos = ((y_c >> 1) << 3) + (x_c >> 1); break;
+ case 5: pos = ((y_c >> 2) << 3) + (x_c >> 2); break;
+ default: pos = (y_c << 2) + x_c;
+ }
+ scale_m = scale_matrix[pos];
+ } else {
+ scale_m = dc_scale;
+ }
+ }
+ trans_coeff_level = (trans_coeff_level * (int64_t)scale * (int64_t)scale_m + add) >> shift;
+ if(trans_coeff_level < 0) {
+ if((~trans_coeff_level) & 0xFffffffffff8000)
+ trans_coeff_level = -32768;
+ } else {
+ if(trans_coeff_level & 0xffffffffffff8000)
+ trans_coeff_level = 32767;
+ }
+ }
+ coeffs[y_c * trafo_size + x_c] = trans_coeff_level;
+ }
+ }
+ }
+
+ if (lc->cu.cu_transquant_bypass_flag) {
+ s->hevcdsp.transquant_bypass[log2_trafo_size-2](dst, coeffs, stride);
+ } else {
+ if (transform_skip_flag)
+ s->hevcdsp.transform_skip(dst, coeffs, stride);
+ else if (lc->cu.pred_mode == MODE_INTRA && c_idx == 0 && log2_trafo_size == 2)
+ s->hevcdsp.transform_4x4_luma_add(dst, coeffs, stride);
+ else
+ s->hevcdsp.transform_add[log2_trafo_size-2](dst, coeffs, stride);
+ }
+}
+
+void ff_hevc_hls_mvd_coding(HEVCContext *s, int x0, int y0, int log2_cb_size)
+{
+ HEVCLocalContext *lc = s->HEVClc;
+ int x = abs_mvd_greater0_flag_decode(s);
+ int y = abs_mvd_greater0_flag_decode(s);
+
+ if (x)
+ x += abs_mvd_greater1_flag_decode(s);
+ if (y)
+ y += abs_mvd_greater1_flag_decode(s);
+
+ switch (x) {
+ case 2: lc->pu.mvd.x = mvd_decode(s); break;
+ case 1: lc->pu.mvd.x = mvd_sign_flag_decode(s); break;
+ case 0: lc->pu.mvd.x = 0; break;
+ }
+
+ switch (y) {
+ case 2: lc->pu.mvd.y = mvd_decode(s); break;
+ case 1: lc->pu.mvd.y = mvd_sign_flag_decode(s); break;
+ case 0: lc->pu.mvd.y = 0; break;
+ }
+}
+
diff --git a/libavcodec/hevc_filter.c b/libavcodec/hevc_filter.c
new file mode 100644
index 0000000..ae72fbb
--- /dev/null
+++ b/libavcodec/hevc_filter.c
@@ -0,0 +1,752 @@
+/*
+ * HEVC video decoder
+ *
+ * Copyright (C) 2012 - 2013 Guillaume Martres
+ * Copyright (C) 2013 Seppo Tomperi
+ * Copyright (C) 2013 Wassim Hamidouche
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "libavutil/common.h"
+#include "libavutil/internal.h"
+
+#include "cabac_functions.h"
+#include "golomb.h"
+#include "hevc.h"
+
+#include "bit_depth_template.c"
+
+#define LUMA 0
+#define CB 1
+#define CR 2
+
+static const uint8_t tctable[54] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, // QP 0...18
+ 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, // QP 19...37
+ 5, 5, 6, 6, 7, 8, 9, 10, 11, 13, 14, 16, 18, 20, 22, 24 // QP 38...53
+};
+
+static const uint8_t betatable[52] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7, 8, // QP 0...18
+ 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, // QP 19...37
+ 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64 // QP 38...51
+};
+
+static int chroma_tc(HEVCContext *s, int qp_y, int c_idx, int tc_offset)
+{
+ static const int qp_c[] = {
+ 29, 30, 31, 32, 33, 33, 34, 34, 35, 35, 36, 36, 37, 37
+ };
+ int qp, qp_i, offset, idxt;
+
+ // slice qp offset is not used for deblocking
+ if (c_idx == 1)
+ offset = s->pps->cb_qp_offset;
+ else
+ offset = s->pps->cr_qp_offset;
+
+ qp_i = av_clip_c(qp_y + offset, 0, 57);
+ if (qp_i < 30)
+ qp = qp_i;
+ else if (qp_i > 43)
+ qp = qp_i - 6;
+ else
+ qp = qp_c[qp_i - 30];
+
+ idxt = av_clip_c(qp + DEFAULT_INTRA_TC_OFFSET + tc_offset, 0, 53);
+ return tctable[idxt];
+}
+
+static int get_qPy_pred(HEVCContext *s, int xC, int yC,
+ int xBase, int yBase, int log2_cb_size)
+{
+ HEVCLocalContext *lc = s->HEVClc;
+ int ctb_size_mask = (1 << s->sps->log2_ctb_size) - 1;
+ int MinCuQpDeltaSizeMask = (1 << (s->sps->log2_ctb_size -
+ s->pps->diff_cu_qp_delta_depth)) - 1;
+ int xQgBase = xBase - (xBase & MinCuQpDeltaSizeMask);
+ int yQgBase = yBase - (yBase & MinCuQpDeltaSizeMask);
+ int min_cb_width = s->sps->min_cb_width;
+ int min_cb_height = s->sps->min_cb_height;
+ int x_cb = xQgBase >> s->sps->log2_min_cb_size;
+ int y_cb = yQgBase >> s->sps->log2_min_cb_size;
+ int availableA = (xBase & ctb_size_mask) &&
+ (xQgBase & ctb_size_mask);
+ int availableB = (yBase & ctb_size_mask) &&
+ (yQgBase & ctb_size_mask);
+ int qPy_pred, qPy_a, qPy_b;
+
+ // qPy_pred
+ if (lc->first_qp_group) {
+ lc->first_qp_group = !lc->tu.is_cu_qp_delta_coded;
+ qPy_pred = s->sh.slice_qp;
+ } else {
+ qPy_pred = lc->qp_y;
+ if (log2_cb_size < s->sps->log2_ctb_size -
+ s->pps->diff_cu_qp_delta_depth) {
+ static const int offsetX[8][8] = {
+ { -1, 1, 3, 1, 7, 1, 3, 1 },
+ { 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 1, 3, 1, 3, 1, 3, 1, 3 },
+ { 2, 2, 2, 2, 2, 2, 2, 2 },
+ { 3, 5, 7, 5, 3, 5, 7, 5 },
+ { 4, 4, 4, 4, 4, 4, 4, 4 },
+ { 5, 7, 5, 7, 5, 7, 5, 7 },
+ { 6, 6, 6, 6, 6, 6, 6, 6 }
+ };
+ static const int offsetY[8][8] = {
+ { 7, 0, 1, 2, 3, 4, 5, 6 },
+ { 0, 1, 2, 3, 4, 5, 6, 7 },
+ { 1, 0, 3, 2, 5, 4, 7, 6 },
+ { 0, 1, 2, 3, 4, 5, 6, 7 },
+ { 3, 0, 1, 2, 7, 4, 5, 6 },
+ { 0, 1, 2, 3, 4, 5, 6, 7 },
+ { 1, 0, 3, 2, 5, 4, 7, 6 },
+ { 0, 1, 2, 3, 4, 5, 6, 7 }
+ };
+ int xC0b = (xC - (xC & ctb_size_mask)) >> s->sps->log2_min_cb_size;
+ int yC0b = (yC - (yC & ctb_size_mask)) >> s->sps->log2_min_cb_size;
+ int idxX = (xQgBase & ctb_size_mask) >> s->sps->log2_min_cb_size;
+ int idxY = (yQgBase & ctb_size_mask) >> s->sps->log2_min_cb_size;
+ int idx_mask = ctb_size_mask >> s->sps->log2_min_cb_size;
+ int x, y;
+
+ x = FFMIN(xC0b + offsetX[idxX][idxY], min_cb_width - 1);
+ y = FFMIN(yC0b + (offsetY[idxX][idxY] & idx_mask), min_cb_height - 1);
+
+ if (xC0b == (lc->start_of_tiles_x >> s->sps->log2_min_cb_size) &&
+ offsetX[idxX][idxY] == -1) {
+ x = (lc->end_of_tiles_x >> s->sps->log2_min_cb_size) - 1;
+ y = yC0b - 1;
+ }
+ qPy_pred = s->qp_y_tab[y * min_cb_width + x];
+ }
+ }
+
+ // qPy_a
+ if (availableA == 0)
+ qPy_a = qPy_pred;
+ else
+ qPy_a = s->qp_y_tab[(x_cb - 1) + y_cb * min_cb_width];
+
+ // qPy_b
+ if (availableB == 0)
+ qPy_b = qPy_pred;
+ else
+ qPy_b = s->qp_y_tab[x_cb + (y_cb - 1) * min_cb_width];
+
+ return (qPy_a + qPy_b + 1) >> 1;
+}
+
+void ff_hevc_set_qPy(HEVCContext *s, int xC, int yC,
+ int xBase, int yBase, int log2_cb_size)
+{
+ int qp_y = get_qPy_pred(s, xC, yC, xBase, yBase, log2_cb_size);
+
+ if (s->HEVClc->tu.cu_qp_delta != 0) {
+ int off = s->sps->qp_bd_offset;
+ s->HEVClc->qp_y = ((qp_y + s->HEVClc->tu.cu_qp_delta + 52 + 2 * off) %
+ (52 + off)) - off;
+ } else
+ s->HEVClc->qp_y = qp_y;
+}
+
+static int get_qPy(HEVCContext *s, int xC, int yC)
+{
+ int log2_min_cb_size = s->sps->log2_min_cb_size;
+ int x = xC >> log2_min_cb_size;
+ int y = yC >> log2_min_cb_size;
+ return s->qp_y_tab[x + y * s->sps->min_cb_width];
+}
+
+static void copy_CTB(uint8_t *dst, uint8_t *src,
+ int width, int height, int stride)
+{
+ int i;
+
+ for (i = 0; i < height; i++) {
+ memcpy(dst, src, width);
+ dst += stride;
+ src += stride;
+ }
+}
+
+#define CTB(tab, x, y) ((tab)[(y) * s->sps->ctb_width + (x)])
+
+static void sao_filter_CTB(HEVCContext *s, int x, int y)
+{
+ // TODO: This should be easily parallelizable
+ // TODO: skip CBs when (cu_transquant_bypass_flag || (pcm_loop_filter_disable_flag && pcm_flag))
+ int c_idx = 0;
+ int class = 1, class_index;
+ int edges[4]; // 0 left 1 top 2 right 3 bottom
+ SAOParams *sao[4];
+ int classes[4];
+ int x_shift = 0, y_shift = 0;
+ int x_ctb = x >> s->sps->log2_ctb_size;
+ int y_ctb = y >> s->sps->log2_ctb_size;
+ int ctb_addr_rs = y_ctb * s->sps->ctb_width + x_ctb;
+ int ctb_addr_ts = s->pps->ctb_addr_rs_to_ts[ctb_addr_rs];
+
+ // flags indicating unfilterable edges
+ uint8_t vert_edge[] = { 0, 0, 0, 0 };
+ uint8_t horiz_edge[] = { 0, 0, 0, 0 };
+ uint8_t diag_edge[] = { 0, 0, 0, 0 };
+ uint8_t lfase[3]; // current, above, left
+ uint8_t no_tile_filter = s->pps->tiles_enabled_flag &&
+ !s->pps->loop_filter_across_tiles_enabled_flag;
+ uint8_t left_tile_edge = 0;
+ uint8_t up_tile_edge = 0;
+
+ sao[0] = &CTB(s->sao, x_ctb, y_ctb);
+ edges[0] = x_ctb == 0;
+ edges[1] = y_ctb == 0;
+ edges[2] = x_ctb == s->sps->ctb_width - 1;
+ edges[3] = y_ctb == s->sps->ctb_height - 1;
+ lfase[0] = CTB(s->filter_slice_edges, x_ctb, y_ctb);
+ classes[0] = 0;
+
+ if (!edges[0]) {
+ left_tile_edge = no_tile_filter && s->pps->tile_id[ctb_addr_ts] != s->pps->tile_id[s->pps->ctb_addr_rs_to_ts[ctb_addr_rs-1]];
+ sao[class] = &CTB(s->sao, x_ctb - 1, y_ctb);
+ vert_edge[0] = (!lfase[0] && CTB(s->tab_slice_address, x_ctb, y_ctb) != CTB(s->tab_slice_address, x_ctb - 1, y_ctb)) || left_tile_edge;
+ vert_edge[2] = vert_edge[0];
+ lfase[2] = CTB(s->filter_slice_edges, x_ctb - 1, y_ctb);
+ classes[class] = 2;
+ class++;
+ x_shift = 8;
+ }
+
+ if (!edges[1]) {
+ up_tile_edge = no_tile_filter && s->pps->tile_id[ctb_addr_ts] != s->pps->tile_id[s->pps->ctb_addr_rs_to_ts[ctb_addr_rs - s->sps->ctb_width]];
+ sao[class] = &CTB(s->sao, x_ctb, y_ctb - 1);
+ horiz_edge[0] = (!lfase[0] && CTB(s->tab_slice_address, x_ctb, y_ctb) != CTB(s->tab_slice_address, x_ctb, y_ctb - 1)) || up_tile_edge;
+ horiz_edge[1] = horiz_edge[0];
+ lfase[1] = CTB(s->filter_slice_edges, x_ctb, y_ctb - 1);
+ classes[class] = 1;
+ class++;
+ y_shift = 4;
+
+ if (!edges[0]) {
+ classes[class] = 3;
+ sao[class] = &CTB(s->sao, x_ctb - 1, y_ctb - 1);
+ class++;
+
+ // Tile check here is done current CTB row/col, not above/left like you'd expect,
+ //but that is because the tile boundary always extends through the whole pic
+ vert_edge[1] = (!lfase[1] && CTB(s->tab_slice_address, x_ctb, y_ctb - 1) != CTB(s->tab_slice_address, x_ctb - 1, y_ctb - 1)) || left_tile_edge;
+ vert_edge[3] = vert_edge[1];
+ horiz_edge[2] = (!lfase[2] && CTB(s->tab_slice_address, x_ctb - 1, y_ctb) != CTB(s->tab_slice_address, x_ctb - 1, y_ctb - 1)) || up_tile_edge;
+ horiz_edge[3] = horiz_edge[2];
+ diag_edge[0] = (!lfase[0] && CTB(s->tab_slice_address, x_ctb, y_ctb) != CTB(s->tab_slice_address, x_ctb - 1, y_ctb - 1)) || left_tile_edge || up_tile_edge;
+ diag_edge[3] = diag_edge[0];
+
+ // Does left CTB comes after above CTB?
+ if (CTB(s->tab_slice_address, x_ctb - 1, y_ctb) >
+ CTB(s->tab_slice_address, x_ctb, y_ctb - 1)) {
+ diag_edge[2] = !lfase[2] || left_tile_edge || up_tile_edge;
+ diag_edge[1] = diag_edge[2];
+ } else if (CTB(s->tab_slice_address, x_ctb - 1, y_ctb) <
+ CTB(s->tab_slice_address, x_ctb, y_ctb - 1)) {
+ diag_edge[1] = !lfase[1] || left_tile_edge || up_tile_edge;
+ diag_edge[2] = diag_edge[1];
+ } else {
+ // Same slice, only consider tiles
+ diag_edge[2] = left_tile_edge || up_tile_edge;
+ diag_edge[1] = diag_edge[2];
+ }
+ }
+ }
+
+ for (c_idx = 0; c_idx < 3; c_idx++) {
+ int chroma = c_idx ? 1 : 0;
+ int x0 = x >> chroma;
+ int y0 = y >> chroma;
+ int stride = s->frame->linesize[c_idx];
+ int ctb_size = (1 << (s->sps->log2_ctb_size)) >> s->sps->hshift[c_idx];
+ int width = FFMIN(ctb_size,
+ (s->sps->width >> s->sps->hshift[c_idx]) - x0);
+ int height = FFMIN(ctb_size,
+ (s->sps->height >> s->sps->vshift[c_idx]) - y0);
+
+ uint8_t *src = &s->frame->data[c_idx][y0 * stride + (x0 << s->sps->pixel_shift)];
+ uint8_t *dst = &s->sao_frame->data[c_idx][y0 * stride + (x0 << s->sps->pixel_shift)];
+ int offset = (y_shift >> chroma) * stride + ((x_shift >> chroma) << s->sps->pixel_shift);
+
+ copy_CTB(dst - offset, src - offset,
+ (edges[2] ? width + (x_shift >> chroma) : width) << s->sps->pixel_shift,
+ (edges[3] ? height + (y_shift >> chroma) : height), stride);
+
+ for (class_index = 0; class_index < class; class_index++) {
+
+ switch (sao[class_index]->type_idx[c_idx]) {
+ case SAO_BAND:
+ s->hevcdsp.sao_band_filter[classes[class_index]](dst, src,
+ stride,
+ sao[class_index],
+ edges, width,
+ height, c_idx);
+ break;
+ case SAO_EDGE:
+ s->hevcdsp.sao_edge_filter[classes[class_index]](dst, src,
+ stride,
+ sao[class_index],
+ edges, width,
+ height, c_idx,
+ vert_edge[classes[class_index]],
+ horiz_edge[classes[class_index]],
+ diag_edge[classes[class_index]]);
+ break;
+ }
+ }
+ }
+}
+
+static int get_pcm(HEVCContext *s, int x, int y)
+{
+ int log2_min_pu_size = s->sps->log2_min_pu_size;
+ int x_pu = x >> log2_min_pu_size;
+ int y_pu = y >> log2_min_pu_size;
+
+ if (x < 0 || x_pu >= s->sps->min_pu_width ||
+ y < 0 || y_pu >= s->sps->min_pu_height)
+ return 2;
+ return s->is_pcm[y_pu * s->sps->min_pu_width + x_pu];
+}
+
+#define TC_CALC(qp, bs) \
+ tctable[av_clip((qp) + DEFAULT_INTRA_TC_OFFSET * ((bs) - 1) + \
+ (tc_offset >> 1 << 1), \
+ 0, MAX_QP + DEFAULT_INTRA_TC_OFFSET)]
+
+static void deblocking_filter_CTB(HEVCContext *s, int x0, int y0)
+{
+ uint8_t *src;
+ int x, y;
+ int chroma;
+ int c_tc[2], beta[2], tc[2];
+ uint8_t no_p[2] = { 0 };
+ uint8_t no_q[2] = { 0 };
+
+ int log2_ctb_size = s->sps->log2_ctb_size;
+ int x_end, y_end;
+ int ctb_size = 1 << log2_ctb_size;
+ int ctb = (x0 >> log2_ctb_size) +
+ (y0 >> log2_ctb_size) * s->sps->ctb_width;
+ int cur_tc_offset = s->deblock[ctb].tc_offset;
+ int cur_beta_offset = s->deblock[ctb].beta_offset;
+ int left_tc_offset, left_beta_offset;
+ int tc_offset, beta_offset;
+ int pcmf = (s->sps->pcm_enabled_flag &&
+ s->sps->pcm.loop_filter_disable_flag) ||
+ s->pps->transquant_bypass_enable_flag;
+
+ if (x0) {
+ left_tc_offset = s->deblock[ctb - 1].tc_offset;
+ left_beta_offset = s->deblock[ctb - 1].beta_offset;
+ }
+
+ x_end = x0 + ctb_size;
+ if (x_end > s->sps->width)
+ x_end = s->sps->width;
+ y_end = y0 + ctb_size;
+ if (y_end > s->sps->height)
+ y_end = s->sps->height;
+
+ tc_offset = cur_tc_offset;
+ beta_offset = cur_beta_offset;
+
+ // vertical filtering luma
+ for (y = y0; y < y_end; y += 8) {
+ for (x = x0 ? x0 : 8; x < x_end; x += 8) {
+ const int bs0 = s->vertical_bs[(x >> 3) + (y >> 2) * s->bs_width];
+ const int bs1 = s->vertical_bs[(x >> 3) + ((y + 4) >> 2) * s->bs_width];
+ if (bs0 || bs1) {
+ const int qp0 = (get_qPy(s, x - 1, y) + get_qPy(s, x, y) + 1) >> 1;
+ const int qp1 = (get_qPy(s, x - 1, y + 4) + get_qPy(s, x, y + 4) + 1) >> 1;
+
+ beta[0] = betatable[av_clip(qp0 + (beta_offset >> 1 << 1), 0, MAX_QP)];
+ beta[1] = betatable[av_clip(qp1 + (beta_offset >> 1 << 1), 0, MAX_QP)];
+ tc[0] = bs0 ? TC_CALC(qp0, bs0) : 0;
+ tc[1] = bs1 ? TC_CALC(qp1, bs1) : 0;
+ src = &s->frame->data[LUMA][y * s->frame->linesize[LUMA] + (x << s->sps->pixel_shift)];
+ if (pcmf) {
+ no_p[0] = get_pcm(s, x - 1, y);
+ no_p[1] = get_pcm(s, x - 1, y + 4);
+ no_q[0] = get_pcm(s, x, y);
+ no_q[1] = get_pcm(s, x, y + 4);
+ s->hevcdsp.hevc_v_loop_filter_luma_c(src,
+ s->frame->linesize[LUMA],
+ beta, tc, no_p, no_q);
+ } else
+ s->hevcdsp.hevc_v_loop_filter_luma(src,
+ s->frame->linesize[LUMA],
+ beta, tc, no_p, no_q);
+ }
+ }
+ }
+
+ // vertical filtering chroma
+ for (chroma = 1; chroma <= 2; chroma++) {
+ for (y = y0; y < y_end; y += 16) {
+ for (x = x0 ? x0 : 16; x < x_end; x += 16) {
+ const int bs0 = s->vertical_bs[(x >> 3) + (y >> 2) * s->bs_width];
+ const int bs1 = s->vertical_bs[(x >> 3) + ((y + 8) >> 2) * s->bs_width];
+ if ((bs0 == 2) || (bs1 == 2)) {
+ const int qp0 = (get_qPy(s, x - 1, y) + get_qPy(s, x, y) + 1) >> 1;
+ const int qp1 = (get_qPy(s, x - 1, y + 8) + get_qPy(s, x, y + 8) + 1) >> 1;
+
+ c_tc[0] = (bs0 == 2) ? chroma_tc(s, qp0, chroma, tc_offset) : 0;
+ c_tc[1] = (bs1 == 2) ? chroma_tc(s, qp1, chroma, tc_offset) : 0;
+ src = &s->frame->data[chroma][y / 2 * s->frame->linesize[chroma] + ((x / 2) << s->sps->pixel_shift)];
+ if (pcmf) {
+ no_p[0] = get_pcm(s, x - 1, y);
+ no_p[1] = get_pcm(s, x - 1, y + 8);
+ no_q[0] = get_pcm(s, x, y);
+ no_q[1] = get_pcm(s, x, y + 8);
+ s->hevcdsp.hevc_v_loop_filter_chroma_c(src,
+ s->frame->linesize[chroma],
+ c_tc, no_p, no_q);
+ } else
+ s->hevcdsp.hevc_v_loop_filter_chroma(src,
+ s->frame->linesize[chroma],
+ c_tc, no_p, no_q);
+ }
+ }
+ }
+ }
+
+ // horizontal filtering luma
+ if (x_end != s->sps->width)
+ x_end -= 8;
+ for (y = y0 ? y0 : 8; y < y_end; y += 8) {
+ for (x = x0 ? x0 - 8 : 0; x < x_end; x += 8) {
+ const int bs0 = s->horizontal_bs[(x + y * s->bs_width) >> 2];
+ const int bs1 = s->horizontal_bs[(x + 4 + y * s->bs_width) >> 2];
+ if (bs0 || bs1) {
+ const int qp0 = (get_qPy(s, x, y - 1) + get_qPy(s, x, y) + 1) >> 1;
+ const int qp1 = (get_qPy(s, x + 4, y - 1) + get_qPy(s, x + 4, y) + 1) >> 1;
+
+ tc_offset = x >= x0 ? cur_tc_offset : left_tc_offset;
+ beta_offset = x >= x0 ? cur_beta_offset : left_beta_offset;
+
+ beta[0] = betatable[av_clip(qp0 + (beta_offset >> 1 << 1), 0, MAX_QP)];
+ beta[1] = betatable[av_clip(qp1 + (beta_offset >> 1 << 1), 0, MAX_QP)];
+ tc[0] = bs0 ? TC_CALC(qp0, bs0) : 0;
+ tc[1] = bs1 ? TC_CALC(qp1, bs1) : 0;
+ src = &s->frame->data[LUMA][y * s->frame->linesize[LUMA] + (x << s->sps->pixel_shift)];
+ if (pcmf) {
+ no_p[0] = get_pcm(s, x, y - 1);
+ no_p[1] = get_pcm(s, x + 4, y - 1);
+ no_q[0] = get_pcm(s, x, y);
+ no_q[1] = get_pcm(s, x + 4, y);
+ s->hevcdsp.hevc_h_loop_filter_luma_c(src,
+ s->frame->linesize[LUMA],
+ beta, tc, no_p, no_q);
+ } else
+ s->hevcdsp.hevc_h_loop_filter_luma(src,
+ s->frame->linesize[LUMA],
+ beta, tc, no_p, no_q);
+ }
+ }
+ }
+
+ // horizontal filtering chroma
+ for (chroma = 1; chroma <= 2; chroma++) {
+ for (y = y0 ? y0 : 16; y < y_end; y += 16) {
+ for (x = x0 - 8; x < x_end; x += 16) {
+ int bs0, bs1;
+ // to make sure no memory access over boundary when x = -8
+ // TODO: simplify with row based deblocking
+ if (x < 0) {
+ bs0 = 0;
+ bs1 = s->horizontal_bs[(x + 8 + y * s->bs_width) >> 2];
+ } else if (x >= x_end - 8) {
+ bs0 = s->horizontal_bs[(x + y * s->bs_width) >> 2];
+ bs1 = 0;
+ } else {
+ bs0 = s->horizontal_bs[(x + y * s->bs_width) >> 2];
+ bs1 = s->horizontal_bs[(x + 8 + y * s->bs_width) >> 2];
+ }
+
+ if ((bs0 == 2) || (bs1 == 2)) {
+ const int qp0 = bs0 == 2 ? (get_qPy(s, x, y - 1) + get_qPy(s, x, y) + 1) >> 1 : 0;
+ const int qp1 = bs1 == 2 ? (get_qPy(s, x + 8, y - 1) + get_qPy(s, x + 8, y) + 1) >> 1 : 0;
+
+ tc_offset = x >= x0 ? cur_tc_offset : left_tc_offset;
+ c_tc[0] = bs0 == 2 ? chroma_tc(s, qp0, chroma, tc_offset) : 0;
+ c_tc[1] = bs1 == 2 ? chroma_tc(s, qp1, chroma, cur_tc_offset) : 0;
+ src = &s->frame->data[chroma][y / 2 * s->frame->linesize[chroma] + ((x / 2) << s->sps->pixel_shift)];
+ if (pcmf) {
+ no_p[0] = get_pcm(s, x, y - 1);
+ no_p[1] = get_pcm(s, x + 8, y - 1);
+ no_q[0] = get_pcm(s, x, y);
+ no_q[1] = get_pcm(s, x + 8, y);
+ s->hevcdsp.hevc_h_loop_filter_chroma_c(src,
+ s->frame->linesize[chroma],
+ c_tc, no_p, no_q);
+ } else
+ s->hevcdsp.hevc_h_loop_filter_chroma(src,
+ s->frame->linesize[chroma],
+ c_tc, no_p, no_q);
+ }
+ }
+ }
+ }
+}
+
+static int boundary_strength(HEVCContext *s, MvField *curr,
+ uint8_t curr_cbf_luma, MvField *neigh,
+ uint8_t neigh_cbf_luma,
+ RefPicList *neigh_refPicList,
+ int tu_border)
+{
+ int mvs = curr->pred_flag[0] + curr->pred_flag[1];
+
+ if (tu_border) {
+ if (curr->is_intra || neigh->is_intra)
+ return 2;
+ if (curr_cbf_luma || neigh_cbf_luma)
+ return 1;
+ }
+
+ if (mvs == neigh->pred_flag[0] + neigh->pred_flag[1]) {
+ if (mvs == 2) {
+ // same L0 and L1
+ if (s->ref->refPicList[0].list[curr->ref_idx[0]] == neigh_refPicList[0].list[neigh->ref_idx[0]] &&
+ s->ref->refPicList[0].list[curr->ref_idx[0]] == s->ref->refPicList[1].list[curr->ref_idx[1]] &&
+ neigh_refPicList[0].list[neigh->ref_idx[0]] == neigh_refPicList[1].list[neigh->ref_idx[1]]) {
+ if ((abs(neigh->mv[0].x - curr->mv[0].x) >= 4 || abs(neigh->mv[0].y - curr->mv[0].y) >= 4 ||
+ abs(neigh->mv[1].x - curr->mv[1].x) >= 4 || abs(neigh->mv[1].y - curr->mv[1].y) >= 4) &&
+ (abs(neigh->mv[1].x - curr->mv[0].x) >= 4 || abs(neigh->mv[1].y - curr->mv[0].y) >= 4 ||
+ abs(neigh->mv[0].x - curr->mv[1].x) >= 4 || abs(neigh->mv[0].y - curr->mv[1].y) >= 4))
+ return 1;
+ else
+ return 0;
+ } else if (neigh_refPicList[0].list[neigh->ref_idx[0]] == s->ref->refPicList[0].list[curr->ref_idx[0]] &&
+ neigh_refPicList[1].list[neigh->ref_idx[1]] == s->ref->refPicList[1].list[curr->ref_idx[1]]) {
+ if (abs(neigh->mv[0].x - curr->mv[0].x) >= 4 || abs(neigh->mv[0].y - curr->mv[0].y) >= 4 ||
+ abs(neigh->mv[1].x - curr->mv[1].x) >= 4 || abs(neigh->mv[1].y - curr->mv[1].y) >= 4)
+ return 1;
+ else
+ return 0;
+ } else if (neigh_refPicList[1].list[neigh->ref_idx[1]] == s->ref->refPicList[0].list[curr->ref_idx[0]] &&
+ neigh_refPicList[0].list[neigh->ref_idx[0]] == s->ref->refPicList[1].list[curr->ref_idx[1]]) {
+ if (abs(neigh->mv[1].x - curr->mv[0].x) >= 4 || abs(neigh->mv[1].y - curr->mv[0].y) >= 4 ||
+ abs(neigh->mv[0].x - curr->mv[1].x) >= 4 || abs(neigh->mv[0].y - curr->mv[1].y) >= 4)
+ return 1;
+ else
+ return 0;
+ } else {
+ return 1;
+ }
+ } else { // 1 MV
+ Mv A, B;
+ int ref_A, ref_B;
+
+ if (curr->pred_flag[0]) {
+ A = curr->mv[0];
+ ref_A = s->ref->refPicList[0].list[curr->ref_idx[0]];
+ } else {
+ A = curr->mv[1];
+ ref_A = s->ref->refPicList[1].list[curr->ref_idx[1]];
+ }
+
+ if (neigh->pred_flag[0]) {
+ B = neigh->mv[0];
+ ref_B = neigh_refPicList[0].list[neigh->ref_idx[0]];
+ } else {
+ B = neigh->mv[1];
+ ref_B = neigh_refPicList[1].list[neigh->ref_idx[1]];
+ }
+
+ if (ref_A == ref_B) {
+ if (abs(A.x - B.x) >= 4 || abs(A.y - B.y) >= 4)
+ return 1;
+ else
+ return 0;
+ } else
+ return 1;
+ }
+ }
+
+ return 1;
+}
+
+void ff_hevc_deblocking_boundary_strengths(HEVCContext *s, int x0, int y0,
+ int log2_trafo_size,
+ int slice_or_tiles_up_boundary,
+ int slice_or_tiles_left_boundary)
+{
+ MvField *tab_mvf = s->ref->tab_mvf;
+ int log2_min_pu_size = s->sps->log2_min_pu_size;
+ int log2_min_tu_size = s->sps->log2_min_tb_size;
+ int min_pu_width = s->sps->min_pu_width;
+ int min_tu_width = s->sps->min_tb_width;
+ int is_intra = tab_mvf[(y0 >> log2_min_pu_size) * min_pu_width +
+ (x0 >> log2_min_pu_size)].is_intra;
+ int i, j, bs;
+
+ if (y0 > 0 && (y0 & 7) == 0) {
+ int yp_pu = (y0 - 1) >> log2_min_pu_size;
+ int yq_pu = y0 >> log2_min_pu_size;
+ int yp_tu = (y0 - 1) >> log2_min_tu_size;
+ int yq_tu = y0 >> log2_min_tu_size;
+
+ for (i = 0; i < (1 << log2_trafo_size); i += 4) {
+ int x_pu = (x0 + i) >> log2_min_pu_size;
+ int x_tu = (x0 + i) >> log2_min_tu_size;
+ MvField *top = &tab_mvf[yp_pu * min_pu_width + x_pu];
+ MvField *curr = &tab_mvf[yq_pu * min_pu_width + x_pu];
+ uint8_t top_cbf_luma = s->cbf_luma[yp_tu * min_tu_width + x_tu];
+ uint8_t curr_cbf_luma = s->cbf_luma[yq_tu * min_tu_width + x_tu];
+ RefPicList *top_refPicList = ff_hevc_get_ref_list(s, s->ref,
+ x0 + i, y0 - 1);
+
+ bs = boundary_strength(s, curr, curr_cbf_luma,
+ top, top_cbf_luma, top_refPicList, 1);
+ if (!s->sh.slice_loop_filter_across_slices_enabled_flag &&
+ (slice_or_tiles_up_boundary & 1) &&
+ (y0 % (1 << s->sps->log2_ctb_size)) == 0)
+ bs = 0;
+ else if (!s->pps->loop_filter_across_tiles_enabled_flag &&
+ (slice_or_tiles_up_boundary & 2) &&
+ (y0 % (1 << s->sps->log2_ctb_size)) == 0)
+ bs = 0;
+ if (y0 == 0 || s->sh.disable_deblocking_filter_flag == 1)
+ bs = 0;
+ if (bs)
+ s->horizontal_bs[((x0 + i) + y0 * s->bs_width) >> 2] = bs;
+ }
+ }
+
+ // bs for TU internal horizontal PU boundaries
+ if (log2_trafo_size > s->sps->log2_min_pu_size && !is_intra)
+ for (j = 8; j < (1 << log2_trafo_size); j += 8) {
+ int yp_pu = (y0 + j - 1) >> log2_min_pu_size;
+ int yq_pu = (y0 + j) >> log2_min_pu_size;
+ int yp_tu = (y0 + j - 1) >> log2_min_tu_size;
+ int yq_tu = (y0 + j) >> log2_min_tu_size;
+
+ for (i = 0; i < (1 << log2_trafo_size); i += 4) {
+ int x_pu = (x0 + i) >> log2_min_pu_size;
+ int x_tu = (x0 + i) >> log2_min_tu_size;
+ MvField *top = &tab_mvf[yp_pu * min_pu_width + x_pu];
+ MvField *curr = &tab_mvf[yq_pu * min_pu_width + x_pu];
+ uint8_t top_cbf_luma = s->cbf_luma[yp_tu * min_tu_width + x_tu];
+ uint8_t curr_cbf_luma = s->cbf_luma[yq_tu * min_tu_width + x_tu];
+ RefPicList *top_refPicList = ff_hevc_get_ref_list(s, s->ref,
+ x0 + i,
+ y0 + j - 1);
+
+ bs = boundary_strength(s, curr, curr_cbf_luma,
+ top, top_cbf_luma, top_refPicList, 0);
+ if (s->sh.disable_deblocking_filter_flag == 1)
+ bs = 0;
+ if (bs)
+ s->horizontal_bs[((x0 + i) + (y0 + j) * s->bs_width) >> 2] = bs;
+ }
+ }
+
+ // bs for vertical TU boundaries
+ if (x0 > 0 && (x0 & 7) == 0) {
+ int xp_pu = (x0 - 1) >> log2_min_pu_size;
+ int xq_pu = x0 >> log2_min_pu_size;
+ int xp_tu = (x0 - 1) >> log2_min_tu_size;
+ int xq_tu = x0 >> log2_min_tu_size;
+
+ for (i = 0; i < (1 << log2_trafo_size); i += 4) {
+ int y_pu = (y0 + i) >> log2_min_pu_size;
+ int y_tu = (y0 + i) >> log2_min_tu_size;
+ MvField *left = &tab_mvf[y_pu * min_pu_width + xp_pu];
+ MvField *curr = &tab_mvf[y_pu * min_pu_width + xq_pu];
+
+ uint8_t left_cbf_luma = s->cbf_luma[y_tu * min_tu_width + xp_tu];
+ uint8_t curr_cbf_luma = s->cbf_luma[y_tu * min_tu_width + xq_tu];
+ RefPicList *left_refPicList = ff_hevc_get_ref_list(s, s->ref,
+ x0 - 1, y0 + i);
+
+ bs = boundary_strength(s, curr, curr_cbf_luma,
+ left, left_cbf_luma, left_refPicList, 1);
+ if (!s->sh.slice_loop_filter_across_slices_enabled_flag &&
+ (slice_or_tiles_left_boundary & 1) &&
+ (x0 % (1 << s->sps->log2_ctb_size)) == 0)
+ bs = 0;
+ else if (!s->pps->loop_filter_across_tiles_enabled_flag &&
+ (slice_or_tiles_left_boundary & 2) &&
+ (x0 % (1 << s->sps->log2_ctb_size)) == 0)
+ bs = 0;
+ if (x0 == 0 || s->sh.disable_deblocking_filter_flag == 1)
+ bs = 0;
+ if (bs)
+ s->vertical_bs[(x0 >> 3) + ((y0 + i) >> 2) * s->bs_width] = bs;
+ }
+ }
+
+ // bs for TU internal vertical PU boundaries
+ if (log2_trafo_size > log2_min_pu_size && !is_intra)
+ for (j = 0; j < (1 << log2_trafo_size); j += 4) {
+ int y_pu = (y0 + j) >> log2_min_pu_size;
+ int y_tu = (y0 + j) >> log2_min_tu_size;
+
+ for (i = 8; i < (1 << log2_trafo_size); i += 8) {
+ int xp_pu = (x0 + i - 1) >> log2_min_pu_size;
+ int xq_pu = (x0 + i) >> log2_min_pu_size;
+ int xp_tu = (x0 + i - 1) >> log2_min_tu_size;
+ int xq_tu = (x0 + i) >> log2_min_tu_size;
+ MvField *left = &tab_mvf[y_pu * min_pu_width + xp_pu];
+ MvField *curr = &tab_mvf[y_pu * min_pu_width + xq_pu];
+ uint8_t left_cbf_luma = s->cbf_luma[y_tu * min_tu_width + xp_tu];
+ uint8_t curr_cbf_luma = s->cbf_luma[y_tu * min_tu_width + xq_tu];
+ RefPicList *left_refPicList = ff_hevc_get_ref_list(s, s->ref,
+ x0 + i - 1,
+ y0 + j);
+
+ bs = boundary_strength(s, curr, curr_cbf_luma,
+ left, left_cbf_luma, left_refPicList, 0);
+ if (s->sh.disable_deblocking_filter_flag == 1)
+ bs = 0;
+ if (bs)
+ s->vertical_bs[((x0 + i) >> 3) + ((y0 + j) >> 2) * s->bs_width] = bs;
+ }
+ }
+}
+
+#undef LUMA
+#undef CB
+#undef CR
+
+void ff_hevc_hls_filter(HEVCContext *s, int x, int y)
+{
+ deblocking_filter_CTB(s, x, y);
+ if (s->sps->sao_enabled)
+ sao_filter_CTB(s, x, y);
+}
+
+void ff_hevc_hls_filters(HEVCContext *s, int x_ctb, int y_ctb, int ctb_size)
+{
+ if (y_ctb && x_ctb)
+ ff_hevc_hls_filter(s, x_ctb - ctb_size, y_ctb - ctb_size);
+ if (y_ctb && x_ctb >= s->sps->width - ctb_size) {
+ ff_hevc_hls_filter(s, x_ctb, y_ctb - ctb_size);
+ if (s->threads_type == FF_THREAD_FRAME )
+ ff_thread_report_progress(&s->ref->tf, y_ctb - ctb_size, 0);
+ }
+ if (x_ctb && y_ctb >= s->sps->height - ctb_size)
+ ff_hevc_hls_filter(s, x_ctb - ctb_size, y_ctb);
+}
diff --git a/libavcodec/hevc_mvs.c b/libavcodec/hevc_mvs.c
new file mode 100644
index 0000000..b4e067b
--- /dev/null
+++ b/libavcodec/hevc_mvs.c
@@ -0,0 +1,817 @@
+/*
+ * HEVC video decoder
+ *
+ * Copyright (C) 2012 - 2013 Guillaume Martres
+ * Copyright (C) 2013 Anand Meher Kotra
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "hevc.h"
+
+static const uint8_t l0_l1_cand_idx[12][2] = {
+ { 0, 1, },
+ { 1, 0, },
+ { 0, 2, },
+ { 2, 0, },
+ { 1, 2, },
+ { 2, 1, },
+ { 0, 3, },
+ { 3, 0, },
+ { 1, 3, },
+ { 3, 1, },
+ { 2, 3, },
+ { 3, 2, },
+};
+
+void ff_hevc_set_neighbour_available(HEVCContext *s, int x0, int y0,
+ int nPbW, int nPbH)
+{
+ HEVCLocalContext *lc = s->HEVClc;
+ int x0b = x0 & ((1 << s->sps->log2_ctb_size) - 1);
+ int y0b = y0 & ((1 << s->sps->log2_ctb_size) - 1);
+
+ lc->na.cand_up = (lc->ctb_up_flag || y0b);
+ lc->na.cand_left = (lc->ctb_left_flag || x0b);
+ lc->na.cand_up_left = (!x0b && !y0b) ? lc->ctb_up_left_flag : lc->na.cand_left && lc->na.cand_up;
+ lc->na.cand_up_right_sap =
+ ((x0b + nPbW) == (1 << s->sps->log2_ctb_size)) ?
+ lc->ctb_up_right_flag && !y0b : lc->na.cand_up;
+ lc->na.cand_up_right =
+ ((x0b + nPbW) == (1 << s->sps->log2_ctb_size) ?
+ lc->ctb_up_right_flag && !y0b : lc->na.cand_up )
+ && (x0 + nPbW) < lc->end_of_tiles_x;
+ lc->na.cand_bottom_left = ((y0 + nPbH) >= lc->end_of_tiles_y) ? 0 : lc->na.cand_left;
+}
+
+/*
+ * 6.4.1 Derivation process for z-scan order block availability
+ */
+static int z_scan_block_avail(HEVCContext *s, int xCurr, int yCurr,
+ int xN, int yN)
+{
+#define MIN_TB_ADDR_ZS(x, y) \
+ s->pps->min_tb_addr_zs[(y) * s->sps->min_tb_width + (x)]
+ int Curr = MIN_TB_ADDR_ZS(xCurr >> s->sps->log2_min_tb_size,
+ yCurr >> s->sps->log2_min_tb_size);
+ int N;
+
+ if (xN < 0 || yN < 0 ||
+ xN >= s->sps->width ||
+ yN >= s->sps->height)
+ return 0;
+
+ N = MIN_TB_ADDR_ZS(xN >> s->sps->log2_min_tb_size,
+ yN >> s->sps->log2_min_tb_size);
+
+ return N <= Curr;
+}
+
+static int same_prediction_block(HEVCLocalContext *lc, int log2_cb_size,
+ int x0, int y0, int nPbW, int nPbH,
+ int xA1, int yA1, int partIdx)
+{
+ return !(nPbW << 1 == 1 << log2_cb_size &&
+ nPbH << 1 == 1 << log2_cb_size && partIdx == 1 &&
+ lc->cu.x + nPbW > xA1 &&
+ lc->cu.y + nPbH <= yA1);
+}
+
+/*
+ * 6.4.2 Derivation process for prediction block availability
+ */
+static int check_prediction_block_available(HEVCContext *s, int log2_cb_size,
+ int x0, int y0, int nPbW, int nPbH,
+ int xA1, int yA1, int partIdx)
+{
+ HEVCLocalContext *lc = s->HEVClc;
+
+ if (lc->cu.x < xA1 && lc->cu.y < yA1 &&
+ (lc->cu.x + (1 << log2_cb_size)) > xA1 &&
+ (lc->cu.y + (1 << log2_cb_size)) > yA1)
+ return same_prediction_block(lc, log2_cb_size, x0, y0,
+ nPbW, nPbH, xA1, yA1, partIdx);
+ else
+ return z_scan_block_avail(s, x0, y0, xA1, yA1);
+}
+
+//check if the two luma locations belong to the same mostion estimation region
+static int isDiffMER(HEVCContext *s, int xN, int yN, int xP, int yP)
+{
+ uint8_t plevel = s->pps->log2_parallel_merge_level;
+
+ return xN >> plevel == xP >> plevel &&
+ yN >> plevel == yP >> plevel;
+}
+
+#define MATCH(x) (A.x == B.x)
+
+// check if the mv's and refidx are the same between A and B
+static int compareMVrefidx(struct MvField A, struct MvField B)
+{
+ if (A.pred_flag[0] && A.pred_flag[1] && B.pred_flag[0] && B.pred_flag[1])
+ return MATCH(ref_idx[0]) && MATCH(mv[0].x) && MATCH(mv[0].y) &&
+ MATCH(ref_idx[1]) && MATCH(mv[1].x) && MATCH(mv[1].y);
+
+ if (A.pred_flag[0] && !A.pred_flag[1] && B.pred_flag[0] && !B.pred_flag[1])
+ return MATCH(ref_idx[0]) && MATCH(mv[0].x) && MATCH(mv[0].y);
+
+ if (!A.pred_flag[0] && A.pred_flag[1] && !B.pred_flag[0] && B.pred_flag[1])
+ return MATCH(ref_idx[1]) && MATCH(mv[1].x) && MATCH(mv[1].y);
+
+ return 0;
+}
+
+static av_always_inline void mv_scale(Mv *dst, Mv *src, int td, int tb)
+{
+ int tx, scale_factor;
+
+ td = av_clip_int8_c(td);
+ tb = av_clip_int8_c(tb);
+ tx = (0x4000 + abs(td / 2)) / td;
+ scale_factor = av_clip_c((tb * tx + 32) >> 6, -4096, 4095);
+ dst->x = av_clip_int16_c((scale_factor * src->x + 127 +
+ (scale_factor * src->x < 0)) >> 8);
+ dst->y = av_clip_int16_c((scale_factor * src->y + 127 +
+ (scale_factor * src->y < 0)) >> 8);
+}
+
+static int check_mvset(Mv *mvLXCol, Mv *mvCol,
+ int colPic, int poc,
+ RefPicList *refPicList, int X, int refIdxLx,
+ RefPicList *refPicList_col, int listCol, int refidxCol)
+{
+ int cur_lt = refPicList[X].isLongTerm[refIdxLx];
+ int col_lt = refPicList_col[listCol].isLongTerm[refidxCol];
+ int col_poc_diff, cur_poc_diff;
+
+ if (cur_lt != col_lt) {
+ mvLXCol->x = 0;
+ mvLXCol->y = 0;
+ return 0;
+ }
+
+ col_poc_diff = colPic - refPicList_col[listCol].list[refidxCol];
+ cur_poc_diff = poc - refPicList[X].list[refIdxLx];
+
+ if (!col_poc_diff)
+ col_poc_diff = 1; // error resilience
+
+ if (cur_lt || col_poc_diff == cur_poc_diff) {
+ mvLXCol->x = mvCol->x;
+ mvLXCol->y = mvCol->y;
+ } else {
+ mv_scale(mvLXCol, mvCol, col_poc_diff, cur_poc_diff);
+ }
+ return 1;
+}
+
+#define CHECK_MVSET(l) \
+ check_mvset(mvLXCol, temp_col.mv + l, \
+ colPic, s->poc, \
+ refPicList, X, refIdxLx, \
+ refPicList_col, L ## l, temp_col.ref_idx[l])
+
+// derive the motion vectors section 8.5.3.1.8
+static int derive_temporal_colocated_mvs(HEVCContext *s, MvField temp_col,
+ int refIdxLx, Mv *mvLXCol, int X,
+ int colPic, RefPicList *refPicList_col)
+{
+ RefPicList *refPicList = s->ref->refPicList;
+
+ if (temp_col.is_intra) {
+ mvLXCol->x = 0;
+ mvLXCol->y = 0;
+ return 0;
+ }
+
+ if (temp_col.pred_flag[0] == 0)
+ return CHECK_MVSET(1);
+ else if (temp_col.pred_flag[0] == 1 && temp_col.pred_flag[1] == 0)
+ return CHECK_MVSET(0);
+ else if (temp_col.pred_flag[0] == 1 && temp_col.pred_flag[1] == 1) {
+ int check_diffpicount = 0;
+ int i = 0;
+ for (i = 0; i < refPicList[0].nb_refs; i++) {
+ if (refPicList[0].list[i] > s->poc)
+ check_diffpicount++;
+ }
+ for (i = 0; i < refPicList[1].nb_refs; i++) {
+ if (refPicList[1].list[i] > s->poc)
+ check_diffpicount++;
+ }
+ if (check_diffpicount == 0 && X == 0)
+ return CHECK_MVSET(0);
+ else if (check_diffpicount == 0 && X == 1)
+ return CHECK_MVSET(1);
+ else {
+ if (s->sh.collocated_list == L1)
+ return CHECK_MVSET(0);
+ else
+ return CHECK_MVSET(1);
+ }
+ }
+
+ return 0;
+}
+
+#define TAB_MVF(x, y) \
+ tab_mvf[(y) * min_pu_width + x]
+
+#define TAB_MVF_PU(v) \
+ TAB_MVF(x ## v ## _pu, y ## v ## _pu)
+
+#define DERIVE_TEMPORAL_COLOCATED_MVS \
+ derive_temporal_colocated_mvs(s, temp_col, \
+ refIdxLx, mvLXCol, X, colPic, \
+ ff_hevc_get_ref_list(s, ref, x, y))
+
+/*
+ * 8.5.3.1.7 temporal luma motion vector prediction
+ */
+static int temporal_luma_motion_vector(HEVCContext *s, int x0, int y0,
+ int nPbW, int nPbH, int refIdxLx,
+ Mv *mvLXCol, int X)
+{
+ MvField *tab_mvf;
+ MvField temp_col;
+ int x, y, x_pu, y_pu;
+ int min_pu_width = s->sps->min_pu_width;
+ int availableFlagLXCol = 0;
+ int colPic;
+
+ HEVCFrame *ref = s->ref->collocated_ref;
+
+ if (!ref)
+ return 0;
+
+ tab_mvf = ref->tab_mvf;
+ colPic = ref->poc;
+
+ //bottom right collocated motion vector
+ x = x0 + nPbW;
+ y = y0 + nPbH;
+
+ if (s->threads_type == FF_THREAD_FRAME )
+ ff_thread_await_progress(&ref->tf, y, 0);
+ if (tab_mvf &&
+ (y0 >> s->sps->log2_ctb_size) == (y >> s->sps->log2_ctb_size) &&
+ y < s->sps->height &&
+ x < s->sps->width) {
+ x = ((x >> 4) << 4);
+ y = ((y >> 4) << 4);
+ x_pu = x >> s->sps->log2_min_pu_size;
+ y_pu = y >> s->sps->log2_min_pu_size;
+ temp_col = TAB_MVF(x_pu, y_pu);
+ availableFlagLXCol = DERIVE_TEMPORAL_COLOCATED_MVS;
+ }
+
+ // derive center collocated motion vector
+ if (tab_mvf && !availableFlagLXCol) {
+ x = x0 + (nPbW >> 1);
+ y = y0 + (nPbH >> 1);
+ x = ((x >> 4) << 4);
+ y = ((y >> 4) << 4);
+ x_pu = x >> s->sps->log2_min_pu_size;
+ y_pu = y >> s->sps->log2_min_pu_size;
+ temp_col = TAB_MVF(x_pu, y_pu);
+ availableFlagLXCol = DERIVE_TEMPORAL_COLOCATED_MVS;
+ }
+ return availableFlagLXCol;
+}
+
+#define AVAILABLE(cand, v) \
+ (cand && !TAB_MVF_PU(v).is_intra)
+
+#define PRED_BLOCK_AVAILABLE(v) \
+ check_prediction_block_available(s, log2_cb_size, \
+ x0, y0, nPbW, nPbH, \
+ x ## v, y ## v, part_idx)
+
+#define COMPARE_MV_REFIDX(a, b) \
+ compareMVrefidx(TAB_MVF_PU(a), TAB_MVF_PU(b))
+
+/*
+ * 8.5.3.1.2 Derivation process for spatial merging candidates
+ */
+static void derive_spatial_merge_candidates(HEVCContext *s, int x0, int y0,
+ int nPbW, int nPbH,
+ int log2_cb_size,
+ int singleMCLFlag, int part_idx,
+ struct MvField mergecandlist[])
+{
+ HEVCLocalContext *lc = s->HEVClc;
+ RefPicList *refPicList = s->ref->refPicList;
+ MvField *tab_mvf = s->ref->tab_mvf;
+
+ const int min_pu_width = s->sps->min_pu_width;
+
+ const int cand_bottom_left = lc->na.cand_bottom_left;
+ const int cand_left = lc->na.cand_left;
+ const int cand_up_left = lc->na.cand_up_left;
+ const int cand_up = lc->na.cand_up;
+ const int cand_up_right = lc->na.cand_up_right_sap;
+
+ const int xA1 = x0 - 1;
+ const int yA1 = y0 + nPbH - 1;
+ const int xA1_pu = xA1 >> s->sps->log2_min_pu_size;
+ const int yA1_pu = yA1 >> s->sps->log2_min_pu_size;
+
+ const int xB1 = x0 + nPbW - 1;
+ const int yB1 = y0 - 1;
+ const int xB1_pu = xB1 >> s->sps->log2_min_pu_size;
+ const int yB1_pu = yB1 >> s->sps->log2_min_pu_size;
+
+ const int xB0 = x0 + nPbW;
+ const int yB0 = y0 - 1;
+ const int xB0_pu = xB0 >> s->sps->log2_min_pu_size;
+ const int yB0_pu = yB0 >> s->sps->log2_min_pu_size;
+
+ const int xA0 = x0 - 1;
+ const int yA0 = y0 + nPbH;
+ const int xA0_pu = xA0 >> s->sps->log2_min_pu_size;
+ const int yA0_pu = yA0 >> s->sps->log2_min_pu_size;
+
+ const int xB2 = x0 - 1;
+ const int yB2 = y0 - 1;
+ const int xB2_pu = xB2 >> s->sps->log2_min_pu_size;
+ const int yB2_pu = yB2 >> s->sps->log2_min_pu_size;
+
+ const int nb_refs = (s->sh.slice_type == P_SLICE) ?
+ s->sh.nb_refs[0] : FFMIN(s->sh.nb_refs[0], s->sh.nb_refs[1]);
+ int check_MER = 1;
+ int check_MER_1 = 1;
+
+ int zero_idx = 0;
+
+ int nb_merge_cand = 0;
+ int nb_orig_merge_cand = 0;
+
+ int is_available_a0;
+ int is_available_a1;
+ int is_available_b0;
+ int is_available_b1;
+ int is_available_b2;
+ int check_B0;
+ int check_A0;
+
+ //first left spatial merge candidate
+ is_available_a1 = AVAILABLE(cand_left, A1);
+
+ if (!singleMCLFlag && part_idx == 1 &&
+ (lc->cu.part_mode == PART_Nx2N ||
+ lc->cu.part_mode == PART_nLx2N ||
+ lc->cu.part_mode == PART_nRx2N) ||
+ isDiffMER(s, xA1, yA1, x0, y0)) {
+ is_available_a1 = 0;
+ }
+
+ if (is_available_a1)
+ mergecandlist[nb_merge_cand++] = TAB_MVF_PU(A1);
+
+ // above spatial merge candidate
+ is_available_b1 = AVAILABLE(cand_up, B1);
+
+ if (!singleMCLFlag && part_idx == 1 &&
+ (lc->cu.part_mode == PART_2NxN ||
+ lc->cu.part_mode == PART_2NxnU ||
+ lc->cu.part_mode == PART_2NxnD) ||
+ isDiffMER(s, xB1, yB1, x0, y0)) {
+ is_available_b1 = 0;
+ }
+
+ if (is_available_a1 && is_available_b1)
+ check_MER = !COMPARE_MV_REFIDX(B1, A1);
+
+ if (is_available_b1 && check_MER)
+ mergecandlist[nb_merge_cand++] = TAB_MVF_PU(B1);
+
+ // above right spatial merge candidate
+ check_MER = 1;
+ check_B0 = PRED_BLOCK_AVAILABLE(B0);
+
+ is_available_b0 = check_B0 && AVAILABLE(cand_up_right, B0);
+
+ if (isDiffMER(s, xB0, yB0, x0, y0))
+ is_available_b0 = 0;
+
+ if (is_available_b1 && is_available_b0)
+ check_MER = !COMPARE_MV_REFIDX(B0, B1);
+
+ if (is_available_b0 && check_MER)
+ mergecandlist[nb_merge_cand++] = TAB_MVF_PU(B0);
+
+ // left bottom spatial merge candidate
+ check_MER = 1;
+ check_A0 = PRED_BLOCK_AVAILABLE(A0);
+
+ is_available_a0 = check_A0 && AVAILABLE(cand_bottom_left, A0);
+
+ if (isDiffMER(s, xA0, yA0, x0, y0))
+ is_available_a0 = 0;
+
+ if (is_available_a1 && is_available_a0)
+ check_MER = !COMPARE_MV_REFIDX(A0, A1);
+
+ if (is_available_a0 && check_MER)
+ mergecandlist[nb_merge_cand++] = TAB_MVF_PU(A0);
+
+ // above left spatial merge candidate
+ check_MER = 1;
+
+ is_available_b2 = AVAILABLE(cand_up_left, B2);
+
+ if (isDiffMER(s, xB2, yB2, x0, y0))
+ is_available_b2 = 0;
+
+ if (is_available_a1 && is_available_b2)
+ check_MER = !COMPARE_MV_REFIDX(B2, A1);
+
+ if (is_available_b1 && is_available_b2)
+ check_MER_1 = !COMPARE_MV_REFIDX(B2, B1);
+
+ if (is_available_b2 && check_MER && check_MER_1 && nb_merge_cand != 4)
+ mergecandlist[nb_merge_cand++] = TAB_MVF_PU(B2);
+
+ // temporal motion vector candidate
+ if (s->sh.slice_temporal_mvp_enabled_flag &&
+ nb_merge_cand < s->sh.max_num_merge_cand) {
+ Mv mv_l0_col, mv_l1_col;
+ int available_l0 = temporal_luma_motion_vector(s, x0, y0, nPbW, nPbH,
+ 0, &mv_l0_col, 0);
+ int available_l1 = (s->sh.slice_type == B_SLICE) ?
+ temporal_luma_motion_vector(s, x0, y0, nPbW, nPbH,
+ 0, &mv_l1_col, 1) : 0;
+
+ if (available_l0 || available_l1) {
+ mergecandlist[nb_merge_cand].is_intra = 0;
+ mergecandlist[nb_merge_cand].pred_flag[0] = available_l0;
+ mergecandlist[nb_merge_cand].pred_flag[1] = available_l1;
+ if (available_l0) {
+ mergecandlist[nb_merge_cand].mv[0] = mv_l0_col;
+ mergecandlist[nb_merge_cand].ref_idx[0] = 0;
+ }
+ if (available_l1) {
+ mergecandlist[nb_merge_cand].mv[1] = mv_l1_col;
+ mergecandlist[nb_merge_cand].ref_idx[1] = 0;
+ }
+ nb_merge_cand++;
+ }
+ }
+
+ nb_orig_merge_cand = nb_merge_cand;
+
+ // combined bi-predictive merge candidates (applies for B slices)
+ if (s->sh.slice_type == B_SLICE && nb_orig_merge_cand > 1 &&
+ nb_orig_merge_cand < s->sh.max_num_merge_cand) {
+ int comb_idx = 0;
+
+ for (comb_idx = 0; nb_merge_cand < s->sh.max_num_merge_cand &&
+ comb_idx < nb_orig_merge_cand * (nb_orig_merge_cand - 1); comb_idx++) {
+ int l0_cand_idx = l0_l1_cand_idx[comb_idx][0];
+ int l1_cand_idx = l0_l1_cand_idx[comb_idx][1];
+ MvField l0_cand = mergecandlist[l0_cand_idx];
+ MvField l1_cand = mergecandlist[l1_cand_idx];
+
+ if (l0_cand.pred_flag[0] && l1_cand.pred_flag[1] &&
+ (refPicList[0].list[l0_cand.ref_idx[0]] !=
+ refPicList[1].list[l1_cand.ref_idx[1]] ||
+ l0_cand.mv[0].x != l1_cand.mv[1].x ||
+ l0_cand.mv[0].y != l1_cand.mv[1].y)) {
+ mergecandlist[nb_merge_cand].ref_idx[0] = l0_cand.ref_idx[0];
+ mergecandlist[nb_merge_cand].ref_idx[1] = l1_cand.ref_idx[1];
+ mergecandlist[nb_merge_cand].pred_flag[0] = 1;
+ mergecandlist[nb_merge_cand].pred_flag[1] = 1;
+ mergecandlist[nb_merge_cand].mv[0].x = l0_cand.mv[0].x;
+ mergecandlist[nb_merge_cand].mv[0].y = l0_cand.mv[0].y;
+ mergecandlist[nb_merge_cand].mv[1].x = l1_cand.mv[1].x;
+ mergecandlist[nb_merge_cand].mv[1].y = l1_cand.mv[1].y;
+ mergecandlist[nb_merge_cand].is_intra = 0;
+ nb_merge_cand++;
+ }
+ }
+ }
+
+ // append Zero motion vector candidates
+ while (nb_merge_cand < s->sh.max_num_merge_cand) {
+ mergecandlist[nb_merge_cand].pred_flag[0] = 1;
+ mergecandlist[nb_merge_cand].pred_flag[1] = s->sh.slice_type == B_SLICE;
+ mergecandlist[nb_merge_cand].mv[0].x = 0;
+ mergecandlist[nb_merge_cand].mv[0].y = 0;
+ mergecandlist[nb_merge_cand].mv[1].x = 0;
+ mergecandlist[nb_merge_cand].mv[1].y = 0;
+ mergecandlist[nb_merge_cand].is_intra = 0;
+ mergecandlist[nb_merge_cand].ref_idx[0] = zero_idx < nb_refs ? zero_idx : 0;
+ mergecandlist[nb_merge_cand].ref_idx[1] = zero_idx < nb_refs ? zero_idx : 0;
+
+ nb_merge_cand++;
+ zero_idx++;
+ }
+}
+
+/*
+ * 8.5.3.1.1 Derivation process of luma Mvs for merge mode
+ */
+void ff_hevc_luma_mv_merge_mode(HEVCContext *s, int x0, int y0, int nPbW,
+ int nPbH, int log2_cb_size, int part_idx,
+ int merge_idx, MvField *mv)
+{
+ int singleMCLFlag = 0;
+ int nCS = 1 << log2_cb_size;
+ struct MvField mergecand_list[MRG_MAX_NUM_CANDS] = { { { { 0 } } } };
+ int nPbW2 = nPbW;
+ int nPbH2 = nPbH;
+ HEVCLocalContext *lc = s->HEVClc;
+
+ if (s->pps->log2_parallel_merge_level > 2 && nCS == 8) {
+ singleMCLFlag = 1;
+ x0 = lc->cu.x;
+ y0 = lc->cu.y;
+ nPbW = nCS;
+ nPbH = nCS;
+ part_idx = 0;
+ }
+
+ ff_hevc_set_neighbour_available(s, x0, y0, nPbW, nPbH);
+ derive_spatial_merge_candidates(s, x0, y0, nPbW, nPbH, log2_cb_size,
+ singleMCLFlag, part_idx, mergecand_list);
+
+ if (mergecand_list[merge_idx].pred_flag[0] == 1 &&
+ mergecand_list[merge_idx].pred_flag[1] == 1 &&
+ (nPbW2 + nPbH2) == 12) {
+ mergecand_list[merge_idx].ref_idx[1] = -1;
+ mergecand_list[merge_idx].pred_flag[1] = 0;
+ }
+
+ *mv = mergecand_list[merge_idx];
+}
+
+static av_always_inline void dist_scale(HEVCContext *s, Mv *mv,
+ int min_pu_width, int x, int y,
+ int elist, int ref_idx_curr, int ref_idx)
+{
+ RefPicList *refPicList = s->ref->refPicList;
+ MvField *tab_mvf = s->ref->tab_mvf;
+ int ref_pic_elist = refPicList[elist].list[TAB_MVF(x, y).ref_idx[elist]];
+ int ref_pic_curr = refPicList[ref_idx_curr].list[ref_idx];
+
+ if (ref_pic_elist != ref_pic_curr)
+ mv_scale(mv, mv, s->poc - ref_pic_elist, s->poc - ref_pic_curr);
+}
+
+static int mv_mp_mode_mx(HEVCContext *s, int x, int y, int pred_flag_index,
+ Mv *mv, int ref_idx_curr, int ref_idx)
+{
+ MvField *tab_mvf = s->ref->tab_mvf;
+ int min_pu_width = s->sps->min_pu_width;
+
+ RefPicList *refPicList = s->ref->refPicList;
+
+ if (TAB_MVF(x, y).pred_flag[pred_flag_index] == 1 &&
+ refPicList[pred_flag_index].list[TAB_MVF(x, y).ref_idx[pred_flag_index]] == refPicList[ref_idx_curr].list[ref_idx]) {
+ *mv = TAB_MVF(x, y).mv[pred_flag_index];
+ return 1;
+ }
+ return 0;
+}
+
+static int mv_mp_mode_mx_lt(HEVCContext *s, int x, int y, int pred_flag_index,
+ Mv *mv, int ref_idx_curr, int ref_idx)
+{
+ MvField *tab_mvf = s->ref->tab_mvf;
+ int min_pu_width = s->sps->min_pu_width;
+
+ RefPicList *refPicList = s->ref->refPicList;
+ int currIsLongTerm = refPicList[ref_idx_curr].isLongTerm[ref_idx];
+
+ int colIsLongTerm =
+ refPicList[pred_flag_index].isLongTerm[(TAB_MVF(x, y).ref_idx[pred_flag_index])];
+
+ if (TAB_MVF(x, y).pred_flag[pred_flag_index] &&
+ colIsLongTerm == currIsLongTerm) {
+ *mv = TAB_MVF(x, y).mv[pred_flag_index];
+ if (!currIsLongTerm)
+ dist_scale(s, mv, min_pu_width, x, y,
+ pred_flag_index, ref_idx_curr, ref_idx);
+ return 1;
+ }
+ return 0;
+}
+
+#define MP_MX(v, pred, mx) \
+ mv_mp_mode_mx(s, x ## v ## _pu, y ## v ## _pu, pred, \
+ &mx, ref_idx_curr, ref_idx)
+
+#define MP_MX_LT(v, pred, mx) \
+ mv_mp_mode_mx_lt(s, x ## v ## _pu, y ## v ## _pu, pred, \
+ &mx, ref_idx_curr, ref_idx)
+
+void ff_hevc_luma_mv_mvp_mode(HEVCContext *s, int x0, int y0, int nPbW,
+ int nPbH, int log2_cb_size, int part_idx,
+ int merge_idx, MvField *mv,
+ int mvp_lx_flag, int LX)
+{
+ HEVCLocalContext *lc = s->HEVClc;
+ MvField *tab_mvf = s->ref->tab_mvf;
+ int isScaledFlag_L0 = 0;
+ int availableFlagLXA0 = 0;
+ int availableFlagLXB0 = 0;
+ int numMVPCandLX = 0;
+ int min_pu_width = s->sps->min_pu_width;
+
+ int xA0, yA0;
+ int xA0_pu, yA0_pu;
+ int is_available_a0;
+
+ int xA1, yA1;
+ int xA1_pu, yA1_pu;
+ int is_available_a1;
+
+ int xB0, yB0;
+ int xB0_pu, yB0_pu;
+ int is_available_b0;
+
+ int xB1, yB1;
+ int xB1_pu = 0, yB1_pu = 0;
+ int is_available_b1 = 0;
+
+ int xB2, yB2;
+ int xB2_pu = 0, yB2_pu = 0;
+ int is_available_b2 = 0;
+ Mv mvpcand_list[2] = { { 0 } };
+ Mv mxA = { 0 };
+ Mv mxB = { 0 };
+ int ref_idx_curr = 0;
+ int ref_idx = 0;
+ int pred_flag_index_l0;
+ int pred_flag_index_l1;
+ int x0b = x0 & ((1 << s->sps->log2_ctb_size) - 1);
+ int y0b = y0 & ((1 << s->sps->log2_ctb_size) - 1);
+
+ int cand_up = (lc->ctb_up_flag || y0b);
+ int cand_left = (lc->ctb_left_flag || x0b);
+ int cand_up_left =
+ (!x0b && !y0b) ? lc->ctb_up_left_flag : cand_left && cand_up;
+ int cand_up_right =
+ (x0b + nPbW == (1 << s->sps->log2_ctb_size) ||
+ x0 + nPbW >= lc->end_of_tiles_x) ? lc->ctb_up_right_flag && !y0b
+ : cand_up;
+ int cand_bottom_left = (y0 + nPbH >= lc->end_of_tiles_y) ? 0 : cand_left;
+
+ ref_idx_curr = LX;
+ ref_idx = mv->ref_idx[LX];
+ pred_flag_index_l0 = LX;
+ pred_flag_index_l1 = !LX;
+
+ // left bottom spatial candidate
+ xA0 = x0 - 1;
+ yA0 = y0 + nPbH;
+ xA0_pu = xA0 >> s->sps->log2_min_pu_size;
+ yA0_pu = yA0 >> s->sps->log2_min_pu_size;
+
+ is_available_a0 = PRED_BLOCK_AVAILABLE(A0) && AVAILABLE(cand_bottom_left, A0);
+
+ //left spatial merge candidate
+ xA1 = x0 - 1;
+ yA1 = y0 + nPbH - 1;
+ xA1_pu = xA1 >> s->sps->log2_min_pu_size;
+ yA1_pu = yA1 >> s->sps->log2_min_pu_size;
+
+ is_available_a1 = AVAILABLE(cand_left, A1);
+ if (is_available_a0 || is_available_a1)
+ isScaledFlag_L0 = 1;
+
+ if (is_available_a0) {
+ availableFlagLXA0 = MP_MX(A0, pred_flag_index_l0, mxA);
+ if (!availableFlagLXA0)
+ availableFlagLXA0 = MP_MX(A0, pred_flag_index_l1, mxA);
+ }
+
+ if (is_available_a1 && !availableFlagLXA0) {
+ availableFlagLXA0 = MP_MX(A1, pred_flag_index_l0, mxA);
+ if (!availableFlagLXA0)
+ availableFlagLXA0 = MP_MX(A1, pred_flag_index_l1, mxA);
+ }
+
+ if (is_available_a0 && !availableFlagLXA0) {
+ availableFlagLXA0 = MP_MX_LT(A0, pred_flag_index_l0, mxA);
+ if (!availableFlagLXA0)
+ availableFlagLXA0 = MP_MX_LT(A0, pred_flag_index_l1, mxA);
+ }
+
+ if (is_available_a1 && !availableFlagLXA0) {
+ availableFlagLXA0 = MP_MX_LT(A1, pred_flag_index_l0, mxA);
+ if (!availableFlagLXA0)
+ availableFlagLXA0 = MP_MX_LT(A1, pred_flag_index_l1, mxA);
+ }
+
+ // B candidates
+ // above right spatial merge candidate
+ xB0 = x0 + nPbW;
+ yB0 = y0 - 1;
+ xB0_pu = xB0 >> s->sps->log2_min_pu_size;
+ yB0_pu = yB0 >> s->sps->log2_min_pu_size;
+
+ is_available_b0 = PRED_BLOCK_AVAILABLE(B0) && AVAILABLE(cand_up_right, B0);
+
+ if (is_available_b0) {
+ availableFlagLXB0 = MP_MX(B0, pred_flag_index_l0, mxB);
+ if (!availableFlagLXB0)
+ availableFlagLXB0 = MP_MX(B0, pred_flag_index_l1, mxB);
+ }
+
+ if (!availableFlagLXB0) {
+ // above spatial merge candidate
+ xB1 = x0 + nPbW - 1;
+ yB1 = y0 - 1;
+ xB1_pu = xB1 >> s->sps->log2_min_pu_size;
+ yB1_pu = yB1 >> s->sps->log2_min_pu_size;
+
+ is_available_b1 = AVAILABLE(cand_up, B1);
+
+ if (is_available_b1) {
+ availableFlagLXB0 = MP_MX(B1, pred_flag_index_l0, mxB);
+ if (!availableFlagLXB0)
+ availableFlagLXB0 = MP_MX(B1, pred_flag_index_l1, mxB);
+ }
+ }
+
+ if (!availableFlagLXB0) {
+ // above left spatial merge candidate
+ xB2 = x0 - 1;
+ yB2 = y0 - 1;
+ xB2_pu = xB2 >> s->sps->log2_min_pu_size;
+ yB2_pu = yB2 >> s->sps->log2_min_pu_size;
+ is_available_b2 = AVAILABLE(cand_up_left, B2);
+
+ if (is_available_b2) {
+ availableFlagLXB0 = MP_MX(B2, pred_flag_index_l0, mxB);
+ if (!availableFlagLXB0)
+ availableFlagLXB0 = MP_MX(B2, pred_flag_index_l1, mxB);
+ }
+ }
+
+ if (isScaledFlag_L0 == 0) {
+ if (availableFlagLXB0) {
+ availableFlagLXA0 = 1;
+ mxA = mxB;
+ }
+ availableFlagLXB0 = 0;
+
+ // XB0 and L1
+ if (is_available_b0) {
+ availableFlagLXB0 = MP_MX_LT(B0, pred_flag_index_l0, mxB);
+ if (!availableFlagLXB0)
+ availableFlagLXB0 = MP_MX_LT(B0, pred_flag_index_l1, mxB);
+ }
+
+ if (is_available_b1 && !availableFlagLXB0) {
+ availableFlagLXB0 = MP_MX_LT(B1, pred_flag_index_l0, mxB);
+ if (!availableFlagLXB0)
+ availableFlagLXB0 = MP_MX_LT(B1, pred_flag_index_l1, mxB);
+ }
+
+ if (is_available_b2 && !availableFlagLXB0) {
+ availableFlagLXB0 = MP_MX_LT(B2, pred_flag_index_l0, mxB);
+ if (!availableFlagLXB0)
+ availableFlagLXB0 = MP_MX_LT(B2, pred_flag_index_l1, mxB);
+ }
+ }
+
+ if (availableFlagLXA0)
+ mvpcand_list[numMVPCandLX++] = mxA;
+
+ if (availableFlagLXB0 && (!availableFlagLXA0 || mxA.x != mxB.x || mxA.y != mxB.y))
+ mvpcand_list[numMVPCandLX++] = mxB;
+
+ //temporal motion vector prediction candidate
+ if (numMVPCandLX < 2 && s->sh.slice_temporal_mvp_enabled_flag) {
+ Mv mv_col;
+ int available_col = temporal_luma_motion_vector(s, x0, y0, nPbW,
+ nPbH, ref_idx,
+ &mv_col, LX);
+ if (available_col)
+ mvpcand_list[numMVPCandLX++] = mv_col;
+ }
+
+ // insert zero motion vectors when the number of available candidates are less than 2
+ while (numMVPCandLX < 2)
+ mvpcand_list[numMVPCandLX++] = (Mv){ 0, 0 };
+
+ mv->mv[LX].x = mvpcand_list[mvp_lx_flag].x;
+ mv->mv[LX].y = mvpcand_list[mvp_lx_flag].y;
+}
diff --git a/libavcodec/hevc_parser.c b/libavcodec/hevc_parser.c
new file mode 100644
index 0000000..dc1f6d5
--- /dev/null
+++ b/libavcodec/hevc_parser.c
@@ -0,0 +1,347 @@
+/*
+ * HEVC Annex B format parser
+ *
+ * Copyright (C) 2012 - 2013 Guillaume Martres
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "libavutil/common.h"
+
+#include "parser.h"
+#include "hevc.h"
+#include "golomb.h"
+
+#define START_CODE 0x000001 ///< start_code_prefix_one_3bytes
+
+typedef struct HEVCParseContext {
+ HEVCContext h;
+ ParseContext pc;
+} HEVCParseContext;
+
+/**
+ * Find the end of the current frame in the bitstream.
+ * @return the position of the first byte of the next frame, or END_NOT_FOUND
+ */
+static int hevc_find_frame_end(AVCodecParserContext *s, const uint8_t *buf,
+ int buf_size)
+{
+ int i;
+ ParseContext *pc = &((HEVCParseContext *)s->priv_data)->pc;
+
+ for (i = 0; i < buf_size; i++) {
+ int nut;
+
+ pc->state64 = (pc->state64 << 8) | buf[i];
+
+ if (((pc->state64 >> 3 * 8) & 0xFFFFFF) != START_CODE)
+ continue;
+
+ nut = (pc->state64 >> 2 * 8 + 1) & 0x3F;
+ // Beginning of access unit
+ if ((nut >= NAL_VPS && nut <= NAL_AUD) || nut == NAL_SEI_PREFIX ||
+ (nut >= 41 && nut <= 44) || (nut >= 48 && nut <= 55)) {
+ if (pc->frame_start_found) {
+ pc->frame_start_found = 0;
+ return i - 5;
+ }
+ } else if (nut <= NAL_RASL_R ||
+ (nut >= NAL_BLA_W_LP && nut <= NAL_CRA_NUT)) {
+ int first_slice_segment_in_pic_flag = buf[i] >> 7;
+ if (first_slice_segment_in_pic_flag) {
+ if (!pc->frame_start_found) {
+ pc->frame_start_found = 1;
+ } else { // First slice of next frame found
+ pc->frame_start_found = 0;
+ return i - 5;
+ }
+ }
+ }
+ }
+
+ return END_NOT_FOUND;
+}
+
+/**
+ * Parse NAL units of found picture and decode some basic information.
+ *
+ * @param s parser context.
+ * @param avctx codec context.
+ * @param buf buffer with field/frame data.
+ * @param buf_size size of the buffer.
+ */
+static inline int parse_nal_units(AVCodecParserContext *s, AVCodecContext *avctx,
+ const uint8_t *buf, int buf_size)
+{
+ HEVCContext *h = &((HEVCParseContext *)s->priv_data)->h;
+ GetBitContext *gb = &h->HEVClc->gb;
+ SliceHeader *sh = &h->sh;
+ const uint8_t *buf_end = buf + buf_size;
+ int state = -1, i;
+ HEVCNAL *nal;
+
+ /* set some sane default values */
+ s->pict_type = AV_PICTURE_TYPE_I;
+ s->key_frame = 0;
+ s->picture_structure = AV_PICTURE_STRUCTURE_UNKNOWN;
+
+ h->avctx = avctx;
+
+ if (!buf_size)
+ return 0;
+
+ if (h->nals_allocated < 1) {
+ HEVCNAL *tmp = av_realloc_array(h->nals, 1, sizeof(*tmp));
+ if (!tmp)
+ return AVERROR(ENOMEM);
+ h->nals = tmp;
+ memset(h->nals, 0, sizeof(*tmp));
+ h->nals_allocated = 1;
+ }
+
+ nal = &h->nals[0];
+
+ for (;;) {
+ int src_length, consumed;
+ buf = avpriv_find_start_code(buf, buf_end, &state);
+ if (--buf + 2 >= buf_end)
+ break;
+ src_length = buf_end - buf;
+
+ h->nal_unit_type = (*buf >> 1) & 0x3f;
+ h->temporal_id = (*(buf + 1) & 0x07) - 1;
+ if (h->nal_unit_type <= NAL_CRA_NUT) {
+ // Do not walk the whole buffer just to decode slice segment header
+ if (src_length > 20)
+ src_length = 20;
+ }
+
+ consumed = ff_hevc_extract_rbsp(h, buf, src_length, nal);
+ if (consumed < 0)
+ return consumed;
+
+ init_get_bits8(gb, nal->data + 2, nal->size);
+ switch (h->nal_unit_type) {
+ case NAL_VPS:
+ ff_hevc_decode_nal_vps(h);
+ break;
+ case NAL_SPS:
+ ff_hevc_decode_nal_sps(h);
+ break;
+ case NAL_PPS:
+ ff_hevc_decode_nal_pps(h);
+ break;
+ case NAL_SEI_PREFIX:
+ case NAL_SEI_SUFFIX:
+ ff_hevc_decode_nal_sei(h);
+ break;
+ case NAL_TRAIL_N:
+ case NAL_TRAIL_R:
+ case NAL_TSA_N:
+ case NAL_TSA_R:
+ case NAL_STSA_N:
+ case NAL_STSA_R:
+ case NAL_RADL_N:
+ case NAL_RADL_R:
+ case NAL_RASL_N:
+ case NAL_RASL_R:
+ case NAL_BLA_W_LP:
+ case NAL_BLA_W_RADL:
+ case NAL_BLA_N_LP:
+ case NAL_IDR_W_RADL:
+ case NAL_IDR_N_LP:
+ case NAL_CRA_NUT:
+ sh->first_slice_in_pic_flag = get_bits1(gb);
+ s->picture_structure = h->picture_struct;
+ s->field_order = h->picture_struct;
+
+ if (h->nal_unit_type >= 16 && h->nal_unit_type <= 23) {
+ s->key_frame = 1;
+ sh->no_output_of_prior_pics_flag = get_bits1(gb);
+ }
+
+ sh->pps_id = get_ue_golomb(gb);
+ if (sh->pps_id >= MAX_PPS_COUNT || !h->pps_list[sh->pps_id]) {
+ av_log(h->avctx, AV_LOG_ERROR, "PPS id out of range: %d\n", sh->pps_id);
+ return AVERROR_INVALIDDATA;
+ }
+ h->pps = (HEVCPPS*)h->pps_list[sh->pps_id]->data;
+
+ if (h->pps->sps_id >= MAX_SPS_COUNT || !h->sps_list[h->pps->sps_id]) {
+ av_log(h->avctx, AV_LOG_ERROR, "SPS id out of range: %d\n", h->pps->sps_id);
+ return AVERROR_INVALIDDATA;
+ }
+ if (h->sps != (HEVCSPS*)h->sps_list[h->pps->sps_id]->data) {
+ h->sps = (HEVCSPS*)h->sps_list[h->pps->sps_id]->data;
+ h->vps = (HEVCVPS*)h->vps_list[h->sps->vps_id]->data;
+ }
+
+ if (!sh->first_slice_in_pic_flag) {
+ int slice_address_length;
+
+ if (h->pps->dependent_slice_segments_enabled_flag)
+ sh->dependent_slice_segment_flag = get_bits1(gb);
+ else
+ sh->dependent_slice_segment_flag = 0;
+
+ slice_address_length = av_ceil_log2_c(h->sps->ctb_width *
+ h->sps->ctb_height);
+ sh->slice_segment_addr = get_bits(gb, slice_address_length);
+ if (sh->slice_segment_addr >= h->sps->ctb_width * h->sps->ctb_height) {
+ av_log(h->avctx, AV_LOG_ERROR, "Invalid slice segment address: %u.\n",
+ sh->slice_segment_addr);
+ return AVERROR_INVALIDDATA;
+ }
+ } else
+ sh->dependent_slice_segment_flag = 0;
+
+ if (sh->dependent_slice_segment_flag)
+ break;
+
+ for (i = 0; i < h->pps->num_extra_slice_header_bits; i++)
+ skip_bits(gb, 1); // slice_reserved_undetermined_flag[]
+
+ sh->slice_type = get_ue_golomb(gb);
+ if (!(sh->slice_type == I_SLICE || sh->slice_type == P_SLICE ||
+ sh->slice_type == B_SLICE)) {
+ av_log(h->avctx, AV_LOG_ERROR, "Unknown slice type: %d.\n",
+ sh->slice_type);
+ return AVERROR_INVALIDDATA;
+ }
+ s->pict_type = sh->slice_type == B_SLICE ? AV_PICTURE_TYPE_B :
+ sh->slice_type == P_SLICE ? AV_PICTURE_TYPE_P :
+ AV_PICTURE_TYPE_I;
+
+ if (h->pps->output_flag_present_flag)
+ sh->pic_output_flag = get_bits1(gb);
+
+ if (h->sps->separate_colour_plane_flag)
+ sh->colour_plane_id = get_bits(gb, 2);
+
+ if (!IS_IDR(h)) {
+ sh->pic_order_cnt_lsb = get_bits(gb, h->sps->log2_max_poc_lsb);
+ s->output_picture_number = h->poc = ff_hevc_compute_poc(h, sh->pic_order_cnt_lsb);
+ } else
+ s->output_picture_number = h->poc = 0;
+
+ if (h->temporal_id == 0 &&
+ h->nal_unit_type != NAL_TRAIL_N &&
+ h->nal_unit_type != NAL_TSA_N &&
+ h->nal_unit_type != NAL_STSA_N &&
+ h->nal_unit_type != NAL_RADL_N &&
+ h->nal_unit_type != NAL_RASL_N &&
+ h->nal_unit_type != NAL_RADL_R &&
+ h->nal_unit_type != NAL_RASL_R)
+ h->pocTid0 = h->poc;
+
+ return 0; /* no need to evaluate the rest */
+ }
+ buf += consumed;
+ }
+ /* didn't find a picture! */
+ av_log(h->avctx, AV_LOG_ERROR, "missing picture in access unit\n");
+ return -1;
+}
+
+static int hevc_parse(AVCodecParserContext *s,
+ AVCodecContext *avctx,
+ const uint8_t **poutbuf, int *poutbuf_size,
+ const uint8_t *buf, int buf_size)
+{
+ int next;
+ ParseContext *pc = &((HEVCParseContext *)s->priv_data)->pc;
+
+ if (s->flags & PARSER_FLAG_COMPLETE_FRAMES) {
+ next = buf_size;
+ } else {
+ next = hevc_find_frame_end(s, buf, buf_size);
+ if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) {
+ *poutbuf = NULL;
+ *poutbuf_size = 0;
+ return buf_size;
+ }
+ }
+
+ parse_nal_units(s, avctx, buf, buf_size);
+
+ *poutbuf = buf;
+ *poutbuf_size = buf_size;
+ return next;
+}
+
+// Split after the parameter sets at the beginning of the stream if they exist.
+static int hevc_split(AVCodecContext *avctx, const uint8_t *buf, int buf_size)
+{
+ int i;
+ uint32_t state = -1;
+ int has_ps = 0;
+
+ for (i = 0; i < buf_size; i++) {
+ state = (state << 8) | buf[i];
+ if (((state >> 8) & 0xFFFFFF) == START_CODE) {
+ int nut = (state >> 1) & 0x3F;
+ if (nut >= NAL_VPS && nut <= NAL_PPS)
+ has_ps = 1;
+ else if (has_ps)
+ return i - 3;
+ else // no parameter set at the beginning of the stream
+ return 0;
+ }
+ }
+ return 0;
+}
+
+static int hevc_init(AVCodecParserContext *s)
+{
+ HEVCContext *h = &((HEVCParseContext *)s->priv_data)->h;
+ h->HEVClc = av_mallocz(sizeof(HEVCLocalContext));
+ h->skipped_bytes_pos_size = INT_MAX;
+
+ return 0;
+}
+
+static void hevc_close(AVCodecParserContext *s)
+{
+ int i;
+ HEVCContext *h = &((HEVCParseContext *)s->priv_data)->h;
+ ParseContext *pc = &((HEVCParseContext *)s->priv_data)->pc;
+
+ av_freep(&h->skipped_bytes_pos);
+ av_freep(&h->HEVClc);
+ av_freep(&pc->buffer);
+
+ for (i = 0; i < FF_ARRAY_ELEMS(h->vps_list); i++)
+ av_buffer_unref(&h->vps_list[i]);
+ for (i = 0; i < FF_ARRAY_ELEMS(h->sps_list); i++)
+ av_buffer_unref(&h->sps_list[i]);
+ for (i = 0; i < FF_ARRAY_ELEMS(h->pps_list); i++)
+ av_buffer_unref(&h->pps_list[i]);
+
+ for (i = 0; i < h->nals_allocated; i++)
+ av_freep(&h->nals[i].rbsp_buffer);
+ av_freep(&h->nals);
+ h->nals_allocated = 0;
+}
+
+AVCodecParser ff_hevc_parser = {
+ .codec_ids = { AV_CODEC_ID_HEVC },
+ .priv_data_size = sizeof(HEVCParseContext),
+ .parser_init = hevc_init,
+ .parser_parse = hevc_parse,
+ .parser_close = hevc_close,
+ .split = hevc_split,
+};
diff --git a/libavcodec/hevc_ps.c b/libavcodec/hevc_ps.c
new file mode 100644
index 0000000..16eeab4
--- /dev/null
+++ b/libavcodec/hevc_ps.c
@@ -0,0 +1,1338 @@
+/*
+ * HEVC Parameter Set decoding
+ *
+ * Copyright (C) 2012 - 2103 Guillaume Martres
+ * Copyright (C) 2012 - 2103 Mickael Raulet
+ * Copyright (C) 2012 - 2013 Gildas Cocherel
+ * Copyright (C) 2013 Vittorio Giovara
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "libavutil/imgutils.h"
+#include "golomb.h"
+#include "hevc.h"
+
+static const uint8_t default_scaling_list_intra[] = {
+ 16, 16, 16, 16, 17, 18, 21, 24,
+ 16, 16, 16, 16, 17, 19, 22, 25,
+ 16, 16, 17, 18, 20, 22, 25, 29,
+ 16, 16, 18, 21, 24, 27, 31, 36,
+ 17, 17, 20, 24, 30, 35, 41, 47,
+ 18, 19, 22, 27, 35, 44, 54, 65,
+ 21, 22, 25, 31, 41, 54, 70, 88,
+ 24, 25, 29, 36, 47, 65, 88, 115
+};
+
+static const uint8_t default_scaling_list_inter[] = {
+ 16, 16, 16, 16, 17, 18, 20, 24,
+ 16, 16, 16, 17, 18, 20, 24, 25,
+ 16, 16, 17, 18, 20, 24, 25, 28,
+ 16, 17, 18, 20, 24, 25, 28, 33,
+ 17, 18, 20, 24, 25, 28, 33, 41,
+ 18, 20, 24, 25, 28, 33, 41, 54,
+ 20, 24, 25, 28, 33, 41, 54, 71,
+ 24, 25, 28, 33, 41, 54, 71, 91
+};
+
+static const AVRational vui_sar[] = {
+ { 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 },
+ { 4, 3 },
+ { 3, 2 },
+ { 2, 1 },
+};
+
+int ff_hevc_decode_short_term_rps(HEVCContext *s, ShortTermRPS *rps,
+ const HEVCSPS *sps, int is_slice_header)
+{
+ HEVCLocalContext *lc = s->HEVClc;
+ uint8_t rps_predict = 0;
+ int delta_poc;
+ int k0 = 0;
+ int k1 = 0;
+ int k = 0;
+ int i;
+
+ GetBitContext *gb = &lc->gb;
+
+ if (rps != sps->st_rps && sps->nb_st_rps)
+ rps_predict = get_bits1(gb);
+
+ if (rps_predict) {
+ const ShortTermRPS *rps_ridx;
+ int delta_rps, abs_delta_rps;
+ uint8_t use_delta_flag = 0;
+ uint8_t delta_rps_sign;
+
+ if (is_slice_header) {
+ int delta_idx = get_ue_golomb_long(gb) + 1;
+ if (delta_idx > sps->nb_st_rps) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "Invalid value of delta_idx in slice header RPS: %d > %d.\n",
+ delta_idx, sps->nb_st_rps);
+ return AVERROR_INVALIDDATA;
+ }
+ rps_ridx = &sps->st_rps[sps->nb_st_rps - delta_idx];
+ } else
+ rps_ridx = &sps->st_rps[rps - sps->st_rps - 1];
+
+ delta_rps_sign = get_bits1(gb);
+ abs_delta_rps = get_ue_golomb_long(gb) + 1;
+ delta_rps = (1 - (delta_rps_sign << 1)) * abs_delta_rps;
+ for (i = 0; i <= rps_ridx->num_delta_pocs; i++) {
+ int used = rps->used[k] = get_bits1(gb);
+
+ if (!used)
+ use_delta_flag = get_bits1(gb);
+
+ if (used || use_delta_flag) {
+ if (i < rps_ridx->num_delta_pocs)
+ delta_poc = delta_rps + rps_ridx->delta_poc[i];
+ else
+ delta_poc = delta_rps;
+ rps->delta_poc[k] = delta_poc;
+ if (delta_poc < 0)
+ k0++;
+ else
+ k1++;
+ k++;
+ }
+ }
+
+ rps->num_delta_pocs = k;
+ rps->num_negative_pics = k0;
+ // sort in increasing order (smallest first)
+ if (rps->num_delta_pocs != 0) {
+ int used, tmp;
+ for (i = 1; i < rps->num_delta_pocs; i++) {
+ delta_poc = rps->delta_poc[i];
+ used = rps->used[i];
+ for (k = i - 1; k >= 0; k--) {
+ tmp = rps->delta_poc[k];
+ if (delta_poc < tmp) {
+ rps->delta_poc[k + 1] = tmp;
+ rps->used[k + 1] = rps->used[k];
+ rps->delta_poc[k] = delta_poc;
+ rps->used[k] = used;
+ }
+ }
+ }
+ }
+ if ((rps->num_negative_pics >> 1) != 0) {
+ int used;
+ k = rps->num_negative_pics - 1;
+ // flip the negative values to largest first
+ for (i = 0; i < rps->num_negative_pics >> 1; i++) {
+ delta_poc = rps->delta_poc[i];
+ used = rps->used[i];
+ rps->delta_poc[i] = rps->delta_poc[k];
+ rps->used[i] = rps->used[k];
+ rps->delta_poc[k] = delta_poc;
+ rps->used[k] = used;
+ k--;
+ }
+ }
+ } else {
+ unsigned int prev, nb_positive_pics;
+ rps->num_negative_pics = get_ue_golomb_long(gb);
+ nb_positive_pics = get_ue_golomb_long(gb);
+
+ if (rps->num_negative_pics >= MAX_REFS ||
+ nb_positive_pics >= MAX_REFS) {
+ av_log(s->avctx, AV_LOG_ERROR, "Too many refs in a short term RPS.\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ rps->num_delta_pocs = rps->num_negative_pics + nb_positive_pics;
+ if (rps->num_delta_pocs) {
+ prev = 0;
+ for (i = 0; i < rps->num_negative_pics; i++) {
+ delta_poc = get_ue_golomb_long(gb) + 1;
+ prev -= delta_poc;
+ rps->delta_poc[i] = prev;
+ rps->used[i] = get_bits1(gb);
+ }
+ prev = 0;
+ for (i = 0; i < nb_positive_pics; i++) {
+ delta_poc = get_ue_golomb_long(gb) + 1;
+ prev += delta_poc;
+ rps->delta_poc[rps->num_negative_pics + i] = prev;
+ rps->used[rps->num_negative_pics + i] = get_bits1(gb);
+ }
+ }
+ }
+ return 0;
+}
+
+
+static int decode_profile_tier_level(HEVCContext *s, ProfileTierLevel *ptl)
+{
+ int i;
+ HEVCLocalContext *lc = s->HEVClc;
+ GetBitContext *gb = &lc->gb;
+
+ ptl->profile_space = get_bits(gb, 2);
+ ptl->tier_flag = get_bits1(gb);
+ ptl->profile_idc = get_bits(gb, 5);
+ if (ptl->profile_idc == 1)
+ av_log(s->avctx, AV_LOG_DEBUG, "Main profile bitstream\n");
+ else if (ptl->profile_idc == 2)
+ av_log(s->avctx, AV_LOG_DEBUG, "Main10 profile bitstream\n");
+ else
+ av_log(s->avctx, AV_LOG_WARNING, "No profile indication! (%d)\n", ptl->profile_idc);
+
+ for (i = 0; i < 32; i++)
+ ptl->profile_compatibility_flag[i] = get_bits1(gb);
+ ptl->progressive_source_flag = get_bits1(gb);
+ ptl->interlaced_source_flag = get_bits1(gb);
+ ptl->non_packed_constraint_flag = get_bits1(gb);
+ ptl->frame_only_constraint_flag = get_bits1(gb);
+ if (get_bits(gb, 16) != 0) // XXX_reserved_zero_44bits[0..15]
+ return -1;
+ if (get_bits(gb, 16) != 0) // XXX_reserved_zero_44bits[16..31]
+ return -1;
+ if (get_bits(gb, 12) != 0) // XXX_reserved_zero_44bits[32..43]
+ return -1;
+ ptl->level_idc = get_bits(gb, 8);
+ return 0;
+}
+
+static int parse_ptl(HEVCContext *s, PTL *ptl, int max_num_sub_layers)
+{
+ int i;
+ HEVCLocalContext *lc = s->HEVClc;
+ GetBitContext *gb = &lc->gb;
+ decode_profile_tier_level(s, &ptl->general_PTL);
+
+ for (i = 0; i < max_num_sub_layers - 1; i++) {
+ ptl->sub_layer_profile_present_flag[i] = get_bits1(gb);
+ ptl->sub_layer_level_present_flag[i] = get_bits1(gb);
+ }
+ if (max_num_sub_layers - 1> 0)
+ for (i = max_num_sub_layers - 1; i < 8; i++)
+ skip_bits(gb, 2); // reserved_zero_2bits[i]
+ for (i = 0; i < max_num_sub_layers - 1; i++) {
+ if (ptl->sub_layer_profile_present_flag[i]) {
+ decode_profile_tier_level(s, &ptl->sub_layer_PTL[i]);
+ ptl->sub_layer_PTL[i].level_idc = get_bits(gb, 8);
+ }
+ }
+ return 0;
+}
+
+static void decode_sublayer_hrd(HEVCContext *s, int nb_cpb,
+ int subpic_params_present)
+{
+ GetBitContext *gb = &s->HEVClc->gb;
+ int i;
+
+ for (i = 0; i < nb_cpb; i++) {
+ get_ue_golomb_long(gb); // bit_rate_value_minus1
+ get_ue_golomb_long(gb); // cpb_size_value_minus1
+
+ if (subpic_params_present) {
+ get_ue_golomb_long(gb); // cpb_size_du_value_minus1
+ get_ue_golomb_long(gb); // bit_rate_du_value_minus1
+ }
+ skip_bits1(gb); // cbr_flag
+ }
+}
+
+static void decode_hrd(HEVCContext *s, int common_inf_present,
+ int max_sublayers)
+{
+ GetBitContext *gb = &s->HEVClc->gb;
+ int nal_params_present = 0, vcl_params_present = 0;
+ int subpic_params_present = 0;
+ int i;
+
+ if (common_inf_present) {
+ nal_params_present = get_bits1(gb);
+ vcl_params_present = get_bits1(gb);
+
+ if (nal_params_present || vcl_params_present) {
+ subpic_params_present = get_bits1(gb);
+
+ if (subpic_params_present) {
+ skip_bits(gb, 8); // tick_divisor_minus2
+ skip_bits(gb, 5); // du_cpb_removal_delay_increment_length_minus1
+ skip_bits(gb, 1); // sub_pic_cpb_params_in_pic_timing_sei_flag
+ skip_bits(gb, 5); // dpb_output_delay_du_length_minus1
+ }
+
+ skip_bits(gb, 4); // bit_rate_scale
+ skip_bits(gb, 4); // cpb_size_scale
+
+ if (subpic_params_present)
+ skip_bits(gb, 4); // cpb_size_du_scale
+
+ skip_bits(gb, 5); // initial_cpb_removal_delay_length_minus1
+ skip_bits(gb, 5); // au_cpb_removal_delay_length_minus1
+ skip_bits(gb, 5); // dpb_output_delay_length_minus1
+ }
+ }
+
+ for (i = 0; i < max_sublayers; i++) {
+ int low_delay = 0;
+ int nb_cpb = 1;
+ int fixed_rate = get_bits1(gb);
+
+ if (!fixed_rate)
+ fixed_rate = get_bits1(gb);
+
+ if (fixed_rate)
+ get_ue_golomb_long(gb); // elemental_duration_in_tc_minus1
+ else
+ low_delay = get_bits1(gb);
+
+ if (!low_delay)
+ nb_cpb = get_ue_golomb_long(gb) + 1;
+
+ if (nal_params_present)
+ decode_sublayer_hrd(s, nb_cpb, subpic_params_present);
+ if (vcl_params_present)
+ decode_sublayer_hrd(s, nb_cpb, subpic_params_present);
+ }
+}
+
+int ff_hevc_decode_nal_vps(HEVCContext *s)
+{
+ int i,j;
+ GetBitContext *gb = &s->HEVClc->gb;
+ int vps_id = 0;
+ HEVCVPS *vps;
+ AVBufferRef *vps_buf = av_buffer_allocz(sizeof(*vps));
+
+ if (!vps_buf)
+ return AVERROR(ENOMEM);
+ vps = (HEVCVPS*)vps_buf->data;
+
+ av_log(s->avctx, AV_LOG_DEBUG, "Decoding VPS\n");
+
+ if (!vps)
+ return AVERROR(ENOMEM);
+
+ vps_id = get_bits(gb, 4);
+ if (vps_id >= MAX_VPS_COUNT) {
+ av_log(s->avctx, AV_LOG_ERROR, "VPS id out of range: %d\n", vps_id);
+ goto err;
+ }
+
+ if (get_bits(gb, 2) != 3) { // vps_reserved_three_2bits
+ av_log(s->avctx, AV_LOG_ERROR, "vps_reserved_three_2bits is not three\n");
+ goto err;
+ }
+
+ vps->vps_max_layers = get_bits(gb, 6) + 1;
+ vps->vps_max_sub_layers = get_bits(gb, 3) + 1;
+ vps->vps_temporal_id_nesting_flag = get_bits1(gb);
+
+ if (get_bits(gb, 16) != 0xffff) { // vps_reserved_ffff_16bits
+ av_log(s->avctx, AV_LOG_ERROR, "vps_reserved_ffff_16bits is not 0xffff\n");
+ goto err;
+ }
+
+ if (vps->vps_max_sub_layers > MAX_SUB_LAYERS) {
+ av_log(s->avctx, AV_LOG_ERROR, "vps_max_sub_layers out of range: %d\n",
+ vps->vps_max_sub_layers);
+ goto err;
+ }
+
+ if (parse_ptl(s, &vps->ptl, vps->vps_max_sub_layers) < 0) {
+ av_log(s->avctx, AV_LOG_ERROR, "Error decoding profile tier level.\n");
+ goto err;
+ }
+ vps->vps_sub_layer_ordering_info_present_flag = get_bits1(gb);
+
+ i = vps->vps_sub_layer_ordering_info_present_flag ? 0 : vps->vps_max_sub_layers - 1;
+ for (; i < vps->vps_max_sub_layers; i++) {
+ vps->vps_max_dec_pic_buffering[i] = get_ue_golomb_long(gb) + 1;
+ vps->vps_num_reorder_pics[i] = get_ue_golomb_long(gb);
+ vps->vps_max_latency_increase[i] = get_ue_golomb_long(gb) - 1;
+
+ if (vps->vps_max_dec_pic_buffering[i] > MAX_DPB_SIZE) {
+ av_log(s->avctx, AV_LOG_ERROR, "vps_max_dec_pic_buffering_minus1 out of range: %d\n",
+ vps->vps_max_dec_pic_buffering[i] - 1);
+ goto err;
+ }
+ if (vps->vps_num_reorder_pics[i] > vps->vps_max_dec_pic_buffering[i] - 1) {
+ av_log(s->avctx, AV_LOG_ERROR, "vps_max_num_reorder_pics out of range: %d\n",
+ vps->vps_num_reorder_pics[i]);
+ goto err;
+ }
+ }
+
+ vps->vps_max_layer_id = get_bits(gb, 6);
+ vps->vps_num_layer_sets = get_ue_golomb_long(gb) + 1;
+ for (i = 1; i < vps->vps_num_layer_sets; i++)
+ for (j = 0; j <= vps->vps_max_layer_id; j++)
+ skip_bits(gb, 1); // layer_id_included_flag[i][j]
+
+ vps->vps_timing_info_present_flag = get_bits1(gb);
+ if (vps->vps_timing_info_present_flag) {
+ vps->vps_num_units_in_tick = get_bits_long(gb, 32);
+ vps->vps_time_scale = get_bits_long(gb, 32);
+ vps->vps_poc_proportional_to_timing_flag = get_bits1(gb);
+ if (vps->vps_poc_proportional_to_timing_flag)
+ vps->vps_num_ticks_poc_diff_one = get_ue_golomb_long(gb) + 1;
+ vps->vps_num_hrd_parameters = get_ue_golomb_long(gb);
+ for (i = 0; i < vps->vps_num_hrd_parameters; i++) {
+ int common_inf_present = 1;
+
+ get_ue_golomb_long(gb); // hrd_layer_set_idx
+ if (i)
+ common_inf_present = get_bits1(gb);
+ decode_hrd(s, common_inf_present, vps->vps_max_sub_layers);
+ }
+ }
+
+ vps->vps_extension_flag = get_bits1(gb);
+
+ av_buffer_unref(&s->vps_list[vps_id]);
+ s->vps_list[vps_id] = vps_buf;
+
+ return 0;
+
+err:
+ av_buffer_unref(&vps_buf);
+ return AVERROR_INVALIDDATA;
+}
+
+static void decode_vui(HEVCContext *s, HEVCSPS *sps)
+{
+ VUI *vui = &sps->vui;
+ GetBitContext *gb = &s->HEVClc->gb;
+ int sar_present;
+
+ av_log(s->avctx, AV_LOG_DEBUG, "Decoding VUI\n");
+
+ sar_present = get_bits1(gb);
+ if (sar_present) {
+ uint8_t sar_idx = get_bits(gb, 8);
+ if (sar_idx < FF_ARRAY_ELEMS(vui_sar))
+ vui->sar = vui_sar[sar_idx];
+ else if (sar_idx == 255) {
+ vui->sar.num = get_bits(gb, 16);
+ vui->sar.den = get_bits(gb, 16);
+ } else
+ av_log(s->avctx, AV_LOG_WARNING,
+ "Unknown SAR index: %u.\n", sar_idx);
+ }
+
+ vui->overscan_info_present_flag = get_bits1(gb);
+ if (vui->overscan_info_present_flag)
+ vui->overscan_appropriate_flag = get_bits1(gb);
+
+ vui->video_signal_type_present_flag = get_bits1(gb);
+ if (vui->video_signal_type_present_flag) {
+ vui->video_format = get_bits(gb, 3);
+ vui->video_full_range_flag = get_bits1(gb);
+ vui->colour_description_present_flag = get_bits1(gb);
+ if (vui->video_full_range_flag && sps->pix_fmt == AV_PIX_FMT_YUV420P)
+ sps->pix_fmt = AV_PIX_FMT_YUVJ420P;
+ if (vui->colour_description_present_flag) {
+ vui->colour_primaries = get_bits(gb, 8);
+ vui->transfer_characteristic = get_bits(gb, 8);
+ vui->matrix_coeffs = get_bits(gb, 8);
+
+ // Set invalid values to "unspecified"
+ if (vui->colour_primaries >= AVCOL_PRI_NB)
+ vui->colour_primaries = AVCOL_PRI_UNSPECIFIED;
+ if (vui->transfer_characteristic >= AVCOL_TRC_NB)
+ vui->transfer_characteristic = AVCOL_TRC_UNSPECIFIED;
+ if (vui->matrix_coeffs >= AVCOL_SPC_NB)
+ vui->matrix_coeffs = AVCOL_SPC_UNSPECIFIED;
+ }
+ }
+
+ vui->chroma_loc_info_present_flag = get_bits1(gb);
+ if (vui->chroma_loc_info_present_flag) {
+ vui->chroma_sample_loc_type_top_field = get_ue_golomb_long(gb);
+ vui->chroma_sample_loc_type_bottom_field = get_ue_golomb_long(gb);
+ }
+
+ vui->neutra_chroma_indication_flag = get_bits1(gb);
+ vui->field_seq_flag = get_bits1(gb);
+ vui->frame_field_info_present_flag = get_bits1(gb);
+
+ vui->default_display_window_flag = get_bits1(gb);
+ if (vui->default_display_window_flag) {
+ //TODO: * 2 is only valid for 420
+ vui->def_disp_win.left_offset = get_ue_golomb_long(gb) * 2;
+ vui->def_disp_win.right_offset = get_ue_golomb_long(gb) * 2;
+ vui->def_disp_win.top_offset = get_ue_golomb_long(gb) * 2;
+ vui->def_disp_win.bottom_offset = get_ue_golomb_long(gb) * 2;
+
+ if (s->apply_defdispwin &&
+ s->avctx->flags2 & CODEC_FLAG2_IGNORE_CROP) {
+ av_log(s->avctx, AV_LOG_DEBUG,
+ "discarding vui default display window, "
+ "original values are l:%u r:%u t:%u b:%u\n",
+ vui->def_disp_win.left_offset,
+ vui->def_disp_win.right_offset,
+ vui->def_disp_win.top_offset,
+ vui->def_disp_win.bottom_offset);
+
+ vui->def_disp_win.left_offset =
+ vui->def_disp_win.right_offset =
+ vui->def_disp_win.top_offset =
+ vui->def_disp_win.bottom_offset = 0;
+ }
+ }
+
+ vui->vui_timing_info_present_flag = get_bits1(gb);
+
+ if (vui->vui_timing_info_present_flag) {
+ vui->vui_num_units_in_tick = get_bits(gb, 32);
+ vui->vui_time_scale = get_bits(gb, 32);
+ s->avctx->time_base.num = vui->vui_num_units_in_tick;
+ s->avctx->time_base.den = vui->vui_time_scale;
+ vui->vui_poc_proportional_to_timing_flag = get_bits1(gb);
+ if (vui->vui_poc_proportional_to_timing_flag)
+ vui->vui_num_ticks_poc_diff_one_minus1 = get_ue_golomb_long(gb);
+ vui->vui_hrd_parameters_present_flag = get_bits1(gb);
+ if (vui->vui_hrd_parameters_present_flag)
+ decode_hrd(s, 1, sps->max_sub_layers);
+ }
+
+ vui->bitstream_restriction_flag = get_bits1(gb);
+ if (vui->bitstream_restriction_flag) {
+ vui->tiles_fixed_structure_flag = get_bits1(gb);
+ vui->motion_vectors_over_pic_boundaries_flag = get_bits1(gb);
+ vui->restricted_ref_pic_lists_flag = get_bits1(gb);
+ vui->min_spatial_segmentation_idc = get_ue_golomb_long(gb);
+ vui->max_bytes_per_pic_denom = get_ue_golomb_long(gb);
+ vui->max_bits_per_min_cu_denom = get_ue_golomb_long(gb);
+ vui->log2_max_mv_length_horizontal = get_ue_golomb_long(gb);
+ vui->log2_max_mv_length_vertical = get_ue_golomb_long(gb);
+ }
+}
+
+static void set_default_scaling_list_data(ScalingList *sl)
+{
+ int matrixId;
+
+ for (matrixId = 0; matrixId < 6; matrixId++) {
+ // 4x4 default is 16
+ memset(sl->sl[0][matrixId], 16, 16);
+ sl->sl_dc[0][matrixId] = 16; // default for 16x16
+ sl->sl_dc[1][matrixId] = 16; // default for 32x32
+ }
+ memcpy(sl->sl[1][0], default_scaling_list_intra, 64);
+ memcpy(sl->sl[1][1], default_scaling_list_intra, 64);
+ memcpy(sl->sl[1][2], default_scaling_list_intra, 64);
+ memcpy(sl->sl[1][3], default_scaling_list_inter, 64);
+ memcpy(sl->sl[1][4], default_scaling_list_inter, 64);
+ memcpy(sl->sl[1][5], default_scaling_list_inter, 64);
+ memcpy(sl->sl[2][0], default_scaling_list_intra, 64);
+ memcpy(sl->sl[2][1], default_scaling_list_intra, 64);
+ memcpy(sl->sl[2][2], default_scaling_list_intra, 64);
+ memcpy(sl->sl[2][3], default_scaling_list_inter, 64);
+ memcpy(sl->sl[2][4], default_scaling_list_inter, 64);
+ memcpy(sl->sl[2][5], default_scaling_list_inter, 64);
+ memcpy(sl->sl[3][0], default_scaling_list_intra, 64);
+ memcpy(sl->sl[3][1], default_scaling_list_inter, 64);
+}
+
+static int scaling_list_data(HEVCContext *s, ScalingList *sl)
+{
+ GetBitContext *gb = &s->HEVClc->gb;
+ uint8_t scaling_list_pred_mode_flag[4][6];
+ int32_t scaling_list_dc_coef[2][6];
+ int size_id, matrix_id, i, pos, delta;
+
+ for (size_id = 0; size_id < 4; size_id++)
+ for (matrix_id = 0; matrix_id < (size_id == 3 ? 2 : 6); matrix_id++) {
+ scaling_list_pred_mode_flag[size_id][matrix_id] = get_bits1(gb);
+ if (!scaling_list_pred_mode_flag[size_id][matrix_id]) {
+ delta = get_ue_golomb_long(gb);
+ /* Only need to handle non-zero delta. Zero means default,
+ * which should already be in the arrays. */
+ if (delta) {
+ // Copy from previous array.
+ if (matrix_id - delta < 0) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "Invalid delta in scaling list data: %d.\n", delta);
+ return AVERROR_INVALIDDATA;
+ }
+
+ memcpy(sl->sl[size_id][matrix_id],
+ sl->sl[size_id][matrix_id - delta],
+ size_id > 0 ? 64 : 16);
+ if (size_id > 1)
+ sl->sl_dc[size_id - 2][matrix_id] = sl->sl_dc[size_id - 2][matrix_id - delta];
+ }
+ } else {
+ int next_coef, coef_num;
+ int32_t scaling_list_delta_coef;
+
+ next_coef = 8;
+ coef_num = FFMIN(64, 1 << (4 + (size_id << 1)));
+ if (size_id > 1) {
+ scaling_list_dc_coef[size_id - 2][matrix_id] = get_se_golomb(gb) + 8;
+ next_coef = scaling_list_dc_coef[size_id - 2][matrix_id];
+ sl->sl_dc[size_id - 2][matrix_id] = next_coef;
+ }
+ for (i = 0; i < coef_num; i++) {
+ if (size_id == 0)
+ pos = 4 * ff_hevc_diag_scan4x4_y[i] +
+ ff_hevc_diag_scan4x4_x[i];
+ else
+ pos = 8 * ff_hevc_diag_scan8x8_y[i] +
+ ff_hevc_diag_scan8x8_x[i];
+
+ scaling_list_delta_coef = get_se_golomb(gb);
+ next_coef = (next_coef + scaling_list_delta_coef + 256) % 256;
+ sl->sl[size_id][matrix_id][pos] = next_coef;
+ }
+ }
+ }
+
+ return 0;
+}
+
+int ff_hevc_decode_nal_sps(HEVCContext *s)
+{
+ const AVPixFmtDescriptor *desc;
+ GetBitContext *gb = &s->HEVClc->gb;
+ int ret = 0;
+ int sps_id = 0;
+ int log2_diff_max_min_transform_block_size;
+ int bit_depth_chroma, start, vui_present, sublayer_ordering_info;
+ int i;
+
+ HEVCSPS *sps;
+ AVBufferRef *sps_buf = av_buffer_allocz(sizeof(*sps));
+
+ if (!sps_buf)
+ return AVERROR(ENOMEM);
+ sps = (HEVCSPS*)sps_buf->data;
+
+ av_log(s->avctx, AV_LOG_DEBUG, "Decoding SPS\n");
+
+ // Coded parameters
+
+ sps->vps_id = get_bits(gb, 4);
+ if (sps->vps_id >= MAX_VPS_COUNT) {
+ av_log(s->avctx, AV_LOG_ERROR, "VPS id out of range: %d\n", sps->vps_id);
+ ret = AVERROR_INVALIDDATA;
+ goto err;
+ }
+
+ sps->max_sub_layers = get_bits(gb, 3) + 1;
+ if (sps->max_sub_layers > MAX_SUB_LAYERS) {
+ av_log(s->avctx, AV_LOG_ERROR, "sps_max_sub_layers out of range: %d\n",
+ sps->max_sub_layers);
+ ret = AVERROR_INVALIDDATA;
+ goto err;
+ }
+
+ skip_bits1(gb); // temporal_id_nesting_flag
+
+ if (parse_ptl(s, &sps->ptl, sps->max_sub_layers) < 0) {
+ av_log(s->avctx, AV_LOG_ERROR, "error decoding profile tier level\n");
+ ret = AVERROR_INVALIDDATA;
+ goto err;
+ }
+ sps_id = get_ue_golomb_long(gb);
+ if (sps_id >= MAX_SPS_COUNT) {
+ av_log(s->avctx, AV_LOG_ERROR, "SPS id out of range: %d\n", sps_id);
+ ret = AVERROR_INVALIDDATA;
+ goto err;
+ }
+
+ sps->chroma_format_idc = get_ue_golomb_long(gb);
+ if (sps->chroma_format_idc != 1) {
+ avpriv_report_missing_feature(s->avctx, "chroma_format_idc != 1\n");
+ ret = AVERROR_PATCHWELCOME;
+ goto err;
+ }
+
+ if (sps->chroma_format_idc == 3)
+ sps->separate_colour_plane_flag = get_bits1(gb);
+
+ sps->width = get_ue_golomb_long(gb);
+ sps->height = get_ue_golomb_long(gb);
+ if ((ret = av_image_check_size(sps->width,
+ sps->height, 0, s->avctx)) < 0)
+ goto err;
+
+ if (get_bits1(gb)) { // pic_conformance_flag
+ //TODO: * 2 is only valid for 420
+ sps->pic_conf_win.left_offset = get_ue_golomb_long(gb) * 2;
+ sps->pic_conf_win.right_offset = get_ue_golomb_long(gb) * 2;
+ sps->pic_conf_win.top_offset = get_ue_golomb_long(gb) * 2;
+ sps->pic_conf_win.bottom_offset = get_ue_golomb_long(gb) * 2;
+
+ if (s->avctx->flags2 & CODEC_FLAG2_IGNORE_CROP) {
+ av_log(s->avctx, AV_LOG_DEBUG,
+ "discarding sps conformance window, "
+ "original values are l:%u r:%u t:%u b:%u\n",
+ sps->pic_conf_win.left_offset,
+ sps->pic_conf_win.right_offset,
+ sps->pic_conf_win.top_offset,
+ sps->pic_conf_win.bottom_offset);
+
+ sps->pic_conf_win.left_offset =
+ sps->pic_conf_win.right_offset =
+ sps->pic_conf_win.top_offset =
+ sps->pic_conf_win.bottom_offset = 0;
+ }
+ sps->output_window = sps->pic_conf_win;
+ }
+
+ sps->bit_depth = get_ue_golomb_long(gb) + 8;
+ bit_depth_chroma = get_ue_golomb_long(gb) + 8;
+ if (bit_depth_chroma != sps->bit_depth) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "Luma bit depth (%d) is different from chroma bit depth (%d), "
+ "this is unsupported.\n",
+ sps->bit_depth, bit_depth_chroma);
+ ret = AVERROR_INVALIDDATA;
+ goto err;
+ }
+
+ if (sps->chroma_format_idc == 1) {
+ switch (sps->bit_depth) {
+ case 8: sps->pix_fmt = AV_PIX_FMT_YUV420P; break;
+ case 9: sps->pix_fmt = AV_PIX_FMT_YUV420P9; break;
+ case 10: sps->pix_fmt = AV_PIX_FMT_YUV420P10; break;
+ default:
+ av_log(s->avctx, AV_LOG_ERROR, "Unsupported bit depth: %d\n",
+ sps->bit_depth);
+ ret = AVERROR_PATCHWELCOME;
+ goto err;
+ }
+ } else {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "non-4:2:0 support is currently unspecified.\n");
+ return AVERROR_PATCHWELCOME;
+ }
+
+ desc = av_pix_fmt_desc_get(sps->pix_fmt);
+ if (!desc) {
+ ret = AVERROR(EINVAL);
+ goto err;
+ }
+
+ sps->hshift[0] = sps->vshift[0] = 0;
+ sps->hshift[2] = sps->hshift[1] = desc->log2_chroma_w;
+ sps->vshift[2] = sps->vshift[1] = desc->log2_chroma_h;
+
+ sps->pixel_shift = sps->bit_depth > 8;
+
+ sps->log2_max_poc_lsb = get_ue_golomb_long(gb) + 4;
+ if (sps->log2_max_poc_lsb > 16) {
+ av_log(s->avctx, AV_LOG_ERROR, "log2_max_pic_order_cnt_lsb_minus4 out range: %d\n",
+ sps->log2_max_poc_lsb - 4);
+ ret = AVERROR_INVALIDDATA;
+ goto err;
+ }
+
+ sublayer_ordering_info = get_bits1(gb);
+ start = sublayer_ordering_info ? 0 : sps->max_sub_layers - 1;
+ for (i = start; i < sps->max_sub_layers; i++) {
+ sps->temporal_layer[i].max_dec_pic_buffering = get_ue_golomb_long(gb) + 1;
+ sps->temporal_layer[i].num_reorder_pics = get_ue_golomb_long(gb);
+ sps->temporal_layer[i].max_latency_increase = get_ue_golomb_long(gb) - 1;
+ if (sps->temporal_layer[i].max_dec_pic_buffering > MAX_DPB_SIZE) {
+ av_log(s->avctx, AV_LOG_ERROR, "sps_max_dec_pic_buffering_minus1 out of range: %d\n",
+ sps->temporal_layer[i].max_dec_pic_buffering - 1);
+ ret = AVERROR_INVALIDDATA;
+ goto err;
+ }
+ if (sps->temporal_layer[i].num_reorder_pics > sps->temporal_layer[i].max_dec_pic_buffering - 1) {
+ av_log(s->avctx, AV_LOG_ERROR, "sps_max_num_reorder_pics out of range: %d\n",
+ sps->temporal_layer[i].num_reorder_pics);
+ ret = AVERROR_INVALIDDATA;
+ goto err;
+ }
+ }
+
+ if (!sublayer_ordering_info) {
+ for (i = 0; i < start; i++) {
+ sps->temporal_layer[i].max_dec_pic_buffering = sps->temporal_layer[start].max_dec_pic_buffering;
+ sps->temporal_layer[i].num_reorder_pics = sps->temporal_layer[start].num_reorder_pics;
+ sps->temporal_layer[i].max_latency_increase = sps->temporal_layer[start].max_latency_increase;
+ }
+ }
+
+ sps->log2_min_cb_size = get_ue_golomb_long(gb) + 3;
+ sps->log2_diff_max_min_coding_block_size = get_ue_golomb_long(gb);
+ sps->log2_min_tb_size = get_ue_golomb_long(gb) + 2;
+ log2_diff_max_min_transform_block_size = get_ue_golomb_long(gb);
+ sps->log2_max_trafo_size = log2_diff_max_min_transform_block_size +
+ sps->log2_min_tb_size;
+
+ if (sps->log2_min_tb_size >= sps->log2_min_cb_size) {
+ av_log(s->avctx, AV_LOG_ERROR, "Invalid value for log2_min_tb_size");
+ ret = AVERROR_INVALIDDATA;
+ goto err;
+ }
+ sps->max_transform_hierarchy_depth_inter = get_ue_golomb_long(gb);
+ sps->max_transform_hierarchy_depth_intra = get_ue_golomb_long(gb);
+
+ sps->scaling_list_enable_flag = get_bits1(gb);
+ if (sps->scaling_list_enable_flag) {
+ set_default_scaling_list_data(&sps->scaling_list);
+
+ if (get_bits1(gb)) {
+ ret = scaling_list_data(s, &sps->scaling_list);
+ if (ret < 0)
+ goto err;
+ }
+ }
+
+ sps->amp_enabled_flag = get_bits1(gb);
+ sps->sao_enabled = get_bits1(gb);
+
+ sps->pcm_enabled_flag = get_bits1(gb);
+ if (sps->pcm_enabled_flag) {
+ sps->pcm.bit_depth = get_bits(gb, 4) + 1;
+ sps->pcm.bit_depth_chroma = get_bits(gb, 4) + 1;
+ sps->pcm.log2_min_pcm_cb_size = get_ue_golomb_long(gb) + 3;
+ sps->pcm.log2_max_pcm_cb_size = sps->pcm.log2_min_pcm_cb_size +
+ get_ue_golomb_long(gb);
+ if (sps->pcm.bit_depth > sps->bit_depth) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "PCM bit depth (%d) is greater than normal bit depth (%d)\n",
+ sps->pcm.bit_depth, sps->bit_depth);
+ ret = AVERROR_INVALIDDATA;
+ goto err;
+ }
+
+ sps->pcm.loop_filter_disable_flag = get_bits1(gb);
+ }
+
+ sps->nb_st_rps = get_ue_golomb_long(gb);
+ if (sps->nb_st_rps > MAX_SHORT_TERM_RPS_COUNT) {
+ av_log(s->avctx, AV_LOG_ERROR, "Too many short term RPS: %d.\n",
+ sps->nb_st_rps);
+ ret = AVERROR_INVALIDDATA;
+ goto err;
+ }
+ for (i = 0; i < sps->nb_st_rps; i++) {
+ if ((ret = ff_hevc_decode_short_term_rps(s, &sps->st_rps[i],
+ sps, 0)) < 0)
+ goto err;
+ }
+
+ sps->long_term_ref_pics_present_flag = get_bits1(gb);
+ if (sps->long_term_ref_pics_present_flag) {
+ sps->num_long_term_ref_pics_sps = get_ue_golomb_long(gb);
+ for (i = 0; i < sps->num_long_term_ref_pics_sps; i++) {
+ sps->lt_ref_pic_poc_lsb_sps[i] = get_bits(gb, sps->log2_max_poc_lsb);
+ sps->used_by_curr_pic_lt_sps_flag[i] = get_bits1(gb);
+ }
+ }
+
+ sps->sps_temporal_mvp_enabled_flag = get_bits1(gb);
+ sps->sps_strong_intra_smoothing_enable_flag = get_bits1(gb);
+ sps->vui.sar = (AVRational){0, 1};
+ vui_present = get_bits1(gb);
+ if (vui_present)
+ decode_vui(s, sps);
+ skip_bits1(gb); // sps_extension_flag
+
+ if (s->apply_defdispwin) {
+ sps->output_window.left_offset += sps->vui.def_disp_win.left_offset;
+ sps->output_window.right_offset += sps->vui.def_disp_win.right_offset;
+ sps->output_window.top_offset += sps->vui.def_disp_win.top_offset;
+ sps->output_window.bottom_offset += sps->vui.def_disp_win.bottom_offset;
+ }
+ if (sps->output_window.left_offset & (0x1F >> (sps->pixel_shift)) &&
+ !(s->avctx->flags & CODEC_FLAG_UNALIGNED)) {
+ sps->output_window.left_offset &= ~(0x1F >> (sps->pixel_shift));
+ av_log(s->avctx, AV_LOG_WARNING, "Reducing left output window to %d "
+ "chroma samples to preserve alignment.\n",
+ sps->output_window.left_offset);
+ }
+ sps->output_width = sps->width -
+ (sps->output_window.left_offset + sps->output_window.right_offset);
+ sps->output_height = sps->height -
+ (sps->output_window.top_offset + sps->output_window.bottom_offset);
+ if (sps->output_width <= 0 || sps->output_height <= 0) {
+ av_log(s->avctx, AV_LOG_WARNING, "Invalid visible frame dimensions: %dx%d.\n",
+ sps->output_width, sps->output_height);
+ if (s->avctx->err_recognition & AV_EF_EXPLODE) {
+ ret = AVERROR_INVALIDDATA;
+ goto err;
+ }
+ av_log(s->avctx, AV_LOG_WARNING,
+ "Displaying the whole video surface.\n");
+ sps->pic_conf_win.left_offset =
+ sps->pic_conf_win.right_offset =
+ sps->pic_conf_win.top_offset =
+ sps->pic_conf_win.bottom_offset = 0;
+ sps->output_width = sps->width;
+ sps->output_height = sps->height;
+ }
+
+ // Inferred parameters
+ sps->log2_ctb_size = sps->log2_min_cb_size +
+ sps->log2_diff_max_min_coding_block_size;
+ sps->log2_min_pu_size = sps->log2_min_cb_size - 1;
+
+ sps->ctb_width = (sps->width + (1 << sps->log2_ctb_size) - 1) >> sps->log2_ctb_size;
+ sps->ctb_height = (sps->height + (1 << sps->log2_ctb_size) - 1) >> sps->log2_ctb_size;
+ sps->ctb_size = sps->ctb_width * sps->ctb_height;
+
+ sps->min_cb_width = sps->width >> sps->log2_min_cb_size;
+ sps->min_cb_height = sps->height >> sps->log2_min_cb_size;
+ sps->min_tb_width = sps->width >> sps->log2_min_tb_size;
+ sps->min_tb_height = sps->height >> sps->log2_min_tb_size;
+ sps->min_pu_width = sps->width >> sps->log2_min_pu_size;
+ sps->min_pu_height = sps->height >> sps->log2_min_pu_size;
+
+ sps->qp_bd_offset = 6 * (sps->bit_depth - 8);
+
+ if (sps->width & ((1 << sps->log2_min_cb_size) - 1) ||
+ sps->height & ((1 << sps->log2_min_cb_size) - 1)) {
+ av_log(s->avctx, AV_LOG_ERROR, "Invalid coded frame dimensions.\n");
+ goto err;
+ }
+
+ if (sps->log2_ctb_size > MAX_LOG2_CTB_SIZE) {
+ av_log(s->avctx, AV_LOG_ERROR, "CTB size out of range: 2^%d\n", sps->log2_ctb_size);
+ goto err;
+ }
+ if (sps->max_transform_hierarchy_depth_inter > sps->log2_ctb_size - sps->log2_min_tb_size) {
+ av_log(s->avctx, AV_LOG_ERROR, "max_transform_hierarchy_depth_inter out of range: %d\n",
+ sps->max_transform_hierarchy_depth_inter);
+ goto err;
+ }
+ if (sps->max_transform_hierarchy_depth_intra > sps->log2_ctb_size - sps->log2_min_tb_size) {
+ av_log(s->avctx, AV_LOG_ERROR, "max_transform_hierarchy_depth_intra out of range: %d\n",
+ sps->max_transform_hierarchy_depth_intra);
+ goto err;
+ }
+ if (sps->log2_max_trafo_size > FFMIN(sps->log2_ctb_size, 5)) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "max transform block size out of range: %d\n",
+ sps->log2_max_trafo_size);
+ goto err;
+ }
+
+ if (s->avctx->debug & FF_DEBUG_BITSTREAM) {
+ av_log(s->avctx, AV_LOG_DEBUG,
+ "Parsed SPS: id %d; coded wxh: %dx%d; "
+ "cropped wxh: %dx%d; pix_fmt: %s.\n",
+ sps_id, sps->width, sps->height,
+ sps->output_width, sps->output_height,
+ av_get_pix_fmt_name(sps->pix_fmt));
+ }
+
+ /* check if this is a repeat of an already parsed SPS, then keep the
+ * original one.
+ * otherwise drop all PPSes that depend on it */
+ if (s->sps_list[sps_id] &&
+ !memcmp(s->sps_list[sps_id]->data, sps_buf->data, sps_buf->size)) {
+ av_buffer_unref(&sps_buf);
+ } else {
+ for (i = 0; i < FF_ARRAY_ELEMS(s->pps_list); i++) {
+ if (s->pps_list[i] && ((HEVCPPS*)s->pps_list[i]->data)->sps_id == sps_id)
+ av_buffer_unref(&s->pps_list[i]);
+ }
+ av_buffer_unref(&s->sps_list[sps_id]);
+ s->sps_list[sps_id] = sps_buf;
+ }
+
+ return 0;
+
+err:
+ av_buffer_unref(&sps_buf);
+ return ret;
+}
+
+static void hevc_pps_free(void *opaque, uint8_t *data)
+{
+ HEVCPPS *pps = (HEVCPPS*)data;
+
+ av_freep(&pps->column_width);
+ av_freep(&pps->row_height);
+ av_freep(&pps->col_bd);
+ av_freep(&pps->row_bd);
+ av_freep(&pps->col_idxX);
+ av_freep(&pps->ctb_addr_rs_to_ts);
+ av_freep(&pps->ctb_addr_ts_to_rs);
+ av_freep(&pps->tile_pos_rs);
+ av_freep(&pps->tile_id);
+ av_freep(&pps->min_cb_addr_zs);
+ av_freep(&pps->min_tb_addr_zs);
+
+ av_freep(&pps);
+}
+
+int ff_hevc_decode_nal_pps(HEVCContext *s)
+{
+ GetBitContext *gb = &s->HEVClc->gb;
+ HEVCSPS *sps = NULL;
+ int pic_area_in_ctbs, pic_area_in_min_cbs, pic_area_in_min_tbs;
+ int log2_diff_ctb_min_tb_size;
+ int i, j, x, y, ctb_addr_rs, tile_id;
+ int ret = 0;
+ int pps_id = 0;
+
+ AVBufferRef *pps_buf;
+ HEVCPPS *pps = av_mallocz(sizeof(*pps));
+
+ if (!pps)
+ return AVERROR(ENOMEM);
+
+ pps_buf = av_buffer_create((uint8_t *)pps, sizeof(*pps),
+ hevc_pps_free, NULL, 0);
+ if (!pps_buf) {
+ av_freep(&pps);
+ return AVERROR(ENOMEM);
+ }
+
+ av_log(s->avctx, AV_LOG_DEBUG, "Decoding PPS\n");
+
+ // Default values
+ pps->loop_filter_across_tiles_enabled_flag = 1;
+ pps->num_tile_columns = 1;
+ pps->num_tile_rows = 1;
+ pps->uniform_spacing_flag = 1;
+ pps->disable_dbf = 0;
+ pps->beta_offset = 0;
+ pps->tc_offset = 0;
+
+ // Coded parameters
+ pps_id = get_ue_golomb_long(gb);
+ if (pps_id >= MAX_PPS_COUNT) {
+ av_log(s->avctx, AV_LOG_ERROR, "PPS id out of range: %d\n", pps_id);
+ ret = AVERROR_INVALIDDATA;
+ goto err;
+ }
+ pps->sps_id = get_ue_golomb_long(gb);
+ if (pps->sps_id >= MAX_SPS_COUNT) {
+ av_log(s->avctx, AV_LOG_ERROR, "SPS id out of range: %d\n", pps->sps_id);
+ ret = AVERROR_INVALIDDATA;
+ goto err;
+ }
+ if (!s->sps_list[pps->sps_id]) {
+ av_log(s->avctx, AV_LOG_ERROR, "SPS does not exist \n");
+ ret = AVERROR_INVALIDDATA;
+ goto err;
+ }
+ sps = (HEVCSPS *)s->sps_list[pps->sps_id]->data;
+
+ pps->dependent_slice_segments_enabled_flag = get_bits1(gb);
+ pps->output_flag_present_flag = get_bits1(gb);
+ pps->num_extra_slice_header_bits = get_bits(gb, 3);
+
+ pps->sign_data_hiding_flag = get_bits1(gb);
+
+ pps->cabac_init_present_flag = get_bits1(gb);
+
+ pps->num_ref_idx_l0_default_active = get_ue_golomb_long(gb) + 1;
+ pps->num_ref_idx_l1_default_active = get_ue_golomb_long(gb) + 1;
+
+ pps->pic_init_qp_minus26 = get_se_golomb(gb);
+
+ pps->constrained_intra_pred_flag = get_bits1(gb);
+ pps->transform_skip_enabled_flag = get_bits1(gb);
+
+ pps->cu_qp_delta_enabled_flag = get_bits1(gb);
+ pps->diff_cu_qp_delta_depth = 0;
+ if (pps->cu_qp_delta_enabled_flag)
+ pps->diff_cu_qp_delta_depth = get_ue_golomb_long(gb);
+
+ pps->cb_qp_offset = get_se_golomb(gb);
+ if (pps->cb_qp_offset < -12 || pps->cb_qp_offset > 12) {
+ av_log(s->avctx, AV_LOG_ERROR, "pps_cb_qp_offset out of range: %d\n",
+ pps->cb_qp_offset);
+ ret = AVERROR_INVALIDDATA;
+ goto err;
+ }
+ pps->cr_qp_offset = get_se_golomb(gb);
+ if (pps->cr_qp_offset < -12 || pps->cr_qp_offset > 12) {
+ av_log(s->avctx, AV_LOG_ERROR, "pps_cr_qp_offset out of range: %d\n",
+ pps->cr_qp_offset);
+ ret = AVERROR_INVALIDDATA;
+ goto err;
+ }
+ pps->pic_slice_level_chroma_qp_offsets_present_flag = get_bits1(gb);
+
+ pps->weighted_pred_flag = get_bits1(gb);
+ pps->weighted_bipred_flag = get_bits1(gb);
+
+ pps->transquant_bypass_enable_flag = get_bits1(gb);
+ pps->tiles_enabled_flag = get_bits1(gb);
+ pps->entropy_coding_sync_enabled_flag = get_bits1(gb);
+
+ if (pps->tiles_enabled_flag) {
+ pps->num_tile_columns = get_ue_golomb_long(gb) + 1;
+ pps->num_tile_rows = get_ue_golomb_long(gb) + 1;
+ if (pps->num_tile_columns == 0 ||
+ pps->num_tile_columns >= sps->width) {
+ av_log(s->avctx, AV_LOG_ERROR, "num_tile_columns_minus1 out of range: %d\n",
+ pps->num_tile_columns - 1);
+ ret = AVERROR_INVALIDDATA;
+ goto err;
+ }
+ if (pps->num_tile_rows == 0 ||
+ pps->num_tile_rows >= sps->height) {
+ av_log(s->avctx, AV_LOG_ERROR, "num_tile_rows_minus1 out of range: %d\n",
+ pps->num_tile_rows - 1);
+ ret = AVERROR_INVALIDDATA;
+ goto err;
+ }
+
+ pps->column_width = av_malloc_array(pps->num_tile_columns, sizeof(*pps->column_width));
+ pps->row_height = av_malloc_array(pps->num_tile_rows, sizeof(*pps->row_height));
+ if (!pps->column_width || !pps->row_height) {
+ ret = AVERROR(ENOMEM);
+ goto err;
+ }
+
+ pps->uniform_spacing_flag = get_bits1(gb);
+ if (!pps->uniform_spacing_flag) {
+ int sum = 0;
+ for (i = 0; i < pps->num_tile_columns - 1; i++) {
+ pps->column_width[i] = get_ue_golomb_long(gb) + 1;
+ sum += pps->column_width[i];
+ }
+ if (sum >= sps->ctb_width) {
+ av_log(s->avctx, AV_LOG_ERROR, "Invalid tile widths.\n");
+ ret = AVERROR_INVALIDDATA;
+ goto err;
+ }
+ pps->column_width[pps->num_tile_columns - 1] = sps->ctb_width - sum;
+
+ sum = 0;
+ for (i = 0; i < pps->num_tile_rows - 1; i++) {
+ pps->row_height[i] = get_ue_golomb_long(gb) + 1;
+ sum += pps->row_height[i];
+ }
+ if (sum >= sps->ctb_height) {
+ av_log(s->avctx, AV_LOG_ERROR, "Invalid tile heights.\n");
+ ret = AVERROR_INVALIDDATA;
+ goto err;
+ }
+ pps->row_height[pps->num_tile_rows - 1] = sps->ctb_height - sum;
+ }
+ pps->loop_filter_across_tiles_enabled_flag = get_bits1(gb);
+ }
+
+ pps->seq_loop_filter_across_slices_enabled_flag = get_bits1(gb);
+
+ pps->deblocking_filter_control_present_flag = get_bits1(gb);
+ if (pps->deblocking_filter_control_present_flag) {
+ pps->deblocking_filter_override_enabled_flag = get_bits1(gb);
+ pps->disable_dbf = get_bits1(gb);
+ if (!pps->disable_dbf) {
+ pps->beta_offset = get_se_golomb(gb) * 2;
+ pps->tc_offset = get_se_golomb(gb) * 2;
+ if (pps->beta_offset/2 < -6 || pps->beta_offset/2 > 6) {
+ av_log(s->avctx, AV_LOG_ERROR, "pps_beta_offset_div2 out of range: %d\n",
+ pps->beta_offset/2);
+ ret = AVERROR_INVALIDDATA;
+ goto err;
+ }
+ if (pps->tc_offset/2 < -6 || pps->tc_offset/2 > 6) {
+ av_log(s->avctx, AV_LOG_ERROR, "pps_tc_offset_div2 out of range: %d\n",
+ pps->tc_offset/2);
+ ret = AVERROR_INVALIDDATA;
+ goto err;
+ }
+ }
+ }
+
+ pps->scaling_list_data_present_flag = get_bits1(gb);
+ if (pps->scaling_list_data_present_flag) {
+ set_default_scaling_list_data(&pps->scaling_list);
+ ret = scaling_list_data(s, &pps->scaling_list);
+ if (ret < 0)
+ goto err;
+ }
+ pps->lists_modification_present_flag = get_bits1(gb);
+ pps->log2_parallel_merge_level = get_ue_golomb_long(gb) + 2;
+ if (pps->log2_parallel_merge_level > sps->log2_ctb_size) {
+ av_log(s->avctx, AV_LOG_ERROR, "log2_parallel_merge_level_minus2 out of range: %d\n",
+ pps->log2_parallel_merge_level - 2);
+ ret = AVERROR_INVALIDDATA;
+ goto err;
+ }
+
+ pps->slice_header_extension_present_flag = get_bits1(gb);
+ pps->pps_extension_flag = get_bits1(gb);
+
+ // Inferred parameters
+ pps->col_bd = av_malloc_array(pps->num_tile_columns + 1, sizeof(*pps->col_bd));
+ pps->row_bd = av_malloc_array(pps->num_tile_rows + 1, sizeof(*pps->row_bd));
+ pps->col_idxX = av_malloc_array(sps->ctb_width, sizeof(*pps->col_idxX));
+ if (!pps->col_bd || !pps->row_bd || !pps->col_idxX) {
+ ret = AVERROR(ENOMEM);
+ goto err;
+ }
+
+ if (pps->uniform_spacing_flag) {
+ if (!pps->column_width) {
+ pps->column_width = av_malloc_array(pps->num_tile_columns, sizeof(*pps->column_width));
+ pps->row_height = av_malloc_array(pps->num_tile_rows, sizeof(*pps->row_height));
+ }
+ if (!pps->column_width || !pps->row_height) {
+ ret = AVERROR(ENOMEM);
+ goto err;
+ }
+
+ for (i = 0; i < pps->num_tile_columns; i++) {
+ pps->column_width[i] = ((i + 1) * sps->ctb_width) / pps->num_tile_columns -
+ (i * sps->ctb_width) / pps->num_tile_columns;
+ }
+
+ for (i = 0; i < pps->num_tile_rows; i++) {
+ pps->row_height[i] = ((i + 1) * sps->ctb_height) / pps->num_tile_rows -
+ (i * sps->ctb_height) / pps->num_tile_rows;
+ }
+ }
+
+ pps->col_bd[0] = 0;
+ for (i = 0; i < pps->num_tile_columns; i++)
+ pps->col_bd[i + 1] = pps->col_bd[i] + pps->column_width[i];
+
+ pps->row_bd[0] = 0;
+ for (i = 0; i < pps->num_tile_rows; i++)
+ pps->row_bd[i + 1] = pps->row_bd[i] + pps->row_height[i];
+
+ for (i = 0, j = 0; i < sps->ctb_width; i++) {
+ if (i > pps->col_bd[j])
+ j++;
+ pps->col_idxX[i] = j;
+ }
+
+ /**
+ * 6.5
+ */
+ pic_area_in_ctbs = sps->ctb_width * sps->ctb_height;
+ pic_area_in_min_cbs = sps->min_cb_width * sps->min_cb_height;
+ pic_area_in_min_tbs = sps->min_tb_width * sps->min_tb_height;
+
+ pps->ctb_addr_rs_to_ts = av_malloc_array(pic_area_in_ctbs, sizeof(*pps->ctb_addr_rs_to_ts));
+ pps->ctb_addr_ts_to_rs = av_malloc_array(pic_area_in_ctbs, sizeof(*pps->ctb_addr_ts_to_rs));
+ pps->tile_id = av_malloc_array(pic_area_in_ctbs, sizeof(*pps->tile_id));
+ pps->min_cb_addr_zs = av_malloc_array(pic_area_in_min_cbs, sizeof(*pps->min_cb_addr_zs));
+ pps->min_tb_addr_zs = av_malloc_array(pic_area_in_min_tbs, sizeof(*pps->min_tb_addr_zs));
+ if (!pps->ctb_addr_rs_to_ts || !pps->ctb_addr_ts_to_rs ||
+ !pps->tile_id || !pps->min_cb_addr_zs || !pps->min_tb_addr_zs) {
+ ret = AVERROR(ENOMEM);
+ goto err;
+ }
+
+ for (ctb_addr_rs = 0; ctb_addr_rs < pic_area_in_ctbs; ctb_addr_rs++) {
+ int tb_x = ctb_addr_rs % sps->ctb_width;
+ int tb_y = ctb_addr_rs / sps->ctb_width;
+ int tile_x = 0;
+ int tile_y = 0;
+ int val = 0;
+
+ for (i = 0; i < pps->num_tile_columns; i++) {
+ if (tb_x < pps->col_bd[i + 1]) {
+ tile_x = i;
+ break;
+ }
+ }
+
+ for (i = 0; i < pps->num_tile_rows; i++) {
+ if (tb_y < pps->row_bd[i + 1]) {
+ tile_y = i;
+ break;
+ }
+ }
+
+ for (i = 0; i < tile_x; i++)
+ val += pps->row_height[tile_y] * pps->column_width[i];
+ for (i = 0; i < tile_y; i++)
+ val += sps->ctb_width * pps->row_height[i];
+
+ val += (tb_y - pps->row_bd[tile_y]) * pps->column_width[tile_x] +
+ tb_x - pps->col_bd[tile_x];
+
+ pps->ctb_addr_rs_to_ts[ctb_addr_rs] = val;
+ pps->ctb_addr_ts_to_rs[val] = ctb_addr_rs;
+ }
+
+ for (j = 0, tile_id = 0; j < pps->num_tile_rows; j++)
+ for (i = 0; i < pps->num_tile_columns; i++, tile_id++)
+ for (y = pps->row_bd[j]; y < pps->row_bd[j + 1]; y++)
+ for (x = pps->col_bd[i]; x < pps->col_bd[i + 1]; x++)
+ pps->tile_id[pps->ctb_addr_rs_to_ts[y * sps->ctb_width + x]] = tile_id;
+
+ pps->tile_pos_rs = av_malloc_array(tile_id, sizeof(*pps->tile_pos_rs));
+ if (!pps->tile_pos_rs) {
+ ret = AVERROR(ENOMEM);
+ goto err;
+ }
+
+ for (j = 0; j < pps->num_tile_rows; j++)
+ for (i = 0; i < pps->num_tile_columns; i++)
+ pps->tile_pos_rs[j * pps->num_tile_columns + i] = pps->row_bd[j] * sps->ctb_width + pps->col_bd[i];
+
+ for (y = 0; y < sps->min_cb_height; y++) {
+ for (x = 0; x < sps->min_cb_width; x++) {
+ int tb_x = x >> sps->log2_diff_max_min_coding_block_size;
+ int tb_y = y >> sps->log2_diff_max_min_coding_block_size;
+ int ctb_addr_rs = sps->ctb_width * tb_y + tb_x;
+ int val = pps->ctb_addr_rs_to_ts[ctb_addr_rs] <<
+ (sps->log2_diff_max_min_coding_block_size * 2);
+ for (i = 0; i < sps->log2_diff_max_min_coding_block_size; i++) {
+ int m = 1 << i;
+ val += (m & x ? m * m : 0) + (m & y ? 2 * m * m : 0);
+ }
+ pps->min_cb_addr_zs[y * sps->min_cb_width + x] = val;
+ }
+ }
+
+ log2_diff_ctb_min_tb_size = sps->log2_ctb_size - sps->log2_min_tb_size;
+ for (y = 0; y < sps->min_tb_height; y++) {
+ for (x = 0; x < sps->min_tb_width; x++) {
+ int tb_x = x >> log2_diff_ctb_min_tb_size;
+ int tb_y = y >> log2_diff_ctb_min_tb_size;
+ int ctb_addr_rs = sps->ctb_width * tb_y + tb_x;
+ int val = pps->ctb_addr_rs_to_ts[ctb_addr_rs] <<
+ (log2_diff_ctb_min_tb_size * 2);
+ for (i = 0; i < log2_diff_ctb_min_tb_size; i++) {
+ int m = 1 << i;
+ val += (m & x ? m * m : 0) + (m & y ? 2 * m * m : 0);
+ }
+ pps->min_tb_addr_zs[y * sps->min_tb_width + x] = val;
+ }
+ }
+
+ av_buffer_unref(&s->pps_list[pps_id]);
+ s->pps_list[pps_id] = pps_buf;
+
+ return 0;
+
+err:
+ av_buffer_unref(&pps_buf);
+ return ret;
+}
diff --git a/libavcodec/hevc_refs.c b/libavcodec/hevc_refs.c
new file mode 100644
index 0000000..118688f
--- /dev/null
+++ b/libavcodec/hevc_refs.c
@@ -0,0 +1,488 @@
+/*
+ * HEVC video Decoder
+ *
+ * Copyright (C) 2012 - 2013 Guillaume Martres
+ * Copyright (C) 2012 - 2013 Gildas Cocherel
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "libavutil/pixdesc.h"
+
+#include "internal.h"
+#include "thread.h"
+#include "hevc.h"
+
+void ff_hevc_unref_frame(HEVCContext *s, HEVCFrame *frame, int flags)
+{
+ /* frame->frame can be NULL if context init failed */
+ if (!frame->frame || !frame->frame->buf[0])
+ return;
+
+ frame->flags &= ~flags;
+ if (!frame->flags) {
+ ff_thread_release_buffer(s->avctx, &frame->tf);
+
+ av_buffer_unref(&frame->tab_mvf_buf);
+ frame->tab_mvf = NULL;
+
+ av_buffer_unref(&frame->rpl_buf);
+ av_buffer_unref(&frame->rpl_tab_buf);
+ frame->rpl_tab = NULL;
+ frame->refPicList = NULL;
+
+ frame->collocated_ref = NULL;
+ }
+}
+
+RefPicList *ff_hevc_get_ref_list(HEVCContext *s, HEVCFrame *ref, int x0, int y0)
+{
+ if (x0 < 0 || y0 < 0) {
+ return s->ref->refPicList;
+ } else {
+ int x_cb = x0 >> s->sps->log2_ctb_size;
+ int y_cb = y0 >> s->sps->log2_ctb_size;
+ int pic_width_cb = (s->sps->width + (1 << s->sps->log2_ctb_size) - 1) >>
+ s->sps->log2_ctb_size;
+ int ctb_addr_ts = s->pps->ctb_addr_rs_to_ts[y_cb * pic_width_cb + x_cb];
+ return (RefPicList *)ref->rpl_tab[ctb_addr_ts];
+ }
+}
+
+void ff_hevc_clear_refs(HEVCContext *s)
+{
+ int i;
+ for (i = 0; i < FF_ARRAY_ELEMS(s->DPB); i++)
+ ff_hevc_unref_frame(s, &s->DPB[i],
+ HEVC_FRAME_FLAG_SHORT_REF |
+ HEVC_FRAME_FLAG_LONG_REF);
+}
+
+void ff_hevc_flush_dpb(HEVCContext *s)
+{
+ int i;
+ for (i = 0; i < FF_ARRAY_ELEMS(s->DPB); i++)
+ ff_hevc_unref_frame(s, &s->DPB[i], ~0);
+}
+
+static HEVCFrame *alloc_frame(HEVCContext *s)
+{
+ int i, j, ret;
+ for (i = 0; i < FF_ARRAY_ELEMS(s->DPB); i++) {
+ HEVCFrame *frame = &s->DPB[i];
+ if (frame->frame->buf[0])
+ continue;
+
+ ret = ff_thread_get_buffer(s->avctx, &frame->tf,
+ AV_GET_BUFFER_FLAG_REF);
+ if (ret < 0)
+ return NULL;
+
+ frame->rpl_buf = av_buffer_allocz(s->nb_nals * sizeof(RefPicListTab));
+ if (!frame->rpl_buf)
+ goto fail;
+
+ frame->tab_mvf_buf = av_buffer_pool_get(s->tab_mvf_pool);
+ if (!frame->tab_mvf_buf)
+ goto fail;
+ frame->tab_mvf = (MvField *)frame->tab_mvf_buf->data;
+
+ frame->rpl_tab_buf = av_buffer_pool_get(s->rpl_tab_pool);
+ if (!frame->rpl_tab_buf)
+ goto fail;
+ frame->rpl_tab = (RefPicListTab **)frame->rpl_tab_buf->data;
+ frame->ctb_count = s->sps->ctb_width * s->sps->ctb_height;
+ for (j = 0; j < frame->ctb_count; j++)
+ frame->rpl_tab[j] = (RefPicListTab *)frame->rpl_buf->data;
+
+ frame->frame->top_field_first = s->picture_struct == AV_PICTURE_STRUCTURE_TOP_FIELD;
+ frame->frame->interlaced_frame = (s->picture_struct == AV_PICTURE_STRUCTURE_TOP_FIELD) || (s->picture_struct == AV_PICTURE_STRUCTURE_BOTTOM_FIELD);
+ return frame;
+fail:
+ ff_hevc_unref_frame(s, frame, ~0);
+ return NULL;
+ }
+ av_log(s->avctx, AV_LOG_ERROR, "Error allocating frame, DPB full.\n");
+ return NULL;
+}
+
+int ff_hevc_set_new_ref(HEVCContext *s, AVFrame **frame, int poc)
+{
+ HEVCFrame *ref;
+ int i;
+
+ /* check that this POC doesn't already exist */
+ for (i = 0; i < FF_ARRAY_ELEMS(s->DPB); i++) {
+ HEVCFrame *frame = &s->DPB[i];
+
+ if (frame->frame->buf[0] && frame->sequence == s->seq_decode &&
+ frame->poc == poc) {
+ av_log(s->avctx, AV_LOG_ERROR, "Duplicate POC in a sequence: %d.\n",
+ poc);
+ return AVERROR_INVALIDDATA;
+ }
+ }
+
+ ref = alloc_frame(s);
+ if (!ref)
+ return AVERROR(ENOMEM);
+
+ *frame = ref->frame;
+ s->ref = ref;
+
+ ref->poc = poc;
+ ref->flags = HEVC_FRAME_FLAG_OUTPUT | HEVC_FRAME_FLAG_SHORT_REF;
+ ref->sequence = s->seq_decode;
+ ref->window = s->sps->output_window;
+
+ return 0;
+}
+
+int ff_hevc_output_frame(HEVCContext *s, AVFrame *out, int flush)
+{
+ do {
+ int nb_output = 0;
+ int min_poc = INT_MAX;
+ int i, min_idx, ret;
+
+ for (i = 0; i < FF_ARRAY_ELEMS(s->DPB); i++) {
+ HEVCFrame *frame = &s->DPB[i];
+ if ((frame->flags & HEVC_FRAME_FLAG_OUTPUT) &&
+ frame->sequence == s->seq_output) {
+ nb_output++;
+ if (frame->poc < min_poc) {
+ min_poc = frame->poc;
+ min_idx = i;
+ }
+ }
+ }
+
+ /* wait for more frames before output */
+ if (!flush && s->seq_output == s->seq_decode && s->sps &&
+ nb_output <= s->sps->temporal_layer[s->sps->max_sub_layers - 1].num_reorder_pics)
+ return 0;
+
+ if (nb_output) {
+ HEVCFrame *frame = &s->DPB[min_idx];
+ AVFrame *dst = out;
+ AVFrame *src = frame->frame;
+ const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(src->format);
+ int pixel_shift = !!(desc->comp[0].depth_minus1 > 7);
+
+ ret = av_frame_ref(out, src);
+ ff_hevc_unref_frame(s, frame, HEVC_FRAME_FLAG_OUTPUT);
+ if (ret < 0)
+ return ret;
+
+ for (i = 0; i < 3; i++) {
+ int hshift = (i > 0) ? desc->log2_chroma_w : 0;
+ int vshift = (i > 0) ? desc->log2_chroma_h : 0;
+ int off = ((frame->window.left_offset >> hshift) << pixel_shift) +
+ (frame->window.top_offset >> vshift) * dst->linesize[i];
+ dst->data[i] += off;
+ }
+ av_log(s->avctx, AV_LOG_DEBUG,
+ "Output frame with POC %d.\n", frame->poc);
+ return 1;
+ }
+
+ if (s->seq_output != s->seq_decode)
+ s->seq_output = (s->seq_output + 1) & 0xff;
+ else
+ break;
+ } while (1);
+
+ return 0;
+}
+
+static int init_slice_rpl(HEVCContext *s)
+{
+ HEVCFrame *frame = s->ref;
+ int ctb_count = frame->ctb_count;
+ int ctb_addr_ts = s->pps->ctb_addr_rs_to_ts[s->sh.slice_segment_addr];
+ int i;
+
+ if (s->slice_idx >= frame->rpl_buf->size / sizeof(RefPicListTab))
+ return AVERROR_INVALIDDATA;
+
+ for (i = ctb_addr_ts; i < ctb_count; i++)
+ frame->rpl_tab[i] = (RefPicListTab *)frame->rpl_buf->data + s->slice_idx;
+
+ frame->refPicList = (RefPicList *)frame->rpl_tab[ctb_addr_ts];
+
+ return 0;
+}
+
+int ff_hevc_slice_rpl(HEVCContext *s)
+{
+ SliceHeader *sh = &s->sh;
+
+ uint8_t nb_list = sh->slice_type == B_SLICE ? 2 : 1;
+ uint8_t list_idx;
+ int i, j, ret;
+
+ ret = init_slice_rpl(s);
+ if (ret < 0)
+ return ret;
+
+ if (!(s->rps[ST_CURR_BEF].nb_refs + s->rps[ST_CURR_AFT].nb_refs +
+ s->rps[LT_CURR].nb_refs)) {
+ av_log(s->avctx, AV_LOG_ERROR, "Zero refs in the frame RPS.\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ for (list_idx = 0; list_idx < nb_list; list_idx++) {
+ RefPicList rpl_tmp = { { 0 } };
+ RefPicList *rpl = &s->ref->refPicList[list_idx];
+
+ /* The order of the elements is
+ * ST_CURR_BEF - ST_CURR_AFT - LT_CURR for the L0 and
+ * ST_CURR_AFT - ST_CURR_BEF - LT_CURR for the L1 */
+ int cand_lists[3] = { list_idx ? ST_CURR_AFT : ST_CURR_BEF,
+ list_idx ? ST_CURR_BEF : ST_CURR_AFT,
+ LT_CURR };
+
+ /* concatenate the candidate lists for the current frame */
+ while (rpl_tmp.nb_refs < sh->nb_refs[list_idx]) {
+ for (i = 0; i < FF_ARRAY_ELEMS(cand_lists); i++) {
+ RefPicList *rps = &s->rps[cand_lists[i]];
+ for (j = 0; j < rps->nb_refs && rpl_tmp.nb_refs < MAX_REFS; j++) {
+ rpl_tmp.list[rpl_tmp.nb_refs] = rps->list[j];
+ rpl_tmp.ref[rpl_tmp.nb_refs] = rps->ref[j];
+ rpl_tmp.isLongTerm[rpl_tmp.nb_refs] = i == 2;
+ rpl_tmp.nb_refs++;
+ }
+ }
+ }
+
+ /* reorder the references if necessary */
+ if (sh->rpl_modification_flag[list_idx]) {
+ for (i = 0; i < sh->nb_refs[list_idx]; i++) {
+ int idx = sh->list_entry_lx[list_idx][i];
+
+ if (idx >= rpl_tmp.nb_refs) {
+ av_log(s->avctx, AV_LOG_ERROR, "Invalid reference index.\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ rpl->list[i] = rpl_tmp.list[idx];
+ rpl->ref[i] = rpl_tmp.ref[idx];
+ rpl->isLongTerm[i] = rpl_tmp.isLongTerm[idx];
+ rpl->nb_refs++;
+ }
+ } else {
+ memcpy(rpl, &rpl_tmp, sizeof(*rpl));
+ rpl->nb_refs = FFMIN(rpl->nb_refs, sh->nb_refs[list_idx]);
+ }
+
+ if (sh->collocated_list == list_idx &&
+ sh->collocated_ref_idx < rpl->nb_refs)
+ s->ref->collocated_ref = rpl->ref[sh->collocated_ref_idx];
+ }
+
+ return 0;
+}
+
+static HEVCFrame *find_ref_idx(HEVCContext *s, int poc)
+{
+ int i;
+ int LtMask = (1 << s->sps->log2_max_poc_lsb) - 1;
+
+ for (i = 0; i < FF_ARRAY_ELEMS(s->DPB); i++) {
+ HEVCFrame *ref = &s->DPB[i];
+ if (ref->frame->buf[0] && (ref->sequence == s->seq_decode)) {
+ if ((ref->poc & LtMask) == poc)
+ return ref;
+ }
+ }
+
+ for (i = 0; i < FF_ARRAY_ELEMS(s->DPB); i++) {
+ HEVCFrame *ref = &s->DPB[i];
+ if (ref->frame->buf[0] && ref->sequence == s->seq_decode) {
+ if (ref->poc == poc || (ref->poc & LtMask) == poc)
+ return ref;
+ }
+ }
+
+ av_log(s->avctx, AV_LOG_ERROR,
+ "Could not find ref with POC %d\n", poc);
+ return NULL;
+}
+
+static void mark_ref(HEVCFrame *frame, int flag)
+{
+ frame->flags &= ~(HEVC_FRAME_FLAG_LONG_REF | HEVC_FRAME_FLAG_SHORT_REF);
+ frame->flags |= flag;
+}
+
+static HEVCFrame *generate_missing_ref(HEVCContext *s, int poc)
+{
+ HEVCFrame *frame;
+ int i, x, y;
+
+ frame = alloc_frame(s);
+ if (!frame)
+ return NULL;
+
+ if (!s->sps->pixel_shift) {
+ for (i = 0; frame->frame->buf[i]; i++)
+ memset(frame->frame->buf[i]->data, 1 << (s->sps->bit_depth - 1),
+ frame->frame->buf[i]->size);
+ } else {
+ for (i = 0; frame->frame->data[i]; i++)
+ for (y = 0; y < (s->sps->height >> s->sps->vshift[i]); y++)
+ for (x = 0; x < (s->sps->width >> s->sps->hshift[i]); x++) {
+ AV_WN16(frame->frame->data[i] + y * frame->frame->linesize[i] + 2 * x,
+ 1 << (s->sps->bit_depth - 1));
+ }
+ }
+
+ frame->poc = poc;
+ frame->sequence = s->seq_decode;
+ frame->flags = 0;
+
+ if (s->threads_type == FF_THREAD_FRAME)
+ ff_thread_report_progress(&frame->tf, INT_MAX, 0);
+
+ return frame;
+}
+
+/* add a reference with the given poc to the list and mark it as used in DPB */
+static int add_candidate_ref(HEVCContext *s, RefPicList *list,
+ int poc, int ref_flag)
+{
+ HEVCFrame *ref = find_ref_idx(s, poc);
+
+ if (ref == s->ref)
+ return AVERROR_INVALIDDATA;
+
+ if (!ref) {
+ ref = generate_missing_ref(s, poc);
+ if (!ref)
+ return AVERROR(ENOMEM);
+ }
+
+ list->list[list->nb_refs] = ref->poc;
+ list->ref[list->nb_refs] = ref;
+ list->nb_refs++;
+
+ mark_ref(ref, ref_flag);
+ return 0;
+}
+
+int ff_hevc_frame_rps(HEVCContext *s)
+{
+ const ShortTermRPS *short_rps = s->sh.short_term_rps;
+ const LongTermRPS *long_rps = &s->sh.long_term_rps;
+ RefPicList *rps = s->rps;
+ int i, ret;
+
+ if (!short_rps) {
+ rps[0].nb_refs = rps[1].nb_refs = 0;
+ return 0;
+ }
+
+ /* clear the reference flags on all frames except the current one */
+ for (i = 0; i < FF_ARRAY_ELEMS(s->DPB); i++) {
+ HEVCFrame *frame = &s->DPB[i];
+
+ if (frame == s->ref)
+ continue;
+
+ mark_ref(frame, 0);
+ }
+
+ for (i = 0; i < NB_RPS_TYPE; i++)
+ rps[i].nb_refs = 0;
+
+ /* add the short refs */
+ for (i = 0; i < short_rps->num_delta_pocs; i++) {
+ int poc = s->poc + short_rps->delta_poc[i];
+ int list;
+
+ if (!short_rps->used[i])
+ list = ST_FOLL;
+ else if (i < short_rps->num_negative_pics)
+ list = ST_CURR_BEF;
+ else
+ list = ST_CURR_AFT;
+
+ ret = add_candidate_ref(s, &rps[list], poc, HEVC_FRAME_FLAG_SHORT_REF);
+ if (ret < 0)
+ return ret;
+ }
+
+ /* add the long refs */
+ for (i = 0; i < long_rps->nb_refs; i++) {
+ int poc = long_rps->poc[i];
+ int list = long_rps->used[i] ? LT_CURR : LT_FOLL;
+
+ ret = add_candidate_ref(s, &rps[list], poc, HEVC_FRAME_FLAG_LONG_REF);
+ if (ret < 0)
+ return ret;
+ }
+
+ /* release any frames that are now unused */
+ for (i = 0; i < FF_ARRAY_ELEMS(s->DPB); i++)
+ ff_hevc_unref_frame(s, &s->DPB[i], 0);
+
+ return 0;
+}
+
+int ff_hevc_compute_poc(HEVCContext *s, int poc_lsb)
+{
+ int max_poc_lsb = 1 << s->sps->log2_max_poc_lsb;
+ int prev_poc_lsb = s->pocTid0 % max_poc_lsb;
+ int prev_poc_msb = s->pocTid0 - prev_poc_lsb;
+ int poc_msb;
+
+ if (poc_lsb < prev_poc_lsb && prev_poc_lsb - poc_lsb >= max_poc_lsb / 2)
+ poc_msb = prev_poc_msb + max_poc_lsb;
+ else if (poc_lsb > prev_poc_lsb && poc_lsb - prev_poc_lsb > max_poc_lsb / 2)
+ poc_msb = prev_poc_msb - max_poc_lsb;
+ else
+ poc_msb = prev_poc_msb;
+
+ // For BLA picture types, POCmsb is set to 0.
+ if (s->nal_unit_type == NAL_BLA_W_LP ||
+ s->nal_unit_type == NAL_BLA_W_RADL ||
+ s->nal_unit_type == NAL_BLA_N_LP)
+ poc_msb = 0;
+
+ return poc_msb + poc_lsb;
+}
+
+int ff_hevc_frame_nb_refs(HEVCContext *s)
+{
+ int ret = 0;
+ int i;
+ const ShortTermRPS *rps = s->sh.short_term_rps;
+ LongTermRPS *long_rps = &s->sh.long_term_rps;
+
+ if (rps) {
+ for (i = 0; i < rps->num_negative_pics; i++)
+ ret += !!rps->used[i];
+ for (; i < rps->num_delta_pocs; i++)
+ ret += !!rps->used[i];
+ }
+
+ if (long_rps) {
+ for (i = 0; i < long_rps->nb_refs; i++)
+ ret += !!long_rps->used[i];
+ }
+ return ret;
+}
diff --git a/libavcodec/hevc_sei.c b/libavcodec/hevc_sei.c
new file mode 100644
index 0000000..af8cb7d
--- /dev/null
+++ b/libavcodec/hevc_sei.c
@@ -0,0 +1,192 @@
+/*
+ * HEVC Supplementary Enhancement Information messages
+ *
+ * Copyright (C) 2012 - 2013 Guillaume Martres
+ * Copyright (C) 2012 - 2013 Gildas Cocherel
+ * Copyright (C) 2013 Vittorio Giovara
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "hevc.h"
+#include "golomb.h"
+
+static void decode_nal_sei_decoded_picture_hash(HEVCContext *s)
+{
+ int cIdx, i;
+ uint8_t hash_type;
+ //uint16_t picture_crc;
+ //uint32_t picture_checksum;
+ GetBitContext *gb = &s->HEVClc->gb;
+ hash_type = get_bits(gb, 8);
+
+ for (cIdx = 0; cIdx < 3/*((s->sps->chroma_format_idc == 0) ? 1 : 3)*/; cIdx++) {
+ if (hash_type == 0) {
+ s->is_md5 = 1;
+ for (i = 0; i < 16; i++)
+ s->md5[cIdx][i] = get_bits(gb, 8);
+ } else if (hash_type == 1) {
+ // picture_crc = get_bits(gb, 16);
+ skip_bits(gb, 16);
+ } else if (hash_type == 2) {
+ // picture_checksum = get_bits(gb, 32);
+ skip_bits(gb, 32);
+ }
+ }
+}
+
+static void decode_nal_sei_frame_packing_arrangement(HEVCContext *s)
+{
+ GetBitContext *gb = &s->HEVClc->gb;
+ int cancel, type, quincunx;
+
+ get_ue_golomb(gb); // frame_packing_arrangement_id
+ cancel = get_bits1(gb); // frame_packing_cancel_flag
+ if (cancel == 0) {
+ type = get_bits(gb, 7); // frame_packing_arrangement_type
+ quincunx = get_bits1(gb); // quincunx_sampling_flag
+ skip_bits(gb, 6); // content_interpretation_type
+
+ // the following skips spatial_flipping_flag frame0_flipped_flag
+ // field_views_flag current_frame_is_frame0_flag
+ // frame0_self_contained_flag frame1_self_contained_flag
+ skip_bits(gb, 6);
+
+ if (quincunx == 0 && type != 5)
+ skip_bits(gb, 16); // frame[01]_grid_position_[xy]
+ skip_bits(gb, 8); // frame_packing_arrangement_reserved_byte
+ skip_bits1(gb); // frame_packing_arrangement_persistance_flag
+ }
+ skip_bits1(gb); // upsampled_aspect_ratio_flag
+}
+
+static int decode_pic_timing(HEVCContext *s)
+{
+ GetBitContext *gb = &s->HEVClc->gb;
+ HEVCSPS *sps;
+
+ if (!s->sps_list[s->active_seq_parameter_set_id])
+ return(AVERROR(ENOMEM));
+ sps = (HEVCSPS*)s->sps_list[s->active_seq_parameter_set_id]->data;
+
+ if (sps->vui.frame_field_info_present_flag) {
+ int pic_struct = get_bits(gb, 4);
+ s->picture_struct = AV_PICTURE_STRUCTURE_UNKNOWN;
+ if (pic_struct == 2) {
+ av_log(s->avctx, AV_LOG_DEBUG, "BOTTOM Field\n");
+ s->picture_struct = AV_PICTURE_STRUCTURE_BOTTOM_FIELD;
+ } else if (pic_struct == 1) {
+ av_log(s->avctx, AV_LOG_DEBUG, "TOP Field\n");
+ s->picture_struct = AV_PICTURE_STRUCTURE_TOP_FIELD;
+ }
+ get_bits(gb, 2); // source_scan_type
+ get_bits(gb, 1); // duplicate_flag
+ }
+ return 1;
+}
+
+static int active_parameter_sets(HEVCContext *s)
+{
+ GetBitContext *gb = &s->HEVClc->gb;
+ int num_sps_ids_minus1;
+ int i;
+ unsigned active_seq_parameter_set_id;
+
+ get_bits(gb, 4); // active_video_parameter_set_id
+ get_bits(gb, 1); // self_contained_cvs_flag
+ get_bits(gb, 1); // num_sps_ids_minus1
+ num_sps_ids_minus1 = get_ue_golomb_long(gb); // num_sps_ids_minus1
+
+ active_seq_parameter_set_id = get_ue_golomb_long(gb);
+ if (active_seq_parameter_set_id >= MAX_SPS_COUNT) {
+ av_log(s->avctx, AV_LOG_ERROR, "active_parameter_set_id %d invalid\n", active_seq_parameter_set_id);
+ return AVERROR_INVALIDDATA;
+ }
+ s->active_seq_parameter_set_id = active_seq_parameter_set_id;
+
+ for (i = 1; i <= num_sps_ids_minus1; i++)
+ get_ue_golomb_long(gb); // active_seq_parameter_set_id[i]
+
+ return 0;
+}
+
+static int decode_nal_sei_message(HEVCContext *s)
+{
+ GetBitContext *gb = &s->HEVClc->gb;
+
+ int payload_type = 0;
+ int payload_size = 0;
+ int byte = 0xFF;
+ av_log(s->avctx, AV_LOG_DEBUG, "Decoding SEI\n");
+
+ while (byte == 0xFF) {
+ byte = get_bits(gb, 8);
+ payload_type += byte;
+ }
+ byte = 0xFF;
+ while (byte == 0xFF) {
+ byte = get_bits(gb, 8);
+ payload_size += byte;
+ }
+ if (s->nal_unit_type == NAL_SEI_PREFIX) {
+ if (payload_type == 256 /*&& s->decode_checksum_sei*/) {
+ decode_nal_sei_decoded_picture_hash(s);
+ return 1;
+ } else if (payload_type == 45) {
+ decode_nal_sei_frame_packing_arrangement(s);
+ return 1;
+ } else if (payload_type == 1){
+ int ret = decode_pic_timing(s);
+ av_log(s->avctx, AV_LOG_DEBUG, "Skipped PREFIX SEI %d\n", payload_type);
+ skip_bits(gb, 8 * payload_size);
+ return ret;
+ } else if (payload_type == 129){
+ active_parameter_sets(s);
+ av_log(s->avctx, AV_LOG_DEBUG, "Skipped PREFIX SEI %d\n", payload_type);
+ return 1;
+ } else {
+ av_log(s->avctx, AV_LOG_DEBUG, "Skipped PREFIX SEI %d\n", payload_type);
+ skip_bits(gb, 8*payload_size);
+ return 1;
+ }
+ } else { /* nal_unit_type == NAL_SEI_SUFFIX */
+ if (payload_type == 132 /* && s->decode_checksum_sei */)
+ decode_nal_sei_decoded_picture_hash(s);
+ else {
+ av_log(s->avctx, AV_LOG_DEBUG, "Skipped SUFFIX SEI %d\n", payload_type);
+ skip_bits(gb, 8 * payload_size);
+ }
+ return 1;
+ }
+}
+
+static int more_rbsp_data(GetBitContext *gb)
+{
+ return get_bits_left(gb) > 0 && show_bits(gb, 8) != 0x80;
+}
+
+int ff_hevc_decode_nal_sei(HEVCContext *s)
+{
+ int ret;
+
+ do {
+ ret = decode_nal_sei_message(s);
+ if (ret < 0)
+ return(AVERROR(ENOMEM));
+ } while (more_rbsp_data(&s->HEVClc->gb));
+ return 1;
+}
diff --git a/libavcodec/hevcdsp.c b/libavcodec/hevcdsp.c
new file mode 100644
index 0000000..b3abc9d
--- /dev/null
+++ b/libavcodec/hevcdsp.c
@@ -0,0 +1,191 @@
+/*
+ * HEVC video decoder
+ *
+ * Copyright (C) 2012 - 2013 Guillaume Martres
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "hevc.h"
+#include "hevcdsp.h"
+
+static const int8_t transform[32][32] = {
+ { 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64 },
+ { 90, 90, 88, 85, 82, 78, 73, 67, 61, 54, 46, 38, 31, 22, 13, 4,
+ -4, -13, -22, -31, -38, -46, -54, -61, -67, -73, -78, -82, -85, -88, -90, -90 },
+ { 90, 87, 80, 70, 57, 43, 25, 9, -9, -25, -43, -57, -70, -80, -87, -90,
+ -90, -87, -80, -70, -57, -43, -25, -9, 9, 25, 43, 57, 70, 80, 87, 90 },
+ { 90, 82, 67, 46, 22, -4, -31, -54, -73, -85, -90, -88, -78, -61, -38, -13,
+ 13, 38, 61, 78, 88, 90, 85, 73, 54, 31, 4, -22, -46, -67, -82, -90 },
+ { 89, 75, 50, 18, -18, -50, -75, -89, -89, -75, -50, -18, 18, 50, 75, 89,
+ 89, 75, 50, 18, -18, -50, -75, -89, -89, -75, -50, -18, 18, 50, 75, 89 },
+ { 88, 67, 31, -13, -54, -82, -90, -78, -46, -4, 38, 73, 90, 85, 61, 22,
+ -22, -61, -85, -90, -73, -38, 4, 46, 78, 90, 82, 54, 13, -31, -67, -88 },
+ { 87, 57, 9, -43, -80, -90, -70, -25, 25, 70, 90, 80, 43, -9, -57, -87,
+ -87, -57, -9, 43, 80, 90, 70, 25, -25, -70, -90, -80, -43, 9, 57, 87 },
+ { 85, 46, -13, -67, -90, -73, -22, 38, 82, 88, 54, -4, -61, -90, -78, -31,
+ 31, 78, 90, 61, 4, -54, -88, -82, -38, 22, 73, 90, 67, 13, -46, -85 },
+ { 83, 36, -36, -83, -83, -36, 36, 83, 83, 36, -36, -83, -83, -36, 36, 83,
+ 83, 36, -36, -83, -83, -36, 36, 83, 83, 36, -36, -83, -83, -36, 36, 83 },
+ { 82, 22, -54, -90, -61, 13, 78, 85, 31, -46, -90, -67, 4, 73, 88, 38,
+ -38, -88, -73, -4, 67, 90, 46, -31, -85, -78, -13, 61, 90, 54, -22, -82 },
+ { 80, 9, -70, -87, -25, 57, 90, 43, -43, -90, -57, 25, 87, 70, -9, -80,
+ -80, -9, 70, 87, 25, -57, -90, -43, 43, 90, 57, -25, -87, -70, 9, 80 },
+ { 78, -4, -82, -73, 13, 85, 67, -22, -88, -61, 31, 90, 54, -38, -90, -46,
+ 46, 90, 38, -54, -90, -31, 61, 88, 22, -67, -85, -13, 73, 82, 4, -78 },
+ { 75, -18, -89, -50, 50, 89, 18, -75, -75, 18, 89, 50, -50, -89, -18, 75,
+ 75, -18, -89, -50, 50, 89, 18, -75, -75, 18, 89, 50, -50, -89, -18, 75 },
+ { 73, -31, -90, -22, 78, 67, -38, -90, -13, 82, 61, -46, -88, -4, 85, 54,
+ -54, -85, 4, 88, 46, -61, -82, 13, 90, 38, -67, -78, 22, 90, 31, -73 },
+ { 70, -43, -87, 9, 90, 25, -80, -57, 57, 80, -25, -90, -9, 87, 43, -70,
+ -70, 43, 87, -9, -90, -25, 80, 57, -57, -80, 25, 90, 9, -87, -43, 70 },
+ { 67, -54, -78, 38, 85, -22, -90, 4, 90, 13, -88, -31, 82, 46, -73, -61,
+ 61, 73, -46, -82, 31, 88, -13, -90, -4, 90, 22, -85, -38, 78, 54, -67 },
+ { 64, -64, -64, 64, 64, -64, -64, 64, 64, -64, -64, 64, 64, -64, -64, 64,
+ 64, -64, -64, 64, 64, -64, -64, 64, 64, -64, -64, 64, 64, -64, -64, 64 },
+ { 61, -73, -46, 82, 31, -88, -13, 90, -4, -90, 22, 85, -38, -78, 54, 67,
+ -67, -54, 78, 38, -85, -22, 90, 4, -90, 13, 88, -31, -82, 46, 73, -61 },
+ { 57, -80, -25, 90, -9, -87, 43, 70, -70, -43, 87, 9, -90, 25, 80, -57,
+ -57, 80, 25, -90, 9, 87, -43, -70, 70, 43, -87, -9, 90, -25, -80, 57 },
+ { 54, -85, -4, 88, -46, -61, 82, 13, -90, 38, 67, -78, -22, 90, -31, -73,
+ 73, 31, -90, 22, 78, -67, -38, 90, -13, -82, 61, 46, -88, 4, 85, -54 },
+ { 50, -89, 18, 75, -75, -18, 89, -50, -50, 89, -18, -75, 75, 18, -89, 50,
+ 50, -89, 18, 75, -75, -18, 89, -50, -50, 89, -18, -75, 75, 18, -89, 50 },
+ { 46, -90, 38, 54, -90, 31, 61, -88, 22, 67, -85, 13, 73, -82, 4, 78,
+ -78, -4, 82, -73, -13, 85, -67, -22, 88, -61, -31, 90, -54, -38, 90, -46 },
+ { 43, -90, 57, 25, -87, 70, 9, -80, 80, -9, -70, 87, -25, -57, 90, -43,
+ -43, 90, -57, -25, 87, -70, -9, 80, -80, 9, 70, -87, 25, 57, -90, 43 },
+ { 38, -88, 73, -4, -67, 90, -46, -31, 85, -78, 13, 61, -90, 54, 22, -82,
+ 82, -22, -54, 90, -61, -13, 78, -85, 31, 46, -90, 67, 4, -73, 88, -38 },
+ { 36, -83, 83, -36, -36, 83, -83, 36, 36, -83, 83, -36, -36, 83, -83, 36,
+ 36, -83, 83, -36, -36, 83, -83, 36, 36, -83, 83, -36, -36, 83, -83, 36 },
+ { 31, -78, 90, -61, 4, 54, -88, 82, -38, -22, 73, -90, 67, -13, -46, 85,
+ -85, 46, 13, -67, 90, -73, 22, 38, -82, 88, -54, -4, 61, -90, 78, -31 },
+ { 25, -70, 90, -80, 43, 9, -57, 87, -87, 57, -9, -43, 80, -90, 70, -25,
+ -25, 70, -90, 80, -43, -9, 57, -87, 87, -57, 9, 43, -80, 90, -70, 25 },
+ { 22, -61, 85, -90, 73, -38, -4, 46, -78, 90, -82, 54, -13, -31, 67, -88,
+ 88, -67, 31, 13, -54, 82, -90, 78, -46, 4, 38, -73, 90, -85, 61, -22 },
+ { 18, -50, 75, -89, 89, -75, 50, -18, -18, 50, -75, 89, -89, 75, -50, 18,
+ 18, -50, 75, -89, 89, -75, 50, -18, -18, 50, -75, 89, -89, 75, -50, 18 },
+ { 13, -38, 61, -78, 88, -90, 85, -73, 54, -31, 4, 22, -46, 67, -82, 90,
+ -90, 82, -67, 46, -22, -4, 31, -54, 73, -85, 90, -88, 78, -61, 38, -13 },
+ { 9, -25, 43, -57, 70, -80, 87, -90, 90, -87, 80, -70, 57, -43, 25, -9,
+ -9, 25, -43, 57, -70, 80, -87, 90, -90, 87, -80, 70, -57, 43, -25, 9 },
+ { 4, -13, 22, -31, 38, -46, 54, -61, 67, -73, 78, -82, 85, -88, 90, -90,
+ 90, -90, 88, -85, 82, -78, 73, -67, 61, -54, 46, -38, 31, -22, 13, -4 },
+};
+
+DECLARE_ALIGNED(16, const int8_t, ff_hevc_epel_filters[7][16]) = {
+ { -2, 58, 10, -2, -2, 58, 10, -2, -2, 58, 10, -2, -2, 58, 10, -2 },
+ { -4, 54, 16, -2, -4, 54, 16, -2, -4, 54, 16, -2, -4, 54, 16, -2 },
+ { -6, 46, 28, -4, -6, 46, 28, -4, -6, 46, 28, -4, -6, 46, 28, -4 },
+ { -4, 36, 36, -4, -4, 36, 36, -4, -4, 36, 36, -4, -4, 36, 36, -4 },
+ { -4, 28, 46, -6, -4, 28, 46, -6, -4, 28, 46, -6, -4, 28, 46, -6 },
+ { -2, 16, 54, -4, -2, 16, 54, -4, -2, 16, 54, -4, -2, 16, 54, -4 },
+ { -2, 10, 58, -2, -2, 10, 58, -2, -2, 10, 58, -2, -2, 10, 58, -2 },
+};
+
+#define BIT_DEPTH 8
+#include "hevcdsp_template.c"
+#undef BIT_DEPTH
+
+#define BIT_DEPTH 9
+#include "hevcdsp_template.c"
+#undef BIT_DEPTH
+
+#define BIT_DEPTH 10
+#include "hevcdsp_template.c"
+#undef BIT_DEPTH
+
+void ff_hevc_dsp_init(HEVCDSPContext *hevcdsp, int bit_depth)
+{
+#undef FUNC
+#define FUNC(a, depth) a ## _ ## depth
+
+#define HEVC_DSP(depth) \
+ hevcdsp->put_pcm = FUNC(put_pcm, depth); \
+ hevcdsp->transquant_bypass[0] = FUNC(transquant_bypass4x4, depth); \
+ hevcdsp->transquant_bypass[1] = FUNC(transquant_bypass8x8, depth); \
+ hevcdsp->transquant_bypass[2] = FUNC(transquant_bypass16x16, depth); \
+ hevcdsp->transquant_bypass[3] = FUNC(transquant_bypass32x32, depth); \
+ hevcdsp->transform_skip = FUNC(transform_skip, depth); \
+ hevcdsp->transform_4x4_luma_add = FUNC(transform_4x4_luma_add, depth); \
+ hevcdsp->transform_add[0] = FUNC(transform_4x4_add, depth); \
+ hevcdsp->transform_add[1] = FUNC(transform_8x8_add, depth); \
+ hevcdsp->transform_add[2] = FUNC(transform_16x16_add, depth); \
+ hevcdsp->transform_add[3] = FUNC(transform_32x32_add, depth); \
+ \
+ hevcdsp->sao_band_filter[0] = FUNC(sao_band_filter_0, depth); \
+ hevcdsp->sao_band_filter[1] = FUNC(sao_band_filter_1, depth); \
+ hevcdsp->sao_band_filter[2] = FUNC(sao_band_filter_2, depth); \
+ hevcdsp->sao_band_filter[3] = FUNC(sao_band_filter_3, depth); \
+ \
+ hevcdsp->sao_edge_filter[0] = FUNC(sao_edge_filter_0, depth); \
+ hevcdsp->sao_edge_filter[1] = FUNC(sao_edge_filter_1, depth); \
+ hevcdsp->sao_edge_filter[2] = FUNC(sao_edge_filter_2, depth); \
+ hevcdsp->sao_edge_filter[3] = FUNC(sao_edge_filter_3, depth); \
+ \
+ hevcdsp->put_hevc_qpel[0][0] = FUNC(put_hevc_qpel_pixels, depth); \
+ hevcdsp->put_hevc_qpel[0][1] = FUNC(put_hevc_qpel_h1, depth); \
+ hevcdsp->put_hevc_qpel[0][2] = FUNC(put_hevc_qpel_h2, depth); \
+ hevcdsp->put_hevc_qpel[0][3] = FUNC(put_hevc_qpel_h3, depth); \
+ hevcdsp->put_hevc_qpel[1][0] = FUNC(put_hevc_qpel_v1, depth); \
+ hevcdsp->put_hevc_qpel[1][1] = FUNC(put_hevc_qpel_h1v1, depth); \
+ hevcdsp->put_hevc_qpel[1][2] = FUNC(put_hevc_qpel_h2v1, depth); \
+ hevcdsp->put_hevc_qpel[1][3] = FUNC(put_hevc_qpel_h3v1, depth); \
+ hevcdsp->put_hevc_qpel[2][0] = FUNC(put_hevc_qpel_v2, depth); \
+ hevcdsp->put_hevc_qpel[2][1] = FUNC(put_hevc_qpel_h1v2, depth); \
+ hevcdsp->put_hevc_qpel[2][2] = FUNC(put_hevc_qpel_h2v2, depth); \
+ hevcdsp->put_hevc_qpel[2][3] = FUNC(put_hevc_qpel_h3v2, depth); \
+ hevcdsp->put_hevc_qpel[3][0] = FUNC(put_hevc_qpel_v3, depth); \
+ hevcdsp->put_hevc_qpel[3][1] = FUNC(put_hevc_qpel_h1v3, depth); \
+ hevcdsp->put_hevc_qpel[3][2] = FUNC(put_hevc_qpel_h2v3, depth); \
+ hevcdsp->put_hevc_qpel[3][3] = FUNC(put_hevc_qpel_h3v3, depth); \
+ \
+ hevcdsp->put_hevc_epel[0][0] = FUNC(put_hevc_epel_pixels, depth); \
+ hevcdsp->put_hevc_epel[0][1] = FUNC(put_hevc_epel_h, depth); \
+ hevcdsp->put_hevc_epel[1][0] = FUNC(put_hevc_epel_v, depth); \
+ hevcdsp->put_hevc_epel[1][1] = FUNC(put_hevc_epel_hv, depth); \
+ \
+ hevcdsp->put_unweighted_pred = FUNC(put_unweighted_pred, depth); \
+ hevcdsp->put_weighted_pred_avg = FUNC(put_weighted_pred_avg, depth); \
+ \
+ hevcdsp->weighted_pred = FUNC(weighted_pred, depth); \
+ hevcdsp->weighted_pred_avg = FUNC(weighted_pred_avg, depth); \
+ \
+ hevcdsp->hevc_h_loop_filter_luma = FUNC(hevc_h_loop_filter_luma, depth); \
+ hevcdsp->hevc_v_loop_filter_luma = FUNC(hevc_v_loop_filter_luma, depth); \
+ hevcdsp->hevc_h_loop_filter_chroma = FUNC(hevc_h_loop_filter_chroma, depth); \
+ hevcdsp->hevc_v_loop_filter_chroma = FUNC(hevc_v_loop_filter_chroma, depth); \
+ hevcdsp->hevc_h_loop_filter_luma_c = FUNC(hevc_h_loop_filter_luma, depth); \
+ hevcdsp->hevc_v_loop_filter_luma_c = FUNC(hevc_v_loop_filter_luma, depth); \
+ hevcdsp->hevc_h_loop_filter_chroma_c = FUNC(hevc_h_loop_filter_chroma, depth); \
+ hevcdsp->hevc_v_loop_filter_chroma_c = FUNC(hevc_v_loop_filter_chroma, depth);
+
+ switch (bit_depth) {
+ case 9:
+ HEVC_DSP(9);
+ break;
+ case 10:
+ HEVC_DSP(10);
+ break;
+ default:
+ HEVC_DSP(8);
+ break;
+ }
+}
diff --git a/libavcodec/hevcdsp.h b/libavcodec/hevcdsp.h
new file mode 100644
index 0000000..c6511b0
--- /dev/null
+++ b/libavcodec/hevcdsp.h
@@ -0,0 +1,77 @@
+/*
+ * HEVC video Decoder
+ *
+ * Copyright (C) 2012 - 2013 Guillaume Martres
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVCODEC_HEVCDSP_H
+#define AVCODEC_HEVCDSP_H
+
+#include "get_bits.h"
+
+struct SAOParams;
+
+typedef struct HEVCDSPContext {
+ void (*put_pcm)(uint8_t *_dst, ptrdiff_t _stride, int size,
+ GetBitContext *gb, int pcm_bit_depth);
+
+ void (*transquant_bypass[4])(uint8_t *_dst, int16_t *coeffs, ptrdiff_t _stride);
+
+ void (*transform_skip)(uint8_t *dst, int16_t *coeffs, ptrdiff_t stride);
+
+ void (*transform_4x4_luma_add)(uint8_t *dst, int16_t *coeffs, ptrdiff_t stride);
+
+ void (*transform_add[4])(uint8_t *dst, int16_t *coeffs, ptrdiff_t _stride);
+
+ void (*sao_band_filter[4])( uint8_t *_dst, uint8_t *_src, ptrdiff_t _stride, struct SAOParams *sao, int *borders, int width, int height, int c_idx);
+
+ void (*sao_edge_filter[4])(uint8_t *_dst, uint8_t *_src, ptrdiff_t _stride, struct SAOParams *sao, int *borders, int _width, int _height, int c_idx, uint8_t vert_edge, uint8_t horiz_edge, uint8_t diag_edge);
+
+
+ void (*put_hevc_qpel[4][4])(int16_t *dst, ptrdiff_t dststride, uint8_t *src, ptrdiff_t srcstride,
+ int width, int height, int16_t* mcbuffer);
+
+ void (*put_hevc_epel[2][2])(int16_t *dst, ptrdiff_t dststride, uint8_t *src, ptrdiff_t srcstride,
+ int width, int height, int mx, int my, int16_t* mcbuffer);
+
+ void (*put_unweighted_pred)(uint8_t *dst, ptrdiff_t dststride, int16_t *src, ptrdiff_t srcstride,
+ int width, int height);
+
+ void (*put_weighted_pred_avg)(uint8_t *dst, ptrdiff_t dststride, int16_t *src1, int16_t *src2,
+ ptrdiff_t srcstride, int width, int height);
+ void (*weighted_pred)(uint8_t denom, int16_t wlxFlag, int16_t olxFlag, uint8_t *dst, ptrdiff_t dststride, int16_t *src,
+ ptrdiff_t srcstride, int width, int height);
+ void (*weighted_pred_avg)(uint8_t denom, int16_t wl0Flag, int16_t wl1Flag, int16_t ol0Flag, int16_t ol1Flag,
+ uint8_t *dst, ptrdiff_t dststride, int16_t *src1, int16_t *src2,
+ ptrdiff_t srcstride, int width, int height);
+ void (*hevc_h_loop_filter_luma)(uint8_t *_pix, ptrdiff_t _stride, int *_beta, int *_tc, uint8_t *_no_p, uint8_t *_no_q);
+ void (*hevc_v_loop_filter_luma)(uint8_t *_pix, ptrdiff_t _stride, int *_beta, int *_tc, uint8_t *_no_p, uint8_t *_no_q);
+ void (*hevc_h_loop_filter_chroma)(uint8_t *_pix, ptrdiff_t _stride, int *_tc, uint8_t *_no_p, uint8_t *_no_q);
+ void (*hevc_v_loop_filter_chroma)(uint8_t *_pix, ptrdiff_t _stride, int *_tc, uint8_t *_no_p, uint8_t *_no_q);
+ void (*hevc_h_loop_filter_luma_c)(uint8_t *_pix, ptrdiff_t _stride, int *_beta, int *_tc, uint8_t *_no_p, uint8_t *_no_q);
+ void (*hevc_v_loop_filter_luma_c)(uint8_t *_pix, ptrdiff_t _stride, int *_beta, int *_tc, uint8_t *_no_p, uint8_t *_no_q);
+ void (*hevc_h_loop_filter_chroma_c)(uint8_t *_pix, ptrdiff_t _stride, int *_tc, uint8_t *_no_p, uint8_t *_no_q);
+ void (*hevc_v_loop_filter_chroma_c)(uint8_t *_pix, ptrdiff_t _stride, int *_tc, uint8_t *_no_p, uint8_t *_no_q);
+} HEVCDSPContext;
+
+void ff_hevc_dsp_init(HEVCDSPContext *hpc, int bit_depth);
+
+extern const int8_t ff_hevc_epel_filters[7][16];
+
+#endif /* AVCODEC_HEVCDSP_H */
diff --git a/libavcodec/hevcdsp_template.c b/libavcodec/hevcdsp_template.c
new file mode 100644
index 0000000..c9386e0
--- /dev/null
+++ b/libavcodec/hevcdsp_template.c
@@ -0,0 +1,1372 @@
+/*
+ * HEVC video decoder
+ *
+ * Copyright (C) 2012 - 2013 Guillaume Martres
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "get_bits.h"
+#include "hevc.h"
+
+#include "bit_depth_template.c"
+#include "hevcdsp.h"
+
+
+static void FUNC(put_pcm)(uint8_t *_dst, ptrdiff_t stride, int size,
+ GetBitContext *gb, int pcm_bit_depth)
+{
+ int x, y;
+ pixel *dst = (pixel *)_dst;
+
+ stride /= sizeof(pixel);
+
+ for (y = 0; y < size; y++) {
+ for (x = 0; x < size; x++)
+ dst[x] = get_bits(gb, pcm_bit_depth) << (BIT_DEPTH - pcm_bit_depth);
+ dst += stride;
+ }
+}
+
+static void FUNC(transquant_bypass4x4)(uint8_t *_dst, int16_t *coeffs,
+ ptrdiff_t stride)
+{
+ int x, y;
+ pixel *dst = (pixel *)_dst;
+
+ stride /= sizeof(pixel);
+
+ for (y = 0; y < 4; y++) {
+ for (x = 0; x < 4; x++) {
+ dst[x] += *coeffs;
+ coeffs++;
+ }
+ dst += stride;
+ }
+}
+
+static void FUNC(transquant_bypass8x8)(uint8_t *_dst, int16_t *coeffs,
+ ptrdiff_t stride)
+{
+ int x, y;
+ pixel *dst = (pixel *)_dst;
+
+ stride /= sizeof(pixel);
+
+ for (y = 0; y < 8; y++) {
+ for (x = 0; x < 8; x++) {
+ dst[x] += *coeffs;
+ coeffs++;
+ }
+ dst += stride;
+ }
+}
+
+static void FUNC(transquant_bypass16x16)(uint8_t *_dst, int16_t *coeffs,
+ ptrdiff_t stride)
+{
+ int x, y;
+ pixel *dst = (pixel *)_dst;
+
+ stride /= sizeof(pixel);
+
+ for (y = 0; y < 16; y++) {
+ for (x = 0; x < 16; x++) {
+ dst[x] += *coeffs;
+ coeffs++;
+ }
+ dst += stride;
+ }
+}
+
+static void FUNC(transquant_bypass32x32)(uint8_t *_dst, int16_t *coeffs,
+ ptrdiff_t stride)
+{
+ int x, y;
+ pixel *dst = (pixel *)_dst;
+
+ stride /= sizeof(pixel);
+
+ for (y = 0; y < 32; y++) {
+ for (x = 0; x < 32; x++) {
+ dst[x] += *coeffs;
+ coeffs++;
+ }
+ dst += stride;
+ }
+}
+
+static void FUNC(transform_skip)(uint8_t *_dst, int16_t *coeffs,
+ ptrdiff_t stride)
+{
+ pixel *dst = (pixel *)_dst;
+ int shift = 13 - BIT_DEPTH;
+#if BIT_DEPTH <= 13
+ int offset = 1 << (shift - 1);
+#else
+ int offset = 0;
+#endif
+ int x, y;
+
+ stride /= sizeof(pixel);
+
+ for (y = 0; y < 4 * 4; y += 4) {
+ for (x = 0; x < 4; x++)
+ dst[x] = av_clip_pixel(dst[x] + ((coeffs[y + x] + offset) >> shift));
+ dst += stride;
+ }
+}
+
+#define SET(dst, x) (dst) = (x)
+#define SCALE(dst, x) (dst) = av_clip_int16(((x) + add) >> shift)
+#define ADD_AND_SCALE(dst, x) \
+ (dst) = av_clip_pixel((dst) + av_clip_int16(((x) + add) >> shift))
+
+#define TR_4x4_LUMA(dst, src, step, assign) \
+ do { \
+ int c0 = src[0 * step] + src[2 * step]; \
+ int c1 = src[2 * step] + src[3 * step]; \
+ int c2 = src[0 * step] - src[3 * step]; \
+ int c3 = 74 * src[1 * step]; \
+ \
+ assign(dst[2 * step], 74 * (src[0 * step] - \
+ src[2 * step] + \
+ src[3 * step])); \
+ assign(dst[0 * step], 29 * c0 + 55 * c1 + c3); \
+ assign(dst[1 * step], 55 * c2 - 29 * c1 + c3); \
+ assign(dst[3 * step], 55 * c0 + 29 * c2 - c3); \
+ } while (0)
+
+static void FUNC(transform_4x4_luma_add)(uint8_t *_dst, int16_t *coeffs,
+ ptrdiff_t stride)
+{
+ int i;
+ pixel *dst = (pixel *)_dst;
+ int shift = 7;
+ int add = 1 << (shift - 1);
+ int16_t *src = coeffs;
+
+ stride /= sizeof(pixel);
+
+ for (i = 0; i < 4; i++) {
+ TR_4x4_LUMA(src, src, 4, SCALE);
+ src++;
+ }
+
+ shift = 20 - BIT_DEPTH;
+ add = 1 << (shift - 1);
+ for (i = 0; i < 4; i++) {
+ TR_4x4_LUMA(dst, coeffs, 1, ADD_AND_SCALE);
+ coeffs += 4;
+ dst += stride;
+ }
+}
+
+#undef TR_4x4_LUMA
+
+#define TR_4(dst, src, dstep, sstep, assign) \
+ do { \
+ const int e0 = transform[8 * 0][0] * src[0 * sstep] + \
+ transform[8 * 2][0] * src[2 * sstep]; \
+ const int e1 = transform[8 * 0][1] * src[0 * sstep] + \
+ transform[8 * 2][1] * src[2 * sstep]; \
+ const int o0 = transform[8 * 1][0] * src[1 * sstep] + \
+ transform[8 * 3][0] * src[3 * sstep]; \
+ const int o1 = transform[8 * 1][1] * src[1 * sstep] + \
+ transform[8 * 3][1] * src[3 * sstep]; \
+ \
+ assign(dst[0 * dstep], e0 + o0); \
+ assign(dst[1 * dstep], e1 + o1); \
+ assign(dst[2 * dstep], e1 - o1); \
+ assign(dst[3 * dstep], e0 - o0); \
+ } while (0)
+#define TR_4_1(dst, src) TR_4(dst, src, 4, 4, SCALE)
+#define TR_4_2(dst, src) TR_4(dst, src, 1, 1, ADD_AND_SCALE)
+
+static void FUNC(transform_4x4_add)(uint8_t *_dst, int16_t *coeffs,
+ ptrdiff_t stride)
+{
+ int i;
+ pixel *dst = (pixel *)_dst;
+ int shift = 7;
+ int add = 1 << (shift - 1);
+ int16_t *src = coeffs;
+
+ stride /= sizeof(pixel);
+
+ for (i = 0; i < 4; i++) {
+ TR_4_1(src, src);
+ src++;
+ }
+
+ shift = 20 - BIT_DEPTH;
+ add = 1 << (shift - 1);
+ for (i = 0; i < 4; i++) {
+ TR_4_2(dst, coeffs);
+ coeffs += 4;
+ dst += stride;
+ }
+}
+
+#define TR_8(dst, src, dstep, sstep, assign) \
+ do { \
+ int i, j; \
+ int e_8[4]; \
+ int o_8[4] = { 0 }; \
+ for (i = 0; i < 4; i++) \
+ for (j = 1; j < 8; j += 2) \
+ o_8[i] += transform[4 * j][i] * src[j * sstep]; \
+ TR_4(e_8, src, 1, 2 * sstep, SET); \
+ \
+ for (i = 0; i < 4; i++) { \
+ assign(dst[i * dstep], e_8[i] + o_8[i]); \
+ assign(dst[(7 - i) * dstep], e_8[i] - o_8[i]); \
+ } \
+ } while (0)
+
+#define TR_16(dst, src, dstep, sstep, assign) \
+ do { \
+ int i, j; \
+ int e_16[8]; \
+ int o_16[8] = { 0 }; \
+ for (i = 0; i < 8; i++) \
+ for (j = 1; j < 16; j += 2) \
+ o_16[i] += transform[2 * j][i] * src[j * sstep]; \
+ TR_8(e_16, src, 1, 2 * sstep, SET); \
+ \
+ for (i = 0; i < 8; i++) { \
+ assign(dst[i * dstep], e_16[i] + o_16[i]); \
+ assign(dst[(15 - i) * dstep], e_16[i] - o_16[i]); \
+ } \
+ } while (0)
+
+#define TR_32(dst, src, dstep, sstep, assign) \
+ do { \
+ int i, j; \
+ int e_32[16]; \
+ int o_32[16] = { 0 }; \
+ for (i = 0; i < 16; i++) \
+ for (j = 1; j < 32; j += 2) \
+ o_32[i] += transform[j][i] * src[j * sstep]; \
+ TR_16(e_32, src, 1, 2 * sstep, SET); \
+ \
+ for (i = 0; i < 16; i++) { \
+ assign(dst[i * dstep], e_32[i] + o_32[i]); \
+ assign(dst[(31 - i) * dstep], e_32[i] - o_32[i]); \
+ } \
+ } while (0)
+
+#define TR_8_1(dst, src) TR_8(dst, src, 8, 8, SCALE)
+#define TR_16_1(dst, src) TR_16(dst, src, 16, 16, SCALE)
+#define TR_32_1(dst, src) TR_32(dst, src, 32, 32, SCALE)
+
+#define TR_8_2(dst, src) TR_8(dst, src, 1, 1, ADD_AND_SCALE)
+#define TR_16_2(dst, src) TR_16(dst, src, 1, 1, ADD_AND_SCALE)
+#define TR_32_2(dst, src) TR_32(dst, src, 1, 1, ADD_AND_SCALE)
+
+static void FUNC(transform_8x8_add)(uint8_t *_dst, int16_t *coeffs,
+ ptrdiff_t stride)
+{
+ int i;
+ pixel *dst = (pixel *)_dst;
+ int shift = 7;
+ int add = 1 << (shift - 1);
+ int16_t *src = coeffs;
+
+ stride /= sizeof(pixel);
+
+ for (i = 0; i < 8; i++) {
+ TR_8_1(src, src);
+ src++;
+ }
+
+ shift = 20 - BIT_DEPTH;
+ add = 1 << (shift - 1);
+ for (i = 0; i < 8; i++) {
+ TR_8_2(dst, coeffs);
+ coeffs += 8;
+ dst += stride;
+ }
+}
+
+static void FUNC(transform_16x16_add)(uint8_t *_dst, int16_t *coeffs,
+ ptrdiff_t stride)
+{
+ int i;
+ pixel *dst = (pixel *)_dst;
+ int shift = 7;
+ int add = 1 << (shift - 1);
+ int16_t *src = coeffs;
+
+ stride /= sizeof(pixel);
+
+ for (i = 0; i < 16; i++) {
+ TR_16_1(src, src);
+ src++;
+ }
+
+ shift = 20 - BIT_DEPTH;
+ add = 1 << (shift - 1);
+ for (i = 0; i < 16; i++) {
+ TR_16_2(dst, coeffs);
+ coeffs += 16;
+ dst += stride;
+ }
+}
+
+static void FUNC(transform_32x32_add)(uint8_t *_dst, int16_t *coeffs,
+ ptrdiff_t stride)
+{
+#define IT32x32_even(i,w) ( src[ 0*w] * transform[ 0][i] ) + ( src[16*w] * transform[16][i] )
+#define IT32x32_odd(i,w) ( src[ 8*w] * transform[ 8][i] ) + ( src[24*w] * transform[24][i] )
+#define IT16x16(i,w) ( src[ 4*w] * transform[ 4][i] ) + ( src[12*w] * transform[12][i] ) + ( src[20*w] * transform[20][i] ) + ( src[28*w] * transform[28][i] )
+#define IT8x8(i,w) ( src[ 2*w] * transform[ 2][i] ) + ( src[ 6*w] * transform[ 6][i] ) + ( src[10*w] * transform[10][i] ) + ( src[14*w] * transform[14][i] ) + \
+ ( src[18*w] * transform[18][i] ) + ( src[22*w] * transform[22][i] ) + ( src[26*w] * transform[26][i] ) + ( src[30*w] * transform[30][i] )
+#define IT4x4(i,w) ( src[ 1*w] * transform[ 1][i] ) + ( src[ 3*w] * transform[ 3][i] ) + ( src[ 5*w] * transform[ 5][i] ) + ( src[ 7*w] * transform[ 7][i] ) + \
+ ( src[ 9*w] * transform[ 9][i] ) + ( src[11*w] * transform[11][i] ) + ( src[13*w] * transform[13][i] ) + ( src[15*w] * transform[15][i] ) + \
+ ( src[17*w] * transform[17][i] ) + ( src[19*w] * transform[19][i] ) + ( src[21*w] * transform[21][i] ) + ( src[23*w] * transform[23][i] ) + \
+ ( src[25*w] * transform[25][i] ) + ( src[27*w] * transform[27][i] ) + ( src[29*w] * transform[29][i] ) + ( src[31*w] * transform[31][i] )
+ int i;
+ pixel *dst = (pixel *)_dst;
+ int shift = 7;
+ int add = 1 << (shift - 1);
+ int16_t *src = coeffs;
+
+ stride /= sizeof(pixel);
+
+ for (i = 0; i < 32; i++) {
+ TR_32_1(src, src);
+ src++;
+ }
+ src = coeffs;
+ shift = 20 - BIT_DEPTH;
+ add = 1 << (shift - 1);
+ for (i = 0; i < 32; i++) {
+ TR_32_2(dst, coeffs);
+ coeffs += 32;
+ dst += stride;
+ }
+#undef IT32x32_even
+#undef IT32x32_odd
+#undef IT16x16
+#undef IT8x8
+#undef IT4x4
+}
+
+static void FUNC(sao_band_filter)(uint8_t *_dst, uint8_t *_src,
+ ptrdiff_t stride, SAOParams *sao,
+ int *borders, int width, int height,
+ int c_idx, int class)
+{
+ pixel *dst = (pixel *)_dst;
+ pixel *src = (pixel *)_src;
+ int offset_table[32] = { 0 };
+ int k, y, x;
+ int chroma = !!c_idx;
+ int shift = BIT_DEPTH - 5;
+ int *sao_offset_val = sao->offset_val[c_idx];
+ int sao_left_class = sao->band_position[c_idx];
+ int init_y = 0, init_x = 0;
+
+ stride /= sizeof(pixel);
+
+ switch (class) {
+ case 0:
+ if (!borders[2])
+ width -= (8 >> chroma) + 2;
+ if (!borders[3])
+ height -= (4 >> chroma) + 2;
+ break;
+ case 1:
+ init_y = -(4 >> chroma) - 2;
+ if (!borders[2])
+ width -= (8 >> chroma) + 2;
+ height = (4 >> chroma) + 2;
+ break;
+ case 2:
+ init_x = -(8 >> chroma) - 2;
+ width = (8 >> chroma) + 2;
+ if (!borders[3])
+ height -= (4 >> chroma) + 2;
+ break;
+ case 3:
+ init_y = -(4 >> chroma) - 2;
+ init_x = -(8 >> chroma) - 2;
+ width = (8 >> chroma) + 2;
+ height = (4 >> chroma) + 2;
+ break;
+ }
+
+ dst = dst + (init_y * stride + init_x);
+ src = src + (init_y * stride + init_x);
+ for (k = 0; k < 4; k++)
+ offset_table[(k + sao_left_class) & 31] = sao_offset_val[k + 1];
+ for (y = 0; y < height; y++) {
+ for (x = 0; x < width; x++)
+ dst[x] = av_clip_pixel(src[x] + offset_table[av_clip_pixel(src[x] >> shift)]);
+ dst += stride;
+ src += stride;
+ }
+}
+
+static void FUNC(sao_band_filter_0)(uint8_t *dst, uint8_t *src,
+ ptrdiff_t stride, SAOParams *sao,
+ int *borders, int width, int height,
+ int c_idx)
+{
+ FUNC(sao_band_filter)(dst, src, stride, sao, borders,
+ width, height, c_idx, 0);
+}
+
+static void FUNC(sao_band_filter_1)(uint8_t *dst, uint8_t *src,
+ ptrdiff_t stride, SAOParams *sao,
+ int *borders, int width, int height,
+ int c_idx)
+{
+ FUNC(sao_band_filter)(dst, src, stride, sao, borders,
+ width, height, c_idx, 1);
+}
+
+static void FUNC(sao_band_filter_2)(uint8_t *dst, uint8_t *src,
+ ptrdiff_t stride, SAOParams *sao,
+ int *borders, int width, int height,
+ int c_idx)
+{
+ FUNC(sao_band_filter)(dst, src, stride, sao, borders,
+ width, height, c_idx, 2);
+}
+
+static void FUNC(sao_band_filter_3)(uint8_t *_dst, uint8_t *_src,
+ ptrdiff_t stride, SAOParams *sao,
+ int *borders, int width, int height,
+ int c_idx)
+{
+ FUNC(sao_band_filter)(_dst, _src, stride, sao, borders,
+ width, height, c_idx, 3);
+}
+
+static void FUNC(sao_edge_filter_0)(uint8_t *_dst, uint8_t *_src,
+ ptrdiff_t stride, SAOParams *sao,
+ int *borders, int _width, int _height,
+ int c_idx, uint8_t vert_edge,
+ uint8_t horiz_edge, uint8_t diag_edge)
+{
+ int x, y;
+ pixel *dst = (pixel *)_dst;
+ pixel *src = (pixel *)_src;
+ int chroma = !!c_idx;
+ int *sao_offset_val = sao->offset_val[c_idx];
+ int sao_eo_class = sao->eo_class[c_idx];
+ int init_x = 0, init_y = 0, width = _width, height = _height;
+
+ static const int8_t pos[4][2][2] = {
+ { { -1, 0 }, { 1, 0 } }, // horizontal
+ { { 0, -1 }, { 0, 1 } }, // vertical
+ { { -1, -1 }, { 1, 1 } }, // 45 degree
+ { { 1, -1 }, { -1, 1 } }, // 135 degree
+ };
+ static const uint8_t edge_idx[] = { 1, 2, 0, 3, 4 };
+
+#define CMP(a, b) ((a) > (b) ? 1 : ((a) == (b) ? 0 : -1))
+
+ stride /= sizeof(pixel);
+
+ if (!borders[2])
+ width -= (8 >> chroma) + 2;
+ if (!borders[3])
+ height -= (4 >> chroma) + 2;
+
+ dst = dst + (init_y * stride + init_x);
+ src = src + (init_y * stride + init_x);
+ init_y = init_x = 0;
+ if (sao_eo_class != SAO_EO_VERT) {
+ if (borders[0]) {
+ int offset_val = sao_offset_val[0];
+ int y_stride = 0;
+ for (y = 0; y < height; y++) {
+ dst[y_stride] = av_clip_pixel(src[y_stride] + offset_val);
+ y_stride += stride;
+ }
+ init_x = 1;
+ }
+ if (borders[2]) {
+ int offset_val = sao_offset_val[0];
+ int x_stride = width - 1;
+ for (x = 0; x < height; x++) {
+ dst[x_stride] = av_clip_pixel(src[x_stride] + offset_val);
+ x_stride += stride;
+ }
+ width--;
+ }
+ }
+ if (sao_eo_class != SAO_EO_HORIZ) {
+ if (borders[1]) {
+ int offset_val = sao_offset_val[0];
+ for (x = init_x; x < width; x++)
+ dst[x] = av_clip_pixel(src[x] + offset_val);
+ init_y = 1;
+ }
+ if (borders[3]) {
+ int offset_val = sao_offset_val[0];
+ int y_stride = stride * (height - 1);
+ for (x = init_x; x < width; x++)
+ dst[x + y_stride] = av_clip_pixel(src[x + y_stride] + offset_val);
+ height--;
+ }
+ }
+ {
+ int y_stride = init_y * stride;
+ int pos_0_0 = pos[sao_eo_class][0][0];
+ int pos_0_1 = pos[sao_eo_class][0][1];
+ int pos_1_0 = pos[sao_eo_class][1][0];
+ int pos_1_1 = pos[sao_eo_class][1][1];
+
+ int y_stride_0_1 = (init_y + pos_0_1) * stride;
+ int y_stride_1_1 = (init_y + pos_1_1) * stride;
+ for (y = init_y; y < height; y++) {
+ for (x = init_x; x < width; x++) {
+ int diff0 = CMP(src[x + y_stride], src[x + pos_0_0 + y_stride_0_1]);
+ int diff1 = CMP(src[x + y_stride], src[x + pos_1_0 + y_stride_1_1]);
+ int offset_val = edge_idx[2 + diff0 + diff1];
+ dst[x + y_stride] = av_clip_pixel(src[x + y_stride] + sao_offset_val[offset_val]);
+ }
+ y_stride += stride;
+ y_stride_0_1 += stride;
+ y_stride_1_1 += stride;
+ }
+ }
+
+ {
+ // Restore pixels that can't be modified
+ int save_upper_left = !diag_edge && sao_eo_class == SAO_EO_135D && !borders[0] && !borders[1];
+ if (vert_edge && sao_eo_class != SAO_EO_VERT)
+ for (y = init_y+save_upper_left; y< height; y++)
+ dst[y*stride] = src[y*stride];
+ if(horiz_edge && sao_eo_class != SAO_EO_HORIZ)
+ for(x = init_x+save_upper_left; x<width; x++)
+ dst[x] = src[x];
+ if(diag_edge && sao_eo_class == SAO_EO_135D)
+ dst[0] = src[0];
+ }
+
+#undef CMP
+}
+
+static void FUNC(sao_edge_filter_1)(uint8_t *_dst, uint8_t *_src,
+ ptrdiff_t stride, SAOParams *sao,
+ int *borders, int _width, int _height,
+ int c_idx, uint8_t vert_edge,
+ uint8_t horiz_edge, uint8_t diag_edge)
+{
+ int x, y;
+ pixel *dst = (pixel *)_dst;
+ pixel *src = (pixel *)_src;
+ int chroma = !!c_idx;
+ int *sao_offset_val = sao->offset_val[c_idx];
+ int sao_eo_class = sao->eo_class[c_idx];
+ int init_x = 0, init_y = 0, width = _width, height = _height;
+
+ static const int8_t pos[4][2][2] = {
+ { { -1, 0 }, { 1, 0 } }, // horizontal
+ { { 0, -1 }, { 0, 1 } }, // vertical
+ { { -1, -1 }, { 1, 1 } }, // 45 degree
+ { { 1, -1 }, { -1, 1 } }, // 135 degree
+ };
+ static const uint8_t edge_idx[] = { 1, 2, 0, 3, 4 };
+
+#define CMP(a, b) ((a) > (b) ? 1 : ((a) == (b) ? 0 : -1))
+
+ stride /= sizeof(pixel);
+
+ init_y = -(4 >> chroma) - 2;
+ if (!borders[2])
+ width -= (8 >> chroma) + 2;
+ height = (4 >> chroma) + 2;
+
+ dst = dst + (init_y * stride + init_x);
+ src = src + (init_y * stride + init_x);
+ init_y = init_x = 0;
+ if (sao_eo_class != SAO_EO_VERT) {
+ if (borders[0]) {
+ int offset_val = sao_offset_val[0];
+ int y_stride = 0;
+ for (y = 0; y < height; y++) {
+ dst[y_stride] = av_clip_pixel(src[y_stride] + offset_val);
+ y_stride += stride;
+ }
+ init_x = 1;
+ }
+ if (borders[2]) {
+ int offset_val = sao_offset_val[0];
+ int x_stride = width - 1;
+ for (x = 0; x < height; x++) {
+ dst[x_stride] = av_clip_pixel(src[x_stride] + offset_val);
+ x_stride += stride;
+ }
+ width--;
+ }
+ }
+ {
+ int y_stride = init_y * stride;
+ int pos_0_0 = pos[sao_eo_class][0][0];
+ int pos_0_1 = pos[sao_eo_class][0][1];
+ int pos_1_0 = pos[sao_eo_class][1][0];
+ int pos_1_1 = pos[sao_eo_class][1][1];
+
+ int y_stride_0_1 = (init_y + pos_0_1) * stride;
+ int y_stride_1_1 = (init_y + pos_1_1) * stride;
+ for (y = init_y; y < height; y++) {
+ for (x = init_x; x < width; x++) {
+ int diff0 = CMP(src[x + y_stride], src[x + pos_0_0 + y_stride_0_1]);
+ int diff1 = CMP(src[x + y_stride], src[x + pos_1_0 + y_stride_1_1]);
+ int offset_val = edge_idx[2 + diff0 + diff1];
+ dst[x + y_stride] = av_clip_pixel(src[x + y_stride] + sao_offset_val[offset_val]);
+ }
+ y_stride += stride;
+ y_stride_0_1 += stride;
+ y_stride_1_1 += stride;
+ }
+ }
+
+ {
+ // Restore pixels that can't be modified
+ int save_lower_left = !diag_edge && sao_eo_class == SAO_EO_45D && !borders[0];
+ if(vert_edge && sao_eo_class != SAO_EO_VERT)
+ for(y = init_y; y< height-save_lower_left; y++)
+ dst[y*stride] = src[y*stride];
+ if(horiz_edge && sao_eo_class != SAO_EO_HORIZ)
+ for(x = init_x+save_lower_left; x<width; x++)
+ dst[(height-1)*stride+x] = src[(height-1)*stride+x];
+ if(diag_edge && sao_eo_class == SAO_EO_45D)
+ dst[stride*(height-1)] = src[stride*(height-1)];
+ }
+
+#undef CMP
+}
+
+static void FUNC(sao_edge_filter_2)(uint8_t *_dst, uint8_t *_src,
+ ptrdiff_t stride, SAOParams *sao,
+ int *borders, int _width, int _height,
+ int c_idx, uint8_t vert_edge,
+ uint8_t horiz_edge, uint8_t diag_edge)
+{
+ int x, y;
+ pixel *dst = (pixel *)_dst;
+ pixel *src = (pixel *)_src;
+ int chroma = !!c_idx;
+ int *sao_offset_val = sao->offset_val[c_idx];
+ int sao_eo_class = sao->eo_class[c_idx];
+
+ static const int8_t pos[4][2][2] = {
+ { { -1, 0 }, { 1, 0 } }, // horizontal
+ { { 0, -1 }, { 0, 1 } }, // vertical
+ { { -1, -1 }, { 1, 1 } }, // 45 degree
+ { { 1, -1 }, { -1, 1 } }, // 135 degree
+ };
+ static const uint8_t edge_idx[] = { 1, 2, 0, 3, 4 };
+
+ int init_x = 0, init_y = 0, width = _width, height = _height;
+
+#define CMP(a, b) ((a) > (b) ? 1 : ((a) == (b) ? 0 : -1))
+ stride /= sizeof(pixel);
+
+ init_x = -(8 >> chroma) - 2;
+ width = (8 >> chroma) + 2;
+ if (!borders[3])
+ height -= (4 >> chroma) + 2;
+
+ dst = dst + (init_y * stride + init_x);
+ src = src + (init_y * stride + init_x);
+ init_y = init_x = 0;
+ if (sao_eo_class != SAO_EO_HORIZ) {
+ if (borders[1]) {
+ int offset_val = sao_offset_val[0];
+ for (x = init_x; x < width; x++)
+ dst[x] = av_clip_pixel(src[x] + offset_val);
+ init_y = 1;
+ }
+ if (borders[3]) {
+ int offset_val = sao_offset_val[0];
+ int y_stride = stride * (height - 1);
+ for (x = init_x; x < width; x++)
+ dst[x + y_stride] = av_clip_pixel(src[x + y_stride] + offset_val);
+ height--;
+ }
+ }
+ {
+ int y_stride = init_y * stride;
+ int pos_0_0 = pos[sao_eo_class][0][0];
+ int pos_0_1 = pos[sao_eo_class][0][1];
+ int pos_1_0 = pos[sao_eo_class][1][0];
+ int pos_1_1 = pos[sao_eo_class][1][1];
+
+ int y_stride_0_1 = (init_y + pos_0_1) * stride;
+ int y_stride_1_1 = (init_y + pos_1_1) * stride;
+ for (y = init_y; y < height; y++) {
+ for (x = init_x; x < width; x++) {
+ int diff0 = CMP(src[x + y_stride], src[x + pos_0_0 + y_stride_0_1]);
+ int diff1 = CMP(src[x + y_stride], src[x + pos_1_0 + y_stride_1_1]);
+ int offset_val = edge_idx[2 + diff0 + diff1];
+ dst[x + y_stride] = av_clip_pixel(src[x + y_stride] + sao_offset_val[offset_val]);
+ }
+ y_stride += stride;
+ y_stride_0_1 += stride;
+ y_stride_1_1 += stride;
+ }
+ }
+
+ {
+ // Restore pixels that can't be modified
+ int save_upper_right = !diag_edge && sao_eo_class == SAO_EO_45D && !borders[1];
+ if(vert_edge && sao_eo_class != SAO_EO_VERT)
+ for(y = init_y+save_upper_right; y< height; y++)
+ dst[y*stride+width-1] = src[y*stride+width-1];
+ if(horiz_edge && sao_eo_class != SAO_EO_HORIZ)
+ for(x = init_x; x<width-save_upper_right; x++)
+ dst[x] = src[x];
+ if(diag_edge && sao_eo_class == SAO_EO_45D)
+ dst[width-1] = src[width-1];
+ }
+#undef CMP
+}
+
+static void FUNC(sao_edge_filter_3)(uint8_t *_dst, uint8_t *_src,
+ ptrdiff_t stride, SAOParams *sao,
+ int *borders, int _width, int _height,
+ int c_idx, uint8_t vert_edge,
+ uint8_t horiz_edge, uint8_t diag_edge)
+{
+ int x, y;
+ pixel *dst = (pixel *)_dst;
+ pixel *src = (pixel *)_src;
+ int chroma = !!c_idx;
+ int *sao_offset_val = sao->offset_val[c_idx];
+ int sao_eo_class = sao->eo_class[c_idx];
+ int init_x = 0, init_y = 0, width = _width, height = _height;
+
+ static const int8_t pos[4][2][2] = {
+ { { -1, 0 }, { 1, 0 } }, // horizontal
+ { { 0, -1 }, { 0, 1 } }, // vertical
+ { { -1, -1 }, { 1, 1 } }, // 45 degree
+ { { 1, -1 }, { -1, 1 } }, // 135 degree
+ };
+ static const uint8_t edge_idx[] = { 1, 2, 0, 3, 4 };
+
+#define CMP(a, b) ((a) > (b) ? 1 : ((a) == (b) ? 0 : -1))
+
+ stride /= sizeof(pixel);
+
+ init_y = -(4 >> chroma) - 2;
+ init_x = -(8 >> chroma) - 2;
+ width = (8 >> chroma) + 2;
+ height = (4 >> chroma) + 2;
+
+
+ dst = dst + (init_y * stride + init_x);
+ src = src + (init_y * stride + init_x);
+ init_y = init_x = 0;
+
+ {
+ int y_stride = init_y * stride;
+ int pos_0_0 = pos[sao_eo_class][0][0];
+ int pos_0_1 = pos[sao_eo_class][0][1];
+ int pos_1_0 = pos[sao_eo_class][1][0];
+ int pos_1_1 = pos[sao_eo_class][1][1];
+
+ int y_stride_0_1 = (init_y + pos_0_1) * stride;
+ int y_stride_1_1 = (init_y + pos_1_1) * stride;
+
+ for (y = init_y; y < height; y++) {
+ for (x = init_x; x < width; x++) {
+ int diff0 = CMP(src[x + y_stride], src[x + pos_0_0 + y_stride_0_1]);
+ int diff1 = CMP(src[x + y_stride], src[x + pos_1_0 + y_stride_1_1]);
+ int offset_val = edge_idx[2 + diff0 + diff1];
+ dst[x + y_stride] = av_clip_pixel(src[x + y_stride] + sao_offset_val[offset_val]);
+ }
+ y_stride += stride;
+ y_stride_0_1 += stride;
+ y_stride_1_1 += stride;
+ }
+ }
+
+ {
+ // Restore pixels that can't be modified
+ int save_lower_right = !diag_edge && sao_eo_class == SAO_EO_135D;
+ if(vert_edge && sao_eo_class != SAO_EO_VERT)
+ for(y = init_y; y< height-save_lower_right; y++)
+ dst[y*stride+width-1] = src[y*stride+width-1];
+ if(horiz_edge && sao_eo_class != SAO_EO_HORIZ)
+ for(x = init_x; x<width-save_lower_right; x++)
+ dst[(height-1)*stride+x] = src[(height-1)*stride+x];
+ if(diag_edge && sao_eo_class == SAO_EO_135D)
+ dst[stride*(height-1)+width-1] = src[stride*(height-1)+width-1];
+ }
+#undef CMP
+}
+
+#undef SET
+#undef SCALE
+#undef ADD_AND_SCALE
+#undef TR_4
+#undef TR_4_1
+#undef TR_4_2
+#undef TR_8
+#undef TR_8_1
+#undef TR_8_2
+#undef TR_16
+#undef TR_16_1
+#undef TR_16_2
+#undef TR_32
+#undef TR_32_1
+#undef TR_32_2
+
+static void FUNC(put_hevc_qpel_pixels)(int16_t *dst, ptrdiff_t dststride,
+ uint8_t *_src, ptrdiff_t _srcstride,
+ int width, int height, int16_t* mcbuffer)
+{
+ int x, y;
+ pixel *src = (pixel *)_src;
+ ptrdiff_t srcstride = _srcstride / sizeof(pixel);
+
+ for (y = 0; y < height; y++) {
+ for (x = 0; x < width; x++)
+ dst[x] = src[x] << (14 - BIT_DEPTH);
+ src += srcstride;
+ dst += dststride;
+ }
+}
+
+#define QPEL_FILTER_1(src, stride) \
+ (1 * -src[x - 3 * stride] + \
+ 4 * src[x - 2 * stride] - \
+ 10 * src[x - stride] + \
+ 58 * src[x] + \
+ 17 * src[x + stride] - \
+ 5 * src[x + 2 * stride] + \
+ 1 * src[x + 3 * stride])
+
+#define QPEL_FILTER_2(src, stride) \
+ (1 * -src[x - 3 * stride] + \
+ 4 * src[x - 2 * stride] - \
+ 11 * src[x - stride] + \
+ 40 * src[x] + \
+ 40 * src[x + stride] - \
+ 11 * src[x + 2 * stride] + \
+ 4 * src[x + 3 * stride] - \
+ 1 * src[x + 4 * stride])
+
+#define QPEL_FILTER_3(src, stride) \
+ (1 * src[x - 2 * stride] - \
+ 5 * src[x - stride] + \
+ 17 * src[x] + \
+ 58 * src[x + stride] - \
+ 10 * src[x + 2 * stride] + \
+ 4 * src[x + 3 * stride] - \
+ 1 * src[x + 4 * stride])
+
+
+#define PUT_HEVC_QPEL_H(H) \
+static void FUNC(put_hevc_qpel_h ## H)(int16_t *dst, ptrdiff_t dststride, \
+ uint8_t *_src, ptrdiff_t _srcstride, \
+ int width, int height, \
+ int16_t* mcbuffer) \
+{ \
+ int x, y; \
+ pixel *src = (pixel*)_src; \
+ ptrdiff_t srcstride = _srcstride / sizeof(pixel); \
+ \
+ for (y = 0; y < height; y++) { \
+ for (x = 0; x < width; x++) \
+ dst[x] = QPEL_FILTER_ ## H(src, 1) >> (BIT_DEPTH - 8); \
+ src += srcstride; \
+ dst += dststride; \
+ } \
+}
+
+#define PUT_HEVC_QPEL_V(V) \
+static void FUNC(put_hevc_qpel_v ## V)(int16_t *dst, ptrdiff_t dststride, \
+ uint8_t *_src, ptrdiff_t _srcstride, \
+ int width, int height, \
+ int16_t* mcbuffer) \
+{ \
+ int x, y; \
+ pixel *src = (pixel*)_src; \
+ ptrdiff_t srcstride = _srcstride / sizeof(pixel); \
+ \
+ for (y = 0; y < height; y++) { \
+ for (x = 0; x < width; x++) \
+ dst[x] = QPEL_FILTER_ ## V(src, srcstride) >> (BIT_DEPTH - 8); \
+ src += srcstride; \
+ dst += dststride; \
+ } \
+}
+
+#define PUT_HEVC_QPEL_HV(H, V) \
+static void FUNC(put_hevc_qpel_h ## H ## v ## V)(int16_t *dst, \
+ ptrdiff_t dststride, \
+ uint8_t *_src, \
+ ptrdiff_t _srcstride, \
+ int width, int height, \
+ int16_t* mcbuffer) \
+{ \
+ int x, y; \
+ pixel *src = (pixel*)_src; \
+ ptrdiff_t srcstride = _srcstride / sizeof(pixel); \
+ \
+ int16_t tmp_array[(MAX_PB_SIZE + 7) * MAX_PB_SIZE]; \
+ int16_t *tmp = tmp_array; \
+ \
+ src -= ff_hevc_qpel_extra_before[V] * srcstride; \
+ \
+ for (y = 0; y < height + ff_hevc_qpel_extra[V]; y++) { \
+ for (x = 0; x < width; x++) \
+ tmp[x] = QPEL_FILTER_ ## H(src, 1) >> (BIT_DEPTH - 8); \
+ src += srcstride; \
+ tmp += MAX_PB_SIZE; \
+ } \
+ \
+ tmp = tmp_array + ff_hevc_qpel_extra_before[V] * MAX_PB_SIZE; \
+ \
+ for (y = 0; y < height; y++) { \
+ for (x = 0; x < width; x++) \
+ dst[x] = QPEL_FILTER_ ## V(tmp, MAX_PB_SIZE) >> 6; \
+ tmp += MAX_PB_SIZE; \
+ dst += dststride; \
+ } \
+}
+
+PUT_HEVC_QPEL_H(1)
+PUT_HEVC_QPEL_H(2)
+PUT_HEVC_QPEL_H(3)
+PUT_HEVC_QPEL_V(1)
+PUT_HEVC_QPEL_V(2)
+PUT_HEVC_QPEL_V(3)
+PUT_HEVC_QPEL_HV(1, 1)
+PUT_HEVC_QPEL_HV(1, 2)
+PUT_HEVC_QPEL_HV(1, 3)
+PUT_HEVC_QPEL_HV(2, 1)
+PUT_HEVC_QPEL_HV(2, 2)
+PUT_HEVC_QPEL_HV(2, 3)
+PUT_HEVC_QPEL_HV(3, 1)
+PUT_HEVC_QPEL_HV(3, 2)
+PUT_HEVC_QPEL_HV(3, 3)
+
+static void FUNC(put_hevc_epel_pixels)(int16_t *dst, ptrdiff_t dststride,
+ uint8_t *_src, ptrdiff_t _srcstride,
+ int width, int height, int mx, int my,
+ int16_t* mcbuffer)
+{
+ int x, y;
+ pixel *src = (pixel *)_src;
+ ptrdiff_t srcstride = _srcstride / sizeof(pixel);
+
+ for (y = 0; y < height; y++) {
+ for (x = 0; x < width; x++)
+ dst[x] = src[x] << (14 - BIT_DEPTH);
+ src += srcstride;
+ dst += dststride;
+ }
+}
+
+#define EPEL_FILTER(src, stride) \
+ (filter_0 * src[x - stride] + \
+ filter_1 * src[x] + \
+ filter_2 * src[x + stride] + \
+ filter_3 * src[x + 2 * stride])
+
+static void FUNC(put_hevc_epel_h)(int16_t *dst, ptrdiff_t dststride,
+ uint8_t *_src, ptrdiff_t _srcstride,
+ int width, int height, int mx, int my,
+ int16_t* mcbuffer)
+{
+ int x, y;
+ pixel *src = (pixel *)_src;
+ ptrdiff_t srcstride = _srcstride / sizeof(pixel);
+ const int8_t *filter = ff_hevc_epel_filters[mx - 1];
+ int8_t filter_0 = filter[0];
+ int8_t filter_1 = filter[1];
+ int8_t filter_2 = filter[2];
+ int8_t filter_3 = filter[3];
+ for (y = 0; y < height; y++) {
+ for (x = 0; x < width; x++)
+ dst[x] = EPEL_FILTER(src, 1) >> (BIT_DEPTH - 8);
+ src += srcstride;
+ dst += dststride;
+ }
+}
+
+static void FUNC(put_hevc_epel_v)(int16_t *dst, ptrdiff_t dststride,
+ uint8_t *_src, ptrdiff_t _srcstride,
+ int width, int height, int mx, int my,
+ int16_t* mcbuffer)
+{
+ int x, y;
+ pixel *src = (pixel *)_src;
+ ptrdiff_t srcstride = _srcstride / sizeof(pixel);
+ const int8_t *filter = ff_hevc_epel_filters[my - 1];
+ int8_t filter_0 = filter[0];
+ int8_t filter_1 = filter[1];
+ int8_t filter_2 = filter[2];
+ int8_t filter_3 = filter[3];
+
+ for (y = 0; y < height; y++) {
+ for (x = 0; x < width; x++)
+ dst[x] = EPEL_FILTER(src, srcstride) >> (BIT_DEPTH - 8);
+ src += srcstride;
+ dst += dststride;
+ }
+}
+
+static void FUNC(put_hevc_epel_hv)(int16_t *dst, ptrdiff_t dststride,
+ uint8_t *_src, ptrdiff_t _srcstride,
+ int width, int height, int mx, int my,
+ int16_t* mcbuffer)
+{
+ int x, y;
+ pixel *src = (pixel *)_src;
+ ptrdiff_t srcstride = _srcstride / sizeof(pixel);
+ const int8_t *filter_h = ff_hevc_epel_filters[mx - 1];
+ const int8_t *filter_v = ff_hevc_epel_filters[my - 1];
+ int8_t filter_0 = filter_h[0];
+ int8_t filter_1 = filter_h[1];
+ int8_t filter_2 = filter_h[2];
+ int8_t filter_3 = filter_h[3];
+ int16_t tmp_array[(MAX_PB_SIZE + 3) * MAX_PB_SIZE];
+ int16_t *tmp = tmp_array;
+
+ src -= EPEL_EXTRA_BEFORE * srcstride;
+
+ for (y = 0; y < height + EPEL_EXTRA; y++) {
+ for (x = 0; x < width; x++)
+ tmp[x] = EPEL_FILTER(src, 1) >> (BIT_DEPTH - 8);
+ src += srcstride;
+ tmp += MAX_PB_SIZE;
+ }
+
+ tmp = tmp_array + EPEL_EXTRA_BEFORE * MAX_PB_SIZE;
+ filter_0 = filter_v[0];
+ filter_1 = filter_v[1];
+ filter_2 = filter_v[2];
+ filter_3 = filter_v[3];
+ for (y = 0; y < height; y++) {
+ for (x = 0; x < width; x++)
+ dst[x] = EPEL_FILTER(tmp, MAX_PB_SIZE) >> 6;
+ tmp += MAX_PB_SIZE;
+ dst += dststride;
+ }
+}
+
+static void FUNC(put_unweighted_pred)(uint8_t *_dst, ptrdiff_t _dststride,
+ int16_t *src, ptrdiff_t srcstride,
+ int width, int height)
+{
+ int x, y;
+ pixel *dst = (pixel *)_dst;
+ ptrdiff_t dststride = _dststride / sizeof(pixel);
+
+ int shift = 14 - BIT_DEPTH;
+#if BIT_DEPTH < 14
+ int offset = 1 << (shift - 1);
+#else
+ int offset = 0;
+#endif
+ for (y = 0; y < height; y++) {
+ for (x = 0; x < width; x++)
+ dst[x] = av_clip_pixel((src[x] + offset) >> shift);
+ dst += dststride;
+ src += srcstride;
+ }
+}
+
+static void FUNC(put_weighted_pred_avg)(uint8_t *_dst, ptrdiff_t _dststride,
+ int16_t *src1, int16_t *src2,
+ ptrdiff_t srcstride,
+ int width, int height)
+{
+ int x, y;
+ pixel *dst = (pixel *)_dst;
+ ptrdiff_t dststride = _dststride / sizeof(pixel);
+
+ int shift = 14 + 1 - BIT_DEPTH;
+#if BIT_DEPTH < 14
+ int offset = 1 << (shift - 1);
+#else
+ int offset = 0;
+#endif
+
+ for (y = 0; y < height; y++) {
+ for (x = 0; x < width; x++)
+ dst[x] = av_clip_pixel((src1[x] + src2[x] + offset) >> shift);
+ dst += dststride;
+ src1 += srcstride;
+ src2 += srcstride;
+ }
+}
+
+static void FUNC(weighted_pred)(uint8_t denom, int16_t wlxFlag, int16_t olxFlag,
+ uint8_t *_dst, ptrdiff_t _dststride,
+ int16_t *src, ptrdiff_t srcstride,
+ int width, int height)
+{
+ int shift, log2Wd, wx, ox, x, y, offset;
+ pixel *dst = (pixel *)_dst;
+ ptrdiff_t dststride = _dststride / sizeof(pixel);
+
+ shift = 14 - BIT_DEPTH;
+ log2Wd = denom + shift;
+ offset = 1 << (log2Wd - 1);
+ wx = wlxFlag;
+ ox = olxFlag * (1 << (BIT_DEPTH - 8));
+
+ for (y = 0; y < height; y++) {
+ for (x = 0; x < width; x++) {
+ if (log2Wd >= 1) {
+ dst[x] = av_clip_pixel(((src[x] * wx + offset) >> log2Wd) + ox);
+ } else {
+ dst[x] = av_clip_pixel(src[x] * wx + ox);
+ }
+ }
+ dst += dststride;
+ src += srcstride;
+ }
+}
+
+static void FUNC(weighted_pred_avg)(uint8_t denom,
+ int16_t wl0Flag, int16_t wl1Flag,
+ int16_t ol0Flag, int16_t ol1Flag,
+ uint8_t *_dst, ptrdiff_t _dststride,
+ int16_t *src1, int16_t *src2,
+ ptrdiff_t srcstride,
+ int width, int height)
+{
+ int shift, log2Wd, w0, w1, o0, o1, x, y;
+ pixel *dst = (pixel *)_dst;
+ ptrdiff_t dststride = _dststride / sizeof(pixel);
+
+ shift = 14 - BIT_DEPTH;
+ log2Wd = denom + shift;
+ w0 = wl0Flag;
+ w1 = wl1Flag;
+ o0 = ol0Flag * (1 << (BIT_DEPTH - 8));
+ o1 = ol1Flag * (1 << (BIT_DEPTH - 8));
+
+ for (y = 0; y < height; y++) {
+ for (x = 0; x < width; x++)
+ dst[x] = av_clip_pixel((src1[x] * w0 + src2[x] * w1 +
+ ((o0 + o1 + 1) << log2Wd)) >> (log2Wd + 1));
+ dst += dststride;
+ src1 += srcstride;
+ src2 += srcstride;
+ }
+}
+
+// line zero
+#define P3 pix[-4 * xstride]
+#define P2 pix[-3 * xstride]
+#define P1 pix[-2 * xstride]
+#define P0 pix[-1 * xstride]
+#define Q0 pix[0 * xstride]
+#define Q1 pix[1 * xstride]
+#define Q2 pix[2 * xstride]
+#define Q3 pix[3 * xstride]
+
+// line three. used only for deblocking decision
+#define TP3 pix[-4 * xstride + 3 * ystride]
+#define TP2 pix[-3 * xstride + 3 * ystride]
+#define TP1 pix[-2 * xstride + 3 * ystride]
+#define TP0 pix[-1 * xstride + 3 * ystride]
+#define TQ0 pix[0 * xstride + 3 * ystride]
+#define TQ1 pix[1 * xstride + 3 * ystride]
+#define TQ2 pix[2 * xstride + 3 * ystride]
+#define TQ3 pix[3 * xstride + 3 * ystride]
+
+static void FUNC(hevc_loop_filter_luma)(uint8_t *_pix,
+ ptrdiff_t _xstride, ptrdiff_t _ystride,
+ int *_beta, int *_tc,
+ uint8_t *_no_p, uint8_t *_no_q)
+{
+ int d, j;
+ pixel *pix = (pixel *)_pix;
+ ptrdiff_t xstride = _xstride / sizeof(pixel);
+ ptrdiff_t ystride = _ystride / sizeof(pixel);
+
+ for (j = 0; j < 2; j++) {
+ const int dp0 = abs(P2 - 2 * P1 + P0);
+ const int dq0 = abs(Q2 - 2 * Q1 + Q0);
+ const int dp3 = abs(TP2 - 2 * TP1 + TP0);
+ const int dq3 = abs(TQ2 - 2 * TQ1 + TQ0);
+ const int d0 = dp0 + dq0;
+ const int d3 = dp3 + dq3;
+ const int beta = _beta[j] << (BIT_DEPTH - 8);
+ const int tc = _tc[j] << (BIT_DEPTH - 8);
+ const int no_p = _no_p[j];
+ const int no_q = _no_q[j];
+
+ if (d0 + d3 >= beta /*|| tc <= 0*/) {
+ pix += 4 * ystride;
+ continue;
+ } else {
+ const int beta_3 = beta >> 3;
+ const int beta_2 = beta >> 2;
+ const int tc25 = ((tc * 5 + 1) >> 1);
+
+ if (abs(P3 - P0) + abs(Q3 - Q0) < beta_3 && abs(P0 - Q0) < tc25 &&
+ abs(TP3 - TP0) + abs(TQ3 - TQ0) < beta_3 && abs(TP0 - TQ0) < tc25 &&
+ (d0 << 1) < beta_2 && (d3 << 1) < beta_2) {
+ // strong filtering
+ const int tc2 = tc << 1;
+ for (d = 0; d < 4; d++) {
+ const int p3 = P3;
+ const int p2 = P2;
+ const int p1 = P1;
+ const int p0 = P0;
+ const int q0 = Q0;
+ const int q1 = Q1;
+ const int q2 = Q2;
+ const int q3 = Q3;
+ if (!no_p) {
+ P0 = p0 + av_clip(((p2 + 2 * p1 + 2 * p0 + 2 * q0 + q1 + 4) >> 3) - p0, -tc2, tc2);
+ P1 = p1 + av_clip(((p2 + p1 + p0 + q0 + 2) >> 2) - p1, -tc2, tc2);
+ P2 = p2 + av_clip(((2 * p3 + 3 * p2 + p1 + p0 + q0 + 4) >> 3) - p2, -tc2, tc2);
+ }
+ if (!no_q) {
+ Q0 = q0 + av_clip(((p1 + 2 * p0 + 2 * q0 + 2 * q1 + q2 + 4) >> 3) - q0, -tc2, tc2);
+ Q1 = q1 + av_clip(((p0 + q0 + q1 + q2 + 2) >> 2) - q1, -tc2, tc2);
+ Q2 = q2 + av_clip(((2 * q3 + 3 * q2 + q1 + q0 + p0 + 4) >> 3) - q2, -tc2, tc2);
+ }
+ pix += ystride;
+ }
+ } else { // normal filtering
+ int nd_p = 1;
+ int nd_q = 1;
+ const int tc_2 = tc >> 1;
+ if (dp0 + dp3 < ((beta + (beta >> 1)) >> 3))
+ nd_p = 2;
+ if (dq0 + dq3 < ((beta + (beta >> 1)) >> 3))
+ nd_q = 2;
+
+ for (d = 0; d < 4; d++) {
+ const int p2 = P2;
+ const int p1 = P1;
+ const int p0 = P0;
+ const int q0 = Q0;
+ const int q1 = Q1;
+ const int q2 = Q2;
+ int delta0 = (9 * (q0 - p0) - 3 * (q1 - p1) + 8) >> 4;
+ if (abs(delta0) < 10 * tc) {
+ delta0 = av_clip(delta0, -tc, tc);
+ if (!no_p)
+ P0 = av_clip_pixel(p0 + delta0);
+ if (!no_q)
+ Q0 = av_clip_pixel(q0 - delta0);
+ if (!no_p && nd_p > 1) {
+ const int deltap1 = av_clip((((p2 + p0 + 1) >> 1) - p1 + delta0) >> 1, -tc_2, tc_2);
+ P1 = av_clip_pixel(p1 + deltap1);
+ }
+ if (!no_q && nd_q > 1) {
+ const int deltaq1 = av_clip((((q2 + q0 + 1) >> 1) - q1 - delta0) >> 1, -tc_2, tc_2);
+ Q1 = av_clip_pixel(q1 + deltaq1);
+ }
+ }
+ pix += ystride;
+ }
+ }
+ }
+ }
+}
+
+static void FUNC(hevc_loop_filter_chroma)(uint8_t *_pix, ptrdiff_t _xstride,
+ ptrdiff_t _ystride, int *_tc,
+ uint8_t *_no_p, uint8_t *_no_q)
+{
+ int d, j, no_p, no_q;
+ pixel *pix = (pixel *)_pix;
+ ptrdiff_t xstride = _xstride / sizeof(pixel);
+ ptrdiff_t ystride = _ystride / sizeof(pixel);
+
+ for (j = 0; j < 2; j++) {
+ const int tc = _tc[j] << (BIT_DEPTH - 8);
+ if (tc <= 0) {
+ pix += 4 * ystride;
+ continue;
+ }
+ no_p = _no_p[j];
+ no_q = _no_q[j];
+
+ for (d = 0; d < 4; d++) {
+ int delta0;
+ const int p1 = P1;
+ const int p0 = P0;
+ const int q0 = Q0;
+ const int q1 = Q1;
+ delta0 = av_clip((((q0 - p0) << 2) + p1 - q1 + 4) >> 3, -tc, tc);
+ if (!no_p)
+ P0 = av_clip_pixel(p0 + delta0);
+ if (!no_q)
+ Q0 = av_clip_pixel(q0 - delta0);
+ pix += ystride;
+ }
+ }
+}
+
+static void FUNC(hevc_h_loop_filter_chroma)(uint8_t *pix, ptrdiff_t stride,
+ int *tc, uint8_t *no_p,
+ uint8_t *no_q)
+{
+ FUNC(hevc_loop_filter_chroma)(pix, stride, sizeof(pixel), tc, no_p, no_q);
+}
+
+static void FUNC(hevc_v_loop_filter_chroma)(uint8_t *pix, ptrdiff_t stride,
+ int *tc, uint8_t *no_p,
+ uint8_t *no_q)
+{
+ FUNC(hevc_loop_filter_chroma)(pix, sizeof(pixel), stride, tc, no_p, no_q);
+}
+
+static void FUNC(hevc_h_loop_filter_luma)(uint8_t *pix, ptrdiff_t stride,
+ int *beta, int *tc, uint8_t *no_p,
+ uint8_t *no_q)
+{
+ FUNC(hevc_loop_filter_luma)(pix, stride, sizeof(pixel),
+ beta, tc, no_p, no_q);
+}
+
+static void FUNC(hevc_v_loop_filter_luma)(uint8_t *pix, ptrdiff_t stride,
+ int *beta, int *tc, uint8_t *no_p,
+ uint8_t *no_q)
+{
+ FUNC(hevc_loop_filter_luma)(pix, sizeof(pixel), stride,
+ beta, tc, no_p, no_q);
+}
+
+#undef P3
+#undef P2
+#undef P1
+#undef P0
+#undef Q0
+#undef Q1
+#undef Q2
+#undef Q3
+
+#undef TP3
+#undef TP2
+#undef TP1
+#undef TP0
+#undef TQ0
+#undef TQ1
+#undef TQ2
+#undef TQ3
diff --git a/libavcodec/hevcpred.c b/libavcodec/hevcpred.c
new file mode 100644
index 0000000..e4987f8
--- /dev/null
+++ b/libavcodec/hevcpred.c
@@ -0,0 +1,67 @@
+/*
+ * HEVC video Decoder
+ *
+ * Copyright (C) 2012 - 2013 Guillaume Martres
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "hevc.h"
+
+#include "hevcpred.h"
+
+#define BIT_DEPTH 8
+#include "hevcpred_template.c"
+#undef BIT_DEPTH
+
+#define BIT_DEPTH 9
+#include "hevcpred_template.c"
+#undef BIT_DEPTH
+
+#define BIT_DEPTH 10
+#include "hevcpred_template.c"
+#undef BIT_DEPTH
+
+void ff_hevc_pred_init(HEVCPredContext *hpc, int bit_depth)
+{
+#undef FUNC
+#define FUNC(a, depth) a ## _ ## depth
+
+#define HEVC_PRED(depth) \
+ hpc->intra_pred = FUNC(intra_pred, depth); \
+ hpc->pred_planar[0] = FUNC(pred_planar_0, depth); \
+ hpc->pred_planar[1] = FUNC(pred_planar_1, depth); \
+ hpc->pred_planar[2] = FUNC(pred_planar_2, depth); \
+ hpc->pred_planar[3] = FUNC(pred_planar_3, depth); \
+ hpc->pred_dc = FUNC(pred_dc, depth); \
+ hpc->pred_angular[0] = FUNC(pred_angular_0, depth); \
+ hpc->pred_angular[1] = FUNC(pred_angular_1, depth); \
+ hpc->pred_angular[2] = FUNC(pred_angular_2, depth); \
+ hpc->pred_angular[3] = FUNC(pred_angular_3, depth);
+
+ switch (bit_depth) {
+ case 9:
+ HEVC_PRED(9);
+ break;
+ case 10:
+ HEVC_PRED(10);
+ break;
+ default:
+ HEVC_PRED(8);
+ break;
+ }
+}
diff --git a/libavcodec/hevcpred.h b/libavcodec/hevcpred.h
new file mode 100644
index 0000000..4dead2e
--- /dev/null
+++ b/libavcodec/hevcpred.h
@@ -0,0 +1,43 @@
+/*
+ * HEVC video Decoder
+ *
+ * Copyright (C) 2012 - 2013 Guillaume Martres
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVCODEC_HEVCPRED_H
+#define AVCODEC_HEVCPRED_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+struct HEVCContext;
+
+typedef struct HEVCPredContext {
+ void (*intra_pred)(struct HEVCContext *s, int x0, int y0, int log2_size, int c_idx);
+
+ void(*pred_planar[4])(uint8_t *src, const uint8_t *top, const uint8_t *left, ptrdiff_t stride);
+ void(*pred_dc)(uint8_t *src, const uint8_t *top, const uint8_t *left, ptrdiff_t stride,
+ int log2_size, int c_idx);
+ void(*pred_angular[4])(uint8_t *src, const uint8_t *top, const uint8_t *left, ptrdiff_t stride,
+ int c_idx, int mode);
+} HEVCPredContext;
+
+void ff_hevc_pred_init(HEVCPredContext *hpc, int bit_depth);
+
+#endif /* AVCODEC_HEVCPRED_H */
diff --git a/libavcodec/hevcpred_template.c b/libavcodec/hevcpred_template.c
new file mode 100644
index 0000000..5ba9591
--- /dev/null
+++ b/libavcodec/hevcpred_template.c
@@ -0,0 +1,559 @@
+/*
+ * HEVC video decoder
+ *
+ * Copyright (C) 2012 - 2013 Guillaume Martres
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "libavutil/pixdesc.h"
+
+#include "bit_depth_template.c"
+#include "hevcpred.h"
+
+#define POS(x, y) src[(x) + stride * (y)]
+
+static void FUNC(intra_pred)(HEVCContext *s, int x0, int y0, int log2_size, int c_idx)
+{
+#define PU(x) \
+ ((x) >> s->sps->log2_min_pu_size)
+#define MVF(x, y) \
+ (s->ref->tab_mvf[(x) + (y) * min_pu_width])
+#define MVF_PU(x, y) \
+ MVF(PU(x0 + ((x) << hshift)), PU(y0 + ((y) << vshift)))
+#define IS_INTRA(x, y) \
+ MVF_PU(x, y).is_intra
+#define MIN_TB_ADDR_ZS(x, y) \
+ s->pps->min_tb_addr_zs[(y) * s->sps->min_tb_width + (x)]
+#define EXTEND_LEFT(ptr, start, length) \
+ for (i = (start); i > (start) - (length); i--) \
+ ptr[i - 1] = ptr[i]
+#define EXTEND_RIGHT(ptr, start, length) \
+ for (i = (start); i < (start) + (length); i++) \
+ ptr[i] = ptr[i - 1]
+#define EXTEND_UP(ptr, start, length) EXTEND_LEFT(ptr, start, length)
+#define EXTEND_DOWN(ptr, start, length) EXTEND_RIGHT(ptr, start, length)
+#define EXTEND_LEFT_CIP(ptr, start, length) \
+ for (i = (start); i > (start) - (length); i--) \
+ if (!IS_INTRA(i - 1, -1)) \
+ ptr[i - 1] = ptr[i]
+#define EXTEND_RIGHT_CIP(ptr, start, length) \
+ for (i = (start); i < (start) + (length); i++) \
+ if (!IS_INTRA(i, -1)) \
+ ptr[i] = ptr[i - 1]
+#define EXTEND_UP_CIP(ptr, start, length) \
+ for (i = (start); i > (start) - (length); i--) \
+ if (!IS_INTRA(-1, i - 1)) \
+ ptr[i - 1] = ptr[i]
+#define EXTEND_UP_CIP_0(ptr, start, length) \
+ for (i = (start); i > (start) - (length); i--) \
+ ptr[i - 1] = ptr[i]
+#define EXTEND_DOWN_CIP(ptr, start, length) \
+ for (i = (start); i < (start) + (length); i++) \
+ if (!IS_INTRA(-1, i)) \
+ ptr[i] = ptr[i - 1]
+ HEVCLocalContext *lc = s->HEVClc;
+ int i;
+ int hshift = s->sps->hshift[c_idx];
+ int vshift = s->sps->vshift[c_idx];
+ int size = (1 << log2_size);
+ int size_in_luma = size << hshift;
+ int size_in_tbs = size_in_luma >> s->sps->log2_min_tb_size;
+ int x = x0 >> hshift;
+ int y = y0 >> vshift;
+ int x_tb = x0 >> s->sps->log2_min_tb_size;
+ int y_tb = y0 >> s->sps->log2_min_tb_size;
+ int cur_tb_addr = MIN_TB_ADDR_ZS(x_tb, y_tb);
+
+ ptrdiff_t stride = s->frame->linesize[c_idx] / sizeof(pixel);
+ pixel *src = (pixel*)s->frame->data[c_idx] + x + y * stride;
+
+ int min_pu_width = s->sps->min_pu_width;
+
+ enum IntraPredMode mode = c_idx ? lc->pu.intra_pred_mode_c :
+ lc->tu.cur_intra_pred_mode;
+
+ pixel left_array[2 * MAX_TB_SIZE + 1];
+ pixel filtered_left_array[2 * MAX_TB_SIZE + 1];
+ pixel top_array[2 * MAX_TB_SIZE + 1];
+ pixel filtered_top_array[2 * MAX_TB_SIZE + 1];
+
+ pixel *left = left_array + 1;
+ pixel *top = top_array + 1;
+ pixel *filtered_left = filtered_left_array + 1;
+ pixel *filtered_top = filtered_top_array + 1;
+
+ int cand_bottom_left = lc->na.cand_bottom_left && cur_tb_addr > MIN_TB_ADDR_ZS(x_tb - 1, y_tb + size_in_tbs);
+ int cand_left = lc->na.cand_left;
+ int cand_up_left = lc->na.cand_up_left;
+ int cand_up = lc->na.cand_up;
+ int cand_up_right = lc->na.cand_up_right && cur_tb_addr > MIN_TB_ADDR_ZS(x_tb + size_in_tbs, y_tb - 1);
+
+ int bottom_left_size = (FFMIN(y0 + 2 * size_in_luma, s->sps->height) -
+ (y0 + size_in_luma)) >> vshift;
+ int top_right_size = (FFMIN(x0 + 2 * size_in_luma, s->sps->width) -
+ (x0 + size_in_luma)) >> hshift;
+
+ if (s->pps->constrained_intra_pred_flag == 1) {
+ int size_in_luma_pu = PU(size_in_luma);
+ int on_pu_edge_x = !(x0 & ((1 << s->sps->log2_min_pu_size) - 1));
+ int on_pu_edge_y = !(y0 & ((1 << s->sps->log2_min_pu_size) - 1));
+ if (!size_in_luma_pu)
+ size_in_luma_pu++;
+ if (cand_bottom_left == 1 && on_pu_edge_x) {
+ int x_left_pu = PU(x0 - 1);
+ int y_bottom_pu = PU(y0 + size_in_luma);
+ int max = FFMIN(size_in_luma_pu, s->sps->min_pu_height - y_bottom_pu);
+ cand_bottom_left = 0;
+ for (i = 0; i < max; i++)
+ cand_bottom_left |= MVF(x_left_pu, y_bottom_pu + i).is_intra;
+ }
+ if (cand_left == 1 && on_pu_edge_x) {
+ int x_left_pu = PU(x0 - 1);
+ int y_left_pu = PU(y0);
+ int max = FFMIN(size_in_luma_pu, s->sps->min_pu_height - y_left_pu);
+ cand_left = 0;
+ for (i = 0; i < max; i++)
+ cand_left |= MVF(x_left_pu, y_left_pu + i).is_intra;
+ }
+ if (cand_up_left == 1) {
+ int x_left_pu = PU(x0 - 1);
+ int y_top_pu = PU(y0 - 1);
+ cand_up_left = MVF(x_left_pu, y_top_pu).is_intra;
+ }
+ if (cand_up == 1 && on_pu_edge_y) {
+ int x_top_pu = PU(x0);
+ int y_top_pu = PU(y0 - 1);
+ int max = FFMIN(size_in_luma_pu, s->sps->min_pu_width - x_top_pu);
+ cand_up = 0;
+ for (i = 0; i < max; i++)
+ cand_up |= MVF(x_top_pu + i, y_top_pu).is_intra;
+ }
+ if (cand_up_right == 1 && on_pu_edge_y) {
+ int y_top_pu = PU(y0 - 1);
+ int x_right_pu = PU(x0 + size_in_luma);
+ int max = FFMIN(size_in_luma_pu, s->sps->min_pu_width - x_right_pu);
+ cand_up_right = 0;
+ for (i = 0; i < max; i++)
+ cand_up_right |= MVF(x_right_pu + i, y_top_pu).is_intra;
+ }
+ for (i = 0; i < 2 * MAX_TB_SIZE; i++) {
+ left[i] = 128;
+ top[i] = 128;
+ }
+ }
+ if (cand_bottom_left) {
+ for (i = size + bottom_left_size; i < (size << 1); i++)
+ if (IS_INTRA(-1, size + bottom_left_size - 1) ||
+ !s->pps->constrained_intra_pred_flag)
+ left[i] = POS(-1, size + bottom_left_size - 1);
+ for (i = size + bottom_left_size - 1; i >= size; i--)
+ if (IS_INTRA(-1, i) || !s->pps->constrained_intra_pred_flag)
+ left[i] = POS(-1, i);
+ }
+ if (cand_left)
+ for (i = size - 1; i >= 0; i--)
+ if (IS_INTRA(-1, i) || !s->pps->constrained_intra_pred_flag)
+ left[i] = POS(-1, i);
+ if (cand_up_left)
+ if (IS_INTRA(-1, -1) || !s->pps->constrained_intra_pred_flag) {
+ left[-1] = POS(-1, -1);
+ top[-1] = left[-1];
+ }
+ if (cand_up)
+ for (i = size - 1; i >= 0; i--)
+ if (IS_INTRA(i, -1) || !s->pps->constrained_intra_pred_flag)
+ top[i] = POS(i, -1);
+ if (cand_up_right) {
+ for (i = size + top_right_size; i < (size << 1); i++)
+ if (IS_INTRA(size + top_right_size - 1, -1) ||
+ !s->pps->constrained_intra_pred_flag)
+ top[i] = POS(size + top_right_size - 1, -1);
+ for (i = size + top_right_size - 1; i >= size; i--)
+ if (IS_INTRA(i, -1) || !s->pps->constrained_intra_pred_flag)
+ top[i] = POS(i, -1);
+ }
+
+ if (s->pps->constrained_intra_pred_flag == 1) {
+ if (cand_bottom_left || cand_left || cand_up_left || cand_up || cand_up_right) {
+ int size_max_x = x0 + ((2 * size) << hshift) < s->sps->width ?
+ 2 * size : (s->sps->width - x0) >> hshift;
+ int size_max_y = y0 + ((2 * size) << vshift) < s->sps->height ?
+ 2 * size : (s->sps->height - y0) >> vshift;
+ int j = size + (cand_bottom_left? bottom_left_size: 0) -1;
+ if (!cand_up_right) {
+ size_max_x = x0 + ((size) << hshift) < s->sps->width ?
+ size : (s->sps->width - x0) >> hshift;
+ }
+ if (!cand_bottom_left) {
+ size_max_y = y0 + (( size) << vshift) < s->sps->height ?
+ size : (s->sps->height - y0) >> vshift;
+ }
+ if (cand_bottom_left || cand_left || cand_up_left) {
+ while (j > -1 && !IS_INTRA(-1, j))
+ j--;
+ if (!IS_INTRA(-1, j)) {
+ j = 0;
+ while (j < size_max_x && !IS_INTRA(j, -1))
+ j++;
+ EXTEND_LEFT_CIP(top, j, j + 1);
+ left[-1] = top[-1];
+ j = 0;
+ }
+ } else {
+ j = 0;
+ while (j < size_max_x && !IS_INTRA(j, -1))
+ j++;
+ if (j > 0)
+ if (x0 > 0) {
+ EXTEND_LEFT_CIP(top, j, j + 1);
+ } else {
+ EXTEND_LEFT_CIP(top, j, j);
+ top[-1] = top[0];
+ }
+ left[-1] = top[-1];
+ j = 0;
+ }
+ if (cand_bottom_left || cand_left) {
+ EXTEND_DOWN_CIP(left, j, size_max_y - j);
+ }
+ if (!cand_left) {
+ EXTEND_DOWN(left, 0, size);
+ }
+ if (!cand_bottom_left) {
+ EXTEND_DOWN(left, size, size);
+ }
+ if (x0 != 0 && y0 != 0) {
+ EXTEND_UP_CIP(left, size_max_y - 1, size_max_y);
+ } else if (x0 == 0) {
+ EXTEND_UP_CIP_0(left, size_max_y - 1, size_max_y);
+ } else {
+ EXTEND_UP_CIP(left, size_max_y - 1, size_max_y - 1);
+ }
+ top[-1] = left[-1];
+ if (y0 != 0) {
+ EXTEND_RIGHT_CIP(top, 0, size_max_x);
+ }
+ }
+ }
+ // Infer the unavailable samples
+ if (!cand_bottom_left) {
+ if (cand_left) {
+ EXTEND_DOWN(left, size, size);
+ } else if (cand_up_left) {
+ EXTEND_DOWN(left, 0, 2 * size);
+ cand_left = 1;
+ } else if (cand_up) {
+ left[-1] = top[0];
+ EXTEND_DOWN(left, 0, 2 * size);
+ cand_up_left = 1;
+ cand_left = 1;
+ } else if (cand_up_right) {
+ EXTEND_LEFT(top, size, size);
+ left[-1] = top[0];
+ EXTEND_DOWN(left, 0, 2 * size);
+ cand_up = 1;
+ cand_up_left = 1;
+ cand_left = 1;
+ } else { // No samples available
+ top[0] = left[-1] = (1 << (BIT_DEPTH - 1));
+ EXTEND_RIGHT(top, 1, 2 * size - 1);
+ EXTEND_DOWN(left, 0, 2 * size);
+ }
+ }
+
+ if (!cand_left) {
+ EXTEND_UP(left, size, size);
+ }
+ if (!cand_up_left) {
+ left[-1] = left[0];
+ }
+ if (!cand_up) {
+ top[0] = left[-1];
+ EXTEND_RIGHT(top, 1, size - 1);
+ }
+ if (!cand_up_right) {
+ EXTEND_RIGHT(top, size, size);
+ }
+
+ top[-1] = left[-1];
+
+ // Filtering process
+ if (c_idx == 0 && mode != INTRA_DC && size != 4) {
+ int intra_hor_ver_dist_thresh[] = { 7, 1, 0 };
+ int min_dist_vert_hor = FFMIN(FFABS((int)(mode - 26U)),
+ FFABS((int)(mode - 10U)));
+ if (min_dist_vert_hor > intra_hor_ver_dist_thresh[log2_size - 3]) {
+ int threshold = 1 << (BIT_DEPTH - 5);
+ if (s->sps->sps_strong_intra_smoothing_enable_flag &&
+ log2_size == 5 &&
+ FFABS(top[-1] + top[63] - 2 * top[31]) < threshold &&
+ FFABS(left[-1] + left[63] - 2 * left[31]) < threshold) {
+ // We can't just overwrite values in top because it could be
+ // a pointer into src
+ filtered_top[-1] = top[-1];
+ filtered_top[63] = top[63];
+ for (i = 0; i < 63; i++)
+ filtered_top[i] = ((64 - (i + 1)) * top[-1] +
+ (i + 1) * top[63] + 32) >> 6;
+ for (i = 0; i < 63; i++)
+ left[i] = ((64 - (i + 1)) * left[-1] +
+ (i + 1) * left[63] + 32) >> 6;
+ top = filtered_top;
+ } else {
+ filtered_left[2 * size - 1] = left[2 * size - 1];
+ filtered_top[2 * size - 1] = top[2 * size - 1];
+ for (i = 2 * size - 2; i >= 0; i--)
+ filtered_left[i] = (left[i + 1] + 2 * left[i] +
+ left[i - 1] + 2) >> 2;
+ filtered_top[-1] =
+ filtered_left[-1] = (left[0] + 2 * left[-1] + top[0] + 2) >> 2;
+ for (i = 2 * size - 2; i >= 0; i--)
+ filtered_top[i] = (top[i + 1] + 2 * top[i] +
+ top[i - 1] + 2) >> 2;
+ left = filtered_left;
+ top = filtered_top;
+ }
+ }
+ }
+
+ switch (mode) {
+ case INTRA_PLANAR:
+ s->hpc.pred_planar[log2_size - 2]((uint8_t *)src, (uint8_t *)top,
+ (uint8_t *)left, stride);
+ break;
+ case INTRA_DC:
+ s->hpc.pred_dc((uint8_t *)src, (uint8_t *)top,
+ (uint8_t *)left, stride, log2_size, c_idx);
+ break;
+ default:
+ s->hpc.pred_angular[log2_size - 2]((uint8_t *)src, (uint8_t *)top,
+ (uint8_t *)left, stride, c_idx,
+ mode);
+ break;
+ }
+}
+
+static void FUNC(pred_planar_0)(uint8_t *_src, const uint8_t *_top,
+ const uint8_t *_left,
+ ptrdiff_t stride)
+{
+ int x, y;
+ pixel *src = (pixel *)_src;
+ const pixel *top = (const pixel *)_top;
+ const pixel *left = (const pixel *)_left;
+ for (y = 0; y < 4; y++)
+ for (x = 0; x < 4; x++)
+ POS(x, y) = ((3 - x) * left[y] + (x + 1) * top[4] +
+ (3 - y) * top[x] + (y + 1) * left[4] + 4) >> 3;
+}
+
+static void FUNC(pred_planar_1)(uint8_t *_src, const uint8_t *_top,
+ const uint8_t *_left, ptrdiff_t stride)
+{
+ int x, y;
+ pixel *src = (pixel *)_src;
+ const pixel *top = (const pixel *)_top;
+ const pixel *left = (const pixel *)_left;
+ for (y = 0; y < 8; y++)
+ for (x = 0; x < 8; x++)
+ POS(x, y) = ((7 - x) * left[y] + (x + 1) * top[8] +
+ (7 - y) * top[x] + (y + 1) * left[8] + 8) >> 4;
+}
+
+static void FUNC(pred_planar_2)(uint8_t *_src, const uint8_t *_top,
+ const uint8_t *_left, ptrdiff_t stride)
+{
+ int x, y;
+ pixel *src = (pixel *)_src;
+ const pixel *top = (const pixel *)_top;
+ const pixel *left = (const pixel *)_left;
+ for (y = 0; y < 16; y++)
+ for (x = 0; x < 16; x++)
+ POS(x, y) = ((15 - x) * left[y] + (x + 1) * top[16] +
+ (15 - y) * top[x] + (y + 1) * left[16] + 16) >> 5;
+}
+
+static void FUNC(pred_planar_3)(uint8_t *_src, const uint8_t *_top,
+ const uint8_t *_left, ptrdiff_t stride)
+{
+ int x, y;
+ pixel *src = (pixel *)_src;
+ const pixel *top = (const pixel *)_top;
+ const pixel *left = (const pixel *)_left;
+ for (y = 0; y < 32; y++)
+ for (x = 0; x < 32; x++)
+ POS(x, y) = ((31 - x) * left[y] + (x + 1) * top[32] +
+ (31 - y) * top[x] + (y + 1) * left[32] + 32) >> 6;
+}
+
+static void FUNC(pred_dc)(uint8_t *_src, const uint8_t *_top,
+ const uint8_t *_left,
+ ptrdiff_t stride, int log2_size, int c_idx)
+{
+ int i, j, x, y;
+ int size = (1 << log2_size);
+ pixel *src = (pixel *)_src;
+ const pixel *top = (const pixel *)_top;
+ const pixel *left = (const pixel *)_left;
+ int dc = size;
+ pixel4 a;
+ for (i = 0; i < size; i++)
+ dc += left[i] + top[i];
+
+ dc >>= log2_size + 1;
+
+ a = PIXEL_SPLAT_X4(dc);
+
+ for (i = 0; i < size; i++)
+ for (j = 0; j < size / 4; j++)
+ AV_WN4PA(&POS(j * 4, i), a);
+
+ if (c_idx == 0 && size < 32) {
+ POS(0, 0) = (left[0] + 2 * dc + top[0] + 2) >> 2;
+ for (x = 1; x < size; x++)
+ POS(x, 0) = (top[x] + 3 * dc + 2) >> 2;
+ for (y = 1; y < size; y++)
+ POS(0, y) = (left[y] + 3 * dc + 2) >> 2;
+ }
+}
+
+static av_always_inline void FUNC(pred_angular)(uint8_t *_src,
+ const uint8_t *_top,
+ const uint8_t *_left,
+ ptrdiff_t stride, int c_idx,
+ int mode, int size)
+{
+ int x, y;
+ pixel *src = (pixel *)_src;
+ const pixel *top = (const pixel *)_top;
+ const pixel *left = (const pixel *)_left;
+
+ static const int intra_pred_angle[] = {
+ 32, 26, 21, 17, 13, 9, 5, 2, 0, -2, -5, -9, -13, -17, -21, -26, -32,
+ -26, -21, -17, -13, -9, -5, -2, 0, 2, 5, 9, 13, 17, 21, 26, 32
+ };
+ static const int inv_angle[] = {
+ -4096, -1638, -910, -630, -482, -390, -315, -256, -315, -390, -482,
+ -630, -910, -1638, -4096
+ };
+
+ int angle = intra_pred_angle[mode - 2];
+ pixel ref_array[3 * MAX_TB_SIZE + 1];
+ pixel *ref_tmp = ref_array + size;
+ const pixel *ref;
+ int last = (size * angle) >> 5;
+
+ if (mode >= 18) {
+ ref = top - 1;
+ if (angle < 0 && last < -1) {
+ for (x = 0; x <= size; x++)
+ ref_tmp[x] = top[x - 1];
+ for (x = last; x <= -1; x++)
+ ref_tmp[x] = left[-1 + ((x * inv_angle[mode - 11] + 128) >> 8)];
+ ref = ref_tmp;
+ }
+
+ for (y = 0; y < size; y++) {
+ int idx = ((y + 1) * angle) >> 5;
+ int fact = ((y + 1) * angle) & 31;
+ if (fact) {
+ for (x = 0; x < size; x++) {
+ POS(x, y) = ((32 - fact) * ref[x + idx + 1] +
+ fact * ref[x + idx + 2] + 16) >> 5;
+ }
+ } else {
+ for (x = 0; x < size; x++)
+ POS(x, y) = ref[x + idx + 1];
+ }
+ }
+ if (mode == 26 && c_idx == 0 && size < 32) {
+ for (y = 0; y < size; y++)
+ POS(0, y) = av_clip_pixel(top[0] + ((left[y] - left[-1]) >> 1));
+ }
+ } else {
+ ref = left - 1;
+ if (angle < 0 && last < -1) {
+ for (x = 0; x <= size; x++)
+ ref_tmp[x] = left[x - 1];
+ for (x = last; x <= -1; x++)
+ ref_tmp[x] = top[-1 + ((x * inv_angle[mode - 11] + 128) >> 8)];
+ ref = ref_tmp;
+ }
+
+ for (x = 0; x < size; x++) {
+ int idx = ((x + 1) * angle) >> 5;
+ int fact = ((x + 1) * angle) & 31;
+ if (fact) {
+ for (y = 0; y < size; y++) {
+ POS(x, y) = ((32 - fact) * ref[y + idx + 1] +
+ fact * ref[y + idx + 2] + 16) >> 5;
+ }
+ } else {
+ for (y = 0; y < size; y++)
+ POS(x, y) = ref[y + idx + 1];
+ }
+ }
+ if (mode == 10 && c_idx == 0 && size < 32) {
+ for (x = 0; x < size; x++)
+ POS(x, 0) = av_clip_pixel(left[0] + ((top[x] - top[-1]) >> 1));
+ }
+ }
+}
+
+static void FUNC(pred_angular_0)(uint8_t *src, const uint8_t *top,
+ const uint8_t *left,
+ ptrdiff_t stride, int c_idx, int mode)
+{
+ FUNC(pred_angular)(src, top, left, stride, c_idx, mode, 1 << 2);
+}
+
+static void FUNC(pred_angular_1)(uint8_t *src, const uint8_t *top,
+ const uint8_t *left,
+ ptrdiff_t stride, int c_idx, int mode)
+{
+ FUNC(pred_angular)(src, top, left, stride, c_idx, mode, 1 << 3);
+}
+
+static void FUNC(pred_angular_2)(uint8_t *src, const uint8_t *top,
+ const uint8_t *left,
+ ptrdiff_t stride, int c_idx, int mode)
+{
+ FUNC(pred_angular)(src, top, left, stride, c_idx, mode, 1 << 4);
+}
+
+static void FUNC(pred_angular_3)(uint8_t *src, const uint8_t *top,
+ const uint8_t *left,
+ ptrdiff_t stride, int c_idx, int mode)
+{
+ FUNC(pred_angular)(src, top, left, stride, c_idx, mode, 1 << 5);
+}
+
+#undef EXTEND_LEFT_CIP
+#undef EXTEND_RIGHT_CIP
+#undef EXTEND_UP_CIP
+#undef EXTEND_DOWN_CIP
+#undef IS_INTRA
+#undef MVF_PU
+#undef MVF
+#undef PU
+#undef EXTEND_LEFT
+#undef EXTEND_RIGHT
+#undef EXTEND_UP
+#undef EXTEND_DOWN
+#undef MIN_TB_ADDR_ZS
+#undef POS
diff --git a/libavcodec/hnm4video.c b/libavcodec/hnm4video.c
new file mode 100644
index 0000000..177972b
--- /dev/null
+++ b/libavcodec/hnm4video.c
@@ -0,0 +1,503 @@
+/*
+ * Cryo Interactive Entertainment HNM4 video decoder
+ *
+ * Copyright (c) 2012 David Kment
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <string.h>
+
+#include "libavutil/internal.h"
+#include "libavutil/intreadwrite.h"
+#include "libavutil/mem.h"
+#include "avcodec.h"
+#include "bytestream.h"
+#include "internal.h"
+
+#define HNM4_CHUNK_ID_PL 19536
+#define HNM4_CHUNK_ID_IZ 23113
+#define HNM4_CHUNK_ID_IU 21833
+#define HNM4_CHUNK_ID_SD 17491
+
+typedef struct Hnm4VideoContext {
+ uint8_t version;
+ uint16_t width;
+ uint16_t height;
+ uint8_t *current;
+ uint8_t *previous;
+ uint8_t *buffer1;
+ uint8_t *buffer2;
+ uint8_t *processed;
+ uint32_t palette[256];
+} Hnm4VideoContext;
+
+static int getbit(GetByteContext *gb, uint32_t *bitbuf, int *bits)
+{
+ int ret;
+
+ if (!*bits) {
+ *bitbuf = bytestream2_get_le32(gb);
+ *bits = 32;
+ }
+
+ ret = *bitbuf >> 31;
+ *bitbuf <<= 1;
+ (*bits)--;
+
+ return ret;
+}
+
+static void unpack_intraframe(AVCodecContext *avctx, uint8_t *src,
+ uint32_t size)
+{
+ Hnm4VideoContext *hnm = avctx->priv_data;
+ GetByteContext gb;
+ uint32_t bitbuf = 0, writeoffset = 0, count = 0;
+ uint16_t word;
+ int32_t offset;
+ int bits = 0;
+
+ bytestream2_init(&gb, src, size);
+
+ while (bytestream2_tell(&gb) < size) {
+ if (getbit(&gb, &bitbuf, &bits)) {
+ if (writeoffset >= hnm->width * hnm->height) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Attempting to write out of bounds\n");
+ break;
+ }
+ hnm->current[writeoffset++] = bytestream2_get_byte(&gb);
+ } else {
+ if (getbit(&gb, &bitbuf, &bits)) {
+ word = bytestream2_get_le16(&gb);
+ count = word & 0x07;
+ offset = (word >> 3) - 0x2000;
+ if (!count)
+ count = bytestream2_get_byte(&gb);
+ if (!count)
+ return;
+ } else {
+ count = getbit(&gb, &bitbuf, &bits) * 2;
+ count += getbit(&gb, &bitbuf, &bits);
+ offset = bytestream2_get_byte(&gb) - 0x0100;
+ }
+ count += 2;
+ offset += writeoffset;
+ if (offset < 0 || offset + count >= hnm->width * hnm->height) {
+ av_log(avctx, AV_LOG_ERROR, "Attempting to read out of bounds\n");
+ break;
+ } else if (writeoffset + count >= hnm->width * hnm->height) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Attempting to write out of bounds\n");
+ break;
+ }
+ while (count--) {
+ hnm->current[writeoffset++] = hnm->current[offset++];
+ }
+ }
+ }
+}
+
+static void postprocess_current_frame(AVCodecContext *avctx)
+{
+ Hnm4VideoContext *hnm = avctx->priv_data;
+ uint32_t x, y, src_x, src_y;
+
+ for (y = 0; y < hnm->height; y++) {
+ src_y = y - (y % 2);
+ src_x = src_y * hnm->width + (y % 2);
+ for (x = 0; x < hnm->width; x++) {
+ hnm->processed[(y * hnm->width) + x] = hnm->current[src_x];
+ src_x += 2;
+ }
+ }
+}
+
+static void copy_processed_frame(AVCodecContext *avctx, AVFrame *frame)
+{
+ Hnm4VideoContext *hnm = avctx->priv_data;
+ uint8_t *src = hnm->processed;
+ uint8_t *dst = frame->data[0];
+ int y;
+
+ for (y = 0; y < hnm->height; y++) {
+ memcpy(dst, src, hnm->width);
+ src += hnm->width;
+ dst += frame->linesize[0];
+ }
+}
+
+static void decode_interframe_v4(AVCodecContext *avctx, uint8_t *src, uint32_t size)
+{
+ Hnm4VideoContext *hnm = avctx->priv_data;
+ GetByteContext gb;
+ uint32_t writeoffset = 0;
+ int count, left, offset;
+ uint8_t tag, previous, backline, backward, swap;
+
+ bytestream2_init(&gb, src, size);
+
+ while (bytestream2_tell(&gb) < size) {
+ count = bytestream2_peek_byte(&gb) & 0x1F;
+ if (count == 0) {
+ tag = bytestream2_get_byte(&gb) & 0xE0;
+ tag = tag >> 5;
+
+ if (tag == 0) {
+ if (writeoffset + 2 > hnm->width * hnm->height) {
+ av_log(avctx, AV_LOG_ERROR, "writeoffset out of bounds\n");
+ break;
+ }
+ hnm->current[writeoffset++] = bytestream2_get_byte(&gb);
+ hnm->current[writeoffset++] = bytestream2_get_byte(&gb);
+ } else if (tag == 1) {
+ writeoffset += bytestream2_get_byte(&gb) * 2;
+ } else if (tag == 2) {
+ count = bytestream2_get_le16(&gb);
+ count *= 2;
+ writeoffset += count;
+ } else if (tag == 3) {
+ count = bytestream2_get_byte(&gb) * 2;
+ if (writeoffset + count > hnm->width * hnm->height) {
+ av_log(avctx, AV_LOG_ERROR, "writeoffset out of bounds\n");
+ break;
+ }
+ while (count > 0) {
+ hnm->current[writeoffset++] = bytestream2_peek_byte(&gb);
+ count--;
+ }
+ bytestream2_skip(&gb, 1);
+ } else {
+ break;
+ }
+ if (writeoffset > hnm->width * hnm->height) {
+ av_log(avctx, AV_LOG_ERROR, "writeoffset out of bounds\n");
+ break;
+ }
+ } else {
+ previous = bytestream2_peek_byte(&gb) & 0x20;
+ backline = bytestream2_peek_byte(&gb) & 0x40;
+ backward = bytestream2_peek_byte(&gb) & 0x80;
+ bytestream2_skip(&gb, 1);
+ swap = bytestream2_peek_byte(&gb) & 0x01;
+ offset = bytestream2_get_le16(&gb);
+ offset = (offset >> 1) & 0x7FFF;
+ offset = writeoffset + (offset * 2) - 0x8000;
+
+ left = count;
+
+ if (!backward && offset + 2*count > hnm->width * hnm->height) {
+ av_log(avctx, AV_LOG_ERROR, "Attempting to read out of bounds\n");
+ break;
+ } else if (backward && offset + 1 >= hnm->width * hnm->height) {
+ av_log(avctx, AV_LOG_ERROR, "Attempting to read out of bounds\n");
+ break;
+ } else if (writeoffset + 2*count > hnm->width * hnm->height) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Attempting to write out of bounds\n");
+ break;
+ }
+ if(backward) {
+ if (offset < (!!backline)*(2 * hnm->width - 1) + 2*(left-1)) {
+ av_log(avctx, AV_LOG_ERROR, "Attempting to read out of bounds\n");
+ break;
+ }
+ } else {
+ if (offset < (!!backline)*(2 * hnm->width - 1)) {
+ av_log(avctx, AV_LOG_ERROR, "Attempting to read out of bounds\n");
+ break;
+ }
+ }
+
+ if (previous) {
+ while (left > 0) {
+ if (backline) {
+ hnm->current[writeoffset++] = hnm->previous[offset - (2 * hnm->width) + 1];
+ hnm->current[writeoffset++] = hnm->previous[offset++];
+ offset++;
+ } else {
+ hnm->current[writeoffset++] = hnm->previous[offset++];
+ hnm->current[writeoffset++] = hnm->previous[offset++];
+ }
+ if (backward)
+ offset -= 4;
+ left--;
+ }
+ } else {
+ while (left > 0) {
+ if (backline) {
+ hnm->current[writeoffset++] = hnm->current[offset - (2 * hnm->width) + 1];
+ hnm->current[writeoffset++] = hnm->current[offset++];
+ offset++;
+ } else {
+ hnm->current[writeoffset++] = hnm->current[offset++];
+ hnm->current[writeoffset++] = hnm->current[offset++];
+ }
+ if (backward)
+ offset -= 4;
+ left--;
+ }
+ }
+
+ if (swap) {
+ left = count;
+ writeoffset -= count * 2;
+ while (left > 0) {
+ swap = hnm->current[writeoffset];
+ hnm->current[writeoffset] = hnm->current[writeoffset + 1];
+ hnm->current[writeoffset + 1] = swap;
+ left--;
+ writeoffset += 2;
+ }
+ }
+ }
+ }
+}
+
+static void decode_interframe_v4a(AVCodecContext *avctx, uint8_t *src,
+ uint32_t size)
+{
+ Hnm4VideoContext *hnm = avctx->priv_data;
+ GetByteContext gb;
+ uint32_t writeoffset = 0, offset;
+ uint8_t tag, count, previous, delta;
+
+ bytestream2_init(&gb, src, size);
+
+ while (bytestream2_tell(&gb) < size) {
+ count = bytestream2_peek_byte(&gb) & 0x3F;
+ if (count == 0) {
+ tag = bytestream2_get_byte(&gb) & 0xC0;
+ tag = tag >> 6;
+ if (tag == 0) {
+ writeoffset += bytestream2_get_byte(&gb);
+ } else if (tag == 1) {
+ if (writeoffset + hnm->width >= hnm->width * hnm->height) {
+ av_log(avctx, AV_LOG_ERROR, "writeoffset out of bounds\n");
+ break;
+ }
+ hnm->current[writeoffset] = bytestream2_get_byte(&gb);
+ hnm->current[writeoffset + hnm->width] = bytestream2_get_byte(&gb);
+ writeoffset++;
+ } else if (tag == 2) {
+ writeoffset += hnm->width;
+ } else if (tag == 3) {
+ break;
+ }
+ if (writeoffset > hnm->width * hnm->height) {
+ av_log(avctx, AV_LOG_ERROR, "writeoffset out of bounds\n");
+ break;
+ }
+ } else {
+ delta = bytestream2_peek_byte(&gb) & 0x80;
+ previous = bytestream2_peek_byte(&gb) & 0x40;
+ bytestream2_skip(&gb, 1);
+
+ offset = writeoffset;
+ offset += bytestream2_get_le16(&gb);
+
+ if (delta)
+ offset -= 0x10000;
+
+ if (offset + hnm->width + count >= hnm->width * hnm->height) {
+ av_log(avctx, AV_LOG_ERROR, "Attempting to read out of bounds\n");
+ break;
+ } else if (writeoffset + hnm->width + count >= hnm->width * hnm->height) {
+ av_log(avctx, AV_LOG_ERROR, "Attempting to write out of bounds\n");
+ break;
+ }
+
+ if (previous) {
+ while (count > 0) {
+ hnm->current[writeoffset] = hnm->previous[offset];
+ hnm->current[writeoffset + hnm->width] = hnm->previous[offset + hnm->width];
+ writeoffset++;
+ offset++;
+ count--;
+ }
+ } else {
+ while (count > 0) {
+ hnm->current[writeoffset] = hnm->current[offset];
+ hnm->current[writeoffset + hnm->width] = hnm->current[offset + hnm->width];
+ writeoffset++;
+ offset++;
+ count--;
+ }
+ }
+ }
+ }
+}
+
+static void hnm_update_palette(AVCodecContext *avctx, uint8_t *src,
+ uint32_t size)
+{
+ Hnm4VideoContext *hnm = avctx->priv_data;
+ GetByteContext gb;
+ uint8_t start, writeoffset;
+ uint16_t count;
+ int eight_bit_colors;
+
+ eight_bit_colors = src[7] & 0x80 && hnm->version == 0x4a;
+
+ // skip first 8 bytes
+ bytestream2_init(&gb, src + 8, size - 8);
+
+ while (bytestream2_tell(&gb) < size - 8) {
+ start = bytestream2_get_byte(&gb);
+ count = bytestream2_get_byte(&gb);
+ if (start == 255 && count == 255)
+ break;
+ if (count == 0)
+ count = 256;
+ writeoffset = start;
+ while (count > 0) {
+ hnm->palette[writeoffset] = bytestream2_get_be24(&gb);
+ if (!eight_bit_colors)
+ hnm->palette[writeoffset] <<= 2;
+ count--;
+ writeoffset++;
+ }
+ }
+}
+
+static void hnm_flip_buffers(Hnm4VideoContext *hnm)
+{
+ uint8_t *temp;
+
+ temp = hnm->current;
+ hnm->current = hnm->previous;
+ hnm->previous = temp;
+}
+
+static int hnm_decode_frame(AVCodecContext *avctx, void *data,
+ int *got_frame, AVPacket *avpkt)
+{
+ AVFrame *frame = data;
+ Hnm4VideoContext *hnm = avctx->priv_data;
+ int ret;
+ uint16_t chunk_id;
+
+ if (avpkt->size < 8) {
+ av_log(avctx, AV_LOG_ERROR, "packet too small\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ chunk_id = AV_RL16(avpkt->data + 4);
+
+ if (chunk_id == HNM4_CHUNK_ID_PL) {
+ hnm_update_palette(avctx, avpkt->data, avpkt->size);
+ } else if (chunk_id == HNM4_CHUNK_ID_IZ) {
+ if (avpkt->size < 12) {
+ av_log(avctx, AV_LOG_ERROR, "packet too small\n");
+ return AVERROR_INVALIDDATA;
+ }
+ if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
+ return ret;
+
+ unpack_intraframe(avctx, avpkt->data + 12, avpkt->size - 12);
+ memcpy(hnm->previous, hnm->current, hnm->width * hnm->height);
+ if (hnm->version == 0x4a)
+ memcpy(hnm->processed, hnm->current, hnm->width * hnm->height);
+ else
+ postprocess_current_frame(avctx);
+ copy_processed_frame(avctx, frame);
+ frame->pict_type = AV_PICTURE_TYPE_I;
+ frame->key_frame = 1;
+ memcpy(frame->data[1], hnm->palette, 256 * 4);
+ *got_frame = 1;
+ } else if (chunk_id == HNM4_CHUNK_ID_IU) {
+ if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
+ return ret;
+
+ if (hnm->version == 0x4a) {
+ decode_interframe_v4a(avctx, avpkt->data + 8, avpkt->size - 8);
+ memcpy(hnm->processed, hnm->current, hnm->width * hnm->height);
+ } else {
+ decode_interframe_v4(avctx, avpkt->data + 8, avpkt->size - 8);
+ postprocess_current_frame(avctx);
+ }
+ copy_processed_frame(avctx, frame);
+ frame->pict_type = AV_PICTURE_TYPE_P;
+ frame->key_frame = 0;
+ memcpy(frame->data[1], hnm->palette, 256 * 4);
+ *got_frame = 1;
+ hnm_flip_buffers(hnm);
+ } else {
+ av_log(avctx, AV_LOG_ERROR, "invalid chunk id: %d\n", chunk_id);
+ return AVERROR_INVALIDDATA;
+ }
+
+ return avpkt->size;
+}
+
+static av_cold int hnm_decode_init(AVCodecContext *avctx)
+{
+ Hnm4VideoContext *hnm = avctx->priv_data;
+
+ if (avctx->extradata_size < 1) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Extradata missing, decoder requires version number\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ hnm->version = avctx->extradata[0];
+ avctx->pix_fmt = AV_PIX_FMT_PAL8;
+ hnm->width = avctx->width;
+ hnm->height = avctx->height;
+ hnm->buffer1 = av_mallocz(avctx->width * avctx->height);
+ hnm->buffer2 = av_mallocz(avctx->width * avctx->height);
+ hnm->processed = av_mallocz(avctx->width * avctx->height);
+
+ if ( !hnm->buffer1 || !hnm->buffer2 || !hnm->processed
+ || avctx->width * avctx->height == 0
+ || avctx->height % 2) {
+ av_log(avctx, AV_LOG_ERROR, "av_mallocz() failed\n");
+ av_freep(&hnm->buffer1);
+ av_freep(&hnm->buffer2);
+ av_freep(&hnm->processed);
+ return AVERROR(ENOMEM);
+ }
+
+ hnm->current = hnm->buffer1;
+ hnm->previous = hnm->buffer2;
+
+ return 0;
+}
+
+static av_cold int hnm_decode_end(AVCodecContext *avctx)
+{
+ Hnm4VideoContext *hnm = avctx->priv_data;
+
+ av_freep(&hnm->buffer1);
+ av_freep(&hnm->buffer2);
+ av_freep(&hnm->processed);
+
+ return 0;
+}
+
+AVCodec ff_hnm4_video_decoder = {
+ .name = "hnm4video",
+ .long_name = NULL_IF_CONFIG_SMALL("HNM 4 video"),
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = AV_CODEC_ID_HNM4_VIDEO,
+ .priv_data_size = sizeof(Hnm4VideoContext),
+ .init = hnm_decode_init,
+ .close = hnm_decode_end,
+ .decode = hnm_decode_frame,
+ .capabilities = CODEC_CAP_DR1,
+};
diff --git a/libavcodec/huffman.c b/libavcodec/huffman.c
index 2b64b3e..8dd356d 100644
--- a/libavcodec/huffman.c
+++ b/libavcodec/huffman.c
@@ -24,6 +24,8 @@
* huffman tree builder and VLC generator
*/
+#include <stdint.h>
+
#include "avcodec.h"
#include "get_bits.h"
#include "huffman.h"
diff --git a/libavcodec/huffyuv.h b/libavcodec/huffyuv.h
index e34b562..e2cacc1 100644
--- a/libavcodec/huffyuv.h
+++ b/libavcodec/huffyuv.h
@@ -78,7 +78,6 @@
uint32_t bits[3][256];
uint32_t pix_bgr_map[1<<VLC_BITS];
VLC vlc[6]; //Y,U,V,YY,YU,YV
- AVFrame picture;
uint8_t *bitstream_buffer;
unsigned int bitstream_buffer_size;
DSPContext dsp;
diff --git a/libavcodec/huffyuvdec.c b/libavcodec/huffyuvdec.c
index 9b904d4..3cfda9b 100644
--- a/libavcodec/huffyuvdec.c
+++ b/libavcodec/huffyuvdec.c
@@ -256,7 +256,6 @@
ff_huffyuv_common_init(avctx);
memset(s->vlc, 0, 3 * sizeof(VLC));
- avcodec_get_frame_defaults(&s->picture);
s->interlaced = s->height > 288;
s->bgr32 = 1;
diff --git a/libavcodec/huffyuvenc.c b/libavcodec/huffyuvenc.c
index c56e281..3a55d54 100644
--- a/libavcodec/huffyuvenc.c
+++ b/libavcodec/huffyuvenc.c
@@ -156,7 +156,12 @@
}
s->version = 2;
- avctx->coded_frame = &s->picture;
+ avctx->coded_frame = av_frame_alloc();
+ if (!avctx->coded_frame)
+ return AVERROR(ENOMEM);
+
+ avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
+ avctx->coded_frame->key_frame = 1;
switch (avctx->pix_fmt) {
case AV_PIX_FMT_YUV420P:
@@ -446,16 +451,12 @@
const int fake_ystride = s->interlaced ? pict->linesize[0]*2 : pict->linesize[0];
const int fake_ustride = s->interlaced ? pict->linesize[1]*2 : pict->linesize[1];
const int fake_vstride = s->interlaced ? pict->linesize[2]*2 : pict->linesize[2];
- AVFrame * const p = &s->picture;
+ const AVFrame * const p = pict;
int i, j, size = 0, ret;
if ((ret = ff_alloc_packet2(avctx, pkt, width * height * 3 * 4 + FF_MIN_BUFFER_SIZE)) < 0)
return ret;
- *p = *pict;
- p->pict_type = AV_PICTURE_TYPE_I;
- p->key_frame = 1;
-
if (s->context) {
for (i = 0; i < 3; i++) {
ff_huff_gen_len_table(s->len[i], s->stats[i]);
@@ -681,6 +682,8 @@
av_freep(&avctx->extradata);
av_freep(&avctx->stats_out);
+ av_frame_free(&avctx->coded_frame);
+
return 0;
}
diff --git a/libavcodec/iff.c b/libavcodec/iff.c
index 6da153e..e71f5b0 100644
--- a/libavcodec/iff.c
+++ b/libavcodec/iff.c
@@ -25,6 +25,8 @@
* IFF ACBM/DEEP/ILBM/PBM bitmap decoder
*/
+#include <stdint.h>
+
#include "libavutil/imgutils.h"
#include "bytestream.h"
#include "avcodec.h"
@@ -184,7 +186,7 @@
*
* @param avctx the AVCodecContext where to extract extra context to
* @param avpkt the AVPacket to extract extra context from or NULL to use avctx
- * @return 0 in case of success, a negative error code otherwise
+ * @return >= 0 in case of success, a negative error code otherwise
*/
static int extract_header(AVCodecContext *const avctx,
const AVPacket *const avpkt) {
@@ -318,6 +320,16 @@
return 0;
}
+static av_cold int decode_end(AVCodecContext *avctx)
+{
+ IffContext *s = avctx->priv_data;
+ av_frame_free(&s->frame);
+ av_freep(&s->planebuf);
+ av_freep(&s->ham_buf);
+ av_freep(&s->ham_palbuf);
+ return 0;
+}
+
static av_cold int decode_init(AVCodecContext *avctx)
{
IffContext *s = avctx->priv_data;
@@ -360,8 +372,10 @@
s->bpp = avctx->bits_per_coded_sample;
s->frame = av_frame_alloc();
- if (!s->frame)
+ if (!s->frame) {
+ decode_end(avctx);
return AVERROR(ENOMEM);
+ }
if ((err = extract_header(avctx, NULL)) < 0)
return err;
@@ -858,16 +872,6 @@
return buf_size;
}
-static av_cold int decode_end(AVCodecContext *avctx)
-{
- IffContext *s = avctx->priv_data;
- av_frame_free(&s->frame);
- av_freep(&s->planebuf);
- av_freep(&s->ham_buf);
- av_freep(&s->ham_palbuf);
- return 0;
-}
-
#if CONFIG_IFF_ILBM_DECODER
AVCodec ff_iff_ilbm_decoder = {
.name = "iff",
diff --git a/libavcodec/indeo2.c b/libavcodec/indeo2.c
index d3bbc6d..aabe348 100644
--- a/libavcodec/indeo2.c
+++ b/libavcodec/indeo2.c
@@ -171,36 +171,36 @@
if (s->decode_delta) { /* intraframe */
if ((ret = ir2_decode_plane(s, avctx->width, avctx->height,
- s->picture->data[0], s->picture->linesize[0],
+ p->data[0], p->linesize[0],
ir2_luma_table)) < 0)
return ret;
/* swapped U and V */
if ((ret = ir2_decode_plane(s, avctx->width >> 2, avctx->height >> 2,
- s->picture->data[2], s->picture->linesize[2],
+ p->data[2], p->linesize[2],
ir2_luma_table)) < 0)
return ret;
if ((ret = ir2_decode_plane(s, avctx->width >> 2, avctx->height >> 2,
- s->picture->data[1], s->picture->linesize[1],
+ p->data[1], p->linesize[1],
ir2_luma_table)) < 0)
return ret;
} else { /* interframe */
if ((ret = ir2_decode_plane_inter(s, avctx->width, avctx->height,
- s->picture->data[0], s->picture->linesize[0],
+ p->data[0], p->linesize[0],
ir2_luma_table)) < 0)
return ret;
/* swapped U and V */
if ((ret = ir2_decode_plane_inter(s, avctx->width >> 2, avctx->height >> 2,
- s->picture->data[2], s->picture->linesize[2],
+ p->data[2], p->linesize[2],
ir2_luma_table)) < 0)
return ret;
if ((ret = ir2_decode_plane_inter(s, avctx->width >> 2, avctx->height >> 2,
- s->picture->data[1], s->picture->linesize[1],
+ p->data[1], p->linesize[1],
ir2_luma_table)) < 0)
return ret;
}
- if ((ret = av_frame_ref(picture, s->picture)) < 0)
+ if ((ret = av_frame_ref(picture, p)) < 0)
return ret;
*got_frame = 1;
diff --git a/libavcodec/indeo3.c b/libavcodec/indeo3.c
index b882763..ddb4ad0 100644
--- a/libavcodec/indeo3.c
+++ b/libavcodec/indeo3.c
@@ -956,7 +956,7 @@
free_frame_buffers(ctx);
if ((res = allocate_frame_buffers(ctx, avctx, width, height)) < 0)
return res;
- avcodec_set_dimensions(avctx, width, height);
+ ff_set_dimensions(avctx, width, height);
}
y_offset = bytestream2_get_le32(&gb);
diff --git a/libavcodec/indeo4.c b/libavcodec/indeo4.c
index df878c5..0774f82 100644
--- a/libavcodec/indeo4.c
+++ b/libavcodec/indeo4.c
@@ -284,6 +284,7 @@
{
int plane, band_num, indx, transform_id, scan_indx;
int i;
+ int quant_mat;
plane = get_bits(&ctx->gb, 2);
band_num = get_bits(&ctx->gb, 4);
@@ -382,18 +383,17 @@
band->scan = scan_index_to_tab[scan_indx];
band->scan_size = band->blk_size;
- band->quant_mat = get_bits(&ctx->gb, 5);
- if (band->quant_mat >= FF_ARRAY_ELEMS(quant_index_to_tab)) {
-
- if (band->quant_mat == 31)
- av_log(avctx, AV_LOG_ERROR,
- "Custom quant matrix encountered!\n");
- else
- avpriv_request_sample(avctx, "Quantization matrix %d",
- band->quant_mat);
- band->quant_mat = -1;
+ quant_mat = get_bits(&ctx->gb, 5);
+ if (quant_mat == 31) {
+ av_log(avctx, AV_LOG_ERROR, "Custom quant matrix encountered!\n");
return AVERROR_INVALIDDATA;
}
+ if (quant_mat >= FF_ARRAY_ELEMS(quant_index_to_tab)) {
+ avpriv_request_sample(avctx, "Quantization matrix %d",
+ quant_mat);
+ return AVERROR_INVALIDDATA;
+ }
+ band->quant_mat = quant_mat;
} else {
if (old_blk_size != band->blk_size) {
av_log(avctx, AV_LOG_ERROR,
@@ -401,10 +401,6 @@
"inherited\n");
return AVERROR_INVALIDDATA;
}
- if (band->quant_mat < 0) {
- av_log(avctx, AV_LOG_ERROR, "Invalid quant_mat inherited\n");
- return AVERROR_INVALIDDATA;
- }
}
if (quant_index_to_tab[band->quant_mat] > 4 && band->blk_size == 4) {
av_log(avctx, AV_LOG_ERROR, "Invalid quant matrix for 4x4 block encountered!\n");
diff --git a/libavcodec/intelh263dec.c b/libavcodec/intelh263dec.c
index e5462e7..5da4202 100644
--- a/libavcodec/intelh263dec.c
+++ b/libavcodec/intelh263dec.c
@@ -111,9 +111,8 @@
}
/* PEI */
- while (get_bits1(&s->gb) != 0) {
- skip_bits(&s->gb, 8);
- }
+ if (skip_1stop_8data_bits(&s->gb) < 0)
+ return AVERROR_INVALIDDATA;
s->f_code = 1;
s->y_dc_scale_table=
diff --git a/libavcodec/internal.h b/libavcodec/internal.h
index 96976e1..35bfcd4 100644
--- a/libavcodec/internal.h
+++ b/libavcodec/internal.h
@@ -91,10 +91,18 @@
*/
int last_audio_frame;
- AVFrame to_free;
+ AVFrame *to_free;
FramePool *pool;
+ void *thread_ctx;
+
+ /**
+ * Current packet as passed into the decoder, to avoid having to pass the
+ * packet into every function.
+ */
+ AVPacket *pkt;
+
/**
* temporary buffer used for encoders to store their bitstream
*/
@@ -118,11 +126,10 @@
* Return the hardware accelerated codec for codec codec_id and
* pixel format pix_fmt.
*
- * @param codec_id the codec to match
- * @param pix_fmt the pixel format to match
+ * @param avctx The codec context containing the codec_id and pixel format.
* @return the hardware accelerated codec, or NULL if none was found.
*/
-AVHWAccel *ff_find_hwaccel(enum AVCodecID codec_id, enum AVPixelFormat pix_fmt);
+AVHWAccel *ff_find_hwaccel(AVCodecContext *avctx);
/**
* Return the index into tab at which {a,b} match elements {[0],[1]} of tab.
@@ -225,4 +232,10 @@
const uint8_t *end,
uint32_t *state);
+/**
+ * Check that the provided frame dimensions are valid and set them on the codec
+ * context.
+ */
+int ff_set_dimensions(AVCodecContext *s, int width, int height);
+
#endif /* AVCODEC_INTERNAL_H */
diff --git a/libavcodec/ituh263dec.c b/libavcodec/ituh263dec.c
index 241d558..8a17c6f 100644
--- a/libavcodec/ituh263dec.c
+++ b/libavcodec/ituh263dec.c
@@ -199,30 +199,6 @@
}
/**
- * 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
- */
-const uint8_t *ff_h263_find_resync_marker(MpegEncContext *s, const uint8_t *av_restrict p, const uint8_t *av_restrict end)
-{
- av_assert2(p < end);
-
- end-=2;
- p++;
- if(s->resync_marker){
- int prefix_len = ff_mpeg4_get_video_packet_prefix_length(s);
- for(;p<end; p+=2){
- if(!*p){
- if (!p[-1] && ((p[1] >> (23-prefix_len)) == 1)) return p - 1;
- else if (!p[ 1] && ((p[2] >> (23-prefix_len)) == 1)) return p;
- }
- }
- }
- return end+2;
-}
-
-/**
* Decode the group of blocks / video packet header.
* @return bit position of the resync_marker, or <0 if none was found
*/
@@ -237,7 +213,7 @@
if(show_bits(&s->gb, 16)==0){
pos= get_bits_count(&s->gb);
if(CONFIG_MPEG4_DECODER && s->codec_id==AV_CODEC_ID_MPEG4)
- ret= ff_mpeg4_decode_video_packet_header(s);
+ ret= ff_mpeg4_decode_video_packet_header(s->avctx->priv_data);
else
ret= h263_decode_gob_header(s);
if(ret>=0)
@@ -254,7 +230,7 @@
pos= get_bits_count(&s->gb);
if(CONFIG_MPEG4_DECODER && s->codec_id==AV_CODEC_ID_MPEG4)
- ret= ff_mpeg4_decode_video_packet_header(s);
+ ret= ff_mpeg4_decode_video_packet_header(s->avctx->priv_data);
else
ret= h263_decode_gob_header(s);
if(ret>=0)
@@ -894,7 +870,6 @@
i = get_bits(&s->gb, 8); /* picture timestamp */
if( (s->picture_number&~0xFF)+i < s->picture_number)
i+= 256;
- s->current_picture_ptr->f.pts =
s->picture_number= (s->picture_number&~0xFF) + i;
/* PTYPE starts here */
@@ -1113,9 +1088,8 @@
}
/* PEI */
- while (get_bits1(&s->gb) != 0) {
- skip_bits(&s->gb, 8);
- }
+ if (skip_1stop_8data_bits(&s->gb) < 0)
+ return AVERROR_INVALIDDATA;
if(s->h263_slice_structured){
if (get_bits1(&s->gb) != 1) {
diff --git a/libavcodec/ivi_common.c b/libavcodec/ivi_common.c
index 4179852..9b5f5f8 100644
--- a/libavcodec/ivi_common.c
+++ b/libavcodec/ivi_common.c
@@ -1042,7 +1042,12 @@
*/
if (avctx->codec_id == AV_CODEC_ID_INDEO4 &&
ctx->frame_type == 0/*FRAMETYPE_INTRA*/) {
- while (get_bits(&ctx->gb, 8)); // skip version string
+ // skip version string
+ while (get_bits(&ctx->gb, 8)) {
+ if (get_bits_left(&ctx->gb) < 8)
+ return AVERROR_INVALIDDATA;
+ }
+
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");
@@ -1051,7 +1056,10 @@
if (!ctx->is_nonnull_frame(ctx))
return buf_size;
- avcodec_set_dimensions(avctx, ctx->planes[0].width, ctx->planes[0].height);
+ result = ff_set_dimensions(avctx, ctx->planes[0].width, ctx->planes[0].height);
+ if (result < 0)
+ return result;
+
if ((result = ff_get_buffer(avctx, frame, 0)) < 0)
return result;
diff --git a/libavcodec/jpeg2000dec.c b/libavcodec/jpeg2000dec.c
index 80bc335..d3e49a1 100644
--- a/libavcodec/jpeg2000dec.c
+++ b/libavcodec/jpeg2000dec.c
@@ -243,6 +243,11 @@
s->tile_offset_y = bytestream2_get_be32u(&s->g); // YT0Siz
ncomponents = bytestream2_get_be16u(&s->g); // CSiz
+ if (s->image_offset_x || s->image_offset_y) {
+ avpriv_request_sample(s->avctx, "Support for image offsets");
+ return AVERROR_PATCHWELCOME;
+ }
+
if (ncomponents <= 0) {
av_log(s->avctx, AV_LOG_ERROR, "Invalid number of components: %d\n",
s->ncomponents);
@@ -884,6 +889,10 @@
prcx = ff_jpeg2000_ceildivpow2(x, reducedresno) >> rlevel->log2_prec_width;
prcy = ff_jpeg2000_ceildivpow2(y, reducedresno) >> rlevel->log2_prec_height;
precno = prcx + rlevel->num_precincts_x * prcy;
+
+ if (prcx >= rlevel->num_precincts_x || prcy >= rlevel->num_precincts_y)
+ return AVERROR_PATCHWELCOME;
+
for (layno = 0; layno < tile->codsty[0].nlayers; layno++) {
if ((ret = jpeg2000_decode_packet(s, codsty, rlevel,
precno, layno,
diff --git a/libavcodec/jpegls.h b/libavcodec/jpegls.h
index 2dc3832..10ae054 100644
--- a/libavcodec/jpegls.h
+++ b/libavcodec/jpegls.h
@@ -33,7 +33,6 @@
typedef struct JpeglsContext {
AVCodecContext *avctx;
- AVFrame picture;
} JpeglsContext;
typedef struct JLSState {
diff --git a/libavcodec/jpeglsdec.c b/libavcodec/jpeglsdec.c
index 0e344f5..190b9b6 100644
--- a/libavcodec/jpeglsdec.c
+++ b/libavcodec/jpeglsdec.c
@@ -148,6 +148,8 @@
ret = ret >> 1;
}
+ if(FFABS(ret) > 0xFFFF)
+ return -0x10000;
/* update state */
state->A[Q] += FFABS(ret) - RItype;
ret *= state->twonear;
@@ -279,9 +281,9 @@
JLSState *state;
int off = 0, stride = 1, width, shift, ret = 0;
- zero = av_mallocz(s->picture.linesize[0]);
+ zero = av_mallocz(s->picture_ptr->linesize[0]);
last = zero;
- cur = s->picture.data[0];
+ cur = s->picture_ptr->data[0];
state = av_mallocz(sizeof(JLSState));
/* initialize JPEG-LS state from JPEG parameters */
@@ -328,7 +330,7 @@
t = *((uint16_t *)last);
}
last = cur;
- cur += s->picture.linesize[0];
+ cur += s->picture_ptr->linesize[0];
if (s->restart_interval && !--s->restart_count) {
align_get_bits(&s->gb);
@@ -339,7 +341,7 @@
int j;
int Rc[3] = { 0, 0, 0 };
stride = (s->nb_components > 1) ? 3 : 1;
- memset(cur, 0, s->picture.linesize[0]);
+ memset(cur, 0, s->picture_ptr->linesize[0]);
width = s->width * stride;
for (i = 0; i < s->height; i++) {
for (j = 0; j < stride; j++) {
@@ -353,7 +355,7 @@
}
}
last = cur;
- cur += s->picture.linesize[0];
+ cur += s->picture_ptr->linesize[0];
}
} else if (ilv == 2) { /* sample interleaving */
avpriv_report_missing_feature(s->avctx, "Sample interleaved images");
@@ -367,7 +369,7 @@
w = s->width * s->nb_components;
if (s->bits <= 8) {
- uint8_t *src = s->picture.data[0];
+ uint8_t *src = s->picture_ptr->data[0];
for (i = 0; i < s->height; i++) {
switch(s->xfrm) {
@@ -402,7 +404,7 @@
}
break;
}
- src += s->picture.linesize[0];
+ src += s->picture_ptr->linesize[0];
}
}else
avpriv_report_missing_feature(s->avctx, "16bit xfrm");
@@ -414,20 +416,20 @@
w = s->width * s->nb_components;
if (s->bits <= 8) {
- uint8_t *src = s->picture.data[0];
+ uint8_t *src = s->picture_ptr->data[0];
for (i = 0; i < s->height; i++) {
for (x = off; x < w; x += stride)
src[x] <<= shift;
- src += s->picture.linesize[0];
+ src += s->picture_ptr->linesize[0];
}
} else {
- uint16_t *src = (uint16_t *)s->picture.data[0];
+ uint16_t *src = (uint16_t *)s->picture_ptr->data[0];
for (i = 0; i < s->height; i++) {
for (x = 0; x < w; x++)
src[x] <<= shift;
- src += s->picture.linesize[0] / 2;
+ src += s->picture_ptr->linesize[0] / 2;
}
}
}
diff --git a/libavcodec/jpeglsenc.c b/libavcodec/jpeglsenc.c
index 308d6d3..030178f 100644
--- a/libavcodec/jpeglsenc.c
+++ b/libavcodec/jpeglsenc.c
@@ -249,8 +249,7 @@
static int encode_picture_ls(AVCodecContext *avctx, AVPacket *pkt,
const AVFrame *pict, int *got_packet)
{
- JpeglsContext *const s = avctx->priv_data;
- AVFrame *const p = &s->picture;
+ const AVFrame *const p = pict;
const int near = avctx->prediction_method;
PutBitContext pb, pb2;
GetBitContext gb;
@@ -259,10 +258,6 @@
int i, size, ret;
int comps;
- *p = *pict;
- p->pict_type = AV_PICTURE_TYPE_I;
- p->key_frame = 1;
-
if (avctx->pix_fmt == AV_PIX_FMT_GRAY8 ||
avctx->pix_fmt == AV_PIX_FMT_GRAY16)
comps = 1;
@@ -349,7 +344,7 @@
Rc[j] = last[j];
}
last = cur;
- cur += s->picture.linesize[0];
+ cur += p->linesize[0];
}
} else if (avctx->pix_fmt == AV_PIX_FMT_BGR24) {
int j, width;
@@ -363,7 +358,7 @@
Rc[j] = last[j];
}
last = cur;
- cur += s->picture.linesize[0];
+ cur += p->linesize[0];
}
}
@@ -403,12 +398,20 @@
return 0;
}
+static av_cold int encode_close(AVCodecContext *avctx)
+{
+ av_frame_free(&avctx->coded_frame);
+ return 0;
+}
+
static av_cold int encode_init_ls(AVCodecContext *ctx)
{
- JpeglsContext *c = (JpeglsContext *)ctx->priv_data;
+ ctx->coded_frame = av_frame_alloc();
+ if (!ctx->coded_frame)
+ return AVERROR(ENOMEM);
- c->avctx = ctx;
- ctx->coded_frame = &c->picture;
+ ctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
+ ctx->coded_frame->key_frame = 1;
if (ctx->pix_fmt != AV_PIX_FMT_GRAY8 &&
ctx->pix_fmt != AV_PIX_FMT_GRAY16 &&
@@ -426,8 +429,8 @@
.long_name = NULL_IF_CONFIG_SMALL("JPEG-LS"),
.type = AVMEDIA_TYPE_VIDEO,
.id = AV_CODEC_ID_JPEGLS,
- .priv_data_size = sizeof(JpeglsContext),
.init = encode_init_ls,
+ .close = encode_close,
.encode2 = encode_picture_ls,
.pix_fmts = (const enum AVPixelFormat[]) {
AV_PIX_FMT_BGR24, AV_PIX_FMT_RGB24,
diff --git a/libavcodec/jvdec.c b/libavcodec/jvdec.c
index 740884a..cad0532 100644
--- a/libavcodec/jvdec.c
+++ b/libavcodec/jvdec.c
@@ -41,11 +41,13 @@
static av_cold int decode_init(AVCodecContext *avctx)
{
JvContext *s = avctx->priv_data;
- avctx->pix_fmt = AV_PIX_FMT_PAL8;
- ff_dsputil_init(&s->dsp, avctx);
+
s->frame = av_frame_alloc();
if (!s->frame)
return AVERROR(ENOMEM);
+
+ avctx->pix_fmt = AV_PIX_FMT_PAL8;
+ ff_dsputil_init(&s->dsp, avctx);
return 0;
}
diff --git a/libavcodec/kgv1dec.c b/libavcodec/kgv1dec.c
index f793137..5528c6f 100644
--- a/libavcodec/kgv1dec.c
+++ b/libavcodec/kgv1dec.c
@@ -38,7 +38,7 @@
{
KgvContext * const c = avctx->priv_data;
- av_frame_unref(c->prev);
+ av_frame_free(&c->prev);
}
static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
@@ -60,12 +60,10 @@
h = (buf[1] + 1) * 8;
buf += 2;
- if ((res = av_image_check_size(w, h, 0, avctx)) < 0)
- return res;
-
if (w != avctx->width || h != avctx->height) {
av_frame_unref(c->prev);
- avcodec_set_dimensions(avctx, w, h);
+ if ((res = ff_set_dimensions(avctx, w, h)) < 0)
+ return res;
}
maxcnt = w * h;
@@ -157,13 +155,13 @@
{
KgvContext * const c = avctx->priv_data;
- avctx->pix_fmt = AV_PIX_FMT_RGB555;
- avctx->flags |= CODEC_FLAG_EMU_EDGE;
-
c->prev = av_frame_alloc();
if (!c->prev)
return AVERROR(ENOMEM);
+ avctx->pix_fmt = AV_PIX_FMT_RGB555;
+ avctx->flags |= CODEC_FLAG_EMU_EDGE;
+
return 0;
}
diff --git a/libavcodec/lclenc.c b/libavcodec/lclenc.c
index 1dac307..0afe553 100644
--- a/libavcodec/lclenc.c
+++ b/libavcodec/lclenc.c
@@ -135,6 +135,13 @@
if (!avctx->extradata)
return AVERROR(ENOMEM);
+ avctx->coded_frame = av_frame_alloc();
+ if (!avctx->coded_frame)
+ return AVERROR(ENOMEM);
+
+ avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
+ avctx->coded_frame->key_frame = 1;
+
c->compression = avctx->compression_level == FF_COMPRESSION_DEFAULT ?
COMP_ZLIB_NORMAL :
av_clip(avctx->compression_level, 0, 9);
@@ -176,6 +183,8 @@
av_freep(&avctx->extradata);
deflateEnd(&c->zstream);
+ av_frame_free(&avctx->coded_frame);
+
return 0;
}
diff --git a/libavcodec/libfdk-aacdec.c b/libavcodec/libfdk-aacdec.c
index bc3802c..c833a98 100644
--- a/libavcodec/libfdk-aacdec.c
+++ b/libavcodec/libfdk-aacdec.c
@@ -229,10 +229,8 @@
if (s->initialized) {
frame->nb_samples = avctx->frame_size;
- if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
- av_log(avctx, AV_LOG_ERROR, "ff_get_buffer() failed\n");
+ if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
return ret;
- }
buf = frame->extended_data[0];
buf_size = avctx->channels * frame->nb_samples *
av_get_bytes_per_sample(avctx->sample_fmt);
@@ -264,10 +262,8 @@
if (tmpptr) {
frame->nb_samples = avctx->frame_size;
- if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
- av_log(avctx, AV_LOG_ERROR, "ff_get_buffer() failed\n");
+ if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
goto end;
- }
memcpy(frame->extended_data[0], tmpptr,
avctx->channels * avctx->frame_size *
av_get_bytes_per_sample(avctx->sample_fmt));
diff --git a/libavcodec/libmp3lame.c b/libavcodec/libmp3lame.c
index 2204f55..e6cb64b 100644
--- a/libavcodec/libmp3lame.c
+++ b/libavcodec/libmp3lame.c
@@ -49,6 +49,7 @@
int buffer_size;
int reservoir;
int joint_stereo;
+ int abr;
float *samples_flt[2];
AudioFrameQueue afq;
AVFloatDSPContext fdsp;
@@ -58,18 +59,14 @@
static int realloc_buffer(LAMEContext *s)
{
if (!s->buffer || s->buffer_size - s->buffer_index < BUFFER_SIZE) {
- uint8_t *tmp;
- int new_size = s->buffer_index + 2 * BUFFER_SIZE;
+ int new_size = s->buffer_index + 2 * BUFFER_SIZE, err;
av_dlog(s->avctx, "resizing output buffer: %d -> %d\n", s->buffer_size,
new_size);
- tmp = av_realloc(s->buffer, new_size);
- if (!tmp) {
- av_freep(&s->buffer);
+ if ((err = av_reallocp(&s->buffer, new_size)) < 0) {
s->buffer_size = s->buffer_index = 0;
- return AVERROR(ENOMEM);
+ return err;
}
- s->buffer = tmp;
s->buffer_size = new_size;
}
return 0;
@@ -115,12 +112,17 @@
lame_set_quality(s->gfp, avctx->compression_level);
/* rate control */
- if (avctx->flags & CODEC_FLAG_QSCALE) {
+ if (avctx->flags & CODEC_FLAG_QSCALE) { // VBR
lame_set_VBR(s->gfp, vbr_default);
lame_set_VBR_quality(s->gfp, avctx->global_quality / (float)FF_QP2LAMBDA);
} else {
- if (avctx->bit_rate)
- lame_set_brate(s->gfp, avctx->bit_rate / 1000);
+ if (avctx->bit_rate) {
+ if (s->abr) { // ABR
+ lame_set_VBR(s->gfp, vbr_abr);
+ lame_set_VBR_mean_bitrate_kbps(s->gfp, avctx->bit_rate / 1000);
+ } else // CBR
+ lame_set_brate(s->gfp, avctx->bit_rate / 1000);
+ }
}
/* do not get a Xing VBR header frame from LAME */
@@ -263,8 +265,9 @@
#define OFFSET(x) offsetof(LAMEContext, 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, { .i64 = 1 }, 0, 1, AE },
- { "joint_stereo", "Use joint stereo.", OFFSET(joint_stereo), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 1, AE },
+ { "reservoir", "use bit reservoir", OFFSET(reservoir), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 1, AE },
+ { "joint_stereo", "use joint stereo", OFFSET(joint_stereo), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 1, AE },
+ { "abr", "use ABR", OFFSET(abr), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, AE },
{ NULL },
};
diff --git a/libavcodec/libopenjpegdec.c b/libavcodec/libopenjpegdec.c
index 734b54f..0543e3a 100644
--- a/libavcodec/libopenjpegdec.c
+++ b/libavcodec/libopenjpegdec.c
@@ -32,6 +32,7 @@
#include "libavutil/pixfmt.h"
#include "libavutil/opt.h"
#include "avcodec.h"
+#include "internal.h"
#include "thread.h"
#if HAVE_OPENJPEG_1_5_OPENJPEG_H
@@ -245,7 +246,7 @@
opj_dinfo_t *dec;
opj_cio_t *stream;
opj_image_t *image;
- int width, height, ret = -1;
+ int width, height, ret;
int pixel_size = 0;
int ispacked = 0;
int i;
@@ -267,7 +268,7 @@
if (!dec) {
av_log(avctx, AV_LOG_ERROR, "Error initializing decoder.\n");
- return -1;
+ return AVERROR_UNKNOWN;
}
opj_set_event_mgr((opj_common_ptr)dec, NULL, NULL);
ctx->dec_params.cp_limit_decoding = LIMIT_TO_MAIN_HEADER;
@@ -280,7 +281,7 @@
av_log(avctx, AV_LOG_ERROR,
"Codestream could not be opened for reading.\n");
opj_destroy_decompress(dec);
- return -1;
+ return AVERROR_UNKNOWN;
}
// Decode the header only.
@@ -290,19 +291,15 @@
if (!image) {
av_log(avctx, AV_LOG_ERROR, "Error decoding codestream.\n");
opj_destroy_decompress(dec);
- return -1;
+ return AVERROR_UNKNOWN;
}
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);
+ ret = ff_set_dimensions(avctx, width, height);
+ if (ret < 0)
goto done;
- }
-
- avcodec_set_dimensions(avctx, width, height);
if (avctx->pix_fmt != AV_PIX_FMT_NONE)
if (!libopenjpeg_matches_pix_fmt(image, avctx->pix_fmt))
@@ -319,7 +316,7 @@
if (image->comps[i].prec > avctx->bits_per_raw_sample)
avctx->bits_per_raw_sample = image->comps[i].prec;
- if (ff_thread_get_buffer(avctx, &frame, 0) < 0)
+ if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
goto done;
ctx->dec_params.cp_limit_decoding = NO_LIMITATION;
@@ -330,6 +327,7 @@
if (!stream) {
av_log(avctx, AV_LOG_ERROR,
"Codestream could not be opened for reading.\n");
+ ret = AVERROR_UNKNOWN;
goto done;
}
@@ -340,6 +338,7 @@
if (!image) {
av_log(avctx, AV_LOG_ERROR, "Error decoding codestream.\n");
+ ret = AVERROR_UNKNOWN;
goto done;
}
@@ -376,6 +375,7 @@
break;
default:
av_log(avctx, AV_LOG_ERROR, "unsupported pixel size %d\n", pixel_size);
+ ret = AVERROR_PATCHWELCOME;
goto done;
}
diff --git a/libavcodec/libopenjpegenc.c b/libavcodec/libopenjpegenc.c
index c7769f7..14579b6 100644
--- a/libavcodec/libopenjpegenc.c
+++ b/libavcodec/libopenjpegenc.c
@@ -242,7 +242,7 @@
goto fail;
}
- avctx->coded_frame = avcodec_alloc_frame();
+ avctx->coded_frame = av_frame_alloc();
if (!avctx->coded_frame) {
av_log(avctx, AV_LOG_ERROR, "Error allocating coded frame\n");
goto fail;
diff --git a/libavcodec/libopusenc.c b/libavcodec/libopusenc.c
index 97d3bba..8ceb877 100644
--- a/libavcodec/libopusenc.c
+++ b/libavcodec/libopusenc.c
@@ -400,7 +400,7 @@
{ "voip", "Favor improved speech intelligibility", 0, AV_OPT_TYPE_CONST, { .i64 = OPUS_APPLICATION_VOIP }, 0, 0, FLAGS, "application" },
{ "audio", "Favor faithfulness to the input", 0, AV_OPT_TYPE_CONST, { .i64 = OPUS_APPLICATION_AUDIO }, 0, 0, FLAGS, "application" },
{ "lowdelay", "Restrict to only the lowest delay modes", 0, AV_OPT_TYPE_CONST, { .i64 = OPUS_APPLICATION_RESTRICTED_LOWDELAY }, 0, 0, FLAGS, "application" },
- { "frame_duration", "Duration of a frame in milliseconds", OFFSET(frame_duration), AV_OPT_TYPE_FLOAT, { .dbl = 10.0 }, 2.5, 60.0, FLAGS },
+ { "frame_duration", "Duration of a frame in milliseconds", OFFSET(frame_duration), AV_OPT_TYPE_FLOAT, { .dbl = 20.0 }, 2.5, 60.0, FLAGS },
{ "packet_loss", "Expected packet loss percentage", OFFSET(packet_loss), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 100, FLAGS },
{ "vbr", "Variable bit rate mode", OFFSET(vbr), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 2, FLAGS, "vbr" },
{ "off", "Use constant bit rate", 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, 0, 0, FLAGS, "vbr" },
diff --git a/libavcodec/libschroedingerenc.c b/libavcodec/libschroedingerenc.c
index 43530e8..294fb06 100644
--- a/libavcodec/libschroedingerenc.c
+++ b/libavcodec/libschroedingerenc.c
@@ -47,9 +47,6 @@
/** Schroedinger frame format */
SchroFrameFormat frame_format;
- /** frame being encoded */
- AVFrame picture;
-
/** frame size */
int frame_size;
@@ -162,7 +159,9 @@
avctx->width,
avctx->height);
- avctx->coded_frame = &p_schro_params->picture;
+ avctx->coded_frame = av_frame_alloc();
+ if (!avctx->coded_frame)
+ return AVERROR(ENOMEM);
if (!avctx->gop_size) {
schro_encoder_setting_set_double(p_schro_params->encoder,
@@ -294,21 +293,27 @@
/* Now check to see if we have any output from the encoder. */
while (go) {
+ int err;
SchroStateEnum state;
state = schro_encoder_wait(encoder);
switch (state) {
case SCHRO_STATE_HAVE_BUFFER:
case SCHRO_STATE_END_OF_STREAM:
enc_buf = schro_encoder_pull(encoder, &presentation_frame);
- av_assert0(enc_buf->length > 0);
+ if (enc_buf->length <= 0)
+ return AVERROR_BUG;
parse_code = enc_buf->data[4];
/* All non-frame data is prepended to actual frame data to
* be able to set the pts correctly. So we don't write data
* to the frame output queue until we actually have a frame
*/
- p_schro_params->enc_buf = av_realloc(p_schro_params->enc_buf,
- p_schro_params->enc_buf_size + enc_buf->length);
+ if ((err = av_reallocp(&p_schro_params->enc_buf,
+ p_schro_params->enc_buf_size +
+ enc_buf->length)) < 0) {
+ p_schro_params->enc_buf_size = 0;
+ return err;
+ }
memcpy(p_schro_params->enc_buf + p_schro_params->enc_buf_size,
enc_buf->data, enc_buf->length);
@@ -427,6 +432,8 @@
/* Free the video format structure. */
av_freep(&p_schro_params->format);
+ av_frame_free(&avctx->coded_frame);
+
return 0;
}
diff --git a/libavcodec/libshine.c b/libavcodec/libshine.c
index 2418188..48333bb 100644
--- a/libavcodec/libshine.c
+++ b/libavcodec/libshine.c
@@ -134,7 +134,7 @@
.name = "libshine",
.long_name = NULL_IF_CONFIG_SMALL("libshine MP3 (MPEG audio layer 3)"),
.type = AVMEDIA_TYPE_AUDIO,
- .id = CODEC_ID_MP3,
+ .id = AV_CODEC_ID_MP3,
.priv_data_size = sizeof(SHINEContext),
.init = libshine_encode_init,
.encode2 = libshine_encode_frame,
diff --git a/libavcodec/libtheoraenc.c b/libavcodec/libtheoraenc.c
index 9fa096f..4c90822 100644
--- a/libavcodec/libtheoraenc.c
+++ b/libavcodec/libtheoraenc.c
@@ -58,31 +58,26 @@
const ogg_packet* packet)
{
const char* message = NULL;
- uint8_t* newdata = NULL;
int newsize = avc_context->extradata_size + 2 + packet->bytes;
- int ret;
+ int err = AVERROR_INVALIDDATA;
if (packet->bytes < 0) {
message = "ogg_packet has negative size";
- ret = AVERROR_INVALIDDATA;
} else if (packet->bytes > 0xffff) {
message = "ogg_packet is larger than 65535 bytes";
- ret = AVERROR_INVALIDDATA;
} else if (newsize < avc_context->extradata_size) {
message = "extradata_size would overflow";
- ret = AVERROR_INVALIDDATA;
} else {
- newdata = av_realloc(avc_context->extradata, newsize);
- if (!newdata)
+ if ((err = av_reallocp(&avc_context->extradata, newsize)) < 0) {
+ avc_context->extradata_size = 0;
message = "av_realloc failed";
- ret = AVERROR(ENOMEM);
+ }
}
if (message) {
av_log(avc_context, AV_LOG_ERROR, "concatenate_packet failed: %s\n", message);
- return ret;
+ return err;
}
- avc_context->extradata = newdata;
avc_context->extradata_size = newsize;
AV_WB16(avc_context->extradata + (*offset), packet->bytes);
*offset += 2;
@@ -264,7 +259,7 @@
th_comment_clear(&t_comment);
/* Set up the output AVFrame */
- avc_context->coded_frame= avcodec_alloc_frame();
+ avc_context->coded_frame = av_frame_alloc();
return 0;
}
diff --git a/libavcodec/libutvideodec.cpp b/libavcodec/libutvideodec.cpp
index 0fae9f7..0d8fa1a 100644
--- a/libavcodec/libutvideodec.cpp
+++ b/libavcodec/libutvideodec.cpp
@@ -96,7 +96,7 @@
}
/* Allocate the output frame */
- avctx->coded_frame = avcodec_alloc_frame();
+ avctx->coded_frame = av_frame_alloc();
/* Ut Video only supports 8-bit */
avctx->bits_per_raw_sample = 8;
diff --git a/libavcodec/libutvideoenc.cpp b/libavcodec/libutvideoenc.cpp
index 44cd42f..ad70669 100644
--- a/libavcodec/libutvideoenc.cpp
+++ b/libavcodec/libutvideoenc.cpp
@@ -74,7 +74,7 @@
flags = ((avctx->prediction_method + 1) << 8) | (avctx->thread_count - 1);
avctx->priv_data = utv;
- avctx->coded_frame = avcodec_alloc_frame();
+ avctx->coded_frame = av_frame_alloc();
/* Alloc extradata buffer */
info = (UtVideoExtra *)av_malloc(sizeof(*info));
diff --git a/libavcodec/libvpx.c b/libavcodec/libvpx.c
new file mode 100644
index 0000000..9ff2e91
--- /dev/null
+++ b/libavcodec/libvpx.c
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2013 Guillaume Martres <smarter@ubuntu.com>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <vpx/vpx_codec.h>
+
+#include "libvpx.h"
+
+int ff_vp9_check_experimental(AVCodecContext *avctx)
+{
+ if (avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL &&
+ (vpx_codec_version_major() < 1 ||
+ (vpx_codec_version_major() == 1 && vpx_codec_version_minor() < 3))) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Non-experimental support of VP9 requires libvpx >= 1.3.0\n");
+ return AVERROR_EXPERIMENTAL;
+ }
+ return 0;
+}
diff --git a/libavcodec/libvpx.h b/libavcodec/libvpx.h
new file mode 100644
index 0000000..2c901f9
--- /dev/null
+++ b/libavcodec/libvpx.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2013 Guillaume Martres <smarter@ubuntu.com>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVCODEC_LIBVPX_H
+#define AVCODEC_LIBVPX_H
+
+#include "avcodec.h"
+
+int ff_vp9_check_experimental(AVCodecContext *avctx);
+
+#endif /* AVCODEC_LIBVPX_H */
diff --git a/libavcodec/libvpxdec.c b/libavcodec/libvpxdec.c
index de32f40..8d608c3 100644
--- a/libavcodec/libvpxdec.c
+++ b/libavcodec/libvpxdec.c
@@ -31,6 +31,7 @@
#include "libavutil/imgutils.h"
#include "avcodec.h"
#include "internal.h"
+#include "libvpx.h"
typedef struct VP8DecoderContext {
struct vpx_codec_ctx decoder;
@@ -90,9 +91,9 @@
if ((int) img->d_w != avctx->width || (int) img->d_h != avctx->height) {
av_log(avctx, AV_LOG_INFO, "dimension change! %dx%d -> %dx%d\n",
avctx->width, avctx->height, img->d_w, img->d_h);
- if (av_image_check_size(img->d_w, img->d_h, 0, avctx))
- return AVERROR_INVALIDDATA;
- avcodec_set_dimensions(avctx, img->d_w, img->d_h);
+ ret = ff_set_dimensions(avctx, img->d_w, img->d_h);
+ if (ret < 0)
+ return ret;
}
if ((ret = ff_get_buffer(avctx, picture, 0)) < 0)
return ret;
@@ -132,6 +133,9 @@
#if CONFIG_LIBVPX_VP9_DECODER
static av_cold int vp9_init(AVCodecContext *avctx)
{
+ int ret;
+ if ((ret = ff_vp9_check_experimental(avctx)))
+ return ret;
return vpx_init(avctx, &vpx_codec_vp9_dx_algo);
}
@@ -144,6 +148,6 @@
.init = vp9_init,
.close = vp8_free,
.decode = vp8_decode,
- .capabilities = CODEC_CAP_AUTO_THREADS | CODEC_CAP_EXPERIMENTAL,
+ .capabilities = CODEC_CAP_AUTO_THREADS | CODEC_CAP_DR1,
};
#endif /* CONFIG_LIBVPX_VP9_DECODER */
diff --git a/libavcodec/libvpxenc.c b/libavcodec/libvpxenc.c
index 8ebf052..c7ca050 100644
--- a/libavcodec/libvpxenc.c
+++ b/libavcodec/libvpxenc.c
@@ -31,6 +31,7 @@
#include "avcodec.h"
#include "internal.h"
#include "libavutil/avassert.h"
+#include "libvpx.h"
#include "libavutil/base64.h"
#include "libavutil/common.h"
#include "libavutil/intreadwrite.h"
@@ -89,6 +90,12 @@
int error_resilient;
int crf;
int max_intra_rate;
+
+ // VP9-only
+ int lossless;
+ int tile_columns;
+ int tile_rows;
+ int frame_parallel;
} VP8Context;
/** String mappings for enum vp8e_enc_control_id */
@@ -111,6 +118,12 @@
[VP8E_SET_ARNR_TYPE] = "VP8E_SET_ARNR_TYPE",
[VP8E_SET_CQ_LEVEL] = "VP8E_SET_CQ_LEVEL",
[VP8E_SET_MAX_INTRA_BITRATE_PCT] = "VP8E_SET_MAX_INTRA_BITRATE_PCT",
+#if CONFIG_LIBVPX_VP9_ENCODER
+ [VP9E_SET_LOSSLESS] = "VP9E_SET_LOSSLESS",
+ [VP9E_SET_TILE_COLUMNS] = "VP9E_SET_TILE_COLUMNS",
+ [VP9E_SET_TILE_ROWS] = "VP9E_SET_TILE_ROWS",
+ [VP9E_SET_FRAME_PARALLEL_DECODING] = "VP9E_SET_FRAME_PARALLEL_DECODING",
+#endif
};
static av_cold void log_encoder_error(AVCodecContext *avctx, const char *desc)
@@ -308,7 +321,7 @@
if (avctx->qmin >= 0)
enccfg.rc_min_quantizer = avctx->qmin;
- if (avctx->qmax > 0)
+ if (avctx->qmax >= 0)
enccfg.rc_max_quantizer = avctx->qmax;
if (enccfg.rc_end_usage == VPX_CQ) {
@@ -415,12 +428,26 @@
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));
+ if (avctx->codec_id == AV_CODEC_ID_VP8)
+ codecctl_int(avctx, VP8E_SET_TOKEN_PARTITIONS, av_log2(avctx->slices));
codecctl_int(avctx, VP8E_SET_STATIC_THRESHOLD, avctx->mb_threshold);
codecctl_int(avctx, VP8E_SET_CQ_LEVEL, ctx->crf);
if (ctx->max_intra_rate >= 0)
codecctl_int(avctx, VP8E_SET_MAX_INTRA_BITRATE_PCT, ctx->max_intra_rate);
+#if CONFIG_LIBVPX_VP9_ENCODER
+ if (avctx->codec_id == AV_CODEC_ID_VP9) {
+ if (ctx->lossless >= 0)
+ codecctl_int(avctx, VP9E_SET_LOSSLESS, ctx->lossless);
+ if (ctx->tile_columns >= 0)
+ codecctl_int(avctx, VP9E_SET_TILE_COLUMNS, ctx->tile_columns);
+ if (ctx->tile_rows >= 0)
+ codecctl_int(avctx, VP9E_SET_TILE_ROWS, ctx->tile_rows);
+ if (ctx->frame_parallel >= 0)
+ codecctl_int(avctx, VP9E_SET_FRAME_PARALLEL_DECODING, ctx->frame_parallel);
+ }
+#endif
+
av_log(avctx, AV_LOG_DEBUG, "Using deadline: %d\n", ctx->deadline);
//provide dummy value to initialize wrapper, values will be updated each _encode()
@@ -431,7 +458,7 @@
vpx_img_wrap(&ctx->rawimg_alpha, VPX_IMG_FMT_I420, avctx->width, avctx->height, 1,
(unsigned char*)1);
- avctx->coded_frame = avcodec_alloc_frame();
+ avctx->coded_frame = av_frame_alloc();
if (!avctx->coded_frame) {
av_log(avctx, AV_LOG_ERROR, "Error allocating coded frame\n");
vp8_free(avctx);
@@ -611,11 +638,13 @@
break;
case VPX_CODEC_STATS_PKT: {
struct vpx_fixed_buf *stats = &ctx->twopass_stats;
- stats->buf = av_realloc_f(stats->buf, 1,
- stats->sz + pkt->data.twopass_stats.sz);
- if (!stats->buf) {
+ int err;
+ if ((err = av_reallocp(&stats->buf,
+ stats->sz +
+ pkt->data.twopass_stats.sz)) < 0) {
+ stats->sz = 0;
av_log(avctx, AV_LOG_ERROR, "Stat buffer realloc failed\n");
- return AVERROR(ENOMEM);
+ return err;
}
memcpy((uint8_t*)stats->buf + stats->sz,
pkt->data.twopass_stats.buf, pkt->data.twopass_stats.sz);
@@ -718,43 +747,70 @@
#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, {.i64 = 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, {.i64 = -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, {.i64 = -1}, -1, INT_MAX, VE},
- { "arnr-maxframes", "altref noise reduction max frame count", OFFSET(arnr_max_frames), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, VE},
- { "arnr-strength", "altref noise reduction filter strength", OFFSET(arnr_strength), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, VE},
- { "arnr-type", "altref noise reduction filter type", OFFSET(arnr_type), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, VE, "arnr_type"},
- { "backward", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 1}, 0, 0, VE, "arnr_type" },
- { "forward", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 2}, 0, 0, VE, "arnr_type" },
- { "centered", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 3}, 0, 0, VE, "arnr_type" },
- { "deadline", "Time to spend encoding, in microseconds.", OFFSET(deadline), AV_OPT_TYPE_INT, {.i64 = VPX_DL_GOOD_QUALITY}, INT_MIN, INT_MAX, VE, "quality"},
- { "best", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = VPX_DL_BEST_QUALITY}, 0, 0, VE, "quality"},
- { "good", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = VPX_DL_GOOD_QUALITY}, 0, 0, VE, "quality"},
- { "realtime", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = VPX_DL_REALTIME}, 0, 0, VE, "quality"},
- { "error-resilient", "Error resilience configuration", OFFSET(error_resilient), AV_OPT_TYPE_FLAGS, {.i64 = 0}, INT_MIN, INT_MAX, VE, "er"},
- { "max-intra-rate", "Maximum I-frame bitrate (pct) 0=unlimited", OFFSET(max_intra_rate), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, VE},
-#ifdef VPX_ERROR_RESILIENT_DEFAULT
- { "default", "Improve resiliency against losses of whole frames", 0, AV_OPT_TYPE_CONST, {.i64 = 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, {.i64 = VPX_ERROR_RESILIENT_PARTITIONS}, 0, 0, VE, "er"},
+
+#ifndef VPX_ERROR_RESILIENT_DEFAULT
+#define VPX_ERROR_RESILIENT_DEFAULT 1
+#define VPX_ERROR_RESILIENT_PARTITIONS 2
#endif
-{"speed", "", offsetof(VP8Context, cpu_used), AV_OPT_TYPE_INT, {.i64 = 3}, -16, 16, VE},
-{"quality", "", offsetof(VP8Context, deadline), AV_OPT_TYPE_INT, {.i64 = VPX_DL_GOOD_QUALITY}, INT_MIN, INT_MAX, VE, "quality"},
-{"vp8flags", "", offsetof(VP8Context, flags), FF_OPT_TYPE_FLAGS, {.i64 = 0}, 0, UINT_MAX, VE, "flags"},
-{"error_resilient", "enable error resilience", 0, FF_OPT_TYPE_CONST, {.dbl = VP8F_ERROR_RESILIENT}, INT_MIN, INT_MAX, VE, "flags"},
-{"altref", "enable use of alternate reference frames (VP8/2-pass only)", 0, FF_OPT_TYPE_CONST, {.dbl = VP8F_AUTO_ALT_REF}, INT_MIN, INT_MAX, VE, "flags"},
-{"arnr_max_frames", "altref noise reduction max frame count", offsetof(VP8Context, arnr_max_frames), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 15, VE},
-{"arnr_strength", "altref noise reduction filter strength", offsetof(VP8Context, arnr_strength), AV_OPT_TYPE_INT, {.i64 = 3}, 0, 6, VE},
-{"arnr_type", "altref noise reduction filter type", offsetof(VP8Context, arnr_type), AV_OPT_TYPE_INT, {.i64 = 3}, 1, 3, VE},
-{"rc_lookahead", "Number of frames to look ahead for alternate reference frame selection", offsetof(VP8Context, lag_in_frames), AV_OPT_TYPE_INT, {.i64 = 25}, 0, 25, VE},
- { "crf", "Select the quality for constant quality mode", offsetof(VP8Context, crf), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 63, VE },
+
+#define COMMON_OPTIONS \
+ { "cpu-used", "Quality/Speed ratio modifier", OFFSET(cpu_used), AV_OPT_TYPE_INT, {.i64 = 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, {.i64 = -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, {.i64 = -1}, -1, INT_MAX, VE}, \
+ { "arnr-maxframes", "altref noise reduction max frame count", OFFSET(arnr_max_frames), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, VE}, \
+ { "arnr-strength", "altref noise reduction filter strength", OFFSET(arnr_strength), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, VE}, \
+ { "arnr-type", "altref noise reduction filter type", OFFSET(arnr_type), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, VE, "arnr_type"}, \
+ { "backward", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 1}, 0, 0, VE, "arnr_type" }, \
+ { "forward", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 2}, 0, 0, VE, "arnr_type" }, \
+ { "centered", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 3}, 0, 0, VE, "arnr_type" }, \
+ { "deadline", "Time to spend encoding, in microseconds.", OFFSET(deadline), AV_OPT_TYPE_INT, {.i64 = VPX_DL_GOOD_QUALITY}, INT_MIN, INT_MAX, VE, "quality"}, \
+ { "best", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = VPX_DL_BEST_QUALITY}, 0, 0, VE, "quality"}, \
+ { "good", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = VPX_DL_GOOD_QUALITY}, 0, 0, VE, "quality"}, \
+ { "realtime", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = VPX_DL_REALTIME}, 0, 0, VE, "quality"}, \
+ { "error-resilient", "Error resilience configuration", OFFSET(error_resilient), AV_OPT_TYPE_FLAGS, {.i64 = 0}, INT_MIN, INT_MAX, VE, "er"}, \
+ { "max-intra-rate", "Maximum I-frame bitrate (pct) 0=unlimited", OFFSET(max_intra_rate), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, VE}, \
+ { "default", "Improve resiliency against losses of whole frames", 0, AV_OPT_TYPE_CONST, {.i64 = 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, {.i64 = VPX_ERROR_RESILIENT_PARTITIONS}, 0, 0, VE, "er"}, \
+ { "crf", "Select the quality for constant quality mode", offsetof(VP8Context, crf), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 63, VE }, \
+
+#define LEGACY_OPTIONS \
+ {"speed", "", offsetof(VP8Context, cpu_used), AV_OPT_TYPE_INT, {.i64 = 1}, -16, 16, VE}, \
+ {"quality", "", offsetof(VP8Context, deadline), AV_OPT_TYPE_INT, {.i64 = VPX_DL_GOOD_QUALITY}, INT_MIN, INT_MAX, VE, "quality"}, \
+ {"vp8flags", "", offsetof(VP8Context, flags), FF_OPT_TYPE_FLAGS, {.i64 = 0}, 0, UINT_MAX, VE, "flags"}, \
+ {"error_resilient", "enable error resilience", 0, FF_OPT_TYPE_CONST, {.dbl = VP8F_ERROR_RESILIENT}, INT_MIN, INT_MAX, VE, "flags"}, \
+ {"altref", "enable use of alternate reference frames (VP8/2-pass only)", 0, FF_OPT_TYPE_CONST, {.dbl = VP8F_AUTO_ALT_REF}, INT_MIN, INT_MAX, VE, "flags"}, \
+ {"arnr_max_frames", "altref noise reduction max frame count", offsetof(VP8Context, arnr_max_frames), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 15, VE}, \
+ {"arnr_strength", "altref noise reduction filter strength", offsetof(VP8Context, arnr_strength), AV_OPT_TYPE_INT, {.i64 = 3}, 0, 6, VE}, \
+ {"arnr_type", "altref noise reduction filter type", offsetof(VP8Context, arnr_type), AV_OPT_TYPE_INT, {.i64 = 3}, 1, 3, VE}, \
+ {"rc_lookahead", "Number of frames to look ahead for alternate reference frame selection", offsetof(VP8Context, lag_in_frames), AV_OPT_TYPE_INT, {.i64 = 25}, 0, 25, VE}, \
+
+#if CONFIG_LIBVPX_VP8_ENCODER
+static const AVOption vp8_options[] = {
+ COMMON_OPTIONS
+ LEGACY_OPTIONS
{ NULL }
};
+#endif
+
+#if CONFIG_LIBVPX_VP9_ENCODER
+static const AVOption vp9_options[] = {
+ COMMON_OPTIONS
+ { "lossless", "Lossless mode", OFFSET(lossless), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 1, VE},
+ { "tile-columns", "Number of tile columns to use, log2", OFFSET(tile_columns), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 6, VE},
+ { "tile-rows", "Number of tile rows to use, log2", OFFSET(tile_rows), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 2, VE},
+ { "frame-parallel", "Enable frame parallel decodability features", OFFSET(frame_parallel), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 1, VE},
+ LEGACY_OPTIONS
+ { NULL }
+};
+#endif
+
+#undef COMMON_OPTIONS
+#undef LEGACY_OPTIONS
static const AVCodecDefault defaults[] = {
{ "qmin", "-1" },
@@ -773,7 +829,7 @@
static const AVClass class_vp8 = {
.class_name = "libvpx-vp8 encoder",
.item_name = av_default_item_name,
- .option = options,
+ .option = vp8_options,
.version = LIBAVUTIL_VERSION_INT,
};
@@ -796,13 +852,16 @@
#if CONFIG_LIBVPX_VP9_ENCODER
static av_cold int vp9_init(AVCodecContext *avctx)
{
+ int ret;
+ if ((ret = ff_vp9_check_experimental(avctx)))
+ return ret;
return vpx_init(avctx, &vpx_codec_vp9_cx_algo);
}
static const AVClass class_vp9 = {
.class_name = "libvpx-vp9 encoder",
.item_name = av_default_item_name,
- .option = options,
+ .option = vp9_options,
.version = LIBAVUTIL_VERSION_INT,
};
@@ -815,7 +874,7 @@
.init = vp9_init,
.encode2 = vp8_encode,
.close = vp8_free,
- .capabilities = CODEC_CAP_DELAY | CODEC_CAP_AUTO_THREADS | CODEC_CAP_EXPERIMENTAL,
+ .capabilities = CODEC_CAP_DELAY | CODEC_CAP_AUTO_THREADS,
.pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE },
.priv_class = &class_vp9,
.defaults = defaults,
diff --git a/libavcodec/libx264.c b/libavcodec/libx264.c
index 4093510..89df55f 100644
--- a/libavcodec/libx264.c
+++ b/libavcodec/libx264.c
@@ -44,7 +44,6 @@
x264_picture_t pic;
uint8_t *sei;
int sei_size;
- AVFrame out_pic;
char *preset;
char *tune;
char *profile;
@@ -208,20 +207,20 @@
switch (pic_out.i_type) {
case X264_TYPE_IDR:
case X264_TYPE_I:
- x4->out_pic.pict_type = AV_PICTURE_TYPE_I;
+ ctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
break;
case X264_TYPE_P:
- x4->out_pic.pict_type = AV_PICTURE_TYPE_P;
+ ctx->coded_frame->pict_type = AV_PICTURE_TYPE_P;
break;
case X264_TYPE_B:
case X264_TYPE_BREF:
- x4->out_pic.pict_type = AV_PICTURE_TYPE_B;
+ ctx->coded_frame->pict_type = AV_PICTURE_TYPE_B;
break;
}
pkt->flags |= AV_PKT_FLAG_KEY*pic_out.b_keyframe;
if (ret)
- x4->out_pic.quality = (pic_out.i_qpplus1 - 1) * FF_QP2LAMBDA;
+ ctx->coded_frame->quality = (pic_out.i_qpplus1 - 1) * FF_QP2LAMBDA;
*got_packet = ret;
return 0;
@@ -237,6 +236,8 @@
if (x4->enc)
x264_encoder_close(x4->enc);
+ av_frame_free(&avctx->coded_frame);
+
return 0;
}
@@ -570,7 +571,9 @@
if (!x4->enc)
return -1;
- avctx->coded_frame = &x4->out_pic;
+ avctx->coded_frame = av_frame_alloc();
+ if (!avctx->coded_frame)
+ return AVERROR(ENOMEM);
if (avctx->flags & CODEC_FLAG_GLOBAL_HEADER) {
x264_nal_t *nal;
diff --git a/libavcodec/libxavs.c b/libavcodec/libxavs.c
index f7b99e0..ffe3411 100644
--- a/libavcodec/libxavs.c
+++ b/libavcodec/libxavs.c
@@ -45,7 +45,6 @@
xavs_picture_t pic;
uint8_t *sei;
int sei_size;
- AVFrame out_pic;
int end_of_stream;
float crf;
int cqp;
@@ -111,10 +110,10 @@
return 1;
}
-static int XAVS_frame(AVCodecContext *ctx, AVPacket *pkt,
+static int XAVS_frame(AVCodecContext *avctx, AVPacket *pkt,
const AVFrame *frame, int *got_packet)
{
- XavsContext *x4 = ctx->priv_data;
+ XavsContext *x4 = avctx->priv_data;
xavs_nal_t *nal;
int nnal, i, ret;
xavs_picture_t pic_out;
@@ -130,67 +129,67 @@
x4->pic.i_pts = frame->pts;
x4->pic.i_type = XAVS_TYPE_AUTO;
- x4->pts_buffer[ctx->frame_number % (ctx->max_b_frames+1)] = frame->pts;
+ x4->pts_buffer[avctx->frame_number % (avctx->max_b_frames+1)] = frame->pts;
}
if (xavs_encoder_encode(x4->enc, &nal, &nnal,
frame? &x4->pic: NULL, &pic_out) < 0)
return -1;
- ret = encode_nals(ctx, pkt, nal, nnal);
+ ret = encode_nals(avctx, pkt, nal, nnal);
if (ret < 0)
return -1;
if (!ret) {
if (!frame && !(x4->end_of_stream)) {
- if ((ret = ff_alloc_packet2(ctx, pkt, 4)) < 0)
+ if ((ret = ff_alloc_packet2(avctx, pkt, 4)) < 0)
return ret;
pkt->data[0] = 0x0;
pkt->data[1] = 0x0;
pkt->data[2] = 0x01;
pkt->data[3] = 0xb1;
- pkt->dts = 2*x4->pts_buffer[(x4->out_frame_count-1)%(ctx->max_b_frames+1)] -
- x4->pts_buffer[(x4->out_frame_count-2)%(ctx->max_b_frames+1)];
+ pkt->dts = 2*x4->pts_buffer[(x4->out_frame_count-1)%(avctx->max_b_frames+1)] -
+ x4->pts_buffer[(x4->out_frame_count-2)%(avctx->max_b_frames+1)];
x4->end_of_stream = END_OF_STREAM;
*got_packet = 1;
}
return 0;
}
- x4->out_pic.pts = pic_out.i_pts;
+ avctx->coded_frame->pts = pic_out.i_pts;
pkt->pts = pic_out.i_pts;
- if (ctx->has_b_frames) {
+ if (avctx->has_b_frames) {
if (!x4->out_frame_count)
pkt->dts = pkt->pts - (x4->pts_buffer[1] - x4->pts_buffer[0]);
else
- pkt->dts = x4->pts_buffer[(x4->out_frame_count-1)%(ctx->max_b_frames+1)];
+ pkt->dts = x4->pts_buffer[(x4->out_frame_count-1)%(avctx->max_b_frames+1)];
} else
pkt->dts = pkt->pts;
switch (pic_out.i_type) {
case XAVS_TYPE_IDR:
case XAVS_TYPE_I:
- x4->out_pic.pict_type = AV_PICTURE_TYPE_I;
+ avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
break;
case XAVS_TYPE_P:
- x4->out_pic.pict_type = AV_PICTURE_TYPE_P;
+ avctx->coded_frame->pict_type = AV_PICTURE_TYPE_P;
break;
case XAVS_TYPE_B:
case XAVS_TYPE_BREF:
- x4->out_pic.pict_type = AV_PICTURE_TYPE_B;
+ avctx->coded_frame->pict_type = AV_PICTURE_TYPE_B;
break;
}
/* There is no IDR frame in AVS JiZhun */
/* Sequence header is used as a flag */
if (pic_out.i_type == XAVS_TYPE_I) {
- x4->out_pic.key_frame = 1;
+ avctx->coded_frame->key_frame = 1;
pkt->flags |= AV_PKT_FLAG_KEY;
}
- x4->out_pic.quality = (pic_out.i_qpplus1 - 1) * FF_QP2LAMBDA;
+ avctx->coded_frame->quality = (pic_out.i_qpplus1 - 1) * FF_QP2LAMBDA;
x4->out_frame_count++;
*got_packet = ret;
@@ -208,6 +207,8 @@
if (x4->enc)
xavs_encoder_close(x4->enc);
+ av_frame_free(&avctx->coded_frame);
+
return 0;
}
@@ -355,7 +356,10 @@
if (!(x4->pts_buffer = av_mallocz((avctx->max_b_frames+1) * sizeof(*x4->pts_buffer))))
return AVERROR(ENOMEM);
- avctx->coded_frame = &x4->out_pic;
+ avctx->coded_frame = av_frame_alloc();
+ if (!avctx->coded_frame)
+ return AVERROR(ENOMEM);
+
/* TAG: Do we have GLOBAL HEADER in AVS */
/* We Have PPS and SPS in AVS */
if (avctx->flags & CODEC_FLAG_GLOBAL_HEADER) {
diff --git a/libavcodec/libxvid.c b/libavcodec/libxvid.c
index d4c7149..40b3bff 100644
--- a/libavcodec/libxvid.c
+++ b/libavcodec/libxvid.c
@@ -56,7 +56,6 @@
int me_flags; /**< Motion Estimation flags */
int qscale; /**< Do we use constant scale? */
int quicktime_format; /**< Are we in a QT-based format? */
- AVFrame encoded_picture; /**< Encoded frame information */
char *twopassbuffer; /**< Character buffer for two-pass */
char *old_twopassbuffer; /**< Old character buffer (two-pass) */
char *twopassfile; /**< second pass temp file name */
@@ -651,7 +650,9 @@
}
x->encoder_handle = xvid_enc_create.handle;
- avctx->coded_frame = &x->encoded_picture;
+ avctx->coded_frame = av_frame_alloc();
+ if (!avctx->coded_frame)
+ return AVERROR(ENOMEM);
return 0;
fail:
@@ -665,7 +666,7 @@
int xerr, i, ret, user_packet = !!pkt->data;
char *tmp;
struct xvid_context *x = avctx->priv_data;
- AVFrame *p = &x->encoded_picture;
+ AVFrame *p = avctx->coded_frame;
int mb_width = (avctx->width + 15) / 16;
int mb_height = (avctx->height + 15) / 16;
@@ -678,7 +679,6 @@
/* Start setting up the frame */
xvid_enc_frame.version = XVID_VERSION;
xvid_enc_stats.version = XVID_VERSION;
- *p = *picture;
/* Let Xvid know where to put the frame. */
xvid_enc_frame.bitstream = pkt->data;
diff --git a/libavcodec/libzvbi-teletextdec.c b/libavcodec/libzvbi-teletextdec.c
index 2f6714c..bf2dc06 100644
--- a/libavcodec/libzvbi-teletextdec.c
+++ b/libavcodec/libzvbi-teletextdec.c
@@ -19,7 +19,9 @@
*/
#include "avcodec.h"
+#include "libavcodec/ass.h"
#include "libavutil/opt.h"
+#include "libavutil/bprint.h"
#include "libavutil/intreadwrite.h"
#include <libzvbi.h>
@@ -31,6 +33,15 @@
#define VBI_G(rgba) (((rgba) >> 8) & 0xFF)
#define VBI_B(rgba) (((rgba) >> 16) & 0xFF)
#define VBI_A(rgba) (((rgba) >> 24) & 0xFF)
+#define MAX_BUFFERED_PAGES 25
+
+typedef struct TeletextPage
+{
+ AVSubtitleRect *sub_rect;
+ int pgno;
+ int subno;
+ int64_t pts;
+} TeletextPage;
/* main data structure */
typedef struct TeletextContext
@@ -39,15 +50,17 @@
char *pgno;
int x_offset;
int y_offset;
- char *format;
- int format_id; /* 0 = bitmap, 1 = text */
+ int format_id; /* 0 = bitmap, 1 = text/ass */
int chop_top;
int sub_duration; /* in msec */
int transparent_bg;
int chop_spaces;
int lines_processed;
- AVSubtitleRect *sub_rect;
+ TeletextPage *pages;
+ int nb_pages;
+ int64_t pts;
+ int handler_ret;
vbi_decoder * vbi;
vbi_dvb_demux * dx;
@@ -72,14 +85,54 @@
return len;
}
+static void
+subtitle_rect_free(AVSubtitleRect **sub_rect)
+{
+ av_freep(&(*sub_rect)->pict.data[0]);
+ av_freep(&(*sub_rect)->pict.data[1]);
+ av_freep(&(*sub_rect)->ass);
+ av_freep(sub_rect);
+}
+
+static int
+create_ass_text(TeletextContext *ctx, const char *text, char **ass)
+{
+ int ret;
+ AVBPrint buf, buf2;
+ const int ts_start = av_rescale_q(ctx->pts, AV_TIME_BASE_Q, (AVRational){1, 100});
+ const int ts_duration = av_rescale_q(ctx->sub_duration, (AVRational){1, 1000}, (AVRational){1, 100});
+
+ /* First we escape the plain text into buf. */
+ av_bprint_init(&buf, 0, AV_BPRINT_SIZE_UNLIMITED);
+ ff_ass_bprint_text_event(&buf, text, strlen(text), "", 0);
+
+ if (!av_bprint_is_complete(&buf)) {
+ av_bprint_finalize(&buf, NULL);
+ return AVERROR(ENOMEM);
+ }
+
+ /* Then we create the ass dialog line in buf2 from the escaped text in buf. */
+ av_bprint_init(&buf2, 0, AV_BPRINT_SIZE_UNLIMITED);
+ ff_ass_bprint_dialog(&buf2, buf.str, ts_start, ts_duration, 0);
+ av_bprint_finalize(&buf, NULL);
+
+ if (!av_bprint_is_complete(&buf2)) {
+ av_bprint_finalize(&buf2, NULL);
+ return AVERROR(ENOMEM);
+ }
+
+ if ((ret = av_bprint_finalize(&buf2, ass)) < 0)
+ return ret;
+
+ return 0;
+}
+
// draw a page as text
static int
-gen_sub_text(TeletextContext *ctx, vbi_page *page, int chop_top)
+gen_sub_text(TeletextContext *ctx, AVSubtitleRect *sub_rect, vbi_page *page, int chop_top)
{
- AVSubtitleRect *sub_rect = ctx->sub_rect;
- char *text;
const char *in;
- char *out;
+ AVBPrint buf;
char *vbi_text = av_malloc(TEXT_MAXSZ);
int sz;
@@ -97,11 +150,8 @@
}
vbi_text[sz] = '\0';
in = vbi_text;
- out = text = av_malloc(TEXT_MAXSZ);
- if (!text) {
- av_free(vbi_text);
- return AVERROR(ENOMEM);
- }
+ av_bprint_init(&buf, 0, TEXT_MAXSZ);
+
if (ctx->chop_spaces) {
for (;;) {
int nl, sz;
@@ -116,33 +166,38 @@
break;
// skip trailing spaces
sz = chop_spaces_utf8(in, nl);
- memcpy(out, in, sz);
- out += sz;
- *out++ = '\n';
+ av_bprint_append_data(&buf, in, sz);
+ av_bprintf(&buf, "\n");
in += nl;
}
} else {
- strcpy(text, vbi_text);
- out += sz;
- *out++ = '\n';
+ av_bprintf(&buf, "%s\n", vbi_text);
}
av_free(vbi_text);
- *out = '\0';
- if (out > text) {
- sub_rect->type = SUBTITLE_TEXT;
- sub_rect->text = text;
- av_log(ctx, AV_LOG_DEBUG, "subtext:%s:txetbus\n", text);
+
+ if (!av_bprint_is_complete(&buf)) {
+ av_bprint_finalize(&buf, NULL);
+ return AVERROR(ENOMEM);
+ }
+
+ if (buf.len) {
+ int ret;
+ sub_rect->type = SUBTITLE_ASS;
+ if ((ret = create_ass_text(ctx, buf.str, &sub_rect->ass)) < 0) {
+ av_bprint_finalize(&buf, NULL);
+ return ret;
+ }
+ av_log(ctx, AV_LOG_DEBUG, "subtext:%s:txetbus\n", sub_rect->ass);
} else {
sub_rect->type = SUBTITLE_NONE;
- av_free(text);
}
+ av_bprint_finalize(&buf, NULL);
return 0;
}
static void
-fix_transparency(TeletextContext *ctx, vbi_page *page, int chop_top, uint8_t transparent_color, int resx, int resy)
+fix_transparency(TeletextContext *ctx, AVSubtitleRect *sub_rect, vbi_page *page, int chop_top, uint8_t transparent_color, int resx, int resy)
{
- AVSubtitleRect *sub_rect = ctx->sub_rect;
int iy;
// Hack for transparency, inspired by VLC code...
@@ -173,9 +228,8 @@
// draw a page as bitmap
static int
-gen_sub_bitmap(TeletextContext *ctx, vbi_page *page, int chop_top)
+gen_sub_bitmap(TeletextContext *ctx, AVSubtitleRect *sub_rect, vbi_page *page, int chop_top)
{
- AVSubtitleRect *sub_rect = ctx->sub_rect;
int resx = page->columns * 12;
int resy = (page->rows - chop_top) * 10;
uint8_t ci, cmax = 0;
@@ -206,7 +260,7 @@
0, chop_top, page->columns, page->rows - chop_top,
/*reveal*/ 1, /*flash*/ 1);
- fix_transparency(ctx, page, chop_top, cmax, resx, resy);
+ fix_transparency(ctx, sub_rect, page, chop_top, cmax, resx, resy);
sub_rect->x = ctx->x_offset;
sub_rect->y = ctx->y_offset;
sub_rect->w = resx;
@@ -239,6 +293,7 @@
handler(vbi_event *ev, void *user_data)
{
TeletextContext *ctx = user_data;
+ TeletextPage *new_pages;
vbi_page page;
int res;
char pgno_str[12];
@@ -253,6 +308,8 @@
if (strcmp(ctx->pgno, "*") && !strstr(ctx->pgno, pgno_str))
return;
+ if (ctx->handler_ret < 0)
+ return;
/* Fetch the page. */
res = vbi_fetch_vt_page(ctx->vbi, &page,
@@ -279,18 +336,34 @@
av_log(ctx, AV_LOG_DEBUG, "%d x %d page chop:%d\n",
page.columns, page.rows, chop_top);
- if (!ctx->sub_rect) {
- ctx->sub_rect = av_mallocz(sizeof(*ctx->sub_rect));
- if (ctx->sub_rect) {
- res = (ctx->format_id == 0) ?
- gen_sub_bitmap(ctx, &page, chop_top) :
- gen_sub_text (ctx, &page, chop_top);
- if (res)
- av_freep(&ctx->sub_rect);
+ if (ctx->nb_pages < MAX_BUFFERED_PAGES) {
+ if ((new_pages = av_realloc_array(ctx->pages, ctx->nb_pages + 1, sizeof(TeletextPage)))) {
+ TeletextPage *cur_page = new_pages + ctx->nb_pages;
+ ctx->pages = new_pages;
+ cur_page->sub_rect = av_mallocz(sizeof(*cur_page->sub_rect));
+ cur_page->pts = ctx->pts;
+ cur_page->pgno = ev->ev.ttx_page.pgno;
+ cur_page->subno = ev->ev.ttx_page.subno;
+ if (cur_page->sub_rect) {
+ res = (ctx->format_id == 0) ?
+ gen_sub_bitmap(ctx, cur_page->sub_rect, &page, chop_top) :
+ gen_sub_text (ctx, cur_page->sub_rect, &page, chop_top);
+ if (res < 0) {
+ av_freep(&cur_page->sub_rect);
+ ctx->handler_ret = res;
+ } else {
+ ctx->pages[ctx->nb_pages++] = *cur_page;
+ }
+ } else {
+ ctx->handler_ret = AVERROR(ENOMEM);
+ }
+ } else {
+ ctx->handler_ret = AVERROR(ENOMEM);
}
} else {
- // FIXME: Multiple teletext pages in a single packet, some kind of buffering should be done instead of dropping the page...
- av_log(ctx, AV_LOG_WARNING, "Missed page %s.%02x.\n", pgno_str, ev->ev.ttx_page.subno & 0xFF);
+ //TODO: If multiple packets contain more than one page, pages may got queued up, and this may happen...
+ av_log(ctx, AV_LOG_ERROR, "Buffered too many pages, dropping page %s.\n", pgno_str);
+ ctx->handler_ret = AVERROR(ENOSYS);
}
vbi_unref_page(&page);
@@ -304,10 +377,11 @@
TeletextContext *ctx = avctx->priv_data;
AVSubtitle *sub = data;
const uint8_t *buf = pkt->data;
- unsigned int left = pkt->size;
+ int left = pkt->size;
uint8_t pesheader[45] = {0x00, 0x00, 0x01, 0xbd, 0x00, 0x00, 0x85, 0x80, 0x24, 0x21, 0x00, 0x01, 0x00, 0x01};
int pesheader_size = sizeof(pesheader);
const uint8_t *pesheader_buf = pesheader;
+ int ret = 0;
if (!ctx->vbi) {
if (!(ctx->vbi = vbi_decoder_new()))
@@ -321,64 +395,84 @@
if (!ctx->dx && (!(ctx->dx = vbi_dvb_pes_demux_new (/* callback */ NULL, NULL))))
return AVERROR(ENOMEM);
- // We allow unreasonably big packets, even if the standard only allows a max size of 1472
- if ((pesheader_size + left) < 184 || (pesheader_size + left) > 65504 || (pesheader_size + left) % 184 != 0)
- return AVERROR_INVALIDDATA;
+ if (avctx->pkt_timebase.den && pkt->pts != AV_NOPTS_VALUE)
+ ctx->pts = av_rescale_q(pkt->pts, avctx->pkt_timebase, AV_TIME_BASE_Q);
- memset(pesheader + 14, 0xff, pesheader_size - 14);
- AV_WB16(pesheader + 4, left + pesheader_size - 6);
+ if (left) {
+ // We allow unreasonably big packets, even if the standard only allows a max size of 1472
+ if ((pesheader_size + left) < 184 || (pesheader_size + left) > 65504 || (pesheader_size + left) % 184 != 0)
+ return AVERROR_INVALIDDATA;
- /* PTS is deliberately left as 0 in the PES header, otherwise libzvbi uses
- * it to detect dropped frames. Unforunatey the guessed packet PTS values
- * (see mpegts demuxer) are not accurate enough to pass that test. */
- vbi_dvb_demux_cor(ctx->dx, ctx->sliced, 64, NULL, &pesheader_buf, &pesheader_size);
+ memset(pesheader + 14, 0xff, pesheader_size - 14);
+ AV_WB16(pesheader + 4, left + pesheader_size - 6);
- while (left > 0) {
- int64_t pts = 0;
- unsigned int lines = vbi_dvb_demux_cor(ctx->dx, ctx->sliced, 64, &pts, &buf, &left);
+ /* PTS is deliberately left as 0 in the PES header, otherwise libzvbi uses
+ * it to detect dropped frames. Unforunatey the guessed packet PTS values
+ * (see mpegts demuxer) are not accurate enough to pass that test. */
+ vbi_dvb_demux_cor(ctx->dx, ctx->sliced, 64, NULL, &pesheader_buf, &pesheader_size);
+
+ ctx->handler_ret = pkt->size;
+
+ while (left > 0) {
+ int64_t pts = 0;
+ unsigned int lines = vbi_dvb_demux_cor(ctx->dx, ctx->sliced, 64, &pts, &buf, &left);
#ifdef DEBUG
- av_log(avctx, AV_LOG_DEBUG,
- "ctx=%p buf_size=%d left=%u lines=%u pts=%f pkt_pts=%f\n",
- ctx, pkt->size, left, lines, (double)pts/90000.0, (double)pkt->pts/90000.0);
+ av_log(avctx, AV_LOG_DEBUG,
+ "ctx=%p buf_size=%d left=%u lines=%u pts=%f pkt_pts=%f\n",
+ ctx, pkt->size, left, lines, (double)pts/90000.0, (double)pkt->pts/90000.0);
#endif
- if (lines > 0) {
+ if (lines > 0) {
#ifdef DEBUGx
- int i;
- for(i=0; i<lines; ++i)
- av_log(avctx, AV_LOG_DEBUG,
- "lines=%d id=%x\n", i, ctx->sliced[i].id);
+ int i;
+ for(i=0; i<lines; ++i)
+ av_log(avctx, AV_LOG_DEBUG,
+ "lines=%d id=%x\n", i, ctx->sliced[i].id);
#endif
- vbi_decode(ctx->vbi, ctx->sliced, lines, (double)pts/90000.0);
- ctx->lines_processed += lines;
+ vbi_decode(ctx->vbi, ctx->sliced, lines, (double)pts/90000.0);
+ ctx->lines_processed += lines;
+ }
}
+ ctx->pts = AV_NOPTS_VALUE;
+ ret = ctx->handler_ret;
}
+ if (ret < 0)
+ return ret;
+
// is there a subtitle to pass?
- if (ctx->sub_rect) {
- sub->format = (ctx->sub_rect->type == SUBTITLE_TEXT ? 1: 0);
+ if (ctx->nb_pages) {
+ int i;
+ sub->format = ctx->format_id;
sub->start_display_time = 0;
sub->end_display_time = ctx->sub_duration;
sub->num_rects = 0;
+ sub->pts = ctx->pages->pts;
- if (ctx->sub_rect->type != SUBTITLE_NONE) {
+ if (ctx->pages->sub_rect->type != SUBTITLE_NONE) {
sub->rects = av_malloc(sizeof(*sub->rects) * 1);
if (sub->rects) {
sub->num_rects = 1;
- sub->rects[0] = ctx->sub_rect;
+ sub->rects[0] = ctx->pages->sub_rect;
+ } else {
+ ret = AVERROR(ENOMEM);
}
} else {
av_log(avctx, AV_LOG_DEBUG, "sending empty sub\n");
sub->rects = NULL;
}
if (!sub->rects) // no rect was passed
- av_free(ctx->sub_rect);
- ctx->sub_rect = NULL;
+ subtitle_rect_free(&ctx->pages->sub_rect);
- *data_size = 1;
+ for (i = 0; i < ctx->nb_pages - 1; i++)
+ ctx->pages[i] = ctx->pages[i + 1];
+ ctx->nb_pages--;
+
+ if (ret >= 0)
+ *data_size = 1;
} else
*data_size = 0;
- return pkt->size;
+ return ret;
}
static int teletext_init_decoder(AVCodecContext *avctx)
@@ -394,15 +488,7 @@
ctx->dx = NULL;
ctx->vbi = NULL;
- ctx->sub_rect = NULL;
- if (!strcmp(ctx->format, "bitmap")) {
- ctx->format_id = 0;
- } else if (!strcmp(ctx->format, "text")) {
- ctx->format_id = 1;
- } else {
- av_log(avctx, AV_LOG_ERROR, "unkown format %s\n", ctx->format);
- return AVERROR_OPTION_NOT_FOUND;
- }
+ ctx->pts = AV_NOPTS_VALUE;
#ifdef DEBUG
{
@@ -411,7 +497,7 @@
}
#endif
av_log(avctx, AV_LOG_VERBOSE, "page filter: %s\n", ctx->pgno);
- return 0;
+ return (ctx->format_id == 1) ? ff_ass_subtitle_header_default(avctx) : 0;
}
static int teletext_close_decoder(AVCodecContext *avctx)
@@ -421,11 +507,15 @@
#ifdef DEBUG
av_log(avctx, AV_LOG_DEBUG, "lines_total=%u\n", ctx->lines_processed);
#endif
+ while (ctx->nb_pages)
+ subtitle_rect_free(&ctx->pages[--ctx->nb_pages].sub_rect);
+ av_freep(&ctx->pages);
vbi_dvb_demux_delete(ctx->dx);
vbi_decoder_delete(ctx->vbi);
ctx->dx = NULL;
ctx->vbi = NULL;
+ ctx->pts = AV_NOPTS_VALUE;
return 0;
}
@@ -439,7 +529,9 @@
static const AVOption options[] = {
{"txt_page", "list of teletext page numbers to decode, * is all", OFFSET(pgno), AV_OPT_TYPE_STRING, {.str = "*"}, 0, 0, SD},
{"txt_chop_top", "discards the top teletext line", OFFSET(chop_top), AV_OPT_TYPE_INT, {.i64 = 1}, 0, 1, SD},
- {"txt_format", "format of the subtitles (bitmap or text)", OFFSET(format), AV_OPT_TYPE_STRING, {.str = "bitmap"}, 0, 0, SD},
+ {"txt_format", "format of the subtitles (bitmap or text)", OFFSET(format_id), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, SD, "txt_format"},
+ {"bitmap", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 0}, 0, 0, SD, "txt_format"},
+ {"text", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 1}, 0, 0, SD, "txt_format"},
{"txt_left", "x offset of generated bitmaps", OFFSET(x_offset), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 65535, SD},
{"txt_top", "y offset of generated bitmaps", OFFSET(y_offset), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 65535, SD},
{"txt_chop_spaces", "chops leading and trailing spaces from text", OFFSET(chop_spaces), AV_OPT_TYPE_INT, {.i64 = 1}, 0, 1, SD},
@@ -459,11 +551,12 @@
.name = "libzvbi_teletextdec",
.long_name = NULL_IF_CONFIG_SMALL("Libzvbi DVB teletext decoder"),
.type = AVMEDIA_TYPE_SUBTITLE,
- .id = CODEC_ID_DVB_TELETEXT,
+ .id = AV_CODEC_ID_DVB_TELETEXT,
.priv_data_size = sizeof(TeletextContext),
.init = teletext_init_decoder,
.close = teletext_close_decoder,
.decode = teletext_decode_frame,
+ .capabilities = CODEC_CAP_DELAY,
.flush = teletext_flush,
.priv_class= &teletext_class,
};
diff --git a/libavcodec/ljpegenc.c b/libavcodec/ljpegenc.c
index af126aa..35b82fd 100644
--- a/libavcodec/ljpegenc.c
+++ b/libavcodec/ljpegenc.c
@@ -30,207 +30,297 @@
* lossless JPEG encoder.
*/
+#include "libavutil/frame.h"
+#include "libavutil/mem.h"
+#include "libavutil/pixdesc.h"
+
#include "avcodec.h"
+#include "dsputil.h"
#include "internal.h"
#include "mpegvideo.h"
#include "mjpeg.h"
#include "mjpegenc.h"
+typedef struct LJpegEncContext {
+ DSPContext dsp;
+ ScanTable scantable;
+ uint16_t matrix[64];
-static int encode_picture_lossless(AVCodecContext *avctx, AVPacket *pkt,
- const AVFrame *pict, int *got_packet)
+ int vsample[3];
+ int hsample[3];
+
+ uint16_t huff_code_dc_luminance[12];
+ uint16_t huff_code_dc_chrominance[12];
+ uint8_t huff_size_dc_luminance[12];
+ uint8_t huff_size_dc_chrominance[12];
+
+ uint16_t (*scratch)[4];
+} LJpegEncContext;
+
+static int ljpeg_encode_bgr(AVCodecContext *avctx, PutBitContext *pb,
+ const AVFrame *frame)
{
- MpegEncContext * const s = avctx->priv_data;
- MJpegContext * const m = s->mjpeg_ctx;
- const int width= s->width;
- const int height= s->height;
- AVFrame * const p = &s->current_picture.f;
- const int predictor= avctx->prediction_method+1;
- const int mb_width = (width + s->mjpeg_hsample[0] - 1) / s->mjpeg_hsample[0];
- const int mb_height = (height + s->mjpeg_vsample[0] - 1) / s->mjpeg_vsample[0];
- int ret, max_pkt_size = FF_MIN_BUFFER_SIZE;
+ LJpegEncContext *s = avctx->priv_data;
+ const int width = frame->width;
+ const int height = frame->height;
+ const int linesize = frame->linesize[0];
+ uint16_t (*buffer)[4] = s->scratch;
+ const int predictor = avctx->prediction_method+1;
+ int left[3], top[3], topleft[3];
+ int x, y, i;
- if (avctx->pix_fmt == AV_PIX_FMT_BGRA)
+ for (i = 0; i < 3; i++)
+ buffer[0][i] = 1 << (9 - 1);
+
+ for (y = 0; y < height; y++) {
+ const int modified_predictor = y ? predictor : 1;
+ uint8_t *ptr = frame->data[0] + (linesize * y);
+
+ if (pb->buf_end - pb->buf - (put_bits_count(pb) >> 3) < width * 3 * 4) {
+ av_log(avctx, AV_LOG_ERROR, "encoded frame too large\n");
+ return -1;
+ }
+
+ for (i = 0; i < 3; i++)
+ top[i]= left[i]= topleft[i]= buffer[0][i];
+
+ for (x = 0; x < width; x++) {
+ if(avctx->pix_fmt == AV_PIX_FMT_BGR24){
+ buffer[x][1] = ptr[3 * x + 0] - ptr[3 * x + 1] + 0x100;
+ buffer[x][2] = ptr[3 * x + 2] - ptr[3 * x + 1] + 0x100;
+ buffer[x][0] = (ptr[3 * x + 0] + 2 * ptr[3 * x + 1] + ptr[3 * x + 2]) >> 2;
+ }else{
+ buffer[x][1] = ptr[4 * x + 0] - ptr[4 * x + 1] + 0x100;
+ buffer[x][2] = ptr[4 * x + 2] - ptr[4 * x + 1] + 0x100;
+ buffer[x][0] = (ptr[4 * x + 0] + 2 * ptr[4 * x + 1] + ptr[4 * x + 2]) >> 2;
+ }
+
+ for (i = 0; i < 3; i++) {
+ int pred, diff;
+
+ PREDICT(pred, topleft[i], top[i], left[i], modified_predictor);
+
+ topleft[i] = top[i];
+ top[i] = buffer[x+1][i];
+
+ left[i] = buffer[x][i];
+
+ diff = ((left[i] - pred + 0x100) & 0x1FF) - 0x100;
+
+ if (i == 0)
+ ff_mjpeg_encode_dc(pb, diff, s->huff_size_dc_luminance, s->huff_code_dc_luminance); //FIXME ugly
+ else
+ ff_mjpeg_encode_dc(pb, diff, s->huff_size_dc_chrominance, s->huff_code_dc_chrominance);
+ }
+ }
+ }
+
+ return 0;
+}
+
+static inline void ljpeg_encode_yuv_mb(LJpegEncContext *s, PutBitContext *pb,
+ const AVFrame *frame, int predictor,
+ int mb_x, int mb_y)
+{
+ int i;
+
+ if (mb_x == 0 || mb_y == 0) {
+ for (i = 0; i < 3; i++) {
+ uint8_t *ptr;
+ int x, y, h, v, linesize;
+ h = s->hsample[i];
+ v = s->vsample[i];
+ linesize = frame->linesize[i];
+
+ for (y = 0; y < v; y++) {
+ for (x = 0; x < h; x++) {
+ int pred;
+
+ ptr = frame->data[i] + (linesize * (v * mb_y + y)) + (h * mb_x + x); //FIXME optimize this crap
+ if (y == 0 && mb_y == 0) {
+ if (x == 0 && mb_x == 0)
+ pred = 128;
+ else
+ pred = ptr[-1];
+ } else {
+ if (x == 0 && mb_x == 0) {
+ pred = ptr[-linesize];
+ } else {
+ PREDICT(pred, ptr[-linesize - 1], ptr[-linesize],
+ ptr[-1], predictor);
+ }
+ }
+
+ if (i == 0)
+ ff_mjpeg_encode_dc(pb, *ptr - pred, s->huff_size_dc_luminance, s->huff_code_dc_luminance); //FIXME ugly
+ else
+ ff_mjpeg_encode_dc(pb, *ptr - pred, s->huff_size_dc_chrominance, s->huff_code_dc_chrominance);
+ }
+ }
+ }
+ } else {
+ for (i = 0; i < 3; i++) {
+ uint8_t *ptr;
+ int x, y, h, v, linesize;
+ h = s->hsample[i];
+ v = s->vsample[i];
+ linesize = frame->linesize[i];
+
+ for (y = 0; y < v; y++) {
+ for (x = 0; x < h; x++) {
+ int pred;
+
+ ptr = frame->data[i] + (linesize * (v * mb_y + y)) + (h * mb_x + x); //FIXME optimize this crap
+ PREDICT(pred, ptr[-linesize - 1], ptr[-linesize], ptr[-1], predictor);
+
+ if (i == 0)
+ ff_mjpeg_encode_dc(pb, *ptr - pred, s->huff_size_dc_luminance, s->huff_code_dc_luminance); //FIXME ugly
+ else
+ ff_mjpeg_encode_dc(pb, *ptr - pred, s->huff_size_dc_chrominance, s->huff_code_dc_chrominance);
+ }
+ }
+ }
+ }
+}
+
+static int ljpeg_encode_yuv(AVCodecContext *avctx, PutBitContext *pb,
+ const AVFrame *frame)
+{
+ const int predictor = avctx->prediction_method + 1;
+ LJpegEncContext *s = avctx->priv_data;
+ const int mb_width = (avctx->width + s->hsample[0] - 1) / s->hsample[0];
+ const int mb_height = (avctx->height + s->vsample[0] - 1) / s->vsample[0];
+ int mb_x, mb_y;
+
+ for (mb_y = 0; mb_y < mb_height; mb_y++) {
+ if (pb->buf_end - pb->buf - (put_bits_count(pb) >> 3) <
+ mb_width * 4 * 3 * s->hsample[0] * s->vsample[0]) {
+ av_log(avctx, AV_LOG_ERROR, "encoded frame too large\n");
+ return -1;
+ }
+
+ for (mb_x = 0; mb_x < mb_width; mb_x++)
+ ljpeg_encode_yuv_mb(s, pb, frame, predictor, mb_x, mb_y);
+ }
+
+ return 0;
+}
+
+static int ljpeg_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
+ const AVFrame *pict, int *got_packet)
+{
+ LJpegEncContext *s = avctx->priv_data;
+ PutBitContext pb;
+ const int width = avctx->width;
+ const int height = avctx->height;
+ const int mb_width = (width + s->hsample[0] - 1) / s->hsample[0];
+ const int mb_height = (height + s->vsample[0] - 1) / s->vsample[0];
+ int max_pkt_size = FF_MIN_BUFFER_SIZE;
+ int ret, header_bits;
+
+ if( avctx->pix_fmt == AV_PIX_FMT_BGR0
+ || avctx->pix_fmt == AV_PIX_FMT_BGRA
+ || avctx->pix_fmt == AV_PIX_FMT_BGR24)
max_pkt_size += width * height * 3 * 4;
else {
max_pkt_size += mb_width * mb_height * 3 * 4
- * s->mjpeg_hsample[0] * s->mjpeg_vsample[0];
- }
-
- if (!s->edge_emu_buffer &&
- (ret = ff_mpv_frame_size_alloc(s, pict->linesize[0])) < 0) {
- av_log(avctx, AV_LOG_ERROR, "failed to allocate context scratch buffers.\n");
- return ret;
+ * s->hsample[0] * s->vsample[0];
}
if ((ret = ff_alloc_packet2(avctx, pkt, max_pkt_size)) < 0)
return ret;
- init_put_bits(&s->pb, pkt->data, pkt->size);
+ init_put_bits(&pb, pkt->data, pkt->size);
- av_frame_unref(p);
- ret = av_frame_ref(p, pict);
+ ff_mjpeg_encode_picture_header(avctx, &pb, &s->scantable,
+ s->matrix);
+
+ header_bits = put_bits_count(&pb);
+
+ if( avctx->pix_fmt == AV_PIX_FMT_BGR0
+ || avctx->pix_fmt == AV_PIX_FMT_BGRA
+ || avctx->pix_fmt == AV_PIX_FMT_BGR24)
+ ret = ljpeg_encode_bgr(avctx, &pb, pict);
+ else
+ ret = ljpeg_encode_yuv(avctx, &pb, pict);
if (ret < 0)
return ret;
- p->pict_type= AV_PICTURE_TYPE_I;
- p->key_frame= 1;
-
- ff_mjpeg_encode_picture_header(s);
-
- s->header_bits= put_bits_count(&s->pb);
-
- if(avctx->pix_fmt == AV_PIX_FMT_BGR0
- || avctx->pix_fmt == AV_PIX_FMT_BGRA
- || avctx->pix_fmt == AV_PIX_FMT_BGR24){
- int x, y, i;
- const int linesize= p->linesize[0];
- uint16_t (*buffer)[4]= (void *) s->rd_scratchpad;
- int left[3], top[3], topleft[3];
-
- for(i=0; i<3; i++){
- buffer[0][i]= 1 << (9 - 1);
- }
-
- for(y = 0; y < height; y++) {
- const int modified_predictor= y ? predictor : 1;
- uint8_t *ptr = p->data[0] + (linesize * y);
-
- if(s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb)>>3) < width*3*4){
- av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n");
- return -1;
- }
-
- for(i=0; i<3; i++){
- top[i]= left[i]= topleft[i]= buffer[0][i];
- }
- for(x = 0; x < width; x++) {
- if(avctx->pix_fmt == AV_PIX_FMT_BGR24){
- buffer[x][1] = ptr[3*x+0] - ptr[3*x+1] + 0x100;
- buffer[x][2] = ptr[3*x+2] - ptr[3*x+1] + 0x100;
- buffer[x][0] = (ptr[3*x+0] + 2*ptr[3*x+1] + ptr[3*x+2])>>2;
- }else{
- buffer[x][1] = ptr[4*x+0] - ptr[4*x+1] + 0x100;
- buffer[x][2] = ptr[4*x+2] - ptr[4*x+1] + 0x100;
- buffer[x][0] = (ptr[4*x+0] + 2*ptr[4*x+1] + ptr[4*x+2])>>2;
- }
-
- for(i=0;i<3;i++) {
- int pred, diff;
-
- PREDICT(pred, topleft[i], top[i], left[i], modified_predictor);
-
- topleft[i]= top[i];
- top[i]= buffer[x+1][i];
-
- left[i]= buffer[x][i];
-
- diff= ((left[i] - pred + 0x100)&0x1FF) - 0x100;
-
- if(i==0)
- ff_mjpeg_encode_dc(s, diff, m->huff_size_dc_luminance, m->huff_code_dc_luminance); //FIXME ugly
- else
- ff_mjpeg_encode_dc(s, diff, m->huff_size_dc_chrominance, m->huff_code_dc_chrominance);
- }
- }
- }
- }else{
- int mb_x, mb_y, i;
-
- for(mb_y = 0; mb_y < mb_height; mb_y++) {
- if(s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb)>>3) < mb_width * 4 * 3 * s->mjpeg_hsample[0] * s->mjpeg_vsample[0]){
- av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n");
- return -1;
- }
- for(mb_x = 0; mb_x < mb_width; mb_x++) {
- if(mb_x==0 || mb_y==0){
- for(i=0;i<3;i++) {
- uint8_t *ptr;
- int x, y, h, v, linesize;
- h = s->mjpeg_hsample[i];
- v = s->mjpeg_vsample[i];
- linesize= p->linesize[i];
-
- for(y=0; y<v; y++){
- for(x=0; x<h; x++){
- int pred;
-
- ptr = p->data[i] + (linesize * (v * mb_y + y)) + (h * mb_x + x); //FIXME optimize this crap
- if(y==0 && mb_y==0){
- if(x==0 && mb_x==0){
- pred= 128;
- }else{
- pred= ptr[-1];
- }
- }else{
- if(x==0 && mb_x==0){
- pred= ptr[-linesize];
- }else{
- PREDICT(pred, ptr[-linesize-1], ptr[-linesize], ptr[-1], predictor);
- }
- }
-
- if(i==0)
- ff_mjpeg_encode_dc(s, *ptr - pred, m->huff_size_dc_luminance, m->huff_code_dc_luminance); //FIXME ugly
- else
- ff_mjpeg_encode_dc(s, *ptr - pred, m->huff_size_dc_chrominance, m->huff_code_dc_chrominance);
- }
- }
- }
- }else{
- for(i=0;i<3;i++) {
- uint8_t *ptr;
- int x, y, h, v, linesize;
- h = s->mjpeg_hsample[i];
- v = s->mjpeg_vsample[i];
- linesize= p->linesize[i];
-
- for(y=0; y<v; y++){
- for(x=0; x<h; x++){
- int pred;
-
- ptr = p->data[i] + (linesize * (v * mb_y + y)) + (h * mb_x + x); //FIXME optimize this crap
- PREDICT(pred, ptr[-linesize-1], ptr[-linesize], ptr[-1], predictor);
-
- if(i==0)
- ff_mjpeg_encode_dc(s, *ptr - pred, m->huff_size_dc_luminance, m->huff_code_dc_luminance); //FIXME ugly
- else
- ff_mjpeg_encode_dc(s, *ptr - pred, m->huff_size_dc_chrominance, m->huff_code_dc_chrominance);
- }
- }
- }
- }
- }
- }
- }
emms_c();
- av_assert0(s->esc_pos == s->header_bits >> 3);
- ff_mjpeg_encode_stuffing(s);
- ff_mjpeg_encode_picture_trailer(s);
- s->picture_number++;
- flush_put_bits(&s->pb);
- pkt->size = put_bits_ptr(&s->pb) - s->pb.buf;
+ ff_mjpeg_escape_FF(&pb, header_bits >> 3);
+ ff_mjpeg_encode_picture_trailer(&pb, header_bits);
+
+ flush_put_bits(&pb);
+ pkt->size = put_bits_ptr(&pb) - pb.buf;
pkt->flags |= AV_PKT_FLAG_KEY;
*got_packet = 1;
return 0;
-// return (put_bits_count(&f->pb)+7)/8;
}
+static av_cold int ljpeg_encode_close(AVCodecContext *avctx)
+{
+ LJpegEncContext *s = avctx->priv_data;
-AVCodec ff_ljpeg_encoder = { //FIXME avoid MPV_* lossless JPEG should not need them
+ av_frame_free(&avctx->coded_frame);
+ av_freep(&s->scratch);
+
+ return 0;
+}
+
+static av_cold int ljpeg_encode_init(AVCodecContext *avctx)
+{
+ LJpegEncContext *s = avctx->priv_data;
+
+ if ((avctx->pix_fmt == AV_PIX_FMT_YUV420P ||
+ avctx->pix_fmt == AV_PIX_FMT_YUV422P ||
+ avctx->pix_fmt == AV_PIX_FMT_YUV444P) &&
+ avctx->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Limited range YUV is non-standard, set strict_std_compliance to "
+ "at least unofficial to use it.\n");
+ return AVERROR(EINVAL);
+ }
+
+ avctx->coded_frame = av_frame_alloc();
+ if (!avctx->coded_frame)
+ return AVERROR(ENOMEM);
+
+ avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
+ avctx->coded_frame->key_frame = 1;
+
+ s->scratch = av_malloc_array(avctx->width + 1, sizeof(*s->scratch));
+
+ ff_dsputil_init(&s->dsp, avctx);
+ ff_init_scantable(s->dsp.idct_permutation, &s->scantable, ff_zigzag_direct);
+
+ ff_mjpeg_init_hvsample(avctx, s->hsample, s->vsample);
+
+ ff_mjpeg_build_huffman_codes(s->huff_size_dc_luminance,
+ s->huff_code_dc_luminance,
+ avpriv_mjpeg_bits_dc_luminance,
+ avpriv_mjpeg_val_dc);
+ ff_mjpeg_build_huffman_codes(s->huff_size_dc_chrominance,
+ s->huff_code_dc_chrominance,
+ avpriv_mjpeg_bits_dc_chrominance,
+ avpriv_mjpeg_val_dc);
+
+ return 0;
+}
+
+AVCodec ff_ljpeg_encoder = {
.name = "ljpeg",
.long_name = NULL_IF_CONFIG_SMALL("Lossless JPEG"),
.type = AVMEDIA_TYPE_VIDEO,
.id = AV_CODEC_ID_LJPEG,
- .priv_data_size = sizeof(MpegEncContext),
- .init = ff_MPV_encode_init,
- .encode2 = encode_picture_lossless,
- .close = ff_MPV_encode_end,
+ .priv_data_size = sizeof(LJpegEncContext),
+ .init = ljpeg_encode_init,
+ .encode2 = ljpeg_encode_frame,
+ .close = ljpeg_encode_close,
.pix_fmts = (const enum AVPixelFormat[]){
- AV_PIX_FMT_BGR24, AV_PIX_FMT_BGRA, AV_PIX_FMT_BGR0,
+ AV_PIX_FMT_BGR24 , AV_PIX_FMT_BGRA , AV_PIX_FMT_BGR0,
AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUVJ422P,
- AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUV422P,
+ AV_PIX_FMT_YUV420P , AV_PIX_FMT_YUV444P , AV_PIX_FMT_YUV422P,
AV_PIX_FMT_NONE},
};
diff --git a/libavcodec/lpc.c b/libavcodec/lpc.c
index 1d52edf..a6f2377 100644
--- a/libavcodec/lpc.c
+++ b/libavcodec/lpc.c
@@ -20,7 +20,7 @@
*/
#include "libavutil/common.h"
-#include "libavutil/lls.h"
+#include "libavutil/lls2.h"
#define LPC_USE_DOUBLE
#include "lpc.h"
@@ -208,7 +208,7 @@
}
if (lpc_type == FF_LPC_TYPE_CHOLESKY) {
- LLSModel m[2];
+ LLSModel2 m[2];
LOCAL_ALIGNED(32, double, var, [FFALIGN(MAX_LPC_ORDER+1,4)]);
double av_uninit(weight);
memset(var, 0, FFALIGN(MAX_LPC_ORDER+1,4)*sizeof(*var));
@@ -217,7 +217,7 @@
m[0].coeff[max_order-1][j] = -lpc[max_order-1][j];
for(; pass<lpc_passes; pass++){
- avpriv_init_lls(&m[pass&1], max_order);
+ avpriv_init_lls2(&m[pass&1], max_order);
weight=0;
for(i=max_order; i<blocksize; i++){
@@ -238,7 +238,7 @@
m[pass&1].update_lls(&m[pass&1], var);
}
- avpriv_solve_lls(&m[pass&1], 0.001, 0);
+ avpriv_solve_lls2(&m[pass&1], 0.001, 0);
}
for(i=0; i<max_order; i++){
diff --git a/libavcodec/mdct_fixed.c b/libavcodec/mdct_fixed.c
index 33a266d..2ee29b6 100644
--- a/libavcodec/mdct_fixed.c
+++ b/libavcodec/mdct_fixed.c
@@ -18,7 +18,7 @@
#define CONFIG_FFT_FLOAT 0
#define CONFIG_FFT_FIXED_32 0
-#include "mdct.c"
+#include "mdct_template.c"
/* same as ff_mdct_calcw_c with double-width unscaled output */
void ff_mdct_calcw_c(FFTContext *s, FFTDouble *out, const FFTSample *input)
diff --git a/libavcodec/mdct_fixed_32.c b/libavcodec/mdct_fixed_32.c
index 66226f3..f1d6a2d 100644
--- a/libavcodec/mdct_fixed_32.c
+++ b/libavcodec/mdct_fixed_32.c
@@ -49,4 +49,4 @@
#define CONFIG_FFT_FLOAT 0
#define CONFIG_FFT_FIXED_32 1
-#include "mdct.c"
+#include "mdct_template.c"
diff --git a/libavcodec/mdct_float.c b/libavcodec/mdct_float.c
index fec18ba..75b5f0d 100644
--- a/libavcodec/mdct_float.c
+++ b/libavcodec/mdct_float.c
@@ -18,4 +18,4 @@
#define CONFIG_FFT_FLOAT 1
#define CONFIG_FFT_FIXED_32 0
-#include "mdct.c"
+#include "mdct_template.c"
diff --git a/libavcodec/mdct.c b/libavcodec/mdct_template.c
similarity index 100%
rename from libavcodec/mdct.c
rename to libavcodec/mdct_template.c
diff --git a/libavcodec/mdec.c b/libavcodec/mdec.c
index ea47822..1567e14 100644
--- a/libavcodec/mdec.c
+++ b/libavcodec/mdec.c
@@ -163,20 +163,17 @@
const uint8_t *buf = avpkt->data;
int buf_size = avpkt->size;
ThreadFrame frame = { .f = data };
- int i, ret;
+ int ret;
if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
return ret;
frame.f->pict_type = AV_PICTURE_TYPE_I;
frame.f->key_frame = 1;
- av_fast_malloc(&a->bitstream_buffer, &a->bitstream_buffer_size, buf_size + FF_INPUT_BUFFER_PADDING_SIZE);
+ av_fast_padded_malloc(&a->bitstream_buffer, &a->bitstream_buffer_size, buf_size);
if (!a->bitstream_buffer)
return AVERROR(ENOMEM);
- for (i = 0; i < buf_size; i += 2) {
- a->bitstream_buffer[i] = buf[i + 1];
- a->bitstream_buffer[i + 1] = buf[i];
- }
+ a->dsp.bswap16_buf((uint16_t *)a->bitstream_buffer, (uint16_t *)buf, (buf_size + 1) / 2);
if ((ret = init_get_bits8(&a->gb, a->bitstream_buffer, buf_size)) < 0)
return ret;
diff --git a/libavcodec/metasound.c b/libavcodec/metasound.c
index 9cda336..677e959 100644
--- a/libavcodec/metasound.c
+++ b/libavcodec/metasound.c
@@ -163,7 +163,7 @@
static int metasound_read_bitstream(AVCodecContext *avctx, TwinVQContext *tctx,
const uint8_t *buf, int buf_size)
{
- TwinVQFrameData *bits = &tctx->bits;
+ TwinVQFrameData *bits;
const TwinVQModeTab *mtab = tctx->mtab;
int channels = tctx->avctx->channels;
int sub;
@@ -172,61 +172,70 @@
init_get_bits(&gb, buf, buf_size * 8);
- bits->window_type = get_bits(&gb, TWINVQ_WINDOW_TYPE_BITS);
+ for (tctx->cur_frame = 0; tctx->cur_frame < tctx->frames_per_packet;
+ tctx->cur_frame++) {
+ bits = tctx->bits + tctx->cur_frame;
- if (bits->window_type > 8) {
- av_log(avctx, AV_LOG_ERROR, "Invalid window type, broken sample?\n");
- return AVERROR_INVALIDDATA;
- }
+ bits->window_type = get_bits(&gb, TWINVQ_WINDOW_TYPE_BITS);
- bits->ftype = ff_twinvq_wtype_to_ftype_table[tctx->bits.window_type];
+ if (bits->window_type > 8) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid window type, broken sample?\n");
+ return AVERROR_INVALIDDATA;
+ }
- sub = mtab->fmode[bits->ftype].sub;
+ bits->ftype = ff_twinvq_wtype_to_ftype_table[tctx->bits[tctx->cur_frame].window_type];
- if (bits->ftype != TWINVQ_FT_SHORT)
- get_bits(&gb, 2);
+ sub = mtab->fmode[bits->ftype].sub;
- read_cb_data(tctx, &gb, bits->main_coeffs, bits->ftype);
+ if (bits->ftype != TWINVQ_FT_SHORT && !tctx->is_6kbps)
+ get_bits(&gb, 2);
- for (i = 0; i < channels; i++)
- for (j = 0; j < sub; j++)
- for (k = 0; k < mtab->fmode[bits->ftype].bark_n_coef; k++)
- bits->bark1[i][j][k] =
- get_bits(&gb, mtab->fmode[bits->ftype].bark_n_bit);
+ read_cb_data(tctx, &gb, bits->main_coeffs, bits->ftype);
- for (i = 0; i < channels; i++)
- for (j = 0; j < sub; j++)
- bits->bark_use_hist[i][j] = get_bits1(&gb);
-
- if (bits->ftype == TWINVQ_FT_LONG) {
for (i = 0; i < channels; i++)
- bits->gain_bits[i] = get_bits(&gb, TWINVQ_GAIN_BITS);
- } else {
- for (i = 0; i < channels; i++) {
- bits->gain_bits[i] = get_bits(&gb, TWINVQ_GAIN_BITS);
for (j = 0; j < sub; j++)
- bits->sub_gain_bits[i * sub + j] =
- get_bits(&gb, TWINVQ_SUB_GAIN_BITS);
+ for (k = 0; k < mtab->fmode[bits->ftype].bark_n_coef; k++)
+ bits->bark1[i][j][k] =
+ get_bits(&gb, mtab->fmode[bits->ftype].bark_n_bit);
+
+ for (i = 0; i < channels; i++)
+ for (j = 0; j < sub; j++)
+ bits->bark_use_hist[i][j] = get_bits1(&gb);
+
+ if (bits->ftype == TWINVQ_FT_LONG) {
+ for (i = 0; i < channels; i++)
+ bits->gain_bits[i] = get_bits(&gb, TWINVQ_GAIN_BITS);
+ } else {
+ for (i = 0; i < channels; i++) {
+ bits->gain_bits[i] = get_bits(&gb, TWINVQ_GAIN_BITS);
+ for (j = 0; j < sub; j++)
+ bits->sub_gain_bits[i * sub + j] =
+ get_bits(&gb, TWINVQ_SUB_GAIN_BITS);
+ }
}
- }
- for (i = 0; i < channels; i++) {
- bits->lpc_hist_idx[i] = get_bits(&gb, mtab->lsp_bit0);
- bits->lpc_idx1[i] = get_bits(&gb, mtab->lsp_bit1);
-
- for (j = 0; j < mtab->lsp_split; j++)
- bits->lpc_idx2[i][j] = get_bits(&gb, mtab->lsp_bit2);
- }
-
- if (bits->ftype == TWINVQ_FT_LONG) {
- read_cb_data(tctx, &gb, bits->ppc_coeffs, 3);
for (i = 0; i < channels; i++) {
- bits->p_coef[i] = get_bits(&gb, mtab->ppc_period_bit);
- bits->g_coef[i] = get_bits(&gb, mtab->pgain_bit);
+ bits->lpc_hist_idx[i] = get_bits(&gb, mtab->lsp_bit0);
+ bits->lpc_idx1[i] = get_bits(&gb, mtab->lsp_bit1);
+
+ for (j = 0; j < mtab->lsp_split; j++)
+ bits->lpc_idx2[i][j] = get_bits(&gb, mtab->lsp_bit2);
}
+
+ if (bits->ftype == TWINVQ_FT_LONG) {
+ read_cb_data(tctx, &gb, bits->ppc_coeffs, 3);
+ for (i = 0; i < channels; i++) {
+ bits->p_coef[i] = get_bits(&gb, mtab->ppc_period_bit);
+ bits->g_coef[i] = get_bits(&gb, mtab->pgain_bit);
+ }
+ }
+
+ // subframes are aligned to nibbles
+ if (get_bits_count(&gb) & 3)
+ skip_bits(&gb, 4 - (get_bits_count(&gb) & 3));
}
- return 0;
+ return (get_bits_count(&gb) + 7) / 8;
}
typedef struct MetasoundProps {
@@ -298,32 +307,68 @@
ibps = avctx->bit_rate / (1000 * avctx->channels);
switch ((avctx->channels << 16) + (isampf << 8) + ibps) {
+ case (1 << 16) + ( 8 << 8) + 6:
+ tctx->mtab = &ff_metasound_mode0806;
+ break;
+ case (2 << 16) + ( 8 << 8) + 6:
+ tctx->mtab = &ff_metasound_mode0806s;
+ break;
case (1 << 16) + ( 8 << 8) + 8:
tctx->mtab = &ff_metasound_mode0808;
break;
+ case (2 << 16) + ( 8 << 8) + 8:
+ tctx->mtab = &ff_metasound_mode0808s;
+ break;
+ case (1 << 16) + (11 << 8) + 10:
+ tctx->mtab = &ff_metasound_mode1110;
+ break;
+ case (2 << 16) + (11 << 8) + 10:
+ tctx->mtab = &ff_metasound_mode1110s;
+ break;
case (1 << 16) + (16 << 8) + 16:
tctx->mtab = &ff_metasound_mode1616;
break;
+ case (2 << 16) + (16 << 8) + 16:
+ tctx->mtab = &ff_metasound_mode1616s;
+ break;
+ case (1 << 16) + (22 << 8) + 24:
+ tctx->mtab = &ff_metasound_mode2224;
+ break;
+ case (2 << 16) + (22 << 8) + 24:
+ tctx->mtab = &ff_metasound_mode2224s;
+ break;
case (1 << 16) + (44 << 8) + 32:
tctx->mtab = &ff_metasound_mode4432;
break;
+ case (2 << 16) + (44 << 8) + 32:
+ tctx->mtab = &ff_metasound_mode4432s;
+ break;
+ case (1 << 16) + (44 << 8) + 40:
+ tctx->mtab = &ff_metasound_mode4440;
+ break;
+ case (2 << 16) + (44 << 8) + 40:
+ tctx->mtab = &ff_metasound_mode4440s;
+ break;
+ case (1 << 16) + (44 << 8) + 48:
+ tctx->mtab = &ff_metasound_mode4448;
+ break;
case (2 << 16) + (44 << 8) + 48:
tctx->mtab = &ff_metasound_mode4448s;
break;
default:
av_log(avctx, AV_LOG_ERROR,
"This version does not support %d kHz - %d kbit/s/ch mode.\n",
- isampf, isampf);
+ isampf, ibps);
return AVERROR(ENOSYS);
}
- avctx->block_align = (avctx->bit_rate * tctx->mtab->size
- / avctx->sample_rate + 7) / 8;
-
tctx->codec = TWINVQ_CODEC_METASOUND;
tctx->read_bitstream = metasound_read_bitstream;
tctx->dec_bark_env = dec_bark_env;
tctx->decode_ppc = decode_ppc;
+ tctx->frame_size = avctx->bit_rate * tctx->mtab->size
+ / avctx->sample_rate;
+ tctx->is_6kbps = ibps == 6;
return ff_twinvq_decode_init(avctx);
}
diff --git a/libavcodec/metasound_data.c b/libavcodec/metasound_data.c
index 3465499..ed23cdf 100644
--- a/libavcodec/metasound_data.c
+++ b/libavcodec/metasound_data.c
@@ -21,6 +21,1192 @@
#include "metasound_data.h"
+static const int16_t cb0806sl0[] = {
+ -417, -225, -84, 16, -106, -34, -246, -164,
+ 112, 48, -47, 36, -65, -68, -172, -1655,
+ -36, 140, -3, -2, -2, 2, 0, 0,
+ 178, 7, -181, -177, 120, -64, -129, 80,
+ -6826, -38, -25, 147, 148, -13, -25, 110,
+ 21, 21, -1, 0, 0, 0, 0, 0,
+ 3319, 632, -734, -187, 40, -249, -155, -1,
+ -173, 95, 28, -2, 20, -44, 35, 120,
+ -47, -221, -5, 2, -7, 1, 0, 0,
+ 63, 268, -260, -419, 187, -75, -228, 296,
+ -470, 177, -515, 318, 124, 308, 92, 371,
+ 3046, 362, -1, -1, -10, 1, 0, 0,
+ -356, -16, -199, 117, -75, 46, -108, -14,
+ -124, -173, 4914, -75, -474, 105, 87, 190,
+ -183, -208, 0, 0, 1, 1, 0, -1,
+ 162, 89, 49, -314, -2788, 265, -263, -3,
+ -3156, 316, 112, 128, -333, -138, -114, -141,
+ -287, -234, -1, 0, 0, 0, 0, 1,
+ 733, 126, -424, -389, 642, 432, 134, -251,
+ 407, -51, -151, -491, -308, 91, 50, 3836,
+ 87, 100, -5, -6, 0, 1, 0, 0,
+ 304, 1727, 83, -8, 216, -81, -189, 152,
+ -67, 15, 310, -93, 6, -37, 54, -110,
+ -15, 78, 0, 0, 1, 12, 0, -1,
+ 129, -198, 1, -48, -66, -147, 30, 264,
+ -84, 102, 42, 126, 1, -6451, 225, -51,
+ 8, 123, 0, -1, 0, -1, 0, 0,
+ -374, 66, -256, -80, -1139, 303, 2002, -199,
+ -98, -98, -39, -76, 180, 15, -456, 148,
+ -183, 118, -2, 1, 0, 0, 0, 0,
+ 151, 13, -114, 65, 6156, 76, -82, -30,
+ -26, 163, 81, 167, -83, -101, 55, -40,
+ 161, -793, -8, 0, 0, -1, -1, 0,
+ -102, -33, 55, -131, 434, 108, 70, 68,
+ 62, 1913, -109, 235, 110, 124, -25, -58,
+ -76, 18, -1, -1, 0, 0, 0, 0,
+ -105, -7322, -9, 82, 53, -43, -5, 18,
+ 90, 91, 20, -34, 26, -93, -50, -46,
+ -77, 105, 0, 6, -12, -6, 1, 0,
+ -1334, 980, -163, -351, -514, 537, 62, -300,
+ 80, -318, 14, -3570, -52, -116, -280, 540,
+ 250, -775, -7, 0, 0, 0, 0, 0,
+ 507, 317, -417, -236, -2438, -72, -346, 2507,
+ 302, -185, 30, 1539, 205, 87, -112, -482,
+ -296, 132, -1, 0, -1, 1, 0, 0,
+ -64, -208, -159, 1, 336, -62, -14, 13,
+ 81, 101, 382, 32, 116, -5, -41, 25,
+ -175, -7829, 1, 0, 1, 0, 0, 0,
+ 7551, -7, 86, -165, -57, -17, 183, -207,
+ 69, 54, -99, -25, 167, -58, 107, -81,
+ 165, 172, 2, -2, 0, 1, 0, -9,
+ 26, 28, 86, -183, -320, -32, 116, -53,
+ -49, -15, 133, -283, -152, 576, 6630, 185,
+ 44, 25, 20, 1, -12, 1, -1, 0,
+ -145, -51, -114, -29, -228, 78, -409, 235,
+ 147, 45, -192, 177, -91, 68, -2572, -52,
+ 81, 181, -5, 13, -1, -1, -17, 0,
+ -65, -23, -28, 9, 242, 14, -35, 88,
+ 77, -20, 37, -7097, -58, 51, 137, 126,
+ -90, 136, 0, 4, -1, 0, 0, 0,
+ -266, -82, -205, 816, -309, 3267, 1053, 369,
+ -216, -302, 18, 168, 395, 273, 343, 243,
+ -98, -53, 1, 0, 0, 1, 0, 0,
+ -65, -76, 1850, -991, -454, -535, 2927, -145,
+ 101, 23, 20, 234, -74, 77, 114, 4,
+ -106, 527, -11, 4, 0, 1, -1, 0,
+ 573, -46, 207, 2640, -956, 47, 26, -10,
+ 317, -217, -5, -867, -3, 213, 52, 53,
+ -428, -175, 0, 0, -1, -1, 0, -1,
+ -223, -55, 135, 184, 313, 0, 2868, 245,
+ -3187, -721, -291, 9, -265, -120, -105, -36,
+ 454, 55, -1, 49, 0, 1, -1, 0,
+ -291, 41, 84, 557, -201, -2300, 429, 283,
+ 21, -2, 132, 286, -124, 149, -14, 146,
+ 320, -298, 0, -1, 1, -2, 0, 0,
+ -86, -3493, 131, -3581, 185, 26, -197, -65,
+ -96, 147, -53, -150, -35, -35, 179, 68,
+ -157, 0, 0, 2, 0, 1, 2, -1,
+ -22, -218, 13, -1447, -400, 288, -1295, 0,
+ -119, 69, -56, -139, 157, -26, -122, -61,
+ -38, -108, -1, 1, 0, 0, 0, 0,
+ -229, 3335, 103, -108, 10, 3008, -712, 50,
+ 27, 152, -307, -106, 148, -77, -178, -46,
+ 7, -114, 0, -9, 0, 0, 1, 0,
+ 932, -443, 311, -75, 62, -80, -179, 459,
+ -232, -160, 2, 169, 134, -260, 41, -149,
+ 23, 92, -2, 0, 11, 1, 0, 0,
+ 16, -90, -574, -171, 163, 261, -299, 2994,
+ 74, -3818, -396, -171, 13, -29, -45, -168,
+ -287, -390, 1, 0, 0, -4, 0, -1,
+ 89, -702, 2223, 101, -249, 2983, 36, -333,
+ -382, 410, -262, 185, -146, 98, -8, -317,
+ -279, -879, 0, 0, 0, 0, 4, 0,
+ -98, -325, 75, -229, -13, 112, -5743, -34,
+ -89, 263, -155, 80, 140, -50, 33, 143,
+ -60, -77, 1, -2, 0, -1, 1, 0,
+ 52, -576, -543, -1142, -947, -184, 449, -71,
+ -75, -156, -3412, -50, -487, 307, 663, -1000,
+ -415, -2348, -7, -1, -1, 0, 0, 0,
+ 64, 3, -35, 11, 14, -198, -2, -8042,
+ 140, -11, -93, 29, -65, 330, 34, 110,
+ -19, -137, 2, 0, 0, 0, 0, 0,
+ 1236, 303, 2681, 234, -217, -406, -395, -380,
+ 247, 349, -101, -33, 370, -39, 139, 59,
+ 18, 24, 0, 0, 0, 0, 0, 0,
+ 166, -21, -5392, -117, -296, 114, 230, -255,
+ 131, -53, 13, -45, 200, 7, -56, 87,
+ 46, 223, -59, 0, -1, 0, 0, -1,
+ 214, -511, 175, 204, -123, -47, -440, 6,
+ 23, 92, -355, 80, -4885, -238, -37, 78,
+ -218, 175, 0, 2, 0, 0, 0, 0,
+ -146, 74, -13, -4, 27, -45, 51, 81,
+ -80, 53, -18, 173, -146, -64, -8, 8192,
+ 79, 15, 0, -3, 0, 1, 0, 0,
+ -3, -16, -28, 288, -61, 4, -187, 6,
+ -5, -14, 77, -12, -53, 16, -41, -7,
+ -10, -2, 7, -1, -9, 1, 0, 0,
+ -285, -35, -8, 221, -68, 114, 135, -8,
+ -203, -181, -91, 2043, -58, 127, 201, 111,
+ 46, -344, -11, -49, 0, 1, 0, -1,
+ -160, -186, 58, 4761, 289, 51, -145, 51,
+ -32, 71, 62, 175, -13, 181, 203, 141,
+ -200, 106, -1, 4, -2, 0, 0, 0,
+ 803, -76, -96, -940, 300, 3429, -84, 3037,
+ 262, -9, -39, 120, -629, -309, 233, -374,
+ 398, 894, -12, 1, 1, 1, 0, 0,
+ -282, 2525, -31, -176, -2473, 53, 102, -610,
+ 180, -145, 42, -51, 223, 27, -69, 727,
+ -14, -51, 0, 0, 0, -3, 0, -40,
+ 214, 72, 41, 1, 190, 78, -228, -235,
+ 105, -4619, -140, -46, -7, 49, 9, -19,
+ 137, -2, 9, 1, 0, 0, 0, 0,
+ -142, -262, 29, -142, 39, -39, -92, 95,
+ 50, -282, 2, -106, 114, 8, 35, 78,
+ -121, 2589, 1, -4, -10, 1, 1, 0,
+ -192, 59, 287, 400, -67, -6989, -301, 446,
+ 115, 7, 33, -60, 111, 102, 8, 206,
+ 46, -31, -1, -1, -2, 0, 0, 0,
+ -104, 332, -223, 1066, -188, 1270, -222, 309,
+ -296, 259, 780, -460, -1914, 218, -556, 210,
+ 2962, 130, 1, -2, 2, 0, 1, 0,
+ -320, -365, -266, 822, -119, 824, -312, 58,
+ -1857, 235, 48, -3985, 118, -307, -703, -931,
+ -560, 105, -2, -3, 0, 0, 0, 1,
+ 156, -48, 187, 214, -212, 180, 342, 373,
+ 1973, 128, -5, 146, -40, -11, 71, -60,
+ 76, 17, 0, 0, -1, 2, 0, 7,
+ 214, 63, 274, 2876, -65, 314, 400, 344,
+ 140, 39, 193, -226, 124, -3177, 68, 46,
+ -60, -317, 2, 0, -1, 0, 7, 0,
+ -160, 118, 233, 239, -465, 96, 253, 3178,
+ -88, 299, 368, -220, 197, 397, -353, -463,
+ -202, -103, -4, 0, 0, 0, 0, 0,
+ 687, -448, -749, 87, -35, 112, 309, -33,
+ -16, 88, 141, 63, -51, 274, -113, -76,
+ 46, -273, -1, 1, 0, 1, 0, 1,
+ -298, -206, 670, 303, -451, -277, -493, 404,
+ -173, 284, 148, 626, -322, -296, -68, 3044,
+ -442, 1138, -7, 2, 0, 1, 0, 0,
+ -1338, 18, 2862, 223, 250, 260, 144, 259,
+ -38, -647, 602, -160, 75, -5, -8, 34,
+ 237, 50, 2, 0, 1, -1, -1, 0,
+ -412, 2153, 933, 478, 768, 186, -424, -657,
+ -3458, -443, 294, 224, -468, -58, -120, -1565,
+ 211, -420, 0, 0, 1, -1, 0, 0,
+ 198, 227, -112, 350, 297, -303, 108, -192,
+ 153, 32, -2717, -111, -1093, -200, 476, 326,
+ -271, 627, 0, -4, 0, 0, 0, -1,
+ 462, -616, 126, 316, -2413, 204, -350, -3549,
+ -263, -386, -112, 483, -1339, 636, 70, -531,
+ 96, 38, 8, -1, 0, -3, 0, 0,
+ -310, -1128, 616, -339, -168, -124, -905, -151,
+ -383, 76, 137, -44, 3689, -388, 184, 1799,
+ -102, -930, 6, -1, -1, -1, 0, 0,
+ -284, 280, 39, -728, 143, 15, 181, 798,
+ 382, 10, 2267, -12, -3582, -27, 357, 514,
+ -565, -121, 0, -1, 0, -9, -1, 0,
+ 429, -16, 2993, -2903, 47, -136, 30, 792,
+ -327, -347, -69, -50, -93, -223, -438, 158,
+ 203, -475, 0, -4, -1, 2, 0, 0,
+ -3465, 415, -963, 252, 397, -945, -448, -231,
+ -130, 673, 504, 55, -355, 221, 29, 167,
+ -19, 134, -1, -1, -4, 0, -14, -2,
+ 44, 433, -535, -216, 2485, 33, 19, -100,
+ -185, -171, 91, 336, -208, 140, -3, 46,
+ -67, -116, 32, 0, 5, 3, 0, 0,
+ 220, 91, -65, -15, -169, 217, -183, -169,
+ -47, 181, -272, 138, -166, 110, -9, 41,
+ -6957, 33, -5, -2, 1, 1, 0, -1,
+ 164, -4062, -109, 230, -220, 1748, -1338, -246,
+ -242, -98, 300, 217, -202, -130, 157, -3,
+ -19, -453, 0, 2, 0, 0, 0, 0,
+};
+
+static const int16_t cb0806sl1[] = {
+ 75, 87, -31, 607, -132, 5963, -262, 494,
+ 134, -4, 141, 19, 225, 229, 239, 93,
+ -20, -189, 2, 0, -3, -1, -1, 0,
+ 214, -206, 877, 83, -588, 83, 132, 78,
+ 5, -85, 66, -24, 47, -11, 25, 26,
+ -3, 46, 2, -5, 0, 1, -1, 0,
+ -113, 295, -81, 74, 223, -50, -93, -5671,
+ -28, 115, 256, -228, -31, -539, 300, -278,
+ -59, 426, -110, -1, 1, 1, 0, 0,
+ -95, -116, 266, 176, 761, -3, 90, -91,
+ 98, -209, -414, -27, -56, 26, -76, 6,
+ -32, 4634, 1, 0, -4, 0, 0, 0,
+ 177, 147, -236, -93, -7925, 11, -111, -74,
+ 36, 176, 352, 88, 112, 16, 144, -110,
+ 91, 329, -1, 2, 0, 1, 0, 1,
+ 119, 304, -94, -422, 113, 129, -70, 155,
+ 247, -116, -139, 327, -355, 77, 143, -5362,
+ 27, -377, -1, 7, 2, 1, 0, 0,
+ 179, 127, 1500, -324, -15, 673, 184, -1382,
+ 167, 1833, -3058, 200, -1203, 459, -1905, 1020,
+ -259, -120, 10, -4, 0, 1, 0, 0,
+ 995, -112, 37, -160, -21, -4011, 172, 228,
+ -210, 80, -131, 1, 20, -128, -252, -288,
+ -132, 337, -1, 0, -1, 0, 1, -1,
+ -60, 61, 197, -185, -40, -2951, -592, -57,
+ 210, -3248, -226, -44, 391, -167, -7, 219,
+ -15, 172, 0, -1, 1, 0, 0, 0,
+ 106, -70, -291, 192, 45, 162, 37, 143,
+ 91, 21, -7032, 12, -173, -30, 1, 259,
+ -286, 387, -36, 0, 0, 0, 0, 0,
+ -1593, -210, 83, 47, 194, 61, 85, -182,
+ -23, 40, -74, 22, 12, 216, 59, -165,
+ -163, -159, -8, 0, 0, 2, 0, 0,
+ -3, 182, -80, 2068, 702, 115, -164, -85,
+ 21, -124, -191, -113, 263, 138, 4235, 37,
+ 204, -436, 0, 24, 1, -1, 0, 0,
+ 147, 83, -177, -168, -609, -9, -16, -46,
+ 127, 120, -25, 3435, 51, 31, 49, 366,
+ 31, -129, 1, -32, 0, -1, 0, -2,
+ 295, 158, 116, 11, -280, 471, 169, 29,
+ -2589, 338, 32, 299, 172, -187, -32, 437,
+ -38, 359, -1, -1, 1, 0, 0, 0,
+ 243, 413, -29, -4774, 187, 12, -117, 168,
+ -114, -208, -55, 5, 0, -31, 436, 545,
+ -45, 272, 0, -4, 0, 0, 1, 0,
+ 127, 38, 6620, -33, -103, 34, 84, -35,
+ 30, -131, -8, -79, -126, -98, 17, -75,
+ -31, -176, 14, -1, 0, 0, -1, -1,
+ 273, -219, 176, -83, 187, -36, 1, 2639,
+ 158, 3812, 127, -233, 175, 310, 148, 387,
+ -14, 308, 0, -3, 0, 0, 0, 0,
+ 3321, -447, 153, -128, 254, -275, 79, -181,
+ 17, 146, 61, 46, -48, 253, 51, -17,
+ 1, 1, 0, 1, -1, -2, 0, -13,
+ 791, -130, 40, 78, -64, -179, 42, -455,
+ 422, 112, -19, -4499, -113, -341, 52, 69,
+ 67, 254, -6, -1, 4, 0, 0, 1,
+ -98, -976, 68, 1563, 228, 1018, 458, -1020,
+ 411, 249, -627, 2321, 738, -460, -1469, 362,
+ 884, -261, 0, -1, 1, 1, 0, 0,
+ -601, 378, -71, 61, -160, 800, -386, -773,
+ 303, -53, 248, -22, 59, -3809, -61, 102,
+ -45, 395, 0, 0, 28, 0, -12, 0,
+ 717, -424, 499, 296, -15, 11, 2732, -103,
+ -119, -116, 107, -50, 462, 73, -82, 75,
+ 41, 131, 0, 3, 1, -1, 0, 0,
+ -134, 109, 48, -1847, -205, -6, 20, -203,
+ 136, 197, 113, -77, -124, -50, 184, 225,
+ -175, -295, -1, -1, -6, -1, -1, 0,
+ -59, -2017, -193, -237, 226, 630, 1950, -2,
+ 179, -3666, -34, 140, 88, 157, 51, 81,
+ -263, -169, 1, 0, 0, 0, 0, 0,
+ 229, -14, -1590, -123, 162, 63, -224, -332,
+ 119, 2931, 21, -48, 406, 15, 320, -51,
+ 64, -228, -9, -1, 0, -1, 0, 0,
+ -453, 84, -320, -654, -4, -91, -61, 558,
+ -61, -233, 31, -224, -105, 63, 86, 3771,
+ 162, -1535, 3, -3, 1, 1, 0, 1,
+ -1992, -279, -59, -3048, -1696, 102, -168, 194,
+ 172, -142, 55, 134, 116, -146, -29, -287,
+ 102, 265, -3, 1, 0, 1, 0, 0,
+ -96, 46, -16, 2474, -58, -712, -25, -294,
+ 187, 22, -39, -102, 62, 2666, -237, -1,
+ 32, -41, 0, 0, 0, 0, 0, 0,
+ -282, -25, -198, -862, -127, -379, -210, -20,
+ 45, -79, -2805, -364, 575, 106, 215, -410,
+ -76, 511, 15, -44, -1, 1, 0, 0,
+ 329, 224, 130, 43, -1, -255, -51, -297,
+ 4529, 52, 186, 757, -68, -89, 46, 250,
+ 46, -79, 5, 1, 0, 1, 0, -19,
+ 79, 74, 65, 256, 260, 492, -106, -217,
+ -357, 20, 166, 233, 132, 165, 18, -1,
+ 4445, -22, 5, 3, -7, 0, 0, -6,
+ -922, 2156, 269, 1385, 235, -206, -94, 130,
+ 112, 145, -126, 166, 1, 45, 83, 36,
+ -153, -255, 0, -1, 0, 0, 1, 0,
+ 241, -237, -117, -510, 85, 7, -4418, 30,
+ 94, -92, 99, -71, 140, -265, 149, 69,
+ 286, 104, 0, -2, 1, 0, 0, 0,
+ -165, 22, -245, 29, 50, 145, -53, 1641,
+ -40, -128, -112, -190, 47, 53, -247, -50,
+ 88, 39, 1, -1, 0, 0, 0, 0,
+ -288, 130, 88, -132, 4055, -7, 55, -105,
+ 277, 81, 69, -66, -53, 52, -56, 90,
+ 160, 386, 1, -4, 0, -2, 0, 0,
+ 107, 124, -39, 40, 25, -6, -248, -81,
+ 70, -13, 46, 5, 20, 24, -5, -2,
+ -41, -34, 1, 1, -8, 0, -4, 0,
+ -61, 1, 457, 454, 768, 89, 640, 61,
+ 66, -360, -2727, -155, -370, -44, -292, 570,
+ 34, -3209, -5, -1, 1, 0, -1, 0,
+ 22, -82, -20, -125, -91, 98, 7843, 25,
+ -2, -31, 2, -52, -73, -25, 31, -35,
+ -6, -114, 1, -1, 2, 0, 0, 0,
+ 217, -5202, 86, -76, -76, 109, 389, -95,
+ -253, 124, 130, 58, 190, -44, -67, -142,
+ 54, 6, -1, 1, 1, 1, 0, 0,
+ -183, 547, -200, 348, 372, 437, 425, 547,
+ -457, 388, 87, 38, -522, -210, -556, 41,
+ -2979, -17, 7, -4, 6, 0, 0, 0,
+ 189, 196, 240, -75, 46, -50, 101, -160,
+ -16, -223, 92, 71, -7633, 78, 90, 69,
+ 190, -75, 2, 1, -2, -1, 0, 1,
+ 205, -433, -267, -175, 3068, -210, -514, 330,
+ -3099, -273, 155, 132, -306, 361, 316, -53,
+ -421, -125, -3, 0, -11, 0, 0, 0,
+ 179, -38, 151, -36, 215, -102, -145, 139,
+ 50, 200, 383, 37, 3102, -27, 9, -157,
+ -68, 367, 1, 1, 0, 0, 1, 0,
+ -50, 177, -24, 24, 119, 4, 76, 99,
+ -111, -7367, 26, 51, -11, -146, -125, -48,
+ 54, 50, 1, 0, 0, 0, -1, 0,
+ -71, -16, -184, -61, -36, -151, 79, -128,
+ -102, 135, -228, 190, -79, -10, -176, -113,
+ 1008, -856, -13, -4, 8, 28, 0, 1,
+ -4909, -93, -167, -141, 51, -203, 71, -199,
+ -49, 106, -142, -94, 126, -225, 158, 36,
+ 269, 159, 0, 1, 1, 0, 0, -5,
+ -61, -79, -20, 306, 67, -621, 1774, 346,
+ -442, 125, 305, -170, 55, -2537, -103, 118,
+ 87, 505, 16, -7, -2, 0, 20, 0,
+ 35, -154, -158, 224, -36, -344, 79, 4232,
+ 234, -219, -71, 204, -484, -131, 1153, 23,
+ 111, 499, 5, 0, -17, 0, 0, 1,
+ 1135, -3469, -489, 2572, -450, -432, -358, -34,
+ -78, -10, -775, 17, -131, -154, 218, 82,
+ -312, 279, 1, 0, 1, 0, 0, 0,
+ 96, 230, 18, 47, -5, -102, 646, -122,
+ 35, -81, 183, 171, -1479, 201, 84, -24,
+ 143, 302, 1, 5, 0, 0, 0, 0,
+ -34, -48, 89, 7789, -85, -27, -56, 46,
+ 39, 30, 98, -40, 138, -147, 104, -35,
+ -41, -151, 1, 9, 1, 0, 0, 0,
+ -140, -1970, -170, 273, 226, 33, -324, -38,
+ 11, 188, 603, 188, -183, 98, -58, -67,
+ -63, 7, 0, 0, 0, 0, 1, 0,
+ 384, 899, 493, 765, -1062, 646, 275, -2699,
+ 93, 796, 120, -25, 177, -85, 721, -189,
+ -295, -436, 0, -1, 0, 0, -1, 0,
+ -358, 117, -2435, 325, -3137, -158, 23, 97,
+ 6, 204, 288, -426, 156, 22, -101, 171,
+ -56, 235, 0, -1, 0, -1, 0, 0,
+ 656, 3878, -286, -383, 75, -50, 114, -377,
+ -105, 106, 154, -30, -204, -105, 171, -56,
+ 230, -587, 0, 1, 0, 8, 1, -1,
+ -58, 177, -7, 45, -159, 405, 45, 84,
+ -206, 77, 277, -259, 121, 3719, 140, 79,
+ -202, 843, -8, 0, -1, 1, -2, 0,
+ -248, 560, 2651, -49, -625, -147, -2416, 119,
+ -70, 87, 137, 18, -401, -147, -598, -150,
+ 239, -1004, 7, 3, 13, 1, 1, 1,
+ 276, 342, 97, 600, 230, 95, 213, 159,
+ -259, -25, -176, 3360, -283, -325, -37, -2626,
+ -151, 178, -1, -18, 0, 0, 0, 0,
+ -233, 237, -78, 290, -284, 141, -20, 146,
+ 58, -21, 73, -35, -101, -23, -4068, -116,
+ 49, -196, -5, -2, 0, 1, -1, 0,
+ -292, -195, 51, -714, 172, 44, -119, 134,
+ 168, 107, -74, -2379, 308, 173, -252, -3470,
+ -135, 641, -10, 0, 0, 1, 0, 0,
+ 146, 2060, -84, -164, -247, 26, -1724, 216,
+ 226, -2499, 312, -66, 850, 41, -1, 20,
+ -1339, 411, 0, 0, -1, -12, 0, 0,
+ 921, 17, -3510, -119, 325, 34, -97, -205,
+ 3, -188, 252, 91, 0, -135, -76, 208,
+ 199, -202, -1, 1, 1, 2, 0, -1,
+ -88, -461, 319, -963, 266, 1540, 643, -3424,
+ 76, -1058, 501, 342, 297, 268, -158, -103,
+ 26, -30, 0, -1, -1, 0, 0, 0,
+ 211, 245, 183, 1579, 106, 26, -3450, -22,
+ -1053, -266, -736, 113, 475, -241, 117, -85,
+ -492, 372, 0, 1, 1, 0, 0, 0,
+};
+
+static const int16_t cb0806ss0[] = {
+ -381, -1638, -8192, 5, 983, -1481, -20, -719,
+ -238, 767, 571, -200, 754, 460, 1678, 1376,
+ -155, -1998, 294, -455, 80, 2, 26, 3,
+ 10, 25, -931, -1098, -1166, -3221, -1995, 702,
+ 104, -2429, -2270, 1372, 2326, -37, -1492, 1692,
+ 644, -1283, 363, 624, -483, -15, 346, -6,
+ 2, 0, 1, 3, 2, -2429, -8192, -956,
+ 1190, 706, -955, 367, 959, -194, -723, -1104,
+ 375, 554, -962, -229, 66, 368, 18, -150,
+ 56, 968, -15, 0, -1, -5, 0, 9,
+ -250, -720, 1910, 827, 198, -645, 2021, 32,
+ -1972, -705, 441, 373, 800, -2293, 1747, 1504,
+ -537, -1731, -1192, 1597, -4031, 24, 0, -2,
+ 1, 1, 1, -131, 1594, -153, 1127, 2732,
+ 469, -558, -11, 1190, 115, -933, 1988, 1841,
+ -4530, 1385, 571, 2399, 1709, -63, -3663, -2681,
+ 57, -4, 11, -4, 0, -3, 426, -4257,
+ 2755, -76, -1667, 2450, -373, 3375, -91, -232,
+ 511, 648, 886, 1182, 1667, 65, -3029, -579,
+ 865, 2186, 2911, 537, 0, 2, -3, 0,
+ 7, 585, 8192, -2855, 8192, 5527, -5491, -1926,
+ -4231, -1204, 1953, -1193, 191, 3278, -1726, 259,
+ -2794, 4205, 4315, -6121, -606, -1922, 3666, -324,
+ -238, -313, -720, -1447, -539, -794, 3151, -1726,
+ 3444, 876, 584, -671, -497, 407, 909, -2183,
+ 2575, 246, -673, 270, 824, 1784, -201, 7329,
+ 589, -70, -1, 4, -5, -3, -8, -417,
+ 382, 2786, -972, 520, 1154, 886, 521, 6032,
+ -687, 3791, -522, -1226, 608, 428, 891, -1524,
+ -1015, 1147, 1278, 559, -6, 3, 0, 6,
+ 2, -3, 115, 3586, -2847, 95, 460, 2832,
+ 2326, -1665, 1720, 453, 965, 1154, 452, -1721,
+ -1375, -269, 2138, -2032, 55, -674, -870, -124,
+ 0, 5, 0, -5, -3, -283, 1077, 2604,
+ 1270, -1082, -1753, 6840, -2502, 988, -1790, 1378,
+ 1231, 438, -1188, 286, 540, -138, 1054, -111,
+ -2321, 74, 56, -3, -2, 0, -32, 5,
+ 1539, -1399, 7413, -903, -1698, 1781, -255, -466,
+ -1436, 3419, 1916, 852, 590, -1126, -1617, -1309,
+ -5560, -241, 3363, -1225, 2682, 620, -6, 58,
+ 2, -186, -17, -2959, 619, 2228, -2627, -3119,
+ 730, 3716, -538, -101, -1863, -516, 142, -2384,
+ -1514, -5506, -825, 514, 714, 746, -2790, 569,
+ -425, 4, -68, 70, 24, 12, 817, -276,
+ -3363, -2942, 103, -581, -925, 651, 561, 43,
+ 434, 712, -541, -2042, -1291, -453, -443, -4312,
+ -1344, 1277, 605, -4, 0, -1, -1, 1,
+ 2, -930, 276, 3219, -404, -944, -497, 840,
+ 278, -98, -1432, -1136, -1975, -1863, -1102, -1446,
+ 938, 693, -5186, -1, 1085, -2275, 1, 1,
+ -1, -1, -2, 3, -1194, -312, -1257, 1973,
+ 1570, -1703, -1637, 639, -855, 1925, 970, 604,
+ 1313, 780, -5170, -603, 220, -731, 2952, -872,
+ 166, 30, 0, -2, -1, 3, -1, -743,
+ 504, 1363, 1436, 1632, -634, -709, -2346, 87,
+ 1149, 3468, 2132, 3028, -1039, -92, 2087, -990,
+ -301, 966, -773, -1057, 42, 0, -2, 0,
+ 2, 2, 252, 217, 3625, -2323, 212, -381,
+ -1121, 1664, -307, 1680, 2193, -1854, -187, -3100,
+ 254, -673, 595, 1995, 669, -687, -509, 13,
+ 0, 8, -3, 11, -3, -552, -87, 6,
+ 2933, -267, -1392, 40, 644, 32, 2966, -1386,
+ -2480, -956, 1160, 1399, 1049, 3902, -2092, -525,
+ 1724, 69, -33, 0, -2, 0, 2, 2,
+ -452, -4739, -3237, -510, -598, -1397, 855, 1573,
+ 2143, -79, -1546, -17, -973, -2400, 1689, 133,
+ -1213, 784, 726, 916, -388, -390, 1, -1,
+ -3, -1, 0, 170, -205, -2905, 8192, -465,
+ 3119, 4407, -709, -403, 859, -373, -1301, -1397,
+ -750, -88, 277, -2097, -222, -134, -88, -1189,
+ 974, -56, -57, -83, -21, 102, 626, -114,
+ -2304, 979, -1836, -868, 1261, 2226, -261, 579,
+ 983, 655, -2578, 1803, 117, -1128, 365, 3971,
+ 3539, -21, -790, -62, 2, 3, 23, -3,
+ 31, 1273, 3212, -1617, 4116, -281, 725, -284,
+ 1079, 293, -3759, 2581, -1617, -259, -19, -1999,
+ 3040, -3077, -1522, 1056, -92, 897, 243, -1,
+ 36, -19, -10, -46, 231, 1129, 363, -1978,
+ -882, -1788, 319, 4807, -1707, -1379, -1465, 2327,
+ -827, -681, 410, -1816, -2507, 1036, 740, 730,
+ -687, 100, -1, -1, -1, 1, -4, -276,
+ 303, -2331, -2912, -1864, -3694, 412, -1218, 1642,
+ 4448, 658, -213, 872, 2867, 227, 868, -590,
+ 2293, 1759, -1666, -1585, -140, 1, -3, -1,
+ 26, -10, -287, 898, -2442, 3997, -1655, -1341,
+ -56, 689, -1869, 572, -2044, 616, -2603, -278,
+ 2987, 2397, -2055, 247, 128, 598, 1732, -146,
+ 0, 3, -1, -3, 5, 842, 597, 779,
+ -1529, -802, 2142, -1668, 2339, -3550, -2651, 1733,
+ -1531, -46, 600, 618, -867, -665, 1524, 392,
+ -1386, -3279, 45, 0, 9, -7, -3, -8,
+ -224, -2632, -147, -505, 2223, 1773, 1799, -1696,
+ 194, -1186, -543, 775, -1171, 5491, -2319, -3193,
+ -313, -355, -133, -1097, 125, -22, -2, 2,
+ 1, -3, -10, -354, -1447, -662, -313, -4302,
+ 3888, -121, -323, 1112, -801, -1513, -814, -1646,
+ -616, -1207, 347, 483, 670, 900, -35, -885,
+ 14, 1, 0, 1, -2, 7, -432, -486,
+ -1539, 785, 4853, 904, 925, 895, -1223, -2464,
+ 3395, -506, -808, 207, 197, 874, -928, 1347,
+ -107, 1512, 1063, -182, 1, -4, -1, -6,
+ 3, -1236, -1047, 774, 26, -630, 863, 1055,
+ -2632, -1187, -534, -619, -1079, -2574, -2037, 658,
+ 1229, -262, 2702, -3393, -2187, 1764, 66, 0,
+ 7, 0, 7, -3, 677, -444, -2111, -5256,
+ -4485, -1667, 2077, 1613, 1483, -1520, 1600, 1767,
+ 1148, 2054, 1676, 1866, 783, -2199, 765, 568,
+ 2779, -683, 4, 17, 0, -32, 15, 45,
+ 228, -2445, 752, 2510, -1657, -1039, 113, 1107,
+ -1054, -1765, -1245, -2527, 589, 455, 328, 640,
+ -579, 2370, 1313, -540, 31, 1, -1, -4,
+ 2, -3, -235, -560, 455, 3809, 102, 403,
+ -21, 1844, 402, 148, -32, 5573, -3765, -265,
+ -718, -399, -349, 366, -1105, 91, 1881, 34,
+ 1, 1, 5, 0, 9, 289, -1146, 795,
+ -2504, 412, 1156, -302, -946, 2063, -2569, -273,
+ -1434, 141, 642, -631, 4856, -1008, 169, -40,
+ 191, -2293, -86, 6, 1, -2, 0, 1,
+ 139, 1955, -1111, -944, 140, -1074, 1071, -1312,
+ -541, 664, 1801, -892, 1605, -1750, -654, -680,
+ -8102, 120, -24, 1014, -351, -120, 0, -2,
+ 1, -1, -1, 1038, 5199, 779, -1195, 128,
+ 462, 184, 3705, -1292, -2247, -2481, 2610, 4396,
+ 4161, 4039, 1111, 838, 188, -571, 2811, -1915,
+ -1909, 13, 99, -20, -2, 11, 395, 155,
+ 2667, -202, -2639, 1303, -912, -1734, 1097, -583,
+ 3532, -218, -1514, -3881, 378, -46, -1189, -957,
+ -3010, -743, -648, 15, 1, 3, 3, 4,
+ -4, 330, 198, -275, -677, -8192, -629, 1953,
+ -783, 592, 926, 1487, -39, -1002, 1134, 1560,
+ -27, -118, -1363, -360, 2163, 442, 92, 1,
+ 1, -2, 5, 1, -670, 326, 2773, 1346,
+ -26, 327, 184, -1091, -121, 576, -1324, 212,
+ -645, 860, -2111, -493, -2119, 316, -688, 475,
+ -652, -33, 0, 1, 2, 0, -3, 92,
+ 170, 6224, 2162, 761, -1994, 2176, 1692, -1773,
+ 561, -966, 3406, -20, -593, 574, -681, 1121,
+ -335, -412, -2651, -4712, -79, 1, 2, -1,
+ 4, -6, 932, -2579, 344, -2614, 1119, 6623,
+ -314, -1068, 338, 1977, -1375, -1338, -1996, 1310,
+ 118, -500, -393, 622, -1798, -1232, 3, -75,
+ 0, 17, 0, -2, -9, 715, 8135, 400,
+ 3748, 2156, 1882, 772, 2728, -403, -775, 2110,
+ 1603, -766, -2592, 767, -618, 4727, 668, 2280,
+ -1157, 1246, -794, -14, -2, 2, 5, 16,
+ -107, 642, -1806, -158, -2447, 309, -764, 2313,
+ -101, -766, 209, -691, 2001, 268, -273, 615,
+ 803, 6062, -434, 1287, -543, -3, 0, 0,
+ 1, 1, 0, 503, -598, -2043, -1160, 1074,
+ 1255, 3269, 1405, 1182, 197, 3098, -138, 2326,
+ -244, -772, 901, -225, 337, -65, -536, -331,
+ 15, 2, 13, 8, -3, 20, -32, -52,
+ -1012, 232, 1502, -17, -1574, -741, -57, 164,
+ -22, 74, -181, 1616, 296, -1483, 1387, -357,
+ -5380, -322, -1346, 6, -3, 2, -3, 1,
+ 0, -392, -811, -650, -485, 3038, 2750, -776,
+ -503, -1664, -323, 253, -280, -3459, -1313, 541,
+ 2182, 1287, -782, 1785, -695, -49, 72, -4,
+ 0, -15, 3, -21, -211, 1382, -149, 684,
+ 2210, 2654, -1440, -1209, 152, 1080, -3078, -694,
+ 4738, 985, -1337, 819, -518, 1799, -671, 3201,
+ 2636, 7, 1, -6, 14, -31, 0, -34,
+ 4296, -23, 194, 1976, -993, 1353, 709, -342,
+ -1142, -140, -271, 2291, -709, 1734, 818, -3571,
+ 1125, 912, -590, 784, -275, -2, -1, -5,
+ -1, 0, -381, 2754, 1545, -2270, 3608, 2308,
+ -1899, 178, 391, 1826, -127, -1417, -822, -712,
+ 1682, 2225, 2247, 446, 994, 56, 734, 196,
+ 7, 3, 8, 0, 7, 639, 833, -3313,
+ 675, -263, -648, 3016, -701, 235, -1304, -582,
+ -2930, -210, -1243, 374, -3095, -2013, 354, 599,
+ -1469, 140, -17, -1, -3, 2, 0, -2,
+ -183, 399, -603, 796, -1424, 2685, -3929, 416,
+ -2291, 1737, 1906, 1667, 810, -222, 3242, -3636,
+ 5196, -1542, 940, -124, 2047, -67, -4, 6,
+ -1, 13, 2, -161, 417, 4132, 492, -1068,
+ -817, 2732, -250, -1457, 1723, 2104, 1121, -1276,
+ 1147, 990, -523, -1533, 297, 1219, 3901, -2549,
+ -22, 0, 0, 0, 0, 2, -1632, 172,
+ 829, -747, -1229, -1990, -1070, 1134, 1623, 228,
+ 3689, 625, -757, 8192, -82, 738, 213, 1900,
+ -1200, 91, 892, -45, 15, -1, 5, -4,
+ 5, 392, -3067, -1903, 139, 661, 43, 2174,
+ -1919, -270, -1490, -569, 2, 85, -1091, 6740,
+ 886, 85, -1052, -647, -563, -2971, -145, -1,
+ 39, -5, -6, -7, -1023, -1104, -1774, -3154,
+ -1058, 3488, -2551, 3547, -253, -204, -235, -1544,
+ -73, -584, -302, -3118, -2314, -308, 1790, 916,
+ 152, -155, -11, 6, -26, -1, -31, 21,
+ 919, -1856, -456, -1050, 663, 1454, -1515, -2606,
+ -4287, 1553, 3564, 1334, 1797, 1540, -392, -701,
+ -971, -3442, 281, -271, 133, 1, 5, 4,
+ 32, 3, -521, -1530, -1368, 1787, -515, -913,
+ -2391, 93, 2690, -578, -576, -1656, 554, 649,
+ -1509, -258, -605, 1233, -2258, 640, 837, -43,
+ 1, -3, 0, 5, 3, 148, -4761, 1783,
+ 3244, -277, -1139, 1539, -2016, 1898, -1276, -776,
+ -1725, -1900, -51, 559, 311, 1737, -928, 3687,
+ -1087, 1329, 134, 2, -2, -7, 9, 5,
+ -77, -1116, 4986, -940, -905, -3229, -773, 3335,
+ -23, 578, -2376, 386, 122, 1253, 363, -2748,
+ -512, -4612, 1690, 848, -1116, 195, 5, 2,
+ 11, 1, 18, 659, -1282, 562, 1170, 4701,
+ 903, 490, -3508, 3468, -39, 654, -1196, -909,
+ -268, 980, 283, 3221, 348, 1121, -897, -1011,
+ -103, -11, -2, -9, 16, -8, -274, -4100,
+ -2312, -2379, 617, 1629, 2154, 3026, -1737, -603,
+ -803, -366, 977, 1035, -1835, -255, -275, -1245,
+ 1274, -161, -4476, -181, -4, 0, -2, 1,
+ 2, 156, 551, -832, -630, 3740, -2115, 344,
+ 229, 1295, 65, 290, -1462, -1794, 3297, -1049,
+ 2451, 322, -2642, -2810, -1246, 613, 90, -1,
+ -1, 0, 0, 0, -277, 854, 1259, 1542,
+ -433, 3601, -453, 1091, -113, 1438, 994, -2746,
+ -786, 867, 1422, 1093, -1723, -1167, -1389, -1062,
+ -436, -81, 2, 1, 11, 1, 26, -197,
+};
+
+static const int16_t cb0806ss1[] = {
+ 1760, -4335, 6384, -2036, 2874, -2504, -1529, 102,
+ 6995, -1267, -3141, 1050, -59, 1556, -1002, 1536,
+ 1024, 1867, 40, -1156, -2627, -213, -1034, -660,
+ 291, -963, -323, 462, -804, 2219, -859, 1709,
+ 550, -3390, 319, 24, 644, 3154, 4503, -1961,
+ 744, 194, -151, -1255, -1318, 3033, -899, -18,
+ 1, 0, 2, 0, 28, -1213, -3725, -2525,
+ -177, -1164, 361, -357, -649, -459, 1324, 2463,
+ -3108, -3323, -575, -2744, -108, -121, -508, -564,
+ -849, -773, -288, 0, 8, 0, -2, 5,
+ 691, -602, 2269, 2373, -2027, 786, 3011, 3234,
+ -1387, -310, 659, -358, 1058, -1554, 1031, 795,
+ 2254, -549, 334, 325, 599, -36, -1, -1,
+ -2, 3, 4, -450, -533, -1657, -1928, -1034,
+ -636, -1446, -320, 2695, 1184, 697, 1126, 1159,
+ 2970, 449, -30, -2058, -1171, -684, -66, 905,
+ -43, 1, 0, 3, 0, 3, 228, 272,
+ -79, -718, 1978, 667, -2760, 1507, -1893, -796,
+ 1164, 35, -4440, -4492, -1667, 4189, 6485, -495,
+ 1721, -1639, -526, 458, 0, 385, -183, 511,
+ -153, -2025, -376, 2948, -2606, -910, -741, -427,
+ -1080, 2128, 565, -483, 1791, -2222, -45, -1204,
+ 799, 512, -4790, 1462, 511, -1906, 15, 0,
+ 0, 1, 3, 8, -867, -685, -140, 5299,
+ 376, -891, 1657, 1843, -1465, -1297, 518, -4640,
+ 303, -277, -650, -97, 2308, -679, 720, -171,
+ -475, -269, 0, -5, 4, -1, 9, -1155,
+ -4954, 1684, -2045, 939, 819, -751, -165, -93,
+ -2327, 306, 965, 4999, 557, -55, -999, 30,
+ -36, 989, -1680, -1594, 318, -3, -8, -4,
+ 1, -9, -402, 8192, 475, 2080, -418, -1739,
+ -273, -55, -441, 794, -79, 272, -2039, 789,
+ 2266, 874, 2495, 627, 2203, 1212, -1052, 389,
+ 14, -24, -59, 10, 133, -535, -1160, -1139,
+ -146, 180, 1064, 3718, -1412, 1153, 1873, -549,
+ -1698, -1479, 209, 725, -940, 2152, 1848, 678,
+ 2493, 4608, -11, 0, -1, -3, -3, 2,
+ 334, 681, 673, -8192, 3958, -3111, 1641, 1500,
+ 1184, -268, -3147, 571, 958, -663, -1031, -870,
+ -674, -1098, -529, 78, 1212, 120, -8, -13,
+ -5, -42, -37, -498, 1304, -2541, 1730, -355,
+ 1462, 2315, 2017, -403, -2010, 555, 1391, 887,
+ 2039, 366, 135, 85, 371, 1291, -225, 335,
+ -45, 0, 1, 2, -1, 2, -1095, -261,
+ 3249, 3212, -1877, 934, -1671, -1289, 1398, -2287,
+ -205, 1659, 642, 1105, 751, 2864, 1171, -1001,
+ 318, -290, 60, -54, 5, 3, 5, 2,
+ 1, -105, 590, 36, -194, 1832, -639, 777,
+ 3243, 578, 2820, 428, 2020, 623, -2104, -52,
+ -331, -1015, 3064, -347, -303, -1100, 61, -1,
+ -1, 0, 2, -1, 592, 127, 887, -1094,
+ -2819, 2573, -2670, -1693, -2775, 48, -266, -961,
+ 1220, -472, 167, 3201, 1118, -173, 1304, -26,
+ -899, 76, 0, 3, 0, 1, -1, -718,
+ -746, 947, -524, 142, 958, -1609, -777, -1362,
+ 385, -578, -6947, 157, -290, 1357, -1703, 484,
+ 117, -2224, -3736, -838, -96, -1, 11, 5,
+ 4, 2, 475, -426, 500, -767, -2304, 1248,
+ 2200, -1829, -992, -225, -573, -1107, -832, 2555,
+ -2866, 3453, 4335, -88, -1160, -1666, -94, -33,
+ 0, 0, 1, -2, -7, -147, -8192, 1204,
+ -1181, -702, -604, -770, 1032, -173, 770, 861,
+ 611, -509, 802, -467, 839, 491, -785, 523,
+ -669, 73, -34, 0, 0, -2, -3, -3,
+ 286, -2183, -1238, 1743, 387, -2228, -1404, -3439,
+ -1701, -2371, -451, 2294, 2061, 3062, -1122, -1489,
+ -1274, 51, 5649, -170, 2197, 365, -1, -13,
+ 4, 3, -5, -15, -4099, 789, 4132, 4982,
+ -1996, 784, 748, 2123, 3535, -1493, -1454, -344,
+ -867, 40, 831, -1198, 66, 542, 1633, -2402,
+ 117, -119, -18, 49, 18, 40, -500, 808,
+ -726, 1192, 3623, 1526, -484, 1080, -2502, -579,
+ 1315, -1887, 84, 1771, -2902, 1387, -1098, 1559,
+ -1126, 652, -896, 32, -1, 3, 1, 3,
+ -2, 233, 782, 8192, 566, -701, -352, 1047,
+ 581, -1070, 3159, -1157, -1585, 1599, -978, -663,
+ -931, -2581, 5074, 781, -551, -590, -247, -63,
+ -54, -50, 253, -138, -313, 387, -3004, -1136,
+ 654, -1283, 1318, 434, 80, -1486, 694, -512,
+ 393, -238, -700, -232, 706, 1478, -8192, 377,
+ 601, 18, -1, -3, 0, -6, -3, 2221,
+ 3531, -862, 1792, -242, -3686, 420, 1891, 918,
+ 1324, 234, -819, -601, 2363, -1097, 2355, 754,
+ -125, 245, -615, 3285, 204, 0, 6, -4,
+ -3, -1, -637, 673, 1233, 2886, 265, -195,
+ -226, 2521, 281, -210, 1809, -2733, -3865, -2287,
+ 641, -2604, -4235, 107, 789, 1163, -2600, -463,
+ -5, 10, 2, -10, 39, 1380, 754, -5077,
+ 4061, -1633, -1738, -1604, 1937, 1815, 1039, 3696,
+ -593, 2218, -1061, 1081, -1217, 2062, -637, -1580,
+ 149, -626, -253, -3, -17, 2, 33, 1,
+ 118, 525, 158, 1213, 910, -105, -1437, -1311,
+ 2255, -419, -2394, 1542, -3830, -1167, -998, -1099,
+ 1635, 1678, -1112, -275, 122, -50, 0, 3,
+ 0, -1, -1, 998, -4020, -1913, -1083, -159,
+ 1853, -436, -683, 298, 211, 711, 4128, -1977,
+ -958, 1048, 642, -420, 329, -1150, 459, 2161,
+ 29, -4, 0, -1, -6, 1, 1365, 1053,
+ 1032, 952, 854, 2405, 5106, 1863, 3049, 981,
+ -863, -397, 508, -1283, -631, 17, 532, -1453,
+ -1056, 66, 501, -27, -1, 3, -1, -13,
+ -2, -273, -2924, 839, -433, -395, -252, 1945,
+ 195, -307, -1297, -1474, -985, 4412, -1017, 1074,
+ 2711, 996, 919, 183, -10, -605, 38, 1,
+ -1, -1, 2, 1, 2115, -422, 3655, -1972,
+ 1473, -2033, 2461, -1112, -1267, 179, -394, -906,
+ -1273, -432, 1082, 367, -720, 1746, -657, 595,
+ 701, 16, -1, 0, 0, 2, -3, -255,
+ 443, -1840, -2379, 296, 258, -675, -221, 406,
+ -216, -6295, -1041, 1062, 199, 1705, -1032, -1627,
+ -2399, 198, -1097, -271, -99, 0, 1, -2,
+ 2, -13, 343, -219, -1447, 1779, 630, -1944,
+ -1093, -1578, -62, -1334, 2811, -815, 1311, -3102,
+ -300, 67, 24, 98, 764, -1246, 203, 6,
+ 0, -4, 0, 1, 0, -18, -1704, -1427,
+ -352, -2665, -588, 287, 715, -454, 688, -424,
+ 1736, -1124, 1028, -7581, -752, -482, -363, -75,
+ -720, -619, 449, 0, 3, 0, 16, -3,
+ -1211, 2484, 3490, -547, -705, 1776, -286, -1580,
+ 2896, -2257, -214, -1784, -1266, -562, -1170, -542,
+ 785, 1606, 535, 51, -1405, -7, -1, -1,
+ 0, -1, 2, -428, -579, -1091, -2627, 2287,
+ -757, 1445, -411, -160, 567, 108, -1305, -4356,
+ -390, -917, 345, -2169, -896, 3772, 1224, 691,
+ -25, 1, 1, 1, -2, 1, 281, 1365,
+ -1628, -585, 3485, 169, 746, -395, 1072, 1569,
+ -1073, 744, 1274, -3472, 1035, -906, -3394, -1537,
+ -869, 2841, 401, 4, -1, -3, -3, -1,
+ -3, -37, -1628, -888, 785, 3328, 1105, 3551,
+ 6946, -1688, 2690, -2051, -2212, -3750, -1903, -497,
+ 1251, 1187, -6198, 3930, 85, -1077, 16, -23,
+ -80, -130, 43, 66, -974, 579, -2047, -3607,
+ -666, -2248, 4619, 6846, 88, -649, 1129, -255,
+ 3567, -124, 41, 58, 634, -1252, 696, 2536,
+ -1590, 209, 12, -102, -275, 27, 216, 1110,
+ 259, -2091, 1775, -3768, 598, 441, -1809, -431,
+ 22, -991, -621, 84, -1803, 1585, 559, -1101,
+ 42, 456, -392, -874, -4, 0, 0, 1,
+ -1, 0, -371, -211, -339, -1232, 438, -2683,
+ -1007, 1250, 5343, 861, -1305, -577, 2107, -2649,
+ -3227, 1020, -127, 562, 5495, -3136, -414, -529,
+ 12, -53, -34, 151, 106, -2946, -575, -1796,
+ 3095, -257, -591, 126, 967, -547, -271, 560,
+ 974, -3335, -2110, -1403, 5915, -1108, 388, -1266,
+ -522, 336, 167, 1, -3, -2, 2, -3,
+ -312, 19, 3356, 1123, -676, -247, 697, 548,
+ 1768, 1174, -525, -253, -423, 546, -2373, -2940,
+ -1055, -2304, 203, 1309, -574, -8, 0, -3,
+ 4, 0, 4, -215, 8192, -670, -1289, -1547,
+ -304, 1498, -967, -529, -582, -2205, 1752, 321,
+ 573, -1096, 64, 1152, -87, 574, -250, 539,
+ 62, 7, 2, -1, -3, 3, -465, 243,
+ -1179, 828, -2501, -223, 198, -883, -740, 1113,
+ -1821, -2068, -3234, 1715, 1989, 1817, 727, 1640,
+ 3386, -1538, -864, 45, 0, -4, 0, 0,
+ 2, 608, -1495, 1259, -132, 1311, 350, 537,
+ 2735, 1428, 151, 1324, 547, -3983, -1892, 104,
+ 2023, 1908, -1042, 1130, 1252, -701, 9, 0,
+ -2, -1, 1, 1, 602, -8192, -2776, -661,
+ 1640, 443, 3452, -738, 829, 637, 292, 232,
+ 1352, 4879, 1429, 912, 649, 1593, 308, -330,
+ 68, 63, -3, 4, -57, 26, 25, 1250,
+ 400, -4839, 211, -2748, -664, 996, 341, -1053,
+ 321, 2458, 764, 743, -729, 12, -283, -346,
+ 118, -249, -153, -2329, -37, 0, -1, 0,
+ 1, 1, 352, -878, 2336, -634, -2690, -3415,
+ -2949, -531, 1259, 394, 163, -994, 845, 1259,
+ 890, 1400, 279, 1908, 161, -2174, 1876, 76,
+ 1, -1, -1, 10, 0, 47, -1123, 1611,
+ 489, 618, -816, -7, 2001, -1190, 1857, -2749,
+ -311, -331, 733, 1412, 1390, -1525, 1262, -1393,
+ -263, 3124, -98, 0, 1, 0, 1, -2,
+ 514, -3533, -2394, 3623, 249, -1056, 515, 1279,
+ 2821, 477, 183, 689, 1182, 1378, 1287, -711,
+ 1264, -713, -278, 217, -664, -225, -1, 0,
+ 6, 2, 9, -1171, 3119, 1340, -1229, -1929,
+ 1984, -1333, 1018, 10, 1205, 63, 358, -1108,
+ -455, -413, 854, -1550, -423, -180, 2529, -8192,
+ -18, 0, -2, -1, 0, 0, -678, 3819,
+ -1316, 1159, 590, -231, 2203, -1533, 986, 4289,
+ 1114, 1135, -1162, -921, -58, 691, 11, -1718,
+ -270, -531, 530, 65, 0, -1, 1, 4,
+ 0, -1184, -1359, 7230, -533, -2077, -1188, 113,
+ -1472, 490, 1518, 1476, -1885, 934, 244, 1840,
+ -696, -480, -2476, 3324, -2433, 1102, 120, 1,
+ -11, -2, 18, -3, -1016, 189, -3835, -1659,
+ -46, -180, -2659, 1998, -1437, 1107, -2248, 165,
+ -657, -5079, -224, 1246, 469, 421, 1145, 1148,
+ 84, -18, 3, 0, 0, -6, 0, -66,
+ -206, 2279, -220, 1606, -421, -1482, -413, -1237,
+ 374, 3691, 491, -774, 410, 791, 380, 3385,
+ 615, -950, -620, -197, 65, -1, 3, -3,
+ 2, -1, -484, 1396, 273, -3591, 1317, -1013,
+ 1563, -134, 602, -1069, 733, -1167, 233, 319,
+ -262, 350, 780, -407, -496, -1285, 1326, -13,
+ 0, 2, -1, 0, -1, -328, -626, -848,
+ 745, -1047, 4048, -380, -456, -1894, 869, -1085,
+ -373, 2829, 622, 473, 394, 237, -2175, 1167,
+ -4942, 246, 100, -1, 1, -6, 1, -6,
+ -70, 35, 1613, 2597, 1307, 1756, -1184, 1082,
+ 971, -2004, -1459, -494, -40, 745, 2788, -830,
+ 76, 536, -2002, 401, -57, -20, 0, 0,
+ 0, 0, 0, -8, 244, 1927, 1162, -2416,
+ -1414, 463, -89, 1217, -798, 394, -1527, -719,
+ -666, 998, 1518, -2455, -3049, -1174, -2696, -3119,
+ 2, 0, -2, 2, 2, 3, 1093, -623,
+ 1660, -1635, 1457, 2560, 763, -2750, 931, 1798,
+ 2550, 1402, 914, -919, 1931, -383, -435, -583,
+ 439, 9, -1106, -12, -1, 0, 0, 0,
+ -2, -335, -730, -2102, -1414, 2576, -3869, 1025,
+ -1657, -2, 857, -336, -3011, 205, 1108, 364,
+ -789, -179, 171, 331, 2204, 527, -13, 1,
+ -3, 2, 1, -4, -565, -211, -139, 1799,
+ 195, -877, -632, 358, -244, -1459, 1398, 2271,
+ 550, 1987, 2206, -337, 199, -7036, 589, 195,
+ -466, 72, -1, 2, 1, 0, 0, -27,
+};
+
+static const int16_t cb0806sm0[] = {
+ -8192, 389, 245, -67, -42, 79, 503, -488,
+ -310, 107, -13, -431, -203, 96, 510, 151,
+ 270, 0, 0, 0, 0, 0, -463, -23,
+ -72, -322, 74, 1589, -152, -198, 81, 1120,
+ -125, -434, -3275, -2210, -348, -344, 91, 0,
+ 0, 0, 0, 0, -254, -224, 46, -154,
+ -131, -465, -57, 8192, 345, 112, -725, -49,
+ 183, -191, 246, 263, 370, 0, 0, 0,
+ 0, 0, 39, -739, -6603, -2454, -95, 312,
+ -53, -392, 63, -165, 31, -505, 111, 484,
+ -535, 179, 143, 0, 0, 0, 0, 0,
+ 1279, -139, -1769, 244, 59, -135, -429, 707,
+ 809, -4355, -354, 428, -300, 108, -799, -1421,
+ 599, 0, 0, 0, 0, 0, 4, -5,
+ 7, 75, 49, 8192, 276, 200, 191, -167,
+ -14, 82, 222, -277, -483, -216, -441, 0,
+ 0, 0, 0, 0, 171, -423, 174, 401,
+ -517, -377, -234, -644, -829, -350, -976, -146,
+ -928, 296, 3003, 3545, -30, 0, 0, 0,
+ 0, 0, 161, -6753, 1138, -855, -132, -242,
+ 559, -225, -346, -168, 10, -481, -6, -1208,
+ 252, -323, -191, 0, 0, 0, 0, 0,
+ -262, 574, 433, -145, 622, 329, -2634, -439,
+ -1178, 351, -433, -842, 4125, 296, 305, 359,
+ -22, 0, 0, 0, 0, 0, -34, -56,
+ -1019, -247, -163, 305, 574, -51, -179, 24,
+ -1097, 248, -166, -18, 303, 252, -555, 0,
+ 0, 0, 0, 0, -400, -254, -256, 2783,
+ -296, -1904, 552, 1284, -336, -2371, 3396, -1092,
+ 102, 176, 140, 640, -359, 0, 0, 0,
+ 0, 0, 373, 473, -2167, -774, -388, 405,
+ -1402, -1391, -1319, -155, 1104, -533, 382, 1561,
+ -2958, 406, 787, 0, 0, 0, 0, 0,
+ -3800, -58, 2098, -181, -570, 385, -4125, 759,
+ -1584, 9, -278, 201, -528, -527, -435, 436,
+ 681, 0, 0, 0, 0, 0, 30, -80,
+ -60, -4031, -70, -3367, 316, -861, 67, -169,
+ -144, 1598, 966, 32, -1263, -434, -738, 0,
+ 0, 0, 0, 0, 181, 12, 115, 91,
+ 253, 518, 517, 216, 830, 336, -568, -3125,
+ -796, -847, 1627, 58, -158, 0, 0, 0,
+ 0, 0, 48, -851, -286, 393, 390, 707,
+ 595, 427, -235, -116, 814, -198, 6145, -1590,
+ 647, 15, -259, 0, 0, 0, 0, 0,
+ -621, 152, 590, -16, 215, -633, -784, -140,
+ 1087, 723, -4191, 2701, 951, -972, 273, -554,
+ 387, 0, 0, 0, 0, 0, -124, -2939,
+ -38, 383, 234, 687, -2873, -466, 61, -472,
+ 854, -396, 305, -233, 82, -2677, -206, 0,
+ 0, 0, 0, 0, -120, -246, -614, -394,
+ 8192, 75, -450, 177, -251, 45, -142, 65,
+ -1248, -14, 389, 375, 114, 0, 0, 0,
+ 0, 0, 2870, 158, -473, -166, 928, -618,
+ -1909, 224, -931, 1898, -16, 427, 447, -1044,
+ 85, -333, 197, 0, 0, 0, 0, 0,
+ 78, 114, -167, 73, -1070, -80, 3512, -3004,
+ -1553, 769, 213, 851, -377, 978, 1097, 71,
+ 66, 0, 0, 0, 0, 0, -129, 248,
+ 455, -376, 344, 128, -60, 546, -321, -7898,
+ -719, -55, -941, 1242, 207, 215, 323, 0,
+ 0, 0, 0, 0, -24, -225, 136, 142,
+ -739, -117, 2, 242, -152, -20, -1775, -484,
+ -36, -408, -2767, -471, 251, 0, 0, 0,
+ 0, 0, 22, 111, -180, -7417, 365, 293,
+ -313, 1031, -191, 154, -210, -239, 121, -333,
+ -1504, 209, 146, 0, 0, 0, 0, 0,
+ 898, -643, 3080, 528, -91, -718, -512, 275,
+ -3564, 396, 160, -850, 346, -595, 1558, 684,
+ -310, 0, 0, 0, 0, 0, 234, -419,
+ -724, -433, 292, -1003, 682, -117, -1318, -914,
+ -5137, 128, 53, 291, 408, 1269, -284, 0,
+ 0, 0, 0, 0, -252, 190, -2911, 130,
+ 255, -172, -4331, 26, -267, 280, -133, -613,
+ -1063, -1135, 759, -1290, 216, 0, 0, 0,
+ 0, 0, 133, -177, 4069, -311, -197, 3260,
+ 341, 201, -117, -515, 105, -658, 975, 81,
+ -333, -333, 262, 0, 0, 0, 0, 0,
+ 273, -87, 321, 190, 1385, 274, 182, -2553,
+ -150, 164, -830, 89, -459, -5279, -624, -336,
+ 399, 0, 0, 0, 0, 0, -172, -232,
+ 11, 45, 121, -254, -457, 196, -3487, -838,
+ 512, -310, -2831, -85, 98, -145, -331, 0,
+ 0, 0, 0, 0, -55, -149, 2068, -61,
+ 3087, -143, 1574, -1381, 2853, 1899, -453, -580,
+ -137, 1211, -1413, 171, 125, 0, 0, 0,
+ 0, 0, -228, 30, -956, 5569, 209, -89,
+ 25, 573, -1669, 507, 182, -132, 697, -132,
+ -2964, -637, 139, 0, 0, 0, 0, 0,
+ -3078, -3278, -771, 928, -38, -463, 820, 1141,
+ -1234, 620, 652, -1710, -382, -1618, -409, 179,
+ 483, 0, 0, 0, 0, 0, -102, 4256,
+ -20, -162, 2021, 730, 1439, 2776, 459, 498,
+ -152, 482, 35, -271, 810, -1345, -249, 0,
+ 0, 0, 0, 0, 131, 5, -281, 431,
+ -2498, -1046, 482, 842, 297, -311, -1260, 148,
+ -906, -4217, -1411, -102, -361, 0, 0, 0,
+ 0, 0, 116, -3083, 235, -1195, -19, -646,
+ 42, 487, 309, 1654, 1051, -1643, 689, -823,
+ 2279, 1488, 571, 0, 0, 0, 0, 0,
+ 42, -95, -3, 36, -170, -114, 8104, 217,
+ 140, -217, 599, -774, -64, -675, -211, 166,
+ 204, 0, 0, 0, 0, 0, 99, 594,
+ -48, 224, 52, -1499, 271, 2224, -219, 3184,
+ -165, 828, -1345, -785, 181, 133, 124, 0,
+ 0, 0, 0, 0, -235, -286, 254, -171,
+ -4980, -453, -1432, 12, 734, -391, -640, 339,
+ 537, 313, -700, 1016, 148, 0, 0, 0,
+ 0, 0, -49, -19, 803, 935, 520, -90,
+ 641, 1053, -454, 2338, -6071, -478, 616, -559,
+ -339, 445, -1464, 0, 0, 0, 0, 0,
+ -175, 111, -132, 65, -264, 732, 221, 231,
+ -1972, -305, 325, -859, 583, 1272, -441, 2651,
+ 229, 0, 0, 0, 0, 0, -286, -4646,
+ -262, 593, 613, 936, 310, -615, 83, 223,
+ -816, 1910, 2041, 281, -190, -434, 114, 0,
+ 0, 0, 0, 0, -123, 684, -208, 524,
+ -606, -1223, 264, -983, -109, -1057, 696, 195,
+ -521, 945, -7503, 193, -120, 0, 0, 0,
+ 0, 0, 98, -358, -2165, 244, 277, 393,
+ 771, 3360, -258, -1218, -122, -1253, -2297, 806,
+ -198, 540, 7, 0, 0, 0, 0, 0,
+ 78, -281, -368, 2809, 159, 2611, 833, -120,
+ -3987, 933, 360, -49, -515, -106, -360, 650,
+ -125, 0, 0, 0, 0, 0, 203, 1369,
+ 749, -502, -2295, -326, 448, -309, 630, -84,
+ 345, -520, -4, -623, 1066, -3915, 373, 0,
+ 0, 0, 0, 0, -4603, -794, -625, -355,
+ 1071, -601, -553, 593, -296, 626, -328, 621,
+ 85, 1348, 92, -288, 204, 0, 0, 0,
+ 0, 0, -9, 602, -162, -749, -104, 464,
+ -372, -1375, -1905, 2200, 61, -3308, -897, 634,
+ 1036, -2112, -182, 0, 0, 0, 0, 0,
+ -76, 2341, -675, -72, -29, 704, -536, 1656,
+ -541, -736, -1420, -1539, 2458, -228, 674, -1258,
+ -3, 0, 0, 0, 0, 0, -133, 1111,
+ 63, 327, 470, 1226, 541, -276, -3042, -1594,
+ -3192, 357, -617, 658, -315, -978, 631, 0,
+ 0, 0, 0, 0, 111, -188, 619, 236,
+ 104, 54, 545, 424, 5912, -332, 711, -1249,
+ -533, 291, -1544, -216, 113, 0, 0, 0,
+ 0, 0, -199, 267, 152, -301, -172, 1294,
+ 2311, -482, -2451, -82, 1833, 214, 130, -1183,
+ -2212, 403, -625, 0, 0, 0, 0, 0,
+ -106, 662, -48, -131, 324, 2337, 445, 462,
+ -349, -189, 669, 4945, -1797, 16, 268, -602,
+ 2, 0, 0, 0, 0, 0, 55, 154,
+ 892, -35, -145, 357, 562, 42, -9, -284,
+ 177, 84, 422, -181, -358, 7618, 29, 0,
+ 0, 0, 0, 0, -353, 68, -41, -4096,
+ 177, -20, -267, 782, 954, -430, 1573, -696,
+ 1785, -3611, 89, -243, 683, 0, 0, 0,
+ 0, 0, -220, 1983, -891, 614, 226, -202,
+ 67, 761, 1904, 179, 226, 416, -657, -3409,
+ 1026, 2834, -438, 0, 0, 0, 0, 0,
+ -551, -229, -304, -462, -2277, -419, 451, -122,
+ -108, 258, 784, 1105, 382, 137, 5695, -241,
+ -491, 0, 0, 0, 0, 0, 34, -272,
+ -1687, 1769, -332, 365, 33, -2594, 3729, 325,
+ 85, -295, -290, -152, 2238, -611, -41, 0,
+ 0, 0, 0, 0, 102, 166, 241, 1098,
+ -107, 775, -414, 4256, -277, 935, -200, 495,
+ 255, 1144, 468, -184, -59, 0, 0, 0,
+ 0, 0, 94, -282, -57, 12, -390, 245,
+ 1872, -620, 1089, 3754, 432, 947, -509, -284,
+ -3836, 26, 482, 0, 0, 0, 0, 0,
+ 9, 971, -373, 1111, -480, 2342, -182, 528,
+ 802, 1196, -1017, -879, 499, 2800, -830, -230,
+ -4, 0, 0, 0, 0, 0, -382, -815,
+ -1669, -2437, -593, 193, -688, 632, 479, 2883,
+ 565, 540, 5, 1598, 1618, -640, -246, 0,
+ 0, 0, 0, 0, -421, -103, 1482, -3026,
+ -65, -101, 4, 3921, 688, -941, -234, 49,
+ 202, 1905, 935, -1155, -4, 0, 0, 0,
+ 0, 0, 210, -625, -118, -3215, 344, 978,
+ -10, 773, -126, -804, -1534, 182, -1146, -646,
+ -146, 2011, 463, 0, 0, 0, 0, 0,
+};
+
+static const int16_t cb0806sm1[] = {
+ 35, -237, 547, 705, -9, 1612, 382, 195,
+ -191, -250, -101, -357, 709, 153, 850, -5091,
+ -100, 0, 0, 0, 0, 0, -6406, -158,
+ -527, 137, -330, 580, -484, 63, 541, -1245,
+ -205, 138, 247, -489, -147, -132, -863, 0,
+ 0, 0, 0, 0, 53, -38, 283, -22,
+ -1506, -467, -418, 117, 133, -2152, -48, -991,
+ 808, -1047, 2402, 261, 423, 0, 0, 0,
+ 0, 0, -14, 500, 4697, -174, -544, 87,
+ -379, -243, 577, 682, 258, -1190, -1984, 599,
+ 607, -123, -290, 0, 0, 0, 0, 0,
+ 60, 4254, 194, 888, -81, -395, 422, -1786,
+ 916, 288, 1191, -658, 502, 2177, -977, -301,
+ 587, 0, 0, 0, 0, 0, 232, 204,
+ -452, -853, -4266, -219, 1164, 92, 91, 1561,
+ 950, -705, -1217, -734, 1617, 120, -324, 0,
+ 0, 0, 0, 0, -3442, -456, -667, 987,
+ -89, 1383, -704, -187, -280, -583, 341, -732,
+ 649, -2129, -3505, -175, -215, 0, 0, 0,
+ 0, 0, 200, -635, -471, -1221, 215, 2844,
+ 1633, 522, -720, 1722, -272, 473, 198, -604,
+ 480, -88, 169, 0, 0, 0, 0, 0,
+ -160, -268, 130, 284, -612, 95, 43, 42,
+ 641, -258, -6884, -167, -689, 123, 276, -592,
+ 717, 0, 0, 0, 0, 0, 313, -90,
+ -4310, 2706, -1708, 648, -796, 791, 998, -468,
+ 632, 1893, 43, 1937, -1279, -22, -64, 0,
+ 0, 0, 0, 0, -106, 135, -287, 335,
+ -7999, 51, -250, -388, 16, 285, -101, 685,
+ -944, 604, -624, -792, 209, 0, 0, 0,
+ 0, 0, 496, -205, 422, 49, 274, -229,
+ 220, 73, -734, 381, -394, -8192, -405, 755,
+ -9, 46, 116, 0, 0, 0, 0, 0,
+ -28, 332, 1152, -129, 244, 84, -2193, 632,
+ -1854, -384, 110, -302, -270, 435, -1689, -797,
+ 686, 0, 0, 0, 0, 0, -1660, 624,
+ -664, 2611, 30, -1155, -419, -3539, -568, 1719,
+ -1374, -676, -55, -1934, 863, 1391, 433, 0,
+ 0, 0, 0, 0, -1012, 290, 2302, -330,
+ -95, -2355, -55, -763, -1995, -298, -680, 715,
+ -85, 1615, 1011, -1989, -1028, 0, 0, 0,
+ 0, 0, 21, -5001, 507, -58, 229, -37,
+ -113, 632, 1809, -62, 334, -1201, -893, -344,
+ 98, 438, -65, 0, 0, 0, 0, 0,
+ 0, 143, 131, -18, -135, -306, 392, 232,
+ 265, 543, 376, -562, 362, 2458, 785, 3653,
+ -456, 0, 0, 0, 0, 0, 855, -4009,
+ -1207, 118, -86, -223, 266, 154, -1886, -1145,
+ 241, -397, 246, 244, -776, 808, -132, 0,
+ 0, 0, 0, 0, 2, -633, 113, -94,
+ -154, -173, -162, -168, 439, -6548, 778, -392,
+ -60, 99, -1901, 171, -130, 0, 0, 0,
+ 0, 0, -11, -324, 711, -903, 560, -1654,
+ 1473, -300, 1048, 137, -1140, -1115, -1302, -1008,
+ -792, -3264, -540, 0, 0, 0, 0, 0,
+ -347, 78, -103, -7, -3, 437, 6053, 299,
+ -435, 323, 664, 477, 1097, 158, 656, 273,
+ 200, 0, 0, 0, 0, 0, -101, 80,
+ -153, 144, -235, 492, -399, -3, 4958, 699,
+ -586, -162, 153, -860, 161, 665, 4, 0,
+ 0, 0, 0, 0, -87, -189, 1744, -350,
+ -1840, 325, -2354, 1193, 1386, -1589, 80, 1055,
+ -188, 273, 807, 2038, -419, 0, 0, 0,
+ 0, 0, 50, -185, 68, -59, -9, 78,
+ -585, -121, -7888, 771, -908, -284, 349, 158,
+ -1122, -139, -189, 0, 0, 0, 0, 0,
+ 310, -286, 235, -687, -919, -364, -697, -253,
+ 492, 300, -238, 272, 518, -525, -5863, -190,
+ -59, 0, 0, 0, 0, 0, 151, 616,
+ -4420, 227, 240, -252, 516, -250, 68, 411,
+ -192, -87, -607, 671, 1281, -317, -305, 0,
+ 0, 0, 0, 0, -9, 817, -451, -1079,
+ 86, 5060, -1157, -1159, -421, 302, 1636, -316,
+ -66, -518, 1010, 1068, 96, 0, 0, 0,
+ 0, 0, -576, -362, 107, 3516, 303, -364,
+ -402, 805, 574, 993, -554, 298, -925, 410,
+ 1898, 13, 138, 0, 0, 0, 0, 0,
+ -340, -150, 528, 142, -464, 1034, -397, 3944,
+ -697, 962, 902, 1393, 2212, -1021, -1034, -961,
+ -319, 0, 0, 0, 0, 0, 58, 38,
+ 382, 221, -212, 826, -1373, -4559, 1329, -123,
+ 216, -23, -736, 95, -300, -418, -4, 0,
+ 0, 0, 0, 0, -58, 7814, 218, 141,
+ -90, -124, 455, -27, 49, -311, -364, 80,
+ -136, -1257, 96, 332, -287, 0, 0, 0,
+ 0, 0, -8, 624, 127, 1857, -480, -869,
+ -575, -1461, -493, -261, 97, 32, -328, -467,
+ 173, -2588, 132, 0, 0, 0, 0, 0,
+ 5257, -1037, 191, -844, 247, 130, -571, -548,
+ -496, 216, -161, 336, 62, 990, 130, 517,
+ -65, 0, 0, 0, 0, 0, -89, 9,
+ -138, 405, -701, -479, 3605, 699, -629, -102,
+ 27, -1374, -1059, -18, -2707, -172, -557, 0,
+ 0, 0, 0, 0, -67, 209, 571, -93,
+ -405, -172, -260, -19, 86, 22, 659, -630,
+ 222, -8192, 106, -34, 60, 0, 0, 0,
+ 0, 0, -10, -3386, 336, 651, -1377, 681,
+ -16, -45, -382, 1102, -280, 169, -822, 522,
+ 434, -1111, -299, 0, 0, 0, 0, 0,
+ 194, -445, -231, -532, -438, -180, -591, -1680,
+ 179, 5921, -184, -685, -467, 875, -573, 282,
+ 235, 0, 0, 0, 0, 0, 339, 139,
+ -745, -68, -201, 467, -743, 477, -23, -1177,
+ 1384, -357, -1254, -3760, 454, 1175, 252, 0,
+ 0, 0, 0, 0, 109, -252, 8027, -765,
+ 136, 111, -86, -593, -84, -750, -121, 782,
+ 739, -296, 284, 213, -1196, 0, 0, 0,
+ 0, 0, -40, 69, 1992, 452, -75, -84,
+ 683, 1678, -1350, -1846, 3068, -749, -1410, -271,
+ 536, 1120, 117, 0, 0, 0, 0, 0,
+ 4053, 340, 108, -88, 411, 990, 217, 3675,
+ 755, 752, -206, 205, -297, -573, 188, 127,
+ -313, 0, 0, 0, 0, 0, 47, -2870,
+ -3417, 216, 1730, -83, 189, -1615, 1016, -44,
+ -502, 2151, 6, -1057, 550, 194, -498, 0,
+ 0, 0, 0, 0, -133, 1, -387, -497,
+ 586, 173, 923, -4078, -1232, 329, -2086, -185,
+ 592, 681, 3320, -914, -327, 0, 0, 0,
+ 0, 0, -132, 493, -179, 220, 142, -4345,
+ 422, -173, 357, 1317, 240, -525, 1613, -178,
+ -1584, -734, 549, 0, 0, 0, 0, 0,
+ -337, 111, -1238, 116, 302, 325, 189, 610,
+ -3180, -284, -817, 1383, 1559, -802, 422, 438,
+ 460, 0, 0, 0, 0, 0, -96, 372,
+ 335, -843, 3967, 221, 380, 227, 309, 447,
+ -199, -257, 372, -397, -534, 736, -152, 0,
+ 0, 0, 0, 0, -144, 463, -54, -288,
+ -83, 115, -574, -229, 485, -2643, 58, 4312,
+ -1155, 642, -647, 1122, 118, 0, 0, 0,
+ 0, 0, 157, 6, -1017, -1155, 687, -288,
+ 918, -212, -332, -2486, -197, -1025, -546, 4099,
+ 155, -731, -333, 0, 0, 0, 0, 0,
+ -43, -496, -546, -541, 283, -521, -47, -18,
+ 208, -552, 1899, 2107, 588, 818, -911, -1104,
+ -84, 0, 0, 0, 0, 0, -71, 40,
+ -326, 92, 216, -106, -255, 28, 120, -58,
+ -2720, -133, -288, -28, -1157, 1563, 400, 0,
+ 0, 0, 0, 0, 40, -4, 559, 1350,
+ 30, 3905, -675, -1092, -587, -1524, -1987, -1031,
+ 1892, -679, -623, 1051, -33, 0, 0, 0,
+ 0, 0, -98, 106, 105, -5887, -463, 424,
+ -42, -506, -589, 376, 840, 140, -640, 771,
+ 23, -441, -6, 0, 0, 0, 0, 0,
+ 22, 203, -3452, -635, -605, 1668, 422, 2973,
+ 394, -1605, -968, -739, 344, -1438, 820, -1318,
+ -26, 0, 0, 0, 0, 0, 258, -32,
+ 1061, 643, -152, 92, -454, -1305, 1621, 554,
+ 344, 82, -404, 5222, -344, 286, 177, 0,
+ 0, 0, 0, 0, 63, -360, -127, 814,
+ 3639, -3322, 390, 12, -515, -493, 1515, 1706,
+ -727, 394, 1164, 357, -208, 0, 0, 0,
+ 0, 0, -27, 648, -342, -125, -327, 194,
+ -3639, 598, 29, 244, 898, -493, 372, -635,
+ 567, 31, -237, 0, 0, 0, 0, 0,
+ -160, 2798, -1768, -2186, 493, 517, -82, -468,
+ -290, 2890, -460, 450, 414, -265, -1121, 219,
+ -1115, 0, 0, 0, 0, 0, 14, 76,
+ -2806, 338, -1429, -402, 253, -130, -235, -799,
+ 309, -525, 3823, 175, 36, 113, 247, 0,
+ 0, 0, 0, 0, 352, 521, 213, -107,
+ -71, -762, 790, -856, -252, -246, -729, -631,
+ 1258, -3276, 1534, -436, -635, 0, 0, 0,
+ 0, 0, -54, 118, -453, -124, -32, 539,
+ 356, -169, -202, -590, 721, -444, -6260, -275,
+ -239, -105, -52, 0, 0, 0, 0, 0,
+ -464, 507, -796, 1273, 2297, 790, 652, 392,
+ 3364, -1949, 2154, -701, -229, 99, 88, 471,
+ -524, 0, 0, 0, 0, 0, 71, -914,
+ 1835, -156, -242, -196, 513, 431, -481, -84,
+ -734, 4501, -510, 115, 461, -428, 83, 0,
+ 0, 0, 0, 0, -3987, 1063, -717, -2640,
+ -963, -667, -147, 536, -68, 422, 341, -1916,
+ -616, 996, 522, 568, 1174, 0, 0, 0,
+ 0, 0, 8, 112, 693, 392, 445, 5309,
+ 259, 121, 1670, 343, 176, 472, 197, 419,
+ -240, -1178, -107, 0, 0, 0, 0, 0,
+};
+
static const int16_t cb0808l0[] = {
164, -3637, -3563, -243, -123, -47, -87, -32,
62, 129, -2, 131, -36, -202, -197, 37,
@@ -855,6 +2041,2748 @@
-222, 151, 224, -210, 264, 192, 29, -84,
};
+static const int16_t cb0808sl0[] = {
+ 24, -3148, -3111, 106, 45, -114, -85, -211,
+ 154, 172, 246, 368, -130, 58, -135, 70,
+ 102, -150, -76, -7, 13, -1, -29, 20,
+ -7, 112, -234, -115, -138, -40, 106, 178,
+ -7276, -537, 25, 856, 460, 3107, 146, -520,
+ -631, -118, 393, 179, 144, -86, 47, 82,
+ 3031, 28, 164, -308, -411, 72, 138, 378,
+ 242, 253, 12, 158, -28, -60, -29, -46,
+ -5, -11, 84, 2753, -113, -65, 3, 5,
+ 13, -5110, -74, -126, -129, -82, -58, 116,
+ 15, 68, 243, -32, 126, -48, 11, -7,
+ 75, 10, 166, -153, 8, -43, -38, 81,
+ -41, 13, 100, 27, 46, -441, -56, 35,
+ 4, 51, 7528, 52, -141, -153, 39, -36,
+ -86, 80, -35, 50, -46, 23, 178, -3986,
+ -3350, 59, -278, 37, -2, 14, -157, -208,
+ -317, 218, 15, -296, -32, -51, 36, -27,
+ -2062, 28, -37, 322, 2286, 214, -196, -171,
+ -64, -163, 265, -50, 3, -177, -22, 68,
+ 124, 37, -15, -2202, 60, 133, 4, 371,
+ 2753, -111, 480, -446, 484, 43, 150, -331,
+ 1410, -791, 123, -136, -192, 267, 0, -89,
+ -105, 421, 68, -126, 79, 279, 202, -132,
+ -208, -3345, -105, 59, 118, -647, -48, -12,
+ 145, -403, 200, 7, -4, -3192, -223, 64,
+ 0, 415, 366, 136, 49, -7611, 79, -105,
+ 127, -69, -43, 103, -95, -93, -10, -30,
+ 94, 108, -109, 0, -87, -70, 300, -93,
+ 113, 25, -17, 2263, 41, 192, 18, 73,
+ 179, 129, 149, -81, -1, 0, 201, 184,
+ 651, 8, 18, 114, 2820, 383, -71, 376,
+ -2281, -1190, -143, 121, -45, -2157, -410, 81,
+ -14, 1537, -833, 29, 1150, -494, -8, -14,
+ 210, 188, 3073, -1775, -123, 80, -103, 227,
+ 296, 111, 1637, -197, 1349, 174, 3276, 49,
+ -98, 74, 660, 3, -252, -356, -9, 527,
+ -63, -7995, -16, 85, 249, 74, 26, 2,
+ 3, 26, -124, -61, -26, -144, 4, -52,
+ 6, -517, -95, 2566, -26, -190, -196, -509,
+ -2982, 4, -178, -9, -67, -25, 1, 193,
+ -68, -46, -82, -3734, -14, -339, -44, -151,
+ 55, 230, -3, 100, -47, -69, 35, 107,
+ 127, -175, -11, -10, -158, -140, 2934, -132,
+ 2571, -158, -217, 106, 137, -222, 74, -42,
+ 64, 559, 122, 73, -112, -2964, 2502, 13,
+ 301, -41, 203, -382, -151, -221, -147, -24,
+ 83, 37, -45, 56, 89, 71, 109, -14,
+ -43, -130, -108, -18, 74, -23, -34, 79,
+ 7662, -88, 70, 21, -110, 147, 26, 250,
+ 74, 165, 49, 43, 45, -22, -14, 293,
+ 5275, 57, -72, 93, 40, 115, -139, -332,
+ 95, 92, -26, 26, 169, -94, 332, 71,
+ -482, 137, 190, 114, 14, 151, 3125, 6,
+ 109, 6, 7, 1543, 282, -24, 24, 142,
+ 33, 123, 41, -72, -253, -33, 309, -107,
+ -64, -131, 56, -3528, 82, -17, 417, -47,
+ -588, 274, 155, 158, -245, 186, 147, -7,
+ -50, -218, 12, 118, -62, 652, 145, 64,
+ 2473, -146, 220, -2973, 97, 284, 29, 268,
+ 29, -208, -40, -251, -175, -16, -58, -65,
+ 28, 26, 55, 74, -12, 1911, 43, -82,
+ -150, -13, -119, 8, 119, 156, 1550, -88,
+ -102, 46, 226, -132, 95, 100, 87, 7,
+ -46, 8, -32, -16, -12, 317, -33, -27,
+ 291, -88, 169, 1, -101, -61, 161, 162,
+ -33, -1, 11, 5097, -34, 142, 31, 94,
+ 3619, -94, 67, 3379, -65, 28, 254, 189,
+ 110, 138, -41, 52, 32, -104, 154, 172,
+ -2365, -464, 281, 207, -66, -190, 399, -158,
+ 13, -155, -223, 92, -108, -25, 468, 189,
+ -4359, 42, -135, 138, 36, -1403, -264, -336,
+ -164, -49, 54, -125, -61, 62, 16, 172,
+ 182, 3134, -1373, 63, -227, -106, -133, -165,
+ -69, -57, -184, -46, 9, -57, 50, -3,
+ -62, -15, -123, 108, 111, 91, -161, 23,
+ -81, 7, 208, -5385, -244, 24, 95, 12,
+ -264, 62, -44, 21, -240, -299, -12, 117,
+ -61, -2551, 389, 2816, -179, 203, -421, 899,
+ -7, 174, -200, 98, 1036, -166, 11, -137,
+ 78, -7, -121, 245, -77, 124, 102, 51,
+ 3136, 74, -310, 40, 212, -239, -373, -154,
+ 398, 2967, 654, 488, 103, -230, -330, 831,
+ -63, -473, 152, -556, -2186, -371, 4, 86,
+ -12, -141, 5503, -87, -123, -17, -15, 154,
+ 192, -86, 97, 165, 352, 56, 154, 43,
+ -331, 1004, -52, -131, -3311, 3, 110, -153,
+ -70, 137, -168, -20, 115, 140, -25, -54,
+ -13, -300, 57, -131, 214, 261, -92, 618,
+ -2752, -3146, 61, -51, 210, -230, 87, -184,
+ 330, 22, -19, -107, -477, -39, 1, 127,
+ 178, -73, 425, 56, -25, -41, 135, 2423,
+ 59, -46, -10, 49, -116, -51, -2239, -228,
+ -75, 48, 3, 181, 161, -133, -355, 81,
+ 5, 84, -222, -83, 92, 33, -7558, -38,
+ -3, 159, 33, -58, -37, -107, 16, -61,
+ -94, 93, 97, 49, -275, 29, -198, -4,
+ -68, 87, 116, -7039, 46, 81, -25, 0,
+ -7, -46, 152, 64, -40, -143, -56, 147,
+ 403, 257, 2380, -538, -400, -132, -89, -29,
+ -2878, 457, -552, -12, -189, -370, -357, -3679,
+ 422, 63, 200, 116, -9, -229, -72, -100,
+ 3346, 88, -18, 28, -47, 159, 108, -160,
+ 253, 58, 2938, 55, 366, -33, -3209, 31,
+ -148, -10, -40, -443, 127, 120, 106, 9,
+ 4, -240, 200, 129, 328, -102, 187, 182,
+ 112, 2757, -3260, 314, -163, -3, -185, 354,
+ -97, -69, -199, 41, -143, 19, 108, -22,
+ -32, -18, -149, 35, 31, -5, -5083, 52,
+ 9, 5, -44, -52, 76, 7, -100, 7,
+ -79, 0, -33, 110, -208, 20, -159, -76,
+ 2, -8192, 156, 118, -306, -88, 136, -293,
+ -176, 163, 8, 1871, -112, 229, 311, -95,
+ -75, 17, 217, 152, 62, 17, -246, 3579,
+ 5, -87, -21, 92, 114, -185, 118, 8,
+ 196, -124, -220, 175, 104, 54, 104, -40,
+ -45, -152, 392, 216, -24, -28, 2024, -6,
+ 42, -91, -201, -9, -192, 35, -43, 1661,
+ -356, 1207, -1322, 340, -2937, -16, 163, -801,
+ -423, 197, -512, -70, 229, -412, 291, 511,
+ -36, -179, -98, -54, 93, 87, 263, -44,
+ 167, 77, -4, 7278, -101, -193, 91, -251,
+ -131, 269, 15, -168, -22, -26, 44, 24,
+ 154, 115, -11, -124, 28, 37, -14, -46,
+ -67, -8192, -51, -169, 41, -302, -81, 1991,
+ -11, 136, -175, 71, -104, 89, 60, 137,
+ 17, 106, 96, -238, -83, -52, -113, 53,
+ 2903, -47, 9, -227, -2784, -245, 146, -196,
+ -216, 41, -6, -128, -53, 1, -128, -145,
+ 149, 32, 25, -57, -14, 72, -135, 10,
+ -1946, -67, 74, -127, 141, -299, 55, 8,
+ 947, -2239, -271, 74, -227, -81, 31, 291,
+ -86, -2914, 22, -7, 293, 2, -25, 9,
+ -2997, 89, 3158, 192, -46, -246, -140, 46,
+ 287, 133, -110, 308, -114, -33, -106, 9,
+ -89, 105, 364, -172, 185, -61, 4464, -92,
+ -264, -66, -161, 102, -178, -264, -21, 114,
+};
+
+static const int16_t cb0808sl1[] = {
+ 246, -6, -180, 90, 127, 3322, 598, 182,
+ 81, 82, 67, -39, 87, -60, -8, -89,
+ 185, 99, -25, 27, 9, -59, -7421, 49,
+ -17, 116, -85, 6, -305, 88, -164, 99,
+ 61, -415, -114, -288, 1, -165, -12, 5,
+ -143, -142, -521, -245, -53, 38, -99, 3709,
+ -52, 0, -41, -135, 147, -217, 62, -2144,
+ 255, 132, 264, 65, -37, 204, -338, -280,
+ 192, -184, -158, -3685, -26, 203, 430, -29,
+ -16, 77, 230, -311, 597, 2553, -1126, -63,
+ 154, -431, -161, 315, 286, -147, 177, -3,
+ 93, 449, 253, -37, 101, -244, -77, 42,
+ -384, 22, 36, 235, -4973, 243, -120, -105,
+ -226, -114, -455, -404, 164, -505, 476, -124,
+ -2837, -82, -2920, -3, 0, 134, -94, 264,
+ -53, -53, 108, -3, -845, -2813, 228, -179,
+ -60, -2, 65, 33, -153, -16, -149, -2135,
+ 209, -929, -288, 227, 2656, -125, -42, 17,
+ 30, 3375, -367, 53, -262, -351, 108, -270,
+ 11, -57, -182, -51, -149, -287, -115, -24,
+ 99, -76, 6954, -75, -4, 38, -168, 138,
+ 109, -239, -45, 49, 28, -1376, 49, 66,
+ -83, -129, -61, -99, 135, 14, -93, 111,
+ 37, -16, 2, -76, 360, -77, 82, 161,
+ 149, -1660, 18, 98, -34, -12, -36, -65,
+ 126, -57, 28, 519, 2044, 297, 73, -218,
+ 51, 17, 21, -70, -32, -73, -39, -38,
+ -11, 60, 38, -129, -105, -173, 200, 7,
+ 124, -74, -2780, 2608, -57, -213, 54, -200,
+ 134, 208, -34, 236, 143, 101, 327, 558,
+ 75, 317, 3090, -188, 544, -186, 15, 116,
+ 237, 76, -105, 29, -300, -27, -211, 71,
+ -144, 183, -77, 38, -16, 39, 56, -7308,
+ -113, -116, -32, 222, 60, 76, -21, 59,
+ 52, 104, 383, 73, 149, 88, 127, 34,
+ -1819, -46, 50, 11, -159, -223, -163, -149,
+ 95, -163, -2168, -19, -937, -183, 66, -465,
+ -257, 341, -70, 111, 228, 52, 83, 63,
+ -52, -187, 16, -2539, -51, 3240, -81, 87,
+ -116, -183, -182, 96, -22, -191, -107, 217,
+ -10, -215, 9, -7, -97, -331, -55, 513,
+ -398, 1378, 2627, -2129, 563, 1462, -369, 498,
+ 1176, -469, 220, -953, -122, -236, -306, -276,
+ 31, 35, -167, 558, -134, 45, -54, 16,
+ 36, 18, 300, 2438, 62, -177, 77, 2638,
+ -108, -115, 3392, 274, -123, -66, 201, -400,
+ 170, 142, 151, 332, 53, -507, 81, -653,
+ -93, -3204, -5, 10, -43, 79, 3879, 77,
+ 191, 24, 23, -208, 6, -109, -97, 126,
+ -306, 629, 26, -516, 79, 21, 131, 43,
+ -253, -3463, 840, 653, -95, -48, 300, -1026,
+ -324, -909, -383, 195, 342, -136, -192, 422,
+ 262, -13, 534, 3125, 8, 1672, 176, -293,
+ 211, -1213, 537, 637, -10, -116, -149, 44,
+ 53, 105, 7, -97, 3, 17, 8, -21,
+ -7, -41, -38, -4959, -81, 1, 165, 196,
+ 98, 35, -35, 8, -28, 113, -20, 108,
+ -130, -65, 172, 2858, 41, -3295, 138, 10,
+ -95, -30, -173, 85, 42, 30, -119, 161,
+ 195, 125, -32, 136, 319, -33, 5142, 50,
+ 100, 128, -90, -53, -67, -203, 28, 19,
+ 37, -137, -124, -105, -25, -3405, -250, 294,
+ 409, -99, -1072, -383, -12, 212, -276, 3389,
+ -101, 171, -41, -554, -295, -437, 86, 158,
+ -242, 167, 135, 7, -149, 48, -4, -84,
+ 4911, 283, 5, -14, 105, -107, -384, 102,
+ 183, 47, 67, -5105, -5, 16, -155, 181,
+ 110, 24, -77, -32, 120, 1, 22, 167,
+ -90, -150, -5, 163, -44, -28, 54, -3058,
+ -174, 58, 152, -31, -179, -122, -57, 232,
+ -395, -4961, 61, -115, 31, 14, 82, -109,
+ -39, 59, -49, -133, 52, 17, 57, 52,
+ -63, 275, 146, 104, 53, 47, -55, 311,
+ 4871, -26, 48, -94, -11, -58, 63, 140,
+ -74, -94, -269, -77, 3372, -3116, 16, -47,
+ -74, -161, 115, 58, -247, -119, 399, 42,
+ -181, 154, -218, -24, -237, 58, -275, 2979,
+ 187, -124, 312, 301, 2767, -8, 40, -23,
+ -6, -38, -52, -363, -265, -78, -230, 286,
+ -135, -337, -81, 170, -13, -58, -117, 519,
+ -4784, 157, -193, 9, 62, -21, 180, 128,
+ 326, 213, 2440, 62, -601, -55, 2, -18,
+ -342, 142, 358, -632, -377, 3590, -248, -278,
+ -235, -28, 242, -133, 144, 26, -261, 113,
+ 45, -23, -1984, -77, 128, 249, -8, -266,
+ -38, -6, -1672, -45, -84, -377, 154, 17,
+ -83, -44, 156, -137, 43, 91, 253, 17,
+ -71, -92, 178, 12, 18, -8, -105, 101,
+ 7068, 71, -81, 84, -33, 79, 53, -7,
+ -85, -265, 117, 317, 114, 72, -482, -418,
+ -185, -97, 268, -1543, -79, -146, -48, -45,
+ -3259, -212, 1149, -165, 177, -158, -77, 100,
+ 86, -69, 107, 219, -512, -253, -418, -45,
+ 16, 5501, -184, 207, 67, 46, 109, -28,
+ -9, 33, 63, -16, 39, 92, 27, 23,
+ -10, -8192, 0, 50, -57, 68, -444, 1082,
+ 247, -138, 120, 472, -692, 212, -1576, 66,
+ 3061, 402, -160, 337, -685, -519, 227, -279,
+ 92, -4135, -393, -44, 6, -129, 59, 239,
+ 151, 153, -39, 116, 134, -40, 171, 118,
+ 207, 2615, 38, -167, -1671, 85, -135, -182,
+ -88, 246, 53, 29, -2, 16, 232, 544,
+ -46, -138, 122, -52, 1312, 9, 92, 13,
+ 4, 66, -35, -134, -56, 85, -43, -31,
+ 28, -3187, 100, -103, 70, -3, 186, -43,
+ 122, -3040, -27, -46, -121, 1, 37, 0,
+ -60, 2, -100, -152, -218, 175, -406, 175,
+ -193, 68, -208, -23, -230, 221, 3397, 45,
+ 48, 37, 337, 11, 15, -69, -4, -82,
+ 53, 33, -56, 75, -98, -69, -11, -19,
+ -12, 81, -52, 5428, 121, 82, 465, 10,
+ -229, 126, 32, 119, 439, 126, 1996, -85,
+ -81, -57, 88, 232, 108, -22, -24, 27,
+ -136, 91, -32, 18, 226, -33, 15, 117,
+ 145, -7737, 9, 58, -102, -113, 26, -2174,
+ 28, -421, -11, -70, -23, -70, -119, -96,
+ -133, 208, 20, -3750, -14, 23, 41, -180,
+ 2097, -103, -599, 146, 251, -77, -557, -76,
+ -96, 69, 266, 316, 74, -17, -227, 223,
+ 33, -261, 135, 8126, 250, -5, -57, 35,
+ 382, -44, 136, 81, 42, -80, 179, -73,
+ -75, -57, 274, -15, -3140, 3236, 196, 150,
+ -51, 222, -190, 13, 83, -313, -149, 89,
+ -281, -12, -42, 293, 567, 19, -43, 146,
+ 102, -39, 3666, 95, 76, -1, 12, 27,
+ 7, -5, 261, 132, -215, -295, -51, 496,
+ 77, 100, 16, -285, 649, -95, 280, 77,
+ 121, -2676, 25, -1148, 2912, -341, -91, 2380,
+ -80, -6, 269, -34, -686, -208, 19, 228,
+ 24, -5, -150, 11, 214, -316, 1187, 599,
+ -62, -2274, -240, 48, -86, 87, 86, 477,
+ 3832, 67, 135, 68, 747, 339, 385, -255,
+ -224, 184, 70, 171, -134, 2604, -231, 72,
+ 170, 51, -2785, -580, -86, -393, -63, -79,
+ -151, 334, 78, 329, -278, 102, -26, -55,
+ -3531, -378, -247, 176, -202, 147, 169, 87,
+};
+
+static const int16_t cb0808ss0[] = {
+ -1872, -332, -1311, -512, -934, -11, 112, 389,
+ -189, -1513, 1508, -1081, 185, -87, 3092, 529,
+ -166, -171, -1648, 2544, 2144, -259, -688, -1113,
+ -71, 387, 1194, -733, 175, 856, -976, 268,
+ 589, -1773, -426, -109, 1210, -486, 297, 195,
+ -991, -1543, -432, 1190, -1089, -531, -421, 80,
+ -225, 354, -231, -670, -299, -3694, -510, -882,
+ 31, 2804, 476, -478, 1897, 686, -1066, -1222,
+ -882, -374, -427, -1464, 957, 549, -1211, -204,
+ -218, -1412, -545, -968, 943, -342, 80, -281,
+ -249, -968, 3424, -2342, -212, 949, -167, -271,
+ 607, -838, -418, -891, -398, -877, 138, 1653,
+ -1034, -2515, -1363, -1535, -364, 432, -324, -1120,
+ 1531, 407, -698, 396, 325, 1432, 646, 2777,
+ 174, -836, -605, 2257, 1086, -888, 348, 36,
+ 513, 2229, 1543, 1293, 94, 2444, -574, -1030,
+ 933, -9, -668, 555, 346, 511, 715, -4033,
+ 409, -299, -166, 700, -560, 950, -1265, -245,
+ 1418, -1362, -20, 870, 152, 942, -331, -66,
+ 227, -186, 251, -3632, -1057, -989, -1798, 923,
+ 542, -630, 2889, -128, 1475, -97, -964, -860,
+ 534, -217, -746, 181, 321, -1007, 2595, -411,
+ 1298, 635, 310, 1955, -17, 846, -824, -11,
+ -952, 208, 328, -547, -1086, 1481, -264, -1574,
+ 3579, 500, 242, 1038, -1030, 353, -75, -2100,
+ -347, 2662, -2378, 261, 210, -1151, 525, 291,
+ 368, -200, -702, 105, -140, -81, 663, -716,
+ 334, 1220, 239, 21, 114, 301, -1898, 3647,
+ -302, 550, -489, -484, -853, -274, 1509, -419,
+ -330, -1121, -2666, 2507, -621, -818, 1188, -69,
+ -885, 231, 316, 1837, -740, -187, -102, 1148,
+ 1219, -123, 852, 1154, 27, 139, -344, -404,
+ -1133, 425, 353, 145, -123, 179, 49, -5836,
+ -571, 39, 274, -38, -457, 172, -80, 593,
+ -1977, -331, -421, 1965, 1768, -113, 64, 2272,
+ 475, 2165, 210, 873, -819, 757, -119, -530,
+ -1431, -2167, -1517, -864, 1060, -752, -1366, 2349,
+ -671, 1180, -179, 10, -450, 781, -799, -1303,
+ -393, -61, -113, 2053, -550, -843, 1028, -2044,
+ -2631, -1388, 1078, 171, 517, 496, -928, -1695,
+ 298, 708, -557, 122, -917, -197, -423, 1142,
+ 116, -528, -585, -470, 480, 400, 4605, 384,
+ -142, 57, -2340, -1507, -67, 907, 8192, 356,
+ -18, -704, 528, -32, -379, -611, 418, 703,
+ -396, 531, 155, 642, 678, -427, 85, 814,
+ 212, 845, -579, -590, -456, 103, -624, -4541,
+ -306, 638, -760, 36, -149, 1929, 1229, -717,
+ -543, 530, -694, 169, -2996, 423, -346, -897,
+ 1077, 255, -1054, -63, -1773, -479, 479, -701,
+ 1547, -1683, -342, -926, 112, -663, 1638, -9,
+ 2587, 311, -561, -932, -539, -335, 589, 779,
+ 2345, -432, 788, -967, 319, -4, 192, -588,
+ -103, 357, -3508, -257, 707, -473, 1521, -9,
+ 130, 3290, 274, -296, -802, -139, -814, -19,
+ 971, 849, 253, 486, 40, -1216, 1179, -1772,
+ -996, 1400, 838, 1955, -1432, -1925, 2324, 767,
+ 896, 1314, 3407, -1003, -552, -967, -166, -26,
+ 1099, -1965, 9, 239, -10, -243, 864, 1251,
+ 91, -2279, -691, -542, -473, -1908, -1208, -1447,
+ -891, -311, -1136, 1638, 1150, 586, 1656, 260,
+ 538, -1746, 1460, -478, -860, 297, -605, -139,
+ 822, -3718, -194, 307, 609, 30, 3418, 226,
+ -338, 161, -387, -344, -472, 354, -170, -421,
+ 433, 601, -1446, 821, -48, -31, 493, 916,
+ -347, -3740, -899, 1389, -355, 71, 382, -644,
+ 485, 218, 975, -542, -3191, 742, -102, -783,
+ -1607, 473, 196, 1692, -71, 258, 2446, 1507,
+ -968, -1025, -1087, 637, -921, -1405, 1192, -88,
+ 2044, -1813, 922, 156, -1096, 1007, -695, -485,
+ -1015, -468, -316, 1825, 190, 2132, -205, -218,
+ -3556, -286, -1350, -212, -634, 120, 417, -311,
+ -90, 219, 870, -334, -1304, 523, 999, -144,
+ 98, 2157, 205, 45, -247, 1401, 2423, 278,
+ -766, -66, 309, -121, 316, -543, -3418, 932,
+ -803, 637, 436, -2341, 2016, 928, -836, -1212,
+ 702, -1179, -544, 6, -1429, 1014, 464, 1166,
+ 581, -291, 136, 0, 983, -799, 693, -230,
+ -727, -186, -310, -76, 698, -6, -660, 762,
+ 814, 451, -328, 4469, -454, 14, -423, -116,
+ -134, -568, 1535, -562, -629, -269, 826, 380,
+ 68, 282, -409, 640, -384, 218, -5702, -280,
+ -638, -2586, -557, -877, 49, 648, 434, 1178,
+ 3442, 883, -78, 2024, -253, -210, -1090, 198,
+ -67, -52, 3226, -671, -1606, 49, 1775, -422,
+ -173, 309, -720, -667, -505, 2073, -678, -1152,
+ -231, -519, -719, 422, -2614, -394, 543, -993,
+ 1449, 437, -463, -1286, 1191, -1274, -710, -463,
+ 659, 1493, 45, -832, -414, 306, 94, 1284,
+ -669, -1312, 1082, -917, 2489, -494, 547, 738,
+ -1696, -174, 282, -1442, -1455, 1633, 912, -428,
+ 964, 12, -2404, -485, 631, -311, 1810, 2912,
+ -16, 576, 50, -927, -175, 37, 673, -201,
+ 995, 684, -244, -251, -1444, 3195, 1863, -88,
+ -1183, -966, 1769, 36, -825, 766, 489, -86,
+ -365, -106, -1477, -330, 125, -253, -250, -523,
+ -731, -5130, 653, 395, 99, -845, -721, 127,
+ -287, 850, 479, 25, -30, 36, -782, 611,
+ 448, 99, 933, -20, -853, -949, -286, -379,
+ -654, -385, 1298, 547, 235, 1242, -583, -4147,
+ 81, -547, -1142, 1280, -223, -1712, -1501, 458,
+ -142, 2065, 208, 855, -1115, -187, 861, 1090,
+ -760, -2551, 2326, -378, -1205, 488, -241, 893,
+ 113, 176, 4060, -225, -41, -717, -26, -442,
+ -445, -312, 813, 494, 314, -210, -98, -788,
+ 255, 632, -506, 166, -704, -334, -214, -860,
+ -5281, 60, -34, -238, -147, 643, 520, 2038,
+ 28, 2433, -1694, -1316, -615, 572, -150, -107,
+ 349, -1763, -307, 78, -1124, -631, 1162, -326,
+ -277, -591, 558, 1016, -4668, -324, -815, -251,
+ -1284, 52, 294, -1283, 598, 630, -345, 641,
+ -34, 1085, 4247, 637, 1695, -858, 212, -243,
+ -64, 327, 557, 426, -321, 363, -652, 372,
+ 777, -567, -749, -1704, 414, 5299, 389, 242,
+ 39, 31, -315, 179, -102, 11, 62, 248,
+ 557, 706, 359, -85, 303, -403, 1531, 409,
+ -2092, 144, -1354, 54, -48, 51, -1787, 1278,
+ 942, 1264, -1495, 1671, 92, -899, -1149, 1908,
+ -903, -596, 342, 1749, -825, -13, 509, -1163,
+ 1065, 2405, -253, -741, 1099, -528, 2971, -412,
+ -235, -869, -136, -352, -489, -384, 745, -398,
+ -4197, 84, 1152, -497, 955, -161, 461, -16,
+ -871, 801, -93, -15, -352, 1826, -490, -536,
+ -2853, -633, 128, -1537, -1670, 538, 788, 1276,
+ 554, -340, 565, 1216, -1758, 384, -1313, -628,
+ 24, 835, -862, -927, 1792, -1042, 209, -784,
+ 807, -383, -1399, 3531, 52, -537, 205, -271,
+ 3071, 1678, -694, -2313, -1279, -1656, -428, -1063,
+ -1576, -323, -342, -257, -227, -716, -458, 1161,
+ -180, -71, -40, -1276, 1778, -3123, -378, -1363,
+ -827, 880, 275, -274, -581, -186, -8, 661,
+ -1114, -199, -171, 379, 429, -1551, 1645, -857,
+ -163, -2623, 1217, 1458, -596, -68, 383, 973,
+ -485, -354, -597, -2875, -516, 234, -83, 340,
+ -396, 1365, -574, -816, -2086, -1059, -1589, -593,
+ -779, 334, -546, 49, -1065, -1959, 1736, 1134,
+ 187, 1833, 17, -82, 68, 803, -456, -89,
+ 1760, 836, 1570, 122, -985, 2549, 1616, 82,
+ 1102, 227, 222, -1236, -155, -1012, 633, 467,
+ 163, 445, 166, 766, -253, -347, 1041, 5121,
+ -21, 792, 81, -478, 128, -158, 316, -1180,
+ -372, 1692, -828, -31, 1122, -2583, 1346, 2483,
+ 195, 72, 549, 424, 947, -470, 1940, -75,
+ 505, 1377, 550, 58, 1785, 343, -817, 874,
+ 3483, -307, -576, 240, 35, 837, -717, -247,
+};
+
+static const int16_t cb0808ss1[] = {
+ 2328, 183, 1652, -907, -3005, 1329, -61, -465,
+ 0, -453, -1621, 223, 232, -59, 254, -312,
+ -117, -59, -477, -2648, -1176, -227, -1937, 962,
+ 141, -1489, 849, 93, -1284, 1000, 295, 192,
+ -139, -468, -736, -436, 2155, 371, 2475, -348,
+ 856, -1985, 38, 94, 496, 758, 954, -243,
+ 134, -1759, 491, -1406, 1114, -2554, -447, -692,
+ -2128, 44, -923, 1610, 787, 150, -500, 3442,
+ -698, 276, -517, -1555, 379, -72, 810, -1373,
+ 2897, 936, -586, -438, 925, 1881, -419, 211,
+ 1724, 721, 885, 614, 253, 613, -1440, 509,
+ 842, -2407, -216, -1765, 451, 1419, 599, 689,
+ 1473, -175, -2974, -1015, 1983, -68, 640, 21,
+ 140, -1295, -556, -89, -836, 718, -343, -1903,
+ 443, 502, -1064, 1328, 86, 2049, 1235, 130,
+ 892, 1105, 692, -2968, -755, 473, 423, -1371,
+ -2032, 1885, -29, -516, -1118, 285, 482, 164,
+ -1932, -685, -819, 695, 715, -1520, 1300, -1188,
+ -121, -197, -4233, -141, 1279, 299, 208, 1071,
+ 20, 772, 692, 531, 257, 428, 78, 202,
+ -399, -27, 793, 1150, -736, 388, -1922, 155,
+ -410, 85, 1135, 835, 133, -88, 65, 62,
+ -534, -136, -4590, -162, -968, 1378, -445, -2825,
+ -93, -519, 402, 12, -1110, -637, -765, 210,
+ -2305, 654, 447, 26, -265, -91, 71, -886,
+ 126, -109, 7, 346, 19, -713, -257, 774,
+ 1080, -579, 185, 200, -5691, 541, 228, 424,
+ 37, 512, -78, -201, 848, -369, 1099, -1001,
+ 214, -336, 266, 2502, 1583, -2131, -654, -2476,
+ -97, -787, -738, 1056, 1385, 124, 944, -3421,
+ 1172, -547, -226, 1249, 1552, 1194, -308, 489,
+ -1152, 751, -92, -168, -3112, -1451, 2038, 35,
+ 371, -1585, 535, 308, 5, -53, 523, -169,
+ 591, -175, -1028, 91, 743, -144, 230, 1831,
+ -177, 509, 1291, 1808, -3322, -815, -227, -475,
+ -1064, -647, 79, 1223, 174, -10, -412, 393,
+ -305, 1224, 1310, 12, -521, -1267, 1911, 2245,
+ 407, 724, -1232, -2017, 566, 506, -467, 813,
+ 660, -196, -3643, 2495, 870, -561, 289, 662,
+ 654, -508, -734, -325, 622, 220, -309, -307,
+ -181, -445, 131, -1655, -835, -631, 883, 211,
+ 737, 552, -881, -3103, -766, 595, 112, 151,
+ -1177, 601, 479, -14, 37, -926, -505, 1062,
+ -1755, -799, -178, -555, 2509, -694, -792, 662,
+ 737, 847, 1611, 397, -67, -134, 474, -2251,
+ 2698, -245, 2054, 1603, 1291, 1188, 40, 763,
+ -216, 1554, -297, -1769, 410, 1270, 1089, 440,
+ -967, 294, -37, 270, 471, 1287, 3773, -108,
+ -610, -275, -298, 270, -384, 2072, -675, 1002,
+ 174, 18, 171, 704, 3311, -105, -1774, 108,
+ 511, -3001, -69, 543, -227, -1196, 1431, -63,
+ 6, 1279, -1, 671, 239, -2127, -1924, -934,
+ 168, -300, 1075, 1071, 3088, -590, 1439, 329,
+ 1073, 127, 762, -131, 274, 837, -134, -610,
+ -399, -1415, 1047, -156, 415, 765, 698, 428,
+ -748, 241, -4226, 152, -829, 1040, -937, 145,
+ -852, -85, -2957, -130, -406, 726, 168, -37,
+ -1321, -1069, -1255, 1159, 1575, 552, 649, -1953,
+ -17, 1027, 1078, -385, -2761, -553, -201, 58,
+ -1900, -24, 283, 1248, -90, 419, 1122, 902,
+ -1548, -32, 34, -360, 707, 45, -3458, -246,
+ 287, 308, 397, 393, 822, 1323, -565, 505,
+ -1553, -1902, -677, 625, 1079, -135, -2132, -187,
+ -163, -1001, -1479, -932, 1131, -2588, -316, 53,
+ 1270, -747, -966, 980, 242, -266, -1575, -1146,
+ -605, -523, -221, 585, -787, 1365, -286, -183,
+ 411, 546, 4779, -286, -578, -101, 309, 896,
+ 34, 451, -1022, -699, 170, 935, 458, 4143,
+ 229, -572, -912, -397, -40, -132, -198, 98,
+ -1858, 612, 101, -98, -18, -349, 322, -1626,
+ 1304, 273, -235, 418, -509, 3961, -493, 1040,
+ -416, 1808, 161, 1443, 1052, -460, 55, -67,
+ 41, 514, 1305, -836, -1636, 1353, 379, 147,
+ 398, -3814, -679, 235, 327, -2293, -716, 1234,
+ -728, -323, 698, 1992, 4, -275, 944, 895,
+ 212, 334, 285, -710, -891, -1325, 3107, 3,
+ 367, -1779, 300, -868, -59, -644, -326, 111,
+ 267, -43, 421, 976, 57, 1461, -172, 245,
+ -188, 296, -215, 5269, -46, 177, 199, -539,
+ 92, -542, 251, 951, -231, 117, -580, -898,
+ 402, 847, 4, 384, -215, 161, -1991, 4422,
+ 2461, -1219, -751, 1843, 1483, 1072, 2621, -16,
+ -1157, 243, -557, 651, 953, 476, -417, -533,
+ 505, -590, 713, 153, 1268, -312, -217, -124,
+ 870, -484, -751, -161, 897, 755, -823, 4117,
+ -1311, -729, 447, -642, 929, -2408, -338, -967,
+ -104, -1048, -2216, -1722, -124, -204, -196, -1156,
+ 1460, 391, -543, 120, 70, 204, 1185, -2490,
+ 2950, -507, -615, 1243, -150, -363, -475, -531,
+ 783, 671, -205, -591, 217, -523, 263, -14,
+ 71, 958, -1185, -1029, -330, 327, -705, 1229,
+ -2925, 131, -495, 1756, 2101, 441, -11, 133,
+ 1274, 1253, -154, 772, 522, 1725, -277, -1012,
+ -726, 1339, -1200, -241, 1676, 974, 2256, 347,
+ 2743, 1482, -738, -241, -868, -1294, -664, 855,
+ -1329, -4174, -1647, -104, 101, 307, -647, -823,
+ 347, 4, -120, -1112, 334, 27, 265, 990,
+ 319, -1414, 313, -603, 52, -3138, 1552, -612,
+ -854, 626, 212, 773, 2334, 662, 614, 560,
+ 589, -533, 1337, 229, 557, -26, 1458, -626,
+ 1890, 2392, -1525, 1023, 667, -431, 72, 1691,
+ 1015, -97, -515, 1380, 796, 1192, -39, 162,
+ -2821, 2960, 1558, -1058, 1327, 793, 1231, -743,
+ -1190, -245, 29, 486, -494, -1371, 1633, -66,
+ -1806, 231, -664, -147, 2402, -584, 473, -527,
+ 1272, 464, 1991, -1007, -235, 357, 201, -1176,
+ -341, 223, -47, -2089, 815, 49, 192, -719,
+ -1041, -248, 3046, -40, -501, -346, -1347, -401,
+ 57, -1588, -1039, 443, 590, -1089, -182, -1365,
+ -1013, -3917, -382, -98, 1025, -51, 698, -197,
+ 848, -75, 1596, -408, -1796, -3191, 1155, 234,
+ -100, 698, 571, -1233, -315, -1502, -647, -571,
+ -322, 842, -1048, -1115, 8192, -784, -472, 17,
+ -718, 37, 1190, -393, 146, -547, 90, -433,
+ -321, -1143, -501, 468, 235, -486, -64, -2214,
+ -330, -837, 1214, -127, 709, -3, 623, -384,
+ 221, 297, -783, -3802, -408, -11, -707, 92,
+ -275, -268, -117, 1580, 1466, 710, -1300, 142,
+ -746, 1647, 2399, -1231, 114, 1220, -1112, 882,
+ 467, -973, -976, 3855, -647, -150, -1244, 973,
+ -364, -154, 473, -675, -817, -346, -266, -769,
+ -613, -476, 1181, -8, -1054, 405, -768, 1385,
+ -1598, -892, 672, -2185, 83, -27, 582, -434,
+ -944, 99, -888, -1658, -1516, 2392, 726, -222,
+ 284, 324, 4848, -67, -782, -45, 424, -203,
+ -194, -1229, -114, -189, -216, 275, -935, -93,
+ 117, -1725, 360, -2561, -1555, -1199, -769, -285,
+ 74, 1267, -387, 1368, 179, -113, 952, 1025,
+ 725, -542, -186, 1258, -1396, -747, 572, 603,
+ 1965, -668, -12, -2512, 1337, -255, 254, 2285,
+ 1136, 1397, 557, -671, -1149, -614, -462, -913,
+ -452, 1206, -2922, 485, -882, 270, -1309, -605,
+ -21, -580, -1284, -194, 169, -2314, -216, -229,
+ 1124, 103, -1205, 1500, 1118, 1456, -1149, 780,
+ -467, -385, 585, -1062, 289, -3356, 198, -309,
+ -310, 91, 44, -377, -632, -737, -516, 30,
+ -779, 73, -482, 4661, -275, 38, -632, 479,
+ -345, -406, 76, -208, -230, 80, -220, -313,
+ 203, -3, 1740, -131, 773, -30, 372, 767,
+ 1673, -770, 3326, 1586, 234, 408, -257, 474,
+ -584, -990, 1378, 696, 47, -612, -313, 189,
+ -3964, 795, -289, 202, -437, -1648, 373, -780,
+ -24, -952, 123, 438, 797, 539, -481, 191,
+ 291, 37, -790, -321, 4520, -49, -281, 211,
+};
+
+static const int16_t cb0808sm0[] = {
+ -4664, -115, 59, -280, -199, -25, 213, -937,
+ 344, -2137, -841, -370, 256, 512, 1098, -130,
+ 58, -121, -414, 8192, 489, -296, -33, 98,
+ 49, -217, 721, -42, -418, -227, -8, 205,
+ -276, 407, -1218, -146, -292, -143, 113, 978,
+ 2693, -9, -1032, 1781, 1777, -215, -978, -824,
+ 68, -162, 55, 2991, -844, 682, 497, 406,
+ -922, 2471, 599, 774, -129, 1292, -1004, 777,
+ 42, 314, -102, -963, -2794, -2620, 510, 355,
+ 372, -248, -391, -163, -298, 561, 117, 1183,
+ 38, 182, 1811, -4, 328, -13, -456, 305,
+ 368, -1691, -2818, -1074, 1029, 261, -1446, 343,
+ 12, -2757, 1021, -375, -3, -155, 116, 195,
+ 3420, 64, 139, 780, 187, -464, 261, -313,
+ -128, 185, 3703, 3160, 960, 706, 41, 405,
+ 10, 1191, 353, -549, 131, 164, 105, 1,
+ 23, 386, 73, -509, 2651, -1441, -834, -1657,
+ -645, 1005, -777, 695, 212, 1420, 65, 701,
+ 25, 335, 136, 359, -112, -150, 191, 392,
+ -258, -1140, 651, -4551, 411, 251, -169, 804,
+ -83, -208, -363, 81, 152, 75, -1194, -203,
+ -9, 157, 413, -62, -210, 5393, -22, -407,
+ 132, -288, 2360, 131, -1535, 553, -2524, -140,
+ 250, 1259, -30, -1, 1766, 99, -529, 91,
+ 3948, -262, -3752, -382, -339, -701, -140, -787,
+ 67, -11, 331, -828, -443, 596, 47, 1634,
+ 31, -318, 39, 147, -670, -776, 707, -921,
+ 172, 971, 1163, 48, -81, -1357, -181, 2872,
+ -152, 898, 1075, 529, 91, -2279, 2925, -848,
+ 589, 1910, 549, 1088, 743, -631, 42, -1528,
+ 23, 380, -5, 389, -1147, -209, -2041, 224,
+ -1998, 520, -776, 193, -2648, -78, -34, -131,
+ 22, -200, -28, 18, 328, 215, 67, 61,
+ 50, -72, 301, -207, 413, 720, -6194, 967,
+ -3275, 149, -2444, -521, -772, -278, 137, -159,
+ 932, -111, 1219, 525, 17, -684, -1229, -1776,
+ 66, -2307, -195, -527, 272, -470, -356, -7,
+ -338, 146, 1021, -893, -2980, 591, 129, -257,
+ 209, -58, 538, -3973, 576, -905, -642, -2092,
+ 153, 737, -596, 573, 236, -887, -1692, -370,
+ -189, -216, -58, 714, 10, -582, 517, -86,
+ 450, -147, -310, 162, 1747, -656, 3577, 700,
+ 190, -685, -170, 241, 91, -126, 5567, 441,
+ -50, -688, -73, 938, 320, -130, -839, 1154,
+ 149, -446, -10, -11, 12, -659, -138, 637,
+ -470, 933, -431, 235, -86, -2, -407, -5851,
+ -250, 1414, 525, 110, 421, 255, -149, 86,
+ 378, -321, 1380, 118, -2849, -1138, 180, 1175,
+ 1932, 32, -488, -121, -412, -441, 397, 249,
+ -172, -95, 420, 375, -132, -215, -167, -206,
+ 8192, -116, -61, -311, 269, 615, -353, -115,
+ -383, 366, -651, -196, -98, 85, 861, 543,
+ -231, 237, 493, 380, -766, -168, 3227, 659,
+ 701, 181, -3004, -7, 154, 298, 298, -257,
+ -32, -5713, 48, 102, -776, -148, -110, 316,
+ -645, 212, 213, 575, -69, 31, 553, -673,
+ -5, -48, -148, -133, 11, 143, 10, 159,
+ 319, 43, 7462, 162, 228, -90, 75, 151,
+ 103, -2542, -13, -338, 11, -442, 123, -3039,
+ -452, 7, 106, 502, 227, -2034, 90, 500,
+ -28, -646, -262, -62, -78, 40, 419, 6761,
+ -11, 40, 209, 61, -151, -68, -245, -401,
+ 26, -123, 189, -57, 611, 6, -1285, -99,
+ -890, 3609, -302, -808, 639, -3245, -226, 107,
+ 54, -108, -316, -61, -56, 228, -16, 195,
+ 275, 214, -60, 77, -7157, 130, 8, 244,
+ -2160, -760, 450, -186, -378, 32, -797, 214,
+ -3569, -450, 307, -17, -141, 16, 1024, 404,
+ -2063, -288, -160, 4056, 877, -346, -970, -87,
+ 336, 961, 666, 585, -465, -1329, 350, -338,
+ -5421, -173, -295, 72, -201, 533, 462, -133,
+ -937, 1891, 264, 71, -935, 640, 687, 852,
+ -386, -85, -5644, 306, 240, 640, 67, 94,
+ -902, -351, -417, -3, 284, 38, -156, 359,
+ 53, 139, 185, 274, 2613, 213, 1282, 2867,
+ 30, 1234, -911, 343, -93, -1671, 57, -814,
+ -19, 326, -256, -113, 72, 3177, 3393, -125,
+ 460, -261, -503, -1019, -681, -253, -957, -157,
+ -117, -231, -212, 1446, 225, -3009, 313, -435,
+ 387, -928, 696, -857, -452, 66, -2063, 782,
+ 14, -94, 51, 242, -422, 236, -3825, -666,
+ 348, 196, -2770, 429, -416, -266, -1215, -586,
+ 84, 328, -302, 219, -457, -532, -764, 85,
+ 2008, -806, 2906, -1405, 367, 835, 715, -986,
+ -217, 88, -328, 569, -586, 3096, 249, -615,
+ 453, 176, -540, 792, -2472, 2189, 876, -353,
+ 111, 212, -7, 597, -154, 818, -401, -1408,
+ 748, 2502, 1426, -2897, 1069, 326, -605, 120,
+ -4149, -3087, 729, 82, 224, 320, 353, -77,
+ -163, -322, 220, -1073, 10, 545, -518, -453,
+ 50, -386, -2002, 614, -705, -806, -928, 2941,
+ -520, -35, 1208, 413, 900, 138, -414, -289,
+ -15, -75, 185, -373, 649, -251, 666, 2708,
+ -2817, -749, -159, -112, 454, -385, 1037, -46,
+ -25, -14, 66, 552, 160, -40, -552, -156,
+ 151, -5287, 541, -242, -82, -1164, 849, -773,
+ -136, -162, -76, 23, -371, -222, -2245, 468,
+ 425, -356, 418, -3, -322, -3573, 148, 260,
+ -155, 3301, -165, -3186, -709, -458, 870, 386,
+ 59, -161, 533, -150, 598, 384, 900, -1233,
+ -74, -464, -519, -661, -55, -2562, 290, 1489,
+ 1739, 2277, 874, -1483, -447, 93, 309, 311,
+ -203, -19, 2271, -1280, -125, -443, -538, 2650,
+ -42, 290, 245, -149, 24, 38, -133, 1638,
+ 210, -239, -180, 516, -12, -719, -19, -517,
+ -6190, -181, -89, 318, 485, 631, 11, -205,
+ -57, 257, 573, -72, 273, -579, 107, -5,
+ 112, 425, 2449, 2741, 758, 656, -663, -282,
+ -48, -45, -294, -448, -5562, 61, -1, -464,
+ -263, -688, -115, -15, -108, -569, -448, -48,
+ -180, -105, 14, -180, 490, 274, 625, -588,
+ -120, -196, -305, -126, 435, -2490, -2693, -3414,
+ 31, 97, -167, -114, 247, 7695, -189, -580,
+ 219, 241, 188, 327, 179, -193, 135, -176,
+ 127, 479, 529, 234, 112, 234, -358, -286,
+ 1109, 2940, -610, -13, -2650, 495, 1355, -574,
+ -43, -1497, -292, -503, 564, -363, 24, -313,
+ 1387, 221, -3612, 783, 637, 43, 1351, 217,
+ -21, 149, -3104, 190, -259, -201, -342, -201,
+ 166, 2411, -1082, 283, -382, -725, 157, 155,
+ -1609, -592, 527, -2959, 9, 216, 526, 79,
+ 54, -132, 202, 785, 929, 1755, -663, 366,
+ -3735, 3282, 305, 572, -36, -111, -231, 119,
+ 603, 1357, -153, 553, 363, -760, -1188, 890,
+ 147, -3844, -3788, 150, 257, -588, -234, 497,
+ 361, -543, 255, -175, -377, 49, -616, -200,
+ 4115, -541, 130, 678, -3458, -506, -218, -1317,
+ 889, 29, -104, -2, 532, -393, 513, -792,
+};
+
+static const int16_t cb0808sm1[] = {
+ 4123, -74, 639, 326, -110, 1896, 826, -855,
+ -299, -452, 536, -323, 262, 79, 486, 144,
+ 270, -64, 277, 154, 399, 50, -7270, -61,
+ 14, -8, 19, -104, 333, 119, 374, 389,
+ -196, 77, -322, 261, 75, 386, 162, 2360,
+ 644, -2785, 355, 277, -121, -148, 156, 2136,
+ 112, -453, 429, 171, 2405, -1245, -775, -181,
+ 2110, -583, 127, 889, -290, -550, -165, 1027,
+ 2155, -351, -936, 432, 2689, 217, -20, 646,
+ -785, 908, 654, 970, -294, -41, 466, -245,
+ 138, 50, -108, -366, 177, 481, -2118, 968,
+ -594, 3892, 528, 188, -613, 18, 283, 733,
+ -35, 1598, 387, 1, 156, -206, -437, 203,
+ -244, -347, 325, 296, 100, 1171, 49, 920,
+ -418, -54, -2756, 24, 123, 1018, 303, -501,
+ 901, -447, 322, -2361, 1039, -1067, 877, 1329,
+ -143, -2773, 269, 1560, 398, -3193, 102, 990,
+ 279, 379, -204, -144, -174, 139, 411, -234,
+ 21, -5064, -188, 365, 278, 353, -189, 94,
+ 593, -402, -353, -257, -788, 383, -1036, 569,
+ -72, -1764, 571, 1003, 629, 670, -1400, 0,
+ -435, 64, 189, 2874, 239, 1128, 992, 1213,
+ 69, -128, 207, 713, -2436, -931, -387, -111,
+ 1064, -170, -2853, -1072, -367, -1048, -238, -60,
+ -49, 340, 2382, 370, -245, 351, 248, -64,
+ 2331, 458, -484, -34, 281, 689, 483, 636,
+ 199, 3153, 607, -124, -3296, 953, -407, 49,
+ 455, 1083, 690, -169, -725, 311, -493, -1761,
+ -3054, 376, -544, 479, 91, 159, -2837, -1257,
+ -830, -948, -254, 289, -1039, 856, 86, 1123,
+ 203, -768, 1089, 73, -866, 308, 437, 674,
+ -2067, -240, -1079, 33, -1069, -3502, 756, -676,
+ 45, -2544, 378, -365, -275, -293, -394, -649,
+ -507, -2850, 672, 370, 186, -417, 682, 185,
+ -15, 2863, 21, -165, 356, -3776, -103, 535,
+ -416, -345, -31, 24, -90, -205, 96, -966,
+ 94, 424, -5, -188, 149, -2193, -183, 2342,
+ 425, -647, -1697, -627, -444, 1248, -967, -702,
+ -48, 3616, -3484, 774, -299, 94, 421, 472,
+ 71, -144, -523, 114, -172, 349, -285, -106,
+ 101, 59, 429, 512, 3362, -38, -62, 50,
+ -225, -1408, 780, -2747, -404, 489, -975, 840,
+ 357, 982, 488, -275, -109, 393, 375, 4794,
+ 183, -110, 922, -760, 61, -1067, -8, 322,
+ 74, -101, 554, -350, -486, 66, 384, 748,
+ 14, 223, -45, -386, 69, 6231, 247, 325,
+ -320, -47, -50, -165, 153, -380, 589, -3243,
+ -173, -140, 341, -747, -1559, 639, -1658, 356,
+ 110, -150, -273, 76, -632, -425, -227, 640,
+ 211, 192, -747, -165, 4608, 290, -160, 1268,
+ 2754, -3, 578, 189, -485, -2747, -123, -1309,
+ 662, 601, 43, -136, 84, 1625, -1113, 1400,
+ 75, -126, 3581, -243, 2339, -514, 2203, -400,
+ -483, 521, 30, -246, -76, 359, 101, 663,
+ -40, 57, 52, 360, -447, -290, 254, 104,
+ 102, 113, 215, -163, -388, 299, 4570, 31,
+ 108, -41, 41, -2633, 2891, 1188, -505, 1061,
+ -349, -604, -449, -374, -320, 969, -304, -192,
+ 246, -152, 441, -46, -1416, 137, 1987, 495,
+ -63, 1087, 875, 699, 201, 211, -3157, -273,
+ -60, 195, -2813, -239, 2486, -55, 294, 315,
+ -133, 448, -1849, 363, 1063, 76, -928, -574,
+ -72, -57, 168, 5673, -156, -116, 400, -124,
+ 82, 218, -487, 37, 112, 53, -544, 178,
+ 99, 480, -7179, -196, 271, -160, 308, -62,
+ 393, 394, -220, -740, -14, 92, 408, -364,
+ 299, -305, 76, -239, 26, -312, -234, 34,
+ -189, 871, -297, 364, 282, -321, -927, 4511,
+ 2, 6, 308, -82, 87, -128, 518, 82,
+ -4509, 1145, 960, -109, -186, 83, -144, 752,
+ 84, -2876, -162, 877, -249, 317, 510, 338,
+ 298, 744, 2892, -791, 363, 1088, 630, -2506,
+ -1, 3150, 219, 130, 119, 313, -822, -668,
+ 1201, -2948, -237, -106, -711, 405, 276, -255,
+ 0, 440, 161, 2587, -734, 3376, 276, 154,
+ 287, -200, 594, -29, 198, -237, -608, -445,
+ -286, 202, -783, 112, -3879, 78, 2809, -337,
+ -606, -684, -434, 559, 273, 201, 331, 903,
+ -53, 346, 700, 2599, 302, -590, -2551, -498,
+ -26, -667, 576, -546, 457, -289, -1408, -1021,
+ -63, 78, 153, -83, -696, -3105, 2498, -1502,
+ -1249, -238, 254, -287, 215, 313, 279, -517,
+ 67, -58, -148, -1111, 58, 5151, 346, 283,
+ -367, -900, 542, 209, -438, -128, -135, 54,
+ 7, 869, 291, -1073, 775, -61, -145, 457,
+ 562, 1332, -4589, 99, 1366, 184, 980, -920,
+ 80, -266, -152, -1877, -266, 364, -1432, 272,
+ 2275, 567, 60, 50, -2504, -386, -700, 373,
+ 6775, -15, -434, 347, 215, -369, -20, -281,
+ -243, -325, 227, -283, -665, -74, 336, -674,
+ -112, -369, -53, -396, 328, 3588, -541, -557,
+ -164, 1305, -817, -462, 1986, 1249, -574, 130,
+ 152, -2375, -425, 442, -3827, 322, -728, 563,
+ -179, 534, 620, -937, 590, -1, -59, 584,
+ 175, -193, -168, -5, -150, 156, -175, -178,
+ -245, -7481, -273, 212, -35, 318, -178, 446,
+ -55, -26, 42, -46, -265, 767, 330, 295,
+ 910, -54, 490, 2952, 598, -2578, -644, 403,
+ 149, -88, 549, -510, 596, -225, -2341, -286,
+ -2724, 5, -1960, -262, 922, 537, 646, -62,
+ -18, 8192, 484, 112, -222, -211, -224, 317,
+ 112, 82, -853, 1, 176, -475, -162, 200,
+ -193, 166, -228, -214, 72, 417, -27, -16,
+ 4, 395, -515, -6832, 28, -47, 626, -173,
+ 63, 90, 141, 217, 1037, 335, 4520, -896,
+ 111, 91, -656, -103, -729, -29, 653, -599,
+ -11, 2734, -378, -291, 60, 228, 47, -3670,
+ -192, 653, 733, -597, 898, -420, 1572, -133,
+ -154, 329, -259, -225, 218, -82, 117, 300,
+ -479, 277, 787, -1719, 136, -3603, 702, 1357,
+ 3340, 362, -438, 131, -1463, 367, -467, 1722,
+ -2186, 343, -379, 1221, -562, -260, 1157, 2692,
+ 37, -89, -322, -322, 8192, -284, 235, -528,
+ 113, -359, 44, 74, 119, -917, 403, 410,
+ -150, 157, 514, 168, 407, -246, -31, 510,
+ 105, 449, 4612, 635, -90, -1260, 774, -284,
+ -80, 456, 7, -3000, -324, -212, -104, -374,
+ -440, 1268, 2736, 53, -1178, -403, -438, -534,
+ 121, 261, -497, -73, 10, -262, 17, -1870,
+ 178, -1339, 224, 3115, -436, -448, 385, 894,
+ -1, 105, -18, 268, 342, 270, 891, 367,
+ 121, -325, -1610, -75, -3233, -189, -1050, 961,
+ -2833, -304, -51, 400, -284, -810, 824, -71,
+ -135, 194, 297, -297, 1129, 660, 518, 2426,
+ -225, 251, 4677, -176, -464, 296, -1208, -423,
+ -875, -581, -707, -1150, 499, -778, 28, 29,
+ 101, -4213, -127, -3681, 425, 481, -529, -679,
+ 11, 266, 127, -445, 527, -577, 310, 1465,
+};
+
+static const int16_t cb1110l0[] = {
+ -3748, -3820, -105, 16, -22, -7, 112, -14,
+ 52, 28, -42, -113, 132, -81, -8, -112,
+ 19, 33, -251, 117, -33, -9, -13, -28,
+ 60, -30, 29, 27, -58, -7, 4, 43,
+ -10108, -38, -3, 48, 3, -23, 202, -175,
+ -202, 71, -2143, 3, -82, -38, -113, 141,
+ 38, -66, -118, -38, -14, 148, -264, 143,
+ -13, -56, -9, -21, -28, 8930, -23, 53,
+ -40, 30, 72, -46, 26, 66, 22, 32,
+ 44, 22, -50, -66, -115, -141, 24, -3013,
+ -3460, 492, 207, -62, -567, 134, -26, -64,
+ 287, 343, -213, 42, -274, -144, -144, -77,
+ -26, -39, 4, -4, 42, 43, 30, -16,
+ 34, 113, 9291, -171, -17, 24, -53, -27,
+ 45, 42, 533, 146, -65, 32, 156, -144,
+ 2821, 889, -7, 614, 11, 1, -473, 434,
+ 659, -323, -2448, 23, -138, -582, 436, -152,
+ -30, 29, -290, -302, 3127, 496, 14, -346,
+ -70, 457, -1976, -229, 53, -2077, -313, 58,
+ 33, -91, -175, 141, 2728, 3232, -2150, 245,
+ -142, 13, -318, 70, -152, -64, 132, -322,
+ 44, 30, -70, -184, 433, -25, -97, -2035,
+ 145, 47, 640, 179, -441, 48, -108, 1742,
+ -280, 33, -3259, 79, -147, 324, -80, 65,
+ 48, 90, -7, -21, 22, 3, 56, -30,
+ 14, -2, -111, 22, -8, -8252, -103, -36,
+ 57, -203, 287, -2761, -220, 143, 11, -3597,
+ 21, -81, 62, -99, 41, -172, 108, 29,
+ 351, -370, 15, -122, -207, 275, -93, -2760,
+ 400, -212, 225, 230, -239, -3530, -73, 211,
+ 288, 85, -6, -634, 57, -78, 361, -149,
+ -1843, -23, 17, -37, -71, -174, -237, 42,
+ -22, -243, 63, -101, 131, 35, 136, -4025,
+ 41, -262, -57, 197, -290, 307, 35, -16,
+ 3, -5, 45, -7, 1, -47, 41, -19,
+ 79, 78, 42, -85, 74, -414, 1696, 703,
+ 297, -3296, 108, -546, 1129, 44, 447, -433,
+ 315, -1012, 133, 141, 1051, 601, -18, -532,
+ -30, 712, -127, -210, 10, 2442, -95, -46,
+ -14, 77, 32, -11, 10, -103, -15, 637,
+ -60, 352, 694, -202, 284, -5524, 92, -82,
+ 5, 140, -54, -115, 45, 287, -14, -307,
+ -342, 10, -181, 50, -30, -6, 10144, 77,
+ 42, 13, 26, -20, 34, 10, 37, -37,
+ -47, 90, -5, -44, -85, -64, -51, -1,
+ 16, -152, -91, 212, 4, -25, -237, -6124,
+ 22, -120, -1, 171, -17, -43, 141, -13,
+ -57, -185, 80, 273, -493, 178, 45, 11,
+ -57, 16, -23, -30, -37, 82, 4, -13,
+ -130, 98, 272, -450, -161, 133, 5104, 14,
+ 4576, -193, 11, 55, -30, 1, 123, -265,
+ -84, -340, -18, 152, -24, -266, 33, -90,
+ -108, -639, 1662, 299, -14, -389, 4679, -226,
+ 21, 311, -294, 159, -209, 172, 184, 292,
+ -373, 169, 84, 55, -269, 1453, -50, 41,
+ 68, -9, -62, 35, 23, -132, 96, 58,
+ -122, -3956, -318, 210, -117, 678, -104, 378,
+ -842, 61, 2549, 37, 149, -512, 70, -2971,
+ 225, -411, 230, -214, 697, -58, -871, -281,
+ -128, -204, -37, -128, 51, -174, -405, 497,
+ -4455, -219, 124, -120, 63, 135, 201, -122,
+ -435, -677, 221, 138, 486, 535, 3153, 165,
+ 11, -275, 94, -100, 69, 52, -67, -742,
+ 212, 16, -93, -428, 863, -17, -2465, 767,
+ -35, -130, 97, 1387, 34, 72, -23, -17,
+ 2845, -90, -71, 213, 291, 87, 826, -63,
+ 189, 641, -256, 832, 2087, -199, -170, -193,
+ -62, -7, 37, -60, -4277, -43, 24, -69,
+ 574, -163, -113, 263, -86, 45, 171, 1075,
+ -154, -39, 121, 74, -132, 182, 34, 13,
+ -278, -41, 96, 716, -221, -626, 1205, 244,
+ -351, 3914, -78, -32, 2833, -150, -37, 95,
+ -227, -84, -3432, 57, 238, -143, -365, 39,
+ 27, -238, -307, -170, 124, 66, -133, 40,
+ 62, -19, 42, -66, 2, -80, -2, 60,
+ 7, 10, 263, -4987, -69, -389, 62, -53,
+ -66, 24, -87, 13, 34, -15, -25, -20,
+ 197, 9, 101, -83, -79, -156, -100, 2,
+ -108, 5687, -157, 878, -1728, 32, 72, -66,
+ 70, -2, -46, -163, 206, 17, 247, 2974,
+ -66, 1354, 335, 238, -249, -410, -553, 354,
+ -41, 132, -96, 68, 2174, -329, -58, -76,
+ 6, 3089, 284, -274, -398, 471, 283, 427,
+ -220, 81, 2676, 40, -23, -46, 251, 109,
+ -3059, 50, -25, -551, 124, -389, 228, 95,
+ 56, -1320, -79, 1027, -4938, -105, -82, 13,
+ -159, 52, -101, 23, -220, -77, -153, 113,
+ -282, 42, 185, -144, -402, 46, -144, -99,
+ -2862, -3432, -2, 16, -32, 23, -25, -145,
+ 181, 49, 6, -236, -226, -28, 234, -26,
+ -89, -14, -355, 146, 117, -50, 76, -10,
+ 441, -95, -2, 346, -242, -3745, 884, -305,
+ -184, 350, 18, -293, -328, 257, 109, 49,
+ 157, -44, -70, 35, 6, 89, -4085, -167,
+ -263, -59, 35, -13, 430, -212, 17, -618,
+ -5, -8968, 114, 41, 73, -85, 122, 5,
+ 38, 19, -60, 14, -36, -42, -89, 20,
+ 85, -17, 20, 282, -3396, -25, 3722, 151,
+ -183, 100, -150, 19, -221, 126, 34, -21,
+ 72, 28, 138, -90, 30, 162, 46, 40,
+ 27, 15, -55, -21, 38, 55, 32, 83,
+ 9675, 31, 26, -2, 4, 96, -51, 120,
+ -132, 213, 2106, 39, -251, 98, -2572, -429,
+ -331, 1436, 2078, 335, -381, 371, 299, 339,
+ 300, -141, -99, -303, 2952, 49, 93, 40,
+ -3949, -45, 50, -215, 73, -39, -165, -283,
+ 46, -123, -347, 23, -158, 41, 20, 41,
+ -46, 19, 34, 86, -8770, 40, 20, -32,
+ -30, -16, 77, 72, -4, 92, -34, 103,
+ -77, 128, -532, -314, 24, 728, 49, -36,
+ -178, 76, 22, -14, -164, -194, 69, 3133,
+ 1007, -130, -280, 2502, 482, -2, 45, -62,
+ -7, -94, 17, 23, -4, 9516, -27, 11,
+ 22, 54, -13, 2, -2, 6, -22, -63,
+ 67, -686, 130, -2180, -124, 57, -61, -158,
+ 3364, 518, 4, 315, -367, -103, -295, 259,
+ -597, 56, -6, 72, -86, -45, -13, -47,
+ -13, -27, -3, 48, -12, -52, -6, -14,
+ -26, -16, -34, 9554, 80, 91, -270, 1,
+ -121, 117, 33, 8, 40, -99, -79, 43,
+ -3451, -92, -70, -57, 43, 68, 64, 284,
+ -639, 458, 118, -54, -2755, 370, -66, 54,
+ 27, -198, 331, 115, -40, -209, -312, 82,
+ -16, 8, 230, 212, 1853, -94, 1957, -118,
+ 153, -13, -73, 71, 116, -72, -3285, 106,
+ 19, -121, 177, -300, 455, -29, 94, 190,
+ -21, -8, 201, 16, 2, 83, -6280, 32,
+ -18, 59, -18, -41, -132, 22, 1, -39,
+ -212, -198, 186, 3154, -102, 3463, -280, -118,
+ -132, -132, 63, -19, 353, -24, -77, 224,
+ 82, 143, -65, 165, -16, -3774, 3543, -28,
+ -44, 93, -45, -13, -24, -5, -40, 58,
+ 3, 89, 71, 113, 46, 62, 44, 160,
+ -77, -8, -59, -6505, 134, -42, -73, 0,
+ 85, 2, 16, 34, 157, -34, -60, 78,
+ 24, 64, 96, 478, 231, -125, -217, 13,
+ 21, 44, 83, 198, -69, 21, -167, -52,
+ 4085, -234, -393, 17, -446, -354, -28, 42,
+ 53, -37, 28, 15, -16, -10, -85, 9471,
+ -16, -89, -87, -56, 52, -97, 86, -7,
+ -103, -12, 71, -39, 17, -40, 23, 63,
+ 65, -19, -14, -106, 29, 9707, -1, -12,
+ 1, -86, 100, 7, 1097, 266, 252, 197,
+ -64, -214, -197, -28, 3843, -1577, 310, -117,
+ 594, 13, 90, -309, -384, 134, -90, -194,
+ -316, 2884, 156, -185, 196, -103, 75, 1009,
+ 69, 768, -75, -605, -1488, 389, 242, 368,
+ 278, -122, -2500, 121, 7, -303, 91, -10,
+ 3642, 23, -109, -13, 138, -405, 18, -43,
+ 3, 42, 194, -112, 237, -2241, 23, 296,
+ -83, -14, -58, -163, -8, -174, -239, 85,
+ -108, -82, -79, 344, 236, -427, 127, 52,
+};
+
+static const int16_t cb1110l1[] = {
+ -64, 11, -74, -96, 39, 6072, 16, 46,
+ -215, 137, 77, 128, -195, -192, -87, 96,
+ 379, -73, 367, 437, -366, 84, -155, -29,
+ -69, -61, -34, -129, 260, -177, 3738, 739,
+ -221, -14, -40, 2, -483, -269, 2664, 166,
+ 29, -256, 30, 92, 51, 111, -45, 3893,
+ 90, -30, -99, 12, 74, 201, -52, -96,
+ -196, -85, -36, 123, -44, -68, 2, 8666,
+ 33, -41, 24, -12, -52, 69, 59, -27,
+ 38, -148, -55, -20, -60, 50, 3363, 30,
+ 3749, -92, 228, 173, -239, -167, -75, -79,
+ -86, -217, 32, 34, -137, -13, 17, -128,
+ -1462, -170, -224, -393, -3383, -1243, -47, 24,
+ -223, 26, 311, -343, -47, 784, 459, -548,
+ 558, 983, 103, 269, 32, 13, 19, -84,
+ -37, -29, -47, -6286, 7, 48, -100, 13,
+ 11, -271, -86, 115, -17, 183, 3247, -3336,
+ 57, -67, -117, -87, 19, 74, -271, 237,
+ -24, 242, 49, -179, 298, 85, -69, 328,
+ -238, -34, 103, -50, 79, 2, -27, -16,
+ -103, -61, 5868, -105, -262, 74, -74, -158,
+ 263, -110, 154, 212, -3, -84, -126, 25,
+ -67, -2501, -12, -35, 139, 259, -95, -141,
+ 137, 90, 12, -244, -142, 314, 15, -124,
+ 1, -25, -27, -2, -6, 28, -48, -17,
+ -2, 43, 67, 42, 9023, -25, 19, -13,
+ -23, -43, 73, -30, 143, -1, 2884, -142,
+ -4, 3549, -49, -366, 110, 314, 19, -55,
+ 363, 204, 469, 189, 217, -181, 119, 41,
+ -133, 29, -55, -94, 71, -49, 41, 85,
+ -14, 6140, 71, -142, 10, 18, 169, 136,
+ 282, -49, 36, 446, -99, 263, 92, 2201,
+ -127, 43, -143, -350, 36, 389, -208, 15,
+ -3610, -275, 383, 1599, -179, -177, -1100, -4,
+ 67, -38, 2, 278, 39, 107, -120, 465,
+ 204, -397, 305, 416, 7, -262, 68, 2341,
+ 189, -75, -23, 25, -20, -74, 56, -43,
+ -125, 170, 509, 63, 26, 263, -741, -31,
+ 8, -296, 101, 20, -149, 2846, -218, 379,
+ -310, 151, 901, 84, -85, -83, -387, 161,
+ -3102, -158, -438, 38, 191, -58, -202, 127,
+ 126, -88, -430, -3077, -1829, -332, 61, -152,
+ -14, -32, -156, -5, -375, -1083, -5130, 110,
+ 77, -201, -15, 4, 13, 86, 119, 67,
+ 149, 80, 264, -253, -121, 63, 193, -103,
+ -129, 63, 120, -226, -100, 3196, 72, -11,
+ 8, -56, 279, -73, -192, 47, -87, 125,
+ -43, -108, 277, 188, -107, 289, 5966, -20,
+ -303, -78, -21, 40, -139, 44, 28, 6,
+ -254, -244, 47, -1, -151, 29, -344, -2318,
+ 30, -3767, 114, 84, -155, 85, -90, 155,
+ 111, -506, 6, 453, -241, 215, 131, -802,
+ 15, -343, 176, -430, 251, -74, 6, -41,
+ -44, -131, -105, -248, 346, 39, -4524, 93,
+ -120, -79, -777, -416, -570, -221, 21, 28,
+ -52, 56, 71, -187, 2949, -2531, 666, 799,
+ -137, 970, 243, -695, -148, -281, 326, 450,
+ -734, -99, -2078, 112, -83, -90, -78, 262,
+ -138, -31, -5, -74, -171, -99, 344, 143,
+ 4035, 56, -121, -921, -8, 46, 4576, 97,
+ -219, -34, 123, -44, -1, 85, -36, 399,
+ -260, -231, 132, -318, 55, -181, 156, -3093,
+ 142, -9, -3418, -31, 43, 126, 136, 309,
+ -50, -20, 170, -90, 188, -173, 175, 50,
+ 144, -244, 22, 64, -476, -22, -66, 272,
+ 3839, 715, -188, -82, -250, -587, 10, 368,
+ -507, 242, -40, -531, 451, 35, 560, -107,
+ 138, 15, 113, 56, 242, 33, -23, -27,
+ 81, -157, 301, -327, 359, 3648, 62, -1489,
+ -167, 136, -39, 183, 53, -151, -16, -60,
+ -65, -5182, -17, -257, -10, 56, -104, 713,
+ -2, 328, 72, 353, 43, -51, -5949, 40,
+ 32, -82, -36, -22, 57, 56, 55, 112,
+ -104, 76, 5, 80, -29, 173, -360, -113,
+ 42, -119, 180, -26, 120, 250, -3024, 198,
+ 115, -140, 22, 136, 275, 698, -149, 699,
+ 426, -220, 279, 63, 55, -63, -108, -51,
+ -70, -70, 419, -156, 5870, 33, -57, -114,
+ -388, -213, -164, 1543, 117, 165, 1944, 223,
+ -83, 46, 201, 12, -103, 228, 139, -207,
+ 136, -1218, -544, -723, 90, -652, 793, -1,
+ -100, -32, -236, 49, 164, 138, 16, 82,
+ -3221, -62, -168, 62, -313, 98, -652, -484,
+ 684, -91, 33, -2926, -3453, 566, 34, 35,
+ 104, 13, 189, 235, -49, -324, 126, 226,
+ -102, 123, -253, -403, 38, 160, -5, 100,
+ -30, 16, -19, -44, 2, -70, -30, 82,
+ 118, 6, 132, -15, -36, 59, -8835, -448,
+ 3707, 324, 87, 67, -110, 114, -76, 294,
+ 354, 7, 140, 11, 340, -117, -559, 67,
+ 129, 201, -314, 328, -209, 102, -121, 378,
+ -5010, 140, 53, 15, -253, -14, 414, -183,
+ -70, -25, -51, 34, -347, -171, 146, -98,
+ -101, -3, -99, 96, 66, 50, -5, -115,
+ -23, -45, -351, -4202, 143, 480, -46, 140,
+ 17, -6312, -110, -23, 150, 60, -39, -9,
+ -48, -60, -8, -20, 37, 57, -162, 60,
+ -137, 55, -101, 65, 100, -8952, 3, -49,
+ -3, -9, 28, 15, -89, -136, 59, 125,
+ -73, -35, -111, -69, -28, 111, -16, 48,
+ 27, 9272, 55, 34, -92, 66, 3, 3,
+ -38, 12, 59, 95, -100, 3, 51, 121,
+ 146, -200, 142, -254, 65, 3, -169, -8,
+ -65, 44, 10, 15, -99, 56, -6, -108,
+ -20, -5461, -89, 395, 2085, 486, -48, 324,
+ 422, -3703, 468, 198, 239, 0, -277, -115,
+ -227, 227, -29, 159, -128, -447, -291, -1953,
+ -110, 25, 2274, 141, 177, 204, 38, -258,
+ 90, -8, -131, -2636, 55, 561, -99, -220,
+ -33, 142, -334, -160, -117, -12, -33, 6,
+ 72, -3, -11, 50, 1, -45, 8, 23,
+ -15, -33, -15, 30, -32, 107, 145, 14,
+ 60, 114, 45, 24, 8811, -9, 61, 192,
+ 16, 124, 46, -54, -31, 89, -147, -112,
+ 3341, -395, 91, -323, 45, -156, 25, -18,
+ 34, -534, 118, 83, -187, -92, 180, 34,
+ 659, 135, 103, -2342, 54, 6, 179, 40,
+ 143, 232, -3858, -201, 179, 32, -56, 406,
+ -236, 541, -70, -88, -121, 447, 3028, -223,
+ 138, -557, 230, 3457, 96, -4, -22, -13,
+ -136, -45, -123, -8, 107, 270, 132, -64,
+ -32, 464, -33, -44, -2544, -251, -246, -71,
+ -4063, 40, 107, 384, -22, -197, 64, 166,
+ -137, -44, 98, -35, 193, 4, -2103, 57,
+ -109, 245, 3487, -55, -60, 21, 187, -267,
+ 279, 3, 166, -78, 108, -135, 126, -122,
+ 171, -133, -21, -134, 183, 25, -56, -6210,
+ 107, 109, 22, -93, 39, 95, 43, -11,
+ -44, -5, -82, 6, -54, -27, -116, -16,
+ 84, 44, 22, -68, -1, -57, 78, 35,
+ 83, 4664, 46, 1, -164, 3301, -358, -3757,
+ 236, 104, -81, -121, -278, -112, -20, 89,
+ -123, 35, 113, 17, -331, 273, -172, 125,
+ -73, 77, 2515, -3944, -170, -87, 174, 84,
+ 142, 138, 13, 227, 127, 146, 141, 196,
+ 38, -40, -112, 136, 2311, 328, 87, -22,
+ -77, -34, -195, 58, -333, 337, -159, 626,
+ -3008, 408, 523, -316, 539, -587, -81, -2824,
+ 98, 200, 613, -107, -170, -1190, 1121, 521,
+ 229, -217, 143, 144, -1248, -384, 1535, 470,
+ -655, 492, -429, -26, -132, -180, 52, 97,
+ 10, -35, -60, 7, -5422, -26, 154, -132,
+ -221, 124, 136, -17, -68, 25, 29, 4,
+ 5, -15, 9, 69, -16, -47, -76, 5,
+ 41, 6, -22, 63, -8, 9709, -33, 650,
+ -545, -159, 81, -75, 54, -92, -49, -80,
+ 14, -78, -145, -399, -3935, 186, -1144, 207,
+ 60, 286, 2642, 44, 117, 3758, -154, 426,
+ 331, -615, -216, 271, -121, -109, 495, 42,
+ 813, -19, 545, -149, 633, -2424, -2089, 265,
+ -136, -58, 4, -28, 147, 2, -123, -93,
+ 14, -50, 317, 131, -130, -152, 322, 1023,
+};
+
+static const int16_t cb1110s0[] = {
+ -6433, 495, -277, -630, 411, 1241, -326, -425,
+ 523, 114, -225, -53, -538, -702, -260, -417,
+ -401, -222, -263, -416, 163, -1256, 590, -1176,
+ 1865, 1483, -927, -65, -674, 1303, -147, -750,
+ -132, 407, -283, 852, 1788, -2257, 210, -450,
+ 303, -272, -2536, 94, 2010, 428, -921, -3,
+ -71, -875, 156, -681, 521, 49, 51, -523,
+ 1532, 1619, -690, 402, -923, 318, 865, 193,
+ -2187, -662, 553, -1104, -70, -1313, 462, -1045,
+ 320, 937, -1453, -514, 404, -231, -1748, -1592,
+ -2039, -217, -364, -1313, -428, 2419, 1257, -1292,
+ 19, 2867, -278, -1832, -239, -691, -383, 62,
+ 185, -455, -1589, 116, 419, -319, -418, 537,
+ -280, -1834, 2681, -857, -210, -156, -1143, -104,
+ -1774, 1702, 184, 1017, -135, -610, 525, 335,
+ -355, -494, -231, -154, 986, 434, 1134, 1213,
+ 914, 1457, -258, -1086, 477, -2247, 498, -1741,
+ -975, -262, 812, 108, 834, -412, 120, -1032,
+ -533, -456, 139, -301, -387, -690, 798, 3,
+ -1556, 1261, 745, -4486, 8, 213, 977, -151,
+ -269, -344, 13, 544, -270, -166, -706, 672,
+ 184, -943, -1714, 1510, -739, 1891, -477, 528,
+ 1847, -1572, 420, 103, -85, 508, 231, 2024,
+ -1343, 20, 238, -655, 668, -1561, -743, -651,
+ 709, -1136, -208, 979, 258, -693, -535, -1126,
+ -283, -944, -209, 603, -1797, -2998, 253, -296,
+ 842, 63, -203, -468, 675, 337, 1458, 114,
+ 259, 3202, 145, 419, 631, 352, 2309, 1337,
+ 815, -99, -824, -779, -1839, -1455, 166, -2092,
+ 1299, 162, -1026, -914, 128, 1321, 896, -209,
+ 255, -1144, 807, -2870, -632, -588, 866, 81,
+ 453, 154, -1258, -499, -452, -98, 2599, 3070,
+ 540, -834, -228, -1268, -313, 1269, -65, -56,
+ 1035, -499, -507, -657, 447, 26, 96, -175,
+ 133, -291, -538, -259, 7, -206, 411, 145,
+ 25, 215, 267, -4354, -442, 250, -814, -143,
+ -459, -182, -640, -1258, 169, 379, -1196, 429,
+ -128, -1971, 2681, -45, 1641, 152, -556, 909,
+ 365, -618, -417, -363, -434, 270, -1388, -473,
+ 62, 58, 509, -3909, 1327, 1571, 482, 1081,
+ -896, 459, 480, -557, -267, 390, -15, 484,
+ 248, 52, 49, 702, -10, 162, 245, -416,
+ 1397, 23, 183, 325, 591, -816, 4429, 674,
+ -332, -1243, 68, 285, 235, 759, -315, 799,
+ 313, -331, -182, -629, 394, -1079, 3879, -81,
+ 651, -774, -21, -297, 231, -1826, 47, 104,
+ 284, -171, -198, -110, -193, 881, -715, 294,
+ -490, 395, -1261, 2859, -3175, -1477, 668, -215,
+ 310, 10, 762, -837, 101, 142, 201, -940,
+ 453, -82, 493, -983, 23, -211, 990, 1327,
+ 4664, -27, 821, 809, 500, 243, 41, 568,
+ 44, -320, 105, 461, 306, -408, -793, -35,
+ -18, 229, -12, -416, 577, -301, 4870, -520,
+ 499, 57, -544, -21, 611, 226, -20, -412,
+ 440, -680, 448, 430, 226, -610, -310, -218,
+ 1161, 523, -400, -148, 783, 395, -126, 370,
+ 686, -497, -301, 161, -5, 238, 375, 357,
+ -126, 954, 5952, -53, 121, -405, 1571, 435,
+ 461, -1166, -1163, 1347, 1394, 170, 2035, -1580,
+ -958, 276, -680, -968, 275, -323, 524, 48,
+ -1896, 46, -495, 548, -929, -859, 224, 1079,
+ 863, 3080, -1594, -379, 302, -403, 710, 655,
+ -293, -719, -683, -944, 228, -341, 563, -495,
+ 920, 738, -614, 552, -249, -402, -164, -262,
+ -425, -4025, 164, -984, -518, 157, -1156, -729,
+ 1024, -768, 1003, 481, -116, 319, -918, 1563,
+ -662, 4852, 617, -250, 549, -265, -93, 680,
+ 470, 925, -293, 629, 142, 231, 44, 133,
+ 12, 40, -867, 269, -77, 445, -1132, -985,
+ -1304, 728, 424, 530, -258, -625, 377, -1400,
+ -2538, -470, -1711, 413, -1603, -81, -393, -1013,
+ 1130, 906, 287, 640, 3785, -463, -159, 43,
+ -165, -441, -513, -287, -554, 1547, 848, -275,
+ 936, 653, 769, -58, -1007, -698, -792, 2175,
+ 398, 1382, -122, 459, -7, 281, 2785, -637,
+ 632, -279, 293, -1078, -996, 96, -293, -1335,
+ -74, -587, -286, -565, -977, -228, 5080, 3,
+ 171, 111, -34, -177, -619, 577, 448, -280,
+ 189, 1033, -579, 134, -713, -947, -249, -1897,
+ 364, 1748, -2098, 21, 859, -73, -1881, 116,
+ 36, 1591, 1386, -1128, -346, -1015, -25, -90,
+ -691, -984, -120, 29, -635, -236, 26, -691,
+ -742, -203, 294, -472, -901, 2582, -171, -357,
+ 406, 162, 1561, -913, 308, -3319, 461, 779,
+ -305, -927, 290, -941, 615, -688, -508, 222,
+ -432, 387, 170, -115, -5338, 508, -212, 150,
+ 26, -38, 306, -15, 50, 2008, -1112, -187,
+ 44, 591, -280, 1187, 934, -228, 554, 65,
+ -1387, -1999, -805, 2555, -1225, -283, -435, -430,
+ -50, -655, -103, 248, -234, 32, -826, -708,
+ -704, -1006, 176, 784, 274, 626, -2353, 707,
+ 1852, -132, -196, -169, -463, -2117, 56, 413,
+ -141, -818, -365, 921, -816, -126, -135, 438,
+ -948, -145, -349, 700, 205, 1001, -3626, 314,
+ -493, -1182, 131, 733, 2404, -1244, 564, -960,
+ 328, -1137, -108, -755, -168, -995, 966, -1706,
+ -565, 806, -693, 1369, -269, -428, 675, 768,
+ 341, -794, 2265, -208, -1883, -801, -1889, 961,
+ 182, -504, -595, 871, -1280, 952, 1351, 665,
+ 474, 1032, 58, 451, -198, 345, 176, -853,
+ -2891, 2250, 624, -616, 183, 144, 736, 0,
+ -198, -138, -1218, -501, -658, -24, 1232, -286,
+ -233, -937, 2150, -1035, 449, -623, -2748, -2176,
+ 918, -170, 421, 1376, 93, 153, 627, 493,
+ 28, 549, -292, -175, 1066, 1037, -475, 413,
+ -2006, -2022, -334, 365, 901, 945, -663, 515,
+ -351, -597, 155, 1318, -153, 417, -425, 44,
+ 338, -1958, -355, -596, -2134, 360, 341, 2501,
+ 824, -2106, -282, -1723, -735, -550, -743, 113,
+ 1027, -479, -2114, -16, -631, -282, -1054, 1320,
+ -158, -234, 3479, 28, 1818, 627, 1464, -795,
+ -22, 897, -6, 392, -234, -170, 714, -382,
+ 1262, 67, -618, 145, 25, -710, -247, -545,
+ -1386, -1797, -995, 865, 465, -364, 830, -53,
+ -1108, -383, -538, 85, 731, -188, -813, 2,
+ -1667, 3379, 289, 425, 1319, -259, -592, -212,
+ 271, -268, -126, 1282, 306, 3859, -1423, 607,
+ 20, 755, 174, -782, 72, -234, 675, -1177,
+ 1101, -635, -1641, 2574, -978, -1390, -1743, 2183,
+ 53, 75, 650, -97, -456, -126, -719, -675,
+ 557, -375, 643, 853, -81, -192, -1174, -1288,
+ -954, -883, -806, -2182, -2111, -1426, 180, -266,
+ -301, 626, -443, 61, -149, -443, -935, -48,
+ 642, 250, 17, 596, 1342, -2127, 323, -1456,
+ 1995, 837, -1456, -1683, 945, -722, -1445, 452,
+ 178, -441, -250, -137, -128, -50, -311, -600,
+ 2237, 922, 139, -107, -637, 1770, -2503, 413,
+ -803, 496, 209, -391, 401, 412, -552, 605,
+ -37, -667, -1609, -19, -1073, 1522, -705, 670,
+ -992, 882, -1213, -854, 2150, -371, 73, -1167,
+ -592, -153, -509, -584, -495, -83, 2075, -1489,
+ 719, 1245, -1138, 72, 950, -950, 542, -590,
+ 988, 1646, -64, 562, -223, 73, 583, -151,
+ 215, 914, 1391, -2997, 161, 436, 49, 2225,
+ 271, -283, 3844, -578, 335, -90, -698, -162,
+ 1236, -117, 470, 383, -718, 520, 295, 29,
+ 292, -179, 774, 204, 372, -251, -824, -487,
+ -1822, -312, -731, 568, -1008, -255, 189, -1195,
+ 657, -227, 3422, 651, -220, -1204, -590, 713,
+ 365, -977, 204, 3118, 321, 922, -347, 1505,
+ 375, -77, -1520, -1411, -680, -507, 543, -492,
+ -1844, 135, 689, 384, -408, 140, 633, -1192,
+ 475, 220, -1711, -1318, 606, -103, -712, -1734,
+ -218, -855, -835, -3071, -109, 1391, 62, 21,
+ -75, -77, 369, 216, -1484, 2057, 661, 314,
+ 275, 1048, 175, 1842, 743, 808, -594, 338,
+ -1217, 1606, -531, -1360, -1073, 452, -531, -798,
+ -771, -1292, -918, 606, -1776, -509, 178, 1422,
+ 3424, 634, 722, -257, 525, 437, -197, -130,
+ 291, -411, -259, -890, -84, 368, 1117, -1321,
+ -324, -2122, 515, 1158, 1749, -963, 681, 39,
+ 268, 549, 324, -601, 151, -200, 829, 3881,
+ 797, 660, -572, -693, 633, 1023, -147, -581,
+ 102, -207, -163, -511, -30, -102, 379, 776,
+ 494, -510, 55, -1811, 1073, 4384, -318, 3277,
+ 1958, -209, -539, 1823, 1200, -182, -186, 213,
+ 123, 506, -471, -431, -698, -331, -1168, 88,
+ 276, -184, 733, -295, -1053, -717, 862, -1453,
+ -4235, 1063, 1049, -621, -429, 372, 1043, 599,
+ 271, -693, -689, 122, 466, -323, 332, -533,
+ 645, 516, -371, -207, -2046, 72, -1125, -229,
+ -2769, -330, 1387, -89, 342, 2786, -730, 152,
+ 629, 809, -459, -248, -266, 111, 380, 724,
+ -411, 640, -72, 323, 34, -277, 443, 289,
+ 151, -4816, 402, -171, -731, 635, -84, -133,
+ -310, 397, 904, 1193, -1512, -25, -1306, 587,
+ 322, -3762, 537, -306, -981, 917, 190, 787,
+ -613, 149, 301, -376, 366, 350, 18, 893,
+};
+
+static const int16_t cb1110s1[] = {
+ -332, 1306, 1626, 1555, -3510, -225, 418, 1520,
+ -969, -74, -286, 233, -313, -97, 375, 181,
+ -309, 1348, 969, -504, -141, 789, -1224, -137,
+ -704, 98, 1003, 466, 2259, 1485, -225, 61,
+ 272, -223, -347, -23, -368, 96, 2345, 112,
+ 363, -552, -6, -806, -1637, -1703, 1597, -2114,
+ -196, 293, -1173, -630, -863, -1224, 784, -722,
+ 744, 885, 798, -384, 92, 298, -873, 1808,
+ 1389, 488, -1569, -1541, -3064, -734, 3, 467,
+ -987, 346, 1915, -683, 205, -487, 341, -330,
+ 274, -25, 49, -83, 1246, -405, -777, 266,
+ 121, -250, 466, -1232, -3197, -871, -638, -332,
+ 1563, 1900, -470, 556, -465, -412, 901, -86,
+ -683, -577, -1033, 808, -863, 1212, -724, 2222,
+ 429, 2733, 413, 891, 1669, 515, -439, 187,
+ -359, 414, 176, -706, 679, -63, 1247, -1721,
+ 779, -2770, -484, -633, -993, -243, 1442, -312,
+ -324, -370, 392, -407, 229, 97, 1267, -18,
+ 46, -303, -684, 515, -166, 4212, -775, -23,
+ -53, 23, 1966, -465, 231, 1195, 252, -1036,
+ 16, -824, -116, -582, -286, 470, -159, 217,
+ -456, 549, 648, 60, -1119, 221, -747, 354,
+ -628, -486, 894, 1280, -2631, 247, 430, -1703,
+ 69, -236, 147, 1445, 540, -936, 181, -163,
+ 931, -1044, 669, 2457, 519, 597, -2031, 11,
+ -1319, -4, -1190, 85, 254, -1494, 230, 1583,
+ -547, 277, -2006, -103, 1195, -2522, 1301, -633,
+ -104, -511, 573, 1628, -451, -1022, 564, -692,
+ 255, 1029, -408, 757, 172, -395, -472, -1703,
+ -1856, -379, 289, 509, -628, -1349, -207, 404,
+ -399, 1671, 392, -935, -190, 952, -1267, 1150,
+ 1562, -609, 491, -346, -270, -483, 310, 1420,
+ -1017, 1714, -645, 897, -1327, 3154, -1046, -857,
+ -499, -496, -1348, 399, 63, -653, -315, 820,
+ 1645, 614, 2202, 779, 3001, 1382, 387, -843,
+ -1840, 422, -1017, 246, -219, -550, 105, -608,
+ 426, -346, -224, 375, 22, -448, -270, -1150,
+ -897, 4298, -882, 49, 633, -937, -694, 675,
+ -322, -793, -516, -360, -248, 1190, 575, -843,
+ -13, 50, -801, 1181, 452, -335, -495, -102,
+ -1057, 506, -206, 66, -647, 991, 259, 259,
+ -468, 197, 373, -4216, -750, 224, -182, 520,
+ -530, 1888, -2018, -1492, 656, -1447, 993, -790,
+ -785, 792, 1658, 373, 131, -460, -703, 1080,
+ -875, -212, -694, 747, -639, -2267, 1263, -415,
+ -749, -1278, 591, -745, -225, -1677, 69, 625,
+ -146, 212, 345, 728, -553, 1117, 471, 550,
+ -498, -729, -2070, 1006, -330, 939, 3636, 34,
+ 349, 761, -131, 372, 610, -399, 10, 86,
+ 110, 931, -1159, -175, 633, 568, 140, 712,
+ 2800, -1558, 2343, 3, -974, -673, 233, 1436,
+ -783, 599, -442, 852, 639, 447, -976, -564,
+ 1511, 36, 529, 433, 677, 1971, 2777, -820,
+ -655, -1463, -1392, -1142, -352, 432, 730, 439,
+ -273, 844, 108, 115, 408, -361, 504, 337,
+ 58, 1074, -1645, -1623, -493, -70, -1585, 2878,
+ -741, 636, -224, -974, 722, -147, 149, 135,
+ -107, -154, -1027, -18, -989, 282, 3173, 1123,
+ -778, 1389, -591, 337, 1660, -288, 1162, -65,
+ 660, 326, 141, 358, 679, -222, 460, 105,
+ 512, 36, -854, -477, -942, -2362, 265, 2252,
+ -164, -2059, 106, 666, -420, 521, -178, 396,
+ -1836, 475, 82, 356, 207, 433, -1005, 97,
+ 385, -304, -853, 1282, -239, -2134, 83, 84,
+ 201, -1894, -1603, 683, -1957, -113, 839, 1187,
+ -313, 774, -754, 941, -739, 748, 116, 716,
+ 1134, -530, -2178, 71, -611, 1544, 3527, -3,
+ 283, 527, 457, 399, 762, 17, -279, 196,
+ -518, -160, -1204, -289, -1354, 132, -315, -290,
+ -2179, 676, -1474, -1010, -1397, 363, -45, 783,
+ 1326, -33, -109, -617, -271, -967, -103, 1867,
+ 769, 740, -818, 1011, 1411, -693, -2458, 808,
+ 806, -213, 468, 31, -70, 166, 230, -405,
+ 163, 70, 652, 1077, -190, -622, 2343, -1328,
+ 601, 928, -1661, 174, 429, -2479, 501, 503,
+ -41, 1365, 671, 1006, -1968, 7, 103, -399,
+ -382, 573, -27, 554, -2263, -3174, 277, 177,
+ 807, -328, -816, 453, -1548, 828, -327, 187,
+ -393, -745, -76, -808, 575, -8, -326, -2062,
+ 601, 566, 755, 775, 595, 419, -3925, -226,
+ 272, 368, 395, 59, 1117, 548, -649, -429,
+ 321, 549, -744, 319, 82, 135, 73, 14,
+ 374, 93, -270, -453, 177, 4991, 569, 169,
+ 111, -246, -362, -88, -49, 583, -35, 60,
+ -759, 1327, 1768, 766, -350, -880, -106, -449,
+ -113, -683, -418, -999, 992, 559, -290, -147,
+ -324, 93, -947, -3932, -37, 307, 1087, -314,
+ -293, 432, 830, -130, -208, 59, 719, -348,
+ 4511, 224, 488, -174, 588, 795, -301, -246,
+ -447, 682, 917, -1207, -503, -450, 575, -116,
+ -126, 594, -22, -101, 5, -1188, -431, 1146,
+ -3869, -72, 402, -417, -390, 350, 1141, -138,
+ 697, 77, -3255, -268, -786, -106, -1386, 400,
+ -856, -691, -438, -1550, -228, 2162, 236, 64,
+ -382, 1, 1032, 153, -659, 1563, -410, 1280,
+ 1573, -3675, -1041, 240, 401, 215, -353, -1140,
+ 265, -103, -824, -93, -319, -849, 253, -477,
+ -463, 153, -1017, 538, 1233, -1041, 11, 998,
+ -437, -569, -970, 2118, -1577, 1, 321, 1784,
+ -298, 2315, 72, -20, 83, 905, -1289, -246,
+ 731, 4076, -1477, 602, -911, 978, 698, -239,
+ 391, -729, -276, 225, 143, -417, -500, -27,
+ -1220, 89, -403, -1453, -2546, 1015, 70, 78,
+ 2364, -159, -775, 29, 37, -231, 73, 433,
+ 426, -529, 420, -613, -100, -605, 1463, 1001,
+ 1159, -4082, -553, 348, -806, 624, -162, -1121,
+ -25, 919, -62, 90, -275, 233, 203, 32,
+ 745, -221, 458, 529, 901, 1088, 38, 1209,
+ 450, 451, 2250, -411, -205, 761, 249, -1226,
+ -266, -3195, -801, -31, 1015, -324, -596, -42,
+ 150, 207, 2597, 1041, -1045, -2254, -1428, 250,
+ 217, 69, -933, 1424, 280, 446, 524, 540,
+ 639, -1027, 23, 412, 36, -67, 475, -1126,
+ -739, 1160, 514, -157, -2832, -1432, 559, 77,
+ 740, -888, 134, 1304, -267, -267, 329, 8,
+ 1721, 1488, -29, -1760, -1904, -2634, -1342, -528,
+ 2233, -219, -194, -2919, 128, 1203, -623, -127,
+ 488, -386, -133, -329, 62, 85, 1271, -185,
+ -479, -588, -2964, 546, 1651, 1526, -830, 1046,
+ 347, 63, -1048, 239, 1402, -22, 307, -1606,
+ 768, 999, 304, -512, -175, -246, -373, 529,
+ 93, -521, 1310, -508, -4366, 27, -768, -358,
+ -575, -2, -593, -21, -838, 635, 197, 634,
+ 321, -263, -377, -549, 20, 739, 395, -9,
+ -392, 70, 5679, -133, -130, -240, -678, 421,
+ -101, 412, 143, 209, 194, 216, 200, -22,
+ -748, -399, 2863, 284, 231, 691, 571, -3460,
+ -200, 312, 480, -1338, -603, 435, -308, -615,
+ 520, 178, 68, -716, 45, -593, -32, -1393,
+ -554, -1000, -867, 613, 288, 507, 202, -113,
+ 17, 93, -141, -47, 665, 559, -808, -4091,
+ -575, -193, -873, -790, 673, -608, -941, 745,
+ 1562, -1060, 988, 1192, 29, -1207, 207, 653,
+ -622, -132, 370, 1435, 1977, -1878, -119, 101,
+ -100, -154, -869, -2375, 1254, 122, 188, 877,
+ 188, -838, -355, 667, 3813, 1076, 369, -771,
+ -712, -669, -14, 107, 1027, 112, 2306, 1418,
+ 133, 1055, 377, 249, 1023, -927, 12, -1983,
+ 1174, 223, 385, 827, 1425, -1694, -1178, -94,
+ -593, -286, 1263, -671, -425, 2002, 701, 1546,
+ 547, 182, 1013, 128, 351, -243, 407, 2349,
+ -376, 445, -93, 968, -337, -601, 1342, 987,
+ -1499, -644, 521, 327, -557, 1800, 12, 285,
+ 127, -269, -1989, -449, 87, -1042, 184, -499,
+ 1231, -1664, -352, 4, 1253, 403, -1064, 837,
+ -1702, 133, 1687, -1300, 2248, 179, -847, -617,
+ 460, 450, -260, 94, -780, -675, 1209, 38,
+ 453, 857, -631, 317, 535, 1086, -196, 638,
+ -288, -389, 688, -93, 1271, -4290, -96, 445,
+ 64, -211, 148, -74, 486, -1873, 1214, 1836,
+ -708, 1800, 1644, 576, -1088, -1212, 1147, -456,
+ 173, -911, 489, -443, 644, 534, 846, -1522,
+ -786, 497, -401, -1087, 1410, 1391, 837, -253,
+ 124, -598, -254, -3945, -1169, 103, -193, 50,
+ 846, -1014, 353, 455, 784, 1343, 3055, 178,
+ -628, -148, -266, -324, -96, -190, -930, 115,
+ 475, -651, -314, -82, -236, -88, -3753, -1048,
+ -283, -178, 351, -671, 325, 1054, 28, 540,
+ 113, -73, 763, 844, 543, -6, 799, 245,
+ 176, 124, 262, -112, 1010, 361, -843, 3290,
+ -3741, 914, -1835, -259, 2467, 297, -1205, 168,
+ -1917, 156, 87, 637, -677, -955, 312, 1246,
+ -219, 92, 1090, -292, -773, 343, -523, 299,
+ -513, 1321, -536, 586, -1324, 2345, 2384, -719,
+ -936, 1389, -27, 880, 338, -127, -666, -441,
+ 1603, 143, -218, 2167, -1335, 469, -1224, 2489,
+ 1365, 568, 19, -1322, -736, 208, -494, -454,
+ 990, -250, 305, -575, 206, -168, -1177, 282,
+};
+
+static const int16_t cb1110m0[] = {
+ 429, -104, -210, 216, 361, -2586, 253, -1350,
+ 145, 2795, -5, 663, -262, 37, -122, 205,
+ 270, 321, 2623, 256, 4, -42, -37, 112,
+ -346, 20, -51, 9, -90, -3342, 78, 52,
+ -239, -454, -207, 355, -136, -19, 394, -212,
+ -166, -73, -68, 1049, -2945, 385, -545, -211,
+ 116, -15, 687, -232, 1824, -66, 133, -403,
+ -63, 3, 46, -104, -101, 136, -61, 420,
+ 149, -24, -9, 4277, -149, -166, 96, -35,
+ 1786, -1044, 115, -1326, 3381, -520, 70, -134,
+ -433, -198, 146, -615, -143, 201, 342, 412,
+ -162, 22, 111, 16, -85, 14, -120, 79,
+ -30, -84, 56, -34, -52, -147, 19, 155,
+ 17, -120, 5853, 96, 767, 262, -194, 124,
+ -180, 13, 3081, 39, 402, 90, 292, 84,
+ 1999, -16, 866, 292, 416, -314, 177, -1,
+ 68, 3, -28, -56, -54, 10, -5, -63,
+ 89, -69, -251, 70, 7523, -83, 67, 62,
+ 178, -1723, -76, 101, 369, -139, 58, 135,
+ -32, 138, 3393, -575, 586, 292, -296, -505,
+ -634, 52, 280, 78, 14, 117, -39, 77,
+ 231, 136, 14, 51, 173, -96, 5, 378,
+ -52, -4340, -263, 61, 22, -2896, -20, 180,
+ 21, 3636, -138, 104, -279, 56, -407, -8,
+ -123, 134, -95, -500, 266, -64, -43, 1,
+ -170, 31, 110, 53, 56, -5938, 151, 49,
+ -76, -166, 34, -8, 193, 198, -118, -4,
+ -44, 249, -28, -102, -3614, 49, 464, -388,
+ -744, -500, 603, -88, -19, 1606, 325, -227,
+ -277, -142, 232, -1835, 150, -89, 29, 9,
+ 76, 425, -320, 179, 231, 1720, 424, -2730,
+ -298, 666, 72, -428, -1243, -299, 93, -12,
+ -20, -96, -123, 18, 188, -1, -235, -2,
+ 3328, 107, -1489, 199, 893, -63, 46, 3799,
+ 22, -118, -127, 283, 254, -2091, 293, 331,
+ 857, -92, 46, 13, -457, 169, 851, -19,
+ -231, -8735, -62, 69, -190, -103, -31, 108,
+ 66, 95, 53, -6, 12, 19, -73, 105,
+ -40, -29, 60, -263, -107, 2233, -246, 485,
+ 342, 1732, 76, 2489, 40, 44, -300, 280,
+ -109, -107, -990, -45, 1014, -5073, 1, -169,
+ 25, -55, -340, -427, 603, 206, 151, 360,
+ 312, -44, -106, 514, 683, 98, 3331, 19,
+ -106, 106, -3383, 85, -161, -88, 8, 12,
+ -163, 183, -393, 117, -243, -498, -60, 292,
+ -322, -2105, 920, 301, 41, -19, -142, -2485,
+ 631, -289, -849, 132, 800, -255, -390, 137,
+ -850, -411, 41, -93, -8653, 9, -25, 134,
+ -66, 222, 152, 59, 29, -193, -129, -105,
+ 39, -21, 188, 111, 25, -3, 0, -79,
+ 8907, -24, -18, 37, -33, -42, 87, -44,
+ 56, -79, -67, -52, 18, -132, 1925, 309,
+ 145, -443, 1279, 200, 1215, 281, 3343, 311,
+ 390, -154, -119, -523, 19, -529, 190, 272,
+ 541, -393, 278, 161, 13, 161, 891, -65,
+ -199, -1376, -350, -1409, 340, 2115, -209, 2459,
+ 30, -509, 141, 11, -557, -1560, -1912, -234,
+ 76, 787, 2781, 45, -158, 330, -623, 655,
+ -845, -463, -119, -252, -299, -1940, 145, 17,
+ -183, -71, 98, 67, 145, -134, -88, -5,
+ -3636, 3, 34, 231, 981, 33, -953, -403,
+ 129, 215, -11, 109, -188, 51, 5176, -89,
+ -113, 60, -138, -94, 142, 216, 322, -33,
+ 350, -285, 182, 92, -16, 12, 15, 126,
+ -27, 5, -5220, -154, 13, 109, 18, -326,
+ -257, 118, 313, 342, 2289, -35, -22, 115,
+ -256, -2908, 68, 1211, 203, -735, -380, -134,
+ 249, 522, 109, -48, -5114, 32, -42, 85,
+ -99, 265, -187, -93, 373, 341, -254, 16,
+ -121, -92, -260, -80, -2, -322, 234, -96,
+ -2834, 230, 146, -264, -3287, -153, 41, -349,
+ -149, -98, 140, -115, 628, -11, 292, 4,
+ -166, 82, -4548, 116, -23, -311, 612, -334,
+ 451, 259, 559, 320, -267, 517, -139, -166,
+ 126, 27, -89, -156, 14, 63, -3, 31,
+ 109, -43, 10, -7682, 36, -23, 73, 129,
+ 0, -116, 66, 5, 137, -17, 2523, 203,
+ 431, -2729, 175, 540, 454, -175, -297, -60,
+ 348, 53, 688, -49, 133, -72, 200, -348,
+ 136, -142, -2259, -3047, -60, -737, 48, -331,
+ 85, -134, 218, -962, -278, -148, -1077, -131,
+ 53, -127, -2265, 82, -31, -262, 226, -385,
+ 83, 756, -2715, -492, -115, 663, -312, 240,
+ -318, -819, 3040, -181, 148, 165, 376, 92,
+ -233, 188, -100, 902, -401, 1005, -52, 162,
+ 219, 1831, -68, -66, -10023, -90, -23, 39,
+ -91, -231, 23, 174, 42, 79, -57, -58,
+ 18, 175, 32, 122, -185, 266, 162, 300,
+ -3158, -3381, -3, -312, 178, -24, -234, 248,
+ 68, 293, 360, -146, -30, -2, 177, 113,
+ -1215, -538, -274, 79, -2, -17, 2791, 71,
+ -1300, 93, -818, -558, -331, 115, 215, -603,
+ -202, 113, -87, 39, -277, 3564, 75, -444,
+ 201, 111, -369, -1072, 212, -276, -322, -484,
+ -700, 37, -302, 177, 86, 10, -87, 56,
+ 76, -8941, -27, -73, -133, -51, -106, -28,
+ -52, 49, 68, 26, 16, -81, -423, 2834,
+ 7, -54, -107, 144, -3812, 17, -355, 3,
+ -32, -24, 14, 76, 169, -260, 349, -159,
+ 3691, -184, 4345, -46, 146, -14, 143, -384,
+ -75, 12, 144, 105, 47, 141, -32, -31,
+ 48, 187, 74, 139, 132, 86, -15, -317,
+ -267, 3112, 1821, -363, -125, -1152, -294, -449,
+ 277, 1151, -341, 12, -41, 210, -51, 6,
+ 18, 53, 11, 37, -36, -70, 65, 44,
+ -7302, 15, -133, 56, 150, 63, 515, 271,
+ -32, 47, 41, -130, 168, -158, -239, -60,
+ 226, 247, -593, -237, -3559, 65, 623, 16,
+ -212, 26, -181, 81, 83, 26, -25, -92,
+ -5, 36, -31, 277, -263, 135, 78, -173,
+ 220, -5260, 2239, -96, -19, -95, 75, -25,
+ -64, 244, -154, -2646, -446, 980, 512, 392,
+ -402, -1050, 276, -456, -1334, 1863, 636, -1512,
+ 234, 199, 237, 363, 66, 284, 198, -277,
+ -267, -540, -329, 856, -482, -645, 178, -240,
+ -178, 6633, -5, 127, -80, -167, 307, 7,
+ 248, 13, 53, 124, 215, -310, 255, -194,
+ -3066, -22, 3524, 51, 193, 165, 82, -80,
+ 54, -191, -278, -19, 379, 285, -58, -157,
+ -168, -183, 388, -198, 191, 107, 10, -2,
+ -6148, 45, -58, 48, -150, -72, 112, -124,
+ -41, -129, 36, -66, -3311, -4092, 15, -11,
+ 93, -54, 72, -105, 131, 66, 29, -54,
+ 201, -210, 221, 47, 55, -99, 31, -3626,
+ -3623, -175, 91, -53, 40, -98, -76, 224,
+ 15, 172, 85, 103, -147, -135, -214, -313,
+ 1304, 143, 190, 19, -2526, -91, -168, 875,
+ -27, 789, 791, -462, 912, -580, 70, 1523,
+ 787, -150, 567, 2717, -5, 2943, -107, 155,
+ 32, 65, 158, 133, -191, -44, 141, -149,
+ 199, 177, 270, -14, -57, -3669, 3891, -158,
+ 239, -17, 52, 244, -343, -118, 186, -54,
+ -134, 106, -133, -116, 186, -149, -894, -22,
+ -399, 1, 288, -3988, -260, 113, 66, -276,
+ 179, -226, 119, 420, 51, -483, 551, 129,
+ 245, 2013, 639, -87, 5058, 41, -53, -116,
+ -130, -223, -104, -760, 276, 117, 338, -137,
+ -233, -65, 119, 100, -3245, 2, 3877, 126,
+ 172, -2, -72, -153, 200, -109, -62, 135,
+ 194, -82, -150, 98, 550, -251, -274, 71,
+ 160, 121, -13, -365, 356, -212, -271, 5067,
+ -203, -251, 222, 75, -131, 17, 103, -911,
+ -348, -26, 6, 110, 120, -645, 355, -649,
+ -132, -3416, 65, -1478, 461, -109, 258, -15,
+};
+
+static const int16_t cb1110m1[] = {
+ -110, 2743, -31, 86, -11, 3705, 192, -89,
+ 57, -252, -11, -212, 163, 0, -137, 405,
+ -99, -124, -137, -407, 125, 106, -922, 1567,
+ 85, 165, 241, 110, 2918, 598, -443, 812,
+ 159, 518, 555, -1886, -65, -52, -3, -27,
+ 56, -30, -126, 126, 23, 74, 157, 6990,
+ -34, 56, -257, -172, 115, -23, -616, -243,
+ -441, 34, 159, 6, 78, -119, 49, 34,
+ -133, 988, -1007, 474, 77, -274, 354, 4907,
+ 222, -16, 69, -4, 924, -18, 3535, -299,
+ -38, -83, -111, 977, -138, -1075, -444, 540,
+ 199, 202, -502, -194, -198, 249, 101, 276,
+ -89, 96, -301, 6, -4023, -70, 174, 93,
+ 192, -120, 755, -560, -22, 78, 56, 29,
+ 28, -44, 65, -4, 0, 49, -250, 87,
+ 46, 44, -41, -7035, 14, 288, 632, -259,
+ -64, 20, -178, -343, -274, 106, 2842, 336,
+ -283, 245, -612, -5, 500, 77, 2492, -250,
+ 64, 171, -988, 4, -51, -34, -555, -171,
+ -2629, 272, 2852, -162, -98, -237, -278, -489,
+ 641, -96, 7815, -139, -116, -137, -121, -314,
+ -161, 211, 76, 136, -35, -124, -27, 76,
+ -98, 133, 85, 332, -4352, 507, -14, -275,
+ -212, 308, 258, 129, -165, -197, -104, -150,
+ -104, 60, 125, 568, -3, 1694, 62, -70,
+ 109, 122, -57, -18, 8642, 100, 50, 92,
+ 17, -86, -93, -68, -121, -61, -32, 27,
+ -188, 502, 123, -81, 37, 48, 187, 75,
+ -30, -22, -224, -292, 99, -49, 4273, 10,
+ 834, -25, 225, 2773, 78, -3281, -181, 234,
+ -130, -74, 101, 214, -26, -113, -268, -168,
+ -90, -435, -26, 38, -569, -4009, -1, 11,
+ 69, 3, 249, 98, 178, 131, 300, -826,
+ 48, 337, -828, -371, 96, 312, 712, -667,
+ -70, -2070, -242, 519, -676, 143, -613, 893,
+ -2193, 471, 1071, 213, -1231, -196, -580, 155,
+ 401, 78, -64, 27, -238, 22, -73, -19,
+ 194, 60, -87, -210, -155, 244, -123, -169,
+ -4442, 169, 3132, -181, 65, 3950, -396, 209,
+ 39, -52, -26, 166, 1, -164, 143, -66,
+ 169, 46, -16, -295, 39, 42, 40, 67,
+ 25, 17, -1, -8920, -82, -42, 49, 81,
+ -61, 1, 39, -40, 18, 74, 206, -131,
+ -71, 106, 7, 88, -13, 69, -113, -89,
+ 212, -4, 4373, -34, 283, 105, 252, 59,
+ -2578, -298, 1846, -110, -105, -310, -143, -127,
+ 274, 225, 861, 262, -815, -311, -26, -685,
+ 243, -620, -374, 2992, -112, -35, 2903, -94,
+ -56, -213, 65, 383, 41, 508, -258, -103,
+ -440, -237, 428, 132, 2793, -77, -113, -58,
+ -19, -3857, -25, 40, -167, -243, -233, -41,
+ -279, 213, -22, 8, 120, 126, 159, -212,
+ -244, 183, 1605, 62, -12, -244, 519, 780,
+ 116, -3197, -992, 341, 222, 681, -357, -669,
+ 55, 1213, 100, 441, 1, -57, 232, 10,
+ -114, 318, -147, 89, 188, 448, -327, 3735,
+ -292, 875, -216, 211, 111, 160, 172, 286,
+ -3513, -849, -185, -9, 31, 442, 747, -1045,
+ 187, 704, -219, 509, 48, 69, -25, -10,
+ 75, 23, 10, 23, -32, 89, 8628, -77,
+ -19, 27, 0, -232, 22, -50, -1904, -137,
+ -169, 128, 138, 78, -443, 243, 157, -3809,
+ 231, 277, -341, 73, -70, 596, 259, 157,
+ 2197, 575, 2445, 11, -53, 118, -115, 562,
+ 108, 30, -241, 30, -394, -155, -186, -344,
+ -237, -319, -2258, 343, -311, 14, 169, 59,
+ -15, 233, 732, 365, -692, -108, 1416, -463,
+ -279, -248, -1731, -406, -278, 298, 209, 5333,
+ -198, -167, 50, 439, 142, 91, -523, 226,
+ 262, -130, -15, 573, -4, 271, -2, -47,
+ 7, -9106, -69, -44, -144, -98, 199, -181,
+ 6, 45, 47, 37, -51, -68, -50, -116,
+ -105, 49, 376, -420, 187, 2894, 29, -471,
+ -221, 455, -1, -858, 55, -197, 359, -1972,
+ -188, 921, -134, 186, -843, -2542, 322, -1,
+ -158, -352, -307, -578, -60, 143, -1302, 333,
+ 681, 1373, -1021, 18, 284, -28, 8, -57,
+ -16, 15, 58, 31, 8389, -35, 18, 77,
+ -78, 15, 36, 17, -134, -17, 316, -680,
+ 491, 38, -217, -278, 276, -299, -75, -4030,
+ -293, -507, -62, -344, 64, -438, -344, -256,
+ 341, 199, -66, 28, -17, -17, 2, 142,
+ 6, -48, -169, -27, -117, 6739, 42, -61,
+ 140, 246, 3357, -3243, 48, -55, 49, 27,
+ 4, 172, -169, 6, 69, -265, 70, 25,
+ 223, 28, 129, 231, 57, -1608, 2640, -28,
+ -197, 29, -11, 138, 621, 427, 20, 514,
+ 663, 562, 447, -158, -909, 343, -321, -257,
+ 6641, -1, -20, -70, 62, 241, 51, -83,
+ -48, -156, -266, -335, -43, 421, 350, 306,
+ 165, -541, 47, 5, -40, 364, 21, 190,
+ -4584, -125, -441, 489, -571, -47, -10, 205,
+ 60, -73, -584, 417, 233, -34, -109, 85,
+ 41, 134, 485, -171, -183, -1522, 202, 390,
+ -3112, 144, 1675, 651, 402, 1953, 120, 93,
+ -276, -1930, -197, -61, 100, 81, -250, -155,
+ -19, 336, -178, -2340, 88, -543, 226, -2507,
+ -60, -62, 218, -9, 158, -3617, -66, 32,
+ 314, -192, -121, 372, 334, 516, 412, 247,
+ -609, -1237, 312, -120, -39, 47, 61, -63,
+ -90, 4500, -191, -353, 10, 54, -163, -345,
+ 121, -318, -235, 190, -99, 181, -3369, 4,
+ -188, -87, 128, 167, -507, -1132, -666, -354,
+ 121, 43, -546, 601, -409, 181, -47, -315,
+ 127, -2845, 487, 186, -2724, 343, 177, -837,
+ 387, -84, 259, 122, -159, 88, 117, 137,
+ 79, 126, 1584, -521, -2448, 2648, -246, -75,
+ 567, 114, 244, 653, -551, -196, -623, 205,
+ 816, 48, -326, 66, -94, -33, 133, 412,
+ -241, 491, -32, -712, -249, -3756, -185, -229,
+ 248, 268, 557, 73, 164, 24, -70, -27,
+ 54, -156, -51, -47, -26, 43, 187, 179,
+ -38, -137, 218, 1916, 4614, 435, -15, 21,
+ 145, 1868, 241, 240, 299, -204, 73, -24,
+ -118, -372, -89, 23, -298, 479, 2837, 959,
+ -76, -85, -2, 28, 94, -3245, 28, -130,
+ 159, 295, 264, -419, -98, -16, -159, 349,
+ 202, -158, -2680, -210, -390, -18, -8, 364,
+ 1367, -110, 932, -232, 1348, -80, 865, -291,
+ -408, 406, -118, 6462, -55, 10, -152, -161,
+ -132, 231, 258, 135, -13, -104, 247, 207,
+ -238, 212, -19, -31, -3303, -160, -24, 3402,
+ 50, 116, -191, 97, -139, -100, 71, -49,
+ -293, 133, -120, -10, 197, 196, -516, -686,
+ 79, -52, 6002, -47, 88, -201, 146, 136,
+ 54, 162, -180, 287, 67, 70, -55, 210,
+ -1938, 635, -162, 82, -120, -456, -75, -3753,
+ -83, 176, 137, 18, -6, -281, 232, 137,
+ -167, 373, 78, -2622, -38, -293, 89, 69,
+ -3476, 8, 152, 136, 32, -15, -140, 11,
+ 6, 13, 481, -175, -228, -254, 158, -3423,
+ 206, 22, 900, 2025, 266, -402, 132, -356,
+ 558, -592, -262, -419, 1002, 73, -246, -24,
+ -3145, 3220, -33, 283, 398, -31, -25, -7,
+ 103, -93, -143, 1, 32, -497, 206, -35,
+ 1424, 114, 140, 2393, 3245, -218, -163, 113,
+ 191, -164, -215, 504, -256, 140, -364, -226,
+ -340, 91, -464, 32, 188, 4, 15, -6068,
+ 69, 109, 219, 75, 196, -24, -84, -218,
+ 27, 57, -97, 8, -338, -4, 358, 23,
+ -52, -68, 552, 4023, -255, 684, 144, 188,
+ 100, -293, 462, 553, 9, 665, 12, -640,
+ -5099, -158, -245, -74, -168, 263, -355, -370,
+ -653, -163, -473, -394, -233, 750, 17, -31,
+};
+
+static const int16_t cb1110sl0[] = {
+ -3736, -3737, -18, -285, 383, -144, -155, -204,
+ 296, -399, -663, 356, -364, 329, -330, -5,
+ -52, -88, -41, 228, -21, -45, -136, -280,
+ -109, -86, 57, 91, -212, 158, -106, -90,
+ -8192, 70, -255, 78, -8, -89, -110, -58,
+ 104, -51, -2598, 411, -94, -567, 209, -464,
+ 139, -234, -336, 754, 863, 399, 345, 117,
+ -3435, -219, 369, 59, -325, 2439, -148, 6,
+ -48, 84, -14, 71, 94, 10, 6, 73,
+ 106, -490, -200, 186, 345, -8, 99, -3687,
+ -1571, 1836, -1593, 1111, -3700, 470, -6, 401,
+ -182, -119, 438, -263, 228, 785, -361, -56,
+ -492, 465, 333, 61, 53, 234, -23, -87,
+ 39, 105, 7282, 59, -47, -57, -77, -45,
+ -172, 12, 179, -134, 37, -157, -19, -206,
+ 9, 1186, -264, 600, 350, 374, 115, -55,
+ 727, -164, -3903, -735, 586, -24, 145, -786,
+ -118, 943, 514, 396, 3435, -35, 83, 294,
+ 107, 16, -3636, -93, 360, -307, -105, -172,
+ 204, 320, -148, 410, 175, 335, 0, -178,
+ 12, 94, -47, -91, -49, -159, -155, -65,
+ -17, -159, -316, 64, 155, -260, 81, -4766,
+ -150, -116, -332, 128, 675, -105, -479, 563,
+ -101, 101, -379, 33, 37, 1, 106, 151,
+ 69, 140, -6, -74, 157, -125, -120, -33,
+ -178, -286, 60, -158, 43, -7291, -295, -68,
+ -34, -68, -58, 8, 176, -42, -212, 176,
+ -533, -62, -27, 167, 291, 59, 311, -3050,
+ 552, -493, -207, 2576, -991, -375, -102, -980,
+ 1130, -565, -199, 559, -1390, -428, -618, 70,
+ -437, -245, -1132, -1302, -453, 83, 222, -1555,
+ -178, -1396, -1176, -228, 730, -3121, -1085, 84,
+ -326, 71, -185, -315, 889, 803, -2910, -3609,
+ -639, -199, 187, 137, -622, 473, 121, 181,
+ 85, 395, 523, 589, 71, 703, 123, 361,
+ 47, -675, 299, -446, 307, 591, 3341, 64,
+ 526, -1541, -50, -1369, 701, -144, 1720, -713,
+ 562, 297, 146, -34, 1315, 956, 761, -415,
+ -1311, 637, -1263, -1096, -385, 3228, -395, 317,
+ -354, -503, 255, -526, 245, 598, 853, -269,
+ -110, 1354, 333, 110, 855, -3346, 635, 636,
+ -917, -577, 260, 147, 1041, 1273, 385, -862,
+ 1751, -1099, 80, -148, 120, -118, 5565, -484,
+ -74, 326, 291, 234, -41, 212, 192, 207,
+ -108, 198, 118, -389, 178, -151, -252, -69,
+ -243, -800, 2640, -531, 84, -301, 157, -3428,
+ 3, -418, -173, -166, -722, 207, 448, -387,
+ -504, 202, 453, 210, -203, 304, 190, -264,
+ 101, -23, 36, 74, -146, 26, 29, -33,
+ 59, -127, 22, 213, -167, 103, 8192, 183,
+ 2709, -125, 324, -964, -259, -400, -41, -430,
+ 367, 127, 266, 369, 1081, -190, -220, -1083,
+ 641, -2733, 750, 525, -623, -18, 3159, 686,
+ -278, -2083, 1680, 587, 123, -6, -266, 376,
+ 522, -433, -499, 169, 106, 2041, 174, 571,
+ -108, 129, -116, -87, -252, 89, -14, 14,
+ 120, -7874, -204, 15, 19, -110, -82, -54,
+ 66, 31, 210, 55, 339, 61, -219, -3205,
+ 1292, 80, 344, -733, 3172, -21, -55, 712,
+ -192, 38, 408, 489, 388, -343, -763, 438,
+ -1812, -6, -129, -1392, -382, -28, 105, -284,
+ -168, -462, -284, 22, 113, 1203, 3253, -589,
+ -619, 348, 113, 847, 3, -557, 460, -636,
+ -601, -742, 46, -111, 51, -66, -2867, 551,
+ 455, 898, 17, 2205, 1004, -46, -1475, -367,
+ 2849, 766, -32, -119, 624, -722, 3371, 172,
+ -330, 93, -221, 457, -453, 84, -281, -360,
+ 108, 487, -301, 166, -2611, 577, 192, 34,
+ 1105, 705, 34, 29, -3041, -898, 172, 578,
+ 307, 483, -439, -327, 360, -935, -76, 387,
+ -2485, 800, 333, 601, -712, -973, -65, -442,
+ 220, 3577, -428, -210, 565, 757, -382, 289,
+ 726, -19, -182, 384, -32, 38, -810, -181,
+ -2978, 259, -213, -473, -187, -823, -279, 1518,
+ 26, -385, 1143, -409, 1310, 676, -2472, 64,
+ -391, -102, 455, -5751, 278, 30, 64, -177,
+ -113, -170, 94, -234, -167, 101, -2, -149,
+ -131, 351, -254, -138, 149, -42, 631, -21,
+ 237, 2893, -291, 2917, -1240, 211, -215, 22,
+ -827, -160, 140, -213, 156, -250, -1233, 691,
+ 498, -30, 350, -28, -12, 217, 34, -348,
+ -70, -140, 103, -60, 353, -200, -314, -74,
+ 112, 4435, -80, -287, 413, -99, 1407, 1519,
+ -2230, 114, 3179, -523, 39, 340, -379, 373,
+ -1552, -138, -446, -106, -762, -1017, -297, -183,
+ 498, -481, 374, 271, -5609, 297, 98, -378,
+ 187, -78, -125, 333, 114, -81, 62, -145,
+ 14, 362, 518, 134, 195, 130, -34, -72,
+ -3088, -2965, -114, 585, -78, 6, 552, -633,
+ -98, -224, 980, 338, -83, -1064, 42, 106,
+ -119, 644, -293, 496, 67, 128, -129, 620,
+ 20, 526, -177, 68, 351, -3703, 1465, 905,
+ -245, 86, 511, 39, -512, -150, 239, 86,
+ 60, 39, -79, -9, -65, 77, -7993, 57,
+ -19, 56, -38, 161, -221, -129, 8, 93,
+ 52, -5622, -114, 133, 26, 64, -194, -316,
+ -143, 225, -66, -81, -74, 240, 130, 137,
+ -549, 11, 352, -53, -4029, 513, 3164, -205,
+ 127, 80, -193, -197, -36, -885, 223, -858,
+ 5, -458, 290, 459, 247, -284, -176, -748,
+ 173, 191, 114, 406, 126, 3, 91, 84,
+ 8027, 379, -56, 47, 35, 246, -143, 65,
+ -36, 8, 59, 67, -69, -421, -3492, 312,
+ -252, 261, 3367, 319, -67, 77, -346, 386,
+ 34, 237, 18, 111, 348, -547, 186, -93,
+ -3558, -178, -3801, -133, -27, -561, -308, 112,
+ -224, 272, -195, -270, -179, -165, 199, -524,
+ 681, -117, -429, 37, -5891, 94, -55, -433,
+ -354, 122, -60, 67, -200, -80, 267, -136,
+ -42, 130, -324, -25, 156, 167, -47, 178,
+ 8, 289, 157, 88, -28, -39, -262, -11,
+ 9, -113, 76, 8192, 89, 115, -298, 137,
+ 34, 0, 261, -30, 49, 274, 130, 824,
+ -944, -56, 1074, -314, -76, 527, 75, -3321,
+ 733, -798, -352, -1038, 1049, 72, -233, 312,
+ 3363, 69, 104, -149, 22, 283, -20, -101,
+ -3350, 164, -328, -362, -993, 430, 78, 125,
+ 269, -29, 362, -73, -30, -1189, 1396, 59,
+ -1285, -216, -121, 3893, 84, -464, -38, -113,
+ -369, -181, -930, -1012, 394, 120, 274, -552,
+ -800, 105, -141, -12, 241, -667, 543, -416,
+ 28, -182, 51, 905, -3964, -1213, 12, -271,
+ 378, -234, 838, -113, 56, 567, 35, 48,
+ 490, -180, 1097, 170, 2596, -28, 3098, -220,
+ 424, 885, -42, 783, -30, 907, 63, 46,
+ -131, 28, -55, 54, -46, -25, 30, 58,
+ -15, -200, -6, 11, -70, 66, -8089, 86,
+ -136, 96, -56, -101, 300, -661, -41, -201,
+ 760, -252, 955, 189, 1459, 3562, -457, 35,
+ -54, -164, -329, -1245, -830, -365, -399, -23,
+ 616, -238, -1301, -198, 335, -3400, 149, 175,
+ -97, -279, -594, -92, -915, -830, 468, 628,
+ 728, 1024, -549, 1073, 222, -142, 296, -75,
+ -168, -5, -67, -7311, -50, -256, -321, 121,
+ 358, -272, 30, 258, 105, -161, -291, 462,
+ -7, -211, -227, -104, -151, -152, -72, -98,
+ -59, -23, -98, -203, 103, 89, 239, -484,
+ 7749, 110, 35, 345, 282, -578, 140, -51,
+ -62, -238, 102, 454, 64, -107, -223, -174,
+ 285, 110, -190, -16, 1624, 142, 3813, -849,
+ 43, 234, 84, 0, -132, 131, -135, -70,
+ -1, 125, -83, 171, 109, 8044, 97, -38,
+ 143, 64, 13, 4, -225, 181, 712, 626,
+ 20, 167, -467, 186, 3801, -2179, -647, -119,
+ -112, -183, -223, 295, -438, -407, -29, 36,
+ -34, 2536, -47, -402, -33, -62, -136, 2444,
+ -152, -717, -868, 86, -2323, 931, 659, -1281,
+ -98, 638, -162, 195, -5, -40, -88, 3019,
+ 3466, -323, 316, -784, -715, 5, 188, 42,
+ 155, -608, 500, 185, 475, 100, -51, 879,
+ -891, -158, 18, -453, 380, -207, -143, 401,
+ -153, 926, -184, 2775, 3176, -797, -198, -888,
+ 405, 460, 309, 304, -114, 2386, 2319, 658,
+ -2200, 216, 435, -1210, -655, 154, 81, 538,
+ 908, 220, -118, 482, -864, -526, -241, 857,
+ -473, 774, -288, -886, 46, 250, -96, 301,
+ 120, -488, -128, -233, 422, 38, -3416, -974,
+ -243, -226, 381, 2394, 652, 3124, -205, -1303,
+ 1484, -159, -152, -1037, -105, -121, -466, -76,
+ 605, 181, -55, -326, -527, -126, 1691, 1316,
+};
+
+static const int16_t cb1110sl1[] = {
+ -743, -300, -347, -441, 85, 5282, -250, 32,
+ 28, -306, -434, 78, -178, -112, -28, -162,
+ -188, -43, 17, 94, -242, -258, -2691, -471,
+ -556, -815, 120, -57, -36, -325, 3282, -765,
+ 355, 2, -162, -454, -72, 192, 86, 219,
+ -123, 237, 135, -42, 492, -471, -114, 5146,
+ -164, 28, 77, 70, 276, -148, 333, 64,
+ -89, -46, -135, 474, -218, -119, 351, 7619,
+ 93, -80, -84, -51, -110, -223, -13, -116,
+ -160, -102, -64, -140, -376, 156, -143, -421,
+ 105, 102, 519, 1256, 786, -284, -3029, -3021,
+ -365, -515, -1358, -273, 394, 489, -242, 31,
+ 239, -1328, 169, -488, -3069, -398, 303, -274,
+ 498, -2758, -748, -208, -324, -285, 78, -386,
+ -1063, 298, 5, 693, 160, -629, 1656, 186,
+ 457, 742, 422, -3723, 1997, 1025, -24, 291,
+ -588, 16, -327, 459, -521, 421, 1279, -408,
+ -2, -1320, 101, -372, -66, 100, -605, 3214,
+ -374, -660, -371, 207, 175, -553, -574, 2962,
+ 119, -551, -140, -62, 50, -608, -237, -100,
+ 108, 101, 3258, -31, -45, 375, -161, 132,
+ 2842, 1458, 235, 800, -113, 719, -291, -29,
+ -512, -267, 53, 780, -59, 3387, -175, 88,
+ -78, -475, -536, 584, -3025, -19, -105, 91,
+ 875, -55, -771, 143, 384, 810, -372, -253,
+ 160, -128, 232, 98, 7755, 181, -19, -177,
+ 46, -39, -30, -212, -289, 75, 127, -114,
+ 80, 79, 325, -128, -436, 2547, -73, -29,
+ 1046, 344, 3340, -335, 458, 637, -175, -695,
+ -366, 294, -322, 564, 542, 209, 524, -62,
+ 444, 2827, -53, 66, -959, 84, 484, -147,
+ 158, 259, -479, 3216, 232, -68, 583, -810,
+ 107, 93, 629, -168, 143, -552, 96, -71,
+ -3903, -438, 335, -133, -186, -278, 73, -575,
+ -253, -733, -91, -8, -1149, 350, 140, 12,
+ 3935, -236, 103, 469, 610, -536, -305, 3112,
+ 13, -182, -686, 637, 525, 327, 102, -49,
+ -450, -16, -480, 233, -82, -132, -3979, 426,
+ 757, 54, 152, -701, 513, 2330, 148, 242,
+ 1709, 162, -168, 146, 0, 891, -644, 109,
+ -549, 104, -50, 275, -193, -55, -144, -117,
+ 31, -234, 68, -5369, 72, 54, 54, 119,
+ -140, 192, 286, -42, -278, -3524, -3609, 692,
+ -366, -15, 343, -885, -267, 294, -387, -215,
+ -83, -469, 790, 85, 428, -613, 114, 634,
+ 279, -570, 616, -813, -117, 3073, 3121, -717,
+ -200, 285, -1061, -44, 945, 386, -166, 494,
+ 776, 36, -25, -444, -260, 407, 3885, 1049,
+ 1348, 185, 454, -136, -2275, 1064, -271, -316,
+ 645, -1050, 483, 430, 32, 569, -676, -335,
+ -328, -2982, -370, 50, 189, 155, 1058, -119,
+ -407, -310, 461, 3293, -604, 195, 48, 68,
+ 196, 194, 547, -210, 785, -383, -410, -268,
+ -149, 192, -88, -13, 20, -80, -5146, -86,
+ -111, 40, -36, -138, 12, 239, -36, -84,
+ -512, 149, -237, -672, 3477, -3446, 1198, 220,
+ 146, -747, 242, 48, -146, -196, -335, -777,
+ -405, 620, -340, -367, -389, -108, -27, -184,
+ -2024, 518, 241, -104, 417, -1356, -1961, 134,
+ 3221, -423, 286, -60, -110, -568, 14, 76,
+ -144, 159, 704, -410, 542, -43, 223, 105,
+ -154, -141, -84, -132, -271, -235, -285, -248,
+ 480, 430, -4711, -487, -86, 482, 80, 46,
+ -239, -93, -115, -54, -1, 7, 97, -12,
+ 151, -180, 159, -63, 65, -215, 54, 5712,
+ 2886, -115, -236, 113, -25, -301, -450, -276,
+ -78, 197, -55, -278, -511, 163, 3442, -910,
+ -74, -225, -103, 63, -204, -43, -126, -334,
+ 223, 192, -131, 202, -83, 5000, -66, 441,
+ 33, 0, -116, 237, -238, -37, 445, -48,
+ 7, -1855, -1154, -251, -117, -185, 125, 1877,
+ 375, 388, -904, 202, 649, 376, -3231, 897,
+ 101, -637, 376, 16, 1, 845, -550, -610,
+ -380, -1363, -955, 71, 1303, 296, -264, -584,
+ 247, 3247, 98, 1035, -670, 416, -2008, -448,
+ -56, -169, -1787, 3314, 408, 2541, -833, -2,
+ -169, -184, 193, -575, -81, 410, -293, -478,
+ 21, 194, 223, -111, 4648, 60, 354, -593,
+ -2429, -671, 150, -350, 151, -448, -5, 386,
+ -441, 131, -339, 87, 815, 279, 51, 131,
+ 56, -3194, -170, -3899, -297, 270, 21, -215,
+ 7, 205, -305, 141, 577, 83, -289, -502,
+ -66, -96, 433, -106, -685, -194, -82, 33,
+ 98, 315, 258, -2453, -2957, 608, 672, 152,
+ -681, 1804, -74, -459, -423, 114, -1183, -100,
+ -798, 357, -79, -3418, -676, 580, -1637, -506,
+ 306, 437, 1001, 731, -885, -1276, -583, -359,
+ 650, 15, -189, 190, 86, 39, -7987, -133,
+ 324, 174, 22, 86, -144, -125, -43, -81,
+ -49, 68, 39, -204, -159, -291, -217, -68,
+ 264, 193, 406, 247, 27, -272, -168, 536,
+ -5740, -141, 38, 18, -7, 258, -111, 125,
+ 476, -364, 5, 72, -2668, -197, -605, -671,
+ -82, 201, -752, 227, 240, 345, -11, -138,
+ 551, -351, -228, -2774, -132, 1115, -1038, -18,
+ 791, -3136, 81, 219, 357, 755, 579, 26,
+ -3129, -398, -719, 193, 495, 290, -1123, 854,
+ -381, -535, 33, 232, 2340, -4577, -94, 1023,
+ -117, 39, -54, 15, -161, -860, 64, -209,
+ -597, 415, -135, -407, 1068, 894, -784, 108,
+ 267, 7506, 140, 67, 198, 74, 52, -388,
+ -184, -24, -54, -24, 172, 172, -50, -184,
+ -113, 164, 128, -39, 252, 90, 356, -313,
+ -90, -313, -355, -73, 19, 139, 141, -122,
+ -231, -4548, -157, -227, 47, 231, -421, 60,
+ -80, -3619, 4252, -354, 69, 148, 336, 446,
+ -183, 86, 248, 35, 73, 120, 157, 156,
+ -291, -523, 35, -264, 3434, 189, 495, -59,
+ 533, -343, -554, -3014, -415, 17, 436, 552,
+ -240, -394, -761, 43, -766, 46, -1119, -254,
+ 1540, 195, -298, -833, 45, -93, 61, 40,
+ -171, 167, 82, 107, 16, 40, -166, -46,
+ 120, -185, 13, 151, 8151, -235, 92, -23,
+ 214, 206, 260, 93, 163, 78, 184, -60,
+ -12, -171, -499, -151, -219, 11, -221, 221,
+ 3253, -376, -1079, -481, 763, -257, -120, -10,
+ 34, -640, 341, -2953, 528, 567, -672, -335,
+ -175, -61, 581, -260, 1159, -802, 1070, 12,
+ 168, 2305, 291, 203, -15, -569, 3247, -179,
+ 620, 339, 224, 710, -416, 512, -86, 571,
+ 439, -167, 571, -72, -144, 236, -382, 11,
+ 268, -176, -136, -337, 220, 64, 341, 361,
+ -4474, 25, 385, 453, -153, 89, -572, 245,
+ -197, 33, 75, 588, 51, -199, -74, -149,
+ 224, 210, 4689, 282, 20, -47, 129, 221,
+ -72, 27, 76, 93, 331, 215, -5, -20,
+ 74, -80, 169, 126, -40, -137, -24, -8101,
+ -23, 165, 271, 403, -34, -19, 290, -199,
+ -14, 205, 657, 301, -885, 2457, -1965, -2266,
+ -1004, -224, -554, 182, -220, -467, -611, 1012,
+ -122, 3303, -73, -205, 93, 3549, 217, -223,
+ 55, -459, 541, 286, -46, 128, 354, 137,
+ 824, -313, 32, 301, 139, -492, 170, 136,
+ -35, -752, 4613, -830, -34, 41, 344, 279,
+ 643, -394, -461, 163, -330, 199, -215, 83,
+ 1096, 613, -473, 816, 3534, 210, -772, 935,
+ -275, -600, -341, 602, 104, -598, -217, -789,
+ -2428, 870, -351, 474, 50, 321, -148, -2929,
+ 25, -135, -46, 11, -566, -3057, -664, 700,
+ -300, 256, -960, 350, -480, 414, 431, 24,
+ -51, -228, 407, 142, -321, 316, -290, 149,
+ 56, -84, -359, -118, -4948, 138, 373, -49,
+ 142, 71, -163, -13, -279, 38, -121, 35,
+ -47, -70, -43, 116, 3, -159, -11, 97,
+ -116, -62, 156, 307, -173, 7294, -143, 288,
+ -34, 671, 613, 16, -240, -229, -414, -494,
+ -43, -169, -854, 336, -991, 719, -353, -163,
+ -750, 2685, 2837, -558, 129, 2076, -47, 641,
+ -37, -93, 226, -69, 598, -284, 127, 106,
+ -426, -555, -947, 485, 54, -3175, 622, -341,
+ -544, 278, -205, -689, 391, 238, 9, 152,
+ -233, -392, 28, 36, -394, -1059, 132, 3761,
+ -480, 87, -656, 1304, 478, -272, 65, -147,
+ 91, 520, -896, 166, 62, -30, -28, 194,
+ 542, 3, 625, 1795, 3613, 1097, 1030, 906,
+ 400, 133, -127, 219, 958, 93, -546, -702,
+ 2937, -524, -270, -767, -192, 725, -897, -643,
+ 2502, 141, -1147, 257, 279, 470, -3001, -104,
+ 79, 508, 450, 265, -21, -74, -437, 647,
+ -2755, -407, -816, 620, 24, 537, -668, 604,
+};
+
+static const int16_t cb1110ss0[] = {
+ -8187, 90, -694, -168, -452, -4, -259, -332,
+ 352, -554, 43, 389, 236, 508, -175, 461,
+ -277, 118, 651, -245, 696, -1423, 368, -1417,
+ 1782, 1650, -540, 27, -461, 516, -599, -185,
+ 422, -11, -181, 19, 1809, -3226, -839, -191,
+ 468, 180, -550, 198, 2487, -923, -1335, -1008,
+ 1029, 1716, 588, 371, 902, -1214, 179, 1026,
+ 1560, 1815, -1714, 1230, -712, 1675, 1867, -154,
+ -2860, -484, 2289, -1018, 33, -1494, 614, -2340,
+ -724, -1088, -1930, -775, -876, 642, -1358, -144,
+ -2518, 62, 543, -1049, -1081, 672, 1305, -1506,
+ -86, 2920, 518, -1836, -546, -132, -45, -642,
+ 381, -404, -2206, -1211, 698, -703, -667, -606,
+ -677, -2246, 526, -1157, 177, 510, -1420, -617,
+ -1819, 1710, 1631, 1049, -1697, -495, 961, -1250,
+ 39, 482, 445, -956, -71, 977, 426, 1826,
+ 286, 36, 295, 1786, 794, -3456, 1645, -766,
+ -1580, -2435, 1108, -286, 731, -659, 960, -1759,
+ -978, 316, -350, 91, -35, -222, -1417, -53,
+ -529, -679, 681, -4700, -524, -39, -350, 196,
+ 199, 191, 653, 1344, -942, -428, 156, 173,
+ 636, -1538, 1795, 1709, -190, 1265, 164, 650,
+ 2302, -1757, 1762, 413, -851, 44, -1371, 343,
+ -3845, -122, 1864, -489, 601, -748, -402, 590,
+ -124, -1988, -1536, -999, 399, -753, 295, -384,
+ -1316, 55, -669, 262, -1157, -3766, 992, -111,
+ -2928, -1424, -98, -62, -334, -1848, 377, 1560,
+ 947, 1568, 1554, 206, 664, 2014, 2098, -164,
+ -640, -2897, -647, -1675, -2307, -254, -555, -2426,
+ 1497, 465, -1525, -1148, 55, 632, 554, 2068,
+ 451, -1532, -715, -2065, -1177, -623, 478, -88,
+ -1140, -72, -450, -248, -1111, -250, 1356, 2717,
+ -1841, 420, -1299, -1715, 746, -101, 600, 1130,
+ -903, -473, 1225, -876, 193, 694, -193, -482,
+ -1838, 94, 157, 1131, 267, -242, 2021, -39,
+ 795, -285, 438, -4322, 1097, -621, -518, -338,
+ -289, -114, -671, 1700, -477, 449, -1664, -693,
+ 1403, -3629, 1480, -991, -234, -213, 354, -269,
+ -1140, -40, 1455, -758, 1273, 497, -686, -945,
+ 59, -66, -769, -2930, 2343, 2452, -1576, 995,
+ -734, 1009, 98, -350, -1116, 545, 189, 99,
+ 566, -916, 20, 117, -807, 986, -428, 177,
+ 1247, 485, -680, 1139, -1263, -256, 4828, 89,
+ 27, -1339, -1091, 149, -641, -703, -570, -112,
+ 346, -93, -641, -97, -991, -2247, 2284, 847,
+ 2110, -1393, -315, -1468, 514, -1493, -46, 1135,
+ -1231, 39, -913, -278, -762, 1775, -684, 735,
+ -1676, 386, -2030, 2534, -2371, -1661, 1204, -111,
+ -8, -607, 1233, -1532, -1263, 1530, -537, -1728,
+ -335, 269, -614, 12, -1187, -770, 471, 373,
+ 4743, 12, 197, 610, -101, 417, -350, 551,
+ 544, -898, 387, -682, -1216, 126, 96, 94,
+ -268, 535, 126, -778, 1595, -1379, 3366, 49,
+ 460, 1772, 198, -896, 75, 253, -1376, 68,
+ 838, -1121, -578, -630, -718, -975, -565, 1303,
+ 354, -769, -38, -246, -193, -408, 41, 165,
+ 374, -87, -155, -8, -746, -430, -869, -1842,
+ -385, 281, 5119, 432, 1119, -807, 1756, 816,
+ 131, -548, -528, 1347, 478, 1482, 2942, -290,
+ 650, 1012, 163, 840, -804, 94, 2507, 1514,
+ -953, -289, 23, 1128, -895, -1009, 1871, -370,
+ 699, 659, -3069, -695, -1559, 1435, 672, 94,
+ 1496, -637, -2208, 1083, 688, 485, 251, -828,
+ 1313, -21, -1948, 230, -603, 783, -829, 524,
+ -1142, -3845, -1383, 323, 1295, 732, 759, 591,
+ 68, -1869, -756, 1727, 339, -1565, -510, 2623,
+ 358, 3071, 281, -790, 1129, 243, -588, -431,
+ 492, 372, 96, 890, -935, -727, -236, -416,
+ 171, 226, -1090, 1257, -1063, -303, -817, -1506,
+ -947, 2282, -659, -406, 79, 772, -816, -2610,
+ -1802, -1019, -816, -1886, -1306, 1365, 624, -2314,
+ -57, 1012, 215, -130, 3404, -864, 959, 202,
+ -26, -1015, -1212, -34, -408, 3494, -284, 845,
+ 275, -1005, 458, 840, -2258, -13, -129, 2536,
+ 1269, 1216, 2071, -243, 624, 584, 2192, 720,
+ 604, -1397, 766, 984, -1050, 157, -246, 438,
+ 240, -587, 1251, -649, -22, 33, 5818, 608,
+ -996, 474, -523, -454, 1252, -791, 631, -465,
+ 663, 452, 1793, 853, 39, 3732, 758, -1329,
+ 11, 2217, -136, -540, 1335, 65, -2047, 943,
+ 701, 1886, 2085, -890, -16, -184, 325, -1077,
+ -271, -1246, 391, -1686, -651, -77, 319, 292,
+ -160, 1204, 1093, 776, -310, 1512, -1196, 149,
+ 46, 593, 1738, -566, 97, -3667, -485, -683,
+ -121, -216, -149, -344, 406, -989, -311, 383,
+ 979, -828, 394, -22, -5143, -1368, -18, -433,
+ 359, 607, 996, -1144, -229, 1365, -1243, 413,
+ -591, -621, 803, 1356, -625, 1149, -234, 182,
+ -1285, -2487, 359, 2640, -1426, -66, -688, 237,
+ 1307, -361, 108, 207, 1026, -500, -1156, -1043,
+ -2192, -2232, 1790, 1135, 1742, 1494, -1156, -698,
+ 2520, -2596, -620, 431, 748, 88, 912, 832,
+ 1122, -483, 1837, 1821, -826, 1112, -424, -306,
+ -750, 1085, 260, 152, -114, -1065, -4518, -300,
+ -976, 143, 1452, 1395, 1677, 59, -51, -1072,
+ 868, -171, -26, -914, -109, -2420, -48, 69,
+ -230, 630, -522, 2274, 1265, -1612, 2570, 836,
+ -2042, -1922, 2970, 775, -320, -2486, -2935, 553,
+ 178, 994, -1054, -1321, 699, 749, 1002, 513,
+ 586, 1550, 35, 654, -995, 1743, -1049, -405,
+ -3431, 1943, 700, 555, 111, -67, 1007, 111,
+ -57, 661, 404, -628, 425, 2185, 860, -516,
+ -523, 452, 238, -1778, -378, -721, -2197, 218,
+ 864, -1031, -832, 135, -2543, -447, 789, 1117,
+ -1491, 120, 1294, -702, 627, -412, -902, 404,
+ -1843, -786, -597, 900, 1963, 22, -843, 1168,
+ -1045, -797, 764, -423, 329, 2308, -1950, 331,
+ -1090, -2466, -483, 2023, -3363, 2126, 495, 2812,
+ 1922, -1488, -1041, -798, 135, 408, 33, 563,
+ 1333, -36, -2181, -787, 709, 287, -971, 93,
+ -459, -975, 2412, 280, 2555, 32, 2217, -1825,
+ 650, 313, 585, -947, 1170, 45, 1108, -435,
+ 1092, 220, -155, 512, 460, 211, -231, -627,
+ -836, -2205, -181, -113, 130, 226, -321, -765,
+ -1327, -1190, -676, -357, 691, 232, -365, -1818,
+ -3007, 2210, 997, 601, 2156, -782, 1626, -1081,
+ -49, -616, 685, -12, 40, 3480, 563, 515,
+ 245, 51, 290, 1227, 171, -1078, 520, -483,
+ 280, -1517, -1331, 2132, -1176, -1381, -1546, 1436,
+ -852, -505, 672, -807, 623, -244, -125, -1958,
+ 516, 798, 1185, 922, 441, 651, -610, -1430,
+ -1887, 114, -869, -2024, -1627, -2276, 2008, -1224,
+ 125, -609, 371, -1104, -506, -942, -624, -478,
+ 197, 141, -242, -1051, 1532, -1269, 666, -1055,
+ 1689, 444, 1720, 16, 301, -2311, 1196, 1108,
+ 1298, -564, -1197, -1858, 439, -198, 324, -1884,
+ 3193, 2281, 201, 587, -2028, 1969, -1087, -352,
+ -87, -632, 144, 165, 68, 1150, 173, 478,
+ -837, -470, -464, -195, -205, 2111, 15, 643,
+ -453, -339, -1128, -1368, 1182, 822, 654, -2331,
+ -1668, -215, -678, -2460, 1169, -664, 777, -348,
+ 2570, -767, -563, 254, 562, -557, 4, -97,
+ 1990, 373, -780, -677, 1996, -1527, -365, -416,
+ -325, 587, 910, -3780, -553, 104, 1705, 240,
+ -719, -1717, 2765, -582, -76, 399, -1152, 2379,
+ 3169, -1153, -725, -35, -1214, 362, 1600, -724,
+ 424, -722, 472, 872, 694, -126, -1649, -1314,
+ -1814, -95, -312, -34, 780, -884, 824, -864,
+ 526, -100, 3820, -56, -452, 43, 564, 487,
+ 177, 890, -1423, 894, -552, 1438, 204, 1015,
+ -4, 327, -3327, -433, -335, -869, 1312, -488,
+ -1287, -169, 2018, 435, 73, 508, 1160, -1060,
+ -134, -1304, -341, 623, 125, -15, -1120, 108,
+ -71, -1487, -189, -3640, 1424, 1740, 1116, 579,
+ 1603, -3294, 1241, -225, 1481, 2775, 1326, -242,
+ -632, -1560, 563, 559, 138, 115, -557, 2004,
+ -1771, 717, -1052, -1115, -1634, 889, -441, 1954,
+ -164, -1507, -1312, -407, 662, -867, -896, 225,
+ 2576, -224, -107, 237, -694, 859, 192, -1033,
+ 2255, -1225, -891, -1994, -90, 339, -382, -774,
+ 1460, -1553, 648, -521, 2370, 160, 714, 54,
+ -906, 1435, -1752, -274, -523, -36, 1208, 1553,
+ -339, 1000, -178, 209, -1001, 916, 495, 310,
+ 726, 127, -391, 107, -513, -1052, -376, 297,
+ -307, 933, -233, -253, 1196, 4619, -1278, 762,
+ -13, -387, -973, 2153, 68, 362, -887, -1922,
+ -106, 298, -1127, -2601, -2184, -111, 111, -1588,
+ 1002, -365, -2226, -290, -599, 610, 551, -1368,
+ -4344, 618, -172, 349, -914, -530, -192, 718,
+ 348, -675, -884, 913, -94, 215, -834, 353,
+ 753, -811, -84, -905, -128, -483, -1782, -1255,
+ -2333, -1110, 477, -566, 346, 2018, -1644, -325,
+ 1365, -1223, 158, -1786, 566, 203, 742, 281,
+ -555, 573, -978, -459, -1671, 378, -689, 349,
+ 606, -5961, 562, -13, -223, -419, -442, -447,
+ 125, -1052, 53, 2594, -1377, 209, -1549, 533,
+ -118, -2538, 1808, -364, -37, 1221, 607, 593,
+ 309, -240, 1574, 254, 434, -141, -220, -2018,
+};
+
+static const int16_t cb1110ss1[] = {
+ 631, 3041, 1215, 2376, -1843, -103, 750, 144,
+ -87, -249, 715, -201, 758, 202, -197, -135,
+ -523, 1243, 457, -717, -700, 1662, 918, -48,
+ -1008, 180, 411, 948, 2192, 2607, -826, -962,
+ -1130, -59, -1047, -305, -325, -1032, 2096, -287,
+ 395, -1543, -268, -1218, -2045, -1674, 951, -1846,
+ -636, 263, -138, -287, -327, -2208, -664, 496,
+ 2179, 1645, 340, -601, 473, 670, 950, 2774,
+ 364, 613, -1896, -1876, -3177, -105, 506, -164,
+ 281, 718, 2419, -1077, -50, 365, -1631, -134,
+ -384, 231, 767, -285, 1268, 321, -1408, 217,
+ -409, -725, 1225, -2551, -2622, -274, 473, 2752,
+ -11, 342, -495, 1627, 79, 240, 2, -1021,
+ 640, -508, -269, 648, -116, -1283, -217, 13,
+ -1674, 2402, -879, 1791, 2753, 2386, 1195, -700,
+ -282, -428, -671, -92, 1187, -672, 1037, -1913,
+ 246, -816, -69, -2284, -712, -996, 2498, 902,
+ 809, -149, 66, 775, -44, -566, 955, -1073,
+ -1438, -894, -978, 274, -390, 5528, 1153, 17,
+ -750, 63, 545, -725, -301, -323, 661, -813,
+ -347, 739, 335, 136, 203, 342, 802, -199,
+ -818, -679, -282, 2195, -1714, -757, -154, 182,
+ 132, -1737, 405, 2394, -3727, 1349, 213, -193,
+ -2495, -1354, -629, -1171, 1429, -16, 834, -1260,
+ 160, -1892, 874, 1754, -567, 344, -3499, 1612,
+ -987, -424, -997, -1640, 594, 1058, -783, 511,
+ -604, -1480, -1754, -424, 2262, -1991, 1297, -638,
+ 350, -588, -55, 1483, -456, -567, 146, -946,
+ 731, 1541, -759, 592, 1231, -270, 171, -1975,
+ -2707, -456, -227, 392, -891, 1008, -1066, -487,
+ 231, 1372, -51, -599, -227, 696, -820, 354,
+ 1928, -48, -1302, -570, 316, -283, -848, 2563,
+ -266, 2821, 540, 553, -1272, 1120, -1164, -451,
+ 384, -1058, -1018, 1735, 992, -1220, -83, 1490,
+ 2304, 122, 1630, 1108, 1997, 2346, -647, 301,
+ -1746, -218, 313, 462, 1486, -536, -508, -463,
+ 104, 930, 605, 2116, 793, 2881, -724, -1379,
+ -53, 4458, 793, 275, -180, -516, -489, -774,
+ -265, 704, 112, 175, 112, -121, 652, 310,
+ 564, -440, 773, 1885, 927, -672, -773, 1726,
+ -614, 818, 1589, -372, -207, 499, -894, 987,
+ 796, 652, -1228, -4010, -2208, 458, 645, 498,
+ -279, -852, -1897, -1820, -35, 674, 201, 474,
+ 77, 94, 2327, 723, -1081, 261, 209, 1179,
+ -1175, 623, -1293, 2154, -117, -3707, 940, 813,
+ -1059, -335, 1306, 525, -191, -2066, -425, 19,
+ -366, 529, -145, 822, -913, 254, 424, -354,
+ -167, -2437, -1433, 603, -318, -1517, 4250, 541,
+ -1360, 450, -531, 200, 534, 1200, -222, -535,
+ -162, -1211, -116, -144, -462, -139, -482, 511,
+ 2068, -2100, 971, -1487, -1050, -3150, -701, 119,
+ 16, 1535, 272, -1184, 2242, 488, -492, -915,
+ 1660, 212, -826, -444, 1003, 2705, 3591, -174,
+ -333, -431, -59, -903, 61, 751, 1087, -45,
+ -1031, 617, 686, -15, 848, -348, 947, 396,
+ 931, 1785, -552, -920, -669, -63, -1869, 2357,
+ -1549, 807, 889, -1581, -1071, 1587, -1108, 1300,
+ -658, -625, 300, -285, -977, 1656, 4183, 1487,
+ -191, 658, -300, 497, 1378, -300, 1031, 322,
+ 114, -449, 666, 1250, 264, 125, -109, 748,
+ -503, -40, 199, -1212, -1643, -2522, 151, 121,
+ -1128, -3200, 876, -446, 878, -989, 1510, 2261,
+ -1507, 1793, -402, 30, 228, -50, 985, -1568,
+ 755, 1559, -688, 1342, -423, -1507, 96, -501,
+ 474, -2926, -2493, -131, -656, 450, 1035, 812,
+ -14, -933, 941, 1396, -957, -621, -516, 379,
+ -225, -2063, -2048, 669, 287, 1688, 1727, 299,
+ -658, 852, 745, -260, 993, 158, -1236, -1422,
+ 33, 611, -112, -323, -194, 839, -1407, -1505,
+ -2010, 1267, -355, -675, -3779, 768, -228, -643,
+ 661, 1313, -529, 962, -948, -212, 1043, 1560,
+ -174, 1744, -938, 289, 1942, -2228, -1932, 1056,
+ -590, -940, 922, 601, -853, -791, -637, -2,
+ -52, -83, -209, 1422, 856, -1141, 2500, -1195,
+ 773, 1087, -1389, 409, 439, -3674, 453, 1637,
+ -15, 1013, 2635, 1530, -1104, 440, 895, -210,
+ 1118, -6, 45, 65, -1110, -3307, -331, 478,
+ -155, -410, -721, -1234, 129, -971, -1117, -27,
+ -1132, -1289, 1888, -1112, 203, -1091, 442, -2207,
+ 501, -343, 468, -52, 385, 269, -3102, -366,
+ -469, 391, 505, 176, 356, -69, -929, 1155,
+ -280, -1264, -897, 1006, -494, 155, 36, -627,
+ 924, -816, 154, -750, -837, 5263, -1099, 91,
+ -481, 71, -681, -574, 1229, 675, 1217, 1073,
+ -695, 274, -381, -140, 1372, -524, 1164, 341,
+ -149, -856, 793, -1294, 981, -961, 371, 1178,
+ 1463, 373, 1375, -4384, 239, 136, 67, -1196,
+ -126, -1001, -228, 150, 437, -1830, 477, 498,
+ 4246, 793, -661, 260, -1810, 1405, 76, 902,
+ -844, 908, 1830, 27, -124, 257, 765, -98,
+ 592, 487, -132, 202, 675, -669, -679, 1309,
+ -4002, -206, -66, -390, -253, -190, -921, -83,
+ 1411, -417, -2560, -646, 1853, -148, 548, -370,
+ -723, 959, -906, -3058, -276, 467, -1280, 970,
+ 687, 484, 506, 1143, -1509, 828, -2169, 2931,
+ 1322, -579, 1033, 209, -979, 217, -434, -1438,
+ 314, 2384, -906, -29, -1478, -31, 574, -373,
+ 1478, -124, -680, 330, 794, -753, -977, 1151,
+ -1190, -1479, -642, 1658, -2201, -1469, 1589, 587,
+ 52, 1298, 2092, -1483, 678, 1988, 918, -648,
+ 328, 2096, -1090, 2153, -1416, 295, 537, 261,
+ 398, -1389, -399, 1105, 10, -395, 1169, -431,
+ -423, -1617, 766, -1900, -3205, 131, -746, -852,
+ 2215, -317, -232, 1079, 293, -727, 50, -446,
+ -713, -897, 768, -896, -667, -281, 377, 115,
+ 1695, -4870, 713, -393, 251, 1268, 477, -497,
+ 294, 18, -359, 556, 308, -752, -863, -216,
+ 151, -163, 695, 587, 810, 2107, -107, 921,
+ 1203, -472, 1280, 372, 110, -581, -225, -714,
+ -58, -2587, -1980, -186, -372, -1410, -1504, -1020,
+ -745, -88, 2373, -568, -2841, -2041, -1841, 2065,
+ 389, -430, 1163, -208, 569, 375, 650, 317,
+ 1114, -1036, -959, -896, 1060, 1014, -599, -1743,
+ 1121, 808, 1556, 326, -2876, -1556, -1283, 384,
+ -1102, 378, 1433, 702, 1454, -1243, -725, 224,
+ -610, -455, 1413, -1747, -2516, -572, -1455, -313,
+ 231, 780, 1531, -2475, -34, 921, -1650, 269,
+ 818, 5, 835, -209, -911, -432, -1104, 165,
+ -1638, -46, -2031, -445, 1308, 1519, -1992, 1606,
+ 956, 757, 1139, 116, 829, -1376, 209, -893,
+ 963, -569, -466, -185, -1345, 1524, 1714, 269,
+ 219, -161, 482, -1178, -3621, -831, -668, 1871,
+ -529, -983, 558, -818, 81, 555, 33, -473,
+ -187, 113, 899, -577, -1093, 1408, 902, -258,
+ -111, -648, 4340, -780, -651, 789, -92, 2310,
+ -401, 669, -213, 369, -104, -820, -290, 48,
+ -917, 71, 1070, -239, -744, 891, 23, -5130,
+ -761, 312, 319, 842, 280, 78, -149, 352,
+ -594, -361, 354, -906, 42, -1610, 835, 157,
+ -631, 1100, -297, 1081, -96, 484, -825, -2132,
+ 549, 1305, 128, -314, -1733, -265, 1285, -4061,
+ -348, -136, -940, -507, -232, -1511, -876, 78,
+ 2120, 175, 2216, 1179, 497, 335, 350, -18,
+ -1307, -387, -2207, 587, 3209, -370, 1155, 1501,
+ -1687, -796, -1417, -733, -269, 801, 83, 1173,
+ 718, -2702, 19, -315, 4501, 1025, -365, 348,
+ -417, -510, -172, -1201, 1478, 671, 1933, 1759,
+ 676, 416, 30, 400, 531, 351, -1176, -2807,
+ 1969, -1398, 1159, -568, 754, -149, -1880, -274,
+ -1203, -43, 1391, 383, 702, 2116, 1299, 1952,
+ 646, -719, 1735, -986, 100, -956, 1040, 2287,
+ -1606, 612, 1760, 733, -2453, 531, -14, -1,
+ -3214, -1993, 371, 227, 45, 2011, -531, 1089,
+ -1029, 282, -2426, -525, 989, -469, 285, 1787,
+ 927, -335, 1127, -305, 1143, -412, -1626, 1759,
+ -2567, -82, 1170, -3051, 1266, 1522, -124, -1935,
+ 552, 1122, -51, 347, -674, -360, 1183, 223,
+ 3015, 955, -826, 1108, 2325, 868, 1152, 1079,
+ 223, 217, -428, 382, 642, -2849, -767, -70,
+ 407, 147, -392, -407, -55, -508, 1785, -683,
+ -885, 851, 3879, 471, -674, -231, 1493, 1621,
+ -1698, 528, 623, 300, 1367, -588, 816, -24,
+ 600, -182, -841, 854, 370, 715, 116, 714,
+ -1308, 1435, 1802, -2627, -814, 363, -318, -73,
+ 850, -1744, 2509, -303, 1077, 660, 2145, 2130,
+ -730, -88, -115, -517, -154, 160, -337, 27,
+ 1502, 509, -70, 502, 820, -309, -3740, -1294,
+ -610, 241, -662, -524, 1319, 456, 926, 958,
+ -111, -1004, 1795, -604, 1086, 462, -127, -125,
+ 264, -1093, 1427, 334, 838, 1979, -576, 3052,
+ -3590, 1607, 356, 728, 1619, -400, 279, 570,
+ -434, 777, -1448, -888, 156, -277, -1529, 1122,
+ 2235, -794, 3417, -830, -82, -664, -1837, 946,
+ -370, 1434, -50, 742, -2368, 1438, 1264, 1172,
+ -1338, -108, -226, -958, -2130, -2, 917, 896,
+ 1563, 2181, 2684, 2343, 237, -407, -2685, 1447,
+ 1028, -728, 109, -620, 478, 46, -542, -789,
+ -879, -438, 1244, 1075, -1730, 119, -694, 137,
+};
+
+static const int16_t cb1110sm0[] = {
+ 916, -269, -44, 343, 623, -2512, -171, -1904,
+ 1001, 2776, 226, 1487, 705, 763, -616, 288,
+ -212, -535, 3080, -352, -367, 512, -673, 620,
+ -874, 769, -956, 460, -601, -2793, -102, -765,
+ -431, -1369, 149, 481, -49, 109, -412, 670,
+ -615, 287, 150, 321, -3293, -237, -1627, 188,
+ 1867, 1481, 353, -134, 2706, 147, 74, -77,
+ -148, -224, 196, -60, 179, 125, -13, 1011,
+ -189, -172, 658, 4441, -540, 531, 239, -329,
+ 2782, 392, 97, -660, 3488, -78, 1308, -574,
+ -903, -170, -279, 173, -70, 601, -385, 123,
+ -423, -512, -193, -233, 106, 175, 210, 185,
+ 489, -236, 153, -670, 25, 61, -196, 213,
+ 67, 339, 5443, 116, -647, 149, -130, 197,
+ -11, 305, 2669, 1212, 298, 84, 219, -26,
+ 2661, 650, 1348, -65, 574, -1482, -268, -30,
+ 626, 328, 279, -245, 87, 94, -202, 2,
+ 366, -505, -592, 2, 5666, 384, 22, 227,
+ 208, -1221, 78, 155, 260, -1111, 165, 396,
+ -678, -739, 2503, -2395, 2025, 1424, -343, -759,
+ -837, 101, 55, 274, -481, 22, -568, 1044,
+ -271, -124, -609, -833, -206, 53, -591, 1150,
+ -1950, -2875, 1949, 59, -334, -3230, 176, 1133,
+ -372, 2937, -803, -663, 631, -659, -32, -82,
+ 851, 113, -60, -625, 556, 177, 112, -753,
+ -33, 313, -33, -208, -177, -5496, 55, -533,
+ -815, 123, -755, -215, 638, 223, -156, -917,
+ -166, -33, 504, 704, -3001, 124, -153, -1809,
+ -977, -717, 1718, 476, 212, 1661, 953, -1422,
+ -1014, -94, -524, -2562, -267, 371, 104, -63,
+ -546, 262, 193, -1714, 261, 1867, 738, -1878,
+ 400, 1754, -445, -405, -841, -439, 709, 44,
+ 675, 248, 640, -138, 1217, 393, -1402, 653,
+ 3110, -938, -2491, -688, 1214, -649, -1356, 2506,
+ 203, 172, 679, 1003, 772, -3010, 82, -998,
+ 1011, -980, -28, -138, -430, 614, 427, -341,
+ 201, -8082, -118, 224, -1167, 195, -920, -352,
+ -657, 5, 46, -39, -72, 698, -136, -40,
+ 391, 287, 157, -1197, -60, 2808, -123, 489,
+ 152, 2318, -805, 958, 98, -1496, -835, -846,
+ 589, 455, -868, 245, -10, -5047, 12, -50,
+ 1277, -95, 456, -49, 570, 608, -658, -352,
+ -277, -268, 214, 388, 1865, 2, 3033, -269,
+ 259, -75, -3437, 800, -190, 668, -263, -111,
+ 229, -43, -139, 659, -290, 782, -18, -854,
+ 271, -2223, 30, -162, 71, 47, 756, -1269,
+ 336, 863, -1998, -16, 1172, 236, 929, -477,
+ -2446, -92, -425, -193, -8192, 321, -102, 85,
+ -85, 108, 318, 149, -27, -182, 69, -237,
+ 35, 451, -263, -890, -348, -295, 64, 410,
+ 6427, 569, 604, 543, 38, 31, -15, 148,
+ 249, -83, -67, 457, -76, -560, 694, -797,
+ 190, -113, 2006, 136, 1705, -428, 3549, -550,
+ 70, -3, -147, -288, 1142, -919, 493, -1305,
+ -460, -151, 831, 623, -768, -211, 31, -296,
+ 167, -2721, -16, -654, 243, 2555, -311, 1845,
+ -531, -576, 143, -574, 490, -1089, -2302, 1080,
+ 701, 472, 2782, 320, -1455, -632, -218, 281,
+ -1492, -661, -1379, -538, -236, -1928, -502, -565,
+ -480, 525, -81, 38, 263, 3, 366, 163,
+ -3140, 882, 189, 1123, 382, -1748, -1210, 371,
+ -602, 696, -413, -207, 358, -616, 4725, -473,
+ -784, 249, 621, 764, -265, -1004, -570, 339,
+ -643, -123, 302, 284, 1, -159, -321, 250,
+ -297, -43, -3512, -1064, -493, 556, -1184, -263,
+ 1314, 2028, 1074, 9, 2941, -998, -271, 966,
+ -754, -2589, 88, 741, -307, 134, 152, -86,
+ 311, 904, -917, 1199, -5090, 118, 181, -311,
+ -412, 475, -647, -717, -637, -221, -291, -469,
+ 77, 946, -1196, -119, -175, 530, -465, 383,
+ -1253, 589, 826, 835, -3578, -319, -80, 488,
+ -238, -497, 360, 839, 1870, 762, -1669, -769,
+ 429, 778, -3121, -325, -55, -128, 2606, -874,
+ 1043, -902, 1746, -725, 115, 167, 142, 604,
+ -101, -725, -11, -458, -27, 450, 293, 2,
+ -383, 23, 172, -6725, 400, -205, 165, 45,
+ -38, 86, 372, 354, -68, 390, 2444, 521,
+ 4, -3586, 357, 129, 665, -328, 524, 113,
+ -446, -514, 1132, 289, -560, 239, 167, -349,
+ -724, 101, -3165, -3139, -163, -147, 865, -617,
+ 0, -789, 797, -1026, 432, 359, -460, -105,
+ 1119, 486, -233, -360, -175, -349, 837, 469,
+ -250, -521, -4470, -108, 1009, -575, 283, 22,
+ -555, -682, -234, -249, -33, -106, 521, 515,
+ -283, -78, 101, -135, -648, 506, 181, 392,
+ -517, 5405, 442, -106, -8168, 51, -310, -813,
+ 49, -314, 586, -479, 376, 113, 337, -151,
+ 245, 270, -1, 619, -312, -37, -215, -482,
+ -3055, -3261, -346, -493, -357, 306, -160, -21,
+ 258, 872, -577, -141, 18, -84, 693, 151,
+ 218, -533, -37, 540, 61, 40, 3150, 157,
+ -2549, -324, 267, -456, -1236, 798, 517, -224,
+ -196, 587, -495, 18, 258, 3147, -15, -568,
+ 957, -444, 637, -354, 828, 1182, -769, -137,
+ -2130, 408, -1667, 252, 282, 201, 239, 154,
+ 125, -7882, -332, 198, -47, 265, -289, 358,
+ -4, 103, -795, 207, 82, 229, 429, 361,
+ 263, -409, -451, -1036, -3419, 899, -568, -1480,
+ 898, 284, -53, 179, 975, -1283, 759, -150,
+ 3244, 408, 2579, -418, -117, 226, 583, 210,
+ -62, -1513, -148, -820, 1073, 1290, -263, -454,
+ 653, 555, 286, 218, -105, -135, 231, -892,
+ -284, 2513, 2715, -1530, -165, -1419, -223, -66,
+ 525, 1556, -18, -664, -19, 856, 179, 535,
+ -339, -245, 498, 193, 235, 328, -491, 231,
+ -5629, 65, -85, 313, -395, 6, 344, 267,
+ 672, -991, 178, -1335, -64, 9, -1508, -69,
+ 57, -310, -1793, -850, -3669, 427, -79, -720,
+ 219, 366, 131, 523, 141, -1055, -66, 13,
+ -843, -55, -794, 661, 112, -407, -496, 550,
+ 931, -3938, 1780, -509, -543, -157, -270, -1015,
+ 564, -231, -854, -3372, -327, 869, -196, -981,
+ -205, -215, 605, 746, -2188, 2250, 74, -2979,
+ -242, 832, -190, 365, -1327, 453, 95, 76,
+ 158, -683, 628, 297, -867, -542, -143, -568,
+ -414, 6018, -40, -35, -456, -632, -779, -226,
+ -442, -295, 310, -766, 578, -197, 84, -961,
+ -3346, -106, 3266, -3, -477, -8, 652, 122,
+ -606, 49, 34, 686, 385, -258, 214, -572,
+ -72, -193, 124, 440, 48, 45, 75, 9,
+ -7724, 200, -364, 578, 318, -461, 84, -233,
+ 46, -404, 185, 470, -3387, -3397, 374, -519,
+ -320, -378, 27, 921, -280, 188, -245, -69,
+ -322, 504, -72, 460, -80, -35, -220, -3098,
+ -3678, 477, 248, -801, 580, 187, 468, -636,
+ -364, -432, 183, -82, -79, 266, -787, -740,
+ 552, 228, 238, 482, -2229, 275, 149, -360,
+ -350, 2774, 871, -118, 55, -961, -165, 2429,
+ 982, 313, -502, 3094, -431, 3485, 473, -347,
+ 171, 544, 253, -324, -50, 464, 116, 650,
+ 1102, 495, 420, -404, -1, -2991, 4055, 207,
+ 374, -187, -121, 130, -451, -953, 822, 526,
+ 287, 120, -979, 376, 594, -79, -130, -362,
+ -979, 166, 693, -4108, 84, -135, -195, -703,
+ -1506, -1098, -611, 870, 935, -156, 974, 286,
+ -86, 83, 2975, -681, 3218, -286, -452, -70,
+ -113, -395, 137, -1295, -503, 853, 297, -352,
+ -1004, -117, 476, -431, -2848, -7, 3601, 402,
+ -534, 312, 86, 1524, -358, -164, -43, 913,
+ 1003, 239, -364, -88, -468, -672, 220, -211,
+ -326, -431, 438, -297, 380, 125, -146, 4550,
+ -271, -831, 768, -1360, -45, 266, -278, -246,
+ 625, -132, 153, 514, 115, -1311, 707, -361,
+ -601, -3224, 376, -2107, -259, -1155, 426, -646,
+};
+
+static const int16_t cb1110sm1[] = {
+ 360, 3106, -518, 185, -906, 3245, 508, -91,
+ 938, -1270, -492, 36, 168, -997, -208, 991,
+ 99, 1553, -294, 204, -22, -108, -2405, 2893,
+ 49, 72, -490, -529, -218, 1343, -786, 903,
+ 411, 207, 131, -636, -129, -134, 621, -253,
+ 319, 135, -234, -75, -293, 46, 207, 5985,
+ 280, -86, -78, 690, 984, -770, -565, -226,
+ -242, 374, 26, -696, 81, -277, -9, 639,
+ -730, 250, -232, -488, -284, 460, -398, 4336,
+ -303, -266, 546, -292, 2936, 70, 2077, 373,
+ -141, 292, 2102, 340, -312, -523, -341, 1017,
+ 457, 224, 315, 271, 1080, 152, 192, 568,
+ 1014, 155, 85, 329, -5235, 137, -503, 141,
+ 275, -7, 752, 282, -267, 321, -735, 746,
+ 489, 450, 478, 432, -152, 451, -1192, 1267,
+ -341, 1136, 100, -3538, -1551, 1547, -551, 294,
+ -473, -821, -51, 718, -655, -11, 2817, -26,
+ 73, -459, -1569, 181, 516, -151, 2846, -112,
+ 186, 714, -228, -210, -451, 920, -99, -132,
+ -2662, 589, 3040, 376, 662, -834, 782, 542,
+ 1485, 538, 3531, 107, 47, 62, 398, -11,
+ -15, -733, 471, -231, 668, -212, 38, -536,
+ -1905, 2769, -149, 1623, -3418, 237, 55, -328,
+ -770, 335, 2755, 340, 62, -466, 267, -946,
+ 427, 266, 80, 1134, 34, 949, 366, -339,
+ -112, 3, -105, 442, 5117, 545, -93, 611,
+ -186, 566, -39, -172, -59, -1120, 388, 703,
+ 619, -359, -117, -68, 569, 148, -214, -245,
+ 281, 617, -2337, -88, -255, 124, 3292, 443,
+ 434, -17, -1157, 3090, -205, -245, -983, 250,
+ -1086, 643, 1392, 831, 733, -59, -1199, 1747,
+ -415, 1073, 279, 428, -512, -3392, 0, -6,
+ 526, 275, -79, 477, 411, 85, 1485, 795,
+ -209, 495, -2628, 367, -1734, 900, 301, 239,
+ -53, -2068, 403, 1333, -1304, -566, -1420, -771,
+ -2300, -15, 842, 342, -2373, 61, -1379, 303,
+ 733, -108, -316, 94, -477, -254, -211, 807,
+ 273, -792, 159, -66, -857, 1092, -1001, -69,
+ -3770, 999, 2418, 854, 173, 2281, -681, 485,
+ 578, 145, -1245, 845, -375, 219, -259, 374,
+ 751, 226, -1347, -825, 66, 319, -173, 191,
+ 445, 284, 62, -8150, -71, 53, 637, -96,
+ 227, 75, 73, -88, 654, -24, -466, 477,
+ 671, -125, -942, 104, 248, -151, -383, 11,
+ 322, 332, 4160, 108, -301, 463, -402, 352,
+ -1799, 580, 1443, 396, 287, -158, -421, 340,
+ -349, 109, 61, 47, -2816, -298, -947, -817,
+ 673, 189, 36, 4069, -584, -335, 2608, 10,
+ -378, -630, -801, 228, 946, -405, -1186, 473,
+ 625, -2, -741, 523, 3747, 318, 733, 171,
+ 268, -2554, 402, -252, -205, 292, -351, 64,
+ 289, 801, 989, 435, -100, -163, -1215, -467,
+ 661, -714, 165, -228, -637, 1357, -498, -52,
+ 488, -3882, 130, -1053, 796, 1040, 381, -729,
+ 147, 803, 169, 46, -157, 167, -209, 126,
+ -1016, 88, -1018, -458, -527, 1259, 621, 3847,
+ -525, 1247, 18, 253, 642, 340, -705, 838,
+ -2769, -672, 153, 115, 453, 773, 9, -2285,
+ -291, 6, -219, 628, 284, -330, 568, -240,
+ -206, -127, 273, 373, 367, -494, 8192, -595,
+ -255, -158, -326, -60, 513, 334, -667, -549,
+ -110, 2, 573, 1086, -610, -368, 259, -3611,
+ -455, 1577, -524, 11, 904, 390, 313, 707,
+ 2670, -223, 2710, 593, -25, 228, 540, 663,
+ 740, -1108, 298, 1223, -531, -1978, 248, -661,
+ -341, -910, -2434, 111, 217, 748, 231, -305,
+ -419, 1873, 1094, -936, -1741, 1133, 1881, -671,
+ 41, 268, -1826, 466, 135, 37, -200, 4623,
+ -1212, -969, 541, 1278, 652, 1061, -759, -747,
+ -427, -107, -1329, -583, -255, -67, -311, -10,
+ -421, -8192, 322, -181, -442, 76, 176, -742,
+ -175, 147, 385, -275, -87, -704, -545, -315,
+ -414, 569, 81, -387, 628, 2954, -604, -1459,
+ -29, 1693, 840, -1024, -66, -317, 266, -2465,
+ -917, -14, 151, -369, 366, -2388, 1, -773,
+ 1333, -99, 223, -694, -1169, 917, -2496, -1290,
+ -286, -1007, -508, 734, 451, -256, 266, -105,
+ -143, 439, -120, -146, 7690, -183, 188, 68,
+ -385, 7, -278, -24, -66, 292, 137, 143,
+ 21, -495, -527, -284, 89, -1584, -64, -3664,
+ 286, -2258, 80, -932, -771, -338, -830, -1029,
+ -99, -32, -800, 351, -87, 600, -93, 133,
+ 389, -690, 269, 201, -328, 5489, 558, -702,
+ -487, 210, 3107, -3628, -96, -388, -169, -221,
+ 339, 403, -816, -24, 469, -112, 560, 844,
+ -441, 698, 169, -378, -283, -924, 2842, -479,
+ -694, -117, -94, 523, 974, 1356, -638, 590,
+ 820, 2164, 247, -532, 648, -243, -599, -67,
+ 5686, 174, 78, -608, 230, -172, 369, 342,
+ -113, 111, -345, -311, 594, 350, -260, -1423,
+ -425, -407, -1017, -298, -180, -738, -891, 66,
+ -3312, -1157, 1, 811, -1431, 612, 797, -1344,
+ -890, -959, 318, 392, -190, 735, 196, -347,
+ 61, -116, 344, 243, -411, -446, 62, -128,
+ -3386, 476, 2695, -193, -39, 1960, -7, 909,
+ -118, -2275, -28, -997, -210, 374, -586, -82,
+ 914, 323, -73, -2743, 858, -65, 43, -2444,
+ -246, 145, 78, -638, 844, -2079, 352, -332,
+ 615, -779, 270, 1799, 680, 500, 686, 1168,
+ -397, -2233, -31, -163, -18, 602, -232, -915,
+ -941, 3708, -337, -559, 315, -401, 42, 26,
+ 316, -100, -191, 36, 206, 214, -3336, -407,
+ 494, 749, -491, -162, -55, -2902, -1515, -198,
+ -311, -359, 439, 359, -935, 203, -214, -2401,
+ -607, -2843, 818, -579, -2066, 388, -514, -912,
+ 787, 564, 149, -103, -757, 389, 173, -303,
+ 154, 814, 1631, -393, -2264, 1664, -802, 904,
+ 541, 784, 1063, 1152, -2510, 297, 84, -154,
+ 160, -497, -78, 1503, -598, -543, 86, 1683,
+ -330, 46, -24, -892, 747, -3336, -393, -2268,
+ 107, 710, 1682, -277, -278, -276, 1253, 327,
+ -986, 802, 191, -732, 286, -761, 1008, 461,
+ 1615, -1041, 2127, 2456, 3927, -160, 187, 31,
+ -101, 3258, 202, -75, 330, 375, -301, -275,
+ -782, 949, 12, -621, -617, 572, 1007, 414,
+ -91, -428, -392, -985, -692, -3422, 199, 845,
+ 91, 418, 290, -983, 721, -1265, 208, 1200,
+ 91, -758, -2649, -451, -814, -623, -458, 272,
+ 2777, 809, 1282, 763, 1122, 21, 520, 50,
+ -1018, 428, 385, 6149, -255, 8, -12, 21,
+ 20, 293, -315, -446, -423, 549, 428, -56,
+ -497, 101, 653, -177, -3975, 56, -127, 3214,
+ 291, -384, -721, 478, -314, -231, -469, -362,
+ -682, 765, -308, 420, 456, 322, -54, -2,
+ 10, -239, 6916, -461, -482, -211, -286, -110,
+ -877, -711, -470, 159, 260, 59, 252, -97,
+ -2978, -646, -35, 156, -123, 360, 556, -3254,
+ -475, -313, -268, -1771, -538, 203, 967, 283,
+ -653, -565, 387, -3097, -255, 25, 295, 264,
+ -3716, 505, 1024, -315, -215, -222, -780, 660,
+ 431, -341, -521, 46, 127, -244, -772, -3741,
+ 190, -335, -17, 2135, 744, -35, 627, -1115,
+ 681, -343, 123, -1534, -86, -542, -297, -82,
+ -2772, 3914, -75, 526, 124, -523, -112, 500,
+ 863, 371, 190, 1036, 141, -1011, 373, 796,
+ 421, -682, 403, 2924, 3730, 6, 211, -691,
+ -167, -391, -655, 162, 348, 216, -227, -535,
+ -147, 367, -189, 331, -191, 159, 49, -4905,
+ -252, -290, 609, -452, 1042, 1027, -645, -159,
+ -633, -542, -925, -262, -91, 192, 1266, -2,
+ -164, 587, 188, 3434, -1014, 2, 1373, 1832,
+ -1224, -965, 831, -987, 1180, 1389, -925, 48,
+ -3239, 263, -329, -660, -733, 262, -988, 598,
+ -2421, 630, 720, -925, -455, 208, 1092, -294,
+};
+
static const int16_t cb1616l0[] = {
-15, -7707, 115, 30, -36, -27, -22, -43,
2, 5, 31, -1, 87, 2, 41, 21,
@@ -1625,6 +5553,2220 @@
-275, 100, 0, 2484, -482, -128, -144, -206,
};
+static const int16_t cb1616sl0[] = {
+ -46, -5073, 119, -68, 8, -160, 201, -15,
+ 55, 44, 44, -197, -110, -83, -90, -66,
+ -29, -128, 2449, -182, 2226, 298, -69, 189,
+ -167, 199, -78, 60, -154, -169, -242, 189,
+ 214, 132, -41, 169, 222, -130, 209, 20,
+ -154, -327, -3458, 186, 1356, 672, 133, 100,
+ 375, -491, -52, -87, 153, 537, 2513, -349,
+ 47, -27, 118, -301, 250, 45, 191, -150,
+ 279, 2367, -70, 191, -301, -206, -5, -40,
+ -201, 3680, -67, 36, -341, -133, -197, -383,
+ -101, 21, -68, -1240, 69, -8, -7, -16,
+ 28, -47, -145, -169, 32, 170, 246, 149,
+ 3039, -2617, -42, -95, 184, -74, 71, -56,
+ -22, -85, -203, 129, 97, -105, -91, -304,
+ 4, 93, 89, 2724, 2809, -178, 52, -155,
+ -152, 149, 47, 182, 124, -75, 24, 256,
+ -38, 53, -135, 63, 70, 59, -59, 7,
+ 6, 46, 8192, -157, 142, 81, 121, 136,
+ -87, -147, -71, 59, 57, 119, 21, -1938,
+ 46, 186, 100, -158, -52, 34, 95, 22,
+ 20, 179, 112, 116, 234, 2551, -3012, -167,
+ -93, -379, -90, 24, 208, 257, 253, 23,
+ -1361, 209, 75, 191, -23, -115, 2024, 264,
+ 77, -159, 77, -219, -237, -154, 13, 273,
+ -3338, 122, -205, 3796, -96, 103, -136, -60,
+ 115, -81, 19, 69, 396, 225, -280, 86,
+ 329, 284, 505, 403, -37, 203, 310, -2587,
+ -2374, -241, -17, 492, -42, -32, 261, 112,
+ 123, -33, -1271, -112, -41, 12, 82, 67,
+ -71, 56, -10, -83, -28, 15, -12, 42,
+ 2292, 297, -235, -3, 528, -57, 159, -185,
+ -54, -84, -152, 775, 15, 54, 451, -294,
+ 53, -2, 141, 39, -65, 75, 149, -5460,
+ 17, -58, -126, -281, 264, 151, 362, -98,
+ 62, -2361, -2560, 173, 42, -290, -161, -96,
+ -52, 82, 130, -86, -150, 48, 20, -57,
+ 52, -2263, -96, 2662, -66, 21, 74, -37,
+ 22, 323, 64, 270, -141, -599, -300, -121,
+ -12, -128, -96, -3, -129, -4339, -293, -55,
+ 31, -82, 8, 82, -20, 58, 15, -238,
+ 140, -125, -98, 7632, -14, 96, -129, -12,
+ -39, 85, 0, -104, -225, 24, 3, 95,
+ -87, 115, 168, 19, 22, 95, 8056, 36,
+ -12, 106, -99, -15, -87, 112, -122, 55,
+ 14, 282, -31, 80, 42, -4, 81, -73,
+ 74, -10, 82, 35, 173, -20, -40, -8192,
+ -35, -386, 270, 263, -231, -142, 42, -445,
+ 204, 177, -330, -859, 715, 2731, 59, 2578,
+ 220, -478, 3, 410, -47, 61, -214, 2765,
+ -206, 174, 56, 427, 442, 118, 2708, -66,
+ -40, 41, 119, -65, -71, -21, 124, 106,
+ -18, -2586, -35, 106, -364, 286, -16, -178,
+ -146, -82, 157, 92, -4, -437, -131, -85,
+ -27, -90, 23, -58, -5332, 115, -69, -25,
+ -14, 13, 52, 14, -286, -13, -60, 16,
+ 19, 53, 35, 7, -21, 7, 231, 48,
+ 2495, -82, 2836, 44, -134, -76, 33, -394,
+ 47, -124, -175, 95, 103, 161, 57, -37,
+ 174, -499, 131, -394, 2007, -2596, -481, 294,
+ 152, 601, 144, -438, 109, -204, 317, 37,
+ 362, -153, 216, 269, -39, 1250, 505, 505,
+ 2571, -115, -595, -806, -998, 1226, -71, 26,
+ -67, 262, 51, -161, 183, 1622, -32, 233,
+ 3, -217, 19, -16, 209, 51, 40, -40,
+ -43, -27, -7227, 13, -128, -18, 82, 154,
+ 133, -121, 33, -66, 8, -102, 71, 8,
+ 2780, -43, 79, 3212, -282, -165, 125, 78,
+ -101, -59, 59, -136, 308, -61, -295, -241,
+ -29, 27, -326, 2932, -563, 308, -269, -34,
+ -158, -26, -64, -411, -75, 420, -294, -239,
+ -11, 429, 44, 36, 69, -200, -56, 279,
+ 80, -218, -294, -294, 252, 64, 7793, 7,
+ -155, -56, -3118, -2749, -178, 62, 441, 105,
+ -45, 23, 23, -101, -109, -26, -149, 566,
+ -29, -394, -850, 1699, 1986, 243, -665, 565,
+ 155, -1746, 96, -344, -651, 387, -363, 283,
+ 241, 101, 71, -18, -9, 43, 114, -22,
+ 9, -109, -119, -92, 117, 8192, -67, 87,
+ 174, -42, -195, 527, -155, -195, -167, -1619,
+ 2638, -824, 121, 44, 138, -808, 407, 584,
+ -217, -90, -278, 549, -118, -1278, 837, 220,
+ 142, -956, -294, 89, 2627, 269, -129, 253,
+ 10, 15, 167, 163, 87, -262, 89, 48,
+ 14, 24, 2967, -175, 2550, 51, 11, -152,
+ -111, 230, -267, -79, 321, -641, 507, -32,
+ -20, -238, 23, -322, -2506, 173, 2205, -91,
+ -21, -1594, 420, -157, 97, 64, 126, -38,
+ -84, 10, -85, 93, -21, 272, -427, 30,
+ -60, 61, -81, -40, 27, 18, -29, -208,
+ -70, -8192, 16, 15, 53, 34, 49, -26,
+ -2512, -152, 23, -77, 3015, 87, -164, 247,
+ 119, 91, 444, -43, -166, -26, 253, -93,
+ 50, 408, -3274, 913, 104, 119, 17, -54,
+ 42, 19, -294, -298, -416, -82, 38, -263,
+ 137, 132, -2609, -44, 2783, -34, -9, 266,
+ 8, 18, -183, 520, 515, -93, -159, -21,
+ 186, 27, -89, 137, 77, -60, -33, 34,
+ -5115, -44, -172, -122, -9, -104, 69, 16,
+ 94, 2813, -200, -142, -50, 375, 3276, -272,
+ -44, 47, -41, -188, 263, -237, -24, 312,
+ 120, -326, 823, 193, 410, -95, 356, 565,
+ 296, 1202, -2737, -968, 87, -204, -1329, -826,
+ -827, 584, 194, -31, -12, -109, -39, -7,
+ 73, 29, 24, -12, 256, -98, -46, 63,
+ 207, -8, 73, -342, 4578, -37, 60, -66,
+ 8, -39, -176, -125, -34, 57, -141, -52,
+ -39, -128, -50, -143, -85, -107, 19, -38,
+ 74, -40, -161, -54, -63, -3452, 176, 116,
+ 5274, 19, -42, 198, 3, 33, 80, -99,
+ -111, 11, -90, 97, -6, -3, -52, 301,
+ 2335, 148, -171, -88, 44, -404, 124, 4,
+ -80, 189, 2838, 62, -247, 394, -230, -91,
+ 92, -2587, 84, -139, -31, 3014, 25, 201,
+ -137, -64, 383, 2, -70, -115, -210, 43,
+ -1111, -403, -379, -9, 243, 77, -220, -60,
+ -38, -15, 7, 109, 41, 143, 56, -211,
+ -2492, -48, -218, -115, -321, -358, 388, -10,
+ -172, -52, 177, 2996, -96, 480, -23, -15,
+ 177, -225, 217, 10, 367, 129, -45, -114,
+ 23, 257, -48, 2497, 236, 12, 197, 245,
+ 19, -173, -321, 310, 406, -280, -72, -279,
+ 73, 3307, 245, 78, -186, 2928, 264, 263,
+ -227, 50, 172, 91, 293, 24, -148, -245,
+ -61, 219, -88, 169, 220, -99, 3222, 3,
+ 0, 103, 19, 116, 69, -180, -7, -49,
+ 26, -59, -93, -68, 123, 357, 241, -3308,
+ -297, 198, 40, -80, 285, 161, 90, -46,
+ -165, -32, 87, -5676, 254, -37, 7, -20,
+};
+
+static const int16_t cb1616sl1[] = {
+ 73, 78, -64, 76, 17, 6250, -4, -167,
+ 52, 4, -3, 11, -189, -19, -136, -220,
+ 15, 6, -420, -2205, 38, -2944, 16, 118,
+ -116, 61, 119, -390, 217, 548, 24, 161,
+ -24, -2342, -148, -159, -2783, 225, 401, -226,
+ 210, 643, -366, 240, 264, 167, 115, 827,
+ -39, -161, 30, -173, 42, 29, 98, 377,
+ -58, -163, -41, 27, 25, 4368, 87, -2836,
+ -175, -71, -62, -84, -476, 4, 2466, 113,
+ -2830, -916, 593, 276, -356, -427, -686, -215,
+ 2752, 395, -9, -345, 117, -122, -327, 92,
+ 107, -106, 32, 270, 271, 171, 3138, 198,
+ -46, -70, 46, 502, 91, 77, -19, 216,
+ 94, 122, -64, -392, -31, -2696, -364, -131,
+ -315, 129, -461, 229, 192, 236, 185, -263,
+ -173, 44, 24, -267, -40, -177, -149, -2471,
+ 26, 113, -183, -1693, -188, 48, 22, -73,
+ 50, -133, 58, -70, -173, -308, -442, -188,
+ 92, 389, -35, 167, 235, 66, 2593, 2435,
+ 244, 630, -22, 235, 112, -32, 533, -158,
+ 81, 71, 44, -59, -158, -23, 28, 8192,
+ -58, -181, 39, 220, -54, -124, -59, -277,
+ 71, 41, -82, -157, -6860, -4, 44, -84,
+ -48, 134, -193, 159, -45, 218, -47, -133,
+ 147, 1749, 765, -84, 184, -317, -286, -17,
+ -340, -262, -244, -21, 3122, 290, -127, -119,
+ 179, -128, -125, -439, 2766, 1917, 85, 57,
+ -32, 373, -16, 170, -74, 31, 425, 626,
+ 1, -511, 64, 387, 142, -621, 183, -224,
+ 220, 1195, 386, -3360, 332, 484, -1112, -96,
+ 187, 43, 1838, 39, -36, 13, -132, -8,
+ -1, -43, 29, -132, -19, 10, 10, -218,
+ -3659, 119, -103, -27, -29, -108, 13, 181,
+ 39, -117, 92, 37, -17, -198, 330, 538,
+ 17, 113, 4758, 1, 28, -10, 87, 22,
+ 96, -14, -99, -56, -130, 0, -55, 45,
+ -63, -2845, 2751, 464, -31, -62, 76, -154,
+ 88, 81, 125, 373, -348, 587, -314, -278,
+ -53, 2039, -516, 2437, 191, -212, 87, -2,
+ 181, -242, 117, 23, -63, 334, 145, 454,
+ 343, -235, 91, 69, -8, 2, -106, -108,
+ -5, 137, -168, -7818, -231, 25, 37, 75,
+ -138, 56, 142, -596, 130, -114, 3293, -366,
+ 290, 160, -2, -219, 83, 843, -18, 1289,
+ -177, 226, 667, 252, -683, 816, 26, 157,
+ 168, -487, -49, -3282, 432, 184, 1207, 23,
+ 164, 544, 965, -1, 61, -118, 92, 1359,
+ 89, -3234, 15, 496, 244, 177, -613, -160,
+ -23, -195, -111, -372, -115, 278, 96, 77,
+ -2567, 49, -423, -468, 13, -484, 1345, -298,
+ 194, -123, -248, -139, 738, 102, 1154, -335,
+ 2694, 1326, 213, 758, 17, 154, 609, -518,
+ -367, 201, -144, 61, 66, 2288, 50, 2688,
+ -87, 45, -13, -101, 127, -190, -40, -286,
+ 6, 121, 32, 31, 119, -85, 28, 93,
+ 8192, 273, 169, 44, 37, 255, -224, 219,
+ -34, -127, -134, 165, 169, 126, -188, -52,
+ 98, 15, -5820, -193, -331, -395, -1, 49,
+ -187, 55, -121, -196, 114, 10, 258, -145,
+ -14, -385, 105, -187, 59, 383, 5322, 147,
+ -110, -69, 378, 138, -352, -69, 15, -267,
+ 75, 162, -6, 3148, 515, 231, -74, -436,
+ 1288, 1234, -105, 68, -96, -166, -49, -64,
+ 144, -67, 135, 258, -71, -162, 156, -366,
+ -7, -67, -133, -20, -119, 71, -84, 31,
+ 26, 116, -2237, 212, 43, 380, -74, 13,
+ -7, 774, -1276, -103, -124, -48, -178, -319,
+ 26, 435, -111, 858, 295, 1601, -2727, -242,
+ 8, 36, -61, -20, -19, -19, 31, 258,
+ 21, -14, 381, -153, -8192, -99, 327, 72,
+ 175, -1181, -271, 104, -30, -135, -169, 21,
+ 29, -182, -25, 125, 165, -82, 73, -26,
+ 2311, -85, -2983, -125, 85, -206, -100, -100,
+ 36, -3, -77, -180, 35, 0, -170, 123,
+ 168, -302, 366, -334, 2936, -70, 404, -2870,
+ 13, 79, 226, -163, -242, -124, -40, -171,
+ -109, 189, 20, -52, 144, -1869, -88, 230,
+ -8, -27, 45, 131, -11, -188, 93, -227,
+ -452, -229, 158, 377, -9, -1736, 16, 3268,
+ -164, 41, 305, -414, -642, -111, -100, 118,
+ -155, -236, 936, -114, 51, 31, 60, 1299,
+ 5, 3048, 274, 273, -197, -289, -245, -288,
+ 1927, -7, 27, 307, 174, -243, -95, -134,
+ 14, 24, -119, -132, -2811, -254, 35, 95,
+ 22, 135, 21, -155, -80, -143, -60, -6,
+ 182, 77, 11, -197, -8, -6080, 28, 155,
+ 11, -27, 22, -48, -8, -50, -122, 11,
+ -34, 342, -1, 40, -208, 117, -35, -69,
+ 150, -3944, -425, 46, 456, 182, -451, -219,
+ 38, 15, -203, 766, -232, 243, -70, 179,
+ 2107, -222, 346, -166, 143, 239, 245, 59,
+ -137, 17, 475, -68, 2679, -423, 20, -313,
+ 74, 152, 171, -269, 68, 39, -4743, 94,
+ -3, 110, 134, -168, 73, 180, -116, 276,
+ -74, -203, 2, -83, 17, 170, 96, 169,
+ 75, -5541, 46, 20, -168, -22, 35, -74,
+ 104, -153, 264, 4, -57, 94, -192, 161,
+ 15, 7, 45, -186, 15, -125, 121, -4981,
+ -254, 179, 282, 72, 543, -97, 363, -5,
+ -67, -389, -66, 178, 427, -276, -2675, 447,
+ -2, -125, -223, 2869, -502, 117, 2017, -71,
+ 41, 9, 124, 19, 357, -562, 25, -385,
+ 80, -53, -175, 2532, -73, -2990, -164, 57,
+ -128, -254, 53, -150, -180, 16, -45, 322,
+ 266, -2418, -264, 317, 371, 5, 197, 7,
+ -2476, -93, 152, 90, -165, 11, -259, -24,
+ -55, -16, 98, -4904, -116, 53, 205, -45,
+ -57, 116, 75, 161, -55, 97, -292, 27,
+ -1396, 105, -127, 133, -265, -33, 5, -3622,
+ 25, -3, -104, 8, -283, -229, 236, -208,
+ 145, 627, -240, 118, 296, 108, -309, 48,
+ -3345, 582, 498, 259, 20, 785, -138, 421,
+ 97, 370, 161, 141, -2793, 106, -246, -140,
+ -172, 42, -194, -202, -319, -107, -24, 423,
+ 7293, -109, -13, -242, 55, 171, 13, -93,
+ 131, -141, 88, 132, 76, 176, 78, 153,
+ -63, -55, -410, -39, 6, 27, -223, -174,
+ 61, 645, 167, -35, 3079, -173, 950, 1,
+ -109, -118, -106, 15, -1345, -14, 50, -70,
+ -69, 24, 109, 182, 84, 31, -179, -93,
+ -3152, -3013, -60, 56, -60, 58, 166, -161,
+ 24, 129, 1, 181, 128, -12, 273, -43,
+ -1256, 134, 159, -36, 175, 43, -49, 41,
+ 48, -38, -45, 59, -36, -82, 48, -74,
+ -104, 2944, -124, -24, 98, 248, -146, -231,
+ -241, 72, -114, 776, -498, 242, -357, 250,
+ -102, 7121, 109, 11, 94, -53, 37, -37,
+ -133, 24, -157, 47, -46, -69, 62, -79,
+};
+
+static const int16_t cb1616ss0[] = {
+ 1401, 373, -516, 330, -711, -752, -475, -224,
+ 139, 492, -556, 4629, 1039, 333, 872, -542,
+ 474, -360, -378, -3459, 254, 1199, 113, -525,
+ -1705, 231, 46, 188, -50, -1038, 32, -198,
+ -109, 619, 1071, -1601, 1002, -411, -189, -3276,
+ 615, -468, -467, -275, -1286, 736, 541, -1107,
+ 423, 191, 439, -205, 17, -87, 500, 176,
+ 262, -341, -142, 268, 8164, -2, 112, -190,
+ 227, -50, -143, -326, 647, 601, 482, 443,
+ 2761, -497, 979, -298, 454, -2927, 746, -735,
+ 3921, 480, -167, -317, 1303, 111, 216, -961,
+ 110, -595, 244, 246, -222, -205, 46, 61,
+ -798, 258, 360, -7038, -654, -95, 75, 498,
+ -24, -250, 71, 138, 527, 240, -215, 250,
+ -408, 552, -325, 333, -989, 2648, -483, -1121,
+ 2344, -1647, -116, -901, 615, 327, 1, 497,
+ 411, -138, 332, 281, -145, 337, 163, -7379,
+ 70, 265, 365, 238, 604, 99, -149, 233,
+ 109, 827, -704, 1367, 1208, -717, -17, -223,
+ 15, -3259, 53, -485, -631, 285, 511, -8,
+ 242, 547, 129, 145, 2046, 520, 44, -177,
+ 382, 283, -169, -346, -2737, 294, -1311, 145,
+ 1873, 815, 1078, 677, -3419, -434, 484, 144,
+ -27, 669, 153, -242, -242, 814, 350, 361,
+ -462, -63, 2317, 1259, -373, -489, -534, 300,
+ 867, 2621, -117, -168, -414, -239, 812, 840,
+ 112, -463, -6286, -693, -830, 140, -168, 448,
+ 549, -149, 418, -105, 137, 31, -40, -43,
+ 422, -99, 297, 3, -220, -15, 81, 45,
+ -647, -535, -448, -731, 250, -6742, -320, -350,
+ -192, 1540, -1112, -1043, 1317, -1203, 1035, -506,
+ 673, 721, 854, -1487, 780, -294, 1173, 2142,
+ -8192, -170, -138, -54, -54, -233, -127, 145,
+ -233, -185, 87, 20, 530, -305, 141, -394,
+ 310, 40, 645, 809, 4801, -186, -432, -451,
+ 312, -144, -65, 65, 135, -64, -15, -357,
+ -3546, -1299, 216, 249, 261, -207, 117, -3138,
+ 527, 14, -142, 286, 100, 340, 581, 157,
+ 234, 739, -2521, -3, 639, -1440, 131, -3796,
+ 159, 39, 41, -659, 284, 165, 1100, -346,
+ -481, 295, 806, -227, -288, 4520, 253, 487,
+ -252, 88, -43, -1612, -5, -57, -66, 18,
+ 19, 557, -337, 1526, -2897, 144, 844, -404,
+ 1976, 787, 246, 264, -406, 778, -918, 51,
+ -113, -235, 518, 602, -307, -2046, -692, 2775,
+ 400, -2165, -184, 139, 403, -1855, -1317, 289,
+ 710, 1124, 1888, -517, 276, 190, 637, -441,
+ 717, 972, -370, 478, 626, -354, 241, -3651,
+ 145, 7, -738, 397, 991, -343, -826, 142,
+ 672, 2425, -616, -3278, 751, -193, -944, -35,
+ -1061, 1258, 631, -721, 145, -112, -69, 828,
+ -39, -196, -237, -73, 771, -195, 239, -533,
+ -1673, 3477, -559, 104, -647, -798, 167, -497,
+ -559, 591, 259, 300, -25, 422, 93, 39,
+ -63, 233, 144, -1170, 142, -456, 73, 411,
+ 6920, -338, -307, 436, 143, 420, 152, -9,
+ -1788, -1096, -2998, -727, -524, 128, 460, 782,
+ -102, -576, -138, -976, 1035, -3196, -436, -27,
+ -1047, -1389, 3244, -143, -883, -1012, 4, 327,
+ 16, 411, -497, 1444, 516, 1183, 252, 510,
+ -698, -676, 569, -70, -397, -227, 7829, 312,
+ -410, 20, 41, -65, -219, 175, 297, 40,
+ -1534, -498, 194, 871, 409, 280, 1098, -1471,
+ -2825, 931, -105, -545, -801, -795, -372, 73,
+ 331, 100, 488, -2101, 560, 44, 885, 1065,
+ 380, -195, 276, 124, -87, 193, 3979, 30,
+ 95, -509, -931, 2737, -457, 805, 10, 53,
+ -73, -203, -587, -177, 242, 238, 656, -3403,
+ -380, 2364, 2902, -226, 204, 1559, -2219, -40,
+ -442, 111, -703, -424, -252, -241, 461, 749,
+ 658, -481, 125, -366, 601, -246, -286, 132,
+ 297, -232, 5231, -141, 196, -121, -235, 406,
+ -199, -174, 87, -107, 363, 272, -563, -620,
+ 235, 223, -627, -339, -467, 349, -1596, -5496,
+ 644, -96, -81, 1938, 749, -160, -1976, -1436,
+ -1056, -1045, -1098, 2327, 976, -57, -124, 1139,
+ 275, -209, -636, 298, 2484, 2764, 962, -39,
+ 108, -718, -442, 9, 797, 1123, 1092, 1179,
+ -1170, -701, -381, -237, -1266, -1045, -337, -351,
+ -274, -981, -272, -111, -3409, -387, 421, -406,
+ -2123, 623, -18, 2473, 617, 176, 26, 1402,
+ -1351, 212, 23, -172, 296, 1572, -63, -402,
+ 837, -521, 2209, -613, -329, -309, -180, -1152,
+ -535, -1380, -2617, 475, 385, -672, 182, 92,
+ -2211, 320, 109, -633, -582, 1208, -1536, 1009,
+ 896, 1991, -374, 1750, -1259, -341, 1774, 1063,
+ 678, -2084, 987, -337, 48, -205, -82, -288,
+ 388, 217, 1263, 2427, -1472, -1073, -964, -836,
+ 2086, -161, 438, -449, -37, -926, -3706, 164,
+ -372, -616, 160, -572, -725, 727, 11, 53,
+ -84, 7494, -74, 523, -172, 464, 452, -426,
+ 803, 106, -262, 32, 298, -491, -181, -760,
+ -908, 303, 747, 1316, 272, 906, 767, 105,
+ 247, 6120, 948, -557, -928, -595, -342, -450,
+ 686, -815, -1243, -157, 572, 1414, 166, -229,
+ 3317, 1940, -283, 623, -781, 717, -212, -707,
+ 30, 3635, 1147, -696, -928, -637, 925, 797,
+ 843, -1359, 214, 1096, 1031, 852, -84, -228,
+ -34, 1067, -1109, 392, 292, -755, 3495, -40,
+ -1806, -637, -236, -602, -264, -147, -68, -233,
+ -55, -2005, -271, -647, 963, 309, -5, 56,
+ -275, -398, 34, -496, 2556, 1249, -87, -112,
+ 1663, -554, -1926, 627, 2515, -1128, -566, 1539,
+ 740, 38, -614, 272, -232, -152, -782, -420,
+ -304, -2313, -33, -944, -77, -3468, -69, -1730,
+ -21, 665, -314, -1640, 660, 661, 106, -21,
+ -1505, -2888, -427, -866, -666, 3128, 786, -55,
+ 739, 112, 8, 567, -602, -350, 165, 108,
+ 767, 64, -715, 980, 673, -186, 768, -545,
+ -298, -233, -524, -70, 511, -2051, 3816, -1104,
+ 529, 1012, 2577, 777, 342, -387, 2730, 247,
+ -20, -227, -432, -263, -885, -1192, -644, -259,
+ 2314, 38, 108, 614, -386, 470, -78, 681,
+ -3334, -1049, -300, 177, -174, -422, 110, -641,
+ -406, -472, 468, 885, -730, -877, -1972, -1372,
+ -410, 545, 543, -800, -1156, 279, 3290, -1305,
+ -213, -262, -832, -994, -1110, 718, -364, 1416,
+ -7, 963, 452, 680, 165, -3815, 903, 806,
+ 149, 11, -1332, -622, -451, 152, -618, -309,
+ 246, 435, -2098, 487, 469, -451, -1574, -204,
+ -187, 552, -333, 515, -331, 1452, 278, -2691,
+ -146, 1009, 353, -839, 6, -3206, -1080, -572,
+ -2698, 752, -1726, -318, 397, -152, -128, -77,
+ -36, -506, 456, 1094, 281, -158, -19, -149,
+ 48, -2831, 2042, 2545, -161, 619, 1129, 274,
+ 24, 1, 313, -164, 655, 157, 770, 182,
+ 1942, 241, -898, -1748, -589, 256, 322, 683,
+ -65, -73, 621, 74, -317, 2585, 185, -465,
+};
+
+static const int16_t cb1616ss1[] = {
+ -3218, -607, 1665, 1100, -563, 421, 377, 445,
+ -270, -3, -1503, 224, -593, -316, 31, 362,
+ 1186, 389, -1817, 589, -2842, 289, -1925, -356,
+ -228, -148, 618, 135, 358, 238, 1, -767,
+ -266, 1, 101, 245, 231, -167, 408, 1,
+ 162, -35, 241, 215, -4702, 486, 546, -339,
+ 349, -292, 1342, -881, 184, -675, 2639, -284,
+ -995, 346, -499, 1499, 1616, 578, 445, -78,
+ 844, 1800, -686, -414, -1425, 795, 754, -1418,
+ -178, -2226, 515, -143, 43, 569, 967, -2333,
+ -1991, 282, 528, 1410, -377, 736, 394, -230,
+ -365, -242, 2773, 136, -738, -36, -1171, -76,
+ -132, -300, -223, -680, -416, -2738, 93, 414,
+ 490, -346, 75, -1089, -1132, 2237, 1844, 395,
+ 325, -1514, 1913, -1850, 1162, -442, 689, -66,
+ -71, -83, 342, -197, -940, 206, -3381, -1275,
+ -423, -87, -455, 498, 865, 355, 1225, -115,
+ -3333, -404, -588, 1021, -2180, -1470, 1225, 728,
+ 59, 2592, -335, 194, -649, 3586, -951, -142,
+ -947, 898, -99, -269, 977, 1520, 488, -364,
+ -253, 127, 2524, 849, -1166, -191, 627, 372,
+ 772, 145, -21, 279, 402, -863, -2695, 1217,
+ 1543, 1005, -1419, 1712, 110, -2191, 969, 1563,
+ 183, 811, -218, -1078, -220, -1092, -322, 803,
+ -533, -359, 405, -70, -771, -267, -4730, 235,
+ -607, -387, -285, -68, 48, -60, -222, 229,
+ -1087, -1261, -2249, 1265, -1624, 864, -65, 223,
+ -322, 337, -262, -3170, -12, 4571, 19, 198,
+ 458, -1029, 2560, -3, -115, 619, -645, -836,
+ -399, 246, -81, -12, -1057, -2119, 2780, 25,
+ -1559, 291, 592, -513, 62, 157, 553, 570,
+ -657, 72, -118, -284, -454, 3853, 145, 259,
+ -1709, -2161, -3167, 189, -233, -1099, 141, 114,
+ -506, -1012, -775, 474, 331, 798, 469, 1915,
+ 96, -266, -385, -329, -658, 192, 16, 97,
+ -47, 284, -163, 200, 189, 18, -7453, 160,
+ -2988, 2725, 520, -132, 2593, 627, -694, -26,
+ -558, 44, -209, 40, 377, 491, -68, 384,
+ 271, 2117, 642, 3166, -569, 702, 513, -1858,
+ 108, 944, 248, 166, 681, 408, -908, 525,
+ -145, 1035, 189, 2812, 135, -356, -2551, 401,
+ 150, -508, -265, 244, 461, 958, -233, -204,
+ 744, -1603, 397, -229, -174, 539, -139, -4473,
+ 837, -310, 253, -635, 397, -80, 601, -371,
+ -2015, -261, -364, 50, 331, 89, -938, 709,
+ 1444, -2910, -228, -162, 419, 62, -319, -266,
+ 584, 3728, 57, 220, -543, 768, -630, 361,
+ 361, 642, -313, 182, -488, -48, 3001, -397,
+ 640, 179, 8, 1081, -1161, -58, -70, -64,
+ 4456, 323, 883, -191, -16, 61, 419, 429,
+ 627, -898, -883, 750, 499, -1335, -467, -1410,
+ -5, 283, -301, 276, -1636, 310, 114, -428,
+ -8192, 12, -114, 74, 215, 511, 317, -314,
+ -86, 198, 138, 315, -271, 246, -363, 426,
+ 608, -714, 367, -1356, -2217, 1178, -385, 1442,
+ 28, -642, -371, -87, -2895, -710, 303, -150,
+ -398, -868, -1727, 1548, 982, 1177, 332, -377,
+ 1580, 962, -1028, 1922, 1494, -824, 93, -1362,
+ -552, 1641, -1729, 228, 1054, 421, -185, -536,
+ 51, 87, -204, 88, -847, -754, -3761, -2706,
+ -138, -1242, 35, 64, 418, -460, 713, 3960,
+ 733, 468, -150, -823, -211, -674, 366, -269,
+ 180, -294, -384, 604, 1829, -121, 271, 241,
+ 192, -211, -2672, -1483, -1102, 960, 90, 49,
+ -1144, 2552, -887, -32, -301, 62, -183, 193,
+ 78, -781, 193, -606, -285, -3082, 240, 392,
+ 704, 20, -1103, -195, 166, 577, -105, -45,
+ -310, -106, 3035, 28, -369, 725, 53, 87,
+ -232, -191, 7, -282, -572, -8192, 325, 99,
+ 162, -113, -237, -209, 412, -573, 295, -389,
+ -1603, -66, -485, -867, 466, -882, 862, -216,
+ 221, 50, -51, 3927, 557, 441, 223, 234,
+ 4048, -173, 420, 1670, 436, 341, 175, -441,
+ -201, 75, -549, 315, 172, 418, -159, 7,
+ 2973, -3, -220, -1360, 26, 2781, 132, 295,
+ -15, 217, -166, 187, -282, 357, -121, 480,
+ -216, 294, 263, 95, -7367, 589, -63, -412,
+ -103, -201, 335, -96, -203, 240, 223, -435,
+ 366, -467, 118, 528, -472, -559, -417, -189,
+ -641, 339, 1546, -2741, 1413, -265, 637, -1556,
+ -49, 422, -195, 392, -21, 3, -2, 282,
+ -130, -272, -483, -860, -675, 762, -1455, 5212,
+ 178, 197, -468, 270, -310, 1038, 406, 2699,
+ -537, -33, 272, 225, -1986, 1295, -857, -2906,
+ -904, -1861, -206, 866, -145, -207, 252, -825,
+ 3051, -1361, -441, 85, -186, -127, 139, 285,
+ 3067, -332, 1163, 248, -483, -177, 268, 691,
+ 733, -104, -54, 2541, -1042, -226, 165, 250,
+ 7, -259, -383, 327, 2164, 2272, -750, 2482,
+ -930, -139, 1203, 766, 150, 320, 970, 28,
+ -1351, 467, 544, 521, -2908, -75, -902, 611,
+ 575, 1216, -209, -7, 541, 330, 528, 347,
+ -185, -306, -432, -3384, -1844, -380, 155, -1230,
+ 629, -1085, -413, 119, 114, 1093, 198, 806,
+ 491, -137, -518, 536, -64, 387, -1712, 608,
+ -24, 4961, 149, 299, -342, 505, 503, -387,
+ -944, -297, -2423, -98, -1027, -432, -259, 736,
+ 127, 3561, -473, -623, -751, 114, -438, 657,
+ 2448, 863, -413, -81, 2066, 988, -539, -528,
+ -111, 314, 390, -1228, -863, 19, 763, 2227,
+ -844, -24, 4164, 139, 130, -111, -630, -428,
+ 538, -606, 940, -877, 122, 526, 194, -104,
+ 127, 117, 907, -789, 2865, 526, -548, -253,
+ 289, 2329, 176, -70, 775, 681, 21, 38,
+ -1481, 766, 2093, -2974, -289, -571, -445, 1833,
+ 333, -84, -243, -413, 188, -492, -22, -867,
+ 605, -333, 904, 3192, -29, 491, -411, 370,
+ -556, -2671, -294, 132, -243, -233, 180, 181,
+ 383, -79, 26, -3539, 642, 1127, -2125, -170,
+ -386, -135, -703, -290, -157, -444, -885, -341,
+ -920, 460, -407, -176, 3153, -3084, -505, 543,
+ 7, 79, 1191, 1148, -401, -17, 289, -735,
+ 300, 1971, 626, -146, 110, -1281, -613, -649,
+ -206, 1850, 701, 1138, -803, 742, -1392, 147,
+ 554, 1861, -658, -1481, 108, 856, 1021, 574,
+ 3314, 518, -1156, -307, 42, -92, -132, 278,
+ -352, -37, 35, 146, -93, -662, 216, 125,
+ 823, -876, -170, -5027, 444, -182, 844, 189,
+ -490, -1441, -335, -907, -173, 1138, -472, -1505,
+ -1641, 648, 66, 627, 64, -1096, -620, 1588,
+ -506, 309, -100, 5702, -555, -157, -179, -85,
+ -299, -114, -20, 178, 415, 118, -581, -132,
+ 1025, -2631, -1154, 2623, -286, 201, 340, 949,
+ 235, 171, 649, 328, 397, -142, 1369, -7,
+ 2305, -373, 658, -1681, -744, -3574, 34, -183,
+ -504, 165, 81, 21, 635, -307, 428, -520,
+ 164, -4701, 744, 249, -844, -7, -334, 38,
+ 539, 267, -213, 73, 134, -251, -248, -923,
+};
+
+static const int16_t cb1616sm0[] = {
+ -4119, -2861, -76, -49, -192, -542, 0, 94,
+ -550, 6, 601, 236, -446, -202, 167, 238,
+ 2609, -688, -406, 265, -3078, 321, 59, -601,
+ 157, 200, -265, 78, -699, -679, 18, -54,
+ 203, -687, 2683, -111, -3037, -627, -493, 413,
+ -480, 54, 75, 276, 206, -1861, 17, -420,
+ -169, 312, 361, -277, -12, -363, -592, 758,
+ -123, 3267, 78, -862, 81, -356, 596, -536,
+ 729, 2239, -49, 553, 112, 444, 652, -2990,
+ -70, 1084, -436, 34, 53, -10, -23, 41,
+ -3, -126, 207, -130, -208, 63, 480, 191,
+ 6229, -45, -33, -82, 35, 56, 259, 1,
+ 8034, -97, 52, -159, -334, -41, 50, -57,
+ 56, -194, -567, 2050, 146, 987, -383, 416,
+ -258, 2846, 51, 8, 690, -126, -704, 316,
+ 16, -4, -90, 159, 34, 126, 65, 218,
+ -7037, -261, -87, -21, -185, 14, 112, 42,
+ -164, 274, -269, 1138, -208, 574, 589, -143,
+ -479, 2745, 782, -13, -2492, -132, 498, -406,
+ 260, 828, -580, 558, -2861, -600, -447, -313,
+ 1316, 800, 1772, 1131, 323, -48, -3972, 697,
+ 5, -403, 46, 95, 130, 84, -39, 219,
+ 117, 1629, -189, -1371, 25, -116, 2311, -681,
+ -411, -685, -1340, -409, 223, -462, 2530, -816,
+ -1118, 314, -893, -109, -262, 376, -2795, -48,
+ -2878, -6, 180, 53, -500, -181, 125, -291,
+ -265, -154, -23, -184, 185, -563, -1159, 675,
+ 24, -213, 273, -2905, -242, 2373, -6, -166,
+ 92, 276, 1375, -28, 1879, 2572, 205, -121,
+ 51, 356, -873, -308, -1060, 952, 719, 456,
+ 106, 116, -107, -211, -21, 3319, 2109, -172,
+ -172, 143, -718, -138, 1135, 232, -1361, 157,
+ -99, 522, -4367, 84, 605, 319, -937, -397,
+ 117, -434, 82, 633, 274, -1555, -221, -59,
+ -2419, -2486, -112, 136, -182, -480, 27, -548,
+ -237, 817, 530, 656, 252, -2685, -26, 703,
+ -3268, 381, -383, -323, 105, -500, 66, -299,
+ -1056, -363, -69, 21, 292, 398, -379, -106,
+ -356, 38, 169, 2866, 206, -523, -277, -2875,
+ -582, -69, 649, -3, 198, -30, 98, 145,
+ -125, -186, -19, -107, -102, -173, -7299, -62,
+ -503, -231, 24, 145, 1367, -355, -175, 373,
+ -953, -704, -3454, 170, 899, 386, 592, -754,
+ 620, 81, 86, -65, 84, 683, 3054, -280,
+ -2825, -757, 53, -10, 441, -145, 138, 1364,
+ -2, -92, -300, 225, -199, -2087, 1095, -363,
+ -75, 288, 765, -869, -7, 3261, 9, -2860,
+ -330, -382, 3309, 28, 629, 244, -143, -298,
+ -512, -409, -241, 104, -6, -271, -2, 8192,
+ -137, 139, -304, -14, 81, 262, -36, 51,
+ 380, 11, 101, 100, -153, 2167, -271, 267,
+ 306, -3008, 579, -277, 316, 327, 1168, 71,
+ -1401, 389, -25, -265, 101, -53, -170, -226,
+ 2861, 145, 3040, -159, 77, -16, 233, -570,
+ 490, 661, 452, 1986, -522, 212, -107, 196,
+ -247, 308, -353, 186, -2689, 486, -46, 813,
+ -24, 233, -166, 3305, 2832, -343, -82, 475,
+ 267, -385, 26, -35, -226, 27, 416, 231,
+ 12, 88, -209, -139, 404, -239, -109, -182,
+ -851, 260, 242, 109, 11, -1096, 85, -4226,
+ -124, 12, -139, -100, -604, -87, 89, 5820,
+ 59, -43, -84, 264, -543, 0, 428, -16,
+ -146, -556, -195, -159, 875, 27, 261, 207,
+ -182, 2367, -622, -3193, 481, -289, 52, 12,
+ 34, 3014, 10, -345, -94, -2883, -62, 400,
+ 249, 51, -178, 1190, -128, -3940, 41, -296,
+ -48, 13, -26, 223, -2392, 516, -384, 33,
+ -46, -161, -43, -224, -89, -4, -349, 135,
+ 540, -120, -276, -198, 129, -5113, 175, -45,
+ -34, -109, 419, -45, -104, -185, -393, 416,
+ -3514, 149, -3088, -115, -78, 431, -172, 21,
+ -290, -162, 216, 41, -56, -487, 705, -194,
+ -1003, 100, 172, 2793, -83, 2584, -189, 1198,
+ 551, -119, -73, -91, 2103, -619, 124, 128,
+ 2628, 192, 160, -110, 270, 1739, 1062, -568,
+ -73, -56, 328, 100, 384, -173, 83, 39,
+ -236, -25, -457, 53, -6413, 345, -459, -110,
+ 28, -127, -109, -593, 32, 141, -879, 254,
+ 2132, -410, -623, 1103, -2302, 528, 156, 28,
+ 81, 613, 602, 171, 500, -2356, 620, 17,
+ -523, -2961, -921, -107, -405, -230, -129, 18,
+ 363, -881, 1282, 1427, -363, 658, 205, -51,
+ 2835, -2003, 188, -26, 73, -231, 352, 74,
+ -490, -222, 2423, -341, -2762, -14, -56, -260,
+ -41, 33, 169, -190, 1248, -77, -2322, -607,
+ 3610, -104, -200, -90, -81, 719, -52, -359,
+ 394, -301, 66, -39, -56, -8192, 87, 56,
+ -291, 50, 231, 284, -211, -16, -86, -84,
+ -28, 52, 3, -51, 304, -224, 228, -374,
+ 458, -1958, -210, -2613, 401, -2128, -119, -12,
+ -60, -14, -8192, 53, 27, 113, 289, -7,
+ 22, 60, -192, 333, 72, -344, 238, 147,
+ -2235, 324, 124, 176, -415, 450, -476, -558,
+ -429, -246, -551, -287, 672, 2145, 8192, 161,
+ -165, -34, 193, -108, -137, -96, -68, 156,
+ 308, -182, 5, 438, -71, -27, -164, 187,
+ -110, 5786, -82, -130, -126, 197, -262, -182,
+ -118, -110, 121, -93, 235, -56, -99, -212,
+ -3013, -193, -10, -2944, 58, -135, -624, -170,
+ 84, 339, 115, -85, -1886, 250, 123, -104,
+ -374, -2241, 2454, -438, -168, 632, -136, -725,
+ -329, -394, -60, 19, 2795, 438, -796, 141,
+ -143, 132, 251, 37, 286, 1858, 39, 2381,
+ -9, -85, -110, 149, -415, 355, -172, -9,
+ -149, 554, -324, -4931, -537, -261, -585, -291,
+ 764, -92, -139, -8, -80, 65, -6, -26,
+ -81, 37, -14, 45, 115, 171, -321, 313,
+ 308, -4637, -128, -120, -174, 148, 768, 490,
+ 81, -175, -261, -136, 1501, 345, 25, -56,
+ -212, -324, -836, 207, -652, -752, 2406, -332,
+ 489, -275, -932, 284, 3103, -315, 614, -2711,
+ 1706, -1072, -163, -75, -1104, 163, -421, 1532,
+ -92, -163, -811, -118, -38, -754, 466, -314,
+ 232, -595, 3613, -30, 570, -62, 785, 1626,
+ 1080, 553, -407, 32, -105, 82, -156, -75,
+ 8063, -67, 114, -65, -65, -242, 98, -124,
+ 38, 441, -2645, -92, 69, 17, -3284, -278,
+ -278, 116, 567, -742, 182, -304, 432, 261,
+ 86, -4109, 389, 795, -138, 151, 111, -223,
+ 2392, 399, -135, -545, 182, -226, 61, 234,
+};
+
+static const int16_t cb1616sm1[] = {
+ -29, -13, -6217, -136, -196, 24, -228, -301,
+ -155, -37, -54, -91, -4, -130, -424, -89,
+ -181, 657, 110, -4526, -391, 762, 1033, -310,
+ -808, -282, -721, -690, 258, -259, 16, -555,
+ 2675, -379, -2580, 356, 198, -455, 95, -194,
+ -754, 383, -263, -873, 271, -107, -191, -28,
+ 11, -66, 91, 25, -215, 9, 152, 11,
+ -124, 66, 422, 521, 5401, 103, -179, -291,
+ -821, -1265, -396, 150, -69, -15, 154, 1504,
+ -445, 116, -136, -3528, 2819, -5, 174, 166,
+ 289, -60, 158, -701, 83, -636, -407, 194,
+ -240, -138, 124, -94, 132, -105, -106, 72,
+ 139, 101, 97, -7928, 6, 112, 164, -83,
+ -329, 41, 124, 389, -22, -194, 157, -378,
+ -2255, -431, 3176, -199, -310, 49, 483, -208,
+ -235, 11, 45, 637, 1220, 2309, 93, 514,
+ -1939, 136, 276, -165, 137, 2496, 56, 31,
+ 238, -538, -433, 690, -318, -44, 834, -1684,
+ -132, 2619, -157, 1959, -566, 119, 183, 227,
+ 2066, 401, -48, 1257, 604, 1306, 149, 273,
+ 586, -199, 2166, 257, 2047, -46, -377, -761,
+ -25, -454, -1592, -42, 432, -2312, 222, -528,
+ -87, -287, 532, 2906, -2011, 720, 554, 423,
+ -576, 425, 280, -894, -232, -179, 485, 628,
+ -2918, 405, 229, -2, -146, 127, -329, -243,
+ 194, 2443, -531, 592, -14, 1679, 292, -914,
+ -332, 2382, -3040, 297, -2856, -88, 236, -485,
+ 438, 241, -283, 448, 579, -660, 277, 233,
+ 201, 126, 15, -411, -560, -582, -389, -392,
+ -7, 238, 1, 344, -216, -4601, -457, 1027,
+ -114, 13, -301, 288, 172, -488, -124, -2721,
+ 100, -105, 434, -13, 2791, -827, 1600, -219,
+ -4992, -100, 411, 326, -608, -779, 94, 974,
+ 453, -1326, -236, 429, -189, 830, 32, 187,
+ 459, 2489, 476, 165, 3261, -445, 169, 179,
+ -113, 168, -393, 52, -383, -33, 73, 137,
+ -6021, -259, -121, -29, -46, -156, 68, -225,
+ 217, 152, -280, 7, 62, 3, 17, 295,
+ 221, -158, -5406, -335, 232, -454, -320, 467,
+ -45, 96, -170, -267, 1273, 287, 258, 536,
+ -695, -953, 1134, 428, 251, 3331, 717, -804,
+ 627, 1099, 120, 4, 42, 191, -9, 259,
+ -335, -337, -25, -56, 116, -228, -351, -463,
+ 5942, 193, -114, -64, -268, 300, 146, -15,
+ 657, 367, -2, -2911, 838, -251, -1, 2897,
+ -78, -609, -545, -588, 488, 1383, 486, 1820,
+ 126, 2971, -151, 11, 10, -349, -279, -260,
+ -265, 142, -683, -191, 172, 30, -293, -5103,
+ -61, -247, -38, 722, 275, -326, -34, 132,
+ 297, 3305, -46, 227, -1052, -1114, 562, 62,
+ -1618, 699, 362, -1624, -455, 150, -110, 61,
+ -266, -168, -168, -391, 136, -569, -772, -203,
+ 467, 20, -4747, -170, 142, -138, 129, 1719,
+ 1896, 210, -1008, 206, 585, -325, 295, 175,
+ -2542, -489, 121, -94, -38, -2766, -115, -3206,
+ -305, 320, -179, 503, 83, -72, -122, -52,
+ -181, 98, 39, -506, -2751, -93, -1, -59,
+ 2645, 248, -309, -203, 138, 324, -567, 696,
+ -493, 170, 2440, 919, -420, -3029, -335, -593,
+ -72, 536, -82, 202, 78, 510, 184, -2,
+ 227, -2830, 19, 1590, -281, 387, -46, 408,
+ -463, -536, 262, 2214, -115, -1614, -385, 203,
+ 32, -885, -2606, 2338, 97, 292, -449, 449,
+ -1038, -582, 0, -68, 211, -160, 62, -286,
+ -2466, -421, -48, 1903, -1037, -173, 1339, -591,
+ 152, -1231, 792, 524, 214, -92, 29, 181,
+ -225, -150, -1, 139, -8135, 238, -119, 189,
+ 34, -140, -188, 141, -112, 56, -176, 154,
+ 91, 5653, 298, -316, -23, 232, -74, -317,
+ -4, -630, -506, 105, -1655, -126, 2417, 113,
+ -95, -472, 134, 290, -755, 152, -1222, -58,
+ 981, -236, 8192, -154, 75, 218, -185, 107,
+ -10, 39, 265, -225, -87, 9, 123, -906,
+ -382, 2544, 44, -1985, -102, 407, -91, -1835,
+ -108, 122, 142, 169, 134, -721, -1530, -4,
+ -133, 45, 374, -1049, -76, 16, -357, 277,
+ 158, -2596, -4, -1484, -13, 2660, -198, 9,
+ -218, 408, -63, 177, -71, -195, 4293, -8,
+ 228, 34, -421, 695, -1409, 85, 2740, 350,
+ 44, 473, 141, -93, 144, -59, -220, -154,
+ -148, -168, -205, 3049, 229, 194, -107, 90,
+ -353, 508, -343, 473, -446, 457, -452, -116,
+ 3493, 504, 2152, -228, -1832, -463, -657, 555,
+ 657, 540, 546, 604, 2214, -68, 254, 563,
+ 267, 227, 92, -107, 143, 260, 23, 42,
+ 64, -67, 138, -167, 72, 457, 4958, 61,
+ -933, 1, 5341, -32, 89, 161, 504, 823,
+ 311, 11, -184, -574, -79, -1654, -74, -366,
+ 164, -363, 117, 53, 706, -701, -2966, 233,
+ 11, 165, 394, 462, -2632, 703, -291, -65,
+ -49, 4080, -862, -65, -19, -110, -872, 323,
+ 833, -154, 369, 475, 2211, 20, -212, 1711,
+ -24, -28, -58, 32, 1746, 41, -779, 614,
+ 508, 3050, 687, 423, -182, -484, -60, 242,
+ 3895, -565, -453, 110, 547, -961, 320, -34,
+ -347, -1963, -116, 730, -435, -34, 41, 26,
+ -51, 8192, -115, 312, 184, -148, -199, 157,
+ 153, 82, 99, 138, -32, -19, -64, -139,
+ 107, 43, 133, -87, 42, -148, 7080, -158,
+ -335, -249, -64, 81, 157, 813, -279, 2226,
+ -16, 1191, -705, 607, 205, -11, -1341, -548,
+ -2251, -326, -149, -2536, 139, -750, 73, -394,
+ -218, -35, 181, 925, -557, 226, -63, 2582,
+ -737, 164, 181, -167, -230, 413, 328, 406,
+ -287, -2992, 539, 1133, -85, -2162, -154, -357,
+ -245, -8, 162, -118, 111, 1275, 47, -314,
+ -2043, -2732, -1052, -28, 625, -810, -487, 40,
+ -131, 273, 105, 2605, -2974, 268, -19, -257,
+ 842, -662, 855, 505, 590, -243, 68, 6978,
+ 118, -101, 349, -232, -258, -318, 212, 55,
+ -686, -177, -173, -102, 480, 35, 149, 263,
+ -2838, -198, 942, 392, 135, 2980, 34, 92,
+ -237, -672, 224, -298, 298, 2128, 359, 254,
+ 150, -839, 1001, 3234, -169, 261, -302, 74,
+ -277, 498, 321, 194, -3275, -152, -2786, 33,
+ 70, 236, -222, 88, -393, 47, -636, 869,
+ -754, 842, -2326, -460, 133, 0, 264, 172,
+ -2955, -286, -243, 399, 882, -722, -382, 872,
+ -119, -65, -2403, -119, -246, -890, -185, 102,
+ -32, -573, 225, 3044, -484, -40, -809, 403,
+};
+
+static const int16_t cb2224l0[] = {
+ -3546, -433, -76, 46, 24, -641, 214, 114,
+ -779, -930, -57, -462, -569, -848, -413, 53,
+ 45, -3172, 2915, -734, 152, 487, -113, 246,
+ -196, -187, -136, 469, 475, 382, 213, -886,
+ -275, 313, 3148, -62, -773, 785, -24, -1499,
+ -65, -175, -1942, -325, 78, -15, -38, 2,
+ 6, -29, -16, 9690, -15, -49, -13, 12,
+ -21, 11, -45, -63, -528, 192, -137, 201,
+ 138, -154, 57, -88, -1695, 155, 105, 121,
+ 4249, -59, 467, -439, 4483, -130, -39, 262,
+ -21, -377, 441, -353, -768, 366, 23, 841,
+ 529, 195, 2722, 2892, -255, -67, 628, -498,
+ 33, 241, 212, -1020, -97, -723, 594, 35,
+ -31, 1459, 19, -75, -27, -1, 48, 28,
+ 267, -275, 3780, -515, -467, 36, -405, -272,
+ -1968, 60, 44, 449, -2877, -124, -1524, 1195,
+ 1042, 117, 115, -305, 225, 215, -357, 144,
+ 35, -23, 89, 2133, 2, 65, -27, -48,
+ -243, -216, -807, 700, 1258, 6, -140, 4,
+ -31, -21, 42, 67, 97, -2, 104, -10,
+ -7734, 134, -50, -95, -88, -269, 105, -18,
+ -229, 453, 1038, -2609, -2944, -57, 27, 372,
+ 59, -556, -87, -242, 114, 1083, -119, -139,
+ 175, 146, -55, 1689, 342, 501, 2722, -1273,
+ 1626, 868, -290, -145, 62, 194, -23, -179,
+ 1540, -85, 360, 254, 339, -681, 2081, 2730,
+ 838, -128, 31, -2133, -173, 483, -138, 2706,
+ 2007, 91, 293, -642, 35, 280, -132, 454,
+ -66, -6263, -24, 82, -31, -39, 5, 41,
+ 66, 239, 18, -57, 61, -117, 103, 16,
+ -1231, 1384, -164, 104, 370, -1891, 2237, -440,
+ -1399, -1394, 3, 274, 223, -30, -70, 579,
+ 361, 423, 355, -176, -164, -443, -306, -2382,
+ 713, -2987, -340, -691, 1407, -5, 439, -264,
+ -86, 1964, -17, 88, 175, 56, -119, 31,
+ 466, 1980, 176, 513, 1809, 17, 3000, 1861,
+ -71, 314, -255, 2041, 576, 203, 443, -392,
+ -539, -380, -685, -204, -161, 287, 378, -502,
+ 1898, 1540, 1073, 2282, 573, 867, 122, 1064,
+ -628, -564, 97, 280, -36, 1601, -90, -174,
+ -10, 45, -57, 159, -496, 641, -959, -91,
+ -90, 3057, 1680, -83, 80, 19, 63, -119,
+ 1, -72, 466, -335, 453, -177, 3930, -21,
+ 327, -199, -651, -38, -6, -13, 7, -77,
+ 1, 8, 40, -125, 36, -136, 272, 6266,
+ -3299, 3331, 24, 18, -71, 9, -79, -374,
+ -277, 128, -233, -175, -350, -216, 81, -693,
+ -49, 33, -44, -37, -4260, -70, 96, 177,
+ -319, 133, 178, -377, -45, 182, 156, -155,
+ -34, 10, 22, 53, -211, 4, 5740, 48,
+ -42, 114, 149, -30, 122, -106, -309, -148,
+ -82, 20, 130, 2734, -40, -596, 1309, 1163,
+ -1470, 396, -264, 884, 142, -1818, 67, -1,
+ 38, -52, -73, 1, 279, 143, 278, -45,
+ 1541, -886, -677, -2609, -88, -3766, -201, 237,
+ -40, 195, -50, -366, 88, 166, 403, 236,
+ -130, 205, -45, -8636, -13, -27, -50, 8,
+ 40, 21, 41, -36, -25, -40, -14, -14,
+ 42, 296, 2495, 372, -361, -501, 1951, -2141,
+ 220, -847, 98, 228, -250, 563, -1121, -29,
+ 2888, -196, 151, -19, -287, -2298, 65, -482,
+ -124, -186, 1215, 468, -781, -227, 621, 298,
+ -42, -44, -115, 0, 50, 179, 23, 9,
+ -65, -8, 10, -101, -4998, 77, 1181, -304,
+ 139, 250, -2257, -97, 847, 433, 385, -2411,
+ 800, -852, -528, 435, -953, -23, 4, 928,
+ -108, -634, -273, -879, 2566, -2609, 621, 807,
+ 295, -77, 627, -1114, -297, -109, 2103, -53,
+ -9, 44, 32, 339, 679, 77, -3186, -416,
+ 1234, -801, 472, 408, 153, 465, 1703, 879,
+ -2411, -553, 440, 2099, -899, -288, 310, 665,
+ -47, -148, 1457, 3932, -213, 243, -1763, -2,
+ 288, -425, -972, 478, -302, 552, -377, -352,
+ 179, -480, 1466, 2019, 2817, 5, 824, 13,
+ -384, -582, -297, -1165, 689, -120, 703, -118,
+ 663, 206, -49, -2853, -76, 32, 170, 11,
+ 42, -503, -1139, 1548, -287, -1112, 765, -455,
+ -35, 2452, 22, -134, 144, 1867, -149, 2771,
+ 19, 264, 700, -48, 286, -593, -2637, 408,
+ 2304, -14, 187, -135, -210, 745, 282, 724,
+ 861, 21, -414, 606, 836, -564, 212, 203,
+ 64, 4706, -30, -43, -85, -61, -90, 644,
+ -281, 287, -122, -340, -137, 36, -4, -22,
+ 8, 9486, -3, 4, 10, 4, 86, 58,
+ -8, 6, -105, -15, 15, -63, -58, -30,
+ 15, 0, -19, 78, -8267, -134, -8, -45,
+ 163, -19, 149, -298, -167, 34, 190, -39,
+ -2229, 2821, 126, 185, -791, -1229, 1003, -331,
+ 980, 659, -60, -60, -48, 20, 12, -167,
+ -60, -39, 66, 180, -22, -20, 84, -108,
+ 131, -10, -8493, -1, -18, -4, -53, 25,
+ -63, -14, 20, 25, -41, 40, -5, -2330,
+ -74, 59, -7, -154, -293, -64, -2702, 819,
+ 75, 977, -602, 1138, 160, 262, 26, -81,
+ 18, 5558, 118, -167, 98, 110, -5, -44,
+ -27, 72, 51, -189, 0, 1868, 743, -275,
+ 2530, 6, 180, -1019, -1307, 710, 303, -152,
+ -115, -1498, -501, -495, -103, -76, 78, -7,
+ -9337, -6, 31, -21, 16, -14, 57, 36,
+ -81, -67, -30, -535, 216, 313, 310, -157,
+ 2830, -914, 122, 1353, -1842, 298, -1165, -13,
+ -253, -100, -560, -61, 40, 24, 3, 56,
+ -18, 5709, 41, 13, -23, -55, -98, 214,
+ 109, -205, -45, 27, -26, 177, -290, 89,
+ 8, 1315, 3102, 1657, 210, -1032, 774, -211,
+ -581, -51, 896, 852, 331, 349, -474, -119,
+ -865, -145, 2270, 703, -1967, -2088, 610, -700,
+ 113, -231, 2062, -152, -599, -474, -38, -601,
+ 432, -983, -731, 744, -2880, 156, -240, -1903,
+ 2497, -89, -963, -2179, -1208, 189, 318, 150,
+ 204, 29, -167, -138, -93, 73, 292, -3225,
+ -310, -510, 173, -90, 154, 1831, 380, -1191,
+ -976, -1460, -514, 235, 13, -2950, 22, -95,
+ 228, 85, 10, 264, -3165, 46, -184, -782,
+ 143, -9, 37, 12, 108, -65, -64, 115,
+ 86, 5039, -55, -203, -163, -462, 77, -92,
+ 423, 139, 239, -5, 1887, 426, 729, 118,
+ -159, -2821, -124, 2147, -167, -1023, 92, -23,
+ 162, -159, -47, -3, 14, -34, 37, -29,
+ -97, 41, -92, -75, -6983, -224, 250, -80,
+};
+
+static const int16_t cb2224l1[] = {
+ -2888, -183, 3606, 0, 33, 99, -76, -264,
+ -351, -508, -546, -103, 252, -49, 46, -32,
+ 48, -245, 67, -2408, 340, 3153, -154, -280,
+ -440, 374, -224, -39, -720, -289, -136, -3095,
+ -98, -37, -86, 145, 51, 132, 773, -1158,
+ -330, -449, -141, -1831, 666, -2680, -110, -906,
+ -307, -3299, 287, 55, -521, -173, -431, -383,
+ 67, -28, 34, 247, 2814, 1479, 32, -2196,
+ -1625, 135, 72, 3, 634, 76, 502, -306,
+ -366, -120, -219, 1934, 372, -130, -113, 255,
+ -14, 30, -687, -576, 797, 306, -2360, -242,
+ 2062, 69, 2273, 26, -20, -21, -68, -69,
+ -4618, 60, -171, -235, -271, 175, -110, 147,
+ 100, 1628, -197, -2, -4002, 520, -1236, -21,
+ 62, -396, 513, -369, -168, 285, 561, 131,
+ 1347, 83, -101, 89, 206, 5, 4556, -23,
+ 1191, 39, 352, -158, 99, -195, -33, 481,
+ -446, -125, 181, 2678, 2860, -524, -239, 55,
+ -360, -358, -560, 93, 307, 285, 77, -295,
+ -90, 114, -45, 54, -328, 94, -222, -30,
+ -5004, -164, 100, 379, 208, 424, -11, 26,
+ 10, -26, -32, 114, 30, 18, -44, -221,
+ -184, -32, 0, -99, -9001, -7, -33, 1,
+ 41, -3, 13, 9, -46, -86, 47, 56,
+ 72, -7, 5, -1162, 101, 456, -217, 3440,
+ -220, 400, 100, 1503, 365, 655, -230, 42,
+ 1129, 767, 192, -16, -3440, -79, -236, 3,
+ -80, 51, -11, -984, -142, 29, 554, 339,
+ 1851, 105, -279, -2915, 116, 3090, -431, 233,
+ 337, 61, 927, 32, -174, 237, 255, -250,
+ 604, 115, 2036, 78, -79, -50, -349, 338,
+ 285, 169, 394, -49, 1194, -2966, 447, 57,
+ -2591, 415, -586, -2616, -197, -61, 596, -1159,
+ 130, -441, 356, 47, 1192, 496, -1801, -15,
+ -142, -23, 132, 21, 84, 234, -137, 23,
+ -147, -3254, 407, 107, 1132, 130, 74, 153,
+ 3148, 2184, -464, 1294, 222, 589, 457, -397,
+ -87, -605, -631, 311, -703, 110, 20, -23,
+ -75, 18, -43, -182, 8, -94, 151, 4989,
+ -619, 662, 82, 8, 69, -4, 126, -35,
+ -99, -277, -227, -2212, 3188, 1115, -467, -618,
+ -989, 681, 218, -25, -37, -9, 32, -46,
+ 97, 15, -23, -95, -6, 55, 19, 7904,
+ -14, -508, 3, 14, -12, -58, 28, 154,
+ 11, 271, -593, 344, -336, 3489, -41, -2998,
+ 622, -2739, 2796, 1536, 310, 176, -318, 399,
+ -70, -298, -509, 256, -381, -158, 322, -197,
+ 3, -53, 37, 98, -6136, -25, -54, 57,
+ 138, -74, 239, -46, -18, 29, -265, -2278,
+ 22, 110, -21, -147, 266, 85, -286, 137,
+ 3434, -485, 68, 475, -3, 159, -181, -237,
+ 1595, 759, 786, 1490, 926, -2841, -160, 1092,
+ -7, 130, 895, -345, -95, -31, -35, 139,
+ -98, 2106, 305, 672, -66, 349, 229, -1561,
+ -1694, -1786, -743, -76, -67, 1666, 76, 10,
+ -22, 60, -45, 5, 409, -458, 583, -405,
+ 2586, -264, 175, 633, 842, 3208, -1488, -802,
+ 40, -119, -197, -84, 1645, 328, 823, -175,
+ 342, 12, -217, 67, 124, -180, -106, -2877,
+ -336, 171, 185, 132, -2263, -75, -622, -631,
+ -2404, 176, -132, 35, 179, -1498, 182, 68,
+ 699, 597, -2728, 325, 52, 421, -863, 609,
+ 53, -159, 258, -307, 2919, 44, -826, -467,
+ 91, 542, 1883, 815, -682, 548, -419, 593,
+ 82, -2108, -158, -75, -524, 2440, -528, -469,
+ 723, -14, -1817, -487, 448, 4, -155, -70,
+ -1715, 34, -55, 134, 0, 19, 107, 419,
+ 334, 74, 446, 1241, -4288, 61, -65, 21,
+ 71, 133, 2, -88, -238, 322, -283, -6,
+ 404, 98, 78, -1951, 412, -1942, 418, 257,
+ -42, -2444, -97, 1491, 464, 346, 229, -154,
+ 96, 261, 29, 302, 39, -201, -40, -98,
+ -157, 335, -3624, -349, -573, 633, -116, -312,
+ -82, 263, -2, -101, -57, 1817, -424, 3,
+ -245, 386, 74, 609, 2171, -77, -2604, -1036,
+ -117, 1585, -2, 9, -23, 31, -12, 48,
+ 215, 84, 13, 219, 419, -275, 4373, -91,
+ -6, 18, 2228, -46, 157, -408, 2288, 654,
+ -725, -245, -10, -1182, 1726, 324, 367, 3013,
+ 3429, -140, 360, -122, -574, -165, 109, -330,
+ -82, 340, -133, 210, 355, -8, 47, -52,
+ 8064, 5, 60, -42, -95, -3, 91, -69,
+ -47, -42, 101, 118, -44, -16, -14, -9,
+ 27, 8, -33, -3, -9302, 27, 49, -6,
+ 61, 74, 204, 430, 252, -259, 73, 125,
+ 366, -458, -2846, 89, -2694, -106, -344, -702,
+ 809, 451, 69, 585, -1897, 608, -1138, 52,
+ 618, 106, 771, 2992, 266, 1007, 184, -486,
+ 36, 3317, -311, 38, 105, -89, 16, 97,
+ -88, 28, 183, -2834, -44, 387, -49, 467,
+ -2524, 77, -56, -3727, 81, -308, 63, -137,
+ 203, -77, 139, 254, -65, -264, -58, 631,
+ -2559, 739, -1343, 595, -117, -193, -2572, 322,
+ 267, 185, 669, -110, 641, 212, 45, -16,
+ 12, 14, -3, -12, 78, -48, -196, -128,
+ 179, 146, -7348, 177, -138, -48, 142, -33,
+ 34, -6037, 15, -105, 103, 136, -48, 217,
+ -169, 88, -31, 9, 24, 41, 1733, -2757,
+ -335, 1783, 988, -161, 1014, 633, -66, -1114,
+ 525, -266, 461, 1137, -26, -173, 89, 82,
+ -3365, 67, -198, -107, 44, 352, -793, 867,
+ -807, -166, 107, 4, 71, 61, 124, 27,
+ -2477, 178, -32, -172, 2895, 1301, 798, 707,
+ 267, -720, -403, 167, -157, 2572, -210, 527,
+ -312, -1664, -214, -1556, -332, 595, -1634, -58,
+ 203, -1777, -469, 24, 188, -59, -860, 879,
+ 15, 855, -1534, 2910, 534, -71, 276, 471,
+ 41, -25, 105, -37, -150, 110, 226, -277,
+ -4687, 574, 139, -152, -586, 67, -1082, 261,
+ -68, 25, -216, 110, 46, -3703, 281, 355,
+ -506, 80, -218, 164, -398, 75, -97, 5782,
+ 39, -68, 26, 76, 74, 38, -103, 105,
+ 44, 116, 187, 288, 90, 5847, -41, 28,
+ -19, 20, 129, -99, 258, 22, -28, -120,
+ -101, -121, 79, -180, -23, 22, -5, -60,
+ 63, 35, -8987, -11, 2, -15, -3, -28,
+ 47, 29, 241, 132, -166, -259, -48, 102,
+ 70, 2830, 3163, 285, -813, 0, 105, 176,
+ -455, 141, 1382, -481, -2282, 2971, -200, -473,
+ 37, -930, -1162, 930, 890, 412, 190, -160,
+};
+
+static const int16_t cb2224s0[] = {
+ -5789, 1229, -138, 1010, 823, -602, -987, -237,
+ 47, -29, 428, 210, 87, -11, -20, -261,
+ -3148, 1219, -2074, -132, -258, 707, -634, 878,
+ -486, 989, -276, -137, -263, 592, 1248, 474,
+ -293, -981, 2125, -653, -1451, -833, -1522, 387,
+ -269, 349, 698, 295, 870, 661, 1532, 202,
+ 654, 362, -1265, 3972, -651, 224, 213, -728,
+ -83, 575, -503, -766, 559, -657, 86, 941,
+ 1498, -72, 2297, 1413, -376, 697, -738, 384,
+ -807, -354, 1141, 374, 1186, -597, 222, 630,
+ -717, -1653, 106, -1377, -929, 982, -3469, -321,
+ -201, -1185, -147, -13, 268, 103, 2967, -2083,
+ -416, 702, 377, -1126, 92, 963, -494, -94,
+ -436, 1893, 1401, -40, -1464, -1608, 1980, 44,
+ 254, 676, 529, -891, -95, 9, -172, -129,
+ 158, -403, -1147, 1026, -410, 86, 2593, -1060,
+ -621, 480, 254, -780, 691, -1020, 79, -192,
+ -2264, -1219, -748, 602, 243, 338, 550, -444,
+ -130, 79, 24, 3396, 124, -572, 749, 976,
+ 33, -883, -368, -609, 694, -569, -560, 192,
+ 868, 644, 173, 86, -4302, 633, 7899, -360,
+ 478, 493, -306, 14, 244, 96, 71, -169,
+ 336, 346, 74, -52, 1779, 828, -252, 739,
+ -1005, -755, 31, -46, 200, 581, -11, 802,
+ 1104, 3252, -1053, 723, -491, -2492, -2330, -245,
+ 308, -1021, -312, 563, -85, 991, -16, 224,
+ -85, -957, 2262, -4585, -1475, 102, 310, 298,
+ -875, -6, -268, 8, -284, 324, -471, -224,
+ 133, 1502, -1714, -1095, -104, 809, 2584, -273,
+ -1014, -296, 130, 732, -259, -335, -745, -619,
+ -716, 247, 503, 862, -277, -137, -224, -4897,
+ 124, 277, 298, -40, 169, 678, 557, 4379,
+ 677, -2016, -506, -108, -47, 49, -115, -260,
+ -300, 206, 1196, -17, 202, 365, -808, -473,
+ -160, -609, 526, -1124, 1629, -2924, 713, -487,
+ -109, 540, -511, 221, -394, -1420, 1023, -460,
+ 424, -86, -875, -1557, -88, -244, -1597, -3015,
+ 355, 166, 330, -334, -325, 505, 3632, -1760,
+ 1626, -427, 573, 1197, -317, -566, -663, 460,
+ 338, -442, -597, 1565, -854, -534, -219, -128,
+ -2175, 739, 1064, 2050, -61, -349, 361, -375,
+ 1111, -122, -121, -164, -2573, 938, 1758, -15,
+ 884, 865, -630, -573, 994, 1112, -26, 9,
+ -30, 3893, -38, 1386, 605, 568, -680, 117,
+ 37, 572, 245, -53, -1030, -241, 397, 363,
+ -1632, -567, -26, -698, -2109, -1033, -1389, 1381,
+ -418, 402, -534, 9, 1143, 991, 693, 2557,
+ -1268, 1273, -192, 1225, 876, 472, 835, 509,
+ -452, -1519, 482, 1103, -626, -299, 1580, -1532,
+ 599, 2245, 503, -110, -1879, 978, -1158, -130,
+ -665, 448, -1247, 604, -528, -677, -711, 78,
+ -563, -349, -53, 261, 952, -338, -534, 43,
+ -2, -2555, 1976, 2393, 1715, 996, 5628, 1036,
+ 171, -28, -199, -83, -126, -35, -248, -393,
+ 36, 209, 77, -1793, 244, -108, -130, -41,
+ -578, -2347, -687, 1650, 131, -138, 407, -228,
+ -1348, -209, -841, 1332, -542, 220, -193, 843,
+ -103, 853, 261, -653, 217, -107, -113, -54,
+ -4151, -1303, -287, 4065, -376, -71, 43, -1481,
+ -359, -481, 78, 529, 689, -194, 178, 60,
+ -997, -1555, 1687, 345, 169, 266, 2894, 83,
+ -500, -425, -396, -245, 6, 517, 112, 129,
+ 725, -121, -404, 234, 47, -61, -122, 710,
+ -4283, 985, 56, -105, -45, 1043, 720, 73,
+ 321, 4452, -1614, 91, -620, -299, 506, 766,
+ -882, 650, -138, 123, -608, 210, -1582, -538,
+ -62, 246, 464, -332, -1560, 2271, 1559, -199,
+ -832, -1133, -797, 341, 1860, 1628, -1133, -607,
+ 637, -404, 437, -1148, 542, -474, -882, -610,
+ -1340, -159, 1524, 1424, 169, -6, 52, 447,
+ -5513, -592, 244, -294, 44, 164, -51, 147,
+ 202, -48, 139, 113, -399, -17, -173, -199,
+ 1, 17, -166, 15, -258, -7, 238, -5748,
+ -394, -852, -248, -46, 192, -32, -1033, -349,
+ 151, 483, 130, -1628, -3391, 1527, 694, -305,
+ 740, -357, -491, -186, -1649, -1394, -873, 213,
+ 652, -1975, 319, -1131, -103, -48, 673, 155,
+ -627, 1115, 469, -1122, 1901, -184, -237, -296,
+ -2887, -120, 211, 835, 57, -826, 1272, -255,
+ -937, 242, -525, 836, -334, 393, -624, 111,
+ -347, -178, -3441, 219, -352, 1831, -296, 587,
+ -357, -1099, 5, 313, -3806, -394, 814, -118,
+ -233, -23, -125, -21, -1414, 813, -403, 2482,
+ 442, -184, 934, 340, 472, 374, 1073, -283,
+ -2348, 477, -387, -713, 1071, -899, 252, -1299,
+ -502, -375, -410, -1785, 686, -605, -141, -871,
+ -1777, 2780, 53, -237, -237, 2701, 944, 44,
+ 595, 3, 1263, -1558, -2267, -998, 221, 355,
+ -319, -739, -1160, -594, 2977, 191, -41, -284,
+ 83, 484, 481, -73, -13, 138, -2761, -909,
+ -578, -139, -1056, 189, -645, -147, -61, -168,
+ 368, 130, 390, 4187, 101, 79, -45, 451,
+ -1374, -1941, -534, -301, -979, -668, -533, -2978,
+ 386, 574, -454, -4, 554, -120, 366, 83,
+ 1079, -351, 156, 389, 7724, 83, 102, -191,
+ -1059, -255, -86, 451, -211, 175, 774, 306,
+ -253, 2386, 1166, -2025, 223, 438, 1279, 1721,
+ -23, -91, 606, -1285, -775, -3228, -536, 543,
+ 877, 1140, -1616, -603, 550, -678, -462, 248,
+ 209, -515, -310, -2538, -2002, 231, -495, 319,
+ 538, 509, -113, -17, 143, -3062, -29, -52,
+ 299, 681, 595, 390, 530, -398, -969, 472,
+ -1145, 860, 4113, 329, -1183, -691, -605, 859,
+ 305, 986, -81, 2029, 408, 2, -2442, 59,
+ -85, -911, -285, -532, 28, 434, -2295, -76,
+ -2977, 51, 824, -1786, 2301, 622, -593, -9,
+ 643, 246, 427, 193, 51, 118, 4, 234,
+ 459, 31, -408, 710, -264, 144, -404, -476,
+ 278, -4836, -113, 382, -29, 177, 345, -33,
+ -17, -85, 6027, 72, -165, 544, -198, 75,
+ -278, -262, 155, 501, -305, -279, -439, 1506,
+ 827, -875, -2592, -1196, -1201, 149, 16, 547,
+ 1020, -616, 374, -193, -155, -3627, 231, 264,
+ -2143, 90, 419, 574, -795, 177, 328, 752,
+ -295, 210, -360, -1250, 2639, -3172, -13, -34,
+ 489, 484, -390, -159, -285, 27, 444, -252,
+ 265, 530, -2714, -340, -1543, 2330, -1152, -114,
+ 452, 304, -224, -451, -317, -579, 301, -567,
+ 1214, -594, -621, -2718, 59, 257, 410, -3,
+ 145, 70, 877, -3103, 244, -1134, 236, -1148,
+};
+
+static const int16_t cb2224s1[] = {
+ 8488, 277, 63, 173, 224, -30, -158, 64,
+ 133, -133, 234, 205, -65, 408, 249, -546,
+ -30, -1, -430, 80, 102, -450, -160, -5634,
+ 145, -406, -351, 37, 282, 232, -898, 430,
+ 3301, -1175, -559, 495, 2685, -21, -215, -87,
+ 728, -55, 235, 430, -250, -505, 506, -128,
+ -72, 3288, 1588, 291, 7, -39, -944, 478,
+ 1719, 168, -1085, 225, 330, 1480, -183, -597,
+ -6131, 668, -387, 672, -173, -55, 113, 40,
+ -113, -44, 341, -340, -594, -1001, 1757, 127,
+ -59, 537, -1834, 1401, 856, -1153, -234, 1232,
+ -562, 476, 110, 2188, 146, 119, 2119, -872,
+ 450, 597, -371, -1350, -996, -120, -495, 829,
+ 111, -897, -5445, -670, 390, -118, 4, 109,
+ 772, 495, 196, 410, -125, 812, 426, 900,
+ 436, 1155, -553, -1223, 275, 266, -891, 63,
+ -1267, 523, -548, -2445, 239, 1163, 72, -68,
+ -1576, 2212, -340, 1499, 494, -671, -73, -281,
+ 598, 1901, -1652, -845, 266, 795, -545, -574,
+ 19, -461, 371, 288, -3959, 421, 299, -121,
+ -2561, -65, 118, 181, -227, 719, -92, -2334,
+ -3178, -2497, -198, 58, 1279, -309, 152, -715,
+ 466, -316, 10, 98, 1568, -1015, -18, -435,
+ -42, 2606, 1971, -119, 705, 254, 443, 36,
+ 788, 1135, 1234, 2281, 942, 115, 581, -113,
+ -194, -694, 434, -30, 2835, -423, 436, 522,
+ 406, 1329, 1191, -2628, 421, -2601, 646, -202,
+ 637, 610, -584, 357, -1586, -499, -1230, 134,
+ -83, -1264, 2434, -58, -2924, 641, -285, 172,
+ -478, -402, 584, -1180, -137, -238, -151, -679,
+ -619, -495, 1044, 1281, -1180, -444, 376, 1969,
+ -693, -283, 618, 128, -2622, -90, -115, 672,
+ 1738, -459, 519, -924, 2582, 937, -555, 672,
+ 131, 31, 775, 307, -282, -527, -1299, -516,
+ 10, 239, -4069, 118, 10, -665, -15, -484,
+ 472, 262, 279, 677, -755, 1288, -1278, 403,
+ 666, -394, -1230, -2819, -221, 109, 603, 754,
+ 951, 488, -147, -107, -426, 1875, 2056, -129,
+ 239, -561, 81, -324, 243, 349, 197, -811,
+ -146, -929, 1193, 1433, -776, 3209, 434, -6,
+ 2465, -231, -57, 312, 899, -396, -170, -549,
+ 346, 135, 17, -596, 401, 269, 499, -64,
+ -321, -342, -132, -312, 5845, 276, -104, -9,
+ -50, -678, -478, -1125, -1477, 2058, 156, 538,
+ 451, 2572, 495, 101, 74, -753, 98, 685,
+ 2424, -1999, 1050, -280, -1030, 29, -178, -244,
+ -134, 130, -137, -103, -245, 2161, -446, -1016,
+ 464, 573, -473, 446, -3822, 942, -1261, -334,
+ 568, -528, -301, 415, -740, 661, -813, 849,
+ 1491, 774, -774, 1637, -977, -246, 647, -572,
+ -140, -2946, -654, -650, -311, 339, -165, 757,
+ 803, -958, 704, 171, 380, 763, 159, 2721,
+ -1599, 1006, -118, -597, 2985, 2699, 69, 395,
+ 523, 657, 438, 190, 72, 164, -268, -145,
+ 506, -550, 222, -3641, 5, -173, 60, -194,
+ 677, 686, 724, -107, 882, -339, 14, -54,
+ 555, 483, 1523, 119, -142, -394, -1683, -984,
+ 18, -108, -190, 141, 540, 281, -1238, -2195,
+ -341, -327, -1014, -990, 4694, 46, -1018, 360,
+ -671, -83, 218, 857, 144, -188, 463, -379,
+ -571, -865, -1345, -447, -18, -64, 5201, 132,
+ 90, -158, -132, 381, -85, -107, -103, 970,
+ -555, -1204, 1802, 1230, 253, 540, -372, -2347,
+ -386, 835, -705, -437, 941, 795, -182, -368,
+ 1088, 168, 256, 210, -667, 290, 1783, -636,
+ 165, -363, 638, -3527, 1872, 1997, 1503, -189,
+ -2587, -359, 384, 493, -384, -658, -1758, 993,
+ -306, 148, 198, 163, 430, -313, -149, -337,
+ 352, -354, 484, 358, -264, -4525, -560, -55,
+ 154, 374, -317, -426, 1446, -161, -285, -110,
+ 209, 299, 2329, 99, 1406, 1374, 993, 1178,
+ -413, -642, -103, 3678, -1829, -754, -1358, -349,
+ 648, -492, 755, 188, 114, -444, -930, -224,
+ 319, 212, 1223, -648, 593, 1293, -1289, 24,
+ -712, 2591, -494, 1503, -9, 534, 923, 1490,
+ 985, 491, 272, 988, 348, -503, -454, 893,
+ 409, -422, -1187, 3097, 602, -402, 462, 1598,
+ -219, 982, 319, 125, 558, -100, -261, 108,
+ -59, -3435, 76, -1065, -150, -1758, -1997, 1921,
+ 1239, 426, 507, 173, -856, -829, -538, 247,
+ -1203, 488, -1094, 453, -1104, 1021, 2185, -2855,
+ 427, 177, -778, -182, 641, -670, 91, 569,
+ 50, -90, 571, 108, -374, 174, 1997, 964,
+ 644, -428, -1868, 668, 171, 320, 676, 121,
+ -218, 1901, -857, -721, -194, -2433, -34, -1671,
+ 352, -644, 295, 571, 253, -288, -1786, 32,
+ 74, -73, -902, -1954, -1126, -3427, 168, -318,
+ 23, -755, -441, 201, -84, 499, 367, -153,
+ -426, 716, 650, -457, 80, -709, 859, -2098,
+ -723, -197, -1030, -253, 283, -1187, -899, 1403,
+ -117, -25, 7617, -63, -355, -283, -560, -85,
+ -358, -45, 63, 179, -193, 130, -294, -676,
+ -525, -907, -430, -627, -5267, -539, 257, 594,
+ -173, 890, 203, -33, -136, -803, 479, -56,
+ -634, 464, -919, -146, 306, 5, 198, -90,
+ -138, -337, 4826, -310, 259, 1651, -687, -1676,
+ 424, 2729, -966, -61, 386, 60, 769, -72,
+ -1652, 49, 106, 503, -1462, -1056, 892, 359,
+ 209, -129, 260, -130, -2081, 798, 488, 846,
+ -836, -366, 1786, -2237, -484, 72, -2680, -828,
+ -857, 920, 560, 930, -197, 56, -872, -34,
+ -355, 929, 35, -449, 514, 70, -1277, 208,
+ 353, 3654, -256, 134, -895, -184, 375, 402,
+ 1576, 1515, -100, -438, -679, 384, 1143, -24,
+ 100, -2818, 554, -219, 105, 652, -2778, -108,
+ 44, 306, 445, -470, -1151, -1170, 1305, -741,
+ 1223, -443, -838, 374, -3000, 72, -590, -587,
+ 3686, 76, -493, 246, 1348, -1215, 473, -244,
+ -304, 1937, -68, -626, 278, 392, 1167, -1899,
+ -309, 474, 226, -421, -95, -483, 105, -148,
+ 749, -430, -3057, -789, -1793, -1857, -158, -489,
+ -676, -204, 806, -930, -3192, -204, -106, -812,
+ 1159, 648, 119, -93, -205, -139, 280, -7786,
+ -388, -132, -12, -332, 32, -174, 100, 153,
+ -7, 289, -29, -984, -329, -592, 2568, 704,
+ 544, 66, 521, -661, -1632, -868, -310, 313,
+ -466, -347, -146, 197, 266, 765, -240, -201,
+ -265, -1129, -35, -563, -356, 172, 862, 3831,
+ 1547, -1618, -1445, -3726, 388, 548, -457, 143,
+ -38, 402, 255, 840, -703, -154, 776, -1038,
+};
+
+static const int16_t cb2224m0[] = {
+ -7078, 2846, 79, -111, -20, 330, 227, -36,
+ 305, 45, 81, 148, -13, 68, 364, -317,
+ -72, 2021, 28, 93, 328, -256, -181, 2547,
+ 235, -1102, 130, -577, -164, 1290, 1885, -171,
+ -147, -3247, 324, -72, -313, -62, 32, 284,
+ -138, -9, -146, 1709, -390, 1833, 289, 125,
+ 2369, 60, 223, -137, 642, -113, 204, 288,
+ -1516, -138, 228, 368, 219, -622, 273, 3211,
+ -215, -423, 139, 65, 85, -203, -953, 11,
+ 193, 294, 279, 3267, 246, -2377, -59, -324,
+ 136, -492, 23, -56, 79, 307, 115, -146,
+ 2229, 325, -1680, -597, -423, 2200, -44, 48,
+ 386, 396, -122, -36, 35, 9763, 33, -67,
+ 19, -34, 15, 41, -25, -30, -61, 20,
+ -121, 117, -155, -28, -65, -27, 40, 137,
+ 188, -211, -240, 71, -33, -4873, 1992, 56,
+ -2701, -1, 151, -96, 286, -398, -418, -221,
+ 295, -394, -119, -182, -124, 77, 7, -44,
+ 168, -34, -154, 257, 4, -114, 634, 131,
+ 4930, -118, -2364, 46, -204, -129, -3168, -138,
+ -489, 454, -96, 120, -447, 9, -230, 174,
+ 11359, 456, -261, -74, -249, -28, 149, -79,
+ -36, 211, -10, 213, -110, 337, -3800, 4,
+ -223, -18, 136, -290, -155, -235, 57, 447,
+ -495, -231, -15, -1036, -85, -154, -4421, -19,
+ -237, -1191, 12, -19, 2, -88, -84, 269,
+ -7, 431, -26, -2676, -100, 287, -31, -2916,
+ -160, -83, -198, 9, 183, -279, -68, -23,
+ -55, 2955, -121, -71, 183, -702, -323, 1689,
+ -132, 309, 136, -1217, 440, -125, -1671, 1569,
+ -161, -108, 232, 269, -516, 37, 21, -260,
+ -230, 564, -375, 224, 129, 4332, -120, 3306,
+ 153, -25, -260, -84, 123, 21, 5, -17,
+ -145, -44, 7, -1, 290, -2394, -182, 51,
+ 933, 1037, 26, 211, 187, -1783, 68, -749,
+ -52, 1428, -1571, -261, 34, -199, 722, -127,
+ -118, -114, -2385, 146, -1042, -71, -1475, -150,
+ -2195, 151, -29, 6, 96, -1213, 282, 219,
+ 466, 144, -300, 109, -74, 125, 2863, 2,
+ -2963, -218, 235, 3, 359, 319, 372, -500,
+ -271, 494, 2695, -65, -29, 47, 74, -34,
+ -95, -48, -76, -71, -2985, -30, -11, 26,
+ -176, 107, 96, 22, -60, 114, -70, -147,
+ -43, 6981, 110, -86, 33, 66, 8, -61,
+ 52, -169, 82, 233, 56, -115, -295, 241,
+ -1053, -3914, -79, 361, -869, -144, -144, -805,
+ 158, -278, 515, 4, -317, 917, -669, 3314,
+ 253, 1316, 259, 12, 8170, 15, 129, -200,
+ 120, -11, 34, -77, -13, 257, 79, 9,
+ 23, 54, 73, 0, -9972, 5, 7, 43,
+ 29, 4, -104, 43, -36, 76, -228, 1,
+ -77, -156, -69, -209, 84, -2826, 242, -1461,
+ -718, -14, 1784, 527, 226, 9852, 83, -15,
+ -389, 34, 51, -16, -46, -1, 232, 115,
+ 26, -42, -124, -78, 58, 3092, -2757, -111,
+ 223, -286, 23, -170, -166, -264, 331, -172,
+ -49, -26, 166, 2616, 128, 3118, 59, 844,
+ -121, -504, -193, -53, -95, 282, -21, -8,
+ -11, 58, -48, 9830, 25, -26, 53, 113,
+ 96, 125, 12, -64, 185, -31, 19, -251,
+ -307, -136, 1383, -37, -128, 56, 4303, -232,
+ -272, 44, -192, 531, -143, -697, -2291, 70,
+ 229, -432, -592, 1262, 906, -207, 1522, 261,
+ -7848, -39, -976, 150, 115, -139, 61, -26,
+ -211, 807, -25, 311, -98, -297, 133, 461,
+ -109, -6, -1031, 236, -2851, 86, 2184, -254,
+ -83, -119, 878, -107, -25, 1636, 1696, 1517,
+ 249, -41, -283, -66, 741, 704, -898, 302,
+ 470, 360, -7, -6002, 26, 268, -109, 150,
+ 202, 196, -262, -57, 160, 155, 7, 9,
+ -5770, 28, 127, 112, -76, -790, 45, -118,
+ 201, -831, 67, -81, 199, 296, 1692, -30,
+ -126, -121, 29, 387, 215, 269, -518, -232,
+ 155, 2735, -235, -82, -33, 3089, -3696, -39,
+ -51, 124, -220, 37, 51, -129, 194, -80,
+ 81, 0, -239, -1924, -244, 107, 372, 111,
+ 206, 418, 39, -118, -2059, -446, 1378, 661,
+ -2135, 122, -105, 60, 272, -91, -227, 48,
+ -3226, -88, -109, 199, 566, 158, 2412, -4380,
+ -177, 153, 252, 24, -323, 264, -116, -12,
+ -333, 99, -181, -124, 256, -131, -39, -45,
+ -88, 69, -26, -173, -4820, 286, -171, -82,
+ 431, 18, -827, -107, 142, 60, 300, 422,
+ 263, 61, 350, 85, 1088, -133, -1284, 70,
+ -4577, 5, 114, -23, 23, 2907, 174, 43,
+ 18, 33, -31, 320, -9, 290, 2, -7,
+ 39, -11, 52, 32, -4, 8454, 18, 10,
+ 67, 20, 22, -3, -209, -103, -212, -101,
+ -101, -420, -2837, -28, 398, 140, 1027, -187,
+ -2338, 406, -152, -288, 723, -412, -1851, 185,
+ 641, -190, 107, -7, -3194, -128, -382, 165,
+ -256, 85, 96, 155, -144, 431, -356, 342,
+ -2508, -2190, -265, -320, -1345, 27, -1981, -1949,
+ 95, -78, -456, -359, 382, -218, -102, 164,
+ 382, 907, 599, 665, 2843, 4275, 17, -156,
+ -264, 73, 104, -25, -120, 91, 84, 325,
+ 170, -65, -245, -23, 89, 52, 4651, 124,
+ 185, 30, 321, 145, 111, -1265, 128, -156,
+ 64, 24, -1934, 133, -84, -10, 34, 801,
+ -148, -88, 169, -1687, 419, 1739, -204, -70,
+ 185, 117, 379, -420, 145, -3650, -264, 1118,
+ 331, -818, -665, -420, 74, 32, -152, -226,
+ 6, 216, 4173, 23, 1230, 239, 2, -57,
+ -690, 516, 90, 58, -24, -61, 175, -2796,
+ -113, -270, 94, -2319, -158, -1075, -275, -647,
+ -3839, 37, 4267, 20, -49, -88, 72, -171,
+ -195, 45, -23, -159, -64, 110, -211, 42,
+ -211, 1591, 276, -3662, 213, 54, -180, 786,
+ -92, -329, 382, 344, 165, -63, 14, -7,
+ 66, 29, 8875, 43, -50, 65, 13, 15,
+ 48, -40, 114, 125, -27, 158, 3, 843,
+ 8, -646, 100, -3121, 1720, 88, 898, 346,
+};
+
+static const int16_t cb2224m1[] = {
+ 9581, -198, -100, -22, 237, -15, -101, -23,
+ 46, 129, 63, -143, 5, -307, -143, -9,
+ 27, 50, 40, 6048, 25, 58, -16, -161,
+ -109, -157, 137, 115, 121, 164, 4, -54,
+ 6477, -68, -120, -29, 45, -8, -13, 334,
+ -87, 105, -1460, 28, -334, -163, -64, -3629,
+ -71, 176, -195, 53, -1, -96, -560, -21,
+ 135, 178, -77, -4202, 20, 2544, -205, 85,
+ -332, 158, 61, -105, 398, -88, 14, 241,
+ -149, 62, -124, -136, -153, 27, 190, 2595,
+ 25, -2499, -530, 1809, -104, -2753, 298, 145,
+ -771, 139, 165, 2462, -502, 860, -174, 199,
+ 74, 163, -686, -25, 57, -103, -309, -360,
+ 39, -296, -2765, -319, -950, -678, -1159, -1743,
+ 1499, 1776, -176, 9, 44, -581, 69, 39,
+ 162, 326, -96, 329, -9, 1274, -2443, -105,
+ -50, 4212, -23, 146, -231, -22, -50, -128,
+ 11, 28, 116, -215, 46, 217, 204, 153,
+ -73, -156, -100, -31, 2632, -190, -2258, 199,
+ -1757, 194, 53, 38, -5723, 66, 169, 352,
+ -39, -150, -1, -462, 41, -98, -110, -40,
+ -5763, -190, -158, -1380, 205, -227, -402, 81,
+ -171, 407, -125, -320, -456, -317, 489, 698,
+ -308, 3989, -172, 402, 196, -457, -1238, -192,
+ -581, -63, -235, 153, -1094, -53, -45, -86,
+ 240, -192, -2660, 2356, 153, -60, 277, 33,
+ 198, -57, 1221, -2984, -327, -326, -48, 61,
+ 93, -34, -167, -311, 904, 348, 415, 57,
+ 2000, -77, 238, 40, -3072, -36, 283, -54,
+ -655, -250, -22, -569, -584, -18, 733, -251,
+ -72, -28, 80, -306, 211, 188, -149, 4596,
+ 305, 372, 351, -82, -184, -79, -65, 2688,
+ 2670, -54, -81, -170, 19, -88, 122, -117,
+ 33, 51, -29, -113, -2973, 46, -3294, 90,
+ 8, -180, -227, -62, 43, -25, 187, -380,
+ -29, -89, 138, -352, 231, 2632, 158, 1993,
+ -15, 350, 107, -982, -16, -1120, 136, -171,
+ -42, 2605, -186, 110, 167, 1673, 1140, -29,
+ -689, 81, 909, -455, 2979, 44, 1, -260,
+ 26, 28, -90, -568, -123, -175, 232, -38,
+ 2372, 111, 312, 529, -65, 331, 100, 488,
+ 12, -596, -497, 2311, -1097, 1242, -94, -2290,
+ -158, -2651, 16, -232, 3352, 24, -53, -83,
+ -5, -52, 205, -104, -294, 217, -196, -37,
+ -7, 0, -28, -45, 60, 13, 41, 111,
+ 142, -7331, -40, -200, 18, -166, -1266, -47,
+ -250, -592, -604, 33, 83, -204, -1131, -166,
+ 1348, -1337, 184, 50, -10066, 30, 24, -184,
+ 137, 53, 32, 87, -27, 151, 100, 10,
+ -47, 28, -138, 12, -2977, -376, 58, 168,
+ 1642, 144, 1039, -399, -807, 5, -1715, 12,
+ -142, -77, -306, 758, 674, -82, 3216, -369,
+ 60, 480, 276, -423, 5102, 3325, 169, 47,
+ 235, 37, 81, -86, -28, -56, -59, -205,
+ -126, 28, 279, -8433, 137, -26, -409, -19,
+ 106, -163, -76, -57, 235, 7, 131, -81,
+ -197, -318, 1281, 310, -2934, 972, -1335, 35,
+ -308, -93, -128, 433, 527, -193, -1303, 162,
+ -34, -87, -157, 262, 4999, 25, -311, -349,
+ 94, -262, 0, -219, 57, 12, -4, 10,
+ -17, 38, -320, 48, 156, 80, 5880, 48,
+ 45, 31, -1022, 31, 227, -727, -135, 261,
+ -21, -688, 307, 3196, 565, 627, -546, 237,
+ -2367, -33, 1622, -87, 1722, -201, 720, -539,
+ -288, -1012, 141, -388, -72, -20, -59, -2042,
+ -53, -101, 208, -233, -835, -16, 3092, 2,
+ 310, 94, -362, -163, -128, 30, -22, -145,
+ 420, -1, 322, -524, 2742, -276, 206, -2475,
+ 575, -653, -342, 1412, 1, 75, -14, 54,
+ 170, 66, 342, -261, 709, -75, 2240, -134,
+ 32, 665, 171, -134, 1822, 109, 569, 3129,
+ 168, -356, 53, 1259, -67, 43, 120, -124,
+ 2185, 2461, -17, -255, -349, -167, -158, -19,
+ 84, -732, -972, 286, 87, 4603, -160, 7,
+ 141, 1, 286, 310, -315, -99, 282, 384,
+ 68, 93, -1815, 63, -86, 121, -293, 210,
+ 115, 63, -174, 616, -1848, -124, 1275, 298,
+ 185, -267, 3516, -105, -162, -253, -434, -674,
+ -90, -2232, 38, 168, -261, 289, 70, 3714,
+ 4096, -81, 17, 56, 57, 68, -20, -146,
+ 28, -152, -17, -97, -131, 2648, 71, -3359,
+ 40, -277, 313, 85, -26, 41, -202, 76,
+ 8, -80, -160, -102, -17, 155, 189, 1552,
+ -3498, -446, -103, -232, -205, -574, -132, 169,
+ 206, 1689, 1043, -736, -178, -93, -2969, 26,
+ -251, -148, 139, 70, -325, 117, -3073, 9,
+ 43, -11, -380, -190, -314, -3012, 50, -330,
+ -26, 710, 153, 19, -2943, 58, -3052, -56,
+ 7, 40, 9, 321, -37, -461, -22, -374,
+ 57, -203, 16, -15, -25, -16, -37, -8,
+ -41, -116, 7964, 70, -59, 77, 200, 0,
+ -43, 118, -72, -67, 104, -6, 78, 171,
+ 13, -103, 793, 98, -4738, -204, 11, 30,
+ -72, 33, -62, 47, 157, 236, -147, -416,
+ -726, 578, 5, 4038, 162, -2, 2367, -138,
+ -185, 470, 3121, 70, 185, -22, -205, 37,
+ -63, -335, -397, 43, 10, -6557, -112, -254,
+ 106, -129, -236, 0, -250, 42, -128, 84,
+ -531, -27, 2259, -282, -21, -70, -408, 19,
+ -664, 945, -196, -1074, 1369, -40, -3233, 28,
+ 20, -2133, 125, 343, 113, 584, -14, 50,
+ -130, -464, 513, 807, -4474, -63, 57, 1120,
+ 64, -30, 346, 462, 129, 219, -30, 287,
+ 448, 384, 198, -359, 1097, -256, 828, -2635,
+ -314, 336, 506, -144, 194, 167, 1323, -273,
+ -4168, 2805, -118, -8, 136, -82, -212, 53,
+ -259, -61, 94, 214, 11, 29, -262, -69,
+ 24, 102, 45, -31, -186, 58, 641, 659,
+ -172, 3628, -192, -423, 34, 3, 45, 19,
+ 349, 117, -5, -4923, 99, -148, 180, 631,
+ 50, -204, 641, -92, 156, -1985, 1077, 201,
+ 56, -405, 710, -220, -1917, -273, -234, 100,
+};
+
+static const int16_t cb2224sl0[] = {
+ -3113, 97, 229, 309, -156, -226, -469, 582,
+ -3202, -336, 102, 20, 96, -960, 297, -227,
+ 592, -3352, 2798, -637, -133, 191, -407, 170,
+ -576, -203, -280, 808, 853, -502, -113, -1704,
+ -1025, 411, 2802, 233, -568, 360, -616, -1715,
+ 47, 391, -2117, -458, -291, -149, -82, 26,
+ -29, -88, -156, 7905, 32, -75, -154, -78,
+ -44, 155, -1, -338, -891, 170, -75, 155,
+ 226, -192, -328, -239, -574, -91, 95, -600,
+ 4271, 25, 990, -207, 4676, 59, -324, 884,
+ 363, 65, 423, -776, -906, -79, -4, 1475,
+ 549, -252, 3584, 3543, -409, 282, 278, 125,
+ -379, 125, -180, -123, -252, -316, -193, 347,
+ 53, 2009, 195, 152, -104, 233, -75, -546,
+ 564, -177, 3243, -865, -924, 518, -692, -381,
+ -1885, -110, -188, 1140, -2043, -438, -1721, 1019,
+ 1678, 13, 273, -751, 922, -291, -15, 75,
+ 232, -112, 60, 2702, 88, 175, -119, 43,
+ -549, -1094, -1879, 401, 1587, 1287, -41, 41,
+ -116, -23, 313, 168, 147, -101, -57, -115,
+ -6990, 54, -14, -240, -164, 127, 25, -703,
+ -361, 769, 1555, -2440, -2616, -192, 86, 769,
+ -29, -721, 554, -663, 327, 659, -31, -79,
+ 91, 365, -74, 1268, 115, 480, 3054, -1758,
+ 1704, 759, -657, -272, -329, 31, -145, -534,
+ 1265, 73, 435, -54, 480, -867, 2724, 2373,
+ 890, -314, -112, -2576, -598, 473, 121, 2764,
+ 1659, 105, 579, -416, -87, 158, 300, 447,
+ -281, -6109, 35, 217, 185, 56, -357, 151,
+ 108, -49, -282, -484, -220, -78, -141, 256,
+ -1095, 1812, -985, 1115, 555, -2116, 2317, -1141,
+ -792, -866, -119, 187, 615, -194, 73, -43,
+ 268, 437, 250, -52, 477, -249, -475, -2621,
+ 590, -2987, -603, -652, 971, -684, 337, -140,
+ -336, 2342, 390, -204, 295, 85, -44, 321,
+ 754, 2660, 61, 782, 1654, -76, 2727, 1590,
+ -1099, 354, 49, 2784, 443, -762, 828, -308,
+ -493, -755, -370, -336, -207, 388, 630, -127,
+ 1955, 1929, 1270, 2054, 525, 388, 562, 942,
+ -789, -453, 158, 995, -99, 2258, -317, -493,
+ 385, -90, -79, 199, -1187, 519, -254, 179,
+ 573, 2803, 2341, 407, 95, 515, 332, 1,
+ -6, -337, 142, -316, 418, 542, 3281, 10,
+ 604, -542, -1595, 43, 79, 10, 75, -122,
+ 100, -55, 212, -223, -353, -557, 490, 4870,
+ -3689, 3594, -145, -192, -47, -252, -380, -180,
+ -221, 656, 78, -188, 120, 135, -253, -437,
+ -208, -151, -504, 217, -3715, -150, 528, 121,
+ -1468, 383, 823, -55, -1167, -8, -198, -515,
+ -296, -24, 84, 129, -472, 7, 5071, -114,
+ -200, -16, -271, 59, -430, -142, -315, 90,
+ 273, -56, 370, 3342, -159, 235, 934, 1605,
+ -1499, 207, -1650, 1137, 396, -2250, 276, -320,
+ -317, -23, 276, -519, 163, 566, 366, -6,
+ 2262, -2035, -662, -3300, -133, -3811, -362, -348,
+ 113, 146, -79, -298, 238, 221, 99, 194,
+ 326, 325, -112, -8160, -59, -15, 8, -41,
+ -261, -20, -6, -68, -140, -41, 167, -125,
+ 129, 337, 2404, 281, -336, -475, 2085, -2646,
+ 572, -1308, 376, 114, -506, 1062, -575, -529,
+ 3347, -212, 520, 274, -163, -3058, -93, -203,
+ -932, -207, -36, 303, -117, 278, 287, 204,
+ 205, -228, -242, 227, 3, 611, -190, -458,
+ -44, -209, 122, -390, -4561, -139, 1378, -329,
+ 440, 989, -1782, -348, 1241, 967, -477, -2312,
+ 554, -970, -1103, 473, -771, -50, 150, 327,
+ 394, -267, -648, -680, 2376, -2543, 276, 1220,
+ 552, 10, 1399, -1498, -801, 9, 2351, -55,
+ 155, 327, 88, 864, 428, 179, -3234, 6,
+ 544, -647, -306, 132, 329, 1147, 1920, 1436,
+ -2107, -1122, 341, 2020, -432, -97, 117, 793,
+ 100, -693, 174, 3639, -570, 910, -2771, 231,
+ -148, -960, -1085, 57, 188, 744, -709, -441,
+ 533, -295, 1287, 2939, 2987, 885, 611, 700,
+ 364, -205, -855, -617, 48, -162, -244, -318,
+ 208, 772, -124, -2505, 454, 330, -220, 335,
+ -362, -899, -827, 2188, -40, -1638, 356, -160,
+ -127, 2886, -69, -41, 209, 1847, -236, 2752,
+ -24, 387, 354, -111, 526, -237, -2169, 1319,
+ 2211, 144, -348, -434, -319, 1373, 78, 906,
+ 701, 539, -134, 414, 496, -325, -36, 116,
+ 124, 4198, -35, -439, -208, -531, -100, 1453,
+ -175, 723, -908, -461, 87, 127, -91, -125,
+ -140, 8012, -186, 23, -93, 107, 176, 218,
+ 35, 193, 174, -27, -4, 77, -103, -199,
+ 116, -41, -80, 186, -6965, -188, 125, -54,
+ 43, 9, -49, -192, 69, -136, -24, -117,
+ -2244, 2289, 145, 226, -1161, -1950, 881, -152,
+ 1611, 1015, -174, -277, -158, 369, 49, -233,
+ 221, 275, 69, 108, 136, -124, 1, -470,
+ 376, 149, -7596, 55, 53, 213, -247, 80,
+ -217, -11, 189, 125, -17, -141, 165, -2890,
+ 14, 201, 106, 242, -254, -306, -3157, 459,
+ -10, 24, -271, 877, 437, -438, 18, -126,
+ -9, 5553, 63, 22, 55, 172, 21, -335,
+ 127, 160, 208, 121, 13, 1989, 676, -294,
+ 2208, -78, 634, -1518, -1037, 1309, 124, -39,
+ -322, -1420, -404, 377, -35, -14, 178, 110,
+ -8146, 26, -98, -153, -243, 145, 280, -8,
+ 29, -57, 85, -309, 281, 282, -47, -27,
+ 2827, -947, 141, 856, -2481, 406, -638, -362,
+ -1031, 230, -341, -119, -17, 1, 190, 41,
+ -15, 5111, 59, 74, 123, -282, -25, -300,
+ 4, -460, -216, 295, -217, 26, 227, 62,
+ 385, 748, 2923, 1946, 391, -1676, 599, 148,
+ -456, -96, 1066, 478, 117, 255, -169, -669,
+ -1939, -656, 2676, 677, -2020, -1314, 425, -525,
+ -89, -522, 2707, 153, 5, -207, 244, -1045,
+ 331, -1315, -82, 449, -2444, 326, -484, -2232,
+ 2380, -591, -999, -2552, -1581, 349, -440, 217,
+ 298, -729, -6, -396, -74, 110, -70, -3543,
+ -388, -51, 596, 126, 295, 2075, -123, -693,
+ -1072, -1779, -420, 127, 432, -3241, -231, -246,
+ 105, -437, -67, -119, -2941, -257, 47, -969,
+ 379, 618, -93, 7, 202, -425, -38, 140,
+ 458, 3599, 242, -24, -811, -624, -19, 524,
+ 2398, -300, 111, 376, 2015, 431, 125, 231,
+ -293, -2379, -634, 1842, -1, -1326, -610, -88,
+ 128, 80, 75, 30, 172, -235, 34, 206,
+ -79, 328, 128, -283, -6862, -101, 260, 68,
+};
+
+static const int16_t cb2224sl1[] = {
+ -3710, -340, 3183, 200, -124, 423, -417, -432,
+ 232, -808, 85, -145, 39, 196, -197, -60,
+ -154, -213, -320, -2941, 993, 3044, -508, 61,
+ -853, 75, 40, 873, -765, -365, -621, -2670,
+ 188, 57, -403, -230, -137, 40, 565, -1910,
+ -1120, -1019, -603, -1927, 150, -3089, 23, -416,
+ -199, -3265, 15, 128, -525, -531, 91, -39,
+ 578, -388, 315, 40, 2376, 1762, 2, -1475,
+ -1774, 111, 934, -459, 777, -582, 114, -218,
+ -82, -195, 165, 2171, 632, -67, 239, 345,
+ -257, 104, -34, -879, 488, -422, -2156, -823,
+ 1940, 699, 2911, -233, -125, -218, -111, -335,
+ -3475, -61, -71, -445, 249, -330, 102, 376,
+ -116, 2667, -453, 19, -4129, 90, -507, 236,
+ 418, 43, 79, 61, 296, 181, 190, 408,
+ 216, 198, 32, -81, 245, -157, 5555, -162,
+ 318, 179, 339, -463, -448, -254, -526, -192,
+ -427, 575, 588, 2792, 2683, -853, -566, 19,
+ -26, 106, -220, 518, 734, -233, 68, -604,
+ -231, 256, -187, -59, -405, 206, 331, -25,
+ -4837, -323, 146, 541, 723, 915, -144, 450,
+ 102, -371, 27, 88, -80, 276, 239, 101,
+ 157, -69, -14, 234, -8192, -18, -110, -52,
+ -8, 48, 79, -43, 153, 187, 211, -118,
+ -111, 238, 11, -2006, 680, 478, -695, 3078,
+ -30, 892, -23, 1512, -194, 423, -16, -318,
+ 895, 406, 634, 47, -3277, -205, -764, 297,
+ -357, -61, -188, -1547, -868, -174, 342, 261,
+ 1926, 88, -35, -3250, -20, 3168, -368, 778,
+ 376, 167, 598, 442, 134, 487, 164, -32,
+ 245, 436, 2067, 595, -578, 49, -163, 633,
+ 138, -279, -99, 118, 1141, -3168, 580, -90,
+ -3192, 551, -663, -2673, -55, 147, 1307, 9,
+ 15, 432, 307, 527, 1002, -469, -2380, -342,
+ -293, -73, -259, 410, 309, 76, -320, -161,
+ 282, -3300, -7, 160, 732, 484, -65, 147,
+ 2923, 2321, -840, 1933, 268, 684, 1172, -377,
+ -365, -568, -283, 492, -538, 409, -194, 17,
+ -297, -52, -123, -270, 161, -94, 92, 4495,
+ -396, 540, 229, -30, -108, 29, 1, 198,
+ 492, -572, -394, -2386, 2787, 885, -1175, -129,
+ -1137, 220, 148, 261, -65, -244, 1, 58,
+ 195, -49, -290, -94, -21, 105, 71, 6641,
+ -200, -407, -496, -75, 233, 222, 549, 363,
+ 188, 739, -869, 122, -355, 3326, 323, -2366,
+ 115, -3207, 2783, 2015, 148, 924, -153, -133,
+ -175, -287, 400, 73, -181, -174, 72, 45,
+ 219, -92, -11, 59, -5407, -362, -188, -120,
+ 239, 249, 133, -229, 158, 180, -575, -2386,
+ -354, 248, 532, -590, 615, -85, -69, 394,
+ 3052, -877, -320, 484, 218, -463, -202, -841,
+ 1729, 284, 1253, 2193, 526, -2444, -351, 1287,
+ -373, 387, 440, -203, 163, -153, 206, -57,
+ -96, 2616, -84, 552, 33, 705, -731, -843,
+ -2197, -2138, -570, 22, -264, 2143, 725, -132,
+ -392, 471, -245, 51, 739, -1057, 1049, -760,
+ 2701, 456, 20, 484, 595, 3248, -1415, -862,
+ 332, -417, 323, -431, 2082, 78, 684, -169,
+ 596, -228, -219, 172, 160, -180, -228, -3193,
+ -520, -100, -447, -629, -2178, -259, -246, -1788,
+ -2264, 223, 115, -74, 230, -2515, 212, -179,
+ 456, 209, -2379, -246, -345, -102, -559, 259,
+ -270, -426, 333, -358, 2866, -589, -1494, -418,
+ -160, -138, 2088, 683, -1313, 1061, -88, 916,
+ -148, -2329, -301, -271, -249, 2822, -525, -405,
+ 592, -322, -1328, -16, 135, -582, -676, -503,
+ -2162, -327, -237, 361, 166, 600, 1176, 1015,
+ 97, -5, 465, 2321, -4544, 202, -350, 313,
+ 149, 544, -420, 552, 183, 351, -1663, 688,
+ 238, 587, 907, -1719, 1267, -2325, 368, 236,
+ 296, -2608, 240, 997, 496, 105, 75, -179,
+ 235, 125, -40, 57, -22, -412, -464, -494,
+ -81, 576, -3461, -1037, -744, 1358, -856, -284,
+ -536, 387, -358, 184, -85, 2150, -1142, -124,
+ 119, 1242, 648, 711, 2161, -591, -1864, -672,
+ 62, 1879, -13, 55, 285, -167, 142, -130,
+ 322, 8, -35, -230, 632, -699, 4114, -500,
+ -189, -48, 2746, 47, 421, -1200, 2418, 460,
+ -306, 331, 164, -1358, 802, 453, 458, 3594,
+ 3065, -24, -134, -437, -892, -110, 241, -368,
+ 336, 673, -147, 130, 154, 89, 81, -341,
+ 7151, 175, 118, -227, -282, 262, 276, -118,
+ -118, -245, 7, 144, -87, -136, -146, -484,
+ 70, 221, -220, -13, -7638, 93, -38, -319,
+ -478, 26, -28, 281, -180, 182, -186, 90,
+ 192, 50, -2919, 153, -2651, 289, 47, -783,
+ 768, 384, 39, 194, -2358, 1242, -1679, 80,
+ 1292, 28, 682, 2807, 342, 466, 299, -380,
+ 376, 4466, 12, 553, 153, -447, 733, 99,
+ 8, -142, 606, -2364, 168, 167, -62, 404,
+ -3144, 352, 115, -3734, 360, -202, -462, -196,
+ 464, -412, 192, -363, -413, -405, 254, 357,
+ -2801, 1054, -1602, 642, -254, -430, -2259, -97,
+ 16, -311, 757, -64, 412, 339, -227, -216,
+ -29, 219, 67, 63, 26, -232, -138, -301,
+ 241, -52, -6118, 223, -379, -157, -221, -201,
+ -93, -5630, -286, -194, 133, 46, 151, 444,
+ -472, 103, -115, -259, -53, 673, 1744, -2374,
+ 359, 2541, 613, -393, 1235, 221, -117, -842,
+ 1166, 105, -142, 1426, 3, -423, 36, 398,
+ -2742, 723, -740, 985, 498, 431, -1312, 832,
+ -1644, 146, -69, -110, 420, -130, 335, 269,
+ -2865, -67, -88, 50, 2735, 1038, 973, 371,
+ 654, -169, -112, 579, -319, 2434, -760, 710,
+ 241, -1889, 39, -1807, -30, 1383, -1080, 449,
+ 639, -2478, -760, 559, 298, 56, -421, 818,
+ -442, 1558, -1610, 2136, -12, -11, 592, 73,
+ 77, -172, 77, 92, -113, 281, 581, -584,
+ -4448, 507, -195, 183, -508, 312, -724, 1043,
+ -18, -10, -776, -534, 249, -3178, 904, 1234,
+ -482, 382, -1040, -448, -579, 227, -82, 5628,
+ -165, 255, 109, -141, 7, -28, 63, 93,
+ -211, 0, 162, 581, -153, 5844, -66, 122,
+ -102, -90, -205, -181, 243, 312, 111, -435,
+ -105, -343, 272, -141, 6, -98, -16, -73,
+ -26, -125, -7627, -73, -66, 108, -175, 186,
+ -189, -102, -240, -37, -354, -260, -120, 30,
+ 87, 2560, 3157, 369, -662, 338, -503, -66,
+ -1405, 178, 1100, -683, -2618, 2459, -1291, -248,
+ -139, -683, -865, 1445, 165, 368, 507, -585,
+};
+
+static const int16_t cb2224ss0[] = {
+ -6880, 657, -621, 69, 219, -588, 681, 229,
+ 248, -302, -110, 734, 12, 253, -454, -890,
+ -3596, 778, -2600, -256, 529, 332, -69, 295,
+ -455, 982, -265, -70, -332, -367, 1494, 586,
+ -158, -1054, 2529, -313, -661, -1302, -2486, 476,
+ 5, 126, 581, 361, 1618, 650, 2033, 202,
+ 76, -265, -161, 3659, -800, 1069, -167, -1792,
+ 389, -580, 597, -268, 621, -1035, 710, 854,
+ 2004, -785, 2714, 1659, 785, 800, -80, 9,
+ -341, -1032, 789, 651, 1068, -609, 661, 747,
+ -928, -999, -1369, -1173, -416, 1596, -2800, 330,
+ 546, -1275, -746, -392, -529, -378, 3571, -2795,
+ -731, -183, -330, -1591, 371, 866, 323, -516,
+ -89, 2277, 1593, 960, -1726, -2229, 727, -415,
+ 189, 500, -145, -177, 550, 467, 240, 1131,
+ 474, -419, -1236, 674, -616, -519, 2439, -1213,
+ -650, 867, 974, -908, 1229, -512, 932, -495,
+ -2521, -865, -466, 8, -426, 912, -77, -236,
+ -407, 433, 128, 3653, 854, 243, 770, 191,
+ 224, -68, -453, -383, 279, -701, -691, 282,
+ -449, 1148, -783, 241, -5021, 643, 8113, -345,
+ 13, 90, -57, 475, 64, -268, -163, -100,
+ -95, 518, 577, 541, 2055, 358, -157, 360,
+ 280, -840, -1161, 500, 95, 302, -662, 1134,
+ 827, 3300, 695, 775, -798, -2651, -2891, -1123,
+ 555, -1125, 156, 328, 671, 751, -347, -972,
+ -392, -1216, 2725, -5152, -402, -15, 150, 31,
+ -182, -278, 245, 81, -3, -46, 310, -72,
+ -138, 1511, -1762, -1840, -364, 123, 2801, -16,
+ -543, -1312, 562, -262, 148, 521, -711, 61,
+ -863, 145, 329, 761, 76, -155, 101, -4986,
+ 192, 269, -364, -174, 640, -261, 629, 3638,
+ 397, -1757, -1177, 342, 388, 1089, 824, 115,
+ 150, 125, 806, 1271, -198, 800, -175, -897,
+ -649, -837, 690, -755, 1416, -2347, 1179, -781,
+ 826, 1567, -148, -156, -1036, -1572, 1248, -187,
+ 464, -260, -749, -1070, 85, -466, -2160, -2802,
+ 233, -181, 447, -482, 113, 548, 2957, -1600,
+ 1341, -559, 803, 2085, -807, -711, -1169, -456,
+ 657, -76, -147, 1932, -1054, -967, -1100, -49,
+ -2829, 1412, 929, 1207, 58, -146, 77, -458,
+ 538, -627, -12, 214, -2397, 692, 1284, 366,
+ 1286, 1997, -856, 267, 1866, 1236, 25, 254,
+ -1187, 3456, 283, 584, 2348, 604, -1130, 7,
+ 500, 232, -51, 120, -695, -930, 317, 67,
+ -1346, -500, 312, -1060, -2338, -1860, -1491, 1539,
+ -1707, 778, -653, -41, 401, 311, -13, 2155,
+ -1011, 1163, 712, 2090, 1336, -726, 574, 1200,
+ -1254, -1567, 723, 683, -877, -653, 1137, -1594,
+ 1127, 2641, 465, 259, -2095, 696, -405, 40,
+ -259, -808, -942, 395, -180, -1119, -966, -230,
+ -534, -114, 88, -661, 757, 75, -286, -119,
+ 924, -2925, 2483, 1662, 1823, 590, 4307, 810,
+ 447, 165, 243, -184, -162, 436, -126, -194,
+ 365, 601, -354, -1983, -211, -663, 276, 155,
+ -696, -2542, -830, 2374, -235, -585, -469, -478,
+ 21, 867, -1633, 1949, -949, -330, -546, 328,
+ -224, 1236, 266, -1117, 36, -61, 221, 153,
+ -3491, -1463, -237, 4676, -241, 273, 268, 347,
+ -393, -277, 168, 426, 155, -65, -605, -569,
+ -1416, -1303, 1248, 595, -148, 512, 3622, 291,
+ -444, -523, 616, 105, 101, 1357, 772, -337,
+ 494, 570, 15, 150, -400, 572, 590, 1674,
+ -4106, 940, 167, -327, -336, 696, 591, 362,
+ 279, 4489, -1325, 608, 294, -41, 549, 982,
+ -31, -184, 367, 77, -466, 398, -1928, -607,
+ 239, 55, 15, 1031, -486, 2788, 2151, -519,
+ -1197, -1144, 274, 671, 1620, 2079, -1555, -961,
+ 543, -11, 26, -627, 777, -581, -1060, -1177,
+ -808, 807, 2863, 607, 144, 195, -274, 18,
+ -5656, -355, -1026, 56, 116, -431, -493, 517,
+ 286, 353, 353, 199, -651, -863, -276, -556,
+ -562, -867, -143, -355, -323, -14, -54, -5354,
+ -43, -1592, 8, -543, 24, 94, -731, -545,
+ 705, -171, 504, -1078, -3367, 1349, 452, -148,
+ 1183, -1650, -1400, -246, -1032, -119, -309, -566,
+ 998, -3240, -444, -658, -605, -186, 491, 439,
+ -190, 688, -29, -965, 2562, -112, -329, -25,
+ -2593, 355, -53, 692, 12, -593, 1930, -804,
+ -82, 386, -632, 927, 1006, -229, -1147, -181,
+ -1075, -245, -3678, 904, -298, 2263, 50, 563,
+ 337, -1051, 173, 310, -3540, -615, -504, 749,
+ 192, -90, -113, -730, -1994, 802, -45, 2234,
+ 167, 289, 1722, -562, 682, 453, 1571, 171,
+ -2429, -441, -230, -1144, 985, -1602, 358, -685,
+ -23, -523, -529, -2438, 700, -624, 37, -1475,
+ -1318, 3292, 702, 394, -798, 2563, 1057, -335,
+ 614, 270, 3135, -1281, -2089, -250, -140, 45,
+ -517, -470, -1429, -172, 2637, 267, 55, -1037,
+ -174, 912, -865, -786, -406, 537, -2805, -642,
+ -1599, 888, -1044, -175, 312, 28, -1157, -240,
+ -181, 298, 521, 3802, -87, 93, 48, 1336,
+ -1071, -1870, 339, -1106, -944, -1036, 361, -3719,
+ -147, 625, 326, -122, 407, -217, 396, 273,
+ -2, -315, -262, 632, 6868, 228, -267, 207,
+ -29, -274, 192, 63, -353, 588, 550, -3,
+ 156, 2115, 1580, -2366, 306, 633, 1354, 2313,
+ -360, -345, 270, -499, -976, -3685, -1305, 907,
+ 1431, 1545, -1334, 18, 1159, 229, -124, 157,
+ 470, -105, 700, -1786, -1895, 795, -1052, -278,
+ 745, -111, -45, 694, 599, -3469, 552, -70,
+ -222, 45, 896, -251, 1, 250, -769, 301,
+ -1151, 1313, 4314, 710, 680, -169, -663, 40,
+ 399, 1171, 581, 775, 936, -488, -2918, 155,
+ -169, -1560, -862, -473, 783, -72, -1791, 567,
+ -2109, -156, 1250, -1486, 3253, 61, -50, -374,
+ -277, 942, 111, 607, -316, 197, -748, 871,
+ 612, -242, -296, 53, -193, 1233, 11, -962,
+ 505, -4492, 21, 754, -150, 451, 183, 881,
+ -652, -159, 6384, 170, 271, 1035, 401, 48,
+ -463, -240, -95, -625, 613, -91, -1138, 1172,
+ 542, -1483, -2638, -1396, -1173, 612, 512, 1355,
+ 977, -362, -22, -17, 124, -3178, -532, 352,
+ -2691, 610, 569, 740, -1603, -5, -492, 704,
+ -436, -96, -595, -1495, 2730, -3089, -164, 565,
+ 1300, -477, -569, 1069, 294, -233, -133, 708,
+ 150, 388, -2108, -1042, -1603, 2275, -1722, 561,
+ 140, 507, -899, -281, 162, -1297, 1504, -158,
+ 193, -730, -944, -2484, 615, -30, 32, -354,
+ -383, 86, 329, -3434, -382, -1604, -299, 208,
+};
+
+static const int16_t cb2224ss1[] = {
+ 8192, -187, -471, -201, 185, -465, 976, 257,
+ 83, -530, 310, 676, 341, 48, 265, -351,
+ 306, 280, 302, 48, 496, -339, 424, -5250,
+ -253, 604, -317, -289, 278, 573, -579, 79,
+ 3218, -574, -377, 276, 2831, -287, -254, 332,
+ -225, 42, 162, -457, -959, -1421, 683, -59,
+ -33, 3362, 393, 606, 249, -873, -930, 1224,
+ 1469, 37, -1592, 1665, -582, 1729, 284, 106,
+ -4753, -120, -475, 867, -444, -203, 431, -11,
+ -526, -324, 732, -1070, -160, -611, 1808, -297,
+ -536, -194, -822, 1224, 2220, -2330, 72, 1004,
+ -787, -149, 557, 2925, 29, 809, 2397, -1143,
+ 648, 904, -568, -707, -839, -274, -1322, 1177,
+ -467, -482, -5181, 234, 223, 354, 386, 737,
+ 1273, 234, -353, 31, -8, -392, 85, -234,
+ 1366, 1449, 120, -695, 838, -622, -96, 382,
+ -1421, 612, -173, -3199, -150, 474, -394, -561,
+ -1171, 2541, -271, 2513, 670, 285, 636, -452,
+ -202, 1319, -2182, -935, -586, 243, -813, -41,
+ -53, -1041, 212, 58, -3424, 111, 268, 964,
+ -3231, -500, 867, -191, 207, 543, 383, -1509,
+ -2712, -2752, 201, 428, 721, 498, 19, -747,
+ 67, 87, 500, 1200, 2244, -1158, 466, -1032,
+ -153, 1197, 2737, -324, 2002, -338, 89, -428,
+ 78, 575, 330, 2013, 175, 305, 567, -539,
+ 17, 384, 485, 860, 3330, 173, 586, 649,
+ 388, 963, 1820, -2610, 251, -2966, 1383, -153,
+ -146, 564, -718, 998, -1283, -566, -619, 394,
+ 459, -1233, 2566, -357, -2601, 98, -929, -367,
+ -501, 96, 1217, -1695, -324, 393, 261, 1745,
+ -1095, -751, 924, 1044, -337, -1243, 393, 2454,
+ -1499, -245, 902, 925, -2126, 167, 838, 638,
+ 2296, -294, 306, -715, 2794, 1522, -339, 21,
+ 318, -95, 1334, 75, -173, -91, -2012, -920,
+ -801, 334, -3363, -348, 550, -911, -261, -1073,
+ 185, -425, 431, 515, -339, 1817, -1589, 241,
+ 548, -337, -471, -3532, -1166, 888, 141, -277,
+ 1353, 310, -654, 198, -516, 2951, 2251, -534,
+ 701, 237, 20, -597, -301, 3, 410, -456,
+ -581, -1254, 1052, 1321, 165, 3108, 477, 196,
+ 2716, 85, 5, -34, 721, -562, 4, 84,
+ -793, 744, 243, 134, -385, -129, -122, -128,
+ -333, -483, -604, 269, 6209, 3, 515, -63,
+ -634, -551, -795, -1696, -2210, 2184, 348, 30,
+ 413, 2531, 214, 214, -186, -72, -552, 958,
+ 1727, -1639, 618, -61, -432, 365, -753, 15,
+ -14, 33, 976, -940, -355, 3318, 677, -1938,
+ 21, 881, -326, -83, -3355, 1483, -1211, -674,
+ 166, 139, -276, 158, -736, 1038, -1005, 1129,
+ 1219, 1115, -392, 558, 96, -188, 314, 536,
+ -423, -3262, 395, -130, 1099, 304, -181, 853,
+ -160, -1272, 428, -179, 634, 608, -173, 2690,
+ -2191, 1385, -518, -416, 3239, 3250, 313, -23,
+ 200, 643, -639, -17, -208, 27, -182, 262,
+ -203, -671, 157, -4131, 383, -404, 337, 51,
+ 431, 92, 138, -438, 29, 337, 488, -252,
+ 656, 509, 2037, -635, -1074, -1115, -2135, -772,
+ -386, -214, -654, -441, 1661, 542, -383, -1720,
+ 22, -103, -1474, -1288, 4361, 282, -1252, 734,
+ -858, -556, 294, 243, 293, 133, 848, 65,
+ -727, -887, -1314, 443, -96, -422, 4268, 672,
+ 142, 608, -442, 843, 365, -866, -157, 780,
+ 107, -888, 2089, 1769, 73, 739, -15, -1730,
+ -1235, 920, -1713, 163, 552, 1479, -692, -755,
+ 1430, -193, -276, -264, -690, 772, 1403, -40,
+ 679, -260, 642, -3562, 962, 2053, 1348, 36,
+ -2974, 155, 303, 821, -944, -179, -967, 632,
+ -725, 411, -447, -463, 694, -337, -146, 59,
+ -1, -416, 12, 524, -497, -4682, -745, 625,
+ 1011, 20, -462, -503, 2012, -475, -27, 85,
+ -1190, 534, 2250, 87, 2591, 1195, 1665, 423,
+ -813, -571, -372, 2601, -2013, -853, -734, -403,
+ 793, -549, 1243, 312, 722, -1013, -1434, -749,
+ -571, 494, -88, -129, 1331, 806, -1227, 326,
+ -1164, 2487, -59, 2346, 583, 519, 368, 793,
+ 1178, 661, 140, 1226, 378, -429, -1214, 1438,
+ -319, -77, -1495, 3598, 361, 21, 39, 1930,
+ 198, 1050, 531, 274, 32, -499, -349, -5,
+ -133, -3324, -379, -742, -250, -1618, -1536, 2084,
+ 1369, 765, -132, -324, 406, -2198, 314, 502,
+ -1431, 759, -729, 320, -2120, 1484, 2468, -3283,
+ 4, 272, -2, 492, 91, -803, 48, 691,
+ 375, 87, -508, -725, -632, 268, 2929, 1302,
+ -11, -628, -2225, 723, 533, 909, 934, 682,
+ 350, 1509, -707, -1142, 106, -2174, 342, -965,
+ 456, -655, 1137, -553, 415, -418, -2631, -121,
+ 237, 3, -1123, -1555, -1413, -3333, 717, 115,
+ -1030, -1007, -819, 130, -851, 281, -43, -473,
+ -1091, 326, 869, -377, 278, -148, 418, -2104,
+ -422, 623, -1777, 633, 1033, -2031, -1221, 4126,
+ -60, -16, 8025, 243, -340, -599, -501, -289,
+ -219, -104, -230, 464, 191, 18, 345, -65,
+ -68, -481, 625, -822, -4011, -516, 741, 734,
+ -316, 530, 122, 945, 371, -298, 1194, -250,
+ -167, 392, -95, -151, -1, -486, 189, 90,
+ -140, 30, 4485, 581, 54, 1905, -895, -2032,
+ -174, 2473, -688, -104, -315, -376, 830, 296,
+ -548, 754, 195, -901, -1548, -1931, 792, 510,
+ 294, 153, 619, -1034, -3038, 1134, 142, -29,
+ -806, -118, -29, -2314, -159, 770, -2899, 23,
+ -1045, 1037, 1496, 1104, -527, 135, -281, -310,
+ -59, 202, -346, -612, 206, 27, -456, 758,
+ 67, 3547, 867, 227, -3, 573, 1440, 421,
+ 170, 1491, -691, -43, -8, 784, 307, 557,
+ 618, -2387, 566, -396, 182, 877, -2666, -163,
+ 553, -155, 691, -188, -1584, -1085, 1033, -308,
+ 1356, -570, -721, -232, -3145, 104, 511, -964,
+ 2783, -685, -168, -51, 1554, -1816, 2431, 327,
+ -440, 1174, -265, -36, 120, -397, 1094, -1254,
+ -973, 574, 1085, -139, -751, -529, -240, 25,
+ 1137, -467, -3471, 338, -806, -2028, 94, -98,
+ -336, -537, 1189, -880, -3607, -168, -59, 100,
+ 309, 1097, 295, 262, 106, -8, 210, -7461,
+ 395, -248, 461, 490, -326, 264, 105, 13,
+ -160, 608, -443, -1331, 835, -1342, 3507, 763,
+ 966, 101, 1047, -469, -1455, -1080, 28, 99,
+ -44, 270, -752, 130, 2, 57, 358, -409,
+ 2, -658, -812, -899, 155, 141, 2101, 3616,
+ 40, -1957, -1028, -4137, 212, 1580, 578, 1019,
+ -512, 167, 366, -580, 448, 216, 79, -149,
+};
+
+static const int16_t cb2224sm0[] = {
+ -4334, 1434, -228, 1477, -1329, 230, 686, -558,
+ 486, -188, 424, -454, -568, -141, -326, -132,
+ -39, 2488, 9, 631, 513, 460, -417, 2656,
+ 633, -1404, -81, -283, -287, 480, 2558, -19,
+ -158, -2699, 405, 276, -639, -151, 529, 241,
+ -941, -796, -213, 1125, -391, 2515, 78, -177,
+ 2677, 217, 955, -687, 867, -485, -121, 1023,
+ -1572, -591, 139, 798, 1262, -467, 722, 2643,
+ -237, -1048, 386, -432, 180, -788, -178, 234,
+ 403, 267, 312, 2661, 585, -2775, -686, -88,
+ -16, -1243, -445, -259, 303, 298, 285, 277,
+ 2355, 163, -2399, -416, 115, 2277, -707, 194,
+ 283, 1183, 23, 119, 97, 8192, -40, 67,
+ -101, 151, 169, 21, -147, -160, 55, -207,
+ 550, -36, -500, -32, 225, 206, 72, 179,
+ 464, -406, 52, 696, -18, -4827, 1547, -516,
+ -2275, 855, 430, -523, 83, -1633, -1898, 285,
+ 202, -645, -167, 102, -124, 382, 24, 236,
+ 830, 324, -84, 491, -95, -154, 767, 25,
+ 4741, -574, -2576, -297, -250, -346, -2867, -64,
+ -1119, 1007, -883, 457, -328, -854, -981, -55,
+ 6922, 569, -307, 261, -100, -832, 129, 416,
+ -154, 681, -136, 1152, -144, -26, -2266, -320,
+ -141, -897, 544, -206, 845, -590, 88, 211,
+ -1761, -574, -653, -2788, 252, -266, -4252, 295,
+ 97, -2112, 209, -144, 655, -89, -369, 591,
+ 205, 1137, 30, -2907, 88, 92, -240, -3106,
+ -16, -398, -576, -720, 421, 427, -423, -195,
+ -18, 2503, -133, -918, 104, -512, -489, 2623,
+ -314, 215, -103, -1014, 761, 382, -1456, 1719,
+ -980, 248, 55, 644, -1945, 42, -162, -35,
+ -852, 1993, -189, 664, -149, 3132, -50, 3438,
+ 550, -234, -566, 434, 64, 379, -169, -291,
+ -718, -608, 31, -207, 651, -2567, -790, 906,
+ 518, 1740, 373, 1158, 114, -2044, 285, -1136,
+ -373, 932, -2185, -488, 148, 3, 724, 623,
+ -568, -359, -2748, 751, -1098, -858, -1140, -253,
+ -2377, -402, -312, -398, -47, -2618, 816, -568,
+ 1274, -158, 118, 107, 181, 394, 2758, 80,
+ -3057, 20, -279, 110, 482, 1010, -162, -1081,
+ -56, 685, 2207, -10, 82, 440, 593, 43,
+ 1010, -853, -624, 288, -3045, -426, 9, 132,
+ 104, 157, 466, -118, 116, 226, -214, -219,
+ 299, 6093, 122, 7, 174, 444, 200, -42,
+ -4, -313, 99, 218, 292, -159, -409, 523,
+ -1357, -4098, -96, 968, 8, -172, -444, -1040,
+ 755, -476, 967, 175, -100, 1689, -813, 3175,
+ 369, 1828, 248, -161, 6693, 631, 536, -125,
+ 274, -467, 259, -427, 130, -523, 361, 584,
+ 27, 60, -57, -30, -8192, 148, -64, 217,
+ -308, 163, -116, 89, 108, 191, -129, -149,
+ 128, 60, 575, 253, -385, -2937, 888, -1402,
+ -543, -607, 2639, 156, 251, 6966, -147, -382,
+ -388, 39, 476, 260, -1048, 575, 401, -245,
+ -441, 121, 389, -666, 95, 2919, -2212, -765,
+ 169, -161, 184, -320, -315, -497, 136, -470,
+ 479, -541, 712, 2966, 519, 2595, -77, 1089,
+ 18, -697, -616, 241, -54, 388, 461, 368,
+ 144, -149, 181, 7699, 11, 3, -368, 65,
+ 304, 358, -29, 255, -162, -169, -470, -16,
+ 198, 92, 2137, 233, 273, 255, 4078, -279,
+ -194, -274, 101, 45, -225, -716, -2522, -188,
+ 10, -590, -745, 894, 1976, -48, 2302, -4,
+ -4691, -67, -1325, -506, 605, -297, 317, -271,
+ -176, 1706, 541, 1, 31, -580, 103, 148,
+ -122, -141, -849, 76, -3094, -67, 2775, -38,
+ -598, -314, 793, 40, 324, 1474, 1986, 1505,
+ 832, -504, 739, -1233, 1201, 695, -1363, 670,
+ 805, 696, -137, -4977, -306, 137, -885, 455,
+ 1021, 600, -1711, 536, 235, -149, 31, -5,
+ -3747, -405, 394, 140, 102, -1576, 190, 408,
+ 663, -2075, -747, 466, 631, 807, 1867, -655,
+ 102, 341, 435, 551, 500, 426, -650, -88,
+ -26, 2672, -1791, 34, -86, 2963, -3330, -793,
+ -307, 277, -584, -240, -141, 258, 708, -242,
+ -499, 808, -104, -2061, -518, 684, 889, 406,
+ 259, 211, 462, 428, -2597, -1147, 1729, 683,
+ -2173, -167, 392, 440, 599, -815, -624, -368,
+ -2962, -172, 845, 423, 362, 711, 2131, -3899,
+ 84, 147, 826, -399, -637, 1132, 108, -480,
+ 230, 265, -423, 48, 11, 239, -599, -281,
+ 10, 541, -397, 142, -4322, 1172, -257, -101,
+ 292, -321, -401, 60, -309, 468, 267, 611,
+ 438, -638, 2194, 346, 1421, -1192, -3109, -170,
+ -3336, -49, -69, -75, 184, 3094, 591, 82,
+ -373, 140, -22, 848, 124, 589, 157, -4,
+ 260, -177, 147, 73, -284, 6253, 111, 302,
+ -74, 356, 381, -547, -16, -275, -500, 93,
+ 344, -346, -2837, 364, -43, -592, 1741, -702,
+ -2247, 848, -203, 168, 758, -849, -2454, 562,
+ 1104, -169, 463, -398, -2759, -299, -903, 647,
+ -62, -124, 301, 337, -201, 463, -86, -139,
+ -2189, -2424, -942, -376, -2043, -80, -1791, -1580,
+ 513, 29, -1115, -582, 1214, -642, 355, 240,
+ 285, 1759, 1209, 862, 1707, 3353, -223, 245,
+ -515, -928, 794, -190, -282, 1097, -32, 1675,
+ 857, -730, -15, 102, 356, -309, 3867, 24,
+ 93, 899, -608, -497, -215, -2244, 735, -194,
+ 102, -51, -1939, 846, 74, -116, 7, 1981,
+ 512, 233, 574, -2508, 83, 1966, -251, -96,
+ 532, 97, 897, -1120, 390, -3192, -652, 2045,
+ 193, -880, -398, -148, 548, -281, -19, -987,
+ 467, -326, 2777, 195, 1560, 1034, -828, 102,
+ -1531, 1292, -126, 539, -247, 36, 55, -2487,
+ -297, -362, 482, -2241, -1021, -1535, -244, 38,
+ -3416, 141, 3408, 35, -67, 95, 333, -427,
+ -235, -128, 304, -548, 337, -349, -330, 23,
+ -450, 1657, 327, -3087, 695, -273, -1090, 1262,
+ -111, -868, 1516, 269, 119, 192, 14, 200,
+ 141, -395, 7145, 48, 334, 143, -139, 154,
+ -102, -312, -2, 283, 238, -30, 626, 1328,
+ 242, -416, 442, -3050, 1388, -100, 1215, 817,
+};
+
+static const int16_t cb2224sm1[] = {
+ 8192, -13, 346, -52, 5, 131, -294, -167,
+ -65, -347, -438, -559, 57, -86, -223, -224,
+ -251, 629, -58, 5249, 127, -464, 644, 210,
+ -154, -480, 165, 211, 13, 318, 152, -173,
+ 5451, 235, 170, -100, -6, -460, -249, 390,
+ 54, 993, -1637, -288, -978, -197, 234, -2877,
+ -570, -151, -82, 772, 199, -385, -1899, 345,
+ -25, 527, -477, -2918, 385, 2784, 78, -524,
+ -759, 795, 433, 511, 856, -275, 511, 136,
+ -444, 151, 233, 208, -589, -375, 282, 2886,
+ 30, -2749, -930, 1079, 86, -2285, 980, -229,
+ -1369, 93, -80, 2314, -170, 1224, 397, 405,
+ 463, 1014, -377, -90, -269, -82, -376, -773,
+ 684, -94, -2893, -323, -644, -849, -1892, -2244,
+ 417, 2165, -164, 221, 454, -2337, 142, 99,
+ 418, 486, -49, 97, 138, 2221, -2301, -156,
+ -578, 3963, 196, 140, -374, 180, 451, 354,
+ -952, 946, -479, -874, -159, 145, 290, 240,
+ -240, -233, -418, 226, 2878, -571, -2491, 741,
+ -1438, 557, 197, -370, -4720, 379, 32, 821,
+ 39, -545, -141, -1507, 192, -1150, 905, -1095,
+ -5028, -169, 533, -23, 371, 162, -1198, 465,
+ -369, -14, -861, -656, -701, -296, 31, 450,
+ -387, 3060, -696, 597, 14, -1019, -2741, -208,
+ -1186, -338, 712, -64, -344, 41, 327, 9,
+ 576, -349, -2808, 2428, 433, -566, 908, -108,
+ -145, -1011, 201, -3042, -327, 210, -368, 230,
+ -310, -400, 12, -1034, 1734, 992, 1842, 1022,
+ 2162, 588, 366, 154, -3078, -587, 1096, 215,
+ -1072, -784, 472, -1089, 94, 487, 18, 72,
+ 34, -15, -374, -607, 316, 830, -146, 4377,
+ -301, 390, 838, 121, -110, -143, -93, 2988,
+ 2914, -352, -353, -744, -115, 99, 495, -343,
+ 309, 1261, -519, 101, -2662, -44, -3139, -491,
+ 1142, -323, -50, 776, 86, 187, 480, 271,
+ -167, 1, -267, -99, 991, 2492, -152, 2423,
+ -225, 34, 576, -1486, -236, -375, 160, -176,
+ -145, 2525, -131, 194, 317, 1215, 1553, 295,
+ -1408, 130, 2279, -1185, 2671, -137, -324, -23,
+ 26, -779, -431, -4, 488, -186, 174, -119,
+ 3062, -149, -168, 191, 169, 1124, 301, 1471,
+ -409, -999, -166, 2174, -1405, 992, -179, -2606,
+ -71, -3151, 92, -976, 3091, -322, 310, -374,
+ -779, 599, -55, 425, -697, 63, 27, -38,
+ 86, 170, -11, -616, -97, 525, 78, 14,
+ 684, -5556, -308, -444, 266, -396, -1665, 86,
+ -722, -1087, -921, -525, 3, -439, -1600, -37,
+ 2038, -2672, -187, 361, -8192, 425, 365, 54,
+ 343, -703, 253, 284, -57, -327, -154, 392,
+ 99, -181, 213, 395, -2412, -303, 182, 82,
+ 2311, 45, 1801, -209, -988, 42, -1430, 38,
+ -721, 118, -163, 1279, 2184, -18, 2851, 274,
+ -363, 297, 150, -220, 3653, 3135, -381, 335,
+ 254, 378, -52, 52, 328, -383, -61, -802,
+ -409, -49, 49, -8192, 362, -48, -430, -54,
+ 255, 243, -525, 14, 152, 10, -392, -301,
+ -594, -539, 1200, 626, -2979, 233, -1504, 664,
+ -728, -1293, -491, 394, 1317, 298, 169, 214,
+ -429, -1083, 42, 389, 4751, 510, 299, -542,
+ 456, -852, 30, 208, -63, -131, 72, -425,
+ 73, 213, -287, -277, 43, 128, 5528, 165,
+ -316, -135, -576, -583, 217, -1298, 47, 134,
+ 103, -1894, 148, 3406, 880, 964, -697, -94,
+ -1626, 223, 1256, -514, 2079, -529, 1917, -1452,
+ -616, -605, 385, -963, 395, 105, -154, -1627,
+ -214, 40, 969, -708, -1492, -824, 2457, 275,
+ 404, 876, -781, -1029, 34, 72, 229, -137,
+ 264, -387, 305, -57, 2908, -143, -249, -2473,
+ 202, -1467, -364, 2094, -521, -70, 260, 132,
+ 465, 71, 982, -36, 1792, 306, 2907, -55,
+ 254, 421, 231, 140, 1727, 474, 761, 3153,
+ -18, -356, 414, 2218, 564, -247, -510, 67,
+ 2390, 2531, 240, 117, -487, -310, 261, 222,
+ -286, -861, -2180, 480, -75, 4769, -407, 248,
+ 227, -224, 302, 901, -1200, -728, 1025, 734,
+ -336, 115, -1726, -179, 131, 43, -357, 364,
+ -681, 283, -189, 715, -2793, -692, 1367, 916,
+ 28, -500, 3094, -543, -627, -709, -506, -1094,
+ 34, -2464, 434, 257, 357, 10, -390, 3206,
+ 3483, 137, 147, 180, 231, -260, -707, -818,
+ 476, -528, 656, 824, -8, 3073, 362, -3034,
+ -199, 47, 694, -252, 819, -147, -479, -32,
+ 530, -141, -91, 251, -154, 376, -603, 2305,
+ -2853, -622, 316, -680, 402, -819, 323, 471,
+ -47, 1772, 1507, -1052, -685, 18, -2509, -418,
+ 377, -31, -412, 105, -906, -267, -2806, -189,
+ -97, 198, -802, -82, -658, -2980, 795, -447,
+ 646, 1037, 486, -689, -2654, 55, -3534, 540,
+ -68, 502, -90, 277, -87, -497, 24, -246,
+ 400, 392, 348, 76, -345, -231, -71, 155,
+ -7, -226, 6553, 371, 261, -290, 88, -44,
+ 311, 470, -5, 182, -105, 56, -324, 267,
+ 241, 327, 966, 218, -4695, -968, 27, -352,
+ -315, 202, -204, 435, 360, -539, -375, -527,
+ -1157, 1010, -241, 4171, -292, 66, 2343, 310,
+ -682, 595, 3040, 539, -118, -573, -128, 952,
+ -172, -547, -285, -1, 345, -5701, 345, -153,
+ 77, 349, -225, -364, -655, -270, -716, -825,
+ 27, 55, 2179, -154, -275, 359, -501, -992,
+ -665, 1538, -218, -1159, 2176, -845, -3018, 105,
+ -459, -3146, 67, -197, -293, 539, 115, -74,
+ 119, -158, -89, 1449, -3006, 104, 651, 886,
+ -310, -242, 1219, 1805, 176, 2235, 579, 294,
+ 634, 1345, -1, -454, 755, -1030, 1760, -2404,
+ -406, 894, 614, -74, 113, -1325, 1843, -392,
+ -3239, 2440, -54, 222, 1349, -695, -1009, 434,
+ -468, -509, -280, 462, 228, 573, 213, 55,
+ 325, 557, 100, -721, -674, 600, 795, 1567,
+ 407, 3273, -58, -1330, 349, -181, 417, -503,
+ 911, 350, -681, -4502, -127, -26, 330, 618,
+ 241, -147, 284, -226, -127, -2692, 484, -146,
+ -18, -416, 755, 85, -3119, -404, 0, -478,
+};
+
static const int16_t cb4432l0[] = {
-3764, -227, 184, -258, -1713, 122, 410, -32,
-244, -1337, -328, -20, -236, -359, -13, -52,
@@ -2699,6 +8841,856 @@
-1617, -765, 839, 505, -36, -58, -2894, 226,
};
+static const int16_t cb4440sl0[] = {
+ -3624, -495, 158, -246, -529, -813, 689, 504,
+ -527, -2216, -198, -323, -690, -591, 175, 262,
+ 243, -3676, 2648, -986, 166, 243, 301, -700,
+ 324, -324, 13, 362, 222, -470, 30, 20,
+ -46, -147, 4050, -97, -560, 284, 317, -1611,
+ 655, -416, -1582, -675, 389, -124, 150, -27,
+ 325, -84, 48, 7474, 97, 105, 19, 38,
+ 133, 19, 28, 25, 40, 34, -59, 22,
+ 11, 27, 21, 5, -1596, -428, 439, 353,
+ 2288, -18, 357, -274, 2582, -126, -90, 71,
+ -9, -704, 205, 22, 44, -120, -43, 517,
+ 817, 1370, 2151, 2818, -470, 90, 395, -1243,
+ -345, 959, 19, -1, 123, -108, 347, 25,
+ -138, 15, 119, -117, -146, 142, 183, -254,
+ -276, -174, 5980, 283, -317, 70, 51, -15,
+ -2447, -79, 234, 736, -2600, -641, -1162, 376,
+ 959, -250, 701, -40, -102, 204, -38, -24,
+ -893, -387, 339, 1338, -91, -655, -864, 78,
+ 299, 228, -2732, 234, 1995, -1321, -139, 500,
+ -316, -140, 2, -80, 186, 11, 16, -69,
+ -7534, 85, -263, 189, -7, -1, -67, -68,
+ 3, 24, 391, -3299, -2952, -121, -393, 103,
+ -60, -113, 141, 185, -119, 240, 270, -392,
+ -105, 9, -39, 2529, -17, 353, 2966, -855,
+ 1042, 1294, 132, -257, -257, -496, 112, -179,
+ 424, 486, -63, 77, 275, -198, 2026, 1657,
+ 913, -255, -147, -1748, -5, 418, 356, 2022,
+ 927, -295, 194, 165, 28, 109, 13, 209,
+ -133, -2802, 420, -1873, -648, 309, -1172, -1825,
+ -36, 840, 280, 44, -118, 128, 34, 241,
+ -1005, 1160, -303, 318, 726, -1716, 2625, -950,
+ -839, -1257, -901, -238, 1123, 131, 252, 1,
+ 440, 1455, -14, -274, -461, 87, -515, -2299,
+ 928, -2867, -804, -215, 680, 147, 80, 215,
+ 15, 1339, 141, -95, 134, -35, 122, 53,
+ 429, 168, 476, -45, 745, 236, 4229, 318,
+ 247, -201, -372, 2289, 161, 431, 337, -707,
+ -1024, 121, -1773, -795, -1187, -401, 394, -1431,
+ 1526, -35, 432, 2929, 90, 1880, 628, 1298,
+ -552, -498, 207, -97, -1431, 1105, 29, -739,
+ -56, 62, 94, 537, -732, 1255, -766, 200,
+ -365, 2846, 2139, 435, 92, -710, -512, 360,
+ -339, 1021, 474, -132, 405, -440, 3435, 75,
+ -254, -2443, -880, 325, 343, 285, 230, -431,
+ -191, 215, 201, -443, 93, -81, -131, 2981,
+ -2986, 1003, 437, 434, -386, 17, 222, 70,
+ 173, -550, 267, -121, -43, 114, -11, -795,
+ 561, -147, 187, -198, -4969, 50, 59, 674,
+ -853, 163, 71, -205, -284, -50, -28, -1412,
+ -105, 262, 272, 565, -824, -541, 3381, 430,
+ -81, 228, -426, 978, -294, 422, -538, 13,
+ 9, 430, 180, 2329, -564, -1082, 1740, 1108,
+ -2011, 11, 343, 868, 723, -806, 342, 339,
+ -141, -173, 186, 50, 297, 705, 783, -593,
+ 1609, 212, 528, -2547, -863, -2457, -876, 164,
+ 162, 365, 68, 30, 11, 48, 47, -285,
+ -64, 166, -21, -6880, -191, -226, 89, -1,
+ 22, -93, -6, 44, 282, 52, 294, -690,
+ -147, 372, 2247, 804, -637, 54, 2385, -1799,
+ 315, -929, 692, -65, -54, 218, -752, -519,
+ 2171, 177, 907, 22, -778, -2656, 62, -418,
+ -434, 307, 1906, -280, 196, 76, 58, -46,
+ 70, -367, -67, 50, 125, 77, -547, -287,
+ -97, -10, -84, -271, -4856, 10, 490, -560,
+ -21, 66, -2469, -322, 1021, 936, 625, -2520,
+ 1144, -373, 270, 804, 603, -91, 262, 659,
+ 9, -324, 50, -712, 2705, -3016, 594, 87,
+ -88, 697, -205, -799, -128, 37, 504, 59,
+ -274, 655, 672, -20, 1294, -221, -2954, 198,
+ 674, -1676, 863, 324, 968, 731, 1125, -41,
+ -149, -303, 223, 1370, -67, -194, -1, -194,
+ 251, -459, -39, 4477, 113, -74, -386, 214,
+ -72, -77, -1593, 511, -461, 752, -559, -476,
+ 204, -722, 1050, 2080, 2468, -154, -208, 964,
+ 103, -58, 390, -1863, 910, -307, 209, -32,
+ 663, 103, -133, -3137, -423, 259, -605, -242,
+ 139, -391, -488, 77, -266, -1694, 397, -659,
+ 237, 2068, -3, -867, 870, 1647, 645, 1848,
+ 68, 382, 455, -551, -87, -99, -2926, 372,
+ 2438, -1166, -6, 521, -195, 1259, -162, 917,
+ 140, 275, -273, 133, 318, -25, 252, -119,
+ -132, 3120, 397, 398, -420, 1756, 666, 2176,
+ -141, 271, -51, 22, -494, -36, 57, 308,
+ 222, 3585, 16, -265, 2628, -24, 162, 13,
+ -240, -96, 620, 331, -449, 710, -123, -105,
+ 23, -170, 20, 256, -5228, 398, -186, 272,
+ 129, 175, 598, -16, -502, 11, -215, 28,
+ -110, 3570, 68, 199, -2535, -933, 781, -762,
+ 325, 18, -438, -319, 473, -677, 176, 290,
+ 0, 67, -6, -156, 31, 35, -131, -127,
+ 24, -100, -6826, -117, -53, -40, 99, -50,
+ -93, 31, 34, -251, 186, 487, -203, -662,
+ -182, -96, 239, 308, 338, -86, -4871, 264,
+ -48, 314, -66, 100, -188, 151, 24, 198,
+ 4, 5046, -47, -654, -43, 41, 109, 103,
+ -262, 93, -118, -63, 58, 2088, 336, -320,
+ 2326, 548, -810, -1315, -864, 461, 171, 76,
+ -1109, -1510, -874, -620, 97, 88, 40, -4,
+ -7295, -128, -39, 23, -100, -9, -74, 112,
+ -151, 67, 21, 53, 2, -29, -33, 52,
+ 3287, -2178, 626, 339, -817, 349, -1187, -550,
+ -390, 57, -41, 295, 756, 185, -215, 17,
+ 3, 7502, -134, -122, -31, -53, 91, -170,
+ -71, 133, -34, 57, -112, -5, -66, 17,
+ 1, 2328, 3714, 214, -123, -839, 9, -62,
+ 54, 70, -18, 817, 186, -61, -252, 37,
+ 98, 9, 2010, 738, -1651, -1924, 1106, -624,
+ 143, -548, 847, -198, -140, -691, 478, -758,
+ 56, 54, -7, 209, -2665, 109, -127, -134,
+ 2099, 333, -602, -2217, -743, 346, 74, 216,
+ 579, 223, 61, -30, 57, 94, 224, -2595,
+ -566, -851, 246, 314, 65, 2857, 114, -760,
+ 77, -611, 119, 181, 4, -2556, 127, 138,
+ -164, -219, -116, 157, -3143, 197, -98, -1040,
+ 235, -332, -424, -152, -338, -33, -220, 207,
+ 254, 5469, -102, -390, -125, -420, 113, -233,
+ 329, -34, 109, -171, 103, 50, 58, 96,
+ -500, -2317, -259, 2178, 109, -2030, 759, -780,
+ 448, 678, -384, -271, 213, 334, -271, 23,
+ -1121, 636, -1103, -482, -3059, -1200, 1160, 109,
+ -232, 541, -788, 130, -166, -300, 664, 233,
+ -97, -29, -286, 33, 1272, -298, -382, -242,
+ -199, 47, 479, 224, -1761, -1904, 1780, 1439,
+ -681, -1973, -118, -90, -148, 247, -758, 1936,
+ 182, 1373, 2346, 120, -758, -476, 1789, 1177,
+ 611, -394, -14, -39, -994, -674, 1049, -41,
+ 836, -391, 942, -1040, -1437, 1376, -1916, 1129,
+ -1018, -653, 1284, -72, -166, 321, 194, -142,
+ -151, -77, 251, -162, 732, -790, 107, -292,
+ -675, -4248, -51, -86, -299, -495, 413, -128,
+ -455, -105, -842, 881, -492, 1241, -1432, -1296,
+ -52, -430, 2533, -1765, 838, 84, -24, -798,
+ -428, -154, -658, 37, -388, -591, -931, -433,
+ -1837, 1363, -683, -717, 3115, 104, 0, 1104,
+ 208, 148, 404, 101, 18, 217, 58, 49,
+ 4, -49, -195, 187, -239, -21, 294, -138,
+};
+
+static const int16_t cb4440sl1[] = {
+ -3057, -853, 3212, -334, 5, 224, 63, -250,
+ -345, -102, -289, -115, 75, -99, 206, -8,
+ 19, 96, -254, -2566, 334, 2773, 136, 199,
+ -1076, 347, -187, 481, -64, 654, -9, -1094,
+ 196, 40, -95, 5, 163, -135, 253, -1053,
+ 316, -231, 24, -2307, 1480, -2052, -18, -459,
+ -550, -1860, -15, 98, -1406, -66, -250, 21,
+ 497, -404, -54, -228, 2477, 2011, -145, -1957,
+ -426, -906, 608, 15, 1453, 218, -79, -636,
+ -1005, -332, 304, 2338, 1356, 81, -1201, -170,
+ -126, -1177, -1644, -1046, 16, 182, -328, -347,
+ 346, 591, 418, 623, -110, -342, -227, 10,
+ -5055, -411, 128, -103, 87, -28, -133, 196,
+ 333, 1785, -479, -442, -2892, 453, -2292, -19,
+ -383, -44, -435, -193, 503, 130, 4, 144,
+ 2184, -245, -7, 458, 82, -76, 3052, -375,
+ 1299, -76, 364, -145, 372, 36, 59, -39,
+ 48, 385, -230, 2764, 2956, -741, -372, 428,
+ -504, -220, -821, -47, -49, 609, -62, 56,
+ 6, 216, 376, 519, -512, 54, -318, -183,
+ -4563, 297, 795, -182, 108, 234, 404, 218,
+ -123, -17, -192, 170, 349, 134, -91, 43,
+ -135, -24, -6, -32, -6681, 50, -138, -89,
+ -18, 15, 24, -416, 356, 311, 83, -267,
+ 81, 209, -155, -368, 396, 358, 232, 4696,
+ -347, 724, 112, 10, 331, 358, 197, 54,
+ 824, 646, -214, 113, -4425, 184, -11, 101,
+ -313, 186, 253, 169, 78, 52, -70, -108,
+ 1669, -22, -18, -2600, -27, 2806, 288, -106,
+ 506, 176, 616, -299, 58, -30, 1, -220,
+ 400, -177, 874, 70, -36, -274, -139, 1148,
+ 372, 40, 236, 505, 619, -4002, -95, -48,
+ -2854, 114, -69, -2805, -401, -9, 203, -1011,
+ 472, -1066, 412, -220, 245, -183, -27, 35,
+ -762, 312, -137, -292, -242, 896, 172, -345,
+ 106, -4490, 506, 569, -11, -352, -108, 334,
+ -165, 2389, -895, 2761, 467, 201, 150, -516,
+ 39, -1105, 4, 587, -152, -764, -184, -15,
+ -137, -30, -12, 7, 382, -461, 1577, 3519,
+ -173, 1370, 80, 499, 344, -771, 123, -13,
+ 288, 233, 111, -2472, 3952, 771, 216, -505,
+ -446, 531, -230, 103, -72, 34, 61, 249,
+ -175, 353, 83, 51, 169, -97, -60, 7827,
+ 95, 75, -13, 201, -27, 103, -11, 1,
+ 3, 121, -73, -28, 7, 2908, -209, -987,
+ -129, -341, 2840, 889, -147, -521, 123, 95,
+ -239, 552, -738, 279, -66, 0, 16, 116,
+ -45, -28, -43, -38, -7627, 30, -52, -209,
+ 281, -46, 23, -24, 56, -25, -23, -2534,
+ -107, -46, -93, -49, 238, -25, 96, -356,
+ 3483, -459, -414, 205, 102, 202, -150, -116,
+ 1785, 1399, 793, 543, 685, -2837, 255, 362,
+ -96, 410, 926, 1068, 416, 558, -169, 246,
+ 138, 2136, 39, -96, -605, 279, -130, -2741,
+ -1101, -935, -20, -227, 453, 1261, 103, 275,
+ 358, 43, 197, -23, -251, 322, -22, 233,
+ 2560, -214, 2, -101, 645, 2864, 287, -479,
+ 904, -65, 73, 224, 2418, -95, 428, -678,
+ -278, 71, -545, -571, -566, -181, -212, -2947,
+ 222, 780, -365, 124, -2703, -198, -69, -246,
+ -3056, -184, -598, -75, -145, -690, 380, 194,
+ 485, 214, -484, 54, 163, 363, -924, 1684,
+ 201, 34, 236, -539, 2374, -150, -490, -1313,
+ -61, 317, 2123, 315, -551, -26, -328, 207,
+ 253, -3015, 166, 109, -662, 2466, -157, -740,
+ 751, 254, -788, -369, -6, 100, -211, 107,
+ -309, -39, -47, 279, -126, -91, 97, -705,
+ 235, -231, 182, 283, -5097, -68, 285, 49,
+ 50, 637, 111, 39, -386, 923, 223, 115,
+ 1638, 1214, -640, -2168, 482, -2228, 857, 172,
+ 15, -2207, -89, 335, -18, 295, 718, -956,
+ 26, 604, -436, 2856, -1131, 98, -754, 243,
+ 9, 29, -4028, -1725, -1741, 432, -211, -60,
+ -535, 201, -273, 111, 444, 607, -250, 122,
+ 98, 159, 97, 281, 3071, -412, -2849, -721,
+ -14, 960, -43, 794, -427, 297, 478, 379,
+ -47, -22, 69, -60, -30, -732, 2456, 170,
+ 142, 6, 2520, -644, -201, -16, 1602, -20,
+ -293, 542, -451, -167, -9, 14, 1052, 2707,
+ 2980, -117, 479, -202, -92, 36, 904, -66,
+ -1088, -31, 75, -62, -110, -29, 112, -102,
+ 5217, -85, 14, -191, -202, -175, -71, 182,
+ -231, 275, 144, -1, -202, -13, -29, -19,
+ 70, 39, 46, 56, -7608, -53, -104, -61,
+ 44, 23, 1, -157, 42, 12, 38, 37,
+ 331, -609, -2516, -174, -2491, 258, -256, -926,
+ 983, 100, 83, 173, -965, 650, -304, -97,
+ 98, -166, 534, 2570, -611, 493, 103, -98,
+ 148, 3081, -131, 285, 13, -367, 205, -53,
+ 41, 29, -154, -2657, -51, -312, 134, 50,
+ -1514, 634, 411, -2885, -391, 365, -373, -54,
+ -74, -151, 80, 152, -91, -64, -209, 1134,
+ -2921, 316, -951, 1124, 713, 2, -2212, 31,
+ 164, -260, 103, 36, 229, 111, -23, -65,
+ -37, -220, -108, -30, 86, 17, 87, 205,
+ 163, 63, -5763, 254, 178, -18, 1760, -380,
+ 1453, -3151, 710, 106, 66, 387, 235, 463,
+ -295, 688, -124, 322, -193, 82, 1012, -2033,
+ -656, 1362, 805, -747, 2527, 470, 43, -1001,
+ 100, -83, 161, 74, -1128, -307, -82, -197,
+ -5470, 226, -327, 137, -131, 471, -432, -16,
+ 243, 224, 168, -164, -58, 125, 23, -2,
+ -2752, 268, -92, -466, 2876, 874, 182, 540,
+ -407, -338, -396, 562, -376, 536, -225, 160,
+ 44, -1501, -246, -1062, -378, 446, -2448, -124,
+ 499, -2297, -353, -637, 395, 598, -747, 418,
+ -495, 5, -1014, 2138, 289, -75, 301, 944,
+ 66, -457, -459, -253, -2, 678, 367, 116,
+ -2901, 436, -239, -303, -973, 384, -2574, 6,
+ -225, -164, -440, 627, 388, -3074, -263, 156,
+ -805, 381, -9, -112, -1481, 536, -711, 3770,
+ -496, 908, 483, 474, 298, -424, -793, -203,
+ -334, 134, -91, 208, -73, 5440, -316, -304,
+ 249, -1, -98, -214, 190, 242, -57, -38,
+ 244, -219, 30, -224, 66, -30, 22, 24,
+ 24, -109, -7594, -115, 90, -147, -83, 21,
+ -257, -52, 134, -49, 92, -117, 30, -8,
+ -636, 1551, 2207, -66, -1962, 212, 567, 969,
+ -1595, -562, 355, -467, -861, 937, -148, 15,
+ -68, -1516, -2118, 1477, 777, 1458, 976, 522,
+ 325, 957, -130, -132, -918, 448, 1088, 102,
+ 142, -644, -284, 687, -665, -132, -1870, 1387,
+ 733, -84, 920, -508, 53, -2183, 254, 565,
+ 2056, 97, 57, 219, 688, -344, 659, 2033,
+ 963, -1717, -290, -934, -2119, 57, -1452, 24,
+ -639, -739, -232, 170, 28, 359, -312, 310,
+ -103, -1067, -953, 1081, -857, 1926, 1364, -1719,
+ -863, 1832, 786, 55, 166, 383, -1373, -347,
+ 1710, -908, 91, 1257, 2013, -592, -1337, 1431,
+ -90, 617, 549, -356, -68, 134, -48, -133,
+ -176, -18, -65, 23, 84, -23, -36, -4,
+ 230, 297, -204, -150, 86, -4965, 742, 40,
+ 32, -1070, 149, 38, 302, -329, -386, -57,
+ 45, -1622, 1425, 1817, 1568, 2202, 7, -1192,
+ -201, -42, -62, -170, -32, -117, -38, 229,
+ 44, -226, 155, 70, 747, 259, -261, -120,
+};
+
+static const int16_t cb4440ss0[] = {
+ -3021, 2048, -450, 1147, 1487, -796, -657, 459,
+ 609, 63, -153, -1174, -144, 37, -176, -160,
+ 43, -31, -2577, 88, -797, 1179, -707, 3154,
+ -543, 875, 116, -40, -150, 326, 293, -112,
+ -73, -34, 61, 8, -2251, -1551, -2507, 6,
+ -52, -5, -323, -313, 1076, 920, 1116, -1100,
+ 1103, 310, -144, 904, 149, -59, 636, -1508,
+ -378, 381, -917, -868, 1388, -1225, -68, 1491,
+ 685, -220, 3253, 48, -504, 192, 114, -11,
+ -1718, -916, 660, -240, 767, -1061, 332, 591,
+ -477, -278, 25, -1485, 55, 216, -3238, -19,
+ -320, -148, 273, -876, 22, -529, 3263, -2535,
+ -756, -133, -481, -1024, 34, 418, -415, 412,
+ -92, -90, 161, -49, -1699, -2737, 2923, -243,
+ 122, 87, 984, -377, -37, 128, 350, -444,
+ -98, -52, 14, -14, -86, 255, 1997, -1239,
+ 42, 247, -15, 16, 405, 302, -17, 84,
+ -4033, -12, 254, -365, -205, -162, 329, 31,
+ -1158, -210, -376, 3958, -1601, -1128, 737, 731,
+ 300, -785, -777, -403, 463, -226, -109, -277,
+ -70, -53, -856, -785, -997, 71, 5565, 317,
+ 447, -279, -357, 254, 93, -47, -206, 133,
+ 88, 272, 7, 44, 2229, 1666, 234, 519,
+ -1996, -1195, 549, 449, 174, -1010, 622, 425,
+ 2288, -9, -390, 612, -40, 32, -1867, -673,
+ -70, -1174, 106, 134, 354, 61, -144, -290,
+ 82, -604, 202, -3954, 248, -76, 7, 224,
+ -1844, 99, -146, 206, -335, 243, 25, 60,
+ 186, 117, 67, -137, 119, 46, 4563, 45,
+ -46, -2, 874, 533, 216, -38, 185, -540,
+ -191, -163, -126, -108, -184, 193, -39, -4768,
+ 111, -89, -61, 17, 1064, 1678, 894, 4334,
+ 139, -892, 317, -351, 417, -87, -22, 195,
+ 20, 140, 234, -197, -268, -5, -1618, -756,
+ -119, -1749, -704, -943, 421, -3488, 871, -468,
+ 656, 266, -79, 325, -303, 45, -3, -31,
+ 1140, -707, -1578, -1434, 290, 327, -1365, -2913,
+ 1048, 38, -136, -871, -572, -30, 186, 343,
+ -30, -157, 1301, 1913, -515, -842, -723, -84,
+ -340, 270, -918, 3213, -1530, -394, -184, -60,
+ -391, -27, -110, 84, 104, 419, 1201, -810,
+ 1546, 39, -914, -334, -4257, 427, -95, -426,
+ -94, 256, -148, 246, -80, 9, -462, -1125,
+ 644, 3541, -140, 2346, 1045, -335, -867, 809,
+ 432, 386, -6, 159, 70, -10, 218, 43,
+ -2229, -607, 537, -924, -3038, -943, -968, 1261,
+ 28, 197, -285, 61, 137, 69, -2, -251,
+ 111, -19, -314, 2064, 960, 1529, 1056, 926,
+ -319, -1617, 1305, 1473, -867, 684, 1357, -834,
+ -66, 477, 74, -15, -1769, 1925, -2448, -1777,
+ -507, 264, -1740, 176, -518, -58, 32, -108,
+ 165, -68, 189, 35, 40, -85, -1152, 255,
+ 36, -1922, 1500, 1415, 841, -92, 3305, -110,
+ 3, -219, 167, 573, 219, 310, 27, 195,
+ 359, -244, 538, -2042, 355, 656, 51, -199,
+ -204, -3611, -396, 839, 743, -241, -80, -210,
+ -101, 28, -1399, 1062, -955, 54, -630, -178,
+ -376, 212, 237, -219, 47, 805, 216, 26,
+ -4334, 455, 4, 4, -1587, 95, 1186, -3101,
+ -140, -862, 916, 2063, 211, 96, 337, -185,
+ -195, 424, 1207, -31, -162, 206, 2485, -46,
+ -451, -1778, -40, 144, -155, 2884, 803, 396,
+ 1196, -635, 297, -76, -121, -162, -206, -149,
+ -2204, 1035, 232, -815, -49, 1006, 553, -407,
+ 161, 3650, -264, 370, -418, -28, 141, -177,
+ -113, -90, -315, 626, 62, 1392, -1815, 336,
+ -1276, -402, 486, -1060, -1848, 2610, 826, 485,
+ -250, 39, 208, 14, 2555, 2869, -813, -2074,
+ 337, 601, 855, -655, 566, -707, 189, -77,
+ 137, -510, -282, 79, 42, 73, 62, 650,
+ -4732, -486, 354, 420, 828, -645, -492, 388,
+ 753, 18, 2, 766, -212, 126, -43, 45,
+ 447, -283, 607, 251, -166, -10, 48, -5850,
+ -251, 128, -205, -95, 90, 90, 67, 24,
+ -50, -48, -167, -3231, -2926, 1831, 199, 484,
+ 169, -614, -135, -374, -418, -239, -89, -121,
+ 45, 75, -11, 16, -1058, 354, 1633, 589,
+ -1223, 1218, 842, -1146, 2186, 374, -363, 216,
+ -2153, -429, 429, -597, 93, 148, 1849, -797,
+ -162, 31, -325, 343, -323, 161, -373, 684,
+ -367, -452, -4306, -88, 28, -56, -59, 43,
+ -49, -1998, -956, 1331, -4214, -129, 30, 79,
+ -90, -129, 109, 130, -160, 409, 105, 298,
+ 208, 178, 1724, 731, 773, 128, 817, -425,
+ -4046, 180, -782, -116, 191, -259, 181, -31,
+ 162, 43, -41, -69, 1463, -1769, -2, -442,
+ -636, 1495, -218, -123, -58, 3616, 454, -475,
+ 247, -383, 304, 185, 155, 40, 1104, 1046,
+ -8, -736, -1155, -115, 3925, -257, -35, -599,
+ -437, -135, -256, 55, 214, -88, 215, -57,
+ -1097, 183, -501, -608, -135, 148, 405, 295,
+ 96, -513, 1013, 4350, -162, -61, 427, 315,
+ 24, -77, -1278, -167, -1774, -133, -323, -4339,
+ 732, 597, -30, -103, 79, -241, 177, -388,
+ 7, 44, 175, -143, 5030, 277, 58, 42,
+ -222, -133, -319, 6, 240, 217, -238, -198,
+ 218, -43, 439, 49, 37, 106, 1123, 2196,
+ 158, 171, 458, -932, -435, -2783, -300, 444,
+ 2317, -146, -339, -162, 157, -216, 1, 66,
+ 987, -190, -728, -3188, -3167, 378, -1, 158,
+ 459, 78, -42, 386, -133, 155, 294, 359,
+ -29, 78, 1763, 780, 1019, -330, 179, -51,
+ -393, 338, 4422, -296, -392, 170, 2, 52,
+ 253, 150, -191, 139, -371, 161, -2202, 156,
+ 37, -1004, -384, -466, 23, 183, -3701, 97,
+ -1293, -355, -83, -63, -26, 69, -1817, 641,
+ 2996, -16, 2011, -406, -647, -652, 332, 788,
+ 484, 918, -440, 1246, 165, 52, -260, 31,
+ -255, -7237, 14, 90, -135, 122, 14, 154,
+ 5, -78, 111, -254, 154, -23, -24, -83,
+ -9, 49, -426, 1657, 99, -36, -191, 2625,
+ 655, -20, -2723, -977, -222, -48, 155, 41,
+ 20, 194, -73, -26, -1206, -3517, -471, -815,
+ -1144, -371, 1353, -1069, -1238, 829, -227, 487,
+ -297, -101, 914, 100, -17, 115, -806, -798,
+ 585, 1097, -1, -792, 818, 29, -256, -417,
+ 942, 68, -4165, 34, -408, -252, 55, -77,
+ 246, 2055, -4, -313, -661, -836, 559, -393,
+ 2043, 153, 286, -2700, 98, -177, 1201, 99,
+ 308, -73, 1441, -3902, 730, -1610, 886, -599,
+ -126, 473, 43, -252, 45, 95, -291, 101,
+ -307, 259, -149, 26, -510, 498, 1403, -78,
+ -1039, -2551, 773, -1176, -1525, -405, -259, -283,
+ 398, 2080, -199, 62, 239, -26, 960, 582,
+ 2516, 799, -2127, 325, -253, -1652, -965, 1413,
+ 8, -119, 396, -342, 277, 541, 186, -142,
+ 1210, -732, 798, -47, -557, -12, 63, 537,
+ 148, -128, 328, 290, 203, 361, -328, -64,
+ 4004, 197, -640, 996, -93, -2314, 76, -914,
+ 1437, -964, -1735, 984, -578, 1389, -1025, -66,
+ -120, -1211, -32, 5, -1215, 771, 1621, -934,
+ -984, 148, -1592, -446, 19, -976, -1709, -1113,
+ -218, 191, -279, 2183, 10, -37, -842, -1582,
+ -92, 558, 227, -702, -365, -576, -100, 670,
+ -305, 285, 48, -329, 253, 3878, 156, 70,
+ -1008, 641, 1541, -234, 1440, 421, 1088, 735,
+ -206, -83, 460, -139, 107, -1160, -6, 2087,
+ 1894, -117, 962, 113, -990, 93, -29, 579,
+ 1217, -52, -342, -451, 670, 202, -1070, 837,
+ -132, 3507, -59, -114, -691, 208, -1170, 1089,
+ 305, -200, 603, -1301, -942, -1631, 1291, -2727,
+ 414, 80, 815, -443, 54, -34, -1141, 1301,
+ -1199, 372, 102, -257, 70, 450, -55, 80,
+ -227, 218, 264, 739, -52, -200, 3873, 83,
+};
+
+static const int16_t cb4440ss1[] = {
+ 6875, -104, -66, 161, 57, 24, -4, 76,
+ -122, -100, 31, 188, -119, -50, -244, 49,
+ 1, -100, 555, 253, 433, 633, -163, -5345,
+ -170, -217, -49, -29, 331, 633, -87, -46,
+ -29, 44, -174, -74, 2188, 434, 660, -593,
+ 1548, 379, 1443, 1676, -63, -2125, 246, 534,
+ -463, 872, -169, -12, 33, 211, -409, 408,
+ 1514, -189, -277, 391, -361, -35, 145, -362,
+ -4669, 212, -97, -65, 387, -81, 70, 36,
+ 448, 303, 332, -1077, -258, -1353, 1185, -50,
+ -12, -74, -2101, 2429, 1817, -939, 393, 169,
+ -22, -36, 1219, 3237, 816, 452, 1807, -646,
+ 407, -447, -1778, -370, -528, -127, 104, 416,
+ -121, -134, -62, 20, 1751, -640, -222, 950,
+ 1603, 555, 9, 219, -1272, 2724, 1004, 1237,
+ -395, 356, -453, -98, -24, 80, -1621, 474,
+ -1947, -237, -1059, -2091, 780, 1211, 939, 268,
+ -412, 1923, -419, 851, 230, 567, 143, 48,
+ 1506, 2228, -1226, -453, 246, 469, 540, -538,
+ -96, 977, 508, 105, -3150, -142, -37, 395,
+ 9, -38, 1, -135, -391, 1702, -179, -1566,
+ -3181, -1679, 203, -151, 387, 250, 563, 203,
+ 443, -168, 82, 61, 1604, -1878, 229, -82,
+ 208, 2965, 1093, 251, 1592, -432, -532, 153,
+ 407, 157, 191, -216, 52, -58, 935, -2161,
+ -409, -513, 977, -113, 3247, -1207, -743, -1178,
+ 136, 206, 184, -885, -64, 16, -23, -24,
+ 731, 1769, -941, 1543, -2386, -669, -958, 233,
+ 105, -1124, 948, 97, -1949, 59, -152, -65,
+ 114, 82, 387, -1908, -492, 129, -624, 93,
+ 658, -753, 1032, 2480, -1776, 360, -38, 1924,
+ 168, -12, -10, -128, -1712, -446, 939, 465,
+ 605, -586, -299, -393, 3878, 111, -379, 146,
+ 186, -50, -279, -30, -3, 35, -1941, 360,
+ -79, -111, -4287, -6, 671, -214, -792, 277,
+ 77, 58, 8, 16, 133, 161, 21, 33,
+ 1535, -296, -2668, -3198, -28, -386, 1156, 144,
+ -201, 256, -411, 298, 67, 670, 11, -227,
+ -4, -104, 12, -1000, 1192, 860, 813, 360,
+ 25, 93, 792, -350, 81, 4046, -178, 122,
+ 332, 28, -112, -8, 288, 539, -17, -63,
+ 8, 231, 55, -514, 105, -344, 252, -153,
+ 59, -10, -21, 51, 6793, 45, 259, 384,
+ 209, -2010, 311, -769, -1957, 2791, -463, -293,
+ -218, 1026, 897, -798, 47, -525, 31, -42,
+ 2018, -2767, 1658, 685, -1947, 46, -1468, 340,
+ -272, 318, 21, -421, -396, 244, -51, 290,
+ 45, 3, -1530, 1359, -3681, 1487, -1689, 209,
+ 438, -785, -220, 2, -55, -483, -35, 40,
+ 6, 189, -200, 2, -2026, -1747, 838, -880,
+ 1128, -3108, 184, -671, -261, 8, 296, -130,
+ -78, -268, -100, 18, -105, -9, 448, 3184,
+ -570, 656, -376, -969, 1682, 2635, -277, 577,
+ 217, 281, 219, -351, 31, 64, 101, 82,
+ 957, -1885, 774, -3536, -168, -431, -106, -479,
+ 1041, -103, 774, -142, 894, -724, -94, -766,
+ -58, 112, 2028, 566, -346, -139, -2671, -1907,
+ 1039, 189, -33, 1690, 263, -514, -225, -237,
+ 145, -319, 38, 116, 2891, -77, -2065, 2559,
+ -327, -763, 86, -172, -283, -147, 137, 245,
+ -333, 220, 92, 194, -176, 105, 3108, 329,
+ -372, -1188, 670, 773, -235, 34, -146, 876,
+ -259, -1580, 876, 105, 582, 259, -63, -99,
+ -1558, 1122, -1541, -438, 227, 1221, -1297, -746,
+ 2698, -29, 1169, 995, -2, 201, 392, -405,
+ -22, -36, 757, -4039, 725, 1960, 1478, -107,
+ 67, -367, -97, -88, 154, -80, 0, -265,
+ -163, 14, -109, 33, 597, 115, 543, 468,
+ -757, 826, 509, -176, -305, -4959, -118, -464,
+ -421, -72, 1, -187, 123, -88, -1086, 26,
+ 368, 610, 3394, -337, 364, 2594, 491, 759,
+ -309, 395, 152, 338, 249, 303, -122, 63,
+ 1019, -864, 1546, 196, 75, -633, -93, -631,
+ 777, -74, 1235, -745, 377, 3113, -174, -282,
+ -24, 89, -920, 2124, 620, 566, 1290, 2977,
+ 1180, 278, 188, 750, 981, -357, 80, 69,
+ 77, -151, 150, -15, 834, -893, 818, 1655,
+ -500, 237, 133, 243, 405, 239, 16, -152,
+ -70, -3692, -110, 145, 58, -57, -2527, 3072,
+ 2226, 218, -824, 384, -96, 119, -228, -194,
+ 136, 111, -251, -109, -179, -34, 143, 109,
+ 1157, -216, -1429, -702, 323, -1199, -60, 632,
+ -585, -340, 1040, 471, -32, -380, 3432, 455,
+ -138, -39, -2416, 652, -253, 145, 281, 393,
+ -671, 2841, -1616, -46, -385, -1417, -273, -168,
+ 318, -263, -2, -69, -638, -137, -2668, -359,
+ -86, 79, -777, -404, -560, -3533, 122, -113,
+ 617, 497, 117, -268, 110, 73, 752, -1105,
+ -521, 762, 695, -587, -147, -1235, 1866, -2250,
+ -671, -511, -2178, -820, -619, 162, -37, 102,
+ -342, -278, 6837, -278, 185, 10, 361, -52,
+ -171, 246, 184, -175, 19, 166, -48, -41,
+ 92, -152, -1227, -983, -3985, -703, 1143, 204,
+ -523, 1053, -623, 1002, 231, 53, -277, -409,
+ -67, -56, -90, -47, 448, 754, 554, 972,
+ 505, -331, 4946, -193, 89, 530, -24, -172,
+ 254, 244, 140, -10, 40, -77, 1655, -438,
+ -2776, 51, -553, 592, -2902, 280, 804, 776,
+ 131, 69, -207, 131, 7, 209, 93, -19,
+ -1148, -733, 2674, -1628, -1243, -506, -2346, -857,
+ -1028, 666, 365, -353, 105, 120, 210, -85,
+ 37, -40, 1027, 11, 1234, -5, -1976, 515,
+ 289, 3815, -142, -188, -248, -273, -265, 593,
+ 205, 164, -65, 70, -992, 1586, 2130, 779,
+ 92, -3067, 421, 1, 1172, 496, -917, -760,
+ 169, -64, 14, -40, -247, -95, 1769, -145,
+ 712, -794, -571, 240, -1774, -38, -129, -836,
+ 3372, 887, -451, 73, -107, 182, 100, 14,
+ -703, 2559, 490, -839, -333, 134, 804, -3549,
+ 50, -199, -215, -370, 453, -86, 151, -98,
+ -58, 128, -2624, -1507, -1623, -2186, -89, -55,
+ -472, -667, 2, -439, -1453, -262, 565, 56,
+ -118, 288, -56, 87, -398, 729, 40, -6015,
+ 219, -212, 287, -250, -211, -29, -61, -55,
+ -120, -92, 30, 129, -122, 111, 2037, 1260,
+ 943, -252, -13, -794, -2570, -1117, 297, 374,
+ -1629, -1, -407, -597, -324, -179, 408, 58,
+ -902, -1672, 611, -198, -61, 103, 366, 915,
+ 811, -280, -401, -3849, -111, 221, 353, 232,
+ 4, -18, 673, 1792, -2350, 132, 1979, -2318,
+ -417, -689, 326, 768, -377, -522, 373, -389,
+ -105, -103, 33, -48, 1497, 1125, 1893, -2744,
+ -1219, 921, 472, -165, -438, -129, -682, -783,
+ -685, 167, -715, 156, 64, 61, 1147, -892,
+ -72, 579, 1191, -2759, 1831, 1895, 663, 816,
+ -98, -61, -223, -366, -429, 31, -129, -121,
+ -255, 1804, 138, 180, -1063, 598, 763, 720,
+ 385, -526, 143, 80, 168, 976, -714, 236,
+ -3204, 93, 874, 238, -359, 1595, 191, 568,
+ -182, 20, -608, -288, 602, -224, 3874, -308,
+ -70, -826, -109, -42, -882, -1421, -1603, 625,
+ -1206, 31, 782, -106, -700, -246, -571, -124,
+ -848, -390, -523, -2903, -9, 39, -109, -199,
+ 497, -11, 377, 5, 25, -115, -61, 283,
+ 27, -131, -193, 280, 178, -5439, 44, -52,
+ -1210, -617, -162, -1097, -3, 748, -45, -1197,
+ -1058, 909, 1607, 693, 42, -749, -3001, 407,
+ -62, 45, 214, -312, -1054, 498, 1291, 1189,
+ -1268, 1083, -757, -319, -2796, -716, 310, 1583,
+ -608, 319, -84, -119, -1415, -602, 628, 463,
+ -1213, -794, -474, 2682, 931, 240, 2491, 76,
+ -234, -161, -690, 359, 28, -19, -774, -1023,
+ 738, 675, 248, 52, -348, -545, -2715, -599,
+ -252, 660, -387, -104, 2316, 456, -90, 100,
+};
+
+static const int16_t cb4440sm0[] = {
+ -6448, -59, 298, -659, -59, 329, -569, 397,
+ -224, 128, -216, 153, -100, 319, -53, -90,
+ 50, 3313, 4, -215, 405, -256, 78, 2890,
+ -187, -969, 195, -1022, -119, 214, 254, -360,
+ -222, 39, 2139, 91, -290, 529, -73, -16,
+ -318, 128, -348, 565, -1190, 202, -185, -234,
+ 3498, 48, 68, -1917, 1694, 212, -477, 239,
+ -3301, -489, 424, 418, -82, -61, 599, 1530,
+ -200, -252, 162, -243, 43, -534, -2695, 255,
+ 317, 489, 279, 3337, 246, -349, -149, -128,
+ -146, 256, -455, 137, -75, 836, 209, -349,
+ 3494, 255, -1948, -732, 367, 1373, -211, 608,
+ 345, -17, 43, 102, 19, -219, 173, -2361,
+ 130, -862, 637, -103, -589, 219, -1261, -238,
+ -2528, 1643, -1587, -690, -166, 7, -57, 1221,
+ 326, 103, -830, 608, 196, -3705, 1103, 568,
+ -1602, 543, -153, -416, 74, 185, 156, 34,
+ 1329, -798, -214, -515, 121, -797, 749, 346,
+ 629, -609, -877, -60, 184, -157, 250, 193,
+ 4385, 369, -181, -191, -308, -314, -395, -173,
+ -88, -388, -43, 46, 9, -167, 189, -192,
+ 6086, -226, -1795, 126, -941, -423, 397, 380,
+ 461, 319, 364, -194, 433, 1214, -3715, -274,
+ 9, -327, 212, -375, 130, -917, -63, 1120,
+ -651, -211, 149, -1128, 265, -73, -4630, 493,
+ -83, -20, -314, -91, 910, -109, -3, -417,
+ -109, 374, 357, -2773, 253, -234, -306, -3060,
+ -762, 53, 476, -299, -89, -2440, -658, -83,
+ -854, 3770, 374, 552, 450, 51, 346, 887,
+ -463, 189, 254, 182, 15, -37, -3263, 2594,
+ -647, -83, 404, 770, 691, -654, -301, 81,
+ -13, 742, 371, 54, 31, -83, -59, 4196,
+ 653, 256, -1075, -539, 1084, -1077, 1238, 259,
+ 20, -191, 854, 179, -47, -1025, -189, 281,
+ 2556, 1765, 106, -79, 320, -3066, 228, -500,
+ 1, -183, -46, 220, -233, -50, -98, -261,
+ -84, -25, -4378, -428, -1395, -582, -619, 443,
+ -1456, 375, 144, -32, 356, -454, 28, 136,
+ 5, 247, -1057, 709, -362, 293, 3084, 545,
+ -2804, -625, 16, -228, -238, 164, -201, -114,
+ -149, 58, -74, 203, 271, 462, 1037, 159,
+ -1652, -591, -846, -166, -3272, 710, 773, 824,
+ -1138, 630, -14, 209, 348, 1476, 322, -371,
+ 241, 4133, -877, -476, -391, 602, 1259, -1204,
+ 352, 90, -473, 43, -152, -439, -131, -217,
+ -1559, -5029, -186, -239, -44, 750, 33, -167,
+ -211, -67, -91, -143, 124, 32, -16, 8192,
+ 68, -102, 163, -31, 458, 38, 249, 21,
+ 157, -63, 36, 49, -22, 89, 9, 153,
+ 46, 60, -146, -13, -7506, -104, 101, -141,
+ 25, 165, -84, 219, 53, -182, -94, 46,
+ -1314, -371, -298, -527, 6, -1955, 52, -714,
+ -461, 174, 1450, -298, 107, 2965, 250, -65,
+ 46, -171, 296, -785, -784, 35, 36, 29,
+ 915, -891, -391, 168, 509, 3763, -1267, -138,
+ 132, 424, -53, -669, -1491, -927, 712, -638,
+ -440, -299, 522, 1593, 445, 3234, 547, 498,
+ 440, 145, -135, -188, -296, 1080, 468, 77,
+ 176, -315, 221, 4784, -666, 274, 762, -42,
+ 218, -86, -273, 116, 814, -21, 402, -266,
+ -392, -425, 1126, -68, 142, 357, 5143, 363,
+ -224, -198, 115, -221, -262, -736, -2774, -196,
+ -208, -613, 163, 696, 789, 132, 114, 121,
+ -3138, 164, 172, -189, 232, 53, 310, -50,
+ -407, 1207, -474, 249, -806, 21, 20, 72,
+ -534, 101, -47, -223, -4568, -128, -29, -910,
+ -254, 105, 3163, -119, -135, 1745, 1744, 1105,
+ 291, -333, -278, -441, 660, 141, -291, 314,
+ 149, 142, -121, -7878, -240, -204, 189, 376,
+ 3, -129, 59, 46, 170, 82, -150, -34,
+ 67, -110, 635, 148, 256, -2939, 157, -509,
+ 1439, -2470, 794, -298, 407, 980, 805, 349,
+ 208, -35, 1009, 1180, -114, 776, -339, -776,
+ 250, 1951, -557, 172, -395, 795, -3075, -348,
+ -106, 122, -47, -9, 55, 40, 3002, 421,
+ 538, -1, -277, -3062, -15, 168, 461, 521,
+ -525, 413, -196, 159, -3314, -85, 983, 565,
+ -3113, 38, 79, -172, 20, -228, -520, 346,
+ 47, 485, -177, 51, 175, 444, 3475, -3416,
+ -81, 118, 264, -162, 20, -192, -219, -111,
+ -57, -225, 159, -218, 117, -28, -150, -1100,
+ -681, 444, -54, -11, -4669, -216, -1151, 858,
+ 168, -39, 52, 387, 74, -39, -154, 2767,
+ 307, -132, 531, 175, 906, 14, -129, 49,
+ -3389, 476, -127, -329, 479, 118, -85, 209,
+ 4, 227, 154, -2, -238, 263, -24, 553,
+ -231, 78, 2, -183, 31, 5933, 117, 86,
+ 386, 359, 153, 101, -784, -553, -13, 256,
+ -347, -1311, -936, -64, 1718, -444, 168, -590,
+ -3252, -194, -243, -269, 2096, -994, -1081, 309,
+ 1003, 290, -66, 306, -3239, -25, 700, 365,
+ -770, 144, 4, 259, -185, 1493, -158, 726,
+ -3180, -1683, -119, 45, -493, -205, -1728, -1226,
+ -235, -87, -88, -87, 1966, 8, 142, 496,
+ 239, 828, 30, -517, 3150, 2266, 402, -315,
+ 74, -312, -414, -16, 458, 381, 376, 1287,
+ 1093, -410, -967, 80, 382, -106, 4419, 445,
+ 293, -283, 282, 324, -80, -25, 115, -1667,
+ -756, 1893, -2772, 395, 3, -349, 138, 1094,
+ 406, 432, 214, -1328, 632, -132, -100, 135,
+ 1627, 1062, 1026, -1341, 24, -3352, -173, 1265,
+ 861, -821, -87, -367, 278, 151, -101, -32,
+ 161, 387, 5778, -564, 492, 83, 324, 29,
+ -423, 91, -132, 190, -310, -457, -62, -99,
+ 171, -214, -159, -2500, -693, -1538, -311, -784,
+ -2422, -498, 1781, 342, -467, -78, 466, -252,
+ 241, 197, 186, -1039, -190, 346, -1881, -240,
+ -65, 1438, 1001, -3009, -52, 221, -490, 1224,
+ -63, -39, 53, 169, 130, 86, -56, -90,
+ 116, 4, 7098, -5, 61, -172, -65, 160,
+ -94, -30, -111, 270, -653, 521, -426, 1084,
+ -1169, -1158, 584, -2499, 2494, -321, 695, 823,
+ -429, 35, 529, -280, -45, -286, 2997, 207,
+ -633, -2207, 1708, -298, -413, 673, -1017, 292,
+ 493, 76, -136, -365, -65, 266, 852, 512,
+ 791, -129, 1364, -1065, 1371, 383, -524, 505,
+ 943, 147, 229, 39, -2969, 70, -295, 66,
+ 2759, -16, -435, -474, -1058, 762, 54, -257,
+ 560, -3167, -572, -418, -478, 370, 72, -20,
+ 296, 54, -2683, 550, -15, -155, 2146, -143,
+ -1144, 463, -117, -1690, -1917, 42, 249, -278,
+ -319, -513, 544, -2033, -317, -1955, -2646, 1345,
+ 759, 268, 207, 1243, 256, -32, -45, -750,
+ -211, -184, 2397, 473, 2572, -489, 260, 389,
+ -237, 602, -463, 569, 1673, -176, -227, 964,
+ 203, 130, -269, -190, 1339, -978, 973, 1986,
+ 1145, 1258, 272, 1779, -436, -1306, 652, 807,
+ 574, 1401, 53, -183, 1612, -828, -3094, -82,
+ 1061, 1042, -200, -891, -126, 181, -1324, 549,
+ 555, -4, -868, 79, 157, -1533, 18, 230,
+ -1096, -335, -669, -166, 1853, -310, -340, 249,
+ -954, -594, -2929, 415, 5, 135, -1315, -237,
+ 1868, 787, 1912, -1100, 1139, -1103, -217, -382,
+ -654, 2078, 528, 133, -115, -56, -41, -207,
+ 69, 461, 465, -396, 1725, 1306, -443, -720,
+ -1600, 1176, 652, -997, -306, -1040, 2258, -75,
+};
+
+static const int16_t cb4440sm1[] = {
+ 8192, 96, 214, -395, -106, 291, -401, 305,
+ -102, 194, -73, 31, 71, -19, -349, 65,
+ -183, 26, -21, 8154, 107, -136, -37, -35,
+ 85, 127, -202, 43, -195, 225, -51, -69,
+ -57, -107, 141, -120, -284, -227, 28, 680,
+ 218, 29, -1800, 488, -207, -453, -99, -3680,
+ -210, 39, 279, 1406, 278, -37, -1596, 232,
+ 376, 90, 234, -3348, 242, 1765, 555, -883,
+ 118, 115, 48, -116, 2166, -292, 136, 527,
+ -236, -18, 411, -20, -190, -480, 665, 3332,
+ 378, -287, 337, 199, -5, -3904, 311, -297,
+ -2720, -193, -17, 911, -224, 457, -48, 254,
+ 271, -24, -77, 165, 23, 182, -1122, 122,
+ -520, 309, -3604, -1013, -405, -647, -145, -1162,
+ 1019, -190, -278, 69, 362, -185, -78, -245,
+ 472, 670, -493, 620, 76, 717, -2296, -111,
+ -454, 3224, 27, 47, -351, -154, -293, 187,
+ -93, 96, 87, -453, -132, 9, 125, -209,
+ -26, 284, -552, 255, 87, 227, -5445, 112,
+ 172, -15, -448, 475, -5747, 367, 149, -228,
+ -797, 371, 67, -102, -118, -418, 332, 38,
+ -100, 90, -183, -3302, 15, -1049, -1560, 1299,
+ -710, 1257, 698, 316, -283, 955, 240, 182,
+ 269, 12, -37, 1817, 649, -1273, -2071, -1719,
+ -765, 977, -1159, 351, -1583, -85, -771, -215,
+ 123, 314, -158, 32, 560, 208, 265, -451,
+ -413, 32, 1954, -3598, -1680, -832, -646, 761,
+ 272, 394, 213, -35, -44, 343, 309, 244,
+ 3041, -399, -50, -126, -2755, -146, 243, -367,
+ -600, -166, -832, -537, 269, -48, 2419, -526,
+ -309, -17, -235, 73, 341, 351, -840, 3241,
+ -94, -432, 404, -588, 158, -127, -49, 3259,
+ 3543, 134, -256, -106, 622, -45, -170, -109,
+ 68, 377, -84, 210, -250, -267, 257, -77,
+ 6, -1109, -1498, -327, 1063, 992, 632, -245,
+ -656, -1100, -60, -456, -170, 3208, -6, 13,
+ -95, 606, -594, -2039, -369, -1743, 275, -93,
+ 117, 2828, -138, -108, 206, 1819, 98, -45,
+ 45, -163, 2962, -398, 3536, -183, -259, -581,
+ 65, -498, -288, -357, -339, -13, -71, -409,
+ 36, -15, -545, 1433, 135, -220, 99, 752,
+ 177, -455, -251, 1172, -1274, 1062, -774, -999,
+ -63, -2756, 99, -86, 4695, -171, -129, -856,
+ 26, -543, 610, -1350, -2, 271, 455, -150,
+ 358, 101, 536, 125, 101, 88, -16, -12,
+ 488, -7479, 110, 264, 140, -302, 110, 232,
+ 0, 15, 70, -28, -27, -110, -99, 201,
+ 78, 215, -108, -267, -7548, 34, 312, -86,
+ 197, 125, 80, -75, -117, -2, 128, -207,
+ -131, -513, 614, 33, -4844, -302, -323, 160,
+ 808, 645, 243, -603, 68, -70, 158, -131,
+ -212, -34, -247, 625, 134, -42, 525, -89,
+ 31, 116, -1, 508, 5021, 395, 111, -86,
+ -172, 1433, -114, -126, -148, -337, -260, 233,
+ -479, 275, -247, -5672, 386, -110, -99, -142,
+ -171, -154, -358, 30, 1028, -78, 575, 523,
+ -586, -739, 1586, 1076, -2519, 1572, -1448, -201,
+ 166, -54, 137, 1268, 1157, -411, -2905, 195,
+ 489, -740, 154, 522, 2276, -604, 194, -1112,
+ 192, 400, -271, 250, 413, 273, 158, -299,
+ -874, -228, -2454, 162, 819, 457, 3401, 689,
+ -208, -298, -461, -360, -70, -2133, -114, -124,
+ 81, -228, 625, 3525, 909, 254, -234, 1316,
+ -773, 531, -30, -16, -164, -84, 2360, -1900,
+ 351, -2979, 545, 653, 416, 273, -79, -825,
+ -107, 71, 495, 223, -176, 129, 40, 424,
+ 1627, 207, 47, -8, -273, -715, 60, -1253,
+ 1501, -1199, -248, 39, 2859, -432, 89, 299,
+ 948, -2608, -896, 3468, 84, 511, 55, 151,
+ 733, 270, -354, 470, -219, -115, -105, 91,
+ -259, 1941, 775, 12, 2764, 484, 557, 2288,
+ -118, 294, -32, 719, -62, -64, -295, -82,
+ -145, -285, -492, 87, -135, -98, 194, -288,
+ -8, 263, -475, -53, -388, 5621, 41, -28,
+ 34, -323, 138, 1935, -1806, -185, 340, 1380,
+ 48, -542, -2965, -339, 88, 554, 41, 4,
+ -151, 182, -39, -193, -3355, -312, 3106, -203,
+ 442, -110, 317, -269, 225, 31, -62, -277,
+ 163, -766, -408, 210, -58, 128, 161, 3308,
+ 3321, -138, -278, -149, 216, 134, -253, -135,
+ -154, -123, 254, 200, -2, 133, -307, -6253,
+ 310, -6, 959, 26, 191, 315, 528, -75,
+ -230, -203, 153, -265, -94, -61, -2, 2761,
+ -4623, -353, -19, 102, -139, 54, 438, 267,
+ -73, 447, 226, 71, -19, 75, -40, -32,
+ -850, -500, 422, 1237, -688, 357, -3158, -468,
+ -450, -279, -694, -1109, 734, -1602, -117, 122,
+ 261, 979, -20, 385, -2929, 342, -3164, -146,
+ 252, -104, 62, 469, 289, 249, -214, -38,
+ 73, 83, -7, 18, -394, -5, -140, -267,
+ 331, -147, 6540, 395, -103, -147, -271, -20,
+ 191, 73, -155, 197, 71, 503, 19, 138,
+ -129, 335, 209, 75, -6207, 140, -176, -5,
+ 35, -40, -61, -146, 1080, 58, 327, -49,
+ -842, 1431, 595, 3461, 1, 142, 2001, 297,
+ -16, -425, 1156, -101, -54, 1060, -222, -295,
+ 938, -1212, -2374, 73, -272, -3318, -8, -718,
+ 114, -154, 85, -9, 72, 86, -1330, 226,
+ -1414, -521, 3161, -1856, 133, 240, -499, -371,
+ -745, 779, -463, -506, 463, -229, -226, 389,
+ 135, -4137, 360, 735, -318, 777, 593, 977,
+ -174, 286, 187, -95, -1626, 245, 97, 9,
+ 277, 299, 1568, 1066, 375, 1342, -390, 884,
+ 271, 185, -258, -1100, 2113, -107, -447, -1917,
+ -58, -29, 1081, -455, -524, -196, 1869, -677,
+ -3564, 1443, 29, -425, -28, -370, -342, -28,
+ 30, -118, 58, 607, 454, 45, -120, 232,
+ 20, 21, -175, -112, -236, 492, 411, 42,
+ -42, 4041, 39, -2579, 235, -146, 122, 24,
+ 1301, 123, -461, -3264, 316, -88, -209, 140,
+ 387, -430, 78, 508, 149, -3588, 1107, 820,
+ -140, 654, 812, -566, -2578, -403, -72, 120,
+ 355, -136, -121, 209, 240, 116, 231, 1630,
+ 208, -178, -3160, 2203, -52, 451, 84, -310,
+ -1199, 596, 69, 285, 242, 15, 49, 341,
+ -154, -2286, 1206, -109, 1048, -647, 1127, 98,
+ -1264, -808, 1744, -1597, 13, 26, -216, 263,
+ 3276, 3192, -105, -390, -31, 676, 73, 265,
+ 31, 101, 479, -69, 123, -24, -49, 32,
+ -653, 2253, 49, -346, 1476, 1820, 396, 639,
+ -219, 792, 1728, 147, -765, -140, 1181, 98,
+ 153, -98, -755, 2473, 452, 231, 2031, 2468,
+ -416, 587, 724, 148, 500, -933, -229, 55,
+ 102, 74, -164, 652, -425, 100, -2684, 1358,
+ 1626, -350, 544, -301, -1589, -305, -1266, 11,
+ 243, -125, -330, 294, 1471, -2922, 1581, -546,
+ 582, 231, -1407, -877, 602, 219, 350, 1130,
+ -86, 214, -56, 201, -181, -2140, 1108, 493,
+ 456, -542, -113, -852, 1647, 1897, 840, -1178,
+ -369, 788, 488, 256, 366, 2298, 1167, -205,
+ 256, 585, -555, 292, 2615, 748, -247, -1102,
+ -1682, 226, 415, 20, 27, 100, 9, 436,
+ -1746, 2621, 1583, -211, -833, 441, 54, -1183,
+ -826, -916, -707, 564, -232, -14, 147, 453,
+ 70, 1094, -903, -337, 450, -1546, -662, -1047,
+ -2345, -811, -1037, 96, 560, 1381, -119, -383,
+};
+
static const int16_t cb4448sl0[] = {
-3850, -1289, -449, -36, -1178, -1175, 705, -97,
37, -650, 426, -477, -145, 124, 6, 207,
@@ -3574,6 +10566,481 @@
12, -674, -901, -897, -827, -682, 323, 2580,
};
+static const int16_t fcb8sl[] = {
+ -1269, -1637, -1349, -1672, -1421, 2750, 212, 3563,
+ -74, 1555, -1495, -1148, -1172, 1351, -484, -473,
+ 1418, 557, 899, 635, 6124, -1140, -1154, 783,
+ -1444, -1509, -1041, 1793, 4459, 1325, 2055, -921,
+ -794, -713, 1625, -50, 78, -159, 361, 855,
+ 10282, -1533, -1105, -1582, -1704, -1697, -1440, -1001,
+ 864, 2038, -1347, -847, -1419, 1474, -1369, -1189,
+ -1125, -655, -134, 950, -1398, -222, -1498, -1262,
+ 2597, 729, 2521, -544, 457, 2058, 3821, -1568,
+ -1577, 2013, -1717, -1620, -1292, 2771, 2559, 4942,
+ -1497, -1576, -1724, -1550, -1775, -1734, -1097, -635,
+ 1934, 2706, -1399, -994, 1685, -1142, -511, 1595,
+ -275, 861, 484, 958, -1374, -764, -1105, -1493,
+ -1678, -1630, -521, 5138, 53, 1331, 4909, -1376,
+ 2134, -1638, 1562, -1565, -1487, -1625, 3232, 4742,
+ -1017, -1353, -1212, -1585, -1309, -1139, -71, -820,
+ 5928, 2987, -641, -1314, -1198, -1182, -1005, -542,
+ -1287, -1210, -1103, 6865, -1130, 1375, -884, 1241,
+ -532, -173, -68, 15, 309, 192, -1128, -1107,
+ -849, -1343, 2233, -1281, -535, -679, 3878, 1865,
+ -1427, 4508, -1022, -747, -1117, -1104, -33, 669,
+ 1216, 1482, -1360, -1075, -1483, -1390, -1366, -754,
+ -1042, -766, 3467, -624, -968, -1101, -393, -890,
+ -447, -995, 2346, -909, -784, 977, -1141, -1201,
+ 5256, -1552, -536, -1419, 0, 596, 556, 1654,
+ -1124, -1225, -830, 1267, -719, 1791, -546, -297,
+ 978, 378, 2674, -1261, -1159, -951, -1027, 2537,
+ -470, -360, -268, 1098, -1154, -1513, -729, -1455,
+ 5671, -1236, -800, -874, 1630, 1273, 1909, -623,
+ -724, 1417, -559, -326, -257, -189, 265, 220,
+ -284, -1302, -1272, -1223, -842, 4338, -934, -1001,
+ -495, 2944, 4295, -924, -1004, -1097, -1024, -328,
+ 1736, 106, 452, 158, -1024, -541, -1296, 4376,
+ -1117, -1224, -843, 1097, 1121, 1251, -829, -1374,
+ 2292, -1505, 1850, -1153, -943, -979, -534, 1444,
+ -1510, -1494, -1147, -1397, 1535, -794, -21, 1313,
+ 638, 1015, -1072, -1275, -1166, -1602, -1618, -1379,
+ 4541, -226, 2169, 888, -1369, 2392, -1087, -948,
+ 1074, 674, 384, 124, 500, 749, 398, -1091,
+ -721, -114, -15, 413, 200, 135, 290, 189,
+ -1185, -1188, -1339, -1549, -871, -574, 2333, -346,
+ 554, 3773, -1247, -1531, -1408, -1310, -1007, 2861,
+ 2465, 608, 1080, 1224, -1103, -1477, 1884, -1412,
+ -904, -1473, -846, -188, 782, 2049, -1473, 1531,
+ -1530, -1459, -1546, -1260, -856, 1191, 652, 933,
+ 5072, -1456, -1653, 3759, -1751, -531, -1391, 4297,
+ -374, -751, -1570, -1242, 1461, -1286, -913, -621,
+ 1768, 1246, 1291, 779, -1360, 1641, 1122, -629,
+ -328, -197, 241, 359, 560, 536, -1474, -506,
+ -1523, 298, -1551, -1254, -985, 3603, 4317, 958,
+ -885, -241, -1159, -930, -1249, 1490, -825, 274,
+ 347, 307, -1060, -1027, -809, -1063, 1554, 1708,
+ -242, -23, 424, 804, -1317, -853, 1571, 1898,
+ 239, -556, 298, -161, 777, 765, -1464, 1053,
+ -1198, -1156, -917, 0, 1460, 447, 1178, 629,
+ -1455, -1591, 296, -1785, -1694, -1631, 3669, 3819,
+ 3437, 3274, -956, -666, -874, -284, -858, -202,
+ -687, 1728, -512, -951, 4692, -1360, -1242, -1188,
+ -1513, -449, -1566, -1515, -1226, 3857, 1246, -1225,
+ -860, -1068, -748, -27, 380, 1190, 591, 552,
+ -1391, 194, -763, -463, 331, -265, 702, 181,
+ 290, -145, -838, -1359, -1381, -1569, -1399, -1088,
+ -1357, -1295, -486, -612, 1638, -586, 1458, -774,
+ -223, -620, -104, 189, 344, 269, 1555, 1428,
+ -867, -621, -294, -206, 32, 235, 261, 161,
+ -1021, -105, 654, -235, -282, -7, 189, -159,
+ -218, 113, -1096, -1318, -1256, -1335, -931, -476,
+ -1041, -1199, -1134, 2781, -1479, -1222, -1397, -867,
+ -815, -661, 740, -240, 1158, 735, -1435, -1003,
+ 351, -990, -245, -72, -347, -72, 1408, 634,
+ -1697, -1727, -1534, -1716, -1436, -102, 402, 1518,
+ 1903, 1311, -1477, -930, -355, 508, -162, 21,
+ -46, 454, 387, 173, -1312, -1284, -1486, -1172,
+ -1356, -965, -1106, 1760, -670, 2163, -70, 417,
+ -559, -667, -545, -945, -429, -363, 157, 1280,
+ 2059, -1319, -1291, -975, -1354, -1249, -780, -476,
+ 1410, 1252, -1193, -927, -1462, 871, -1281, -1327,
+ -900, 1540, 1531, 1227, -1651, -1334, -1073, -752,
+ -154, 710, 830, 773, 279, 307, -1294, -796,
+ -761, 1012, 1583, -420, -177, -323, 154, 582,
+};
+
+static const int16_t fcb8ss[] = {
+ -1481, -1069, -1082, -726, -818, -550, -417, 343,
+ 489, 275, -814, -510, -712, -933, -558, -236,
+ 32, 3051, 451, 301, -414, -237, -683, -599,
+ 3627, -445, -232, 56, 58, 112, -1226, -639,
+ 4096, -644, -226, -23, 90, 162, 313, 104,
+ -1385, 5607, -428, -860, -447, -265, -145, -132,
+ 115, -200, -1349, -1280, -1216, -1046, -657, 43,
+ 1333, 831, 675, 1174, -1394, 2288, 1840, -682,
+ -497, -256, 22, 22, 261, 70, -1369, -826,
+ -975, 2286, -329, -267, 142, 36, 437, 313,
+ 1570, 52, -470, 622, -244, -247, -114, 22,
+ -117, -541, -1167, -596, -809, -929, -669, -327,
+ 102, 516, 2790, 597, -1317, -870, 1327, 987,
+ -25, 391, -48, -82, 209, -242, 4424, -311,
+ -396, -765, -382, -336, -365, -414, -74, -13,
+ 1127, -588, 1363, -714, 368, -450, -390, -364,
+ 84, 139, 1864, 1881, -15, -790, -281, -286,
+ 38, -186, -31, -238, -1249, 262, -841, 731,
+ -414, -61, -274, 280, 100, 557, -841, -775,
+ -1007, -1063, -687, -374, -360, 31, 1048, 3471,
+ -1385, 2464, -840, -1105, -714, -400, 56, 445,
+ 588, 427, 1785, -1093, -783, -847, 41, -23,
+ 465, 392, 382, 428, -518, -249, -58, -791,
+ -689, -581, 3146, -183, 296, 66, -1243, 1059,
+ -1076, -874, 416, 544, 253, 66, 168, 211,
+ -1388, 1253, 138, -727, -509, 905, 319, -297,
+ 67, -525, -1470, 2237, -87, 547, 556, -239,
+ 90, -147, -114, -302, -1017, -824, -585, 25,
+ 0, 62, 1422, -155, -41, -320, -1125, -1069,
+ -1134, -783, 1129, 45, 183, 47, 716, 672,
+ 409, -1169, -910, -447, -34, 79, 95, 455,
+ 504, 381, 342, -877, -506, -812, -805, 3031,
+ -249, -518, -69, 564, 243, 261, -332, -434,
+ -173, -37, 61, 45, -5, 6, -1433, -1009,
+ 1428, -951, -582, 154, 143, 625, 383, 387,
+ -1392, -1222, -578, 229, 1294, 218, -142, 355,
+ -149, 201, -1341, -1135, -857, -767, -273, 2059,
+ 255, 578, 350, 315, -1041, -617, 254, -504,
+ -255, -96, -537, -396, 363, 1074, -1361, 484,
+ 538, -789, -704, -447, 200, 521, 213, 90,
+};
+
+static const int16_t fcb8sm[] = {
+ -1183, -1170, -867, -948, -746, 492, 1531, 1412,
+ 524, 82, 590, -994, -916, -859, -680, 12,
+ 742, 961, 230, 255, 34, 38, -176, -1,
+ 1880, -240, -769, -531, 269, -32, -772, -494,
+ 757, -583, -677, -281, 717, 440, 561, 91,
+ -1121, -1054, -1189, -1100, -745, -417, -61, 302,
+ 3079, 1817, -1384, -1479, -1477, -1509, -1077, -323,
+ 902, 2348, 1464, 1038, -487, -179, -447, -311,
+ -296, -439, -172, 2166, 245, -28, -1050, -390,
+ -238, 633, 302, -335, 843, -52, 185, 230,
+ -110, -433, -690, 148, 63, -289, -404, -469,
+ 1948, 245, 2016, 1337, -341, -554, -617, -457,
+ -436, -459, -400, -520, -661, -7, 1078, 971,
+ -326, -332, -23, -749, 83, -104, 2106, -947,
+ -867, -883, -705, -433, -35, 164, 427, 646,
+ -924, 2196, -656, -798, -282, 217, -227, 134,
+ 446, -15, -584, 33, 185, -571, -159, 1852,
+ -405, -94, -61, -83, -329, -516, -394, -450,
+ -173, -140, -54, -156, 226, 1850, -752, -1304,
+ -1378, -1275, -1017, -680, -337, 356, 1131, 4143,
+ -1120, -1253, -1269, -860, 90, 973, 152, 886,
+ 609, 1454, -29, 36, -117, -815, -651, -346,
+ 2085, -414, 24, -93, -235, -1103, -1132, -758,
+ -98, 1497, 1285, -289, -34, 402, -646, 637,
+ 2147, -677, -350, -266, -232, -61, -199, -359,
+ 167, 1546, 816, -453, -35, -251, -468, -491,
+ -371, -593, -878, 1445, -795, 651, 108, -155,
+ -201, -14, 250, -271, -732, 793, 154, -288,
+ -86, 16, 557, 642, -592, -587, -87, -365,
+ -309, 1753, -40, 95, -529, -87, -214, -234,
+ 4999, -466, -755, -800, -785, -722, -532, -703,
+ -526, -465, 591, 3937, -229, -804, -808, -698,
+ -576, -613, -506, -725, 10, 13, -117, -55,
+ 101, 52, 125, -76, -25, -28, 1469, -245,
+ 8, -25, 65, -53, -262, -282, -411, -588,
+ -667, 1374, 304, -787, -661, -675, 55, 320,
+ 720, -4, 366, -103, -136, -332, -314, -293,
+ -38, 127, 151, 380, -1330, -1338, -618, -40,
+ 1284, 1500, 466, -515, 105, -161, 19, 697,
+ -417, -559, -317, -712, -756, -567, 754, 1481,
+};
+
+static const int16_t fcb11l[] = {
+ -1291, -1237, -1175, -1186, -1139, 524, 1225, 1464,
+ -1042, -721, -901, 41, -728, 822, -657, 1078,
+ -483, 1530, -489, 1253, 926, -326, 404, 89,
+ -1191, -1170, -1237, 1633, 1493, -465, 986, 1184,
+ -857, -832, -300, -811, -936, -667, -254, 492,
+ 4044, -1136, -983, -855, -592, -199, 383, 876,
+ 2076, -1042, -1019, -729, 1435, -25, 64, 845,
+ -991, -921, -861, 916, -402, -551, 236, 429,
+ 5253, -1233, -1268, -414, 1793, -463, -569, 1693,
+ -1197, 6322, -887, -211, -945, -540, 626, 903,
+ -993, 1500, -490, 1445, -764, -136, 321, 548,
+ 462, -228, 127, -322, 481, -183, 88, 155,
+ -809, -844, -959, 4011, -581, -232, 330, 986,
+ -900, -916, -1069, -866, -979, -439, 4016, 1558,
+ -1023, 2121, 1717, -612, -588, -446, 223, 430,
+ 2567, -972, 2118, -1030, -900, -664, 180, 858,
+ 3232, -991, -1132, 2119, -446, -548, -258, 895,
+ -962, -184, 2639, 1081, -661, -222, 292, 530,
+ -952, 1767, -213, -701, 1079, 37, 131, 489,
+ -875, -749, 3167, -776, 1247, -109, -83, 636,
+ -1146, -1070, -1001, -1064, -942, 2891, 1137, 1585,
+ -1314, -632, -1179, -1105, 1101, 51, 2038, 2036,
+ -926, -727, 180, 1515, -566, 1191, 101, 595,
+ 2247, -364, -315, -105, -130, -79, 121, 210,
+ 7994, -1302, -898, -785, -758, -777, 31, 415,
+ 744, -652, 688, 1226, -649, -605, -268, 314,
+ 611, 662, -240, -411, -698, -434, 377, 339,
+ 953, -810, -931, 1054, -484, -298, 721, 522,
+ 922, -1046, -952, -871, -618, -270, 419, 635,
+ 1006, 129, -838, -724, 220, 481, 253, 329,
+ 205, -456, -724, 675, 598, 332, -14, 291,
+ -1016, -695, 542, 1270, 498, -456, -113, 362,
+ -547, -1068, -1178, -1261, -1161, -905, 390, 2204,
+ -1056, -1102, 5611, -1100, -1076, -902, 360, 978,
+ -538, -286, 1253, -430, -457, -148, -1, -60,
+ -1116, -955, 2869, -926, -680, 1111, 706, 842,
+ -1311, -1275, -1150, -236, 675, 897, 758, 912,
+ 1886, -1115, -999, -84, -588, 2190, -171, 739,
+ -737, 150, -902, -854, -917, 334, 557, 534,
+ -851, -39, -25, 214, -136, -73, 263, 234,
+ -1021, 1332, -543, -655, -712, -651, 80, 479,
+ 1555, 1933, -707, -485, -206, 139, 312, 405,
+ 2472, -1172, -945, -939, -713, 568, 1421, 684,
+ 70, -1263, -1235, 586, -195, -1065, -449, 3182,
+ -1143, 529, -926, -558, 419, 390, 375, 563,
+ -1090, 3370, -688, -528, -346, 136, 317, 615,
+ -803, -977, -1082, -806, 3607, -443, -156, 1130,
+ -1288, 1585, -1218, -1226, -979, 359, 1555, 1402,
+ -341, -416, -480, -360, -415, 542, -148, -322,
+ -1095, -1074, 762, -864, -634, 1770, 340, 466,
+ -1040, -834, 1508, -707, 143, 74, 1418, 905,
+ -1094, -710, -549, -860, 373, 1492, 2024, 741,
+ -938, -910, 2661, -1087, -1105, -901, 383, 906,
+ 755, -819, 581, -612, -420, 305, 344, 363,
+ -356, -991, -845, -1051, 2112, 1738, 554, 954,
+ -1028, -943, -892, -896, -236, -674, 1076, 679,
+ -611, -1099, -859, -914, -444, 910, 491, 709,
+ -1063, 775, 496, -669, -304, 672, 261, 496,
+ -1086, -963, 1037, -639, -134, -577, 33, 607,
+ -1070, -649, 730, -748, 1884, -18, 346, 627,
+ -1089, -1118, -955, 751, -690, 606, 1204, 1037,
+ -1016, -1095, 473, -919, -1036, -685, 1744, 1216,
+ -834, -916, -920, -634, 1086, -474, 161, 620,
+ -997, -899, -25, -499, 399, 405, 163, 401,
+};
+
+static const int16_t fcb11s[] = {
+ -1148, -1134, -1000, -585, 715, 774, 626, 650,
+ 2109, -898, -729, -239, -213, 847, 77, 371,
+ -902, -790, 1853, -871, -816, 163, 295, 377,
+ 1718, -1070, -840, -791, 1612, -129, 144, 450,
+ -830, 1909, -539, 803, -411, -188, 122, 148,
+ 1202, 705, -696, -578, -213, -25, 126, 142,
+ 3309, -1083, -865, -771, -470, -237, 980, 521,
+ 428, -995, -1003, 3088, -1000, -455, 320, 503,
+ -615, 1746, -751, -734, 1092, 31, 97, 225,
+ -1175, 2287, 1278, -421, -315, 91, 130, 120,
+ -1203, 4211, -970, -878, -228, 71, 327, 288,
+ -1012, -850, 1471, -732, 1228, 201, 146, 271,
+ -868, -528, 1196, 744, -186, 85, 38, 153,
+ -1081, -895, -742, 1014, 1110, 66, 237, 335,
+ -1012, -1137, 4357, -1062, -569, 377, 268, 445,
+ 1203, -717, 1070, -541, -72, -29, 91, 104,
+ 6448, -1148, -1069, -810, -659, 118, -284, 300,
+ -1085, -940, -214, -621, -781, -622, 1789, 711,
+ -1165, 1643, -890, -809, -533, 148, 384, 373,
+ -910, -986, -855, -1032, 3647, -478, -132, 713,
+ -3, -674, -1036, -956, -899, 2698, 629, 665,
+ -764, -1066, -1173, -1058, -692, -144, 1114, 3195,
+ -1012, -643, -670, 1547, -576, 351, 251, 273,
+ -950, 563, -742, 248, -149, 514, 100, 185,
+ -193, -616, -655, 255, -364, -323, 172, 256,
+ 308, 228, 16, -187, -243, 219, 88, 53,
+ -1024, 664, 450, -416, -189, -239, 43, 102,
+ -64, -499, -159, -400, 905, -64, -68, 46,
+ -1055, -77, -813, -661, 59, -77, 226, 321,
+ 1224, -553, -436, 793, -155, -83, -5, 72,
+ -652, -897, -157, -579, -539, 846, 181, 318,
+ 782, -967, -802, -569, -6, 364, 540, 513,
+};
+
+static const int16_t fcb11m[] = {
+ -453, -1087, -1133, -1125, -852, -158, 1152, 3313,
+ 1015, -444, 1085, -465, -317, -298, -471, -238,
+ -647, 1426, -241, 149, -300, -169, -19, -228,
+ 3282, -269, -1025, -1069, -1097, -1071, -539, 1303,
+ 1111, -933, -741, -801, -553, 98, 393, 1031,
+ -786, -729, -835, -810, -78, 1569, 631, 944,
+ 1031, 651, -409, -397, -346, -221, -99, -216,
+ -88, -211, -419, 193, 1298, 196, -221, -879,
+ -1036, -1303, -1282, -1052, -575, 283, 3110, 1337,
+ 489, -463, -640, 112, 341, -322, 261, 266,
+ 1646, -817, -1256, -1273, -1217, -1031, -142, 3691,
+ 3012, 1564, -289, -830, -970, -1032, -1075, -989,
+ 556, 52, -588, -589, -613, -748, -352, 2054,
+ -69, -785, -718, -499, -141, 192, 1396, 446,
+ -3, -514, -612, 3, 171, 1067, -114, -109,
+ -812, -893, -776, -342, 1428, 421, 438, 552,
+ -933, -1143, -207, 1312, 791, 166, -198, -79,
+ -632, 1122, -537, -620, 450, 97, -85, 174,
+ 1760, 123, -168, 485, -77, -567, -776, -952,
+ -758, -1176, -1322, -1355, -1207, -928, -177, 6229,
+ -413, 261, -327, -848, -725, -395, 849, 1533,
+ -201, -124, 2976, -335, -703, -674, -727, -949,
+ -521, 209, 1004, 838, 56, -477, -751, -603,
+ -922, -615, 1832, -448, -329, -148, 73, 467,
+ 4991, -86, -809, -928, -951, -956, -819, -751,
+ 1841, -790, -712, -116, -113, -91, 0, -388,
+ -729, -196, 758, -377, 68, 85, 428, -35,
+ -5, 2, -9, 18, -31, 53, -23, 26,
+ -896, -445, -188, 818, -347, -44, 502, 578,
+ 101, 2968, 269, -724, -702, -747, -719, -673,
+ 7587, 68, -1171, -1377, -1441, -1455, -1473, -1178,
+ 699, 585, 15, 2257, -503, -940, -1085, -1288,
+};
+
+static const int16_t fcb11sl[] = {
+ -1502, -1463, -1336, -1177, -367, 89, 475, 867,
+ 550, 820, -805, -580, -803, -89, -817, 1691,
+ -304, 120, 36, 564, 409, -525, -820, 362,
+ -969, -870, -605, 1983, 993, 722, 1505, 1101,
+ -842, -848, -918, -379, -71, 257, 499, 607,
+ 1619, -956, -1024, -869, -744, -74, 795, 684,
+ 532, 634, -1360, -818, 49, -981, 111, -473,
+ -718, -477, 377, 710, -1399, -1105, -1152, -1024,
+ 2426, -356, -191, 1079, 911, 1164, -809, -791,
+ -919, 2731, -851, -400, -113, 242, 508, 847,
+ -1229, 1199, -910, 1127, -686, -383, 26, 352,
+ 536, 646, -790, -1243, -1103, -1170, -1132, -1065,
+ -788, -521, 161, 3842, -1098, -883, -1052, 8,
+ -1103, -747, -552, -480, -241, 820, 3392, -770,
+ -770, -724, -588, -426, -153, 426, 639, 724,
+ 1626, -713, 1157, -736, -492, -512, -160, 461,
+ 569, 583, -1351, 1332, -1222, -1358, 240, 1541,
+ -724, 612, 1583, 1194, -1061, -990, -671, -969,
+ -952, 2368, -442, -413, 1933, 1023, -144, -283,
+ -992, -940, 983, -232, 818, 341, 502, 549,
+ -1420, -1268, -1279, -1213, -621, 2019, 685, 1948,
+ 1264, 1200, -1293, -664, 392, -848, 866, 1191,
+ -220, 95, 450, 640, -1334, 1098, -751, -701,
+ 1296, -347, -92, 233, 532, 599, -952, -694,
+ 3085, -908, -256, -494, -177, 123, 809, 941,
+ 18, -1089, -801, 303, -761, 11, 632, 288,
+ 476, 518, -241, -1138, -1068, -869, 292, 121,
+ -26, -96, 457, 548, -106, -784, 930, -700,
+ 1842, -812, -617, -307, 430, 655, -698, 1157,
+ 947, -803, -662, -743, -49, 1120, 348, 578,
+ 855, -1049, -753, -67, 710, -347, -28, 694,
+ 411, 468, -61, 239, 23, -1072, -757, 477,
+ -658, -362, 239, 576, -1479, -1279, -1286, -677,
+ -939, -722, 3217, 338, 1562, 1566, 925, 917,
+ -697, -708, 645, -447, -280, 714, 503, 552,
+ -1050, -1021, 889, -956, -934, 705, 457, 616,
+ 556, 667, -1331, -51, -256, -48, -234, 240,
+ 757, -74, 148, 356, -1278, 1538, 234, -372,
+ -472, -221, -424, -494, 170, 551, 216, 294,
+ -885, 231, -263, 334, -64, -54, 291, 350,
+ -1140, -1074, -1199, -1374, -1278, -845, -547, 667,
+ 4544, 1922, -899, -930, -954, -1120, -1092, 1156,
+ 1889, -404, 259, 1114, -956, -836, 881, -316,
+ -977, -860, 202, -249, 121, 816, -1188, 3644,
+ -829, -876, -670, -473, -161, 420, 851, 886,
+ -1014, 1191, -938, -958, -864, 741, 241, 957,
+ 288, 629, -1155, -898, 1104, -789, 28, -867,
+ -580, 2588, 836, 1234, -953, -749, 934, 1137,
+ -310, -177, -113, 244, 532, 424, -341, -602,
+ -880, -1105, -303, -381, -527, 1943, 126, 759,
+ -1277, -1037, 59, -783, 485, -589, 1341, 737,
+ 488, 709, -1473, -1208, -1082, 589, 791, 735,
+ 447, 322, 835, 731, -1116, -681, -592, 704,
+ 520, -545, -104, -24, 263, 458, 632, -721,
+ -1086, -1223, -1150, -866, 1537, 2815, 123, 1097,
+ -1238, -861, -1217, -1238, -1261, -914, 1165, 422,
+ 711, 883, -1196, -972, -428, -230, 171, 8,
+ -448, 1195, 445, 440, -413, -139, -375, -568,
+ -781, -520, 611, -586, 881, 589, -724, 972,
+ -907, -794, -819, -641, 1650, 66, 254, 703,
+ -1380, -1168, -967, 676, -765, -537, 578, 1542,
+ 687, 833, 1151, -811, -948, -995, -246, 1301,
+ -377, 262, 632, 652, 1530, -679, -682, 993,
+ -666, -457, -72, -20, 317, 516, 861, -528,
+ 24, -579, -386, 53, 526, -76, 66, 345,
+ -59, -612, 165, -181, -98, -34, -66, 286,
+ 95, 108, -1118, -147, 643, -1055, -768, -502,
+ -587, 27, 2113, 811, -1219, -947, -811, -1188,
+ 1143, -609, -753, 88, 2844, 1424, -1428, -1082,
+ -1273, 1086, -1206, -1171, 279, -510, 2325, 1757,
+ -1437, 654, -1278, -1267, -1117, -950, 779, 2205,
+ 1150, 1101, -1484, -1009, -1199, -1416, -1215, 657,
+ -737, 634, 1266, 1742, -1445, -1193, -1358, -1158,
+ -1015, -995, -655, 4035, 1966, 1903, -1069, 954,
+ -1099, -1171, -1029, -818, -576, -104, 1390, 1069,
+ 559, -914, -1034, -1152, -987, -582, -222, 394,
+ 1204, 775, -1464, -51, -959, -1005, -452, 347,
+ -94, 1, 525, 595, -1324, -1226, -1102, -825,
+ -927, -776, -582, 175, 1675, 632, -859, 28,
+ -914, -209, -468, -625, -230, 646, 579, 446,
+};
+
+static const int16_t fcb11ss[] = {
+ -1351, -1229, -1174, -767, 1403, 182, 532, 445,
+ 415, 610, -1095, -771, -1142, 3221, -803, -680,
+ -302, 318, 441, 438, -1188, 1145, 1552, -528,
+ 887, -547, -429, 124, 99, 128, -768, 1049,
+ -562, 1121, -593, -96, -105, 105, 251, 154,
+ 1684, 1598, -635, -685, -177, -211, -268, 234,
+ -118, -49, -719, -873, -1092, -985, -678, -406,
+ -234, 407, 653, 3195, 991, -584, -874, -14,
+ -683, 2964, -769, -450, 287, 350, 853, -803,
+ -574, 1761, -410, -60, -230, -78, -21, 19,
+ -1271, 4435, -673, -790, 110, -243, -81, 147,
+ 191, 145, 5571, -611, -634, -699, -195, -281,
+ -249, -302, -272, -67, -893, -656, -745, -697,
+ -550, -639, -409, 3085, 383, 798, -311, -340,
+ -564, -787, 3628, -332, -510, -219, 465, 351,
+ -747, -1084, -972, -727, -404, -630, -176, 437,
+ 3352, 978, -886, -751, -767, -580, -693, -942,
+ -803, -158, -36, -3, -966, -674, 3075, -926,
+ -172, -9, -40, 111, 169, 212, 181, -811,
+ -715, -986, -521, -686, 3915, 18, -58, 499,
+ 210, -1187, -903, -915, -522, 1038, 477, 788,
+ 290, 412, -1010, -791, -700, -710, 34, 1774,
+ -256, 96, 131, 241, -1251, 2086, -5, -765,
+ -446, 141, 93, 160, 88, 129, -1153, 1171,
+ -1192, -1073, -391, -187, 206, 416, 444, 648,
+ 707, -542, -504, -750, -623, -648, 776, 692,
+ 165, 330, 1112, -1199, -876, -428, 949, 65,
+ 250, 104, 108, 173, 2147, -905, -846, -540,
+ -376, -131, -113, 124, 314, 485, 1253, -515,
+ 1435, -527, 21, -100, -368, -84, -119, -144,
+ -1375, -1189, -1189, -999, -723, -190, 796, 639,
+ 699, 816, -1188, -919, 683, 842, 177, -62,
+ -25, 71, 15, 16, 157, 80, -331, -343,
+ 12, 193, -133, -94, -94, -64, -1306, 531,
+ -917, -142, 1274, 102, -15, 184, 159, 148,
+ -43, -1103, -581, -419, 447, -132, -204, 187,
+ 631, 461, -1302, -1162, -927, 896, 203, 164,
+ -55, 287, 544, 485, -1258, -791, 677, -945,
+ -244, -101, 423, 362, 298, 389, -825, -640,
+ -646, 274, -73, -274, 1473, -13, 132, 169,
+};
+
+static const int16_t fcb11sm[] = {
+ -767, -1179, -1188, -1069, -690, -172, 787, 1389,
+ 1623, 844, -169, -894, -919, 51, 15, 426,
+ -326, 1579, 182, 77, 202, -417, -357, -17,
+ 2154, -77, -607, -589, -375, -261, -376, 175,
+ -829, -801, -579, -290, -244, 533, 1307, 873,
+ -877, -1175, -1157, -726, 461, 1729, 433, 219,
+ 246, 606, -791, -827, 649, 891, 820, 720,
+ 407, -641, -727, -708, 2498, 961, -99, -542,
+ -530, -507, -536, -608, -642, -622, 316, 195,
+ -721, -549, -253, 1520, 171, -81, -372, -333,
+ 1166, -1072, -1230, -1123, -1031, -868, -370, 209,
+ 1561, 1751, 113, -367, 399, -663, -10, -271,
+ 950, 118, -335, -272, -863, 60, -875, 1850,
+ -242, -276, -38, -106, 471, 30, 823, -344,
+ -752, -714, -309, -419, 86, 1604, -250, -185,
+ -839, -703, -561, -281, 1813, -57, 255, 266,
+ -32, 99, 400, 2520, 315, -372, -306, -511,
+ -549, -659, -760, -729, -559, -137, -610, 174,
+ 924, -310, -705, -307, 885, 512, -611, -1097,
+ -1172, -1072, -758, -527, -192, 278, 740, 3398,
+ -1136, 409, -230, -353, -137, 322, 326, 365,
+ 133, 173, 2291, -644, -725, -596, -535, -340,
+ -88, -65, -53, 273, -760, -390, -649, 119,
+ -243, -222, 1726, -113, 44, 326, -618, 311,
+ 2345, -241, -398, -399, -382, -322, -444, -457,
+ 1873, -454, -505, 42, 481, 187, -49, -505,
+ -634, -754, 1052, -597, 1315, 297, -412, -110,
+ -205, -552, -682, -524, -1055, -431, 971, -363,
+ -539, -366, 39, 995, 181, 476, 662, 229,
+ -445, 1682, -205, -181, -273, -497, -685, -628,
+ 6135, -21, -834, -934, -1002, -1066, -931, -974,
+ -902, -643, -820, 1891, -706, -288, -252, -231,
+ -79, 126, 35, 37, 10, -10, -36, -6,
+ -9, -47, -7, 1, 11, -2, 644, 315,
+ 145, -353, -396, -428, -357, -60, 275, 109,
+ -1179, -952, -698, 138, 286, 171, 394, 263,
+ 814, 495, -490, 110, 369, 599, 9, 599,
+ -431, -233, -328, -69, 410, -1002, -462, 77,
+ 97, 196, 133, -91, 512, 49, 621, -436,
+ -352, -390, -211, -188, -454, -318, 44, 1424,
+};
+
static const int16_t fcb16l[] = {
-13, -798, -772, 235, 515, -181, -120, -509,
-392, -1159, -844, -1041, -881, -1193, 1103, -1080,
@@ -3741,6 +11208,649 @@
-688, -209, 915, 622, -1038, -474, -343, -91,
-173, -104, 255, 96, 1547, 773, -625, 2272,
-90, -509, -527, -247, -147, -234, -45, 166,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const int16_t fcb16sl[] = {
+ -1337, -1122, -1559, -1452, -1353, -973, 3858, 1145,
+ 1225, 2103, -607, -181, 557, -429, 15, -496,
+ -444, -523, -1866, -1134, -1270, 3029, -1110, -798,
+ -824, -659, 44, 614, 1059, 1173, 714, -932,
+ -1095, -1061, -921, -1034, -873, 7, -872, 660,
+ -1335, -1496, -1623, -1405, -1070, -680, 943, 134,
+ -190, 2837, -1034, -221, -337, -540, -571, -173,
+ -411, 2314, -111, 970, -1220, -1036, -1096, -147,
+ 1087, 604, -367, 83, 461, 679, -1333, 194,
+ -1292, -1139, -1097, -570, -508, -109, 54, 962,
+ 2592, -1112, -944, -636, -521, 12, 230, 442,
+ 562, 624, -1107, -1190, 1554, -981, 1507, -1013,
+ -394, 595, 823, 1094, -1453, -1298, 242, -1185,
+ -686, -541, 858, 331, 695, 1197, -1259, 968,
+ -1180, -1254, -752, 1473, 222, 342, 973, 1029,
+ -1631, -1500, -1619, -1517, -1299, 1683, 2203, 1163,
+ 1225, 1497, -1189, -937, -931, 3193, -977, -708,
+ -262, 549, 917, 1465, 704, -565, -708, 846,
+ -130, -322, -257, 221, 367, 309, -1416, -1123,
+ -1323, -1260, -405, 3303, -210, 785, 1007, 1616,
+ -1043, -717, 44, 824, 419, -492, -579, -604,
+ -15, 676, -1067, -1079, 3897, -1211, -474, -1020,
+ -589, 114, 593, 1504, -1481, -1249, -1036, -1012,
+ -719, 846, -189, -297, -31, 1209, -1761, -1566,
+ -1449, -1645, -1464, 1422, 24, 2153, 1377, 1948,
+ -1480, 652, -929, -415, -689, -386, 1628, 489,
+ 487, 756, -1424, -805, 1241, 228, -697, -316,
+ 423, 660, 557, 587, 1248, -777, 1088, -848,
+ -498, -399, -60, 169, 497, 689, 5679, -778,
+ -1109, -1118, -895, -1042, -504, 390, 1670, 469,
+ 977, -929, -1173, -1058, -999, -696, 1912, 52,
+ 1297, 1081, -1469, -1243, -1055, 385, -529, 910,
+ 79, 508, 1225, 753, 656, -1307, -1239, -1470,
+ -1110, -1255, -362, 2351, 889, 1687, -1566, -1331,
+ -1410, -1385, 779, -499, -217, 936, 2064, 1493,
+ -1499, -1345, -1162, 790, -1115, -673, 2083, 1010,
+ 588, 1265, -1439, -1168, -1294, 752, -1421, -1234,
+ -169, -529, 1606, 2131, -1556, -1442, -1444, 487,
+ -1260, -1139, 360, 2528, 1994, 1686, -1548, -1473,
+ -563, -1125, 967, 1490, 1503, 487, 991, 1024,
+ -1430, -1151, -1215, -729, -746, -762, -472, 778,
+ 889, 774, -1329, -1129, 1383, -1230, -723, 1478,
+ 379, 161, 1266, 1238, -1467, -843, -1277, -1323,
+ -715, 58, -182, 5140, 762, 1723, -1285, 1134,
+ -1175, -1057, 1294, -4, -417, 557, 939, 1182,
+ 39, 565, -809, -703, -783, -883, -112, 412,
+ 1056, 691, -273, -1334, -898, -1345, -1069, -1247,
+ -105, 638, 6811, 1157, 982, -856, -805, -1093,
+ 1267, -747, -650, 311, 281, 1076, 1371, 1614,
+ -891, -886, -396, -246, -65, 77, 472, 605,
+ -943, 178, -509, 112, -142, 512, -66, 109,
+ 144, 76, 2934, -1203, -1428, -1525, -1269, -1618,
+ -1129, -184, -225, 3157, -249, -1276, -1055, -439,
+ -161, -268, 284, 614, 778, 670, -1243, 1682,
+ 919, -468, -479, -341, 31, 468, 325, 606,
+ -1081, -723, 83, -399, -275, -658, 240, 149,
+ 2746, 679, -1573, -1287, -494, 775, 975, -751,
+ -47, 1758, 652, 1155, -1465, -1073, -1087, -1026,
+ 289, 340, 448, 1348, 351, 682, 2065, -1183,
+ -1313, -1562, -466, -1546, -1077, -477, 3012, 2512,
+ -1560, -1532, -1441, -1229, 861, -421, 1515, 2195,
+ 1163, 1418, -1268, -1103, -804, -1094, 3254, -711,
+ -558, 713, 1414, 1684, 542, -781, -827, -814,
+ -245, 1129, -160, 210, 386, 618, -1633, 488,
+ -1584, -1571, -1349, -662, 711, 1516, 1661, 1673,
+ -1510, -1530, 1013, -1172, 425, -1415, -856, 2963,
+ 2258, 1919, -744, -1208, -863, -634, -729, -1068,
+ -857, -289, 701, 6703, -1502, -1353, -1531, -1372,
+ -1388, -1067, 1392, 100, 2570, 1703, -1551, -1500,
+ -1587, -1693, -1753, -1431, -1048, 1162, 1308, 3073,
+ -998, -1575, -517, -1346, -1293, -1493, -1375, -1109,
+ -803, 2972, -1446, -1316, -1114, -1405, -1240, -1057,
+ -1109, -589, 2623, 1626, -1555, -1026, -1346, -1467,
+ -902, 1291, 176, 630, 4293, 1949, -1233, -1362,
+ -930, -1175, -1118, -1375, -1172, -967, 4896, 4195,
+ -1744, -1562, -1797, -1815, -1577, -1194, 371, 3326,
+ 3183, 3071, -1425, -1773, -1562, -1358, -547, -246,
+ 24, -526, -1502, 29376, -860, -614, -857, -795,
+ 793, -616, 1691, -125, 156, 559, -1643, -1462,
+ -1523, -1413, -1251, -592, 1014, 1888, 243, 1041,
+};
+
+static const int16_t fcb16ss[] = {
+ 308, -532, -811, -974, -641, -431, 3409, 258,
+ 567, 641, 1315, -723, -738, -502, 142, 678,
+ -67, -170, 73, -65, 2717, -804, -958, -878,
+ -532, -562, 238, 497, 548, 718, -868, -669,
+ -932, -1004, -518, -502, -286, 405, 2987, 1420,
+ 174, -779, -748, -575, -153, -40, 340, 413,
+ 275, 387, 965, 82, -550, -744, -592, -591,
+ -604, -163, 428, 843, -1280, 1756, -368, 777,
+ -29, -453, -61, 43, 50, 137, 950, -229,
+ 1504, -491, -353, -167, -285, -158, -94, -185,
+ -1431, 303, 673, -758, -610, -308, 1247, 348,
+ 95, 31, 1631, 1963, -624, -770, -466, -150,
+ -122, -123, 34, -141, -883, -374, -948, -629,
+ 3420, -772, -392, -31, 603, 646, -760, -871,
+ -936, -948, -727, 3563, -376, 858, 699, 561,
+ -1370, 2366, -775, -1241, -1105, -247, 177, 432,
+ 414, 379, -1360, -1057, -945, -848, -568, -779,
+ -632, -328, -295, 425, -349, 630, -275, -527,
+ 438, 47, -194, -96, -239, -545, -1381, -689,
+ 1644, 1165, -437, -153, -193, 307, 183, 66,
+ -1335, 2590, 2169, -447, -435, -317, -82, 204,
+ 45, -145, -1324, -205, 4019, -973, -578, 28,
+ 175, 506, 235, -98, -908, -294, 1443, -850,
+ -556, 1707, -277, 58, 241, -188, -853, -572,
+ -577, 1258, 1007, -190, 1, -3, 103, -49,
+ 5385, 137, -707, -834, -510, -517, -392, -390,
+ -231, -275, -1249, 5229, -812, -893, -353, -663,
+ -29, 187, 45, 10, -1388, -1171, -1051, 412,
+ -379, -411, 240, 574, 632, 284, -838, -912,
+ -924, 3062, -695, -409, -224, 422, 293, 267,
+ -1436, -1237, -1303, -1305, -914, -243, 821, 839,
+ 1043, 1284, -1178, -496, 1594, -736, 1752, -601,
+ -396, 330, 231, 48, -1253, 808, -896, -967,
+ -653, -84, 4, 442, 363, 589, -1005, -672,
+ -687, -93, -274, 1376, -232, -52, 399, 255,
+ -1085, -1214, -1088, -748, 1036, 414, 220, 509,
+ 436, 499, -648, -765, -931, -983, -758, -543,
+ -379, -115, 780, 3327, -1086, -893, -773, -881,
+ -683, -11, -322, 3418, 739, 961, -1363, -929,
+ 899, -1005, -792, -338, -185, 702, 627, 638,
+};
+
+static const int16_t fcb16sm[] = {
+ -1125, -1385, -1439, -1387, -1120, -681, -135, 616,
+ 3086, 2537, -1440, -1209, -1027, -1209, -626, 173,
+ 662, 899, 861, 2180, 387, 1032, 936, 140,
+ -353, -302, -290, -330, -551, -1019, 3555, -68,
+ -441, -539, -500, -27, -423, -506, -522, -415,
+ 2347, 1890, -312, -742, -679, -679, -653, -609,
+ -433, -472, 2709, -755, -1153, -1066, -1028, -862,
+ -826, -315, 78, 1699, -363, -429, -690, -190,
+ -358, -667, 1909, 39, -1, 138, -1592, -1559,
+ -1357, -1554, -750, 813, 1676, 1537, 977, -269,
+ 8320, -602, -1140, -1153, -1136, -1174, -1004, -1091,
+ -1388, -1187, -507, 3103, -200, -665, -590, -381,
+ -365, -40, -295, -591, -963, 271, 2231, -547,
+ -65, -270, -64, 243, -183, -548, -796, -277,
+ -7, -168, 1575, -361, 35, -19, 192, -154,
+ -384, 144, -426, -528, -598, -778, -297, 1847,
+ 564, 218, 864, -654, -485, -435, 45, 709,
+ 630, -11, -691, -111, -775, -356, -522, 2247,
+ -79, -433, -620, 594, 79, 60, -828, -475,
+ 768, -79, -655, 550, -201, 77, 858, -11,
+ -803, 1173, 1027, -971, -656, -648, -40, 17,
+ 720, 176, -1055, -936, -258, 550, 1086, 1065,
+ 0, -473, -364, 30, 53, -6, -54, -24,
+ 21, -81, -88, -45, -14, 81, 674, -1189,
+ -1049, -846, -489, -24, -47, 165, 658, 1909,
+ -241, -390, -387, -454, -319, -549, -307, -112,
+ 778, 1486, -314, 34, -93, -799, -538, 2219,
+ -445, 39, -38, -258, -427, -943, -760, -602,
+ -575, -450, 376, 668, 879, 1215, -1216, -784,
+ -646, -291, 275, 1019, -77, 124, 256, 1166,
+ -410, -993, -1145, -1118, -940, -825, -560, -131,
+ 1006, 4878, -1401, -1286, -1316, -1394, 177, -919,
+ 162, 2292, 1792, 1242, -762, 937, -168, -900,
+ -829, 203, 1225, 626, -122, -515, 992, -198,
+ -782, -25, 74, 1019, -606, -364, -350, -5,
+ 451, 324, 265, -1143, -820, 382, -362, 85,
+ -797, 693, 1594, -335, -229, -396, -211, -356,
+ -97, -115, 92, 49, -476, -1124, -1084, -594,
+ -228, 728, 16, 589, 1213, 841, -829, 1874,
+ -907, -1000, 1411, -621, -707, 356, 437, 37,
+};
+
+static const int16_t fcb22l[] = {
+ 2735, -1224, -1198, -1073, -1115, -1054, -713, 1693,
+ -1106, -1259, 722, -1256, -1223, 1686, 1589, 2003,
+ -906, 2529, 2141, -396, -338, -36, 52, 476,
+ 319, -420, 561, -492, -526, -359, -221, -254,
+ -752, -1136, -690, -896, 4307, -363, -42, 1363,
+ -717, -1036, -874, 2315, -952, -872, 262, 1418,
+ 737, 1374, -506, -470, -275, -126, 242, 428,
+ -678, -681, -581, 1016, -553, -509, -485, -408,
+ 9595, -1015, -1168, -932, -812, -690, -167, 753,
+ -935, -439, 2105, -526, -710, -570, 9, 548,
+ 530, -1308, -1060, -351, -974, -1038, 93, 5579,
+ -737, -1282, 1386, -1284, -1243, -1105, 790, 2169,
+ -701, -660, -555, 1317, 2805, 792, 2209, -490,
+ -758, -1262, -1083, -1073, 930, -810, -170, 2326,
+ -1213, -1286, 3435, -1135, -1051, 220, 3040, 1999,
+ -933, -663, -714, -855, -372, -599, -437, 373,
+ 5873, -987, -1081, -1003, -747, -271, 582, 1069,
+ -917, -754, 5676, -565, -616, -396, 177, 908,
+ 3106, 1459, -678, -543, -340, 47, 336, 493,
+ -1060, 1427, -560, -763, -710, -661, 193, 595,
+ -996, 2488, -588, -752, 1306, 114, 292, 689,
+ -1202, 2334, -1173, -1167, -755, 353, 1711, 1572,
+ -932, -751, 2099, 2025, -417, 62, 458, 611,
+ -981, 4387, -639, -560, -520, -152, 262, 748,
+ -828, -818, -682, 5250, -640, -270, 385, 1049,
+ -1072, -774, 1870, -668, 1514, -158, 283, 793,
+ -1087, -1150, -899, -875, -188, -184, 6656, 2311,
+ -906, 1654, -446, 1677, -654, -101, 364, 721,
+ -1272, 7928, -812, -576, -708, -347, 397, 1128,
+ 3830, -1034, -1055, 2244, -759, -706, 79, 893,
+ -922, -1067, 2740, -868, -858, 1129, 34, 1096,
+ 2455, -694, 1970, -650, -674, -131, 370, 697,
+ -1069, -1137, -948, -1045, -1087, -964, 367, 1091,
+ 4096, -960, -921, -870, 1397, -511, -190, 545,
+ -657, -1194, -536, -951, -1094, 117, -720, 2532,
+ -1098, -1147, -1177, 1764, -757, -121, 2372, 2010,
+ 3662, -952, -995, -894, -625, 464, 731, 863,
+ -607, -505, 401, -423, -540, 2144, 755, -430,
+ -1499, -1242, -1202, -1190, -626, 1249, 3388, 2379,
+ -983, -1090, -907, -1021, -1012, -870, 2723, 1589,
+ -913, 332, -102, 99, 226, 6, 176, 354,
+ 156, -36, -829, -774, -685, -15, 498, 503,
+ 2030, -409, -599, -572, -341, -2, 111, 302,
+ 788, -1002, -978, -929, -1001, -886, 578, 995,
+ 1237, -747, -696, -653, 1143, 62, 506, 571,
+ 994, -993, -902, -871, -662, 1527, 370, 979,
+ 980, -466, -484, 787, -261, 61, 250, 377,
+ -112, -676, -535, -344, 274, 363, 185, 334,
+ -48, -1144, -1095, -1011, -552, 445, 1355, 1207,
+ -1108, -1128, -1085, -826, -83, 2001, 1265, 1429,
+ -1024, 1199, -671, -701, -444, 1192, 187, 673,
+ -1039, -1056, -953, -732, 359, 714, 787, 935,
+ -1187, -1133, -1112, -971, 2158, 1720, 801, 2016,
+ -1056, -1068, -889, 1808, 503, 892, 358, 1041,
+ -1180, -1184, -1068, -788, 1423, -573, 2141, 1949,
+ -1042, -924, -849, 512, -629, -272, 779, 815,
+ 1939, -1069, -1092, -1027, -770, 48, 1554, 1285,
+ -1109, -1148, -1157, -1033, -934, 779, 1358, 1560,
+ -1053, 222, -1095, -1001, -681, -26, 1112, 1035,
+ -1168, -1285, -1169, -1180, -1085, -1097, 1313, 3112,
+ -928, -655, -811, -618, 1555, -480, 71, 467,
+ -1220, -1123, -1008, -577, -845, 3854, 491, 1878,
+ -1051, -761, 617, -650, -453, 51, 784, 757,
+ -993, -883, -905, -708, -869, 969, -64, 655,
+};
+
+static const int16_t fcb22s[] = {
+ 9854, -479, -1163, -1147, -1316, -1137, -991, -942,
+ 522, 739, -1042, -1306, -1040, -126, 1147, 3526,
+ 1880, -477, -483, -328, -899, 1063, 1243, -610,
+ -721, -527, -372, 171, 90, 196, 6615, -1167,
+ -1189, -1079, -954, -817, -833, 2246, 439, 1038,
+ -1053, -1136, -938, -805, -1022, -1041, -717, 2021,
+ 341, 935, -1164, -1230, -573, 1768, 11111, -1113,
+ -874, -631, -367, 7, -1077, -925, 1558, -850,
+ -918, -755, -512, 452, 260, 400, -787, -966,
+ -690, -584, -843, -802, 2092, 120, 103, 580,
+ -746, -512, -241, -621, 2771, -486, -268, 258,
+ 171, 232, -1265, -1253, 15128, -1123, -1037, -885,
+ -1109, -664, -659, -240, 1558, -909, -1160, -1247,
+ -1223, -1031, -989, -415, 3504, 1569, -651, -1241,
+ -1145, -1014, -1322, -1000, -354, 59, 709, 4206,
+ -1124, -986, -633, -976, -907, -636, -371, 255,
+ 1195, 876, -145, -1146, -1018, -992, -480, -762,
+ 6904, -703, -431, 1043, -1048, -638, -142, 394,
+ -852, -730, -533, -361, 234, 221, -1070, -930,
+ -764, 3210, -780, -256, 1777, 258, 307, 382,
+ -1224, 987, 4894, 3525, -412, -558, -819, -863,
+ -572, -497, -1175, -1197, 7637, -1109, -748, -116,
+ -306, 27, 386, 630, -1334, -1378, -1302, 12592,
+ -1327, -971, 89, -731, 259, 201, -1135, -951,
+ -585, -64, 3489, 2765, 43, 75, -527, -162,
+ 2865, -1344, -1394, -1391, -1231, -748, -962, 5403,
+ 719, 1418, -724, -1101, -955, -743, -937, -1064,
+ -1095, -601, -60, 411, -1113, -873, -603, 2913,
+ 2512, -339, -36, 26, -39, 78, -757, -998,
+ -522, -838, 5507, -973, 796, 536, 250, 312,
+ -1363, -944, 6021, -58, 5313, -690, -549, -485,
+ -66, -133, -1257, 6004, 6374, 1487, -976, -987,
+ -969, -803, -1027, -624, -967, 1744, 3504, 6,
+ -659, -691, -326, -129, -49, 148, -1032, -683,
+ 1819, 1804, -491, -452, -295, 33, -20, 42,
+ -1226, -1086, -792, 6412, -657, -278, -103, -25,
+ -82, 207, 2450, -6, 2417, 251, -622, -593,
+ -409, -193, -339, -304, -862, -667, 2457, -500,
+ -438, -504, 1408, 143, 203, 265, -1128, -1148,
+ 2791, -373, -951, 2129, -842, -278, 81, 307,
+ -787, -822, 2655, -604, 2028, -787, 4, 335,
+ 170, 219, 649, -457, 972, -607, -359, -470,
+ -238, 68, -57, 107, 2285, -526, -490, -604,
+ 179, -41, 230, 64, 20, 50, -802, 1168,
+ -235, -264, -316, 1469, -499, 108, 183, 150,
+ -1068, -806, -399, 1244, -355, 487, -57, 450,
+ 195, 248, -1122, -1096, 3327, -956, 1084, 1306,
+ 247, 442, 169, 283, 3416, -609, -891, -879,
+ -853, -573, -285, -147, 380, 608, 1271, -874,
+ -931, 40, -989, 1432, 1981, -34, 285, 190,
+ -902, -974, 4117, -868, -784, -584, -358, 200,
+ 261, 521, -945, -981, -773, 3517, -961, 2420,
+ 9, 318, 187, 322, -1006, -779, -526, 2972,
+ -712, -578, -576, 167, 156, 270, 460, -74,
+ -237, 939, -440, -515, 126, 63, 82, 67,
+ -1069, -1104, -923, -634, -190, 1151, 526, 2920,
+ 125, 566, -1144, 4199, 1314, -458, -568, -336,
+ -515, -332, -352, -143, -770, 283, -770, -785,
+ -807, -348, 93, 427, 181, 334, -798, -830,
+ -300, -509, 1257, -554, 1341, 6, 242, 272,
+ -1030, 62, 1293, 340, 752, -493, -6, -34,
+ 33, 85, -893, -1202, 244, -131, -306, 7590,
+ -832, 420, 80, 423, -799, -870, -930, -720,
+ -640, 2390, -409, -177, 91, 370, -864, -949,
+ 838, -574, -234, 555, 46, -9, -83, 146,
+ -825, -478, -664, -57, 867, -296, -380, -73,
+ 70, 171, -1124, 10522, -228, -609, -958, -1025,
+ -548, -384, -257, 55, 5414, 436, -651, -748,
+ -671, -525, -25, -273, -264, 57, -1129, 1974,
+ -145, 1650, -317, -514, -305, -78, -154, 59,
+ 1269, 1008, -510, -711, -534, -358, 194, 117,
+ 102, 57, -837, 1260, -126, -494, 47, -162,
+ 924, -72, 130, 97, 742, -803, -711, -755,
+ -402, -188, 24, 309, 187, 379, -1092, 5862,
+ -647, -807, -715, -696, -408, -29, 104, 353,
+ 3298, 2193, -263, -772, -908, -754, -449, -164,
+ -157, -44, -986, 2313, -596, 56, 2057, -478,
+ 74, -51, 51, 121, -899, 1793, -595, -669,
+ -743, -689, -546, 71, 201, 382, -1061, 3375,
+ -776, -876, -648, -407, -44, 260, 258, 393,
+};
+
+static const int16_t fcb22m[] = {
+ 11522, 868, -1444, -1572, -1674, -1745, -1844, -1616,
+ -1723, -1508, 27, -321, -693, -597, -374, -380,
+ 327, 209, 611, 1182, -548, 176, -544, -485,
+ -341, -376, -383, 1024, 1316, -4, 192, -649,
+ -979, -945, -802, -183, 3749, 812, -416, -527,
+ -734, 1059, -521, 924, -462, -631, -76, 182,
+ 126, 100, -653, -643, -1189, -1264, -1312, -1311,
+ -1212, -1016, -218, 8415, -1005, 734, 1303, -272,
+ -397, -521, -245, 389, 242, -234, 458, -912,
+ -1215, -1228, -1288, -1131, -845, -404, 912, 5497,
+ 413, 3161, -432, -148, 1704, -663, -996, -1009,
+ -1419, -929, -36, -471, -640, -571, -197, -573,
+ -462, 2586, -179, -382, -757, -895, -1096, -1140,
+ -1216, -1051, -688, -44, 3311, 3518, -474, 2530,
+ 1475, -676, -702, -777, -380, -316, -538, -468,
+ -708, 542, -213, -713, -911, -482, -696, -135,
+ 1282, 2006, 5707, 476, -707, -771, -650, -788,
+ -778, -853, -962, -926, 10, -11, 3, 1,
+ -12, -14, 21, 7, -13, -10, -1410, -1712,
+ 1379, 5757, 218, -1232, -563, -929, -684, -827,
+ -261, 1040, -154, -309, -99, 62, 856, 199,
+ -614, -926, -626, 1568, -258, 374, 1071, -140,
+ -250, -332, -832, -706, -863, -714, -749, 3081,
+ 498, -695, -395, -600, -279, 588, 245, 3122,
+ -329, -677, -262, 67, 19, -530, -882, -862,
+ -1033, -160, 1542, 1916, -416, -600, -553, -219,
+ -130, -497, -699, 1719, 160, 3293, -212, -923,
+ -1045, -761, -1238, -1038, 1543, 738, -548, -541,
+ -403, -281, -115, -95, -313, -19, -292, 1136,
+ 3592, 696, -654, -856, -726, -693, -1057, -1267,
+ -722, -381, -683, 1364, -30, 589, 454, 262,
+ -57, -1018, -312, 846, -139, -587, -127, 2482,
+ -178, -233, -977, -796, -6, 250, 220, 1577,
+ 1141, -251, -649, -809, -1051, -873, -762, -990,
+ -1010, -890, -897, -639, -671, 1964, 788, 2310,
+ 6001, 20, -1008, -1159, -1208, -1208, -1318, -1227,
+ -829, 1680, -1023, -998, -1224, -945, -769, -41,
+ 2033, 196, 917, 1615, 2026, -654, -1014, -918,
+ -750, -675, -839, 1541, 282, 430, -1059, -708,
+ -507, -522, -169, 438, 196, 835, 778, 897,
+ 420, 526, 1239, 198, -736, -953, -835, -229,
+ -348, 726, -767, 1311, 248, -353, -550, 1017,
+ -250, -732, 256, -175, -638, 763, -761, -957,
+ -554, 539, 252, 299, 431, 613, 4398, -378,
+ -1022, -1020, -990, -757, -621, -83, -34, 122,
+ -476, 77, -799, -116, 4546, -787, -735, -462,
+ -875, -907, -1373, -1354, -1355, -1220, -1024, -88,
+ 1298, 2844, 940, 1135, 2261, 2142, 181, -735,
+ -924, -941, -799, -715, -662, 86, -719, -521,
+ 115, -576, -699, 1052, 1295, -57, 42, 230,
+ 2876, 501, -294, -158, 104, -157, -515, -662,
+ -987, -1069, -703, -985, -1061, -946, -878, -267,
+ 397, 132, 534, 3642, 1298, -560, -701, -526,
+ -294, 197, 310, 75, -3, 267, -342, 2058,
+ -328, -427, -709, -688, 14, -43, 237, 506,
+ 2822, -337, -900, -818, -638, -192, 883, -14,
+ -271, -559, 2822, -165, -988, -933, -917, -603,
+ -583, -397, 467, 1092, -1044, -479, 2478, -386,
+ -535, -253, 63, -49, 79, 27, -182, -100,
+ 362, -628, -661, -707, 1557, 136, 335, 89,
+ -197, 5697, 220, -473, -472, -1053, -1023, -1087,
+ -1203, -756, -377, -917, -925, -568, -237, 1422,
+ 197, -98, 614, 867, -831, -829, -969, -720,
+ 414, 1080, 1707, 828, -121, -757, -1044, -289,
+ 816, 284, 809, -84, -22, -552, -9, 193,
+ -359, 66, -582, -674, 1992, -31, 58, 427,
+ -515, -299, 932, -608, -1103, -1068, -1016, -770,
+ 200, 1031, 1112, 1026, -598, -818, -891, -635,
+ -828, -866, -650, 4795, -407, 215, -853, 373,
+ -696, 159, 995, 465, -509, 109, 60, 10,
+ 8455, 198, -999, -1131, -1111, -1195, -1246, -1192,
+ -1181, -934, -365, -764, -689, -589, -734, 2479,
+ -960, 1279, 104, -209, -1012, -824, -1059, -921,
+ -812, -204, 199, 601, 3136, 637, 3021, 3851,
+ -490, -18, -930, -1081, -1133, -1182, -1268, -980,
+ -864, -945, -278, 961, -514, -123, 562, 874,
+ -130, 336, 3314, -331, -1112, -1162, -1227, -1230,
+ -1172, -988, -319, 3582, 890, 50, -681, -788,
+ -906, -876, -829, -827, -41, 3416, -740, -913,
+ -893, 404, 2059, -651, -474, 302, 516, 578,
+};
+
+static const int16_t fcb22sl[] = {
+ 1098, -1107, -1125, -983, -770, -233, 201, 823,
+ -1433, -1294, -17, -1156, -301, 1185, 1307, 1108,
+ -1247, 1829, 1353, -537, -457, 116, 574, 712,
+ 159, -489, 511, -340, 54, 119, 213, 351,
+ -1489, -1256, -1324, -1132, 3710, 262, 1087, 1465,
+ -1434, -1027, -1116, 825, -662, -428, -109, 1045,
+ 229, 753, -604, -422, 122, -220, 279, 375,
+ -349, -684, -197, 490, -160, -116, -120, 146,
+ 5195, -895, -974, -758, -524, 21, 761, 1016,
+ -1216, 151, 864, -602, -715, -591, -347, 592,
+ -1265, -1328, -1375, -878, -660, -549, 143, 4302,
+ -1433, -1277, 360, -1032, -835, -385, 337, 1111,
+ -1345, -1250, -1156, 914, 1594, 22, 912, 1012,
+ -1576, -1411, -1364, -1153, 842, -184, 240, 1302,
+ -1486, -1162, 1246, -880, -830, 14, 2487, 1607,
+ -1384, -158, -572, -977, 43, -30, -184, 572,
+ 2759, -892, -768, -522, -289, -44, 351, 575,
+ -1292, -546, 3736, -609, -538, -25, 514, 924,
+ 1772, 1639, -903, -595, -263, 340, 579, 670,
+ -1425, 770, -1179, -920, -1158, -675, 496, 1208,
+ -1337, 1240, -1030, -1044, 1840, 312, 809, 908,
+ -1457, 1410, -1240, -1083, -541, 568, 2768, 1432,
+ -1249, -890, 1078, 1278, -558, 63, 573, 778,
+ -1285, 1932, -1004, -902, -339, 59, 17, 659,
+ -1352, -935, -877, 3421, -455, 160, 820, 1230,
+ -1326, -978, 986, -790, 1541, 41, 542, 743,
+ -1491, -1162, -1389, -1265, -928, -139, 5045, 2259,
+ -1182, 1358, -953, 1338, -502, 122, 749, 839,
+ -1284, 4389, -1001, -813, -421, 44, 855, 1072,
+ 1658, -881, -821, 1409, -299, 4, 453, 700,
+ -1144, -1112, 1230, -790, -421, 1250, -12, 655,
+ 1545, -872, 1199, -632, -365, 56, 415, 663,
+ -1401, -1189, -1403, -1189, -1145, -687, -116, 1120,
+ 1768, -1068, -1024, -629, 1440, 88, 578, 711,
+ -1651, -1561, -1564, -1430, -1037, 1264, -21, 1944,
+ -1552, -1336, -1277, 916, -412, 27, 2454, 1661,
+ 1996, -1087, -1223, -924, -393, 1673, 794, 1017,
+ -1362, -132, 151, 537, -992, 1830, 777, 991,
+ -1591, -1355, -1494, -1420, -666, 2407, 3210, 2092,
+ -1114, -624, -1087, -903, -808, -438, 1881, 654,
+ -1140, 254, -105, 212, 386, 49, 256, 314,
+ 83, 98, -1128, -901, -578, 362, 702, 691,
+ 1191, -204, -335, -226, -102, -44, -5, 120,
+ 57, -1110, -403, -651, -806, -202, 567, 690,
+ 349, -908, -1075, -941, 1487, 464, 763, 782,
+ 387, -1070, -990, -765, -295, 1669, 341, 881,
+ 232, -1013, -1043, 723, -311, 294, 646, 574,
+ 72, -1191, -546, -183, 493, 161, 201, 465,
+ -185, -1434, -1368, -1051, 64, 385, 748, 986,
+ -740, -530, -1199, -562, 142, 1388, 1487, 715,
+ -1359, 873, -1187, -923, -455, 1914, 403, 1016,
+ -1245, -1223, -624, -495, 724, 652, 433, 585,
+ -1499, -1277, -1381, -1148, 1679, 2138, 995, 1424,
+ -1345, -1319, -1296, 906, -228, 1534, 506, 1024,
+ -1628, -1410, -1422, -1197, 1393, -22, 2728, 1784,
+ -1245, -1056, -942, 2, -165, -115, 840, 569,
+ 1016, -1191, -1091, -862, -457, 95, 2087, 1029,
+ -1460, -1486, -1459, -1104, -571, 925, 1234, 935,
+ -1568, -49, -1325, -1255, -64, 315, 838, 962,
+ -1651, -1562, -1606, -1571, -1308, -380, 1988, 2117,
+ -848, -412, -987, -370, 1224, -304, 10, 498,
+ -1523, -1348, -1373, -959, -772, 3767, 621, 1773,
+ -931, -628, 169, -513, 61, -306, 994, 476,
+ -1116, -879, -875, -484, -795, 958, -162, 444,
+};
+
+static const int16_t fcb22ss[] = {
+ 6765, -638, -1108, -977, -679, -446, -325, -432,
+ -127, 96, -569, -621, -1050, -841, -800, 1474,
+ 1170, 60, 330, 223, -1317, 855, 307, -931,
+ -648, -549, -148, 535, 642, 445, 3666, -1146,
+ -1167, -944, -584, 942, -284, 25, 573, 472,
+ -1041, -1096, -1209, -1082, -770, -737, -139, 2073,
+ 753, 832, 507, -828, -1112, -1130, 4284, -722,
+ -261, -57, 499, 300, -1380, -1130, 135, -898,
+ -816, -395, 195, 453, 650, 537, -953, -1109,
+ -1221, -981, -747, -647, 2360, 467, 845, 684,
+ -1177, -792, -1254, -1148, 1344, -745, -323, 180,
+ 729, 739, -1020, 183, 5226, -638, -358, -86,
+ -268, -143, 84, -115, 480, -543, -1229, -1097,
+ -594, -983, -792, -391, 2637, 1405, -761, -866,
+ -1186, -973, -792, -640, -220, -102, 1165, 3159,
+ -1241, -1057, -1322, -1007, -731, 44, 264, 668,
+ 2645, 1592, 2885, -1155, -1347, -1209, -309, -1161,
+ 4216, -64, 830, 616, -688, -638, -596, 202,
+ -665, -623, -499, -248, 512, 749, -1395, -708,
+ -1086, 1209, -745, -367, 1397, 279, 374, 259,
+ -1357, -254, 2310, 1839, -147, 36, -402, 300,
+ -49, 47, -1328, -992, 3453, -889, -621, 135,
+ 437, 70, 663, 346, -1339, -1136, -1275, 6675,
+ -1309, 2285, -869, 1154, 640, 617, -505, -1042,
+ -984, -702, 1283, 1573, -168, 135, 249, 253,
+ -783, -1119, -1342, -975, -1127, 1391, -705, 4439,
+ 1160, 845, -1283, -1224, -1286, -1142, -1019, -901,
+ -658, -157, 231, 611, -994, -463, -1017, 1082,
+ 1831, -459, -164, 114, 0, 108, -1386, -1079,
+ -1318, -1091, 2540, -717, 762, 1414, 849, 576,
+ -1405, -566, 2704, -996, 2133, -678, 404, 281,
+ 4, -32, -1474, 3530, 2301, -711, -919, -305,
+ -125, 184, 450, 73, -1132, 1567, 1620, -551,
+ -198, -645, 19, 8, 190, 191, -741, -728,
+ 410, 1067, -322, -239, 86, 11, -137, -220,
+ -489, -607, -963, 3630, -624, -478, -12, 124,
+ 219, 63, 2040, 75, 1338, -293, -333, -336,
+ -330, -246, -360, -344, -953, -393, 1550, -701,
+ -616, -254, 1908, 211, 328, -43, -1089, -299,
+ 1070, -723, -923, 2170, -400, -13, -28, 108,
+ -812, -400, 876, -650, 1308, -772, -256, -200,
+ 117, 329, 649, -639, 437, -704, -567, -20,
+ -211, 197, 330, 342, 1670, -468, -920, -588,
+ 972, -310, 9, -46, 70, -29, -1313, 1684,
+ -794, -979, -752, 1864, -173, 108, 248, 292,
+ -1247, -1226, -1059, 288, -112, 189, 20, 540,
+ 454, 380, -1035, -803, 1267, -767, 746, 1331,
+ 107, 317, 158, -116, 2093, -723, -1064, -906,
+ -713, -789, -518, 48, 494, 1018, 1835, -1353,
+ -1303, -1098, -559, 800, 520, 662, 615, 574,
+ -1282, -526, 1829, -1086, -885, -356, -539, -50,
+ 493, 402, -777, -374, -754, 1721, -701, 2086,
+ -348, 218, 138, 109, -1367, -1226, -1041, 1949,
+ -433, -291, -363, 567, 613, 560, 1166, -481,
+ -737, 1193, -479, -163, -69, 2, 133, 239,
+ -1444, -1448, -1350, -987, -296, 606, 755, 543,
+ 741, 806, -851, 2437, 23, -681, -670, -271,
+ -439, -227, -243, -198, -1307, 424, -1212, -987,
+ -745, -369, 162, 641, 915, 611, -24, -728,
+ -1061, -659, 808, -532, 1241, -233, 266, 353,
+ 175, 210, -262, -328, 101, -238, 66, -339,
+ -472, -415, 952, -1490, -1302, -955, -1270, 5776,
+ -792, 777, 1097, 807, -1334, -1172, -1211, -924,
+ -877, 2458, -355, 593, 936, 699, -336, -700,
+ -762, -569, -337, 642, 97, 441, -188, -533,
+ -1062, 188, -873, -801, 418, -167, -57, -29,
+ 79, 241, -1110, 6430, -816, -807, -462, -601,
+ -56, -45, 188, 74, 2869, 43, -1122, -799,
+ -772, -847, 1394, -36, 294, 13, -1304, 2155,
+ -534, 1545, -315, -325, 183, 31, 372, 187,
+ 873, 1376, -1037, -810, -516, -235, 485, 99,
+ 287, 327, -1074, 1203, -1089, -882, -515, -544,
+ 2041, -40, 208, 191, 597, -1141, -1274, -885,
+ -386, 106, 593, 394, 671, 678, -1292, 3861,
+ -1085, -1150, -748, -218, 500, 55, 335, 469,
+ 3217, 2888, -882, -643, -590, -506, 43, -459,
+ -210, -222, -965, 2453, -830, -779, 1808, -588,
+ 130, 4, 130, -23, -1269, 1374, -1238, -1148,
+ -523, -659, -170, -302, 1055, 1389, -1467, 2505,
+ -930, -1181, -842, -516, 399, 886, 849, 738,
+};
+
+static const int16_t fcb22sm[] = {
+ 5761, -398, -743, -948, -944, -845, -883, -896,
+ -811, -604, -1142, -1388, -1190, -685, -118, 1498,
+ 1590, 293, 564, 352, 124, 851, -131, -652,
+ -573, -279, -756, -478, 833, 670, 2609, -1138,
+ -1107, -1024, -739, -646, -387, 33, 635, 1037,
+ -717, -990, -1161, -948, -660, -230, 69, 2510,
+ 1274, 841, -49, -872, -764, -211, 3046, -30,
+ -143, -311, -324, -413, -760, 67, 619, -699,
+ -725, 305, -484, 1292, 472, -156, -568, -1243,
+ -1256, -994, -803, -386, 1692, 596, 1325, 1290,
+ -492, -1007, -732, -788, 1136, -610, 45, 1307,
+ 420, 649, -534, -1075, -949, -367, 219, 444,
+ -120, 251, 476, 1806, 902, -927, -1151, -879,
+ -659, -741, -5, 298, 1861, 995, -244, -1031,
+ -1142, -1085, -952, -773, -468, -9, 1637, 3592,
+ -971, -1150, -1199, -985, -689, -317, 150, 540,
+ 2727, 1678, -223, -403, 102, -902, -773, -223,
+ 3182, -457, 75, -188, -291, -428, -101, -365,
+ -442, -336, -128, -33, 781, 1242, 501, -753,
+ -846, 757, -444, -311, 1182, 4, -8, -122,
+ 1866, -528, -142, 1598, -15, -219, -557, -804,
+ -916, -965, 114, 130, 3672, -19, -873, -280,
+ -777, -919, -824, -654, 1078, 39, -50, 119,
+ -411, -311, -359, -57, -137, 7, -780, -892,
+ -767, -167, 1302, 1693, -205, -51, -174, -71,
+ 838, -220, -1133, -993, -710, -340, 650, 1341,
+ 191, -5, 743, -543, -125, -567, 70, -42,
+ -501, -448, 47, 1151, 400, -774, -781, 1324,
+ 1089, 32, -256, -415, -352, -214, 912, -1141,
+ -988, -638, 1349, 251, 124, -4, 89, -16,
+ -678, -569, 1502, 146, 114, 816, -98, -269,
+ -622, -808, -634, 3319, 1218, -323, -750, -548,
+ -525, -575, -591, -730, 35, 764, 1423, 574,
+ -352, -672, -802, -314, -308, -29, -1040, -717,
+ 469, 421, -527, -420, 589, 195, 556, 472,
+ -626, -864, -133, 3531, -667, -460, -523, 103,
+ 23, -309, 2381, 136, 1197, -399, -399, -501,
+ -638, -899, -813, -707, -249, 719, 821, -989,
+ -629, -568, 642, -4, 297, 70, -1105, 454,
+ 400, -235, -562, 1607, -116, -205, 1, -490,
+ 7, -523, 764, 329, 992, -240, -249, -275,
+ -366, -265, 662, -803, 393, -567, -501, -32,
+ 178, 371, 126, -146, 1748, -516, -634, -395,
+ 268, 893, 154, -36, -620, -999, 304, 1490,
+ -512, -821, -479, 1922, -610, -481, -482, -805,
+ -996, -16, -567, 542, -22, 589, -114, 69,
+ 322, 358, -848, 1205, 509, -527, 25, 111,
+ -243, -197, -20, 62, 1500, -977, -974, -391,
+ -555, 448, -256, 79, 392, 547, 1472, -1276,
+ -1203, -987, -315, 515, 855, 183, 231, 62,
+ -1176, -397, 2831, -527, -575, -435, 174, -337,
+ 723, 107, -502, -765, -455, 1124, -218, 1444,
+ 53, -201, -135, -267, -510, -1058, -869, 1130,
+ -128, -394, 16, 873, 597, 455, 16, 0,
+ -11, 14, -12, 9, 6, -14, -11, -23,
+ -453, -1056, -988, -713, -267, 794, 954, 1361,
+ 822, -448, 379, 1163, 336, -724, 55, 109,
+ 237, -80, -732, -1017, -264, 654, -1043, -1015,
+ -654, 91, 17, 548, 504, 932, -1057, -1151,
+ -964, -130, 1171, -146, 740, 134, 790, 539,
+ -591, -577, -388, 154, 609, 341, 657, 838,
+ -379, -872, 711, -665, -818, -549, -151, 2501,
+ -28, -189, -255, -378, -363, -1157, -929, -887,
+ -338, 1926, -33, -26, 1009, 765, -79, -98,
+ -37, -967, -566, 1012, 905, -245, 41, 322,
+ 194, -148, -220, -171, -239, -242, -147, -14,
+ 221, 575, 1754, 3059, -246, -713, -696, -636,
+ -640, -843, -841, -755, 2554, -504, -568, -318,
+ -324, -171, -294, -238, -288, -174, -289, 1273,
+ -231, 1053, -284, -338, -394, -227, -303, -226,
+ 966, 742, -873, -503, -586, -286, 119, -59,
+ 339, -38, -843, 977, -448, -238, 227, -77,
+ 729, 6, 45, -493, 277, -1385, -1289, -846,
+ -117, 376, 763, 553, 769, 670, -652, 3280,
+ -762, -882, -396, -299, 124, -270, -31, -210,
+ 2413, 644, -790, -912, -581, -507, -110, -408,
+ -54, -30, 632, 969, -632, -206, 955, -95,
+ -578, -337, -377, -467, 1264, 67, -854, -863,
+ -909, -751, -616, -479, 563, 2070, -972, 1478,
+ -450, -715, -859, -689, 190, 736, 617, 530,
};
static const int16_t fcb44sl[] = {
@@ -4055,7 +12165,407 @@
0.0482, 0.1174, 0.1270, 0.0594, 0.0165, 0.0949, 0.1098, 0.0137,
0.4951, 0.4999, 0.4958, 0.4907, 0.4984, 0.4965, 0.4958, 0.4996,
0.4987, 0.4958, 0.4986, 0.4977, 0.2841, 0.2186, 0.1474, 0.1687,
- 0.2217, 0.2632, 0.2706, 0.2624, 0.2162, 0.2453, 0.2460, 0.2531
+ 0.2217, 0.2632, 0.2706, 0.2624, 0.2162, 0.2453, 0.2460, 0.2531,
+};
+
+static const float lsp8s[] = {
+ 0.2702, 0.5096, 0.6437, 0.7672, 0.9639, 1.0696, 1.2625, 1.5789,
+ 1.9285, 2.2383, 2.5129, 2.8470, 0.1740, 0.3677, 0.6082, 0.8387,
+ 1.1084, 1.3721, 1.6362, 1.8733, 2.0640, 2.3442, 2.6087, 2.8548,
+ 0.1536, 0.3279, 0.5143, 0.6859, 0.9763, 1.2744, 1.5605, 1.8566,
+ 2.1007, 2.3450, 2.6075, 2.8850, 0.2075, 0.4533, 0.7709, 1.0377,
+ 1.2953, 1.5132, 1.7826, 2.0351, 2.2590, 2.4996, 2.6795, 2.8748,
+ 0.1393, 0.2453, 0.3754, 0.5453, 0.8148, 1.1289, 1.4389, 1.7592,
+ 2.0353, 2.3215, 2.5934, 2.8588, 0.1250, 0.3627, 0.7613, 1.1380,
+ 1.4163, 1.5565, 1.6920, 1.8130, 1.8678, 2.0427, 2.4318, 2.8544,
+ 0.2256, 0.4223, 0.6452, 0.8599, 1.0673, 1.3118, 1.5486, 1.8366,
+ 2.0759, 2.3026, 2.5284, 2.8030, 0.2304, 0.4404, 0.6891, 0.8964,
+ 1.1510, 1.4202, 1.6483, 1.8580, 2.1181, 2.3686, 2.6078, 2.9128,
+ 0.2230, 0.3816, 0.5520, 0.6062, 0.7909, 1.0988, 1.4330, 1.7846,
+ 2.0713, 2.3457, 2.6048, 2.8708, 0.2447, 0.5800, 0.8249, 0.9905,
+ 1.1721, 1.3990, 1.6694, 1.9064, 2.1307, 2.4255, 2.6815, 2.9117,
+ 0.1974, 0.3812, 0.5802, 0.7759, 0.9280, 1.1547, 1.4170, 1.6369,
+ 1.8890, 2.2587, 2.5626, 2.8239, 0.1209, 0.2510, 0.4841, 0.8048,
+ 1.1197, 1.3563, 1.6073, 1.8926, 2.1350, 2.3669, 2.6291, 2.8985,
+ 0.2352, 0.4347, 0.6582, 0.8178, 0.9548, 1.1654, 1.4942, 1.8812,
+ 2.1703, 2.3779, 2.6412, 2.8871, 0.2091, 0.4084, 0.6730, 0.9151,
+ 1.1259, 1.3262, 1.5937, 1.8129, 2.0237, 2.3317, 2.5778, 2.8620,
+ 0.1167, 0.2406, 0.4520, 0.7298, 0.9848, 1.2448, 1.5137, 1.7874,
+ 2.0280, 2.3020, 2.5914, 2.8794, 0.3003, 0.4966, 0.6520, 0.8505,
+ 1.1600, 1.3981, 1.5805, 1.8346, 2.0757, 2.3102, 2.5760, 2.8499,
+ 0.2451, 0.4163, 0.5960, 0.7805, 0.9507, 1.2438, 1.5587, 1.8581,
+ 2.0735, 2.3198, 2.5704, 2.8220, 0.3112, 0.5517, 0.7032, 0.8528,
+ 1.1489, 1.4257, 1.6848, 1.9388, 2.1577, 2.4265, 2.6678, 2.9051,
+ 0.2249, 0.3897, 0.5559, 0.7473, 1.0158, 1.3581, 1.6914, 1.9930,
+ 2.1843, 2.3534, 2.5512, 2.8065, 0.2600, 0.4574, 0.7349, 0.9691,
+ 1.1696, 1.3848, 1.6335, 1.9021, 2.1174, 2.3481, 2.5902, 2.8390,
+ 0.2246, 0.3372, 0.4560, 0.5249, 0.7056, 1.0273, 1.3810, 1.7132,
+ 1.9819, 2.2574, 2.5410, 2.8491, 0.1419, 0.4834, 0.8835, 1.1453,
+ 1.2839, 1.4224, 1.5593, 1.7877, 2.1285, 2.4070, 2.6043, 2.8511,
+ 0.1886, 0.3677, 0.5617, 0.8099, 1.1277, 1.3841, 1.5804, 1.8136,
+ 2.0307, 2.2805, 2.5399, 2.8322, 0.2351, 0.4151, 0.6675, 0.8713,
+ 1.0464, 1.3292, 1.6586, 1.9281, 2.1355, 2.3495, 2.6222, 2.8782,
+ 0.2700, 0.4489, 0.6206, 0.7121, 0.7737, 0.9848, 1.3658, 1.7433,
+ 2.0139, 2.2243, 2.4806, 2.8175, 0.2479, 0.4425, 0.6490, 0.8745,
+ 1.1161, 1.3849, 1.6773, 1.9566, 2.1491, 2.3624, 2.5685, 2.8114,
+ 0.2035, 0.3701, 0.5567, 0.7953, 1.0082, 1.2758, 1.5373, 1.7822,
+ 2.0175, 2.2601, 2.4759, 2.7771, 0.1856, 0.3461, 0.5998, 0.9041,
+ 1.2383, 1.4612, 1.6667, 1.9305, 2.1617, 2.4107, 2.6477, 2.8656,
+ 0.2107, 0.3715, 0.5289, 0.6651, 0.8420, 1.1168, 1.4401, 1.7230,
+ 1.9901, 2.2687, 2.5452, 2.8655, 0.1218, 0.2999, 0.6348, 0.9482,
+ 1.2745, 1.5876, 1.9129, 2.2348, 2.4020, 2.4922, 2.6351, 2.8357,
+ 0.1617, 0.3483, 0.5869, 0.8163, 1.0366, 1.2344, 1.4609, 1.7029,
+ 1.9476, 2.2337, 2.5258, 2.8442, 0.2505, 0.4894, 0.7510, 0.9152,
+ 1.0845, 1.3657, 1.6528, 1.8346, 2.0160, 2.2811, 2.5338, 2.8136,
+ 0.0947, 0.1158, 0.0578, -0.0337, -0.0066, 0.0104, -0.0447, -0.0505,
+ -0.0778, -0.0293, 0.0251, -0.0143, 0.0349, -0.0227, -0.0909, 0.0523,
+ 0.0325, -0.0410, -0.1045, -0.0899, -0.0009, 0.0075, -0.0575, -0.0855,
+ -0.0129, 0.0575, 0.0597, 0.0391, 0.0371, -0.0184, -0.0083, 0.0287,
+ 0.0143, 0.0167, 0.0120, -0.0168, 0.0452, 0.0223, -0.0352, 0.0119,
+ -0.0496, -0.0965, -0.0661, -0.0072, 0.1099, 0.0843, -0.0087, -0.0478,
+ -0.0128, -0.0120, -0.0004, 0.0731, 0.1047, 0.0630, 0.0196, -0.0103,
+ -0.0399, -0.0986, -0.0912, -0.0390, -0.0247, -0.0694, -0.0749, -0.0066,
+ 0.0223, 0.0634, 0.0343, -0.0134, 0.0727, 0.0241, 0.0066, 0.0437,
+ 0.0610, 0.0364, 0.0248, -0.0358, -0.0686, -0.0104, 0.0426, 0.0088,
+ -0.0137, -0.0165, 0.0671, 0.0815, -0.0863, -0.0644, -0.0088, 0.0023,
+ 0.0482, 0.1174, 0.1270, 0.0594, 0.0165, 0.0949, 0.1098, 0.0137,
+ 0.4951, 0.4999, 0.4958, 0.4907, 0.4984, 0.4965, 0.4958, 0.4996,
+ 0.4987, 0.4958, 0.4986, 0.4977, 0.2841, 0.2186, 0.1474, 0.1687,
+ 0.2217, 0.2632, 0.2706, 0.2624, 0.2162, 0.2453, 0.2460, 0.2531,
+};
+
+static const float lsp11[] = {
+ 0.1103, 0.3862, 0.6863, 0.8447, 0.9231, 1.0261, 1.1248, 1.4057,
+ 1.6621, 1.8010, 1.8692, 2.0704, 2.3490, 2.6060, 2.7539, 2.8977,
+ 0.1273, 0.2407, 0.3812, 0.6004, 0.7767, 0.9383, 1.1344, 1.3351,
+ 1.5233, 1.7262, 1.9466, 2.1739, 2.3495, 2.5162, 2.7164, 2.9202,
+ 0.2010, 0.3330, 0.4488, 0.6465, 0.8046, 0.9889, 1.1479, 1.2964,
+ 1.4770, 1.6606, 1.8789, 2.1155, 2.3287, 2.5199, 2.7101, 2.9119,
+ 0.1168, 0.2197, 0.3279, 0.4691, 0.6268, 0.8251, 1.0533, 1.2714,
+ 1.4712, 1.6762, 1.8831, 2.1114, 2.3230, 2.5297, 2.7365, 2.9270,
+ 0.1405, 0.3109, 0.4986, 0.6891, 0.8634, 1.0583, 1.2594, 1.4349,
+ 1.6232, 1.8116, 1.9905, 2.1935, 2.3799, 2.5656, 2.7661, 2.9486,
+ 0.1703, 0.3057, 0.4403, 0.5225, 0.5969, 0.8110, 1.0729, 1.3215,
+ 1.5407, 1.7381, 1.9477, 2.1680, 2.3586, 2.5612, 2.7630, 2.9410,
+ 0.1128, 0.2628, 0.4523, 0.6495, 0.8176, 0.9816, 1.1746, 1.3710,
+ 1.5568, 1.7518, 1.9497, 2.1452, 2.3346, 2.5389, 2.7362, 2.9264,
+ 0.1809, 0.3287, 0.5205, 0.7264, 0.9298, 1.1217, 1.2970, 1.4894,
+ 1.6874, 1.8493, 2.0576, 2.2382, 2.4097, 2.6041, 2.7796, 2.9389,
+ 0.2502, 0.4709, 0.6892, 0.8346, 0.9209, 1.0455, 1.2399, 1.4616,
+ 1.6463, 1.8380, 2.0475, 2.2397, 2.4665, 2.6550, 2.7701, 2.8895,
+ 0.1040, 0.2340, 0.3964, 0.5740, 0.7764, 0.9941, 1.2000, 1.4014,
+ 1.6024, 1.7974, 1.9939, 2.1959, 2.3783, 2.5663, 2.7613, 2.9484,
+ 0.1912, 0.3393, 0.4743, 0.6313, 0.8014, 0.9879, 1.1855, 1.3922,
+ 1.5678, 1.7289, 1.9271, 2.1165, 2.3089, 2.5414, 2.7448, 2.9269,
+ 0.0965, 0.2025, 0.3398, 0.4990, 0.6934, 0.9386, 1.1730, 1.3766,
+ 1.5783, 1.7783, 1.9790, 2.1831, 2.3670, 2.5578, 2.7641, 2.9516,
+ 0.2126, 0.3652, 0.5545, 0.7170, 0.8674, 1.0640, 1.2558, 1.4061,
+ 1.5904, 1.8095, 1.9760, 2.1505, 2.3549, 2.5575, 2.7023, 2.8877,
+ 0.1827, 0.3426, 0.4894, 0.6488, 0.7960, 0.9535, 1.1217, 1.2798,
+ 1.4566, 1.6453, 1.8044, 2.0042, 2.2379, 2.4611, 2.6697, 2.8966,
+ 0.2034, 0.3822, 0.5231, 0.6960, 0.9200, 1.0394, 1.1616, 1.3772,
+ 1.5493, 1.7330, 1.9646, 2.1233, 2.3334, 2.5361, 2.7087, 2.9470,
+ 0.1050, 0.2060, 0.3705, 0.5998, 0.8337, 1.0577, 1.2559, 1.4327,
+ 1.6334, 1.8165, 1.9853, 2.2058, 2.4063, 2.5818, 2.7625, 2.9458,
+ 0.1419, 0.4053, 0.6660, 0.8911, 1.0405, 1.1547, 1.2506, 1.3926,
+ 1.5669, 1.7527, 1.9694, 2.2054, 2.3889, 2.5743, 2.7586, 2.9174,
+ 0.1514, 0.2825, 0.4309, 0.5772, 0.7470, 0.9703, 1.1462, 1.3316,
+ 1.5321, 1.7259, 1.9282, 2.1266, 2.3106, 2.5064, 2.7067, 2.9094,
+ 0.1693, 0.3156, 0.4878, 0.6635, 0.8206, 0.9569, 1.1154, 1.3064,
+ 1.5109, 1.7184, 1.9179, 2.1036, 2.2763, 2.4820, 2.6949, 2.9105,
+ 0.1432, 0.2718, 0.4241, 0.5564, 0.6939, 0.9011, 1.1582, 1.3948,
+ 1.6181, 1.8024, 1.9814, 2.1740, 2.3459, 2.5456, 2.7491, 2.9307,
+ 0.2294, 0.3857, 0.5590, 0.7434, 0.9189, 1.0941, 1.2740, 1.4456,
+ 1.6178, 1.7994, 1.9689, 2.1644, 2.3525, 2.5385, 2.7468, 2.9405,
+ 0.1667, 0.3109, 0.4612, 0.6032, 0.7375, 0.8866, 1.0840, 1.3053,
+ 1.4982, 1.7044, 1.9146, 2.1117, 2.2942, 2.4983, 2.7084, 2.9132,
+ 0.1810, 0.3205, 0.4696, 0.6231, 0.7641, 0.9959, 1.2427, 1.4361,
+ 1.5889, 1.7544, 1.9083, 2.0733, 2.2457, 2.4461, 2.6793, 2.9098,
+ 0.1164, 0.3753, 0.6068, 0.7503, 1.0100, 1.2131, 1.3793, 1.5302,
+ 1.6300, 1.7950, 1.9057, 2.1031, 2.3830, 2.5745, 2.6949, 2.8779,
+ 0.1571, 0.4378, 0.6735, 0.8312, 0.8944, 0.9818, 1.1622, 1.4094,
+ 1.6423, 1.8066, 1.9258, 2.1838, 2.4363, 2.6279, 2.7358, 2.8790,
+ 0.1398, 0.2686, 0.4248, 0.6156, 0.7870, 1.0035, 1.2012, 1.3689,
+ 1.5363, 1.7398, 1.9604, 2.1619, 2.3345, 2.5097, 2.7271, 2.9368,
+ 0.1913, 0.3338, 0.4987, 0.6446, 0.7852, 1.0163, 1.1886, 1.3610,
+ 1.5379, 1.7230, 1.8880, 2.0862, 2.2960, 2.4928, 2.7122, 2.9151,
+ 0.0908, 0.1752, 0.2899, 0.5365, 0.7761, 1.0100, 1.2124, 1.4060,
+ 1.6019, 1.8010, 1.9774, 2.1905, 2.3733, 2.5623, 2.7660, 2.9565,
+ 0.1773, 0.3179, 0.4925, 0.6864, 0.8452, 0.9897, 1.1860, 1.3722,
+ 1.5515, 1.7658, 1.9802, 2.1819, 2.3620, 2.5442, 2.7250, 2.9220,
+ 0.1286, 0.2341, 0.3689, 0.5364, 0.7176, 0.9350, 1.1083, 1.2943,
+ 1.4974, 1.7059, 1.9047, 2.1145, 2.3242, 2.5361, 2.7453, 2.9329,
+ 0.2273, 0.3834, 0.5565, 0.7192, 0.8431, 0.9962, 1.1763, 1.3571,
+ 1.5774, 1.7419, 1.9202, 2.1131, 2.2919, 2.4898, 2.6895, 2.9180,
+ 0.1775, 0.3058, 0.4274, 0.6023, 0.8151, 1.0734, 1.3211, 1.5178,
+ 1.6706, 1.8154, 1.9686, 2.1537, 2.3461, 2.5276, 2.7181, 2.9121,
+ 0.1653, 0.4304, 0.6361, 0.7824, 0.9183, 1.0452, 1.2071, 1.4077,
+ 1.6206, 1.8299, 2.0089, 2.1948, 2.3900, 2.5982, 2.7844, 2.9487,
+ 0.1492, 0.2609, 0.3820, 0.5485, 0.7243, 0.9319, 1.1538, 1.3579,
+ 1.5266, 1.7002, 1.8873, 2.1016, 2.3175, 2.5221, 2.7241, 2.9243,
+ 0.2074, 0.3781, 0.5209, 0.6869, 0.8577, 0.9875, 1.1849, 1.3568,
+ 1.4907, 1.7335, 1.8902, 2.1224, 2.3099, 2.4918, 2.7023, 2.8765,
+ 0.1359, 0.2254, 0.3286, 0.4432, 0.6586, 0.8964, 1.1125, 1.3523,
+ 1.5626, 1.7579, 1.9846, 2.1905, 2.3548, 2.5542, 2.7663, 2.9346,
+ 0.1430, 0.2966, 0.4685, 0.6493, 0.8315, 1.0304, 1.2220, 1.4082,
+ 1.5995, 1.7888, 1.9774, 2.1737, 2.3607, 2.5577, 2.7558, 2.9405,
+ 0.1477, 0.2694, 0.4056, 0.5626, 0.7051, 0.8647, 1.0491, 1.2488,
+ 1.4814, 1.7072, 1.9150, 2.1147, 2.3038, 2.5144, 2.7184, 2.9202,
+ 0.1690, 0.3033, 0.4580, 0.6686, 0.8536, 1.0293, 1.2124, 1.3998,
+ 1.5718, 1.7607, 1.9580, 2.1245, 2.2971, 2.4762, 2.6896, 2.9177,
+ 0.1092, 0.2779, 0.4853, 0.6880, 0.9011, 1.0953, 1.2752, 1.4618,
+ 1.6623, 1.8484, 2.0264, 2.2152, 2.4017, 2.5835, 2.7671, 2.9436,
+ 0.1497, 0.3637, 0.6014, 0.8032, 0.9963, 1.1835, 1.3741, 1.5698,
+ 1.7382, 1.9094, 2.0710, 2.2392, 2.4082, 2.5926, 2.7762, 2.9536,
+ 0.1434, 0.2492, 0.3966, 0.5934, 0.8033, 1.0657, 1.2796, 1.4276,
+ 1.5745, 1.7833, 1.9288, 2.1247, 2.3543, 2.5412, 2.7049, 2.8872,
+ 0.1612, 0.2926, 0.4574, 0.6387, 0.8265, 1.0180, 1.1808, 1.3526,
+ 1.5564, 1.7536, 1.9187, 2.1192, 2.3149, 2.5006, 2.7101, 2.9217,
+ 0.0828, 0.1863, 0.3235, 0.5050, 0.7250, 0.9867, 1.2093, 1.3941,
+ 1.5980, 1.7932, 1.9809, 2.1894, 2.3918, 2.5773, 2.7540, 2.9329,
+ 0.2001, 0.3655, 0.5290, 0.6761, 0.8027, 0.9972, 1.2090, 1.4255,
+ 1.6085, 1.7825, 1.9804, 2.1681, 2.3457, 2.5325, 2.7319, 2.9196,
+ 0.1505, 0.2767, 0.4254, 0.6054, 0.7821, 0.9567, 1.1294, 1.3080,
+ 1.4984, 1.6954, 1.8666, 2.0736, 2.2875, 2.4969, 2.7072, 2.9163,
+ 0.1589, 0.4151, 0.5749, 0.6651, 0.8061, 1.0470, 1.2616, 1.3690,
+ 1.4985, 1.7808, 1.9825, 2.1068, 2.2751, 2.5448, 2.7133, 2.8689,
+ 0.0916, 0.1846, 0.3788, 0.6329, 0.8774, 1.0687, 1.2653, 1.4561,
+ 1.6573, 1.8449, 2.0402, 2.2254, 2.3968, 2.5861, 2.7792, 2.9508,
+ 0.2282, 0.4159, 0.5834, 0.6899, 0.8108, 1.0321, 1.2795, 1.5262,
+ 1.6936, 1.8469, 2.0922, 2.2607, 2.3795, 2.5301, 2.7386, 2.9530,
+ 0.1651, 0.3004, 0.4555, 0.6179, 0.7891, 0.9584, 1.1372, 1.3707,
+ 1.5951, 1.7880, 1.9434, 2.1465, 2.3311, 2.5081, 2.6977, 2.8970,
+ 0.1279, 0.3828, 0.6330, 0.8323, 0.9652, 1.1175, 1.2319, 1.3511,
+ 1.5115, 1.6392, 1.7835, 1.9558, 2.2008, 2.4635, 2.6910, 2.9058,
+ 0.1193, 0.2185, 0.3521, 0.5311, 0.7378, 0.9239, 1.1105, 1.3217,
+ 1.5362, 1.7504, 1.9536, 2.1627, 2.3560, 2.5506, 2.7548, 2.9453,
+ 0.1806, 0.3432, 0.4981, 0.6948, 0.8928, 1.0527, 1.2467, 1.4140,
+ 1.6326, 1.7950, 1.9935, 2.1969, 2.3512, 2.5682, 2.7445, 2.9277,
+ 0.1846, 0.3112, 0.4568, 0.5891, 0.7317, 0.8493, 1.0204, 1.2022,
+ 1.3688, 1.6020, 1.8428, 2.0710, 2.2725, 2.4879, 2.7057, 2.9160,
+ 0.0880, 0.2514, 0.5332, 0.7272, 0.8906, 1.1354, 1.3199, 1.4941,
+ 1.6010, 1.7151, 1.8712, 2.0643, 2.2755, 2.5375, 2.7054, 2.8891,
+ 0.1382, 0.2833, 0.4658, 0.6897, 0.9071, 1.0716, 1.2469, 1.4143,
+ 1.5910, 1.7947, 1.9805, 2.1581, 2.3338, 2.5215, 2.7292, 2.9211,
+ 0.1061, 0.3494, 0.6327, 0.8570, 0.9748, 1.0560, 1.1529, 1.3250,
+ 1.6032, 1.8340, 1.9711, 2.1157, 2.3011, 2.5464, 2.8078, 2.9803,
+ 0.1603, 0.2839, 0.4307, 0.5980, 0.7980, 1.0399, 1.1971, 1.3524,
+ 1.5715, 1.7838, 1.9468, 2.1498, 2.3627, 2.5514, 2.7327, 2.9148,
+ 0.1691, 0.3117, 0.4796, 0.6895, 0.8732, 1.0164, 1.1916, 1.3707,
+ 1.5384, 1.7202, 1.8857, 2.0672, 2.2487, 2.4593, 2.6789, 2.8940,
+ 0.0965, 0.1702, 0.3191, 0.5721, 0.8100, 1.0241, 1.2272, 1.4196,
+ 1.6093, 1.8057, 1.9884, 2.2037, 2.3925, 2.5805, 2.7578, 2.9366,
+ 0.1950, 0.3519, 0.5272, 0.6973, 0.8732, 1.0656, 1.2112, 1.3959,
+ 1.6116, 1.7821, 1.9445, 2.1592, 2.3348, 2.5142, 2.7440, 2.9297,
+ 0.1388, 0.2557, 0.4120, 0.5727, 0.7354, 0.9196, 1.0985, 1.2805,
+ 1.4643, 1.6535, 1.8340, 2.0546, 2.2758, 2.4778, 2.6921, 2.9122,
+ 0.1823, 0.3336, 0.4957, 0.6771, 0.8563, 1.0137, 1.2299, 1.3849,
+ 1.5718, 1.7667, 1.9193, 2.1326, 2.3135, 2.5268, 2.7133, 2.8998,
+ 0.0790, 0.1901, 0.4083, 0.6456, 0.8463, 1.0285, 1.2297, 1.4181,
+ 1.6159, 1.8056, 1.9971, 2.1912, 2.3816, 2.5746, 2.7692, 2.9497,
+ 0.0049, 0.0116, 0.0045, 0.0039, -0.0010, -0.0122, -0.0205, -0.0034,
+ -0.0140, -0.0041, 0.0191, -0.0322, 0.0002, -0.0124, -0.0269, 0.0059,
+ 0.0586, 0.0339, -0.0389, -0.0319, -0.0079, -0.0205, -0.0363, -0.0211,
+ 0.0241, 0.0595, 0.0469, 0.0283, 0.0176, -0.0183, -0.0173, -0.0004,
+ 0.0024, 0.0145, 0.0534, 0.0197, -0.0065, -0.0067, 0.0133, 0.0358,
+ -0.0104, -0.0386, -0.0109, -0.0078, 0.0275, 0.0565, 0.0251, -0.0027,
+ -0.0053, 0.0171, 0.0088, 0.0495, 0.0141, 0.0039, -0.0445, -0.0426,
+ -0.0184, -0.0280, -0.0223, 0.0039, -0.0171, -0.0606, -0.0786, -0.0430,
+ 0.0544, 0.0595, 0.0320, -0.0012, 0.0108, 0.0185, 0.0066, 0.0408,
+ 0.0552, -0.0073, -0.0247, -0.0480, -0.0288, 0.0186, 0.0212, -0.0013,
+ 0.0403, 0.0598, 0.0690, 0.0516, -0.0298, -0.0177, 0.0278, 0.0168,
+ -0.0106, 0.0251, 0.0386, 0.0331, -0.0052, 0.0133, 0.0291, -0.0158,
+ -0.0329, -0.0367, 0.0287, 0.0462, -0.0176, 0.0049, 0.0242, -0.0034,
+ 0.0135, 0.0086, -0.0149, 0.0241, 0.0504, 0.0246, -0.0273, -0.0369,
+ -0.0108, -0.0449, -0.0625, -0.0414, -0.0292, -0.0571, -0.0440, -0.0088,
+ 0.0098, 0.0009, -0.0004, 0.0007, -0.0314, -0.0208, -0.0138, -0.0277,
+ -0.0044, 0.0522, 0.0315, -0.0270, -0.0277, -0.0256, -0.0103, -0.0201,
+ -0.0287, -0.0279, -0.0182, 0.0472, 0.0613, 0.0450, 0.0413, 0.0333,
+ 0.0444, 0.0223, 0.0061, 0.0316, 0.0321, 0.0501, 0.0460, 0.0250,
+ 0.0227, 0.0235, 0.0099, 0.0185, -0.0347, -0.0684, -0.0189, 0.0242,
+ -0.0190, -0.0273, -0.0012, -0.0253, 0.0293, -0.0231, -0.0219, -0.0010,
+ 0.0153, 0.0128, -0.0166, -0.0435, -0.0417, -0.0121, -0.0351, -0.0390,
+ 0.0077, -0.0278, -0.0355, 0.0092, -0.0063, 0.0005, 0.0216, 0.0461,
+ 0.0538, 0.0451, 0.0298, -0.0130, 0.0058, 0.0206, 0.0471, 0.0499,
+ 0.0280, 0.0086, -0.0007, -0.0317, 0.0259, 0.0176, 0.0043, 0.0212,
+ 0.0138, 0.0106, 0.0220, -0.0025, 0.0050, 0.0122, -0.0051, -0.0086,
+ -0.0472, -0.0005, 0.0193, 0.0032, 0.0246, 0.0222, 0.0090, -0.0320,
+ -0.0713, -0.0526, -0.0151, -0.0440, -0.0648, -0.0466, -0.0092, 0.0115,
+ -0.0129, 0.0053, -0.0344, -0.0385, 0.0392, 0.0599, 0.0414, 0.0165,
+ -0.0098, -0.0320, -0.0261, -0.0055, -0.0139, -0.0110, 0.0084, 0.0172,
+ -0.0492, -0.0537, -0.0320, -0.0036, 0.0265, 0.0385, 0.0064, -0.0280,
+ -0.0230, 0.0134, 0.0241, 0.0106, 0.0387, 0.0105, 0.0068, 0.0260,
+ 0.4940, 0.4911, 0.4849, 0.4820, 0.4837, 0.4839, 0.4824, 0.4799,
+ 0.4812, 0.4782, 0.4788, 0.4711, 0.4706, 0.4671, 0.4601, 0.4578,
+ 0.2954, 0.2121, 0.1859, 0.1958, 0.1474, 0.1086, 0.1351, 0.1362,
+ 0.1486, 0.1342, 0.1215, 0.1423, 0.1634, 0.1588, 0.1539, 0.1857,
+};
+
+static const float lsp11s[] = {
+ 0.1103, 0.3862, 0.6863, 0.8447, 0.9231, 1.0261, 1.1248, 1.4057,
+ 1.6621, 1.8010, 1.8692, 2.0704, 2.3490, 2.6060, 2.7539, 2.8977,
+ 0.1273, 0.2407, 0.3812, 0.6004, 0.7767, 0.9383, 1.1344, 1.3351,
+ 1.5233, 1.7262, 1.9466, 2.1739, 2.3495, 2.5162, 2.7164, 2.9202,
+ 0.2010, 0.3330, 0.4488, 0.6465, 0.8046, 0.9889, 1.1479, 1.2964,
+ 1.4770, 1.6606, 1.8789, 2.1155, 2.3287, 2.5199, 2.7101, 2.9119,
+ 0.1168, 0.2197, 0.3279, 0.4691, 0.6268, 0.8251, 1.0533, 1.2714,
+ 1.4712, 1.6762, 1.8831, 2.1114, 2.3230, 2.5297, 2.7365, 2.9270,
+ 0.1405, 0.3109, 0.4986, 0.6891, 0.8634, 1.0583, 1.2594, 1.4349,
+ 1.6232, 1.8116, 1.9905, 2.1935, 2.3799, 2.5656, 2.7661, 2.9486,
+ 0.1703, 0.3057, 0.4403, 0.5225, 0.5969, 0.8110, 1.0729, 1.3215,
+ 1.5407, 1.7381, 1.9477, 2.1680, 2.3586, 2.5612, 2.7630, 2.9410,
+ 0.1128, 0.2628, 0.4523, 0.6495, 0.8176, 0.9816, 1.1746, 1.3710,
+ 1.5568, 1.7518, 1.9497, 2.1452, 2.3346, 2.5389, 2.7362, 2.9264,
+ 0.1809, 0.3287, 0.5205, 0.7264, 0.9298, 1.1217, 1.2970, 1.4894,
+ 1.6874, 1.8493, 2.0576, 2.2382, 2.4097, 2.6041, 2.7796, 2.9389,
+ 0.2502, 0.4709, 0.6892, 0.8346, 0.9209, 1.0455, 1.2399, 1.4616,
+ 1.6463, 1.8380, 2.0475, 2.2397, 2.4665, 2.6550, 2.7701, 2.8895,
+ 0.1040, 0.2340, 0.3964, 0.5740, 0.7764, 0.9941, 1.2000, 1.4014,
+ 1.6024, 1.7974, 1.9939, 2.1959, 2.3783, 2.5663, 2.7613, 2.9484,
+ 0.1912, 0.3393, 0.4743, 0.6313, 0.8014, 0.9879, 1.1855, 1.3922,
+ 1.5678, 1.7289, 1.9271, 2.1165, 2.3089, 2.5414, 2.7448, 2.9269,
+ 0.0965, 0.2025, 0.3398, 0.4990, 0.6934, 0.9386, 1.1730, 1.3766,
+ 1.5783, 1.7783, 1.9790, 2.1831, 2.3670, 2.5578, 2.7641, 2.9516,
+ 0.2126, 0.3652, 0.5545, 0.7170, 0.8674, 1.0640, 1.2558, 1.4061,
+ 1.5904, 1.8095, 1.9760, 2.1505, 2.3549, 2.5575, 2.7023, 2.8877,
+ 0.1827, 0.3426, 0.4894, 0.6488, 0.7960, 0.9535, 1.1217, 1.2798,
+ 1.4566, 1.6453, 1.8044, 2.0042, 2.2379, 2.4611, 2.6697, 2.8966,
+ 0.2034, 0.3822, 0.5231, 0.6960, 0.9200, 1.0394, 1.1616, 1.3772,
+ 1.5493, 1.7330, 1.9646, 2.1233, 2.3334, 2.5361, 2.7087, 2.9470,
+ 0.1050, 0.2060, 0.3705, 0.5998, 0.8337, 1.0577, 1.2559, 1.4327,
+ 1.6334, 1.8165, 1.9853, 2.2058, 2.4063, 2.5818, 2.7625, 2.9458,
+ 0.1419, 0.4053, 0.6660, 0.8911, 1.0405, 1.1547, 1.2506, 1.3926,
+ 1.5669, 1.7527, 1.9694, 2.2054, 2.3889, 2.5743, 2.7586, 2.9174,
+ 0.1514, 0.2825, 0.4309, 0.5772, 0.7470, 0.9703, 1.1462, 1.3316,
+ 1.5321, 1.7259, 1.9282, 2.1266, 2.3106, 2.5064, 2.7067, 2.9094,
+ 0.1693, 0.3156, 0.4878, 0.6635, 0.8206, 0.9569, 1.1154, 1.3064,
+ 1.5109, 1.7184, 1.9179, 2.1036, 2.2763, 2.4820, 2.6949, 2.9105,
+ 0.1432, 0.2718, 0.4241, 0.5564, 0.6939, 0.9011, 1.1582, 1.3948,
+ 1.6181, 1.8024, 1.9814, 2.1740, 2.3459, 2.5456, 2.7491, 2.9307,
+ 0.2294, 0.3857, 0.5590, 0.7434, 0.9189, 1.0941, 1.2740, 1.4456,
+ 1.6178, 1.7994, 1.9689, 2.1644, 2.3525, 2.5385, 2.7468, 2.9405,
+ 0.1667, 0.3109, 0.4612, 0.6032, 0.7375, 0.8866, 1.0840, 1.3053,
+ 1.4982, 1.7044, 1.9146, 2.1117, 2.2942, 2.4983, 2.7084, 2.9132,
+ 0.1810, 0.3205, 0.4696, 0.6231, 0.7641, 0.9959, 1.2427, 1.4361,
+ 1.5889, 1.7544, 1.9083, 2.0733, 2.2457, 2.4461, 2.6793, 2.9098,
+ 0.1164, 0.3753, 0.6068, 0.7503, 1.0100, 1.2131, 1.3793, 1.5302,
+ 1.6300, 1.7950, 1.9057, 2.1031, 2.3830, 2.5745, 2.6949, 2.8779,
+ 0.1571, 0.4378, 0.6735, 0.8312, 0.8944, 0.9818, 1.1622, 1.4094,
+ 1.6423, 1.8066, 1.9258, 2.1838, 2.4363, 2.6279, 2.7358, 2.8790,
+ 0.1398, 0.2686, 0.4248, 0.6156, 0.7870, 1.0035, 1.2012, 1.3689,
+ 1.5363, 1.7398, 1.9604, 2.1619, 2.3345, 2.5097, 2.7271, 2.9368,
+ 0.1913, 0.3338, 0.4987, 0.6446, 0.7852, 1.0163, 1.1886, 1.3610,
+ 1.5379, 1.7230, 1.8880, 2.0862, 2.2960, 2.4928, 2.7122, 2.9151,
+ 0.0908, 0.1752, 0.2899, 0.5365, 0.7761, 1.0100, 1.2124, 1.4060,
+ 1.6019, 1.8010, 1.9774, 2.1905, 2.3733, 2.5623, 2.7660, 2.9565,
+ 0.1773, 0.3179, 0.4925, 0.6864, 0.8452, 0.9897, 1.1860, 1.3722,
+ 1.5515, 1.7658, 1.9802, 2.1819, 2.3620, 2.5442, 2.7250, 2.9220,
+ 0.1286, 0.2341, 0.3689, 0.5364, 0.7176, 0.9350, 1.1083, 1.2943,
+ 1.4974, 1.7059, 1.9047, 2.1145, 2.3242, 2.5361, 2.7453, 2.9329,
+ 0.2273, 0.3834, 0.5565, 0.7192, 0.8431, 0.9962, 1.1763, 1.3571,
+ 1.5774, 1.7419, 1.9202, 2.1131, 2.2919, 2.4898, 2.6895, 2.9180,
+ 0.1775, 0.3058, 0.4274, 0.6023, 0.8151, 1.0734, 1.3211, 1.5178,
+ 1.6706, 1.8154, 1.9686, 2.1537, 2.3461, 2.5276, 2.7181, 2.9121,
+ 0.1653, 0.4304, 0.6361, 0.7824, 0.9183, 1.0452, 1.2071, 1.4077,
+ 1.6206, 1.8299, 2.0089, 2.1948, 2.3900, 2.5982, 2.7844, 2.9487,
+ 0.1492, 0.2609, 0.3820, 0.5485, 0.7243, 0.9319, 1.1538, 1.3579,
+ 1.5266, 1.7002, 1.8873, 2.1016, 2.3175, 2.5221, 2.7241, 2.9243,
+ 0.2074, 0.3781, 0.5209, 0.6869, 0.8577, 0.9875, 1.1849, 1.3568,
+ 1.4907, 1.7335, 1.8902, 2.1224, 2.3099, 2.4918, 2.7023, 2.8765,
+ 0.1359, 0.2254, 0.3286, 0.4432, 0.6586, 0.8964, 1.1125, 1.3523,
+ 1.5626, 1.7579, 1.9846, 2.1905, 2.3548, 2.5542, 2.7663, 2.9346,
+ 0.1430, 0.2966, 0.4685, 0.6493, 0.8315, 1.0304, 1.2220, 1.4082,
+ 1.5995, 1.7888, 1.9774, 2.1737, 2.3607, 2.5577, 2.7558, 2.9405,
+ 0.1477, 0.2694, 0.4056, 0.5626, 0.7051, 0.8647, 1.0491, 1.2488,
+ 1.4814, 1.7072, 1.9150, 2.1147, 2.3038, 2.5144, 2.7184, 2.9202,
+ 0.1690, 0.3033, 0.4580, 0.6686, 0.8536, 1.0293, 1.2124, 1.3998,
+ 1.5718, 1.7607, 1.9580, 2.1245, 2.2971, 2.4762, 2.6896, 2.9177,
+ 0.1092, 0.2779, 0.4853, 0.6880, 0.9011, 1.0953, 1.2752, 1.4618,
+ 1.6623, 1.8484, 2.0264, 2.2152, 2.4017, 2.5835, 2.7671, 2.9436,
+ 0.1497, 0.3637, 0.6014, 0.8032, 0.9963, 1.1835, 1.3741, 1.5698,
+ 1.7382, 1.9094, 2.0710, 2.2392, 2.4082, 2.5926, 2.7762, 2.9536,
+ 0.1434, 0.2492, 0.3966, 0.5934, 0.8033, 1.0657, 1.2796, 1.4276,
+ 1.5745, 1.7833, 1.9288, 2.1247, 2.3543, 2.5412, 2.7049, 2.8872,
+ 0.1612, 0.2926, 0.4574, 0.6387, 0.8265, 1.0180, 1.1808, 1.3526,
+ 1.5564, 1.7536, 1.9187, 2.1192, 2.3149, 2.5006, 2.7101, 2.9217,
+ 0.0828, 0.1863, 0.3235, 0.5050, 0.7250, 0.9867, 1.2093, 1.3941,
+ 1.5980, 1.7932, 1.9809, 2.1894, 2.3918, 2.5773, 2.7540, 2.9329,
+ 0.2001, 0.3655, 0.5290, 0.6761, 0.8027, 0.9972, 1.2090, 1.4255,
+ 1.6085, 1.7825, 1.9804, 2.1681, 2.3457, 2.5325, 2.7319, 2.9196,
+ 0.1505, 0.2767, 0.4254, 0.6054, 0.7821, 0.9567, 1.1294, 1.3080,
+ 1.4984, 1.6954, 1.8666, 2.0736, 2.2875, 2.4969, 2.7072, 2.9163,
+ 0.1589, 0.4151, 0.5749, 0.6651, 0.8061, 1.0470, 1.2616, 1.3690,
+ 1.4985, 1.7808, 1.9825, 2.1068, 2.2751, 2.5448, 2.7133, 2.8689,
+ 0.0916, 0.1846, 0.3788, 0.6329, 0.8774, 1.0687, 1.2653, 1.4561,
+ 1.6573, 1.8449, 2.0402, 2.2254, 2.3968, 2.5861, 2.7792, 2.9508,
+ 0.2282, 0.4159, 0.5834, 0.6899, 0.8108, 1.0321, 1.2795, 1.5262,
+ 1.6936, 1.8469, 2.0922, 2.2607, 2.3795, 2.5301, 2.7386, 2.9530,
+ 0.1651, 0.3004, 0.4555, 0.6179, 0.7891, 0.9584, 1.1372, 1.3707,
+ 1.5951, 1.7880, 1.9434, 2.1465, 2.3311, 2.5081, 2.6977, 2.8970,
+ 0.1279, 0.3828, 0.6330, 0.8323, 0.9652, 1.1175, 1.2319, 1.3511,
+ 1.5115, 1.6392, 1.7835, 1.9558, 2.2008, 2.4635, 2.6910, 2.9058,
+ 0.1193, 0.2185, 0.3521, 0.5311, 0.7378, 0.9239, 1.1105, 1.3217,
+ 1.5362, 1.7504, 1.9536, 2.1627, 2.3560, 2.5506, 2.7548, 2.9453,
+ 0.1806, 0.3432, 0.4981, 0.6948, 0.8928, 1.0527, 1.2467, 1.4140,
+ 1.6326, 1.7950, 1.9935, 2.1969, 2.3512, 2.5682, 2.7445, 2.9277,
+ 0.1846, 0.3112, 0.4568, 0.5891, 0.7317, 0.8493, 1.0204, 1.2022,
+ 1.3688, 1.6020, 1.8428, 2.0710, 2.2725, 2.4879, 2.7057, 2.9160,
+ 0.0880, 0.2514, 0.5332, 0.7272, 0.8906, 1.1354, 1.3199, 1.4941,
+ 1.6010, 1.7151, 1.8712, 2.0643, 2.2755, 2.5375, 2.7054, 2.8891,
+ 0.1382, 0.2833, 0.4658, 0.6897, 0.9071, 1.0716, 1.2469, 1.4143,
+ 1.5910, 1.7947, 1.9805, 2.1581, 2.3338, 2.5215, 2.7292, 2.9211,
+ 0.1061, 0.3494, 0.6327, 0.8570, 0.9748, 1.0560, 1.1529, 1.3250,
+ 1.6032, 1.8340, 1.9711, 2.1157, 2.3011, 2.5464, 2.8078, 2.9803,
+ 0.1603, 0.2839, 0.4307, 0.5980, 0.7980, 1.0399, 1.1971, 1.3524,
+ 1.5715, 1.7838, 1.9468, 2.1498, 2.3627, 2.5514, 2.7327, 2.9148,
+ 0.1691, 0.3117, 0.4796, 0.6895, 0.8732, 1.0164, 1.1916, 1.3707,
+ 1.5384, 1.7202, 1.8857, 2.0672, 2.2487, 2.4593, 2.6789, 2.8940,
+ 0.0965, 0.1702, 0.3191, 0.5721, 0.8100, 1.0241, 1.2272, 1.4196,
+ 1.6093, 1.8057, 1.9884, 2.2037, 2.3925, 2.5805, 2.7578, 2.9366,
+ 0.1950, 0.3519, 0.5272, 0.6973, 0.8732, 1.0656, 1.2112, 1.3959,
+ 1.6116, 1.7821, 1.9445, 2.1592, 2.3348, 2.5142, 2.7440, 2.9297,
+ 0.1388, 0.2557, 0.4120, 0.5727, 0.7354, 0.9196, 1.0985, 1.2805,
+ 1.4643, 1.6535, 1.8340, 2.0546, 2.2758, 2.4778, 2.6921, 2.9122,
+ 0.1823, 0.3336, 0.4957, 0.6771, 0.8563, 1.0137, 1.2299, 1.3849,
+ 1.5718, 1.7667, 1.9193, 2.1326, 2.3135, 2.5268, 2.7133, 2.8998,
+ 0.0790, 0.1901, 0.4083, 0.6456, 0.8463, 1.0285, 1.2297, 1.4181,
+ 1.6159, 1.8056, 1.9971, 2.1912, 2.3816, 2.5746, 2.7692, 2.9497,
+ 0.0049, 0.0116, 0.0045, 0.0039, -0.0010, -0.0122, -0.0205, -0.0034,
+ -0.0140, -0.0041, 0.0191, -0.0322, 0.0002, -0.0124, -0.0269, 0.0059,
+ 0.0586, 0.0339, -0.0389, -0.0319, -0.0079, -0.0205, -0.0363, -0.0211,
+ 0.0241, 0.0595, 0.0469, 0.0283, 0.0176, -0.0183, -0.0173, -0.0004,
+ 0.0024, 0.0145, 0.0534, 0.0197, -0.0065, -0.0067, 0.0133, 0.0358,
+ -0.0104, -0.0386, -0.0109, -0.0078, 0.0275, 0.0565, 0.0251, -0.0027,
+ -0.0053, 0.0171, 0.0088, 0.0495, 0.0141, 0.0039, -0.0445, -0.0426,
+ -0.0184, -0.0280, -0.0223, 0.0039, -0.0171, -0.0606, -0.0786, -0.0430,
+ 0.0544, 0.0595, 0.0320, -0.0012, 0.0108, 0.0185, 0.0066, 0.0408,
+ 0.0552, -0.0073, -0.0247, -0.0480, -0.0288, 0.0186, 0.0212, -0.0013,
+ 0.0403, 0.0598, 0.0690, 0.0516, -0.0298, -0.0177, 0.0278, 0.0168,
+ -0.0106, 0.0251, 0.0386, 0.0331, -0.0052, 0.0133, 0.0291, -0.0158,
+ -0.0329, -0.0367, 0.0287, 0.0462, -0.0176, 0.0049, 0.0242, -0.0034,
+ 0.0135, 0.0086, -0.0149, 0.0241, 0.0504, 0.0246, -0.0273, -0.0369,
+ -0.0108, -0.0449, -0.0625, -0.0414, -0.0292, -0.0571, -0.0440, -0.0088,
+ 0.0098, 0.0009, -0.0004, 0.0007, -0.0314, -0.0208, -0.0138, -0.0277,
+ -0.0044, 0.0522, 0.0315, -0.0270, -0.0277, -0.0256, -0.0103, -0.0201,
+ -0.0287, -0.0279, -0.0182, 0.0472, 0.0613, 0.0450, 0.0413, 0.0333,
+ 0.0444, 0.0223, 0.0061, 0.0316, 0.0321, 0.0501, 0.0460, 0.0250,
+ 0.0227, 0.0235, 0.0099, 0.0185, -0.0347, -0.0684, -0.0189, 0.0242,
+ -0.0190, -0.0273, -0.0012, -0.0253, 0.0293, -0.0231, -0.0219, -0.0010,
+ 0.0153, 0.0128, -0.0166, -0.0435, -0.0417, -0.0121, -0.0351, -0.0390,
+ 0.0077, -0.0278, -0.0355, 0.0092, -0.0063, 0.0005, 0.0216, 0.0461,
+ 0.0538, 0.0451, 0.0298, -0.0130, 0.0058, 0.0206, 0.0471, 0.0499,
+ 0.0280, 0.0086, -0.0007, -0.0317, 0.0259, 0.0176, 0.0043, 0.0212,
+ 0.0138, 0.0106, 0.0220, -0.0025, 0.0050, 0.0122, -0.0051, -0.0086,
+ -0.0472, -0.0005, 0.0193, 0.0032, 0.0246, 0.0222, 0.0090, -0.0320,
+ -0.0713, -0.0526, -0.0151, -0.0440, -0.0648, -0.0466, -0.0092, 0.0115,
+ -0.0129, 0.0053, -0.0344, -0.0385, 0.0392, 0.0599, 0.0414, 0.0165,
+ -0.0098, -0.0320, -0.0261, -0.0055, -0.0139, -0.0110, 0.0084, 0.0172,
+ -0.0492, -0.0537, -0.0320, -0.0036, 0.0265, 0.0385, 0.0064, -0.0280,
+ -0.0230, 0.0134, 0.0241, 0.0106, 0.0387, 0.0105, 0.0068, 0.0260,
+ 0.4940, 0.4911, 0.4849, 0.4820, 0.4837, 0.4839, 0.4824, 0.4799,
+ 0.4812, 0.4782, 0.4788, 0.4711, 0.4706, 0.4671, 0.4601, 0.4578,
+ 0.2954, 0.2121, 0.1859, 0.1958, 0.1474, 0.1086, 0.1351, 0.1362,
+ 0.1486, 0.1342, 0.1215, 0.1423, 0.1634, 0.1588, 0.1539, 0.1857,
};
static const float lsp16[] = {
@@ -4234,7 +12744,520 @@
0.0306, 0.0090, -0.0054, 0.0333, 0.0047, 0.0238, 0.0141, 0.0165,
0.0306, 0.0420, 0.0159, 0.0124, 0.0414, 0.0158, -0.0237, 0.0141,
0.0765, 0.0057, -0.0260, -0.0426, -0.0395, -0.0126, -0.0579, -0.0417,
- -0.0429, -0.0615, -0.0893, -0.0618, -0.0384, -0.0134, -0.0232, -0.0238
+ -0.0429, -0.0615, -0.0893, -0.0618, -0.0384, -0.0134, -0.0232, -0.0238,
+};
+
+static const float lsp16s[] = {
+ 0.1813, 0.3911, 0.6301, 0.8012, 1.0057, 1.2041, 1.4271, 1.6943,
+ 1.9402, 2.1733, 2.3521, 2.4989, 2.5839, 2.6846, 2.7634, 2.8950,
+ 0.1311, 0.3183, 0.4659, 0.5601, 0.6658, 0.7828, 1.0065, 1.2717,
+ 1.5185, 1.7339, 1.9530, 2.2189, 2.3739, 2.4991, 2.6984, 2.9256,
+ 0.1627, 0.4519, 0.6323, 0.7012, 0.7848, 0.9801, 1.1810, 1.3222,
+ 1.5413, 1.8129, 1.9338, 2.0809, 2.3180, 2.5189, 2.7066, 2.9514,
+ 0.1475, 0.2447, 0.4240, 0.5669, 0.7872, 0.9838, 1.1823, 1.3814,
+ 1.5358, 1.6820, 1.8794, 2.1419, 2.4132, 2.6112, 2.7911, 2.9511,
+ 0.1224, 0.2876, 0.5013, 0.6985, 0.8902, 1.0901, 1.2835, 1.4768,
+ 1.6596, 1.8538, 2.0467, 2.2304, 2.4124, 2.5942, 2.7729, 2.9531,
+ 0.1741, 0.3034, 0.4677, 0.5879, 0.7258, 0.9648, 1.1417, 1.3220,
+ 1.5081, 1.7151, 1.9212, 2.1286, 2.3208, 2.4938, 2.6765, 2.8891,
+ 0.1657, 0.3174, 0.4907, 0.6559, 0.8295, 1.0254, 1.2071, 1.3880,
+ 1.5737, 1.7845, 1.9027, 2.1139, 2.3323, 2.5157, 2.7323, 2.9015,
+ 0.1592, 0.2758, 0.4417, 0.6315, 0.8257, 0.9873, 1.1277, 1.2830,
+ 1.4337, 1.6315, 1.8899, 2.1356, 2.3572, 2.5632, 2.7468, 2.9420,
+ 0.1524, 0.4325, 0.5931, 0.7036, 0.7696, 0.8923, 1.1739, 1.4773,
+ 1.6609, 1.7911, 1.9666, 2.1972, 2.3754, 2.5045, 2.6613, 2.8882,
+ 0.2130, 0.3013, 0.3721, 0.4257, 0.5079, 0.7015, 0.9815, 1.2554,
+ 1.4648, 1.6966, 1.9138, 2.1075, 2.3318, 2.5292, 2.7453, 2.9347,
+ 0.1142, 0.3748, 0.6205, 0.7642, 0.8121, 0.9022, 0.9843, 1.1558,
+ 1.4467, 1.7422, 1.9574, 2.1302, 2.3812, 2.5898, 2.7720, 2.9583,
+ 0.1255, 0.2339, 0.3570, 0.5323, 0.7458, 1.0003, 1.1729, 1.3567,
+ 1.5217, 1.6977, 1.8924, 2.0942, 2.3145, 2.5408, 2.7553, 2.9337,
+ 0.1316, 0.2289, 0.4327, 0.6663, 0.8509, 0.9994, 1.1697, 1.3804,
+ 1.5609, 1.6903, 1.8572, 2.1019, 2.3687, 2.5789, 2.7715, 2.9472,
+ 0.1502, 0.2546, 0.3883, 0.5333, 0.6976, 0.9163, 1.1071, 1.3364,
+ 1.5420, 1.7525, 1.8948, 2.0839, 2.2819, 2.4651, 2.6875, 2.8987,
+ 0.1593, 0.3014, 0.4573, 0.6354, 0.8157, 0.9805, 1.1783, 1.3747,
+ 1.5678, 1.7326, 1.9286, 2.1340, 2.3253, 2.5280, 2.7180, 2.9298,
+ 0.1811, 0.3167, 0.4655, 0.6507, 0.8198, 1.0075, 1.1892, 1.3743,
+ 1.5227, 1.7090, 1.8849, 2.0743, 2.2750, 2.4830, 2.6896, 2.8953,
+ 0.1846, 0.3577, 0.5315, 0.7290, 0.9176, 1.1016, 1.2654, 1.4525,
+ 1.6315, 1.8268, 2.0238, 2.1934, 2.3868, 2.5753, 2.7682, 2.9469,
+ 0.0876, 0.1439, 0.2048, 0.3654, 0.6281, 0.8853, 1.0907, 1.2992,
+ 1.5227, 1.7373, 1.9395, 2.1419, 2.3488, 2.5486, 2.7466, 2.9348,
+ 0.1391, 0.4170, 0.6561, 0.7953, 0.8734, 0.9986, 1.1870, 1.4520,
+ 1.6042, 1.7910, 2.0135, 2.1870, 2.3358, 2.5066, 2.7409, 2.9955,
+ 0.0804, 0.1355, 0.2599, 0.4998, 0.7408, 0.9474, 1.1276, 1.3428,
+ 1.5556, 1.7712, 1.9699, 2.1535, 2.3605, 2.5548, 2.7489, 2.9325,
+ 0.1304, 0.3087, 0.4979, 0.6584, 0.8414, 1.0329, 1.2244, 1.4189,
+ 1.6118, 1.8200, 1.9985, 2.1893, 2.3915, 2.5794, 2.7647, 2.9344,
+ 0.1895, 0.2849, 0.3705, 0.4126, 0.6265, 0.9207, 1.1774, 1.3762,
+ 1.5757, 1.7728, 1.9568, 2.1662, 2.3615, 2.5575, 2.7561, 2.9416,
+ 0.1800, 0.3078, 0.4805, 0.6796, 0.8503, 1.0046, 1.1703, 1.3269,
+ 1.4862, 1.6502, 1.8454, 2.0873, 2.3175, 2.5356, 2.7516, 2.9469,
+ 0.1950, 0.3233, 0.4568, 0.5940, 0.7589, 0.9978, 1.1701, 1.3383,
+ 1.5017, 1.6565, 1.8243, 2.0605, 2.2938, 2.5147, 2.7419, 2.9396,
+ 0.2531, 0.4391, 0.5790, 0.7170, 0.8998, 1.1430, 1.3577, 1.5326,
+ 1.6328, 1.7627, 1.9726, 2.1762, 2.3563, 2.5478, 2.7385, 2.9067,
+ 0.1805, 0.2788, 0.3591, 0.3881, 0.5441, 0.8055, 1.0766, 1.3165,
+ 1.5316, 1.7508, 1.9477, 2.1374, 2.3438, 2.5484, 2.7501, 2.9410,
+ 0.2044, 0.3671, 0.5396, 0.7042, 0.8582, 0.9831, 1.1261, 1.3194,
+ 1.4769, 1.6979, 1.8717, 2.0463, 2.2620, 2.4739, 2.7054, 2.9208,
+ 0.1048, 0.2175, 0.4206, 0.5923, 0.7483, 0.9400, 1.1356, 1.3799,
+ 1.5958, 1.7320, 1.8984, 2.1296, 2.3594, 2.5492, 2.7387, 2.9305,
+ 0.0842, 0.1729, 0.3951, 0.6447, 0.8688, 1.0605, 1.2472, 1.4330,
+ 1.6232, 1.8144, 2.0216, 2.1915, 2.3878, 2.5763, 2.7685, 2.9464,
+ 0.1461, 0.2593, 0.4105, 0.5677, 0.7328, 0.8919, 1.0484, 1.2302,
+ 1.4386, 1.6635, 1.8873, 2.1024, 2.3116, 2.5268, 2.7273, 2.9269,
+ 0.1503, 0.3108, 0.4756, 0.6731, 0.8600, 1.0233, 1.2115, 1.3971,
+ 1.5915, 1.7892, 1.9517, 2.1603, 2.3487, 2.5460, 2.7308, 2.8998,
+ 0.2163, 0.3669, 0.5125, 0.6709, 0.8143, 0.9930, 1.2095, 1.4205,
+ 1.6176, 1.7112, 1.8398, 2.0896, 2.3513, 2.5290, 2.6667, 2.8960,
+ 0.2133, 0.4382, 0.6287, 0.8702, 1.1088, 1.3749, 1.6062, 1.7446,
+ 1.8333, 1.9122, 1.9614, 2.0669, 2.1789, 2.3449, 2.6038, 2.8849,
+ 0.1598, 0.2719, 0.3877, 0.4815, 0.5926, 0.7795, 1.0449, 1.3045,
+ 1.5210, 1.7391, 1.9462, 2.1397, 2.3553, 2.5458, 2.7540, 2.9392,
+ 0.2918, 0.5607, 0.6801, 0.7404, 0.8285, 0.9431, 1.1579, 1.4080,
+ 1.6332, 1.8472, 1.9738, 2.0771, 2.2890, 2.5178, 2.7445, 2.9830,
+ 0.1664, 0.2842, 0.3965, 0.5463, 0.8162, 1.0346, 1.1849, 1.3446,
+ 1.5122, 1.7563, 1.9960, 2.2002, 2.3796, 2.5689, 2.7712, 2.9550,
+ 0.0911, 0.2397, 0.5052, 0.7868, 1.0299, 1.1311, 1.2244, 1.3333,
+ 1.4395, 1.6790, 1.9369, 2.1717, 2.3689, 2.5538, 2.7340, 2.9326,
+ 0.1647, 0.2931, 0.3836, 0.4978, 0.6255, 0.9243, 1.1339, 1.3001,
+ 1.5269, 1.8010, 1.9715, 2.1419, 2.3784, 2.5503, 2.6719, 2.8745,
+ 0.2440, 0.3802, 0.4756, 0.6613, 0.8627, 1.0292, 1.2291, 1.4060,
+ 1.5198, 1.7354, 1.9044, 2.1010, 2.3147, 2.4996, 2.7171, 2.9041,
+ 0.1590, 0.2876, 0.4572, 0.5996, 0.7713, 0.9490, 1.1205, 1.2815,
+ 1.4516, 1.6385, 1.8179, 2.0457, 2.2759, 2.4785, 2.6861, 2.9080,
+ 0.2297, 0.4309, 0.5712, 0.6717, 0.8138, 1.0463, 1.2492, 1.4560,
+ 1.6796, 1.8458, 1.9642, 2.1452, 2.3636, 2.5395, 2.7456, 2.9495,
+ 0.2975, 0.4678, 0.4996, 0.5809, 0.6279, 0.6884, 0.8606, 1.1386,
+ 1.4412, 1.6876, 1.8760, 2.0932, 2.3178, 2.5166, 2.7345, 2.9280,
+ 0.1278, 0.3737, 0.6004, 0.7069, 0.8147, 1.0180, 1.2581, 1.3812,
+ 1.4855, 1.7268, 1.9970, 2.1258, 2.2936, 2.5702, 2.7563, 2.8983,
+ 0.1314, 0.2508, 0.3999, 0.5680, 0.7424, 0.9367, 1.1286, 1.3175,
+ 1.5336, 1.7404, 1.9317, 2.1404, 2.3514, 2.5562, 2.7510, 2.9402,
+ 0.1043, 0.2367, 0.4293, 0.6376, 0.8160, 0.9836, 1.1779, 1.3850,
+ 1.5835, 1.7875, 1.9765, 2.1593, 2.3654, 2.5577, 2.7465, 2.9398,
+ 0.1529, 0.2515, 0.3454, 0.4374, 0.7011, 0.9015, 1.0744, 1.3532,
+ 1.5699, 1.7545, 2.0021, 2.1259, 2.2278, 2.4546, 2.7264, 2.9425,
+ 0.1429, 0.2808, 0.4395, 0.6334, 0.8069, 0.9705, 1.1520, 1.3250,
+ 1.5109, 1.7285, 1.9356, 2.1469, 2.3479, 2.5554, 2.7512, 2.9348,
+ 0.1625, 0.3022, 0.4756, 0.6315, 0.8032, 0.9924, 1.1596, 1.3204,
+ 1.4994, 1.6929, 1.8955, 2.1090, 2.3025, 2.5018, 2.6908, 2.8980,
+ 0.1692, 0.3427, 0.5228, 0.7756, 0.9688, 1.0950, 1.3056, 1.4360,
+ 1.5675, 1.8049, 1.9376, 2.1151, 2.3407, 2.5012, 2.7192, 2.9258,
+ 0.0474, 0.1251, 0.1939, 0.3841, 0.6501, 0.9231, 1.1153, 1.3240,
+ 1.5478, 1.7599, 1.9651, 2.1510, 2.3645, 2.5552, 2.7542, 2.9393,
+ 0.2196, 0.4656, 0.7492, 0.9922, 1.1678, 1.2489, 1.3112, 1.3657,
+ 1.4223, 1.5302, 1.7212, 1.9996, 2.2523, 2.4844, 2.7036, 2.9145,
+ 0.1128, 0.2368, 0.3704, 0.5476, 0.7723, 0.9968, 1.1930, 1.3992,
+ 1.6013, 1.7957, 1.9888, 2.1857, 2.3825, 2.5705, 2.7616, 2.9434,
+ 0.1341, 0.2768, 0.4510, 0.6359, 0.8332, 1.0335, 1.2004, 1.3952,
+ 1.5762, 1.7681, 1.9815, 2.1735, 2.3657, 2.5552, 2.7514, 2.9498,
+ 0.1247, 0.2559, 0.3516, 0.4726, 0.6861, 0.9483, 1.1852, 1.3858,
+ 1.5851, 1.7815, 1.9778, 2.1737, 2.3729, 2.5664, 2.7620, 2.9429,
+ 0.1988, 0.3320, 0.4777, 0.6737, 0.8425, 1.0265, 1.1694, 1.3655,
+ 1.5463, 1.7135, 1.9385, 2.1650, 2.3529, 2.5367, 2.7545, 2.9585,
+ 0.1376, 0.2620, 0.4273, 0.6169, 0.7755, 0.9441, 1.1169, 1.3157,
+ 1.5179, 1.7020, 1.8931, 2.1059, 2.3112, 2.5136, 2.7169, 2.9198,
+ 0.2112, 0.4385, 0.6091, 0.7618, 0.9553, 1.1543, 1.3445, 1.5396,
+ 1.7153, 1.9192, 2.1263, 2.3593, 2.5958, 2.8171, 2.9394, 3.0409,
+ 0.1347, 0.2099, 0.2646, 0.3453, 0.5266, 0.7869, 1.0513, 1.2795,
+ 1.4880, 1.7181, 1.9294, 2.1332, 2.3362, 2.5442, 2.7433, 2.9362,
+ 0.3141, 0.5935, 0.7517, 0.8313, 0.8568, 0.9570, 1.0250, 1.1275,
+ 1.3422, 1.6303, 1.8577, 2.0705, 2.2957, 2.5095, 2.7244, 2.9262,
+ 0.0962, 0.2116, 0.3961, 0.5641, 0.7122, 0.8883, 1.1023, 1.3481,
+ 1.5623, 1.7554, 1.9618, 2.1675, 2.3706, 2.5556, 2.7430, 2.9337,
+ 0.0898, 0.1510, 0.3060, 0.5820, 0.8221, 1.0388, 1.2261, 1.4289,
+ 1.6054, 1.8103, 1.9941, 2.1844, 2.3742, 2.5711, 2.7632, 2.9474,
+ 0.1326, 0.2316, 0.3761, 0.5177, 0.6782, 0.8761, 1.0952, 1.3175,
+ 1.5078, 1.7034, 1.9051, 2.1245, 2.3424, 2.5484, 2.7444, 2.9389,
+ 0.1740, 0.3293, 0.5174, 0.6824, 0.8394, 1.0372, 1.2046, 1.3723,
+ 1.5656, 1.7444, 1.9442, 2.1386, 2.3139, 2.4960, 2.7071, 2.9297,
+ 0.2304, 0.3775, 0.4865, 0.6182, 0.7842, 0.9208, 1.1151, 1.2843,
+ 1.4641, 1.6988, 1.9209, 2.1260, 2.3099, 2.5229, 2.7414, 2.9276,
+ 0.0094, 0.0261, -0.0037, 0.0041, -0.0092, -0.0044, -0.0232, -0.0073,
+ -0.0047, -0.0021, 0.0250, -0.0580, -0.0140, -0.0342, -0.0586, 0.0020,
+ 0.0449, 0.0155, -0.0523, -0.0279, 0.0299, -0.0183, -0.0736, -0.0639,
+ -0.0017, 0.0336, 0.0209, 0.0046, 0.0077, -0.0148, -0.0114, -0.0120,
+ 0.0115, -0.0050, 0.0445, 0.0048, 0.0188, -0.0137, -0.0080, 0.0239,
+ -0.0184, -0.0524, -0.0195, -0.0126, 0.0284, 0.0632, 0.0141, -0.0093,
+ -0.0096, 0.0196, 0.0230, 0.0379, 0.0308, 0.0237, -0.0224, -0.0600,
+ -0.0755, -0.1074, -0.0988, -0.0606, -0.1038, -0.1552, -0.1480, -0.0672,
+ 0.0504, 0.0676, 0.0336, -0.0042, 0.0729, 0.1013, 0.0868, 0.0846,
+ 0.0954, 0.0515, -0.0066, -0.0851, -0.0485, 0.0294, 0.0395, 0.0087,
+ 0.0078, 0.0446, 0.0881, 0.0672, -0.0384, -0.0025, 0.0415, 0.0353,
+ 0.0080, 0.0052, 0.0190, 0.0182, 0.0069, 0.0168, 0.0374, 0.0037,
+ -0.0292, -0.0429, 0.0302, 0.0681, -0.0233, -0.0238, -0.0003, -0.0043,
+ 0.0054, -0.0029, -0.0149, 0.0642, 0.0622, 0.0341, -0.0232, -0.0461,
+ -0.0082, -0.0469, -0.0618, -0.0326, -0.0452, -0.0649, -0.0597, -0.0398,
+ -0.0318, -0.0116, 0.0011, 0.0009, -0.0384, -0.0384, -0.0156, -0.0260,
+ -0.0007, 0.0473, 0.0111, -0.0358, -0.0484, -0.0204, -0.0029, -0.0090,
+ -0.0285, -0.0495, -0.0376, 0.0917, 0.1192, 0.1026, 0.0745, 0.0397,
+ 0.0463, 0.0253, 0.0025, 0.0465, 0.0100, 0.0488, 0.0416, 0.0223,
+ 0.0263, 0.0072, -0.0053, 0.0595, 0.0060, -0.0518, -0.0316, -0.0043,
+ -0.0133, -0.0233, -0.0075, -0.0251, 0.0277, -0.0067, -0.0136, -0.0004,
+ 0.0235, 0.0112, -0.0182, -0.0324, -0.0210, -0.0035, -0.0395, -0.0384,
+ 0.0005, -0.0150, -0.0356, 0.0127, -0.0033, -0.0034, 0.0205, 0.0747,
+ 0.1138, 0.1015, 0.0995, -0.0161, -0.0045, 0.0129, 0.0472, 0.0575,
+ 0.0222, 0.0091, 0.0037, -0.0471, 0.0371, 0.0132, 0.0208, 0.0247,
+ 0.0117, 0.0164, 0.0225, 0.0124, -0.0023, 0.0088, -0.0046, 0.0047,
+ -0.0393, 0.0018, 0.0148, 0.0020, 0.0044, 0.0165, 0.0229, -0.0208,
+ -0.0477, -0.0310, -0.0164, -0.0390, -0.0764, -0.0525, -0.0094, 0.0075,
+ -0.0102, -0.0045, -0.0504, -0.0709, 0.0822, 0.0710, 0.0426, 0.0014,
+ -0.0371, -0.0400, -0.0157, -0.0155, -0.0173, -0.0138, -0.0015, 0.0134,
+ -0.0418, -0.0682, -0.0256, 0.0050, 0.0360, 0.0354, 0.0074, -0.0396,
+ -0.0235, 0.0284, 0.0494, 0.0153, 0.0448, 0.0025, -0.0061, 0.0252,
+ 0.1000, 0.2260, 0.2158, 0.2116, 0.2198, 0.2055, 0.2110, 0.1873,
+ 0.1907, 0.2071, 0.2164, 0.2009, 0.2059, 0.2124, 0.2141, 0.2093,
+ 0.0875, 0.0981, 0.1177, 0.1071, 0.1033, 0.1248, 0.1048, 0.1238,
+ 0.1166, 0.1008, 0.1062, 0.0992, 0.0994, 0.1067, 0.0999, 0.1187,
+ 0.0750, 0.0794, 0.0828, 0.0854, 0.0859, 0.0801, 0.0891, 0.0933,
+ 0.0969, 0.0920, 0.0915, 0.0862, 0.0868, 0.0891, 0.0842, 0.0824,
+ 0.0625, 0.0930, 0.0815, 0.0853, 0.0898, 0.0828, 0.0822, 0.0910,
+ 0.0873, 0.0906, 0.0856, 0.0840, 0.0774, 0.0785, 0.0684, 0.0711,
+ 0.3319, 0.4219, 0.4588, 0.4090, 0.4092, 0.4014, 0.3548, 0.3353,
+ 0.3708, 0.3352, 0.3720, 0.3538, 0.4084, 0.4289, 0.4060, 0.4210,
+ 0.0588, 0.0209, -0.0082, -0.0115, -0.0343, -0.0621, -0.0541, -0.0346,
+ -0.0346, -0.0366, -0.0220, -0.0265, -0.0102, 0.0374, 0.0306, 0.0404,
+ 0.0306, 0.0090, -0.0054, 0.0333, 0.0047, 0.0238, 0.0141, 0.0165,
+ 0.0306, 0.0420, 0.0159, 0.0124, 0.0414, 0.0158, -0.0237, 0.0141,
+ 0.0765, 0.0057, -0.0260, -0.0426, -0.0395, -0.0126, -0.0579, -0.0417,
+ -0.0429, -0.0615, -0.0893, -0.0618, -0.0384, -0.0134, -0.0232, -0.0238,
+};
+
+static const float lsp22[] = {
+ 0.0664, 0.1875, 0.4300, 0.6730, 0.8793, 1.0640, 1.2563, 1.4433,
+ 1.6394, 1.8176, 2.0029, 2.1921, 2.3796, 2.5671, 2.7595, 2.9536,
+ 0.2128, 0.4052, 0.5311, 0.6404, 0.7875, 0.8775, 1.0974, 1.3261,
+ 1.5563, 1.6790, 1.8339, 2.1195, 2.3226, 2.4609, 2.6440, 2.8947,
+ 0.2024, 0.3362, 0.4834, 0.6784, 0.9088, 1.0850, 1.2188, 1.4054,
+ 1.6102, 1.7767, 1.9679, 2.1436, 2.3445, 2.5467, 2.7429, 2.9320,
+ 0.1181, 0.2279, 0.4413, 0.6114, 0.7710, 0.9427, 1.1142, 1.2707,
+ 1.4892, 1.7416, 1.9526, 2.1466, 2.3629, 2.5445, 2.7293, 2.9205,
+ 0.1155, 0.2720, 0.4886, 0.6812, 0.8594, 1.0422, 1.2315, 1.4116,
+ 1.6137, 1.8020, 1.9758, 2.1743, 2.3602, 2.5568, 2.7472, 2.9374,
+ 0.1110, 0.3312, 0.4735, 0.5612, 0.7129, 0.8146, 1.0233, 1.3155,
+ 1.5765, 1.7746, 1.9574, 2.1416, 2.3220, 2.5384, 2.7334, 2.9318,
+ 0.1656, 0.3350, 0.4215, 0.5609, 0.6759, 0.8503, 1.1405, 1.4094,
+ 1.6057, 1.6860, 1.7639, 2.0031, 2.2680, 2.5076, 2.7263, 2.9368,
+ 0.1466, 0.3638, 0.4587, 0.5674, 0.7381, 0.8669, 0.9619, 1.1658,
+ 1.4667, 1.7440, 1.9335, 2.1018, 2.3022, 2.5281, 2.7359, 2.9261,
+ 0.1061, 0.2566, 0.4739, 0.6751, 0.8711, 1.0704, 1.2720, 1.4655,
+ 1.6605, 1.8494, 2.0290, 2.2197, 2.4008, 2.5912, 2.7772, 2.9513,
+ 0.1116, 0.2364, 0.3971, 0.6316, 0.8583, 1.0335, 1.1686, 1.3302,
+ 1.5612, 1.7877, 1.9829, 2.2052, 2.3596, 2.5460, 2.7341, 2.9290,
+ 0.2661, 0.4186, 0.5126, 0.6477, 0.8818, 1.1045, 1.2852, 1.4128,
+ 1.5851, 1.7593, 1.9399, 2.1757, 2.3684, 2.5136, 2.6927, 2.9064,
+ 0.1495, 0.2749, 0.4391, 0.6304, 0.8239, 1.0181, 1.1995, 1.3759,
+ 1.5669, 1.7722, 1.9671, 2.1635, 2.3586, 2.5528, 2.7445, 2.9311,
+ 0.0912, 0.1759, 0.3066, 0.5660, 0.8005, 0.9568, 1.1832, 1.4504,
+ 1.6259, 1.7948, 2.0113, 2.2002, 2.3654, 2.5583, 2.7929, 2.9735,
+ 0.1353, 0.2747, 0.4078, 0.5977, 0.7658, 0.9124, 1.1081, 1.3630,
+ 1.5875, 1.7847, 1.9323, 2.1181, 2.3321, 2.5046, 2.7183, 2.9225,
+ 0.1938, 0.4063, 0.4982, 0.6002, 0.7702, 0.9071, 1.1631, 1.3885,
+ 1.6043, 1.8118, 1.9306, 2.0893, 2.2724, 2.4609, 2.6283, 2.8802,
+ 0.1857, 0.3351, 0.4381, 0.6101, 0.7561, 0.8555, 1.0384, 1.3171,
+ 1.5667, 1.6904, 1.7552, 1.9689, 2.2597, 2.5260, 2.7272, 2.9337,
+ 0.1037, 0.2159, 0.4188, 0.6174, 0.8035, 1.0285, 1.2256, 1.4230,
+ 1.6400, 1.8322, 2.0144, 2.1988, 2.3810, 2.5682, 2.7613, 2.9438,
+ 0.1625, 0.2776, 0.4225, 0.6001, 0.7879, 0.9087, 1.0801, 1.2759,
+ 1.4899, 1.7448, 1.9911, 2.1770, 2.3723, 2.5777, 2.7971, 2.9444,
+ 0.2111, 0.3640, 0.5839, 0.7290, 0.8051, 1.0023, 1.2315, 1.4143,
+ 1.5878, 1.7755, 1.9804, 2.1498, 2.3312, 2.5350, 2.7613, 2.9472,
+ 0.1423, 0.2646, 0.4136, 0.6350, 0.8070, 0.9514, 1.1168, 1.3213,
+ 1.5776, 1.7721, 1.9404, 2.1545, 2.3385, 2.5137, 2.7396, 2.9553,
+ 0.1132, 0.2386, 0.4103, 0.5931, 0.7808, 0.9881, 1.1840, 1.3860,
+ 1.6021, 1.7990, 1.9922, 2.1885, 2.3852, 2.5717, 2.7640, 2.9510,
+ 0.1267, 0.2602, 0.3913, 0.5944, 0.7598, 0.9198, 1.0781, 1.2715,
+ 1.5299, 1.7573, 1.9308, 2.1346, 2.3267, 2.5419, 2.7466, 2.9320,
+ 0.2023, 0.3417, 0.4392, 0.6141, 0.7439, 0.8593, 1.1096, 1.3543,
+ 1.5185, 1.6553, 1.7862, 2.0341, 2.2718, 2.4834, 2.7103, 2.9466,
+ 0.1113, 0.2470, 0.3677, 0.5686, 0.7700, 0.9356, 1.0806, 1.2452,
+ 1.4830, 1.7344, 1.9268, 2.1404, 2.3371, 2.5169, 2.7329, 2.9012,
+ 0.1664, 0.3554, 0.5573, 0.7471, 0.9245, 1.0998, 1.2787, 1.4655,
+ 1.6654, 1.8346, 2.0179, 2.2159, 2.4096, 2.5946, 2.7790, 2.9530,
+ 0.1313, 0.2625, 0.4731, 0.6444, 0.8110, 0.9878, 1.1493, 1.3212,
+ 1.5719, 1.8138, 1.9861, 2.1943, 2.3714, 2.5578, 2.7346, 2.9296,
+ 0.1186, 0.3035, 0.5049, 0.6860, 0.8670, 0.9975, 1.1364, 1.3471,
+ 1.5695, 1.7412, 1.9346, 2.1506, 2.3413, 2.5531, 2.7794, 2.9627,
+ 0.1108, 0.2697, 0.4787, 0.6344, 0.7909, 0.9586, 1.1440, 1.3511,
+ 1.5686, 1.7601, 1.9246, 2.1241, 2.3293, 2.5390, 2.7315, 2.9333,
+ 0.0985, 0.2302, 0.3544, 0.5759, 0.7620, 0.9651, 1.1497, 1.3080,
+ 1.5500, 1.7845, 1.9518, 2.1734, 2.3565, 2.5665, 2.7605, 2.9102,
+ 0.1208, 0.2727, 0.4381, 0.5736, 0.7382, 0.8390, 1.0102, 1.2648,
+ 1.5100, 1.7440, 1.9619, 2.1430, 2.3307, 2.5159, 2.7264, 2.9211,
+ 0.1582, 0.2777, 0.4475, 0.6551, 0.8591, 1.0084, 1.1414, 1.3291,
+ 1.5902, 1.7826, 1.9543, 2.1659, 2.3233, 2.5044, 2.6935, 2.9199,
+ 0.1360, 0.2873, 0.4585, 0.6295, 0.7592, 0.9089, 1.0492, 1.2733,
+ 1.5391, 1.7768, 1.9372, 2.1329, 2.3168, 2.5015, 2.6857, 2.8837,
+ 0.0886, 0.1829, 0.3696, 0.6126, 0.8334, 1.0135, 1.2303, 1.4674,
+ 1.6743, 1.8564, 2.0530, 2.2370, 2.3960, 2.5787, 2.7756, 2.9377,
+ 0.2005, 0.3537, 0.4700, 0.6249, 0.7385, 0.9097, 1.1759, 1.3811,
+ 1.5314, 1.6705, 1.8546, 2.1229, 2.3292, 2.5251, 2.7951, 2.9646,
+ 0.1999, 0.3112, 0.4722, 0.7146, 0.8908, 1.0028, 1.1831, 1.3903,
+ 1.6125, 1.7514, 1.9083, 2.1248, 2.3271, 2.5339, 2.6945, 2.8918,
+ 0.1243, 0.2606, 0.4382, 0.5850, 0.7705, 0.9727, 1.1214, 1.3059,
+ 1.5218, 1.7406, 1.9137, 2.1353, 2.3354, 2.5299, 2.7287, 2.9068,
+ 0.1039, 0.2426, 0.4265, 0.6284, 0.8152, 0.9941, 1.2004, 1.4038,
+ 1.5912, 1.7763, 1.9650, 2.1598, 2.3474, 2.5488, 2.7419, 2.9322,
+ 0.1364, 0.2420, 0.3886, 0.5864, 0.7663, 0.8844, 1.0860, 1.3242,
+ 1.5518, 1.7893, 2.0004, 2.1562, 2.3619, 2.5516, 2.7687, 2.9181,
+ 0.1483, 0.2851, 0.4479, 0.6312, 0.7924, 0.9821, 1.1705, 1.3386,
+ 1.5375, 1.7226, 1.9053, 2.0991, 2.2898, 2.4953, 2.7000, 2.9146,
+ 0.2332, 0.4561, 0.5407, 0.6212, 0.7524, 0.8215, 0.9522, 1.1685,
+ 1.5216, 1.7132, 1.8291, 2.0647, 2.2811, 2.4857, 2.7071, 2.9281,
+ 0.1348, 0.3126, 0.5179, 0.7192, 0.9227, 1.1363, 1.3223, 1.4756,
+ 1.6509, 1.8191, 1.9991, 2.1976, 2.3877, 2.5768, 2.7590, 2.9386,
+ 0.1093, 0.2211, 0.4763, 0.6703, 0.8282, 0.9536, 1.1202, 1.3796,
+ 1.6043, 1.8031, 1.9832, 2.1604, 2.3578, 2.5856, 2.7650, 2.9291,
+ 0.1865, 0.3027, 0.4580, 0.6719, 0.8400, 1.0082, 1.1901, 1.3782,
+ 1.5448, 1.6885, 1.9477, 2.1381, 2.2797, 2.5113, 2.7465, 2.9414,
+ 0.1575, 0.3124, 0.4649, 0.6262, 0.8095, 0.9858, 1.1676, 1.3602,
+ 1.5646, 1.7582, 1.9550, 2.1671, 2.3628, 2.5734, 2.7670, 2.9519,
+ 0.1174, 0.2777, 0.4663, 0.6333, 0.8169, 1.0096, 1.1885, 1.3847,
+ 1.5803, 1.7571, 1.9380, 2.1398, 2.3414, 2.5407, 2.7360, 2.9375,
+ 0.1073, 0.2264, 0.4083, 0.5973, 0.7474, 0.9514, 1.1349, 1.3337,
+ 1.5433, 1.7348, 1.9380, 2.1436, 2.3441, 2.5438, 2.7457, 2.9383,
+ 0.1472, 0.2880, 0.4793, 0.6268, 0.8015, 1.0063, 1.1715, 1.3644,
+ 1.5525, 1.7410, 1.9258, 2.1227, 2.3214, 2.5149, 2.7148, 2.9196,
+ 0.1414, 0.2565, 0.4349, 0.6111, 0.7695, 0.9496, 1.1212, 1.3265,
+ 1.5218, 1.7209, 1.9015, 2.0887, 2.3158, 2.5077, 2.7233, 2.9421,
+ 0.1252, 0.2667, 0.4454, 0.6431, 0.8371, 1.0124, 1.2110, 1.4160,
+ 1.6240, 1.8242, 2.0047, 2.1974, 2.3902, 2.5778, 2.7637, 2.9481,
+ 0.1321, 0.2565, 0.3846, 0.5847, 0.7578, 0.9259, 1.0637, 1.2239,
+ 1.4690, 1.7346, 1.9750, 2.1882, 2.3712, 2.5509, 2.7280, 2.8885,
+ 0.1437, 0.2930, 0.4428, 0.6156, 0.8045, 0.9638, 1.1450, 1.3138,
+ 1.5144, 1.7355, 1.9469, 2.1534, 2.3414, 2.5452, 2.7353, 2.9334,
+ 0.1692, 0.2770, 0.3831, 0.6100, 0.7825, 0.9302, 1.0690, 1.2481,
+ 1.4615, 1.6799, 1.9165, 2.1739, 2.3435, 2.5349, 2.7520, 2.9163,
+ 0.1235, 0.2489, 0.4354, 0.6343, 0.8236, 1.0066, 1.1908, 1.3474,
+ 1.5656, 1.8275, 2.0620, 2.2548, 2.4135, 2.5913, 2.7639, 2.9334,
+ 0.1090, 0.1961, 0.3854, 0.5701, 0.7024, 0.8843, 1.1393, 1.3785,
+ 1.5940, 1.7797, 1.9442, 2.1740, 2.3853, 2.5773, 2.7727, 2.9406,
+ 0.1560, 0.3477, 0.5011, 0.6287, 0.7612, 0.9896, 1.1510, 1.3420,
+ 1.5435, 1.6816, 1.8731, 2.0651, 2.2613, 2.4999, 2.7027, 2.8971,
+ 0.1459, 0.2416, 0.3833, 0.5450, 0.7916, 0.9223, 1.0662, 1.1953,
+ 1.4029, 1.6616, 1.9320, 2.1459, 2.3386, 2.5081, 2.6799, 2.9195,
+ 0.1546, 0.3854, 0.6184, 0.8460, 1.0599, 1.2428, 1.3906, 1.5550,
+ 1.7388, 1.8945, 2.0757, 2.2386, 2.4014, 2.5705, 2.7574, 2.9400,
+ 0.1080, 0.2307, 0.4112, 0.6067, 0.7725, 0.9467, 1.1285, 1.3205,
+ 1.5348, 1.7609, 1.9937, 2.1878, 2.3583, 2.5515, 2.7199, 2.9049,
+ 0.1482, 0.3178, 0.4983, 0.6342, 0.7783, 0.9880, 1.2019, 1.3404,
+ 1.5223, 1.7296, 1.9211, 2.0943, 2.2928, 2.5008, 2.7136, 2.9224,
+ 0.1145, 0.2910, 0.4891, 0.6492, 0.8126, 0.9530, 1.1180, 1.3155,
+ 1.5054, 1.6893, 1.8899, 2.1188, 2.3389, 2.5512, 2.7313, 2.9224,
+ 0.0939, 0.1689, 0.3250, 0.5792, 0.7698, 0.9245, 1.1574, 1.3865,
+ 1.5959, 1.7977, 1.9821, 2.1528, 2.3326, 2.5540, 2.7553, 2.9179,
+ 0.1243, 0.2474, 0.3923, 0.6199, 0.7908, 0.9379, 1.1497, 1.3734,
+ 1.5582, 1.7420, 1.9539, 2.1385, 2.3240, 2.5277, 2.7311, 2.9178,
+ 0.1961, 0.3748, 0.5176, 0.6387, 0.8169, 1.0477, 1.2124, 1.3869,
+ 1.5604, 1.7225, 1.8770, 2.0837, 2.2960, 2.5103, 2.6945, 2.8862,
+ 0.1295, 0.2403, 0.4149, 0.6189, 0.7913, 0.9130, 1.0832, 1.2787,
+ 1.4860, 1.7112, 1.9502, 2.1348, 2.2776, 2.4982, 2.7431, 2.9522,
+ 0.0160, 0.0362, 0.0097, 0.0057, -0.0014, -0.0073, -0.0046, -0.0064,
+ -0.0121, 0.0019, 0.0149, -0.0440, -0.0479, -0.0382, -0.0480, -0.0182,
+ 0.0170, 0.0114, -0.0298, -0.0175, -0.0033, -0.0354, -0.0510, -0.0025,
+ 0.0307, 0.0351, 0.0338, 0.0420, 0.0138, -0.0175, -0.0102, 0.0053,
+ 0.0084, -0.0003, 0.0412, -0.0027, 0.0145, -0.0039, 0.0083, 0.0400,
+ 0.0001, -0.0262, 0.0055, -0.0082, 0.0348, 0.0433, 0.0137, -0.0024,
+ -0.0055, 0.0262, 0.0521, 0.0349, 0.0185, 0.0076, -0.0319, -0.0561,
+ -0.0460, -0.0253, -0.0097, 0.0163, 0.0184, -0.0037, -0.0480, -0.0371,
+ 0.0628, 0.0665, 0.0296, -0.0057, 0.0253, 0.0227, 0.0350, 0.0692,
+ 0.0545, 0.0218, 0.0094, -0.0449, -0.0372, 0.0005, 0.0258, 0.0118,
+ 0.0285, 0.0760, 0.0822, 0.0527, -0.0299, -0.0049, 0.0170, 0.0195,
+ 0.0136, 0.0286, 0.0289, 0.0139, 0.0054, 0.0152, 0.0244, 0.0028,
+ -0.0056, -0.0260, 0.0307, 0.0572, -0.0087, 0.0088, 0.0062, 0.0000,
+ 0.0125, 0.0000, -0.0292, 0.0820, 0.0872, 0.0646, 0.0346, 0.0076,
+ -0.0022, -0.0253, -0.0567, -0.0188, -0.0336, -0.0673, -0.0549, -0.0166,
+ -0.0259, -0.0140, 0.0040, -0.0029, -0.0430, -0.0531, -0.0253, -0.0019,
+ -0.0071, 0.0393, 0.0072, -0.0327, -0.0236, -0.0235, -0.0177, -0.0186,
+ -0.0280, -0.0201, -0.0077, 0.0383, 0.0418, 0.0321, 0.0294, 0.0169,
+ 0.0468, 0.0301, 0.0133, 0.0363, 0.0516, 0.0937, 0.1240, 0.1404,
+ 0.1325, 0.1178, 0.0999, 0.0251, -0.0037, -0.0495, -0.0703, -0.0219,
+ -0.0261, -0.0304, -0.0204, -0.0372, 0.0355, 0.0131, -0.0093, -0.0099,
+ -0.0069, -0.0034, -0.0065, -0.0208, -0.0231, -0.0117, -0.0211, -0.0243,
+ 0.0046, -0.0107, -0.0070, 0.0123, 0.0230, 0.0152, 0.0164, 0.0412,
+ 0.0619, 0.0858, 0.0862, -0.0056, 0.0125, 0.0182, 0.0347, 0.0388,
+ 0.0456, 0.0407, -0.0249, -0.0460, 0.0206, 0.0299, 0.0253, 0.0207,
+ 0.0177, 0.0238, 0.0253, 0.0030, 0.0042, 0.0020, -0.0081, -0.0136,
+ -0.0290, -0.0042, 0.0122, 0.0051, 0.0107, 0.0228, 0.0211, -0.0068,
+ -0.0436, -0.0299, -0.0078, -0.0779, -0.1157, -0.0679, 0.0172, 0.0150,
+ -0.0051, 0.0081, -0.0512, -0.0616, 0.0576, 0.0799, 0.0803, 0.0336,
+ 0.0001, -0.0298, -0.0747, -0.0115, -0.0101, -0.0170, -0.0050, 0.0174,
+ -0.0290, -0.0601, -0.0150, 0.0121, 0.0165, 0.0230, 0.0028, -0.0317,
+ -0.0165, 0.0356, 0.0451, 0.0120, 0.0321, 0.0084, -0.0058, 0.0122,
+ 0.1935, 0.1802, 0.2195, 0.2410, 0.2201, 0.1915, 0.1840, 0.1935,
+ 0.2213, 0.2079, 0.1858, 0.1974, 0.2239, 0.2173, 0.1840, 0.2120,
+ 0.4912, 0.4777, 0.4607, 0.4395, 0.4426, 0.4388, 0.4416, 0.4345,
+ 0.4239, 0.4331, 0.4522, 0.4423, 0.4475, 0.4387, 0.4525, 0.4446,
+};
+
+static const float lsp22s[] = {
+ 0.0664, 0.1875, 0.4300, 0.6730, 0.8793, 1.0640, 1.2563, 1.4433,
+ 1.6394, 1.8176, 2.0029, 2.1921, 2.3796, 2.5671, 2.7595, 2.9536,
+ 0.2128, 0.4052, 0.5311, 0.6404, 0.7875, 0.8775, 1.0974, 1.3261,
+ 1.5563, 1.6790, 1.8339, 2.1195, 2.3226, 2.4609, 2.6440, 2.8947,
+ 0.2024, 0.3362, 0.4834, 0.6784, 0.9088, 1.0850, 1.2188, 1.4054,
+ 1.6102, 1.7767, 1.9679, 2.1436, 2.3445, 2.5467, 2.7429, 2.9320,
+ 0.1181, 0.2279, 0.4413, 0.6114, 0.7710, 0.9427, 1.1142, 1.2707,
+ 1.4892, 1.7416, 1.9526, 2.1466, 2.3629, 2.5445, 2.7293, 2.9205,
+ 0.1155, 0.2720, 0.4886, 0.6812, 0.8594, 1.0422, 1.2315, 1.4116,
+ 1.6137, 1.8020, 1.9758, 2.1743, 2.3602, 2.5568, 2.7472, 2.9374,
+ 0.1110, 0.3312, 0.4735, 0.5612, 0.7129, 0.8146, 1.0233, 1.3155,
+ 1.5765, 1.7746, 1.9574, 2.1416, 2.3220, 2.5384, 2.7334, 2.9318,
+ 0.1656, 0.3350, 0.4215, 0.5609, 0.6759, 0.8503, 1.1405, 1.4094,
+ 1.6057, 1.6860, 1.7639, 2.0031, 2.2680, 2.5076, 2.7263, 2.9368,
+ 0.1466, 0.3638, 0.4587, 0.5674, 0.7381, 0.8669, 0.9619, 1.1658,
+ 1.4667, 1.7440, 1.9335, 2.1018, 2.3022, 2.5281, 2.7359, 2.9261,
+ 0.1061, 0.2566, 0.4739, 0.6751, 0.8711, 1.0704, 1.2720, 1.4655,
+ 1.6605, 1.8494, 2.0290, 2.2197, 2.4008, 2.5912, 2.7772, 2.9513,
+ 0.1116, 0.2364, 0.3971, 0.6316, 0.8583, 1.0335, 1.1686, 1.3302,
+ 1.5612, 1.7877, 1.9829, 2.2052, 2.3596, 2.5460, 2.7341, 2.9290,
+ 0.2661, 0.4186, 0.5126, 0.6477, 0.8818, 1.1045, 1.2852, 1.4128,
+ 1.5851, 1.7593, 1.9399, 2.1757, 2.3684, 2.5136, 2.6927, 2.9064,
+ 0.1495, 0.2749, 0.4391, 0.6304, 0.8239, 1.0181, 1.1995, 1.3759,
+ 1.5669, 1.7722, 1.9671, 2.1635, 2.3586, 2.5528, 2.7445, 2.9311,
+ 0.0912, 0.1759, 0.3066, 0.5660, 0.8005, 0.9568, 1.1832, 1.4504,
+ 1.6259, 1.7948, 2.0113, 2.2002, 2.3654, 2.5583, 2.7929, 2.9735,
+ 0.1353, 0.2747, 0.4078, 0.5977, 0.7658, 0.9124, 1.1081, 1.3630,
+ 1.5875, 1.7847, 1.9323, 2.1181, 2.3321, 2.5046, 2.7183, 2.9225,
+ 0.1938, 0.4063, 0.4982, 0.6002, 0.7702, 0.9071, 1.1631, 1.3885,
+ 1.6043, 1.8118, 1.9306, 2.0893, 2.2724, 2.4609, 2.6283, 2.8802,
+ 0.1857, 0.3351, 0.4381, 0.6101, 0.7561, 0.8555, 1.0384, 1.3171,
+ 1.5667, 1.6904, 1.7552, 1.9689, 2.2597, 2.5260, 2.7272, 2.9337,
+ 0.1037, 0.2159, 0.4188, 0.6174, 0.8035, 1.0285, 1.2256, 1.4230,
+ 1.6400, 1.8322, 2.0144, 2.1988, 2.3810, 2.5682, 2.7613, 2.9438,
+ 0.1625, 0.2776, 0.4225, 0.6001, 0.7879, 0.9087, 1.0801, 1.2759,
+ 1.4899, 1.7448, 1.9911, 2.1770, 2.3723, 2.5777, 2.7971, 2.9444,
+ 0.2111, 0.3640, 0.5839, 0.7290, 0.8051, 1.0023, 1.2315, 1.4143,
+ 1.5878, 1.7755, 1.9804, 2.1498, 2.3312, 2.5350, 2.7613, 2.9472,
+ 0.1423, 0.2646, 0.4136, 0.6350, 0.8070, 0.9514, 1.1168, 1.3213,
+ 1.5776, 1.7721, 1.9404, 2.1545, 2.3385, 2.5137, 2.7396, 2.9553,
+ 0.1132, 0.2386, 0.4103, 0.5931, 0.7808, 0.9881, 1.1840, 1.3860,
+ 1.6021, 1.7990, 1.9922, 2.1885, 2.3852, 2.5717, 2.7640, 2.9510,
+ 0.1267, 0.2602, 0.3913, 0.5944, 0.7598, 0.9198, 1.0781, 1.2715,
+ 1.5299, 1.7573, 1.9308, 2.1346, 2.3267, 2.5419, 2.7466, 2.9320,
+ 0.2023, 0.3417, 0.4392, 0.6141, 0.7439, 0.8593, 1.1096, 1.3543,
+ 1.5185, 1.6553, 1.7862, 2.0341, 2.2718, 2.4834, 2.7103, 2.9466,
+ 0.1113, 0.2470, 0.3677, 0.5686, 0.7700, 0.9356, 1.0806, 1.2452,
+ 1.4830, 1.7344, 1.9268, 2.1404, 2.3371, 2.5169, 2.7329, 2.9012,
+ 0.1664, 0.3554, 0.5573, 0.7471, 0.9245, 1.0998, 1.2787, 1.4655,
+ 1.6654, 1.8346, 2.0179, 2.2159, 2.4096, 2.5946, 2.7790, 2.9530,
+ 0.1313, 0.2625, 0.4731, 0.6444, 0.8110, 0.9878, 1.1493, 1.3212,
+ 1.5719, 1.8138, 1.9861, 2.1943, 2.3714, 2.5578, 2.7346, 2.9296,
+ 0.1186, 0.3035, 0.5049, 0.6860, 0.8670, 0.9975, 1.1364, 1.3471,
+ 1.5695, 1.7412, 1.9346, 2.1506, 2.3413, 2.5531, 2.7794, 2.9627,
+ 0.1108, 0.2697, 0.4787, 0.6344, 0.7909, 0.9586, 1.1440, 1.3511,
+ 1.5686, 1.7601, 1.9246, 2.1241, 2.3293, 2.5390, 2.7315, 2.9333,
+ 0.0985, 0.2302, 0.3544, 0.5759, 0.7620, 0.9651, 1.1497, 1.3080,
+ 1.5500, 1.7845, 1.9518, 2.1734, 2.3565, 2.5665, 2.7605, 2.9102,
+ 0.1208, 0.2727, 0.4381, 0.5736, 0.7382, 0.8390, 1.0102, 1.2648,
+ 1.5100, 1.7440, 1.9619, 2.1430, 2.3307, 2.5159, 2.7264, 2.9211,
+ 0.1582, 0.2777, 0.4475, 0.6551, 0.8591, 1.0084, 1.1414, 1.3291,
+ 1.5902, 1.7826, 1.9543, 2.1659, 2.3233, 2.5044, 2.6935, 2.9199,
+ 0.1360, 0.2873, 0.4585, 0.6295, 0.7592, 0.9089, 1.0492, 1.2733,
+ 1.5391, 1.7768, 1.9372, 2.1329, 2.3168, 2.5015, 2.6857, 2.8837,
+ 0.0886, 0.1829, 0.3696, 0.6126, 0.8334, 1.0135, 1.2303, 1.4674,
+ 1.6743, 1.8564, 2.0530, 2.2370, 2.3960, 2.5787, 2.7756, 2.9377,
+ 0.2005, 0.3537, 0.4700, 0.6249, 0.7385, 0.9097, 1.1759, 1.3811,
+ 1.5314, 1.6705, 1.8546, 2.1229, 2.3292, 2.5251, 2.7951, 2.9646,
+ 0.1999, 0.3112, 0.4722, 0.7146, 0.8908, 1.0028, 1.1831, 1.3903,
+ 1.6125, 1.7514, 1.9083, 2.1248, 2.3271, 2.5339, 2.6945, 2.8918,
+ 0.1243, 0.2606, 0.4382, 0.5850, 0.7705, 0.9727, 1.1214, 1.3059,
+ 1.5218, 1.7406, 1.9137, 2.1353, 2.3354, 2.5299, 2.7287, 2.9068,
+ 0.1039, 0.2426, 0.4265, 0.6284, 0.8152, 0.9941, 1.2004, 1.4038,
+ 1.5912, 1.7763, 1.9650, 2.1598, 2.3474, 2.5488, 2.7419, 2.9322,
+ 0.1364, 0.2420, 0.3886, 0.5864, 0.7663, 0.8844, 1.0860, 1.3242,
+ 1.5518, 1.7893, 2.0004, 2.1562, 2.3619, 2.5516, 2.7687, 2.9181,
+ 0.1483, 0.2851, 0.4479, 0.6312, 0.7924, 0.9821, 1.1705, 1.3386,
+ 1.5375, 1.7226, 1.9053, 2.0991, 2.2898, 2.4953, 2.7000, 2.9146,
+ 0.2332, 0.4561, 0.5407, 0.6212, 0.7524, 0.8215, 0.9522, 1.1685,
+ 1.5216, 1.7132, 1.8291, 2.0647, 2.2811, 2.4857, 2.7071, 2.9281,
+ 0.1348, 0.3126, 0.5179, 0.7192, 0.9227, 1.1363, 1.3223, 1.4756,
+ 1.6509, 1.8191, 1.9991, 2.1976, 2.3877, 2.5768, 2.7590, 2.9386,
+ 0.1093, 0.2211, 0.4763, 0.6703, 0.8282, 0.9536, 1.1202, 1.3796,
+ 1.6043, 1.8031, 1.9832, 2.1604, 2.3578, 2.5856, 2.7650, 2.9291,
+ 0.1865, 0.3027, 0.4580, 0.6719, 0.8400, 1.0082, 1.1901, 1.3782,
+ 1.5448, 1.6885, 1.9477, 2.1381, 2.2797, 2.5113, 2.7465, 2.9414,
+ 0.1575, 0.3124, 0.4649, 0.6262, 0.8095, 0.9858, 1.1676, 1.3602,
+ 1.5646, 1.7582, 1.9550, 2.1671, 2.3628, 2.5734, 2.7670, 2.9519,
+ 0.1174, 0.2777, 0.4663, 0.6333, 0.8169, 1.0096, 1.1885, 1.3847,
+ 1.5803, 1.7571, 1.9380, 2.1398, 2.3414, 2.5407, 2.7360, 2.9375,
+ 0.1073, 0.2264, 0.4083, 0.5973, 0.7474, 0.9514, 1.1349, 1.3337,
+ 1.5433, 1.7348, 1.9380, 2.1436, 2.3441, 2.5438, 2.7457, 2.9383,
+ 0.1472, 0.2880, 0.4793, 0.6268, 0.8015, 1.0063, 1.1715, 1.3644,
+ 1.5525, 1.7410, 1.9258, 2.1227, 2.3214, 2.5149, 2.7148, 2.9196,
+ 0.1414, 0.2565, 0.4349, 0.6111, 0.7695, 0.9496, 1.1212, 1.3265,
+ 1.5218, 1.7209, 1.9015, 2.0887, 2.3158, 2.5077, 2.7233, 2.9421,
+ 0.1252, 0.2667, 0.4454, 0.6431, 0.8371, 1.0124, 1.2110, 1.4160,
+ 1.6240, 1.8242, 2.0047, 2.1974, 2.3902, 2.5778, 2.7637, 2.9481,
+ 0.1321, 0.2565, 0.3846, 0.5847, 0.7578, 0.9259, 1.0637, 1.2239,
+ 1.4690, 1.7346, 1.9750, 2.1882, 2.3712, 2.5509, 2.7280, 2.8885,
+ 0.1437, 0.2930, 0.4428, 0.6156, 0.8045, 0.9638, 1.1450, 1.3138,
+ 1.5144, 1.7355, 1.9469, 2.1534, 2.3414, 2.5452, 2.7353, 2.9334,
+ 0.1692, 0.2770, 0.3831, 0.6100, 0.7825, 0.9302, 1.0690, 1.2481,
+ 1.4615, 1.6799, 1.9165, 2.1739, 2.3435, 2.5349, 2.7520, 2.9163,
+ 0.1235, 0.2489, 0.4354, 0.6343, 0.8236, 1.0066, 1.1908, 1.3474,
+ 1.5656, 1.8275, 2.0620, 2.2548, 2.4135, 2.5913, 2.7639, 2.9334,
+ 0.1090, 0.1961, 0.3854, 0.5701, 0.7024, 0.8843, 1.1393, 1.3785,
+ 1.5940, 1.7797, 1.9442, 2.1740, 2.3853, 2.5773, 2.7727, 2.9406,
+ 0.1560, 0.3477, 0.5011, 0.6287, 0.7612, 0.9896, 1.1510, 1.3420,
+ 1.5435, 1.6816, 1.8731, 2.0651, 2.2613, 2.4999, 2.7027, 2.8971,
+ 0.1459, 0.2416, 0.3833, 0.5450, 0.7916, 0.9223, 1.0662, 1.1953,
+ 1.4029, 1.6616, 1.9320, 2.1459, 2.3386, 2.5081, 2.6799, 2.9195,
+ 0.1546, 0.3854, 0.6184, 0.8460, 1.0599, 1.2428, 1.3906, 1.5550,
+ 1.7388, 1.8945, 2.0757, 2.2386, 2.4014, 2.5705, 2.7574, 2.9400,
+ 0.1080, 0.2307, 0.4112, 0.6067, 0.7725, 0.9467, 1.1285, 1.3205,
+ 1.5348, 1.7609, 1.9937, 2.1878, 2.3583, 2.5515, 2.7199, 2.9049,
+ 0.1482, 0.3178, 0.4983, 0.6342, 0.7783, 0.9880, 1.2019, 1.3404,
+ 1.5223, 1.7296, 1.9211, 2.0943, 2.2928, 2.5008, 2.7136, 2.9224,
+ 0.1145, 0.2910, 0.4891, 0.6492, 0.8126, 0.9530, 1.1180, 1.3155,
+ 1.5054, 1.6893, 1.8899, 2.1188, 2.3389, 2.5512, 2.7313, 2.9224,
+ 0.0939, 0.1689, 0.3250, 0.5792, 0.7698, 0.9245, 1.1574, 1.3865,
+ 1.5959, 1.7977, 1.9821, 2.1528, 2.3326, 2.5540, 2.7553, 2.9179,
+ 0.1243, 0.2474, 0.3923, 0.6199, 0.7908, 0.9379, 1.1497, 1.3734,
+ 1.5582, 1.7420, 1.9539, 2.1385, 2.3240, 2.5277, 2.7311, 2.9178,
+ 0.1961, 0.3748, 0.5176, 0.6387, 0.8169, 1.0477, 1.2124, 1.3869,
+ 1.5604, 1.7225, 1.8770, 2.0837, 2.2960, 2.5103, 2.6945, 2.8862,
+ 0.1295, 0.2403, 0.4149, 0.6189, 0.7913, 0.9130, 1.0832, 1.2787,
+ 1.4860, 1.7112, 1.9502, 2.1348, 2.2776, 2.4982, 2.7431, 2.9522,
+ 0.0160, 0.0362, 0.0097, 0.0057, -0.0014, -0.0073, -0.0046, -0.0064,
+ -0.0121, 0.0019, 0.0149, -0.0440, -0.0479, -0.0382, -0.0480, -0.0182,
+ 0.0170, 0.0114, -0.0298, -0.0175, -0.0033, -0.0354, -0.0510, -0.0025,
+ 0.0307, 0.0351, 0.0338, 0.0420, 0.0138, -0.0175, -0.0102, 0.0053,
+ 0.0084, -0.0003, 0.0412, -0.0027, 0.0145, -0.0039, 0.0083, 0.0400,
+ 0.0001, -0.0262, 0.0055, -0.0082, 0.0348, 0.0433, 0.0137, -0.0024,
+ -0.0055, 0.0262, 0.0521, 0.0349, 0.0185, 0.0076, -0.0319, -0.0561,
+ -0.0460, -0.0253, -0.0097, 0.0163, 0.0184, -0.0037, -0.0480, -0.0371,
+ 0.0628, 0.0665, 0.0296, -0.0057, 0.0253, 0.0227, 0.0350, 0.0692,
+ 0.0545, 0.0218, 0.0094, -0.0449, -0.0372, 0.0005, 0.0258, 0.0118,
+ 0.0285, 0.0760, 0.0822, 0.0527, -0.0299, -0.0049, 0.0170, 0.0195,
+ 0.0136, 0.0286, 0.0289, 0.0139, 0.0054, 0.0152, 0.0244, 0.0028,
+ -0.0056, -0.0260, 0.0307, 0.0572, -0.0087, 0.0088, 0.0062, 0.0000,
+ 0.0125, 0.0000, -0.0292, 0.0820, 0.0872, 0.0646, 0.0346, 0.0076,
+ -0.0022, -0.0253, -0.0567, -0.0188, -0.0336, -0.0673, -0.0549, -0.0166,
+ -0.0259, -0.0140, 0.0040, -0.0029, -0.0430, -0.0531, -0.0253, -0.0019,
+ -0.0071, 0.0393, 0.0072, -0.0327, -0.0236, -0.0235, -0.0177, -0.0186,
+ -0.0280, -0.0201, -0.0077, 0.0383, 0.0418, 0.0321, 0.0294, 0.0169,
+ 0.0468, 0.0301, 0.0133, 0.0363, 0.0516, 0.0937, 0.1240, 0.1404,
+ 0.1325, 0.1178, 0.0999, 0.0251, -0.0037, -0.0495, -0.0703, -0.0219,
+ -0.0261, -0.0304, -0.0204, -0.0372, 0.0355, 0.0131, -0.0093, -0.0099,
+ -0.0069, -0.0034, -0.0065, -0.0208, -0.0231, -0.0117, -0.0211, -0.0243,
+ 0.0046, -0.0107, -0.0070, 0.0123, 0.0230, 0.0152, 0.0164, 0.0412,
+ 0.0619, 0.0858, 0.0862, -0.0056, 0.0125, 0.0182, 0.0347, 0.0388,
+ 0.0456, 0.0407, -0.0249, -0.0460, 0.0206, 0.0299, 0.0253, 0.0207,
+ 0.0177, 0.0238, 0.0253, 0.0030, 0.0042, 0.0020, -0.0081, -0.0136,
+ -0.0290, -0.0042, 0.0122, 0.0051, 0.0107, 0.0228, 0.0211, -0.0068,
+ -0.0436, -0.0299, -0.0078, -0.0779, -0.1157, -0.0679, 0.0172, 0.0150,
+ -0.0051, 0.0081, -0.0512, -0.0616, 0.0576, 0.0799, 0.0803, 0.0336,
+ 0.0001, -0.0298, -0.0747, -0.0115, -0.0101, -0.0170, -0.0050, 0.0174,
+ -0.0290, -0.0601, -0.0150, 0.0121, 0.0165, 0.0230, 0.0028, -0.0317,
+ -0.0165, 0.0356, 0.0451, 0.0120, 0.0321, 0.0084, -0.0058, 0.0122,
+ 0.1935, 0.1802, 0.2195, 0.2410, 0.2201, 0.1915, 0.1840, 0.1935,
+ 0.2213, 0.2079, 0.1858, 0.1974, 0.2239, 0.2173, 0.1840, 0.2120,
+ 0.4912, 0.4777, 0.4607, 0.4395, 0.4426, 0.4388, 0.4416, 0.4345,
+ 0.4239, 0.4331, 0.4522, 0.4423, 0.4475, 0.4387, 0.4525, 0.4446,
};
static const float lsp44s[] = {
@@ -4442,7 +13465,7 @@
0.4534, 0.4468, 0.4412, 0.4354, 0.4298, 0.4272, 0.4498, 0.4506,
0.4560, 0.4592, 0.4758, 0.4941, 0.2476, 0.1771, 0.1974, 0.1881,
0.1667, 0.1826, 0.2067, 0.2031, 0.1734, 0.1534, 0.1415, 0.1761,
- 0.1897, 0.1772, 0.1651, 0.1247, 0.1041, 0.1231, 0.1809, 0.2234
+ 0.1897, 0.1772, 0.1651, 0.1247, 0.1041, 0.1231, 0.1809, 0.2234,
};
static const int16_t shape8[] = {
@@ -4608,6 +13631,495 @@
991, 3527, -281, -6050, -1251, 1802, 8, -3916,
};
+static const int16_t shape8s[] = {
+ 2639, 550, 6487, 2812, 1014, 1926, 2959, 757,
+ -1452, -111, -45, -409, 401, 545, 1545, -1677,
+ 75, -607, -3658, -368, -4486, 272, 6017, -468,
+ 1108, 1056, 606, -3288, 1003, -830, -336, -2940,
+ 247, 227, 1700, 338, -161, 5694, 317, -584,
+ 6278, -2902, -3862, 293, -3400, 540, 177, -840,
+ -471, 963, -243, -289, 77, 39, 7626, 333,
+ 577, 327, -359, 999, -392, 107, 1410, 509,
+ -983, 36, -193, -68, -7612, -775, -178, 1415,
+ 1069, 1534, -1276, 1204, 615, 2065, 499, 124,
+ 265, -454, 1974, 6428, -4028, 1102, -1418, -85,
+ -816, -64, -46, 926, -960, 78, 4823, -41,
+ -74, -682, -761, -6598, 3084, -1597, 2945, -861,
+ -3203, -669, -3717, -310, -2865, -1447, 72, 1987,
+ 364, 4919, -247, 3678, -196, -6807, -127, -965,
+ 233, -133, 4000, -76, -182, 3825, 67, 700,
+ -1934, 545, -2467, -1441, 629, 3409, 512, -3333,
+ 539, -4896, 3413, -2083, 554, 574, 9430, 296,
+ -88, -533, -321, -1082, 2363, 42, -50, -5402,
+ -123, 4458, 1130, 2737, 378, 1509, -3267, 970,
+ 179, -2114, 602, 479, -438, 277, -9389, 1144,
+ 2453, -3705, -3842, 3965, 482, 1230, 2211, -281,
+ -1833, -1741, 1653, -868, 485, -3740, 5371, 989,
+ 1182, 10, -1812, 233, 1028, -3300, 4698, 1572,
+ 1580, 928, -314, -3452, 830, -1511, -1079, 554,
+ 641, 1383, 105, -1101, 1549, -3944, 902, -6557,
+ 493, -3117, 782, -699, -4806, 910, -259, -28,
+ 1713, -7012, 570, -1270, -4698, -8, 220, -4295,
+ 1135, -3905, 945, -467, -2164, -651, 181, 212,
+ 159, 587, 1587, 1101, -7153, -309, -1470, -1135,
+ -265, -326, 172, 8840, 726, -780, 170, -1038,
+ 466, 216, 764, 231, -547, 2456, -420, 8132,
+ 486, 866, -359, 3351, -1829, 2018, -352, -1353,
+ 711, 645, 1149, 74, -466, -669, 1009, 3086,
+ 240, 7468, -182, 1947, -221, 496, -448, 189,
+ -113, -752, 133, -214, -1310, -144, -1034, 5235,
+ -1939, -2664, 192, 1526, -2320, 762, -778, 357,
+ 1251, 424, -225, -1008, -229, -352, -3559, -271,
+ -1069, 1274, -175, 368, 6453, -505, 31, 7678,
+ 165, -418, -112, -649, 1421, 667, -334, 1041,
+ -353, 585, 4109, 1095, 5283, 685, -687, -1459,
+ 1054, 5048, -194, 2220, 81, 244, 3789, 12,
+ -923, -1459, 319, 2378, -53, 4097, -662, -1156,
+ 223, 2589, -547, 4951, -346, -1812, -111, 344,
+ 5247, 387, -459, -810, 1022, 234, 726, 1840,
+ -545, -888, 728, 106, 1027, -497, 349, -248,
+ 11173, -311, 126, 479, -2036, 265, -1286, -7196,
+ -511, 128, -1833, 496, 7620, 2539, -1809, 962,
+ -614, -876, 857, 2178, 642, -1180, -2294, 911,
+ 3932, 711, -1073, -1381, -5317, 237, -414, 579,
+ -78, -27, -78, -14, 100, -191, 142, -1,
+ 430, -182, 207, -61, -72, -4866, 583, 5099,
+ -704, -1496, 1065, -206, 2371, 1496, 1777, -308,
+ 4802, -1415, 1178, 2650, 312, -338, -250, -64,
+ -27, -3163, -561, -1283, 952, -902, 354, 1597,
+ -74, -685, -3266, -873, -744, 7079, 732, 697,
+ 550, -1362, 251, 34, -742, 0, 105, -608,
+ -1, 10459, 854, -103, -419, 2286, -3041, -3278,
+ -51, -491, -187, 4204, 857, -1085, -2501, -1647,
+ 6740, 605, -2079, 1748, 519, 3462, 106, -699,
+ 220, -615, -406, 420, 786, 572, 679, 218,
+ -888, 10283, 129, -2286, -705, -78, 5072, 634,
+ 702, -6315, -551, -307, -7946, 177, -1897, -579,
+ 1620, 125, 116, -89, -308, -1018, 142, -506,
+ -624, 917, -779, 632, -5103, 314, -155, 5687,
+ 77, -144, 2957, -176, 30, 1347, -426, -51,
+ 7829, 1201, -592, 1, 4617, -5476, 2216, 414,
+ 1281, -81, -423, -322, 3623, 447, 863, -375,
+ -489, 526, -485, 159, 1090, 463, 401, -131,
+ 223, 1630, -2462, -2261, 623, 1019, 6385, -595,
+ -654, -2787, 2381, 328, -2069, 5410, -402, -554,
+ -1594, -860, 83, -5011, -938, 1061, 163, -3523,
+ -1064, 1215, 761, 1604, -4224, 904, -2706, 4907,
+ -1838, 3287, -3118, -464, -217, -1187, -6792, 1748,
+ -569, 613, -3177, -253, 164, -845, 539, -440,
+ -1871, -2010, -2322, -3026, 478, 2297, -560, -5813,
+ 768, -1709, -620, 66, -4667, 805, -215, 5366,
+ -442, -233, -6732, 345, 106, 4483, 1720, 2725,
+ -109, 2746, -188, 204, 1905, 1225, 253, 3270,
+ 1912, -1852, -256, -4131, 768, 3984, 473, -1434,
+ 4380, 208, 2547, 1051, 3347, -171, 629, -2389,
+ -722, -759, 166, 2192, 325, -193, -289, -945,
+ -436, 931, 1352, 6918, -2707, -987, 2940, 3574,
+ 4135, -3205, 351, 927, 128, -1873, -4894, -4816,
+ -461, 696, -1618, 129, -28, 2195, 2450, 585,
+ 2557, -1308, -2204, -590, 2345, 3699, -312, 4436,
+ 3422, -611, -106, -2647, -1752, -73, 8914, -673,
+ 1625, 850, 720, -1182, -245, -113, 882, -223,
+ -4873, -1009, 5643, -97, -4779, -155, 444, 2894,
+ -876, -5534, 1268, -132, -881, -389, -4250, -153,
+ -44, 986, 1820, 8671, 662, -344, -198, -1909,
+ 1083, 114, -318, 1070, -3293, -375, 6621, 232,
+ -2973, -100, -483, -529, -120, -5312, 1702, 651,
+ -631, 485, 5675, 50, 1132, -465, -1053, 2675,
+ -1592, 5565, 1036, -2808, 325, 999, 524, 2813,
+ -265, 337, 4226, 514, 576, 6047, 175, 204,
+ -514, -617, -94, -2862, -294, 1774, 978, -7040,
+ -169, 835, -829, 2258, -37, -319, 2750, 138,
+ -289, -1092, 78, 1032, 4316, -1201, 808, -6243,
+ -940, 4136, 89, -1076, -647, -255, -207, 227,
+ -70, -62, -202, 66, 24, -988, -9542, -225,
+ -739, 161, -2698, 117, -608, 173, -629, 1770,
+ 5037, 5145, 2530, -1028, 3077, -496, 4671, -1859,
+ 2148, 447, -4231, 170, 713, 323, 746, 1447,
+ -1880, 5069, 7765, -492, -775, -659, -770, -59,
+ -258, -92, -1683, -4639, -1727, -2128, 545, -5060,
+ 2536, 1549, 492, -1280, -6034, 965, 3244, 475,
+ -1208, 680, -283, 295, -357, -257, 1753, -362,
+ 3159, 106, -181, 1805, 947, -1002, -136, 756,
+ 1189, 237, -2427, -263, -5746, 13, 2171, -1197,
+ -319, -372, -1300, 5458, 955, 1224, 618, -1087,
+ 2661, -2026, -20, 2137, 342, 4076, 482, 5441,
+ -6, 2126, -143, -1596, 274, 1009, 94, -3446,
+ 398, 1079, 289, 2042, 883, -2005, -320, 3848,
+ 395, 472, 615, 3245, 753, -1881, -216, 5670,
+ -64, -565, -2560, 1574, 772, -3824, 932, 4830,
+ 1182, -1054, 390, -40, 1833, -350, 151, 149,
+ -966, -62, -713, -8794, -593, 87, -3523, -243,
+ 560, -3296, 244, -775, 7174, 749, -271, 8566,
+ 99, 1258, 1239, -489, -107, -1699, -611, 1046,
+ 65, -509, 524, -354, 6400, -248, 148, -682,
+ -93, -1584, -61, 4509, 479, 110, 7116, -295,
+ 480, 1545, 3, 127, -2292, 894, 1261, -6288,
+ -45, -410, -402, -356, 2649, 649, 1652, -643,
+ 6587, 117, 876, -33, 956, -302, 1619, -1023,
+ -99, 386, -86, -498, 684, 1189, 146, 381,
+ 9832, -97, 264, 91, -1197, 461, 374, -6788,
+ 427, 294, -4776, 0, 2868, 5199, 4573, -827,
+ -1867, 623, -1214, -573, -1099, -1476, 306, -701,
+ -224, -4261, -1135, 2500, -4758, 1469, -101, 1812,
+ -129, 15, 760, -149, -892, -1417, 761, 1213,
+ -417, 1569, -98, 1675, -139, -7382, -633, 2584,
+ -519, -5483, 29, 320, -383, -596, -295, -357,
+ -416, 4054, -457, -355, -5213, -840, -319, 1321,
+ -424, -129, 5225, 181, -2696, -174, -7363, -327,
+ 519, 860, -5132, 275, -141, 4943, 204, -200,
+ 2989, 939, 390, -461, -333, -394, -174, 312,
+ -129, 7257, -402, 860, -1, 2677, 901, 609,
+ 248, 935, -493, 8147, 2081, -1171, -2145, 1560,
+ 1634, 55, -1746, 561, -747, 931, -712, -544,
+ 798, -98, 580, -829, -546, 238, -2052, -197,
+ 802, 13067, 373, -6438, 1159, -845, 4313, 19,
+ 670, -627, -944, 1277, -6997, -609, 1913, 607,
+ -454, -89, 859, -43, -71, 494, 169, -713,
+ -2014, 1570, -4712, 233, -4113, 210, -3689, 1019,
+ 200, 49, 1800, -611, -472, 1234, 579, 363,
+ -134, 233, 101, -5539, 1924, -1734, -982, -928,
+ -707, -1238, 1586, 3676, 4741, -2770, 3105, 942,
+ -1933, 1363, 288, -2528, 160, 485, -38, 23,
+ 113, -19, -518, -110, -173, -170, 589, -473,
+ 296, -3742, 1109, -2977, 1349, 5899, 98, 3130,
+ 855, 499, 3, -3111, -592, 572, -890, 687,
+ 697, 194, -344, 1139, 3255, 1270, -2451, 1958,
+ -395, 267, -951, -2224, 2108, -11, -3357, 2602,
+ 2403, 1596, -532, 2701, 2251, -1217, -2148, 691,
+ -757, -2051, 373, 1964, 1493, 4756, 1246, -4345,
+ -496, -1333, -20, -84, -1558, 305, 1183, 8148,
+ -628, -702, -1730, 232, -261, 2732, 245, 353,
+ -3745, 1013, 186, -2042, 810, -3894, 351, 2501,
+ 852, 4162, -425, -4941, -1536, 2237, 1348, -4274,
+};
+
+static const int16_t shape11[] = {
+ 347, -5391, 106, 156, -182, -36, 177, 401,
+ 700, 524, -1343, -402, -6982, 63, 194, -14,
+ 82, -36, -677, -393, 187, 7364, -507, -1173,
+ -759, -3759, -728, 2970, 1334, 32, -1322, -2965,
+ 156, -839, 382, -6382, -149, 874, 1352, -35,
+ -499, 99, -425, -3118, -32, -1596, 5608, -822,
+ -41, 2974, -592, 615, 1777, 2364, 5189, -4171,
+ -581, 936, -527, 318, -1606, -551, 5350, -448,
+ -40, 7476, 189, 319, -1390, 10, -921, 10016,
+ 573, -1065, 829, -1190, -22, -4263, 87, -1742,
+ -325, 313, -188, 540, -5542, -188, 511, -168,
+ -518, 17, 152, 1966, -2568, -860, 2735, -1210,
+ 404, -144, -6873, -129, 434, -2978, 2829, -48,
+ -9196, -1829, -11261, 1492, -4938, 1802, 93, 384,
+ 1340, 236, 10066, 731, 861, -195, -7571, -77,
+ -481, -700, 4694, -734, -6317, 281, 1773, 175,
+ -5535, 532, 31, 7012, -637, -3586, 1096, 3596,
+ -197, -7837, -611, 1825, -26, -259, 2307, 12,
+ 729, -1958, 156, 262, 5494, 26, -5792, -3146,
+ 450, -1075, 297, 509, 154, 668, 191, -268,
+ -1585, 369, 1314, -693, 677, 1482, 198, 378,
+ 11088, -83, 2321, -193, -1082, -3053, 20, -271,
+ 12975, 272, 1114, 476, -798, -309, -159, 5406,
+ -109, -675, 621, -2564, 11190, -1342, -88, 428,
+ -465, -4633, -503, 106, -9448, -454, -28, -402,
+ 1271, -7972, 754, -207, -2491, 518, -3701, -542,
+ -1268, -617, -177, 467, -130, 990, 4087, 857,
+ -524, -5822, 145, 217, -7703, -275, 6647, -81,
+ 550, 887, -433, -802, 532, 643, 188, 1965,
+ -920, -284, 3711, 1196, -8896, -357, -626, 908,
+ -284, -706, -1582, 182, 7705, -138, -2372, -158,
+ -888, 4247, 4381, -6722, -1619, -1810, 632, -1176,
+ -62, 4261, -89, 265, 1405, -1449, -389, -7068,
+ 258, -244, -272, -8149, 37, -457, -8839, 3243,
+ -4291, -396, -3935, 907, -58, 2388, -908, -1209,
+ -635, -487, -1717, 6989, -4834, 2136, -822, -699,
+ 2187, -96, -9775, -3464, 795, 634, -823, -669,
+ 146, -843, 15, -227, 671, -707, -10004, 198,
+ 81, -1611, -34, -2127, -2385, -689, 622, 1834,
+ -63, -4925, -215, -1181, -514, 7701, 607, 2030,
+ -264, 2479, 913, 178, 3625, -194, 613, 877,
+ -384, -7732, 1008, 2117, 528, -301, 540, -80,
+ 559, 28, 7542, -496, 1146, -6573, -1457, 7789,
+ -227, -1671, -76, -371, -865, -141, 42, 96,
+ 277, -410, -5606, 328, -8954, -222, -1792, 981,
+ -120, -650, 2269, -1412, 1038, -186, -8530, -264,
+ 2284, -727, 1511, -4611, -1653, 1985, -50, -8985,
+ -245, -3315, 407, -915, -23, -70, 30, -669,
+ -303, 902, 84, 433, 217, -8303, 7847, -1865,
+ -680, 254, -38, 364, 16, 50, 90, -534,
+ -4649, -800, 969, -1081, 454, 147, -62, 8797,
+ 84, -912, -518, -351, 76, -560, -1438, 629,
+ 16384, 656, 151, 880, 396, -90, 752, -138,
+ -861, 9605, 258, -440, -6441, 434, 5765, 282,
+ 1494, -260, -180, -769, 7867, -86, 536, -262,
+ -230, -8956, 5857, -591, 1533, 418, -505, -156,
+ 1165, 415, -168, -1504, -336, -667, 527, 5725,
+ 42, 429, 1691, 1, 85, -196, 3681, 36,
+ 469, -364, 559, 910, -1848, 259, 249, -1688,
+ 261, -36, -592, -156, -69, -5938, -180, -294,
+ 22, -903, 1389, 4853, 121, 5185, 970, 1210,
+ 561, 926, 472, -183, 6623, 357, -78, -5877,
+ 91, -188, -6746, -146, 342, -5648, 3697, 1336,
+ 728, -69, 398, 2667, -2103, 1901, -807, 258,
+ 72, -137, 341, 71, -169, -104, -83, 206,
+ -420, 1187, 744, 120, -5151, -574, 72, -8553,
+ -312, 140, -69, 6067, 5229, 202, -1722, -164,
+ 73, 1695, -1064, 234, 24, 4881, -849, -460,
+ 8641, -328, -1217, 1666, -283, -76, 2772, 401,
+ 843, -4756, 297, 8593, 367, -732, -225, -198,
+ -3936, 248, -436, 473, -19, -441, 164, 220,
+ -266, 3, 106, -244, -5814, 597, -666, -245,
+ -9298, -867, -480, 280, -40, -139, -6378, -4972,
+ -886, 3062, 747, -1991, -1668, -423, 534, 866,
+ -73, -6501, -195, 324, -51, -123, 298, 500,
+ 193, 278, -8503, -297, 1034, -16, -209, 7451,
+ 521, -305, -297, -1537, -3025, 689, 248, 319,
+ 5393, 1497, 2228, -773, -141, 2184, 1024, -4535,
+ -9160, -600, -932, -2145, -539, 460, -1943, 4265,
+ -2512, 4416, -304, 1744, 489, -362, 898, 2236,
+ -2224, 49, -192, 332, 366, -143, 329, -7747,
+ -4, 1075, 116, 551, 19, -7, 7090, -169,
+ 837, -71, -371, 451, -31, 474, 867, -421,
+ -4544, 78, 3208, -549, 1984, 1386, -2208, -1402,
+ 1616, 189, -37, -6953, -5733, 1589, -1314, 1040,
+ -1480, -5608, 2627, 3517, 250, 7930, 94, 4687,
+ 1522, 5543, -130, -462, 7613, -654, 647, -6187,
+ 139, 342, 5069, -729, 128, 17, -49, 176,
+ 122, 826, 503, 76, -196, 15583, 12884, 746,
+ -3942, 814, -1744, 1774, -338, 3089, -1694, 559,
+ -5355, 2834, -1448, 108, -329, -711, 350, 171,
+ 297, -123, 672, 625, -5884, 6822, 842, 276,
+ 242, -2254, -623, -846, 2441, 887, -2066, -1019,
+ 1329, 107, -83, 826, -67, -352, 549, 137,
+ -1023, -184, -11, 13790, 48, 883, 3538, -533,
+ -5553, 861, 738, -436, -5259, -66, -405, 3777,
+ -574, 738, 253, 363, -76, 288, 324, -337,
+ 157, -119, -97, 171, 514, -1932, -5171, 579,
+ 249, 1072, -204, -194, -311, 655, -6728, 186,
+ -178, 99, 5749, -329, 419, 924, -1131, 598,
+ -15, -103, -2277, 186, -716, -542, 153, -226,
+ 5689, 219, 52, 3706, -917, 140, -10576, -151,
+ 1060, 645, 404, 1310, 331, 216, -1413, -6030,
+ -5069, -3992, 1366, 932, 1559, -87, 7799, 3854,
+ 3762, -1043, 474, 1184, 102, -2775, -1199, -1079,
+ 358, -63, 9784, 141, 3947, 194, -132, -332,
+ -512, -212, -5839, -227, 7759, 807, -597, -1782,
+ -148, -352, -1225, -692, 147, -1970, 3508, -947,
+ 3463, -197, 4737, -698, 578, -172, -775, 8167,
+ 3102, 883, -914, 16, 827, 114, -1916, -909,
+ -606, 87, 1036, -435, 102, 96, -370, -204,
+ -11952, 21, 477, 1285, 6281, 855, -7717, 1155,
+ -501, -597, 5943, 145, -630, -3406, 13, -4211,
+ 679, 6570, -231, -6042, -503, -194, 1437, 5640,
+ -1222, 8181, 386, -986, -503, 1221, 839, 763,
+ -277, -1787, -1491, 5, -206, 42, 2800, -332,
+ -2841, -143, -456, 646, -668, -117, 883, 86,
+ 7111, -270, 624, -1133, -308, -479, -9149, -1424,
+ 242, -12048, 8, 2307, -6530, -529, 462, -1346,
+ -153, 4315, -182, -675, -78, -480, -49, 398,
+ -408, -1440, 8196, 436, -561, -184, 175, 1799,
+ -154, -439, -721, 2170, 322, 6555, -539, -1672,
+ -629, -2985, 239, -37, 7544, -1048, -1241, 7241,
+ -636, 2044, -750, 1206, 1363, -530, -5960, 342,
+ -7440, 616, 372, 4572, -118, 343, 1086, 570,
+ -164, 553, -433, 562, 33, 8225, -235, -234,
+ 1230, 234, 906, 563, -73, 10464, -353, -644,
+ -1453, 1119, 237, 670, -112, 7083, -451, 3410,
+ -105, 3244, -1331, 102, 738, -3602, 76, 413,
+ -318, 10, -5471, 1024, -335, 246, -7820, -164,
+ 2515, -1411, 673, 6022, 50, -6715, 268, 2152,
+ -951, -60, 234, -2085, 342, 3002, -169, 2473,
+ -667, -6846, 870, 5467, 150, -66, -4294, -299,
+ -612, -3859, 177, 353, -4726, 547, 340, -5646,
+ -2022, 117, -4949, -303, 280, -266, -361, 673,
+ -139, -5, -7123, -264, 243, -5245, 351, 656,
+ 5005, 682, -107, 298, -79, 1407, -449, -797,
+ -669, -552, -242, -8013, 56, 4092, 1583, -3981,
+ -49, -7972, 390, 366, -31, 1126, 272, 5120,
+ -10, 1147, -3682, -155, 252, 163, 455, 358,
+ -746, -2719, -431, 444, -433, 432, -357, 5370,
+ 328, -3, 1748, 514, 7198, -527, 172, 401,
+ -59, -3586, 1443, 534, 1029, 539, 3723, 5392,
+ -6619, -2559, 2344, 282, -980, 97, -317, -786,
+ 475, -8646, 307, 447, -3107, 211, -56, 3344,
+ -1549, -9223, 454, 352, -27, 205, 503, 260,
+ -372, -631, -1165, -6543, 444, 1535, 404, -1752,
+ -43, -9381, 754, -94, -7134, 2064, 170, 8222,
+ -280, -1250, -347, 1688, -1203, 239, -1048, -4570,
+ -4720, -434, -1008, -4151, -2211, -1414, -506, -5411,
+ 5379, 984, 4587, -63, 143, 968, -203, 5315,
+ 591, -756, 1228, -372, 703, 6829, -76, 6935,
+ 467, 3119, -2, -3825, 175, -4000, -3012, -7745,
+ -832, -2582, 173, 1992, 3768, 275, 39, 603,
+ -536, 5851, 474, 254, -72, 1286, -836, 5576,
+ 1357, 3524, 406, -9214, -554, 3974, -352, 1763,
+ -482, 658, 1628, 3885, 1938, 6172, 1693, -5183,
+ 150, -6729, 1238, 1062, -10035, -428, 48, 421,
+ -185, 659, -426, -633, 131, -741, 462, -463,
+ -391, -193, -270, -682, -343, -12130, -86, -148,
+};
+
+static const int16_t shape11s[] = {
+ 22, -5296, -415, -206, 306, 265, 189, 376,
+ 721, -1503, -429, -538, -6008, -97, -385, -570,
+ -313, -1469, -219, -1661, 10, 6256, -1230, -635,
+ -28, -4208, -344, 394, 138, 1174, -170, -822,
+ 114, -1087, -101, -7362, 84, 862, 1514, 341,
+ -115, 320, -120, -1625, 55, -719, 1443, -733,
+ -577, 7197, 148, 26, 120, 1969, 4940, -3777,
+ -607, 1675, 64, -634, -84, 334, 6882, -644,
+ -232, 5008, -316, -164, -138, -16, 15, 9441,
+ -74, -65, 262, 834, 1143, -101, 434, -329,
+ 123, -204, -45, 147, -4586, -742, 464, 1412,
+ 548, -1602, -56, 1356, -771, 263, 709, -481,
+ -193, 345, -8395, -41, 36, -1900, -178, 816,
+ -7590, 31, -3011, -371, -2698, 2234, -99, 0,
+ 714, -845, 9357, 701, -1269, -187, -4227, -450,
+ -73, -1637, 4679, -138, -4470, 356, 1416, 1462,
+ -3162, 453, -61, 5243, -241, -2385, 438, 4919,
+ -252, -3781, 150, 335, 58, -185, 1870, 179,
+ 192, -2572, -454, 77, 4819, 1891, -4843, -2106,
+ -472, -3842, 167, 1092, -671, 194, -870, 139,
+ -115, -455, 452, -519, 299, 1024, 330, -99,
+ 11189, 82, 57, -849, 167, -4190, 639, 768,
+ 7477, 626, 94, -1259, -303, 181, -280, 2873,
+ -589, -461, 1591, -29, 6940, -1264, 120, -282,
+ -159, -3755, -4, -61, -10172, 152, -12, -200,
+ 111, -8471, -243, 400, -842, 1661, -3099, 500,
+ -451, -423, -193, 230, 423, 263, 5011, 1010,
+ 1044, -4781, 707, 84, -6091, -213, 5193, 434,
+ 534, 1100, -520, -1590, 75, -322, 2, 2008,
+ -534, 153, 2641, 1510, -6830, -246, 4, 271,
+ 75, -1308, -1934, -257, 6748, 589, -301, 627,
+ 1197, 3708, 4450, -5582, -1312, -2859, 881, 429,
+ 552, 738, -882, 984, 488, -868, -464, -6969,
+ 721, -2078, 417, -6121, -184, -128, -7840, 2659,
+ -2584, -254, 176, -790, -727, 482, 357, 104,
+ -441, -158, -980, 4563, -4098, 1086, -1217, -562,
+ 2033, 512, -8331, -3506, -73, 808, -372, -1602,
+ 748, 911, -599, -1499, 58, 309, -10000, -115,
+ 70, 1603, 280, -146, -817, 517, 18, 1355,
+ -121, -4134, 152, -1300, 247, 7258, 415, 130,
+ -27, 2108, 337, -816, 2480, 396, 533, 66,
+ -171, -6213, 47, 3081, -648, -930, 1810, -233,
+ -433, -588, 5526, 58, -18, -3498, -381, 8009,
+ 7, 1229, 152, -410, -567, 423, -354, 463,
+ -82, -146, -2868, 271, -5773, 2694, -1006, 150,
+ -113, -521, 2553, -278, 593, -69, -6517, -785,
+ 369, -2483, -216, -3144, -889, 1724, -168, -6303,
+ 171, -1895, -798, -137, -172, -746, -54, 162,
+ -607, 409, 201, -284, -143, -10681, 7747, -1148,
+ 303, 58, 4, -96, -485, -146, -286, -577,
+ -644, -512, 236, 576, 421, 93, 293, 10284,
+ -2, -117, -590, -546, 350, 445, -301, -300,
+ 10823, -224, -96, -551, -148, 1042, -125, 224,
+ -706, 8583, -195, 52, -2732, 200, 4419, 390,
+ 870, 100, -184, 233, 6179, -317, -472, 1964,
+ -302, -8722, 2509, -644, 488, -3101, 891, -253,
+ -38, 133, -15, -1365, -779, -612, 673, 5587,
+ 834, 377, 835, -2018, 75, -185, 3641, 121,
+ 693, 63, 503, 646, -7, 348, 141, -1311,
+ 532, -513, 95, -315, -65, -6478, -16, -848,
+ -210, -120, 676, 5125, 533, 4147, -622, -4,
+ -150, -1507, -124, -185, 5365, 267, 1073, -4479,
+ 173, -204, -4164, -952, -23, -4088, 1391, 205,
+ 712, -473, -373, 547, -685, 4542, -49, -71,
+ 33, -271, 132, 246, -188, 6, -309, 118,
+ 96, 1774, 158, -83, -3573, 1175, -122, -6619,
+ -1677, -1161, -266, 4776, 3453, 62, -346, -450,
+ -1380, 103, -457, -1260, -71, 4271, -338, -1394,
+ 6462, 395, 647, 2430, -735, 444, 1837, 403,
+ 144, -5573, 211, 4608, -15, 804, 70, 1969,
+ -3451, -138, -352, 1176, -171, -518, -114, -88,
+ 335, -308, -64, -428, -4115, 318, -205, -126,
+ -7854, -609, 105, 144, 270, 266, -4543, -5246,
+ -311, 587, 305, -115, 372, 727, -294, 414,
+ 877, -7899, 411, -538, 394, 535, 233, -826,
+ 329, 491, -4848, -650, 331, 1026, -140, 6474,
+ 194, -457, 98, -871, -2293, 873, 353, 812,
+ 4510, 1102, 379, 651, -214, -110, 20, -2749,
+ -8040, -96, 221, 221, -39, 444, -280, 2814,
+ -536, 3509, 111, 830, 594, 553, 47, 2812,
+ -1898, 203, -353, -60, 371, 181, 824, -5448,
+ 297, 476, 42, -133, 97, 425, 8586, -317,
+ 121, 453, 1014, -350, 175, 747, -78, -287,
+ -5832, 625, 4170, -308, 1853, 2846, -3, -876,
+ 535, 431, -411, -2139, -6021, 374, 298, 1572,
+ 19, -4069, 1567, 144, 3, 5541, -438, 920,
+ 87, 1728, 230, 807, 5848, -413, 7, -6241,
+ 214, 205, 1312, -675, 70, 264, 114, -24,
+ -482, -72, -296, 327, 249, 11047, 11070, 18,
+ -937, 350, 22, 362, 555, 815, 130, -125,
+ -4545, 2662, 203, -318, -305, 323, 633, 416,
+ -254, 301, 99, 407, -4951, 4766, -790, 1334,
+ 912, -1046, -350, -135, 3744, 22, -1647, -422,
+ -151, -113, -130, -345, -2, -263, 18, -24,
+ -771, -34, -543, 10259, 183, 0, 1743, 1267,
+ -2554, 320, 611, -1064, -1446, 875, -808, 4865,
+ -816, 3452, 68, 326, -178, 177, -10, -138,
+ -33, -93, 65, 264, 185, -157, -5749, 110,
+ 407, 1240, -698, -61, 176, 1557, -6012, -606,
+ -555, 458, 3226, -939, 933, 153, -32, 928,
+ 69, -490, -1543, -87, -20, -196, -327, 423,
+ 7911, -189, 178, 335, -194, 459, -10572, -196,
+ 174, -286, 502, -1041, 12, 39, -101, -3983,
+ -1650, -2902, 386, -151, 1051, -619, 6854, 3408,
+ 1140, -1854, -755, -40, -1108, -1502, 221, -397,
+ 375, 1081, 10375, 389, 270, -239, 311, -212,
+ 384, 1237, -2951, 199, 5281, -56, 34, -704,
+ 942, 1169, 33, -310, 97, -1216, 3023, -836,
+ 3256, 404, 3951, -257, 2139, 111, 179, 8255,
+ 611, -240, -252, -367, -251, -296, -2282, 957,
+ 61, -265, 720, 232, 34, 146, 204, -290,
+ -9923, 529, 65, 696, 2958, 352, -3852, 1248,
+ -743, -395, 5969, 92, -132, -1206, 314, -4013,
+ 717, 5157, -770, -1878, -1201, -958, 525, 4028,
+ 116, 6772, -45, -1086, -335, 5815, 51, 57,
+ -85, -2301, -133, -300, 7, 227, 3429, -1075,
+ -4353, -832, 30, 1259, -484, 451, 604, -717,
+ 6765, 294, 118, -410, 299, 592, -3845, 66,
+ -502, -9088, -74, 259, 450, 475, 202, -1792,
+ 23, 4719, 709, -398, -1676, -351, -898, -622,
+ 145, -1392, 7305, 1014, -80, 519, -2065, 1531,
+ 860, -1448, 134, 1683, 689, 7179, -345, -327,
+ 1004, -2467, -340, -1302, 5825, 373, 50, 6796,
+ 314, 13, -270, -426, 702, 279, -4392, -508,
+ -6521, 60, -278, 2479, 847, -360, -68, -1948,
+ 91, 969, 421, 459, -341, 6020, -550, -77,
+ -687, -754, 5, 109, 410, 10860, -183, -317,
+ -734, -87, 501, -601, 158, 5836, -1057, 1236,
+ -850, 2965, -330, 547, 1249, -2804, 127, 218,
+ -455, -805, -4002, 108, -569, 660, -5356, -1091,
+ 581, -445, -311, 6409, 510, -6789, 519, 1607,
+ 296, 342, 368, -1440, -846, 1997, -227, 2332,
+ -2062, -4657, 1030, 5322, 135, 131, -3414, 320,
+ 1030, -3341, -256, -373, -4565, 1222, 171, -4972,
+ -1444, 303, -5427, 435, 208, 251, 467, 539,
+ 136, 199, -8876, -195, -771, -3096, 740, 368,
+ 1047, -490, 83, 485, 168, 531, -635, -801,
+ -953, 4, -95, -7603, -59, 2023, 739, -702,
+ 263, -9230, -313, -997, -510, -772, 156, 3986,
+ -113, 398, -2602, -1079, 195, -211, 128, 1917,
+ 221, -965, 11, 71, -101, 180, -36, 7839,
+ -144, -722, 288, 429, 5704, -984, -510, 775,
+ 440, -1849, -1348, 1989, 300, 43, 1928, 4341,
+ -3840, -2427, 2025, -660, -293, 23, -249, -177,
+ -327, -7858, 33, 245, -1334, 237, -687, 2800,
+ 30, -8807, -404, 43, 183, 289, 528, 510,
+ -197, 590, -94, -5423, 381, 1317, 141, -1639,
+ -432, -7628, -224, 56, -7788, 113, 134, 6981,
+ -636, 756, -743, 97, 159, 1263, -143, -2941,
+ -2680, -479, 1395, -1667, -472, -992, -451, -5708,
+ 4262, 334, 3053, 76, -584, -599, -276, 3518,
+ 264, -2118, 358, -106, 911, 5053, 480, 4538,
+ 949, 5203, -103, -14, 177, -3397, 55, -6813,
+ 680, -1788, 145, 2267, 1104, -789, 54, 261,
+ 228, 5494, 15, -224, 192, 740, 0, 7632,
+ 398, 2879, 430, -8212, -657, 815, -228, -488,
+ -90, -1296, 595, 2979, -15, 4055, -252, -3883,
+ -935, -7654, 330, 97, -10200, 462, 223, -1017,
+ -309, -342, -124, -1258, 211, 351, 316, 414,
+ -91, -18, -202, -74, 410, -11127, 326, 261,
+};
+
static const int16_t shape16[] = {
-855, 1549, -4841, 629, 932, -5896, 840, -2041,
-305, -2574, 343, -31, -780, -773, -353, 403,
@@ -4851,6 +14363,543 @@
79, -1325, 397, -150, 1977, 442, 747, -127,
};
+static const int16_t shape16s[] = {
+ -392, 96, -7720, 99, 524, -8272, -20, 164,
+ -434, -85, -428, 1362, 108, 223, 1053, -11,
+ -193, -5140, -191, -159, 193, 8005, -39, -483,
+ 1764, -1061, -268, -318, -880, 474, 49, -8,
+ -223, 130, 11263, 165, 12, -43, -103, -1145,
+ -588, -81, 299, 73, 444, -7243, -1411, -640,
+ -946, 16, -881, 496, 2403, -476, 1090, -294,
+ 29, -148, 109, 145, -52, 247, -545, 1115,
+ -7451, -491, -1459, 397, -8603, -1022, 1494, 298,
+ -5156, -358, -1097, -2911, 423, 652, -378, -2357,
+ -74, 415, -367, 402, 2173, -154, 122, 283,
+ 1352, 302, -373, -431, -283, -109, -64, -343,
+ -108, 55, -14644, 241, 37, -723, -71, -208,
+ -126, 4061, -9887, 494, 2273, -505, -4040, 66,
+ -806, -1121, -1894, 783, -1445, 426, -820, -1739,
+ -11, 650, -282, -518, 124, -7266, -21, 160,
+ -339, 5, -208, 11712, 198, -53, 921, 89,
+ 5987, -4806, 176, 1884, 64, -517, 2169, 108,
+ 297, -111, -389, -840, 663, 75, -485, -4862,
+ -177, 2663, -229, 8120, -219, 462, 3104, 955,
+ 384, 1310, -73, -504, 258, 170, -1796, -482,
+ 5691, -437, -8474, 583, -1685, -827, 292, -65,
+ 1994, -384, 105, 123, 256, -82, -367, 15204,
+ -128, -260, -10, 169, 249, -1286, 1055, 136,
+ 678, 61, 1420, -159, -15, -221, -250, 107,
+ -21, 297, 54, 242, -111, 468, 237, -36,
+ -159, 37, -102, -488, -4577, 72, 1009, -1,
+ 1218, 2023, -640, -437, 766, -299, 6144, 184,
+ -1023, 171, -388, 884, -1294, -320, 8718, 896,
+ -295, -976, -803, 3092, 1720, -255, -1354, -665,
+ -63, 4382, 41, -121, -157, 354, 127, 587,
+ -599, -231, 484, -150, -284, -498, -511, 79,
+ 5503, 13, 6537, 761, -1619, 1164, -2403, 3057,
+ -4966, 724, 1076, -1555, 889, -365, 60, -440,
+ -7144, -132, 283, -305, -126, -1482, 125, -52,
+ -33, 1284, -961, 1355, 953, -1012, -227, 86,
+ 731, -14, -15977, -56, -875, -1676, 127, 500,
+ 3390, -14, -319, -644, 143, 249, -10752, 23,
+ 54, -1075, -111, 680, -1714, 328, -2092, -852,
+ 622, 949, 61, 6, -17, 144, 190, 216,
+ 130, -65, 27, -322, -139, 43, 89, 76,
+ -84, -10120, -47, 367, -261, 38, 50, 4233,
+ -210, 14, -1, 25, 762, -299, -132, 177,
+ 974, -492, -145, -43, 5105, -394, -196, -91,
+ -25, 473, -8358, -476, 589, -1372, -254, -2387,
+ -293, -304, 3828, -254, -193, 493, 54, -108,
+ -8789, -262, -233, -821, -222, 714, 1270, -61,
+ 892, 13, 3952, -36, -1567, -620, -126, -1056,
+ 587, 390, -24, 2027, 267, 218, 15, -56,
+ -130, 40, 551, -29, 14594, -23, 106, -14,
+ -172, 279, 427, -241, 303, -20, -748, 55,
+ 5187, 598, -217, 2026, 643, 118, 911, 8023,
+ 296, 791, 39, -2621, 655, 228, -671, -272,
+ -176, 6644, -166, -264, -10429, 91, -83, -684,
+ -169, -344, 2123, -102, -333, -317, -826, 586,
+ 116, -9311, 445, 141, -1315, -758, 144, 5620,
+ 363, 66, 142, -161, -684, 454, -6584, -205,
+ 577, 205, 305, -1536, -4109, -318, 121, -323,
+ -1036, 8020, 1146, -4004, 175, -1568, -1537, -525,
+ 2284, 62, 11, 640, 1243, 260, -104, -344,
+ 102, -624, 122, -300, 266, -6104, -1149, 412,
+ -1380, 22, 7561, 360, 564, 398, -338, 174,
+ -76, 131, 44, -426, -12, -175, -113, 78,
+ 293, -120, -92, 331, -16163, -74, -101, -1198,
+ -298, -171, 4052, -139, -187, 131, 323, 370,
+ -144, -160, 131, -284, -190, 83, 878, -14817,
+ 14, 196, 198, 294, -120, 40, 800, 1841,
+ 393, -168, 337, -540, -356, 130, 9210, 880,
+ 304, -2304, -275, 1394, 9903, 673, -62, -4706,
+ -130, 274, 528, 89, -458, -90, 6318, -133,
+ 310, -5953, 682, 37, 2937, -371, 197, 77,
+ -184, 1240, 22, -7695, -171, -4874, -676, -1121,
+ -842, -642, 1160, -1088, -864, 352, -790, 794,
+ 801, 10564, -1777, 1095, -441, 1718, 116, 982,
+ -268, 199, -2408, -2042, 279, -146, 645, -1350,
+ 5, -150, -932, 113, 25, -672, 153, 158,
+ -6140, -262, 142, 4815, -1, -424, 810, 63,
+ 88, -510, -236, 3964, -66, 1229, -16, -758,
+ -11023, -1149, 48, -1756, 167, 2308, -96, -654,
+ -639, 369, -221, 47, 202, 329, -352, -26,
+ -19, 13198, -383, 124, -1211, 3879, -344, -1954,
+ -8702, 32, 924, 472, 7953, 692, -216, -415,
+ -3174, -1959, 935, 4048, 155, 7521, 854, -157,
+ 643, 3760, -107, -2536, 622, -742, 1881, 2262,
+ 758, -968, -271, -131, 385, -5107, -212, -2548,
+ 29, -132, -506, -190, -1065, 314, 202, 332,
+ -2274, 701, 4, -22, -439, 198, -265, -92,
+ -143, 460, -32, 189, 334, 87, -7639, 45,
+ -387, 4240, 1231, 92, 1032, -333, -280, 2061,
+ 296, 365, 2003, -426, -35, 96, -62, 882,
+ -784, 483, -128, -143, 474, 13740, -166, 184,
+ -714, 142, 278, 5622, -67, 282, 647, -130,
+ -31, 300, 727, 728, 409, 178, -601, 84,
+ 8305, -446, 179, 115, 209, -273, -47, 1932,
+ -255, -3171, -102, 461, -119, -8102, -809, 108,
+ -1680, -3171, -775, 324, -246, 132, -27, 84,
+ 8495, -45, 153, 21, -1384, 290, -869, 38,
+ -440, 133, -257, -22, -3046, 12, -2797, 4517,
+ 142, 1605, 423, 579, -558, -301, -257, 701,
+ -246, -468, -1946, 120, 321, 710, -217, -203,
+ -50, -44, -5866, 80, 259, 488, 754, 124,
+ -517, 703, -197, 146, 576, -717, 247, 4121,
+ 10, -422, -2686, 329, 1183, 14573, 72, 301,
+ 2043, -125, -1420, -1263, 10340, -678, -1226, 330,
+ -62, 173, 5885, -56, -178, -1090, -616, 953,
+ -216, 8277, -124, 411, 7758, -78, -326, 786,
+ 46, -1365, -555, 479, -774, -576, 8, 304,
+ 390, -186, -820, 72, -67, -585, 11070, -213,
+ -12, 344, -399, -748, -150, 2719, 195, 5652,
+ 4626, 549, 2782, -4, 1928, 482, 1008, -6398,
+ 843, 457, 1843, 269, 1247, 350, -661, -35,
+ -6477, 3727, 2313, -424, -907, 415, 1075, 3960,
+ -1499, 61, 594, -744, 110, 2486, 967, 27,
+ -5263, -618, -578, 313, 7055, -1081, 739, -492,
+ -2051, 317, 112, -155, -304, -507, 150, 253,
+ -42, 221, 92, -275, -355, -8494, -663, 109,
+ 282, -836, -271, 9316, 165, 63, -171, 10,
+ -38, -180, -219, -250, -924, -573, -241, 566,
+ -175, 20, 454, 251, -328, 236, -215, -5673,
+ 0, -265, 225, 354, 113, -488, 174, -132,
+ 134, -188, 1255, -94, -55, -193, 404, 504,
+ 784, -377, -5731, 333, -447, 222, 138, 72,
+ -256, -58, -230, -169, 728, -481, 95, -394,
+ -74, -489, -253, -13770, 61, 184, -36, 5025,
+ -232, 321, 253, -3414, 120, -2512, 799, -586,
+ 1186, -1135, -955, -54, 7, 83, 0, 5259,
+ 466, -6358, 254, 388, -211, 207, 2449, 379,
+ 430, -219, -442, 228, 151, 11819, 67, -101,
+ 239, -282, 121, -270, 1209, -386, 553, -108,
+ 789, -518, 237, -48, 497, 8986, 80, 8232,
+ -89, -359, -803, 473, 995, 1132, 624, 1353,
+ -305, 711, -71, -26, 18, 254, 13079, -72,
+ 178, -18, -116, 293, 155, -254, -819, -166,
+ -808, -190, 150, -4328, -33, -14, 272, -6417,
+ 78, 78, 67, 310, -177, -435, 225, 610,
+ -15, 1, -6706, 30, 1, -189, 270, -21,
+ 276, -182, 77, -231, 30, -116, -7713, 158,
+ 344, 560, 1466, 3575, -84, -4583, -1260, 372,
+ 1395, -5223, 284, -1911, 315, -2312, -47, -207,
+ 414, 129, 36, 85, 317, -125, -63, -212,
+ -76, 130, -385, 157, 117, 12, 16140, -171,
+ 375, -721, 161, -342, 950, -667, 1011, 15,
+ 536, -1203, 1039, -242, -159, 7664, -429, -264,
+ -8221, -109, 867, -74, -79, -414, 544, 206,
+ 120, 1859, -44, 73, 554, 121, -160, -127,
+ -33, 44, -24, 285, 589, -12514, 51, 464,
+ 17, 264, 58, -6861, 367, -672, 227, 2793,
+ 782, -6286, -420, -808, -1247, 895, 950, 1533,
+ -1079, -207, -1927, -4947, -803, -328, 7677, -386,
+ -4608, -329, -485, 2365, -1492, -1738, -378, -707,
+ -1850, 9044, 314, 3530, 61, 2921, 79, 9508,
+ -1102, -3487, 814, -2828, 550, -929, -712, -274,
+ -566, -2521, 536, -296, -97, 951, 11352, -614,
+ 106, -342, -1017, -1183, -157, -457, 266, 109,
+ 545, -313, 1015, 6961, 52, -224, 2247, -248,
+ -180, 12367, 311, 514, 1218, -561, -2546, -3275,
+ 218, 8281, 187, -6550, -96, -1001, 1777, 89,
+ 916, 1042, 399, -267, -97, -3552, 397, 1984,
+ -6134, 784, 2136, -1346, 619, -1450, -1022, -1226,
+ 185, 306, -274, -122, 343, 129, -4481, -749,
+ -759, -496, 8785, -178, 457, -601, 875, 1040,
+ -268, -1592, -531, 9667, 360, -4978, 525, -436,
+ 123, -1566, 227, 820, 74, -5, 1477, 154,
+ -1589, -9411, 248, -485, -3293, -690, 175, 53,
+ -21, 303, -2376, 106, 515, 2688, -401, -1278,
+ 425, 540, -353, 662, -7461, -397, -7029, -976,
+ 445, -1648, 164, -254, -563, 556, 876, -205,
+ 884, 214, -92, -509, 96, -53, 5734, -295,
+ -136, 211, 168, 261, -74, 411, 25, -59,
+ 3596, 400, 320, -69, -21, 14062, -510, 142,
+ -232, 1597, 34, 240, -476, 131, -3836, -186,
+ 2579, 2812, -1501, 274, 2685, 2809, -1100, 2696,
+ -402, 67, 650, -1804, -11, -216, 6751, 112,
+ 455, -7210, -251, -1075, -833, -966, 1443, -138,
+ 273, -494, 1557, -15, -339, -82, 402, 206,
+ 31, -77, -94, 78, -5468, -179, -44, 421,
+ 163, -386, -133, -6334, 427, 747, -121, -292,
+ 368, -1087, -338, -1534, 3740, -881, -2012, -1284,
+ 902, 97, -3407, -567, -118, 1340, -77, -445,
+ 642, 184, 901, -341, -81, 595, -6531, -248,
+ -167, 8740, 373, 408, 23, 10709, -299, -876,
+ -584, -1067, 20, -4556, 295, -1956, 990, -132,
+ -152, 4068, -92, 142, -1512, 23, -815, 454,
+ 330, -331, 9042, 120, -100, 34, 96, 152,
+ -11083, 345, -567, -498, 198, -37, 9276, -479,
+ 611, -2788, 253, -176, 617, -224, 248, 390,
+ 39, 25, -110, 127, -13, 6675, -84, 115,
+ 294, 84, -366, -405, -32, -109, -10469, 99,
+ 17, -88, -226, 316, -133, -203, -60, 311,
+ -87, -331, 357, -11, 158, 74, 562, 8,
+ 354, -10843, -114, -206, 699, -617, -141, 807,
+ 87, -149, 174, 199, -55, 10880, -332, 182,
+ 544, 651, -27, 261, -190, -655, 24, -443,
+ -630, 204, 207, -4174, 3557, 89, -386, 1754,
+ -485, -127, -97, 40, -1336, -488, -177, -750,
+ 88, -1040, -2215, -507, 169, 2908, 69, -52,
+ 8458, 601, 174, 1635, 480, 181, 3004, -3021,
+ 1868, -364, -2100, -256, -3065, -33, -7467, -890,
+ -1949, -20, -9472, -230, -847, -634, -377, -40,
+ 1184, 242, 265, 7056, 42, 16, -5070, -71,
+ 300, -1186, 187, 337, -1331, 77, -473, 3213,
+ 5738, 626, 2524, 531, 1001, -803, 1231, -1083,
+ -564, 539, 191, -498, 184, 603, -1777, -479,
+ 2298, -604, -2077, 634, 4682, -1387, -875, 498,
+ -10011, -173, 752, 109, -70, 171, -64, -261,
+ -79, 37, -233, 128, -66, -70, 356, -310,
+ 214, -14792, 6, 200, -227, 59, -241, 560,
+ -230, 479, 403, -22, 148, 7428, 110, -177,
+ 110, 7518, -2372, -1277, 223, -708, 731, 695,
+ -702, -2906, 256, -1160, 4941, 121, -1148, -68,
+ -424, -1590, 4697, 705, 525, 684, -451, -246,
+ -115, 556, 543, -6658, 384, -589, -1505, 12,
+ 114, 82, -5084, 164, 154, -295, 106, -271,
+ -40, -394, -437, 397, -279, -3825, -286, 632,
+ -1041, 1137, -93, 48, 192, -5914, -92, -235,
+ 682, 5817, -702, 180, -243, -219, -910, -174,
+ -146, 142, 12, -69, -207, -269, -53, 567,
+ -336, 114, 9601, -272, -270, 459, 610, -258,
+ 97, -10950, 397, 57, -7, 229, 1669, -173,
+ -173, -92, -347, -133, -357, 92, 132, -609,
+ 60, -124, 116, -54, -15205, 142, 109, 1127,
+ 268, -220, 336, -743, -238, -29, -902, 91,
+ -3597, -288, 1114, -3797, -1615, 32, 11481, 55,
+ 194, 3567, -1857, -2561, -237, -15, -48, -232,
+ -58, -21, 37, -535, -450, 857, 2001, 12,
+ 48, 840, 211, 126, 4833, 275, 176, -111,
+ 9, -112, -403, 182, 296, 181, -425, -14,
+ 276, 118, -240, 384, 139, 9183, -230, 143,
+ 2412, -70, 250, 10191, 809, -15, -257, -1242,
+ -163, -4253, -352, -436, 264, -4998, -17, -215,
+ 1412, 1592, 856, -159, 4756, -5032, 307, -251,
+ 194, 6414, -56, -7, -503, -261, -646, -1050,
+ -271, -578, -291, 614, 130, -336, -923, -120,
+ 149, -6012, 273, -295, -4586, 137, 206, 1246,
+ 498, 614, 991, 13776, 122, 52, -660, -76,
+ -211, -477, -224, 196, 411, 398, -590, 820,
+ -441, -35, 4394, 5010, -902, 509, 45, 747,
+ 1035, -455, -579, 105, 1103, -496, -1249, -248,
+ 46, -5771, -198, -386, 736, 15, -335, -85,
+ -624, -124, 580, -327, -102, -18, 866, 381,
+};
+
+static const int16_t shape22[] = {
+ 2560, -127, -137, -385, -1875, 90, -240, 140,
+ 1290, 200, -6762, 374, 1871, 8730, -111, -555,
+ -1524, -2175, -4689, 521, -179, 166, -1573, 1056,
+ -346, 247, -92, 5713, 561, 233, -360, 480,
+ -741, -7552, -1508, 259, -8746, 1604, 1385, 723,
+ 5678, 2243, 403, 12370, 3526, 574, 4982, 563,
+ 1713, -1337, 1336, -60, -890, -2184, -563, 9347,
+ 775, 6318, -883, 1476, -335, 736, -564, 635,
+ -5557, 617, 54, 257, -325, -66, -5689, 1061,
+ -897, 90, 8394, 2004, 9456, -222, -2026, -969,
+ 93, -5, -922, -6491, 1496, -1537, 651, -277,
+ -1038, 6072, -8534, -2526, 1645, 1459, 547, 2347,
+ -85, -761, -7210, -153, 414, 6096, 383, 320,
+ 370, -902, 823, 3071, 499, -731, 38, 473,
+ 1693, -9456, 946, 1218, -1054, 70, 367, -469,
+ -7861, -913, 401, 198, -83, 877, -308, 8633,
+ 253, -2025, 1925, 1412, 1351, -360, -948, -7526,
+ 1089, -7449, 1652, 141, -43, -2082, 44, 130,
+ -7525, -15049, -1345, 180, -3009, -4581, -267, 2309,
+ -1397, -112, -63, 307, -746, -13, 35, -8800,
+ -1947, -1143, -1096, -2582, -1210, 7683, -743, -1589,
+ 5699, -80, -1375, -93, -483, 129, 6076, -6099,
+ 374, -176, -1150, -416, 137, -4309, -1926, 3099,
+ 82, -836, 392, -655, 108, 428, 3361, 313,
+ 363, 7534, 1153, 334, 2262, -367, -69, -813,
+ -9702, 3074, -5461, 0, -1889, 1303, -8306, -113,
+ -677, 692, -2752, 1292, -171, 430, 4609, -2238,
+ 196, 1661, -25, -164, -2590, -4919, -615, -7,
+ -753, 5104, 5197, -66, -310, 827, -126, 615,
+ 70, -456, 238, 682, -639, -561, 369, 183,
+ 113, 430, -840, -792, -7282, -7537, 619, -445,
+ 588, 19, -1061, 652, 46, 861, 9641, -1251,
+ -41, -699, -605, -1389, 240, -10798, 733, 194,
+ -1230, -1092, -520, -219, 7, 518, -181, -12062,
+ 651, -40, 1128, -390, -220, -438, 471, 510,
+ 632, -321, 1393, 8827, -3241, -6683, 350, 1953,
+ -246, -582, -5486, -7576, -157, 888, 2965, -23,
+ 762, 6867, 3697, -43, -7905, -938, 2119, 377,
+ -25, 691, 136, -725, 7643, -730, 2024, -6932,
+ 804, 53, 392, 440, 336, 6235, -7037, -5584,
+ -1579, 1115, 1757, 1001, 32, -294, -592, 300,
+ -764, -8879, -1612, -845, 1722, 6968, 384, 267,
+ 862, 10830, -364, -1138, -49, 1041, -908, -14960,
+ 809, 628, -1150, -1348, -437, 805, 877, -64,
+ 1041, 5253, -270, 2022, 1253, -992, 11015, 2686,
+ 17, 80, -1463, 4229, 80, -834, -9286, 1179,
+ 66, -39, -64, -4057, -423, 116, -1441, -1733,
+ 752, 1674, 1443, 757, -3149, 9057, -3522, 4007,
+ -893, 1179, -388, 6368, -478, 4397, 13868, -2996,
+ 790, 704, -2299, -6003, 449, -5410, 1999, 181,
+ -1807, -362, -57, 454, -2371, 3658, -485, -212,
+ 11551, 1535, 478, -1570, -278, 584, 608, -5211,
+ 6965, 1042, -168, -337, -1071, 72, 451, -204,
+ -1000, -1044, 689, 186, -166, -375, 9426, 363,
+ 93, -717, 304, 107, 7853, -1251, 1093, 692,
+ -742, 33, 576, 447, 678, 452, 408, -4813,
+ 711, -595, -516, -1108, 1941, 3056, -219, -3413,
+ 10946, 1513, -2375, 48, -408, 49, -399, -5608,
+ -58, 161, 4808, 436, 68, -5675, 230, 832,
+ -1228, 6382, -588, -1312, 772, 4337, -405, -5467,
+ -222, 1382, 2158, 620, -840, 810, -3830, 48,
+ -101, 529, -2670, -249, 1035, -7620, -1081, -6646,
+ 1469, 1043, 743, 1553, -556, -274, 68, 238,
+ 1078, -110, -5163, 562, 735, -8317, 1202, -1325,
+ -962, 61, 4280, 570, 7450, 265, -1516, 696,
+ -1567, -681, 0, -4064, 1548, -2521, 657, 567,
+ -8343, 1691, -1430, 4827, 807, 905, -2601, -7415,
+ 921, -1741, 363, 309, 211, -521, 3013, -797,
+ 648, -3709, 961, 662, 403, -386, -719, -5752,
+ 1355, 6717, 191, 591, -371, -1225, -5125, 800,
+ -252, -5769, 1101, 657, -141, 2377, -1365, -218,
+ -114, 148, 276, 358, -354, 18, -31, -9413,
+ -5514, -1458, -220, 298, 666, 659, 359, 980,
+ -1389, 101, 1500, 4661, 472, 264, -7590, -1469,
+ 41, 38, -259, -346, -486, -9949, 812, 422,
+ -1354, -2461, -2057, -253, 1806, -107, -41, 16384,
+ -140, -684, 5421, 1907, -10, -889, -1877, -6815,
+ -818, -5854, -3196, -895, -1706, -186, 7944, 100,
+ -11260, -4573, -415, 4685, 395, -6035, 5789, -4566,
+ 624, -2146, 570, 130, -892, 1385, -262, 6638,
+ -2324, 348, -288, 607, -1574, 7119, -1037, -40,
+ -4955, -946, -5215, -1013, -1232, -875, -78, -399,
+ 231, -173, -5860, 189, -755, -8265, 745, 966,
+ 202, -1858, -26, -658, 55, 1131, -56, 3030,
+ 158, 3742, -1261, 317, 6397, 521, -508, -522,
+ -2040, -747, -6906, -868, -110, -719, 2602, 2570,
+ -1106, -787, -352, 9212, -545, 7339, -10183, -726,
+ 1104, -1118, -1655, 383, 1370, 1412, 528, -4689,
+ -398, -3802, -682, -11004, -2310, 8011, 2301, -5941,
+ -512, 3813, 210, 1379, -15209, 1143, -2344, 2459,
+ 2368, -6484, -2078, -246, 383, -204, 1449, -453,
+ -1539, 416, 508, -7168, -1930, 4279, 453, -215,
+ -296, -346, 5691, -200, -855, 552, 5921, -109,
+ 588, -3049, 1312, 6767, -78, -7204, 1187, -754,
+ -1043, -455, 412, -490, 3124, -273, 1468, -546,
+ 552, -306, 835, -263, -7234, 324, 318, -1224,
+ 240, 198, 193, -550, -684, -12416, 85, -1469,
+ -463, -301, 180, 290, -928, -6399, -931, 176,
+ 310, -692, 7964, -204, 512, 975, -6415, -394,
+ -30, -120, 1638, -1474, -381, 5912, 156, -830,
+ -575, -225, -4079, -787, -957, -801, 181, 575,
+ 1116, -795, -743, -981, 434, -365, -9780, -1814,
+ 1447, 1081, 153, 884, 8697, 259, 881, -661,
+ -1232, -547, 464, 898, -3988, -476, 790, 7589,
+ -525, -809, -2900, -1271, 170, 223, -5050, -2554,
+ 1458, -666, 537, -6733, 212, 448, -1556, 1459,
+ 802, -2716, -8785, 11020, -258, 1229, 1138, 843,
+ 508, 103, -657, 1273, 8140, 368, -605, 6856,
+ 110, -423, 5458, -417, 993, 257, 5552, -47,
+ 1401, -119, -1320, 6193, -1196, 56, -93, -1604,
+ -1491, -897, 238, 823, 4213, 104, 145, -1049,
+ -9286, -26, -813, -139, 499, -10351, -466, -515,
+ -1166, -412, -746, 503, 1872, 17, -11941, -3350,
+ -108, -7296, -411, 4811, -1870, 162, 5595, -658,
+ 339, -904, 6911, -715, -240, -71, 377, 4747,
+ -57, -8920, 521, 753, -375, -1185, 1322, -328,
+ 5, 525, -610, 127, 1519, 791, 784, -16384,
+ 116, -1007, -352, 486, -7871, 202, -3684, -387,
+ 676, -8942, -713, -447, -557, 1159, 974, -380,
+ -1183, 1049, -9, 838, -932, -139, 371, 1688,
+ -7617, 1192, 2350, -220, -4558, 2681, 1568, 102,
+ 1274, -446, -351, 1551, 1101, -8995, -5276, -4416,
+ 3411, 221, -429, 412, 1625, -4575, 254, -631,
+ 310, -378, 9743, 859, 934, 142, -1400, -6921,
+ 6466, -4068, 2664, 418, 70, 284, -903, -23,
+ -502, 4354, -5993, 125, -34, -1246, -1946, -204,
+ 1002, -7454, -88, -8628, 2449, 13715, 318, -8759,
+ 294, -2212, 138, -761, 285, -1686, 291, 606,
+ 180, 761, -359, -1467, 299, -417, -361, -895,
+ -5692, 127, -951, 165, 1, 396, -819, -5508,
+ 280, 760, -411, -1025, -649, -1688, -6290, 272,
+ -17, -7595, 9, 307, 128, -3995, -119, 481,
+ -3100, -255, 651, 139, -3492, -6, -4471, 452,
+ -71, 139, 1255, -6128, 1191, 326, 28, -238,
+ 1374, -334, -457, -836, -10390, 185, -616, 3366,
+ -39, 183, -21, 6240, 1141, 341, -348, 738,
+ 121, -65, -386, -27, -548, 337, -4, -126,
+ 571, 2263, 4936, -1093, -397, 961, -5886, -734,
+ 1509, -660, -61, 170, -783, -4197, -1459, 906,
+ -31, 400, -481, 561, 6, 489, -5397, -1666,
+ 41, -536, -116, 6713, 1288, -157, -116, 4256,
+ 1895, 6671, 1837, -544, 1276, 2031, 345, 6471,
+ -84, 1868, -2006, -1304, -7792, 702, -1189, 105,
+ -4869, -282, -790, 7083, -628, -1273, 252, -179,
+};
+
+static const int16_t shape22s[] = {
+ 493, -2, -310, -109, -1218, -193, -267, -11,
+ -466, -34, -2492, 287, 241, 3621, -537, 458,
+ 869, -915, -290, 782, 65, -90, -635, 1836,
+ 80, 519, 868, 1359, 550, -92, -704, 110,
+ -210, -4337, -376, -200, -2693, 6, 381, 688,
+ 556, 883, -88, 1698, 1081, 133, 1130, -78,
+ 853, -424, -39, -909, -1579, -2774, -372, 3604,
+ -519, 3777, -66, 1330, -1055, 1135, -995, 220,
+ -3124, 122, 83, 1045, -701, -120, -6800, -269,
+ 195, 1197, 5500, -490, 5453, -201, 411, 823,
+ -146, 46, 252, -2724, 606, -924, -1538, 394,
+ -420, 6405, -5632, -941, -402, -137, 984, -24,
+ 594, -40, -140, -20, 204, 1211, 290, -680,
+ 103, -434, -294, 1646, -159, -2296, -237, 507,
+ -67, -8999, -97, 403, -1473, -111, 22, -257,
+ -2203, -600, 577, -117, 48, 2216, -170, 1192,
+ 700, -477, 1678, 979, 2395, -69, -1746, -2139,
+ -294, -4210, 181, -372, 320, -180, -503, -550,
+ -3994, -6315, 502, -804, -432, -112, -457, -1016,
+ 637, 297, 932, 533, 798, 229, -1001, -2780,
+ -4009, 1176, 189, -1575, 21, 3512, -348, -1450,
+ 2488, 463, 611, -46, 85, 94, 3319, -3041,
+ -362, -261, -1534, -1900, 7, -519, -52, 1166,
+ -174, -152, -189, -415, 641, 27, 1764, 280,
+ -301, 2976, 146, -632, 4022, -1994, -84, -61,
+ -1633, 285, -439, 781, -592, 399, -4794, 203,
+ -295, 32, -1423, 216, -2773, -9, 3589, -3952,
+ -195, 161, -223, -2240, -1886, -2643, 978, 113,
+ -1019, 1645, 1493, -851, 1417, -74, 717, 411,
+ 887, -1384, 73, 117, -65, -7, 133, 18,
+ 69, 11, -98, 45, -1751, -2710, 11, -140,
+ 29, 185, 327, 705, 56, 152, 8202, -117,
+ 157, -478, 36, -564, 996, -9359, -707, 674,
+ 1169, 270, 156, -679, 15, 720, -38, -4952,
+ -196, 183, -356, -1004, 185, -148, -61, 151,
+ -229, -161, 23, 4350, -650, -4384, -21, 909,
+ 105, -271, -2538, -4018, -1268, 351, 396, -190,
+ -135, 970, 3159, -935, -6968, -131, -1031, 53,
+ -430, 242, -219, 384, 2832, -151, 152, -6891,
+ 1444, -63, -46, 72, 653, 3955, -4187, -321,
+ -298, 678, -471, 664, -42, -30, 825, 195,
+ -1147, -2728, -178, -2305, 680, 1980, -147, 320,
+ -348, 4307, 806, -263, -60, -102, 8, -10085,
+ 626, -130, 267, -621, 45, -157, 438, 190,
+ 78, 1608, -246, -386, 256, -255, 5651, -449,
+ -13, 198, -3193, 329, -500, -1368, -6647, 609,
+ -507, -96, 222, -1196, 171, -12, -299, -1423,
+ 442, 47, -5, -282, -18, 4969, -1764, 231,
+ -471, 5044, 412, 1496, -146, 35, 5083, -228,
+ 355, -482, -1063, 1265, 80, -1278, 1225, 826,
+ -1914, 779, 439, -511, -4177, 425, -38, -55,
+ 9786, 1005, -538, -664, -641, 638, 125, -2811,
+ 2308, 28, -1157, -229, -624, 45, 354, -368,
+ -1661, 90, 778, -328, 272, -223, 9558, 822,
+ -167, -12, -1020, 2962, 2372, -932, 1961, 1398,
+ 2660, 3, 235, 421, 114, -283, 371, -1652,
+ 329, -435, -113, -1296, -501, -686, 297, -384,
+ 10328, 472, 614, 139, -765, -309, 180, -2009,
+ -171, -175, 3571, 146, 46, -1356, -134, -15,
+ -166, 2046, 108, 119, -281, 971, -471, -1134,
+ 34, -104, 219, 746, -223, 245, -181, 12,
+ -165, 216, -792, 86, 562, -1807, -116, -1324,
+ 590, -320, -80, 1863, -420, -1066, -698, -2879,
+ -6, 182, -2325, 575, 97, -2616, 2938, -673,
+ -693, -116, 1905, -430, 4739, -12, -3307, 693,
+ -227, 223, -111, -1498, 5, 1751, -36, 234,
+ -4584, 838, -370, -296, -818, 337, -46, -8921,
+ 875, -423, 496, -1196, -24, -1014, 969, 294,
+ 237, -1733, 27, 2543, 1494, 190, 457, -1391,
+ 1209, 5651, 548, 504, 686, -2889, -151, 725,
+ 486, -3716, -285, 830, 31, 5132, 770, -24,
+ -482, -369, -126, -1552, -347, -272, -387, -9485,
+ -1547, -1189, 369, 812, 311, 536, 391, 361,
+ -1708, -288, -94, 2053, 557, -611, -4551, -2368,
+ 173, 472, 160, -1849, 96, -7569, 183, 484,
+ -393, -346, -309, -13, -7, 2, -239, 10395,
+ -587, -115, 1282, -634, 81, 90, -725, -2685,
+ -1214, -4455, -1897, -2903, -827, 124, 2215, 696,
+ -1225, -1353, -371, 343, 421, -640, 1480, -1174,
+ 76, -835, -716, -625, -547, 1250, -2696, 2132,
+ -548, 439, -607, 408, -221, 5026, 352, -344,
+ -1339, -602, -1650, -404, -458, -502, 61, -164,
+ 53, -26, -2652, -209, 64, -4068, 713, 193,
+ -117, -1290, 95, -86, -515, 1336, -492, 1654,
+ -2963, 3663, -4231, -1, 3017, 371, 276, -7,
+ -289, -33, -5942, 237, 30, 586, -264, -493,
+ 435, -388, -165, 10434, 192, 3897, -5414, 361,
+ 845, -259, 481, 331, 650, -232, 23, -1789,
+ 27, -4065, 1020, -4261, -651, 3174, 951, -3363,
+ 577, -112, 642, -1177, -1707, 492, -250, -1236,
+ 24, -1394, -1807, -853, 1681, -69, 851, -959,
+ -5759, -202, 30, -3466, -593, 5414, 65, 141,
+ -319, 674, 1183, -155, -312, 372, 2829, -75,
+ -60, -2618, -240, 2944, -631, -4221, -16, 467,
+ 211, -58, 55, -527, -51, -160, 642, -305,
+ 388, 413, 210, -81, -3383, -120, 144, -220,
+ -672, 1352, -630, -2324, -423, -8053, -131, -912,
+ -260, -380, 470, 154, -1346, -2417, -426, -403,
+ -137, -160, 2823, 609, -216, -173, -585, -514,
+ 95, -202, 222, 16, 136, 1751, 237, -1089,
+ 957, -144, -518, 416, -347, -60, 207, 277,
+ 512, -1133, 166, 1423, -883, -194, -7016, -1938,
+ 417, 2302, -992, -179, 738, -74, 411, -462,
+ -413, 67, 234, -322, -164, -47, -89, 1409,
+ 390, -1180, -2888, 655, 1958, 0, -1826, -471,
+ -1247, 307, 104, -8502, -198, -222, 191, 281,
+ -868, 47, -4553, 2434, 174, 263, 2844, -72,
+ -597, -1183, -374, -93, 3348, 13, 173, 6285,
+ -32, -213, 1882, 411, -608, -562, 2998, 293,
+ 54, -147, -120, 822, -93, 679, 206, -3229,
+ -767, -1603, -259, -310, 4306, 548, -9, -99,
+ -5722, -328, -176, 453, 338, -9687, -63, 844,
+ 322, 615, -1075, -370, 159, -33, -6213, -1375,
+ 741, -801, -1319, 1513, 1331, -69, 2702, -458,
+ -203, 103, 4696, -284, 465, -62, -40, 3184,
+ 238, -6131, 546, 1713, -365, -24, 116, -33,
+ 304, 807, -231, 291, 903, 749, -254, -12215,
+ 115, -35, -95, -166, -3776, -170, -4517, -151,
+ 67, -7725, 666, -573, -744, -719, 37, 31,
+ 373, 148, -125, 15, -150, -905, -42, 272,
+ -5223, 650, 5233, 109, -1235, 991, 211, 1522,
+ -555, -328, -52, 5335, -22, -5476, -3102, -637,
+ 986, 468, -37, -164, -264, -1290, 754, -940,
+ -685, -862, 7270, -279, -441, 472, -153, -2515,
+ 3899, -95, 360, 762, 14, 434, 619, 185,
+ -230, 1233, -1330, 1360, -756, 361, -1391, -247,
+ 120, -3573, 293, 375, 806, 5526, 536, 137,
+ 486, -484, 13, -37, 12, -4, 81, 43,
+ 10, 43, -38, -371, -64, -1167, -117, -371,
+ -1958, -166, 543, -97, -83, 391, -59, -1631,
+ 302, 1077, -128, -641, -64, 21, -2562, -235,
+ 342, -7121, -646, -49, -961, -141, -210, -555,
+ -1596, -988, 723, -209, -3585, 10, -35, 1051,
+ 0, 138, 941, -5002, 805, 3009, 35, -70,
+ 513, -21, -432, -224, -10628, -167, -1045, 2603,
+ 336, 360, 515, 683, 981, 3028, 492, -543,
+ -1844, 23, -30, 52, -40, 447, 11, 363,
+ -95, 1609, 2613, -13, -400, 719, -4513, -676,
+ -290, 456, -332, -11, -261, -455, 89, -301,
+ 285, 287, 202, 281, 87, -202, -1482, -535,
+ 874, -478, -201, 4715, 824, -204, 145, 2882,
+ 404, 3376, 363, -18, -127, 764, 106, 1626,
+ 178, 185, 22, -637, -6216, 1399, -961, -88,
+ -553, -91, 98, 1831, 9, -583, 1253, -1741,
+};
+
static const int16_t shape44s[] = {
-20, -140, 683, -586, -1742, 177, -538, 1900,
2193, -17, -2096, 261, 645, 339, 77, 1136,
@@ -5011,6 +15060,57 @@
2, 1, 2, 2, 3, 4, 5, 7, 13, 25
};
+static const uint16_t bark_tab_l8s_512[] = {
+ 7, 8, 7, 8, 8, 8, 8, 8,
+ 8, 9, 9, 10, 10, 11, 11, 12,
+ 12, 14, 15, 16, 18, 19, 21, 24,
+ 27, 30, 35, 40, 46, 53,
+};
+
+static const uint16_t bark_tab_s8s_64[] = {
+ 3, 3, 3, 3, 4, 5, 6, 8,
+ 12, 17,
+};
+
+static const uint16_t bark_tab_m8s_256[] = {
+ 6, 5, 6, 6, 6, 6, 7, 7,
+ 8, 8, 9, 10, 11, 13, 15, 18,
+ 20, 25, 31, 39,
+};
+
+static const uint16_t bark_tab_l11_512[] = {
+ 4, 4, 5, 4, 5, 4, 5, 6,
+ 6, 6, 7, 8, 9, 10, 12, 14,
+ 17, 21, 27, 33, 44, 58, 82, 121,
+};
+
+static const uint16_t bark_tab_s11_64[] = {
+ 2, 1, 2, 3, 4, 6, 13, 33,
+};
+
+static const uint16_t bark_tab_m11_256[] = {
+ 3, 3, 4, 3, 4, 4, 5, 6,
+ 7, 9, 11, 15, 21, 30, 48, 83,
+};
+
+static const uint16_t bark_tab_l11s_512[] = {
+ 6, 6, 6, 6, 6, 6, 7, 6,
+ 7, 7, 8, 8, 8, 9, 10, 10,
+ 11, 13, 13, 15, 17, 18, 21, 25,
+ 27, 33, 38, 45, 54, 66,
+};
+
+static const uint16_t bark_tab_s11s_64[] = {
+ 2, 3, 2, 3, 3, 4, 6, 8,
+ 12, 21,
+};
+
+static const uint16_t bark_tab_m11s_256[] = {
+ 4, 5, 4, 5, 5, 5, 6, 5,
+ 7, 7, 8, 9, 10, 12, 15, 17,
+ 22, 28, 35, 47,
+};
+
static const uint16_t bark_tab_l16_1024[] = {
5, 5, 5, 5, 5, 5, 5, 6, 6, 7, 7, 7, 8, 9, 10, 11,
12, 14, 17, 19, 22, 27, 33, 40, 51, 64, 84, 114, 164, 257
@@ -5029,6 +15129,60 @@
1, 1, 2, 2, 3, 6, 11, 38
};
+static const uint16_t bark_tab_l16s_1024[] = {
+ 9, 9, 8, 9, 10, 9, 10, 10,
+ 10, 12, 11, 13, 13, 14, 16, 17,
+ 19, 20, 24, 26, 30, 35, 40, 48,
+ 56, 68, 83, 102, 128, 165,
+};
+
+static const uint16_t bark_tab_s16s_128[] = {
+ 3, 4, 4, 4, 5, 7, 10, 16,
+ 26, 49,
+};
+
+static const uint16_t bark_tab_m16s_512[] = {
+ 7, 6, 7, 7, 7, 8, 9, 9,
+ 10, 11, 14, 15, 18, 22, 27, 34,
+ 44, 59, 81, 117,
+};
+
+static const uint16_t bark_tab_l22_1024[] = {
+ 3, 4, 3, 4, 3, 4, 4, 4,
+ 4, 4, 5, 5, 5, 6, 7, 7,
+ 8, 9, 11, 12, 14, 16, 20, 24,
+ 29, 36, 45, 60, 80, 113, 173, 302,
+};
+
+static const uint16_t bark_tab_s22_128[] = {
+ 1, 2, 1, 2, 3, 4, 6, 10,
+ 23, 76,
+};
+
+static const uint16_t bark_tab_m22_512[] = {
+ 3, 2, 3, 3, 3, 4, 3, 5,
+ 4, 6, 7, 8, 10, 14, 18, 25,
+ 36, 55, 95, 208,
+};
+
+static const uint16_t bark_tab_l22s_1024[] = {
+ 6, 7, 6, 6, 7, 7, 7, 7,
+ 7, 8, 9, 8, 10, 10, 11, 12,
+ 13, 15, 16, 18, 21, 24, 27, 33,
+ 38, 46, 55, 68, 84, 107, 140, 191,
+};
+
+static const uint16_t bark_tab_s22s_128[] = {
+ 3, 2, 3, 4, 4, 6, 9, 14,
+ 26, 57,
+};
+
+static const uint16_t bark_tab_m22s_512[] = {
+ 5, 5, 5, 6, 5, 7, 6, 7,
+ 9, 9, 11, 13, 15, 20, 24, 33,
+ 43, 61, 88, 140,
+};
+
static const uint16_t bark_tab_l44_2048[] = {
5, 6, 5, 6, 5, 6, 6, 6, 6, 6, 7, 7, 7, 8, 8, 9,
9, 10, 11, 11, 13, 14, 16, 17, 19, 22, 25, 29, 33, 39, 46, 54,
@@ -5044,6 +15198,24 @@
1, 2, 1, 2, 3, 4, 6, 10, 23, 76
};
+const TwinVQModeTab ff_metasound_mode0806 = {
+ {
+ { 8, bark_tab_s8_64, 10, fcb8s, 1, 5, cb0806ss0, cb0806ss1, 27 },
+ { 2, bark_tab_m8_256, 20, fcb8m, 2, 5, cb0806sm0, cb0806sm1, 22 },
+ { 1, bark_tab_l8_512, 30, fcb8l, 3, 6, cb0806sl0, cb0806sl1, 24 }
+ },
+ 512, 12, lsp8, 1, 5, 3, 3, shape8, 8, 28, 20, 6, 200
+};
+
+const TwinVQModeTab ff_metasound_mode0806s = {
+ {
+ { 8, bark_tab_s8s_64, 10, fcb8ss, 1, 5, cb0806ss0, cb0806ss1, 27 },
+ { 2, bark_tab_m8s_256, 20, fcb8sm, 2, 5, cb0806sm0, cb0806sm1, 22 },
+ { 1, bark_tab_l8s_512, 30, fcb8sl, 3, 6, cb0806sl0, cb0806sl1, 24 }
+ },
+ 512, 12, lsp8s, 1, 5, 3, 3, shape8s, 8, 28, 20, 6, 200
+};
+
const TwinVQModeTab ff_metasound_mode0808 = {
{
{ 8, bark_tab_s8_64, 10, fcb8s, 1, 5, cb0808s0, cb0808s1, 18 },
@@ -5053,6 +15225,33 @@
512, 12, lsp8, 1, 5, 3, 3, shape8, 8, 28, 20, 6, 200
};
+const TwinVQModeTab ff_metasound_mode0808s = {
+ {
+ { 8, bark_tab_s8s_64, 10, fcb8ss, 1, 5, cb0808ss0, cb0808ss1, 18 },
+ { 2, bark_tab_m8s_256, 20, fcb8sm, 2, 5, cb0808sm0, cb0808sm1, 16 },
+ { 1, bark_tab_l8s_512, 30, fcb8sl, 3, 6, cb0808sl0, cb0808sl1, 17 }
+ },
+ 512, 12, lsp8s, 1, 5, 3, 3, shape8s, 8, 28, 20, 6, 200
+};
+
+const TwinVQModeTab ff_metasound_mode1110 = {
+ {
+ { 8, bark_tab_s11_64, 8, fcb11s, 1, 5, cb1110s0, cb1110s1, 21 },
+ { 2, bark_tab_m11_256, 16, fcb11m, 2, 5, cb1110m0, cb1110m1, 18 },
+ { 1, bark_tab_l11_512, 24, fcb11l, 3, 6, cb1110l0, cb1110l1, 19 }
+ },
+ 512, 16, lsp11, 1, 6, 4, 3, shape11, 9, 28, 20, 7, 200
+};
+
+const TwinVQModeTab ff_metasound_mode1110s = {
+ {
+ { 8, bark_tab_s11s_64, 10, fcb11ss, 1, 5, cb1110ss0, cb1110ss1, 21 },
+ { 2, bark_tab_m11s_256, 20, fcb11sm, 2, 5, cb1110sm0, cb1110sm1, 18 },
+ { 1, bark_tab_l11s_512, 30, fcb11sl, 3, 6, cb1110sl0, cb1110sl1, 20 }
+ },
+ 512, 16, lsp11s, 1, 6, 4, 3, shape11s, 9, 36, 30, 7, 200
+};
+
const TwinVQModeTab ff_metasound_mode1616 = {
{
{ 8, bark_tab_s16_128, 10, fcb16s, 1, 5, cb1616s0, cb1616s1, 16 },
@@ -5062,6 +15261,33 @@
1024, 16, lsp16, 1, 6, 4, 3, shape16, 9, 28, 30, 7, 200
};
+const TwinVQModeTab ff_metasound_mode1616s = {
+ {
+ { 8, bark_tab_s16s_128, 10, fcb16ss, 1, 5, cb1616ss0, cb1616ss1, 16 },
+ { 2, bark_tab_m16s_512, 20, fcb16sm, 2, 5, cb1616sm0, cb1616sm1, 15 },
+ { 1, bark_tab_l16s_1024, 30, fcb16sl, 3, 6, cb1616sl0, cb1616sl1, 16 }
+ },
+ 1024, 16, lsp16, 1, 6, 4, 3, shape16s, 9, 56, 60, 7, 200
+};
+
+const TwinVQModeTab ff_metasound_mode2224 = {
+ {
+ { 8, bark_tab_s22_128, 10, fcb22s, 1, 6, cb2224s0, cb2224s1, 15 },
+ { 2, bark_tab_m22_512, 20, fcb22m, 2, 6, cb2224m0, cb2224m1, 14 },
+ { 1, bark_tab_l22_1024, 32, fcb22l, 4, 6, cb2224l0, cb2224l1, 15 }
+ },
+ 1024, 16, lsp22, 1, 6, 4, 3, shape22, 9, 56, 36, 7, 200
+};
+
+const TwinVQModeTab ff_metasound_mode2224s = {
+ {
+ { 8, bark_tab_s22s_128, 10, fcb22ss, 1, 6, cb2224ss0, cb2224ss1, 15 },
+ { 2, bark_tab_m22s_512, 20, fcb22sm, 2, 6, cb2224sm0, cb2224sm1, 14 },
+ { 1, bark_tab_l22s_1024, 32, fcb22sl, 4, 6, cb2224sl0, cb2224sl1, 15 }
+ },
+ 1024, 16, lsp22s, 1, 6, 4, 3, shape22s, 9, 56, 36, 7, 200
+};
+
const TwinVQModeTab ff_metasound_mode4432 = {
{
{ 16, bark_tab_s44_128, 10, fcb44ss, 1, 6, cb4432s0, cb4432s1, 23 },
@@ -5071,6 +15297,42 @@
2048, 20, lsp44s, 1, 6, 4, 4, shape44s, 9, 84, 54, 7, 200,
};
+const TwinVQModeTab ff_metasound_mode4432s = {
+ {
+ { 16, bark_tab_s44_128, 10, fcb44ss, 1, 6, cb4432s0, cb4432s1, 23 },
+ { 4, bark_tab_m44_512, 20, fcb44sm, 2, 6, cb4432m0, cb4432m1, 21 },
+ { 1, bark_tab_l44_2048, 40, fcb44sl, 4, 6, cb4432l0, cb4432l1, 22 }
+ },
+ 2048, 20, lsp44s, 1, 6, 4, 4, shape44s, 9, 84, 54, 7, 200,
+};
+
+const TwinVQModeTab ff_metasound_mode4440 = {
+ {
+ { 16, bark_tab_s44_128, 10, fcb44ss, 1, 6, cb4440ss0, cb4440ss1, 18 },
+ { 4, bark_tab_m44_512, 20, fcb44sm, 2, 6, cb4440sm0, cb4440sm1, 17 },
+ { 1, bark_tab_l44_2048, 40, fcb44sl, 4, 6, cb4440sl0, cb4440sl1, 17 }
+ },
+ 2048, 20, lsp44s, 1, 6, 4, 4, shape44s, 9, 84, 54, 7, 200
+};
+
+const TwinVQModeTab ff_metasound_mode4440s = {
+ {
+ { 16, bark_tab_s44_128, 10, fcb44ss, 1, 6, cb4440ss0, cb4440ss1, 18 },
+ { 4, bark_tab_m44_512, 20, fcb44sm, 2, 6, cb4440sm0, cb4440sm1, 17 },
+ { 1, bark_tab_l44_2048, 40, fcb44sl, 4, 6, cb4440sl0, cb4440sl1, 17 }
+ },
+ 2048, 20, lsp44s, 1, 6, 4, 4, shape44s, 9, 84, 54, 7, 200
+};
+
+const TwinVQModeTab ff_metasound_mode4448 = {
+ {
+ { 16, bark_tab_s44_128, 10, fcb44ss, 1, 6, cb4448ss0, cb4448ss1, 15 },
+ { 4, bark_tab_m44_512, 20, fcb44sm, 2, 6, cb4448sm0, cb4448sm1, 14 },
+ { 1, bark_tab_l44_2048, 40, fcb44sl, 4, 6, cb4448sl0, cb4448sl1, 14 }
+ },
+ 2048, 20, lsp44s, 1, 6, 4, 4, shape44s, 9, 84, 54, 7, 200
+};
+
const TwinVQModeTab ff_metasound_mode4448s = {
{
{ 16, bark_tab_s44_128, 10, fcb44ss, 1, 6, cb4448ss0, cb4448ss1, 15 },
diff --git a/libavcodec/mimic.c b/libavcodec/mimic.c
index a1cb5e7..31d6393 100644
--- a/libavcodec/mimic.c
+++ b/libavcodec/mimic.c
@@ -116,7 +116,8 @@
MimicContext *ctx = avctx->priv_data;
int i;
- av_free(ctx->swap_buf);
+ av_freep(&ctx->swap_buf);
+ ctx->swap_buf_size = 0;
for (i = 0; i < FF_ARRAY_ELEMS(ctx->frames); i++) {
if (ctx->frames[i].f)
diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c
index 5c25a07..187f325 100644
--- a/libavcodec/mjpegdec.c
+++ b/libavcodec/mjpegdec.c
@@ -87,9 +87,12 @@
{
MJpegDecodeContext *s = avctx->priv_data;
- if (!s->picture_ptr)
- s->picture_ptr = &s->picture;
- avcodec_get_frame_defaults(&s->picture);
+ if (!s->picture_ptr) {
+ s->picture = av_frame_alloc();
+ if (!s->picture)
+ return AVERROR(ENOMEM);
+ s->picture_ptr = s->picture;
+ }
s->avctx = avctx;
ff_hpeldsp_init(&s->hdsp, avctx->flags);
@@ -215,7 +218,7 @@
int ff_mjpeg_decode_sof(MJpegDecodeContext *s)
{
- int len, nb_components, i, width, height, pix_fmt_id;
+ int len, nb_components, i, width, height, pix_fmt_id, ret;
int h_count[MAX_COMPONENTS];
int v_count[MAX_COMPONENTS];
@@ -326,7 +329,9 @@
height *= 2;
}
- avcodec_set_dimensions(s->avctx, width, height);
+ ret = ff_set_dimensions(s->avctx, width, height);
+ if (ret < 0)
+ return ret;
s->first_picture = 0;
}
@@ -823,7 +828,7 @@
buffer[0][i] = 1 << (s->bits - 1);
for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
- uint8_t *ptr = s->picture.data[0] + (linesize * mb_y);
+ uint8_t *ptr = s->picture_ptr->data[0] + (linesize * mb_y);
if (s->interlaced && s->bottom_field)
ptr += linesize >> 1;
@@ -957,7 +962,7 @@
if(dc == 0xFFFFF)
return -1;
if(bits<=8){
- ptr = s->picture.data[c] + (linesize * (v * mb_y + y)) + (h * mb_x + x); //FIXME optimize this crap
+ ptr = s->picture_ptr->data[c] + (linesize * (v * mb_y + y)) + (h * mb_x + x); //FIXME optimize this crap
if(y==0 && toprow){
if(x==0 && leftcol){
pred= 1 << (bits - 1);
@@ -977,7 +982,7 @@
pred &= mask;
*ptr= pred + (dc << point_transform);
}else{
- ptr16 = (uint16_t*)(s->picture.data[c] + 2*(linesize * (v * mb_y + y)) + 2*(h * mb_x + x)); //FIXME optimize this crap
+ ptr16 = (uint16_t*)(s->picture_ptr->data[c] + 2*(linesize * (v * mb_y + y)) + 2*(h * mb_x + x)); //FIXME optimize this crap
if(y==0 && toprow){
if(x==0 && leftcol){
pred= 1 << (bits - 1);
@@ -1025,7 +1030,7 @@
if(dc == 0xFFFFF)
return -1;
if(bits<=8){
- ptr = s->picture.data[c] +
+ ptr = s->picture_ptr->data[c] +
(linesize * (v * mb_y + y)) +
(h * mb_x + x); //FIXME optimize this crap
PREDICT(pred, ptr[-linesize-1], ptr[-linesize], ptr[-1], predictor);
@@ -1033,7 +1038,7 @@
pred &= mask;
*ptr = pred + (dc << point_transform);
}else{
- ptr16 = (uint16_t*)(s->picture.data[c] + 2*(linesize * (v * mb_y + y)) + 2*(h * mb_x + x)); //FIXME optimize this crap
+ ptr16 = (uint16_t*)(s->picture_ptr->data[c] + 2*(linesize * (v * mb_y + y)) + 2*(h * mb_x + x)); //FIXME optimize this crap
PREDICT(pred, ptr16[-linesize-1], ptr16[-linesize], ptr16[-1], predictor);
pred &= mask;
@@ -1207,7 +1212,7 @@
int mb_x, mb_y;
int EOBRUN = 0;
int c = s->comp_index[0];
- uint8_t *data = s->picture.data[c];
+ uint8_t *data = s->picture_ptr->data[c];
int linesize = s->linesize[c];
int last_scan = 0;
int16_t *quant_matrix = s->quant_matrixes[s->quant_sindex[0]];
@@ -1368,7 +1373,7 @@
s->last_dc[i] = (4 << s->bits);
if (s->lossless) {
- av_assert0(s->picture_ptr == &s->picture);
+ av_assert0(s->picture_ptr == s->picture);
if (CONFIG_JPEGLS_DECODER && s->ls) {
// for () {
// reset_ls_coding_parameters(s, 0);
@@ -1389,7 +1394,7 @@
}
} else {
if (s->progressive && predictor) {
- av_assert0(s->picture_ptr == &s->picture);
+ av_assert0(s->picture_ptr == s->picture);
if ((ret = mjpeg_decode_scan_progressive_ac(s, predictor,
ilv, prev_shift,
point_transform)) < 0)
@@ -1441,7 +1446,7 @@
int len, id, i;
len = get_bits(&s->gb, 16);
- if (len < 5)
+ if (len < 6)
return AVERROR_INVALIDDATA;
if (8 * len > get_bits_left(&s->gb))
return AVERROR_INVALIDDATA;
@@ -1555,7 +1560,7 @@
}
/* EXIF metadata */
- if (s->start_code == APP1 && id == AV_RB32("Exif")) {
+ if (s->start_code == APP1 && id == AV_RB32("Exif") && len >= 2) {
GetByteContext gbytes;
int ret, le, ifd_offset, bytes_read;
const uint8_t *aligned;
@@ -2035,7 +2040,10 @@
av_log(avctx, AV_LOG_INFO, "Single field\n");
}
- if (s->picture_ptr)
+ if (s->picture) {
+ av_frame_free(&s->picture);
+ s->picture_ptr = NULL;
+ } else if (s->picture_ptr)
av_frame_unref(s->picture_ptr);
av_free(s->buffer);
diff --git a/libavcodec/mjpegdec.h b/libavcodec/mjpegdec.h
index fa69d50..1335c66 100644
--- a/libavcodec/mjpegdec.h
+++ b/libavcodec/mjpegdec.h
@@ -90,7 +90,7 @@
int h_max, v_max; /* maximum h and v counts */
int quant_index[4]; /* quant table index for each component */
int last_dc[MAX_COMPONENTS]; /* last DEQUANTIZED dc (XXX: am I right to do that ?) */
- AVFrame picture; /* picture structure */
+ AVFrame *picture; /* picture structure */
AVFrame *picture_ptr; /* pointer to picture structure */
int got_picture; ///< we found a SOF and picture is valid, too.
int linesize[MAX_COMPONENTS]; ///< linesize << interlaced
diff --git a/libavcodec/mjpegenc.c b/libavcodec/mjpegenc.c
index 74817ca..ffc29fd 100644
--- a/libavcodec/mjpegenc.c
+++ b/libavcodec/mjpegenc.c
@@ -30,6 +30,8 @@
* MJPEG encoder.
*/
+#include "libavutil/pixdesc.h"
+
#include "avcodec.h"
#include "mpegvideo.h"
#include "mjpeg.h"
@@ -84,10 +86,9 @@
}
/* table_class: 0 = DC coef, 1 = AC coefs */
-static int put_huffman_table(MpegEncContext *s, int table_class, int table_id,
+static int put_huffman_table(PutBitContext *p, int table_class, int table_id,
const uint8_t *bits_table, const uint8_t *value_table)
{
- PutBitContext *p = &s->pb;
int n, i;
put_bits(p, 4, table_class);
@@ -105,13 +106,15 @@
return n + 17;
}
-static void jpeg_table_header(MpegEncContext *s)
+static void jpeg_table_header(AVCodecContext *avctx, PutBitContext *p,
+ ScanTable *intra_scantable,
+ uint16_t intra_matrix[64],
+ int hsample[3])
{
- PutBitContext *p = &s->pb;
int i, j, size;
uint8_t *ptr;
- if (s->avctx->codec_id != AV_CODEC_ID_LJPEG) {
+ if (avctx->codec_id != AV_CODEC_ID_LJPEG) {
/* quant matrixes */
put_marker(p, DQT);
#ifdef TWOMATRIXES
@@ -122,8 +125,8 @@
put_bits(p, 4, 0); /* 8 bit precision */
put_bits(p, 4, 0); /* table 0 */
for(i=0;i<64;i++) {
- j = s->intra_scantable.permutated[i];
- put_bits(p, 8, s->intra_matrix[j]);
+ j = intra_scantable->permutated[i];
+ put_bits(p, 8, intra_matrix[j]);
}
#ifdef TWOMATRIXES
put_bits(p, 4, 0); /* 8 bit precision */
@@ -135,10 +138,10 @@
#endif
}
- if(s->avctx->active_thread_type & FF_THREAD_SLICE){
+ if(avctx->active_thread_type & FF_THREAD_SLICE){
put_marker(p, DRI);
put_bits(p, 16, 4);
- put_bits(p, 16, (s->width-1)/(8*s->mjpeg_hsample[0]) + 1);
+ put_bits(p, 16, (avctx->width-1)/(8*hsample[0]) + 1);
}
/* huffman table */
@@ -147,40 +150,38 @@
ptr = put_bits_ptr(p);
put_bits(p, 16, 0); /* patched later */
size = 2;
- size += put_huffman_table(s, 0, 0, avpriv_mjpeg_bits_dc_luminance,
+ size += put_huffman_table(p, 0, 0, avpriv_mjpeg_bits_dc_luminance,
avpriv_mjpeg_val_dc);
- size += put_huffman_table(s, 0, 1, avpriv_mjpeg_bits_dc_chrominance,
+ size += put_huffman_table(p, 0, 1, avpriv_mjpeg_bits_dc_chrominance,
avpriv_mjpeg_val_dc);
- size += put_huffman_table(s, 1, 0, avpriv_mjpeg_bits_ac_luminance,
+ size += put_huffman_table(p, 1, 0, avpriv_mjpeg_bits_ac_luminance,
avpriv_mjpeg_val_ac_luminance);
- size += put_huffman_table(s, 1, 1, avpriv_mjpeg_bits_ac_chrominance,
+ size += put_huffman_table(p, 1, 1, avpriv_mjpeg_bits_ac_chrominance,
avpriv_mjpeg_val_ac_chrominance);
AV_WB16(ptr, size);
}
-static void jpeg_put_comments(MpegEncContext *s)
+static void jpeg_put_comments(AVCodecContext *avctx, PutBitContext *p)
{
- PutBitContext *p = &s->pb;
int size;
uint8_t *ptr;
- if (s->avctx->sample_aspect_ratio.num /* && !lossless */)
- {
- /* JFIF header */
- put_marker(p, APP0);
- put_bits(p, 16, 16);
- avpriv_put_string(p, "JFIF", 1); /* this puts the trailing zero-byte too */
- put_bits(p, 16, 0x0102); /* v 1.02 */
- put_bits(p, 8, 0); /* units type: 0 - aspect ratio */
- put_bits(p, 16, s->avctx->sample_aspect_ratio.num);
- put_bits(p, 16, s->avctx->sample_aspect_ratio.den);
- put_bits(p, 8, 0); /* thumbnail width */
- put_bits(p, 8, 0); /* thumbnail height */
+ if (avctx->sample_aspect_ratio.num > 0 && avctx->sample_aspect_ratio.den > 0) {
+ /* JFIF header */
+ put_marker(p, APP0);
+ put_bits(p, 16, 16);
+ avpriv_put_string(p, "JFIF", 1); /* this puts the trailing zero-byte too */
+ put_bits(p, 16, 0x0102); /* v 1.02 */
+ put_bits(p, 8, 0); /* units type: 0 - aspect ratio */
+ put_bits(p, 16, avctx->sample_aspect_ratio.num);
+ put_bits(p, 16, avctx->sample_aspect_ratio.den);
+ put_bits(p, 8, 0); /* thumbnail width */
+ put_bits(p, 8, 0); /* thumbnail height */
}
/* comment */
- if(!(s->flags & CODEC_FLAG_BITEXACT)){
+ if (!(avctx->flags & CODEC_FLAG_BITEXACT)) {
put_marker(p, COM);
flush_put_bits(p);
ptr = put_bits_ptr(p);
@@ -190,9 +191,9 @@
AV_WB16(ptr, size);
}
- if( s->avctx->pix_fmt == AV_PIX_FMT_YUV420P
- ||s->avctx->pix_fmt == AV_PIX_FMT_YUV422P
- ||s->avctx->pix_fmt == AV_PIX_FMT_YUV444P){
+ if (avctx->pix_fmt == AV_PIX_FMT_YUV420P ||
+ avctx->pix_fmt == AV_PIX_FMT_YUV422P ||
+ avctx->pix_fmt == AV_PIX_FMT_YUV444P) {
put_marker(p, COM);
flush_put_bits(p);
ptr = put_bits_ptr(p);
@@ -203,105 +204,148 @@
}
}
-void ff_mjpeg_encode_picture_header(MpegEncContext *s)
+void ff_mjpeg_init_hvsample(AVCodecContext *avctx, int hsample[3], int vsample[3])
{
- const int lossless= s->avctx->codec_id != AV_CODEC_ID_MJPEG;
+ int chroma_h_shift, chroma_v_shift;
+
+ av_pix_fmt_get_chroma_sub_sample(avctx->pix_fmt, &chroma_h_shift,
+ &chroma_v_shift);
+ if (avctx->codec->id == AV_CODEC_ID_LJPEG &&
+ ( avctx->pix_fmt == AV_PIX_FMT_BGR0
+ || avctx->pix_fmt == AV_PIX_FMT_BGRA
+ || avctx->pix_fmt == AV_PIX_FMT_BGR24)) {
+ vsample[0] = hsample[0] =
+ vsample[1] = hsample[1] =
+ vsample[2] = hsample[2] = 1;
+ } else if (avctx->pix_fmt == AV_PIX_FMT_YUV444P || avctx->pix_fmt == AV_PIX_FMT_YUVJ444P) {
+ vsample[0] = vsample[1] = vsample[2] = 2;
+ hsample[0] = hsample[1] = hsample[2] = 1;
+ } else {
+ vsample[0] = 2;
+ vsample[1] = 2 >> chroma_v_shift;
+ vsample[2] = 2 >> chroma_v_shift;
+ hsample[0] = 2;
+ hsample[1] = 2 >> chroma_h_shift;
+ hsample[2] = 2 >> chroma_h_shift;
+ }
+}
+
+void ff_mjpeg_encode_picture_header(AVCodecContext *avctx, PutBitContext *pb,
+ ScanTable *intra_scantable,
+ uint16_t intra_matrix[64])
+{
+ const int lossless = avctx->codec_id != AV_CODEC_ID_MJPEG && avctx->codec_id != AV_CODEC_ID_AMV;
+ int hsample[3], vsample[3];
int i;
- put_marker(&s->pb, SOI);
+ ff_mjpeg_init_hvsample(avctx, hsample, vsample);
+
+ put_marker(pb, SOI);
// hack for AMV mjpeg format
- if(s->avctx->codec_id == AV_CODEC_ID_AMV) goto end;
+ if(avctx->codec_id == AV_CODEC_ID_AMV) goto end;
- jpeg_put_comments(s);
+ jpeg_put_comments(avctx, pb);
- jpeg_table_header(s);
+ jpeg_table_header(avctx, pb, intra_scantable, intra_matrix, hsample);
- switch(s->avctx->codec_id){
- case AV_CODEC_ID_MJPEG: put_marker(&s->pb, SOF0 ); break;
- case AV_CODEC_ID_LJPEG: put_marker(&s->pb, SOF3 ); break;
+ switch (avctx->codec_id) {
+ case AV_CODEC_ID_MJPEG: put_marker(pb, SOF0 ); break;
+ case AV_CODEC_ID_LJPEG: put_marker(pb, SOF3 ); break;
default: av_assert0(0);
}
- put_bits(&s->pb, 16, 17);
- if(lossless && (s->avctx->pix_fmt == AV_PIX_FMT_BGR0
- || s->avctx->pix_fmt == AV_PIX_FMT_BGRA
- || s->avctx->pix_fmt == AV_PIX_FMT_BGR24))
- put_bits(&s->pb, 8, 9); /* 9 bits/component RCT */
+ put_bits(pb, 16, 17);
+ if (lossless && ( avctx->pix_fmt == AV_PIX_FMT_BGR0
+ || avctx->pix_fmt == AV_PIX_FMT_BGRA
+ || avctx->pix_fmt == AV_PIX_FMT_BGR24))
+ put_bits(pb, 8, 9); /* 9 bits/component RCT */
else
- put_bits(&s->pb, 8, 8); /* 8 bits/component */
- put_bits(&s->pb, 16, s->height);
- put_bits(&s->pb, 16, s->width);
- put_bits(&s->pb, 8, 3); /* 3 components */
+ put_bits(pb, 8, 8); /* 8 bits/component */
+ put_bits(pb, 16, avctx->height);
+ put_bits(pb, 16, avctx->width);
+ put_bits(pb, 8, 3); /* 3 components */
/* Y component */
- put_bits(&s->pb, 8, 1); /* component number */
- put_bits(&s->pb, 4, s->mjpeg_hsample[0]); /* H factor */
- put_bits(&s->pb, 4, s->mjpeg_vsample[0]); /* V factor */
- put_bits(&s->pb, 8, 0); /* select matrix */
+ put_bits(pb, 8, 1); /* component number */
+ put_bits(pb, 4, hsample[0]); /* H factor */
+ put_bits(pb, 4, vsample[0]); /* V factor */
+ put_bits(pb, 8, 0); /* select matrix */
/* Cb component */
- put_bits(&s->pb, 8, 2); /* component number */
- put_bits(&s->pb, 4, s->mjpeg_hsample[1]); /* H factor */
- put_bits(&s->pb, 4, s->mjpeg_vsample[1]); /* V factor */
+ put_bits(pb, 8, 2); /* component number */
+ put_bits(pb, 4, hsample[1]); /* H factor */
+ put_bits(pb, 4, vsample[1]); /* V factor */
#ifdef TWOMATRIXES
- put_bits(&s->pb, 8, lossless ? 0 : 1); /* select matrix */
+ put_bits(pb, 8, lossless ? 0 : 1); /* select matrix */
#else
- put_bits(&s->pb, 8, 0); /* select matrix */
+ put_bits(pb, 8, 0); /* select matrix */
#endif
/* Cr component */
- put_bits(&s->pb, 8, 3); /* component number */
- put_bits(&s->pb, 4, s->mjpeg_hsample[2]); /* H factor */
- put_bits(&s->pb, 4, s->mjpeg_vsample[2]); /* V factor */
+ put_bits(pb, 8, 3); /* component number */
+ put_bits(pb, 4, hsample[2]); /* H factor */
+ put_bits(pb, 4, vsample[2]); /* V factor */
#ifdef TWOMATRIXES
- put_bits(&s->pb, 8, lossless ? 0 : 1); /* select matrix */
+ put_bits(pb, 8, lossless ? 0 : 1); /* select matrix */
#else
- put_bits(&s->pb, 8, 0); /* select matrix */
+ put_bits(pb, 8, 0); /* select matrix */
#endif
/* scan header */
- put_marker(&s->pb, SOS);
- put_bits(&s->pb, 16, 12); /* length */
- put_bits(&s->pb, 8, 3); /* 3 components */
+ put_marker(pb, SOS);
+ put_bits(pb, 16, 12); /* length */
+ put_bits(pb, 8, 3); /* 3 components */
/* Y component */
- put_bits(&s->pb, 8, 1); /* index */
- put_bits(&s->pb, 4, 0); /* DC huffman table index */
- put_bits(&s->pb, 4, 0); /* AC huffman table index */
+ put_bits(pb, 8, 1); /* index */
+ put_bits(pb, 4, 0); /* DC huffman table index */
+ put_bits(pb, 4, 0); /* AC huffman table index */
/* Cb component */
- put_bits(&s->pb, 8, 2); /* index */
- put_bits(&s->pb, 4, 1); /* DC huffman table index */
- put_bits(&s->pb, 4, lossless ? 0 : 1); /* AC huffman table index */
+ put_bits(pb, 8, 2); /* index */
+ put_bits(pb, 4, 1); /* DC huffman table index */
+ put_bits(pb, 4, lossless ? 0 : 1); /* AC huffman table index */
/* Cr component */
- put_bits(&s->pb, 8, 3); /* index */
- put_bits(&s->pb, 4, 1); /* DC huffman table index */
- put_bits(&s->pb, 4, lossless ? 0 : 1); /* AC huffman table index */
+ put_bits(pb, 8, 3); /* index */
+ put_bits(pb, 4, 1); /* DC huffman table index */
+ put_bits(pb, 4, lossless ? 0 : 1); /* AC huffman table index */
- put_bits(&s->pb, 8, lossless ? s->avctx->prediction_method+1 : 0); /* Ss (not used) */
+ put_bits(pb, 8, lossless ? avctx->prediction_method + 1 : 0); /* Ss (not used) */
- switch(s->avctx->codec_id){
- case AV_CODEC_ID_MJPEG: put_bits(&s->pb, 8, 63); break; /* Se (not used) */
- case AV_CODEC_ID_LJPEG: put_bits(&s->pb, 8, 0); break; /* not used */
+ switch (avctx->codec_id) {
+ case AV_CODEC_ID_MJPEG: put_bits(pb, 8, 63); break; /* Se (not used) */
+ case AV_CODEC_ID_LJPEG: put_bits(pb, 8, 0); break; /* not used */
default: av_assert0(0);
}
- put_bits(&s->pb, 8, 0); /* Ah/Al (not used) */
+ put_bits(pb, 8, 0); /* Ah/Al (not used) */
end:
- s->esc_pos = put_bits_count(&s->pb) >> 3;
- for(i=1; i<s->slice_context_count; i++)
- s->thread_context[i]->esc_pos = 0;
+ if (!lossless) {
+ MpegEncContext *s = avctx->priv_data;
+ av_assert0(avctx->codec->priv_data_size == sizeof(MpegEncContext));
+
+ s->esc_pos = put_bits_count(pb) >> 3;
+ for(i=1; i<s->slice_context_count; i++)
+ s->thread_context[i]->esc_pos = 0;
+ }
}
-static void escape_FF(MpegEncContext *s, int start)
+void ff_mjpeg_escape_FF(PutBitContext *pb, int start)
{
- int size= put_bits_count(&s->pb) - start*8;
+ int size;
int i, ff_count;
- uint8_t *buf= s->pb.buf + start;
+ uint8_t *buf = pb->buf + start;
int align= (-(size_t)(buf))&3;
+ int pad = (-put_bits_count(pb))&7;
+
+ if (pad)
+ put_bits(pb, pad, (1<<pad)-1);
+
+ flush_put_bits(pb);
+ size = put_bits_count(pb) - start * 8;
av_assert1((size&7) == 0);
size >>= 3;
@@ -333,8 +377,8 @@
if(ff_count==0) return;
- flush_put_bits(&s->pb);
- skip_put_bytes(&s->pb, ff_count);
+ flush_put_bits(pb);
+ skip_put_bytes(pb, ff_count);
for(i=size-1; ff_count; i--){
int v= buf[i];
@@ -350,14 +394,11 @@
void ff_mjpeg_encode_stuffing(MpegEncContext *s)
{
- int length, i;
+ int i;
PutBitContext *pbc = &s->pb;
int mb_y = s->mb_y - !s->mb_x;
- length= (-put_bits_count(pbc))&7;
- if(length) put_bits(pbc, length, (1<<length)-1);
- flush_put_bits(&s->pb);
- escape_FF(s, s->esc_pos);
+ ff_mjpeg_escape_FF(pbc, s->esc_pos);
if((s->avctx->active_thread_type & FF_THREAD_SLICE) && mb_y < s->mb_height)
put_marker(pbc, RST0 + (mb_y&7));
@@ -367,22 +408,20 @@
s->last_dc[i] = 128 << s->intra_dc_precision;
}
-void ff_mjpeg_encode_picture_trailer(MpegEncContext *s)
+void ff_mjpeg_encode_picture_trailer(PutBitContext *pb, int header_bits)
{
+ av_assert1((header_bits & 7) == 0);
- av_assert1((s->header_bits&7)==0);
-
-
- put_marker(&s->pb, EOI);
+ put_marker(pb, EOI);
}
-void ff_mjpeg_encode_dc(MpegEncContext *s, int val,
+void ff_mjpeg_encode_dc(PutBitContext *pb, int val,
uint8_t *huff_size, uint16_t *huff_code)
{
int mant, nbits;
if (val == 0) {
- put_bits(&s->pb, huff_size[0], huff_code[0]);
+ put_bits(pb, huff_size[0], huff_code[0]);
} else {
mant = val;
if (val < 0) {
@@ -392,9 +431,9 @@
nbits= av_log2_16bit(val) + 1;
- put_bits(&s->pb, huff_size[nbits], huff_code[nbits]);
+ put_bits(pb, huff_size[nbits], huff_code[nbits]);
- put_sbits(&s->pb, nbits, mant);
+ put_sbits(pb, nbits, mant);
}
}
@@ -411,11 +450,11 @@
dc = block[0]; /* overflow is impossible */
val = dc - s->last_dc[component];
if (n < 4) {
- ff_mjpeg_encode_dc(s, val, m->huff_size_dc_luminance, m->huff_code_dc_luminance);
+ ff_mjpeg_encode_dc(&s->pb, val, m->huff_size_dc_luminance, m->huff_code_dc_luminance);
huff_size_ac = m->huff_size_ac_luminance;
huff_code_ac = m->huff_code_ac_luminance;
} else {
- ff_mjpeg_encode_dc(s, val, m->huff_size_dc_chrominance, m->huff_code_dc_chrominance);
+ ff_mjpeg_encode_dc(&s->pb, val, m->huff_size_dc_chrominance, m->huff_code_dc_chrominance);
huff_size_ac = m->huff_size_ac_chrominance;
huff_code_ac = m->huff_code_ac_chrominance;
}
@@ -441,7 +480,7 @@
mant--;
}
- nbits= av_log2(val) + 1;
+ nbits= av_log2_16bit(val) + 1;
code = (run << 4) | nbits;
put_bits(&s->pb, huff_size_ac[code], huff_code_ac[code]);
@@ -500,6 +539,9 @@
MpegEncContext *s = avctx->priv_data;
AVFrame pic = *pic_arg;
int i;
+ int chroma_h_shift, chroma_v_shift;
+
+ av_pix_fmt_get_chroma_sub_sample(avctx->pix_fmt, &chroma_h_shift, &chroma_v_shift);
//CODEC_FLAG_EMU_EDGE have to be cleared
if(s->avctx->flags & CODEC_FLAG_EMU_EDGE)
@@ -507,7 +549,8 @@
//picture should be flipped upside-down
for(i=0; i < 3; i++) {
- pic.data[i] += (pic.linesize[i] * (s->mjpeg_vsample[i] * (8 * s->mb_height -((s->height/V_MAX)&7)) - 1 ));
+ int vsample = i ? 2 >> chroma_v_shift : 2;
+ pic.data[i] += (pic.linesize[i] * (vsample * (8 * s->mb_height -((s->height/V_MAX)&7)) - 1 ));
pic.linesize[i] *= -1;
}
return ff_MPV_encode_picture(avctx, pkt, &pic, got_packet);
diff --git a/libavcodec/mjpegenc.h b/libavcodec/mjpegenc.h
index ce0c1cc..4b19e21 100644
--- a/libavcodec/mjpegenc.h
+++ b/libavcodec/mjpegenc.h
@@ -51,10 +51,14 @@
int ff_mjpeg_encode_init(MpegEncContext *s);
void ff_mjpeg_encode_close(MpegEncContext *s);
-void ff_mjpeg_encode_picture_header(MpegEncContext *s);
-void ff_mjpeg_encode_picture_trailer(MpegEncContext *s);
+void ff_mjpeg_encode_picture_header(AVCodecContext *avctx, PutBitContext *pb,
+ ScanTable *intra_scantable,
+ uint16_t intra_matrix[64]);
+void ff_mjpeg_encode_picture_trailer(PutBitContext *pb, int header_bits);
+void ff_mjpeg_escape_FF(PutBitContext *pb, int start);
void ff_mjpeg_encode_stuffing(MpegEncContext *s);
-void ff_mjpeg_encode_dc(MpegEncContext *s, int val,
+void ff_mjpeg_init_hvsample(AVCodecContext *avctx, int hsample[3], int vsample[3]);
+void ff_mjpeg_encode_dc(PutBitContext *pb, int val,
uint8_t *huff_size, uint16_t *huff_code);
void ff_mjpeg_encode_mb(MpegEncContext *s, int16_t block[6][64]);
diff --git a/libavcodec/mmvideo.c b/libavcodec/mmvideo.c
index 800e65c..ab59b58 100644
--- a/libavcodec/mmvideo.c
+++ b/libavcodec/mmvideo.c
@@ -48,7 +48,7 @@
typedef struct MmContext {
AVCodecContext *avctx;
- AVFrame frame;
+ AVFrame *frame;
int palette[AVPALETTE_COUNT];
GetByteContext gb;
} MmContext;
@@ -61,7 +61,9 @@
avctx->pix_fmt = AV_PIX_FMT_PAL8;
- avcodec_get_frame_defaults(&s->frame);
+ s->frame = av_frame_alloc();
+ if (!s->frame)
+ return AVERROR(ENOMEM);
return 0;
}
@@ -108,9 +110,9 @@
return AVERROR_INVALIDDATA;
if (color) {
- memset(s->frame.data[0] + y*s->frame.linesize[0] + x, color, run_length);
+ memset(s->frame->data[0] + y*s->frame->linesize[0] + x, color, run_length);
if (half_vert)
- memset(s->frame.data[0] + (y+1)*s->frame.linesize[0] + x, color, run_length);
+ memset(s->frame->data[0] + (y+1)*s->frame->linesize[0] + x, color, run_length);
}
x+= run_length;
@@ -129,7 +131,8 @@
*/
static int mm_decode_inter(MmContext * s, int half_horiz, int half_vert)
{
- int data_off = bytestream2_get_le16(&s->gb), y = 0;
+ int data_off = bytestream2_get_le16(&s->gb);
+ int y = 0;
GetByteContext data_ptr;
if (bytestream2_get_bytes_left(&s->gb) < data_off)
@@ -158,13 +161,13 @@
return AVERROR_INVALIDDATA;
if (replace) {
int color = bytestream2_get_byte(&data_ptr);
- s->frame.data[0][y*s->frame.linesize[0] + x] = color;
+ s->frame->data[0][y*s->frame->linesize[0] + x] = color;
if (half_horiz)
- s->frame.data[0][y*s->frame.linesize[0] + x + 1] = color;
+ s->frame->data[0][y*s->frame->linesize[0] + x + 1] = color;
if (half_vert) {
- s->frame.data[0][(y+1)*s->frame.linesize[0] + x] = color;
+ s->frame->data[0][(y+1)*s->frame->linesize[0] + x] = color;
if (half_horiz)
- s->frame.data[0][(y+1)*s->frame.linesize[0] + x + 1] = color;
+ s->frame->data[0][(y+1)*s->frame->linesize[0] + x + 1] = color;
}
}
x += 1 + half_horiz;
@@ -193,7 +196,7 @@
buf_size -= MM_PREAMBLE_SIZE;
bytestream2_init(&s->gb, buf, buf_size);
- if ((res = ff_reget_buffer(avctx, &s->frame)) < 0)
+ if ((res = ff_reget_buffer(avctx, s->frame)) < 0)
return res;
switch(type) {
@@ -211,9 +214,9 @@
if (res < 0)
return res;
- memcpy(s->frame.data[1], s->palette, AVPALETTE_SIZE);
+ memcpy(s->frame->data[1], s->palette, AVPALETTE_SIZE);
- if ((res = av_frame_ref(data, &s->frame)) < 0)
+ if ((res = av_frame_ref(data, s->frame)) < 0)
return res;
*got_frame = 1;
@@ -225,7 +228,7 @@
{
MmContext *s = avctx->priv_data;
- av_frame_unref(&s->frame);
+ av_frame_free(&s->frame);
return 0;
}
diff --git a/libavcodec/motionpixels.c b/libavcodec/motionpixels.c
index f8aa08b..089909a 100644
--- a/libavcodec/motionpixels.c
+++ b/libavcodec/motionpixels.c
@@ -36,7 +36,7 @@
typedef struct MotionPixelsContext {
AVCodecContext *avctx;
- AVFrame frame;
+ AVFrame *frame;
DSPContext dsp;
uint8_t *changes_map;
int offset_bits_len;
@@ -50,6 +50,19 @@
int bswapbuf_size;
} MotionPixelsContext;
+static av_cold int mp_decode_end(AVCodecContext *avctx)
+{
+ MotionPixelsContext *mp = avctx->priv_data;
+
+ av_freep(&mp->changes_map);
+ av_freep(&mp->vpt);
+ av_freep(&mp->hpt);
+ av_freep(&mp->bswapbuf);
+ av_frame_free(&mp->frame);
+
+ return 0;
+}
+
static av_cold int mp_decode_init(AVCodecContext *avctx)
{
MotionPixelsContext *mp = avctx->priv_data;
@@ -75,7 +88,13 @@
return AVERROR(ENOMEM);
}
avctx->pix_fmt = AV_PIX_FMT_RGB555;
- avcodec_get_frame_defaults(&mp->frame);
+
+ mp->frame = av_frame_alloc();
+ if (!mp->frame) {
+ mp_decode_end(avctx);
+ return AVERROR(ENOMEM);
+ }
+
return 0;
}
@@ -96,14 +115,14 @@
continue;
w = FFMIN(w, mp->avctx->width - x);
h = FFMIN(h, mp->avctx->height - y);
- pixels = (uint16_t *)&mp->frame.data[0][y * mp->frame.linesize[0] + x * 2];
+ pixels = (uint16_t *)&mp->frame->data[0][y * mp->frame->linesize[0] + x * 2];
while (h--) {
mp->changes_map[offset] = w;
if (read_color)
for (i = 0; i < w; ++i)
pixels[i] = color;
offset += mp->avctx->width;
- pixels += mp->frame.linesize[0] / 2;
+ pixels += mp->frame->linesize[0] / 2;
}
}
}
@@ -165,7 +184,7 @@
{
int color;
- color = *(uint16_t *)&mp->frame.data[0][y * mp->frame.linesize[0] + x * 2];
+ color = *(uint16_t *)&mp->frame->data[0][y * mp->frame->linesize[0] + x * 2];
return mp_rgb_yuv_table[color];
}
@@ -174,7 +193,7 @@
int color;
color = mp_yuv_to_rgb(p->y, p->v, p->u, 1);
- *(uint16_t *)&mp->frame.data[0][y * mp->frame.linesize[0] + x * 2] = color;
+ *(uint16_t *)&mp->frame->data[0][y * mp->frame->linesize[0] + x * 2] = color;
}
static int mp_get_vlc(MotionPixelsContext *mp, GetBitContext *gb)
@@ -271,17 +290,16 @@
GetBitContext gb;
int i, count1, count2, sz, ret;
- if ((ret = ff_reget_buffer(avctx, &mp->frame)) < 0)
+ if ((ret = ff_reget_buffer(avctx, mp->frame)) < 0)
return ret;
/* le32 bitstream msb first */
- av_fast_malloc(&mp->bswapbuf, &mp->bswapbuf_size, buf_size + FF_INPUT_BUFFER_PADDING_SIZE);
+ av_fast_padded_malloc(&mp->bswapbuf, &mp->bswapbuf_size, buf_size);
if (!mp->bswapbuf)
return AVERROR(ENOMEM);
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);
@@ -297,7 +315,7 @@
goto end;
if (mp->changes_map[0] == 0) {
- *(uint16_t *)mp->frame.data[0] = get_bits(&gb, 15);
+ *(uint16_t *)mp->frame->data[0] = get_bits(&gb, 15);
mp->changes_map[0] = 1;
}
if (mp_read_codes_table(mp, &gb) < 0)
@@ -317,25 +335,12 @@
ff_free_vlc(&mp->vlc);
end:
- if ((ret = av_frame_ref(data, &mp->frame)) < 0)
+ if ((ret = av_frame_ref(data, mp->frame)) < 0)
return ret;
*got_frame = 1;
return buf_size;
}
-static av_cold int mp_decode_end(AVCodecContext *avctx)
-{
- MotionPixelsContext *mp = avctx->priv_data;
-
- av_freep(&mp->changes_map);
- av_freep(&mp->vpt);
- av_freep(&mp->hpt);
- av_freep(&mp->bswapbuf);
- av_frame_unref(&mp->frame);
-
- return 0;
-}
-
AVCodec ff_motionpixels_decoder = {
.name = "motionpixels",
.long_name = NULL_IF_CONFIG_SMALL("Motion Pixels video"),
diff --git a/libavcodec/mp3_header_compress_bsf.c b/libavcodec/mp3_header_compress_bsf.c
deleted file mode 100644
index e479f6b..0000000
--- a/libavcodec/mp3_header_compress_bsf.c
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
- *
- * This file is part of FFmpeg.
- *
- * FFmpeg is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * FFmpeg is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with FFmpeg; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "libavutil/common.h"
-#include "libavutil/intreadwrite.h"
-#include "avcodec.h"
-#include "mpegaudiodecheader.h"
-
-
-static int mp3_header_compress(AVBitStreamFilterContext *bsfc, AVCodecContext *avctx, const char *args,
- uint8_t **poutbuf, int *poutbuf_size,
- const uint8_t *buf, int buf_size, int keyframe){
- uint32_t header, extraheader;
- int mode_extension, header_size;
-
- if(avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL){
- av_log(avctx, AV_LOG_ERROR, "not standards compliant\n");
- return -1;
- }
-
- header = AV_RB32(buf);
- mode_extension= (header>>4)&3;
-
- if(ff_mpa_check_header(header) < 0 || (header&0x60000) != 0x20000){
-output_unchanged:
- *poutbuf= (uint8_t *) buf;
- *poutbuf_size= buf_size;
-
- av_log(avctx, AV_LOG_INFO, "cannot compress %08X\n", header);
- return 0;
- }
-
- if(avctx->extradata_size == 0){
- avctx->extradata_size=15;
- avctx->extradata= av_malloc(avctx->extradata_size);
- strcpy(avctx->extradata, "FFCMP3 0.0");
- memcpy(avctx->extradata+11, buf, 4);
- }
- if(avctx->extradata_size != 15){
- av_log(avctx, AV_LOG_ERROR, "Extradata invalid\n");
- return -1;
- }
- extraheader = AV_RB32(avctx->extradata+11);
- if((extraheader&MP3_MASK) != (header&MP3_MASK))
- goto output_unchanged;
-
- header_size= (header&0x10000) ? 4 : 6;
-
- *poutbuf_size= buf_size - header_size;
- *poutbuf= av_malloc(buf_size - header_size + FF_INPUT_BUFFER_PADDING_SIZE);
- memcpy(*poutbuf, buf + header_size, buf_size - header_size + FF_INPUT_BUFFER_PADDING_SIZE);
-
- if(avctx->channels==2){
- if((header & (3<<19)) != 3<<19){
- (*poutbuf)[1] &= 0x3F;
- (*poutbuf)[1] |= mode_extension<<6;
- FFSWAP(int, (*poutbuf)[1], (*poutbuf)[2]);
- }else{
- (*poutbuf)[1] &= 0x8F;
- (*poutbuf)[1] |= mode_extension<<4;
- }
- }
-
- return 1;
-}
-
-AVBitStreamFilter ff_mp3_header_compress_bsf={
- .name = "mp3comp",
- .filter = mp3_header_compress,
-};
diff --git a/libavcodec/mpeg12.c b/libavcodec/mpeg12.c
index 383d5c2..c391ffd 100644
--- a/libavcodec/mpeg12.c
+++ b/libavcodec/mpeg12.c
@@ -38,7 +38,6 @@
#include "mpeg12data.h"
#include "bytestream.h"
#include "vdpau_internal.h"
-#include "xvmc_internal.h"
#include "thread.h"
uint8_t ff_mpeg12_static_rl_table_store[2][2][2*MAX_RUN + MAX_LEVEL + 3];
diff --git a/libavcodec/mpeg12dec.c b/libavcodec/mpeg12dec.c
index 82b503d..1104867 100644
--- a/libavcodec/mpeg12dec.c
+++ b/libavcodec/mpeg12dec.c
@@ -38,19 +38,22 @@
#include "vdpau_internal.h"
#include "xvmc_internal.h"
#include "thread.h"
+#include "version.h"
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 */
+ uint8_t *a53_caption;
+ int a53_caption_size;
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 tmpgexs;
+ int first_slice;
int extradata_decoded;
} Mpeg1Context;
@@ -773,6 +776,8 @@
} else
memset(s->last_mv, 0, sizeof(s->last_mv)); /* reset mv prediction */
s->mb_intra = 1;
+#if FF_API_XVMC
+FF_DISABLE_DEPRECATION_WARNINGS
// 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
@@ -780,6 +785,8 @@
exchange_uv(s);
}
}
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif /* FF_API_XVMC */
if (s->codec_id == AV_CODEC_ID_MPEG2VIDEO) {
if (s->flags2 & CODEC_FLAG2_FAST) {
@@ -992,6 +999,8 @@
return -1;
}
+#if FF_API_XVMC
+FF_DISABLE_DEPRECATION_WARNINGS
//if 1, we memcpy blocks in xvmcvideo
if (CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration > 1) {
ff_xvmc_pack_pblocks(s, cbp);
@@ -999,6 +1008,8 @@
exchange_uv(s);
}
}
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif /* FF_API_XVMC */
if (s->codec_id == AV_CODEC_ID_MPEG2VIDEO) {
if (s->flags2 & CODEC_FLAG2_FAST) {
@@ -1122,10 +1133,12 @@
}
static const enum AVPixelFormat mpeg1_hwaccel_pixfmt_list_420[] = {
+#if FF_API_XVMC
#if CONFIG_MPEG_XVMC_DECODER
AV_PIX_FMT_XVMC_MPEG2_IDCT,
AV_PIX_FMT_XVMC_MPEG2_MC,
#endif
+#endif /* FF_API_XVMC */
#if CONFIG_MPEG1_VDPAU_HWACCEL
AV_PIX_FMT_VDPAU_MPEG1,
AV_PIX_FMT_VDPAU,
@@ -1135,10 +1148,12 @@
};
static const enum AVPixelFormat mpeg2_hwaccel_pixfmt_list_420[] = {
+#if FF_API_XVMC
#if CONFIG_MPEG_XVMC_DECODER
AV_PIX_FMT_XVMC_MPEG2_IDCT,
AV_PIX_FMT_XVMC_MPEG2_MC,
#endif
+#endif /* FF_API_XVMC */
#if CONFIG_MPEG2_VDPAU_HWACCEL
AV_PIX_FMT_VDPAU_MPEG2,
AV_PIX_FMT_VDPAU,
@@ -1175,14 +1190,22 @@
static void setup_hwaccel_for_pixfmt(AVCodecContext *avctx)
{
+#if FF_API_XVMC
+FF_DISABLE_DEPRECATION_WARNINGS
if (avctx->pix_fmt != AV_PIX_FMT_XVMC_MPEG2_IDCT && avctx->pix_fmt != AV_PIX_FMT_XVMC_MPEG2_MC) {
avctx->xvmc_acceleration = 0;
} else if (!avctx->xvmc_acceleration) {
avctx->xvmc_acceleration = 2;
}
- avctx->hwaccel = ff_find_hwaccel(avctx->codec->id, avctx->pix_fmt);
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif /* FF_API_XVMC */
+ avctx->hwaccel = ff_find_hwaccel(avctx);
// until then pix_fmt may be changed right after codec init
+#if FF_API_XVMC
if (avctx->pix_fmt == AV_PIX_FMT_XVMC_MPEG2_IDCT ||
+#else
+ if (
+#endif
avctx->hwaccel || uses_vdpau(avctx))
if (avctx->idct_algo == FF_IDCT_AUTO)
avctx->idct_algo = FF_IDCT_SIMPLE;
@@ -1195,6 +1218,7 @@
Mpeg1Context *s1 = avctx->priv_data;
MpegEncContext *s = &s1->mpeg_enc_ctx;
uint8_t old_permutation[64];
+ int ret;
if ((s1->mpeg_enc_ctx_allocated == 0) ||
avctx->coded_width != s->width ||
@@ -1217,7 +1241,10 @@
if ((s->width == 0) || (s->height == 0))
return -2;
- avcodec_set_dimensions(avctx, s->width, s->height);
+ ret = ff_set_dimensions(avctx, s->width, s->height);
+ if (ret < 0)
+ return ret;
+
if (avctx->codec_id == AV_CODEC_ID_MPEG2VIDEO && s->bit_rate) {
avctx->rc_max_rate = s->bit_rate;
} else if (avctx->codec_id == AV_CODEC_ID_MPEG1VIDEO && s->bit_rate &&
@@ -1565,6 +1592,14 @@
return AVERROR(ENOMEM);
memcpy(pan_scan->data, &s1->pan_scan, sizeof(s1->pan_scan));
+ if (s1->a53_caption) {
+ AVFrameSideData *sd = av_frame_new_side_data(
+ &s->current_picture_ptr->f, AV_FRAME_DATA_A53_CC,
+ s1->a53_caption_size);
+ if (sd)
+ memcpy(sd->data, s1->a53_caption, s1->a53_caption_size);
+ av_freep(&s1->a53_caption);
+ }
if (HAVE_THREADS && (avctx->active_thread_type & FF_THREAD_FRAME))
ff_thread_finish_setup(avctx);
} else { // second field
@@ -1594,11 +1629,15 @@
return -1;
}
+#if FF_API_XVMC
+FF_DISABLE_DEPRECATION_WARNINGS
// 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)
return -1;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif /* FF_API_XVMC */
return 0;
}
@@ -1639,9 +1678,8 @@
}
/* extra slice info */
- while (get_bits1(&s->gb) != 0) {
- skip_bits(&s->gb, 8);
- }
+ if (skip_1stop_8data_bits(&s->gb) < 0)
+ return AVERROR_INVALIDDATA;
s->mb_x = 0;
@@ -1702,9 +1740,13 @@
}
for (;;) {
+#if FF_API_XVMC
+FF_DISABLE_DEPRECATION_WARNINGS
// 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
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif /* FF_API_XVMC */
if (mpeg_decode_mb(s, s->block) < 0)
return -1;
@@ -1906,11 +1948,15 @@
av_log(avctx, AV_LOG_ERROR, "hardware accelerator failed to decode picture\n");
}
+#if FF_API_XVMC
+FF_DISABLE_DEPRECATION_WARNINGS
if (CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration)
ff_xvmc_field_end(s);
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif /* FF_API_XVMC */
/* end of slice reached */
- if (/*s->mb_y << field_pic == s->mb_height &&*/ !s->first_field && !s->first_slice) {
+ if (/*s->mb_y << field_pic == s->mb_height &&*/ !s->first_field && !s1->first_slice) {
/* end of image */
ff_er_frame_end(&s->er);
@@ -2070,7 +2116,6 @@
if (s->codec_tag == AV_RL32("BW10")) {
s->codec_id = s->avctx->codec_id = AV_CODEC_ID_MPEG1VIDEO;
} else {
- 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
s->codec_id = s->avctx->codec_id = AV_CODEC_ID_MPEG2VIDEO;
}
@@ -2081,6 +2126,60 @@
}
+static int mpeg_decode_a53_cc(AVCodecContext *avctx,
+ const uint8_t *p, int buf_size)
+{
+ Mpeg1Context *s1 = avctx->priv_data;
+
+ if (buf_size >= 6 &&
+ p[0] == 'G' && p[1] == 'A' && p[2] == '9' && p[3] == '4' &&
+ p[4] == 3 && (p[5] & 0x40)) {
+ /* extract A53 Part 4 CC data */
+ int cc_count = p[5] & 0x1f;
+ if (cc_count > 0 && buf_size >= 7 + cc_count * 3) {
+ av_freep(&s1->a53_caption);
+ s1->a53_caption_size = cc_count * 3;
+ s1->a53_caption = av_malloc(s1->a53_caption_size);
+ if (s1->a53_caption) {
+ memcpy(s1->a53_caption, p + 7, s1->a53_caption_size);
+ }
+ }
+ return 1;
+ } else if (buf_size >= 11 &&
+ p[0] == 'C' && p[1] == 'C' && p[2] == 0x01 && p[3] == 0xf8) {
+ /* extract DVD CC data */
+ int cc_count = 0;
+ int i;
+ // There is a caption count field in the data, but it is often
+ // incorect. So count the number of captions present.
+ for (i = 5; i + 6 <= buf_size && ((p[i] & 0xfe) == 0xfe); i += 6)
+ cc_count++;
+ // Transform the DVD format into A53 Part 4 format
+ if (cc_count > 0) {
+ av_freep(&s1->a53_caption);
+ s1->a53_caption_size = cc_count * 6;
+ s1->a53_caption = av_malloc(s1->a53_caption_size);
+ if (s1->a53_caption) {
+ uint8_t field1 = !!(p[4] & 0x80);
+ uint8_t *cap = s1->a53_caption;
+ p += 5;
+ for (i = 0; i < cc_count; i++) {
+ cap[0] = (p[0] == 0xff && field1) ? 0xfc : 0xfd;
+ cap[1] = p[1];
+ cap[2] = p[2];
+ cap[3] = (p[3] == 0xff && !field1) ? 0xfc : 0xfd;
+ cap[4] = p[4];
+ cap[5] = p[5];
+ cap += 6;
+ p += 6;
+ }
+ }
+ }
+ return 1;
+ }
+ return 0;
+}
+
static void mpeg_decode_user_data(AVCodecContext *avctx,
const uint8_t *p, int buf_size)
{
@@ -2114,6 +2213,8 @@
return;
avctx->dtg_active_format = p[0] & 0x0f;
}
+ } else if (mpeg_decode_a53_cc(avctx, p, buf_size)) {
+ return;
}
}
@@ -2185,6 +2286,10 @@
}
}
s2->pict_type = 0;
+
+ if (avctx->err_recognition & AV_EF_EXPLODE && s2->er.error_count)
+ return AVERROR_INVALIDDATA;
+
return FFMAX(0, buf_ptr - buf - s2->parse_context.last_index);
}
@@ -2248,7 +2353,7 @@
/* 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;
+ s->first_slice = 1;
last_code = PICTURE_START_CODE;
} else {
av_log(avctx, AV_LOG_ERROR, "ignoring pic after %X\n", last_code);
@@ -2392,9 +2497,9 @@
break;
}
- if (s2->first_slice) {
+ if (s->first_slice) {
skip_frame = 0;
- s2->first_slice = 0;
+ s->first_slice = 0;
if (mpeg_field_start(s2, buf, buf_size) < 0)
return -1;
}
@@ -2526,6 +2631,7 @@
if (s->mpeg_enc_ctx_allocated)
ff_MPV_common_end(&s->mpeg_enc_ctx);
+ av_freep(&s->a53_caption);
return 0;
}
@@ -2591,6 +2697,7 @@
.max_lowres = 3,
};
+#if FF_API_XVMC
#if CONFIG_MPEG_XVMC_DECODER
static av_cold int mpeg_mc_decode_init(AVCodecContext *avctx)
{
@@ -2624,6 +2731,7 @@
};
#endif
+#endif /* FF_API_XVMC */
#if CONFIG_MPEG_VDPAU_DECODER
AVCodec ff_mpeg_vdpau_decoder = {
diff --git a/libavcodec/mpeg12enc.c b/libavcodec/mpeg12enc.c
index 6882789..a550379 100644
--- a/libavcodec/mpeg12enc.c
+++ b/libavcodec/mpeg12enc.c
@@ -25,6 +25,8 @@
* MPEG1/2 encoder
*/
+#include <stdint.h>
+
#include "libavutil/attributes.h"
#include "libavutil/avassert.h"
#include "libavutil/log.h"
diff --git a/libavcodec/mpeg4video.c b/libavcodec/mpeg4video.c
index 9b86997..3f92ba5 100644
--- a/libavcodec/mpeg4video.c
+++ b/libavcodec/mpeg4video.c
@@ -24,19 +24,20 @@
#include "mpeg4video.h"
#include "mpeg4data.h"
-uint8_t ff_mpeg4_static_rl_table_store[3][2][2*MAX_RUN + MAX_LEVEL + 3];
+uint8_t ff_mpeg4_static_rl_table_store[3][2][2 * MAX_RUN + MAX_LEVEL + 3];
-int ff_mpeg4_get_video_packet_prefix_length(MpegEncContext *s){
- switch(s->pict_type){
- case AV_PICTURE_TYPE_I:
- return 16;
- case AV_PICTURE_TYPE_P:
- case AV_PICTURE_TYPE_S:
- return s->f_code+15;
- case AV_PICTURE_TYPE_B:
- return FFMAX3(s->f_code, s->b_code, 2) + 15;
- default:
- return -1;
+int ff_mpeg4_get_video_packet_prefix_length(MpegEncContext *s)
+{
+ switch (s->pict_type) {
+ case AV_PICTURE_TYPE_I:
+ return 16;
+ case AV_PICTURE_TYPE_P:
+ case AV_PICTURE_TYPE_S:
+ return s->f_code + 15;
+ case AV_PICTURE_TYPE_B:
+ return FFMAX3(s->f_code, s->b_code, 2) + 15;
+ default:
+ return -1;
}
}
@@ -44,70 +45,75 @@
{
int c_wrap, c_xy, l_wrap, l_xy;
- l_wrap= s->b8_stride;
- l_xy= (2*s->mb_y-1)*l_wrap + s->mb_x*2 - 1;
- c_wrap= s->mb_stride;
- c_xy= (s->mb_y-1)*c_wrap + s->mb_x - 1;
+ l_wrap = s->b8_stride;
+ l_xy = (2 * s->mb_y - 1) * l_wrap + s->mb_x * 2 - 1;
+ c_wrap = s->mb_stride;
+ c_xy = (s->mb_y - 1) * c_wrap + s->mb_x - 1;
#if 0
/* clean DC */
- memsetw(s->dc_val[0] + l_xy, 1024, l_wrap*2+1);
- memsetw(s->dc_val[1] + c_xy, 1024, c_wrap+1);
- memsetw(s->dc_val[2] + c_xy, 1024, c_wrap+1);
+ memsetw(s->dc_val[0] + l_xy, 1024, l_wrap * 2 + 1);
+ memsetw(s->dc_val[1] + c_xy, 1024, c_wrap + 1);
+ memsetw(s->dc_val[2] + c_xy, 1024, c_wrap + 1);
#endif
/* clean AC */
- memset(s->ac_val[0] + l_xy, 0, (l_wrap*2+1)*16*sizeof(int16_t));
- memset(s->ac_val[1] + c_xy, 0, (c_wrap +1)*16*sizeof(int16_t));
- memset(s->ac_val[2] + c_xy, 0, (c_wrap +1)*16*sizeof(int16_t));
+ memset(s->ac_val[0] + l_xy, 0, (l_wrap * 2 + 1) * 16 * sizeof(int16_t));
+ memset(s->ac_val[1] + c_xy, 0, (c_wrap + 1) * 16 * sizeof(int16_t));
+ memset(s->ac_val[2] + c_xy, 0, (c_wrap + 1) * 16 * sizeof(int16_t));
/* clean MV */
// we can't clear the MVs as they might be needed by a b frame
-// memset(s->motion_val + l_xy, 0, (l_wrap*2+1)*2*sizeof(int16_t));
-// memset(s->motion_val, 0, 2*sizeof(int16_t)*(2 + s->mb_width*2)*(2 + s->mb_height*2));
- s->last_mv[0][0][0]=
- s->last_mv[0][0][1]=
- s->last_mv[1][0][0]=
- s->last_mv[1][0][1]= 0;
+// memset(s->motion_val + l_xy, 0, (l_wrap * 2 + 1) * 2 * sizeof(int16_t));
+// memset(s->motion_val, 0, 2 * sizeof(int16_t) * (2 + s->mb_width * 2) *
+// (2 + s->mb_height * 2));
+ s->last_mv[0][0][0] =
+ s->last_mv[0][0][1] =
+ s->last_mv[1][0][0] =
+ s->last_mv[1][0][1] = 0;
}
#define tab_size ((signed)FF_ARRAY_ELEMS(s->direct_scale_mv[0]))
-#define tab_bias (tab_size/2)
+#define tab_bias (tab_size / 2)
-//used by mpeg4 and rv10 decoder
-void ff_mpeg4_init_direct_mv(MpegEncContext *s){
+// used by mpeg4 and rv10 decoder
+void ff_mpeg4_init_direct_mv(MpegEncContext *s)
+{
int i;
- for(i=0; i<tab_size; i++){
- s->direct_scale_mv[0][i] = (i-tab_bias)*s->pb_time/s->pp_time;
- s->direct_scale_mv[1][i] = (i-tab_bias)*(s->pb_time-s->pp_time)/s->pp_time;
+ for (i = 0; i < tab_size; i++) {
+ s->direct_scale_mv[0][i] = (i - tab_bias) * s->pb_time / s->pp_time;
+ s->direct_scale_mv[1][i] = (i - tab_bias) * (s->pb_time - s->pp_time) /
+ s->pp_time;
}
}
-static inline void ff_mpeg4_set_one_direct_mv(MpegEncContext *s, int mx, int my, int i){
- int xy= s->block_index[i];
- uint16_t time_pp= s->pp_time;
- uint16_t time_pb= s->pb_time;
+static inline void ff_mpeg4_set_one_direct_mv(MpegEncContext *s, int mx,
+ int my, int i)
+{
+ int xy = s->block_index[i];
+ uint16_t time_pp = s->pp_time;
+ uint16_t time_pb = s->pb_time;
int p_mx, p_my;
p_mx = s->next_picture.motion_val[0][xy][0];
- if((unsigned)(p_mx + tab_bias) < tab_size){
+ 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
: s->direct_scale_mv[1][p_mx + tab_bias];
- }else{
- s->mv[0][i][0] = p_mx*time_pb/time_pp + mx;
+ } else {
+ s->mv[0][i][0] = p_mx * time_pb / time_pp + mx;
s->mv[1][i][0] = mx ? s->mv[0][i][0] - p_mx
- : p_mx*(time_pb - time_pp)/time_pp;
+ : p_mx * (time_pb - time_pp) / time_pp;
}
p_my = s->next_picture.motion_val[0][xy][1];
- if((unsigned)(p_my + tab_bias) < tab_size){
+ 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
: s->direct_scale_mv[1][p_my + tab_bias];
- }else{
- s->mv[0][i][1] = p_my*time_pb/time_pp + my;
+ } else {
+ s->mv[0][i][1] = p_my * time_pb / time_pp + my;
s->mv[1][i][1] = my ? s->mv[0][i][1] - p_my
- : p_my*(time_pb - time_pp)/time_pp;
+ : p_my * (time_pb - time_pp) / time_pp;
}
}
@@ -115,56 +121,72 @@
#undef tab_bias
/**
- *
* @return the mb_type
*/
-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;
+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];
uint16_t time_pp;
uint16_t time_pb;
int i;
- //FIXME avoid divides
+ // FIXME avoid divides
// try special case with shifts for 1 and 3 B-frames?
- if(IS_8X8(colocated_mb_type)){
+ if (IS_8X8(colocated_mb_type)) {
s->mv_type = MV_TYPE_8X8;
- for(i=0; i<4; i++){
+ for (i = 0; i < 4; i++)
ff_mpeg4_set_one_direct_mv(s, mx, my, i);
- }
return MB_TYPE_DIRECT2 | MB_TYPE_8x8 | MB_TYPE_L0L1;
- } else if(IS_INTERLACED(colocated_mb_type)){
+ } else if (IS_INTERLACED(colocated_mb_type)) {
s->mv_type = MV_TYPE_FIELD;
- for(i=0; i<2; i++){
+ for (i = 0; i < 2; i++) {
int field_select = s->next_picture.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){
- time_pp= s->pp_field_time - field_select + i;
- time_pb= s->pb_field_time - field_select + i;
- }else{
- time_pp= s->pp_field_time + field_select - i;
- time_pb= s->pb_field_time + field_select - i;
+ s->field_select[0][i] = field_select;
+ s->field_select[1][i] = i;
+ if (s->top_field_first) {
+ time_pp = s->pp_field_time - field_select + i;
+ time_pb = s->pb_field_time - field_select + i;
+ } else {
+ time_pp = s->pp_field_time + field_select - i;
+ time_pb = s->pb_field_time + field_select - i;
}
- s->mv[0][i][0] = s->p_field_mv_table[i][0][mb_index][0]*time_pb/time_pp + mx;
- s->mv[0][i][1] = s->p_field_mv_table[i][0][mb_index][1]*time_pb/time_pp + my;
- s->mv[1][i][0] = mx ? s->mv[0][i][0] - s->p_field_mv_table[i][0][mb_index][0]
- : s->p_field_mv_table[i][0][mb_index][0]*(time_pb - time_pp)/time_pp;
- s->mv[1][i][1] = my ? s->mv[0][i][1] - s->p_field_mv_table[i][0][mb_index][1]
- : s->p_field_mv_table[i][0][mb_index][1]*(time_pb - time_pp)/time_pp;
+ s->mv[0][i][0] = s->p_field_mv_table[i][0][mb_index][0] *
+ time_pb / time_pp + mx;
+ s->mv[0][i][1] = s->p_field_mv_table[i][0][mb_index][1] *
+ time_pb / time_pp + my;
+ s->mv[1][i][0] = mx ? s->mv[0][i][0] -
+ s->p_field_mv_table[i][0][mb_index][0]
+ : s->p_field_mv_table[i][0][mb_index][0] *
+ (time_pb - time_pp) / time_pp;
+ s->mv[1][i][1] = my ? s->mv[0][i][1] -
+ s->p_field_mv_table[i][0][mb_index][1]
+ : s->p_field_mv_table[i][0][mb_index][1] *
+ (time_pb - time_pp) / time_pp;
}
- return MB_TYPE_DIRECT2 | MB_TYPE_16x8 | MB_TYPE_L0L1 | MB_TYPE_INTERLACED;
- }else{
+ return MB_TYPE_DIRECT2 | MB_TYPE_16x8 |
+ MB_TYPE_L0L1 | MB_TYPE_INTERLACED;
+ } else {
ff_mpeg4_set_one_direct_mv(s, mx, my, 0);
- s->mv[0][1][0] = s->mv[0][2][0] = s->mv[0][3][0] = s->mv[0][0][0];
- s->mv[0][1][1] = s->mv[0][2][1] = s->mv[0][3][1] = s->mv[0][0][1];
- s->mv[1][1][0] = s->mv[1][2][0] = s->mv[1][3][0] = s->mv[1][0][0];
- s->mv[1][1][1] = s->mv[1][2][1] = s->mv[1][3][1] = s->mv[1][0][1];
- if((s->avctx->workaround_bugs & FF_BUG_DIRECT_BLOCKSIZE) || !s->quarter_sample)
- s->mv_type= MV_TYPE_16X16;
+ s->mv[0][1][0] =
+ s->mv[0][2][0] =
+ s->mv[0][3][0] = s->mv[0][0][0];
+ s->mv[0][1][1] =
+ s->mv[0][2][1] =
+ s->mv[0][3][1] = s->mv[0][0][1];
+ s->mv[1][1][0] =
+ s->mv[1][2][0] =
+ s->mv[1][3][0] = s->mv[1][0][0];
+ s->mv[1][1][1] =
+ s->mv[1][2][1] =
+ s->mv[1][3][1] = s->mv[1][0][1];
+ if ((s->avctx->workaround_bugs & FF_BUG_DIRECT_BLOCKSIZE) ||
+ !s->quarter_sample)
+ s->mv_type = MV_TYPE_16X16;
else
- s->mv_type= MV_TYPE_8X8;
- return MB_TYPE_DIRECT2 | MB_TYPE_16x16 | MB_TYPE_L0L1; //Note see prev line
+ s->mv_type = MV_TYPE_8X8;
+ // Note see prev line
+ return MB_TYPE_DIRECT2 | MB_TYPE_16x16 | MB_TYPE_L0L1;
}
}
diff --git a/libavcodec/mpeg4video.h b/libavcodec/mpeg4video.h
index c4d23c9..5320b0b 100644
--- a/libavcodec/mpeg4video.h
+++ b/libavcodec/mpeg4video.h
@@ -24,6 +24,7 @@
#define AVCODEC_MPEG4VIDEO_H
#include <stdint.h>
+
#include "get_bits.h"
#include "mpegvideo.h"
#include "rl.h"
@@ -34,13 +35,13 @@
#define BIN_ONLY_SHAPE 2
#define GRAY_SHAPE 3
-#define SIMPLE_VO_TYPE 1
-#define CORE_VO_TYPE 3
-#define MAIN_VO_TYPE 4
-#define NBIT_VO_TYPE 5
-#define ARTS_VO_TYPE 10
-#define ACE_VO_TYPE 12
-#define ADV_SIMPLE_VO_TYPE 17
+#define SIMPLE_VO_TYPE 1
+#define CORE_VO_TYPE 3
+#define MAIN_VO_TYPE 4
+#define NBIT_VO_TYPE 5
+#define ARTS_VO_TYPE 10
+#define ACE_VO_TYPE 12
+#define ADV_SIMPLE_VO_TYPE 17
// aspect_ratio_info
#define EXTENDED_PAR 15
@@ -58,6 +59,49 @@
#define VISUAL_OBJ_STARTCODE 0x1B5
#define VOP_STARTCODE 0x1B6
+typedef struct Mpeg4DecContext {
+ MpegEncContext m;
+
+ /// number of bits to represent the fractional part of time
+ int time_increment_bits;
+ int shape;
+ int vol_sprite_usage;
+ int sprite_brightness_change;
+ int num_sprite_warping_points;
+ /// sprite trajectory points
+ uint16_t sprite_traj[4][2];
+ /// sprite shift [isChroma]
+ int sprite_shift[2];
+
+ // reversible vlc
+ int rvlc;
+ /// could this stream contain resync markers
+ int resync_marker;
+ /// time distance of first I -> B, used for interlaced b frames
+ int t_frame;
+
+ int new_pred;
+ int enhancement_type;
+ int scalability;
+ int use_intra_dc_vlc;
+
+ /// QP above whch the ac VLC should be used for intra dc
+ int intra_dc_threshold;
+
+ /* bug workarounds */
+ int divx_version;
+ int divx_build;
+ int xvid_build;
+ int lavc_build;
+
+ /// flag for having shown the warning about divxs invalid b frames
+ int showed_packed_warning;
+
+ int cplx_estimation_trash_i;
+ int cplx_estimation_trash_p;
+ int cplx_estimation_trash_b;
+} Mpeg4DecContext;
+
/* dc encoding for mpeg4 */
extern const uint8_t ff_mpeg4_DCtab_lum[13][2];
extern const uint8_t ff_mpeg4_DCtab_chrom[13][2];
@@ -88,23 +132,25 @@
void ff_mpeg4_encode_mb(MpegEncContext *s,
int16_t block[6][64],
int motion_x, int motion_y);
-void ff_mpeg4_pred_ac(MpegEncContext * s, int16_t *block, int n,
+void ff_mpeg4_pred_ac(MpegEncContext *s, int16_t *block, int n,
int dir);
-void ff_set_mpeg4_time(MpegEncContext * s);
+void ff_set_mpeg4_time(MpegEncContext *s);
void ff_mpeg4_encode_picture_header(MpegEncContext *s, int picture_number);
-int ff_mpeg4_decode_picture_header(MpegEncContext * s, GetBitContext *gb);
+int ff_mpeg4_decode_picture_header(Mpeg4DecContext *ctx, GetBitContext *gb);
void ff_mpeg4_encode_video_packet_header(MpegEncContext *s);
void ff_mpeg4_clean_buffers(MpegEncContext *s);
-void ff_mpeg4_stuffing(PutBitContext * pbc);
+void ff_mpeg4_stuffing(PutBitContext *pbc);
void ff_mpeg4_init_partitions(MpegEncContext *s);
void ff_mpeg4_merge_partitions(MpegEncContext *s);
void ff_clean_mpeg4_qscales(MpegEncContext *s);
-int ff_mpeg4_decode_partitions(MpegEncContext *s);
+int ff_mpeg4_decode_partitions(Mpeg4DecContext *ctx);
int ff_mpeg4_get_video_packet_prefix_length(MpegEncContext *s);
-int ff_mpeg4_decode_video_packet_header(MpegEncContext *s);
+int ff_mpeg4_decode_video_packet_header(Mpeg4DecContext *ctx);
void ff_mpeg4_init_direct_mv(MpegEncContext *s);
void ff_mpeg4videodec_static_init(void);
+int ff_mpeg4_workaround_bugs(AVCodecContext *avctx);
+int ff_mpeg4_frame_end(AVCodecContext *avctx, const uint8_t *buf, int buf_size);
/**
*
@@ -112,8 +158,7 @@
*/
int ff_mpeg4_set_direct_mv(MpegEncContext *s, int mx, int my);
-extern uint8_t ff_mpeg4_static_rl_table_store[3][2][2*MAX_RUN + MAX_LEVEL + 3];
-
+extern uint8_t ff_mpeg4_static_rl_table_store[3][2][2 * MAX_RUN + MAX_LEVEL + 3];
#if 0 //3IV1 is quite rare and it slows things down a tiny bit
#define IS_3IV1 s->codec_tag == AV_RL32("3IV1")
@@ -121,7 +166,6 @@
#define IS_3IV1 0
#endif
-
/**
* Predict the dc.
* encoding quantized level -> quantized diff
@@ -129,75 +173,81 @@
* @param n block index (0-3 are luma, 4-5 are chroma)
* @param dir_ptr pointer to an integer where the prediction direction will be stored
*/
-static inline int ff_mpeg4_pred_dc(MpegEncContext * s, int n, int level, int *dir_ptr, int encoding)
+static inline int ff_mpeg4_pred_dc(MpegEncContext *s, int n, int level,
+ int *dir_ptr, int encoding)
{
int a, b, c, wrap, pred, scale, ret;
int16_t *dc_val;
/* find prediction */
- if (n < 4) {
+ if (n < 4)
scale = s->y_dc_scale;
- } else {
+ else
scale = s->c_dc_scale;
- }
- if(IS_3IV1)
- scale= 8;
+ if (IS_3IV1)
+ scale = 8;
- wrap= s->block_wrap[n];
+ wrap = s->block_wrap[n];
dc_val = s->dc_val[0] + s->block_index[n];
/* B C
* A X
*/
- a = dc_val[ - 1];
- b = dc_val[ - 1 - wrap];
- c = dc_val[ - wrap];
+ a = dc_val[-1];
+ b = dc_val[-1 - wrap];
+ c = dc_val[-wrap];
- /* outside slice handling (we can't do that by memset as we need the dc for error resilience) */
- if(s->first_slice_line && n!=3){
- if(n!=2) b=c= 1024;
- if(n!=1 && s->mb_x == s->resync_mb_x) b=a= 1024;
+ /* outside slice handling (we can't do that by memset as we need the
+ * dc for error resilience) */
+ if (s->first_slice_line && n != 3) {
+ if (n != 2)
+ b = c = 1024;
+ if (n != 1 && s->mb_x == s->resync_mb_x)
+ b = a = 1024;
}
- if(s->mb_x == s->resync_mb_x && s->mb_y == s->resync_mb_y+1){
- if(n==0 || n==4 || n==5)
- b=1024;
+ if (s->mb_x == s->resync_mb_x && s->mb_y == s->resync_mb_y + 1) {
+ if (n == 0 || n == 4 || n == 5)
+ b = 1024;
}
if (abs(a - b) < abs(b - c)) {
- pred = c;
+ pred = c;
*dir_ptr = 1; /* top */
} else {
- pred = a;
+ pred = a;
*dir_ptr = 0; /* left */
}
/* we assume pred is positive */
pred = FASTDIV((pred + (scale >> 1)), scale);
- if(encoding){
+ if (encoding) {
ret = level - pred;
- }else{
+ } else {
level += pred;
- ret= level;
- if(s->err_recognition&(AV_EF_BITSTREAM|AV_EF_AGGRESSIVE)){
- if(level<0){
- av_log(s->avctx, AV_LOG_ERROR, "dc<0 at %dx%d\n", s->mb_x, s->mb_y);
+ ret = level;
+ if (s->err_recognition & (AV_EF_BITSTREAM | AV_EF_AGGRESSIVE)) {
+ if (level < 0) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "dc<0 at %dx%d\n", s->mb_x, s->mb_y);
return -1;
}
- if(level*scale > 2048 + scale){
- av_log(s->avctx, AV_LOG_ERROR, "dc overflow at %dx%d\n", s->mb_x, s->mb_y);
+ if (level * scale > 2048 + scale) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "dc overflow at %dx%d\n", s->mb_x, s->mb_y);
return -1;
}
}
}
- level *=scale;
- if(level&(~2047)){
- if(level<0)
- level=0;
- else if(!(s->workaround_bugs&FF_BUG_DC_CLIP))
- level=2047;
+ level *= scale;
+ if (level & (~2047)) {
+ if (level < 0)
+ level = 0;
+ else if (!(s->workaround_bugs & FF_BUG_DC_CLIP))
+ level = 2047;
}
- dc_val[0]= level;
+ dc_val[0] = level;
return ret;
}
+
#endif /* AVCODEC_MPEG4VIDEO_H */
diff --git a/libavcodec/mpeg4video_parser.c b/libavcodec/mpeg4video_parser.c
index 9c14fd0..1da96c0 100644
--- a/libavcodec/mpeg4video_parser.c
+++ b/libavcodec/mpeg4video_parser.c
@@ -20,6 +20,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include "internal.h"
#include "parser.h"
#include "mpegvideo.h"
#include "mpeg4video.h"
@@ -27,44 +28,45 @@
struct Mp4vParseContext {
ParseContext pc;
- struct MpegEncContext enc;
+ Mpeg4DecContext dec_ctx;
int first_picture;
};
-int ff_mpeg4_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size){
+int ff_mpeg4_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size)
+{
int vop_found, i;
uint32_t state;
- vop_found= pc->frame_start_found;
- state= pc->state;
+ vop_found = pc->frame_start_found;
+ state = pc->state;
- i=0;
- if(!vop_found){
- for(i=0; i<buf_size; i++){
- state= (state<<8) | buf[i];
- if(state == 0x1B6){
+ i = 0;
+ if (!vop_found) {
+ for (i = 0; i < buf_size; i++) {
+ state = (state << 8) | buf[i];
+ if (state == 0x1B6) {
i++;
- vop_found=1;
+ vop_found = 1;
break;
}
}
}
- if(vop_found){
+ if (vop_found) {
/* EOF considered as end of frame */
if (buf_size == 0)
return 0;
- for(; i<buf_size; i++){
- state= (state<<8) | buf[i];
- if((state&0xFFFFFF00) == 0x100){
- pc->frame_start_found=0;
- pc->state=-1;
- return i-3;
+ for (; i < buf_size; i++) {
+ state = (state << 8) | buf[i];
+ if ((state & 0xFFFFFF00) == 0x100) {
+ pc->frame_start_found = 0;
+ pc->state = -1;
+ return i - 3;
}
}
}
- pc->frame_start_found= vop_found;
- pc->state= state;
+ pc->frame_start_found = vop_found;
+ pc->state = state;
return END_NOT_FOUND;
}
@@ -74,22 +76,26 @@
const uint8_t *buf, int buf_size)
{
struct Mp4vParseContext *pc = s1->priv_data;
- MpegEncContext *s = &pc->enc;
+ Mpeg4DecContext *dec_ctx = &pc->dec_ctx;
+ MpegEncContext *s = &dec_ctx->m;
GetBitContext gb1, *gb = &gb1;
int ret;
- s->avctx = avctx;
+ s->avctx = avctx;
s->current_picture_ptr = &s->current_picture;
- if (avctx->extradata_size && pc->first_picture){
- init_get_bits(gb, avctx->extradata, avctx->extradata_size*8);
- ret = ff_mpeg4_decode_picture_header(s, gb);
+ if (avctx->extradata_size && pc->first_picture) {
+ init_get_bits(gb, avctx->extradata, avctx->extradata_size * 8);
+ ret = ff_mpeg4_decode_picture_header(dec_ctx, gb);
}
init_get_bits(gb, buf, 8 * buf_size);
- ret = ff_mpeg4_decode_picture_header(s, gb);
- if (s->width && (!avctx->width || !avctx->height || !avctx->coded_width || !avctx->coded_height)) {
- avcodec_set_dimensions(avctx, s->width, s->height);
+ ret = ff_mpeg4_decode_picture_header(dec_ctx, gb);
+ if (s->width && (!avctx->width || !avctx->height ||
+ !avctx->coded_width || !avctx->coded_height)) {
+ ret = ff_set_dimensions(avctx, s->width, s->height);
+ if (ret < 0)
+ return ret;
}
if((s1->flags & PARSER_FLAG_USE_CODEC_TS) && s->avctx->time_base.den>0 && ret>=0){
av_assert1(s1->pts == AV_NOPTS_VALUE);
@@ -98,7 +104,7 @@
s1->pts = av_rescale_q(s->time, (AVRational){1, s->avctx->time_base.den}, (AVRational){1, 1200000});
}
- s1->pict_type= s->pict_type;
+ s1->pict_type = s->pict_type;
pc->first_picture = 0;
return ret;
}
@@ -109,40 +115,39 @@
ff_mpeg4videodec_static_init();
- pc->first_picture = 1;
- pc->enc.quant_precision=5;
- pc->enc.slice_context_count = 1;
- pc->enc.showed_packed_warning = 1;
+ pc->first_picture = 1;
+ pc->dec_ctx.m.quant_precision = 5;
+ pc->dec_ctx.m.slice_context_count = 1;
+ pc->dec_ctx.showed_packed_warning = 1;
return 0;
}
static int mpeg4video_parse(AVCodecParserContext *s,
- AVCodecContext *avctx,
- const uint8_t **poutbuf, int *poutbuf_size,
- const uint8_t *buf, int buf_size)
+ AVCodecContext *avctx,
+ const uint8_t **poutbuf, int *poutbuf_size,
+ const uint8_t *buf, int buf_size)
{
ParseContext *pc = s->priv_data;
int next;
- if(s->flags & PARSER_FLAG_COMPLETE_FRAMES){
- next= buf_size;
- }else{
- next= ff_mpeg4_find_frame_end(pc, buf, buf_size);
+ if (s->flags & PARSER_FLAG_COMPLETE_FRAMES) {
+ next = buf_size;
+ } else {
+ next = ff_mpeg4_find_frame_end(pc, buf, buf_size);
if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) {
- *poutbuf = NULL;
+ *poutbuf = NULL;
*poutbuf_size = 0;
return buf_size;
}
}
av_mpeg4_decode_header(s, avctx, buf, buf_size);
- *poutbuf = buf;
+ *poutbuf = buf;
*poutbuf_size = buf_size;
return next;
}
-
AVCodecParser ff_mpeg4video_parser = {
.codec_ids = { AV_CODEC_ID_MPEG4 },
.priv_data_size = sizeof(struct Mp4vParseContext),
diff --git a/libavcodec/mpeg4videodec.c b/libavcodec/mpeg4videodec.c
index 6cf342f..9b7799d 100644
--- a/libavcodec/mpeg4videodec.c
+++ b/libavcodec/mpeg4videodec.c
@@ -28,24 +28,23 @@
#include "h263.h"
#include "thread.h"
-// The defines below define the number of bits that are read at once for
-// reading vlc values. Changing these may improve speed and data cache needs
-// be aware though that decreasing them may need the number of stages that is
-// passed to get_vlc* to be increased.
+/* The defines below define the number of bits that are read at once for
+ * reading vlc values. Changing these may improve speed and data cache needs
+ * be aware though that decreasing them may need the number of stages that is
+ * passed to get_vlc* to be increased. */
#define SPRITE_TRAJ_VLC_BITS 6
#define DC_VLC_BITS 9
#define MB_TYPE_B_VLC_BITS 4
-
static VLC dc_lum, dc_chrom;
static VLC sprite_trajectory;
static VLC mb_type_b_vlc;
-static const int mb_type_b_map[4]= {
+static const int mb_type_b_map[4] = {
MB_TYPE_DIRECT2 | MB_TYPE_L0L1,
- MB_TYPE_L0L1 | MB_TYPE_16x16,
- MB_TYPE_L1 | MB_TYPE_16x16,
- MB_TYPE_L0 | MB_TYPE_16x16,
+ MB_TYPE_L0L1 | MB_TYPE_16x16,
+ MB_TYPE_L1 | MB_TYPE_16x16,
+ MB_TYPE_L0 | MB_TYPE_16x16,
};
/**
@@ -53,309 +52,328 @@
* @param n block index (0-3 are luma, 4-5 are chroma)
* @param dir the ac prediction direction
*/
-void ff_mpeg4_pred_ac(MpegEncContext * s, int16_t *block, int n,
- int dir)
+void ff_mpeg4_pred_ac(MpegEncContext *s, int16_t *block, int n, int dir)
{
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.qscale_table;
/* find prediction */
- 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_val1 = ac_val;
if (s->ac_pred) {
if (dir == 0) {
- const int xy= s->mb_x-1 + s->mb_y*s->mb_stride;
+ const int xy = s->mb_x - 1 + s->mb_y * s->mb_stride;
/* left prediction */
ac_val -= 16;
- if(s->mb_x==0 || s->qscale == qscale_table[xy] || n==1 || n==3){
+ if (s->mb_x == 0 || s->qscale == qscale_table[xy] ||
+ n == 1 || n == 3) {
/* same qscale */
- for(i=1;i<8;i++) {
- block[s->dsp.idct_permutation[i<<3]] += ac_val[i];
- }
- }else{
+ for (i = 1; i < 8; i++)
+ block[s->dsp.idct_permutation[i << 3]] += ac_val[i];
+ } else {
/* different qscale, we must rescale */
- for(i=1;i<8;i++) {
- block[s->dsp.idct_permutation[i<<3]] += ROUNDED_DIV(ac_val[i]*qscale_table[xy], s->qscale);
- }
+ for (i = 1; i < 8; i++)
+ block[s->dsp.idct_permutation[i << 3]] += ROUNDED_DIV(ac_val[i] * qscale_table[xy], s->qscale);
}
} else {
- const int xy= s->mb_x + s->mb_y*s->mb_stride - s->mb_stride;
+ const int xy = s->mb_x + s->mb_y * s->mb_stride - s->mb_stride;
/* top prediction */
ac_val -= 16 * s->block_wrap[n];
- if(s->mb_y==0 || s->qscale == qscale_table[xy] || n==2 || n==3){
+ if (s->mb_y == 0 || s->qscale == qscale_table[xy] ||
+ n == 2 || n == 3) {
/* same qscale */
- for(i=1;i<8;i++) {
+ for (i = 1; i < 8; i++)
block[s->dsp.idct_permutation[i]] += ac_val[i + 8];
- }
- }else{
+ } else {
/* different qscale, we must rescale */
- for(i=1;i<8;i++) {
- block[s->dsp.idct_permutation[i]] += ROUNDED_DIV(ac_val[i + 8]*qscale_table[xy], s->qscale);
- }
+ for (i = 1; i < 8; i++)
+ block[s->dsp.idct_permutation[i]] += ROUNDED_DIV(ac_val[i + 8] * qscale_table[xy], s->qscale);
}
}
}
/* left copy */
- for(i=1;i<8;i++)
- ac_val1[i ] = block[s->dsp.idct_permutation[i<<3]];
+ for (i = 1; i < 8; i++)
+ ac_val1[i] = block[s->dsp.idct_permutation[i << 3]];
/* top copy */
- for(i=1;i<8;i++)
- ac_val1[8 + i] = block[s->dsp.idct_permutation[i ]];
-
+ for (i = 1; i < 8; i++)
+ ac_val1[8 + i] = block[s->dsp.idct_permutation[i]];
}
/**
* check if the next stuff is a resync marker or the end.
* @return 0 if not
*/
-static inline int mpeg4_is_resync(MpegEncContext *s){
- int bits_count= get_bits_count(&s->gb);
- int v= show_bits(&s->gb, 16);
+static inline int mpeg4_is_resync(Mpeg4DecContext *ctx)
+{
+ MpegEncContext *s = &ctx->m;
+ int bits_count = get_bits_count(&s->gb);
+ int v = show_bits(&s->gb, 16);
- if(s->workaround_bugs&FF_BUG_NO_PADDING && !s->resync_marker){
+ if (s->workaround_bugs & FF_BUG_NO_PADDING && !ctx->resync_marker)
return 0;
- }
- while(v<=0xFF){
- if(s->pict_type==AV_PICTURE_TYPE_B || (v>>(8-s->pict_type)!=1) || s->partitioned_frame)
+ while (v <= 0xFF) {
+ if (s->pict_type == AV_PICTURE_TYPE_B ||
+ (v >> (8 - s->pict_type) != 1) || s->partitioned_frame)
break;
- skip_bits(&s->gb, 8+s->pict_type);
- bits_count+= 8+s->pict_type;
- v= show_bits(&s->gb, 16);
+ skip_bits(&s->gb, 8 + s->pict_type);
+ bits_count += 8 + s->pict_type;
+ v = show_bits(&s->gb, 16);
}
- if(bits_count + 8 >= s->gb.size_in_bits){
- v>>=8;
- v|= 0x7F >> (7-(bits_count&7));
+ if (bits_count + 8 >= s->gb.size_in_bits) {
+ v >>= 8;
+ v |= 0x7F >> (7 - (bits_count & 7));
- if(v==0x7F)
+ if (v == 0x7F)
return s->mb_num;
- }else{
- if(v == ff_mpeg4_resync_prefix[bits_count&7]){
+ } else {
+ if (v == ff_mpeg4_resync_prefix[bits_count & 7]) {
int len, mb_num;
- int mb_num_bits= av_log2(s->mb_num - 1) + 1;
- GetBitContext gb= s->gb;
+ int mb_num_bits = av_log2(s->mb_num - 1) + 1;
+ GetBitContext gb = s->gb;
skip_bits(&s->gb, 1);
align_get_bits(&s->gb);
- for(len=0; len<32; len++){
- if(get_bits1(&s->gb)) break;
- }
+ for (len = 0; len < 32; len++)
+ if (get_bits1(&s->gb))
+ break;
- mb_num= get_bits(&s->gb, mb_num_bits);
- if(!mb_num || mb_num > s->mb_num || get_bits_count(&s->gb)+6 > s->gb.size_in_bits)
+ mb_num = get_bits(&s->gb, mb_num_bits);
+ if (!mb_num || mb_num > s->mb_num || get_bits_count(&s->gb)+6 > s->gb.size_in_bits)
mb_num= -1;
- s->gb= gb;
+ s->gb = gb;
- if(len>=ff_mpeg4_get_video_packet_prefix_length(s))
+ if (len >= ff_mpeg4_get_video_packet_prefix_length(s))
return mb_num;
}
}
return 0;
}
-static int mpeg4_decode_sprite_trajectory(MpegEncContext *s, GetBitContext *gb)
+static int mpeg4_decode_sprite_trajectory(Mpeg4DecContext *ctx, GetBitContext *gb)
{
- int i;
- int a= 2<<s->sprite_warping_accuracy;
- int rho= 3-s->sprite_warping_accuracy;
- int r=16/a;
- const int vop_ref[4][2]= {{0,0}, {s->width,0}, {0, s->height}, {s->width, s->height}}; // only true for rectangle shapes
- int d[4][2]={{0,0}, {0,0}, {0,0}, {0,0}};
+ MpegEncContext *s = &ctx->m;
+ int a = 2 << s->sprite_warping_accuracy;
+ int rho = 3 - s->sprite_warping_accuracy;
+ int r = 16 / a;
+ int alpha = 0;
+ int beta = 0;
+ int w = s->width;
+ int h = s->height;
+ int min_ab, i, w2, h2, w3, h3;
int sprite_ref[4][2];
int virtual_ref[2][2];
- int w2, h2, w3, h3;
- int alpha=0, beta=0;
- int w= s->width;
- int h= s->height;
- int min_ab;
+
+ // only true for rectangle shapes
+ const int vop_ref[4][2] = { { 0, 0 }, { s->width, 0 },
+ { 0, s->height }, { s->width, s->height } };
+ int d[4][2] = { { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } };
if (w <= 0 || h <= 0)
return AVERROR_INVALIDDATA;
- for(i=0; i<s->num_sprite_warping_points; i++){
+ for (i = 0; i < ctx->num_sprite_warping_points; i++) {
int length;
- int x=0, y=0;
+ int x = 0, y = 0;
- length= get_vlc2(gb, sprite_trajectory.table, SPRITE_TRAJ_VLC_BITS, 3);
- if(length){
- x= get_xbits(gb, length);
- }
- if(!(s->divx_version==500 && s->divx_build==413)) skip_bits1(gb); /* marker bit */
+ length = get_vlc2(gb, sprite_trajectory.table, SPRITE_TRAJ_VLC_BITS, 3);
+ if (length)
+ x = get_xbits(gb, length);
- length= get_vlc2(gb, sprite_trajectory.table, SPRITE_TRAJ_VLC_BITS, 3);
- if(length){
- y=get_xbits(gb, length);
- }
- skip_bits1(gb); /* marker bit */
- s->sprite_traj[i][0]= d[i][0]= x;
- s->sprite_traj[i][1]= d[i][1]= y;
+ if (!(ctx->divx_version == 500 && ctx->divx_build == 413))
+ skip_bits1(gb); /* marker bit */
+
+ length = get_vlc2(gb, sprite_trajectory.table, SPRITE_TRAJ_VLC_BITS, 3);
+ if (length)
+ y = get_xbits(gb, length);
+
+ skip_bits1(gb); /* marker bit */
+ ctx->sprite_traj[i][0] = d[i][0] = x;
+ ctx->sprite_traj[i][1] = d[i][1] = y;
}
- for(; i<4; i++)
- s->sprite_traj[i][0]= s->sprite_traj[i][1]= 0;
+ for (; i < 4; i++)
+ ctx->sprite_traj[i][0] = ctx->sprite_traj[i][1] = 0;
- while((1<<alpha)<w) alpha++;
- while((1<<beta )<h) beta++; // there seems to be a typo in the mpeg4 std for the definition of w' and h'
- w2= 1<<alpha;
- h2= 1<<beta;
+ while ((1 << alpha) < w)
+ alpha++;
+ while ((1 << beta) < h)
+ beta++; /* typo in the mpeg4 std for the definition of w' and h' */
+ w2 = 1 << alpha;
+ h2 = 1 << beta;
-// Note, the 4th point isn't used for GMC
- if(s->divx_version==500 && s->divx_build==413){
- sprite_ref[0][0]= a*vop_ref[0][0] + d[0][0];
- sprite_ref[0][1]= a*vop_ref[0][1] + d[0][1];
- sprite_ref[1][0]= a*vop_ref[1][0] + d[0][0] + d[1][0];
- sprite_ref[1][1]= a*vop_ref[1][1] + d[0][1] + d[1][1];
- sprite_ref[2][0]= a*vop_ref[2][0] + d[0][0] + d[2][0];
- sprite_ref[2][1]= a*vop_ref[2][1] + d[0][1] + d[2][1];
+ // Note, the 4th point isn't used for GMC
+ if (ctx->divx_version == 500 && ctx->divx_build == 413) {
+ sprite_ref[0][0] = a * vop_ref[0][0] + d[0][0];
+ sprite_ref[0][1] = a * vop_ref[0][1] + d[0][1];
+ sprite_ref[1][0] = a * vop_ref[1][0] + d[0][0] + d[1][0];
+ sprite_ref[1][1] = a * vop_ref[1][1] + d[0][1] + d[1][1];
+ sprite_ref[2][0] = a * vop_ref[2][0] + d[0][0] + d[2][0];
+ sprite_ref[2][1] = a * vop_ref[2][1] + d[0][1] + d[2][1];
} else {
- sprite_ref[0][0]= (a>>1)*(2*vop_ref[0][0] + d[0][0]);
- sprite_ref[0][1]= (a>>1)*(2*vop_ref[0][1] + d[0][1]);
- sprite_ref[1][0]= (a>>1)*(2*vop_ref[1][0] + d[0][0] + d[1][0]);
- sprite_ref[1][1]= (a>>1)*(2*vop_ref[1][1] + d[0][1] + d[1][1]);
- sprite_ref[2][0]= (a>>1)*(2*vop_ref[2][0] + d[0][0] + d[2][0]);
- sprite_ref[2][1]= (a>>1)*(2*vop_ref[2][1] + d[0][1] + d[2][1]);
+ sprite_ref[0][0] = (a >> 1) * (2 * vop_ref[0][0] + d[0][0]);
+ sprite_ref[0][1] = (a >> 1) * (2 * vop_ref[0][1] + d[0][1]);
+ sprite_ref[1][0] = (a >> 1) * (2 * vop_ref[1][0] + d[0][0] + d[1][0]);
+ sprite_ref[1][1] = (a >> 1) * (2 * vop_ref[1][1] + d[0][1] + d[1][1]);
+ sprite_ref[2][0] = (a >> 1) * (2 * vop_ref[2][0] + d[0][0] + d[2][0]);
+ sprite_ref[2][1] = (a >> 1) * (2 * vop_ref[2][1] + d[0][1] + d[2][1]);
}
-/* sprite_ref[3][0]= (a>>1)*(2*vop_ref[3][0] + d[0][0] + d[1][0] + d[2][0] + d[3][0]);
- sprite_ref[3][1]= (a>>1)*(2*vop_ref[3][1] + d[0][1] + d[1][1] + d[2][1] + d[3][1]); */
+ /* sprite_ref[3][0] = (a >> 1) * (2 * vop_ref[3][0] + d[0][0] + d[1][0] + d[2][0] + d[3][0]);
+ * sprite_ref[3][1] = (a >> 1) * (2 * vop_ref[3][1] + d[0][1] + d[1][1] + d[2][1] + d[3][1]); */
-// this is mostly identical to the mpeg4 std (and is totally unreadable because of that ...)
-// perhaps it should be reordered to be more readable ...
-// the idea behind this virtual_ref mess is to be able to use shifts later per pixel instead of divides
-// so the distance between points is converted from w&h based to w2&h2 based which are of the 2^x form
- virtual_ref[0][0]= 16*(vop_ref[0][0] + w2)
- + ROUNDED_DIV(((w - w2)*(r*sprite_ref[0][0] - 16*vop_ref[0][0]) + w2*(r*sprite_ref[1][0] - 16*vop_ref[1][0])),w);
- virtual_ref[0][1]= 16*vop_ref[0][1]
- + ROUNDED_DIV(((w - w2)*(r*sprite_ref[0][1] - 16*vop_ref[0][1]) + w2*(r*sprite_ref[1][1] - 16*vop_ref[1][1])),w);
- virtual_ref[1][0]= 16*vop_ref[0][0]
- + ROUNDED_DIV(((h - h2)*(r*sprite_ref[0][0] - 16*vop_ref[0][0]) + h2*(r*sprite_ref[2][0] - 16*vop_ref[2][0])),h);
- virtual_ref[1][1]= 16*(vop_ref[0][1] + h2)
- + ROUNDED_DIV(((h - h2)*(r*sprite_ref[0][1] - 16*vop_ref[0][1]) + h2*(r*sprite_ref[2][1] - 16*vop_ref[2][1])),h);
+ /* this is mostly identical to the mpeg4 std (and is totally unreadable
+ * because of that...). Perhaps it should be reordered to be more readable.
+ * The idea behind this virtual_ref mess is to be able to use shifts later
+ * per pixel instead of divides so the distance between points is converted
+ * from w&h based to w2&h2 based which are of the 2^x form. */
+ virtual_ref[0][0] = 16 * (vop_ref[0][0] + w2) +
+ ROUNDED_DIV(((w - w2) *
+ (r * sprite_ref[0][0] - 16 * vop_ref[0][0]) +
+ w2 * (r * sprite_ref[1][0] - 16 * vop_ref[1][0])), w);
+ virtual_ref[0][1] = 16 * vop_ref[0][1] +
+ ROUNDED_DIV(((w - w2) *
+ (r * sprite_ref[0][1] - 16 * vop_ref[0][1]) +
+ w2 * (r * sprite_ref[1][1] - 16 * vop_ref[1][1])), w);
+ virtual_ref[1][0] = 16 * vop_ref[0][0] +
+ ROUNDED_DIV(((h - h2) * (r * sprite_ref[0][0] - 16 * vop_ref[0][0]) +
+ h2 * (r * sprite_ref[2][0] - 16 * vop_ref[2][0])), h);
+ virtual_ref[1][1] = 16 * (vop_ref[0][1] + h2) +
+ ROUNDED_DIV(((h - h2) * (r * sprite_ref[0][1] - 16 * vop_ref[0][1]) +
+ h2 * (r * sprite_ref[2][1] - 16 * vop_ref[2][1])), h);
- switch(s->num_sprite_warping_points)
- {
- case 0:
- s->sprite_offset[0][0]= 0;
- s->sprite_offset[0][1]= 0;
- s->sprite_offset[1][0]= 0;
- s->sprite_offset[1][1]= 0;
- s->sprite_delta[0][0]= a;
- s->sprite_delta[0][1]= 0;
- s->sprite_delta[1][0]= 0;
- s->sprite_delta[1][1]= a;
- s->sprite_shift[0]= 0;
- s->sprite_shift[1]= 0;
- break;
- case 1: //GMC only
- s->sprite_offset[0][0]= sprite_ref[0][0] - a*vop_ref[0][0];
- s->sprite_offset[0][1]= sprite_ref[0][1] - a*vop_ref[0][1];
- s->sprite_offset[1][0]= ((sprite_ref[0][0]>>1)|(sprite_ref[0][0]&1)) - a*(vop_ref[0][0]/2);
- s->sprite_offset[1][1]= ((sprite_ref[0][1]>>1)|(sprite_ref[0][1]&1)) - a*(vop_ref[0][1]/2);
- s->sprite_delta[0][0]= a;
- s->sprite_delta[0][1]= 0;
- s->sprite_delta[1][0]= 0;
- s->sprite_delta[1][1]= a;
- s->sprite_shift[0]= 0;
- s->sprite_shift[1]= 0;
- break;
- case 2:
- s->sprite_offset[0][0]= (sprite_ref[0][0]<<(alpha+rho))
- + (-r*sprite_ref[0][0] + virtual_ref[0][0])*(-vop_ref[0][0])
- + ( r*sprite_ref[0][1] - virtual_ref[0][1])*(-vop_ref[0][1])
- + (1<<(alpha+rho-1));
- s->sprite_offset[0][1]= (sprite_ref[0][1]<<(alpha+rho))
- + (-r*sprite_ref[0][1] + virtual_ref[0][1])*(-vop_ref[0][0])
- + (-r*sprite_ref[0][0] + virtual_ref[0][0])*(-vop_ref[0][1])
- + (1<<(alpha+rho-1));
- s->sprite_offset[1][0]= ( (-r*sprite_ref[0][0] + virtual_ref[0][0])*(-2*vop_ref[0][0] + 1)
- +( r*sprite_ref[0][1] - virtual_ref[0][1])*(-2*vop_ref[0][1] + 1)
- +2*w2*r*sprite_ref[0][0]
- - 16*w2
- + (1<<(alpha+rho+1)));
- s->sprite_offset[1][1]= ( (-r*sprite_ref[0][1] + virtual_ref[0][1])*(-2*vop_ref[0][0] + 1)
- +(-r*sprite_ref[0][0] + virtual_ref[0][0])*(-2*vop_ref[0][1] + 1)
- +2*w2*r*sprite_ref[0][1]
- - 16*w2
- + (1<<(alpha+rho+1)));
- s->sprite_delta[0][0]= (-r*sprite_ref[0][0] + virtual_ref[0][0]);
- s->sprite_delta[0][1]= (+r*sprite_ref[0][1] - virtual_ref[0][1]);
- s->sprite_delta[1][0]= (-r*sprite_ref[0][1] + virtual_ref[0][1]);
- s->sprite_delta[1][1]= (-r*sprite_ref[0][0] + virtual_ref[0][0]);
+ switch (ctx->num_sprite_warping_points) {
+ case 0:
+ s->sprite_offset[0][0] =
+ s->sprite_offset[0][1] =
+ s->sprite_offset[1][0] =
+ s->sprite_offset[1][1] = 0;
+ s->sprite_delta[0][0] = a;
+ s->sprite_delta[0][1] =
+ s->sprite_delta[1][0] = 0;
+ s->sprite_delta[1][1] = a;
+ ctx->sprite_shift[0] =
+ ctx->sprite_shift[1] = 0;
+ break;
+ case 1: // GMC only
+ s->sprite_offset[0][0] = sprite_ref[0][0] - a * vop_ref[0][0];
+ s->sprite_offset[0][1] = sprite_ref[0][1] - a * vop_ref[0][1];
+ s->sprite_offset[1][0] = ((sprite_ref[0][0] >> 1) | (sprite_ref[0][0] & 1)) -
+ a * (vop_ref[0][0] / 2);
+ s->sprite_offset[1][1] = ((sprite_ref[0][1] >> 1) | (sprite_ref[0][1] & 1)) -
+ a * (vop_ref[0][1] / 2);
+ s->sprite_delta[0][0] = a;
+ s->sprite_delta[0][1] =
+ s->sprite_delta[1][0] = 0;
+ s->sprite_delta[1][1] = a;
+ ctx->sprite_shift[0] =
+ ctx->sprite_shift[1] = 0;
+ break;
+ case 2:
+ s->sprite_offset[0][0] = (sprite_ref[0][0] << (alpha + rho)) +
+ (-r * sprite_ref[0][0] + virtual_ref[0][0]) *
+ (-vop_ref[0][0]) +
+ (r * sprite_ref[0][1] - virtual_ref[0][1]) *
+ (-vop_ref[0][1]) + (1 << (alpha + rho - 1));
+ s->sprite_offset[0][1] = (sprite_ref[0][1] << (alpha + rho)) +
+ (-r * sprite_ref[0][1] + virtual_ref[0][1]) *
+ (-vop_ref[0][0]) +
+ (-r * sprite_ref[0][0] + virtual_ref[0][0]) *
+ (-vop_ref[0][1]) + (1 << (alpha + rho - 1));
+ s->sprite_offset[1][0] = ((-r * sprite_ref[0][0] + virtual_ref[0][0]) *
+ (-2 * vop_ref[0][0] + 1) +
+ (r * sprite_ref[0][1] - virtual_ref[0][1]) *
+ (-2 * vop_ref[0][1] + 1) + 2 * w2 * r *
+ sprite_ref[0][0] - 16 * w2 + (1 << (alpha + rho + 1)));
+ s->sprite_offset[1][1] = ((-r * sprite_ref[0][1] + virtual_ref[0][1]) *
+ (-2 * vop_ref[0][0] + 1) +
+ (-r * sprite_ref[0][0] + virtual_ref[0][0]) *
+ (-2 * vop_ref[0][1] + 1) + 2 * w2 * r *
+ sprite_ref[0][1] - 16 * w2 + (1 << (alpha + rho + 1)));
+ s->sprite_delta[0][0] = (-r * sprite_ref[0][0] + virtual_ref[0][0]);
+ s->sprite_delta[0][1] = (+r * sprite_ref[0][1] - virtual_ref[0][1]);
+ s->sprite_delta[1][0] = (-r * sprite_ref[0][1] + virtual_ref[0][1]);
+ s->sprite_delta[1][1] = (-r * sprite_ref[0][0] + virtual_ref[0][0]);
- s->sprite_shift[0]= alpha+rho;
- s->sprite_shift[1]= alpha+rho+2;
- break;
- case 3:
- min_ab= FFMIN(alpha, beta);
- w3= w2>>min_ab;
- h3= h2>>min_ab;
- s->sprite_offset[0][0]= (sprite_ref[0][0]<<(alpha+beta+rho-min_ab))
- + (-r*sprite_ref[0][0] + virtual_ref[0][0])*h3*(-vop_ref[0][0])
- + (-r*sprite_ref[0][0] + virtual_ref[1][0])*w3*(-vop_ref[0][1])
- + (1<<(alpha+beta+rho-min_ab-1));
- s->sprite_offset[0][1]= (sprite_ref[0][1]<<(alpha+beta+rho-min_ab))
- + (-r*sprite_ref[0][1] + virtual_ref[0][1])*h3*(-vop_ref[0][0])
- + (-r*sprite_ref[0][1] + virtual_ref[1][1])*w3*(-vop_ref[0][1])
- + (1<<(alpha+beta+rho-min_ab-1));
- s->sprite_offset[1][0]= (-r*sprite_ref[0][0] + virtual_ref[0][0])*h3*(-2*vop_ref[0][0] + 1)
- + (-r*sprite_ref[0][0] + virtual_ref[1][0])*w3*(-2*vop_ref[0][1] + 1)
- + 2*w2*h3*r*sprite_ref[0][0]
- - 16*w2*h3
- + (1<<(alpha+beta+rho-min_ab+1));
- s->sprite_offset[1][1]= (-r*sprite_ref[0][1] + virtual_ref[0][1])*h3*(-2*vop_ref[0][0] + 1)
- + (-r*sprite_ref[0][1] + virtual_ref[1][1])*w3*(-2*vop_ref[0][1] + 1)
- + 2*w2*h3*r*sprite_ref[0][1]
- - 16*w2*h3
- + (1<<(alpha+beta+rho-min_ab+1));
- s->sprite_delta[0][0]= (-r*sprite_ref[0][0] + virtual_ref[0][0])*h3;
- s->sprite_delta[0][1]= (-r*sprite_ref[0][0] + virtual_ref[1][0])*w3;
- s->sprite_delta[1][0]= (-r*sprite_ref[0][1] + virtual_ref[0][1])*h3;
- s->sprite_delta[1][1]= (-r*sprite_ref[0][1] + virtual_ref[1][1])*w3;
+ ctx->sprite_shift[0] = alpha + rho;
+ ctx->sprite_shift[1] = alpha + rho + 2;
+ break;
+ case 3:
+ min_ab = FFMIN(alpha, beta);
+ w3 = w2 >> min_ab;
+ h3 = h2 >> min_ab;
+ s->sprite_offset[0][0] = (sprite_ref[0][0] << (alpha + beta + rho - min_ab)) +
+ (-r * sprite_ref[0][0] + virtual_ref[0][0]) *
+ h3 * (-vop_ref[0][0]) +
+ (-r * sprite_ref[0][0] + virtual_ref[1][0]) *
+ w3 * (-vop_ref[0][1]) +
+ (1 << (alpha + beta + rho - min_ab - 1));
+ s->sprite_offset[0][1] = (sprite_ref[0][1] << (alpha + beta + rho - min_ab)) +
+ (-r * sprite_ref[0][1] + virtual_ref[0][1]) *
+ h3 * (-vop_ref[0][0]) +
+ (-r * sprite_ref[0][1] + virtual_ref[1][1]) *
+ w3 * (-vop_ref[0][1]) +
+ (1 << (alpha + beta + rho - min_ab - 1));
+ s->sprite_offset[1][0] = (-r * sprite_ref[0][0] + virtual_ref[0][0]) *
+ h3 * (-2 * vop_ref[0][0] + 1) +
+ (-r * sprite_ref[0][0] + virtual_ref[1][0]) *
+ w3 * (-2 * vop_ref[0][1] + 1) + 2 * w2 * h3 *
+ r * sprite_ref[0][0] - 16 * w2 * h3 +
+ (1 << (alpha + beta + rho - min_ab + 1));
+ s->sprite_offset[1][1] = (-r * sprite_ref[0][1] + virtual_ref[0][1]) *
+ h3 * (-2 * vop_ref[0][0] + 1) +
+ (-r * sprite_ref[0][1] + virtual_ref[1][1]) *
+ w3 * (-2 * vop_ref[0][1] + 1) + 2 * w2 * h3 *
+ r * sprite_ref[0][1] - 16 * w2 * h3 +
+ (1 << (alpha + beta + rho - min_ab + 1));
+ s->sprite_delta[0][0] = (-r * sprite_ref[0][0] + virtual_ref[0][0]) * h3;
+ s->sprite_delta[0][1] = (-r * sprite_ref[0][0] + virtual_ref[1][0]) * w3;
+ s->sprite_delta[1][0] = (-r * sprite_ref[0][1] + virtual_ref[0][1]) * h3;
+ s->sprite_delta[1][1] = (-r * sprite_ref[0][1] + virtual_ref[1][1]) * w3;
- s->sprite_shift[0]= alpha + beta + rho - min_ab;
- s->sprite_shift[1]= alpha + beta + rho - min_ab + 2;
- break;
+ ctx->sprite_shift[0] = alpha + beta + rho - min_ab;
+ ctx->sprite_shift[1] = alpha + beta + rho - min_ab + 2;
+ break;
}
/* try to simplify the situation */
- if( s->sprite_delta[0][0] == a<<s->sprite_shift[0]
- && s->sprite_delta[0][1] == 0
- && s->sprite_delta[1][0] == 0
- && s->sprite_delta[1][1] == a<<s->sprite_shift[0])
- {
- s->sprite_offset[0][0]>>=s->sprite_shift[0];
- s->sprite_offset[0][1]>>=s->sprite_shift[0];
- s->sprite_offset[1][0]>>=s->sprite_shift[1];
- s->sprite_offset[1][1]>>=s->sprite_shift[1];
- s->sprite_delta[0][0]= a;
- s->sprite_delta[0][1]= 0;
- s->sprite_delta[1][0]= 0;
- s->sprite_delta[1][1]= a;
- s->sprite_shift[0]= 0;
- s->sprite_shift[1]= 0;
- s->real_sprite_warping_points=1;
- }
- else{
- int shift_y= 16 - s->sprite_shift[0];
- int shift_c= 16 - s->sprite_shift[1];
- for(i=0; i<2; i++){
- s->sprite_offset[0][i]<<= shift_y;
- s->sprite_offset[1][i]<<= shift_c;
- s->sprite_delta[0][i]<<= shift_y;
- s->sprite_delta[1][i]<<= shift_y;
- s->sprite_shift[i]= 16;
+ if (s->sprite_delta[0][0] == a << ctx->sprite_shift[0] &&
+ s->sprite_delta[0][1] == 0 &&
+ s->sprite_delta[1][0] == 0 &&
+ s->sprite_delta[1][1] == a << ctx->sprite_shift[0]) {
+ s->sprite_offset[0][0] >>= ctx->sprite_shift[0];
+ s->sprite_offset[0][1] >>= ctx->sprite_shift[0];
+ s->sprite_offset[1][0] >>= ctx->sprite_shift[1];
+ s->sprite_offset[1][1] >>= ctx->sprite_shift[1];
+ s->sprite_delta[0][0] = a;
+ s->sprite_delta[0][1] = 0;
+ s->sprite_delta[1][0] = 0;
+ s->sprite_delta[1][1] = a;
+ ctx->sprite_shift[0] = 0;
+ ctx->sprite_shift[1] = 0;
+ s->real_sprite_warping_points = 1;
+ } else {
+ int shift_y = 16 - ctx->sprite_shift[0];
+ int shift_c = 16 - ctx->sprite_shift[1];
+ for (i = 0; i < 2; i++) {
+ s->sprite_offset[0][i] <<= shift_y;
+ s->sprite_offset[1][i] <<= shift_c;
+ s->sprite_delta[0][i] <<= shift_y;
+ s->sprite_delta[1][i] <<= shift_y;
+ ctx->sprite_shift[i] = 16;
}
- s->real_sprite_warping_points= s->num_sprite_warping_points;
+ s->real_sprite_warping_points = ctx->num_sprite_warping_points;
}
+
return 0;
}
-static int decode_new_pred(MpegEncContext *s, GetBitContext *gb){
- int len = FFMIN(s->time_increment_bits + 3, 15);
+static int decode_new_pred(Mpeg4DecContext *ctx, GetBitContext *gb) {
+ int len = FFMIN(ctx->time_increment_bits + 3, 15);
get_bits(gb, len);
if (get_bits1(gb))
@@ -369,86 +387,91 @@
* Decode the next video packet.
* @return <0 if something went wrong
*/
-int ff_mpeg4_decode_video_packet_header(MpegEncContext *s)
+int ff_mpeg4_decode_video_packet_header(Mpeg4DecContext *ctx)
{
- int mb_num_bits= av_log2(s->mb_num - 1) + 1;
- int header_extension=0, mb_num, len;
+ MpegEncContext *s = &ctx->m;
+
+ int mb_num_bits = av_log2(s->mb_num - 1) + 1;
+ int header_extension = 0, mb_num, len;
/* is there enough space left for a video packet + header */
- if( get_bits_count(&s->gb) > s->gb.size_in_bits-20) return -1;
+ if (get_bits_count(&s->gb) > s->gb.size_in_bits - 20)
+ return -1;
- for(len=0; len<32; len++){
- if(get_bits1(&s->gb)) break;
- }
+ for (len = 0; len < 32; len++)
+ if (get_bits1(&s->gb))
+ break;
- if(len!=ff_mpeg4_get_video_packet_prefix_length(s)){
+ if (len != ff_mpeg4_get_video_packet_prefix_length(s)) {
av_log(s->avctx, AV_LOG_ERROR, "marker does not match f_code\n");
return -1;
}
- if(s->shape != RECT_SHAPE){
- header_extension= get_bits1(&s->gb);
- //FIXME more stuff here
+ if (ctx->shape != RECT_SHAPE) {
+ header_extension = get_bits1(&s->gb);
+ // FIXME more stuff here
}
- mb_num= get_bits(&s->gb, mb_num_bits);
- if(mb_num>=s->mb_num){
- av_log(s->avctx, AV_LOG_ERROR, "illegal mb_num in video packet (%d %d) \n", mb_num, s->mb_num);
+ mb_num = get_bits(&s->gb, mb_num_bits);
+ if (mb_num >= s->mb_num) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "illegal mb_num in video packet (%d %d) \n", mb_num, s->mb_num);
return -1;
}
- s->mb_x= mb_num % s->mb_width;
- s->mb_y= mb_num / s->mb_width;
+ s->mb_x = mb_num % s->mb_width;
+ s->mb_y = mb_num / s->mb_width;
- if(s->shape != BIN_ONLY_SHAPE){
- int qscale= get_bits(&s->gb, s->quant_precision);
- if(qscale)
- s->chroma_qscale=s->qscale= qscale;
+ if (ctx->shape != BIN_ONLY_SHAPE) {
+ int qscale = get_bits(&s->gb, s->quant_precision);
+ if (qscale)
+ s->chroma_qscale = s->qscale = qscale;
}
- if(s->shape == RECT_SHAPE){
- header_extension= get_bits1(&s->gb);
- }
- if(header_extension){
- int time_incr=0;
+ if (ctx->shape == RECT_SHAPE)
+ header_extension = get_bits1(&s->gb);
+
+ if (header_extension) {
+ int time_incr = 0;
while (get_bits1(&s->gb) != 0)
time_incr++;
check_marker(&s->gb, "before time_increment in video packed header");
- skip_bits(&s->gb, s->time_increment_bits); /* time_increment */
+ skip_bits(&s->gb, ctx->time_increment_bits); /* time_increment */
check_marker(&s->gb, "before vop_coding_type in video packed header");
skip_bits(&s->gb, 2); /* vop coding type */
- //FIXME not rect stuff here
+ // FIXME not rect stuff here
- if(s->shape != BIN_ONLY_SHAPE){
+ if (ctx->shape != BIN_ONLY_SHAPE) {
skip_bits(&s->gb, 3); /* intra dc vlc threshold */
-//FIXME don't just ignore everything
- if(s->pict_type == AV_PICTURE_TYPE_S && s->vol_sprite_usage==GMC_SPRITE){
- if (mpeg4_decode_sprite_trajectory(s, &s->gb) < 0)
+ // FIXME don't just ignore everything
+ if (s->pict_type == AV_PICTURE_TYPE_S &&
+ ctx->vol_sprite_usage == GMC_SPRITE) {
+ if (mpeg4_decode_sprite_trajectory(ctx, &s->gb) < 0)
return AVERROR_INVALIDDATA;
av_log(s->avctx, AV_LOG_ERROR, "untested\n");
}
- //FIXME reduced res stuff here
+ // FIXME reduced res stuff here
if (s->pict_type != AV_PICTURE_TYPE_I) {
int f_code = get_bits(&s->gb, 3); /* fcode_for */
- if(f_code==0){
- av_log(s->avctx, AV_LOG_ERROR, "Error, video packet header damaged (f_code=0)\n");
- }
+ if (f_code == 0)
+ av_log(s->avctx, AV_LOG_ERROR,
+ "Error, video packet header damaged (f_code=0)\n");
}
if (s->pict_type == AV_PICTURE_TYPE_B) {
int b_code = get_bits(&s->gb, 3);
- if(b_code==0){
- av_log(s->avctx, AV_LOG_ERROR, "Error, video packet header damaged (b_code=0)\n");
- }
+ if (b_code == 0)
+ av_log(s->avctx, AV_LOG_ERROR,
+ "Error, video packet header damaged (b_code=0)\n");
}
}
}
- if (s->new_pred)
- decode_new_pred(s, &s->gb);
+ if (ctx->new_pred)
+ decode_new_pred(ctx, &s->gb);
return 0;
}
@@ -458,43 +481,49 @@
* @param n either 0 for the x component or 1 for y
* @return the average MV for a GMC MB
*/
-static inline int get_amv(MpegEncContext *s, int n){
+static inline int get_amv(Mpeg4DecContext *ctx, int n)
+{
+ MpegEncContext *s = &ctx->m;
int x, y, mb_v, sum, dx, dy, shift;
- int len = 1 << (s->f_code + 4);
- const int a= s->sprite_warping_accuracy;
+ int len = 1 << (s->f_code + 4);
+ const int a = s->sprite_warping_accuracy;
- if(s->workaround_bugs & FF_BUG_AMV)
+ if (s->workaround_bugs & FF_BUG_AMV)
len >>= s->quarter_sample;
- if(s->real_sprite_warping_points==1){
- if(s->divx_version==500 && s->divx_build==413)
- sum= s->sprite_offset[0][n] / (1<<(a - s->quarter_sample));
+ if (s->real_sprite_warping_points == 1) {
+ if (ctx->divx_version == 500 && ctx->divx_build == 413)
+ sum = s->sprite_offset[0][n] / (1 << (a - s->quarter_sample));
else
- sum= RSHIFT(s->sprite_offset[0][n]<<s->quarter_sample, a);
- }else{
- dx= s->sprite_delta[n][0];
- dy= s->sprite_delta[n][1];
- shift= s->sprite_shift[0];
- if(n) dy -= 1<<(shift + a + 1);
- else dx -= 1<<(shift + a + 1);
- mb_v= s->sprite_offset[0][n] + dx*s->mb_x*16 + dy*s->mb_y*16;
+ sum = RSHIFT(s->sprite_offset[0][n] << s->quarter_sample, a);
+ } else {
+ dx = s->sprite_delta[n][0];
+ dy = s->sprite_delta[n][1];
+ shift = ctx->sprite_shift[0];
+ if (n)
+ dy -= 1 << (shift + a + 1);
+ else
+ dx -= 1 << (shift + a + 1);
+ mb_v = s->sprite_offset[0][n] + dx * s->mb_x * 16 + dy * s->mb_y * 16;
- sum=0;
- for(y=0; y<16; y++){
+ sum = 0;
+ for (y = 0; y < 16; y++) {
int v;
- v= mb_v + dy*y;
- //XXX FIXME optimize
- for(x=0; x<16; x++){
- sum+= v>>shift;
- v+= dx;
+ v = mb_v + dy * y;
+ // FIXME optimize
+ for (x = 0; x < 16; x++) {
+ sum += v >> shift;
+ v += dx;
}
}
- sum= RSHIFT(sum, a+8-s->quarter_sample);
+ sum = RSHIFT(sum, a + 8 - s->quarter_sample);
}
- if (sum < -len) sum= -len;
- else if (sum >= len) sum= len-1;
+ if (sum < -len)
+ sum = -len;
+ else if (sum >= len)
+ sum = len - 1;
return sum;
}
@@ -505,7 +534,7 @@
* @param dir_ptr the prediction direction will be stored here
* @return the quantized dc
*/
-static inline int mpeg4_decode_dc(MpegEncContext * s, int n, int *dir_ptr)
+static inline int mpeg4_decode_dc(MpegEncContext *s, int n, int *dir_ptr)
{
int level, code;
@@ -513,29 +542,31 @@
code = get_vlc2(&s->gb, dc_lum.table, DC_VLC_BITS, 1);
else
code = get_vlc2(&s->gb, dc_chrom.table, DC_VLC_BITS, 1);
- if (code < 0 || code > 9 /* && s->nbit<9 */){
+
+ if (code < 0 || code > 9 /* && s->nbit < 9 */) {
av_log(s->avctx, AV_LOG_ERROR, "illegal dc vlc\n");
return -1;
}
+
if (code == 0) {
level = 0;
} else {
- if(IS_3IV1){
- if(code==1)
- level= 2*get_bits1(&s->gb)-1;
- else{
- if(get_bits1(&s->gb))
- level = get_bits(&s->gb, code-1) + (1<<(code-1));
+ if (IS_3IV1) {
+ if (code == 1)
+ level = 2 * get_bits1(&s->gb) - 1;
+ else {
+ if (get_bits1(&s->gb))
+ level = get_bits(&s->gb, code - 1) + (1 << (code - 1));
else
- level = -get_bits(&s->gb, code-1) - (1<<(code-1));
+ level = -get_bits(&s->gb, code - 1) - (1 << (code - 1));
}
- }else{
+ } else {
level = get_xbits(&s->gb, code);
}
- if (code > 8){
- if(get_bits1(&s->gb)==0){ /* marker */
- if(s->err_recognition&(AV_EF_BITSTREAM|AV_EF_COMPLIANT)){
+ if (code > 8) {
+ if (get_bits1(&s->gb) == 0) { /* marker */
+ if (s->err_recognition & (AV_EF_BITSTREAM|AV_EF_COMPLIANT)) {
av_log(s->avctx, AV_LOG_ERROR, "dc marker bit missing\n");
return -1;
}
@@ -550,124 +581,145 @@
* Decode first partition.
* @return number of MBs decoded or <0 if an error occurred
*/
-static int mpeg4_decode_partition_a(MpegEncContext *s){
- int mb_num;
+static int mpeg4_decode_partition_a(Mpeg4DecContext *ctx)
+{
+ MpegEncContext *s = &ctx->m;
+ int mb_num = 0;
static const int8_t quant_tab[4] = { -1, -2, 1, 2 };
/* decode first partition */
- mb_num=0;
- s->first_slice_line=1;
- for(; s->mb_y<s->mb_height; s->mb_y++){
+ s->first_slice_line = 1;
+ for (; s->mb_y < s->mb_height; s->mb_y++) {
ff_init_block_index(s);
- for(; s->mb_x<s->mb_width; s->mb_x++){
- const int xy= s->mb_x + s->mb_y*s->mb_stride;
+ for (; s->mb_x < s->mb_width; s->mb_x++) {
+ const int xy = s->mb_x + s->mb_y * s->mb_stride;
int cbpc;
- int dir=0;
+ int dir = 0;
mb_num++;
ff_update_block_index(s);
- if(s->mb_x == s->resync_mb_x && s->mb_y == s->resync_mb_y+1)
- s->first_slice_line=0;
+ if (s->mb_x == s->resync_mb_x && s->mb_y == s->resync_mb_y + 1)
+ s->first_slice_line = 0;
- if(s->pict_type==AV_PICTURE_TYPE_I){
+ if (s->pict_type == AV_PICTURE_TYPE_I) {
int i;
- do{
- if(show_bits_long(&s->gb, 19)==DC_MARKER){
- return mb_num-1;
- }
+ do {
+ if (show_bits_long(&s->gb, 19) == DC_MARKER)
+ return mb_num - 1;
cbpc = get_vlc2(&s->gb, ff_h263_intra_MCBPC_vlc.table, INTRA_MCBPC_VLC_BITS, 2);
- if (cbpc < 0){
- av_log(s->avctx, AV_LOG_ERROR, "cbpc corrupted at %d %d\n", s->mb_x, s->mb_y);
+ if (cbpc < 0) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "cbpc corrupted at %d %d\n", s->mb_x, s->mb_y);
return -1;
}
- }while(cbpc == 8);
+ } while (cbpc == 8);
- s->cbp_table[xy]= cbpc & 3;
+ s->cbp_table[xy] = cbpc & 3;
s->current_picture.mb_type[xy] = MB_TYPE_INTRA;
- s->mb_intra = 1;
+ s->mb_intra = 1;
- if(cbpc & 4) {
+ 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->mbintra_table[xy]= 1;
- for(i=0; i<6; i++){
+ s->current_picture.qscale_table[xy] = s->qscale;
+
+ s->mbintra_table[xy] = 1;
+ for (i = 0; i < 6; i++) {
int dc_pred_dir;
- int dc= mpeg4_decode_dc(s, i, &dc_pred_dir);
- if(dc < 0){
- av_log(s->avctx, AV_LOG_ERROR, "DC corrupted at %d %d\n", s->mb_x, s->mb_y);
+ int dc = mpeg4_decode_dc(s, i, &dc_pred_dir);
+ if (dc < 0) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "DC corrupted at %d %d\n", s->mb_x, s->mb_y);
return -1;
}
- dir<<=1;
- if(dc_pred_dir) dir|=1;
+ dir <<= 1;
+ if (dc_pred_dir)
+ dir |= 1;
}
- s->pred_dir_table[xy]= dir;
- }else{ /* P/S_TYPE */
+ 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]];
- const int stride= s->b8_stride*2;
+ int16_t *const mot_val = s->current_picture.motion_val[0][s->block_index[0]];
+ const int stride = s->b8_stride * 2;
try_again:
- bits= show_bits(&s->gb, 17);
- if(bits==MOTION_MARKER){
- return mb_num-1;
- }
- skip_bits1(&s->gb);
- 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;
- 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;
- mx=my=0;
- }
- mot_val[0 ]= mot_val[2 ]=
- mot_val[0+stride]= mot_val[2+stride]= mx;
- mot_val[1 ]= mot_val[3 ]=
- mot_val[1+stride]= mot_val[3+stride]= my;
+ bits = show_bits(&s->gb, 17);
+ if (bits == MOTION_MARKER)
+ return mb_num - 1;
- if(s->mbintra_table[xy])
+ skip_bits1(&s->gb);
+ if (bits & 0x10000) {
+ /* skip mb */
+ if (s->pict_type == AV_PICTURE_TYPE_S &&
+ ctx->vol_sprite_usage == GMC_SPRITE) {
+ s->current_picture.mb_type[xy] = MB_TYPE_SKIP |
+ MB_TYPE_16x16 |
+ MB_TYPE_GMC |
+ MB_TYPE_L0;
+ mx = get_amv(ctx, 0);
+ my = get_amv(ctx, 1);
+ } else {
+ s->current_picture.mb_type[xy] = MB_TYPE_SKIP |
+ MB_TYPE_16x16 |
+ MB_TYPE_L0;
+ mx = my = 0;
+ }
+ mot_val[0] =
+ mot_val[2] =
+ mot_val[0 + stride] =
+ mot_val[2 + stride] = mx;
+ mot_val[1] =
+ mot_val[3] =
+ mot_val[1 + stride] =
+ mot_val[3 + stride] = my;
+
+ if (s->mbintra_table[xy])
ff_clean_intra_table_entries(s);
continue;
}
cbpc = get_vlc2(&s->gb, ff_h263_inter_MCBPC_vlc.table, INTER_MCBPC_VLC_BITS, 2);
- if (cbpc < 0){
- av_log(s->avctx, AV_LOG_ERROR, "cbpc corrupted at %d %d\n", s->mb_x, s->mb_y);
+ if (cbpc < 0) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "cbpc corrupted at %d %d\n", s->mb_x, s->mb_y);
return -1;
}
- if(cbpc == 20)
+ if (cbpc == 20)
goto try_again;
- s->cbp_table[xy]= cbpc&(8+3); //8 is dquant
+ s->cbp_table[xy] = cbpc & (8 + 3); // 8 is dquant
s->mb_intra = ((cbpc & 4) != 0);
- if(s->mb_intra){
+ if (s->mb_intra) {
s->current_picture.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;
- mot_val[1 ]= mot_val[3 ]=
- mot_val[1+stride]= mot_val[3+stride]= 0;
- }else{
- if(s->mbintra_table[xy])
+ s->mbintra_table[xy] = 1;
+ 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;
+ } else {
+ if (s->mbintra_table[xy])
ff_clean_intra_table_entries(s);
- if(s->pict_type==AV_PICTURE_TYPE_S && s->vol_sprite_usage==GMC_SPRITE && (cbpc & 16) == 0)
- s->mcsel= get_bits1(&s->gb);
- else s->mcsel= 0;
+ if (s->pict_type == AV_PICTURE_TYPE_S &&
+ ctx->vol_sprite_usage == GMC_SPRITE &&
+ (cbpc & 16) == 0)
+ s->mcsel = get_bits1(&s->gb);
+ else
+ s->mcsel = 0;
if ((cbpc & 16) == 0) {
/* 16x16 motion prediction */
ff_h263_pred_motion(s, 0, 0, &pred_x, &pred_y);
- if(!s->mcsel){
+ if (!s->mcsel) {
mx = ff_h263_decode_motion(s, pred_x, s->f_code);
if (mx >= 0xffff)
return -1;
@@ -675,22 +727,30 @@
my = ff_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.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;
+ mx = get_amv(ctx, 0);
+ my = get_amv(ctx, 1);
+ s->current_picture.mb_type[xy] = MB_TYPE_16x16 |
+ MB_TYPE_GMC |
+ MB_TYPE_L0;
}
- mot_val[0 ]= mot_val[2 ] =
- mot_val[0+stride]= mot_val[2+stride]= mx;
- mot_val[1 ]= mot_val[3 ]=
- mot_val[1+stride]= mot_val[3+stride]= my;
+ mot_val[0] =
+ mot_val[2] =
+ mot_val[0 + stride] =
+ mot_val[2 + stride] = mx;
+ mot_val[1] =
+ mot_val[3] =
+ mot_val[1 + stride] =
+ mot_val[3 + stride] = my;
} else {
int i;
- s->current_picture.mb_type[xy] = MB_TYPE_8x8 | MB_TYPE_L0;
- for(i=0;i<4;i++) {
- int16_t *mot_val= ff_h263_pred_motion(s, i, 0, &pred_x, &pred_y);
+ s->current_picture.mb_type[xy] = MB_TYPE_8x8 |
+ MB_TYPE_L0;
+ for (i = 0; i < 4; i++) {
+ int16_t *mot_val = ff_h263_pred_motion(s, i, 0, &pred_x, &pred_y);
mx = ff_h263_decode_motion(s, pred_x, s->f_code);
if (mx >= 0xffff)
return -1;
@@ -705,7 +765,7 @@
}
}
}
- s->mb_x= 0;
+ s->mb_x = 0;
}
return mb_num;
@@ -715,85 +775,91 @@
* decode second partition.
* @return <0 if an error occurred
*/
-static int mpeg4_decode_partition_b(MpegEncContext *s, int mb_count){
- int mb_num=0;
+static int mpeg4_decode_partition_b(MpegEncContext *s, int mb_count)
+{
+ int mb_num = 0;
static const int8_t quant_tab[4] = { -1, -2, 1, 2 };
- s->mb_x= s->resync_mb_x;
- s->first_slice_line=1;
- for(s->mb_y= s->resync_mb_y; mb_num < mb_count; s->mb_y++){
+ s->mb_x = s->resync_mb_x;
+ s->first_slice_line = 1;
+ for (s->mb_y = s->resync_mb_y; mb_num < mb_count; s->mb_y++) {
ff_init_block_index(s);
- for(; mb_num < mb_count && s->mb_x<s->mb_width; s->mb_x++){
- const int xy= s->mb_x + s->mb_y*s->mb_stride;
+ for (; mb_num < mb_count && s->mb_x < s->mb_width; s->mb_x++) {
+ const int xy = s->mb_x + s->mb_y * s->mb_stride;
mb_num++;
ff_update_block_index(s);
- if(s->mb_x == s->resync_mb_x && s->mb_y == s->resync_mb_y+1)
- s->first_slice_line=0;
+ if (s->mb_x == s->resync_mb_x && s->mb_y == s->resync_mb_y + 1)
+ s->first_slice_line = 0;
- if(s->pict_type==AV_PICTURE_TYPE_I){
- int ac_pred= get_bits1(&s->gb);
- int cbpy = get_vlc2(&s->gb, ff_h263_cbpy_vlc.table, CBPY_VLC_BITS, 1);
- if(cbpy<0){
- av_log(s->avctx, AV_LOG_ERROR, "cbpy corrupted at %d %d\n", s->mb_x, s->mb_y);
+ if (s->pict_type == AV_PICTURE_TYPE_I) {
+ int ac_pred = get_bits1(&s->gb);
+ int cbpy = get_vlc2(&s->gb, ff_h263_cbpy_vlc.table, CBPY_VLC_BITS, 1);
+ if (cbpy < 0) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "cbpy corrupted at %d %d\n", s->mb_x, s->mb_y);
return -1;
}
- s->cbp_table[xy]|= cbpy<<2;
- s->current_picture.mb_type[xy] |= ac_pred*MB_TYPE_ACPRED;
- }else{ /* P || S_TYPE */
+ s->cbp_table[xy] |= cbpy << 2;
+ s->current_picture.mb_type[xy] |= ac_pred * MB_TYPE_ACPRED;
+ } else { /* P || S_TYPE */
if (IS_INTRA(s->current_picture.mb_type[xy])) {
- int dir=0,i;
+ int i;
+ int dir = 0;
int ac_pred = get_bits1(&s->gb);
- int cbpy = get_vlc2(&s->gb, ff_h263_cbpy_vlc.table, CBPY_VLC_BITS, 1);
+ int cbpy = get_vlc2(&s->gb, ff_h263_cbpy_vlc.table, CBPY_VLC_BITS, 1);
- if(cbpy<0){
- av_log(s->avctx, AV_LOG_ERROR, "I cbpy corrupted at %d %d\n", s->mb_x, s->mb_y);
+ if (cbpy < 0) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "I cbpy corrupted at %d %d\n", s->mb_x, s->mb_y);
return -1;
}
- if(s->cbp_table[xy] & 8) {
+ 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;
- for(i=0; i<6; i++){
+ for (i = 0; i < 6; i++) {
int dc_pred_dir;
- int dc= mpeg4_decode_dc(s, i, &dc_pred_dir);
- if(dc < 0){
- av_log(s->avctx, AV_LOG_ERROR, "DC corrupted at %d %d\n", s->mb_x, s->mb_y);
+ int dc = mpeg4_decode_dc(s, i, &dc_pred_dir);
+ if (dc < 0) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "DC corrupted at %d %d\n", s->mb_x, s->mb_y);
return -1;
}
- dir<<=1;
- if(dc_pred_dir) dir|=1;
+ dir <<= 1;
+ if (dc_pred_dir)
+ dir |= 1;
}
- 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->pred_dir_table[xy]= dir;
+ 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->pred_dir_table[xy] = dir;
} else if (IS_SKIP(s->current_picture.mb_type[xy])) {
s->current_picture.qscale_table[xy] = s->qscale;
- s->cbp_table[xy]= 0;
- }else{
+ s->cbp_table[xy] = 0;
+ } else {
int cbpy = get_vlc2(&s->gb, ff_h263_cbpy_vlc.table, CBPY_VLC_BITS, 1);
- if(cbpy<0){
- av_log(s->avctx, AV_LOG_ERROR, "P cbpy corrupted at %d %d\n", s->mb_x, s->mb_y);
+ if (cbpy < 0) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "P cbpy corrupted at %d %d\n", s->mb_x, s->mb_y);
return -1;
}
- if(s->cbp_table[xy] & 8) {
+ 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->cbp_table[xy]&= 3; //remove dquant
- s->cbp_table[xy]|= (cbpy^0xf)<<2;
+ s->cbp_table[xy] &= 3; // remove dquant
+ s->cbp_table[xy] |= (cbpy ^ 0xf) << 2;
}
}
}
- if(mb_num >= mb_count) return 0;
- s->mb_x= 0;
+ if (mb_num >= mb_count)
+ return 0;
+ s->mb_x = 0;
}
return 0;
}
@@ -802,50 +868,60 @@
* 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 ff_mpeg4_decode_partitions(Mpeg4DecContext *ctx)
{
+ MpegEncContext *s = &ctx->m;
int mb_num;
- 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;
+ 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){
- ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, part_a_error);
+ mb_num = mpeg4_decode_partition_a(ctx);
+ if (mb_num < 0) {
+ ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y,
+ s->mb_x, s->mb_y, part_a_error);
return -1;
}
- if(s->resync_mb_x + s->resync_mb_y*s->mb_width + mb_num > s->mb_num){
+ if (s->resync_mb_x + s->resync_mb_y * s->mb_width + mb_num > s->mb_num) {
av_log(s->avctx, AV_LOG_ERROR, "slice below monitor ...\n");
- ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, part_a_error);
+ ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y,
+ s->mb_x, s->mb_y, part_a_error);
return -1;
}
- s->mb_num_left= mb_num;
+ s->mb_num_left = mb_num;
- if(s->pict_type==AV_PICTURE_TYPE_I){
- while(show_bits(&s->gb, 9) == 1)
+ if (s->pict_type == AV_PICTURE_TYPE_I) {
+ while (show_bits(&s->gb, 9) == 1)
skip_bits(&s->gb, 9);
- if(get_bits_long(&s->gb, 19)!=DC_MARKER){
- av_log(s->avctx, AV_LOG_ERROR, "marker missing after first I partition at %d %d\n", s->mb_x, s->mb_y);
+ if (get_bits_long(&s->gb, 19) != DC_MARKER) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "marker missing after first I partition at %d %d\n",
+ s->mb_x, s->mb_y);
return -1;
}
- }else{
- while(show_bits(&s->gb, 10) == 1)
+ } else {
+ while (show_bits(&s->gb, 10) == 1)
skip_bits(&s->gb, 10);
- if(get_bits(&s->gb, 17)!=MOTION_MARKER){
- av_log(s->avctx, AV_LOG_ERROR, "marker missing after first P partition at %d %d\n", s->mb_x, s->mb_y);
+ if (get_bits(&s->gb, 17) != MOTION_MARKER) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "marker missing after first P partition at %d %d\n",
+ s->mb_x, s->mb_y);
return -1;
}
}
- ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, part_a_end);
+ ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y,
+ s->mb_x - 1, s->mb_y, part_a_end);
- if( mpeg4_decode_partition_b(s, mb_num) < 0){
- if(s->pict_type==AV_PICTURE_TYPE_P)
- ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, ER_DC_ERROR);
+ if (mpeg4_decode_partition_b(s, mb_num) < 0) {
+ if (s->pict_type == AV_PICTURE_TYPE_P)
+ ff_er_add_slice(&s->er, 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->er, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, ER_DC_END);
+ } else {
+ if (s->pict_type == AV_PICTURE_TYPE_P)
+ ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y,
+ s->mb_x - 1, s->mb_y, ER_DC_END);
}
return 0;
@@ -855,243 +931,265 @@
* Decode a block.
* @return <0 if an error occurred
*/
-static inline int mpeg4_decode_block(MpegEncContext * s, int16_t * block,
- int n, int coded, int intra, int rvlc)
+static inline int mpeg4_decode_block(Mpeg4DecContext *ctx, int16_t *block,
+ int n, int coded, int intra, int rvlc)
{
- int level, i, last, run;
+ MpegEncContext *s = &ctx->m;
+ int level, i, last, run, qmul, qadd;
int av_uninit(dc_pred_dir);
- RLTable * rl;
- RL_VLC_ELEM * rl_vlc;
- const uint8_t * scan_table;
- int qmul, qadd;
+ RLTable *rl;
+ RL_VLC_ELEM *rl_vlc;
+ const uint8_t *scan_table;
- //Note intra & rvlc should be optimized away if this is inlined
+ // Note intra & rvlc should be optimized away if this is inlined
- if(intra) {
- if(s->use_intra_dc_vlc){
- /* DC coef */
- if(s->partitioned_frame){
- level = s->dc_val[0][ s->block_index[n] ];
- if(n<4) level= FASTDIV((level + (s->y_dc_scale>>1)), s->y_dc_scale);
- else level= FASTDIV((level + (s->c_dc_scale>>1)), s->c_dc_scale);
- dc_pred_dir= (s->pred_dir_table[s->mb_x + s->mb_y*s->mb_stride]<<n)&32;
- }else{
- level = mpeg4_decode_dc(s, n, &dc_pred_dir);
- if (level < 0)
- return -1;
- }
- block[0] = level;
- i = 0;
- }else{
+ if (intra) {
+ if (ctx->use_intra_dc_vlc) {
+ /* DC coef */
+ if (s->partitioned_frame) {
+ level = s->dc_val[0][s->block_index[n]];
+ if (n < 4)
+ level = FASTDIV((level + (s->y_dc_scale >> 1)), s->y_dc_scale);
+ else
+ level = FASTDIV((level + (s->c_dc_scale >> 1)), s->c_dc_scale);
+ dc_pred_dir = (s->pred_dir_table[s->mb_x + s->mb_y * s->mb_stride] << n) & 32;
+ } else {
+ level = mpeg4_decode_dc(s, n, &dc_pred_dir);
+ if (level < 0)
+ return -1;
+ }
+ block[0] = level;
+ i = 0;
+ } else {
i = -1;
ff_mpeg4_pred_dc(s, n, 0, &dc_pred_dir, 0);
- }
- if (!coded)
- goto not_coded;
+ }
+ if (!coded)
+ goto not_coded;
- if(rvlc){
- rl = &ff_rvlc_rl_intra;
- rl_vlc = ff_rvlc_rl_intra.rl_vlc[0];
- }else{
- rl = &ff_mpeg4_rl_intra;
- rl_vlc = ff_mpeg4_rl_intra.rl_vlc[0];
- }
- if (s->ac_pred) {
- if (dc_pred_dir == 0)
- scan_table = s->intra_v_scantable.permutated; /* left */
- else
- scan_table = s->intra_h_scantable.permutated; /* top */
- } else {
+ if (rvlc) {
+ rl = &ff_rvlc_rl_intra;
+ rl_vlc = ff_rvlc_rl_intra.rl_vlc[0];
+ } else {
+ rl = &ff_mpeg4_rl_intra;
+ rl_vlc = ff_mpeg4_rl_intra.rl_vlc[0];
+ }
+ if (s->ac_pred) {
+ if (dc_pred_dir == 0)
+ scan_table = s->intra_v_scantable.permutated; /* left */
+ else
+ scan_table = s->intra_h_scantable.permutated; /* top */
+ } else {
scan_table = s->intra_scantable.permutated;
- }
- qmul=1;
- qadd=0;
+ }
+ qmul = 1;
+ qadd = 0;
} else {
i = -1;
if (!coded) {
s->block_last_index[n] = i;
return 0;
}
- if(rvlc) rl = &ff_rvlc_rl_inter;
- else rl = &ff_h263_rl_inter;
+ if (rvlc)
+ rl = &ff_rvlc_rl_inter;
+ else
+ rl = &ff_h263_rl_inter;
scan_table = s->intra_scantable.permutated;
- if(s->mpeg_quant){
- qmul=1;
- qadd=0;
- if(rvlc){
+ if (s->mpeg_quant) {
+ qmul = 1;
+ qadd = 0;
+ if (rvlc)
rl_vlc = ff_rvlc_rl_inter.rl_vlc[0];
- }else{
+ else
rl_vlc = ff_h263_rl_inter.rl_vlc[0];
- }
- }else{
+ } else {
qmul = s->qscale << 1;
qadd = (s->qscale - 1) | 1;
- if(rvlc){
+ if (rvlc)
rl_vlc = ff_rvlc_rl_inter.rl_vlc[s->qscale];
- }else{
+ else
rl_vlc = ff_h263_rl_inter.rl_vlc[s->qscale];
- }
}
}
- {
- OPEN_READER(re, &s->gb);
- for(;;) {
- UPDATE_CACHE(re, &s->gb);
- GET_RL_VLC(level, run, re, &s->gb, rl_vlc, TEX_VLC_BITS, 2, 0);
- if (level==0) {
- /* escape */
- if(rvlc){
- if(SHOW_UBITS(re, &s->gb, 1)==0){
- av_log(s->avctx, AV_LOG_ERROR, "1. marker bit missing in rvlc esc\n");
- return -1;
- }; SKIP_CACHE(re, &s->gb, 1);
+ {
+ OPEN_READER(re, &s->gb);
+ for (;;) {
+ UPDATE_CACHE(re, &s->gb);
+ GET_RL_VLC(level, run, re, &s->gb, rl_vlc, TEX_VLC_BITS, 2, 0);
+ if (level == 0) {
+ /* escape */
+ if (rvlc) {
+ if (SHOW_UBITS(re, &s->gb, 1) == 0) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "1. marker bit missing in rvlc esc\n");
+ return -1;
+ }
+ 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);
- SKIP_COUNTER(re, &s->gb, 1+1+6);
- UPDATE_CACHE(re, &s->gb);
-
- if(SHOW_UBITS(re, &s->gb, 1)==0){
- av_log(s->avctx, AV_LOG_ERROR, "2. marker bit missing in rvlc esc\n");
- return -1;
- }; SKIP_CACHE(re, &s->gb, 1);
-
- level= SHOW_UBITS(re, &s->gb, 11); SKIP_CACHE(re, &s->gb, 11);
-
- if(SHOW_UBITS(re, &s->gb, 5)!=0x10){
- av_log(s->avctx, AV_LOG_ERROR, "reverse esc missing\n");
- return -1;
- }; SKIP_CACHE(re, &s->gb, 5);
-
- level= level * qmul + qadd;
- 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;
- if(last) i+=192;
- }else{
- int cache;
- cache= GET_CACHE(re, &s->gb);
-
- if(IS_3IV1)
- cache ^= 0xC0000000;
-
- if (cache&0x80000000) {
- if (cache&0x40000000) {
- /* 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);
- SKIP_COUNTER(re, &s->gb, 2+1+6);
+ last = SHOW_UBITS(re, &s->gb, 1);
+ SKIP_CACHE(re, &s->gb, 1);
+ run = SHOW_UBITS(re, &s->gb, 6);
+ SKIP_COUNTER(re, &s->gb, 1 + 1 + 6);
UPDATE_CACHE(re, &s->gb);
- if(IS_3IV1){
- level= SHOW_SBITS(re, &s->gb, 12); LAST_SKIP_BITS(re, &s->gb, 12);
- }else{
- if(SHOW_UBITS(re, &s->gb, 1)==0){
- av_log(s->avctx, AV_LOG_ERROR, "1. marker bit missing in 3. esc\n");
- return -1;
- }; SKIP_CACHE(re, &s->gb, 1);
-
- level= SHOW_SBITS(re, &s->gb, 12); SKIP_CACHE(re, &s->gb, 12);
-
- 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;
- }
-
- SKIP_COUNTER(re, &s->gb, 1+12+1);
+ if (SHOW_UBITS(re, &s->gb, 1) == 0) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "2. marker bit missing in rvlc esc\n");
+ return -1;
}
+ SKIP_CACHE(re, &s->gb, 1);
+
+ level = SHOW_UBITS(re, &s->gb, 11);
+ SKIP_CACHE(re, &s->gb, 11);
+
+ if (SHOW_UBITS(re, &s->gb, 5) != 0x10) {
+ av_log(s->avctx, AV_LOG_ERROR, "reverse esc missing\n");
+ return -1;
+ }
+ SKIP_CACHE(re, &s->gb, 5);
+
+ level = level * qmul + qadd;
+ 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;
+ if (last)
+ i += 192;
+ } else {
+ int cache;
+ cache = GET_CACHE(re, &s->gb);
+
+ if (IS_3IV1)
+ cache ^= 0xC0000000;
+
+ if (cache & 0x80000000) {
+ if (cache & 0x40000000) {
+ /* 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);
+ SKIP_COUNTER(re, &s->gb, 2 + 1 + 6);
+ UPDATE_CACHE(re, &s->gb);
+
+ if (IS_3IV1) {
+ level = SHOW_SBITS(re, &s->gb, 12);
+ LAST_SKIP_BITS(re, &s->gb, 12);
+ } else {
+ if (SHOW_UBITS(re, &s->gb, 1) == 0) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "1. marker bit missing in 3. esc\n");
+ return -1;
+ }
+ SKIP_CACHE(re, &s->gb, 1);
+
+ level = SHOW_SBITS(re, &s->gb, 12);
+ SKIP_CACHE(re, &s->gb, 12);
+
+ 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;
+ }
+
+ 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;
+ 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 (level > 0)
+ level = level * qmul + qadd;
+ else
+ level = level * qmul - qadd;
- if((unsigned)(level + 2048) > 4095){
- if(s->err_recognition & (AV_EF_BITSTREAM|AV_EF_AGGRESSIVE)){
- if(level > 2560 || level<-2560){
- av_log(s->avctx, AV_LOG_ERROR, "|level| overflow in 3. esc, qp=%d\n", s->qscale);
- return -1;
+ if ((unsigned)(level + 2048) > 4095) {
+ if (s->err_recognition & (AV_EF_BITSTREAM|AV_EF_AGGRESSIVE)) {
+ if (level > 2560 || level < -2560) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "|level| overflow in 3. esc, qp=%d\n",
+ s->qscale);
+ return -1;
+ }
+ }
+ level = level < 0 ? -2048 : 2047;
}
- }
- level= level<0 ? -2048 : 2047;
- }
- i+= run + 1;
- if(last) i+=192;
- } else {
- /* second escape */
- SKIP_BITS(re, &s->gb, 2);
- GET_RL_VLC(level, run, re, &s->gb, rl_vlc, TEX_VLC_BITS, 2, 1);
- i+= run + rl->max_run[run>>7][level/qmul] +1; //FIXME opt indexing
- level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);
- LAST_SKIP_BITS(re, &s->gb, 1);
+ i += run + 1;
+ if (last)
+ i += 192;
+ } else {
+ /* second escape */
+ SKIP_BITS(re, &s->gb, 2);
+ GET_RL_VLC(level, run, re, &s->gb, rl_vlc, TEX_VLC_BITS, 2, 1);
+ i += run + rl->max_run[run >> 7][level / qmul] + 1; // FIXME opt indexing
+ level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);
+ LAST_SKIP_BITS(re, &s->gb, 1);
+ }
+ } else {
+ /* first escape */
+ SKIP_BITS(re, &s->gb, 1);
+ GET_RL_VLC(level, run, re, &s->gb, rl_vlc, TEX_VLC_BITS, 2, 1);
+ i += run;
+ level = level + rl->max_level[run >> 7][(run - 1) & 63] * qmul; // FIXME opt indexing
+ level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);
+ LAST_SKIP_BITS(re, &s->gb, 1);
+ }
}
} else {
- /* first escape */
- SKIP_BITS(re, &s->gb, 1);
- GET_RL_VLC(level, run, re, &s->gb, rl_vlc, TEX_VLC_BITS, 2, 1);
- i+= run;
- level = level + rl->max_level[run>>7][(run-1)&63] * qmul;//FIXME opt indexing
+ i += run;
level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);
LAST_SKIP_BITS(re, &s->gb, 1);
}
- }
- } else {
- i+= run;
- level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);
- LAST_SKIP_BITS(re, &s->gb, 1);
- }
- if (i > 62){
- i-= 192;
- 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;
+ if (i > 62) {
+ i -= 192;
+ 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[scan_table[i]] = level;
+ break;
}
block[scan_table[i]] = level;
- break;
}
-
- block[scan_table[i]] = level;
+ CLOSE_READER(re, &s->gb);
}
- CLOSE_READER(re, &s->gb);
- }
- not_coded:
+
+not_coded:
if (intra) {
- if(!s->use_intra_dc_vlc){
+ if (!ctx->use_intra_dc_vlc) {
block[0] = ff_mpeg4_pred_dc(s, n, block[0], &dc_pred_dir, 0);
- i -= i>>31; //if(i == -1) i=0;
+ i -= i >> 31; // if (i == -1) i = 0;
}
ff_mpeg4_pred_ac(s, block, n, dc_pred_dir);
- if (s->ac_pred) {
- i = 63; /* XXX: not optimal */
- }
+ if (s->ac_pred)
+ i = 63; // FIXME not optimal
}
s->block_last_index[n] = i;
return 0;
@@ -1103,21 +1201,22 @@
*/
static int mpeg4_decode_partitioned_mb(MpegEncContext *s, int16_t block[6][64])
{
+ Mpeg4DecContext *ctx = (Mpeg4DecContext *)s;
int cbp, mb_type;
- const int xy= s->mb_x + s->mb_y*s->mb_stride;
+ const int xy = s->mb_x + s->mb_y * s->mb_stride;
mb_type = s->current_picture.mb_type[xy];
- cbp = s->cbp_table[xy];
+ cbp = s->cbp_table[xy];
- s->use_intra_dc_vlc= s->qscale < s->intra_dc_threshold;
+ ctx->use_intra_dc_vlc = s->qscale < ctx->intra_dc_threshold;
- if (s->current_picture.qscale_table[xy] != s->qscale) {
+ if (s->current_picture.qscale_table[xy] != s->qscale)
ff_set_qscale(s, s->current_picture.qscale_table[xy]);
- }
- if (s->pict_type == AV_PICTURE_TYPE_P || s->pict_type==AV_PICTURE_TYPE_S) {
+ if (s->pict_type == AV_PICTURE_TYPE_P ||
+ s->pict_type == AV_PICTURE_TYPE_S) {
int i;
- for(i=0; i<4; 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];
}
@@ -1125,21 +1224,22 @@
if (IS_SKIP(mb_type)) {
/* skip mb */
- for(i=0;i<6;i++)
+ for (i = 0; i < 6; i++)
s->block_last_index[i] = -1;
- s->mv_dir = MV_DIR_FORWARD;
+ 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->mcsel=1;
+ if (s->pict_type == AV_PICTURE_TYPE_S
+ && ctx->vol_sprite_usage == GMC_SPRITE) {
+ s->mcsel = 1;
s->mb_skipped = 0;
- }else{
- s->mcsel=0;
+ } else {
+ s->mcsel = 0;
s->mb_skipped = 1;
}
- }else if(s->mb_intra){
+ } else if (s->mb_intra) {
s->ac_pred = IS_ACPRED(s->current_picture.mb_type[xy]);
- }else if(!s->mb_intra){
-// s->mcsel= 0; //FIXME do we need to init that
+ } else if (!s->mb_intra) {
+ // s->mcsel = 0; // FIXME do we need to init that?
s->mv_dir = MV_DIR_FORWARD;
if (IS_8X8(mb_type)) {
@@ -1150,7 +1250,7 @@
}
} 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.mb_type[xy]);
}
if (!IS_SKIP(mb_type)) {
@@ -1158,123 +1258,138 @@
s->dsp.clear_blocks(s->block[0]);
/* decode each block */
for (i = 0; i < 6; i++) {
- if(mpeg4_decode_block(s, block[i], i, cbp&32, s->mb_intra, s->rvlc) < 0){
- av_log(s->avctx, AV_LOG_ERROR, "texture corrupted at %d %d %d\n", s->mb_x, s->mb_y, s->mb_intra);
+ if (mpeg4_decode_block(ctx, block[i], i, cbp & 32, s->mb_intra, ctx->rvlc) < 0) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "texture corrupted at %d %d %d\n",
+ s->mb_x, s->mb_y, s->mb_intra);
return -1;
}
- cbp+=cbp;
+ cbp += cbp;
}
}
/* per-MB end of slice check */
-
- if(--s->mb_num_left <= 0){
- if(mpeg4_is_resync(s))
+ if (--s->mb_num_left <= 0) {
+ if (mpeg4_is_resync(ctx))
return SLICE_END;
else
return SLICE_NOEND;
- }else{
- if(mpeg4_is_resync(s)){
- const int delta= s->mb_x + 1 == s->mb_width ? 2 : 1;
- if(s->cbp_table[xy+delta])
+ } else {
+ if (mpeg4_is_resync(ctx)) {
+ const int delta = s->mb_x + 1 == s->mb_width ? 2 : 1;
+ if (s->cbp_table[xy + delta])
return SLICE_END;
}
return SLICE_OK;
}
}
-static int mpeg4_decode_mb(MpegEncContext *s,
- int16_t block[6][64])
+static int mpeg4_decode_mb(MpegEncContext *s, int16_t block[6][64])
{
+ Mpeg4DecContext *ctx = (Mpeg4DecContext *)s;
int cbpc, cbpy, i, cbp, pred_x, pred_y, mx, my, dquant;
int16_t *mot_val;
static int8_t quant_tab[4] = { -1, -2, 1, 2 };
- const int xy= s->mb_x + s->mb_y * s->mb_stride;
+ const int xy = s->mb_x + s->mb_y * s->mb_stride;
av_assert2(s->h263_pred);
- if (s->pict_type == AV_PICTURE_TYPE_P || s->pict_type==AV_PICTURE_TYPE_S) {
- do{
+ if (s->pict_type == AV_PICTURE_TYPE_P ||
+ s->pict_type == AV_PICTURE_TYPE_S) {
+ do {
if (get_bits1(&s->gb)) {
/* skip mb */
s->mb_intra = 0;
- for(i=0;i<6;i++)
+ for (i = 0; i < 6; i++)
s->block_last_index[i] = -1;
- s->mv_dir = MV_DIR_FORWARD;
+ 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->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->mcsel=0;
+ if (s->pict_type == AV_PICTURE_TYPE_S &&
+ ctx->vol_sprite_usage == GMC_SPRITE) {
+ s->current_picture.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(ctx, 0);
+ s->mv[0][0][1] = get_amv(ctx, 1);
+ s->mb_skipped = 0;
+ } else {
+ s->current_picture.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;
- s->mb_skipped = 1;
+ s->mb_skipped = 1;
}
goto end;
}
cbpc = get_vlc2(&s->gb, ff_h263_inter_MCBPC_vlc.table, INTER_MCBPC_VLC_BITS, 2);
- if (cbpc < 0){
- av_log(s->avctx, AV_LOG_ERROR, "cbpc damaged at %d %d\n", s->mb_x, s->mb_y);
+ if (cbpc < 0) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "cbpc damaged at %d %d\n", s->mb_x, s->mb_y);
return -1;
}
- }while(cbpc == 20);
+ } while (cbpc == 20);
s->dsp.clear_blocks(s->block[0]);
- dquant = cbpc & 8;
+ dquant = cbpc & 8;
s->mb_intra = ((cbpc & 4) != 0);
- if (s->mb_intra) goto intra;
+ if (s->mb_intra)
+ goto intra;
- if(s->pict_type==AV_PICTURE_TYPE_S && s->vol_sprite_usage==GMC_SPRITE && (cbpc & 16) == 0)
- s->mcsel= get_bits1(&s->gb);
- else s->mcsel= 0;
+ if (s->pict_type == AV_PICTURE_TYPE_S &&
+ ctx->vol_sprite_usage == GMC_SPRITE && (cbpc & 16) == 0)
+ s->mcsel = get_bits1(&s->gb);
+ else
+ s->mcsel = 0;
cbpy = get_vlc2(&s->gb, ff_h263_cbpy_vlc.table, CBPY_VLC_BITS, 1) ^ 0x0F;
cbp = (cbpc & 3) | (cbpy << 2);
- if (dquant) {
+ if (dquant)
ff_set_qscale(s, s->qscale + quant_tab[get_bits(&s->gb, 2)]);
- }
- if((!s->progressive_sequence) && (cbp || (s->workaround_bugs&FF_BUG_XVID_ILACE)))
- s->interlaced_dct= get_bits1(&s->gb);
+ if ((!s->progressive_sequence) &&
+ (cbp || (s->workaround_bugs & FF_BUG_XVID_ILACE)))
+ s->interlaced_dct = get_bits1(&s->gb);
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;
+ if (s->mcsel) {
+ s->current_picture.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);
- my= get_amv(s, 1);
+ s->mv_type = MV_TYPE_16X16;
+ mx = get_amv(ctx, 0);
+ my = get_amv(ctx, 1);
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;
+ } else if ((!s->progressive_sequence) && get_bits1(&s->gb)) {
+ s->current_picture.mb_type[xy] = MB_TYPE_16x8 |
+ MB_TYPE_L0 |
+ MB_TYPE_INTERLACED;
/* 16x8 field motion prediction */
- s->mv_type= MV_TYPE_FIELD;
+ s->mv_type = MV_TYPE_FIELD;
- s->field_select[0][0]= get_bits1(&s->gb);
- s->field_select[0][1]= get_bits1(&s->gb);
+ s->field_select[0][0] = get_bits1(&s->gb);
+ s->field_select[0][1] = get_bits1(&s->gb);
ff_h263_pred_motion(s, 0, 0, &pred_x, &pred_y);
- for(i=0; i<2; i++){
+ for (i = 0; i < 2; i++) {
mx = ff_h263_decode_motion(s, pred_x, s->f_code);
if (mx >= 0xffff)
return -1;
- my = ff_h263_decode_motion(s, pred_y/2, s->f_code);
+ my = ff_h263_decode_motion(s, pred_y / 2, s->f_code);
if (my >= 0xffff)
return -1;
s->mv[0][i][0] = mx;
s->mv[0][i][1] = my;
}
- }else{
+ } else {
s->current_picture.mb_type[xy] = MB_TYPE_16x16 | MB_TYPE_L0;
/* 16x16 motion prediction */
s->mv_type = MV_TYPE_16X16;
@@ -1293,10 +1408,10 @@
}
} else {
s->current_picture.mb_type[xy] = MB_TYPE_8x8 | MB_TYPE_L0;
- s->mv_type = MV_TYPE_8X8;
- for(i=0;i<4;i++) {
+ s->mv_type = MV_TYPE_8X8;
+ for (i = 0; i < 4; i++) {
mot_val = ff_h263_pred_motion(s, i, 0, &pred_x, &pred_y);
- mx = ff_h263_decode_motion(s, pred_x, s->f_code);
+ mx = ff_h263_decode_motion(s, pred_x, s->f_code);
if (mx >= 0xffff)
return -1;
@@ -1305,215 +1420,233 @@
return -1;
s->mv[0][i][0] = mx;
s->mv[0][i][1] = my;
- mot_val[0] = mx;
- mot_val[1] = my;
+ mot_val[0] = mx;
+ mot_val[1] = my;
}
}
- } else if(s->pict_type==AV_PICTURE_TYPE_B) {
- int modb1; // first bit of modb
- int modb2; // second bit of modb
+ } else if (s->pict_type == AV_PICTURE_TYPE_B) {
+ int modb1; // first bit of modb
+ int modb2; // second bit of modb
int mb_type;
- s->mb_intra = 0; //B-frames never contain intra blocks
- s->mcsel=0; // ... true gmc blocks
+ s->mb_intra = 0; // B-frames never contain intra blocks
+ s->mcsel = 0; // ... true gmc blocks
- if(s->mb_x==0){
- for(i=0; i<2; i++){
- s->last_mv[i][0][0]=
- s->last_mv[i][0][1]=
- s->last_mv[i][1][0]=
- s->last_mv[i][1][1]= 0;
+ if (s->mb_x == 0) {
+ for (i = 0; i < 2; i++) {
+ s->last_mv[i][0][0] =
+ s->last_mv[i][0][1] =
+ s->last_mv[i][1][0] =
+ s->last_mv[i][1][1] = 0;
}
ff_thread_await_progress(&s->next_picture_ptr->tf, s->mb_y, 0);
}
/* 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.mbskip_table[s->mb_y * s->mb_stride + s->mb_x]; // Note, skiptab=0 if last was GMC
- if(s->mb_skipped){
- /* skip mb */
- for(i=0;i<6;i++)
+ if (s->mb_skipped) {
+ /* skip mb */
+ for (i = 0; i < 6; i++)
s->block_last_index[i] = -1;
- s->mv_dir = MV_DIR_FORWARD;
- s->mv_type = MV_TYPE_16X16;
- s->mv[0][0][0] = 0;
- s->mv[0][0][1] = 0;
- s->mv[1][0][0] = 0;
+ s->mv_dir = MV_DIR_FORWARD;
+ s->mv_type = MV_TYPE_16X16;
+ s->mv[0][0][0] =
+ s->mv[0][0][1] =
+ s->mv[1][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.mb_type[xy] = MB_TYPE_SKIP |
+ MB_TYPE_16x16 |
+ MB_TYPE_L0;
goto end;
}
- modb1= get_bits1(&s->gb);
- if(modb1){
- mb_type= MB_TYPE_DIRECT2 | MB_TYPE_SKIP | MB_TYPE_L0L1; //like MB_TYPE_B_DIRECT but no vectors coded
- cbp=0;
- }else{
- modb2= get_bits1(&s->gb);
- mb_type= get_vlc2(&s->gb, mb_type_b_vlc.table, MB_TYPE_B_VLC_BITS, 1);
- if(mb_type<0){
+ modb1 = get_bits1(&s->gb);
+ if (modb1) {
+ // like MB_TYPE_B_DIRECT but no vectors coded
+ mb_type = MB_TYPE_DIRECT2 | MB_TYPE_SKIP | MB_TYPE_L0L1;
+ cbp = 0;
+ } else {
+ modb2 = get_bits1(&s->gb);
+ mb_type = get_vlc2(&s->gb, mb_type_b_vlc.table, MB_TYPE_B_VLC_BITS, 1);
+ if (mb_type < 0) {
av_log(s->avctx, AV_LOG_ERROR, "illegal MB_type\n");
return -1;
}
- mb_type= mb_type_b_map[ mb_type ];
- if(modb2) cbp= 0;
- else{
+ mb_type = mb_type_b_map[mb_type];
+ if (modb2) {
+ cbp = 0;
+ } else {
s->dsp.clear_blocks(s->block[0]);
- cbp= get_bits(&s->gb, 6);
+ cbp = get_bits(&s->gb, 6);
}
if ((!IS_DIRECT(mb_type)) && cbp) {
- if(get_bits1(&s->gb)){
- ff_set_qscale(s, s->qscale + get_bits1(&s->gb)*4 - 2);
- }
+ if (get_bits1(&s->gb))
+ ff_set_qscale(s, s->qscale + get_bits1(&s->gb) * 4 - 2);
}
- if(!s->progressive_sequence){
- if(cbp)
- s->interlaced_dct= get_bits1(&s->gb);
+ if (!s->progressive_sequence) {
+ if (cbp)
+ s->interlaced_dct = get_bits1(&s->gb);
- if(!IS_DIRECT(mb_type) && get_bits1(&s->gb)){
+ if (!IS_DIRECT(mb_type) && get_bits1(&s->gb)) {
mb_type |= MB_TYPE_16x8 | MB_TYPE_INTERLACED;
mb_type &= ~MB_TYPE_16x16;
- if(USES_LIST(mb_type, 0)){
- s->field_select[0][0]= get_bits1(&s->gb);
- s->field_select[0][1]= get_bits1(&s->gb);
+ if (USES_LIST(mb_type, 0)) {
+ s->field_select[0][0] = get_bits1(&s->gb);
+ s->field_select[0][1] = get_bits1(&s->gb);
}
- if(USES_LIST(mb_type, 1)){
- s->field_select[1][0]= get_bits1(&s->gb);
- s->field_select[1][1]= get_bits1(&s->gb);
+ if (USES_LIST(mb_type, 1)) {
+ s->field_select[1][0] = get_bits1(&s->gb);
+ s->field_select[1][1] = get_bits1(&s->gb);
}
}
}
s->mv_dir = 0;
- if((mb_type & (MB_TYPE_DIRECT2|MB_TYPE_INTERLACED)) == 0){
- s->mv_type= MV_TYPE_16X16;
+ if ((mb_type & (MB_TYPE_DIRECT2 | MB_TYPE_INTERLACED)) == 0) {
+ s->mv_type = MV_TYPE_16X16;
- if(USES_LIST(mb_type, 0)){
+ if (USES_LIST(mb_type, 0)) {
s->mv_dir = MV_DIR_FORWARD;
mx = ff_h263_decode_motion(s, s->last_mv[0][0][0], s->f_code);
my = ff_h263_decode_motion(s, s->last_mv[0][0][1], s->f_code);
- s->last_mv[0][1][0]= s->last_mv[0][0][0]= s->mv[0][0][0] = mx;
- s->last_mv[0][1][1]= s->last_mv[0][0][1]= s->mv[0][0][1] = my;
+ s->last_mv[0][1][0] =
+ s->last_mv[0][0][0] =
+ s->mv[0][0][0] = mx;
+ s->last_mv[0][1][1] =
+ s->last_mv[0][0][1] =
+ s->mv[0][0][1] = my;
}
- if(USES_LIST(mb_type, 1)){
+ if (USES_LIST(mb_type, 1)) {
s->mv_dir |= MV_DIR_BACKWARD;
mx = ff_h263_decode_motion(s, s->last_mv[1][0][0], s->b_code);
my = ff_h263_decode_motion(s, s->last_mv[1][0][1], s->b_code);
- s->last_mv[1][1][0]= s->last_mv[1][0][0]= s->mv[1][0][0] = mx;
- s->last_mv[1][1][1]= s->last_mv[1][0][1]= s->mv[1][0][1] = my;
+ s->last_mv[1][1][0] =
+ s->last_mv[1][0][0] =
+ s->mv[1][0][0] = mx;
+ s->last_mv[1][1][1] =
+ s->last_mv[1][0][1] =
+ s->mv[1][0][1] = my;
}
- }else if(!IS_DIRECT(mb_type)){
- s->mv_type= MV_TYPE_FIELD;
+ } else if (!IS_DIRECT(mb_type)) {
+ s->mv_type = MV_TYPE_FIELD;
- if(USES_LIST(mb_type, 0)){
+ if (USES_LIST(mb_type, 0)) {
s->mv_dir = MV_DIR_FORWARD;
- for(i=0; i<2; i++){
- mx = ff_h263_decode_motion(s, s->last_mv[0][i][0] , s->f_code);
- my = ff_h263_decode_motion(s, s->last_mv[0][i][1]/2, s->f_code);
- s->last_mv[0][i][0]= s->mv[0][i][0] = mx;
- s->last_mv[0][i][1]= (s->mv[0][i][1] = my)*2;
+ for (i = 0; i < 2; i++) {
+ mx = ff_h263_decode_motion(s, s->last_mv[0][i][0], s->f_code);
+ my = ff_h263_decode_motion(s, s->last_mv[0][i][1] / 2, s->f_code);
+ s->last_mv[0][i][0] =
+ s->mv[0][i][0] = mx;
+ s->last_mv[0][i][1] = (s->mv[0][i][1] = my) * 2;
}
}
- if(USES_LIST(mb_type, 1)){
+ if (USES_LIST(mb_type, 1)) {
s->mv_dir |= MV_DIR_BACKWARD;
- for(i=0; i<2; i++){
- mx = ff_h263_decode_motion(s, s->last_mv[1][i][0] , s->b_code);
- my = ff_h263_decode_motion(s, s->last_mv[1][i][1]/2, s->b_code);
- s->last_mv[1][i][0]= s->mv[1][i][0] = mx;
- s->last_mv[1][i][1]= (s->mv[1][i][1] = my)*2;
+ for (i = 0; i < 2; i++) {
+ mx = ff_h263_decode_motion(s, s->last_mv[1][i][0], s->b_code);
+ my = ff_h263_decode_motion(s, s->last_mv[1][i][1] / 2, s->b_code);
+ s->last_mv[1][i][0] =
+ s->mv[1][i][0] = mx;
+ s->last_mv[1][i][1] = (s->mv[1][i][1] = my) * 2;
}
}
}
}
- if(IS_DIRECT(mb_type)){
- if(IS_SKIP(mb_type))
- mx=my=0;
- else{
+ if (IS_DIRECT(mb_type)) {
+ if (IS_SKIP(mb_type)) {
+ mx =
+ my = 0;
+ } else {
mx = ff_h263_decode_motion(s, 0, 1);
my = ff_h263_decode_motion(s, 0, 1);
}
s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD | MV_DIRECT;
- mb_type |= ff_mpeg4_set_direct_mv(s, mx, my);
+ mb_type |= ff_mpeg4_set_direct_mv(s, mx, my);
}
s->current_picture.mb_type[xy] = mb_type;
} else { /* I-Frame */
- do{
+ do {
cbpc = get_vlc2(&s->gb, ff_h263_intra_MCBPC_vlc.table, INTRA_MCBPC_VLC_BITS, 2);
- if (cbpc < 0){
- av_log(s->avctx, AV_LOG_ERROR, "I cbpc damaged at %d %d\n", s->mb_x, s->mb_y);
+ if (cbpc < 0) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "I cbpc damaged at %d %d\n", s->mb_x, s->mb_y);
return -1;
}
- }while(cbpc == 8);
+ } while (cbpc == 8);
dquant = cbpc & 4;
s->mb_intra = 1;
+
intra:
s->ac_pred = get_bits1(&s->gb);
- if(s->ac_pred)
+ if (s->ac_pred)
s->current_picture.mb_type[xy] = MB_TYPE_INTRA | MB_TYPE_ACPRED;
else
s->current_picture.mb_type[xy] = MB_TYPE_INTRA;
cbpy = get_vlc2(&s->gb, ff_h263_cbpy_vlc.table, CBPY_VLC_BITS, 1);
- if(cbpy<0){
- av_log(s->avctx, AV_LOG_ERROR, "I cbpy damaged at %d %d\n", s->mb_x, s->mb_y);
+ if (cbpy < 0) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "I cbpy damaged at %d %d\n", s->mb_x, s->mb_y);
return -1;
}
cbp = (cbpc & 3) | (cbpy << 2);
- s->use_intra_dc_vlc= s->qscale < s->intra_dc_threshold;
+ ctx->use_intra_dc_vlc = s->qscale < ctx->intra_dc_threshold;
- if (dquant) {
+ if (dquant)
ff_set_qscale(s, s->qscale + quant_tab[get_bits(&s->gb, 2)]);
- }
- if(!s->progressive_sequence)
- s->interlaced_dct= get_bits1(&s->gb);
+ if (!s->progressive_sequence)
+ s->interlaced_dct = get_bits1(&s->gb);
s->dsp.clear_blocks(s->block[0]);
/* decode each block */
for (i = 0; i < 6; i++) {
- if (mpeg4_decode_block(s, block[i], i, cbp&32, 1, 0) < 0)
+ if (mpeg4_decode_block(ctx, block[i], i, cbp & 32, 1, 0) < 0)
return -1;
- cbp+=cbp;
+ cbp += cbp;
}
goto end;
}
/* decode each block */
for (i = 0; i < 6; i++) {
- if (mpeg4_decode_block(s, block[i], i, cbp&32, 0, 0) < 0)
+ if (mpeg4_decode_block(ctx, block[i], i, cbp & 32, 0, 0) < 0)
return -1;
- cbp+=cbp;
+ cbp += cbp;
}
-end:
- /* per-MB end of slice check */
- if(s->codec_id==AV_CODEC_ID_MPEG4){
- int next= mpeg4_is_resync(s);
- if(next) {
+end:
+ /* per-MB end of slice check */
+ if (s->codec_id == AV_CODEC_ID_MPEG4) {
+ int next = mpeg4_is_resync(ctx);
+ if (next) {
if (s->mb_x + s->mb_y*s->mb_width + 1 > next && (s->avctx->err_recognition & AV_EF_AGGRESSIVE)) {
return -1;
} else if (s->mb_x + s->mb_y*s->mb_width + 1 >= next)
return SLICE_END;
- if(s->pict_type==AV_PICTURE_TYPE_B){
+ if (s->pict_type == AV_PICTURE_TYPE_B) {
const int delta= s->mb_x + 1 == s->mb_width ? 2 : 1;
ff_thread_await_progress(&s->next_picture_ptr->tf,
- (s->mb_x + delta >= s->mb_width) ? FFMIN(s->mb_y+1, s->mb_height-1) : s->mb_y, 0);
+ (s->mb_x + delta >= s->mb_width)
+ ? FFMIN(s->mb_y + 1, s->mb_height - 1)
+ : s->mb_y, 0);
if (s->next_picture.mbskip_table[xy + delta])
return SLICE_OK;
}
@@ -1525,21 +1658,21 @@
return SLICE_OK;
}
-
-static int mpeg4_decode_gop_header(MpegEncContext * s, GetBitContext *gb){
+static int mpeg4_decode_gop_header(MpegEncContext *s, GetBitContext *gb)
+{
int hours, minutes, seconds;
- if(!show_bits(gb, 23)){
+ if (!show_bits(gb, 23)) {
av_log(s->avctx, AV_LOG_WARNING, "GOP header invalid\n");
return -1;
}
- hours= get_bits(gb, 5);
- minutes= get_bits(gb, 6);
+ hours = get_bits(gb, 5);
+ minutes = get_bits(gb, 6);
skip_bits1(gb);
- seconds= get_bits(gb, 6);
+ seconds = get_bits(gb, 6);
- s->time_base= seconds + 60*(minutes + 60*hours);
+ s->time_base = seconds + 60*(minutes + 60*hours);
skip_bits1(gb);
skip_bits1(gb);
@@ -1547,7 +1680,8 @@
return 0;
}
-static int mpeg4_decode_profile_level(MpegEncContext * s, GetBitContext *gb){
+static int mpeg4_decode_profile_level(MpegEncContext *s, GetBitContext *gb)
+{
s->avctx->profile = get_bits(gb, 4);
s->avctx->level = get_bits(gb, 4);
@@ -1560,33 +1694,35 @@
return 0;
}
-static int decode_vol_header(MpegEncContext *s, GetBitContext *gb){
+static int decode_vol_header(Mpeg4DecContext *ctx, GetBitContext *gb)
+{
+ MpegEncContext *s = &ctx->m;
int width, height, vo_ver_id;
/* vol header */
- skip_bits(gb, 1); /* random access */
- s->vo_type= get_bits(gb, 8);
- if (get_bits1(gb) != 0) { /* is_ol_id */
- vo_ver_id = get_bits(gb, 4); /* vo_ver_id */
- skip_bits(gb, 3); /* vo_priority */
+ skip_bits(gb, 1); /* random access */
+ s->vo_type = get_bits(gb, 8);
+ if (get_bits1(gb) != 0) { /* is_ol_id */
+ vo_ver_id = get_bits(gb, 4); /* vo_ver_id */
+ skip_bits(gb, 3); /* vo_priority */
} else {
vo_ver_id = 1;
}
- s->aspect_ratio_info= get_bits(gb, 4);
- if(s->aspect_ratio_info == FF_ASPECT_EXTENDED){
- s->avctx->sample_aspect_ratio.num= get_bits(gb, 8); // par_width
- s->avctx->sample_aspect_ratio.den= get_bits(gb, 8); // par_height
- }else{
- s->avctx->sample_aspect_ratio= ff_h263_pixel_aspect[s->aspect_ratio_info];
+ s->aspect_ratio_info = get_bits(gb, 4);
+ if (s->aspect_ratio_info == FF_ASPECT_EXTENDED) {
+ s->avctx->sample_aspect_ratio.num = get_bits(gb, 8); // par_width
+ s->avctx->sample_aspect_ratio.den = get_bits(gb, 8); // par_height
+ } else {
+ s->avctx->sample_aspect_ratio = ff_h263_pixel_aspect[s->aspect_ratio_info];
}
- if ((s->vol_control_parameters=get_bits1(gb))) { /* vol control parameter */
- int chroma_format= get_bits(gb, 2);
- if(chroma_format!=CHROMA_420){
+ if ((s->vol_control_parameters = get_bits1(gb))) { /* vol control parameter */
+ int chroma_format = get_bits(gb, 2);
+ if (chroma_format != CHROMA_420)
av_log(s->avctx, AV_LOG_ERROR, "illegal chroma format\n");
- }
- s->low_delay= get_bits1(gb);
- if(get_bits1(gb)){ /* vbv parameters */
+
+ s->low_delay = get_bits1(gb);
+ if (get_bits1(gb)) { /* vbv parameters */
get_bits(gb, 15); /* first_half_bitrate */
skip_bits1(gb); /* marker */
get_bits(gb, 15); /* latter_half_bitrate */
@@ -1599,97 +1735,108 @@
get_bits(gb, 15); /* latter_half_vbv_occupancy */
skip_bits1(gb); /* marker */
}
- }else{
- // set low delay flag only once the smartest? low delay detection won't be overridden
- if(s->picture_number==0)
- s->low_delay=0;
+ } else {
+ /* is setting low delay flag only once the smartest thing to do?
+ * low delay detection won't be overriden. */
+ if (s->picture_number == 0)
+ s->low_delay = 0;
}
- s->shape = get_bits(gb, 2); /* vol shape */
- if(s->shape != RECT_SHAPE) av_log(s->avctx, AV_LOG_ERROR, "only rectangular vol supported\n");
- if(s->shape == GRAY_SHAPE && vo_ver_id != 1){
+ ctx->shape = get_bits(gb, 2); /* vol shape */
+ if (ctx->shape != RECT_SHAPE)
+ av_log(s->avctx, AV_LOG_ERROR, "only rectangular vol supported\n");
+ if (ctx->shape == GRAY_SHAPE && vo_ver_id != 1) {
av_log(s->avctx, AV_LOG_ERROR, "Gray shape not supported\n");
- skip_bits(gb, 4); //video_object_layer_shape_extension
+ skip_bits(gb, 4); /* video_object_layer_shape_extension */
}
check_marker(gb, "before time_increment_resolution");
s->avctx->time_base.den = get_bits(gb, 16);
- if(!s->avctx->time_base.den){
+ if (!s->avctx->time_base.den) {
av_log(s->avctx, AV_LOG_ERROR, "time_base.den==0\n");
s->avctx->time_base.num = 0;
return -1;
}
- s->time_increment_bits = av_log2(s->avctx->time_base.den - 1) + 1;
- if (s->time_increment_bits < 1)
- s->time_increment_bits = 1;
+ ctx->time_increment_bits = av_log2(s->avctx->time_base.den - 1) + 1;
+ if (ctx->time_increment_bits < 1)
+ ctx->time_increment_bits = 1;
check_marker(gb, "before fixed_vop_rate");
- if (get_bits1(gb) != 0) { /* fixed_vop_rate */
- s->avctx->time_base.num = get_bits(gb, s->time_increment_bits);
- }else
+ if (get_bits1(gb) != 0) /* fixed_vop_rate */
+ s->avctx->time_base.num = get_bits(gb, ctx->time_increment_bits);
+ else
s->avctx->time_base.num = 1;
- s->t_frame=0;
+ ctx->t_frame = 0;
- if (s->shape != BIN_ONLY_SHAPE) {
- if (s->shape == RECT_SHAPE) {
+ if (ctx->shape != BIN_ONLY_SHAPE) {
+ if (ctx->shape == RECT_SHAPE) {
check_marker(gb, "before width");
width = get_bits(gb, 13);
check_marker(gb, "before height");
height = get_bits(gb, 13);
check_marker(gb, "after height");
- if(width && height && !(s->width && s->codec_tag == AV_RL32("MP4S"))){ /* they should be non zero but who knows ... */
+ if (width && height && /* they should be non zero but who knows */
+ !(s->width && s->codec_tag == AV_RL32("MP4S"))) {
if (s->width && s->height &&
(s->width != width || s->height != height))
s->context_reinit = 1;
- s->width = width;
+ s->width = width;
s->height = height;
}
}
- s->progressive_sequence=
- s->progressive_frame= get_bits1(gb)^1;
- s->interlaced_dct=0;
- if(!get_bits1(gb) && (s->avctx->debug & FF_DEBUG_PICT_INFO))
- av_log(s->avctx, AV_LOG_INFO, "MPEG4 OBMC not supported (very likely buggy encoder)\n"); /* OBMC Disable */
- if (vo_ver_id == 1) {
- s->vol_sprite_usage = get_bits1(gb); /* vol_sprite_usage */
- } else {
- s->vol_sprite_usage = get_bits(gb, 2); /* vol_sprite_usage */
- }
- if(s->vol_sprite_usage==STATIC_SPRITE) av_log(s->avctx, AV_LOG_ERROR, "Static Sprites not supported\n");
- if(s->vol_sprite_usage==STATIC_SPRITE || s->vol_sprite_usage==GMC_SPRITE){
- if(s->vol_sprite_usage==STATIC_SPRITE){
- s->sprite_width = get_bits(gb, 13);
+ s->progressive_sequence =
+ s->progressive_frame = get_bits1(gb) ^ 1;
+ s->interlaced_dct = 0;
+ if (!get_bits1(gb) && (s->avctx->debug & FF_DEBUG_PICT_INFO))
+ av_log(s->avctx, AV_LOG_INFO, /* OBMC Disable */
+ "MPEG4 OBMC not supported (very likely buggy encoder)\n");
+ if (vo_ver_id == 1)
+ ctx->vol_sprite_usage = get_bits1(gb); /* vol_sprite_usage */
+ else
+ ctx->vol_sprite_usage = get_bits(gb, 2); /* vol_sprite_usage */
+
+ if (ctx->vol_sprite_usage == STATIC_SPRITE)
+ av_log(s->avctx, AV_LOG_ERROR, "Static Sprites not supported\n");
+ if (ctx->vol_sprite_usage == STATIC_SPRITE ||
+ ctx->vol_sprite_usage == GMC_SPRITE) {
+ if (ctx->vol_sprite_usage == STATIC_SPRITE) {
+ skip_bits(gb, 13); // sprite_width
skip_bits1(gb); /* marker */
- s->sprite_height= get_bits(gb, 13);
+ skip_bits(gb, 13); // sprite_height
skip_bits1(gb); /* marker */
- s->sprite_left = get_bits(gb, 13);
+ skip_bits(gb, 13); // sprite_left
skip_bits1(gb); /* marker */
- s->sprite_top = get_bits(gb, 13);
+ skip_bits(gb, 13); // sprite_top
skip_bits1(gb); /* marker */
}
- s->num_sprite_warping_points= get_bits(gb, 6);
- if(s->num_sprite_warping_points > 3){
- av_log(s->avctx, AV_LOG_ERROR, "%d sprite_warping_points\n", s->num_sprite_warping_points);
- s->num_sprite_warping_points= 0;
+ ctx->num_sprite_warping_points = get_bits(gb, 6);
+ if (ctx->num_sprite_warping_points > 3) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "%d sprite_warping_points\n",
+ ctx->num_sprite_warping_points);
+ ctx->num_sprite_warping_points = 0;
return -1;
}
- s->sprite_warping_accuracy = get_bits(gb, 2);
- s->sprite_brightness_change= get_bits1(gb);
- if(s->vol_sprite_usage==STATIC_SPRITE)
- s->low_latency_sprite= get_bits1(gb);
+ s->sprite_warping_accuracy = get_bits(gb, 2);
+ ctx->sprite_brightness_change = get_bits1(gb);
+ if (ctx->vol_sprite_usage == STATIC_SPRITE)
+ skip_bits1(gb); // low_latency_sprite
}
// FIXME sadct disable bit if verid!=1 && shape not rect
- if (get_bits1(gb) == 1) { /* not_8_bit */
- s->quant_precision = get_bits(gb, 4); /* quant_precision */
- if(get_bits(gb, 4)!=8) av_log(s->avctx, AV_LOG_ERROR, "N-bit not supported\n"); /* bits_per_pixel */
- if(s->quant_precision!=5) av_log(s->avctx, AV_LOG_ERROR, "quant precision %d\n", s->quant_precision);
- if(s->quant_precision<3 || s->quant_precision>9) {
+ if (get_bits1(gb) == 1) { /* not_8_bit */
+ s->quant_precision = get_bits(gb, 4); /* quant_precision */
+ if (get_bits(gb, 4) != 8) /* bits_per_pixel */
+ av_log(s->avctx, AV_LOG_ERROR, "N-bit not supported\n");
+ if (s->quant_precision != 5)
+ av_log(s->avctx, AV_LOG_ERROR,
+ "quant precision %d\n", s->quant_precision);
+ if (s->quant_precision<3 || s->quant_precision>9) {
s->quant_precision = 5;
}
} else {
@@ -1698,186 +1845,190 @@
// FIXME a bunch of grayscale shape things
- if((s->mpeg_quant=get_bits1(gb))){ /* vol_quant_type */
+ if ((s->mpeg_quant = get_bits1(gb))) { /* vol_quant_type */
int i, v;
/* load default matrixes */
- for(i=0; i<64; i++){
- int j= s->dsp.idct_permutation[i];
- v= ff_mpeg4_default_intra_matrix[i];
- s->intra_matrix[j]= v;
- s->chroma_intra_matrix[j]= v;
+ for (i = 0; i < 64; i++) {
+ int j = s->dsp.idct_permutation[i];
+ v = ff_mpeg4_default_intra_matrix[i];
+ s->intra_matrix[j] = v;
+ s->chroma_intra_matrix[j] = v;
- v= ff_mpeg4_default_non_intra_matrix[i];
- s->inter_matrix[j]= v;
- s->chroma_inter_matrix[j]= v;
+ v = ff_mpeg4_default_non_intra_matrix[i];
+ s->inter_matrix[j] = v;
+ s->chroma_inter_matrix[j] = v;
}
/* load custom intra matrix */
- if(get_bits1(gb)){
- int last=0;
- for(i=0; i<64; i++){
+ if (get_bits1(gb)) {
+ int last = 0;
+ for (i = 0; i < 64; i++) {
int j;
- v= get_bits(gb, 8);
- if(v==0) break;
+ v = get_bits(gb, 8);
+ if (v == 0)
+ break;
- last= v;
- j= s->dsp.idct_permutation[ ff_zigzag_direct[i] ];
- s->intra_matrix[j]= v;
- s->chroma_intra_matrix[j]= v;
+ last = v;
+ j = s->dsp.idct_permutation[ff_zigzag_direct[i]];
+ s->intra_matrix[j] = last;
+ s->chroma_intra_matrix[j] = last;
}
/* replicate last value */
- for(; i<64; i++){
- int j= s->dsp.idct_permutation[ ff_zigzag_direct[i] ];
- s->intra_matrix[j]= last;
- s->chroma_intra_matrix[j]= last;
+ for (; i < 64; i++) {
+ int j = s->dsp.idct_permutation[ff_zigzag_direct[i]];
+ s->intra_matrix[j] = last;
+ s->chroma_intra_matrix[j] = last;
}
}
/* load custom non intra matrix */
- if(get_bits1(gb)){
- int last=0;
- for(i=0; i<64; i++){
+ if (get_bits1(gb)) {
+ int last = 0;
+ for (i = 0; i < 64; i++) {
int j;
- v= get_bits(gb, 8);
- if(v==0) break;
+ v = get_bits(gb, 8);
+ if (v == 0)
+ break;
- last= v;
- j= s->dsp.idct_permutation[ ff_zigzag_direct[i] ];
- s->inter_matrix[j]= v;
- s->chroma_inter_matrix[j]= v;
+ last = v;
+ j = s->dsp.idct_permutation[ff_zigzag_direct[i]];
+ s->inter_matrix[j] = v;
+ s->chroma_inter_matrix[j] = v;
}
/* replicate last value */
- for(; i<64; i++){
- int j= s->dsp.idct_permutation[ ff_zigzag_direct[i] ];
- s->inter_matrix[j]= last;
- s->chroma_inter_matrix[j]= last;
+ for (; i < 64; i++) {
+ int j = s->dsp.idct_permutation[ff_zigzag_direct[i]];
+ s->inter_matrix[j] = last;
+ s->chroma_inter_matrix[j] = last;
}
}
// FIXME a bunch of grayscale shape things
}
- if(vo_ver_id != 1)
- s->quarter_sample= get_bits1(gb);
- else s->quarter_sample=0;
+ if (vo_ver_id != 1)
+ s->quarter_sample = get_bits1(gb);
+ else
+ s->quarter_sample = 0;
- if(!get_bits1(gb)){
- int pos= get_bits_count(gb);
- int estimation_method= get_bits(gb, 2);
- if(estimation_method<2){
- if(!get_bits1(gb)){
- s->cplx_estimation_trash_i += 8*get_bits1(gb); //opaque
- s->cplx_estimation_trash_i += 8*get_bits1(gb); //transparent
- s->cplx_estimation_trash_i += 8*get_bits1(gb); //intra_cae
- s->cplx_estimation_trash_i += 8*get_bits1(gb); //inter_cae
- s->cplx_estimation_trash_i += 8*get_bits1(gb); //no_update
- s->cplx_estimation_trash_i += 8*get_bits1(gb); //upampling
+ if (!get_bits1(gb)) {
+ int pos = get_bits_count(gb);
+ int estimation_method = get_bits(gb, 2);
+ if (estimation_method < 2) {
+ if (!get_bits1(gb)) {
+ ctx->cplx_estimation_trash_i += 8 * get_bits1(gb); /* opaque */
+ ctx->cplx_estimation_trash_i += 8 * get_bits1(gb); /* transparent */
+ ctx->cplx_estimation_trash_i += 8 * get_bits1(gb); /* intra_cae */
+ ctx->cplx_estimation_trash_i += 8 * get_bits1(gb); /* inter_cae */
+ ctx->cplx_estimation_trash_i += 8 * get_bits1(gb); /* no_update */
+ ctx->cplx_estimation_trash_i += 8 * get_bits1(gb); /* upampling */
}
- if(!get_bits1(gb)){
- s->cplx_estimation_trash_i += 8*get_bits1(gb); //intra_blocks
- s->cplx_estimation_trash_p += 8*get_bits1(gb); //inter_blocks
- s->cplx_estimation_trash_p += 8*get_bits1(gb); //inter4v_blocks
- s->cplx_estimation_trash_i += 8*get_bits1(gb); //not coded blocks
+ if (!get_bits1(gb)) {
+ ctx->cplx_estimation_trash_i += 8 * get_bits1(gb); /* intra_blocks */
+ ctx->cplx_estimation_trash_p += 8 * get_bits1(gb); /* inter_blocks */
+ ctx->cplx_estimation_trash_p += 8 * get_bits1(gb); /* inter4v_blocks */
+ ctx->cplx_estimation_trash_i += 8 * get_bits1(gb); /* not coded blocks */
}
- if(!check_marker(gb, "in complexity estimation part 1")){
+ if (!check_marker(gb, "in complexity estimation part 1")) {
skip_bits_long(gb, pos - get_bits_count(gb));
goto no_cplx_est;
}
- if(!get_bits1(gb)){
- s->cplx_estimation_trash_i += 8*get_bits1(gb); //dct_coeffs
- s->cplx_estimation_trash_i += 8*get_bits1(gb); //dct_lines
- s->cplx_estimation_trash_i += 8*get_bits1(gb); //vlc_syms
- s->cplx_estimation_trash_i += 4*get_bits1(gb); //vlc_bits
+ if (!get_bits1(gb)) {
+ ctx->cplx_estimation_trash_i += 8 * get_bits1(gb); /* dct_coeffs */
+ ctx->cplx_estimation_trash_i += 8 * get_bits1(gb); /* dct_lines */
+ ctx->cplx_estimation_trash_i += 8 * get_bits1(gb); /* vlc_syms */
+ ctx->cplx_estimation_trash_i += 4 * get_bits1(gb); /* vlc_bits */
}
- if(!get_bits1(gb)){
- s->cplx_estimation_trash_p += 8*get_bits1(gb); //apm
- s->cplx_estimation_trash_p += 8*get_bits1(gb); //npm
- s->cplx_estimation_trash_b += 8*get_bits1(gb); //interpolate_mc_q
- s->cplx_estimation_trash_p += 8*get_bits1(gb); //forwback_mc_q
- s->cplx_estimation_trash_p += 8*get_bits1(gb); //halfpel2
- s->cplx_estimation_trash_p += 8*get_bits1(gb); //halfpel4
+ if (!get_bits1(gb)) {
+ ctx->cplx_estimation_trash_p += 8 * get_bits1(gb); /* apm */
+ ctx->cplx_estimation_trash_p += 8 * get_bits1(gb); /* npm */
+ ctx->cplx_estimation_trash_b += 8 * get_bits1(gb); /* interpolate_mc_q */
+ ctx->cplx_estimation_trash_p += 8 * get_bits1(gb); /* forwback_mc_q */
+ ctx->cplx_estimation_trash_p += 8 * get_bits1(gb); /* halfpel2 */
+ ctx->cplx_estimation_trash_p += 8 * get_bits1(gb); /* halfpel4 */
}
- if(!check_marker(gb, "in complexity estimation part 2")){
+ if (!check_marker(gb, "in complexity estimation part 2")) {
skip_bits_long(gb, pos - get_bits_count(gb));
goto no_cplx_est;
}
- if(estimation_method==1){
- s->cplx_estimation_trash_i += 8*get_bits1(gb); //sadct
- s->cplx_estimation_trash_p += 8*get_bits1(gb); //qpel
+ if (estimation_method == 1) {
+ ctx->cplx_estimation_trash_i += 8 * get_bits1(gb); /* sadct */
+ ctx->cplx_estimation_trash_p += 8 * get_bits1(gb); /* qpel */
}
- }else
- av_log(s->avctx, AV_LOG_ERROR, "Invalid Complexity estimation method %d\n", estimation_method);
- }else{
+ } else
+ av_log(s->avctx, AV_LOG_ERROR,
+ "Invalid Complexity estimation method %d\n",
+ estimation_method);
+ } else {
+
no_cplx_est:
- s->cplx_estimation_trash_i=
- s->cplx_estimation_trash_p=
- s->cplx_estimation_trash_b= 0;
+ ctx->cplx_estimation_trash_i =
+ ctx->cplx_estimation_trash_p =
+ ctx->cplx_estimation_trash_b = 0;
}
- s->resync_marker= !get_bits1(gb); /* resync_marker_disabled */
+ ctx->resync_marker = !get_bits1(gb); /* resync_marker_disabled */
- s->data_partitioning= get_bits1(gb);
- if(s->data_partitioning){
- s->rvlc= get_bits1(gb);
- }
+ s->data_partitioning = get_bits1(gb);
+ if (s->data_partitioning)
+ ctx->rvlc = get_bits1(gb);
- if(vo_ver_id != 1) {
- s->new_pred= get_bits1(gb);
- if(s->new_pred){
+ if (vo_ver_id != 1) {
+ ctx->new_pred = get_bits1(gb);
+ if (ctx->new_pred) {
av_log(s->avctx, AV_LOG_ERROR, "new pred not supported\n");
skip_bits(gb, 2); /* requested upstream message type */
- skip_bits1(gb); /* newpred segment type */
+ skip_bits1(gb); /* newpred segment type */
}
- s->reduced_res_vop= get_bits1(gb);
- if(s->reduced_res_vop) av_log(s->avctx, AV_LOG_ERROR, "reduced resolution VOP not supported\n");
- }
- else{
- s->new_pred=0;
- s->reduced_res_vop= 0;
+ if (get_bits1(gb)) // reduced_res_vop
+ av_log(s->avctx, AV_LOG_ERROR,
+ "reduced resolution VOP not supported\n");
+ } else {
+ ctx->new_pred = 0;
}
- s->scalability= get_bits1(gb);
+ ctx->scalability = get_bits1(gb);
- if (s->scalability) {
- GetBitContext bak= *gb;
+ if (ctx->scalability) {
+ GetBitContext bak = *gb;
int h_sampling_factor_n;
int h_sampling_factor_m;
int v_sampling_factor_n;
int v_sampling_factor_m;
- s->hierachy_type= get_bits1(gb);
+ skip_bits1(gb); // hierarchy_type
skip_bits(gb, 4); /* ref_layer_id */
skip_bits1(gb); /* ref_layer_sampling_dir */
- h_sampling_factor_n= get_bits(gb, 5);
- h_sampling_factor_m= get_bits(gb, 5);
- v_sampling_factor_n= get_bits(gb, 5);
- v_sampling_factor_m= get_bits(gb, 5);
- s->enhancement_type= get_bits1(gb);
+ h_sampling_factor_n = get_bits(gb, 5);
+ h_sampling_factor_m = get_bits(gb, 5);
+ v_sampling_factor_n = get_bits(gb, 5);
+ v_sampling_factor_m = get_bits(gb, 5);
+ ctx->enhancement_type = get_bits1(gb);
- if( h_sampling_factor_n==0 || h_sampling_factor_m==0
- || v_sampling_factor_n==0 || v_sampling_factor_m==0){
+ if (h_sampling_factor_n == 0 || h_sampling_factor_m == 0 ||
+ v_sampling_factor_n == 0 || v_sampling_factor_m == 0) {
/* illegal scalability header (VERY broken encoder),
* trying to workaround */
- s->scalability=0;
- *gb= bak;
- }else
+ ctx->scalability = 0;
+ *gb = bak;
+ } else
av_log(s->avctx, AV_LOG_ERROR, "scalability not supported\n");
// bin shape stuff FIXME
}
}
- if(s->avctx->debug&FF_DEBUG_PICT_INFO) {
+ if (s->avctx->debug&FF_DEBUG_PICT_INFO) {
av_log(s->avctx, AV_LOG_DEBUG, "tb %d/%d, tincrbits:%d, qp_prec:%d, ps:%d, %s%s%s%s\n",
s->avctx->time_base.num, s->avctx->time_base.den,
- s->time_increment_bits,
+ ctx->time_increment_bits,
s->quant_precision,
s->progressive_sequence,
- s->scalability ? "scalability " :"" , s->quarter_sample ? "qpel " : "",
- s->data_partitioning ? "partition " : "", s->rvlc ? "rvlc " : ""
+ ctx->scalability ? "scalability " :"" , s->quarter_sample ? "qpel " : "",
+ s->data_partitioning ? "partition " : "", ctx->rvlc ? "rvlc " : ""
);
}
@@ -1888,293 +2039,441 @@
* Decode the user data stuff in the header.
* Also initializes divx/xvid/lavc_version/build.
*/
-static int decode_user_data(MpegEncContext *s, GetBitContext *gb){
+static int decode_user_data(Mpeg4DecContext *ctx, GetBitContext *gb)
+{
+ MpegEncContext *s = &ctx->m;
char buf[256];
int i;
int e;
int ver = 0, build = 0, ver2 = 0, ver3 = 0;
char last;
- for(i=0; i<255 && get_bits_count(gb) < gb->size_in_bits; i++){
- if(show_bits(gb, 23) == 0) break;
- buf[i]= get_bits(gb, 8);
+ for (i = 0; i < 255 && get_bits_count(gb) < gb->size_in_bits; i++) {
+ if (show_bits(gb, 23) == 0)
+ break;
+ buf[i] = get_bits(gb, 8);
}
- buf[i]=0;
+ buf[i] = 0;
/* divx detection */
- e=sscanf(buf, "DivX%dBuild%d%c", &ver, &build, &last);
- if(e<2)
- e=sscanf(buf, "DivX%db%d%c", &ver, &build, &last);
- if(e>=2){
- s->divx_version= ver;
- s->divx_build= build;
- s->divx_packed= e==3 && last=='p';
- if(s->divx_packed && !s->showed_packed_warning) {
+ e = sscanf(buf, "DivX%dBuild%d%c", &ver, &build, &last);
+ if (e < 2)
+ e = sscanf(buf, "DivX%db%d%c", &ver, &build, &last);
+ if (e >= 2) {
+ ctx->divx_version = ver;
+ ctx->divx_build = build;
+ s->divx_packed = e == 3 && last == 'p';
+ if (s->divx_packed && !ctx->showed_packed_warning) {
av_log(s->avctx, AV_LOG_INFO, "Video uses a non-standard and "
"wasteful way to store B-frames ('packed B-frames'). "
"Consider using a tool like VirtualDub or avidemux to fix it.\n");
- s->showed_packed_warning=1;
+ ctx->showed_packed_warning = 1;
}
}
/* 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);
- if(e!=4){
- e=sscanf(buf, "Lavc%d.%d.%d", &ver, &ver2, &ver3)+1;
- if (e>1)
- build= (ver<<16) + (ver2<<8) + ver3;
+ 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);
+ if (e != 4) {
+ e = sscanf(buf, "Lavc%d.%d.%d", &ver, &ver2, &ver3) + 1;
+ if (e > 1)
+ build = (ver << 16) + (ver2 << 8) + ver3;
}
- if(e!=4){
- if(strcmp(buf, "ffmpeg")==0){
- s->lavc_build= 4600;
- }
+ if (e != 4) {
+ if (strcmp(buf, "ffmpeg") == 0)
+ ctx->lavc_build = 4600;
}
- if(e==4){
- s->lavc_build= build;
- }
+ if (e == 4)
+ ctx->lavc_build = build;
/* Xvid detection */
- e=sscanf(buf, "XviD%d", &build);
- if(e==1){
- s->xvid_build= build;
- }
+ e = sscanf(buf, "XviD%d", &build);
+ if (e == 1)
+ ctx->xvid_build = build;
return 0;
}
-static int decode_vop_header(MpegEncContext *s, GetBitContext *gb){
- int time_incr, time_increment;
+int ff_mpeg4_workaround_bugs(AVCodecContext *avctx)
+{
+ Mpeg4DecContext *ctx = avctx->priv_data;
+ MpegEncContext *s = &ctx->m;
- s->pict_type = get_bits(gb, 2) + AV_PICTURE_TYPE_I; /* pict type: I = 0 , P = 1 */
- if(s->pict_type==AV_PICTURE_TYPE_B && s->low_delay && s->vol_control_parameters==0 && !(s->flags & CODEC_FLAG_LOW_DELAY)){
- av_log(s->avctx, AV_LOG_ERROR, "low_delay flag incorrectly, clearing it\n");
- s->low_delay=0;
+ if (ctx->xvid_build == -1 && ctx->divx_version == -1 && ctx->lavc_build == -1) {
+ if (s->stream_codec_tag == AV_RL32("XVID") ||
+ s->codec_tag == AV_RL32("XVID") ||
+ s->codec_tag == AV_RL32("XVIX") ||
+ s->codec_tag == AV_RL32("RMP4") ||
+ s->codec_tag == AV_RL32("ZMP4") ||
+ s->codec_tag == AV_RL32("SIPP"))
+ ctx->xvid_build = 0;
}
- s->partitioned_frame= s->data_partitioning && s->pict_type!=AV_PICTURE_TYPE_B;
- if(s->partitioned_frame)
- s->decode_mb= mpeg4_decode_partitioned_mb;
- else
- s->decode_mb= mpeg4_decode_mb;
+ if (ctx->xvid_build == -1 && ctx->divx_version == -1 && ctx->lavc_build == -1)
+ if (s->codec_tag == AV_RL32("DIVX") && s->vo_type == 0 &&
+ s->vol_control_parameters == 0)
+ ctx->divx_version = 400; // divx 4
- time_incr=0;
+ if (ctx->xvid_build >= 0 && ctx->divx_version >= 0) {
+ ctx->divx_version =
+ ctx->divx_build = -1;
+ }
+
+ if (s->workaround_bugs & FF_BUG_AUTODETECT) {
+ if (s->codec_tag == AV_RL32("XVIX"))
+ s->workaround_bugs |= FF_BUG_XVID_ILACE;
+
+ if (s->codec_tag == AV_RL32("UMP4"))
+ s->workaround_bugs |= FF_BUG_UMP4;
+
+ if (ctx->divx_version >= 500 && ctx->divx_build < 1814)
+ s->workaround_bugs |= FF_BUG_QPEL_CHROMA;
+
+ if (ctx->divx_version > 502 && ctx->divx_build < 1814)
+ s->workaround_bugs |= FF_BUG_QPEL_CHROMA2;
+
+ if (ctx->xvid_build <= 3U)
+ s->padding_bug_score = 256 * 256 * 256 * 64;
+
+ if (ctx->xvid_build <= 1U)
+ s->workaround_bugs |= FF_BUG_QPEL_CHROMA;
+
+ if (ctx->xvid_build <= 12U)
+ s->workaround_bugs |= FF_BUG_EDGE;
+
+ if (ctx->xvid_build <= 32U)
+ s->workaround_bugs |= FF_BUG_DC_CLIP;
+
+#define SET_QPEL_FUNC(postfix1, postfix2) \
+ s->dsp.put_ ## postfix1 = ff_put_ ## postfix2; \
+ s->dsp.put_no_rnd_ ## postfix1 = ff_put_no_rnd_ ## postfix2; \
+ s->dsp.avg_ ## postfix1 = ff_avg_ ## postfix2;
+
+ if (ctx->lavc_build < 4653U)
+ s->workaround_bugs |= FF_BUG_STD_QPEL;
+
+ if (ctx->lavc_build < 4655U)
+ s->workaround_bugs |= FF_BUG_DIRECT_BLOCKSIZE;
+
+ if (ctx->lavc_build < 4670U)
+ s->workaround_bugs |= FF_BUG_EDGE;
+
+ if (ctx->lavc_build <= 4712U)
+ s->workaround_bugs |= FF_BUG_DC_CLIP;
+
+ if (ctx->divx_version >= 0)
+ s->workaround_bugs |= FF_BUG_DIRECT_BLOCKSIZE;
+ if (ctx->divx_version == 501 && ctx->divx_build == 20020416)
+ s->padding_bug_score = 256 * 256 * 256 * 64;
+
+ if (ctx->divx_version < 500U)
+ s->workaround_bugs |= FF_BUG_EDGE;
+
+ if (ctx->divx_version >= 0)
+ s->workaround_bugs |= FF_BUG_HPEL_CHROMA;
+ }
+
+ if (s->workaround_bugs & FF_BUG_STD_QPEL) {
+ SET_QPEL_FUNC(qpel_pixels_tab[0][5], qpel16_mc11_old_c)
+ SET_QPEL_FUNC(qpel_pixels_tab[0][7], qpel16_mc31_old_c)
+ SET_QPEL_FUNC(qpel_pixels_tab[0][9], qpel16_mc12_old_c)
+ SET_QPEL_FUNC(qpel_pixels_tab[0][11], qpel16_mc32_old_c)
+ SET_QPEL_FUNC(qpel_pixels_tab[0][13], qpel16_mc13_old_c)
+ SET_QPEL_FUNC(qpel_pixels_tab[0][15], qpel16_mc33_old_c)
+
+ SET_QPEL_FUNC(qpel_pixels_tab[1][5], qpel8_mc11_old_c)
+ SET_QPEL_FUNC(qpel_pixels_tab[1][7], qpel8_mc31_old_c)
+ SET_QPEL_FUNC(qpel_pixels_tab[1][9], qpel8_mc12_old_c)
+ SET_QPEL_FUNC(qpel_pixels_tab[1][11], qpel8_mc32_old_c)
+ SET_QPEL_FUNC(qpel_pixels_tab[1][13], qpel8_mc13_old_c)
+ SET_QPEL_FUNC(qpel_pixels_tab[1][15], qpel8_mc33_old_c)
+ }
+
+ if (avctx->debug & FF_DEBUG_BUGS)
+ av_log(s->avctx, AV_LOG_DEBUG,
+ "bugs: %X lavc_build:%d xvid_build:%d divx_version:%d divx_build:%d %s\n",
+ s->workaround_bugs, ctx->lavc_build, ctx->xvid_build,
+ ctx->divx_version, ctx->divx_build, s->divx_packed ? "p" : "");
+
+#if HAVE_MMX
+ if (s->codec_id == AV_CODEC_ID_MPEG4 && ctx->xvid_build >= 0 &&
+ avctx->idct_algo == FF_IDCT_AUTO &&
+ (av_get_cpu_flags() & AV_CPU_FLAG_MMX)) {
+ avctx->idct_algo = FF_IDCT_XVIDMMX;
+ ff_dct_common_init(s);
+ return 1;
+ }
+#endif
+ return 0;
+}
+
+static int decode_vop_header(Mpeg4DecContext *ctx, GetBitContext *gb)
+{
+ MpegEncContext *s = &ctx->m;
+ int time_incr, time_increment;
+ int64_t pts;
+
+ s->pict_type = get_bits(gb, 2) + AV_PICTURE_TYPE_I; /* pict type: I = 0 , P = 1 */
+ if (s->pict_type == AV_PICTURE_TYPE_B && s->low_delay &&
+ s->vol_control_parameters == 0 && !(s->flags & CODEC_FLAG_LOW_DELAY)) {
+ av_log(s->avctx, AV_LOG_ERROR, "low_delay flag incorrectly, clearing it\n");
+ s->low_delay = 0;
+ }
+
+ s->partitioned_frame = s->data_partitioning && s->pict_type != AV_PICTURE_TYPE_B;
+ if (s->partitioned_frame)
+ s->decode_mb = mpeg4_decode_partitioned_mb;
+ else
+ s->decode_mb = mpeg4_decode_mb;
+
+ time_incr = 0;
while (get_bits1(gb) != 0)
time_incr++;
check_marker(gb, "before time_increment");
- if(s->time_increment_bits==0 || !(show_bits(gb, s->time_increment_bits+1)&1)){
- av_log(s->avctx, AV_LOG_ERROR, "hmm, seems the headers are not complete, trying to guess time_increment_bits\n");
+ if (ctx->time_increment_bits == 0 ||
+ !(show_bits(gb, ctx->time_increment_bits + 1) & 1)) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "hmm, seems the headers are not complete, trying to guess time_increment_bits\n");
- for(s->time_increment_bits=1 ;s->time_increment_bits<16; s->time_increment_bits++){
- if ( s->pict_type == AV_PICTURE_TYPE_P
- || (s->pict_type == AV_PICTURE_TYPE_S && s->vol_sprite_usage==GMC_SPRITE)) {
- if((show_bits(gb, s->time_increment_bits+6)&0x37) == 0x30) break;
- }else
- if((show_bits(gb, s->time_increment_bits+5)&0x1F) == 0x18) break;
+ for (ctx->time_increment_bits = 1;
+ ctx->time_increment_bits < 16;
+ ctx->time_increment_bits++) {
+ if (s->pict_type == AV_PICTURE_TYPE_P ||
+ (s->pict_type == AV_PICTURE_TYPE_S &&
+ ctx->vol_sprite_usage == GMC_SPRITE)) {
+ if ((show_bits(gb, ctx->time_increment_bits + 6) & 0x37) == 0x30)
+ break;
+ } else if ((show_bits(gb, ctx->time_increment_bits + 5) & 0x1F) == 0x18)
+ break;
}
- av_log(s->avctx, AV_LOG_ERROR, "my guess is %d bits ;)\n",s->time_increment_bits);
- if (s->avctx->time_base.den && 4*s->avctx->time_base.den < 1<<s->time_increment_bits) {
- s->avctx->time_base.den = 1<<s->time_increment_bits;
+ av_log(s->avctx, AV_LOG_ERROR,
+ "my guess is %d bits ;)\n", ctx->time_increment_bits);
+ if (s->avctx->time_base.den && 4*s->avctx->time_base.den < 1<<ctx->time_increment_bits) {
+ s->avctx->time_base.den = 1<<ctx->time_increment_bits;
}
}
- if(IS_3IV1) time_increment= get_bits1(gb); //FIXME investigate further
- else time_increment= get_bits(gb, s->time_increment_bits);
+ if (IS_3IV1)
+ time_increment = get_bits1(gb); // FIXME investigate further
+ else
+ time_increment = get_bits(gb, ctx->time_increment_bits);
- if(s->pict_type!=AV_PICTURE_TYPE_B){
- s->last_time_base= s->time_base;
- s->time_base+= time_incr;
- s->time= s->time_base*s->avctx->time_base.den + time_increment;
- if(s->workaround_bugs&FF_BUG_UMP4){
- if(s->time < s->last_non_b_time){
+ if (s->pict_type != AV_PICTURE_TYPE_B) {
+ s->last_time_base = s->time_base;
+ s->time_base += time_incr;
+ s->time = s->time_base * s->avctx->time_base.den + time_increment;
+ if (s->workaround_bugs & FF_BUG_UMP4) {
+ if (s->time < s->last_non_b_time) {
/* header is not mpeg-4-compatible, broken encoder,
* trying to workaround */
s->time_base++;
- s->time+= s->avctx->time_base.den;
+ s->time += s->avctx->time_base.den;
}
}
- s->pp_time= s->time - s->last_non_b_time;
- s->last_non_b_time= s->time;
- }else{
- s->time= (s->last_time_base + time_incr)*s->avctx->time_base.den + time_increment;
- s->pb_time= s->pp_time - (s->last_non_b_time - s->time);
- if(s->pp_time <=s->pb_time || s->pp_time <= s->pp_time - s->pb_time || s->pp_time<=0){
+ s->pp_time = s->time - s->last_non_b_time;
+ s->last_non_b_time = s->time;
+ } else {
+ s->time = (s->last_time_base + time_incr) * s->avctx->time_base.den + time_increment;
+ s->pb_time = s->pp_time - (s->last_non_b_time - s->time);
+ if (s->pp_time <= s->pb_time ||
+ s->pp_time <= s->pp_time - s->pb_time ||
+ s->pp_time <= 0) {
/* messed up order, maybe after seeking? skipping current b-frame */
return FRAME_SKIPPED;
}
ff_mpeg4_init_direct_mv(s);
- if(s->t_frame==0) s->t_frame= s->pb_time;
- if(s->t_frame==0) s->t_frame=1; // 1/0 protection
- s->pp_field_time= ( ROUNDED_DIV(s->last_non_b_time, s->t_frame)
- - ROUNDED_DIV(s->last_non_b_time - s->pp_time, s->t_frame))*2;
- s->pb_field_time= ( ROUNDED_DIV(s->time, s->t_frame)
- - ROUNDED_DIV(s->last_non_b_time - s->pp_time, s->t_frame))*2;
- if(!s->progressive_sequence){
- if(s->pp_field_time <= s->pb_field_time || s->pb_field_time <= 1)
+ if (ctx->t_frame == 0)
+ ctx->t_frame = s->pb_time;
+ if (ctx->t_frame == 0)
+ ctx->t_frame = 1; // 1/0 protection
+ s->pp_field_time = (ROUNDED_DIV(s->last_non_b_time, ctx->t_frame) -
+ ROUNDED_DIV(s->last_non_b_time - s->pp_time, ctx->t_frame)) * 2;
+ s->pb_field_time = (ROUNDED_DIV(s->time, ctx->t_frame) -
+ ROUNDED_DIV(s->last_non_b_time - s->pp_time, ctx->t_frame)) * 2;
+ if (!s->progressive_sequence) {
+ if (s->pp_field_time <= s->pb_field_time || s->pb_field_time <= 1)
return FRAME_SKIPPED;
}
}
- if(s->avctx->time_base.num)
- s->current_picture_ptr->f.pts = ROUNDED_DIV(s->time, s->avctx->time_base.num);
+ if (s->avctx->time_base.num)
+ pts = ROUNDED_DIV(s->time, s->avctx->time_base.num);
else
- s->current_picture_ptr->f.pts = AV_NOPTS_VALUE;
- if(s->avctx->debug&FF_DEBUG_PTS)
+ 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->f.pts);
+ pts);
check_marker(gb, "before vop_coded");
/* vop coded */
- if (get_bits1(gb) != 1){
- if(s->avctx->debug&FF_DEBUG_PICT_INFO)
+ if (get_bits1(gb) != 1) {
+ if (s->avctx->debug & FF_DEBUG_PICT_INFO)
av_log(s->avctx, AV_LOG_ERROR, "vop not coded\n");
return FRAME_SKIPPED;
}
- if (s->new_pred)
- decode_new_pred(s, gb);
+ if (ctx->new_pred)
+ decode_new_pred(ctx, gb);
- if (s->shape != BIN_ONLY_SHAPE && ( s->pict_type == AV_PICTURE_TYPE_P
- || (s->pict_type == AV_PICTURE_TYPE_S && s->vol_sprite_usage==GMC_SPRITE))) {
+ if (ctx->shape != BIN_ONLY_SHAPE &&
+ (s->pict_type == AV_PICTURE_TYPE_P ||
+ (s->pict_type == AV_PICTURE_TYPE_S &&
+ ctx->vol_sprite_usage == GMC_SPRITE))) {
/* rounding type for motion estimation */
s->no_rounding = get_bits1(gb);
} else {
s->no_rounding = 0;
}
-//FIXME reduced res stuff
+ // FIXME reduced res stuff
- if (s->shape != RECT_SHAPE) {
- if (s->vol_sprite_usage != 1 || s->pict_type != AV_PICTURE_TYPE_I) {
- skip_bits(gb, 13); /* width */
- skip_bits1(gb); /* marker */
- skip_bits(gb, 13); /* height */
- skip_bits1(gb); /* marker */
- skip_bits(gb, 13); /* hor_spat_ref */
- skip_bits1(gb); /* marker */
- skip_bits(gb, 13); /* ver_spat_ref */
- }
- skip_bits1(gb); /* change_CR_disable */
+ if (ctx->shape != RECT_SHAPE) {
+ if (ctx->vol_sprite_usage != 1 || s->pict_type != AV_PICTURE_TYPE_I) {
+ skip_bits(gb, 13); /* width */
+ skip_bits1(gb); /* marker */
+ skip_bits(gb, 13); /* height */
+ skip_bits1(gb); /* marker */
+ skip_bits(gb, 13); /* hor_spat_ref */
+ skip_bits1(gb); /* marker */
+ skip_bits(gb, 13); /* ver_spat_ref */
+ }
+ skip_bits1(gb); /* change_CR_disable */
- if (get_bits1(gb) != 0) {
- skip_bits(gb, 8); /* constant_alpha_value */
- }
- }
-//FIXME complexity estimation stuff
+ if (get_bits1(gb) != 0)
+ skip_bits(gb, 8); /* constant_alpha_value */
+ }
- if (s->shape != BIN_ONLY_SHAPE) {
- skip_bits_long(gb, s->cplx_estimation_trash_i);
- if(s->pict_type != AV_PICTURE_TYPE_I)
- skip_bits_long(gb, s->cplx_estimation_trash_p);
- if(s->pict_type == AV_PICTURE_TYPE_B)
- skip_bits_long(gb, s->cplx_estimation_trash_b);
+ // FIXME complexity estimation stuff
- if(get_bits_left(gb) < 3) {
- av_log(s->avctx, AV_LOG_ERROR, "Header truncated\n");
- return -1;
- }
- s->intra_dc_threshold= ff_mpeg4_dc_threshold[ get_bits(gb, 3) ];
- if(!s->progressive_sequence){
- s->top_field_first= get_bits1(gb);
- s->alternate_scan= get_bits1(gb);
- }else
- s->alternate_scan= 0;
- }
+ if (ctx->shape != BIN_ONLY_SHAPE) {
+ skip_bits_long(gb, ctx->cplx_estimation_trash_i);
+ if (s->pict_type != AV_PICTURE_TYPE_I)
+ skip_bits_long(gb, ctx->cplx_estimation_trash_p);
+ if (s->pict_type == AV_PICTURE_TYPE_B)
+ skip_bits_long(gb, ctx->cplx_estimation_trash_b);
- 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);
- ff_init_scantable(s->dsp.idct_permutation, &s->intra_h_scantable, ff_alternate_vertical_scan);
- ff_init_scantable(s->dsp.idct_permutation, &s->intra_v_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);
- ff_init_scantable(s->dsp.idct_permutation, &s->intra_h_scantable, ff_alternate_horizontal_scan);
- ff_init_scantable(s->dsp.idct_permutation, &s->intra_v_scantable, ff_alternate_vertical_scan);
- }
+ if (get_bits_left(gb) < 3) {
+ av_log(s->avctx, AV_LOG_ERROR, "Header truncated\n");
+ return -1;
+ }
+ ctx->intra_dc_threshold = ff_mpeg4_dc_threshold[get_bits(gb, 3)];
+ if (!s->progressive_sequence) {
+ s->top_field_first = get_bits1(gb);
+ s->alternate_scan = get_bits1(gb);
+ } else
+ s->alternate_scan = 0;
+ }
- if(s->pict_type == AV_PICTURE_TYPE_S && (s->vol_sprite_usage==STATIC_SPRITE || s->vol_sprite_usage==GMC_SPRITE)){
- if (mpeg4_decode_sprite_trajectory(s, gb) < 0)
- return AVERROR_INVALIDDATA;
- if(s->sprite_brightness_change) av_log(s->avctx, AV_LOG_ERROR, "sprite_brightness_change not supported\n");
- if(s->vol_sprite_usage==STATIC_SPRITE) av_log(s->avctx, AV_LOG_ERROR, "static sprite not supported\n");
- }
+ 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);
+ ff_init_scantable(s->dsp.idct_permutation, &s->intra_h_scantable, ff_alternate_vertical_scan);
+ ff_init_scantable(s->dsp.idct_permutation, &s->intra_v_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);
+ ff_init_scantable(s->dsp.idct_permutation, &s->intra_h_scantable, ff_alternate_horizontal_scan);
+ ff_init_scantable(s->dsp.idct_permutation, &s->intra_v_scantable, ff_alternate_vertical_scan);
+ }
- if (s->shape != BIN_ONLY_SHAPE) {
- s->chroma_qscale= s->qscale = get_bits(gb, s->quant_precision);
- if(s->qscale==0){
- av_log(s->avctx, AV_LOG_ERROR, "Error, header damaged or not MPEG4 header (qscale=0)\n");
- return -1; // makes no sense to continue, as there is nothing left from the image then
- }
+ if (s->pict_type == AV_PICTURE_TYPE_S &&
+ (ctx->vol_sprite_usage == STATIC_SPRITE ||
+ ctx->vol_sprite_usage == GMC_SPRITE)) {
+ if (mpeg4_decode_sprite_trajectory(ctx, gb) < 0)
+ return AVERROR_INVALIDDATA;
+ if (ctx->sprite_brightness_change)
+ av_log(s->avctx, AV_LOG_ERROR,
+ "sprite_brightness_change not supported\n");
+ if (ctx->vol_sprite_usage == STATIC_SPRITE)
+ av_log(s->avctx, AV_LOG_ERROR, "static sprite not supported\n");
+ }
- if (s->pict_type != AV_PICTURE_TYPE_I) {
- s->f_code = get_bits(gb, 3); /* fcode_for */
- if(s->f_code==0){
- av_log(s->avctx, AV_LOG_ERROR, "Error, header damaged or not MPEG4 header (f_code=0)\n");
- s->f_code=1;
- return -1; // makes no sense to continue, as the MV decoding will break very quickly
- }
- }else
- s->f_code=1;
+ if (ctx->shape != BIN_ONLY_SHAPE) {
+ s->chroma_qscale = s->qscale = get_bits(gb, s->quant_precision);
+ if (s->qscale == 0) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "Error, header damaged or not MPEG4 header (qscale=0)\n");
+ return -1; // makes no sense to continue, as there is nothing left from the image then
+ }
- if (s->pict_type == AV_PICTURE_TYPE_B) {
- s->b_code = get_bits(gb, 3);
- if(s->b_code==0){
- av_log(s->avctx, AV_LOG_ERROR, "Error, header damaged or not MPEG4 header (b_code=0)\n");
- s->b_code=1;
- return -1; // makes no sense to continue, as the MV decoding will break very quickly
- }
- }else
- s->b_code=1;
+ if (s->pict_type != AV_PICTURE_TYPE_I) {
+ s->f_code = get_bits(gb, 3); /* fcode_for */
+ if (s->f_code == 0) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "Error, header damaged or not MPEG4 header (f_code=0)\n");
+ s->f_code = 1;
+ return -1; // makes no sense to continue, as there is nothing left from the image then
+ }
+ } else
+ s->f_code = 1;
- if(s->avctx->debug&FF_DEBUG_PICT_INFO){
- av_log(s->avctx, AV_LOG_DEBUG, "qp:%d fc:%d,%d %s size:%d pro:%d alt:%d top:%d %spel part:%d resync:%d w:%d a:%d rnd:%d vot:%d%s dc:%d ce:%d/%d/%d time:%"PRId64" tincr:%d\n",
- s->qscale, s->f_code, s->b_code,
- 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")),
- gb->size_in_bits,s->progressive_sequence, s->alternate_scan, s->top_field_first,
- s->quarter_sample ? "q" : "h", s->data_partitioning, s->resync_marker, s->num_sprite_warping_points,
- s->sprite_warping_accuracy, 1-s->no_rounding, s->vo_type, s->vol_control_parameters ? " VOLC" : " ", s->intra_dc_threshold,
- s->cplx_estimation_trash_i, s->cplx_estimation_trash_p, s->cplx_estimation_trash_b,
- s->time,
- time_increment
- );
- }
+ if (s->pict_type == AV_PICTURE_TYPE_B) {
+ s->b_code = get_bits(gb, 3);
+ if (s->b_code == 0) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "Error, header damaged or not MPEG4 header (b_code=0)\n");
+ s->b_code=1;
+ return -1; // makes no sense to continue, as the MV decoding will break very quickly
+ }
+ } else
+ s->b_code = 1;
- if(!s->scalability){
- if (s->shape!=RECT_SHAPE && s->pict_type!=AV_PICTURE_TYPE_I) {
- skip_bits1(gb); // vop shape coding type
- }
- }else{
- if(s->enhancement_type){
- int load_backward_shape= get_bits1(gb);
- if(load_backward_shape){
- av_log(s->avctx, AV_LOG_ERROR, "load backward shape isn't supported\n");
- }
- }
- skip_bits(gb, 2); //ref_select_code
- }
- }
- /* detect buggy encoders which don't set the low_delay flag (divx4/xvid/opendivx)*/
- // note we cannot detect divx5 without b-frames easily (although it's buggy too)
- if(s->vo_type==0 && s->vol_control_parameters==0 && s->divx_version==-1 && s->picture_number==0){
- av_log(s->avctx, AV_LOG_WARNING, "looks like this file was encoded with (divx4/(old)xvid/opendivx) -> forcing low_delay flag\n");
- s->low_delay=1;
- }
+ if (s->avctx->debug & FF_DEBUG_PICT_INFO) {
+ av_log(s->avctx, AV_LOG_DEBUG,
+ "qp:%d fc:%d,%d %s size:%d pro:%d alt:%d top:%d %spel part:%d resync:%d w:%d a:%d rnd:%d vot:%d%s dc:%d ce:%d/%d/%d time:%"PRId64" tincr:%d\n",
+ s->qscale, s->f_code, s->b_code,
+ 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")),
+ gb->size_in_bits,s->progressive_sequence, s->alternate_scan,
+ s->top_field_first, s->quarter_sample ? "q" : "h",
+ s->data_partitioning, ctx->resync_marker,
+ ctx->num_sprite_warping_points, s->sprite_warping_accuracy,
+ 1 - s->no_rounding, s->vo_type,
+ s->vol_control_parameters ? " VOLC" : " ", ctx->intra_dc_threshold,
+ ctx->cplx_estimation_trash_i, ctx->cplx_estimation_trash_p,
+ ctx->cplx_estimation_trash_b,
+ s->time,
+ time_increment
+ );
+ }
- s->picture_number++; // better than pic number==0 always ;)
+ if (!ctx->scalability) {
+ if (ctx->shape != RECT_SHAPE && s->pict_type != AV_PICTURE_TYPE_I)
+ skip_bits1(gb); // vop shape coding type
+ } else {
+ if (ctx->enhancement_type) {
+ int load_backward_shape = get_bits1(gb);
+ if (load_backward_shape)
+ av_log(s->avctx, AV_LOG_ERROR,
+ "load backward shape isn't supported\n");
+ }
+ skip_bits(gb, 2); // ref_select_code
+ }
+ }
+ /* detect buggy encoders which don't set the low_delay flag
+ * (divx4/xvid/opendivx). Note we cannot detect divx5 without b-frames
+ * easily (although it's buggy too) */
+ if (s->vo_type == 0 && s->vol_control_parameters == 0 &&
+ ctx->divx_version == -1 && s->picture_number == 0) {
+ av_log(s->avctx, AV_LOG_WARNING,
+ "looks like this file was encoded with (divx4/(old)xvid/opendivx) -> forcing low_delay flag\n");
+ s->low_delay = 1;
+ }
- s->y_dc_scale_table= ff_mpeg4_y_dc_scale_table; //FIXME add short header support
- s->c_dc_scale_table= ff_mpeg4_c_dc_scale_table;
+ s->picture_number++; // better than pic number==0 always ;)
- if(s->workaround_bugs&FF_BUG_EDGE){
- s->h_edge_pos= s->width;
- s->v_edge_pos= s->height;
- }
- return 0;
+ // FIXME add short header support
+ s->y_dc_scale_table = ff_mpeg4_y_dc_scale_table;
+ s->c_dc_scale_table = ff_mpeg4_c_dc_scale_table;
+
+ if (s->workaround_bugs & FF_BUG_EDGE) {
+ s->h_edge_pos = s->width;
+ s->v_edge_pos = s->height;
+ }
+ return 0;
}
/**
@@ -2183,93 +2482,120 @@
* 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 ff_mpeg4_decode_picture_header(Mpeg4DecContext *ctx, GetBitContext *gb)
{
+ MpegEncContext *s = &ctx->m;
unsigned startcode, v;
/* search next start code */
align_get_bits(gb);
- if(s->codec_tag == AV_RL32("WV1F") && show_bits(gb, 24) == 0x575630){
+ if (s->codec_tag == AV_RL32("WV1F") && show_bits(gb, 24) == 0x575630) {
skip_bits(gb, 24);
- if(get_bits(gb, 8) == 0xF0)
+ if (get_bits(gb, 8) == 0xF0)
goto end;
}
startcode = 0xff;
- for(;;) {
- if(get_bits_count(gb) >= gb->size_in_bits){
- if(gb->size_in_bits==8 && (s->divx_version>=0 || s->xvid_build>=0) || s->codec_tag == AV_RL32("QMP4")){
+ for (;;) {
+ if (get_bits_count(gb) >= gb->size_in_bits) {
+ if (gb->size_in_bits == 8 &&
+ (ctx->divx_version >= 0 || ctx->xvid_build >= 0) || s->codec_tag == AV_RL32("QMP4")) {
av_log(s->avctx, AV_LOG_VERBOSE, "frame skip %d\n", gb->size_in_bits);
- return FRAME_SKIPPED; //divx bug
- }else
- return -1; //end of stream
+ return FRAME_SKIPPED; // divx bug
+ } else
+ return -1; // end of stream
}
/* use the bits after the test */
v = get_bits(gb, 8);
startcode = ((startcode << 8) | v) & 0xffffffff;
- if((startcode&0xFFFFFF00) != 0x100)
- continue; //no startcode
+ if ((startcode & 0xFFFFFF00) != 0x100)
+ continue; // no startcode
- if(s->avctx->debug&FF_DEBUG_STARTCODE){
+ if (s->avctx->debug & FF_DEBUG_STARTCODE) {
av_log(s->avctx, AV_LOG_DEBUG, "startcode: %3X ", startcode);
- if (startcode<=0x11F) av_log(s->avctx, AV_LOG_DEBUG, "Video Object Start");
- else if(startcode<=0x12F) av_log(s->avctx, AV_LOG_DEBUG, "Video Object Layer Start");
- else if(startcode<=0x13F) av_log(s->avctx, AV_LOG_DEBUG, "Reserved");
- else if(startcode<=0x15F) av_log(s->avctx, AV_LOG_DEBUG, "FGS bp start");
- else if(startcode<=0x1AF) av_log(s->avctx, AV_LOG_DEBUG, "Reserved");
- else if(startcode==0x1B0) av_log(s->avctx, AV_LOG_DEBUG, "Visual Object Seq Start");
- else if(startcode==0x1B1) av_log(s->avctx, AV_LOG_DEBUG, "Visual Object Seq End");
- else if(startcode==0x1B2) av_log(s->avctx, AV_LOG_DEBUG, "User Data");
- else if(startcode==0x1B3) av_log(s->avctx, AV_LOG_DEBUG, "Group of VOP start");
- else if(startcode==0x1B4) av_log(s->avctx, AV_LOG_DEBUG, "Video Session Error");
- else if(startcode==0x1B5) av_log(s->avctx, AV_LOG_DEBUG, "Visual Object Start");
- else if(startcode==0x1B6) av_log(s->avctx, AV_LOG_DEBUG, "Video Object Plane start");
- else if(startcode==0x1B7) av_log(s->avctx, AV_LOG_DEBUG, "slice start");
- else if(startcode==0x1B8) av_log(s->avctx, AV_LOG_DEBUG, "extension start");
- else if(startcode==0x1B9) av_log(s->avctx, AV_LOG_DEBUG, "fgs start");
- else if(startcode==0x1BA) av_log(s->avctx, AV_LOG_DEBUG, "FBA Object start");
- else if(startcode==0x1BB) av_log(s->avctx, AV_LOG_DEBUG, "FBA Object Plane start");
- else if(startcode==0x1BC) av_log(s->avctx, AV_LOG_DEBUG, "Mesh Object start");
- else if(startcode==0x1BD) av_log(s->avctx, AV_LOG_DEBUG, "Mesh Object Plane start");
- else if(startcode==0x1BE) av_log(s->avctx, AV_LOG_DEBUG, "Still Texture Object start");
- else if(startcode==0x1BF) av_log(s->avctx, AV_LOG_DEBUG, "Texture Spatial Layer start");
- else if(startcode==0x1C0) av_log(s->avctx, AV_LOG_DEBUG, "Texture SNR Layer start");
- else if(startcode==0x1C1) av_log(s->avctx, AV_LOG_DEBUG, "Texture Tile start");
- else if(startcode==0x1C2) av_log(s->avctx, AV_LOG_DEBUG, "Texture Shape Layer start");
- else if(startcode==0x1C3) av_log(s->avctx, AV_LOG_DEBUG, "stuffing start");
- else if(startcode<=0x1C5) av_log(s->avctx, AV_LOG_DEBUG, "reserved");
- else if(startcode<=0x1FF) av_log(s->avctx, AV_LOG_DEBUG, "System start");
+ if (startcode <= 0x11F)
+ av_log(s->avctx, AV_LOG_DEBUG, "Video Object Start");
+ else if (startcode <= 0x12F)
+ av_log(s->avctx, AV_LOG_DEBUG, "Video Object Layer Start");
+ else if (startcode <= 0x13F)
+ av_log(s->avctx, AV_LOG_DEBUG, "Reserved");
+ else if (startcode <= 0x15F)
+ av_log(s->avctx, AV_LOG_DEBUG, "FGS bp start");
+ else if (startcode <= 0x1AF)
+ av_log(s->avctx, AV_LOG_DEBUG, "Reserved");
+ else if (startcode == 0x1B0)
+ av_log(s->avctx, AV_LOG_DEBUG, "Visual Object Seq Start");
+ else if (startcode == 0x1B1)
+ av_log(s->avctx, AV_LOG_DEBUG, "Visual Object Seq End");
+ else if (startcode == 0x1B2)
+ av_log(s->avctx, AV_LOG_DEBUG, "User Data");
+ else if (startcode == 0x1B3)
+ av_log(s->avctx, AV_LOG_DEBUG, "Group of VOP start");
+ else if (startcode == 0x1B4)
+ av_log(s->avctx, AV_LOG_DEBUG, "Video Session Error");
+ else if (startcode == 0x1B5)
+ av_log(s->avctx, AV_LOG_DEBUG, "Visual Object Start");
+ else if (startcode == 0x1B6)
+ av_log(s->avctx, AV_LOG_DEBUG, "Video Object Plane start");
+ else if (startcode == 0x1B7)
+ av_log(s->avctx, AV_LOG_DEBUG, "slice start");
+ else if (startcode == 0x1B8)
+ av_log(s->avctx, AV_LOG_DEBUG, "extension start");
+ else if (startcode == 0x1B9)
+ av_log(s->avctx, AV_LOG_DEBUG, "fgs start");
+ else if (startcode == 0x1BA)
+ av_log(s->avctx, AV_LOG_DEBUG, "FBA Object start");
+ else if (startcode == 0x1BB)
+ av_log(s->avctx, AV_LOG_DEBUG, "FBA Object Plane start");
+ else if (startcode == 0x1BC)
+ av_log(s->avctx, AV_LOG_DEBUG, "Mesh Object start");
+ else if (startcode == 0x1BD)
+ av_log(s->avctx, AV_LOG_DEBUG, "Mesh Object Plane start");
+ else if (startcode == 0x1BE)
+ av_log(s->avctx, AV_LOG_DEBUG, "Still Texture Object start");
+ else if (startcode == 0x1BF)
+ av_log(s->avctx, AV_LOG_DEBUG, "Texture Spatial Layer start");
+ else if (startcode == 0x1C0)
+ av_log(s->avctx, AV_LOG_DEBUG, "Texture SNR Layer start");
+ else if (startcode == 0x1C1)
+ av_log(s->avctx, AV_LOG_DEBUG, "Texture Tile start");
+ else if (startcode == 0x1C2)
+ av_log(s->avctx, AV_LOG_DEBUG, "Texture Shape Layer start");
+ else if (startcode == 0x1C3)
+ av_log(s->avctx, AV_LOG_DEBUG, "stuffing start");
+ else if (startcode <= 0x1C5)
+ av_log(s->avctx, AV_LOG_DEBUG, "reserved");
+ else if (startcode <= 0x1FF)
+ av_log(s->avctx, AV_LOG_DEBUG, "System start");
av_log(s->avctx, AV_LOG_DEBUG, " at %d\n", get_bits_count(gb));
}
- if(startcode >= 0x120 && startcode <= 0x12F){
- if(decode_vol_header(s, gb) < 0)
+ if (startcode >= 0x120 && startcode <= 0x12F) {
+ if (decode_vol_header(ctx, gb) < 0)
return -1;
- }
- else if(startcode == USER_DATA_STARTCODE){
- decode_user_data(s, gb);
- }
- else if(startcode == GOP_STARTCODE){
+ } else if (startcode == USER_DATA_STARTCODE) {
+ decode_user_data(ctx, gb);
+ } else if (startcode == GOP_STARTCODE) {
mpeg4_decode_gop_header(s, gb);
- }
- else if(startcode == VOS_STARTCODE){
+ } else if (startcode == VOS_STARTCODE) {
mpeg4_decode_profile_level(s, gb);
- }
- else if(startcode == VOP_STARTCODE){
+ } else if (startcode == VOP_STARTCODE) {
break;
}
align_get_bits(gb);
startcode = 0xff;
}
+
end:
- if(s->flags& CODEC_FLAG_LOW_DELAY)
- s->low_delay=1;
- s->avctx->has_b_frames= !s->low_delay;
- return decode_vop_header(s, gb);
+ if (s->flags & CODEC_FLAG_LOW_DELAY)
+ s->low_delay = 1;
+ s->avctx->has_b_frames = !s->low_delay;
+
+ return decode_vop_header(ctx, gb);
}
av_cold void ff_mpeg4videodec_static_init(void) {
@@ -2283,42 +2609,101 @@
INIT_VLC_RL(ff_rvlc_rl_inter, 1072);
INIT_VLC_RL(ff_rvlc_rl_intra, 1072);
INIT_VLC_STATIC(&dc_lum, DC_VLC_BITS, 10 /* 13 */,
- &ff_mpeg4_DCtab_lum[0][1], 2, 1,
- &ff_mpeg4_DCtab_lum[0][0], 2, 1, 512);
+ &ff_mpeg4_DCtab_lum[0][1], 2, 1,
+ &ff_mpeg4_DCtab_lum[0][0], 2, 1, 512);
INIT_VLC_STATIC(&dc_chrom, DC_VLC_BITS, 10 /* 13 */,
- &ff_mpeg4_DCtab_chrom[0][1], 2, 1,
- &ff_mpeg4_DCtab_chrom[0][0], 2, 1, 512);
+ &ff_mpeg4_DCtab_chrom[0][1], 2, 1,
+ &ff_mpeg4_DCtab_chrom[0][0], 2, 1, 512);
INIT_VLC_STATIC(&sprite_trajectory, SPRITE_TRAJ_VLC_BITS, 15,
- &ff_sprite_trajectory_tab[0][1], 4, 2,
- &ff_sprite_trajectory_tab[0][0], 4, 2, 128);
+ &ff_sprite_trajectory_tab[0][1], 4, 2,
+ &ff_sprite_trajectory_tab[0][0], 4, 2, 128);
INIT_VLC_STATIC(&mb_type_b_vlc, MB_TYPE_B_VLC_BITS, 4,
- &ff_mb_type_b_tab[0][1], 2, 1,
- &ff_mb_type_b_tab[0][0], 2, 1, 16);
+ &ff_mb_type_b_tab[0][1], 2, 1,
+ &ff_mb_type_b_tab[0][0], 2, 1, 16);
done = 1;
}
}
+int ff_mpeg4_frame_end(AVCodecContext *avctx, const uint8_t *buf, int buf_size)
+{
+ Mpeg4DecContext *ctx = avctx->priv_data;
+ MpegEncContext *s = &ctx->m;
+
+ /* divx 5.01+ bitstream reorder stuff */
+ /* Since this clobbers the input buffer and hwaccel codecs still need the
+ * data during hwaccel->end_frame we should not do this any earlier */
+ if (s->divx_packed) {
+ int current_pos = s->gb.buffer == s->bitstream_buffer ? 0 : (get_bits_count(&s->gb) >> 3);
+ int startcode_found = 0;
+
+ if (buf_size - current_pos > 7) {
+
+ int i;
+ for (i = current_pos; i < buf_size - 4; i++)
+
+ if (buf[i] == 0 &&
+ buf[i + 1] == 0 &&
+ buf[i + 2] == 1 &&
+ buf[i + 3] == 0xB6) {
+ startcode_found = !(buf[i + 4] & 0x40);
+ break;
+ }
+ }
+
+ if (startcode_found) {
+ av_fast_malloc(&s->bitstream_buffer,
+ &s->allocated_bitstream_buffer_size,
+ buf_size - current_pos +
+ FF_INPUT_BUFFER_PADDING_SIZE);
+ if (!s->bitstream_buffer)
+ return AVERROR(ENOMEM);
+ memcpy(s->bitstream_buffer, buf + current_pos,
+ buf_size - current_pos);
+ s->bitstream_buffer_size = buf_size - current_pos;
+ }
+ }
+
+ return 0;
+}
+
+static int mpeg4_update_thread_context(AVCodecContext *dst,
+ const AVCodecContext *src)
+{
+ Mpeg4DecContext *s = dst->priv_data;
+ const Mpeg4DecContext *s1 = src->priv_data;
+
+ int ret = ff_mpeg_update_thread_context(dst, src);
+
+ if (ret < 0)
+ return ret;
+
+ memcpy(((uint8_t*)s) + sizeof(MpegEncContext), ((uint8_t*)s1) + sizeof(MpegEncContext), sizeof(Mpeg4DecContext) - sizeof(MpegEncContext));
+
+ return 0;
+}
+
static av_cold int decode_init(AVCodecContext *avctx)
{
- MpegEncContext *s = avctx->priv_data;
+ Mpeg4DecContext *ctx = avctx->priv_data;
+ MpegEncContext *s = &ctx->m;
int ret;
- s->divx_version=
- s->divx_build=
- s->xvid_build=
- s->lavc_build= -1;
+ ctx->divx_version =
+ ctx->divx_build =
+ ctx->xvid_build =
+ ctx->lavc_build = -1;
- if((ret=ff_h263_decode_init(avctx)) < 0)
+ if ((ret = ff_h263_decode_init(avctx)) < 0)
return ret;
ff_mpeg4videodec_static_init();
s->h263_pred = 1;
- s->low_delay = 0; //default, might be overridden in the vol header during header parsing
- s->decode_mb= mpeg4_decode_mb;
- s->time_increment_bits = 4; /* default value for broken headers */
- avctx->chroma_sample_location = AVCHROMA_LOC_LEFT;
+ s->low_delay = 0; /* default, might be overridden in the vol header during header parsing */
+ s->decode_mb = mpeg4_decode_mb;
+ ctx->time_increment_bits = 4; /* default value for broken headers */
+ avctx->chroma_sample_location = AVCHROMA_LOC_LEFT;
avctx->internal->allocate_progress = 1;
return 0;
@@ -2369,7 +2754,7 @@
.long_name = NULL_IF_CONFIG_SMALL("MPEG-4 part 2"),
.type = AVMEDIA_TYPE_VIDEO,
.id = AV_CODEC_ID_MPEG4,
- .priv_data_size = sizeof(MpegEncContext),
+ .priv_data_size = sizeof(Mpeg4DecContext),
.init = decode_init,
.close = ff_h263_decode_end,
.decode = ff_h263_decode_frame,
@@ -2380,7 +2765,7 @@
.max_lowres = 3,
.pix_fmts = ff_h263_hwaccel_pixfmt_list_420,
.profiles = NULL_IF_CONFIG_SMALL(mpeg4_video_profiles),
- .update_thread_context = ONLY_IF_THREADS_ENABLED(ff_mpeg_update_thread_context),
+ .update_thread_context = ONLY_IF_THREADS_ENABLED(mpeg4_update_thread_context),
.priv_class = &mpeg4_class,
};
@@ -2397,7 +2782,7 @@
.decode = ff_h263_decode_frame,
.capabilities = CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED | CODEC_CAP_DELAY |
CODEC_CAP_HWACCEL_VDPAU,
- .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_VDPAU_MPEG4,
+ .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_VDPAU_MPEG4,
AV_PIX_FMT_NONE },
.priv_class = &mpeg4_vdpau_class,
};
diff --git a/libavcodec/mpeg4videoenc.c b/libavcodec/mpeg4videoenc.c
index db05b4b..14c6e8f 100644
--- a/libavcodec/mpeg4videoenc.c
+++ b/libavcodec/mpeg4videoenc.c
@@ -27,63 +27,66 @@
#include "h263.h"
#include "mpeg4video.h"
-//The uni_DCtab_* tables below contain unified bits+length tables to encode DC
-//differences in mpeg4. Unified in the sense that the specification specifies
-//this encoding in several steps.
-static uint8_t uni_DCtab_lum_len[512];
-static uint8_t uni_DCtab_chrom_len[512];
+/* The uni_DCtab_* tables below contain unified bits+length tables to encode DC
+ * differences in mpeg4. Unified in the sense that the specification specifies
+ * this encoding in several steps. */
+static uint8_t uni_DCtab_lum_len[512];
+static uint8_t uni_DCtab_chrom_len[512];
static uint16_t uni_DCtab_lum_bits[512];
static uint16_t uni_DCtab_chrom_bits[512];
-//unified encoding tables for run length encoding of coefficients
-//unified in the sense that the specification specifies the encoding in several steps.
-static uint32_t uni_mpeg4_intra_rl_bits[64*64*2*2];
-static uint8_t uni_mpeg4_intra_rl_len [64*64*2*2];
-static uint32_t uni_mpeg4_inter_rl_bits[64*64*2*2];
-static uint8_t uni_mpeg4_inter_rl_len [64*64*2*2];
-//#define UNI_MPEG4_ENC_INDEX(last,run,level) ((last)*128 + (run)*256 + (level))
-//#define UNI_MPEG4_ENC_INDEX(last,run,level) ((last)*128*64 + (run) + (level)*64)
-#define UNI_MPEG4_ENC_INDEX(last,run,level) ((last)*128*64 + (run)*128 + (level))
+/* Unified encoding tables for run length encoding of coefficients.
+ * Unified in the sense that the specification specifies the encoding in several steps. */
+static uint32_t uni_mpeg4_intra_rl_bits[64 * 64 * 2 * 2];
+static uint8_t uni_mpeg4_intra_rl_len[64 * 64 * 2 * 2];
+static uint32_t uni_mpeg4_inter_rl_bits[64 * 64 * 2 * 2];
+static uint8_t uni_mpeg4_inter_rl_len[64 * 64 * 2 * 2];
+
+//#define UNI_MPEG4_ENC_INDEX(last, run, level) ((last) * 128 + (run) * 256 + (level))
+//#define UNI_MPEG4_ENC_INDEX(last, run, level) ((last) * 128 * 64 + (run) + (level) * 64)
+#define UNI_MPEG4_ENC_INDEX(last, run, level) ((last) * 128 * 64 + (run) * 128 + (level))
/* mpeg4
-inter
-max level: 24/6
-max run: 53/63
-
-intra
-max level: 53/16
-max run: 29/41
-*/
-
+ * inter
+ * max level: 24/6
+ * max run: 53/63
+ *
+ * intra
+ * max level: 53/16
+ * max run: 29/41
+ */
/**
* Return the number of bits that encoding the 8x8 block in block would need.
* @param[in] block_last_index last index in scantable order that refers to a non zero element in block.
*/
-static inline int get_block_rate(MpegEncContext * s, int16_t block[64], int block_last_index, uint8_t scantable[64]){
- int last=0;
+static inline int get_block_rate(MpegEncContext *s, int16_t block[64],
+ int block_last_index, uint8_t scantable[64])
+{
+ int last = 0;
int j;
- int rate=0;
+ int rate = 0;
- for(j=1; j<=block_last_index; j++){
- const int index= scantable[j];
- int level= block[index];
- if(level){
- level+= 64;
- if((level&(~127)) == 0){
- if(j<block_last_index) rate+= s->intra_ac_vlc_length [UNI_AC_ENC_INDEX(j-last-1, level)];
- else rate+= s->intra_ac_vlc_last_length[UNI_AC_ENC_INDEX(j-last-1, level)];
- }else
+ for (j = 1; j <= block_last_index; j++) {
+ const int index = scantable[j];
+ int level = block[index];
+ if (level) {
+ level += 64;
+ if ((level & (~127)) == 0) {
+ if (j < block_last_index)
+ rate += s->intra_ac_vlc_length[UNI_AC_ENC_INDEX(j - last - 1, level)];
+ else
+ rate += s->intra_ac_vlc_last_length[UNI_AC_ENC_INDEX(j - last - 1, level)];
+ } else
rate += s->ac_esc_length;
- last= j;
+ last = j;
}
}
return rate;
}
-
/**
* Restore the ac coefficients in block that have been changed by decide_ac_pred().
* This function also restores s->block_last_index.
@@ -92,25 +95,25 @@
* @param[out] st scantable for each 8x8 block
* @param[in] zigzag_last_index index referring to the last non zero coefficient in zigzag order
*/
-static inline void restore_ac_coeffs(MpegEncContext * s, int16_t block[6][64], const int dir[6], uint8_t *st[6], const int zigzag_last_index[6])
+static inline void restore_ac_coeffs(MpegEncContext *s, int16_t block[6][64],
+ const int dir[6], uint8_t *st[6],
+ const int zigzag_last_index[6])
{
int i, n;
- memcpy(s->block_last_index, zigzag_last_index, sizeof(int)*6);
+ memcpy(s->block_last_index, zigzag_last_index, sizeof(int) * 6);
- for(n=0; n<6; n++){
+ for (n = 0; n < 6; n++) {
int16_t *ac_val = s->ac_val[0][0] + s->block_index[n] * 16;
- st[n]= s->intra_scantable.permutated;
- if(dir[n]){
+ st[n] = s->intra_scantable.permutated;
+ if (dir[n]) {
/* top prediction */
- for(i=1; i<8; i++){
- block[n][s->dsp.idct_permutation[i ]] = ac_val[i+8];
- }
- }else{
+ for (i = 1; i < 8; i++)
+ block[n][s->dsp.idct_permutation[i]] = ac_val[i + 8];
+ } else {
/* left prediction */
- for(i=1; i<8; i++){
- block[n][s->dsp.idct_permutation[i<<3]]= ac_val[i ];
- }
+ for (i = 1; i < 8; i++)
+ block[n][s->dsp.idct_permutation[i << 3]] = ac_val[i];
}
}
}
@@ -123,77 +126,81 @@
* @param[out] st scantable for each 8x8 block
* @param[out] zigzag_last_index index referring to the last non zero coefficient in zigzag order
*/
-static inline int decide_ac_pred(MpegEncContext * s, int16_t block[6][64], const int dir[6], uint8_t *st[6], int zigzag_last_index[6])
+static inline int decide_ac_pred(MpegEncContext *s, int16_t block[6][64],
+ const int dir[6], uint8_t *st[6],
+ int zigzag_last_index[6])
{
- int score= 0;
+ int score = 0;
int i, n;
- int8_t * const qscale_table = s->current_picture.qscale_table;
+ int8_t *const qscale_table = s->current_picture.qscale_table;
- memcpy(zigzag_last_index, s->block_last_index, sizeof(int)*6);
+ memcpy(zigzag_last_index, s->block_last_index, sizeof(int) * 6);
- for(n=0; n<6; n++){
+ for (n = 0; n < 6; n++) {
int16_t *ac_val, *ac_val1;
- score -= get_block_rate(s, block[n], s->block_last_index[n], s->intra_scantable.permutated);
+ score -= get_block_rate(s, block[n], s->block_last_index[n],
+ s->intra_scantable.permutated);
- ac_val = s->ac_val[0][0] + s->block_index[n] * 16;
- ac_val1= ac_val;
- if(dir[n]){
- const int xy= s->mb_x + s->mb_y*s->mb_stride - s->mb_stride;
+ ac_val = s->ac_val[0][0] + s->block_index[n] * 16;
+ ac_val1 = ac_val;
+ if (dir[n]) {
+ const int xy = s->mb_x + s->mb_y * s->mb_stride - s->mb_stride;
/* top prediction */
- ac_val-= s->block_wrap[n]*16;
- if(s->mb_y==0 || s->qscale == qscale_table[xy] || n==2 || n==3){
+ ac_val -= s->block_wrap[n] * 16;
+ if (s->mb_y == 0 || s->qscale == qscale_table[xy] || n == 2 || n == 3) {
/* same qscale */
- for(i=1; i<8; i++){
- const int level= block[n][s->dsp.idct_permutation[i ]];
- block[n][s->dsp.idct_permutation[i ]] = level - ac_val[i+8];
- ac_val1[i ]= block[n][s->dsp.idct_permutation[i<<3]];
- ac_val1[i+8]= level;
+ for (i = 1; i < 8; i++) {
+ const int level = block[n][s->dsp.idct_permutation[i]];
+ block[n][s->dsp.idct_permutation[i]] = level - ac_val[i + 8];
+ ac_val1[i] = block[n][s->dsp.idct_permutation[i << 3]];
+ ac_val1[i + 8] = level;
}
- }else{
+ } else {
/* different qscale, we must rescale */
- for(i=1; i<8; i++){
- const int level= block[n][s->dsp.idct_permutation[i ]];
- block[n][s->dsp.idct_permutation[i ]] = level - ROUNDED_DIV(ac_val[i + 8]*qscale_table[xy], s->qscale);
- ac_val1[i ]= block[n][s->dsp.idct_permutation[i<<3]];
- ac_val1[i+8]= level;
+ for (i = 1; i < 8; i++) {
+ const int level = block[n][s->dsp.idct_permutation[i]];
+ block[n][s->dsp.idct_permutation[i]] = level - ROUNDED_DIV(ac_val[i + 8] * qscale_table[xy], s->qscale);
+ ac_val1[i] = block[n][s->dsp.idct_permutation[i << 3]];
+ ac_val1[i + 8] = level;
}
}
- st[n]= s->intra_h_scantable.permutated;
- }else{
- const int xy= s->mb_x-1 + s->mb_y*s->mb_stride;
+ st[n] = s->intra_h_scantable.permutated;
+ } else {
+ const int xy = s->mb_x - 1 + s->mb_y * s->mb_stride;
/* left prediction */
- ac_val-= 16;
- if(s->mb_x==0 || s->qscale == qscale_table[xy] || n==1 || n==3){
+ ac_val -= 16;
+ if (s->mb_x == 0 || s->qscale == qscale_table[xy] || n == 1 || n == 3) {
/* same qscale */
- for(i=1; i<8; i++){
- const int level= block[n][s->dsp.idct_permutation[i<<3]];
- block[n][s->dsp.idct_permutation[i<<3]]= level - ac_val[i];
- ac_val1[i ]= level;
- ac_val1[i+8]= block[n][s->dsp.idct_permutation[i ]];
+ for (i = 1; i < 8; i++) {
+ const int level = block[n][s->dsp.idct_permutation[i << 3]];
+ block[n][s->dsp.idct_permutation[i << 3]] = level - ac_val[i];
+ ac_val1[i] = level;
+ ac_val1[i + 8] = block[n][s->dsp.idct_permutation[i]];
}
- }else{
+ } else {
/* different qscale, we must rescale */
- for(i=1; i<8; i++){
- const int level= block[n][s->dsp.idct_permutation[i<<3]];
- block[n][s->dsp.idct_permutation[i<<3]]= level - ROUNDED_DIV(ac_val[i]*qscale_table[xy], s->qscale);
- ac_val1[i ]= level;
- ac_val1[i+8]= block[n][s->dsp.idct_permutation[i ]];
+ for (i = 1; i < 8; i++) {
+ const int level = block[n][s->dsp.idct_permutation[i << 3]];
+ block[n][s->dsp.idct_permutation[i << 3]] = level - ROUNDED_DIV(ac_val[i] * qscale_table[xy], s->qscale);
+ ac_val1[i] = level;
+ ac_val1[i + 8] = block[n][s->dsp.idct_permutation[i]];
}
}
- st[n]= s->intra_v_scantable.permutated;
+ st[n] = s->intra_v_scantable.permutated;
}
- for(i=63; i>0; i--) //FIXME optimize
- if(block[n][ st[n][i] ]) break;
- s->block_last_index[n]= i;
+ for (i = 63; i > 0; i--) // FIXME optimize
+ if (block[n][st[n][i]])
+ break;
+ s->block_last_index[n] = i;
score += get_block_rate(s, block[n], s->block_last_index[n], st[n]);
}
- if(score < 0){
+ if (score < 0) {
return 1;
- }else{
+ } else {
restore_ac_coeffs(s, block, dir, st, zigzag_last_index);
return 0;
}
@@ -202,51 +209,55 @@
/**
* modify mb_type & qscale so that encoding is actually possible in mpeg4
*/
-void ff_clean_mpeg4_qscales(MpegEncContext *s){
+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.qscale_table;
ff_clean_h263_qscales(s);
- if(s->pict_type== AV_PICTURE_TYPE_B){
- int odd=0;
- /* ok, come on, this isn't funny anymore, there's more code for handling this mpeg4 mess than for the actual adaptive quantization */
+ if (s->pict_type == AV_PICTURE_TYPE_B) {
+ int odd = 0;
+ /* ok, come on, this isn't funny anymore, there's more code for
+ * handling this mpeg4 mess than for the actual adaptive quantization */
- for(i=0; i<s->mb_num; i++){
- int mb_xy= s->mb_index2xy[i];
- odd += qscale_table[mb_xy]&1;
+ for (i = 0; i < s->mb_num; i++) {
+ int mb_xy = s->mb_index2xy[i];
+ odd += qscale_table[mb_xy] & 1;
}
- if(2*odd > s->mb_num) odd=1;
- else odd=0;
+ if (2 * odd > s->mb_num)
+ odd = 1;
+ else
+ odd = 0;
- for(i=0; i<s->mb_num; i++){
- int mb_xy= s->mb_index2xy[i];
- if((qscale_table[mb_xy]&1) != odd)
+ for (i = 0; i < s->mb_num; i++) {
+ int mb_xy = s->mb_index2xy[i];
+ if ((qscale_table[mb_xy] & 1) != odd)
qscale_table[mb_xy]++;
- if(qscale_table[mb_xy] > 31)
- qscale_table[mb_xy]= 31;
+ if (qscale_table[mb_xy] > 31)
+ qscale_table[mb_xy] = 31;
}
- for(i=1; i<s->mb_num; i++){
- int mb_xy= s->mb_index2xy[i];
- if(qscale_table[mb_xy] != qscale_table[s->mb_index2xy[i-1]] && (s->mb_type[mb_xy]&CANDIDATE_MB_TYPE_DIRECT)){
- s->mb_type[mb_xy]|= CANDIDATE_MB_TYPE_BIDIR;
+ for (i = 1; i < s->mb_num; i++) {
+ int mb_xy = s->mb_index2xy[i];
+ if (qscale_table[mb_xy] != qscale_table[s->mb_index2xy[i - 1]] &&
+ (s->mb_type[mb_xy] & CANDIDATE_MB_TYPE_DIRECT)) {
+ s->mb_type[mb_xy] |= CANDIDATE_MB_TYPE_BIDIR;
}
}
}
}
-
/**
* 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)
+static inline void mpeg4_encode_dc(PutBitContext *s, int level, int n)
{
#if 1
/* DC will overflow if level is outside the [-255,255] range. */
- level+=256;
+ level += 256;
if (n < 4) {
/* luminance */
put_bits(s, uni_DCtab_lum_len[level], uni_DCtab_lum_bits[level]);
@@ -258,7 +269,7 @@
int size, v;
/* find number of bits */
size = 0;
- v = abs(level);
+ v = abs(level);
while (v) {
v >>= 1;
size++;
@@ -283,85 +294,98 @@
#endif
}
-static inline int mpeg4_get_dc_length(int level, int n){
- if (n < 4) {
+static inline int mpeg4_get_dc_length(int level, int n)
+{
+ if (n < 4)
return uni_DCtab_lum_len[level + 256];
- } else {
+ else
return uni_DCtab_chrom_len[level + 256];
- }
}
/**
* Encode an 8x8 block.
* @param n block index (0-3 are luma, 4-5 are chroma)
*/
-static inline void mpeg4_encode_block(MpegEncContext * s, int16_t * block, int n, int intra_dc,
- uint8_t *scan_table, PutBitContext *dc_pb, PutBitContext *ac_pb)
+static inline void mpeg4_encode_block(MpegEncContext *s,
+ int16_t *block, int n, int intra_dc,
+ uint8_t *scan_table, PutBitContext *dc_pb,
+ PutBitContext *ac_pb)
{
int i, last_non_zero;
uint32_t *bits_tab;
uint8_t *len_tab;
const int last_index = s->block_last_index[n];
- if (s->mb_intra) { //Note gcc (3.2.1 at least) will optimize this away
+ if (s->mb_intra) { // Note gcc (3.2.1 at least) will optimize this away
/* mpeg4 based DC predictor */
mpeg4_encode_dc(dc_pb, intra_dc, n);
- if(last_index<1) return;
+ if (last_index < 1)
+ return;
i = 1;
- bits_tab= uni_mpeg4_intra_rl_bits;
- len_tab = uni_mpeg4_intra_rl_len;
+ bits_tab = uni_mpeg4_intra_rl_bits;
+ len_tab = uni_mpeg4_intra_rl_len;
} else {
- if(last_index<0) return;
+ if (last_index < 0)
+ return;
i = 0;
- bits_tab= uni_mpeg4_inter_rl_bits;
- len_tab = uni_mpeg4_inter_rl_len;
+ bits_tab = uni_mpeg4_inter_rl_bits;
+ len_tab = uni_mpeg4_inter_rl_len;
}
/* AC coefs */
last_non_zero = i - 1;
for (; i < last_index; i++) {
- int level = block[ scan_table[i] ];
+ int level = block[scan_table[i]];
if (level) {
int run = i - last_non_zero - 1;
- level+=64;
- if((level&(~127)) == 0){
- const int index= UNI_MPEG4_ENC_INDEX(0, run, level);
+ level += 64;
+ if ((level & (~127)) == 0) {
+ const int index = UNI_MPEG4_ENC_INDEX(0, run, level);
put_bits(ac_pb, len_tab[index], bits_tab[index]);
- }else{ //ESC3
- put_bits(ac_pb, 7+2+1+6+1+12+1, (3<<23)+(3<<21)+(0<<20)+(run<<14)+(1<<13)+(((level-64)&0xfff)<<1)+1);
+ } else { // ESC3
+ put_bits(ac_pb,
+ 7 + 2 + 1 + 6 + 1 + 12 + 1,
+ (3 << 23) + (3 << 21) + (0 << 20) + (run << 14) +
+ (1 << 13) + (((level - 64) & 0xfff) << 1) + 1);
}
last_non_zero = i;
}
}
- /*if(i<=last_index)*/{
- int level = block[ scan_table[i] ];
- int run = i - last_non_zero - 1;
- level+=64;
- if((level&(~127)) == 0){
- const int index= UNI_MPEG4_ENC_INDEX(1, run, level);
+ /* if (i <= last_index) */ {
+ int level = block[scan_table[i]];
+ int run = i - last_non_zero - 1;
+ level += 64;
+ if ((level & (~127)) == 0) {
+ const int index = UNI_MPEG4_ENC_INDEX(1, run, level);
put_bits(ac_pb, len_tab[index], bits_tab[index]);
- }else{ //ESC3
- 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 { // ESC3
+ 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);
}
}
}
-static int mpeg4_get_block_length(MpegEncContext * s, int16_t * block, int n, int intra_dc,
- uint8_t *scan_table)
+static int mpeg4_get_block_length(MpegEncContext *s,
+ int16_t *block, int n,
+ int intra_dc, uint8_t *scan_table)
{
int i, last_non_zero;
uint8_t *len_tab;
const int last_index = s->block_last_index[n];
- int len=0;
+ int len = 0;
- if (s->mb_intra) { //Note gcc (3.2.1 at least) will optimize this away
+ if (s->mb_intra) { // Note gcc (3.2.1 at least) will optimize this away
/* mpeg4 based DC predictor */
len += mpeg4_get_dc_length(intra_dc, n);
- if(last_index<1) return len;
+ if (last_index < 1)
+ return len;
i = 1;
len_tab = uni_mpeg4_intra_rl_len;
} else {
- if(last_index<0) return 0;
+ if (last_index < 0)
+ return 0;
i = 0;
len_tab = uni_mpeg4_inter_rl_len;
}
@@ -369,82 +393,88 @@
/* AC coefs */
last_non_zero = i - 1;
for (; i < last_index; i++) {
- int level = block[ scan_table[i] ];
+ int level = block[scan_table[i]];
if (level) {
int run = i - last_non_zero - 1;
- level+=64;
- if((level&(~127)) == 0){
- const int index= UNI_MPEG4_ENC_INDEX(0, run, level);
+ level += 64;
+ if ((level & (~127)) == 0) {
+ const int index = UNI_MPEG4_ENC_INDEX(0, run, level);
len += len_tab[index];
- }else{ //ESC3
- len += 7+2+1+6+1+12+1;
+ } else { // ESC3
+ len += 7 + 2 + 1 + 6 + 1 + 12 + 1;
}
last_non_zero = i;
}
}
- /*if(i<=last_index)*/{
- int level = block[ scan_table[i] ];
- int run = i - last_non_zero - 1;
- level+=64;
- if((level&(~127)) == 0){
- const int index= UNI_MPEG4_ENC_INDEX(1, run, level);
+ /* if (i <= last_index) */ {
+ int level = block[scan_table[i]];
+ int run = i - last_non_zero - 1;
+ level += 64;
+ if ((level & (~127)) == 0) {
+ const int index = UNI_MPEG4_ENC_INDEX(1, run, level);
len += len_tab[index];
- }else{ //ESC3
- len += 7+2+1+6+1+12+1;
+ } else { // ESC3
+ len += 7 + 2 + 1 + 6 + 1 + 12 + 1;
}
}
return len;
}
-static inline void mpeg4_encode_blocks(MpegEncContext * s, int16_t block[6][64], int intra_dc[6],
- uint8_t **scan_table, PutBitContext *dc_pb, PutBitContext *ac_pb){
+static inline void mpeg4_encode_blocks(MpegEncContext *s, int16_t block[6][64],
+ int intra_dc[6], uint8_t **scan_table,
+ PutBitContext *dc_pb,
+ PutBitContext *ac_pb)
+{
int i;
- if(scan_table){
- if(s->flags2 & CODEC_FLAG2_NO_OUTPUT){
- for (i = 0; i < 6; i++) {
- skip_put_bits(&s->pb, mpeg4_get_block_length(s, block[i], i, intra_dc[i], scan_table[i]));
- }
- }else{
+ if (scan_table) {
+ if (s->flags2 & CODEC_FLAG2_NO_OUTPUT) {
+ for (i = 0; i < 6; i++)
+ skip_put_bits(&s->pb,
+ mpeg4_get_block_length(s, block[i], i,
+ intra_dc[i], scan_table[i]));
+ } else {
/* encode each block */
- for (i = 0; i < 6; i++) {
- mpeg4_encode_block(s, block[i], i, intra_dc[i], scan_table[i], dc_pb, ac_pb);
- }
+ for (i = 0; i < 6; i++)
+ mpeg4_encode_block(s, block[i], i,
+ intra_dc[i], scan_table[i], dc_pb, ac_pb);
}
- }else{
- if(s->flags2 & CODEC_FLAG2_NO_OUTPUT){
- for (i = 0; i < 6; i++) {
- skip_put_bits(&s->pb, mpeg4_get_block_length(s, block[i], i, 0, s->intra_scantable.permutated));
- }
- }else{
+ } else {
+ if (s->flags2 & CODEC_FLAG2_NO_OUTPUT) {
+ for (i = 0; i < 6; i++)
+ skip_put_bits(&s->pb,
+ mpeg4_get_block_length(s, block[i], i, 0,
+ s->intra_scantable.permutated));
+ } else {
/* encode each block */
- for (i = 0; i < 6; i++) {
- mpeg4_encode_block(s, block[i], i, 0, s->intra_scantable.permutated, dc_pb, ac_pb);
- }
+ for (i = 0; i < 6; i++)
+ mpeg4_encode_block(s, block[i], i, 0,
+ s->intra_scantable.permutated, dc_pb, ac_pb);
}
}
}
-static inline int get_b_cbp(MpegEncContext * s, int16_t block[6][64],
+static inline int get_b_cbp(MpegEncContext *s, int16_t block[6][64],
int motion_x, int motion_y, int mb_type)
{
int cbp = 0, i;
if (s->mpv_flags & FF_MPV_FLAG_CBP_RD) {
- int score = 0;
+ int score = 0;
const int lambda = s->lambda2 >> (FF_LAMBDA_SHIFT - 6);
- for (i = 0; i < 6; i++)
+ 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 -= 4; // 2 * MV + mb_type + cbp bit
zero_score *= lambda;
if (zero_score <= score)
@@ -466,62 +496,61 @@
return cbp;
}
-//FIXME this is duplicated to h263.c
-static const int dquant_code[5]= {1,0,9,2,3};
+// FIXME this is duplicated to h263.c
+static const int dquant_code[5] = { 1, 0, 9, 2, 3 };
-void ff_mpeg4_encode_mb(MpegEncContext * s,
- int16_t block[6][64],
+void ff_mpeg4_encode_mb(MpegEncContext *s, int16_t block[6][64],
int motion_x, int motion_y)
{
int cbpc, cbpy, pred_x, pred_y;
- PutBitContext * const pb2 = s->data_partitioning ? &s->pb2 : &s->pb;
- PutBitContext * const tex_pb = s->data_partitioning && s->pict_type!=AV_PICTURE_TYPE_B ? &s->tex_pb : &s->pb;
- PutBitContext * const dc_pb = s->data_partitioning && s->pict_type!=AV_PICTURE_TYPE_I ? &s->pb2 : &s->pb;
- const int interleaved_stats= (s->flags&CODEC_FLAG_PASS1) && !s->data_partitioning ? 1 : 0;
+ PutBitContext *const pb2 = s->data_partitioning ? &s->pb2 : &s->pb;
+ PutBitContext *const tex_pb = s->data_partitioning && s->pict_type != AV_PICTURE_TYPE_B ? &s->tex_pb : &s->pb;
+ PutBitContext *const dc_pb = s->data_partitioning && s->pict_type != AV_PICTURE_TYPE_I ? &s->pb2 : &s->pb;
+ const int interleaved_stats = (s->flags & CODEC_FLAG_PASS1) && !s->data_partitioning ? 1 : 0;
if (!s->mb_intra) {
int i, cbp;
- if(s->pict_type==AV_PICTURE_TYPE_B){
- static const int mb_type_table[8]= {-1, 3, 2, 1,-1,-1,-1, 0}; /* convert from mv_dir to type */
- int mb_type= mb_type_table[s->mv_dir];
+ if (s->pict_type == AV_PICTURE_TYPE_B) {
+ /* convert from mv_dir to type */
+ static const int mb_type_table[8] = { -1, 3, 2, 1, -1, -1, -1, 0 };
+ int mb_type = mb_type_table[s->mv_dir];
- if(s->mb_x==0){
- for(i=0; i<2; i++){
- s->last_mv[i][0][0]=
- s->last_mv[i][0][1]=
- s->last_mv[i][1][0]=
- s->last_mv[i][1][1]= 0;
- }
+ if (s->mb_x == 0) {
+ for (i = 0; i < 2; i++)
+ s->last_mv[i][0][0] =
+ s->last_mv[i][0][1] =
+ s->last_mv[i][1][0] =
+ s->last_mv[i][1][1] = 0;
}
- av_assert2(s->dquant>=-2 && s->dquant<=2);
- av_assert2((s->dquant&1)==0);
- av_assert2(mb_type>=0);
+ av_assert2(s->dquant >= -2 && s->dquant <= 2);
+ av_assert2((s->dquant & 1) == 0);
+ av_assert2(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.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]=
- s->mv[1][0][0]=
- s->mv[1][0][1]= 0;
- s->mv_dir= MV_DIR_FORWARD; //doesn't matter
+ s->mv[0][0][0] =
+ s->mv[0][0][1] =
+ s->mv[1][0][0] =
+ s->mv[1][0][1] = 0;
+ s->mv_dir = MV_DIR_FORWARD; // doesn't matter
s->qscale -= s->dquant;
-// s->mb_skipped=1;
+// s->mb_skipped = 1;
return;
}
- cbp= get_b_cbp(s, block, motion_x, motion_y, mb_type);
+ cbp = get_b_cbp(s, block, motion_x, motion_y, mb_type);
- if ((cbp | motion_x | motion_y | mb_type) ==0) {
+ if ((cbp | motion_x | motion_y | mb_type) == 0) {
/* direct MB with MV={0,0} */
- av_assert2(s->dquant==0);
+ av_assert2(s->dquant == 0);
put_bits(&s->pb, 1, 1); /* mb not coded modb1=1 */
- if(interleaved_stats){
+ if (interleaved_stats) {
s->misc_bits++;
s->last_bits++;
}
@@ -529,149 +558,160 @@
return;
}
- put_bits(&s->pb, 1, 0); /* mb coded modb1=0 */
- put_bits(&s->pb, 1, cbp ? 0 : 1); /* modb2 */ //FIXME merge
- put_bits(&s->pb, mb_type+1, 1); // this table is so simple that we don't need it :)
- if(cbp) put_bits(&s->pb, 6, cbp);
+ put_bits(&s->pb, 1, 0); /* mb coded modb1=0 */
+ put_bits(&s->pb, 1, cbp ? 0 : 1); /* modb2 */ // FIXME merge
+ put_bits(&s->pb, mb_type + 1, 1); // this table is so simple that we don't need it :)
+ if (cbp)
+ put_bits(&s->pb, 6, cbp);
- if(cbp && mb_type){
- if(s->dquant)
- put_bits(&s->pb, 2, (s->dquant>>2)+3);
+ if (cbp && mb_type) {
+ if (s->dquant)
+ put_bits(&s->pb, 2, (s->dquant >> 2) + 3);
else
put_bits(&s->pb, 1, 0);
- }else
+ } else
s->qscale -= s->dquant;
- if(!s->progressive_sequence){
- if(cbp)
+ if (!s->progressive_sequence) {
+ if (cbp)
put_bits(&s->pb, 1, s->interlaced_dct);
- if(mb_type) // not direct mode
+ if (mb_type) // not direct mode
put_bits(&s->pb, 1, s->mv_type == MV_TYPE_FIELD);
}
- if(interleaved_stats){
- s->misc_bits+= get_bits_diff(s);
- }
+ if (interleaved_stats)
+ s->misc_bits += get_bits_diff(s);
- if(mb_type == 0){
+ if (!mb_type) {
av_assert2(s->mv_dir & MV_DIRECT);
ff_h263_encode_motion_vector(s, motion_x, motion_y, 1);
s->b_count++;
s->f_count++;
- }else{
+ } else {
av_assert2(mb_type > 0 && mb_type < 4);
- if(s->mv_type != MV_TYPE_FIELD){
- if(s->mv_dir & MV_DIR_FORWARD){
- ff_h263_encode_motion_vector(s, s->mv[0][0][0] - s->last_mv[0][0][0],
- s->mv[0][0][1] - s->last_mv[0][0][1], s->f_code);
- s->last_mv[0][0][0]= s->last_mv[0][1][0]= s->mv[0][0][0];
- s->last_mv[0][0][1]= s->last_mv[0][1][1]= s->mv[0][0][1];
+ if (s->mv_type != MV_TYPE_FIELD) {
+ if (s->mv_dir & MV_DIR_FORWARD) {
+ ff_h263_encode_motion_vector(s,
+ s->mv[0][0][0] - s->last_mv[0][0][0],
+ s->mv[0][0][1] - s->last_mv[0][0][1],
+ s->f_code);
+ s->last_mv[0][0][0] =
+ s->last_mv[0][1][0] = s->mv[0][0][0];
+ s->last_mv[0][0][1] =
+ s->last_mv[0][1][1] = s->mv[0][0][1];
s->f_count++;
}
- if(s->mv_dir & MV_DIR_BACKWARD){
- ff_h263_encode_motion_vector(s, s->mv[1][0][0] - s->last_mv[1][0][0],
- s->mv[1][0][1] - s->last_mv[1][0][1], s->b_code);
- s->last_mv[1][0][0]= s->last_mv[1][1][0]= s->mv[1][0][0];
- s->last_mv[1][0][1]= s->last_mv[1][1][1]= s->mv[1][0][1];
+ if (s->mv_dir & MV_DIR_BACKWARD) {
+ ff_h263_encode_motion_vector(s,
+ s->mv[1][0][0] - s->last_mv[1][0][0],
+ s->mv[1][0][1] - s->last_mv[1][0][1],
+ s->b_code);
+ s->last_mv[1][0][0] =
+ s->last_mv[1][1][0] = s->mv[1][0][0];
+ s->last_mv[1][0][1] =
+ s->last_mv[1][1][1] = s->mv[1][0][1];
s->b_count++;
}
- }else{
- if(s->mv_dir & MV_DIR_FORWARD){
+ } else {
+ if (s->mv_dir & MV_DIR_FORWARD) {
put_bits(&s->pb, 1, s->field_select[0][0]);
put_bits(&s->pb, 1, s->field_select[0][1]);
}
- if(s->mv_dir & MV_DIR_BACKWARD){
+ if (s->mv_dir & MV_DIR_BACKWARD) {
put_bits(&s->pb, 1, s->field_select[1][0]);
put_bits(&s->pb, 1, s->field_select[1][1]);
}
- if(s->mv_dir & MV_DIR_FORWARD){
- for(i=0; i<2; i++){
- ff_h263_encode_motion_vector(s, s->mv[0][i][0] - s->last_mv[0][i][0] ,
- s->mv[0][i][1] - s->last_mv[0][i][1]/2, s->f_code);
- s->last_mv[0][i][0]= s->mv[0][i][0];
- s->last_mv[0][i][1]= s->mv[0][i][1]*2;
+ if (s->mv_dir & MV_DIR_FORWARD) {
+ for (i = 0; i < 2; i++) {
+ ff_h263_encode_motion_vector(s,
+ s->mv[0][i][0] - s->last_mv[0][i][0],
+ s->mv[0][i][1] - s->last_mv[0][i][1] / 2,
+ s->f_code);
+ s->last_mv[0][i][0] = s->mv[0][i][0];
+ s->last_mv[0][i][1] = s->mv[0][i][1] * 2;
}
s->f_count++;
}
- if(s->mv_dir & MV_DIR_BACKWARD){
- for(i=0; i<2; i++){
- ff_h263_encode_motion_vector(s, s->mv[1][i][0] - s->last_mv[1][i][0] ,
- s->mv[1][i][1] - s->last_mv[1][i][1]/2, s->b_code);
- s->last_mv[1][i][0]= s->mv[1][i][0];
- s->last_mv[1][i][1]= s->mv[1][i][1]*2;
+ if (s->mv_dir & MV_DIR_BACKWARD) {
+ for (i = 0; i < 2; i++) {
+ ff_h263_encode_motion_vector(s,
+ s->mv[1][i][0] - s->last_mv[1][i][0],
+ s->mv[1][i][1] - s->last_mv[1][i][1] / 2,
+ s->b_code);
+ s->last_mv[1][i][0] = s->mv[1][i][0];
+ s->last_mv[1][i][1] = s->mv[1][i][1] * 2;
}
s->b_count++;
}
}
}
- if(interleaved_stats){
- s->mv_bits+= get_bits_diff(s);
- }
+ if (interleaved_stats)
+ s->mv_bits += get_bits_diff(s);
mpeg4_encode_blocks(s, block, NULL, NULL, NULL, &s->pb);
- if(interleaved_stats){
- s->p_tex_bits+= get_bits_diff(s);
- }
+ if (interleaved_stats)
+ s->p_tex_bits += get_bits_diff(s);
+ } else { /* s->pict_type==AV_PICTURE_TYPE_B */
+ cbp = get_p_cbp(s, block, motion_x, motion_y);
- }else{ /* s->pict_type==AV_PICTURE_TYPE_B */
- cbp= get_p_cbp(s, block, motion_x, motion_y);
-
- if ((cbp | motion_x | motion_y | s->dquant) == 0 && s->mv_type==MV_TYPE_16X16) {
- /* check if the B frames can skip it too, as we must skip it if we skip here
- why didn't they just compress the skip-mb bits instead of reusing them ?! */
- if(s->max_b_frames>0){
+ if ((cbp | motion_x | motion_y | s->dquant) == 0 &&
+ s->mv_type == MV_TYPE_16X16) {
+ /* check if the B frames can skip it too, as we must skip it
+ * if we skip here why didn't they just compress
+ * the skip-mb bits instead of reusing them ?! */
+ if (s->max_b_frames > 0) {
int i;
- int x,y, offset;
+ int x, y, offset;
uint8_t *p_pic;
- x= s->mb_x*16;
- y= s->mb_y*16;
+ x = s->mb_x * 16;
+ y = s->mb_y * 16;
- offset= x + y*s->linesize;
- p_pic = s->new_picture.f.data[0] + offset;
+ offset = x + y * s->linesize;
+ p_pic = s->new_picture.f.data[0] + offset;
- s->mb_skipped=1;
- for(i=0; i<s->max_b_frames; i++){
+ s->mb_skipped = 1;
+ for (i = 0; i < s->max_b_frames; i++) {
uint8_t *b_pic;
int diff;
- Picture *pic= s->reordered_input_picture[i+1];
+ Picture *pic = s->reordered_input_picture[i + 1];
- if (pic == NULL || pic->f.pict_type != AV_PICTURE_TYPE_B)
+ if (!pic || pic->f.pict_type != AV_PICTURE_TYPE_B)
break;
b_pic = pic->f.data[0] + offset;
if (!pic->shared)
- b_pic+= INPLACE_OFFSET;
+ b_pic += INPLACE_OFFSET;
- if(x+16 > s->width || y+16 > s->height){
- int x1,y1;
- int xe= FFMIN(16, s->width - x);
- int ye= FFMIN(16, s->height- y);
- diff=0;
- for(y1=0; y1<ye; y1++){
- for(x1=0; x1<xe; x1++){
- diff+= FFABS(p_pic[x1+y1*s->linesize] - b_pic[x1+y1*s->linesize]);
+ if (x + 16 > s->width || y + 16 > s->height) {
+ int x1, y1;
+ int xe = FFMIN(16, s->width - x);
+ int ye = FFMIN(16, s->height - y);
+ diff = 0;
+ for (y1 = 0; y1 < ye; y1++) {
+ for (x1 = 0; x1 < xe; x1++) {
+ diff += FFABS(p_pic[x1 + y1 * s->linesize] - b_pic[x1 + y1 * s->linesize]);
}
}
- diff= diff*256/(xe*ye);
- }else{
- diff= s->dsp.sad[0](NULL, p_pic, b_pic, s->linesize, 16);
+ diff = diff * 256 / (xe * ye);
+ } else {
+ diff = s->dsp.sad[0](NULL, p_pic, b_pic, s->linesize, 16);
}
- if(diff>s->qscale*70){ //FIXME check that 70 is optimal
- s->mb_skipped=0;
+ if (diff > s->qscale * 70) { // FIXME check that 70 is optimal
+ s->mb_skipped = 0;
break;
}
}
- }else
- s->mb_skipped=1;
+ } else
+ s->mb_skipped = 1;
- if(s->mb_skipped==1){
+ if (s->mb_skipped == 1) {
/* skip macroblock */
put_bits(&s->pb, 1, 1);
- if(interleaved_stats){
+ if (interleaved_stats) {
s->misc_bits++;
s->last_bits++;
}
@@ -682,162 +722,164 @@
}
put_bits(&s->pb, 1, 0); /* mb coded */
- cbpc = cbp & 3;
- cbpy = cbp >> 2;
+ cbpc = cbp & 3;
+ cbpy = cbp >> 2;
cbpy ^= 0xf;
- if(s->mv_type==MV_TYPE_16X16){
- if(s->dquant) cbpc+= 8;
+ if (s->mv_type == MV_TYPE_16X16) {
+ if (s->dquant)
+ cbpc += 8;
put_bits(&s->pb,
- ff_h263_inter_MCBPC_bits[cbpc],
- ff_h263_inter_MCBPC_code[cbpc]);
+ ff_h263_inter_MCBPC_bits[cbpc],
+ ff_h263_inter_MCBPC_code[cbpc]);
put_bits(pb2, ff_h263_cbpy_tab[cbpy][1], ff_h263_cbpy_tab[cbpy][0]);
- if(s->dquant)
- put_bits(pb2, 2, dquant_code[s->dquant+2]);
+ if (s->dquant)
+ put_bits(pb2, 2, dquant_code[s->dquant + 2]);
- if(!s->progressive_sequence){
- if(cbp)
+ if (!s->progressive_sequence) {
+ if (cbp)
put_bits(pb2, 1, s->interlaced_dct);
put_bits(pb2, 1, 0);
}
- if(interleaved_stats){
- s->misc_bits+= get_bits_diff(s);
- }
+ if (interleaved_stats)
+ s->misc_bits += get_bits_diff(s);
/* motion vectors: 16x16 mode */
ff_h263_pred_motion(s, 0, 0, &pred_x, &pred_y);
- ff_h263_encode_motion_vector(s, motion_x - pred_x,
- motion_y - pred_y, s->f_code);
- }else if(s->mv_type==MV_TYPE_FIELD){
- if(s->dquant) cbpc+= 8;
+ ff_h263_encode_motion_vector(s,
+ motion_x - pred_x,
+ motion_y - pred_y,
+ s->f_code);
+ } else if (s->mv_type == MV_TYPE_FIELD) {
+ if (s->dquant)
+ cbpc += 8;
put_bits(&s->pb,
- ff_h263_inter_MCBPC_bits[cbpc],
- ff_h263_inter_MCBPC_code[cbpc]);
+ ff_h263_inter_MCBPC_bits[cbpc],
+ ff_h263_inter_MCBPC_code[cbpc]);
put_bits(pb2, ff_h263_cbpy_tab[cbpy][1], ff_h263_cbpy_tab[cbpy][0]);
- if(s->dquant)
- put_bits(pb2, 2, dquant_code[s->dquant+2]);
+ if (s->dquant)
+ put_bits(pb2, 2, dquant_code[s->dquant + 2]);
av_assert2(!s->progressive_sequence);
- if(cbp)
+ if (cbp)
put_bits(pb2, 1, s->interlaced_dct);
put_bits(pb2, 1, 1);
- if(interleaved_stats){
- s->misc_bits+= get_bits_diff(s);
- }
+ if (interleaved_stats)
+ s->misc_bits += get_bits_diff(s);
/* motion vectors: 16x8 interlaced mode */
ff_h263_pred_motion(s, 0, 0, &pred_x, &pred_y);
- pred_y /=2;
+ pred_y /= 2;
put_bits(&s->pb, 1, s->field_select[0][0]);
put_bits(&s->pb, 1, s->field_select[0][1]);
- ff_h263_encode_motion_vector(s, s->mv[0][0][0] - pred_x,
- s->mv[0][0][1] - pred_y, s->f_code);
- ff_h263_encode_motion_vector(s, s->mv[0][1][0] - pred_x,
- s->mv[0][1][1] - pred_y, s->f_code);
- }else{
- av_assert2(s->mv_type==MV_TYPE_8X8);
+ ff_h263_encode_motion_vector(s,
+ s->mv[0][0][0] - pred_x,
+ s->mv[0][0][1] - pred_y,
+ s->f_code);
+ ff_h263_encode_motion_vector(s,
+ s->mv[0][1][0] - pred_x,
+ s->mv[0][1][1] - pred_y,
+ s->f_code);
+ } else {
+ av_assert2(s->mv_type == MV_TYPE_8X8);
put_bits(&s->pb,
- ff_h263_inter_MCBPC_bits[cbpc+16],
- ff_h263_inter_MCBPC_code[cbpc+16]);
+ ff_h263_inter_MCBPC_bits[cbpc + 16],
+ ff_h263_inter_MCBPC_code[cbpc + 16]);
put_bits(pb2, ff_h263_cbpy_tab[cbpy][1], ff_h263_cbpy_tab[cbpy][0]);
- if(!s->progressive_sequence){
- if(cbp)
- put_bits(pb2, 1, s->interlaced_dct);
- }
+ if (!s->progressive_sequence && cbp)
+ put_bits(pb2, 1, s->interlaced_dct);
- if(interleaved_stats){
- s->misc_bits+= get_bits_diff(s);
- }
+ if (interleaved_stats)
+ s->misc_bits += get_bits_diff(s);
- for(i=0; i<4; i++){
+ for (i = 0; i < 4; i++) {
/* motion vectors: 8x8 mode*/
ff_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.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);
}
}
- if(interleaved_stats){
- s->mv_bits+= get_bits_diff(s);
- }
+ if (interleaved_stats)
+ s->mv_bits += get_bits_diff(s);
mpeg4_encode_blocks(s, block, NULL, NULL, NULL, tex_pb);
- if(interleaved_stats){
- s->p_tex_bits+= get_bits_diff(s);
- }
+ if (interleaved_stats)
+ s->p_tex_bits += get_bits_diff(s);
+
s->f_count++;
}
} else {
int cbp;
- int dc_diff[6]; //dc values with the dc prediction subtracted
- int dir[6]; //prediction direction
+ int dc_diff[6]; // dc values with the dc prediction subtracted
+ int dir[6]; // prediction direction
int zigzag_last_index[6];
uint8_t *scan_table[6];
int i;
- for(i=0; i<6; i++){
- dc_diff[i]= ff_mpeg4_pred_dc(s, i, block[i][0], &dir[i], 1);
- }
+ for (i = 0; i < 6; i++)
+ dc_diff[i] = ff_mpeg4_pred_dc(s, i, block[i][0], &dir[i], 1);
- if(s->flags & CODEC_FLAG_AC_PRED){
- s->ac_pred= decide_ac_pred(s, block, dir, scan_table, zigzag_last_index);
- }else{
- for(i=0; i<6; i++)
- scan_table[i]= s->intra_scantable.permutated;
+ if (s->flags & CODEC_FLAG_AC_PRED) {
+ s->ac_pred = decide_ac_pred(s, block, dir, scan_table, zigzag_last_index);
+ } else {
+ for (i = 0; i < 6; i++)
+ scan_table[i] = s->intra_scantable.permutated;
}
/* compute cbp */
cbp = 0;
- for (i = 0; i < 6; i++) {
+ for (i = 0; i < 6; i++)
if (s->block_last_index[i] >= 1)
cbp |= 1 << (5 - i);
- }
cbpc = cbp & 3;
if (s->pict_type == AV_PICTURE_TYPE_I) {
- if(s->dquant) cbpc+=4;
+ if (s->dquant)
+ cbpc += 4;
put_bits(&s->pb,
- ff_h263_intra_MCBPC_bits[cbpc],
- ff_h263_intra_MCBPC_code[cbpc]);
+ ff_h263_intra_MCBPC_bits[cbpc],
+ ff_h263_intra_MCBPC_code[cbpc]);
} else {
- if(s->dquant) cbpc+=8;
+ if (s->dquant)
+ cbpc += 8;
put_bits(&s->pb, 1, 0); /* mb coded */
put_bits(&s->pb,
- ff_h263_inter_MCBPC_bits[cbpc + 4],
- ff_h263_inter_MCBPC_code[cbpc + 4]);
+ ff_h263_inter_MCBPC_bits[cbpc + 4],
+ ff_h263_inter_MCBPC_code[cbpc + 4]);
}
put_bits(pb2, 1, s->ac_pred);
cbpy = cbp >> 2;
put_bits(pb2, ff_h263_cbpy_tab[cbpy][1], ff_h263_cbpy_tab[cbpy][0]);
- if(s->dquant)
- put_bits(dc_pb, 2, dquant_code[s->dquant+2]);
+ if (s->dquant)
+ put_bits(dc_pb, 2, dquant_code[s->dquant + 2]);
- if(!s->progressive_sequence){
+ if (!s->progressive_sequence)
put_bits(dc_pb, 1, s->interlaced_dct);
- }
- if(interleaved_stats){
- s->misc_bits+= get_bits_diff(s);
- }
+ if (interleaved_stats)
+ s->misc_bits += get_bits_diff(s);
mpeg4_encode_blocks(s, block, dc_diff, scan_table, dc_pb, tex_pb);
- if(interleaved_stats){
- s->i_tex_bits+= get_bits_diff(s);
- }
+ if (interleaved_stats)
+ s->i_tex_bits += get_bits_diff(s);
s->i_count++;
- /* restore ac coeffs & last_index stuff if we messed them up with the prediction */
- if(s->ac_pred)
+ /* restore ac coeffs & last_index stuff
+ * if we messed them up with the prediction */
+ if (s->ac_pred)
restore_ac_coeffs(s, block, dir, scan_table, zigzag_last_index);
}
}
@@ -845,25 +887,28 @@
/**
* add mpeg4 stuffing bits (01...1)
*/
-void ff_mpeg4_stuffing(PutBitContext * pbc)
+void ff_mpeg4_stuffing(PutBitContext *pbc)
{
int length;
put_bits(pbc, 1, 0);
- length= (-put_bits_count(pbc))&7;
- if(length) put_bits(pbc, length, (1<<length)-1);
+ length = (-put_bits_count(pbc)) & 7;
+ if (length)
+ put_bits(pbc, length, (1 << length) - 1);
}
/* must be called before writing the header */
-void ff_set_mpeg4_time(MpegEncContext * s){
- if(s->pict_type==AV_PICTURE_TYPE_B){
+void ff_set_mpeg4_time(MpegEncContext *s)
+{
+ if (s->pict_type == AV_PICTURE_TYPE_B) {
ff_mpeg4_init_direct_mv(s);
- }else{
- s->last_time_base= s->time_base;
- s->time_base= FFUDIV(s->time, s->avctx->time_base.den);
+ } else {
+ s->last_time_base = s->time_base;
+ s->time_base = FFUDIV(s->time, s->avctx->time_base.den);
}
}
-static void mpeg4_encode_gop_header(MpegEncContext * s){
+static void mpeg4_encode_gop_header(MpegEncContext *s)
+{
int hours, minutes, seconds;
int64_t time;
@@ -871,52 +916,51 @@
put_bits(&s->pb, 16, GOP_STARTCODE);
time = s->current_picture_ptr->f.pts;
- if(s->reordered_input_picture[1])
+ if (s->reordered_input_picture[1])
time = FFMIN(time, s->reordered_input_picture[1]->f.pts);
- time= time*s->avctx->time_base.num;
- s->last_time_base= FFUDIV(time, s->avctx->time_base.den);
+ time = time * s->avctx->time_base.num;
+ s->last_time_base = FFUDIV(time, s->avctx->time_base.den);
- seconds= FFUDIV(time, s->avctx->time_base.den);
- minutes= FFUDIV(seconds, 60); seconds = FFUMOD(seconds, 60);
- hours = FFUDIV(minutes, 60); minutes = FFUMOD(minutes, 60);
- hours = FFUMOD(hours , 24);
+ seconds = FFUDIV(time, s->avctx->time_base.den);
+ minutes = FFUDIV(seconds, 60); seconds = FFUMOD(seconds, 60);
+ hours = FFUDIV(minutes, 60); minutes = FFUMOD(minutes, 60);
+ hours = FFUMOD(hours , 24);
put_bits(&s->pb, 5, hours);
put_bits(&s->pb, 6, minutes);
put_bits(&s->pb, 1, 1);
put_bits(&s->pb, 6, seconds);
- put_bits(&s->pb, 1, !!(s->flags&CODEC_FLAG_CLOSED_GOP));
- put_bits(&s->pb, 1, 0); //broken link == NO
+ put_bits(&s->pb, 1, !!(s->flags & CODEC_FLAG_CLOSED_GOP));
+ put_bits(&s->pb, 1, 0); // broken link == NO
ff_mpeg4_stuffing(&s->pb);
}
-static void mpeg4_encode_visual_object_header(MpegEncContext * s){
+static void mpeg4_encode_visual_object_header(MpegEncContext *s)
+{
int profile_and_level_indication;
int vo_ver_id;
- if(s->avctx->profile != FF_PROFILE_UNKNOWN){
+ if (s->avctx->profile != FF_PROFILE_UNKNOWN) {
profile_and_level_indication = s->avctx->profile << 4;
- }else if(s->max_b_frames || s->quarter_sample){
- profile_and_level_indication= 0xF0; // adv simple
- }else{
- profile_and_level_indication= 0x00; // simple
+ } else if (s->max_b_frames || s->quarter_sample) {
+ profile_and_level_indication = 0xF0; // adv simple
+ } else {
+ profile_and_level_indication = 0x00; // simple
}
- if(s->avctx->level != FF_LEVEL_UNKNOWN){
+ if (s->avctx->level != FF_LEVEL_UNKNOWN)
profile_and_level_indication |= s->avctx->level;
- }else{
- profile_and_level_indication |= 1; //level 1
- }
+ else
+ profile_and_level_indication |= 1; // level 1
- if(profile_and_level_indication>>4 == 0xF){
- vo_ver_id= 5;
- }else{
- vo_ver_id= 1;
- }
+ if (profile_and_level_indication >> 4 == 0xF)
+ vo_ver_id = 5;
+ else
+ vo_ver_id = 1;
- //FIXME levels
+ // FIXME levels
put_bits(&s->pb, 16, 0);
put_bits(&s->pb, 16, VOS_STARTCODE);
@@ -927,28 +971,31 @@
put_bits(&s->pb, 16, VISUAL_OBJ_STARTCODE);
put_bits(&s->pb, 1, 1);
- put_bits(&s->pb, 4, vo_ver_id);
- put_bits(&s->pb, 3, 1); //priority
+ put_bits(&s->pb, 4, vo_ver_id);
+ put_bits(&s->pb, 3, 1); // priority
- put_bits(&s->pb, 4, 1); //visual obj type== video obj
+ put_bits(&s->pb, 4, 1); // visual obj type== video obj
- put_bits(&s->pb, 1, 0); //video signal type == no clue //FIXME
+ put_bits(&s->pb, 1, 0); // video signal type == no clue // FIXME
ff_mpeg4_stuffing(&s->pb);
}
-static void mpeg4_encode_vol_header(MpegEncContext * s, int vo_number, int vol_number)
+static void mpeg4_encode_vol_header(MpegEncContext *s,
+ int vo_number,
+ int vol_number)
{
int vo_ver_id;
- if (!CONFIG_MPEG4_ENCODER) return;
+ if (!CONFIG_MPEG4_ENCODER)
+ return;
- if(s->max_b_frames || s->quarter_sample){
- vo_ver_id= 5;
- s->vo_type= ADV_SIMPLE_VO_TYPE;
- }else{
- vo_ver_id= 1;
- s->vo_type= SIMPLE_VO_TYPE;
+ if (s->max_b_frames || s->quarter_sample) {
+ vo_ver_id = 5;
+ s->vo_type = ADV_SIMPLE_VO_TYPE;
+ } else {
+ vo_ver_id = 1;
+ s->vo_type = SIMPLE_VO_TYPE;
}
put_bits(&s->pb, 16, 0);
@@ -958,7 +1005,7 @@
put_bits(&s->pb, 1, 0); /* random access vol */
put_bits(&s->pb, 8, s->vo_type); /* video obj type indication */
- if(s->workaround_bugs & FF_BUG_MS) {
+ if (s->workaround_bugs & FF_BUG_MS) {
put_bits(&s->pb, 1, 0); /* is obj layer id= no */
} else {
put_bits(&s->pb, 1, 1); /* is obj layer id= yes */
@@ -966,17 +1013,17 @@
put_bits(&s->pb, 3, 1); /* is obj layer priority */
}
- s->aspect_ratio_info= ff_h263_aspect_to_info(s->avctx->sample_aspect_ratio);
+ s->aspect_ratio_info = ff_h263_aspect_to_info(s->avctx->sample_aspect_ratio);
- put_bits(&s->pb, 4, s->aspect_ratio_info);/* aspect ratio info */
- if (s->aspect_ratio_info == FF_ASPECT_EXTENDED){
+ put_bits(&s->pb, 4, s->aspect_ratio_info); /* aspect ratio info */
+ if (s->aspect_ratio_info == FF_ASPECT_EXTENDED) {
av_reduce(&s->avctx->sample_aspect_ratio.num, &s->avctx->sample_aspect_ratio.den,
s->avctx->sample_aspect_ratio.num, s->avctx->sample_aspect_ratio.den, 255);
put_bits(&s->pb, 8, s->avctx->sample_aspect_ratio.num);
put_bits(&s->pb, 8, s->avctx->sample_aspect_ratio.den);
}
- if(s->workaround_bugs & FF_BUG_MS) { //
+ if (s->workaround_bugs & FF_BUG_MS) {
put_bits(&s->pb, 1, 0); /* vol control parameters= no @@@ */
} else {
put_bits(&s->pb, 1, 1); /* vol control parameters= yes */
@@ -1000,16 +1047,15 @@
put_bits(&s->pb, 1, 1); /* marker bit */
put_bits(&s->pb, 1, s->progressive_sequence ? 0 : 1);
put_bits(&s->pb, 1, 1); /* obmc disable */
- if (vo_ver_id == 1) {
- put_bits(&s->pb, 1, s->vol_sprite_usage); /* sprite enable */
- }else{
- put_bits(&s->pb, 2, s->vol_sprite_usage); /* sprite enable */
- }
+ if (vo_ver_id == 1)
+ put_bits(&s->pb, 1, 0); /* sprite enable */
+ else
+ put_bits(&s->pb, 2, 0); /* sprite enable */
put_bits(&s->pb, 1, 0); /* not 8 bit == false */
put_bits(&s->pb, 1, s->mpeg_quant); /* quant type= (0=h263 style)*/
- if(s->mpeg_quant){
+ if (s->mpeg_quant) {
ff_write_quant_matrix(&s->pb, s->avctx->intra_matrix);
ff_write_quant_matrix(&s->pb, s->avctx->inter_matrix);
}
@@ -1017,14 +1063,12 @@
if (vo_ver_id != 1)
put_bits(&s->pb, 1, s->quarter_sample);
put_bits(&s->pb, 1, 1); /* complexity estimation disable */
- s->resync_marker= s->rtp_mode;
- put_bits(&s->pb, 1, s->resync_marker ? 0 : 1);/* resync marker disable */
+ put_bits(&s->pb, 1, s->rtp_mode ? 0 : 1); /* resync marker disable */
put_bits(&s->pb, 1, s->data_partitioning ? 1 : 0);
- if(s->data_partitioning){
+ if (s->data_partitioning)
put_bits(&s->pb, 1, 0); /* no rvlc */
- }
- if (vo_ver_id != 1){
+ if (vo_ver_id != 1) {
put_bits(&s->pb, 1, 0); /* newpred */
put_bits(&s->pb, 1, 0); /* reduced res vop */
}
@@ -1033,7 +1077,7 @@
ff_mpeg4_stuffing(&s->pb);
/* user data */
- if(!(s->flags & CODEC_FLAG_BITEXACT)){
+ if (!(s->flags & CODEC_FLAG_BITEXACT)) {
put_bits(&s->pb, 16, 0);
put_bits(&s->pb, 16, 0x1B2); /* user_data */
avpriv_put_string(&s->pb, LIBAVCODEC_IDENT, 0);
@@ -1041,33 +1085,33 @@
}
/* write mpeg4 VOP header */
-void ff_mpeg4_encode_picture_header(MpegEncContext * s, int picture_number)
+void ff_mpeg4_encode_picture_header(MpegEncContext *s, int picture_number)
{
int time_incr;
int time_div, time_mod;
- if(s->pict_type==AV_PICTURE_TYPE_I){
- if(!(s->flags&CODEC_FLAG_GLOBAL_HEADER)){
- if(s->strict_std_compliance < FF_COMPLIANCE_VERY_STRICT) //HACK, the reference sw is buggy
+ if (s->pict_type == AV_PICTURE_TYPE_I) {
+ if (!(s->flags & CODEC_FLAG_GLOBAL_HEADER)) {
+ if (s->strict_std_compliance < FF_COMPLIANCE_VERY_STRICT) // HACK, the reference sw is buggy
mpeg4_encode_visual_object_header(s);
- if(s->strict_std_compliance < FF_COMPLIANCE_VERY_STRICT || picture_number==0) //HACK, the reference sw is buggy
+ if (s->strict_std_compliance < FF_COMPLIANCE_VERY_STRICT || picture_number == 0) // HACK, the reference sw is buggy
mpeg4_encode_vol_header(s, 0, 0);
}
- if(!(s->workaround_bugs & FF_BUG_MS))
+ if (!(s->workaround_bugs & FF_BUG_MS))
mpeg4_encode_gop_header(s);
}
- s->partitioned_frame= s->data_partitioning && s->pict_type!=AV_PICTURE_TYPE_B;
+ s->partitioned_frame = s->data_partitioning && s->pict_type != AV_PICTURE_TYPE_B;
put_bits(&s->pb, 16, 0); /* vop header */
put_bits(&s->pb, 16, VOP_STARTCODE); /* vop header */
put_bits(&s->pb, 2, s->pict_type - 1); /* pict type: I = 0 , P = 1 */
- time_div= FFUDIV(s->time, s->avctx->time_base.den);
- time_mod= FFUMOD(s->time, s->avctx->time_base.den);
- time_incr= time_div - s->last_time_base;
+ time_div = FFUDIV(s->time, s->avctx->time_base.den);
+ time_mod = FFUMOD(s->time, s->avctx->time_base.den);
+ time_incr = time_div - s->last_time_base;
av_assert0(time_incr >= 0);
- while(time_incr--)
+ while (time_incr--)
put_bits(&s->pb, 1, 1);
put_bits(&s->pb, 1, 0);
@@ -1076,75 +1120,76 @@
put_bits(&s->pb, s->time_increment_bits, time_mod); /* time increment */
put_bits(&s->pb, 1, 1); /* marker */
put_bits(&s->pb, 1, 1); /* vop coded */
- if ( s->pict_type == AV_PICTURE_TYPE_P
- || (s->pict_type == AV_PICTURE_TYPE_S && s->vol_sprite_usage==GMC_SPRITE)) {
+ if (s->pict_type == AV_PICTURE_TYPE_P) {
put_bits(&s->pb, 1, s->no_rounding); /* rounding type */
}
put_bits(&s->pb, 3, 0); /* intra dc VLC threshold */
- if(!s->progressive_sequence){
- put_bits(&s->pb, 1, s->current_picture_ptr->f.top_field_first);
- put_bits(&s->pb, 1, s->alternate_scan);
+ if (!s->progressive_sequence) {
+ put_bits(&s->pb, 1, s->current_picture_ptr->f.top_field_first);
+ put_bits(&s->pb, 1, s->alternate_scan);
}
- //FIXME sprite stuff
+ // FIXME sprite stuff
put_bits(&s->pb, 5, s->qscale);
if (s->pict_type != AV_PICTURE_TYPE_I)
- put_bits(&s->pb, 3, s->f_code); /* fcode_for */
+ put_bits(&s->pb, 3, s->f_code); /* fcode_for */
if (s->pict_type == AV_PICTURE_TYPE_B)
- put_bits(&s->pb, 3, s->b_code); /* fcode_back */
+ put_bits(&s->pb, 3, s->b_code); /* fcode_back */
}
-
static av_cold void init_uni_dc_tab(void)
{
int level, uni_code, uni_len;
- for(level=-256; level<256; level++){
+ for (level = -256; level < 256; level++) {
int size, v, l;
/* find number of bits */
size = 0;
- v = abs(level);
+ v = abs(level);
while (v) {
v >>= 1;
size++;
}
if (level < 0)
- l= (-level) ^ ((1 << size) - 1);
+ l = (-level) ^ ((1 << size) - 1);
else
- l= level;
+ l = level;
/* luminance */
- uni_code= ff_mpeg4_DCtab_lum[size][0];
- uni_len = ff_mpeg4_DCtab_lum[size][1];
+ uni_code = ff_mpeg4_DCtab_lum[size][0];
+ uni_len = ff_mpeg4_DCtab_lum[size][1];
if (size > 0) {
- uni_code<<=size; uni_code|=l;
- uni_len+=size;
- if (size > 8){
- uni_code<<=1; uni_code|=1;
+ uni_code <<= size;
+ uni_code |= l;
+ uni_len += size;
+ if (size > 8) {
+ uni_code <<= 1;
+ uni_code |= 1;
uni_len++;
}
}
- uni_DCtab_lum_bits[level+256]= uni_code;
- uni_DCtab_lum_len [level+256]= uni_len;
+ uni_DCtab_lum_bits[level + 256] = uni_code;
+ uni_DCtab_lum_len[level + 256] = uni_len;
/* chrominance */
- uni_code= ff_mpeg4_DCtab_chrom[size][0];
- uni_len = ff_mpeg4_DCtab_chrom[size][1];
+ uni_code = ff_mpeg4_DCtab_chrom[size][0];
+ uni_len = ff_mpeg4_DCtab_chrom[size][1];
if (size > 0) {
- uni_code<<=size; uni_code|=l;
- uni_len+=size;
- if (size > 8){
- uni_code<<=1; uni_code|=1;
+ uni_code <<= size;
+ uni_code |= l;
+ uni_len += size;
+ if (size > 8) {
+ uni_code <<= 1;
+ uni_code |= 1;
uni_len++;
}
}
- uni_DCtab_chrom_bits[level+256]= uni_code;
- uni_DCtab_chrom_len [level+256]= uni_len;
-
+ uni_DCtab_chrom_bits[level + 256] = uni_code;
+ uni_DCtab_chrom_len[level + 256] = uni_len;
}
}
@@ -1154,77 +1199,89 @@
int slevel, run, last;
av_assert0(MAX_LEVEL >= 64);
- av_assert0(MAX_RUN >= 63);
+ av_assert0(MAX_RUN >= 63);
- for(slevel=-64; slevel<64; slevel++){
- if(slevel==0) continue;
- for(run=0; run<64; run++){
- for(last=0; last<=1; last++){
- const int index= UNI_MPEG4_ENC_INDEX(last, run, slevel+64);
- int level= slevel < 0 ? -slevel : slevel;
- int sign= slevel < 0 ? 1 : 0;
+ for (slevel = -64; slevel < 64; slevel++) {
+ if (slevel == 0)
+ continue;
+ for (run = 0; run < 64; run++) {
+ for (last = 0; last <= 1; last++) {
+ const int index = UNI_MPEG4_ENC_INDEX(last, run, slevel + 64);
+ int level = slevel < 0 ? -slevel : slevel;
+ int sign = slevel < 0 ? 1 : 0;
int bits, len, code;
int level1, run1;
- len_tab[index]= 100;
+ len_tab[index] = 100;
/* ESC0 */
- code= get_rl_index(rl, last, run, level);
- bits= rl->table_vlc[code][0];
- len= rl->table_vlc[code][1];
- bits=bits*2+sign; len++;
+ code = get_rl_index(rl, last, run, level);
+ bits = rl->table_vlc[code][0];
+ len = rl->table_vlc[code][1];
+ bits = bits * 2 + sign;
+ len++;
- if(code!=rl->n && len < len_tab[index]){
- bits_tab[index]= bits;
- len_tab [index]= len;
+ if (code != rl->n && len < len_tab[index]) {
+ bits_tab[index] = bits;
+ len_tab[index] = len;
}
/* ESC1 */
- bits= rl->table_vlc[rl->n][0];
- len= rl->table_vlc[rl->n][1];
- bits=bits*2; len++; //esc1
- level1= level - rl->max_level[last][run];
- if(level1>0){
- code= get_rl_index(rl, last, run, level1);
- bits<<= rl->table_vlc[code][1];
- len += rl->table_vlc[code][1];
- bits += rl->table_vlc[code][0];
- bits=bits*2+sign; len++;
+ bits = rl->table_vlc[rl->n][0];
+ len = rl->table_vlc[rl->n][1];
+ bits = bits * 2;
+ len++; // esc1
+ level1 = level - rl->max_level[last][run];
+ if (level1 > 0) {
+ code = get_rl_index(rl, last, run, level1);
+ bits <<= rl->table_vlc[code][1];
+ len += rl->table_vlc[code][1];
+ bits += rl->table_vlc[code][0];
+ bits = bits * 2 + sign;
+ len++;
- if(code!=rl->n && len < len_tab[index]){
- bits_tab[index]= bits;
- len_tab [index]= len;
+ if (code != rl->n && len < len_tab[index]) {
+ bits_tab[index] = bits;
+ len_tab[index] = len;
}
}
/* ESC2 */
- bits= rl->table_vlc[rl->n][0];
- len= rl->table_vlc[rl->n][1];
- bits=bits*4+2; len+=2; //esc2
+ bits = rl->table_vlc[rl->n][0];
+ len = rl->table_vlc[rl->n][1];
+ bits = bits * 4 + 2;
+ len += 2; // esc2
run1 = run - rl->max_run[last][level] - 1;
- if(run1>=0){
- code= get_rl_index(rl, last, run1, level);
- bits<<= rl->table_vlc[code][1];
- len += rl->table_vlc[code][1];
- bits += rl->table_vlc[code][0];
- bits=bits*2+sign; len++;
+ if (run1 >= 0) {
+ code = get_rl_index(rl, last, run1, level);
+ bits <<= rl->table_vlc[code][1];
+ len += rl->table_vlc[code][1];
+ bits += rl->table_vlc[code][0];
+ bits = bits * 2 + sign;
+ len++;
- if(code!=rl->n && len < len_tab[index]){
- bits_tab[index]= bits;
- len_tab [index]= len;
+ if (code != rl->n && len < len_tab[index]) {
+ bits_tab[index] = bits;
+ len_tab[index] = len;
}
}
/* ESC3 */
- bits= rl->table_vlc[rl->n][0];
- len = rl->table_vlc[rl->n][1];
- bits=bits*4+3; len+=2; //esc3
- bits=bits*2+last; len++;
- bits=bits*64+run; len+=6;
- bits=bits*2+1; len++; //marker
- bits=bits*4096+(slevel&0xfff); len+=12;
- bits=bits*2+1; len++; //marker
+ bits = rl->table_vlc[rl->n][0];
+ len = rl->table_vlc[rl->n][1];
+ bits = bits * 4 + 3;
+ len += 2; // esc3
+ bits = bits * 2 + last;
+ len++;
+ bits = bits * 64 + run;
+ len += 6;
+ bits = bits * 2 + 1;
+ len++; // marker
+ bits = bits * 4096 + (slevel & 0xfff);
+ len += 12;
+ bits = bits * 2 + 1;
+ len++; // marker
- if(len < len_tab[index]){
- bits_tab[index]= bits;
- len_tab [index]= len;
+ if (len < len_tab[index]) {
+ bits_tab[index] = bits;
+ len_tab[index] = len;
}
}
}
@@ -1242,7 +1299,7 @@
return AVERROR(EINVAL);
}
- if((ret=ff_MPV_encode_init(avctx)) < 0)
+ if ((ret = ff_MPV_encode_init(avctx)) < 0)
return ret;
if (!done) {
@@ -1256,81 +1313,79 @@
init_uni_mpeg4_rl_tab(&ff_h263_rl_inter, uni_mpeg4_inter_rl_bits, uni_mpeg4_inter_rl_len);
}
- s->min_qcoeff= -2048;
- s->max_qcoeff= 2047;
- s->intra_ac_vlc_length = uni_mpeg4_intra_rl_len;
- s->intra_ac_vlc_last_length= uni_mpeg4_intra_rl_len + 128*64;
- 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->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;
+ s->min_qcoeff = -2048;
+ s->max_qcoeff = 2047;
+ s->intra_ac_vlc_length = uni_mpeg4_intra_rl_len;
+ s->intra_ac_vlc_last_length = uni_mpeg4_intra_rl_len + 128 * 64;
+ 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->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;
- if(s->flags & CODEC_FLAG_GLOBAL_HEADER){
-
- s->avctx->extradata= av_malloc(1024);
+ if (s->flags & CODEC_FLAG_GLOBAL_HEADER) {
+ s->avctx->extradata = av_malloc(1024);
init_put_bits(&s->pb, s->avctx->extradata, 1024);
- if(!(s->workaround_bugs & FF_BUG_MS))
+ if (!(s->workaround_bugs & FF_BUG_MS))
mpeg4_encode_visual_object_header(s);
mpeg4_encode_vol_header(s, 0, 0);
// ff_mpeg4_stuffing(&s->pb); ?
flush_put_bits(&s->pb);
- s->avctx->extradata_size= (put_bits_count(&s->pb)+7)>>3;
+ s->avctx->extradata_size = (put_bits_count(&s->pb) + 7) >> 3;
}
return 0;
}
void ff_mpeg4_init_partitions(MpegEncContext *s)
{
- uint8_t *start= put_bits_ptr(&s->pb);
- uint8_t *end= s->pb.buf_end;
- int size= end - start;
- int pb_size = (((intptr_t)start + size/3)&(~3)) - (intptr_t)start;
- int tex_size= (size - 2*pb_size)&(~3);
+ uint8_t *start = put_bits_ptr(&s->pb);
+ uint8_t *end = s->pb.buf_end;
+ int size = end - start;
+ int pb_size = (((intptr_t)start + size / 3) & (~3)) - (intptr_t)start;
+ int tex_size = (size - 2 * pb_size) & (~3);
set_put_bits_buffer_size(&s->pb, pb_size);
- init_put_bits(&s->tex_pb, start + pb_size , tex_size);
- init_put_bits(&s->pb2 , start + pb_size + tex_size, pb_size);
+ init_put_bits(&s->tex_pb, start + pb_size, tex_size);
+ init_put_bits(&s->pb2, start + pb_size + tex_size, pb_size);
}
void ff_mpeg4_merge_partitions(MpegEncContext *s)
{
- const int pb2_len = put_bits_count(&s->pb2 );
- const int tex_pb_len= put_bits_count(&s->tex_pb);
- const int bits= put_bits_count(&s->pb);
+ const int pb2_len = put_bits_count(&s->pb2);
+ const int tex_pb_len = put_bits_count(&s->tex_pb);
+ const int bits = put_bits_count(&s->pb);
- if(s->pict_type==AV_PICTURE_TYPE_I){
+ if (s->pict_type == AV_PICTURE_TYPE_I) {
put_bits(&s->pb, 19, DC_MARKER);
- s->misc_bits+=19 + pb2_len + bits - s->last_bits;
- s->i_tex_bits+= tex_pb_len;
- }else{
+ s->misc_bits += 19 + pb2_len + bits - s->last_bits;
+ s->i_tex_bits += tex_pb_len;
+ } else {
put_bits(&s->pb, 17, MOTION_MARKER);
- s->misc_bits+=17 + pb2_len;
- s->mv_bits+= bits - s->last_bits;
- s->p_tex_bits+= tex_pb_len;
+ s->misc_bits += 17 + pb2_len;
+ s->mv_bits += bits - s->last_bits;
+ s->p_tex_bits += tex_pb_len;
}
flush_put_bits(&s->pb2);
flush_put_bits(&s->tex_pb);
set_put_bits_buffer_size(&s->pb, s->pb2.buf_end - s->pb.buf);
- avpriv_copy_bits(&s->pb, s->pb2.buf , pb2_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);
+ s->last_bits = put_bits_count(&s->pb);
}
-
void ff_mpeg4_encode_video_packet_header(MpegEncContext *s)
{
- int mb_num_bits= av_log2(s->mb_num - 1) + 1;
+ int mb_num_bits = av_log2(s->mb_num - 1) + 1;
put_bits(&s->pb, ff_mpeg4_get_video_packet_prefix_length(s), 0);
put_bits(&s->pb, 1, 1);
- put_bits(&s->pb, mb_num_bits, s->mb_x + s->mb_y*s->mb_width);
+ put_bits(&s->pb, mb_num_bits, s->mb_x + s->mb_y * s->mb_width);
put_bits(&s->pb, s->quant_precision, s->qscale);
put_bits(&s->pb, 1, 0); /* no HEC */
}
@@ -1338,8 +1393,8 @@
#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, { .i64 = 0 }, 0, 1, VE },
- { "alternate_scan", "Enable alternate scantable.", OFFSET(alternate_scan), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE },
+ { "data_partitioning", "Use data partitioning.", OFFSET(data_partitioning), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE },
+ { "alternate_scan", "Enable alternate scantable.", OFFSET(alternate_scan), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE },
FF_MPV_COMMON_OPTS
{ NULL },
};
@@ -1360,7 +1415,7 @@
.init = encode_init,
.encode2 = ff_MPV_encode_picture,
.close = ff_MPV_encode_end,
- .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE },
+ .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE },
.capabilities = CODEC_CAP_DELAY | CODEC_CAP_SLICE_THREADS,
.priv_class = &mpeg4enc_class,
};
diff --git a/libavcodec/mpegaudio.h b/libavcodec/mpegaudio.h
index b880b7a..1591a17 100644
--- a/libavcodec/mpegaudio.h
+++ b/libavcodec/mpegaudio.h
@@ -26,8 +26,8 @@
#ifndef AVCODEC_MPEGAUDIO_H
#define AVCODEC_MPEGAUDIO_H
-#ifndef CONFIG_FLOAT
-# define CONFIG_FLOAT 0
+#ifndef USE_FLOATS
+# define USE_FLOATS 0
#endif
#include <stdint.h>
@@ -58,7 +58,7 @@
#define FIX(a) ((int)((a) * FRAC_ONE))
-#if CONFIG_FLOAT
+#if USE_FLOATS
# define INTFLOAT float
typedef float MPA_INT;
typedef float OUT_INT;
diff --git a/libavcodec/mpegaudio_tablegen.h b/libavcodec/mpegaudio_tablegen.h
index 789bc2a..f9557c9 100644
--- a/libavcodec/mpegaudio_tablegen.h
+++ b/libavcodec/mpegaudio_tablegen.h
@@ -63,7 +63,7 @@
/* cbrtf() isn't available on all systems, so we use powf(). */
double f = (double)value * pow(value, 1.0 / 3.0) * pow(2, (exponent - 400) * 0.25 + FRAC_BITS + 5) / IMDCT_SCALAR;
/* llrint() isn't always available, so round and cast manually. */
- expval_table_fixed[exponent][value] = (long long int) floor(f + 0.5);
+ expval_table_fixed[exponent][value] = (long long int) (f < 0xFFFFFFFF ? floor(f + 0.5) : 0xFFFFFFFF);
expval_table_float[exponent][value] = f;
}
exp_table_fixed[exponent] = expval_table_fixed[exponent][1];
diff --git a/libavcodec/mpegaudiodec_fixed.c b/libavcodec/mpegaudiodec_fixed.c
new file mode 100644
index 0000000..904c885
--- /dev/null
+++ b/libavcodec/mpegaudiodec_fixed.c
@@ -0,0 +1,120 @@
+/*
+ * Fixed-point MPEG audio decoder
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include "libavutil/samplefmt.h"
+
+#define USE_FLOATS 0
+
+#include "mpegaudio.h"
+
+#define SHR(a,b) ((a)>>(b))
+/* 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))
+#define MULH3(x, y, s) MULH((s)*(x), y)
+#define MULLx(x, y, s) MULL(x,y,s)
+#define RENAME(a) a ## _fixed
+#define OUT_FMT AV_SAMPLE_FMT_S16
+#define OUT_FMT_P AV_SAMPLE_FMT_S16P
+
+#include "mpegaudiodec_template.c"
+
+#if CONFIG_MP1_DECODER
+AVCodec ff_mp1_decoder = {
+ .name = "mp1",
+ .long_name = NULL_IF_CONFIG_SMALL("MP1 (MPEG audio layer 1)"),
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = AV_CODEC_ID_MP1,
+ .priv_data_size = sizeof(MPADecodeContext),
+ .init = decode_init,
+ .decode = decode_frame,
+ .capabilities = CODEC_CAP_DR1,
+ .flush = flush,
+ .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P,
+ AV_SAMPLE_FMT_S16,
+ AV_SAMPLE_FMT_NONE },
+};
+#endif
+#if CONFIG_MP2_DECODER
+AVCodec ff_mp2_decoder = {
+ .name = "mp2",
+ .long_name = NULL_IF_CONFIG_SMALL("MP2 (MPEG audio layer 2)"),
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = AV_CODEC_ID_MP2,
+ .priv_data_size = sizeof(MPADecodeContext),
+ .init = decode_init,
+ .decode = decode_frame,
+ .capabilities = CODEC_CAP_DR1,
+ .flush = flush,
+ .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P,
+ AV_SAMPLE_FMT_S16,
+ AV_SAMPLE_FMT_NONE },
+};
+#endif
+#if CONFIG_MP3_DECODER
+AVCodec ff_mp3_decoder = {
+ .name = "mp3",
+ .long_name = NULL_IF_CONFIG_SMALL("MP3 (MPEG audio layer 3)"),
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = AV_CODEC_ID_MP3,
+ .priv_data_size = sizeof(MPADecodeContext),
+ .init = decode_init,
+ .decode = decode_frame,
+ .capabilities = CODEC_CAP_DR1,
+ .flush = flush,
+ .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P,
+ AV_SAMPLE_FMT_S16,
+ AV_SAMPLE_FMT_NONE },
+};
+#endif
+#if CONFIG_MP3ADU_DECODER
+AVCodec ff_mp3adu_decoder = {
+ .name = "mp3adu",
+ .long_name = NULL_IF_CONFIG_SMALL("ADU (Application Data Unit) MP3 (MPEG audio layer 3)"),
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = AV_CODEC_ID_MP3ADU,
+ .priv_data_size = sizeof(MPADecodeContext),
+ .init = decode_init,
+ .decode = decode_frame_adu,
+ .capabilities = CODEC_CAP_DR1,
+ .flush = flush,
+ .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P,
+ AV_SAMPLE_FMT_S16,
+ AV_SAMPLE_FMT_NONE },
+};
+#endif
+#if CONFIG_MP3ON4_DECODER
+AVCodec ff_mp3on4_decoder = {
+ .name = "mp3on4",
+ .long_name = NULL_IF_CONFIG_SMALL("MP3onMP4"),
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = AV_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,
+ .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P,
+ AV_SAMPLE_FMT_NONE },
+};
+#endif
diff --git a/libavcodec/mpegaudiodec_float.c b/libavcodec/mpegaudiodec_float.c
index 61b332e..35f07fa 100644
--- a/libavcodec/mpegaudiodec_float.c
+++ b/libavcodec/mpegaudiodec_float.c
@@ -19,8 +19,24 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#define CONFIG_FLOAT 1
-#include "mpegaudiodec.c"
+#include "config.h"
+#include "libavutil/samplefmt.h"
+
+#define USE_FLOATS 1
+
+#include "mpegaudio.h"
+
+#define SHR(a,b) ((a)*(1.0f/(1<<(b))))
+#define FIXR_OLD(a) ((int)((a) * FRAC_ONE + 0.5))
+#define FIXR(x) ((float)(x))
+#define FIXHR(x) ((float)(x))
+#define MULH3(x, y, s) ((s)*(y)*(x))
+#define MULLx(x, y, s) ((y)*(x))
+#define RENAME(a) a ## _float
+#define OUT_FMT AV_SAMPLE_FMT_FLT
+#define OUT_FMT_P AV_SAMPLE_FMT_FLTP
+
+#include "mpegaudiodec_template.c"
#if CONFIG_MP1FLOAT_DECODER
AVCodec ff_mp1float_decoder = {
diff --git a/libavcodec/mpegaudiodec.c b/libavcodec/mpegaudiodec_template.c
similarity index 93%
rename from libavcodec/mpegaudiodec.c
rename to libavcodec/mpegaudiodec_template.c
index fc900d8..1f29679 100644
--- a/libavcodec/mpegaudiodec.c
+++ b/libavcodec/mpegaudiodec_template.c
@@ -89,31 +89,6 @@
AVFrame *frame;
} MPADecodeContext;
-#if CONFIG_FLOAT
-# define SHR(a,b) ((a)*(1.0f/(1<<(b))))
-# define FIXR_OLD(a) ((int)((a) * FRAC_ONE + 0.5))
-# define FIXR(x) ((float)(x))
-# define FIXHR(x) ((float)(x))
-# define MULH3(x, y, s) ((s)*(y)*(x))
-# define MULLx(x, y, s) ((y)*(x))
-# define RENAME(a) a ## _float
-# define OUT_FMT AV_SAMPLE_FMT_FLT
-# define OUT_FMT_P AV_SAMPLE_FMT_FLTP
-#else
-# define SHR(a,b) ((a)>>(b))
-/* 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))
-# define MULH3(x, y, s) MULH((s)*(x), y)
-# define MULLx(x, y, s) MULL(x,y,s)
-# define RENAME(a) a ## _fixed
-# define OUT_FMT AV_SAMPLE_FMT_S16
-# define OUT_FMT_P AV_SAMPLE_FMT_S16P
-#endif
-
-/****************/
-
#define HEADER_SIZE 4
#include "mpegaudiodata.h"
@@ -417,7 +392,7 @@
ci = ci_table[i];
cs = 1.0 / sqrt(1.0 + ci * ci);
ca = cs * ci;
-#if !CONFIG_FLOAT
+#if !USE_FLOATS
csa_table[i][0] = FIXHR(cs/4);
csa_table[i][1] = FIXHR(ca/4);
csa_table[i][2] = FIXHR(ca/4) + FIXHR(cs/4);
@@ -853,7 +828,7 @@
v = -v;
*dst = v;
*/
-#if CONFIG_FLOAT
+#if USE_FLOATS
#define READ_FLIP_SIGN(dst,src) \
v = AV_RN32A(src) ^ (get_bits1(&s->gb) << 31); \
AV_WN32A(dst, v);
@@ -1162,7 +1137,7 @@
/* ms stereo ONLY */
/* NOTE: the 1/sqrt(2) normalization factor is included in the
global gain */
-#if CONFIG_FLOAT
+#if USE_FLOATS
s->fdsp.butterflies_float(g0->sb_hybrid, g1->sb_hybrid, 576);
#else
tab0 = g0->sb_hybrid;
@@ -1177,7 +1152,7 @@
}
}
-#if CONFIG_FLOAT
+#if USE_FLOATS
#if HAVE_MIPSFPU
# include "mips/compute_antialias_float.h"
#endif /* HAVE_MIPSFPU */
@@ -1185,10 +1160,10 @@
#if HAVE_MIPSDSPR1
# include "mips/compute_antialias_fixed.h"
#endif /* HAVE_MIPSDSPR1 */
-#endif /* CONFIG_FLOAT */
+#endif /* USE_FLOATS */
#ifndef compute_antialias
-#if CONFIG_FLOAT
+#if USE_FLOATS
#define AA(j) do { \
float tmp0 = ptr[-1-j]; \
float tmp1 = ptr[ j]; \
@@ -1994,86 +1969,3 @@
return buf_size;
}
#endif /* CONFIG_MP3ON4_DECODER || CONFIG_MP3ON4FLOAT_DECODER */
-
-#if !CONFIG_FLOAT
-#if CONFIG_MP1_DECODER
-AVCodec ff_mp1_decoder = {
- .name = "mp1",
- .long_name = NULL_IF_CONFIG_SMALL("MP1 (MPEG audio layer 1)"),
- .type = AVMEDIA_TYPE_AUDIO,
- .id = AV_CODEC_ID_MP1,
- .priv_data_size = sizeof(MPADecodeContext),
- .init = decode_init,
- .decode = decode_frame,
- .capabilities = CODEC_CAP_DR1,
- .flush = flush,
- .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P,
- AV_SAMPLE_FMT_S16,
- AV_SAMPLE_FMT_NONE },
-};
-#endif
-#if CONFIG_MP2_DECODER
-AVCodec ff_mp2_decoder = {
- .name = "mp2",
- .long_name = NULL_IF_CONFIG_SMALL("MP2 (MPEG audio layer 2)"),
- .type = AVMEDIA_TYPE_AUDIO,
- .id = AV_CODEC_ID_MP2,
- .priv_data_size = sizeof(MPADecodeContext),
- .init = decode_init,
- .decode = decode_frame,
- .capabilities = CODEC_CAP_DR1,
- .flush = flush,
- .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P,
- AV_SAMPLE_FMT_S16,
- AV_SAMPLE_FMT_NONE },
-};
-#endif
-#if CONFIG_MP3_DECODER
-AVCodec ff_mp3_decoder = {
- .name = "mp3",
- .long_name = NULL_IF_CONFIG_SMALL("MP3 (MPEG audio layer 3)"),
- .type = AVMEDIA_TYPE_AUDIO,
- .id = AV_CODEC_ID_MP3,
- .priv_data_size = sizeof(MPADecodeContext),
- .init = decode_init,
- .decode = decode_frame,
- .capabilities = CODEC_CAP_DR1,
- .flush = flush,
- .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P,
- AV_SAMPLE_FMT_S16,
- AV_SAMPLE_FMT_NONE },
-};
-#endif
-#if CONFIG_MP3ADU_DECODER
-AVCodec ff_mp3adu_decoder = {
- .name = "mp3adu",
- .long_name = NULL_IF_CONFIG_SMALL("ADU (Application Data Unit) MP3 (MPEG audio layer 3)"),
- .type = AVMEDIA_TYPE_AUDIO,
- .id = AV_CODEC_ID_MP3ADU,
- .priv_data_size = sizeof(MPADecodeContext),
- .init = decode_init,
- .decode = decode_frame_adu,
- .capabilities = CODEC_CAP_DR1,
- .flush = flush,
- .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P,
- AV_SAMPLE_FMT_S16,
- AV_SAMPLE_FMT_NONE },
-};
-#endif
-#if CONFIG_MP3ON4_DECODER
-AVCodec ff_mp3on4_decoder = {
- .name = "mp3on4",
- .long_name = NULL_IF_CONFIG_SMALL("MP3onMP4"),
- .type = AVMEDIA_TYPE_AUDIO,
- .id = AV_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,
- .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P,
- AV_SAMPLE_FMT_NONE },
-};
-#endif
-#endif
diff --git a/libavcodec/mpegaudiodsp_fixed.c b/libavcodec/mpegaudiodsp_fixed.c
index 8b69cc2..83c9d66 100644
--- a/libavcodec/mpegaudiodsp_fixed.c
+++ b/libavcodec/mpegaudiodsp_fixed.c
@@ -16,5 +16,5 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#define CONFIG_FLOAT 0
+#define USE_FLOATS 0
#include "mpegaudiodsp_template.c"
diff --git a/libavcodec/mpegaudiodsp_float.c b/libavcodec/mpegaudiodsp_float.c
index 777cac8..c45b136 100644
--- a/libavcodec/mpegaudiodsp_float.c
+++ b/libavcodec/mpegaudiodsp_float.c
@@ -16,5 +16,5 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#define CONFIG_FLOAT 1
+#define USE_FLOATS 1
#include "mpegaudiodsp_template.c"
diff --git a/libavcodec/mpegaudiodsp_template.c b/libavcodec/mpegaudiodsp_template.c
index f79e068..62454ca 100644
--- a/libavcodec/mpegaudiodsp_template.c
+++ b/libavcodec/mpegaudiodsp_template.c
@@ -27,7 +27,7 @@
#include "mpegaudiodsp.h"
#include "mpegaudio.h"
-#if CONFIG_FLOAT
+#if USE_FLOATS
#define RENAME(n) n##_float
static inline float round_sample(float *sum)
@@ -125,7 +125,7 @@
register const MPA_INT *w, *w2, *p;
int j;
OUT_INT *samples2;
-#if CONFIG_FLOAT
+#if USE_FLOATS
float sum, sum2;
#else
int64_t sum, sum2;
@@ -200,7 +200,7 @@
for(i=0;i<257;i++) {
INTFLOAT v;
v = ff_mpa_enwindow[i];
-#if CONFIG_FLOAT
+#if USE_FLOATS
v *= 1.0 / (1LL<<(16 + FRAC_BITS));
#endif
window[i] = v;
diff --git a/libavcodec/mpegaudioenc_fixed.c b/libavcodec/mpegaudioenc_fixed.c
new file mode 100644
index 0000000..022b6fe
--- /dev/null
+++ b/libavcodec/mpegaudioenc_fixed.c
@@ -0,0 +1,41 @@
+/*
+ * The simplest mpeg audio layer 2 encoder
+ * Copyright (c) 2000, 2001 Fabrice Bellard
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "mpegaudioenc_template.c"
+
+AVCodec ff_mp2fixed_encoder = {
+ .name = "mp2fixed",
+ .long_name = NULL_IF_CONFIG_SMALL("MP2 fixed point (MPEG audio layer 2)"),
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = AV_CODEC_ID_MP2,
+ .priv_data_size = sizeof(MpegAudioContext),
+ .init = MPA_encode_init,
+ .encode2 = MPA_encode_frame,
+ .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16,
+ AV_SAMPLE_FMT_NONE },
+ .supported_samplerates = (const int[]){
+ 44100, 48000, 32000, 22050, 24000, 16000, 0
+ },
+ .channel_layouts = (const uint64_t[]){ AV_CH_LAYOUT_MONO,
+ AV_CH_LAYOUT_STEREO,
+ 0 },
+ .defaults = mp2_defaults,
+};
diff --git a/libavcodec/mpegaudioenc_float.c b/libavcodec/mpegaudioenc_float.c
new file mode 100644
index 0000000..4d4ab2d
--- /dev/null
+++ b/libavcodec/mpegaudioenc_float.c
@@ -0,0 +1,42 @@
+/*
+ * The simplest mpeg audio layer 2 encoder
+ * Copyright (c) 2000, 2001 Fabrice Bellard
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#define USE_FLOATS 1
+#include "mpegaudioenc_template.c"
+
+AVCodec ff_mp2_encoder = {
+ .name = "mp2",
+ .long_name = NULL_IF_CONFIG_SMALL("MP2 (MPEG audio layer 2)"),
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = AV_CODEC_ID_MP2,
+ .priv_data_size = sizeof(MpegAudioContext),
+ .init = MPA_encode_init,
+ .encode2 = MPA_encode_frame,
+ .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16,
+ AV_SAMPLE_FMT_NONE },
+ .supported_samplerates = (const int[]){
+ 44100, 48000, 32000, 22050, 24000, 16000, 0
+ },
+ .channel_layouts = (const uint64_t[]){ AV_CH_LAYOUT_MONO,
+ AV_CH_LAYOUT_STEREO,
+ 0 },
+ .defaults = mp2_defaults,
+};
diff --git a/libavcodec/mpegaudioenc.c b/libavcodec/mpegaudioenc_template.c
similarity index 90%
rename from libavcodec/mpegaudioenc.c
rename to libavcodec/mpegaudioenc_template.c
index 63c8460..b2dfe78 100644
--- a/libavcodec/mpegaudioenc.c
+++ b/libavcodec/mpegaudioenc_template.c
@@ -35,6 +35,8 @@
#include "mpegaudio.h"
#include "mpegaudiodsp.h"
+#include "mpegaudiodata.h"
+#include "mpegaudiotab.h"
/* currently, cannot change these constants (need to modify
quantization stage) */
@@ -59,14 +61,18 @@
unsigned char scale_code[MPA_MAX_CHANNELS][SBLIMIT];
int sblimit; /* number of used subbands */
const unsigned char *alloc_table;
+ int16_t filter_bank[512];
+ int scale_factor_table[64];
+ unsigned char scale_diff_table[128];
+#if USE_FLOATS
+ float scale_factor_inv_table[64];
+#else
+ int8_t scale_factor_shift[64];
+ unsigned short scale_factor_mult[64];
+#endif
+ unsigned short total_quant_bits[17]; /* total number of bits per allocation group */
} MpegAudioContext;
-/* define it to use floats in quantization (I don't like floats !) */
-#define USE_FLOATS
-
-#include "mpegaudiodata.h"
-#include "mpegaudiotab.h"
-
static av_cold int MPA_encode_init(AVCodecContext *avctx)
{
MpegAudioContext *s = avctx->priv_data;
@@ -140,24 +146,24 @@
#if WFRAC_BITS != 16
v = (v + (1 << (16 - WFRAC_BITS - 1))) >> (16 - WFRAC_BITS);
#endif
- filter_bank[i] = v;
+ s->filter_bank[i] = v;
if ((i & 63) != 0)
v = -v;
if (i != 0)
- filter_bank[512 - i] = v;
+ s->filter_bank[512 - i] = v;
}
for(i=0;i<64;i++) {
v = (int)(exp2((3 - i) / 3.0) * (1 << 20));
if (v <= 0)
v = 1;
- scale_factor_table[i] = v;
-#ifdef USE_FLOATS
- scale_factor_inv_table[i] = exp2(-(3 - i) / 3.0) / (float)(1 << 20);
+ s->scale_factor_table[i] = v;
+#if USE_FLOATS
+ s->scale_factor_inv_table[i] = exp2(-(3 - i) / 3.0) / (float)(1 << 20);
#else
#define P 15
- scale_factor_shift[i] = 21 - P - (i / 3);
- scale_factor_mult[i] = (1 << P) * exp2((i % 3) / 3.0);
+ s->scale_factor_shift[i] = 21 - P - (i / 3);
+ s->scale_factor_mult[i] = (1 << P) * exp2((i % 3) / 3.0);
#endif
}
for(i=0;i<128;i++) {
@@ -172,7 +178,7 @@
v = 3;
else
v = 4;
- scale_diff_table[i] = v;
+ s->scale_diff_table[i] = v;
}
for(i=0;i<17;i++) {
@@ -181,7 +187,7 @@
v = -v;
else
v = v * 3;
- total_quant_bits[i] = 12 * v;
+ s->total_quant_bits[i] = 12 * v;
}
return 0;
@@ -328,7 +334,7 @@
/* filter */
p = s->samples_buf[ch] + offset;
- q = filter_bank;
+ q = s->filter_bank;
/* maxsum = 23169 */
for(i=0;i<64;i++) {
sum = p[0*64] * q[0*64];
@@ -362,7 +368,8 @@
s->samples_offset[ch] = offset;
}
-static void compute_scale_factors(unsigned char scale_code[SBLIMIT],
+static void compute_scale_factors(MpegAudioContext *s,
+ unsigned char scale_code[SBLIMIT],
unsigned char scale_factors[SBLIMIT][3],
int sb_samples[3][12][SBLIMIT],
int sblimit)
@@ -389,7 +396,7 @@
use at most 2 compares to find the index */
index = (21 - n) * 3 - 3;
if (index >= 0) {
- while (vmax <= scale_factor_table[index+1])
+ while (vmax <= s->scale_factor_table[index+1])
index++;
} else {
index = 0; /* very unlikely case of overflow */
@@ -399,7 +406,7 @@
}
av_dlog(NULL, "%2d:%d in=%x %x %d\n",
- j, i, vmax, scale_factor_table[index], index);
+ j, i, vmax, s->scale_factor_table[index], index);
/* store the scale factor */
av_assert2(index >=0 && index <= 63);
sf[i] = index;
@@ -407,8 +414,8 @@
/* compute the transmission factor : look if the scale factors
are close enough to each other */
- d1 = scale_diff_table[sf[0] - sf[1] + 64];
- d2 = scale_diff_table[sf[1] - sf[2] + 64];
+ d1 = s->scale_diff_table[sf[0] - sf[1] + 64];
+ d2 = s->scale_diff_table[sf[1] - sf[2] + 64];
/* handle the 25 cases */
switch(d1 * 5 + d2) {
@@ -558,12 +565,12 @@
if (subband_status[max_ch][max_sb] == SB_NOTALLOCATED) {
/* nothing was coded for this band: add the necessary bits */
incr = 2 + nb_scale_factors[s->scale_code[max_ch][max_sb]] * 6;
- incr += total_quant_bits[alloc[1]];
+ incr += s->total_quant_bits[alloc[1]];
} else {
/* increments bit allocation */
b = bit_alloc[max_ch][max_sb];
- incr = total_quant_bits[alloc[b + 1]] -
- total_quant_bits[alloc[b]];
+ incr = s->total_quant_bits[alloc[b + 1]] -
+ s->total_quant_bits[alloc[b]];
}
if (current_frame_size + incr <= max_frame_size) {
@@ -674,18 +681,18 @@
for(m=0;m<3;m++) {
sample = s->sb_samples[ch][k][l + m][i];
/* divide by scale factor */
-#ifdef USE_FLOATS
+#if USE_FLOATS
{
float a;
- a = (float)sample * scale_factor_inv_table[s->scale_factors[ch][i][k]];
+ a = (float)sample * s->scale_factor_inv_table[s->scale_factors[ch][i][k]];
q[m] = (int)((a + 1.0) * steps * 0.5);
}
#else
{
int q1, e, shift, mult;
e = s->scale_factors[ch][i][k];
- shift = scale_factor_shift[e];
- mult = scale_factor_mult[e];
+ shift = s->scale_factor_shift[e];
+ mult = s->scale_factor_mult[e];
/* normalize to P bits */
if (shift < 0)
@@ -694,6 +701,8 @@
q1 = sample >> shift;
q1 = (q1 * mult) >> P;
q[m] = ((q1 + (1 << P)) * steps) >> (P + 1);
+ if (q[m] < 0)
+ q[m] = 0;
}
#endif
if (q[m] >= steps)
@@ -740,7 +749,7 @@
}
for(i=0;i<s->nb_channels;i++) {
- compute_scale_factors(s->scale_code[i], s->scale_factors[i],
+ compute_scale_factors(s, s->scale_code[i], s->scale_factors[i],
s->sb_samples[i], s->sblimit);
}
for(i=0;i<s->nb_channels;i++) {
@@ -768,21 +777,3 @@
{ NULL },
};
-AVCodec ff_mp2_encoder = {
- .name = "mp2",
- .long_name = NULL_IF_CONFIG_SMALL("MP2 (MPEG audio layer 2)"),
- .type = AVMEDIA_TYPE_AUDIO,
- .id = AV_CODEC_ID_MP2,
- .priv_data_size = sizeof(MpegAudioContext),
- .init = MPA_encode_init,
- .encode2 = MPA_encode_frame,
- .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16,
- AV_SAMPLE_FMT_NONE },
- .supported_samplerates = (const int[]){
- 44100, 48000, 32000, 22050, 24000, 16000, 0
- },
- .channel_layouts = (const uint64_t[]){ AV_CH_LAYOUT_MONO,
- AV_CH_LAYOUT_STEREO,
- 0 },
- .defaults = mp2_defaults,
-};
diff --git a/libavcodec/mpegaudiotab.h b/libavcodec/mpegaudiotab.h
index 35129e6..42d42d8 100644
--- a/libavcodec/mpegaudiotab.h
+++ b/libavcodec/mpegaudiotab.h
@@ -79,20 +79,6 @@
};
-static int16_t filter_bank[512];
-
-static int scale_factor_table[64];
-#ifdef USE_FLOATS
-static float scale_factor_inv_table[64];
-#else
-static int8_t scale_factor_shift[64];
-static unsigned short scale_factor_mult[64];
-#endif
-static unsigned char scale_diff_table[128];
-
-/* total number of bits per allocation group */
-static unsigned short total_quant_bits[17];
-
/* signal to noise ratio of each quantification step (could be
computed from quant_steps[]). The values are dB multiplied by 10
*/
diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c
index 32d6fa7..7380af0 100644
--- a/libavcodec/mpegvideo.c
+++ b/libavcodec/mpegvideo.c
@@ -30,6 +30,7 @@
#include "libavutil/attributes.h"
#include "libavutil/avassert.h"
#include "libavutil/imgutils.h"
+#include "libavutil/internal.h"
#include "avcodec.h"
#include "dsputil.h"
#include "h264chroma.h"
@@ -195,7 +196,7 @@
return 0;
}
-int ff_mpv_frame_size_alloc(MpegEncContext *s, int linesize)
+static int frame_size_alloc(MpegEncContext *s, int linesize)
{
int alloc_size = FFALIGN(FFABS(linesize) + 64, 32);
@@ -240,7 +241,7 @@
r = avcodec_default_get_buffer2(s->avctx, &pic->f, 0);
}
- if (r < 0 || !pic->f.data[0]) {
+ if (r < 0 || !pic->f.buf[0]) {
av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed (%d %p)\n",
r, pic->f.data[0]);
return -1;
@@ -274,7 +275,7 @@
}
if (!s->edge_emu_buffer &&
- (ret = ff_mpv_frame_size_alloc(s, pic->f.linesize[0])) < 0) {
+ (ret = frame_size_alloc(s, pic->f.linesize[0])) < 0) {
av_log(s->avctx, AV_LOG_ERROR,
"get_buffer() failed to allocate context scratch buffers.\n");
ff_mpeg_unref_picture(s, pic);
@@ -284,7 +285,7 @@
return 0;
}
-static void free_picture_tables(Picture *pic)
+void ff_free_picture_tables(Picture *pic)
{
int i;
@@ -327,8 +328,7 @@
return AVERROR(ENOMEM);
}
- if (s->out_format == FMT_H263 || s->encoding ||
- (s->avctx->debug & FF_DEBUG_MV) || s->avctx->debug_mv) {
+ if (s->out_format == FMT_H263 || s->encoding || s->avctx->debug_mv) {
int mv_size = 2 * (b8_array_size + 4) * sizeof(int16_t);
int ref_index_size = 4 * mb_array_size;
@@ -382,13 +382,13 @@
if (pic->qscale_table_buf)
if ( pic->alloc_mb_width != s->mb_width
|| pic->alloc_mb_height != s->mb_height)
- free_picture_tables(pic);
+ ff_free_picture_tables(pic);
if (shared) {
av_assert0(pic->f.data[0]);
pic->shared = 1;
} else {
- av_assert0(!pic->f.data[0]);
+ av_assert0(!pic->f.buf[0]);
if (alloc_frame_buffer(s, pic) < 0)
return -1;
@@ -425,7 +425,7 @@
fail:
av_log(s->avctx, AV_LOG_ERROR, "Error allocating a picture.\n");
ff_mpeg_unref_picture(s, pic);
- free_picture_tables(pic);
+ ff_free_picture_tables(pic);
return AVERROR(ENOMEM);
}
@@ -449,7 +449,7 @@
av_buffer_unref(&pic->hwaccel_priv_buf);
if (pic->needs_realloc)
- free_picture_tables(pic);
+ ff_free_picture_tables(pic);
memset((uint8_t*)pic + off, 0, sizeof(*pic) - off);
}
@@ -465,7 +465,7 @@
av_buffer_unref(&dst->table);\
dst->table = av_buffer_ref(src->table);\
if (!dst->table) {\
- free_picture_tables(dst);\
+ ff_free_picture_tables(dst);\
return AVERROR(ENOMEM);\
}\
}\
@@ -537,6 +537,15 @@
return ret;
}
+static void exchange_uv(MpegEncContext *s)
+{
+ int16_t (*tmp)[64];
+
+ tmp = s->pblocks[4];
+ s->pblocks[4] = s->pblocks[5];
+ s->pblocks[5] = tmp;
+}
+
static int init_duplicate_context(MpegEncContext *s)
{
int y_size = s->b8_stride * (2 * s->mb_height + 1);
@@ -567,6 +576,8 @@
for (i = 0; i < 12; i++) {
s->pblocks[i] = &s->block[i];
}
+ if (s->avctx->codec_tag == AV_RL32("VCR2"))
+ exchange_uv(s);
if (s->out_format == FMT_H263) {
/* ac values */
@@ -641,8 +652,10 @@
for (i = 0; i < 12; i++) {
dst->pblocks[i] = &dst->block[i];
}
+ if (dst->avctx->codec_tag == AV_RL32("VCR2"))
+ exchange_uv(dst);
if (!dst->edge_emu_buffer &&
- (ret = ff_mpv_frame_size_alloc(dst, dst->linesize)) < 0) {
+ (ret = frame_size_alloc(dst, dst->linesize)) < 0) {
av_log(dst->avctx, AV_LOG_ERROR, "failed to allocate context "
"scratch buffers.\n");
return ret;
@@ -698,13 +711,12 @@
s->coded_picture_number = s1->coded_picture_number;
s->picture_number = s1->picture_number;
- s->input_picture_number = s1->input_picture_number;
av_assert0(!s->picture || s->picture != s1->picture);
if(s->picture)
for (i = 0; i < MAX_PICTURE_COUNT; i++) {
ff_mpeg_unref_picture(s, &s->picture[i]);
- if (s1->picture[i].f.data[0] &&
+ if (s1->picture[i].f.buf[0] &&
(ret = ff_mpeg_ref_picture(s, &s->picture[i], &s1->picture[i])) < 0)
return ret;
}
@@ -712,7 +724,7 @@
#define UPDATE_PICTURE(pic)\
do {\
ff_mpeg_unref_picture(s, &s->pic);\
- if (s1->pic.f.data[0])\
+ if (s1->pic.f.buf[0])\
ret = ff_mpeg_ref_picture(s, &s->pic, &s1->pic);\
else\
ret = update_picture_tables(&s->pic, &s1->pic);\
@@ -734,8 +746,9 @@
s->padding_bug_score = s1->padding_bug_score;
// MPEG4 timing info
- memcpy(&s->time_increment_bits, &s1->time_increment_bits,
- (char *) &s1->shape - (char *) &s1->time_increment_bits);
+ memcpy(&s->last_time_base, &s1->last_time_base,
+ (char *) &s1->pb_field_time + sizeof(s1->pb_field_time) -
+ (char *) &s1->last_time_base);
// B-frame info
s->max_b_frames = s1->max_b_frames;
@@ -761,7 +774,7 @@
// linesize dependend scratch buffer allocation
if (!s->edge_emu_buffer)
if (s1->linesize) {
- if (ff_mpv_frame_size_alloc(s, s1->linesize) < 0) {
+ if (frame_size_alloc(s, s1->linesize) < 0) {
av_log(s->avctx, AV_LOG_ERROR, "Failed to allocate context "
"scratch buffers.\n");
return AVERROR(ENOMEM);
@@ -779,10 +792,6 @@
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 != AV_PICTURE_TYPE_B) {
- s->last_non_b_pict_type = s1->pict_type;
- }
}
return 0;
@@ -805,9 +814,6 @@
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;
@@ -1034,32 +1040,9 @@
&s->chroma_y_shift);
/* convert fourcc to upper case */
- s->codec_tag = avpriv_toupper4(s->avctx->codec_tag);
- s->stream_codec_tag = avpriv_toupper4(s->avctx->stream_codec_tag);
+ s->codec_tag = avpriv_toupper4(s->avctx->codec_tag);
- s->avctx->coded_frame = &s->current_picture.f;
-
- if (s->encoding) {
- 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);
-
- FF_ALLOCZ_OR_GOTO(s->avctx, s->q_intra_matrix, 64 * 32 * sizeof(int), fail)
- FF_ALLOCZ_OR_GOTO(s->avctx, s->q_chroma_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_chroma_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->stream_codec_tag = avpriv_toupper4(s->avctx->stream_codec_tag);
FF_ALLOCZ_OR_GOTO(s->avctx, s->picture,
MAX_PICTURE_COUNT * sizeof(Picture), fail);
@@ -1261,36 +1244,19 @@
av_freep(&s->bitstream_buffer);
s->allocated_bitstream_buffer_size = 0;
- av_freep(&s->avctx->stats_out);
- av_freep(&s->ac_stats);
-
- if(s->q_chroma_intra_matrix != s->q_intra_matrix ) av_freep(&s->q_chroma_intra_matrix);
- if(s->q_chroma_intra_matrix16 != s->q_intra_matrix16) av_freep(&s->q_chroma_intra_matrix16);
- s->q_chroma_intra_matrix= NULL;
- s->q_chroma_intra_matrix16= NULL;
- av_freep(&s->q_intra_matrix);
- av_freep(&s->q_inter_matrix);
- av_freep(&s->q_intra_matrix16);
- av_freep(&s->q_inter_matrix16);
- av_freep(&s->input_picture);
- av_freep(&s->reordered_input_picture);
- av_freep(&s->dct_offset);
-
if (s->picture) {
for (i = 0; i < MAX_PICTURE_COUNT; i++) {
- free_picture_tables(&s->picture[i]);
+ ff_free_picture_tables(&s->picture[i]);
ff_mpeg_unref_picture(s, &s->picture[i]);
}
}
av_freep(&s->picture);
- free_picture_tables(&s->last_picture);
+ ff_free_picture_tables(&s->last_picture);
ff_mpeg_unref_picture(s, &s->last_picture);
- free_picture_tables(&s->current_picture);
+ ff_free_picture_tables(&s->current_picture);
ff_mpeg_unref_picture(s, &s->current_picture);
- free_picture_tables(&s->next_picture);
+ ff_free_picture_tables(&s->next_picture);
ff_mpeg_unref_picture(s, &s->next_picture);
- free_picture_tables(&s->new_picture);
- ff_mpeg_unref_picture(s, &s->new_picture);
free_context_frame(s);
@@ -1393,16 +1359,14 @@
}
}
-void ff_release_unused_pictures(MpegEncContext*s, int remove_current)
+static void release_unused_pictures(MpegEncContext *s)
{
int i;
/* release non reference frames */
for (i = 0; i < MAX_PICTURE_COUNT; i++) {
- if (!s->picture[i].reference &&
- (remove_current || &s->picture[i] != s->current_picture_ptr)) {
+ if (!s->picture[i].reference)
ff_mpeg_unref_picture(s, &s->picture[i]);
- }
}
}
@@ -1410,7 +1374,7 @@
{
if (pic == s->last_picture_ptr)
return 0;
- if (pic->f.data[0] == NULL)
+ if (pic->f.buf[0] == NULL)
return 1;
if (pic->needs_realloc && !(pic->reference & DELAYED_PIC_REF))
return 1;
@@ -1423,7 +1387,7 @@
if (shared) {
for (i = 0; i < MAX_PICTURE_COUNT; i++) {
- if (s->picture[i].f.data[0] == NULL && &s->picture[i] != s->last_picture_ptr)
+ if (s->picture[i].f.buf[0] == NULL && &s->picture[i] != s->last_picture_ptr)
return i;
}
} else {
@@ -1457,7 +1421,7 @@
if (ret >= 0 && ret < MAX_PICTURE_COUNT) {
if (s->picture[ret].needs_realloc) {
s->picture[ret].needs_realloc = 0;
- free_picture_tables(&s->picture[ret]);
+ ff_free_picture_tables(&s->picture[ret]);
ff_mpeg_unref_picture(s, &s->picture[ret]);
avcodec_get_frame_defaults(&s->picture[ret].f);
}
@@ -1504,7 +1468,7 @@
/* 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]) {
+ s->last_picture_ptr->f.buf[0]) {
ff_mpeg_unref_picture(s, s->last_picture_ptr);
}
@@ -1526,10 +1490,10 @@
ff_mpeg_unref_picture(s, &s->current_picture);
if (!s->encoding) {
- ff_release_unused_pictures(s, 1);
+ release_unused_pictures(s);
if (s->current_picture_ptr &&
- s->current_picture_ptr->f.data[0] == NULL) {
+ s->current_picture_ptr->f.buf[0] == NULL) {
// we already have a unused image
// (maybe it was set before reading the header)
pic = s->current_picture_ptr;
@@ -1589,13 +1553,13 @@
s->pict_type, s->droppable);
if ((s->last_picture_ptr == NULL ||
- s->last_picture_ptr->f.data[0] == NULL) &&
+ s->last_picture_ptr->f.buf[0] == NULL) &&
(s->pict_type != AV_PICTURE_TYPE_I ||
s->picture_structure != PICT_FRAME)) {
int h_chroma_shift, v_chroma_shift;
av_pix_fmt_get_chroma_sub_sample(s->avctx->pix_fmt,
&h_chroma_shift, &v_chroma_shift);
- if (s->pict_type == AV_PICTURE_TYPE_B && s->next_picture_ptr && s->next_picture_ptr->f.data[0])
+ if (s->pict_type == AV_PICTURE_TYPE_B && s->next_picture_ptr && s->next_picture_ptr->f.buf[0])
av_log(avctx, AV_LOG_DEBUG,
"allocating dummy last picture for B frame\n");
else if (s->pict_type != AV_PICTURE_TYPE_I)
@@ -1636,7 +1600,7 @@
ff_thread_report_progress(&s->last_picture_ptr->tf, INT_MAX, 1);
}
if ((s->next_picture_ptr == NULL ||
- s->next_picture_ptr->f.data[0] == NULL) &&
+ s->next_picture_ptr->f.buf[0] == NULL) &&
s->pict_type == AV_PICTURE_TYPE_B) {
/* Allocate a dummy frame */
i = ff_find_unused_picture(s, 0);
@@ -1660,21 +1624,21 @@
#endif
if (s->last_picture_ptr) {
ff_mpeg_unref_picture(s, &s->last_picture);
- if (s->last_picture_ptr->f.data[0] &&
+ if (s->last_picture_ptr->f.buf[0] &&
(ret = ff_mpeg_ref_picture(s, &s->last_picture,
s->last_picture_ptr)) < 0)
return ret;
}
if (s->next_picture_ptr) {
ff_mpeg_unref_picture(s, &s->next_picture);
- if (s->next_picture_ptr->f.data[0] &&
+ if (s->next_picture_ptr->f.buf[0] &&
(ret = ff_mpeg_ref_picture(s, &s->next_picture,
s->next_picture_ptr)) < 0)
return ret;
}
av_assert0(s->pict_type == AV_PICTURE_TYPE_I || (s->last_picture_ptr &&
- s->last_picture_ptr->f.data[0]));
+ s->last_picture_ptr->f.buf[0]));
if (s->picture_structure!= PICT_FRAME) {
int i;
@@ -1710,29 +1674,37 @@
update_noise_reduction(s);
}
+#if FF_API_XVMC
+FF_DISABLE_DEPRECATION_WARNINGS
if (CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration)
return ff_xvmc_field_start(s, avctx);
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif /* FF_API_XVMC */
return 0;
}
-/* generic function for encode/decode called after a
- * frame has been coded/decoded. */
+/* called after a frame has been decoded. */
void ff_MPV_frame_end(MpegEncContext *s)
{
+#if FF_API_XVMC
+FF_DISABLE_DEPRECATION_WARNINGS
/* 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) {
ff_xvmc_field_end(s);
- } else if ((s->er.error_count || s->encoding || !(s->avctx->codec->capabilities&CODEC_CAP_DRAW_HORIZ_BAND)) &&
- !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) &&
- !s->avctx->lowres
- ) {
+ } else
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif /* FF_API_XVMC */
+ if ((s->er.error_count || !(s->avctx->codec->capabilities&CODEC_CAP_DRAW_HORIZ_BAND)) &&
+ !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) &&
+ !s->avctx->lowres
+ ) {
const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(s->avctx->pix_fmt);
int hshift = desc->log2_chroma_w;
int vshift = desc->log2_chroma_h;
@@ -1752,30 +1724,6 @@
emms_c();
- 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].f.data[0] == s->current_picture.f.data[0]) {
- s->picture[i] = s->current_picture;
- break;
- }
- }
- av_assert0(i < MAX_PICTURE_COUNT);
-#endif
-
- // clear copies, to avoid confusion
-#if 0
- 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 = &s->current_picture_ptr->f;
-
if (s->current_picture.reference)
ff_thread_report_progress(&s->current_picture_ptr->tf, INT_MAX, 0);
}
@@ -2204,12 +2152,11 @@
if ((unsigned)src_x > FFMAX( h_edge_pos - (!!sx) - w, 0) ||
(unsigned)src_y > FFMAX((v_edge_pos >> field_based) - (!!sy) - h, 0)) {
- s->vdsp.emulated_edge_mc(s->edge_emu_buffer, s->linesize,
- src, s->linesize, w + 1,
- (h + 1) << field_based, src_x,
- src_y << field_based,
- h_edge_pos,
- v_edge_pos);
+ s->vdsp.emulated_edge_mc(s->edge_emu_buffer, src,
+ s->linesize, 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;
}
@@ -2307,21 +2254,22 @@
if ((unsigned) src_x > FFMAX( h_edge_pos - (!!sx) - 2 * block_s, 0) || uvsrc_y<0 ||
(unsigned) src_y > FFMAX((v_edge_pos >> field_based) - (!!sy) - h, 0)) {
- s->vdsp.emulated_edge_mc(s->edge_emu_buffer, linesize >> field_based, ptr_y,
- linesize >> field_based, 17, 17 + field_based,
+ s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr_y,
+ linesize >> field_based, linesize >> field_based,
+ 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->vdsp.emulated_edge_mc(uvbuf, uvlinesize >> field_based,
- ptr_cb, uvlinesize >> field_based, 9,
- 9 + field_based,
+ s->vdsp.emulated_edge_mc(uvbuf, ptr_cb,
+ uvlinesize >> field_based, uvlinesize >> field_based,
+ 9, 9 + field_based,
uvsrc_x, uvsrc_y << field_based,
h_edge_pos >> 1, v_edge_pos >> 1);
- s->vdsp.emulated_edge_mc(uvbuf + 16, uvlinesize >> field_based,
- ptr_cr, uvlinesize >> field_based, 9,
- 9 + field_based,
+ s->vdsp.emulated_edge_mc(uvbuf + 16, ptr_cr,
+ uvlinesize >> field_based,uvlinesize >> field_based,
+ 9, 9 + field_based,
uvsrc_x, uvsrc_y << field_based,
h_edge_pos >> 1, v_edge_pos >> 1);
ptr_cb = uvbuf;
@@ -2393,8 +2341,10 @@
ptr = ref_picture[1] + offset;
if ((unsigned) src_x > FFMAX(h_edge_pos - (!!sx) - block_s, 0) ||
(unsigned) src_y > FFMAX(v_edge_pos - (!!sy) - block_s, 0)) {
- s->vdsp.emulated_edge_mc(s->edge_emu_buffer, s->uvlinesize, ptr, s->uvlinesize,
- 9, 9, src_x, src_y, h_edge_pos, v_edge_pos);
+ s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr,
+ s->uvlinesize, s->uvlinesize,
+ 9, 9,
+ src_x, src_y, h_edge_pos, v_edge_pos);
ptr = s->edge_emu_buffer;
emu = 1;
}
@@ -2404,9 +2354,10 @@
ptr = ref_picture[2] + offset;
if (emu) {
- s->vdsp.emulated_edge_mc(s->edge_emu_buffer, s->uvlinesize,
- ptr, s->uvlinesize, 9, 9,
- src_x, src_y, h_edge_pos, v_edge_pos);
+ s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr,
+ s->uvlinesize, 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);
@@ -2667,10 +2618,15 @@
int lowres_flag, int is_mpeg12)
{
const int mb_xy = s->mb_y * s->mb_stride + s->mb_x;
+
+#if FF_API_XVMC
+FF_DISABLE_DEPRECATION_WARNINGS
if(CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration){
ff_xvmc_decode_mb(s);//xvmc uses pblocks
return;
}
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif /* FF_API_XVMC */
if(s->avctx->debug&FF_DEBUG_DCT_COEFF) {
/* print DCT coefficients */
@@ -2768,7 +2724,7 @@
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;
+ op_qpix = s->me.qpel_put;
if ((!s->no_rounding) || s->pict_type==AV_PICTURE_TYPE_B){
op_pix = s->hdsp.put_pixels_tab;
}else{
@@ -2879,7 +2835,7 @@
}else{
dct_linesize = uvlinesize << s->interlaced_dct;
- dct_offset = s->interlaced_dct? uvlinesize : uvlinesize*block_size;
+ dct_offset = s->interlaced_dct ? uvlinesize : uvlinesize*block_size;
s->dsp.idct_put(dest_cb, dct_linesize, block[4]);
s->dsp.idct_put(dest_cr, dct_linesize, block[5]);
diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h
index 2152af2..65c4f9e 100644
--- a/libavcodec/mpegvideo.h
+++ b/libavcodec/mpegvideo.h
@@ -33,6 +33,7 @@
#include "error_resilience.h"
#include "get_bits.h"
#include "h264chroma.h"
+#include "h263dsp.h"
#include "hpeldsp.h"
#include "put_bits.h"
#include "ratecontrol.h"
@@ -65,6 +66,8 @@
#define MAX_THREADS 32
#define MAX_PICTURE_COUNT 36
+#define MAX_B_FRAMES 16
+
#define ME_MAP_SIZE 64
#define ME_MAP_SHIFT 3
#define ME_MAP_MV_BITS 11
@@ -107,6 +110,30 @@
AVBufferRef *mb_type_buf;
uint32_t *mb_type;
+#if !FF_API_MB_TYPE
+#define MB_TYPE_INTRA4x4 0x0001
+#define MB_TYPE_INTRA16x16 0x0002 //FIXME H.264-specific
+#define MB_TYPE_INTRA_PCM 0x0004 //FIXME H.264-specific
+#define MB_TYPE_16x16 0x0008
+#define MB_TYPE_16x8 0x0010
+#define MB_TYPE_8x16 0x0020
+#define MB_TYPE_8x8 0x0040
+#define MB_TYPE_INTERLACED 0x0080
+#define MB_TYPE_DIRECT2 0x0100 //FIXME
+#define MB_TYPE_ACPRED 0x0200
+#define MB_TYPE_GMC 0x0400
+#define MB_TYPE_SKIP 0x0800
+#define MB_TYPE_P0L0 0x1000
+#define MB_TYPE_P1L0 0x2000
+#define MB_TYPE_P0L1 0x4000
+#define MB_TYPE_P1L1 0x8000
+#define MB_TYPE_L0 (MB_TYPE_P0L0 | MB_TYPE_P1L0)
+#define MB_TYPE_L1 (MB_TYPE_P0L1 | MB_TYPE_P1L1)
+#define MB_TYPE_L0L1 (MB_TYPE_L0 | MB_TYPE_L1)
+#define MB_TYPE_QUANT 0x00010000
+#define MB_TYPE_CBP 0x00020000
+#endif
+
AVBufferRef *mbskip_table_buf;
uint8_t *mbskip_table;
@@ -167,7 +194,6 @@
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 separate fields
- int sync; ///< has been decoded after a keyframe
int mb_var_sum; ///< sum of MB variance for current frame
int mc_mb_var_sum; ///< motion compensated MB variance for current frame
@@ -177,6 +203,7 @@
int reference;
int shared;
+ int recovered; ///< Picture at IDR or recovery point + recovery count
int crop;
int crop_left;
@@ -396,6 +423,7 @@
H264ChromaContext h264chroma;
HpelDSPContext hdsp;
VideoDSPContext vdsp;
+ H263DSPContext h263dsp;
int f_code; ///< forward MV resolution
int b_code; ///< backward MV resolution for B Frames (mpeg4)
int16_t (*p_mv_table_base)[2];
@@ -540,7 +568,6 @@
/* H.263 specific */
int gob_index;
int obmc; ///< overlapped block motion compensation
- int showed_packed_warning; ///< flag for having shown the warning about divxs invalid b frames
int mb_info; ///< interval for outputting info about mb offsets as side data
int prev_mb_info, last_mb_info;
uint8_t *mb_info_ptr;
@@ -557,7 +584,8 @@
int custom_pcf;
/* mpeg4 specific */
- int time_increment_bits; ///< number of bits to represent the fractional part of time
+ ///< number of bits to represent the fractional part of time (encoder only)
+ int time_increment_bits;
int last_time_base;
int time_base; ///< time in seconds of last I,P,S Frame
int64_t time; ///< time of current frame
@@ -566,61 +594,30 @@
uint16_t pb_time; ///< time distance between the last b and p,s,i frame
uint16_t pp_field_time;
uint16_t pb_field_time; ///< like above, just for interlaced
- int shape;
- int vol_sprite_usage;
- int sprite_width;
- int sprite_height;
- int sprite_left;
- int sprite_top;
- int sprite_brightness_change;
- int num_sprite_warping_points;
int real_sprite_warping_points;
- uint16_t sprite_traj[4][2]; ///< sprite trajectory points
int sprite_offset[2][2]; ///< sprite offset[isChroma][isMVY]
int sprite_delta[2][2]; ///< sprite_delta [isY][isMVY]
- int sprite_shift[2]; ///< sprite shift [isChroma]
int mcsel;
int quant_precision;
int quarter_sample; ///< 1->qpel, 0->half pel ME/MC
- int scalability;
- int hierachy_type;
- int enhancement_type;
- int new_pred;
- int reduced_res_vop;
int aspect_ratio_info; //FIXME remove
int sprite_warping_accuracy;
- int low_latency_sprite;
int data_partitioning; ///< data partitioning flag from header
int partitioned_frame; ///< is current frame partitioned
- int rvlc; ///< reversible vlc
- int resync_marker; ///< could this stream contain resync markers
int low_delay; ///< no reordering needed / has no b-frames
int vo_type;
int vol_control_parameters; ///< does the stream contain the low_delay flag, used to workaround buggy encoders
- int intra_dc_threshold; ///< QP above whch the ac VLC should be used for intra dc
- int use_intra_dc_vlc;
PutBitContext tex_pb; ///< used for data partitioned VOPs
PutBitContext pb2; ///< used for data partitioned VOPs
int mpeg_quant;
- int t_frame; ///< time distance of first I -> B, used for interlaced b frames
int padding_bug_score; ///< used to detect the VERY common padding bug in MPEG4
- int cplx_estimation_trash_i;
- int cplx_estimation_trash_p;
- int cplx_estimation_trash_b;
/* divx specific, used to workaround (many) bugs in divx5 */
- int divx_version;
- int divx_build;
int divx_packed;
uint8_t *bitstream_buffer; //Divx 5.01 puts several frames in a single one, this is used to reorder them
int bitstream_buffer_size;
unsigned int allocated_bitstream_buffer_size;
- int xvid_build;
-
- /* lavc specific stuff, used to workaround bugs in libavcodec */
- int lavc_build;
-
/* RV10 specific */
int rv10_version; ///< RV10 version: 0 or 3
int rv10_first_dc_coded[3];
@@ -628,8 +625,6 @@
/* MJPEG specific */
struct MJpegContext *mjpeg_ctx;
- int mjpeg_vsample[3]; ///< vertical sampling factors, default = {2, 1, 1}
- int mjpeg_hsample[3]; ///< horizontal sampling factors, default = {2, 1, 1}
int esc_pos;
/* MSMPEG4 specific */
@@ -656,7 +651,6 @@
/* Mpeg1 specific */
int gop_picture_number; ///< index of the first picture of a GOP based on fake_pic_num & mpeg1 specific
int last_mv_dir; ///< last mv_dir, used for b frame encoding
- int broken_link; ///< no_output_of_prior_pics_flag
uint8_t *vbv_delay_ptr; ///< pointer to vbv_delay in the bitstream
/* MPEG-2-specific - I wished not to have to support this mess. */
@@ -687,7 +681,6 @@
int progressive_frame;
int full_pel[2];
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.
@@ -745,6 +738,11 @@
int context_reinit;
ERContext er;
+
+ int error_rate;
+
+ /* temporary frames used by b_frame_strategy = 2 */
+ AVFrame *tmp_frames[MAX_B_FRAMES + 2];
} MpegEncContext;
#define REBASE_PICTURE(pic, new_ctx, old_ctx) \
@@ -770,7 +768,9 @@
FF_MPV_OFFSET(luma_elim_threshold), AV_OPT_TYPE_INT, { .i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS },\
{ "chroma_elim_threshold", "single coefficient elimination threshold for chrominance (negative values also consider dc coefficient)",\
FF_MPV_OFFSET(chroma_elim_threshold), AV_OPT_TYPE_INT, { .i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS },\
-{ "quantizer_noise_shaping", NULL, FF_MPV_OFFSET(quantizer_noise_shaping), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, FF_MPV_OPT_FLAGS },
+{ "quantizer_noise_shaping", NULL, FF_MPV_OFFSET(quantizer_noise_shaping), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, FF_MPV_OPT_FLAGS },\
+{ "error_rate", "Simulate errors in the bitstream to test error concealment.", \
+ FF_MPV_OFFSET(error_rate), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, FF_MPV_OPT_FLAGS },
extern const AVOption ff_mpv_generic_options[];
@@ -791,7 +791,6 @@
void ff_MPV_decode_defaults(MpegEncContext *s);
int ff_MPV_common_init(MpegEncContext *s);
-int ff_mpv_frame_size_alloc(MpegEncContext *s, int linesize);
int ff_MPV_common_frame_size_change(MpegEncContext *s);
void ff_MPV_common_end(MpegEncContext *s);
void ff_MPV_decode_mb(MpegEncContext *s, int16_t block[12][64]);
@@ -823,7 +822,6 @@
int ff_mpv_export_qp_table(MpegEncContext *s, AVFrame *f, Picture *p, int qp_type);
void ff_write_quant_matrix(PutBitContext *pb, uint16_t *matrix);
-void ff_release_unused_pictures(MpegEncContext *s, int remove_current);
int ff_find_unused_picture(MpegEncContext *s, int shared);
void ff_denoise_dct(MpegEncContext *s, int16_t *block);
int ff_update_duplicate_context(MpegEncContext *dst, MpegEncContext *src);
@@ -924,7 +922,6 @@
extern const uint8_t ff_aic_dc_scale_table[32];
extern const uint8_t ff_h263_chroma_qscale_table[32];
-extern const uint8_t ff_h263_loop_filter_strength[32];
/* rv10.c */
void ff_rv10_encode_picture_header(MpegEncContext *s, int picture_number);
@@ -956,6 +953,7 @@
int ff_mpeg_ref_picture(MpegEncContext *s, Picture *dst, Picture *src);
void ff_mpeg_unref_picture(MpegEncContext *s, Picture *picture);
+void ff_free_picture_tables(Picture *pic);
#endif /* AVCODEC_MPEGVIDEO_H */
diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index 655cc59..fb9f451 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -27,6 +27,8 @@
* The simplest mpeg encoder (well, it was the simplest!).
*/
+#include <stdint.h>
+
#include "libavutil/internal.h"
#include "libavutil/intmath.h"
#include "libavutil/mathematics.h"
@@ -215,12 +217,16 @@
}
s->me.mv_penalty = default_mv_penalty;
s->fcode_tab = default_fcode_tab;
+
+ s->input_picture_number = 0;
+ s->picture_in_gop_number = 0;
}
av_cold int ff_dct_encode_init(MpegEncContext *s) {
if (ARCH_X86)
ff_dct_encode_init_x86(s);
+ ff_h263dsp_init(&s->h263dsp);
if (!s->dct_quantize)
s->dct_quantize = ff_dct_quantize_c;
if (!s->denoise_dct)
@@ -236,8 +242,7 @@
av_cold int ff_MPV_encode_init(AVCodecContext *avctx)
{
MpegEncContext *s = avctx->priv_data;
- int i;
- int chroma_h_shift, chroma_v_shift;
+ int i, ret;
MPV_encode_defaults(s);
@@ -250,21 +255,6 @@
return -1;
}
break;
- case AV_CODEC_ID_LJPEG:
- if (avctx->pix_fmt != AV_PIX_FMT_YUVJ420P &&
- avctx->pix_fmt != AV_PIX_FMT_YUVJ422P &&
- avctx->pix_fmt != AV_PIX_FMT_YUVJ444P &&
- avctx->pix_fmt != AV_PIX_FMT_BGR0 &&
- avctx->pix_fmt != AV_PIX_FMT_BGRA &&
- avctx->pix_fmt != AV_PIX_FMT_BGR24 &&
- ((avctx->pix_fmt != AV_PIX_FMT_YUV420P &&
- avctx->pix_fmt != AV_PIX_FMT_YUV422P &&
- avctx->pix_fmt != AV_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 AV_CODEC_ID_MJPEG:
case AV_CODEC_ID_AMV:
if (avctx->pix_fmt != AV_PIX_FMT_YUVJ420P &&
@@ -315,6 +305,11 @@
s->avctx = avctx;
s->flags = avctx->flags;
s->flags2 = avctx->flags2;
+ if (avctx->max_b_frames > MAX_B_FRAMES) {
+ av_log(avctx, AV_LOG_ERROR, "Too many B-frames requested, maximum "
+ "is %d.\n", MAX_B_FRAMES);
+ avctx->max_b_frames = MAX_B_FRAMES;
+ }
s->max_b_frames = avctx->max_b_frames;
s->codec_id = avctx->codec->id;
s->strict_std_compliance = avctx->strict_std_compliance;
@@ -452,6 +447,11 @@
av_log(avctx, AV_LOG_ERROR, "b frames not supported by codec\n");
return -1;
}
+ if (s->max_b_frames < 0) {
+ av_log(avctx, AV_LOG_ERROR,
+ "max b frames must be 0 or positive for mpegvideo based encoders\n");
+ return -1;
+ }
if ((s->codec_id == AV_CODEC_ID_MPEG4 ||
s->codec_id == AV_CODEC_ID_H263 ||
@@ -641,8 +641,6 @@
av_log(avctx, AV_LOG_DEBUG, "intra_quant_bias = %d inter_quant_bias = %d\n",s->intra_quant_bias,s->inter_quant_bias);
- avcodec_get_chroma_sub_sample(avctx->pix_fmt, &chroma_h_shift, &chroma_v_shift);
-
if (avctx->codec_id == AV_CODEC_ID_MPEG4 &&
s->avctx->time_base.den > (1 << 16) - 1) {
av_log(avctx, AV_LOG_ERROR,
@@ -666,30 +664,11 @@
avctx->delay = s->low_delay ? 0 : (s->max_b_frames + 1);
s->rtp_mode = 1;
break;
- case AV_CODEC_ID_LJPEG:
case AV_CODEC_ID_MJPEG:
case AV_CODEC_ID_AMV:
s->out_format = FMT_MJPEG;
s->intra_only = 1; /* force intra only for jpeg */
- if (avctx->codec->id == AV_CODEC_ID_LJPEG &&
- (avctx->pix_fmt == AV_PIX_FMT_BGR0
- || s->avctx->pix_fmt == AV_PIX_FMT_BGRA
- || s->avctx->pix_fmt == AV_PIX_FMT_BGR24)) {
- 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 if (avctx->pix_fmt == AV_PIX_FMT_YUV444P || avctx->pix_fmt == AV_PIX_FMT_YUVJ444P) {
- s->mjpeg_vsample[0] = s->mjpeg_vsample[1] = s->mjpeg_vsample[2] = 2;
- s->mjpeg_hsample[0] = s->mjpeg_hsample[1] = s->mjpeg_hsample[2] = 1;
- } else {
- s->mjpeg_vsample[0] = 2;
- 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;
- }
- if (!(CONFIG_MJPEG_ENCODER || CONFIG_LJPEG_ENCODER) ||
+ if (!CONFIG_MJPEG_ENCODER ||
ff_mjpeg_encode_init(s) < 0)
return -1;
avctx->delay = 0;
@@ -821,6 +800,31 @@
if (ff_MPV_common_init(s) < 0)
return -1;
+ s->avctx->coded_frame = &s->current_picture.f;
+
+ 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);
+
+ FF_ALLOCZ_OR_GOTO(s->avctx, s->q_intra_matrix, 64 * 32 * sizeof(int), fail);
+ FF_ALLOCZ_OR_GOTO(s->avctx, s->q_chroma_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_chroma_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_dct_encode_init(s);
if ((CONFIG_H263P_ENCODER || CONFIG_RV20_ENCODER) && s->modified_quant)
@@ -876,22 +880,70 @@
if (ff_rate_control_init(s) < 0)
return -1;
+#if FF_API_ERROR_RATE
+ FF_DISABLE_DEPRECATION_WARNINGS
+ if (avctx->error_rate)
+ s->error_rate = avctx->error_rate;
+ FF_ENABLE_DEPRECATION_WARNINGS;
+#endif
+
+ if (avctx->b_frame_strategy == 2) {
+ for (i = 0; i < s->max_b_frames + 2; i++) {
+ s->tmp_frames[i] = av_frame_alloc();
+ if (!s->tmp_frames[i])
+ return AVERROR(ENOMEM);
+
+ s->tmp_frames[i]->format = AV_PIX_FMT_YUV420P;
+ s->tmp_frames[i]->width = s->width >> avctx->brd_scale;
+ s->tmp_frames[i]->height = s->height >> avctx->brd_scale;
+
+ ret = av_frame_get_buffer(s->tmp_frames[i], 32);
+ if (ret < 0)
+ return ret;
+ }
+ }
+
return 0;
+fail:
+ ff_MPV_encode_end(avctx);
+ return AVERROR_UNKNOWN;
}
av_cold int ff_MPV_encode_end(AVCodecContext *avctx)
{
MpegEncContext *s = avctx->priv_data;
+ int i;
ff_rate_control_uninit(s);
ff_MPV_common_end(s);
- if ((CONFIG_MJPEG_ENCODER || CONFIG_LJPEG_ENCODER) &&
+ if (CONFIG_MJPEG_ENCODER &&
s->out_format == FMT_MJPEG)
ff_mjpeg_encode_close(s);
av_freep(&avctx->extradata);
+ for (i = 0; i < FF_ARRAY_ELEMS(s->tmp_frames); i++)
+ av_frame_free(&s->tmp_frames[i]);
+
+ ff_free_picture_tables(&s->new_picture);
+ ff_mpeg_unref_picture(s, &s->new_picture);
+
+ av_freep(&s->avctx->stats_out);
+ av_freep(&s->ac_stats);
+
+ if(s->q_chroma_intra_matrix != s->q_intra_matrix ) av_freep(&s->q_chroma_intra_matrix);
+ if(s->q_chroma_intra_matrix16 != s->q_intra_matrix16) av_freep(&s->q_chroma_intra_matrix16);
+ s->q_chroma_intra_matrix= NULL;
+ s->q_chroma_intra_matrix16= NULL;
+ av_freep(&s->q_intra_matrix);
+ av_freep(&s->q_inter_matrix);
+ av_freep(&s->q_intra_matrix16);
+ av_freep(&s->q_inter_matrix16);
+ av_freep(&s->input_picture);
+ av_freep(&s->reordered_input_picture);
+ av_freep(&s->dct_offset);
+
return 0;
}
@@ -984,8 +1036,8 @@
if (pic_arg->linesize[2] != s->uvlinesize)
direct = 0;
- av_dlog(s->avctx, "%d %d %d %d\n", pic_arg->linesize[0],
- pic_arg->linesize[1], (int) s->linesize, (int) s->uvlinesize);
+ av_dlog(s->avctx, "%d %d %td %td\n", pic_arg->linesize[0],
+ pic_arg->linesize[1], s->linesize, s->uvlinesize);
if (direct) {
i = ff_find_unused_picture(s, 1);
@@ -1133,7 +1185,6 @@
{
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;
int64_t best_rd = INT64_MAX;
@@ -1168,19 +1219,9 @@
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;
- 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;
@@ -1190,13 +1231,13 @@
pre_input.f.data[2] += INPLACE_OFFSET;
}
- s->dsp.shrink[scale](input[i].data[0], input[i].linesize[0],
+ s->dsp.shrink[scale](s->tmp_frames[i]->data[0], s->tmp_frames[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],
+ s->dsp.shrink[scale](s->tmp_frames[i]->data[1], s->tmp_frames[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],
+ s->dsp.shrink[scale](s->tmp_frames[i]->data[2], s->tmp_frames[i]->linesize[2],
pre_input.f.data[2], pre_input.f.linesize[2],
c->width >> 1, c->height >> 1);
}
@@ -1210,21 +1251,21 @@
c->error[0] = c->error[1] = c->error[2] = 0;
- input[0].pict_type = AV_PICTURE_TYPE_I;
- input[0].quality = 1 * FF_QP2LAMBDA;
+ s->tmp_frames[0]->pict_type = AV_PICTURE_TYPE_I;
+ s->tmp_frames[0]->quality = 1 * FF_QP2LAMBDA;
- out_size = encode_frame(c, &input[0]);
+ out_size = encode_frame(c, s->tmp_frames[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;
- input[i + 1].pict_type = is_p ?
+ s->tmp_frames[i + 1]->pict_type = is_p ?
AV_PICTURE_TYPE_P : AV_PICTURE_TYPE_B;
- input[i + 1].quality = is_p ? p_lambda : b_lambda;
+ s->tmp_frames[i + 1]->quality = is_p ? p_lambda : b_lambda;
- out_size = encode_frame(c, &input[i + 1]);
+ out_size = encode_frame(c, s->tmp_frames[i + 1]);
rd += (out_size * lambda2) >> (FF_LAMBDA_SHIFT - 3);
}
@@ -1246,10 +1287,6 @@
avcodec_close(c);
av_freep(&c);
- for (i = 0; i < s->max_b_frames + 2; i++) {
- av_freep(&input[i].data[0]);
- }
-
return best_b_count;
}
@@ -1431,6 +1468,39 @@
return 0;
}
+static void frame_end(MpegEncContext *s)
+{
+ if (s->unrestricted_mv &&
+ s->current_picture.reference &&
+ !s->intra_only) {
+ const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(s->avctx->pix_fmt);
+ int hshift = desc->log2_chroma_w;
+ int vshift = desc->log2_chroma_h;
+ s->dsp.draw_edges(s->current_picture.f.data[0], s->current_picture.f.linesize[0],
+ 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->current_picture.f.linesize[1],
+ 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->current_picture.f.linesize[2],
+ 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->f.quality;
+ if (s->pict_type!= AV_PICTURE_TYPE_B)
+ s->last_non_b_pict_type = s->pict_type;
+
+ s->avctx->coded_frame = &s->current_picture_ptr->f;
+
+}
+
int ff_MPV_encode_picture(AVCodecContext *avctx, AVPacket *pkt,
AVFrame *pic_arg, int *got_packet)
{
@@ -1486,10 +1556,10 @@
avctx->p_count = s->mb_num - s->i_count - s->skip_count;
avctx->skip_count = s->skip_count;
- ff_MPV_frame_end(s);
+ frame_end(s);
if (CONFIG_MJPEG_ENCODER && s->out_format == FMT_MJPEG)
- ff_mjpeg_encode_picture_trailer(s);
+ ff_mjpeg_encode_picture_trailer(&s->pb, s->header_bits);
if (avctx->rc_buffer_size) {
RateControlContext *rcc = &s->rc_context;
@@ -1815,19 +1885,25 @@
ptr_cr = s->new_picture.f.data[2] +
(mb_y * mb_block_height * wrap_c) + mb_x * mb_block_width;
- if((mb_x*16+16 > s->width || mb_y*16+16 > s->height) && s->codec_id != AV_CODEC_ID_AMV){
+ if((mb_x * 16 + 16 > s->width || mb_y * 16 + 16 > s->height) && s->codec_id != AV_CODEC_ID_AMV){
uint8_t *ebuf = s->edge_emu_buffer + 32;
int cw = (s->width + s->chroma_x_shift) >> s->chroma_x_shift;
int ch = (s->height + s->chroma_y_shift) >> s->chroma_y_shift;
- s->vdsp.emulated_edge_mc(ebuf, wrap_y, ptr_y, wrap_y, 16, 16, mb_x * 16,
- mb_y * 16, s->width, s->height);
+ s->vdsp.emulated_edge_mc(ebuf, ptr_y,
+ wrap_y, wrap_y,
+ 16, 16, mb_x * 16, mb_y * 16,
+ s->width, s->height);
ptr_y = ebuf;
- s->vdsp.emulated_edge_mc(ebuf + 18 * wrap_y, wrap_c, ptr_cb, wrap_c, mb_block_width,
- mb_block_height, mb_x * mb_block_width, mb_y * mb_block_height,
+ s->vdsp.emulated_edge_mc(ebuf + 18 * wrap_y, ptr_cb,
+ wrap_c, wrap_c,
+ mb_block_width, mb_block_height,
+ mb_x * mb_block_width, mb_y * mb_block_height,
cw, ch);
ptr_cb = ebuf + 18 * wrap_y;
- s->vdsp.emulated_edge_mc(ebuf + 18 * wrap_y + 16, wrap_c, ptr_cr, wrap_c, mb_block_width,
- mb_block_height, mb_x * mb_block_width, mb_y * mb_block_height,
+ s->vdsp.emulated_edge_mc(ebuf + 18 * wrap_y + 16, ptr_cr,
+ wrap_c, wrap_c,
+ mb_block_width, mb_block_height,
+ mb_x * mb_block_width, mb_y * mb_block_height,
cw, ch);
ptr_cr = ebuf + 18 * wrap_y + 16;
}
@@ -2567,6 +2643,7 @@
if(is_gob_start){
if(s->start_mb_y != mb_y || mb_x!=0){
write_slice_end(s);
+
if(CONFIG_MPEG4_ENCODER && s->codec_id==AV_CODEC_ID_MPEG4 && s->partitioned_frame){
ff_mpeg4_init_partitions(s);
}
@@ -2575,9 +2652,9 @@
av_assert2((put_bits_count(&s->pb)&7) == 0);
current_packet_size= put_bits_ptr(&s->pb) - s->ptr_lastgob;
- if(s->avctx->error_rate && s->resync_mb_x + s->resync_mb_y > 0){
+ if (s->error_rate && s->resync_mb_x + s->resync_mb_y > 0) {
int r= put_bits_count(&s->pb)/8 + s->picture_number + 16 + s->mb_x + s->mb_y;
- int d= 100 / s->avctx->error_rate;
+ int d = 100 / s->error_rate;
if(r % d == 0){
current_packet_size=0;
s->pb.buf_ptr= s->ptr_lastgob;
@@ -3372,7 +3449,8 @@
switch(s->out_format) {
case FMT_MJPEG:
if (CONFIG_MJPEG_ENCODER)
- ff_mjpeg_encode_picture_header(s);
+ ff_mjpeg_encode_picture_header(s->avctx, &s->pb, &s->intra_scantable,
+ s->intra_matrix);
break;
case FMT_H261:
if (CONFIG_H261_ENCODER)
@@ -3572,7 +3650,7 @@
av_assert2(level);
- if(s->out_format == FMT_H263){
+ if(s->out_format == FMT_H263 || s->out_format == FMT_H261){
unquant_coeff= alevel*qmul + qadd;
}else{ //MPEG1
j= s->dsp.idct_permutation[ scantable[i] ]; //FIXME optimize
@@ -3601,7 +3679,7 @@
}
}
- if(s->out_format == FMT_H263){
+ if(s->out_format == FMT_H263 || s->out_format == FMT_H261){
for(j=survivor_count-1; j>=0; j--){
int run= i - survivor[j];
int score= distortion + last_length[UNI_AC_ENC_INDEX(run, level)]*lambda;
@@ -3627,7 +3705,7 @@
}
}
- if(s->out_format == FMT_H263){
+ if(s->out_format == FMT_H263 || s->out_format == FMT_H261){
for(j=survivor_count-1; j>=0; j--){
int run= i - survivor[j];
int score= distortion + score_tab[i-run];
@@ -3660,7 +3738,7 @@
survivor[ survivor_count++ ]= i+1;
}
- if(s->out_format != FMT_H263){
+ if(s->out_format != FMT_H263 && s->out_format != FMT_H261){
last_score= 256*256*256*120;
for(i= survivor[0]; i<=last_non_zero + 1; i++){
int score= score_tab[i];
@@ -3693,7 +3771,7 @@
int alevel= FFABS(level);
int unquant_coeff, score, distortion;
- if(s->out_format == FMT_H263){
+ if(s->out_format == FMT_H263 || s->out_format == FMT_H261){
unquant_coeff= (alevel*qmul + qadd)>>3;
}else{ //MPEG1
unquant_coeff = ((( alevel << 1) + 1) * qscale * ((int) s->inter_matrix[0])) >> 4;
diff --git a/libavcodec/mpegvideo_motion.c b/libavcodec/mpegvideo_motion.c
index 09061d8..9ec3789 100644
--- a/libavcodec/mpegvideo_motion.c
+++ b/libavcodec/mpegvideo_motion.c
@@ -38,88 +38,96 @@
uint8_t **ref_picture)
{
uint8_t *ptr;
- int src_x, src_y;
+ int src_x, src_y, motion_x, motion_y;
ptrdiff_t offset, linesize, uvlinesize;
- int motion_x, motion_y;
- int emu=0;
+ int emu = 0;
- motion_x= s->sprite_offset[0][0];
- motion_y= s->sprite_offset[0][1];
- src_x = s->mb_x * 16 + (motion_x >> (s->sprite_warping_accuracy+1));
- src_y = s->mb_y * 16 + (motion_y >> (s->sprite_warping_accuracy+1));
- motion_x<<=(3-s->sprite_warping_accuracy);
- motion_y<<=(3-s->sprite_warping_accuracy);
- src_x = av_clip(src_x, -16, s->width);
+ motion_x = s->sprite_offset[0][0];
+ motion_y = s->sprite_offset[0][1];
+ src_x = s->mb_x * 16 + (motion_x >> (s->sprite_warping_accuracy + 1));
+ src_y = s->mb_y * 16 + (motion_y >> (s->sprite_warping_accuracy + 1));
+ motion_x <<= (3 - s->sprite_warping_accuracy);
+ motion_y <<= (3 - s->sprite_warping_accuracy);
+ src_x = av_clip(src_x, -16, s->width);
if (src_x == s->width)
- motion_x =0;
+ motion_x = 0;
src_y = av_clip(src_y, -16, s->height);
if (src_y == s->height)
- motion_y =0;
+ motion_y = 0;
- linesize = s->linesize;
+ linesize = s->linesize;
uvlinesize = s->uvlinesize;
- ptr = ref_picture[0] + (src_y * linesize) + src_x;
+ ptr = ref_picture[0] + src_y * linesize + src_x;
- if( (unsigned)src_x >= FFMAX(s->h_edge_pos - 17, 0)
- || (unsigned)src_y >= FFMAX(s->v_edge_pos - 17, 0)){
- s->vdsp.emulated_edge_mc(s->edge_emu_buffer, linesize,
- ptr, linesize, 17, 17, src_x, src_y,
+ if ((unsigned)src_x >= FFMAX(s->h_edge_pos - 17, 0) ||
+ (unsigned)src_y >= FFMAX(s->v_edge_pos - 17, 0)) {
+ s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr,
+ linesize, linesize,
+ 17, 17,
+ src_x, src_y,
s->h_edge_pos, s->v_edge_pos);
- ptr= s->edge_emu_buffer;
+ ptr = s->edge_emu_buffer;
}
- if((motion_x|motion_y)&7){
- s->dsp.gmc1(dest_y , ptr , linesize, 16, motion_x&15, motion_y&15, 128 - s->no_rounding);
- s->dsp.gmc1(dest_y+8, ptr+8, linesize, 16, motion_x&15, motion_y&15, 128 - s->no_rounding);
- }else{
+ if ((motion_x | motion_y) & 7) {
+ s->dsp.gmc1(dest_y, ptr, linesize, 16,
+ motion_x & 15, motion_y & 15, 128 - s->no_rounding);
+ s->dsp.gmc1(dest_y + 8, ptr + 8, linesize, 16,
+ motion_x & 15, motion_y & 15, 128 - s->no_rounding);
+ } else {
int dxy;
- dxy= ((motion_x>>3)&1) | ((motion_y>>2)&2);
- if (s->no_rounding){
+ dxy = ((motion_x >> 3) & 1) | ((motion_y >> 2) & 2);
+ if (s->no_rounding) {
s->hdsp.put_no_rnd_pixels_tab[0][dxy](dest_y, ptr, linesize, 16);
- }else{
- s->hdsp.put_pixels_tab [0][dxy](dest_y, ptr, linesize, 16);
+ } else {
+ s->hdsp.put_pixels_tab[0][dxy](dest_y, ptr, linesize, 16);
}
}
- if(CONFIG_GRAY && s->flags&CODEC_FLAG_GRAY) return;
+ if (CONFIG_GRAY && s->flags & CODEC_FLAG_GRAY)
+ return;
- motion_x= s->sprite_offset[1][0];
- motion_y= s->sprite_offset[1][1];
- src_x = s->mb_x * 8 + (motion_x >> (s->sprite_warping_accuracy+1));
- src_y = s->mb_y * 8 + (motion_y >> (s->sprite_warping_accuracy+1));
- motion_x<<=(3-s->sprite_warping_accuracy);
- motion_y<<=(3-s->sprite_warping_accuracy);
- src_x = av_clip(src_x, -8, s->width>>1);
- if (src_x == s->width>>1)
- motion_x =0;
- src_y = av_clip(src_y, -8, s->height>>1);
- if (src_y == s->height>>1)
- motion_y =0;
+ motion_x = s->sprite_offset[1][0];
+ motion_y = s->sprite_offset[1][1];
+ src_x = s->mb_x * 8 + (motion_x >> (s->sprite_warping_accuracy + 1));
+ src_y = s->mb_y * 8 + (motion_y >> (s->sprite_warping_accuracy + 1));
+ motion_x <<= (3 - s->sprite_warping_accuracy);
+ motion_y <<= (3 - s->sprite_warping_accuracy);
+ src_x = av_clip(src_x, -8, s->width >> 1);
+ if (src_x == s->width >> 1)
+ motion_x = 0;
+ src_y = av_clip(src_y, -8, s->height >> 1);
+ if (src_y == s->height >> 1)
+ motion_y = 0;
offset = (src_y * uvlinesize) + src_x;
- ptr = ref_picture[1] + offset;
- if( (unsigned)src_x >= FFMAX((s->h_edge_pos>>1) - 9, 0)
- || (unsigned)src_y >= FFMAX((s->v_edge_pos>>1) - 9, 0)){
- s->vdsp.emulated_edge_mc(s->edge_emu_buffer, uvlinesize,
- ptr, uvlinesize, 9, 9, src_x, src_y,
- s->h_edge_pos>>1, s->v_edge_pos>>1);
- ptr= s->edge_emu_buffer;
- emu=1;
+ ptr = ref_picture[1] + offset;
+ if ((unsigned)src_x >= FFMAX((s->h_edge_pos >> 1) - 9, 0) ||
+ (unsigned)src_y >= FFMAX((s->v_edge_pos >> 1) - 9, 0)) {
+ s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr,
+ uvlinesize, uvlinesize,
+ 9, 9,
+ src_x, src_y,
+ s->h_edge_pos >> 1, s->v_edge_pos >> 1);
+ ptr = s->edge_emu_buffer;
+ emu = 1;
}
- s->dsp.gmc1(dest_cb, ptr, uvlinesize, 8, motion_x&15, motion_y&15, 128 - s->no_rounding);
+ s->dsp.gmc1(dest_cb, ptr, uvlinesize, 8,
+ motion_x & 15, motion_y & 15, 128 - s->no_rounding);
ptr = ref_picture[2] + offset;
- if(emu){
- s->vdsp.emulated_edge_mc(s->edge_emu_buffer, uvlinesize,
- ptr, uvlinesize, 9, 9, src_x, src_y,
- s->h_edge_pos>>1, s->v_edge_pos>>1);
- ptr= s->edge_emu_buffer;
+ if (emu) {
+ s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr,
+ uvlinesize, uvlinesize,
+ 9, 9,
+ src_x, src_y,
+ s->h_edge_pos >> 1, s->v_edge_pos >> 1);
+ ptr = s->edge_emu_buffer;
}
- s->dsp.gmc1(dest_cr, ptr, uvlinesize, 8, motion_x&15, motion_y&15, 128 - s->no_rounding);
-
- return;
+ s->dsp.gmc1(dest_cr, ptr, uvlinesize, 8,
+ motion_x & 15, motion_y & 15, 128 - s->no_rounding);
}
static void gmc_motion(MpegEncContext *s,
@@ -128,70 +136,72 @@
{
uint8_t *ptr;
int linesize, uvlinesize;
- const int a= s->sprite_warping_accuracy;
+ const int a = s->sprite_warping_accuracy;
int ox, oy;
- linesize = s->linesize;
+ linesize = s->linesize;
uvlinesize = s->uvlinesize;
ptr = ref_picture[0];
- ox= s->sprite_offset[0][0] + s->sprite_delta[0][0]*s->mb_x*16 + s->sprite_delta[0][1]*s->mb_y*16;
- oy= s->sprite_offset[0][1] + s->sprite_delta[1][0]*s->mb_x*16 + s->sprite_delta[1][1]*s->mb_y*16;
+ ox = s->sprite_offset[0][0] + s->sprite_delta[0][0] * s->mb_x * 16 +
+ s->sprite_delta[0][1] * s->mb_y * 16;
+ oy = s->sprite_offset[0][1] + s->sprite_delta[1][0] * s->mb_x * 16 +
+ s->sprite_delta[1][1] * s->mb_y * 16;
s->dsp.gmc(dest_y, ptr, linesize, 16,
- ox,
- oy,
- s->sprite_delta[0][0], s->sprite_delta[0][1],
- s->sprite_delta[1][0], s->sprite_delta[1][1],
- a+1, (1<<(2*a+1)) - s->no_rounding,
- s->h_edge_pos, s->v_edge_pos);
- s->dsp.gmc(dest_y+8, ptr, linesize, 16,
- ox + s->sprite_delta[0][0]*8,
- oy + s->sprite_delta[1][0]*8,
- s->sprite_delta[0][0], s->sprite_delta[0][1],
- s->sprite_delta[1][0], s->sprite_delta[1][1],
- a+1, (1<<(2*a+1)) - s->no_rounding,
- s->h_edge_pos, s->v_edge_pos);
+ ox, oy,
+ s->sprite_delta[0][0], s->sprite_delta[0][1],
+ s->sprite_delta[1][0], s->sprite_delta[1][1],
+ a + 1, (1 << (2 * a + 1)) - s->no_rounding,
+ s->h_edge_pos, s->v_edge_pos);
+ s->dsp.gmc(dest_y + 8, ptr, linesize, 16,
+ ox + s->sprite_delta[0][0] * 8,
+ oy + s->sprite_delta[1][0] * 8,
+ s->sprite_delta[0][0], s->sprite_delta[0][1],
+ s->sprite_delta[1][0], s->sprite_delta[1][1],
+ a + 1, (1 << (2 * a + 1)) - s->no_rounding,
+ s->h_edge_pos, s->v_edge_pos);
- if(CONFIG_GRAY && s->flags&CODEC_FLAG_GRAY) return;
+ if (CONFIG_GRAY && s->flags & CODEC_FLAG_GRAY)
+ return;
- ox= s->sprite_offset[1][0] + s->sprite_delta[0][0]*s->mb_x*8 + s->sprite_delta[0][1]*s->mb_y*8;
- oy= s->sprite_offset[1][1] + s->sprite_delta[1][0]*s->mb_x*8 + s->sprite_delta[1][1]*s->mb_y*8;
+ ox = s->sprite_offset[1][0] + s->sprite_delta[0][0] * s->mb_x * 8 +
+ s->sprite_delta[0][1] * s->mb_y * 8;
+ oy = s->sprite_offset[1][1] + s->sprite_delta[1][0] * s->mb_x * 8 +
+ s->sprite_delta[1][1] * s->mb_y * 8;
ptr = ref_picture[1];
s->dsp.gmc(dest_cb, ptr, uvlinesize, 8,
- ox,
- oy,
- s->sprite_delta[0][0], s->sprite_delta[0][1],
- s->sprite_delta[1][0], s->sprite_delta[1][1],
- a+1, (1<<(2*a+1)) - s->no_rounding,
- s->h_edge_pos>>1, s->v_edge_pos>>1);
+ ox, oy,
+ s->sprite_delta[0][0], s->sprite_delta[0][1],
+ s->sprite_delta[1][0], s->sprite_delta[1][1],
+ a + 1, (1 << (2 * a + 1)) - s->no_rounding,
+ s->h_edge_pos >> 1, s->v_edge_pos >> 1);
ptr = ref_picture[2];
s->dsp.gmc(dest_cr, ptr, uvlinesize, 8,
- ox,
- oy,
- s->sprite_delta[0][0], s->sprite_delta[0][1],
- s->sprite_delta[1][0], s->sprite_delta[1][1],
- a+1, (1<<(2*a+1)) - s->no_rounding,
- s->h_edge_pos>>1, s->v_edge_pos>>1);
+ ox, oy,
+ s->sprite_delta[0][0], s->sprite_delta[0][1],
+ s->sprite_delta[1][0], s->sprite_delta[1][1],
+ a + 1, (1 << (2 * a + 1)) - s->no_rounding,
+ s->h_edge_pos >> 1, s->v_edge_pos >> 1);
}
static inline int hpel_motion(MpegEncContext *s,
- uint8_t *dest, uint8_t *src,
- int src_x, int src_y,
- op_pixels_func *pix_op,
- int motion_x, int motion_y)
+ uint8_t *dest, uint8_t *src,
+ int src_x, int src_y,
+ op_pixels_func *pix_op,
+ int motion_x, int motion_y)
{
int dxy = 0;
- int emu=0;
+ int emu = 0;
src_x += motion_x >> 1;
src_y += motion_y >> 1;
/* WARNING: do no forget half pels */
- src_x = av_clip(src_x, -16, s->width); //FIXME unneeded for emu?
+ src_x = av_clip(src_x, -16, s->width); // FIXME unneeded for emu?
if (src_x != s->width)
dxy |= motion_x & 1;
src_y = av_clip(src_y, -16, s->height);
@@ -199,14 +209,16 @@
dxy |= (motion_y & 1) << 1;
src += src_y * s->linesize + src_x;
- if(s->unrestricted_mv && (s->flags&CODEC_FLAG_EMU_EDGE)){
- if( (unsigned)src_x > FFMAX(s->h_edge_pos - (motion_x&1) - 8, 0)
- || (unsigned)src_y > FFMAX(s->v_edge_pos - (motion_y&1) - 8, 0)){
- s->vdsp.emulated_edge_mc(s->edge_emu_buffer, s->linesize,
- src, s->linesize, 9, 9,
- src_x, src_y, s->h_edge_pos, s->v_edge_pos);
- src= s->edge_emu_buffer;
- emu=1;
+ if (s->flags & CODEC_FLAG_EMU_EDGE) {
+ if ((unsigned)src_x > FFMAX(s->h_edge_pos - (motion_x & 1) - 8, 0) ||
+ (unsigned)src_y > FFMAX(s->v_edge_pos - (motion_y & 1) - 8, 0)) {
+ s->vdsp.emulated_edge_mc(s->edge_emu_buffer, src,
+ s->linesize, s->linesize,
+ 9, 9,
+ src_x, src_y,
+ s->h_edge_pos, s->v_edge_pos);
+ src = s->edge_emu_buffer;
+ emu = 1;
}
}
pix_op[dxy](dest, src, s->linesize, 8);
@@ -215,10 +227,19 @@
static av_always_inline
void mpeg_motion_internal(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, op_pixels_func (*pix_op)[4],
- int motion_x, int motion_y, int h, int is_mpeg12, 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,
+ op_pixels_func (*pix_op)[4],
+ int motion_x,
+ int motion_y,
+ int h,
+ int is_mpeg12,
+ int mb_y)
{
uint8_t *ptr_y, *ptr_cb, *ptr_cr;
int dxy, uvdxy, mx, my, src_x, src_y,
@@ -226,56 +247,56 @@
ptrdiff_t uvlinesize, linesize;
#if 0
-if(s->quarter_sample)
-{
- motion_x>>=1;
- motion_y>>=1;
-}
+ if (s->quarter_sample) {
+ motion_x >>= 1;
+ motion_y >>= 1;
+ }
#endif
v_edge_pos = s->v_edge_pos >> 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);
- src_y =( mb_y<<(4-field_based)) + (motion_y >> 1);
+ dxy = ((motion_y & 1) << 1) | (motion_x & 1);
+ src_x = s->mb_x * 16 + (motion_x >> 1);
+ src_y = (mb_y << (4 - field_based)) + (motion_y >> 1);
if (!is_mpeg12 && s->out_format == FMT_H263) {
- if((s->workaround_bugs & FF_BUG_HPEL_CHROMA) && field_based){
- mx = (motion_x>>1)|(motion_x&1);
- my = motion_y >>1;
- uvdxy = ((my & 1) << 1) | (mx & 1);
- uvsrc_x = s->mb_x* 8 + (mx >> 1);
- uvsrc_y =( mb_y<<(3-field_based))+ (my >> 1);
- }else{
- uvdxy = dxy | (motion_y & 2) | ((motion_x & 2) >> 1);
- uvsrc_x = src_x>>1;
- uvsrc_y = src_y>>1;
- }
- }else if(!is_mpeg12 && s->out_format == FMT_H261){//even chroma mv's are full pel in H261
- mx = motion_x / 4;
- my = motion_y / 4;
- uvdxy = 0;
- uvsrc_x = s->mb_x*8 + mx;
- uvsrc_y = mb_y*8 + my;
- } else {
- if(s->chroma_y_shift){
- mx = motion_x / 2;
- my = motion_y / 2;
- uvdxy = ((my & 1) << 1) | (mx & 1);
- uvsrc_x = s->mb_x* 8 + (mx >> 1);
- uvsrc_y =( mb_y<<(3-field_based))+ (my >> 1);
+ if ((s->workaround_bugs & FF_BUG_HPEL_CHROMA) && field_based) {
+ mx = (motion_x >> 1) | (motion_x & 1);
+ my = motion_y >> 1;
+ uvdxy = ((my & 1) << 1) | (mx & 1);
+ uvsrc_x = s->mb_x * 8 + (mx >> 1);
+ uvsrc_y = (mb_y << (3 - field_based)) + (my >> 1);
} else {
- if(s->chroma_x_shift){
- //Chroma422
- mx = motion_x / 2;
- uvdxy = ((motion_y & 1) << 1) | (mx & 1);
- uvsrc_x = s->mb_x* 8 + (mx >> 1);
+ uvdxy = dxy | (motion_y & 2) | ((motion_x & 2) >> 1);
+ uvsrc_x = src_x >> 1;
+ uvsrc_y = src_y >> 1;
+ }
+ // Even chroma mv's are full pel in H261
+ } else if (!is_mpeg12 && s->out_format == FMT_H261) {
+ mx = motion_x / 4;
+ my = motion_y / 4;
+ uvdxy = 0;
+ uvsrc_x = s->mb_x * 8 + mx;
+ uvsrc_y = mb_y * 8 + my;
+ } else {
+ if (s->chroma_y_shift) {
+ mx = motion_x / 2;
+ my = motion_y / 2;
+ uvdxy = ((my & 1) << 1) | (mx & 1);
+ uvsrc_x = s->mb_x * 8 + (mx >> 1);
+ uvsrc_y = (mb_y << (3 - field_based)) + (my >> 1);
+ } else {
+ if (s->chroma_x_shift) {
+ // Chroma422
+ mx = motion_x / 2;
+ uvdxy = ((motion_y & 1) << 1) | (mx & 1);
+ uvsrc_x = s->mb_x * 8 + (mx >> 1);
uvsrc_y = src_y;
} else {
- //Chroma444
- uvdxy = dxy;
+ // Chroma444
+ uvdxy = dxy;
uvsrc_x = src_x;
uvsrc_y = src_y;
}
@@ -286,58 +307,63 @@
ptr_cb = ref_picture[1] + uvsrc_y * uvlinesize + uvsrc_x;
ptr_cr = ref_picture[2] + uvsrc_y * uvlinesize + uvsrc_x;
- if( (unsigned)src_x > FFMAX(s->h_edge_pos - (motion_x&1) - 16, 0)
- || (unsigned)src_y > FFMAX( v_edge_pos - (motion_y&1) - h , 0)){
- if(is_mpeg12 || s->codec_id == AV_CODEC_ID_MPEG2VIDEO ||
- s->codec_id == AV_CODEC_ID_MPEG1VIDEO){
- av_log(s->avctx,AV_LOG_DEBUG,
- "MPEG motion vector out of boundary (%d %d)\n", src_x, src_y);
- return;
- }
- s->vdsp.emulated_edge_mc(s->edge_emu_buffer, s->linesize,
- ptr_y, s->linesize, 17, 17+field_based,
- src_x, src_y<<field_based,
- s->h_edge_pos, s->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->vdsp.emulated_edge_mc(uvbuf, s->uvlinesize,
- ptr_cb, s->uvlinesize,
- 9, 9+field_based,
- uvsrc_x, uvsrc_y<<field_based,
- s->h_edge_pos>>1, s->v_edge_pos>>1);
- s->vdsp.emulated_edge_mc(uvbuf+16, s->uvlinesize,
- ptr_cr, s->uvlinesize,
- 9, 9+field_based,
- uvsrc_x, uvsrc_y<<field_based,
- s->h_edge_pos>>1, s->v_edge_pos>>1);
- ptr_cb= uvbuf;
- ptr_cr= uvbuf+16;
- }
+ if ((unsigned)src_x > FFMAX(s->h_edge_pos - (motion_x & 1) - 16, 0) ||
+ (unsigned)src_y > FFMAX( v_edge_pos - (motion_y & 1) - h , 0)) {
+ if (is_mpeg12 ||
+ s->codec_id == AV_CODEC_ID_MPEG2VIDEO ||
+ s->codec_id == AV_CODEC_ID_MPEG1VIDEO) {
+ av_log(s->avctx, AV_LOG_DEBUG,
+ "MPEG motion vector out of boundary (%d %d)\n", src_x,
+ src_y);
+ return;
+ }
+ s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr_y,
+ s->linesize, s->linesize,
+ 17, 17 + field_based,
+ src_x, src_y << field_based,
+ s->h_edge_pos, s->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->vdsp.emulated_edge_mc(uvbuf, ptr_cb,
+ s->uvlinesize, s->uvlinesize,
+ 9, 9 + field_based,
+ uvsrc_x, uvsrc_y << field_based,
+ s->h_edge_pos >> 1, s->v_edge_pos >> 1);
+ s->vdsp.emulated_edge_mc(uvbuf + 16, ptr_cr,
+ s->uvlinesize, s->uvlinesize,
+ 9, 9 + field_based,
+ uvsrc_x, uvsrc_y << field_based,
+ s->h_edge_pos >> 1, s->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;
+ /* FIXME use this for field pix too instead of the obnoxious hack which
+ * changes picture.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;
+ if (field_select) {
+ ptr_y += s->linesize;
+ ptr_cb += s->uvlinesize;
+ ptr_cr += s->uvlinesize;
}
pix_op[0][dxy](dest_y, ptr_y, linesize, h);
- if(!CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY)){
+ if (!CONFIG_GRAY || !(s->flags & CODEC_FLAG_GRAY)) {
pix_op[s->chroma_x_shift][uvdxy]
- (dest_cb, ptr_cb, uvlinesize, h >> s->chroma_y_shift);
+ (dest_cb, ptr_cb, uvlinesize, h >> s->chroma_y_shift);
pix_op[s->chroma_x_shift][uvdxy]
- (dest_cr, ptr_cr, uvlinesize, h >> s->chroma_y_shift);
+ (dest_cr, ptr_cr, uvlinesize, h >> s->chroma_y_shift);
}
- if(!is_mpeg12 && (CONFIG_H261_ENCODER || CONFIG_H261_DECODER) &&
- s->out_format == FMT_H261){
+ if (!is_mpeg12 && (CONFIG_H261_ENCODER || CONFIG_H261_DECODER) &&
+ s->out_format == FMT_H261) {
ff_h261_loop_filter(s);
}
}
@@ -349,15 +375,15 @@
int motion_x, int motion_y, int h, int mb_y)
{
#if !CONFIG_SMALL
- if(s->out_format == FMT_MPEG1)
+ if (s->out_format == FMT_MPEG1)
mpeg_motion_internal(s, dest_y, dest_cb, dest_cr, 0, 0,
- field_select, ref_picture, pix_op,
- motion_x, motion_y, h, 1, mb_y);
+ field_select, ref_picture, pix_op,
+ motion_x, motion_y, h, 1, mb_y);
else
#endif
mpeg_motion_internal(s, dest_y, dest_cb, dest_cr, 0, 0,
- field_select, ref_picture, pix_op,
- motion_x, motion_y, h, 0, mb_y);
+ field_select, ref_picture, pix_op,
+ motion_x, motion_y, h, 0, mb_y);
}
static void mpeg_motion_field(MpegEncContext *s, uint8_t *dest_y,
@@ -368,25 +394,26 @@
int motion_x, int motion_y, int h, int mb_y)
{
#if !CONFIG_SMALL
- if(s->out_format == FMT_MPEG1)
+ if (s->out_format == FMT_MPEG1)
mpeg_motion_internal(s, dest_y, dest_cb, dest_cr, 1,
- bottom_field, field_select, ref_picture, pix_op,
- motion_x, motion_y, h, 1, mb_y);
+ bottom_field, field_select, ref_picture, pix_op,
+ motion_x, motion_y, h, 1, mb_y);
else
#endif
mpeg_motion_internal(s, dest_y, dest_cb, dest_cr, 1,
- bottom_field, field_select, ref_picture, pix_op,
- motion_x, motion_y, h, 0, mb_y);
+ bottom_field, field_select, ref_picture, pix_op,
+ motion_x, motion_y, h, 0, mb_y);
}
-//FIXME move to dsputil, avg variant, 16x16 version
-static inline void put_obmc(uint8_t *dst, uint8_t *src[5], int stride){
+// FIXME move to dsputil, avg variant, 16x16 version
+static inline void put_obmc(uint8_t *dst, uint8_t *src[5], int stride)
+{
int x;
- uint8_t * const top = src[1];
- uint8_t * const left = src[2];
- uint8_t * const mid = src[0];
- uint8_t * const right = src[3];
- uint8_t * const bottom= src[4];
+ uint8_t *const top = src[1];
+ uint8_t *const left = src[2];
+ uint8_t *const mid = src[0];
+ uint8_t *const right = src[3];
+ uint8_t *const bottom = src[4];
#define OBMC_FILTER(x, t, l, m, r, b)\
dst[x]= (t*top[x] + l*left[x] + m*mid[x] + r*right[x] + b*bottom[x] + 4)>>3
#define OBMC_FILTER4(x, t, l, m, r, b)\
@@ -395,40 +422,40 @@
OBMC_FILTER(x +stride, t, l, m, r, b);\
OBMC_FILTER(x+1+stride, t, l, m, r, b);
- x=0;
- OBMC_FILTER (x , 2, 2, 4, 0, 0);
- OBMC_FILTER (x+1, 2, 1, 5, 0, 0);
- OBMC_FILTER4(x+2, 2, 1, 5, 0, 0);
- OBMC_FILTER4(x+4, 2, 0, 5, 1, 0);
- OBMC_FILTER (x+6, 2, 0, 5, 1, 0);
- OBMC_FILTER (x+7, 2, 0, 4, 2, 0);
- x+= stride;
- OBMC_FILTER (x , 1, 2, 5, 0, 0);
- OBMC_FILTER (x+1, 1, 2, 5, 0, 0);
- OBMC_FILTER (x+6, 1, 0, 5, 2, 0);
- OBMC_FILTER (x+7, 1, 0, 5, 2, 0);
- x+= stride;
- OBMC_FILTER4(x , 1, 2, 5, 0, 0);
- OBMC_FILTER4(x+2, 1, 1, 6, 0, 0);
- OBMC_FILTER4(x+4, 1, 0, 6, 1, 0);
- OBMC_FILTER4(x+6, 1, 0, 5, 2, 0);
- x+= 2*stride;
- OBMC_FILTER4(x , 0, 2, 5, 0, 1);
- OBMC_FILTER4(x+2, 0, 1, 6, 0, 1);
- OBMC_FILTER4(x+4, 0, 0, 6, 1, 1);
- OBMC_FILTER4(x+6, 0, 0, 5, 2, 1);
- x+= 2*stride;
- OBMC_FILTER (x , 0, 2, 5, 0, 1);
- OBMC_FILTER (x+1, 0, 2, 5, 0, 1);
- OBMC_FILTER4(x+2, 0, 1, 5, 0, 2);
- OBMC_FILTER4(x+4, 0, 0, 5, 1, 2);
- OBMC_FILTER (x+6, 0, 0, 5, 2, 1);
- OBMC_FILTER (x+7, 0, 0, 5, 2, 1);
- x+= stride;
- OBMC_FILTER (x , 0, 2, 4, 0, 2);
- OBMC_FILTER (x+1, 0, 1, 5, 0, 2);
- OBMC_FILTER (x+6, 0, 0, 5, 1, 2);
- OBMC_FILTER (x+7, 0, 0, 4, 2, 2);
+ x = 0;
+ OBMC_FILTER (x , 2, 2, 4, 0, 0);
+ OBMC_FILTER (x + 1, 2, 1, 5, 0, 0);
+ OBMC_FILTER4(x + 2, 2, 1, 5, 0, 0);
+ OBMC_FILTER4(x + 4, 2, 0, 5, 1, 0);
+ OBMC_FILTER (x + 6, 2, 0, 5, 1, 0);
+ OBMC_FILTER (x + 7, 2, 0, 4, 2, 0);
+ x += stride;
+ OBMC_FILTER (x , 1, 2, 5, 0, 0);
+ OBMC_FILTER (x + 1, 1, 2, 5, 0, 0);
+ OBMC_FILTER (x + 6, 1, 0, 5, 2, 0);
+ OBMC_FILTER (x + 7, 1, 0, 5, 2, 0);
+ x += stride;
+ OBMC_FILTER4(x , 1, 2, 5, 0, 0);
+ OBMC_FILTER4(x + 2, 1, 1, 6, 0, 0);
+ OBMC_FILTER4(x + 4, 1, 0, 6, 1, 0);
+ OBMC_FILTER4(x + 6, 1, 0, 5, 2, 0);
+ x += 2 * stride;
+ OBMC_FILTER4(x , 0, 2, 5, 0, 1);
+ OBMC_FILTER4(x + 2, 0, 1, 6, 0, 1);
+ OBMC_FILTER4(x + 4, 0, 0, 6, 1, 1);
+ OBMC_FILTER4(x + 6, 0, 0, 5, 2, 1);
+ x += 2*stride;
+ OBMC_FILTER (x , 0, 2, 5, 0, 1);
+ OBMC_FILTER (x + 1, 0, 2, 5, 0, 1);
+ OBMC_FILTER4(x + 2, 0, 1, 5, 0, 2);
+ OBMC_FILTER4(x + 4, 0, 0, 5, 1, 2);
+ OBMC_FILTER (x + 6, 0, 0, 5, 2, 1);
+ OBMC_FILTER (x + 7, 0, 0, 5, 2, 1);
+ x += stride;
+ OBMC_FILTER (x , 0, 2, 4, 0, 2);
+ OBMC_FILTER (x + 1, 0, 1, 5, 0, 2);
+ OBMC_FILTER (x + 6, 0, 0, 5, 1, 2);
+ OBMC_FILTER (x + 7, 0, 0, 4, 2, 2);
}
/* obmc for 1 8x8 luma block */
@@ -436,22 +463,21 @@
uint8_t *dest, uint8_t *src,
int src_x, int src_y,
op_pixels_func *pix_op,
- int16_t mv[5][2]/* mid top left right bottom*/)
+ int16_t mv[5][2] /* mid top left right bottom */)
#define MID 0
{
int i;
uint8_t *ptr[5];
- av_assert2(s->quarter_sample==0);
+ av_assert2(s->quarter_sample == 0);
- for(i=0; i<5; i++){
- if(i && mv[i][0]==mv[MID][0] && mv[i][1]==mv[MID][1]){
- ptr[i]= ptr[MID];
- }else{
- ptr[i]= s->obmc_scratchpad + 8*(i&1) + s->linesize*8*(i>>1);
- hpel_motion(s, ptr[i], src,
- src_x, src_y,
- pix_op,
+ for (i = 0; i < 5; i++) {
+ if (i && mv[i][0] == mv[MID][0] && mv[i][1] == mv[MID][1]) {
+ ptr[i] = ptr[MID];
+ } else {
+ ptr[i] = s->obmc_scratchpad + 8 * (i & 1) +
+ s->linesize * 8 * (i >> 1);
+ hpel_motion(s, ptr[i], src, src_x, src_y, pix_op,
mv[i][0], mv[i][1]);
}
}
@@ -460,9 +486,12 @@
}
static inline void qpel_motion(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, op_pixels_func (*pix_op)[4],
+ 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,
+ op_pixels_func (*pix_op)[4],
qpel_mc_func (*qpix_op)[16],
int motion_x, int motion_y, int h)
{
@@ -470,86 +499,88 @@
int dxy, uvdxy, mx, my, src_x, src_y, uvsrc_x, uvsrc_y, v_edge_pos;
ptrdiff_t linesize, uvlinesize;
- dxy = ((motion_y & 3) << 2) | (motion_x & 3);
+ dxy = ((motion_y & 3) << 2) | (motion_x & 3);
+
src_x = s->mb_x * 16 + (motion_x >> 2);
src_y = s->mb_y * (16 >> field_based) + (motion_y >> 2);
v_edge_pos = s->v_edge_pos >> field_based;
- linesize = s->linesize << field_based;
+ linesize = s->linesize << field_based;
uvlinesize = s->uvlinesize << field_based;
- if(field_based){
- mx= motion_x/2;
- my= motion_y>>1;
- }else if(s->workaround_bugs&FF_BUG_QPEL_CHROMA2){
- static const int rtab[8]= {0,0,1,1,0,0,0,1};
- mx= (motion_x>>1) + rtab[motion_x&7];
- my= (motion_y>>1) + rtab[motion_y&7];
- }else if(s->workaround_bugs&FF_BUG_QPEL_CHROMA){
- mx= (motion_x>>1)|(motion_x&1);
- my= (motion_y>>1)|(motion_y&1);
- }else{
- mx= motion_x/2;
- my= motion_y/2;
+ if (field_based) {
+ mx = motion_x / 2;
+ my = motion_y >> 1;
+ } else if (s->workaround_bugs & FF_BUG_QPEL_CHROMA2) {
+ static const int rtab[8] = { 0, 0, 1, 1, 0, 0, 0, 1 };
+ mx = (motion_x >> 1) + rtab[motion_x & 7];
+ my = (motion_y >> 1) + rtab[motion_y & 7];
+ } else if (s->workaround_bugs & FF_BUG_QPEL_CHROMA) {
+ mx = (motion_x >> 1) | (motion_x & 1);
+ my = (motion_y >> 1) | (motion_y & 1);
+ } else {
+ mx = motion_x / 2;
+ my = motion_y / 2;
}
- mx= (mx>>1)|(mx&1);
- my= (my>>1)|(my&1);
+ mx = (mx >> 1) | (mx & 1);
+ my = (my >> 1) | (my & 1);
- uvdxy= (mx&1) | ((my&1)<<1);
- mx>>=1;
- my>>=1;
+ uvdxy = (mx & 1) | ((my & 1) << 1);
+ mx >>= 1;
+ my >>= 1;
uvsrc_x = s->mb_x * 8 + mx;
uvsrc_y = s->mb_y * (8 >> field_based) + my;
- 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 > FFMAX(s->h_edge_pos - (motion_x&3) - 16, 0)
- || (unsigned)src_y > FFMAX( v_edge_pos - (motion_y&3) - h , 0)){
- s->vdsp.emulated_edge_mc(s->edge_emu_buffer, s->linesize,
- ptr_y, s->linesize,
- 17, 17+field_based, src_x, src_y<<field_based,
+ if ((unsigned)src_x > FFMAX(s->h_edge_pos - (motion_x & 3) - 16, 0) ||
+ (unsigned)src_y > FFMAX( v_edge_pos - (motion_y & 3) - h, 0)) {
+ s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr_y,
+ s->linesize, s->linesize,
+ 17, 17 + field_based,
+ src_x, src_y << field_based,
s->h_edge_pos, s->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->vdsp.emulated_edge_mc(uvbuf, s->uvlinesize,
- ptr_cb, s->uvlinesize,
+ 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->vdsp.emulated_edge_mc(uvbuf, ptr_cb,
+ s->uvlinesize, s->uvlinesize,
9, 9 + field_based,
- uvsrc_x, uvsrc_y<<field_based,
- s->h_edge_pos>>1, s->v_edge_pos>>1);
- s->vdsp.emulated_edge_mc(uvbuf + 16, s->uvlinesize,
- ptr_cr, s->uvlinesize,
+ uvsrc_x, uvsrc_y << field_based,
+ s->h_edge_pos >> 1, s->v_edge_pos >> 1);
+ s->vdsp.emulated_edge_mc(uvbuf + 16, ptr_cr,
+ s->uvlinesize, s->uvlinesize,
9, 9 + field_based,
- uvsrc_x, uvsrc_y<<field_based,
- s->h_edge_pos>>1, s->v_edge_pos>>1);
- ptr_cb= uvbuf;
- ptr_cr= uvbuf + 16;
+ uvsrc_x, uvsrc_y << field_based,
+ s->h_edge_pos >> 1, s->v_edge_pos >> 1);
+ ptr_cb = uvbuf;
+ ptr_cr = uvbuf + 16;
}
}
- if(!field_based)
+ if (!field_based)
qpix_op[0][dxy](dest_y, ptr_y, linesize);
- else{
- if(bottom_field){
- dest_y += s->linesize;
- dest_cb+= s->uvlinesize;
- dest_cr+= s->uvlinesize;
+ else {
+ if (bottom_field) {
+ dest_y += s->linesize;
+ dest_cb += s->uvlinesize;
+ dest_cr += s->uvlinesize;
}
- if(field_select){
+ if (field_select) {
ptr_y += s->linesize;
ptr_cb += s->uvlinesize;
ptr_cr += s->uvlinesize;
}
- //damn interlaced mode
- //FIXME boundary mirroring is not exactly correct here
- qpix_op[1][dxy](dest_y , ptr_y , linesize);
- qpix_op[1][dxy](dest_y+8, ptr_y+8, linesize);
+ // damn interlaced mode
+ // FIXME boundary mirroring is not exactly correct here
+ qpix_op[1][dxy](dest_y, ptr_y, linesize);
+ qpix_op[1][dxy](dest_y + 8, ptr_y + 8, linesize);
}
- if(!CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY)){
+ if (!CONFIG_GRAY || !(s->flags & CODEC_FLAG_GRAY)) {
pix_op[1][uvdxy](dest_cr, ptr_cr, uvlinesize, h >> 1);
pix_op[1][uvdxy](dest_cb, ptr_cb, uvlinesize, h >> 1);
}
@@ -564,16 +595,16 @@
op_pixels_func *pix_op,
int mx, int my)
{
- int dxy, emu=0, src_x, src_y;
- ptrdiff_t offset;
uint8_t *ptr;
+ int src_x, src_y, dxy, emu = 0;
+ ptrdiff_t offset;
/* 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);
+ * with a special rounding */
+ mx = ff_h263_round_chroma(mx);
+ my = ff_h263_round_chroma(my);
- dxy = ((my & 1) << 1) | (mx & 1);
+ dxy = ((my & 1) << 1) | (mx & 1);
mx >>= 1;
my >>= 1;
@@ -587,39 +618,204 @@
dxy &= ~2;
offset = src_y * s->uvlinesize + src_x;
- ptr = ref_picture[1] + offset;
- if(s->flags&CODEC_FLAG_EMU_EDGE){
- if( (unsigned)src_x > FFMAX((s->h_edge_pos>>1) - (dxy &1) - 8, 0)
- || (unsigned)src_y > FFMAX((s->v_edge_pos>>1) - (dxy>>1) - 8, 0)){
- s->vdsp.emulated_edge_mc(s->edge_emu_buffer, s->uvlinesize,
- ptr, s->uvlinesize, 9, 9, src_x, src_y,
- s->h_edge_pos>>1, s->v_edge_pos>>1);
- ptr= s->edge_emu_buffer;
- emu=1;
+ ptr = ref_picture[1] + offset;
+ if (s->flags & CODEC_FLAG_EMU_EDGE) {
+ if ((unsigned)src_x > FFMAX((s->h_edge_pos >> 1) - (dxy & 1) - 8, 0) ||
+ (unsigned)src_y > FFMAX((s->v_edge_pos >> 1) - (dxy >> 1) - 8, 0)) {
+ s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr,
+ s->uvlinesize, s->uvlinesize,
+ 9, 9, src_x, src_y,
+ s->h_edge_pos >> 1, s->v_edge_pos >> 1);
+ ptr = s->edge_emu_buffer;
+ emu = 1;
}
}
pix_op[dxy](dest_cb, ptr, s->uvlinesize, 8);
ptr = ref_picture[2] + offset;
- if(emu){
- s->vdsp.emulated_edge_mc(s->edge_emu_buffer, s->uvlinesize,
- ptr, s->uvlinesize, 9, 9, src_x, src_y,
- s->h_edge_pos>>1, s->v_edge_pos>>1);
- ptr= s->edge_emu_buffer;
+ if (emu) {
+ s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr,
+ s->uvlinesize, s->uvlinesize,
+ 9, 9, src_x, src_y,
+ s->h_edge_pos >> 1, s->v_edge_pos >> 1);
+ ptr = s->edge_emu_buffer;
}
pix_op[dxy](dest_cr, ptr, s->uvlinesize, 8);
}
-static inline void prefetch_motion(MpegEncContext *s, uint8_t **pix, int dir){
+static inline void prefetch_motion(MpegEncContext *s, uint8_t **pix, int dir)
+{
/* fetch pixels for estimated mv 4 macroblocks ahead
* optimized for 64byte cache lines */
const int shift = s->quarter_sample ? 2 : 1;
- const int mx= (s->mv[dir][0][0]>>shift) + 16*s->mb_x + 8;
- const int my= (s->mv[dir][0][1]>>shift) + 16*s->mb_y;
- int off= mx + (my + (s->mb_x&3)*4)*s->linesize + 64;
- s->vdsp.prefetch(pix[0]+off, s->linesize, 4);
- off= (mx>>1) + ((my>>1) + (s->mb_x&7))*s->uvlinesize + 64;
- s->vdsp.prefetch(pix[1]+off, pix[2]-pix[1], 2);
+ const int mx = (s->mv[dir][0][0] >> shift) + 16 * s->mb_x + 8;
+ const int my = (s->mv[dir][0][1] >> shift) + 16 * s->mb_y;
+ int off = mx + (my + (s->mb_x & 3) * 4) * s->linesize + 64;
+
+ s->vdsp.prefetch(pix[0] + off, s->linesize, 4);
+ off = (mx >> 1) + ((my >> 1) + (s->mb_x & 7)) * s->uvlinesize + 64;
+ s->vdsp.prefetch(pix[1] + off, pix[2] - pix[1], 2);
+}
+
+static inline void apply_obmc(MpegEncContext *s,
+ uint8_t *dest_y,
+ uint8_t *dest_cb,
+ uint8_t *dest_cr,
+ uint8_t **ref_picture,
+ op_pixels_func (*pix_op)[4])
+{
+ LOCAL_ALIGNED_8(int16_t, mv_cache, [4], [4][2]);
+ Picture *cur_frame = &s->current_picture;
+ int mb_x = s->mb_x;
+ int mb_y = s->mb_y;
+ const int xy = mb_x + mb_y * s->mb_stride;
+ const int mot_stride = s->b8_stride;
+ const int mot_xy = mb_x * 2 + mb_y * 2 * mot_stride;
+ int mx, my, i;
+
+ av_assert2(!s->mb_skipped);
+
+ AV_COPY32(mv_cache[1][1], cur_frame->motion_val[0][mot_xy]);
+ AV_COPY32(mv_cache[1][2], cur_frame->motion_val[0][mot_xy + 1]);
+
+ AV_COPY32(mv_cache[2][1],
+ cur_frame->motion_val[0][mot_xy + mot_stride]);
+ AV_COPY32(mv_cache[2][2],
+ cur_frame->motion_val[0][mot_xy + mot_stride + 1]);
+
+ AV_COPY32(mv_cache[3][1],
+ cur_frame->motion_val[0][mot_xy + mot_stride]);
+ AV_COPY32(mv_cache[3][2],
+ cur_frame->motion_val[0][mot_xy + mot_stride + 1]);
+
+ if (mb_y == 0 || IS_INTRA(cur_frame->mb_type[xy - s->mb_stride])) {
+ AV_COPY32(mv_cache[0][1], mv_cache[1][1]);
+ AV_COPY32(mv_cache[0][2], mv_cache[1][2]);
+ } else {
+ AV_COPY32(mv_cache[0][1],
+ cur_frame->motion_val[0][mot_xy - mot_stride]);
+ AV_COPY32(mv_cache[0][2],
+ cur_frame->motion_val[0][mot_xy - mot_stride + 1]);
+ }
+
+ if (mb_x == 0 || IS_INTRA(cur_frame->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], cur_frame->motion_val[0][mot_xy - 1]);
+ AV_COPY32(mv_cache[2][0],
+ cur_frame->motion_val[0][mot_xy - 1 + mot_stride]);
+ }
+
+ if (mb_x + 1 >= s->mb_width || IS_INTRA(cur_frame->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], cur_frame->motion_val[0][mot_xy + 2]);
+ AV_COPY32(mv_cache[2][3],
+ cur_frame->motion_val[0][mot_xy + 2 + mot_stride]);
+ }
+
+ mx = 0;
+ my = 0;
+ for (i = 0; i < 4; i++) {
+ const int x = (i & 1) + 1;
+ const int y = (i >> 1) + 1;
+ int16_t mv[5][2] = {
+ { mv_cache[y][x][0], mv_cache[y][x][1] },
+ { mv_cache[y - 1][x][0], mv_cache[y - 1][x][1] },
+ { mv_cache[y][x - 1][0], mv_cache[y][x - 1][1] },
+ { mv_cache[y][x + 1][0], mv_cache[y][x + 1][1] },
+ { mv_cache[y + 1][x][0], mv_cache[y + 1][x][1] }
+ };
+ // FIXME cleanup
+ obmc_motion(s, dest_y + ((i & 1) * 8) + (i >> 1) * 8 * s->linesize,
+ ref_picture[0],
+ mb_x * 16 + (i & 1) * 8, mb_y * 16 + (i >> 1) * 8,
+ pix_op[1],
+ mv);
+
+ mx += mv[0][0];
+ my += mv[0][1];
+ }
+ if (!CONFIG_GRAY || !(s->flags & CODEC_FLAG_GRAY))
+ chroma_4mv_motion(s, dest_cb, dest_cr,
+ ref_picture, pix_op[1],
+ mx, my);
+}
+
+static inline void apply_8x8(MpegEncContext *s,
+ uint8_t *dest_y,
+ uint8_t *dest_cb,
+ uint8_t *dest_cr,
+ int dir,
+ uint8_t **ref_picture,
+ qpel_mc_func (*qpix_op)[16],
+ op_pixels_func (*pix_op)[4])
+{
+ int dxy, mx, my, src_x, src_y;
+ int i;
+ int mb_x = s->mb_x;
+ int mb_y = s->mb_y;
+ uint8_t *ptr, *dest;
+
+ mx = 0;
+ my = 0;
+ if (s->quarter_sample) {
+ for (i = 0; i < 4; i++) {
+ int motion_x = s->mv[dir][i][0];
+ int motion_y = s->mv[dir][i][1];
+
+ dxy = ((motion_y & 3) << 2) | (motion_x & 3);
+ src_x = mb_x * 16 + (motion_x >> 2) + (i & 1) * 8;
+ src_y = mb_y * 16 + (motion_y >> 2) + (i >> 1) * 8;
+
+ /* WARNING: do no forget half pels */
+ src_x = av_clip(src_x, -16, s->width);
+ if (src_x == s->width)
+ dxy &= ~3;
+ src_y = av_clip(src_y, -16, s->height);
+ if (src_y == s->height)
+ dxy &= ~12;
+
+ ptr = ref_picture[0] + (src_y * s->linesize) + (src_x);
+ if (s->flags & CODEC_FLAG_EMU_EDGE) {
+ if ((unsigned)src_x > FFMAX(s->h_edge_pos - (motion_x & 3) - 8, 0) ||
+ (unsigned)src_y > FFMAX(s->v_edge_pos - (motion_y & 3) - 8, 0)) {
+ s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr,
+ s->linesize, s->linesize,
+ 9, 9,
+ src_x, src_y,
+ s->h_edge_pos,
+ s->v_edge_pos);
+ ptr = s->edge_emu_buffer;
+ }
+ }
+ dest = dest_y + ((i & 1) * 8) + (i >> 1) * 8 * s->linesize;
+ qpix_op[1][dxy](dest, ptr, s->linesize);
+
+ mx += s->mv[dir][i][0] / 2;
+ my += s->mv[dir][i][1] / 2;
+ }
+ } else {
+ for (i = 0; i < 4; i++) {
+ hpel_motion(s,
+ dest_y + ((i & 1) * 8) + (i >> 1) * 8 * s->linesize,
+ ref_picture[0],
+ mb_x * 16 + (i & 1) * 8,
+ mb_y * 16 + (i >> 1) * 8,
+ pix_op[1],
+ 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(s, dest_cb, dest_cr,
+ ref_picture, pix_op[1], mx, my);
}
/**
@@ -635,101 +831,36 @@
* the motion vectors are taken from s->mv and the MV type from s->mv_type
*/
static av_always_inline void MPV_motion_internal(MpegEncContext *s,
- uint8_t *dest_y, uint8_t *dest_cb,
- uint8_t *dest_cr, int dir,
- uint8_t **ref_picture,
- op_pixels_func (*pix_op)[4],
- qpel_mc_func (*qpix_op)[16], int is_mpeg12)
+ uint8_t *dest_y,
+ uint8_t *dest_cb,
+ uint8_t *dest_cr,
+ int dir,
+ uint8_t **ref_picture,
+ op_pixels_func (*pix_op)[4],
+ qpel_mc_func (*qpix_op)[16],
+ int is_mpeg12)
{
- int dxy, mx, my, src_x, src_y, motion_x, motion_y;
- int mb_x, mb_y, i;
- uint8_t *ptr, *dest;
-
- mb_x = s->mb_x;
- mb_y = s->mb_y;
+ int i;
+ int mb_y = s->mb_y;
prefetch_motion(s, ref_picture, dir);
- if(!is_mpeg12 && s->obmc && s->pict_type != AV_PICTURE_TYPE_B){
- LOCAL_ALIGNED_8(int16_t, mv_cache, [4], [4][2]);
- Picture *cur_frame = &s->current_picture;
- const int xy= s->mb_x + s->mb_y*s->mb_stride;
- const int mot_stride= s->b8_stride;
- const int mot_xy= mb_x*2 + mb_y*2*mot_stride;
-
- av_assert2(!s->mb_skipped);
-
- AV_COPY32(mv_cache[1][1], cur_frame->motion_val[0][mot_xy ]);
- AV_COPY32(mv_cache[1][2], cur_frame->motion_val[0][mot_xy + 1]);
-
- AV_COPY32(mv_cache[2][1], cur_frame->motion_val[0][mot_xy + mot_stride ]);
- AV_COPY32(mv_cache[2][2], cur_frame->motion_val[0][mot_xy + mot_stride + 1]);
-
- AV_COPY32(mv_cache[3][1], cur_frame->motion_val[0][mot_xy + mot_stride ]);
- AV_COPY32(mv_cache[3][2], cur_frame->motion_val[0][mot_xy + mot_stride + 1]);
-
- if (mb_y == 0 || IS_INTRA(cur_frame->mb_type[xy - s->mb_stride])) {
- AV_COPY32(mv_cache[0][1], mv_cache[1][1]);
- AV_COPY32(mv_cache[0][2], mv_cache[1][2]);
- }else{
- AV_COPY32(mv_cache[0][1], cur_frame->motion_val[0][mot_xy - mot_stride ]);
- AV_COPY32(mv_cache[0][2], cur_frame->motion_val[0][mot_xy - mot_stride + 1]);
- }
-
- if (mb_x == 0 || IS_INTRA(cur_frame->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], cur_frame->motion_val[0][mot_xy - 1]);
- AV_COPY32(mv_cache[2][0], cur_frame->motion_val[0][mot_xy - 1 + mot_stride]);
- }
-
- if (mb_x + 1 >= s->mb_width || IS_INTRA(cur_frame->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], cur_frame->motion_val[0][mot_xy + 2]);
- AV_COPY32(mv_cache[2][3], cur_frame->motion_val[0][mot_xy + 2 + mot_stride]);
- }
-
- mx = 0;
- my = 0;
- for(i=0;i<4;i++) {
- const int x= (i&1)+1;
- const int y= (i>>1)+1;
- int16_t mv[5][2]= {
- {mv_cache[y][x ][0], mv_cache[y][x ][1]},
- {mv_cache[y-1][x][0], mv_cache[y-1][x][1]},
- {mv_cache[y][x-1][0], mv_cache[y][x-1][1]},
- {mv_cache[y][x+1][0], mv_cache[y][x+1][1]},
- {mv_cache[y+1][x][0], mv_cache[y+1][x][1]}};
- //FIXME cleanup
- obmc_motion(s, dest_y + ((i & 1) * 8) + (i >> 1) * 8 * s->linesize,
- ref_picture[0],
- mb_x * 16 + (i & 1) * 8, mb_y * 16 + (i >>1) * 8,
- pix_op[1],
- mv);
-
- mx += mv[0][0];
- my += mv[0][1];
- }
- if(!CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY))
- chroma_4mv_motion(s, dest_cb, dest_cr, ref_picture, pix_op[1], mx, my);
-
+ if (!is_mpeg12 && s->obmc && s->pict_type != AV_PICTURE_TYPE_B) {
+ apply_obmc(s, dest_y, dest_cb, dest_cr, ref_picture, pix_op);
return;
}
- switch(s->mv_type) {
+ switch (s->mv_type) {
case MV_TYPE_16X16:
- if(s->mcsel){
- if(s->real_sprite_warping_points==1){
+ if (s->mcsel) {
+ if (s->real_sprite_warping_points == 1) {
gmc1_motion(s, dest_y, dest_cb, dest_cr,
ref_picture);
- }else{
+ } else {
gmc_motion(s, dest_y, dest_cb, dest_cr,
- ref_picture);
+ ref_picture);
}
- }else if(!is_mpeg12 && s->quarter_sample){
+ } else if (!is_mpeg12 && s->quarter_sample) {
qpel_motion(s, dest_y, dest_cb, dest_cr,
0, 0, 0,
ref_picture, pix_op, qpix_op,
@@ -737,80 +868,28 @@
} else if (!is_mpeg12 && (CONFIG_WMV2_DECODER || CONFIG_WMV2_ENCODER) &&
s->mspel && s->codec_id == AV_CODEC_ID_WMV2) {
ff_mspel_motion(s, dest_y, dest_cb, dest_cr,
- ref_picture, pix_op,
- s->mv[dir][0][0], s->mv[dir][0][1], 16);
- }else
- {
+ ref_picture, pix_op,
+ s->mv[dir][0][0], s->mv[dir][0][1], 16);
+ } else {
mpeg_motion(s, dest_y, dest_cb, dest_cr, 0,
ref_picture, pix_op,
s->mv[dir][0][0], s->mv[dir][0][1], 16, mb_y);
}
break;
case MV_TYPE_8X8:
- if (!is_mpeg12) {
- mx = 0;
- my = 0;
- if(s->quarter_sample){
- for(i=0;i<4;i++) {
- motion_x = s->mv[dir][i][0];
- motion_y = s->mv[dir][i][1];
-
- dxy = ((motion_y & 3) << 2) | (motion_x & 3);
- src_x = mb_x * 16 + (motion_x >> 2) + (i & 1) * 8;
- src_y = mb_y * 16 + (motion_y >> 2) + (i >>1) * 8;
-
- /* WARNING: do no forget half pels */
- src_x = av_clip(src_x, -16, s->width);
- if (src_x == s->width)
- dxy &= ~3;
- src_y = av_clip(src_y, -16, s->height);
- if (src_y == s->height)
- dxy &= ~12;
-
- ptr = ref_picture[0] + (src_y * s->linesize) + (src_x);
- if(s->flags&CODEC_FLAG_EMU_EDGE){
- if( (unsigned)src_x > FFMAX(s->h_edge_pos - (motion_x&3) - 8, 0)
- || (unsigned)src_y > FFMAX(s->v_edge_pos - (motion_y&3) - 8, 0)){
- s->vdsp.emulated_edge_mc(s->edge_emu_buffer, s->linesize,
- ptr, s->linesize, 9, 9,
- src_x, src_y,
- s->h_edge_pos, s->v_edge_pos);
- ptr= s->edge_emu_buffer;
- }
- }
- dest = dest_y + ((i & 1) * 8) + (i >> 1) * 8 * s->linesize;
- qpix_op[1][dxy](dest, ptr, s->linesize);
-
- mx += s->mv[dir][i][0]/2;
- my += s->mv[dir][i][1]/2;
- }
- }else{
- for(i=0;i<4;i++) {
- hpel_motion(s, dest_y + ((i & 1) * 8) + (i >> 1) * 8 * s->linesize,
- ref_picture[0],
- mb_x * 16 + (i & 1) * 8, mb_y * 16 + (i >>1) * 8,
- pix_op[1],
- 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(s, dest_cb, dest_cr, ref_picture, pix_op[1], mx, my);
- }
+ if (!is_mpeg12)
+ apply_8x8(s, dest_y, dest_cb, dest_cr,
+ dir, ref_picture, qpix_op, pix_op);
break;
case MV_TYPE_FIELD:
if (s->picture_structure == PICT_FRAME) {
- if(!is_mpeg12 && s->quarter_sample){
- for(i=0; i<2; i++){
+ if (!is_mpeg12 && s->quarter_sample) {
+ for (i = 0; i < 2; i++)
qpel_motion(s, dest_y, dest_cb, dest_cr,
1, i, s->field_select[dir][i],
ref_picture, pix_op, qpix_op,
s->mv[dir][i][0], s->mv[dir][i][1], 8);
- }
- }else{
+ } else {
/* top field */
mpeg_motion_field(s, dest_y, dest_cb, dest_cr,
0, s->field_select[dir][0],
@@ -823,70 +902,72 @@
s->mv[dir][1][0], s->mv[dir][1][1], 8, 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[0]){
+ if ( s->picture_structure != s->field_select[dir][0] + 1 && s->pict_type != AV_PICTURE_TYPE_B && !s->first_field
+ || !ref_picture[0]) {
ref_picture = s->current_picture_ptr->f.data;
}
mpeg_motion(s, dest_y, dest_cb, dest_cr,
s->field_select[dir][0],
ref_picture, pix_op,
- s->mv[dir][0][0], s->mv[dir][0][1], 16, mb_y>>1);
+ s->mv[dir][0][0], s->mv[dir][0][1], 16, 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) && ref_picture[0]){
- ref2picture= ref_picture;
- }else{
+ if ((s->picture_structure == s->field_select[dir][i] + 1
+ || s->pict_type == AV_PICTURE_TYPE_B || s->first_field) && ref_picture[0]) {
+ ref2picture = ref_picture;
+ } else {
ref2picture = s->current_picture_ptr->f.data;
}
mpeg_motion(s, dest_y, dest_cb, dest_cr,
s->field_select[dir][i],
ref2picture, pix_op,
- s->mv[dir][i][0], s->mv[dir][i][1] + 16*i, 8, mb_y>>1);
+ s->mv[dir][i][0], s->mv[dir][i][1] + 16 * i,
+ 8, mb_y >> 1);
- dest_y += 16*s->linesize;
- dest_cb+= (16>>s->chroma_y_shift)*s->uvlinesize;
- dest_cr+= (16>>s->chroma_y_shift)*s->uvlinesize;
+ dest_y += 16 * s->linesize;
+ dest_cb += (16 >> s->chroma_y_shift) * s->uvlinesize;
+ dest_cr += (16 >> 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_field(s, dest_y, dest_cb, dest_cr,
- j, j^i, ref_picture, pix_op,
- s->mv[dir][2*i + j][0],
- s->mv[dir][2*i + j][1], 8, mb_y);
- }
+ j, j ^ i, ref_picture, pix_op,
+ s->mv[dir][2 * i + j][0],
+ s->mv[dir][2 * i + j][1], 8, mb_y);
pix_op = s->hdsp.avg_pixels_tab;
}
- }else{
+ } else {
if (!ref_picture[0]) {
ref_picture = s->current_picture_ptr->f.data;
}
- for(i=0; i<2; i++){
+ for (i = 0; i < 2; i++) {
mpeg_motion(s, dest_y, dest_cb, dest_cr,
- s->picture_structure != i+1,
+ s->picture_structure != i + 1,
ref_picture, pix_op,
- s->mv[dir][2*i][0],s->mv[dir][2*i][1],16, mb_y>>1);
+ s->mv[dir][2 * i][0], s->mv[dir][2 * i][1],
+ 16, mb_y >> 1);
// after put we make avg of the same block
- pix_op=s->hdsp.avg_pixels_tab;
+ pix_op = s->hdsp.avg_pixels_tab;
- //opposite parity is always in the same frame if this is second field
- if(!s->first_field){
+ /* 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;
+ break;
default: av_assert2(0);
}
}
@@ -899,7 +980,7 @@
qpel_mc_func (*qpix_op)[16])
{
#if !CONFIG_SMALL
- if(s->out_format == FMT_MPEG1)
+ if (s->out_format == FMT_MPEG1)
MPV_motion_internal(s, dest_y, dest_cb, dest_cr, dir,
ref_picture, pix_op, qpix_op, 1);
else
diff --git a/libavcodec/mpegvideo_parser.c b/libavcodec/mpegvideo_parser.c
index f127218..7aa3660 100644
--- a/libavcodec/mpegvideo_parser.c
+++ b/libavcodec/mpegvideo_parser.c
@@ -66,7 +66,7 @@
pc->width = (buf[0] << 4) | (buf[1] >> 4);
pc->height = ((buf[1] & 0x0f) << 8) | buf[2];
if(!avctx->width || !avctx->height || !avctx->coded_width || !avctx->coded_height){
- avcodec_set_dimensions(avctx, pc->width, pc->height);
+ ff_set_dimensions(avctx, pc->width, pc->height);
did_set_size=1;
}
frame_rate_index = buf[3] & 0xf;
@@ -94,7 +94,7 @@
pc->height |=( vert_size_ext << 12);
bit_rate = (bit_rate&0x3FFFF) | (bit_rate_ext << 18);
if(did_set_size)
- avcodec_set_dimensions(avctx, pc->width, pc->height);
+ ff_set_dimensions(avctx, pc->width, pc->height);
avctx->time_base.den = pc->frame_rate.den * (frame_rate_ext_n + 1) * 2;
avctx->time_base.num = pc->frame_rate.num * (frame_rate_ext_d + 1);
avctx->codec_id = AV_CODEC_ID_MPEG2VIDEO;
diff --git a/libavcodec/mpegvideo_xvmc.c b/libavcodec/mpegvideo_xvmc.c
index 6b0c6ac..664c008 100644
--- a/libavcodec/mpegvideo_xvmc.c
+++ b/libavcodec/mpegvideo_xvmc.c
@@ -30,6 +30,9 @@
#include "xvmc.h"
#include "xvmc_internal.h"
+#include "version.h"
+
+#if FF_API_XVMC
/**
* Initialize the block field of the MpegEncContext pointer passed as
@@ -329,3 +332,5 @@
if (render->filled_mv_blocks_num == render->allocated_mv_blocks)
ff_mpeg_draw_horiz_band(s, 0, 0);
}
+
+#endif /* FF_API_XVMC */
diff --git a/libavcodec/msgsmdec.c b/libavcodec/msgsmdec.c
index 90e83ae..4c4ddb4 100644
--- a/libavcodec/msgsmdec.c
+++ b/libavcodec/msgsmdec.c
@@ -26,13 +26,13 @@
#include "gsmdec_template.c"
int ff_msgsm_decode_block(AVCodecContext *avctx, int16_t *samples,
- const uint8_t *buf)
+ const uint8_t *buf, int mode)
{
int res;
GetBitContext gb;
init_get_bits(&gb, buf, GSM_MS_BLOCK_SIZE * 8);
- res = gsm_decode_block(avctx, samples, &gb);
+ res = gsm_decode_block(avctx, samples, &gb, mode);
if (res < 0)
return res;
- return gsm_decode_block(avctx, samples + GSM_FRAME_SIZE, &gb);
+ return gsm_decode_block(avctx, samples + GSM_FRAME_SIZE, &gb, mode);
}
diff --git a/libavcodec/msgsmdec.h b/libavcodec/msgsmdec.h
index 3bfd1fd..b2a1a62 100644
--- a/libavcodec/msgsmdec.h
+++ b/libavcodec/msgsmdec.h
@@ -25,6 +25,6 @@
#include "avcodec.h"
int ff_msgsm_decode_block(AVCodecContext *avctx, int16_t *samples,
- const uint8_t *buf);
+ const uint8_t *buf, int mode);
#endif /* AVCODEC_MSGSMDEC_H */
diff --git a/libavcodec/msmpeg4.c b/libavcodec/msmpeg4.c
index f2110e7..b071d74 100644
--- a/libavcodec/msmpeg4.c
+++ b/libavcodec/msmpeg4.c
@@ -240,10 +240,7 @@
: "%eax", "%edx"
);
#else
- /* #elif ARCH_ALPHA */
- /* Divisions are extremely costly on Alpha; optimize the most
- common case. But they are costly everywhere...
- */
+ /* Divisions are costly everywhere; optimize the most common case. */
if (scale == 8) {
a = (a + (8 >> 1)) / 8;
b = (b + (8 >> 1)) / 8;
diff --git a/libavcodec/msrle.c b/libavcodec/msrle.c
index 2b4ab1a..2836fec 100644
--- a/libavcodec/msrle.c
+++ b/libavcodec/msrle.c
@@ -38,7 +38,7 @@
typedef struct MsrleContext {
AVCodecContext *avctx;
- AVFrame frame;
+ AVFrame *frame;
GetByteContext gb;
const unsigned char *buf;
@@ -70,7 +70,9 @@
return AVERROR_INVALIDDATA;
}
- avcodec_get_frame_defaults(&s->frame);
+ s->frame = av_frame_alloc();
+ if (!s->frame)
+ return AVERROR(ENOMEM);
if (avctx->extradata_size >= 4)
for (i = 0; i < FFMIN(avctx->extradata_size, AVPALETTE_SIZE)/4; i++)
@@ -92,24 +94,24 @@
s->buf = buf;
s->size = buf_size;
- if ((ret = ff_reget_buffer(avctx, &s->frame)) < 0)
+ if ((ret = ff_reget_buffer(avctx, s->frame)) < 0)
return ret;
if (avctx->bits_per_coded_sample > 1 && avctx->bits_per_coded_sample <= 8) {
const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, NULL);
if (pal) {
- s->frame.palette_has_changed = 1;
+ s->frame->palette_has_changed = 1;
memcpy(s->pal, pal, AVPALETTE_SIZE);
}
/* make the palette available */
- memcpy(s->frame.data[1], s->pal, AVPALETTE_SIZE);
+ memcpy(s->frame->data[1], s->pal, AVPALETTE_SIZE);
}
/* FIXME how to correctly detect RLE ??? */
if (avctx->height * istride == avpkt->size) { /* assume uncompressed */
int linesize = (avctx->width * avctx->bits_per_coded_sample + 7) / 8;
- uint8_t *ptr = s->frame.data[0];
+ uint8_t *ptr = s->frame->data[0];
uint8_t *buf = avpkt->data + (avctx->height-1)*istride;
int i, j;
@@ -125,14 +127,14 @@
memcpy(ptr, buf, linesize);
}
buf -= istride;
- ptr += s->frame.linesize[0];
+ ptr += s->frame->linesize[0];
}
} else {
bytestream2_init(&s->gb, buf, buf_size);
- ff_msrle_decode(avctx, (AVPicture*)&s->frame, avctx->bits_per_coded_sample, &s->gb);
+ ff_msrle_decode(avctx, (AVPicture*)s->frame, avctx->bits_per_coded_sample, &s->gb);
}
- if ((ret = av_frame_ref(data, &s->frame)) < 0)
+ if ((ret = av_frame_ref(data, s->frame)) < 0)
return ret;
*got_frame = 1;
@@ -146,7 +148,7 @@
MsrleContext *s = avctx->priv_data;
/* release the last frame */
- av_frame_unref(&s->frame);
+ av_frame_free(&s->frame);
return 0;
}
diff --git a/libavcodec/mss1.c b/libavcodec/mss1.c
index 46ea2b5..fc88eb0 100644
--- a/libavcodec/mss1.c
+++ b/libavcodec/mss1.c
@@ -30,7 +30,7 @@
typedef struct MSS1Context {
MSS12Context ctx;
- AVFrame pic;
+ AVFrame *pic;
SliceContext sc;
} MSS1Context;
@@ -139,8 +139,6 @@
static int mss1_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
AVPacket *avpkt)
{
- const uint8_t *buf = avpkt->data;
- int buf_size = avpkt->size;
MSS1Context *ctx = avctx->priv_data;
MSS12Context *c = &ctx->ctx;
GetBitContext gb;
@@ -148,41 +146,43 @@
int pal_changed = 0;
int ret;
- init_get_bits(&gb, buf, buf_size * 8);
- arith_init(&acoder, &gb);
-
- if ((ret = ff_reget_buffer(avctx, &ctx->pic)) < 0)
+ if ((ret = init_get_bits8(&gb, avpkt->data, avpkt->size)) < 0)
return ret;
- c->pal_pic = ctx->pic.data[0] + ctx->pic.linesize[0] * (avctx->height - 1);
- c->pal_stride = -ctx->pic.linesize[0];
+ arith_init(&acoder, &gb);
+
+ if ((ret = ff_reget_buffer(avctx, ctx->pic)) < 0)
+ return ret;
+
+ c->pal_pic = ctx->pic->data[0] + ctx->pic->linesize[0] * (avctx->height - 1);
+ c->pal_stride = -ctx->pic->linesize[0];
c->keyframe = !arith_get_bit(&acoder);
if (c->keyframe) {
c->corrupted = 0;
ff_mss12_slicecontext_reset(&ctx->sc);
pal_changed = decode_pal(c, &acoder);
- ctx->pic.key_frame = 1;
- ctx->pic.pict_type = AV_PICTURE_TYPE_I;
+ ctx->pic->key_frame = 1;
+ ctx->pic->pict_type = AV_PICTURE_TYPE_I;
} else {
if (c->corrupted)
return AVERROR_INVALIDDATA;
- ctx->pic.key_frame = 0;
- ctx->pic.pict_type = AV_PICTURE_TYPE_P;
+ ctx->pic->key_frame = 0;
+ ctx->pic->pict_type = AV_PICTURE_TYPE_P;
}
c->corrupted = ff_mss12_decode_rect(&ctx->sc, &acoder, 0, 0,
avctx->width, avctx->height);
if (c->corrupted)
return AVERROR_INVALIDDATA;
- memcpy(ctx->pic.data[1], c->pal, AVPALETTE_SIZE);
- ctx->pic.palette_has_changed = pal_changed;
+ memcpy(ctx->pic->data[1], c->pal, AVPALETTE_SIZE);
+ ctx->pic->palette_has_changed = pal_changed;
- if ((ret = av_frame_ref(data, &ctx->pic)) < 0)
+ if ((ret = av_frame_ref(data, ctx->pic)) < 0)
return ret;
*got_frame = 1;
/* always report that the buffer was completely consumed */
- return buf_size;
+ return avpkt->size;
}
static av_cold int mss1_decode_init(AVCodecContext *avctx)
@@ -192,7 +192,9 @@
c->ctx.avctx = avctx;
- avcodec_get_frame_defaults(&c->pic);
+ c->pic = av_frame_alloc();
+ if (!c->pic)
+ return AVERROR(ENOMEM);
ret = ff_mss12_decode_init(&c->ctx, 0, &c->sc, NULL);
@@ -205,7 +207,7 @@
{
MSS1Context * const ctx = avctx->priv_data;
- av_frame_unref(&ctx->pic);
+ av_frame_free(&ctx->pic);
ff_mss12_decode_end(&ctx->ctx);
return 0;
diff --git a/libavcodec/mss2.c b/libavcodec/mss2.c
index fcb50e3..99db046 100644
--- a/libavcodec/mss2.c
+++ b/libavcodec/mss2.c
@@ -377,14 +377,8 @@
ff_mpeg_flush(avctx);
- 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];
- }
-
- init_get_bits(&s->gb, buf, buf_size * 8);
+ if ((ret = init_get_bits8(&s->gb, buf, buf_size)) < 0)
+ return ret;
s->loop_filter = avctx->skip_loop_filter < AVDISCARD_ALL;
@@ -482,7 +476,8 @@
av_assert0(FF_INPUT_BUFFER_PADDING_SIZE >=
ARITH2_PADDING + (MIN_CACHE_BITS + 7) / 8);
- init_get_bits(&gb, buf, buf_size * 8);
+ if ((ret = init_get_bits8(&gb, buf, buf_size)) < 0)
+ return ret;
if (keyframe = get_bits1(&gb))
skip_bits(&gb, 7);
@@ -640,7 +635,8 @@
ff_mss12_slicecontext_reset(&ctx->sc[1]);
}
if (is_rle) {
- init_get_bits(&gb, buf, buf_size * 8);
+ if ((ret = init_get_bits8(&gb, buf, buf_size)) < 0)
+ return ret;
if (ret = decode_rle(&gb, c->pal_pic, c->pal_stride,
c->rgb_pic, c->rgb_stride, c->pal, keyframe,
ctx->split_position, 0,
@@ -775,7 +771,7 @@
v->overlap = 0;
- v->s.resync_marker = 0;
+ v->resync_marker = 0;
v->rangered = 0;
v->s.max_b_frames = avctx->max_b_frames = 0;
@@ -837,6 +833,7 @@
avctx->pix_fmt = c->free_colours == 127 ? AV_PIX_FMT_RGB555
: AV_PIX_FMT_RGB24;
+
return 0;
}
diff --git a/libavcodec/mss3.c b/libavcodec/mss3.c
index a3aec80..c6bb838 100644
--- a/libavcodec/mss3.c
+++ b/libavcodec/mss3.c
@@ -803,15 +803,24 @@
return buf_size;
}
+static av_cold int mss3_decode_end(AVCodecContext *avctx)
+{
+ MSS3Context * const c = avctx->priv_data;
+ int i;
+
+ av_frame_free(&c->pic);
+ for (i = 0; i < 3; i++)
+ av_freep(&c->dct_coder[i].prev_dc);
+
+ return 0;
+}
+
static av_cold int mss3_decode_init(AVCodecContext *avctx)
{
MSS3Context * const c = avctx->priv_data;
int i;
c->avctx = avctx;
- c->pic = av_frame_alloc();
- if (!c->pic)
- return AVERROR(ENOMEM);
if ((avctx->width & 0xF) || (avctx->height & 0xF)) {
av_log(avctx, AV_LOG_ERROR,
@@ -838,6 +847,12 @@
}
}
+ c->pic = av_frame_alloc();
+ if (!c->pic) {
+ mss3_decode_end(avctx);
+ return AVERROR(ENOMEM);
+ }
+
avctx->pix_fmt = AV_PIX_FMT_YUV420P;
init_coders(c);
@@ -845,18 +860,6 @@
return 0;
}
-static av_cold int mss3_decode_end(AVCodecContext *avctx)
-{
- MSS3Context * const c = avctx->priv_data;
- int i;
-
- av_frame_free(&c->pic);
- for (i = 0; i < 3; i++)
- av_freep(&c->dct_coder[i].prev_dc);
-
- return 0;
-}
-
AVCodec ff_msa1_decoder = {
.name = "msa1",
.long_name = NULL_IF_CONFIG_SMALL("MS ATC Screen"),
diff --git a/libavcodec/mss4.c b/libavcodec/mss4.c
index fd1f316..662cf24 100644
--- a/libavcodec/mss4.c
+++ b/libavcodec/mss4.c
@@ -626,14 +626,23 @@
return buf_size;
}
-static av_cold int mss4_decode_init(AVCodecContext *avctx)
+static av_cold int mss4_decode_end(AVCodecContext *avctx)
{
MSS4Context * const c = avctx->priv_data;
int i;
- c->pic = av_frame_alloc();
- if (!c->pic)
- return AVERROR(ENOMEM);
+ av_frame_free(&c->pic);
+ for (i = 0; i < 3; i++)
+ av_freep(&c->prev_dc[i]);
+ mss4_free_vlcs(c);
+
+ return 0;
+}
+
+static av_cold int mss4_decode_init(AVCodecContext *avctx)
+{
+ MSS4Context * const c = avctx->priv_data;
+ int i;
if (mss4_init_vlcs(c)) {
av_log(avctx, AV_LOG_ERROR, "Cannot initialise VLCs\n");
@@ -650,25 +659,17 @@
}
}
+ c->pic = av_frame_alloc();
+ if (!c->pic) {
+ mss4_decode_end(avctx);
+ return AVERROR(ENOMEM);
+ }
+
avctx->pix_fmt = AV_PIX_FMT_YUV444P;
return 0;
}
-static av_cold int mss4_decode_end(AVCodecContext *avctx)
-{
- MSS4Context * const c = avctx->priv_data;
- int i;
-
- av_frame_free(&c->pic);
-
- for (i = 0; i < 3; i++)
- av_freep(&c->prev_dc[i]);
- mss4_free_vlcs(c);
-
- return 0;
-}
-
AVCodec ff_mts2_decoder = {
.name = "mts2",
.long_name = NULL_IF_CONFIG_SMALL("MS Expression Encoder Screen"),
diff --git a/libavcodec/msvideo1.c b/libavcodec/msvideo1.c
index 83c50ac..970c67c 100644
--- a/libavcodec/msvideo1.c
+++ b/libavcodec/msvideo1.c
@@ -47,7 +47,7 @@
typedef struct Msvideo1Context {
AVCodecContext *avctx;
- AVFrame frame;
+ AVFrame *frame;
const unsigned char *buf;
int size;
@@ -72,7 +72,9 @@
avctx->pix_fmt = AV_PIX_FMT_RGB555;
}
- avcodec_get_frame_defaults(&s->frame);
+ s->frame = av_frame_alloc();
+ if (!s->frame)
+ return AVERROR(ENOMEM);
return 0;
}
@@ -93,8 +95,8 @@
unsigned short flags;
int skip_blocks;
unsigned char colors[8];
- unsigned char *pixels = s->frame.data[0];
- int stride = s->frame.linesize[0];
+ unsigned char *pixels = s->frame->data[0];
+ int stride = s->frame->linesize[0];
stream_ptr = 0;
skip_blocks = 0;
@@ -174,7 +176,7 @@
/* make the palette available on the way out */
if (s->avctx->pix_fmt == AV_PIX_FMT_PAL8)
- memcpy(s->frame.data[1], s->pal, AVPALETTE_SIZE);
+ memcpy(s->frame->data[1], s->pal, AVPALETTE_SIZE);
}
static void msvideo1_decode_16bit(Msvideo1Context *s)
@@ -193,8 +195,8 @@
unsigned short flags;
int skip_blocks;
unsigned short colors[8];
- unsigned short *pixels = (unsigned short *)s->frame.data[0];
- int stride = s->frame.linesize[0] / 2;
+ unsigned short *pixels = (unsigned short *)s->frame->data[0];
+ int stride = s->frame->linesize[0] / 2;
stream_ptr = 0;
skip_blocks = 0;
@@ -298,7 +300,7 @@
s->buf = buf;
s->size = buf_size;
- if ((ret = ff_reget_buffer(avctx, &s->frame)) < 0)
+ if ((ret = ff_reget_buffer(avctx, s->frame)) < 0)
return ret;
if (s->mode_8bit) {
@@ -306,7 +308,7 @@
if (pal) {
memcpy(s->pal, pal, AVPALETTE_SIZE);
- s->frame.palette_has_changed = 1;
+ s->frame->palette_has_changed = 1;
}
}
@@ -315,7 +317,7 @@
else
msvideo1_decode_16bit(s);
- if ((ret = av_frame_ref(data, &s->frame)) < 0)
+ if ((ret = av_frame_ref(data, s->frame)) < 0)
return ret;
*got_frame = 1;
@@ -328,7 +330,7 @@
{
Msvideo1Context *s = avctx->priv_data;
- av_frame_unref(&s->frame);
+ av_frame_free(&s->frame);
return 0;
}
diff --git a/libavcodec/msvideo1enc.c b/libavcodec/msvideo1enc.c
index 1da302a..7844d57 100644
--- a/libavcodec/msvideo1enc.c
+++ b/libavcodec/msvideo1enc.c
@@ -118,8 +118,8 @@
}
// try to find optimal value to fill whole 4x4 block
score = 0;
- ff_init_elbg(c->block, 3, 16, c->avg, 1, 1, c->output, &c->rnd);
- ff_do_elbg (c->block, 3, 16, c->avg, 1, 1, c->output, &c->rnd);
+ avpriv_init_elbg(c->block, 3, 16, c->avg, 1, 1, c->output, &c->rnd);
+ avpriv_do_elbg (c->block, 3, 16, c->avg, 1, 1, c->output, &c->rnd);
if(c->avg[0] == 1) // red component = 1 will be written as skip code
c->avg[0] = 0;
for(j = 0; j < 4; j++){
@@ -138,8 +138,8 @@
}
// search for optimal filling of 2-color block
score = 0;
- ff_init_elbg(c->block, 3, 16, c->codebook, 2, 1, c->output, &c->rnd);
- ff_do_elbg (c->block, 3, 16, c->codebook, 2, 1, c->output, &c->rnd);
+ avpriv_init_elbg(c->block, 3, 16, c->codebook, 2, 1, c->output, &c->rnd);
+ avpriv_do_elbg (c->block, 3, 16, c->codebook, 2, 1, c->output, &c->rnd);
// last output value should be always 1, swap codebooks if needed
if(!c->output[15]){
for(i = 0; i < 3; i++)
@@ -164,8 +164,8 @@
// search for optimal filling of 2-color 2x2 subblocks
score = 0;
for(i = 0; i < 4; i++){
- ff_init_elbg(c->block2 + i*4*3, 3, 4, c->codebook2 + i*2*3, 2, 1, c->output2 + i*4, &c->rnd);
- ff_do_elbg (c->block2 + i*4*3, 3, 4, c->codebook2 + i*2*3, 2, 1, c->output2 + i*4, &c->rnd);
+ avpriv_init_elbg(c->block2 + i*4*3, 3, 4, c->codebook2 + i*2*3, 2, 1, c->output2 + i*4, &c->rnd);
+ avpriv_do_elbg (c->block2 + i*4*3, 3, 4, c->codebook2 + i*2*3, 2, 1, c->output2 + i*4, &c->rnd);
}
// last value should be always 1, swap codebooks if needed
if(!c->output2[15]){
diff --git a/libavcodec/mvcdec.c b/libavcodec/mvcdec.c
index 423c7c4..2cc7735 100644
--- a/libavcodec/mvcdec.c
+++ b/libavcodec/mvcdec.c
@@ -39,6 +39,7 @@
MvcContext *s = avctx->priv_data;
int width = avctx->width;
int height = avctx->height;
+ int ret;
if (avctx->codec_id == AV_CODEC_ID_MVC1) {
width += 3;
@@ -46,8 +47,8 @@
}
width &= ~3;
height &= ~3;
- if (width != avctx->width || height != avctx->height)
- avcodec_set_dimensions(avctx, width, height);
+ if ((ret = ff_set_dimensions(avctx, width, height)) < 0)
+ return ret;
avctx->pix_fmt = (avctx->codec_id == AV_CODEC_ID_MVC1) ? AV_PIX_FMT_RGB555 : AV_PIX_FMT_BGRA;
s->frame = av_frame_alloc();
diff --git a/libavcodec/mxpegdec.c b/libavcodec/mxpegdec.c
index 0069ca5..8eee3b8 100644
--- a/libavcodec/mxpegdec.c
+++ b/libavcodec/mxpegdec.c
@@ -31,7 +31,7 @@
typedef struct MXpegDecodeContext {
MJpegDecodeContext jpg;
- AVFrame picture[2]; /* pictures array */
+ AVFrame *picture[2]; /* pictures array */
int picture_index; /* index of current picture */
int got_sof_data; /* true if SOF data successfully parsed */
int got_mxm_bitmask; /* true if MXM bitmask available */
@@ -42,11 +42,36 @@
unsigned mb_width, mb_height; /* size of picture in MB's from MXM header */
} MXpegDecodeContext;
+static av_cold int mxpeg_decode_end(AVCodecContext *avctx)
+{
+ MXpegDecodeContext *s = avctx->priv_data;
+ MJpegDecodeContext *jpg = &s->jpg;
+ int i;
+
+ jpg->picture_ptr = NULL;
+ ff_mjpeg_decode_end(avctx);
+
+ for (i = 0; i < 2; ++i)
+ av_frame_free(&s->picture[i]);
+
+ av_freep(&s->mxm_bitmask);
+ av_freep(&s->completion_bitmask);
+
+ return 0;
+}
+
static av_cold int mxpeg_decode_init(AVCodecContext *avctx)
{
MXpegDecodeContext *s = avctx->priv_data;
- s->jpg.picture_ptr = &s->picture[0];
+ s->picture[0] = av_frame_alloc();
+ s->picture[1] = av_frame_alloc();
+ if (!s->picture[0] || !s->picture[1]) {
+ mxpeg_decode_end(avctx);
+ return AVERROR(ENOMEM);
+ }
+
+ s->jpg.picture_ptr = s->picture[0];
return ff_mjpeg_decode_init(avctx);
}
@@ -260,7 +285,7 @@
}
if (s->got_mxm_bitmask) {
- AVFrame *reference_ptr = &s->picture[s->picture_index ^ 1];
+ AVFrame *reference_ptr = s->picture[s->picture_index ^ 1];
if (mxpeg_check_dimensions(s, jpg, reference_ptr) < 0)
break;
@@ -295,7 +320,7 @@
*got_frame = 1;
s->picture_index ^= 1;
- jpg->picture_ptr = &s->picture[s->picture_index];
+ jpg->picture_ptr = s->picture[s->picture_index];
if (!s->has_complete_frame) {
if (!s->got_mxm_bitmask)
@@ -308,24 +333,6 @@
return buf_ptr - buf;
}
-static av_cold int mxpeg_decode_end(AVCodecContext *avctx)
-{
- MXpegDecodeContext *s = avctx->priv_data;
- MJpegDecodeContext *jpg = &s->jpg;
- int i;
-
- jpg->picture_ptr = NULL;
- ff_mjpeg_decode_end(avctx);
-
- for (i = 0; i < 2; ++i)
- av_frame_unref(&s->picture[i]);
-
- av_freep(&s->mxm_bitmask);
- av_freep(&s->completion_bitmask);
-
- return 0;
-}
-
AVCodec ff_mxpeg_decoder = {
.name = "mxpeg",
.long_name = NULL_IF_CONFIG_SMALL("Mobotix MxPEG video"),
diff --git a/libavcodec/nuv.c b/libavcodec/nuv.c
index bfbf802..d4d9318 100644
--- a/libavcodec/nuv.c
+++ b/libavcodec/nuv.c
@@ -32,7 +32,7 @@
#include "rtjpeg.h"
typedef struct {
- AVFrame pic;
+ AVFrame *pic;
int codec_frameheader;
int quality;
int width, height;
@@ -140,7 +140,7 @@
}
ff_rtjpeg_decode_init(&c->rtj, &c->dsp, c->width, c->height,
c->lq, c->cq);
- av_frame_unref(&c->pic);
+ av_frame_unref(c->pic);
return 1;
} else if (quality != c->quality)
ff_rtjpeg_decode_init(&c->rtj, &c->dsp, c->width, c->height,
@@ -248,20 +248,20 @@
}
if (size_change || keyframe) {
- av_frame_unref(&c->pic);
+ av_frame_unref(c->pic);
init_frame = 1;
}
- if ((result = ff_reget_buffer(avctx, &c->pic)) < 0)
+ if ((result = ff_reget_buffer(avctx, c->pic)) < 0)
return result;
if (init_frame) {
- memset(c->pic.data[0], 0, avctx->height * c->pic.linesize[0]);
- memset(c->pic.data[1], 0x80, avctx->height * c->pic.linesize[1] / 2);
- memset(c->pic.data[2], 0x80, avctx->height * c->pic.linesize[2] / 2);
+ memset(c->pic->data[0], 0, avctx->height * c->pic->linesize[0]);
+ memset(c->pic->data[1], 0x80, avctx->height * c->pic->linesize[1] / 2);
+ memset(c->pic->data[2], 0x80, avctx->height * c->pic->linesize[2] / 2);
}
- c->pic.pict_type = keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P;
- c->pic.key_frame = keyframe;
+ c->pic->pict_type = keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P;
+ c->pic->key_frame = keyframe;
// decompress/copy/whatever data
switch (comptype) {
case NUV_LZO:
@@ -272,19 +272,19 @@
height = buf_size / c->width / 3 * 2;
}
if(height > 0)
- copy_frame(&c->pic, buf, c->width, height);
+ copy_frame(c->pic, buf, c->width, height);
break;
}
case NUV_RTJPEG_IN_LZO:
case NUV_RTJPEG:
- ret = ff_rtjpeg_decode_frame_yuv420(&c->rtj, &c->pic, buf, buf_size);
+ ret = ff_rtjpeg_decode_frame_yuv420(&c->rtj, c->pic, buf, buf_size);
if (ret < 0)
return ret;
break;
case NUV_BLACK:
- memset(c->pic.data[0], 0, c->width * c->height);
- memset(c->pic.data[1], 128, c->width * c->height / 4);
- memset(c->pic.data[2], 128, c->width * c->height / 4);
+ memset(c->pic->data[0], 0, c->width * c->height);
+ memset(c->pic->data[1], 128, c->width * c->height / 4);
+ memset(c->pic->data[2], 128, c->width * c->height / 4);
break;
case NUV_COPY_LAST:
/* nothing more to do here */
@@ -294,7 +294,7 @@
return AVERROR_INVALIDDATA;
}
- if ((result = av_frame_ref(picture, &c->pic)) < 0)
+ if ((result = av_frame_ref(picture, c->pic)) < 0)
return result;
*got_frame = 1;
@@ -306,8 +306,11 @@
NuvContext *c = avctx->priv_data;
int ret;
+ c->pic = av_frame_alloc();
+ if (!c->pic)
+ return AVERROR(ENOMEM);
+
avctx->pix_fmt = AV_PIX_FMT_YUV420P;
- c->pic.data[0] = NULL;
c->decomp_buf = NULL;
c->quality = -1;
c->width = 0;
@@ -331,7 +334,7 @@
NuvContext *c = avctx->priv_data;
av_freep(&c->decomp_buf);
- av_frame_unref(&c->pic);
+ av_frame_free(&c->pic);
return 0;
}
diff --git a/libavcodec/old_codec_ids.h b/libavcodec/old_codec_ids.h
index d8a8f74..b956264 100644
--- a/libavcodec/old_codec_ids.h
+++ b/libavcodec/old_codec_ids.h
@@ -34,7 +34,9 @@
/* video codecs */
CODEC_ID_MPEG1VIDEO,
CODEC_ID_MPEG2VIDEO, ///< preferred ID for MPEG-1/2 video decoding
+#if FF_API_XVMC
CODEC_ID_MPEG2VIDEO_XVMC,
+#endif
CODEC_ID_H261,
CODEC_ID_H263,
CODEC_ID_RV10,
diff --git a/libavcodec/options.c b/libavcodec/options.c
index 02fb89f..5ee9d6b 100644
--- a/libavcodec/options.c
+++ b/libavcodec/options.c
@@ -86,14 +86,6 @@
.get_category = get_category,
};
-#if FF_API_ALLOC_CONTEXT
-void avcodec_get_context_defaults2(AVCodecContext *s, enum AVMediaType codec_type){
- AVCodec c= {0};
- c.type= codec_type;
- avcodec_get_context_defaults3(s, &c);
-}
-#endif
-
int avcodec_get_context_defaults3(AVCodecContext *s, const AVCodec *codec)
{
int flags=0;
@@ -162,26 +154,6 @@
return avctx;
}
-#if FF_API_ALLOC_CONTEXT
-AVCodecContext *avcodec_alloc_context2(enum AVMediaType codec_type){
- AVCodecContext *avctx= av_malloc(sizeof(AVCodecContext));
-
- if(avctx==NULL) return NULL;
-
- avcodec_get_context_defaults2(avctx, codec_type);
-
- return avctx;
-}
-
-void avcodec_get_context_defaults(AVCodecContext *s){
- avcodec_get_context_defaults2(s, AVMEDIA_TYPE_UNKNOWN);
-}
-
-AVCodecContext *avcodec_alloc_context(void){
- return avcodec_alloc_context2(AVMEDIA_TYPE_UNKNOWN);
-}
-#endif
-
int avcodec_copy_context(AVCodecContext *dest, const AVCodecContext *src)
{
if (avcodec_is_open(dest)) { // check that the dest context is uninitialized
@@ -201,7 +173,6 @@
dest->codec = NULL;
dest->slice_offset = NULL;
dest->hwaccel = NULL;
- dest->thread_opaque = NULL;
dest->internal = NULL;
/* reallocate values that should be allocated separately */
diff --git a/libavcodec/options_table.h b/libavcodec/options_table.h
index a274073..49af29c 100644
--- a/libavcodec/options_table.h
+++ b/libavcodec/options_table.h
@@ -24,6 +24,7 @@
#include <float.h>
#include <limits.h>
+#include <stdint.h>
#include "libavutil/opt.h"
#include "avcodec.h"
@@ -70,6 +71,7 @@
{"aic", "H.263 advanced intra coding / MPEG-4 AC prediction", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_AC_PRED }, INT_MIN, INT_MAX, V|E, "flags"},
{"ilme", "interlaced motion estimation", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_INTERLACED_ME }, INT_MIN, INT_MAX, V|E, "flags"},
{"cgop", "closed GOP", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_CLOSED_GOP }, INT_MIN, INT_MAX, V|E, "flags"},
+{"output_corrupt", "Output even potentially corrupted frames", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_OUTPUT_CORRUPT }, INT_MIN, INT_MAX, V|D, "flags"},
{"fast", "allow non-spec-compliant speedup tricks", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG2_FAST }, INT_MIN, INT_MAX, V|E, "flags2"},
{"noout", "skip bitstream encoding", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG2_NO_OUTPUT }, INT_MIN, INT_MAX, V|E, "flags2"},
{"ignorecrop", "ignore cropping information from sps", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG2_IGNORE_CROP }, INT_MIN, INT_MAX, V|D, "flags2"},
@@ -105,7 +107,7 @@
{"qmin", "minimum video quantizer scale (VBR)", OFFSET(qmin), AV_OPT_TYPE_INT, {.i64 = 2 }, -1, 69, V|E},
{"qmax", "maximum video quantizer scale (VBR)", OFFSET(qmax), AV_OPT_TYPE_INT, {.i64 = 31 }, -1, 1024, V|E},
{"qdiff", "maximum difference between the quantizer scales (VBR)", OFFSET(max_qdiff), AV_OPT_TYPE_INT, {.i64 = 3 }, INT_MIN, INT_MAX, V|E},
-{"bf", "use 'frames' B frames", OFFSET(max_b_frames), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, -1, FF_MAX_B_FRAMES, V|E},
+{"bf", "set maximum number of B frames between non-B-frames", OFFSET(max_b_frames), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, -1, INT_MAX, 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, {.i64 = 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, {.i64 = 0 }, INT_MIN, INT_MAX, V|E},
@@ -122,12 +124,16 @@
{"codec_tag", NULL, OFFSET(codec_tag), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
{"bug", "work around not autodetected encoder bugs", OFFSET(workaround_bugs), AV_OPT_TYPE_FLAGS, {.i64 = FF_BUG_AUTODETECT }, INT_MIN, INT_MAX, V|D, "bug"},
{"autodetect", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_AUTODETECT }, INT_MIN, INT_MAX, V|D, "bug"},
+#if FF_API_OLD_MSMPEG4
{"old_msmpeg4", "some old lavc-generated MSMPEG4v3 files (no autodetection)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_OLD_MSMPEG4 }, INT_MIN, INT_MAX, V|D, "bug"},
+#endif
{"xvid_ilace", "Xvid interlacing bug (autodetected if FOURCC == XVIX)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_XVID_ILACE }, INT_MIN, INT_MAX, V|D, "bug"},
{"ump4", "(autodetected if FOURCC == UMP4)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_UMP4 }, INT_MIN, INT_MAX, V|D, "bug"},
{"no_padding", "padding bug (autodetected)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_NO_PADDING }, INT_MIN, INT_MAX, V|D, "bug"},
{"amv", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_AMV }, INT_MIN, INT_MAX, V|D, "bug"},
+#if FF_API_AC_VLC
{"ac_vlc", "illegal VLC bug (autodetected per FOURCC)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_AC_VLC }, INT_MIN, INT_MAX, V|D, "bug"},
+#endif
{"qpel_chroma", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 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, {.i64 = FF_BUG_STD_QPEL }, INT_MIN, INT_MAX, V|D, "bug"},
{"qpel_chroma2", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_QPEL_CHROMA2 }, INT_MIN, INT_MAX, V|D, "bug"},
@@ -144,12 +150,12 @@
{"unofficial", "allow unofficial extensions", 0, AV_OPT_TYPE_CONST, {.i64 = FF_COMPLIANCE_UNOFFICIAL }, INT_MIN, INT_MAX, V|D|E, "strict"},
{"experimental", "allow non-standardized experimental things", 0, AV_OPT_TYPE_CONST, {.i64 = 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},
-{"err_detect", "set error detection flags", OFFSET(err_recognition), AV_OPT_TYPE_FLAGS, {.i64 = AV_EF_CRCCHECK }, INT_MIN, INT_MAX, A|V|D, "err_detect"},
+{"err_detect", "set error detection flags", OFFSET(err_recognition), AV_OPT_TYPE_FLAGS, {.i64 = 0 }, INT_MIN, INT_MAX, A|V|D, "err_detect"},
{"crccheck", "verify embedded CRCs", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_CRCCHECK }, INT_MIN, INT_MAX, A|V|D, "err_detect"},
{"bitstream", "detect bitstream specification deviations", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_BITSTREAM }, INT_MIN, INT_MAX, A|V|D, "err_detect"},
{"buffer", "detect improper bitstream length", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_BUFFER }, INT_MIN, INT_MAX, A|V|D, "err_detect"},
{"explode", "abort decoding on minor error detection", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_EXPLODE }, INT_MIN, INT_MAX, A|V|D, "err_detect"},
-{"careful", "consider things that violate the spec and have not been seen in the wild as errors", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_CAREFUL }, INT_MIN, INT_MAX, A|V|D, "err_detect"},
+{"careful", "consider things that violate the spec, are fast to check and have not been seen in the wild as errors", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_CAREFUL }, INT_MIN, INT_MAX, A|V|D, "err_detect"},
{"compliant", "consider all spec non compliancies as errors", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_COMPLIANT }, INT_MIN, INT_MAX, A|V|D, "err_detect"},
{"aggressive", "consider things that a sane encoder should not do as an error", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_AGGRESSIVE }, INT_MIN, INT_MAX, A|V|D, "err_detect"},
{"has_b_frames", NULL, OFFSET(has_b_frames), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
@@ -196,7 +202,9 @@
{"simplearmv5te", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEARMV5TE }, INT_MIN, INT_MAX, V|E|D, "idct"},
{"simplearmv6", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEARMV6 }, INT_MIN, INT_MAX, V|E|D, "idct"},
{"simpleneon", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLENEON }, INT_MIN, INT_MAX, V|E|D, "idct"},
+#if FF_API_ARCH_ALPHA
{"simplealpha", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEALPHA }, INT_MIN, INT_MAX, V|E|D, "idct"},
+#endif
{"ipp", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_IPP }, INT_MIN, INT_MAX, V|E|D, "idct"},
{"xvidmmx", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_XVIDMMX }, INT_MIN, INT_MAX, V|E|D, "idct"},
{"faani", "floating point AAN IDCT", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_FAAN }, INT_MIN, INT_MAX, V|D|E, "idct"},
@@ -216,7 +224,9 @@
{"bitstream", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_BITSTREAM }, INT_MIN, INT_MAX, V|D, "debug"},
{"mb_type", "macroblock (MB) type", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_MB_TYPE }, INT_MIN, INT_MAX, V|D, "debug"},
{"qp", "per-block quantization parameter (QP)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_QP }, INT_MIN, INT_MAX, V|D, "debug"},
+#if FF_API_DEBUG_MV
{"mv", "motion vector", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_MV }, INT_MIN, INT_MAX, V|D, "debug"},
+#endif
{"dct_coeff", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_DCT_COEFF }, INT_MIN, INT_MAX, V|D, "debug"},
{"skip", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_SKIP }, INT_MIN, INT_MAX, V|D, "debug"},
{"startcode", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_STARTCODE }, INT_MIN, INT_MAX, V|D, "debug"},
@@ -272,7 +282,9 @@
{"deflate", "deflate-based coder", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CODER_TYPE_DEFLATE }, INT_MIN, INT_MAX, V|E, "coder"},
{"context", "context model", OFFSET(context_model), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
{"slice_flags", NULL, OFFSET(slice_flags), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
+#if FF_API_XVMC
{"xvmc_acceleration", NULL, OFFSET(xvmc_acceleration), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
+#endif /* FF_API_XVMC */
{"mbd", "macroblock decision algorithm (high quality mode)", OFFSET(mb_decision), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, 2, V|E, "mbd"},
{"simple", "use mbcmp (default)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MB_DECISION_SIMPLE }, INT_MIN, INT_MAX, V|E, "mbd"},
{"bits", "use fewest bits", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MB_DECISION_BITS }, INT_MIN, INT_MAX, V|E, "mbd"},
@@ -284,7 +296,9 @@
{"nr", "noise reduction", OFFSET(noise_reduction), AV_OPT_TYPE_INT, {.i64 = 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, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
{"flags2", NULL, OFFSET(flags2), AV_OPT_TYPE_FLAGS, {.i64 = DEFAULT}, 0, UINT_MAX, V|A|E|D, "flags2"},
+#if FF_API_ERROR_RATE
{"error", NULL, OFFSET(error_rate), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
+#endif
{"threads", NULL, OFFSET(thread_count), AV_OPT_TYPE_INT, {.i64 = 1 }, 0, INT_MAX, V|A|E|D, "threads"},
{"auto", "autodetect a suitable number of threads to use", 0, AV_OPT_TYPE_CONST, {.i64 = 0 }, INT_MIN, INT_MAX, V|E|D, "threads"},
{"me_threshold", "motion estimation threshold", OFFSET(me_threshold), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
diff --git a/libavcodec/pamenc.c b/libavcodec/pamenc.c
index 2421464..64ab2b5 100644
--- a/libavcodec/pamenc.c
+++ b/libavcodec/pamenc.c
@@ -21,13 +21,11 @@
#include "avcodec.h"
#include "internal.h"
-#include "pnm.h"
-
static int pam_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
const AVFrame *p, int *got_packet)
{
- PNMContext *s = avctx->priv_data;
+ uint8_t *bytestream_start, *bytestream, *bytestream_end;
int i, h, w, n, linesize, depth, maxval, ret;
const char *tuple_type;
uint8_t *ptr;
@@ -90,14 +88,14 @@
if ((ret = ff_alloc_packet2(avctx, pkt, n*h + 200)) < 0)
return ret;
- s->bytestream_start =
- s->bytestream = pkt->data;
- s->bytestream_end = pkt->data + pkt->size;
+ bytestream_start =
+ bytestream = pkt->data;
+ bytestream_end = pkt->data + pkt->size;
- snprintf(s->bytestream, s->bytestream_end - s->bytestream,
+ snprintf(bytestream, bytestream_end - bytestream,
"P7\nWIDTH %d\nHEIGHT %d\nDEPTH %d\nMAXVAL %d\nTUPLTYPE %s\nENDHDR\n",
w, h, depth, maxval, tuple_type);
- s->bytestream += strlen(s->bytestream);
+ bytestream += strlen(bytestream);
ptr = p->data[0];
linesize = p->linesize[0];
@@ -106,30 +104,48 @@
int j;
for (i = 0; i < h; i++) {
for (j = 0; j < w; j++)
- *s->bytestream++ = ptr[j >> 3] >> (7 - j & 7) & 1;
+ *bytestream++ = ptr[j >> 3] >> (7 - j & 7) & 1;
ptr += linesize;
}
} else {
for (i = 0; i < h; i++) {
- memcpy(s->bytestream, ptr, n);
- s->bytestream += n;
- ptr += linesize;
+ memcpy(bytestream, ptr, n);
+ bytestream += n;
+ ptr += linesize;
}
}
- pkt->size = s->bytestream - s->bytestream_start;
+ pkt->size = bytestream - bytestream_start;
pkt->flags |= AV_PKT_FLAG_KEY;
*got_packet = 1;
return 0;
}
+static av_cold int pam_encode_init(AVCodecContext *avctx)
+{
+ avctx->coded_frame = av_frame_alloc();
+ if (!avctx->coded_frame)
+ return AVERROR(ENOMEM);
+
+ avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
+ avctx->coded_frame->key_frame = 1;
+
+ return 0;
+}
+
+static av_cold int pam_encode_close(AVCodecContext *avctx)
+{
+ av_frame_free(&avctx->coded_frame);
+ return 0;
+}
AVCodec ff_pam_encoder = {
.name = "pam",
.long_name = NULL_IF_CONFIG_SMALL("PAM (Portable AnyMap) image"),
.type = AVMEDIA_TYPE_VIDEO,
.id = AV_CODEC_ID_PAM,
- .priv_data_size = sizeof(PNMContext),
+ .init = pam_encode_init,
+ .close = pam_encode_close,
.encode2 = pam_encode_frame,
.pix_fmts = (const enum AVPixelFormat[]){
AV_PIX_FMT_RGB24, AV_PIX_FMT_RGBA, AV_PIX_FMT_RGB48BE, AV_PIX_FMT_RGBA64BE, AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY8A, AV_PIX_FMT_GRAY16BE, AV_PIX_FMT_MONOBLACK, AV_PIX_FMT_NONE
diff --git a/libavcodec/parser.c b/libavcodec/parser.c
index 8a82593..083ce02 100644
--- a/libavcodec/parser.c
+++ b/libavcodec/parser.c
@@ -20,6 +20,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <stdint.h>
#include <string.h>
#include "parser.h"
diff --git a/libavcodec/pcm-dvd.c b/libavcodec/pcm-dvd.c
index 9696b09..77da8bf 100644
--- a/libavcodec/pcm-dvd.c
+++ b/libavcodec/pcm-dvd.c
@@ -173,6 +173,17 @@
#endif
return dst16;
case 20:
+ if (avctx->channels == 1) {
+ do {
+ for (i = 2; i; i--) {
+ dst32[0] = bytestream2_get_be16u(&gb) << 16;
+ dst32[1] = bytestream2_get_be16u(&gb) << 16;
+ t = bytestream2_get_byteu(&gb);
+ *dst32++ += (t & 0xf0) << 8;
+ *dst32++ += (t & 0x0f) << 12;
+ }
+ } while (--blocks);
+ } else {
do {
for (i = s->groups_per_block; i; i--) {
dst32[0] = bytestream2_get_be16u(&gb) << 16;
@@ -180,15 +191,26 @@
dst32[2] = bytestream2_get_be16u(&gb) << 16;
dst32[3] = bytestream2_get_be16u(&gb) << 16;
t = bytestream2_get_byteu(&gb);
- *dst32 += (t & 0xf0) << 8;
- *dst32 += (t & 0x0f) << 12;
+ *dst32++ += (t & 0xf0) << 8;
+ *dst32++ += (t & 0x0f) << 12;
t = bytestream2_get_byteu(&gb);
- *dst32 += (t & 0xf0) << 8;
- *dst32 += (t & 0x0f) << 12;
+ *dst32++ += (t & 0xf0) << 8;
+ *dst32++ += (t & 0x0f) << 12;
}
} while (--blocks);
+ }
return dst32;
case 24:
+ if (avctx->channels == 1) {
+ do {
+ for (i = 2; i; i--) {
+ dst32[0] = bytestream2_get_be16u(&gb) << 16;
+ dst32[1] = bytestream2_get_be16u(&gb) << 16;
+ *dst32++ += bytestream2_get_byteu(&gb) << 8;
+ *dst32++ += bytestream2_get_byteu(&gb) << 8;
+ }
+ } while (--blocks);
+ } else {
do {
for (i = s->groups_per_block; i; i--) {
dst32[0] = bytestream2_get_be16u(&gb) << 16;
@@ -201,6 +223,7 @@
*dst32++ += bytestream2_get_byteu(&gb) << 8;
}
} while (--blocks);
+ }
return dst32;
default:
return NULL;
@@ -225,8 +248,8 @@
if ((retval = pcm_dvd_parse_header(avctx, src)))
return retval;
- if (s->last_block_size != s->block_size) {
- av_log(avctx, AV_LOG_WARNING, "block_size has changed\n");
+ if (s->last_block_size && s->last_block_size != s->block_size) {
+ av_log(avctx, AV_LOG_WARNING, "block_size has changed %d != %d\n", s->last_block_size, s->block_size);
s->extra_sample_count = 0;
}
s->last_block_size = s->block_size;
diff --git a/libavcodec/pcx.c b/libavcodec/pcx.c
index 66b1a35..6487aa5 100644
--- a/libavcodec/pcx.c
+++ b/libavcodec/pcx.c
@@ -132,10 +132,9 @@
bytestream2_skipu(&gb, 60);
- if ((ret = av_image_check_size(w, h, 0, avctx)) < 0)
+ if ((ret = ff_set_dimensions(avctx, w, h)) < 0)
return ret;
- if (w != avctx->width || h != avctx->height)
- avcodec_set_dimensions(avctx, w, h);
+
if ((ret = ff_get_buffer(avctx, p, 0)) < 0)
return ret;
diff --git a/libavcodec/pcxenc.c b/libavcodec/pcxenc.c
index fa45888..f48063b 100644
--- a/libavcodec/pcxenc.c
+++ b/libavcodec/pcxenc.c
@@ -33,6 +33,24 @@
static const uint32_t monoblack_pal[16] = { 0x000000, 0xFFFFFF };
+static av_cold int pcx_encode_init(AVCodecContext *avctx)
+{
+ avctx->coded_frame = av_frame_alloc();
+ if (!avctx->coded_frame)
+ return AVERROR(ENOMEM);
+
+ avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
+ avctx->coded_frame->key_frame = 1;
+
+ return 0;
+}
+
+static av_cold int pcx_encode_close(AVCodecContext *avctx)
+{
+ av_frame_free(&avctx->coded_frame);
+ return 0;
+}
+
/**
* PCX run-length encoder
* @param dst output buffer
@@ -86,7 +104,6 @@
static int pcx_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
const AVFrame *frame, int *got_packet)
{
- AVFrame *const pict = (AVFrame *) frame;
const uint8_t *buf_end;
uint8_t *buf;
@@ -95,9 +112,6 @@
uint32_t palette256[256];
const uint8_t *src;
- pict->pict_type = AV_PICTURE_TYPE_I;
- pict->key_frame = 1;
-
if (avctx->width > 65535 || avctx->height > 65535) {
av_log(avctx, AV_LOG_ERROR, "image dimensions do not fit in 16 bits\n");
return -1;
@@ -121,7 +135,7 @@
case AV_PIX_FMT_PAL8:
bpp = 8;
nplanes = 1;
- pal = (uint32_t *)pict->data[1];
+ pal = (uint32_t *)frame->data[1];
break;
case AV_PIX_FMT_MONOBLACK:
bpp = 1;
@@ -166,7 +180,7 @@
while (buf - pkt->data < 128)
*buf++= 0;
- src = pict->data[0];
+ src = frame->data[0];
for (y = 0; y < avctx->height; y++) {
if ((written = pcx_rle_encode(buf, buf_end - buf,
@@ -175,7 +189,7 @@
return -1;
}
buf += written;
- src += pict->linesize[0];
+ src += frame->linesize[0];
}
if (nplanes == 1 && bpp == 8) {
@@ -201,6 +215,8 @@
.long_name = NULL_IF_CONFIG_SMALL("PC Paintbrush PCX image"),
.type = AVMEDIA_TYPE_VIDEO,
.id = AV_CODEC_ID_PCX,
+ .init = pcx_encode_init,
+ .close = pcx_encode_close,
.encode2 = pcx_encode_frame,
.pix_fmts = (const enum AVPixelFormat[]){
AV_PIX_FMT_RGB24,
diff --git a/libavcodec/pgssubdec.c b/libavcodec/pgssubdec.c
index 4de83f3..f45f0bf 100644
--- a/libavcodec/pgssubdec.c
+++ b/libavcodec/pgssubdec.c
@@ -27,6 +27,8 @@
#include "avcodec.h"
#include "dsputil.h"
#include "bytestream.h"
+#include "internal.h"
+
#include "libavutil/colorspace.h"
#include "libavutil/imgutils.h"
#include "libavutil/opt.h"
@@ -294,11 +296,12 @@
* @param buf_size size of packet to process
* @todo TODO: Implement cropping
*/
-static void parse_presentation_segment(AVCodecContext *avctx,
- const uint8_t *buf, int buf_size,
- int64_t pts)
+static int parse_presentation_segment(AVCodecContext *avctx,
+ const uint8_t *buf, int buf_size,
+ int64_t pts)
{
PGSSubContext *ctx = avctx->priv_data;
+ int ret;
int w = bytestream_get_be16(&buf);
int h = bytestream_get_be16(&buf);
@@ -309,8 +312,9 @@
av_dlog(avctx, "Video Dimensions %dx%d\n",
w, h);
- if (av_image_check_size(w, h, 0, avctx) >= 0)
- avcodec_set_dimensions(avctx, w, h);
+ ret = ff_set_dimensions(avctx, w, h);
+ if (ret < 0)
+ return ret;
/* Skip 1 bytes of unknown, frame rate? */
buf++;
@@ -327,20 +331,20 @@
ctx->presentation.object_count = bytestream_get_byte(&buf);
if (!ctx->presentation.object_count)
- return;
+ return 0;
/* Verify that enough bytes are remaining for all of the objects. */
buf_size -= 11;
if (buf_size < ctx->presentation.object_count * 8) {
ctx->presentation.object_count = 0;
- return;
+ return AVERROR_INVALIDDATA;
}
av_freep(&ctx->presentation.objects);
ctx->presentation.objects = av_malloc(sizeof(PGSSubPictureReference) * ctx->presentation.object_count);
if (!ctx->presentation.objects) {
ctx->presentation.object_count = 0;
- return;
+ return AVERROR(ENOMEM);
}
for (object_index = 0; object_index < ctx->presentation.object_count; ++object_index) {
@@ -365,6 +369,8 @@
reference->y = 0;
}
}
+
+ return 0;
}
/**
@@ -456,7 +462,7 @@
const uint8_t *buf_end;
uint8_t segment_type;
int segment_length;
- int i;
+ int i, ret;
av_dlog(avctx, "PGS sub packet:\n");
@@ -495,7 +501,9 @@
parse_picture_segment(avctx, buf, segment_length);
break;
case PRESENTATION_SEGMENT:
- parse_presentation_segment(avctx, buf, segment_length, sub->pts);
+ ret = parse_presentation_segment(avctx, buf, segment_length, sub->pts);
+ if (ret < 0)
+ return ret;
break;
case WINDOW_SEGMENT:
/*
diff --git a/libavcodec/pictordec.c b/libavcodec/pictordec.c
index 5b528f5..1bc51bc 100644
--- a/libavcodec/pictordec.c
+++ b/libavcodec/pictordec.c
@@ -143,7 +143,9 @@
if (av_image_check_size(s->width, s->height, 0, avctx) < 0)
return -1;
if (s->width != avctx->width && s->height != avctx->height) {
- avcodec_set_dimensions(avctx, s->width, s->height);
+ ret = ff_set_dimensions(avctx, s->width, s->height);
+ if (ret < 0)
+ return ret;
}
if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
diff --git a/libavcodec/pngenc.c b/libavcodec/pngenc.c
index 58acc3c..bf61be1 100644
--- a/libavcodec/pngenc.c
+++ b/libavcodec/pngenc.c
@@ -38,7 +38,6 @@
uint8_t *bytestream;
uint8_t *bytestream_start;
uint8_t *bytestream_end;
- AVFrame picture;
int filter_type;
@@ -218,7 +217,7 @@
const AVFrame *pict, int *got_packet)
{
PNGEncContext *s = avctx->priv_data;
- AVFrame * const p= &s->picture;
+ const AVFrame * const p = pict;
int bit_depth, color_type, y, len, row_size, ret, is_progressive;
int bits_per_pixel, pass_row_size, enc_row_size;
int64_t max_packet_size;
@@ -228,10 +227,6 @@
uint8_t *progressive_buf = NULL;
uint8_t *top_buf = NULL;
- *p = *pict;
- p->pict_type= AV_PICTURE_TYPE_I;
- p->key_frame= 1;
-
is_progressive = !!(avctx->flags & CODEC_FLAG_INTERLACED_DCT);
switch(avctx->pix_fmt) {
case AV_PIX_FMT_RGBA64BE:
@@ -454,8 +449,13 @@
avctx->bits_per_coded_sample = 8;
}
- avcodec_get_frame_defaults(&s->picture);
- avctx->coded_frame= &s->picture;
+ avctx->coded_frame = av_frame_alloc();
+ if (!avctx->coded_frame)
+ return AVERROR(ENOMEM);
+
+ avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
+ avctx->coded_frame->key_frame = 1;
+
ff_dsputil_init(&s->dsp, avctx);
s->filter_type = av_clip(avctx->prediction_method, PNG_FILTER_VALUE_NONE, PNG_FILTER_VALUE_MIXED);
@@ -472,6 +472,12 @@
return 0;
}
+static av_cold int png_enc_close(AVCodecContext *avctx)
+{
+ av_frame_free(&avctx->coded_frame);
+ return 0;
+}
+
#define OFFSET(x) offsetof(PNGEncContext, x)
#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
static const AVOption options[] = {
@@ -494,6 +500,7 @@
.id = AV_CODEC_ID_PNG,
.priv_data_size = sizeof(PNGEncContext),
.init = png_enc_init,
+ .close = png_enc_close,
.encode2 = encode_frame,
.capabilities = CODEC_CAP_FRAME_THREADS | CODEC_CAP_INTRA_ONLY,
.pix_fmts = (const enum AVPixelFormat[]){
diff --git a/libavcodec/pnmenc.c b/libavcodec/pnmenc.c
index 9b2824a..e6c3635 100644
--- a/libavcodec/pnmenc.c
+++ b/libavcodec/pnmenc.c
@@ -22,13 +22,11 @@
#include "libavutil/pixdesc.h"
#include "avcodec.h"
#include "internal.h"
-#include "pnm.h"
-
static int pnm_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
const AVFrame *p, int *got_packet)
{
- PNMContext *s = avctx->priv_data;
+ uint8_t *bytestream, *bytestream_start, *bytestream_end;
int i, h, h1, c, n, linesize, ret;
uint8_t *ptr, *ptr1, *ptr2;
@@ -37,9 +35,9 @@
avctx->height) + 200)) < 0)
return ret;
- s->bytestream_start =
- s->bytestream = pkt->data;
- s->bytestream_end = pkt->data + pkt->size;
+ bytestream_start =
+ bytestream = pkt->data;
+ bytestream_end = pkt->data + pkt->size;
h = avctx->height;
h1 = h;
@@ -81,22 +79,22 @@
default:
return -1;
}
- snprintf(s->bytestream, s->bytestream_end - s->bytestream,
+ snprintf(bytestream, bytestream_end - bytestream,
"P%c\n%d %d\n", c, avctx->width, h1);
- s->bytestream += strlen(s->bytestream);
+ bytestream += strlen(bytestream);
if (avctx->pix_fmt != AV_PIX_FMT_MONOWHITE) {
int maxdepth = (1 << (av_pix_fmt_desc_get(avctx->pix_fmt)->comp[0].depth_minus1 + 1)) - 1;
- snprintf(s->bytestream, s->bytestream_end - s->bytestream,
+ snprintf(bytestream, bytestream_end - bytestream,
"%d\n", maxdepth);
- s->bytestream += strlen(s->bytestream);
+ bytestream += strlen(bytestream);
}
ptr = p->data[0];
linesize = p->linesize[0];
for (i = 0; i < h; i++) {
- memcpy(s->bytestream, ptr, n);
- s->bytestream += n;
- ptr += linesize;
+ memcpy(bytestream, ptr, n);
+ bytestream += n;
+ ptr += linesize;
}
if (avctx->pix_fmt == AV_PIX_FMT_YUV420P || avctx->pix_fmt == AV_PIX_FMT_YUV420P16BE) {
@@ -105,21 +103,38 @@
ptr1 = p->data[1];
ptr2 = p->data[2];
for (i = 0; i < h; i++) {
- memcpy(s->bytestream, ptr1, n);
- s->bytestream += n;
- memcpy(s->bytestream, ptr2, n);
- s->bytestream += n;
+ memcpy(bytestream, ptr1, n);
+ bytestream += n;
+ memcpy(bytestream, ptr2, n);
+ bytestream += n;
ptr1 += p->linesize[1];
ptr2 += p->linesize[2];
}
}
- pkt->size = s->bytestream - s->bytestream_start;
+ pkt->size = bytestream - bytestream_start;
pkt->flags |= AV_PKT_FLAG_KEY;
*got_packet = 1;
return 0;
}
+static av_cold int pnm_encode_init(AVCodecContext *avctx)
+{
+ avctx->coded_frame = av_frame_alloc();
+ if (!avctx->coded_frame)
+ return AVERROR(ENOMEM);
+
+ avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
+ avctx->coded_frame->key_frame = 1;
+
+ return 0;
+}
+
+static av_cold int pnm_encode_close(AVCodecContext *avctx)
+{
+ av_frame_free(&avctx->coded_frame);
+ return 0;
+}
#if CONFIG_PGM_ENCODER
AVCodec ff_pgm_encoder = {
@@ -127,7 +142,8 @@
.long_name = NULL_IF_CONFIG_SMALL("PGM (Portable GrayMap) image"),
.type = AVMEDIA_TYPE_VIDEO,
.id = AV_CODEC_ID_PGM,
- .priv_data_size = sizeof(PNMContext),
+ .init = pnm_encode_init,
+ .close = pnm_encode_close,
.encode2 = pnm_encode_frame,
.pix_fmts = (const enum AVPixelFormat[]){
AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY16BE, AV_PIX_FMT_NONE
@@ -141,7 +157,8 @@
.long_name = NULL_IF_CONFIG_SMALL("PGMYUV (Portable GrayMap YUV) image"),
.type = AVMEDIA_TYPE_VIDEO,
.id = AV_CODEC_ID_PGMYUV,
- .priv_data_size = sizeof(PNMContext),
+ .init = pnm_encode_init,
+ .close = pnm_encode_close,
.encode2 = pnm_encode_frame,
.pix_fmts = (const enum AVPixelFormat[]){
AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV420P16BE, AV_PIX_FMT_NONE
@@ -155,7 +172,8 @@
.long_name = NULL_IF_CONFIG_SMALL("PPM (Portable PixelMap) image"),
.type = AVMEDIA_TYPE_VIDEO,
.id = AV_CODEC_ID_PPM,
- .priv_data_size = sizeof(PNMContext),
+ .init = pnm_encode_init,
+ .close = pnm_encode_close,
.encode2 = pnm_encode_frame,
.pix_fmts = (const enum AVPixelFormat[]){
AV_PIX_FMT_RGB24, AV_PIX_FMT_RGB48BE, AV_PIX_FMT_NONE
@@ -169,7 +187,8 @@
.long_name = NULL_IF_CONFIG_SMALL("PBM (Portable BitMap) image"),
.type = AVMEDIA_TYPE_VIDEO,
.id = AV_CODEC_ID_PBM,
- .priv_data_size = sizeof(PNMContext),
+ .init = pnm_encode_init,
+ .close = pnm_encode_close,
.encode2 = pnm_encode_frame,
.pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_MONOWHITE,
AV_PIX_FMT_NONE },
diff --git a/libavcodec/ppc/gmc_altivec.c b/libavcodec/ppc/gmc_altivec.c
index 4db761d..45d850a 100644
--- a/libavcodec/ppc/gmc_altivec.c
+++ b/libavcodec/ppc/gmc_altivec.c
@@ -66,7 +66,7 @@
srcvA = vec_perm(src_0, src_1, vec_lvsl(0, src));
if (src_really_odd != 0x0000000F) {
- // if src & 0xF == 0xF, then (src+1) is properly aligned
+ // if (src & 0xF) == 0xF, then (src+1) is properly aligned
// on the second vector.
srcvB = vec_perm(src_0, src_1, vec_lvsl(1, src));
} else {
@@ -90,7 +90,7 @@
srcvC = vec_perm(src_0, src_1, vec_lvsl(stride + 0, src));
if (src_really_odd != 0x0000000F) {
- // if src & 0xF == 0xF, then (src+1) is properly aligned
+ // if (src & 0xF) == 0xF, then (src+1) is properly aligned
// on the second vector.
srcvD = vec_perm(src_0, src_1, vec_lvsl(stride + 1, src));
} else {
diff --git a/libavcodec/proresenc_anatoliy.c b/libavcodec/proresenc_anatoliy.c
index e124b41..80ce135 100644
--- a/libavcodec/proresenc_anatoliy.c
+++ b/libavcodec/proresenc_anatoliy.c
@@ -581,7 +581,7 @@
scale_mat(QMAT_CHROMA[avctx->profile], ctx->qmat_chroma[i - 1], i);
}
- avctx->coded_frame = avcodec_alloc_frame();
+ avctx->coded_frame = av_frame_alloc();
avctx->coded_frame->key_frame = 1;
avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
diff --git a/libavcodec/proresenc_kostya.c b/libavcodec/proresenc_kostya.c
index 510b408..71c2cb4 100644
--- a/libavcodec/proresenc_kostya.c
+++ b/libavcodec/proresenc_kostya.c
@@ -1073,7 +1073,7 @@
int interlaced = !!(avctx->flags & CODEC_FLAG_INTERLACED_DCT);
avctx->bits_per_raw_sample = 10;
- avctx->coded_frame = avcodec_alloc_frame();
+ avctx->coded_frame = av_frame_alloc();
if (!avctx->coded_frame)
return AVERROR(ENOMEM);
diff --git a/libavcodec/pthread.c b/libavcodec/pthread.c
index 8329155..407ca2e 100644
--- a/libavcodec/pthread.c
+++ b/libavcodec/pthread.c
@@ -29,1046 +29,10 @@
* @see doc/multithreading.txt
*/
-#include "config.h"
-
#include "avcodec.h"
#include "internal.h"
+#include "pthread_internal.h"
#include "thread.h"
-#include "libavutil/avassert.h"
-#include "libavutil/common.h"
-#include "libavutil/cpu.h"
-#include "libavutil/internal.h"
-
-#if HAVE_PTHREADS
-#include <pthread.h>
-#elif HAVE_W32THREADS
-#include "compat/w32pthreads.h"
-#elif HAVE_OS2THREADS
-#include "compat/os2threads.h"
-#endif
-
-typedef int (action_func)(AVCodecContext *c, void *arg);
-typedef int (action_func2)(AVCodecContext *c, void *arg, int jobnr, int threadnr);
-
-typedef struct ThreadContext {
- pthread_t *workers;
- action_func *func;
- action_func2 *func2;
- void *args;
- int *rets;
- int rets_count;
- int job_count;
- int job_size;
-
- pthread_cond_t last_job_cond;
- pthread_cond_t current_job_cond;
- pthread_mutex_t current_job_lock;
- int current_job;
- unsigned int current_execute;
- int done;
-} ThreadContext;
-
-/**
- * Context used by codec threads and stored in their AVCodecContext thread_opaque.
- */
-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.
-
- pthread_mutex_t mutex; ///< Mutex used to protect the contents of the PerThreadContext.
- pthread_mutex_t progress_mutex; ///< Mutex used to protect frame progress values and progress_cond.
-
- AVCodecContext *avctx; ///< Context used to decode packets passed to this thread.
-
- AVPacket avpkt; ///< Input packet (for decoding) or output (for encoding).
- uint8_t *buf; ///< backup storage for packet data when the input packet is not refcounted
- int allocated_buf_size; ///< Size allocated for buf
-
- AVFrame frame; ///< Output frame (for decoding) or input (for encoding).
- int got_frame; ///< The output of got_picture_ptr from the last avcodec_decode_video() call.
- int result; ///< The result of the last codec decode/encode() call.
-
- enum {
- STATE_INPUT_READY, ///< Set when the thread is awaiting a packet.
- STATE_SETTING_UP, ///< Set before the codec has called ff_thread_finish_setup().
- STATE_GET_BUFFER, /**<
- * Set when the codec calls get_buffer().
- * State is returned to STATE_SETTING_UP afterwards.
- */
- STATE_GET_FORMAT, /**<
- * Set when the codec calls get_format().
- * State is returned to STATE_SETTING_UP afterwards.
- */
- STATE_SETUP_FINISHED ///< Set after the codec has called ff_thread_finish_setup().
- } state;
-
- /**
- * Array of frames passed to ff_thread_release_buffer().
- * Frames are released after all threads referencing them are finished.
- */
- AVFrame *released_buffers;
- int num_released_buffers;
- int released_buffers_allocated;
-
- AVFrame *requested_frame; ///< AVFrame the codec passed to get_buffer()
- int requested_flags; ///< flags passed to get_buffer() for requested_frame
-
- const enum AVPixelFormat *available_formats; ///< Format array for get_format()
- enum AVPixelFormat result_format; ///< get_format() result
-} PerThreadContext;
-
-/**
- * Context stored in the client AVCodecContext thread_opaque.
- */
-typedef struct FrameThreadContext {
- PerThreadContext *threads; ///< The contexts for each thread.
- PerThreadContext *prev_thread; ///< The last thread submit_packet() was called on.
-
- pthread_mutex_t buffer_mutex; ///< Mutex used to protect get/release_buffer().
-
- int next_decoding; ///< The next context to submit a packet to.
- int next_finished; ///< The next context to return output from.
-
- int delaying; /**<
- * Set for the first N packets, where N is the number of threads.
- * While it is set, ff_thread_en/decode_frame won't return any results.
- */
-
- 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 void* attribute_align_arg worker(void *v)
-{
- AVCodecContext *avctx = v;
- ThreadContext *c = avctx->thread_opaque;
- int our_job = c->job_count;
- int last_execute = 0;
- int thread_count = avctx->thread_count;
- int self_id;
-
- pthread_mutex_lock(&c->current_job_lock);
- self_id = c->current_job++;
- for (;;){
- while (our_job >= c->job_count) {
- if (c->current_job == thread_count + c->job_count)
- pthread_cond_signal(&c->last_job_cond);
-
- while (last_execute == c->current_execute && !c->done)
- pthread_cond_wait(&c->current_job_cond, &c->current_job_lock);
- last_execute = c->current_execute;
- our_job = self_id;
-
- if (c->done) {
- pthread_mutex_unlock(&c->current_job_lock);
- return NULL;
- }
- }
- pthread_mutex_unlock(&c->current_job_lock);
-
- c->rets[our_job%c->rets_count] = c->func ? c->func(avctx, (char*)c->args + our_job*c->job_size):
- c->func2(avctx, c->args, our_job, self_id);
-
- pthread_mutex_lock(&c->current_job_lock);
- our_job = c->current_job++;
- }
-}
-
-static av_always_inline void avcodec_thread_park_workers(ThreadContext *c, int thread_count)
-{
- while (c->current_job != thread_count + c->job_count)
- pthread_cond_wait(&c->last_job_cond, &c->current_job_lock);
- pthread_mutex_unlock(&c->current_job_lock);
-}
-
-static void thread_free(AVCodecContext *avctx)
-{
- ThreadContext *c = avctx->thread_opaque;
- int i;
-
- pthread_mutex_lock(&c->current_job_lock);
- c->done = 1;
- pthread_cond_broadcast(&c->current_job_cond);
- pthread_mutex_unlock(&c->current_job_lock);
-
- for (i=0; i<avctx->thread_count; i++)
- pthread_join(c->workers[i], NULL);
-
- pthread_mutex_destroy(&c->current_job_lock);
- pthread_cond_destroy(&c->current_job_cond);
- pthread_cond_destroy(&c->last_job_cond);
- av_free(c->workers);
- av_freep(&avctx->thread_opaque);
-}
-
-static int avcodec_thread_execute(AVCodecContext *avctx, action_func* func, void *arg, int *ret, int job_count, int job_size)
-{
- ThreadContext *c= avctx->thread_opaque;
- int dummy_ret;
-
- if (!(avctx->active_thread_type&FF_THREAD_SLICE) || avctx->thread_count <= 1)
- return avcodec_default_execute(avctx, func, arg, ret, job_count, job_size);
-
- if (job_count <= 0)
- return 0;
-
- pthread_mutex_lock(&c->current_job_lock);
-
- c->current_job = avctx->thread_count;
- c->job_count = job_count;
- c->job_size = job_size;
- c->args = arg;
- c->func = func;
- if (ret) {
- c->rets = ret;
- c->rets_count = job_count;
- } else {
- c->rets = &dummy_ret;
- c->rets_count = 1;
- }
- c->current_execute++;
- pthread_cond_broadcast(&c->current_job_cond);
-
- avcodec_thread_park_workers(c, avctx->thread_count);
-
- return 0;
-}
-
-static int avcodec_thread_execute2(AVCodecContext *avctx, action_func2* func2, void *arg, int *ret, int job_count)
-{
- ThreadContext *c= avctx->thread_opaque;
- c->func2 = func2;
- return avcodec_thread_execute(avctx, NULL, arg, ret, job_count, 0);
-}
-
-static int thread_init_internal(AVCodecContext *avctx)
-{
- int i;
- ThreadContext *c;
- int thread_count = avctx->thread_count;
-
- if (!thread_count) {
- int nb_cpus = av_cpu_count();
- if (avctx->height)
- nb_cpus = FFMIN(nb_cpus, (avctx->height+15)/16);
- // use number of cores + 1 as thread count if there is more than one
- if (nb_cpus > 1)
- thread_count = avctx->thread_count = FFMIN(nb_cpus + 1, MAX_AUTO_THREADS);
- else
- thread_count = avctx->thread_count = 1;
- }
-
- if (thread_count <= 1) {
- avctx->active_thread_type = 0;
- return 0;
- }
-
- c = av_mallocz(sizeof(ThreadContext));
- if (!c)
- return -1;
-
- c->workers = av_mallocz(sizeof(pthread_t)*thread_count);
- if (!c->workers) {
- av_free(c);
- return -1;
- }
-
- avctx->thread_opaque = c;
- c->current_job = 0;
- c->job_count = 0;
- c->job_size = 0;
- c->done = 0;
- pthread_cond_init(&c->current_job_cond, NULL);
- pthread_cond_init(&c->last_job_cond, NULL);
- pthread_mutex_init(&c->current_job_lock, NULL);
- pthread_mutex_lock(&c->current_job_lock);
- for (i=0; i<thread_count; i++) {
- if(pthread_create(&c->workers[i], NULL, worker, avctx)) {
- avctx->thread_count = i;
- pthread_mutex_unlock(&c->current_job_lock);
- ff_thread_free(avctx);
- return -1;
- }
- }
-
- avcodec_thread_park_workers(c, thread_count);
-
- avctx->execute = avcodec_thread_execute;
- avctx->execute2 = avcodec_thread_execute2;
- return 0;
-}
-
-#define THREAD_SAFE_CALLBACKS(avctx) \
-((avctx)->thread_safe_callbacks || (!(avctx)->get_buffer && (avctx)->get_buffer2 == avcodec_default_get_buffer2))
-
-/**
- * Codec worker thread.
- *
- * Automatically calls ff_thread_finish_setup() if the codec does
- * not provide an update_thread_context method, or if the codec returns
- * before calling it.
- */
-static attribute_align_arg void *frame_worker_thread(void *arg)
-{
- PerThreadContext *p = arg;
- FrameThreadContext *fctx = p->parent;
- AVCodecContext *avctx = p->avctx;
- const AVCodec *codec = avctx->codec;
-
- pthread_mutex_lock(&p->mutex);
- while (1) {
- while (p->state == STATE_INPUT_READY && !fctx->die)
- pthread_cond_wait(&p->input_cond, &p->mutex);
-
- if (fctx->die) break;
-
- if (!codec->update_thread_context && THREAD_SAFE_CALLBACKS(avctx))
- ff_thread_finish_setup(avctx);
-
- avcodec_get_frame_defaults(&p->frame);
- p->got_frame = 0;
- p->result = codec->decode(avctx, &p->frame, &p->got_frame, &p->avpkt);
-
- /* many decoders assign whole AVFrames, thus overwriting extended_data;
- * make sure it's set correctly */
- p->frame.extended_data = p->frame.data;
-
- if (p->state == STATE_SETTING_UP) ff_thread_finish_setup(avctx);
-
- pthread_mutex_lock(&p->progress_mutex);
-#if 0 //BUFREF-FIXME
- for (i = 0; i < MAX_BUFFERS; i++)
- if (p->progress_used[i] && (p->got_frame || p->result<0 || avctx->codec_id != AV_CODEC_ID_H264)) {
- p->progress[i][0] = INT_MAX;
- p->progress[i][1] = INT_MAX;
- }
-#endif
- p->state = STATE_INPUT_READY;
-
- pthread_cond_broadcast(&p->progress_cond);
- pthread_cond_signal(&p->output_cond);
- pthread_mutex_unlock(&p->progress_mutex);
- }
- pthread_mutex_unlock(&p->mutex);
-
- return NULL;
-}
-
-/**
- * Update the next thread's AVCodecContext with values from the reference thread's context.
- *
- * @param dst The destination context.
- * @param src The source context.
- * @param for_user 0 if the destination is a codec thread, 1 if the destination is the user's thread
- */
-static int update_context_from_thread(AVCodecContext *dst, AVCodecContext *src, int for_user)
-{
- int err = 0;
-
- if (dst != src) {
- dst->time_base = src->time_base;
- dst->width = src->width;
- 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->bits_per_coded_sample = src->bits_per_coded_sample;
- dst->sample_aspect_ratio = src->sample_aspect_ratio;
- dst->dtg_active_format = src->dtg_active_format;
-
- dst->profile = src->profile;
- dst->level = src->level;
-
- dst->bits_per_raw_sample = src->bits_per_raw_sample;
- dst->ticks_per_frame = src->ticks_per_frame;
- dst->color_primaries = src->color_primaries;
-
- dst->color_trc = src->color_trc;
- dst->colorspace = src->colorspace;
- dst->color_range = src->color_range;
- dst->chroma_sample_location = src->chroma_sample_location;
-
- dst->hwaccel = src->hwaccel;
- dst->hwaccel_context = src->hwaccel_context;
-
- dst->channels = src->channels;
- dst->sample_rate = src->sample_rate;
- dst->sample_fmt = src->sample_fmt;
- dst->channel_layout = src->channel_layout;
- }
-
- if (for_user) {
- dst->delay = 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);
- }
-
- return err;
-}
-
-/**
- * Update the next thread's AVCodecContext with values set by the user.
- *
- * @param dst The destination context.
- * @param src The source context.
- * @return 0 on success, negative error code on failure
- */
-static int update_context_from_user(AVCodecContext *dst, AVCodecContext *src)
-{
-#define copy_fields(s, e) memcpy(&dst->s, &src->s, (char*)&dst->e - (char*)&dst->s);
- dst->flags = src->flags;
-
- dst->draw_horiz_band= src->draw_horiz_band;
- dst->get_buffer2 = src->get_buffer2;
-#if FF_API_GET_BUFFER
-FF_DISABLE_DEPRECATION_WARNINGS
- dst->get_buffer = src->get_buffer;
- dst->release_buffer = src->release_buffer;
-FF_ENABLE_DEPRECATION_WARNINGS
-#endif
-
- dst->opaque = src->opaque;
- dst->debug = src->debug;
- dst->debug_mv = src->debug_mv;
-
- dst->slice_flags = src->slice_flags;
- dst->flags2 = src->flags2;
-
- copy_fields(skip_loop_filter, subtitle_header);
-
- dst->frame_number = src->frame_number;
- dst->reordered_opaque = src->reordered_opaque;
- dst->thread_safe_callbacks = src->thread_safe_callbacks;
-
- if (src->slice_count && src->slice_offset) {
- if (dst->slice_count < src->slice_count) {
- int *tmp = av_realloc(dst->slice_offset, src->slice_count *
- sizeof(*dst->slice_offset));
- if (!tmp) {
- av_free(dst->slice_offset);
- return AVERROR(ENOMEM);
- }
- dst->slice_offset = tmp;
- }
- memcpy(dst->slice_offset, src->slice_offset,
- src->slice_count * sizeof(*dst->slice_offset));
- }
- dst->slice_count = src->slice_count;
- return 0;
-#undef copy_fields
-}
-
-/// Releases the buffers that this decoding thread was the last user of.
-static void release_delayed_buffers(PerThreadContext *p)
-{
- FrameThreadContext *fctx = p->parent;
-
- while (p->num_released_buffers > 0) {
- AVFrame *f;
-
- pthread_mutex_lock(&fctx->buffer_mutex);
-
- // fix extended data in case the caller screwed it up
- av_assert0(p->avctx->codec_type == AVMEDIA_TYPE_VIDEO ||
- p->avctx->codec_type == AVMEDIA_TYPE_AUDIO);
- f = &p->released_buffers[--p->num_released_buffers];
- f->extended_data = f->data;
- av_frame_unref(f);
-
- pthread_mutex_unlock(&fctx->buffer_mutex);
- }
-}
-
-static int submit_packet(PerThreadContext *p, AVPacket *avpkt)
-{
- FrameThreadContext *fctx = p->parent;
- PerThreadContext *prev_thread = fctx->prev_thread;
- const AVCodec *codec = p->avctx->codec;
-
- if (!avpkt->size && !(codec->capabilities & CODEC_CAP_DELAY)) return 0;
-
- pthread_mutex_lock(&p->mutex);
-
- release_delayed_buffers(p);
-
- if (prev_thread) {
- int err;
- if (prev_thread->state == STATE_SETTING_UP) {
- pthread_mutex_lock(&prev_thread->progress_mutex);
- while (prev_thread->state == STATE_SETTING_UP)
- pthread_cond_wait(&prev_thread->progress_cond, &prev_thread->progress_mutex);
- pthread_mutex_unlock(&prev_thread->progress_mutex);
- }
-
- err = update_context_from_thread(p->avctx, prev_thread->avctx, 0);
- if (err) {
- pthread_mutex_unlock(&p->mutex);
- return err;
- }
- }
-
- av_buffer_unref(&p->avpkt.buf);
- p->avpkt = *avpkt;
- if (avpkt->buf)
- p->avpkt.buf = av_buffer_ref(avpkt->buf);
- else {
- av_fast_malloc(&p->buf, &p->allocated_buf_size, avpkt->size + FF_INPUT_BUFFER_PADDING_SIZE);
- p->avpkt.data = p->buf;
- memcpy(p->buf, avpkt->data, avpkt->size);
- memset(p->buf + avpkt->size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
- }
-
- p->state = STATE_SETTING_UP;
- pthread_cond_signal(&p->input_cond);
- pthread_mutex_unlock(&p->mutex);
-
- /*
- * If the client doesn't have a thread-safe get_buffer(),
- * then decoding threads call back to the main thread,
- * and it calls back to the client here.
- */
-
-FF_DISABLE_DEPRECATION_WARNINGS
- if (!p->avctx->thread_safe_callbacks && (
- p->avctx->get_format != avcodec_default_get_format ||
-#if FF_API_GET_BUFFER
- p->avctx->get_buffer ||
-#endif
- p->avctx->get_buffer2 != avcodec_default_get_buffer2)) {
-FF_ENABLE_DEPRECATION_WARNINGS
- while (p->state != STATE_SETUP_FINISHED && p->state != STATE_INPUT_READY) {
- int call_done = 1;
- pthread_mutex_lock(&p->progress_mutex);
- while (p->state == STATE_SETTING_UP)
- pthread_cond_wait(&p->progress_cond, &p->progress_mutex);
-
- switch (p->state) {
- case STATE_GET_BUFFER:
- p->result = ff_get_buffer(p->avctx, p->requested_frame, p->requested_flags);
- break;
- case STATE_GET_FORMAT:
- p->result_format = p->avctx->get_format(p->avctx, p->available_formats);
- break;
- default:
- call_done = 0;
- break;
- }
- if (call_done) {
- p->state = STATE_SETTING_UP;
- pthread_cond_signal(&p->progress_cond);
- }
- pthread_mutex_unlock(&p->progress_mutex);
- }
- }
-
- fctx->prev_thread = p;
- fctx->next_decoding++;
-
- return 0;
-}
-
-int ff_thread_decode_frame(AVCodecContext *avctx,
- AVFrame *picture, int *got_picture_ptr,
- AVPacket *avpkt)
-{
- FrameThreadContext *fctx = avctx->thread_opaque;
- int finished = fctx->next_finished;
- PerThreadContext *p;
- int err;
-
- /*
- * Submit a packet to the next decoding thread.
- */
-
- p = &fctx->threads[fctx->next_decoding];
- err = update_context_from_user(p->avctx, avctx);
- if (err) return err;
- err = submit_packet(p, avpkt);
- if (err) return err;
-
- /*
- * If we're still receiving the initial packets, don't return a frame.
- */
-
- if (fctx->next_decoding > (avctx->thread_count-1-(avctx->codec_id == AV_CODEC_ID_FFV1)))
- fctx->delaying = 0;
-
- if (fctx->delaying) {
- *got_picture_ptr=0;
- if (avpkt->size)
- return avpkt->size;
- }
-
- /*
- * Return the next available frame from the oldest thread.
- * If we're at the end of the stream, then we have to skip threads that
- * didn't output a frame, because we don't want to accidentally signal
- * EOF (avpkt->size == 0 && *got_picture_ptr == 0).
- */
-
- do {
- p = &fctx->threads[finished++];
-
- if (p->state != STATE_INPUT_READY) {
- pthread_mutex_lock(&p->progress_mutex);
- while (p->state != STATE_INPUT_READY)
- pthread_cond_wait(&p->output_cond, &p->progress_mutex);
- pthread_mutex_unlock(&p->progress_mutex);
- }
-
- av_frame_move_ref(picture, &p->frame);
- *got_picture_ptr = p->got_frame;
- picture->pkt_dts = p->avpkt.dts;
-
- /*
- * A later call with avkpt->size == 0 may loop over all threads,
- * including this one, searching for a frame to return before being
- * stopped by the "finished != fctx->next_finished" condition.
- * Make sure we don't mistakenly return the same frame again.
- */
- p->got_frame = 0;
-
- if (finished >= avctx->thread_count) finished = 0;
- } while (!avpkt->size && !*got_picture_ptr && finished != fctx->next_finished);
-
- update_context_from_thread(avctx, p->avctx, 1);
-
- if (fctx->next_decoding >= avctx->thread_count) fctx->next_decoding = 0;
-
- fctx->next_finished = finished;
-
- /* return the size of the consumed packet if no error occurred */
- return (p->result >= 0) ? avpkt->size : p->result;
-}
-
-void ff_thread_report_progress(ThreadFrame *f, int n, int field)
-{
- PerThreadContext *p;
- volatile int *progress = f->progress ? (int*)f->progress->data : NULL;
-
- if (!progress || progress[field] >= n) return;
-
- p = f->owner->thread_opaque;
-
- if (f->owner->debug&FF_DEBUG_THREADS)
- av_log(f->owner, AV_LOG_DEBUG, "%p finished %d field %d\n", progress, n, field);
-
- pthread_mutex_lock(&p->progress_mutex);
- progress[field] = n;
- pthread_cond_broadcast(&p->progress_cond);
- pthread_mutex_unlock(&p->progress_mutex);
-}
-
-void ff_thread_await_progress(ThreadFrame *f, int n, int field)
-{
- PerThreadContext *p;
- volatile int *progress = f->progress ? (int*)f->progress->data : NULL;
-
- if (!progress || progress[field] >= n) return;
-
- p = f->owner->thread_opaque;
-
- if (f->owner->debug&FF_DEBUG_THREADS)
- av_log(f->owner, AV_LOG_DEBUG, "thread awaiting %d field %d from %p\n", n, field, progress);
-
- pthread_mutex_lock(&p->progress_mutex);
- while (progress[field] < n)
- pthread_cond_wait(&p->progress_cond, &p->progress_mutex);
- pthread_mutex_unlock(&p->progress_mutex);
-}
-
-void ff_thread_finish_setup(AVCodecContext *avctx) {
- PerThreadContext *p = avctx->thread_opaque;
-
- if (!(avctx->active_thread_type&FF_THREAD_FRAME)) return;
-
- if(p->state == STATE_SETUP_FINISHED){
- av_log(avctx, AV_LOG_WARNING, "Multiple ff_thread_finish_setup() calls\n");
- }
-
- pthread_mutex_lock(&p->progress_mutex);
- p->state = STATE_SETUP_FINISHED;
- pthread_cond_broadcast(&p->progress_cond);
- pthread_mutex_unlock(&p->progress_mutex);
-}
-
-/// Waits for all threads to finish.
-static void park_frame_worker_threads(FrameThreadContext *fctx, int thread_count)
-{
- int i;
-
- for (i = 0; i < thread_count; i++) {
- PerThreadContext *p = &fctx->threads[i];
-
- if (p->state != STATE_INPUT_READY) {
- pthread_mutex_lock(&p->progress_mutex);
- while (p->state != STATE_INPUT_READY)
- pthread_cond_wait(&p->output_cond, &p->progress_mutex);
- pthread_mutex_unlock(&p->progress_mutex);
- }
- p->got_frame = 0;
- }
-}
-
-static void frame_thread_free(AVCodecContext *avctx, int thread_count)
-{
- FrameThreadContext *fctx = avctx->thread_opaque;
- const AVCodec *codec = avctx->codec;
- int i;
-
- park_frame_worker_threads(fctx, thread_count);
-
- if (fctx->prev_thread && fctx->prev_thread != fctx->threads)
- if (update_context_from_thread(fctx->threads->avctx, fctx->prev_thread->avctx, 0) < 0) {
- av_log(avctx, AV_LOG_ERROR, "Final thread update failed\n");
- fctx->prev_thread->avctx->internal->is_copy = fctx->threads->avctx->internal->is_copy;
- fctx->threads->avctx->internal->is_copy = 1;
- }
-
- fctx->die = 1;
-
- for (i = 0; i < thread_count; i++) {
- PerThreadContext *p = &fctx->threads[i];
-
- pthread_mutex_lock(&p->mutex);
- pthread_cond_signal(&p->input_cond);
- pthread_mutex_unlock(&p->mutex);
-
- if (p->thread_init)
- pthread_join(p->thread, NULL);
- p->thread_init=0;
-
- if (codec->close)
- codec->close(p->avctx);
-
- avctx->codec = NULL;
-
- release_delayed_buffers(p);
- av_frame_unref(&p->frame);
- }
-
- for (i = 0; i < thread_count; i++) {
- PerThreadContext *p = &fctx->threads[i];
-
- pthread_mutex_destroy(&p->mutex);
- pthread_mutex_destroy(&p->progress_mutex);
- pthread_cond_destroy(&p->input_cond);
- pthread_cond_destroy(&p->progress_cond);
- pthread_cond_destroy(&p->output_cond);
- av_buffer_unref(&p->avpkt.buf);
- av_freep(&p->buf);
- av_freep(&p->released_buffers);
-
- if (i) {
- av_freep(&p->avctx->priv_data);
- av_freep(&p->avctx->internal);
- av_freep(&p->avctx->slice_offset);
- }
-
- av_freep(&p->avctx);
- }
-
- av_freep(&fctx->threads);
- pthread_mutex_destroy(&fctx->buffer_mutex);
- av_freep(&avctx->thread_opaque);
-}
-
-static int frame_thread_init(AVCodecContext *avctx)
-{
- int thread_count = avctx->thread_count;
- const AVCodec *codec = avctx->codec;
- AVCodecContext *src = avctx;
- FrameThreadContext *fctx;
- int i, err = 0;
-
- if (!thread_count) {
- int nb_cpus = av_cpu_count();
- if ((avctx->debug & (FF_DEBUG_VIS_QP | FF_DEBUG_VIS_MB_TYPE)) || avctx->debug_mv)
- nb_cpus = 1;
- // use number of cores + 1 as thread count if there is more than one
- if (nb_cpus > 1)
- thread_count = avctx->thread_count = FFMIN(nb_cpus + 1, MAX_AUTO_THREADS);
- else
- thread_count = avctx->thread_count = 1;
- }
-
- if (thread_count <= 1) {
- avctx->active_thread_type = 0;
- return 0;
- }
-
- avctx->thread_opaque = fctx = av_mallocz(sizeof(FrameThreadContext));
-
- fctx->threads = av_mallocz(sizeof(PerThreadContext) * thread_count);
- pthread_mutex_init(&fctx->buffer_mutex, NULL);
- fctx->delaying = 1;
-
- for (i = 0; i < thread_count; i++) {
- AVCodecContext *copy = av_malloc(sizeof(AVCodecContext));
- PerThreadContext *p = &fctx->threads[i];
-
- pthread_mutex_init(&p->mutex, NULL);
- pthread_mutex_init(&p->progress_mutex, NULL);
- pthread_cond_init(&p->input_cond, NULL);
- pthread_cond_init(&p->progress_cond, NULL);
- pthread_cond_init(&p->output_cond, NULL);
-
- p->parent = fctx;
- p->avctx = copy;
-
- if (!copy) {
- err = AVERROR(ENOMEM);
- goto error;
- }
-
- *copy = *src;
- copy->thread_opaque = p;
- copy->pkt = &p->avpkt;
-
- if (!i) {
- src = copy;
-
- if (codec->init)
- err = codec->init(copy);
-
- update_context_from_thread(avctx, copy, 1);
- } else {
- 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);
- }
-
- if (err) goto error;
-
- err = AVERROR(pthread_create(&p->thread, NULL, frame_worker_thread, p));
- p->thread_init= !err;
- if(!p->thread_init)
- goto error;
- }
-
- return 0;
-
-error:
- frame_thread_free(avctx, i+1);
-
- return err;
-}
-
-void ff_thread_flush(AVCodecContext *avctx)
-{
- int i;
- FrameThreadContext *fctx = avctx->thread_opaque;
-
- if (!avctx->thread_opaque) return;
-
- park_frame_worker_threads(fctx, avctx->thread_count);
- if (fctx->prev_thread) {
- if (fctx->prev_thread != &fctx->threads[0])
- update_context_from_thread(fctx->threads[0].avctx, fctx->prev_thread->avctx, 0);
- if (avctx->codec->flush)
- avctx->codec->flush(fctx->threads[0].avctx);
- }
-
- fctx->next_decoding = fctx->next_finished = 0;
- fctx->delaying = 1;
- fctx->prev_thread = NULL;
- for (i = 0; i < avctx->thread_count; i++) {
- PerThreadContext *p = &fctx->threads[i];
- // Make sure decode flush calls with size=0 won't return old frames
- p->got_frame = 0;
- av_frame_unref(&p->frame);
-
- release_delayed_buffers(p);
- }
-}
-
-int ff_thread_can_start_frame(AVCodecContext *avctx)
-{
- PerThreadContext *p = avctx->thread_opaque;
- if ((avctx->active_thread_type&FF_THREAD_FRAME) && p->state != STATE_SETTING_UP &&
- (avctx->codec->update_thread_context || !THREAD_SAFE_CALLBACKS(avctx))) {
- return 0;
- }
- return 1;
-}
-
-static int thread_get_buffer_internal(AVCodecContext *avctx, ThreadFrame *f, int flags)
-{
- PerThreadContext *p = avctx->thread_opaque;
- int err;
-
- f->owner = avctx;
-
- ff_init_buffer_info(avctx, f->f);
-
- if (!(avctx->active_thread_type & FF_THREAD_FRAME))
- return ff_get_buffer(avctx, f->f, flags);
-
- if (p->state != STATE_SETTING_UP &&
- (avctx->codec->update_thread_context || !THREAD_SAFE_CALLBACKS(avctx))) {
- av_log(avctx, AV_LOG_ERROR, "get_buffer() cannot be called after ff_thread_finish_setup()\n");
- return -1;
- }
-
- if (avctx->internal->allocate_progress) {
- int *progress;
- f->progress = av_buffer_alloc(2 * sizeof(int));
- if (!f->progress) {
- return AVERROR(ENOMEM);
- }
- progress = (int*)f->progress->data;
-
- progress[0] = progress[1] = -1;
- }
-
- pthread_mutex_lock(&p->parent->buffer_mutex);
-
-FF_DISABLE_DEPRECATION_WARNINGS
- if (avctx->thread_safe_callbacks || (
-#if FF_API_GET_BUFFER
- !avctx->get_buffer &&
-#endif
- avctx->get_buffer2 == avcodec_default_get_buffer2)) {
-FF_ENABLE_DEPRECATION_WARNINGS
- err = ff_get_buffer(avctx, f->f, flags);
- } else {
- pthread_mutex_lock(&p->progress_mutex);
- p->requested_frame = f->f;
- p->requested_flags = flags;
- p->state = STATE_GET_BUFFER;
- pthread_cond_broadcast(&p->progress_cond);
-
- while (p->state != STATE_SETTING_UP)
- pthread_cond_wait(&p->progress_cond, &p->progress_mutex);
-
- err = p->result;
-
- pthread_mutex_unlock(&p->progress_mutex);
-
- }
- if (!THREAD_SAFE_CALLBACKS(avctx) && !avctx->codec->update_thread_context)
- ff_thread_finish_setup(avctx);
-
- if (err)
- av_buffer_unref(&f->progress);
-
- pthread_mutex_unlock(&p->parent->buffer_mutex);
-
- return err;
-}
-
-enum AVPixelFormat ff_thread_get_format(AVCodecContext *avctx, const enum AVPixelFormat *fmt)
-{
- enum AVPixelFormat res;
- PerThreadContext *p = avctx->thread_opaque;
- if (!(avctx->active_thread_type & FF_THREAD_FRAME) || avctx->thread_safe_callbacks ||
- avctx->get_format == avcodec_default_get_format)
- return avctx->get_format(avctx, fmt);
- if (p->state != STATE_SETTING_UP) {
- av_log(avctx, AV_LOG_ERROR, "get_format() cannot be called after ff_thread_finish_setup()\n");
- return -1;
- }
- pthread_mutex_lock(&p->progress_mutex);
- p->available_formats = fmt;
- p->state = STATE_GET_FORMAT;
- pthread_cond_broadcast(&p->progress_cond);
-
- while (p->state != STATE_SETTING_UP)
- pthread_cond_wait(&p->progress_cond, &p->progress_mutex);
-
- res = p->result_format;
-
- pthread_mutex_unlock(&p->progress_mutex);
-
- return res;
-}
-
-int ff_thread_get_buffer(AVCodecContext *avctx, ThreadFrame *f, int flags)
-{
- int ret = thread_get_buffer_internal(avctx, f, flags);
- if (ret < 0)
- av_log(avctx, AV_LOG_ERROR, "thread_get_buffer() failed\n");
- return ret;
-}
-
-void ff_thread_release_buffer(AVCodecContext *avctx, ThreadFrame *f)
-{
- PerThreadContext *p = avctx->thread_opaque;
- FrameThreadContext *fctx;
- AVFrame *dst, *tmp;
-FF_DISABLE_DEPRECATION_WARNINGS
- int can_direct_free = !(avctx->active_thread_type & FF_THREAD_FRAME) ||
- avctx->thread_safe_callbacks ||
- (
-#if FF_API_GET_BUFFER
- !avctx->get_buffer &&
-#endif
- avctx->get_buffer2 == avcodec_default_get_buffer2);
-FF_ENABLE_DEPRECATION_WARNINGS
-
- if (!f->f->data[0])
- return;
-
- if (avctx->debug & FF_DEBUG_BUFFERS)
- av_log(avctx, AV_LOG_DEBUG, "thread_release_buffer called on pic %p\n", f);
-
- av_buffer_unref(&f->progress);
- f->owner = NULL;
-
- if (can_direct_free) {
- av_frame_unref(f->f);
- return;
- }
-
- fctx = p->parent;
- pthread_mutex_lock(&fctx->buffer_mutex);
-
- if (p->num_released_buffers + 1 >= INT_MAX / sizeof(*p->released_buffers))
- goto fail;
- tmp = av_fast_realloc(p->released_buffers, &p->released_buffers_allocated,
- (p->num_released_buffers + 1) *
- sizeof(*p->released_buffers));
- if (!tmp)
- goto fail;
- p->released_buffers = tmp;
-
- dst = &p->released_buffers[p->num_released_buffers];
- av_frame_move_ref(dst, f->f);
-
- p->num_released_buffers++;
-
-fail:
- pthread_mutex_unlock(&fctx->buffer_mutex);
-}
/**
* Set the threading algorithms used.
@@ -1105,16 +69,12 @@
int ff_thread_init(AVCodecContext *avctx)
{
-#if HAVE_W32THREADS
- w32thread_init();
-#endif
-
validate_thread_parameters(avctx);
if (avctx->active_thread_type&FF_THREAD_SLICE)
- return thread_init_internal(avctx);
+ return ff_slice_thread_init(avctx);
else if (avctx->active_thread_type&FF_THREAD_FRAME)
- return frame_thread_init(avctx);
+ return ff_frame_thread_init(avctx);
return 0;
}
@@ -1122,7 +82,7 @@
void ff_thread_free(AVCodecContext *avctx)
{
if (avctx->active_thread_type&FF_THREAD_FRAME)
- frame_thread_free(avctx, avctx->thread_count);
+ ff_frame_thread_free(avctx, avctx->thread_count);
else
- thread_free(avctx);
+ ff_slice_thread_free(avctx);
}
diff --git a/libavcodec/pthread_frame.c b/libavcodec/pthread_frame.c
new file mode 100644
index 0000000..51a1633
--- /dev/null
+++ b/libavcodec/pthread_frame.c
@@ -0,0 +1,895 @@
+/*
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * Frame multithreading support functions
+ * @see doc/multithreading.txt
+ */
+
+#include "config.h"
+
+#include <stdint.h>
+
+#if HAVE_PTHREADS
+#include <pthread.h>
+#elif HAVE_W32THREADS
+#include "compat/w32pthreads.h"
+#elif HAVE_OS2THREADS
+#include "compat/os2threads.h"
+#endif
+
+#include "avcodec.h"
+#include "internal.h"
+#include "pthread_internal.h"
+#include "thread.h"
+
+#include "libavutil/avassert.h"
+#include "libavutil/buffer.h"
+#include "libavutil/common.h"
+#include "libavutil/cpu.h"
+#include "libavutil/frame.h"
+#include "libavutil/log.h"
+#include "libavutil/mem.h"
+
+/**
+ * Context used by codec threads and stored in their AVCodecInternal thread_ctx.
+ */
+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.
+
+ pthread_mutex_t mutex; ///< Mutex used to protect the contents of the PerThreadContext.
+ pthread_mutex_t progress_mutex; ///< Mutex used to protect frame progress values and progress_cond.
+
+ AVCodecContext *avctx; ///< Context used to decode packets passed to this thread.
+
+ AVPacket avpkt; ///< Input packet (for decoding) or output (for encoding).
+ uint8_t *buf; ///< backup storage for packet data when the input packet is not refcounted
+ int allocated_buf_size; ///< Size allocated for buf
+
+ AVFrame *frame; ///< Output frame (for decoding) or input (for encoding).
+ int got_frame; ///< The output of got_picture_ptr from the last avcodec_decode_video() call.
+ int result; ///< The result of the last codec decode/encode() call.
+
+ enum {
+ STATE_INPUT_READY, ///< Set when the thread is awaiting a packet.
+ STATE_SETTING_UP, ///< Set before the codec has called ff_thread_finish_setup().
+ STATE_GET_BUFFER, /**<
+ * Set when the codec calls get_buffer().
+ * State is returned to STATE_SETTING_UP afterwards.
+ */
+ STATE_GET_FORMAT, /**<
+ * Set when the codec calls get_format().
+ * State is returned to STATE_SETTING_UP afterwards.
+ */
+ STATE_SETUP_FINISHED ///< Set after the codec has called ff_thread_finish_setup().
+ } state;
+
+ /**
+ * Array of frames passed to ff_thread_release_buffer().
+ * Frames are released after all threads referencing them are finished.
+ */
+ AVFrame *released_buffers;
+ int num_released_buffers;
+ int released_buffers_allocated;
+
+ AVFrame *requested_frame; ///< AVFrame the codec passed to get_buffer()
+ int requested_flags; ///< flags passed to get_buffer() for requested_frame
+
+ const enum AVPixelFormat *available_formats; ///< Format array for get_format()
+ enum AVPixelFormat result_format; ///< get_format() result
+} PerThreadContext;
+
+/**
+ * Context stored in the client AVCodecInternal thread_ctx.
+ */
+typedef struct FrameThreadContext {
+ PerThreadContext *threads; ///< The contexts for each thread.
+ PerThreadContext *prev_thread; ///< The last thread submit_packet() was called on.
+
+ pthread_mutex_t buffer_mutex; ///< Mutex used to protect get/release_buffer().
+
+ int next_decoding; ///< The next context to submit a packet to.
+ int next_finished; ///< The next context to return output from.
+
+ int delaying; /**<
+ * Set for the first N packets, where N is the number of threads.
+ * While it is set, ff_thread_en/decode_frame won't return any results.
+ */
+
+ int die; ///< Set when threads should exit.
+} FrameThreadContext;
+
+#define THREAD_SAFE_CALLBACKS(avctx) \
+((avctx)->thread_safe_callbacks || (!(avctx)->get_buffer && (avctx)->get_buffer2 == avcodec_default_get_buffer2))
+
+/**
+ * Codec worker thread.
+ *
+ * Automatically calls ff_thread_finish_setup() if the codec does
+ * not provide an update_thread_context method, or if the codec returns
+ * before calling it.
+ */
+static attribute_align_arg void *frame_worker_thread(void *arg)
+{
+ PerThreadContext *p = arg;
+ FrameThreadContext *fctx = p->parent;
+ AVCodecContext *avctx = p->avctx;
+ const AVCodec *codec = avctx->codec;
+
+ pthread_mutex_lock(&p->mutex);
+ while (1) {
+ while (p->state == STATE_INPUT_READY && !fctx->die)
+ pthread_cond_wait(&p->input_cond, &p->mutex);
+
+ if (fctx->die) break;
+
+ if (!codec->update_thread_context && THREAD_SAFE_CALLBACKS(avctx))
+ ff_thread_finish_setup(avctx);
+
+ av_frame_unref(p->frame);
+ p->got_frame = 0;
+ p->result = codec->decode(avctx, p->frame, &p->got_frame, &p->avpkt);
+
+ if (p->state == STATE_SETTING_UP) ff_thread_finish_setup(avctx);
+
+ pthread_mutex_lock(&p->progress_mutex);
+#if 0 //BUFREF-FIXME
+ for (i = 0; i < MAX_BUFFERS; i++)
+ if (p->progress_used[i] && (p->got_frame || p->result<0 || avctx->codec_id != AV_CODEC_ID_H264)) {
+ p->progress[i][0] = INT_MAX;
+ p->progress[i][1] = INT_MAX;
+ }
+#endif
+ p->state = STATE_INPUT_READY;
+
+ pthread_cond_broadcast(&p->progress_cond);
+ pthread_cond_signal(&p->output_cond);
+ pthread_mutex_unlock(&p->progress_mutex);
+ }
+ pthread_mutex_unlock(&p->mutex);
+
+ return NULL;
+}
+
+/**
+ * Update the next thread's AVCodecContext with values from the reference thread's context.
+ *
+ * @param dst The destination context.
+ * @param src The source context.
+ * @param for_user 0 if the destination is a codec thread, 1 if the destination is the user's thread
+ */
+static int update_context_from_thread(AVCodecContext *dst, AVCodecContext *src, int for_user)
+{
+ int err = 0;
+
+ if (dst != src) {
+ dst->time_base = src->time_base;
+ dst->width = src->width;
+ 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->bits_per_coded_sample = src->bits_per_coded_sample;
+ dst->sample_aspect_ratio = src->sample_aspect_ratio;
+ dst->dtg_active_format = src->dtg_active_format;
+
+ dst->profile = src->profile;
+ dst->level = src->level;
+
+ dst->bits_per_raw_sample = src->bits_per_raw_sample;
+ dst->ticks_per_frame = src->ticks_per_frame;
+ dst->color_primaries = src->color_primaries;
+
+ dst->color_trc = src->color_trc;
+ dst->colorspace = src->colorspace;
+ dst->color_range = src->color_range;
+ dst->chroma_sample_location = src->chroma_sample_location;
+
+ dst->hwaccel = src->hwaccel;
+ dst->hwaccel_context = src->hwaccel_context;
+
+ dst->channels = src->channels;
+ dst->sample_rate = src->sample_rate;
+ dst->sample_fmt = src->sample_fmt;
+ dst->channel_layout = src->channel_layout;
+ }
+
+ if (for_user) {
+ dst->delay = 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);
+ }
+
+ return err;
+}
+
+/**
+ * Update the next thread's AVCodecContext with values set by the user.
+ *
+ * @param dst The destination context.
+ * @param src The source context.
+ * @return 0 on success, negative error code on failure
+ */
+static int update_context_from_user(AVCodecContext *dst, AVCodecContext *src)
+{
+#define copy_fields(s, e) memcpy(&dst->s, &src->s, (char*)&dst->e - (char*)&dst->s);
+ dst->flags = src->flags;
+
+ dst->draw_horiz_band= src->draw_horiz_band;
+ dst->get_buffer2 = src->get_buffer2;
+#if FF_API_GET_BUFFER
+FF_DISABLE_DEPRECATION_WARNINGS
+ dst->get_buffer = src->get_buffer;
+ dst->release_buffer = src->release_buffer;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+
+ dst->opaque = src->opaque;
+ dst->debug = src->debug;
+ dst->debug_mv = src->debug_mv;
+
+ dst->slice_flags = src->slice_flags;
+ dst->flags2 = src->flags2;
+
+ copy_fields(skip_loop_filter, subtitle_header);
+
+ dst->frame_number = src->frame_number;
+ dst->reordered_opaque = src->reordered_opaque;
+ dst->thread_safe_callbacks = src->thread_safe_callbacks;
+
+ if (src->slice_count && src->slice_offset) {
+ if (dst->slice_count < src->slice_count) {
+ int *tmp = av_realloc(dst->slice_offset, src->slice_count *
+ sizeof(*dst->slice_offset));
+ if (!tmp) {
+ av_free(dst->slice_offset);
+ return AVERROR(ENOMEM);
+ }
+ dst->slice_offset = tmp;
+ }
+ memcpy(dst->slice_offset, src->slice_offset,
+ src->slice_count * sizeof(*dst->slice_offset));
+ }
+ dst->slice_count = src->slice_count;
+ return 0;
+#undef copy_fields
+}
+
+/// Releases the buffers that this decoding thread was the last user of.
+static void release_delayed_buffers(PerThreadContext *p)
+{
+ FrameThreadContext *fctx = p->parent;
+
+ while (p->num_released_buffers > 0) {
+ AVFrame *f;
+
+ pthread_mutex_lock(&fctx->buffer_mutex);
+
+ // fix extended data in case the caller screwed it up
+ av_assert0(p->avctx->codec_type == AVMEDIA_TYPE_VIDEO ||
+ p->avctx->codec_type == AVMEDIA_TYPE_AUDIO);
+ f = &p->released_buffers[--p->num_released_buffers];
+ f->extended_data = f->data;
+ av_frame_unref(f);
+
+ pthread_mutex_unlock(&fctx->buffer_mutex);
+ }
+}
+
+static int submit_packet(PerThreadContext *p, AVPacket *avpkt)
+{
+ FrameThreadContext *fctx = p->parent;
+ PerThreadContext *prev_thread = fctx->prev_thread;
+ const AVCodec *codec = p->avctx->codec;
+
+ if (!avpkt->size && !(codec->capabilities & CODEC_CAP_DELAY)) return 0;
+
+ pthread_mutex_lock(&p->mutex);
+
+ release_delayed_buffers(p);
+
+ if (prev_thread) {
+ int err;
+ if (prev_thread->state == STATE_SETTING_UP) {
+ pthread_mutex_lock(&prev_thread->progress_mutex);
+ while (prev_thread->state == STATE_SETTING_UP)
+ pthread_cond_wait(&prev_thread->progress_cond, &prev_thread->progress_mutex);
+ pthread_mutex_unlock(&prev_thread->progress_mutex);
+ }
+
+ err = update_context_from_thread(p->avctx, prev_thread->avctx, 0);
+ if (err) {
+ pthread_mutex_unlock(&p->mutex);
+ return err;
+ }
+ }
+
+ av_buffer_unref(&p->avpkt.buf);
+ p->avpkt = *avpkt;
+ if (avpkt->buf)
+ p->avpkt.buf = av_buffer_ref(avpkt->buf);
+ else {
+ av_fast_malloc(&p->buf, &p->allocated_buf_size, avpkt->size + FF_INPUT_BUFFER_PADDING_SIZE);
+ if (!p->buf) {
+ pthread_mutex_unlock(&p->mutex);
+ return AVERROR(ENOMEM);
+ }
+ p->avpkt.data = p->buf;
+ memcpy(p->buf, avpkt->data, avpkt->size);
+ memset(p->buf + avpkt->size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
+ }
+
+ p->state = STATE_SETTING_UP;
+ pthread_cond_signal(&p->input_cond);
+ pthread_mutex_unlock(&p->mutex);
+
+ /*
+ * If the client doesn't have a thread-safe get_buffer(),
+ * then decoding threads call back to the main thread,
+ * and it calls back to the client here.
+ */
+
+FF_DISABLE_DEPRECATION_WARNINGS
+ if (!p->avctx->thread_safe_callbacks && (
+ p->avctx->get_format != avcodec_default_get_format ||
+#if FF_API_GET_BUFFER
+ p->avctx->get_buffer ||
+#endif
+ p->avctx->get_buffer2 != avcodec_default_get_buffer2)) {
+FF_ENABLE_DEPRECATION_WARNINGS
+ while (p->state != STATE_SETUP_FINISHED && p->state != STATE_INPUT_READY) {
+ int call_done = 1;
+ pthread_mutex_lock(&p->progress_mutex);
+ while (p->state == STATE_SETTING_UP)
+ pthread_cond_wait(&p->progress_cond, &p->progress_mutex);
+
+ switch (p->state) {
+ case STATE_GET_BUFFER:
+ p->result = ff_get_buffer(p->avctx, p->requested_frame, p->requested_flags);
+ break;
+ case STATE_GET_FORMAT:
+ p->result_format = p->avctx->get_format(p->avctx, p->available_formats);
+ break;
+ default:
+ call_done = 0;
+ break;
+ }
+ if (call_done) {
+ p->state = STATE_SETTING_UP;
+ pthread_cond_signal(&p->progress_cond);
+ }
+ pthread_mutex_unlock(&p->progress_mutex);
+ }
+ }
+
+ fctx->prev_thread = p;
+ fctx->next_decoding++;
+
+ return 0;
+}
+
+int ff_thread_decode_frame(AVCodecContext *avctx,
+ AVFrame *picture, int *got_picture_ptr,
+ AVPacket *avpkt)
+{
+ FrameThreadContext *fctx = avctx->internal->thread_ctx;
+ int finished = fctx->next_finished;
+ PerThreadContext *p;
+ int err;
+
+ /*
+ * Submit a packet to the next decoding thread.
+ */
+
+ p = &fctx->threads[fctx->next_decoding];
+ err = update_context_from_user(p->avctx, avctx);
+ if (err) return err;
+ err = submit_packet(p, avpkt);
+ if (err) return err;
+
+ /*
+ * If we're still receiving the initial packets, don't return a frame.
+ */
+
+ if (fctx->next_decoding > (avctx->thread_count-1-(avctx->codec_id == AV_CODEC_ID_FFV1)))
+ fctx->delaying = 0;
+
+ if (fctx->delaying) {
+ *got_picture_ptr=0;
+ if (avpkt->size)
+ return avpkt->size;
+ }
+
+ /*
+ * Return the next available frame from the oldest thread.
+ * If we're at the end of the stream, then we have to skip threads that
+ * didn't output a frame, because we don't want to accidentally signal
+ * EOF (avpkt->size == 0 && *got_picture_ptr == 0).
+ */
+
+ do {
+ p = &fctx->threads[finished++];
+
+ if (p->state != STATE_INPUT_READY) {
+ pthread_mutex_lock(&p->progress_mutex);
+ while (p->state != STATE_INPUT_READY)
+ pthread_cond_wait(&p->output_cond, &p->progress_mutex);
+ pthread_mutex_unlock(&p->progress_mutex);
+ }
+
+ av_frame_move_ref(picture, p->frame);
+ *got_picture_ptr = p->got_frame;
+ picture->pkt_dts = p->avpkt.dts;
+
+ /*
+ * A later call with avkpt->size == 0 may loop over all threads,
+ * including this one, searching for a frame to return before being
+ * stopped by the "finished != fctx->next_finished" condition.
+ * Make sure we don't mistakenly return the same frame again.
+ */
+ p->got_frame = 0;
+
+ if (finished >= avctx->thread_count) finished = 0;
+ } while (!avpkt->size && !*got_picture_ptr && finished != fctx->next_finished);
+
+ update_context_from_thread(avctx, p->avctx, 1);
+
+ if (fctx->next_decoding >= avctx->thread_count) fctx->next_decoding = 0;
+
+ fctx->next_finished = finished;
+
+ /* return the size of the consumed packet if no error occurred */
+ return (p->result >= 0) ? avpkt->size : p->result;
+}
+
+void ff_thread_report_progress(ThreadFrame *f, int n, int field)
+{
+ PerThreadContext *p;
+ volatile int *progress = f->progress ? (int*)f->progress->data : NULL;
+
+ if (!progress || progress[field] >= n) return;
+
+ p = f->owner->internal->thread_ctx;
+
+ if (f->owner->debug&FF_DEBUG_THREADS)
+ av_log(f->owner, AV_LOG_DEBUG, "%p finished %d field %d\n", progress, n, field);
+
+ pthread_mutex_lock(&p->progress_mutex);
+ progress[field] = n;
+ pthread_cond_broadcast(&p->progress_cond);
+ pthread_mutex_unlock(&p->progress_mutex);
+}
+
+void ff_thread_await_progress(ThreadFrame *f, int n, int field)
+{
+ PerThreadContext *p;
+ volatile int *progress = f->progress ? (int*)f->progress->data : NULL;
+
+ if (!progress || progress[field] >= n) return;
+
+ p = f->owner->internal->thread_ctx;
+
+ if (f->owner->debug&FF_DEBUG_THREADS)
+ av_log(f->owner, AV_LOG_DEBUG, "thread awaiting %d field %d from %p\n", n, field, progress);
+
+ pthread_mutex_lock(&p->progress_mutex);
+ while (progress[field] < n)
+ pthread_cond_wait(&p->progress_cond, &p->progress_mutex);
+ pthread_mutex_unlock(&p->progress_mutex);
+}
+
+void ff_thread_finish_setup(AVCodecContext *avctx) {
+ PerThreadContext *p = avctx->internal->thread_ctx;
+
+ if (!(avctx->active_thread_type&FF_THREAD_FRAME)) return;
+
+ if(p->state == STATE_SETUP_FINISHED){
+ av_log(avctx, AV_LOG_WARNING, "Multiple ff_thread_finish_setup() calls\n");
+ }
+
+ pthread_mutex_lock(&p->progress_mutex);
+ p->state = STATE_SETUP_FINISHED;
+ pthread_cond_broadcast(&p->progress_cond);
+ pthread_mutex_unlock(&p->progress_mutex);
+}
+
+/// Waits for all threads to finish.
+static void park_frame_worker_threads(FrameThreadContext *fctx, int thread_count)
+{
+ int i;
+
+ for (i = 0; i < thread_count; i++) {
+ PerThreadContext *p = &fctx->threads[i];
+
+ if (p->state != STATE_INPUT_READY) {
+ pthread_mutex_lock(&p->progress_mutex);
+ while (p->state != STATE_INPUT_READY)
+ pthread_cond_wait(&p->output_cond, &p->progress_mutex);
+ pthread_mutex_unlock(&p->progress_mutex);
+ }
+ p->got_frame = 0;
+ }
+}
+
+void ff_frame_thread_free(AVCodecContext *avctx, int thread_count)
+{
+ FrameThreadContext *fctx = avctx->internal->thread_ctx;
+ const AVCodec *codec = avctx->codec;
+ int i;
+
+ park_frame_worker_threads(fctx, thread_count);
+
+ if (fctx->prev_thread && fctx->prev_thread != fctx->threads)
+ if (update_context_from_thread(fctx->threads->avctx, fctx->prev_thread->avctx, 0) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "Final thread update failed\n");
+ fctx->prev_thread->avctx->internal->is_copy = fctx->threads->avctx->internal->is_copy;
+ fctx->threads->avctx->internal->is_copy = 1;
+ }
+
+ fctx->die = 1;
+
+ for (i = 0; i < thread_count; i++) {
+ PerThreadContext *p = &fctx->threads[i];
+
+ pthread_mutex_lock(&p->mutex);
+ pthread_cond_signal(&p->input_cond);
+ pthread_mutex_unlock(&p->mutex);
+
+ if (p->thread_init)
+ pthread_join(p->thread, NULL);
+ p->thread_init=0;
+
+ if (codec->close)
+ codec->close(p->avctx);
+
+ avctx->codec = NULL;
+
+ release_delayed_buffers(p);
+ av_frame_free(&p->frame);
+ }
+
+ for (i = 0; i < thread_count; i++) {
+ PerThreadContext *p = &fctx->threads[i];
+
+ pthread_mutex_destroy(&p->mutex);
+ pthread_mutex_destroy(&p->progress_mutex);
+ pthread_cond_destroy(&p->input_cond);
+ pthread_cond_destroy(&p->progress_cond);
+ pthread_cond_destroy(&p->output_cond);
+ av_buffer_unref(&p->avpkt.buf);
+ av_freep(&p->buf);
+ av_freep(&p->released_buffers);
+
+ if (i) {
+ av_freep(&p->avctx->priv_data);
+ av_freep(&p->avctx->slice_offset);
+ }
+
+ av_freep(&p->avctx->internal);
+ av_freep(&p->avctx);
+ }
+
+ av_freep(&fctx->threads);
+ pthread_mutex_destroy(&fctx->buffer_mutex);
+ av_freep(&avctx->internal->thread_ctx);
+}
+
+int ff_frame_thread_init(AVCodecContext *avctx)
+{
+ int thread_count = avctx->thread_count;
+ const AVCodec *codec = avctx->codec;
+ AVCodecContext *src = avctx;
+ FrameThreadContext *fctx;
+ int i, err = 0;
+
+#if HAVE_W32THREADS
+ w32thread_init();
+#endif
+
+ if (!thread_count) {
+ int nb_cpus = av_cpu_count();
+ if ((avctx->debug & (FF_DEBUG_VIS_QP | FF_DEBUG_VIS_MB_TYPE)) || avctx->debug_mv)
+ nb_cpus = 1;
+ // use number of cores + 1 as thread count if there is more than one
+ if (nb_cpus > 1)
+ thread_count = avctx->thread_count = FFMIN(nb_cpus + 1, MAX_AUTO_THREADS);
+ else
+ thread_count = avctx->thread_count = 1;
+ }
+
+ if (thread_count <= 1) {
+ avctx->active_thread_type = 0;
+ return 0;
+ }
+
+ avctx->internal->thread_ctx = fctx = av_mallocz(sizeof(FrameThreadContext));
+
+ fctx->threads = av_mallocz(sizeof(PerThreadContext) * thread_count);
+ pthread_mutex_init(&fctx->buffer_mutex, NULL);
+ fctx->delaying = 1;
+
+ for (i = 0; i < thread_count; i++) {
+ AVCodecContext *copy = av_malloc(sizeof(AVCodecContext));
+ PerThreadContext *p = &fctx->threads[i];
+
+ pthread_mutex_init(&p->mutex, NULL);
+ pthread_mutex_init(&p->progress_mutex, NULL);
+ pthread_cond_init(&p->input_cond, NULL);
+ pthread_cond_init(&p->progress_cond, NULL);
+ pthread_cond_init(&p->output_cond, NULL);
+
+ p->frame = av_frame_alloc();
+ if (!p->frame) {
+ err = AVERROR(ENOMEM);
+ goto error;
+ }
+
+ p->parent = fctx;
+ p->avctx = copy;
+
+ if (!copy) {
+ err = AVERROR(ENOMEM);
+ goto error;
+ }
+
+ *copy = *src;
+
+ copy->internal = av_malloc(sizeof(AVCodecInternal));
+ if (!copy->internal) {
+ err = AVERROR(ENOMEM);
+ goto error;
+ }
+ *copy->internal = *src->internal;
+ copy->internal->thread_ctx = p;
+ copy->internal->pkt = &p->avpkt;
+
+ if (!i) {
+ src = copy;
+
+ if (codec->init)
+ err = codec->init(copy);
+
+ update_context_from_thread(avctx, copy, 1);
+ } else {
+ 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->is_copy = 1;
+
+ if (codec->init_thread_copy)
+ err = codec->init_thread_copy(copy);
+ }
+
+ if (err) goto error;
+
+ err = AVERROR(pthread_create(&p->thread, NULL, frame_worker_thread, p));
+ p->thread_init= !err;
+ if(!p->thread_init)
+ goto error;
+ }
+
+ return 0;
+
+error:
+ ff_frame_thread_free(avctx, i+1);
+
+ return err;
+}
+
+void ff_thread_flush(AVCodecContext *avctx)
+{
+ int i;
+ FrameThreadContext *fctx = avctx->internal->thread_ctx;
+
+ if (!fctx) return;
+
+ park_frame_worker_threads(fctx, avctx->thread_count);
+ if (fctx->prev_thread) {
+ if (fctx->prev_thread != &fctx->threads[0])
+ update_context_from_thread(fctx->threads[0].avctx, fctx->prev_thread->avctx, 0);
+ if (avctx->codec->flush)
+ avctx->codec->flush(fctx->threads[0].avctx);
+ }
+
+ fctx->next_decoding = fctx->next_finished = 0;
+ fctx->delaying = 1;
+ fctx->prev_thread = NULL;
+ for (i = 0; i < avctx->thread_count; i++) {
+ PerThreadContext *p = &fctx->threads[i];
+ // Make sure decode flush calls with size=0 won't return old frames
+ p->got_frame = 0;
+ av_frame_unref(p->frame);
+
+ release_delayed_buffers(p);
+ }
+}
+
+int ff_thread_can_start_frame(AVCodecContext *avctx)
+{
+ PerThreadContext *p = avctx->internal->thread_ctx;
+ if ((avctx->active_thread_type&FF_THREAD_FRAME) && p->state != STATE_SETTING_UP &&
+ (avctx->codec->update_thread_context || !THREAD_SAFE_CALLBACKS(avctx))) {
+ return 0;
+ }
+ return 1;
+}
+
+static int thread_get_buffer_internal(AVCodecContext *avctx, ThreadFrame *f, int flags)
+{
+ PerThreadContext *p = avctx->internal->thread_ctx;
+ int err;
+
+ f->owner = avctx;
+
+ ff_init_buffer_info(avctx, f->f);
+
+ if (!(avctx->active_thread_type & FF_THREAD_FRAME))
+ return ff_get_buffer(avctx, f->f, flags);
+
+ if (p->state != STATE_SETTING_UP &&
+ (avctx->codec->update_thread_context || !THREAD_SAFE_CALLBACKS(avctx))) {
+ av_log(avctx, AV_LOG_ERROR, "get_buffer() cannot be called after ff_thread_finish_setup()\n");
+ return -1;
+ }
+
+ if (avctx->internal->allocate_progress) {
+ int *progress;
+ f->progress = av_buffer_alloc(2 * sizeof(int));
+ if (!f->progress) {
+ return AVERROR(ENOMEM);
+ }
+ progress = (int*)f->progress->data;
+
+ progress[0] = progress[1] = -1;
+ }
+
+ pthread_mutex_lock(&p->parent->buffer_mutex);
+FF_DISABLE_DEPRECATION_WARNINGS
+ if (avctx->thread_safe_callbacks || (
+#if FF_API_GET_BUFFER
+ !avctx->get_buffer &&
+#endif
+ avctx->get_buffer2 == avcodec_default_get_buffer2)) {
+FF_ENABLE_DEPRECATION_WARNINGS
+ err = ff_get_buffer(avctx, f->f, flags);
+ } else {
+ pthread_mutex_lock(&p->progress_mutex);
+ p->requested_frame = f->f;
+ p->requested_flags = flags;
+ p->state = STATE_GET_BUFFER;
+ pthread_cond_broadcast(&p->progress_cond);
+
+ while (p->state != STATE_SETTING_UP)
+ pthread_cond_wait(&p->progress_cond, &p->progress_mutex);
+
+ err = p->result;
+
+ pthread_mutex_unlock(&p->progress_mutex);
+
+ }
+ if (!THREAD_SAFE_CALLBACKS(avctx) && !avctx->codec->update_thread_context)
+ ff_thread_finish_setup(avctx);
+
+ if (err)
+ av_buffer_unref(&f->progress);
+
+ pthread_mutex_unlock(&p->parent->buffer_mutex);
+
+ return err;
+}
+
+enum AVPixelFormat ff_thread_get_format(AVCodecContext *avctx, const enum AVPixelFormat *fmt)
+{
+ enum AVPixelFormat res;
+ PerThreadContext *p = avctx->internal->thread_ctx;
+ if (!(avctx->active_thread_type & FF_THREAD_FRAME) || avctx->thread_safe_callbacks ||
+ avctx->get_format == avcodec_default_get_format)
+ return avctx->get_format(avctx, fmt);
+ if (p->state != STATE_SETTING_UP) {
+ av_log(avctx, AV_LOG_ERROR, "get_format() cannot be called after ff_thread_finish_setup()\n");
+ return -1;
+ }
+ pthread_mutex_lock(&p->progress_mutex);
+ p->available_formats = fmt;
+ p->state = STATE_GET_FORMAT;
+ pthread_cond_broadcast(&p->progress_cond);
+
+ while (p->state != STATE_SETTING_UP)
+ pthread_cond_wait(&p->progress_cond, &p->progress_mutex);
+
+ res = p->result_format;
+
+ pthread_mutex_unlock(&p->progress_mutex);
+
+ return res;
+}
+
+int ff_thread_get_buffer(AVCodecContext *avctx, ThreadFrame *f, int flags)
+{
+ int ret = thread_get_buffer_internal(avctx, f, flags);
+ if (ret < 0)
+ av_log(avctx, AV_LOG_ERROR, "thread_get_buffer() failed\n");
+ return ret;
+}
+
+void ff_thread_release_buffer(AVCodecContext *avctx, ThreadFrame *f)
+{
+ PerThreadContext *p = avctx->internal->thread_ctx;
+ FrameThreadContext *fctx;
+ AVFrame *dst, *tmp;
+FF_DISABLE_DEPRECATION_WARNINGS
+ int can_direct_free = !(avctx->active_thread_type & FF_THREAD_FRAME) ||
+ avctx->thread_safe_callbacks ||
+ (
+#if FF_API_GET_BUFFER
+ !avctx->get_buffer &&
+#endif
+ avctx->get_buffer2 == avcodec_default_get_buffer2);
+FF_ENABLE_DEPRECATION_WARNINGS
+
+ if (!f->f->buf[0])
+ return;
+
+ if (avctx->debug & FF_DEBUG_BUFFERS)
+ av_log(avctx, AV_LOG_DEBUG, "thread_release_buffer called on pic %p\n", f);
+
+ av_buffer_unref(&f->progress);
+ f->owner = NULL;
+
+ if (can_direct_free) {
+ av_frame_unref(f->f);
+ return;
+ }
+
+ fctx = p->parent;
+ pthread_mutex_lock(&fctx->buffer_mutex);
+
+ if (p->num_released_buffers + 1 >= INT_MAX / sizeof(*p->released_buffers))
+ goto fail;
+ tmp = av_fast_realloc(p->released_buffers, &p->released_buffers_allocated,
+ (p->num_released_buffers + 1) *
+ sizeof(*p->released_buffers));
+ if (!tmp)
+ goto fail;
+ p->released_buffers = tmp;
+
+ dst = &p->released_buffers[p->num_released_buffers];
+ av_frame_move_ref(dst, f->f);
+
+ p->num_released_buffers++;
+
+fail:
+ pthread_mutex_unlock(&fctx->buffer_mutex);
+}
diff --git a/libavcodec/pthread_internal.h b/libavcodec/pthread_internal.h
new file mode 100644
index 0000000..6a2f378
--- /dev/null
+++ b/libavcodec/pthread_internal.h
@@ -0,0 +1,34 @@
+/*
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVCODEC_PTHREAD_INTERNAL_H
+#define AVCODEC_PTHREAD_INTERNAL_H
+
+#include "avcodec.h"
+
+/* 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
+
+int ff_slice_thread_init(AVCodecContext *avctx);
+void ff_slice_thread_free(AVCodecContext *avctx);
+
+int ff_frame_thread_init(AVCodecContext *avctx);
+void ff_frame_thread_free(AVCodecContext *avctx, int thread_count);
+
+#endif // AVCODEC_PTHREAD_INTERNAL_H
diff --git a/libavcodec/pthread_slice.c b/libavcodec/pthread_slice.c
new file mode 100644
index 0000000..edfe9c6
--- /dev/null
+++ b/libavcodec/pthread_slice.c
@@ -0,0 +1,292 @@
+/*
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * Slice multithreading support functions
+ * @see doc/multithreading.txt
+ */
+
+#include "config.h"
+
+#if HAVE_PTHREADS
+#include <pthread.h>
+#elif HAVE_W32THREADS
+#include "compat/w32pthreads.h"
+#elif HAVE_OS2THREADS
+#include "compat/os2threads.h"
+#endif
+
+#include "avcodec.h"
+#include "internal.h"
+#include "pthread_internal.h"
+#include "thread.h"
+
+#include "libavutil/common.h"
+#include "libavutil/cpu.h"
+#include "libavutil/mem.h"
+
+typedef int (action_func)(AVCodecContext *c, void *arg);
+typedef int (action_func2)(AVCodecContext *c, void *arg, int jobnr, int threadnr);
+
+typedef struct SliceThreadContext {
+ pthread_t *workers;
+ action_func *func;
+ action_func2 *func2;
+ void *args;
+ int *rets;
+ int rets_count;
+ int job_count;
+ int job_size;
+
+ pthread_cond_t last_job_cond;
+ pthread_cond_t current_job_cond;
+ pthread_mutex_t current_job_lock;
+ unsigned current_execute;
+ int current_job;
+ int done;
+
+ int *entries;
+ int entries_count;
+ int thread_count;
+ pthread_cond_t *progress_cond;
+ pthread_mutex_t *progress_mutex;
+} SliceThreadContext;
+
+static void* attribute_align_arg worker(void *v)
+{
+ AVCodecContext *avctx = v;
+ SliceThreadContext *c = avctx->internal->thread_ctx;
+ unsigned last_execute = 0;
+ int our_job = c->job_count;
+ int thread_count = avctx->thread_count;
+ int self_id;
+
+ pthread_mutex_lock(&c->current_job_lock);
+ self_id = c->current_job++;
+ for (;;){
+ while (our_job >= c->job_count) {
+ if (c->current_job == thread_count + c->job_count)
+ pthread_cond_signal(&c->last_job_cond);
+
+ while (last_execute == c->current_execute && !c->done)
+ pthread_cond_wait(&c->current_job_cond, &c->current_job_lock);
+ last_execute = c->current_execute;
+ our_job = self_id;
+
+ if (c->done) {
+ pthread_mutex_unlock(&c->current_job_lock);
+ return NULL;
+ }
+ }
+ pthread_mutex_unlock(&c->current_job_lock);
+
+ c->rets[our_job%c->rets_count] = c->func ? c->func(avctx, (char*)c->args + our_job*c->job_size):
+ c->func2(avctx, c->args, our_job, self_id);
+
+ pthread_mutex_lock(&c->current_job_lock);
+ our_job = c->current_job++;
+ }
+}
+
+void ff_slice_thread_free(AVCodecContext *avctx)
+{
+ SliceThreadContext *c = avctx->internal->thread_ctx;
+ int i;
+
+ pthread_mutex_lock(&c->current_job_lock);
+ c->done = 1;
+ pthread_cond_broadcast(&c->current_job_cond);
+ pthread_mutex_unlock(&c->current_job_lock);
+
+ for (i=0; i<avctx->thread_count; i++)
+ pthread_join(c->workers[i], NULL);
+
+ pthread_mutex_destroy(&c->current_job_lock);
+ pthread_cond_destroy(&c->current_job_cond);
+ pthread_cond_destroy(&c->last_job_cond);
+ av_free(c->workers);
+ av_freep(&avctx->internal->thread_ctx);
+}
+
+static av_always_inline void thread_park_workers(SliceThreadContext *c, int thread_count)
+{
+ while (c->current_job != thread_count + c->job_count)
+ pthread_cond_wait(&c->last_job_cond, &c->current_job_lock);
+ pthread_mutex_unlock(&c->current_job_lock);
+}
+
+static int thread_execute(AVCodecContext *avctx, action_func* func, void *arg, int *ret, int job_count, int job_size)
+{
+ SliceThreadContext *c = avctx->internal->thread_ctx;
+ int dummy_ret;
+
+ if (!(avctx->active_thread_type&FF_THREAD_SLICE) || avctx->thread_count <= 1)
+ return avcodec_default_execute(avctx, func, arg, ret, job_count, job_size);
+
+ if (job_count <= 0)
+ return 0;
+
+ pthread_mutex_lock(&c->current_job_lock);
+
+ c->current_job = avctx->thread_count;
+ c->job_count = job_count;
+ c->job_size = job_size;
+ c->args = arg;
+ c->func = func;
+ if (ret) {
+ c->rets = ret;
+ c->rets_count = job_count;
+ } else {
+ c->rets = &dummy_ret;
+ c->rets_count = 1;
+ }
+ c->current_execute++;
+ pthread_cond_broadcast(&c->current_job_cond);
+
+ thread_park_workers(c, avctx->thread_count);
+
+ return 0;
+}
+
+static int thread_execute2(AVCodecContext *avctx, action_func2* func2, void *arg, int *ret, int job_count)
+{
+ SliceThreadContext *c = avctx->internal->thread_ctx;
+ c->func2 = func2;
+ return thread_execute(avctx, NULL, arg, ret, job_count, 0);
+}
+
+int ff_slice_thread_init(AVCodecContext *avctx)
+{
+ int i;
+ SliceThreadContext *c;
+ int thread_count = avctx->thread_count;
+
+#if HAVE_W32THREADS
+ w32thread_init();
+#endif
+
+ if (!thread_count) {
+ int nb_cpus = av_cpu_count();
+ if (avctx->height)
+ nb_cpus = FFMIN(nb_cpus, (avctx->height+15)/16);
+ // use number of cores + 1 as thread count if there is more than one
+ if (nb_cpus > 1)
+ thread_count = avctx->thread_count = FFMIN(nb_cpus + 1, MAX_AUTO_THREADS);
+ else
+ thread_count = avctx->thread_count = 1;
+ }
+
+ if (thread_count <= 1) {
+ avctx->active_thread_type = 0;
+ return 0;
+ }
+
+ c = av_mallocz(sizeof(SliceThreadContext));
+ if (!c)
+ return -1;
+
+ c->workers = av_mallocz(sizeof(pthread_t)*thread_count);
+ if (!c->workers) {
+ av_free(c);
+ return -1;
+ }
+
+ avctx->internal->thread_ctx = c;
+ c->current_job = 0;
+ c->job_count = 0;
+ c->job_size = 0;
+ c->done = 0;
+ pthread_cond_init(&c->current_job_cond, NULL);
+ pthread_cond_init(&c->last_job_cond, NULL);
+ pthread_mutex_init(&c->current_job_lock, NULL);
+ pthread_mutex_lock(&c->current_job_lock);
+ for (i=0; i<thread_count; i++) {
+ if(pthread_create(&c->workers[i], NULL, worker, avctx)) {
+ avctx->thread_count = i;
+ pthread_mutex_unlock(&c->current_job_lock);
+ ff_thread_free(avctx);
+ return -1;
+ }
+ }
+
+ thread_park_workers(c, thread_count);
+
+ avctx->execute = thread_execute;
+ avctx->execute2 = thread_execute2;
+ return 0;
+}
+
+void ff_thread_report_progress2(AVCodecContext *avctx, int field, int thread, int n)
+{
+ SliceThreadContext *p = avctx->internal->thread_ctx;
+ int *entries = p->entries;
+
+ pthread_mutex_lock(&p->progress_mutex[thread]);
+ entries[field] +=n;
+ pthread_cond_signal(&p->progress_cond[thread]);
+ pthread_mutex_unlock(&p->progress_mutex[thread]);
+}
+
+void ff_thread_await_progress2(AVCodecContext *avctx, int field, int thread, int shift)
+{
+ SliceThreadContext *p = avctx->internal->thread_ctx;
+ int *entries = p->entries;
+
+ if (!entries || !field) return;
+
+ thread = thread ? thread - 1 : p->thread_count - 1;
+
+ pthread_mutex_lock(&p->progress_mutex[thread]);
+ while ((entries[field - 1] - entries[field]) < shift){
+ pthread_cond_wait(&p->progress_cond[thread], &p->progress_mutex[thread]);
+ }
+ pthread_mutex_unlock(&p->progress_mutex[thread]);
+}
+
+int ff_alloc_entries(AVCodecContext *avctx, int count)
+{
+ int i;
+
+ if (avctx->active_thread_type & FF_THREAD_SLICE) {
+ SliceThreadContext *p = avctx->internal->thread_ctx;
+ p->thread_count = avctx->thread_count;
+ p->entries = av_mallocz(count * sizeof(int));
+
+ if (!p->entries) {
+ return AVERROR(ENOMEM);
+ }
+
+ p->entries_count = count;
+ p->progress_mutex = av_malloc(p->thread_count * sizeof(pthread_mutex_t));
+ p->progress_cond = av_malloc(p->thread_count * sizeof(pthread_cond_t));
+
+ for (i = 0; i < p->thread_count; i++) {
+ pthread_mutex_init(&p->progress_mutex[i], NULL);
+ pthread_cond_init(&p->progress_cond[i], NULL);
+ }
+ }
+
+ return 0;
+}
+
+void ff_reset_entries(AVCodecContext *avctx)
+{
+ SliceThreadContext *p = avctx->internal->thread_ctx;
+ memset(p->entries, 0, p->entries_count * sizeof(int));
+}
diff --git a/libavcodec/ptx.c b/libavcodec/ptx.c
index 6da9f02..8c3abd7 100644
--- a/libavcodec/ptx.c
+++ b/libavcodec/ptx.c
@@ -55,10 +55,9 @@
buf += offset;
- if ((ret = av_image_check_size(w, h, 0, avctx)) < 0)
+ if ((ret = ff_set_dimensions(avctx, w, h)) < 0)
return ret;
- if (w != avctx->width || h != avctx->height)
- avcodec_set_dimensions(avctx, w, h);
+
if ((ret = ff_get_buffer(avctx, p, 0)) < 0)
return ret;
diff --git a/libavcodec/qdm2.c b/libavcodec/qdm2.c
index 0a9eea0..bf830db 100644
--- a/libavcodec/qdm2.c
+++ b/libavcodec/qdm2.c
@@ -1750,12 +1750,19 @@
*
* @param q context
*/
-static av_cold void qdm2_init_static_data(AVCodec *codec) {
+static av_cold void qdm2_init_static_data(void) {
+ static int done;
+
+ if(done)
+ return;
+
qdm2_init_vlc();
ff_mpa_synth_init_float(ff_mpa_synth_window_float);
softclip_table_init();
rnd_table_init();
init_noise_samples();
+
+ done = 1;
}
/**
@@ -1768,6 +1775,8 @@
int extradata_size;
int tmp_val, tmp, size;
+ qdm2_init_static_data();
+
/* extradata parsing
Structure:
@@ -2044,7 +2053,6 @@
.id = AV_CODEC_ID_QDM2,
.priv_data_size = sizeof(QDM2Context),
.init = qdm2_decode_init,
- .init_static_data = qdm2_init_static_data,
.close = qdm2_decode_close,
.decode = qdm2_decode_frame,
.capabilities = CODEC_CAP_DR1,
diff --git a/libavcodec/qpeg.c b/libavcodec/qpeg.c
index edde937..94cb5bd 100644
--- a/libavcodec/qpeg.c
+++ b/libavcodec/qpeg.c
@@ -30,7 +30,7 @@
typedef struct QpegContext{
AVCodecContext *avctx;
- AVFrame pic, ref;
+ AVFrame *pic, *ref;
uint32_t pal[256];
GetByteContext buffer;
} QpegContext;
@@ -110,7 +110,7 @@
{ 0x00, 0x20, 0x18, 0x08, 0x18, 0x10, 0x20, 0x10, 0x08, 0x10, 0x20, 0x20, 0x08, 0x10, 0x18, 0x04};
/* Decodes delta frames */
-static void qpeg_decode_inter(QpegContext *qctx, uint8_t *dst,
+static void av_noinline qpeg_decode_inter(QpegContext *qctx, uint8_t *dst,
int stride, int width, int height,
int delta, const uint8_t *ctable,
uint8_t *refdata)
@@ -255,8 +255,8 @@
{
uint8_t ctable[128];
QpegContext * const a = avctx->priv_data;
- AVFrame * p = &a->pic;
- AVFrame * ref= &a->ref;
+ AVFrame * const p = a->pic;
+ AVFrame * const ref = a->ref;
uint8_t* outdata;
int delta, ret;
const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, NULL);
@@ -273,26 +273,26 @@
if ((ret = ff_get_buffer(avctx, p, AV_GET_BUFFER_FLAG_REF)) < 0)
return ret;
- outdata = a->pic.data[0];
+ outdata = p->data[0];
bytestream2_skip(&a->buffer, 4);
bytestream2_get_buffer(&a->buffer, ctable, 128);
bytestream2_skip(&a->buffer, 1);
delta = bytestream2_get_byte(&a->buffer);
if(delta == 0x10) {
- qpeg_decode_intra(a, outdata, a->pic.linesize[0], avctx->width, avctx->height);
+ qpeg_decode_intra(a, outdata, p->linesize[0], avctx->width, avctx->height);
} else {
- qpeg_decode_inter(a, outdata, a->pic.linesize[0], avctx->width, avctx->height, delta, ctable, a->ref.data[0]);
+ qpeg_decode_inter(a, outdata, p->linesize[0], avctx->width, avctx->height, delta, ctable, ref->data[0]);
}
/* make the palette available on the way out */
if (pal) {
- a->pic.palette_has_changed = 1;
+ p->palette_has_changed = 1;
memcpy(a->pal, pal, AVPALETTE_SIZE);
}
- memcpy(a->pic.data[1], a->pal, AVPALETTE_SIZE);
+ memcpy(p->data[1], a->pal, AVPALETTE_SIZE);
- if ((ret = av_frame_ref(data, &a->pic)) < 0)
+ if ((ret = av_frame_ref(data, p)) < 0)
return ret;
*got_frame = 1;
@@ -312,28 +312,30 @@
a->pal[i] = 0xFFU<<24 | AV_RL32(pal_src+4*i);
}
+static av_cold int decode_end(AVCodecContext *avctx)
+{
+ QpegContext * const a = avctx->priv_data;
+
+ av_frame_free(&a->pic);
+ av_frame_free(&a->ref);
+
+ return 0;
+}
+
static av_cold int decode_init(AVCodecContext *avctx){
QpegContext * const a = avctx->priv_data;
- avcodec_get_frame_defaults(&a->pic);
- avcodec_get_frame_defaults(&a->ref);
a->avctx = avctx;
avctx->pix_fmt= AV_PIX_FMT_PAL8;
decode_flush(avctx);
- avcodec_get_frame_defaults(&a->pic);
-
- return 0;
-}
-
-static av_cold int decode_end(AVCodecContext *avctx){
- QpegContext * const a = avctx->priv_data;
- AVFrame * const p = &a->pic;
- AVFrame * const ref= &a->ref;
-
- av_frame_unref(p);
- av_frame_unref(ref);
+ a->pic = av_frame_alloc();
+ a->ref = av_frame_alloc();
+ if (!a->pic || !a->ref) {
+ decode_end(avctx);
+ return AVERROR(ENOMEM);
+ }
return 0;
}
diff --git a/libavcodec/qtrleenc.c b/libavcodec/qtrleenc.c
index 2395cff..7f9525a 100644
--- a/libavcodec/qtrleenc.c
+++ b/libavcodec/qtrleenc.c
@@ -36,7 +36,6 @@
typedef struct QtrleEncContext {
AVCodecContext *avctx;
- AVFrame frame;
int pixel_size;
AVPicture previous_frame;
unsigned int max_buf_size;
@@ -61,6 +60,19 @@
uint8_t* skip_table;
} QtrleEncContext;
+static av_cold int qtrle_encode_end(AVCodecContext *avctx)
+{
+ QtrleEncContext *s = avctx->priv_data;
+
+ av_frame_free(&avctx->coded_frame);
+
+ avpicture_free(&s->previous_frame);
+ av_free(s->rlecode_table);
+ av_free(s->length_table);
+ av_free(s->skip_table);
+ return 0;
+}
+
static av_cold int qtrle_encode_init(AVCodecContext *avctx)
{
QtrleEncContext *s = avctx->priv_data;
@@ -108,7 +120,13 @@
+ 15 /* header + footer */
+ s->avctx->height*2 /* skip code+rle end */
+ s->logical_width/MAX_RLE_BULK + 1 /* rle codes */;
- avctx->coded_frame = &s->frame;
+
+ avctx->coded_frame = av_frame_alloc();
+ if (!avctx->coded_frame) {
+ qtrle_encode_end(avctx);
+ return AVERROR(ENOMEM);
+ }
+
return 0;
}
@@ -197,7 +215,7 @@
}
}
- if (!s->frame.key_frame && !memcmp(this_line, prev_line, s->pixel_size))
+ if (!s->avctx->coded_frame->key_frame && !memcmp(this_line, prev_line, s->pixel_size))
skipcount = FFMIN(skipcount + 1, MAX_RLE_SKIP);
else
skipcount = 0;
@@ -308,7 +326,7 @@
int end_line = s->avctx->height;
uint8_t *orig_buf = buf;
- if (!s->frame.key_frame) {
+ if (!s->avctx->coded_frame->key_frame) {
unsigned line_size = s->logical_width * s->pixel_size;
for (start_line = 0; start_line < s->avctx->height; start_line++)
if (memcmp(p->data[0] + start_line*p->linesize[0],
@@ -346,11 +364,9 @@
const AVFrame *pict, int *got_packet)
{
QtrleEncContext * const s = avctx->priv_data;
- AVFrame * const p = &s->frame;
+ AVFrame * const p = avctx->coded_frame;
int ret;
- *p = *pict;
-
if ((ret = ff_alloc_packet2(avctx, pkt, s->max_buf_size)) < 0)
return ret;
@@ -367,7 +383,8 @@
pkt->size = encode_frame(s, pict, pkt->data);
/* save the current frame */
- av_picture_copy(&s->previous_frame, (AVPicture *)p, avctx->pix_fmt, avctx->width, avctx->height);
+ av_picture_copy(&s->previous_frame, (const AVPicture *)pict,
+ avctx->pix_fmt, avctx->width, avctx->height);
if (p->key_frame)
pkt->flags |= AV_PKT_FLAG_KEY;
@@ -376,17 +393,6 @@
return 0;
}
-static av_cold int qtrle_encode_end(AVCodecContext *avctx)
-{
- QtrleEncContext *s = avctx->priv_data;
-
- avpicture_free(&s->previous_frame);
- av_free(s->rlecode_table);
- av_free(s->length_table);
- av_free(s->skip_table);
- return 0;
-}
-
AVCodec ff_qtrle_encoder = {
.name = "qtrle",
.long_name = NULL_IF_CONFIG_SMALL("QuickTime Animation (RLE) video"),
diff --git a/libavcodec/r210enc.c b/libavcodec/r210enc.c
index 80230f5..d61cd75 100644
--- a/libavcodec/r210enc.c
+++ b/libavcodec/r210enc.c
@@ -26,7 +26,7 @@
static av_cold int encode_init(AVCodecContext *avctx)
{
- avctx->coded_frame = avcodec_alloc_frame();
+ avctx->coded_frame = av_frame_alloc();
if (!avctx->coded_frame)
return AVERROR(ENOMEM);
diff --git a/libavcodec/rawdec.c b/libavcodec/rawdec.c
index dd47f53..3f4a8fc 100644
--- a/libavcodec/rawdec.c
+++ b/libavcodec/rawdec.c
@@ -25,6 +25,7 @@
*/
#include "avcodec.h"
+#include "internal.h"
#include "raw.h"
#include "libavutil/avassert.h"
#include "libavutil/buffer.h"
@@ -182,9 +183,9 @@
frame->pict_type = AV_PICTURE_TYPE_I;
frame->key_frame = 1;
frame->reordered_opaque = avctx->reordered_opaque;
- frame->pkt_pts = avctx->pkt->pts;
- av_frame_set_pkt_pos (frame, avctx->pkt->pos);
- av_frame_set_pkt_duration(frame, avctx->pkt->duration);
+ frame->pkt_pts = avctx->internal->pkt->pts;
+ av_frame_set_pkt_pos (frame, avctx->internal->pkt->pos);
+ av_frame_set_pkt_duration(frame, avctx->internal->pkt->duration);
if (context->tff >= 0) {
frame->interlaced_frame = 1;
diff --git a/libavcodec/roqvideo.h b/libavcodec/roqvideo.h
index 3834897..39dda0c 100644
--- a/libavcodec/roqvideo.h
+++ b/libavcodec/roqvideo.h
@@ -44,7 +44,6 @@
typedef struct RoqContext {
AVCodecContext *avctx;
- AVFrame frames[2];
AVFrame *last_frame;
AVFrame *current_frame;
int first_frame;
diff --git a/libavcodec/roqvideoenc.c b/libavcodec/roqvideoenc.c
index bf0756c..37bd8d5 100644
--- a/libavcodec/roqvideoenc.c
+++ b/libavcodec/roqvideoenc.c
@@ -806,8 +806,8 @@
else
closest_cb = tempdata->closest_cb2;
- ff_init_elbg(points, 6*c_size, inputCount, codebook, cbsize, 1, closest_cb, &enc->randctx);
- ff_do_elbg(points, 6*c_size, inputCount, codebook, cbsize, 1, closest_cb, &enc->randctx);
+ avpriv_init_elbg(points, 6*c_size, inputCount, codebook, cbsize, 1, closest_cb, &enc->randctx);
+ avpriv_do_elbg(points, 6*c_size, inputCount, codebook, cbsize, 1, closest_cb, &enc->randctx);
if (size == 4)
av_free(closest_cb);
diff --git a/libavcodec/rpza.c b/libavcodec/rpza.c
index 4917369..d4e2b17 100644
--- a/libavcodec/rpza.c
+++ b/libavcodec/rpza.c
@@ -46,7 +46,7 @@
typedef struct RpzaContext {
AVCodecContext *avctx;
- AVFrame frame;
+ AVFrame *frame;
const unsigned char *buf;
int size;
@@ -72,7 +72,7 @@
static void rpza_decode_stream(RpzaContext *s)
{
int width = s->avctx->width;
- int stride = s->frame.linesize[0] / 2;
+ int stride = s->frame->linesize[0] / 2;
int row_inc = stride - 4;
int stream_ptr = 0;
int chunk_size;
@@ -82,7 +82,7 @@
unsigned short color4[4];
unsigned char index, idx;
unsigned short ta, tb;
- unsigned short *pixels = (unsigned short *)s->frame.data[0];
+ unsigned short *pixels = (unsigned short *)s->frame->data[0];
int row_ptr = 0;
int pixel_ptr = -4;
@@ -239,7 +239,9 @@
s->avctx = avctx;
avctx->pix_fmt = AV_PIX_FMT_RGB555;
- avcodec_get_frame_defaults(&s->frame);
+ s->frame = av_frame_alloc();
+ if (!s->frame)
+ return AVERROR(ENOMEM);
return 0;
}
@@ -256,12 +258,12 @@
s->buf = buf;
s->size = buf_size;
- if ((ret = ff_reget_buffer(avctx, &s->frame)) < 0)
+ if ((ret = ff_reget_buffer(avctx, s->frame)) < 0)
return ret;
rpza_decode_stream(s);
- if ((ret = av_frame_ref(data, &s->frame)) < 0)
+ if ((ret = av_frame_ref(data, s->frame)) < 0)
return ret;
*got_frame = 1;
@@ -274,7 +276,7 @@
{
RpzaContext *s = avctx->priv_data;
- av_frame_unref(&s->frame);
+ av_frame_free(&s->frame);
return 0;
}
diff --git a/libavcodec/rv10.c b/libavcodec/rv10.c
index 5206533..4d48a49 100644
--- a/libavcodec/rv10.c
+++ b/libavcodec/rv10.c
@@ -28,6 +28,7 @@
#include "libavutil/imgutils.h"
#include "avcodec.h"
#include "error_resilience.h"
+#include "internal.h"
#include "mpegvideo.h"
#include "mpeg4video.h"
#include "h263.h"
@@ -374,7 +375,11 @@
s->avctx->sample_aspect_ratio = av_mul_q(old_aspect, (AVRational){2, 1});
if (new_w * s->height == 2 * new_h * s->width)
s->avctx->sample_aspect_ratio = av_mul_q(old_aspect, (AVRational){1, 2});
- avcodec_set_dimensions(s->avctx, new_w, new_h);
+
+ ret = ff_set_dimensions(s->avctx, new_w, new_h);
+ if (ret < 0)
+ return ret;
+
s->width = new_w;
s->height = new_h;
if ((ret = ff_MPV_common_init(s)) < 0)
@@ -497,6 +502,7 @@
if ((ret = ff_MPV_common_init(s)) < 0)
return ret;
+ ff_h263dsp_init(&s->h263dsp);
ff_h263_decode_init_vlc();
/* init rv vlc */
diff --git a/libavcodec/rv34.c b/libavcodec/rv34.c
index f84fb00..1aee59c 100644
--- a/libavcodec/rv34.c
+++ b/libavcodec/rv34.c
@@ -724,15 +724,21 @@
uint8_t *uvbuf = s->edge_emu_buffer + 22 * s->linesize;
srcY -= 2 + 2*s->linesize;
- s->vdsp.emulated_edge_mc(s->edge_emu_buffer, s->linesize, srcY, s->linesize,
- (width<<3)+6, (height<<3)+6, src_x - 2, src_y - 2,
+ s->vdsp.emulated_edge_mc(s->edge_emu_buffer, srcY,
+ s->linesize, s->linesize,
+ (width << 3) + 6, (height << 3) + 6,
+ src_x - 2, src_y - 2,
s->h_edge_pos, s->v_edge_pos);
srcY = s->edge_emu_buffer + 2 + 2*s->linesize;
- s->vdsp.emulated_edge_mc(uvbuf, s->uvlinesize, srcU, s->uvlinesize,
- (width<<2)+1, (height<<2)+1, uvsrc_x, uvsrc_y,
+ s->vdsp.emulated_edge_mc(uvbuf, srcU,
+ s->uvlinesize, s->uvlinesize,
+ (width << 2) + 1, (height << 2) + 1,
+ uvsrc_x, uvsrc_y,
s->h_edge_pos >> 1, s->v_edge_pos >> 1);
- s->vdsp.emulated_edge_mc(uvbuf + 16, s->uvlinesize, srcV, s->uvlinesize,
- (width<<2)+1, (height<<2)+1, uvsrc_x, uvsrc_y,
+ s->vdsp.emulated_edge_mc(uvbuf + 16, srcV,
+ s->uvlinesize, s->uvlinesize,
+ (width << 2) + 1, (height << 2) + 1,
+ uvsrc_x, uvsrc_y,
s->h_edge_pos >> 1, s->v_edge_pos >> 1);
srcU = uvbuf;
srcV = uvbuf + 16;
@@ -1693,7 +1699,11 @@
si.width, si.height);
s->width = si.width;
s->height = si.height;
- avcodec_set_dimensions(s->avctx, s->width, s->height);
+
+ err = ff_set_dimensions(s->avctx, s->width, s->height);
+ if (err < 0)
+ return err;
+
if ((err = ff_MPV_common_frame_size_change(s)) < 0)
return err;
if ((err = rv34_decoder_realloc(r)) < 0)
diff --git a/libavcodec/s302menc.c b/libavcodec/s302menc.c
index c428d54..a7e5b1d 100644
--- a/libavcodec/s302menc.c
+++ b/libavcodec/s302menc.c
@@ -165,7 +165,7 @@
.name = "s302m",
.long_name = NULL_IF_CONFIG_SMALL("SMPTE 302M"),
.type = AVMEDIA_TYPE_AUDIO,
- .id = CODEC_ID_S302M,
+ .id = AV_CODEC_ID_S302M,
.priv_data_size = sizeof(S302MEncContext),
.init = s302m_encode_init,
.encode2 = s302m_encode2_frame,
diff --git a/libavcodec/sanm.c b/libavcodec/sanm.c
index 76da8bb..a6c1c01 100644
--- a/libavcodec/sanm.c
+++ b/libavcodec/sanm.c
@@ -738,11 +738,10 @@
}
if (ctx->width < left + w || ctx->height < top + h) {
- if (av_image_check_size(FFMAX(left + w, ctx->width),
- FFMAX(top + h, ctx->height), 0, ctx->avctx) < 0)
- return AVERROR_INVALIDDATA;
- avcodec_set_dimensions(ctx->avctx, FFMAX(left + w, ctx->width),
- FFMAX(top + h, ctx->height));
+ int ret = ff_set_dimensions(ctx->avctx, FFMAX(left + w, ctx->width),
+ FFMAX(top + h, ctx->height));
+ if (ret < 0)
+ return ret;
init_sizes(ctx, FFMAX(left + w, ctx->width),
FFMAX(top + h, ctx->height));
if (init_buffers(ctx)) {
diff --git a/libavcodec/sgidec.c b/libavcodec/sgidec.c
index df41e89..35063ea 100644
--- a/libavcodec/sgidec.c
+++ b/libavcodec/sgidec.c
@@ -138,10 +138,9 @@
for (y = s->height - 1; y >= 0; y--) {
out_end = out_buf + (y * s->linesize);
if (s->bytes_per_channel == 1) {
- for (x = s->width; x > 0; x--) {
- bytestream2_get_bufferu(&gp[z], out_end, s->depth);
- out_end += s->depth;
- }
+ for (x = s->width; x > 0; x--)
+ for (z = 0; z < s->depth; z++)
+ *out_end++ = bytestream2_get_byteu(&gp[z]);
} else {
uint16_t *out16 = (uint16_t *)out_end;
for (x = s->width; x > 0; x--)
@@ -203,9 +202,9 @@
return AVERROR_INVALIDDATA;
}
- if (av_image_check_size(s->width, s->height, 0, avctx))
- return AVERROR_INVALIDDATA;
- avcodec_set_dimensions(avctx, s->width, s->height);
+ ret = ff_set_dimensions(avctx, s->width, s->height);
+ if (ret < 0)
+ return ret;
if ((ret = ff_get_buffer(avctx, p, 0)) < 0)
return ret;
diff --git a/libavcodec/sgienc.c b/libavcodec/sgienc.c
index 48532ff..0e4f304 100644
--- a/libavcodec/sgienc.c
+++ b/libavcodec/sgienc.c
@@ -34,6 +34,9 @@
av_log(avctx, AV_LOG_ERROR, "SGI does not support resolutions above 65535x65535\n");
return -1;
}
+ avctx->coded_frame = av_frame_alloc();
+ if (!avctx->coded_frame)
+ return AVERROR(ENOMEM);
return 0;
}
@@ -41,14 +44,14 @@
static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
const AVFrame *frame, int *got_packet)
{
- AVFrame * const p = (AVFrame *)frame;
+ const AVFrame * const p = frame;
uint8_t *offsettab, *lengthtab, *in_buf, *encode_buf, *buf;
int x, y, z, length, tablesize, ret;
unsigned int width, height, depth, dimension, bytes_per_channel, pixmax, put_be;
unsigned char *end_buf;
- p->pict_type = AV_PICTURE_TYPE_I;
- p->key_frame = 1;
+ avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
+ avctx->coded_frame->key_frame = 1;
width = avctx->width;
height = avctx->height;
@@ -199,6 +202,12 @@
return 0;
}
+static av_cold int encode_close(AVCodecContext *avctx)
+{
+ av_frame_free(&avctx->coded_frame);
+ return 0;
+}
+
AVCodec ff_sgi_encoder = {
.name = "sgi",
.long_name = NULL_IF_CONFIG_SMALL("SGI image"),
@@ -206,6 +215,7 @@
.id = AV_CODEC_ID_SGI,
.init = encode_init,
.encode2 = encode_frame,
+ .close = encode_close,
.pix_fmts = (const enum AVPixelFormat[]){
AV_PIX_FMT_RGB24, AV_PIX_FMT_RGBA,
AV_PIX_FMT_RGB48LE, AV_PIX_FMT_RGB48BE,
diff --git a/libavcodec/shorten.c b/libavcodec/shorten.c
index c25097c..2bd35d2 100644
--- a/libavcodec/shorten.c
+++ b/libavcodec/shorten.c
@@ -122,9 +122,7 @@
static int allocate_buffers(ShortenContext *s)
{
- int i, chan;
- int *coeffs;
- void *tmp_ptr;
+ int i, chan, err;
for (chan = 0; chan < s->channels; chan++) {
if (FFMAX(1, s->nmean) >= UINT_MAX / sizeof(int32_t)) {
@@ -138,26 +136,21 @@
return AVERROR_INVALIDDATA;
}
- 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;
+ if ((err = av_reallocp(&s->offset[chan],
+ sizeof(int32_t) *
+ FFMAX(1, s->nmean))) < 0)
+ return err;
- tmp_ptr = av_realloc(s->decoded_base[chan], (s->blocksize + s->nwrap) *
- sizeof(s->decoded_base[0][0]));
- if (!tmp_ptr)
- return AVERROR(ENOMEM);
- s->decoded_base[chan] = tmp_ptr;
+ if ((err = av_reallocp(&s->decoded_base[chan], (s->blocksize + s->nwrap) *
+ sizeof(s->decoded_base[0][0]))) < 0)
+ return err;
for (i = 0; i < s->nwrap; i++)
s->decoded_base[chan][i] = 0;
s->decoded[chan] = s->decoded_base[chan] + s->nwrap;
}
- coeffs = av_realloc(s->coeffs, s->nwrap * sizeof(*s->coeffs));
- if (!coeffs)
- return AVERROR(ENOMEM);
- s->coeffs = coeffs;
+ if ((err = av_reallocp(&s->coeffs, s->nwrap * sizeof(*s->coeffs))) < 0)
+ return err;
return 0;
}
diff --git a/libavcodec/smacker.c b/libavcodec/smacker.c
index 3cdb0d5..717e9ea 100644
--- a/libavcodec/smacker.c
+++ b/libavcodec/smacker.c
@@ -584,6 +584,10 @@
avctx->pix_fmt = AV_PIX_FMT_PAL8;
+ c->pic = av_frame_alloc();
+ if (!c->pic)
+ return AVERROR(ENOMEM);
+
/* decode huffman trees from extradata */
if(avctx->extradata_size < 16){
av_log(avctx, AV_LOG_ERROR, "Extradata missing!\n");
@@ -596,10 +600,6 @@
return ret;
}
- c->pic = av_frame_alloc();
- if (!c->pic)
- return AVERROR(ENOMEM);
-
return 0;
}
diff --git a/libavcodec/smc.c b/libavcodec/smc.c
index 3b836e7..31e6c88 100644
--- a/libavcodec/smc.c
+++ b/libavcodec/smc.c
@@ -46,7 +46,7 @@
typedef struct SmcContext {
AVCodecContext *avctx;
- AVFrame frame;
+ AVFrame *frame;
GetByteContext gb;
@@ -81,7 +81,7 @@
{
int width = s->avctx->width;
int height = s->avctx->height;
- int stride = s->frame.linesize[0];
+ int stride = s->frame->linesize[0];
int i;
int chunk_size;
int buf_size = bytestream2_size(&s->gb);
@@ -92,9 +92,9 @@
unsigned int color_flags_b;
unsigned int flag_mask;
- unsigned char *pixels = s->frame.data[0];
+ unsigned char *pixels = s->frame->data[0];
- int image_size = height * s->frame.linesize[0];
+ int image_size = height * s->frame->linesize[0];
int row_ptr = 0;
int pixel_ptr = 0;
int pixel_x, pixel_y;
@@ -112,7 +112,7 @@
int color_octet_index = 0;
/* make the palette available */
- memcpy(s->frame.data[1], s->pal, AVPALETTE_SIZE);
+ memcpy(s->frame->data[1], s->pal, AVPALETTE_SIZE);
bytestream2_skip(&s->gb, 1);
chunk_size = bytestream2_get_be24(&s->gb);
@@ -417,7 +417,9 @@
s->avctx = avctx;
avctx->pix_fmt = AV_PIX_FMT_PAL8;
- avcodec_get_frame_defaults(&s->frame);
+ s->frame = av_frame_alloc();
+ if (!s->frame)
+ return AVERROR(ENOMEM);
return 0;
}
@@ -434,18 +436,18 @@
bytestream2_init(&s->gb, buf, buf_size);
- if ((ret = ff_reget_buffer(avctx, &s->frame)) < 0)
+ if ((ret = ff_reget_buffer(avctx, s->frame)) < 0)
return ret;
if (pal) {
- s->frame.palette_has_changed = 1;
+ s->frame->palette_has_changed = 1;
memcpy(s->pal, pal, AVPALETTE_SIZE);
}
smc_decode_stream(s);
*got_frame = 1;
- if ((ret = av_frame_ref(data, &s->frame)) < 0)
+ if ((ret = av_frame_ref(data, s->frame)) < 0)
return ret;
/* always report that the buffer was completely consumed */
@@ -456,7 +458,7 @@
{
SmcContext *s = avctx->priv_data;
- av_frame_unref(&s->frame);
+ av_frame_free(&s->frame);
return 0;
}
diff --git a/libavcodec/snow.c b/libavcodec/snow.c
index b54c491..c645b12 100644
--- a/libavcodec/snow.c
+++ b/libavcodec/snow.c
@@ -349,7 +349,8 @@
src += sx + sy*stride;
if( (unsigned)sx >= FFMAX(w - b_w - (HTAPS_MAX-2), 0)
|| (unsigned)sy >= FFMAX(h - b_h - (HTAPS_MAX-2), 0)){
- s->vdsp.emulated_edge_mc(tmp + MB_SIZE, stride, src, stride,
+ s->vdsp.emulated_edge_mc(tmp + MB_SIZE, src,
+ stride, stride,
b_w+HTAPS_MAX-1, b_h+HTAPS_MAX-1,
sx, sy, w, h);
src= tmp + MB_SIZE;
diff --git a/libavcodec/srtenc.c b/libavcodec/srtenc.c
index 3036a7f..89c26dc 100644
--- a/libavcodec/srtenc.c
+++ b/libavcodec/srtenc.c
@@ -22,6 +22,7 @@
#include <stdarg.h>
#include "avcodec.h"
#include "libavutil/avstring.h"
+#include "libavutil/bprint.h"
#include "ass_split.h"
#include "ass.h"
@@ -31,10 +32,8 @@
typedef struct {
AVCodecContext *avctx;
ASSSplitContext *ass_ctx;
- char buffer[2048];
- char *ptr;
- char *end;
- char *dialog_start;
+ AVBPrint buffer;
+ unsigned timestamp_end;
int count;
char stack[SRT_STACK_SIZE];
int stack_ptr;
@@ -49,7 +48,7 @@
{
va_list vargs;
va_start(vargs, str);
- s->ptr += vsnprintf(s->ptr, s->end - s->ptr, str, vargs);
+ av_vbprintf(&s->buffer, str, vargs);
va_end(vargs);
}
@@ -138,14 +137,14 @@
SRTContext *s = avctx->priv_data;
s->avctx = avctx;
s->ass_ctx = ff_ass_split(avctx->subtitle_header);
+ av_bprint_init(&s->buffer, 0, AV_BPRINT_SIZE_UNLIMITED);
return s->ass_ctx ? 0 : AVERROR_INVALIDDATA;
}
static void srt_text_cb(void *priv, const char *text, int len)
{
SRTContext *s = priv;
- av_strlcpy(s->ptr, text, FFMIN(s->end-s->ptr, len+1));
- s->ptr += len;
+ av_bprint_append_data(&s->buffer, text, len);
}
static void srt_new_line_cb(void *priv, int forced)
@@ -208,11 +207,19 @@
char buffer[32];
int len = snprintf(buffer, sizeof(buffer),
" X1:%03u X2:%03u Y1:%03u Y2:%03u", x1, x2, y1, y2);
- if (s->end - s->ptr > len) {
- memmove(s->dialog_start+len, s->dialog_start, s->ptr-s->dialog_start+1);
- memcpy(s->dialog_start, buffer, len);
- s->ptr += len;
+ unsigned char *dummy;
+ unsigned room;
+
+ av_bprint_get_buffer(&s->buffer, len, &dummy, &room);
+ if (room >= len) {
+ memmove(s->buffer.str + s->timestamp_end + len,
+ s->buffer.str + s->timestamp_end,
+ s->buffer.len - s->timestamp_end + 1);
+ memcpy(s->buffer.str + s->timestamp_end, buffer, len);
}
+ /* Increment even if av_bprint_get_buffer() did not return enough room:
+ the bprint structure will be treated as truncated. */
+ s->buffer.len += len;
}
}
@@ -243,10 +250,9 @@
{
SRTContext *s = avctx->priv_data;
ASSDialog *dialog;
- int i, len, num;
+ int i, num;
- s->ptr = s->buffer;
- s->end = s->ptr + sizeof(s->buffer);
+ av_bprint_clear(&s->buffer);
for (i=0; i<sub->num_rects; i++) {
@@ -268,7 +274,7 @@
es = ec/ 1000; ec -= 1000*es;
srt_print(s,"%d\r\n%02d:%02d:%02d,%03d --> %02d:%02d:%02d,%03d\r\n",
++s->count, sh, sm, ss, sc, eh, em, es, ec);
- s->dialog_start = s->ptr - 2;
+ s->timestamp_end = s->buffer.len - 2;
}
s->alignment_applied = 0;
srt_style_apply(s, dialog->style);
@@ -276,23 +282,25 @@
}
}
- if (s->ptr == s->buffer)
+ if (!av_bprint_is_complete(&s->buffer))
+ return AVERROR(ENOMEM);
+ if (!s->buffer.len)
return 0;
- len = av_strlcpy(buf, s->buffer, bufsize);
-
- if (len > bufsize-1) {
+ if (s->buffer.len > bufsize) {
av_log(avctx, AV_LOG_ERROR, "Buffer too small for ASS event.\n");
return -1;
}
+ memcpy(buf, s->buffer.str, s->buffer.len);
- return len;
+ return s->buffer.len;
}
static int srt_encode_close(AVCodecContext *avctx)
{
SRTContext *s = avctx->priv_data;
ff_ass_split_free(s->ass_ctx);
+ av_bprint_finalize(&s->buffer, NULL);
return 0;
}
diff --git a/libavcodec/sunrast.c b/libavcodec/sunrast.c
index a373df7..d9918f4 100644
--- a/libavcodec/sunrast.c
+++ b/libavcodec/sunrast.c
@@ -61,10 +61,6 @@
av_log(avctx, AV_LOG_ERROR, "invalid (compression) type\n");
return AVERROR_INVALIDDATA;
}
- if (av_image_check_size(w, h, 0, avctx)) {
- av_log(avctx, AV_LOG_ERROR, "invalid image size\n");
- return AVERROR_INVALIDDATA;
- }
if (maptype == RMT_RAW) {
avpriv_request_sample(avctx, "Unknown colormap type");
return AVERROR_PATCHWELCOME;
@@ -100,8 +96,10 @@
return AVERROR_INVALIDDATA;
}
- if (w != avctx->width || h != avctx->height)
- avcodec_set_dimensions(avctx, w, h);
+ ret = ff_set_dimensions(avctx, w, h);
+ if (ret < 0)
+ return ret;
+
if ((ret = ff_get_buffer(avctx, p, 0)) < 0)
return ret;
diff --git a/libavcodec/sunrastenc.c b/libavcodec/sunrastenc.c
index 0879ce6..a55e3d4 100644
--- a/libavcodec/sunrastenc.c
+++ b/libavcodec/sunrastenc.c
@@ -198,6 +198,12 @@
return 0;
}
+static av_cold int sunrast_encode_close(AVCodecContext *avctx)
+{
+ av_frame_free(&avctx->coded_frame);
+ return 0;
+}
+
static const AVCodecDefault sunrast_defaults[] = {
{ "coder", "rle" },
{ NULL },
@@ -210,6 +216,7 @@
.id = AV_CODEC_ID_SUNRAST,
.priv_data_size = sizeof(SUNRASTContext),
.init = sunrast_encode_init,
+ .close = sunrast_encode_close,
.encode2 = sunrast_encode_frame,
.defaults = sunrast_defaults,
.pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_BGR24,
diff --git a/libavcodec/svq1dec.c b/libavcodec/svq1dec.c
index 5193798..1e7ab49 100644
--- a/libavcodec/svq1dec.c
+++ b/libavcodec/svq1dec.c
@@ -593,8 +593,8 @@
skip_bits1(bitbuf);
skip_bits(bitbuf, 2);
- while (get_bits1(bitbuf))
- skip_bits(bitbuf, 8);
+ if (skip_1stop_8data_bits(bitbuf) < 0)
+ return AVERROR_INVALIDDATA;
}
s->width = width;
@@ -638,7 +638,10 @@
av_dlog(avctx, "Error in svq1_decode_frame_header %i\n", result);
return result;
}
- avcodec_set_dimensions(avctx, s->width, s->height);
+
+ result = ff_set_dimensions(avctx, s->width, s->height);
+ if (result < 0)
+ return result;
if ((avctx->skip_frame >= AVDISCARD_NONREF && s->nonref) ||
(avctx->skip_frame >= AVDISCARD_NONKEY &&
@@ -739,7 +742,7 @@
int i;
int offset = 0;
- s->prev = avcodec_alloc_frame();
+ s->prev = av_frame_alloc();
if (!s->prev)
return AVERROR(ENOMEM);
diff --git a/libavcodec/svq1enc.c b/libavcodec/svq1enc.c
index a6c94ad..2d7e848 100644
--- a/libavcodec/svq1enc.c
+++ b/libavcodec/svq1enc.c
@@ -45,9 +45,8 @@
AVCodecContext *avctx;
DSPContext dsp;
HpelDSPContext hdsp;
- AVFrame picture;
- AVFrame current_picture;
- AVFrame last_picture;
+ AVFrame *current_picture;
+ AVFrame *last_picture;
PutBitContext pb;
GetBitContext gb;
@@ -264,13 +263,14 @@
unsigned char *decoded_plane,
int width, int height, int src_stride, int stride)
{
+ const AVFrame *f = s->avctx->coded_frame;
int x, y;
int i;
int block_width, block_height;
int level;
int threshold[6];
uint8_t *src = s->scratchbuf + stride * 16;
- const int lambda = (s->picture.quality * s->picture.quality) >>
+ const int lambda = (f->quality * f->quality) >>
(2 * FF_LAMBDA_SHIFT);
/* figure out the acceptable level thresholds in advance */
@@ -281,7 +281,7 @@
block_width = (width + 15) / 16;
block_height = (height + 15) / 16;
- if (s->picture.pict_type == AV_PICTURE_TYPE_P) {
+ if (f->pict_type == AV_PICTURE_TYPE_P) {
s->m.avctx = s->avctx;
s->m.current_picture_ptr = &s->m.current_picture;
s->m.last_picture_ptr = &s->m.last_picture;
@@ -297,13 +297,13 @@
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 = s->picture.pict_type;
+ s->m.pict_type = f->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.out_format = FMT_H263;
// s->m.unrestricted_mv = 1;
- s->m.lambda = s->picture.quality;
+ s->m.lambda = f->quality;
s->m.qscale = s->m.lambda * 139 +
FF_LAMBDA_SCALE * 64 >>
FF_LAMBDA_SHIFT + 7;
@@ -396,13 +396,13 @@
ff_init_block_index(&s->m);
ff_update_block_index(&s->m);
- if (s->picture.pict_type == AV_PICTURE_TYPE_I ||
+ if (f->pict_type == AV_PICTURE_TYPE_I ||
(s->m.mb_type[x + y * s->m.mb_stride] &
CANDIDATE_MB_TYPE_INTRA)) {
for (i = 0; i < 6; i++)
init_put_bits(&s->reorder_pb[i], reorder_buffer[0][i],
7 * 32);
- if (s->picture.pict_type == AV_PICTURE_TYPE_P) {
+ if (f->pict_type == AV_PICTURE_TYPE_P) {
const uint8_t *vlc = ff_svq1_block_type_vlc[SVQ1_BLOCK_INTRA];
put_bits(&s->reorder_pb[5], vlc[1], vlc[0]);
score[0] = vlc[1] * lambda;
@@ -418,7 +418,7 @@
best = 0;
- if (s->picture.pict_type == AV_PICTURE_TYPE_P) {
+ if (f->pict_type == AV_PICTURE_TYPE_P) {
const uint8_t *vlc = ff_svq1_block_type_vlc[SVQ1_BLOCK_INTER];
int mx, my, pred_x, pred_y, dxy;
int16_t *motion_ptr;
@@ -498,13 +498,48 @@
return 0;
}
+static av_cold int svq1_encode_end(AVCodecContext *avctx)
+{
+ SVQ1Context *const s = avctx->priv_data;
+ int i;
+
+ av_log(avctx, AV_LOG_DEBUG, "RD: %f\n",
+ s->rd_total / (double)(avctx->width * avctx->height *
+ avctx->frame_number));
+
+ av_freep(&s->m.me.scratchpad);
+ av_freep(&s->m.me.map);
+ av_freep(&s->m.me.score_map);
+ av_freep(&s->mb_type);
+ av_freep(&s->dummy);
+ av_freep(&s->scratchbuf);
+
+ for (i = 0; i < 3; i++) {
+ av_freep(&s->motion_val8[i]);
+ av_freep(&s->motion_val16[i]);
+ }
+
+ av_frame_free(&s->current_picture);
+ av_frame_free(&s->last_picture);
+ av_frame_free(&avctx->coded_frame);
+
+ return 0;
+}
+
static av_cold int svq1_encode_init(AVCodecContext *avctx)
{
SVQ1Context *const s = avctx->priv_data;
ff_dsputil_init(&s->dsp, avctx);
ff_hpeldsp_init(&s->hdsp, avctx->flags);
- avctx->coded_frame = &s->picture;
+
+ avctx->coded_frame = av_frame_alloc();
+ s->current_picture = av_frame_alloc();
+ s->last_picture = av_frame_alloc();
+ if (!avctx->coded_frame || !s->current_picture || !s->last_picture) {
+ svq1_encode_end(avctx);
+ return AVERROR(ENOMEM);
+ }
s->frame_width = avctx->width;
s->frame_height = avctx->height;
@@ -536,8 +571,7 @@
const AVFrame *pict, int *got_packet)
{
SVQ1Context *const s = avctx->priv_data;
- AVFrame *const p = &s->picture;
- AVFrame temp;
+ AVFrame *const p = avctx->coded_frame;
int i, ret;
if ((ret = ff_alloc_packet2(avctx, pkt, s->y_block_width * s->y_block_height *
@@ -549,35 +583,33 @@
return -1;
}
- if (!s->current_picture.data[0]) {
- if ((ret = ff_get_buffer(avctx, &s->current_picture, 0))< 0 ||
- (ret = ff_get_buffer(avctx, &s->last_picture, 0)) < 0) {
+ if (!s->current_picture->data[0]) {
+ if ((ret = ff_get_buffer(avctx, s->current_picture, 0))< 0 ||
+ (ret = ff_get_buffer(avctx, s->last_picture, 0)) < 0) {
return ret;
}
- s->scratchbuf = av_malloc(s->current_picture.linesize[0] * 16 * 2);
+ s->scratchbuf = av_malloc(s->current_picture->linesize[0] * 16 * 2);
}
- av_frame_move_ref(&temp, &s->current_picture);
- av_frame_move_ref(&s->current_picture, &s->last_picture);
- av_frame_move_ref(&s->last_picture, &temp);
+ FFSWAP(AVFrame*, s->current_picture, s->last_picture);
init_put_bits(&s->pb, pkt->data, pkt->size);
- *p = *pict;
p->pict_type = avctx->gop_size && avctx->frame_number % avctx->gop_size ?
AV_PICTURE_TYPE_P : AV_PICTURE_TYPE_I;
p->key_frame = p->pict_type == AV_PICTURE_TYPE_I;
+ p->quality = pict->quality;
svq1_write_header(s, p->pict_type);
for (i = 0; i < 3; i++)
if (svq1_encode_plane(s, i,
- s->picture.data[i],
- s->last_picture.data[i],
- s->current_picture.data[i],
+ pict->data[i],
+ s->last_picture->data[i],
+ s->current_picture->data[i],
s->frame_width / (i ? 4 : 1),
s->frame_height / (i ? 4 : 1),
- s->picture.linesize[i],
- s->current_picture.linesize[i]) < 0)
+ pict->linesize[i],
+ s->current_picture->linesize[i]) < 0)
return -1;
// avpriv_align_put_bits(&s->pb);
@@ -594,33 +626,6 @@
return 0;
}
-static av_cold int svq1_encode_end(AVCodecContext *avctx)
-{
- SVQ1Context *const s = avctx->priv_data;
- int i;
-
- av_log(avctx, AV_LOG_DEBUG, "RD: %f\n",
- s->rd_total / (double)(avctx->width * avctx->height *
- avctx->frame_number));
-
- av_freep(&s->m.me.scratchpad);
- av_freep(&s->m.me.map);
- av_freep(&s->m.me.score_map);
- av_freep(&s->mb_type);
- av_freep(&s->dummy);
- av_freep(&s->scratchbuf);
-
- for (i = 0; i < 3; i++) {
- av_freep(&s->motion_val8[i]);
- av_freep(&s->motion_val16[i]);
- }
-
- av_frame_unref(&s->current_picture);
- av_frame_unref(&s->last_picture);
-
- return 0;
-}
-
AVCodec ff_svq1_encoder = {
.name = "svq1",
.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 89bb616..189be48 100644
--- a/libavcodec/svq3.c
+++ b/libavcodec/svq3.c
@@ -317,8 +317,8 @@
src = pic->f.data[0] + mx + my * h->linesize;
if (emu) {
- h->vdsp.emulated_edge_mc(h->edge_emu_buffer, h->linesize,
- src, h->linesize,
+ h->vdsp.emulated_edge_mc(h->edge_emu_buffer, src,
+ h->linesize, h->linesize,
width + 1, height + 1,
mx, my, s->h_edge_pos, s->v_edge_pos);
src = h->edge_emu_buffer;
@@ -344,8 +344,8 @@
src = pic->f.data[i] + mx + my * h->uvlinesize;
if (emu) {
- h->vdsp.emulated_edge_mc(h->edge_emu_buffer, h->uvlinesize,
- src, h->uvlinesize,
+ h->vdsp.emulated_edge_mc(h->edge_emu_buffer, src,
+ h->uvlinesize, h->uvlinesize,
width + 1, height + 1,
mx, my, (s->h_edge_pos >> 1),
s->v_edge_pos >> 1);
@@ -838,8 +838,8 @@
skip_bits1(&h->gb);
skip_bits(&h->gb, 2);
- while (get_bits1(&h->gb))
- skip_bits(&h->gb, 8);
+ if (skip_1stop_8data_bits(&h->gb) < 0)
+ return AVERROR_INVALIDDATA;
/* reset intra predictors and invalidate motion vector references */
if (h->mb_x > 0) {
@@ -970,8 +970,8 @@
/* unknown field */
skip_bits1(&gb);
- while (get_bits1(&gb))
- skip_bits(&gb, 8);
+ if (skip_1stop_8data_bits(&gb) < 0)
+ return AVERROR_INVALIDDATA;
s->unknown_flag = get_bits1(&gb);
avctx->has_b_frames = !h->low_delay;
@@ -1125,8 +1125,7 @@
h->mb_x = h->mb_y = h->mb_xy = 0;
if (s->watermark_key) {
- av_fast_malloc(&s->buf, &s->buf_size,
- buf_size+FF_INPUT_BUFFER_PADDING_SIZE);
+ av_fast_padded_malloc(&s->buf, &s->buf_size, buf_size);
if (!s->buf)
return AVERROR(ENOMEM);
memcpy(s->buf, avpkt->data, buf_size);
diff --git a/libavcodec/takdec.c b/libavcodec/takdec.c
index 1017032..fcbe10a 100644
--- a/libavcodec/takdec.c
+++ b/libavcodec/takdec.c
@@ -686,11 +686,12 @@
if ((ret = ff_tak_decode_frame_header(avctx, gb, &s->ti, 0)) < 0)
return ret;
- if (avctx->err_recognition & AV_EF_CRCCHECK) {
+ if (avctx->err_recognition & (AV_EF_CRCCHECK|AV_EF_COMPLIANT)) {
hsize = get_bits_count(gb) / 8;
if (ff_tak_check_crc(pkt->data, hsize)) {
av_log(avctx, AV_LOG_ERROR, "CRC error\n");
- return AVERROR_INVALIDDATA;
+ if (avctx->err_recognition & AV_EF_EXPLODE)
+ return AVERROR_INVALIDDATA;
}
}
@@ -861,11 +862,12 @@
else if (get_bits_left(gb) > 0)
av_log(avctx, AV_LOG_DEBUG, "underread\n");
- if (avctx->err_recognition & AV_EF_CRCCHECK) {
+ if (avctx->err_recognition & (AV_EF_CRCCHECK | AV_EF_COMPLIANT)) {
if (ff_tak_check_crc(pkt->data + hsize,
get_bits_count(gb) / 8 - hsize)) {
av_log(avctx, AV_LOG_ERROR, "CRC error\n");
- return AVERROR_INVALIDDATA;
+ if (avctx->err_recognition & AV_EF_EXPLODE)
+ return AVERROR_INVALIDDATA;
}
}
diff --git a/libavcodec/targa.c b/libavcodec/targa.c
index b3616c2..b0c9b55 100644
--- a/libavcodec/targa.c
+++ b/libavcodec/targa.c
@@ -173,10 +173,9 @@
return AVERROR_INVALIDDATA;
}
- if ((ret = av_image_check_size(w, h, 0, avctx)) < 0)
+ if ((ret = ff_set_dimensions(avctx, w, h)) < 0)
return ret;
- if (w != avctx->width || h != avctx->height)
- avcodec_set_dimensions(avctx, w, h);
+
if ((ret = ff_get_buffer(avctx, p, 0)) < 0)
return ret;
p->pict_type = AV_PICTURE_TYPE_I;
diff --git a/libavcodec/targaenc.c b/libavcodec/targaenc.c
index 108e148..d4483ec 100644
--- a/libavcodec/targaenc.c
+++ b/libavcodec/targaenc.c
@@ -170,11 +170,31 @@
return 0;
}
+static av_cold int targa_encode_init(AVCodecContext *avctx)
+{
+ avctx->coded_frame = av_frame_alloc();
+ if (!avctx->coded_frame)
+ return AVERROR(ENOMEM);
+
+ avctx->coded_frame->key_frame = 1;
+ avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
+
+ return 0;
+}
+
+static av_cold int targa_encode_close(AVCodecContext *avctx)
+{
+ av_frame_free(&avctx->coded_frame);
+ return 0;
+}
+
AVCodec ff_targa_encoder = {
.name = "targa",
.long_name = NULL_IF_CONFIG_SMALL("Truevision Targa image"),
.type = AVMEDIA_TYPE_VIDEO,
.id = AV_CODEC_ID_TARGA,
+ .init = targa_encode_init,
+ .close = targa_encode_close,
.encode2 = targa_encode_frame,
.pix_fmts = (const enum AVPixelFormat[]){
AV_PIX_FMT_BGR24, AV_PIX_FMT_BGRA, AV_PIX_FMT_RGB555LE, AV_PIX_FMT_GRAY8, AV_PIX_FMT_PAL8,
diff --git a/libavcodec/textdec.c b/libavcodec/textdec.c
index a8f9e40..d904023 100644
--- a/libavcodec/textdec.c
+++ b/libavcodec/textdec.c
@@ -41,59 +41,20 @@
{ NULL }
};
-static int text_event_to_ass(const AVCodecContext *avctx, AVBPrint *buf,
- const char *p, const char *p_end)
-{
- const TextContext *text = avctx->priv_data;
-
- for (; p < p_end && *p; p++) {
-
- /* forced custom line breaks, not accounted as "normal" EOL */
- if (text->linebreaks && strchr(text->linebreaks, *p)) {
- av_bprintf(buf, "\\N");
-
- /* standard ASS escaping so random characters don't get mis-interpreted
- * as ASS */
- } else if (!text->keep_ass_markup && strchr("{}\\", *p)) {
- av_bprintf(buf, "\\%c", *p);
-
- /* some packets might end abruptly (no \0 at the end, like for example
- * in some cases of demuxing from a classic video container), some
- * might be terminated with \n or \r\n which we have to remove (for
- * consistency with those who haven't), and we also have to deal with
- * evil cases such as \r at the end of the buffer (and no \0 terminated
- * character) */
- } else if (p[0] == '\n') {
- /* some stuff left so we can insert a line break */
- if (p < p_end - 1)
- av_bprintf(buf, "\\N");
- } else if (p[0] == '\r' && p < p_end - 1 && p[1] == '\n') {
- /* \r followed by a \n, we can skip it. We don't insert the \N yet
- * because we don't know if it is followed by more text */
- continue;
-
- /* finally, a sane character */
- } else {
- av_bprint_chars(buf, *p, 1);
- }
- }
- av_bprintf(buf, "\r\n");
- return 0;
-}
-
static int text_decode_frame(AVCodecContext *avctx, void *data,
int *got_sub_ptr, AVPacket *avpkt)
{
AVBPrint buf;
AVSubtitle *sub = data;
const char *ptr = avpkt->data;
+ const TextContext *text = avctx->priv_data;
const int ts_start = av_rescale_q(avpkt->pts, avctx->time_base, (AVRational){1,100});
const int ts_duration = avpkt->duration != -1 ?
av_rescale_q(avpkt->duration, avctx->time_base, (AVRational){1,100}) : -1;
av_bprint_init(&buf, 0, AV_BPRINT_SIZE_UNLIMITED);
- if (ptr && avpkt->size > 0 && *ptr &&
- !text_event_to_ass(avctx, &buf, ptr, ptr + avpkt->size)) {
+ if (ptr && avpkt->size > 0 && *ptr) {
+ ff_ass_bprint_text_event(&buf, ptr, avpkt->size, text->linebreaks, text->keep_ass_markup);
if (!av_bprint_is_complete(&buf)) {
av_bprint_finalize(&buf, NULL);
return AVERROR(ENOMEM);
diff --git a/libavcodec/thread.h b/libavcodec/thread.h
index 0dc04e0..c848d7a 100644
--- a/libavcodec/thread.h
+++ b/libavcodec/thread.h
@@ -135,4 +135,9 @@
int ff_thread_init(AVCodecContext *s);
void ff_thread_free(AVCodecContext *s);
+int ff_alloc_entries(AVCodecContext *avctx, int count);
+void ff_reset_entries(AVCodecContext *avctx);
+void ff_thread_report_progress2(AVCodecContext *avctx, int field, int thread, int n);
+void ff_thread_await_progress2(AVCodecContext *avctx, int field, int thread, int shift);
+
#endif /* AVCODEC_THREAD_H */
diff --git a/libavcodec/tiertexseqv.c b/libavcodec/tiertexseqv.c
index 0da9afd..7c62208 100644
--- a/libavcodec/tiertexseqv.c
+++ b/libavcodec/tiertexseqv.c
@@ -32,7 +32,7 @@
typedef struct SeqVideoContext {
AVCodecContext *avctx;
- AVFrame frame;
+ AVFrame *frame;
} SeqVideoContext;
@@ -93,14 +93,14 @@
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];
+ dst += seq->frame->linesize[0];
}
break;
case 2:
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];
+ dst[b * seq->frame->linesize[0]] = block[i * 8 + b];
++dst;
}
break;
@@ -117,7 +117,7 @@
for (b = 0; b < 8; b++) {
for (i = 0; i < 8; i++)
dst[i] = color_table[get_bits(&gb, bits)];
- dst += seq->frame.linesize[0];
+ dst += seq->frame->linesize[0];
}
}
@@ -137,7 +137,7 @@
for (i = 0; i < 8; i++) {
memcpy(dst, src, 8);
src += 8;
- dst += seq->frame.linesize[0];
+ dst += seq->frame->linesize[0];
}
return src;
@@ -154,7 +154,7 @@
if (src_end - src < 2)
return NULL;
pos = *src++;
- offset = ((pos >> 3) & 7) * seq->frame.linesize[0] + (pos & 7);
+ offset = ((pos >> 3) & 7) * seq->frame->linesize[0] + (pos & 7);
dst[offset] = *src++;
} while (!(pos & 0x80));
@@ -173,7 +173,7 @@
flags = *data++;
if (flags & 1) {
- palette = (uint32_t *)seq->frame.data[1];
+ palette = (uint32_t *)seq->frame->data[1];
if (data_end - data < 256 * 3)
return AVERROR_INVALIDDATA;
for (i = 0; i < 256; i++) {
@@ -181,7 +181,7 @@
c[j] = (*data << 2) | (*data >> 4);
palette[i] = 0xFFU << 24 | AV_RB24(c);
}
- seq->frame.palette_has_changed = 1;
+ seq->frame->palette_has_changed = 1;
}
if (flags & 2) {
@@ -190,7 +190,7 @@
init_get_bits(&gb, data, 128 * 8); data += 128;
for (y = 0; y < 128; y += 8)
for (x = 0; x < 256; x += 8) {
- dst = &seq->frame.data[0][y * seq->frame.linesize[0] + x];
+ dst = &seq->frame->data[0][y * seq->frame->linesize[0] + x];
op = get_bits(&gb, 2);
switch (op) {
case 1:
@@ -217,7 +217,9 @@
seq->avctx = avctx;
avctx->pix_fmt = AV_PIX_FMT_PAL8;
- avcodec_get_frame_defaults(&seq->frame);
+ seq->frame = av_frame_alloc();
+ if (!seq->frame)
+ return AVERROR(ENOMEM);
return 0;
}
@@ -232,13 +234,13 @@
SeqVideoContext *seq = avctx->priv_data;
- if ((ret = ff_reget_buffer(avctx, &seq->frame)) < 0)
+ if ((ret = ff_reget_buffer(avctx, seq->frame)) < 0)
return ret;
if (seqvideo_decode(seq, buf, buf_size))
return AVERROR_INVALIDDATA;
- if ((ret = av_frame_ref(data, &seq->frame)) < 0)
+ if ((ret = av_frame_ref(data, seq->frame)) < 0)
return ret;
*got_frame = 1;
@@ -249,7 +251,7 @@
{
SeqVideoContext *seq = avctx->priv_data;
- av_frame_unref(&seq->frame);
+ av_frame_free(&seq->frame);
return 0;
}
diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c
index 0e8ddec..cd20967 100644
--- a/libavcodec/tiff.c
+++ b/libavcodec/tiff.c
@@ -546,9 +546,9 @@
return AVERROR_INVALIDDATA;
}
if (s->width != s->avctx->width || s->height != s->avctx->height) {
- if ((ret = av_image_check_size(s->width, s->height, 0, s->avctx)) < 0)
+ ret = ff_set_dimensions(s->avctx, s->width, s->height);
+ if (ret < 0)
return ret;
- avcodec_set_dimensions(s->avctx, s->width, s->height);
}
if ((ret = ff_thread_get_buffer(s->avctx, frame, 0)) < 0)
return ret;
@@ -578,28 +578,21 @@
goto end;
}
+ off = bytestream2_tell(&s->gb);
if (count == 1) {
switch (type) {
case TIFF_BYTE:
case TIFF_SHORT:
- value = ff_tget(&s->gb, type, s->le);
- break;
case TIFF_LONG:
- off = ff_tget_long(&s->gb, s->le);
- value = off;
+ value = ff_tget(&s->gb, type, s->le);
break;
case TIFF_STRING:
if (count <= 4) {
break;
}
default:
- off = bytestream2_tell(&s->gb);
value = UINT_MAX;
}
- } else {
- if (type_sizes[type] * count > 4) {
- off = bytestream2_tell(&s->gb);
- }
}
switch (tag) {
@@ -622,9 +615,6 @@
else {
switch (type) {
case TIFF_BYTE:
- s->bpp = (off & 0xFF) + ((off >> 8) & 0xFF) +
- ((off >> 16) & 0xFF) + ((off >> 24) & 0xFF);
- break;
case TIFF_SHORT:
case TIFF_LONG:
s->bpp = 0;
diff --git a/libavcodec/tiff_common.c b/libavcodec/tiff_common.c
index 6a10d71..ce91219 100644
--- a/libavcodec/tiff_common.c
+++ b/libavcodec/tiff_common.c
@@ -219,7 +219,7 @@
char *ap;
int i;
- if (count >= INT_MAX / sizeof(int8_t) || count <= 0)
+ if (count >= INT_MAX / sizeof(int8_t) || count < 0)
return AVERROR_INVALIDDATA;
if (bytestream2_get_bytes_left(gb) < count * sizeof(int8_t))
return AVERROR_INVALIDDATA;
diff --git a/libavcodec/tiffenc.c b/libavcodec/tiffenc.c
index f5d04ea..7b1e510 100644
--- a/libavcodec/tiffenc.c
+++ b/libavcodec/tiffenc.c
@@ -52,7 +52,6 @@
typedef struct TiffEncoderContext {
AVClass *class; ///< for private options
AVCodecContext *avctx;
- AVFrame picture;
int width; ///< picture width
int height; ///< picture height
@@ -195,9 +194,9 @@
}
}
-static void pack_yuv(TiffEncoderContext *s, uint8_t *dst, int lnum)
+static void pack_yuv(TiffEncoderContext *s, const AVFrame *p,
+ uint8_t *dst, int lnum)
{
- AVFrame *p = &s->picture;
int i, j, k;
int w = (s->width - 1) / s->subsampling[0] + 1;
uint8_t *pu = &p->data[1][lnum / s->subsampling[1] * p->linesize[1]];
@@ -223,24 +222,12 @@
}
}
-static av_cold int encode_init(AVCodecContext *avctx)
-{
- TiffEncoderContext *s = avctx->priv_data;
-
- avctx->coded_frame = &s->picture;
- avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
- avctx->coded_frame->key_frame = 1;
- s->avctx = avctx;
-
- return 0;
-}
-
static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
const AVFrame *pict, int *got_packet)
{
const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
TiffEncoderContext *s = avctx->priv_data;
- AVFrame *const p = &s->picture;
+ const AVFrame *const p = pict;
int i;
uint8_t *ptr;
uint8_t *offset;
@@ -252,8 +239,6 @@
int is_yuv = 0, alpha = 0;
int shift_h, shift_v;
- *p = *pict;
-
s->width = avctx->width;
s->height = avctx->height;
s->subsampling[0] = 1;
@@ -373,7 +358,7 @@
zn = 0;
for (j = 0; j < s->rps; j++) {
if (is_yuv) {
- pack_yuv(s, s->yuv_line, j);
+ pack_yuv(s, p, s->yuv_line, j);
memcpy(zbuf + zn, s->yuv_line, bytes_per_row);
j += s->subsampling[1] - 1;
} else
@@ -409,7 +394,7 @@
s->strip_offsets[i / s->rps] = ptr - pkt->data;
}
if (is_yuv) {
- pack_yuv(s, s->yuv_line, i);
+ pack_yuv(s, p, s->yuv_line, i);
ret = encode_strip(s, s->yuv_line, ptr, bytes_per_row, s->compr);
i += s->subsampling[1] - 1;
} else
@@ -497,10 +482,26 @@
return ret < 0 ? ret : 0;
}
+static av_cold int encode_init(AVCodecContext *avctx)
+{
+ TiffEncoderContext *s = avctx->priv_data;
+
+ avctx->coded_frame = av_frame_alloc();
+ if (!avctx->coded_frame)
+ return AVERROR(ENOMEM);
+
+ avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
+ avctx->coded_frame->key_frame = 1;
+ s->avctx = avctx;
+
+ return 0;
+}
+
static av_cold int encode_close(AVCodecContext *avctx)
{
TiffEncoderContext *s = avctx->priv_data;
+ av_frame_free(&avctx->coded_frame);
av_freep(&s->strip_sizes);
av_freep(&s->strip_offsets);
av_freep(&s->yuv_line);
@@ -536,8 +537,8 @@
.id = AV_CODEC_ID_TIFF,
.priv_data_size = sizeof(TiffEncoderContext),
.init = encode_init,
- .encode2 = encode_frame,
.close = encode_close,
+ .encode2 = encode_frame,
.pix_fmts = (const enum AVPixelFormat[]) {
AV_PIX_FMT_RGB24, AV_PIX_FMT_PAL8, AV_PIX_FMT_GRAY8,
AV_PIX_FMT_GRAY8A, AV_PIX_FMT_GRAY16LE,
diff --git a/libavcodec/timecode.c b/libavcodec/timecode.c
deleted file mode 100644
index f9862e5..0000000
--- a/libavcodec/timecode.c
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * Copyright (C) 2006 Smartjog S.A.S, Baptiste Coudurier <baptiste.coudurier@gmail.com>
- * Copyright (C) 2011 Smartjog S.A.S, Clément Bœsch <clement.boesch@smartjog.com>
- *
- * This file is part of FFmpeg.
- *
- * FFmpeg is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * FFmpeg is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with FFmpeg; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/**
- * @file
- * Timecode helpers
- * This *private* API is deprecated, please use the one available in libavutil instead.
- */
-
-#include "version.h"
-
-#if FF_API_OLD_TIMECODE
-
-#include <stdio.h>
-#include "timecode.h"
-#include "libavutil/log.h"
-
-int avpriv_framenum_to_drop_timecode(int frame_num)
-{
- /* only works for NTSC 29.97 */
- int d = frame_num / 17982;
- int m = frame_num % 17982;
- //if (m < 2) m += 2; /* not needed since -2,-1 / 1798 in C returns 0 */
- return frame_num + 18 * d + 2 * ((m - 2) / 1798);
-}
-
-uint32_t avpriv_framenum_to_smpte_timecode(unsigned frame, int fps, int drop)
-{
- return (0 << 31) | // color frame flag
- (drop << 30) | // drop frame flag
- ( ((frame % fps) / 10) << 28) | // tens of frames
- ( ((frame % fps) % 10) << 24) | // units of frames
- (0 << 23) | // field phase (NTSC), b0 (PAL)
- ((((frame / fps) % 60) / 10) << 20) | // tens of seconds
- ((((frame / fps) % 60) % 10) << 16) | // units of seconds
- (0 << 15) | // b0 (NTSC), b2 (PAL)
- ((((frame / (fps * 60)) % 60) / 10) << 12) | // tens of minutes
- ((((frame / (fps * 60)) % 60) % 10) << 8) | // units of minutes
- (0 << 7) | // b1
- (0 << 6) | // b2 (NTSC), field phase (PAL)
- ((((frame / (fps * 3600) % 24)) / 10) << 4) | // tens of hours
- ( (frame / (fps * 3600) % 24)) % 10; // units of hours
-}
-
-int avpriv_check_timecode_rate(void *avcl, AVRational rate, int drop)
-{
- int fps;
-
- if (!rate.num || !rate.den) {
- av_log(avcl, AV_LOG_ERROR, "Timecode frame rate must be specified\n");
- return -1;
- }
- fps = (rate.num + rate.den/2) / rate.den;
- if (drop && fps != 30) {
- av_log(avcl, AV_LOG_ERROR, "Drop frame is only allowed with 30000/1001 FPS\n");
- return -2;
- }
- switch (fps) {
- case 24:
- case 25:
- case 30: return 0;
-
- default:
- av_log(avcl, AV_LOG_ERROR, "Timecode frame rate not supported\n");
- return -3;
- }
-}
-
-char *avpriv_timecode_to_string(char *buf, const struct ff_timecode *tc, unsigned frame)
-{
- int frame_num = tc->start + frame;
- int fps = (tc->rate.num + tc->rate.den/2) / tc->rate.den;
- int hh, mm, ss, ff, neg = 0;
-
- if (tc->drop)
- frame_num = avpriv_framenum_to_drop_timecode(frame_num);
- if (frame_num < 0) {
- frame_num = -frame_num;
- neg = 1;
- }
- ff = frame_num % fps;
- ss = frame_num / fps % 60;
- mm = frame_num / (fps*60) % 60;
- hh = frame_num / (fps*3600);
- snprintf(buf, 16, "%s%02d:%02d:%02d%c%02d",
- neg ? "-" : "",
- hh, mm, ss, tc->drop ? ';' : ':', ff);
- return buf;
-}
-
-int avpriv_init_smpte_timecode(void *avcl, struct ff_timecode *tc)
-{
- int hh, mm, ss, ff, fps, ret;
- char c;
-
- if (sscanf(tc->str, "%d:%d:%d%c%d", &hh, &mm, &ss, &c, &ff) != 5) {
- av_log(avcl, AV_LOG_ERROR, "unable to parse timecode, "
- "syntax: hh:mm:ss[:;.]ff\n");
- return -1;
- }
-
- tc->drop = c != ':'; // drop if ';', '.', ...
-
- ret = avpriv_check_timecode_rate(avcl, tc->rate, tc->drop);
- if (ret < 0)
- return ret;
-
- fps = (tc->rate.num + tc->rate.den/2) / tc->rate.den;
- tc->start = (hh*3600 + mm*60 + ss) * fps + ff;
-
- if (tc->drop) { /* adjust frame number */
- int tmins = 60*hh + mm;
- tc->start -= 2 * (tmins - tmins/10);
- }
- return 0;
-}
-
-int ff_framenum_to_drop_timecode(int frame_num)
-{
- return avpriv_framenum_to_drop_timecode(frame_num);
-}
-
-uint32_t ff_framenum_to_smtpe_timecode(unsigned frame, int fps, int drop)
-{
- return avpriv_framenum_to_smpte_timecode(frame, fps, drop);
-}
-
-int ff_init_smtpe_timecode(void *avcl, struct ff_timecode *tc)
-{
- return avpriv_init_smpte_timecode(avcl, tc);
-}
-#endif
diff --git a/libavcodec/timecode.h b/libavcodec/timecode.h
deleted file mode 100644
index 8bc69e9..0000000
--- a/libavcodec/timecode.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (C) 2006 Smartjog S.A.S, Baptiste Coudurier <baptiste.coudurier@gmail.com>
- * Copyright (C) 2011 Smartjog S.A.S, Clément Bœsch <clement.boesch@smartjog.com>
- *
- * This file is part of FFmpeg.
- *
- * FFmpeg is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * FFmpeg is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with FFmpeg; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/**
- * @file
- * Timecode helpers header
- * This *private* API is deprecated, please use the one available in libavutil instead.
- */
-
-#ifndef AVCODEC_TIMECODE_H
-#define AVCODEC_TIMECODE_H
-
-#include "version.h"
-
-#if FF_API_OLD_TIMECODE
-
-#include <stdint.h>
-#include "avcodec.h"
-#include "libavutil/rational.h"
-
-#define TIMECODE_OPT(ctx, flags) \
- "timecode", "set timecode value following hh:mm:ss[:;.]ff format, " \
- "use ';' or '.' before frame number for drop frame", \
- offsetof(ctx, tc.str), \
- AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX, flags
-
-struct ff_timecode {
- char *str; ///< string following the hh:mm:ss[:;.]ff format
- int start; ///< timecode frame start
- int drop; ///< drop flag (1 if drop, else 0)
- AVRational rate; ///< Frame rate in rational form
-};
-
-/**
- * @brief Adjust frame number for NTSC drop frame time code
- * @param frame_num Actual frame number to adjust
- * @return Adjusted frame number
- * @warning Adjustment is only valid in NTSC 29.97
- */
-int avpriv_framenum_to_drop_timecode(int frame_num);
-
-/**
- * @brief Convert frame id (timecode) to SMPTE 12M binary representation
- * @param frame Frame number
- * @param fps Frame rate
- * @param drop Drop flag
- * @return The actual binary representation
- */
-uint32_t avpriv_framenum_to_smpte_timecode(unsigned frame, int fps, int drop);
-
-/**
- * @brief Load timecode string in buf
- * @param buf Destination buffer
- * @param tc Timecode struct pointer
- * @param frame Frame id (timecode frame is computed with tc->start+frame)
- * @return a pointer to the buf parameter
- * @note timecode representation can be a negative timecode and have
- * more than 24 hours.
- * @note buf must have enough space to store the timecode representation: 16
- * bytes is the minimum required size.
- */
-char *avpriv_timecode_to_string(char *buf, const struct ff_timecode *tc, unsigned frame);
-
-/**
- * Check if timecode rate is valid and consistent with the drop flag.
- *
- * @return 0 on success, negative value on failure
- */
-int avpriv_check_timecode_rate(void *avcl, AVRational rate, int drop);
-
-/**
- * Parse SMTPE 12M time representation (hh:mm:ss[:;.]ff). str and rate fields
- * from tc struct must be set.
- *
- * @param avcl A pointer to an arbitrary struct of which the first field is a
- * pointer to an AVClass struct (used for av_log).
- * @param tc Timecode struct pointer
- * @return 0 on success, negative value on failure
- * @warning Adjustement is only valid in NTSC 29.97
- */
-int avpriv_init_smpte_timecode(void *avcl, struct ff_timecode *tc);
-
-attribute_deprecated int ff_framenum_to_drop_timecode(int frame_num);
-attribute_deprecated uint32_t ff_framenum_to_smtpe_timecode(unsigned frame, int fps, int drop);
-attribute_deprecated int ff_init_smtpe_timecode(void *avcl, struct ff_timecode *tc);
-#endif
-
-#endif /* AVCODEC_TIMECODE_H */
diff --git a/libavcodec/truemotion1.c b/libavcodec/truemotion1.c
index d72cee8..6528a1f 100644
--- a/libavcodec/truemotion1.c
+++ b/libavcodec/truemotion1.c
@@ -44,7 +44,7 @@
typedef struct TrueMotion1Context {
AVCodecContext *avctx;
- AVFrame frame;
+ AVFrame *frame;
const uint8_t *buf;
int size;
@@ -397,15 +397,16 @@
new_pix_fmt = AV_PIX_FMT_RGB555; // RGB565 is supported as well
s->w >>= width_shift;
- if ((ret = av_image_check_size(s->w, s->h, 0, s->avctx)) < 0)
- return ret;
if (s->w != s->avctx->width || s->h != s->avctx->height ||
new_pix_fmt != s->avctx->pix_fmt) {
- av_frame_unref(&s->frame);
+ av_frame_unref(s->frame);
s->avctx->sample_aspect_ratio = (AVRational){ 1 << width_shift, 1 };
s->avctx->pix_fmt = new_pix_fmt;
- avcodec_set_dimensions(s->avctx, s->w, s->h);
+
+ if ((ret = ff_set_dimensions(s->avctx, s->w, s->h)) < 0)
+ return ret;
+
av_fast_malloc(&s->vert_pred, &s->vert_pred_size, s->avctx->width * sizeof(unsigned int));
if (!s->vert_pred)
return AVERROR(ENOMEM);
@@ -470,7 +471,9 @@
// else
// avctx->pix_fmt = AV_PIX_FMT_RGB555;
- avcodec_get_frame_defaults(&s->frame);
+ s->frame = av_frame_alloc();
+ if (!s->frame)
+ return AVERROR(ENOMEM);
/* there is a vertical predictor for each pixel in a line; each vertical
* predictor is 0 to start with */
@@ -516,11 +519,16 @@
index = s->index_stream[index_stream_index++] * 4; \
}
+#define INC_INDEX \
+do { \
+ if (index >= 1023) { \
+ av_log(s->avctx, AV_LOG_ERROR, "Invalid index value.\n"); \
+ return; \
+ } \
+ index++; \
+} while (0)
+
#define APPLY_C_PREDICTOR() \
- if(index > 1023){\
- av_log(s->avctx, AV_LOG_ERROR, " index %d went out of bounds\n", index); \
- return; \
- }\
predictor_pair = s->c_predictor_table[index]; \
horiz_pred += (predictor_pair >> 1); \
if (predictor_pair & 1) { \
@@ -532,16 +540,12 @@
if (predictor_pair & 1) \
GET_NEXT_INDEX() \
else \
- index++; \
+ INC_INDEX; \
} \
} else \
- index++;
+ INC_INDEX;
#define APPLY_C_PREDICTOR_24() \
- if(index > 1023){\
- av_log(s->avctx, AV_LOG_ERROR, " index %d went out of bounds\n", index); \
- return; \
- }\
predictor_pair = s->c_predictor_table[index]; \
horiz_pred += (predictor_pair >> 1); \
if (predictor_pair & 1) { \
@@ -553,17 +557,13 @@
if (predictor_pair & 1) \
GET_NEXT_INDEX() \
else \
- index++; \
+ INC_INDEX; \
} \
} else \
- index++;
+ INC_INDEX;
#define APPLY_Y_PREDICTOR() \
- if(index > 1023){\
- av_log(s->avctx, AV_LOG_ERROR, " index %d went out of bounds\n", index); \
- return; \
- }\
predictor_pair = s->y_predictor_table[index]; \
horiz_pred += (predictor_pair >> 1); \
if (predictor_pair & 1) { \
@@ -575,16 +575,12 @@
if (predictor_pair & 1) \
GET_NEXT_INDEX() \
else \
- index++; \
+ INC_INDEX; \
} \
} else \
- index++;
+ INC_INDEX;
#define APPLY_Y_PREDICTOR_24() \
- if(index > 1023){\
- av_log(s->avctx, AV_LOG_ERROR, " index %d went out of bounds\n", index); \
- return; \
- }\
predictor_pair = s->y_predictor_table[index]; \
horiz_pred += (predictor_pair >> 1); \
if (predictor_pair & 1) { \
@@ -596,10 +592,10 @@
if (predictor_pair & 1) \
GET_NEXT_INDEX() \
else \
- index++; \
+ INC_INDEX; \
} \
} else \
- index++;
+ INC_INDEX;
#define OUTPUT_PIXEL_PAIR() \
*current_pixel_pair = *vert_pred + horiz_pred; \
@@ -613,7 +609,7 @@
unsigned int horiz_pred;
unsigned int *vert_pred;
unsigned int *current_pixel_pair;
- unsigned char *current_line = s->frame.data[0];
+ unsigned char *current_line = s->frame->data[0];
int keyframe = s->flags & FLAG_KEYFRAME;
/* these variables are for managing the stream of macroblock change bits */
@@ -727,7 +723,7 @@
if (((y + 1) & 3) == 0)
mb_change_bits += s->mb_change_bits_row_size;
- current_line += s->frame.linesize[0];
+ current_line += s->frame->linesize[0];
}
}
@@ -739,7 +735,7 @@
unsigned int horiz_pred;
unsigned int *vert_pred;
unsigned int *current_pixel_pair;
- unsigned char *current_line = s->frame.data[0];
+ unsigned char *current_line = s->frame->data[0];
int keyframe = s->flags & FLAG_KEYFRAME;
/* these variables are for managing the stream of macroblock change bits */
@@ -853,7 +849,7 @@
if (((y + 1) & 3) == 0)
mb_change_bits += s->mb_change_bits_row_size;
- current_line += s->frame.linesize[0];
+ current_line += s->frame->linesize[0];
}
}
@@ -872,7 +868,7 @@
if ((ret = truemotion1_decode_header(s)) < 0)
return ret;
- if ((ret = ff_reget_buffer(avctx, &s->frame)) < 0)
+ if ((ret = ff_reget_buffer(avctx, s->frame)) < 0)
return ret;
if (compression_types[s->compression].algorithm == ALGO_RGB24H) {
@@ -881,7 +877,7 @@
truemotion1_decode_16bit(s);
}
- if ((ret = av_frame_ref(data, &s->frame)) < 0)
+ if ((ret = av_frame_ref(data, s->frame)) < 0)
return ret;
*got_frame = 1;
@@ -894,7 +890,7 @@
{
TrueMotion1Context *s = avctx->priv_data;
- av_frame_unref(&s->frame);
+ av_frame_free(&s->frame);
av_freep(&s->vert_pred);
return 0;
diff --git a/libavcodec/truemotion2.c b/libavcodec/truemotion2.c
index 42badcb..a1683f5 100644
--- a/libavcodec/truemotion2.c
+++ b/libavcodec/truemotion2.c
@@ -931,6 +931,7 @@
l->avctx = avctx;
avctx->pix_fmt = AV_PIX_FMT_BGR24;
+
l->pic = av_frame_alloc();
if (!l->pic)
return AVERROR(ENOMEM);
diff --git a/libavcodec/tscc2.c b/libavcodec/tscc2.c
index 9bcfa38..bdc7525 100644
--- a/libavcodec/tscc2.c
+++ b/libavcodec/tscc2.c
@@ -192,7 +192,8 @@
int i, mb_x, q, ret;
int off;
- init_get_bits(&c->gb, buf, buf_size * 8);
+ if ((ret = init_get_bits8(&c->gb, buf, buf_size)) < 0)
+ return ret;
for (mb_x = 0; mb_x < c->mb_width; mb_x++) {
q = c->slice_quants[mb_x + c->mb_width * mb_y];
diff --git a/libavcodec/tta.c b/libavcodec/tta.c
index 6ba3235..b917881 100644
--- a/libavcodec/tta.c
+++ b/libavcodec/tta.c
@@ -251,7 +251,8 @@
int32_t *p;
if (avctx->err_recognition & AV_EF_CRCCHECK) {
- if (buf_size < 4 || tta_check_crc(s, buf, buf_size - 4))
+ if (buf_size < 4 ||
+ (tta_check_crc(s, buf, buf_size - 4) && avctx->err_recognition & AV_EF_EXPLODE))
return AVERROR_INVALIDDATA;
}
diff --git a/libavcodec/twinvq.c b/libavcodec/twinvq.c
index 00b423d..08a7a9f 100644
--- a/libavcodec/twinvq.c
+++ b/libavcodec/twinvq.c
@@ -215,7 +215,7 @@
enum TwinVQFrameType ftype, float *out)
{
const TwinVQModeTab *mtab = tctx->mtab;
- const TwinVQFrameData *bits = &tctx->bits;
+ const TwinVQFrameData *bits = &tctx->bits[tctx->cur_frame];
int i, j;
int sub = mtab->fmode[ftype].sub;
float step = TWINVQ_AMP_MAX / ((1 << TWINVQ_GAIN_BITS) - 1);
@@ -376,11 +376,12 @@
}
static void imdct_output(TwinVQContext *tctx, enum TwinVQFrameType ftype,
- int wtype, float **out)
+ int wtype, float **out, int offset)
{
const TwinVQModeTab *mtab = tctx->mtab;
float *prev_buf = tctx->prev_frame + tctx->last_block_pos[0];
int size1, size2, i;
+ float *out1, *out2;
for (i = 0; i < tctx->avctx->channels; i++)
imdct_and_window(tctx, ftype, wtype,
@@ -394,15 +395,17 @@
size2 = tctx->last_block_pos[0];
size1 = mtab->size - size2;
- memcpy(&out[0][0], prev_buf, size1 * sizeof(out[0][0]));
- memcpy(&out[0][size1], tctx->curr_frame, size2 * sizeof(out[0][0]));
+ out1 = &out[0][0] + offset;
+ memcpy(out1, prev_buf, size1 * sizeof(*out1));
+ memcpy(out1 + size1, tctx->curr_frame, size2 * sizeof(*out1));
if (tctx->avctx->channels == 2) {
- memcpy(&out[1][0], &prev_buf[2 * mtab->size],
- size1 * sizeof(out[1][0]));
- memcpy(&out[1][size1], &tctx->curr_frame[2 * mtab->size],
- size2 * sizeof(out[1][0]));
- tctx->fdsp.butterflies_float(out[0], out[1], mtab->size);
+ out2 = &out[1][0] + offset;
+ memcpy(out2, &prev_buf[2 * mtab->size],
+ size1 * sizeof(*out2));
+ memcpy(out2 + size1, &tctx->curr_frame[2 * mtab->size],
+ size2 * sizeof(*out2));
+ tctx->fdsp.butterflies_float(out1, out2, mtab->size);
}
}
@@ -410,7 +413,7 @@
enum TwinVQFrameType ftype)
{
const TwinVQModeTab *mtab = tctx->mtab;
- TwinVQFrameData *bits = &tctx->bits;
+ TwinVQFrameData *bits = &tctx->bits[tctx->cur_frame];
int channels = tctx->avctx->channels;
int sub = mtab->fmode[ftype].sub;
int block_size = mtab->size / sub;
@@ -483,7 +486,7 @@
/* get output buffer */
if (tctx->discarded_packets >= 2) {
- frame->nb_samples = mtab->size;
+ frame->nb_samples = mtab->size * tctx->frames_per_packet;
if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
return ret;
out = (float **)frame->extended_data;
@@ -498,11 +501,17 @@
if ((ret = tctx->read_bitstream(avctx, tctx, buf, buf_size)) < 0)
return ret;
- read_and_decode_spectrum(tctx, tctx->spectrum, tctx->bits.ftype);
+ for (tctx->cur_frame = 0; tctx->cur_frame < tctx->frames_per_packet;
+ tctx->cur_frame++) {
+ read_and_decode_spectrum(tctx, tctx->spectrum,
+ tctx->bits[tctx->cur_frame].ftype);
- imdct_output(tctx, tctx->bits.ftype, tctx->bits.window_type, out);
+ imdct_output(tctx, tctx->bits[tctx->cur_frame].ftype,
+ tctx->bits[tctx->cur_frame].window_type, out,
+ tctx->cur_frame * mtab->size);
- FFSWAP(float *, tctx->curr_frame, tctx->prev_frame);
+ FFSWAP(float *, tctx->curr_frame, tctx->prev_frame);
+ }
if (tctx->discarded_packets < 2) {
tctx->discarded_packets++;
@@ -512,6 +521,9 @@
*got_frame_ptr = 1;
+ // VQF can deliver packets 1 byte greater than block align
+ if (buf_size == avctx->block_align + 1)
+ return buf_size;
return avctx->block_align;
}
@@ -692,7 +704,7 @@
TWINVQ_WINDOW_TYPE_BITS +
mtab->fmode[i].sub * (bse_bits[i] + n_ch * TWINVQ_SUB_GAIN_BITS);
- if (tctx->codec == TWINVQ_CODEC_METASOUND) {
+ if (tctx->codec == TWINVQ_CODEC_METASOUND && !tctx->is_6kbps) {
bsize_no_main_cb[1] += 2;
bsize_no_main_cb[2] += 2;
}
@@ -762,6 +774,20 @@
tctx->avctx = avctx;
avctx->sample_fmt = AV_SAMPLE_FMT_FLTP;
+ if (!avctx->block_align) {
+ avctx->block_align = tctx->frame_size + 7 >> 3;
+ } else if (avctx->block_align * 8 < tctx->frame_size) {
+ av_log(avctx, AV_LOG_ERROR, "Block align is %d bits, expected %d\n",
+ avctx->block_align * 8, tctx->frame_size);
+ return AVERROR_INVALIDDATA;
+ }
+ tctx->frames_per_packet = avctx->block_align * 8 / tctx->frame_size;
+ if (tctx->frames_per_packet > TWINVQ_MAX_FRAMES_PER_PACKET) {
+ av_log(avctx, AV_LOG_ERROR, "Too many frames per packet (%d)\n",
+ tctx->frames_per_packet);
+ return AVERROR_INVALIDDATA;
+ }
+
avpriv_float_dsp_init(&tctx->fdsp, avctx->flags & CODEC_FLAG_BITEXACT);
if ((ret = init_mdct_win(tctx))) {
av_log(avctx, AV_LOG_ERROR, "Error initializing MDCT\n");
diff --git a/libavcodec/twinvq.h b/libavcodec/twinvq.h
index 44215db..c4e9688 100644
--- a/libavcodec/twinvq.h
+++ b/libavcodec/twinvq.h
@@ -58,6 +58,8 @@
#define TWINVQ_SUBBLOCKS_MAX 16
#define TWINVQ_BARK_N_COEF_MAX 4
+#define TWINVQ_MAX_FRAMES_PER_PACKET 2
+
/**
* Parameters and tables that are different for each frame type
*/
@@ -139,6 +141,8 @@
const TwinVQModeTab *mtab;
+ int is_6kbps;
+
// history
float lsp_hist[2][20]; ///< LSP coefficients of the last frame
float bark_hist[3][2][40]; ///< BSE coefficients of last frame
@@ -162,7 +166,8 @@
// scratch buffers
float *tmp_buf;
- TwinVQFrameData bits;
+ int frame_size, frames_per_packet, cur_frame;
+ TwinVQFrameData bits[TWINVQ_MAX_FRAMES_PER_PACKET];
enum TwinVQCodec codec;
diff --git a/libavcodec/twinvqdec.c b/libavcodec/twinvqdec.c
index 067df56..67ce031 100644
--- a/libavcodec/twinvqdec.c
+++ b/libavcodec/twinvqdec.c
@@ -251,7 +251,7 @@
static int twinvq_read_bitstream(AVCodecContext *avctx, TwinVQContext *tctx,
const uint8_t *buf, int buf_size)
{
- TwinVQFrameData *bits = &tctx->bits;
+ TwinVQFrameData *bits = &tctx->bits[0];
const TwinVQModeTab *mtab = tctx->mtab;
int channels = tctx->avctx->channels;
int sub;
@@ -268,7 +268,7 @@
return AVERROR_INVALIDDATA;
}
- bits->ftype = ff_twinvq_wtype_to_ftype_table[tctx->bits.window_type];
+ bits->ftype = ff_twinvq_wtype_to_ftype_table[tctx->bits[0].window_type];
sub = mtab->fmode[bits->ftype].sub;
@@ -312,7 +312,7 @@
}
}
- return 0;
+ return (get_bits_count(&gb) + 7) / 8;
}
static av_cold int twinvq_decode_init(AVCodecContext *avctx)
@@ -396,13 +396,18 @@
return -1;
}
- avctx->block_align = (avctx->bit_rate * tctx->mtab->size
- / avctx->sample_rate + 15) / 8;
-
tctx->codec = TWINVQ_CODEC_VQF;
tctx->read_bitstream = twinvq_read_bitstream;
tctx->dec_bark_env = dec_bark_env;
tctx->decode_ppc = decode_ppc;
+ tctx->frame_size = avctx->bit_rate * tctx->mtab->size
+ / avctx->sample_rate + 8;
+ tctx->is_6kbps = 0;
+ if (avctx->block_align && avctx->block_align * 8 / tctx->frame_size > 1) {
+ av_log(avctx, AV_LOG_ERROR,
+ "VQF TwinVQ should have only one frame per packet\n");
+ return AVERROR_INVALIDDATA;
+ }
return ff_twinvq_decode_init(avctx);
}
diff --git a/libavcodec/txd.c b/libavcodec/txd.c
index 7526f13..ad1a015 100644
--- a/libavcodec/txd.c
+++ b/libavcodec/txd.c
@@ -63,10 +63,9 @@
return AVERROR_PATCHWELCOME;
}
- if ((ret = av_image_check_size(w, h, 0, avctx)) < 0)
+ if ((ret = ff_set_dimensions(avctx, w, h)) < 0)
return ret;
- if (w != avctx->width || h != avctx->height)
- avcodec_set_dimensions(avctx, w, h);
+
if ((ret = ff_get_buffer(avctx, p, 0)) < 0)
return ret;
diff --git a/libavcodec/ulti.c b/libavcodec/ulti.c
index aee713f..6b76214 100644
--- a/libavcodec/ulti.c
+++ b/libavcodec/ulti.c
@@ -37,7 +37,7 @@
typedef struct UltimotionDecodeContext {
AVCodecContext *avctx;
int width, height, blocks;
- AVFrame frame;
+ AVFrame *frame;
const uint8_t *ulti_codebook;
GetByteContext gb;
} UltimotionDecodeContext;
@@ -51,19 +51,19 @@
s->height = avctx->height;
s->blocks = (s->width / 8) * (s->height / 8);
avctx->pix_fmt = AV_PIX_FMT_YUV410P;
- avctx->coded_frame = &s->frame;
- avctx->coded_frame = (AVFrame*) &s->frame;
s->ulti_codebook = ulti_codebook;
- avcodec_get_frame_defaults(&s->frame);
+
+ s->frame = av_frame_alloc();
+ if (!s->frame)
+ return AVERROR(ENOMEM);
return 0;
}
static av_cold int ulti_decode_end(AVCodecContext *avctx){
UltimotionDecodeContext *s = avctx->priv_data;
- AVFrame *pic = &s->frame;
- av_frame_unref(pic);
+ av_frame_free(&s->frame);
return 0;
}
@@ -227,7 +227,7 @@
int skip;
int tmp;
- if ((ret = ff_reget_buffer(avctx, &s->frame)) < 0)
+ if ((ret = ff_reget_buffer(avctx, s->frame)) < 0)
return ret;
bytestream2_init(&s->gb, buf, buf_size);
@@ -368,7 +368,7 @@
Luma[14] = (tmp >> 6) & 0x3F;
Luma[15] = tmp & 0x3F;
- ulti_convert_yuv(&s->frame, tx, ty, Luma, chroma);
+ ulti_convert_yuv(s->frame, tx, ty, Luma, chroma);
} else {
if (bytestream2_get_bytes_left(&s->gb) < 4)
goto err;
@@ -380,20 +380,20 @@
Y[1] = tmp & 0x3F;
Y[2] = bytestream2_get_byteu(&s->gb) & 0x3F;
Y[3] = bytestream2_get_byteu(&s->gb) & 0x3F;
- ulti_grad(&s->frame, tx, ty, Y, chroma, angle); //draw block
+ ulti_grad(s->frame, tx, ty, Y, chroma, angle); //draw block
} else { // some patterns
int f0, f1;
f0 = bytestream2_get_byteu(&s->gb);
f1 = tmp;
Y[0] = bytestream2_get_byteu(&s->gb) & 0x3F;
Y[1] = bytestream2_get_byteu(&s->gb) & 0x3F;
- ulti_pattern(&s->frame, tx, ty, f1, f0, Y[0], Y[1], chroma);
+ ulti_pattern(s->frame, tx, ty, f1, f0, Y[0], Y[1], chroma);
}
}
break;
}
if(code != 3)
- ulti_grad(&s->frame, tx, ty, Y, chroma, angle); // draw block
+ ulti_grad(s->frame, tx, ty, Y, chroma, angle); // draw block
}
blocks++;
x += 8;
@@ -405,7 +405,7 @@
}
*got_frame = 1;
- if ((ret = av_frame_ref(data, &s->frame)) < 0)
+ if ((ret = av_frame_ref(data, s->frame)) < 0)
return ret;
return buf_size;
diff --git a/libavcodec/utils.c b/libavcodec/utils.c
index 9e15c6d..c67fd9c 100644
--- a/libavcodec/utils.c
+++ b/libavcodec/utils.c
@@ -56,31 +56,79 @@
# include <iconv.h>
#endif
+#if HAVE_PTHREADS
+#include <pthread.h>
+#elif HAVE_W32THREADS
+#include "compat/w32pthreads.h"
+#elif HAVE_OS2THREADS
+#include "compat/os2threads.h"
+#endif
+
+#if HAVE_PTHREADS || HAVE_W32THREADS || HAVE_OS2THREADS
+static int default_lockmgr_cb(void **arg, enum AVLockOp op)
+{
+ void * volatile * mutex = arg;
+ int err;
+
+ switch (op) {
+ case AV_LOCK_CREATE:
+ return 0;
+ case AV_LOCK_OBTAIN:
+ if (!*mutex) {
+ pthread_mutex_t *tmp = av_malloc(sizeof(pthread_mutex_t));
+ if (!tmp)
+ return AVERROR(ENOMEM);
+ if ((err = pthread_mutex_init(tmp, NULL))) {
+ av_free(tmp);
+ return AVERROR(err);
+ }
+ if (avpriv_atomic_ptr_cas(mutex, NULL, tmp)) {
+ pthread_mutex_destroy(tmp);
+ av_free(tmp);
+ }
+ }
+
+ if ((err = pthread_mutex_lock(*mutex)))
+ return AVERROR(err);
+
+ return 0;
+ case AV_LOCK_RELEASE:
+ if ((err = pthread_mutex_unlock(*mutex)))
+ return AVERROR(err);
+
+ return 0;
+ case AV_LOCK_DESTROY:
+ if (*mutex)
+ pthread_mutex_destroy(*mutex);
+ av_free(*mutex);
+ avpriv_atomic_ptr_cas(mutex, *mutex, NULL);
+ return 0;
+ }
+ return 1;
+}
+static int (*lockmgr_cb)(void **mutex, enum AVLockOp op) = default_lockmgr_cb;
+#else
+static int (*lockmgr_cb)(void **mutex, enum AVLockOp op) = NULL;
+#endif
+
+
volatile int ff_avcodec_locked;
static int volatile entangled_thread_counter = 0;
-static int (*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)
+#if FF_API_FAST_MALLOC && CONFIG_SHARED && HAVE_SYMVER
+FF_SYMVER(void*, av_fast_realloc, (void *ptr, unsigned int *size, size_t min_size), "LIBAVCODEC_55")
{
- if (min_size < *size)
- return ptr;
-
- min_size = FFMAX(17 * min_size / 16 + 32, min_size);
-
- ptr = av_realloc(ptr, min_size);
- /* we could set this to the unmodified min_size but this is safer
- * if the user lost the ptr and uses NULL now
- */
- if (!ptr)
- min_size = 0;
-
- *size = min_size;
-
- return ptr;
+ return av_fast_realloc(ptr, size, min_size);
}
+FF_SYMVER(void, av_fast_malloc, (void *ptr, unsigned int *size, size_t min_size), "LIBAVCODEC_55")
+{
+ av_fast_malloc(ptr, size, min_size);
+}
+#endif
+
static inline int ff_fast_malloc(void *ptr, unsigned int *size, size_t min_size, int zero_realloc)
{
void **p = ptr;
@@ -95,11 +143,6 @@
return 1;
}
-void av_fast_malloc(void *ptr, unsigned int *size, size_t min_size)
-{
- ff_fast_malloc(ptr, size, min_size, 0);
-}
-
void av_fast_padded_malloc(void *ptr, unsigned int *size, size_t min_size)
{
uint8_t **p = ptr;
@@ -163,7 +206,8 @@
avcodec_init();
p = &first_avcodec;
codec->next = NULL;
- while(avpriv_atomic_ptr_cas((void * volatile *)p, NULL, codec))
+
+ while(*p || avpriv_atomic_ptr_cas((void * volatile *)p, NULL, codec))
p = &(*p)->next;
if (codec->init_static_data)
@@ -175,12 +219,26 @@
return EDGE_WIDTH;
}
+#if FF_API_SET_DIMENSIONS
void avcodec_set_dimensions(AVCodecContext *s, int width, int height)
{
+ ff_set_dimensions(s, width, height);
+}
+#endif
+
+int ff_set_dimensions(AVCodecContext *s, int width, int height)
+{
+ int ret = av_image_check_size(width, height, 0, s);
+
+ if (ret < 0)
+ width = height = 0;
+
s->coded_width = width;
s->coded_height = height;
s->width = FF_CEIL_RSHIFT(width, s->lowres);
s->height = FF_CEIL_RSHIFT(height, s->lowres);
+
+ return ret;
}
#if HAVE_NEON || ARCH_PPC || HAVE_MMX
@@ -660,11 +718,11 @@
int ff_init_buffer_info(AVCodecContext *avctx, AVFrame *frame)
{
- if (avctx->pkt) {
- frame->pkt_pts = avctx->pkt->pts;
- av_frame_set_pkt_pos (frame, avctx->pkt->pos);
- av_frame_set_pkt_duration(frame, avctx->pkt->duration);
- av_frame_set_pkt_size (frame, avctx->pkt->size);
+ if (avctx->internal->pkt) {
+ frame->pkt_pts = avctx->internal->pkt->pts;
+ av_frame_set_pkt_pos (frame, avctx->internal->pkt->pos);
+ av_frame_set_pkt_duration(frame, avctx->internal->pkt->duration);
+ av_frame_set_pkt_size (frame, avctx->internal->pkt->size);
} else {
frame->pkt_pts = AV_NOPTS_VALUE;
av_frame_set_pkt_pos (frame, -1);
@@ -1013,6 +1071,7 @@
av_frame_set_colorspace(frame, AVCOL_SPC_UNSPECIFIED);
}
+#if FF_API_AVFRAME_LAVC
AVFrame *avcodec_alloc_frame(void)
{
AVFrame *frame = av_malloc(sizeof(AVFrame));
@@ -1025,6 +1084,7 @@
return frame;
}
+#endif
void avcodec_free_frame(AVFrame **frame)
{
@@ -1080,13 +1140,6 @@
return bit_rate;
}
-#if FF_API_AVCODEC_OPEN
-int attribute_align_arg avcodec_open(AVCodecContext *avctx, AVCodec *codec)
-{
- return avcodec_open2(avctx, codec, NULL);
-}
-#endif
-
int attribute_align_arg ff_codec_open2_recursive(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options)
{
int ret = 0;
@@ -1141,6 +1194,12 @@
goto free_and_end;
}
+ avctx->internal->to_free = av_frame_alloc();
+ if (!avctx->internal->to_free) {
+ ret = AVERROR(ENOMEM);
+ goto free_and_end;
+ }
+
if (codec->priv_data_size > 0) {
if (!avctx->priv_data) {
avctx->priv_data = av_mallocz(codec->priv_data_size);
@@ -1161,20 +1220,22 @@
if ((ret = av_opt_set_dict(avctx, &tmp)) < 0)
goto free_and_end;
- // only call avcodec_set_dimensions() for non H.264/VP6F codecs so as not to overwrite previously setup dimensions
+ // only call ff_set_dimensions() for non H.264/VP6F codecs so as not to overwrite previously setup dimensions
if (!(avctx->coded_width && avctx->coded_height && avctx->width && avctx->height &&
(avctx->codec_id == AV_CODEC_ID_H264 || avctx->codec_id == AV_CODEC_ID_VP6F))) {
if (avctx->coded_width && avctx->coded_height)
- avcodec_set_dimensions(avctx, avctx->coded_width, avctx->coded_height);
+ ret = ff_set_dimensions(avctx, avctx->coded_width, avctx->coded_height);
else if (avctx->width && avctx->height)
- avcodec_set_dimensions(avctx, avctx->width, avctx->height);
+ ret = ff_set_dimensions(avctx, avctx->width, avctx->height);
+ if (ret < 0)
+ goto free_and_end;
}
if ((avctx->coded_width || avctx->coded_height || avctx->width || avctx->height)
&& ( av_image_check_size(avctx->coded_width, avctx->coded_height, 0, avctx) < 0
|| av_image_check_size(avctx->width, avctx->height, 0, avctx) < 0)) {
av_log(avctx, AV_LOG_WARNING, "Ignoring invalid width/height values\n");
- avcodec_set_dimensions(avctx, 0, 0);
+ ff_set_dimensions(avctx, 0, 0);
}
/* if the decoder init function was already called previously,
@@ -1507,7 +1568,7 @@
AVFrame *frame = NULL;
int ret;
- if (!(frame = avcodec_alloc_frame()))
+ if (!(frame = av_frame_alloc()))
return AVERROR(ENOMEM);
frame->format = src->format;
@@ -1899,69 +1960,119 @@
return pts;
}
-static void apply_param_change(AVCodecContext *avctx, AVPacket *avpkt)
+static int apply_param_change(AVCodecContext *avctx, AVPacket *avpkt)
{
- int size = 0;
+ int size = 0, ret;
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;
+ if (!data)
+ return 0;
+
+ if (!(avctx->codec->capabilities & CODEC_CAP_PARAM_CHANGE)) {
+ av_log(avctx, AV_LOG_ERROR, "This decoder does not support parameter "
+ "changes, but PARAM_CHANGE side data was sent to it.\n");
+ return AVERROR(EINVAL);
+ }
+
+ if (size < 4)
+ goto fail;
+
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) {
+ if (size < 4)
+ goto fail;
avctx->channels = bytestream_get_le32(&data);
size -= 4;
}
if (flags & AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_LAYOUT) {
if (size < 8)
- return;
+ goto fail;
avctx->channel_layout = bytestream_get_le64(&data);
size -= 8;
}
- if (size < 4)
- return;
if (flags & AV_SIDE_DATA_PARAM_CHANGE_SAMPLE_RATE) {
+ if (size < 4)
+ goto fail;
avctx->sample_rate = bytestream_get_le32(&data);
size -= 4;
}
if (flags & AV_SIDE_DATA_PARAM_CHANGE_DIMENSIONS) {
if (size < 8)
- return;
+ goto fail;
avctx->width = bytestream_get_le32(&data);
avctx->height = bytestream_get_le32(&data);
- avcodec_set_dimensions(avctx, avctx->width, avctx->height);
size -= 8;
+ ret = ff_set_dimensions(avctx, avctx->width, avctx->height);
+ if (ret < 0)
+ return ret;
}
+
+ return 0;
+fail:
+ av_log(avctx, AV_LOG_ERROR, "PARAM_CHANGE side data too small.\n");
+ return AVERROR_INVALIDDATA;
}
static int add_metadata_from_side_data(AVCodecContext *avctx, AVFrame *frame)
{
- int size, ret = 0;
+ int size;
const uint8_t *side_metadata;
- const uint8_t *end;
- side_metadata = av_packet_get_side_data(avctx->pkt,
+ AVDictionary **frame_md = avpriv_frame_get_metadatap(frame);
+
+ side_metadata = av_packet_get_side_data(avctx->internal->pkt,
AV_PKT_DATA_STRINGS_METADATA, &size);
- if (!side_metadata)
- goto end;
- end = side_metadata + size;
- while (side_metadata < end) {
- const uint8_t *key = side_metadata;
- const uint8_t *val = side_metadata + strlen(key) + 1;
- int ret = av_dict_set(avpriv_frame_get_metadatap(frame), key, val, 0);
- if (ret < 0)
- break;
- side_metadata = val + strlen(val) + 1;
- }
-end:
- return ret;
+ return av_packet_unpack_dictionary(side_metadata, size, frame_md);
+}
+
+static int unrefcount_frame(AVCodecInternal *avci, AVFrame *frame)
+{
+ int ret;
+
+ /* move the original frame to our backup */
+ av_frame_unref(avci->to_free);
+ av_frame_move_ref(avci->to_free, frame);
+
+ /* now copy everything except the AVBufferRefs back
+ * note that we make a COPY of the side data, so calling av_frame_free() on
+ * the caller's frame will work properly */
+ ret = av_frame_copy_props(frame, avci->to_free);
+ if (ret < 0)
+ return ret;
+
+ memcpy(frame->data, avci->to_free->data, sizeof(frame->data));
+ memcpy(frame->linesize, avci->to_free->linesize, sizeof(frame->linesize));
+ if (avci->to_free->extended_data != avci->to_free->data) {
+ int planes = av_get_channel_layout_nb_channels(avci->to_free->channel_layout);
+ int size = planes * sizeof(*frame->extended_data);
+
+ if (!size) {
+ av_frame_unref(frame);
+ return AVERROR_BUG;
+ }
+
+ frame->extended_data = av_malloc(size);
+ if (!frame->extended_data) {
+ av_frame_unref(frame);
+ return AVERROR(ENOMEM);
+ }
+ memcpy(frame->extended_data, avci->to_free->extended_data,
+ size);
+ } else
+ frame->extended_data = frame->data;
+
+ frame->format = avci->to_free->format;
+ frame->width = avci->to_free->width;
+ frame->height = avci->to_free->height;
+ frame->channel_layout = avci->to_free->channel_layout;
+ frame->nb_samples = avci->to_free->nb_samples;
+ av_frame_set_channels(frame, av_frame_get_channels(avci->to_free));
+
+ return 0;
}
int attribute_align_arg avcodec_decode_video2(AVCodecContext *avctx, AVFrame *picture,
@@ -1986,13 +2097,16 @@
avcodec_get_frame_defaults(picture);
- if (!avctx->refcounted_frames)
- av_frame_unref(&avci->to_free);
-
if ((avctx->codec->capabilities & CODEC_CAP_DELAY) || avpkt->size || (avctx->active_thread_type & FF_THREAD_FRAME)) {
int did_split = av_packet_split_side_data(&tmp);
- apply_param_change(avctx, &tmp);
- avctx->pkt = &tmp;
+ ret = apply_param_change(avctx, &tmp);
+ if (ret < 0) {
+ av_log(avctx, AV_LOG_ERROR, "Error applying parameter changes.\n");
+ if (avctx->err_recognition & AV_EF_EXPLODE)
+ goto fail;
+ }
+
+ avctx->internal->pkt = &tmp;
if (HAVE_THREADS && avctx->active_thread_type & FF_THREAD_FRAME)
ret = ff_thread_decode_frame(avctx, picture, got_picture_ptr,
&tmp);
@@ -2015,23 +2129,21 @@
}
add_metadata_from_side_data(avctx, picture);
+fail:
emms_c(); //needed to avoid an emms_c() call before every return;
- avctx->pkt = NULL;
+ avctx->internal->pkt = NULL;
if (did_split) {
av_packet_free_side_data(&tmp);
if(ret == tmp.size)
ret = avpkt->size;
}
- if (ret < 0 && picture->data[0])
- av_frame_unref(picture);
-
if (*got_picture_ptr) {
if (!avctx->refcounted_frames) {
- avci->to_free = *picture;
- avci->to_free.extended_data = avci->to_free.data;
- memset(picture->buf, 0, sizeof(picture->buf));
+ int err = unrefcount_frame(avci, picture);
+ if (err < 0)
+ return err;
}
avctx->frame_number++;
@@ -2039,7 +2151,8 @@
guess_correct_pts(avctx,
picture->pkt_pts,
picture->pkt_dts));
- }
+ } else
+ av_frame_unref(picture);
} else
ret = 0;
@@ -2105,7 +2218,6 @@
const AVPacket *avpkt)
{
AVCodecInternal *avci = avctx->internal;
- int planar, channels;
int ret = 0;
*got_frame_ptr = 0;
@@ -2123,9 +2235,6 @@
avcodec_get_frame_defaults(frame);
- if (!avctx->refcounted_frames)
- av_frame_unref(&avci->to_free);
-
if ((avctx->codec->capabilities & CODEC_CAP_DELAY) || avpkt->size || (avctx->active_thread_type & FF_THREAD_FRAME)) {
uint8_t *side;
int side_size;
@@ -2133,9 +2242,14 @@
// copy to ensure we do not change avpkt
AVPacket tmp = *avpkt;
int did_split = av_packet_split_side_data(&tmp);
- apply_param_change(avctx, &tmp);
+ ret = apply_param_change(avctx, &tmp);
+ if (ret < 0) {
+ av_log(avctx, AV_LOG_ERROR, "Error applying parameter changes.\n");
+ if (avctx->err_recognition & AV_EF_EXPLODE)
+ goto fail;
+ }
- avctx->pkt = &tmp;
+ avctx->internal->pkt = &tmp;
if (HAVE_THREADS && avctx->active_thread_type & FF_THREAD_FRAME)
ret = ff_thread_decode_frame(avctx, frame, got_frame_ptr, &tmp);
else {
@@ -2159,7 +2273,7 @@
frame->sample_rate = avctx->sample_rate;
}
- side= av_packet_get_side_data(avctx->pkt, AV_PKT_DATA_SKIP_SAMPLES, &side_size);
+ side= av_packet_get_side_data(avctx->internal->pkt, AV_PKT_DATA_SKIP_SAMPLES, &side_size);
if(side && side_size>=10) {
avctx->internal->skip_samples = AV_RL32(side);
av_log(avctx, AV_LOG_DEBUG, "skip %d samples due to side data\n",
@@ -2213,8 +2327,8 @@
frame->nb_samples -= discard_padding;
}
}
-
- avctx->pkt = NULL;
+fail:
+ avctx->internal->pkt = NULL;
if (did_split) {
av_packet_free_side_data(&tmp);
if(ret == tmp.size)
@@ -2223,28 +2337,14 @@
if (ret >= 0 && *got_frame_ptr) {
if (!avctx->refcounted_frames) {
- avci->to_free = *frame;
- avci->to_free.extended_data = avci->to_free.data;
- memset(frame->buf, 0, sizeof(frame->buf));
- frame->extended_buf = NULL;
- frame->nb_extended_buf = 0;
+ int err = unrefcount_frame(avci, frame);
+ if (err < 0)
+ return err;
}
- } else if (frame->data[0])
+ } else
av_frame_unref(frame);
}
- /* many decoders assign whole AVFrames, thus overwriting extended_data;
- * make sure it's set correctly; assume decoders that actually use
- * extended_data are doing it correctly */
- if (*got_frame_ptr) {
- planar = av_sample_fmt_is_planar(frame->format);
- channels = av_frame_get_channels(frame);
- if (!(planar && channels > AV_NUM_DATA_POINTERS))
- frame->extended_data = frame->data;
- } else {
- frame->extended_data = NULL;
- }
-
return ret;
}
@@ -2260,7 +2360,7 @@
AVPacket tmp;
#endif
- if (avctx->sub_charenc_mode != FF_SUB_CHARENC_MODE_PRE_DECODER)
+ if (avctx->sub_charenc_mode != FF_SUB_CHARENC_MODE_PRE_DECODER || inpkt->size == 0)
return 0;
#if CONFIG_ICONV
@@ -2333,6 +2433,12 @@
{
int i, ret = 0;
+ if (!avpkt->data && avpkt->size) {
+ av_log(avctx, AV_LOG_ERROR, "invalid packet: NULL data, size != 0\n");
+ return AVERROR(EINVAL);
+ }
+ if (!avctx->codec)
+ return AVERROR(EINVAL);
if (avctx->codec->type != AVMEDIA_TYPE_SUBTITLE) {
av_log(avctx, AV_LOG_ERROR, "Invalid media type for subtitles\n");
return AVERROR(EINVAL);
@@ -2341,18 +2447,28 @@
*got_sub_ptr = 0;
avcodec_get_subtitle_defaults(sub);
- if (avpkt->size) {
+ if ((avctx->codec->capabilities & CODEC_CAP_DELAY) || avpkt->size) {
AVPacket pkt_recoded;
AVPacket tmp = *avpkt;
int did_split = av_packet_split_side_data(&tmp);
//apply_param_change(avctx, &tmp);
+ if (did_split) {
+ /* FFMIN() prevents overflow in case the packet wasn't allocated with
+ * proper padding.
+ * If the side data is smaller than the buffer padding size, the
+ * remaining bytes should have already been filled with zeros by the
+ * original packet allocation anyway. */
+ memset(tmp.data + tmp.size, 0,
+ FFMIN(avpkt->size - tmp.size, FF_INPUT_BUFFER_PADDING_SIZE));
+ }
+
pkt_recoded = tmp;
ret = recode_subtitle(avctx, &pkt_recoded, &tmp);
if (ret < 0) {
*got_sub_ptr = 0;
} else {
- avctx->pkt = &pkt_recoded;
+ avctx->internal->pkt = &pkt_recoded;
if (avctx->pkt_timebase.den && avpkt->pts != AV_NOPTS_VALUE)
sub->pts = av_rescale_q(avpkt->pts,
@@ -2389,7 +2505,7 @@
sub->format = 0;
else if (avctx->codec_descriptor->props & AV_CODEC_PROP_TEXT_SUB)
sub->format = 1;
- avctx->pkt = NULL;
+ avctx->internal->pkt = NULL;
}
if (did_split) {
@@ -2456,15 +2572,14 @@
ff_frame_thread_encoder_free(avctx);
ff_lock_avcodec(avctx);
}
- if (HAVE_THREADS && avctx->thread_opaque)
+ if (HAVE_THREADS && avctx->internal->thread_ctx)
ff_thread_free(avctx);
if (avctx->codec && avctx->codec->close)
avctx->codec->close(avctx);
avctx->coded_frame = NULL;
avctx->internal->byte_buffer_size = 0;
av_freep(&avctx->internal->byte_buffer);
- if (!avctx->refcounted_frames)
- av_frame_unref(&avctx->internal->to_free);
+ av_frame_free(&avctx->internal->to_free);
for (i = 0; i < FF_ARRAY_ELEMS(pool->pools); i++)
av_buffer_pool_uninit(&pool->pools[i]);
av_freep(&avctx->internal->pool);
@@ -2497,6 +2612,7 @@
case AV_CODEC_ID_ESCAPE130_DEPRECATED : return AV_CODEC_ID_ESCAPE130;
case AV_CODEC_ID_G2M_DEPRECATED : return AV_CODEC_ID_G2M;
case AV_CODEC_ID_WEBP_DEPRECATED: return AV_CODEC_ID_WEBP;
+ case AV_CODEC_ID_HEVC_DEPRECATED: return AV_CODEC_ID_HEVC;
default : return id;
}
}
@@ -2785,7 +2901,7 @@
avctx->pts_correction_last_dts = INT64_MIN;
if (!avctx->refcounted_frames)
- av_frame_unref(&avctx->internal->to_free);
+ av_frame_unref(avctx->internal->to_free);
}
int av_get_exact_bits_per_sample(enum AVCodecID codec_id)
@@ -3106,7 +3222,7 @@
{
AVHWAccel **p = &first_hwaccel;
hwaccel->next = NULL;
- while(avpriv_atomic_ptr_cas((void * volatile *)p, NULL, hwaccel))
+ while(*p || avpriv_atomic_ptr_cas((void * volatile *)p, NULL, hwaccel))
p = &(*p)->next;
}
@@ -3115,8 +3231,11 @@
return hwaccel ? hwaccel->next : first_hwaccel;
}
-AVHWAccel *ff_find_hwaccel(enum AVCodecID codec_id, enum AVPixelFormat pix_fmt)
+AVHWAccel *ff_find_hwaccel(AVCodecContext *avctx)
{
+ enum AVCodecID codec_id = avctx->codec->id;
+ enum AVPixelFormat pix_fmt = avctx->pix_fmt;
+
AVHWAccel *hwaccel = NULL;
while ((hwaccel = av_hwaccel_next(hwaccel)))
@@ -3258,6 +3377,23 @@
return 1;
}
+int ff_alloc_entries(AVCodecContext *avctx, int count)
+{
+ return 0;
+}
+
+void ff_reset_entries(AVCodecContext *avctx)
+{
+}
+
+void ff_thread_await_progress2(AVCodecContext *avctx, int field, int thread, int shift)
+{
+}
+
+void ff_thread_report_progress2(AVCodecContext *avctx, int field, int thread, int n)
+{
+}
+
#endif
enum AVMediaType avcodec_get_type(enum AVCodecID codec_id)
diff --git a/libavcodec/utvideoenc.c b/libavcodec/utvideoenc.c
index c4885a5..e5a858d 100644
--- a/libavcodec/utvideoenc.c
+++ b/libavcodec/utvideoenc.c
@@ -126,7 +126,7 @@
return AVERROR_OPTION_NOT_FOUND;
}
- avctx->coded_frame = avcodec_alloc_frame();
+ avctx->coded_frame = av_frame_alloc();
if (!avctx->coded_frame) {
av_log(avctx, AV_LOG_ERROR, "Could not allocate frame.\n");
@@ -513,8 +513,7 @@
bytestream2_init_writer(&pb, dst, pkt->size);
- av_fast_malloc(&c->slice_bits, &c->slice_bits_size,
- width * height + FF_INPUT_BUFFER_PADDING_SIZE);
+ av_fast_padded_malloc(&c->slice_bits, &c->slice_bits_size, width * height);
if (!c->slice_bits) {
av_log(avctx, AV_LOG_ERROR, "Cannot allocate temporary buffer 2.\n");
diff --git a/libavcodec/v210enc.c b/libavcodec/v210enc.c
index 51ec6ef..1e53bdb 100644
--- a/libavcodec/v210enc.c
+++ b/libavcodec/v210enc.c
@@ -36,7 +36,7 @@
av_log(avctx, AV_LOG_WARNING, "bits per raw sample: %d != 10-bit\n",
avctx->bits_per_raw_sample);
- avctx->coded_frame = avcodec_alloc_frame();
+ avctx->coded_frame = av_frame_alloc();
if (!avctx->coded_frame)
return AVERROR(ENOMEM);
diff --git a/libavcodec/v308enc.c b/libavcodec/v308enc.c
index 7a97d5a..c6c5ac5 100644
--- a/libavcodec/v308enc.c
+++ b/libavcodec/v308enc.c
@@ -31,7 +31,7 @@
return AVERROR_INVALIDDATA;
}
- avctx->coded_frame = avcodec_alloc_frame();
+ avctx->coded_frame = av_frame_alloc();
if (!avctx->coded_frame) {
av_log(avctx, AV_LOG_ERROR, "Could not allocate frame.\n");
diff --git a/libavcodec/v408enc.c b/libavcodec/v408enc.c
index 85cf7c8..20f08c7 100644
--- a/libavcodec/v408enc.c
+++ b/libavcodec/v408enc.c
@@ -26,7 +26,7 @@
static av_cold int v408_encode_init(AVCodecContext *avctx)
{
- avctx->coded_frame = avcodec_alloc_frame();
+ avctx->coded_frame = av_frame_alloc();
if (!avctx->coded_frame) {
av_log(avctx, AV_LOG_ERROR, "Could not allocate frame.\n");
diff --git a/libavcodec/v410enc.c b/libavcodec/v410enc.c
index c4ce3df..0e2e82a 100644
--- a/libavcodec/v410enc.c
+++ b/libavcodec/v410enc.c
@@ -32,7 +32,7 @@
return AVERROR_INVALIDDATA;
}
- avctx->coded_frame = avcodec_alloc_frame();
+ avctx->coded_frame = av_frame_alloc();
if (!avctx->coded_frame) {
av_log(avctx, AV_LOG_ERROR, "Could not allocate frame.\n");
diff --git a/libavcodec/vaapi_mpeg2.c b/libavcodec/vaapi_mpeg2.c
index d626f24..cdc70ee 100644
--- a/libavcodec/vaapi_mpeg2.c
+++ b/libavcodec/vaapi_mpeg2.c
@@ -115,8 +115,8 @@
intra_slice_flag = get_bits1(&gb);
if (intra_slice_flag) {
skip_bits(&gb, 8);
- while (get_bits1(&gb) != 0)
- skip_bits(&gb, 8);
+ if (skip_1stop_8data_bits(&gb) < 0)
+ return AVERROR_INVALIDDATA;
}
macroblock_offset = get_bits_count(&gb);
diff --git a/libavcodec/vaapi_mpeg4.c b/libavcodec/vaapi_mpeg4.c
index 5923b07..9ed007f 100644
--- a/libavcodec/vaapi_mpeg4.c
+++ b/libavcodec/vaapi_mpeg4.c
@@ -22,9 +22,10 @@
#include "vaapi_internal.h"
#include "h263.h"
+#include "mpeg4video.h"
/** Reconstruct bitstream intra_dc_vlc_thr */
-static int mpeg4_get_intra_dc_vlc_thr(MpegEncContext *s)
+static int mpeg4_get_intra_dc_vlc_thr(Mpeg4DecContext *s)
{
switch (s->intra_dc_threshold) {
case 99: return 0;
@@ -41,7 +42,8 @@
static int vaapi_mpeg4_start_frame(AVCodecContext *avctx, av_unused const uint8_t *buffer, av_unused uint32_t size)
{
- MpegEncContext * const s = avctx->priv_data;
+ Mpeg4DecContext *ctx = avctx->priv_data;
+ MpegEncContext * const s = &ctx->m;
struct vaapi_context * const vactx = avctx->hwaccel_context;
VAPictureParameterBufferMPEG4 *pic_param;
VAIQMatrixBufferMPEG4 *iq_matrix;
@@ -64,24 +66,24 @@
pic_param->vol_fields.bits.chroma_format = CHROMA_420;
pic_param->vol_fields.bits.interlaced = !s->progressive_sequence;
pic_param->vol_fields.bits.obmc_disable = 1;
- pic_param->vol_fields.bits.sprite_enable = s->vol_sprite_usage;
+ pic_param->vol_fields.bits.sprite_enable = ctx->vol_sprite_usage;
pic_param->vol_fields.bits.sprite_warping_accuracy = s->sprite_warping_accuracy;
pic_param->vol_fields.bits.quant_type = s->mpeg_quant;
pic_param->vol_fields.bits.quarter_sample = s->quarter_sample;
pic_param->vol_fields.bits.data_partitioned = s->data_partitioning;
- pic_param->vol_fields.bits.reversible_vlc = s->rvlc;
- pic_param->vol_fields.bits.resync_marker_disable = !s->resync_marker;
- pic_param->no_of_sprite_warping_points = s->num_sprite_warping_points;
- for (i = 0; i < s->num_sprite_warping_points && i < 3; i++) {
- pic_param->sprite_trajectory_du[i] = s->sprite_traj[i][0];
- pic_param->sprite_trajectory_dv[i] = s->sprite_traj[i][1];
+ pic_param->vol_fields.bits.reversible_vlc = ctx->rvlc;
+ pic_param->vol_fields.bits.resync_marker_disable = !ctx->resync_marker;
+ pic_param->no_of_sprite_warping_points = ctx->num_sprite_warping_points;
+ for (i = 0; i < ctx->num_sprite_warping_points && i < 3; i++) {
+ pic_param->sprite_trajectory_du[i] = ctx->sprite_traj[i][0];
+ pic_param->sprite_trajectory_dv[i] = ctx->sprite_traj[i][1];
}
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.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.intra_dc_vlc_thr = mpeg4_get_intra_dc_vlc_thr(ctx);
pic_param->vop_fields.bits.top_field_first = s->top_field_first;
pic_param->vop_fields.bits.alternate_vertical_scan_flag = s->alternate_scan;
pic_param->vop_fcode_forward = s->f_code;
diff --git a/libavcodec/vaapi_vc1.c b/libavcodec/vaapi_vc1.c
index b8f0530..266fa3c 100644
--- a/libavcodec/vaapi_vc1.c
+++ b/libavcodec/vaapi_vc1.c
@@ -169,7 +169,7 @@
pic_param->sequence_fields.bits.psf = v->psf;
pic_param->sequence_fields.bits.multires = v->multires;
pic_param->sequence_fields.bits.overlap = v->overlap;
- pic_param->sequence_fields.bits.syncmarker = s->resync_marker;
+ pic_param->sequence_fields.bits.syncmarker = v->resync_marker;
pic_param->sequence_fields.bits.rangered = v->rangered;
pic_param->sequence_fields.bits.max_b_frames = s->avctx->max_b_frames;
#if VA_CHECK_VERSION(0,32,0)
diff --git a/libavcodec/vc1.c b/libavcodec/vc1.c
index f755811..181a4df 100644
--- a/libavcodec/vc1.c
+++ b/libavcodec/vc1.c
@@ -367,7 +367,7 @@
v->overlap = get_bits1(gb); //common
- v->s.resync_marker = get_bits1(gb);
+ v->resync_marker = get_bits1(gb);
v->rangered = get_bits1(gb);
if (v->rangered && v->profile == PROFILE_SIMPLE) {
av_log(avctx, AV_LOG_INFO,
@@ -409,7 +409,7 @@
"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->rangered, v->vstransform, v->overlap, v->resync_marker,
v->dquant, v->quantizer_mode, avctx->max_b_frames);
return 0;
}
@@ -1021,6 +1021,8 @@
v->reffield = get_bits1(gb);
v->ref_field_type[0] = v->reffield ^ !v->cur_field_type;
}
+ } else {
+ v->numref = 0;
}
if (v->extended_mv)
v->mvrange = get_unary(gb, 0, 3);
diff --git a/libavcodec/vc1.h b/libavcodec/vc1.h
index c77ab7c..0cf4e0f 100644
--- a/libavcodec/vc1.h
+++ b/libavcodec/vc1.h
@@ -378,7 +378,7 @@
//@{
int new_sprite;
int two_sprites;
- AVFrame sprite_output_frame;
+ AVFrame *sprite_output_frame;
int output_width, output_height, sprite_width, sprite_height;
uint8_t* sr_rows[2][2]; ///< Sprite resizer line cache
//@}
@@ -399,6 +399,7 @@
int end_mb_x; ///< Horizontal macroblock limit (used only by mss2)
int parse_only; ///< Context is used within parser
+ int resync_marker; ///< could this stream contain resync markers
} VC1Context;
/** Find VC-1 marker in buffer
diff --git a/libavcodec/vc1_parser.c b/libavcodec/vc1_parser.c
index 1321320..cc29ce1 100644
--- a/libavcodec/vc1_parser.c
+++ b/libavcodec/vc1_parser.c
@@ -51,6 +51,7 @@
for(start = buf, end = buf + buf_size; next < end; start = next){
int buf2_size, size;
+ int ret;
next = find_next_marker(start + 4, end);
size = next - start - 4;
@@ -66,9 +67,12 @@
break;
case VC1_CODE_FRAME:
if(vpc->v.profile < PROFILE_ADVANCED)
- ff_vc1_parse_frame_header (&vpc->v, &gb);
+ ret = ff_vc1_parse_frame_header (&vpc->v, &gb);
else
- ff_vc1_parse_frame_header_adv(&vpc->v, &gb);
+ ret = ff_vc1_parse_frame_header_adv(&vpc->v, &gb);
+
+ if (ret < 0)
+ break;
/* keep AV_PICTURE_TYPE_BI internal to VC1 */
if (vpc->v.s.pict_type == AV_PICTURE_TYPE_BI)
diff --git a/libavcodec/vc1dec.c b/libavcodec/vc1dec.c
index 6749c2b..8784644 100644
--- a/libavcodec/vc1dec.c
+++ b/libavcodec/vc1dec.c
@@ -454,17 +454,21 @@
uint8_t *uvbuf = s->edge_emu_buffer + 19 * s->linesize;
srcY -= s->mspel * (1 + s->linesize);
- s->vdsp.emulated_edge_mc(s->edge_emu_buffer, s->linesize,
- srcY, s->linesize,
+ s->vdsp.emulated_edge_mc(s->edge_emu_buffer, srcY,
+ s->linesize, 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->vdsp.emulated_edge_mc(uvbuf, s->uvlinesize, srcU, s->uvlinesize,
- 8 + 1, 8 + 1, uvsrc_x, uvsrc_y,
+ s->vdsp.emulated_edge_mc(uvbuf, srcU,
+ s->uvlinesize, s->uvlinesize,
+ 8 + 1, 8 + 1,
+ uvsrc_x, uvsrc_y,
s->h_edge_pos >> 1, v_edge_pos >> 1);
- s->vdsp.emulated_edge_mc(uvbuf + 16, s->uvlinesize, srcV, s->uvlinesize,
- 8 + 1, 8 + 1, uvsrc_x, uvsrc_y,
+ s->vdsp.emulated_edge_mc(uvbuf + 16, srcV,
+ s->uvlinesize, s->uvlinesize,
+ 8 + 1, 8 + 1,
+ uvsrc_x, uvsrc_y,
s->h_edge_pos >> 1, v_edge_pos >> 1);
srcU = uvbuf;
srcV = uvbuf + 16;
@@ -700,7 +704,8 @@
|| (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->vdsp.emulated_edge_mc(s->edge_emu_buffer, s->linesize, srcY, s->linesize,
+ s->vdsp.emulated_edge_mc(s->edge_emu_buffer, srcY,
+ s->linesize, 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);
@@ -915,11 +920,13 @@
|| s->h_edge_pos < 18 || v_edge_pos < 18
|| (unsigned)uvsrc_x > (s->h_edge_pos >> 1) - 9
|| (unsigned)uvsrc_y > (v_edge_pos >> 1) - 9) {
- s->vdsp.emulated_edge_mc(s->edge_emu_buffer, s->uvlinesize, srcU,
- s->uvlinesize, 8 + 1, 8 + 1, uvsrc_x, uvsrc_y,
+ s->vdsp.emulated_edge_mc(s->edge_emu_buffer, srcU,
+ s->uvlinesize, s->uvlinesize,
+ 8 + 1, 8 + 1, uvsrc_x, uvsrc_y,
s->h_edge_pos >> 1, v_edge_pos >> 1);
- s->vdsp.emulated_edge_mc(s->edge_emu_buffer + 16, s->uvlinesize, srcV,
- s->uvlinesize, 8 + 1, 8 + 1, uvsrc_x, uvsrc_y,
+ s->vdsp.emulated_edge_mc(s->edge_emu_buffer + 16, srcV,
+ s->uvlinesize, 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;
@@ -1036,12 +1043,14 @@
|| s->h_edge_pos < 10 || v_edge_pos < (5 << fieldmv)
|| (unsigned)uvsrc_x > (s->h_edge_pos >> 1) - 5
|| (unsigned)uvsrc_y > v_edge_pos - (5 << fieldmv)) {
- s->vdsp.emulated_edge_mc(s->edge_emu_buffer, s->uvlinesize, srcU,
- s->uvlinesize, 5, (5 << fieldmv), uvsrc_x,
- uvsrc_y, s->h_edge_pos >> 1, v_edge_pos);
- s->vdsp.emulated_edge_mc(s->edge_emu_buffer + 16, s->uvlinesize, srcV,
- s->uvlinesize, 5, (5 << fieldmv), uvsrc_x,
- uvsrc_y, s->h_edge_pos >> 1, v_edge_pos);
+ s->vdsp.emulated_edge_mc(s->edge_emu_buffer, srcU,
+ s->uvlinesize, s->uvlinesize,
+ 5, (5 << fieldmv), uvsrc_x, uvsrc_y,
+ s->h_edge_pos >> 1, v_edge_pos);
+ s->vdsp.emulated_edge_mc(s->edge_emu_buffer + 16, srcV,
+ s->uvlinesize, 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;
@@ -1815,8 +1824,7 @@
} else if (total_valid) {
if (a_valid) { px = A[0]; py = A[1]; }
else if (b_valid) { px = B[0]; py = B[1]; }
- else if (c_valid) { px = C[0]; py = C[1]; }
- else av_assert2(0);
+ else { px = C[0]; py = C[1]; }
}
}
} else {
@@ -1969,16 +1977,21 @@
uint8_t *uvbuf = s->edge_emu_buffer + 19 * s->linesize;
srcY -= s->mspel * (1 + s->linesize);
- s->vdsp.emulated_edge_mc(s->edge_emu_buffer, s->linesize, srcY, s->linesize,
+ s->vdsp.emulated_edge_mc(s->edge_emu_buffer, srcY,
+ s->linesize, 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->vdsp.emulated_edge_mc(uvbuf, s->uvlinesize, srcU, s->uvlinesize,
- 8 + 1, 8 + 1, uvsrc_x, uvsrc_y,
+ s->vdsp.emulated_edge_mc(uvbuf, srcU,
+ s->uvlinesize, s->uvlinesize,
+ 8 + 1, 8 + 1,
+ uvsrc_x, uvsrc_y,
s->h_edge_pos >> 1, v_edge_pos >> 1);
- s->vdsp.emulated_edge_mc(uvbuf + 16, s->uvlinesize, srcV, s->uvlinesize,
- 8 + 1, 8 + 1, uvsrc_x, uvsrc_y,
+ s->vdsp.emulated_edge_mc(uvbuf + 16, srcV,
+ s->uvlinesize, s->uvlinesize,
+ 8 + 1, 8 + 1,
+ uvsrc_x, uvsrc_y,
s->h_edge_pos >> 1, v_edge_pos >> 1);
srcU = uvbuf;
srcV = uvbuf + 16;
@@ -4550,9 +4563,9 @@
if (mb_has_coeffs)
cbp = 1 + get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2);
if (!direct) {
- if (bmvtype == BMV_TYPE_INTERPOLATED & twomv) {
+ if (bmvtype == BMV_TYPE_INTERPOLATED && twomv) {
v->fourmvbp = get_vlc2(gb, v->fourmvbp_vlc->table, VC1_4MV_BLOCK_PATTERN_VLC_BITS, 1);
- } else if (bmvtype == BMV_TYPE_INTERPOLATED | twomv) {
+ } else if (bmvtype == BMV_TYPE_INTERPOLATED || twomv) {
v->twomvbp = get_vlc2(gb, v->twomvbp_vlc->table, VC1_2MV_BLOCK_PATTERN_VLC_BITS, 1);
}
}
@@ -5366,8 +5379,8 @@
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;
+ 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];
@@ -5458,8 +5471,8 @@
v->two_sprites = 0;
}
- av_frame_unref(&v->sprite_output_frame);
- if ((ret = ff_get_buffer(avctx, &v->sprite_output_frame, 0)) < 0)
+ av_frame_unref(v->sprite_output_frame);
+ if ((ret = ff_get_buffer(avctx, v->sprite_output_frame, 0)) < 0)
return ret;
vc1_draw_sprites(v, &sd);
@@ -5598,7 +5611,7 @@
avctx->pix_fmt = avctx->get_format(avctx, avctx->codec->pix_fmts);
else
avctx->pix_fmt = AV_PIX_FMT_GRAY8;
- avctx->hwaccel = ff_find_hwaccel(avctx->codec->id, avctx->pix_fmt);
+ avctx->hwaccel = ff_find_hwaccel(avctx);
v->s.avctx = avctx;
avctx->flags |= CODEC_FLAG_EMU_EDGE;
v->s.flags |= CODEC_FLAG_EMU_EDGE;
@@ -5686,6 +5699,10 @@
v->res_sprite = (avctx->codec_id == AV_CODEC_ID_VC1IMAGE);
}
+ v->sprite_output_frame = av_frame_alloc();
+ if (!v->sprite_output_frame)
+ return AVERROR(ENOMEM);
+
avctx->profile = v->profile;
if (v->profile == PROFILE_ADVANCED)
avctx->level = v->level;
@@ -5732,7 +5749,7 @@
VC1Context *v = avctx->priv_data;
int i;
- av_frame_unref(&v->sprite_output_frame);
+ av_frame_free(&v->sprite_output_frame);
for (i = 0; i < 4; i++)
av_freep(&v->sr_rows[i >> 1][i & 1]);
@@ -5951,15 +5968,6 @@
}
}
- /* 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
v->pic_header_flag = 0;
v->first_pic_header_flag = 1;
@@ -5988,18 +5996,6 @@
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.f.pict_type = s->pict_type;
s->current_picture.f.key_frame = s->pict_type == AV_PICTURE_TYPE_I;
@@ -6028,6 +6024,18 @@
v->s.current_picture_ptr->f.interlaced_frame = (v->fcm != PROGRESSIVE);
v->s.current_picture_ptr->f.top_field_first = v->tff;
+ // 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;
+ }
+
s->me.qpel_put = s->dsp.put_qpel_pixels_tab;
s->me.qpel_avg = s->dsp.avg_qpel_pixels_tab;
@@ -6187,7 +6195,7 @@
if (vc1_decode_sprites(v, &s->gb))
goto err;
#endif
- if ((ret = av_frame_ref(pict, &v->sprite_output_frame)) < 0)
+ if ((ret = av_frame_ref(pict, v->sprite_output_frame)) < 0)
goto err;
*got_frame = 1;
} else {
@@ -6195,12 +6203,11 @@
if ((ret = av_frame_ref(pict, &s->current_picture_ptr->f)) < 0)
goto err;
ff_print_debug_info(s, s->current_picture_ptr, pict);
+ *got_frame = 1;
} else if (s->last_picture_ptr != NULL) {
if ((ret = av_frame_ref(pict, &s->last_picture_ptr->f)) < 0)
goto err;
ff_print_debug_info(s, s->last_picture_ptr, pict);
- }
- if (s->last_picture_ptr || s->low_delay) {
*got_frame = 1;
}
}
diff --git a/libavcodec/vcr1.c b/libavcodec/vcr1.c
index c1393b5..f8281ea 100644
--- a/libavcodec/vcr1.c
+++ b/libavcodec/vcr1.c
@@ -55,8 +55,8 @@
const uint8_t *bytestream_end = bytestream + avpkt->size;
int i, x, y, ret;
- if(avpkt->size < 16 + avctx->height + avctx->width*avctx->height*5/8){
- av_log(avctx, AV_LOG_ERROR, "Insufficient input data.\n");
+ if(avpkt->size < 32 + avctx->height + avctx->width*avctx->height*5/8){
+ av_log(avctx, AV_LOG_ERROR, "Insufficient input data. %d < %d\n", avpkt->size , 32 + avctx->height + avctx->width*avctx->height*5/8);
return AVERROR(EINVAL);
}
diff --git a/libavcodec/vda_h264.c b/libavcodec/vda_h264.c
index c01a21a..e0561e2 100644
--- a/libavcodec/vda_h264.c
+++ b/libavcodec/vda_h264.c
@@ -33,11 +33,11 @@
};
/* 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)
+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;
diff --git a/libavcodec/vda_h264_dec.c b/libavcodec/vda_h264_dec.c
index 9463f6a..e5fa807 100644
--- a/libavcodec/vda_h264_dec.c
+++ b/libavcodec/vda_h264_dec.c
@@ -56,6 +56,15 @@
int h264_initialized;
struct vda_context vda_ctx;
enum AVPixelFormat pix_fmt;
+
+ /* for backing-up fields set by user.
+ * we have to gain full control of such fields here */
+ void *hwaccel_context;
+ enum AVPixelFormat (*get_format)(struct AVCodecContext *s, const enum AVPixelFormat * fmt);
+ int (*get_buffer2)(struct AVCodecContext *s, AVFrame *frame, int flags);
+#if FF_API_GET_BUFFER
+ int (*get_buffer)(struct AVCodecContext *c, AVFrame *pic);
+#endif
} VDADecoderContext;
static enum AVPixelFormat get_format(struct AVCodecContext *avctx,
@@ -90,6 +99,32 @@
return 0;
}
+static inline void set_context(AVCodecContext *avctx)
+{
+ VDADecoderContext *ctx = avctx->priv_data;
+ ctx->hwaccel_context = avctx->hwaccel_context;
+ avctx->hwaccel_context = &ctx->vda_ctx;
+ ctx->get_format = avctx->get_format;
+ avctx->get_format = get_format;
+ ctx->get_buffer2 = avctx->get_buffer2;
+ avctx->get_buffer2 = get_buffer2;
+#if FF_API_GET_BUFFER
+ ctx->get_buffer = avctx->get_buffer;
+ avctx->get_buffer = NULL;
+#endif
+}
+
+static inline void restore_context(AVCodecContext *avctx)
+{
+ VDADecoderContext *ctx = avctx->priv_data;
+ avctx->hwaccel_context = ctx->hwaccel_context;
+ avctx->get_format = ctx->get_format;
+ avctx->get_buffer2 = ctx->get_buffer2;
+#if FF_API_GET_BUFFER
+ avctx->get_buffer = ctx->get_buffer;
+#endif
+}
+
static int vdadec_decode(AVCodecContext *avctx,
void *data, int *got_frame, AVPacket *avpkt)
{
@@ -97,7 +132,9 @@
AVFrame *pic = data;
int ret;
+ set_context(avctx);
ret = ff_h264_decoder.decode(avctx, data, got_frame, avpkt);
+ restore_context(avctx);
if (*got_frame) {
AVBufferRef *buffer = pic->buf[0];
VDABufferContext *context = av_buffer_get_opaque(buffer);
@@ -130,8 +167,11 @@
/* release buffers and decoder */
ff_vda_destroy_decoder(&ctx->vda_ctx);
/* close H.264 decoder */
- if (ctx->h264_initialized)
+ if (ctx->h264_initialized) {
+ set_context(avctx);
ff_h264_decoder.close(avctx);
+ restore_context(avctx);
+ }
return 0;
}
@@ -184,18 +224,11 @@
"Failed to init VDA decoder: %d.\n", status);
goto failed;
}
- avctx->hwaccel_context = vda_ctx;
-
- /* changes callback functions */
- avctx->get_format = get_format;
- avctx->get_buffer2 = get_buffer2;
-#if FF_API_GET_BUFFER
- // force the old get_buffer to be empty
- avctx->get_buffer = NULL;
-#endif
/* init H.264 decoder */
+ set_context(avctx);
ret = ff_h264_decoder.init(avctx);
+ restore_context(avctx);
if (ret < 0) {
av_log(avctx, AV_LOG_ERROR, "Failed to open H.264 decoder.\n");
goto failed;
@@ -211,7 +244,9 @@
static void vdadec_flush(AVCodecContext *avctx)
{
- return ff_h264_decoder.flush(avctx);
+ set_context(avctx);
+ ff_h264_decoder.flush(avctx);
+ restore_context(avctx);
}
AVCodec ff_h264_vda_decoder = {
diff --git a/libavcodec/vdpau.c b/libavcodec/vdpau.c
index 7a4d145..32a3843 100644
--- a/libavcodec/vdpau.c
+++ b/libavcodec/vdpau.c
@@ -40,7 +40,7 @@
AVVDPAUContext *av_alloc_vdpaucontext(void)
{
- return av_mallocz(sizeof(AVVDPAUContext));
+ return av_vdpau_alloc_context();
}
MAKE_ACCESSORS(AVVDPAUContext, vdpau_hwaccel, AVVDPAU_Render2, render2)
@@ -345,7 +345,7 @@
render->info.vc1.range_mapuv = v->range_mapuv;
/* Specific to simple/main profile only */
render->info.vc1.multires = v->multires;
- render->info.vc1.syncmarker = v->s.resync_marker;
+ render->info.vc1.syncmarker = v->resync_marker;
render->info.vc1.rangered = v->rangered | (v->rangeredfrm << 1);
render->info.vc1.maxbframes = v->s.max_b_frames;
@@ -383,9 +383,10 @@
#endif /* (CONFIG_VC1_VDPAU_DECODER */
#if CONFIG_MPEG4_VDPAU_DECODER
-void ff_vdpau_mpeg4_decode_picture(MpegEncContext *s, const uint8_t *buf,
+void ff_vdpau_mpeg4_decode_picture(Mpeg4DecContext *ctx, const uint8_t *buf,
int buf_size)
{
+ MpegEncContext *s = &ctx->m;
struct vdpau_render_state *render, *last, *next;
int i;
@@ -403,7 +404,7 @@
render->info.mpeg4.vop_coding_type = 0;
render->info.mpeg4.vop_fcode_forward = s->f_code;
render->info.mpeg4.vop_fcode_backward = s->b_code;
- render->info.mpeg4.resync_marker_disable = !s->resync_marker;
+ render->info.mpeg4.resync_marker_disable = !ctx->resync_marker;
render->info.mpeg4.interlaced = !s->progressive_sequence;
render->info.mpeg4.quant_type = s->mpeg_quant;
render->info.mpeg4.quarter_sample = s->quarter_sample;
@@ -438,4 +439,52 @@
}
#endif /* CONFIG_MPEG4_VDPAU_DECODER */
+int av_vdpau_get_profile(AVCodecContext *avctx, VdpDecoderProfile *profile)
+{
+#define PROFILE(prof) \
+do { \
+ *profile = prof; \
+ return 0; \
+} while (0)
+
+ switch (avctx->codec_id) {
+ case AV_CODEC_ID_MPEG1VIDEO: PROFILE(VDP_DECODER_PROFILE_MPEG1);
+ case AV_CODEC_ID_MPEG2VIDEO:
+ switch (avctx->profile) {
+ case FF_PROFILE_MPEG2_MAIN: PROFILE(VDP_DECODER_PROFILE_MPEG2_MAIN);
+ case FF_PROFILE_MPEG2_SIMPLE: PROFILE(VDP_DECODER_PROFILE_MPEG2_SIMPLE);
+ default: return AVERROR(EINVAL);
+ }
+ case AV_CODEC_ID_H263: PROFILE(VDP_DECODER_PROFILE_MPEG4_PART2_ASP);
+ case AV_CODEC_ID_MPEG4:
+ switch (avctx->profile) {
+ case FF_PROFILE_MPEG4_SIMPLE: PROFILE(VDP_DECODER_PROFILE_MPEG4_PART2_SP);
+ case FF_PROFILE_MPEG4_ADVANCED_SIMPLE: PROFILE(VDP_DECODER_PROFILE_MPEG4_PART2_ASP);
+ default: return AVERROR(EINVAL);
+ }
+ case AV_CODEC_ID_H264:
+ switch (avctx->profile) {
+ case FF_PROFILE_H264_CONSTRAINED_BASELINE:
+ case FF_PROFILE_H264_BASELINE: PROFILE(VDP_DECODER_PROFILE_H264_BASELINE);
+ case FF_PROFILE_H264_MAIN: PROFILE(VDP_DECODER_PROFILE_H264_MAIN);
+ case FF_PROFILE_H264_HIGH: PROFILE(VDP_DECODER_PROFILE_H264_HIGH);
+ default: return AVERROR(EINVAL);
+ }
+ case AV_CODEC_ID_WMV3:
+ case AV_CODEC_ID_VC1:
+ switch (avctx->profile) {
+ case FF_PROFILE_VC1_SIMPLE: PROFILE(VDP_DECODER_PROFILE_VC1_SIMPLE);
+ case FF_PROFILE_VC1_MAIN: PROFILE(VDP_DECODER_PROFILE_VC1_MAIN);
+ case FF_PROFILE_VC1_ADVANCED: PROFILE(VDP_DECODER_PROFILE_VC1_ADVANCED);
+ default: return AVERROR(EINVAL);
+ }
+ }
+ return AVERROR(EINVAL);
+}
+
+AVVDPAUContext *av_vdpau_alloc_context(void)
+{
+ return av_mallocz(sizeof(AVVDPAUContext));
+}
+
/* @}*/
diff --git a/libavcodec/vdpau.h b/libavcodec/vdpau.h
index b1c836c..e25cc42 100644
--- a/libavcodec/vdpau.h
+++ b/libavcodec/vdpau.h
@@ -54,12 +54,8 @@
#include "libavutil/avconfig.h"
#include "libavutil/attributes.h"
-#ifndef FF_API_CAP_VDPAU
-#define FF_API_CAP_VDPAU 1
-#endif
-#ifndef FF_API_BUFS_VDPAU
-#define FF_API_BUFS_VDPAU 1
-#endif
+#include "avcodec.h"
+#include "version.h"
#if FF_API_BUFS_VDPAU
union AVVDPAUPictureInfo {
@@ -86,6 +82,10 @@
* during initialization or through each AVCodecContext.get_buffer()
* function call. In any case, they must be valid prior to calling
* decoding functions.
+ *
+ * The size of this structure is not a part of the public ABI and must not
+ * be used outside of libavcodec. Use av_vdpau_alloc_context() to allocate an
+ * AVVDPAUContext.
*/
typedef struct AVVDPAUContext {
/**
@@ -149,6 +149,26 @@
AVVDPAU_Render2 av_vdpau_hwaccel_get_render2(const AVVDPAUContext *);
void av_vdpau_hwaccel_set_render2(AVVDPAUContext *, AVVDPAU_Render2);
+/**
+ * Allocate an AVVDPAUContext.
+ *
+ * @return Newly-allocated AVVDPAUContext or NULL on failure.
+ */
+AVVDPAUContext *av_vdpau_alloc_context(void);
+
+/**
+ * Get a decoder profile that should be used for initializing a VDPAU decoder.
+ * Should be called from the AVCodecContext.get_format() callback.
+ *
+ * @param avctx the codec context being used for decoding the stream
+ * @param profile a pointer into which the result will be written on success.
+ * The contents of profile are undefined if this function returns
+ * an error.
+ *
+ * @return 0 on success (non-negative), a negative AVERROR on failure.
+ */
+int av_vdpau_get_profile(AVCodecContext *avctx, VdpDecoderProfile *profile);
+
#if FF_API_CAP_VDPAU
/** @brief The videoSurface is used for rendering. */
#define FF_VDPAU_STATE_USED_FOR_RENDER 1
diff --git a/libavcodec/vdpau_internal.h b/libavcodec/vdpau_internal.h
index b6701f3..cc63411 100644
--- a/libavcodec/vdpau_internal.h
+++ b/libavcodec/vdpau_internal.h
@@ -28,10 +28,13 @@
#include <stdint.h>
#if CONFIG_VDPAU
#include <vdpau/vdpau.h>
-#include "vdpau.h"
#endif
#include "h264.h"
+
+#include "avcodec.h"
+#include "mpeg4video.h"
#include "mpegvideo.h"
+#include "version.h"
/** Extract VdpVideoSurface from a Picture */
static inline uintptr_t ff_vdpau_get_surface_id(Picture *pic)
@@ -47,6 +50,8 @@
VdpPictureInfoVC1 vc1;
VdpPictureInfoMPEG4Part2 mpeg4;
};
+#else
+#include "vdpau.h"
#endif
struct vdpau_picture_context {
@@ -91,7 +96,7 @@
void ff_vdpau_vc1_decode_picture(MpegEncContext *s, const uint8_t *buf,
int buf_size);
-void ff_vdpau_mpeg4_decode_picture(MpegEncContext *s, const uint8_t *buf,
+void ff_vdpau_mpeg4_decode_picture(Mpeg4DecContext *s, const uint8_t *buf,
int buf_size);
#endif /* AVCODEC_VDPAU_INTERNAL_H */
diff --git a/libavcodec/vdpau_mpeg4.c b/libavcodec/vdpau_mpeg4.c
index 84683a4..282796e 100644
--- a/libavcodec/vdpau_mpeg4.c
+++ b/libavcodec/vdpau_mpeg4.c
@@ -24,13 +24,15 @@
#include <vdpau/vdpau.h>
#include "avcodec.h"
+#include "mpeg4video.h"
#include "vdpau.h"
#include "vdpau_internal.h"
static int vdpau_mpeg4_start_frame(AVCodecContext *avctx,
const uint8_t *buffer, uint32_t size)
{
- MpegEncContext * const s = avctx->priv_data;
+ Mpeg4DecContext *ctx = avctx->priv_data;
+ MpegEncContext * const s = &ctx->m;
Picture *pic = s->current_picture_ptr;
struct vdpau_picture_context *pic_ctx = pic->hwaccel_picture_private;
VdpPictureInfoMPEG4Part2 *info = &pic_ctx->info.mpeg4;
@@ -62,7 +64,7 @@
info->vop_time_increment_resolution = s->avctx->time_base.den;
info->vop_fcode_forward = s->f_code;
info->vop_fcode_backward = s->b_code;
- info->resync_marker_disable = !s->resync_marker;
+ info->resync_marker_disable = !ctx->resync_marker;
info->interlaced = !s->progressive_sequence;
info->quant_type = s->mpeg_quant;
info->quarter_sample = s->quarter_sample;
diff --git a/libavcodec/vdpau_vc1.c b/libavcodec/vdpau_vc1.c
index c6e3343..c655529 100644
--- a/libavcodec/vdpau_vc1.c
+++ b/libavcodec/vdpau_vc1.c
@@ -87,7 +87,7 @@
info->range_mapuv = v->range_mapuv;
/* Specific to simple/main profile only */
info->multires = v->multires;
- info->syncmarker = v->s.resync_marker;
+ info->syncmarker = v->resync_marker;
info->rangered = v->rangered | (v->rangeredfrm << 1);
info->maxbframes = v->s.max_b_frames;
info->deblockEnable = v->postprocflag & 1;
diff --git a/libavcodec/version.h b/libavcodec/version.h
index c540c27..eab1622 100644
--- a/libavcodec/version.h
+++ b/libavcodec/version.h
@@ -29,7 +29,7 @@
#include "libavutil/avutil.h"
#define LIBAVCODEC_VERSION_MAJOR 55
-#define LIBAVCODEC_VERSION_MINOR 36
+#define LIBAVCODEC_VERSION_MINOR 45
#define LIBAVCODEC_VERSION_MICRO 100
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
@@ -51,19 +51,9 @@
#ifndef FF_API_REQUEST_CHANNELS
#define FF_API_REQUEST_CHANNELS (LIBAVCODEC_VERSION_MAJOR < 56)
#endif
-#ifndef FF_API_ALLOC_CONTEXT
-#define FF_API_ALLOC_CONTEXT (LIBAVCODEC_VERSION_MAJOR < 55)
-#endif
-#ifndef FF_API_AVCODEC_OPEN
-#define FF_API_AVCODEC_OPEN (LIBAVCODEC_VERSION_MAJOR < 55)
-#endif
#ifndef FF_API_OLD_DECODE_AUDIO
#define FF_API_OLD_DECODE_AUDIO (LIBAVCODEC_VERSION_MAJOR < 56)
#endif
-#ifndef FF_API_OLD_TIMECODE
-#define FF_API_OLD_TIMECODE (LIBAVCODEC_VERSION_MAJOR < 55)
-#endif
-
#ifndef FF_API_OLD_ENCODE_AUDIO
#define FF_API_OLD_ENCODE_AUDIO (LIBAVCODEC_VERSION_MAJOR < 56)
#endif
@@ -73,8 +63,11 @@
#ifndef FF_API_CODEC_ID
#define FF_API_CODEC_ID (LIBAVCODEC_VERSION_MAJOR < 56)
#endif
+#ifndef FF_API_AUDIO_CONVERT
+#define FF_API_AUDIO_CONVERT (LIBAVCODEC_VERSION_MAJOR < 56)
+#endif
#ifndef FF_API_AVCODEC_RESAMPLE
-#define FF_API_AVCODEC_RESAMPLE (LIBAVCODEC_VERSION_MAJOR < 56)
+#define FF_API_AVCODEC_RESAMPLE FF_API_AUDIO_CONVERT
#endif
#ifndef FF_API_DEINTERLACE
#define FF_API_DEINTERLACE (LIBAVCODEC_VERSION_MAJOR < 56)
@@ -100,5 +93,50 @@
#ifndef FF_API_VOXWARE
#define FF_API_VOXWARE (LIBAVCODEC_VERSION_MAJOR < 56)
#endif
+#ifndef FF_API_SET_DIMENSIONS
+#define FF_API_SET_DIMENSIONS (LIBAVCODEC_VERSION_MAJOR < 56)
+#endif
+#ifndef FF_API_DEBUG_MV
+#define FF_API_DEBUG_MV (LIBAVCODEC_VERSION_MAJOR < 56)
+#endif
+#ifndef FF_API_AC_VLC
+#define FF_API_AC_VLC (LIBAVCODEC_VERSION_MAJOR < 56)
+#endif
+#ifndef FF_API_OLD_MSMPEG4
+#define FF_API_OLD_MSMPEG4 (LIBAVCODEC_VERSION_MAJOR < 56)
+#endif
+#ifndef FF_API_ASPECT_EXTENDED
+#define FF_API_ASPECT_EXTENDED (LIBAVCODEC_VERSION_MAJOR < 56)
+#endif
+#ifndef FF_API_THREAD_OPAQUE
+#define FF_API_THREAD_OPAQUE (LIBAVCODEC_VERSION_MAJOR < 56)
+#endif
+#ifndef FF_API_CODEC_PKT
+#define FF_API_CODEC_PKT (LIBAVCODEC_VERSION_MAJOR < 56)
+#endif
+#ifndef FF_API_ARCH_ALPHA
+#define FF_API_ARCH_ALPHA (LIBAVCODEC_VERSION_MAJOR < 56)
+#endif
+#ifndef FF_API_XVMC
+#define FF_API_XVMC (LIBAVCODEC_VERSION_MAJOR < 56)
+#endif
+#ifndef FF_API_ERROR_RATE
+#define FF_API_ERROR_RATE (LIBAVCODEC_VERSION_MAJOR < 56)
+#endif
+#ifndef FF_API_QSCALE_TYPE
+#define FF_API_QSCALE_TYPE (LIBAVCODEC_VERSION_MAJOR < 56)
+#endif
+#ifndef FF_API_MB_TYPE
+#define FF_API_MB_TYPE (LIBAVCODEC_VERSION_MAJOR < 56)
+#endif
+#ifndef FF_API_MAX_BFRAMES
+#define FF_API_MAX_BFRAMES (LIBAVCODEC_VERSION_MAJOR < 56)
+#endif
+#ifndef FF_API_FAST_MALLOC
+#define FF_API_FAST_MALLOC (LIBAVCODEC_VERSION_MAJOR < 56)
+#endif
+#ifndef FF_API_NEG_LINESIZES
+#define FF_API_NEG_LINESIZES (LIBAVCODEC_VERSION_MAJOR < 56)
+#endif
#endif /* AVCODEC_VERSION_H */
diff --git a/libavcodec/videodsp.h b/libavcodec/videodsp.h
index e1f7ee5..0bb15f2 100644
--- a/libavcodec/videodsp.h
+++ b/libavcodec/videodsp.h
@@ -30,8 +30,8 @@
#include <stdint.h>
#define EMULATED_EDGE(depth) \
-void ff_emulated_edge_mc_ ## depth(uint8_t *dst, ptrdiff_t dst_stride, \
- const uint8_t *src, ptrdiff_t src_stride, \
+void ff_emulated_edge_mc_ ## depth(uint8_t *dst, const uint8_t *src, \
+ ptrdiff_t dst_stride, ptrdiff_t src_stride, \
int block_w, int block_h,\
int src_x, int src_y, int w, int h);
@@ -47,8 +47,10 @@
* @param dst_stride number of bytes between 2 vertically adjacent samples
* in destination buffer
* @param src source buffer
- * @param src_stride number of bytes between 2 vertically adjacent samples
- * in source buffer
+ * @param dst_linesize number of bytes between 2 vertically adjacent
+ * samples in the destination buffer
+ * @param src_linesize number of bytes between 2 vertically adjacent
+ * samples in both the source buffer
* @param block_w width of block
* @param block_h height of block
* @param src_x x coordinate of the top left sample of the block in the
@@ -58,8 +60,9 @@
* @param w width of the source buffer
* @param h height of the source buffer
*/
- void (*emulated_edge_mc)(uint8_t *dst, ptrdiff_t dst_stride,
- const uint8_t *src, ptrdiff_t src_stride,
+ void (*emulated_edge_mc)(uint8_t *dst, const uint8_t *src,
+ ptrdiff_t dst_linesize,
+ ptrdiff_t src_linesize,
int block_w, int block_h,
int src_x, int src_y, int w, int h);
diff --git a/libavcodec/videodsp_template.c b/libavcodec/videodsp_template.c
index f7e7bfd..c569c30 100644
--- a/libavcodec/videodsp_template.c
+++ b/libavcodec/videodsp_template.c
@@ -20,8 +20,9 @@
*/
#include "bit_depth_template.c"
-void FUNC(ff_emulated_edge_mc)(uint8_t *buf, ptrdiff_t buf_stride,
- const uint8_t *src, ptrdiff_t src_stride,
+void FUNC(ff_emulated_edge_mc)(uint8_t *buf, const uint8_t *src,
+ ptrdiff_t buf_linesize,
+ ptrdiff_t src_linesize,
int block_w, int block_h,
int src_x, int src_y, int w, int h)
{
@@ -32,12 +33,12 @@
return;
if (src_y >= h) {
- src -= src_y * src_stride;
- src += (h - 1) * src_stride;
+ src -= src_y * src_linesize;
+ src += (h - 1) * src_linesize;
src_y = h - 1;
} else if (src_y <= -block_h) {
- src -= src_y * src_stride;
- src += (1 - block_h) * src_stride;
+ src -= src_y * src_linesize;
+ src += (1 - block_h) * src_linesize;
src_y = 1 - block_h;
}
if (src_x >= w) {
@@ -56,30 +57,30 @@
av_assert2(start_x < end_x && block_w);
w = end_x - start_x;
- src += start_y * src_stride + start_x * sizeof(pixel);
+ src += start_y * src_linesize + start_x * sizeof(pixel);
buf += start_x * sizeof(pixel);
// top
for (y = 0; y < start_y; y++) {
memcpy(buf, src, w * sizeof(pixel));
- buf += buf_stride;
+ buf += buf_linesize;
}
// copy existing part
for (; y < end_y; y++) {
memcpy(buf, src, w * sizeof(pixel));
- src += src_stride;
- buf += buf_stride;
+ src += src_linesize;
+ buf += buf_linesize;
}
// bottom
- src -= src_stride;
+ src -= src_linesize;
for (; y < block_h; y++) {
memcpy(buf, src, w * sizeof(pixel));
- buf += buf_stride;
+ buf += buf_linesize;
}
- buf -= block_h * buf_stride + start_x * sizeof(pixel);
+ buf -= block_h * buf_linesize + start_x * sizeof(pixel);
while (block_h--) {
pixel *bufp = (pixel *) buf;
@@ -92,6 +93,6 @@
for (x = end_x; x < block_w; x++) {
bufp[x] = bufp[end_x - 1];
}
- buf += buf_stride;
+ buf += buf_linesize;
}
}
diff --git a/libavcodec/vmdav.c b/libavcodec/vmdav.c
index ea0e842..e67377a 100644
--- a/libavcodec/vmdav.c
+++ b/libavcodec/vmdav.c
@@ -61,7 +61,7 @@
typedef struct VmdVideoContext {
AVCodecContext *avctx;
- AVFrame prev_frame;
+ AVFrame *prev_frame;
const unsigned char *buf;
int size;
@@ -244,11 +244,11 @@
/* if only a certain region will be updated, copy the entire previous
* frame before the decode */
- if (s->prev_frame.data[0] &&
+ if (s->prev_frame->data[0] &&
(frame_x || frame_y || (frame_width != s->avctx->width) ||
(frame_height != s->avctx->height))) {
- memcpy(frame->data[0], s->prev_frame.data[0],
+ memcpy(frame->data[0], s->prev_frame->data[0],
s->avctx->height * frame->linesize[0]);
}
@@ -291,7 +291,7 @@
}
dp = &frame->data[0][frame_y * frame->linesize[0] + frame_x];
- pp = &s->prev_frame.data[0][frame_y * s->prev_frame.linesize[0] + frame_x];
+ pp = &s->prev_frame->data[0][frame_y * s->prev_frame->linesize[0] + frame_x];
switch (meth) {
case 1:
for (i = 0; i < frame_height; i++) {
@@ -307,7 +307,7 @@
ofs += len;
} else {
/* interframe pixel copy */
- if (ofs + len + 1 > frame_width || !s->prev_frame.data[0])
+ if (ofs + len + 1 > frame_width || !s->prev_frame->data[0])
return AVERROR_INVALIDDATA;
memcpy(&dp[ofs], &pp[ofs], len + 1);
ofs += len + 1;
@@ -320,7 +320,7 @@
return AVERROR_INVALIDDATA;
}
dp += frame->linesize[0];
- pp += s->prev_frame.linesize[0];
+ pp += s->prev_frame->linesize[0];
}
break;
@@ -328,7 +328,7 @@
for (i = 0; i < frame_height; i++) {
bytestream2_get_buffer(&gb, dp, frame_width);
dp += frame->linesize[0];
- pp += s->prev_frame.linesize[0];
+ pp += s->prev_frame->linesize[0];
}
break;
@@ -353,7 +353,7 @@
}
} else {
/* interframe pixel copy */
- if (ofs + len + 1 > frame_width || !s->prev_frame.data[0])
+ if (ofs + len + 1 > frame_width || !s->prev_frame->data[0])
return AVERROR_INVALIDDATA;
memcpy(&dp[ofs], &pp[ofs], len + 1);
ofs += len + 1;
@@ -366,13 +366,24 @@
return AVERROR_INVALIDDATA;
}
dp += frame->linesize[0];
- pp += s->prev_frame.linesize[0];
+ pp += s->prev_frame->linesize[0];
}
break;
}
return 0;
}
+static av_cold int vmdvideo_decode_end(AVCodecContext *avctx)
+{
+ VmdVideoContext *s = avctx->priv_data;
+
+ av_frame_free(&s->prev_frame);
+ av_freep(&s->unpack_buffer);
+ s->unpack_buffer_size = 0;
+
+ return 0;
+}
+
static av_cold int vmdvideo_decode_init(AVCodecContext *avctx)
{
VmdVideoContext *s = avctx->priv_data;
@@ -412,7 +423,11 @@
palette32[i] |= palette32[i] >> 6 & 0x30303;
}
- avcodec_get_frame_defaults(&s->prev_frame);
+ s->prev_frame = av_frame_alloc();
+ if (!s->prev_frame) {
+ vmdvideo_decode_end(avctx);
+ return AVERROR(ENOMEM);
+ }
return 0;
}
@@ -443,8 +458,8 @@
memcpy(frame->data[1], s->palette, PALETTE_COUNT * 4);
/* shuffle frames */
- av_frame_unref(&s->prev_frame);
- if ((ret = av_frame_ref(&s->prev_frame, frame)) < 0)
+ av_frame_unref(s->prev_frame);
+ if ((ret = av_frame_ref(s->prev_frame, frame)) < 0)
return ret;
*got_frame = 1;
@@ -453,17 +468,6 @@
return buf_size;
}
-static av_cold int vmdvideo_decode_end(AVCodecContext *avctx)
-{
- VmdVideoContext *s = avctx->priv_data;
-
- av_frame_unref(&s->prev_frame);
- av_free(s->unpack_buffer);
-
- return 0;
-}
-
-
/*
* Audio Decoder
*/
diff --git a/libavcodec/vmnc.c b/libavcodec/vmnc.c
index c1b6d4e..5f91ab1 100644
--- a/libavcodec/vmnc.c
+++ b/libavcodec/vmnc.c
@@ -57,7 +57,7 @@
*/
typedef struct VmncContext {
AVCodecContext *avctx;
- AVFrame *frame;
+ AVFrame *pic;
int bpp;
int bpp2;
@@ -320,15 +320,14 @@
GetByteContext *gb = &c->gb;
uint8_t *outptr;
int dx, dy, w, h, depth, enc, chunks, res, size_left, ret;
- AVFrame *frame = c->frame;
- if ((ret = ff_reget_buffer(avctx, frame)) < 0)
+ if ((ret = ff_reget_buffer(avctx, c->pic)) < 0)
return ret;
bytestream2_init(gb, buf, buf_size);
- frame->key_frame = 0;
- frame->pict_type = AV_PICTURE_TYPE_P;
+ c->pic->key_frame = 0;
+ c->pic->pict_type = AV_PICTURE_TYPE_P;
// restore screen after cursor
if (c->screendta) {
@@ -350,11 +349,11 @@
dy = 0;
}
if ((w > 0) && (h > 0)) {
- outptr = frame->data[0] + dx * c->bpp2 + dy * frame->linesize[0];
+ outptr = c->pic->data[0] + dx * c->bpp2 + dy * c->pic->linesize[0];
for (i = 0; i < h; i++) {
memcpy(outptr, c->screendta + i * c->cur_w * c->bpp2,
w * c->bpp2);
- outptr += frame->linesize[0];
+ outptr += c->pic->linesize[0];
}
}
}
@@ -370,7 +369,7 @@
w = bytestream2_get_be16(gb);
h = bytestream2_get_be16(gb);
enc = bytestream2_get_be32(gb);
- outptr = frame->data[0] + dx * c->bpp2 + dy * frame->linesize[0];
+ outptr = c->pic->data[0] + dx * c->bpp2 + dy * c->pic->linesize[0];
size_left = bytestream2_get_bytes_left(gb);
switch (enc) {
case MAGIC_WMVd: // cursor
@@ -424,8 +423,8 @@
bytestream2_skip(gb, 4);
break;
case MAGIC_WMVi: // ServerInitialization struct
- frame->key_frame = 1;
- frame->pict_type = AV_PICTURE_TYPE_I;
+ c->pic->key_frame = 1;
+ c->pic->pict_type = AV_PICTURE_TYPE_I;
depth = bytestream2_get_byte(gb);
if (depth != c->bpp) {
av_log(avctx, AV_LOG_INFO,
@@ -460,7 +459,7 @@
return AVERROR_INVALIDDATA;
}
paint_raw(outptr, w, h, gb, c->bpp2, c->bigendian,
- frame->linesize[0]);
+ c->pic->linesize[0]);
break;
case 0x00000005: // HexTile encoded rectangle
if ((dx + w > c->width) || (dy + h > c->height)) {
@@ -469,7 +468,7 @@
w, h, dx, dy, c->width, c->height);
return AVERROR_INVALIDDATA;
}
- res = decode_hextile(c, outptr, gb, w, h, frame->linesize[0]);
+ res = decode_hextile(c, outptr, gb, w, h, c->pic->linesize[0]);
if (res < 0)
return res;
break;
@@ -498,18 +497,18 @@
dy = 0;
}
if ((w > 0) && (h > 0)) {
- outptr = frame->data[0] + dx * c->bpp2 + dy * frame->linesize[0];
+ outptr = c->pic->data[0] + dx * c->bpp2 + dy * c->pic->linesize[0];
for (i = 0; i < h; i++) {
memcpy(c->screendta + i * c->cur_w * c->bpp2, outptr,
w * c->bpp2);
- outptr += frame->linesize[0];
+ outptr += c->pic->linesize[0];
}
- outptr = frame->data[0];
- put_cursor(outptr, frame->linesize[0], c, c->cur_x, c->cur_y);
+ outptr = c->pic->data[0];
+ put_cursor(outptr, c->pic->linesize[0], c, c->cur_x, c->cur_y);
}
}
*got_frame = 1;
- if ((ret = av_frame_ref(data, frame)) < 0)
+ if ((ret = av_frame_ref(data, c->pic)) < 0)
return ret;
/* always report that the buffer was completely consumed */
@@ -541,8 +540,8 @@
return AVERROR_INVALIDDATA;
}
- c->frame = av_frame_alloc();
- if (!c->frame)
+ c->pic = av_frame_alloc();
+ if (!c->pic)
return AVERROR(ENOMEM);
return 0;
@@ -552,7 +551,7 @@
{
VmncContext * const c = avctx->priv_data;
- av_frame_free(&c->frame);
+ av_frame_free(&c->pic);
av_freep(&c->curbits);
av_freep(&c->curmask);
diff --git a/libavcodec/vorbis_parser.c b/libavcodec/vorbis_parser.c
index fcbecc8..1e2cab3 100644
--- a/libavcodec/vorbis_parser.c
+++ b/libavcodec/vorbis_parser.c
@@ -201,8 +201,8 @@
return 0;
}
-int avpriv_vorbis_parse_frame(VorbisParseContext *s, const uint8_t *buf,
- int buf_size)
+int avpriv_vorbis_parse_frame_flags(VorbisParseContext *s, const uint8_t *buf,
+ int buf_size, int *flags)
{
int duration = 0;
@@ -211,6 +211,22 @@
int previous_blocksize = s->previous_blocksize;
if (buf[0] & 1) {
+ /* If the user doesn't care about special packets, it's a bad one. */
+ if (!flags)
+ goto bad_packet;
+
+ /* Set the flag for which kind of special packet it is. */
+ if (buf[0] == 1)
+ *flags |= VORBIS_FLAG_HEADER;
+ else if (buf[0] == 3)
+ *flags |= VORBIS_FLAG_COMMENT;
+ else
+ goto bad_packet;
+
+ /* Special packets have no duration. */
+ return 0;
+
+bad_packet:
av_log(s->avctx, AV_LOG_ERROR, "Invalid packet\n");
return AVERROR_INVALIDDATA;
}
@@ -234,6 +250,12 @@
return duration;
}
+int avpriv_vorbis_parse_frame(VorbisParseContext *s, const uint8_t *buf,
+ int buf_size)
+{
+ return avpriv_vorbis_parse_frame_flags(s, buf, buf_size, NULL);
+}
+
void avpriv_vorbis_parse_reset(VorbisParseContext *s)
{
if (s->valid_extradata)
diff --git a/libavcodec/vorbis_parser.h b/libavcodec/vorbis_parser.h
index 101df5d..590101b 100644
--- a/libavcodec/vorbis_parser.h
+++ b/libavcodec/vorbis_parser.h
@@ -50,6 +50,24 @@
*/
int avpriv_vorbis_parse_extradata(AVCodecContext *avctx, VorbisParseContext *s);
+#define VORBIS_FLAG_HEADER 0x00000001
+#define VORBIS_FLAG_COMMENT 0x00000002
+
+/**
+ * Get the duration for a Vorbis packet.
+ *
+ * avpriv_vorbis_parse_extradata() must have been successfully called prior to
+ * this in order for a correct duration to be returned. If @p flags is @c NULL,
+ * special frames are considered invalid.
+ *
+ * @param s Vorbis parser context
+ * @param buf buffer containing a Vorbis frame
+ * @param buf_size size of the buffer
+ * @param flags flags for special frames
+ */
+int avpriv_vorbis_parse_frame_flags(VorbisParseContext *s, const uint8_t *buf,
+ int buf_size, int *flags);
+
/**
* Get the duration for a Vorbis packet.
*
diff --git a/libavcodec/vp3.c b/libavcodec/vp3.c
index 12fe3ab..626642f 100644
--- a/libavcodec/vp3.c
+++ b/libavcodec/vp3.c
@@ -1294,7 +1294,7 @@
int width = s->fragment_width[!!plane];
int height = s->fragment_height[!!plane];
int fragment = s->fragment_start [plane] + ystart * width;
- int stride = s->current_frame.f->linesize[plane];
+ ptrdiff_t stride = s->current_frame.f->linesize[plane];
uint8_t *plane_data = s->current_frame.f->data [plane];
if (!s->flipped_image) stride = -stride;
plane_data += s->data_offset[plane] + 8*ystart*stride;
@@ -1549,10 +1549,11 @@
uint8_t *temp= s->edge_emu_buffer;
if(stride<0) temp -= 8*stride;
- s->vdsp.emulated_edge_mc(temp, stride,
- motion_source, stride,
+ s->vdsp.emulated_edge_mc(temp, motion_source,
+ stride, stride,
9, 9, src_x, src_y,
- plane_width, plane_height);
+ plane_width,
+ plane_height);
motion_source= temp;
}
}
@@ -2196,6 +2197,7 @@
Vp3DecodeContext *s = avctx->priv_data;
int visible_width, visible_height, colorspace;
int offset_x = 0, offset_y = 0;
+ int ret;
AVRational fps, aspect;
s->theora = get_bits_long(gb, 24);
@@ -2212,12 +2214,6 @@
visible_width = s->width = get_bits(gb, 16) << 4;
visible_height = s->height = get_bits(gb, 16) << 4;
- if(av_image_check_size(s->width, s->height, 0, avctx)){
- av_log(avctx, AV_LOG_ERROR, "Invalid dimensions (%dx%d)\n", s->width, s->height);
- s->width= s->height= 0;
- return -1;
- }
-
if (s->theora >= 0x030200) {
visible_width = get_bits_long(gb, 24);
visible_height = get_bits_long(gb, 24);
@@ -2268,9 +2264,11 @@
if ( visible_width <= s->width && visible_width > s->width-16
&& visible_height <= s->height && visible_height > s->height-16
&& !offset_x && (offset_y == s->height - visible_height))
- avcodec_set_dimensions(avctx, visible_width, visible_height);
+ ret = ff_set_dimensions(avctx, visible_width, visible_height);
else
- avcodec_set_dimensions(avctx, s->width, s->height);
+ ret = ff_set_dimensions(avctx, s->width, s->height);
+ if (ret < 0)
+ return ret;
if (colorspace == 1) {
avctx->color_primaries = AVCOL_PRI_BT470M;
diff --git a/libavcodec/vp5.c b/libavcodec/vp5.c
index 2ab90b7..756dc92 100644
--- a/libavcodec/vp5.c
+++ b/libavcodec/vp5.c
@@ -28,6 +28,7 @@
#include "avcodec.h"
#include "get_bits.h"
+#include "internal.h"
#include "vp56.h"
#include "vp56data.h"
@@ -66,7 +67,9 @@
if (!s->macroblocks || /* first frame */
16*cols != s->avctx->coded_width ||
16*rows != s->avctx->coded_height) {
- avcodec_set_dimensions(s->avctx, 16*cols, 16*rows);
+ int ret = ff_set_dimensions(s->avctx, 16 * cols, 16 * rows);
+ if (ret < 0)
+ return ret;
return VP56_SIZE_CHANGE;
}
} else if (!s->macroblocks)
diff --git a/libavcodec/vp56.c b/libavcodec/vp56.c
index d7d08f2..a0cb060 100644
--- a/libavcodec/vp56.c
+++ b/libavcodec/vp56.c
@@ -303,7 +303,7 @@
}
static void vp56_deblock_filter(VP56Context *s, uint8_t *yuv,
- int stride, int dx, int dy)
+ ptrdiff_t stride, int dx, int dy)
{
int t = ff_vp56_filter_threshold[s->quantizer];
if (dx) s->vp56dsp.edge_filter_hor(yuv + 10-dx , stride, t);
@@ -339,11 +339,12 @@
if (x<0 || x+12>=s->plane_width[plane] ||
y<0 || y+12>=s->plane_height[plane]) {
- s->vdsp.emulated_edge_mc(s->edge_emu_buffer, stride,
- src + s->block_offset[b] + (dy-2)*stride + (dx-2),
- stride, 12, 12, x, y,
- s->plane_width[plane],
- s->plane_height[plane]);
+ s->vdsp.emulated_edge_mc(s->edge_emu_buffer,
+ src + s->block_offset[b] + (dy-2)*stride + (dx-2),
+ stride, stride,
+ 12, 12, x, y,
+ s->plane_width[plane],
+ s->plane_height[plane]);
src_block = s->edge_emu_buffer;
src_offset = 2 + 2*stride;
} else if (deblock_filtering) {
@@ -470,7 +471,7 @@
s->mb_height = (avctx->coded_height+15) / 16;
if (s->mb_width > 1000 || s->mb_height > 1000) {
- avcodec_set_dimensions(avctx, 0, 0);
+ ff_set_dimensions(avctx, 0, 0);
av_log(avctx, AV_LOG_ERROR, "picture too big\n");
return -1;
}
@@ -584,7 +585,8 @@
VP56Context *s = is_alpha ? s0->alpha_context : s0;
AVFrame *const p = s->frames[VP56_FRAME_CURRENT];
int mb_row, mb_col, mb_row_flip, mb_offset = 0;
- int block, y, uv, stride_y, stride_uv;
+ int block, y, uv;
+ ptrdiff_t stride_y, stride_uv;
int res;
if (p->key_frame) {
diff --git a/libavcodec/vp6.c b/libavcodec/vp6.c
index 4cf11ee..f552524 100644
--- a/libavcodec/vp6.c
+++ b/libavcodec/vp6.c
@@ -32,6 +32,7 @@
#include "avcodec.h"
#include "get_bits.h"
#include "huffman.h"
+#include "internal.h"
#include "vp56.h"
#include "vp56data.h"
@@ -92,7 +93,10 @@
s->avctx->coded_width = 16 * cols;
s->avctx->coded_height = 16 * rows;
} else {
- avcodec_set_dimensions(s->avctx, 16 * cols, 16 * rows);
+ int ret = ff_set_dimensions(s->avctx, 16 * cols, 16 * rows);
+ if (ret < 0)
+ return ret;
+
if (s->avctx->extradata_size == 1) {
s->avctx->width -= s->avctx->extradata[0] >> 4;
s->avctx->height -= s->avctx->extradata[0] & 0x0F;
@@ -154,7 +158,7 @@
buf_size -= coeff_offset;
if (buf_size < 0) {
if (s->frames[VP56_FRAME_CURRENT]->key_frame)
- avcodec_set_dimensions(s->avctx, 0, 0);
+ ff_set_dimensions(s->avctx, 0, 0);
return AVERROR_INVALIDDATA;
}
if (s->use_huffman) {
diff --git a/libavcodec/vp8.c b/libavcodec/vp8.c
index 46a75a1..4aaef88 100644
--- a/libavcodec/vp8.c
+++ b/libavcodec/vp8.c
@@ -113,16 +113,15 @@
static int update_dimensions(VP8Context *s, int width, int height)
{
AVCodecContext *avctx = s->avctx;
- int i;
+ int i, ret;
if (width != s->avctx->width || ((width+15)/16 != s->mb_width || (height+15)/16 != s->mb_height) && s->macroblocks_base ||
height != s->avctx->height) {
- if (av_image_check_size(width, height, 0, s->avctx))
- return AVERROR_INVALIDDATA;
-
vp8_decode_flush_impl(s->avctx, 1);
- avcodec_set_dimensions(s->avctx, width, height);
+ ret = ff_set_dimensions(s->avctx, width, height);
+ if (ret < 0)
+ return ret;
}
s->mb_width = (s->avctx->coded_width +15) / 16;
@@ -1197,8 +1196,9 @@
src += y_off * linesize + x_off;
if (x_off < mx_idx || x_off >= width - block_w - subpel_idx[2][mx] ||
y_off < my_idx || y_off >= height - block_h - subpel_idx[2][my]) {
- s->vdsp.emulated_edge_mc(td->edge_emu_buffer, 32,
- src - my_idx * linesize - mx_idx, linesize,
+ s->vdsp.emulated_edge_mc(td->edge_emu_buffer,
+ src - my_idx * linesize - mx_idx,
+ 32, linesize,
block_w + subpel_idx[1][mx],
block_h + subpel_idx[1][my],
x_off - mx_idx, y_off - my_idx, width, height);
@@ -1250,16 +1250,18 @@
ff_thread_await_progress(ref, (3 + y_off + block_h + subpel_idx[2][my]) >> 3, 0);
if (x_off < mx_idx || x_off >= width - block_w - subpel_idx[2][mx] ||
y_off < my_idx || y_off >= height - block_h - subpel_idx[2][my]) {
- s->vdsp.emulated_edge_mc(td->edge_emu_buffer, 32,
- src1 - my_idx * linesize - mx_idx, linesize,
+ s->vdsp.emulated_edge_mc(td->edge_emu_buffer,
+ src1 - my_idx * linesize - mx_idx,
+ 32, linesize,
block_w + subpel_idx[1][mx],
block_h + subpel_idx[1][my],
x_off - mx_idx, y_off - my_idx, width, height);
src1 = td->edge_emu_buffer + mx_idx + 32 * my_idx;
mc_func[my_idx][mx_idx](dst1, linesize, src1, 32, block_h, mx, my);
- s->vdsp.emulated_edge_mc(td->edge_emu_buffer, 32,
- src2 - my_idx * linesize - mx_idx, linesize,
+ s->vdsp.emulated_edge_mc(td->edge_emu_buffer,
+ src2 - my_idx * linesize - mx_idx,
+ 32, linesize,
block_w + subpel_idx[1][mx],
block_h + subpel_idx[1][my],
x_off - mx_idx, y_off - my_idx, width, height);
@@ -2113,52 +2115,6 @@
return 0;
}
-static unsigned apply_padding(unsigned size) { return size + (size & 1); }
-
-static int webp_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
- AVPacket *avpkt)
-{
- const uint8_t *buf = avpkt->data;
- int buf_size = avpkt->size;
- AVPacket pkt = *avpkt;
-
- if (buf_size >= 16
- && AV_RL32(buf ) == AV_RL32("RIFF")
- && AV_RL32(buf+ 8) == AV_RL32("WEBP")) {
- unsigned riff_size = apply_padding(AV_RL32(buf+4)) + 8;
- buf += 12; // Skip over main header
- buf_size -= 12;
- if (buf_size < 8 || riff_size < 8) {
- av_log(avctx, AV_LOG_ERROR, "Incomplete header.\n");
- return AVERROR_INVALIDDATA;
- }
- if (AV_RL32(buf) == AV_RL32("VP8L")) {
- av_log(avctx, AV_LOG_ERROR, "Unsupported WebP lossless format.\n");
- return AVERROR_PATCHWELCOME;
- }
- if (AV_RL32(buf) == AV_RL32("VP8X") && AV_RL32(buf+4) < (unsigned)buf_size) {
- unsigned size = apply_padding(AV_RL32(buf+4) + 8);
- buf += size;
- buf_size -= size;
- }
- if (buf_size >= 8
- && AV_RL32(buf) == AV_RL32("ALPH") && AV_RL32(buf+4) < (unsigned)buf_size) {
- unsigned size = apply_padding(AV_RL32(buf+4) + 8);
- buf += size;
- buf_size -= size;
- av_log(avctx, AV_LOG_WARNING, "Skipping alpha plane\n");
- }
- if (buf_size >= 8 && AV_RL32(buf) == AV_RL32("VP8 ")) {
- buf += 8;
- buf_size -= 8;
- }
- }
- pkt.data = buf;
- pkt.size = buf_size;
-
- return ff_vp8_decode_frame(avctx, data, data_size, &pkt);
-}
-
AVCodec ff_vp8_decoder = {
.name = "vp8",
.long_name = NULL_IF_CONFIG_SMALL("On2 VP8"),
@@ -2174,17 +2130,3 @@
.update_thread_context = ONLY_IF_THREADS_ENABLED(vp8_decode_update_thread_context),
};
-// AVCodec ff_webp_decoder = {
-// .name = "webp",
-// .long_name = NULL_IF_CONFIG_SMALL("WebP"),
-// .type = AVMEDIA_TYPE_VIDEO,
-// .id = AV_CODEC_ID_WEBP,
-// .priv_data_size = sizeof(VP8Context),
-// .init = vp8_decode_init,
-// .close = vp8_decode_free,
-// .decode = webp_decode_frame,
-// .capabilities = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS | CODEC_CAP_SLICE_THREADS,
-// .flush = vp8_decode_flush,
-// .init_thread_copy = ONLY_IF_THREADS_ENABLED(vp8_decode_init_thread_copy),
-// .update_thread_context = ONLY_IF_THREADS_ENABLED(vp8_decode_update_thread_context),
-// };
diff --git a/libavcodec/vp9.c b/libavcodec/vp9.c
index 0eb92f8..a52924c 100644
--- a/libavcodec/vp9.c
+++ b/libavcodec/vp9.c
@@ -24,6 +24,7 @@
#include "avcodec.h"
#include "get_bits.h"
#include "internal.h"
+#include "thread.h"
#include "videodsp.h"
#include "vp56.h"
#include "vp9.h"
@@ -68,6 +69,13 @@
int8_t ref[2];
};
+typedef struct VP9Frame {
+ ThreadFrame tf;
+ AVBufferRef *extradata;
+ uint8_t *segmentation_map;
+ struct VP9mvrefPair *mv;
+} VP9Frame;
+
struct VP9Filter {
uint8_t level[8 * 8];
uint8_t /* bit=col */ mask[2 /* 0=y, 1=uv */][2 /* 0=col, 1=row */]
@@ -80,10 +88,8 @@
VP56mv mv[4 /* b_idx */][2 /* ref */];
enum BlockSize bs;
enum TxfmMode tx, uvtx;
-
- int row, row7, col, col7;
- uint8_t *dst[3];
- ptrdiff_t y_stride, uv_stride;
+ enum BlockLevel bl;
+ enum BlockPartition bp;
} VP9Block;
typedef struct VP9Context {
@@ -93,12 +99,16 @@
VP56RangeCoder c;
VP56RangeCoder *c_b;
unsigned c_b_size;
- VP9Block b;
+ VP9Block *b_base, *b;
+ int pass, uses_2pass, last_uses_2pass;
+ int row, row7, col, col7;
+ uint8_t *dst[3];
+ ptrdiff_t y_stride, uv_stride;
// bitstream header
uint8_t profile;
uint8_t keyframe, last_keyframe;
- uint8_t invisible, last_invisible;
+ uint8_t invisible;
uint8_t use_last_frame_mvs;
uint8_t errorres;
uint8_t colorspace;
@@ -116,7 +126,10 @@
uint8_t refidx[3];
uint8_t signbias[3];
uint8_t varcompref[2];
- AVFrame *refs[8], *f, *fb[10];
+ ThreadFrame refs[8], next_refs[8];
+#define CUR_FRAME 0
+#define LAST_FRAME 1
+ VP9Frame frames[2];
struct {
uint8_t level;
@@ -213,16 +226,12 @@
// whole-frame cache
uint8_t *intra_pred_data[3];
- uint8_t *segmentation_map;
- struct VP9mvrefPair *mv[2];
struct VP9Filter *lflvl;
DECLARE_ALIGNED(32, uint8_t, edge_emu_buffer)[71*80];
// block reconstruction intermediates
- DECLARE_ALIGNED(32, int16_t, block)[4096];
- DECLARE_ALIGNED(32, int16_t, uvblock)[2][1024];
- uint8_t eob[256];
- uint8_t uveob[2][64];
+ int16_t *block_base, *block, *uvblock_base[2], *uvblock[2];
+ uint8_t *eob_base, *uveob_base[2], *eob, *uveob[2];
VP56mv min_mv, max_mv;
DECLARE_ALIGNED(32, uint8_t, tmp_y)[64*64];
DECLARE_ALIGNED(32, uint8_t, tmp_uv)[2][32*32];
@@ -238,11 +247,60 @@
}
};
+static int vp9_alloc_frame(AVCodecContext *ctx, VP9Frame *f)
+{
+ VP9Context *s = ctx->priv_data;
+ int ret, sz;
+
+ if ((ret = ff_thread_get_buffer(ctx, &f->tf, AV_GET_BUFFER_FLAG_REF)) < 0)
+ return ret;
+ sz = 64 * s->sb_cols * s->sb_rows;
+ if (!(f->extradata = av_buffer_allocz(sz * (1 + sizeof(struct VP9mvrefPair))))) {
+ ff_thread_release_buffer(ctx, &f->tf);
+ return AVERROR(ENOMEM);
+ }
+
+ f->segmentation_map = f->extradata->data;
+ f->mv = (struct VP9mvrefPair *) (f->extradata->data + sz);
+
+ // retain segmentation map if it doesn't update
+ if (s->segmentation.enabled && !s->segmentation.update_map) {
+ memcpy(f->segmentation_map, s->frames[LAST_FRAME].segmentation_map, sz);
+ }
+
+ return 0;
+}
+
+static void vp9_unref_frame(AVCodecContext *ctx, VP9Frame *f)
+{
+ ff_thread_release_buffer(ctx, &f->tf);
+ av_buffer_unref(&f->extradata);
+}
+
+static int vp9_ref_frame(AVCodecContext *ctx, VP9Frame *dst, VP9Frame *src)
+{
+ int res;
+
+ if ((res = ff_thread_ref_frame(&dst->tf, &src->tf)) < 0) {
+ return res;
+ } else if (!(dst->extradata = av_buffer_ref(src->extradata))) {
+ vp9_unref_frame(ctx, dst);
+ return AVERROR(ENOMEM);
+ }
+
+ dst->segmentation_map = src->segmentation_map;
+ dst->mv = src->mv;
+
+ return 0;
+}
+
static int update_size(AVCodecContext *ctx, int w, int h)
{
VP9Context *s = ctx->priv_data;
uint8_t *p;
+ av_assert0(w > 0 && h > 0);
+
if (s->above_partition_ctx && w == ctx->width && h == ctx->height)
return 0;
@@ -254,9 +312,8 @@
s->rows = (h + 7) >> 3;
#define assign(var, type, n) var = (type) p; p += s->sb_cols * n * sizeof(*var)
- av_free(s->above_partition_ctx);
- p = av_malloc(s->sb_cols * (240 + sizeof(*s->lflvl) + 16 * sizeof(*s->above_mv_ctx) +
- 64 * s->sb_rows * (1 + sizeof(*s->mv[0]) * 2)));
+ av_freep(&s->above_partition_ctx);
+ p = av_malloc(s->sb_cols * (240 + sizeof(*s->lflvl) + 16 * sizeof(*s->above_mv_ctx)));
if (!p)
return AVERROR(ENOMEM);
assign(s->above_partition_ctx, uint8_t *, 8);
@@ -276,11 +333,34 @@
assign(s->above_filter_ctx, uint8_t *, 8);
assign(s->lflvl, struct VP9Filter *, 1);
assign(s->above_mv_ctx, VP56mv(*)[2], 16);
- assign(s->segmentation_map, uint8_t *, 64 * s->sb_rows);
- assign(s->mv[0], struct VP9mvrefPair *, 64 * s->sb_rows);
- assign(s->mv[1], struct VP9mvrefPair *, 64 * s->sb_rows);
#undef assign
+ av_free(s->b_base);
+ av_free(s->block_base);
+ if (ctx->active_thread_type == FF_THREAD_FRAME && s->refreshctx && !s->parallelmode) {
+ int sbs = s->sb_cols * s->sb_rows;
+
+ s->b_base = av_malloc(sizeof(VP9Block) * s->cols * s->rows);
+ s->block_base = av_mallocz((64 * 64 + 128) * sbs * 3);
+ if (!s->b_base || !s->block_base)
+ return AVERROR(ENOMEM);
+ s->uvblock_base[0] = s->block_base + sbs * 64 * 64;
+ s->uvblock_base[1] = s->uvblock_base[0] + sbs * 32 * 32;
+ s->eob_base = (uint8_t *) (s->uvblock_base[1] + sbs * 32 * 32);
+ s->uveob_base[0] = s->eob_base + 256 * sbs;
+ s->uveob_base[1] = s->uveob_base[0] + 64 * sbs;
+ } else {
+ s->b_base = av_malloc(sizeof(VP9Block));
+ s->block_base = av_mallocz((64 * 64 + 128) * 3);
+ if (!s->b_base || !s->block_base)
+ return AVERROR(ENOMEM);
+ s->uvblock_base[0] = s->block_base + 64 * 64;
+ s->uvblock_base[1] = s->uvblock_base[0] + 32 * 32;
+ s->eob_base = (uint8_t *) (s->uvblock_base[1] + 32 * 32);
+ s->uveob_base[0] = s->eob_base + 256;
+ s->uveob_base[1] = s->uveob_base[0] + 64;
+ }
+
return 0;
}
@@ -359,11 +439,12 @@
{
VP9Context *s = ctx->priv_data;
int c, i, j, k, l, m, n, w, h, max, size2, res, sharp;
+ int last_invisible;
const uint8_t *data2;
/* general header */
if ((res = init_get_bits8(&s->gb, data, size)) < 0) {
- av_log(ctx, AV_LOG_ERROR, "Failed to intialize bitstream reader\n");
+ av_log(ctx, AV_LOG_ERROR, "Failed to initialize bitstream reader\n");
return res;
}
if (get_bits(&s->gb, 2) != 0x2) { // frame marker
@@ -379,13 +460,14 @@
*ref = get_bits(&s->gb, 3);
return 0;
}
+ s->last_uses_2pass = s->uses_2pass;
s->last_keyframe = s->keyframe;
s->keyframe = !get_bits1(&s->gb);
- s->last_invisible = s->invisible;
+ last_invisible = s->invisible;
s->invisible = !get_bits1(&s->gb);
s->errorres = get_bits1(&s->gb);
// FIXME disable this upon resolution change
- s->use_last_frame_mvs = !s->errorres && !s->last_invisible;
+ s->use_last_frame_mvs = !s->errorres && !last_invisible;
if (s->keyframe) {
if (get_bits_long(&s->gb, 24) != VP9_SYNCCODE) { // synccode
av_log(ctx, AV_LOG_ERROR, "Invalid sync code\n");
@@ -424,20 +506,21 @@
s->signbias[1] = get_bits1(&s->gb);
s->refidx[2] = get_bits(&s->gb, 3);
s->signbias[2] = get_bits1(&s->gb);
- if (!s->refs[s->refidx[0]] || !s->refs[s->refidx[1]] ||
- !s->refs[s->refidx[2]]) {
+ if (!s->refs[s->refidx[0]].f->data[0] ||
+ !s->refs[s->refidx[1]].f->data[0] ||
+ !s->refs[s->refidx[2]].f->data[0]) {
av_log(ctx, AV_LOG_ERROR, "Not all references are available\n");
return AVERROR_INVALIDDATA;
}
if (get_bits1(&s->gb)) {
- w = s->refs[s->refidx[0]]->width;
- h = s->refs[s->refidx[0]]->height;
+ w = s->refs[s->refidx[0]].f->width;
+ h = s->refs[s->refidx[0]].f->height;
} else if (get_bits1(&s->gb)) {
- w = s->refs[s->refidx[1]]->width;
- h = s->refs[s->refidx[1]]->height;
+ w = s->refs[s->refidx[1]].f->width;
+ h = s->refs[s->refidx[1]].f->height;
} else if (get_bits1(&s->gb)) {
- w = s->refs[s->refidx[2]]->width;
- h = s->refs[s->refidx[2]]->height;
+ w = s->refs[s->refidx[2]].f->width;
+ h = s->refs[s->refidx[2]].f->height;
} else {
w = get_bits(&s->gb, 16) + 1;
h = get_bits(&s->gb, 16) + 1;
@@ -857,8 +940,8 @@
[BS_4x4] = {{ 0, -1 }, { -1, 0 }, { -1, -1 }, { 0, -2 },
{ -2, 0 }, { -1, -2 }, { -2, -1 }, { -2, -2 }},
};
- VP9Block *const b = &s->b;
- int row = b->row, col = b->col, row7 = b->row7;
+ VP9Block *b = s->b;
+ int row = s->row, col = s->col, row7 = s->row7;
const int8_t (*p)[2] = mv_ref_blk_off[b->bs];
#define INVALID_MV 0x80008000U
uint32_t mem = INVALID_MV;
@@ -918,7 +1001,7 @@
} while (0)
if (row > 0) {
- struct VP9mvrefPair *mv = &s->mv[0][(row - 1) * s->sb_cols * 8 + col];
+ struct VP9mvrefPair *mv = &s->frames[CUR_FRAME].mv[(row - 1) * s->sb_cols * 8 + col];
if (mv->ref[0] == ref) {
RETURN_MV(s->above_mv_ctx[2 * col + (sb & 1)][0]);
} else if (mv->ref[1] == ref) {
@@ -926,7 +1009,7 @@
}
}
if (col > s->tiling.tile_col_start) {
- struct VP9mvrefPair *mv = &s->mv[0][row * s->sb_cols * 8 + col - 1];
+ struct VP9mvrefPair *mv = &s->frames[CUR_FRAME].mv[row * s->sb_cols * 8 + col - 1];
if (mv->ref[0] == ref) {
RETURN_MV(s->left_mv_ctx[2 * row7 + (sb >> 1)][0]);
} else if (mv->ref[1] == ref) {
@@ -943,7 +1026,7 @@
int c = p[i][0] + col, r = p[i][1] + row;
if (c >= s->tiling.tile_col_start && c < s->cols && r >= 0 && r < s->rows) {
- struct VP9mvrefPair *mv = &s->mv[0][r * s->sb_cols * 8 + c];
+ struct VP9mvrefPair *mv = &s->frames[CUR_FRAME].mv[r * s->sb_cols * 8 + c];
if (mv->ref[0] == ref) {
RETURN_MV(mv->mv[0]);
@@ -955,8 +1038,10 @@
// MV at this position in previous frame, using same reference frame
if (s->use_last_frame_mvs) {
- struct VP9mvrefPair *mv = &s->mv[1][row * s->sb_cols * 8 + col];
+ struct VP9mvrefPair *mv = &s->frames[LAST_FRAME].mv[row * s->sb_cols * 8 + col];
+ if (!s->last_uses_2pass)
+ ff_thread_await_progress(&s->frames[LAST_FRAME].tf, row >> 3, 0);
if (mv->ref[0] == ref) {
RETURN_MV(mv->mv[0]);
} else if (mv->ref[1] == ref) {
@@ -979,12 +1064,15 @@
int c = p[i][0] + col, r = p[i][1] + row;
if (c >= s->tiling.tile_col_start && c < s->cols && r >= 0 && r < s->rows) {
- struct VP9mvrefPair *mv = &s->mv[0][r * s->sb_cols * 8 + c];
+ struct VP9mvrefPair *mv = &s->frames[CUR_FRAME].mv[r * s->sb_cols * 8 + c];
if (mv->ref[0] != ref && mv->ref[0] >= 0) {
RETURN_SCALE_MV(mv->mv[0], s->signbias[mv->ref[0]] != s->signbias[ref]);
}
- if (mv->ref[1] != ref && mv->ref[1] >= 0) {
+ if (mv->ref[1] != ref && mv->ref[1] >= 0 &&
+ // BUG - libvpx has this condition regardless of whether
+ // we used the first ref MV and pre-scaling
+ AV_RN32A(&mv->mv[0]) != AV_RN32A(&mv->mv[1])) {
RETURN_SCALE_MV(mv->mv[1], s->signbias[mv->ref[1]] != s->signbias[ref]);
}
}
@@ -992,12 +1080,16 @@
// MV at this position in previous frame, using different reference frame
if (s->use_last_frame_mvs) {
- struct VP9mvrefPair *mv = &s->mv[1][row * s->sb_cols * 8 + col];
+ struct VP9mvrefPair *mv = &s->frames[LAST_FRAME].mv[row * s->sb_cols * 8 + col];
+ // no need to await_progress, because we already did that above
if (mv->ref[0] != ref && mv->ref[0] >= 0) {
RETURN_SCALE_MV(mv->mv[0], s->signbias[mv->ref[0]] != s->signbias[ref]);
}
- if (mv->ref[1] != ref && mv->ref[1] >= 0) {
+ if (mv->ref[1] != ref && mv->ref[1] >= 0 &&
+ // BUG - libvpx has this condition regardless of whether
+ // we used the first ref MV and pre-scaling
+ AV_RN32A(&mv->mv[0]) != AV_RN32A(&mv->mv[1])) {
RETURN_SCALE_MV(mv->mv[1], s->signbias[mv->ref[1]] != s->signbias[ref]);
}
}
@@ -1064,7 +1156,7 @@
static void fill_mv(VP9Context *s,
VP56mv *mv, int mode, int sb)
{
- VP9Block *const b = &s->b;
+ VP9Block *b = s->b;
if (mode == ZEROMV) {
memset(mv, 0, sizeof(*mv) * 2);
@@ -1147,8 +1239,8 @@
TX_16X16, TX_8X8, TX_8X8, TX_8X8, TX_4X4, TX_4X4, TX_4X4
};
VP9Context *s = ctx->priv_data;
- VP9Block *const b = &s->b;
- int row = b->row, col = b->col, row7 = b->row7;
+ VP9Block *b = s->b;
+ int row = s->row, col = s->col, row7 = s->row7;
enum TxfmMode max_tx = max_tx_for_bl_bp[b->bs];
int w4 = FFMIN(s->cols - col, bwh_tab[1][b->bs][0]);
int h4 = FFMIN(s->rows - row, bwh_tab[1][b->bs][1]), y;
@@ -1165,10 +1257,14 @@
s->prob.segpred[s->above_segpred_ctx[col] +
s->left_segpred_ctx[row7]]))) {
int pred = 8, x;
+ uint8_t *refsegmap = s->frames[LAST_FRAME].segmentation_map;
+ if (!s->last_uses_2pass)
+ ff_thread_await_progress(&s->frames[LAST_FRAME].tf, row >> 3, 0);
for (y = 0; y < h4; y++)
for (x = 0; x < w4; x++)
- pred = FFMIN(pred, s->segmentation_map[(y + row) * 8 * s->sb_cols + x + col]);
+ pred = FFMIN(pred, refsegmap[(y + row) * 8 * s->sb_cols + x + col]);
+ av_assert1(pred < 8);
b->seg_id = pred;
memset(&s->above_segpred_ctx[col], 1, w4);
@@ -1181,9 +1277,10 @@
memset(&s->left_segpred_ctx[row7], 0, h4);
}
if ((s->segmentation.enabled && s->segmentation.update_map) || s->keyframe) {
+ uint8_t *segmap = s->frames[CUR_FRAME].segmentation_map;
+
for (y = 0; y < h4; y++)
- memset(&s->segmentation_map[(y + row) * 8 * s->sb_cols + col],
- b->seg_id, w4);
+ memset(&segmap[(y + row) * 8 * s->sb_cols + col], b->seg_id, w4);
}
b->skip = s->segmentation.enabled &&
@@ -1757,24 +1854,25 @@
// FIXME kinda ugly
for (y = 0; y < h4; y++) {
int x, o = (row + y) * s->sb_cols * 8 + col;
+ struct VP9mvrefPair *mv = &s->frames[CUR_FRAME].mv[o];
if (b->intra) {
for (x = 0; x < w4; x++) {
- s->mv[0][o + x].ref[0] =
- s->mv[0][o + x].ref[1] = -1;
+ mv[x].ref[0] =
+ mv[x].ref[1] = -1;
}
} else if (b->comp) {
for (x = 0; x < w4; x++) {
- s->mv[0][o + x].ref[0] = b->ref[0];
- s->mv[0][o + x].ref[1] = b->ref[1];
- AV_COPY32(&s->mv[0][o + x].mv[0], &b->mv[3][0]);
- AV_COPY32(&s->mv[0][o + x].mv[1], &b->mv[3][1]);
+ mv[x].ref[0] = b->ref[0];
+ mv[x].ref[1] = b->ref[1];
+ AV_COPY32(&mv[x].mv[0], &b->mv[3][0]);
+ AV_COPY32(&mv[x].mv[1], &b->mv[3][1]);
}
} else {
for (x = 0; x < w4; x++) {
- s->mv[0][o + x].ref[0] = b->ref[0];
- s->mv[0][o + x].ref[1] = -1;
- AV_COPY32(&s->mv[0][o + x].mv[0], &b->mv[3][0]);
+ mv[x].ref[0] = b->ref[0];
+ mv[x].ref[1] = -1;
+ AV_COPY32(&mv[x].mv[0], &b->mv[3][0]);
}
}
}
@@ -1835,43 +1933,43 @@
if (!vp56_rac_get_prob_branchy(c, tp[7])) {
val = 5 + vp56_rac_get_prob(c, 159);
} else {
- val = 7 + (vp56_rac_get_prob(c, 165) << 1) +
- vp56_rac_get_prob(c, 145);
+ val = 7 + (vp56_rac_get_prob(c, 165) << 1);
+ val += vp56_rac_get_prob(c, 145);
}
} else { // cat 3-6
cache[rc] = 5;
if (!vp56_rac_get_prob_branchy(c, tp[8])) {
if (!vp56_rac_get_prob_branchy(c, tp[9])) {
- val = 11 + (vp56_rac_get_prob(c, 173) << 2) +
- (vp56_rac_get_prob(c, 148) << 1) +
- vp56_rac_get_prob(c, 140);
+ val = 11 + (vp56_rac_get_prob(c, 173) << 2);
+ val += (vp56_rac_get_prob(c, 148) << 1);
+ val += vp56_rac_get_prob(c, 140);
} else {
- val = 19 + (vp56_rac_get_prob(c, 176) << 3) +
- (vp56_rac_get_prob(c, 155) << 2) +
- (vp56_rac_get_prob(c, 140) << 1) +
- vp56_rac_get_prob(c, 135);
+ val = 19 + (vp56_rac_get_prob(c, 176) << 3);
+ val += (vp56_rac_get_prob(c, 155) << 2);
+ val += (vp56_rac_get_prob(c, 140) << 1);
+ val += vp56_rac_get_prob(c, 135);
}
} else if (!vp56_rac_get_prob_branchy(c, tp[10])) {
- val = 35 + (vp56_rac_get_prob(c, 180) << 4) +
- (vp56_rac_get_prob(c, 157) << 3) +
- (vp56_rac_get_prob(c, 141) << 2) +
- (vp56_rac_get_prob(c, 134) << 1) +
- vp56_rac_get_prob(c, 130);
+ val = 35 + (vp56_rac_get_prob(c, 180) << 4);
+ val += (vp56_rac_get_prob(c, 157) << 3);
+ val += (vp56_rac_get_prob(c, 141) << 2);
+ val += (vp56_rac_get_prob(c, 134) << 1);
+ val += vp56_rac_get_prob(c, 130);
} else {
- val = 67 + (vp56_rac_get_prob(c, 254) << 13) +
- (vp56_rac_get_prob(c, 254) << 12) +
- (vp56_rac_get_prob(c, 254) << 11) +
- (vp56_rac_get_prob(c, 252) << 10) +
- (vp56_rac_get_prob(c, 249) << 9) +
- (vp56_rac_get_prob(c, 243) << 8) +
- (vp56_rac_get_prob(c, 230) << 7) +
- (vp56_rac_get_prob(c, 196) << 6) +
- (vp56_rac_get_prob(c, 177) << 5) +
- (vp56_rac_get_prob(c, 153) << 4) +
- (vp56_rac_get_prob(c, 140) << 3) +
- (vp56_rac_get_prob(c, 133) << 2) +
- (vp56_rac_get_prob(c, 130) << 1) +
- vp56_rac_get_prob(c, 129);
+ val = 67 + (vp56_rac_get_prob(c, 254) << 13);
+ val += (vp56_rac_get_prob(c, 254) << 12);
+ val += (vp56_rac_get_prob(c, 254) << 11);
+ val += (vp56_rac_get_prob(c, 252) << 10);
+ val += (vp56_rac_get_prob(c, 249) << 9);
+ val += (vp56_rac_get_prob(c, 243) << 8);
+ val += (vp56_rac_get_prob(c, 230) << 7);
+ val += (vp56_rac_get_prob(c, 196) << 6);
+ val += (vp56_rac_get_prob(c, 177) << 5);
+ val += (vp56_rac_get_prob(c, 153) << 4);
+ val += (vp56_rac_get_prob(c, 140) << 3);
+ val += (vp56_rac_get_prob(c, 133) << 2);
+ val += (vp56_rac_get_prob(c, 130) << 1);
+ val += vp56_rac_get_prob(c, 129);
}
}
}
@@ -1888,11 +1986,11 @@
return i;
}
-static int decode_coeffs(AVCodecContext *ctx)
+static void decode_coeffs(AVCodecContext *ctx)
{
VP9Context *s = ctx->priv_data;
- VP9Block *const b = &s->b;
- int row = b->row, col = b->col;
+ VP9Block *b = s->b;
+ int row = s->row, col = s->col;
uint8_t (*p)[6][11] = s->prob.coef[b->tx][0 /* y */][!b->intra];
unsigned (*c)[6][3] = s->counts.coef[b->tx][0 /* y */][!b->intra];
unsigned (*e)[6][2] = s->counts.eob[b->tx][0 /* y */][!b->intra];
@@ -1903,13 +2001,13 @@
int uvstep1d = 1 << b->uvtx, uvstep = 1 << (b->uvtx * 2), res;
int16_t (*qmul)[2] = s->segmentation.feat[b->seg_id].qmul;
int tx = 4 * s->lossless + b->tx;
- const int16_t **yscans = vp9_scans[tx];
- const int16_t (**ynbs)[2] = vp9_scans_nb[tx];
+ const int16_t * const *yscans = vp9_scans[tx];
+ const int16_t (* const *ynbs)[2] = vp9_scans_nb[tx];
const int16_t *uvscan = vp9_scans[b->uvtx][DCT_DCT];
const int16_t (*uvnb)[2] = vp9_scans_nb[b->uvtx][DCT_DCT];
uint8_t *a = &s->above_y_nnz_ctx[col * 2];
uint8_t *l = &s->left_y_nnz_ctx[(row & 7) << 1];
- static const int16_t band_counts[4][6] = {
+ static const int16_t band_counts[4][8] = {
{ 1, 2, 3, 4, 3, 16 - 13 },
{ 1, 2, 3, 4, 11, 64 - 21 },
{ 1, 2, 3, 4, 11, 256 - 21 },
@@ -1933,10 +2031,9 @@
b->bs > BS_8x8 ?
n : 0]];
int nnz = a[x] + l[y];
- if ((res = decode_coeffs_b(&s->c, s->block + 16 * n, 16 * step,
- b->tx, c, e, p, nnz, yscans[txtp],
- ynbs[txtp], y_band_counts, qmul[0])) < 0)
- return res;
+ res = decode_coeffs_b(&s->c, s->block + 16 * n, 16 * step,
+ b->tx, c, e, p, nnz, yscans[txtp],
+ ynbs[txtp], y_band_counts, qmul[0]);
a[x] = l[y] = !!res;
if (b->tx > TX_8X8) {
AV_WN16A(&s->eob[n], res);
@@ -1973,11 +2070,9 @@
for (n = 0, y = 0; y < end_y; y += uvstep1d) {
for (x = 0; x < end_x; x += uvstep1d, n += uvstep) {
int nnz = a[x] + l[y];
- if ((res = decode_coeffs_b(&s->c, s->uvblock[pl] + 16 * n,
- 16 * uvstep, b->uvtx, c, e, p, nnz,
- uvscan, uvnb, uv_band_counts,
- qmul[1])) < 0)
- return res;
+ res = decode_coeffs_b(&s->c, s->uvblock[pl] + 16 * n,
+ 16 * uvstep, b->uvtx, c, e, p, nnz,
+ uvscan, uvnb, uv_band_counts, qmul[1]);
a[x] = l[y] = !!res;
if (b->uvtx > TX_8X8) {
AV_WN16A(&s->uveob[pl][n], res);
@@ -1993,8 +2088,6 @@
memset(&a[x + 1], a[x], FFMIN(end_x - x - 1, uvstep1d - 1));
}
}
-
- return 0;
}
static av_always_inline int check_intra_mode(VP9Context *s, int mode, uint8_t **a,
@@ -2135,15 +2228,15 @@
static void intra_recon(AVCodecContext *ctx, ptrdiff_t y_off, ptrdiff_t uv_off)
{
VP9Context *s = ctx->priv_data;
- VP9Block *const b = &s->b;
- int row = b->row, col = b->col;
+ VP9Block *b = s->b;
+ int row = s->row, col = s->col;
int w4 = bwh_tab[1][b->bs][0] << 1, step1d = 1 << b->tx, n;
int h4 = bwh_tab[1][b->bs][1] << 1, x, y, step = 1 << (b->tx * 2);
int end_x = FFMIN(2 * (s->cols - col), w4);
int end_y = FFMIN(2 * (s->rows - row), h4);
int tx = 4 * s->lossless + b->tx, uvtx = b->uvtx + 4 * s->lossless;
int uvstep1d = 1 << b->uvtx, p;
- uint8_t *dst = b->dst[0], *dst_r = s->f->data[0] + y_off;
+ uint8_t *dst = s->dst[0], *dst_r = s->frames[CUR_FRAME].tf.f->data[0] + y_off;
for (n = 0, y = 0; y < end_y; y += step1d) {
uint8_t *ptr = dst, *ptr_r = dst_r;
@@ -2154,18 +2247,19 @@
LOCAL_ALIGNED_16(uint8_t, a_buf, [48]);
uint8_t *a = &a_buf[16], l[32];
enum TxfmType txtp = vp9_intra_txfm_type[mode];
- int eob = b->tx > TX_8X8 ? AV_RN16A(&s->eob[n]) : s->eob[n];
+ int eob = b->skip ? 0 : b->tx > TX_8X8 ? AV_RN16A(&s->eob[n]) : s->eob[n];
- mode = check_intra_mode(s, mode, &a, ptr_r, s->f->linesize[0],
- ptr, b->y_stride, l,
+ mode = check_intra_mode(s, mode, &a, ptr_r,
+ s->frames[CUR_FRAME].tf.f->linesize[0],
+ ptr, s->y_stride, l,
col, x, w4, row, y, b->tx, 0);
- s->dsp.intra_pred[b->tx][mode](ptr, b->y_stride, l, a);
+ s->dsp.intra_pred[b->tx][mode](ptr, s->y_stride, l, a);
if (eob)
- s->dsp.itxfm_add[tx][txtp](ptr, b->y_stride,
+ s->dsp.itxfm_add[tx][txtp](ptr, s->y_stride,
s->block + 16 * n, eob);
}
- dst_r += 4 * s->f->linesize[0] * step1d;
- dst += 4 * b->y_stride * step1d;
+ dst_r += 4 * step1d * s->frames[CUR_FRAME].tf.f->linesize[0];
+ dst += 4 * step1d * s->y_stride;
}
// U/V
@@ -2175,8 +2269,8 @@
end_y >>= 1;
step = 1 << (b->uvtx * 2);
for (p = 0; p < 2; p++) {
- dst = b->dst[1 + p];
- dst_r = s->f->data[1 + p] + uv_off;
+ dst = s->dst[1 + p];
+ dst_r = s->frames[CUR_FRAME].tf.f->data[1 + p] + uv_off;
for (n = 0, y = 0; y < end_y; y += uvstep1d) {
uint8_t *ptr = dst, *ptr_r = dst_r;
for (x = 0; x < end_x; x += uvstep1d, ptr += 4 * uvstep1d,
@@ -2184,18 +2278,19 @@
int mode = b->uvmode;
LOCAL_ALIGNED_16(uint8_t, a_buf, [48]);
uint8_t *a = &a_buf[16], l[32];
- int eob = b->uvtx > TX_8X8 ? AV_RN16A(&s->uveob[p][n]) : s->uveob[p][n];
+ int eob = b->skip ? 0 : b->uvtx > TX_8X8 ? AV_RN16A(&s->uveob[p][n]) : s->uveob[p][n];
- mode = check_intra_mode(s, mode, &a, ptr_r, s->f->linesize[1],
- ptr, b->uv_stride, l,
+ mode = check_intra_mode(s, mode, &a, ptr_r,
+ s->frames[CUR_FRAME].tf.f->linesize[1],
+ ptr, s->uv_stride, l,
col, x, w4, row, y, b->uvtx, p + 1);
- s->dsp.intra_pred[b->uvtx][mode](ptr, b->uv_stride, l, a);
+ s->dsp.intra_pred[b->uvtx][mode](ptr, s->uv_stride, l, a);
if (eob)
- s->dsp.itxfm_add[uvtx][DCT_DCT](ptr, b->uv_stride,
+ s->dsp.itxfm_add[uvtx][DCT_DCT](ptr, s->uv_stride,
s->uvblock[p] + 16 * n, eob);
}
- dst_r += 4 * uvstep1d * s->f->linesize[1];
- dst += 4 * uvstep1d * b->uv_stride;
+ dst_r += 4 * uvstep1d * s->frames[CUR_FRAME].tf.f->linesize[1];
+ dst += 4 * uvstep1d * s->uv_stride;
}
}
}
@@ -2203,10 +2298,11 @@
static av_always_inline void mc_luma_dir(VP9Context *s, vp9_mc_func (*mc)[2],
uint8_t *dst, ptrdiff_t dst_stride,
const uint8_t *ref, ptrdiff_t ref_stride,
+ ThreadFrame *ref_frame,
ptrdiff_t y, ptrdiff_t x, const VP56mv *mv,
int bw, int bh, int w, int h)
{
- int mx = mv->x, my = mv->y;
+ int mx = mv->x, my = mv->y, th;
y += my >> 3;
x += mx >> 3;
@@ -2214,11 +2310,15 @@
mx &= 7;
my &= 7;
// FIXME bilinear filter only needs 0/1 pixels, not 3/4
+ // we use +7 because the last 7 pixels of each sbrow can be changed in
+ // the longest loopfilter of the next sbrow
+ th = (y + bh + 4 * !!my + 7) >> 6;
+ ff_thread_await_progress(ref_frame, FFMAX(th, 0), 0);
if (x < !!mx * 3 || y < !!my * 3 ||
x + !!mx * 4 > w - bw || y + !!my * 4 > h - bh) {
- s->vdsp.emulated_edge_mc(s->edge_emu_buffer, 80,
+ s->vdsp.emulated_edge_mc(s->edge_emu_buffer,
ref - !!my * 3 * ref_stride - !!mx * 3,
- ref_stride,
+ 80, ref_stride,
bw + !!mx * 7, bh + !!my * 7,
x - !!mx * 3, y - !!my * 3, w, h);
ref = s->edge_emu_buffer + !!my * 3 * 80 + !!mx * 3;
@@ -2232,10 +2332,11 @@
ptrdiff_t dst_stride,
const uint8_t *ref_u, ptrdiff_t src_stride_u,
const uint8_t *ref_v, ptrdiff_t src_stride_v,
+ ThreadFrame *ref_frame,
ptrdiff_t y, ptrdiff_t x, const VP56mv *mv,
int bw, int bh, int w, int h)
{
- int mx = mv->x, my = mv->y;
+ int mx = mv->x, my = mv->y, th;
y += my >> 4;
x += mx >> 4;
@@ -2244,17 +2345,23 @@
mx &= 15;
my &= 15;
// FIXME bilinear filter only needs 0/1 pixels, not 3/4
+ // we use +7 because the last 7 pixels of each sbrow can be changed in
+ // the longest loopfilter of the next sbrow
+ th = (y + bh + 4 * !!my + 7) >> 5;
+ ff_thread_await_progress(ref_frame, FFMAX(th, 0), 0);
if (x < !!mx * 3 || y < !!my * 3 ||
x + !!mx * 4 > w - bw || y + !!my * 4 > h - bh) {
- s->vdsp.emulated_edge_mc(s->edge_emu_buffer, 80,
- ref_u - !!my * 3 * src_stride_u - !!mx * 3, src_stride_u,
+ s->vdsp.emulated_edge_mc(s->edge_emu_buffer,
+ ref_u - !!my * 3 * src_stride_u - !!mx * 3,
+ 80, src_stride_u,
bw + !!mx * 7, bh + !!my * 7,
x - !!mx * 3, y - !!my * 3, w, h);
ref_u = s->edge_emu_buffer + !!my * 3 * 80 + !!mx * 3;
mc[!!mx][!!my](dst_u, dst_stride, ref_u, 80, bh, mx, my);
- s->vdsp.emulated_edge_mc(s->edge_emu_buffer, 80,
- ref_v - !!my * 3 * src_stride_v - !!mx * 3, src_stride_v,
+ s->vdsp.emulated_edge_mc(s->edge_emu_buffer,
+ ref_v - !!my * 3 * src_stride_v - !!mx * 3,
+ 80, src_stride_v,
bw + !!mx * 7, bh + !!my * 7,
x - !!mx * 3, y - !!my * 3, w, h);
ref_v = s->edge_emu_buffer + !!my * 3 * 80 + !!mx * 3;
@@ -2272,47 +2379,49 @@
{ 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, 4 },
};
VP9Context *s = ctx->priv_data;
- VP9Block *const b = &s->b;
- int row = b->row, col = b->col;
- AVFrame *ref1 = s->refs[s->refidx[b->ref[0]]];
- AVFrame *ref2 = b->comp ? s->refs[s->refidx[b->ref[1]]] : NULL;
+ VP9Block *b = s->b;
+ int row = s->row, col = s->col;
+ ThreadFrame *tref1 = &s->refs[s->refidx[b->ref[0]]];
+ AVFrame *ref1 = tref1->f;
+ ThreadFrame *tref2 = b->comp ? &s->refs[s->refidx[b->ref[1]]] : NULL;
+ AVFrame *ref2 = b->comp ? tref2->f : NULL;
int w = ctx->width, h = ctx->height;
- ptrdiff_t ls_y = b->y_stride, ls_uv = b->uv_stride;
+ ptrdiff_t ls_y = s->y_stride, ls_uv = s->uv_stride;
// y inter pred
if (b->bs > BS_8x8) {
if (b->bs == BS_8x4) {
- mc_luma_dir(s, s->dsp.mc[3][b->filter][0], b->dst[0], ls_y,
- ref1->data[0], ref1->linesize[0],
+ mc_luma_dir(s, s->dsp.mc[3][b->filter][0], s->dst[0], ls_y,
+ ref1->data[0], ref1->linesize[0], tref1,
row << 3, col << 3, &b->mv[0][0], 8, 4, w, h);
mc_luma_dir(s, s->dsp.mc[3][b->filter][0],
- b->dst[0] + 4 * ls_y, ls_y,
- ref1->data[0], ref1->linesize[0],
+ s->dst[0] + 4 * ls_y, ls_y,
+ ref1->data[0], ref1->linesize[0], tref1,
(row << 3) + 4, col << 3, &b->mv[2][0], 8, 4, w, h);
if (b->comp) {
- mc_luma_dir(s, s->dsp.mc[3][b->filter][1], b->dst[0], ls_y,
- ref2->data[0], ref2->linesize[0],
+ mc_luma_dir(s, s->dsp.mc[3][b->filter][1], s->dst[0], ls_y,
+ ref2->data[0], ref2->linesize[0], tref2,
row << 3, col << 3, &b->mv[0][1], 8, 4, w, h);
mc_luma_dir(s, s->dsp.mc[3][b->filter][1],
- b->dst[0] + 4 * ls_y, ls_y,
- ref2->data[0], ref2->linesize[0],
+ s->dst[0] + 4 * ls_y, ls_y,
+ ref2->data[0], ref2->linesize[0], tref2,
(row << 3) + 4, col << 3, &b->mv[2][1], 8, 4, w, h);
}
} else if (b->bs == BS_4x8) {
- mc_luma_dir(s, s->dsp.mc[4][b->filter][0], b->dst[0], ls_y,
- ref1->data[0], ref1->linesize[0],
+ mc_luma_dir(s, s->dsp.mc[4][b->filter][0], s->dst[0], ls_y,
+ ref1->data[0], ref1->linesize[0], tref1,
row << 3, col << 3, &b->mv[0][0], 4, 8, w, h);
- mc_luma_dir(s, s->dsp.mc[4][b->filter][0], b->dst[0] + 4, ls_y,
- ref1->data[0], ref1->linesize[0],
+ mc_luma_dir(s, s->dsp.mc[4][b->filter][0], s->dst[0] + 4, ls_y,
+ ref1->data[0], ref1->linesize[0], tref1,
row << 3, (col << 3) + 4, &b->mv[1][0], 4, 8, w, h);
if (b->comp) {
- mc_luma_dir(s, s->dsp.mc[4][b->filter][1], b->dst[0], ls_y,
- ref2->data[0], ref2->linesize[0],
+ mc_luma_dir(s, s->dsp.mc[4][b->filter][1], s->dst[0], ls_y,
+ ref2->data[0], ref2->linesize[0], tref2,
row << 3, col << 3, &b->mv[0][1], 4, 8, w, h);
- mc_luma_dir(s, s->dsp.mc[4][b->filter][1], b->dst[0] + 4, ls_y,
- ref2->data[0], ref2->linesize[0],
+ mc_luma_dir(s, s->dsp.mc[4][b->filter][1], s->dst[0] + 4, ls_y,
+ ref2->data[0], ref2->linesize[0], tref2,
row << 3, (col << 3) + 4, &b->mv[1][1], 4, 8, w, h);
}
} else {
@@ -2320,35 +2429,35 @@
// FIXME if two horizontally adjacent blocks have the same MV,
// do a w8 instead of a w4 call
- mc_luma_dir(s, s->dsp.mc[4][b->filter][0], b->dst[0], ls_y,
- ref1->data[0], ref1->linesize[0],
+ mc_luma_dir(s, s->dsp.mc[4][b->filter][0], s->dst[0], ls_y,
+ ref1->data[0], ref1->linesize[0], tref1,
row << 3, col << 3, &b->mv[0][0], 4, 4, w, h);
- mc_luma_dir(s, s->dsp.mc[4][b->filter][0], b->dst[0] + 4, ls_y,
- ref1->data[0], ref1->linesize[0],
+ mc_luma_dir(s, s->dsp.mc[4][b->filter][0], s->dst[0] + 4, ls_y,
+ ref1->data[0], ref1->linesize[0], tref1,
row << 3, (col << 3) + 4, &b->mv[1][0], 4, 4, w, h);
mc_luma_dir(s, s->dsp.mc[4][b->filter][0],
- b->dst[0] + 4 * ls_y, ls_y,
- ref1->data[0], ref1->linesize[0],
+ s->dst[0] + 4 * ls_y, ls_y,
+ ref1->data[0], ref1->linesize[0], tref1,
(row << 3) + 4, col << 3, &b->mv[2][0], 4, 4, w, h);
mc_luma_dir(s, s->dsp.mc[4][b->filter][0],
- b->dst[0] + 4 * ls_y + 4, ls_y,
- ref1->data[0], ref1->linesize[0],
+ s->dst[0] + 4 * ls_y + 4, ls_y,
+ ref1->data[0], ref1->linesize[0], tref1,
(row << 3) + 4, (col << 3) + 4, &b->mv[3][0], 4, 4, w, h);
if (b->comp) {
- mc_luma_dir(s, s->dsp.mc[4][b->filter][1], b->dst[0], ls_y,
- ref2->data[0], ref2->linesize[0],
+ mc_luma_dir(s, s->dsp.mc[4][b->filter][1], s->dst[0], ls_y,
+ ref2->data[0], ref2->linesize[0], tref2,
row << 3, col << 3, &b->mv[0][1], 4, 4, w, h);
- mc_luma_dir(s, s->dsp.mc[4][b->filter][1], b->dst[0] + 4, ls_y,
- ref2->data[0], ref2->linesize[0],
+ mc_luma_dir(s, s->dsp.mc[4][b->filter][1], s->dst[0] + 4, ls_y,
+ ref2->data[0], ref2->linesize[0], tref2,
row << 3, (col << 3) + 4, &b->mv[1][1], 4, 4, w, h);
mc_luma_dir(s, s->dsp.mc[4][b->filter][1],
- b->dst[0] + 4 * ls_y, ls_y,
- ref2->data[0], ref2->linesize[0],
+ s->dst[0] + 4 * ls_y, ls_y,
+ ref2->data[0], ref2->linesize[0], tref2,
(row << 3) + 4, col << 3, &b->mv[2][1], 4, 4, w, h);
mc_luma_dir(s, s->dsp.mc[4][b->filter][1],
- b->dst[0] + 4 * ls_y + 4, ls_y,
- ref2->data[0], ref2->linesize[0],
+ s->dst[0] + 4 * ls_y + 4, ls_y,
+ ref2->data[0], ref2->linesize[0], tref2,
(row << 3) + 4, (col << 3) + 4, &b->mv[3][1], 4, 4, w, h);
}
}
@@ -2356,13 +2465,13 @@
int bwl = bwlog_tab[0][b->bs];
int bw = bwh_tab[0][b->bs][0] * 4, bh = bwh_tab[0][b->bs][1] * 4;
- mc_luma_dir(s, s->dsp.mc[bwl][b->filter][0], b->dst[0], ls_y,
- ref1->data[0], ref1->linesize[0],
+ mc_luma_dir(s, s->dsp.mc[bwl][b->filter][0], s->dst[0], ls_y,
+ ref1->data[0], ref1->linesize[0], tref1,
row << 3, col << 3, &b->mv[0][0],bw, bh, w, h);
if (b->comp)
- mc_luma_dir(s, s->dsp.mc[bwl][b->filter][1], b->dst[0], ls_y,
- ref2->data[0], ref2->linesize[0],
+ mc_luma_dir(s, s->dsp.mc[bwl][b->filter][1], s->dst[0], ls_y,
+ ref2->data[0], ref2->linesize[0], tref2,
row << 3, col << 3, &b->mv[0][1], bw, bh, w, h);
}
@@ -2382,9 +2491,9 @@
}
mc_chroma_dir(s, s->dsp.mc[bwl][b->filter][0],
- b->dst[1], b->dst[2], ls_uv,
+ s->dst[1], s->dst[2], ls_uv,
ref1->data[1], ref1->linesize[1],
- ref1->data[2], ref1->linesize[2],
+ ref1->data[2], ref1->linesize[2], tref1,
row << 2, col << 2, &mvuv, bw, bh, w, h);
if (b->comp) {
@@ -2395,9 +2504,9 @@
mvuv = b->mv[0][1];
}
mc_chroma_dir(s, s->dsp.mc[bwl][b->filter][1],
- b->dst[1], b->dst[2], ls_uv,
+ s->dst[1], s->dst[2], ls_uv,
ref2->data[1], ref2->linesize[1],
- ref2->data[2], ref2->linesize[2],
+ ref2->data[2], ref2->linesize[2], tref2,
row << 2, col << 2, &mvuv, bw, bh, w, h);
}
}
@@ -2411,7 +2520,7 @@
int end_y = FFMIN(2 * (s->rows - row), h4);
int tx = 4 * s->lossless + b->tx, uvtx = b->uvtx + 4 * s->lossless;
int uvstep1d = 1 << b->uvtx, p;
- uint8_t *dst = b->dst[0];
+ uint8_t *dst = s->dst[0];
// y itxfm add
for (n = 0, y = 0; y < end_y; y += step1d) {
@@ -2420,10 +2529,10 @@
int eob = b->tx > TX_8X8 ? AV_RN16A(&s->eob[n]) : s->eob[n];
if (eob)
- s->dsp.itxfm_add[tx][DCT_DCT](ptr, b->y_stride,
+ s->dsp.itxfm_add[tx][DCT_DCT](ptr, s->y_stride,
s->block + 16 * n, eob);
}
- dst += 4 * b->y_stride * step1d;
+ dst += 4 * s->y_stride * step1d;
}
// uv itxfm add
@@ -2433,17 +2542,17 @@
end_y >>= 1;
step = 1 << (b->uvtx * 2);
for (p = 0; p < 2; p++) {
- dst = b->dst[p + 1];
+ dst = s->dst[p + 1];
for (n = 0, y = 0; y < end_y; y += uvstep1d) {
uint8_t *ptr = dst;
for (x = 0; x < end_x; x += uvstep1d, ptr += 4 * uvstep1d, n += step) {
int eob = b->uvtx > TX_8X8 ? AV_RN16A(&s->uveob[p][n]) : s->uveob[p][n];
if (eob)
- s->dsp.itxfm_add[uvtx][DCT_DCT](ptr, b->uv_stride,
+ s->dsp.itxfm_add[uvtx][DCT_DCT](ptr, s->uv_stride,
s->uvblock[p] + 16 * n, eob);
}
- dst += 4 * uvstep1d * b->uv_stride;
+ dst += 4 * uvstep1d * s->uv_stride;
}
}
}
@@ -2582,64 +2691,79 @@
}
}
-static int decode_b(AVCodecContext *ctx, int row, int col,
- struct VP9Filter *lflvl, ptrdiff_t yoff, ptrdiff_t uvoff,
- enum BlockLevel bl, enum BlockPartition bp)
+static void decode_b(AVCodecContext *ctx, int row, int col,
+ struct VP9Filter *lflvl, ptrdiff_t yoff, ptrdiff_t uvoff,
+ enum BlockLevel bl, enum BlockPartition bp)
{
VP9Context *s = ctx->priv_data;
- VP9Block *const b = &s->b;
+ VP9Block *b = s->b;
enum BlockSize bs = bl * 3 + bp;
- int res, y, w4 = bwh_tab[1][bs][0], h4 = bwh_tab[1][bs][1], lvl;
+ int y, w4 = bwh_tab[1][bs][0], h4 = bwh_tab[1][bs][1], lvl;
int emu[2];
+ AVFrame *f = s->frames[CUR_FRAME].tf.f;
- b->row = row;
- b->row7 = row & 7;
- b->col = col;
- b->col7 = col & 7;
+ s->row = row;
+ s->row7 = row & 7;
+ s->col = col;
+ s->col7 = col & 7;
s->min_mv.x = -(128 + col * 64);
s->min_mv.y = -(128 + row * 64);
s->max_mv.x = 128 + (s->cols - col - w4) * 64;
s->max_mv.y = 128 + (s->rows - row - h4) * 64;
- b->bs = bs;
- decode_mode(ctx);
- b->uvtx = b->tx - (w4 * 2 == (1 << b->tx) || h4 * 2 == (1 << b->tx));
+ if (s->pass < 2) {
+ b->bs = bs;
+ b->bl = bl;
+ b->bp = bp;
+ decode_mode(ctx);
+ b->uvtx = b->tx - (w4 * 2 == (1 << b->tx) || h4 * 2 == (1 << b->tx));
- if (!b->skip) {
- if ((res = decode_coeffs(ctx)) < 0)
- return res;
- } else {
- int pl;
+ if (!b->skip) {
+ decode_coeffs(ctx);
+ } else {
+ int pl;
- memset(&s->above_y_nnz_ctx[col * 2], 0, w4 * 2);
- memset(&s->left_y_nnz_ctx[(row & 7) << 1], 0, h4 * 2);
- for (pl = 0; pl < 2; pl++) {
- memset(&s->above_uv_nnz_ctx[pl][col], 0, w4);
- memset(&s->left_uv_nnz_ctx[pl][row & 7], 0, h4);
+ memset(&s->above_y_nnz_ctx[col * 2], 0, w4 * 2);
+ memset(&s->left_y_nnz_ctx[(row & 7) << 1], 0, h4 * 2);
+ for (pl = 0; pl < 2; pl++) {
+ memset(&s->above_uv_nnz_ctx[pl][col], 0, w4);
+ memset(&s->left_uv_nnz_ctx[pl][row & 7], 0, h4);
+ }
+ }
+ if (s->pass == 1) {
+ s->b++;
+ s->block += w4 * h4 * 64;
+ s->uvblock[0] += w4 * h4 * 16;
+ s->uvblock[1] += w4 * h4 * 16;
+ s->eob += 4 * w4 * h4;
+ s->uveob[0] += w4 * h4;
+ s->uveob[1] += w4 * h4;
+
+ return;
}
}
// emulated overhangs if the stride of the target buffer can't hold. This
// allows to support emu-edge and so on even if we have large block
// overhangs
- emu[0] = (col + w4) * 8 > s->f->linesize[0] ||
+ emu[0] = (col + w4) * 8 > f->linesize[0] ||
(row + h4) > s->rows + 2 * !(ctx->flags & CODEC_FLAG_EMU_EDGE);
- emu[1] = (col + w4) * 4 > s->f->linesize[1] ||
+ emu[1] = (col + w4) * 4 > f->linesize[1] ||
(row + h4) > s->rows + 2 * !(ctx->flags & CODEC_FLAG_EMU_EDGE);
if (emu[0]) {
- b->dst[0] = s->tmp_y;
- b->y_stride = 64;
+ s->dst[0] = s->tmp_y;
+ s->y_stride = 64;
} else {
- b->dst[0] = s->f->data[0] + yoff;
- b->y_stride = s->f->linesize[0];
+ s->dst[0] = f->data[0] + yoff;
+ s->y_stride = f->linesize[0];
}
if (emu[1]) {
- b->dst[1] = s->tmp_uv[0];
- b->dst[2] = s->tmp_uv[1];
- b->uv_stride = 32;
+ s->dst[1] = s->tmp_uv[0];
+ s->dst[2] = s->tmp_uv[1];
+ s->uv_stride = 32;
} else {
- b->dst[1] = s->f->data[1] + uvoff;
- b->dst[2] = s->f->data[2] + uvoff;
- b->uv_stride = s->f->linesize[1];
+ s->dst[1] = f->data[1] + uvoff;
+ s->dst[2] = f->data[2] + uvoff;
+ s->uv_stride = f->linesize[1];
}
if (b->intra) {
intra_recon(ctx, yoff, uvoff);
@@ -2654,7 +2778,7 @@
av_assert2(n <= 4);
if (w & bw) {
- s->dsp.mc[n][0][0][0][0](s->f->data[0] + yoff + o, s->f->linesize[0],
+ s->dsp.mc[n][0][0][0][0](f->data[0] + yoff + o, f->linesize[0],
s->tmp_y + o, 64, h, 0, 0);
o += bw;
}
@@ -2668,9 +2792,9 @@
av_assert2(n <= 4);
if (w & bw) {
- s->dsp.mc[n][0][0][0][0](s->f->data[1] + uvoff + o, s->f->linesize[1],
+ s->dsp.mc[n][0][0][0][0](f->data[1] + uvoff + o, f->linesize[1],
s->tmp_uv[0] + o, 32, h, 0, 0);
- s->dsp.mc[n][0][0][0][0](s->f->data[2] + uvoff + o, s->f->linesize[2],
+ s->dsp.mc[n][0][0][0][0](f->data[2] + uvoff + o, f->linesize[2],
s->tmp_uv[1] + o, 32, h, 0, 0);
o += bw;
}
@@ -2707,95 +2831,146 @@
}
}
- return 0;
+ if (s->pass == 2) {
+ s->b++;
+ s->block += w4 * h4 * 64;
+ s->uvblock[0] += w4 * h4 * 16;
+ s->uvblock[1] += w4 * h4 * 16;
+ s->eob += 4 * w4 * h4;
+ s->uveob[0] += w4 * h4;
+ s->uveob[1] += w4 * h4;
+ }
}
-static int decode_sb(AVCodecContext *ctx, int row, int col, struct VP9Filter *lflvl,
- ptrdiff_t yoff, ptrdiff_t uvoff, enum BlockLevel bl)
+static void decode_sb(AVCodecContext *ctx, int row, int col, struct VP9Filter *lflvl,
+ ptrdiff_t yoff, ptrdiff_t uvoff, enum BlockLevel bl)
{
VP9Context *s = ctx->priv_data;
int c = ((s->above_partition_ctx[col] >> (3 - bl)) & 1) |
- (((s->left_partition_ctx[row & 0x7] >> (3 - bl)) & 1) << 1), res;
+ (((s->left_partition_ctx[row & 0x7] >> (3 - bl)) & 1) << 1);
const uint8_t *p = s->keyframe ? vp9_default_kf_partition_probs[bl][c] :
s->prob.p.partition[bl][c];
enum BlockPartition bp;
ptrdiff_t hbs = 4 >> bl;
+ AVFrame *f = s->frames[CUR_FRAME].tf.f;
+ ptrdiff_t y_stride = f->linesize[0], uv_stride = f->linesize[1];
if (bl == BL_8X8) {
bp = vp8_rac_get_tree(&s->c, vp9_partition_tree, p);
- res = decode_b(ctx, row, col, lflvl, yoff, uvoff, bl, bp);
- } else if (col + hbs < s->cols) {
- if (row + hbs < s->rows) {
+ decode_b(ctx, row, col, lflvl, yoff, uvoff, bl, bp);
+ } else if (col + hbs < s->cols) { // FIXME why not <=?
+ if (row + hbs < s->rows) { // FIXME why not <=?
bp = vp8_rac_get_tree(&s->c, vp9_partition_tree, p);
switch (bp) {
case PARTITION_NONE:
- res = decode_b(ctx, row, col, lflvl, yoff, uvoff, bl, bp);
+ decode_b(ctx, row, col, lflvl, yoff, uvoff, bl, bp);
break;
case PARTITION_H:
- if (!(res = decode_b(ctx, row, col, lflvl, yoff, uvoff, bl, bp))) {
- yoff += hbs * 8 * s->f->linesize[0];
- uvoff += hbs * 4 * s->f->linesize[1];
- res = decode_b(ctx, row + hbs, col, lflvl, yoff, uvoff, bl, bp);
- }
+ decode_b(ctx, row, col, lflvl, yoff, uvoff, bl, bp);
+ yoff += hbs * 8 * y_stride;
+ uvoff += hbs * 4 * uv_stride;
+ decode_b(ctx, row + hbs, col, lflvl, yoff, uvoff, bl, bp);
break;
case PARTITION_V:
- if (!(res = decode_b(ctx, row, col, lflvl, yoff, uvoff, bl, bp))) {
- yoff += hbs * 8;
- uvoff += hbs * 4;
- res = decode_b(ctx, row, col + hbs, lflvl, yoff, uvoff, bl, bp);
- }
+ decode_b(ctx, row, col, lflvl, yoff, uvoff, bl, bp);
+ yoff += hbs * 8;
+ uvoff += hbs * 4;
+ decode_b(ctx, row, col + hbs, lflvl, yoff, uvoff, bl, bp);
break;
case PARTITION_SPLIT:
- if (!(res = decode_sb(ctx, row, col, lflvl, yoff, uvoff, bl + 1))) {
- if (!(res = decode_sb(ctx, row, col + hbs, lflvl,
- yoff + 8 * hbs, uvoff + 4 * hbs, bl + 1))) {
- yoff += hbs * 8 * s->f->linesize[0];
- uvoff += hbs * 4 * s->f->linesize[1];
- if (!(res = decode_sb(ctx, row + hbs, col, lflvl,
- yoff, uvoff, bl + 1)))
- res = decode_sb(ctx, row + hbs, col + hbs, lflvl,
- yoff + 8 * hbs, uvoff + 4 * hbs, bl + 1);
- }
- }
+ decode_sb(ctx, row, col, lflvl, yoff, uvoff, bl + 1);
+ decode_sb(ctx, row, col + hbs, lflvl,
+ yoff + 8 * hbs, uvoff + 4 * hbs, bl + 1);
+ yoff += hbs * 8 * y_stride;
+ uvoff += hbs * 4 * uv_stride;
+ decode_sb(ctx, row + hbs, col, lflvl, yoff, uvoff, bl + 1);
+ decode_sb(ctx, row + hbs, col + hbs, lflvl,
+ yoff + 8 * hbs, uvoff + 4 * hbs, bl + 1);
break;
+ default:
+ av_assert0(0);
}
} else if (vp56_rac_get_prob_branchy(&s->c, p[1])) {
bp = PARTITION_SPLIT;
- if (!(res = decode_sb(ctx, row, col, lflvl, yoff, uvoff, bl + 1)))
- res = decode_sb(ctx, row, col + hbs, lflvl,
- yoff + 8 * hbs, uvoff + 4 * hbs, bl + 1);
+ decode_sb(ctx, row, col, lflvl, yoff, uvoff, bl + 1);
+ decode_sb(ctx, row, col + hbs, lflvl,
+ yoff + 8 * hbs, uvoff + 4 * hbs, bl + 1);
} else {
bp = PARTITION_H;
- res = decode_b(ctx, row, col, lflvl, yoff, uvoff, bl, bp);
+ decode_b(ctx, row, col, lflvl, yoff, uvoff, bl, bp);
}
- } else if (row + hbs < s->rows) {
+ } else if (row + hbs < s->rows) { // FIXME why not <=?
if (vp56_rac_get_prob_branchy(&s->c, p[2])) {
bp = PARTITION_SPLIT;
- if (!(res = decode_sb(ctx, row, col, lflvl, yoff, uvoff, bl + 1))) {
- yoff += hbs * 8 * s->f->linesize[0];
- uvoff += hbs * 4 * s->f->linesize[1];
- res = decode_sb(ctx, row + hbs, col, lflvl,
- yoff, uvoff, bl + 1);
- }
+ decode_sb(ctx, row, col, lflvl, yoff, uvoff, bl + 1);
+ yoff += hbs * 8 * y_stride;
+ uvoff += hbs * 4 * uv_stride;
+ decode_sb(ctx, row + hbs, col, lflvl, yoff, uvoff, bl + 1);
} else {
bp = PARTITION_V;
- res = decode_b(ctx, row, col, lflvl, yoff, uvoff, bl, bp);
+ decode_b(ctx, row, col, lflvl, yoff, uvoff, bl, bp);
}
} else {
bp = PARTITION_SPLIT;
- res = decode_sb(ctx, row, col, lflvl, yoff, uvoff, bl + 1);
+ decode_sb(ctx, row, col, lflvl, yoff, uvoff, bl + 1);
}
s->counts.partition[bl][c][bp]++;
+}
- return res;
+static void decode_sb_mem(AVCodecContext *ctx, int row, int col, struct VP9Filter *lflvl,
+ ptrdiff_t yoff, ptrdiff_t uvoff, enum BlockLevel bl)
+{
+ VP9Context *s = ctx->priv_data;
+ VP9Block *b = s->b;
+ ptrdiff_t hbs = 4 >> bl;
+ AVFrame *f = s->frames[CUR_FRAME].tf.f;
+ ptrdiff_t y_stride = f->linesize[0], uv_stride = f->linesize[1];
+
+ if (bl == BL_8X8) {
+ av_assert2(b->bl == BL_8X8);
+ decode_b(ctx, row, col, lflvl, yoff, uvoff, b->bl, b->bp);
+ } else if (s->b->bl == bl) {
+ decode_b(ctx, row, col, lflvl, yoff, uvoff, b->bl, b->bp);
+ if (b->bp == PARTITION_H && row + hbs < s->rows) {
+ yoff += hbs * 8 * y_stride;
+ uvoff += hbs * 4 * uv_stride;
+ decode_b(ctx, row + hbs, col, lflvl, yoff, uvoff, b->bl, b->bp);
+ } else if (b->bp == PARTITION_V && col + hbs < s->cols) {
+ yoff += hbs * 8;
+ uvoff += hbs * 4;
+ decode_b(ctx, row, col + hbs, lflvl, yoff, uvoff, b->bl, b->bp);
+ }
+ } else {
+ decode_sb_mem(ctx, row, col, lflvl, yoff, uvoff, bl + 1);
+ if (col + hbs < s->cols) { // FIXME why not <=?
+ if (row + hbs < s->rows) {
+ decode_sb_mem(ctx, row, col + hbs, lflvl, yoff + 8 * hbs,
+ uvoff + 4 * hbs, bl + 1);
+ yoff += hbs * 8 * y_stride;
+ uvoff += hbs * 4 * uv_stride;
+ decode_sb_mem(ctx, row + hbs, col, lflvl, yoff, uvoff, bl + 1);
+ decode_sb_mem(ctx, row + hbs, col + hbs, lflvl,
+ yoff + 8 * hbs, uvoff + 4 * hbs, bl + 1);
+ } else {
+ yoff += hbs * 8;
+ uvoff += hbs * 4;
+ decode_sb_mem(ctx, row, col + hbs, lflvl, yoff, uvoff, bl + 1);
+ }
+ } else if (row + hbs < s->rows) {
+ yoff += hbs * 8 * y_stride;
+ uvoff += hbs * 4 * uv_stride;
+ decode_sb_mem(ctx, row + hbs, col, lflvl, yoff, uvoff, bl + 1);
+ }
+ }
}
static void loopfilter_sb(AVCodecContext *ctx, struct VP9Filter *lflvl,
int row, int col, ptrdiff_t yoff, ptrdiff_t uvoff)
{
VP9Context *s = ctx->priv_data;
- uint8_t *dst = s->f->data[0] + yoff, *lvl = lflvl->level;
- ptrdiff_t ls_y = s->f->linesize[0], ls_uv = s->f->linesize[1];
+ AVFrame *f = s->frames[CUR_FRAME].tf.f;
+ uint8_t *dst = f->data[0] + yoff, *lvl = lflvl->level;
+ ptrdiff_t ls_y = f->linesize[0], ls_uv = f->linesize[1];
int y, x, p;
// FIXME in how far can we interleave the v/h loopfilter calls? E.g.
@@ -2872,7 +3047,7 @@
// block1
// filter edges between rows, Y plane (e.g. ------)
// block2
- dst = s->f->data[0] + yoff;
+ dst = f->data[0] + yoff;
lvl = lflvl->level;
for (y = 0; y < 8; y++, dst += 8 * ls_y, lvl += 8) {
uint8_t *ptr = dst, *l = lvl, *vmask = lflvl->mask[0][1][y];
@@ -2936,7 +3111,7 @@
// same principle but for U/V planes
for (p = 0; p < 2; p++) {
lvl = lflvl->level;
- dst = s->f->data[1 + p] + uvoff;
+ dst = f->data[1 + p] + uvoff;
for (y = 0; y < 8; y += 4, dst += 16 * ls_uv, lvl += 32) {
uint8_t *ptr = dst, *l = lvl, *hmask1 = lflvl->mask[1][0][y];
uint8_t *hmask2 = lflvl->mask[1][0][y + 2];
@@ -2981,7 +3156,7 @@
}
}
lvl = lflvl->level;
- dst = s->f->data[1 + p] + uvoff;
+ dst = f->data[1 + p] + uvoff;
for (y = 0; y < 8; y++, dst += 4 * ls_uv) {
uint8_t *ptr = dst, *l = lvl, *vmask = lflvl->mask[1][1][y];
unsigned vm = vmask[0] | vmask[1] | vmask[2];
@@ -3274,22 +3449,52 @@
}
}
-static int vp9_decode_frame(AVCodecContext *ctx, void *out_pic,
- int *got_frame, const uint8_t *data, int size)
+static av_cold int vp9_decode_free(AVCodecContext *ctx)
{
VP9Context *s = ctx->priv_data;
+ int i;
+
+ for (i = 0; i < 2; i++) {
+ if (s->frames[i].tf.f->data[0])
+ vp9_unref_frame(ctx, &s->frames[i]);
+ av_frame_free(&s->frames[i].tf.f);
+ }
+ for (i = 0; i < 8; i++) {
+ if (s->refs[i].f->data[0])
+ ff_thread_release_buffer(ctx, &s->refs[i]);
+ av_frame_free(&s->refs[i].f);
+ if (s->next_refs[i].f->data[0])
+ ff_thread_release_buffer(ctx, &s->next_refs[i]);
+ av_frame_free(&s->next_refs[i].f);
+ }
+ av_freep(&s->above_partition_ctx);
+ av_freep(&s->c_b);
+ s->c_b_size = 0;
+ av_freep(&s->b_base);
+ av_freep(&s->block_base);
+
+ return 0;
+}
+
+
+static int vp9_decode_frame(AVCodecContext *ctx, void *frame,
+ int *got_frame, AVPacket *pkt)
+{
+ const uint8_t *data = pkt->data;
+ int size = pkt->size;
+ VP9Context *s = ctx->priv_data;
int res, tile_row, tile_col, i, ref, row, col;
- ptrdiff_t yoff = 0, uvoff = 0;
- //AVFrame *prev_frame = s->f; // for segmentation map
+ ptrdiff_t yoff, uvoff, ls_y, ls_uv;
+ AVFrame *f;
if ((res = decode_frame_header(ctx, data, size, &ref)) < 0) {
return res;
} else if (res == 0) {
- if (!s->refs[ref]) {
+ if (!s->refs[ref].f->data[0]) {
av_log(ctx, AV_LOG_ERROR, "Requested reference %d not available\n", ref);
return AVERROR_INVALIDDATA;
}
- if ((res = av_frame_ref(out_pic, s->refs[ref])) < 0)
+ if ((res = av_frame_ref(frame, s->refs[ref].f)) < 0)
return res;
*got_frame = 1;
return 0;
@@ -3297,27 +3502,33 @@
data += res;
size -= res;
- // discard old references
- for (i = 0; i < 10; i++) {
- AVFrame *f = s->fb[i];
- if (f->data[0] && f != s->f &&
- f != s->refs[0] && f != s->refs[1] &&
- f != s->refs[2] && f != s->refs[3] &&
- f != s->refs[4] && f != s->refs[5] &&
- f != s->refs[6] && f != s->refs[7])
- av_frame_unref(f);
- }
-
- // find unused reference
- for (i = 0; i < 10; i++)
- if (!s->fb[i]->data[0])
- break;
- s->f = s->fb[i];
- if ((res = ff_get_buffer(ctx, s->f,
- s->refreshrefmask ? AV_GET_BUFFER_FLAG_REF : 0)) < 0)
+ if (s->frames[LAST_FRAME].tf.f->data[0])
+ vp9_unref_frame(ctx, &s->frames[LAST_FRAME]);
+ if (!s->keyframe && s->frames[CUR_FRAME].tf.f->data[0] &&
+ (res = vp9_ref_frame(ctx, &s->frames[LAST_FRAME], &s->frames[CUR_FRAME])) < 0)
return res;
- s->f->key_frame = s->keyframe;
- s->f->pict_type = s->keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P;
+ if (s->frames[CUR_FRAME].tf.f->data[0])
+ vp9_unref_frame(ctx, &s->frames[CUR_FRAME]);
+ if ((res = vp9_alloc_frame(ctx, &s->frames[CUR_FRAME])) < 0)
+ return res;
+ f = s->frames[CUR_FRAME].tf.f;
+ f->key_frame = s->keyframe;
+ f->pict_type = s->keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P;
+ ls_y = f->linesize[0];
+ ls_uv =f->linesize[1];
+
+ // ref frame setup
+ for (i = 0; i < 8; i++) {
+ if (s->next_refs[i].f->data[0])
+ ff_thread_release_buffer(ctx, &s->next_refs[i]);
+ if (s->refreshrefmask & (1 << i)) {
+ res = ff_thread_ref_frame(&s->next_refs[i], &s->frames[CUR_FRAME].tf);
+ } else {
+ res = ff_thread_ref_frame(&s->next_refs[i], &s->refs[i]);
+ }
+ if (res < 0)
+ return res;
+ }
// main tile decode loop
memset(s->above_partition_ctx, 0, s->cols);
@@ -3331,120 +3542,155 @@
memset(s->above_uv_nnz_ctx[0], 0, s->sb_cols * 8);
memset(s->above_uv_nnz_ctx[1], 0, s->sb_cols * 8);
memset(s->above_segpred_ctx, 0, s->cols);
- for (tile_row = 0; tile_row < s->tiling.tile_rows; tile_row++) {
- set_tile_offset(&s->tiling.tile_row_start, &s->tiling.tile_row_end,
- tile_row, s->tiling.log2_tile_rows, s->sb_rows);
- for (tile_col = 0; tile_col < s->tiling.tile_cols; tile_col++) {
- unsigned tile_size;
+ s->pass = s->uses_2pass =
+ ctx->active_thread_type == FF_THREAD_FRAME && s->refreshctx && !s->parallelmode;
+ if (s->refreshctx && s->parallelmode) {
+ int j, k, l, m;
- if (tile_col == s->tiling.tile_cols - 1 &&
- tile_row == s->tiling.tile_rows - 1) {
- tile_size = size;
- } else {
- tile_size = AV_RB32(data);
- data += 4;
- size -= 4;
- }
- if (tile_size > size)
- return AVERROR_INVALIDDATA;
- ff_vp56_init_range_decoder(&s->c_b[tile_col], data, tile_size);
- if (vp56_rac_get_prob_branchy(&s->c_b[tile_col], 128)) // marker bit
- return AVERROR_INVALIDDATA;
- data += tile_size;
- size -= tile_size;
- }
-
- for (row = s->tiling.tile_row_start;
- row < s->tiling.tile_row_end;
- row += 8, yoff += s->f->linesize[0] * 64,
- uvoff += s->f->linesize[1] * 32) {
- struct VP9Filter *lflvl_ptr = s->lflvl;
- ptrdiff_t yoff2 = yoff, uvoff2 = uvoff;
-
- for (tile_col = 0; tile_col < s->tiling.tile_cols; tile_col++) {
- set_tile_offset(&s->tiling.tile_col_start, &s->tiling.tile_col_end,
- tile_col, s->tiling.log2_tile_cols, s->sb_cols);
-
- memset(s->left_partition_ctx, 0, 8);
- memset(s->left_skip_ctx, 0, 8);
- if (s->keyframe || s->intraonly) {
- memset(s->left_mode_ctx, DC_PRED, 16);
- } else {
- memset(s->left_mode_ctx, NEARESTMV, 8);
- }
- memset(s->left_y_nnz_ctx, 0, 16);
- memset(s->left_uv_nnz_ctx, 0, 16);
- memset(s->left_segpred_ctx, 0, 8);
-
- memcpy(&s->c, &s->c_b[tile_col], sizeof(s->c));
- for (col = s->tiling.tile_col_start;
- col < s->tiling.tile_col_end;
- col += 8, yoff2 += 64, uvoff2 += 32, lflvl_ptr++) {
- // FIXME integrate with lf code (i.e. zero after each
- // use, similar to invtxfm coefficients, or similar)
- memset(lflvl_ptr->mask, 0, sizeof(lflvl_ptr->mask));
-
- if ((res = decode_sb(ctx, row, col, lflvl_ptr,
- yoff2, uvoff2, BL_64X64)) < 0)
- return res;
- }
- memcpy(&s->c_b[tile_col], &s->c, sizeof(s->c));
- }
-
- // backup pre-loopfilter reconstruction data for intra
- // prediction of next row of sb64s
- if (row + 8 < s->rows) {
- memcpy(s->intra_pred_data[0],
- s->f->data[0] + yoff + 63 * s->f->linesize[0],
- 8 * s->cols);
- memcpy(s->intra_pred_data[1],
- s->f->data[1] + uvoff + 31 * s->f->linesize[1],
- 4 * s->cols);
- memcpy(s->intra_pred_data[2],
- s->f->data[2] + uvoff + 31 * s->f->linesize[2],
- 4 * s->cols);
- }
-
- // loopfilter one row
- if (s->filter.level) {
- yoff2 = yoff;
- uvoff2 = uvoff;
- lflvl_ptr = s->lflvl;
- for (col = 0; col < s->cols;
- col += 8, yoff2 += 64, uvoff2 += 32, lflvl_ptr++) {
- loopfilter_sb(ctx, lflvl_ptr, row, col, yoff2, uvoff2);
- }
- }
- }
+ for (i = 0; i < 4; i++)
+ for (j = 0; j < 2; j++)
+ for (k = 0; k < 2; k++)
+ for (l = 0; l < 6; l++)
+ for (m = 0; m < 6; m++)
+ memcpy(s->prob_ctx[s->framectxid].coef[i][j][k][l][m],
+ s->prob.coef[i][j][k][l][m], 3);
+ s->prob_ctx[s->framectxid].p = s->prob.p;
+ ff_thread_finish_setup(ctx);
}
- // bw adaptivity (or in case of parallel decoding mode, fw adaptivity
- // probability maintenance between frames)
- if (s->refreshctx) {
- if (s->parallelmode) {
- int i, j, k, l, m;
+ do {
+ yoff = uvoff = 0;
+ s->b = s->b_base;
+ s->block = s->block_base;
+ s->uvblock[0] = s->uvblock_base[0];
+ s->uvblock[1] = s->uvblock_base[1];
+ s->eob = s->eob_base;
+ s->uveob[0] = s->uveob_base[0];
+ s->uveob[1] = s->uveob_base[1];
- for (i = 0; i < 4; i++)
- for (j = 0; j < 2; j++)
- for (k = 0; k < 2; k++)
- for (l = 0; l < 6; l++)
- for (m = 0; m < 6; m++)
- memcpy(s->prob_ctx[s->framectxid].coef[i][j][k][l][m],
- s->prob.coef[i][j][k][l][m], 3);
- s->prob_ctx[s->framectxid].p = s->prob.p;
- } else {
+ for (tile_row = 0; tile_row < s->tiling.tile_rows; tile_row++) {
+ set_tile_offset(&s->tiling.tile_row_start, &s->tiling.tile_row_end,
+ tile_row, s->tiling.log2_tile_rows, s->sb_rows);
+ if (s->pass != 2) {
+ for (tile_col = 0; tile_col < s->tiling.tile_cols; tile_col++) {
+ unsigned tile_size;
+
+ if (tile_col == s->tiling.tile_cols - 1 &&
+ tile_row == s->tiling.tile_rows - 1) {
+ tile_size = size;
+ } else {
+ tile_size = AV_RB32(data);
+ data += 4;
+ size -= 4;
+ }
+ if (tile_size > size)
+ return AVERROR_INVALIDDATA;
+ ff_vp56_init_range_decoder(&s->c_b[tile_col], data, tile_size);
+ if (vp56_rac_get_prob_branchy(&s->c_b[tile_col], 128)) // marker bit
+ return AVERROR_INVALIDDATA;
+ data += tile_size;
+ size -= tile_size;
+ }
+ }
+
+ for (row = s->tiling.tile_row_start; row < s->tiling.tile_row_end;
+ row += 8, yoff += ls_y * 64, uvoff += ls_uv * 32) {
+ struct VP9Filter *lflvl_ptr = s->lflvl;
+ ptrdiff_t yoff2 = yoff, uvoff2 = uvoff;
+
+ for (tile_col = 0; tile_col < s->tiling.tile_cols; tile_col++) {
+ set_tile_offset(&s->tiling.tile_col_start, &s->tiling.tile_col_end,
+ tile_col, s->tiling.log2_tile_cols, s->sb_cols);
+
+ if (s->pass != 2) {
+ memset(s->left_partition_ctx, 0, 8);
+ memset(s->left_skip_ctx, 0, 8);
+ if (s->keyframe || s->intraonly) {
+ memset(s->left_mode_ctx, DC_PRED, 16);
+ } else {
+ memset(s->left_mode_ctx, NEARESTMV, 8);
+ }
+ memset(s->left_y_nnz_ctx, 0, 16);
+ memset(s->left_uv_nnz_ctx, 0, 16);
+ memset(s->left_segpred_ctx, 0, 8);
+
+ memcpy(&s->c, &s->c_b[tile_col], sizeof(s->c));
+ }
+
+ for (col = s->tiling.tile_col_start;
+ col < s->tiling.tile_col_end;
+ col += 8, yoff2 += 64, uvoff2 += 32, lflvl_ptr++) {
+ // FIXME integrate with lf code (i.e. zero after each
+ // use, similar to invtxfm coefficients, or similar)
+ if (s->pass != 1) {
+ memset(lflvl_ptr->mask, 0, sizeof(lflvl_ptr->mask));
+ }
+
+ if (s->pass == 2) {
+ decode_sb_mem(ctx, row, col, lflvl_ptr,
+ yoff2, uvoff2, BL_64X64);
+ } else {
+ decode_sb(ctx, row, col, lflvl_ptr,
+ yoff2, uvoff2, BL_64X64);
+ }
+ }
+ if (s->pass != 2) {
+ memcpy(&s->c_b[tile_col], &s->c, sizeof(s->c));
+ }
+ }
+
+ if (s->pass == 1) {
+ continue;
+ }
+
+ // backup pre-loopfilter reconstruction data for intra
+ // prediction of next row of sb64s
+ if (row + 8 < s->rows) {
+ memcpy(s->intra_pred_data[0],
+ f->data[0] + yoff + 63 * ls_y,
+ 8 * s->cols);
+ memcpy(s->intra_pred_data[1],
+ f->data[1] + uvoff + 31 * ls_uv,
+ 4 * s->cols);
+ memcpy(s->intra_pred_data[2],
+ f->data[2] + uvoff + 31 * ls_uv,
+ 4 * s->cols);
+ }
+
+ // loopfilter one row
+ if (s->filter.level) {
+ yoff2 = yoff;
+ uvoff2 = uvoff;
+ lflvl_ptr = s->lflvl;
+ for (col = 0; col < s->cols;
+ col += 8, yoff2 += 64, uvoff2 += 32, lflvl_ptr++) {
+ loopfilter_sb(ctx, lflvl_ptr, row, col, yoff2, uvoff2);
+ }
+ }
+
+ // FIXME maybe we can make this more finegrained by running the
+ // loopfilter per-block instead of after each sbrow
+ // In fact that would also make intra pred left preparation easier?
+ ff_thread_report_progress(&s->frames[CUR_FRAME].tf, row >> 3, 0);
+ }
+ }
+
+ if (s->pass < 2 && s->refreshctx && !s->parallelmode) {
adapt_probs(s);
+ ff_thread_finish_setup(ctx);
}
- }
- FFSWAP(struct VP9mvrefPair *, s->mv[0], s->mv[1]);
+ } while (s->pass++ == 1);
+ ff_thread_report_progress(&s->frames[CUR_FRAME].tf, INT_MAX, 0);
// ref frame setup
- for (i = 0; i < 8; i++)
- if (s->refreshrefmask & (1 << i))
- s->refs[i] = s->f;
+ for (i = 0; i < 8; i++) {
+ if (s->refs[i].f->data[0])
+ ff_thread_release_buffer(ctx, &s->refs[i]);
+ ff_thread_ref_frame(&s->refs[i], &s->next_refs[i]);
+ }
if (!s->invisible) {
- if ((res = av_frame_ref(out_pic, s->f)) < 0)
+ if ((res = av_frame_ref(frame, s->frames[CUR_FRAME].tf.f)) < 0)
return res;
*got_frame = 1;
}
@@ -3452,125 +3698,109 @@
return 0;
}
-static int vp9_decode_packet(AVCodecContext *avctx, void *out_pic,
- int *got_frame, AVPacket *avpkt)
-{
- const uint8_t *data = avpkt->data;
- int size = avpkt->size, marker, res;
-
- // read superframe index - this is a collection of individual frames that
- // together lead to one visible frame
- av_assert1(size > 0); // without CODEC_CAP_DELAY, this is implied
- marker = data[size - 1];
- if ((marker & 0xe0) == 0xc0) {
- int nbytes = 1 + ((marker >> 3) & 0x3);
- int n_frames = 1 + (marker & 0x7), idx_sz = 2 + n_frames * nbytes;
-
- if (size >= idx_sz && data[size - idx_sz] == marker) {
- const uint8_t *idx = data + size + 1 - idx_sz;
- switch (nbytes) {
-#define case_n(a, rd) \
- case a: \
- while (n_frames--) { \
- int sz = rd; \
- idx += a; \
- if (sz > size) { \
- av_log(avctx, AV_LOG_ERROR, \
- "Superframe packet size too big: %d > %d\n", \
- sz, size); \
- return AVERROR_INVALIDDATA; \
- } \
- res = vp9_decode_frame(avctx, out_pic, got_frame, \
- data, sz); \
- if (res < 0) \
- return res; \
- data += sz; \
- size -= sz; \
- } \
- break;
- case_n(1, *idx);
- case_n(2, AV_RL16(idx));
- case_n(3, AV_RL24(idx));
- case_n(4, AV_RL32(idx));
- }
- return size;
- }
- }
- // if we get here, there was no valid superframe index, i.e. this is just
- // one whole single frame - decode it as such from the complete input buf
- if ((res = vp9_decode_frame(avctx, out_pic, got_frame, data, size)) < 0)
- return res;
- return size;
-}
-
static void vp9_decode_flush(AVCodecContext *ctx)
{
VP9Context *s = ctx->priv_data;
int i;
- for (i = 0; i < 10; i++)
- if (s->fb[i]->data[0])
- av_frame_unref(s->fb[i]);
+ for (i = 0; i < 2; i++)
+ vp9_unref_frame(ctx, &s->frames[i]);
for (i = 0; i < 8; i++)
- s->refs[i] = NULL;
- s->f = NULL;
+ ff_thread_release_buffer(ctx, &s->refs[i]);
+}
+
+static int init_frames(AVCodecContext *ctx)
+{
+ VP9Context *s = ctx->priv_data;
+ int i;
+
+ for (i = 0; i < 2; i++) {
+ s->frames[i].tf.f = av_frame_alloc();
+ if (!s->frames[i].tf.f) {
+ vp9_decode_free(ctx);
+ av_log(ctx, AV_LOG_ERROR, "Failed to allocate frame buffer %d\n", i);
+ return AVERROR(ENOMEM);
+ }
+ }
+ for (i = 0; i < 8; i++) {
+ s->refs[i].f = av_frame_alloc();
+ s->next_refs[i].f = av_frame_alloc();
+ if (!s->refs[i].f || !s->next_refs[i].f) {
+ vp9_decode_free(ctx);
+ av_log(ctx, AV_LOG_ERROR, "Failed to allocate frame buffer %d\n", i);
+ return AVERROR(ENOMEM);
+ }
+ }
+
+ return 0;
}
static av_cold int vp9_decode_init(AVCodecContext *ctx)
{
VP9Context *s = ctx->priv_data;
- int i;
+ ctx->internal->allocate_progress = 1;
ctx->pix_fmt = AV_PIX_FMT_YUV420P;
ff_vp9dsp_init(&s->dsp);
ff_videodsp_init(&s->vdsp, 8);
- for (i = 0; i < 10; i++) {
- s->fb[i] = av_frame_alloc();
- if (!s->fb[i]) {
- av_log(ctx, AV_LOG_ERROR, "Failed to allocate frame buffer %d\n", i);
- return AVERROR(ENOMEM);
- }
- }
s->filter.sharpness = -1;
- return 0;
+ return init_frames(ctx);
}
-static av_cold int vp9_decode_free(AVCodecContext *ctx)
+static av_cold int vp9_decode_init_thread_copy(AVCodecContext *avctx)
{
- VP9Context *s = ctx->priv_data;
- int i;
+ return init_frames(avctx);
+}
- for (i = 0; i < 10; i++) {
- if (s->fb[i]->data[0])
- av_frame_unref(s->fb[i]);
- av_frame_free(&s->fb[i]);
+static int vp9_decode_update_thread_context(AVCodecContext *dst, const AVCodecContext *src)
+{
+ int i, res;
+ VP9Context *s = dst->priv_data, *ssrc = src->priv_data;
+
+ // FIXME scalability, size, etc.
+
+ for (i = 0; i < 2; i++) {
+ if (s->frames[i].tf.f->data[0])
+ vp9_unref_frame(dst, &s->frames[i]);
+ if (ssrc->frames[i].tf.f->data[0]) {
+ if ((res = vp9_ref_frame(dst, &s->frames[i], &ssrc->frames[i])) < 0)
+ return res;
+ }
}
- av_freep(&s->above_partition_ctx);
- s->above_skip_ctx = s->above_txfm_ctx = s->above_mode_ctx = NULL;
- s->above_y_nnz_ctx = s->above_uv_nnz_ctx[0] = s->above_uv_nnz_ctx[1] = NULL;
- s->intra_pred_data[0] = s->intra_pred_data[1] = s->intra_pred_data[2] = NULL;
- s->above_segpred_ctx = s->above_intra_ctx = s->above_comp_ctx = NULL;
- s->above_ref_ctx = s->above_filter_ctx = NULL;
- s->above_mv_ctx = NULL;
- s->segmentation_map = NULL;
- s->mv[0] = s->mv[1] = NULL;
- s->lflvl = NULL;
- av_freep(&s->c_b);
- s->c_b_size = 0;
+ for (i = 0; i < 8; i++) {
+ if (s->refs[i].f->data[0])
+ ff_thread_release_buffer(dst, &s->refs[i]);
+ if (ssrc->next_refs[i].f->data[0]) {
+ if ((res = ff_thread_ref_frame(&s->refs[i], &ssrc->next_refs[i])) < 0)
+ return res;
+ }
+ }
+
+ s->invisible = ssrc->invisible;
+ s->keyframe = ssrc->keyframe;
+ s->uses_2pass = ssrc->uses_2pass;
+ memcpy(&s->prob_ctx, &ssrc->prob_ctx, sizeof(s->prob_ctx));
+ memcpy(&s->lf_delta, &ssrc->lf_delta, sizeof(s->lf_delta));
+ if (ssrc->segmentation.enabled) {
+ memcpy(&s->segmentation.feat, &ssrc->segmentation.feat,
+ sizeof(s->segmentation.feat));
+ }
return 0;
}
AVCodec ff_vp9_decoder = {
- .name = "vp9",
- .long_name = NULL_IF_CONFIG_SMALL("Google VP9"),
- .type = AVMEDIA_TYPE_VIDEO,
- .id = AV_CODEC_ID_VP9,
- .priv_data_size = sizeof(VP9Context),
- .init = vp9_decode_init,
- .close = vp9_decode_free,
- .decode = vp9_decode_packet,
- .capabilities = CODEC_CAP_DR1,
- .flush = vp9_decode_flush,
+ .name = "vp9",
+ .long_name = NULL_IF_CONFIG_SMALL("Google VP9"),
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = AV_CODEC_ID_VP9,
+ .priv_data_size = sizeof(VP9Context),
+ .init = vp9_decode_init,
+ .close = vp9_decode_free,
+ .decode = vp9_decode_frame,
+ .capabilities = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS,
+ .flush = vp9_decode_flush,
+ .init_thread_copy = ONLY_IF_THREADS_ENABLED(vp9_decode_init_thread_copy),
+ .update_thread_context = ONLY_IF_THREADS_ENABLED(vp9_decode_update_thread_context),
};
diff --git a/libavcodec/vp9_parser.c b/libavcodec/vp9_parser.c
new file mode 100644
index 0000000..24f588f
--- /dev/null
+++ b/libavcodec/vp9_parser.c
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2008 Michael Niedermayer
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "libavutil/intreadwrite.h"
+#include "parser.h"
+
+typedef struct VP9ParseContext {
+ int n_frames; // 1-8
+ int size[8];
+} VP9ParseContext;
+
+static void parse_frame(AVCodecParserContext *ctx, const uint8_t *buf, int size)
+{
+ if (buf[0] & 0x4) {
+ ctx->pict_type = AV_PICTURE_TYPE_P;
+ ctx->key_frame = 0;
+ } else {
+ ctx->pict_type = AV_PICTURE_TYPE_I;
+ ctx->key_frame = 1;
+ }
+}
+
+static int parse(AVCodecParserContext *ctx,
+ AVCodecContext *avctx,
+ const uint8_t **out_data, int *out_size,
+ const uint8_t *data, int size)
+{
+ VP9ParseContext *s = ctx->priv_data;
+ int marker;
+
+ if (size <= 0) {
+ *out_size = 0;
+ *out_data = data;
+
+ return 0;
+ }
+
+ if (s->n_frames > 0) {
+ *out_data = data;
+ *out_size = s->size[--s->n_frames];
+ parse_frame(ctx, *out_data, *out_size);
+
+ return s->n_frames > 0 ? *out_size : size /* i.e. include idx tail */;
+ }
+
+ marker = data[size - 1];
+ if ((marker & 0xe0) == 0xc0) {
+ int nbytes = 1 + ((marker >> 3) & 0x3);
+ int n_frames = 1 + (marker & 0x7), idx_sz = 2 + n_frames * nbytes;
+
+ if (size >= idx_sz && data[size - idx_sz] == marker) {
+ const uint8_t *idx = data + size + 1 - idx_sz;
+ int first = 1;
+
+ switch (nbytes) {
+#define case_n(a, rd) \
+ case a: \
+ while (n_frames--) { \
+ int sz = rd; \
+ idx += a; \
+ if (sz > size) { \
+ s->n_frames = 0; \
+ av_log(ctx, AV_LOG_ERROR, \
+ "Superframe packet size too big: %d > %d\n", \
+ sz, size); \
+ return AVERROR_INVALIDDATA; \
+ } \
+ if (first) { \
+ first = 0; \
+ *out_data = data; \
+ *out_size = sz; \
+ s->n_frames = n_frames; \
+ } else { \
+ s->size[n_frames] = sz; \
+ } \
+ data += sz; \
+ size -= sz; \
+ } \
+ parse_frame(ctx, *out_data, *out_size); \
+ return *out_size
+
+ case_n(1, *idx);
+ case_n(2, AV_RL16(idx));
+ case_n(3, AV_RL24(idx));
+ case_n(4, AV_RL32(idx));
+ }
+ }
+ }
+
+ *out_data = data;
+ *out_size = size;
+ parse_frame(ctx, data, size);
+
+ return size;
+}
+
+AVCodecParser ff_vp9_parser = {
+ .codec_ids = { AV_CODEC_ID_VP9 },
+ .priv_data_size = sizeof(VP9ParseContext),
+ .parser_parse = parse,
+};
diff --git a/libavcodec/vp9data.h b/libavcodec/vp9data.h
index d38365a..625b60e 100644
--- a/libavcodec/vp9data.h
+++ b/libavcodec/vp9data.h
@@ -469,7 +469,7 @@
923, 954, 985, 1016, 831, 862, 893, 955, 986, 1017, 863, 894, 987, 1018, 895, 1019, 924, 925, 956, 926, 957, 988, 927, 958, 989, 1020, 959, 990, 1021, 991, 1022, 1023,
};
-static const int16_t *vp9_scans[5][4] = {
+static const int16_t * const vp9_scans[5][4] = {
{
vp9_default_scan_4x4, vp9_col_scan_4x4,
vp9_row_scan_4x4, vp9_default_scan_4x4
@@ -1026,7 +1026,7 @@
{ 990, 959 }, { 1021, 990 }, { 1022, 991 }, { 0, 0 },
};
-static const int16_t (*vp9_scans_nb[5][4])[2] = {
+static const int16_t (* const vp9_scans_nb[5][4])[2] = {
{
vp9_default_scan_4x4_nb, vp9_col_scan_4x4_nb,
vp9_row_scan_4x4_nb, vp9_default_scan_4x4_nb
diff --git a/libavcodec/vp9dsp.c b/libavcodec/vp9dsp.c
index d35d753..ec0b411 100644
--- a/libavcodec/vp9dsp.c
+++ b/libavcodec/vp9dsp.c
@@ -772,9 +772,9 @@
vo[size - 2] = (top[size - 2] + top[size - 1] * 3 + 2) >> 2; \
\
for (j = 0; j < size / 2; j++) { \
- memcpy(dst + j*2 * stride, ve + j, size - j); \
+ memcpy(dst + j*2 * stride, ve + j, size - j - 1); \
memset(dst + j*2 * stride + size - j - 1, top[size - 1], j + 1); \
- memcpy(dst + (j*2 + 1) * stride, vo + j, size - j); \
+ memcpy(dst + (j*2 + 1) * stride, vo + j, size - j - 1); \
memset(dst + (j*2 + 1) * stride + size - j - 1, top[size - 1], j + 1); \
} \
}
@@ -853,13 +853,29 @@
#undef init_intra_pred
}
-#define itxfm_wrapper(type_a, type_b, sz, bits) \
+#define itxfm_wrapper(type_a, type_b, sz, bits, has_dconly) \
static void type_a##_##type_b##_##sz##x##sz##_add_c(uint8_t *dst, \
ptrdiff_t stride, \
int16_t *block, int eob) \
{ \
int i, j; \
int16_t tmp[sz * sz], out[sz]; \
+\
+ if (has_dconly && eob == 1) { \
+ const int t = (((block[0] * 11585 + (1 << 13)) >> 14) \
+ * 11585 + (1 << 13)) >> 14; \
+ block[0] = 0; \
+ for (i = 0; i < sz; i++) { \
+ for (j = 0; j < sz; j++) \
+ dst[j * stride] = av_clip_uint8(dst[j * stride] + \
+ (bits ? \
+ (t + (1 << (bits - 1))) >> bits : \
+ t)); \
+ dst++; \
+ } \
+ return; \
+ } \
+\
for (i = 0; i < sz; i++) \
type_a##sz##_1d(block + i, sz, tmp + i * sz, 0); \
memset(block, 0, sz * sz * sizeof(*block)); \
@@ -875,10 +891,10 @@
}
#define itxfm_wrap(sz, bits) \
-itxfm_wrapper(idct, idct, sz, bits) \
-itxfm_wrapper(iadst, idct, sz, bits) \
-itxfm_wrapper(idct, iadst, sz, bits) \
-itxfm_wrapper(iadst, iadst, sz, bits)
+itxfm_wrapper(idct, idct, sz, bits, 1) \
+itxfm_wrapper(iadst, idct, sz, bits, 0) \
+itxfm_wrapper(idct, iadst, sz, bits, 0) \
+itxfm_wrapper(iadst, iadst, sz, bits, 0)
#define IN(x) in[x * stride]
@@ -1397,7 +1413,7 @@
out[31] = t0 - t31;
}
-itxfm_wrapper(idct, idct, 32, 6)
+itxfm_wrapper(idct, idct, 32, 6, 1)
static av_always_inline void iwht4_1d(const int16_t *in, ptrdiff_t stride,
int16_t *out, int pass)
@@ -1430,7 +1446,7 @@
out[3] = t3;
}
-itxfm_wrapper(iwht, iwht, 4, 0)
+itxfm_wrapper(iwht, iwht, 4, 0, 0)
#undef IN
#undef itxfm_wrapper
@@ -1460,8 +1476,7 @@
#undef init_idct
}
-static av_always_inline void loop_filter(uint8_t *dst, ptrdiff_t stride,
- int E, int I, int H,
+static av_always_inline void loop_filter(uint8_t *dst, int E, int I, int H,
ptrdiff_t stridea, ptrdiff_t strideb,
int wd)
{
@@ -1573,7 +1588,7 @@
ptrdiff_t stride, \
int E, int I, int H) \
{ \
- loop_filter(dst, stride, E, I, H, stridea, strideb, wd); \
+ loop_filter(dst, E, I, H, stridea, strideb, wd); \
}
#define lf_8_fns(wd) \
diff --git a/libavcodec/wavpack.c b/libavcodec/wavpack.c
index 203cd28..6036a5c 100644
--- a/libavcodec/wavpack.c
+++ b/libavcodec/wavpack.c
@@ -548,9 +548,11 @@
} while (!last && count < s->samples);
wv_reset_saved_context(s);
- if ((s->avctx->err_recognition & AV_EF_CRCCHECK) &&
- wv_check_crc(s, crc, crc_extra_bits))
- return AVERROR_INVALIDDATA;
+ if (s->avctx->err_recognition & AV_EF_CRCCHECK) {
+ int ret = wv_check_crc(s, crc, crc_extra_bits);
+ if (ret < 0 && s->avctx->err_recognition & AV_EF_EXPLODE)
+ return ret;
+ }
return 0;
}
@@ -845,7 +847,8 @@
case WP_ID_DATA:
s->sc.offset = bytestream2_tell(&gb);
s->sc.size = size * 8;
- init_get_bits(&s->gb, gb.buffer, size * 8);
+ if ((ret = init_get_bits8(&s->gb, gb.buffer, size)) < 0)
+ return ret;
s->data_size = size * 8;
bytestream2_skip(&gb, size);
got_bs = 1;
@@ -859,7 +862,8 @@
}
s->extra_sc.offset = bytestream2_tell(&gb);
s->extra_sc.size = size * 8;
- init_get_bits(&s->gb_extra_bits, gb.buffer, size * 8);
+ if ((ret = init_get_bits8(&s->gb_extra_bits, gb.buffer, size)) < 0)
+ return ret;
s->crc_extra_bits = get_bits_long(&s->gb_extra_bits, 32);
bytestream2_skip(&gb, size);
s->got_extra_bits = 1;
diff --git a/libavcodec/wavpackenc.c b/libavcodec/wavpackenc.c
index 10e6e14..d7a1c61 100644
--- a/libavcodec/wavpackenc.c
+++ b/libavcodec/wavpackenc.c
@@ -2482,7 +2482,7 @@
uint8_t *out, int out_size)
{
int block_size, start, end, data_size, tcount, temp, m = 0;
- int i, j, ret, got_extra = 0, nb_samples = s->block_samples;
+ int i, j, ret = 0, got_extra = 0, nb_samples = s->block_samples;
uint32_t crc = 0xffffffffu;
struct Decorr *dpp;
PutByteContext pb;
diff --git a/libavcodec/webp.c b/libavcodec/webp.c
index 213e1ce..c6d41be 100644
--- a/libavcodec/webp.c
+++ b/libavcodec/webp.c
@@ -277,10 +277,26 @@
static int huff_reader_build_canonical(HuffReader *r, int *code_lengths,
int alphabet_size)
{
- int len, sym, code, ret;
+ int len = 0, sym, code = 0, ret;
int max_code_length = 0;
uint16_t *codes;
+ /* special-case 1 symbol since the vlc reader cannot handle it */
+ for (sym = 0; sym < alphabet_size; sym++) {
+ if (code_lengths[sym] > 0) {
+ len++;
+ code = sym;
+ if (len > 1)
+ break;
+ }
+ }
+ if (len == 1) {
+ r->nb_symbols = 1;
+ r->simple_symbols[0] = code;
+ r->simple = 1;
+ return 0;
+ }
+
for (sym = 0; sym < alphabet_size; sym++)
max_code_length = FFMAX(max_code_length, code_lengths[sym]);
@@ -1085,10 +1101,10 @@
s->width, w);
}
s->height = h;
- ret = av_image_check_size(s->width, s->height, 0, avctx);
+
+ ret = ff_set_dimensions(avctx, s->width, s->height);
if (ret < 0)
return ret;
- avcodec_set_dimensions(avctx, s->width, s->height);
s->has_alpha = get_bits1(&s->gb);
@@ -1129,10 +1145,8 @@
if (is_alpha_chunk)
s->image[IMAGE_ROLE_ARGB].is_alpha_primary = 1;
ret = decode_entropy_coded_image(s, IMAGE_ROLE_ARGB, w, h);
- if (ret < 0) {
- av_frame_free(&p);
+ if (ret < 0)
goto free_and_return;
- }
/* apply transformations */
for (i = s->nb_transforms - 1; i >= 0; i--) {
@@ -1150,10 +1164,8 @@
ret = apply_color_indexing_transform(s);
break;
}
- if (ret < 0) {
- av_frame_free(&p);
+ if (ret < 0)
goto free_and_return;
- }
}
*got_frame = 1;
diff --git a/libavcodec/wmalosslessdec.c b/libavcodec/wmalosslessdec.c
index 21b4f91..7a80248 100644
--- a/libavcodec/wmalosslessdec.c
+++ b/libavcodec/wmalosslessdec.c
@@ -1182,6 +1182,8 @@
if (s->packet_done || s->packet_loss) {
s->packet_done = 0;
+ if (!buf_size)
+ return 0;
/* sanity check for the buffer length */
if (buf_size < avctx->block_align) {
av_log(avctx, AV_LOG_ERROR, "buf size %d invalid\n", buf_size);
diff --git a/libavcodec/wmaprodec.c b/libavcodec/wmaprodec.c
index 6de6fcd..d57c24d 100644
--- a/libavcodec/wmaprodec.c
+++ b/libavcodec/wmaprodec.c
@@ -681,7 +681,7 @@
/**
*@brief Decode channel transformation parameters
*@param s codec context
- *@return 0 in case of success, < 0 in case of bitstream errors
+ *@return >= 0 in case of success, < 0 in case of bitstream errors
*/
static int decode_channel_transform(WMAProDecodeCtx* s)
{
diff --git a/libavcodec/wmv2.c b/libavcodec/wmv2.c
index 8d30259..30c8bc1 100644
--- a/libavcodec/wmv2.c
+++ b/libavcodec/wmv2.c
@@ -119,9 +119,11 @@
if(src_x<1 || src_y<1 || src_x + 17 >= s->h_edge_pos
|| src_y + h+1 >= v_edge_pos){
- s->vdsp.emulated_edge_mc(s->edge_emu_buffer, s->linesize,
- ptr - 1 - s->linesize, s->linesize, 19, 19,
- src_x-1, src_y-1,
+ s->vdsp.emulated_edge_mc(s->edge_emu_buffer,
+ ptr - 1 - s->linesize,
+ s->linesize, s->linesize,
+ 19, 19,
+ src_x - 1, src_y - 1,
s->h_edge_pos, s->v_edge_pos);
ptr= s->edge_emu_buffer + 1 + s->linesize;
emu=1;
@@ -161,18 +163,22 @@
offset = (src_y * uvlinesize) + src_x;
ptr = ref_picture[1] + offset;
if(emu){
- s->vdsp.emulated_edge_mc(s->edge_emu_buffer, s->uvlinesize,
- ptr, s->uvlinesize, 9, 9, src_x, src_y,
- s->h_edge_pos>>1, s->v_edge_pos>>1);
+ s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr,
+ s->uvlinesize, s->uvlinesize,
+ 9, 9,
+ src_x, src_y,
+ s->h_edge_pos >> 1, s->v_edge_pos >> 1);
ptr= s->edge_emu_buffer;
}
pix_op[1][dxy](dest_cb, ptr, uvlinesize, h >> 1);
ptr = ref_picture[2] + offset;
if(emu){
- s->vdsp.emulated_edge_mc(s->edge_emu_buffer, s->uvlinesize,
- ptr, s->uvlinesize, 9, 9, src_x, src_y,
- s->h_edge_pos>>1, s->v_edge_pos>>1);
+ s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr,
+ s->uvlinesize, s->uvlinesize,
+ 9, 9,
+ src_x, src_y,
+ s->h_edge_pos >> 1, s->v_edge_pos >> 1);
ptr= s->edge_emu_buffer;
}
pix_op[1][dxy](dest_cr, ptr, uvlinesize, h >> 1);
diff --git a/libavcodec/wmv2enc.c b/libavcodec/wmv2enc.c
index ab5e085..6aeee59 100644
--- a/libavcodec/wmv2enc.c
+++ b/libavcodec/wmv2enc.c
@@ -169,10 +169,12 @@
ff_wmv2_inter_table[w->cbp_table_index][cbp + 64][1],
ff_wmv2_inter_table[w->cbp_table_index][cbp + 64][0]);
+ s->misc_bits += get_bits_diff(s);
/* motion vector */
ff_h263_pred_motion(s, 0, 0, &pred_x, &pred_y);
ff_msmpeg4_encode_motion(s, motion_x - pred_x,
motion_y - pred_y);
+ s->mv_bits += get_bits_diff(s);
} else {
/* compute cbp */
cbp = 0;
@@ -203,11 +205,16 @@
s->h263_aic_dir=0;
put_bits(&s->pb, ff_table_inter_intra[s->h263_aic_dir][1], ff_table_inter_intra[s->h263_aic_dir][0]);
}
+ s->misc_bits += get_bits_diff(s);
}
for (i = 0; i < 6; i++) {
ff_msmpeg4_encode_block(s, block[i], i);
}
+ if (s->mb_intra)
+ s->i_tex_bits += get_bits_diff(s);
+ else
+ s->p_tex_bits += get_bits_diff(s);
}
AVCodec ff_wmv2_encoder = {
diff --git a/libavcodec/x86/Makefile b/libavcodec/x86/Makefile
index da86815..2d2d5a0 100644
--- a/libavcodec/x86/Makefile
+++ b/libavcodec/x86/Makefile
@@ -12,6 +12,7 @@
x86/fdct.o \
x86/motion_est.o
OBJS-$(CONFIG_FFT) += x86/fft_init.o
+OBJS-$(CONFIG_H263DSP) += x86/h263dsp_init.o
OBJS-$(CONFIG_H264CHROMA) += x86/h264chroma_init.o
OBJS-$(CONFIG_H264DSP) += x86/h264dsp_init.o
OBJS-$(CONFIG_H264PRED) += x86/h264_intrapred_init.o
@@ -68,8 +69,7 @@
x86/qpel.o
YASM-OBJS-$(CONFIG_ENCODERS) += x86/dsputilenc.o
YASM-OBJS-$(CONFIG_FFT) += x86/fft.o
-YASM-OBJS-$(CONFIG_H263_DECODER) += x86/h263_loopfilter.o
-YASM-OBJS-$(CONFIG_H263_ENCODER) += x86/h263_loopfilter.o
+YASM-OBJS-$(CONFIG_H263DSP) += x86/h263_loopfilter.o
YASM-OBJS-$(CONFIG_H264CHROMA) += x86/h264_chromamc.o \
x86/h264_chromamc_10bit.o
YASM-OBJS-$(CONFIG_H264DSP) += x86/h264_deblock.o \
@@ -99,6 +99,8 @@
YASM-OBJS-$(CONFIG_VORBIS_DECODER) += x86/vorbisdsp.o
YASM-OBJS-$(CONFIG_VP3DSP) += x86/vp3dsp.o
YASM-OBJS-$(CONFIG_VP6_DECODER) += x86/vp6dsp.o
-YASM-OBJS-$(CONFIG_VP8_DECODER) += x86/vp8dsp.o
-YASM-OBJS-$(CONFIG_VP9_DECODER) += x86/vp9dsp.o
+YASM-OBJS-$(CONFIG_VP8_DECODER) += x86/vp8dsp.o \
+ x86/vp8dsp_loopfilter.o
+YASM-OBJS-$(CONFIG_VP9_DECODER) += x86/vp9itxfm.o \
+ x86/vp9mc.o
YASM-OBJS-$(CONFIG_WEBP_DECODER) += x86/vp8dsp.o
diff --git a/libavcodec/x86/ac3dsp_init.c b/libavcodec/x86/ac3dsp_init.c
index 8c94db0..5819d00 100644
--- a/libavcodec/x86/ac3dsp_init.c
+++ b/libavcodec/x86/ac3dsp_init.c
@@ -51,6 +51,19 @@
void ff_ac3_extract_exponents_sse2 (uint8_t *exp, int32_t *coef, int nb_coefs);
void ff_ac3_extract_exponents_ssse3(uint8_t *exp, int32_t *coef, int nb_coefs);
+void ff_apply_window_int16_round_mmxext(int16_t *output, const int16_t *input,
+ const int16_t *window, unsigned int len);
+void ff_apply_window_int16_round_sse2(int16_t *output, const int16_t *input,
+ const int16_t *window, unsigned int len);
+void ff_apply_window_int16_mmxext(int16_t *output, const int16_t *input,
+ const int16_t *window, unsigned int len);
+void ff_apply_window_int16_sse2(int16_t *output, const int16_t *input,
+ const int16_t *window, unsigned int len);
+void ff_apply_window_int16_ssse3(int16_t *output, const int16_t *input,
+ const int16_t *window, unsigned int len);
+void ff_apply_window_int16_ssse3_atom(int16_t *output, const int16_t *input,
+ const int16_t *window, unsigned int len);
+
#if ARCH_X86_32 && defined(__INTEL_COMPILER)
# undef HAVE_7REGS
# define HAVE_7REGS 0
@@ -201,6 +214,11 @@
if (EXTERNAL_MMXEXT(cpu_flags)) {
c->ac3_exponent_min = ff_ac3_exponent_min_mmxext;
c->ac3_max_msb_abs_int16 = ff_ac3_max_msb_abs_int16_mmxext;
+ if (bit_exact) {
+ c->apply_window_int16 = ff_apply_window_int16_mmxext;
+ } else {
+ c->apply_window_int16 = ff_apply_window_int16_round_mmxext;
+ }
}
if (EXTERNAL_SSE(cpu_flags)) {
c->float_to_fixed24 = ff_float_to_fixed24_sse;
@@ -215,11 +233,19 @@
c->ac3_lshift_int16 = ff_ac3_lshift_int16_sse2;
c->ac3_rshift_int32 = ff_ac3_rshift_int32_sse2;
}
+ if (bit_exact) {
+ c->apply_window_int16 = ff_apply_window_int16_sse2;
+ } else if (!(cpu_flags & AV_CPU_FLAG_SSE2SLOW)) {
+ c->apply_window_int16 = ff_apply_window_int16_round_sse2;
+ }
}
if (EXTERNAL_SSSE3(cpu_flags)) {
c->ac3_max_msb_abs_int16 = ff_ac3_max_msb_abs_int16_ssse3;
- if (!(cpu_flags & AV_CPU_FLAG_ATOM)) {
+ if (cpu_flags & AV_CPU_FLAG_ATOM) {
+ c->apply_window_int16 = ff_apply_window_int16_ssse3_atom;
+ } else {
c->extract_exponents = ff_ac3_extract_exponents_ssse3;
+ c->apply_window_int16 = ff_apply_window_int16_ssse3;
}
}
diff --git a/libavcodec/x86/cabac.h b/libavcodec/x86/cabac.h
index 89011e8..558d287 100644
--- a/libavcodec/x86/cabac.h
+++ b/libavcodec/x86/cabac.h
@@ -36,6 +36,18 @@
#if HAVE_INLINE_ASM
+#ifndef UNCHECKED_BITSTREAM_READER
+#define UNCHECKED_BITSTREAM_READER !CONFIG_SAFE_BITSTREAM_READER
+#endif
+
+#if UNCHECKED_BITSTREAM_READER
+#define END_CHECK(end) ""
+#else
+#define END_CHECK(end) \
+ "cmp "end" , %%"REG_c" \n\t"\
+ "jge 1f \n\t"
+#endif
+
#ifdef BROKEN_RELOCATIONS
#define TABLES_ARG , "r"(tables)
@@ -80,7 +92,9 @@
"test "lowword" , "lowword" \n\t"\
"jnz 2f \n\t"\
"mov "byte" , %%"REG_c" \n\t"\
+ END_CHECK(end)\
"add"OPSIZE" $2 , "byte" \n\t"\
+ "1: \n\t"\
"movzwl (%%"REG_c") , "tmp" \n\t"\
"lea -1("low") , %%ecx \n\t"\
"xor "low" , %%ecx \n\t"\
@@ -139,7 +153,9 @@
"test "lowword" , "lowword" \n\t"\
" jnz 2f \n\t"\
"mov "byte" , %%"REG_c" \n\t"\
+ END_CHECK(end)\
"add"OPSIZE" $2 , "byte" \n\t"\
+ "1: \n\t"\
"movzwl (%%"REG_c") , "tmp" \n\t"\
"lea -1("low") , %%ecx \n\t"\
"xor "low" , %%ecx \n\t"\
@@ -191,6 +207,7 @@
}
#endif /* HAVE_7REGS */
+#if !BROKEN_COMPILER
#define get_cabac_bypass_sign get_cabac_bypass_sign_x86
static av_always_inline int get_cabac_bypass_sign_x86(CABACContext *c, int val)
{
@@ -213,9 +230,16 @@
"movzwl (%1), %%edx \n\t"
"bswap %%edx \n\t"
"shrl $15, %%edx \n\t"
+#if UNCHECKED_BITSTREAM_READER
"add $2, %1 \n\t"
"addl %%edx, %%eax \n\t"
"mov %1, %c4(%2) \n\t"
+#else
+ "addl %%edx, %%eax \n\t"
+ "cmp %c5(%2), %1 \n\t"
+ "jge 1f \n\t"
+ "add"OPSIZE" $2, %c4(%2) \n\t"
+#endif
"1: \n\t"
"movl %%eax, %c3(%2) \n\t"
@@ -230,7 +254,6 @@
return val;
}
-#if !BROKEN_COMPILER
#define get_cabac_bypass get_cabac_bypass_x86
static av_always_inline int get_cabac_bypass_x86(CABACContext *c)
{
diff --git a/libavcodec/x86/cavsdsp.c b/libavcodec/x86/cavsdsp.c
index 068995d..aaa09d1 100644
--- a/libavcodec/x86/cavsdsp.c
+++ b/libavcodec/x86/cavsdsp.c
@@ -547,12 +547,12 @@
if (INLINE_MMX(cpu_flags))
cavsdsp_init_mmx(c, avctx);
#endif /* HAVE_MMX_INLINE */
-#if HAVE_MMXEXT_INLINE
- if (INLINE_MMXEXT(cpu_flags))
- cavsdsp_init_mmxext(c, avctx);
-#endif /* HAVE_MMXEXT_INLINE */
#if HAVE_AMD3DNOW_INLINE
if (INLINE_AMD3DNOW(cpu_flags))
cavsdsp_init_3dnow(c, avctx);
#endif /* HAVE_AMD3DNOW_INLINE */
+#if HAVE_MMXEXT_INLINE
+ if (INLINE_MMXEXT(cpu_flags))
+ cavsdsp_init_mmxext(c, avctx);
+#endif /* HAVE_MMXEXT_INLINE */
}
diff --git a/libavcodec/x86/dsputil_init.c b/libavcodec/x86/dsputil_init.c
index 2516f2a..4c9f499 100644
--- a/libavcodec/x86/dsputil_init.c
+++ b/libavcodec/x86/dsputil_init.c
@@ -22,6 +22,7 @@
#include "config.h"
#include "libavutil/attributes.h"
#include "libavutil/cpu.h"
+#include "libavutil/internal.h"
#include "libavutil/x86/asm.h"
#include "libavutil/x86/cpu.h"
#include "libavcodec/dsputil.h"
@@ -71,9 +72,6 @@
#define ff_put_no_rnd_pixels16_mmxext ff_put_pixels16_mmxext
#define ff_put_no_rnd_pixels8_mmxext ff_put_pixels8_mmxext
-void ff_h263_v_loop_filter_mmx(uint8_t *src, int stride, int qscale);
-void ff_h263_h_loop_filter_mmx(uint8_t *src, int stride, int qscale);
-
int32_t ff_scalarproduct_int16_mmxext(const int16_t *v1, const int16_t *v2,
int order);
int32_t ff_scalarproduct_int16_sse2(const int16_t *v1, const int16_t *v2,
@@ -88,19 +86,6 @@
const int16_t *v3,
int order, int mul);
-void ff_apply_window_int16_round_mmxext(int16_t *output, const int16_t *input,
- const int16_t *window, unsigned int len);
-void ff_apply_window_int16_round_sse2(int16_t *output, const int16_t *input,
- const int16_t *window, unsigned int len);
-void ff_apply_window_int16_mmxext(int16_t *output, const int16_t *input,
- const int16_t *window, unsigned int len);
-void ff_apply_window_int16_sse2(int16_t *output, const int16_t *input,
- const int16_t *window, unsigned int len);
-void ff_apply_window_int16_ssse3(int16_t *output, const int16_t *input,
- const int16_t *window, unsigned int len);
-void ff_apply_window_int16_ssse3_atom(int16_t *output, const int16_t *input,
- const int16_t *window, unsigned int len);
-
void ff_bswap32_buf_ssse3(uint32_t *dst, const uint32_t *src, int w);
void ff_bswap32_buf_sse2(uint32_t *dst, const uint32_t *src, int w);
@@ -556,11 +541,6 @@
#endif /* HAVE_MMX_INLINE */
#if HAVE_MMX_EXTERNAL
- if (CONFIG_H263_DECODER || CONFIG_H263_ENCODER) {
- c->h263_v_loop_filter = ff_h263_v_loop_filter_mmx;
- c->h263_h_loop_filter = ff_h263_h_loop_filter_mmx;
- }
-
c->vector_clip_int32 = ff_vector_clip_int32_mmx;
#endif /* HAVE_MMX_EXTERNAL */
}
@@ -593,12 +573,6 @@
c->scalarproduct_int16 = ff_scalarproduct_int16_mmxext;
c->scalarproduct_and_madd_int16 = ff_scalarproduct_and_madd_int16_mmxext;
-
- if (avctx->flags & CODEC_FLAG_BITEXACT) {
- c->apply_window_int16 = ff_apply_window_int16_mmxext;
- } else {
- c->apply_window_int16 = ff_apply_window_int16_round_mmxext;
- }
#endif /* HAVE_MMXEXT_EXTERNAL */
}
@@ -609,11 +583,17 @@
const int high_bit_depth = avctx->bits_per_raw_sample > 8;
if (!high_bit_depth) {
+#if FF_API_XVMC
+FF_DISABLE_DEPRECATION_WARNINGS
if (!(CONFIG_MPEG_XVMC_DECODER && avctx->xvmc_acceleration > 1)) {
/* XvMCCreateBlocks() may not allocate 16-byte aligned blocks */
- c->clear_block = ff_clear_block_sse;
- c->clear_blocks = ff_clear_blocks_sse;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif /* FF_API_XVMC */
+ c->clear_block = ff_clear_block_sse;
+ c->clear_blocks = ff_clear_blocks_sse;
+#if FF_API_XVMC
}
+#endif /* FF_API_XVMC */
}
c->vector_clipf = ff_vector_clipf_sse;
@@ -648,11 +628,6 @@
} 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;
- } else if (!(cpu_flags & AV_CPU_FLAG_SSE2SLOW)) {
- c->apply_window_int16 = ff_apply_window_int16_round_sse2;
- }
c->bswap_buf = ff_bswap32_buf_sse2;
#endif /* HAVE_SSE2_EXTERNAL */
}
@@ -665,10 +640,6 @@
if (cpu_flags & AV_CPU_FLAG_SSE4) // not really SSE4, just slow on Conroe
c->add_hfyu_left_prediction = ff_add_hfyu_left_prediction_sse4;
- if (cpu_flags & AV_CPU_FLAG_ATOM)
- c->apply_window_int16 = ff_apply_window_int16_ssse3_atom;
- else
- c->apply_window_int16 = ff_apply_window_int16_ssse3;
if (!(cpu_flags & (AV_CPU_FLAG_SSE42 | AV_CPU_FLAG_3DNOW))) // cachesplit
c->scalarproduct_and_madd_int16 = ff_scalarproduct_and_madd_int16_ssse3;
c->bswap_buf = ff_bswap32_buf_ssse3;
diff --git a/libavcodec/x86/dsputil_mmx.c b/libavcodec/x86/dsputil_mmx.c
index 805bacd..df8cfdb 100644
--- a/libavcodec/x86/dsputil_mmx.c
+++ b/libavcodec/x86/dsputil_mmx.c
@@ -367,8 +367,9 @@
}
}
-typedef void emulated_edge_mc_func(uint8_t *dst, ptrdiff_t dst_stride,
- const uint8_t *src, ptrdiff_t src_linesize,
+typedef void emulated_edge_mc_func(uint8_t *dst, const uint8_t *src,
+ ptrdiff_t dst_stride,
+ ptrdiff_t src_linesize,
int block_w, int block_h,
int src_x, int src_y, int w, int h);
@@ -417,7 +418,7 @@
src += ix + iy * stride;
if (need_emu) {
- emu_edge_fn(edge_buf, stride, src, stride, w + 1, h + 1, ix, iy, width, height);
+ emu_edge_fn(edge_buf, src, stride, stride, w + 1, h + 1, ix, iy, width, height);
src = edge_buf;
}
diff --git a/libavcodec/x86/dsputilenc_mmx.c b/libavcodec/x86/dsputilenc_mmx.c
index 6205577..5de8ade 100644
--- a/libavcodec/x86/dsputilenc_mmx.c
+++ b/libavcodec/x86/dsputilenc_mmx.c
@@ -992,6 +992,13 @@
c->ssd_int8_vs_int16 = ssd_int8_vs_int16_mmx;
}
+ if (INLINE_AMD3DNOW(cpu_flags)) {
+ if (!(avctx->flags & CODEC_FLAG_BITEXACT)) {
+ c->try_8x8basis = try_8x8basis_3dnow;
+ }
+ c->add_8x8basis = add_8x8basis_3dnow;
+ }
+
if (INLINE_MMXEXT(cpu_flags)) {
if (avctx->bits_per_raw_sample <= 8 &&
(dct_algo == FF_DCT_AUTO || dct_algo == FF_DCT_MMX))
@@ -1024,13 +1031,6 @@
c->sum_abs_dctelem = sum_abs_dctelem_ssse3;
}
#endif
-
- if (INLINE_AMD3DNOW(cpu_flags)) {
- if (!(avctx->flags & CODEC_FLAG_BITEXACT)) {
- c->try_8x8basis = try_8x8basis_3dnow;
- }
- c->add_8x8basis = add_8x8basis_3dnow;
- }
#endif /* HAVE_INLINE_ASM */
if (EXTERNAL_MMX(cpu_flags)) {
diff --git a/libavcodec/x86/h263dsp_init.c b/libavcodec/x86/h263dsp_init.c
new file mode 100644
index 0000000..ab81063
--- /dev/null
+++ b/libavcodec/x86/h263dsp_init.c
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2013 Diego Biurrun <diego@biurrun.de>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdint.h>
+
+#include "libavutil/attributes.h"
+#include "libavutil/cpu.h"
+#include "libavutil/x86/cpu.h"
+#include "libavcodec/h263dsp.h"
+
+void ff_h263_h_loop_filter_mmx(uint8_t *src, int stride, int qscale);
+void ff_h263_v_loop_filter_mmx(uint8_t *src, int stride, int qscale);
+
+av_cold void ff_h263dsp_init_x86(H263DSPContext *c)
+{
+ int cpu_flags = av_get_cpu_flags();
+
+ if (EXTERNAL_MMX(cpu_flags)) {
+ c->h263_h_loop_filter = ff_h263_h_loop_filter_mmx;
+ c->h263_v_loop_filter = ff_h263_v_loop_filter_mmx;
+ }
+}
diff --git a/libavcodec/x86/h264_intrapred.asm b/libavcodec/x86/h264_intrapred.asm
index 5c0dff4..3064ec5 100644
--- a/libavcodec/x86/h264_intrapred.asm
+++ b/libavcodec/x86/h264_intrapred.asm
@@ -2486,10 +2486,7 @@
pshufb mm3, mm6
pshufb mm4, mm6
pshufb mm5, mm6
- psubw mm2, mm7
- psubw mm3, mm7
- psubw mm4, mm7
- psubw mm5, mm7
+ psubw mm0, mm7
paddw mm2, mm0
paddw mm3, mm0
paddw mm4, mm0
diff --git a/libavcodec/x86/hpeldsp.asm b/libavcodec/x86/hpeldsp.asm
index 1a572a3..4eaba6e 100644
--- a/libavcodec/x86/hpeldsp.asm
+++ b/libavcodec/x86/hpeldsp.asm
@@ -423,30 +423,30 @@
mova m6, [pb_1]
lea r4, [r2*2]
mova m0, [r1]
- pavgb m0, [r1+1]
+ PAVGB m0, [r1+1]
.loop:
mova m2, [r1+r4]
mova m1, [r1+r2]
psubusb m2, m6
- pavgb m1, [r1+r2+1]
- pavgb m2, [r1+r4+1]
+ PAVGB m1, [r1+r2+1]
+ PAVGB m2, [r1+r4+1]
add r1, r4
- pavgb m0, m1
- pavgb m1, m2
- pavgb m0, [r0]
- pavgb m1, [r0+r2]
+ PAVGB m0, m1
+ PAVGB m1, m2
+ PAVGB m0, [r0]
+ PAVGB m1, [r0+r2]
mova [r0], m0
mova [r0+r2], m1
mova m1, [r1+r2]
mova m0, [r1+r4]
- pavgb m1, [r1+r2+1]
- pavgb m0, [r1+r4+1]
+ PAVGB m1, [r1+r2+1]
+ PAVGB m0, [r1+r4+1]
add r0, r4
add r1, r4
- pavgb m2, m1
- pavgb m1, m0
- pavgb m2, [r0]
- pavgb m1, [r0+r2]
+ PAVGB m2, m1
+ PAVGB m1, m0
+ PAVGB m2, [r0]
+ PAVGB m1, [r0+r2]
mova [r0], m2
mova [r0+r2], m1
add r0, r4
diff --git a/libavcodec/x86/hpeldsp_init.c b/libavcodec/x86/hpeldsp_init.c
index 7db0683..8ecf909 100644
--- a/libavcodec/x86/hpeldsp_init.c
+++ b/libavcodec/x86/hpeldsp_init.c
@@ -258,12 +258,12 @@
if (INLINE_MMX(cpu_flags))
hpeldsp_init_mmx(c, flags, cpu_flags);
- if (EXTERNAL_MMXEXT(cpu_flags))
- hpeldsp_init_mmxext(c, flags, cpu_flags);
-
if (EXTERNAL_AMD3DNOW(cpu_flags))
hpeldsp_init_3dnow(c, flags, cpu_flags);
+ if (EXTERNAL_MMXEXT(cpu_flags))
+ hpeldsp_init_mmxext(c, flags, cpu_flags);
+
if (EXTERNAL_SSE2(cpu_flags))
hpeldsp_init_sse2(c, flags, cpu_flags);
}
diff --git a/libavcodec/x86/mpegvideoenc.c b/libavcodec/x86/mpegvideoenc.c
index 97aa3c7..77fc163 100644
--- a/libavcodec/x86/mpegvideoenc.c
+++ b/libavcodec/x86/mpegvideoenc.c
@@ -28,7 +28,8 @@
#include "libavcodec/mpegvideo.h"
#include "dsputil_x86.h"
-extern uint16_t ff_inv_zigzag_direct16[64];
+/* not permutated inverse zigzag_direct + 1 for MMX quantizer */
+DECLARE_ALIGNED(16, static uint16_t, inv_zigzag_direct16)[64];
#if HAVE_MMX_INLINE
#define COMPILE_TEMPLATE_MMXEXT 0
@@ -84,6 +85,10 @@
av_cold void ff_dct_encode_init_x86(MpegEncContext *s)
{
const int dct_algo = s->avctx->dct_algo;
+ int i;
+
+ for (i = 0; i < 64; i++)
+ inv_zigzag_direct16[ff_zigzag_direct[i]] = i + 1;
if (dct_algo == FF_DCT_AUTO || dct_algo == FF_DCT_MMX) {
#if HAVE_MMX_INLINE
diff --git a/libavcodec/x86/mpegvideoenc_template.c b/libavcodec/x86/mpegvideoenc_template.c
index 1e0505e..0defc40 100644
--- a/libavcodec/x86/mpegvideoenc_template.c
+++ b/libavcodec/x86/mpegvideoenc_template.c
@@ -171,7 +171,7 @@
"movzb %%al, %%"REG_a" \n\t" // last_non_zero_p1
: "+a" (last_non_zero_p1)
: "r" (block+64), "r" (qmat), "r" (bias),
- "r" (ff_inv_zigzag_direct16+64), "r" (temp_block+64)
+ "r" (inv_zigzag_direct16 + 64), "r" (temp_block + 64)
XMM_CLOBBERS_ONLY("%xmm0", "%xmm1", "%xmm2", "%xmm3",
"%xmm4", "%xmm5", "%xmm6", "%xmm7")
);
@@ -205,7 +205,7 @@
"movzb %%al, %%"REG_a" \n\t" // last_non_zero_p1
: "+a" (last_non_zero_p1)
: "r" (block+64), "r" (qmat+64), "r" (bias+64),
- "r" (ff_inv_zigzag_direct16+64), "r" (temp_block+64)
+ "r" (inv_zigzag_direct16 + 64), "r" (temp_block + 64)
XMM_CLOBBERS_ONLY("%xmm0", "%xmm1", "%xmm2", "%xmm3",
"%xmm4", "%xmm5", "%xmm6", "%xmm7")
);
diff --git a/libavcodec/x86/rv40dsp.asm b/libavcodec/x86/rv40dsp.asm
index e561935..792a54f 100644
--- a/libavcodec/x86/rv40dsp.asm
+++ b/libavcodec/x86/rv40dsp.asm
@@ -98,11 +98,7 @@
%endif
packuswb %1, %1
%ifidn %3, avg
-%if cpuflag(3dnow)
- pavgusb %1, %2
-%else
- pavgb %1, %2
-%endif
+ PAVGB %1, %2
%endif
movh [dstq], %1
%endmacro
diff --git a/libavcodec/x86/videodsp.asm b/libavcodec/x86/videodsp.asm
index aa865f5..1ac0257 100644
--- a/libavcodec/x86/videodsp.asm
+++ b/libavcodec/x86/videodsp.asm
@@ -100,10 +100,10 @@
; FIXME also write a ssse3 version using pshufb
movzx wd, byte [dstq+start_xq] ; w = read(1)
imul wd, 0x01010101 ; w *= 0x01010101
- movd m0, wd ; FIXME this is sse2, not sse
+ movd m0, wd
mov wq, n_wordsq ; initialize w
-%if cpuflag(sse)
- shufps m0, m0, q0000 ; splat
+%if cpuflag(sse2)
+ pshufd m0, m0, q0000 ; splat
%else ; mmx
punpckldq m0, m0 ; splat
%endif ; mmx/sse
@@ -124,7 +124,7 @@
hvar_fn
%endif
-INIT_XMM sse
+INIT_XMM sse2
hvar_fn
; macro to read/write a horizontal number of pixels (%2) to/from registers
@@ -344,25 +344,23 @@
; obviously not the same on both sides.
%macro READ_V_PIXEL 2
-%if %1 == 2
- movzx valw, byte %2
- imul valw, 0x0101
-%else
movzx vald, byte %2
imul vald, 0x01010101
%if %1 >= 8
movd m0, vald
%if mmsize == 16
- shufps m0, m0, q0000
+ pshufd m0, m0, q0000
%else
punpckldq m0, m0
-%endif
-%endif ; %1 >= 8
-%endif
+%endif ; mmsize == 16
+%endif ; %1 > 16
%endmacro ; READ_V_PIXEL
%macro WRITE_V_PIXEL 2
%assign %%off 0
+
+%if %1 >= 8
+
%rep %1/mmsize
movu [%2+%%off], m0
%assign %%off %%off+mmsize
@@ -378,27 +376,29 @@
%assign %%off %%off+8
%endif
%endif ; %1-%%off >= 8
-%endif
+%endif ; mmsize == 16
%if %1-%%off >= 4
-%if %1 > 8 %% %1-%%off > 4
+%if %1 > 8 && %1-%%off > 4
movq [%2+%1-8], m0
%assign %%off %1
-%elif %1 >= 8 && %1-%%off >= 4
- movd [%2+%%off], m0
-%assign %%off %%off+4
%else
- mov [%2+%%off], vald
+ movd [%2+%%off], m0
%assign %%off %%off+4
%endif
%endif ; %1-%%off >= 4
-%if %1-%%off >= 2
-%if %1 >= 8
- movd [%2+%1-4], m0
-%else
+%else ; %1 < 8
+
+%rep %1/4
+ mov [%2+%%off], vald
+%assign %%off %%off+4
+%endrep ; %1/4
+
+%endif ; %1 >=/< 8
+
+%if %1-%%off == 2
mov [%2+%%off], valw
-%endif
%endif ; (%1-%%off)/2
%endmacro ; WRITE_V_PIXEL
@@ -423,7 +423,7 @@
H_EXTEND 16, 22
%endif
-INIT_XMM sse
+INIT_XMM sse2
H_EXTEND 16, 22
%macro PREFETCH_FN 1
diff --git a/libavcodec/x86/videodsp_init.c b/libavcodec/x86/videodsp_init.c
index b5bab72..2013a93 100644
--- a/libavcodec/x86/videodsp_init.c
+++ b/libavcodec/x86/videodsp_init.c
@@ -117,20 +117,21 @@
};
#endif
extern emu_edge_hvar_func ff_emu_edge_hvar_mmx;
-extern emu_edge_hfix_func ff_emu_edge_hfix16_sse;
-extern emu_edge_hfix_func ff_emu_edge_hfix18_sse;
-extern emu_edge_hfix_func ff_emu_edge_hfix20_sse;
-extern emu_edge_hfix_func ff_emu_edge_hfix22_sse;
-static emu_edge_hfix_func *hfixtbl_sse[11] = {
+extern emu_edge_hfix_func ff_emu_edge_hfix16_sse2;
+extern emu_edge_hfix_func ff_emu_edge_hfix18_sse2;
+extern emu_edge_hfix_func ff_emu_edge_hfix20_sse2;
+extern emu_edge_hfix_func ff_emu_edge_hfix22_sse2;
+static emu_edge_hfix_func *hfixtbl_sse2[11] = {
ff_emu_edge_hfix2_mmx, ff_emu_edge_hfix4_mmx, ff_emu_edge_hfix6_mmx,
ff_emu_edge_hfix8_mmx, ff_emu_edge_hfix10_mmx, ff_emu_edge_hfix12_mmx,
- ff_emu_edge_hfix14_mmx, ff_emu_edge_hfix16_sse, ff_emu_edge_hfix18_sse,
- ff_emu_edge_hfix20_sse, ff_emu_edge_hfix22_sse
+ ff_emu_edge_hfix14_mmx, ff_emu_edge_hfix16_sse2, ff_emu_edge_hfix18_sse2,
+ ff_emu_edge_hfix20_sse2, ff_emu_edge_hfix22_sse2
};
-extern emu_edge_hvar_func ff_emu_edge_hvar_sse;
+extern emu_edge_hvar_func ff_emu_edge_hvar_sse2;
-static av_always_inline void emulated_edge_mc(uint8_t *dst, ptrdiff_t dst_stride,
- const uint8_t *src, ptrdiff_t src_stride,
+static av_always_inline void emulated_edge_mc(uint8_t *dst, const uint8_t *src,
+ ptrdiff_t dst_stride,
+ ptrdiff_t src_stride,
x86_reg block_w, x86_reg block_h,
x86_reg src_x, x86_reg src_y,
x86_reg w, x86_reg h,
@@ -141,7 +142,7 @@
{
x86_reg start_y, start_x, end_y, end_x, src_y_add = 0, p;
- if(!w || !h)
+ if (!w || !h)
return;
if (src_y >= h) {
@@ -203,30 +204,38 @@
}
#if ARCH_X86_32
-static av_noinline void emulated_edge_mc_mmx(uint8_t *buf, ptrdiff_t buf_stride,
- const uint8_t *src, ptrdiff_t src_stride,
+static av_noinline void emulated_edge_mc_mmx(uint8_t *buf, const uint8_t *src,
+ ptrdiff_t buf_stride,
+ ptrdiff_t src_stride,
int block_w, int block_h,
int src_x, int src_y, int w, int h)
{
- emulated_edge_mc(buf, buf_stride, src, src_stride, block_w, block_h,
+ emulated_edge_mc(buf, src, buf_stride, src_stride, block_w, block_h,
src_x, src_y, w, h, vfixtbl_mmx, &ff_emu_edge_vvar_mmx,
hfixtbl_mmx, &ff_emu_edge_hvar_mmx);
}
+
+static av_noinline void emulated_edge_mc_sse(uint8_t *buf, const uint8_t *src,
+ ptrdiff_t buf_stride,
+ ptrdiff_t src_stride,
+ int block_w, int block_h,
+ int src_x, int src_y, int w, int h)
+{
+ emulated_edge_mc(buf, src, buf_stride, src_stride, block_w, block_h,
+ src_x, src_y, w, h, vfixtbl_sse, &ff_emu_edge_vvar_sse,
+ hfixtbl_mmx, &ff_emu_edge_hvar_mmx);
+}
#endif
-static av_noinline void emulated_edge_mc_sse(uint8_t *buf, ptrdiff_t buf_stride,
- const uint8_t *src, ptrdiff_t src_stride,
- int block_w, int block_h,
- int src_x, int src_y, int w, int h)
+static av_noinline void emulated_edge_mc_sse2(uint8_t *buf, const uint8_t *src,
+ ptrdiff_t buf_stride,
+ ptrdiff_t src_stride,
+ int block_w, int block_h,
+ int src_x, int src_y, int w, int h)
{
- emulated_edge_mc(buf, buf_stride, src, src_stride, block_w, block_h, src_x,
- src_y, w, h, vfixtbl_sse, &ff_emu_edge_vvar_sse, hfixtbl_sse,
-#if ARCH_X86_64
- &ff_emu_edge_hvar_sse
-#else
- &ff_emu_edge_hvar_mmx
-#endif
- );
+ emulated_edge_mc(buf, src, buf_stride, src_stride, block_w, block_h,
+ src_x, src_y, w, h, vfixtbl_sse, &ff_emu_edge_vvar_sse,
+ hfixtbl_sse2, &ff_emu_edge_hvar_sse2);
}
#endif /* HAVE_YASM */
@@ -249,8 +258,13 @@
if (EXTERNAL_MMXEXT(cpu_flags)) {
ctx->prefetch = ff_prefetch_mmxext;
}
+#if ARCH_X86_32
if (EXTERNAL_SSE(cpu_flags) && bpc <= 8) {
ctx->emulated_edge_mc = emulated_edge_mc_sse;
}
+#endif /* ARCH_X86_32 */
+ if (EXTERNAL_SSE2(cpu_flags) && bpc <= 8) {
+ ctx->emulated_edge_mc = emulated_edge_mc_sse2;
+ }
#endif /* HAVE_YASM */
}
diff --git a/libavcodec/x86/vp8dsp.asm b/libavcodec/x86/vp8dsp.asm
index ca07333..85c7e99 100644
--- a/libavcodec/x86/vp8dsp.asm
+++ b/libavcodec/x86/vp8dsp.asm
@@ -143,27 +143,13 @@
filter_h6_shuf2: db 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9
filter_h6_shuf3: db 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11
-pw_27: times 8 dw 27
-pw_63: times 8 dw 63
pw_256: times 8 dw 256
pw_20091: times 4 dw 20091
pw_17734: times 4 dw 17734
-pb_4: times 16 db 4
-pb_F8: times 16 db 0xF8
-pb_FE: times 16 db 0xFE
-pb_27_63: times 8 db 27, 63
-pb_18_63: times 8 db 18, 63
-pb_9_63: times 8 db 9, 63
-
-cextern pb_1
cextern pw_3
-cextern pb_3
cextern pw_4
-cextern pw_9
-cextern pw_18
cextern pw_64
-cextern pb_80
SECTION .text
@@ -1237,1544 +1223,3 @@
%endif
INIT_MMX sse
VP8_DC_WHT
-
-;-----------------------------------------------------------------------------
-; void vp8_h/v_loop_filter_simple_<opt>(uint8_t *dst, int stride, int flim);
-;-----------------------------------------------------------------------------
-
-; macro called with 7 mm register indexes as argument, and 4 regular registers
-;
-; first 4 mm registers will carry the transposed pixel data
-; the other three are scratchspace (one would be sufficient, but this allows
-; for more spreading/pipelining and thus faster execution on OOE CPUs)
-;
-; first two regular registers are buf+4*stride and buf+5*stride
-; third is -stride, fourth is +stride
-%macro READ_8x4_INTERLEAVED 11
- ; interleave 8 (A-H) rows of 4 pixels each
- movd m%1, [%8+%10*4] ; A0-3
- movd m%5, [%9+%10*4] ; B0-3
- movd m%2, [%8+%10*2] ; C0-3
- movd m%6, [%8+%10] ; D0-3
- movd m%3, [%8] ; E0-3
- movd m%7, [%9] ; F0-3
- movd m%4, [%9+%11] ; G0-3
- punpcklbw m%1, m%5 ; A/B interleaved
- movd m%5, [%9+%11*2] ; H0-3
- punpcklbw m%2, m%6 ; C/D interleaved
- punpcklbw m%3, m%7 ; E/F interleaved
- punpcklbw m%4, m%5 ; G/H interleaved
-%endmacro
-
-; macro called with 7 mm register indexes as argument, and 5 regular registers
-; first 11 mean the same as READ_8x4_TRANSPOSED above
-; fifth regular register is scratchspace to reach the bottom 8 rows, it
-; will be set to second regular register + 8*stride at the end
-%macro READ_16x4_INTERLEAVED 12
- ; transpose 16 (A-P) rows of 4 pixels each
- lea %12, [r0+8*r2]
-
- ; read (and interleave) those addressable by %8 (=r0), A/C/D/E/I/K/L/M
- movd m%1, [%8+%10*4] ; A0-3
- movd m%3, [%12+%10*4] ; I0-3
- movd m%2, [%8+%10*2] ; C0-3
- movd m%4, [%12+%10*2] ; K0-3
- movd m%6, [%8+%10] ; D0-3
- movd m%5, [%12+%10] ; L0-3
- movd m%7, [%12] ; M0-3
- add %12, %11
- punpcklbw m%1, m%3 ; A/I
- movd m%3, [%8] ; E0-3
- punpcklbw m%2, m%4 ; C/K
- punpcklbw m%6, m%5 ; D/L
- punpcklbw m%3, m%7 ; E/M
- punpcklbw m%2, m%6 ; C/D/K/L interleaved
-
- ; read (and interleave) those addressable by %9 (=r4), B/F/G/H/J/N/O/P
- movd m%5, [%9+%10*4] ; B0-3
- movd m%4, [%12+%10*4] ; J0-3
- movd m%7, [%9] ; F0-3
- movd m%6, [%12] ; N0-3
- punpcklbw m%5, m%4 ; B/J
- punpcklbw m%7, m%6 ; F/N
- punpcklbw m%1, m%5 ; A/B/I/J interleaved
- punpcklbw m%3, m%7 ; E/F/M/N interleaved
- movd m%4, [%9+%11] ; G0-3
- movd m%6, [%12+%11] ; O0-3
- movd m%5, [%9+%11*2] ; H0-3
- movd m%7, [%12+%11*2] ; P0-3
- punpcklbw m%4, m%6 ; G/O
- punpcklbw m%5, m%7 ; H/P
- punpcklbw m%4, m%5 ; G/H/O/P interleaved
-%endmacro
-
-; write 4 mm registers of 2 dwords each
-; first four arguments are mm register indexes containing source data
-; last four are registers containing buf+4*stride, buf+5*stride,
-; -stride and +stride
-%macro WRITE_4x2D 8
- ; write out (2 dwords per register)
- movd [%5+%7*4], m%1
- movd [%5+%7*2], m%2
- movd [%5], m%3
- movd [%6+%8], m%4
- punpckhdq m%1, m%1
- punpckhdq m%2, m%2
- punpckhdq m%3, m%3
- punpckhdq m%4, m%4
- movd [%6+%7*4], m%1
- movd [%5+%7], m%2
- movd [%6], m%3
- movd [%6+%8*2], m%4
-%endmacro
-
-; write 4 xmm registers of 4 dwords each
-; arguments same as WRITE_2x4D, but with an extra register, so that the 5 regular
-; registers contain buf+4*stride, buf+5*stride, buf+12*stride, -stride and +stride
-; we add 1*stride to the third regular registry in the process
-; the 10th argument is 16 if it's a Y filter (i.e. all regular registers cover the
-; same memory region), or 8 if they cover two separate buffers (third one points to
-; a different memory region than the first two), allowing for more optimal code for
-; the 16-width case
-%macro WRITE_4x4D 10
- ; write out (4 dwords per register), start with dwords zero
- movd [%5+%8*4], m%1
- movd [%5], m%2
- movd [%7+%8*4], m%3
- movd [%7], m%4
-
- ; store dwords 1
- psrldq m%1, 4
- psrldq m%2, 4
- psrldq m%3, 4
- psrldq m%4, 4
- movd [%6+%8*4], m%1
- movd [%6], m%2
-%if %10 == 16
- movd [%6+%9*4], m%3
-%endif
- movd [%7+%9], m%4
-
- ; write dwords 2
- psrldq m%1, 4
- psrldq m%2, 4
-%if %10 == 8
- movd [%5+%8*2], m%1
- movd %5d, m%3
-%endif
- psrldq m%3, 4
- psrldq m%4, 4
-%if %10 == 16
- movd [%5+%8*2], m%1
-%endif
- movd [%6+%9], m%2
- movd [%7+%8*2], m%3
- movd [%7+%9*2], m%4
- add %7, %9
-
- ; store dwords 3
- psrldq m%1, 4
- psrldq m%2, 4
- psrldq m%3, 4
- psrldq m%4, 4
-%if %10 == 8
- mov [%7+%8*4], %5d
- movd [%6+%8*2], m%1
-%else
- movd [%5+%8], m%1
-%endif
- movd [%6+%9*2], m%2
- movd [%7+%8*2], m%3
- movd [%7+%9*2], m%4
-%endmacro
-
-; write 4 or 8 words in the mmx/xmm registers as 8 lines
-; 1 and 2 are the registers to write, this can be the same (for SSE2)
-; for pre-SSE4:
-; 3 is a general-purpose register that we will clobber
-; for SSE4:
-; 3 is a pointer to the destination's 5th line
-; 4 is a pointer to the destination's 4th line
-; 5/6 is -stride and +stride
-%macro WRITE_2x4W 6
- movd %3d, %1
- punpckhdq %1, %1
- mov [%4+%5*4], %3w
- shr %3, 16
- add %4, %6
- mov [%4+%5*4], %3w
-
- movd %3d, %1
- add %4, %5
- mov [%4+%5*2], %3w
- shr %3, 16
- mov [%4+%5 ], %3w
-
- movd %3d, %2
- punpckhdq %2, %2
- mov [%4 ], %3w
- shr %3, 16
- mov [%4+%6 ], %3w
-
- movd %3d, %2
- add %4, %6
- mov [%4+%6 ], %3w
- shr %3, 16
- mov [%4+%6*2], %3w
- add %4, %5
-%endmacro
-
-%macro WRITE_8W 5
-%if cpuflag(sse4)
- pextrw [%3+%4*4], %1, 0
- pextrw [%2+%4*4], %1, 1
- pextrw [%3+%4*2], %1, 2
- pextrw [%3+%4 ], %1, 3
- pextrw [%3 ], %1, 4
- pextrw [%2 ], %1, 5
- pextrw [%2+%5 ], %1, 6
- pextrw [%2+%5*2], %1, 7
-%else
- movd %2d, %1
- psrldq %1, 4
- mov [%3+%4*4], %2w
- shr %2, 16
- add %3, %5
- mov [%3+%4*4], %2w
-
- movd %2d, %1
- psrldq %1, 4
- add %3, %4
- mov [%3+%4*2], %2w
- shr %2, 16
- mov [%3+%4 ], %2w
-
- movd %2d, %1
- psrldq %1, 4
- mov [%3 ], %2w
- shr %2, 16
- mov [%3+%5 ], %2w
-
- movd %2d, %1
- add %3, %5
- mov [%3+%5 ], %2w
- shr %2, 16
- mov [%3+%5*2], %2w
-%endif
-%endmacro
-
-%macro SIMPLE_LOOPFILTER 2
-cglobal vp8_%1_loop_filter_simple, 3, %2, 8, dst, stride, flim, cntr
-%if mmsize == 8 ; mmx/mmxext
- mov cntrq, 2
-%endif
-%if cpuflag(ssse3)
- pxor m0, m0
-%endif
- SPLATB_REG m7, flim, m0 ; splat "flim" into register
-
- ; set up indexes to address 4 rows
-%if mmsize == 8
- DEFINE_ARGS dst1, mstride, stride, cntr, dst2
-%else
- DEFINE_ARGS dst1, mstride, stride, dst3, dst2
-%endif
- mov strideq, mstrideq
- neg mstrideq
-%ifidn %1, h
- lea dst1q, [dst1q+4*strideq-2]
-%endif
-
-%if mmsize == 8 ; mmx / mmxext
-.next8px:
-%endif
-%ifidn %1, v
- ; read 4 half/full rows of pixels
- mova m0, [dst1q+mstrideq*2] ; p1
- mova m1, [dst1q+mstrideq] ; p0
- mova m2, [dst1q] ; q0
- mova m3, [dst1q+ strideq] ; q1
-%else ; h
- lea dst2q, [dst1q+ strideq]
-
-%if mmsize == 8 ; mmx/mmxext
- READ_8x4_INTERLEAVED 0, 1, 2, 3, 4, 5, 6, dst1q, dst2q, mstrideq, strideq
-%else ; sse2
- READ_16x4_INTERLEAVED 0, 1, 2, 3, 4, 5, 6, dst1q, dst2q, mstrideq, strideq, dst3q
-%endif
- TRANSPOSE4x4W 0, 1, 2, 3, 4
-%endif
-
- ; simple_limit
- mova m5, m2 ; m5=backup of q0
- mova m6, m1 ; m6=backup of p0
- psubusb m1, m2 ; p0-q0
- psubusb m2, m6 ; q0-p0
- por m1, m2 ; FFABS(p0-q0)
- paddusb m1, m1 ; m1=FFABS(p0-q0)*2
-
- mova m4, m3
- mova m2, m0
- psubusb m3, m0 ; q1-p1
- psubusb m0, m4 ; p1-q1
- por m3, m0 ; FFABS(p1-q1)
- mova m0, [pb_80]
- pxor m2, m0
- pxor m4, m0
- psubsb m2, m4 ; m2=p1-q1 (signed) backup for below
- pand m3, [pb_FE]
- psrlq m3, 1 ; m3=FFABS(p1-q1)/2, this can be used signed
- paddusb m3, m1
- psubusb m3, m7
- pxor m1, m1
- pcmpeqb m3, m1 ; abs(p0-q0)*2+abs(p1-q1)/2<=flim mask(0xff/0x0)
-
- ; filter_common (use m2/p1-q1, m4=q0, m6=p0, m5/q0-p0 and m3/mask)
- mova m4, m5
- pxor m5, m0
- pxor m0, m6
- psubsb m5, m0 ; q0-p0 (signed)
- paddsb m2, m5
- paddsb m2, m5
- paddsb m2, m5 ; a=(p1-q1) + 3*(q0-p0)
- pand m2, m3 ; apply filter mask (m3)
-
- mova m3, [pb_F8]
- mova m1, m2
- paddsb m2, [pb_4] ; f1<<3=a+4
- paddsb m1, [pb_3] ; f2<<3=a+3
- pand m2, m3
- pand m1, m3 ; cache f2<<3
-
- pxor m0, m0
- pxor m3, m3
- pcmpgtb m0, m2 ; which values are <0?
- psubb m3, m2 ; -f1<<3
- psrlq m2, 3 ; +f1
- psrlq m3, 3 ; -f1
- pand m3, m0
- pandn m0, m2
- psubusb m4, m0
- paddusb m4, m3 ; q0-f1
-
- pxor m0, m0
- pxor m3, m3
- pcmpgtb m0, m1 ; which values are <0?
- psubb m3, m1 ; -f2<<3
- psrlq m1, 3 ; +f2
- psrlq m3, 3 ; -f2
- pand m3, m0
- pandn m0, m1
- paddusb m6, m0
- psubusb m6, m3 ; p0+f2
-
- ; store
-%ifidn %1, v
- mova [dst1q], m4
- mova [dst1q+mstrideq], m6
-%else ; h
- inc dst1q
- SBUTTERFLY bw, 6, 4, 0
-
-%if mmsize == 16 ; sse2
-%if cpuflag(sse4)
- inc dst2q
-%endif
- WRITE_8W m6, dst2q, dst1q, mstrideq, strideq
- lea dst2q, [dst3q+mstrideq+1]
-%if cpuflag(sse4)
- inc dst3q
-%endif
- WRITE_8W m4, dst3q, dst2q, mstrideq, strideq
-%else ; mmx/mmxext
- WRITE_2x4W m6, m4, dst2q, dst1q, mstrideq, strideq
-%endif
-%endif
-
-%if mmsize == 8 ; mmx/mmxext
- ; next 8 pixels
-%ifidn %1, v
- add dst1q, 8 ; advance 8 cols = pixels
-%else ; h
- lea dst1q, [dst1q+strideq*8-1] ; advance 8 rows = lines
-%endif
- dec cntrq
- jg .next8px
- REP_RET
-%else ; sse2
- RET
-%endif
-%endmacro
-
-%if ARCH_X86_32
-INIT_MMX mmx
-SIMPLE_LOOPFILTER v, 4
-SIMPLE_LOOPFILTER h, 5
-INIT_MMX mmxext
-SIMPLE_LOOPFILTER v, 4
-SIMPLE_LOOPFILTER h, 5
-%endif
-
-INIT_XMM sse2
-SIMPLE_LOOPFILTER v, 3
-SIMPLE_LOOPFILTER h, 5
-INIT_XMM ssse3
-SIMPLE_LOOPFILTER v, 3
-SIMPLE_LOOPFILTER h, 5
-INIT_XMM sse4
-SIMPLE_LOOPFILTER h, 5
-
-;-----------------------------------------------------------------------------
-; void vp8_h/v_loop_filter<size>_inner_<opt>(uint8_t *dst, [uint8_t *v,] int stride,
-; int flimE, int flimI, int hev_thr);
-;-----------------------------------------------------------------------------
-
-%macro INNER_LOOPFILTER 2
-%define stack_size 0
-%ifndef m8 ; stack layout: [0]=E, [1]=I, [2]=hev_thr
-%ifidn %1, v ; [3]=hev() result
-%define stack_size mmsize * -4
-%else ; h ; extra storage space for transposes
-%define stack_size mmsize * -5
-%endif
-%endif
-
-%if %2 == 8 ; chroma
-cglobal vp8_%1_loop_filter8uv_inner, 6, 6, 13, stack_size, dst, dst8, stride, flimE, flimI, hevthr
-%else ; luma
-cglobal vp8_%1_loop_filter16y_inner, 5, 5, 13, stack_size, dst, stride, flimE, flimI, hevthr
-%endif
-
-%if cpuflag(ssse3)
- pxor m7, m7
-%endif
-
-%ifndef m8
- ; splat function arguments
- SPLATB_REG m0, flimEq, m7 ; E
- SPLATB_REG m1, flimIq, m7 ; I
- SPLATB_REG m2, hevthrq, m7 ; hev_thresh
-
-%define m_flimE [rsp]
-%define m_flimI [rsp+mmsize]
-%define m_hevthr [rsp+mmsize*2]
-%define m_maskres [rsp+mmsize*3]
-%define m_p0backup [rsp+mmsize*3]
-%define m_q0backup [rsp+mmsize*4]
-
- mova m_flimE, m0
- mova m_flimI, m1
- mova m_hevthr, m2
-%else
-%define m_flimE m9
-%define m_flimI m10
-%define m_hevthr m11
-%define m_maskres m12
-%define m_p0backup m12
-%define m_q0backup m8
-
- ; splat function arguments
- SPLATB_REG m_flimE, flimEq, m7 ; E
- SPLATB_REG m_flimI, flimIq, m7 ; I
- SPLATB_REG m_hevthr, hevthrq, m7 ; hev_thresh
-%endif
-
-%if %2 == 8 ; chroma
- DEFINE_ARGS dst1, dst8, mstride, stride, dst2
-%elif mmsize == 8
- DEFINE_ARGS dst1, mstride, stride, dst2, cntr
- mov cntrq, 2
-%else
- DEFINE_ARGS dst1, mstride, stride, dst2, dst8
-%endif
- mov strideq, mstrideq
- neg mstrideq
-%ifidn %1, h
- lea dst1q, [dst1q+strideq*4-4]
-%if %2 == 8 ; chroma
- lea dst8q, [dst8q+strideq*4-4]
-%endif
-%endif
-
-%if mmsize == 8
-.next8px:
-%endif
- ; read
- lea dst2q, [dst1q+strideq]
-%ifidn %1, v
-%if %2 == 8 && mmsize == 16
-%define movrow movh
-%else
-%define movrow mova
-%endif
- movrow m0, [dst1q+mstrideq*4] ; p3
- movrow m1, [dst2q+mstrideq*4] ; p2
- movrow m2, [dst1q+mstrideq*2] ; p1
- movrow m5, [dst2q] ; q1
- movrow m6, [dst2q+ strideq*1] ; q2
- movrow m7, [dst2q+ strideq*2] ; q3
-%if mmsize == 16 && %2 == 8
- movhps m0, [dst8q+mstrideq*4]
- movhps m2, [dst8q+mstrideq*2]
- add dst8q, strideq
- movhps m1, [dst8q+mstrideq*4]
- movhps m5, [dst8q]
- movhps m6, [dst8q+ strideq ]
- movhps m7, [dst8q+ strideq*2]
- add dst8q, mstrideq
-%endif
-%elif mmsize == 8 ; mmx/mmxext (h)
- ; read 8 rows of 8px each
- movu m0, [dst1q+mstrideq*4]
- movu m1, [dst2q+mstrideq*4]
- movu m2, [dst1q+mstrideq*2]
- movu m3, [dst1q+mstrideq ]
- movu m4, [dst1q]
- movu m5, [dst2q]
- movu m6, [dst2q+ strideq ]
-
- ; 8x8 transpose
- TRANSPOSE4x4B 0, 1, 2, 3, 7
- mova m_q0backup, m1
- movu m7, [dst2q+ strideq*2]
- TRANSPOSE4x4B 4, 5, 6, 7, 1
- SBUTTERFLY dq, 0, 4, 1 ; p3/p2
- SBUTTERFLY dq, 2, 6, 1 ; q0/q1
- SBUTTERFLY dq, 3, 7, 1 ; q2/q3
- mova m1, m_q0backup
- mova m_q0backup, m2 ; store q0
- SBUTTERFLY dq, 1, 5, 2 ; p1/p0
- mova m_p0backup, m5 ; store p0
- SWAP 1, 4
- SWAP 2, 4
- SWAP 6, 3
- SWAP 5, 3
-%else ; sse2 (h)
-%if %2 == 16
- lea dst8q, [dst1q+ strideq*8]
-%endif
-
- ; read 16 rows of 8px each, interleave
- movh m0, [dst1q+mstrideq*4]
- movh m1, [dst8q+mstrideq*4]
- movh m2, [dst1q+mstrideq*2]
- movh m5, [dst8q+mstrideq*2]
- movh m3, [dst1q+mstrideq ]
- movh m6, [dst8q+mstrideq ]
- movh m4, [dst1q]
- movh m7, [dst8q]
- punpcklbw m0, m1 ; A/I
- punpcklbw m2, m5 ; C/K
- punpcklbw m3, m6 ; D/L
- punpcklbw m4, m7 ; E/M
-
- add dst8q, strideq
- movh m1, [dst2q+mstrideq*4]
- movh m6, [dst8q+mstrideq*4]
- movh m5, [dst2q]
- movh m7, [dst8q]
- punpcklbw m1, m6 ; B/J
- punpcklbw m5, m7 ; F/N
- movh m6, [dst2q+ strideq ]
- movh m7, [dst8q+ strideq ]
- punpcklbw m6, m7 ; G/O
-
- ; 8x16 transpose
- TRANSPOSE4x4B 0, 1, 2, 3, 7
-%ifdef m8
- SWAP 1, 8
-%else
- mova m_q0backup, m1
-%endif
- movh m7, [dst2q+ strideq*2]
- movh m1, [dst8q+ strideq*2]
- punpcklbw m7, m1 ; H/P
- TRANSPOSE4x4B 4, 5, 6, 7, 1
- SBUTTERFLY dq, 0, 4, 1 ; p3/p2
- SBUTTERFLY dq, 2, 6, 1 ; q0/q1
- SBUTTERFLY dq, 3, 7, 1 ; q2/q3
-%ifdef m8
- SWAP 1, 8
- SWAP 2, 8
-%else
- mova m1, m_q0backup
- mova m_q0backup, m2 ; store q0
-%endif
- SBUTTERFLY dq, 1, 5, 2 ; p1/p0
-%ifdef m12
- SWAP 5, 12
-%else
- mova m_p0backup, m5 ; store p0
-%endif
- SWAP 1, 4
- SWAP 2, 4
- SWAP 6, 3
- SWAP 5, 3
-%endif
-
- ; normal_limit for p3-p2, p2-p1, q3-q2 and q2-q1
- mova m4, m1
- SWAP 4, 1
- psubusb m4, m0 ; p2-p3
- psubusb m0, m1 ; p3-p2
- por m0, m4 ; abs(p3-p2)
-
- mova m4, m2
- SWAP 4, 2
- psubusb m4, m1 ; p1-p2
- psubusb m1, m2 ; p2-p1
- por m1, m4 ; abs(p2-p1)
-
- mova m4, m6
- SWAP 4, 6
- psubusb m4, m7 ; q2-q3
- psubusb m7, m6 ; q3-q2
- por m7, m4 ; abs(q3-q2)
-
- mova m4, m5
- SWAP 4, 5
- psubusb m4, m6 ; q1-q2
- psubusb m6, m5 ; q2-q1
- por m6, m4 ; abs(q2-q1)
-
-%if notcpuflag(mmxext)
- mova m4, m_flimI
- pxor m3, m3
- psubusb m0, m4
- psubusb m1, m4
- psubusb m7, m4
- psubusb m6, m4
- pcmpeqb m0, m3 ; abs(p3-p2) <= I
- pcmpeqb m1, m3 ; abs(p2-p1) <= I
- pcmpeqb m7, m3 ; abs(q3-q2) <= I
- pcmpeqb m6, m3 ; abs(q2-q1) <= I
- pand m0, m1
- pand m7, m6
- pand m0, m7
-%else ; mmxext/sse2
- pmaxub m0, m1
- pmaxub m6, m7
- pmaxub m0, m6
-%endif
-
- ; normal_limit and high_edge_variance for p1-p0, q1-q0
- SWAP 7, 3 ; now m7 is zero
-%ifidn %1, v
- movrow m3, [dst1q+mstrideq ] ; p0
-%if mmsize == 16 && %2 == 8
- movhps m3, [dst8q+mstrideq ]
-%endif
-%elifdef m12
- SWAP 3, 12
-%else
- mova m3, m_p0backup
-%endif
-
- mova m1, m2
- SWAP 1, 2
- mova m6, m3
- SWAP 3, 6
- psubusb m1, m3 ; p1-p0
- psubusb m6, m2 ; p0-p1
- por m1, m6 ; abs(p1-p0)
-%if notcpuflag(mmxext)
- mova m6, m1
- psubusb m1, m4
- psubusb m6, m_hevthr
- pcmpeqb m1, m7 ; abs(p1-p0) <= I
- pcmpeqb m6, m7 ; abs(p1-p0) <= hev_thresh
- pand m0, m1
- mova m_maskres, m6
-%else ; mmxext/sse2
- pmaxub m0, m1 ; max_I
- SWAP 1, 4 ; max_hev_thresh
-%endif
-
- SWAP 6, 4 ; now m6 is I
-%ifidn %1, v
- movrow m4, [dst1q] ; q0
-%if mmsize == 16 && %2 == 8
- movhps m4, [dst8q]
-%endif
-%elifdef m8
- SWAP 4, 8
-%else
- mova m4, m_q0backup
-%endif
- mova m1, m4
- SWAP 1, 4
- mova m7, m5
- SWAP 7, 5
- psubusb m1, m5 ; q0-q1
- psubusb m7, m4 ; q1-q0
- por m1, m7 ; abs(q1-q0)
-%if notcpuflag(mmxext)
- mova m7, m1
- psubusb m1, m6
- psubusb m7, m_hevthr
- pxor m6, m6
- pcmpeqb m1, m6 ; abs(q1-q0) <= I
- pcmpeqb m7, m6 ; abs(q1-q0) <= hev_thresh
- mova m6, m_maskres
- pand m0, m1 ; abs([pq][321]-[pq][210]) <= I
- pand m6, m7
-%else ; mmxext/sse2
- pxor m7, m7
- pmaxub m0, m1
- pmaxub m6, m1
- psubusb m0, m_flimI
- psubusb m6, m_hevthr
- pcmpeqb m0, m7 ; max(abs(..)) <= I
- pcmpeqb m6, m7 ; !(max(abs..) > thresh)
-%endif
-%ifdef m12
- SWAP 6, 12
-%else
- mova m_maskres, m6 ; !(abs(p1-p0) > hev_t || abs(q1-q0) > hev_t)
-%endif
-
- ; simple_limit
- mova m1, m3
- SWAP 1, 3
- mova m6, m4 ; keep copies of p0/q0 around for later use
- SWAP 6, 4
- psubusb m1, m4 ; p0-q0
- psubusb m6, m3 ; q0-p0
- por m1, m6 ; abs(q0-p0)
- paddusb m1, m1 ; m1=2*abs(q0-p0)
-
- mova m7, m2
- SWAP 7, 2
- mova m6, m5
- SWAP 6, 5
- psubusb m7, m5 ; p1-q1
- psubusb m6, m2 ; q1-p1
- por m7, m6 ; abs(q1-p1)
- pxor m6, m6
- pand m7, [pb_FE]
- psrlq m7, 1 ; abs(q1-p1)/2
- paddusb m7, m1 ; abs(q0-p0)*2+abs(q1-p1)/2
- psubusb m7, m_flimE
- pcmpeqb m7, m6 ; abs(q0-p0)*2+abs(q1-p1)/2 <= E
- pand m0, m7 ; normal_limit result
-
- ; filter_common; at this point, m2-m5=p1-q1 and m0 is filter_mask
-%ifdef m8 ; x86-64 && sse2
- mova m8, [pb_80]
-%define m_pb_80 m8
-%else ; x86-32 or mmx/mmxext
-%define m_pb_80 [pb_80]
-%endif
- mova m1, m4
- mova m7, m3
- pxor m1, m_pb_80
- pxor m7, m_pb_80
- psubsb m1, m7 ; (signed) q0-p0
- mova m6, m2
- mova m7, m5
- pxor m6, m_pb_80
- pxor m7, m_pb_80
- psubsb m6, m7 ; (signed) p1-q1
- mova m7, m_maskres
- pandn m7, m6
- paddsb m7, m1
- paddsb m7, m1
- paddsb m7, m1 ; 3*(q0-p0)+is4tap?(p1-q1)
-
- pand m7, m0
- mova m1, [pb_F8]
- mova m6, m7
- paddsb m7, [pb_3]
- paddsb m6, [pb_4]
- pand m7, m1
- pand m6, m1
-
- pxor m1, m1
- pxor m0, m0
- pcmpgtb m1, m7
- psubb m0, m7
- psrlq m7, 3 ; +f2
- psrlq m0, 3 ; -f2
- pand m0, m1
- pandn m1, m7
- psubusb m3, m0
- paddusb m3, m1 ; p0+f2
-
- pxor m1, m1
- pxor m0, m0
- pcmpgtb m0, m6
- psubb m1, m6
- psrlq m6, 3 ; +f1
- psrlq m1, 3 ; -f1
- pand m1, m0
- pandn m0, m6
- psubusb m4, m0
- paddusb m4, m1 ; q0-f1
-
-%ifdef m12
- SWAP 6, 12
-%else
- mova m6, m_maskres
-%endif
-%if notcpuflag(mmxext)
- mova m7, [pb_1]
-%else ; mmxext/sse2
- pxor m7, m7
-%endif
- pand m0, m6
- pand m1, m6
-%if notcpuflag(mmxext)
- paddusb m0, m7
- pand m1, [pb_FE]
- pandn m7, m0
- psrlq m1, 1
- psrlq m7, 1
- SWAP 0, 7
-%else ; mmxext/sse2
- psubusb m1, [pb_1]
- pavgb m0, m7 ; a
- pavgb m1, m7 ; -a
-%endif
- psubusb m5, m0
- psubusb m2, m1
- paddusb m5, m1 ; q1-a
- paddusb m2, m0 ; p1+a
-
- ; store
-%ifidn %1, v
- movrow [dst1q+mstrideq*2], m2
- movrow [dst1q+mstrideq ], m3
- movrow [dst1q], m4
- movrow [dst1q+ strideq ], m5
-%if mmsize == 16 && %2 == 8
- movhps [dst8q+mstrideq*2], m2
- movhps [dst8q+mstrideq ], m3
- movhps [dst8q], m4
- movhps [dst8q+ strideq ], m5
-%endif
-%else ; h
- add dst1q, 2
- add dst2q, 2
-
- ; 4x8/16 transpose
- TRANSPOSE4x4B 2, 3, 4, 5, 6
-
-%if mmsize == 8 ; mmx/mmxext (h)
- WRITE_4x2D 2, 3, 4, 5, dst1q, dst2q, mstrideq, strideq
-%else ; sse2 (h)
- lea dst8q, [dst8q+mstrideq +2]
- WRITE_4x4D 2, 3, 4, 5, dst1q, dst2q, dst8q, mstrideq, strideq, %2
-%endif
-%endif
-
-%if mmsize == 8
-%if %2 == 8 ; chroma
-%ifidn %1, h
- sub dst1q, 2
-%endif
- cmp dst1q, dst8q
- mov dst1q, dst8q
- jnz .next8px
-%else
-%ifidn %1, h
- lea dst1q, [dst1q+ strideq*8-2]
-%else ; v
- add dst1q, 8
-%endif
- dec cntrq
- jg .next8px
-%endif
- REP_RET
-%else ; mmsize == 16
- RET
-%endif
-%endmacro
-
-%if ARCH_X86_32
-INIT_MMX mmx
-INNER_LOOPFILTER v, 16
-INNER_LOOPFILTER h, 16
-INNER_LOOPFILTER v, 8
-INNER_LOOPFILTER h, 8
-
-INIT_MMX mmxext
-INNER_LOOPFILTER v, 16
-INNER_LOOPFILTER h, 16
-INNER_LOOPFILTER v, 8
-INNER_LOOPFILTER h, 8
-%endif
-
-INIT_XMM sse2
-INNER_LOOPFILTER v, 16
-INNER_LOOPFILTER h, 16
-INNER_LOOPFILTER v, 8
-INNER_LOOPFILTER h, 8
-
-INIT_XMM ssse3
-INNER_LOOPFILTER v, 16
-INNER_LOOPFILTER h, 16
-INNER_LOOPFILTER v, 8
-INNER_LOOPFILTER h, 8
-
-;-----------------------------------------------------------------------------
-; void vp8_h/v_loop_filter<size>_mbedge_<opt>(uint8_t *dst, [uint8_t *v,] int stride,
-; int flimE, int flimI, int hev_thr);
-;-----------------------------------------------------------------------------
-
-%macro MBEDGE_LOOPFILTER 2
-%define stack_size 0
-%ifndef m8 ; stack layout: [0]=E, [1]=I, [2]=hev_thr
-%if mmsize == 16 ; [3]=hev() result
- ; [4]=filter tmp result
- ; [5]/[6] = p2/q2 backup
- ; [7]=lim_res sign result
-%define stack_size mmsize * -7
-%else ; 8 ; extra storage space for transposes
-%define stack_size mmsize * -8
-%endif
-%endif
-
-%if %2 == 8 ; chroma
-cglobal vp8_%1_loop_filter8uv_mbedge, 6, 6, 15, stack_size, dst1, dst8, stride, flimE, flimI, hevthr
-%else ; luma
-cglobal vp8_%1_loop_filter16y_mbedge, 5, 5, 15, stack_size, dst1, stride, flimE, flimI, hevthr
-%endif
-
-%if cpuflag(ssse3)
- pxor m7, m7
-%endif
-
-%ifndef m8
- ; splat function arguments
- SPLATB_REG m0, flimEq, m7 ; E
- SPLATB_REG m1, flimIq, m7 ; I
- SPLATB_REG m2, hevthrq, m7 ; hev_thresh
-
-%define m_flimE [rsp]
-%define m_flimI [rsp+mmsize]
-%define m_hevthr [rsp+mmsize*2]
-%define m_maskres [rsp+mmsize*3]
-%define m_limres [rsp+mmsize*4]
-%define m_p0backup [rsp+mmsize*3]
-%define m_q0backup [rsp+mmsize*4]
-%define m_p2backup [rsp+mmsize*5]
-%define m_q2backup [rsp+mmsize*6]
-%if mmsize == 16
-%define m_limsign [rsp]
-%else
-%define m_limsign [rsp+mmsize*7]
-%endif
-
- mova m_flimE, m0
- mova m_flimI, m1
- mova m_hevthr, m2
-%else ; sse2 on x86-64
-%define m_flimE m9
-%define m_flimI m10
-%define m_hevthr m11
-%define m_maskres m12
-%define m_limres m8
-%define m_p0backup m12
-%define m_q0backup m8
-%define m_p2backup m13
-%define m_q2backup m14
-%define m_limsign m9
-
- ; splat function arguments
- SPLATB_REG m_flimE, flimEq, m7 ; E
- SPLATB_REG m_flimI, flimIq, m7 ; I
- SPLATB_REG m_hevthr, hevthrq, m7 ; hev_thresh
-%endif
-
-%if %2 == 8 ; chroma
- DEFINE_ARGS dst1, dst8, mstride, stride, dst2
-%elif mmsize == 8
- DEFINE_ARGS dst1, mstride, stride, dst2, cntr
- mov cntrq, 2
-%else
- DEFINE_ARGS dst1, mstride, stride, dst2, dst8
-%endif
- mov strideq, mstrideq
- neg mstrideq
-%ifidn %1, h
- lea dst1q, [dst1q+strideq*4-4]
-%if %2 == 8 ; chroma
- lea dst8q, [dst8q+strideq*4-4]
-%endif
-%endif
-
-%if mmsize == 8
-.next8px:
-%endif
- ; read
- lea dst2q, [dst1q+ strideq ]
-%ifidn %1, v
-%if %2 == 8 && mmsize == 16
-%define movrow movh
-%else
-%define movrow mova
-%endif
- movrow m0, [dst1q+mstrideq*4] ; p3
- movrow m1, [dst2q+mstrideq*4] ; p2
- movrow m2, [dst1q+mstrideq*2] ; p1
- movrow m5, [dst2q] ; q1
- movrow m6, [dst2q+ strideq ] ; q2
- movrow m7, [dst2q+ strideq*2] ; q3
-%if mmsize == 16 && %2 == 8
- movhps m0, [dst8q+mstrideq*4]
- movhps m2, [dst8q+mstrideq*2]
- add dst8q, strideq
- movhps m1, [dst8q+mstrideq*4]
- movhps m5, [dst8q]
- movhps m6, [dst8q+ strideq ]
- movhps m7, [dst8q+ strideq*2]
- add dst8q, mstrideq
-%endif
-%elif mmsize == 8 ; mmx/mmxext (h)
- ; read 8 rows of 8px each
- movu m0, [dst1q+mstrideq*4]
- movu m1, [dst2q+mstrideq*4]
- movu m2, [dst1q+mstrideq*2]
- movu m3, [dst1q+mstrideq ]
- movu m4, [dst1q]
- movu m5, [dst2q]
- movu m6, [dst2q+ strideq ]
-
- ; 8x8 transpose
- TRANSPOSE4x4B 0, 1, 2, 3, 7
- mova m_q0backup, m1
- movu m7, [dst2q+ strideq*2]
- TRANSPOSE4x4B 4, 5, 6, 7, 1
- SBUTTERFLY dq, 0, 4, 1 ; p3/p2
- SBUTTERFLY dq, 2, 6, 1 ; q0/q1
- SBUTTERFLY dq, 3, 7, 1 ; q2/q3
- mova m1, m_q0backup
- mova m_q0backup, m2 ; store q0
- SBUTTERFLY dq, 1, 5, 2 ; p1/p0
- mova m_p0backup, m5 ; store p0
- SWAP 1, 4
- SWAP 2, 4
- SWAP 6, 3
- SWAP 5, 3
-%else ; sse2 (h)
-%if %2 == 16
- lea dst8q, [dst1q+ strideq*8 ]
-%endif
-
- ; read 16 rows of 8px each, interleave
- movh m0, [dst1q+mstrideq*4]
- movh m1, [dst8q+mstrideq*4]
- movh m2, [dst1q+mstrideq*2]
- movh m5, [dst8q+mstrideq*2]
- movh m3, [dst1q+mstrideq ]
- movh m6, [dst8q+mstrideq ]
- movh m4, [dst1q]
- movh m7, [dst8q]
- punpcklbw m0, m1 ; A/I
- punpcklbw m2, m5 ; C/K
- punpcklbw m3, m6 ; D/L
- punpcklbw m4, m7 ; E/M
-
- add dst8q, strideq
- movh m1, [dst2q+mstrideq*4]
- movh m6, [dst8q+mstrideq*4]
- movh m5, [dst2q]
- movh m7, [dst8q]
- punpcklbw m1, m6 ; B/J
- punpcklbw m5, m7 ; F/N
- movh m6, [dst2q+ strideq ]
- movh m7, [dst8q+ strideq ]
- punpcklbw m6, m7 ; G/O
-
- ; 8x16 transpose
- TRANSPOSE4x4B 0, 1, 2, 3, 7
-%ifdef m8
- SWAP 1, 8
-%else
- mova m_q0backup, m1
-%endif
- movh m7, [dst2q+ strideq*2]
- movh m1, [dst8q+ strideq*2]
- punpcklbw m7, m1 ; H/P
- TRANSPOSE4x4B 4, 5, 6, 7, 1
- SBUTTERFLY dq, 0, 4, 1 ; p3/p2
- SBUTTERFLY dq, 2, 6, 1 ; q0/q1
- SBUTTERFLY dq, 3, 7, 1 ; q2/q3
-%ifdef m8
- SWAP 1, 8
- SWAP 2, 8
-%else
- mova m1, m_q0backup
- mova m_q0backup, m2 ; store q0
-%endif
- SBUTTERFLY dq, 1, 5, 2 ; p1/p0
-%ifdef m12
- SWAP 5, 12
-%else
- mova m_p0backup, m5 ; store p0
-%endif
- SWAP 1, 4
- SWAP 2, 4
- SWAP 6, 3
- SWAP 5, 3
-%endif
-
- ; normal_limit for p3-p2, p2-p1, q3-q2 and q2-q1
- mova m4, m1
- SWAP 4, 1
- psubusb m4, m0 ; p2-p3
- psubusb m0, m1 ; p3-p2
- por m0, m4 ; abs(p3-p2)
-
- mova m4, m2
- SWAP 4, 2
- psubusb m4, m1 ; p1-p2
- mova m_p2backup, m1
- psubusb m1, m2 ; p2-p1
- por m1, m4 ; abs(p2-p1)
-
- mova m4, m6
- SWAP 4, 6
- psubusb m4, m7 ; q2-q3
- psubusb m7, m6 ; q3-q2
- por m7, m4 ; abs(q3-q2)
-
- mova m4, m5
- SWAP 4, 5
- psubusb m4, m6 ; q1-q2
- mova m_q2backup, m6
- psubusb m6, m5 ; q2-q1
- por m6, m4 ; abs(q2-q1)
-
-%if notcpuflag(mmxext)
- mova m4, m_flimI
- pxor m3, m3
- psubusb m0, m4
- psubusb m1, m4
- psubusb m7, m4
- psubusb m6, m4
- pcmpeqb m0, m3 ; abs(p3-p2) <= I
- pcmpeqb m1, m3 ; abs(p2-p1) <= I
- pcmpeqb m7, m3 ; abs(q3-q2) <= I
- pcmpeqb m6, m3 ; abs(q2-q1) <= I
- pand m0, m1
- pand m7, m6
- pand m0, m7
-%else ; mmxext/sse2
- pmaxub m0, m1
- pmaxub m6, m7
- pmaxub m0, m6
-%endif
-
- ; normal_limit and high_edge_variance for p1-p0, q1-q0
- SWAP 7, 3 ; now m7 is zero
-%ifidn %1, v
- movrow m3, [dst1q+mstrideq ] ; p0
-%if mmsize == 16 && %2 == 8
- movhps m3, [dst8q+mstrideq ]
-%endif
-%elifdef m12
- SWAP 3, 12
-%else
- mova m3, m_p0backup
-%endif
-
- mova m1, m2
- SWAP 1, 2
- mova m6, m3
- SWAP 3, 6
- psubusb m1, m3 ; p1-p0
- psubusb m6, m2 ; p0-p1
- por m1, m6 ; abs(p1-p0)
-%if notcpuflag(mmxext)
- mova m6, m1
- psubusb m1, m4
- psubusb m6, m_hevthr
- pcmpeqb m1, m7 ; abs(p1-p0) <= I
- pcmpeqb m6, m7 ; abs(p1-p0) <= hev_thresh
- pand m0, m1
- mova m_maskres, m6
-%else ; mmxext/sse2
- pmaxub m0, m1 ; max_I
- SWAP 1, 4 ; max_hev_thresh
-%endif
-
- SWAP 6, 4 ; now m6 is I
-%ifidn %1, v
- movrow m4, [dst1q] ; q0
-%if mmsize == 16 && %2 == 8
- movhps m4, [dst8q]
-%endif
-%elifdef m8
- SWAP 4, 8
-%else
- mova m4, m_q0backup
-%endif
- mova m1, m4
- SWAP 1, 4
- mova m7, m5
- SWAP 7, 5
- psubusb m1, m5 ; q0-q1
- psubusb m7, m4 ; q1-q0
- por m1, m7 ; abs(q1-q0)
-%if notcpuflag(mmxext)
- mova m7, m1
- psubusb m1, m6
- psubusb m7, m_hevthr
- pxor m6, m6
- pcmpeqb m1, m6 ; abs(q1-q0) <= I
- pcmpeqb m7, m6 ; abs(q1-q0) <= hev_thresh
- mova m6, m_maskres
- pand m0, m1 ; abs([pq][321]-[pq][210]) <= I
- pand m6, m7
-%else ; mmxext/sse2
- pxor m7, m7
- pmaxub m0, m1
- pmaxub m6, m1
- psubusb m0, m_flimI
- psubusb m6, m_hevthr
- pcmpeqb m0, m7 ; max(abs(..)) <= I
- pcmpeqb m6, m7 ; !(max(abs..) > thresh)
-%endif
-%ifdef m12
- SWAP 6, 12
-%else
- mova m_maskres, m6 ; !(abs(p1-p0) > hev_t || abs(q1-q0) > hev_t)
-%endif
-
- ; simple_limit
- mova m1, m3
- SWAP 1, 3
- mova m6, m4 ; keep copies of p0/q0 around for later use
- SWAP 6, 4
- psubusb m1, m4 ; p0-q0
- psubusb m6, m3 ; q0-p0
- por m1, m6 ; abs(q0-p0)
- paddusb m1, m1 ; m1=2*abs(q0-p0)
-
- mova m7, m2
- SWAP 7, 2
- mova m6, m5
- SWAP 6, 5
- psubusb m7, m5 ; p1-q1
- psubusb m6, m2 ; q1-p1
- por m7, m6 ; abs(q1-p1)
- pxor m6, m6
- pand m7, [pb_FE]
- psrlq m7, 1 ; abs(q1-p1)/2
- paddusb m7, m1 ; abs(q0-p0)*2+abs(q1-p1)/2
- psubusb m7, m_flimE
- pcmpeqb m7, m6 ; abs(q0-p0)*2+abs(q1-p1)/2 <= E
- pand m0, m7 ; normal_limit result
-
- ; filter_common; at this point, m2-m5=p1-q1 and m0 is filter_mask
-%ifdef m8 ; x86-64 && sse2
- mova m8, [pb_80]
-%define m_pb_80 m8
-%else ; x86-32 or mmx/mmxext
-%define m_pb_80 [pb_80]
-%endif
- mova m1, m4
- mova m7, m3
- pxor m1, m_pb_80
- pxor m7, m_pb_80
- psubsb m1, m7 ; (signed) q0-p0
- mova m6, m2
- mova m7, m5
- pxor m6, m_pb_80
- pxor m7, m_pb_80
- psubsb m6, m7 ; (signed) p1-q1
- mova m7, m_maskres
- paddsb m6, m1
- paddsb m6, m1
- paddsb m6, m1
- pand m6, m0
-%ifdef m8
- mova m_limres, m6 ; 3*(qp-p0)+(p1-q1) masked for filter_mbedge
- pand m_limres, m7
-%else
- mova m0, m6
- pand m0, m7
- mova m_limres, m0
-%endif
- pandn m7, m6 ; 3*(q0-p0)+(p1-q1) masked for filter_common
-
- mova m1, [pb_F8]
- mova m6, m7
- paddsb m7, [pb_3]
- paddsb m6, [pb_4]
- pand m7, m1
- pand m6, m1
-
- pxor m1, m1
- pxor m0, m0
- pcmpgtb m1, m7
- psubb m0, m7
- psrlq m7, 3 ; +f2
- psrlq m0, 3 ; -f2
- pand m0, m1
- pandn m1, m7
- psubusb m3, m0
- paddusb m3, m1 ; p0+f2
-
- pxor m1, m1
- pxor m0, m0
- pcmpgtb m0, m6
- psubb m1, m6
- psrlq m6, 3 ; +f1
- psrlq m1, 3 ; -f1
- pand m1, m0
- pandn m0, m6
- psubusb m4, m0
- paddusb m4, m1 ; q0-f1
-
- ; filter_mbedge (m2-m5 = p1-q1; lim_res carries w)
-%if cpuflag(ssse3)
- mova m7, [pb_1]
-%else
- mova m7, [pw_63]
-%endif
-%ifdef m8
- SWAP 1, 8
-%else
- mova m1, m_limres
-%endif
- pxor m0, m0
- mova m6, m1
- pcmpgtb m0, m1 ; which are negative
-%if cpuflag(ssse3)
- punpcklbw m6, m7 ; interleave with "1" for rounding
- punpckhbw m1, m7
-%else
- punpcklbw m6, m0 ; signed byte->word
- punpckhbw m1, m0
-%endif
- mova m_limsign, m0
-%if cpuflag(ssse3)
- mova m7, [pb_27_63]
-%ifndef m8
- mova m_limres, m1
-%endif
-%ifdef m10
- SWAP 0, 10 ; don't lose lim_sign copy
-%endif
- mova m0, m7
- pmaddubsw m7, m6
- SWAP 6, 7
- pmaddubsw m0, m1
- SWAP 1, 0
-%ifdef m10
- SWAP 0, 10
-%else
- mova m0, m_limsign
-%endif
-%else
- mova m_maskres, m6 ; backup for later in filter
- mova m_limres, m1
- pmullw m6, [pw_27]
- pmullw m1, [pw_27]
- paddw m6, m7
- paddw m1, m7
-%endif
- psraw m6, 7
- psraw m1, 7
- packsswb m6, m1 ; a0
- pxor m1, m1
- psubb m1, m6
- pand m1, m0 ; -a0
- pandn m0, m6 ; +a0
-%if cpuflag(ssse3)
- mova m6, [pb_18_63] ; pipelining
-%endif
- psubusb m3, m1
- paddusb m4, m1
- paddusb m3, m0 ; p0+a0
- psubusb m4, m0 ; q0-a0
-
-%if cpuflag(ssse3)
- SWAP 6, 7
-%ifdef m10
- SWAP 1, 10
-%else
- mova m1, m_limres
-%endif
- mova m0, m7
- pmaddubsw m7, m6
- SWAP 6, 7
- pmaddubsw m0, m1
- SWAP 1, 0
-%ifdef m10
- SWAP 0, 10
-%endif
- mova m0, m_limsign
-%else
- mova m6, m_maskres
- mova m1, m_limres
- pmullw m6, [pw_18]
- pmullw m1, [pw_18]
- paddw m6, m7
- paddw m1, m7
-%endif
- mova m0, m_limsign
- psraw m6, 7
- psraw m1, 7
- packsswb m6, m1 ; a1
- pxor m1, m1
- psubb m1, m6
- pand m1, m0 ; -a1
- pandn m0, m6 ; +a1
-%if cpuflag(ssse3)
- mova m6, [pb_9_63]
-%endif
- psubusb m2, m1
- paddusb m5, m1
- paddusb m2, m0 ; p1+a1
- psubusb m5, m0 ; q1-a1
-
-%if cpuflag(ssse3)
- SWAP 6, 7
-%ifdef m10
- SWAP 1, 10
-%else
- mova m1, m_limres
-%endif
- mova m0, m7
- pmaddubsw m7, m6
- SWAP 6, 7
- pmaddubsw m0, m1
- SWAP 1, 0
-%else
-%ifdef m8
- SWAP 6, 12
- SWAP 1, 8
-%else
- mova m6, m_maskres
- mova m1, m_limres
-%endif
- pmullw m6, [pw_9]
- pmullw m1, [pw_9]
- paddw m6, m7
- paddw m1, m7
-%endif
-%ifdef m9
- SWAP 7, 9
-%else
- mova m7, m_limsign
-%endif
- psraw m6, 7
- psraw m1, 7
- packsswb m6, m1 ; a1
- pxor m0, m0
- psubb m0, m6
- pand m0, m7 ; -a1
- pandn m7, m6 ; +a1
-%ifdef m8
- SWAP 1, 13
- SWAP 6, 14
-%else
- mova m1, m_p2backup
- mova m6, m_q2backup
-%endif
- psubusb m1, m0
- paddusb m6, m0
- paddusb m1, m7 ; p1+a1
- psubusb m6, m7 ; q1-a1
-
- ; store
-%ifidn %1, v
- movrow [dst2q+mstrideq*4], m1
- movrow [dst1q+mstrideq*2], m2
- movrow [dst1q+mstrideq ], m3
- movrow [dst1q], m4
- movrow [dst2q], m5
- movrow [dst2q+ strideq ], m6
-%if mmsize == 16 && %2 == 8
- add dst8q, mstrideq
- movhps [dst8q+mstrideq*2], m1
- movhps [dst8q+mstrideq ], m2
- movhps [dst8q], m3
- add dst8q, strideq
- movhps [dst8q], m4
- movhps [dst8q+ strideq ], m5
- movhps [dst8q+ strideq*2], m6
-%endif
-%else ; h
- inc dst1q
- inc dst2q
-
- ; 4x8/16 transpose
- TRANSPOSE4x4B 1, 2, 3, 4, 0
- SBUTTERFLY bw, 5, 6, 0
-
-%if mmsize == 8 ; mmx/mmxext (h)
- WRITE_4x2D 1, 2, 3, 4, dst1q, dst2q, mstrideq, strideq
- add dst1q, 4
- WRITE_2x4W m5, m6, dst2q, dst1q, mstrideq, strideq
-%else ; sse2 (h)
- lea dst8q, [dst8q+mstrideq+1]
- WRITE_4x4D 1, 2, 3, 4, dst1q, dst2q, dst8q, mstrideq, strideq, %2
- lea dst1q, [dst2q+mstrideq+4]
- lea dst8q, [dst8q+mstrideq+4]
-%if cpuflag(sse4)
- add dst2q, 4
-%endif
- WRITE_8W m5, dst2q, dst1q, mstrideq, strideq
-%if cpuflag(sse4)
- lea dst2q, [dst8q+ strideq ]
-%endif
- WRITE_8W m6, dst2q, dst8q, mstrideq, strideq
-%endif
-%endif
-
-%if mmsize == 8
-%if %2 == 8 ; chroma
-%ifidn %1, h
- sub dst1q, 5
-%endif
- cmp dst1q, dst8q
- mov dst1q, dst8q
- jnz .next8px
-%else
-%ifidn %1, h
- lea dst1q, [dst1q+ strideq*8-5]
-%else ; v
- add dst1q, 8
-%endif
- dec cntrq
- jg .next8px
-%endif
- REP_RET
-%else ; mmsize == 16
- RET
-%endif
-%endmacro
-
-%if ARCH_X86_32
-INIT_MMX mmx
-MBEDGE_LOOPFILTER v, 16
-MBEDGE_LOOPFILTER h, 16
-MBEDGE_LOOPFILTER v, 8
-MBEDGE_LOOPFILTER h, 8
-
-INIT_MMX mmxext
-MBEDGE_LOOPFILTER v, 16
-MBEDGE_LOOPFILTER h, 16
-MBEDGE_LOOPFILTER v, 8
-MBEDGE_LOOPFILTER h, 8
-%endif
-
-INIT_XMM sse2
-MBEDGE_LOOPFILTER v, 16
-MBEDGE_LOOPFILTER h, 16
-MBEDGE_LOOPFILTER v, 8
-MBEDGE_LOOPFILTER h, 8
-
-INIT_XMM ssse3
-MBEDGE_LOOPFILTER v, 16
-MBEDGE_LOOPFILTER h, 16
-MBEDGE_LOOPFILTER v, 8
-MBEDGE_LOOPFILTER h, 8
-
-INIT_XMM sse4
-MBEDGE_LOOPFILTER h, 16
-MBEDGE_LOOPFILTER h, 8
diff --git a/libavcodec/x86/vp8dsp_loopfilter.asm b/libavcodec/x86/vp8dsp_loopfilter.asm
new file mode 100644
index 0000000..45dd54b
--- /dev/null
+++ b/libavcodec/x86/vp8dsp_loopfilter.asm
@@ -0,0 +1,1584 @@
+;******************************************************************************
+;* VP8 MMXEXT optimizations
+;* Copyright (c) 2010 Ronald S. Bultje <rsbultje@gmail.com>
+;* Copyright (c) 2010 Jason Garrett-Glaser <darkshikari@gmail.com>
+;*
+;* This file is part of FFmpeg.
+;*
+;* FFmpeg is free software; you can redistribute it and/or
+;* modify it under the terms of the GNU Lesser General Public
+;* License as published by the Free Software Foundation; either
+;* version 2.1 of the License, or (at your option) any later version.
+;*
+;* FFmpeg is distributed in the hope that it will be useful,
+;* but WITHOUT ANY WARRANTY; without even the implied warranty of
+;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+;* Lesser General Public License for more details.
+;*
+;* You should have received a copy of the GNU Lesser General Public
+;* License along with FFmpeg; if not, write to the Free Software
+;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+;******************************************************************************
+
+%include "libavutil/x86/x86util.asm"
+
+SECTION_RODATA
+
+pw_27: times 8 dw 27
+pw_63: times 8 dw 63
+
+pb_4: times 16 db 4
+pb_F8: times 16 db 0xF8
+pb_FE: times 16 db 0xFE
+pb_27_63: times 8 db 27, 63
+pb_18_63: times 8 db 18, 63
+pb_9_63: times 8 db 9, 63
+
+cextern pb_1
+cextern pb_3
+cextern pw_9
+cextern pw_18
+cextern pb_80
+
+SECTION .text
+
+;-----------------------------------------------------------------------------
+; void vp8_h/v_loop_filter_simple_<opt>(uint8_t *dst, int stride, int flim);
+;-----------------------------------------------------------------------------
+
+; macro called with 7 mm register indexes as argument, and 4 regular registers
+;
+; first 4 mm registers will carry the transposed pixel data
+; the other three are scratchspace (one would be sufficient, but this allows
+; for more spreading/pipelining and thus faster execution on OOE CPUs)
+;
+; first two regular registers are buf+4*stride and buf+5*stride
+; third is -stride, fourth is +stride
+%macro READ_8x4_INTERLEAVED 11
+ ; interleave 8 (A-H) rows of 4 pixels each
+ movd m%1, [%8+%10*4] ; A0-3
+ movd m%5, [%9+%10*4] ; B0-3
+ movd m%2, [%8+%10*2] ; C0-3
+ movd m%6, [%8+%10] ; D0-3
+ movd m%3, [%8] ; E0-3
+ movd m%7, [%9] ; F0-3
+ movd m%4, [%9+%11] ; G0-3
+ punpcklbw m%1, m%5 ; A/B interleaved
+ movd m%5, [%9+%11*2] ; H0-3
+ punpcklbw m%2, m%6 ; C/D interleaved
+ punpcklbw m%3, m%7 ; E/F interleaved
+ punpcklbw m%4, m%5 ; G/H interleaved
+%endmacro
+
+; macro called with 7 mm register indexes as argument, and 5 regular registers
+; first 11 mean the same as READ_8x4_TRANSPOSED above
+; fifth regular register is scratchspace to reach the bottom 8 rows, it
+; will be set to second regular register + 8*stride at the end
+%macro READ_16x4_INTERLEAVED 12
+ ; transpose 16 (A-P) rows of 4 pixels each
+ lea %12, [r0+8*r2]
+
+ ; read (and interleave) those addressable by %8 (=r0), A/C/D/E/I/K/L/M
+ movd m%1, [%8+%10*4] ; A0-3
+ movd m%3, [%12+%10*4] ; I0-3
+ movd m%2, [%8+%10*2] ; C0-3
+ movd m%4, [%12+%10*2] ; K0-3
+ movd m%6, [%8+%10] ; D0-3
+ movd m%5, [%12+%10] ; L0-3
+ movd m%7, [%12] ; M0-3
+ add %12, %11
+ punpcklbw m%1, m%3 ; A/I
+ movd m%3, [%8] ; E0-3
+ punpcklbw m%2, m%4 ; C/K
+ punpcklbw m%6, m%5 ; D/L
+ punpcklbw m%3, m%7 ; E/M
+ punpcklbw m%2, m%6 ; C/D/K/L interleaved
+
+ ; read (and interleave) those addressable by %9 (=r4), B/F/G/H/J/N/O/P
+ movd m%5, [%9+%10*4] ; B0-3
+ movd m%4, [%12+%10*4] ; J0-3
+ movd m%7, [%9] ; F0-3
+ movd m%6, [%12] ; N0-3
+ punpcklbw m%5, m%4 ; B/J
+ punpcklbw m%7, m%6 ; F/N
+ punpcklbw m%1, m%5 ; A/B/I/J interleaved
+ punpcklbw m%3, m%7 ; E/F/M/N interleaved
+ movd m%4, [%9+%11] ; G0-3
+ movd m%6, [%12+%11] ; O0-3
+ movd m%5, [%9+%11*2] ; H0-3
+ movd m%7, [%12+%11*2] ; P0-3
+ punpcklbw m%4, m%6 ; G/O
+ punpcklbw m%5, m%7 ; H/P
+ punpcklbw m%4, m%5 ; G/H/O/P interleaved
+%endmacro
+
+; write 4 mm registers of 2 dwords each
+; first four arguments are mm register indexes containing source data
+; last four are registers containing buf+4*stride, buf+5*stride,
+; -stride and +stride
+%macro WRITE_4x2D 8
+ ; write out (2 dwords per register)
+ movd [%5+%7*4], m%1
+ movd [%5+%7*2], m%2
+ movd [%5], m%3
+ movd [%6+%8], m%4
+ punpckhdq m%1, m%1
+ punpckhdq m%2, m%2
+ punpckhdq m%3, m%3
+ punpckhdq m%4, m%4
+ movd [%6+%7*4], m%1
+ movd [%5+%7], m%2
+ movd [%6], m%3
+ movd [%6+%8*2], m%4
+%endmacro
+
+; write 4 xmm registers of 4 dwords each
+; arguments same as WRITE_2x4D, but with an extra register, so that the 5 regular
+; registers contain buf+4*stride, buf+5*stride, buf+12*stride, -stride and +stride
+; we add 1*stride to the third regular registry in the process
+; the 10th argument is 16 if it's a Y filter (i.e. all regular registers cover the
+; same memory region), or 8 if they cover two separate buffers (third one points to
+; a different memory region than the first two), allowing for more optimal code for
+; the 16-width case
+%macro WRITE_4x4D 10
+ ; write out (4 dwords per register), start with dwords zero
+ movd [%5+%8*4], m%1
+ movd [%5], m%2
+ movd [%7+%8*4], m%3
+ movd [%7], m%4
+
+ ; store dwords 1
+ psrldq m%1, 4
+ psrldq m%2, 4
+ psrldq m%3, 4
+ psrldq m%4, 4
+ movd [%6+%8*4], m%1
+ movd [%6], m%2
+%if %10 == 16
+ movd [%6+%9*4], m%3
+%endif
+ movd [%7+%9], m%4
+
+ ; write dwords 2
+ psrldq m%1, 4
+ psrldq m%2, 4
+%if %10 == 8
+ movd [%5+%8*2], m%1
+ movd %5d, m%3
+%endif
+ psrldq m%3, 4
+ psrldq m%4, 4
+%if %10 == 16
+ movd [%5+%8*2], m%1
+%endif
+ movd [%6+%9], m%2
+ movd [%7+%8*2], m%3
+ movd [%7+%9*2], m%4
+ add %7, %9
+
+ ; store dwords 3
+ psrldq m%1, 4
+ psrldq m%2, 4
+ psrldq m%3, 4
+ psrldq m%4, 4
+%if %10 == 8
+ mov [%7+%8*4], %5d
+ movd [%6+%8*2], m%1
+%else
+ movd [%5+%8], m%1
+%endif
+ movd [%6+%9*2], m%2
+ movd [%7+%8*2], m%3
+ movd [%7+%9*2], m%4
+%endmacro
+
+; write 4 or 8 words in the mmx/xmm registers as 8 lines
+; 1 and 2 are the registers to write, this can be the same (for SSE2)
+; for pre-SSE4:
+; 3 is a general-purpose register that we will clobber
+; for SSE4:
+; 3 is a pointer to the destination's 5th line
+; 4 is a pointer to the destination's 4th line
+; 5/6 is -stride and +stride
+%macro WRITE_2x4W 6
+ movd %3d, %1
+ punpckhdq %1, %1
+ mov [%4+%5*4], %3w
+ shr %3, 16
+ add %4, %6
+ mov [%4+%5*4], %3w
+
+ movd %3d, %1
+ add %4, %5
+ mov [%4+%5*2], %3w
+ shr %3, 16
+ mov [%4+%5 ], %3w
+
+ movd %3d, %2
+ punpckhdq %2, %2
+ mov [%4 ], %3w
+ shr %3, 16
+ mov [%4+%6 ], %3w
+
+ movd %3d, %2
+ add %4, %6
+ mov [%4+%6 ], %3w
+ shr %3, 16
+ mov [%4+%6*2], %3w
+ add %4, %5
+%endmacro
+
+%macro WRITE_8W 5
+%if cpuflag(sse4)
+ pextrw [%3+%4*4], %1, 0
+ pextrw [%2+%4*4], %1, 1
+ pextrw [%3+%4*2], %1, 2
+ pextrw [%3+%4 ], %1, 3
+ pextrw [%3 ], %1, 4
+ pextrw [%2 ], %1, 5
+ pextrw [%2+%5 ], %1, 6
+ pextrw [%2+%5*2], %1, 7
+%else
+ movd %2d, %1
+ psrldq %1, 4
+ mov [%3+%4*4], %2w
+ shr %2, 16
+ add %3, %5
+ mov [%3+%4*4], %2w
+
+ movd %2d, %1
+ psrldq %1, 4
+ add %3, %4
+ mov [%3+%4*2], %2w
+ shr %2, 16
+ mov [%3+%4 ], %2w
+
+ movd %2d, %1
+ psrldq %1, 4
+ mov [%3 ], %2w
+ shr %2, 16
+ mov [%3+%5 ], %2w
+
+ movd %2d, %1
+ add %3, %5
+ mov [%3+%5 ], %2w
+ shr %2, 16
+ mov [%3+%5*2], %2w
+%endif
+%endmacro
+
+%macro SIMPLE_LOOPFILTER 2
+cglobal vp8_%1_loop_filter_simple, 3, %2, 8, dst, stride, flim, cntr
+%if mmsize == 8 ; mmx/mmxext
+ mov cntrq, 2
+%endif
+%if cpuflag(ssse3)
+ pxor m0, m0
+%endif
+ SPLATB_REG m7, flim, m0 ; splat "flim" into register
+
+ ; set up indexes to address 4 rows
+%if mmsize == 8
+ DEFINE_ARGS dst1, mstride, stride, cntr, dst2
+%else
+ DEFINE_ARGS dst1, mstride, stride, dst3, dst2
+%endif
+ mov strideq, mstrideq
+ neg mstrideq
+%ifidn %1, h
+ lea dst1q, [dst1q+4*strideq-2]
+%endif
+
+%if mmsize == 8 ; mmx / mmxext
+.next8px:
+%endif
+%ifidn %1, v
+ ; read 4 half/full rows of pixels
+ mova m0, [dst1q+mstrideq*2] ; p1
+ mova m1, [dst1q+mstrideq] ; p0
+ mova m2, [dst1q] ; q0
+ mova m3, [dst1q+ strideq] ; q1
+%else ; h
+ lea dst2q, [dst1q+ strideq]
+
+%if mmsize == 8 ; mmx/mmxext
+ READ_8x4_INTERLEAVED 0, 1, 2, 3, 4, 5, 6, dst1q, dst2q, mstrideq, strideq
+%else ; sse2
+ READ_16x4_INTERLEAVED 0, 1, 2, 3, 4, 5, 6, dst1q, dst2q, mstrideq, strideq, dst3q
+%endif
+ TRANSPOSE4x4W 0, 1, 2, 3, 4
+%endif
+
+ ; simple_limit
+ mova m5, m2 ; m5=backup of q0
+ mova m6, m1 ; m6=backup of p0
+ psubusb m1, m2 ; p0-q0
+ psubusb m2, m6 ; q0-p0
+ por m1, m2 ; FFABS(p0-q0)
+ paddusb m1, m1 ; m1=FFABS(p0-q0)*2
+
+ mova m4, m3
+ mova m2, m0
+ psubusb m3, m0 ; q1-p1
+ psubusb m0, m4 ; p1-q1
+ por m3, m0 ; FFABS(p1-q1)
+ mova m0, [pb_80]
+ pxor m2, m0
+ pxor m4, m0
+ psubsb m2, m4 ; m2=p1-q1 (signed) backup for below
+ pand m3, [pb_FE]
+ psrlq m3, 1 ; m3=FFABS(p1-q1)/2, this can be used signed
+ paddusb m3, m1
+ psubusb m3, m7
+ pxor m1, m1
+ pcmpeqb m3, m1 ; abs(p0-q0)*2+abs(p1-q1)/2<=flim mask(0xff/0x0)
+
+ ; filter_common (use m2/p1-q1, m4=q0, m6=p0, m5/q0-p0 and m3/mask)
+ mova m4, m5
+ pxor m5, m0
+ pxor m0, m6
+ psubsb m5, m0 ; q0-p0 (signed)
+ paddsb m2, m5
+ paddsb m2, m5
+ paddsb m2, m5 ; a=(p1-q1) + 3*(q0-p0)
+ pand m2, m3 ; apply filter mask (m3)
+
+ mova m3, [pb_F8]
+ mova m1, m2
+ paddsb m2, [pb_4] ; f1<<3=a+4
+ paddsb m1, [pb_3] ; f2<<3=a+3
+ pand m2, m3
+ pand m1, m3 ; cache f2<<3
+
+ pxor m0, m0
+ pxor m3, m3
+ pcmpgtb m0, m2 ; which values are <0?
+ psubb m3, m2 ; -f1<<3
+ psrlq m2, 3 ; +f1
+ psrlq m3, 3 ; -f1
+ pand m3, m0
+ pandn m0, m2
+ psubusb m4, m0
+ paddusb m4, m3 ; q0-f1
+
+ pxor m0, m0
+ pxor m3, m3
+ pcmpgtb m0, m1 ; which values are <0?
+ psubb m3, m1 ; -f2<<3
+ psrlq m1, 3 ; +f2
+ psrlq m3, 3 ; -f2
+ pand m3, m0
+ pandn m0, m1
+ paddusb m6, m0
+ psubusb m6, m3 ; p0+f2
+
+ ; store
+%ifidn %1, v
+ mova [dst1q], m4
+ mova [dst1q+mstrideq], m6
+%else ; h
+ inc dst1q
+ SBUTTERFLY bw, 6, 4, 0
+
+%if mmsize == 16 ; sse2
+%if cpuflag(sse4)
+ inc dst2q
+%endif
+ WRITE_8W m6, dst2q, dst1q, mstrideq, strideq
+ lea dst2q, [dst3q+mstrideq+1]
+%if cpuflag(sse4)
+ inc dst3q
+%endif
+ WRITE_8W m4, dst3q, dst2q, mstrideq, strideq
+%else ; mmx/mmxext
+ WRITE_2x4W m6, m4, dst2q, dst1q, mstrideq, strideq
+%endif
+%endif
+
+%if mmsize == 8 ; mmx/mmxext
+ ; next 8 pixels
+%ifidn %1, v
+ add dst1q, 8 ; advance 8 cols = pixels
+%else ; h
+ lea dst1q, [dst1q+strideq*8-1] ; advance 8 rows = lines
+%endif
+ dec cntrq
+ jg .next8px
+ REP_RET
+%else ; sse2
+ RET
+%endif
+%endmacro
+
+%if ARCH_X86_32
+INIT_MMX mmx
+SIMPLE_LOOPFILTER v, 4
+SIMPLE_LOOPFILTER h, 5
+INIT_MMX mmxext
+SIMPLE_LOOPFILTER v, 4
+SIMPLE_LOOPFILTER h, 5
+%endif
+
+INIT_XMM sse2
+SIMPLE_LOOPFILTER v, 3
+SIMPLE_LOOPFILTER h, 5
+INIT_XMM ssse3
+SIMPLE_LOOPFILTER v, 3
+SIMPLE_LOOPFILTER h, 5
+INIT_XMM sse4
+SIMPLE_LOOPFILTER h, 5
+
+;-----------------------------------------------------------------------------
+; void vp8_h/v_loop_filter<size>_inner_<opt>(uint8_t *dst, [uint8_t *v,] int stride,
+; int flimE, int flimI, int hev_thr);
+;-----------------------------------------------------------------------------
+
+%macro INNER_LOOPFILTER 2
+%define stack_size 0
+%ifndef m8 ; stack layout: [0]=E, [1]=I, [2]=hev_thr
+%ifidn %1, v ; [3]=hev() result
+%define stack_size mmsize * -4
+%else ; h ; extra storage space for transposes
+%define stack_size mmsize * -5
+%endif
+%endif
+
+%if %2 == 8 ; chroma
+cglobal vp8_%1_loop_filter8uv_inner, 6, 6, 13, stack_size, dst, dst8, stride, flimE, flimI, hevthr
+%else ; luma
+cglobal vp8_%1_loop_filter16y_inner, 5, 5, 13, stack_size, dst, stride, flimE, flimI, hevthr
+%endif
+
+%if cpuflag(ssse3)
+ pxor m7, m7
+%endif
+
+%ifndef m8
+ ; splat function arguments
+ SPLATB_REG m0, flimEq, m7 ; E
+ SPLATB_REG m1, flimIq, m7 ; I
+ SPLATB_REG m2, hevthrq, m7 ; hev_thresh
+
+%define m_flimE [rsp]
+%define m_flimI [rsp+mmsize]
+%define m_hevthr [rsp+mmsize*2]
+%define m_maskres [rsp+mmsize*3]
+%define m_p0backup [rsp+mmsize*3]
+%define m_q0backup [rsp+mmsize*4]
+
+ mova m_flimE, m0
+ mova m_flimI, m1
+ mova m_hevthr, m2
+%else
+%define m_flimE m9
+%define m_flimI m10
+%define m_hevthr m11
+%define m_maskres m12
+%define m_p0backup m12
+%define m_q0backup m8
+
+ ; splat function arguments
+ SPLATB_REG m_flimE, flimEq, m7 ; E
+ SPLATB_REG m_flimI, flimIq, m7 ; I
+ SPLATB_REG m_hevthr, hevthrq, m7 ; hev_thresh
+%endif
+
+%if %2 == 8 ; chroma
+ DEFINE_ARGS dst1, dst8, mstride, stride, dst2
+%elif mmsize == 8
+ DEFINE_ARGS dst1, mstride, stride, dst2, cntr
+ mov cntrq, 2
+%else
+ DEFINE_ARGS dst1, mstride, stride, dst2, dst8
+%endif
+ mov strideq, mstrideq
+ neg mstrideq
+%ifidn %1, h
+ lea dst1q, [dst1q+strideq*4-4]
+%if %2 == 8 ; chroma
+ lea dst8q, [dst8q+strideq*4-4]
+%endif
+%endif
+
+%if mmsize == 8
+.next8px:
+%endif
+ ; read
+ lea dst2q, [dst1q+strideq]
+%ifidn %1, v
+%if %2 == 8 && mmsize == 16
+%define movrow movh
+%else
+%define movrow mova
+%endif
+ movrow m0, [dst1q+mstrideq*4] ; p3
+ movrow m1, [dst2q+mstrideq*4] ; p2
+ movrow m2, [dst1q+mstrideq*2] ; p1
+ movrow m5, [dst2q] ; q1
+ movrow m6, [dst2q+ strideq*1] ; q2
+ movrow m7, [dst2q+ strideq*2] ; q3
+%if mmsize == 16 && %2 == 8
+ movhps m0, [dst8q+mstrideq*4]
+ movhps m2, [dst8q+mstrideq*2]
+ add dst8q, strideq
+ movhps m1, [dst8q+mstrideq*4]
+ movhps m5, [dst8q]
+ movhps m6, [dst8q+ strideq ]
+ movhps m7, [dst8q+ strideq*2]
+ add dst8q, mstrideq
+%endif
+%elif mmsize == 8 ; mmx/mmxext (h)
+ ; read 8 rows of 8px each
+ movu m0, [dst1q+mstrideq*4]
+ movu m1, [dst2q+mstrideq*4]
+ movu m2, [dst1q+mstrideq*2]
+ movu m3, [dst1q+mstrideq ]
+ movu m4, [dst1q]
+ movu m5, [dst2q]
+ movu m6, [dst2q+ strideq ]
+
+ ; 8x8 transpose
+ TRANSPOSE4x4B 0, 1, 2, 3, 7
+ mova m_q0backup, m1
+ movu m7, [dst2q+ strideq*2]
+ TRANSPOSE4x4B 4, 5, 6, 7, 1
+ SBUTTERFLY dq, 0, 4, 1 ; p3/p2
+ SBUTTERFLY dq, 2, 6, 1 ; q0/q1
+ SBUTTERFLY dq, 3, 7, 1 ; q2/q3
+ mova m1, m_q0backup
+ mova m_q0backup, m2 ; store q0
+ SBUTTERFLY dq, 1, 5, 2 ; p1/p0
+ mova m_p0backup, m5 ; store p0
+ SWAP 1, 4
+ SWAP 2, 4
+ SWAP 6, 3
+ SWAP 5, 3
+%else ; sse2 (h)
+%if %2 == 16
+ lea dst8q, [dst1q+ strideq*8]
+%endif
+
+ ; read 16 rows of 8px each, interleave
+ movh m0, [dst1q+mstrideq*4]
+ movh m1, [dst8q+mstrideq*4]
+ movh m2, [dst1q+mstrideq*2]
+ movh m5, [dst8q+mstrideq*2]
+ movh m3, [dst1q+mstrideq ]
+ movh m6, [dst8q+mstrideq ]
+ movh m4, [dst1q]
+ movh m7, [dst8q]
+ punpcklbw m0, m1 ; A/I
+ punpcklbw m2, m5 ; C/K
+ punpcklbw m3, m6 ; D/L
+ punpcklbw m4, m7 ; E/M
+
+ add dst8q, strideq
+ movh m1, [dst2q+mstrideq*4]
+ movh m6, [dst8q+mstrideq*4]
+ movh m5, [dst2q]
+ movh m7, [dst8q]
+ punpcklbw m1, m6 ; B/J
+ punpcklbw m5, m7 ; F/N
+ movh m6, [dst2q+ strideq ]
+ movh m7, [dst8q+ strideq ]
+ punpcklbw m6, m7 ; G/O
+
+ ; 8x16 transpose
+ TRANSPOSE4x4B 0, 1, 2, 3, 7
+%ifdef m8
+ SWAP 1, 8
+%else
+ mova m_q0backup, m1
+%endif
+ movh m7, [dst2q+ strideq*2]
+ movh m1, [dst8q+ strideq*2]
+ punpcklbw m7, m1 ; H/P
+ TRANSPOSE4x4B 4, 5, 6, 7, 1
+ SBUTTERFLY dq, 0, 4, 1 ; p3/p2
+ SBUTTERFLY dq, 2, 6, 1 ; q0/q1
+ SBUTTERFLY dq, 3, 7, 1 ; q2/q3
+%ifdef m8
+ SWAP 1, 8
+ SWAP 2, 8
+%else
+ mova m1, m_q0backup
+ mova m_q0backup, m2 ; store q0
+%endif
+ SBUTTERFLY dq, 1, 5, 2 ; p1/p0
+%ifdef m12
+ SWAP 5, 12
+%else
+ mova m_p0backup, m5 ; store p0
+%endif
+ SWAP 1, 4
+ SWAP 2, 4
+ SWAP 6, 3
+ SWAP 5, 3
+%endif
+
+ ; normal_limit for p3-p2, p2-p1, q3-q2 and q2-q1
+ mova m4, m1
+ SWAP 4, 1
+ psubusb m4, m0 ; p2-p3
+ psubusb m0, m1 ; p3-p2
+ por m0, m4 ; abs(p3-p2)
+
+ mova m4, m2
+ SWAP 4, 2
+ psubusb m4, m1 ; p1-p2
+ psubusb m1, m2 ; p2-p1
+ por m1, m4 ; abs(p2-p1)
+
+ mova m4, m6
+ SWAP 4, 6
+ psubusb m4, m7 ; q2-q3
+ psubusb m7, m6 ; q3-q2
+ por m7, m4 ; abs(q3-q2)
+
+ mova m4, m5
+ SWAP 4, 5
+ psubusb m4, m6 ; q1-q2
+ psubusb m6, m5 ; q2-q1
+ por m6, m4 ; abs(q2-q1)
+
+%if notcpuflag(mmxext)
+ mova m4, m_flimI
+ pxor m3, m3
+ psubusb m0, m4
+ psubusb m1, m4
+ psubusb m7, m4
+ psubusb m6, m4
+ pcmpeqb m0, m3 ; abs(p3-p2) <= I
+ pcmpeqb m1, m3 ; abs(p2-p1) <= I
+ pcmpeqb m7, m3 ; abs(q3-q2) <= I
+ pcmpeqb m6, m3 ; abs(q2-q1) <= I
+ pand m0, m1
+ pand m7, m6
+ pand m0, m7
+%else ; mmxext/sse2
+ pmaxub m0, m1
+ pmaxub m6, m7
+ pmaxub m0, m6
+%endif
+
+ ; normal_limit and high_edge_variance for p1-p0, q1-q0
+ SWAP 7, 3 ; now m7 is zero
+%ifidn %1, v
+ movrow m3, [dst1q+mstrideq ] ; p0
+%if mmsize == 16 && %2 == 8
+ movhps m3, [dst8q+mstrideq ]
+%endif
+%elifdef m12
+ SWAP 3, 12
+%else
+ mova m3, m_p0backup
+%endif
+
+ mova m1, m2
+ SWAP 1, 2
+ mova m6, m3
+ SWAP 3, 6
+ psubusb m1, m3 ; p1-p0
+ psubusb m6, m2 ; p0-p1
+ por m1, m6 ; abs(p1-p0)
+%if notcpuflag(mmxext)
+ mova m6, m1
+ psubusb m1, m4
+ psubusb m6, m_hevthr
+ pcmpeqb m1, m7 ; abs(p1-p0) <= I
+ pcmpeqb m6, m7 ; abs(p1-p0) <= hev_thresh
+ pand m0, m1
+ mova m_maskres, m6
+%else ; mmxext/sse2
+ pmaxub m0, m1 ; max_I
+ SWAP 1, 4 ; max_hev_thresh
+%endif
+
+ SWAP 6, 4 ; now m6 is I
+%ifidn %1, v
+ movrow m4, [dst1q] ; q0
+%if mmsize == 16 && %2 == 8
+ movhps m4, [dst8q]
+%endif
+%elifdef m8
+ SWAP 4, 8
+%else
+ mova m4, m_q0backup
+%endif
+ mova m1, m4
+ SWAP 1, 4
+ mova m7, m5
+ SWAP 7, 5
+ psubusb m1, m5 ; q0-q1
+ psubusb m7, m4 ; q1-q0
+ por m1, m7 ; abs(q1-q0)
+%if notcpuflag(mmxext)
+ mova m7, m1
+ psubusb m1, m6
+ psubusb m7, m_hevthr
+ pxor m6, m6
+ pcmpeqb m1, m6 ; abs(q1-q0) <= I
+ pcmpeqb m7, m6 ; abs(q1-q0) <= hev_thresh
+ mova m6, m_maskres
+ pand m0, m1 ; abs([pq][321]-[pq][210]) <= I
+ pand m6, m7
+%else ; mmxext/sse2
+ pxor m7, m7
+ pmaxub m0, m1
+ pmaxub m6, m1
+ psubusb m0, m_flimI
+ psubusb m6, m_hevthr
+ pcmpeqb m0, m7 ; max(abs(..)) <= I
+ pcmpeqb m6, m7 ; !(max(abs..) > thresh)
+%endif
+%ifdef m12
+ SWAP 6, 12
+%else
+ mova m_maskres, m6 ; !(abs(p1-p0) > hev_t || abs(q1-q0) > hev_t)
+%endif
+
+ ; simple_limit
+ mova m1, m3
+ SWAP 1, 3
+ mova m6, m4 ; keep copies of p0/q0 around for later use
+ SWAP 6, 4
+ psubusb m1, m4 ; p0-q0
+ psubusb m6, m3 ; q0-p0
+ por m1, m6 ; abs(q0-p0)
+ paddusb m1, m1 ; m1=2*abs(q0-p0)
+
+ mova m7, m2
+ SWAP 7, 2
+ mova m6, m5
+ SWAP 6, 5
+ psubusb m7, m5 ; p1-q1
+ psubusb m6, m2 ; q1-p1
+ por m7, m6 ; abs(q1-p1)
+ pxor m6, m6
+ pand m7, [pb_FE]
+ psrlq m7, 1 ; abs(q1-p1)/2
+ paddusb m7, m1 ; abs(q0-p0)*2+abs(q1-p1)/2
+ psubusb m7, m_flimE
+ pcmpeqb m7, m6 ; abs(q0-p0)*2+abs(q1-p1)/2 <= E
+ pand m0, m7 ; normal_limit result
+
+ ; filter_common; at this point, m2-m5=p1-q1 and m0 is filter_mask
+%ifdef m8 ; x86-64 && sse2
+ mova m8, [pb_80]
+%define m_pb_80 m8
+%else ; x86-32 or mmx/mmxext
+%define m_pb_80 [pb_80]
+%endif
+ mova m1, m4
+ mova m7, m3
+ pxor m1, m_pb_80
+ pxor m7, m_pb_80
+ psubsb m1, m7 ; (signed) q0-p0
+ mova m6, m2
+ mova m7, m5
+ pxor m6, m_pb_80
+ pxor m7, m_pb_80
+ psubsb m6, m7 ; (signed) p1-q1
+ mova m7, m_maskres
+ pandn m7, m6
+ paddsb m7, m1
+ paddsb m7, m1
+ paddsb m7, m1 ; 3*(q0-p0)+is4tap?(p1-q1)
+
+ pand m7, m0
+ mova m1, [pb_F8]
+ mova m6, m7
+ paddsb m7, [pb_3]
+ paddsb m6, [pb_4]
+ pand m7, m1
+ pand m6, m1
+
+ pxor m1, m1
+ pxor m0, m0
+ pcmpgtb m1, m7
+ psubb m0, m7
+ psrlq m7, 3 ; +f2
+ psrlq m0, 3 ; -f2
+ pand m0, m1
+ pandn m1, m7
+ psubusb m3, m0
+ paddusb m3, m1 ; p0+f2
+
+ pxor m1, m1
+ pxor m0, m0
+ pcmpgtb m0, m6
+ psubb m1, m6
+ psrlq m6, 3 ; +f1
+ psrlq m1, 3 ; -f1
+ pand m1, m0
+ pandn m0, m6
+ psubusb m4, m0
+ paddusb m4, m1 ; q0-f1
+
+%ifdef m12
+ SWAP 6, 12
+%else
+ mova m6, m_maskres
+%endif
+%if notcpuflag(mmxext)
+ mova m7, [pb_1]
+%else ; mmxext/sse2
+ pxor m7, m7
+%endif
+ pand m0, m6
+ pand m1, m6
+%if notcpuflag(mmxext)
+ paddusb m0, m7
+ pand m1, [pb_FE]
+ pandn m7, m0
+ psrlq m1, 1
+ psrlq m7, 1
+ SWAP 0, 7
+%else ; mmxext/sse2
+ psubusb m1, [pb_1]
+ pavgb m0, m7 ; a
+ pavgb m1, m7 ; -a
+%endif
+ psubusb m5, m0
+ psubusb m2, m1
+ paddusb m5, m1 ; q1-a
+ paddusb m2, m0 ; p1+a
+
+ ; store
+%ifidn %1, v
+ movrow [dst1q+mstrideq*2], m2
+ movrow [dst1q+mstrideq ], m3
+ movrow [dst1q], m4
+ movrow [dst1q+ strideq ], m5
+%if mmsize == 16 && %2 == 8
+ movhps [dst8q+mstrideq*2], m2
+ movhps [dst8q+mstrideq ], m3
+ movhps [dst8q], m4
+ movhps [dst8q+ strideq ], m5
+%endif
+%else ; h
+ add dst1q, 2
+ add dst2q, 2
+
+ ; 4x8/16 transpose
+ TRANSPOSE4x4B 2, 3, 4, 5, 6
+
+%if mmsize == 8 ; mmx/mmxext (h)
+ WRITE_4x2D 2, 3, 4, 5, dst1q, dst2q, mstrideq, strideq
+%else ; sse2 (h)
+ lea dst8q, [dst8q+mstrideq +2]
+ WRITE_4x4D 2, 3, 4, 5, dst1q, dst2q, dst8q, mstrideq, strideq, %2
+%endif
+%endif
+
+%if mmsize == 8
+%if %2 == 8 ; chroma
+%ifidn %1, h
+ sub dst1q, 2
+%endif
+ cmp dst1q, dst8q
+ mov dst1q, dst8q
+ jnz .next8px
+%else
+%ifidn %1, h
+ lea dst1q, [dst1q+ strideq*8-2]
+%else ; v
+ add dst1q, 8
+%endif
+ dec cntrq
+ jg .next8px
+%endif
+ REP_RET
+%else ; mmsize == 16
+ RET
+%endif
+%endmacro
+
+%if ARCH_X86_32
+INIT_MMX mmx
+INNER_LOOPFILTER v, 16
+INNER_LOOPFILTER h, 16
+INNER_LOOPFILTER v, 8
+INNER_LOOPFILTER h, 8
+
+INIT_MMX mmxext
+INNER_LOOPFILTER v, 16
+INNER_LOOPFILTER h, 16
+INNER_LOOPFILTER v, 8
+INNER_LOOPFILTER h, 8
+%endif
+
+INIT_XMM sse2
+INNER_LOOPFILTER v, 16
+INNER_LOOPFILTER h, 16
+INNER_LOOPFILTER v, 8
+INNER_LOOPFILTER h, 8
+
+INIT_XMM ssse3
+INNER_LOOPFILTER v, 16
+INNER_LOOPFILTER h, 16
+INNER_LOOPFILTER v, 8
+INNER_LOOPFILTER h, 8
+
+;-----------------------------------------------------------------------------
+; void vp8_h/v_loop_filter<size>_mbedge_<opt>(uint8_t *dst, [uint8_t *v,] int stride,
+; int flimE, int flimI, int hev_thr);
+;-----------------------------------------------------------------------------
+
+%macro MBEDGE_LOOPFILTER 2
+%define stack_size 0
+%ifndef m8 ; stack layout: [0]=E, [1]=I, [2]=hev_thr
+%if mmsize == 16 ; [3]=hev() result
+ ; [4]=filter tmp result
+ ; [5]/[6] = p2/q2 backup
+ ; [7]=lim_res sign result
+%define stack_size mmsize * -7
+%else ; 8 ; extra storage space for transposes
+%define stack_size mmsize * -8
+%endif
+%endif
+
+%if %2 == 8 ; chroma
+cglobal vp8_%1_loop_filter8uv_mbedge, 6, 6, 15, stack_size, dst1, dst8, stride, flimE, flimI, hevthr
+%else ; luma
+cglobal vp8_%1_loop_filter16y_mbedge, 5, 5, 15, stack_size, dst1, stride, flimE, flimI, hevthr
+%endif
+
+%if cpuflag(ssse3)
+ pxor m7, m7
+%endif
+
+%ifndef m8
+ ; splat function arguments
+ SPLATB_REG m0, flimEq, m7 ; E
+ SPLATB_REG m1, flimIq, m7 ; I
+ SPLATB_REG m2, hevthrq, m7 ; hev_thresh
+
+%define m_flimE [rsp]
+%define m_flimI [rsp+mmsize]
+%define m_hevthr [rsp+mmsize*2]
+%define m_maskres [rsp+mmsize*3]
+%define m_limres [rsp+mmsize*4]
+%define m_p0backup [rsp+mmsize*3]
+%define m_q0backup [rsp+mmsize*4]
+%define m_p2backup [rsp+mmsize*5]
+%define m_q2backup [rsp+mmsize*6]
+%if mmsize == 16
+%define m_limsign [rsp]
+%else
+%define m_limsign [rsp+mmsize*7]
+%endif
+
+ mova m_flimE, m0
+ mova m_flimI, m1
+ mova m_hevthr, m2
+%else ; sse2 on x86-64
+%define m_flimE m9
+%define m_flimI m10
+%define m_hevthr m11
+%define m_maskres m12
+%define m_limres m8
+%define m_p0backup m12
+%define m_q0backup m8
+%define m_p2backup m13
+%define m_q2backup m14
+%define m_limsign m9
+
+ ; splat function arguments
+ SPLATB_REG m_flimE, flimEq, m7 ; E
+ SPLATB_REG m_flimI, flimIq, m7 ; I
+ SPLATB_REG m_hevthr, hevthrq, m7 ; hev_thresh
+%endif
+
+%if %2 == 8 ; chroma
+ DEFINE_ARGS dst1, dst8, mstride, stride, dst2
+%elif mmsize == 8
+ DEFINE_ARGS dst1, mstride, stride, dst2, cntr
+ mov cntrq, 2
+%else
+ DEFINE_ARGS dst1, mstride, stride, dst2, dst8
+%endif
+ mov strideq, mstrideq
+ neg mstrideq
+%ifidn %1, h
+ lea dst1q, [dst1q+strideq*4-4]
+%if %2 == 8 ; chroma
+ lea dst8q, [dst8q+strideq*4-4]
+%endif
+%endif
+
+%if mmsize == 8
+.next8px:
+%endif
+ ; read
+ lea dst2q, [dst1q+ strideq ]
+%ifidn %1, v
+%if %2 == 8 && mmsize == 16
+%define movrow movh
+%else
+%define movrow mova
+%endif
+ movrow m0, [dst1q+mstrideq*4] ; p3
+ movrow m1, [dst2q+mstrideq*4] ; p2
+ movrow m2, [dst1q+mstrideq*2] ; p1
+ movrow m5, [dst2q] ; q1
+ movrow m6, [dst2q+ strideq ] ; q2
+ movrow m7, [dst2q+ strideq*2] ; q3
+%if mmsize == 16 && %2 == 8
+ movhps m0, [dst8q+mstrideq*4]
+ movhps m2, [dst8q+mstrideq*2]
+ add dst8q, strideq
+ movhps m1, [dst8q+mstrideq*4]
+ movhps m5, [dst8q]
+ movhps m6, [dst8q+ strideq ]
+ movhps m7, [dst8q+ strideq*2]
+ add dst8q, mstrideq
+%endif
+%elif mmsize == 8 ; mmx/mmxext (h)
+ ; read 8 rows of 8px each
+ movu m0, [dst1q+mstrideq*4]
+ movu m1, [dst2q+mstrideq*4]
+ movu m2, [dst1q+mstrideq*2]
+ movu m3, [dst1q+mstrideq ]
+ movu m4, [dst1q]
+ movu m5, [dst2q]
+ movu m6, [dst2q+ strideq ]
+
+ ; 8x8 transpose
+ TRANSPOSE4x4B 0, 1, 2, 3, 7
+ mova m_q0backup, m1
+ movu m7, [dst2q+ strideq*2]
+ TRANSPOSE4x4B 4, 5, 6, 7, 1
+ SBUTTERFLY dq, 0, 4, 1 ; p3/p2
+ SBUTTERFLY dq, 2, 6, 1 ; q0/q1
+ SBUTTERFLY dq, 3, 7, 1 ; q2/q3
+ mova m1, m_q0backup
+ mova m_q0backup, m2 ; store q0
+ SBUTTERFLY dq, 1, 5, 2 ; p1/p0
+ mova m_p0backup, m5 ; store p0
+ SWAP 1, 4
+ SWAP 2, 4
+ SWAP 6, 3
+ SWAP 5, 3
+%else ; sse2 (h)
+%if %2 == 16
+ lea dst8q, [dst1q+ strideq*8 ]
+%endif
+
+ ; read 16 rows of 8px each, interleave
+ movh m0, [dst1q+mstrideq*4]
+ movh m1, [dst8q+mstrideq*4]
+ movh m2, [dst1q+mstrideq*2]
+ movh m5, [dst8q+mstrideq*2]
+ movh m3, [dst1q+mstrideq ]
+ movh m6, [dst8q+mstrideq ]
+ movh m4, [dst1q]
+ movh m7, [dst8q]
+ punpcklbw m0, m1 ; A/I
+ punpcklbw m2, m5 ; C/K
+ punpcklbw m3, m6 ; D/L
+ punpcklbw m4, m7 ; E/M
+
+ add dst8q, strideq
+ movh m1, [dst2q+mstrideq*4]
+ movh m6, [dst8q+mstrideq*4]
+ movh m5, [dst2q]
+ movh m7, [dst8q]
+ punpcklbw m1, m6 ; B/J
+ punpcklbw m5, m7 ; F/N
+ movh m6, [dst2q+ strideq ]
+ movh m7, [dst8q+ strideq ]
+ punpcklbw m6, m7 ; G/O
+
+ ; 8x16 transpose
+ TRANSPOSE4x4B 0, 1, 2, 3, 7
+%ifdef m8
+ SWAP 1, 8
+%else
+ mova m_q0backup, m1
+%endif
+ movh m7, [dst2q+ strideq*2]
+ movh m1, [dst8q+ strideq*2]
+ punpcklbw m7, m1 ; H/P
+ TRANSPOSE4x4B 4, 5, 6, 7, 1
+ SBUTTERFLY dq, 0, 4, 1 ; p3/p2
+ SBUTTERFLY dq, 2, 6, 1 ; q0/q1
+ SBUTTERFLY dq, 3, 7, 1 ; q2/q3
+%ifdef m8
+ SWAP 1, 8
+ SWAP 2, 8
+%else
+ mova m1, m_q0backup
+ mova m_q0backup, m2 ; store q0
+%endif
+ SBUTTERFLY dq, 1, 5, 2 ; p1/p0
+%ifdef m12
+ SWAP 5, 12
+%else
+ mova m_p0backup, m5 ; store p0
+%endif
+ SWAP 1, 4
+ SWAP 2, 4
+ SWAP 6, 3
+ SWAP 5, 3
+%endif
+
+ ; normal_limit for p3-p2, p2-p1, q3-q2 and q2-q1
+ mova m4, m1
+ SWAP 4, 1
+ psubusb m4, m0 ; p2-p3
+ psubusb m0, m1 ; p3-p2
+ por m0, m4 ; abs(p3-p2)
+
+ mova m4, m2
+ SWAP 4, 2
+ psubusb m4, m1 ; p1-p2
+ mova m_p2backup, m1
+ psubusb m1, m2 ; p2-p1
+ por m1, m4 ; abs(p2-p1)
+
+ mova m4, m6
+ SWAP 4, 6
+ psubusb m4, m7 ; q2-q3
+ psubusb m7, m6 ; q3-q2
+ por m7, m4 ; abs(q3-q2)
+
+ mova m4, m5
+ SWAP 4, 5
+ psubusb m4, m6 ; q1-q2
+ mova m_q2backup, m6
+ psubusb m6, m5 ; q2-q1
+ por m6, m4 ; abs(q2-q1)
+
+%if notcpuflag(mmxext)
+ mova m4, m_flimI
+ pxor m3, m3
+ psubusb m0, m4
+ psubusb m1, m4
+ psubusb m7, m4
+ psubusb m6, m4
+ pcmpeqb m0, m3 ; abs(p3-p2) <= I
+ pcmpeqb m1, m3 ; abs(p2-p1) <= I
+ pcmpeqb m7, m3 ; abs(q3-q2) <= I
+ pcmpeqb m6, m3 ; abs(q2-q1) <= I
+ pand m0, m1
+ pand m7, m6
+ pand m0, m7
+%else ; mmxext/sse2
+ pmaxub m0, m1
+ pmaxub m6, m7
+ pmaxub m0, m6
+%endif
+
+ ; normal_limit and high_edge_variance for p1-p0, q1-q0
+ SWAP 7, 3 ; now m7 is zero
+%ifidn %1, v
+ movrow m3, [dst1q+mstrideq ] ; p0
+%if mmsize == 16 && %2 == 8
+ movhps m3, [dst8q+mstrideq ]
+%endif
+%elifdef m12
+ SWAP 3, 12
+%else
+ mova m3, m_p0backup
+%endif
+
+ mova m1, m2
+ SWAP 1, 2
+ mova m6, m3
+ SWAP 3, 6
+ psubusb m1, m3 ; p1-p0
+ psubusb m6, m2 ; p0-p1
+ por m1, m6 ; abs(p1-p0)
+%if notcpuflag(mmxext)
+ mova m6, m1
+ psubusb m1, m4
+ psubusb m6, m_hevthr
+ pcmpeqb m1, m7 ; abs(p1-p0) <= I
+ pcmpeqb m6, m7 ; abs(p1-p0) <= hev_thresh
+ pand m0, m1
+ mova m_maskres, m6
+%else ; mmxext/sse2
+ pmaxub m0, m1 ; max_I
+ SWAP 1, 4 ; max_hev_thresh
+%endif
+
+ SWAP 6, 4 ; now m6 is I
+%ifidn %1, v
+ movrow m4, [dst1q] ; q0
+%if mmsize == 16 && %2 == 8
+ movhps m4, [dst8q]
+%endif
+%elifdef m8
+ SWAP 4, 8
+%else
+ mova m4, m_q0backup
+%endif
+ mova m1, m4
+ SWAP 1, 4
+ mova m7, m5
+ SWAP 7, 5
+ psubusb m1, m5 ; q0-q1
+ psubusb m7, m4 ; q1-q0
+ por m1, m7 ; abs(q1-q0)
+%if notcpuflag(mmxext)
+ mova m7, m1
+ psubusb m1, m6
+ psubusb m7, m_hevthr
+ pxor m6, m6
+ pcmpeqb m1, m6 ; abs(q1-q0) <= I
+ pcmpeqb m7, m6 ; abs(q1-q0) <= hev_thresh
+ mova m6, m_maskres
+ pand m0, m1 ; abs([pq][321]-[pq][210]) <= I
+ pand m6, m7
+%else ; mmxext/sse2
+ pxor m7, m7
+ pmaxub m0, m1
+ pmaxub m6, m1
+ psubusb m0, m_flimI
+ psubusb m6, m_hevthr
+ pcmpeqb m0, m7 ; max(abs(..)) <= I
+ pcmpeqb m6, m7 ; !(max(abs..) > thresh)
+%endif
+%ifdef m12
+ SWAP 6, 12
+%else
+ mova m_maskres, m6 ; !(abs(p1-p0) > hev_t || abs(q1-q0) > hev_t)
+%endif
+
+ ; simple_limit
+ mova m1, m3
+ SWAP 1, 3
+ mova m6, m4 ; keep copies of p0/q0 around for later use
+ SWAP 6, 4
+ psubusb m1, m4 ; p0-q0
+ psubusb m6, m3 ; q0-p0
+ por m1, m6 ; abs(q0-p0)
+ paddusb m1, m1 ; m1=2*abs(q0-p0)
+
+ mova m7, m2
+ SWAP 7, 2
+ mova m6, m5
+ SWAP 6, 5
+ psubusb m7, m5 ; p1-q1
+ psubusb m6, m2 ; q1-p1
+ por m7, m6 ; abs(q1-p1)
+ pxor m6, m6
+ pand m7, [pb_FE]
+ psrlq m7, 1 ; abs(q1-p1)/2
+ paddusb m7, m1 ; abs(q0-p0)*2+abs(q1-p1)/2
+ psubusb m7, m_flimE
+ pcmpeqb m7, m6 ; abs(q0-p0)*2+abs(q1-p1)/2 <= E
+ pand m0, m7 ; normal_limit result
+
+ ; filter_common; at this point, m2-m5=p1-q1 and m0 is filter_mask
+%ifdef m8 ; x86-64 && sse2
+ mova m8, [pb_80]
+%define m_pb_80 m8
+%else ; x86-32 or mmx/mmxext
+%define m_pb_80 [pb_80]
+%endif
+ mova m1, m4
+ mova m7, m3
+ pxor m1, m_pb_80
+ pxor m7, m_pb_80
+ psubsb m1, m7 ; (signed) q0-p0
+ mova m6, m2
+ mova m7, m5
+ pxor m6, m_pb_80
+ pxor m7, m_pb_80
+ psubsb m6, m7 ; (signed) p1-q1
+ mova m7, m_maskres
+ paddsb m6, m1
+ paddsb m6, m1
+ paddsb m6, m1
+ pand m6, m0
+%ifdef m8
+ mova m_limres, m6 ; 3*(qp-p0)+(p1-q1) masked for filter_mbedge
+ pand m_limres, m7
+%else
+ mova m0, m6
+ pand m0, m7
+ mova m_limres, m0
+%endif
+ pandn m7, m6 ; 3*(q0-p0)+(p1-q1) masked for filter_common
+
+ mova m1, [pb_F8]
+ mova m6, m7
+ paddsb m7, [pb_3]
+ paddsb m6, [pb_4]
+ pand m7, m1
+ pand m6, m1
+
+ pxor m1, m1
+ pxor m0, m0
+ pcmpgtb m1, m7
+ psubb m0, m7
+ psrlq m7, 3 ; +f2
+ psrlq m0, 3 ; -f2
+ pand m0, m1
+ pandn m1, m7
+ psubusb m3, m0
+ paddusb m3, m1 ; p0+f2
+
+ pxor m1, m1
+ pxor m0, m0
+ pcmpgtb m0, m6
+ psubb m1, m6
+ psrlq m6, 3 ; +f1
+ psrlq m1, 3 ; -f1
+ pand m1, m0
+ pandn m0, m6
+ psubusb m4, m0
+ paddusb m4, m1 ; q0-f1
+
+ ; filter_mbedge (m2-m5 = p1-q1; lim_res carries w)
+%if cpuflag(ssse3)
+ mova m7, [pb_1]
+%else
+ mova m7, [pw_63]
+%endif
+%ifdef m8
+ SWAP 1, 8
+%else
+ mova m1, m_limres
+%endif
+ pxor m0, m0
+ mova m6, m1
+ pcmpgtb m0, m1 ; which are negative
+%if cpuflag(ssse3)
+ punpcklbw m6, m7 ; interleave with "1" for rounding
+ punpckhbw m1, m7
+%else
+ punpcklbw m6, m0 ; signed byte->word
+ punpckhbw m1, m0
+%endif
+ mova m_limsign, m0
+%if cpuflag(ssse3)
+ mova m7, [pb_27_63]
+%ifndef m8
+ mova m_limres, m1
+%endif
+%ifdef m10
+ SWAP 0, 10 ; don't lose lim_sign copy
+%endif
+ mova m0, m7
+ pmaddubsw m7, m6
+ SWAP 6, 7
+ pmaddubsw m0, m1
+ SWAP 1, 0
+%ifdef m10
+ SWAP 0, 10
+%else
+ mova m0, m_limsign
+%endif
+%else
+ mova m_maskres, m6 ; backup for later in filter
+ mova m_limres, m1
+ pmullw m6, [pw_27]
+ pmullw m1, [pw_27]
+ paddw m6, m7
+ paddw m1, m7
+%endif
+ psraw m6, 7
+ psraw m1, 7
+ packsswb m6, m1 ; a0
+ pxor m1, m1
+ psubb m1, m6
+ pand m1, m0 ; -a0
+ pandn m0, m6 ; +a0
+%if cpuflag(ssse3)
+ mova m6, [pb_18_63] ; pipelining
+%endif
+ psubusb m3, m1
+ paddusb m4, m1
+ paddusb m3, m0 ; p0+a0
+ psubusb m4, m0 ; q0-a0
+
+%if cpuflag(ssse3)
+ SWAP 6, 7
+%ifdef m10
+ SWAP 1, 10
+%else
+ mova m1, m_limres
+%endif
+ mova m0, m7
+ pmaddubsw m7, m6
+ SWAP 6, 7
+ pmaddubsw m0, m1
+ SWAP 1, 0
+%ifdef m10
+ SWAP 0, 10
+%endif
+ mova m0, m_limsign
+%else
+ mova m6, m_maskres
+ mova m1, m_limres
+ pmullw m6, [pw_18]
+ pmullw m1, [pw_18]
+ paddw m6, m7
+ paddw m1, m7
+%endif
+ mova m0, m_limsign
+ psraw m6, 7
+ psraw m1, 7
+ packsswb m6, m1 ; a1
+ pxor m1, m1
+ psubb m1, m6
+ pand m1, m0 ; -a1
+ pandn m0, m6 ; +a1
+%if cpuflag(ssse3)
+ mova m6, [pb_9_63]
+%endif
+ psubusb m2, m1
+ paddusb m5, m1
+ paddusb m2, m0 ; p1+a1
+ psubusb m5, m0 ; q1-a1
+
+%if cpuflag(ssse3)
+ SWAP 6, 7
+%ifdef m10
+ SWAP 1, 10
+%else
+ mova m1, m_limres
+%endif
+ mova m0, m7
+ pmaddubsw m7, m6
+ SWAP 6, 7
+ pmaddubsw m0, m1
+ SWAP 1, 0
+%else
+%ifdef m8
+ SWAP 6, 12
+ SWAP 1, 8
+%else
+ mova m6, m_maskres
+ mova m1, m_limres
+%endif
+ pmullw m6, [pw_9]
+ pmullw m1, [pw_9]
+ paddw m6, m7
+ paddw m1, m7
+%endif
+%ifdef m9
+ SWAP 7, 9
+%else
+ mova m7, m_limsign
+%endif
+ psraw m6, 7
+ psraw m1, 7
+ packsswb m6, m1 ; a1
+ pxor m0, m0
+ psubb m0, m6
+ pand m0, m7 ; -a1
+ pandn m7, m6 ; +a1
+%ifdef m8
+ SWAP 1, 13
+ SWAP 6, 14
+%else
+ mova m1, m_p2backup
+ mova m6, m_q2backup
+%endif
+ psubusb m1, m0
+ paddusb m6, m0
+ paddusb m1, m7 ; p1+a1
+ psubusb m6, m7 ; q1-a1
+
+ ; store
+%ifidn %1, v
+ movrow [dst2q+mstrideq*4], m1
+ movrow [dst1q+mstrideq*2], m2
+ movrow [dst1q+mstrideq ], m3
+ movrow [dst1q], m4
+ movrow [dst2q], m5
+ movrow [dst2q+ strideq ], m6
+%if mmsize == 16 && %2 == 8
+ add dst8q, mstrideq
+ movhps [dst8q+mstrideq*2], m1
+ movhps [dst8q+mstrideq ], m2
+ movhps [dst8q], m3
+ add dst8q, strideq
+ movhps [dst8q], m4
+ movhps [dst8q+ strideq ], m5
+ movhps [dst8q+ strideq*2], m6
+%endif
+%else ; h
+ inc dst1q
+ inc dst2q
+
+ ; 4x8/16 transpose
+ TRANSPOSE4x4B 1, 2, 3, 4, 0
+ SBUTTERFLY bw, 5, 6, 0
+
+%if mmsize == 8 ; mmx/mmxext (h)
+ WRITE_4x2D 1, 2, 3, 4, dst1q, dst2q, mstrideq, strideq
+ add dst1q, 4
+ WRITE_2x4W m5, m6, dst2q, dst1q, mstrideq, strideq
+%else ; sse2 (h)
+ lea dst8q, [dst8q+mstrideq+1]
+ WRITE_4x4D 1, 2, 3, 4, dst1q, dst2q, dst8q, mstrideq, strideq, %2
+ lea dst1q, [dst2q+mstrideq+4]
+ lea dst8q, [dst8q+mstrideq+4]
+%if cpuflag(sse4)
+ add dst2q, 4
+%endif
+ WRITE_8W m5, dst2q, dst1q, mstrideq, strideq
+%if cpuflag(sse4)
+ lea dst2q, [dst8q+ strideq ]
+%endif
+ WRITE_8W m6, dst2q, dst8q, mstrideq, strideq
+%endif
+%endif
+
+%if mmsize == 8
+%if %2 == 8 ; chroma
+%ifidn %1, h
+ sub dst1q, 5
+%endif
+ cmp dst1q, dst8q
+ mov dst1q, dst8q
+ jnz .next8px
+%else
+%ifidn %1, h
+ lea dst1q, [dst1q+ strideq*8-5]
+%else ; v
+ add dst1q, 8
+%endif
+ dec cntrq
+ jg .next8px
+%endif
+ REP_RET
+%else ; mmsize == 16
+ RET
+%endif
+%endmacro
+
+%if ARCH_X86_32
+INIT_MMX mmx
+MBEDGE_LOOPFILTER v, 16
+MBEDGE_LOOPFILTER h, 16
+MBEDGE_LOOPFILTER v, 8
+MBEDGE_LOOPFILTER h, 8
+
+INIT_MMX mmxext
+MBEDGE_LOOPFILTER v, 16
+MBEDGE_LOOPFILTER h, 16
+MBEDGE_LOOPFILTER v, 8
+MBEDGE_LOOPFILTER h, 8
+%endif
+
+INIT_XMM sse2
+MBEDGE_LOOPFILTER v, 16
+MBEDGE_LOOPFILTER h, 16
+MBEDGE_LOOPFILTER v, 8
+MBEDGE_LOOPFILTER h, 8
+
+INIT_XMM ssse3
+MBEDGE_LOOPFILTER v, 16
+MBEDGE_LOOPFILTER h, 16
+MBEDGE_LOOPFILTER v, 8
+MBEDGE_LOOPFILTER h, 8
+
+INIT_XMM sse4
+MBEDGE_LOOPFILTER h, 16
+MBEDGE_LOOPFILTER h, 8
diff --git a/libavcodec/x86/vp9dsp_init.c b/libavcodec/x86/vp9dsp_init.c
index cf7a1a4..3c02520 100644
--- a/libavcodec/x86/vp9dsp_init.c
+++ b/libavcodec/x86/vp9dsp_init.c
@@ -23,6 +23,7 @@
#include "libavutil/cpu.h"
#include "libavutil/mem.h"
#include "libavutil/x86/asm.h"
+#include "libavutil/x86/cpu.h"
#include "libavcodec/vp9dsp.h"
#if HAVE_YASM
@@ -150,6 +151,9 @@
#undef filters_8tap_1d_fn3
#undef filter_8tap_1d_fn
+void ff_vp9_idct_idct_4x4_add_ssse3(uint8_t *dst, ptrdiff_t stride, int16_t *block, int eob);
+void ff_vp9_idct_idct_8x8_add_ssse3(uint8_t *dst, ptrdiff_t stride, int16_t *block, int eob);
+
#endif /* HAVE_YASM */
av_cold void ff_vp9dsp_init_x86(VP9DSPContext *dsp)
@@ -181,12 +185,12 @@
init_subpel2(idx, 0, 1, v, type, opt); \
init_subpel2(idx, 1, 0, h, type, opt)
- if (cpu_flags & AV_CPU_FLAG_MMX) {
+ if (EXTERNAL_MMX(cpu_flags)) {
init_fpel(4, 0, 4, put, mmx);
init_fpel(3, 0, 8, put, mmx);
}
- if (cpu_flags & AV_CPU_FLAG_SSE) {
+ if (EXTERNAL_SSE(cpu_flags)) {
init_fpel(2, 0, 16, put, sse);
init_fpel(1, 0, 32, put, sse);
init_fpel(0, 0, 64, put, sse);
@@ -194,15 +198,18 @@
init_fpel(3, 1, 8, avg, sse);
}
- if (cpu_flags & AV_CPU_FLAG_SSE2) {
+ if (EXTERNAL_SSE2(cpu_flags)) {
init_fpel(2, 1, 16, avg, sse2);
init_fpel(1, 1, 32, avg, sse2);
init_fpel(0, 1, 64, avg, sse2);
}
- if (cpu_flags & AV_CPU_FLAG_SSSE3) {
+ if (EXTERNAL_SSSE3(cpu_flags)) {
init_subpel3(0, put, ssse3);
init_subpel3(1, avg, ssse3);
+ dsp->itxfm_add[TX_4X4][DCT_DCT] = ff_vp9_idct_idct_4x4_add_ssse3;
+ if (ARCH_X86_64)
+ dsp->itxfm_add[TX_8X8][DCT_DCT] = ff_vp9_idct_idct_8x8_add_ssse3;
}
#undef init_fpel
diff --git a/libavcodec/x86/vp9itxfm.asm b/libavcodec/x86/vp9itxfm.asm
new file mode 100644
index 0000000..ebf3044
--- /dev/null
+++ b/libavcodec/x86/vp9itxfm.asm
@@ -0,0 +1,355 @@
+;******************************************************************************
+;* VP9 IDCT SIMD optimizations
+;*
+;* Copyright (C) 2013 Clément Bœsch <u pkh me>
+;*
+;* This file is part of FFmpeg.
+;*
+;* FFmpeg is free software; you can redistribute it and/or
+;* modify it under the terms of the GNU Lesser General Public
+;* License as published by the Free Software Foundation; either
+;* version 2.1 of the License, or (at your option) any later version.
+;*
+;* FFmpeg is distributed in the hope that it will be useful,
+;* but WITHOUT ANY WARRANTY; without even the implied warranty of
+;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+;* Lesser General Public License for more details.
+;*
+;* You should have received a copy of the GNU Lesser General Public
+;* License along with FFmpeg; if not, write to the Free Software
+;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+;******************************************************************************
+
+%include "libavutil/x86/x86util.asm"
+
+SECTION_RODATA
+
+pw_11585x2: times 8 dw 23170
+
+%macro VP9_IDCT_COEFFS 2
+pw_m%1_%2: dw -%1, %2, -%1, %2, -%1, %2, -%1, %2
+pw_%2_%1: dw %2, %1, %2, %1, %2, %1, %2, %1
+%endmacro
+
+%macro VP9_IDCT_COEFFS_ALL 2
+pw_%1x2: times 8 dw %1*2
+pw_%2x2: times 8 dw %2*2
+VP9_IDCT_COEFFS %1, %2
+%endmacro
+
+VP9_IDCT_COEFFS_ALL 15137, 6270
+VP9_IDCT_COEFFS_ALL 16069, 3196
+VP9_IDCT_COEFFS_ALL 9102, 13623
+
+pd_8192: times 4 dd 8192
+pw_2048: times 8 dw 2048
+pw_1024: times 8 dw 1024
+
+SECTION .text
+
+; (a*x + b*y + round) >> shift
+%macro VP9_MULSUB_2W_2X 6 ; dst1, dst2, src (unchanged), round, coefs1, coefs2
+ pmaddwd m%1, m%3, %5
+ pmaddwd m%2, m%3, %6
+ paddd m%1, %4
+ paddd m%2, %4
+ psrad m%1, 14
+ psrad m%2, 14
+%endmacro
+
+%macro VP9_UNPACK_MULSUB_2W_4X 7 ; dst1, dst2, coef1, coef2, rnd, tmp1, tmp2
+ punpckhwd m%6, m%2, m%1
+ VP9_MULSUB_2W_2X %7, %6, %6, %5, [pw_m%3_%4], [pw_%4_%3]
+ punpcklwd m%2, m%1
+ VP9_MULSUB_2W_2X %1, %2, %2, %5, [pw_m%3_%4], [pw_%4_%3]
+ packssdw m%1, m%7
+ packssdw m%2, m%6
+%endmacro
+
+%macro VP9_STORE_2X 5 ; reg1, reg2, tmp1, tmp2, zero
+ movh m%3, [dstq]
+ movh m%4, [dstq+strideq]
+ punpcklbw m%3, m%5
+ punpcklbw m%4, m%5
+ paddw m%3, m%1
+ paddw m%4, m%2
+ packuswb m%3, m%5
+ packuswb m%4, m%5
+ movh [dstq], m%3
+ movh [dstq+strideq], m%4
+%endmacro
+
+;-------------------------------------------------------------------------------------------
+; void vp9_idct_idct_4x4_add_<opt>(uint8_t *dst, ptrdiff_t stride, int16_t *block, int eob);
+;-------------------------------------------------------------------------------------------
+
+%macro VP9_IDCT4_1D_FINALIZE 0
+ SUMSUB_BA w, 3, 2, 4 ; m3=t3+t0, m2=-t3+t0
+ SUMSUB_BA w, 1, 0, 4 ; m1=t2+t1, m0=-t2+t1
+ SWAP 0, 3, 2 ; 3102 -> 0123
+%endmacro
+
+%macro VP9_IDCT4_1D 0
+ SUMSUB_BA w, 2, 0, 4 ; m2=IN(0)+IN(2) m0=IN(0)-IN(2)
+ pmulhrsw m2, m6 ; m2=t0
+ pmulhrsw m0, m6 ; m0=t1
+ VP9_UNPACK_MULSUB_2W_4X 1, 3, 15137, 6270, m7, 4, 5 ; m1=t2, m3=t3
+ VP9_IDCT4_1D_FINALIZE
+%endmacro
+
+; 2x2 top left corner
+%macro VP9_IDCT4_2x2_1D 0
+ pmulhrsw m0, m5 ; m0=t1
+ mova m2, m0 ; m2=t0
+ mova m3, m1
+ pmulhrsw m1, m6 ; m1=t2
+ pmulhrsw m3, m7 ; m3=t3
+ VP9_IDCT4_1D_FINALIZE
+%endmacro
+
+%macro VP9_IDCT4_WRITEOUT 0
+ mova m5, [pw_2048]
+ pmulhrsw m0, m5 ; (x*2048 + (1<<14))>>15 <=> (x+8)>>4
+ pmulhrsw m1, m5
+ VP9_STORE_2X 0, 1, 6, 7, 4
+ lea dstq, [dstq+2*strideq]
+ pmulhrsw m2, m5
+ pmulhrsw m3, m5
+ VP9_STORE_2X 2, 3, 6, 7, 4
+%endmacro
+
+INIT_MMX ssse3
+cglobal vp9_idct_idct_4x4_add, 4,4,0, dst, stride, block, eob
+
+ cmp eobd, 4 ; 2x2 or smaller
+ jg .idctfull
+
+ cmp eobd, 1 ; faster path for when only DC is set
+ jne .idct2x2
+
+ movd m0, [blockq]
+ mova m5, [pw_11585x2]
+ pmulhrsw m0, m5
+ pmulhrsw m0, m5
+ pshufw m0, m0, 0
+ pxor m4, m4
+ movh [blockq], m4
+ pmulhrsw m0, [pw_2048] ; (x*2048 + (1<<14))>>15 <=> (x+8)>>4
+ VP9_STORE_2X 0, 0, 6, 7, 4
+ lea dstq, [dstq+2*strideq]
+ VP9_STORE_2X 0, 0, 6, 7, 4
+ RET
+
+; faster path for when only top left 2x2 block is set
+.idct2x2:
+ movd m0, [blockq+0]
+ movd m1, [blockq+8]
+ mova m5, [pw_11585x2]
+ mova m6, [pw_6270x2]
+ mova m7, [pw_15137x2]
+ VP9_IDCT4_2x2_1D
+ TRANSPOSE4x4W 0, 1, 2, 3, 4
+ VP9_IDCT4_2x2_1D
+ pxor m4, m4 ; used for the block reset, and VP9_STORE_2X
+ movh [blockq+ 0], m4
+ movh [blockq+ 8], m4
+ VP9_IDCT4_WRITEOUT
+ RET
+
+.idctfull: ; generic full 4x4 idct/idct
+ mova m0, [blockq+ 0]
+ mova m1, [blockq+ 8]
+ mova m2, [blockq+16]
+ mova m3, [blockq+24]
+ mova m6, [pw_11585x2]
+ mova m7, [pd_8192] ; rounding
+ VP9_IDCT4_1D
+ TRANSPOSE4x4W 0, 1, 2, 3, 4
+ VP9_IDCT4_1D
+ pxor m4, m4 ; used for the block reset, and VP9_STORE_2X
+ mova [blockq+ 0], m4
+ mova [blockq+ 8], m4
+ mova [blockq+16], m4
+ mova [blockq+24], m4
+ VP9_IDCT4_WRITEOUT
+ RET
+
+;-------------------------------------------------------------------------------------------
+; void vp9_idct_idct_8x8_add_<opt>(uint8_t *dst, ptrdiff_t stride, int16_t *block, int eob);
+;-------------------------------------------------------------------------------------------
+
+%if ARCH_X86_64 ; TODO: 32-bit? (32-bit limited to 8 xmm reg, we use 13 here)
+%macro VP9_IDCT8_1D_FINALIZE 0
+ SUMSUB_BA w, 3, 10, 4 ; m3=t0+t7, m10=t0-t7
+ SUMSUB_BA w, 1, 2, 4 ; m1=t1+t6, m2=t1-t6
+ SUMSUB_BA w, 11, 0, 4 ; m11=t2+t5, m0=t2-t5
+ SUMSUB_BA w, 9, 8, 4 ; m9=t3+t4, m8=t3-t4
+ SWAP 11, 10, 2
+ SWAP 3, 9, 0
+%endmacro
+
+%macro VP9_IDCT8_1D 0
+ SUMSUB_BA w, 8, 0, 4 ; m8=IN(0)+IN(4) m0=IN(0)-IN(4)
+ pmulhrsw m8, m12 ; m8=t0a
+ pmulhrsw m0, m12 ; m0=t1a
+ VP9_UNPACK_MULSUB_2W_4X 2, 10, 15137, 6270, m7, 4, 5 ; m2=t2a, m10=t3a
+ VP9_UNPACK_MULSUB_2W_4X 1, 11, 16069, 3196, m7, 4, 5 ; m1=t4a, m11=t7a
+ VP9_UNPACK_MULSUB_2W_4X 9, 3, 9102, 13623, m7, 4, 5 ; m9=t5a, m3=t6a
+ SUMSUB_BA w, 10, 8, 4 ; m10=t0a+t3a (t0), m8=t0a-t3a (t3)
+ SUMSUB_BA w, 2, 0, 4 ; m2=t1a+t2a (t1), m0=t1a-t2a (t2)
+ SUMSUB_BA w, 9, 1, 4 ; m9=t4a+t5a (t4), m1=t4a-t5a (t5a)
+ SUMSUB_BA w, 3, 11, 4 ; m3=t7a+t6a (t7), m11=t7a-t6a (t6a)
+ SUMSUB_BA w, 1, 11, 4 ; m1=t6a+t5a (t6), m11=t6a-t5a (t5)
+ pmulhrsw m1, m12 ; m1=t6
+ pmulhrsw m11, m12 ; m11=t5
+ VP9_IDCT8_1D_FINALIZE
+%endmacro
+
+%macro VP9_IDCT8_4x4_1D 0
+ pmulhrsw m0, m12 ; m0=t1a/t0a
+ pmulhrsw m10, m2, [pw_15137x2] ; m10=t3a
+ pmulhrsw m2, [pw_6270x2] ; m2=t2a
+ pmulhrsw m11, m1, [pw_16069x2] ; m11=t7a
+ pmulhrsw m1, [pw_3196x2] ; m1=t4a
+ pmulhrsw m9, m3, [pw_9102x2] ; m9=-t5a
+ pmulhrsw m3, [pw_13623x2] ; m3=t6a
+ psubw m8, m0, m10 ; m8=t0a-t3a (t3)
+ paddw m10, m0 ; m10=t0a+t3a (t0)
+ SUMSUB_BA w, 2, 0, 4 ; m2=t1a+t2a (t1), m0=t1a-t2a (t2)
+ SUMSUB_BA w, 9, 1, 4 ; m1=t4a+t5a (t4), m9=t4a-t5a (t5a)
+ SWAP 1, 9
+ SUMSUB_BA w, 3, 11, 4 ; m3=t7a+t6a (t7), m11=t7a-t6a (t6a)
+ SUMSUB_BA w, 1, 11, 4 ; m1=t6a+t5a (t6), m11=t6a-t5a (t5)
+ pmulhrsw m1, m12 ; m1=t6
+ pmulhrsw m11, m12 ; m11=t5
+ VP9_IDCT8_1D_FINALIZE
+%endmacro
+
+; TODO: a lot of t* copies can probably be removed and merged with
+; following SUMSUBs from VP9_IDCT8_1D_FINALIZE with AVX
+%macro VP9_IDCT8_2x2_1D 0
+ pmulhrsw m0, m12 ; m0=t0
+ mova m3, m1
+ pmulhrsw m1, m6 ; m1=t4
+ pmulhrsw m3, m7 ; m3=t7
+ mova m2, m0 ; m2=t1
+ mova m10, m0 ; m10=t2
+ mova m8, m0 ; m8=t3
+ mova m11, m3 ; t5 = t7a ...
+ mova m9, m3 ; t6 = t7a ...
+ psubw m11, m1 ; t5 = t7a - t4a
+ paddw m9, m1 ; t6 = t7a + t4a
+ pmulhrsw m11, m12 ; m11=t5
+ pmulhrsw m9, m12 ; m9=t6
+ SWAP 0, 10
+ SWAP 9, 1
+ VP9_IDCT8_1D_FINALIZE
+%endmacro
+
+%macro VP9_IDCT8_WRITEOUT 0
+ mova m5, [pw_1024]
+ pmulhrsw m0, m5 ; (x*1024 + (1<<14))>>15 <=> (x+16)>>5
+ pmulhrsw m1, m5
+ VP9_STORE_2X 0, 1, 6, 7, 4
+ lea dstq, [dstq+2*strideq]
+ pmulhrsw m2, m5
+ pmulhrsw m3, m5
+ VP9_STORE_2X 2, 3, 6, 7, 4
+ lea dstq, [dstq+2*strideq]
+ pmulhrsw m8, m5
+ pmulhrsw m9, m5
+ VP9_STORE_2X 8, 9, 6, 7, 4
+ lea dstq, [dstq+2*strideq]
+ pmulhrsw m10, m5
+ pmulhrsw m11, m5
+ VP9_STORE_2X 10, 11, 6, 7, 4
+%endmacro
+
+INIT_XMM ssse3
+cglobal vp9_idct_idct_8x8_add, 4,4,13, dst, stride, block, eob
+
+ mova m12, [pw_11585x2] ; often used
+
+ cmp eobd, 12 ; top left half or less
+ jg .idctfull
+
+ cmp eobd, 3 ; top left corner or less
+ jg .idcthalf
+
+ cmp eobd, 1 ; faster path for when only DC is set
+ jne .idcttopleftcorner
+
+ movd m0, [blockq]
+ pmulhrsw m0, m12
+ pmulhrsw m0, m12
+ SPLATW m0, m0, 0
+ pxor m4, m4
+ movd [blockq], m4
+ mova m5, [pw_1024]
+ pmulhrsw m0, m5 ; (x*1024 + (1<<14))>>15 <=> (x+16)>>5
+ VP9_STORE_2X 0, 0, 6, 7, 4
+ lea dstq, [dstq+2*strideq]
+ VP9_STORE_2X 0, 0, 6, 7, 4
+ lea dstq, [dstq+2*strideq]
+ VP9_STORE_2X 0, 0, 6, 7, 4
+ lea dstq, [dstq+2*strideq]
+ VP9_STORE_2X 0, 0, 6, 7, 4
+ RET
+
+; faster path for when only left corner is set (3 input: DC, right to DC, below
+; to DC). Note: also working with a 2x2 block
+.idcttopleftcorner:
+ movd m0, [blockq+0]
+ movd m1, [blockq+16]
+ mova m6, [pw_3196x2]
+ mova m7, [pw_16069x2]
+ VP9_IDCT8_2x2_1D
+ TRANSPOSE8x8W 0, 1, 2, 3, 8, 9, 10, 11, 4
+ VP9_IDCT8_2x2_1D
+ pxor m4, m4 ; used for the block reset, and VP9_STORE_2X
+ movd [blockq+ 0], m4
+ movd [blockq+16], m4
+ VP9_IDCT8_WRITEOUT
+ RET
+
+.idcthalf:
+ movh m0, [blockq + 0]
+ movh m1, [blockq +16]
+ movh m2, [blockq +32]
+ movh m3, [blockq +48]
+ VP9_IDCT8_4x4_1D
+ TRANSPOSE8x8W 0, 1, 2, 3, 8, 9, 10, 11, 4
+ VP9_IDCT8_4x4_1D
+ pxor m4, m4
+ movh [blockq+ 0], m4
+ movh [blockq+16], m4
+ movh [blockq+32], m4
+ movh [blockq+48], m4
+ VP9_IDCT8_WRITEOUT
+ RET
+
+.idctfull: ; generic full 8x8 idct/idct
+ mova m0, [blockq+ 0] ; IN(0)
+ mova m1, [blockq+ 16] ; IN(1)
+ mova m2, [blockq+ 32] ; IN(2)
+ mova m3, [blockq+ 48] ; IN(3)
+ mova m8, [blockq+ 64] ; IN(4)
+ mova m9, [blockq+ 80] ; IN(5)
+ mova m10, [blockq+ 96] ; IN(6)
+ mova m11, [blockq+112] ; IN(7)
+ mova m7, [pd_8192] ; rounding
+ VP9_IDCT8_1D
+ TRANSPOSE8x8W 0, 1, 2, 3, 8, 9, 10, 11, 4
+ VP9_IDCT8_1D
+ pxor m4, m4 ; used for the block reset, and VP9_STORE_2X
+ mova [blockq+ 0], m4
+ mova [blockq+ 16], m4
+ mova [blockq+ 32], m4
+ mova [blockq+ 48], m4
+ mova [blockq+ 64], m4
+ mova [blockq+ 80], m4
+ mova [blockq+ 96], m4
+ mova [blockq+112], m4
+ VP9_IDCT8_WRITEOUT
+ RET
+%endif
diff --git a/libavcodec/x86/vp9dsp.asm b/libavcodec/x86/vp9mc.asm
similarity index 99%
rename from libavcodec/x86/vp9dsp.asm
rename to libavcodec/x86/vp9mc.asm
index f81ac72..21c38b4 100644
--- a/libavcodec/x86/vp9dsp.asm
+++ b/libavcodec/x86/vp9mc.asm
@@ -1,5 +1,5 @@
;******************************************************************************
-;* VP9 SIMD optimizations
+;* VP9 MC SIMD optimizations
;*
;* Copyright (c) 2013 Ronald S. Bultje <rsbultje gmail com>
;*
diff --git a/libavcodec/xan.c b/libavcodec/xan.c
index 1c2e97c..7489113 100644
--- a/libavcodec/xan.c
+++ b/libavcodec/xan.c
@@ -71,7 +71,18 @@
} XanContext;
-static av_cold int xan_decode_end(AVCodecContext *avctx);
+static av_cold int xan_decode_end(AVCodecContext *avctx)
+{
+ XanContext *s = avctx->priv_data;
+
+ av_frame_free(&s->last_frame);
+
+ av_freep(&s->buffer1);
+ av_freep(&s->buffer2);
+ av_freep(&s->palettes);
+
+ return 0;
+}
static av_cold int xan_decode_init(AVCodecContext *avctx)
{
@@ -92,6 +103,7 @@
av_freep(&s->buffer1);
return AVERROR(ENOMEM);
}
+
s->last_frame = av_frame_alloc();
if (!s->last_frame) {
xan_decode_end(avctx);
@@ -111,12 +123,11 @@
uint8_t val = ival;
uint8_t *dest_end = dest + dest_len;
uint8_t *dest_start = dest;
+ int ret;
GetBitContext gb;
- if (ptr_len < 0)
- return AVERROR_INVALIDDATA;
-
- init_get_bits(&gb, ptr, ptr_len * 8);
+ if ((ret = init_get_bits8(&gb, ptr, ptr_len)) < 0)
+ return ret;
while (val != 0x16) {
unsigned idx = val - 0x17 + get_bits1(&gb) * byte;
@@ -624,19 +635,6 @@
return buf_size;
}
-static av_cold int xan_decode_end(AVCodecContext *avctx)
-{
- XanContext *s = avctx->priv_data;
-
- av_frame_free(&s->last_frame);
-
- av_freep(&s->buffer1);
- av_freep(&s->buffer2);
- av_freep(&s->palettes);
-
- return 0;
-}
-
AVCodec ff_xan_wc3_decoder = {
.name = "xan_wc3",
.long_name = NULL_IF_CONFIG_SMALL("Wing Commander III / Xan"),
diff --git a/libavcodec/xfaceenc.c b/libavcodec/xfaceenc.c
index e737f6d..e213c9d 100644
--- a/libavcodec/xfaceenc.c
+++ b/libavcodec/xfaceenc.c
@@ -125,7 +125,7 @@
static av_cold int xface_encode_init(AVCodecContext *avctx)
{
- avctx->coded_frame = avcodec_alloc_frame();
+ avctx->coded_frame = av_frame_alloc();
if (!avctx->coded_frame)
return AVERROR(ENOMEM);
avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
diff --git a/libavcodec/xsubenc.c b/libavcodec/xsubenc.c
index 9dc80ee..53f4d6c 100644
--- a/libavcodec/xsubenc.c
+++ b/libavcodec/xsubenc.c
@@ -166,8 +166,8 @@
bytestream_put_le16(&hdr, height);
bytestream_put_le16(&hdr, h->rects[0]->x);
bytestream_put_le16(&hdr, h->rects[0]->y);
- bytestream_put_le16(&hdr, h->rects[0]->x + width);
- bytestream_put_le16(&hdr, h->rects[0]->y + height);
+ bytestream_put_le16(&hdr, h->rects[0]->x + width -1);
+ bytestream_put_le16(&hdr, h->rects[0]->y + height -1);
rlelenptr = hdr; // Will store length of first field here later.
hdr+=2;
@@ -206,6 +206,8 @@
if (!avctx->codec_tag)
avctx->codec_tag = MKTAG('D','X','S','B');
+ avctx->bits_per_coded_sample = 4;
+
return 0;
}
diff --git a/libavcodec/xvmc.h b/libavcodec/xvmc.h
index b2bf518..efd69fc 100644
--- a/libavcodec/xvmc.h
+++ b/libavcodec/xvmc.h
@@ -29,8 +29,12 @@
#include <X11/extensions/XvMC.h>
+#include "libavutil/attributes.h"
+#include "version.h"
#include "avcodec.h"
+#if FF_API_XVMC
+
/**
* @defgroup lavc_codec_hwaccel_xvmc XvMC
* @ingroup lavc_codec_hwaccel
@@ -41,7 +45,7 @@
#define AV_XVMC_ID 0x1DC711C0 /**< special value to ensure that regular pixel routines haven't corrupted the struct
the number is 1337 speak for the letters IDCT MCo (motion compensation) */
-struct xvmc_pix_fmt {
+attribute_deprecated struct xvmc_pix_fmt {
/** The field contains the special constant value AV_XVMC_ID.
It is used as a test that the application correctly uses the API,
and that there is no corruption caused by pixel routines.
@@ -165,4 +169,6 @@
* @}
*/
+#endif /* FF_API_XVMC */
+
#endif /* AVCODEC_XVMC_H */
diff --git a/libavcodec/xvmc_internal.h b/libavcodec/xvmc_internal.h
index 04197ce..6a60add 100644
--- a/libavcodec/xvmc_internal.h
+++ b/libavcodec/xvmc_internal.h
@@ -23,6 +23,9 @@
#include "avcodec.h"
#include "mpegvideo.h"
+#include "version.h"
+
+#if FF_API_XVMC
void ff_xvmc_init_block(MpegEncContext *s);
void ff_xvmc_pack_pblocks(MpegEncContext *s, int cbp);
@@ -30,4 +33,6 @@
void ff_xvmc_field_end(MpegEncContext *s);
void ff_xvmc_decode_mb(MpegEncContext *s);
+#endif /* FF_API_XVMC */
+
#endif /* AVCODEC_XVMC_INTERNAL_H */
diff --git a/libavcodec/xxan.c b/libavcodec/xxan.c
index 56d5f49..b261cdf 100644
--- a/libavcodec/xxan.c
+++ b/libavcodec/xxan.c
@@ -38,7 +38,17 @@
GetByteContext gb;
} XanContext;
-static av_cold int xan_decode_end(AVCodecContext *avctx);
+static av_cold int xan_decode_end(AVCodecContext *avctx)
+{
+ XanContext *s = avctx->priv_data;
+
+ av_frame_free(&s->pic);
+
+ av_freep(&s->y_buffer);
+ av_freep(&s->scratch_buffer);
+
+ return 0;
+}
static av_cold int xan_decode_init(AVCodecContext *avctx)
{
@@ -428,18 +438,6 @@
return avpkt->size;
}
-static av_cold int xan_decode_end(AVCodecContext *avctx)
-{
- XanContext *s = avctx->priv_data;
-
- av_frame_free(&s->pic);
-
- av_freep(&s->y_buffer);
- av_freep(&s->scratch_buffer);
-
- return 0;
-}
-
AVCodec ff_xan_wc4_decoder = {
.name = "xan_wc4",
.long_name = NULL_IF_CONFIG_SMALL("Wing Commander IV / Xxan"),
diff --git a/libavcodec/y41penc.c b/libavcodec/y41penc.c
index 41666cc..8f67944 100644
--- a/libavcodec/y41penc.c
+++ b/libavcodec/y41penc.c
@@ -30,7 +30,7 @@
return AVERROR_INVALIDDATA;
}
- avctx->coded_frame = avcodec_alloc_frame();
+ avctx->coded_frame = av_frame_alloc();
avctx->bits_per_coded_sample = 12;
if (!avctx->coded_frame) {
diff --git a/libavcodec/yuv4enc.c b/libavcodec/yuv4enc.c
index 8d3907b..ed0fc77 100644
--- a/libavcodec/yuv4enc.c
+++ b/libavcodec/yuv4enc.c
@@ -25,7 +25,7 @@
static av_cold int yuv4_encode_init(AVCodecContext *avctx)
{
- avctx->coded_frame = avcodec_alloc_frame();
+ avctx->coded_frame = av_frame_alloc();
if (!avctx->coded_frame) {
av_log(avctx, AV_LOG_ERROR, "Could not allocate frame.\n");
diff --git a/libavcodec/zerocodec.c b/libavcodec/zerocodec.c
index 80264b3..9f6c37c 100644
--- a/libavcodec/zerocodec.c
+++ b/libavcodec/zerocodec.c
@@ -23,7 +23,7 @@
#include "libavutil/common.h"
typedef struct {
- AVFrame previous_frame;
+ AVFrame *previous_frame;
z_stream zstream;
} ZeroCodecContext;
@@ -32,7 +32,7 @@
{
ZeroCodecContext *zc = avctx->priv_data;
AVFrame *pic = data;
- AVFrame *prev_pic = &zc->previous_frame;
+ AVFrame *prev_pic = zc->previous_frame;
z_stream *zstream = &zc->zstream;
uint8_t *prev = prev_pic->data[0];
uint8_t *dst;
@@ -91,8 +91,8 @@
dst -= pic->linesize[0];
}
- av_frame_unref(&zc->previous_frame);
- if ((ret = av_frame_ref(&zc->previous_frame, pic)) < 0)
+ av_frame_unref(zc->previous_frame);
+ if ((ret = av_frame_ref(zc->previous_frame, pic)) < 0)
return ret;
*got_frame = 1;
@@ -104,7 +104,7 @@
{
ZeroCodecContext *zc = avctx->priv_data;
- av_frame_unref(&zc->previous_frame);
+ av_frame_free(&zc->previous_frame);
inflateEnd(&zc->zstream);
@@ -130,6 +130,12 @@
return AVERROR(ENOMEM);
}
+ zc->previous_frame = av_frame_alloc();
+ if (!zc->previous_frame) {
+ zerocodec_decode_close(avctx);
+ return AVERROR(ENOMEM);
+ }
+
return 0;
}
diff --git a/libavcodec/zmbvenc.c b/libavcodec/zmbvenc.c
index 2907c99..28dbe20 100644
--- a/libavcodec/zmbvenc.c
+++ b/libavcodec/zmbvenc.c
@@ -44,6 +44,7 @@
*/
typedef struct ZmbvEncContext {
AVCodecContext *avctx;
+
int range;
uint8_t *comp_buf, *work_buf;
uint8_t pal[768];
@@ -119,7 +120,7 @@
const AVFrame *pict, int *got_packet)
{
ZmbvEncContext * const c = avctx->priv_data;
- AVFrame * const p = (AVFrame *)pict;
+ const AVFrame * const p = pict;
uint8_t *src, *prev, *buf;
uint32_t *palptr;
int keyframe, chpal;
@@ -132,8 +133,8 @@
c->curfrm++;
if(c->curfrm == c->keyint)
c->curfrm = 0;
- p->pict_type= keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P;
- p->key_frame= keyframe;
+ avctx->coded_frame->pict_type = keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P;
+ avctx->coded_frame->key_frame = keyframe;
chpal = !keyframe && memcmp(p->data[1], c->pal2, 1024);
palptr = (uint32_t*)p->data[1];
@@ -248,6 +249,20 @@
return 0;
}
+static av_cold int encode_end(AVCodecContext *avctx)
+{
+ ZmbvEncContext * const c = avctx->priv_data;
+
+ av_freep(&c->comp_buf);
+ av_freep(&c->work_buf);
+
+ deflateEnd(&c->zstream);
+ av_freep(&c->prev);
+
+ av_frame_free(&avctx->coded_frame);
+
+ return 0;
+}
/**
* Init zmbv encoder
@@ -309,23 +324,11 @@
return -1;
}
- return 0;
-}
-
-
-
-/**
- * Uninit zmbv encoder
- */
-static av_cold int encode_end(AVCodecContext *avctx)
-{
- ZmbvEncContext * const c = avctx->priv_data;
-
- av_freep(&c->comp_buf);
- av_freep(&c->work_buf);
-
- deflateEnd(&c->zstream);
- av_freep(&c->prev);
+ avctx->coded_frame = av_frame_alloc();
+ if (!avctx->coded_frame) {
+ encode_end(avctx);
+ return AVERROR(ENOMEM);
+ }
return 0;
}
diff --git a/libavdevice/Makefile b/libavdevice/Makefile
index ad959ee..531818a 100644
--- a/libavdevice/Makefile
+++ b/libavdevice/Makefile
@@ -10,8 +10,6 @@
OBJS = alldevices.o \
avdevice.o \
-OBJS-$(HAVE_MSVCRT) += file_open.o
-
# input/output devices
OBJS-$(CONFIG_ALSA_INDEV) += alsa-audio-common.o \
alsa-audio-dec.o timefilter.o
@@ -23,7 +21,10 @@
dshow_enumpins.o dshow_filter.o \
dshow_pin.o dshow_common.o
OBJS-$(CONFIG_DV1394_INDEV) += dv1394.o
-OBJS-$(CONFIG_FBDEV_INDEV) += fbdev.o
+OBJS-$(CONFIG_FBDEV_INDEV) += fbdev_dec.o \
+ fbdev_common.o
+OBJS-$(CONFIG_FBDEV_OUTDEV) += fbdev_enc.o \
+ fbdev_common.o
OBJS-$(CONFIG_IEC61883_INDEV) += iec61883.o
OBJS-$(CONFIG_JACK_INDEV) += jack_audio.o timefilter.o
OBJS-$(CONFIG_LAVFI_INDEV) += lavfi.o
@@ -48,6 +49,11 @@
OBJS-$(CONFIG_LIBCDIO_INDEV) += libcdio.o
OBJS-$(CONFIG_LIBDC1394_INDEV) += libdc1394.o
+OBJS-$(HAVE_LIBC_MSVCRT) += file_open.o
+
+# Windows resource file
+SLIBOBJS-$(HAVE_GNU_WINDRES) += avdeviceres.o
+
SKIPHEADERS-$(CONFIG_DSHOW_INDEV) += dshow_capture.h
SKIPHEADERS-$(CONFIG_LIBPULSE) += pulse_audio_common.h
SKIPHEADERS-$(CONFIG_V4L2_INDEV) += v4l2-common.h
diff --git a/libavdevice/alldevices.c b/libavdevice/alldevices.c
index 33ce155..5178f30 100644
--- a/libavdevice/alldevices.c
+++ b/libavdevice/alldevices.c
@@ -51,7 +51,7 @@
REGISTER_OUTDEV (CACA, caca);
REGISTER_INDEV (DSHOW, dshow);
REGISTER_INDEV (DV1394, dv1394);
- REGISTER_INDEV (FBDEV, fbdev);
+ REGISTER_INOUTDEV(FBDEV, fbdev);
REGISTER_INDEV (IEC61883, iec61883);
REGISTER_INDEV (JACK, jack);
REGISTER_INDEV (LAVFI, lavfi);
diff --git a/libavdevice/alsa-audio-enc.c b/libavdevice/alsa-audio-enc.c
index 0f4e4a2..83e1d2f 100644
--- a/libavdevice/alsa-audio-enc.c
+++ b/libavdevice/alsa-audio-enc.c
@@ -47,12 +47,17 @@
static av_cold int audio_write_header(AVFormatContext *s1)
{
AlsaData *s = s1->priv_data;
- AVStream *st;
+ AVStream *st = NULL;
unsigned int sample_rate;
enum AVCodecID codec_id;
int res;
+ if (s1->nb_streams != 1 || s1->streams[0]->codec->codec_type != AVMEDIA_TYPE_AUDIO) {
+ av_log(s1, AV_LOG_ERROR, "Only a single audio stream is supported.\n");
+ return AVERROR(EINVAL);
+ }
st = s1->streams[0];
+
sample_rate = st->codec->sample_rate;
codec_id = st->codec->codec_id;
res = ff_alsa_open(s1, SND_PCM_STREAM_PLAYBACK, &sample_rate,
@@ -80,6 +85,10 @@
uint8_t *buf = pkt->data;
size /= s->frame_size;
+ if (pkt->dts != AV_NOPTS_VALUE)
+ s->timestamp = pkt->dts;
+ s->timestamp += pkt->duration ? pkt->duration : size;
+
if (s->reorder_func) {
if (size > s->reorder_buf_size)
if (ff_alsa_extend_reorder_buf(s, size))
@@ -112,7 +121,7 @@
snd_pcm_sframes_t delay = 0;
*wall = av_gettime();
snd_pcm_delay(s->h, &delay);
- *dts = s1->streams[0]->cur_dts - delay;
+ *dts = s->timestamp - delay;
}
AVOutputFormat ff_alsa_muxer = {
diff --git a/libavdevice/alsa-audio.h b/libavdevice/alsa-audio.h
index 44b7c72..583c911 100644
--- a/libavdevice/alsa-audio.h
+++ b/libavdevice/alsa-audio.h
@@ -57,6 +57,7 @@
void (*reorder_func)(const void *, void *, int);
void *reorder_buf;
int reorder_buf_size; ///< in frames
+ int64_t timestamp; ///< current timestamp, without latency applied.
} AlsaData;
/**
diff --git a/libavdevice/avdeviceres.rc b/libavdevice/avdeviceres.rc
new file mode 100644
index 0000000..e13e73d
--- /dev/null
+++ b/libavdevice/avdeviceres.rc
@@ -0,0 +1,55 @@
+/*
+ * Windows resource file for libavdevice
+ *
+ * Copyright (C) 2012 James Almer
+ * Copyright (C) 2013 Tiancheng "Timothy" Gu
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <windows.h>
+#include "libavdevice/version.h"
+#include "libavutil/ffversion.h"
+#include "config.h"
+
+1 VERSIONINFO
+FILEVERSION LIBAVDEVICE_VERSION_MAJOR, LIBAVDEVICE_VERSION_MINOR, LIBAVDEVICE_VERSION_MICRO, 0
+PRODUCTVERSION LIBAVDEVICE_VERSION_MAJOR, LIBAVDEVICE_VERSION_MINOR, LIBAVDEVICE_VERSION_MICRO, 0
+FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+FILEOS VOS_NT_WINDOWS32
+FILETYPE VFT_DLL
+{
+ BLOCK "StringFileInfo"
+ {
+ BLOCK "040904B0"
+ {
+ VALUE "CompanyName", "FFmpeg Project"
+ VALUE "FileDescription", "FFmpeg device handling library"
+ VALUE "FileVersion", AV_STRINGIFY(LIBAVDEVICE_VERSION)
+ VALUE "InternalName", "libavdevice"
+ VALUE "LegalCopyright", "Copyright (C) 2000-" AV_STRINGIFY(CONFIG_THIS_YEAR) " FFmpeg Project"
+ VALUE "OriginalFilename", "avdevice" BUILDSUF "-" AV_STRINGIFY(LIBAVDEVICE_VERSION_MAJOR) SLIBSUF
+ VALUE "ProductName", "FFmpeg"
+ VALUE "ProductVersion", FFMPEG_VERSION
+ }
+ }
+
+ BLOCK "VarFileInfo"
+ {
+ VALUE "Translation", 0x0409, 0x04B0
+ }
+}
diff --git a/libavdevice/fbdev_common.c b/libavdevice/fbdev_common.c
new file mode 100644
index 0000000..45ae08b
--- /dev/null
+++ b/libavdevice/fbdev_common.c
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2011 Stefano Sabatini
+ * Copyright (c) 2009 Giliard B. de Freitas <giliarde@gmail.com>
+ * Copyright (C) 2002 Gunnar Monell <gmo@linux.nu>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdlib.h>
+#include "fbdev_common.h"
+#include "libavutil/common.h"
+
+struct rgb_pixfmt_map_entry {
+ int bits_per_pixel;
+ int red_offset, green_offset, blue_offset, alpha_offset;
+ enum AVPixelFormat pixfmt;
+};
+
+static const struct rgb_pixfmt_map_entry rgb_pixfmt_map[] = {
+ // bpp, red_offset, green_offset, blue_offset, alpha_offset, pixfmt
+ { 32, 0, 8, 16, 24, AV_PIX_FMT_RGBA },
+ { 32, 16, 8, 0, 24, AV_PIX_FMT_BGRA },
+ { 32, 8, 16, 24, 0, AV_PIX_FMT_ARGB },
+ { 32, 3, 2, 8, 0, AV_PIX_FMT_ABGR },
+ { 24, 0, 8, 16, 0, AV_PIX_FMT_RGB24 },
+ { 24, 16, 8, 0, 0, AV_PIX_FMT_BGR24 },
+ { 16, 11, 5, 0, 16, AV_PIX_FMT_RGB565 },
+};
+
+enum AVPixelFormat ff_get_pixfmt_from_fb_varinfo(struct fb_var_screeninfo *varinfo)
+{
+ int i;
+
+ for (i = 0; i < FF_ARRAY_ELEMS(rgb_pixfmt_map); i++) {
+ const struct rgb_pixfmt_map_entry *entry = &rgb_pixfmt_map[i];
+ if (entry->bits_per_pixel == varinfo->bits_per_pixel &&
+ entry->red_offset == varinfo->red.offset &&
+ entry->green_offset == varinfo->green.offset &&
+ entry->blue_offset == varinfo->blue.offset)
+ return entry->pixfmt;
+ }
+
+ return AV_PIX_FMT_NONE;
+}
+
+const char* ff_fbdev_default_device()
+{
+ const char *dev = getenv("FRAMEBUFFER");
+ if (!dev)
+ dev = "/dev/fb0";
+ return dev;
+}
+
diff --git a/libavdevice/fbdev_common.h b/libavdevice/fbdev_common.h
new file mode 100644
index 0000000..40a1ded
--- /dev/null
+++ b/libavdevice/fbdev_common.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2011 Stefano Sabatini
+ * Copyright (c) 2009 Giliard B. de Freitas <giliarde@gmail.com>
+ * Copyright (C) 2002 Gunnar Monell <gmo@linux.nu>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVDEVICE_FBDEV_COMMON_H
+#define AVDEVICE_FBDEV_COMMON_H
+
+#include <features.h>
+#include <linux/fb.h>
+#include "libavutil/pixfmt.h"
+
+enum AVPixelFormat ff_get_pixfmt_from_fb_varinfo(struct fb_var_screeninfo *varinfo);
+
+const char* ff_fbdev_default_device(void);
+
+#endif /* AVDEVICE_FBDEV_COMMON_H */
diff --git a/libavdevice/fbdev.c b/libavdevice/fbdev_dec.c
similarity index 79%
rename from libavdevice/fbdev.c
rename to libavdevice/fbdev_dec.c
index 1156fb5..14ebab3 100644
--- a/libavdevice/fbdev.c
+++ b/libavdevice/fbdev_dec.c
@@ -41,41 +41,9 @@
#include "libavutil/time.h"
#include "libavutil/parseutils.h"
#include "libavutil/pixdesc.h"
-#include "avdevice.h"
#include "libavformat/internal.h"
-
-struct rgb_pixfmt_map_entry {
- int bits_per_pixel;
- int red_offset, green_offset, blue_offset, alpha_offset;
- enum AVPixelFormat pixfmt;
-};
-
-static const struct rgb_pixfmt_map_entry rgb_pixfmt_map[] = {
- // bpp, red_offset, green_offset, blue_offset, alpha_offset, pixfmt
- { 32, 0, 8, 16, 24, AV_PIX_FMT_RGBA },
- { 32, 16, 8, 0, 24, AV_PIX_FMT_BGRA },
- { 32, 8, 16, 24, 0, AV_PIX_FMT_ARGB },
- { 32, 3, 2, 8, 0, AV_PIX_FMT_ABGR },
- { 24, 0, 8, 16, 0, AV_PIX_FMT_RGB24 },
- { 24, 16, 8, 0, 0, AV_PIX_FMT_BGR24 },
- { 16, 11, 5, 0, 16, AV_PIX_FMT_RGB565 },
-};
-
-static enum AVPixelFormat get_pixfmt_from_fb_varinfo(struct fb_var_screeninfo *varinfo)
-{
- int i;
-
- for (i = 0; i < FF_ARRAY_ELEMS(rgb_pixfmt_map); i++) {
- const struct rgb_pixfmt_map_entry *entry = &rgb_pixfmt_map[i];
- if (entry->bits_per_pixel == varinfo->bits_per_pixel &&
- entry->red_offset == varinfo->red.offset &&
- entry->green_offset == varinfo->green.offset &&
- entry->blue_offset == varinfo->blue.offset)
- return entry->pixfmt;
- }
-
- return AV_PIX_FMT_NONE;
-}
+#include "avdevice.h"
+#include "fbdev_common.h"
typedef struct {
AVClass *class; ///< class for private options
@@ -113,25 +81,25 @@
ret = AVERROR(errno);
av_log(avctx, AV_LOG_ERROR,
"Could not open framebuffer device '%s': %s\n",
- avctx->filename, strerror(ret));
+ avctx->filename, av_err2str(ret));
return ret;
}
if (ioctl(fbdev->fd, FBIOGET_VSCREENINFO, &fbdev->varinfo) < 0) {
ret = AVERROR(errno);
av_log(avctx, AV_LOG_ERROR,
- "FBIOGET_VSCREENINFO: %s\n", strerror(errno));
+ "FBIOGET_VSCREENINFO: %s\n", av_err2str(ret));
goto fail;
}
if (ioctl(fbdev->fd, FBIOGET_FSCREENINFO, &fbdev->fixinfo) < 0) {
ret = AVERROR(errno);
av_log(avctx, AV_LOG_ERROR,
- "FBIOGET_FSCREENINFO: %s\n", strerror(errno));
+ "FBIOGET_FSCREENINFO: %s\n", av_err2str(ret));
goto fail;
}
- pix_fmt = get_pixfmt_from_fb_varinfo(&fbdev->varinfo);
+ pix_fmt = ff_get_pixfmt_from_fb_varinfo(&fbdev->varinfo);
if (pix_fmt == AV_PIX_FMT_NONE) {
ret = AVERROR(EINVAL);
av_log(avctx, AV_LOG_ERROR,
@@ -148,7 +116,7 @@
fbdev->data = mmap(NULL, fbdev->fixinfo.smem_len, PROT_READ, MAP_SHARED, fbdev->fd, 0);
if (fbdev->data == MAP_FAILED) {
ret = AVERROR(errno);
- av_log(avctx, AV_LOG_ERROR, "Error in mmap(): %s\n", strerror(errno));
+ av_log(avctx, AV_LOG_ERROR, "Error in mmap(): %s\n", av_err2str(ret));
goto fail;
}
@@ -209,7 +177,7 @@
/* refresh fbdev->varinfo, visible data position may change at each call */
if (ioctl(fbdev->fd, FBIOGET_VSCREENINFO, &fbdev->varinfo) < 0)
av_log(avctx, AV_LOG_WARNING,
- "Error refreshing variable info: %s\n", strerror(errno));
+ "Error refreshing variable info: %s\n", av_err2str(ret));
pkt->pts = curtime;
@@ -231,7 +199,7 @@
{
FBDevContext *fbdev = avctx->priv_data;
- munmap(fbdev->data, fbdev->frame_size);
+ munmap(fbdev->data, fbdev->fixinfo.smem_len);
close(fbdev->fd);
return 0;
diff --git a/libavdevice/fbdev_enc.c b/libavdevice/fbdev_enc.c
new file mode 100644
index 0000000..8291b59
--- /dev/null
+++ b/libavdevice/fbdev_enc.c
@@ -0,0 +1,212 @@
+/*
+ * Copyright (c) 2013 Lukasz Marek
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <linux/fb.h>
+#include "libavutil/pixdesc.h"
+#include "libavutil/log.h"
+#include "libavutil/mem.h"
+#include "libavutil/opt.h"
+#include "libavformat/avformat.h"
+#include "fbdev_common.h"
+
+typedef struct {
+ AVClass *class; ///< class for private options
+ int xoffset; ///< x coordinate of top left corner
+ int yoffset; ///< y coordinate of top left corner
+ struct fb_var_screeninfo varinfo; ///< framebuffer variable info
+ struct fb_fix_screeninfo fixinfo; ///< framebuffer fixed info
+ int fd; ///< framebuffer device file descriptor
+ uint8_t *data; ///< framebuffer data
+} FBDevContext;
+
+static av_cold int fbdev_write_header(AVFormatContext *h)
+{
+ FBDevContext *fbdev = h->priv_data;
+ enum AVPixelFormat pix_fmt;
+ int ret, flags = O_RDWR;
+ const char* device;
+
+ if (h->nb_streams != 1 || h->streams[0]->codec->codec_type != AVMEDIA_TYPE_VIDEO) {
+ av_log(fbdev, AV_LOG_ERROR, "Only a single video stream is supported.\n");
+ return AVERROR(EINVAL);
+ }
+
+ if (h->filename[0])
+ device = h->filename;
+ else
+ device = ff_fbdev_default_device();
+
+ if ((fbdev->fd = avpriv_open(device, flags)) == -1) {
+ ret = AVERROR(errno);
+ av_log(h, AV_LOG_ERROR,
+ "Could not open framebuffer device '%s': %s\n",
+ device, av_err2str(ret));
+ return ret;
+ }
+
+ if (ioctl(fbdev->fd, FBIOGET_VSCREENINFO, &fbdev->varinfo) < 0) {
+ ret = AVERROR(errno);
+ av_log(h, AV_LOG_ERROR, "FBIOGET_VSCREENINFO: %s\n", av_err2str(ret));
+ goto fail;
+ }
+
+ if (ioctl(fbdev->fd, FBIOGET_FSCREENINFO, &fbdev->fixinfo) < 0) {
+ ret = AVERROR(errno);
+ av_log(h, AV_LOG_ERROR, "FBIOGET_FSCREENINFO: %s\n", av_err2str(ret));
+ goto fail;
+ }
+
+ pix_fmt = ff_get_pixfmt_from_fb_varinfo(&fbdev->varinfo);
+ if (pix_fmt == AV_PIX_FMT_NONE) {
+ ret = AVERROR(EINVAL);
+ av_log(h, AV_LOG_ERROR, "Framebuffer pixel format not supported.\n");
+ goto fail;
+ }
+
+ fbdev->data = mmap(NULL, fbdev->fixinfo.smem_len, PROT_WRITE, MAP_SHARED, fbdev->fd, 0);
+ if (fbdev->data == MAP_FAILED) {
+ ret = AVERROR(errno);
+ av_log(h, AV_LOG_ERROR, "Error in mmap(): %s\n", av_err2str(ret));
+ goto fail;
+ }
+
+ return 0;
+ fail:
+ close(fbdev->fd);
+ return ret;
+}
+
+static int fbdev_write_packet(AVFormatContext *h, AVPacket *pkt)
+{
+ FBDevContext *fbdev = h->priv_data;
+ uint8_t *pin, *pout;
+ enum AVPixelFormat fb_pix_fmt;
+ int disp_height;
+ int bytes_to_copy;
+ AVCodecContext *codec_ctx = h->streams[0]->codec;
+ enum AVPixelFormat video_pix_fmt = codec_ctx->pix_fmt;
+ int video_width = codec_ctx->width;
+ int video_height = codec_ctx->height;
+ int bytes_per_pixel = ((codec_ctx->bits_per_coded_sample + 7) >> 3);
+ int src_line_size = video_width * bytes_per_pixel;
+ int i;
+
+ if (ioctl(fbdev->fd, FBIOGET_VSCREENINFO, &fbdev->varinfo) < 0)
+ av_log(h, AV_LOG_WARNING,
+ "Error refreshing variable info: %s\n", av_err2str(AVERROR(errno)));
+
+ fb_pix_fmt = ff_get_pixfmt_from_fb_varinfo(&fbdev->varinfo);
+
+ if (fb_pix_fmt != video_pix_fmt) {
+ av_log(h, AV_LOG_ERROR, "Pixel format %s is not supported, use %s\n",
+ av_get_pix_fmt_name(video_pix_fmt), av_get_pix_fmt_name(fb_pix_fmt));
+ return AVERROR(EINVAL);
+ }
+
+ disp_height = FFMIN(fbdev->varinfo.yres, video_height);
+ bytes_to_copy = FFMIN(fbdev->varinfo.xres, video_width) * bytes_per_pixel;
+
+ pin = pkt->data;
+ pout = fbdev->data +
+ bytes_per_pixel * fbdev->varinfo.xoffset +
+ fbdev->varinfo.yoffset * fbdev->fixinfo.line_length;
+
+ if (fbdev->xoffset) {
+ if (fbdev->xoffset < 0) {
+ if (-fbdev->xoffset >= video_width) //nothing to display
+ return 0;
+ bytes_to_copy += fbdev->xoffset * bytes_per_pixel;
+ pin -= fbdev->xoffset * bytes_per_pixel;
+ } else {
+ int diff = (video_width + fbdev->xoffset) - fbdev->varinfo.xres;
+ if (diff > 0) {
+ if (diff >= video_width) //nothing to display
+ return 0;
+ bytes_to_copy -= diff * bytes_per_pixel;
+ }
+ pout += bytes_per_pixel * fbdev->xoffset;
+ }
+ }
+
+ if (fbdev->yoffset) {
+ if (fbdev->yoffset < 0) {
+ if (-fbdev->yoffset >= video_height) //nothing to display
+ return 0;
+ disp_height += fbdev->yoffset;
+ pin -= fbdev->yoffset * src_line_size;
+ } else {
+ int diff = (video_height + fbdev->yoffset) - fbdev->varinfo.yres;
+ if (diff > 0) {
+ if (diff >= video_height) //nothing to display
+ return 0;
+ disp_height -= diff;
+ }
+ pout += fbdev->yoffset * fbdev->fixinfo.line_length;
+ }
+ }
+
+ for (i = 0; i < disp_height; i++) {
+ memcpy(pout, pin, bytes_to_copy);
+ pout += fbdev->fixinfo.line_length;
+ pin += src_line_size;
+ }
+
+ return 0;
+}
+
+static av_cold int fbdev_write_trailer(AVFormatContext *h)
+{
+ FBDevContext *fbdev = h->priv_data;
+ munmap(fbdev->data, fbdev->fixinfo.smem_len);
+ close(fbdev->fd);
+ return 0;
+}
+
+#define OFFSET(x) offsetof(FBDevContext, x)
+#define ENC AV_OPT_FLAG_ENCODING_PARAM
+static const AVOption options[] = {
+ { "xoffset", "set x coordinate of top left corner", OFFSET(xoffset), AV_OPT_TYPE_INT, {.i64 = 0}, INT_MIN, INT_MAX, ENC },
+ { "yoffset", "set y coordinate of top left corner", OFFSET(yoffset), AV_OPT_TYPE_INT, {.i64 = 0}, INT_MIN, INT_MAX, ENC },
+ { NULL }
+};
+
+static const AVClass fbdev_class = {
+ .class_name = "fbdev outdev",
+ .item_name = av_default_item_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
+AVOutputFormat ff_fbdev_muxer = {
+ .name = "fbdev",
+ .long_name = NULL_IF_CONFIG_SMALL("Linux framebuffer"),
+ .priv_data_size = sizeof(FBDevContext),
+ .audio_codec = AV_CODEC_ID_NONE,
+ .video_codec = AV_CODEC_ID_RAWVIDEO,
+ .write_header = fbdev_write_header,
+ .write_packet = fbdev_write_packet,
+ .write_trailer = fbdev_write_trailer,
+ .flags = AVFMT_NOFILE | AVFMT_VARIABLE_FPS | AVFMT_NOTIMESTAMPS,
+ .priv_class = &fbdev_class,
+};
diff --git a/libavdevice/jack_audio.c b/libavdevice/jack_audio.c
index bd6a770..5ba6731 100644
--- a/libavdevice/jack_audio.c
+++ b/libavdevice/jack_audio.c
@@ -188,6 +188,10 @@
/* Create time filter */
self->timefilter = ff_timefilter_new (1.0 / self->sample_rate, self->buffer_size, 1.5);
+ if (!self->timefilter) {
+ jack_client_close(self->client);
+ return AVERROR(ENOMEM);
+ }
/* Create FIFO buffers */
self->filled_pkts = av_fifo_alloc(FIFO_PACKETS_NUM * sizeof(AVPacket));
diff --git a/libavdevice/lavfi.c b/libavdevice/lavfi.c
index 559f721..a177ad0 100644
--- a/libavdevice/lavfi.c
+++ b/libavdevice/lavfi.c
@@ -248,6 +248,10 @@
ret = av_opt_set_int_list(sink, "sample_fmts", sample_fmts, AV_SAMPLE_FMT_NONE, AV_OPT_SEARCH_CHILDREN);
if (ret < 0)
goto end;
+ ret = av_opt_set_int(sink, "all_channel_counts", 1,
+ AV_OPT_SEARCH_CHILDREN);
+ if (ret < 0)
+ goto end;
}
lavfi->sinks[i] = sink;
diff --git a/libavdevice/pulse_audio_common.c b/libavdevice/pulse_audio_common.c
index bbc8c97..f7227f6 100644
--- a/libavdevice/pulse_audio_common.c
+++ b/libavdevice/pulse_audio_common.c
@@ -19,11 +19,10 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include "libavutil/attributes.h"
-#include "libavcodec/avcodec.h"
#include "pulse_audio_common.h"
+#include "libavutil/attributes.h"
-pa_sample_format_t av_cold codec_id_to_pulse_format(int codec_id)
+pa_sample_format_t av_cold ff_codec_id_to_pulse_format(enum AVCodecID codec_id)
{
switch (codec_id) {
case AV_CODEC_ID_PCM_U8: return PA_SAMPLE_U8;
diff --git a/libavdevice/pulse_audio_common.h b/libavdevice/pulse_audio_common.h
index e4409ba..99ba6a3 100644
--- a/libavdevice/pulse_audio_common.h
+++ b/libavdevice/pulse_audio_common.h
@@ -23,7 +23,8 @@
#define AVDEVICE_PULSE_AUDIO_COMMON_H
#include <pulse/simple.h>
+#include "libavcodec/avcodec.h"
-pa_sample_format_t codec_id_to_pulse_format(int codec_id);
+pa_sample_format_t ff_codec_id_to_pulse_format(enum AVCodecID codec_id);
#endif /* AVDEVICE_PULSE_AUDIO_COMMON_H */
diff --git a/libavdevice/pulse_audio_dec.c b/libavdevice/pulse_audio_dec.c
index 21b3caa..639b381 100644
--- a/libavdevice/pulse_audio_dec.c
+++ b/libavdevice/pulse_audio_dec.c
@@ -57,7 +57,7 @@
int ret;
enum AVCodecID codec_id =
s->audio_codec_id == AV_CODEC_ID_NONE ? DEFAULT_CODEC_ID : s->audio_codec_id;
- const pa_sample_spec ss = { codec_id_to_pulse_format(codec_id),
+ const pa_sample_spec ss = { ff_codec_id_to_pulse_format(codec_id),
pd->sample_rate,
pd->channels };
@@ -144,13 +144,13 @@
#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 = LIBAVFORMAT_IDENT}, 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, {.i64 = 48000}, 1, INT_MAX, D },
- { "channels", "number of audio channels", OFFSET(channels), AV_OPT_TYPE_INT, {.i64 = 2}, 1, INT_MAX, D },
- { "frame_size", "number of bytes per frame", OFFSET(frame_size), AV_OPT_TYPE_INT, {.i64 = 1024}, 1, INT_MAX, D },
- { "fragment_size", "buffering size, affects latency and cpu usage", OFFSET(fragment_size), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, D },
+ { "server", "set PulseAudio server", OFFSET(server), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, D },
+ { "name", "set application name", OFFSET(name), AV_OPT_TYPE_STRING, {.str = LIBAVFORMAT_IDENT}, 0, 0, D },
+ { "stream_name", "set stream description", OFFSET(stream_name), AV_OPT_TYPE_STRING, {.str = "record"}, 0, 0, D },
+ { "sample_rate", "set sample rate in Hz", OFFSET(sample_rate), AV_OPT_TYPE_INT, {.i64 = 48000}, 1, INT_MAX, D },
+ { "channels", "set number of audio channels", OFFSET(channels), AV_OPT_TYPE_INT, {.i64 = 2}, 1, INT_MAX, D },
+ { "frame_size", "set number of bytes per frame", OFFSET(frame_size), AV_OPT_TYPE_INT, {.i64 = 1024}, 1, INT_MAX, D },
+ { "fragment_size", "set buffering size, affects latency and cpu usage", OFFSET(fragment_size), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, D },
{ NULL },
};
diff --git a/libavdevice/pulse_audio_enc.c b/libavdevice/pulse_audio_enc.c
index 25caa65..e047299 100644
--- a/libavdevice/pulse_audio_enc.c
+++ b/libavdevice/pulse_audio_enc.c
@@ -34,7 +34,9 @@
const char *stream_name;
const char *device;
pa_simple *pa;
- unsigned int stream_index;
+ int64_t timestamp;
+ int buffer_size;
+ int buffer_duration;
} PulseData;
static av_cold int pulse_write_header(AVFormatContext *h)
@@ -46,23 +48,33 @@
pa_buffer_attr attr = { -1, -1, -1, -1, -1 };
const char *stream_name = s->stream_name;
- for (unsigned i = 0; i < h->nb_streams; i++) {
- if (h->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
- st = h->streams[i];
- s->stream_index = i;
- break;
- }
- }
-
- if (!st) {
- av_log(s, AV_LOG_ERROR, "No audio stream found.\n");
+ if (h->nb_streams != 1 || h->streams[0]->codec->codec_type != AVMEDIA_TYPE_AUDIO) {
+ av_log(s, AV_LOG_ERROR, "Only a single audio stream is supported.\n");
return AVERROR(EINVAL);
}
+ st = h->streams[0];
- if (!stream_name)
- stream_name = h->filename;
+ if (!stream_name) {
+ if (h->filename[0])
+ stream_name = h->filename;
+ else
+ stream_name = "Playback";
+ }
- ss.format = codec_id_to_pulse_format(st->codec->codec_id);
+ if (s->buffer_duration) {
+ int64_t bytes = s->buffer_duration;
+ bytes *= st->codec->channels * st->codec->sample_rate *
+ av_get_bytes_per_sample(st->codec->sample_fmt);
+ bytes /= 1000;
+ attr.tlength = FFMAX(s->buffer_size, av_clip64(bytes, 0, UINT32_MAX - 1));
+ av_log(s, AV_LOG_DEBUG,
+ "Buffer duration: %ums recalculated into %"PRId64" bytes buffer.\n",
+ s->buffer_duration, bytes);
+ av_log(s, AV_LOG_DEBUG, "Real buffer length is %u bytes\n", attr.tlength);
+ } else if (s->buffer_size)
+ attr.tlength = s->buffer_size;
+
+ ss.format = ff_codec_id_to_pulse_format(st->codec->codec_id);
ss.rate = st->codec->sample_rate;
ss.channels = st->codec->channels;
@@ -98,14 +110,30 @@
static int pulse_write_packet(AVFormatContext *h, AVPacket *pkt)
{
PulseData *s = h->priv_data;
- int size = pkt->size;
- uint8_t *buf = pkt->data;
int error;
- if (s->stream_index != pkt->stream_index)
- return 0;
+ if (!pkt) {
+ if (pa_simple_flush(s->pa, &error) < 0) {
+ av_log(s, AV_LOG_ERROR, "pa_simple_flush failed: %s\n", pa_strerror(error));
+ return AVERROR(EIO);
+ }
+ return 1;
+ }
- if ((error = pa_simple_write(s->pa, buf, size, &error))) {
+ if (pkt->dts != AV_NOPTS_VALUE)
+ s->timestamp = pkt->dts;
+
+ if (pkt->duration) {
+ s->timestamp += pkt->duration;
+ } else {
+ AVStream *st = h->streams[0];
+ AVCodecContext *codec_ctx = st->codec;
+ AVRational r = { 1, codec_ctx->sample_rate };
+ int64_t samples = pkt->size / (av_get_bytes_per_sample(codec_ctx->sample_fmt) * codec_ctx->channels);
+ s->timestamp += av_rescale_q(samples, r, st->time_base);
+ }
+
+ if (pa_simple_write(s->pa, pkt->data, pkt->size, &error) < 0) {
av_log(s, AV_LOG_ERROR, "pa_simple_write failed: %s\n", pa_strerror(error));
return AVERROR(EIO);
}
@@ -118,7 +146,7 @@
PulseData *s = h->priv_data;
pa_usec_t latency = pa_simple_get_latency(s->pa, NULL);
*wall = av_gettime();
- *dts = h->streams[s->stream_index]->cur_dts - latency;
+ *dts = s->timestamp - latency;
}
#define OFFSET(a) offsetof(PulseData, a)
@@ -129,6 +157,8 @@
{ "name", "set application name", OFFSET(name), AV_OPT_TYPE_STRING, {.str = LIBAVFORMAT_IDENT}, 0, 0, E },
{ "stream_name", "set stream description", OFFSET(stream_name), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E },
{ "device", "set device name", OFFSET(device), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E },
+ { "buffer_size", "set buffer size in bytes", OFFSET(buffer_size), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, E },
+ { "buffer_duration", "set buffer duration in millisecs", OFFSET(buffer_duration), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, E },
{ NULL }
};
@@ -149,6 +179,6 @@
.write_packet = pulse_write_packet,
.write_trailer = pulse_write_trailer,
.get_output_timestamp = pulse_get_output_timestamp,
- .flags = AVFMT_NOFILE,
+ .flags = AVFMT_NOFILE | AVFMT_ALLOW_FLUSH,
.priv_class = &pulse_muxer_class,
};
diff --git a/libavdevice/sdl.c b/libavdevice/sdl.c
index e708dfd..72d327e 100644
--- a/libavdevice/sdl.c
+++ b/libavdevice/sdl.c
@@ -24,10 +24,13 @@
*/
#include <SDL.h>
+#include <SDL_thread.h>
+
#include "libavutil/avstring.h"
#include "libavutil/opt.h"
#include "libavutil/parseutils.h"
#include "libavutil/pixdesc.h"
+#include "libavutil/time.h"
#include "avdevice.h"
typedef struct {
@@ -38,10 +41,17 @@
char *icon_title;
int window_width, window_height; /**< size of the window */
int window_fullscreen;
- int overlay_width, overlay_height; /**< size of the video in the window */
- int overlay_x, overlay_y;
+
+ SDL_Rect overlay_rect;
int overlay_fmt;
+
int sdl_was_already_inited;
+ SDL_Thread *event_thread;
+ SDL_mutex *mutex;
+ SDL_cond *init_cond;
+ int init_ret; /* return code used to signal initialization errors */
+ int inited;
+ int quit;
} SDLContext;
static const struct sdl_overlay_pix_fmt_entry {
@@ -57,27 +67,170 @@
{
SDLContext *sdl = s->priv_data;
- av_freep(&sdl->window_title);
- av_freep(&sdl->icon_title);
+ sdl->quit = 1;
- if (sdl->overlay) {
+ if (sdl->overlay)
SDL_FreeYUVOverlay(sdl->overlay);
- sdl->overlay = NULL;
- }
+ if (sdl->event_thread)
+ SDL_WaitThread(sdl->event_thread, NULL);
+ if (sdl->mutex)
+ SDL_DestroyMutex(sdl->mutex);
+ if (sdl->init_cond)
+ SDL_DestroyCond(sdl->init_cond);
+
if (!sdl->sdl_was_already_inited)
SDL_Quit();
return 0;
}
+static void compute_overlay_rect(AVFormatContext *s)
+{
+ AVRational sar, dar; /* sample and display aspect ratios */
+ SDLContext *sdl = s->priv_data;
+ AVStream *st = s->streams[0];
+ AVCodecContext *encctx = st->codec;
+ SDL_Rect *overlay_rect = &sdl->overlay_rect;
+
+ /* compute overlay width and height from the codec context information */
+ sar = st->sample_aspect_ratio.num ? st->sample_aspect_ratio : (AVRational){ 1, 1 };
+ dar = av_mul_q(sar, (AVRational){ encctx->width, encctx->height });
+
+ /* we suppose the screen has a 1/1 sample aspect ratio */
+ if (sdl->window_width && sdl->window_height) {
+ /* fit in the window */
+ if (av_cmp_q(dar, (AVRational){ sdl->window_width, sdl->window_height }) > 0) {
+ /* fit in width */
+ overlay_rect->w = sdl->window_width;
+ overlay_rect->h = av_rescale(overlay_rect->w, dar.den, dar.num);
+ } else {
+ /* fit in height */
+ overlay_rect->h = sdl->window_height;
+ overlay_rect->w = av_rescale(overlay_rect->h, dar.num, dar.den);
+ }
+ } else {
+ if (sar.num > sar.den) {
+ overlay_rect->w = encctx->width;
+ overlay_rect->h = av_rescale(overlay_rect->w, dar.den, dar.num);
+ } else {
+ overlay_rect->h = encctx->height;
+ overlay_rect->w = av_rescale(overlay_rect->h, dar.num, dar.den);
+ }
+ sdl->window_width = overlay_rect->w;
+ sdl->window_height = overlay_rect->h;
+ }
+
+ overlay_rect->x = (sdl->window_width - overlay_rect->w) / 2;
+ overlay_rect->y = (sdl->window_height - overlay_rect->h) / 2;
+}
+
+#define SDL_BASE_FLAGS (SDL_SWSURFACE|SDL_RESIZABLE)
+
+static int event_thread(void *arg)
+{
+ AVFormatContext *s = arg;
+ SDLContext *sdl = s->priv_data;
+ int flags = SDL_BASE_FLAGS | (sdl->window_fullscreen ? SDL_FULLSCREEN : 0);
+ AVStream *st = s->streams[0];
+ AVCodecContext *encctx = st->codec;
+
+ /* initialization */
+ if (SDL_Init(SDL_INIT_VIDEO) != 0) {
+ av_log(s, AV_LOG_ERROR, "Unable to initialize SDL: %s\n", SDL_GetError());
+ sdl->init_ret = AVERROR(EINVAL);
+ goto init_end;
+ }
+
+ SDL_WM_SetCaption(sdl->window_title, sdl->icon_title);
+ sdl->surface = SDL_SetVideoMode(sdl->window_width, sdl->window_height,
+ 24, flags);
+ if (!sdl->surface) {
+ av_log(sdl, AV_LOG_ERROR, "Unable to set video mode: %s\n", SDL_GetError());
+ sdl->init_ret = AVERROR(EINVAL);
+ goto init_end;
+ }
+
+ sdl->overlay = SDL_CreateYUVOverlay(encctx->width, encctx->height,
+ sdl->overlay_fmt, sdl->surface);
+ if (!sdl->overlay || sdl->overlay->pitches[0] < encctx->width) {
+ av_log(s, AV_LOG_ERROR,
+ "SDL does not support an overlay with size of %dx%d pixels\n",
+ encctx->width, encctx->height);
+ sdl->init_ret = AVERROR(EINVAL);
+ goto init_end;
+ }
+
+ sdl->init_ret = 0;
+ av_log(s, AV_LOG_VERBOSE, "w:%d h:%d fmt:%s -> w:%d h:%d\n",
+ encctx->width, encctx->height, av_get_pix_fmt_name(encctx->pix_fmt),
+ sdl->overlay_rect.w, sdl->overlay_rect.h);
+
+init_end:
+ SDL_LockMutex(sdl->mutex);
+ sdl->inited = 1;
+ SDL_UnlockMutex(sdl->mutex);
+ SDL_CondSignal(sdl->init_cond);
+
+ if (sdl->init_ret < 0)
+ return sdl->init_ret;
+
+ /* event loop */
+ while (!sdl->quit) {
+ int ret;
+ SDL_Event event;
+ SDL_PumpEvents();
+ ret = SDL_PeepEvents(&event, 1, SDL_GETEVENT, SDL_ALLEVENTS);
+ if (ret < 0) {
+ av_log(s, AV_LOG_ERROR, "Error when getting SDL event: %s\n", SDL_GetError());
+ continue;
+ }
+ if (ret == 0) {
+ SDL_Delay(10);
+ continue;
+ }
+
+ switch (event.type) {
+ case SDL_KEYDOWN:
+ switch (event.key.keysym.sym) {
+ case SDLK_ESCAPE:
+ case SDLK_q:
+ sdl->quit = 1;
+ break;
+ }
+ break;
+ case SDL_QUIT:
+ sdl->quit = 1;
+ break;
+
+ case SDL_VIDEORESIZE:
+ sdl->window_width = event.resize.w;
+ sdl->window_height = event.resize.h;
+
+ SDL_LockMutex(sdl->mutex);
+ sdl->surface = SDL_SetVideoMode(sdl->window_width, sdl->window_height, 24, SDL_BASE_FLAGS);
+ if (!sdl->surface) {
+ av_log(s, AV_LOG_ERROR, "Failed to set SDL video mode: %s\n", SDL_GetError());
+ sdl->quit = 1;
+ } else {
+ compute_overlay_rect(s);
+ }
+ SDL_UnlockMutex(sdl->mutex);
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return 0;
+}
+
static int sdl_write_header(AVFormatContext *s)
{
SDLContext *sdl = s->priv_data;
AVStream *st = s->streams[0];
AVCodecContext *encctx = st->codec;
- AVRational sar, dar; /* sample and display aspect ratios */
int i, ret;
- int flags = SDL_SWSURFACE | sdl->window_fullscreen ? SDL_FULLSCREEN : 0;
if (!sdl->window_title)
sdl->window_title = av_strdup(s->filename);
@@ -92,12 +245,6 @@
goto fail;
}
- if (SDL_Init(SDL_INIT_VIDEO) != 0) {
- av_log(s, AV_LOG_ERROR, "Unable to initialize SDL: %s\n", SDL_GetError());
- ret = AVERROR(EINVAL);
- goto fail;
- }
-
if ( s->nb_streams > 1
|| encctx->codec_type != AVMEDIA_TYPE_VIDEO
|| encctx->codec_id != AV_CODEC_ID_RAWVIDEO) {
@@ -122,57 +269,37 @@
}
/* compute overlay width and height from the codec context information */
- sar = st->sample_aspect_ratio.num ? st->sample_aspect_ratio : (AVRational){ 1, 1 };
- dar = av_mul_q(sar, (AVRational){ encctx->width, encctx->height });
+ compute_overlay_rect(s);
- /* we suppose the screen has a 1/1 sample aspect ratio */
- if (sdl->window_width && sdl->window_height) {
- /* fit in the window */
- if (av_cmp_q(dar, (AVRational){ sdl->window_width, sdl->window_height }) > 0) {
- /* fit in width */
- sdl->overlay_width = sdl->window_width;
- sdl->overlay_height = av_rescale(sdl->overlay_width, dar.den, dar.num);
- } else {
- /* fit in height */
- sdl->overlay_height = sdl->window_height;
- sdl->overlay_width = av_rescale(sdl->overlay_height, dar.num, dar.den);
- }
- } else {
- if (sar.num > sar.den) {
- sdl->overlay_width = encctx->width;
- sdl->overlay_height = av_rescale(sdl->overlay_width, dar.den, dar.num);
- } else {
- sdl->overlay_height = encctx->height;
- sdl->overlay_width = av_rescale(sdl->overlay_height, dar.num, dar.den);
- }
- sdl->window_width = sdl->overlay_width;
- sdl->window_height = sdl->overlay_height;
+ sdl->init_cond = SDL_CreateCond();
+ if (!sdl->init_cond) {
+ av_log(s, AV_LOG_ERROR, "Could not create SDL condition variable: %s\n", SDL_GetError());
+ ret = AVERROR_EXTERNAL;
+ goto fail;
}
- sdl->overlay_x = (sdl->window_width - sdl->overlay_width ) / 2;
- sdl->overlay_y = (sdl->window_height - sdl->overlay_height) / 2;
-
- SDL_WM_SetCaption(sdl->window_title, sdl->icon_title);
- sdl->surface = SDL_SetVideoMode(sdl->window_width, sdl->window_height,
- 24, flags);
- if (!sdl->surface) {
- av_log(s, AV_LOG_ERROR, "Unable to set video mode: %s\n", SDL_GetError());
- ret = AVERROR(EINVAL);
+ sdl->mutex = SDL_CreateMutex();
+ if (!sdl->mutex) {
+ av_log(s, AV_LOG_ERROR, "Could not create SDL mutex: %s\n", SDL_GetError());
+ ret = AVERROR_EXTERNAL;
+ goto fail;
+ }
+ sdl->event_thread = SDL_CreateThread(event_thread, s);
+ if (!sdl->event_thread) {
+ av_log(s, AV_LOG_ERROR, "Could not create SDL event thread: %s\n", SDL_GetError());
+ ret = AVERROR_EXTERNAL;
goto fail;
}
- sdl->overlay = SDL_CreateYUVOverlay(encctx->width, encctx->height,
- sdl->overlay_fmt, sdl->surface);
- if (!sdl->overlay || sdl->overlay->pitches[0] < encctx->width) {
- av_log(s, AV_LOG_ERROR,
- "SDL does not support an overlay with size of %dx%d pixels\n",
- encctx->width, encctx->height);
- ret = AVERROR(EINVAL);
+ /* wait until the video system has been inited */
+ SDL_LockMutex(sdl->mutex);
+ if (!sdl->inited) {
+ SDL_CondWait(sdl->init_cond, sdl->mutex);
+ }
+ SDL_UnlockMutex(sdl->mutex);
+ if (sdl->init_ret < 0) {
+ ret = sdl->init_ret;
goto fail;
}
-
- av_log(s, AV_LOG_VERBOSE, "w:%d h:%d fmt:%s sar:%d/%d -> w:%d h:%d\n",
- encctx->width, encctx->height, av_get_pix_fmt_name(encctx->pix_fmt), sar.num, sar.den,
- sdl->overlay_width, sdl->overlay_height);
return 0;
fail:
@@ -184,12 +311,16 @@
{
SDLContext *sdl = s->priv_data;
AVCodecContext *encctx = s->streams[0]->codec;
- SDL_Rect rect = { sdl->overlay_x, sdl->overlay_y, sdl->overlay_width, sdl->overlay_height };
AVPicture pict;
int i;
+ if (sdl->quit) {
+ sdl_write_trailer(s);
+ return AVERROR(EIO);
+ }
avpicture_fill(&pict, pkt->data, encctx->pix_fmt, encctx->width, encctx->height);
+ SDL_LockMutex(sdl->mutex);
SDL_FillRect(sdl->surface, &sdl->surface->clip_rect,
SDL_MapRGB(sdl->surface->format, 0, 0, 0));
SDL_LockYUVOverlay(sdl->overlay);
@@ -197,10 +328,13 @@
sdl->overlay->pixels [i] = pict.data [i];
sdl->overlay->pitches[i] = pict.linesize[i];
}
- SDL_DisplayYUVOverlay(sdl->overlay, &rect);
+ SDL_DisplayYUVOverlay(sdl->overlay, &sdl->overlay_rect);
SDL_UnlockYUVOverlay(sdl->overlay);
- SDL_UpdateRect(sdl->surface, rect.x, rect.y, rect.w, rect.h);
+ SDL_UpdateRect(sdl->surface,
+ sdl->overlay_rect.x, sdl->overlay_rect.y,
+ sdl->overlay_rect.w, sdl->overlay_rect.h);
+ SDL_UnlockMutex(sdl->mutex);
return 0;
}
@@ -208,10 +342,10 @@
#define OFFSET(x) offsetof(SDLContext,x)
static const AVOption options[] = {
- { "window_title", "set SDL window title", OFFSET(window_title), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, AV_OPT_FLAG_ENCODING_PARAM },
- { "icon_title", "set SDL iconified window title", OFFSET(icon_title) , AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, AV_OPT_FLAG_ENCODING_PARAM },
- { "window_size", "set SDL window forced size", OFFSET(window_width), AV_OPT_TYPE_IMAGE_SIZE,{.str=NULL}, 0, 0, AV_OPT_FLAG_ENCODING_PARAM },
- { "window_fullscreen", "set SDL window fullscreen", OFFSET(window_fullscreen), AV_OPT_TYPE_INT,{.i64=0}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
+ { "window_title", "set SDL window title", OFFSET(window_title), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, AV_OPT_FLAG_ENCODING_PARAM },
+ { "icon_title", "set SDL iconified window title", OFFSET(icon_title) , AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, AV_OPT_FLAG_ENCODING_PARAM },
+ { "window_size", "set SDL window forced size", OFFSET(window_width), AV_OPT_TYPE_IMAGE_SIZE, { .str = NULL }, 0, 0, AV_OPT_FLAG_ENCODING_PARAM },
+ { "window_fullscreen", "set SDL window fullscreen", OFFSET(window_fullscreen), AV_OPT_TYPE_INT, { .i64 = 0 }, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
{ NULL },
};
diff --git a/libavdevice/timefilter.c b/libavdevice/timefilter.c
index 424e492..9d38f93 100644
--- a/libavdevice/timefilter.c
+++ b/libavdevice/timefilter.c
@@ -49,6 +49,10 @@
{
TimeFilter *self = av_mallocz(sizeof(TimeFilter));
double o = 2 * M_PI * bandwidth * period * time_base;
+
+ if (!self)
+ return NULL;
+
self->clock_period = time_base;
self->feedback2_factor = qexpneg(M_SQRT2 * o);
self->feedback3_factor = qexpneg(o * o) / period;
@@ -121,6 +125,10 @@
for (par1 = bestpar1 * 0.8; par1 <= bestpar1 * 1.21; par1 += bestpar1 * 0.05) {
double error = 0;
TimeFilter *tf = ff_timefilter_new(1, par0, par1);
+ if (!tf) {
+ printf("Could not allocate memory for timefilter.\n");
+ exit(1);
+ }
for (i = 0; i < SAMPLES; i++) {
double filtered;
filtered = ff_timefilter_update(tf, samples[i], i ? (samplet[i] - samplet[i-1]) : 1);
diff --git a/libavdevice/timefilter.h b/libavdevice/timefilter.h
index 6662959..cb3d0a7 100644
--- a/libavdevice/timefilter.h
+++ b/libavdevice/timefilter.h
@@ -58,6 +58,8 @@
* @param period expected update interval, in input units
* @param brandwidth filtering bandwidth, in Hz
*
+ * @return a pointer to a TimeFilter struct, or NULL on error
+ *
* For more details about these parameters and background concepts please see:
* http://www.kokkinizita.net/papers/usingdll.pdf
*/
diff --git a/libavdevice/v4l2.c b/libavdevice/v4l2.c
index 1b2ede4..cb962b7 100644
--- a/libavdevice/v4l2.c
+++ b/libavdevice/v4l2.c
@@ -455,6 +455,8 @@
av_log(ctx, AV_LOG_INFO, "Detected monotonic timestamps, converting\n");
/* microseconds instead of seconds, MHz instead of Hz */
s->timefilter = ff_timefilter_new(1, period, 1.0E-6);
+ if (!s->timefilter)
+ return AVERROR(ENOMEM);
s->ts_mode = V4L_TS_CONVERT_READY;
return 0;
}
diff --git a/libavdevice/version.h b/libavdevice/version.h
index 5823ab9..0bbd48e 100644
--- a/libavdevice/version.h
+++ b/libavdevice/version.h
@@ -28,8 +28,8 @@
#include "libavutil/avutil.h"
#define LIBAVDEVICE_VERSION_MAJOR 55
-#define LIBAVDEVICE_VERSION_MINOR 4
-#define LIBAVDEVICE_VERSION_MICRO 100
+#define LIBAVDEVICE_VERSION_MINOR 5
+#define LIBAVDEVICE_VERSION_MICRO 102
#define LIBAVDEVICE_VERSION_INT AV_VERSION_INT(LIBAVDEVICE_VERSION_MAJOR, \
LIBAVDEVICE_VERSION_MINOR, \
diff --git a/libavdevice/x11grab.c b/libavdevice/x11grab.c
index eb23ec3..0e7b6ae 100644
--- a/libavdevice/x11grab.c
+++ b/libavdevice/x11grab.c
@@ -77,6 +77,8 @@
int follow_mouse; /**< Set by a private option. */
int show_region; /**< set by a private option. */
AVRational framerate; /**< Set by a private option. */
+ int palette_changed;
+ uint32_t palette[256];
Cursor c;
Window region_win; /**< This is used by show_region option. */
@@ -167,6 +169,9 @@
int use_shm;
char *dpyname, *offset;
int ret = 0;
+ Colormap color_map;
+ XColor color[256];
+ int i;
dpyname = av_strdup(s1->filename);
if (!dpyname)
@@ -258,6 +263,15 @@
case 8:
av_log (s1, AV_LOG_DEBUG, "8 bit palette\n");
input_pixfmt = AV_PIX_FMT_PAL8;
+ color_map = DefaultColormap(dpy, screen);
+ for (i = 0; i < 256; ++i)
+ color[i].pixel = i;
+ XQueryColors(dpy, color_map, color, 256);
+ for (i = 0; i < 256; ++i)
+ x11grab->palette[i] = (color[i].red & 0xFF00) << 8 |
+ (color[i].green & 0xFF00) |
+ (color[i].blue & 0xFF00) >> 8;
+ x11grab->palette_changed = 1;
break;
case 16:
if ( image->red_mask == 0xf800 &&
@@ -489,6 +503,16 @@
pkt->data = image->data;
pkt->size = s->frame_size;
pkt->pts = curtime;
+ if (s->palette_changed) {
+ uint8_t *pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE,
+ AVPALETTE_SIZE);
+ if (!pal) {
+ av_log(s, AV_LOG_ERROR, "Cannot append palette to packet\n");
+ } else {
+ memcpy(pal, s->palette, AVPALETTE_SIZE);
+ s->palette_changed = 0;
+ }
+ }
screen = DefaultScreen(dpy);
root = RootWindow(dpy, screen);
diff --git a/libavdevice/xv.c b/libavdevice/xv.c
index 65f2f72..ad60482 100644
--- a/libavdevice/xv.c
+++ b/libavdevice/xv.c
@@ -35,6 +35,7 @@
#include "libavutil/opt.h"
#include "libavutil/pixdesc.h"
+#include "libavutil/imgutils.h"
#include "avdevice.h"
typedef struct {
@@ -50,18 +51,58 @@
char *display_name;
XvImage* yuv_image;
+ enum AVPixelFormat image_format;
int image_width, image_height;
XShmSegmentInfo yuv_shminfo;
int xv_port;
} XVContext;
+typedef struct XVTagFormatMap
+{
+ int tag;
+ enum AVPixelFormat format;
+} XVTagFormatMap;
+
+static XVTagFormatMap tag_codec_map[] = {
+ { MKTAG('I','4','2','0'), AV_PIX_FMT_YUV420P },
+ { MKTAG('U','Y','V','Y'), AV_PIX_FMT_UYVY422 },
+ { MKTAG('Y','U','Y','2'), AV_PIX_FMT_YUYV422 },
+ { 0, AV_PIX_FMT_NONE }
+};
+
+static int xv_get_tag_from_format(enum AVPixelFormat format)
+{
+ XVTagFormatMap *m = tag_codec_map;
+ int i;
+ for (i = 0; m->tag; m = &tag_codec_map[++i]) {
+ if (m->format == format)
+ return m->tag;
+ }
+ return 0;
+}
+
+static int xv_write_trailer(AVFormatContext *s)
+{
+ XVContext *xv = s->priv_data;
+ if (xv->display) {
+ XShmDetach(xv->display, &xv->yuv_shminfo);
+ if (xv->yuv_image)
+ shmdt(xv->yuv_image->data);
+ XFree(xv->yuv_image);
+ if (xv->gc)
+ XFreeGC(xv->display, xv->gc);
+ XCloseDisplay(xv->display);
+ }
+ return 0;
+}
+
static int xv_write_header(AVFormatContext *s)
{
XVContext *xv = s->priv_data;
unsigned int num_adaptors;
XvAdaptorInfo *ai;
XvImageFormatValues *fv;
- int num_formats = 0, j;
+ int num_formats = 0, j, tag, ret;
AVCodecContext *encctx = s->streams[0]->codec;
if ( s->nb_streams > 1
@@ -71,6 +112,14 @@
return AVERROR(EINVAL);
}
+ if (!(tag = xv_get_tag_from_format(encctx->pix_fmt))) {
+ av_log(s, AV_LOG_ERROR,
+ "Unsupported pixel format '%s', only yuv420p, uyvy422, yuyv422 are currently supported\n",
+ av_get_pix_fmt_name(encctx->pix_fmt));
+ return AVERROR_PATCHWELCOME;
+ }
+ xv->image_format = encctx->pix_fmt;
+
xv->display = XOpenDisplay(xv->display_name);
if (!xv->display) {
av_log(s, AV_LOG_ERROR, "Could not open the X11 display '%s'\n", xv->display_name);
@@ -88,28 +137,28 @@
xv->window_width, xv->window_height,
0, 0, 0);
if (!xv->window_title) {
- if (!(xv->window_title = av_strdup(s->filename)))
- return AVERROR(ENOMEM);
+ if (!(xv->window_title = av_strdup(s->filename))) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
}
XStoreName(xv->display, xv->window, xv->window_title);
XMapWindow(xv->display, xv->window);
- if (XvQueryAdaptors(xv->display, DefaultRootWindow(xv->display), &num_adaptors, &ai) != Success)
- return AVERROR_EXTERNAL;
- xv->xv_port = ai[0].base_id;
-
- if (encctx->pix_fmt != AV_PIX_FMT_YUV420P) {
- av_log(s, AV_LOG_ERROR,
- "Unsupported pixel format '%s', only yuv420p is currently supported\n",
- av_get_pix_fmt_name(encctx->pix_fmt));
- return AVERROR_PATCHWELCOME;
+ if (XvQueryAdaptors(xv->display, DefaultRootWindow(xv->display), &num_adaptors, &ai) != Success) {
+ ret = AVERROR_EXTERNAL;
+ goto fail;
}
+ xv->xv_port = ai[0].base_id;
+ XvFreeAdaptorInfo(ai);
fv = XvListImageFormats(xv->display, xv->xv_port, &num_formats);
- if (!fv)
- return AVERROR_EXTERNAL;
+ if (!fv) {
+ ret = AVERROR_EXTERNAL;
+ goto fail;
+ }
for (j = 0; j < num_formats; j++) {
- if (fv[j].id == MKTAG('I','4','2','0')) {
+ if (fv[j].id == tag) {
break;
}
}
@@ -117,15 +166,16 @@
if (j >= num_formats) {
av_log(s, AV_LOG_ERROR,
- "Device does not support pixel format yuv420p, aborting\n");
- return AVERROR(EINVAL);
+ "Device does not support pixel format %s, aborting\n",
+ av_get_pix_fmt_name(encctx->pix_fmt));
+ ret = AVERROR(EINVAL);
+ goto fail;
}
xv->gc = XCreateGC(xv->display, xv->window, 0, 0);
xv->image_width = encctx->width;
xv->image_height = encctx->height;
- xv->yuv_image = XvShmCreateImage(xv->display, xv->xv_port,
- MKTAG('I','4','2','0'), 0,
+ xv->yuv_image = XvShmCreateImage(xv->display, xv->xv_port, tag, 0,
xv->image_width, xv->image_height, &xv->yuv_shminfo);
xv->yuv_shminfo.shmid = shmget(IPC_PRIVATE, xv->yuv_image->data_size,
IPC_CREAT | 0777);
@@ -138,6 +188,9 @@
shmctl(xv->yuv_shminfo.shmid, IPC_RMID, 0);
return 0;
+ fail:
+ xv_write_trailer(s);
+ return ret;
}
static int xv_write_packet(AVFormatContext *s, AVPacket *pkt)
@@ -147,22 +200,15 @@
XWindowAttributes window_attrs;
AVPicture pict;
AVCodecContext *ctx = s->streams[0]->codec;
- int y, h;
-
- h = img->height / 2;
+ uint8_t *data[3] = {
+ img->data + img->offsets[0],
+ img->data + img->offsets[1],
+ img->data + img->offsets[2]
+ };
avpicture_fill(&pict, pkt->data, ctx->pix_fmt, ctx->width, ctx->height);
- for (y = 0; y < img->height; y++) {
- memcpy(&img->data[img->offsets[0] + (y * img->pitches[0])],
- &pict.data[0][y * pict.linesize[0]], img->pitches[0]);
- }
-
- for (y = 0; y < h; ++y) {
- memcpy(&img->data[img->offsets[1] + (y * img->pitches[1])],
- &pict.data[1][y * pict.linesize[1]], img->pitches[1]);
- memcpy(&img->data[img->offsets[2] + (y * img->pitches[2])],
- &pict.data[2][y * pict.linesize[2]], img->pitches[2]);
- }
+ av_image_copy(data, img->pitches, (const uint8_t **)pict.data, pict.linesize,
+ xv->image_format, img->width, img->height);
XGetWindowAttributes(xv->display, xv->window, &window_attrs);
if (XvShmPutImage(xv->display, xv->xv_port, xv->window, xv->gc,
@@ -174,17 +220,6 @@
return 0;
}
-static int xv_write_trailer(AVFormatContext *s)
-{
- XVContext *xv = s->priv_data;
-
- XShmDetach(xv->display, &xv->yuv_shminfo);
- shmdt(xv->yuv_image->data);
- XFree(xv->yuv_image);
- XCloseDisplay(xv->display);
- return 0;
-}
-
#define OFFSET(x) offsetof(XVContext, x)
static const AVOption options[] = {
{ "display_name", "set display name", OFFSET(display_name), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, AV_OPT_FLAG_ENCODING_PARAM },
diff --git a/libavfilter/Makefile b/libavfilter/Makefile
index b2d3587..3d587fe 100644
--- a/libavfilter/Makefile
+++ b/libavfilter/Makefile
@@ -9,6 +9,7 @@
FFLIBS-$(CONFIG_ATEMPO_FILTER) += avcodec
FFLIBS-$(CONFIG_DECIMATE_FILTER) += avcodec
FFLIBS-$(CONFIG_DESHAKE_FILTER) += avcodec
+FFLIBS-$(CONFIG_ELBG_FILTER) += avcodec
FFLIBS-$(CONFIG_MCDEINT_FILTER) += avcodec
FFLIBS-$(CONFIG_MOVIE_FILTER) += avformat avcodec
FFLIBS-$(CONFIG_MP_FILTER) += avcodec
@@ -48,12 +49,11 @@
OBJS-$(CONFIG_AVCODEC) += avcodec.o
-OBJS-$(CONFIG_AVFORMAT) += lavfutils.o
-OBJS-$(CONFIG_SWSCALE) += lswsutils.o
OBJS-$(CONFIG_ACONVERT_FILTER) += af_aconvert.o
OBJS-$(CONFIG_ADELAY_FILTER) += af_adelay.o
OBJS-$(CONFIG_AECHO_FILTER) += af_aecho.o
+OBJS-$(CONFIG_AEVAL_FILTER) += aeval.o
OBJS-$(CONFIG_AFADE_FILTER) += af_afade.o
OBJS-$(CONFIG_AFORMAT_FILTER) += af_aformat.o
OBJS-$(CONFIG_AINTERLEAVE_FILTER) += f_interleave.o
@@ -94,13 +94,14 @@
OBJS-$(CONFIG_LADSPA_FILTER) += af_ladspa.o
OBJS-$(CONFIG_LOWPASS_FILTER) += af_biquads.o
OBJS-$(CONFIG_PAN_FILTER) += af_pan.o
+OBJS-$(CONFIG_REPLAYGAIN_FILTER) += af_replaygain.o
OBJS-$(CONFIG_RESAMPLE_FILTER) += af_resample.o
OBJS-$(CONFIG_SILENCEDETECT_FILTER) += af_silencedetect.o
OBJS-$(CONFIG_TREBLE_FILTER) += af_biquads.o
OBJS-$(CONFIG_VOLUME_FILTER) += af_volume.o
OBJS-$(CONFIG_VOLUMEDETECT_FILTER) += af_volumedetect.o
-OBJS-$(CONFIG_AEVALSRC_FILTER) += asrc_aevalsrc.o
+OBJS-$(CONFIG_AEVALSRC_FILTER) += aeval.o
OBJS-$(CONFIG_ANULLSRC_FILTER) += asrc_anullsrc.o
OBJS-$(CONFIG_FLITE_FILTER) += asrc_flite.o
OBJS-$(CONFIG_SINE_FILTER) += asrc_sine.o
@@ -129,6 +130,7 @@
OBJS-$(CONFIG_DRAWBOX_FILTER) += vf_drawbox.o
OBJS-$(CONFIG_DRAWGRID_FILTER) += vf_drawbox.o
OBJS-$(CONFIG_DRAWTEXT_FILTER) += vf_drawtext.o
+OBJS-$(CONFIG_ELBG_FILTER) += vf_elbg.o
OBJS-$(CONFIG_EDGEDETECT_FILTER) += vf_edgedetect.o
OBJS-$(CONFIG_EXTRACTPLANES_FILTER) += vf_extractplanes.o
OBJS-$(CONFIG_FADE_FILTER) += vf_fade.o
@@ -157,6 +159,7 @@
OBJS-$(CONFIG_LUTRGB_FILTER) += vf_lut.o
OBJS-$(CONFIG_LUTYUV_FILTER) += vf_lut.o
OBJS-$(CONFIG_MCDEINT_FILTER) += vf_mcdeint.o
+OBJS-$(CONFIG_MERGEPLANES_FILTER) += vf_mergeplanes.o framesync.o
OBJS-$(CONFIG_MP_FILTER) += vf_mp.o
OBJS-$(CONFIG_MPDECIMATE_FILTER) += vf_mpdecimate.o
OBJS-$(CONFIG_NEGATE_FILTER) += vf_lut.o
@@ -245,6 +248,9 @@
OBJS-$(CONFIG_AMOVIE_FILTER) += src_movie.o
OBJS-$(CONFIG_MOVIE_FILTER) += src_movie.o
+# Windows resource file
+SLIBOBJS-$(HAVE_GNU_WINDRES) += avfilterres.o
+
SKIPHEADERS-$(CONFIG_LIBVIDSTAB) += vidstabutils.h
SKIPHEADERS-$(CONFIG_OPENCL) += opencl_internal.h deshake_opencl_kernel.h unsharp_opencl_kernel.h
diff --git a/libavfilter/aeval.c b/libavfilter/aeval.c
new file mode 100644
index 0000000..3a05fb0
--- /dev/null
+++ b/libavfilter/aeval.c
@@ -0,0 +1,466 @@
+/*
+ * Copyright (c) 2011 Stefano Sabatini
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * eval audio source
+ */
+
+#include "libavutil/avassert.h"
+#include "libavutil/avstring.h"
+#include "libavutil/channel_layout.h"
+#include "libavutil/eval.h"
+#include "libavutil/opt.h"
+#include "libavutil/parseutils.h"
+#include "avfilter.h"
+#include "audio.h"
+#include "internal.h"
+
+static const char * const var_names[] = {
+ "ch", ///< the value of the current channel
+ "n", ///< number of frame
+ "nb_in_channels",
+ "nb_out_channels",
+ "t", ///< timestamp expressed in seconds
+ "s", ///< sample rate
+ NULL
+};
+
+enum var_name {
+ VAR_CH,
+ VAR_N,
+ VAR_NB_IN_CHANNELS,
+ VAR_NB_OUT_CHANNELS,
+ VAR_T,
+ VAR_S,
+ VAR_VARS_NB
+};
+
+typedef struct {
+ const AVClass *class;
+ char *sample_rate_str;
+ int sample_rate;
+ int64_t chlayout;
+ char *chlayout_str;
+ int nb_channels; ///< number of output channels
+ int nb_in_channels; ///< number of input channels
+ int same_chlayout; ///< set output as input channel layout
+ int64_t pts;
+ AVExpr **expr;
+ char *exprs;
+ int nb_samples; ///< number of samples per requested frame
+ int64_t duration;
+ uint64_t n;
+ double var_values[VAR_VARS_NB];
+ double *channel_values;
+ int64_t out_channel_layout;
+} EvalContext;
+
+static double val(void *priv, double ch)
+{
+ EvalContext *eval = priv;
+ return eval->channel_values[FFMIN((int)ch, eval->nb_in_channels-1)];
+}
+
+static double (* const aeval_func1[])(void *, double) = { val, NULL };
+static const char * const aeval_func1_names[] = { "val", NULL };
+
+#define OFFSET(x) offsetof(EvalContext, x)
+#define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
+
+static const AVOption aevalsrc_options[]= {
+ { "exprs", "set the '|'-separated list of channels expressions", OFFSET(exprs), AV_OPT_TYPE_STRING, {.str = NULL}, .flags = FLAGS },
+ { "nb_samples", "set the number of samples per requested frame", OFFSET(nb_samples), AV_OPT_TYPE_INT, {.i64 = 1024}, 0, INT_MAX, FLAGS },
+ { "n", "set the number of samples per requested frame", OFFSET(nb_samples), AV_OPT_TYPE_INT, {.i64 = 1024}, 0, INT_MAX, FLAGS },
+ { "sample_rate", "set the sample rate", OFFSET(sample_rate_str), AV_OPT_TYPE_STRING, {.str = "44100"}, CHAR_MIN, CHAR_MAX, FLAGS },
+ { "s", "set the sample rate", OFFSET(sample_rate_str), AV_OPT_TYPE_STRING, {.str = "44100"}, CHAR_MIN, CHAR_MAX, FLAGS },
+ { "duration", "set audio duration", OFFSET(duration), AV_OPT_TYPE_DURATION, {.i64 = -1}, -1, INT64_MAX, FLAGS },
+ { "d", "set audio duration", OFFSET(duration), AV_OPT_TYPE_DURATION, {.i64 = -1}, -1, INT64_MAX, FLAGS },
+ { "channel_layout", "set channel layout", OFFSET(chlayout_str), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS },
+ { "c", "set channel layout", OFFSET(chlayout_str), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS },
+ { NULL }
+};
+
+AVFILTER_DEFINE_CLASS(aevalsrc);
+
+static int parse_channel_expressions(AVFilterContext *ctx,
+ int expected_nb_channels)
+{
+ EvalContext *eval = ctx->priv;
+ char *args1 = av_strdup(eval->exprs);
+ char *expr, *last_expr, *buf;
+ double (* const *func1)(void *, double) = NULL;
+ const char * const *func1_names = NULL;
+ int i, ret = 0;
+
+ if (!args1)
+ return AVERROR(ENOMEM);
+
+ if (!eval->exprs) {
+ av_log(ctx, AV_LOG_ERROR, "Channels expressions list is empty\n");
+ return AVERROR(EINVAL);
+ }
+
+ if (!strcmp(ctx->filter->name, "aeval")) {
+ func1 = aeval_func1;
+ func1_names = aeval_func1_names;
+ }
+
+#define ADD_EXPRESSION(expr_) do { \
+ if (!av_dynarray2_add((void **)&eval->expr, &eval->nb_channels, \
+ sizeof(*eval->expr), NULL)) { \
+ ret = AVERROR(ENOMEM); \
+ goto end; \
+ } \
+ eval->expr[eval->nb_channels-1] = NULL; \
+ ret = av_expr_parse(&eval->expr[eval->nb_channels - 1], expr_, \
+ var_names, func1_names, func1, \
+ NULL, NULL, 0, ctx); \
+ if (ret < 0) \
+ goto end; \
+ } while (0)
+
+ /* reset expressions */
+ for (i = 0; i < eval->nb_channels; i++) {
+ av_expr_free(eval->expr[i]);
+ eval->expr[i] = NULL;
+ }
+ av_freep(&eval->expr);
+ eval->nb_channels = 0;
+
+ buf = args1;
+ while (expr = av_strtok(buf, "|", &buf)) {
+ ADD_EXPRESSION(expr);
+ last_expr = expr;
+ }
+
+ if (expected_nb_channels > eval->nb_channels)
+ for (i = eval->nb_channels; i < expected_nb_channels; i++)
+ ADD_EXPRESSION(last_expr);
+
+ if (expected_nb_channels > 0 && eval->nb_channels != expected_nb_channels) {
+ av_log(ctx, AV_LOG_ERROR,
+ "Mismatch between the specified number of channel expressions '%d' "
+ "and the number of expected output channels '%d' for the specified channel layout\n",
+ eval->nb_channels, expected_nb_channels);
+ ret = AVERROR(EINVAL);
+ goto end;
+ }
+
+end:
+ av_free(args1);
+ return ret;
+}
+
+static av_cold int init(AVFilterContext *ctx)
+{
+ EvalContext *eval = ctx->priv;
+ int ret;
+
+ if (eval->chlayout_str) {
+ if (!strcmp(eval->chlayout_str, "same") && !strcmp(ctx->filter->name, "aeval")) {
+ eval->same_chlayout = 1;
+ } else {
+ ret = ff_parse_channel_layout(&eval->chlayout, NULL, eval->chlayout_str, ctx);
+ if (ret < 0)
+ return ret;
+
+ ret = parse_channel_expressions(ctx, av_get_channel_layout_nb_channels(eval->chlayout));
+ if (ret < 0)
+ return ret;
+ }
+ } else {
+ /* guess channel layout from nb expressions/channels */
+ if ((ret = parse_channel_expressions(ctx, -1)) < 0)
+ return ret;
+
+ eval->chlayout = av_get_default_channel_layout(eval->nb_channels);
+ if (!eval->chlayout && eval->nb_channels <= 0) {
+ av_log(ctx, AV_LOG_ERROR, "Invalid number of channels '%d' provided\n",
+ eval->nb_channels);
+ return AVERROR(EINVAL);
+ }
+ }
+
+ if (eval->sample_rate_str)
+ if ((ret = ff_parse_sample_rate(&eval->sample_rate, eval->sample_rate_str, ctx)))
+ return ret;
+ eval->n = 0;
+
+ return ret;
+}
+
+static av_cold void uninit(AVFilterContext *ctx)
+{
+ EvalContext *eval = ctx->priv;
+ int i;
+
+ for (i = 0; i < eval->nb_channels; i++) {
+ av_expr_free(eval->expr[i]);
+ eval->expr[i] = NULL;
+ }
+ av_freep(&eval->expr);
+}
+
+static int config_props(AVFilterLink *outlink)
+{
+ EvalContext *eval = outlink->src->priv;
+ char buf[128];
+
+ outlink->time_base = (AVRational){1, eval->sample_rate};
+ outlink->sample_rate = eval->sample_rate;
+
+ eval->var_values[VAR_S] = eval->sample_rate;
+ eval->var_values[VAR_NB_IN_CHANNELS] = NAN;
+ eval->var_values[VAR_NB_OUT_CHANNELS] = outlink->channels;
+
+ av_get_channel_layout_string(buf, sizeof(buf), 0, eval->chlayout);
+
+ av_log(outlink->src, AV_LOG_VERBOSE,
+ "sample_rate:%d chlayout:%s duration:%"PRId64"\n",
+ eval->sample_rate, buf, eval->duration);
+
+ return 0;
+}
+
+static int query_formats(AVFilterContext *ctx)
+{
+ EvalContext *eval = ctx->priv;
+ static const enum AVSampleFormat sample_fmts[] = { AV_SAMPLE_FMT_DBLP, AV_SAMPLE_FMT_NONE };
+ int64_t chlayouts[] = { eval->chlayout ? eval->chlayout : FF_COUNT2LAYOUT(eval->nb_channels) , -1 };
+ int sample_rates[] = { eval->sample_rate, -1 };
+
+ ff_set_common_formats (ctx, ff_make_format_list(sample_fmts));
+ ff_set_common_channel_layouts(ctx, avfilter_make_format64_list(chlayouts));
+ ff_set_common_samplerates(ctx, ff_make_format_list(sample_rates));
+
+ return 0;
+}
+
+static int request_frame(AVFilterLink *outlink)
+{
+ EvalContext *eval = outlink->src->priv;
+ AVFrame *samplesref;
+ int i, j;
+ int64_t t = av_rescale(eval->n, AV_TIME_BASE, eval->sample_rate);
+
+ if (eval->duration >= 0 && t >= eval->duration)
+ return AVERROR_EOF;
+
+ samplesref = ff_get_audio_buffer(outlink, eval->nb_samples);
+ if (!samplesref)
+ return AVERROR(ENOMEM);
+
+ /* evaluate expression for each single sample and for each channel */
+ for (i = 0; i < eval->nb_samples; i++, eval->n++) {
+ eval->var_values[VAR_N] = eval->n;
+ eval->var_values[VAR_T] = eval->var_values[VAR_N] * (double)1/eval->sample_rate;
+
+ for (j = 0; j < eval->nb_channels; j++) {
+ *((double *) samplesref->extended_data[j] + i) =
+ av_expr_eval(eval->expr[j], eval->var_values, NULL);
+ }
+ }
+
+ samplesref->pts = eval->pts;
+ samplesref->sample_rate = eval->sample_rate;
+ eval->pts += eval->nb_samples;
+
+ return ff_filter_frame(outlink, samplesref);
+}
+
+#if CONFIG_AEVALSRC_FILTER
+static const AVFilterPad aevalsrc_outputs[] = {
+ {
+ .name = "default",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .config_props = config_props,
+ .request_frame = request_frame,
+ },
+ { NULL }
+};
+
+AVFilter ff_asrc_aevalsrc = {
+ .name = "aevalsrc",
+ .description = NULL_IF_CONFIG_SMALL("Generate an audio signal generated by an expression."),
+ .query_formats = query_formats,
+ .init = init,
+ .uninit = uninit,
+ .priv_size = sizeof(EvalContext),
+ .inputs = NULL,
+ .outputs = aevalsrc_outputs,
+ .priv_class = &aevalsrc_class,
+};
+
+#endif /* CONFIG_AEVALSRC_FILTER */
+
+#define OFFSET(x) offsetof(EvalContext, x)
+#define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
+
+static const AVOption aeval_options[]= {
+ { "exprs", "set the '|'-separated list of channels expressions", OFFSET(exprs), AV_OPT_TYPE_STRING, {.str = NULL}, .flags = FLAGS },
+ { "channel_layout", "set channel layout", OFFSET(chlayout_str), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS },
+ { "c", "set channel layout", OFFSET(chlayout_str), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS },
+ { NULL }
+};
+
+AVFILTER_DEFINE_CLASS(aeval);
+
+static int aeval_query_formats(AVFilterContext *ctx)
+{
+ AVFilterFormats *formats = NULL;
+ AVFilterChannelLayouts *layouts;
+ AVFilterLink *inlink = ctx->inputs[0];
+ AVFilterLink *outlink = ctx->outputs[0];
+ EvalContext *eval = ctx->priv;
+ static const enum AVSampleFormat sample_fmts[] = {
+ AV_SAMPLE_FMT_DBLP, AV_SAMPLE_FMT_NONE
+ };
+
+ // inlink supports any channel layout
+ layouts = ff_all_channel_counts();
+ ff_channel_layouts_ref(layouts, &inlink->out_channel_layouts);
+
+ if (eval->same_chlayout) {
+ layouts = ff_all_channel_counts();
+ if (!layouts)
+ return AVERROR(ENOMEM);
+ ff_set_common_channel_layouts(ctx, layouts);
+ } else {
+ // outlink supports only requested output channel layout
+ layouts = NULL;
+ ff_add_channel_layout(&layouts,
+ eval->out_channel_layout ? eval->out_channel_layout :
+ FF_COUNT2LAYOUT(eval->nb_channels));
+ ff_channel_layouts_ref(layouts, &outlink->in_channel_layouts);
+ }
+
+ formats = ff_make_format_list(sample_fmts);
+ if (!formats)
+ return AVERROR(ENOMEM);
+ ff_set_common_formats(ctx, formats);
+
+ formats = ff_all_samplerates();
+ if (!formats)
+ return AVERROR(ENOMEM);
+ ff_set_common_samplerates(ctx, formats);
+
+ return 0;
+}
+
+static int aeval_config_output(AVFilterLink *outlink)
+{
+ AVFilterContext *ctx = outlink->src;
+ EvalContext *eval = ctx->priv;
+ AVFilterLink *inlink = ctx->inputs[0];
+ int ret;
+
+ if (eval->same_chlayout) {
+ eval->chlayout = inlink->channel_layout;
+
+ if ((ret = parse_channel_expressions(ctx, inlink->channels)) < 0)
+ return ret;
+ }
+
+ eval->n = 0;
+ eval->nb_in_channels = eval->var_values[VAR_NB_IN_CHANNELS] = inlink->channels;
+ eval->var_values[VAR_NB_OUT_CHANNELS] = outlink->channels;
+ eval->var_values[VAR_S] = inlink->sample_rate;
+ eval->var_values[VAR_T] = NAN;
+
+ eval->channel_values = av_realloc_f(eval->channel_values,
+ inlink->channels, sizeof(*eval->channel_values));
+ if (!eval->channel_values)
+ return AVERROR(ENOMEM);
+
+ return 0;
+}
+
+#define TS2T(ts, tb) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts)*av_q2d(tb))
+
+static int filter_frame(AVFilterLink *inlink, AVFrame *in)
+{
+ EvalContext *eval = inlink->dst->priv;
+ AVFilterLink *outlink = inlink->dst->outputs[0];
+ int nb_samples = in->nb_samples;
+ AVFrame *out;
+ double t0;
+ int i, j;
+
+ /* do volume scaling in-place if input buffer is writable */
+ out = ff_get_audio_buffer(outlink, nb_samples);
+ if (!out)
+ return AVERROR(ENOMEM);
+ av_frame_copy_props(out, in);
+
+ t0 = TS2T(in->pts, inlink->time_base);
+
+ /* evaluate expression for each single sample and for each channel */
+ for (i = 0; i < nb_samples; i++, eval->n++) {
+ eval->var_values[VAR_N] = eval->n;
+ eval->var_values[VAR_T] = t0 + i * (double)1/inlink->sample_rate;
+
+ for (j = 0; j < inlink->channels; j++)
+ eval->channel_values[j] = *((double *) in->extended_data[j] + i);
+
+ for (j = 0; j < outlink->channels; j++) {
+ eval->var_values[VAR_CH] = j;
+ *((double *) out->extended_data[j] + i) =
+ av_expr_eval(eval->expr[j], eval->var_values, eval);
+ }
+ }
+
+ av_frame_free(&in);
+ return ff_filter_frame(outlink, out);
+}
+
+#if CONFIG_AEVAL_FILTER
+
+static const AVFilterPad aeval_inputs[] = {
+ {
+ .name = "default",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .filter_frame = filter_frame,
+ },
+ { NULL }
+};
+
+static const AVFilterPad aeval_outputs[] = {
+ {
+ .name = "default",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .config_props = aeval_config_output,
+ },
+ { NULL }
+};
+
+AVFilter ff_af_aeval = {
+ .name = "aeval",
+ .description = NULL_IF_CONFIG_SMALL("Filter audio signal according to a specified expression."),
+ .query_formats = aeval_query_formats,
+ .init = init,
+ .uninit = uninit,
+ .priv_size = sizeof(EvalContext),
+ .inputs = aeval_inputs,
+ .outputs = aeval_outputs,
+ .priv_class = &aeval_class,
+};
+
+#endif /* CONFIG_AEVAL_FILTER */
diff --git a/libavfilter/af_aconvert.c b/libavfilter/af_aconvert.c
index a198d2b..19095cb 100644
--- a/libavfilter/af_aconvert.c
+++ b/libavfilter/af_aconvert.c
@@ -66,7 +66,7 @@
(ret = ff_parse_sample_format(&aconvert->out_sample_fmt, aconvert->format_str, ctx)) < 0)
return ret;
if (aconvert->channel_layout_str && strcmp(aconvert->channel_layout_str, "auto"))
- return ff_parse_channel_layout(&aconvert->out_chlayout, aconvert->channel_layout_str, ctx);
+ return ff_parse_channel_layout(&aconvert->out_chlayout, NULL, aconvert->channel_layout_str, ctx);
return ret;
}
@@ -183,7 +183,7 @@
{ NULL }
};
-AVFilter avfilter_af_aconvert = {
+AVFilter ff_af_aconvert = {
.name = "aconvert",
.description = NULL_IF_CONFIG_SMALL("Convert the input audio to sample_fmt:channel_layout."),
.priv_size = sizeof(AConvertContext),
diff --git a/libavfilter/af_adelay.c b/libavfilter/af_adelay.c
index d51264f..363b84d 100644
--- a/libavfilter/af_adelay.c
+++ b/libavfilter/af_adelay.c
@@ -270,7 +270,7 @@
{ NULL }
};
-AVFilter avfilter_af_adelay = {
+AVFilter ff_af_adelay = {
.name = "adelay",
.description = NULL_IF_CONFIG_SMALL("Delay one or more audio channels."),
.query_formats = query_formats,
diff --git a/libavfilter/af_aecho.c b/libavfilter/af_aecho.c
index 0c3ba2f..8355e8c 100644
--- a/libavfilter/af_aecho.c
+++ b/libavfilter/af_aecho.c
@@ -285,10 +285,11 @@
s->echo_samples(s, s->delayptrs, frame->extended_data, out_frame->extended_data,
frame->nb_samples, inlink->channels);
+ s->next_pts = frame->pts + av_rescale_q(frame->nb_samples, (AVRational){1, inlink->sample_rate}, inlink->time_base);
+
if (frame != out_frame)
av_frame_free(&frame);
- s->next_pts = frame->pts + av_rescale_q(frame->nb_samples, (AVRational){1, inlink->sample_rate}, inlink->time_base);
return ff_filter_frame(ctx->outputs[0], out_frame);
}
@@ -346,7 +347,7 @@
{ NULL }
};
-AVFilter avfilter_af_aecho = {
+AVFilter ff_af_aecho = {
.name = "aecho",
.description = NULL_IF_CONFIG_SMALL("Add echoing to the audio."),
.query_formats = query_formats,
diff --git a/libavfilter/af_afade.c b/libavfilter/af_afade.c
index 2ffb962..fbf9802 100644
--- a/libavfilter/af_afade.c
+++ b/libavfilter/af_afade.c
@@ -287,7 +287,7 @@
{ NULL }
};
-AVFilter avfilter_af_afade = {
+AVFilter ff_af_afade = {
.name = "afade",
.description = NULL_IF_CONFIG_SMALL("Fade in/out input audio."),
.query_formats = query_formats,
diff --git a/libavfilter/af_aformat.c b/libavfilter/af_aformat.c
index 0239f63..5fd0308 100644
--- a/libavfilter/af_aformat.c
+++ b/libavfilter/af_aformat.c
@@ -135,7 +135,7 @@
{ NULL }
};
-AVFilter avfilter_af_aformat = {
+AVFilter ff_af_aformat = {
.name = "aformat",
.description = NULL_IF_CONFIG_SMALL("Convert the input audio to one of the specified formats."),
.init = init,
diff --git a/libavfilter/af_amerge.c b/libavfilter/af_amerge.c
index 47e7ee6..82b694b 100644
--- a/libavfilter/af_amerge.c
+++ b/libavfilter/af_amerge.c
@@ -335,7 +335,7 @@
{ NULL }
};
-AVFilter avfilter_af_amerge = {
+AVFilter ff_af_amerge = {
.name = "amerge",
.description = NULL_IF_CONFIG_SMALL("Merge two or more audio streams into "
"a single multi-channel stream."),
diff --git a/libavfilter/af_amix.c b/libavfilter/af_amix.c
index 0902c2a..7140b6c 100644
--- a/libavfilter/af_amix.c
+++ b/libavfilter/af_amix.c
@@ -546,7 +546,7 @@
{ NULL }
};
-AVFilter avfilter_af_amix = {
+AVFilter ff_af_amix = {
.name = "amix",
.description = NULL_IF_CONFIG_SMALL("Audio mixing."),
.priv_size = sizeof(MixContext),
diff --git a/libavfilter/af_anull.c b/libavfilter/af_anull.c
index 09791a7..fff456e 100644
--- a/libavfilter/af_anull.c
+++ b/libavfilter/af_anull.c
@@ -43,7 +43,7 @@
{ NULL }
};
-AVFilter avfilter_af_anull = {
+AVFilter ff_af_anull = {
.name = "anull",
.description = NULL_IF_CONFIG_SMALL("Pass the source unchanged to the output."),
.query_formats = ff_query_formats_all,
diff --git a/libavfilter/af_apad.c b/libavfilter/af_apad.c
index f1c3a78..88a3a77 100644
--- a/libavfilter/af_apad.c
+++ b/libavfilter/af_apad.c
@@ -144,7 +144,7 @@
{ NULL }
};
-AVFilter avfilter_af_apad = {
+AVFilter ff_af_apad = {
.name = "apad",
.description = NULL_IF_CONFIG_SMALL("Pad audio with silence."),
.init = init,
diff --git a/libavfilter/af_aphaser.c b/libavfilter/af_aphaser.c
index 5ac99f3..0fc45ea 100644
--- a/libavfilter/af_aphaser.c
+++ b/libavfilter/af_aphaser.c
@@ -345,7 +345,7 @@
{ NULL }
};
-AVFilter avfilter_af_aphaser = {
+AVFilter ff_af_aphaser = {
.name = "aphaser",
.description = NULL_IF_CONFIG_SMALL("Add a phasing effect to the audio."),
.query_formats = query_formats,
diff --git a/libavfilter/af_aresample.c b/libavfilter/af_aresample.c
index 7b6ab68..e05c0a1 100644
--- a/libavfilter/af_aresample.c
+++ b/libavfilter/af_aresample.c
@@ -170,11 +170,18 @@
{
AResampleContext *aresample = inlink->dst->priv;
const int n_in = insamplesref->nb_samples;
- int n_out = n_in * aresample->ratio * 2 + 256;
+ int64_t delay;
+ int n_out = n_in * aresample->ratio + 32;
AVFilterLink *const outlink = inlink->dst->outputs[0];
- AVFrame *outsamplesref = ff_get_audio_buffer(outlink, n_out);
+ AVFrame *outsamplesref;
int ret;
+ delay = swr_get_delay(aresample->swr, outlink->sample_rate);
+ if (delay > 0)
+ n_out += delay;
+
+ outsamplesref = ff_get_audio_buffer(outlink, n_out);
+
if(!outsamplesref)
return AVERROR(ENOMEM);
@@ -223,10 +230,15 @@
if (ret == AVERROR_EOF) {
AVFrame *outsamplesref;
int n_out = 4096;
+ int64_t pts;
outsamplesref = ff_get_audio_buffer(outlink, n_out);
if (!outsamplesref)
return AVERROR(ENOMEM);
+
+ pts = swr_next_pts(aresample->swr, INT64_MIN);
+ pts = ROUNDED_DIV(pts, inlink->sample_rate);
+
n_out = swr_convert(aresample->swr, outsamplesref->extended_data, n_out, 0, 0);
if (n_out <= 0) {
av_frame_free(&outsamplesref);
@@ -235,14 +247,8 @@
outsamplesref->sample_rate = outlink->sample_rate;
outsamplesref->nb_samples = n_out;
-#if 0
- outsamplesref->pts = aresample->next_pts;
- if(aresample->next_pts != AV_NOPTS_VALUE)
- aresample->next_pts += av_rescale_q(n_out, (AVRational){1 ,outlink->sample_rate}, outlink->time_base);
-#else
- outsamplesref->pts = swr_next_pts(aresample->swr, INT64_MIN);
- outsamplesref->pts = ROUNDED_DIV(outsamplesref->pts, inlink->sample_rate);
-#endif
+
+ outsamplesref->pts = pts;
return ff_filter_frame(outlink, outsamplesref);
}
@@ -296,7 +302,7 @@
{ NULL }
};
-AVFilter avfilter_af_aresample = {
+AVFilter ff_af_aresample = {
.name = "aresample",
.description = NULL_IF_CONFIG_SMALL("Resample audio data."),
.init_dict = init_dict,
diff --git a/libavfilter/af_asetnsamples.c b/libavfilter/af_asetnsamples.c
index bca8fa6..fbcf275 100644
--- a/libavfilter/af_asetnsamples.c
+++ b/libavfilter/af_asetnsamples.c
@@ -184,7 +184,7 @@
{ NULL }
};
-AVFilter avfilter_af_asetnsamples = {
+AVFilter ff_af_asetnsamples = {
.name = "asetnsamples",
.description = NULL_IF_CONFIG_SMALL("Set the number of samples for each output audio frames."),
.priv_size = sizeof(ASNSContext),
diff --git a/libavfilter/af_asetrate.c b/libavfilter/af_asetrate.c
index e031b89..0d06915 100644
--- a/libavfilter/af_asetrate.c
+++ b/libavfilter/af_asetrate.c
@@ -107,7 +107,7 @@
{ NULL }
};
-AVFilter avfilter_af_asetrate = {
+AVFilter ff_af_asetrate = {
.name = "asetrate",
.description = NULL_IF_CONFIG_SMALL("Change the sample rate without "
"altering the data."),
diff --git a/libavfilter/af_ashowinfo.c b/libavfilter/af_ashowinfo.c
index d08c7da..783f9a6 100644
--- a/libavfilter/af_ashowinfo.c
+++ b/libavfilter/af_ashowinfo.c
@@ -116,7 +116,7 @@
{ NULL }
};
-AVFilter avfilter_af_ashowinfo = {
+AVFilter ff_af_ashowinfo = {
.name = "ashowinfo",
.description = NULL_IF_CONFIG_SMALL("Show textual information for each audio frame."),
.priv_size = sizeof(AShowInfoContext),
diff --git a/libavfilter/af_astats.c b/libavfilter/af_astats.c
index f6a2045..60ccd73 100644
--- a/libavfilter/af_astats.c
+++ b/libavfilter/af_astats.c
@@ -262,7 +262,7 @@
{ NULL }
};
-AVFilter avfilter_af_astats = {
+AVFilter ff_af_astats = {
.name = "astats",
.description = NULL_IF_CONFIG_SMALL("Show time domain statistics about audio frames."),
.query_formats = query_formats,
diff --git a/libavfilter/af_astreamsync.c b/libavfilter/af_astreamsync.c
index 1ea3a8a..becfe34 100644
--- a/libavfilter/af_astreamsync.c
+++ b/libavfilter/af_astreamsync.c
@@ -226,7 +226,7 @@
{ NULL }
};
-AVFilter avfilter_af_astreamsync = {
+AVFilter ff_af_astreamsync = {
.name = "astreamsync",
.description = NULL_IF_CONFIG_SMALL("Copy two streams of audio data "
"in a configurable order."),
diff --git a/libavfilter/af_asyncts.c b/libavfilter/af_asyncts.c
index 6a3c15c..5f8e1f6 100644
--- a/libavfilter/af_asyncts.c
+++ b/libavfilter/af_asyncts.c
@@ -16,6 +16,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <stdint.h>
+
#include "libavresample/avresample.h"
#include "libavutil/attributes.h"
#include "libavutil/audio_fifo.h"
@@ -309,7 +311,7 @@
{ NULL }
};
-AVFilter avfilter_af_asyncts = {
+AVFilter ff_af_asyncts = {
.name = "asyncts",
.description = NULL_IF_CONFIG_SMALL("Sync audio data to timestamps"),
.init = init,
diff --git a/libavfilter/af_atempo.c b/libavfilter/af_atempo.c
index ad12786..c474d6a 100644
--- a/libavfilter/af_atempo.c
+++ b/libavfilter/af_atempo.c
@@ -1182,7 +1182,7 @@
{ NULL }
};
-AVFilter avfilter_af_atempo = {
+AVFilter ff_af_atempo = {
.name = "atempo",
.description = NULL_IF_CONFIG_SMALL("Adjust audio tempo."),
.init = init,
diff --git a/libavfilter/af_biquads.c b/libavfilter/af_biquads.c
index 7d7f9f3..5bafad1 100644
--- a/libavfilter/af_biquads.c
+++ b/libavfilter/af_biquads.c
@@ -454,7 +454,7 @@
return init(ctx); \
} \
\
-AVFilter avfilter_af_##name_ = { \
+AVFilter ff_af_##name_ = { \
.name = #name_, \
.description = NULL_IF_CONFIG_SMALL(description_), \
.priv_size = sizeof(BiquadsContext), \
diff --git a/libavfilter/af_channelmap.c b/libavfilter/af_channelmap.c
index be5143a..e5e8987 100644
--- a/libavfilter/af_channelmap.c
+++ b/libavfilter/af_channelmap.c
@@ -397,7 +397,7 @@
{ NULL }
};
-AVFilter avfilter_af_channelmap = {
+AVFilter ff_af_channelmap = {
.name = "channelmap",
.description = NULL_IF_CONFIG_SMALL("Remap audio channels."),
.init = channelmap_init,
diff --git a/libavfilter/af_channelsplit.c b/libavfilter/af_channelsplit.c
index 64db6b4..b3756e2 100644
--- a/libavfilter/af_channelsplit.c
+++ b/libavfilter/af_channelsplit.c
@@ -136,7 +136,7 @@
{ NULL }
};
-AVFilter avfilter_af_channelsplit = {
+AVFilter ff_af_channelsplit = {
.name = "channelsplit",
.description = NULL_IF_CONFIG_SMALL("Split audio into per-channel streams."),
.priv_size = sizeof(ChannelSplitContext),
diff --git a/libavfilter/af_compand.c b/libavfilter/af_compand.c
index 586ac2f..ec1e962 100644
--- a/libavfilter/af_compand.c
+++ b/libavfilter/af_compand.c
@@ -505,7 +505,7 @@
{ NULL }
};
-AVFilter avfilter_af_compand = {
+AVFilter ff_af_compand = {
.name = "compand",
.description = NULL_IF_CONFIG_SMALL("Compress or expand audio dynamic range."),
.query_formats = query_formats,
diff --git a/libavfilter/af_earwax.c b/libavfilter/af_earwax.c
index 3db4659..c310997 100644
--- a/libavfilter/af_earwax.c
+++ b/libavfilter/af_earwax.c
@@ -162,7 +162,7 @@
{ NULL }
};
-AVFilter avfilter_af_earwax = {
+AVFilter ff_af_earwax = {
.name = "earwax",
.description = NULL_IF_CONFIG_SMALL("Widen the stereo image."),
.query_formats = query_formats,
diff --git a/libavfilter/af_join.c b/libavfilter/af_join.c
index a266a24..3e9ccc8 100644
--- a/libavfilter/af_join.c
+++ b/libavfilter/af_join.c
@@ -501,7 +501,7 @@
{ NULL }
};
-AVFilter avfilter_af_join = {
+AVFilter ff_af_join = {
.name = "join",
.description = NULL_IF_CONFIG_SMALL("Join multiple audio streams into "
"multi-channel output."),
diff --git a/libavfilter/af_ladspa.c b/libavfilter/af_ladspa.c
index 7578a38..2057e6d 100644
--- a/libavfilter/af_ladspa.c
+++ b/libavfilter/af_ladspa.c
@@ -450,9 +450,11 @@
count_ports(desc, &inputs, &outputs);
av_log(ctx, AV_LOG_INFO, "%lu:%lu %-25s %s\n", inputs, outputs, desc->Label,
- av_x_if_null(desc->Name, "?"));
- av_log(ctx, AV_LOG_VERBOSE, "Maker: %s\n", av_x_if_null(desc->Maker, "?"));
- av_log(ctx, AV_LOG_VERBOSE, "Copyright: %s\n", av_x_if_null(desc->Copyright, "?"));
+ (char *)av_x_if_null(desc->Name, "?"));
+ av_log(ctx, AV_LOG_VERBOSE, "Maker: %s\n",
+ (char *)av_x_if_null(desc->Maker, "?"));
+ av_log(ctx, AV_LOG_VERBOSE, "Copyright: %s\n",
+ (char *)av_x_if_null(desc->Copyright, "?"));
}
return AVERROR_EXIT;
} else {
@@ -688,7 +690,7 @@
{ NULL }
};
-AVFilter avfilter_af_ladspa = {
+AVFilter ff_af_ladspa = {
.name = "ladspa",
.description = NULL_IF_CONFIG_SMALL("Apply LADSPA effect."),
.priv_size = sizeof(LADSPAContext),
diff --git a/libavfilter/af_pan.c b/libavfilter/af_pan.c
index 9cee9d9..d28f382 100644
--- a/libavfilter/af_pan.c
+++ b/libavfilter/af_pan.c
@@ -46,7 +46,6 @@
double gain[MAX_CHANNELS][MAX_CHANNELS];
int64_t need_renorm;
int need_renumber;
- int nb_input_channels;
int nb_output_channels;
int pure_gains;
@@ -116,10 +115,10 @@
if (!args)
return AVERROR(ENOMEM);
arg = av_strtok(args, "|", &tokenizer);
- ret = ff_parse_channel_layout(&pan->out_channel_layout, arg, ctx);
+ ret = ff_parse_channel_layout(&pan->out_channel_layout,
+ &pan->nb_output_channels, arg, ctx);
if (ret < 0)
goto fail;
- pan->nb_output_channels = av_get_channel_layout_nb_channels(pan->out_channel_layout);
/* parse channel specifications */
while ((arg = arg0 = av_strtok(NULL, "|", &tokenizer))) {
@@ -239,12 +238,14 @@
ff_set_common_samplerates(ctx, formats);
// inlink supports any channel layout
- layouts = ff_all_channel_layouts();
+ layouts = ff_all_channel_counts();
ff_channel_layouts_ref(layouts, &inlink->out_channel_layouts);
// outlink supports only requested output channel layout
layouts = NULL;
- ff_add_channel_layout(&layouts, pan->out_channel_layout);
+ ff_add_channel_layout(&layouts,
+ pan->out_channel_layout ? pan->out_channel_layout :
+ FF_COUNT2LAYOUT(pan->nb_output_channels));
ff_channel_layouts_ref(layouts, &outlink->in_channel_layouts);
return 0;
}
@@ -257,7 +258,6 @@
int i, j, k, r;
double t;
- pan->nb_input_channels = av_get_channel_layout_nb_channels(link->channel_layout);
if (pan->need_renumber) {
// input channels were given by their name: renumber them
for (i = j = 0; i < MAX_CHANNELS; i++) {
@@ -271,7 +271,7 @@
// sanity check; can't be done in query_formats since the inlink
// channel layout is unknown at that time
- if (pan->nb_input_channels > SWR_CH_MAX ||
+ if (link->channels > SWR_CH_MAX ||
pan->nb_output_channels > SWR_CH_MAX) {
av_log(ctx, AV_LOG_ERROR,
"libswresample support a maximum of %d channels. "
@@ -286,6 +286,10 @@
0, ctx);
if (!pan->swr)
return AVERROR(ENOMEM);
+ if (!link->channel_layout)
+ av_opt_set_int(pan->swr, "ich", link->channels, 0);
+ if (!pan->out_channel_layout)
+ av_opt_set_int(pan->swr, "och", pan->nb_output_channels, 0);
// gains are pure, init the channel mapping
if (pan->pure_gains) {
@@ -293,7 +297,7 @@
// get channel map from the pure gains
for (i = 0; i < pan->nb_output_channels; i++) {
int ch_id = -1;
- for (j = 0; j < pan->nb_input_channels; j++) {
+ for (j = 0; j < link->channels; j++) {
if (pan->gain[i][j]) {
ch_id = j;
break;
@@ -311,7 +315,7 @@
if (!((pan->need_renorm >> i) & 1))
continue;
t = 0;
- for (j = 0; j < pan->nb_input_channels; j++)
+ for (j = 0; j < link->channels; j++)
t += pan->gain[i][j];
if (t > -1E-5 && t < 1E-5) {
// t is almost 0 but not exactly, this is probably a mistake
@@ -320,7 +324,7 @@
"Degenerate coefficients while renormalizing\n");
continue;
}
- for (j = 0; j < pan->nb_input_channels; j++)
+ for (j = 0; j < link->channels; j++)
pan->gain[i][j] /= t;
}
av_opt_set_int(pan->swr, "icl", link->channel_layout, 0);
@@ -335,7 +339,7 @@
// summary
for (i = 0; i < pan->nb_output_channels; i++) {
cur = buf;
- for (j = 0; j < pan->nb_input_channels; j++) {
+ for (j = 0; j < link->channels; j++) {
r = snprintf(cur, buf + sizeof(buf) - cur, "%s%.3g i%d",
j ? " + " : "", pan->gain[i][j], j);
cur += FFMIN(buf + sizeof(buf) - cur, r);
@@ -409,7 +413,7 @@
{ NULL }
};
-AVFilter avfilter_af_pan = {
+AVFilter ff_af_pan = {
.name = "pan",
.description = NULL_IF_CONFIG_SMALL("Remix channels with coefficients (panning)."),
.priv_size = sizeof(PanContext),
diff --git a/libavfilter/af_replaygain.c b/libavfilter/af_replaygain.c
new file mode 100644
index 0000000..c419857
--- /dev/null
+++ b/libavfilter/af_replaygain.c
@@ -0,0 +1,613 @@
+/*
+ * Copyright (c) 1998 - 2009 Conifer Software
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * ReplayGain scanner
+ */
+
+#include "libavutil/avassert.h"
+#include "libavutil/channel_layout.h"
+#include "audio.h"
+#include "avfilter.h"
+#include "internal.h"
+
+#define HISTOGRAM_SLOTS 12000
+#define BUTTER_ORDER 2
+#define YULE_ORDER 10
+
+typedef struct ReplayGainFreqInfo {
+ int sample_rate;
+ double BYule[YULE_ORDER + 1];
+ double AYule[YULE_ORDER + 1];
+ double BButter[BUTTER_ORDER + 1];
+ double AButter[BUTTER_ORDER + 1];
+} ReplayGainFreqInfo;
+
+static const ReplayGainFreqInfo freqinfos[] =
+{
+ {
+ 192000,
+ { 0.01184742123123, -0.04631092400086, 0.06584226961238,
+ -0.02165588522478, -0.05656260778952, 0.08607493592760,
+ -0.03375544339786, -0.04216579932754, 0.06416711490648,
+ -0.03444708260844, 0.00697275872241 },
+ { 1.00000000000000, -5.24727318348167, 10.60821585192244,
+ -8.74127665810413, -1.33906071371683, 8.07972882096606,
+ -5.46179918950847, 0.54318070652536, 0.87450969224280,
+ -0.34656083539754, 0.03034796843589 },
+ { 0.99653501465135, -1.99307002930271, 0.99653501465135 },
+ { 1.00000000000000, -1.99305802314321, 0.99308203546221 },
+ },
+ {
+ 176400,
+ { 0.00268568524529, -0.00852379426080, 0.00852704191347,
+ 0.00146116310295, -0.00950855828762, 0.00625449515499,
+ 0.00116183868722, -0.00362461417136, 0.00203961000134,
+ -0.00050664587933, 0.00004327455427 },
+ { 1.00000000000000, -5.57512782763045, 12.44291056065794,
+ -12.87462799681221, 3.08554846961576, 6.62493459880692,
+ -7.07662766313248, 2.51175542736441, 0.06731510802735,
+ -0.24567753819213, 0.03961404162376 },
+ { 0.99622916581118, -1.99245833162236, 0.99622916581118 },
+ { 1.00000000000000, -1.99244411238133, 0.99247255086339 },
+ },
+ {
+ 144000,
+ { 0.00639682359450, -0.02556437970955, 0.04230854400938,
+ -0.03722462201267, 0.01718514827295, 0.00610592243009,
+ -0.03065965747365, 0.04345745003539, -0.03298592681309,
+ 0.01320937236809, -0.00220304127757 },
+ { 1.00000000000000, -6.14814623523425, 15.80002457141566,
+ -20.78487587686937, 11.98848552310315, 3.36462015062606,
+ -10.22419868359470, 6.65599702146473, -1.67141861110485,
+ -0.05417956536718, 0.07374767867406 },
+ { 0.99538268958706, -1.99076537917413, 0.99538268958706 },
+ { 1.00000000000000, -1.99074405950505, 0.99078669884321 },
+ },
+ {
+ 128000,
+ { 0.00553120584305, -0.02112620545016, 0.03549076243117,
+ -0.03362498312306, 0.01425867248183, 0.01344686928787,
+ -0.03392770787836, 0.03464136459530, -0.02039116051549,
+ 0.00667420794705, -0.00093763762995 },
+ { 1.00000000000000, -6.14581710839925, 16.04785903675838,
+ -22.19089131407749, 15.24756471580286, -0.52001440400238,
+ -8.00488641699940, 6.60916094768855, -2.37856022810923,
+ 0.33106947986101, 0.00459820832036 },
+ { 0.99480702681278, -1.98961405362557, 0.99480702681278 },
+ { 1.00000000000000, -1.98958708647324, 0.98964102077790 },
+ },
+ {
+ 112000,
+ { 0.00528778718259, -0.01893240907245, 0.03185982561867,
+ -0.02926260297838, 0.00715743034072, 0.01985743355827,
+ -0.03222614850941, 0.02565681978192, -0.01210662313473,
+ 0.00325436284541, -0.00044173593001 },
+ { 1.00000000000000, -6.24932108456288, 17.42344320538476,
+ -27.86819709054896, 26.79087344681326,-13.43711081485123,
+ -0.66023612948173, 6.03658091814935, -4.24926577030310,
+ 1.40829268709186, -0.19480852628112 },
+ { 0.99406737810867, -1.98813475621734, 0.99406737810867 },
+ { 1.00000000000000, -1.98809955990514, 0.98816995252954 },
+ },
+ {
+ 96000,
+ { 0.00588138296683, -0.01613559730421, 0.02184798954216,
+ -0.01742490405317, 0.00464635643780, 0.01117772513205,
+ -0.02123865824368, 0.01959354413350, -0.01079720643523,
+ 0.00352183686289, -0.00063124341421 },
+ { 1.00000000000000, -5.97808823642008, 16.21362507964068,
+ -25.72923730652599, 25.40470663139513,-14.66166287771134,
+ 2.81597484359752, 2.51447125969733, -2.23575306985286,
+ 0.75788151036791, -0.10078025199029 },
+ { 0.99308203517541, -1.98616407035082, 0.99308203517541 },
+ { 1.00000000000000, -1.98611621154089, 0.98621192916075 },
+ },
+ {
+ 88200,
+ { 0.02667482047416, -0.11377479336097, 0.23063167910965,
+ -0.30726477945593, 0.33188520686529, -0.33862680249063,
+ 0.31807161531340, -0.23730796929880, 0.12273894790371,
+ -0.03840017967282, 0.00549673387936 },
+ { 1.00000000000000, -6.31836451657302, 18.31351310801799,
+ -31.88210014815921, 36.53792146976740,-28.23393036467559,
+ 14.24725258227189, -4.04670980012854, 0.18865757280515,
+ 0.25420333563908, -0.06012333531065 },
+ { 0.99247255046129, -1.98494510092259, 0.99247255046129 },
+ { 1.00000000000000, -1.98488843762335, 0.98500176422183 },
+ },
+ {
+ 64000,
+ { 0.02613056568174, -0.08128786488109, 0.14937282347325,
+ -0.21695711675126, 0.25010286673402, -0.23162283619278,
+ 0.17424041833052, -0.10299599216680, 0.04258696481981,
+ -0.00977952936493, 0.00105325558889 },
+ { 1.00000000000000, -5.73625477092119, 16.15249794355035,
+ -29.68654912464508, 39.55706155674083,-39.82524556246253,
+ 30.50605345013009,-17.43051772821245, 7.05154573908017,
+ -1.80783839720514, 0.22127840210813 },
+ { 0.98964101933472, -1.97928203866944, 0.98964101933472 },
+ { 1.00000000000000, -1.97917472731009, 0.97938935002880 },
+ },
+ {
+ 56000,
+ { 0.03144914734085, -0.06151729206963, 0.08066788708145,
+ -0.09737939921516, 0.08943210803999, -0.06989984672010,
+ 0.04926972841044, -0.03161257848451, 0.01456837493506,
+ -0.00316015108496, 0.00132807215875 },
+ { 1.00000000000000, -4.87377313090032, 12.03922160140209,
+ -20.10151118381395, 25.10388534415171,-24.29065560815903,
+ 18.27158469090663,-10.45249552560593, 4.30319491872003,
+ -1.13716992070185, 0.14510733527035 },
+ { 0.98816995007392, -1.97633990014784, 0.98816995007392 },
+ { 1.00000000000000, -1.97619994516973, 0.97647985512594 },
+ },
+ {
+ 48000,
+ { 0.03857599435200, -0.02160367184185, -0.00123395316851,
+ -0.00009291677959, -0.01655260341619, 0.02161526843274,
+ -0.02074045215285, 0.00594298065125, 0.00306428023191,
+ 0.00012025322027, 0.00288463683916 },
+ { 1.00000000000000, -3.84664617118067, 7.81501653005538,
+ -11.34170355132042, 13.05504219327545,-12.28759895145294,
+ 9.48293806319790, -5.87257861775999, 2.75465861874613,
+ -0.86984376593551, 0.13919314567432 },
+ { 0.98621192462708, -1.97242384925416, 0.98621192462708 },
+ { 1.00000000000000, -1.97223372919527, 0.97261396931306 },
+ },
+ {
+ 44100,
+ { 0.05418656406430, -0.02911007808948, -0.00848709379851,
+ -0.00851165645469, -0.00834990904936, 0.02245293253339,
+ -0.02596338512915, 0.01624864962975, -0.00240879051584,
+ 0.00674613682247, -0.00187763777362 },
+ { 1.00000000000000, -3.47845948550071, 6.36317777566148,
+ -8.54751527471874, 9.47693607801280, -8.81498681370155,
+ 6.85401540936998, -4.39470996079559, 2.19611684890774,
+ -0.75104302451432, 0.13149317958808 },
+ { 0.98500175787242, -1.97000351574484, 0.98500175787242 },
+ { 1.00000000000000, -1.96977855582618, 0.97022847566350 },
+ },
+ {
+ 37800,
+ { 0.08717879977844, -0.01000374016172, -0.06265852122368,
+ -0.01119328800950, -0.00114279372960, 0.02081333954769,
+ -0.01603261863207, 0.01936763028546, 0.00760044736442,
+ -0.00303979112271, -0.00075088605788 },
+ { 1.00000000000000, -2.62816311472146, 3.53734535817992,
+ -3.81003448678921, 3.91291636730132, -3.53518605896288,
+ 2.71356866157873, -1.86723311846592, 1.12075382367659,
+ -0.48574086886890, 0.11330544663849 },
+ { 0.98252400815195, -1.96504801630391, 0.98252400815195 },
+ { 1.00000000000000, -1.96474258269041, 0.96535344991740 },
+ },
+ {
+ 32000,
+ { 0.15457299681924, -0.09331049056315, -0.06247880153653,
+ 0.02163541888798, -0.05588393329856, 0.04781476674921,
+ 0.00222312597743, 0.03174092540049, -0.01390589421898,
+ 0.00651420667831, -0.00881362733839 },
+ { 1.00000000000000, -2.37898834973084, 2.84868151156327,
+ -2.64577170229825, 2.23697657451713, -1.67148153367602,
+ 1.00595954808547, -0.45953458054983, 0.16378164858596,
+ -0.05032077717131, 0.02347897407020 },
+ { 0.97938932735214, -1.95877865470428, 0.97938932735214 },
+ { 1.00000000000000, -1.95835380975398, 0.95920349965459 },
+ },
+ {
+ 24000,
+ { 0.30296907319327, -0.22613988682123, -0.08587323730772,
+ 0.03282930172664, -0.00915702933434, -0.02364141202522,
+ -0.00584456039913, 0.06276101321749, -0.00000828086748,
+ 0.00205861885564, -0.02950134983287 },
+ { 1.00000000000000, -1.61273165137247, 1.07977492259970,
+ -0.25656257754070, -0.16276719120440, -0.22638893773906,
+ 0.39120800788284, -0.22138138954925, 0.04500235387352,
+ 0.02005851806501, 0.00302439095741 },
+ { 0.97531843204928, -1.95063686409857, 0.97531843204928 },
+ { 1.00000000000000, -1.95002759149878, 0.95124613669835 },
+ },
+ {
+ 22050,
+ { 0.33642304856132, -0.25572241425570, -0.11828570177555,
+ 0.11921148675203, -0.07834489609479, -0.00469977914380,
+ -0.00589500224440, 0.05724228140351, 0.00832043980773,
+ -0.01635381384540, -0.01760176568150 },
+ { 1.00000000000000, -1.49858979367799, 0.87350271418188,
+ 0.12205022308084, -0.80774944671438, 0.47854794562326,
+ -0.12453458140019, -0.04067510197014, 0.08333755284107,
+ -0.04237348025746, 0.02977207319925 },
+ { 0.97316523498161, -1.94633046996323, 0.97316523498161 },
+ { 1.00000000000000, -1.94561023566527, 0.94705070426118 },
+ },
+ {
+ 18900,
+ { 0.38524531015142, -0.27682212062067, -0.09980181488805,
+ 0.09951486755646, -0.08934020156622, -0.00322369330199,
+ -0.00110329090689, 0.03784509844682, 0.01683906213303,
+ -0.01147039862572, -0.01941767987192 },
+ { 1.00000000000000, -1.29708918404534, 0.90399339674203,
+ -0.29613799017877, -0.42326645916207, 0.37934887402200,
+ -0.37919795944938, 0.23410283284785, -0.03892971758879,
+ 0.00403009552351, 0.03640166626278 },
+ { 0.96535326815829, -1.93070653631658, 0.96535326815829 },
+ { 1.00000000000000, -1.92950577983524, 0.93190729279793 },
+ },
+ {
+ 16000,
+ { 0.44915256608450, -0.14351757464547, -0.22784394429749,
+ -0.01419140100551, 0.04078262797139, -0.12398163381748,
+ 0.04097565135648, 0.10478503600251, -0.01863887810927,
+ -0.03193428438915, 0.00541907748707 },
+ { 1.00000000000000, -0.62820619233671, 0.29661783706366,
+ -0.37256372942400, 0.00213767857124, -0.42029820170918,
+ 0.22199650564824, 0.00613424350682, 0.06747620744683,
+ 0.05784820375801, 0.03222754072173 },
+ { 0.96454515552826, -1.92909031105652, 0.96454515552826 },
+ { 1.00000000000000, -1.92783286977036, 0.93034775234268 },
+ },
+ {
+ 12000,
+ { 0.56619470757641, -0.75464456939302, 0.16242137742230,
+ 0.16744243493672, -0.18901604199609, 0.30931782841830,
+ -0.27562961986224, 0.00647310677246, 0.08647503780351,
+ -0.03788984554840, -0.00588215443421 },
+ { 1.00000000000000, -1.04800335126349, 0.29156311971249,
+ -0.26806001042947, 0.00819999645858, 0.45054734505008,
+ -0.33032403314006, 0.06739368333110, -0.04784254229033,
+ 0.01639907836189, 0.01807364323573 },
+ { 0.96009142950541, -1.92018285901082, 0.96009142950541 },
+ { 1.00000000000000, -1.91858953033784, 0.92177618768381 },
+ },
+ {
+ 11025,
+ { 0.58100494960553, -0.53174909058578, -0.14289799034253,
+ 0.17520704835522, 0.02377945217615, 0.15558449135573,
+ -0.25344790059353, 0.01628462406333, 0.06920467763959,
+ -0.03721611395801, -0.00749618797172 },
+ { 1.00000000000000, -0.51035327095184, -0.31863563325245,
+ -0.20256413484477, 0.14728154134330, 0.38952639978999,
+ -0.23313271880868, -0.05246019024463, -0.02505961724053,
+ 0.02442357316099, 0.01818801111503 },
+ { 0.95856916599601, -1.91713833199203, 0.95856916599601 },
+ { 1.00000000000000, -1.91542108074780, 0.91885558323625 },
+ },
+ {
+ 8000,
+ { 0.53648789255105, -0.42163034350696, -0.00275953611929,
+ 0.04267842219415, -0.10214864179676, 0.14590772289388,
+ -0.02459864859345, -0.11202315195388, -0.04060034127000,
+ 0.04788665548180, -0.02217936801134 },
+ { 1.00000000000000, -0.25049871956020, -0.43193942311114,
+ -0.03424681017675, -0.04678328784242, 0.26408300200955,
+ 0.15113130533216, -0.17556493366449, -0.18823009262115,
+ 0.05477720428674, 0.04704409688120 },
+ { 0.94597685600279, -1.89195371200558, 0.94597685600279 },
+ { 1.00000000000000, -1.88903307939452, 0.89487434461664 },
+ },
+};
+
+typedef struct ReplayGainContext {
+ uint32_t histogram[HISTOGRAM_SLOTS];
+ float peak;
+ int yule_hist_i, butter_hist_i;
+ const double *yule_coeff_a;
+ const double *yule_coeff_b;
+ const double *butter_coeff_a;
+ const double *butter_coeff_b;
+ float yule_hist_a[256];
+ float yule_hist_b[256];
+ float butter_hist_a[256];
+ float butter_hist_b[256];
+} ReplayGainContext;
+
+static int query_formats(AVFilterContext *ctx)
+{
+ AVFilterFormats *formats = NULL;
+ AVFilterChannelLayouts *layout = NULL;
+ int i;
+
+ ff_add_format(&formats, AV_SAMPLE_FMT_FLT);
+ ff_set_common_formats(ctx, formats);
+ ff_add_channel_layout(&layout, AV_CH_LAYOUT_STEREO);
+ ff_set_common_channel_layouts(ctx, layout);
+
+ formats = NULL;
+ for (i = 0; i < FF_ARRAY_ELEMS(freqinfos); i++)
+ ff_add_format(&formats, freqinfos[i].sample_rate);
+ ff_set_common_samplerates(ctx, formats);
+
+ return 0;
+}
+
+static int config_input(AVFilterLink *inlink)
+{
+ AVFilterContext *ctx = inlink->dst;
+ ReplayGainContext *s = ctx->priv;
+ int i;
+
+ for (i = 0; i < FF_ARRAY_ELEMS(freqinfos); i++) {
+ if (freqinfos[i].sample_rate == inlink->sample_rate)
+ break;
+ }
+ av_assert0(i < FF_ARRAY_ELEMS(freqinfos));
+
+ s->yule_coeff_a = freqinfos[i].AYule;
+ s->yule_coeff_b = freqinfos[i].BYule;
+ s->butter_coeff_a = freqinfos[i].AButter;
+ s->butter_coeff_b = freqinfos[i].BButter;
+
+ s->yule_hist_i = 20;
+ s->butter_hist_i = 4;
+ inlink->partial_buf_size =
+ inlink->min_samples =
+ inlink->max_samples = inlink->sample_rate / 20;
+
+ return 0;
+}
+
+/*
+ * Update largest absolute sample value.
+ */
+static void calc_stereo_peak(const float *samples, int nb_samples,
+ float *peak_p)
+{
+ float peak = 0.0;
+
+ while (nb_samples--) {
+ if (samples[0] > peak)
+ peak = samples[0];
+ else if (-samples[0] > peak)
+ peak = -samples[0];
+
+ if (samples[1] > peak)
+ peak = samples[1];
+ else if (-samples[1] > peak)
+ peak = -samples[1];
+
+ samples += 2;
+ }
+
+ *peak_p = FFMAX(peak, *peak_p);
+}
+
+/*
+ * Calculate stereo RMS level. Minimum value is about -100 dB for
+ * digital silence. The 90 dB offset is to compensate for the
+ * normalized float range and 3 dB is for stereo samples.
+ */
+static double calc_stereo_rms(const float *samples, int nb_samples)
+{
+ int count = nb_samples;
+ double sum = 1e-16;
+
+ while (count--) {
+ sum += samples[0] * samples[0] + samples[1] * samples[1];
+ samples += 2;
+ }
+
+ return 10 * log10 (sum / nb_samples) + 90.0 - 3.0;
+}
+
+/*
+ * Optimized implementation of 2nd-order IIR stereo filter.
+ */
+static void butter_filter_stereo_samples(ReplayGainContext *s,
+ float *samples, int nb_samples)
+{
+ const double *coeff_a = s->butter_coeff_a;
+ const double *coeff_b = s->butter_coeff_b;
+ float *hist_a = s->butter_hist_a;
+ float *hist_b = s->butter_hist_b;
+ double left, right;
+ int i, j;
+
+ i = s->butter_hist_i;
+
+ // If filter history is very small magnitude, clear it completely
+ // to prevent denormals from rattling around in there forever
+ // (slowing us down).
+
+ for (j = -4; j < 0; ++j)
+ if (fabs(hist_a[i + j]) > 1e-10 || fabs(hist_b[i + j]) > 1e-10)
+ break;
+
+ if (!j) {
+ memset(s->butter_hist_a, 0, sizeof(s->butter_hist_a));
+ memset(s->butter_hist_b, 0, sizeof(s->butter_hist_b));
+ }
+
+ while (nb_samples--) {
+ left = (hist_b[i ] = samples[0]) * coeff_b[0];
+ right = (hist_b[i + 1] = samples[1]) * coeff_b[0];
+ left += hist_b[i - 2] * coeff_b[1] - hist_a[i - 2] * coeff_a[1];
+ right += hist_b[i - 1] * coeff_b[1] - hist_a[i - 1] * coeff_a[1];
+ left += hist_b[i - 4] * coeff_b[2] - hist_a[i - 4] * coeff_a[2];
+ right += hist_b[i - 3] * coeff_b[2] - hist_a[i - 3] * coeff_a[2];
+ samples[0] = hist_a[i ] = (float) left;
+ samples[1] = hist_a[i + 1] = (float) right;
+ samples += 2;
+
+ if ((i += 2) == 256) {
+ memcpy(hist_a, hist_a + 252, sizeof(*hist_a) * 4);
+ memcpy(hist_b, hist_b + 252, sizeof(*hist_b) * 4);
+ i = 4;
+ }
+ }
+
+ s->butter_hist_i = i;
+}
+
+/*
+ * Optimized implementation of 10th-order IIR stereo filter.
+ */
+static void yule_filter_stereo_samples(ReplayGainContext *s, const float *src,
+ float *dst, int nb_samples)
+{
+ const double *coeff_a = s->yule_coeff_a;
+ const double *coeff_b = s->yule_coeff_b;
+ float *hist_a = s->yule_hist_a;
+ float *hist_b = s->yule_hist_b;
+ double left, right;
+ int i, j;
+
+ i = s->yule_hist_i;
+
+ // If filter history is very small magnitude, clear it completely to
+ // prevent denormals from rattling around in there forever
+ // (slowing us down).
+
+ for (j = -20; j < 0; ++j)
+ if (fabs(hist_a[i + j]) > 1e-10 || fabs(hist_b[i + j]) > 1e-10)
+ break;
+
+ if (!j) {
+ memset(s->yule_hist_a, 0, sizeof(s->yule_hist_a));
+ memset(s->yule_hist_b, 0, sizeof(s->yule_hist_b));
+ }
+
+ while (nb_samples--) {
+ left = (hist_b[i] = src[0]) * coeff_b[0];
+ right = (hist_b[i + 1] = src[1]) * coeff_b[0];
+ left += hist_b[i - 2] * coeff_b[ 1] - hist_a[i - 2] * coeff_a[1 ];
+ right += hist_b[i - 1] * coeff_b[ 1] - hist_a[i - 1] * coeff_a[1 ];
+ left += hist_b[i - 4] * coeff_b[ 2] - hist_a[i - 4] * coeff_a[2 ];
+ right += hist_b[i - 3] * coeff_b[ 2] - hist_a[i - 3] * coeff_a[2 ];
+ left += hist_b[i - 6] * coeff_b[ 3] - hist_a[i - 6] * coeff_a[3 ];
+ right += hist_b[i - 5] * coeff_b[ 3] - hist_a[i - 5] * coeff_a[3 ];
+ left += hist_b[i - 8] * coeff_b[ 4] - hist_a[i - 8] * coeff_a[4 ];
+ right += hist_b[i - 7] * coeff_b[ 4] - hist_a[i - 7] * coeff_a[4 ];
+ left += hist_b[i - 10] * coeff_b[ 5] - hist_a[i - 10] * coeff_a[5 ];
+ right += hist_b[i - 9] * coeff_b[ 5] - hist_a[i - 9] * coeff_a[5 ];
+ left += hist_b[i - 12] * coeff_b[ 6] - hist_a[i - 12] * coeff_a[6 ];
+ right += hist_b[i - 11] * coeff_b[ 6] - hist_a[i - 11] * coeff_a[6 ];
+ left += hist_b[i - 14] * coeff_b[ 7] - hist_a[i - 14] * coeff_a[7 ];
+ right += hist_b[i - 13] * coeff_b[ 7] - hist_a[i - 13] * coeff_a[7 ];
+ left += hist_b[i - 16] * coeff_b[ 8] - hist_a[i - 16] * coeff_a[8 ];
+ right += hist_b[i - 15] * coeff_b[ 8] - hist_a[i - 15] * coeff_a[8 ];
+ left += hist_b[i - 18] * coeff_b[ 9] - hist_a[i - 18] * coeff_a[9 ];
+ right += hist_b[i - 17] * coeff_b[ 9] - hist_a[i - 17] * coeff_a[9 ];
+ left += hist_b[i - 20] * coeff_b[10] - hist_a[i - 20] * coeff_a[10];
+ right += hist_b[i - 19] * coeff_b[10] - hist_a[i - 19] * coeff_a[10];
+ dst[0] = hist_a[i ] = (float)left;
+ dst[1] = hist_a[i + 1] = (float)right;
+ src += 2;
+ dst += 2;
+
+ if ((i += 2) == 256) {
+ memcpy(hist_a, hist_a + 236, sizeof(*hist_a) * 20);
+ memcpy(hist_b, hist_b + 236, sizeof(*hist_b) * 20);
+ i = 20;
+ }
+ }
+
+ s->yule_hist_i = i;
+}
+
+/*
+ * Calculate the ReplayGain value from the specified loudness histogram;
+ * clip to -24 / +64 dB.
+ */
+static float calc_replaygain(uint32_t *histogram)
+{
+ uint32_t loud_count = 0, total_windows = 0;
+ float gain;
+ int i;
+
+ for (i = 0; i < HISTOGRAM_SLOTS; i++)
+ total_windows += histogram [i];
+
+ while (i--)
+ if ((loud_count += histogram [i]) * 20 >= total_windows)
+ break;
+
+ gain = (float)(64.54 - i / 100.0);
+
+ return av_clipf(gain, -24.0, 64.0);
+}
+
+static int filter_frame(AVFilterLink *inlink, AVFrame *in)
+{
+ AVFilterContext *ctx = inlink->dst;
+ AVFilterLink *outlink = ctx->outputs[0];
+ ReplayGainContext *s = ctx->priv;
+ uint32_t level;
+ AVFrame *out;
+
+ out = ff_get_audio_buffer(inlink, in->nb_samples);
+ if (!out) {
+ av_frame_free(&in);
+ return AVERROR(ENOMEM);
+ }
+
+ calc_stereo_peak((float *)in->data[0],
+ in->nb_samples, &s->peak);
+ yule_filter_stereo_samples(s, (const float *)in->data[0],
+ (float *)out->data[0],
+ out->nb_samples);
+ butter_filter_stereo_samples(s, (float *)out->data[0],
+ out->nb_samples);
+ level = (uint32_t)floor(100 * calc_stereo_rms((float *)out->data[0],
+ out->nb_samples));
+ level = av_clip(level, 0, HISTOGRAM_SLOTS - 1);
+
+ s->histogram[level]++;
+
+ av_frame_free(&out);
+ return ff_filter_frame(outlink, in);
+}
+
+static av_cold void uninit(AVFilterContext *ctx)
+{
+ ReplayGainContext *s = ctx->priv;
+ float gain = calc_replaygain(s->histogram);
+
+ av_log(ctx, AV_LOG_INFO, "track_gain = %+.2f dB\n", gain);
+ av_log(ctx, AV_LOG_INFO, "track_peak = %.6f\n", s->peak);
+}
+
+static const AVFilterPad replaygain_inputs[] = {
+ {
+ .name = "default",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .filter_frame = filter_frame,
+ .config_props = config_input,
+ },
+ { NULL }
+};
+
+static const AVFilterPad replaygain_outputs[] = {
+ {
+ .name = "default",
+ .type = AVMEDIA_TYPE_AUDIO,
+ },
+ { NULL }
+};
+
+AVFilter ff_af_replaygain = {
+ .name = "replaygain",
+ .description = NULL_IF_CONFIG_SMALL("ReplayGain scanner."),
+ .query_formats = query_formats,
+ .uninit = uninit,
+ .priv_size = sizeof(ReplayGainContext),
+ .inputs = replaygain_inputs,
+ .outputs = replaygain_outputs,
+};
diff --git a/libavfilter/af_resample.c b/libavfilter/af_resample.c
index c1f7ef6..bf32aa7 100644
--- a/libavfilter/af_resample.c
+++ b/libavfilter/af_resample.c
@@ -314,7 +314,7 @@
{ NULL }
};
-AVFilter avfilter_af_resample = {
+AVFilter ff_af_resample = {
.name = "resample",
.description = NULL_IF_CONFIG_SMALL("Audio resampling and conversion."),
.priv_size = sizeof(ResampleContext),
diff --git a/libavfilter/af_silencedetect.c b/libavfilter/af_silencedetect.c
index 5dbb964..687d2e7 100644
--- a/libavfilter/af_silencedetect.c
+++ b/libavfilter/af_silencedetect.c
@@ -201,7 +201,7 @@
{ NULL }
};
-AVFilter avfilter_af_silencedetect = {
+AVFilter ff_af_silencedetect = {
.name = "silencedetect",
.description = NULL_IF_CONFIG_SMALL("Detect silence."),
.priv_size = sizeof(SilenceDetectContext),
diff --git a/libavfilter/af_volume.c b/libavfilter/af_volume.c
index a777249..21fe9a1 100644
--- a/libavfilter/af_volume.c
+++ b/libavfilter/af_volume.c
@@ -101,7 +101,7 @@
}
};
- layouts = ff_all_channel_layouts();
+ layouts = ff_all_channel_counts();
if (!layouts)
return AVERROR(ENOMEM);
ff_set_common_channel_layouts(ctx, layouts);
@@ -206,7 +206,7 @@
AVFilterLink *inlink = ctx->inputs[0];
vol->sample_fmt = inlink->format;
- vol->channels = av_get_channel_layout_nb_channels(inlink->channel_layout);
+ vol->channels = inlink->channels;
vol->planes = av_sample_fmt_is_planar(inlink->format) ? vol->channels : 1;
volume_init(vol);
@@ -287,7 +287,7 @@
{ NULL }
};
-AVFilter avfilter_af_volume = {
+AVFilter ff_af_volume = {
.name = "volume",
.description = NULL_IF_CONFIG_SMALL("Change input volume."),
.query_formats = query_formats,
diff --git a/libavfilter/af_volumedetect.c b/libavfilter/af_volumedetect.c
index 20e5a35..5de115e 100644
--- a/libavfilter/af_volumedetect.c
+++ b/libavfilter/af_volumedetect.c
@@ -148,7 +148,7 @@
{ NULL }
};
-AVFilter avfilter_af_volumedetect = {
+AVFilter ff_af_volumedetect = {
.name = "volumedetect",
.description = NULL_IF_CONFIG_SMALL("Detect audio volume."),
.priv_size = sizeof(VolDetectContext),
diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c
index ed11d67..d58e8cc 100644
--- a/libavfilter/allfilters.c
+++ b/libavfilter/allfilters.c
@@ -26,15 +26,15 @@
#define REGISTER_FILTER(X, x, y) \
{ \
- extern AVFilter avfilter_##y##_##x; \
+ extern AVFilter ff_##y##_##x; \
if (CONFIG_##X##_FILTER) \
- avfilter_register(&avfilter_##y##_##x); \
+ avfilter_register(&ff_##y##_##x); \
}
#define REGISTER_FILTER_UNCONDITIONAL(x) \
{ \
- extern AVFilter avfilter_##x; \
- avfilter_register(&avfilter_##x); \
+ extern AVFilter ff_##x; \
+ avfilter_register(&ff_##x); \
}
void avfilter_register_all(void)
@@ -50,6 +50,7 @@
#endif
REGISTER_FILTER(ADELAY, adelay, af);
REGISTER_FILTER(AECHO, aecho, af);
+ REGISTER_FILTER(AEVAL, aeval, af);
REGISTER_FILTER(AFADE, afade, af);
REGISTER_FILTER(AFORMAT, aformat, af);
REGISTER_FILTER(AINTERLEAVE, ainterleave, af);
@@ -90,6 +91,7 @@
REGISTER_FILTER(LADSPA, ladspa, af);
REGISTER_FILTER(LOWPASS, lowpass, af);
REGISTER_FILTER(PAN, pan, af);
+ REGISTER_FILTER(REPLAYGAIN, replaygain, af);
REGISTER_FILTER(RESAMPLE, resample, af);
REGISTER_FILTER(SILENCEDETECT, silencedetect, af);
REGISTER_FILTER(TREBLE, treble, af);
@@ -126,6 +128,7 @@
REGISTER_FILTER(DRAWGRID, drawgrid, vf);
REGISTER_FILTER(DRAWTEXT, drawtext, vf);
REGISTER_FILTER(EDGEDETECT, edgedetect, vf);
+ REGISTER_FILTER(ELBG, elbg, vf);
REGISTER_FILTER(EXTRACTPLANES, extractplanes, vf);
REGISTER_FILTER(FADE, fade, vf);
REGISTER_FILTER(FIELD, field, vf);
@@ -153,6 +156,7 @@
REGISTER_FILTER(LUTRGB, lutrgb, vf);
REGISTER_FILTER(LUTYUV, lutyuv, vf);
REGISTER_FILTER(MCDEINT, mcdeint, vf);
+ REGISTER_FILTER(MERGEPLANES, mergeplanes, vf);
REGISTER_FILTER(MP, mp, vf);
REGISTER_FILTER(MPDECIMATE, mpdecimate, vf);
REGISTER_FILTER(NEGATE, negate, vf);
diff --git a/libavfilter/asink_anullsink.c b/libavfilter/asink_anullsink.c
index 8015da2..9b53d3f 100644
--- a/libavfilter/asink_anullsink.c
+++ b/libavfilter/asink_anullsink.c
@@ -37,7 +37,7 @@
{ NULL },
};
-AVFilter avfilter_asink_anullsink = {
+AVFilter ff_asink_anullsink = {
.name = "anullsink",
.description = NULL_IF_CONFIG_SMALL("Do absolutely nothing with the input audio."),
diff --git a/libavfilter/asrc_aevalsrc.c b/libavfilter/asrc_aevalsrc.c
deleted file mode 100644
index 3f71ac3..0000000
--- a/libavfilter/asrc_aevalsrc.c
+++ /dev/null
@@ -1,242 +0,0 @@
-/*
- * Copyright (c) 2011 Stefano Sabatini
- *
- * This file is part of FFmpeg.
- *
- * FFmpeg is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * FFmpeg is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with FFmpeg; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/**
- * @file
- * eval audio source
- */
-
-#include "libavutil/avassert.h"
-#include "libavutil/avstring.h"
-#include "libavutil/channel_layout.h"
-#include "libavutil/eval.h"
-#include "libavutil/opt.h"
-#include "libavutil/parseutils.h"
-#include "avfilter.h"
-#include "audio.h"
-#include "internal.h"
-
-static const char * const var_names[] = {
- "n", ///< number of frame
- "t", ///< timestamp expressed in seconds
- "s", ///< sample rate
- NULL
-};
-
-enum var_name {
- VAR_N,
- VAR_T,
- VAR_S,
- VAR_VARS_NB
-};
-
-typedef struct {
- const AVClass *class;
- char *sample_rate_str;
- int sample_rate;
- int64_t chlayout;
- char *chlayout_str;
- int nb_channels;
- int64_t pts;
- AVExpr **expr;
- char *exprs;
- int nb_samples; ///< number of samples per requested frame
- int64_t duration;
- uint64_t n;
- double var_values[VAR_VARS_NB];
-} EvalContext;
-
-#define OFFSET(x) offsetof(EvalContext, x)
-#define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
-
-static const AVOption aevalsrc_options[]= {
- { "exprs", "set the '|'-separated list of channels expressions", OFFSET(exprs), AV_OPT_TYPE_STRING, {.str = NULL}, .flags = FLAGS },
- { "nb_samples", "set the number of samples per requested frame", OFFSET(nb_samples), AV_OPT_TYPE_INT, {.i64 = 1024}, 0, INT_MAX, FLAGS },
- { "n", "set the number of samples per requested frame", OFFSET(nb_samples), AV_OPT_TYPE_INT, {.i64 = 1024}, 0, INT_MAX, FLAGS },
- { "sample_rate", "set the sample rate", OFFSET(sample_rate_str), AV_OPT_TYPE_STRING, {.str = "44100"}, CHAR_MIN, CHAR_MAX, FLAGS },
- { "s", "set the sample rate", OFFSET(sample_rate_str), AV_OPT_TYPE_STRING, {.str = "44100"}, CHAR_MIN, CHAR_MAX, FLAGS },
- { "duration", "set audio duration", OFFSET(duration), AV_OPT_TYPE_DURATION, {.i64 = -1}, -1, INT64_MAX, FLAGS },
- { "d", "set audio duration", OFFSET(duration), AV_OPT_TYPE_DURATION, {.i64 = -1}, -1, INT64_MAX, FLAGS },
- { "channel_layout", "set channel layout", OFFSET(chlayout_str), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS },
- { "c", "set channel layout", OFFSET(chlayout_str), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS },
- { NULL }
-};
-
-AVFILTER_DEFINE_CLASS(aevalsrc);
-
-static av_cold int init(AVFilterContext *ctx)
-{
- EvalContext *eval = ctx->priv;
- char *args1 = av_strdup(eval->exprs);
- char *expr, *buf;
- int ret;
-
- if (!args1) {
- av_log(ctx, AV_LOG_ERROR, "Channels expressions list is empty\n");
- ret = eval->exprs ? AVERROR(ENOMEM) : AVERROR(EINVAL);
- goto end;
- }
-
- /* parse expressions */
- buf = args1;
- while (expr = av_strtok(buf, "|", &buf)) {
- if (!av_dynarray2_add((void **)&eval->expr, &eval->nb_channels, sizeof(*eval->expr), NULL)) {
- ret = AVERROR(ENOMEM);
- goto end;
- }
- ret = av_expr_parse(&eval->expr[eval->nb_channels - 1], expr, var_names,
- NULL, NULL, NULL, NULL, 0, ctx);
- if (ret < 0)
- goto end;
- }
-
- if (eval->chlayout_str) {
- int n;
- ret = ff_parse_channel_layout(&eval->chlayout, eval->chlayout_str, ctx);
- if (ret < 0)
- goto end;
-
- n = av_get_channel_layout_nb_channels(eval->chlayout);
- if (n != eval->nb_channels) {
- av_log(ctx, AV_LOG_ERROR,
- "Mismatch between the specified number of channels '%d' "
- "and the number of channels '%d' in the specified channel layout '%s'\n",
- eval->nb_channels, n, eval->chlayout_str);
- ret = AVERROR(EINVAL);
- goto end;
- }
- } else {
- /* guess channel layout from nb expressions/channels */
- eval->chlayout = av_get_default_channel_layout(eval->nb_channels);
- if (!eval->chlayout && eval->nb_channels <= 0) {
- av_log(ctx, AV_LOG_ERROR, "Invalid number of channels '%d' provided\n",
- eval->nb_channels);
- ret = AVERROR(EINVAL);
- goto end;
- }
- }
-
- if ((ret = ff_parse_sample_rate(&eval->sample_rate, eval->sample_rate_str, ctx)))
- goto end;
- eval->n = 0;
-
-end:
- av_free(args1);
- return ret;
-}
-
-static av_cold void uninit(AVFilterContext *ctx)
-{
- EvalContext *eval = ctx->priv;
- int i;
-
- for (i = 0; i < eval->nb_channels; i++) {
- av_expr_free(eval->expr[i]);
- eval->expr[i] = NULL;
- }
- av_freep(&eval->expr);
-}
-
-static int config_props(AVFilterLink *outlink)
-{
- EvalContext *eval = outlink->src->priv;
- char buf[128];
-
- outlink->time_base = (AVRational){1, eval->sample_rate};
- outlink->sample_rate = eval->sample_rate;
-
- eval->var_values[VAR_S] = eval->sample_rate;
-
- av_get_channel_layout_string(buf, sizeof(buf), 0, eval->chlayout);
-
- av_log(outlink->src, AV_LOG_VERBOSE,
- "sample_rate:%d chlayout:%s duration:%"PRId64"\n",
- eval->sample_rate, buf, eval->duration);
-
- return 0;
-}
-
-static int query_formats(AVFilterContext *ctx)
-{
- EvalContext *eval = ctx->priv;
- static const enum AVSampleFormat sample_fmts[] = { AV_SAMPLE_FMT_DBLP, AV_SAMPLE_FMT_NONE };
- int64_t chlayouts[] = { eval->chlayout ? eval->chlayout : FF_COUNT2LAYOUT(eval->nb_channels) , -1 };
- int sample_rates[] = { eval->sample_rate, -1 };
-
- ff_set_common_formats (ctx, ff_make_format_list(sample_fmts));
- ff_set_common_channel_layouts(ctx, avfilter_make_format64_list(chlayouts));
- ff_set_common_samplerates(ctx, ff_make_format_list(sample_rates));
-
- return 0;
-}
-
-static int request_frame(AVFilterLink *outlink)
-{
- EvalContext *eval = outlink->src->priv;
- AVFrame *samplesref;
- int i, j;
- int64_t t = av_rescale(eval->n, AV_TIME_BASE, eval->sample_rate);
-
- if (eval->duration >= 0 && t >= eval->duration)
- return AVERROR_EOF;
-
- samplesref = ff_get_audio_buffer(outlink, eval->nb_samples);
- if (!samplesref)
- return AVERROR(ENOMEM);
-
- /* evaluate expression for each single sample and for each channel */
- for (i = 0; i < eval->nb_samples; i++, eval->n++) {
- eval->var_values[VAR_N] = eval->n;
- eval->var_values[VAR_T] = eval->var_values[VAR_N] * (double)1/eval->sample_rate;
-
- for (j = 0; j < eval->nb_channels; j++) {
- *((double *) samplesref->extended_data[j] + i) =
- av_expr_eval(eval->expr[j], eval->var_values, NULL);
- }
- }
-
- samplesref->pts = eval->pts;
- samplesref->sample_rate = eval->sample_rate;
- eval->pts += eval->nb_samples;
-
- return ff_filter_frame(outlink, samplesref);
-}
-
-static const AVFilterPad aevalsrc_outputs[] = {
- {
- .name = "default",
- .type = AVMEDIA_TYPE_AUDIO,
- .config_props = config_props,
- .request_frame = request_frame,
- },
- { NULL }
-};
-
-AVFilter avfilter_asrc_aevalsrc = {
- .name = "aevalsrc",
- .description = NULL_IF_CONFIG_SMALL("Generate an audio signal generated by an expression."),
- .query_formats = query_formats,
- .init = init,
- .uninit = uninit,
- .priv_size = sizeof(EvalContext),
- .inputs = NULL,
- .outputs = aevalsrc_outputs,
- .priv_class = &aevalsrc_class,
-};
diff --git a/libavfilter/asrc_anullsrc.c b/libavfilter/asrc_anullsrc.c
index 4f76759..28d4500 100644
--- a/libavfilter/asrc_anullsrc.c
+++ b/libavfilter/asrc_anullsrc.c
@@ -68,7 +68,7 @@
null->sample_rate_str, ctx)) < 0)
return ret;
- if ((ret = ff_parse_channel_layout(&null->channel_layout,
+ if ((ret = ff_parse_channel_layout(&null->channel_layout, NULL,
null->channel_layout_str, ctx)) < 0)
return ret;
@@ -134,7 +134,7 @@
{ NULL }
};
-AVFilter avfilter_asrc_anullsrc = {
+AVFilter ff_asrc_anullsrc = {
.name = "anullsrc",
.description = NULL_IF_CONFIG_SMALL("Null audio source, return empty audio frames."),
.init = init,
diff --git a/libavfilter/asrc_flite.c b/libavfilter/asrc_flite.c
index b7131cd..098a1dd 100644
--- a/libavfilter/asrc_flite.c
+++ b/libavfilter/asrc_flite.c
@@ -270,7 +270,7 @@
{ NULL }
};
-AVFilter avfilter_asrc_flite = {
+AVFilter ff_asrc_flite = {
.name = "flite",
.description = NULL_IF_CONFIG_SMALL("Synthesize voice from text using libflite."),
.query_formats = query_formats,
diff --git a/libavfilter/asrc_sine.c b/libavfilter/asrc_sine.c
index 5bb94a3..68e1398 100644
--- a/libavfilter/asrc_sine.c
+++ b/libavfilter/asrc_sine.c
@@ -210,7 +210,7 @@
{ NULL }
};
-AVFilter avfilter_asrc_sine = {
+AVFilter ff_asrc_sine = {
.name = "sine",
.description = NULL_IF_CONFIG_SMALL("Generate sine wave audio signal."),
.query_formats = query_formats,
diff --git a/libavfilter/avcodec.h b/libavfilter/avcodec.h
index ae55df7..8bbdad2 100644
--- a/libavfilter/avcodec.h
+++ b/libavfilter/avcodec.h
@@ -72,7 +72,7 @@
*
* @param frame an already allocated AVFrame
* @param samplesref an audio buffer reference
- * @return 0 in case of success, a negative AVERROR code in case of
+ * @return >= 0 in case of success, a negative AVERROR code in case of
* failure
* @deprecated Use avfilter_copy_buf_props() instead.
*/
@@ -85,7 +85,7 @@
*
* @param frame an already allocated AVFrame
* @param picref a video buffer reference
- * @return 0 in case of success, a negative AVERROR code in case of
+ * @return >= 0 in case of success, a negative AVERROR code in case of
* failure
* @deprecated Use avfilter_copy_buf_props() instead.
*/
@@ -98,7 +98,7 @@
*
* @param frame an already allocated AVFrame
* @param ref a video or audio buffer reference
- * @return 0 in case of success, a negative AVERROR code in case of
+ * @return >= 0 in case of success, a negative AVERROR code in case of
* failure
* @deprecated Use avfilter_copy_buf_props() instead.
*/
diff --git a/libavfilter/avf_avectorscope.c b/libavfilter/avf_avectorscope.c
index 73c5934..3ca596c 100644
--- a/libavfilter/avf_avectorscope.c
+++ b/libavfilter/avf_avectorscope.c
@@ -261,7 +261,7 @@
{ NULL }
};
-AVFilter avfilter_avf_avectorscope = {
+AVFilter ff_avf_avectorscope = {
.name = "avectorscope",
.description = NULL_IF_CONFIG_SMALL("Convert input audio to vectorscope video output."),
.uninit = uninit,
diff --git a/libavfilter/avf_concat.c b/libavfilter/avf_concat.c
index 4b02ac8..c211dc4 100644
--- a/libavfilter/avf_concat.c
+++ b/libavfilter/avf_concat.c
@@ -412,7 +412,7 @@
av_free(cat->in);
}
-AVFilter avfilter_avf_concat = {
+AVFilter ff_avf_concat = {
.name = "concat",
.description = NULL_IF_CONFIG_SMALL("Concatenate audio and video streams."),
.init = init,
diff --git a/libavfilter/avf_showspectrum.c b/libavfilter/avf_showspectrum.c
index 27dd1f2..fc32834 100644
--- a/libavfilter/avf_showspectrum.c
+++ b/libavfilter/avf_showspectrum.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012 Clément Bœsch
+ * Copyright (c) 2012-2013 Clément Bœsch
* Copyright (c) 2013 Rudolf Polzer <divverent@xonotic.org>
*
* This file is part of FFmpeg.
@@ -37,6 +37,7 @@
enum DisplayMode { COMBINED, SEPARATE, NB_MODES };
enum DisplayScale { LINEAR, SQRT, CBRT, LOG, NB_SCALES };
enum ColorMode { CHANNEL, INTENSITY, NB_CLMODES };
+enum WindowFunc { WFUNC_NONE, WFUNC_HANN, WFUNC_HAMMING, WFUNC_BLACKMAN, NB_WFUNC };
typedef struct {
const AVClass *class;
@@ -57,6 +58,7 @@
int filled; ///< number of samples (per channel) filled in current rdft_buffer
int consumed; ///< number of samples (per channel) consumed from the input frame
float *window_func_lut; ///< Window function LUT
+ enum WindowFunc win_func;
float *combine_buffer; ///< color combining buffer (3 * h items)
} ShowSpectrumContext;
@@ -68,17 +70,21 @@
{ "s", "set video size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, {.str = "640x512"}, 0, 0, FLAGS },
{ "slide", "set sliding mode", OFFSET(sliding), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, FLAGS },
{ "mode", "set channel display mode", OFFSET(mode), AV_OPT_TYPE_INT, {.i64=COMBINED}, COMBINED, NB_MODES-1, FLAGS, "mode" },
- { "combined", "combined mode", 0, AV_OPT_TYPE_CONST, {.i64=COMBINED}, 0, 0, FLAGS, "mode" },
- { "separate", "separate mode", 0, AV_OPT_TYPE_CONST, {.i64=SEPARATE}, 0, 0, FLAGS, "mode" },
+ { "combined", "combined mode", 0, AV_OPT_TYPE_CONST, {.i64=COMBINED}, 0, 0, FLAGS, "mode" },
+ { "separate", "separate mode", 0, AV_OPT_TYPE_CONST, {.i64=SEPARATE}, 0, 0, FLAGS, "mode" },
{ "color", "set channel coloring", OFFSET(color_mode), AV_OPT_TYPE_INT, {.i64=CHANNEL}, CHANNEL, NB_CLMODES-1, FLAGS, "color" },
- { "channel", "separate color for each channel", 0, AV_OPT_TYPE_CONST, {.i64=CHANNEL}, 0, 0, FLAGS, "color" },
- { "intensity", "intensity based coloring", 0, AV_OPT_TYPE_CONST, {.i64=INTENSITY}, 0, 0, FLAGS, "color" },
+ { "channel", "separate color for each channel", 0, AV_OPT_TYPE_CONST, {.i64=CHANNEL}, 0, 0, FLAGS, "color" },
+ { "intensity", "intensity based coloring", 0, AV_OPT_TYPE_CONST, {.i64=INTENSITY}, 0, 0, FLAGS, "color" },
{ "scale", "set display scale", OFFSET(scale), AV_OPT_TYPE_INT, {.i64=SQRT}, LINEAR, NB_SCALES-1, FLAGS, "scale" },
- { "sqrt", "square root", 0, AV_OPT_TYPE_CONST, {.i64=SQRT}, 0, 0, FLAGS, "scale" },
- { "cbrt", "cubic root", 0, AV_OPT_TYPE_CONST, {.i64=CBRT}, 0, 0, FLAGS, "scale" },
- { "log", "logarithmic", 0, AV_OPT_TYPE_CONST, {.i64=LOG}, 0, 0, FLAGS, "scale" },
- { "lin", "linear", 0, AV_OPT_TYPE_CONST, {.i64=LINEAR}, 0, 0, FLAGS, "scale" },
+ { "sqrt", "square root", 0, AV_OPT_TYPE_CONST, {.i64=SQRT}, 0, 0, FLAGS, "scale" },
+ { "cbrt", "cubic root", 0, AV_OPT_TYPE_CONST, {.i64=CBRT}, 0, 0, FLAGS, "scale" },
+ { "log", "logarithmic", 0, AV_OPT_TYPE_CONST, {.i64=LOG}, 0, 0, FLAGS, "scale" },
+ { "lin", "linear", 0, AV_OPT_TYPE_CONST, {.i64=LINEAR}, 0, 0, FLAGS, "scale" },
{ "saturation", "color saturation multiplier", OFFSET(saturation), AV_OPT_TYPE_FLOAT, {.dbl = 1}, -10, 10, FLAGS },
+ { "win_func", "set window function", OFFSET(win_func), AV_OPT_TYPE_INT, {.i64 = WFUNC_HANN}, 0, NB_WFUNC-1, FLAGS, "win_func" },
+ { "hann", "Hann window", 0, AV_OPT_TYPE_CONST, {.i64 = WFUNC_HANN}, 0, 0, FLAGS, "win_func" },
+ { "hamming", "Hamming window", 0, AV_OPT_TYPE_CONST, {.i64 = WFUNC_HAMMING}, 0, 0, FLAGS, "win_func" },
+ { "blackman", "Blackman window", 0, AV_OPT_TYPE_CONST, {.i64 = WFUNC_BLACKMAN}, 0, 0, FLAGS, "win_func" },
{ NULL }
};
@@ -195,14 +201,33 @@
}
s->filled = 0;
- /* pre-calc windowing function (hann here) */
+ /* pre-calc windowing function */
s->window_func_lut =
av_realloc_f(s->window_func_lut, win_size,
sizeof(*s->window_func_lut));
if (!s->window_func_lut)
return AVERROR(ENOMEM);
- for (i = 0; i < win_size; i++)
- s->window_func_lut[i] = .5f * (1 - cos(2*M_PI*i / (win_size-1)));
+ switch (s->win_func) {
+ case WFUNC_NONE:
+ for (i = 0; i < win_size; i++)
+ s->window_func_lut[i] = 1.;
+ break;
+ case WFUNC_HANN:
+ for (i = 0; i < win_size; i++)
+ s->window_func_lut[i] = .5f * (1 - cos(2*M_PI*i / (win_size-1)));
+ break;
+ case WFUNC_HAMMING:
+ for (i = 0; i < win_size; i++)
+ s->window_func_lut[i] = .54f - .46f * cos(2*M_PI*i / (win_size-1));
+ break;
+ case WFUNC_BLACKMAN: {
+ for (i = 0; i < win_size; i++)
+ s->window_func_lut[i] = .42f - .5f*cos(2*M_PI*i / (win_size-1)) + .08f*cos(4*M_PI*i / (win_size-1));
+ break;
+ }
+ default:
+ av_assert0(0);
+ }
/* prepare the initial picref buffer (black frame) */
av_frame_free(&s->outpicref);
@@ -490,7 +515,7 @@
{ NULL }
};
-AVFilter avfilter_avf_showspectrum = {
+AVFilter ff_avf_showspectrum = {
.name = "showspectrum",
.description = NULL_IF_CONFIG_SMALL("Convert input audio to a spectrum video output."),
.uninit = uninit,
diff --git a/libavfilter/avf_showwaves.c b/libavfilter/avf_showwaves.c
index 5f40789..0b45bd0 100644
--- a/libavfilter/avf_showwaves.c
+++ b/libavfilter/avf_showwaves.c
@@ -244,7 +244,7 @@
{ NULL }
};
-AVFilter avfilter_avf_showwaves = {
+AVFilter ff_avf_showwaves = {
.name = "showwaves",
.description = NULL_IF_CONFIG_SMALL("Convert input audio to a video output."),
.uninit = uninit,
diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c
index 7ce82f8..2567ce9 100644
--- a/libavfilter/avfilter.c
+++ b/libavfilter/avfilter.c
@@ -119,8 +119,8 @@
(*count)++;
for (i = idx + 1; i < *count; i++)
- if (*links[i])
- (*(unsigned *)((uint8_t *) *links[i] + padidx_off))++;
+ if ((*links)[i])
+ (*(unsigned *)((uint8_t *) (*links)[i] + padidx_off))++;
return 0;
}
@@ -457,6 +457,9 @@
static AVFilter *first_filter;
+#if !FF_API_NOCONST_GET_NAME
+const
+#endif
AVFilter *avfilter_get_by_name(const char *name)
{
const AVFilter *f = NULL;
@@ -487,7 +490,7 @@
filter->next = NULL;
- while(avpriv_atomic_ptr_cas((void * volatile *)f, NULL, filter))
+ while(*f || avpriv_atomic_ptr_cas((void * volatile *)f, NULL, filter))
f = &(*f)->next;
return 0;
diff --git a/libavfilter/avfilter.h b/libavfilter/avfilter.h
index a1687f1..3518ad8 100644
--- a/libavfilter/avfilter.h
+++ b/libavfilter/avfilter.h
@@ -991,6 +991,9 @@
* @return the filter definition, if any matching one is registered.
* NULL if none found.
*/
+#if !FF_API_NOCONST_GET_NAME
+const
+#endif
AVFilter *avfilter_get_by_name(const char *name);
/**
@@ -1316,7 +1319,7 @@
*
* @param graphctx the filter graph
* @param log_ctx context used for logging
- * @return 0 in case of success, a negative AVERROR code otherwise
+ * @return >= 0 in case of success, a negative AVERROR code otherwise
*/
int avfilter_graph_config(AVFilterGraph *graphctx, void *log_ctx);
diff --git a/libavfilter/avfiltergraph.c b/libavfilter/avfiltergraph.c
index 476391c..1fb83c4 100644
--- a/libavfilter/avfiltergraph.c
+++ b/libavfilter/avfiltergraph.c
@@ -224,7 +224,7 @@
* A graph is considered valid if all its input and output pads are
* connected.
*
- * @return 0 in case of success, a negative value otherwise
+ * @return >= 0 in case of success, a negative value otherwise
*/
static int graph_check_validity(AVFilterGraph *graph, AVClass *log_ctx)
{
@@ -262,7 +262,7 @@
/**
* Configure all the links of graphctx.
*
- * @return 0 in case of success, a negative value otherwise
+ * @return >= 0 in case of success, a negative value otherwise
*/
static int graph_config_links(AVFilterGraph *graph, AVClass *log_ctx)
{
@@ -392,6 +392,19 @@
return 1;
a = clone_filter_formats(a_arg);
b = clone_filter_formats(b_arg);
+
+ if (!a || !b) {
+ if (a)
+ av_freep(&a->formats);
+ if (b)
+ av_freep(&b->formats);
+
+ av_freep(&a);
+ av_freep(&b);
+
+ return 0;
+ }
+
if (is_sample_rate) {
ret = ff_merge_samplerates(a, b);
} else {
@@ -641,6 +654,10 @@
av_log(link->src, AV_LOG_ERROR, "Cannot select channel layout for"
" the link between filters %s and %s.\n", link->src->name,
link->dst->name);
+ if (!link->in_channel_layouts->all_counts)
+ av_log(link->src, AV_LOG_ERROR, "Unknown channel layouts not "
+ "supported, try specifying a channel layout using "
+ "'aformat=channel_layouts=something'.\n");
return AVERROR(EINVAL);
}
link->in_channel_layouts->nb_channel_layouts = 1;
@@ -724,7 +741,8 @@
if (inlink->type != outlink->type || fmts->nb_channel_layouts == 1)
continue;
- if (fmts->all_layouts) {
+ if (fmts->all_layouts &&
+ (!FF_LAYOUT2COUNT(fmt) || fmts->all_counts)) {
/* Turn the infinite list into a singleton */
fmts->all_layouts = fmts->all_counts = 0;
ff_add_channel_layout(&outlink->in_channel_layouts, fmt);
diff --git a/libavfilter/avfilterres.rc b/libavfilter/avfilterres.rc
new file mode 100644
index 0000000..8be6247
--- /dev/null
+++ b/libavfilter/avfilterres.rc
@@ -0,0 +1,55 @@
+/*
+ * Windows resource file for libavfilter
+ *
+ * Copyright (C) 2012 James Almer
+ * Copyright (C) 2013 Tiancheng "Timothy" Gu
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <windows.h>
+#include "libavfilter/version.h"
+#include "libavutil/ffversion.h"
+#include "config.h"
+
+1 VERSIONINFO
+FILEVERSION LIBAVFILTER_VERSION_MAJOR, LIBAVFILTER_VERSION_MINOR, LIBAVFILTER_VERSION_MICRO, 0
+PRODUCTVERSION LIBAVFILTER_VERSION_MAJOR, LIBAVFILTER_VERSION_MINOR, LIBAVFILTER_VERSION_MICRO, 0
+FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+FILEOS VOS_NT_WINDOWS32
+FILETYPE VFT_DLL
+{
+ BLOCK "StringFileInfo"
+ {
+ BLOCK "040904B0"
+ {
+ VALUE "CompanyName", "FFmpeg Project"
+ VALUE "FileDescription", "FFmpeg audio/video filtering library"
+ VALUE "FileVersion", AV_STRINGIFY(LIBAVFILTER_VERSION)
+ VALUE "InternalName", "libavfilter"
+ VALUE "LegalCopyright", "Copyright (C) 2000-" AV_STRINGIFY(CONFIG_THIS_YEAR) " FFmpeg Project"
+ VALUE "OriginalFilename", "avfilter" BUILDSUF "-" AV_STRINGIFY(LIBAVFILTER_VERSION_MAJOR) SLIBSUF
+ VALUE "ProductName", "FFmpeg"
+ VALUE "ProductVersion", FFMPEG_VERSION
+ }
+ }
+
+ BLOCK "VarFileInfo"
+ {
+ VALUE "Translation", 0x0409, 0x04B0
+ }
+}
diff --git a/libavfilter/buffer.c b/libavfilter/buffer.c
index 1bbfab8..a626184 100644
--- a/libavfilter/buffer.c
+++ b/libavfilter/buffer.c
@@ -24,6 +24,7 @@
#include "libavutil/avassert.h"
#include "libavutil/common.h"
#include "libavutil/imgutils.h"
+#include "libavutil/internal.h"
#include "libavcodec/avcodec.h"
#include "avfilter.h"
@@ -113,7 +114,9 @@
void avfilter_unref_bufferp(AVFilterBufferRef **ref)
{
+FF_DISABLE_DEPRECATION_WARNINGS
avfilter_unref_buffer(*ref);
+FF_ENABLE_DEPRECATION_WARNINGS
*ref = NULL;
}
diff --git a/libavfilter/buffersink.c b/libavfilter/buffersink.c
index df1cb65..a6b24ad 100644
--- a/libavfilter/buffersink.c
+++ b/libavfilter/buffersink.c
@@ -529,7 +529,7 @@
{ NULL },
};
-AVFilter avfilter_vsink_ffbuffersink = {
+AVFilter ff_vsink_ffbuffersink = {
.name = "ffbuffersink",
.description = NULL_IF_CONFIG_SMALL("Buffer video frames, and make them available to the end of the filter graph."),
.priv_size = sizeof(BufferSinkContext),
@@ -551,7 +551,7 @@
{ NULL },
};
-AVFilter avfilter_asink_ffabuffersink = {
+AVFilter ff_asink_ffabuffersink = {
.name = "ffabuffersink",
.description = NULL_IF_CONFIG_SMALL("Buffer audio frames, and make them available to the end of the filter graph."),
.init_opaque = asink_init,
@@ -573,7 +573,7 @@
{ NULL }
};
-AVFilter avfilter_vsink_buffer = {
+AVFilter ff_vsink_buffer = {
.name = "buffersink",
.description = NULL_IF_CONFIG_SMALL("Buffer video frames, and make them available to the end of the filter graph."),
.priv_size = sizeof(BufferSinkContext),
@@ -595,7 +595,7 @@
{ NULL }
};
-AVFilter avfilter_asink_abuffer = {
+AVFilter ff_asink_abuffer = {
.name = "abuffersink",
.description = NULL_IF_CONFIG_SMALL("Buffer audio frames, and make them available to the end of the filter graph."),
.priv_class = &abuffersink_class,
diff --git a/libavfilter/buffersrc.c b/libavfilter/buffersrc.c
index b64f7fa..6b6210d 100644
--- a/libavfilter/buffersrc.c
+++ b/libavfilter/buffersrc.c
@@ -511,7 +511,7 @@
{ NULL }
};
-AVFilter avfilter_vsrc_buffer = {
+AVFilter ff_vsrc_buffer = {
.name = "buffer",
.description = NULL_IF_CONFIG_SMALL("Buffer video frames, and make them accessible to the filterchain."),
.priv_size = sizeof(BufferSourceContext),
@@ -536,7 +536,7 @@
{ NULL }
};
-AVFilter avfilter_asrc_abuffer = {
+AVFilter ff_asrc_abuffer = {
.name = "abuffer",
.description = NULL_IF_CONFIG_SMALL("Buffer audio frames, and make them accessible to the filterchain."),
.priv_size = sizeof(BufferSourceContext),
diff --git a/libavfilter/deshake.h b/libavfilter/deshake.h
index c24090e..5792973 100644
--- a/libavfilter/deshake.h
+++ b/libavfilter/deshake.h
@@ -55,6 +55,9 @@
#if CONFIG_OPENCL
typedef struct {
+ cl_command_queue command_queue;
+ cl_program program;
+ cl_kernel kernel;
size_t matrix_size;
float matrix_y[9];
float matrix_uv[9];
@@ -67,7 +70,6 @@
size_t cl_inbuf_size;
cl_mem cl_outbuf;
size_t cl_outbuf_size;
- AVOpenCLKernelEnv kernel_env;
} DeshakeOpenclContext;
#endif
diff --git a/libavfilter/deshake_opencl.c b/libavfilter/deshake_opencl.c
index eea873e..e4e4df1 100644
--- a/libavfilter/deshake_opencl.c
+++ b/libavfilter/deshake_opencl.c
@@ -45,7 +45,7 @@
FFOpenclParam opencl_param = {0};
opencl_param.ctx = ctx;
- opencl_param.kernel = deshake->opencl_ctx.kernel_env.kernel;
+ opencl_param.kernel = deshake->opencl_ctx.kernel;
ret = av_opencl_buffer_write(deshake->opencl_ctx.cl_matrix_y, (uint8_t *)matrix_y, deshake->opencl_ctx.matrix_size * sizeof(cl_float));
if (ret < 0)
return ret;
@@ -75,14 +75,14 @@
NULL);
if (ret < 0)
return ret;
- status = clEnqueueNDRangeKernel(deshake->opencl_ctx.kernel_env.command_queue,
- deshake->opencl_ctx.kernel_env.kernel, 1, NULL,
+ status = clEnqueueNDRangeKernel(deshake->opencl_ctx.command_queue,
+ deshake->opencl_ctx.kernel, 1, NULL,
&global_work_size, NULL, 0, NULL, NULL);
if (status != CL_SUCCESS) {
av_log(ctx, AV_LOG_ERROR, "OpenCL run kernel error occurred: %s\n", av_opencl_errstr(status));
return AVERROR_EXTERNAL;
}
- clFinish(deshake->opencl_ctx.kernel_env.command_queue);
+ clFinish(deshake->opencl_ctx.command_queue);
ret = av_opencl_buffer_read_image(out->data, deshake->opencl_ctx.out_plane_size,
deshake->opencl_ctx.plane_num, deshake->opencl_ctx.cl_outbuf,
deshake->opencl_ctx.cl_outbuf_size);
@@ -108,11 +108,21 @@
deshake->opencl_ctx.matrix_size*sizeof(cl_float), CL_MEM_READ_ONLY, NULL);
if (ret < 0)
return ret;
- if (!deshake->opencl_ctx.kernel_env.kernel) {
- ret = av_opencl_create_kernel(&deshake->opencl_ctx.kernel_env, "avfilter_transform");
- if (ret < 0) {
- av_log(ctx, AV_LOG_ERROR, "OpenCL failed to create kernel for name 'avfilter_transform'\n");
- return ret;
+ deshake->opencl_ctx.command_queue = av_opencl_get_command_queue();
+ if (!deshake->opencl_ctx.command_queue) {
+ av_log(ctx, AV_LOG_ERROR, "Unable to get OpenCL command queue in filter 'deshake'\n");
+ return AVERROR(EINVAL);
+ }
+ deshake->opencl_ctx.program = av_opencl_compile("avfilter_transform", NULL);
+ if (!deshake->opencl_ctx.program) {
+ av_log(ctx, AV_LOG_ERROR, "OpenCL failed to compile program 'avfilter_transform'\n");
+ return AVERROR(EINVAL);
+ }
+ if (!deshake->opencl_ctx.kernel) {
+ deshake->opencl_ctx.kernel = clCreateKernel(deshake->opencl_ctx.program, "avfilter_transform", &ret);
+ if (ret != CL_SUCCESS) {
+ av_log(ctx, AV_LOG_ERROR, "OpenCL failed to create kernel 'avfilter_transform'\n");
+ return AVERROR(EINVAL);
}
}
return ret;
@@ -125,11 +135,12 @@
av_opencl_buffer_release(&deshake->opencl_ctx.cl_outbuf);
av_opencl_buffer_release(&deshake->opencl_ctx.cl_matrix_y);
av_opencl_buffer_release(&deshake->opencl_ctx.cl_matrix_uv);
- av_opencl_release_kernel(&deshake->opencl_ctx.kernel_env);
+ clReleaseKernel(deshake->opencl_ctx.kernel);
+ clReleaseProgram(deshake->opencl_ctx.program);
+ deshake->opencl_ctx.command_queue = NULL;
av_opencl_uninit();
}
-
int ff_opencl_deshake_process_inout_buf(AVFilterContext *ctx, AVFrame *in, AVFrame *out)
{
int ret = 0;
diff --git a/libavfilter/f_ebur128.c b/libavfilter/f_ebur128.c
index 7071f05..a2c6160 100644
--- a/libavfilter/f_ebur128.c
+++ b/libavfilter/f_ebur128.c
@@ -785,7 +785,7 @@
{ NULL }
};
-AVFilter avfilter_af_ebur128 = {
+AVFilter ff_af_ebur128 = {
.name = "ebur128",
.description = NULL_IF_CONFIG_SMALL("EBU R128 scanner."),
.priv_size = sizeof(EBUR128Context),
diff --git a/libavfilter/f_interleave.c b/libavfilter/f_interleave.c
index 72050db..95401cf 100644
--- a/libavfilter/f_interleave.c
+++ b/libavfilter/f_interleave.c
@@ -217,7 +217,7 @@
{ NULL }
};
-AVFilter avfilter_vf_interleave = {
+AVFilter ff_vf_interleave = {
.name = "interleave",
.description = NULL_IF_CONFIG_SMALL("Temporally interleave video inputs."),
.priv_size = sizeof(InterleaveContext),
@@ -245,7 +245,7 @@
{ NULL }
};
-AVFilter avfilter_af_ainterleave = {
+AVFilter ff_af_ainterleave = {
.name = "ainterleave",
.description = NULL_IF_CONFIG_SMALL("Temporally interleave audio inputs."),
.priv_size = sizeof(InterleaveContext),
diff --git a/libavfilter/f_perms.c b/libavfilter/f_perms.c
index 8dc2ed8..2c53e8c 100644
--- a/libavfilter/f_perms.c
+++ b/libavfilter/f_perms.c
@@ -133,7 +133,7 @@
{ NULL }
};
-AVFilter avfilter_af_aperms = {
+AVFilter ff_af_aperms = {
.name = "aperms",
.description = NULL_IF_CONFIG_SMALL("Set permissions for the output audio frame."),
.init = init,
@@ -166,7 +166,7 @@
{ NULL }
};
-AVFilter avfilter_vf_perms = {
+AVFilter ff_vf_perms = {
.name = "perms",
.description = NULL_IF_CONFIG_SMALL("Set permissions for the output video frame."),
.init = init,
diff --git a/libavfilter/f_select.c b/libavfilter/f_select.c
index 60cc311..ec84da8 100644
--- a/libavfilter/f_select.c
+++ b/libavfilter/f_select.c
@@ -476,7 +476,7 @@
{ NULL }
};
-AVFilter avfilter_af_aselect = {
+AVFilter ff_af_aselect = {
.name = "aselect",
.description = NULL_IF_CONFIG_SMALL("Select audio frames to pass in output."),
.init = aselect_init,
@@ -519,7 +519,7 @@
{ NULL }
};
-AVFilter avfilter_vf_select = {
+AVFilter ff_vf_select = {
.name = "select",
.description = NULL_IF_CONFIG_SMALL("Select video frames to pass in output."),
.init = select_init,
diff --git a/libavfilter/f_sendcmd.c b/libavfilter/f_sendcmd.c
index 60da49c..c30f49f 100644
--- a/libavfilter/f_sendcmd.c
+++ b/libavfilter/f_sendcmd.c
@@ -527,7 +527,7 @@
{ NULL }
};
-AVFilter avfilter_vf_sendcmd = {
+AVFilter ff_vf_sendcmd = {
.name = "sendcmd",
.description = NULL_IF_CONFIG_SMALL("Send commands to filters."),
.init = init,
@@ -562,7 +562,7 @@
{ NULL }
};
-AVFilter avfilter_af_asendcmd = {
+AVFilter ff_af_asendcmd = {
.name = "asendcmd",
.description = NULL_IF_CONFIG_SMALL("Send commands to filters."),
.init = init,
diff --git a/libavfilter/f_settb.c b/libavfilter/f_settb.c
index 5535bbf..d511c14 100644
--- a/libavfilter/f_settb.c
+++ b/libavfilter/f_settb.c
@@ -143,7 +143,7 @@
{ NULL }
};
-AVFilter avfilter_vf_settb = {
+AVFilter ff_vf_settb = {
.name = "settb",
.description = NULL_IF_CONFIG_SMALL("Set timebase for the video output link."),
.priv_size = sizeof(SetTBContext),
@@ -176,7 +176,7 @@
{ NULL }
};
-AVFilter avfilter_af_asettb = {
+AVFilter ff_af_asettb = {
.name = "asettb",
.description = NULL_IF_CONFIG_SMALL("Set timebase for the audio output link."),
.priv_size = sizeof(SetTBContext),
diff --git a/libavfilter/f_zmq.c b/libavfilter/f_zmq.c
index 8714a3c..d6c3c65 100644
--- a/libavfilter/f_zmq.c
+++ b/libavfilter/f_zmq.c
@@ -226,7 +226,7 @@
{ NULL }
};
-AVFilter avfilter_vf_zmq = {
+AVFilter ff_vf_zmq = {
.name = "zmq",
.description = NULL_IF_CONFIG_SMALL("Receive commands through ZMQ and broker them to filters."),
.init = init,
@@ -261,7 +261,7 @@
{ NULL }
};
-AVFilter avfilter_af_azmq = {
+AVFilter ff_af_azmq = {
.name = "azmq",
.description = NULL_IF_CONFIG_SMALL("Receive commands through ZMQ and broker them to filters."),
.init = init,
diff --git a/libavfilter/fifo.c b/libavfilter/fifo.c
index 3e91298..5310af2 100644
--- a/libavfilter/fifo.c
+++ b/libavfilter/fifo.c
@@ -268,7 +268,7 @@
{ NULL }
};
-AVFilter avfilter_vf_fifo = {
+AVFilter ff_vf_fifo = {
.name = "fifo",
.description = NULL_IF_CONFIG_SMALL("Buffer input images and send them when they are requested."),
@@ -299,7 +299,7 @@
{ NULL }
};
-AVFilter avfilter_af_afifo = {
+AVFilter ff_af_afifo = {
.name = "afifo",
.description = NULL_IF_CONFIG_SMALL("Buffer input frames and send them when they are requested."),
diff --git a/libavfilter/formats.c b/libavfilter/formats.c
index d51bf3c..5816032 100644
--- a/libavfilter/formats.c
+++ b/libavfilter/formats.c
@@ -615,10 +615,21 @@
return 0;
}
-int ff_parse_channel_layout(int64_t *ret, const char *arg, void *log_ctx)
+int ff_parse_channel_layout(int64_t *ret, int *nret, const char *arg,
+ void *log_ctx)
{
char *tail;
- int64_t chlayout = av_get_channel_layout(arg);
+ int64_t chlayout, count;
+
+ if (nret) {
+ count = strtol(arg, &tail, 10);
+ if (*tail == 'c' && !tail[1] && count > 0 && count < 63) {
+ *nret = count;
+ *ret = 0;
+ return 0;
+ }
+ }
+ chlayout = av_get_channel_layout(arg);
if (chlayout == 0) {
chlayout = strtol(arg, &tail, 10);
if (*tail || chlayout == 0) {
@@ -627,6 +638,8 @@
}
}
*ret = chlayout;
+ if (nret)
+ *nret = av_get_channel_layout_nb_channels(chlayout);
return 0;
}
diff --git a/libavfilter/gradfun.h b/libavfilter/gradfun.h
index 7b1140f..eb1f1eb 100644
--- a/libavfilter/gradfun.h
+++ b/libavfilter/gradfun.h
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2010 Nolan Lum <nol888@gmail.com>
- * Copyright (c) 2009 Loren Merritt <lorenm@u.washignton.edu>
+ * Copyright (c) 2009 Loren Merritt <lorenm@u.washington.edu>
*
* This file is part of FFmpeg.
*
diff --git a/libavfilter/graphparser.c b/libavfilter/graphparser.c
index b1368d9..7e25282 100644
--- a/libavfilter/graphparser.c
+++ b/libavfilter/graphparser.c
@@ -89,7 +89,7 @@
* @param filt_name the name of the filter to create
* @param args the arguments provided to the filter during its initialization
* @param log_ctx the log context to use
- * @return 0 in case of success, a negative AVERROR code otherwise
+ * @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, void *log_ctx)
@@ -132,6 +132,8 @@
if (args)
av_log(log_ctx, AV_LOG_ERROR, " with args '%s'", args);
av_log(log_ctx, AV_LOG_ERROR, "\n");
+ avfilter_free(*filt_ctx);
+ *filt_ctx = NULL;
}
av_free(tmp_args);
@@ -152,7 +154,7 @@
* @param index an index which is assigned to the created filter
* instance, and which is supposed to be unique for each filter
* instance added to the filtergraph
- * @return 0 in case of success, a negative AVERROR code otherwise
+ * @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, void *log_ctx)
diff --git a/libavfilter/internal.h b/libavfilter/internal.h
index 5ea3cad..5e19698 100644
--- a/libavfilter/internal.h
+++ b/libavfilter/internal.h
@@ -169,7 +169,7 @@
* @param ret pixel format pointer to where the value should be written
* @param arg string to parse
* @param log_ctx log context
- * @return 0 in case of success, a negative AVERROR code on error
+ * @return >= 0 in case of success, a negative AVERROR code on error
*/
int ff_parse_pixel_format(enum AVPixelFormat *ret, const char *arg, void *log_ctx);
@@ -179,7 +179,7 @@
* @param ret unsigned integer pointer to where the value should be written
* @param arg string to parse
* @param log_ctx log context
- * @return 0 in case of success, a negative AVERROR code on error
+ * @return >= 0 in case of success, a negative AVERROR code on error
*/
int ff_parse_sample_rate(int *ret, const char *arg, void *log_ctx);
@@ -189,7 +189,7 @@
* @param ret unsigned AVRational pointer to where the value should be written
* @param arg string to parse
* @param log_ctx log context
- * @return 0 in case of success, a negative AVERROR code on error
+ * @return >= 0 in case of success, a negative AVERROR code on error
*/
int ff_parse_time_base(AVRational *ret, const char *arg, void *log_ctx);
@@ -199,7 +199,7 @@
* @param ret integer pointer to where the value should be written
* @param arg string to parse
* @param log_ctx log context
- * @return 0 in case of success, a negative AVERROR code on error
+ * @return >= 0 in case of success, a negative AVERROR code on error
*/
int ff_parse_sample_format(int *ret, const char *arg, void *log_ctx);
@@ -207,11 +207,14 @@
* Parse a channel layout or a corresponding integer representation.
*
* @param ret 64bit integer pointer to where the value should be written.
+ * @param nret integer pointer to the number of channels;
+ * if not NULL, then unknown channel layouts are accepted
* @param arg string to parse
* @param log_ctx log context
- * @return 0 in case of success, a negative AVERROR code on error
+ * @return >= 0 in case of success, a negative AVERROR code on error
*/
-int ff_parse_channel_layout(int64_t *ret, const char *arg, void *log_ctx);
+int ff_parse_channel_layout(int64_t *ret, int *nret, const char *arg,
+ void *log_ctx);
void ff_update_link_current_pts(AVFilterLink *link, int64_t pts);
diff --git a/libavfilter/lavfutils.c b/libavfilter/lavfutils.c
index b7a103b..58d98cf 100644
--- a/libavfilter/lavfutils.c
+++ b/libavfilter/lavfutils.c
@@ -57,7 +57,7 @@
goto end;
}
- if (!(frame = avcodec_alloc_frame()) ) {
+ if (!(frame = av_frame_alloc()) ) {
av_log(log_ctx, AV_LOG_ERROR, "Failed to alloc frame\n");
ret = AVERROR(ENOMEM);
goto end;
diff --git a/libavfilter/lavfutils.h b/libavfilter/lavfutils.h
index a310e83..2d5308f 100644
--- a/libavfilter/lavfutils.h
+++ b/libavfilter/lavfutils.h
@@ -34,7 +34,7 @@
* @param pix_fmt pointer to the pixel format of the loaded image
* @param filename the name of the image file to load
* @param log_ctx log context
- * @return 0 in case of success, a negative error code otherwise.
+ * @return >= 0 in case of success, a negative error code otherwise.
*/
int ff_load_image(uint8_t *data[4], int linesize[4],
int *w, int *h, enum AVPixelFormat *pix_fmt,
diff --git a/libavfilter/libmpcodecs/vf_eq.c b/libavfilter/libmpcodecs/vf_eq.c
index 4e256d9..c926c518 100644
--- a/libavfilter/libmpcodecs/vf_eq.c
+++ b/libavfilter/libmpcodecs/vf_eq.c
@@ -31,7 +31,7 @@
#include "libvo/video_out.h"
-static struct vf_priv_s {
+struct vf_priv_s {
unsigned char *buf;
int brightness;
int contrast;
diff --git a/libavfilter/libmpcodecs/vf_uspp.c b/libavfilter/libmpcodecs/vf_uspp.c
index 54cc0f9..1fb2523 100644
--- a/libavfilter/libmpcodecs/vf_uspp.c
+++ b/libavfilter/libmpcodecs/vf_uspp.c
@@ -245,8 +245,8 @@
av_dict_free(&opts);
assert(avctx_enc->codec);
}
- vf->priv->frame= avcodec_alloc_frame();
- vf->priv->frame_dec= avcodec_alloc_frame();
+ vf->priv->frame= av_frame_alloc();
+ vf->priv->frame_dec= av_frame_alloc();
vf->priv->outbuf_size= (width + BLOCK)*(height + BLOCK)*10;
vf->priv->outbuf= malloc(vf->priv->outbuf_size);
diff --git a/libavfilter/pthread.c b/libavfilter/pthread.c
index 8ae2c3f..92c4d08 100644
--- a/libavfilter/pthread.c
+++ b/libavfilter/pthread.c
@@ -58,6 +58,7 @@
pthread_cond_t current_job_cond;
pthread_mutex_t current_job_lock;
int current_job;
+ unsigned int current_execute;
int done;
} ThreadContext;
@@ -66,6 +67,7 @@
ThreadContext *c = v;
int our_job = c->nb_jobs;
int nb_threads = c->nb_threads;
+ unsigned int last_execute = 0;
int self_id;
pthread_mutex_lock(&c->current_job_lock);
@@ -75,8 +77,9 @@
if (c->current_job == nb_threads + c->nb_jobs)
pthread_cond_signal(&c->last_job_cond);
- if (!c->done)
+ while (last_execute == c->current_execute && !c->done)
pthread_cond_wait(&c->current_job_cond, &c->current_job_lock);
+ last_execute = c->current_execute;
our_job = self_id;
if (c->done) {
@@ -113,7 +116,8 @@
static void slice_thread_park_workers(ThreadContext *c)
{
- pthread_cond_wait(&c->last_job_cond, &c->current_job_lock);
+ while (c->current_job != c->nb_threads + c->nb_jobs)
+ pthread_cond_wait(&c->last_job_cond, &c->current_job_lock);
pthread_mutex_unlock(&c->current_job_lock);
}
@@ -140,6 +144,8 @@
c->rets = &dummy_ret;
c->nb_rets = 1;
}
+ c->current_execute++;
+
pthread_cond_broadcast(&c->current_job_cond);
slice_thread_park_workers(c);
diff --git a/libavfilter/setpts.c b/libavfilter/setpts.c
index 5fb4f24..cb6b2b9 100644
--- a/libavfilter/setpts.c
+++ b/libavfilter/setpts.c
@@ -246,7 +246,7 @@
{ NULL }
};
-AVFilter avfilter_vf_setpts = {
+AVFilter ff_vf_setpts = {
.name = "setpts",
.description = NULL_IF_CONFIG_SMALL("Set PTS for the output video frame."),
.init = init,
@@ -283,7 +283,7 @@
{ NULL }
};
-AVFilter avfilter_af_asetpts = {
+AVFilter ff_af_asetpts = {
.name = "asetpts",
.description = NULL_IF_CONFIG_SMALL("Set PTS for the output audio frame."),
.init = init,
diff --git a/libavfilter/split.c b/libavfilter/split.c
index 21e1a60..6abd5ee 100644
--- a/libavfilter/split.c
+++ b/libavfilter/split.c
@@ -113,7 +113,7 @@
{ NULL }
};
-AVFilter avfilter_vf_split = {
+AVFilter ff_vf_split = {
.name = "split",
.description = NULL_IF_CONFIG_SMALL("Pass on the input to N video outputs."),
.priv_size = sizeof(SplitContext),
@@ -134,7 +134,7 @@
{ NULL }
};
-AVFilter avfilter_af_asplit = {
+AVFilter ff_af_asplit = {
.name = "asplit",
.description = NULL_IF_CONFIG_SMALL("Pass on the audio input to N audio outputs."),
.priv_size = sizeof(SplitContext),
diff --git a/libavfilter/src_movie.c b/libavfilter/src_movie.c
index dfb4289..d1289e2 100644
--- a/libavfilter/src_movie.c
+++ b/libavfilter/src_movie.c
@@ -28,6 +28,7 @@
*/
#include <float.h>
+#include <stdint.h>
#include "libavutil/attributes.h"
#include "libavutil/avstring.h"
@@ -565,7 +566,7 @@
AVFILTER_DEFINE_CLASS(movie);
-AVFilter avfilter_avsrc_movie = {
+AVFilter ff_avsrc_movie = {
.name = "movie",
.description = NULL_IF_CONFIG_SMALL("Read from a movie source."),
.priv_size = sizeof(MovieContext),
@@ -586,7 +587,7 @@
#define amovie_options movie_options
AVFILTER_DEFINE_CLASS(amovie);
-AVFilter avfilter_avsrc_amovie = {
+AVFilter ff_avsrc_amovie = {
.name = "amovie",
.description = NULL_IF_CONFIG_SMALL("Read audio from a movie source."),
.priv_size = sizeof(MovieContext),
diff --git a/libavfilter/trim.c b/libavfilter/trim.c
index bcadca3..04e82da 100644
--- a/libavfilter/trim.c
+++ b/libavfilter/trim.c
@@ -18,6 +18,7 @@
#include <float.h>
#include <math.h>
+#include <stdint.h>
#include "config.h"
@@ -227,7 +228,7 @@
{ NULL }
};
-AVFilter avfilter_vf_trim = {
+AVFilter ff_vf_trim = {
.name = "trim",
.description = NULL_IF_CONFIG_SMALL("Pick one continuous section from the input, drop the rest."),
.init = init,
@@ -382,7 +383,7 @@
{ NULL }
};
-AVFilter avfilter_af_atrim = {
+AVFilter ff_af_atrim = {
.name = "atrim",
.description = NULL_IF_CONFIG_SMALL("Pick one continuous section from the input, drop the rest."),
.init = init,
diff --git a/libavfilter/unsharp.h b/libavfilter/unsharp.h
index c225929..8678920 100644
--- a/libavfilter/unsharp.h
+++ b/libavfilter/unsharp.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2013 Wei Gao <weigao@multicorewareinc.com>
+ * Copyright (C) 2013 Lenny Wang
*
* This file is part of FFmpeg.
*
@@ -33,6 +34,11 @@
#if CONFIG_OPENCL
typedef struct {
+ cl_command_queue command_queue;
+ cl_program program;
+ cl_kernel kernel_default;
+ cl_kernel kernel_luma;
+ cl_kernel kernel_chroma;
cl_mem cl_luma_mask;
cl_mem cl_chroma_mask;
int in_plane_size[8];
@@ -42,7 +48,7 @@
size_t cl_inbuf_size;
cl_mem cl_outbuf;
size_t cl_outbuf_size;
- AVOpenCLKernelEnv kernel_env;
+ int use_fast_kernels;
} UnsharpOpenclContext;
#endif
diff --git a/libavfilter/unsharp_opencl.c b/libavfilter/unsharp_opencl.c
index b373b66..fff16ab 100644
--- a/libavfilter/unsharp_opencl.c
+++ b/libavfilter/unsharp_opencl.c
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2013 Wei Gao <weigao@multicorewareinc.com>
+ * Copyright (C) 2013 Lenny Wang
*
* This file is part of FFmpeg.
*
@@ -28,6 +29,7 @@
#include "libavutil/opencl_internal.h"
#define PLANE_NUM 3
+#define ROUND_TO_16(a) ((((a- 1)/16)+1)*16)
static inline void add_mask_counter(uint32_t *dst, uint32_t *counter1, uint32_t *counter2, int len)
{
@@ -135,6 +137,13 @@
step_x[1] = unsharp->chroma.steps_x;
step_y[0] = unsharp->luma.steps_y;
step_y[1] = unsharp->chroma.steps_y;
+
+ /* use default kernel if any matrix dim larger than 8 due to limited local mem size */
+ if (step_x[0]>8 || step_x[1]>8 || step_y[0]>8 || step_y[1]>8)
+ unsharp->opencl_ctx.use_fast_kernels = 0;
+ else
+ unsharp->opencl_ctx.use_fast_kernels = 1;
+
if (!mask_matrix[0] || !mask_matrix[1]) {
av_log(ctx, AV_LOG_ERROR, "Luma mask and chroma mask should not be NULL\n");
return AVERROR(EINVAL);
@@ -153,47 +162,109 @@
AVFilterLink *link = ctx->inputs[0];
UnsharpContext *unsharp = ctx->priv;
cl_int status;
+ FFOpenclParam kernel1 = {0};
+ FFOpenclParam kernel2 = {0};
+ int width = link->w;
+ int height = link->h;
int cw = FF_CEIL_RSHIFT(link->w, unsharp->hsub);
int ch = FF_CEIL_RSHIFT(link->h, unsharp->vsub);
- const size_t global_work_size = link->w * link->h + 2 * ch * cw;
- FFOpenclParam opencl_param = {0};
+ size_t globalWorkSize1d = width * height + 2 * ch * cw;
+ size_t globalWorkSize2dLuma[2];
+ size_t globalWorkSize2dChroma[2];
+ size_t localWorkSize2d[2] = {16, 16};
- opencl_param.ctx = ctx;
- opencl_param.kernel = unsharp->opencl_ctx.kernel_env.kernel;
- ret = ff_opencl_set_parameter(&opencl_param,
- FF_OPENCL_PARAM_INFO(unsharp->opencl_ctx.cl_inbuf),
- FF_OPENCL_PARAM_INFO(unsharp->opencl_ctx.cl_outbuf),
- FF_OPENCL_PARAM_INFO(unsharp->opencl_ctx.cl_luma_mask),
- FF_OPENCL_PARAM_INFO(unsharp->opencl_ctx.cl_chroma_mask),
- FF_OPENCL_PARAM_INFO(unsharp->luma.amount),
- FF_OPENCL_PARAM_INFO(unsharp->chroma.amount),
- FF_OPENCL_PARAM_INFO(unsharp->luma.steps_x),
- FF_OPENCL_PARAM_INFO(unsharp->luma.steps_y),
- FF_OPENCL_PARAM_INFO(unsharp->chroma.steps_x),
- FF_OPENCL_PARAM_INFO(unsharp->chroma.steps_y),
- FF_OPENCL_PARAM_INFO(unsharp->luma.scalebits),
- FF_OPENCL_PARAM_INFO(unsharp->chroma.scalebits),
- FF_OPENCL_PARAM_INFO(unsharp->luma.halfscale),
- FF_OPENCL_PARAM_INFO(unsharp->chroma.halfscale),
- FF_OPENCL_PARAM_INFO(in->linesize[0]),
- FF_OPENCL_PARAM_INFO(in->linesize[1]),
- FF_OPENCL_PARAM_INFO(out->linesize[0]),
- FF_OPENCL_PARAM_INFO(out->linesize[1]),
- FF_OPENCL_PARAM_INFO(link->h),
- FF_OPENCL_PARAM_INFO(link->w),
- FF_OPENCL_PARAM_INFO(ch),
- FF_OPENCL_PARAM_INFO(cw),
- NULL);
- if (ret < 0)
- return ret;
- status = clEnqueueNDRangeKernel(unsharp->opencl_ctx.kernel_env.command_queue,
- unsharp->opencl_ctx.kernel_env.kernel, 1, NULL,
- &global_work_size, NULL, 0, NULL, NULL);
- if (status != CL_SUCCESS) {
- av_log(ctx, AV_LOG_ERROR, "OpenCL run kernel error occurred: %s\n", av_opencl_errstr(status));
- return AVERROR_EXTERNAL;
+ if (unsharp->opencl_ctx.use_fast_kernels) {
+ globalWorkSize2dLuma[0] = (size_t)ROUND_TO_16(width);
+ globalWorkSize2dLuma[1] = (size_t)ROUND_TO_16(height);
+ globalWorkSize2dChroma[0] = (size_t)ROUND_TO_16(cw);
+ globalWorkSize2dChroma[1] = (size_t)(2*ROUND_TO_16(ch));
+
+ kernel1.ctx = ctx;
+ kernel1.kernel = unsharp->opencl_ctx.kernel_luma;
+ ret = ff_opencl_set_parameter(&kernel1,
+ FF_OPENCL_PARAM_INFO(unsharp->opencl_ctx.cl_inbuf),
+ FF_OPENCL_PARAM_INFO(unsharp->opencl_ctx.cl_outbuf),
+ FF_OPENCL_PARAM_INFO(unsharp->opencl_ctx.cl_luma_mask),
+ FF_OPENCL_PARAM_INFO(unsharp->luma.amount),
+ FF_OPENCL_PARAM_INFO(unsharp->luma.scalebits),
+ FF_OPENCL_PARAM_INFO(unsharp->luma.halfscale),
+ FF_OPENCL_PARAM_INFO(in->linesize[0]),
+ FF_OPENCL_PARAM_INFO(out->linesize[0]),
+ FF_OPENCL_PARAM_INFO(width),
+ FF_OPENCL_PARAM_INFO(height),
+ NULL);
+ if (ret < 0)
+ return ret;
+
+ kernel2.ctx = ctx;
+ kernel2.kernel = unsharp->opencl_ctx.kernel_chroma;
+ ret = ff_opencl_set_parameter(&kernel2,
+ FF_OPENCL_PARAM_INFO(unsharp->opencl_ctx.cl_inbuf),
+ FF_OPENCL_PARAM_INFO(unsharp->opencl_ctx.cl_outbuf),
+ FF_OPENCL_PARAM_INFO(unsharp->opencl_ctx.cl_chroma_mask),
+ FF_OPENCL_PARAM_INFO(unsharp->chroma.amount),
+ FF_OPENCL_PARAM_INFO(unsharp->chroma.scalebits),
+ FF_OPENCL_PARAM_INFO(unsharp->chroma.halfscale),
+ FF_OPENCL_PARAM_INFO(in->linesize[0]),
+ FF_OPENCL_PARAM_INFO(in->linesize[1]),
+ FF_OPENCL_PARAM_INFO(out->linesize[0]),
+ FF_OPENCL_PARAM_INFO(out->linesize[1]),
+ FF_OPENCL_PARAM_INFO(link->w),
+ FF_OPENCL_PARAM_INFO(link->h),
+ FF_OPENCL_PARAM_INFO(cw),
+ FF_OPENCL_PARAM_INFO(ch),
+ NULL);
+ if (ret < 0)
+ return ret;
+ status = clEnqueueNDRangeKernel(unsharp->opencl_ctx.command_queue,
+ unsharp->opencl_ctx.kernel_luma, 2, NULL,
+ globalWorkSize2dLuma, localWorkSize2d, 0, NULL, NULL);
+ status |=clEnqueueNDRangeKernel(unsharp->opencl_ctx.command_queue,
+ unsharp->opencl_ctx.kernel_chroma, 2, NULL,
+ globalWorkSize2dChroma, localWorkSize2d, 0, NULL, NULL);
+ if (status != CL_SUCCESS) {
+ av_log(ctx, AV_LOG_ERROR, "OpenCL run kernel error occurred: %s\n", av_opencl_errstr(status));
+ return AVERROR_EXTERNAL;
+ }
+ } else { /* use default kernel */
+ kernel1.ctx = ctx;
+ kernel1.kernel = unsharp->opencl_ctx.kernel_default;
+
+ ret = ff_opencl_set_parameter(&kernel1,
+ FF_OPENCL_PARAM_INFO(unsharp->opencl_ctx.cl_inbuf),
+ FF_OPENCL_PARAM_INFO(unsharp->opencl_ctx.cl_outbuf),
+ FF_OPENCL_PARAM_INFO(unsharp->opencl_ctx.cl_luma_mask),
+ FF_OPENCL_PARAM_INFO(unsharp->opencl_ctx.cl_chroma_mask),
+ FF_OPENCL_PARAM_INFO(unsharp->luma.amount),
+ FF_OPENCL_PARAM_INFO(unsharp->chroma.amount),
+ FF_OPENCL_PARAM_INFO(unsharp->luma.steps_x),
+ FF_OPENCL_PARAM_INFO(unsharp->luma.steps_y),
+ FF_OPENCL_PARAM_INFO(unsharp->chroma.steps_x),
+ FF_OPENCL_PARAM_INFO(unsharp->chroma.steps_y),
+ FF_OPENCL_PARAM_INFO(unsharp->luma.scalebits),
+ FF_OPENCL_PARAM_INFO(unsharp->chroma.scalebits),
+ FF_OPENCL_PARAM_INFO(unsharp->luma.halfscale),
+ FF_OPENCL_PARAM_INFO(unsharp->chroma.halfscale),
+ FF_OPENCL_PARAM_INFO(in->linesize[0]),
+ FF_OPENCL_PARAM_INFO(in->linesize[1]),
+ FF_OPENCL_PARAM_INFO(out->linesize[0]),
+ FF_OPENCL_PARAM_INFO(out->linesize[1]),
+ FF_OPENCL_PARAM_INFO(link->h),
+ FF_OPENCL_PARAM_INFO(link->w),
+ FF_OPENCL_PARAM_INFO(ch),
+ FF_OPENCL_PARAM_INFO(cw),
+ NULL);
+ if (ret < 0)
+ return ret;
+ status = clEnqueueNDRangeKernel(unsharp->opencl_ctx.command_queue,
+ unsharp->opencl_ctx.kernel_default, 1, NULL,
+ &globalWorkSize1d, NULL, 0, NULL, NULL);
+ if (status != CL_SUCCESS) {
+ av_log(ctx, AV_LOG_ERROR, "OpenCL run kernel error occurred: %s\n", av_opencl_errstr(status));
+ return AVERROR_EXTERNAL;
+ }
}
- clFinish(unsharp->opencl_ctx.kernel_env.command_queue);
+ clFinish(unsharp->opencl_ctx.command_queue);
return av_opencl_buffer_read_image(out->data, unsharp->opencl_ctx.out_plane_size,
unsharp->opencl_ctx.plane_num, unsharp->opencl_ctx.cl_outbuf,
unsharp->opencl_ctx.cl_outbuf_size);
@@ -202,6 +273,7 @@
int ff_opencl_unsharp_init(AVFilterContext *ctx)
{
int ret = 0;
+ char build_opts[96];
UnsharpContext *unsharp = ctx->priv;
ret = av_opencl_init(NULL);
if (ret < 0)
@@ -220,11 +292,41 @@
if (ret < 0)
return ret;
unsharp->opencl_ctx.plane_num = PLANE_NUM;
- if (!unsharp->opencl_ctx.kernel_env.kernel) {
- ret = av_opencl_create_kernel(&unsharp->opencl_ctx.kernel_env, "unsharp");
- if (ret < 0) {
- av_log(ctx, AV_LOG_ERROR, "OpenCL failed to create kernel with name 'unsharp'\n");
- return ret;
+ unsharp->opencl_ctx.command_queue = av_opencl_get_command_queue();
+ if (!unsharp->opencl_ctx.command_queue) {
+ av_log(ctx, AV_LOG_ERROR, "Unable to get OpenCL command queue in filter 'unsharp'\n");
+ return AVERROR(EINVAL);
+ }
+ snprintf(build_opts, 96, "-D LU_RADIUS_X=%d -D LU_RADIUS_Y=%d -D CH_RADIUS_X=%d -D CH_RADIUS_Y=%d",
+ 2*unsharp->luma.steps_x+1, 2*unsharp->luma.steps_y+1, 2*unsharp->chroma.steps_x+1, 2*unsharp->chroma.steps_y+1);
+ unsharp->opencl_ctx.program = av_opencl_compile("unsharp", build_opts);
+ if (!unsharp->opencl_ctx.program) {
+ av_log(ctx, AV_LOG_ERROR, "OpenCL failed to compile program 'unsharp'\n");
+ return AVERROR(EINVAL);
+ }
+ if (unsharp->opencl_ctx.use_fast_kernels) {
+ if (!unsharp->opencl_ctx.kernel_luma) {
+ unsharp->opencl_ctx.kernel_luma = clCreateKernel(unsharp->opencl_ctx.program, "unsharp_luma", &ret);
+ if (ret != CL_SUCCESS) {
+ av_log(ctx, AV_LOG_ERROR, "OpenCL failed to create kernel 'unsharp_luma'\n");
+ return ret;
+ }
+ }
+ if (!unsharp->opencl_ctx.kernel_chroma) {
+ unsharp->opencl_ctx.kernel_chroma = clCreateKernel(unsharp->opencl_ctx.program, "unsharp_chroma", &ret);
+ if (ret < 0) {
+ av_log(ctx, AV_LOG_ERROR, "OpenCL failed to create kernel 'unsharp_chroma'\n");
+ return ret;
+ }
+ }
+ }
+ else {
+ if (!unsharp->opencl_ctx.kernel_default) {
+ unsharp->opencl_ctx.kernel_default = clCreateKernel(unsharp->opencl_ctx.program, "unsharp_default", &ret);
+ if (ret < 0) {
+ av_log(ctx, AV_LOG_ERROR, "OpenCL failed to create kernel 'unsharp_default'\n");
+ return ret;
+ }
}
}
return ret;
@@ -237,7 +339,11 @@
av_opencl_buffer_release(&unsharp->opencl_ctx.cl_outbuf);
av_opencl_buffer_release(&unsharp->opencl_ctx.cl_luma_mask);
av_opencl_buffer_release(&unsharp->opencl_ctx.cl_chroma_mask);
- av_opencl_release_kernel(&unsharp->opencl_ctx.kernel_env);
+ clReleaseKernel(unsharp->opencl_ctx.kernel_default);
+ clReleaseKernel(unsharp->opencl_ctx.kernel_luma);
+ clReleaseKernel(unsharp->opencl_ctx.kernel_chroma);
+ clReleaseProgram(unsharp->opencl_ctx.program);
+ unsharp->opencl_ctx.command_queue = NULL;
av_opencl_uninit();
}
diff --git a/libavfilter/unsharp_opencl_kernel.h b/libavfilter/unsharp_opencl_kernel.h
index 0cc8e90..9c4fd65 100644
--- a/libavfilter/unsharp_opencl_kernel.h
+++ b/libavfilter/unsharp_opencl_kernel.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2013 Wei Gao <weigao@multicorewareinc.com>
+ * Copyright (C) 2013 Lenny Wang
*
* This file is part of FFmpeg.
*
@@ -32,7 +33,156 @@
return a;
}
-kernel void unsharp(global unsigned char *src,
+kernel void unsharp_luma(
+ global unsigned char *src,
+ global unsigned char *dst,
+ global int *mask,
+ int amount,
+ int scalebits,
+ int halfscale,
+ int src_stride,
+ int dst_stride,
+ int width,
+ int height)
+{
+ int2 threadIdx, blockIdx, globalIdx;
+ threadIdx.x = get_local_id(0);
+ threadIdx.y = get_local_id(1);
+ blockIdx.x = get_group_id(0);
+ blockIdx.y = get_group_id(1);
+ globalIdx.x = get_global_id(0);
+ globalIdx.y = get_global_id(1);
+
+ if (!amount) {
+ if (globalIdx.x < width && globalIdx.y < height)
+ dst[globalIdx.x + globalIdx.y*dst_stride] = src[globalIdx.x + globalIdx.y*src_stride];
+ return;
+ }
+
+ local uchar l[32][32];
+ local int lc[LU_RADIUS_X*LU_RADIUS_Y];
+ int indexIx, indexIy, i, j;
+
+ for(i = 0; i <= 1; i++) {
+ indexIy = -8 + (blockIdx.y + i) * 16 + threadIdx.y;
+ indexIy = indexIy < 0 ? 0 : indexIy;
+ indexIy = indexIy >= height ? height - 1: indexIy;
+ for(j = 0; j <= 1; j++) {
+ indexIx = -8 + (blockIdx.x + j) * 16 + threadIdx.x;
+ indexIx = indexIx < 0 ? 0 : indexIx;
+ indexIx = indexIx >= width ? width - 1: indexIx;
+ l[i*16 + threadIdx.y][j*16 + threadIdx.x] = src[indexIy*src_stride + indexIx];
+ }
+ }
+
+ int indexL = threadIdx.y*16 + threadIdx.x;
+ if (indexL < LU_RADIUS_X*LU_RADIUS_Y)
+ lc[indexL] = mask[indexL];
+ barrier(CLK_LOCAL_MEM_FENCE);
+
+ int idx, idy, maskIndex;
+ int sum = 0;
+ int steps_x = LU_RADIUS_X/2;
+ int steps_y = LU_RADIUS_Y/2;
+
+ \n#pragma unroll\n
+ for (i = -steps_y; i <= steps_y; i++) {
+ idy = 8 + i + threadIdx.y;
+ \n#pragma unroll\n
+ for (j = -steps_x; j <= steps_x; j++) {
+ idx = 8 + j + threadIdx.x;
+ maskIndex = (i + steps_y)*LU_RADIUS_X + j + steps_x;
+ sum += (int)l[idy][idx] * lc[maskIndex];
+ }
+ }
+ int temp = (int)l[threadIdx.y + 8][threadIdx.x + 8];
+ int res = temp + (((temp - (int)((sum + halfscale) >> scalebits)) * amount) >> 16);
+ if (globalIdx.x < width && globalIdx.y < height)
+ dst[globalIdx.x + globalIdx.y*dst_stride] = clip_uint8(res);
+}
+
+kernel void unsharp_chroma(
+ global unsigned char *src_y,
+ global unsigned char *dst_y,
+ global int *mask,
+ int amount,
+ int scalebits,
+ int halfscale,
+ int src_stride_lu,
+ int src_stride_ch,
+ int dst_stride_lu,
+ int dst_stride_ch,
+ int width,
+ int height,
+ int cw,
+ int ch)
+{
+ global unsigned char *dst_u = dst_y + height * dst_stride_lu;
+ global unsigned char *dst_v = dst_u + ch * dst_stride_ch;
+ global unsigned char *src_u = src_y + height * src_stride_lu;
+ global unsigned char *src_v = src_u + ch * src_stride_ch;
+ int2 threadIdx, blockIdx, globalIdx;
+ threadIdx.x = get_local_id(0);
+ threadIdx.y = get_local_id(1);
+ blockIdx.x = get_group_id(0);
+ blockIdx.y = get_group_id(1);
+ globalIdx.x = get_global_id(0);
+ globalIdx.y = get_global_id(1);
+ int padch = get_global_size(1)/2;
+ global unsigned char *src = globalIdx.y>=padch ? src_v : src_u;
+ global unsigned char *dst = globalIdx.y>=padch ? dst_v : dst_u;
+
+ blockIdx.y = globalIdx.y>=padch ? blockIdx.y - get_num_groups(1)/2 : blockIdx.y;
+ globalIdx.y = globalIdx.y>=padch ? globalIdx.y - padch : globalIdx.y;
+
+ if (!amount) {
+ if (globalIdx.x < cw && globalIdx.y < ch)
+ dst[globalIdx.x + globalIdx.y*dst_stride_ch] = src[globalIdx.x + globalIdx.y*src_stride_ch];
+ return;
+ }
+
+ local uchar l[32][32];
+ local int lc[CH_RADIUS_X*CH_RADIUS_Y];
+ int indexIx, indexIy, i, j;
+ for(i = 0; i <= 1; i++) {
+ indexIy = -8 + (blockIdx.y + i) * 16 + threadIdx.y;
+ indexIy = indexIy < 0 ? 0 : indexIy;
+ indexIy = indexIy >= ch ? ch - 1: indexIy;
+ for(j = 0; j <= 1; j++) {
+ indexIx = -8 + (blockIdx.x + j) * 16 + threadIdx.x;
+ indexIx = indexIx < 0 ? 0 : indexIx;
+ indexIx = indexIx >= cw ? cw - 1: indexIx;
+ l[i*16 + threadIdx.y][j*16 + threadIdx.x] = src[indexIy * src_stride_ch + indexIx];
+ }
+ }
+
+ int indexL = threadIdx.y*16 + threadIdx.x;
+ if (indexL < CH_RADIUS_X*CH_RADIUS_Y)
+ lc[indexL] = mask[indexL];
+ barrier(CLK_LOCAL_MEM_FENCE);
+
+ int idx, idy, maskIndex;
+ int sum = 0;
+ int steps_x = CH_RADIUS_X/2;
+ int steps_y = CH_RADIUS_Y/2;
+
+ \n#pragma unroll\n
+ for (i = -steps_y; i <= steps_y; i++) {
+ idy = 8 + i + threadIdx.y;
+ \n#pragma unroll\n
+ for (j = -steps_x; j <= steps_x; j++) {
+ idx = 8 + j + threadIdx.x;
+ maskIndex = (i + steps_y)*CH_RADIUS_X + j + steps_x;
+ sum += (int)l[idy][idx] * lc[maskIndex];
+ }
+ }
+ int temp = (int)l[threadIdx.y + 8][threadIdx.x + 8];
+ int res = temp + (((temp - (int)((sum + halfscale) >> scalebits)) * amount) >> 16);
+ if (globalIdx.x < cw && globalIdx.y < ch)
+ dst[globalIdx.x + globalIdx.y*dst_stride_ch] = clip_uint8(res);
+}
+
+kernel void unsharp_default(global unsigned char *src,
global unsigned char *dst,
const global unsigned int *mask_lu,
const global unsigned int *mask_ch,
@@ -131,7 +281,6 @@
temp_dst[x + y * temp_dst_stride] = temp_src[x + y * temp_src_stride];
}
}
-
);
#endif /* AVFILTER_UNSHARP_OPENCL_KERNEL_H */
diff --git a/libavfilter/version.h b/libavfilter/version.h
index edc8bcf..9cc7e3c 100644
--- a/libavfilter/version.h
+++ b/libavfilter/version.h
@@ -30,8 +30,8 @@
#include "libavutil/avutil.h"
#define LIBAVFILTER_VERSION_MAJOR 3
-#define LIBAVFILTER_VERSION_MINOR 88
-#define LIBAVFILTER_VERSION_MICRO 101
+#define LIBAVFILTER_VERSION_MINOR 92
+#define LIBAVFILTER_VERSION_MICRO 100
#define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \
LIBAVFILTER_VERSION_MINOR, \
@@ -85,5 +85,8 @@
#ifndef FF_API_DRAWTEXT_OLD_TIMELINE
#define FF_API_DRAWTEXT_OLD_TIMELINE (LIBAVFILTER_VERSION_MAJOR < 4)
#endif
+#ifndef FF_API_NOCONST_GET_NAME
+#define FF_API_NOCONST_GET_NAME (LIBAVFILTER_VERSION_MAJOR < 4)
+#endif
#endif /* AVFILTER_VERSION_H */
diff --git a/libavfilter/vf_alphamerge.c b/libavfilter/vf_alphamerge.c
index 0e5ee22..5f0da35 100644
--- a/libavfilter/vf_alphamerge.c
+++ b/libavfilter/vf_alphamerge.c
@@ -195,7 +195,7 @@
{ NULL }
};
-AVFilter avfilter_vf_alphamerge = {
+AVFilter ff_vf_alphamerge = {
.name = "alphamerge",
.description = NULL_IF_CONFIG_SMALL("Copy the luma value of the second "
"input into the alpha channel of the first input."),
diff --git a/libavfilter/vf_aspect.c b/libavfilter/vf_aspect.c
index 761c828..97fb216 100644
--- a/libavfilter/vf_aspect.c
+++ b/libavfilter/vf_aspect.c
@@ -30,11 +30,32 @@
#include "libavutil/mathematics.h"
#include "libavutil/opt.h"
#include "libavutil/parseutils.h"
+#include "libavutil/pixdesc.h"
#include "avfilter.h"
#include "internal.h"
#include "video.h"
+static const char *const var_names[] = {
+ "w",
+ "h",
+ "a", "dar",
+ "sar",
+ "hsub",
+ "vsub",
+ NULL
+};
+
+enum var_name {
+ VAR_W,
+ VAR_H,
+ VAR_A, VAR_DAR,
+ VAR_SAR,
+ VAR_HSUB,
+ VAR_VSUB,
+ VARS_NB
+};
+
typedef struct {
const AVClass *class;
AVRational dar;
@@ -43,7 +64,7 @@
#if FF_API_OLD_FILTER_OPTS
float aspect_den;
#endif
- char *ratio_str;
+ char *ratio_expr;
} AspectContext;
static av_cold int init(AVFilterContext *ctx)
@@ -52,28 +73,20 @@
int ret;
#if FF_API_OLD_FILTER_OPTS
- if (s->ratio_str && s->aspect_den > 0) {
+ if (s->ratio_expr && s->aspect_den > 0) {
double num;
av_log(ctx, AV_LOG_WARNING,
"num:den syntax is deprecated, please use num/den or named options instead\n");
- ret = av_expr_parse_and_eval(&num, s->ratio_str, NULL, NULL,
+ ret = av_expr_parse_and_eval(&num, s->ratio_expr, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, 0, ctx);
if (ret < 0) {
- av_log(ctx, AV_LOG_ERROR, "Unable to parse ratio numerator \"%s\"\n", s->ratio_str);
+ av_log(ctx, AV_LOG_ERROR, "Unable to parse ratio numerator \"%s\"\n", s->ratio_expr);
return AVERROR(EINVAL);
}
s->sar = s->dar = av_d2q(num / s->aspect_den, s->max);
- } else
-#endif
- if (s->ratio_str) {
- ret = av_parse_ratio(&s->sar, s->ratio_str, s->max, 0, ctx);
- if (ret < 0 || s->sar.num < 0 || s->sar.den <= 0) {
- av_log(ctx, AV_LOG_ERROR,
- "Invalid string '%s' for aspect ratio\n", s->ratio_str);
- return AVERROR(EINVAL);
- }
- s->dar = s->sar;
}
+#endif
+
return 0;
}
@@ -97,6 +110,45 @@
}
}
+static int get_aspect_ratio(AVFilterLink *inlink, AVRational *aspect_ratio)
+{
+ AVFilterContext *ctx = inlink->dst;
+ AspectContext *s = inlink->dst->priv;
+ const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format);
+ double var_values[VARS_NB], res;
+ int ret;
+
+ var_values[VAR_W] = inlink->w;
+ var_values[VAR_H] = inlink->h;
+ var_values[VAR_A] = (double) inlink->w / inlink->h;
+ var_values[VAR_SAR] = inlink->sample_aspect_ratio.num ?
+ (double) inlink->sample_aspect_ratio.num / inlink->sample_aspect_ratio.den : 1;
+ var_values[VAR_DAR] = var_values[VAR_A] * var_values[VAR_SAR];
+ var_values[VAR_HSUB] = 1 << desc->log2_chroma_w;
+ var_values[VAR_VSUB] = 1 << desc->log2_chroma_h;
+
+ /* evaluate new aspect ratio*/
+ ret = av_expr_parse_and_eval(&res, s->ratio_expr,
+ var_names, var_values,
+ NULL, NULL, NULL, NULL, NULL, 0, ctx);
+ if (ret < 0) {
+ ret = av_parse_ratio(aspect_ratio, s->ratio_expr, s->max, 0, ctx);
+ } else
+ *aspect_ratio = av_d2q(res, s->max);
+
+ if (ret < 0) {
+ av_log(ctx, AV_LOG_ERROR,
+ "Error when evaluating the expression '%s'\n", s->ratio_expr);
+ return ret;
+ }
+ if (aspect_ratio->num < 0 || aspect_ratio->den <= 0) {
+ av_log(ctx, AV_LOG_ERROR,
+ "Invalid string '%s' for aspect ratio\n", s->ratio_expr);
+ return AVERROR(EINVAL);
+ }
+ return 0;
+}
+
#if CONFIG_SETDAR_FILTER
static int setdar_config_props(AVFilterLink *inlink)
@@ -105,6 +157,16 @@
AVRational dar;
AVRational old_dar;
AVRational old_sar = inlink->sample_aspect_ratio;
+ int ret;
+
+#if FF_API_OLD_FILTER_OPTS
+ if (!(s->ratio_expr && s->aspect_den > 0)) {
+#endif
+ if ((ret = get_aspect_ratio(inlink, &s->dar)))
+ return ret;
+#if FF_API_OLD_FILTER_OPTS
+ }
+#endif
if (s->dar.num && s->dar.den) {
av_reduce(&s->sar.num, &s->sar.den,
@@ -126,9 +188,9 @@
}
static const AVOption setdar_options[] = {
- { "dar", "set display aspect ratio", OFFSET(ratio_str), AV_OPT_TYPE_STRING, {.str="0"}, .flags=FLAGS },
- { "ratio", "set display aspect ratio", OFFSET(ratio_str), AV_OPT_TYPE_STRING, {.str="0"}, .flags=FLAGS },
- { "r", "set display aspect ratio", OFFSET(ratio_str), AV_OPT_TYPE_STRING, {.str="0"}, .flags=FLAGS },
+ { "dar", "set display aspect ratio", OFFSET(ratio_expr), AV_OPT_TYPE_STRING, { .str = "0" }, .flags = FLAGS },
+ { "ratio", "set display aspect ratio", OFFSET(ratio_expr), AV_OPT_TYPE_STRING, { .str = "0" }, .flags = FLAGS },
+ { "r", "set display aspect ratio", OFFSET(ratio_expr), AV_OPT_TYPE_STRING, { .str = "0" }, .flags = FLAGS },
#if FF_API_OLD_FILTER_OPTS
{ "dar_den", NULL, OFFSET(aspect_den), AV_OPT_TYPE_FLOAT, { .dbl = 0 }, 0, FLT_MAX, FLAGS },
#endif
@@ -156,7 +218,7 @@
{ NULL }
};
-AVFilter avfilter_vf_setdar = {
+AVFilter ff_vf_setdar = {
.name = "setdar",
.description = NULL_IF_CONFIG_SMALL("Set the frame display aspect ratio."),
.init = init,
@@ -175,6 +237,16 @@
AspectContext *s = inlink->dst->priv;
AVRational old_sar = inlink->sample_aspect_ratio;
AVRational old_dar, dar;
+ int ret;
+
+#if FF_API_OLD_FILTER_OPTS
+ if (!(s->ratio_expr && s->aspect_den > 0)) {
+#endif
+ if ((ret = get_aspect_ratio(inlink, &s->sar)))
+ return ret;
+#if FF_API_OLD_FILTER_OPTS
+ }
+#endif
inlink->sample_aspect_ratio = s->sar;
@@ -188,9 +260,9 @@
}
static const AVOption setsar_options[] = {
- { "sar", "set sample (pixel) aspect ratio", OFFSET(ratio_str), AV_OPT_TYPE_STRING, {.str="0"}, .flags=FLAGS },
- { "ratio", "set sample (pixel) aspect ratio", OFFSET(ratio_str), AV_OPT_TYPE_STRING, {.str="0"}, .flags=FLAGS },
- { "r", "set sample (pixel) aspect ratio", OFFSET(ratio_str), AV_OPT_TYPE_STRING, {.str="0"}, .flags=FLAGS },
+ { "sar", "set sample (pixel) aspect ratio", OFFSET(ratio_expr), AV_OPT_TYPE_STRING, { .str = "0" }, .flags = FLAGS },
+ { "ratio", "set sample (pixel) aspect ratio", OFFSET(ratio_expr), AV_OPT_TYPE_STRING, { .str = "0" }, .flags = FLAGS },
+ { "r", "set sample (pixel) aspect ratio", OFFSET(ratio_expr), AV_OPT_TYPE_STRING, { .str = "0" }, .flags = FLAGS },
#if FF_API_OLD_FILTER_OPTS
{ "sar_den", NULL, OFFSET(aspect_den), AV_OPT_TYPE_FLOAT, { .dbl = 0 }, 0, FLT_MAX, FLAGS },
#endif
@@ -218,7 +290,7 @@
{ NULL }
};
-AVFilter avfilter_vf_setsar = {
+AVFilter ff_vf_setsar = {
.name = "setsar",
.description = NULL_IF_CONFIG_SMALL("Set the pixel sample aspect ratio."),
.init = init,
diff --git a/libavfilter/vf_bbox.c b/libavfilter/vf_bbox.c
index 3235358..6c6aab1 100644
--- a/libavfilter/vf_bbox.c
+++ b/libavfilter/vf_bbox.c
@@ -122,7 +122,7 @@
{ NULL }
};
-AVFilter avfilter_vf_bbox = {
+AVFilter ff_vf_bbox = {
.name = "bbox",
.description = NULL_IF_CONFIG_SMALL("Compute bounding box for each frame."),
.priv_size = sizeof(BBoxContext),
diff --git a/libavfilter/vf_blackdetect.c b/libavfilter/vf_blackdetect.c
index 52f2e6e..90a28a9 100644
--- a/libavfilter/vf_blackdetect.c
+++ b/libavfilter/vf_blackdetect.c
@@ -193,7 +193,7 @@
{ NULL }
};
-AVFilter avfilter_vf_blackdetect = {
+AVFilter ff_vf_blackdetect = {
.name = "blackdetect",
.description = NULL_IF_CONFIG_SMALL("Detect video intervals that are (almost) black."),
.priv_size = sizeof(BlackDetectContext),
diff --git a/libavfilter/vf_blackframe.c b/libavfilter/vf_blackframe.c
index dd52b31..9b0c973 100644
--- a/libavfilter/vf_blackframe.c
+++ b/libavfilter/vf_blackframe.c
@@ -119,7 +119,7 @@
{ NULL }
};
-AVFilter avfilter_vf_blackframe = {
+AVFilter ff_vf_blackframe = {
.name = "blackframe",
.description = NULL_IF_CONFIG_SMALL("Detect frames that are (almost) black."),
.priv_size = sizeof(BlackFrameContext),
diff --git a/libavfilter/vf_blend.c b/libavfilter/vf_blend.c
index a5c8e9f..d422a9c 100644
--- a/libavfilter/vf_blend.c
+++ b/libavfilter/vf_blend.c
@@ -451,7 +451,7 @@
{ NULL }
};
-AVFilter avfilter_vf_blend = {
+AVFilter ff_vf_blend = {
.name = "blend",
.description = NULL_IF_CONFIG_SMALL("Blend two video frames into each other."),
.init = init,
diff --git a/libavfilter/vf_boxblur.c b/libavfilter/vf_boxblur.c
index 4f637fe..3183f43 100644
--- a/libavfilter/vf_boxblur.c
+++ b/libavfilter/vf_boxblur.c
@@ -372,7 +372,7 @@
{ NULL }
};
-AVFilter avfilter_vf_boxblur = {
+AVFilter ff_vf_boxblur = {
.name = "boxblur",
.description = NULL_IF_CONFIG_SMALL("Blur the input."),
.priv_size = sizeof(BoxBlurContext),
diff --git a/libavfilter/vf_colorbalance.c b/libavfilter/vf_colorbalance.c
index ca6c781..c151c33 100644
--- a/libavfilter/vf_colorbalance.c
+++ b/libavfilter/vf_colorbalance.c
@@ -201,7 +201,7 @@
{ NULL }
};
-AVFilter avfilter_vf_colorbalance = {
+AVFilter ff_vf_colorbalance = {
.name = "colorbalance",
.description = NULL_IF_CONFIG_SMALL("Adjust the color balance."),
.priv_size = sizeof(ColorBalanceContext),
diff --git a/libavfilter/vf_colorchannelmixer.c b/libavfilter/vf_colorchannelmixer.c
index 9c0044d..c7e63b5 100644
--- a/libavfilter/vf_colorchannelmixer.c
+++ b/libavfilter/vf_colorchannelmixer.c
@@ -347,7 +347,7 @@
{ NULL }
};
-AVFilter avfilter_vf_colorchannelmixer = {
+AVFilter ff_vf_colorchannelmixer = {
.name = "colorchannelmixer",
.description = NULL_IF_CONFIG_SMALL("Adjust colors by mixing color channels."),
.priv_size = sizeof(ColorChannelMixerContext),
diff --git a/libavfilter/vf_colormatrix.c b/libavfilter/vf_colormatrix.c
index 825e120..e1b48fa 100644
--- a/libavfilter/vf_colormatrix.c
+++ b/libavfilter/vf_colormatrix.c
@@ -375,7 +375,7 @@
{ NULL }
};
-AVFilter avfilter_vf_colormatrix = {
+AVFilter ff_vf_colormatrix = {
.name = "colormatrix",
.description = NULL_IF_CONFIG_SMALL("Convert color matrix."),
.priv_size = sizeof(ColorMatrixContext),
diff --git a/libavfilter/vf_copy.c b/libavfilter/vf_copy.c
index b36d5a6..fcc85c5 100644
--- a/libavfilter/vf_copy.c
+++ b/libavfilter/vf_copy.c
@@ -61,7 +61,7 @@
{ NULL }
};
-AVFilter avfilter_vf_copy = {
+AVFilter ff_vf_copy = {
.name = "copy",
.description = NULL_IF_CONFIG_SMALL("Copy the input video unchanged to the output."),
.inputs = avfilter_vf_copy_inputs,
diff --git a/libavfilter/vf_crop.c b/libavfilter/vf_crop.c
index f9ffc8e..261db33 100644
--- a/libavfilter/vf_crop.c
+++ b/libavfilter/vf_crop.c
@@ -332,7 +332,7 @@
{ NULL }
};
-AVFilter avfilter_vf_crop = {
+AVFilter ff_vf_crop = {
.name = "crop",
.description = NULL_IF_CONFIG_SMALL("Crop the input video."),
.priv_size = sizeof(CropContext),
diff --git a/libavfilter/vf_cropdetect.c b/libavfilter/vf_cropdetect.c
index 3aa2448..4a6b658 100644
--- a/libavfilter/vf_cropdetect.c
+++ b/libavfilter/vf_cropdetect.c
@@ -239,7 +239,7 @@
{ NULL }
};
-AVFilter avfilter_vf_cropdetect = {
+AVFilter ff_vf_cropdetect = {
.name = "cropdetect",
.description = NULL_IF_CONFIG_SMALL("Auto-detect crop size."),
.priv_size = sizeof(CropDetectContext),
diff --git a/libavfilter/vf_curves.c b/libavfilter/vf_curves.c
index 6356cef..5123430 100644
--- a/libavfilter/vf_curves.c
+++ b/libavfilter/vf_curves.c
@@ -539,7 +539,7 @@
{ NULL }
};
-AVFilter avfilter_vf_curves = {
+AVFilter ff_vf_curves = {
.name = "curves",
.description = NULL_IF_CONFIG_SMALL("Adjust components curves."),
.priv_size = sizeof(CurvesContext),
diff --git a/libavfilter/vf_dctdnoiz.c b/libavfilter/vf_dctdnoiz.c
index 92129ad..71b8536 100644
--- a/libavfilter/vf_dctdnoiz.c
+++ b/libavfilter/vf_dctdnoiz.c
@@ -419,7 +419,7 @@
{ NULL }
};
-AVFilter avfilter_vf_dctdnoiz = {
+AVFilter ff_vf_dctdnoiz = {
.name = "dctdnoiz",
.description = NULL_IF_CONFIG_SMALL("Denoise frames using 2D DCT."),
.priv_size = sizeof(DCTdnoizContext),
diff --git a/libavfilter/vf_decimate.c b/libavfilter/vf_decimate.c
index abd0776..5efafe9 100644
--- a/libavfilter/vf_decimate.c
+++ b/libavfilter/vf_decimate.c
@@ -43,6 +43,7 @@
AVFrame **clean_src; ///< frame queue for the clean source
int got_frame[2]; ///< frame request flag for each input stream
double ts_unit; ///< timestamp units for the output frames
+ int64_t start_pts; ///< base for output timestamps
uint32_t eof; ///< bitmask for end of stream
int hsub, vsub; ///< chroma subsampling values
int depth;
@@ -210,11 +211,14 @@
av_frame_free(&dm->queue[i].frame);
} else {
AVFrame *frame = dm->queue[i].frame;
+ if (frame->pts != AV_NOPTS_VALUE && dm->start_pts == AV_NOPTS_VALUE)
+ dm->start_pts = frame->pts;
if (dm->ppsrc) {
av_frame_free(&frame);
frame = dm->clean_src[i];
}
- frame->pts = outlink->frame_count * dm->ts_unit;
+ frame->pts = outlink->frame_count * dm->ts_unit +
+ (dm->start_pts == AV_NOPTS_VALUE ? 0 : dm->start_pts);
ret = ff_filter_frame(outlink, frame);
if (ret < 0)
break;
@@ -259,7 +263,7 @@
static av_cold int decimate_init(AVFilterContext *ctx)
{
- const DecimateContext *dm = ctx->priv;
+ DecimateContext *dm = ctx->priv;
AVFilterPad pad = {
.name = av_strdup("main"),
.type = AVMEDIA_TYPE_VIDEO,
@@ -285,6 +289,8 @@
return AVERROR(EINVAL);
}
+ dm->start_pts = AV_NOPTS_VALUE;
+
return 0;
}
@@ -384,7 +390,7 @@
{ NULL }
};
-AVFilter avfilter_vf_decimate = {
+AVFilter ff_vf_decimate = {
.name = "decimate",
.description = NULL_IF_CONFIG_SMALL("Decimate frames (post field matching filter)."),
.init = decimate_init,
diff --git a/libavfilter/vf_delogo.c b/libavfilter/vf_delogo.c
index 24f17f0..fbc8983 100644
--- a/libavfilter/vf_delogo.c
+++ b/libavfilter/vf_delogo.c
@@ -277,7 +277,7 @@
{ NULL }
};
-AVFilter avfilter_vf_delogo = {
+AVFilter ff_vf_delogo = {
.name = "delogo",
.description = NULL_IF_CONFIG_SMALL("Remove logo from input video."),
.priv_size = sizeof(DelogoContext),
diff --git a/libavfilter/vf_deshake.c b/libavfilter/vf_deshake.c
index 24ac41d..1d62c44 100644
--- a/libavfilter/vf_deshake.c
+++ b/libavfilter/vf_deshake.c
@@ -567,7 +567,7 @@
{ NULL }
};
-AVFilter avfilter_vf_deshake = {
+AVFilter ff_vf_deshake = {
.name = "deshake",
.description = NULL_IF_CONFIG_SMALL("Stabilize shaky video."),
.priv_size = sizeof(DeshakeContext),
diff --git a/libavfilter/vf_drawbox.c b/libavfilter/vf_drawbox.c
index 91c32bc..dd884a7 100644
--- a/libavfilter/vf_drawbox.c
+++ b/libavfilter/vf_drawbox.c
@@ -271,7 +271,7 @@
{ NULL }
};
-AVFilter avfilter_vf_drawbox = {
+AVFilter ff_vf_drawbox = {
.name = "drawbox",
.description = NULL_IF_CONFIG_SMALL("Draw a colored box on the input video."),
.priv_size = sizeof(DrawBoxContext),
@@ -377,7 +377,7 @@
{ NULL }
};
-AVFilter avfilter_vf_drawgrid = {
+AVFilter ff_vf_drawgrid = {
.name = "drawgrid",
.description = NULL_IF_CONFIG_SMALL("Draw a colored grid on the input video."),
.priv_size = sizeof(DrawBoxContext),
diff --git a/libavfilter/vf_drawtext.c b/libavfilter/vf_drawtext.c
index f1c7b26..91b8218 100644
--- a/libavfilter/vf_drawtext.c
+++ b/libavfilter/vf_drawtext.c
@@ -48,7 +48,6 @@
#include "video.h"
#include <ft2build.h>
-#include <freetype/config/ftheader.h>
#include FT_FREETYPE_H
#include FT_GLYPH_H
#if CONFIG_FONTCONFIG
@@ -1056,7 +1055,7 @@
{ NULL }
};
-AVFilter avfilter_vf_drawtext = {
+AVFilter ff_vf_drawtext = {
.name = "drawtext",
.description = NULL_IF_CONFIG_SMALL("Draw text on top of video frames using libfreetype library."),
.priv_size = sizeof(DrawTextContext),
diff --git a/libavfilter/vf_edgedetect.c b/libavfilter/vf_edgedetect.c
index ed0a14c..c8ec734 100644
--- a/libavfilter/vf_edgedetect.c
+++ b/libavfilter/vf_edgedetect.c
@@ -317,7 +317,7 @@
{ NULL }
};
-AVFilter avfilter_vf_edgedetect = {
+AVFilter ff_vf_edgedetect = {
.name = "edgedetect",
.description = NULL_IF_CONFIG_SMALL("Detect and draw edge."),
.priv_size = sizeof(EdgeDetectContext),
diff --git a/libavfilter/vf_elbg.c b/libavfilter/vf_elbg.c
new file mode 100644
index 0000000..2781281
--- /dev/null
+++ b/libavfilter/vf_elbg.c
@@ -0,0 +1,212 @@
+/*
+ * Copyright (c) 2013 Stefano Sabatini
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * video quantizer filter based on ELBG
+ */
+
+#include "libavcodec/elbg.h"
+#include "libavutil/opt.h"
+#include "libavutil/pixdesc.h"
+#include "libavutil/random_seed.h"
+
+#include "avfilter.h"
+#include "drawutils.h"
+#include "internal.h"
+#include "video.h"
+
+typedef struct {
+ const AVClass *class;
+ AVLFG lfg;
+ int lfg_seed;
+ int max_steps_nb;
+ int *codeword;
+ int codeword_length;
+ int *codeword_closest_codebook_idxs;
+ int *codebook;
+ int codebook_length;
+ const AVPixFmtDescriptor *pix_desc;
+ uint8_t rgba_map[4];
+} ELBGContext;
+
+#define OFFSET(x) offsetof(ELBGContext, x)
+#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
+
+static const AVOption elbg_options[] = {
+ { "codebook_length", "set codebook length", OFFSET(codebook_length), AV_OPT_TYPE_INT, { .i64 = 256 }, 1, INT_MAX, FLAGS },
+ { "l", "set codebook length", OFFSET(codebook_length), AV_OPT_TYPE_INT, { .i64 = 256 }, 1, INT_MAX, FLAGS },
+ { "nb_steps", "set max number of steps used to compute the mapping", OFFSET(max_steps_nb), AV_OPT_TYPE_INT, { .i64 = 1 }, 1, INT_MAX, FLAGS },
+ { "n", "set max number of steps used to compute the mapping", OFFSET(max_steps_nb), AV_OPT_TYPE_INT, { .i64 = 1 }, 1, INT_MAX, FLAGS },
+ { "seed", "set the random seed", OFFSET(lfg_seed), AV_OPT_TYPE_INT, {.i64 = -1}, -1, UINT32_MAX, FLAGS },
+ { "s", "set the random seed", OFFSET(lfg_seed), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, FLAGS },
+ { NULL }
+};
+
+AVFILTER_DEFINE_CLASS(elbg);
+
+static av_cold int init(AVFilterContext *ctx)
+{
+ ELBGContext *elbg = ctx->priv;
+
+ if (elbg->lfg_seed == -1)
+ elbg->lfg_seed = av_get_random_seed();
+
+ av_lfg_init(&elbg->lfg, elbg->lfg_seed);
+ return 0;
+}
+
+static int query_formats(AVFilterContext *ctx)
+{
+ static const enum PixelFormat pix_fmts[] = {
+ AV_PIX_FMT_ARGB, AV_PIX_FMT_RGBA, AV_PIX_FMT_ABGR, AV_PIX_FMT_BGRA,
+ AV_PIX_FMT_RGB24, AV_PIX_FMT_BGR24,
+ AV_PIX_FMT_NONE
+ };
+
+ ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
+
+ return 0;
+}
+
+#define NB_COMPONENTS 3
+
+static int config_input(AVFilterLink *inlink)
+{
+ AVFilterContext *ctx = inlink->dst;
+ ELBGContext *elbg = ctx->priv;
+
+ elbg->pix_desc = av_pix_fmt_desc_get(inlink->format);
+ elbg->codeword_length = inlink->w * inlink->h;
+ elbg->codeword = av_realloc_f(elbg->codeword, elbg->codeword_length,
+ NB_COMPONENTS * sizeof(*elbg->codeword));
+ if (!elbg->codeword)
+ return AVERROR(ENOMEM);
+
+ elbg->codeword_closest_codebook_idxs =
+ av_realloc_f(elbg->codeword_closest_codebook_idxs, elbg->codeword_length,
+ sizeof(*elbg->codeword_closest_codebook_idxs));
+ if (!elbg->codeword_closest_codebook_idxs)
+ return AVERROR(ENOMEM);
+
+ elbg->codebook = av_realloc_f(elbg->codebook, elbg->codebook_length,
+ NB_COMPONENTS * sizeof(*elbg->codebook));
+ if (!elbg->codebook)
+ return AVERROR(ENOMEM);
+
+ ff_fill_rgba_map(elbg->rgba_map, inlink->format);
+
+ return 0;
+}
+
+#define R 0
+#define G 1
+#define B 2
+
+static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
+{
+ ELBGContext *elbg = inlink->dst->priv;
+ int i, j, k;
+ uint8_t *p, *p0;
+
+ const uint8_t r_idx = elbg->rgba_map[R];
+ const uint8_t g_idx = elbg->rgba_map[G];
+ const uint8_t b_idx = elbg->rgba_map[B];
+
+ /* build the codeword */
+ p0 = frame->data[0];
+ k = 0;
+ for (i = 0; i < inlink->h; i++) {
+ p = p0;
+ for (j = 0; j < inlink->w; j++) {
+ elbg->codeword[k++] = p[r_idx];
+ elbg->codeword[k++] = p[g_idx];
+ elbg->codeword[k++] = p[b_idx];
+ p += elbg->pix_desc->nb_components;
+ }
+ p0 += frame->linesize[0];
+ }
+
+ /* compute the codebook */
+ avpriv_init_elbg(elbg->codeword, NB_COMPONENTS, elbg->codeword_length,
+ elbg->codebook, elbg->codebook_length, elbg->max_steps_nb,
+ elbg->codeword_closest_codebook_idxs, &elbg->lfg);
+ avpriv_do_elbg(elbg->codeword, NB_COMPONENTS, elbg->codeword_length,
+ elbg->codebook, elbg->codebook_length, elbg->max_steps_nb,
+ elbg->codeword_closest_codebook_idxs, &elbg->lfg);
+
+ /* fill the output with the codebook values */
+ p0 = frame->data[0];
+
+ k = 0;
+ for (i = 0; i < inlink->h; i++) {
+ p = p0;
+ for (j = 0; j < inlink->w; j++) {
+ int cb_idx = NB_COMPONENTS * elbg->codeword_closest_codebook_idxs[k++];
+ p[r_idx] = elbg->codebook[cb_idx];
+ p[g_idx] = elbg->codebook[cb_idx+1];
+ p[b_idx] = elbg->codebook[cb_idx+2];
+ p += elbg->pix_desc->nb_components;
+ }
+ p0 += frame->linesize[0];
+ }
+
+ return ff_filter_frame(inlink->dst->outputs[0], frame);
+}
+
+static av_cold void uninit(AVFilterContext *ctx)
+{
+ ELBGContext *elbg = ctx->priv;
+
+ av_freep(&elbg->codebook);
+ av_freep(&elbg->codeword);
+ av_freep(&elbg->codeword_closest_codebook_idxs);
+}
+
+static const AVFilterPad elbg_inputs[] = {
+ {
+ .name = "default",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .config_props = config_input,
+ .filter_frame = filter_frame,
+ .needs_writable = 1,
+ },
+ { NULL }
+};
+
+static const AVFilterPad elbg_outputs[] = {
+ {
+ .name = "default",
+ .type = AVMEDIA_TYPE_VIDEO,
+ },
+ { NULL }
+};
+
+AVFilter ff_vf_elbg = {
+ .name = "elbg",
+ .description = NULL_IF_CONFIG_SMALL("Apply posterize effect, using the ELBG algorithm."),
+ .priv_size = sizeof(ELBGContext),
+ .priv_class = &elbg_class,
+ .query_formats = query_formats,
+ .init = init,
+ .uninit = uninit,
+ .inputs = elbg_inputs,
+ .outputs = elbg_outputs,
+};
diff --git a/libavfilter/vf_extractplanes.c b/libavfilter/vf_extractplanes.c
index 7c04a78..fadd2dd 100644
--- a/libavfilter/vf_extractplanes.c
+++ b/libavfilter/vf_extractplanes.c
@@ -296,7 +296,7 @@
{ NULL }
};
-AVFilter avfilter_vf_extractplanes = {
+AVFilter ff_vf_extractplanes = {
.name = "extractplanes",
.description = NULL_IF_CONFIG_SMALL("Extract planes as grayscale frames."),
.priv_size = sizeof(ExtractPlanesContext),
@@ -320,7 +320,7 @@
return init(ctx);
}
-AVFilter avfilter_vf_alphaextract = {
+AVFilter ff_vf_alphaextract = {
.name = "alphaextract",
.description = NULL_IF_CONFIG_SMALL("Extract an alpha channel as a "
"grayscale image component."),
diff --git a/libavfilter/vf_fade.c b/libavfilter/vf_fade.c
index 1473273..cc10b12 100644
--- a/libavfilter/vf_fade.c
+++ b/libavfilter/vf_fade.c
@@ -25,6 +25,7 @@
* based heavily on vf_negate.c by Bobby Bingham
*/
+#include "libavutil/avassert.h"
#include "libavutil/avstring.h"
#include "libavutil/common.h"
#include "libavutil/eval.h"
@@ -53,7 +54,6 @@
int type;
int factor, fade_per_frame;
int start_frame, nb_frames;
- unsigned int frame_index;
int hsub, vsub, bpp;
unsigned int black_level, black_level_scaled;
uint8_t is_packed_rgb;
@@ -61,6 +61,8 @@
int alpha;
uint64_t start_time, duration;
enum {VF_FADE_WAITING=0, VF_FADE_FADING, VF_FADE_DONE} fade_state;
+ uint8_t color_rgba[4]; ///< fade color
+ int black_fade; ///< if color_rgba is black
} FadeContext;
static av_cold int init(AVFilterContext *ctx)
@@ -89,11 +91,13 @@
(s->duration / (double)AV_TIME_BASE),s->alpha);
}
+ s->black_fade = !memcmp(s->color_rgba, "\x00\x00\x00\xff", 4);
return 0;
}
static int query_formats(AVFilterContext *ctx)
{
+ const FadeContext *s = ctx->priv;
static const enum AVPixelFormat pix_fmts[] = {
AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV420P,
AV_PIX_FMT_YUV411P, AV_PIX_FMT_YUV410P,
@@ -105,8 +109,17 @@
AV_PIX_FMT_RGBA, AV_PIX_FMT_BGRA,
AV_PIX_FMT_NONE
};
+ static const enum AVPixelFormat pix_fmts_rgb[] = {
+ AV_PIX_FMT_RGB24, AV_PIX_FMT_BGR24,
+ AV_PIX_FMT_ARGB, AV_PIX_FMT_ABGR,
+ AV_PIX_FMT_RGBA, AV_PIX_FMT_BGRA,
+ AV_PIX_FMT_NONE
+ };
- ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
+ if (s->black_fade)
+ ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
+ else
+ ff_set_common_formats(ctx, ff_make_format_list(pix_fmts_rgb));
return 0;
}
@@ -138,6 +151,47 @@
return 0;
}
+static av_always_inline void filter_rgb(FadeContext *s, const AVFrame *frame,
+ int slice_start, int slice_end,
+ int do_alpha, int step)
+{
+ int i, j;
+ const uint8_t r_idx = s->rgba_map[R];
+ const uint8_t g_idx = s->rgba_map[G];
+ const uint8_t b_idx = s->rgba_map[B];
+ const uint8_t a_idx = s->rgba_map[A];
+ const uint8_t *c = s->color_rgba;
+
+ for (i = slice_start; i < slice_end; i++) {
+ uint8_t *p = frame->data[0] + i * frame->linesize[0];
+ for (j = 0; j < frame->width; j++) {
+#define INTERP(c_name, c_idx) av_clip_uint8(((c[c_idx]<<16) + ((int)p[c_name] - (int)c[c_idx]) * s->factor + (1<<15)) >> 16)
+ p[r_idx] = INTERP(r_idx, 0);
+ p[g_idx] = INTERP(g_idx, 1);
+ p[b_idx] = INTERP(b_idx, 2);
+ if (do_alpha)
+ p[a_idx] = INTERP(a_idx, 3);
+ p += step;
+ }
+ }
+}
+
+static int filter_slice_rgb(AVFilterContext *ctx, void *arg, int jobnr,
+ int nb_jobs)
+{
+ FadeContext *s = ctx->priv;
+ AVFrame *frame = arg;
+ int slice_start = (frame->height * jobnr ) / nb_jobs;
+ int slice_end = (frame->height * (jobnr+1)) / nb_jobs;
+
+ if (s->alpha) filter_rgb(s, frame, slice_start, slice_end, 1, 4);
+ else if (s->bpp == 3) filter_rgb(s, frame, slice_start, slice_end, 0, 3);
+ else if (s->bpp == 4) filter_rgb(s, frame, slice_start, slice_end, 0, 4);
+ else av_assert0(0);
+
+ return 0;
+}
+
static int filter_slice_luma(AVFilterContext *ctx, void *arg, int jobnr,
int nb_jobs)
{
@@ -222,36 +276,36 @@
// Calculate Fade assuming this is a Fade In
if (s->fade_state == VF_FADE_WAITING) {
s->factor=0;
- if ((frame_timestamp >= (s->start_time/(double)AV_TIME_BASE))
- && (s->frame_index >= s->start_frame)) {
+ if (frame_timestamp >= s->start_time/(double)AV_TIME_BASE
+ && inlink->frame_count >= s->start_frame) {
// Time to start fading
s->fade_state = VF_FADE_FADING;
// Save start time in case we are starting based on frames and fading based on time
- if ((s->start_time == 0) && (s->start_frame != 0)) {
+ if (s->start_time == 0 && s->start_frame != 0) {
s->start_time = frame_timestamp*(double)AV_TIME_BASE;
}
// Save start frame in case we are starting based on time and fading based on frames
- if ((s->start_time != 0) && (s->start_frame == 0)) {
- s->start_frame = s->frame_index;
+ if (s->start_time != 0 && s->start_frame == 0) {
+ s->start_frame = inlink->frame_count;
}
}
}
if (s->fade_state == VF_FADE_FADING) {
if (s->duration == 0) {
// Fading based on frame count
- s->factor = (s->frame_index - s->start_frame) * s->fade_per_frame;
- if (s->frame_index > (s->start_frame + s->nb_frames)) {
+ s->factor = (inlink->frame_count - s->start_frame) * s->fade_per_frame;
+ if (inlink->frame_count > s->start_frame + s->nb_frames) {
s->fade_state = VF_FADE_DONE;
}
} else {
// Fading based on duration
- s->factor = (frame_timestamp - (s->start_time/(double)AV_TIME_BASE))
+ s->factor = (frame_timestamp - s->start_time/(double)AV_TIME_BASE)
* (float) UINT16_MAX / (s->duration/(double)AV_TIME_BASE);
- if (frame_timestamp > ((s->start_time/(double)AV_TIME_BASE)
- + (s->duration/(double)AV_TIME_BASE))) {
+ if (frame_timestamp > s->start_time/(double)AV_TIME_BASE
+ + s->duration/(double)AV_TIME_BASE) {
s->fade_state = VF_FADE_DONE;
}
}
@@ -263,7 +317,7 @@
s->factor = av_clip_uint16(s->factor);
// Invert fade_factor if Fading Out
- if (s->type == 1) {
+ if (s->type == FADE_OUT) {
s->factor=UINT16_MAX-s->factor;
}
@@ -271,8 +325,11 @@
if (s->alpha) {
ctx->internal->execute(ctx, filter_slice_alpha, frame, NULL,
FFMIN(frame->height, ctx->graph->nb_threads));
+ } else if (s->is_packed_rgb && !s->black_fade) {
+ ctx->internal->execute(ctx, filter_slice_rgb, frame, NULL,
+ FFMIN(frame->height, ctx->graph->nb_threads));
} else {
- /* luma or rgb plane */
+ /* luma, or rgb plane in case of black */
ctx->internal->execute(ctx, filter_slice_luma, frame, NULL,
FFMIN(frame->height, ctx->graph->nb_threads));
@@ -284,8 +341,6 @@
}
}
- s->frame_index++;
-
return ff_filter_frame(inlink->dst->outputs[0], frame);
}
@@ -315,6 +370,8 @@
OFFSET(duration), AV_OPT_TYPE_DURATION, {.i64 = 0. }, 0, INT32_MAX, FLAGS },
{ "d", "Duration of the effect in seconds.",
OFFSET(duration), AV_OPT_TYPE_DURATION, {.i64 = 0. }, 0, INT32_MAX, FLAGS },
+ { "color", "set color", OFFSET(color_rgba), AV_OPT_TYPE_COLOR, {.str = "black"}, CHAR_MIN, CHAR_MAX, FLAGS },
+ { "c", "set color", OFFSET(color_rgba), AV_OPT_TYPE_COLOR, {.str = "black"}, CHAR_MIN, CHAR_MAX, FLAGS },
{ NULL }
};
@@ -339,7 +396,7 @@
{ NULL }
};
-AVFilter avfilter_vf_fade = {
+AVFilter ff_vf_fade = {
.name = "fade",
.description = NULL_IF_CONFIG_SMALL("Fade in/out input video."),
.init = init,
diff --git a/libavfilter/vf_field.c b/libavfilter/vf_field.c
index 312c866..ed12379 100644
--- a/libavfilter/vf_field.c
+++ b/libavfilter/vf_field.c
@@ -101,7 +101,7 @@
{ NULL }
};
-AVFilter avfilter_vf_field = {
+AVFilter ff_vf_field = {
.name = "field",
.description = NULL_IF_CONFIG_SMALL("Extract a field from the input video."),
.priv_size = sizeof(FieldContext),
diff --git a/libavfilter/vf_fieldmatch.c b/libavfilter/vf_fieldmatch.c
index 89c4909..e2aa60b 100644
--- a/libavfilter/vf_fieldmatch.c
+++ b/libavfilter/vf_fieldmatch.c
@@ -970,7 +970,7 @@
{ NULL }
};
-AVFilter avfilter_vf_fieldmatch = {
+AVFilter ff_vf_fieldmatch = {
.name = "fieldmatch",
.description = NULL_IF_CONFIG_SMALL("Field matching for inverse telecine."),
.query_formats = query_formats,
diff --git a/libavfilter/vf_fieldorder.c b/libavfilter/vf_fieldorder.c
index c44350f..84088a0 100644
--- a/libavfilter/vf_fieldorder.c
+++ b/libavfilter/vf_fieldorder.c
@@ -84,8 +84,13 @@
AVFrame *out;
if (!frame->interlaced_frame ||
- frame->top_field_first == s->dst_tff)
+ frame->top_field_first == s->dst_tff) {
+ av_log(ctx, AV_LOG_VERBOSE,
+ "Skipping %s.\n",
+ frame->interlaced_frame ?
+ "frame with same field order" : "progressive frame");
return ff_filter_frame(outlink, frame);
+ }
if (av_frame_is_writable(frame)) {
out = frame;
@@ -179,7 +184,7 @@
{ NULL }
};
-AVFilter avfilter_vf_fieldorder = {
+AVFilter ff_vf_fieldorder = {
.name = "fieldorder",
.description = NULL_IF_CONFIG_SMALL("Set the field order."),
.priv_size = sizeof(FieldOrderContext),
diff --git a/libavfilter/vf_format.c b/libavfilter/vf_format.c
index 1813a2c..2e9ff27 100644
--- a/libavfilter/vf_format.c
+++ b/libavfilter/vf_format.c
@@ -128,7 +128,7 @@
{ NULL }
};
-AVFilter avfilter_vf_format = {
+AVFilter ff_vf_format = {
.name = "format",
.description = NULL_IF_CONFIG_SMALL("Convert the input video to one of the specified pixel formats."),
.init = init,
@@ -167,7 +167,7 @@
{ NULL }
};
-AVFilter avfilter_vf_noformat = {
+AVFilter ff_vf_noformat = {
.name = "noformat",
.description = NULL_IF_CONFIG_SMALL("Force libavfilter not to use any of the specified pixel formats for the input to the next filter."),
.init = init,
diff --git a/libavfilter/vf_fps.c b/libavfilter/vf_fps.c
index f523088..e6266cc 100644
--- a/libavfilter/vf_fps.c
+++ b/libavfilter/vf_fps.c
@@ -26,6 +26,7 @@
*/
#include <float.h>
+#include <stdint.h>
#include "libavutil/common.h"
#include "libavutil/fifo.h"
@@ -290,7 +291,7 @@
{ NULL }
};
-AVFilter avfilter_vf_fps = {
+AVFilter ff_vf_fps = {
.name = "fps",
.description = NULL_IF_CONFIG_SMALL("Force constant framerate."),
.init = init,
diff --git a/libavfilter/vf_framestep.c b/libavfilter/vf_framestep.c
index 318b5a4..9087f46 100644
--- a/libavfilter/vf_framestep.c
+++ b/libavfilter/vf_framestep.c
@@ -90,7 +90,7 @@
{ NULL }
};
-AVFilter avfilter_vf_framestep = {
+AVFilter ff_vf_framestep = {
.name = "framestep",
.description = NULL_IF_CONFIG_SMALL("Select one frame every N frames."),
.priv_size = sizeof(FrameStepContext),
diff --git a/libavfilter/vf_frei0r.c b/libavfilter/vf_frei0r.c
index 67d25fb..a070eb4 100644
--- a/libavfilter/vf_frei0r.c
+++ b/libavfilter/vf_frei0r.c
@@ -436,7 +436,7 @@
{ NULL }
};
-AVFilter avfilter_vf_frei0r = {
+AVFilter ff_vf_frei0r = {
.name = "frei0r",
.description = NULL_IF_CONFIG_SMALL("Apply a frei0r effect."),
.query_formats = query_formats,
@@ -517,7 +517,7 @@
{ NULL }
};
-AVFilter avfilter_vsrc_frei0r_src = {
+AVFilter ff_vsrc_frei0r_src = {
.name = "frei0r_src",
.description = NULL_IF_CONFIG_SMALL("Generate a frei0r source."),
.priv_size = sizeof(Frei0rContext),
diff --git a/libavfilter/vf_geq.c b/libavfilter/vf_geq.c
index fe53140..49a3e62 100644
--- a/libavfilter/vf_geq.c
+++ b/libavfilter/vf_geq.c
@@ -266,7 +266,7 @@
{ NULL }
};
-AVFilter avfilter_vf_geq = {
+AVFilter ff_vf_geq = {
.name = "geq",
.description = NULL_IF_CONFIG_SMALL("Apply generic equation to each pixel."),
.priv_size = sizeof(GEQContext),
diff --git a/libavfilter/vf_gradfun.c b/libavfilter/vf_gradfun.c
index a436fab..0da9e0b 100644
--- a/libavfilter/vf_gradfun.c
+++ b/libavfilter/vf_gradfun.c
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2010 Nolan Lum <nol888@gmail.com>
- * Copyright (c) 2009 Loren Merritt <lorenm@u.washignton.edu>
+ * Copyright (c) 2009 Loren Merritt <lorenm@u.washington.edu>
*
* This file is part of FFmpeg.
*
@@ -118,6 +118,7 @@
ctx->filter_line(dst + y * dst_linesize, src + y * src_linesize, dc - r / 2, width, thresh, dither[y & 7]);
if (++y >= height) break;
}
+ emms_c();
}
static av_cold int init(AVFilterContext *ctx)
@@ -250,7 +251,7 @@
{ NULL }
};
-AVFilter avfilter_vf_gradfun = {
+AVFilter ff_vf_gradfun = {
.name = "gradfun",
.description = NULL_IF_CONFIG_SMALL("Debands video quickly using gradients."),
.priv_size = sizeof(GradFunContext),
diff --git a/libavfilter/vf_hflip.c b/libavfilter/vf_hflip.c
index 561879f..19b6606 100644
--- a/libavfilter/vf_hflip.c
+++ b/libavfilter/vf_hflip.c
@@ -190,7 +190,7 @@
{ NULL }
};
-AVFilter avfilter_vf_hflip = {
+AVFilter ff_vf_hflip = {
.name = "hflip",
.description = NULL_IF_CONFIG_SMALL("Horizontally flip the input video."),
.priv_size = sizeof(FlipContext),
diff --git a/libavfilter/vf_histeq.c b/libavfilter/vf_histeq.c
index d0a6c77..6fdb7be 100644
--- a/libavfilter/vf_histeq.c
+++ b/libavfilter/vf_histeq.c
@@ -268,7 +268,7 @@
{ NULL }
};
-AVFilter avfilter_vf_histeq = {
+AVFilter ff_vf_histeq = {
.name = "histeq",
.description = NULL_IF_CONFIG_SMALL("Apply global color histogram equalization."),
.priv_size = sizeof(HisteqContext),
diff --git a/libavfilter/vf_histogram.c b/libavfilter/vf_histogram.c
index faa84e8..34656b5 100644
--- a/libavfilter/vf_histogram.c
+++ b/libavfilter/vf_histogram.c
@@ -365,7 +365,7 @@
{ NULL }
};
-AVFilter avfilter_vf_histogram = {
+AVFilter ff_vf_histogram = {
.name = "histogram",
.description = NULL_IF_CONFIG_SMALL("Compute and draw a histogram."),
.priv_size = sizeof(HistogramContext),
diff --git a/libavfilter/vf_hqdn3d.c b/libavfilter/vf_hqdn3d.c
index c188b4f..518a23d 100644
--- a/libavfilter/vf_hqdn3d.c
+++ b/libavfilter/vf_hqdn3d.c
@@ -349,7 +349,7 @@
{ NULL }
};
-AVFilter avfilter_vf_hqdn3d = {
+AVFilter ff_vf_hqdn3d = {
.name = "hqdn3d",
.description = NULL_IF_CONFIG_SMALL("Apply a High Quality 3D Denoiser."),
.priv_size = sizeof(HQDN3DContext),
diff --git a/libavfilter/vf_hue.c b/libavfilter/vf_hue.c
index f3558bf..faa2e8d 100644
--- a/libavfilter/vf_hue.c
+++ b/libavfilter/vf_hue.c
@@ -434,7 +434,7 @@
{ NULL }
};
-AVFilter avfilter_vf_hue = {
+AVFilter ff_vf_hue = {
.name = "hue",
.description = NULL_IF_CONFIG_SMALL("Adjust the hue and saturation of the input video."),
.priv_size = sizeof(HueContext),
diff --git a/libavfilter/vf_idet.c b/libavfilter/vf_idet.c
index 9edfb85..d441a5f 100644
--- a/libavfilter/vf_idet.c
+++ b/libavfilter/vf_idet.c
@@ -295,7 +295,7 @@
{ NULL }
};
-AVFilter avfilter_vf_idet = {
+AVFilter ff_vf_idet = {
.name = "idet",
.description = NULL_IF_CONFIG_SMALL("Interlace detect Filter."),
.priv_size = sizeof(IDETContext),
diff --git a/libavfilter/vf_il.c b/libavfilter/vf_il.c
index 301fff9..e755caa 100644
--- a/libavfilter/vf_il.c
+++ b/libavfilter/vf_il.c
@@ -200,7 +200,7 @@
{ NULL }
};
-AVFilter avfilter_vf_il = {
+AVFilter ff_vf_il = {
.name = "il",
.description = NULL_IF_CONFIG_SMALL("Deinterleave or interleave fields."),
.priv_size = sizeof(IlContext),
diff --git a/libavfilter/vf_interlace.c b/libavfilter/vf_interlace.c
index 7b45595..63fea2b 100644
--- a/libavfilter/vf_interlace.c
+++ b/libavfilter/vf_interlace.c
@@ -184,6 +184,8 @@
av_log(ctx, AV_LOG_WARNING,
"video is already interlaced, adjusting framerate only\n");
out = av_frame_clone(s->cur);
+ if (!out)
+ return AVERROR(ENOMEM);
out->pts /= 2; // adjust pts to new framerate
ret = ff_filter_frame(outlink, out);
return ret;
@@ -230,7 +232,7 @@
{ NULL }
};
-AVFilter avfilter_vf_interlace = {
+AVFilter ff_vf_interlace = {
.name = "interlace",
.description = NULL_IF_CONFIG_SMALL("Convert progressive video into interlaced."),
.uninit = uninit,
diff --git a/libavfilter/vf_kerndeint.c b/libavfilter/vf_kerndeint.c
index 5f88950..1f8e091 100644
--- a/libavfilter/vf_kerndeint.c
+++ b/libavfilter/vf_kerndeint.c
@@ -306,7 +306,7 @@
};
-AVFilter avfilter_vf_kerndeint = {
+AVFilter ff_vf_kerndeint = {
.name = "kerndeint",
.description = NULL_IF_CONFIG_SMALL("Apply kernel deinterlacing to the input."),
.priv_size = sizeof(KerndeintContext),
diff --git a/libavfilter/vf_libopencv.c b/libavfilter/vf_libopencv.c
index a22f3d3..2306b09 100644
--- a/libavfilter/vf_libopencv.c
+++ b/libavfilter/vf_libopencv.c
@@ -403,7 +403,7 @@
{ NULL }
};
-AVFilter avfilter_vf_ocv = {
+AVFilter ff_vf_ocv = {
.name = "ocv",
.description = NULL_IF_CONFIG_SMALL("Apply transform using libopencv."),
.priv_size = sizeof(OCVContext),
diff --git a/libavfilter/vf_lut.c b/libavfilter/vf_lut.c
index 8c83282..9f30ae0 100644
--- a/libavfilter/vf_lut.c
+++ b/libavfilter/vf_lut.c
@@ -346,7 +346,7 @@
};
#define DEFINE_LUT_FILTER(name_, description_) \
- AVFilter avfilter_vf_##name_ = { \
+ AVFilter ff_vf_##name_ = { \
.name = #name_, \
.description = NULL_IF_CONFIG_SMALL(description_), \
.priv_size = sizeof(LutContext), \
diff --git a/libavfilter/vf_lut3d.c b/libavfilter/vf_lut3d.c
index cc15f20..79566be 100644
--- a/libavfilter/vf_lut3d.c
+++ b/libavfilter/vf_lut3d.c
@@ -603,7 +603,7 @@
{ NULL }
};
-AVFilter avfilter_vf_lut3d = {
+AVFilter ff_vf_lut3d = {
.name = "lut3d",
.description = NULL_IF_CONFIG_SMALL("Adjust colors using a 3D LUT."),
.priv_size = sizeof(LUT3DContext),
@@ -781,7 +781,7 @@
{ NULL }
};
-AVFilter avfilter_vf_haldclut = {
+AVFilter ff_vf_haldclut = {
.name = "haldclut",
.description = NULL_IF_CONFIG_SMALL("Adjust colors using a Hald CLUT."),
.priv_size = sizeof(LUT3DContext),
diff --git a/libavfilter/vf_mcdeint.c b/libavfilter/vf_mcdeint.c
index 4bd11a0..2aa2e27 100644
--- a/libavfilter/vf_mcdeint.c
+++ b/libavfilter/vf_mcdeint.c
@@ -303,7 +303,7 @@
{ NULL }
};
-AVFilter avfilter_vf_mcdeint = {
+AVFilter ff_vf_mcdeint = {
.name = "mcdeint",
.description = NULL_IF_CONFIG_SMALL("Apply motion compensating deinterlacing."),
.priv_size = sizeof(MCDeintContext),
diff --git a/libavfilter/vf_mergeplanes.c b/libavfilter/vf_mergeplanes.c
new file mode 100644
index 0000000..4a81412
--- /dev/null
+++ b/libavfilter/vf_mergeplanes.c
@@ -0,0 +1,313 @@
+/*
+ * Copyright (c) 2013 Paul B Mahol
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "libavutil/avassert.h"
+#include "libavutil/avstring.h"
+#include "libavutil/imgutils.h"
+#include "libavutil/opt.h"
+#include "libavutil/pixdesc.h"
+#include "avfilter.h"
+#include "internal.h"
+#include "framesync.h"
+
+typedef struct InputParam {
+ int depth[4];
+ int nb_planes;
+ int planewidth[4];
+ int planeheight[4];
+} InputParam;
+
+typedef struct MergePlanesContext {
+ const AVClass *class;
+ int64_t mapping;
+ const enum AVPixelFormat out_fmt;
+ int nb_inputs;
+ int nb_planes;
+ int planewidth[4];
+ int planeheight[4];
+ int map[4][2];
+ const AVPixFmtDescriptor *outdesc;
+
+ FFFrameSync fs;
+ FFFrameSyncIn fsin[3]; /* must be immediately after fs */
+} MergePlanesContext;
+
+#define OFFSET(x) offsetof(MergePlanesContext, x)
+#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
+static const AVOption mergeplanes_options[] = {
+ { "mapping", "set input to output plane mapping", OFFSET(mapping), AV_OPT_TYPE_INT, {.i64=0}, 0, 0x33333333, FLAGS },
+ { "format", "set output pixel format", OFFSET(out_fmt), AV_OPT_TYPE_PIXEL_FMT, {.i64=AV_PIX_FMT_YUVA444P}, 0, AV_PIX_FMT_NB-1, .flags=FLAGS },
+ { NULL }
+};
+
+AVFILTER_DEFINE_CLASS(mergeplanes);
+
+static int filter_frame(AVFilterLink *inlink, AVFrame *in)
+{
+ MergePlanesContext *s = inlink->dst->priv;
+ return ff_framesync_filter_frame(&s->fs, inlink, in);
+}
+
+static av_cold int init(AVFilterContext *ctx)
+{
+ MergePlanesContext *s = ctx->priv;
+ int64_t m = s->mapping;
+ int i, ret;
+
+ s->outdesc = av_pix_fmt_desc_get(s->out_fmt);
+ if (!(s->outdesc->flags & AV_PIX_FMT_FLAG_PLANAR) ||
+ s->outdesc->nb_components < 2) {
+ av_log(ctx, AV_LOG_ERROR, "Only planar formats with more than one component are supported.\n");
+ return AVERROR(EINVAL);
+ }
+ s->nb_planes = av_pix_fmt_count_planes(s->out_fmt);
+
+ for (i = s->nb_planes - 1; i >= 0; i--) {
+ s->map[i][0] = m & 0xf;
+ m >>= 4;
+ s->map[i][1] = m & 0xf;
+ m >>= 4;
+
+ if (s->map[i][0] > 3 || s->map[i][1] > 3) {
+ av_log(ctx, AV_LOG_ERROR, "Mapping with out of range input and/or plane number.\n");
+ return AVERROR(EINVAL);
+ }
+
+ s->nb_inputs = FFMAX(s->nb_inputs, s->map[i][1] + 1);
+ }
+
+ av_assert0(s->nb_inputs && s->nb_inputs <= 4);
+
+ for (i = 0; i < s->nb_inputs; i++) {
+ AVFilterPad pad = { 0 };
+
+ pad.type = AVMEDIA_TYPE_VIDEO;
+ pad.name = av_asprintf("in%d", i);
+ if (!pad.name)
+ return AVERROR(ENOMEM);
+ pad.filter_frame = filter_frame;
+
+ if ((ret = ff_insert_inpad(ctx, i, &pad)) < 0){
+ av_freep(&pad.name);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static int query_formats(AVFilterContext *ctx)
+{
+ MergePlanesContext *s = ctx->priv;
+ AVFilterFormats *formats = NULL;
+ int i;
+
+ s->outdesc = av_pix_fmt_desc_get(s->out_fmt);
+ for (i = 0; i < AV_PIX_FMT_NB; i++) {
+ const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(i);
+ if (desc->comp[0].depth_minus1 == s->outdesc->comp[0].depth_minus1 &&
+ av_pix_fmt_count_planes(i) == desc->nb_components)
+ ff_add_format(&formats, i);
+ }
+
+ for (i = 0; i < s->nb_inputs; i++)
+ ff_formats_ref(formats, &ctx->inputs[i]->out_formats);
+
+ formats = NULL;
+ ff_add_format(&formats, s->out_fmt);
+ ff_formats_ref(formats, &ctx->outputs[0]->in_formats);
+
+ return 0;
+}
+
+static int process_frame(FFFrameSync *fs)
+{
+ AVFilterContext *ctx = fs->parent;
+ AVFilterLink *outlink = ctx->outputs[0];
+ MergePlanesContext *s = fs->opaque;
+ AVFrame *in[4] = { NULL };
+ AVFrame *out;
+ int i, ret;
+
+ for (i = 0; i < s->nb_inputs; i++) {
+ if ((ret = ff_framesync_get_frame(&s->fs, i, &in[i], 0)) < 0)
+ return ret;
+ }
+
+ out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
+ if (!out)
+ return AVERROR(ENOMEM);
+ out->pts = av_rescale_q(s->fs.pts, s->fs.time_base, outlink->time_base);
+
+ for (i = 0; i < s->nb_planes; i++) {
+ const int input = s->map[i][1];
+ const int plane = s->map[i][0];
+
+ av_image_copy_plane(out->data[i], out->linesize[i],
+ in[input]->data[plane], in[input]->linesize[plane],
+ s->planewidth[i], s->planeheight[i]);
+ }
+
+ return ff_filter_frame(outlink, out);
+}
+
+static int config_output(AVFilterLink *outlink)
+{
+ AVFilterContext *ctx = outlink->src;
+ MergePlanesContext *s = ctx->priv;
+ InputParam inputsp[4];
+ FFFrameSyncIn *in;
+ int i;
+
+ ff_framesync_init(&s->fs, ctx, s->nb_inputs);
+ in = s->fs.in;
+ s->fs.opaque = s;
+ s->fs.on_event = process_frame;
+
+ outlink->w = ctx->inputs[0]->w;
+ outlink->h = ctx->inputs[0]->h;
+ outlink->time_base = ctx->inputs[0]->time_base;
+ outlink->frame_rate = ctx->inputs[0]->frame_rate;
+ outlink->sample_aspect_ratio = ctx->inputs[0]->sample_aspect_ratio;
+
+ s->planewidth[1] =
+ s->planewidth[2] = FF_CEIL_RSHIFT(outlink->w, s->outdesc->log2_chroma_w);
+ s->planewidth[0] =
+ s->planewidth[3] = outlink->w;
+ s->planeheight[1] =
+ s->planeheight[2] = FF_CEIL_RSHIFT(outlink->h, s->outdesc->log2_chroma_h);
+ s->planeheight[0] =
+ s->planeheight[3] = outlink->h;
+
+ for (i = 0; i < s->nb_inputs; i++) {
+ InputParam *inputp = &inputsp[i];
+ AVFilterLink *inlink = ctx->inputs[i];
+ const AVPixFmtDescriptor *indesc = av_pix_fmt_desc_get(inlink->format);
+ int j;
+
+ if (outlink->sample_aspect_ratio.num != inlink->sample_aspect_ratio.num ||
+ outlink->sample_aspect_ratio.den != inlink->sample_aspect_ratio.den) {
+ av_log(ctx, AV_LOG_ERROR, "input #%d link %s SAR %d:%d "
+ "does not match output link %s SAR %d:%d\n",
+ i, ctx->input_pads[i].name,
+ inlink->sample_aspect_ratio.num,
+ inlink->sample_aspect_ratio.den,
+ ctx->output_pads[0].name,
+ outlink->sample_aspect_ratio.num,
+ outlink->sample_aspect_ratio.den);
+ return AVERROR(EINVAL);
+ }
+
+ inputp->planewidth[1] =
+ inputp->planewidth[2] = FF_CEIL_RSHIFT(inlink->w, indesc->log2_chroma_w);
+ inputp->planewidth[0] =
+ inputp->planewidth[3] = inlink->w;
+ inputp->planeheight[1] =
+ inputp->planeheight[2] = FF_CEIL_RSHIFT(inlink->h, indesc->log2_chroma_h);
+ inputp->planeheight[0] =
+ inputp->planeheight[3] = inlink->h;
+ inputp->nb_planes = av_pix_fmt_count_planes(inlink->format);
+
+ for (j = 0; j < inputp->nb_planes; j++)
+ inputp->depth[j] = indesc->comp[j].depth_minus1 + 1;
+
+ in[i].time_base = inlink->time_base;
+ in[i].sync = 1;
+ in[i].before = EXT_STOP;
+ in[i].after = EXT_STOP;
+ }
+
+ for (i = 0; i < s->nb_planes; i++) {
+ const int input = s->map[i][1];
+ const int plane = s->map[i][0];
+ InputParam *inputp = &inputsp[input];
+
+ if (plane + 1 > inputp->nb_planes) {
+ av_log(ctx, AV_LOG_ERROR, "input %d does not have %d plane\n",
+ input, plane);
+ goto fail;
+ }
+ if (s->outdesc->comp[i].depth_minus1 + 1 != inputp->depth[plane]) {
+ av_log(ctx, AV_LOG_ERROR, "output plane %d depth %d does not "
+ "match input %d plane %d depth %d\n",
+ i, s->outdesc->comp[i].depth_minus1 + 1,
+ input, plane, inputp->depth[plane]);
+ goto fail;
+ }
+ if (s->planewidth[i] != inputp->planewidth[plane]) {
+ av_log(ctx, AV_LOG_ERROR, "output plane %d width %d does not "
+ "match input %d plane %d width %d\n",
+ i, s->planewidth[i],
+ input, plane, inputp->planewidth[plane]);
+ goto fail;
+ }
+ if (s->planeheight[i] != inputp->planeheight[plane]) {
+ av_log(ctx, AV_LOG_ERROR, "output plane %d height %d does not "
+ "match input %d plane %d height %d\n",
+ i, s->planeheight[i],
+ input, plane, inputp->planeheight[plane]);
+ goto fail;
+ }
+ }
+
+ return ff_framesync_configure(&s->fs);
+fail:
+ return AVERROR(EINVAL);
+}
+
+static int request_frame(AVFilterLink *outlink)
+{
+ MergePlanesContext *s = outlink->src->priv;
+ return ff_framesync_request_frame(&s->fs, outlink);
+}
+
+static av_cold void uninit(AVFilterContext *ctx)
+{
+ MergePlanesContext *s = ctx->priv;
+ int i;
+
+ ff_framesync_uninit(&s->fs);
+
+ for (i = 0; i < ctx->nb_inputs; i++)
+ av_freep(&ctx->input_pads[i].name);
+}
+
+static const AVFilterPad mergeplanes_outputs[] = {
+ {
+ .name = "default",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .config_props = config_output,
+ .request_frame = request_frame,
+ },
+ { NULL }
+};
+
+AVFilter ff_vf_mergeplanes = {
+ .name = "mergeplanes",
+ .description = NULL_IF_CONFIG_SMALL("Merge planes."),
+ .priv_size = sizeof(MergePlanesContext),
+ .priv_class = &mergeplanes_class,
+ .init = init,
+ .uninit = uninit,
+ .query_formats = query_formats,
+ .inputs = NULL,
+ .outputs = mergeplanes_outputs,
+ .flags = AVFILTER_FLAG_DYNAMIC_INPUTS,
+};
diff --git a/libavfilter/vf_mp.c b/libavfilter/vf_mp.c
index e4968d6..2c145ab 100644
--- a/libavfilter/vf_mp.c
+++ b/libavfilter/vf_mp.c
@@ -111,8 +111,11 @@
{IMGFMT_444P, AV_PIX_FMT_YUVJ444P},
{IMGFMT_440P, AV_PIX_FMT_YUVJ440P},
+#if FF_API_XVMC
{IMGFMT_XVMC_MOCO_MPEG2, AV_PIX_FMT_XVMC_MPEG2_MC},
{IMGFMT_XVMC_IDCT_MPEG2, AV_PIX_FMT_XVMC_MPEG2_IDCT},
+#endif /* FF_API_XVMC */
+
{IMGFMT_VDPAU_MPEG1, AV_PIX_FMT_VDPAU_MPEG1},
{IMGFMT_VDPAU_MPEG2, AV_PIX_FMT_VDPAU_MPEG2},
{IMGFMT_VDPAU_H264, AV_PIX_FMT_VDPAU_H264},
@@ -778,7 +781,7 @@
{ NULL }
};
-AVFilter avfilter_vf_mp = {
+AVFilter ff_vf_mp = {
.name = "mp",
.description = NULL_IF_CONFIG_SMALL("Apply a libmpcodecs filter to the input video."),
.init = init,
diff --git a/libavfilter/vf_mpdecimate.c b/libavfilter/vf_mpdecimate.c
index a29d35d..099622a 100644
--- a/libavfilter/vf_mpdecimate.c
+++ b/libavfilter/vf_mpdecimate.c
@@ -244,7 +244,7 @@
{ NULL }
};
-AVFilter avfilter_vf_mpdecimate = {
+AVFilter ff_vf_mpdecimate = {
.name = "mpdecimate",
.description = NULL_IF_CONFIG_SMALL("Remove near-duplicate frames."),
.init = init,
diff --git a/libavfilter/vf_noise.c b/libavfilter/vf_noise.c
index 8eb3ee1..c29afa2 100644
--- a/libavfilter/vf_noise.c
+++ b/libavfilter/vf_noise.c
@@ -5,17 +5,17 @@
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public
+ * modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
+ * version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
+ * 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 General Public License along
- * with FFmpeg; if not, write to the Free Software
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -474,7 +474,7 @@
{ NULL }
};
-AVFilter avfilter_vf_noise = {
+AVFilter ff_vf_noise = {
.name = "noise",
.description = NULL_IF_CONFIG_SMALL("Add noise."),
.priv_size = sizeof(NoiseContext),
diff --git a/libavfilter/vf_null.c b/libavfilter/vf_null.c
index 17eb28f..2355615 100644
--- a/libavfilter/vf_null.c
+++ b/libavfilter/vf_null.c
@@ -42,7 +42,7 @@
{ NULL }
};
-AVFilter avfilter_vf_null = {
+AVFilter ff_vf_null = {
.name = "null",
.description = NULL_IF_CONFIG_SMALL("Pass the source unchanged to the output."),
.inputs = avfilter_vf_null_inputs,
diff --git a/libavfilter/vf_overlay.c b/libavfilter/vf_overlay.c
index b5ade85..9047dee 100644
--- a/libavfilter/vf_overlay.c
+++ b/libavfilter/vf_overlay.c
@@ -346,8 +346,8 @@
const int dst_w = dst->width;
const int dst_h = dst->height;
- if (x >= dst_w || x+dst_w < 0 ||
- y >= dst_h || y+dst_h < 0)
+ if (x >= dst_w || x+src_w < 0 ||
+ y >= dst_h || y+src_h < 0)
return; /* no intersection */
if (s->main_is_packed_rgb) {
@@ -622,7 +622,7 @@
{ NULL }
};
-AVFilter avfilter_vf_overlay = {
+AVFilter ff_vf_overlay = {
.name = "overlay",
.description = NULL_IF_CONFIG_SMALL("Overlay a video source on top of the input."),
.init = init,
diff --git a/libavfilter/vf_owdenoise.c b/libavfilter/vf_owdenoise.c
index f82982a..95ba43b 100644
--- a/libavfilter/vf_owdenoise.c
+++ b/libavfilter/vf_owdenoise.c
@@ -329,7 +329,7 @@
{ NULL }
};
-AVFilter avfilter_vf_owdenoise = {
+AVFilter ff_vf_owdenoise = {
.name = "owdenoise",
.description = NULL_IF_CONFIG_SMALL("Denoise using wavelets."),
.priv_size = sizeof(OWDenoiseContext),
diff --git a/libavfilter/vf_pad.c b/libavfilter/vf_pad.c
index bb556c9..2962e20 100644
--- a/libavfilter/vf_pad.c
+++ b/libavfilter/vf_pad.c
@@ -251,7 +251,7 @@
(s->y >> vsub) * frame->linesize[planes[i]];
ptrdiff_t req_end = ((s->w - s->x - frame->width) >> hsub) *
s->draw.pixelstep[planes[i]] +
- (s->y >> vsub) * frame->linesize[planes[i]];
+ ((s->h - s->y - frame->height) >> vsub) * frame->linesize[planes[i]];
if (frame->linesize[planes[i]] < (s->w >> hsub) * s->draw.pixelstep[planes[i]])
return 1;
@@ -391,7 +391,7 @@
{ NULL }
};
-AVFilter avfilter_vf_pad = {
+AVFilter ff_vf_pad = {
.name = "pad",
.description = NULL_IF_CONFIG_SMALL("Pad the input video."),
.priv_size = sizeof(PadContext),
diff --git a/libavfilter/vf_perspective.c b/libavfilter/vf_perspective.c
index 3910b97..f433226 100644
--- a/libavfilter/vf_perspective.c
+++ b/libavfilter/vf_perspective.c
@@ -389,7 +389,7 @@
{ NULL }
};
-AVFilter avfilter_vf_perspective = {
+AVFilter ff_vf_perspective = {
.name = "perspective",
.description = NULL_IF_CONFIG_SMALL("Correct the perspective of video."),
.priv_size = sizeof(PerspectiveContext),
diff --git a/libavfilter/vf_phase.c b/libavfilter/vf_phase.c
index bbcef3a..2dcc6fa 100644
--- a/libavfilter/vf_phase.c
+++ b/libavfilter/vf_phase.c
@@ -308,7 +308,7 @@
{ NULL }
};
-AVFilter avfilter_vf_phase = {
+AVFilter ff_vf_phase = {
.name = "phase",
.description = NULL_IF_CONFIG_SMALL("Phase shift fields."),
.priv_size = sizeof(PhaseContext),
diff --git a/libavfilter/vf_pixdesctest.c b/libavfilter/vf_pixdesctest.c
index d250144..54ddf89 100644
--- a/libavfilter/vf_pixdesctest.c
+++ b/libavfilter/vf_pixdesctest.c
@@ -125,7 +125,7 @@
{ NULL }
};
-AVFilter avfilter_vf_pixdesctest = {
+AVFilter ff_vf_pixdesctest = {
.name = "pixdesctest",
.description = NULL_IF_CONFIG_SMALL("Test pixel format definitions."),
.priv_size = sizeof(PixdescTestContext),
diff --git a/libavfilter/vf_pp.c b/libavfilter/vf_pp.c
index eebc232..c72fdc6 100644
--- a/libavfilter/vf_pp.c
+++ b/libavfilter/vf_pp.c
@@ -171,7 +171,7 @@
{ NULL }
};
-AVFilter avfilter_vf_pp = {
+AVFilter ff_vf_pp = {
.name = "pp",
.description = NULL_IF_CONFIG_SMALL("Filter video using libpostproc."),
.priv_size = sizeof(PPFilterContext),
diff --git a/libavfilter/vf_psnr.c b/libavfilter/vf_psnr.c
index 353f535..4915816 100644
--- a/libavfilter/vf_psnr.c
+++ b/libavfilter/vf_psnr.c
@@ -373,7 +373,7 @@
{ NULL }
};
-AVFilter avfilter_vf_psnr = {
+AVFilter ff_vf_psnr = {
.name = "psnr",
.description = NULL_IF_CONFIG_SMALL("Calculate the PSNR between two video streams."),
.init = init,
diff --git a/libavfilter/vf_pullup.c b/libavfilter/vf_pullup.c
index 4ad441f..69e1e91 100644
--- a/libavfilter/vf_pullup.c
+++ b/libavfilter/vf_pullup.c
@@ -756,7 +756,7 @@
{ NULL }
};
-AVFilter avfilter_vf_pullup = {
+AVFilter ff_vf_pullup = {
.name = "pullup",
.description = NULL_IF_CONFIG_SMALL("Pullup from field sequence to frames."),
.priv_size = sizeof(PullupContext),
diff --git a/libavfilter/vf_removelogo.c b/libavfilter/vf_removelogo.c
index b3f2d0a..01a585c 100644
--- a/libavfilter/vf_removelogo.c
+++ b/libavfilter/vf_removelogo.c
@@ -567,7 +567,7 @@
{ NULL }
};
-AVFilter avfilter_vf_removelogo = {
+AVFilter ff_vf_removelogo = {
.name = "removelogo",
.description = NULL_IF_CONFIG_SMALL("Remove a TV logo based on a mask image."),
.priv_size = sizeof(RemovelogoContext),
diff --git a/libavfilter/vf_rotate.c b/libavfilter/vf_rotate.c
index 639100b..e242ee2 100644
--- a/libavfilter/vf_rotate.c
+++ b/libavfilter/vf_rotate.c
@@ -474,7 +474,7 @@
{ NULL }
};
-AVFilter avfilter_vf_rotate = {
+AVFilter ff_vf_rotate = {
.name = "rotate",
.description = NULL_IF_CONFIG_SMALL("Rotate the input image."),
.priv_size = sizeof(RotContext),
diff --git a/libavfilter/vf_sab.c b/libavfilter/vf_sab.c
index 1d970fa..51bbc5a 100644
--- a/libavfilter/vf_sab.c
+++ b/libavfilter/vf_sab.c
@@ -325,7 +325,7 @@
{ NULL }
};
-AVFilter avfilter_vf_sab = {
+AVFilter ff_vf_sab = {
.name = "sab",
.description = NULL_IF_CONFIG_SMALL("Apply shape adaptive blur."),
.priv_size = sizeof(SabContext),
diff --git a/libavfilter/vf_scale.c b/libavfilter/vf_scale.c
index 703b45b..2e692cf 100644
--- a/libavfilter/vf_scale.c
+++ b/libavfilter/vf_scale.c
@@ -51,6 +51,8 @@
"dar",
"hsub",
"vsub",
+ "ohsub",
+ "ovsub",
NULL
};
@@ -64,6 +66,8 @@
VAR_DAR,
VAR_HSUB,
VAR_VSUB,
+ VAR_OHSUB,
+ VAR_OVSUB,
VARS_NB
};
@@ -227,6 +231,7 @@
enum AVPixelFormat outfmt = outlink->format;
ScaleContext *scale = ctx->priv;
const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format);
+ const AVPixFmtDescriptor *out_desc = av_pix_fmt_desc_get(outlink->format);
int64_t w, h;
double var_values[VARS_NB], res;
char *expr;
@@ -242,6 +247,8 @@
var_values[VAR_DAR] = var_values[VAR_A] * var_values[VAR_SAR];
var_values[VAR_HSUB] = 1 << desc->log2_chroma_w;
var_values[VAR_VSUB] = 1 << desc->log2_chroma_h;
+ var_values[VAR_OHSUB] = 1 << out_desc->log2_chroma_w;
+ var_values[VAR_OVSUB] = 1 << out_desc->log2_chroma_h;
/* evaluate width and height */
av_expr_parse_and_eval(&res, (expr = scale->w_expr),
@@ -528,8 +535,8 @@
{ "full", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_JPEG}, 0, 0, FLAGS, "range" },
{ "jpeg", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_JPEG}, 0, 0, FLAGS, "range" },
{ "mpeg", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_MPEG}, 0, 0, FLAGS, "range" },
- { "tv", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_JPEG}, 0, 0, FLAGS, "range" },
- { "pc", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_MPEG}, 0, 0, FLAGS, "range" },
+ { "tv", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_MPEG}, 0, 0, FLAGS, "range" },
+ { "pc", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_JPEG}, 0, 0, FLAGS, "range" },
{ "in_v_chr_pos", "input vertical chroma position in luma grid/256" , OFFSET(in_v_chr_pos), AV_OPT_TYPE_INT, { .i64 = -1}, -1, 512, FLAGS },
{ "in_h_chr_pos", "input horizontal chroma position in luma grid/256", OFFSET(in_h_chr_pos), AV_OPT_TYPE_INT, { .i64 = -1}, -1, 512, FLAGS },
{ "out_v_chr_pos", "output vertical chroma position in luma grid/256" , OFFSET(out_v_chr_pos), AV_OPT_TYPE_INT, { .i64 = -1}, -1, 512, FLAGS },
@@ -567,7 +574,7 @@
{ NULL }
};
-AVFilter avfilter_vf_scale = {
+AVFilter ff_vf_scale = {
.name = "scale",
.description = NULL_IF_CONFIG_SMALL("Scale the input video size and/or convert the image format."),
.init_dict = init_dict,
diff --git a/libavfilter/vf_separatefields.c b/libavfilter/vf_separatefields.c
index 00ecac1..42ce682 100644
--- a/libavfilter/vf_separatefields.c
+++ b/libavfilter/vf_separatefields.c
@@ -137,7 +137,7 @@
{ NULL }
};
-AVFilter avfilter_vf_separatefields = {
+AVFilter ff_vf_separatefields = {
.name = "separatefields",
.description = NULL_IF_CONFIG_SMALL("Split input video frames into fields."),
.priv_size = sizeof(SeparateFieldsContext),
diff --git a/libavfilter/vf_setfield.c b/libavfilter/vf_setfield.c
index 63c80ca..eb4df74 100644
--- a/libavfilter/vf_setfield.c
+++ b/libavfilter/vf_setfield.c
@@ -84,7 +84,7 @@
{ NULL }
};
-AVFilter avfilter_vf_setfield = {
+AVFilter ff_vf_setfield = {
.name = "setfield",
.description = NULL_IF_CONFIG_SMALL("Force field for the output video frame."),
.priv_size = sizeof(SetFieldContext),
diff --git a/libavfilter/vf_showinfo.c b/libavfilter/vf_showinfo.c
index 4741f9f..ade3e1a 100644
--- a/libavfilter/vf_showinfo.c
+++ b/libavfilter/vf_showinfo.c
@@ -92,7 +92,7 @@
{ NULL }
};
-AVFilter avfilter_vf_showinfo = {
+AVFilter ff_vf_showinfo = {
.name = "showinfo",
.description = NULL_IF_CONFIG_SMALL("Show textual information for each video frame."),
.inputs = avfilter_vf_showinfo_inputs,
diff --git a/libavfilter/vf_smartblur.c b/libavfilter/vf_smartblur.c
index c2388a6..114ac6f 100644
--- a/libavfilter/vf_smartblur.c
+++ b/libavfilter/vf_smartblur.c
@@ -290,7 +290,7 @@
{ NULL }
};
-AVFilter avfilter_vf_smartblur = {
+AVFilter ff_vf_smartblur = {
.name = "smartblur",
.description = NULL_IF_CONFIG_SMALL("Blur the input video without impacting the outlines."),
.priv_size = sizeof(SmartblurContext),
diff --git a/libavfilter/vf_spp.c b/libavfilter/vf_spp.c
index aa117e4..683e333 100644
--- a/libavfilter/vf_spp.c
+++ b/libavfilter/vf_spp.c
@@ -422,7 +422,7 @@
{ NULL }
};
-AVFilter avfilter_vf_spp = {
+AVFilter ff_vf_spp = {
.name = "spp",
.description = NULL_IF_CONFIG_SMALL("Apply a simple post processing filter."),
.priv_size = sizeof(SPPContext),
diff --git a/libavfilter/vf_stereo3d.c b/libavfilter/vf_stereo3d.c
index d4f4951..2140120 100644
--- a/libavfilter/vf_stereo3d.c
+++ b/libavfilter/vf_stereo3d.c
@@ -652,7 +652,7 @@
{ NULL }
};
-AVFilter avfilter_vf_stereo3d = {
+AVFilter ff_vf_stereo3d = {
.name = "stereo3d",
.description = NULL_IF_CONFIG_SMALL("Convert video stereoscopic 3D view."),
.priv_size = sizeof(Stereo3DContext),
diff --git a/libavfilter/vf_subtitles.c b/libavfilter/vf_subtitles.c
index b5f5bc9..e44f61d 100644
--- a/libavfilter/vf_subtitles.c
+++ b/libavfilter/vf_subtitles.c
@@ -228,7 +228,7 @@
return 0;
}
-AVFilter avfilter_vf_ass = {
+AVFilter ff_vf_ass = {
.name = "ass",
.description = NULL_IF_CONFIG_SMALL("Render ASS subtitles onto input video using the libass library."),
.priv_size = sizeof(AssContext),
@@ -352,7 +352,7 @@
return ret;
}
-AVFilter avfilter_vf_subtitles = {
+AVFilter ff_vf_subtitles = {
.name = "subtitles",
.description = NULL_IF_CONFIG_SMALL("Render text subtitles onto input video using the libass library."),
.priv_size = sizeof(AssContext),
diff --git a/libavfilter/vf_super2xsai.c b/libavfilter/vf_super2xsai.c
index dde95f9..686dac1 100644
--- a/libavfilter/vf_super2xsai.c
+++ b/libavfilter/vf_super2xsai.c
@@ -342,7 +342,7 @@
{ NULL }
};
-AVFilter avfilter_vf_super2xsai = {
+AVFilter ff_vf_super2xsai = {
.name = "super2xsai",
.description = NULL_IF_CONFIG_SMALL("Scale the input by 2x using the Super2xSaI pixel art algorithm."),
.priv_size = sizeof(Super2xSaIContext),
diff --git a/libavfilter/vf_swapuv.c b/libavfilter/vf_swapuv.c
index 0c8c923..71ae243 100644
--- a/libavfilter/vf_swapuv.c
+++ b/libavfilter/vf_swapuv.c
@@ -101,7 +101,7 @@
{ NULL }
};
-AVFilter avfilter_vf_swapuv = {
+AVFilter ff_vf_swapuv = {
.name = "swapuv",
.description = NULL_IF_CONFIG_SMALL("Swap U and V components."),
.query_formats = query_formats,
diff --git a/libavfilter/vf_telecine.c b/libavfilter/vf_telecine.c
index 2ed0ecf..811ae27 100644
--- a/libavfilter/vf_telecine.c
+++ b/libavfilter/vf_telecine.c
@@ -272,7 +272,7 @@
{ NULL }
};
-AVFilter avfilter_vf_telecine = {
+AVFilter ff_vf_telecine = {
.name = "telecine",
.description = NULL_IF_CONFIG_SMALL("Apply a telecine pattern."),
.priv_size = sizeof(TelecineContext),
diff --git a/libavfilter/vf_thumbnail.c b/libavfilter/vf_thumbnail.c
index d3c60df..1883154 100644
--- a/libavfilter/vf_thumbnail.c
+++ b/libavfilter/vf_thumbnail.c
@@ -226,7 +226,7 @@
{ NULL }
};
-AVFilter avfilter_vf_thumbnail = {
+AVFilter ff_vf_thumbnail = {
.name = "thumbnail",
.description = NULL_IF_CONFIG_SMALL("Select the most representative frame in a given sequence of consecutive frames."),
.priv_size = sizeof(ThumbContext),
diff --git a/libavfilter/vf_tile.c b/libavfilter/vf_tile.c
index decd681..786f4f6 100644
--- a/libavfilter/vf_tile.c
+++ b/libavfilter/vf_tile.c
@@ -233,7 +233,7 @@
{ NULL }
};
-AVFilter avfilter_vf_tile = {
+AVFilter ff_vf_tile = {
.name = "tile",
.description = NULL_IF_CONFIG_SMALL("Tile several successive frames together."),
.init = init,
diff --git a/libavfilter/vf_tinterlace.c b/libavfilter/vf_tinterlace.c
index 538e05c..db82393 100644
--- a/libavfilter/vf_tinterlace.c
+++ b/libavfilter/vf_tinterlace.c
@@ -263,6 +263,8 @@
case MODE_DROP_ODD: /* only output even frames, odd frames are dropped; height unchanged, half framerate */
case MODE_DROP_EVEN: /* only output odd frames, even frames are dropped; height unchanged, half framerate */
out = av_frame_clone(tinterlace->mode == MODE_DROP_EVEN ? cur : next);
+ if (!out)
+ return AVERROR(ENOMEM);
av_frame_free(&tinterlace->next);
break;
@@ -372,7 +374,7 @@
{ NULL }
};
-AVFilter avfilter_vf_tinterlace = {
+AVFilter ff_vf_tinterlace = {
.name = "tinterlace",
.description = NULL_IF_CONFIG_SMALL("Perform temporal field interlacing."),
.priv_size = sizeof(TInterlaceContext),
diff --git a/libavfilter/vf_transpose.c b/libavfilter/vf_transpose.c
index 2690fed..7e471d4 100644
--- a/libavfilter/vf_transpose.c
+++ b/libavfilter/vf_transpose.c
@@ -290,7 +290,7 @@
{ NULL }
};
-AVFilter avfilter_vf_transpose = {
+AVFilter ff_vf_transpose = {
.name = "transpose",
.description = NULL_IF_CONFIG_SMALL("Transpose input video."),
.priv_size = sizeof(TransContext),
diff --git a/libavfilter/vf_unsharp.c b/libavfilter/vf_unsharp.c
index 240290c..b9f6821 100644
--- a/libavfilter/vf_unsharp.c
+++ b/libavfilter/vf_unsharp.c
@@ -298,7 +298,7 @@
{ NULL }
};
-AVFilter avfilter_vf_unsharp = {
+AVFilter ff_vf_unsharp = {
.name = "unsharp",
.description = NULL_IF_CONFIG_SMALL("Sharpen or blur the input video."),
.priv_size = sizeof(UnsharpContext),
diff --git a/libavfilter/vf_vflip.c b/libavfilter/vf_vflip.c
index f636a52..f6908e4 100644
--- a/libavfilter/vf_vflip.c
+++ b/libavfilter/vf_vflip.c
@@ -102,7 +102,7 @@
{ NULL }
};
-AVFilter avfilter_vf_vflip = {
+AVFilter ff_vf_vflip = {
.name = "vflip",
.description = NULL_IF_CONFIG_SMALL("Flip the input video vertically."),
.priv_size = sizeof(FlipContext),
diff --git a/libavfilter/vf_vidstabdetect.c b/libavfilter/vf_vidstabdetect.c
index 99d99ce..b2977ff 100644
--- a/libavfilter/vf_vidstabdetect.c
+++ b/libavfilter/vf_vidstabdetect.c
@@ -202,7 +202,7 @@
{ NULL }
};
-AVFilter avfilter_vf_vidstabdetect = {
+AVFilter ff_vf_vidstabdetect = {
.name = "vidstabdetect",
.description = NULL_IF_CONFIG_SMALL("Extract relative transformations, "
"pass 1 of 2 for stabilization "
diff --git a/libavfilter/vf_vidstabtransform.c b/libavfilter/vf_vidstabtransform.c
index 40c0593..3c0a5ee 100644
--- a/libavfilter/vf_vidstabtransform.c
+++ b/libavfilter/vf_vidstabtransform.c
@@ -276,7 +276,7 @@
{ NULL }
};
-AVFilter avfilter_vf_vidstabtransform = {
+AVFilter ff_vf_vidstabtransform = {
.name = "vidstabtransform",
.description = NULL_IF_CONFIG_SMALL("Transform the frames, "
"pass 2 of 2 for stabilization "
diff --git a/libavfilter/vf_vignette.c b/libavfilter/vf_vignette.c
index b5fed65..8ce7b7e 100644
--- a/libavfilter/vf_vignette.c
+++ b/libavfilter/vf_vignette.c
@@ -325,7 +325,7 @@
{ NULL }
};
-AVFilter avfilter_vf_vignette = {
+AVFilter ff_vf_vignette = {
.name = "vignette",
.description = NULL_IF_CONFIG_SMALL("Make or reverse a vignette effect."),
.priv_size = sizeof(VignetteContext),
diff --git a/libavfilter/vf_w3fdif.c b/libavfilter/vf_w3fdif.c
index bf9b772..3de7394 100644
--- a/libavfilter/vf_w3fdif.c
+++ b/libavfilter/vf_w3fdif.c
@@ -381,7 +381,7 @@
{ NULL }
};
-AVFilter avfilter_vf_w3fdif = {
+AVFilter ff_vf_w3fdif = {
.name = "w3fdif",
.description = NULL_IF_CONFIG_SMALL("Apply Martin Weston three field deinterlace."),
.priv_size = sizeof(W3FDIFContext),
diff --git a/libavfilter/vf_yadif.c b/libavfilter/vf_yadif.c
index 111948b..40383a4 100644
--- a/libavfilter/vf_yadif.c
+++ b/libavfilter/vf_yadif.c
@@ -23,12 +23,15 @@
#include "libavutil/opt.h"
#include "libavutil/pixdesc.h"
#include "libavutil/imgutils.h"
+#include "libavutil/x86/asm.h"
+#include "libavutil/x86/cpu.h"
#include "avfilter.h"
#include "formats.h"
#include "internal.h"
#include "video.h"
#include "yadif.h"
+
typedef struct ThreadData {
AVFrame *frame;
int plane;
@@ -37,13 +40,42 @@
int tff;
} ThreadData;
+typedef struct YADIFContext {
+ const AVClass *class;
+
+ enum YADIFMode mode;
+ enum YADIFParity parity;
+ enum YADIFDeint deint;
+
+ int frame_pending;
+
+ AVFrame *cur;
+ AVFrame *next;
+ AVFrame *prev;
+ AVFrame *out;
+
+ /**
+ * Required alignment for filter_line
+ */
+ void (*filter_line)(void *dst,
+ void *prev, void *cur, void *next,
+ int w, int prefs, int mrefs, int parity, int mode);
+ void (*filter_edges)(void *dst, void *prev, void *cur, void *next,
+ int w, int prefs, int mrefs, int parity, int mode);
+
+ const AVPixFmtDescriptor *csp;
+ int eof;
+ uint8_t *temp_line;
+ int temp_line_size;
+} YADIFContext;
+
#define CHECK(j)\
- { int score = FFABS(cur[mrefs - 1 + (j)] - cur[prefs - 1 - (j)])\
- + FFABS(cur[mrefs +(j)] - cur[prefs -(j)])\
- + FFABS(cur[mrefs + 1 + (j)] - cur[prefs + 1 - (j)]);\
+ { int score = FFABS(cur[mrefs - 1 + j] - cur[prefs - 1 - j])\
+ + FFABS(cur[mrefs + j] - cur[prefs - j])\
+ + FFABS(cur[mrefs + 1 + j] - cur[prefs + 1 - j]);\
if (score < spatial_score) {\
spatial_score= score;\
- spatial_pred= (cur[mrefs +(j)] + cur[prefs -(j)])>>1;\
+ spatial_pred= (cur[mrefs + j] + cur[prefs - j])>>1;\
/* The is_not_edge argument here controls when the code will enter a branch
* which reads up to and including x-3 and x+3. */
@@ -461,6 +493,9 @@
{
AVFilterContext *ctx = link->src;
YADIFContext *s = link->src->priv;
+ int cpu_flags = av_get_cpu_flags();
+ int bit_depth = (!s->csp) ? 8
+ : s->csp->comp[0].depth_minus1 + 1;
link->time_base.num = link->src->inputs[0]->time_base.num;
link->time_base.den = link->src->inputs[0]->time_base.den * 2;
@@ -484,9 +519,38 @@
s->filter_edges = filter_edges;
}
- if (ARCH_X86)
- ff_yadif_init_x86(s);
-
+#if HAVE_YASM
+ if (bit_depth >= 15) {
+ if (EXTERNAL_SSE4(cpu_flags))
+ s->filter_line = ff_yadif_filter_line_16bit_sse4;
+ else if (EXTERNAL_SSSE3(cpu_flags))
+ s->filter_line = ff_yadif_filter_line_16bit_ssse3;
+ else if (EXTERNAL_SSE2(cpu_flags))
+ s->filter_line = ff_yadif_filter_line_16bit_sse2;
+#if ARCH_X86_32
+ else if (EXTERNAL_MMXEXT(cpu_flags))
+ s->filter_line = ff_yadif_filter_line_16bit_mmxext;
+#endif /* ARCH_X86_32 */
+ } else if ( bit_depth >= 9 && bit_depth <= 14) {
+ if (EXTERNAL_SSSE3(cpu_flags))
+ s->filter_line = ff_yadif_filter_line_10bit_ssse3;
+ else if (EXTERNAL_SSE2(cpu_flags))
+ s->filter_line = ff_yadif_filter_line_10bit_sse2;
+#if ARCH_X86_32
+ else if (EXTERNAL_MMXEXT(cpu_flags))
+ s->filter_line = ff_yadif_filter_line_10bit_mmxext;
+#endif /* ARCH_X86_32 */
+ } else {
+ if (EXTERNAL_SSSE3(cpu_flags))
+ s->filter_line = ff_yadif_filter_line_ssse3;
+ else if (EXTERNAL_SSE2(cpu_flags))
+ s->filter_line = ff_yadif_filter_line_sse2;
+#if ARCH_X86_32
+ else if (EXTERNAL_MMXEXT(cpu_flags))
+ s->filter_line = ff_yadif_filter_line_mmxext;
+#endif /* ARCH_X86_32 */
+ }
+#endif /* HAVE_YASM */
return 0;
}
@@ -517,33 +581,26 @@
AVFILTER_DEFINE_CLASS(yadif);
-static const AVFilterPad avfilter_vf_yadif_inputs[] = {
- {
- .name = "default",
- .type = AVMEDIA_TYPE_VIDEO,
- .filter_frame = filter_frame,
- },
- { NULL }
-};
-
-static const AVFilterPad avfilter_vf_yadif_outputs[] = {
- {
- .name = "default",
- .type = AVMEDIA_TYPE_VIDEO,
- .request_frame = request_frame,
- .config_props = config_props,
- },
- { NULL }
-};
-
-AVFilter avfilter_vf_yadif = {
+AVFilter ff_vf_yadif = {
.name = "yadif",
.description = NULL_IF_CONFIG_SMALL("Deinterlace the input image."),
.priv_size = sizeof(YADIFContext),
.priv_class = &yadif_class,
.uninit = uninit,
.query_formats = query_formats,
- .inputs = avfilter_vf_yadif_inputs,
- .outputs = avfilter_vf_yadif_outputs,
+
+ .inputs = (const AVFilterPad[]) {{ .name = "default",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .filter_frame = filter_frame,
+ },
+ { .name = NULL}},
+
+ .outputs = (const AVFilterPad[]) {{ .name = "default",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .request_frame = request_frame,
+ .config_props = config_props,
+ },
+ { .name = NULL}},
+
.flags = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | AVFILTER_FLAG_SLICE_THREADS,
};
diff --git a/libavfilter/vsink_nullsink.c b/libavfilter/vsink_nullsink.c
index d498aab..281721b 100644
--- a/libavfilter/vsink_nullsink.c
+++ b/libavfilter/vsink_nullsink.c
@@ -35,7 +35,7 @@
{ NULL },
};
-AVFilter avfilter_vsink_nullsink = {
+AVFilter ff_vsink_nullsink = {
.name = "nullsink",
.description = NULL_IF_CONFIG_SMALL("Do absolutely nothing with the input video."),
diff --git a/libavfilter/vsrc_cellauto.c b/libavfilter/vsrc_cellauto.c
index e7bc515..95eabc1 100644
--- a/libavfilter/vsrc_cellauto.c
+++ b/libavfilter/vsrc_cellauto.c
@@ -324,7 +324,7 @@
{ NULL }
};
-AVFilter avfilter_vsrc_cellauto = {
+AVFilter ff_vsrc_cellauto = {
.name = "cellauto",
.description = NULL_IF_CONFIG_SMALL("Create pattern generated by an elementary cellular automaton."),
.priv_size = sizeof(CellAutoContext),
diff --git a/libavfilter/vsrc_life.c b/libavfilter/vsrc_life.c
index 85ebc0e..029e1bb 100644
--- a/libavfilter/vsrc_life.c
+++ b/libavfilter/vsrc_life.c
@@ -437,7 +437,7 @@
{ NULL}
};
-AVFilter avfilter_vsrc_life = {
+AVFilter ff_vsrc_life = {
.name = "life",
.description = NULL_IF_CONFIG_SMALL("Create life."),
.priv_size = sizeof(LifeContext),
diff --git a/libavfilter/vsrc_mandelbrot.c b/libavfilter/vsrc_mandelbrot.c
index bd22be3..19dddf9 100644
--- a/libavfilter/vsrc_mandelbrot.c
+++ b/libavfilter/vsrc_mandelbrot.c
@@ -417,7 +417,7 @@
{ NULL }
};
-AVFilter avfilter_vsrc_mandelbrot = {
+AVFilter ff_vsrc_mandelbrot = {
.name = "mandelbrot",
.description = NULL_IF_CONFIG_SMALL("Render a Mandelbrot fractal."),
.priv_size = sizeof(MBContext),
diff --git a/libavfilter/vsrc_mptestsrc.c b/libavfilter/vsrc_mptestsrc.c
index b24b3e7..d045704 100644
--- a/libavfilter/vsrc_mptestsrc.c
+++ b/libavfilter/vsrc_mptestsrc.c
@@ -349,7 +349,7 @@
{ NULL }
};
-AVFilter avfilter_vsrc_mptestsrc = {
+AVFilter ff_vsrc_mptestsrc = {
.name = "mptestsrc",
.description = NULL_IF_CONFIG_SMALL("Generate various test pattern."),
.priv_size = sizeof(MPTestContext),
diff --git a/libavfilter/vsrc_testsrc.c b/libavfilter/vsrc_testsrc.c
index 1e7f8ca..0ad1474 100644
--- a/libavfilter/vsrc_testsrc.c
+++ b/libavfilter/vsrc_testsrc.c
@@ -258,7 +258,7 @@
{ NULL }
};
-AVFilter avfilter_vsrc_color = {
+AVFilter ff_vsrc_color = {
.name = "color",
.description = NULL_IF_CONFIG_SMALL("Provide an uniformly colored input."),
.priv_class = &color_class,
@@ -389,7 +389,7 @@
{ NULL }
};
-AVFilter avfilter_vsrc_haldclutsrc = {
+AVFilter ff_vsrc_haldclutsrc = {
.name = "haldclutsrc",
.description = NULL_IF_CONFIG_SMALL("Provide an identity Hald CLUT."),
.priv_class = &haldclutsrc_class,
@@ -427,7 +427,7 @@
{ NULL },
};
-AVFilter avfilter_vsrc_nullsrc = {
+AVFilter ff_vsrc_nullsrc = {
.name = "nullsrc",
.description = NULL_IF_CONFIG_SMALL("Null video source, return unprocessed video frames."),
.init = nullsrc_init,
@@ -660,7 +660,7 @@
{ NULL }
};
-AVFilter avfilter_vsrc_testsrc = {
+AVFilter ff_vsrc_testsrc = {
.name = "testsrc",
.description = NULL_IF_CONFIG_SMALL("Generate test pattern."),
.priv_size = sizeof(TestSourceContext),
@@ -776,7 +776,7 @@
{ NULL }
};
-AVFilter avfilter_vsrc_rgbtestsrc = {
+AVFilter ff_vsrc_rgbtestsrc = {
.name = "rgbtestsrc",
.description = NULL_IF_CONFIG_SMALL("Generate RGB test pattern."),
.priv_size = sizeof(TestSourceContext),
@@ -950,7 +950,7 @@
return init(ctx);
}
-AVFilter avfilter_vsrc_smptebars = {
+AVFilter ff_vsrc_smptebars = {
.name = "smptebars",
.description = NULL_IF_CONFIG_SMALL("Generate SMPTE color bars."),
.priv_size = sizeof(TestSourceContext),
@@ -1055,7 +1055,7 @@
return init(ctx);
}
-AVFilter avfilter_vsrc_smptehdbars = {
+AVFilter ff_vsrc_smptehdbars = {
.name = "smptehdbars",
.description = NULL_IF_CONFIG_SMALL("Generate SMPTE HD color bars."),
.priv_size = sizeof(TestSourceContext),
diff --git a/libavfilter/x86/Makefile b/libavfilter/x86/Makefile
index b15c562..be4ad83 100644
--- a/libavfilter/x86/Makefile
+++ b/libavfilter/x86/Makefile
@@ -1,10 +1,10 @@
-OBJS-$(CONFIG_GRADFUN_FILTER) += x86/vf_gradfun.o
+OBJS-$(CONFIG_GRADFUN_FILTER) += x86/vf_gradfun_init.o
OBJS-$(CONFIG_HQDN3D_FILTER) += x86/vf_hqdn3d_init.o
OBJS-$(CONFIG_PULLUP_FILTER) += x86/vf_pullup_init.o
OBJS-$(CONFIG_SPP_FILTER) += x86/vf_spp.o
OBJS-$(CONFIG_VOLUME_FILTER) += x86/af_volume_init.o
-OBJS-$(CONFIG_YADIF_FILTER) += x86/vf_yadif_init.o
+YASM-OBJS-$(CONFIG_GRADFUN_FILTER) += x86/vf_gradfun.o
YASM-OBJS-$(CONFIG_HQDN3D_FILTER) += x86/vf_hqdn3d.o
YASM-OBJS-$(CONFIG_PULLUP_FILTER) += x86/vf_pullup.o
YASM-OBJS-$(CONFIG_VOLUME_FILTER) += x86/af_volume.o
diff --git a/libavfilter/x86/vf_gradfun.asm b/libavfilter/x86/vf_gradfun.asm
new file mode 100644
index 0000000..3581f89
--- /dev/null
+++ b/libavfilter/x86/vf_gradfun.asm
@@ -0,0 +1,110 @@
+;******************************************************************************
+;* x86-optimized functions for gradfun filter
+;*
+;* This file is part of FFmpeg.
+;*
+;* FFmpeg is free software; you can redistribute it and/or
+;* modify it under the terms of the GNU Lesser General Public
+;* License as published by the Free Software Foundation; either
+;* version 2.1 of the License, or (at your option) any later version.
+;*
+;* FFmpeg is distributed in the hope that it will be useful,
+;* but WITHOUT ANY WARRANTY; without even the implied warranty of
+;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+;* Lesser General Public License for more details.
+;*
+;* You should have received a copy of the GNU Lesser General Public
+;* License along with FFmpeg; if not, write to the Free Software
+;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+;******************************************************************************
+
+%include "libavutil/x86/x86util.asm"
+
+SECTION_RODATA
+
+pw_7f: times 8 dw 0x7F
+pw_ff: times 8 dw 0xFF
+
+SECTION .text
+
+%macro FILTER_LINE 1
+ movh m0, [r2+r0]
+ movh m1, [r3+r0]
+ punpcklbw m0, m7
+ punpcklwd m1, m1
+ psllw m0, 7
+ psubw m1, m0
+ PABSW m2, m1
+ pmulhuw m2, m5
+ psubw m2, m6
+ pminsw m2, m7
+ pmullw m2, m2
+ psllw m1, 2
+ paddw m0, %1
+ pmulhw m1, m2
+ paddw m0, m1
+ psraw m0, 7
+ packuswb m0, m0
+ movh [r1+r0], m0
+%endmacro
+
+INIT_MMX mmxext
+cglobal gradfun_filter_line, 6, 6
+ movh m5, r4d
+ pxor m7, m7
+ pshufw m5, m5,0
+ mova m6, [pw_7f]
+ mova m3, [r5]
+ mova m4, [r5+8]
+.loop:
+ FILTER_LINE m3
+ add r0, 4
+ jge .end
+ FILTER_LINE m4
+ add r0, 4
+ jl .loop
+.end:
+ REP_RET
+
+INIT_XMM ssse3
+cglobal gradfun_filter_line, 6, 6, 8
+ movd m5, r4d
+ pxor m7, m7
+ pshuflw m5, m5, 0
+ mova m6, [pw_7f]
+ punpcklqdq m5, m5
+ mova m4, [r5]
+.loop:
+ FILTER_LINE m4
+ add r0, 8
+ jl .loop
+ REP_RET
+
+%macro BLUR_LINE 1
+cglobal gradfun_blur_line_%1, 6, 6, 8
+ mova m7, [pw_ff]
+.loop:
+ %1 m0, [r4+r0]
+ %1 m1, [r5+r0]
+ mova m2, m0
+ mova m3, m1
+ psrlw m0, 8
+ psrlw m1, 8
+ pand m2, m7
+ pand m3, m7
+ paddw m0, m1
+ paddw m2, m3
+ paddw m0, m2
+ paddw m0, [r2+r0]
+ mova m1, [r1+r0]
+ mova [r1+r0], m0
+ psubw m0, m1
+ mova [r3+r0], m0
+ add r0, 16
+ jl .loop
+ REP_RET
+%endmacro
+
+INIT_XMM sse2
+BLUR_LINE movdqa
+BLUR_LINE movdqu
diff --git a/libavfilter/x86/vf_gradfun.c b/libavfilter/x86/vf_gradfun.c
deleted file mode 100644
index 10accca..0000000
--- a/libavfilter/x86/vf_gradfun.c
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
- * Copyright (C) 2009 Loren Merritt <lorenm@u.washignton.edu>
- *
- * This file is part of FFmpeg.
- *
- * FFmpeg is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * FFmpeg is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with FFmpeg; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "libavutil/attributes.h"
-#include "libavutil/cpu.h"
-#include "libavutil/mem.h"
-#include "libavutil/x86/asm.h"
-#include "libavfilter/gradfun.h"
-
-#if HAVE_INLINE_ASM
-
-DECLARE_ALIGNED(16, static const uint16_t, pw_7f)[8] = {0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F};
-DECLARE_ALIGNED(16, static const uint16_t, pw_ff)[8] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
-
-#if HAVE_MMXEXT_INLINE
-static void gradfun_filter_line_mmxext(uint8_t *dst, const uint8_t *src, const uint16_t *dc,
- int width, int thresh,
- const uint16_t *dithers)
-{
- intptr_t x;
- if (width & 3) {
- x = width & ~3;
- ff_gradfun_filter_line_c(dst + x, src + x, dc + x / 2, width - x, thresh, dithers);
- width = x;
- }
- x = -width;
- __asm__ volatile(
- "movd %4, %%mm5 \n"
- "pxor %%mm7, %%mm7 \n"
- "pshufw $0, %%mm5, %%mm5 \n"
- "movq %6, %%mm6 \n"
- "movq (%5), %%mm3 \n"
- "movq 8(%5), %%mm4 \n"
-
- "1: \n"
- "movd (%2,%0), %%mm0 \n"
- "movd (%3,%0), %%mm1 \n"
- "punpcklbw %%mm7, %%mm0 \n"
- "punpcklwd %%mm1, %%mm1 \n"
- "psllw $7, %%mm0 \n"
- "pxor %%mm2, %%mm2 \n"
- "psubw %%mm0, %%mm1 \n" // delta = dc - pix
- "psubw %%mm1, %%mm2 \n"
- "pmaxsw %%mm1, %%mm2 \n"
- "pmulhuw %%mm5, %%mm2 \n" // m = abs(delta) * thresh >> 16
- "psubw %%mm6, %%mm2 \n"
- "pminsw %%mm7, %%mm2 \n" // m = -max(0, 127-m)
- "pmullw %%mm2, %%mm2 \n"
- "paddw %%mm3, %%mm0 \n" // pix += dither
- "psllw $2, %%mm1 \n" // m = m*m*delta >> 14
- "pmulhw %%mm2, %%mm1 \n"
- "paddw %%mm1, %%mm0 \n" // pix += m
- "psraw $7, %%mm0 \n"
- "packuswb %%mm0, %%mm0 \n"
- "movd %%mm0, (%1,%0) \n" // dst = clip(pix>>7)
- "add $4, %0 \n"
- "jnl 2f \n"
-
- "movd (%2,%0), %%mm0 \n"
- "movd (%3,%0), %%mm1 \n"
- "punpcklbw %%mm7, %%mm0 \n"
- "punpcklwd %%mm1, %%mm1 \n"
- "psllw $7, %%mm0 \n"
- "pxor %%mm2, %%mm2 \n"
- "psubw %%mm0, %%mm1 \n" // delta = dc - pix
- "psubw %%mm1, %%mm2 \n"
- "pmaxsw %%mm1, %%mm2 \n"
- "pmulhuw %%mm5, %%mm2 \n" // m = abs(delta) * thresh >> 16
- "psubw %%mm6, %%mm2 \n"
- "pminsw %%mm7, %%mm2 \n" // m = -max(0, 127-m)
- "pmullw %%mm2, %%mm2 \n"
- "paddw %%mm4, %%mm0 \n" // pix += dither
- "psllw $2, %%mm1 \n" // m = m*m*delta >> 14
- "pmulhw %%mm2, %%mm1 \n"
- "paddw %%mm1, %%mm0 \n" // pix += m
- "psraw $7, %%mm0 \n"
- "packuswb %%mm0, %%mm0 \n"
- "movd %%mm0, (%1,%0) \n" // dst = clip(pix>>7)
- "add $4, %0 \n"
- "jl 1b \n"
-
- "2: \n"
- "emms \n"
- :"+r"(x)
- :"r"(dst+width), "r"(src+width), "r"(dc+width/2),
- "rm"(thresh), "r"(dithers), "m"(*pw_7f)
- :"memory"
- );
-}
-#endif
-
-#if HAVE_SSSE3_INLINE
-static void gradfun_filter_line_ssse3(uint8_t *dst, const uint8_t *src, const uint16_t *dc, int width, int thresh, const uint16_t *dithers)
-{
- intptr_t x;
- if (width & 7) {
- // could be 10% faster if I somehow eliminated this
- x = width & ~7;
- ff_gradfun_filter_line_c(dst + x, src + x, dc + x / 2, width - x, thresh, dithers);
- width = x;
- }
- x = -width;
- __asm__ volatile(
- "movd %4, %%xmm5 \n"
- "pxor %%xmm7, %%xmm7 \n"
- "pshuflw $0,%%xmm5, %%xmm5 \n"
- "movdqa %6, %%xmm6 \n"
- "punpcklqdq %%xmm5, %%xmm5 \n"
- "movdqa %5, %%xmm4 \n"
- "1: \n"
- "movq (%2,%0), %%xmm0 \n"
- "movq (%3,%0), %%xmm1 \n"
- "punpcklbw %%xmm7, %%xmm0 \n"
- "punpcklwd %%xmm1, %%xmm1 \n"
- "psllw $7, %%xmm0 \n"
- "psubw %%xmm0, %%xmm1 \n" // delta = dc - pix
- "pabsw %%xmm1, %%xmm2 \n"
- "pmulhuw %%xmm5, %%xmm2 \n" // m = abs(delta) * thresh >> 16
- "psubw %%xmm6, %%xmm2 \n"
- "pminsw %%xmm7, %%xmm2 \n" // m = -max(0, 127-m)
- "pmullw %%xmm2, %%xmm2 \n"
- "psllw $2, %%xmm1 \n"
- "paddw %%xmm4, %%xmm0 \n" // pix += dither
- "pmulhw %%xmm2, %%xmm1 \n" // m = m*m*delta >> 14
- "paddw %%xmm1, %%xmm0 \n" // pix += m
- "psraw $7, %%xmm0 \n"
- "packuswb %%xmm0, %%xmm0 \n"
- "movq %%xmm0, (%1,%0) \n" // dst = clip(pix>>7)
- "add $8, %0 \n"
- "jl 1b \n"
- :"+&r"(x)
- :"r"(dst+width), "r"(src+width), "r"(dc+width/2),
- "rm"(thresh), "m"(*dithers), "m"(*pw_7f)
- :"memory"
- );
-}
-#endif /* HAVE_SSSE3_INLINE */
-
-#if HAVE_SSE2_INLINE
-static void gradfun_blur_line_sse2(uint16_t *dc, uint16_t *buf, const uint16_t *buf1, const uint8_t *src, int src_linesize, int width)
-{
-#define BLURV(load)\
- intptr_t x = -2*width;\
- __asm__ volatile(\
- "movdqa %6, %%xmm7 \n"\
- "1: \n"\
- load" (%4,%0), %%xmm0 \n"\
- load" (%5,%0), %%xmm1 \n"\
- "movdqa %%xmm0, %%xmm2 \n"\
- "movdqa %%xmm1, %%xmm3 \n"\
- "psrlw $8, %%xmm0 \n"\
- "psrlw $8, %%xmm1 \n"\
- "pand %%xmm7, %%xmm2 \n"\
- "pand %%xmm7, %%xmm3 \n"\
- "paddw %%xmm1, %%xmm0 \n"\
- "paddw %%xmm3, %%xmm2 \n"\
- "paddw %%xmm2, %%xmm0 \n"\
- "paddw (%2,%0), %%xmm0 \n"\
- "movdqa (%1,%0), %%xmm1 \n"\
- "movdqa %%xmm0, (%1,%0) \n"\
- "psubw %%xmm1, %%xmm0 \n"\
- "movdqa %%xmm0, (%3,%0) \n"\
- "add $16, %0 \n"\
- "jl 1b \n"\
- :"+&r"(x)\
- :"r"(buf+width),\
- "r"(buf1+width),\
- "r"(dc+width),\
- "r"(src+width*2),\
- "r"(src+width*2+src_linesize),\
- "m"(*pw_ff)\
- :"memory"\
- );
- if (((intptr_t) src | src_linesize) & 15) {
- BLURV("movdqu");
- } else {
- BLURV("movdqa");
- }
-}
-#endif /* HAVE_SSE2_INLINE */
-
-#endif /* HAVE_INLINE_ASM */
-
-av_cold void ff_gradfun_init_x86(GradFunContext *gf)
-{
-#if HAVE_MMXEXT_INLINE
- int cpu_flags = av_get_cpu_flags();
-
- if (cpu_flags & AV_CPU_FLAG_MMXEXT)
- gf->filter_line = gradfun_filter_line_mmxext;
-#endif
-#if HAVE_SSSE3_INLINE
- if (cpu_flags & AV_CPU_FLAG_SSSE3)
- gf->filter_line = gradfun_filter_line_ssse3;
-#endif
-#if HAVE_SSE2_INLINE
- if (cpu_flags & AV_CPU_FLAG_SSE2)
- gf->blur_line = gradfun_blur_line_sse2;
-#endif
-}
diff --git a/libavfilter/x86/vf_gradfun_init.c b/libavfilter/x86/vf_gradfun_init.c
new file mode 100644
index 0000000..c638a05
--- /dev/null
+++ b/libavfilter/x86/vf_gradfun_init.c
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2009 Loren Merritt <lorenm@u.washington.edu>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include "libavutil/attributes.h"
+#include "libavutil/cpu.h"
+#include "libavutil/mem.h"
+#include "libavutil/x86/asm.h"
+#include "libavutil/x86/cpu.h"
+#include "libavfilter/gradfun.h"
+
+void ff_gradfun_filter_line_mmxext(intptr_t x, uint8_t *dst, const uint8_t *src,
+ const uint16_t *dc, int thresh,
+ const uint16_t *dithers);
+void ff_gradfun_filter_line_ssse3(intptr_t x, uint8_t *dst, const uint8_t *src,
+ const uint16_t *dc, int thresh,
+ const uint16_t *dithers);
+
+void ff_gradfun_blur_line_movdqa_sse2(intptr_t x, uint16_t *buf,
+ const uint16_t *buf1, uint16_t *dc,
+ const uint8_t *src1, const uint8_t *src2);
+void ff_gradfun_blur_line_movdqu_sse2(intptr_t x, uint16_t *buf,
+ const uint16_t *buf1, uint16_t *dc,
+ const uint8_t *src1, const uint8_t *src2);
+
+#if HAVE_YASM
+static void gradfun_filter_line_mmxext(uint8_t *dst, const uint8_t *src,
+ const uint16_t *dc,
+ int width, int thresh,
+ const uint16_t *dithers)
+{
+ intptr_t x;
+ if (width & 3) {
+ x = width & ~3;
+ ff_gradfun_filter_line_c(dst + x, src + x, dc + x / 2,
+ width - x, thresh, dithers);
+ width = x;
+ }
+ x = -width;
+ ff_gradfun_filter_line_mmxext(x, dst + width, src + width, dc + width / 2,
+ thresh, dithers);
+}
+
+static void gradfun_filter_line_ssse3(uint8_t *dst, const uint8_t *src, const uint16_t *dc,
+ int width, int thresh,
+ const uint16_t *dithers)
+{
+ intptr_t x;
+ if (width & 7) {
+ // could be 10% faster if I somehow eliminated this
+ x = width & ~7;
+ ff_gradfun_filter_line_c(dst + x, src + x, dc + x / 2,
+ width - x, thresh, dithers);
+ width = x;
+ }
+ x = -width;
+ ff_gradfun_filter_line_ssse3(x, dst + width, src + width, dc + width / 2,
+ thresh, dithers);
+}
+
+static void gradfun_blur_line_sse2(uint16_t *dc, uint16_t *buf, const uint16_t *buf1,
+ const uint8_t *src, int src_linesize, int width)
+{
+ intptr_t x = -2 * width;
+ if (((intptr_t) src | src_linesize) & 15)
+ ff_gradfun_blur_line_movdqu_sse2(x, buf + width, buf1 + width,
+ dc + width, src + width * 2,
+ src + width * 2 + src_linesize);
+ else
+ ff_gradfun_blur_line_movdqa_sse2(x, buf + width, buf1 + width,
+ dc + width, src + width * 2,
+ src + width * 2 + src_linesize);
+}
+#endif /* HAVE_YASM */
+
+av_cold void ff_gradfun_init_x86(GradFunContext *gf)
+{
+#if HAVE_YASM
+ int cpu_flags = av_get_cpu_flags();
+
+ if (EXTERNAL_MMXEXT(cpu_flags))
+ gf->filter_line = gradfun_filter_line_mmxext;
+ if (EXTERNAL_SSSE3(cpu_flags))
+ gf->filter_line = gradfun_filter_line_ssse3;
+
+ if (EXTERNAL_SSE2(cpu_flags))
+ gf->blur_line = gradfun_blur_line_sse2;
+#endif /* HAVE_YASM */
+}
diff --git a/libavfilter/x86/vf_hqdn3d_init.c b/libavfilter/x86/vf_hqdn3d_init.c
index 4abb878..b63916b 100644
--- a/libavfilter/x86/vf_hqdn3d_init.c
+++ b/libavfilter/x86/vf_hqdn3d_init.c
@@ -25,17 +25,25 @@
#include "libavfilter/vf_hqdn3d.h"
#include "config.h"
-void ff_hqdn3d_row_8_x86(uint8_t *src, uint8_t *dst, uint16_t *line_ant, uint16_t *frame_ant, ptrdiff_t w, int16_t *spatial, int16_t *temporal);
-void ff_hqdn3d_row_9_x86(uint8_t *src, uint8_t *dst, uint16_t *line_ant, uint16_t *frame_ant, ptrdiff_t w, int16_t *spatial, int16_t *temporal);
-void ff_hqdn3d_row_10_x86(uint8_t *src, uint8_t *dst, uint16_t *line_ant, uint16_t *frame_ant, ptrdiff_t w, int16_t *spatial, int16_t *temporal);
-void ff_hqdn3d_row_16_x86(uint8_t *src, uint8_t *dst, uint16_t *line_ant, uint16_t *frame_ant, ptrdiff_t w, int16_t *spatial, int16_t *temporal);
+void ff_hqdn3d_row_8_x86(uint8_t *src, uint8_t *dst, uint16_t *line_ant,
+ uint16_t *frame_ant, ptrdiff_t w, int16_t *spatial,
+ int16_t *temporal);
+void ff_hqdn3d_row_9_x86(uint8_t *src, uint8_t *dst, uint16_t *line_ant,
+ uint16_t *frame_ant, ptrdiff_t w, int16_t *spatial,
+ int16_t *temporal);
+void ff_hqdn3d_row_10_x86(uint8_t *src, uint8_t *dst, uint16_t *line_ant,
+ uint16_t *frame_ant, ptrdiff_t w, int16_t *spatial,
+ int16_t *temporal);
+void ff_hqdn3d_row_16_x86(uint8_t *src, uint8_t *dst, uint16_t *line_ant,
+ uint16_t *frame_ant, ptrdiff_t w, int16_t *spatial,
+ int16_t *temporal);
av_cold void ff_hqdn3d_init_x86(HQDN3DContext *hqdn3d)
{
#if HAVE_YASM
- hqdn3d->denoise_row[ 8] = ff_hqdn3d_row_8_x86;
- hqdn3d->denoise_row[ 9] = ff_hqdn3d_row_9_x86;
+ hqdn3d->denoise_row[8] = ff_hqdn3d_row_8_x86;
+ hqdn3d->denoise_row[9] = ff_hqdn3d_row_9_x86;
hqdn3d->denoise_row[10] = ff_hqdn3d_row_10_x86;
hqdn3d->denoise_row[16] = ff_hqdn3d_row_16_x86;
-#endif
+#endif /* HAVE_YASM */
}
diff --git a/libavfilter/x86/vf_yadif_init.c b/libavfilter/x86/vf_yadif_init.c
deleted file mode 100644
index ae09bb0..0000000
--- a/libavfilter/x86/vf_yadif_init.c
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (C) 2006 Michael Niedermayer <michaelni@gmx.at>
- *
- * This file is part of FFmpeg.
- *
- * FFmpeg is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * FFmpeg is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with FFmpeg; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include "libavutil/attributes.h"
-#include "libavutil/cpu.h"
-#include "libavutil/mem.h"
-#include "libavutil/x86/asm.h"
-#include "libavutil/x86/cpu.h"
-#include "libavfilter/yadif.h"
-
-void ff_yadif_filter_line_mmxext(void *dst, void *prev, void *cur,
- void *next, int w, int prefs,
- int mrefs, int parity, int mode);
-void ff_yadif_filter_line_sse2(void *dst, void *prev, void *cur,
- void *next, int w, int prefs,
- int mrefs, int parity, int mode);
-void ff_yadif_filter_line_ssse3(void *dst, void *prev, void *cur,
- void *next, int w, int prefs,
- int mrefs, int parity, int mode);
-
-void ff_yadif_filter_line_16bit_mmxext(void *dst, void *prev, void *cur,
- void *next, int w, int prefs,
- int mrefs, int parity, int mode);
-void ff_yadif_filter_line_16bit_sse2(void *dst, void *prev, void *cur,
- void *next, int w, int prefs,
- int mrefs, int parity, int mode);
-void ff_yadif_filter_line_16bit_ssse3(void *dst, void *prev, void *cur,
- void *next, int w, int prefs,
- int mrefs, int parity, int mode);
-void ff_yadif_filter_line_16bit_sse4(void *dst, void *prev, void *cur,
- void *next, int w, int prefs,
- int mrefs, int parity, int mode);
-
-void ff_yadif_filter_line_10bit_mmxext(void *dst, void *prev, void *cur,
- void *next, int w, int prefs,
- int mrefs, int parity, int mode);
-void ff_yadif_filter_line_10bit_sse2(void *dst, void *prev, void *cur,
- void *next, int w, int prefs,
- int mrefs, int parity, int mode);
-void ff_yadif_filter_line_10bit_ssse3(void *dst, void *prev, void *cur,
- void *next, int w, int prefs,
- int mrefs, int parity, int mode);
-
-av_cold void ff_yadif_init_x86(YADIFContext *yadif)
-{
-#if HAVE_YASM
- int cpu_flags = av_get_cpu_flags();
- int bit_depth = (!yadif->csp) ? 8
- : yadif->csp->comp[0].depth_minus1 + 1;
-
- if (bit_depth >= 15) {
-#if ARCH_X86_32
- if (EXTERNAL_MMXEXT(cpu_flags))
- yadif->filter_line = ff_yadif_filter_line_16bit_mmxext;
-#endif /* ARCH_X86_32 */
- if (EXTERNAL_SSE2(cpu_flags))
- yadif->filter_line = ff_yadif_filter_line_16bit_sse2;
- if (EXTERNAL_SSSE3(cpu_flags))
- yadif->filter_line = ff_yadif_filter_line_16bit_ssse3;
- if (EXTERNAL_SSE4(cpu_flags))
- yadif->filter_line = ff_yadif_filter_line_16bit_sse4;
- } else if ( bit_depth >= 9 && bit_depth <= 14) {
-#if ARCH_X86_32
- if (EXTERNAL_MMXEXT(cpu_flags))
- yadif->filter_line = ff_yadif_filter_line_10bit_mmxext;
-#endif /* ARCH_X86_32 */
- if (EXTERNAL_SSE2(cpu_flags))
- yadif->filter_line = ff_yadif_filter_line_10bit_sse2;
- if (EXTERNAL_SSSE3(cpu_flags))
- yadif->filter_line = ff_yadif_filter_line_10bit_ssse3;
- } else {
-#if ARCH_X86_32
- if (EXTERNAL_MMXEXT(cpu_flags))
- yadif->filter_line = ff_yadif_filter_line_mmxext;
-#endif /* ARCH_X86_32 */
- if (EXTERNAL_SSE2(cpu_flags))
- yadif->filter_line = ff_yadif_filter_line_sse2;
- if (EXTERNAL_SSSE3(cpu_flags))
- yadif->filter_line = ff_yadif_filter_line_ssse3;
- }
-#endif /* HAVE_YASM */
-}
diff --git a/libavfilter/yadif.h b/libavfilter/yadif.h
index 3ddf005..5afe014 100644
--- a/libavfilter/yadif.h
+++ b/libavfilter/yadif.h
@@ -19,7 +19,6 @@
#ifndef AVFILTER_YADIF_H
#define AVFILTER_YADIF_H
-#include "libavutil/pixdesc.h"
#include "avfilter.h"
enum YADIFMode {
@@ -40,35 +39,37 @@
YADIF_DEINT_INTERLACED = 1, ///< only deinterlace frames marked as interlaced
};
-typedef struct YADIFContext {
- const AVClass *class;
+void ff_yadif_filter_line_mmxext(void *dst, void *prev, void *cur,
+ void *next, int w, int prefs,
+ int mrefs, int parity, int mode);
+void ff_yadif_filter_line_sse2(void *dst, void *prev, void *cur,
+ void *next, int w, int prefs,
+ int mrefs, int parity, int mode);
+void ff_yadif_filter_line_ssse3(void *dst, void *prev, void *cur,
+ void *next, int w, int prefs,
+ int mrefs, int parity, int mode);
- enum YADIFMode mode;
- enum YADIFParity parity;
- enum YADIFDeint deint;
+void ff_yadif_filter_line_16bit_mmxext(void *dst, void *prev, void *cur,
+ void *next, int w, int prefs,
+ int mrefs, int parity, int mode);
+void ff_yadif_filter_line_16bit_sse2(void *dst, void *prev, void *cur,
+ void *next, int w, int prefs,
+ int mrefs, int parity, int mode);
+void ff_yadif_filter_line_16bit_ssse3(void *dst, void *prev, void *cur,
+ void *next, int w, int prefs,
+ int mrefs, int parity, int mode);
+void ff_yadif_filter_line_16bit_sse4(void *dst, void *prev, void *cur,
+ void *next, int w, int prefs,
+ int mrefs, int parity, int mode);
- int frame_pending;
-
- AVFrame *cur;
- AVFrame *next;
- AVFrame *prev;
- AVFrame *out;
-
- /**
- * Required alignment for filter_line
- */
- void (*filter_line)(void *dst,
- void *prev, void *cur, void *next,
- int w, int prefs, int mrefs, int parity, int mode);
- void (*filter_edges)(void *dst, void *prev, void *cur, void *next,
- int w, int prefs, int mrefs, int parity, int mode);
-
- const AVPixFmtDescriptor *csp;
- int eof;
- uint8_t *temp_line;
- int temp_line_size;
-} YADIFContext;
-
-void ff_yadif_init_x86(YADIFContext *yadif);
+void ff_yadif_filter_line_10bit_mmxext(void *dst, void *prev, void *cur,
+ void *next, int w, int prefs,
+ int mrefs, int parity, int mode);
+void ff_yadif_filter_line_10bit_sse2(void *dst, void *prev, void *cur,
+ void *next, int w, int prefs,
+ int mrefs, int parity, int mode);
+void ff_yadif_filter_line_10bit_ssse3(void *dst, void *prev, void *cur,
+ void *next, int w, int prefs,
+ int mrefs, int parity, int mode);
#endif /* AVFILTER_YADIF_H */
diff --git a/libavformat/Makefile b/libavformat/Makefile
index 9d4b626..cf3352b 100644
--- a/libavformat/Makefile
+++ b/libavformat/Makefile
@@ -24,8 +24,6 @@
url.o \
utils.o \
-OBJS-$(HAVE_MSVCRT) += file_open.o
-
OBJS-$(CONFIG_NETWORK) += network.o
OBJS-$(CONFIG_RIFFDEC) += riffdec.o
OBJS-$(CONFIG_RIFFENC) += riffenc.o
@@ -64,7 +62,7 @@
OBJS-$(CONFIG_ADP_DEMUXER) += adp.o
OBJS-$(CONFIG_ADX_DEMUXER) += adxdec.o
OBJS-$(CONFIG_ADX_MUXER) += rawenc.o
-OBJS-$(CONFIG_ADTS_MUXER) += adtsenc.o
+OBJS-$(CONFIG_ADTS_MUXER) += adtsenc.o apetag.o
OBJS-$(CONFIG_AEA_DEMUXER) += aea.o pcm.o
OBJS-$(CONFIG_AFC_DEMUXER) += afc.o
OBJS-$(CONFIG_AIFF_DEMUXER) += aiffdec.o pcm.o isom.o \
@@ -166,9 +164,11 @@
OBJS-$(CONFIG_H263_MUXER) += rawenc.o
OBJS-$(CONFIG_H264_DEMUXER) += h264dec.o rawdec.o
OBJS-$(CONFIG_H264_MUXER) += rawenc.o
+OBJS-$(CONFIG_HDS_MUXER) += hdsenc.o
OBJS-$(CONFIG_HEVC_DEMUXER) += hevcdec.o rawdec.o
OBJS-$(CONFIG_HLS_DEMUXER) += hls.o
OBJS-$(CONFIG_HLS_MUXER) += hlsenc.o
+OBJS-$(CONFIG_HNM_DEMUXER) += hnm.o
OBJS-$(CONFIG_ICO_DEMUXER) += icodec.o
OBJS-$(CONFIG_ICO_MUXER) += icoenc.o
OBJS-$(CONFIG_IDCIN_DEMUXER) += idcin.o
@@ -267,6 +267,8 @@
vorbiscomment.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_OPUS_MUXER) += oggenc.o \
+ vorbiscomment.o
OBJS-$(CONFIG_PAF_DEMUXER) += paf.o
OBJS-$(CONFIG_PCM_ALAW_DEMUXER) += pcmdec.o pcm.o
OBJS-$(CONFIG_PCM_ALAW_MUXER) += pcmenc.o rawenc.o
@@ -363,6 +365,8 @@
OBJS-$(CONFIG_SOX_MUXER) += soxenc.o rawenc.o
OBJS-$(CONFIG_SPDIF_DEMUXER) += spdif.o spdifdec.o
OBJS-$(CONFIG_SPDIF_MUXER) += spdif.o spdifenc.o
+OBJS-$(CONFIG_SPEEX_MUXER) += oggenc.o \
+ vorbiscomment.o
OBJS-$(CONFIG_SRT_DEMUXER) += srtdec.o subtitles.o
OBJS-$(CONFIG_SRT_MUXER) += srtenc.o
OBJS-$(CONFIG_STR_DEMUXER) += psxstr.o
@@ -405,9 +409,9 @@
OBJS-$(CONFIG_WEBVTT_MUXER) += webvttenc.o
OBJS-$(CONFIG_WSAUD_DEMUXER) += westwood_aud.o
OBJS-$(CONFIG_WSVQA_DEMUXER) += westwood_vqa.o
-OBJS-$(CONFIG_WTV_DEMUXER) += wtvdec.o wtv.o asfdec.o asf.o asfcrypt.o \
+OBJS-$(CONFIG_WTV_DEMUXER) += wtvdec.o wtv_common.o asfdec.o asf.o asfcrypt.o \
avlanguage.o mpegts.o isom.o
-OBJS-$(CONFIG_WTV_MUXER) += wtvenc.o wtv.o asf.o asfenc.o
+OBJS-$(CONFIG_WTV_MUXER) += wtvenc.o wtv_common.o asf.o asfenc.o
OBJS-$(CONFIG_WV_DEMUXER) += wvdec.o wv.o apetag.o img2.o
OBJS-$(CONFIG_WV_MUXER) += wvenc.o wv.o apetag.o img2.o
OBJS-$(CONFIG_XA_DEMUXER) += xa.o
@@ -461,6 +465,11 @@
OBJS-$(CONFIG_UDP_PROTOCOL) += udp.o
OBJS-$(CONFIG_UNIX_PROTOCOL) += unix.o
+OBJS-$(HAVE_LIBC_MSVCRT) += file_open.o
+
+# Windows resource file
+SLIBOBJS-$(HAVE_GNU_WINDRES) += avformatres.o
+
SKIPHEADERS-$(CONFIG_FFRTMPCRYPT_PROTOCOL) += rtmpdh.h
SKIPHEADERS-$(CONFIG_NETWORK) += network.h rtsp.h
TESTPROGS = seek \
diff --git a/libavformat/adp.c b/libavformat/adp.c
index c5feac4..08a4225 100644
--- a/libavformat/adp.c
+++ b/libavformat/adp.c
@@ -26,14 +26,21 @@
static int adp_probe(AVProbeData *p)
{
- int i;
+ int i, changes = 0;
+ char last = 0;
if (p->buf_size < 32)
return 0;
- for (i = 0; i < p->buf_size - 3; i+=32)
+ for (i = 0; i < p->buf_size - 3; i+=32) {
if (p->buf[i] != p->buf[i+2] || p->buf[i+1] != p->buf[i+3])
return 0;
+ if (p->buf[i] != last)
+ changes++;
+ last = p->buf[i];
+ }
+ if (changes <= 1)
+ return 0;
return p->buf_size < 260 ? 1 : AVPROBE_SCORE_MAX / 4;
}
diff --git a/libavformat/adtsenc.c b/libavformat/adtsenc.c
index 60d7b07..f25f966 100644
--- a/libavformat/adtsenc.c
+++ b/libavformat/adtsenc.c
@@ -24,16 +24,20 @@
#include "libavcodec/put_bits.h"
#include "libavcodec/avcodec.h"
#include "libavcodec/mpeg4audio.h"
+#include "libavutil/opt.h"
#include "avformat.h"
+#include "apetag.h"
#define ADTS_HEADER_SIZE 7
typedef struct {
+ AVClass *class;
int write_adts;
int objecttype;
int sample_rate_index;
int channel_conf;
int pce_size;
+ int apetag;
uint8_t pce_data[MAX_PCE_SIZE];
} ADTSContext;
@@ -162,6 +166,30 @@
return 0;
}
+static int adts_write_trailer(AVFormatContext *s)
+{
+ ADTSContext *adts = s->priv_data;
+
+ if (adts->apetag)
+ ff_ape_write_tag(s);
+
+ return 0;
+}
+
+#define ENC AV_OPT_FLAG_ENCODING_PARAM
+#define OFFSET(obj) offsetof(ADTSContext, obj)
+static const AVOption options[] = {
+ { "write_apetag", "Enable APE tag writing", OFFSET(apetag), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, ENC},
+ { NULL },
+};
+
+static const AVClass adts_muxer_class = {
+ .class_name = "ADTS muxer",
+ .item_name = av_default_item_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
AVOutputFormat ff_adts_muxer = {
.name = "adts",
.long_name = NULL_IF_CONFIG_SMALL("ADTS AAC (Advanced Audio Coding)"),
@@ -172,4 +200,6 @@
.video_codec = AV_CODEC_ID_NONE,
.write_header = adts_write_header,
.write_packet = adts_write_packet,
+ .write_trailer = adts_write_trailer,
+ .priv_class = &adts_muxer_class,
};
diff --git a/libavformat/aiff.h b/libavformat/aiff.h
index c13bcc0..4470254 100644
--- a/libavformat/aiff.h
+++ b/libavformat/aiff.h
@@ -46,7 +46,7 @@
{ AV_CODEC_ID_MACE6, MKTAG('M','A','C','6') },
{ AV_CODEC_ID_GSM, MKTAG('G','S','M',' ') },
{ AV_CODEC_ID_ADPCM_G722, MKTAG('G','7','2','2') },
- { AV_CODEC_ID_ADPCM_G726, MKTAG('G','7','2','6') },
+ { AV_CODEC_ID_ADPCM_G726LE, MKTAG('G','7','2','6') },
{ AV_CODEC_ID_PCM_S16BE, MKTAG('t','w','o','s') },
{ AV_CODEC_ID_PCM_S16LE, MKTAG('s','o','w','t') },
{ AV_CODEC_ID_ADPCM_IMA_QT, MKTAG('i','m','a','4') },
diff --git a/libavformat/aiffdec.c b/libavformat/aiffdec.c
index 2883713..6f82d93 100644
--- a/libavformat/aiffdec.c
+++ b/libavformat/aiffdec.c
@@ -141,6 +141,8 @@
case AV_CODEC_ID_MACE3:
codec->block_align = 2*codec->channels;
break;
+ case AV_CODEC_ID_ADPCM_G726LE:
+ codec->bits_per_coded_sample = 5;
case AV_CODEC_ID_ADPCM_G722:
case AV_CODEC_ID_MACE6:
codec->block_align = 1*codec->channels;
diff --git a/libavformat/aiffenc.c b/libavformat/aiffenc.c
index 7c0b4fb..6e3d8bc 100644
--- a/libavformat/aiffenc.c
+++ b/libavformat/aiffenc.c
@@ -19,6 +19,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <stdint.h>
+
#include "libavutil/intfloat.h"
#include "libavutil/opt.h"
#include "avformat.h"
diff --git a/libavformat/allformats.c b/libavformat/allformats.c
index 0e1b262..f1039dd 100644
--- a/libavformat/allformats.c
+++ b/libavformat/allformats.c
@@ -45,8 +45,7 @@
{ \
extern URLProtocol ff_##x##_protocol; \
if (CONFIG_##X##_PROTOCOL) \
- ffurl_register_protocol(&ff_##x##_protocol, \
- sizeof(ff_##x##_protocol)); \
+ ffurl_register_protocol(&ff_##x##_protocol); \
}
void av_register_all(void)
@@ -135,8 +134,10 @@
REGISTER_MUXDEMUX(H261, h261);
REGISTER_MUXDEMUX(H263, h263);
REGISTER_MUXDEMUX(H264, h264);
+ REGISTER_MUXER (HDS, hds);
REGISTER_DEMUXER (HEVC, hevc);
REGISTER_MUXDEMUX(HLS, hls);
+ REGISTER_DEMUXER (HNM, hnm);
REGISTER_MUXDEMUX(ICO, ico);
REGISTER_DEMUXER (IDCIN, idcin);
REGISTER_DEMUXER (IDF, idf);
@@ -204,6 +205,7 @@
REGISTER_DEMUXER (NUV, nuv);
REGISTER_MUXDEMUX(OGG, ogg);
REGISTER_MUXDEMUX(OMA, oma);
+ REGISTER_MUXER (OPUS, opus);
REGISTER_DEMUXER (PAF, paf);
REGISTER_MUXDEMUX(PCM_ALAW, pcm_alaw);
REGISTER_MUXDEMUX(PCM_MULAW, pcm_mulaw);
@@ -248,8 +250,8 @@
REGISTER_DEMUXER (SBG, sbg);
REGISTER_DEMUXER (SDP, sdp);
#if CONFIG_RTPDEC
- av_register_rtp_dynamic_payload_handlers();
- av_register_rdt_dynamic_payload_handlers();
+ ff_register_rtp_dynamic_payload_handlers();
+ ff_register_rdt_dynamic_payload_handlers();
#endif
REGISTER_DEMUXER (SEGAFILM, segafilm);
REGISTER_MUXER (SEGMENT, segment);
@@ -263,6 +265,7 @@
REGISTER_DEMUXER (SOL, sol);
REGISTER_MUXDEMUX(SOX, sox);
REGISTER_MUXDEMUX(SPDIF, spdif);
+ REGISTER_MUXER (SPEEX, speex);
REGISTER_MUXDEMUX(SRT, srt);
REGISTER_DEMUXER (STR, str);
REGISTER_DEMUXER (SUBVIEWER1, subviewer1);
diff --git a/libavformat/ape.c b/libavformat/ape.c
index 613a59d..6f82480 100644
--- a/libavformat/ape.c
+++ b/libavformat/ape.c
@@ -86,10 +86,14 @@
static int ape_probe(AVProbeData * p)
{
- if (p->buf[0] == 'M' && p->buf[1] == 'A' && p->buf[2] == 'C' && p->buf[3] == ' ')
- return AVPROBE_SCORE_MAX;
+ int version = AV_RL16(p->buf+4);
+ if (AV_RL32(p->buf) != MKTAG('M', 'A', 'C', ' '))
+ return 0;
- return 0;
+ if (version < APE_MIN_VERSION || version > APE_MAX_VERSION)
+ return AVPROBE_SCORE_MAX/4;
+
+ return AVPROBE_SCORE_MAX;
}
static void ape_dumpinfo(AVFormatContext * s, APEContext * ape_ctx)
diff --git a/libavformat/asfdec.c b/libavformat/asfdec.c
index 528bcbd..a9b0326 100644
--- a/libavformat/asfdec.c
+++ b/libavformat/asfdec.c
@@ -1122,8 +1122,7 @@
if (url_feof(pb))
return AVERROR_EOF;
- if (asf->packet_size_left < FRAME_HEADER_SIZE ||
- asf->packet_segments < 1) {
+ if (asf->packet_size_left < FRAME_HEADER_SIZE) {
int ret = asf->packet_size_left + asf->packet_padsize;
assert(ret >= 0);
@@ -1138,7 +1137,7 @@
}
if (asf->packet_time_start == 0) {
if (asf_read_frame_header(s, pb) < 0) {
- asf->packet_segments = 0;
+ asf->packet_time_start = asf->packet_segments = 0;
continue;
}
if (asf->stream_index < 0 ||
@@ -1349,7 +1348,6 @@
int i;
asf->packet_size_left = 0;
- asf->packet_segments = 0;
asf->packet_flags = 0;
asf->packet_property = 0;
asf->packet_timestamp = 0;
diff --git a/libavformat/assdec.c b/libavformat/assdec.c
index 35fcb51..c9bd63b 100644
--- a/libavformat/assdec.c
+++ b/libavformat/assdec.c
@@ -19,6 +19,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <stdint.h>
+
#include "avformat.h"
#include "internal.h"
#include "subtitles.h"
diff --git a/libavformat/astdec.c b/libavformat/astdec.c
index 8862744..3fa26dc 100644
--- a/libavformat/astdec.c
+++ b/libavformat/astdec.c
@@ -27,12 +27,15 @@
static int ast_probe(AVProbeData *p)
{
- if (AV_RL32(p->buf) == MKTAG('S','T','R','M') &&
- AV_RB16(p->buf + 10) &&
- AV_RB16(p->buf + 12) &&
- AV_RB32(p->buf + 16))
- return AVPROBE_SCORE_MAX / 3 * 2;
- return 0;
+ if (AV_RL32(p->buf) != MKTAG('S','T','R','M'))
+ return 0;
+
+ if (!AV_RB16(p->buf + 10) ||
+ !AV_RB16(p->buf + 12) || AV_RB16(p->buf + 12) > 256 ||
+ !AV_RB32(p->buf + 16) || AV_RB32(p->buf + 16) > 8*48000)
+ return AVPROBE_SCORE_MAX / 8;
+
+ return AVPROBE_SCORE_MAX / 3 * 2;
}
static int ast_read_header(AVFormatContext *s)
diff --git a/libavformat/au.c b/libavformat/au.c
index 22004d0..edf0f32 100644
--- a/libavformat/au.c
+++ b/libavformat/au.c
@@ -31,6 +31,7 @@
#include "internal.h"
#include "avio_internal.h"
#include "pcm.h"
+#include "libavutil/avassert.h"
/* if we don't know the size in advance */
#define AU_UNKNOWN_SIZE ((uint32_t)(~0))
@@ -45,8 +46,12 @@
{ AV_CODEC_ID_PCM_S32BE, 5 },
{ AV_CODEC_ID_PCM_F32BE, 6 },
{ AV_CODEC_ID_PCM_F64BE, 7 },
+ { AV_CODEC_ID_ADPCM_G726LE, 23 },
{ AV_CODEC_ID_ADPCM_G722,24 },
+ { AV_CODEC_ID_ADPCM_G726LE, 25 },
+ { AV_CODEC_ID_ADPCM_G726LE, 26 },
{ AV_CODEC_ID_PCM_ALAW, 27 },
+ { AV_CODEC_ID_ADPCM_G726LE, MKBETAG('7','2','6','2') },
{ AV_CODEC_ID_NONE, 0 },
};
@@ -101,7 +106,15 @@
}
bps = av_get_bits_per_sample(codec);
- if (!bps) {
+ if (codec == AV_CODEC_ID_ADPCM_G726LE) {
+ if (id == MKBETAG('7','2','6','2')) {
+ bps = 2;
+ } else {
+ const uint8_t bpcss[] = {4, 0, 3, 5};
+ av_assert0(id >= 23 && id < 23 + 4);
+ bps = bpcss[id - 23];
+ }
+ } else if (!bps) {
avpriv_request_sample(s, "Unknown bits per sample");
return AVERROR_PATCHWELCOME;
}
@@ -124,6 +137,7 @@
st->codec->codec_id = codec;
st->codec->channels = channels;
st->codec->sample_rate = rate;
+ st->codec->bits_per_coded_sample = bps;
st->codec->bit_rate = channels * rate * bps;
st->codec->block_align = FFMAX(bps * st->codec->channels / 8, 1);
if (data_size != AU_UNKNOWN_SIZE)
diff --git a/libavformat/avformat.h b/libavformat/avformat.h
index 4e5683c..6bd54ce 100644
--- a/libavformat/avformat.h
+++ b/libavformat/avformat.h
@@ -775,6 +775,11 @@
int pts_wrap_bits; /**< number of bits in pts (used for wrapping control) */
+#if FF_API_REFERENCE_DTS
+ /* a hack to keep ABI compatibility for ffmpeg and other applications, which accesses parser even
+ * though it should not */
+ int64_t do_not_use;
+#endif
// Timestamp generation support:
/**
* Timestamp corresponding to the last dts sync point.
@@ -783,7 +788,6 @@
* 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;
int64_t last_IP_pts;
diff --git a/libavformat/avformatres.rc b/libavformat/avformatres.rc
new file mode 100644
index 0000000..ffe61e0
--- /dev/null
+++ b/libavformat/avformatres.rc
@@ -0,0 +1,55 @@
+/*
+ * Windows resource file for libavformat
+ *
+ * Copyright (C) 2012 James Almer
+ * Copyright (C) 2013 Tiancheng "Timothy" Gu
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <windows.h>
+#include "libavformat/version.h"
+#include "libavutil/ffversion.h"
+#include "config.h"
+
+1 VERSIONINFO
+FILEVERSION LIBAVFORMAT_VERSION_MAJOR, LIBAVFORMAT_VERSION_MINOR, LIBAVFORMAT_VERSION_MICRO, 0
+PRODUCTVERSION LIBAVFORMAT_VERSION_MAJOR, LIBAVFORMAT_VERSION_MINOR, LIBAVFORMAT_VERSION_MICRO, 0
+FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+FILEOS VOS_NT_WINDOWS32
+FILETYPE VFT_DLL
+{
+ BLOCK "StringFileInfo"
+ {
+ BLOCK "040904B0"
+ {
+ VALUE "CompanyName", "FFmpeg Project"
+ VALUE "FileDescription", "FFmpeg container format library"
+ VALUE "FileVersion", AV_STRINGIFY(LIBAVFORMAT_VERSION)
+ VALUE "InternalName", "libavformat"
+ VALUE "LegalCopyright", "Copyright (C) 2000-" AV_STRINGIFY(CONFIG_THIS_YEAR) " FFmpeg Project"
+ VALUE "OriginalFilename", "avformat" BUILDSUF "-" AV_STRINGIFY(LIBAVFORMAT_VERSION_MAJOR) SLIBSUF
+ VALUE "ProductName", "FFmpeg"
+ VALUE "ProductVersion", FFMPEG_VERSION
+ }
+ }
+
+ BLOCK "VarFileInfo"
+ {
+ VALUE "Translation", 0x0409, 0x04B0
+ }
+}
diff --git a/libavformat/avidec.c b/libavformat/avidec.c
index 1a40e94..1c6b18c 100644
--- a/libavformat/avidec.c
+++ b/libavformat/avidec.c
@@ -19,6 +19,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <stdint.h>
+
#include "libavutil/avassert.h"
#include "libavutil/avstring.h"
#include "libavutil/bswap.h"
@@ -111,8 +113,8 @@
static int guess_ni_flag(AVFormatContext *s);
#define print_tag(str, tag, size) \
- av_dlog(NULL, "%s: tag=%c%c%c%c size=0x%x\n", \
- str, tag & 0xff, \
+ av_dlog(NULL, "pos:%"PRIX64" %s: tag=%c%c%c%c size=0x%x\n", \
+ avio_tell(pb), str, tag & 0xff, \
(tag >> 8) & 0xff, \
(tag >> 16) & 0xff, \
(tag >> 24) & 0xff, \
@@ -623,6 +625,10 @@
if (cur_pos < list_end)
size = FFMIN(size, list_end - cur_pos);
st = s->streams[stream_index];
+ if (st->codec->codec_type != AVMEDIA_TYPE_UNKNOWN) {
+ avio_skip(pb, size);
+ break;
+ }
switch (codec_type) {
case AVMEDIA_TYPE_VIDEO:
if (amv_file_format) {
@@ -1306,10 +1312,9 @@
size);
pkt->stream_index = avi->stream_index;
- if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
+ if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO && st->index_entries) {
AVIndexEntry *e;
int index;
- av_assert0(st->index_entries);
index = av_index_search_timestamp(st, ast->frame_offset, 0);
e = &st->index_entries[index];
diff --git a/libavformat/avienc.c b/libavformat/avienc.c
index 3401cbc..45f7a20 100644
--- a/libavformat/avienc.c
+++ b/libavformat/avienc.c
@@ -26,6 +26,8 @@
#include "avi.h"
#include "avio_internal.h"
#include "riff.h"
+#include "libavformat/avlanguage.h"
+#include "libavutil/avstring.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/dict.h"
#include "libavutil/avassert.h"
@@ -309,6 +311,16 @@
ff_riff_write_info_tag(s->pb, "strn", t->value);
t = NULL;
}
+ if(stream->codec_id == AV_CODEC_ID_XSUB
+ && (t = av_dict_get(s->streams[i]->metadata, "language", NULL, 0))) {
+ const char* langstr = av_convert_lang_to(t->value, AV_LANG_ISO639_1);
+ t = NULL;
+ if (langstr) {
+ char* str = av_asprintf("Subtitle - %s-xx;02", langstr);
+ ff_riff_write_info_tag(s->pb, "strn", str);
+ av_free(str);
+ }
+ }
}
if (pb->seekable) {
@@ -661,5 +673,4 @@
.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 2c7a35e..225d982 100644
--- a/libavformat/avio.c
+++ b/libavformat/avio.c
@@ -42,8 +42,10 @@
static const char *urlcontext_to_name(void *ptr)
{
URLContext *h = (URLContext *)ptr;
- if(h->prot) return h->prot->name;
- else return "NULL";
+ if (h->prot)
+ return h->prot->name;
+ else
+ return "NULL";
}
static void *urlcontext_child_next(void *obj, void *prev)
@@ -68,49 +70,44 @@
if (p->priv_data_class)
return p->priv_data_class;
return NULL;
-
}
-static const AVOption options[] = {{NULL}};
+static const AVOption options[] = { { NULL } };
const AVClass ffurl_context_class = {
- .class_name = "URLContext",
- .item_name = urlcontext_to_name,
- .option = options,
- .version = LIBAVUTIL_VERSION_INT,
- .child_next = urlcontext_child_next,
+ .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,
};
/*@}*/
-
const char *avio_enum_protocols(void **opaque, int output)
{
URLProtocol *p;
*opaque = ffurl_protocol_next(*opaque);
- if (!(p = *opaque)) return NULL;
+ if (!(p = *opaque))
+ return NULL;
if ((output && p->url_write) || (!output && p->url_read))
return p->name;
return avio_enum_protocols(opaque, output);
}
-int ffurl_register_protocol(URLProtocol *protocol, int size)
+int ffurl_register_protocol(URLProtocol *protocol)
{
URLProtocol **p;
- if (size < sizeof(URLProtocol)) {
- URLProtocol* temp = av_mallocz(sizeof(URLProtocol));
- memcpy(temp, protocol, size);
- protocol = temp;
- }
p = &first_protocol;
- while (*p != NULL) p = &(*p)->next;
- *p = protocol;
+ while (*p != NULL)
+ p = &(*p)->next;
+ *p = protocol;
protocol->next = NULL;
return 0;
}
-static int url_alloc_for_protocol (URLContext **puc, struct URLProtocol *up,
- const char *filename, int flags,
- const AVIOInterruptCB *int_cb)
+static int url_alloc_for_protocol(URLContext **puc, struct URLProtocol *up,
+ const char *filename, int flags,
+ const AVIOInterruptCB *int_cb)
{
URLContext *uc;
int err;
@@ -135,18 +132,22 @@
goto fail;
}
uc->av_class = &ffurl_context_class;
- uc->filename = (char *) &uc[1];
+ uc->filename = (char *)&uc[1];
strcpy(uc->filename, filename);
- uc->prot = up;
- uc->flags = flags;
- uc->is_streamed = 0; /* default = not streamed */
+ uc->prot = up;
+ uc->flags = flags;
+ uc->is_streamed = 0; /* default = not streamed */
uc->max_packet_size = 0; /* default: stream file */
if (up->priv_data_size) {
uc->priv_data = av_mallocz(up->priv_data_size);
+ if (!uc->priv_data) {
+ err = AVERROR(ENOMEM);
+ goto fail;
+ }
if (up->priv_data_class) {
int proto_len= strlen(up->name);
char *start = strchr(uc->filename, ',');
- *(const AVClass**)uc->priv_data = up->priv_data_class;
+ *(const AVClass **)uc->priv_data = up->priv_data_class;
av_opt_set_defaults(uc->priv_data);
if(!strncmp(up->name, uc->filename, proto_len) && uc->filename + proto_len == start){
int ret= 0;
@@ -178,8 +179,11 @@
*puc = uc;
return 0;
- fail:
+fail:
*puc = NULL;
+ if (uc)
+ av_freep(&uc->priv_data);
+ av_freep(&uc);
#if CONFIG_NETWORK
if (up->flags & URL_PROTOCOL_FLAG_NETWORK)
ff_network_close();
@@ -187,19 +191,22 @@
return err;
}
-int ffurl_connect(URLContext* uc, AVDictionary **options)
+int ffurl_connect(URLContext *uc, AVDictionary **options)
{
int err =
- uc->prot->url_open2 ? uc->prot->url_open2(uc, uc->filename, uc->flags, options) :
+ uc->prot->url_open2 ? uc->prot->url_open2(uc,
+ uc->filename,
+ uc->flags,
+ options) :
uc->prot->url_open(uc, uc->filename, uc->flags);
if (err)
return err;
uc->is_connected = 1;
- //We must be careful here as ffurl_seek() could be slow, for example for http
- if( (uc->flags & AVIO_FLAG_WRITE)
- || !strcmp(uc->prot->name, "file"))
- if(!uc->is_streamed && ffurl_seek(uc, 0, SEEK_SET) < 0)
- uc->is_streamed= 1;
+ /* We must be careful here as ffurl_seek() could be slow,
+ * for example for http */
+ if ((uc->flags & AVIO_FLAG_WRITE) || !strcmp(uc->prot->name, "file"))
+ if (!uc->is_streamed && ffurl_seek(uc, 0, SEEK_SET) < 0)
+ uc->is_streamed = 1;
return 0;
}
@@ -225,7 +232,8 @@
is_dos_path(filename))
strcpy(proto_str, "file");
else
- av_strlcpy(proto_str, filename, FFMIN(proto_len+1, sizeof(proto_str)));
+ av_strlcpy(proto_str, filename,
+ FFMIN(proto_len + 1, sizeof(proto_str)));
if ((ptr = strchr(proto_str, ',')))
*ptr = '\0';
@@ -235,10 +243,10 @@
while (up = ffurl_protocol_next(up)) {
if (!strcmp(proto_str, up->name))
- return url_alloc_for_protocol (puc, up, filename, flags, int_cb);
+ 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, int_cb);
+ return url_alloc_for_protocol(puc, up, filename, flags, int_cb);
}
*puc = NULL;
if (!strcmp("https", proto_str))
@@ -264,8 +272,11 @@
return ret;
}
-static inline int retry_transfer_wrapper(URLContext *h, unsigned char *buf, int size, int size_min,
- int (*transfer_func)(URLContext *h, unsigned char *buf, int size))
+static inline int retry_transfer_wrapper(URLContext *h, uint8_t *buf,
+ int size, int size_min,
+ int (*transfer_func)(URLContext *h,
+ uint8_t *buf,
+ int size))
{
int ret, len;
int fast_retries = 5;
@@ -275,7 +286,7 @@
while (len < size_min) {
if (ff_check_interrupt(&h->interrupt_callback))
return AVERROR_EXIT;
- ret = transfer_func(h, buf+len, size-len);
+ ret = transfer_func(h, buf + len, size - len);
if (ret == AVERROR(EINTR))
continue;
if (h->flags & AVIO_FLAG_NONBLOCK)
@@ -296,7 +307,7 @@
} else if (ret < 1)
return (ret < 0 && ret != AVERROR_EOF) ? ret : len;
if (ret)
- fast_retries = FFMAX(fast_retries, 2);
+ fast_retries = FFMAX(fast_retries, 2);
len += ret;
}
return len;
@@ -341,7 +352,8 @@
{
URLContext *h= *hh;
int ret = 0;
- if (!h) return 0; /* can happen when ffurl_open fails */
+ if (!h)
+ return 0; /* can happen when ffurl_open fails */
if (h->is_connected && h->prot->url_close)
ret = h->prot->url_close(h);
@@ -387,8 +399,8 @@
{
int64_t pos, size;
- size= ffurl_seek(h, 0, AVSEEK_SIZE);
- if(size<0){
+ size = ffurl_seek(h, 0, AVSEEK_SIZE);
+ if (size < 0) {
pos = ffurl_seek(h, 0, SEEK_CUR);
if ((size = ffurl_seek(h, -1, SEEK_END)) < 0)
return size;
diff --git a/libavformat/avio.h b/libavformat/avio.h
index 5bdbc62..4f4ac3c 100644
--- a/libavformat/avio.h
+++ b/libavformat/avio.h
@@ -368,7 +368,7 @@
* 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
- * @return 0 in case of success, a negative value corresponding to an
+ * @return >= 0 in case of success, a negative value corresponding to an
* AVERROR code in case of failure
*/
int avio_open(AVIOContext **s, const char *url, int flags);
@@ -387,7 +387,7 @@
* @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
+ * @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,
diff --git a/libavformat/avio_internal.h b/libavformat/avio_internal.h
index c5a2a96..8441d49 100644
--- a/libavformat/avio_internal.h
+++ b/libavformat/avio_internal.h
@@ -78,7 +78,7 @@
* @param s The read-only AVIOContext to rewind
* @param buf The probe buffer containing the first buf_size bytes of the file
* @param buf_size The size of buf
- * @return 0 in case of success, a negative value corresponding to an
+ * @return >= 0 in case of success, a negative value corresponding to an
* AVERROR code in case of failure
*/
int ffio_rewind_with_probe_data(AVIOContext *s, unsigned char **buf, int buf_size);
@@ -125,7 +125,7 @@
*
* @param s Used to return the pointer to the created AVIOContext.
* In case of failure the pointed to value is set to NULL.
- * @return 0 in case of success, a negative value corresponding to an
+ * @return >= 0 in case of success, a negative value corresponding to an
* AVERROR code in case of failure
*/
int ffio_fdopen(AVIOContext **s, URLContext *h);
diff --git a/libavformat/aviobuf.c b/libavformat/aviobuf.c
index 8218078..8b4511d 100644
--- a/libavformat/aviobuf.c
+++ b/libavformat/aviobuf.c
@@ -319,15 +319,22 @@
{
const uint8_t *q = str;
int ret = 0;
+ int err = 0;
while (*q) {
uint32_t ch;
uint16_t tmp;
- GET_UTF8(ch, *q++, break;)
+ GET_UTF8(ch, *q++, goto invalid;)
PUT_UTF16(ch, tmp, avio_wl16(s, tmp); ret += 2;)
+ continue;
+invalid:
+ av_log(s, AV_LOG_ERROR, "Invaid UTF8 sequence in avio_put_str16le\n");
+ err = AVERROR(EINVAL);
}
avio_wl16(s, 0);
+ if (err)
+ return err;
ret += 2;
return ret;
}
@@ -1034,6 +1041,11 @@
static const char padbuf[FF_INPUT_BUFFER_PADDING_SIZE] = {0};
int padding = 0;
+ if (!s) {
+ *pbuffer = NULL;
+ return 0;
+ }
+
/* don't attempt to pad fixed-size packet buffers */
if (!s->max_packet_size) {
avio_write(s, padbuf, sizeof(padbuf));
diff --git a/libavformat/avisynth.c b/libavformat/avisynth.c
index d399242..2f438d9 100644
--- a/libavformat/avisynth.c
+++ b/libavformat/avisynth.c
@@ -1,5 +1,5 @@
/*
- * Avi/AvxSynth support
+ * AviSynth/AvxSynth support
* Copyright (c) 2012 AvxSynth Team.
*
* This file is part of FFmpeg
@@ -19,51 +19,38 @@
*/
#include "libavutil/internal.h"
+#include "libavcodec/internal.h"
#include "avformat.h"
#include "internal.h"
-#include "libavcodec/internal.h"
-// Enable function pointer definitions for runtime loading.
+/* Enable function pointer definitions for runtime loading. */
#define AVSC_NO_DECLSPEC
-// Shut up ffmpeg error messages.
-// avisynth_c.h contains inline functions that call these functions.
-#undef malloc
-#undef free
-#undef printf
-
-// Platform-specific directives for AviSynth vs AvxSynth.
+/* Platform-specific directives for AviSynth vs AvxSynth. */
#ifdef _WIN32
#include <windows.h>
#undef EXTERN_C
#include "compat/avisynth/avisynth_c.h"
#include "compat/avisynth/avisynth_c_25.h"
#define AVISYNTH_LIB "avisynth"
+ #define USING_AVISYNTH
#else
#include <dlfcn.h>
#include "compat/avisynth/avxsynth_c.h"
- #if defined (__APPLE__)
- #define AVISYNTH_LIB "libavxsynth.dylib"
- #else
- #define AVISYNTH_LIB "libavxsynth.so"
- #endif
+ #if defined (__APPLE__)
+ #define AVISYNTH_LIB "libavxsynth.dylib"
+ #else
+ #define AVISYNTH_LIB "libavxsynth.so"
+ #endif
#define LoadLibrary(x) dlopen(x, RTLD_NOW | RTLD_GLOBAL)
#define GetProcAddress dlsym
#define FreeLibrary dlclose
#endif
-// AvxSynth doesn't have these colorspaces, so disable them
-#ifndef _WIN32
-#define avs_is_yv24(vi) 0
-#define avs_is_yv16(vi) 0
-#define avs_is_yv411(vi) 0
-#define avs_is_y8(vi) 0
-#endif
-
-typedef struct {
+typedef struct AviSynthLibrary {
void *library;
-#define AVSC_DECLARE_FUNC(name) name##_func name
+#define AVSC_DECLARE_FUNC(name) name ## _func name
AVSC_DECLARE_FUNC(avs_bit_blt);
AVSC_DECLARE_FUNC(avs_clip_get_error);
AVSC_DECLARE_FUNC(avs_create_script_environment);
@@ -81,12 +68,12 @@
#undef AVSC_DECLARE_FUNC
} AviSynthLibrary;
-struct AviSynthContext {
+typedef struct AviSynthContext {
AVS_ScriptEnvironment *env;
AVS_Clip *clip;
const AVS_VideoInfo *vi;
- // avisynth_read_packet_video() iterates over this.
+ /* avisynth_read_packet_video() iterates over this. */
int n_planes;
const int *planes;
@@ -96,40 +83,37 @@
int error;
- // Linked list pointers.
+ /* Linked list pointers. */
struct AviSynthContext *next;
-};
-typedef struct AviSynthContext AviSynthContext;
+} AviSynthContext;
-static const int avs_planes_packed[1] = {0};
-static const int avs_planes_grey[1] = {AVS_PLANAR_Y};
-static const int avs_planes_yuv[3] = {AVS_PLANAR_Y, AVS_PLANAR_U, AVS_PLANAR_V};
+static const int avs_planes_packed[1] = { 0 };
+static const int avs_planes_grey[1] = { AVS_PLANAR_Y };
+static const int avs_planes_yuv[3] = { AVS_PLANAR_Y, AVS_PLANAR_U,
+ AVS_PLANAR_V };
-// A conflict between C++ global objects, atexit, and dynamic loading requires
-// us to register our own atexit handler to prevent double freeing.
-static AviSynthLibrary *avs_library = NULL;
-static int avs_atexit_called = 0;
+/* A conflict between C++ global objects, atexit, and dynamic loading requires
+ * us to register our own atexit handler to prevent double freeing. */
+static AviSynthLibrary avs_library;
+static int avs_atexit_called = 0;
-// Linked list of AviSynthContexts. An atexit handler destroys this list.
+/* Linked list of AviSynthContexts. An atexit handler destroys this list. */
static AviSynthContext *avs_ctx_list = NULL;
static av_cold void avisynth_atexit_handler(void);
-static av_cold int avisynth_load_library(void) {
- avs_library = av_mallocz(sizeof(AviSynthLibrary));
- if (!avs_library)
+static av_cold int avisynth_load_library(void)
+{
+ avs_library.library = LoadLibrary(AVISYNTH_LIB);
+ if (!avs_library.library)
return AVERROR_UNKNOWN;
- avs_library->library = LoadLibrary(AVISYNTH_LIB);
- if (!avs_library->library)
- goto init_fail;
+#define LOAD_AVS_FUNC(name, continue_on_fail) \
+ avs_library.name = \
+ (void *)GetProcAddress(avs_library.library, #name); \
+ if (!continue_on_fail && !avs_library.name) \
+ goto fail;
-#define LOAD_AVS_FUNC(name, continue_on_fail) \
-{ \
- avs_library->name = (void*)GetProcAddress(avs_library->library, #name); \
- if(!continue_on_fail && !avs_library->name) \
- goto fail; \
-}
LOAD_AVS_FUNC(avs_bit_blt, 0);
LOAD_AVS_FUNC(avs_clip_get_error, 0);
LOAD_AVS_FUNC(avs_create_script_environment, 0);
@@ -150,27 +134,25 @@
return 0;
fail:
- FreeLibrary(avs_library->library);
-init_fail:
- av_freep(&avs_library);
+ FreeLibrary(avs_library.library);
return AVERROR_UNKNOWN;
}
-// Note that avisynth_context_create and avisynth_context_destroy
-// do not allocate or free the actual context! That is taken care of
-// by libavformat.
-static av_cold int avisynth_context_create(AVFormatContext *s) {
- AviSynthContext *avs = (AviSynthContext *)s->priv_data;
+/* Note that avisynth_context_create and avisynth_context_destroy
+ * do not allocate or free the actual context! That is taken care of
+ * by libavformat. */
+static av_cold int avisynth_context_create(AVFormatContext *s)
+{
+ AviSynthContext *avs = s->priv_data;
int ret;
- if (!avs_library) {
+ if (!avs_library.library)
if (ret = avisynth_load_library())
return ret;
- }
- avs->env = avs_library->avs_create_script_environment(3);
- if (avs_library->avs_get_error) {
- const char *error = avs_library->avs_get_error(avs->env);
+ avs->env = avs_library.avs_create_script_environment(3);
+ if (avs_library.avs_get_error) {
+ const char *error = avs_library.avs_get_error(avs->env);
if (error) {
av_log(s, AV_LOG_ERROR, "%s\n", error);
return AVERROR_UNKNOWN;
@@ -180,16 +162,17 @@
if (!avs_ctx_list) {
avs_ctx_list = avs;
} else {
- avs->next = avs_ctx_list;
+ avs->next = avs_ctx_list;
avs_ctx_list = avs;
}
return 0;
}
-static av_cold void avisynth_context_destroy(AviSynthContext *avs) {
+static av_cold void avisynth_context_destroy(AviSynthContext *avs)
+{
if (avs_atexit_called)
- return;
+ return;
if (avs == avs_ctx_list) {
avs_ctx_list = avs->next;
@@ -201,16 +184,17 @@
}
if (avs->clip) {
- avs_library->avs_release_clip(avs->clip);
+ avs_library.avs_release_clip(avs->clip);
avs->clip = NULL;
}
if (avs->env) {
- avs_library->avs_delete_script_environment(avs->env);
+ avs_library.avs_delete_script_environment(avs->env);
avs->env = NULL;
}
}
-static av_cold void avisynth_atexit_handler(void) {
+static av_cold void avisynth_atexit_handler(void)
+{
AviSynthContext *avs = avs_ctx_list;
while (avs) {
@@ -218,45 +202,47 @@
avisynth_context_destroy(avs);
avs = next;
}
- FreeLibrary(avs_library->library);
- av_freep(&avs_library);
+ FreeLibrary(avs_library.library);
avs_atexit_called = 1;
}
-// Create AVStream from audio and video data.
-static int avisynth_create_stream_video(AVFormatContext *s, AVStream *st) {
+/* Create AVStream from audio and video data. */
+static int avisynth_create_stream_video(AVFormatContext *s, AVStream *st)
+{
AviSynthContext *avs = s->priv_data;
int planar = 0; // 0: packed, 1: YUV, 2: Y8
st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
- st->codec->codec_id = CODEC_ID_RAWVIDEO;
- st->codec->width = avs->vi->width;
- st->codec->height = avs->vi->height;
+ st->codec->codec_id = AV_CODEC_ID_RAWVIDEO;
+ st->codec->width = avs->vi->width;
+ st->codec->height = avs->vi->height;
- st->time_base = (AVRational) {avs->vi->fps_denominator, avs->vi->fps_numerator};
- st->avg_frame_rate = (AVRational) {avs->vi->fps_numerator, avs->vi->fps_denominator};
- st->start_time = 0;
- st->duration = avs->vi->num_frames;
- st->nb_frames = avs->vi->num_frames;
+ st->time_base = (AVRational) { avs->vi->fps_denominator,
+ avs->vi->fps_numerator };
+ st->avg_frame_rate = (AVRational) { avs->vi->fps_numerator,
+ avs->vi->fps_denominator };
+ st->start_time = 0;
+ st->duration = avs->vi->num_frames;
+ st->nb_frames = avs->vi->num_frames;
switch (avs->vi->pixel_type) {
-#ifdef _WIN32
+#ifdef USING_AVISYNTH
case AVS_CS_YV24:
st->codec->pix_fmt = AV_PIX_FMT_YUV444P;
- planar = 1;
+ planar = 1;
break;
case AVS_CS_YV16:
st->codec->pix_fmt = AV_PIX_FMT_YUV422P;
- planar = 1;
+ planar = 1;
break;
case AVS_CS_YV411:
st->codec->pix_fmt = AV_PIX_FMT_YUV411P;
- planar = 1;
+ planar = 1;
break;
case AVS_CS_Y8:
st->codec->pix_fmt = AV_PIX_FMT_GRAY8;
- planar = 2;
+ planar = 2;
break;
#endif
case AVS_CS_BGR24:
@@ -270,14 +256,15 @@
break;
case AVS_CS_YV12:
st->codec->pix_fmt = AV_PIX_FMT_YUV420P;
- planar = 1;
+ planar = 1;
break;
case AVS_CS_I420: // Is this even used anywhere?
st->codec->pix_fmt = AV_PIX_FMT_YUV420P;
- planar = 1;
+ planar = 1;
break;
default:
- av_log(s, AV_LOG_ERROR, "unknown AviSynth colorspace %d\n", avs->vi->pixel_type);
+ av_log(s, AV_LOG_ERROR,
+ "unknown AviSynth colorspace %d\n", avs->vi->pixel_type);
avs->error = 1;
return AVERROR_UNKNOWN;
}
@@ -285,52 +272,56 @@
switch (planar) {
case 2: // Y8
avs->n_planes = 1;
- avs->planes = avs_planes_grey;
+ avs->planes = avs_planes_grey;
break;
case 1: // YUV
avs->n_planes = 3;
- avs->planes = avs_planes_yuv;
+ avs->planes = avs_planes_yuv;
break;
default:
avs->n_planes = 1;
- avs->planes = avs_planes_packed;
+ avs->planes = avs_planes_packed;
}
return 0;
}
-static int avisynth_create_stream_audio(AVFormatContext *s, AVStream *st) {
+static int avisynth_create_stream_audio(AVFormatContext *s, AVStream *st)
+{
AviSynthContext *avs = s->priv_data;
- st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
+ st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
st->codec->sample_rate = avs->vi->audio_samples_per_second;
- st->codec->channels = avs->vi->nchannels;
- st->time_base = (AVRational) {1, avs->vi->audio_samples_per_second};
+ st->codec->channels = avs->vi->nchannels;
+ st->time_base = (AVRational) { 1,
+ avs->vi->audio_samples_per_second };
switch (avs->vi->sample_type) {
case AVS_SAMPLE_INT8:
- st->codec->codec_id = CODEC_ID_PCM_U8;
+ st->codec->codec_id = AV_CODEC_ID_PCM_U8;
break;
case AVS_SAMPLE_INT16:
- st->codec->codec_id = CODEC_ID_PCM_S16LE;
+ st->codec->codec_id = AV_CODEC_ID_PCM_S16LE;
break;
case AVS_SAMPLE_INT24:
- st->codec->codec_id = CODEC_ID_PCM_S24LE;
+ st->codec->codec_id = AV_CODEC_ID_PCM_S24LE;
break;
case AVS_SAMPLE_INT32:
- st->codec->codec_id = CODEC_ID_PCM_S32LE;
+ st->codec->codec_id = AV_CODEC_ID_PCM_S32LE;
break;
case AVS_SAMPLE_FLOAT:
- st->codec->codec_id = CODEC_ID_PCM_F32LE;
+ st->codec->codec_id = AV_CODEC_ID_PCM_F32LE;
break;
default:
- av_log(s, AV_LOG_ERROR, "unknown AviSynth sample type %d\n", avs->vi->sample_type);
+ av_log(s, AV_LOG_ERROR,
+ "unknown AviSynth sample type %d\n", avs->vi->sample_type);
avs->error = 1;
return AVERROR_UNKNOWN;
}
return 0;
}
-static int avisynth_create_stream(AVFormatContext *s) {
+static int avisynth_create_stream(AVFormatContext *s)
+{
AviSynthContext *avs = s->priv_data;
AVStream *st;
int ret;
@@ -355,11 +346,12 @@
return 0;
}
-static int avisynth_open_file(AVFormatContext *s) {
- AviSynthContext *avs = (AviSynthContext *)s->priv_data;
+static int avisynth_open_file(AVFormatContext *s)
+{
+ AviSynthContext *avs = s->priv_data;
AVS_Value arg, val;
int ret;
-#ifdef _WIN32
+#ifdef USING_AVISYNTH
char filename_ansi[MAX_PATH * 4];
wchar_t filename_wc[MAX_PATH * 4];
#endif
@@ -367,31 +359,32 @@
if (ret = avisynth_context_create(s))
return ret;
-#ifdef _WIN32
- // Convert UTF-8 to ANSI code page
+#ifdef USING_AVISYNTH
+ /* Convert UTF-8 to ANSI code page */
MultiByteToWideChar(CP_UTF8, 0, s->filename, -1, filename_wc, MAX_PATH * 4);
- WideCharToMultiByte(CP_THREAD_ACP, 0, filename_wc, -1, filename_ansi, MAX_PATH * 4, NULL, NULL);
+ WideCharToMultiByte(CP_THREAD_ACP, 0, filename_wc, -1, filename_ansi,
+ MAX_PATH * 4, NULL, NULL);
arg = avs_new_value_string(filename_ansi);
#else
arg = avs_new_value_string(s->filename);
#endif
- val = avs_library->avs_invoke(avs->env, "Import", arg, 0);
+ val = avs_library.avs_invoke(avs->env, "Import", arg, 0);
if (avs_is_error(val)) {
av_log(s, AV_LOG_ERROR, "%s\n", avs_as_error(val));
ret = AVERROR_UNKNOWN;
goto fail;
}
if (!avs_is_clip(val)) {
- av_log(s, AV_LOG_ERROR, "%s\n", "AviSynth script did not return a clip");
+ av_log(s, AV_LOG_ERROR, "AviSynth script did not return a clip\n");
ret = AVERROR_UNKNOWN;
goto fail;
}
- avs->clip = avs_library->avs_take_clip(val, avs->env);
- avs->vi = avs_library->avs_get_video_info(avs->clip);
+ avs->clip = avs_library.avs_take_clip(val, avs->env);
+ avs->vi = avs_library.avs_get_video_info(avs->clip);
- // Release the AVS_Value as it will go out of scope.
- avs_library->avs_release_value(val);
+ /* Release the AVS_Value as it will go out of scope. */
+ avs_library.avs_release_value(val);
if (ret = avisynth_create_stream(s))
goto fail;
@@ -403,7 +396,9 @@
return ret;
}
-static void avisynth_next_stream(AVFormatContext *s, AVStream **st, AVPacket *pkt, int *discard) {
+static void avisynth_next_stream(AVFormatContext *s, AVStream **st,
+ AVPacket *pkt, int *discard)
+{
AviSynthContext *avs = s->priv_data;
pkt->stream_index = avs->curr_stream++;
@@ -418,8 +413,10 @@
return;
}
-// Copy AviSynth clip data into an AVPacket.
-static int avisynth_read_packet_video(AVFormatContext *s, AVPacket *pkt, int discard) {
+/* Copy AviSynth clip data into an AVPacket. */
+static int avisynth_read_packet_video(AVFormatContext *s, AVPacket *pkt,
+ int discard)
+{
AviSynthContext *avs = s->priv_data;
AVS_VideoFrame *frame;
unsigned char *dst_p;
@@ -430,38 +427,45 @@
if (avs->curr_frame >= avs->vi->num_frames)
return AVERROR_EOF;
- // This must happen even if the stream is discarded to prevent desync.
+ /* This must happen even if the stream is discarded to prevent desync. */
n = avs->curr_frame++;
if (discard)
return 0;
- pkt->pts = n;
- pkt->dts = n;
+ pkt->pts = n;
+ pkt->dts = n;
pkt->duration = 1;
- // Define the bpp values for the new AviSynth 2.6 colorspaces
- if (avs_is_yv24(avs->vi)) {
- bits = 24;
- } else if (avs_is_yv16(avs->vi)) {
- bits = 16;
- } else if (avs_is_yv411(avs->vi)) {
- bits = 12;
- } else if (avs_is_y8(avs->vi)) {
- bits = 8;
- } else {
- bits = avs_bits_per_pixel(avs->vi);
- }
+#ifdef USING_AVISYNTH
+ /* Define the bpp values for the new AviSynth 2.6 colorspaces.
+ * Since AvxSynth doesn't have these functions, special-case
+ * it in order to avoid implicit declaration errors. */
- // Without cast to int64_t, calculation overflows at about 9k x 9k resolution.
- pkt->size = (((int64_t)avs->vi->width * (int64_t)avs->vi->height) * bits) / 8;
+ if (avs_is_yv24(avs->vi))
+ bits = 24;
+ else if (avs_is_yv16(avs->vi))
+ bits = 16;
+ else if (avs_is_yv411(avs->vi))
+ bits = 12;
+ else if (avs_is_y8(avs->vi))
+ bits = 8;
+ else
+#endif
+ bits = avs_bits_per_pixel(avs->vi);
+
+ /* Without the cast to int64_t, calculation overflows at about 9k x 9k
+ * resolution. */
+ pkt->size = (((int64_t)avs->vi->width *
+ (int64_t)avs->vi->height) * bits) / 8;
if (!pkt->size)
return AVERROR_UNKNOWN;
- pkt->data = av_malloc(pkt->size);
- if (!pkt->data)
- return AVERROR_UNKNOWN;
+ if (av_new_packet(pkt, (int)pkt->size) < 0) {
+ av_free(pkt);
+ return AVERROR(ENOMEM);
+ }
- frame = avs_library->avs_get_frame(avs->clip, n);
- error = avs_library->avs_clip_get_error(avs->clip);
+ frame = avs_library.avs_get_frame(avs->clip, n);
+ error = avs_library.avs_clip_get_error(avs->clip);
if (error) {
av_log(s, AV_LOG_ERROR, "%s\n", error);
avs->error = 1;
@@ -475,34 +479,37 @@
src_p = avs_get_read_ptr_p(frame, plane);
pitch = avs_get_pitch_p(frame, plane);
-#ifdef _WIN32
- if (avs_library->avs_get_version(avs->clip) == 3) {
- rowsize = avs_get_row_size_p_25(frame, plane);
+#ifdef USING_AVISYNTH
+ if (avs_library.avs_get_version(avs->clip) == 3) {
+ rowsize = avs_get_row_size_p_25(frame, plane);
planeheight = avs_get_height_p_25(frame, plane);
} else {
- rowsize = avs_get_row_size_p(frame, plane);
+ rowsize = avs_get_row_size_p(frame, plane);
planeheight = avs_get_height_p(frame, plane);
}
#else
- rowsize = avs_get_row_size_p(frame, plane);
+ rowsize = avs_get_row_size_p(frame, plane);
planeheight = avs_get_height_p(frame, plane);
#endif
- // Flip RGB video.
+ /* Flip RGB video. */
if (avs_is_rgb24(avs->vi) || avs_is_rgb(avs->vi)) {
src_p = src_p + (planeheight - 1) * pitch;
pitch = -pitch;
}
- avs_library->avs_bit_blt(avs->env, dst_p, rowsize, src_p, pitch, rowsize, planeheight);
+ avs_library.avs_bit_blt(avs->env, dst_p, rowsize, src_p, pitch,
+ rowsize, planeheight);
dst_p += rowsize * planeheight;
}
- avs_library->avs_release_video_frame(frame);
+ avs_library.avs_release_video_frame(frame);
return 0;
}
-static int avisynth_read_packet_audio(AVFormatContext *s, AVPacket *pkt, int discard) {
+static int avisynth_read_packet_audio(AVFormatContext *s, AVPacket *pkt,
+ int discard)
+{
AviSynthContext *avs = s->priv_data;
AVRational fps, samplerate;
int samples;
@@ -512,21 +519,22 @@
if (avs->curr_sample >= avs->vi->num_audio_samples)
return AVERROR_EOF;
- fps.num = avs->vi->fps_numerator;
- fps.den = avs->vi->fps_denominator;
+ fps.num = avs->vi->fps_numerator;
+ fps.den = avs->vi->fps_denominator;
samplerate.num = avs->vi->audio_samples_per_second;
samplerate.den = 1;
if (avs_has_video(avs->vi)) {
if (avs->curr_frame < avs->vi->num_frames)
- samples = av_rescale_q(avs->curr_frame, samplerate, fps) - avs->curr_sample;
+ samples = av_rescale_q(avs->curr_frame, samplerate, fps) -
+ avs->curr_sample;
else
samples = av_rescale_q(1, samplerate, fps);
} else {
samples = 1000;
}
- // After seeking, audio may catch up with video.
+ /* After seeking, audio may catch up with video. */
if (samples <= 0) {
pkt->size = 0;
pkt->data = NULL;
@@ -536,25 +544,26 @@
if (avs->curr_sample + samples > avs->vi->num_audio_samples)
samples = avs->vi->num_audio_samples - avs->curr_sample;
- // This must happen even if the stream is discarded to prevent desync.
- n = avs->curr_sample;
+ /* This must happen even if the stream is discarded to prevent desync. */
+ n = avs->curr_sample;
avs->curr_sample += samples;
if (discard)
return 0;
- pkt->pts = n;
- pkt->dts = n;
+ pkt->pts = n;
+ pkt->dts = n;
pkt->duration = samples;
- pkt->size = avs_bytes_per_channel_sample(avs->vi) * samples * avs->vi->nchannels;
+ pkt->size = avs_bytes_per_channel_sample(avs->vi) *
+ samples * avs->vi->nchannels;
if (!pkt->size)
return AVERROR_UNKNOWN;
pkt->data = av_malloc(pkt->size);
if (!pkt->data)
- return AVERROR_UNKNOWN;
+ return AVERROR(ENOMEM);
- avs_library->avs_get_audio(avs->clip, pkt->data, n, samples);
- error = avs_library->avs_clip_get_error(avs->clip);
+ avs_library.avs_get_audio(avs->clip, pkt->data, n, samples);
+ error = avs_library.avs_clip_get_error(avs->clip);
if (error) {
av_log(s, AV_LOG_ERROR, "%s\n", error);
avs->error = 1;
@@ -564,7 +573,8 @@
return 0;
}
-static av_cold int avisynth_read_header(AVFormatContext *s) {
+static av_cold int avisynth_read_header(AVFormatContext *s)
+{
int ret;
// Calling library must implement a lock for thread-safe opens.
@@ -580,7 +590,8 @@
return 0;
}
-static int avisynth_read_packet(AVFormatContext *s, AVPacket *pkt) {
+static int avisynth_read_packet(AVFormatContext *s, AVPacket *pkt)
+{
AviSynthContext *avs = s->priv_data;
AVStream *st;
int discard = 0;
@@ -589,9 +600,10 @@
if (avs->error)
return AVERROR_UNKNOWN;
- pkt->destruct = av_destruct_packet;
+ av_free_packet(pkt);
- // If either stream reaches EOF, try to read the other one before giving up.
+ /* If either stream reaches EOF, try to read the other one before
+ * giving up. */
avisynth_next_stream(s, &st, pkt, &discard);
if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
ret = avisynth_read_packet_video(s, pkt, discard);
@@ -599,18 +611,19 @@
avisynth_next_stream(s, &st, pkt, &discard);
return avisynth_read_packet_audio(s, pkt, discard);
}
- return ret;
} else {
ret = avisynth_read_packet_audio(s, pkt, discard);
if (ret == AVERROR_EOF && avs_has_video(avs->vi)) {
avisynth_next_stream(s, &st, pkt, &discard);
return avisynth_read_packet_video(s, pkt, discard);
}
- return ret;
}
+
+ return ret;
}
-static av_cold int avisynth_read_close(AVFormatContext *s) {
+static av_cold int avisynth_read_close(AVFormatContext *s)
+{
if (avpriv_lock_avformat())
return AVERROR_UNKNOWN;
@@ -619,7 +632,9 @@
return 0;
}
-static int avisynth_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags) {
+static int avisynth_read_seek(AVFormatContext *s, int stream_index,
+ int64_t timestamp, int flags)
+{
AviSynthContext *avs = s->priv_data;
AVStream *st;
AVRational fps, samplerate;
@@ -627,13 +642,16 @@
if (avs->error)
return AVERROR_UNKNOWN;
- fps = (AVRational) {avs->vi->fps_numerator, avs->vi->fps_denominator};
- samplerate = (AVRational) {avs->vi->audio_samples_per_second, 1};
+ fps = (AVRational) { avs->vi->fps_numerator,
+ avs->vi->fps_denominator };
+ samplerate = (AVRational) { avs->vi->audio_samples_per_second, 1 };
st = s->streams[stream_index];
if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
- // AviSynth frame counts are signed int.
- if ((timestamp >= avs->vi->num_frames) || (timestamp > INT_MAX) || (timestamp < 0))
+ /* AviSynth frame counts are signed int. */
+ if ((timestamp >= avs->vi->num_frames) ||
+ (timestamp > INT_MAX) ||
+ (timestamp < 0))
return AVERROR_EOF;
avs->curr_frame = timestamp;
if (avs_has_audio(avs->vi))
@@ -641,9 +659,9 @@
} else {
if ((timestamp >= avs->vi->num_audio_samples) || (timestamp < 0))
return AVERROR_EOF;
- // Force frame granularity for seeking.
+ /* Force frame granularity for seeking. */
if (avs_has_video(avs->vi)) {
- avs->curr_frame = av_rescale_q(timestamp, fps, samplerate);
+ avs->curr_frame = av_rescale_q(timestamp, fps, samplerate);
avs->curr_sample = av_rescale_q(avs->curr_frame, samplerate, fps);
} else {
avs->curr_sample = timestamp;
diff --git a/libavformat/avr.c b/libavformat/avr.c
index 02edf45..a33134e 100644
--- a/libavformat/avr.c
+++ b/libavformat/avr.c
@@ -26,9 +26,15 @@
static int avr_probe(AVProbeData *p)
{
- if (AV_RL32(p->buf) == MKTAG('2', 'B', 'I', 'T'))
- return AVPROBE_SCORE_EXTENSION;
- return 0;
+ if (AV_RL32(p->buf) != MKTAG('2', 'B', 'I', 'T'))
+ return 0;
+
+ if (!AV_RB16(p->buf+12) || AV_RB16(p->buf+12) > 256) // channels
+ return AVPROBE_SCORE_EXTENSION/2;
+ if (AV_RB16(p->buf+14) > 256) // bps
+ return AVPROBE_SCORE_EXTENSION/2;
+
+ return AVPROBE_SCORE_EXTENSION;
}
static int avr_read_header(AVFormatContext *s)
diff --git a/libavformat/bethsoftvid.c b/libavformat/bethsoftvid.c
index b8f08c1..6b84b79 100644
--- a/libavformat/bethsoftvid.c
+++ b/libavformat/bethsoftvid.c
@@ -61,6 +61,9 @@
if (AV_RL32(p->buf) != MKTAG('V', 'I', 'D', 0))
return 0;
+ if (p->buf[4] != 2)
+ return AVPROBE_SCORE_MAX / 4;
+
return AVPROBE_SCORE_MAX;
}
diff --git a/libavformat/bintext.c b/libavformat/bintext.c
index d504607..d50a8d9 100644
--- a/libavformat/bintext.c
+++ b/libavformat/bintext.c
@@ -65,7 +65,7 @@
avpriv_set_pts_info(st, 60, bin->framerate.den, bin->framerate.num);
/* simulate tty display speed */
- bin->chars_per_frame = FFMAX(av_q2d(st->time_base) * bin->chars_per_frame, 1);
+ bin->chars_per_frame = av_clip(av_q2d(st->time_base) * bin->chars_per_frame, 1, INT_MAX);
return st;
}
diff --git a/libavformat/dfa.c b/libavformat/dfa.c
index 12516af..9cd13e2 100644
--- a/libavformat/dfa.c
+++ b/libavformat/dfa.c
@@ -28,6 +28,9 @@
if (p->buf_size < 4 || AV_RL32(p->buf) != MKTAG('D', 'F', 'I', 'A'))
return 0;
+ if (AV_RL32(p->buf + 16) != 0x80)
+ return AVPROBE_SCORE_MAX / 4;
+
return AVPROBE_SCORE_MAX;
}
diff --git a/libavformat/diracdec.c b/libavformat/diracdec.c
index 6636ead..e061ba5 100644
--- a/libavformat/diracdec.c
+++ b/libavformat/diracdec.c
@@ -25,10 +25,19 @@
static int dirac_probe(AVProbeData *p)
{
- if (AV_RL32(p->buf) == MKTAG('B', 'B', 'C', 'D'))
- return AVPROBE_SCORE_MAX;
- else
+ unsigned size;
+ if (AV_RL32(p->buf) != MKTAG('B', 'B', 'C', 'D'))
return 0;
+
+ size = AV_RB32(p->buf+5);
+ if (size < 13)
+ return 0;
+ if (size + 13LL > p->buf_size)
+ return AVPROBE_SCORE_MAX / 4;
+ if (AV_RL32(p->buf + size) != MKTAG('B', 'B', 'C', 'D'))
+ return 0;
+
+ return AVPROBE_SCORE_MAX;
}
FF_DEF_RAWVIDEO_DEMUXER(dirac, "raw Dirac", dirac_probe, NULL, AV_CODEC_ID_DIRAC)
diff --git a/libavformat/dv.c b/libavformat/dv.c
index e3b0d0a..f972478 100644
--- a/libavformat/dv.c
+++ b/libavformat/dv.c
@@ -32,7 +32,7 @@
#include "avformat.h"
#include "internal.h"
#include "libavcodec/dv_profile.h"
-#include "libavcodec/dvdata.h"
+#include "libavcodec/dv.h"
#include "libavutil/channel_layout.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/mathematics.h"
@@ -582,31 +582,37 @@
static int dv_probe(AVProbeData *p)
{
- unsigned state, marker_pos = 0;
+ unsigned marker_pos = 0;
int i;
int matches = 0;
+ int firstmatch = 0;
int secondary_matches = 0;
if (p->buf_size < 5)
return 0;
- state = AV_RB32(p->buf);
- for (i = 4; i < p->buf_size; i++) {
- if ((state & 0xffffff7f) == 0x1f07003f)
- matches++;
- // any section header, also with seq/chan num != 0,
- // should appear around every 12000 bytes, at least 10 per frame
- if ((state & 0xff07ff7f) == 0x1f07003f)
- secondary_matches++;
- if (state == 0x003f0700 || state == 0xff3f0700)
- marker_pos = i;
- if (state == 0xff3f0701 && i - marker_pos == 80)
- matches++;
- state = (state << 8) | p->buf[i];
+ for (i = 0; i < p->buf_size-4; i++) {
+ unsigned state = AV_RB32(p->buf+i);
+ if ((state & 0x0007f840) == 0x00070000) {
+ // any section header, also with seq/chan num != 0,
+ // should appear around every 12000 bytes, at least 10 per frame
+ if ((state & 0xff07ff7f) == 0x1f07003f) {
+ secondary_matches++;
+ if ((state & 0xffffff7f) == 0x1f07003f) {
+ matches++;
+ if (!i)
+ firstmatch = 1;
+ }
+ }
+ if (state == 0x003f0700 || state == 0xff3f0700)
+ marker_pos = i;
+ if (state == 0xff3f0701 && i - marker_pos == 80)
+ matches++;
+ }
}
if (matches && p->buf_size / matches < 1024 * 1024) {
- if (matches > 4 ||
+ if (matches > 4 || firstmatch ||
(secondary_matches >= 10 &&
p->buf_size / secondary_matches < 24000))
// not max to avoid dv in mov to match
diff --git a/libavformat/dvenc.c b/libavformat/dvenc.c
index e37bd23..43f65c3 100644
--- a/libavformat/dvenc.c
+++ b/libavformat/dvenc.c
@@ -33,7 +33,7 @@
#include "avformat.h"
#include "internal.h"
#include "libavcodec/dv_profile.h"
-#include "libavcodec/dvdata.h"
+#include "libavcodec/dv.h"
#include "dv.h"
#include "libavutil/fifo.h"
#include "libavutil/mathematics.h"
diff --git a/libavformat/electronicarts.c b/libavformat/electronicarts.c
index 97c19c9..dd8cf5d 100644
--- a/libavformat/electronicarts.c
+++ b/libavformat/electronicarts.c
@@ -361,6 +361,11 @@
if (ea->big_endian)
size = av_bswap32(size);
+ if (size < 8) {
+ av_log(s, AV_LOG_ERROR, "chunk size too small\n");
+ return AVERROR_INVALIDDATA;
+ }
+
switch (blockid) {
case ISNh_TAG:
if (avio_rl32(pb) != EACS_TAG) {
@@ -435,6 +440,8 @@
static int ea_probe(AVProbeData *p)
{
+ unsigned big_endian, size;
+
switch (AV_RL32(&p->buf[0])) {
case ISNh_TAG:
case SCHl_TAG:
@@ -449,7 +456,11 @@
default:
return 0;
}
- if (AV_RL32(&p->buf[4]) > 0xfffff && AV_RB32(&p->buf[4]) > 0xfffff)
+ size = AV_RL32(&p->buf[4]);
+ big_endian = size > 0x000FFFFF;
+ if (big_endian)
+ size = av_bswap32(size);
+ if (size > 0xfffff || size < 8)
return 0;
return AVPROBE_SCORE_MAX;
diff --git a/libavformat/ffmdec.c b/libavformat/ffmdec.c
index b20ee13..679d926 100644
--- a/libavformat/ffmdec.c
+++ b/libavformat/ffmdec.c
@@ -19,6 +19,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <stdint.h>
+
#include "libavutil/intreadwrite.h"
#include "libavutil/intfloat.h"
#include "avformat.h"
diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c
index d259927..1024001 100644
--- a/libavformat/flvdec.c
+++ b/libavformat/flvdec.c
@@ -191,7 +191,7 @@
acodec->codec_id = AV_CODEC_ID_PCM_ALAW;
break;
default:
- av_log(s, AV_LOG_INFO, "Unsupported audio codec (%x)\n",
+ avpriv_request_sample(s, "Audio codec (%x)",
flv_codecid >> FLV_AUDIO_CODECID_OFFSET);
acodec->codec_tag = flv_codecid >> FLV_AUDIO_CODECID_OFFSET;
}
@@ -261,7 +261,7 @@
vcodec->codec_id = AV_CODEC_ID_MPEG4;
return 3;
default:
- av_log(s, AV_LOG_INFO, "Unsupported video codec (%x)\n", flv_codecid);
+ avpriv_request_sample(s, "Video codec (%x)", flv_codecid);
vcodec->codec_tag = flv_codecid;
}
diff --git a/libavformat/flvenc.c b/libavformat/flvenc.c
index 9224103..a1b498d 100644
--- a/libavformat/flvenc.c
+++ b/libavformat/flvenc.c
@@ -37,6 +37,7 @@
{ AV_CODEC_ID_FLASHSV, FLV_CODECID_SCREEN },
{ AV_CODEC_ID_FLASHSV2, FLV_CODECID_SCREEN2 },
{ AV_CODEC_ID_VP6F, FLV_CODECID_VP6 },
+ { AV_CODEC_ID_VP6, FLV_CODECID_VP6 },
{ AV_CODEC_ID_VP6A, FLV_CODECID_VP6A },
{ AV_CODEC_ID_H264, FLV_CODECID_H264 },
{ AV_CODEC_ID_NONE, 0 }
@@ -460,7 +461,7 @@
int flags = -1, flags_size, ret;
if (enc->codec_id == AV_CODEC_ID_VP6F || enc->codec_id == AV_CODEC_ID_VP6A ||
- enc->codec_id == AV_CODEC_ID_AAC)
+ enc->codec_id == AV_CODEC_ID_VP6 || enc->codec_id == AV_CODEC_ID_AAC)
flags_size = 2;
else if (enc->codec_id == AV_CODEC_ID_H264 || enc->codec_id == AV_CODEC_ID_MPEG4)
flags_size = 5;
@@ -560,6 +561,8 @@
} else {
av_assert1(flags>=0);
avio_w8(pb,flags);
+ if (enc->codec_id == AV_CODEC_ID_VP6)
+ avio_w8(pb,0);
if (enc->codec_id == AV_CODEC_ID_VP6F || enc->codec_id == AV_CODEC_ID_VP6A) {
if (enc->extradata_size)
avio_w8(pb, enc->extradata[0]);
diff --git a/libavformat/format.c b/libavformat/format.c
index ac9100b..36c0131 100644
--- a/libavformat/format.c
+++ b/libavformat/format.c
@@ -54,7 +54,7 @@
AVInputFormat **p = &first_iformat;
format->next = NULL;
- while(avpriv_atomic_ptr_cas((void * volatile *)p, NULL, format))
+ while(*p || avpriv_atomic_ptr_cas((void * volatile *)p, NULL, format))
p = &(*p)->next;
}
@@ -63,7 +63,7 @@
AVOutputFormat **p = &first_oformat;
format->next = NULL;
- while(avpriv_atomic_ptr_cas((void * volatile *)p, NULL, format))
+ while(*p || avpriv_atomic_ptr_cas((void * volatile *)p, NULL, format))
p = &(*p)->next;
}
diff --git a/libavformat/framehash.c b/libavformat/framehash.c
index 85caeb3..f97f59b 100644
--- a/libavformat/framehash.c
+++ b/libavformat/framehash.c
@@ -23,6 +23,9 @@
int ff_framehash_write_header(AVFormatContext *s)
{
int i;
+
+ if (s->nb_streams && !(s->streams[0]->codec->flags & CODEC_FLAG_BITEXACT))
+ avio_printf(s->pb, "#software: %s\n", LIBAVFORMAT_IDENT);
for (i = 0; i < s->nb_streams; i++) {
AVStream *st = s->streams[i];
avpriv_set_pts_info(st, 64, st->codec->time_base.num, st->codec->time_base.den);
diff --git a/libavformat/gif.c b/libavformat/gif.c
index f6e7625..e52498d 100644
--- a/libavformat/gif.c
+++ b/libavformat/gif.c
@@ -194,7 +194,7 @@
static const AVOption options[] = {
{ "loop", "Number of times to loop the output: -1 - no loop, 0 - infinite loop", OFFSET(loop),
AV_OPT_TYPE_INT, { .i64 = 0 }, -1, 65535, ENC },
- { "final_delay", "Force delay (in ms) after the last frame", OFFSET(last_delay),
+ { "final_delay", "Force delay (in centiseconds) after the last frame", OFFSET(last_delay),
AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 65535, ENC },
{ NULL },
};
diff --git a/libavformat/gxf.c b/libavformat/gxf.c
index e15d06a..c36479a 100644
--- a/libavformat/gxf.c
+++ b/libavformat/gxf.c
@@ -166,7 +166,7 @@
case 26: /* AVCi50 / AVCi100 (AVC Intra) */
case 29: /* AVCHD */
st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
- st->codec->codec_id = CODEC_ID_H264;
+ st->codec->codec_id = AV_CODEC_ID_H264;
st->need_parsing = AVSTREAM_PARSE_HEADERS;
break;
// timecode tracks:
diff --git a/libavformat/h261dec.c b/libavformat/h261dec.c
index 8d882ae..a1d6821 100644
--- a/libavformat/h261dec.c
+++ b/libavformat/h261dec.c
@@ -25,33 +25,30 @@
static int h261_probe(AVProbeData *p)
{
- uint32_t code= -1;
int i;
int valid_psc=0;
int invalid_psc=0;
int next_gn=0;
int src_fmt=0;
- GetBitContext gb;
- init_get_bits8(&gb, p->buf, p->buf_size);
+ for(i=0; i<p->buf_size; i++){
+ if ((AV_RB16(&p->buf[i]) - 1) < 0xFFU) {
+ int shift = av_log2_16bit(p->buf[i+1]);
+ uint32_t code = AV_RB64(&p->buf[FFMAX(i-1, 0)]) >> (24+shift);
+ if ((code & 0xffff0000) == 0x10000) {
+ int gn= (code>>12)&0xf;
+ if(!gn)
+ src_fmt= code&8;
+ if(gn != next_gn) invalid_psc++;
+ else valid_psc++;
- for(i=0; i<p->buf_size*8; i++){
- if ((code & 0x01ff0000) || !(code & 0xff00)) {
- code = (code<<8) + get_bits(&gb, 8);
- i += 7;
- } else
- code = (code<<1) + get_bits1(&gb);
- if ((code & 0xffff0000) == 0x10000) {
- int gn= (code>>12)&0xf;
- if(!gn)
- src_fmt= code&8;
- if(gn != next_gn) invalid_psc++;
- else valid_psc++;
-
- if(src_fmt){ // CIF
- next_gn= (gn+1 )%13;
- }else{ //QCIF
- next_gn= (gn+1+!!gn)% 7;
+ if(src_fmt){ // CIF
+ static const int lut[16]={1,2,3,4,5,6,7,8,9,10,11,12,0,16,16,16};
+ next_gn = lut[gn];
+ }else{ //QCIF
+ static const int lut[16]={1,3,16,5,16,0,16,16,16,16,16,16,16,16,16,16};
+ next_gn = lut[gn];
+ }
}
}
}
diff --git a/libavformat/hdsenc.c b/libavformat/hdsenc.c
new file mode 100644
index 0000000..08ae549
--- /dev/null
+++ b/libavformat/hdsenc.c
@@ -0,0 +1,589 @@
+/*
+ * Live HDS fragmenter
+ * Copyright (c) 2013 Martin Storsjo
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include <float.h>
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include "avformat.h"
+#include "internal.h"
+#include "os_support.h"
+
+#include "libavutil/avstring.h"
+#include "libavutil/base64.h"
+#include "libavutil/intreadwrite.h"
+#include "libavutil/mathematics.h"
+#include "libavutil/opt.h"
+
+typedef struct Fragment {
+ char file[1024];
+ int64_t start_time, duration;
+ int n;
+} Fragment;
+
+typedef struct OutputStream {
+ int bitrate;
+ int first_stream;
+ AVFormatContext *ctx;
+ int ctx_inited;
+ uint8_t iobuf[32768];
+ char temp_filename[1024];
+ int64_t frag_start_ts, last_ts;
+ AVIOContext *out;
+ int packets_written;
+ int nb_fragments, fragments_size, fragment_index;
+ Fragment **fragments;
+
+ int has_audio, has_video;
+
+ uint8_t *metadata;
+ int metadata_size;
+
+ uint8_t *extra_packets[2];
+ int extra_packet_sizes[2];
+ int nb_extra_packets;
+} OutputStream;
+
+typedef struct HDSContext {
+ const AVClass *class; /* Class for private options. */
+ int window_size;
+ int extra_window_size;
+ int min_frag_duration;
+ int remove_at_exit;
+
+ OutputStream *streams;
+ int nb_streams;
+} HDSContext;
+
+static int parse_header(OutputStream *os, const uint8_t *buf, int buf_size)
+{
+ if (buf_size < 13)
+ return AVERROR_INVALIDDATA;
+ if (memcmp(buf, "FLV", 3))
+ return AVERROR_INVALIDDATA;
+ buf += 13;
+ buf_size -= 13;
+ while (buf_size >= 11 + 4) {
+ int type = buf[0];
+ int size = AV_RB24(&buf[1]) + 11 + 4;
+ if (size > buf_size)
+ return AVERROR_INVALIDDATA;
+ if (type == 8 || type == 9) {
+ if (os->nb_extra_packets > FF_ARRAY_ELEMS(os->extra_packets))
+ return AVERROR_INVALIDDATA;
+ os->extra_packet_sizes[os->nb_extra_packets] = size;
+ os->extra_packets[os->nb_extra_packets] = av_malloc(size);
+ if (!os->extra_packets[os->nb_extra_packets])
+ return AVERROR(ENOMEM);
+ memcpy(os->extra_packets[os->nb_extra_packets], buf, size);
+ os->nb_extra_packets++;
+ } else if (type == 0x12) {
+ if (os->metadata)
+ return AVERROR_INVALIDDATA;
+ os->metadata_size = size - 11 - 4;
+ os->metadata = av_malloc(os->metadata_size);
+ if (!os->metadata)
+ return AVERROR(ENOMEM);
+ memcpy(os->metadata, buf + 11, os->metadata_size);
+ }
+ buf += size;
+ buf_size -= size;
+ }
+ if (!os->metadata)
+ return AVERROR_INVALIDDATA;
+ return 0;
+}
+
+static int hds_write(void *opaque, uint8_t *buf, int buf_size)
+{
+ OutputStream *os = opaque;
+ if (os->out) {
+ avio_write(os->out, buf, buf_size);
+ } else {
+ if (!os->metadata_size) {
+ int ret;
+ // Assuming the IO buffer is large enough to fit the
+ // FLV header and all metadata and extradata packets
+ if ((ret = parse_header(os, buf, buf_size)) < 0)
+ return ret;
+ }
+ }
+ return buf_size;
+}
+
+static void hds_free(AVFormatContext *s)
+{
+ HDSContext *c = s->priv_data;
+ int i, j;
+ if (!c->streams)
+ return;
+ for (i = 0; i < s->nb_streams; i++) {
+ OutputStream *os = &c->streams[i];
+ if (os->out)
+ avio_close(os->out);
+ os->out = NULL;
+ if (os->ctx && os->ctx_inited)
+ av_write_trailer(os->ctx);
+ if (os->ctx && os->ctx->pb)
+ av_free(os->ctx->pb);
+ if (os->ctx)
+ avformat_free_context(os->ctx);
+ av_free(os->metadata);
+ for (j = 0; j < os->nb_extra_packets; j++)
+ av_free(os->extra_packets[j]);
+ for (j = 0; j < os->nb_fragments; j++)
+ av_free(os->fragments[j]);
+ av_free(os->fragments);
+ }
+ av_freep(&c->streams);
+}
+
+static int write_manifest(AVFormatContext *s, int final)
+{
+ HDSContext *c = s->priv_data;
+ AVIOContext *out;
+ char filename[1024], temp_filename[1024];
+ int ret, i;
+ float duration = 0;
+
+ if (c->nb_streams > 0)
+ duration = c->streams[0].last_ts * av_q2d(s->streams[0]->time_base);
+
+ snprintf(filename, sizeof(filename), "%s/index.f4m", s->filename);
+ snprintf(temp_filename, sizeof(temp_filename), "%s/index.f4m.tmp", s->filename);
+ ret = avio_open2(&out, temp_filename, AVIO_FLAG_WRITE,
+ &s->interrupt_callback, NULL);
+ if (ret < 0) {
+ av_log(s, AV_LOG_ERROR, "Unable to open %s for writing\n", filename);
+ return ret;
+ }
+ avio_printf(out, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
+ avio_printf(out, "<manifest xmlns=\"http://ns.adobe.com/f4m/1.0\">\n");
+ avio_printf(out, "\t<id>%s</id>\n", av_basename(s->filename));
+ avio_printf(out, "\t<streamType>%s</streamType>\n",
+ final ? "recorded" : "live");
+ avio_printf(out, "\t<deliveryType>streaming</deliveryType>\n");
+ if (final)
+ avio_printf(out, "\t<duration>%f</duration>\n", duration);
+ for (i = 0; i < c->nb_streams; i++) {
+ OutputStream *os = &c->streams[i];
+ int b64_size = AV_BASE64_SIZE(os->metadata_size);
+ char *base64 = av_malloc(b64_size);
+ if (!base64) {
+ avio_close(out);
+ return AVERROR(ENOMEM);
+ }
+ av_base64_encode(base64, b64_size, os->metadata, os->metadata_size);
+
+ avio_printf(out, "\t<bootstrapInfo profile=\"named\" url=\"stream%d.abst\" id=\"bootstrap%d\" />\n", i, i);
+ avio_printf(out, "\t<media bitrate=\"%d\" url=\"stream%d\" bootstrapInfoId=\"bootstrap%d\">\n", os->bitrate/1000, i, i);
+ avio_printf(out, "\t\t<metadata>%s</metadata>\n", base64);
+ avio_printf(out, "\t</media>\n");
+ av_free(base64);
+ }
+ avio_printf(out, "</manifest>\n");
+ avio_flush(out);
+ avio_close(out);
+ rename(temp_filename, filename);
+ return 0;
+}
+
+static void update_size(AVIOContext *out, int64_t pos)
+{
+ int64_t end = avio_tell(out);
+ avio_seek(out, pos, SEEK_SET);
+ avio_wb32(out, end - pos);
+ avio_seek(out, end, SEEK_SET);
+}
+
+/* Note, the .abst files need to be served with the "binary/octet"
+ * mime type, otherwise at least the OSMF player can easily fail
+ * with "stream not found" when polling for the next fragment. */
+static int write_abst(AVFormatContext *s, OutputStream *os, int final)
+{
+ HDSContext *c = s->priv_data;
+ AVIOContext *out;
+ char filename[1024], temp_filename[1024];
+ int i, ret;
+ int64_t asrt_pos, afrt_pos;
+ int start = 0, fragments;
+ int index = s->streams[os->first_stream]->id;
+ int64_t cur_media_time = 0;
+ if (c->window_size)
+ start = FFMAX(os->nb_fragments - c->window_size, 0);
+ fragments = os->nb_fragments - start;
+ if (final)
+ cur_media_time = os->last_ts;
+ else if (os->nb_fragments)
+ cur_media_time = os->fragments[os->nb_fragments - 1]->start_time;
+
+ snprintf(filename, sizeof(filename),
+ "%s/stream%d.abst", s->filename, index);
+ snprintf(temp_filename, sizeof(temp_filename),
+ "%s/stream%d.abst.tmp", s->filename, index);
+ ret = avio_open2(&out, temp_filename, AVIO_FLAG_WRITE,
+ &s->interrupt_callback, NULL);
+ if (ret < 0) {
+ av_log(s, AV_LOG_ERROR, "Unable to open %s for writing\n", temp_filename);
+ return ret;
+ }
+ avio_wb32(out, 0); // abst size
+ avio_wl32(out, MKTAG('a','b','s','t'));
+ avio_wb32(out, 0); // version + flags
+ avio_wb32(out, os->fragment_index - 1); // BootstrapinfoVersion
+ avio_w8(out, final ? 0 : 0x20); // profile, live, update
+ avio_wb32(out, 1000); // timescale
+ avio_wb64(out, cur_media_time);
+ avio_wb64(out, 0); // SmpteTimeCodeOffset
+ avio_w8(out, 0); // MovieIdentifer (null string)
+ avio_w8(out, 0); // ServerEntryCount
+ avio_w8(out, 0); // QualityEntryCount
+ avio_w8(out, 0); // DrmData (null string)
+ avio_w8(out, 0); // MetaData (null string)
+ avio_w8(out, 1); // SegmentRunTableCount
+ asrt_pos = avio_tell(out);
+ avio_wb32(out, 0); // asrt size
+ avio_wl32(out, MKTAG('a','s','r','t'));
+ avio_wb32(out, 0); // version + flags
+ avio_w8(out, 0); // QualityEntryCount
+ avio_wb32(out, 1); // SegmentRunEntryCount
+ avio_wb32(out, 1); // FirstSegment
+ avio_wb32(out, final ? (os->fragment_index - 1) : 0xffffffff); // FragmentsPerSegment
+ update_size(out, asrt_pos);
+ avio_w8(out, 1); // FragmentRunTableCount
+ afrt_pos = avio_tell(out);
+ avio_wb32(out, 0); // afrt size
+ avio_wl32(out, MKTAG('a','f','r','t'));
+ avio_wb32(out, 0); // version + flags
+ avio_wb32(out, 1000); // timescale
+ avio_w8(out, 0); // QualityEntryCount
+ avio_wb32(out, fragments); // FragmentRunEntryCount
+ for (i = start; i < os->nb_fragments; i++) {
+ avio_wb32(out, os->fragments[i]->n);
+ avio_wb64(out, os->fragments[i]->start_time);
+ avio_wb32(out, os->fragments[i]->duration);
+ }
+ update_size(out, afrt_pos);
+ update_size(out, 0);
+ avio_close(out);
+ rename(temp_filename, filename);
+ return 0;
+}
+
+static int init_file(AVFormatContext *s, OutputStream *os, int64_t start_ts)
+{
+ int ret, i;
+ ret = avio_open2(&os->out, os->temp_filename, AVIO_FLAG_WRITE,
+ &s->interrupt_callback, NULL);
+ if (ret < 0)
+ return ret;
+ avio_wb32(os->out, 0);
+ avio_wl32(os->out, MKTAG('m','d','a','t'));
+ for (i = 0; i < os->nb_extra_packets; i++) {
+ AV_WB24(os->extra_packets[i] + 4, start_ts);
+ os->extra_packets[i][7] = (start_ts >> 24) & 0x7f;
+ avio_write(os->out, os->extra_packets[i], os->extra_packet_sizes[i]);
+ }
+ return 0;
+}
+
+static void close_file(OutputStream *os)
+{
+ int64_t pos = avio_tell(os->out);
+ avio_seek(os->out, 0, SEEK_SET);
+ avio_wb32(os->out, pos);
+ avio_flush(os->out);
+ avio_close(os->out);
+ os->out = NULL;
+}
+
+static int hds_write_header(AVFormatContext *s)
+{
+ HDSContext *c = s->priv_data;
+ int ret = 0, i;
+ AVOutputFormat *oformat;
+
+ mkdir(s->filename, 0777);
+
+ oformat = av_guess_format("flv", NULL, NULL);
+ if (!oformat) {
+ ret = AVERROR_MUXER_NOT_FOUND;
+ goto fail;
+ }
+
+ c->streams = av_mallocz(sizeof(*c->streams) * s->nb_streams);
+ if (!c->streams) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+
+ for (i = 0; i < s->nb_streams; i++) {
+ OutputStream *os = &c->streams[c->nb_streams];
+ AVFormatContext *ctx;
+ AVStream *st = s->streams[i];
+
+ if (!st->codec->bit_rate) {
+ av_log(s, AV_LOG_ERROR, "No bit rate set for stream %d\n", i);
+ ret = AVERROR(EINVAL);
+ goto fail;
+ }
+ if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
+ if (os->has_video) {
+ c->nb_streams++;
+ os++;
+ }
+ os->has_video = 1;
+ } else if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
+ if (os->has_audio) {
+ c->nb_streams++;
+ os++;
+ }
+ os->has_audio = 1;
+ } else {
+ av_log(s, AV_LOG_ERROR, "Unsupported stream type in stream %d\n", i);
+ ret = AVERROR(EINVAL);
+ goto fail;
+ }
+ os->bitrate += s->streams[i]->codec->bit_rate;
+
+ if (!os->ctx) {
+ os->first_stream = i;
+ ctx = avformat_alloc_context();
+ if (!ctx) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+ os->ctx = ctx;
+ ctx->oformat = oformat;
+ ctx->interrupt_callback = s->interrupt_callback;
+
+ ctx->pb = avio_alloc_context(os->iobuf, sizeof(os->iobuf),
+ AVIO_FLAG_WRITE, os,
+ NULL, hds_write, NULL);
+ if (!ctx->pb) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+ } else {
+ ctx = os->ctx;
+ }
+ s->streams[i]->id = c->nb_streams;
+
+ if (!(st = avformat_new_stream(ctx, NULL))) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+ avcodec_copy_context(st->codec, s->streams[i]->codec);
+ st->sample_aspect_ratio = s->streams[i]->sample_aspect_ratio;
+ }
+ if (c->streams[c->nb_streams].ctx)
+ c->nb_streams++;
+
+ for (i = 0; i < c->nb_streams; i++) {
+ OutputStream *os = &c->streams[i];
+ int j;
+ if ((ret = avformat_write_header(os->ctx, NULL)) < 0) {
+ goto fail;
+ }
+ os->ctx_inited = 1;
+ avio_flush(os->ctx->pb);
+ for (j = 0; j < os->ctx->nb_streams; j++)
+ s->streams[os->first_stream + j]->time_base = os->ctx->streams[j]->time_base;
+
+ snprintf(os->temp_filename, sizeof(os->temp_filename),
+ "%s/stream%d_temp", s->filename, i);
+ init_file(s, os, 0);
+
+ if (!os->has_video && c->min_frag_duration <= 0) {
+ av_log(s, AV_LOG_WARNING,
+ "No video stream in output stream %d and no min frag duration set\n", i);
+ ret = AVERROR(EINVAL);
+ }
+ os->fragment_index = 1;
+ write_abst(s, os, 0);
+ }
+ ret = write_manifest(s, 0);
+
+fail:
+ if (ret)
+ hds_free(s);
+ return ret;
+}
+
+static int add_fragment(OutputStream *os, const char *file,
+ int64_t start_time, int64_t duration)
+{
+ Fragment *frag;
+ if (duration == 0)
+ duration = 1;
+ if (os->nb_fragments >= os->fragments_size) {
+ int ret;
+ os->fragments_size = (os->fragments_size + 1) * 2;
+ if ((ret = av_reallocp_array(&os->fragments, os->fragments_size,
+ sizeof(*os->fragments))) < 0) {
+ os->fragments_size = 0;
+ os->nb_fragments = 0;
+ return ret;
+ }
+ }
+ frag = av_mallocz(sizeof(*frag));
+ if (!frag)
+ return AVERROR(ENOMEM);
+ av_strlcpy(frag->file, file, sizeof(frag->file));
+ frag->start_time = start_time;
+ frag->duration = duration;
+ frag->n = os->fragment_index;
+ os->fragments[os->nb_fragments++] = frag;
+ os->fragment_index++;
+ return 0;
+}
+
+static int hds_flush(AVFormatContext *s, OutputStream *os, int final,
+ int64_t end_ts)
+{
+ HDSContext *c = s->priv_data;
+ int i, ret = 0;
+ char target_filename[1024];
+ int index = s->streams[os->first_stream]->id;
+
+ if (!os->packets_written)
+ return 0;
+
+ avio_flush(os->ctx->pb);
+ os->packets_written = 0;
+ close_file(os);
+
+ snprintf(target_filename, sizeof(target_filename),
+ "%s/stream%dSeg1-Frag%d", s->filename, index, os->fragment_index);
+ rename(os->temp_filename, target_filename);
+ add_fragment(os, target_filename, os->frag_start_ts, end_ts - os->frag_start_ts);
+
+ if (!final) {
+ ret = init_file(s, os, end_ts);
+ if (ret < 0)
+ return ret;
+ }
+
+ if (c->window_size || (final && c->remove_at_exit)) {
+ int remove = os->nb_fragments - c->window_size - c->extra_window_size;
+ if (final && c->remove_at_exit)
+ remove = os->nb_fragments;
+ if (remove > 0) {
+ for (i = 0; i < remove; i++) {
+ unlink(os->fragments[i]->file);
+ av_free(os->fragments[i]);
+ }
+ os->nb_fragments -= remove;
+ memmove(os->fragments, os->fragments + remove,
+ os->nb_fragments * sizeof(*os->fragments));
+ }
+ }
+
+ if (ret >= 0)
+ ret = write_abst(s, os, final);
+ return ret;
+}
+
+static int hds_write_packet(AVFormatContext *s, AVPacket *pkt)
+{
+ HDSContext *c = s->priv_data;
+ AVStream *st = s->streams[pkt->stream_index];
+ OutputStream *os = &c->streams[s->streams[pkt->stream_index]->id];
+ int64_t end_dts = (os->fragment_index) * c->min_frag_duration;
+ int ret;
+
+ if (st->first_dts == AV_NOPTS_VALUE)
+ st->first_dts = pkt->dts;
+
+ if ((!os->has_video || st->codec->codec_type == AVMEDIA_TYPE_VIDEO) &&
+ av_compare_ts(pkt->dts - st->first_dts, st->time_base,
+ end_dts, AV_TIME_BASE_Q) >= 0 &&
+ pkt->flags & AV_PKT_FLAG_KEY && os->packets_written) {
+
+ if ((ret = hds_flush(s, os, 0, pkt->dts)) < 0)
+ return ret;
+ }
+
+ // Note, these fragment start timestamps, that represent a whole
+ // OutputStream, assume all streams in it have the same time base.
+ if (!os->packets_written)
+ os->frag_start_ts = pkt->dts;
+ os->last_ts = pkt->dts;
+
+ os->packets_written++;
+ return ff_write_chained(os->ctx, pkt->stream_index - os->first_stream, pkt, s);
+}
+
+static int hds_write_trailer(AVFormatContext *s)
+{
+ HDSContext *c = s->priv_data;
+ int i;
+
+ for (i = 0; i < c->nb_streams; i++)
+ hds_flush(s, &c->streams[i], 1, c->streams[i].last_ts);
+ write_manifest(s, 1);
+
+ if (c->remove_at_exit) {
+ char filename[1024];
+ snprintf(filename, sizeof(filename), "%s/index.f4m", s->filename);
+ unlink(filename);
+ for (i = 0; i < c->nb_streams; i++) {
+ snprintf(filename, sizeof(filename), "%s/stream%d.abst", s->filename, i);
+ unlink(filename);
+ }
+ rmdir(s->filename);
+ }
+
+ hds_free(s);
+ return 0;
+}
+
+#define OFFSET(x) offsetof(HDSContext, x)
+#define E AV_OPT_FLAG_ENCODING_PARAM
+static const AVOption options[] = {
+ { "window_size", "number of fragments kept in the manifest", OFFSET(window_size), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, E },
+ { "extra_window_size", "number of fragments kept outside of the manifest before removing from disk", OFFSET(extra_window_size), AV_OPT_TYPE_INT, { .i64 = 5 }, 0, INT_MAX, E },
+ { "min_frag_duration", "minimum fragment duration (in microseconds)", OFFSET(min_frag_duration), AV_OPT_TYPE_INT64, { .i64 = 10000000 }, 0, INT_MAX, E },
+ { "remove_at_exit", "remove all fragments when finished", OFFSET(remove_at_exit), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, E },
+ { NULL },
+};
+
+static const AVClass hds_class = {
+ .class_name = "HDS muxer",
+ .item_name = av_default_item_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
+AVOutputFormat ff_hds_muxer = {
+ .name = "hds",
+ .long_name = NULL_IF_CONFIG_SMALL("HDS Muxer"),
+ .priv_data_size = sizeof(HDSContext),
+ .audio_codec = AV_CODEC_ID_AAC,
+ .video_codec = AV_CODEC_ID_H264,
+ .flags = AVFMT_GLOBALHEADER | AVFMT_NOFILE,
+ .write_header = hds_write_header,
+ .write_packet = hds_write_packet,
+ .write_trailer = hds_write_trailer,
+ .priv_class = &hds_class,
+};
diff --git a/libavformat/hevcdec.c b/libavformat/hevcdec.c
index 51e1504..e36a051 100644
--- a/libavformat/hevcdec.c
+++ b/libavformat/hevcdec.c
@@ -1,5 +1,5 @@
/*
- * RAW H.265 video demuxer
+ * RAW HEVC video demuxer
* Copyright (c) 2013 Dirk Farin <dirk.farin@gmail.com>
*
* This file is part of FFmpeg.
@@ -19,42 +19,46 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include "libavcodec/hevc.h"
+
#include "avformat.h"
#include "rawdec.h"
static int hevc_probe(AVProbeData *p)
{
- uint32_t code= -1;
- int vps=0, sps=0, pps=0, idr=0;
+ uint32_t code = -1;
+ int vps = 0, sps = 0, pps = 0, irap = 0;
int i;
- for(i=0; i<p->buf_size-1; i++){
- code = (code<<8) + p->buf[i];
+ for (i = 0; i < p->buf_size - 1; i++) {
+ code = (code << 8) + p->buf[i];
if ((code & 0xffffff00) == 0x100) {
- uint8_t nal2 = p->buf[i+1];
- int type = (code & 0x7E)>>1;
+ uint8_t nal2 = p->buf[i + 1];
+ int type = (code & 0x7E) >> 1;
- if (code & 0x81) // forbidden and reserved zero bits
- return 0;
+ if (code & 0x81) // forbidden and reserved zero bits
+ return 0;
- if (nal2 & 0xf8) // reserved zero
- return 0;
+ if (nal2 & 0xf8) // reserved zero
+ return 0;
- switch (type) {
- case 32: vps++; break;
- case 33: sps++; break;
- case 34: pps++; break;
- case 19:
- case 20: idr++; break;
- }
+ switch (type) {
+ case NAL_VPS: vps++; break;
+ case NAL_SPS: sps++; break;
+ case NAL_PPS: pps++; break;
+ case NAL_BLA_N_LP:
+ case NAL_BLA_W_LP:
+ case NAL_BLA_W_RADL:
+ case NAL_CRA_NUT:
+ case NAL_IDR_N_LP:
+ case NAL_IDR_W_RADL: irap++; break;
+ }
}
}
- // printf("vps=%d, sps=%d, pps=%d, idr=%d\n", vps, sps, pps, idr);
-
- if (vps && sps && pps && idr)
+ if (vps && sps && pps && irap)
return AVPROBE_SCORE_EXTENSION + 1; // 1 more than .mpg
return 0;
}
-FF_DEF_RAWVIDEO_DEMUXER(hevc , "raw HEVC video", hevc_probe, "h265,265,hevc", AV_CODEC_ID_HEVC)
+FF_DEF_RAWVIDEO_DEMUXER(hevc, "raw HEVC video", hevc_probe, "hevc,h265,265", AV_CODEC_ID_HEVC)
diff --git a/libavformat/hls.c b/libavformat/hls.c
index 231f630..471a62d 100644
--- a/libavformat/hls.c
+++ b/libavformat/hls.c
@@ -105,6 +105,7 @@
AVIOInterruptCB *interrupt_callback;
char *user_agent; ///< holds HTTP user agent set as an AVOption to the HTTP protocol context
char *cookies; ///< holds HTTP cookie values set in either the initial response or as an AVOption to the HTTP protocol context
+ char *headers; ///< holds HTTP headers set as an AVOption to the HTTP protocol context
} HLSContext;
static int read_chomp_line(AVIOContext *s, char *buf, int maxlen)
@@ -215,6 +216,7 @@
char line[MAX_URL_SIZE];
const char *ptr;
int close_in = 0;
+ uint8_t *new_url = NULL;
if (!in) {
AVDictionary *opts = NULL;
@@ -225,6 +227,7 @@
// broker prior HTTP options that should be consistent across requests
av_dict_set(&opts, "user-agent", c->user_agent, 0);
av_dict_set(&opts, "cookies", c->cookies, 0);
+ av_dict_set(&opts, "headers", c->headers, 0);
ret = avio_open2(&in, url, AVIO_FLAG_READ,
c->interrupt_callback, &opts);
@@ -233,6 +236,9 @@
return ret;
}
+ if (av_opt_get(in, "location", AV_OPT_SEARCH_CHILDREN, &new_url) >= 0)
+ url = new_url;
+
read_chomp_line(in, line, sizeof(line));
if (strcmp(line, "#EXTM3U")) {
ret = AVERROR_INVALIDDATA;
@@ -333,6 +339,7 @@
var->last_load_time = av_gettime();
fail:
+ av_free(new_url);
if (close_in)
avio_close(in);
return ret;
@@ -347,6 +354,7 @@
// broker prior HTTP options that should be consistent across requests
av_dict_set(&opts, "user-agent", c->user_agent, 0);
av_dict_set(&opts, "cookies", c->cookies, 0);
+ av_dict_set(&opts, "headers", c->headers, 0);
av_dict_set(&opts, "seekable", "0", 0);
if (seg->key_type == KEY_NONE) {
@@ -495,6 +503,12 @@
av_opt_get(u->priv_data, "cookies", 0, (uint8_t**)&(c->cookies));
if (c->cookies && !strlen(c->cookies))
av_freep(&c->cookies);
+
+ // get the previous headers & set back to null if string size is zero
+ av_freep(&c->headers);
+ av_opt_get(u->priv_data, "headers", 0, (uint8_t**)&(c->headers));
+ if (c->headers && !strlen(c->headers))
+ av_freep(&c->headers);
}
if ((ret = parse_playlist(c, s->filename, NULL, s->pb)) < 0)
@@ -710,7 +724,8 @@
/* Check if this stream still is on an earlier segment number, or
* has the packet with the lowest dts */
if (var->pkt.data) {
- struct variant *minvar = c->variants[minvariant];
+ struct variant *minvar = minvariant < 0 ?
+ NULL : c->variants[minvariant];
if (minvariant < 0 || var->cur_seq_no < minvar->cur_seq_no) {
minvariant = i;
} else if (var->cur_seq_no == minvar->cur_seq_no) {
diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
index dcd53e5..b9bf605 100644
--- a/libavformat/hlsenc.c
+++ b/libavformat/hlsenc.c
@@ -20,6 +20,7 @@
*/
#include <float.h>
+#include <stdint.h>
#include "libavutil/mathematics.h"
#include "libavutil/parseutils.h"
diff --git a/libavformat/hnm.c b/libavformat/hnm.c
new file mode 100644
index 0000000..47a1808
--- /dev/null
+++ b/libavformat/hnm.c
@@ -0,0 +1,204 @@
+/*
+ * Cryo Interactive Entertainment HNM4 demuxer
+ *
+ * Copyright (c) 2012 David Kment
+ *
+ * This file is part of FFmpeg .
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg ; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "libavutil/intreadwrite.h"
+#include "avformat.h"
+#include "internal.h"
+
+#define HNM4_TAG MKTAG('H', 'N', 'M', '4')
+
+#define HNM4_SAMPLE_RATE 22050
+#define HNM4_FRAME_FPS 24
+
+#define HNM4_CHUNK_ID_PL 19536
+#define HNM4_CHUNK_ID_IZ 23113
+#define HNM4_CHUNK_ID_IU 21833
+#define HNM4_CHUNK_ID_SD 17491
+
+typedef struct Hnm4DemuxContext {
+ uint8_t version;
+ uint16_t width;
+ uint16_t height;
+ uint32_t filesize;
+ uint32_t frames;
+ uint32_t taboffset;
+ uint16_t bits;
+ uint16_t channels;
+ uint32_t framesize;
+ uint32_t currentframe;
+ int64_t pts;
+ uint32_t superchunk_remaining;
+ AVPacket vpkt;
+} Hnm4DemuxContext;
+
+static int hnm_probe(AVProbeData *p)
+{
+ if (p->buf_size < 4)
+ return 0;
+
+ // check for HNM4 header.
+ // currently only HNM v4/v4A is supported
+ if (AV_RL32(&p->buf[0]) == HNM4_TAG)
+ return AVPROBE_SCORE_MAX;
+
+ return 0;
+}
+
+static int hnm_read_header(AVFormatContext *s)
+{
+ Hnm4DemuxContext *hnm = s->priv_data;
+ AVIOContext *pb = s->pb;
+ AVStream *vst;
+
+ /* default context members */
+ hnm->pts = 0;
+ av_init_packet(&hnm->vpkt);
+ hnm->vpkt.data = NULL;
+ hnm->vpkt.size = 0;
+
+ hnm->superchunk_remaining = 0;
+
+ avio_skip(pb, 8);
+ hnm->width = avio_rl16(pb);
+ hnm->height = avio_rl16(pb);
+ hnm->filesize = avio_rl32(pb);
+ hnm->frames = avio_rl32(pb);
+ hnm->taboffset = avio_rl32(pb);
+ hnm->bits = avio_rl16(pb);
+ hnm->channels = avio_rl16(pb);
+ hnm->framesize = avio_rl32(pb);
+ avio_skip(pb, 32);
+
+ hnm->currentframe = 0;
+
+ if (hnm->width < 320 || hnm->width > 640 ||
+ hnm->height < 150 || hnm->height > 480) {
+ av_log(s, AV_LOG_ERROR,
+ "invalid resolution: %ux%u\n", hnm->width, hnm->height);
+ return AVERROR_INVALIDDATA;
+ }
+
+ // TODO: find a better way to detect HNM4A
+ if (hnm->width == 640)
+ hnm->version = 0x4a;
+ else
+ hnm->version = 0x40;
+
+ if (!(vst = avformat_new_stream(s, NULL)))
+ return AVERROR(ENOMEM);
+
+ vst->codec->codec_type = AVMEDIA_TYPE_VIDEO;
+ vst->codec->codec_id = AV_CODEC_ID_HNM4_VIDEO;
+ vst->codec->codec_tag = 0;
+ vst->codec->width = hnm->width;
+ vst->codec->height = hnm->height;
+ vst->codec->extradata = av_mallocz(1);
+
+ vst->codec->extradata_size = 1;
+ memcpy(vst->codec->extradata, &hnm->version, 1);
+
+ vst->start_time = 0;
+
+ avpriv_set_pts_info(vst, 33, 1, HNM4_FRAME_FPS);
+
+ return 0;
+}
+
+static int hnm_read_packet(AVFormatContext *s, AVPacket *pkt)
+{
+ Hnm4DemuxContext *hnm = s->priv_data;
+ AVIOContext *pb = s->pb;
+ int ret = 0;
+
+ uint32_t superchunk_size, chunk_size;
+ uint16_t chunk_id;
+
+ if (hnm->currentframe == hnm->frames || pb->eof_reached)
+ return AVERROR_EOF;
+
+ if (hnm->superchunk_remaining == 0) {
+ /* parse next superchunk */
+ superchunk_size = avio_rl24(pb);
+ avio_skip(pb, 1);
+
+ hnm->superchunk_remaining = superchunk_size - 4;
+ }
+
+ chunk_size = avio_rl24(pb);
+ avio_skip(pb, 1);
+ chunk_id = avio_rl16(pb);
+ avio_skip(pb, 2);
+
+ if (chunk_size > hnm->superchunk_remaining || !chunk_size) {
+ av_log(s, AV_LOG_ERROR, "invalid chunk size: %u, offset: %u\n",
+ chunk_size, (int) avio_tell(pb));
+ avio_skip(pb, hnm->superchunk_remaining - 8);
+ hnm->superchunk_remaining = 0;
+ }
+
+ switch (chunk_id) {
+ case HNM4_CHUNK_ID_PL:
+ case HNM4_CHUNK_ID_IZ:
+ case HNM4_CHUNK_ID_IU:
+ avio_seek(pb, -8, SEEK_CUR);
+ ret += av_get_packet(pb, pkt, chunk_size);
+ hnm->superchunk_remaining -= chunk_size;
+ if (chunk_id == HNM4_CHUNK_ID_IZ || chunk_id == HNM4_CHUNK_ID_IU)
+ hnm->currentframe++;
+ break;
+
+ case HNM4_CHUNK_ID_SD:
+ avio_skip(pb, chunk_size - 8);
+ hnm->superchunk_remaining -= chunk_size;
+ break;
+
+ default:
+ av_log(s, AV_LOG_WARNING, "unknown chunk found: %d, offset: %d\n",
+ chunk_id, (int) avio_tell(pb));
+ avio_skip(pb, chunk_size - 8);
+ hnm->superchunk_remaining -= chunk_size;
+ break;
+ }
+
+ return ret;
+}
+
+static int hnm_read_close(AVFormatContext *s)
+{
+ Hnm4DemuxContext *hnm = s->priv_data;
+
+ if (hnm->vpkt.size > 0)
+ av_free_packet(&hnm->vpkt);
+
+ return 0;
+}
+
+AVInputFormat ff_hnm_demuxer = {
+ .name = "hnm",
+ .long_name = NULL_IF_CONFIG_SMALL("Cryo HNM v4"),
+ .priv_data_size = sizeof(Hnm4DemuxContext),
+ .read_probe = hnm_probe,
+ .read_header = hnm_read_header,
+ .read_packet = hnm_read_packet,
+ .read_close = hnm_read_close,
+ .flags = AVFMT_NO_BYTE_SEEK | AVFMT_NOGENSEARCH | AVFMT_NOBINSEARCH
+};
diff --git a/libavformat/http.c b/libavformat/http.c
index 7e8d609..0619e2a 100644
--- a/libavformat/http.c
+++ b/libavformat/http.c
@@ -55,7 +55,7 @@
int64_t off, filesize;
int icy_data_read; ///< how much data was read since last ICY metadata packet
int icy_metaint; ///< after how many bytes of read data a new metadata packet will be found
- char location[MAX_URL_SIZE];
+ char *location;
HTTPAuthState auth_state;
HTTPAuthState proxy_auth_state;
char *headers;
@@ -68,6 +68,7 @@
uint8_t *post_data;
int post_datalen;
int is_akamai;
+ int is_mediagateway;
char *mime_type;
char *cookies; ///< holds newline (\n) delimited Set-Cookie header field values (without the "Set-Cookie: " field name)
int icy;
@@ -95,14 +96,15 @@
{"multiple_requests", "use persistent connections", OFFSET(multiple_requests), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, D|E },
{"post_data", "set custom HTTP post data", OFFSET(post_data), AV_OPT_TYPE_BINARY, .flags = D|E },
{"mime_type", "set MIME type", OFFSET(mime_type), AV_OPT_TYPE_STRING, {0}, 0, 0, 0 },
-{"cookies", "set cookies to be sent in applicable future requests, use newline delimited Set-Cookie HTTP field value syntax", OFFSET(cookies), AV_OPT_TYPE_STRING, {0}, 0, 0, 0 },
+{"cookies", "set cookies to be sent in applicable future requests, use newline delimited Set-Cookie HTTP field value syntax", OFFSET(cookies), AV_OPT_TYPE_STRING, {0}, 0, 0, D },
{"icy", "request ICY metadata", OFFSET(icy), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, D },
{"icy_metadata_headers", "return ICY metadata headers", OFFSET(icy_metadata_headers), AV_OPT_TYPE_STRING, {0}, 0, 0, 0 },
{"icy_metadata_packet", "return current ICY metadata packet", OFFSET(icy_metadata_packet), AV_OPT_TYPE_STRING, {0}, 0, 0, 0 },
{"auth_type", "HTTP authentication type", OFFSET(auth_state.auth_type), AV_OPT_TYPE_INT, {.i64 = HTTP_AUTH_NONE}, HTTP_AUTH_NONE, HTTP_AUTH_BASIC, D|E, "auth_type" },
{"none", "No auth method set, autodetect", 0, AV_OPT_TYPE_CONST, {.i64 = HTTP_AUTH_NONE}, 0, 0, D|E, "auth_type" },
{"basic", "HTTP basic authentication", 0, AV_OPT_TYPE_CONST, {.i64 = HTTP_AUTH_BASIC}, 0, 0, D|E, "auth_type" },
-{"send_expect_100", "Force sending an Expect: 100-continue header for POST", OFFSET(send_expect_100), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, E, "auth_type" },
+{"send_expect_100", "Force sending an Expect: 100-continue header for POST", OFFSET(send_expect_100), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, E },
+{"location", "The actual location of the data received", OFFSET(location), AV_OPT_TYPE_STRING, { 0 }, 0, 0, D|E },
{NULL}
};
#define HTTP_CLASS(flavor)\
@@ -235,7 +237,10 @@
s->off = 0;
s->icy_data_read = 0;
- av_strlcpy(s->location, uri, sizeof(s->location));
+ av_free(s->location);
+ s->location = av_strdup(uri);
+ if (!s->location)
+ return AVERROR(ENOMEM);
av_dict_copy(&options, s->chained_options, 0);
ret = http_open_cnx(h, &options);
@@ -255,7 +260,9 @@
h->is_streamed = 1;
s->filesize = -1;
- av_strlcpy(s->location, uri, sizeof(s->location));
+ s->location = av_strdup(uri);
+ if (!s->location)
+ return AVERROR(ENOMEM);
if (options)
av_dict_copy(&s->chained_options, *options, 0);
@@ -316,7 +323,6 @@
{
HTTPContext *s = h->priv_data;
char *tag, *p, *end;
- char redirected_location[MAX_URL_SIZE];
/* end of header */
if (line[0] == '\0') {
@@ -332,7 +338,7 @@
p++;
s->http_code = strtol(p, &end, 10);
- av_dlog(NULL, "http_code=%d\n", s->http_code);
+ av_log(h, AV_LOG_DEBUG, "http_code=%d\n", s->http_code);
/* error codes are 4xx and 5xx, but regard 401 as a success, so we
* don't abort until all headers have been parsed. */
@@ -356,8 +362,14 @@
while (av_isspace(*p))
p++;
if (!av_strcasecmp(tag, "Location")) {
- ff_make_absolute_url(redirected_location, sizeof(redirected_location), s->location, p);
- av_strlcpy(s->location, redirected_location, sizeof(s->location));
+ char redirected_location[MAX_URL_SIZE], *new_loc;
+ ff_make_absolute_url(redirected_location, sizeof(redirected_location),
+ s->location, p);
+ new_loc = av_strdup(redirected_location);
+ if (!new_loc)
+ return AVERROR(ENOMEM);
+ av_free(s->location);
+ s->location = new_loc;
*new_location = 1;
} else if (!av_strcasecmp (tag, "Content-Length") && s->filesize == -1) {
s->filesize = strtoll(p, NULL, 10);
@@ -386,8 +398,12 @@
} else if (!av_strcasecmp (tag, "Connection")) {
if (!strcmp(p, "close"))
s->willclose = 1;
- } else if (!av_strcasecmp (tag, "Server") && !av_strcasecmp (p, "AkamaiGHost")) {
- s->is_akamai = 1;
+ } else if (!av_strcasecmp (tag, "Server")) {
+ if (!av_strcasecmp (p, "AkamaiGHost")) {
+ s->is_akamai = 1;
+ } else if (!av_strncasecmp (p, "MediaGateway", 12)) {
+ s->is_mediagateway = 1;
+ }
} else if (!av_strcasecmp (tag, "Content-Type")) {
av_free(s->mime_type); s->mime_type = av_strdup(p);
} else if (!av_strcasecmp (tag, "Set-Cookie")) {
@@ -437,7 +453,6 @@
// the header at all if this is the case).
} else {
av_log(h, AV_LOG_WARNING, "Unknown content coding: %s\n", p);
- return AVERROR(ENOSYS);
}
}
}
@@ -561,7 +576,7 @@
if ((err = http_get_line(s, line, sizeof(line))) < 0)
return err;
- av_dlog(NULL, "header='%s'\n", line);
+ av_log(h, AV_LOG_DEBUG, "header='%s'\n", line);
err = process_line(h, line, s->line_count, new_location);
if (err < 0)
@@ -571,6 +586,9 @@
s->line_count++;
}
+ if (s->seekable == -1 && s->is_mediagateway && s->filesize == 2000000000)
+ h->is_streamed = 1; /* we can in fact _not_ seek */
+
return err;
}
@@ -684,6 +702,9 @@
av_freep(&authstr);
av_freep(&proxyauthstr);
+
+ av_log(h, AV_LOG_DEBUG, "request: %s\n", s->buffer);
+
if ((err = ffurl_write(s->hd, s->buffer, strlen(s->buffer))) < 0)
return err;
diff --git a/libavformat/icodec.c b/libavformat/icodec.c
index fa308da..4c038e9 100644
--- a/libavformat/icodec.c
+++ b/libavformat/icodec.c
@@ -45,7 +45,7 @@
static int probe(AVProbeData *p)
{
if (AV_RL16(p->buf) == 0 && AV_RL16(p->buf + 2) == 1 && AV_RL16(p->buf + 4))
- return AVPROBE_SCORE_MAX / 3;
+ return AVPROBE_SCORE_MAX / 4;
return 0;
}
diff --git a/libavformat/idcin.c b/libavformat/idcin.c
index 9671fca..f2d5548 100644
--- a/libavformat/idcin.c
+++ b/libavformat/idcin.c
@@ -94,6 +94,8 @@
static int idcin_probe(AVProbeData *p)
{
unsigned int number, sample_rate;
+ unsigned int w, h;
+ int i;
/*
* This is what you could call a "probabilistic" file check: id CIN
@@ -108,17 +110,17 @@
/* check we have enough data to do all checks, otherwise the
0-padding may cause a wrong recognition */
- if (p->buf_size < 20)
+ if (p->buf_size < 20 + HUFFMAN_TABLE_SIZE + 12)
return 0;
/* check the video width */
- number = AV_RL32(&p->buf[0]);
- if ((number == 0) || (number > 1024))
+ w = AV_RL32(&p->buf[0]);
+ if ((w == 0) || (w > 1024))
return 0;
/* check the video height */
- number = AV_RL32(&p->buf[4]);
- if ((number == 0) || (number > 1024))
+ h = AV_RL32(&p->buf[4]);
+ if ((h == 0) || (h > 1024))
return 0;
/* check the audio sample rate */
@@ -136,6 +138,13 @@
if (number > 2 || sample_rate && !number)
return 0;
+ i = 20 + HUFFMAN_TABLE_SIZE;
+ if (AV_RL32(&p->buf[i]) == 1)
+ i += 768;
+
+ if (i+12 > p->buf_size || AV_RL32(&p->buf[i+8]) != w*h)
+ return 1;
+
/* return half certainty since this check is a bit sketchy */
return AVPROBE_SCORE_EXTENSION;
}
diff --git a/libavformat/img2enc.c b/libavformat/img2enc.c
index 8adf352..3529e12 100644
--- a/libavformat/img2enc.c
+++ b/libavformat/img2enc.c
@@ -21,6 +21,7 @@
*/
#include "libavutil/intreadwrite.h"
+#include "libavutil/avassert.h"
#include "libavutil/avstring.h"
#include "libavutil/log.h"
#include "libavutil/opt.h"
@@ -37,6 +38,7 @@
char path[1024];
int update;
int use_strftime;
+ const char *muxer;
} VideoMuxData;
static int write_header(AVFormatContext *s)
@@ -44,7 +46,6 @@
VideoMuxData *img = s->priv_data;
AVStream *st = s->streams[0];
const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(st->codec->pix_fmt);
- const char *str;
av_strlcpy(img->path, s->filename, sizeof(img->path));
@@ -54,14 +55,17 @@
else
img->is_pipe = 1;
- str = strrchr(img->path, '.');
- img->split_planes = str
- && !av_strcasecmp(str + 1, "y")
- && s->nb_streams == 1
- && st->codec->codec_id == AV_CODEC_ID_RAWVIDEO
- && desc
- &&(desc->flags & AV_PIX_FMT_FLAG_PLANAR)
- && desc->nb_components >= 3;
+ if (st->codec->codec_id == AV_CODEC_ID_GIF) {
+ img->muxer = "gif";
+ } else if (st->codec->codec_id == AV_CODEC_ID_RAWVIDEO) {
+ const char *str = strrchr(img->path, '.');
+ img->split_planes = str
+ && !av_strcasecmp(str + 1, "y")
+ && s->nb_streams == 1
+ && desc
+ &&(desc->flags & AV_PIX_FMT_FLAG_PLANAR)
+ && desc->nb_components >= 3;
+ }
return 0;
}
@@ -102,7 +106,7 @@
if (!img->split_planes || i+1 >= desc->nb_components)
break;
- filename[strlen(filename) - 1] = ((int[]){'U','V','A','x'})[i];
+ filename[strlen(filename) - 1] = "UVAx"[i];
}
} else {
pb[0] = s->pb;
@@ -124,6 +128,37 @@
avio_write(pb[3], pkt->data + ysize + 2*usize, ysize);
avio_close(pb[3]);
}
+ } else if (img->muxer) {
+ int ret;
+ AVStream *st;
+ AVPacket pkt2 = {0};
+ AVFormatContext *fmt = NULL;
+
+ av_assert0(!img->split_planes);
+
+ ret = avformat_alloc_output_context2(&fmt, NULL, img->muxer, s->filename);
+ if (ret < 0)
+ return ret;
+ st = avformat_new_stream(fmt, NULL);
+ if (!st) {
+ avformat_free_context(fmt);
+ return AVERROR(ENOMEM);
+ }
+ st->id = pkt->stream_index;
+
+ fmt->pb = pb[0];
+ if ((ret = av_copy_packet(&pkt2, pkt)) < 0 ||
+ (ret = av_dup_packet(&pkt2)) < 0 ||
+ (ret = avcodec_copy_context(st->codec, s->streams[0]->codec)) < 0 ||
+ (ret = avformat_write_header(fmt, NULL)) < 0 ||
+ (ret = av_interleaved_write_frame(fmt, &pkt2)) < 0 ||
+ (ret = av_write_trailer(fmt)) < 0) {
+ av_free_packet(&pkt2);
+ avformat_free_context(fmt);
+ return ret;
+ }
+ av_free_packet(&pkt2);
+ avformat_free_context(fmt);
} else {
avio_write(pb[0], pkt->data, pkt->size);
}
diff --git a/libavformat/internal.h b/libavformat/internal.h
index 36ee4c0..edc6a11 100644
--- a/libavformat/internal.h
+++ b/libavformat/internal.h
@@ -357,9 +357,10 @@
AVRational ff_choose_timebase(AVFormatContext *s, AVStream *st, int min_precission);
/**
- * Generate standard extradata for AVC-Intra based on width/height and field order.
+ * Generate standard extradata for AVC-Intra based on width/height and field
+ * order.
*/
-void ff_generate_avci_extradata(AVStream *st);
+int ff_generate_avci_extradata(AVStream *st);
/**
* Allocate extradata with additional FF_INPUT_BUFFER_PADDING_SIZE at end
@@ -370,4 +371,14 @@
*/
int ff_alloc_extradata(AVCodecContext *avctx, int size);
+/**
+ * add frame for rfps calculation.
+ *
+ * @param dts timestamp of the i-th frame
+ * @return 0 if OK, AVERROR_xxx on error
+ */
+int ff_rfps_add_frame(AVFormatContext *ic, AVStream *st, int64_t dts);
+
+void ff_rfps_calculate(AVFormatContext *ic);
+
#endif /* AVFORMAT_INTERNAL_H */
diff --git a/libavformat/ipmovie.c b/libavformat/ipmovie.c
index 676363b..368c059 100644
--- a/libavformat/ipmovie.c
+++ b/libavformat/ipmovie.c
@@ -376,7 +376,7 @@
case OPCODE_INIT_VIDEO_BUFFERS:
av_dlog(NULL, "initialize video buffers\n");
- if ((opcode_version > 2) || (opcode_size > 8)) {
+ if ((opcode_version > 2) || (opcode_size > 8) || opcode_size < 4) {
av_dlog(NULL, "bad init_video_buffers opcode\n");
chunk_type = CHUNK_BAD;
break;
diff --git a/libavformat/isom.c b/libavformat/isom.c
index 8cbf70b..de9d20c 100644
--- a/libavformat/isom.c
+++ b/libavformat/isom.c
@@ -151,6 +151,9 @@
{ AV_CODEC_ID_RAWVIDEO, MKTAG('W', 'R', 'A', 'W') },
+ { AV_CODEC_ID_HEVC, MKTAG('h', 'v', 'c', '1') }, /* HEVC/H.265 which indicates parameter sets shall not be in ES */
+ { AV_CODEC_ID_HEVC, MKTAG('h', 'e', 'v', '1') }, /* HEVC/H.265 which indicates parameter sets may be in ES */
+
{ AV_CODEC_ID_H264, MKTAG('a', 'v', 'c', '1') }, /* AVC-1/H.264 */
{ AV_CODEC_ID_H264, MKTAG('a', 'i', '5', 'p') }, /* AVC-Intra 50M 720p24/30/60 */
{ AV_CODEC_ID_H264, MKTAG('a', 'i', '5', 'q') }, /* AVC-Intra 50M 720p25/50 */
@@ -164,6 +167,7 @@
{ AV_CODEC_ID_H264, MKTAG('a', 'i', '1', '3') }, /* AVC-Intra 100M 1080p24/30/60 */
{ AV_CODEC_ID_H264, MKTAG('a', 'i', '1', '5') }, /* AVC-Intra 100M 1080i50 */
{ AV_CODEC_ID_H264, MKTAG('a', 'i', '1', '6') }, /* AVC-Intra 100M 1080i60 */
+ { AV_CODEC_ID_H264, MKTAG('a', 'i', 'v', 'x') }, /* XAVC 4:2:2 10bit */
{ AV_CODEC_ID_H264, MKTAG('A', 'V', 'i', 'n') }, /* AVC-Intra with implicit SPS/PPS */
{ AV_CODEC_ID_MPEG1VIDEO, MKTAG('m', '1', 'v', '1') }, /* Apple MPEG-1 Camcorder */
@@ -280,6 +284,7 @@
{ AV_CODEC_ID_PCM_MULAW, MKTAG('u', 'l', 'a', 'w') },
{ AV_CODEC_ID_PCM_S16BE, MKTAG('t', 'w', 'o', 's') },
{ AV_CODEC_ID_PCM_S16LE, MKTAG('s', 'o', 'w', 't') },
+ { AV_CODEC_ID_PCM_S16BE, MKTAG('l', 'p', 'c', 'm') },
{ AV_CODEC_ID_PCM_S16LE, MKTAG('l', 'p', 'c', 'm') },
{ AV_CODEC_ID_PCM_S24BE, MKTAG('i', 'n', '2', '4') },
{ AV_CODEC_ID_PCM_S24LE, MKTAG('i', 'n', '2', '4') },
diff --git a/libavformat/isom.h b/libavformat/isom.h
index 828e500..2834b11 100644
--- a/libavformat/isom.h
+++ b/libavformat/isom.h
@@ -207,6 +207,22 @@
#define MOV_TKHD_FLAG_IN_PREVIEW 0x0004
#define MOV_TKHD_FLAG_IN_POSTER 0x0008
+#define TAG_IS_AVCI(tag) \
+ ((tag) == MKTAG('a', 'i', '5', 'p') || \
+ (tag) == MKTAG('a', 'i', '5', 'q') || \
+ (tag) == MKTAG('a', 'i', '5', '2') || \
+ (tag) == MKTAG('a', 'i', '5', '3') || \
+ (tag) == MKTAG('a', 'i', '5', '5') || \
+ (tag) == MKTAG('a', 'i', '5', '6') || \
+ (tag) == MKTAG('a', 'i', '1', 'p') || \
+ (tag) == MKTAG('a', 'i', '1', 'q') || \
+ (tag) == MKTAG('a', 'i', '1', '2') || \
+ (tag) == MKTAG('a', 'i', '1', '3') || \
+ (tag) == MKTAG('a', 'i', '1', '5') || \
+ (tag) == MKTAG('a', 'i', '1', '6') || \
+ (tag) == MKTAG('A', 'V', 'i', 'n'))
+
+
int ff_mov_read_esds(AVFormatContext *fc, AVIOContext *pb, MOVAtom atom);
enum AVCodecID ff_mov_get_lpcm_codec_id(int bps, int flags);
diff --git a/libavformat/jacosubdec.c b/libavformat/jacosubdec.c
index e2cbaad..e77ab40 100644
--- a/libavformat/jacosubdec.c
+++ b/libavformat/jacosubdec.c
@@ -43,8 +43,9 @@
static int timed_line(const char *ptr)
{
char c;
+ int fs, fe;
return (sscanf(ptr, "%*u:%*u:%*u.%*u %*u:%*u:%*u.%*u %c", &c) == 1 ||
- sscanf(ptr, "@%*u @%*u %c", &c) == 1);
+ (sscanf(ptr, "@%u @%u %c", &fs, &fe, &c) == 3 && fs < fe));
}
static int jacosub_probe(AVProbeData *p)
diff --git a/libavformat/libgme.c b/libavformat/libgme.c
index 1ae63dc..276477b 100644
--- a/libavformat/libgme.c
+++ b/libavformat/libgme.c
@@ -174,7 +174,7 @@
// Reads 4 bytes - returns "" if unknown format.
if (gme_identify_header(p->buf)[0]) {
if (p->buf_size < 16384)
- return AVPROBE_SCORE_MAX / 4 + 1;
+ return AVPROBE_SCORE_MAX / 4 ;
else
return AVPROBE_SCORE_MAX / 2;
}
diff --git a/libavformat/lvfdec.c b/libavformat/lvfdec.c
index a809c67..1ff67c8 100644
--- a/libavformat/lvfdec.c
+++ b/libavformat/lvfdec.c
@@ -25,9 +25,13 @@
static int lvf_probe(AVProbeData *p)
{
- if (AV_RL32(p->buf) == MKTAG('L', 'V', 'F', 'F'))
- return AVPROBE_SCORE_EXTENSION;
- return 0;
+ if (AV_RL32(p->buf) != MKTAG('L', 'V', 'F', 'F'))
+ return 0;
+
+ if (!AV_RL32(p->buf + 16) || AV_RL32(p->buf + 16) > 256)
+ return AVPROBE_SCORE_MAX / 8;
+
+ return AVPROBE_SCORE_EXTENSION;
}
static int lvf_read_header(AVFormatContext *s)
diff --git a/libavformat/matroska.c b/libavformat/matroska.c
index 10d11a3..77a88a8 100644
--- a/libavformat/matroska.c
+++ b/libavformat/matroska.c
@@ -88,6 +88,7 @@
{"V_MPEG4/ISO/AP" , AV_CODEC_ID_MPEG4},
{"V_MPEG4/ISO/SP" , AV_CODEC_ID_MPEG4},
{"V_MPEG4/ISO/AVC" , AV_CODEC_ID_H264},
+ {"V_MPEGH/ISO/HEVC" , AV_CODEC_ID_HEVC},
{"V_MPEG4/MS/V3" , AV_CODEC_ID_MSMPEG4V3},
{"V_PRORES" , AV_CODEC_ID_PRORES},
{"V_REAL/RV10" , AV_CODEC_ID_RV10},
diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c
index 85194fb..cedb345 100644
--- a/libavformat/matroskadec.c
+++ b/libavformat/matroskadec.c
@@ -68,6 +68,7 @@
EBML_NEST,
EBML_PASS,
EBML_STOP,
+ EBML_SINT,
EBML_TYPE_COUNT
} EbmlType;
@@ -298,7 +299,7 @@
EbmlBin bin;
uint64_t additional_id;
EbmlBin additional;
- uint64_t discard_padding;
+ int64_t discard_padding;
} MatroskaBlock;
static EbmlSyntax ebml_header[] = {
@@ -576,8 +577,8 @@
{ MATROSKA_ID_BLOCKADDITIONS, EBML_NEST, 0, 0, {.n=matroska_blockadditions} },
{ MATROSKA_ID_SIMPLEBLOCK, EBML_BIN, 0, offsetof(MatroskaBlock,bin) },
{ MATROSKA_ID_BLOCKDURATION, EBML_UINT, 0, offsetof(MatroskaBlock,duration) },
- { MATROSKA_ID_DISCARDPADDING, EBML_UINT, 0, offsetof(MatroskaBlock,discard_padding) },
- { MATROSKA_ID_BLOCKREFERENCE, EBML_UINT, 0, offsetof(MatroskaBlock,reference) },
+ { MATROSKA_ID_DISCARDPADDING, EBML_SINT, 0, offsetof(MatroskaBlock,discard_padding) },
+ { MATROSKA_ID_BLOCKREFERENCE, EBML_SINT, 0, offsetof(MatroskaBlock,reference) },
{ MATROSKA_ID_CODECSTATE, EBML_NONE },
{ 1, EBML_UINT, 0, offsetof(MatroskaBlock,non_simple), {.u=1} },
{ 0 }
@@ -765,6 +766,30 @@
}
/*
+ * Read the next element as a signed int.
+ * 0 is success, < 0 is failure.
+ */
+static int ebml_read_sint(AVIOContext *pb, int size, int64_t *num)
+{
+ int n = 1;
+
+ if (size > 8)
+ return AVERROR_INVALIDDATA;
+
+ if (size == 0) {
+ *num = 0;
+ } else {
+ *num = sign_extend(avio_r8(pb), 8);
+
+ /* big-endian ordering; build up number */
+ while (n++ < size)
+ *num = (*num << 8) | avio_r8(pb);
+ }
+
+ return 0;
+}
+
+/*
* Read the next element as a float.
* 0 is success, < 0 is failure.
*/
@@ -991,6 +1016,7 @@
switch (syntax->type) {
case EBML_UINT: res = ebml_read_uint (pb, length, data); break;
+ case EBML_SINT: res = ebml_read_sint (pb, length, data); break;
case EBML_FLOAT: res = ebml_read_float (pb, length, data); break;
case EBML_STR:
case EBML_UTF8: res = ebml_read_ascii (pb, length, data); break;
@@ -1855,7 +1881,9 @@
st->codec->height * track->video.display_width,
st->codec-> width * track->video.display_height,
255);
- st->need_parsing = AVSTREAM_PARSE_HEADERS;
+ if (st->codec->codec_id != AV_CODEC_ID_HEVC)
+ st->need_parsing = AVSTREAM_PARSE_HEADERS;
+
if (track->default_duration) {
av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den,
1000000000, track->default_duration, 30000);
@@ -2405,7 +2433,7 @@
uint64_t timecode, uint64_t lace_duration,
int64_t pos, int is_keyframe,
uint8_t *additional, uint64_t additional_id, int additional_size,
- uint64_t discard_padding)
+ int64_t discard_padding)
{
MatroskaTrackEncoding *encodings = track->encodings.elem;
uint8_t *pkt_data = data;
@@ -2542,7 +2570,7 @@
int size, int64_t pos, uint64_t cluster_time,
uint64_t block_duration, int is_keyframe,
uint8_t *additional, uint64_t additional_id, int additional_size,
- int64_t cluster_pos, uint64_t discard_padding)
+ int64_t cluster_pos, int64_t discard_padding)
{
uint64_t timecode = AV_NOPTS_VALUE;
MatroskaTrack *track;
diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c
index b9848b6..e461c5e 100644
--- a/libavformat/matroskaenc.c
+++ b/libavformat/matroskaenc.c
@@ -19,6 +19,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <stdint.h>
+
#include "avc.h"
#include "avformat.h"
#include "avio_internal.h"
@@ -202,6 +204,19 @@
avio_w8(pb, (uint8_t)(val >> i*8));
}
+static void put_ebml_sint(AVIOContext *pb, unsigned int elementid, int64_t val)
+{
+ int i, bytes = 1;
+ uint64_t tmp = 2*(val < 0 ? val^-1 : val);
+
+ while (tmp>>=8) bytes++;
+
+ put_ebml_id(pb, elementid);
+ put_ebml_num(pb, bytes, 0);
+ for (i = bytes - 1; i >= 0; i--)
+ avio_w8(pb, (uint8_t)(val >> i*8));
+}
+
static void put_ebml_float(AVIOContext *pb, unsigned int elementid, double val)
{
put_ebml_id(pb, elementid);
@@ -592,6 +607,8 @@
int bit_depth = av_get_bits_per_sample(codec->codec_id);
int sample_rate = codec->sample_rate;
int output_sample_rate = 0;
+ int display_width_div = 1;
+ int display_height_div = 1;
AVDictionaryEntry *tag;
if (codec->codec_type == AVMEDIA_TYPE_ATTACHMENT) {
@@ -723,6 +740,21 @@
return AVERROR(EINVAL);
} else
put_ebml_uint(pb, MATROSKA_ID_VIDEOSTEREOMODE, st_mode);
+
+ switch (st_mode) {
+ case 1:
+ case 8:
+ case 9:
+ case 11:
+ display_width_div = 2;
+ break;
+ case 2:
+ case 3:
+ case 6:
+ case 7:
+ display_height_div = 2;
+ break;
+ }
}
if ((tag = av_dict_get(st->metadata, "alpha_mode", NULL, 0)) ||
@@ -737,8 +769,11 @@
av_log(s, AV_LOG_ERROR, "Overflow in display width\n");
return AVERROR(EINVAL);
}
- put_ebml_uint(pb, MATROSKA_ID_VIDEODISPLAYWIDTH , d_width);
- put_ebml_uint(pb, MATROSKA_ID_VIDEODISPLAYHEIGHT, codec->height);
+ put_ebml_uint(pb, MATROSKA_ID_VIDEODISPLAYWIDTH , d_width / display_width_div);
+ put_ebml_uint(pb, MATROSKA_ID_VIDEODISPLAYHEIGHT, codec->height / display_height_div);
+ } else if (display_width_div != 1 || display_height_div != 1) {
+ put_ebml_uint(pb, MATROSKA_ID_VIDEODISPLAYWIDTH , codec->width / display_width_div);
+ put_ebml_uint(pb, MATROSKA_ID_VIDEODISPLAYHEIGHT, codec->height / display_height_div);
}
if (codec->codec_id == AV_CODEC_ID_RAWVIDEO) {
@@ -1304,7 +1339,8 @@
uint8_t *data = NULL, *side_data = NULL;
int offset = 0, size = pkt->size, side_data_size = 0;
int64_t ts = mkv->tracks[pkt->stream_index].write_dts ? pkt->dts : pkt->pts;
- uint64_t additional_id = 0, discard_padding = 0;
+ uint64_t additional_id = 0;
+ int64_t discard_padding = 0;
ebml_master block_group, block_additions, block_more;
av_log(s, AV_LOG_DEBUG, "Writing block at offset %" PRIu64 ", size %d, "
@@ -1363,7 +1399,7 @@
av_free(data);
if (discard_padding) {
- put_ebml_uint(pb, MATROSKA_ID_DISCARDPADDING, discard_padding);
+ put_ebml_sint(pb, MATROSKA_ID_DISCARDPADDING, discard_padding);
}
if (side_data_size && additional_id == 1) {
diff --git a/libavformat/md5enc.c b/libavformat/md5enc.c
index 270d9fb..8b14fba 100644
--- a/libavformat/md5enc.c
+++ b/libavformat/md5enc.c
@@ -117,7 +117,12 @@
int res = av_hash_alloc(&c->hash, c->hash_name);
if (res < 0)
return res;
- return ff_framehash_write_header(s);
+ avio_printf(s->pb, "#format: frame checksums\n");
+ avio_printf(s->pb, "#version: 1\n");
+ avio_printf(s->pb, "#hash: %s\n", av_hash_get_name(c->hash));
+ ff_framehash_write_header(s);
+ avio_printf(s->pb, "#stream#, dts, pts, duration, size, hash\n");
+ return 0;
}
static int framemd5_write_packet(struct AVFormatContext *s, AVPacket *pkt)
diff --git a/libavformat/mmst.c b/libavformat/mmst.c
index 1673036..3828955 100644
--- a/libavformat/mmst.c
+++ b/libavformat/mmst.c
@@ -152,7 +152,7 @@
return 0;
}
-static void mms_put_utf16(MMSContext *mms, const uint8_t *src)
+static int mms_put_utf16(MMSContext *mms, const uint8_t *src)
{
AVIOContext bic;
int size = mms->write_out_ptr - mms->out_buffer;
@@ -161,7 +161,10 @@
sizeof(mms->out_buffer) - size, 1, NULL, NULL, NULL, NULL);
len = avio_put_str16le(&bic, src);
+ if (len < 0)
+ return len;
mms->write_out_ptr += len;
+ return 0;
}
static int send_time_test_data(MMSTContext *mmst)
@@ -173,6 +176,7 @@
static int send_protocol_select(MMSTContext *mmst)
{
+ int ret;
char data_string[256];
MMSContext *mms = &mmst->mms;
@@ -189,18 +193,21 @@
"TCP", // or UDP
LOCAL_PORT);
- mms_put_utf16(mms, data_string);
+ if ((ret = mms_put_utf16(mms, data_string)) < 0)
+ return ret;
return send_command_packet(mmst);
}
static int send_media_file_request(MMSTContext *mmst)
{
+ int ret;
MMSContext *mms = &mmst->mms;
start_command_packet(mmst, CS_PKT_MEDIA_FILE_REQUEST);
insert_command_prefixes(mms, 1, 0xffffffff);
bytestream_put_le32(&mms->write_out_ptr, 0);
bytestream_put_le32(&mms->write_out_ptr, 0);
- mms_put_utf16(mms, mmst->path + 1); // +1 for skip "/"
+ if ((ret = mms_put_utf16(mms, mmst->path + 1)) < 0) // +1 for skip "/"
+ return ret;
return send_command_packet(mmst);
}
@@ -417,6 +424,7 @@
static int send_startup_packet(MMSTContext *mmst)
{
char data_string[256];
+ int ret;
MMSContext *mms = &mmst->mms;
// SubscriberName is defined in MS specification linked below.
// The guid value can be any valid value.
@@ -429,7 +437,8 @@
start_command_packet(mmst, CS_PKT_INITIAL);
insert_command_prefixes(mms, 0, 0x0004000b);
bytestream_put_le32(&mms->write_out_ptr, 0x0003001c);
- mms_put_utf16(mms, data_string);
+ if ((ret = mms_put_utf16(mms, data_string)) < 0)
+ return ret;
return send_command_packet(mmst);
}
diff --git a/libavformat/mov.c b/libavformat/mov.c
index f8535f0..0157a7d 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -24,6 +24,7 @@
*/
#include <limits.h>
+#include <stdint.h>
//#define MOV_EXPORT_ALL_METADATA
@@ -1042,15 +1043,17 @@
static int mov_read_ares(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
- AVCodecContext *codec = c->fc->streams[c->fc->nb_streams-1]->codec;
- if (codec->codec_tag == MKTAG('A', 'V', 'i', 'n') &&
- codec->codec_id == AV_CODEC_ID_H264 &&
- atom.size > 11) {
- avio_skip(pb, 10);
- /* For AVID AVCI50, force width of 1440 to be able to select the correct SPS and PPS */
- if (avio_rb16(pb) == 0xd4d)
- codec->width = 1440;
- return 0;
+ if (c->fc->nb_streams >= 1) {
+ AVCodecContext *codec = c->fc->streams[c->fc->nb_streams-1]->codec;
+ if (codec->codec_tag == MKTAG('A', 'V', 'i', 'n') &&
+ codec->codec_id == AV_CODEC_ID_H264 &&
+ atom.size > 11) {
+ avio_skip(pb, 10);
+ /* For AVID AVCI50, force width of 1440 to be able to select the correct SPS and PPS */
+ if (avio_rb16(pb) == 0xd4d)
+ codec->width = 1440;
+ return 0;
+ }
}
return mov_read_avid(c, pb, atom);
@@ -1590,8 +1593,11 @@
avio_skip(pb, size);
return 1;
}
- if (codec_tag == AV_RL32("avc1"))
- av_log(c->fc, AV_LOG_WARNING, "Concatenated H.264 might not play corrently.\n");
+ if ( codec_tag == AV_RL32("avc1") ||
+ codec_tag == AV_RL32("hvc1") ||
+ codec_tag == AV_RL32("hev1")
+ )
+ av_log(c->fc, AV_LOG_WARNING, "Concatenated H.264 or H.265 might not play correctly.\n");
return 0;
}
@@ -1656,7 +1662,7 @@
if (ret < 0)
return ret;
}
- /* this will read extra atoms at the end (wave, alac, damr, avcC, SMI ...) */
+ /* this will read extra atoms at the end (wave, alac, damr, avcC, hvcC, SMI ...) */
a.size = size - (avio_tell(pb) - start_pos);
if (a.size > 8) {
if ((ret = mov_read_default(c, pb, a)) < 0)
@@ -1776,7 +1782,7 @@
if (!entries)
{
sc->keyframe_absent = 1;
- if (!st->need_parsing)
+ if (!st->need_parsing && st->codec->codec_type == AVMEDIA_TYPE_VIDEO)
st->need_parsing = AVSTREAM_PARSE_HEADERS;
return 0;
}
@@ -2153,6 +2159,8 @@
av_dlog(mov->fc, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
"size %d, distance %d, keyframe %d\n", st->index, current_sample,
current_offset, current_dts, sample_size, distance, keyframe);
+ if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO && st->nb_index_entries < 100)
+ ff_rfps_add_frame(mov->fc, st, current_dts);
}
current_offset += sample_size;
@@ -2384,8 +2392,10 @@
// done for ai5q, ai52, ai55, ai1q, ai12 and ai15.
if (!st->codec->extradata_size && st->codec->codec_id == AV_CODEC_ID_H264 &&
- st->codec->codec_tag != MKTAG('a', 'v', 'c', '1')) {
- ff_generate_avci_extradata(st);
+ TAG_IS_AVCI(st->codec->codec_tag)) {
+ ret = ff_generate_avci_extradata(st);
+ if (ret < 0)
+ return ret;
}
switch (st->codec->codec_id) {
@@ -2962,6 +2972,7 @@
{ MKTAG('c','h','a','n'), mov_read_chan }, /* channel layout */
{ MKTAG('d','v','c','1'), mov_read_dvc1 },
{ MKTAG('s','b','g','p'), mov_read_sbgp },
+{ MKTAG('h','v','c','C'), mov_read_glbl },
{ MKTAG('u','u','i','d'), mov_read_uuid },
{ MKTAG('C','i','n', 0x8e), mov_read_targa_y216 },
{ 0, NULL }
@@ -3401,6 +3412,8 @@
}
}
+ ff_rfps_calculate(s);
+
return 0;
}
diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index 3296762..7315417 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -21,6 +21,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <stdint.h>
+
#include "movenc.h"
#include "avformat.h"
#include "avio_internal.h"
@@ -1051,6 +1053,7 @@
{ AV_CODEC_ID_MP3, MKTAG('.','m','p','3') },
{ AV_CODEC_ID_AAC, MKTAG('m','p','4','a') },
{ AV_CODEC_ID_H264, MKTAG('a','v','c','1') },
+ { AV_CODEC_ID_VP6A, MKTAG('V','P','6','A') },
{ AV_CODEC_ID_VP6F, MKTAG('V','P','6','F') },
{ AV_CODEC_ID_NONE, 0 },
};
@@ -1069,7 +1072,7 @@
tag = ipod_get_codec_tag(s, track);
else if (track->mode & MODE_3GP)
tag = ff_codec_get_tag(codec_3gp_tags, track->enc->codec_id);
- else if (track->mode & MODE_F4V)
+ else if (track->mode == MODE_F4V)
tag = ff_codec_get_tag(codec_f4v_tags, track->enc->codec_id);
else
tag = mov_get_codec_tag(s, track);
@@ -1224,7 +1227,11 @@
mov_write_uuid_tag_ipod(pb);
} else if (track->enc->codec_id == AV_CODEC_ID_VC1 && track->vos_len > 0)
mov_write_dvc1_tag(pb, track);
- else if (track->vos_len > 0)
+ else if (track->enc->codec_id == AV_CODEC_ID_VP6F ||
+ track->enc->codec_id == AV_CODEC_ID_VP6A) {
+ /* Don't write any potential extradata here - the cropping
+ * is signalled via the normal width/height fields. */
+ } else if (track->vos_len > 0)
mov_write_glbl_tag(pb, track);
if (track->enc->codec_id != AV_CODEC_ID_H264 &&
@@ -3878,7 +3885,8 @@
}else{
track->sample_size = (av_get_bits_per_sample(st->codec->codec_id) >> 3) * st->codec->channels;
}
- if (st->codec->codec_id == AV_CODEC_ID_ILBC) {
+ if (st->codec->codec_id == AV_CODEC_ID_ILBC ||
+ st->codec->codec_id == AV_CODEC_ID_ADPCM_IMA_QT) {
track->audio_vbr = 1;
}
if (track->mode != MODE_MOV &&
diff --git a/libavformat/mp3dec.c b/libavformat/mp3dec.c
index e09d45a..5d484e9 100644
--- a/libavformat/mp3dec.c
+++ b/libavformat/mp3dec.c
@@ -67,6 +67,8 @@
for(; buf < end; buf= buf2+1) {
buf2 = buf;
+ if(ff_mpa_check_header(AV_RB32(buf2)))
+ continue;
for(frames = 0; buf2 < end; frames++) {
header = AV_RB32(buf2);
@@ -288,6 +290,7 @@
AVStream *st = s->streams[0];
int64_t ret = av_index_search_timestamp(st, timestamp, flags);
int i, j;
+ int dir = (flags&AVSEEK_FLAG_BACKWARD) ? -1 : 1;
if (mp3->is_cbr && st->duration > 0 && mp3->header_filesize > s->data_offset) {
int64_t filesize = avio_size(s->pb);
@@ -317,7 +320,7 @@
#define MIN_VALID 3
for(i=0; i<4096; i++) {
- int64_t pos = ie->pos + i;
+ int64_t pos = ie->pos + i*dir;
for(j=0; j<MIN_VALID; j++) {
ret = check(s, pos);
if(ret < 0)
@@ -330,7 +333,7 @@
if(j!=MIN_VALID)
i=0;
- ret = avio_seek(s->pb, ie->pos + i, SEEK_SET);
+ ret = avio_seek(s->pb, ie->pos + i*dir, SEEK_SET);
if (ret < 0)
return ret;
ff_update_cur_dts(s, st, ie->timestamp);
diff --git a/libavformat/mpeg.c b/libavformat/mpeg.c
index 64c5a4f..1777283 100644
--- a/libavformat/mpeg.c
+++ b/libavformat/mpeg.c
@@ -193,6 +193,8 @@
/* skip program_stream_info */
avio_skip(pb, ps_info_length);
es_map_length = avio_rb16(pb);
+ /* Ignore es_map_length, trust psm_length */
+ es_map_length = psm_length - ps_info_length - 10;
/* at least one es available? */
while (es_map_length >= 4){
@@ -521,7 +523,13 @@
codec_id = AV_CODEC_ID_DVD_NAV;
} else if (startcode >= 0x1c0 && startcode <= 0x1df) {
type = AVMEDIA_TYPE_AUDIO;
- codec_id = m->sofdec > 0 ? AV_CODEC_ID_ADPCM_ADX : AV_CODEC_ID_MP2;
+ if (m->sofdec > 0) {
+ codec_id = AV_CODEC_ID_ADPCM_ADX;
+ // Auto-detect AC-3
+ request_probe = 50;
+ } else {
+ codec_id = AV_CODEC_ID_MP2;
+ }
} else if (startcode >= 0x80 && startcode <= 0x87) {
type = AVMEDIA_TYPE_AUDIO;
codec_id = AV_CODEC_ID_AC3;
@@ -916,6 +924,8 @@
return ret;
}
+ if (stream_index == -1) // only 1 stream
+ stream_index = 0;
return ff_subtitles_queue_seek(&vobsub->q[stream_index], s, stream_index,
min_ts, ts, max_ts, flags);
}
diff --git a/libavformat/mpegenc.c b/libavformat/mpegenc.c
index 0a9d69b..ccf3ec2 100644
--- a/libavformat/mpegenc.c
+++ b/libavformat/mpegenc.c
@@ -19,6 +19,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <stdint.h>
+
#include "libavutil/attributes.h"
#include "libavutil/fifo.h"
#include "libavutil/log.h"
@@ -344,6 +346,15 @@
switch(st->codec->codec_type) {
case AVMEDIA_TYPE_AUDIO:
+ if (!s->is_mpeg2 &&
+ (st->codec->codec_id == AV_CODEC_ID_AC3 ||
+ st->codec->codec_id == AV_CODEC_ID_DTS ||
+ st->codec->codec_id == AV_CODEC_ID_PCM_S16BE))
+ av_log(ctx, AV_LOG_WARNING,
+ "%s in MPEG-1 system streams is not widely supported, "
+ "consider using the vob or the dvd muxer "
+ "to force a MPEG-2 program stream.\n",
+ avcodec_get_name(st->codec->codec_id));
if (st->codec->codec_id == AV_CODEC_ID_AC3) {
stream->id = ac3_id++;
} else if (st->codec->codec_id == AV_CODEC_ID_DTS) {
diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c
index cd881d8..d67c63a 100644
--- a/libavformat/mpegts.c
+++ b/libavformat/mpegts.c
@@ -452,22 +452,19 @@
static int analyze(const uint8_t *buf, int size, int packet_size, int *index){
int stat[TS_MAX_PACKET_SIZE];
int i;
- int x=0;
int best_score=0;
- memset(stat, 0, packet_size*sizeof(int));
+ memset(stat, 0, packet_size*sizeof(*stat));
- for(x=i=0; i<size-3; i++){
+ for(i=0; i<size-3; i++){
if(buf[i] == 0x47 && !(buf[i+1] & 0x80) && buf[i+3] != 0x47){
+ int x = i % packet_size;
stat[x]++;
if(stat[x] > best_score){
best_score= stat[x];
if(index) *index= x;
}
}
-
- x++;
- if(x == packet_size) x= 0;
}
return best_score;
@@ -599,6 +596,7 @@
{ 0x11, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_AAC_LATM }, /* LATM syntax */
#endif
{ 0x1b, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_H264 },
+ { 0x24, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_HEVC },
{ 0x42, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_CAVS },
{ 0xd1, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_DIRAC },
{ 0xea, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_VC1 },
@@ -633,11 +631,17 @@
{ MKTAG('D','T','S','1'), AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_DTS },
{ MKTAG('D','T','S','2'), AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_DTS },
{ MKTAG('D','T','S','3'), AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_DTS },
+ { MKTAG('H','E','V','C'), AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_HEVC },
{ MKTAG('K','L','V','A'), AVMEDIA_TYPE_DATA, AV_CODEC_ID_SMPTE_KLV },
{ MKTAG('V','C','-','1'), AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_VC1 },
{ 0 },
};
+static const StreamType METADATA_types[] = {
+ { MKTAG('K','L','V','A'), AVMEDIA_TYPE_DATA, AV_CODEC_ID_SMPTE_KLV },
+ { 0 },
+};
+
/* descriptor present */
static const StreamType DESC_types[] = {
{ 0x6a, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_AC3 }, /* AC-3 descriptor */
@@ -968,7 +972,10 @@
pes->pts = AV_NOPTS_VALUE;
pes->dts = AV_NOPTS_VALUE;
if ((flags & 0xc0) == 0x80) {
- pes->dts = pes->pts = ff_parse_pes_pts(r);
+ pes->pts = ff_parse_pes_pts(r);
+ /* video pts is not monotonic, can't be used for dts */
+ if (pes->st->codec->codec_type != AVMEDIA_TYPE_VIDEO)
+ pes->dts = pes->pts;
r += 5;
} else if ((flags & 0xc0) == 0xc0) {
pes->pts = ff_parse_pes_pts(r);
@@ -1000,6 +1007,12 @@
p += sl_header_bytes;
buf_size -= sl_header_bytes;
}
+ if (pes->stream_type == 0x15 && buf_size >= 5) {
+ /* skip metadata access unit header */
+ pes->pes_header_size += 5;
+ p += 5;
+ buf_size -= 5;
+ }
if (pes->ts->fix_teletext_pts && pes->st->codec->codec_id == AV_CODEC_ID_DVB_TELETEXT) {
AVProgram *p = NULL;
while ((p = av_find_program_from_stream(pes->stream, p, pes->st->index))) {
@@ -1487,6 +1500,15 @@
case 0x52: /* stream identifier descriptor */
st->stream_identifier = 1 + get8(pp, desc_end);
break;
+ case 0x26: /* metadata descriptor */
+ if (get16(pp, desc_end) == 0xFFFF)
+ *pp += 4;
+ if (get8(pp, desc_end) == 0xFF) {
+ st->codec->codec_tag = bytestream_get_le32(pp);
+ if (st->codec->codec_id == AV_CODEC_ID_NONE)
+ mpegts_find_stream_type(st, st->codec->codec_tag, METADATA_types);
+ }
+ break;
default:
break;
}
@@ -1974,7 +1996,9 @@
/* check packet sync byte */
if ((*data)[0] != 0x47) {
/* find a new packet start */
- avio_seek(pb, -raw_packet_size, SEEK_CUR);
+ uint64_t pos = avio_tell(pb);
+ avio_seek(pb, -FFMIN(raw_packet_size, pos), SEEK_CUR);
+
if (mpegts_resync(s) < 0)
return AVERROR(EAGAIN);
else
diff --git a/libavformat/mpegvideodec.c b/libavformat/mpegvideodec.c
index a400978..ade76d8 100644
--- a/libavformat/mpegvideodec.c
+++ b/libavformat/mpegvideodec.c
@@ -23,6 +23,8 @@
#include "avformat.h"
#include "rawdec.h"
+#include "libavutil/intreadwrite.h"
+
#define SEQ_START_CODE 0x000001b3
#define GOP_START_CODE 0x000001b8
#define PICTURE_START_CODE 0x00000100
@@ -35,14 +37,29 @@
{
uint32_t code= -1;
int pic=0, seq=0, slice=0, pspack=0, vpes=0, apes=0, res=0, sicle=0;
- int i;
+ int i, j;
uint32_t last = 0;
for(i=0; i<p->buf_size; i++){
code = (code<<8) + p->buf[i];
if ((code & 0xffffff00) == 0x100) {
switch(code){
- case SEQ_START_CODE: seq++; break;
+ case SEQ_START_CODE:
+ if (!(p->buf[i+1+3+1+2] & 0x20))
+ break;
+ j = i;
+ if (p->buf[j+8] & 2)
+ j+= 64;
+ if (j >= p->buf_size)
+ break;
+ if (p->buf[j+8] & 1)
+ j+= 64;
+ if (j >= p->buf_size)
+ break;
+ if (AV_RB24(p->buf + j + 9) & 0xFFFFFE)
+ break;
+ seq++;
+ break;
case PICTURE_START_CODE: pic++; break;
case PACK_START_CODE: pspack++; break;
case 0x1b6:
diff --git a/libavformat/mux.c b/libavformat/mux.c
index eff7caa..79625c6 100644
--- a/libavformat/mux.c
+++ b/libavformat/mux.c
@@ -339,6 +339,8 @@
/* set muxer identification string */
if (s->nb_streams && !(s->streams[0]->codec->flags & CODEC_FLAG_BITEXACT)) {
av_dict_set(&s->metadata, "encoder", LIBAVFORMAT_IDENT, 0);
+ } else {
+ av_dict_set(&s->metadata, "encoder", NULL, 0);
}
if (options) {
diff --git a/libavformat/mxfdec.c b/libavformat/mxfdec.c
index 72faf4c..61c0cb2 100644
--- a/libavformat/mxfdec.c
+++ b/libavformat/mxfdec.c
@@ -43,10 +43,13 @@
* Only tracks with associated descriptors will be decoded. "Highly Desirable" SMPTE 377M D.1
*/
+#include <stdint.h>
+
#include "libavutil/aes.h"
#include "libavutil/avassert.h"
#include "libavutil/mathematics.h"
#include "libavcodec/bytestream.h"
+#include "libavutil/intreadwrite.h"
#include "libavutil/timecode.h"
#include "avformat.h"
#include "internal.h"
@@ -213,6 +216,7 @@
struct AVAES *aesc;
uint8_t *local_tags;
int local_tags_count;
+ uint64_t last_partition;
uint64_t footer_partition;
KLVPacket current_klv_data;
int current_klv_index;
@@ -254,6 +258,7 @@
static const uint8_t mxf_crypto_source_container_ul[] = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x09,0x06,0x01,0x01,0x02,0x02,0x00,0x00,0x00 };
static const uint8_t mxf_encrypted_triplet_key[] = { 0x06,0x0e,0x2b,0x34,0x02,0x04,0x01,0x07,0x0d,0x01,0x03,0x01,0x02,0x7e,0x01,0x00 };
static const uint8_t mxf_encrypted_essence_container[] = { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x07,0x0d,0x01,0x03,0x01,0x02,0x0b,0x01,0x00 };
+static const uint8_t mxf_random_index_pack_key[] = { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0D,0x01,0x02,0x01,0x01,0x11,0x01,0x00 };
static const uint8_t mxf_sony_mpeg4_extradata[] = { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x01,0x0e,0x06,0x06,0x02,0x02,0x01,0x00,0x00 };
#define IS_KLV_KEY(x, y) (!memcmp(x, y, sizeof(y)))
@@ -1513,6 +1518,7 @@
av_log(mxf->fc, AV_LOG_VERBOSE, ".");
}
av_log(mxf->fc, AV_LOG_VERBOSE, "\n");
+
if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
source_track->intra_only = mxf_is_intra_only(descriptor);
container_ul = mxf_get_codec_ul(mxf_picture_essence_container_uls, essence_container_ul);
@@ -1602,8 +1608,10 @@
if (!ff_alloc_extradata(st->codec, descriptor->extradata_size)) {
memcpy(st->codec->extradata, descriptor->extradata, descriptor->extradata_size);
}
- } else if(st->codec->codec_id == AV_CODEC_ID_H264) {
- ff_generate_avci_extradata(st);
+ } else if (st->codec->codec_id == AV_CODEC_ID_H264) {
+ ret = ff_generate_avci_extradata(st);
+ if (ret < 0)
+ return ret;
}
if (st->codec->codec_type != AVMEDIA_TYPE_DATA && (*essence_container_ul)[15] > 0x01) {
/* TODO: decode timestamps */
@@ -1852,31 +1860,33 @@
if (mxf->parsing_backward) {
return mxf_seek_to_previous_partition(mxf);
- } else {
- if (!mxf->footer_partition) {
- av_dlog(mxf->fc, "no footer\n");
- return 0;
- }
+ } else if (mxf->footer_partition || mxf->last_partition){
+ uint64_t offset;
- av_dlog(mxf->fc, "seeking to footer\n");
+ offset = mxf->footer_partition ? mxf->footer_partition : mxf->last_partition;
+
+ av_dlog(mxf->fc, "seeking to last partition\n");
/* remember where we were so we don't end up seeking further back than this */
mxf->last_forward_tell = avio_tell(pb);
if (!pb->seekable) {
- av_log(mxf->fc, AV_LOG_INFO, "file is not seekable - not parsing footer\n");
+ av_log(mxf->fc, AV_LOG_INFO, "file is not seekable - not parsing last partition\n");
return -1;
}
- /* seek to footer partition and parse backward */
- if ((ret = avio_seek(pb, mxf->run_in + mxf->footer_partition, SEEK_SET)) < 0) {
- av_log(mxf->fc, AV_LOG_ERROR, "failed to seek to footer @ 0x%"PRIx64" (%"PRId64") - partial file?\n",
- mxf->run_in + mxf->footer_partition, ret);
+ /* seek to last partition and parse backward */
+ if ((ret = avio_seek(pb, mxf->run_in + offset, SEEK_SET)) < 0) {
+ av_log(mxf->fc, AV_LOG_ERROR, "failed to seek to last partition @ 0x%"PRIx64" (%"PRId64") - partial file?\n",
+ mxf->run_in + offset, ret);
return ret;
}
mxf->current_partition = NULL;
mxf->parsing_backward = 1;
+ } else {
+ av_dlog(mxf->fc, "can't find last partition\n");
+ return 0;
}
return 1;
@@ -1968,6 +1978,34 @@
mxf->edit_units_per_packet = 1920;
}
+static void mxf_read_random_index_pack(AVFormatContext *s)
+{
+ MXFContext *mxf = s->priv_data;
+ uint32_t length;
+ int64_t file_size;
+ KLVPacket klv;
+
+ if (!s->pb->seekable)
+ return;
+
+ file_size = avio_size(s->pb);
+ avio_seek(s->pb, file_size - 4, SEEK_SET);
+ length = avio_rb32(s->pb);
+ if (length <= 32 || length >= FFMIN(file_size, INT_MAX))
+ goto end;
+ avio_seek(s->pb, file_size - length, SEEK_SET);
+ if (klv_read_packet(&klv, s->pb) < 0 ||
+ !IS_KLV_KEY(klv.key, mxf_random_index_pack_key) ||
+ klv.length != length - 20)
+ goto end;
+
+ avio_skip(s->pb, klv.length - 12);
+ mxf->last_partition = avio_rb64(s->pb);
+
+end:
+ avio_seek(s->pb, mxf->run_in, SEEK_SET);
+}
+
static int mxf_read_header(AVFormatContext *s)
{
MXFContext *mxf = s->priv_data;
@@ -1986,6 +2024,8 @@
mxf->fc = s;
mxf->run_in = avio_tell(s->pb);
+ mxf_read_random_index_pack(s);
+
while (!url_feof(s->pb)) {
const MXFMetadataReadTableEntry *metadata;
@@ -2422,10 +2462,19 @@
/* Must skip Run-In Sequence and search for MXF header partition pack key SMPTE 377M 5.5 */
end -= sizeof(mxf_header_partition_pack_key);
- for (; bufp < end; bufp++) {
- if (IS_KLV_KEY(bufp, mxf_header_partition_pack_key))
- return AVPROBE_SCORE_MAX;
+
+ for (; bufp < end;) {
+ if (!((bufp[13] - 1) & 0xF2)){
+ if (AV_RN32(bufp ) == AV_RN32(mxf_header_partition_pack_key ) &&
+ AV_RN32(bufp+ 4) == AV_RN32(mxf_header_partition_pack_key+ 4) &&
+ AV_RN32(bufp+ 8) == AV_RN32(mxf_header_partition_pack_key+ 8) &&
+ AV_RN16(bufp+12) == AV_RN16(mxf_header_partition_pack_key+12))
+ return AVPROBE_SCORE_MAX;
+ bufp ++;
+ } else
+ bufp += 10;
}
+
return 0;
}
diff --git a/libavformat/network.c b/libavformat/network.c
index 4f04861..2ba435d 100644
--- a/libavformat/network.c
+++ b/libavformat/network.c
@@ -245,8 +245,10 @@
{
fd = socket(af, type, proto);
#if HAVE_FCNTL
- if (fd != -1)
- fcntl(fd, F_SETFD, FD_CLOEXEC);
+ if (fd != -1) {
+ if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1)
+ av_log(NULL, AV_LOG_DEBUG, "Failed to set close on exec\n");
+ }
#endif
}
return fd;
diff --git a/libavformat/nullenc.c b/libavformat/nullenc.c
index 7da297b..7c08c39 100644
--- a/libavformat/nullenc.c
+++ b/libavformat/nullenc.c
@@ -32,5 +32,5 @@
.audio_codec = AV_NE(AV_CODEC_ID_PCM_S16BE, AV_CODEC_ID_PCM_S16LE),
.video_codec = AV_CODEC_ID_RAWVIDEO,
.write_packet = null_write_packet,
- .flags = AVFMT_NOFILE | AVFMT_NOTIMESTAMPS | AVFMT_RAWPICTURE,
+ .flags = AVFMT_VARIABLE_FPS | AVFMT_NOFILE | AVFMT_NOTIMESTAMPS | AVFMT_RAWPICTURE,
};
diff --git a/libavformat/nut.c b/libavformat/nut.c
index 7e79979..8b8a4cb 100644
--- a/libavformat/nut.c
+++ b/libavformat/nut.c
@@ -227,11 +227,17 @@
return ((a->ts - b->ts) >> 32) - ((b->ts - a->ts) >> 32);
}
-void ff_nut_add_sp(NUTContext *nut, int64_t pos, int64_t back_ptr, int64_t ts)
+int ff_nut_add_sp(NUTContext *nut, int64_t pos, int64_t back_ptr, int64_t ts)
{
Syncpoint *sp = av_mallocz(sizeof(Syncpoint));
struct AVTreeNode *node = av_tree_node_alloc();
+ if (!sp || !node) {
+ av_freep(&sp);
+ av_freep(&node);
+ return AVERROR(ENOMEM);
+ }
+
nut->sp_count++;
sp->pos = pos;
@@ -242,6 +248,8 @@
av_free(sp);
av_free(node);
}
+
+ return 0;
}
static int enu_free(void *opaque, void *elem)
diff --git a/libavformat/nut.h b/libavformat/nut.h
index dc5af15..da456ac 100644
--- a/libavformat/nut.h
+++ b/libavformat/nut.h
@@ -122,7 +122,7 @@
int64_t ff_lsb2full(StreamContext *stream, int64_t lsb);
int ff_nut_sp_pos_cmp(const Syncpoint *a, const Syncpoint *b);
int ff_nut_sp_pts_cmp(const Syncpoint *a, const Syncpoint *b);
-void ff_nut_add_sp(NUTContext *nut, int64_t pos, int64_t back_ptr, int64_t ts);
+int ff_nut_add_sp(NUTContext *nut, int64_t pos, int64_t back_ptr, int64_t ts);
void ff_nut_free_sp(NUTContext *nut);
extern const Dispositions ff_nut_dispositions[];
diff --git a/libavformat/nutdec.c b/libavformat/nutdec.c
index f380279..aa7ca67 100644
--- a/libavformat/nutdec.c
+++ b/libavformat/nutdec.c
@@ -558,6 +558,7 @@
AVIOContext *bc = s->pb;
int64_t end;
uint64_t tmp;
+ int ret;
nut->last_syncpoint_pos = avio_tell(bc) - 8;
@@ -579,7 +580,9 @@
*ts = tmp / nut->time_base_count *
av_q2d(nut->time_base[tmp % nut->time_base_count]) * AV_TIME_BASE;
- ff_nut_add_sp(nut, nut->last_syncpoint_pos, *back_ptr, *ts);
+
+ if ((ret = ff_nut_add_sp(nut, nut->last_syncpoint_pos, *back_ptr, *ts)) < 0)
+ return ret;
return 0;
}
diff --git a/libavformat/nutenc.c b/libavformat/nutenc.c
index f24813b..10b8fc8 100644
--- a/libavformat/nutenc.c
+++ b/libavformat/nutenc.c
@@ -19,6 +19,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <stdint.h>
+
#include "libavutil/intreadwrite.h"
#include "libavutil/mathematics.h"
#include "libavutil/tree.h"
@@ -858,7 +860,8 @@
ff_put_v(dyn_bc, sp ? (nut->last_syncpoint_pos - sp->pos) >> 4 : 0);
put_packet(nut, bc, dyn_bc, 1, SYNCPOINT_STARTCODE);
- ff_nut_add_sp(nut, nut->last_syncpoint_pos, 0 /*unused*/, pkt->dts);
+ if ((ret = ff_nut_add_sp(nut, nut->last_syncpoint_pos, 0 /*unused*/, pkt->dts)) < 0)
+ return ret;
if ((1ll<<60) % nut->sp_count == 0)
for (i=0; i<s->nb_streams; i++) {
diff --git a/libavformat/oggdec.c b/libavformat/oggdec.c
index 9f8d665..a099eb3 100644
--- a/libavformat/oggdec.c
+++ b/libavformat/oggdec.c
@@ -99,7 +99,7 @@
if (!discard) {
for (i = 0; i < ogg->nstreams; i++)
- av_free(ogg->streams[i].buf);
+ av_freep(&ogg->streams[i].buf);
avio_seek(bc, ost->pos, SEEK_SET);
ogg->page_pos = -1;
@@ -633,14 +633,14 @@
int i;
for (i = 0; i < ogg->nstreams; i++) {
- av_free(ogg->streams[i].buf);
+ av_freep(&ogg->streams[i].buf);
if (ogg->streams[i].codec &&
ogg->streams[i].codec->cleanup) {
ogg->streams[i].codec->cleanup(s, i);
}
- av_free(ogg->streams[i].private);
+ av_freep(&ogg->streams[i].private);
}
- av_free(ogg->streams);
+ av_freep(&ogg->streams);
return 0;
}
diff --git a/libavformat/oggenc.c b/libavformat/oggenc.c
index 1883501..d9ef23c 100644
--- a/libavformat/oggenc.c
+++ b/libavformat/oggenc.c
@@ -19,6 +19,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <stdint.h>
+
#include "libavutil/crc.h"
#include "libavutil/mathematics.h"
#include "libavutil/opt.h"
@@ -84,14 +86,6 @@
{ NULL },
};
-static const AVClass ogg_muxer_class = {
- .class_name = "Ogg muxer",
- .item_name = av_default_item_name,
- .option = options,
- .version = LIBAVUTIL_VERSION_INT,
-};
-
-
static void ogg_update_checksum(AVFormatContext *s, AVIOContext *pb, int64_t crc_offset)
{
int64_t pos = avio_tell(pb);
@@ -622,11 +616,26 @@
return 0;
}
+#if CONFIG_OGG_MUXER
+static const AVClass ogg_muxer_class = {
+ .class_name = "Ogg muxer",
+ .item_name = av_default_item_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
AVOutputFormat ff_ogg_muxer = {
.name = "ogg",
.long_name = NULL_IF_CONFIG_SMALL("Ogg"),
.mime_type = "application/ogg",
- .extensions = "ogg,ogv,spx,opus",
+ .extensions = "ogg,ogv"
+#if !CONFIG_SPEEX_MUXER
+ ",spx"
+#endif
+#if !CONFIG_OPUS_MUXER
+ ",opus"
+#endif
+ ,
.priv_data_size = sizeof(OGGContext),
.audio_codec = AV_CODEC_ID_FLAC,
.video_codec = AV_CODEC_ID_THEORA,
@@ -636,3 +645,52 @@
.flags = AVFMT_TS_NEGATIVE,
.priv_class = &ogg_muxer_class,
};
+#endif
+
+#if CONFIG_SPEEX_MUXER
+static const AVClass speex_muxer_class = {
+ .class_name = "Speex muxer",
+ .item_name = av_default_item_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
+AVOutputFormat ff_speex_muxer = {
+ .name = "speex",
+ .long_name = NULL_IF_CONFIG_SMALL("Speex"),
+ .mime_type = "audio/ogg",
+ .extensions = "spx",
+ .priv_data_size = sizeof(OGGContext),
+ .audio_codec = AV_CODEC_ID_SPEEX,
+ .video_codec = AV_CODEC_ID_NONE,
+ .write_header = ogg_write_header,
+ .write_packet = ogg_write_packet,
+ .write_trailer = ogg_write_trailer,
+ .flags = AVFMT_TS_NEGATIVE,
+ .priv_class = &speex_muxer_class,
+};
+#endif
+
+#if CONFIG_OPUS_MUXER
+static const AVClass opus_muxer_class = {
+ .class_name = "Opus muxer",
+ .item_name = av_default_item_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
+AVOutputFormat ff_opus_muxer = {
+ .name = "opus",
+ .long_name = NULL_IF_CONFIG_SMALL("Opus"),
+ .mime_type = "audio/ogg",
+ .extensions = "opus",
+ .priv_data_size = sizeof(OGGContext),
+ .audio_codec = AV_CODEC_ID_OPUS,
+ .video_codec = AV_CODEC_ID_NONE,
+ .write_header = ogg_write_header,
+ .write_packet = ogg_write_packet,
+ .write_trailer = ogg_write_trailer,
+ .flags = AVFMT_TS_NEGATIVE,
+ .priv_class = &opus_muxer_class,
+};
+#endif
diff --git a/libavformat/oggparsecelt.c b/libavformat/oggparsecelt.c
index 4b6233e..f3c2c1a 100644
--- a/libavformat/oggparsecelt.c
+++ b/libavformat/oggparsecelt.c
@@ -46,7 +46,9 @@
uint32_t overlap, extra_headers;
priv = av_malloc(sizeof(struct oggcelt_private));
- if (!priv || ff_alloc_extradata(st->codec, 2 * sizeof(uint32_t)))
+ if (!priv)
+ return AVERROR(ENOMEM);
+ if (ff_alloc_extradata(st->codec, 2 * sizeof(uint32_t)) < 0)
return AVERROR(ENOMEM);
version = AV_RL32(p + 28);
/* unused header size field skipped */
diff --git a/libavformat/oggparseflac.c b/libavformat/oggparseflac.c
index 894b438..f69533f 100644
--- a/libavformat/oggparseflac.c
+++ b/libavformat/oggparseflac.c
@@ -62,7 +62,8 @@
st->codec->codec_id = AV_CODEC_ID_FLAC;
st->need_parsing = AVSTREAM_PARSE_HEADERS;
- ff_alloc_extradata(st->codec, FLAC_STREAMINFO_SIZE);
+ if (ff_alloc_extradata(st->codec, FLAC_STREAMINFO_SIZE) < 0)
+ return AVERROR(ENOMEM);
memcpy(st->codec->extradata, streaminfo_start, st->codec->extradata_size);
avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
diff --git a/libavformat/oggparseopus.c b/libavformat/oggparseopus.c
index 78aa333..94267b2 100644
--- a/libavformat/oggparseopus.c
+++ b/libavformat/oggparseopus.c
@@ -55,6 +55,7 @@
st->codec->codec_id = AV_CODEC_ID_OPUS;
st->codec->channels = AV_RL8 (packet + 9);
priv->pre_skip = AV_RL16(packet + 10);
+ st->codec->delay = priv->pre_skip;
/*orig_sample_rate = AV_RL32(packet + 12);*/
/*gain = AV_RL16(packet + 16);*/
/*channel_map = AV_RL8 (packet + 18);*/
diff --git a/libavformat/oggparsespeex.c b/libavformat/oggparsespeex.c
index 7cbc7e0..1b9de9c 100644
--- a/libavformat/oggparsespeex.c
+++ b/libavformat/oggparsespeex.c
@@ -77,7 +77,8 @@
if (frames_per_packet)
spxp->packet_size *= frames_per_packet;
- ff_alloc_extradata(st->codec, os->psize);
+ if (ff_alloc_extradata(st->codec, os->psize) < 0)
+ return AVERROR(ENOMEM);
memcpy(st->codec->extradata, p, st->codec->extradata_size);
avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
diff --git a/libavformat/oggparsetheora.c b/libavformat/oggparsetheora.c
index 0fd5812..6458b97 100644
--- a/libavformat/oggparsetheora.c
+++ b/libavformat/oggparsetheora.c
@@ -1,26 +1,26 @@
/**
- Copyright (C) 2005 Matthieu CASTET, Alex Beregszaszi
-
- Permission is hereby granted, free of charge, to any person
- obtaining a copy of this software and associated documentation
- files (the "Software"), to deal in the Software without
- restriction, including without limitation the rights to use, copy,
- modify, merge, publish, distribute, sublicense, and/or sell copies
- of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be
- included in all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- DEALINGS IN THE SOFTWARE.
-**/
+ * Copyright (C) 2005 Matthieu CASTET, Alex Beregszaszi
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ **/
#include <stdlib.h>
#include "libavutil/bswap.h"
@@ -29,64 +29,67 @@
#include "internal.h"
#include "oggdec.h"
-struct theora_params {
+typedef struct TheoraParams {
int gpshift;
int gpmask;
unsigned version;
-};
+} TheoraParams;
-static int
-theora_header (AVFormatContext * s, int idx)
+static int theora_header(AVFormatContext *s, int idx)
{
- struct ogg *ogg = s->priv_data;
+ struct ogg *ogg = s->priv_data;
struct ogg_stream *os = ogg->streams + idx;
- AVStream *st = s->streams[idx];
- struct theora_params *thp = os->private;
- int cds = st->codec->extradata_size + os->psize + 2, err;
+ AVStream *st = s->streams[idx];
+ TheoraParams *thp = os->private;
+ int cds = st->codec->extradata_size + os->psize + 2;
+ int err;
uint8_t *cdp;
- if(!(os->buf[os->pstart] & 0x80))
+ if (!(os->buf[os->pstart] & 0x80))
return 0;
- if(!thp){
+ if (!thp) {
thp = av_mallocz(sizeof(*thp));
+ if (!thp)
+ return AVERROR(ENOMEM);
os->private = thp;
}
switch (os->buf[os->pstart]) {
case 0x80: {
GetBitContext gb;
- int width, height;
AVRational timebase;
- init_get_bits(&gb, os->buf + os->pstart, os->psize*8);
+ init_get_bits(&gb, os->buf + os->pstart, os->psize * 8);
- skip_bits_long(&gb, 7*8); /* 0x80"theora" */
+ /* 0x80"theora" */
+ skip_bits_long(&gb, 7 * 8);
thp->version = get_bits_long(&gb, 24);
- if (thp->version < 0x030100)
- {
+ if (thp->version < 0x030100) {
av_log(s, AV_LOG_ERROR,
- "Too old or unsupported Theora (%x)\n", thp->version);
- return -1;
+ "Too old or unsupported Theora (%x)\n", thp->version);
+ return AVERROR(ENOSYS);
}
- width = get_bits(&gb, 16) << 4;
- height = get_bits(&gb, 16) << 4;
- avcodec_set_dimensions(st->codec, width, height);
+ st->codec->width = get_bits(&gb, 16) << 4;
+ st->codec->height = get_bits(&gb, 16) << 4;
if (thp->version >= 0x030400)
skip_bits(&gb, 100);
if (thp->version >= 0x030200) {
- width = get_bits_long(&gb, 24);
- height = get_bits_long(&gb, 24);
- if ( width <= st->codec->width && width > st->codec->width-16
- && height <= st->codec->height && height > st->codec->height-16)
- avcodec_set_dimensions(st->codec, width, height);
+ int width = get_bits_long(&gb, 24);
+ int height = get_bits_long(&gb, 24);
+ if (width <= st->codec->width && width > st->codec->width - 16 &&
+ height <= st->codec->height && height > st->codec->height - 16) {
+ st->codec->width = width;
+ st->codec->height = height;
+ }
skip_bits(&gb, 16);
}
+
timebase.den = get_bits_long(&gb, 32);
timebase.num = get_bits_long(&gb, 32);
if (!(timebase.num > 0 && timebase.den > 0)) {
@@ -105,22 +108,22 @@
skip_bits(&gb, 2);
thp->gpshift = get_bits(&gb, 5);
- thp->gpmask = (1 << thp->gpshift) - 1;
+ thp->gpmask = (1 << thp->gpshift) - 1;
st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
- st->codec->codec_id = AV_CODEC_ID_THEORA;
- st->need_parsing = AVSTREAM_PARSE_HEADERS;
+ st->codec->codec_id = AV_CODEC_ID_THEORA;
+ st->need_parsing = AVSTREAM_PARSE_HEADERS;
}
break;
case 0x81:
ff_vorbis_comment(s, &st->metadata, os->buf + os->pstart + 7, os->psize - 7);
case 0x82:
if (!thp->version)
- return -1;
+ return AVERROR_INVALIDDATA;
break;
default:
av_log(s, AV_LOG_ERROR, "Unknown header type %X\n", os->buf[os->pstart]);
- return -1;
+ return AVERROR_INVALIDDATA;
}
if ((err = av_reallocp(&st->codec->extradata,
@@ -128,21 +131,21 @@
st->codec->extradata_size = 0;
return err;
}
- cdp = st->codec->extradata + st->codec->extradata_size;
+ cdp = st->codec->extradata + st->codec->extradata_size;
*cdp++ = os->psize >> 8;
*cdp++ = os->psize & 0xff;
- memcpy (cdp, os->buf + os->pstart, os->psize);
+ memcpy(cdp, os->buf + os->pstart, os->psize);
st->codec->extradata_size = cds;
return 1;
}
-static uint64_t
-theora_gptopts(AVFormatContext *ctx, int idx, uint64_t gp, int64_t *dts)
+static uint64_t theora_gptopts(AVFormatContext *ctx, int idx, uint64_t gp,
+ int64_t *dts)
{
- struct ogg *ogg = ctx->priv_data;
+ struct ogg *ogg = ctx->priv_data;
struct ogg_stream *os = ogg->streams + idx;
- struct theora_params *thp = os->private;
+ TheoraParams *thp = os->private;
uint64_t iframe, pframe;
if (!thp)
@@ -154,7 +157,7 @@
if (thp->version < 0x030201)
iframe++;
- if(!pframe)
+ if (!pframe)
os->pflags |= AV_PKT_FLAG_KEY;
if (dts)
@@ -200,10 +203,10 @@
}
const struct ogg_codec ff_theora_codec = {
- .magic = "\200theora",
+ .magic = "\200theora",
.magicsize = 7,
- .header = theora_header,
- .packet = theora_packet,
- .gptopts = theora_gptopts,
+ .header = theora_header,
+ .packet = theora_packet,
+ .gptopts = theora_gptopts,
.nb_header = 3,
};
diff --git a/libavformat/omadec.c b/libavformat/omadec.c
index 4017db3..6a08076 100644
--- a/libavformat/omadec.c
+++ b/libavformat/omadec.c
@@ -232,9 +232,8 @@
av_log(s, AV_LOG_ERROR, "Invalid encryption header\n");
return AVERROR_INVALIDDATA;
}
- if ( OMA_ENC_HEADER_SIZE + oc->k_size + oc->e_size + oc->i_size + 8 > geob->datasize
- || OMA_ENC_HEADER_SIZE + 48 > geob->datasize
- ) {
+ if (OMA_ENC_HEADER_SIZE + oc->k_size + oc->e_size + oc->i_size + 8 > geob->datasize ||
+ OMA_ENC_HEADER_SIZE + 48 > geob->datasize) {
av_log(s, AV_LOG_ERROR, "Too little GEOB data\n");
return AVERROR_INVALIDDATA;
}
@@ -440,23 +439,16 @@
static int oma_read_probe(AVProbeData *p)
{
- const uint8_t *buf;
+ const uint8_t *buf = p->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);
+ if (p->buf_size >= ID3v2_HEADER_SIZE && ff_id3v2_match(buf, ID3v2_EA3_MAGIC))
+ 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_EXTENSION;
+ return tag_len ? AVPROBE_SCORE_EXTENSION : 0;
buf += tag_len;
diff --git a/libavformat/options_table.h b/libavformat/options_table.h
index 982eaa0..8145325 100644
--- a/libavformat/options_table.h
+++ b/libavformat/options_table.h
@@ -69,7 +69,7 @@
{"bitstream", "detect bitstream specification deviations", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_BITSTREAM }, INT_MIN, INT_MAX, D, "err_detect"},
{"buffer", "detect improper bitstream length", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_BUFFER }, INT_MIN, INT_MAX, D, "err_detect"},
{"explode", "abort decoding on minor error detection", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_EXPLODE }, INT_MIN, INT_MAX, D, "err_detect"},
-{"careful", "consider things that violate the spec and have not been seen in the wild as errors", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_CAREFUL }, INT_MIN, INT_MAX, D, "err_detect"},
+{"careful", "consider things that violate the spec, are fast to check and have not been seen in the wild as errors", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_CAREFUL }, INT_MIN, INT_MAX, D, "err_detect"},
{"compliant", "consider all spec non compliancies as errors", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_COMPLIANT }, INT_MIN, INT_MAX, D, "err_detect"},
{"aggressive", "consider things that a sane encoder shouldn't do as an error", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_AGGRESSIVE }, INT_MIN, INT_MAX, D, "err_detect"},
{"use_wallclock_as_timestamps", "use wallclock as timestamps", OFFSET(use_wallclock_as_timestamps), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX-1, D},
diff --git a/libavformat/os_support.c b/libavformat/os_support.c
index 3218956..e8f063a 100644
--- a/libavformat/os_support.c
+++ b/libavformat/os_support.c
@@ -32,13 +32,13 @@
#if !HAVE_POLL_H
#if HAVE_SYS_TIME_H
#include <sys/time.h>
-#endif
+#endif /* HAVE_SYS_TIME_H */
#if HAVE_WINSOCK2_H
#include <winsock2.h>
#elif HAVE_SYS_SELECT_H
#include <sys/select.h>
-#endif
-#endif
+#endif /* HAVE_WINSOCK2_H */
+#endif /* !HAVE_POLL_H */
#include "network.h"
@@ -82,7 +82,7 @@
win_getaddrinfo = GetProcAddress(ws2mod, "getaddrinfo");
if (win_getaddrinfo)
return win_getaddrinfo(node, service, hints, res);
-#endif
+#endif /* HAVE_WINSOCK2_H */
*res = NULL;
sin = av_mallocz(sizeof(struct sockaddr_in));
@@ -156,7 +156,7 @@
win_freeaddrinfo(res);
return;
}
-#endif
+#endif /* HAVE_WINSOCK2_H */
av_free(res->ai_canonname);
av_free(res->ai_addr);
@@ -177,7 +177,7 @@
win_getnameinfo = GetProcAddress(ws2mod, "getnameinfo");
if (win_getnameinfo)
return win_getnameinfo(sa, salen, host, hostlen, serv, servlen, flags);
-#endif
+#endif /* HAVE_WINSOCK2_H */
if (sa->sa_family != AF_INET)
return EAI_FAMILY;
@@ -208,7 +208,7 @@
#if HAVE_GETSERVBYPORT
if (!(flags & NI_NUMERICSERV))
ent = getservbyport(sin->sin_port, flags & NI_DGRAM ? "udp" : "tcp");
-#endif
+#endif /* HAVE_GETSERVBYPORT */
if (ent)
snprintf(serv, servlen, "%s", ent->s_name);
@@ -238,7 +238,7 @@
#if EAI_NODATA != EAI_NONAME
case EAI_NODATA:
return "No address associated with hostname";
-#endif
+#endif /* EAI_NODATA != EAI_NONAME */
case EAI_NONAME:
return "The name does not resolve for the supplied parameters";
case EAI_SERVICE:
@@ -261,7 +261,7 @@
return fcntl(socket, F_SETFL, fcntl(socket, F_GETFL) | O_NONBLOCK);
else
return fcntl(socket, F_SETFL, fcntl(socket, F_GETFL) & ~O_NONBLOCK);
-#endif
+#endif /* HAVE_WINSOCK2_H */
}
#if !HAVE_POLL_H
@@ -279,7 +279,7 @@
errno = EINVAL;
return -1;
}
-#endif
+#endif /* HAVE_WINSOCK2_H */
FD_ZERO(&read_set);
FD_ZERO(&write_set);
@@ -294,7 +294,7 @@
errno = EINVAL;
return -1;
}
-#endif
+#endif /* !HAVE_WINSOCK2_H */
if (fds[i].events & POLLIN)
FD_SET(fds[i].fd, &read_set);
@@ -336,5 +336,6 @@
return rc;
}
-#endif /* HAVE_POLL_H */
+#endif /* !HAVE_POLL_H */
+
#endif /* CONFIG_NETWORK */
diff --git a/libavformat/rdt.c b/libavformat/rdt.c
index 3901e21..201a3e0 100644
--- a/libavformat/rdt.c
+++ b/libavformat/rdt.c
@@ -564,7 +564,7 @@
RDT_HANDLER(video, "x-pn-realvideo", AVMEDIA_TYPE_VIDEO);
RDT_HANDLER(audio, "x-pn-realaudio", AVMEDIA_TYPE_AUDIO);
-void av_register_rdt_dynamic_payload_handlers(void)
+void ff_register_rdt_dynamic_payload_handlers(void)
{
ff_register_dynamic_payload_handler(&rdt_video_handler);
ff_register_dynamic_payload_handler(&rdt_audio_handler);
diff --git a/libavformat/rdt.h b/libavformat/rdt.h
index c2ec94b..ce6026f 100644
--- a/libavformat/rdt.h
+++ b/libavformat/rdt.h
@@ -62,7 +62,7 @@
/**
* Register RDT-related dynamic payload handlers with our cache.
*/
-void av_register_rdt_dynamic_payload_handlers(void);
+void ff_register_rdt_dynamic_payload_handlers(void);
/**
* Add subscription information to Subscribe parameter string.
diff --git a/libavformat/riff.c b/libavformat/riff.c
index 849c1bf..52640d1 100644
--- a/libavformat/riff.c
+++ b/libavformat/riff.c
@@ -85,9 +85,12 @@
{ AV_CODEC_ID_MPEG4, MKTAG('M', '4', 'T', '3') },
{ AV_CODEC_ID_MPEG4, MKTAG('G', 'E', 'O', 'X') },
/* flipped video */
+ { AV_CODEC_ID_MPEG4, MKTAG('G', '2', '6', '4') },
+ /* flipped video */
{ AV_CODEC_ID_MPEG4, MKTAG('H', 'D', 'X', '4') },
{ AV_CODEC_ID_MPEG4, MKTAG('D', 'M', '4', 'V') },
{ AV_CODEC_ID_MPEG4, MKTAG('D', 'M', 'K', '2') },
+ { AV_CODEC_ID_MPEG4, MKTAG('D', 'Y', 'M', '4') },
{ AV_CODEC_ID_MPEG4, MKTAG('D', 'I', 'G', 'I') },
{ AV_CODEC_ID_MPEG4, MKTAG('I', 'N', 'M', 'C') },
/* Ephv MPEG-4 */
@@ -256,6 +259,7 @@
{ AV_CODEC_ID_VP6F, MKTAG('V', 'P', '6', 'F') },
{ AV_CODEC_ID_VP6F, MKTAG('F', 'L', 'V', '4') },
{ AV_CODEC_ID_VP8, MKTAG('V', 'P', '8', '0') },
+ { AV_CODEC_ID_VP9, MKTAG('V', 'P', '9', '0') },
{ AV_CODEC_ID_ASV1, MKTAG('A', 'S', 'V', '1') },
{ AV_CODEC_ID_ASV2, MKTAG('A', 'S', 'V', '2') },
{ AV_CODEC_ID_VCR1, MKTAG('V', 'C', 'R', '1') },
diff --git a/libavformat/rl2.c b/libavformat/rl2.c
index ff40064..56f4cf2 100644
--- a/libavformat/rl2.c
+++ b/libavformat/rl2.c
@@ -32,6 +32,8 @@
* optional background_frame
*/
+#include <stdint.h>
+
#include "libavutil/intreadwrite.h"
#include "libavutil/mathematics.h"
#include "avformat.h"
diff --git a/libavformat/rmdec.c b/libavformat/rmdec.c
index a79fbaf..b0876fe 100644
--- a/libavformat/rmdec.c
+++ b/libavformat/rmdec.c
@@ -680,16 +680,20 @@
pos = get_num(pb, &len);
pic_num = avio_r8(pb); len--;
}
- if(len<0)
+ if(len<0) {
+ av_log(s, AV_LOG_ERROR, "Insufficient data\n");
return -1;
+ }
rm->remaining_len = len;
if(type&1){ // frame, not slice
if(type == 3){ // frame as a part of packet
len= len2;
*timestamp = pos;
}
- if(rm->remaining_len < len)
+ if(rm->remaining_len < len) {
+ av_log(s, AV_LOG_ERROR, "Insufficient remaining len\n");
return -1;
+ }
rm->remaining_len -= len;
if(av_new_packet(pkt, len + 9) < 0)
return AVERROR(EIO);
@@ -698,6 +702,7 @@
AV_WL32(pkt->data + 5, 0);
if ((ret = avio_read(pb, pkt->data + 9, len)) != len) {
av_free_packet(pkt);
+ av_log(s, AV_LOG_ERROR, "Failed to read %d bytes\n", len);
return ret < 0 ? ret : AVERROR(EIO);
}
return 0;
@@ -724,14 +729,18 @@
if(type == 2)
len = FFMIN(len, pos);
- if(++vst->cur_slice > vst->slices)
+ if(++vst->cur_slice > vst->slices) {
+ av_log(s, AV_LOG_ERROR, "cur slice %d, too large\n", vst->cur_slice);
return 1;
+ }
if(!vst->pkt.data)
return AVERROR(ENOMEM);
AV_WL32(vst->pkt.data - 7 + 8*vst->cur_slice, 1);
AV_WL32(vst->pkt.data - 3 + 8*vst->cur_slice, vst->videobufpos - 8*vst->slices - 1);
- if(vst->videobufpos + len > vst->videobufsize)
+ if(vst->videobufpos + len > vst->videobufsize) {
+ av_log(s, AV_LOG_ERROR, "outside videobufsize\n");
return 1;
+ }
if (avio_read(pb, vst->pkt.data + vst->videobufpos, len) != len)
return AVERROR(EIO);
vst->videobufpos += len;
@@ -788,7 +797,7 @@
rm->current_stream= st->id;
ret = rm_assemble_video_frame(s, pb, rm, ast, pkt, len, seq, ×tamp);
if(ret)
- return ret; //got partial frame or error
+ return ret < 0 ? ret : -1; //got partial frame or error
} else if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
if ((ast->deint_id == DEINT_ID_GENR) ||
(ast->deint_id == DEINT_ID_INT4) ||
diff --git a/libavformat/rpl.c b/libavformat/rpl.c
index 61a2316..85b573e 100644
--- a/libavformat/rpl.c
+++ b/libavformat/rpl.c
@@ -19,11 +19,13 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <stdint.h>
+#include <stdlib.h>
+
#include "libavutil/avstring.h"
#include "libavutil/dict.h"
#include "avformat.h"
#include "internal.h"
-#include <stdlib.h>
#define RPL_SIGNATURE "ARMovie\x0A"
#define RPL_SIGNATURE_SIZE 8
diff --git a/libavformat/rsd.c b/libavformat/rsd.c
index 37e544a..341f638 100644
--- a/libavformat/rsd.c
+++ b/libavformat/rsd.c
@@ -43,10 +43,13 @@
static int rsd_probe(AVProbeData *p)
{
- if (!memcmp(p->buf, "RSD", 3) &&
- p->buf[3] - '0' >= 2 && p->buf[3] - '0' <= 6)
- return AVPROBE_SCORE_EXTENSION;
- return 0;
+ if (memcmp(p->buf, "RSD", 3) || p->buf[3] - '0' < 2 || p->buf[3] - '0' > 6)
+ return 0;
+ if (AV_RL32(p->buf + 8) > 256 || !AV_RL32(p->buf + 8))
+ return AVPROBE_SCORE_MAX / 8;
+ if (AV_RL32(p->buf + 16) > 8*48000 || !AV_RL32(p->buf + 16))
+ return AVPROBE_SCORE_MAX / 8;
+ return AVPROBE_SCORE_MAX;
}
static int rsd_read_header(AVFormatContext *s)
diff --git a/libavformat/rtmphttp.c b/libavformat/rtmphttp.c
index 49909ee..0334ba5 100644
--- a/libavformat/rtmphttp.c
+++ b/libavformat/rtmphttp.c
@@ -113,7 +113,7 @@
if (ret < 0 && ret != AVERROR_EOF)
return ret;
- if (ret == AVERROR_EOF) {
+ if (!ret || ret == AVERROR_EOF) {
if (rt->finishing) {
/* Do not send new requests when the client wants to
* close the connection. */
@@ -227,7 +227,7 @@
/* read the server reply which contains a unique ID */
for (;;) {
ret = ffurl_read(rt->stream, rt->client_id + off, sizeof(rt->client_id) - off);
- if (ret == AVERROR_EOF)
+ if (!ret || ret == AVERROR_EOF)
break;
if (ret < 0)
goto fail;
diff --git a/libavformat/rtpdec.c b/libavformat/rtpdec.c
index b2342f1..ed118b0 100644
--- a/libavformat/rtpdec.c
+++ b/libavformat/rtpdec.c
@@ -32,6 +32,12 @@
#define MIN_FEEDBACK_INTERVAL 200000 /* 200 ms in us */
+static RTPDynamicProtocolHandler gsm_dynamic_handler = {
+ .enc_name = "GSM",
+ .codec_type = AVMEDIA_TYPE_AUDIO,
+ .codec_id = AV_CODEC_ID_GSM,
+};
+
static RTPDynamicProtocolHandler realmedia_mp3_dynamic_handler = {
.enc_name = "X-MP3-draft-00",
.codec_type = AVMEDIA_TYPE_AUDIO,
@@ -58,7 +64,7 @@
rtp_first_dynamic_payload_handler = handler;
}
-void av_register_rtp_dynamic_payload_handlers(void)
+void ff_register_rtp_dynamic_payload_handlers(void)
{
ff_register_dynamic_payload_handler(&ff_amr_nb_dynamic_handler);
ff_register_dynamic_payload_handler(&ff_amr_wb_dynamic_handler);
@@ -90,6 +96,7 @@
ff_register_dynamic_payload_handler(&ff_theora_dynamic_handler);
ff_register_dynamic_payload_handler(&ff_vorbis_dynamic_handler);
ff_register_dynamic_payload_handler(&ff_vp8_dynamic_handler);
+ ff_register_dynamic_payload_handler(&gsm_dynamic_handler);
ff_register_dynamic_payload_handler(&opus_dynamic_handler);
ff_register_dynamic_payload_handler(&realmedia_mp3_dynamic_handler);
ff_register_dynamic_payload_handler(&speex_dynamic_handler);
diff --git a/libavformat/rtpdec.h b/libavformat/rtpdec.h
index 2a191ec..9321066 100644
--- a/libavformat/rtpdec.h
+++ b/libavformat/rtpdec.h
@@ -205,7 +205,7 @@
PayloadContext *data,
char *attr, char *value));
-void av_register_rtp_dynamic_payload_handlers(void);
+void ff_register_rtp_dynamic_payload_handlers(void);
/**
* Close the dynamic buffer and make a packet from it.
diff --git a/libavformat/rtpenc.c b/libavformat/rtpenc.c
index 9fd361d..6fdc908 100644
--- a/libavformat/rtpenc.c
+++ b/libavformat/rtpenc.c
@@ -262,7 +262,7 @@
}
/* send an rtcp sender report packet */
-static void rtcp_send_sr(AVFormatContext *s1, int64_t ntp_time)
+static void rtcp_send_sr(AVFormatContext *s1, int64_t ntp_time, int bye)
{
RTPMuxContext *s = s1->priv_data;
uint32_t rtp_ts;
@@ -272,7 +272,7 @@
s->last_rtcp_ntp_time = ntp_time;
rtp_ts = av_rescale_q(ntp_time - s->first_rtcp_ntp_time, (AVRational){1, 1000000},
s1->streams[0]->time_base) + s->base_timestamp;
- avio_w8(s1->pb, (RTP_VERSION << 6));
+ avio_w8(s1->pb, RTP_VERSION << 6);
avio_w8(s1->pb, RTCP_SR);
avio_wb16(s1->pb, 6); /* length in words - 1 */
avio_wb32(s1->pb, s->ssrc);
@@ -296,6 +296,13 @@
avio_w8(s1->pb, 0);
}
+ if (bye) {
+ avio_w8(s1->pb, (RTP_VERSION << 6) | 1);
+ avio_w8(s1->pb, RTCP_BYE);
+ avio_wb16(s1->pb, 1); /* length in words - 1 */
+ avio_wb32(s1->pb, s->ssrc);
+ }
+
avio_flush(s1->pb);
}
@@ -308,7 +315,7 @@
av_dlog(s1, "rtp_send_data size=%d\n", len);
/* build the RTP header */
- avio_w8(s1->pb, (RTP_VERSION << 6));
+ avio_w8(s1->pb, RTP_VERSION << 6);
avio_w8(s1->pb, (s->payload_type & 0x7f) | ((m & 0x01) << 7));
avio_wb16(s1->pb, s->seq);
avio_wb32(s1->pb, s->timestamp);
@@ -494,7 +501,7 @@
if ((s->first_packet || ((rtcp_bytes >= RTCP_SR_SIZE) &&
(ff_ntp_time() - s->last_rtcp_ntp_time > 5000000))) &&
!(s->flags & FF_RTP_FLAG_SKIP_RTCP)) {
- rtcp_send_sr(s1, ff_ntp_time());
+ rtcp_send_sr(s1, ff_ntp_time(), 0);
s->last_octet_count = s->octet_count;
s->first_packet = 0;
}
@@ -590,6 +597,10 @@
{
RTPMuxContext *s = s1->priv_data;
+ /* If the caller closes and recreates ->pb, this might actually
+ * be NULL here even if it was successfully allocated at the start. */
+ if (s1->pb && (s->flags & FF_RTP_FLAG_SEND_BYE))
+ rtcp_send_sr(s1, ff_ntp_time(), 1);
av_freep(&s->buf);
return 0;
diff --git a/libavformat/rtpenc.h b/libavformat/rtpenc.h
index b0c9630..913d05a 100644
--- a/libavformat/rtpenc.h
+++ b/libavformat/rtpenc.h
@@ -68,13 +68,15 @@
#define FF_RTP_FLAG_RFC2190 2
#define FF_RTP_FLAG_SKIP_RTCP 4
#define FF_RTP_FLAG_H264_MODE0 8
+#define FF_RTP_FLAG_SEND_BYE 16
#define FF_RTP_FLAG_OPTS(ctx, fieldname) \
{ "rtpflags", "RTP muxer flags", offsetof(ctx, fieldname), AV_OPT_TYPE_FLAGS, {.i64 = 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, {.i64 = FF_RTP_FLAG_MP4A_LATM}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "rtpflags" }, \
{ "rfc2190", "Use RFC 2190 packetization instead of RFC 4629 for H.263", 0, AV_OPT_TYPE_CONST, {.i64 = FF_RTP_FLAG_RFC2190}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "rtpflags" }, \
{ "skip_rtcp", "Don't send RTCP sender reports", 0, AV_OPT_TYPE_CONST, {.i64 = FF_RTP_FLAG_SKIP_RTCP}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "rtpflags" }, \
- { "h264_mode0", "Use mode 0 for H264 in RTP", 0, AV_OPT_TYPE_CONST, {.i64 = FF_RTP_FLAG_H264_MODE0}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "rtpflags" } \
+ { "h264_mode0", "Use mode 0 for H264 in RTP", 0, AV_OPT_TYPE_CONST, {.i64 = FF_RTP_FLAG_H264_MODE0}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "rtpflags" }, \
+ { "send_bye", "Send RTCP BYE packets when finishing", 0, AV_OPT_TYPE_CONST, {.i64 = FF_RTP_FLAG_SEND_BYE}, 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/rtpproto.c b/libavformat/rtpproto.c
index bf9c60d..a8cbd97 100644
--- a/libavformat/rtpproto.c
+++ b/libavformat/rtpproto.c
@@ -281,6 +281,7 @@
char buf[1024];
char path[1024];
const char *p;
+ int i, max_retry_count = 3;
av_url_split(NULL, 0, NULL, 0, hostname, sizeof(hostname), &rtp_port,
path, sizeof(path), uri);
@@ -328,19 +329,35 @@
}
}
- build_udp_url(buf, sizeof(buf),
- hostname, rtp_port, local_rtp_port, ttl, max_packet_size,
- connect, include_sources, exclude_sources);
- 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;
-
- build_udp_url(buf, sizeof(buf),
- hostname, rtcp_port, local_rtcp_port, ttl, max_packet_size,
- connect, include_sources, exclude_sources);
- if (ffurl_open(&s->rtcp_hd, buf, flags, &h->interrupt_callback, NULL) < 0)
- goto fail;
+ for (i = 0;i < max_retry_count;i++) {
+ build_udp_url(buf, sizeof(buf),
+ hostname, rtp_port, local_rtp_port, ttl, max_packet_size,
+ connect, include_sources, exclude_sources);
+ if (ffurl_open(&s->rtp_hd, buf, flags, &h->interrupt_callback, NULL) < 0)
+ goto fail;
+ local_rtp_port = ff_udp_get_local_port(s->rtp_hd);
+ if(local_rtp_port == 65535) {
+ local_rtp_port = -1;
+ continue;
+ }
+ if (local_rtcp_port<0) {
+ local_rtcp_port = local_rtp_port + 1;
+ build_udp_url(buf, sizeof(buf),
+ hostname, rtcp_port, local_rtcp_port, ttl, max_packet_size,
+ connect, include_sources, exclude_sources);
+ if (ffurl_open(&s->rtcp_hd, buf, flags, &h->interrupt_callback, NULL) < 0) {
+ local_rtp_port = local_rtcp_port = -1;
+ continue;
+ }
+ break;
+ }
+ build_udp_url(buf, sizeof(buf),
+ hostname, rtcp_port, local_rtcp_port, ttl, max_packet_size,
+ connect, include_sources, exclude_sources);
+ if (ffurl_open(&s->rtcp_hd, buf, flags, &h->interrupt_callback, NULL) < 0)
+ goto fail;
+ break;
+ }
/* just to ease handle access. XXX: need to suppress direct handle
access */
diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c
index 2abb36b..3b88fc7 100644
--- a/libavformat/rtsp.c
+++ b/libavformat/rtsp.c
@@ -641,7 +641,7 @@
}
#endif /* CONFIG_RTPDEC */
-void ff_rtsp_undo_setup(AVFormatContext *s)
+void ff_rtsp_undo_setup(AVFormatContext *s, int send_packets)
{
RTSPState *rt = s->priv_data;
int i;
@@ -656,6 +656,8 @@
av_write_trailer(rtpctx);
if (rt->lower_transport == RTSP_LOWER_TRANSPORT_TCP) {
uint8_t *ptr;
+ if (CONFIG_RTSP_MUXER && rtpctx->pb && send_packets)
+ ff_rtsp_tcp_write_packet(s, rtsp_st);
avio_close_dyn_buf(rtpctx->pb, &ptr);
av_free(ptr);
} else {
@@ -681,7 +683,7 @@
int i, j;
RTSPStream *rtsp_st;
- ff_rtsp_undo_setup(s);
+ ff_rtsp_undo_setup(s, 0);
for (i = 0; i < rt->nb_rtsp_streams; i++) {
rtsp_st = rt->rtsp_streams[i];
if (rtsp_st) {
@@ -1547,7 +1549,7 @@
return 0;
fail:
- ff_rtsp_undo_setup(s);
+ ff_rtsp_undo_setup(s, 0);
return err;
}
diff --git a/libavformat/rtsp.h b/libavformat/rtsp.h
index 2dc4b6c..76c7f18 100644
--- a/libavformat/rtsp.h
+++ b/libavformat/rtsp.h
@@ -598,6 +598,11 @@
uint8_t *buf, int buf_size);
/**
+ * Send buffered packets over TCP.
+ */
+int ff_rtsp_tcp_write_packet(AVFormatContext *s, RTSPStream *rtsp_st);
+
+/**
* Receive one packet from the RTSPStreams set up in the AVFormatContext
* (which should contain a RTSPState struct as priv_data).
*/
@@ -615,7 +620,7 @@
* Undo the effect of ff_rtsp_make_setup_request, close the
* transport_priv and rtp_handle fields.
*/
-void ff_rtsp_undo_setup(AVFormatContext *s);
+void ff_rtsp_undo_setup(AVFormatContext *s, int send_packets);
/**
* Open RTSP transport context.
diff --git a/libavformat/rtspdec.c b/libavformat/rtspdec.c
index 3615226..eb650ff 100644
--- a/libavformat/rtspdec.c
+++ b/libavformat/rtspdec.c
@@ -769,7 +769,7 @@
av_url_split(NULL, 0, NULL, 0, host, sizeof(host), &port, NULL, 0,
s->filename);
- ff_rtsp_undo_setup(s);
+ ff_rtsp_undo_setup(s, 0);
return ff_rtsp_make_setup_request(s, host, port, RTSP_LOWER_TRANSPORT_TCP,
rt->real_challenge);
}
diff --git a/libavformat/rtspenc.c b/libavformat/rtspenc.c
index bea1831..d76ae87 100644
--- a/libavformat/rtspenc.c
+++ b/libavformat/rtspenc.c
@@ -136,7 +136,7 @@
return 0;
}
-static int tcp_write_packet(AVFormatContext *s, RTSPStream *rtsp_st)
+int ff_rtsp_tcp_write_packet(AVFormatContext *s, RTSPStream *rtsp_st)
{
RTSPState *rt = s->priv_data;
AVFormatContext *rtpctx = rtsp_st->transport_priv;
@@ -217,7 +217,7 @@
* packets, so we need to send them out on the TCP connection separately.
*/
if (!ret && rt->lower_transport == RTSP_LOWER_TRANSPORT_TCP)
- ret = tcp_write_packet(s, rtsp_st);
+ ret = ff_rtsp_tcp_write_packet(s, rtsp_st);
return ret;
}
@@ -225,6 +225,11 @@
{
RTSPState *rt = s->priv_data;
+ // If we want to send RTCP_BYE packets, these are sent by av_write_trailer.
+ // Thus call this on all streams before doing the teardown. This is
+ // done within ff_rtsp_undo_setup.
+ ff_rtsp_undo_setup(s, 1);
+
ff_rtsp_send_cmd_async(s, "TEARDOWN", rt->control_uri, NULL);
ff_rtsp_close_streams(s);
diff --git a/libavformat/seek.c b/libavformat/seek.c
index 0ae99eb..bb5ca87 100644
--- a/libavformat/seek.c
+++ b/libavformat/seek.c
@@ -20,6 +20,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <stdint.h>
+
#include "seek.h"
#include "libavutil/mathematics.h"
#include "libavutil/mem.h"
@@ -428,13 +430,11 @@
ss->parser = st->parser;
ss->last_IP_pts = st->last_IP_pts;
ss->cur_dts = st->cur_dts;
- ss->reference_dts = st->reference_dts;
ss->probe_packets = st->probe_packets;
st->parser = NULL;
st->last_IP_pts = AV_NOPTS_VALUE;
st->cur_dts = AV_NOPTS_VALUE;
- st->reference_dts = AV_NOPTS_VALUE;
st->probe_packets = MAX_PROBE_PACKETS;
}
@@ -467,7 +467,6 @@
st->parser = ss->parser;
st->last_IP_pts = ss->last_IP_pts;
st->cur_dts = ss->cur_dts;
- st->reference_dts = ss->reference_dts;
st->probe_packets = ss->probe_packets;
}
diff --git a/libavformat/seek.h b/libavformat/seek.h
index b27cb42..3fa7ae3 100644
--- a/libavformat/seek.h
+++ b/libavformat/seek.h
@@ -33,7 +33,6 @@
AVCodecParserContext *parser;
int64_t last_IP_pts;
int64_t cur_dts;
- int64_t reference_dts;
int probe_packets;
} AVParserStreamState;
diff --git a/libavformat/segafilm.c b/libavformat/segafilm.c
index a56568c..8a0e8bc 100644
--- a/libavformat/segafilm.c
+++ b/libavformat/segafilm.c
@@ -69,6 +69,9 @@
if (AV_RB32(&p->buf[0]) != FILM_TAG)
return 0;
+ if (AV_RB32(&p->buf[16]) != FDSC_TAG)
+ return 0;
+
return AVPROBE_SCORE_MAX;
}
diff --git a/libavformat/segment.c b/libavformat/segment.c
index 05e29d4..f07f464 100644
--- a/libavformat/segment.c
+++ b/libavformat/segment.c
@@ -44,7 +44,7 @@
double start_time, end_time;
int64_t start_pts;
int64_t offset_pts;
- char filename[1024];
+ char *filename;
struct SegmentListEntry *next;
} SegmentListEntry;
@@ -72,6 +72,7 @@
char *list; ///< filename for the segment list file
int list_flags; ///< flags affecting list generation
int list_size; ///< number of entries for the segment list file
+ char *list_entry_prefix; ///< prefix to add to list entry filenames
ListType list_type; ///< set the list type
AVIOContext *list_pb; ///< list file put-byte context
char *time_str; ///< segment duration specification string
@@ -158,6 +159,7 @@
{
SegmentContext *seg = s->priv_data;
AVFormatContext *oc = seg->avf;
+ size_t size;
if (seg->segment_idx_wrap)
seg->segment_idx %= seg->segment_idx_wrap;
@@ -166,7 +168,19 @@
av_log(oc, AV_LOG_ERROR, "Invalid segment filename template '%s'\n", s->filename);
return AVERROR(EINVAL);
}
- av_strlcpy(seg->cur_entry.filename, oc->filename, sizeof(seg->cur_entry.filename));
+
+ /* copy modified name in list entry */
+ size = strlen(av_basename(oc->filename)) + 1;
+ if (seg->list_entry_prefix)
+ size += strlen(seg->list_entry_prefix);
+
+ seg->cur_entry.filename = av_mallocz(size);
+ if (!seg->cur_entry.filename)
+ return AVERROR(ENOMEM);
+ snprintf(seg->cur_entry.filename, size, "%s%s",
+ seg->list_entry_prefix ? seg->list_entry_prefix : "",
+ av_basename(oc->filename));
+
return 0;
}
@@ -189,8 +203,10 @@
return err;
if ((err = avio_open2(&oc->pb, oc->filename, AVIO_FLAG_WRITE,
- &s->interrupt_callback, NULL)) < 0)
+ &s->interrupt_callback, NULL)) < 0) {
+ av_log(s, AV_LOG_ERROR, "Failed to open segment '%s'\n", oc->filename);
return err;
+ }
if (oc->oformat->priv_class && oc->priv_data)
av_opt_set(oc->priv_data, "resend_headers", "1", 0); /* mpegts specific */
@@ -211,8 +227,10 @@
ret = avio_open2(&seg->list_pb, seg->list, AVIO_FLAG_WRITE,
&s->interrupt_callback, NULL);
- if (ret < 0)
+ if (ret < 0) {
+ av_log(s, AV_LOG_ERROR, "Failed to open segment list '%s'\n", seg->list);
return ret;
+ }
if (seg->list_type == LIST_TYPE_M3U8 && seg->segment_list_entries) {
SegmentListEntry *entry;
@@ -303,6 +321,7 @@
if (seg->list_size && seg->segment_count > seg->list_size) {
entry = seg->segment_list_entries;
seg->segment_list_entries = seg->segment_list_entries->next;
+ av_free(entry->filename);
av_freep(&entry);
}
@@ -600,8 +619,10 @@
if (seg->write_header_trailer) {
if ((ret = avio_open2(&oc->pb, oc->filename, AVIO_FLAG_WRITE,
- &s->interrupt_callback, NULL)) < 0)
+ &s->interrupt_callback, NULL)) < 0) {
+ av_log(s, AV_LOG_ERROR, "Failed to open segment '%s'\n", oc->filename);
goto fail;
+ }
} else {
if ((ret = open_null_ctx(&oc->pb)) < 0)
goto fail;
@@ -746,6 +767,7 @@
cur = seg->segment_list_entries;
while (cur) {
next = cur->next;
+ av_free(cur->filename);
av_free(cur);
cur = next;
}
@@ -766,6 +788,7 @@
{ "live", "enable live-friendly list generation (useful for HLS)", 0, AV_OPT_TYPE_CONST, {.i64 = SEGMENT_LIST_FLAG_LIVE }, INT_MIN, INT_MAX, E, "list_flags"},
{ "segment_list_size", "set the maximum number of playlist entries", OFFSET(list_size), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, E },
+ { "segment_list_entry_prefix", "set prefix to prepend to each list entry filename", OFFSET(list_entry_prefix), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E },
{ "segment_list_type", "set the segment list type", OFFSET(list_type), AV_OPT_TYPE_INT, {.i64 = LIST_TYPE_UNDEFINED}, -1, LIST_TYPE_NB-1, E, "list_type" },
{ "flat", "flat format", 0, AV_OPT_TYPE_CONST, {.i64=LIST_TYPE_FLAT }, INT_MIN, INT_MAX, E, "list_type" },
diff --git a/libavformat/smacker.c b/libavformat/smacker.c
index 527faf7..0d38588 100644
--- a/libavformat/smacker.c
+++ b/libavformat/smacker.c
@@ -92,11 +92,14 @@
static int smacker_probe(AVProbeData *p)
{
- if(p->buf[0] == 'S' && p->buf[1] == 'M' && p->buf[2] == 'K'
- && (p->buf[3] == '2' || p->buf[3] == '4'))
- return AVPROBE_SCORE_MAX;
- else
+ if ( AV_RL32(p->buf) != MKTAG('S', 'M', 'K', '2')
+ && AV_RL32(p->buf) != MKTAG('S', 'M', 'K', '4'))
return 0;
+
+ if (AV_RL32(p->buf+4) > 32768U || AV_RL32(p->buf+8) > 32768U)
+ return AVPROBE_SCORE_MAX/4;
+
+ return AVPROBE_SCORE_MAX;
}
static int smacker_read_header(AVFormatContext *s)
diff --git a/libavformat/spdifdec.c b/libavformat/spdifdec.c
index 6984350..7da16c9 100644
--- a/libavformat/spdifdec.c
+++ b/libavformat/spdifdec.c
@@ -57,7 +57,7 @@
break;
case IEC61937_MPEG2_AAC:
init_get_bits(&gbc, buf, AAC_ADTS_HEADER_SIZE * 8);
- if (avpriv_aac_parse_header(&gbc, &aac_hdr)) {
+ if (avpriv_aac_parse_header(&gbc, &aac_hdr) < 0) {
if (s) /* be silent during a probe */
av_log(s, AV_LOG_ERROR, "Invalid AAC packet in IEC 61937\n");
return AVERROR_INVALIDDATA;
diff --git a/libavformat/swfdec.c b/libavformat/swfdec.c
index 54e0f6d..e6ceec8 100644
--- a/libavformat/swfdec.c
+++ b/libavformat/swfdec.c
@@ -55,12 +55,18 @@
static int swf_probe(AVProbeData *p)
{
- /* check file header */
- if ((p->buf[0] == 'F' || p->buf[0] == 'C') && p->buf[1] == 'W' &&
- p->buf[2] == 'S')
- return AVPROBE_SCORE_MAX;
- else
+ if(p->buf_size < 15)
return 0;
+
+ /* check file header */
+ if ( AV_RB24(p->buf) != AV_RB24("CWS")
+ && AV_RB24(p->buf) != AV_RB24("FWS"))
+ return 0;
+
+ if (p->buf[3] >= 20)
+ return AVPROBE_SCORE_MAX / 4;
+
+ return AVPROBE_SCORE_MAX;
}
#if CONFIG_ZLIB
diff --git a/libavformat/tee.c b/libavformat/tee.c
index 40b59a4..12ea0ea 100644
--- a/libavformat/tee.c
+++ b/libavformat/tee.c
@@ -102,10 +102,10 @@
static int parse_bsfs(void *log_ctx, const char *bsfs_spec,
AVBitStreamFilterContext **bsfs)
{
- char *bsf_name, *buf, *saveptr;
+ char *bsf_name, *buf, *dup, *saveptr;
int ret = 0;
- if (!(buf = av_strdup(bsfs_spec)))
+ if (!(dup = buf = av_strdup(bsfs_spec)))
return AVERROR(ENOMEM);
while (bsf_name = av_strtok(buf, ",", &saveptr)) {
@@ -128,7 +128,7 @@
}
end:
- av_free(buf);
+ av_free(dup);
return ret;
}
@@ -280,6 +280,7 @@
end:
av_free(format);
+ av_free(select);
av_dict_free(&options);
return ret;
}
@@ -302,6 +303,7 @@
}
}
av_freep(&tee->slaves[i].stream_map);
+ av_freep(&tee->slaves[i].bsfs);
avio_close(avf2->pb);
avf2->pb = NULL;
diff --git a/libavformat/thp.c b/libavformat/thp.c
index 3717b8f..bc4f0daf 100644
--- a/libavformat/thp.c
+++ b/libavformat/thp.c
@@ -26,15 +26,15 @@
typedef struct ThpDemuxContext {
int version;
- int first_frame;
- int first_framesz;
- int last_frame;
+ unsigned first_frame;
+ unsigned first_framesz;
+ unsigned last_frame;
int compoff;
- int framecnt;
+ unsigned framecnt;
AVRational fps;
- int frame;
- int next_frame;
- int next_framesz;
+ unsigned frame;
+ int64_t next_frame;
+ unsigned next_framesz;
int video_stream_index;
int audio_stream_index;
int compcount;
@@ -47,11 +47,16 @@
static int thp_probe(AVProbeData *p)
{
+ double d;
/* check file header */
- if (AV_RL32(p->buf) == MKTAG('T', 'H', 'P', '\0'))
- return AVPROBE_SCORE_MAX;
- else
+ if (AV_RL32(p->buf) != MKTAG('T', 'H', 'P', '\0'))
return 0;
+
+ d = av_int2float(AV_RB32(p->buf + 16));
+ if (d < 0.1 || d > 1000 || isnan(d))
+ return AVPROBE_SCORE_MAX/4;
+
+ return AVPROBE_SCORE_MAX;
}
static int thp_read_header(AVFormatContext *s)
@@ -109,7 +114,6 @@
st->codec->codec_tag = 0; /* no fourcc */
st->codec->width = avio_rb32(pb);
st->codec->height = avio_rb32(pb);
- st->codec->sample_rate = av_q2d(thp->fps);
st->nb_frames =
st->duration = thp->framecnt;
thp->vst = st;
@@ -158,7 +162,7 @@
avio_seek(pb, thp->next_frame, SEEK_SET);
/* Locate the next frame and read out its size. */
- thp->next_frame += thp->next_framesz;
+ thp->next_frame += FFMAX(thp->next_framesz, 1);
thp->next_framesz = avio_rb32(pb);
avio_rb32(pb); /* Previous total size. */
diff --git a/libavformat/url.h b/libavformat/url.h
index 06dfda1..712ea0f 100644
--- a/libavformat/url.h
+++ b/libavformat/url.h
@@ -101,7 +101,7 @@
* 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
+ * @return >= 0 in case of success, a negative value corresponding to an
* AVERROR code in case of failure
*/
int ffurl_alloc(URLContext **puc, const char *filename, int flags,
@@ -130,7 +130,7 @@
* @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
+ * @return >= 0 in case of success, a negative value corresponding to an
* AVERROR code in case of failure
*/
int ffurl_open(URLContext **puc, const char *filename, int flags,
@@ -226,10 +226,8 @@
/**
* Register the URLProtocol protocol.
- *
- * @param size the size of the URLProtocol struct referenced
*/
-int ffurl_register_protocol(URLProtocol *protocol, int size);
+int ffurl_register_protocol(URLProtocol *protocol);
/**
* Check if the user has requested to interrup a blocking function
diff --git a/libavformat/utils.c b/libavformat/utils.c
index 50f7d87..fc4de4c 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -19,6 +19,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <stdint.h>
+
#include "avformat.h"
#include "avio_internal.h"
#include "internal.h"
@@ -399,6 +401,11 @@
av_log(logctx, AV_LOG_WARNING, "Format %s detected only with low score of %d, misdetection possible!\n", (*fmt)->name, score);
}else
av_log(logctx, AV_LOG_DEBUG, "Format %s probed with size=%d and score=%d\n", (*fmt)->name, probe_size, score);
+#if 0
+ FILE *f = fopen("probestat.tmp", "ab");
+ fprintf(f, "probe_size:%d format:%s score:%d filename:%s\n", probe_size, (*fmt)->name, score, filename);
+ fclose(f);
+#endif
}
}
@@ -646,6 +653,70 @@
return 0;
}
+static int update_wrap_reference(AVFormatContext *s, AVStream *st, int stream_index, AVPacket *pkt)
+{
+ int64_t ref = pkt->dts;
+ int i, pts_wrap_behavior;
+ int64_t pts_wrap_reference;
+ AVProgram *first_program;
+
+ if (ref == AV_NOPTS_VALUE)
+ ref = pkt->pts;
+ if (st->pts_wrap_reference != AV_NOPTS_VALUE || st->pts_wrap_bits >= 63 || ref == AV_NOPTS_VALUE || !s->correct_ts_overflow)
+ return 0;
+ ref &= (1LL<<st->pts_wrap_bits)-1;
+
+ // reference time stamp should be 60 s before first time stamp
+ pts_wrap_reference = ref - av_rescale(60, st->time_base.den, st->time_base.num);
+ // if first time stamp is not more than 1/8 and 60s before the wrap point, subtract rather than add wrap offset
+ pts_wrap_behavior = (ref < (1LL<<st->pts_wrap_bits) - (1LL<<st->pts_wrap_bits-3)) ||
+ (ref < (1LL<<st->pts_wrap_bits) - av_rescale(60, st->time_base.den, st->time_base.num)) ?
+ AV_PTS_WRAP_ADD_OFFSET : AV_PTS_WRAP_SUB_OFFSET;
+
+ first_program = av_find_program_from_stream(s, NULL, stream_index);
+
+ if (!first_program) {
+ int default_stream_index = av_find_default_stream_index(s);
+ if (s->streams[default_stream_index]->pts_wrap_reference == AV_NOPTS_VALUE) {
+ for (i=0; i<s->nb_streams; i++) {
+ s->streams[i]->pts_wrap_reference = pts_wrap_reference;
+ s->streams[i]->pts_wrap_behavior = pts_wrap_behavior;
+ }
+ }
+ else {
+ st->pts_wrap_reference = s->streams[default_stream_index]->pts_wrap_reference;
+ st->pts_wrap_behavior = s->streams[default_stream_index]->pts_wrap_behavior;
+ }
+ }
+ else {
+ AVProgram *program = first_program;
+ while (program) {
+ if (program->pts_wrap_reference != AV_NOPTS_VALUE) {
+ pts_wrap_reference = program->pts_wrap_reference;
+ pts_wrap_behavior = program->pts_wrap_behavior;
+ break;
+ }
+ program = av_find_program_from_stream(s, program, stream_index);
+ }
+
+ // update every program with differing pts_wrap_reference
+ program = first_program;
+ while(program) {
+ if (program->pts_wrap_reference != pts_wrap_reference) {
+ for (i=0; i<program->nb_stream_indexes; i++) {
+ s->streams[program->stream_index[i]]->pts_wrap_reference = pts_wrap_reference;
+ s->streams[program->stream_index[i]]->pts_wrap_behavior = pts_wrap_behavior;
+ }
+
+ program->pts_wrap_reference = pts_wrap_reference;
+ program->pts_wrap_behavior = pts_wrap_behavior;
+ }
+ program = av_find_program_from_stream(s, program, stream_index);
+ }
+ }
+ return 1;
+}
+
int ff_read_packet(AVFormatContext *s, AVPacket *pkt)
{
int ret, i, err;
@@ -696,15 +767,23 @@
continue;
}
- if(!(s->flags & AVFMT_FLAG_KEEP_SIDE_DATA))
- av_packet_merge_side_data(pkt);
-
if(pkt->stream_index >= (unsigned)s->nb_streams){
av_log(s, AV_LOG_ERROR, "Invalid stream index %d\n", pkt->stream_index);
continue;
}
st= s->streams[pkt->stream_index];
+
+ if (update_wrap_reference(s, st, pkt->stream_index, pkt) && st->pts_wrap_behavior == AV_PTS_WRAP_SUB_OFFSET) {
+ // correct first time stamps to negative values
+ if (!is_relative(st->first_dts))
+ st->first_dts = wrap_timestamp(st, st->first_dts);
+ if (!is_relative(st->start_time))
+ st->start_time = wrap_timestamp(st, st->start_time);
+ if (!is_relative(st->cur_dts))
+ st->cur_dts = wrap_timestamp(st, st->cur_dts);
+ }
+
pkt->dts = wrap_timestamp(st, pkt->dts);
pkt->pts = wrap_timestamp(st, pkt->pts);
@@ -864,65 +943,6 @@
return NULL;
}
-static int update_wrap_reference(AVFormatContext *s, AVStream *st, int stream_index)
-{
- if (s->correct_ts_overflow && st->pts_wrap_bits < 63 &&
- st->pts_wrap_reference == AV_NOPTS_VALUE && st->first_dts != AV_NOPTS_VALUE) {
- int i;
-
- // reference time stamp should be 60 s before first time stamp
- int64_t pts_wrap_reference = st->first_dts - av_rescale(60, st->time_base.den, st->time_base.num);
- // if first time stamp is not more than 1/8 and 60s before the wrap point, subtract rather than add wrap offset
- int pts_wrap_behavior = (st->first_dts < (1LL<<st->pts_wrap_bits) - (1LL<<st->pts_wrap_bits-3)) ||
- (st->first_dts < (1LL<<st->pts_wrap_bits) - av_rescale(60, st->time_base.den, st->time_base.num)) ?
- AV_PTS_WRAP_ADD_OFFSET : AV_PTS_WRAP_SUB_OFFSET;
-
- AVProgram *first_program = av_find_program_from_stream(s, NULL, stream_index);
-
- if (!first_program) {
- int default_stream_index = av_find_default_stream_index(s);
- if (s->streams[default_stream_index]->pts_wrap_reference == AV_NOPTS_VALUE) {
- for (i=0; i<s->nb_streams; i++) {
- s->streams[i]->pts_wrap_reference = pts_wrap_reference;
- s->streams[i]->pts_wrap_behavior = pts_wrap_behavior;
- }
- }
- else {
- st->pts_wrap_reference = s->streams[default_stream_index]->pts_wrap_reference;
- st->pts_wrap_behavior = s->streams[default_stream_index]->pts_wrap_behavior;
- }
- }
- else {
- AVProgram *program = first_program;
- while (program) {
- if (program->pts_wrap_reference != AV_NOPTS_VALUE) {
- pts_wrap_reference = program->pts_wrap_reference;
- pts_wrap_behavior = program->pts_wrap_behavior;
- break;
- }
- program = av_find_program_from_stream(s, program, stream_index);
- }
-
- // update every program with differing pts_wrap_reference
- program = first_program;
- while(program) {
- if (program->pts_wrap_reference != pts_wrap_reference) {
- for (i=0; i<program->nb_stream_indexes; i++) {
- s->streams[program->stream_index[i]]->pts_wrap_reference = pts_wrap_reference;
- s->streams[program->stream_index[i]]->pts_wrap_behavior = pts_wrap_behavior;
- }
-
- program->pts_wrap_reference = pts_wrap_reference;
- program->pts_wrap_behavior = pts_wrap_behavior;
- }
- program = av_find_program_from_stream(s, program, stream_index);
- }
- }
- return 1;
- }
- return 0;
-}
-
static void update_initial_timestamps(AVFormatContext *s, int stream_index,
int64_t dts, int64_t pts, AVPacket *pkt)
{
@@ -967,15 +987,6 @@
}
}
- if (update_wrap_reference(s, st, stream_index) && st->pts_wrap_behavior == AV_PTS_WRAP_SUB_OFFSET) {
- // correct first time stamps to negative values
- st->first_dts = wrap_timestamp(st, st->first_dts);
- st->cur_dts = wrap_timestamp(st, st->cur_dts);
- pkt->dts = wrap_timestamp(st, pkt->dts);
- pkt->pts = wrap_timestamp(st, pkt->pts);
- pts = wrap_timestamp(st, pts);
- }
-
if (st->start_time == AV_NOPTS_VALUE)
st->start_time = pts;
}
@@ -996,7 +1007,8 @@
}
}
if(pktl && pktl->pkt.dts != st->first_dts) {
- av_log(s, AV_LOG_DEBUG, "first_dts %s not matching first dts %s in the queue\n", av_ts2str(st->first_dts), av_ts2str(pktl->pkt.dts));
+ av_log(s, AV_LOG_DEBUG, "first_dts %s not matching first dts %s (pts %s, duration %d) in the queue\n",
+ av_ts2str(st->first_dts), av_ts2str(pktl->pkt.dts), av_ts2str(pktl->pkt.pts), pktl->pkt.duration);
return;
}
if(!pktl) {
@@ -1038,7 +1050,8 @@
if((s->flags & AVFMT_FLAG_IGNDTS) && pkt->pts != AV_NOPTS_VALUE)
pkt->dts= AV_NOPTS_VALUE;
- if (st->codec->codec_id != AV_CODEC_ID_H264 && pc && pc->pict_type == AV_PICTURE_TYPE_B)
+ if (pc && pc->pict_type == AV_PICTURE_TYPE_B
+ && !st->codec->has_b_frames)
//FIXME Set low_delay = 0 when has_b_frames = 1
st->codec->has_b_frames = 1;
@@ -1090,25 +1103,6 @@
pkt->dts += offset;
}
- if (pc && pc->dts_sync_point >= 0) {
- // we have synchronization info from the parser
- int64_t den = st->codec->time_base.den * (int64_t) st->time_base.num;
- if (den > 0) {
- int64_t num = st->codec->time_base.num * (int64_t) st->time_base.den;
- if (pkt->dts != AV_NOPTS_VALUE) {
- // got DTS from the stream, update reference timestamp
- st->reference_dts = pkt->dts - pc->dts_ref_dts_delta * num / den;
- pkt->pts = pkt->dts + pc->pts_dts_delta * num / den;
- } else if (st->reference_dts != AV_NOPTS_VALUE) {
- // compute DTS based on reference timestamp
- pkt->dts = st->reference_dts + pc->dts_ref_dts_delta * num / den;
- pkt->pts = pkt->dts + pc->pts_dts_delta * num / den;
- }
- if (pc->dts_sync_point > 0)
- st->reference_dts = pkt->dts; // new reference
- }
- }
-
/* This may be redundant, but it should not hurt. */
if(pkt->dts != AV_NOPTS_VALUE && pkt->pts != AV_NOPTS_VALUE && pkt->pts > pkt->dts)
presentation_delayed = 1;
@@ -1413,6 +1407,21 @@
if (!got_packet && s->parse_queue)
ret = read_from_packet_buffer(&s->parse_queue, &s->parse_queue_end, pkt);
+ if (ret >= 0) {
+ AVStream *st = s->streams[pkt->stream_index];
+ if (st->skip_samples) {
+ uint8_t *p = av_packet_new_side_data(pkt, AV_PKT_DATA_SKIP_SAMPLES, 10);
+ if (p) {
+ AV_WL32(p, st->skip_samples);
+ av_log(s, AV_LOG_DEBUG, "demuxer injecting skip %d\n", st->skip_samples);
+ }
+ st->skip_samples = 0;
+ }
+ }
+
+ if(ret >= 0 && !(s->flags & AVFMT_FLAG_KEEP_SIDE_DATA))
+ av_packet_merge_side_data(pkt);
+
if(s->debug & FF_FDEBUG_TS)
av_log(s, AV_LOG_DEBUG, "read_frame_internal stream=%d, pts=%s, dts=%s, size=%d, duration=%d, flags=%d\n",
pkt->stream_index,
@@ -1502,13 +1511,6 @@
return_packet:
st = s->streams[pkt->stream_index];
- if (st->skip_samples) {
- uint8_t *p = av_packet_new_side_data(pkt, AV_PKT_DATA_SKIP_SAMPLES, 10);
- AV_WL32(p, st->skip_samples);
- av_log(s, AV_LOG_DEBUG, "demuxer injecting skip %d\n", st->skip_samples);
- st->skip_samples = 0;
- }
-
if ((s->iformat->flags & AVFMT_GENERIC_INDEX) && pkt->flags & AV_PKT_FLAG_KEY) {
ff_reduce_index(s, st->index);
av_add_index_entry(st, pkt->pos, pkt->dts, 0, 0, AVINDEX_KEYFRAME);
@@ -1576,7 +1578,6 @@
st->last_IP_pts = AV_NOPTS_VALUE;
if(st->first_dts == AV_NOPTS_VALUE) st->cur_dts = RELATIVE_TS_BASE;
else st->cur_dts = AV_NOPTS_VALUE; /* we set the current DTS to an unspecified origin */
- st->reference_dts = AV_NOPTS_VALUE;
st->probe_packets = MAX_PROBE_PACKETS;
@@ -1625,6 +1626,9 @@
if(timestamp == AV_NOPTS_VALUE)
return AVERROR(EINVAL);
+ if (size < 0 || size > 0x3FFFFFFF)
+ return AVERROR(EINVAL);
+
if (is_relative(timestamp)) //FIXME this maintains previous behavior but we should shift by the correct offset once known
timestamp -= RELATIVE_TS_BASE;
@@ -2357,7 +2361,6 @@
st= ic->streams[i];
st->cur_dts= st->first_dts;
st->last_IP_pts = AV_NOPTS_VALUE;
- st->reference_dts = AV_NOPTS_VALUE;
}
}
@@ -2457,7 +2460,7 @@
{
const AVCodec *codec;
int got_picture = 1, ret = 0;
- AVFrame *frame = avcodec_alloc_frame();
+ AVFrame *frame = av_frame_alloc();
AVSubtitle subtitle;
AVPacket pkt = *avpkt;
@@ -2698,6 +2701,113 @@
return ret;
}
+int ff_rfps_add_frame(AVFormatContext *ic, AVStream *st, int64_t ts)
+{
+ int i, j;
+ int64_t last = st->info->last_dts;
+
+ if( ts != AV_NOPTS_VALUE && last != AV_NOPTS_VALUE && ts > last
+ && ts - (uint64_t)last < INT64_MAX){
+ double dts= (is_relative(ts) ? ts - RELATIVE_TS_BASE : ts) * av_q2d(st->time_base);
+ int64_t duration= ts - last;
+
+ if (!st->info->duration_error)
+ st->info->duration_error = av_mallocz(sizeof(st->info->duration_error[0])*2);
+ if (!st->info->duration_error)
+ return AVERROR(ENOMEM);
+
+// if(st->codec->codec_type == AVMEDIA_TYPE_VIDEO)
+// av_log(NULL, AV_LOG_ERROR, "%f\n", dts);
+ for (i=0; i<MAX_STD_TIMEBASES; i++) {
+ if (st->info->duration_error[0][1][i] < 1e10) {
+ int framerate= get_std_framerate(i);
+ double sdts= dts*framerate/(1001*12);
+ for(j=0; j<2; j++){
+ int64_t ticks= llrint(sdts+j*0.5);
+ double error= sdts - ticks + j*0.5;
+ st->info->duration_error[j][0][i] += error;
+ st->info->duration_error[j][1][i] += error*error;
+ }
+ }
+ }
+ st->info->duration_count++;
+
+ if (st->info->duration_count % 10 == 0) {
+ int n = st->info->duration_count;
+ for (i=0; i<MAX_STD_TIMEBASES; i++) {
+ if (st->info->duration_error[0][1][i] < 1e10) {
+ double a0 = st->info->duration_error[0][0][i] / n;
+ double error0 = st->info->duration_error[0][1][i] / n - a0*a0;
+ double a1 = st->info->duration_error[1][0][i] / n;
+ double error1 = st->info->duration_error[1][1][i] / n - a1*a1;
+ if (error0 > 0.04 && error1 > 0.04) {
+ st->info->duration_error[0][1][i] = 2e10;
+ st->info->duration_error[1][1][i] = 2e10;
+ }
+ }
+ }
+ }
+
+ // ignore the first 4 values, they might have some random jitter
+ if (st->info->duration_count > 3 && is_relative(ts) == is_relative(last))
+ st->info->duration_gcd = av_gcd(st->info->duration_gcd, duration);
+ }
+ if (ts != AV_NOPTS_VALUE)
+ st->info->last_dts = ts;
+
+ return 0;
+}
+
+void ff_rfps_calculate(AVFormatContext *ic)
+{
+ int i, j;
+
+ for (i = 0; i<ic->nb_streams; i++) {
+ AVStream *st = ic->streams[i];
+
+ if (st->codec->codec_type != AVMEDIA_TYPE_VIDEO)
+ continue;
+ // the check for tb_unreliable() is not completely correct, since this is not about handling
+ // a unreliable/inexact time base, but a time base that is finer than necessary, as e.g.
+ // ipmovie.c produces.
+ if (tb_unreliable(st->codec) && st->info->duration_count > 15 && st->info->duration_gcd > FFMAX(1, st->time_base.den/(500LL*st->time_base.num)) && !st->r_frame_rate.num)
+ av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den, st->time_base.den, st->time_base.num * st->info->duration_gcd, INT_MAX);
+ if (st->info->duration_count>1 && !st->r_frame_rate.num
+ && tb_unreliable(st->codec)) {
+ int num = 0;
+ double best_error= 0.01;
+
+ for (j=0; j<MAX_STD_TIMEBASES; j++) {
+ int k;
+
+ if(st->info->codec_info_duration && st->info->codec_info_duration*av_q2d(st->time_base) < (1001*12.0)/get_std_framerate(j))
+ continue;
+ if(!st->info->codec_info_duration && 1.0 < (1001*12.0)/get_std_framerate(j))
+ continue;
+ for(k=0; k<2; k++){
+ int n= st->info->duration_count;
+ double a= st->info->duration_error[k][0][j] / n;
+ double error= st->info->duration_error[k][1][j]/n - a*a;
+
+ if(error < best_error && best_error> 0.000000001){
+ best_error= error;
+ num = get_std_framerate(j);
+ }
+ if(error < 0.02)
+ av_log(NULL, AV_LOG_DEBUG, "rfps: %f %f\n", get_std_framerate(j) / 12.0/1001, error);
+ }
+ }
+ // do not increase frame rate by more than 1 % in order to match a standard rate.
+ if (num && (!st->r_frame_rate.num || (double)num/(12*1001) < 1.01 * av_q2d(st->r_frame_rate)))
+ av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den, num, 12*1001, INT_MAX);
+ }
+
+ av_freep(&st->info->duration_error);
+ st->info->last_dts = AV_NOPTS_VALUE;
+ st->info->duration_count = 0;
+ }
+}
+
int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
{
int i, count, ret = 0, j;
@@ -2709,7 +2819,8 @@
int flush_codecs = ic->probesize > 0;
if(ic->pb)
- av_log(ic, AV_LOG_DEBUG, "File position before avformat_find_stream_info() is %"PRId64"\n", avio_tell(ic->pb));
+ av_log(ic, AV_LOG_DEBUG, "Before avformat_find_stream_info() pos: %"PRId64" bytes read:%"PRId64" seeks:%d\n",
+ avio_tell(ic->pb), ic->pb->bytes_read, ic->pb->seek_count);
for(i=0;i<ic->nb_streams;i++) {
const AVCodec *codec;
@@ -2855,9 +2966,10 @@
goto find_stream_info_err;
}
- read_size += pkt->size;
-
st = ic->streams[pkt->stream_index];
+ if (!(st->disposition & AV_DISPOSITION_ATTACHED_PIC))
+ read_size += pkt->size;
+
if (pkt->dts != AV_NOPTS_VALUE && st->codec_info_nb_frames > 1) {
/* check for non-increasing dts */
if (st->info->fps_last_dts != AV_NOPTS_VALUE &&
@@ -2913,39 +3025,7 @@
}
}
#if FF_API_R_FRAME_RATE
- {
- int64_t last = st->info->last_dts;
-
- if( pkt->dts != AV_NOPTS_VALUE && last != AV_NOPTS_VALUE && pkt->dts > last
- && pkt->dts - (uint64_t)last < INT64_MAX){
- double dts= (is_relative(pkt->dts) ? pkt->dts - RELATIVE_TS_BASE : pkt->dts) * av_q2d(st->time_base);
- int64_t duration= pkt->dts - last;
-
- if (!st->info->duration_error)
- st->info->duration_error = av_mallocz(sizeof(st->info->duration_error[0])*2);
- if (!st->info->duration_error)
- return AVERROR(ENOMEM);
-
-// if(st->codec->codec_type == AVMEDIA_TYPE_VIDEO)
-// av_log(NULL, AV_LOG_ERROR, "%f\n", dts);
- for (i=0; i<MAX_STD_TIMEBASES; i++) {
- int framerate= get_std_framerate(i);
- double sdts= dts*framerate/(1001*12);
- for(j=0; j<2; j++){
- int64_t ticks= llrint(sdts+j*0.5);
- double error= sdts - ticks + j*0.5;
- st->info->duration_error[j][0][i] += error;
- st->info->duration_error[j][1][i] += error*error;
- }
- }
- st->info->duration_count++;
- // ignore the first 4 values, they might have some random jitter
- if (st->info->duration_count > 3 && is_relative(pkt->dts) == is_relative(last))
- st->info->duration_gcd = av_gcd(st->info->duration_gcd, duration);
- }
- if (pkt->dts != AV_NOPTS_VALUE)
- st->info->last_dts = pkt->dts;
- }
+ ff_rfps_add_frame(ic, st, pkt->dts);
#endif
if(st->parser && st->parser->parser->split && !st->codec->extradata){
int i= st->parser->parser->split(st->codec, pkt->data, pkt->size);
@@ -3001,6 +3081,9 @@
st = ic->streams[i];
avcodec_close(st->codec);
}
+
+ ff_rfps_calculate(ic);
+
for(i=0;i<ic->nb_streams;i++) {
st = ic->streams[i];
if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
@@ -3039,40 +3122,6 @@
best_fps, 12*1001, INT_MAX);
}
}
- // the check for tb_unreliable() is not completely correct, since this is not about handling
- // a unreliable/inexact time base, but a time base that is finer than necessary, as e.g.
- // ipmovie.c produces.
- if (tb_unreliable(st->codec) && st->info->duration_count > 15 && st->info->duration_gcd > FFMAX(1, st->time_base.den/(500LL*st->time_base.num)) && !st->r_frame_rate.num)
- av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den, st->time_base.den, st->time_base.num * st->info->duration_gcd, INT_MAX);
- if (st->info->duration_count>1 && !st->r_frame_rate.num
- && tb_unreliable(st->codec)) {
- int num = 0;
- double best_error= 0.01;
-
- for (j=0; j<MAX_STD_TIMEBASES; j++) {
- int k;
-
- if(st->info->codec_info_duration && st->info->codec_info_duration*av_q2d(st->time_base) < (1001*12.0)/get_std_framerate(j))
- continue;
- if(!st->info->codec_info_duration && 1.0 < (1001*12.0)/get_std_framerate(j))
- continue;
- for(k=0; k<2; k++){
- int n= st->info->duration_count;
- double a= st->info->duration_error[k][0][j] / n;
- double error= st->info->duration_error[k][1][j]/n - a*a;
-
- if(error < best_error && best_error> 0.000000001){
- best_error= error;
- num = get_std_framerate(j);
- }
- if(error < 0.02)
- av_log(NULL, AV_LOG_DEBUG, "rfps: %f %f\n", get_std_framerate(j) / 12.0/1001, error);
- }
- }
- // do not increase frame rate by more than 1 % in order to match a standard rate.
- if (num && (!st->r_frame_rate.num || (double)num/(12*1001) < 1.01 * av_q2d(st->r_frame_rate)))
- av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den, num, 12*1001, INT_MAX);
- }
if (!st->r_frame_rate.num){
if( st->codec->time_base.den * (int64_t)st->time_base.num
@@ -3135,7 +3184,8 @@
av_freep(&ic->streams[i]->info);
}
if(ic->pb)
- av_log(ic, AV_LOG_DEBUG, "File position after avformat_find_stream_info() is %"PRId64"\n", avio_tell(ic->pb));
+ av_log(ic, AV_LOG_DEBUG, "After avformat_find_stream_info() pos: %"PRId64" bytes read:%"PRId64" seeks:%d frames:%d\n",
+ avio_tell(ic->pb), ic->pb->bytes_read, ic->pb->seek_count, count);
return ret;
}
@@ -3380,7 +3430,6 @@
st->last_IP_pts = AV_NOPTS_VALUE;
for(i=0; i<MAX_REORDER_DELAY+1; i++)
st->pts_buffer[i]= AV_NOPTS_VALUE;
- st->reference_dts = AV_NOPTS_VALUE;
st->sample_aspect_ratio = (AVRational){0,1};
@@ -4181,7 +4230,7 @@
return AVERROR(EINVAL);
}
-void ff_generate_avci_extradata(AVStream *st)
+int ff_generate_avci_extradata(AVStream *st)
{
static const uint8_t avci100_1080p_extradata[] = {
// SPS
@@ -4248,8 +4297,10 @@
0x00, 0x00, 0x00, 0x01, 0x68, 0xce, 0x31, 0x12,
0x11
};
+
+ const uint8_t *data = NULL;
int size = 0;
- const uint8_t *data = 0;
+
if (st->codec->width == 1920) {
if (st->codec->field_order == AV_FIELD_PROGRESSIVE) {
data = avci100_1080p_extradata;
@@ -4265,10 +4316,14 @@
data = avci100_720p_extradata;
size = sizeof(avci100_720p_extradata);
}
+
if (!size)
- return;
+ return 0;
+
av_freep(&st->codec->extradata);
if (ff_alloc_extradata(st->codec, size))
- return;
+ return AVERROR(ENOMEM);
memcpy(st->codec->extradata, data, size);
+
+ return 0;
}
diff --git a/libavformat/version.h b/libavformat/version.h
index ff38e96..4fe8364 100644
--- a/libavformat/version.h
+++ b/libavformat/version.h
@@ -30,8 +30,8 @@
#include "libavutil/avutil.h"
#define LIBAVFORMAT_VERSION_MAJOR 55
-#define LIBAVFORMAT_VERSION_MINOR 19
-#define LIBAVFORMAT_VERSION_MICRO 102
+#define LIBAVFORMAT_VERSION_MINOR 22
+#define LIBAVFORMAT_VERSION_MICRO 100
#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
LIBAVFORMAT_VERSION_MINOR, \
@@ -48,6 +48,9 @@
* dropped at a future version bump. The defines themselves are not part of
* the public API and may change, break or disappear at any time.
*/
+#ifndef FF_API_REFERENCE_DTS
+#define FF_API_REFERENCE_DTS (LIBAVFORMAT_VERSION_MAJOR < 56)
+#endif
#ifndef FF_API_ALLOC_OUTPUT_CONTEXT
#define FF_API_ALLOC_OUTPUT_CONTEXT (LIBAVFORMAT_VERSION_MAJOR < 56)
diff --git a/libavformat/vqf.c b/libavformat/vqf.c
index 4cd0a6d..526b596 100644
--- a/libavformat/vqf.c
+++ b/libavformat/vqf.c
@@ -43,6 +43,9 @@
if (!memcmp(probe_packet->buf + 4, "00052200", 8))
return AVPROBE_SCORE_MAX;
+ if (AV_RL32(probe_packet->buf + 12) > (1<<27))
+ return AVPROBE_SCORE_EXTENSION/2;
+
return AVPROBE_SCORE_EXTENSION;
}
diff --git a/libavformat/wavdec.c b/libavformat/wavdec.c
index 8ae7b45..daea64e 100644
--- a/libavformat/wavdec.c
+++ b/libavformat/wavdec.c
@@ -23,6 +23,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <stdint.h>
+
#include "libavutil/avassert.h"
#include "libavutil/dict.h"
#include "libavutil/intreadwrite.h"
@@ -466,8 +468,8 @@
if (wav->smv_data_ofs > 0) {
int64_t audio_dts, video_dts;
smv_retry:
- audio_dts = s->streams[0]->cur_dts;
- video_dts = s->streams[1]->cur_dts;
+ audio_dts = (int32_t)s->streams[0]->cur_dts;
+ video_dts = (int32_t)s->streams[1]->cur_dts;
if (audio_dts != AV_NOPTS_VALUE && video_dts != AV_NOPTS_VALUE) {
/*We always return a video frame first to get the pixel format first*/
diff --git a/libavformat/wavenc.c b/libavformat/wavenc.c
index fea38cf..0067dfe 100644
--- a/libavformat/wavenc.c
+++ b/libavformat/wavenc.c
@@ -116,6 +116,11 @@
AVIOContext *pb = s->pb;
int64_t fmt;
+ if (s->nb_streams != 1) {
+ av_log(s, AV_LOG_ERROR, "WAVE files have exactly one stream\n");
+ return AVERROR(EINVAL);
+ }
+
if (wav->rf64 == RF64_ALWAYS) {
ffio_wfourcc(pb, "RF64");
avio_wl32(pb, -1); /* RF64 chunk size: use size in ds64 */
diff --git a/libavformat/wtv.h b/libavformat/wtv.h
index 51ac626..efe90d6 100644
--- a/libavformat/wtv.h
+++ b/libavformat/wtv.h
@@ -25,7 +25,7 @@
#include "riff.h"
#include "asf.h"
-#define WTV_SECTOR_BITS INT64_C(12)
+#define WTV_SECTOR_BITS 12
#define WTV_SECTOR_SIZE (1 << WTV_SECTOR_BITS)
#define WTV_BIGSECTOR_BITS 18
#define WTV_PAD8(x) (((x) + 7) & ~7)
diff --git a/libavformat/wtv.c b/libavformat/wtv_common.c
similarity index 100%
rename from libavformat/wtv.c
rename to libavformat/wtv_common.c
diff --git a/libavformat/wtvdec.c b/libavformat/wtvdec.c
index ab51171..4dfe701 100644
--- a/libavformat/wtvdec.c
+++ b/libavformat/wtvdec.c
@@ -58,6 +58,11 @@
int64_t length;
} WtvFile;
+static int64_t seek_by_sector(AVIOContext *pb, int64_t sector, int64_t offset)
+{
+ return avio_seek(pb, (sector << WTV_SECTOR_BITS) + offset, SEEK_SET);
+}
+
/**
* @return bytes read, 0 on end of file, or <0 on error
*/
@@ -88,7 +93,7 @@
int i = wf->position >> wf->sector_bits;
if (i >= wf->nb_sectors ||
(wf->sectors[i] != wf->sectors[i - 1] + (1 << (wf->sector_bits - WTV_SECTOR_BITS)) &&
- avio_seek(pb, wf->sectors[i] << WTV_SECTOR_BITS, SEEK_SET) < 0)) {
+ seek_by_sector(pb, wf->sectors[i], 0) < 0)) {
wf->error = 1;
break;
}
@@ -113,8 +118,8 @@
offset = wf->length;
wf->error = offset < 0 || offset >= wf->length ||
- avio_seek(pb, (wf->sectors[offset >> wf->sector_bits] << WTV_SECTOR_BITS)
- + (offset & ((1 << wf->sector_bits) - 1)), SEEK_SET) < 0;
+ seek_by_sector(pb, wf->sectors[offset >> wf->sector_bits],
+ offset & ((1 << wf->sector_bits) - 1)) < 0;
wf->position = offset;
return offset;
}
@@ -149,7 +154,7 @@
WtvFile *wf;
uint8_t *buffer;
- if (avio_seek(s->pb, (int64_t)first_sector << WTV_SECTOR_BITS, SEEK_SET) < 0)
+ if (seek_by_sector(s->pb, first_sector, 0) < 0)
return NULL;
wf = av_mallocz(sizeof(WtvFile));
@@ -176,14 +181,14 @@
int nb_sectors1 = read_ints(s->pb, sectors1, WTV_SECTOR_SIZE / 4);
int i;
- wf->sectors = av_malloc(nb_sectors1 << WTV_SECTOR_BITS);
+ wf->sectors = av_malloc_array(nb_sectors1, 1 << WTV_SECTOR_BITS);
if (!wf->sectors) {
av_free(wf);
return NULL;
}
wf->nb_sectors = 0;
for (i = 0; i < nb_sectors1; i++) {
- if (avio_seek(s->pb, sectors1[i] << WTV_SECTOR_BITS, SEEK_SET) < 0)
+ if (seek_by_sector(s->pb, sectors1[i], 0) < 0)
break;
wf->nb_sectors += read_ints(s->pb, wf->sectors + i * WTV_SECTOR_SIZE / 4, WTV_SECTOR_SIZE / 4);
}
@@ -213,7 +218,7 @@
/* seek to initial sector */
wf->position = 0;
- if (avio_seek(s->pb, wf->sectors[0] << WTV_SECTOR_BITS, SEEK_SET) < 0) {
+ if (seek_by_sector(s->pb, wf->sectors[0], 0) < 0) {
av_free(wf->sectors);
av_free(wf);
return NULL;
@@ -501,7 +506,7 @@
else
snprintf(buf, buf_size, "%"PRIi64, num);
} else if (type == 5 && length == 2) {
- snprintf(buf, buf_size, "%"PRIi16, avio_rl16(pb));
+ snprintf(buf, buf_size, "%u", avio_rl16(pb));
} else if (type == 6 && length == 16) {
ff_asf_guid guid;
avio_read(pb, guid, 16);
@@ -941,7 +946,7 @@
avio_skip(s->pb, 4);
root_sector = avio_rl32(s->pb);
- avio_seek(s->pb, (int64_t)root_sector << WTV_SECTOR_BITS, SEEK_SET);
+ seek_by_sector(s->pb, root_sector, 0);
root_size = avio_read(s->pb, root, root_size);
if (root_size < 0)
return AVERROR_INVALIDDATA;
diff --git a/libavformat/xwma.c b/libavformat/xwma.c
index 135faf2..e629b3f 100644
--- a/libavformat/xwma.c
+++ b/libavformat/xwma.c
@@ -20,6 +20,7 @@
*/
#include <inttypes.h>
+#include <stdint.h>
#include "avformat.h"
#include "internal.h"
diff --git a/libavresample/Makefile b/libavresample/Makefile
index 6805280..bca23a9 100644
--- a/libavresample/Makefile
+++ b/libavresample/Makefile
@@ -13,4 +13,7 @@
resample.o \
utils.o \
+# Windows resource file
+SLIBOBJS-$(HAVE_GNU_WINDRES) += avresampleres.o
+
TESTPROGS = avresample
diff --git a/libavresample/avresampleres.rc b/libavresample/avresampleres.rc
new file mode 100644
index 0000000..e6d0d15
--- /dev/null
+++ b/libavresample/avresampleres.rc
@@ -0,0 +1,55 @@
+/*
+ * Windows resource file for libavresample
+ *
+ * Copyright (C) 2012 James Almer
+ * Copyright (C) 2013 Tiancheng "Timothy" Gu
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <windows.h>
+#include "libavresample/version.h"
+#include "libavutil/ffversion.h"
+#include "config.h"
+
+1 VERSIONINFO
+FILEVERSION LIBAVRESAMPLE_VERSION_MAJOR, LIBAVRESAMPLE_VERSION_MINOR, LIBAVRESAMPLE_VERSION_MICRO, 0
+PRODUCTVERSION LIBAVRESAMPLE_VERSION_MAJOR, LIBAVRESAMPLE_VERSION_MINOR, LIBAVRESAMPLE_VERSION_MICRO, 0
+FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+FILEOS VOS_NT_WINDOWS32
+FILETYPE VFT_DLL
+{
+ BLOCK "StringFileInfo"
+ {
+ BLOCK "040904B0"
+ {
+ VALUE "CompanyName", "FFmpeg Project"
+ VALUE "FileDescription", "Libav audio resampling library"
+ VALUE "FileVersion", AV_STRINGIFY(LIBAVRESAMPLE_VERSION)
+ VALUE "InternalName", "libavresample"
+ VALUE "LegalCopyright", "Copyright (C) 2000-" AV_STRINGIFY(CONFIG_THIS_YEAR) " FFmpeg Project"
+ VALUE "OriginalFilename", "avresample" BUILDSUF "-" AV_STRINGIFY(LIBAVRESAMPLE_VERSION_MAJOR) SLIBSUF
+ VALUE "ProductName", "FFmpeg"
+ VALUE "ProductVersion", FFMPEG_VERSION
+ }
+ }
+
+ BLOCK "VarFileInfo"
+ {
+ VALUE "Translation", 0x0409, 0x04B0
+ }
+}
diff --git a/libavresample/options.c b/libavresample/options.c
index a0dda6f..5f08cd7 100644
--- a/libavresample/options.c
+++ b/libavresample/options.c
@@ -18,6 +18,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <stdint.h>
+
#include "libavutil/mathematics.h"
#include "libavutil/mem.h"
#include "libavutil/opt.h"
diff --git a/libavresample/utils.c b/libavresample/utils.c
index 35e7ef6..db1e087 100644
--- a/libavresample/utils.c
+++ b/libavresample/utils.c
@@ -438,7 +438,8 @@
resample_out = &output_buffer;
else
resample_out = avr->resample_out_buffer;
- av_dlog(avr, "[resample] %s to %s\n", current_buffer->name,
+ av_dlog(avr, "[resample] %s to %s\n",
+ current_buffer ? current_buffer->name : "null",
resample_out->name);
ret = ff_audio_resample(avr->resample, resample_out,
current_buffer);
diff --git a/libavresample/version.h b/libavresample/version.h
index bd52ca6..0dd5bb6 100644
--- a/libavresample/version.h
+++ b/libavresample/version.h
@@ -25,6 +25,8 @@
* Libavresample version macros.
*/
+#include "libavutil/avutil.h"
+
#define LIBAVRESAMPLE_VERSION_MAJOR 1
#define LIBAVRESAMPLE_VERSION_MINOR 1
#define LIBAVRESAMPLE_VERSION_MICRO 0
diff --git a/libavutil/Makefile b/libavutil/Makefile
index 7b3b439..89708fc 100644
--- a/libavutil/Makefile
+++ b/libavutil/Makefile
@@ -47,6 +47,7 @@
samplefmt.h \
sha.h \
sha512.h \
+ stereo3d.h \
time.h \
timecode.h \
timestamp.h \
@@ -62,7 +63,8 @@
intreadwrite.h \
timer.h \
-BUILT_HEADERS = avconfig.h
+BUILT_HEADERS = avconfig.h \
+ ffversion.h
OBJS = adler32.o \
aes.o \
@@ -90,7 +92,8 @@
intfloat_readwrite.o \
intmath.o \
lfg.o \
- lls.o \
+ lls1.o \
+ lls2.o \
log.o \
log2_tab.o \
mathematics.o \
@@ -108,6 +111,7 @@
samplefmt.o \
sha.o \
sha512.o \
+ stereo3d.o \
time.o \
timecode.o \
tree.o \
@@ -120,6 +124,9 @@
OBJS += $(COMPAT_OBJS:%=../compat/%)
+# Windows resource file
+SLIBOBJS-$(HAVE_GNU_WINDRES) += avutilres.o
+
SKIPHEADERS = old_pix_fmts.h
SKIPHEADERS-$(HAVE_ATOMICS_GCC) += atomic_gcc.h
@@ -143,7 +150,8 @@
fifo \
hmac \
lfg \
- lls \
+ lls1 \
+ lls2 \
md5 \
murmur3 \
opt \
@@ -155,6 +163,7 @@
sha \
sha512 \
tree \
+ utf8 \
xtea \
TESTPROGS-$(HAVE_LZO1X_999_COMPRESS) += lzo
diff --git a/libavutil/adler32.c b/libavutil/adler32.c
index bc9b9a7..579d022 100644
--- a/libavutil/adler32.c
+++ b/libavutil/adler32.c
@@ -21,6 +21,15 @@
* 3. This notice may not be removed or altered from any source distribution.
*/
+/**
+ * @file
+ * Computes the Adler-32 checksum of a data stream
+ *
+ * This is a modified version based on adler32.c from the zlib library.
+ * @author Mark Adler
+ * @ingroup lavu_adler32
+ */
+
#include "config.h"
#include "adler32.h"
#include "common.h"
diff --git a/libavutil/adler32.h b/libavutil/adler32.h
index 8c08d2b..0dc69ec 100644
--- a/libavutil/adler32.h
+++ b/libavutil/adler32.h
@@ -25,6 +25,9 @@
#include "attributes.h"
/**
+ * @file
+ * Public header for libavutil Adler32 hasher
+ *
* @defgroup lavu_adler32 Adler32
* @ingroup lavu_crypto
* @{
diff --git a/libavutil/attributes.h b/libavutil/attributes.h
index 8c0e5b2..7d3f4a9 100644
--- a/libavutil/attributes.h
+++ b/libavutil/attributes.h
@@ -76,7 +76,7 @@
# define av_cold
#endif
-#if AV_GCC_VERSION_AT_LEAST(4,1)
+#if AV_GCC_VERSION_AT_LEAST(4,1) && !defined(__llvm__)
# define av_flatten __attribute__((flatten))
#else
# define av_flatten
diff --git a/libavutil/avstring.c b/libavutil/avstring.c
index eed58fa..2093107 100644
--- a/libavutil/avstring.c
+++ b/libavutil/avstring.c
@@ -307,6 +307,70 @@
return av_isdigit(c) || (c >= 'a' && c <= 'f');
}
+int av_utf8_decode(int32_t *codep, const uint8_t **bufp, const uint8_t *buf_end,
+ unsigned int flags)
+{
+ const uint8_t *p = *bufp;
+ uint32_t top;
+ uint64_t code;
+ int ret = 0;
+
+ if (p >= buf_end)
+ return 0;
+
+ code = *p++;
+
+ /* first sequence byte starts with 10, or is 1111-1110 or 1111-1111,
+ which is not admitted */
+ if ((code & 0xc0) == 0x80 || code >= 0xFE) {
+ ret = AVERROR(EILSEQ);
+ goto end;
+ }
+ top = (code & 128) >> 1;
+
+ while (code & top) {
+ int tmp;
+ if (p >= buf_end) {
+ ret = AVERROR(EILSEQ); /* incomplete sequence */
+ goto end;
+ }
+
+ /* we assume the byte to be in the form 10xx-xxxx */
+ tmp = *p++ - 128; /* strip leading 1 */
+ if (tmp>>6) {
+ ret = AVERROR(EILSEQ);
+ goto end;
+ }
+ code = (code<<6) + tmp;
+ top <<= 5;
+ }
+ code &= (top << 1) - 1;
+
+ if (code >= 1<<31) {
+ ret = AVERROR(EILSEQ); /* out-of-range value */
+ goto end;
+ }
+
+ *codep = code;
+
+ if (code > 0x10FFFF &&
+ !(flags & AV_UTF8_FLAG_ACCEPT_INVALID_BIG_CODES))
+ ret = AVERROR(EILSEQ);
+ if (code < 0x20 && code != 0x9 && code != 0xA && code != 0xD &&
+ flags & AV_UTF8_FLAG_EXCLUDE_XML_INVALID_CONTROL_CODES)
+ ret = AVERROR(EILSEQ);
+ if (code >= 0xD800 && code <= 0xDFFF &&
+ !(flags & AV_UTF8_FLAG_ACCEPT_SURROGATES))
+ ret = AVERROR(EILSEQ);
+ if (code == 0xFFFE || code == 0xFFFF &&
+ (!flags & AV_UTF8_FLAG_ACCEPT_NON_CHARACTERS))
+ ret = AVERROR(EILSEQ);
+
+end:
+ *bufp = p;
+ return ret;
+}
+
#ifdef TEST
int main(void)
diff --git a/libavutil/avstring.h b/libavutil/avstring.h
index 438ef79..882a2b5 100644
--- a/libavutil/avstring.h
+++ b/libavutil/avstring.h
@@ -22,6 +22,7 @@
#define AVUTIL_AVSTRING_H
#include <stddef.h>
+#include <stdint.h>
#include "attributes.h"
/**
@@ -295,6 +296,45 @@
int av_escape(char **dst, const char *src, const char *special_chars,
enum AVEscapeMode mode, int flags);
+#define AV_UTF8_FLAG_ACCEPT_INVALID_BIG_CODES 1 ///< accept codepoints over 0x10FFFF
+#define AV_UTF8_FLAG_ACCEPT_NON_CHARACTERS 2 ///< accept non-characters - 0xFFFE and 0xFFFF
+#define AV_UTF8_FLAG_ACCEPT_SURROGATES 4 ///< accept UTF-16 surrogates codes
+#define AV_UTF8_FLAG_EXCLUDE_XML_INVALID_CONTROL_CODES 8 ///< exclude control codes not accepted by XML
+
+#define AV_UTF8_FLAG_ACCEPT_ALL \
+ AV_UTF8_FLAG_ACCEPT_INVALID_BIG_CODES|AV_UTF8_FLAG_ACCEPT_NON_CHARACTERS|AV_UTF8_FLAG_ACCEPT_SURROGATES
+
+/**
+ * Read and decode a single UTF-8 code point (character) from the
+ * buffer in *buf, and update *buf to point to the next byte to
+ * decode.
+ *
+ * In case of an invalid byte sequence, the pointer will be updated to
+ * the next byte after the invalid sequence and the function will
+ * return an error code.
+ *
+ * Depending on the specified flags, the function will also fail in
+ * case the decoded code point does not belong to a valid range.
+ *
+ * @note For speed-relevant code a carefully implemented use of
+ * GET_UTF8() may be preferred.
+ *
+ * @param codep pointer used to return the parsed code in case of success.
+ * The value in *codep is set even in case the range check fails.
+ * @param bufp pointer to the address the first byte of the sequence
+ * to decode, updated by the function to point to the
+ * byte next after the decoded sequence
+ * @param buf_end pointer to the end of the buffer, points to the next
+ * byte past the last in the buffer. This is used to
+ * avoid buffer overreads (in case of an unfinished
+ * UTF-8 sequence towards the end of the buffer).
+ * @param flags a collection of AV_UTF8_FLAG_* flags
+ * @return >= 0 in case a sequence was successfully read, a negative
+ * value in case of invalid sequence
+ */
+int av_utf8_decode(int32_t *codep, const uint8_t **bufp, const uint8_t *buf_end,
+ unsigned int flags);
+
/**
* @}
*/
diff --git a/libavutil/avutil.h b/libavutil/avutil.h
index 4692c00..4e680ed 100644
--- a/libavutil/avutil.h
+++ b/libavutil/avutil.h
@@ -313,6 +313,13 @@
av_int_list_length_for_size(sizeof(*(list)), list, term)
/**
+ * Open a file using a UTF-8 filename.
+ * The API of this function matches POSIX fopen(), errors are returned through
+ * errno.
+ */
+FILE *av_fopen_utf8(const char *path, const char *mode);
+
+/**
* @}
* @}
*/
diff --git a/libavutil/avutilres.rc b/libavutil/avutilres.rc
new file mode 100644
index 0000000..40a75eb
--- /dev/null
+++ b/libavutil/avutilres.rc
@@ -0,0 +1,55 @@
+/*
+ * Windows resource file for libavutil
+ *
+ * Copyright (C) 2012 James Almer
+ * Copyright (C) 2013 Tiancheng "Timothy" Gu
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <windows.h>
+#include "libavutil/version.h"
+#include "libavutil/ffversion.h"
+#include "config.h"
+
+1 VERSIONINFO
+FILEVERSION LIBAVUTIL_VERSION_MAJOR, LIBAVUTIL_VERSION_MINOR, LIBAVUTIL_VERSION_MICRO, 0
+PRODUCTVERSION LIBAVUTIL_VERSION_MAJOR, LIBAVUTIL_VERSION_MINOR, LIBAVUTIL_VERSION_MICRO, 0
+FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+FILEOS VOS_NT_WINDOWS32
+FILETYPE VFT_DLL
+{
+ BLOCK "StringFileInfo"
+ {
+ BLOCK "040904B0"
+ {
+ VALUE "CompanyName", "FFmpeg Project"
+ VALUE "FileDescription", "FFmpeg utility library"
+ VALUE "FileVersion", AV_STRINGIFY(LIBAVUTIL_VERSION)
+ VALUE "InternalName", "libavutil"
+ VALUE "LegalCopyright", "Copyright (C) 2000-" AV_STRINGIFY(CONFIG_THIS_YEAR) " FFmpeg Project"
+ VALUE "OriginalFilename", "avutil" BUILDSUF "-" AV_STRINGIFY(LIBAVUTIL_VERSION_MAJOR) SLIBSUF
+ VALUE "ProductName", "FFmpeg"
+ VALUE "ProductVersion", FFMPEG_VERSION
+ }
+ }
+
+ BLOCK "VarFileInfo"
+ {
+ VALUE "Translation", 0x0409, 0x04B0
+ }
+}
diff --git a/libavutil/base64.c b/libavutil/base64.c
index 87e2dfd..348690d 100644
--- a/libavutil/base64.c
+++ b/libavutil/base64.c
@@ -270,7 +270,10 @@
}
}
- return error_count;
+ if (error_count)
+ printf("Error Count: %d.\n", error_count);
+
+ return !!error_count;
}
// LCOV_EXCL_STOP
diff --git a/libavutil/channel_layout.c b/libavutil/channel_layout.c
index e582760..4c0677f 100644
--- a/libavutil/channel_layout.c
+++ b/libavutil/channel_layout.c
@@ -23,6 +23,8 @@
* audio channel layout utility functions
*/
+#include <stdint.h>
+
#include "avstring.h"
#include "avutil.h"
#include "channel_layout.h"
@@ -103,7 +105,11 @@
{ "downmix", 2, AV_CH_LAYOUT_STEREO_DOWNMIX, },
};
+#if FF_API_GET_CHANNEL_LAYOUT_COMPAT
+static uint64_t get_channel_layout_single(const char *name, int name_len, int compat)
+#else
static uint64_t get_channel_layout_single(const char *name, int name_len)
+#endif
{
int i;
char *end;
@@ -120,16 +126,40 @@
!memcmp(channel_names[i].name, name, name_len))
return (int64_t)1 << i;
i = strtol(name, &end, 10);
- if (end - name == name_len ||
- (end + 1 - name == name_len && *end == 'c'))
+
+#if FF_API_GET_CHANNEL_LAYOUT_COMPAT
+ if (compat) {
+ if (end - name == name_len ||
+ (end + 1 - name == name_len && *end == 'c')) {
+ layout = av_get_default_channel_layout(i);
+ if (end - name == name_len) {
+ av_log(NULL, AV_LOG_WARNING,
+ "Single channel layout '%.*s' is interpreted as a number of channels, "
+ "switch to the syntax '%.*sc' otherwise it will be interpreted as a "
+ "channel layout number in a later version\n",
+ name_len, name, name_len, name);
+ return layout;
+ }
+ }
+ } else {
+#endif
+ if ((end + 1 - name == name_len && *end == 'c'))
return av_get_default_channel_layout(i);
+#if FF_API_GET_CHANNEL_LAYOUT_COMPAT
+ }
+#endif
+
layout = strtoll(name, &end, 0);
if (end - name == name_len)
return FFMAX(layout, 0);
return 0;
}
+#if FF_API_GET_CHANNEL_LAYOUT_COMPAT
+uint64_t ff_get_channel_layout(const char *name, int compat)
+#else
uint64_t av_get_channel_layout(const char *name)
+#endif
{
const char *n, *e;
const char *name_end = name + strlen(name);
@@ -137,7 +167,11 @@
for (n = name; n < name_end; n = e + 1) {
for (e = n; e < name_end && *e != '+' && *e != '|'; e++);
+#if FF_API_GET_CHANNEL_LAYOUT_COMPAT
+ layout_single = get_channel_layout_single(n, e - n, compat);
+#else
layout_single = get_channel_layout_single(n, e - n);
+#endif
if (!layout_single)
return 0;
layout |= layout_single;
@@ -145,6 +179,13 @@
return layout;
}
+#if FF_API_GET_CHANNEL_LAYOUT_COMPAT
+uint64_t av_get_channel_layout(const char *name)
+{
+ return ff_get_channel_layout(name, 1);
+}
+#endif
+
void av_bprint_channel_layout(struct AVBPrint *bp,
int nb_channels, uint64_t channel_layout)
{
diff --git a/libavutil/channel_layout.h b/libavutil/channel_layout.h
index 2906098..ba4f96d 100644
--- a/libavutil/channel_layout.h
+++ b/libavutil/channel_layout.h
@@ -136,7 +136,12 @@
* - a channel layout mask, in hexadecimal starting with "0x" (see the
* AV_CH_* macros).
*
- * Example: "stereo+FC" = "2+FC" = "2c+1c" = "0x7"
+ * @warning Starting from the next major bump the trailing character
+ * 'c' to specify a number of channels will be required, while a
+ * channel layout mask could also be specified as a decimal number
+ * (if and only if not followed by "c").
+ *
+ * Example: "stereo+FC" = "2c+FC" = "2c+1c" = "0x7"
*/
uint64_t av_get_channel_layout(const char *name);
diff --git a/libavutil/common.h b/libavutil/common.h
index b1203ad..c82a3a6 100644
--- a/libavutil/common.h
+++ b/libavutil/common.h
@@ -26,10 +26,15 @@
#ifndef AVUTIL_COMMON_H
#define AVUTIL_COMMON_H
+#if defined(__cplusplus) && !defined(__STDC_CONSTANT_MACROS) && !defined(UINT64_C)
+#error missing -D__STDC_CONSTANT_MACROS / #define __STDC_CONSTANT_MACROS
+#endif
+
#include <errno.h>
#include <inttypes.h>
#include <limits.h>
#include <math.h>
+#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
diff --git a/libavutil/cpu.c b/libavutil/cpu.c
index a31e195..e0806b1 100644
--- a/libavutil/cpu.c
+++ b/libavutil/cpu.c
@@ -16,6 +16,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <stdint.h>
+
#include "cpu.h"
#include "cpu_internal.h"
#include "config.h"
@@ -85,6 +87,7 @@
#define CPUFLAG_AVX (AV_CPU_FLAG_AVX | CPUFLAG_SSE42)
#define CPUFLAG_XOP (AV_CPU_FLAG_XOP | CPUFLAG_AVX)
#define CPUFLAG_FMA4 (AV_CPU_FLAG_FMA4 | CPUFLAG_AVX)
+#define CPUFLAG_AVX2 (AV_CPU_FLAG_AVX2 | CPUFLAG_AVX)
static const AVOption cpuflags_opts[] = {
{ "flags" , NULL, 0, AV_OPT_TYPE_FLAGS, { .i64 = 0 }, INT64_MIN, INT64_MAX, .unit = "flags" },
#if ARCH_PPC
@@ -104,6 +107,7 @@
{ "avx" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CPUFLAG_AVX }, .unit = "flags" },
{ "xop" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CPUFLAG_XOP }, .unit = "flags" },
{ "fma4" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CPUFLAG_FMA4 }, .unit = "flags" },
+ { "avx2" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CPUFLAG_AVX2 }, .unit = "flags" },
{ "3dnow" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CPUFLAG_3DNOW }, .unit = "flags" },
{ "3dnowext", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CPUFLAG_3DNOWEXT }, .unit = "flags" },
{ "cmov", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_CMOV }, .unit = "flags" },
@@ -267,6 +271,7 @@
{ AV_CPU_FLAG_3DNOW, "3dnow" },
{ AV_CPU_FLAG_3DNOWEXT, "3dnowext" },
{ AV_CPU_FLAG_CMOV, "cmov" },
+ { AV_CPU_FLAG_AVX2, "avx2" },
#endif
{ 0 }
};
diff --git a/libavutil/cpu.h b/libavutil/cpu.h
index 50bdea7..55c3ec9 100644
--- a/libavutil/cpu.h
+++ b/libavutil/cpu.h
@@ -50,6 +50,7 @@
// #else
// #define AV_CPU_FLAG_CMOV 0x1000 ///< supports cmov instruction
// #endif
+#define AV_CPU_FLAG_AVX2 0x8000 ///< AVX2 functions: requires OS support even if YMM registers aren't used
#define AV_CPU_FLAG_ALTIVEC 0x0001 ///< standard
diff --git a/libavutil/dict.h b/libavutil/dict.h
index 38f03a4..1dfc5a6 100644
--- a/libavutil/dict.h
+++ b/libavutil/dict.h
@@ -64,12 +64,13 @@
*
*/
-#define AV_DICT_MATCH_CASE 1
-#define AV_DICT_IGNORE_SUFFIX 2
+#define AV_DICT_MATCH_CASE 1 /**< Only get an entry with exact-case key match. Only relevant in av_dict_get(). */
+#define AV_DICT_IGNORE_SUFFIX 2 /**< Return first entry in a dictionary whose first part corresponds to the search key,
+ ignoring the suffix of the found key string. Only relevant in av_dict_get(). */
#define AV_DICT_DONT_STRDUP_KEY 4 /**< Take ownership of a key that's been
- allocated with av_malloc() and children. */
+ allocated with av_malloc() or another memory allocation function. */
#define AV_DICT_DONT_STRDUP_VAL 8 /**< Take ownership of a value that's been
- allocated with av_malloc() and chilren. */
+ allocated with av_malloc() or another memory allocation function. */
#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. */
@@ -84,8 +85,12 @@
/**
* Get a dictionary entry with matching key.
*
+ * To iterate through all the dictionary entries, you can set the matching key
+ * to the null string "" and set the AV_DICT_IGNORE_SUFFIX flag.
+ *
* @param prev Set to the previous matching element to find the next.
* If set to NULL the first matching element is returned.
+ * @param key matching key
* @param flags Allows case as well as suffix-insensitive comparisons.
* @return Found entry or NULL, changing key or value leads to undefined behavior.
*/
@@ -113,7 +118,10 @@
int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags);
/**
- * Parse the key/value pairs list and add to a dictionary.
+ * Parse the key/value pairs list and add the parsed entries to a dictionary.
+ *
+ * In case of failure, all the successfully set entries are stored in
+ * *pm. You may need to manually free the created dictionary.
*
* @param key_val_sep a 0-terminated list of characters used to separate
* key from value
diff --git a/libavutil/eval.h b/libavutil/eval.h
index a1d1fe3..6159b0f 100644
--- a/libavutil/eval.h
+++ b/libavutil/eval.h
@@ -45,7 +45,7 @@
* @param funcs2 NULL terminated array of function pointers for functions which take 2 arguments
* @param opaque a pointer which will be passed to all functions from funcs1 and funcs2
* @param log_ctx parent logging context
- * @return 0 in case of success, a negative value corresponding to an
+ * @return >= 0 in case of success, a negative value corresponding to an
* AVERROR code otherwise
*/
int av_expr_parse_and_eval(double *res, const char *s,
@@ -68,7 +68,7 @@
* @param func2_names NULL terminated array of zero terminated strings of funcs2 identifiers
* @param funcs2 NULL terminated array of function pointers for functions which take 2 arguments
* @param log_ctx parent logging context
- * @return 0 in case of success, a negative value corresponding to an
+ * @return >= 0 in case of success, a negative value corresponding to an
* AVERROR code otherwise
*/
int av_expr_parse(AVExpr **expr, const char *s,
diff --git a/libavutil/file_open.c b/libavutil/file_open.c
index ddb1c51..bcdd26a 100644
--- a/libavutil/file_open.c
+++ b/libavutil/file_open.c
@@ -85,9 +85,45 @@
fd = open(filename, flags, mode);
#if HAVE_FCNTL
- if (fd != -1)
- fcntl(fd, F_SETFD, FD_CLOEXEC);
+ if (fd != -1) {
+ if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1)
+ av_log(NULL, AV_LOG_DEBUG, "Failed to set close on exec\n");
+ }
#endif
return fd;
}
+
+FILE *av_fopen_utf8(const char *path, const char *mode)
+{
+ int fd;
+ int access;
+ const char *m = mode;
+
+ switch (*m++) {
+ case 'r': access = O_RDONLY; break;
+ case 'w': access = O_CREAT|O_WRONLY|O_TRUNC; break;
+ case 'a': access = O_CREAT|O_WRONLY|O_APPEND; break;
+ default :
+ errno = EINVAL;
+ return NULL;
+ }
+ while (*m) {
+ if (*m == '+') {
+ access &= ~(O_RDONLY | O_WRONLY);
+ access |= O_RDWR;
+ } else if (*m == 'b') {
+#ifdef O_BINARY
+ access |= O_BINARY;
+#endif
+ } else if (*m) {
+ errno = EINVAL;
+ return NULL;
+ }
+ m++;
+ }
+ fd = avpriv_open(path, access, 0666);
+ if (fd == -1)
+ return NULL;
+ return fdopen(fd, mode);
+}
diff --git a/libavutil/frame.c b/libavutil/frame.c
index 654f174..1b44400 100644
--- a/libavutil/frame.c
+++ b/libavutil/frame.c
@@ -183,11 +183,17 @@
static int get_audio_buffer(AVFrame *frame, int align)
{
- int channels = frame->channels;
+ int channels;
int planar = av_sample_fmt_is_planar(frame->format);
- int planes = planar ? channels : 1;
+ int planes;
int ret, i;
+ if (!frame->channels)
+ frame->channels = av_get_channel_layout_nb_channels(frame->channel_layout);
+
+ channels = frame->channels;
+ planes = planar ? channels : 1;
+
CHECK_CHANNELS_CONSISTENCY(frame);
if (!frame->linesize[0]) {
ret = av_samples_get_buffer_size(&frame->linesize[0], channels,
@@ -244,7 +250,7 @@
return AVERROR(EINVAL);
}
-int av_frame_ref(AVFrame *dst, AVFrame *src)
+int av_frame_ref(AVFrame *dst, const AVFrame *src)
{
int i, ret = 0;
@@ -335,7 +341,7 @@
return ret;
}
-AVFrame *av_frame_clone(AVFrame *src)
+AVFrame *av_frame_clone(const AVFrame *src)
{
AVFrame *ret = av_frame_alloc();
@@ -447,32 +453,33 @@
{
int i;
- dst->key_frame = src->key_frame;
- dst->pict_type = src->pict_type;
- dst->sample_aspect_ratio = src->sample_aspect_ratio;
- dst->pts = src->pts;
- dst->repeat_pict = src->repeat_pict;
- dst->interlaced_frame = src->interlaced_frame;
- dst->top_field_first = src->top_field_first;
- dst->palette_has_changed = src->palette_has_changed;
- dst->sample_rate = src->sample_rate;
- dst->opaque = src->opaque;
+ dst->key_frame = src->key_frame;
+ dst->pict_type = src->pict_type;
+ dst->sample_aspect_ratio = src->sample_aspect_ratio;
+ dst->pts = src->pts;
+ dst->repeat_pict = src->repeat_pict;
+ dst->interlaced_frame = src->interlaced_frame;
+ dst->top_field_first = src->top_field_first;
+ dst->palette_has_changed = src->palette_has_changed;
+ dst->sample_rate = src->sample_rate;
+ dst->opaque = src->opaque;
#if FF_API_AVFRAME_LAVC
- dst->type = src->type;
+ dst->type = src->type;
#endif
- dst->pkt_pts = src->pkt_pts;
- dst->pkt_dts = src->pkt_dts;
- dst->pkt_pos = src->pkt_pos;
- dst->pkt_size = src->pkt_size;
- dst->pkt_duration = src->pkt_duration;
- dst->reordered_opaque = src->reordered_opaque;
- dst->quality = src->quality;
- dst->best_effort_timestamp = src->best_effort_timestamp;
- dst->coded_picture_number = src->coded_picture_number;
+ dst->pkt_pts = src->pkt_pts;
+ dst->pkt_dts = src->pkt_dts;
+ dst->pkt_pos = src->pkt_pos;
+ dst->pkt_size = src->pkt_size;
+ dst->pkt_duration = src->pkt_duration;
+ dst->reordered_opaque = src->reordered_opaque;
+ dst->quality = src->quality;
+ dst->best_effort_timestamp = src->best_effort_timestamp;
+ dst->coded_picture_number = src->coded_picture_number;
dst->display_picture_number = src->display_picture_number;
- dst->decode_error_flags = src->decode_error_flags;
- dst->colorspace = src->colorspace;
- dst->color_range = src->color_range;
+ dst->flags = src->flags;
+ dst->decode_error_flags = src->decode_error_flags;
+ dst->colorspace = src->colorspace;
+ dst->color_range = src->color_range;
av_dict_copy(&dst->metadata, src->metadata, 0);
diff --git a/libavutil/frame.h b/libavutil/frame.h
index 6a708c0..b064cc5 100644
--- a/libavutil/frame.h
+++ b/libavutil/frame.h
@@ -31,15 +31,17 @@
#include "samplefmt.h"
enum AVColorSpace{
- AVCOL_SPC_RGB = 0,
- AVCOL_SPC_BT709 = 1, ///< also ITU-R BT1361 / IEC 61966-2-4 xvYCC709 / SMPTE RP177 Annex B
- AVCOL_SPC_UNSPECIFIED = 2,
- AVCOL_SPC_FCC = 4,
- AVCOL_SPC_BT470BG = 5, ///< also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM / IEC 61966-2-4 xvYCC601
- AVCOL_SPC_SMPTE170M = 6, ///< also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC / functionally identical to above
- AVCOL_SPC_SMPTE240M = 7,
- AVCOL_SPC_YCOCG = 8, ///< Used by Dirac / VC-2 and H.264 FRext, see ITU-T SG16
- AVCOL_SPC_NB , ///< Not part of ABI
+ AVCOL_SPC_RGB = 0,
+ AVCOL_SPC_BT709 = 1, ///< also ITU-R BT1361 / IEC 61966-2-4 xvYCC709 / SMPTE RP177 Annex B
+ AVCOL_SPC_UNSPECIFIED = 2,
+ AVCOL_SPC_FCC = 4,
+ AVCOL_SPC_BT470BG = 5, ///< also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM / IEC 61966-2-4 xvYCC601
+ AVCOL_SPC_SMPTE170M = 6, ///< also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC / functionally identical to above
+ AVCOL_SPC_SMPTE240M = 7,
+ AVCOL_SPC_YCOCG = 8, ///< Used by Dirac / VC-2 and H.264 FRext, see ITU-T SG16
+ AVCOL_SPC_BT2020_NCL = 9, ///< ITU-R BT2020 non-constant luminance system
+ AVCOL_SPC_BT2020_CL = 10, ///< ITU-R BT2020 constant luminance system
+ AVCOL_SPC_NB , ///< Not part of ABI
};
#define AVCOL_SPC_YCGCO AVCOL_SPC_YCOCG
@@ -50,11 +52,23 @@
AVCOL_RANGE_NB , ///< Not part of ABI
};
+
enum AVFrameSideDataType {
/**
* The data is the AVPanScan struct defined in libavcodec.
*/
AV_FRAME_DATA_PANSCAN,
+ /**
+ * ATSC A53 Part 4 Closed Captions.
+ * A53 CC bitstream is stored as uint8_t in AVFrameSideData.data.
+ * The number of bytes of CC data is AVFrameSideData.size.
+ */
+ AV_FRAME_DATA_A53_CC,
+ /**
+ * Stereoscopic 3d metadata.
+ * The data is the AVStereo3D struct defined in libavutil/stereo3d.h.
+ */
+ AV_FRAME_DATA_STEREO3D,
};
typedef struct AVFrameSideData {
@@ -388,6 +402,16 @@
AVFrameSideData **side_data;
int nb_side_data;
+/**
+ * The frame data may be corrupted, e.g. due to decoding errors.
+ */
+#define AV_FRAME_FLAG_CORRUPT (1 << 0)
+
+ /**
+ * Frame flags, a combination of AV_FRAME_FLAG_*
+ */
+ int flags;
+
/**
* frame timestamp estimated using various heuristics, in stream time base
* Code outside libavcodec should access this field using:
@@ -551,7 +575,7 @@
*
* @return 0 on success, a negative AVERROR on error
*/
-int av_frame_ref(AVFrame *dst, AVFrame *src);
+int av_frame_ref(AVFrame *dst, const AVFrame *src);
/**
* Create a new frame that references the same data as src.
@@ -560,7 +584,7 @@
*
* @return newly created AVFrame on success, NULL on error.
*/
-AVFrame *av_frame_clone(AVFrame *src);
+AVFrame *av_frame_clone(const AVFrame *src);
/**
* Unreference all the buffers referenced by frame and reset the frame fields.
diff --git a/libavutil/internal.h b/libavutil/internal.h
index 6bc426e..9c5546f 100644
--- a/libavutil/internal.h
+++ b/libavutil/internal.h
@@ -39,6 +39,7 @@
#include "timer.h"
#include "cpu.h"
#include "dict.h"
+#include "version.h"
#if ARCH_X86
# include "x86/emms.h"
@@ -63,7 +64,7 @@
#endif
#if HAVE_PRAGMA_DEPRECATED
-# if defined(__ICL)
+# if defined(__ICL) || defined (__INTEL_COMPILER)
# define FF_DISABLE_DEPRECATION_WARNINGS __pragma(warning(push)) __pragma(warning(disable:1478))
# define FF_ENABLE_DEPRECATION_WARNINGS __pragma(warning(pop))
# elif defined(_MSC_VER)
@@ -210,7 +211,7 @@
void avpriv_request_sample(void *avc,
const char *msg, ...) av_printf_format(2, 3);
-#if HAVE_MSVCRT
+#if HAVE_LIBC_MSVCRT
#define avpriv_open ff_open
#endif
@@ -219,4 +220,8 @@
*/
int avpriv_open(const char *filename, int flags, ...);
+#if FF_API_GET_CHANNEL_LAYOUT_COMPAT
+uint64_t ff_get_channel_layout(const char *name, int compat);
+#endif
+
#endif /* AVUTIL_INTERNAL_H */
diff --git a/libavutil/lls.c b/libavutil/lls1.c
similarity index 87%
rename from libavutil/lls.c
rename to libavutil/lls1.c
index abed8ef..c452d82 100644
--- a/libavutil/lls.c
+++ b/libavutil/lls1.c
@@ -30,14 +30,23 @@
#include "attributes.h"
#include "version.h"
-#include "lls.h"
+#include "lls1.h"
-static void update_lls(LLSModel *m, double *var)
+#if FF_API_LLS1
+
+av_cold void avpriv_init_lls(LLSModel *m, int indep_count)
+{
+ memset(m, 0, sizeof(LLSModel));
+ m->indep_count = indep_count;
+}
+
+void avpriv_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++) {
+ m->covariance[i][j] *= decay;
m->covariance[i][j] += var[i] * var[j];
}
}
@@ -46,8 +55,8 @@
void avpriv_solve_lls(LLSModel *m, double threshold, unsigned short min_order)
{
int i, j, k;
- double (*factor)[MAX_VARS_ALIGN] = (void *) &m->covariance[1][0];
- double (*covar) [MAX_VARS_ALIGN] = (void *) &m->covariance[1][1];
+ 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;
@@ -100,7 +109,7 @@
}
}
-static double evaluate_lls(LLSModel *m, double *param, int order)
+double avpriv_evaluate_lls(LLSModel *m, double *param, int order)
{
int i;
double out = 0;
@@ -111,16 +120,6 @@
return out;
}
-av_cold void avpriv_init_lls(LLSModel *m, int indep_count)
-{
- memset(m, 0, sizeof(LLSModel));
- m->indep_count = indep_count;
- m->update_lls = update_lls;
- m->evaluate_lls = evaluate_lls;
- if (ARCH_X86)
- ff_init_lls_x86(m);
-}
-
#if FF_API_LLS_PRIVATE
av_cold void av_init_lls(LLSModel *m, int indep_count)
{
@@ -128,7 +127,7 @@
}
void av_update_lls(LLSModel *m, double *param, double decay)
{
- m->update_lls(m, param);
+ avpriv_update_lls(m, param, decay);
}
void av_solve_lls(LLSModel *m, double threshold, int min_order)
{
@@ -136,10 +135,12 @@
}
double av_evaluate_lls(LLSModel *m, double *param, int order)
{
- return m->evaluate_lls(m, param, order);
+ return avpriv_evaluate_lls(m, param, order);
}
#endif /* FF_API_LLS_PRIVATE */
+#endif /* FF_API_LLS1 */
+
#ifdef TEST
#include <stdio.h>
@@ -156,17 +157,17 @@
avpriv_init_lls(&m, 3);
for (i = 0; i < 100; i++) {
- LOCAL_ALIGNED(32, double, var, [4]);
+ double var[4];
double eval;
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;
- m.update_lls(&m, var);
+ avpriv_update_lls(&m, var, 0.99);
avpriv_solve_lls(&m, 0.001, 0);
for (order = 0; order < 3; order++) {
- eval = m.evaluate_lls(&m, var + 1, order);
+ eval = avpriv_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],
diff --git a/libavutil/lls.h b/libavutil/lls1.h
similarity index 63%
copy from libavutil/lls.h
copy to libavutil/lls1.h
index c62d78a..c785d44 100644
--- a/libavutil/lls.h
+++ b/libavutil/lls1.h
@@ -23,12 +23,9 @@
#ifndef AVUTIL_LLS_H
#define AVUTIL_LLS_H
-#include "common.h"
-#include "mem.h"
#include "version.h"
#define MAX_VARS 32
-#define MAX_VARS_ALIGN FFALIGN(MAX_VARS+1,4)
//FIXME avoid direct access to LLSModel from outside
@@ -36,30 +33,16 @@
* Linear least squares model.
*/
typedef struct LLSModel {
- DECLARE_ALIGNED(32, double, covariance[MAX_VARS_ALIGN][MAX_VARS_ALIGN]);
- DECLARE_ALIGNED(32, double, coeff[MAX_VARS][MAX_VARS]);
+ double covariance[MAX_VARS + 1][MAX_VARS + 1];
+ double coeff[MAX_VARS][MAX_VARS];
double variance[MAX_VARS];
int indep_count;
- /**
- * Take the outer-product of var[] with itself, and add to the covariance matrix.
- * @param m this context
- * @param var training samples, starting with the value to be predicted
- * 32-byte aligned, and any padding elements must be initialized
- * (i.e not denormal/nan).
- */
- void (*update_lls)(struct LLSModel *m, double *var);
- /**
- * Inner product of var[] and the LPC coefs.
- * @param m this context
- * @param var training samples, excluding the value to be predicted. unaligned.
- * @param order lpc order
- */
- double (*evaluate_lls)(struct LLSModel *m, double *var, int order);
} LLSModel;
void avpriv_init_lls(LLSModel *m, int indep_count);
-void ff_init_lls_x86(LLSModel *m);
+void avpriv_update_lls(LLSModel *m, double *param, double decay);
void avpriv_solve_lls(LLSModel *m, double threshold, unsigned short min_order);
+double avpriv_evaluate_lls(LLSModel *m, double *param, int order);
#if FF_API_LLS_PRIVATE
void av_init_lls(LLSModel *m, int indep_count);
diff --git a/libavutil/lls.c b/libavutil/lls2.c
similarity index 81%
copy from libavutil/lls.c
copy to libavutil/lls2.c
index abed8ef..8cadacb 100644
--- a/libavutil/lls.c
+++ b/libavutil/lls2.c
@@ -30,9 +30,9 @@
#include "attributes.h"
#include "version.h"
-#include "lls.h"
+#include "lls2.h"
-static void update_lls(LLSModel *m, double *var)
+static void update_lls(LLSModel2 *m, double *var)
{
int i, j;
@@ -43,7 +43,7 @@
}
}
-void avpriv_solve_lls(LLSModel *m, double threshold, unsigned short min_order)
+void avpriv_solve_lls2(LLSModel2 *m, double threshold, unsigned short min_order)
{
int i, j, k;
double (*factor)[MAX_VARS_ALIGN] = (void *) &m->covariance[1][0];
@@ -100,7 +100,7 @@
}
}
-static double evaluate_lls(LLSModel *m, double *param, int order)
+static double evaluate_lls(LLSModel2 *m, double *param, int order)
{
int i;
double out = 0;
@@ -111,9 +111,9 @@
return out;
}
-av_cold void avpriv_init_lls(LLSModel *m, int indep_count)
+av_cold void avpriv_init_lls2(LLSModel2 *m, int indep_count)
{
- memset(m, 0, sizeof(LLSModel));
+ memset(m, 0, sizeof(LLSModel2));
m->indep_count = indep_count;
m->update_lls = update_lls;
m->evaluate_lls = evaluate_lls;
@@ -121,25 +121,6 @@
ff_init_lls_x86(m);
}
-#if FF_API_LLS_PRIVATE
-av_cold void av_init_lls(LLSModel *m, int indep_count)
-{
- avpriv_init_lls(m, indep_count);
-}
-void av_update_lls(LLSModel *m, double *param, double decay)
-{
- m->update_lls(m, param);
-}
-void av_solve_lls(LLSModel *m, double threshold, int min_order)
-{
- avpriv_solve_lls(m, threshold, min_order);
-}
-double av_evaluate_lls(LLSModel *m, double *param, int order)
-{
- return m->evaluate_lls(m, param, order);
-}
-#endif /* FF_API_LLS_PRIVATE */
-
#ifdef TEST
#include <stdio.h>
@@ -148,12 +129,12 @@
int main(void)
{
- LLSModel m;
+ LLSModel2 m;
int i, order;
AVLFG lfg;
av_lfg_init(&lfg, 1);
- avpriv_init_lls(&m, 3);
+ avpriv_init_lls2(&m, 3);
for (i = 0; i < 100; i++) {
LOCAL_ALIGNED(32, double, var, [4]);
@@ -164,7 +145,7 @@
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;
m.update_lls(&m, var);
- avpriv_solve_lls(&m, 0.001, 0);
+ avpriv_solve_lls2(&m, 0.001, 0);
for (order = 0; order < 3; order++) {
eval = m.evaluate_lls(&m, var + 1, order);
printf("real:%9f order:%d pred:%9f var:%f coeffs:%f %9f %9f\n",
diff --git a/libavutil/lls.h b/libavutil/lls2.h
similarity index 72%
rename from libavutil/lls.h
rename to libavutil/lls2.h
index c62d78a..35815d2 100644
--- a/libavutil/lls.h
+++ b/libavutil/lls2.h
@@ -30,12 +30,12 @@
#define MAX_VARS 32
#define MAX_VARS_ALIGN FFALIGN(MAX_VARS+1,4)
-//FIXME avoid direct access to LLSModel from outside
+//FIXME avoid direct access to LLSModel2 from outside
/**
* Linear least squares model.
*/
-typedef struct LLSModel {
+typedef struct LLSModel2 {
DECLARE_ALIGNED(32, double, covariance[MAX_VARS_ALIGN][MAX_VARS_ALIGN]);
DECLARE_ALIGNED(32, double, coeff[MAX_VARS][MAX_VARS]);
double variance[MAX_VARS];
@@ -47,25 +47,18 @@
* 32-byte aligned, and any padding elements must be initialized
* (i.e not denormal/nan).
*/
- void (*update_lls)(struct LLSModel *m, double *var);
+ void (*update_lls)(struct LLSModel2 *m, double *var);
/**
* Inner product of var[] and the LPC coefs.
* @param m this context
* @param var training samples, excluding the value to be predicted. unaligned.
* @param order lpc order
*/
- double (*evaluate_lls)(struct LLSModel *m, double *var, int order);
-} LLSModel;
+ double (*evaluate_lls)(struct LLSModel2 *m, double *var, int order);
+} LLSModel2;
-void avpriv_init_lls(LLSModel *m, int indep_count);
-void ff_init_lls_x86(LLSModel *m);
-void avpriv_solve_lls(LLSModel *m, double threshold, unsigned short min_order);
-
-#if FF_API_LLS_PRIVATE
-void av_init_lls(LLSModel *m, int indep_count);
-void av_update_lls(LLSModel *m, double *param, double decay);
-void av_solve_lls(LLSModel *m, double threshold, int min_order);
-double av_evaluate_lls(LLSModel *m, double *param, int order);
-#endif /* FF_API_LLS_PRIVATE */
+void avpriv_init_lls2(LLSModel2 *m, int indep_count);
+void ff_init_lls_x86(LLSModel2 *m);
+void avpriv_solve_lls2(LLSModel2 *m, double threshold, unsigned short min_order);
#endif /* AVUTIL_LLS_H */
diff --git a/libavutil/log.c b/libavutil/log.c
index 53be3ea..a7eb34c 100644
--- a/libavutil/log.c
+++ b/libavutil/log.c
@@ -40,6 +40,11 @@
#include "internal.h"
#include "log.h"
+#if HAVE_PTHREADS
+#include <pthread.h>
+static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
+#endif
+
#define LINE_SZ 1024
static int av_log_level = AV_LOG_INFO;
@@ -70,9 +75,6 @@
static int16_t background, attr_orig;
static HANDLE con;
-#define set_color(x) SetConsoleTextAttribute(con, background | color[x])
-#define set_256color set_color
-#define reset_color() SetConsoleTextAttribute(con, attr_orig)
#else
static const uint32_t color[16 + AV_CLASS_CATEGORY_NB] = {
@@ -96,14 +98,14 @@
[16+AV_CLASS_CATEGORY_SWRESAMPLER ] = 147 << 8 | 0x14,
};
-#define set_color(x) fprintf(stderr, "\033[%d;3%dm", (color[x] >> 4) & 15, color[x] & 15)
-#define set_256color(x) fprintf(stderr, "\033[48;5;%dm\033[38;5;%dm", (color[x] >> 16) & 0xff, (color[x] >> 8) & 0xff)
-#define reset_color() fprintf(stderr, "\033[0m")
#endif
static int use_color = -1;
static void colored_fputs(int level, const char *str)
{
+ if (!*str)
+ return;
+
if (use_color < 0) {
#if HAVE_SETCONSOLETEXTATTRIBUTE
CONSOLE_SCREEN_BUFFER_INFO con_info;
@@ -127,14 +129,29 @@
#endif
}
- if (use_color == 1) {
- set_color(level);
- } else if (use_color == 256)
- set_256color(level);
+#if HAVE_SETCONSOLETEXTATTRIBUTE
+ if (use_color && level != AV_LOG_INFO/8)
+ SetConsoleTextAttribute(con, background | color[level]);
fputs(str, stderr);
- if (use_color) {
- reset_color();
- }
+ if (use_color && level != AV_LOG_INFO/8)
+ SetConsoleTextAttribute(con, attr_orig);
+#else
+ if (use_color == 1 && level != AV_LOG_INFO/8) {
+ fprintf(stderr,
+ "\033[%d;3%dm%s\033[0m",
+ (color[level] >> 4) & 15,
+ color[level] & 15,
+ str);
+ } else if (use_color == 256 && level != AV_LOG_INFO/8) {
+ fprintf(stderr,
+ "\033[48;5;%dm\033[38;5;%dm%s\033[0m",
+ (color[level] >> 16) & 0xff,
+ (color[level] >> 8) & 0xff,
+ str);
+ } else
+ fputs(str, stderr);
+#endif
+
}
const char *av_default_item_name(void *ptr)
@@ -195,7 +212,7 @@
av_vbprintf(part+2, fmt, vl);
if(*part[0].str || *part[1].str || *part[2].str) {
- char lastc = part[2].len ? part[2].str[part[2].len - 1] : 0;
+ char lastc = part[2].len && part[2].len <= part[2].size ? part[2].str[part[2].len - 1] : 0;
*print_prefix = lastc == '\n' || lastc == '\r';
}
}
@@ -221,6 +238,10 @@
if (level > av_log_level)
return;
+#if HAVE_PTHREADS
+ pthread_mutex_lock(&mutex);
+#endif
+
format_line(ptr, level, fmt, vl, part, &print_prefix, type);
snprintf(line, sizeof(line), "%s%s%s", part[0].str, part[1].str, part[2].str);
@@ -234,8 +255,7 @@
count++;
if (is_atty == 1)
fprintf(stderr, " Last message repeated %d times\r", count);
- av_bprint_finalize(part+2, NULL);
- return;
+ goto end;
}
if (count > 0) {
fprintf(stderr, " Last message repeated %d times\n", count);
@@ -248,7 +268,11 @@
colored_fputs(type[1], part[1].str);
sanitize(part[2].str);
colored_fputs(av_clip(level >> 3, 0, 6), part[2].str);
+end:
av_bprint_finalize(part+2, NULL);
+#if HAVE_PTHREADS
+ pthread_mutex_unlock(&mutex);
+#endif
}
static void (*av_log_callback)(void*, int, const char*, va_list) =
@@ -268,8 +292,9 @@
void av_vlog(void* avcl, int level, const char *fmt, va_list vl)
{
- if(av_log_callback)
- av_log_callback(avcl, level, fmt, vl);
+ void (*log_callback)(void*, int, const char*, va_list) = av_log_callback;
+ if (log_callback)
+ log_callback(avcl, level, fmt, vl);
}
int av_log_get_level(void)
diff --git a/libavutil/log.h b/libavutil/log.h
index d3935da..55459e8 100644
--- a/libavutil/log.h
+++ b/libavutil/log.h
@@ -240,6 +240,9 @@
/**
* Set the logging callback
*
+ * @note The callback must be thread safe, even if the application does not use
+ * threads itself as some codecs are multithreaded.
+ *
* @see av_log_default_callback
*
* @param callback A logging function with a compatible signature.
diff --git a/libavutil/mem.c b/libavutil/mem.c
index a7f306a..10b0137 100644
--- a/libavutil/mem.c
+++ b/libavutil/mem.c
@@ -38,6 +38,7 @@
#include "avassert.h"
#include "avutil.h"
+#include "common.h"
#include "intreadwrite.h"
#include "mem.h"
@@ -258,7 +259,7 @@
char *ptr = NULL;
if (s) {
int len = strlen(s) + 1;
- ptr = av_malloc(len);
+ ptr = av_realloc(NULL, len);
if (ptr)
memcpy(ptr, s, len);
}
@@ -463,3 +464,41 @@
}
}
+void *av_fast_realloc(void *ptr, unsigned int *size, size_t min_size)
+{
+ if (min_size < *size)
+ return ptr;
+
+ min_size = FFMAX(17 * min_size / 16 + 32, min_size);
+
+ ptr = av_realloc(ptr, min_size);
+ /* we could set this to the unmodified min_size but this is safer
+ * if the user lost the ptr and uses NULL now
+ */
+ if (!ptr)
+ min_size = 0;
+
+ *size = min_size;
+
+ return ptr;
+}
+
+static inline int ff_fast_malloc(void *ptr, unsigned int *size, size_t min_size, int zero_realloc)
+{
+ void **p = ptr;
+ if (min_size < *size)
+ return 0;
+ min_size = FFMAX(17 * min_size / 16 + 32, min_size);
+ av_free(*p);
+ *p = zero_realloc ? av_mallocz(min_size) : av_malloc(min_size);
+ if (!*p)
+ min_size = 0;
+ *size = min_size;
+ return 1;
+}
+
+void av_fast_malloc(void *ptr, unsigned int *size, size_t min_size)
+{
+ ff_fast_malloc(ptr, size, min_size, 0);
+}
+
diff --git a/libavutil/mem.h b/libavutil/mem.h
index b73b724..703ce81 100644
--- a/libavutil/mem.h
+++ b/libavutil/mem.h
@@ -92,7 +92,7 @@
*/
av_alloc_size(1, 2) static inline void *av_malloc_array(size_t nmemb, size_t size)
{
- if (size <= 0 || nmemb >= INT_MAX / size)
+ if (!size || nmemb >= INT_MAX / size)
return NULL;
return av_malloc(nmemb * size);
}
@@ -227,7 +227,7 @@
*/
av_alloc_size(1, 2) static inline void *av_mallocz_array(size_t nmemb, size_t size)
{
- if (size <= 0 || nmemb >= INT_MAX / size)
+ if (!size || nmemb >= INT_MAX / size)
return NULL;
return av_mallocz(nmemb * size);
}
@@ -336,6 +336,27 @@
void av_memcpy_backptr(uint8_t *dst, int back, int cnt);
/**
+ * Reallocate the given block if it is not large enough, otherwise do nothing.
+ *
+ * @see av_realloc
+ */
+void *av_fast_realloc(void *ptr, unsigned int *size, size_t min_size);
+
+/**
+ * Allocate a buffer, reusing the given one if large enough.
+ *
+ * Contrary to av_fast_realloc the current buffer contents might not be
+ * preserved and on error the old buffer is freed, thus no special
+ * handling to avoid memleaks is necessary.
+ *
+ * @param ptr pointer to pointer to already allocated buffer, overwritten with pointer to new buffer
+ * @param size size of the buffer *ptr points to
+ * @param min_size minimum size of *ptr buffer after returning, *ptr will be NULL and
+ * *size 0 if an error occurred.
+ */
+void av_fast_malloc(void *ptr, unsigned int *size, size_t min_size);
+
+/**
* @}
*/
diff --git a/libavutil/old_pix_fmts.h b/libavutil/old_pix_fmts.h
index 3ee8aec..cd1ed7c 100644
--- a/libavutil/old_pix_fmts.h
+++ b/libavutil/old_pix_fmts.h
@@ -44,8 +44,10 @@
PIX_FMT_YUVJ420P, ///< planar YUV 4:2:0, 12bpp, full scale (JPEG), deprecated in favor of PIX_FMT_YUV420P and setting color_range
PIX_FMT_YUVJ422P, ///< planar YUV 4:2:2, 16bpp, full scale (JPEG), deprecated in favor of PIX_FMT_YUV422P and setting color_range
PIX_FMT_YUVJ444P, ///< planar YUV 4:4:4, 24bpp, full scale (JPEG), deprecated in favor of PIX_FMT_YUV444P and setting color_range
+#if FF_API_XVMC
PIX_FMT_XVMC_MPEG2_MC,///< XVideo Motion Acceleration via common packet passing
PIX_FMT_XVMC_MPEG2_IDCT,
+#endif /* FF_API_XVMC */
PIX_FMT_UYVY422, ///< packed YUV 4:2:2, 16bpp, Cb Y0 Cr Y1
PIX_FMT_UYYVYY411, ///< packed YUV 4:1:1, 12bpp, Cb Y0 Y1 Cr Y2 Y3
PIX_FMT_BGR8, ///< packed RGB 3:3:2, 8bpp, (msb)2B 3G 3R(lsb)
diff --git a/libavutil/opencl.c b/libavutil/opencl.c
index e0b28c3..142c6b0 100644
--- a/libavutil/opencl.c
+++ b/libavutil/opencl.c
@@ -1,7 +1,8 @@
/*
- * Copyright (C) 2012 Peng Gao <peng@multicorewareinc.com>
- * Copyright (C) 2012 Li Cao <li@multicorewareinc.com>
- * Copyright (C) 2012 Wei Gao <weigao@multicorewareinc.com>
+ * Copyright (C) 2012 Peng Gao <peng@multicorewareinc.com>
+ * Copyright (C) 2012 Li Cao <li@multicorewareinc.com>
+ * Copyright (C) 2012 Wei Gao <weigao@multicorewareinc.com>
+ * Copyright (C) 2013 Lenny Wang <lwanghpc@gmail.com>
*
* This file is part of FFmpeg.
*
@@ -39,8 +40,6 @@
#define UNLOCK_OPENCL
#endif
-
-#define MAX_KERNEL_NUM 500
#define MAX_KERNEL_CODE_NUM 200
typedef struct {
@@ -61,17 +60,19 @@
int is_user_created;
int platform_idx;
int device_idx;
- char *build_options;
cl_platform_id platform_id;
cl_device_type device_type;
cl_context context;
cl_device_id device_id;
cl_command_queue command_queue;
+#if FF_API_OLD_OPENCL
+ char *build_options;
int program_count;
cl_program programs[MAX_KERNEL_CODE_NUM];
+ int kernel_count;
+#endif
int kernel_code_count;
KernelCode kernel_code[MAX_KERNEL_CODE_NUM];
- int kernel_count;
AVOpenCLDeviceList device_list;
} OpenclContext;
@@ -80,7 +81,9 @@
static const AVOption opencl_options[] = {
{ "platform_idx", "set platform index value", OFFSET(platform_idx), AV_OPT_TYPE_INT, {.i64=-1}, -1, INT_MAX},
{ "device_idx", "set device index value", OFFSET(device_idx), AV_OPT_TYPE_INT, {.i64=-1}, -1, INT_MAX},
+#if FF_API_OLD_OPENCL
{ "build_options", "build options of opencl", OFFSET(build_options), AV_OPT_TYPE_STRING, {.str="-I."}, CHAR_MIN, CHAR_MAX},
+#endif
{ NULL }
};
@@ -95,7 +98,7 @@
static OpenclContext opencl_ctx = {&openclutils_class};
-static const cl_device_type device_type[] = {CL_DEVICE_TYPE_GPU, CL_DEVICE_TYPE_CPU, CL_DEVICE_TYPE_DEFAULT};
+static const cl_device_type device_type[] = {CL_DEVICE_TYPE_GPU, CL_DEVICE_TYPE_CPU};
typedef struct {
int err_code;
@@ -194,7 +197,7 @@
static int get_device_list(AVOpenCLDeviceList *device_list)
{
cl_int status;
- int i, j, k, device_num, total_devices_num,ret = 0;
+ int i, j, k, device_num, total_devices_num, ret = 0;
int *devices_num;
cl_platform_id *platform_ids = NULL;
cl_device_id *device_ids = NULL;
@@ -388,66 +391,72 @@
return ret;
}
-int av_opencl_create_kernel(AVOpenCLKernelEnv *env, const char *kernel_name)
+cl_program av_opencl_compile(const char *program_name, const char *build_opts)
{
+ int i;
cl_int status;
- int i, ret = 0;
+ int kernel_code_idx = 0;
+ const char *kernel_source;
+ size_t kernel_code_len;
+ char* ptr = NULL;
+ cl_program program = NULL;
+
LOCK_OPENCL;
- if (strlen(kernel_name) + 1 > AV_OPENCL_MAX_KERNEL_NAME_SIZE) {
- av_log(&opencl_ctx, AV_LOG_ERROR, "Created kernel name %s is too long\n", kernel_name);
- ret = AVERROR(EINVAL);
+ for (i = 0; i < opencl_ctx.kernel_code_count; i++) {
+ // identify a program using a unique name within the kernel source
+ ptr = av_stristr(opencl_ctx.kernel_code[i].kernel_string, program_name);
+ if (ptr && !opencl_ctx.kernel_code[i].is_compiled) {
+ kernel_source = opencl_ctx.kernel_code[i].kernel_string;
+ kernel_code_len = strlen(opencl_ctx.kernel_code[i].kernel_string);
+ kernel_code_idx = i;
+ break;
+ }
+ }
+ if (!kernel_source) {
+ av_log(&opencl_ctx, AV_LOG_ERROR,
+ "Unable to find OpenCL kernel source '%s'\n", program_name);
goto end;
}
- if (!env->kernel) {
- if (opencl_ctx.kernel_count >= MAX_KERNEL_NUM) {
- av_log(&opencl_ctx, AV_LOG_ERROR,
- "Could not create kernel with name '%s', maximum number of kernels %d already reached\n",
- kernel_name, MAX_KERNEL_NUM);
- ret = AVERROR(EINVAL);
- goto end;
- }
- if (opencl_ctx.program_count == 0) {
- av_log(&opencl_ctx, AV_LOG_ERROR, "Program count of OpenCL is 0, can not create kernel\n");
- ret = AVERROR(EINVAL);
- goto end;
- }
- for (i = 0; i < opencl_ctx.program_count; i++) {
- env->kernel = clCreateKernel(opencl_ctx.programs[i], kernel_name, &status);
- if (status == CL_SUCCESS)
- break;
- }
- if (status != CL_SUCCESS) {
- av_log(&opencl_ctx, AV_LOG_ERROR, "Could not create OpenCL kernel: %s\n", av_opencl_errstr(status));
- ret = AVERROR_EXTERNAL;
- goto end;
- }
- opencl_ctx.kernel_count++;
- env->command_queue = opencl_ctx.command_queue;
- av_strlcpy(env->kernel_name, kernel_name, sizeof(env->kernel_name));
+
+ /* create a CL program from kernel source */
+ program = clCreateProgramWithSource(opencl_ctx.context, 1, &kernel_source, &kernel_code_len, &status);
+ if(status != CL_SUCCESS) {
+ av_log(&opencl_ctx, AV_LOG_ERROR,
+ "Unable to create OpenCL program '%s': %s\n", program_name, av_opencl_errstr(status));
+ program = NULL;
+ goto end;
}
+ status = clBuildProgram(program, 1, &(opencl_ctx.device_id), build_opts, NULL, NULL);
+ if (status != CL_SUCCESS) {
+ av_log(&opencl_ctx, AV_LOG_ERROR,
+ "Compilation failed with OpenCL program: %s\n", program_name);
+ program = NULL;
+ goto end;
+ }
+
+ opencl_ctx.kernel_code[kernel_code_idx].is_compiled = 1;
end:
UNLOCK_OPENCL;
- return ret;
+ return program;
+}
+
+cl_command_queue av_opencl_get_command_queue(void)
+{
+ return opencl_ctx.command_queue;
+}
+
+#if FF_API_OLD_OPENCL
+int av_opencl_create_kernel(AVOpenCLKernelEnv *env, const char *kernel_name)
+{
+ av_log(&opencl_ctx, AV_LOG_ERROR, "Could not create OpenCL kernel %s, please update libavfilter.\n", kernel_name);
+ return AVERROR(EINVAL);
}
void av_opencl_release_kernel(AVOpenCLKernelEnv *env)
{
- cl_int status;
- LOCK_OPENCL;
- if (!env->kernel)
- goto end;
- status = clReleaseKernel(env->kernel);
- if (status != CL_SUCCESS) {
- av_log(&opencl_ctx, AV_LOG_ERROR, "Could not release kernel: %s\n",
- av_opencl_errstr(status));
- }
- env->kernel = NULL;
- env->command_queue = NULL;
- env->kernel_name[0] = 0;
- opencl_ctx.kernel_count--;
-end:
- UNLOCK_OPENCL;
+ av_log(&opencl_ctx, AV_LOG_ERROR, "Could not release OpenCL kernel, please update libavfilter.\n");
}
+#endif
static int init_opencl_env(OpenclContext *opencl_ctx, AVOpenCLExternalEnv *ext_opencl_env)
{
@@ -542,49 +551,6 @@
return ret;
}
-static int compile_kernel_file(OpenclContext *opencl_ctx)
-{
- cl_int status;
- int i, kernel_code_count = 0;
- const char *kernel_code[MAX_KERNEL_CODE_NUM] = {NULL};
- size_t kernel_code_len[MAX_KERNEL_CODE_NUM] = {0};
-
- for (i = 0; i < opencl_ctx->kernel_code_count; i++) {
- if (!opencl_ctx->kernel_code[i].is_compiled) {
- kernel_code[kernel_code_count] = opencl_ctx->kernel_code[i].kernel_string;
- kernel_code_len[kernel_code_count] = strlen(opencl_ctx->kernel_code[i].kernel_string);
- opencl_ctx->kernel_code[i].is_compiled = 1;
- kernel_code_count++;
- }
- }
- if (!kernel_code_count)
- return 0;
- /* create a CL program using the kernel source */
- opencl_ctx->programs[opencl_ctx->program_count] = clCreateProgramWithSource(opencl_ctx->context,
- kernel_code_count,
- kernel_code,
- kernel_code_len,
- &status);
- if(status != CL_SUCCESS) {
- av_log(opencl_ctx, AV_LOG_ERROR,
- "Could not create OpenCL program with source code: %s\n", av_opencl_errstr(status));
- return AVERROR_EXTERNAL;
- }
- if (!opencl_ctx->programs[opencl_ctx->program_count]) {
- av_log(opencl_ctx, AV_LOG_ERROR, "Created program is NULL\n");
- return AVERROR_EXTERNAL;
- }
- status = clBuildProgram(opencl_ctx->programs[opencl_ctx->program_count], 1, &(opencl_ctx->device_id),
- opencl_ctx->build_options, NULL, NULL);
- if (status != CL_SUCCESS) {
- av_log(opencl_ctx, AV_LOG_ERROR,
- "Could not compile OpenCL kernel: %s\n", av_opencl_errstr(status));
- return AVERROR_EXTERNAL;
- }
- opencl_ctx->program_count++;
- return 0;
-}
-
int av_opencl_init(AVOpenCLExternalEnv *ext_opencl_env)
{
int ret = 0;
@@ -597,18 +563,14 @@
ret = init_opencl_env(&opencl_ctx, ext_opencl_env);
if (ret < 0)
goto end;
- }
- ret = compile_kernel_file(&opencl_ctx);
- if (ret < 0)
- goto end;
- if (opencl_ctx.kernel_code_count <= 0) {
- av_log(&opencl_ctx, AV_LOG_ERROR,
- "No kernel code is registered, compile kernel file failed\n");
- ret = AVERROR(EINVAL);
- goto end;
+ if (opencl_ctx.kernel_code_count <= 0) {
+ av_log(&opencl_ctx, AV_LOG_ERROR,
+ "No kernel code is registered, compile kernel file failed\n");
+ ret = AVERROR(EINVAL);
+ goto end;
+ }
}
opencl_ctx.init_count++;
-
end:
UNLOCK_OPENCL;
return ret;
@@ -617,23 +579,12 @@
void av_opencl_uninit(void)
{
cl_int status;
- int i;
LOCK_OPENCL;
opencl_ctx.init_count--;
if (opencl_ctx.is_user_created)
goto end;
- if (opencl_ctx.init_count > 0 || opencl_ctx.kernel_count > 0)
+ if (opencl_ctx.init_count > 0)
goto end;
- for (i = 0; i < opencl_ctx.program_count; i++) {
- if (opencl_ctx.programs[i]) {
- status = clReleaseProgram(opencl_ctx.programs[i]);
- if (status != CL_SUCCESS) {
- av_log(&opencl_ctx, AV_LOG_ERROR,
- "Could not release OpenCL program: %s\n", av_opencl_errstr(status));
- }
- opencl_ctx.programs[i] = NULL;
- }
- }
if (opencl_ctx.command_queue) {
status = clReleaseCommandQueue(opencl_ctx.command_queue);
if (status != CL_SUCCESS) {
@@ -652,7 +603,7 @@
}
free_device_list(&opencl_ctx.device_list);
end:
- if ((opencl_ctx.init_count <= 0) && (opencl_ctx.kernel_count <= 0))
+ if (opencl_ctx.init_count <= 0)
av_opt_free(&opencl_ctx); //FIXME: free openclutils context
UNLOCK_OPENCL;
}
@@ -810,3 +761,45 @@
}
return 0;
}
+
+int64_t av_opencl_benchmark(AVOpenCLDeviceNode *device_node, cl_platform_id platform,
+ int64_t (*benchmark)(AVOpenCLExternalEnv *ext_opencl_env))
+{
+ int64_t ret = 0;
+ cl_int status;
+ cl_context_properties cps[3];
+ AVOpenCLExternalEnv *ext_opencl_env = NULL;
+
+ ext_opencl_env = av_opencl_alloc_external_env();
+ ext_opencl_env->device_id = device_node->device_id;
+ ext_opencl_env->device_type = device_node->device_type;
+ av_log(&opencl_ctx, AV_LOG_VERBOSE, "Performing test on OpenCL device %s\n",
+ device_node->device_name);
+
+ cps[0] = CL_CONTEXT_PLATFORM;
+ cps[1] = (cl_context_properties)platform;
+ cps[2] = 0;
+ ext_opencl_env->context = clCreateContextFromType(cps, ext_opencl_env->device_type,
+ NULL, NULL, &status);
+ if (status != CL_SUCCESS || !ext_opencl_env->context) {
+ ret = AVERROR_EXTERNAL;
+ goto end;
+ }
+ ext_opencl_env->command_queue = clCreateCommandQueue(ext_opencl_env->context,
+ ext_opencl_env->device_id, 0, &status);
+ if (status != CL_SUCCESS || !ext_opencl_env->command_queue) {
+ ret = AVERROR_EXTERNAL;
+ goto end;
+ }
+ ret = benchmark(ext_opencl_env);
+ if (ret < 0)
+ av_log(&opencl_ctx, AV_LOG_ERROR, "Benchmark failed with OpenCL device %s\n",
+ device_node->device_name);
+end:
+ if (ext_opencl_env->command_queue)
+ clReleaseCommandQueue(ext_opencl_env->command_queue);
+ if (ext_opencl_env->context)
+ clReleaseContext(ext_opencl_env->context);
+ av_opencl_free_external_env(&ext_opencl_env);
+ return ret;
+}
diff --git a/libavutil/opencl.h b/libavutil/opencl.h
index 094c108..cf0abd7 100644
--- a/libavutil/opencl.h
+++ b/libavutil/opencl.h
@@ -1,7 +1,8 @@
/*
- * Copyright (C) 2012 Peng Gao <peng@multicorewareinc.com>
- * Copyright (C) 2012 Li Cao <li@multicorewareinc.com>
- * Copyright (C) 2012 Wei Gao <weigao@multicorewareinc.com>
+ * Copyright (C) 2012 Peng Gao <peng@multicorewareinc.com>
+ * Copyright (C) 2012 Li Cao <li@multicorewareinc.com>
+ * Copyright (C) 2012 Wei Gao <weigao@multicorewareinc.com>
+ * Copyright (C) 2013 Lenny Wang <lwanghpc@gmail.com>
*
* This file is part of FFmpeg.
*
@@ -39,6 +40,8 @@
#endif
#include "dict.h"
+#include "libavutil/version.h"
+
#define AV_OPENCL_KERNEL( ... )# __VA_ARGS__
#define AV_OPENCL_MAX_KERNEL_NAME_SIZE 150
@@ -65,11 +68,13 @@
AVOpenCLPlatformNode **platform_node;
} AVOpenCLDeviceList;
+#if FF_API_OLD_OPENCL
typedef struct {
cl_command_queue command_queue;
cl_kernel kernel;
char kernel_name[AV_OPENCL_MAX_KERNEL_NAME_SIZE];
} AVOpenCLKernelEnv;
+#endif
typedef struct {
cl_platform_id platform_id;
@@ -107,7 +112,6 @@
* av_opencl_init() operation.
*
* The currently accepted options are:
- * - build_options: set options to compile registered kernels code
* - platform: set index of platform in device list
* - device: set index of device in device list
*
@@ -174,15 +178,15 @@
int av_opencl_register_kernel_code(const char *kernel_code);
/**
- * Initialize the run time OpenCL environment and compile the kernel
- * code registered with av_opencl_register_kernel_code().
+ * Initialize the run time OpenCL environment
*
* @param ext_opencl_env external OpenCL environment, created by an
* application program, ignored if set to NULL
* @return >=0 on success, a negative error code in case of failure
*/
- int av_opencl_init(AVOpenCLExternalEnv *ext_opencl_env);
+int av_opencl_init(AVOpenCLExternalEnv *ext_opencl_env);
+#if FF_API_OLD_OPENCL
/**
* Create kernel object in the specified kernel environment.
*
@@ -190,8 +194,27 @@
* the environment used to run the kernel
* @param kernel_name kernel function name
* @return >=0 on success, a negative error code in case of failure
+ * @deprecated, use clCreateKernel
*/
int av_opencl_create_kernel(AVOpenCLKernelEnv *env, const char *kernel_name);
+#endif
+
+/**
+ * compile specific OpenCL kernel source
+ *
+ * @param program_name pointer to a program name used for identification
+ * @param build_opts pointer to a string that describes the preprocessor
+ * build options to be used for building the program
+ * @return a cl_program object
+ */
+cl_program av_opencl_compile(const char *program_name, const char* build_opts);
+
+/**
+ * get OpenCL command queue
+ *
+ * @return a cl_command_queue object
+ */
+cl_command_queue av_opencl_get_command_queue(void);
/**
* Create OpenCL buffer.
@@ -268,13 +291,16 @@
*/
void av_opencl_buffer_release(cl_mem *cl_buf);
+#if FF_API_OLD_OPENCL
/**
* Release kernel object.
*
* @param env kernel environment where the kernel object was created
* with av_opencl_create_kernel()
+ * @deprecated, use clReleaseKernel
*/
void av_opencl_release_kernel(AVOpenCLKernelEnv *env);
+#endif
/**
* Release OpenCL environment.
@@ -284,4 +310,20 @@
*/
void av_opencl_uninit(void);
+/**
+ * Benchmark an OpenCL device with a user defined callback function. This function
+ * sets up an external OpenCL environment including context and command queue on
+ * the device then tears it down in the end. The callback function should perform
+ * the rest of the work.
+ *
+ * @param device pointer to the OpenCL device to be used
+ * @param platform cl_platform_id handle to which the device belongs to
+ * @param benchmark callback function to perform the benchmark, return a
+ * negative value in case of failure
+ * @return the score passed from the callback function, a negative error code in case
+ * of failure
+ */
+int64_t av_opencl_benchmark(AVOpenCLDeviceNode *device, cl_platform_id platform,
+ int64_t (*benchmark)(AVOpenCLExternalEnv *ext_opencl_env));
+
#endif /* LIBAVUTIL_OPENCL_H */
diff --git a/libavutil/opt.c b/libavutil/opt.c
index c035307..f6aa496 100644
--- a/libavutil/opt.c
+++ b/libavutil/opt.c
@@ -27,6 +27,7 @@
#include "avutil.h"
#include "avstring.h"
+#include "channel_layout.h"
#include "common.h"
#include "opt.h"
#include "eval.h"
@@ -77,6 +78,7 @@
case AV_OPT_TYPE_PIXEL_FMT:
case AV_OPT_TYPE_SAMPLE_FMT:
case AV_OPT_TYPE_INT: *intnum = *(int *)dst;return 0;
+ case AV_OPT_TYPE_CHANNEL_LAYOUT:
case AV_OPT_TYPE_DURATION:
case AV_OPT_TYPE_INT64: *intnum = *(int64_t *)dst;return 0;
case AV_OPT_TYPE_FLOAT: *num = *(float *)dst;return 0;
@@ -91,11 +93,21 @@
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) {
+ if (o->type != AV_OPT_TYPE_FLAGS &&
+ (o->max * den < num * intnum || o->min * den > num * intnum)) {
av_log(obj, AV_LOG_ERROR, "Value %f for parameter '%s' out of range [%g - %g]\n",
num*intnum/den, o->name, o->min, o->max);
return AVERROR(ERANGE);
}
+ if (o->type == AV_OPT_TYPE_FLAGS) {
+ double d = num*intnum/den;
+ if (d < -1.5 || d > 0xFFFFFFFF+0.5 || (llrint(d*256) & 255)) {
+ av_log(obj, AV_LOG_ERROR,
+ "Value %f for parameter '%s' is not a valid set of 32bit integer flags\n",
+ num*intnum/den, o->name);
+ return AVERROR(ERANGE);
+ }
+ }
switch (o->type) {
case AV_OPT_TYPE_FLAGS:
@@ -103,6 +115,7 @@
case AV_OPT_TYPE_SAMPLE_FMT:
case AV_OPT_TYPE_INT: *(int *)dst= llrint(num/den)*intnum; break;
case AV_OPT_TYPE_DURATION:
+ case AV_OPT_TYPE_CHANNEL_LAYOUT:
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;
@@ -239,6 +252,49 @@
return 0;
}
+static int set_string_image_size(void *obj, const AVOption *o, const char *val, int *dst)
+{
+ int ret;
+
+ if (!val || !strcmp(val, "none")) {
+ dst[0] =
+ dst[1] = 0;
+ return 0;
+ }
+ ret = av_parse_video_size(dst, dst + 1, val);
+ if (ret < 0)
+ av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as image size\n", val);
+ return ret;
+}
+
+static int set_string_video_rate(void *obj, const AVOption *o, const char *val, AVRational *dst)
+{
+ int ret;
+ if (!val) {
+ ret = AVERROR(EINVAL);
+ } else {
+ ret = av_parse_video_rate(dst, val);
+ }
+ if (ret < 0)
+ av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as video rate\n", val);
+ return ret;
+}
+
+static int set_string_color(void *obj, const AVOption *o, const char *val, uint8_t *dst)
+{
+ int ret;
+
+ if (!val) {
+ return 0;
+ } else {
+ ret = av_parse_color(dst, val, -1, obj);
+ if (ret < 0)
+ av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as color\n", val);
+ return ret;
+ }
+ 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)
{
@@ -251,7 +307,7 @@
int av_opt_set(void *obj, const char *name, const char *val, int search_flags)
{
- int ret;
+ int ret = 0;
void *dst, *target_obj;
const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
if (!o || !target_obj)
@@ -259,7 +315,8 @@
if (!val && (o->type != AV_OPT_TYPE_STRING &&
o->type != AV_OPT_TYPE_PIXEL_FMT && o->type != AV_OPT_TYPE_SAMPLE_FMT &&
o->type != AV_OPT_TYPE_IMAGE_SIZE && o->type != AV_OPT_TYPE_VIDEO_RATE &&
- o->type != AV_OPT_TYPE_DURATION && o->type != AV_OPT_TYPE_COLOR))
+ o->type != AV_OPT_TYPE_DURATION && o->type != AV_OPT_TYPE_COLOR &&
+ o->type != AV_OPT_TYPE_CHANNEL_LAYOUT))
return AVERROR(EINVAL);
dst = ((uint8_t*)target_obj) + o->offset;
@@ -272,24 +329,8 @@
case AV_OPT_TYPE_FLOAT:
case AV_OPT_TYPE_DOUBLE:
case AV_OPT_TYPE_RATIONAL: return set_string_number(obj, target_obj, o, val, dst);
- case AV_OPT_TYPE_IMAGE_SIZE:
- if (!val || !strcmp(val, "none")) {
- *(int *)dst = *((int *)dst + 1) = 0;
- return 0;
- }
- ret = av_parse_video_size(dst, ((int *)dst) + 1, val);
- if (ret < 0)
- av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as image size\n", val);
- return ret;
- case AV_OPT_TYPE_VIDEO_RATE:
- if (!val) {
- ret = AVERROR(EINVAL);
- } else {
- ret = av_parse_video_rate(dst, val);
- }
- if (ret < 0)
- av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as video rate\n", val);
- return ret;
+ case AV_OPT_TYPE_IMAGE_SIZE: return set_string_image_size(obj, o, val, dst);
+ case AV_OPT_TYPE_VIDEO_RATE: return set_string_video_rate(obj, o, val, dst);
case AV_OPT_TYPE_PIXEL_FMT:
if (!val || !strcmp(val, "none")) {
ret = AV_PIX_FMT_NONE;
@@ -332,15 +373,24 @@
return ret;
}
break;
- case AV_OPT_TYPE_COLOR:
- if (!val) {
- return 0;
+ case AV_OPT_TYPE_COLOR: return set_string_color(obj, o, val, dst);
+ case AV_OPT_TYPE_CHANNEL_LAYOUT:
+ if (!val || !strcmp(val, "none")) {
+ *(int64_t *)dst = 0;
} else {
- ret = av_parse_color(dst, val, -1, obj);
- if (ret < 0)
- av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as color\n", val);
+#if FF_API_GET_CHANNEL_LAYOUT_COMPAT
+ int64_t cl = ff_get_channel_layout(val, 0);
+#else
+ int64_t cl = av_get_channel_layout(val);
+#endif
+ if (!cl) {
+ av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as channel layout\n", val);
+ ret = AVERROR(EINVAL);
+ }
+ *(int64_t *)dst = cl;
return ret;
}
+ break;
}
av_log(obj, AV_LOG_ERROR, "Invalid option type.\n");
@@ -532,6 +582,22 @@
return set_format(obj, name, fmt, search_flags, AV_OPT_TYPE_SAMPLE_FMT, "sample", AV_SAMPLE_FMT_NB);
}
+int av_opt_set_channel_layout(void *obj, const char *name, int64_t cl, int search_flags)
+{
+ void *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 (o->type != AV_OPT_TYPE_CHANNEL_LAYOUT) {
+ av_log(obj, AV_LOG_ERROR,
+ "The value set by option '%s' is not a channel layout.\n", o->name);
+ return AVERROR(EINVAL);
+ }
+ *(int *)(((int64_t *)target_obj) + o->offset) = cl;
+ return 0;
+}
+
#if FF_API_OLD_AVOPTIONS
/**
*
@@ -630,6 +696,10 @@
case AV_OPT_TYPE_COLOR:
ret = snprintf(buf, sizeof(buf), "0x%02x%02x%02x%02x", ((int *)dst)[0], ((int *)dst)[1], ((int *)dst)[2], ((int *)dst)[3]);
break;
+ case AV_OPT_TYPE_CHANNEL_LAYOUT:
+ i64 = *(int64_t *)dst;
+ ret = snprintf(buf, sizeof(buf), "0x%"PRIx64, i64);
+ break;
default:
return AVERROR(EINVAL);
}
@@ -799,6 +869,23 @@
return get_format(obj, name, search_flags, out_fmt, AV_OPT_TYPE_SAMPLE_FMT, "sample");
}
+int av_opt_get_channel_layout(void *obj, const char *name, int search_flags, int64_t *cl)
+{
+ 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 (o->type != AV_OPT_TYPE_CHANNEL_LAYOUT) {
+ av_log(obj, AV_LOG_ERROR,
+ "The value for option '%s' is not a channel layout.\n", name);
+ return AVERROR(EINVAL);
+ }
+
+ dst = ((uint8_t*)target_obj) + o->offset;
+ *cl = *(int64_t *)dst;
+ return 0;
+}
+
int av_opt_flag_is_set(void *obj, const char *field_name, const char *flag_name)
{
const AVOption *field = av_opt_find(obj, field_name, NULL, 0, 0);
@@ -902,6 +989,9 @@
case AV_OPT_TYPE_COLOR:
av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<color>");
break;
+ case AV_OPT_TYPE_CHANNEL_LAYOUT:
+ av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<channel_layout>");
+ break;
case AV_OPT_TYPE_CONST:
default:
av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "");
@@ -972,6 +1062,10 @@
case AV_OPT_TYPE_STRING:
case AV_OPT_TYPE_VIDEO_RATE:
av_log(av_log_obj, AV_LOG_INFO, "\"%s\"", opt->default_val.str);
+ break;
+ case AV_OPT_TYPE_CHANNEL_LAYOUT:
+ av_log(av_log_obj, AV_LOG_INFO, "0x%"PRIx64, opt->default_val.i64);
+ break;
}
av_log(av_log_obj, AV_LOG_INFO, ")");
}
@@ -1007,6 +1101,7 @@
const AVClass *class = *(AVClass **)s;
const AVOption *opt = NULL;
while ((opt = av_opt_next(s, opt)) != NULL) {
+ void *dst = ((uint8_t*)s) + opt->offset;
#if FF_API_OLD_AVOPTIONS
if ((opt->flags & mask) != flags)
continue;
@@ -1019,26 +1114,33 @@
case AV_OPT_TYPE_INT:
case AV_OPT_TYPE_INT64:
case AV_OPT_TYPE_DURATION:
- av_opt_set_int(s, opt->name, opt->default_val.i64, 0);
+ case AV_OPT_TYPE_CHANNEL_LAYOUT:
+ write_number(s, opt, dst, 1, 1, opt->default_val.i64);
break;
case AV_OPT_TYPE_DOUBLE:
case AV_OPT_TYPE_FLOAT: {
double val;
val = opt->default_val.dbl;
- av_opt_set_double(s, opt->name, val, 0);
+ write_number(s, opt, dst, val, 1, 1);
}
break;
case AV_OPT_TYPE_RATIONAL: {
AVRational val;
val = av_d2q(opt->default_val.dbl, INT_MAX);
- av_opt_set_q(s, opt->name, val, 0);
+ write_number(s, opt, dst, 1, val.den, val.num);
}
break;
case AV_OPT_TYPE_COLOR:
+ set_string_color(s, opt, opt->default_val.str, dst);
+ break;
case AV_OPT_TYPE_STRING:
+ set_string(s, opt, opt->default_val.str, dst);
+ break;
case AV_OPT_TYPE_IMAGE_SIZE:
+ set_string_image_size(s, opt, opt->default_val.str, dst);
+ break;
case AV_OPT_TYPE_VIDEO_RATE:
- av_opt_set(s, opt->name, opt->default_val.str, 0);
+ set_string_video_rate(s, opt, opt->default_val.str, dst);
break;
case AV_OPT_TYPE_PIXEL_FMT:
#if LIBAVUTIL_VERSION_MAJOR < 53
@@ -1046,7 +1148,7 @@
av_opt_set(s, opt->name, opt->default_val.str, 0);
else
#endif
- av_opt_set_pixel_fmt(s, opt->name, opt->default_val.i64, 0);
+ write_number(s, opt, dst, 1, 1, opt->default_val.i64);
break;
case AV_OPT_TYPE_SAMPLE_FMT:
#if LIBAVUTIL_VERSION_MAJOR < 53
@@ -1054,7 +1156,7 @@
av_opt_set(s, opt->name, opt->default_val.str, 0);
else
#endif
- av_opt_set_sample_fmt(s, opt->name, opt->default_val.i64, 0);
+ write_number(s, opt, dst, 1, 1, opt->default_val.i64);
break;
case AV_OPT_TYPE_BINARY:
/* Cannot set default for binary */
@@ -1395,6 +1497,7 @@
case AV_OPT_TYPE_DOUBLE:
case AV_OPT_TYPE_DURATION:
case AV_OPT_TYPE_COLOR:
+ case AV_OPT_TYPE_CHANNEL_LAYOUT:
break;
case AV_OPT_TYPE_STRING:
range->component_min = 0;
@@ -1462,6 +1565,7 @@
enum AVSampleFormat sample_fmt;
int64_t duration;
uint8_t color[4];
+ int64_t channel_layout;
} TestContext;
#define OFFSET(x) offsetof(TestContext, x)
@@ -1485,6 +1589,7 @@
{"video_rate", "set videorate", OFFSET(video_rate), AV_OPT_TYPE_VIDEO_RATE, {.str = "25"}, 0, 0 },
{"duration", "set duration", OFFSET(duration), AV_OPT_TYPE_DURATION, {.i64 = 0}, 0, INT64_MAX},
{"color", "set color", OFFSET(color), AV_OPT_TYPE_COLOR, {.str = "pink"}, 0, 0},
+{"cl", "set channel layout", OFFSET(channel_layout), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64 = AV_CH_LAYOUT_HEXAGONAL}, 0, INT64_MAX},
{NULL},
};
@@ -1546,6 +1651,8 @@
"color=blue",
"color=0x223300",
"color=0x42FF07AA",
+ "cl=stereo+downmix",
+ "cl=foo",
};
test_ctx.class = &test_class;
@@ -1559,7 +1666,7 @@
av_log(&test_ctx, AV_LOG_ERROR, "Error setting options string: '%s'\n", options[i]);
printf("\n");
}
- av_freep(&test_ctx.string);
+ av_opt_free(&test_ctx);
}
printf("\nTesting av_opt_set_from_string()\n");
@@ -1580,7 +1687,6 @@
test_ctx.class = &test_class;
av_opt_set_defaults(&test_ctx);
- test_ctx.string = av_strdup("default");
av_log_set_level(AV_LOG_DEBUG);
@@ -1590,7 +1696,7 @@
av_log(&test_ctx, AV_LOG_ERROR, "Error setting options string: '%s'\n", options[i]);
printf("\n");
}
- av_freep(&test_ctx.string);
+ av_opt_free(&test_ctx);
}
return 0;
diff --git a/libavutil/opt.h b/libavutil/opt.h
index 331c5de..14faa6e 100644
--- a/libavutil/opt.h
+++ b/libavutil/opt.h
@@ -233,6 +233,7 @@
AV_OPT_TYPE_VIDEO_RATE = MKBETAG('V','R','A','T'), ///< offset must point to AVRational
AV_OPT_TYPE_DURATION = MKBETAG('D','U','R',' '),
AV_OPT_TYPE_COLOR = MKBETAG('C','O','L','R'),
+ AV_OPT_TYPE_CHANNEL_LAYOUT = MKBETAG('C','H','L','A'),
#if FF_API_OLD_AVOPTIONS
FF_OPT_TYPE_FLAGS = 0,
FF_OPT_TYPE_INT,
@@ -319,7 +320,7 @@
/**
* Look for an option in obj. Look only for the options which
* have the flags set as specified in mask and flags (that is,
- * for which it is the case that opt->flags & mask == flags).
+ * for which it is the case that (opt->flags & mask) == flags).
*
* @param[in] obj a pointer to a struct whose first element is a
* pointer to an AVClass
@@ -657,6 +658,7 @@
int av_opt_set_pixel_fmt (void *obj, const char *name, enum AVPixelFormat fmt, int search_flags);
int av_opt_set_sample_fmt(void *obj, const char *name, enum AVSampleFormat fmt, int search_flags);
int av_opt_set_video_rate(void *obj, const char *name, AVRational val, int search_flags);
+int av_opt_set_channel_layout(void *obj, const char *name, int64_t ch_layout, int search_flags);
/**
* Set a binary option to an integer list.
@@ -690,7 +692,7 @@
* @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
+ * @note the returned string will be 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);
@@ -700,6 +702,7 @@
int av_opt_get_pixel_fmt (void *obj, const char *name, int search_flags, enum AVPixelFormat *out_fmt);
int av_opt_get_sample_fmt(void *obj, const char *name, int search_flags, enum AVSampleFormat *out_fmt);
int av_opt_get_video_rate(void *obj, const char *name, int search_flags, AVRational *out_val);
+int av_opt_get_channel_layout(void *obj, const char *name, int search_flags, int64_t *ch_layout);
/**
* @}
*/
diff --git a/libavutil/parseutils.c b/libavutil/parseutils.c
index 1e1b93e..e793e2d 100644
--- a/libavutil/parseutils.c
+++ b/libavutil/parseutils.c
@@ -420,6 +420,20 @@
return 0;
}
+const char *av_get_known_color_name(int color_idx, const uint8_t **rgbp)
+{
+ const ColorEntry *color;
+
+ if ((unsigned)color_idx >= FF_ARRAY_ELEMS(color_table))
+ return NULL;
+
+ color = &color_table[color_idx];
+ if (rgbp)
+ *rgbp = color->rgb_color;
+
+ return color->name;
+}
+
/* get a positive number between n_min and n_max, for a maximum length
of len_max. Return -1 if error. */
static int date_get_num(const char **pp,
diff --git a/libavutil/parseutils.h b/libavutil/parseutils.h
index 3eb35fc..c80f0de 100644
--- a/libavutil/parseutils.h
+++ b/libavutil/parseutils.h
@@ -99,6 +99,19 @@
void *log_ctx);
/**
+ * Get the name of a color from the internal table of hard-coded named
+ * colors.
+ *
+ * This function is meant to enumerate the color names recognized by
+ * av_parse_color().
+ *
+ * @param color_idx index of the requested color, starting from 0
+ * @param rgbp if not NULL, will point to a 3-elements array with the color value in RGB
+ * @return the color name string or NULL if color_idx is not in the array
+ */
+const char *av_get_known_color_name(int color_idx, const uint8_t **rgb);
+
+/**
* Parse timestr and return in *time a corresponding number of
* microseconds.
*
@@ -127,7 +140,7 @@
* @endcode
* @param duration flag which tells how to interpret timestr, if not
* zero timestr is interpreted as a duration, otherwise as a date
- * @return 0 in case of success, a negative value corresponding to an
+ * @return >= 0 in case of success, a negative value corresponding to an
* AVERROR code otherwise
*/
int av_parse_time(int64_t *timeval, const char *timestr, int duration);
diff --git a/libavutil/pixdesc.c b/libavutil/pixdesc.c
index 9a33000..0cb2f34 100644
--- a/libavutil/pixdesc.c
+++ b/libavutil/pixdesc.c
@@ -29,6 +29,7 @@
#include "internal.h"
#include "intreadwrite.h"
#include "avstring.h"
+#include "version.h"
void av_read_image_line(uint16_t *dst,
const uint8_t *data[4], const int linesize[4],
@@ -313,6 +314,7 @@
},
.flags = AV_PIX_FMT_FLAG_PLANAR,
},
+#if FF_API_XVMC
[AV_PIX_FMT_XVMC_MPEG2_MC] = {
.name = "xvmcmc",
.flags = AV_PIX_FMT_FLAG_HWACCEL,
@@ -321,6 +323,7 @@
.name = "xvmcidct",
.flags = AV_PIX_FMT_FLAG_HWACCEL,
},
+#endif /* FF_API_XVMC */
[AV_PIX_FMT_UYVY422] = {
.name = "uyvy422",
.nb_components = 3,
diff --git a/libavutil/pixfmt.h b/libavutil/pixfmt.h
index 1b9e142..3d32d3e 100644
--- a/libavutil/pixfmt.h
+++ b/libavutil/pixfmt.h
@@ -59,8 +59,8 @@
* 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.
+ * 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 AVPixelFormat {
@@ -80,8 +80,10 @@
AV_PIX_FMT_YUVJ420P, ///< planar YUV 4:2:0, 12bpp, full scale (JPEG), deprecated in favor of PIX_FMT_YUV420P and setting color_range
AV_PIX_FMT_YUVJ422P, ///< planar YUV 4:2:2, 16bpp, full scale (JPEG), deprecated in favor of PIX_FMT_YUV422P and setting color_range
AV_PIX_FMT_YUVJ444P, ///< planar YUV 4:4:4, 24bpp, full scale (JPEG), deprecated in favor of PIX_FMT_YUV444P and setting color_range
+#if FF_API_XVMC
AV_PIX_FMT_XVMC_MPEG2_MC,///< XVideo Motion Acceleration via common packet passing
AV_PIX_FMT_XVMC_MPEG2_IDCT,
+#endif /* FF_API_XVMC */
AV_PIX_FMT_UYVY422, ///< packed YUV 4:2:2, 16bpp, Cb Y0 Cr Y1
AV_PIX_FMT_UYYVYY411, ///< packed YUV 4:1:1, 12bpp, Cb Y0 Y1 Cr Y2 Y3
AV_PIX_FMT_BGR8, ///< packed RGB 3:3:2, 8bpp, (msb)2B 3G 3R(lsb)
diff --git a/libavutil/stereo3d.c b/libavutil/stereo3d.c
new file mode 100644
index 0000000..a44af21
--- /dev/null
+++ b/libavutil/stereo3d.c
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2013 Vittorio Giovara <vittorio.giovara@gmail.com>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdint.h>
+
+#include "mem.h"
+#include "stereo3d.h"
+
+AVStereo3D *av_stereo3d_alloc(void)
+{
+ return av_mallocz(sizeof(AVStereo3D));
+}
+
+AVStereo3D *av_stereo3d_create_side_data(AVFrame *frame)
+{
+ AVFrameSideData *side_data = av_frame_new_side_data(frame,
+ AV_FRAME_DATA_STEREO3D,
+ sizeof(AVStereo3D));
+ if (!side_data)
+ return NULL;
+
+ return (AVStereo3D *)side_data->data;
+}
diff --git a/libavutil/stereo3d.h b/libavutil/stereo3d.h
new file mode 100644
index 0000000..b384ad4
--- /dev/null
+++ b/libavutil/stereo3d.h
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2013 Vittorio Giovara <vittorio.giovara@gmail.com>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdint.h>
+
+#include "frame.h"
+
+/**
+ * List of possible 3D Types
+ */
+enum AVStereo3DType {
+ /**
+ * Video is not stereoscopic (and metadata has to be there).
+ */
+ AV_STEREO3D_2D,
+
+ /**
+ * Views are next to each other.
+ *
+ * LLLLRRRR
+ * LLLLRRRR
+ * LLLLRRRR
+ * ...
+ */
+ AV_STEREO3D_SIDEBYSIDE,
+
+ /**
+ * Views are on top of each other.
+ *
+ * LLLLLLLL
+ * LLLLLLLL
+ * RRRRRRRR
+ * RRRRRRRR
+ */
+ AV_STEREO3D_TOPBOTTOM,
+
+ /**
+ * Views are alternated temporally.
+ *
+ * frame0 frame1 frame2 ...
+ * LLLLLLLL RRRRRRRR LLLLLLLL
+ * LLLLLLLL RRRRRRRR LLLLLLLL
+ * LLLLLLLL RRRRRRRR LLLLLLLL
+ * ... ... ...
+ */
+ AV_STEREO3D_FRAMESEQUENCE,
+
+ /**
+ * Views are packed in a checkerboard-like structure per pixel.
+ *
+ * LRLRLRLR
+ * RLRLRLRL
+ * LRLRLRLR
+ * ...
+ */
+ AV_STEREO3D_CHECKERBOARD,
+
+ /**
+ * Views are next to each other, but when upscaling
+ * apply a checkerboard pattern.
+ *
+ * LLLLRRRR L L L L R R R R
+ * LLLLRRRR => L L L L R R R R
+ * LLLLRRRR L L L L R R R R
+ * LLLLRRRR L L L L R R R R
+ */
+ AV_STEREO3D_SIDEBYSIDE_QUINCUNX,
+
+ /**
+ * Views are packed per line, as if interlaced.
+ *
+ * LLLLLLLL
+ * RRRRRRRR
+ * LLLLLLLL
+ * ...
+ */
+ AV_STEREO3D_LINES,
+
+ /**
+ * Views are packed per column.
+ *
+ * LRLRLRLR
+ * LRLRLRLR
+ * LRLRLRLR
+ * ...
+ */
+ AV_STEREO3D_COLUMNS,
+};
+
+
+/**
+ * Inverted views, Right/Bottom represents the left view.
+ */
+#define AV_STEREO3D_FLAG_INVERT (1 << 0)
+
+/**
+ * Stereo 3D type: this structure describes how two videos are packed
+ * within a single video surface, with additional information as needed.
+ *
+ * @note The struct must be allocated with av_stereo3d_alloc() and
+ * its size is not a part of the public ABI.
+ */
+typedef struct AVStereo3D {
+ /**
+ * How views are packed within the video.
+ */
+ enum AVStereo3DType type;
+
+ /**
+ * Additional information about the frame packing.
+ */
+ int flags;
+} AVStereo3D;
+
+/**
+ * Allocate an AVStereo3D structure and set its fields to default values.
+ * The resulting struct can be freed using av_freep().
+ *
+ * @return An AVStereo3D filled with default values or NULL on failure.
+ */
+AVStereo3D *av_stereo3d_alloc(void);
+
+/**
+ * Allocate a complete AVFrameSideData and add it to the frame.
+ *
+ * @param The frame on which the side data is added to.
+ *
+ * @return The AVStereo3D structure to be filled by caller.
+ */
+AVStereo3D *av_stereo3d_create_side_data(AVFrame *frame);
diff --git a/libavutil/tree.c b/libavutil/tree.c
index e1b3197..d0b67ef 100644
--- a/libavutil/tree.c
+++ b/libavutil/tree.c
@@ -225,7 +225,7 @@
if (check(root) > 999) {
av_log(NULL, AV_LOG_ERROR, "FATAL error %d\n", i);
print(root, 0);
- return -1;
+ return 1;
}
av_log(NULL, AV_LOG_DEBUG, "inserting %4d\n", (int)j);
@@ -233,7 +233,7 @@
node = av_tree_node_alloc();
if (!node) {
av_log(NULL, AV_LOG_ERROR, "Memory allocation failure.\n");
- return AVERROR(ENOMEM);
+ return 1;
}
av_tree_insert(&root, (void *)(j + 1), cmp, &node);
diff --git a/libavutil/utf8.c b/libavutil/utf8.c
new file mode 100644
index 0000000..3447a51
--- /dev/null
+++ b/libavutil/utf8.c
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2013 Stefano Sabatini
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifdef TEST
+#include <stdio.h>
+
+#include "libavutil/avstring.h"
+#include "libavutil/file.h"
+
+static void print_sequence(const char *p, int l, int indent)
+{
+ int i;
+ for (i = 0; i < l; i++)
+ printf("%02X", (uint8_t)p[i]);
+ printf("%*s", indent-l*2, "");
+}
+
+int main(int argc, char **argv)
+{
+ int ret;
+ char *filename = argv[1];
+ uint8_t *file_buf;
+ size_t file_buf_size;
+ uint32_t code;
+ const uint8_t *p, *endp;
+
+ ret = av_file_map(filename, &file_buf, &file_buf_size, 0, NULL);
+ if (ret < 0)
+ return 1;
+
+ p = file_buf;
+ endp = file_buf + file_buf_size;
+ while (p < endp) {
+ int l, r;
+ const uint8_t *p0 = p;
+ code = UINT32_MAX;
+ r = av_utf8_decode(&code, &p, endp, 0);
+ l = (int)(p-p0);
+ print_sequence(p0, l, 20);
+ if (code != UINT32_MAX) {
+ printf("%-10d 0x%-10X %-5d ", code, code, l);
+ if (r >= 0) {
+ if (*p0 == '\n') printf("\\n\n");
+ else printf ("%.*s\n", l, p0);
+ } else {
+ printf("invalid code range\n");
+ }
+ } else {
+ printf("invalid sequence\n");
+ }
+ }
+
+ av_file_unmap(file_buf, file_buf_size);
+ return 0;
+}
+#endif
diff --git a/libavutil/utils.c b/libavutil/utils.c
index eb87c90..4c82503 100644
--- a/libavutil/utils.c
+++ b/libavutil/utils.c
@@ -40,6 +40,8 @@
av_assert0(LIBAVUTIL_VERSION_MICRO >= 100);
av_assert0(HAVE_MMX2 == HAVE_MMXEXT);
+ av_assert0(((size_t)-1) > 0); // C gurantees this but if false on a platform we care about revert at least b284e1ffe343d6697fb950d1ee517bafda8a9844
+
if (av_sat_dadd32(1, 2) != 5) {
av_log(NULL, AV_LOG_FATAL, "Libavutil has been build with a broken binutils, please upgrade binutils and rebuild\n");
abort();
@@ -49,7 +51,9 @@
av_log(NULL, AV_LOG_ERROR, "Libavutil has been linked to a broken llrint()\n");
}
+#if defined(ASSERT_LEVEL) && ASSERT_LEVEL > 0
ff_check_pixfmt_descriptors();
+#endif
checks_done = 1;
return LIBAVUTIL_VERSION_INT;
}
diff --git a/libavutil/version.h b/libavutil/version.h
index 2ec1a26..4eff48c 100644
--- a/libavutil/version.h
+++ b/libavutil/version.h
@@ -75,8 +75,8 @@
*/
#define LIBAVUTIL_VERSION_MAJOR 52
-#define LIBAVUTIL_VERSION_MINOR 46
-#define LIBAVUTIL_VERSION_MICRO 101
+#define LIBAVUTIL_VERSION_MINOR 58
+#define LIBAVUTIL_VERSION_MICRO 100
#define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \
LIBAVUTIL_VERSION_MINOR, \
@@ -134,12 +134,24 @@
#ifndef FF_API_LLS_PRIVATE
#define FF_API_LLS_PRIVATE (LIBAVUTIL_VERSION_MAJOR < 53)
#endif
+#ifndef FF_API_LLS1
+#define FF_API_LLS1 (LIBAVUTIL_VERSION_MAJOR < 53)
+#endif
#ifndef FF_API_AVFRAME_LAVC
#define FF_API_AVFRAME_LAVC (LIBAVUTIL_VERSION_MAJOR < 53)
#endif
#ifndef FF_API_VDPAU
#define FF_API_VDPAU (LIBAVUTIL_VERSION_MAJOR < 53)
#endif
+#ifndef FF_API_GET_CHANNEL_LAYOUT_COMPAT
+#define FF_API_GET_CHANNEL_LAYOUT_COMPAT (LIBAVUTIL_VERSION_MAJOR < 53)
+#endif
+#ifndef FF_API_OLD_OPENCL
+#define FF_API_OLD_OPENCL (LIBAVUTIL_VERSION_MAJOR < 53)
+#endif
+#ifndef FF_API_XVMC
+#define FF_API_XVMC (LIBAVUTIL_VERSION_MAJOR < 53)
+#endif
/**
* @}
diff --git a/libavutil/x86/cpu.c b/libavutil/x86/cpu.c
index 81bb15a..18049ea 100644
--- a/libavutil/x86/cpu.c
+++ b/libavutil/x86/cpu.c
@@ -134,6 +134,14 @@
if ((eax & 0x6) == 0x6)
rval |= AV_CPU_FLAG_AVX;
}
+#if HAVE_AVX2
+ if (max_std_level >= 7) {
+ cpuid(7, eax, ebx, ecx, edx);
+ if (ebx&0x00000020)
+ rval |= AV_CPU_FLAG_AVX2;
+ /* TODO: BMI1/2 */
+ }
+#endif /* HAVE_AVX2 */
#endif /* HAVE_AVX */
#endif /* HAVE_SSE */
}
diff --git a/libavutil/x86/cpu.h b/libavutil/x86/cpu.h
index 738c1ec..3724357 100644
--- a/libavutil/x86/cpu.h
+++ b/libavutil/x86/cpu.h
@@ -38,6 +38,7 @@
#define X86_SSE42(flags) CPUEXT(flags, SSE42)
#define X86_AVX(flags) CPUEXT(flags, AVX)
#define X86_FMA4(flags) CPUEXT(flags, FMA4)
+#define X86_AVX2(flags) CPUEXT(flags, AVX2)
#define EXTERNAL_AMD3DNOW(flags) CPUEXT_SUFFIX(flags, _EXTERNAL, AMD3DNOW)
#define EXTERNAL_AMD3DNOWEXT(flags) CPUEXT_SUFFIX(flags, _EXTERNAL, AMD3DNOWEXT)
@@ -51,6 +52,7 @@
#define EXTERNAL_SSE42(flags) CPUEXT_SUFFIX(flags, _EXTERNAL, SSE42)
#define EXTERNAL_AVX(flags) CPUEXT_SUFFIX(flags, _EXTERNAL, AVX)
#define EXTERNAL_FMA4(flags) CPUEXT_SUFFIX(flags, _EXTERNAL, FMA4)
+#define EXTERNAL_AVX2(flags) CPUEXT_SUFFIX(flags, _EXTERNAL, AVX2)
#define INLINE_AMD3DNOW(flags) CPUEXT_SUFFIX(flags, _INLINE, AMD3DNOW)
#define INLINE_AMD3DNOWEXT(flags) CPUEXT_SUFFIX(flags, _INLINE, AMD3DNOWEXT)
@@ -64,6 +66,7 @@
#define INLINE_SSE42(flags) CPUEXT_SUFFIX(flags, _INLINE, SSE42)
#define INLINE_AVX(flags) CPUEXT_SUFFIX(flags, _INLINE, AVX)
#define INLINE_FMA4(flags) CPUEXT_SUFFIX(flags, _INLINE, FMA4)
+#define INLINE_AVX2(flags) CPUEXT_SUFFIX(flags, _INLINE, AVX2)
void ff_cpu_cpuid(int index, int *eax, int *ebx, int *ecx, int *edx);
void ff_cpu_xgetbv(int op, int *eax, int *edx);
diff --git a/libavutil/x86/lls.asm b/libavutil/x86/lls.asm
index 769befb..c2aead3 100644
--- a/libavutil/x86/lls.asm
+++ b/libavutil/x86/lls.asm
@@ -29,7 +29,7 @@
%define COVAR_STRIDE MAX_VARS_ALIGN*8
%define COVAR(x,y) [covarq + (x)*8 + (y)*COVAR_STRIDE]
-struc LLSModel
+struc LLSModel2
.covariance: resq MAX_VARS_ALIGN*MAX_VARS_ALIGN
.coeff: resq MAX_VARS*MAX_VARS
.variance: resq MAX_VARS
@@ -49,7 +49,7 @@
%define movdqa movaps
cglobal update_lls, 2,5,8, ctx, var, i, j, covar2
%define covarq ctxq
- mov id, [ctxq + LLSModel.indep_count]
+ mov id, [ctxq + LLSModel2.indep_count]
lea varq, [varq + iq*8]
neg iq
mov covar2q, covarq
@@ -129,7 +129,7 @@
INIT_YMM avx
cglobal update_lls, 3,6,8, ctx, var, count, i, j, count2
%define covarq ctxq
- mov countd, [ctxq + LLSModel.indep_count]
+ mov countd, [ctxq + LLSModel2.indep_count]
lea count2d, [countq-2]
xor id, id
.loopi:
@@ -206,7 +206,7 @@
%define coefsq ctxq
mov id, orderd
imul orderd, MAX_VARS
- lea coefsq, [ctxq + LLSModel.coeff + orderq*8]
+ lea coefsq, [ctxq + LLSModel2.coeff + orderq*8]
movsd m0, [varq]
movhpd m0, [varq + 8]
mulpd m0, [coefsq]
diff --git a/libavutil/x86/lls_init.c b/libavutil/x86/lls_init.c
index 181ca38..bf999d5 100644
--- a/libavutil/x86/lls_init.c
+++ b/libavutil/x86/lls_init.c
@@ -20,14 +20,14 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include "libavutil/lls.h"
+#include "libavutil/lls2.h"
#include "libavutil/x86/cpu.h"
-void ff_update_lls_sse2(LLSModel *m, double *var);
-void ff_update_lls_avx(LLSModel *m, double *var);
-double ff_evaluate_lls_sse2(LLSModel *m, double *var, int order);
+void ff_update_lls_sse2(LLSModel2 *m, double *var);
+void ff_update_lls_avx(LLSModel2 *m, double *var);
+double ff_evaluate_lls_sse2(LLSModel2 *m, double *var, int order);
-av_cold void ff_init_lls_x86(LLSModel *m)
+av_cold void ff_init_lls_x86(LLSModel2 *m)
{
int cpu_flags = av_get_cpu_flags();
if (EXTERNAL_SSE2(cpu_flags)) {
diff --git a/libavutil/xtea.c b/libavutil/xtea.c
index 5bb4cf7..1750cbc 100644
--- a/libavutil/xtea.c
+++ b/libavutil/xtea.c
@@ -21,6 +21,13 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+/**
+ * @file
+ * @brief XTEA 32-bit implementation
+ * @author Samuel Pitoiset
+ * @ingroup lavu_xtea
+ */
+
#include "avutil.h"
#include "common.h"
#include "intreadwrite.h"
diff --git a/libavutil/xtea.h b/libavutil/xtea.h
index 0899c92..6f1e71e 100644
--- a/libavutil/xtea.h
+++ b/libavutil/xtea.h
@@ -25,6 +25,8 @@
#include <stdint.h>
/**
+ * @file
+ * @brief Public header for libavutil XTEA algorithm
* @defgroup lavu_xtea XTEA
* @ingroup lavu_crypto
* @{
diff --git a/libpostproc/Makefile b/libpostproc/Makefile
index 3fb5a70..b9bb4be 100644
--- a/libpostproc/Makefile
+++ b/libpostproc/Makefile
@@ -7,3 +7,6 @@
version.h \
OBJS = postprocess.o
+
+# Windows resource file
+SLIBOBJS-$(HAVE_GNU_WINDRES) += postprocres.o
diff --git a/libpostproc/postprocres.rc b/libpostproc/postprocres.rc
new file mode 100644
index 0000000..e6104ac
--- /dev/null
+++ b/libpostproc/postprocres.rc
@@ -0,0 +1,55 @@
+/*
+ * Windows resource file for libpostproc
+ *
+ * Copyright (C) 2012 James Almer
+ * Copyright (C) 2013 Tiancheng "Timothy" Gu
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <windows.h>
+#include "libpostproc/version.h"
+#include "libavutil/ffversion.h"
+#include "config.h"
+
+1 VERSIONINFO
+FILEVERSION LIBPOSTPROC_VERSION_MAJOR, LIBPOSTPROC_VERSION_MINOR, LIBPOSTPROC_VERSION_MICRO, 0
+PRODUCTVERSION LIBPOSTPROC_VERSION_MAJOR, LIBPOSTPROC_VERSION_MINOR, LIBPOSTPROC_VERSION_MICRO, 0
+FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+FILEOS VOS_NT_WINDOWS32
+FILETYPE VFT_DLL
+{
+ BLOCK "StringFileInfo"
+ {
+ BLOCK "040904B0"
+ {
+ VALUE "CompanyName", "FFmpeg Project"
+ VALUE "FileDescription", "FFmpeg postprocessing library"
+ VALUE "FileVersion", AV_STRINGIFY(LIBPOSTPROC_VERSION)
+ VALUE "InternalName", "libpostproc"
+ VALUE "LegalCopyright", "Copyright (C) 2000-" AV_STRINGIFY(CONFIG_THIS_YEAR) " FFmpeg Project"
+ VALUE "OriginalFilename", "postproc" BUILDSUF "-" AV_STRINGIFY(LIBPOSTPROC_VERSION_MAJOR) SLIBSUF
+ VALUE "ProductName", "FFmpeg"
+ VALUE "ProductVersion", FFMPEG_VERSION
+ }
+ }
+
+ BLOCK "VarFileInfo"
+ {
+ VALUE "Translation", 0x0409, 0x04B0
+ }
+}
diff --git a/library.mak b/library.mak
index 6d9b989..45096a7 100644
--- a/library.mak
+++ b/library.mak
@@ -25,7 +25,7 @@
$(SUBDIR)x86/%.o: $(SUBDIR)x86/%.asm
$(DEPYASM) $(YASMFLAGS) -I $(<D)/ -M -o $@ $< > $(@:.o=.d)
$(YASM) $(YASMFLAGS) -I $(<D)/ -o $@ $<
- -@ $(if $(STRIP), $(STRIP) -wN '..@*' $@)
+ -$(if $(ASMSTRIPFLAGS), $(STRIP) $(ASMSTRIPFLAGS) $@)
LIBOBJS := $(OBJS) $(SUBDIR)%.h.o $(TESTOBJS)
$(LIBOBJS) $(LIBOBJS:.o=.s) $(LIBOBJS:.o=.i): CPPFLAGS += -DHAVE_AV_CONFIG_H
@@ -51,7 +51,7 @@
$(SUBDIR)$(SLIBNAME): $(SUBDIR)$(SLIBNAME_WITH_MAJOR)
$(Q)cd ./$(SUBDIR) && $(LN_S) $(SLIBNAME_WITH_MAJOR) $(SLIBNAME)
-$(SUBDIR)$(SLIBNAME_WITH_MAJOR): $(OBJS) $(SUBDIR)lib$(NAME).ver
+$(SUBDIR)$(SLIBNAME_WITH_MAJOR): $(OBJS) $(SLIBOBJS) $(SUBDIR)lib$(NAME).ver
$(SLIB_CREATE_DEF_CMD)
$$(LD) $(SHFLAGS) $(LDFLAGS) $$(LD_O) $$(filter %.o,$$^) $(FFEXTRALIBS)
$(SLIB_EXTRA_CMD)
diff --git a/libswresample/Makefile b/libswresample/Makefile
index 0b75bd0..953c945 100644
--- a/libswresample/Makefile
+++ b/libswresample/Makefile
@@ -15,4 +15,7 @@
OBJS-$(CONFIG_LIBSOXR) += soxr_resample.o
OBJS-$(CONFIG_SHARED) += log2_tab.o
+# Windows resource file
+SLIBOBJS-$(HAVE_GNU_WINDRES) += swresampleres.o
+
TESTPROGS = swresample
diff --git a/libswresample/rematrix.c b/libswresample/rematrix.c
index 5c98e68..e146edf 100644
--- a/libswresample/rematrix.c
+++ b/libswresample/rematrix.c
@@ -433,8 +433,8 @@
off = len1 * out->bps;
}
- av_assert0(out->ch_count == av_get_channel_layout_nb_channels(s->out_ch_layout));
- av_assert0(in ->ch_count == av_get_channel_layout_nb_channels(s-> in_ch_layout));
+ av_assert0(!s->out_ch_layout || out->ch_count == av_get_channel_layout_nb_channels(s->out_ch_layout));
+ av_assert0(!s-> in_ch_layout || in ->ch_count == av_get_channel_layout_nb_channels(s-> in_ch_layout));
for(out_i=0; out_i<out->ch_count; out_i++){
switch(s->matrix_ch[out_i][0]){
diff --git a/libswresample/swresample.c b/libswresample/swresample.c
index b9a3c3d..93c96ce 100644
--- a/libswresample/swresample.c
+++ b/libswresample/swresample.c
@@ -57,10 +57,10 @@
{"out_sample_fmt" , "set output sample format" , OFFSET(out_sample_fmt ), AV_OPT_TYPE_SAMPLE_FMT , {.i64=AV_SAMPLE_FMT_NONE}, -1 , AV_SAMPLE_FMT_NB-1, PARAM},
{"tsf" , "set internal sample format" , OFFSET(int_sample_fmt ), AV_OPT_TYPE_SAMPLE_FMT , {.i64=AV_SAMPLE_FMT_NONE}, -1 , AV_SAMPLE_FMT_NB-1, PARAM},
{"internal_sample_fmt" , "set internal sample format" , OFFSET(int_sample_fmt ), AV_OPT_TYPE_SAMPLE_FMT , {.i64=AV_SAMPLE_FMT_NONE}, -1 , AV_SAMPLE_FMT_NB-1, PARAM},
-{"icl" , "set input channel layout" , OFFSET( in_ch_layout ), AV_OPT_TYPE_INT64, {.i64=0 }, 0 , INT64_MAX , PARAM, "channel_layout"},
-{"in_channel_layout" , "set input channel layout" , OFFSET( in_ch_layout ), AV_OPT_TYPE_INT64, {.i64=0 }, 0 , INT64_MAX , PARAM, "channel_layout"},
-{"ocl" , "set output channel layout" , OFFSET(out_ch_layout ), AV_OPT_TYPE_INT64, {.i64=0 }, 0 , INT64_MAX , PARAM, "channel_layout"},
-{"out_channel_layout" , "set output channel layout" , OFFSET(out_ch_layout ), AV_OPT_TYPE_INT64, {.i64=0 }, 0 , INT64_MAX , PARAM, "channel_layout"},
+{"icl" , "set input channel layout" , OFFSET( in_ch_layout ), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=0 }, 0 , INT64_MAX , PARAM, "channel_layout"},
+{"in_channel_layout" , "set input channel layout" , OFFSET( in_ch_layout ), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=0 }, 0 , INT64_MAX , PARAM, "channel_layout"},
+{"ocl" , "set output channel layout" , OFFSET(out_ch_layout ), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=0 }, 0 , INT64_MAX , PARAM, "channel_layout"},
+{"out_channel_layout" , "set output channel layout" , OFFSET(out_ch_layout ), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=0 }, 0 , INT64_MAX , PARAM, "channel_layout"},
{"clev" , "set center mix level" , OFFSET(clev ), AV_OPT_TYPE_FLOAT, {.dbl=C_30DB }, -32 , 32 , PARAM},
{"center_mix_level" , "set center mix level" , OFFSET(clev ), AV_OPT_TYPE_FLOAT, {.dbl=C_30DB }, -32 , 32 , PARAM},
{"slev" , "set surround mix level" , OFFSET(slev ), AV_OPT_TYPE_FLOAT, {.dbl=C_30DB }, -32 , 32 , PARAM},
@@ -534,6 +534,7 @@
AudioData in, out, tmp;
int ret_sum=0;
int border=0;
+ int padless = ARCH_X86 && s->engine == SWR_ENGINE_SWR ? 7 : 0;
av_assert1(s->in_buffer.ch_count == in_param->ch_count);
av_assert1(s->in_buffer.planar == in_param->planar);
@@ -564,9 +565,9 @@
}
}
- if((s->flushed || in_count) && !s->in_buffer_count){
+ if((s->flushed || in_count > padless) && !s->in_buffer_count){
s->in_buffer_index=0;
- ret= s->resampler->multiple_resample(s->resample, &out, out_count, &in, in_count, &consumed);
+ ret= s->resampler->multiple_resample(s->resample, &out, out_count, &in, FFMAX(in_count-padless, 0), &consumed);
out_count -= ret;
ret_sum += ret;
buf_set(&out, &out, ret);
@@ -598,6 +599,10 @@
s->resample_in_constraint= 0;
if(s->in_buffer_count != count || in_count)
continue;
+ if (padless) {
+ padless = 0;
+ continue;
+ }
}
break;
}while(1);
diff --git a/libswresample/swresample.h b/libswresample/swresample.h
index 23ceb98..3811301 100644
--- a/libswresample/swresample.h
+++ b/libswresample/swresample.h
@@ -44,8 +44,8 @@
* matrix):
* @code
* SwrContext *swr = swr_alloc();
- * av_opt_set_int(swr, "in_channel_layout", AV_CH_LAYOUT_5POINT1, 0);
- * av_opt_set_int(swr, "out_channel_layout", AV_CH_LAYOUT_STEREO, 0);
+ * av_opt_set_channel_layout(swr, "in_channel_layout", AV_CH_LAYOUT_5POINT1, 0);
+ * av_opt_set_channel_layout(swr, "out_channel_layout", AV_CH_LAYOUT_STEREO, 0);
* av_opt_set_int(swr, "in_sample_rate", 48000, 0);
* av_opt_set_int(swr, "out_sample_rate", 44100, 0);
* av_opt_set_sample_fmt(swr, "in_sample_fmt", AV_SAMPLE_FMT_FLTP, 0);
diff --git a/libswresample/swresampleres.rc b/libswresample/swresampleres.rc
new file mode 100644
index 0000000..1320f78
--- /dev/null
+++ b/libswresample/swresampleres.rc
@@ -0,0 +1,55 @@
+/*
+ * Windows resource file for libswresample
+ *
+ * Copyright (C) 2012 James Almer
+ * Copyright (C) 2013 Tiancheng "Timothy" Gu
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <windows.h>
+#include "libswresample/version.h"
+#include "libavutil/ffversion.h"
+#include "config.h"
+
+1 VERSIONINFO
+FILEVERSION LIBSWRESAMPLE_VERSION_MAJOR, LIBSWRESAMPLE_VERSION_MINOR, LIBSWRESAMPLE_VERSION_MICRO, 0
+PRODUCTVERSION LIBSWRESAMPLE_VERSION_MAJOR, LIBSWRESAMPLE_VERSION_MINOR, LIBSWRESAMPLE_VERSION_MICRO, 0
+FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+FILEOS VOS_NT_WINDOWS32
+FILETYPE VFT_DLL
+{
+ BLOCK "StringFileInfo"
+ {
+ BLOCK "040904B0"
+ {
+ VALUE "CompanyName", "FFmpeg Project"
+ VALUE "FileDescription", "FFmpeg audio resampling library"
+ VALUE "FileVersion", AV_STRINGIFY(LIBSWRESAMPLE_VERSION)
+ VALUE "InternalName", "libswresample"
+ VALUE "LegalCopyright", "Copyright (C) 2000-" AV_STRINGIFY(CONFIG_THIS_YEAR) " FFmpeg Project"
+ VALUE "OriginalFilename", "swresample" BUILDSUF "-" AV_STRINGIFY(LIBSWRESAMPLE_VERSION_MAJOR) SLIBSUF
+ VALUE "ProductName", "FFmpeg"
+ VALUE "ProductVersion", FFMPEG_VERSION
+ }
+ }
+
+ BLOCK "VarFileInfo"
+ {
+ VALUE "Translation", 0x0409, 0x04B0
+ }
+}
diff --git a/libswresample/version.h b/libswresample/version.h
index 8272b76..464c86d 100644
--- a/libswresample/version.h
+++ b/libswresample/version.h
@@ -30,7 +30,7 @@
#define LIBSWRESAMPLE_VERSION_MAJOR 0
#define LIBSWRESAMPLE_VERSION_MINOR 17
-#define LIBSWRESAMPLE_VERSION_MICRO 103
+#define LIBSWRESAMPLE_VERSION_MICRO 104
#define LIBSWRESAMPLE_VERSION_INT AV_VERSION_INT(LIBSWRESAMPLE_VERSION_MAJOR, \
LIBSWRESAMPLE_VERSION_MINOR, \
diff --git a/libswscale/Makefile b/libswscale/Makefile
index dd00f7d..ca6e27d 100644
--- a/libswscale/Makefile
+++ b/libswscale/Makefile
@@ -15,5 +15,8 @@
utils.o \
yuv2rgb.o \
+# Windows resource file
+SLIBOBJS-$(HAVE_GNU_WINDRES) += swscaleres.o
+
TESTPROGS = colorspace \
swscale \
diff --git a/libswscale/rgb2rgb.c b/libswscale/rgb2rgb.c
index ec9ff71..cf877fb 100644
--- a/libswscale/rgb2rgb.c
+++ b/libswscale/rgb2rgb.c
@@ -83,6 +83,9 @@
void (*interleaveBytes)(const uint8_t *src1, const uint8_t *src2, uint8_t *dst,
int width, int height, int src1Stride,
int src2Stride, int dstStride);
+void (*deinterleaveBytes)(const uint8_t *src, uint8_t *dst1, uint8_t *dst2,
+ int width, int height, int srcStride,
+ int dst1Stride, int dst2Stride);
void (*vu9_to_vu12)(const uint8_t *src1, const uint8_t *src2,
uint8_t *dst1, uint8_t *dst2,
int width, int height,
diff --git a/libswscale/rgb2rgb.h b/libswscale/rgb2rgb.h
index 340cc70..5df5dea 100644
--- a/libswscale/rgb2rgb.h
+++ b/libswscale/rgb2rgb.h
@@ -135,6 +135,10 @@
int width, int height, int src1Stride,
int src2Stride, int dstStride);
+extern void (*deinterleaveBytes)(const uint8_t *src, uint8_t *dst1, uint8_t *dst2,
+ int width, int height, int srcStride,
+ int dst1Stride, int dst2Stride);
+
extern void (*vu9_to_vu12)(const uint8_t *src1, const uint8_t *src2,
uint8_t *dst1, uint8_t *dst2,
int width, int height,
diff --git a/libswscale/rgb2rgb_template.c b/libswscale/rgb2rgb_template.c
index 98e3a14..56e735f 100644
--- a/libswscale/rgb2rgb_template.c
+++ b/libswscale/rgb2rgb_template.c
@@ -693,6 +693,24 @@
}
}
+static void deinterleaveBytes_c(const uint8_t *src, uint8_t *dst1, uint8_t *dst2,
+ int width, int height, int srcStride,
+ int dst1Stride, int dst2Stride)
+{
+ int h;
+
+ for (h = 0; h < height; h++) {
+ int w;
+ for (w = 0; w < width; w++) {
+ dst1[w] = src[2 * w + 0];
+ dst2[w] = src[2 * w + 1];
+ }
+ src += srcStride;
+ dst1 += dst1Stride;
+ dst2 += dst2Stride;
+ }
+}
+
static inline void vu9_to_vu12_c(const uint8_t *src1, const uint8_t *src2,
uint8_t *dst1, uint8_t *dst2,
int width, int height,
@@ -922,6 +940,7 @@
planar2x = planar2x_c;
ff_rgb24toyv12 = ff_rgb24toyv12_c;
interleaveBytes = interleaveBytes_c;
+ deinterleaveBytes = deinterleaveBytes_c;
vu9_to_vu12 = vu9_to_vu12_c;
yvu9_to_yuy2 = yvu9_to_yuy2_c;
diff --git a/libswscale/swscale_internal.h b/libswscale/swscale_internal.h
index 33fdfc2..6ad278e 100644
--- a/libswscale/swscale_internal.h
+++ b/libswscale/swscale_internal.h
@@ -362,9 +362,11 @@
int dstY; ///< Last destination vertical line output from last slice.
int flags; ///< Flags passed by the user to select scaler algorithm, optimizations, subsampling, etc...
void *yuvTable; // pointer to the yuv->rgb table start so it can be freed()
+ // alignment ensures the offset can be added in a single
+ // instruction on e.g. ARM
+ DECLARE_ALIGNED(16, int, table_gV)[256 + 2*YUVRGB_TABLE_HEADROOM];
uint8_t *table_rV[256 + 2*YUVRGB_TABLE_HEADROOM];
uint8_t *table_gU[256 + 2*YUVRGB_TABLE_HEADROOM];
- int table_gV[256 + 2*YUVRGB_TABLE_HEADROOM];
uint8_t *table_bU[256 + 2*YUVRGB_TABLE_HEADROOM];
DECLARE_ALIGNED(16, int32_t, input_rgb2yuv_table)[16+40*4]; // This table can contain both C and SIMD formatted values, teh C vales are always at the XY_IDX points
#define RY_IDX 0
diff --git a/libswscale/swscale_unscaled.c b/libswscale/swscale_unscaled.c
index 8fb2157..4181e0d 100644
--- a/libswscale/swscale_unscaled.c
+++ b/libswscale/swscale_unscaled.c
@@ -168,10 +168,31 @@
if (c->dstFormat == AV_PIX_FMT_NV12)
interleaveBytes(src[1], src[2], dst, c->srcW / 2, srcSliceH / 2,
- srcStride[1], srcStride[2], dstStride[0]);
+ srcStride[1], srcStride[2], dstStride[1]);
else
interleaveBytes(src[2], src[1], dst, c->srcW / 2, srcSliceH / 2,
- srcStride[2], srcStride[1], dstStride[0]);
+ srcStride[2], srcStride[1], dstStride[1]);
+
+ return srcSliceH;
+}
+
+static int nv12ToPlanarWrapper(SwsContext *c, const uint8_t *src[],
+ int srcStride[], int srcSliceY,
+ int srcSliceH, uint8_t *dstParam[],
+ int dstStride[])
+{
+ uint8_t *dst1 = dstParam[1] + dstStride[1] * srcSliceY / 2;
+ uint8_t *dst2 = dstParam[2] + dstStride[2] * srcSliceY / 2;
+
+ copyPlane(src[0], srcStride[0], srcSliceY, srcSliceH, c->srcW,
+ dstParam[0], dstStride[0]);
+
+ if (c->srcFormat == AV_PIX_FMT_NV12)
+ deinterleaveBytes(src[1], dst1, dst2,c->srcW / 2, srcSliceH / 2,
+ srcStride[1], dstStride[1], dstStride[2]);
+ else
+ deinterleaveBytes(src[1], dst2, dst1, c->srcW / 2, srcSliceH / 2,
+ srcStride[1], dstStride[2], dstStride[1]);
return srcSliceH;
}
@@ -394,6 +415,7 @@
int alpha, int swap, int bpp, int width)
{
int x, h, i;
+ int src_alpha = src[3] != NULL;
int scale_high = 16 - bpp, scale_low = (bpp - 8) * 2;
for (h = 0; h < srcSliceH; h++) {
uint16_t *dest = (uint16_t *)(dst + dstStride * h);
@@ -401,7 +423,7 @@
switch(swap) {
case 3:
- if (alpha) {
+ if (alpha && !src_alpha) {
for (x = 0; x < width; x++) {
component = av_bswap16(src[0][x]);
*dest++ = av_bswap16(component << scale_high | component >> scale_low);
@@ -411,6 +433,17 @@
*dest++ = av_bswap16(component << scale_high | component >> scale_low);
*dest++ = 0xffff;
}
+ } else if (alpha && src_alpha) {
+ for (x = 0; x < width; x++) {
+ component = av_bswap16(src[0][x]);
+ *dest++ = av_bswap16(component << scale_high | component >> scale_low);
+ component = av_bswap16(src[1][x]);
+ *dest++ = av_bswap16(component << scale_high | component >> scale_low);
+ component = av_bswap16(src[2][x]);
+ *dest++ = av_bswap16(component << scale_high | component >> scale_low);
+ component = av_bswap16(src[3][x]);
+ *dest++ = av_bswap16(component << scale_high | component >> scale_low);
+ }
} else {
for (x = 0; x < width; x++) {
component = av_bswap16(src[0][x]);
@@ -423,13 +456,20 @@
}
break;
case 2:
- if (alpha) {
+ if (alpha && !src_alpha) {
for (x = 0; x < width; x++) {
*dest++ = av_bswap16(src[0][x] << scale_high | src[0][x] >> scale_low);
*dest++ = av_bswap16(src[1][x] << scale_high | src[1][x] >> scale_low);
*dest++ = av_bswap16(src[2][x] << scale_high | src[2][x] >> scale_low);
*dest++ = 0xffff;
}
+ } else if (alpha && src_alpha) {
+ for (x = 0; x < width; x++) {
+ *dest++ = av_bswap16(src[0][x] << scale_high | src[0][x] >> scale_low);
+ *dest++ = av_bswap16(src[1][x] << scale_high | src[1][x] >> scale_low);
+ *dest++ = av_bswap16(src[2][x] << scale_high | src[2][x] >> scale_low);
+ *dest++ = av_bswap16(src[3][x] << scale_high | src[3][x] >> scale_low);
+ }
} else {
for (x = 0; x < width; x++) {
*dest++ = av_bswap16(src[0][x] << scale_high | src[0][x] >> scale_low);
@@ -439,13 +479,20 @@
}
break;
case 1:
- if (alpha) {
+ if (alpha && !src_alpha) {
for (x = 0; x < width; x++) {
*dest++ = av_bswap16(src[0][x]) << scale_high | av_bswap16(src[0][x]) >> scale_low;
*dest++ = av_bswap16(src[1][x]) << scale_high | av_bswap16(src[1][x]) >> scale_low;
*dest++ = av_bswap16(src[2][x]) << scale_high | av_bswap16(src[2][x]) >> scale_low;
*dest++ = 0xffff;
}
+ } else if (alpha && src_alpha) {
+ for (x = 0; x < width; x++) {
+ *dest++ = av_bswap16(src[0][x]) << scale_high | av_bswap16(src[0][x]) >> scale_low;
+ *dest++ = av_bswap16(src[1][x]) << scale_high | av_bswap16(src[1][x]) >> scale_low;
+ *dest++ = av_bswap16(src[2][x]) << scale_high | av_bswap16(src[2][x]) >> scale_low;
+ *dest++ = av_bswap16(src[3][x]) << scale_high | av_bswap16(src[3][x]) >> scale_low;
+ }
} else {
for (x = 0; x < width; x++) {
*dest++ = av_bswap16(src[0][x]) << scale_high | av_bswap16(src[0][x]) >> scale_low;
@@ -455,13 +502,20 @@
}
break;
default:
- if (alpha) {
+ if (alpha && !src_alpha) {
for (x = 0; x < width; x++) {
*dest++ = src[0][x] << scale_high | src[0][x] >> scale_low;
*dest++ = src[1][x] << scale_high | src[1][x] >> scale_low;
*dest++ = src[2][x] << scale_high | src[2][x] >> scale_low;
*dest++ = 0xffff;
}
+ } else if (alpha && src_alpha) {
+ for (x = 0; x < width; x++) {
+ *dest++ = src[0][x] << scale_high | src[0][x] >> scale_low;
+ *dest++ = src[1][x] << scale_high | src[1][x] >> scale_low;
+ *dest++ = src[2][x] << scale_high | src[2][x] >> scale_low;
+ *dest++ = src[3][x] << scale_high | src[3][x] >> scale_low;
+ }
} else {
for (x = 0; x < width; x++) {
*dest++ = src[0][x] << scale_high | src[0][x] >> scale_low;
@@ -470,7 +524,7 @@
}
}
}
- for (i = 0; i < 3; i++)
+ for (i = 0; i < 3 + src_alpha; i++)
src[i] += srcStride[i] >> 1;
}
}
@@ -479,10 +533,10 @@
int srcStride[], int srcSliceY, int srcSliceH,
uint8_t *dst[], int dstStride[])
{
- const uint16_t *src102[] = { (uint16_t *)src[1], (uint16_t *)src[0], (uint16_t *)src[2] };
- const uint16_t *src201[] = { (uint16_t *)src[2], (uint16_t *)src[0], (uint16_t *)src[1] };
- int stride102[] = { srcStride[1], srcStride[0], srcStride[2] };
- int stride201[] = { srcStride[2], srcStride[0], srcStride[1] };
+ const uint16_t *src102[] = { (uint16_t *)src[1], (uint16_t *)src[0], (uint16_t *)src[2], (uint16_t *)src[3] };
+ const uint16_t *src201[] = { (uint16_t *)src[2], (uint16_t *)src[0], (uint16_t *)src[1], (uint16_t *)src[3] };
+ int stride102[] = { srcStride[1], srcStride[0], srcStride[2], srcStride[3] };
+ int stride201[] = { srcStride[2], srcStride[0], srcStride[1], srcStride[3] };
const AVPixFmtDescriptor *src_format = av_pix_fmt_desc_get(c->srcFormat);
const AVPixFmtDescriptor *dst_format = av_pix_fmt_desc_get(c->dstFormat);
int bits_per_sample = src_format->comp[0].depth_minus1 + 1;
@@ -1058,27 +1112,24 @@
srcPtr += srcStride[plane];
}
} else if (src_depth <= dst_depth) {
- int orig_length = length;
for (i = 0; i < height; i++) {
+ j = 0;
if(isBE(c->srcFormat) == HAVE_BIGENDIAN &&
isBE(c->dstFormat) == HAVE_BIGENDIAN &&
shiftonly) {
unsigned shift = dst_depth - src_depth;
- length = orig_length;
#if HAVE_FAST_64BIT
#define FAST_COPY_UP(shift) \
- for (j = 0; j < length - 3; j += 4) { \
+ for (; j < length - 3; j += 4) { \
uint64_t v = AV_RN64A(srcPtr2 + j); \
AV_WN64A(dstPtr2 + j, v << shift); \
- } \
- length &= 3;
+ }
#else
#define FAST_COPY_UP(shift) \
- for (j = 0; j < length - 1; j += 2) { \
+ for (; j < length - 1; j += 2) { \
uint32_t v = AV_RN32A(srcPtr2 + j); \
AV_WN32A(dstPtr2 + j, v << shift); \
- } \
- length &= 1;
+ }
#endif
switch (shift)
{
@@ -1088,12 +1139,12 @@
}
#define COPY_UP(r,w) \
if(shiftonly){\
- for (j = 0; j < length; j++){ \
+ for (; j < length; j++){ \
unsigned int v= r(&srcPtr2[j]);\
w(&dstPtr2[j], v<<(dst_depth-src_depth));\
}\
}else{\
- for (j = 0; j < length; j++){ \
+ for (; j < length; j++){ \
unsigned int v= r(&srcPtr2[j]);\
w(&dstPtr2[j], (v<<(dst_depth-src_depth)) | \
(v>>(2*src_depth-dst_depth)));\
@@ -1182,6 +1233,11 @@
(dstFormat == AV_PIX_FMT_NV12 || dstFormat == AV_PIX_FMT_NV21)) {
c->swscale = planarToNv12Wrapper;
}
+ /* nv12_to_yv12 */
+ if (dstFormat == AV_PIX_FMT_YUV420P &&
+ (srcFormat == AV_PIX_FMT_NV12 || srcFormat == AV_PIX_FMT_NV21)) {
+ c->swscale = nv12ToPlanarWrapper;
+ }
/* yuv2bgr */
if ((srcFormat == AV_PIX_FMT_YUV420P || srcFormat == AV_PIX_FMT_YUV422P ||
srcFormat == AV_PIX_FMT_YUVA420P) && isAnyRGB(dstFormat) &&
@@ -1225,7 +1281,8 @@
srcFormat == AV_PIX_FMT_GBRP16LE || srcFormat == AV_PIX_FMT_GBRP16BE ||
srcFormat == AV_PIX_FMT_GBRP10LE || srcFormat == AV_PIX_FMT_GBRP10BE ||
srcFormat == AV_PIX_FMT_GBRP12LE || srcFormat == AV_PIX_FMT_GBRP12BE ||
- srcFormat == AV_PIX_FMT_GBRP14LE || srcFormat == AV_PIX_FMT_GBRP14BE) &&
+ srcFormat == AV_PIX_FMT_GBRP14LE || srcFormat == AV_PIX_FMT_GBRP14BE ||
+ srcFormat == AV_PIX_FMT_GBRAP16LE || srcFormat == AV_PIX_FMT_GBRAP16BE) &&
(dstFormat == AV_PIX_FMT_RGB48LE || dstFormat == AV_PIX_FMT_RGB48BE ||
dstFormat == AV_PIX_FMT_BGR48LE || dstFormat == AV_PIX_FMT_BGR48BE ||
dstFormat == AV_PIX_FMT_RGBA64LE || dstFormat == AV_PIX_FMT_RGBA64BE ||
diff --git a/libswscale/swscaleres.rc b/libswscale/swscaleres.rc
new file mode 100644
index 0000000..5cb8ee7
--- /dev/null
+++ b/libswscale/swscaleres.rc
@@ -0,0 +1,55 @@
+/*
+ * Windows resource file for libswscale
+ *
+ * Copyright (C) 2012 James Almer
+ * Copyright (C) 2013 Tiancheng "Timothy" Gu
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <windows.h>
+#include "libswscale/version.h"
+#include "libavutil/ffversion.h"
+#include "config.h"
+
+1 VERSIONINFO
+FILEVERSION LIBSWSCALE_VERSION_MAJOR, LIBSWSCALE_VERSION_MINOR, LIBSWSCALE_VERSION_MICRO, 0
+PRODUCTVERSION LIBSWSCALE_VERSION_MAJOR, LIBSWSCALE_VERSION_MINOR, LIBSWSCALE_VERSION_MICRO, 0
+FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+FILEOS VOS_NT_WINDOWS32
+FILETYPE VFT_DLL
+{
+ BLOCK "StringFileInfo"
+ {
+ BLOCK "040904B0"
+ {
+ VALUE "CompanyName", "FFmpeg Project"
+ VALUE "FileDescription", "FFmpeg image rescaling library"
+ VALUE "FileVersion", AV_STRINGIFY(LIBSWSCALE_VERSION)
+ VALUE "InternalName", "libswscale"
+ VALUE "LegalCopyright", "Copyright (C) 2000-" AV_STRINGIFY(CONFIG_THIS_YEAR) " FFmpeg Project"
+ VALUE "OriginalFilename", "swscale" BUILDSUF "-" AV_STRINGIFY(LIBSWSCALE_VERSION_MAJOR) SLIBSUF
+ VALUE "ProductName", "FFmpeg"
+ VALUE "ProductVersion", FFMPEG_VERSION
+ }
+ }
+
+ BLOCK "VarFileInfo"
+ {
+ VALUE "Translation", 0x0409, 0x04B0
+ }
+}
diff --git a/libswscale/utils.c b/libswscale/utils.c
index 5693291..90ddbf1 100644
--- a/libswscale/utils.c
+++ b/libswscale/utils.c
@@ -260,6 +260,26 @@
return pos >> chr_subsample;
}
+typedef struct {
+ int flag; ///< flag associated to the algorithm
+ const char *description; ///< human-readable description
+ int size_factor; ///< size factor used when initing the filters
+} ScaleAlgorithm;
+
+static const ScaleAlgorithm scale_algorithms[] = {
+ { SWS_AREA, "area averaging", 1 /* downscale only, for upscale it is bilinear */ },
+ { SWS_BICUBIC, "bicubic", 4 },
+ { SWS_BICUBLIN, "luma bicubic / chroma bilinear", -1 },
+ { SWS_BILINEAR, "bilinear", 2 },
+ { SWS_FAST_BILINEAR, "fast bilinear", -1 },
+ { SWS_GAUSS, "Gaussian", 8 /* infinite ;) */ },
+ { SWS_LANCZOS, "Lanczos", -1 /* custom */ },
+ { SWS_POINT, "nearest neighbor / point", -1 },
+ { SWS_SINC, "sinc", 20 /* infinite ;) */ },
+ { SWS_SPLINE, "bicubic spline", 20 /* infinite :)*/ },
+ { SWS_X, "experimental", 8 },
+};
+
static av_cold int initFilter(int16_t **outFilter, int32_t **filterPos,
int *outFilterSize, int xInc, int srcW,
int dstW, int filterAlign, int one,
@@ -332,27 +352,17 @@
}
} else {
int64_t xDstInSrc;
- int sizeFactor;
+ int sizeFactor = -1;
- if (flags & SWS_BICUBIC)
- sizeFactor = 4;
- else if (flags & SWS_X)
- sizeFactor = 8;
- else if (flags & SWS_AREA)
- sizeFactor = 1; // downscale only, for upscale it is bilinear
- else if (flags & SWS_GAUSS)
- sizeFactor = 8; // infinite ;)
- else if (flags & SWS_LANCZOS)
- sizeFactor = param[0] != SWS_PARAM_DEFAULT ? ceil(2 * param[0]) : 6;
- else if (flags & SWS_SINC)
- sizeFactor = 20; // infinite ;)
- else if (flags & SWS_SPLINE)
- sizeFactor = 20; // infinite ;)
- else if (flags & SWS_BILINEAR)
- sizeFactor = 2;
- else {
- av_assert0(0);
+ for (i = 0; i < FF_ARRAY_ELEMS(scale_algorithms); i++) {
+ if (flags & scale_algorithms[i].flag) {
+ sizeFactor = scale_algorithms[i].size_factor;
+ break;
+ }
}
+ if (flags & SWS_LANCZOS)
+ sizeFactor = param[0] != SWS_PARAM_DEFAULT ? ceil(2 * param[0]) : 6;
+ av_assert0(sizeFactor > 0);
if (xInc <= 1 << 16)
filterSize = 1 + sizeFactor; // upscale
@@ -557,7 +567,7 @@
filter = av_malloc(filterSize * dstW * sizeof(*filter));
if (filterSize >= MAX_FILTER_SIZE * 16 /
((flags & SWS_ACCURATE_RND) ? APCK_SIZE : 16) || !filter) {
- av_log(NULL, AV_LOG_ERROR, "sws: filterSize %d is too large, try less extreem scaling or increase MAX_FILTER_SIZE and recompile\n", filterSize);
+ av_log(NULL, AV_LOG_ERROR, "sws: filterSize %d is too large, try less extreme scaling or increase MAX_FILTER_SIZE and recompile\n", filterSize);
goto fail;
}
*outFilterSize = filterSize;
@@ -821,13 +831,6 @@
}
#endif /* HAVE_MMXEXT_INLINE */
-static void getSubSampleFactors(int *h, int *v, enum AVPixelFormat format)
-{
- const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(format);
- *h = desc->log2_chroma_w;
- *v = desc->log2_chroma_h;
-}
-
static void fill_rgb2yuv_table(SwsContext *c, const int table[4], int dstRange)
{
int64_t W, V, Z, Cy, Cu, Cv;
@@ -982,8 +985,6 @@
c->srcRange = srcRange;
c->dstRange = dstRange;
- fill_xyztables(c);
-
if ((isYUV(c->dstFormat) || isGray(c->dstFormat)) && (isYUV(c->srcFormat) || isGray(c->srcFormat)))
return -1;
@@ -991,13 +992,13 @@
c->srcFormatBpp = av_get_bits_per_pixel(desc_src);
if (!isYUV(c->dstFormat) && !isGray(c->dstFormat)) {
- ff_yuv2rgb_c_init_tables(c, inv_table, srcRange, brightness,
- contrast, saturation);
- // FIXME factorize
+ ff_yuv2rgb_c_init_tables(c, inv_table, srcRange, brightness,
+ contrast, saturation);
+ // FIXME factorize
- if (ARCH_PPC)
- ff_yuv2rgb_init_tables_ppc(c, inv_table, brightness,
- contrast, saturation);
+ if (ARCH_PPC)
+ ff_yuv2rgb_init_tables_ppc(c, inv_table, brightness,
+ contrast, saturation);
}
fill_rgb2yuv_table(c, table, dstRange);
@@ -1074,6 +1075,8 @@
c->dst0Alpha |= handle_0alpha(&c->dstFormat);
c->srcXYZ |= handle_xyz(&c->srcFormat);
c->dstXYZ |= handle_xyz(&c->dstFormat);
+ if (c->srcXYZ || c->dstXYZ)
+ fill_xyztables(c);
}
SwsContext *sws_alloc_context(void)
@@ -1199,8 +1202,8 @@
(dstFilter->lumH && dstFilter->lumH->length > 1) ||
(dstFilter->chrH && dstFilter->chrH->length > 1);
- getSubSampleFactors(&c->chrSrcHSubSample, &c->chrSrcVSubSample, srcFormat);
- getSubSampleFactors(&c->chrDstHSubSample, &c->chrDstVSubSample, dstFormat);
+ av_pix_fmt_get_chroma_sub_sample(srcFormat, &c->chrSrcHSubSample, &c->chrSrcVSubSample);
+ av_pix_fmt_get_chroma_sub_sample(dstFormat, &c->chrDstHSubSample, &c->chrDstVSubSample);
if (isAnyRGB(dstFormat) && !(flags&SWS_FULL_CHR_H_INT)) {
if (dstW&1) {
@@ -1430,8 +1433,11 @@
c->hChrFilter, (uint32_t*)c->hChrFilterPos, 4);
#if USE_MMAP
- mprotect(c->lumMmxextFilterCode, c->lumMmxextFilterCodeSize, PROT_EXEC | PROT_READ);
- mprotect(c->chrMmxextFilterCode, c->chrMmxextFilterCodeSize, PROT_EXEC | PROT_READ);
+ if ( mprotect(c->lumMmxextFilterCode, c->lumMmxextFilterCodeSize, PROT_EXEC | PROT_READ) == -1
+ || mprotect(c->chrMmxextFilterCode, c->chrMmxextFilterCodeSize, PROT_EXEC | PROT_READ) == -1) {
+ av_log(c, AV_LOG_ERROR, "mprotect failed, cannot use fast bilinear scaler\n");
+ goto fail;
+ }
#endif
} else
#endif /* HAVE_MMXEXT_INLINE */
@@ -1571,33 +1577,17 @@
av_assert0(c->chrDstH <= dstH);
if (flags & SWS_PRINT_INFO) {
- const char *scaler, *cpucaps;
- if (flags & SWS_FAST_BILINEAR)
- scaler = "FAST_BILINEAR scaler";
- else if (flags & SWS_BILINEAR)
- scaler = "BILINEAR scaler";
- else if (flags & SWS_BICUBIC)
- scaler = "BICUBIC scaler";
- else if (flags & SWS_X)
- scaler = "Experimental scaler";
- else if (flags & SWS_POINT)
- scaler = "Nearest Neighbor / POINT scaler";
- else if (flags & SWS_AREA)
- scaler = "Area Averaging scaler";
- else if (flags & SWS_BICUBLIN)
- scaler = "luma BICUBIC / chroma BILINEAR scaler";
- else if (flags & SWS_GAUSS)
- scaler = "Gaussian scaler";
- else if (flags & SWS_SINC)
- scaler = "Sinc scaler";
- else if (flags & SWS_LANCZOS)
- scaler = "Lanczos scaler";
- else if (flags & SWS_SPLINE)
- scaler = "Bicubic spline scaler";
- else
- scaler = "ehh flags invalid?!";
+ const char *scaler = NULL, *cpucaps;
- av_log(c, AV_LOG_INFO, "%s, from %s to %s%s ",
+ for (i = 0; i < FF_ARRAY_ELEMS(scale_algorithms); i++) {
+ if (flags & scale_algorithms[i].flag) {
+ scaler = scale_algorithms[i].description;
+ break;
+ }
+ }
+ if (!scaler)
+ scaler = "ehh flags invalid?!";
+ av_log(c, AV_LOG_INFO, "%s scaler, from %s to %s%s ",
scaler,
av_get_pix_fmt_name(srcFormat),
#ifdef DITHER1XBPP
diff --git a/libswscale/x86/rgb2rgb.c b/libswscale/x86/rgb2rgb.c
index 986afc4..8af0bc4 100644
--- a/libswscale/x86/rgb2rgb.c
+++ b/libswscale/x86/rgb2rgb.c
@@ -91,35 +91,44 @@
#define COMPILE_TEMPLATE_MMXEXT 0
#define COMPILE_TEMPLATE_AMD3DNOW 0
#define COMPILE_TEMPLATE_SSE2 0
+#define COMPILE_TEMPLATE_AVX 0
//MMX versions
#undef RENAME
-#define RENAME(a) a ## _MMX
+#define RENAME(a) a ## _mmx
#include "rgb2rgb_template.c"
// MMXEXT versions
#undef RENAME
#undef COMPILE_TEMPLATE_MMXEXT
#define COMPILE_TEMPLATE_MMXEXT 1
-#define RENAME(a) a ## _MMXEXT
+#define RENAME(a) a ## _mmxext
#include "rgb2rgb_template.c"
//SSE2 versions
#undef RENAME
#undef COMPILE_TEMPLATE_SSE2
#define COMPILE_TEMPLATE_SSE2 1
-#define RENAME(a) a ## _SSE2
+#define RENAME(a) a ## _sse2
+#include "rgb2rgb_template.c"
+
+//AVX versions
+#undef RENAME
+#undef COMPILE_TEMPLATE_AVX
+#define COMPILE_TEMPLATE_AVX 1
+#define RENAME(a) a ## _avx
#include "rgb2rgb_template.c"
//3DNOW versions
#undef RENAME
#undef COMPILE_TEMPLATE_MMXEXT
#undef COMPILE_TEMPLATE_SSE2
+#undef COMPILE_TEMPLATE_AVX
#undef COMPILE_TEMPLATE_AMD3DNOW
#define COMPILE_TEMPLATE_MMXEXT 0
#define COMPILE_TEMPLATE_SSE2 0
#define COMPILE_TEMPLATE_AMD3DNOW 1
-#define RENAME(a) a ## _3DNOW
+#define RENAME(a) a ## _3dnow
#include "rgb2rgb_template.c"
/*
@@ -137,12 +146,14 @@
int cpu_flags = av_get_cpu_flags();
if (INLINE_MMX(cpu_flags))
- rgb2rgb_init_MMX();
+ rgb2rgb_init_mmx();
if (INLINE_AMD3DNOW(cpu_flags))
- rgb2rgb_init_3DNOW();
+ rgb2rgb_init_3dnow();
if (INLINE_MMXEXT(cpu_flags))
- rgb2rgb_init_MMXEXT();
+ rgb2rgb_init_mmxext();
if (INLINE_SSE2(cpu_flags))
- rgb2rgb_init_SSE2();
+ rgb2rgb_init_sse2();
+ if (INLINE_AVX(cpu_flags))
+ rgb2rgb_init_avx();
#endif /* HAVE_INLINE_ASM */
}
diff --git a/libswscale/x86/rgb2rgb_template.c b/libswscale/x86/rgb2rgb_template.c
index d684b70..aaea510 100644
--- a/libswscale/x86/rgb2rgb_template.c
+++ b/libswscale/x86/rgb2rgb_template.c
@@ -1854,7 +1854,7 @@
#endif /* HAVE_7REGS */
#endif /* !COMPILE_TEMPLATE_SSE2 */
-#if !COMPILE_TEMPLATE_AMD3DNOW
+#if !COMPILE_TEMPLATE_AMD3DNOW && !COMPILE_TEMPLATE_AVX
static void RENAME(interleaveBytes)(const uint8_t *src1, const uint8_t *src2, uint8_t *dest,
int width, int height, int src1Stride,
int src2Stride, int dstStride)
@@ -1924,6 +1924,32 @@
::: "memory"
);
}
+#endif /* !COMPILE_TEMPLATE_AMD3DNOW && !COMPILE_TEMPLATE_AVX*/
+
+#if !COMPILE_TEMPLATE_AMD3DNOW && (ARCH_X86_32 || COMPILE_TEMPLATE_SSE2) && COMPILE_TEMPLATE_MMXEXT == COMPILE_TEMPLATE_SSE2 && HAVE_YASM
+void RENAME(ff_nv12ToUV)(uint8_t *dstU, uint8_t *dstV,
+ const uint8_t *unused0,
+ const uint8_t *src1,
+ const uint8_t *src2,
+ int w, uint32_t *unused);
+static void RENAME(deinterleaveBytes)(const uint8_t *src, uint8_t *dst1, uint8_t *dst2,
+ int width, int height, int srcStride,
+ int dst1Stride, int dst2Stride)
+{
+ int h;
+
+ for (h=0; h < height; h++) {
+ RENAME(ff_nv12ToUV)(dst1, dst2, NULL, src, NULL, width, NULL);
+ src += srcStride;
+ dst1 += dst1Stride;
+ dst2 += dst2Stride;
+ }
+ __asm__(
+ EMMS" \n\t"
+ SFENCE" \n\t"
+ ::: "memory"
+ );
+}
#endif /* !COMPILE_TEMPLATE_AMD3DNOW */
#if !COMPILE_TEMPLATE_SSE2
@@ -2494,7 +2520,10 @@
uyvytoyuv420 = RENAME(uyvytoyuv420);
#endif /* !COMPILE_TEMPLATE_SSE2 */
-#if !COMPILE_TEMPLATE_AMD3DNOW
+#if !COMPILE_TEMPLATE_AMD3DNOW && !COMPILE_TEMPLATE_AVX
interleaveBytes = RENAME(interleaveBytes);
-#endif /* !COMPILE_TEMPLATE_AMD3DNOW */
+#endif /* !COMPILE_TEMPLATE_AMD3DNOW && !COMPILE_TEMPLATE_AVX*/
+#if !COMPILE_TEMPLATE_AMD3DNOW && (ARCH_X86_32 || COMPILE_TEMPLATE_SSE2) && COMPILE_TEMPLATE_MMXEXT == COMPILE_TEMPLATE_SSE2 && HAVE_YASM
+ deinterleaveBytes = RENAME(deinterleaveBytes);
+#endif
}
diff --git a/libswscale/x86/swscale.c b/libswscale/x86/swscale.c
index a86f9f8..2f7e4f7 100644
--- a/libswscale/x86/swscale.c
+++ b/libswscale/x86/swscale.c
@@ -71,7 +71,7 @@
#if HAVE_MMX_INLINE
#undef RENAME
#define COMPILE_TEMPLATE_MMXEXT 0
-#define RENAME(a) a ## _MMX
+#define RENAME(a) a ## _mmx
#include "swscale_template.c"
#endif
@@ -80,7 +80,7 @@
#undef RENAME
#undef COMPILE_TEMPLATE_MMXEXT
#define COMPILE_TEMPLATE_MMXEXT 1
-#define RENAME(a) a ## _MMXEXT
+#define RENAME(a) a ## _mmxext
#include "swscale_template.c"
#endif
@@ -206,7 +206,7 @@
const uint8_t *dither, int offset)
{
if(((int)dest) & 15){
- return yuv2yuvX_MMXEXT(filter, filterSize, src, dest, dstW, dither, offset);
+ return yuv2yuvX_mmxext(filter, filterSize, src, dest, dstW, dither, offset);
}
if (offset) {
__asm__ volatile("movq (%0), %%xmm3\n\t"
@@ -383,11 +383,11 @@
#if HAVE_MMX_INLINE
if (cpu_flags & AV_CPU_FLAG_MMX)
- sws_init_swscale_MMX(c);
+ sws_init_swscale_mmx(c);
#endif
#if HAVE_MMXEXT_INLINE
if (cpu_flags & AV_CPU_FLAG_MMXEXT)
- sws_init_swscale_MMXEXT(c);
+ sws_init_swscale_mmxext(c);
if (cpu_flags & AV_CPU_FLAG_SSE3){
if(c->use_mmx_vfilter && !(c->flags & SWS_ACCURATE_RND))
c->yuv2planeX = yuv2yuvX_sse3;
diff --git a/libswscale/x86/yuv2rgb.c b/libswscale/x86/yuv2rgb.c
index a54b84a..e4315ef 100644
--- a/libswscale/x86/yuv2rgb.c
+++ b/libswscale/x86/yuv2rgb.c
@@ -53,7 +53,7 @@
#undef RENAME
#undef COMPILE_TEMPLATE_MMXEXT
#define COMPILE_TEMPLATE_MMXEXT 0
-#define RENAME(a) a ## _MMX
+#define RENAME(a) a ## _mmx
#include "yuv2rgb_template.c"
#endif /* HAVE_MMX_INLINE */
@@ -62,7 +62,7 @@
#undef RENAME
#undef COMPILE_TEMPLATE_MMXEXT
#define COMPILE_TEMPLATE_MMXEXT 1
-#define RENAME(a) a ## _MMXEXT
+#define RENAME(a) a ## _mmxext
#include "yuv2rgb_template.c"
#endif /* HAVE_MMXEXT_INLINE */
@@ -77,9 +77,9 @@
if (cpu_flags & AV_CPU_FLAG_MMXEXT) {
switch (c->dstFormat) {
case AV_PIX_FMT_RGB24:
- return yuv420_rgb24_MMXEXT;
+ return yuv420_rgb24_mmxext;
case AV_PIX_FMT_BGR24:
- return yuv420_bgr24_MMXEXT;
+ return yuv420_bgr24_mmxext;
}
}
#endif
@@ -89,21 +89,27 @@
case AV_PIX_FMT_RGB32:
if (c->srcFormat == AV_PIX_FMT_YUVA420P) {
#if HAVE_7REGS && CONFIG_SWSCALE_ALPHA
- return yuva420_rgb32_MMX;
+ return yuva420_rgb32_mmx;
#endif
break;
- } else return yuv420_rgb32_MMX;
+ } else
+ return yuv420_rgb32_mmx;
case AV_PIX_FMT_BGR32:
if (c->srcFormat == AV_PIX_FMT_YUVA420P) {
#if HAVE_7REGS && CONFIG_SWSCALE_ALPHA
- return yuva420_bgr32_MMX;
+ return yuva420_bgr32_mmx;
#endif
break;
- } else return yuv420_bgr32_MMX;
- case AV_PIX_FMT_RGB24: return yuv420_rgb24_MMX;
- case AV_PIX_FMT_BGR24: return yuv420_bgr24_MMX;
- case AV_PIX_FMT_RGB565: return yuv420_rgb16_MMX;
- case AV_PIX_FMT_RGB555: return yuv420_rgb15_MMX;
+ } else
+ return yuv420_bgr32_mmx;
+ case AV_PIX_FMT_RGB24:
+ return yuv420_rgb24_mmx;
+ case AV_PIX_FMT_BGR24:
+ return yuv420_bgr24_mmx;
+ case AV_PIX_FMT_RGB565:
+ return yuv420_rgb16_mmx;
+ case AV_PIX_FMT_RGB555:
+ return yuv420_rgb15_mmx;
}
}
#endif /* HAVE_MMX_INLINE */
diff --git a/libswscale/yuv2rgb.c b/libswscale/yuv2rgb.c
index c0263cd..77c56a9 100644
--- a/libswscale/yuv2rgb.c
+++ b/libswscale/yuv2rgb.c
@@ -768,10 +768,10 @@
c->yuv2rgb_u2b_coeff = (int16_t)roundToInt16(cbu << 13);
//scale coefficients by cy
- crv = ((crv << 16) + 0x8000) / cy;
- cbu = ((cbu << 16) + 0x8000) / cy;
- cgu = ((cgu << 16) + 0x8000) / cy;
- cgv = ((cgv << 16) + 0x8000) / cy;
+ crv = ((crv << 16) + 0x8000) / FFMAX(cy, 1);
+ cbu = ((cbu << 16) + 0x8000) / FFMAX(cy, 1);
+ cgu = ((cgu << 16) + 0x8000) / FFMAX(cy, 1);
+ cgv = ((cgv << 16) + 0x8000) / FFMAX(cy, 1);
av_freep(&c->yuvTable);
diff --git a/tests/Makefile b/tests/Makefile
index 20a25dd..6f128e8 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -102,6 +102,7 @@
include $(SRC_PATH)/tests/fate/fft.mak
include $(SRC_PATH)/tests/fate/gif.mak
include $(SRC_PATH)/tests/fate/h264.mak
+include $(SRC_PATH)/tests/fate/hevc.mak
include $(SRC_PATH)/tests/fate/image.mak
include $(SRC_PATH)/tests/fate/indeo.mak
include $(SRC_PATH)/tests/fate/libavcodec.mak
@@ -109,6 +110,7 @@
include $(SRC_PATH)/tests/fate/libavformat.mak
include $(SRC_PATH)/tests/fate/libavresample.mak
include $(SRC_PATH)/tests/fate/libavutil.mak
+include $(SRC_PATH)/tests/fate/libswresample.mak
include $(SRC_PATH)/tests/fate/lossless-audio.mak
include $(SRC_PATH)/tests/fate/lossless-video.mak
include $(SRC_PATH)/tests/fate/microsoft.mak
diff --git a/tests/fate-run.sh b/tests/fate-run.sh
index 52ddc22..48e9dd0 100755
--- a/tests/fate-run.sh
+++ b/tests/fate-run.sh
@@ -90,11 +90,11 @@
}
framecrc(){
- ffmpeg "$@" -f framecrc -
+ ffmpeg "$@" -flags +bitexact -f framecrc -
}
framemd5(){
- ffmpeg "$@" -f framemd5 -
+ ffmpeg "$@" -flags +bitexact -f framemd5 -
}
crc(){
diff --git a/tests/fate.sh b/tests/fate.sh
index c474be7..f371291 100755
--- a/tests/fate.sh
+++ b/tests/fate.sh
@@ -35,7 +35,7 @@
update()(
cd ${src} || return
case "$repo" in
- git:*) git pull --quiet ;;
+ git:*) git fetch --force && git reset --hard FETCH_HEAD ;;
esac
)
diff --git a/tests/fate/aac.mak b/tests/fate/aac.mak
index 304661b..b85a8e8 100644
--- a/tests/fate/aac.mak
+++ b/tests/fate/aac.mak
@@ -50,6 +50,15 @@
fate-aac-ap05_48: CMD = pcm -i $(TARGET_SAMPLES)/aac/ap05_48.mp4
fate-aac-ap05_48: REF = $(SAMPLES)/aac/ap05_48.s16
+FATE_AAC += fate-aac-er_ad6000np_44_ep0
+fate-aac-er_ad6000np_44_ep0: CMD = pcm -i $(TARGET_SAMPLES)/aac/er_ad6000np_44_ep0.mp4
+fate-aac-er_ad6000np_44_ep0: REF = $(SAMPLES)/aac/er_ad6000np_44_ep0.s16
+
+FATE_AAC += fate-aac-er_eld2000np_48_ep0
+fate-aac-er_eld2000np_48_ep0: CMD = pcm -i $(TARGET_SAMPLES)/aac/er_eld2000np_48_ep0.mp4
+fate-aac-er_eld2000np_48_ep0: REF = $(SAMPLES)/aac/er_eld2000np_48_ep0.s16
+
+
fate-aac-ct%: CMD = pcm -i $(TARGET_SAMPLES)/aac/CT_DecoderCheck/$(@:fate-aac-ct-%=%)
fate-aac-ct%: REF = $(SAMPLES)/aac/CT_DecoderCheck/aacPlusv2.wav
diff --git a/tests/fate/acodec.mak b/tests/fate/acodec.mak
index 78508bc..10d4392 100644
--- a/tests/fate/acodec.mak
+++ b/tests/fate/acodec.mak
@@ -68,6 +68,10 @@
fate-acodec-mp2: FMT = mp2
fate-acodec-mp2: CMP_SHIFT = -1924
+FATE_ACODEC-$(call ENCDEC, MP2FIXED MP2 , MP2 MP3) += fate-acodec-mp2fixed
+fate-acodec-mp2fixed: FMT = mp2
+fate-acodec-mp2fixed: CMP_SHIFT = -1924
+
FATE_ACODEC-$(call ENCDEC, ALAC, MOV) += fate-acodec-alac
fate-acodec-alac: FMT = mov
fate-acodec-alac: CODEC = alac -compression_level 1
diff --git a/tests/fate/cover-art.mak b/tests/fate/cover-art.mak
index a40fc55..721c650 100644
--- a/tests/fate/cover-art.mak
+++ b/tests/fate/cover-art.mak
@@ -10,6 +10,10 @@
fate-cover-art-m4a: CMD = md5 -i $(TARGET_SAMPLES)/cover_art/Owner-iTunes_9.0.3.15.m4a -an -c:v copy -f rawvideo
fate-cover-art-m4a: REF = 08ba70a3b594ff6345a93965e96a9d3e
+FATE_COVER_ART-$(CONFIG_OGG_DEMUXER) += fate-cover-art-ogg
+fate-cover-art-ogg: CMD = md5 -i $(TARGET_SAMPLES)/cover_art/ogg_vorbiscomment_cover.opus -map 0:v -c:v copy -f rawvideo
+fate-cover-art-ogg: REF = 7f117e073620eabb4ed02680cf70af41
+
FATE_COVER_ART-$(CONFIG_ASF_DEMUXER) += fate-cover-art-wma
fate-cover-art-wma: CMD = md5 -i $(TARGET_SAMPLES)/cover_art/Californication_cover.wma -an -c:v copy -f rawvideo
fate-cover-art-wma: REF = 0808bd0e1b61542a16e1906812dd924b
@@ -26,10 +30,6 @@
fate-cover-art-wv: CMD = md5 -i $(TARGET_SAMPLES)/cover_art/luckynight_cover.wv -an -c:v copy -f rawvideo
fate-cover-art-wv: REF = 45333c983c45af54449dff10af144317
-FATE_COVER_ART-$(CONFIG_OGG_DEMUXER) += fate-cover-art-ogg
-fate-cover-art-ogg: CMD = md5 -i $(TARGET_SAMPLES)/cover_art/ogg_vorbiscomment_cover.opus -map 0:v -c:v copy -f rawvideo
-fate-cover-art-ogg: REF = 7f117e073620eabb4ed02680cf70af41
-
FCA_TEMP-$(call ALLYES, RAWVIDEO_MUXER FILE_PROTOCOL) = $(FATE_COVER_ART-yes)
FATE_COVER_ART = $(FCA_TEMP-yes)
diff --git a/tests/fate/filter-video.mak b/tests/fate/filter-video.mak
index 6d99ef2..2d9ad13 100644
--- a/tests/fate/filter-video.mak
+++ b/tests/fate/filter-video.mak
@@ -41,6 +41,9 @@
FATE_FILTER_VSYNTH-$(CONFIG_FADE_FILTER) += fate-filter-fade
fate-filter-fade: CMD = framecrc -c:v pgmyuv -i $(SRC) -vf fade=in:5:15,fade=out:30:15
+FATE_FILTER_VSYNTH-$(call ALLYES, INTERLACE_FILTER FIELDORDER_FILTER) += fate-filter-fieldorder
+fate-filter-fieldorder: CMD = framecrc -c:v pgmyuv -i $(SRC) -vf interlace=tff,fieldorder=bff -sws_flags +accurate_rnd+bitexact
+
FATE_FILTER_VSYNTH-$(CONFIG_GRADFUN_FILTER) += fate-filter-gradfun
fate-filter-gradfun: CMD = framecrc -c:v pgmyuv -i $(SRC) -vf gradfun
@@ -78,6 +81,10 @@
FATE_FILTER_VSYNTH-$(CONFIG_SEPARATEFIELDS_FILTER) += fate-filter-separatefields
fate-filter-separatefields: CMD = framecrc -c:v pgmyuv -i $(SRC) -vf separatefields
+FATE_FILTER_VSYNTH-$(CONFIG_SELECT_FILTER) += fate-filter-select-alternate
+fate-filter-select-alternate: tests/data/filtergraphs/select-alternate
+fate-filter-select-alternate: CMD = framecrc -c:v pgmyuv -i $(SRC) -filter_script $(TARGET_PATH)/tests/data/filtergraphs/select-alternate
+
FATE_FILTER_VSYNTH-$(call ALLYES, SETPTS_FILTER SETTB_FILTER) += fate-filter-setpts
fate-filter-setpts: tests/data/filtergraphs/setpts
fate-filter-setpts: CMD = framecrc -c:v pgmyuv -i $(SRC) -filter_script $(TARGET_PATH)/tests/data/filtergraphs/setpts
diff --git a/tests/fate/hevc.mak b/tests/fate/hevc.mak
new file mode 100644
index 0000000..e15497d
--- /dev/null
+++ b/tests/fate/hevc.mak
@@ -0,0 +1,156 @@
+HEVC_SAMPLES = \
+ AMP_A_Samsung_4 \
+ AMP_B_Samsung_4 \
+ AMVP_C_Samsung_4 \
+ AMP_D_Hisilicon \
+ AMP_E_Hisilicon \
+ AMP_F_Hisilicon_3 \
+ AMVP_A_MTK_4 \
+ AMVP_B_MTK_4 \
+ CAINIT_A_SHARP_4 \
+ CAINIT_B_SHARP_4 \
+ CAINIT_C_SHARP_3 \
+ CAINIT_D_SHARP_3 \
+ CAINIT_E_SHARP_3 \
+ CAINIT_F_SHARP_3 \
+ CAINIT_G_SHARP_3 \
+ CAINIT_H_SHARP_3 \
+ CIP_A_Panasonic_3 \
+ cip_B_NEC_2 \
+ CIP_C_Panasonic_2 \
+ DBLK_A_SONY_3 \
+ DBLK_B_SONY_3 \
+ DBLK_C_SONY_3 \
+ DBLK_D_VIXS_1 \
+ DBLK_D_VIXS_2 \
+ DBLK_E_VIXS_1 \
+ DBLK_E_VIXS_2 \
+ DBLK_F_VIXS_1 \
+ DBLK_F_VIXS_2 \
+ DBLK_G_VIXS_1 \
+ DBLK_G_VIXS_2 \
+ DELTAQP_B_SONY_3 \
+ DELTAQP_C_SONY_3 \
+ DSLICE_A_HHI_5 \
+ DSLICE_B_HHI_5 \
+ DSLICE_C_HHI_5 \
+ ENTP_A_LG_2 \
+ ENTP_B_LG_2 \
+ ENTP_C_LG_3 \
+ EXT_A_ericsson_3 \
+ ipcm_A_NEC_2 \
+ ipcm_B_NEC_2 \
+ ipcm_C_NEC_2 \
+ ipcm_D_NEC_2 \
+ IPRED_A_docomo_2 \
+ IPRED_B_Nokia_3 \
+ IPRED_C_Mitsubishi_2 \
+ LS_A_Orange_2 \
+ LS_B_ORANGE_3 \
+ MAXBINS_A_TI_4 \
+ MAXBINS_B_TI_4 \
+ MAXBINS_C_TI_4 \
+ MERGE_A_TI_3 \
+ MERGE_B_TI_3 \
+ MERGE_C_TI_3 \
+ MERGE_D_TI_3 \
+ MERGE_E_TI_3 \
+ MERGE_F_MTK_4 \
+ MERGE_G_HHI_4 \
+ MVCLIP_A_qualcomm_3 \
+ MVDL1ZERO_A_docomo_3 \
+ MVEDGE_A_qualcomm_3 \
+ NUT_A_ericsson_4 \
+ PICSIZE_A_Bossen_1 \
+ PICSIZE_B_Bossen_1 \
+ PICSIZE_C_Bossen_1 \
+ PICSIZE_D_Bossen_1 \
+ PMERGE_A_TI_3 \
+ PMERGE_B_TI_3 \
+ PMERGE_C_TI_3 \
+ PMERGE_D_TI_3 \
+ PMERGE_E_TI_3 \
+ POC_A_Bossen_3 \
+ PPS_A_qualcomm_7 \
+ RAP_A_docomo_4 \
+ PS_A_VIDYO_3 \
+ PS_B_VIDYO_3 \
+ RAP_B_Bossen_1 \
+ RPLM_A_qualcomm_4 \
+ RPLM_B_qualcomm_4 \
+ RPS_A_docomo_4 \
+ RPS_B_qualcomm_5 \
+ RPS_C_ericsson_4 \
+ RPS_D_ericsson_5 \
+ RPS_E_qualcomm_5 \
+ RQT_A_HHI_4 \
+ RQT_B_HHI_4 \
+ RQT_C_HHI_4 \
+ RQT_D_HHI_4 \
+ RQT_E_HHI_4 \
+ RQT_F_HHI_4 \
+ RQT_G_HHI_4 \
+ SAO_A_MediaTek_4 \
+ SAO_B_MediaTek_5 \
+ SAO_C_Samsung_4 \
+ SAO_D_Samsung_4 \
+ SAO_E_Canon_4 \
+ SAO_F_Canon_3 \
+ SAO_G_Canon_3 \
+ SDH_A_Orange_3 \
+ SLICES_A_Rovi_3 \
+ SLIST_A_Sony_4 \
+ SLIST_B_Sony_8 \
+ SLIST_C_Sony_3 \
+ SLIST_D_Sony_9 \
+ STRUCT_A_Samsung_5 \
+ STRUCT_B_Samsung_4 \
+ TILES_A_Cisco_2 \
+ TILES_B_Cisco_1 \
+ TMVP_A_MS_2 \
+ TSCL_A_VIDYO_5 \
+ TSCL_B_VIDYO_4 \
+ TSKIP_A_MS_2 \
+ WP_A_Toshiba_3 \
+ WP_B_Toshiba_3 \
+ WPP_A_ericsson_MAIN_2 \
+ WPP_B_ericsson_MAIN_2 \
+ WPP_C_ericsson_MAIN_2 \
+ WPP_D_ericsson_MAIN_2 \
+ WPP_E_ericsson_MAIN_2 \
+ WPP_F_ericsson_MAIN_2 \
+
+HEVC_SAMPLES_10BIT = \
+ DBLK_A_MAIN10_VIXS_2 \
+ WP_A_MAIN10_Toshiba_3 \
+ WP_MAIN10_B_Toshiba_3 \
+ WPP_A_ericsson_MAIN10_2 \
+ WPP_B_ericsson_MAIN10_2 \
+ WPP_C_ericsson_MAIN10_2 \
+ WPP_D_ericsson_MAIN10_2 \
+ WPP_E_ericsson_MAIN10_2 \
+ WPP_F_ericsson_MAIN10_2 \
+
+# do not pass:
+# DELTAQP_A_BRCM_4.bit -- TODO uses CRC instead of MD5
+# HRD_A_Fujitsu_2.bin -- TODO uses hash 2 ("checksum")
+# TSUNEQBD_A_MAIN10_Technicolor_2.bit (segfault)
+
+define FATE_HEVC_TEST
+FATE_HEVC += fate-hevc-conformance-$(1)
+fate-hevc-conformance-$(1): CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/hevc-conformance/$(1).bit
+endef
+
+define FATE_HEVC_TEST_10BIT
+FATE_HEVC += fate-hevc-conformance-$(1)
+fate-hevc-conformance-$(1): CMD = framecrc -vsync drop -i $(TARGET_SAMPLES)/hevc-conformance/$(1).bit -pix_fmt yuv420p10le
+endef
+
+$(foreach N,$(HEVC_SAMPLES),$(eval $(call FATE_HEVC_TEST,$(N))))
+$(foreach N,$(HEVC_SAMPLES_10BIT),$(eval $(call FATE_HEVC_TEST_10BIT,$(N))))
+
+FATE_HEVC-$(call DEMDEC, HEVC, HEVC) += $(FATE_HEVC)
+
+FATE_SAMPLES_AVCONV += $(FATE_HEVC-yes)
+
+fate-hevc: $(FATE_HEVC-yes)
diff --git a/tests/fate/libavresample.mak b/tests/fate/libavresample.mak
index d7dd2ce..d7c856b 100644
--- a/tests/fate/libavresample.mak
+++ b/tests/fate/libavresample.mak
@@ -1,7 +1,7 @@
CROSS_TEST = $(foreach I,$(1), \
$(foreach J,$(1), \
$(if $(filter-out $(I),$(J)), \
- $(eval $(call $(2),$(I),$(J),$(3),$(4))), \
+ $(eval $(call $(2),$(I),$(J),$(3),$(4),$(5))), \
)))
MIX_CHANNELS = 1 2 3 4 5 6 7 8
@@ -29,13 +29,15 @@
fate-lavr-resample-$(3)-$(1)-$(2): tests/data/asynth-$(1)-1.wav
fate-lavr-resample-$(3)-$(1)-$(2): CMD = ffmpeg -i $(TARGET_PATH)/tests/data/asynth-$(1)-1.wav -ar $(2) -internal_sample_fmt $(3) -f $(4) -af atrim=end_sample=10240 -
fate-lavr-resample-$(3)-$(1)-$(2): CMP = oneoff
+fate-lavr-resample-$(3)-$(1)-$(2): CMP_UNIT = $(5)
+fate-lavr-resample-$(3)-$(1)-$(2): FUZZ = 6
fate-lavr-resample-$(3)-$(1)-$(2): REF = $(SAMPLES)/lavr/lavr-resample-$(3)-$(1)-$(2)
endef
-$(call CROSS_TEST,$(SAMPLERATES),RESAMPLE,s16p,s16le)
-$(call CROSS_TEST,$(SAMPLERATES),RESAMPLE,s32p,s32le)
-$(call CROSS_TEST,$(SAMPLERATES),RESAMPLE,fltp,f32le)
-$(call CROSS_TEST,$(SAMPLERATES),RESAMPLE,dblp,f64le)
+$(call CROSS_TEST,$(SAMPLERATES),RESAMPLE,s16p,s16le,s16)
+$(call CROSS_TEST,$(SAMPLERATES),RESAMPLE,s32p,s32le,s16)
+$(call CROSS_TEST,$(SAMPLERATES),RESAMPLE,fltp,f32le,f32)
+$(call CROSS_TEST,$(SAMPLERATES),RESAMPLE,dblp,f64le,f64)
FATE_LAVR_RESAMPLE-$(call FILTERDEMDECENCMUX, RESAMPLE, WAV, PCM_S16LE, PCM_S16LE, WAV) += $(FATE_LAVR_RESAMPLE)
fate-lavr-resample: $(FATE_LAVR_RESAMPLE-yes)
diff --git a/tests/fate/libswresample.mak b/tests/fate/libswresample.mak
new file mode 100644
index 0000000..dd47de9
--- /dev/null
+++ b/tests/fate/libswresample.mak
@@ -0,0 +1,276 @@
+CROSS_TEST = $(foreach I,$(1), \
+ $(foreach J,$(1), \
+ $(if $(filter-out $(I),$(J)), \
+ $(eval $(call $(2),$(I),$(J),$(3),$(4),$(5))), \
+ )))
+
+
+SAMPLERATES = 2626 8000 44100 48000 96000
+
+define ARESAMPLE
+FATE_SWR_RESAMPLE += fate-swr-resample-$(3)-$(1)-$(2)
+fate-swr-resample-$(3)-$(1)-$(2): tests/data/asynth-$(1)-1.wav
+fate-swr-resample-$(3)-$(1)-$(2): CMD = ffmpeg -i $(TARGET_PATH)/tests/data/asynth-$(1)-1.wav -af atrim=end_sample=10240,aresample=$(2):internal_sample_fmt=$(3),aformat=$(3),aresample=$(1):internal_sample_fmt=$(3) -f wav -acodec pcm_s16le -
+
+fate-swr-resample-$(3)-$(1)-$(2): CMP = stddev
+fate-swr-resample-$(3)-$(1)-$(2): CMP_UNIT = $(5)
+fate-swr-resample-$(3)-$(1)-$(2): FUZZ = 0.1
+fate-swr-resample-$(3)-$(1)-$(2): REF = tests/data/asynth-$(1)-1.wav
+
+#below list is generated by:
+#you can use this if you need to update it!
+#make -k `make fate-list | grep swr` | egrep 'TEST|stddev' | tr '\n' '@' | sed 's#TEST *\([^@]*\)@stddev: *\([0-9.]*\)[^b@]*bytes: *\([0-9]*\) */ *\([0-9]*\)@#fate-\1: CMP_TARGET = \2@fate-\1: SIZE_TOLERANCE = \3 - \4@@#g' | tr '@' '\n'
+
+fate-swr-resample-dblp-2626-44100: CMP_TARGET = 1393.01
+fate-swr-resample-dblp-2626-44100: SIZE_TOLERANCE = 31512 - 20480
+
+fate-swr-resample-dblp-2626-48000: CMP_TARGET = 1393.01
+fate-swr-resample-dblp-2626-48000: SIZE_TOLERANCE = 31512 - 20480
+
+fate-swr-resample-dblp-2626-8000: CMP_TARGET = 1393.90
+fate-swr-resample-dblp-2626-8000: SIZE_TOLERANCE = 31512 - 20482
+
+fate-swr-resample-dblp-2626-96000: CMP_TARGET = 1393.01
+fate-swr-resample-dblp-2626-96000: SIZE_TOLERANCE = 31512 - 20480
+
+fate-swr-resample-dblp-44100-2626: CMP_TARGET = 185.84
+fate-swr-resample-dblp-44100-2626: SIZE_TOLERANCE = 529200 - 20490
+
+fate-swr-resample-dblp-44100-48000: CMP_TARGET = 9.70
+fate-swr-resample-dblp-44100-48000: SIZE_TOLERANCE = 529200 - 20482
+
+fate-swr-resample-dblp-44100-8000: CMP_TARGET = 75.46
+fate-swr-resample-dblp-44100-8000: SIZE_TOLERANCE = 529200 - 20486
+
+fate-swr-resample-dblp-44100-96000: CMP_TARGET = 11.47
+fate-swr-resample-dblp-44100-96000: SIZE_TOLERANCE = 529200 - 20482
+
+fate-swr-resample-dblp-48000-2626: CMP_TARGET = 456.55
+fate-swr-resample-dblp-48000-2626: SIZE_TOLERANCE = 576000 - 20510
+
+fate-swr-resample-dblp-48000-44100: CMP_TARGET = 1.16
+fate-swr-resample-dblp-48000-44100: SIZE_TOLERANCE = 576000 - 20480
+
+fate-swr-resample-dblp-48000-8000: CMP_TARGET = 62.41
+fate-swr-resample-dblp-48000-8000: SIZE_TOLERANCE = 576000 - 20484
+
+fate-swr-resample-dblp-48000-96000: CMP_TARGET = 0.47
+fate-swr-resample-dblp-48000-96000: SIZE_TOLERANCE = 576000 - 20480
+
+fate-swr-resample-dblp-8000-2626: CMP_TARGET = 2506.01
+fate-swr-resample-dblp-8000-2626: SIZE_TOLERANCE = 96000 - 20486
+
+fate-swr-resample-dblp-8000-44100: CMP_TARGET = 15.09
+fate-swr-resample-dblp-8000-44100: SIZE_TOLERANCE = 96000 - 20480
+
+fate-swr-resample-dblp-8000-48000: CMP_TARGET = 14.68
+fate-swr-resample-dblp-8000-48000: SIZE_TOLERANCE = 96000 - 20480
+
+fate-swr-resample-dblp-8000-96000: CMP_TARGET = 13.82
+fate-swr-resample-dblp-8000-96000: SIZE_TOLERANCE = 96000 - 20480
+
+fate-swr-resample-dblp-96000-2626: CMP_TARGET = 675.14
+fate-swr-resample-dblp-96000-2626: SIZE_TOLERANCE = 1152000 - 20474
+
+fate-swr-resample-dblp-96000-44100: CMP_TARGET = 1.58
+fate-swr-resample-dblp-96000-44100: SIZE_TOLERANCE = 1152000 - 20480
+
+fate-swr-resample-dblp-96000-48000: CMP_TARGET = 1.04
+fate-swr-resample-dblp-96000-48000: SIZE_TOLERANCE = 1152000 - 20480
+
+fate-swr-resample-dblp-96000-8000: CMP_TARGET = 58.60
+fate-swr-resample-dblp-96000-8000: SIZE_TOLERANCE = 1152000 - 20496
+
+fate-swr-resample-fltp-2626-44100: CMP_TARGET = 1393.01
+fate-swr-resample-fltp-2626-44100: SIZE_TOLERANCE = 31512 - 20480
+
+fate-swr-resample-fltp-2626-48000: CMP_TARGET = 1393.01
+fate-swr-resample-fltp-2626-48000: SIZE_TOLERANCE = 31512 - 20480
+
+fate-swr-resample-fltp-2626-8000: CMP_TARGET = 1393.90
+fate-swr-resample-fltp-2626-8000: SIZE_TOLERANCE = 31512 - 20482
+
+fate-swr-resample-fltp-2626-96000: CMP_TARGET = 1393.01
+fate-swr-resample-fltp-2626-96000: SIZE_TOLERANCE = 31512 - 20480
+
+fate-swr-resample-fltp-44100-2626: CMP_TARGET = 185.84
+fate-swr-resample-fltp-44100-2626: SIZE_TOLERANCE = 529200 - 20490
+
+fate-swr-resample-fltp-44100-48000: CMP_TARGET = 9.70
+fate-swr-resample-fltp-44100-48000: SIZE_TOLERANCE = 529200 - 20482
+
+fate-swr-resample-fltp-44100-8000: CMP_TARGET = 75.46
+fate-swr-resample-fltp-44100-8000: SIZE_TOLERANCE = 529200 - 20486
+
+fate-swr-resample-fltp-44100-96000: CMP_TARGET = 11.47
+fate-swr-resample-fltp-44100-96000: SIZE_TOLERANCE = 529200 - 20482
+
+fate-swr-resample-fltp-48000-2626: CMP_TARGET = 456.55
+fate-swr-resample-fltp-48000-2626: SIZE_TOLERANCE = 576000 - 20510
+
+fate-swr-resample-fltp-48000-44100: CMP_TARGET = 1.16
+fate-swr-resample-fltp-48000-44100: SIZE_TOLERANCE = 576000 - 20480
+
+fate-swr-resample-fltp-48000-8000: CMP_TARGET = 62.41
+fate-swr-resample-fltp-48000-8000: SIZE_TOLERANCE = 576000 - 20484
+
+fate-swr-resample-fltp-48000-96000: CMP_TARGET = 0.47
+fate-swr-resample-fltp-48000-96000: SIZE_TOLERANCE = 576000 - 20480
+
+fate-swr-resample-fltp-8000-2626: CMP_TARGET = 2506.01
+fate-swr-resample-fltp-8000-2626: SIZE_TOLERANCE = 96000 - 20486
+
+fate-swr-resample-fltp-8000-44100: CMP_TARGET = 15.09
+fate-swr-resample-fltp-8000-44100: SIZE_TOLERANCE = 96000 - 20480
+
+fate-swr-resample-fltp-8000-48000: CMP_TARGET = 14.68
+fate-swr-resample-fltp-8000-48000: SIZE_TOLERANCE = 96000 - 20480
+
+fate-swr-resample-fltp-8000-96000: CMP_TARGET = 13.82
+fate-swr-resample-fltp-8000-96000: SIZE_TOLERANCE = 96000 - 20480
+
+fate-swr-resample-fltp-96000-2626: CMP_TARGET = 675.14
+fate-swr-resample-fltp-96000-2626: SIZE_TOLERANCE = 1152000 - 20474
+
+fate-swr-resample-fltp-96000-44100: CMP_TARGET = 1.58
+fate-swr-resample-fltp-96000-44100: SIZE_TOLERANCE = 1152000 - 20480
+
+fate-swr-resample-fltp-96000-48000: CMP_TARGET = 1.04
+fate-swr-resample-fltp-96000-48000: SIZE_TOLERANCE = 1152000 - 20480
+
+fate-swr-resample-fltp-96000-8000: CMP_TARGET = 58.60
+fate-swr-resample-fltp-96000-8000: SIZE_TOLERANCE = 1152000 - 20496
+
+fate-swr-resample-s16p-2626-44100: CMP_TARGET = 1393.01
+fate-swr-resample-s16p-2626-44100: SIZE_TOLERANCE = 31512 - 20480
+
+fate-swr-resample-s16p-2626-48000: CMP_TARGET = 1392.99
+fate-swr-resample-s16p-2626-48000: SIZE_TOLERANCE = 31512 - 20480
+
+fate-swr-resample-s16p-2626-8000: CMP_TARGET = 1393.90
+fate-swr-resample-s16p-2626-8000: SIZE_TOLERANCE = 31512 - 20482
+
+fate-swr-resample-s16p-2626-96000: CMP_TARGET = 1393.08
+fate-swr-resample-s16p-2626-96000: SIZE_TOLERANCE = 31512 - 20480
+
+fate-swr-resample-s16p-44100-2626: CMP_TARGET = 185.84
+fate-swr-resample-s16p-44100-2626: SIZE_TOLERANCE = 529200 - 20490
+
+fate-swr-resample-s16p-44100-48000: CMP_TARGET = 9.71
+fate-swr-resample-s16p-44100-48000: SIZE_TOLERANCE = 529200 - 20482
+
+fate-swr-resample-s16p-44100-8000: CMP_TARGET = 75.46
+fate-swr-resample-s16p-44100-8000: SIZE_TOLERANCE = 529200 - 20486
+
+fate-swr-resample-s16p-44100-96000: CMP_TARGET = 11.48
+fate-swr-resample-s16p-44100-96000: SIZE_TOLERANCE = 529200 - 20482
+
+fate-swr-resample-s16p-48000-2626: CMP_TARGET = 456.55
+fate-swr-resample-s16p-48000-2626: SIZE_TOLERANCE = 576000 - 20510
+
+fate-swr-resample-s16p-48000-44100: CMP_TARGET = 1.22
+fate-swr-resample-s16p-48000-44100: SIZE_TOLERANCE = 576000 - 20480
+
+fate-swr-resample-s16p-48000-8000: CMP_TARGET = 62.41
+fate-swr-resample-s16p-48000-8000: SIZE_TOLERANCE = 576000 - 20484
+
+fate-swr-resample-s16p-48000-96000: CMP_TARGET = 0.50
+fate-swr-resample-s16p-48000-96000: SIZE_TOLERANCE = 576000 - 20480
+
+fate-swr-resample-s16p-8000-2626: CMP_TARGET = 2506.02
+fate-swr-resample-s16p-8000-2626: SIZE_TOLERANCE = 96000 - 20486
+
+fate-swr-resample-s16p-8000-44100: CMP_TARGET = 15.12
+fate-swr-resample-s16p-8000-44100: SIZE_TOLERANCE = 96000 - 20480
+
+fate-swr-resample-s16p-8000-48000: CMP_TARGET = 14.69
+fate-swr-resample-s16p-8000-48000: SIZE_TOLERANCE = 96000 - 20480
+
+fate-swr-resample-s16p-8000-96000: CMP_TARGET = 13.83
+fate-swr-resample-s16p-8000-96000: SIZE_TOLERANCE = 96000 - 20480
+
+fate-swr-resample-s16p-96000-2626: CMP_TARGET = 675.14
+fate-swr-resample-s16p-96000-2626: SIZE_TOLERANCE = 1152000 - 20474
+
+fate-swr-resample-s16p-96000-44100: CMP_TARGET = 1.62
+fate-swr-resample-s16p-96000-44100: SIZE_TOLERANCE = 1152000 - 20480
+
+fate-swr-resample-s16p-96000-48000: CMP_TARGET = 1.03
+fate-swr-resample-s16p-96000-48000: SIZE_TOLERANCE = 1152000 - 20480
+
+fate-swr-resample-s16p-96000-8000: CMP_TARGET = 58.60
+fate-swr-resample-s16p-96000-8000: SIZE_TOLERANCE = 1152000 - 20496
+
+fate-swr-resample-s32p-2626-44100: CMP_TARGET = 1393.01
+fate-swr-resample-s32p-2626-44100: SIZE_TOLERANCE = 31512 - 20480
+
+fate-swr-resample-s32p-2626-48000: CMP_TARGET = 1393.01
+fate-swr-resample-s32p-2626-48000: SIZE_TOLERANCE = 31512 - 20480
+
+fate-swr-resample-s32p-2626-8000: CMP_TARGET = 1393.90
+fate-swr-resample-s32p-2626-8000: SIZE_TOLERANCE = 31512 - 20482
+
+fate-swr-resample-s32p-2626-96000: CMP_TARGET = 1393.01
+fate-swr-resample-s32p-2626-96000: SIZE_TOLERANCE = 31512 - 20480
+
+fate-swr-resample-s32p-44100-2626: CMP_TARGET = 185.84
+fate-swr-resample-s32p-44100-2626: SIZE_TOLERANCE = 529200 - 20490
+
+fate-swr-resample-s32p-44100-48000: CMP_TARGET = 9.70
+fate-swr-resample-s32p-44100-48000: SIZE_TOLERANCE = 529200 - 20482
+
+fate-swr-resample-s32p-44100-8000: CMP_TARGET = 75.46
+fate-swr-resample-s32p-44100-8000: SIZE_TOLERANCE = 529200 - 20486
+
+fate-swr-resample-s32p-44100-96000: CMP_TARGET = 11.47
+fate-swr-resample-s32p-44100-96000: SIZE_TOLERANCE = 529200 - 20482
+
+fate-swr-resample-s32p-48000-2626: CMP_TARGET = 456.55
+fate-swr-resample-s32p-48000-2626: SIZE_TOLERANCE = 576000 - 20510
+
+fate-swr-resample-s32p-48000-44100: CMP_TARGET = 1.16
+fate-swr-resample-s32p-48000-44100: SIZE_TOLERANCE = 576000 - 20480
+
+fate-swr-resample-s32p-48000-8000: CMP_TARGET = 62.41
+fate-swr-resample-s32p-48000-8000: SIZE_TOLERANCE = 576000 - 20484
+
+fate-swr-resample-s32p-48000-96000: CMP_TARGET = 0.47
+fate-swr-resample-s32p-48000-96000: SIZE_TOLERANCE = 576000 - 20480
+
+fate-swr-resample-s32p-8000-2626: CMP_TARGET = 2506.01
+fate-swr-resample-s32p-8000-2626: SIZE_TOLERANCE = 96000 - 20486
+
+fate-swr-resample-s32p-8000-44100: CMP_TARGET = 15.09
+fate-swr-resample-s32p-8000-44100: SIZE_TOLERANCE = 96000 - 20480
+
+fate-swr-resample-s32p-8000-48000: CMP_TARGET = 14.68
+fate-swr-resample-s32p-8000-48000: SIZE_TOLERANCE = 96000 - 20480
+
+fate-swr-resample-s32p-8000-96000: CMP_TARGET = 13.82
+fate-swr-resample-s32p-8000-96000: SIZE_TOLERANCE = 96000 - 20480
+
+fate-swr-resample-s32p-96000-2626: CMP_TARGET = 675.14
+fate-swr-resample-s32p-96000-2626: SIZE_TOLERANCE = 1152000 - 20474
+
+fate-swr-resample-s32p-96000-44100: CMP_TARGET = 1.58
+fate-swr-resample-s32p-96000-44100: SIZE_TOLERANCE = 1152000 - 20480
+
+fate-swr-resample-s32p-96000-48000: CMP_TARGET = 1.04
+fate-swr-resample-s32p-96000-48000: SIZE_TOLERANCE = 1152000 - 20480
+
+fate-swr-resample-s32p-96000-8000: CMP_TARGET = 58.60
+fate-swr-resample-s32p-96000-8000: SIZE_TOLERANCE = 1152000 - 20496
+endef
+
+
+$(call CROSS_TEST,$(SAMPLERATES),ARESAMPLE,s16p,s16le,s16)
+$(call CROSS_TEST,$(SAMPLERATES),ARESAMPLE,s32p,s32le,s16)
+$(call CROSS_TEST,$(SAMPLERATES),ARESAMPLE,fltp,f32le,s16)
+$(call CROSS_TEST,$(SAMPLERATES),ARESAMPLE,dblp,f64le,s16)
+
+FATE_SWR_RESAMPLE-$(call FILTERDEMDECENCMUX, ARESAMPLE, WAV, PCM_S16LE, PCM_S16LE, WAV) += $(FATE_SWR_RESAMPLE)
+fate-swr-resample: $(FATE_SWR_RESAMPLE-yes)
+FATE_SWR += $(FATE_SWR_RESAMPLE-yes)
+
+FATE_FFMPEG += $(FATE_SWR)
+fate-swr: $(FATE_SWR)
diff --git a/tests/fate/microsoft.mak b/tests/fate/microsoft.mak
index 41954c0..630dda8 100644
--- a/tests/fate/microsoft.mak
+++ b/tests/fate/microsoft.mak
@@ -12,7 +12,7 @@
FATE_WMV8_DRM += fate-wmv8-drm
# discard last packet to avoid fails due to overread of VC-1 decoder
-fate-wmv8-drm: CMD = framecrc -cryptokey 137381538c84c068111902a59c5cf6c340247c39 -i $(TARGET_SAMPLES)/wmv8/wmv_drm.wmv -an -vframes 162
+fate-wmv8-drm: CMD = framecrc -cryptokey 137381538c84c068111902a59c5cf6c340247c39 -i $(TARGET_SAMPLES)/wmv8/wmv_drm.wmv -an -frames:v 129
FATE_WMV8_DRM += fate-wmv8-drm-nodec
fate-wmv8-drm-nodec: CMD = framecrc -cryptokey 137381538c84c068111902a59c5cf6c340247c39 -i $(TARGET_SAMPLES)/wmv8/wmv_drm.wmv -acodec copy -vcodec copy
diff --git a/tests/fate/vcodec.mak b/tests/fate/vcodec.mak
index 3186c4c..9846646 100644
--- a/tests/fate/vcodec.mak
+++ b/tests/fate/vcodec.mak
@@ -74,8 +74,9 @@
fate-vsynth%-flv: ENCOPTS = -qscale 10
fate-vsynth%-flv: FMT = flv
-FATE_VCODEC-$(call ENCDEC, H261, AVI) += h261
+FATE_VCODEC-$(call ENCDEC, H261, AVI) += h261 h261-trellis
fate-vsynth%-h261: ENCOPTS = -qscale 11
+fate-vsynth%-h261-trellis: ENCOPTS = -qscale 12 -trellis 1 -mbd rd
FATE_VCODEC-$(call ENCDEC, H263, AVI) += h263 h263-obmc h263p
fate-vsynth%-h263: ENCOPTS = -qscale 10
diff --git a/tests/fate/video.mak b/tests/fate/video.mak
index c5527ce..d00df1e 100644
--- a/tests/fate/video.mak
+++ b/tests/fate/video.mak
@@ -163,7 +163,7 @@
fate-jpeg2000-dcinema: CMD = framecrc -flags +bitexact -i $(TARGET_SAMPLES)/jpeg2000/chiens_dcinema2K.mxf -pix_fmt xyz12le
FATE_VIDEO-$(call DEMDEC, JV, JV) += fate-jv
-fate-jv: CMD = framecrc -i $(TARGET_SAMPLES)/jv/intro.jv -pix_fmt rgb24 -an
+fate-jv: CMD = framecrc -i $(TARGET_SAMPLES)/jv/intro.jv -an -pix_fmt rgb24
FATE_VIDEO-$(call DEMDEC, AVI, KGV1) += fate-kgv1
fate-kgv1: CMD = framecrc -i $(TARGET_SAMPLES)/kega/kgv1.avi -pix_fmt rgb555le -an
@@ -269,6 +269,9 @@
FATE_VIDEO-$(call DEMDEC, AVI, VCR1) += fate-vcr1
fate-vcr1: CMD = framecrc -i $(TARGET_SAMPLES)/vcr1/VCR1test.avi -an
+FATE_VIDEO-$(call DEMDEC, AVI, MPEG2VIDEO) += fate-vcr2
+fate-vcr2: CMD = framecrc -flags +bitexact -idct simple -i $(TARGET_SAMPLES)/vcr2/VCR2test.avi -an
+
FATE_VIDEO-$(call DEMDEC, AVI, XL) += fate-videoxl
fate-videoxl: CMD = framecrc -i $(TARGET_SAMPLES)/vixl/pig-vixl.avi
diff --git a/tests/fate/vpx.mak b/tests/fate/vpx.mak
index 8398903..de0b58f 100644
--- a/tests/fate/vpx.mak
+++ b/tests/fate/vpx.mak
@@ -79,11 +79,14 @@
$(foreach W,$(VP9_SIZE_B),$(eval $(foreach H,$(VP9_SIZE_B),$(eval $(call FATE_VP9_SUITE,03-size-$(W)x$(H),$(1),$(2))))))
$(eval $(call FATE_VP9_SUITE,03-deltaq,$(1),$(2)))
$(eval $(call FATE_VP9_SUITE,2pass-akiyo,$(1),$(2)))
-$(eval $(call FATE_VP9_SUITE,segmentation-akiyo,$(1),$(2)))
+$(eval $(call FATE_VP9_SUITE,segmentation-sf-akiyo,$(1),$(2)))
+$(eval $(call FATE_VP9_SUITE,segmentation-aq-akiyo,$(1),$(2)))
$(eval $(call FATE_VP9_SUITE,tiling-pedestrian,$(1),$(2)))
+$(eval $(call FATE_VP9_SUITE,parallelmode-akiyo,$(1),$(2)))
endef
$(eval $(call FATE_VP9_FULL))
$(eval $(call FATE_VP9_FULL,-emu-edge,-flags +emu_edge))
+
FATE_SAMPLES_AVCONV-$(CONFIG_VP9_DECODER) += $(FATE_VP9-yes)
fate-vp9: $(FATE_VP9-yes)
diff --git a/tests/fate/vqf.mak b/tests/fate/vqf.mak
index 8b50d7a..ac18ebd 100644
--- a/tests/fate/vqf.mak
+++ b/tests/fate/vqf.mak
@@ -4,7 +4,7 @@
fate-twinvq: REF = $(SAMPLES)/vqf/achterba.pcm
FATE_VQF-$(CONFIG_VQF_DEMUXER) += fate-vqf-demux
-fate-vqf-demux: CMD = md5 -i $(TARGET_SAMPLES)/vqf/achterba.vqf -acodec copy -f framecrc
+fate-vqf-demux: CMD = md5 -i $(TARGET_SAMPLES)/vqf/achterba.vqf -acodec copy -flags bitexact -f framecrc
FATE_VQF += $(FATE_VQF-yes)
diff --git a/tests/filtergraphs/select-alternate b/tests/filtergraphs/select-alternate
new file mode 100644
index 0000000..1302e42
--- /dev/null
+++ b/tests/filtergraphs/select-alternate
@@ -0,0 +1 @@
+select=not(mod(n\,2))
diff --git a/tests/ref/acodec/mp2fixed b/tests/ref/acodec/mp2fixed
new file mode 100644
index 0000000..0203014
--- /dev/null
+++ b/tests/ref/acodec/mp2fixed
@@ -0,0 +1,4 @@
+28fbc7485c7939f40368f79adccb3e3d *tests/data/fate/acodec-mp2fixed.mp2
+96130 tests/data/fate/acodec-mp2fixed.mp2
+87461bd4ce4b0e0cbbf6c43621baf261 *tests/data/fate/acodec-mp2fixed.out.wav
+stddev: 4384.26 PSNR: 23.49 MAXDIFF:52632 bytes: 1058400/ 1057916
diff --git a/tests/ref/fate/filter-fieldorder b/tests/ref/fate/filter-fieldorder
new file mode 100644
index 0000000..6bb647a
--- /dev/null
+++ b/tests/ref/fate/filter-fieldorder
@@ -0,0 +1,26 @@
+#tb 0: 2/25
+0, 0, 0, 1, 202752, 0x789424b6
+0, 1, 1, 1, 202752, 0x7a1f47a9
+0, 2, 2, 1, 202752, 0xa55a9aba
+0, 3, 3, 1, 202752, 0x71aa394c
+0, 4, 4, 1, 202752, 0xa5d9d0a7
+0, 5, 5, 1, 202752, 0x192d92ff
+0, 6, 6, 1, 202752, 0xa66d9bdd
+0, 7, 7, 1, 202752, 0x29a256bf
+0, 8, 8, 1, 202752, 0x75910eed
+0, 9, 9, 1, 202752, 0x99de19d7
+0, 10, 10, 1, 202752, 0x3a5a16e4
+0, 11, 11, 1, 202752, 0x262ce461
+0, 12, 12, 1, 202752, 0x08da338f
+0, 13, 13, 1, 202752, 0xfb515dbe
+0, 14, 14, 1, 202752, 0x984a8697
+0, 15, 15, 1, 202752, 0xbbd58420
+0, 16, 16, 1, 202752, 0xdd7e560b
+0, 17, 17, 1, 202752, 0x49b94d23
+0, 18, 18, 1, 202752, 0xb679bec7
+0, 19, 19, 1, 202752, 0xe6cffad0
+0, 20, 20, 1, 202752, 0x29a65535
+0, 21, 21, 1, 202752, 0x32851117
+0, 22, 22, 1, 202752, 0x35feb7d1
+0, 23, 23, 1, 202752, 0x96ad33b0
+0, 24, 24, 1, 202752, 0x7ec60b7d
diff --git a/tests/ref/fate/filter-select-alternate b/tests/ref/fate/filter-select-alternate
new file mode 100644
index 0000000..0776694
--- /dev/null
+++ b/tests/ref/fate/filter-select-alternate
@@ -0,0 +1,26 @@
+#tb 0: 1/25
+0, 0, 0, 1, 152064, 0x05b789ef
+0, 2, 2, 1, 152064, 0x9dddf64a
+0, 4, 4, 1, 152064, 0x4de3b652
+0, 6, 6, 1, 152064, 0xe20f7c23
+0, 8, 8, 1, 152064, 0x1f1b8026
+0, 10, 10, 1, 152064, 0x02344760
+0, 12, 12, 1, 152064, 0xc711ad61
+0, 14, 14, 1, 152064, 0x52a48ddd
+0, 16, 16, 1, 152064, 0x8e364e18
+0, 18, 18, 1, 152064, 0xf25f6acc
+0, 20, 20, 1, 152064, 0xfc7bf570
+0, 22, 22, 1, 152064, 0x445d1d59
+0, 24, 24, 1, 152064, 0xce09f9d6
+0, 26, 26, 1, 152064, 0x43d796b5
+0, 28, 28, 1, 152064, 0x76d2a455
+0, 30, 30, 1, 152064, 0x0f9d6aca
+0, 32, 32, 1, 152064, 0xd766fc8d
+0, 34, 34, 1, 152064, 0x7fea4378
+0, 36, 36, 1, 152064, 0x4c9737ab
+0, 38, 38, 1, 152064, 0x0b07594c
+0, 40, 40, 1, 152064, 0xd2735925
+0, 42, 42, 1, 152064, 0x20cebfa9
+0, 44, 44, 1, 152064, 0xfd500471
+0, 46, 46, 1, 152064, 0x09ef53ff
+0, 48, 48, 1, 152064, 0xbb87b483
diff --git a/tests/ref/fate/h264-crop-to-container b/tests/ref/fate/h264-crop-to-container
index 0f435ea..4932bdd 100644
--- a/tests/ref/fate/h264-crop-to-container
+++ b/tests/ref/fate/h264-crop-to-container
@@ -1,2 +1,6 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 3110400, 43a312e1eebc7dca1bd23456302a44e3
diff --git a/tests/ref/fate/h264-extreme-plane-pred b/tests/ref/fate/h264-extreme-plane-pred
index db85e99..96c2bf4 100644
--- a/tests/ref/fate/h264-extreme-plane-pred
+++ b/tests/ref/fate/h264-extreme-plane-pred
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1/25
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 152064, 1e857d2dfeea75297e090ffe9e37a249
0, 1, 1, 1, 152064, 29d8336b4e9b77298025074dbad641d1
0, 2, 2, 1, 152064, 3f1a87d2088a7708f4ed06890c8cd018
diff --git a/tests/ref/fate/hevc-conformance-AMP_A_Samsung_4 b/tests/ref/fate/hevc-conformance-AMP_A_Samsung_4
new file mode 100644
index 0000000..84487a5
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-AMP_A_Samsung_4
@@ -0,0 +1,61 @@
+#tb 0: 1/25
+0, 0, 0, 1, 6144000, 0xf7da9a00
+0, 1, 1, 1, 6144000, 0xf5cfc76f
+0, 2, 2, 1, 6144000, 0x20663e82
+0, 3, 3, 1, 6144000, 0xbff3d1e7
+0, 4, 4, 1, 6144000, 0x6f1b824d
+0, 5, 5, 1, 6144000, 0x4d75e5c9
+0, 6, 6, 1, 6144000, 0xb4443853
+0, 7, 7, 1, 6144000, 0x6943bbcb
+0, 8, 8, 1, 6144000, 0x1748b8d3
+0, 9, 9, 1, 6144000, 0x0e15caec
+0, 10, 10, 1, 6144000, 0xf7553ff4
+0, 11, 11, 1, 6144000, 0x34007146
+0, 12, 12, 1, 6144000, 0xd115a7ad
+0, 13, 13, 1, 6144000, 0x1adc8d27
+0, 14, 14, 1, 6144000, 0x2c3a43a6
+0, 15, 15, 1, 6144000, 0x1820500a
+0, 16, 16, 1, 6144000, 0xb33cf5af
+0, 17, 17, 1, 6144000, 0x5ba58d5a
+0, 18, 18, 1, 6144000, 0x453f35bc
+0, 19, 19, 1, 6144000, 0x4e6ac2ab
+0, 20, 20, 1, 6144000, 0xfab2b132
+0, 21, 21, 1, 6144000, 0xf903b7bf
+0, 22, 22, 1, 6144000, 0x160ebf13
+0, 23, 23, 1, 6144000, 0xd147c884
+0, 24, 24, 1, 6144000, 0x266abc04
+0, 25, 25, 1, 6144000, 0x9fabf642
+0, 26, 26, 1, 6144000, 0x1ad4f6c7
+0, 27, 27, 1, 6144000, 0x41fa1e6f
+0, 28, 28, 1, 6144000, 0x14b2b3b4
+0, 29, 29, 1, 6144000, 0x19c6d13e
+0, 30, 30, 1, 6144000, 0x414f5a36
+0, 31, 31, 1, 6144000, 0x439278aa
+0, 32, 32, 1, 6144000, 0xf8e73a55
+0, 33, 33, 1, 6144000, 0xf4cf7779
+0, 34, 34, 1, 6144000, 0x86ac3a16
+0, 35, 35, 1, 6144000, 0xdc9abdb8
+0, 36, 36, 1, 6144000, 0x9ab68a62
+0, 37, 37, 1, 6144000, 0xcd290547
+0, 38, 38, 1, 6144000, 0xd2eb88bb
+0, 39, 39, 1, 6144000, 0x126e084e
+0, 40, 40, 1, 6144000, 0x1aa5302c
+0, 41, 41, 1, 6144000, 0x689cb93e
+0, 42, 42, 1, 6144000, 0xaa9e3be6
+0, 43, 43, 1, 6144000, 0x33dc9ead
+0, 44, 44, 1, 6144000, 0xcb943dd3
+0, 45, 45, 1, 6144000, 0x22a67b19
+0, 46, 46, 1, 6144000, 0x3bfb741a
+0, 47, 47, 1, 6144000, 0x9238e595
+0, 48, 48, 1, 6144000, 0xf0fb6381
+0, 49, 49, 1, 6144000, 0x6ea42af1
+0, 50, 50, 1, 6144000, 0x47d9c3a7
+0, 51, 51, 1, 6144000, 0x9f73966b
+0, 52, 52, 1, 6144000, 0xdf777adc
+0, 53, 53, 1, 6144000, 0xf51f206e
+0, 54, 54, 1, 6144000, 0x465c350a
+0, 55, 55, 1, 6144000, 0x9253a45a
+0, 56, 56, 1, 6144000, 0x72c89751
+0, 57, 57, 1, 6144000, 0x0405cdfc
+0, 58, 58, 1, 6144000, 0xc5ede0c7
+0, 59, 59, 1, 6144000, 0xcf1c2b5e
diff --git a/tests/ref/fate/hevc-conformance-AMP_B_Samsung_4 b/tests/ref/fate/hevc-conformance-AMP_B_Samsung_4
new file mode 100644
index 0000000..034f7b8
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-AMP_B_Samsung_4
@@ -0,0 +1,61 @@
+#tb 0: 1/25
+0, 0, 0, 1, 6144000, 0xcd32ef33
+0, 1, 1, 1, 6144000, 0x58ce681d
+0, 2, 2, 1, 6144000, 0x77a732b6
+0, 3, 3, 1, 6144000, 0xa95418d0
+0, 4, 4, 1, 6144000, 0xa1593606
+0, 5, 5, 1, 6144000, 0x0d5429bc
+0, 6, 6, 1, 6144000, 0xe7cd205c
+0, 7, 7, 1, 6144000, 0x52c30ff4
+0, 8, 8, 1, 6144000, 0xf0a0f686
+0, 9, 9, 1, 6144000, 0xa6371d86
+0, 10, 10, 1, 6144000, 0x18bf1478
+0, 11, 11, 1, 6144000, 0xb84c6322
+0, 12, 12, 1, 6144000, 0x12f35f80
+0, 13, 13, 1, 6144000, 0xa9009e83
+0, 14, 14, 1, 6144000, 0x08568380
+0, 15, 15, 1, 6144000, 0xb01e98e8
+0, 16, 16, 1, 6144000, 0x0796ee90
+0, 17, 17, 1, 6144000, 0x3bb7cbef
+0, 18, 18, 1, 6144000, 0x7c3d6929
+0, 19, 19, 1, 6144000, 0x62c0e56c
+0, 20, 20, 1, 6144000, 0xd05907f7
+0, 21, 21, 1, 6144000, 0x9aa33b33
+0, 22, 22, 1, 6144000, 0xc47a0195
+0, 23, 23, 1, 6144000, 0xa5a5db13
+0, 24, 24, 1, 6144000, 0x54fda44b
+0, 25, 25, 1, 6144000, 0x7695be2f
+0, 26, 26, 1, 6144000, 0x247228e1
+0, 27, 27, 1, 6144000, 0xec38b2f7
+0, 28, 28, 1, 6144000, 0x223b098d
+0, 29, 29, 1, 6144000, 0xdd13f4bf
+0, 30, 30, 1, 6144000, 0x42651b46
+0, 31, 31, 1, 6144000, 0xc0b2ac9a
+0, 32, 32, 1, 6144000, 0x574908ee
+0, 33, 33, 1, 6144000, 0x070f0d88
+0, 34, 34, 1, 6144000, 0xc68ee679
+0, 35, 35, 1, 6144000, 0x4d571c82
+0, 36, 36, 1, 6144000, 0xec7f28cb
+0, 37, 37, 1, 6144000, 0x07ca3ccd
+0, 38, 38, 1, 6144000, 0xa5161fd7
+0, 39, 39, 1, 6144000, 0xb0908b25
+0, 40, 40, 1, 6144000, 0x4fa56c5e
+0, 41, 41, 1, 6144000, 0x1ad84207
+0, 42, 42, 1, 6144000, 0xc862a32b
+0, 43, 43, 1, 6144000, 0x341b9b0a
+0, 44, 44, 1, 6144000, 0xa940cdab
+0, 45, 45, 1, 6144000, 0x57521b2d
+0, 46, 46, 1, 6144000, 0x31969dee
+0, 47, 47, 1, 6144000, 0x7a09e240
+0, 48, 48, 1, 6144000, 0x14e6c360
+0, 49, 49, 1, 6144000, 0x0dfd6085
+0, 50, 50, 1, 6144000, 0xdf231a1e
+0, 51, 51, 1, 6144000, 0x6d1e9ce1
+0, 52, 52, 1, 6144000, 0xc6c2fb26
+0, 53, 53, 1, 6144000, 0xd4bc5e3e
+0, 54, 54, 1, 6144000, 0xa4a56b9e
+0, 55, 55, 1, 6144000, 0x8ba6349f
+0, 56, 56, 1, 6144000, 0x0683757f
+0, 57, 57, 1, 6144000, 0xe3840d8b
+0, 58, 58, 1, 6144000, 0x2fdf2ae6
+0, 59, 59, 1, 6144000, 0xea877e27
diff --git a/tests/ref/fate/hevc-conformance-AMP_D_Hisilicon b/tests/ref/fate/hevc-conformance-AMP_D_Hisilicon
new file mode 100644
index 0000000..6e17b83
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-AMP_D_Hisilicon
@@ -0,0 +1,101 @@
+#tb 0: 1/25
+0, 0, 0, 1, 3110400, 0x1559c293
+0, 1, 1, 1, 3110400, 0xd0802706
+0, 2, 2, 1, 3110400, 0xb48cf229
+0, 3, 3, 1, 3110400, 0x4108509b
+0, 4, 4, 1, 3110400, 0xd1cec277
+0, 5, 5, 1, 3110400, 0x3e68c589
+0, 6, 6, 1, 3110400, 0x1543a517
+0, 7, 7, 1, 3110400, 0x5ddcd669
+0, 8, 8, 1, 3110400, 0x09bd4c27
+0, 9, 9, 1, 3110400, 0xd583bfa1
+0, 10, 10, 1, 3110400, 0xe9411279
+0, 11, 11, 1, 3110400, 0xe07e6f3f
+0, 12, 12, 1, 3110400, 0xcfd23191
+0, 13, 13, 1, 3110400, 0x24276734
+0, 14, 14, 1, 3110400, 0x485aeafe
+0, 15, 15, 1, 3110400, 0xb8039a85
+0, 16, 16, 1, 3110400, 0x1d154e19
+0, 17, 17, 1, 3110400, 0xaa3ce800
+0, 18, 18, 1, 3110400, 0xe2601cba
+0, 19, 19, 1, 3110400, 0xb6657a57
+0, 20, 20, 1, 3110400, 0x34dbda52
+0, 21, 21, 1, 3110400, 0x921e218a
+0, 22, 22, 1, 3110400, 0x7de5262f
+0, 23, 23, 1, 3110400, 0x1a97e083
+0, 24, 24, 1, 3110400, 0x4bfc81d0
+0, 25, 25, 1, 3110400, 0x583396e6
+0, 26, 26, 1, 3110400, 0xc96bcd39
+0, 27, 27, 1, 3110400, 0x483cf7cf
+0, 28, 28, 1, 3110400, 0x20882e52
+0, 29, 29, 1, 3110400, 0x93d352fe
+0, 30, 30, 1, 3110400, 0x0c932722
+0, 31, 31, 1, 3110400, 0x78c5a9f0
+0, 32, 32, 1, 3110400, 0xcea3bddd
+0, 33, 33, 1, 3110400, 0x3e4e7c77
+0, 34, 34, 1, 3110400, 0xbe048a0a
+0, 35, 35, 1, 3110400, 0x1cf7ea0d
+0, 36, 36, 1, 3110400, 0xeb60343a
+0, 37, 37, 1, 3110400, 0x2158ed1f
+0, 38, 38, 1, 3110400, 0x3a7126b1
+0, 39, 39, 1, 3110400, 0x282804ff
+0, 40, 40, 1, 3110400, 0x292ed438
+0, 41, 41, 1, 3110400, 0x49a9769d
+0, 42, 42, 1, 3110400, 0xdfc12632
+0, 43, 43, 1, 3110400, 0xff3da16a
+0, 44, 44, 1, 3110400, 0x134b68c6
+0, 45, 45, 1, 3110400, 0x717e6f1d
+0, 46, 46, 1, 3110400, 0x283293f5
+0, 47, 47, 1, 3110400, 0x3d401456
+0, 48, 48, 1, 3110400, 0x500eddac
+0, 49, 49, 1, 3110400, 0x2a96fbff
+0, 50, 50, 1, 3110400, 0x9d75f303
+0, 51, 51, 1, 3110400, 0x08d1fa48
+0, 52, 52, 1, 3110400, 0xa685a8da
+0, 53, 53, 1, 3110400, 0xc19216d8
+0, 54, 54, 1, 3110400, 0x61ebd7f2
+0, 55, 55, 1, 3110400, 0x866c9002
+0, 56, 56, 1, 3110400, 0x3edda174
+0, 57, 57, 1, 3110400, 0x4e848db7
+0, 58, 58, 1, 3110400, 0x1dd822ba
+0, 59, 59, 1, 3110400, 0x8157b534
+0, 60, 60, 1, 3110400, 0x72637dbe
+0, 61, 61, 1, 3110400, 0xc6fc1305
+0, 62, 62, 1, 3110400, 0xbfadeee4
+0, 63, 63, 1, 3110400, 0xad20c230
+0, 64, 64, 1, 3110400, 0x5afff02b
+0, 65, 65, 1, 3110400, 0x5e533c71
+0, 66, 66, 1, 3110400, 0x52e10588
+0, 67, 67, 1, 3110400, 0x13a6dbb1
+0, 68, 68, 1, 3110400, 0xc74de5ae
+0, 69, 69, 1, 3110400, 0x382aafb8
+0, 70, 70, 1, 3110400, 0x5e0a11b2
+0, 71, 71, 1, 3110400, 0x049fe7cc
+0, 72, 72, 1, 3110400, 0x9d79484e
+0, 73, 73, 1, 3110400, 0x1116ced8
+0, 74, 74, 1, 3110400, 0x5d8d075d
+0, 75, 75, 1, 3110400, 0x49392496
+0, 76, 76, 1, 3110400, 0x5f24b3b3
+0, 77, 77, 1, 3110400, 0x6ca1c16d
+0, 78, 78, 1, 3110400, 0x131a16d2
+0, 79, 79, 1, 3110400, 0x39e2f9a1
+0, 80, 80, 1, 3110400, 0x988bd0ee
+0, 81, 81, 1, 3110400, 0xa6c050ec
+0, 82, 82, 1, 3110400, 0x5275142a
+0, 83, 83, 1, 3110400, 0x5705923d
+0, 84, 84, 1, 3110400, 0x3098d52d
+0, 85, 85, 1, 3110400, 0xb16e2eb7
+0, 86, 86, 1, 3110400, 0x0dee6bc8
+0, 87, 87, 1, 3110400, 0x577acf61
+0, 88, 88, 1, 3110400, 0x2b70d954
+0, 89, 89, 1, 3110400, 0x26b5f1c5
+0, 90, 90, 1, 3110400, 0x2351ad88
+0, 91, 91, 1, 3110400, 0xe5bdf6ad
+0, 92, 92, 1, 3110400, 0xaf0d83de
+0, 93, 93, 1, 3110400, 0xaee86799
+0, 94, 94, 1, 3110400, 0xe73fe067
+0, 95, 95, 1, 3110400, 0x46b90697
+0, 96, 96, 1, 3110400, 0xb270f77a
+0, 97, 97, 1, 3110400, 0xf33aa535
+0, 98, 98, 1, 3110400, 0xcafe6eec
+0, 99, 99, 1, 3110400, 0xcf051a31
diff --git a/tests/ref/fate/hevc-conformance-AMP_E_Hisilicon b/tests/ref/fate/hevc-conformance-AMP_E_Hisilicon
new file mode 100644
index 0000000..c1b7f2e
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-AMP_E_Hisilicon
@@ -0,0 +1,101 @@
+#tb 0: 1/25
+0, 0, 0, 1, 3110400, 0xf9342188
+0, 1, 1, 1, 3110400, 0x46638dc4
+0, 2, 2, 1, 3110400, 0x96da436e
+0, 3, 3, 1, 3110400, 0xae9ee064
+0, 4, 4, 1, 3110400, 0x03fc9d17
+0, 5, 5, 1, 3110400, 0xd7ba9ab8
+0, 6, 6, 1, 3110400, 0x9f3cc881
+0, 7, 7, 1, 3110400, 0x911c9e2a
+0, 8, 8, 1, 3110400, 0x2c1bdec1
+0, 9, 9, 1, 3110400, 0xffc2cfb2
+0, 10, 10, 1, 3110400, 0x34136d4c
+0, 11, 11, 1, 3110400, 0x400dca0c
+0, 12, 12, 1, 3110400, 0x5a3d3c71
+0, 13, 13, 1, 3110400, 0x5bd262f9
+0, 14, 14, 1, 3110400, 0x27bbec47
+0, 15, 15, 1, 3110400, 0x53ca3f78
+0, 16, 16, 1, 3110400, 0x7fee4170
+0, 17, 17, 1, 3110400, 0x393d318c
+0, 18, 18, 1, 3110400, 0x203f26f1
+0, 19, 19, 1, 3110400, 0x35e00c3e
+0, 20, 20, 1, 3110400, 0x995afdde
+0, 21, 21, 1, 3110400, 0xa8b623b9
+0, 22, 22, 1, 3110400, 0x047e53bd
+0, 23, 23, 1, 3110400, 0xc7e69515
+0, 24, 24, 1, 3110400, 0x7e5ade49
+0, 25, 25, 1, 3110400, 0x863cddc9
+0, 26, 26, 1, 3110400, 0xb1f6189c
+0, 27, 27, 1, 3110400, 0x622d6d1d
+0, 28, 28, 1, 3110400, 0x1e82ef1a
+0, 29, 29, 1, 3110400, 0x06a7054a
+0, 30, 30, 1, 3110400, 0x736bd4a9
+0, 31, 31, 1, 3110400, 0x1db8ead3
+0, 32, 32, 1, 3110400, 0x1d872697
+0, 33, 33, 1, 3110400, 0x86b11604
+0, 34, 34, 1, 3110400, 0x54bee045
+0, 35, 35, 1, 3110400, 0x3577fa15
+0, 36, 36, 1, 3110400, 0x717b6c0b
+0, 37, 37, 1, 3110400, 0x5e0f0b6e
+0, 38, 38, 1, 3110400, 0x054ecc86
+0, 39, 39, 1, 3110400, 0x9ec29ad1
+0, 40, 40, 1, 3110400, 0x7c3b56e4
+0, 41, 41, 1, 3110400, 0xcf4cf721
+0, 42, 42, 1, 3110400, 0x43c01adb
+0, 43, 43, 1, 3110400, 0x6abb4879
+0, 44, 44, 1, 3110400, 0x90473c9f
+0, 45, 45, 1, 3110400, 0x5f5bb9a9
+0, 46, 46, 1, 3110400, 0x08678e6b
+0, 47, 47, 1, 3110400, 0xf4ad0c9b
+0, 48, 48, 1, 3110400, 0x22870cc8
+0, 49, 49, 1, 3110400, 0xb417cf63
+0, 50, 50, 1, 3110400, 0xb7a1588e
+0, 51, 51, 1, 3110400, 0x7a35ac81
+0, 52, 52, 1, 3110400, 0xcd1c6d82
+0, 53, 53, 1, 3110400, 0x181b9920
+0, 54, 54, 1, 3110400, 0xf2417d5e
+0, 55, 55, 1, 3110400, 0x8a67e02b
+0, 56, 56, 1, 3110400, 0xe7b99077
+0, 57, 57, 1, 3110400, 0x6814e5c2
+0, 58, 58, 1, 3110400, 0xd8bce44d
+0, 59, 59, 1, 3110400, 0x9faf4ebc
+0, 60, 60, 1, 3110400, 0x3daa5fbf
+0, 61, 61, 1, 3110400, 0x747921ba
+0, 62, 62, 1, 3110400, 0xbe30214e
+0, 63, 63, 1, 3110400, 0x8f5533fe
+0, 64, 64, 1, 3110400, 0x835a4545
+0, 65, 65, 1, 3110400, 0xfa99f4c8
+0, 66, 66, 1, 3110400, 0x9559c5db
+0, 67, 67, 1, 3110400, 0xd0d096f8
+0, 68, 68, 1, 3110400, 0x7b24dbb0
+0, 69, 69, 1, 3110400, 0x4a8aa189
+0, 70, 70, 1, 3110400, 0x876bab32
+0, 71, 71, 1, 3110400, 0xc930bec9
+0, 72, 72, 1, 3110400, 0x009841d8
+0, 73, 73, 1, 3110400, 0x93e5be89
+0, 74, 74, 1, 3110400, 0x82260331
+0, 75, 75, 1, 3110400, 0x7ef2e971
+0, 76, 76, 1, 3110400, 0x606b638a
+0, 77, 77, 1, 3110400, 0xf08b84df
+0, 78, 78, 1, 3110400, 0x8a609222
+0, 79, 79, 1, 3110400, 0xa76cb2f3
+0, 80, 80, 1, 3110400, 0x2b611cb3
+0, 81, 81, 1, 3110400, 0x81d5b315
+0, 82, 82, 1, 3110400, 0x6f385e43
+0, 83, 83, 1, 3110400, 0x5959a754
+0, 84, 84, 1, 3110400, 0x1cf4935c
+0, 85, 85, 1, 3110400, 0xc8da3639
+0, 86, 86, 1, 3110400, 0x50a2ee3d
+0, 87, 87, 1, 3110400, 0xd33ad53a
+0, 88, 88, 1, 3110400, 0xe7ed4eff
+0, 89, 89, 1, 3110400, 0x7d72d260
+0, 90, 90, 1, 3110400, 0x16ca295b
+0, 91, 91, 1, 3110400, 0xf126df1d
+0, 92, 92, 1, 3110400, 0x0aca09d1
+0, 93, 93, 1, 3110400, 0x6aefb52b
+0, 94, 94, 1, 3110400, 0xf797ee6d
+0, 95, 95, 1, 3110400, 0xf1053ace
+0, 96, 96, 1, 3110400, 0xf7f91618
+0, 97, 97, 1, 3110400, 0xc711acf8
+0, 98, 98, 1, 3110400, 0x31123f40
+0, 99, 99, 1, 3110400, 0xc7b703dc
diff --git a/tests/ref/fate/hevc-conformance-AMP_F_Hisilicon_3 b/tests/ref/fate/hevc-conformance-AMP_F_Hisilicon_3
new file mode 100644
index 0000000..71ce9c7
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-AMP_F_Hisilicon_3
@@ -0,0 +1,101 @@
+#tb 0: 1/25
+0, 0, 0, 1, 3110400, 0xa5d2b8b0
+0, 1, 1, 1, 3110400, 0x13035cfa
+0, 2, 2, 1, 3110400, 0x96b16f86
+0, 3, 3, 1, 3110400, 0x09e96331
+0, 4, 4, 1, 3110400, 0xd2662da8
+0, 5, 5, 1, 3110400, 0x77d3db00
+0, 6, 6, 1, 3110400, 0xaa025e5b
+0, 7, 7, 1, 3110400, 0x77284bc5
+0, 8, 8, 1, 3110400, 0x625b165e
+0, 9, 9, 1, 3110400, 0x69c0b4c8
+0, 10, 10, 1, 3110400, 0x52e627a4
+0, 11, 11, 1, 3110400, 0x774eaf6a
+0, 12, 12, 1, 3110400, 0xa9042cad
+0, 13, 13, 1, 3110400, 0xf367e96a
+0, 14, 14, 1, 3110400, 0x4687e2d9
+0, 15, 15, 1, 3110400, 0xe57d46b8
+0, 16, 16, 1, 3110400, 0x074da0b5
+0, 17, 17, 1, 3110400, 0xbf8dd856
+0, 18, 18, 1, 3110400, 0xb9cae21e
+0, 19, 19, 1, 3110400, 0xa43687fc
+0, 20, 20, 1, 3110400, 0x83cce559
+0, 21, 21, 1, 3110400, 0xb19963d9
+0, 22, 22, 1, 3110400, 0x636d69b7
+0, 23, 23, 1, 3110400, 0xfcfe1a00
+0, 24, 24, 1, 3110400, 0x0a804c37
+0, 25, 25, 1, 3110400, 0x6af0c5ec
+0, 26, 26, 1, 3110400, 0xccec0692
+0, 27, 27, 1, 3110400, 0x0547e98d
+0, 28, 28, 1, 3110400, 0xc4dc2caa
+0, 29, 29, 1, 3110400, 0x43473ac6
+0, 30, 30, 1, 3110400, 0xd5e9a795
+0, 31, 31, 1, 3110400, 0x3227df7b
+0, 32, 32, 1, 3110400, 0x087e57bb
+0, 33, 33, 1, 3110400, 0x892f5ad0
+0, 34, 34, 1, 3110400, 0xeeb23459
+0, 35, 35, 1, 3110400, 0xd1efe2a6
+0, 36, 36, 1, 3110400, 0x5abd5104
+0, 37, 37, 1, 3110400, 0x6b018b83
+0, 38, 38, 1, 3110400, 0x91617ca7
+0, 39, 39, 1, 3110400, 0x601cd6ad
+0, 40, 40, 1, 3110400, 0xf81cb126
+0, 41, 41, 1, 3110400, 0x4bb949df
+0, 42, 42, 1, 3110400, 0xed94fea0
+0, 43, 43, 1, 3110400, 0x39ba8fec
+0, 44, 44, 1, 3110400, 0xc65e113c
+0, 45, 45, 1, 3110400, 0x627344cb
+0, 46, 46, 1, 3110400, 0x5680c16a
+0, 47, 47, 1, 3110400, 0x12d02cfc
+0, 48, 48, 1, 3110400, 0x2e409afa
+0, 49, 49, 1, 3110400, 0xfd4142f2
+0, 50, 50, 1, 3110400, 0x6db3965a
+0, 51, 51, 1, 3110400, 0x578962c5
+0, 52, 52, 1, 3110400, 0x68d75bd1
+0, 53, 53, 1, 3110400, 0x568fbb72
+0, 54, 54, 1, 3110400, 0xf3c03b95
+0, 55, 55, 1, 3110400, 0xeb67b532
+0, 56, 56, 1, 3110400, 0x0e445b34
+0, 57, 57, 1, 3110400, 0x32c04ad2
+0, 58, 58, 1, 3110400, 0x239d1a14
+0, 59, 59, 1, 3110400, 0xcb295635
+0, 60, 60, 1, 3110400, 0x7e347c1d
+0, 61, 61, 1, 3110400, 0x74e1fcf7
+0, 62, 62, 1, 3110400, 0x6e399603
+0, 63, 63, 1, 3110400, 0xe3bbdbcd
+0, 64, 64, 1, 3110400, 0xddd336f3
+0, 65, 65, 1, 3110400, 0x7834e9f7
+0, 66, 66, 1, 3110400, 0xb53a7f1f
+0, 67, 67, 1, 3110400, 0x1f52cbb6
+0, 68, 68, 1, 3110400, 0xea26692a
+0, 69, 69, 1, 3110400, 0xa4e1765f
+0, 70, 70, 1, 3110400, 0x6367794d
+0, 71, 71, 1, 3110400, 0x69bff6d1
+0, 72, 72, 1, 3110400, 0xdf52ef08
+0, 73, 73, 1, 3110400, 0x002892b7
+0, 74, 74, 1, 3110400, 0x1ca49791
+0, 75, 75, 1, 3110400, 0x8de95d1d
+0, 76, 76, 1, 3110400, 0x9c9c38cf
+0, 77, 77, 1, 3110400, 0x9f9947cd
+0, 78, 78, 1, 3110400, 0xe5da908b
+0, 79, 79, 1, 3110400, 0x032415ae
+0, 80, 80, 1, 3110400, 0x0fef3a03
+0, 81, 81, 1, 3110400, 0xd04c1b77
+0, 82, 82, 1, 3110400, 0x5d46813b
+0, 83, 83, 1, 3110400, 0x1dbeaa76
+0, 84, 84, 1, 3110400, 0x2b2eea1a
+0, 85, 85, 1, 3110400, 0x7138da47
+0, 86, 86, 1, 3110400, 0xe9a43ef8
+0, 87, 87, 1, 3110400, 0x02f7b1bf
+0, 88, 88, 1, 3110400, 0xd1cdf8b1
+0, 89, 89, 1, 3110400, 0x2e924022
+0, 90, 90, 1, 3110400, 0x59d68bcf
+0, 91, 91, 1, 3110400, 0x3dc70503
+0, 92, 92, 1, 3110400, 0x26aeb1fa
+0, 93, 93, 1, 3110400, 0x91434f9d
+0, 94, 94, 1, 3110400, 0x91411f14
+0, 95, 95, 1, 3110400, 0xd99a172a
+0, 96, 96, 1, 3110400, 0x19678f5a
+0, 97, 97, 1, 3110400, 0xc6c357ae
+0, 98, 98, 1, 3110400, 0xba6cd89f
+0, 99, 99, 1, 3110400, 0x657af6cf
diff --git a/tests/ref/fate/hevc-conformance-AMVP_A_MTK_4 b/tests/ref/fate/hevc-conformance-AMVP_A_MTK_4
new file mode 100644
index 0000000..59115fb
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-AMVP_A_MTK_4
@@ -0,0 +1,31 @@
+#tb 0: 1/25
+0, 0, 0, 1, 149760, 0x88619f80
+0, 1, 1, 1, 149760, 0x550bdaf0
+0, 2, 2, 1, 149760, 0xb769fa4c
+0, 3, 3, 1, 149760, 0x3c2c2e9a
+0, 4, 4, 1, 149760, 0x75316bcc
+0, 5, 5, 1, 149760, 0x7b9ba7ff
+0, 6, 6, 1, 149760, 0x9981ea7b
+0, 7, 7, 1, 149760, 0x3f682105
+0, 8, 8, 1, 149760, 0x63252c25
+0, 9, 9, 1, 149760, 0x44427967
+0, 10, 10, 1, 149760, 0x24199a9e
+0, 11, 11, 1, 149760, 0xaa30c241
+0, 12, 12, 1, 149760, 0xf24faaaf
+0, 13, 13, 1, 149760, 0x0291c766
+0, 14, 14, 1, 149760, 0xb826e44f
+0, 15, 15, 1, 149760, 0xbc2310b8
+0, 16, 16, 1, 149760, 0xcfd81d4a
+0, 17, 17, 1, 149760, 0xb356484a
+0, 18, 18, 1, 149760, 0x02bf515a
+0, 19, 19, 1, 149760, 0x729d778c
+0, 20, 20, 1, 149760, 0x3ade8453
+0, 21, 21, 1, 149760, 0xfedead3d
+0, 22, 22, 1, 149760, 0x46bfc8db
+0, 23, 23, 1, 149760, 0x8590f422
+0, 24, 24, 1, 149760, 0x6d2dfd9d
+0, 25, 25, 1, 149760, 0x373f2c82
+0, 26, 26, 1, 149760, 0xa12f3ca1
+0, 27, 27, 1, 149760, 0x34be4b0d
+0, 28, 28, 1, 149760, 0x24f538b9
+0, 29, 29, 1, 149760, 0xd1616303
diff --git a/tests/ref/fate/hevc-conformance-AMVP_B_MTK_4 b/tests/ref/fate/hevc-conformance-AMVP_B_MTK_4
new file mode 100644
index 0000000..1f998c4
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-AMVP_B_MTK_4
@@ -0,0 +1,42 @@
+#tb 0: 1/25
+0, 0, 0, 1, 149760, 0xcfffa013
+0, 1, 1, 1, 149760, 0x5166146a
+0, 2, 2, 1, 149760, 0xc3cc318e
+0, 3, 3, 1, 149760, 0x5bb465f9
+0, 4, 4, 1, 149760, 0x10c97bd4
+0, 5, 5, 1, 149760, 0xd9d5c4ab
+0, 6, 6, 1, 149760, 0x5112e11d
+0, 7, 7, 1, 149760, 0xde3803d6
+0, 8, 8, 1, 149760, 0x82c62409
+0, 9, 9, 1, 149760, 0x28f88d53
+0, 10, 10, 1, 149760, 0x796fb89d
+0, 11, 11, 1, 149760, 0x1b95dd75
+0, 12, 12, 1, 149760, 0xfcc9ced4
+0, 13, 13, 1, 149760, 0x6b00ee9c
+0, 14, 14, 1, 149760, 0xdb72e81a
+0, 15, 15, 1, 149760, 0x0c771a25
+0, 16, 16, 1, 149760, 0x959a2215
+0, 17, 17, 1, 149760, 0xf1d672ce
+0, 18, 18, 1, 149760, 0x2f407a06
+0, 19, 19, 1, 149760, 0xee389f83
+0, 20, 20, 1, 149760, 0x2e0695dd
+0, 21, 21, 1, 149760, 0xf80ac1eb
+0, 22, 22, 1, 149760, 0x29decec4
+0, 23, 23, 1, 149760, 0xff34eb5e
+0, 24, 24, 1, 149760, 0x1c85fe71
+0, 25, 25, 1, 149760, 0x056dae51
+0, 26, 26, 1, 149760, 0x78a99f1d
+0, 27, 27, 1, 149760, 0xe507b40c
+0, 28, 28, 1, 149760, 0xbd3fa06c
+0, 29, 29, 1, 149760, 0x3475d95b
+0, 30, 30, 1, 149760, 0x9b25d416
+0, 31, 31, 1, 149760, 0x73c4ec88
+0, 32, 32, 1, 149760, 0xd4437e12
+0, 33, 33, 1, 149760, 0xcf08c736
+0, 34, 34, 1, 149760, 0x0cedd0d6
+0, 35, 35, 1, 149760, 0xc317e9bc
+0, 36, 36, 1, 149760, 0x0dcbd636
+0, 37, 37, 1, 149760, 0x4e6501b0
+0, 38, 38, 1, 149760, 0x5f9c02bb
+0, 39, 39, 1, 149760, 0x43052939
+0, 40, 40, 1, 149760, 0x8ec12318
diff --git a/tests/ref/fate/hevc-conformance-AMVP_C_Samsung_4 b/tests/ref/fate/hevc-conformance-AMVP_C_Samsung_4
new file mode 100644
index 0000000..16d3446
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-AMVP_C_Samsung_4
@@ -0,0 +1,61 @@
+#tb 0: 1/25
+0, 0, 0, 1, 599040, 0x8087662a
+0, 1, 1, 1, 599040, 0x5278d8db
+0, 2, 2, 1, 599040, 0x73c74090
+0, 3, 3, 1, 599040, 0xde0d8317
+0, 4, 4, 1, 599040, 0xd9d4c26c
+0, 5, 5, 1, 599040, 0x603a10bd
+0, 6, 6, 1, 599040, 0xa91e9b91
+0, 7, 7, 1, 599040, 0x73567e6a
+0, 8, 8, 1, 599040, 0x67912cc6
+0, 9, 9, 1, 599040, 0x98d3fb2c
+0, 10, 10, 1, 599040, 0x50c6d7fc
+0, 11, 11, 1, 599040, 0x8ae23020
+0, 12, 12, 1, 599040, 0x9eaa976f
+0, 13, 13, 1, 599040, 0x3cadf6c0
+0, 14, 14, 1, 599040, 0x7d498902
+0, 15, 15, 1, 599040, 0x525decac
+0, 16, 16, 1, 599040, 0x081485cc
+0, 17, 17, 1, 599040, 0x3fd6ba7a
+0, 18, 18, 1, 599040, 0x8bbbaa4c
+0, 19, 19, 1, 599040, 0x9e60a407
+0, 20, 20, 1, 599040, 0x394becb9
+0, 21, 21, 1, 599040, 0x068dffb5
+0, 22, 22, 1, 599040, 0x531fd221
+0, 23, 23, 1, 599040, 0x3aa6922e
+0, 24, 24, 1, 599040, 0x089d2456
+0, 25, 25, 1, 599040, 0x7c432995
+0, 26, 26, 1, 599040, 0x3693613d
+0, 27, 27, 1, 599040, 0x8b6d902f
+0, 28, 28, 1, 599040, 0x7c9a947b
+0, 29, 29, 1, 599040, 0x51d9e4c6
+0, 30, 30, 1, 599040, 0xdc7f62f3
+0, 31, 31, 1, 599040, 0x9da6cba0
+0, 32, 32, 1, 599040, 0x1bef8581
+0, 33, 33, 1, 599040, 0xc19c4211
+0, 34, 34, 1, 599040, 0x7824188e
+0, 35, 35, 1, 599040, 0xd0511050
+0, 36, 36, 1, 599040, 0x39d93e78
+0, 37, 37, 1, 599040, 0x1e0dc88e
+0, 38, 38, 1, 599040, 0x2cd7522e
+0, 39, 39, 1, 599040, 0x538928a5
+0, 40, 40, 1, 599040, 0x95549fb2
+0, 41, 41, 1, 599040, 0x1f57d5c1
+0, 42, 42, 1, 599040, 0xc99fa8c6
+0, 43, 43, 1, 599040, 0x567f4e7e
+0, 44, 44, 1, 599040, 0x23d3d54f
+0, 45, 45, 1, 599040, 0xe8f74d97
+0, 46, 46, 1, 599040, 0xd2b03a4d
+0, 47, 47, 1, 599040, 0xe59c4faf
+0, 48, 48, 1, 599040, 0x46da921d
+0, 49, 49, 1, 599040, 0x7a344fa3
+0, 50, 50, 1, 599040, 0xbc736fd4
+0, 51, 51, 1, 599040, 0xfe5c362c
+0, 52, 52, 1, 599040, 0x115ed271
+0, 53, 53, 1, 599040, 0x3c4913fc
+0, 54, 54, 1, 599040, 0x1e1f8114
+0, 55, 55, 1, 599040, 0x08c06e58
+0, 56, 56, 1, 599040, 0x599f07f6
+0, 57, 57, 1, 599040, 0xc922a0c9
+0, 58, 58, 1, 599040, 0xc77b5201
+0, 59, 59, 1, 599040, 0x4c2cde6d
diff --git a/tests/ref/fate/hevc-conformance-CAINIT_A_SHARP_4 b/tests/ref/fate/hevc-conformance-CAINIT_A_SHARP_4
new file mode 100644
index 0000000..53b621b
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-CAINIT_A_SHARP_4
@@ -0,0 +1,51 @@
+#tb 0: 1/25
+0, 0, 0, 1, 599040, 0x001f0c48
+0, 1, 1, 1, 599040, 0x83120d87
+0, 2, 2, 1, 599040, 0x10c267aa
+0, 3, 3, 1, 599040, 0xef591aef
+0, 4, 4, 1, 599040, 0xded62c79
+0, 5, 5, 1, 599040, 0xe7c1c748
+0, 6, 6, 1, 599040, 0x14db55d0
+0, 7, 7, 1, 599040, 0x73c4156b
+0, 8, 8, 1, 599040, 0x0cec903c
+0, 9, 9, 1, 599040, 0x791029a0
+0, 10, 10, 1, 599040, 0x0fe72908
+0, 11, 11, 1, 599040, 0xd0ebe0be
+0, 12, 12, 1, 599040, 0x473cb5aa
+0, 13, 13, 1, 599040, 0xe774cf8c
+0, 14, 14, 1, 599040, 0x3d63909f
+0, 15, 15, 1, 599040, 0xe05af465
+0, 16, 16, 1, 599040, 0x9679aa54
+0, 17, 17, 1, 599040, 0xe9d2ef49
+0, 18, 18, 1, 599040, 0x1e797cac
+0, 19, 19, 1, 599040, 0xf3d51077
+0, 20, 20, 1, 599040, 0x74e3b5e0
+0, 21, 21, 1, 599040, 0xb97e5178
+0, 22, 22, 1, 599040, 0x7c79a425
+0, 23, 23, 1, 599040, 0xfeeedb62
+0, 24, 24, 1, 599040, 0x8d5a3686
+0, 25, 25, 1, 599040, 0x3f6109e4
+0, 26, 26, 1, 599040, 0x365df50e
+0, 27, 27, 1, 599040, 0xd65876a1
+0, 28, 28, 1, 599040, 0xfa21e766
+0, 29, 29, 1, 599040, 0x2f24ed68
+0, 30, 30, 1, 599040, 0x0e90e5d4
+0, 31, 31, 1, 599040, 0xd044eb9c
+0, 32, 32, 1, 599040, 0xe55e8b18
+0, 33, 33, 1, 599040, 0xa92b93b6
+0, 34, 34, 1, 599040, 0x9b6827c6
+0, 35, 35, 1, 599040, 0x486e155b
+0, 36, 36, 1, 599040, 0xbff46adc
+0, 37, 37, 1, 599040, 0x61637615
+0, 38, 38, 1, 599040, 0xc0423ea9
+0, 39, 39, 1, 599040, 0xda80f8d8
+0, 40, 40, 1, 599040, 0xe0f77fcc
+0, 41, 41, 1, 599040, 0x68bef4cf
+0, 42, 42, 1, 599040, 0xd2e0699b
+0, 43, 43, 1, 599040, 0xcc6cd663
+0, 44, 44, 1, 599040, 0x00ed2594
+0, 45, 45, 1, 599040, 0x140b6efb
+0, 46, 46, 1, 599040, 0xa418f9d0
+0, 47, 47, 1, 599040, 0x500083a3
+0, 48, 48, 1, 599040, 0x619045ec
+0, 49, 49, 1, 599040, 0xdf0ce1e6
diff --git a/tests/ref/fate/hevc-conformance-CAINIT_B_SHARP_4 b/tests/ref/fate/hevc-conformance-CAINIT_B_SHARP_4
new file mode 100644
index 0000000..9aeb3b1
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-CAINIT_B_SHARP_4
@@ -0,0 +1,51 @@
+#tb 0: 1/25
+0, 0, 0, 1, 599040, 0x001f0c48
+0, 1, 1, 1, 599040, 0xf8160d82
+0, 2, 2, 1, 599040, 0x5f2060e2
+0, 3, 3, 1, 599040, 0x421104a7
+0, 4, 4, 1, 599040, 0xded62c79
+0, 5, 5, 1, 599040, 0x782b4517
+0, 6, 6, 1, 599040, 0xcf47861d
+0, 7, 7, 1, 599040, 0xd401373c
+0, 8, 8, 1, 599040, 0x0cec903c
+0, 9, 9, 1, 599040, 0x2dec6230
+0, 10, 10, 1, 599040, 0xe8d25791
+0, 11, 11, 1, 599040, 0x243af0ad
+0, 12, 12, 1, 599040, 0x4f77c47b
+0, 13, 13, 1, 599040, 0x9777f7c4
+0, 14, 14, 1, 599040, 0xc5c5be51
+0, 15, 15, 1, 599040, 0xb9b27b63
+0, 16, 16, 1, 599040, 0xc333f76b
+0, 17, 17, 1, 599040, 0x6bd00f09
+0, 18, 18, 1, 599040, 0x7f76875d
+0, 19, 19, 1, 599040, 0xc9e80bec
+0, 20, 20, 1, 599040, 0x8681b48f
+0, 21, 21, 1, 599040, 0xefaa5077
+0, 22, 22, 1, 599040, 0x73cc72a4
+0, 23, 23, 1, 599040, 0x55c8bc27
+0, 24, 24, 1, 599040, 0x9d84419d
+0, 25, 25, 1, 599040, 0x89db2dfe
+0, 26, 26, 1, 599040, 0x39a012fe
+0, 27, 27, 1, 599040, 0x9ae88b01
+0, 28, 28, 1, 599040, 0x0928f3d0
+0, 29, 29, 1, 599040, 0x39359eb1
+0, 30, 30, 1, 599040, 0x3e00a5b5
+0, 31, 31, 1, 599040, 0xaf1b1809
+0, 32, 32, 1, 599040, 0xe55e8b18
+0, 33, 33, 1, 599040, 0xa4739b3d
+0, 34, 34, 1, 599040, 0x224d47d4
+0, 35, 35, 1, 599040, 0x3ce1d830
+0, 36, 36, 1, 599040, 0xd3b33990
+0, 37, 37, 1, 599040, 0x15c3ae0e
+0, 38, 38, 1, 599040, 0xcce735aa
+0, 39, 39, 1, 599040, 0x173d8406
+0, 40, 40, 1, 599040, 0xe0f77fcc
+0, 41, 41, 1, 599040, 0xbeefe9eb
+0, 42, 42, 1, 599040, 0xb3d761cf
+0, 43, 43, 1, 599040, 0x75ffe5f0
+0, 44, 44, 1, 599040, 0xf446226e
+0, 45, 45, 1, 599040, 0xf425475a
+0, 46, 46, 1, 599040, 0x5180ee65
+0, 47, 47, 1, 599040, 0x5edb78f9
+0, 48, 48, 1, 599040, 0x28eb41c5
+0, 49, 49, 1, 599040, 0x0d65d9d3
diff --git a/tests/ref/fate/hevc-conformance-CAINIT_C_SHARP_3 b/tests/ref/fate/hevc-conformance-CAINIT_C_SHARP_3
new file mode 100644
index 0000000..c891c44
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-CAINIT_C_SHARP_3
@@ -0,0 +1,51 @@
+#tb 0: 1/25
+0, 0, 0, 1, 599040, 0x2b58dee2
+0, 1, 1, 1, 599040, 0x2b58dee2
+0, 2, 2, 1, 599040, 0xcd9295f4
+0, 3, 3, 1, 599040, 0xc052f81f
+0, 4, 4, 1, 599040, 0xfe5932ed
+0, 5, 5, 1, 599040, 0x8a8aa4b9
+0, 6, 6, 1, 599040, 0x6ac33b24
+0, 7, 7, 1, 599040, 0xd053bb83
+0, 8, 8, 1, 599040, 0xa9cf6ba6
+0, 9, 9, 1, 599040, 0x3d5a1a3b
+0, 10, 10, 1, 599040, 0x90997f48
+0, 11, 11, 1, 599040, 0xc99390bd
+0, 12, 12, 1, 599040, 0x9723079d
+0, 13, 13, 1, 599040, 0x7f0fe29b
+0, 14, 14, 1, 599040, 0x778afdb4
+0, 15, 15, 1, 599040, 0x72963905
+0, 16, 16, 1, 599040, 0xa677b29c
+0, 17, 17, 1, 599040, 0x88bdccd8
+0, 18, 18, 1, 599040, 0x8be37199
+0, 19, 19, 1, 599040, 0x6628117a
+0, 20, 20, 1, 599040, 0xefa701b0
+0, 21, 21, 1, 599040, 0x75d6705d
+0, 22, 22, 1, 599040, 0x85242d6f
+0, 23, 23, 1, 599040, 0xd559eaa6
+0, 24, 24, 1, 599040, 0xe0663879
+0, 25, 25, 1, 599040, 0x3255d67c
+0, 26, 26, 1, 599040, 0xf41a4d73
+0, 27, 27, 1, 599040, 0xda630d57
+0, 28, 28, 1, 599040, 0x7b8eec79
+0, 29, 29, 1, 599040, 0x70dff7a6
+0, 30, 30, 1, 599040, 0x4b600806
+0, 31, 31, 1, 599040, 0xdcbbc54d
+0, 32, 32, 1, 599040, 0x7e6e66b4
+0, 33, 33, 1, 599040, 0x645ce246
+0, 34, 34, 1, 599040, 0x03d3117c
+0, 35, 35, 1, 599040, 0x7c3cab88
+0, 36, 36, 1, 599040, 0x5cdaeeef
+0, 37, 37, 1, 599040, 0x4cce6d93
+0, 38, 38, 1, 599040, 0x78c28e4c
+0, 39, 39, 1, 599040, 0x8acbe642
+0, 40, 40, 1, 599040, 0xcd0a39f8
+0, 41, 41, 1, 599040, 0x9c580311
+0, 42, 42, 1, 599040, 0x668eab11
+0, 43, 43, 1, 599040, 0xc76f6206
+0, 44, 44, 1, 599040, 0xe0baf2a2
+0, 45, 45, 1, 599040, 0x430db206
+0, 46, 46, 1, 599040, 0x9c1565ad
+0, 47, 47, 1, 599040, 0xfc302be0
+0, 48, 48, 1, 599040, 0x6ccfc206
+0, 49, 49, 1, 599040, 0x46c7722d
diff --git a/tests/ref/fate/hevc-conformance-CAINIT_D_SHARP_3 b/tests/ref/fate/hevc-conformance-CAINIT_D_SHARP_3
new file mode 100644
index 0000000..0294a7e
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-CAINIT_D_SHARP_3
@@ -0,0 +1,51 @@
+#tb 0: 1/25
+0, 0, 0, 1, 599040, 0x2b58dee2
+0, 1, 1, 1, 599040, 0x2b58dee2
+0, 2, 2, 1, 599040, 0xb055b638
+0, 3, 3, 1, 599040, 0x3e2b06c9
+0, 4, 4, 1, 599040, 0xa0e53610
+0, 5, 5, 1, 599040, 0x5f6eca50
+0, 6, 6, 1, 599040, 0x516e679d
+0, 7, 7, 1, 599040, 0xdbbbf791
+0, 8, 8, 1, 599040, 0x04be5abc
+0, 9, 9, 1, 599040, 0x85283636
+0, 10, 10, 1, 599040, 0x1bcdb857
+0, 11, 11, 1, 599040, 0x258bb8a8
+0, 12, 12, 1, 599040, 0x33340003
+0, 13, 13, 1, 599040, 0xa2cc0dc3
+0, 14, 14, 1, 599040, 0x2b83400f
+0, 15, 15, 1, 599040, 0xf33ba886
+0, 16, 16, 1, 599040, 0x73f43f10
+0, 17, 17, 1, 599040, 0x63ff4628
+0, 18, 18, 1, 599040, 0x41170243
+0, 19, 19, 1, 599040, 0x84f34b72
+0, 20, 20, 1, 599040, 0x4913e415
+0, 21, 21, 1, 599040, 0x38cfaac3
+0, 22, 22, 1, 599040, 0xb2f0650c
+0, 23, 23, 1, 599040, 0xe0d12249
+0, 24, 24, 1, 599040, 0xca931ca0
+0, 25, 25, 1, 599040, 0xfc14d1cb
+0, 26, 26, 1, 599040, 0xb74667d8
+0, 27, 27, 1, 599040, 0xfdc22b8b
+0, 28, 28, 1, 599040, 0x30b425eb
+0, 29, 29, 1, 599040, 0xc31f3b73
+0, 30, 30, 1, 599040, 0xefda0062
+0, 31, 31, 1, 599040, 0x8fe0d742
+0, 32, 32, 1, 599040, 0xdaa54d1d
+0, 33, 33, 1, 599040, 0x2188ae4b
+0, 34, 34, 1, 599040, 0x7ef0f088
+0, 35, 35, 1, 599040, 0xcfd2619f
+0, 36, 36, 1, 599040, 0x3b0fca50
+0, 37, 37, 1, 599040, 0x78746df2
+0, 38, 38, 1, 599040, 0xdc917e1b
+0, 39, 39, 1, 599040, 0xc6cf2732
+0, 40, 40, 1, 599040, 0xdbd2f5f2
+0, 41, 41, 1, 599040, 0x45a8cba3
+0, 42, 42, 1, 599040, 0xe276b712
+0, 43, 43, 1, 599040, 0x36057004
+0, 44, 44, 1, 599040, 0xe0da7e77
+0, 45, 45, 1, 599040, 0x823e7c30
+0, 46, 46, 1, 599040, 0x62c9457a
+0, 47, 47, 1, 599040, 0xf6743a30
+0, 48, 48, 1, 599040, 0x8db4f476
+0, 49, 49, 1, 599040, 0x79537927
diff --git a/tests/ref/fate/hevc-conformance-CAINIT_E_SHARP_3 b/tests/ref/fate/hevc-conformance-CAINIT_E_SHARP_3
new file mode 100644
index 0000000..430426b
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-CAINIT_E_SHARP_3
@@ -0,0 +1,51 @@
+#tb 0: 1/25
+0, 0, 0, 1, 599040, 0x1cf21d79
+0, 1, 1, 1, 599040, 0x1cf21d79
+0, 2, 2, 1, 599040, 0xb54ee9e0
+0, 3, 3, 1, 599040, 0x757f33f0
+0, 4, 4, 1, 599040, 0x783e06bc
+0, 5, 5, 1, 599040, 0x73127ae7
+0, 6, 6, 1, 599040, 0x52f86193
+0, 7, 7, 1, 599040, 0x8e8afa2c
+0, 8, 8, 1, 599040, 0x29359620
+0, 9, 9, 1, 599040, 0x23f46fd3
+0, 10, 10, 1, 599040, 0x00c9d47d
+0, 11, 11, 1, 599040, 0xcabcca8d
+0, 12, 12, 1, 599040, 0x02e92d89
+0, 13, 13, 1, 599040, 0x3e97268f
+0, 14, 14, 1, 599040, 0xba6230c2
+0, 15, 15, 1, 599040, 0x4393aa3b
+0, 16, 16, 1, 599040, 0x06b1b9c8
+0, 17, 17, 1, 599040, 0xcc2aa30b
+0, 18, 18, 1, 599040, 0x3e029a11
+0, 19, 19, 1, 599040, 0x0ec1fc36
+0, 20, 20, 1, 599040, 0xd61dd438
+0, 21, 21, 1, 599040, 0xa7b1816b
+0, 22, 22, 1, 599040, 0xa98ef225
+0, 23, 23, 1, 599040, 0x368912ca
+0, 24, 24, 1, 599040, 0x1ae95cbe
+0, 25, 25, 1, 599040, 0x0e01f8ed
+0, 26, 26, 1, 599040, 0x05497937
+0, 27, 27, 1, 599040, 0x735c2420
+0, 28, 28, 1, 599040, 0x0ef80004
+0, 29, 29, 1, 599040, 0xd744091b
+0, 30, 30, 1, 599040, 0x0f3b1576
+0, 31, 31, 1, 599040, 0x24e4fab9
+0, 32, 32, 1, 599040, 0x6b5d7fca
+0, 33, 33, 1, 599040, 0x2afcdaec
+0, 34, 34, 1, 599040, 0x39dfd5b6
+0, 35, 35, 1, 599040, 0xe5844f4e
+0, 36, 36, 1, 599040, 0xf26920d9
+0, 37, 37, 1, 599040, 0x8feb56e2
+0, 38, 38, 1, 599040, 0x6433712f
+0, 39, 39, 1, 599040, 0xba311758
+0, 40, 40, 1, 599040, 0x09f87643
+0, 41, 41, 1, 599040, 0x68562c28
+0, 42, 42, 1, 599040, 0x9465e267
+0, 43, 43, 1, 599040, 0x03e2802f
+0, 44, 44, 1, 599040, 0xa61ed250
+0, 45, 45, 1, 599040, 0x5ab680db
+0, 46, 46, 1, 599040, 0xc4663840
+0, 47, 47, 1, 599040, 0xefe83a4f
+0, 48, 48, 1, 599040, 0x7bfb4ecd
+0, 49, 49, 1, 599040, 0xcafdbfd0
diff --git a/tests/ref/fate/hevc-conformance-CAINIT_F_SHARP_3 b/tests/ref/fate/hevc-conformance-CAINIT_F_SHARP_3
new file mode 100644
index 0000000..aeba53b
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-CAINIT_F_SHARP_3
@@ -0,0 +1,51 @@
+#tb 0: 1/25
+0, 0, 0, 1, 599040, 0x1cf21d79
+0, 1, 1, 1, 599040, 0x1cf21d79
+0, 2, 2, 1, 599040, 0xc182eaa8
+0, 3, 3, 1, 599040, 0x260358ee
+0, 4, 4, 1, 599040, 0x381e5b16
+0, 5, 5, 1, 599040, 0x329dacd8
+0, 6, 6, 1, 599040, 0x7306d51c
+0, 7, 7, 1, 599040, 0x869d359b
+0, 8, 8, 1, 599040, 0xf8fc941a
+0, 9, 9, 1, 599040, 0x0798842b
+0, 10, 10, 1, 599040, 0xe6e1f54e
+0, 11, 11, 1, 599040, 0xc7d5ba9e
+0, 12, 12, 1, 599040, 0xc8c5507a
+0, 13, 13, 1, 599040, 0x97ae604a
+0, 14, 14, 1, 599040, 0x14dd4139
+0, 15, 15, 1, 599040, 0xb2f998dc
+0, 16, 16, 1, 599040, 0xc3a3a6bc
+0, 17, 17, 1, 599040, 0x1f95be77
+0, 18, 18, 1, 599040, 0xb7fd124b
+0, 19, 19, 1, 599040, 0x25703b3c
+0, 20, 20, 1, 599040, 0x3bddeba7
+0, 21, 21, 1, 599040, 0xffcc9b6d
+0, 22, 22, 1, 599040, 0x3dd66a0a
+0, 23, 23, 1, 599040, 0xe9607af7
+0, 24, 24, 1, 599040, 0x218cdc65
+0, 25, 25, 1, 599040, 0x88f97761
+0, 26, 26, 1, 599040, 0x62e1f5d4
+0, 27, 27, 1, 599040, 0xcc3cd429
+0, 28, 28, 1, 599040, 0xb4290272
+0, 29, 29, 1, 599040, 0x4f73142c
+0, 30, 30, 1, 599040, 0x753eefd9
+0, 31, 31, 1, 599040, 0xea77e837
+0, 32, 32, 1, 599040, 0xfa927e55
+0, 33, 33, 1, 599040, 0x3dff1295
+0, 34, 34, 1, 599040, 0x513c2088
+0, 35, 35, 1, 599040, 0x9822b7f0
+0, 36, 36, 1, 599040, 0xc4770af6
+0, 37, 37, 1, 599040, 0x7cb576fb
+0, 38, 38, 1, 599040, 0x2af8ca3a
+0, 39, 39, 1, 599040, 0x0a324910
+0, 40, 40, 1, 599040, 0x1aeb3d7a
+0, 41, 41, 1, 599040, 0x82de1408
+0, 42, 42, 1, 599040, 0x7ebad7f4
+0, 43, 43, 1, 599040, 0xd100bcc1
+0, 44, 44, 1, 599040, 0x4719dc40
+0, 45, 45, 1, 599040, 0xd82f658b
+0, 46, 46, 1, 599040, 0x8c596a54
+0, 47, 47, 1, 599040, 0xd0b4572c
+0, 48, 48, 1, 599040, 0xdc3c5a89
+0, 49, 49, 1, 599040, 0x4f0ad888
diff --git a/tests/ref/fate/hevc-conformance-CAINIT_G_SHARP_3 b/tests/ref/fate/hevc-conformance-CAINIT_G_SHARP_3
new file mode 100644
index 0000000..e0501be
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-CAINIT_G_SHARP_3
@@ -0,0 +1,51 @@
+#tb 0: 1/25
+0, 0, 0, 1, 599040, 0xd9b73cbe
+0, 1, 1, 1, 599040, 0xd9b73cbe
+0, 2, 2, 1, 599040, 0xe4e5dd7c
+0, 3, 3, 1, 599040, 0xa7333d7e
+0, 4, 4, 1, 599040, 0x6b82552b
+0, 5, 5, 1, 599040, 0x4f02e2a4
+0, 6, 6, 1, 599040, 0x8fdcc50a
+0, 7, 7, 1, 599040, 0x2481542d
+0, 8, 8, 1, 599040, 0x73d0dfad
+0, 9, 9, 1, 599040, 0x842b8cd2
+0, 10, 10, 1, 599040, 0x87b3a3b2
+0, 11, 11, 1, 599040, 0xe4decf78
+0, 12, 12, 1, 599040, 0xfba7dd51
+0, 13, 13, 1, 599040, 0x3dc1e85c
+0, 14, 14, 1, 599040, 0xea8a4987
+0, 15, 15, 1, 599040, 0xa3cc5c8c
+0, 16, 16, 1, 599040, 0x10a09cd8
+0, 17, 17, 1, 599040, 0x6739c5f7
+0, 18, 18, 1, 599040, 0x819af14a
+0, 19, 19, 1, 599040, 0xe9d65a5c
+0, 20, 20, 1, 599040, 0x09def54e
+0, 21, 21, 1, 599040, 0x8595aa5d
+0, 22, 22, 1, 599040, 0xc3f134d7
+0, 23, 23, 1, 599040, 0xdac9496a
+0, 24, 24, 1, 599040, 0x760f0897
+0, 25, 25, 1, 599040, 0x8daddaf5
+0, 26, 26, 1, 599040, 0xed313947
+0, 27, 27, 1, 599040, 0xc875ed4d
+0, 28, 28, 1, 599040, 0xdb5d0b3b
+0, 29, 29, 1, 599040, 0x7cbc0e6a
+0, 30, 30, 1, 599040, 0x193bbc9f
+0, 31, 31, 1, 599040, 0x4f20d599
+0, 32, 32, 1, 599040, 0x09e545e8
+0, 33, 33, 1, 599040, 0x0637d524
+0, 34, 34, 1, 599040, 0x11a3bd85
+0, 35, 35, 1, 599040, 0x304155ce
+0, 36, 36, 1, 599040, 0x6636291b
+0, 37, 37, 1, 599040, 0xc4039e80
+0, 38, 38, 1, 599040, 0xd73ca756
+0, 39, 39, 1, 599040, 0x96a68426
+0, 40, 40, 1, 599040, 0xd945391c
+0, 41, 41, 1, 599040, 0x95a83264
+0, 42, 42, 1, 599040, 0x6356a243
+0, 43, 43, 1, 599040, 0xb9b8973e
+0, 44, 44, 1, 599040, 0xf361d0d9
+0, 45, 45, 1, 599040, 0x2783b0e2
+0, 46, 46, 1, 599040, 0x870ac424
+0, 47, 47, 1, 599040, 0xa8397c01
+0, 48, 48, 1, 599040, 0xf1bc2ac0
+0, 49, 49, 1, 599040, 0x82fbb428
diff --git a/tests/ref/fate/hevc-conformance-CAINIT_H_SHARP_3 b/tests/ref/fate/hevc-conformance-CAINIT_H_SHARP_3
new file mode 100644
index 0000000..01ab258
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-CAINIT_H_SHARP_3
@@ -0,0 +1,51 @@
+#tb 0: 1/25
+0, 0, 0, 1, 599040, 0xd9b73cbe
+0, 1, 1, 1, 599040, 0xd9b73cbe
+0, 2, 2, 1, 599040, 0x93a3fabf
+0, 3, 3, 1, 599040, 0x245a522e
+0, 4, 4, 1, 599040, 0xff1e8bb4
+0, 5, 5, 1, 599040, 0x03390b9a
+0, 6, 6, 1, 599040, 0x27030635
+0, 7, 7, 1, 599040, 0x431c6312
+0, 8, 8, 1, 599040, 0xeddc5f83
+0, 9, 9, 1, 599040, 0x34168a1e
+0, 10, 10, 1, 599040, 0xf4d795a4
+0, 11, 11, 1, 599040, 0xe716ea67
+0, 12, 12, 1, 599040, 0xf3b8446d
+0, 13, 13, 1, 599040, 0x082d12d0
+0, 14, 14, 1, 599040, 0x68e12e99
+0, 15, 15, 1, 599040, 0x3fd079df
+0, 16, 16, 1, 599040, 0x6087fb37
+0, 17, 17, 1, 599040, 0x12c2142e
+0, 18, 18, 1, 599040, 0xb3bcf682
+0, 19, 19, 1, 599040, 0xcec84ee7
+0, 20, 20, 1, 599040, 0x12a4fb43
+0, 21, 21, 1, 599040, 0x85749580
+0, 22, 22, 1, 599040, 0x6df99536
+0, 23, 23, 1, 599040, 0x377282a6
+0, 24, 24, 1, 599040, 0xe296f874
+0, 25, 25, 1, 599040, 0x1b29cd1a
+0, 26, 26, 1, 599040, 0x1cf633c9
+0, 27, 27, 1, 599040, 0xf8cd2544
+0, 28, 28, 1, 599040, 0x61c05325
+0, 29, 29, 1, 599040, 0x87646c89
+0, 30, 30, 1, 599040, 0x5b840711
+0, 31, 31, 1, 599040, 0x5bc4c181
+0, 32, 32, 1, 599040, 0x91ce695a
+0, 33, 33, 1, 599040, 0xed54dcca
+0, 34, 34, 1, 599040, 0xc41fef8e
+0, 35, 35, 1, 599040, 0x9da8830b
+0, 36, 36, 1, 599040, 0xb76cec12
+0, 37, 37, 1, 599040, 0xef9661f0
+0, 38, 38, 1, 599040, 0xe1d38227
+0, 39, 39, 1, 599040, 0xce440134
+0, 40, 40, 1, 599040, 0x41a54dd1
+0, 41, 41, 1, 599040, 0xdd83da8e
+0, 42, 42, 1, 599040, 0xf9cee595
+0, 43, 43, 1, 599040, 0x6f5db54d
+0, 44, 44, 1, 599040, 0x00b6f064
+0, 45, 45, 1, 599040, 0xfbaa978d
+0, 46, 46, 1, 599040, 0x2c9ee1d7
+0, 47, 47, 1, 599040, 0xe8c4be1f
+0, 48, 48, 1, 599040, 0x132a260f
+0, 49, 49, 1, 599040, 0x8571a213
diff --git a/tests/ref/fate/hevc-conformance-CIP_A_Panasonic_3 b/tests/ref/fate/hevc-conformance-CIP_A_Panasonic_3
new file mode 100644
index 0000000..afa4854
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-CIP_A_Panasonic_3
@@ -0,0 +1,3 @@
+#tb 0: 1/25
+0, 0, 0, 1, 149760, 0x6e1f16d0
+0, 1, 1, 1, 149760, 0x5be5bde9
diff --git a/tests/ref/fate/hevc-conformance-CIP_C_Panasonic_2 b/tests/ref/fate/hevc-conformance-CIP_C_Panasonic_2
new file mode 100644
index 0000000..3346e20
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-CIP_C_Panasonic_2
@@ -0,0 +1,3 @@
+#tb 0: 1/25
+0, 0, 0, 1, 149760, 0xcd1019b2
+0, 1, 1, 1, 149760, 0xeb39efeb
diff --git a/tests/ref/fate/hevc-conformance-DBLK_A_MAIN10_VIXS_2 b/tests/ref/fate/hevc-conformance-DBLK_A_MAIN10_VIXS_2
new file mode 100644
index 0000000..50be4f1
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-DBLK_A_MAIN10_VIXS_2
@@ -0,0 +1,9 @@
+#tb 0: 1/25
+0, 0, 0, 1, 76032, 0x4313935b
+0, 1, 1, 1, 76032, 0x4c8071b5
+0, 2, 2, 1, 76032, 0x5e627edc
+0, 3, 3, 1, 76032, 0xb51a996d
+0, 4, 4, 1, 76032, 0x77d1800b
+0, 5, 5, 1, 76032, 0x4fb9bf3f
+0, 6, 6, 1, 76032, 0x838f8c05
+0, 7, 7, 1, 76032, 0xa87aabb6
diff --git a/tests/ref/fate/hevc-conformance-DBLK_A_SONY_3 b/tests/ref/fate/hevc-conformance-DBLK_A_SONY_3
new file mode 100644
index 0000000..589cbf3
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-DBLK_A_SONY_3
@@ -0,0 +1,31 @@
+#tb 0: 1/25
+0, 0, 0, 1, 599040, 0x154e6dd9
+0, 1, 1, 1, 599040, 0xcce25693
+0, 2, 2, 1, 599040, 0x3dd84e88
+0, 3, 3, 1, 599040, 0xca197027
+0, 4, 4, 1, 599040, 0xc9af0241
+0, 5, 5, 1, 599040, 0x510470de
+0, 6, 6, 1, 599040, 0xac8c0a7c
+0, 7, 7, 1, 599040, 0x04cbed5e
+0, 8, 8, 1, 599040, 0x514ce2f1
+0, 9, 9, 1, 599040, 0xf37a4eec
+0, 10, 10, 1, 599040, 0xabfd7f2f
+0, 11, 11, 1, 599040, 0x944458a1
+0, 12, 12, 1, 599040, 0xf4f81db2
+0, 13, 13, 1, 599040, 0xdde236fb
+0, 14, 14, 1, 599040, 0x6b0132be
+0, 15, 15, 1, 599040, 0x641683a3
+0, 16, 16, 1, 599040, 0x81d6be90
+0, 17, 17, 1, 599040, 0xf1e04e55
+0, 18, 18, 1, 599040, 0x63c4dc0a
+0, 19, 19, 1, 599040, 0x47170db8
+0, 20, 20, 1, 599040, 0xdc22f27b
+0, 21, 21, 1, 599040, 0xd5b63800
+0, 22, 22, 1, 599040, 0x07b76936
+0, 23, 23, 1, 599040, 0x5215eee2
+0, 24, 24, 1, 599040, 0xb5b2c9b1
+0, 25, 25, 1, 599040, 0x79bee732
+0, 26, 26, 1, 599040, 0x14c1f436
+0, 27, 27, 1, 599040, 0x384f7f05
+0, 28, 28, 1, 599040, 0x44229c42
+0, 29, 29, 1, 599040, 0x5dea88e9
diff --git a/tests/ref/fate/hevc-conformance-DBLK_B_SONY_3 b/tests/ref/fate/hevc-conformance-DBLK_B_SONY_3
new file mode 100644
index 0000000..077b38e
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-DBLK_B_SONY_3
@@ -0,0 +1,31 @@
+#tb 0: 1/25
+0, 0, 0, 1, 599040, 0xda0cb5d4
+0, 1, 1, 1, 599040, 0x352bc397
+0, 2, 2, 1, 599040, 0x72bc28fe
+0, 3, 3, 1, 599040, 0x22294f68
+0, 4, 4, 1, 599040, 0x1f6415a7
+0, 5, 5, 1, 599040, 0xa9f6b0d7
+0, 6, 6, 1, 599040, 0x6b7c1f2d
+0, 7, 7, 1, 599040, 0xb93857f5
+0, 8, 8, 1, 599040, 0xb0d752d3
+0, 9, 9, 1, 599040, 0x0622e689
+0, 10, 10, 1, 599040, 0x23d8780a
+0, 11, 11, 1, 599040, 0x4844581b
+0, 12, 12, 1, 599040, 0x791322f9
+0, 13, 13, 1, 599040, 0x82f6cf43
+0, 14, 14, 1, 599040, 0xcace3aba
+0, 15, 15, 1, 599040, 0x68a68427
+0, 16, 16, 1, 599040, 0x23fa500a
+0, 17, 17, 1, 599040, 0x7d78b77d
+0, 18, 18, 1, 599040, 0x8d295032
+0, 19, 19, 1, 599040, 0x16fa266c
+0, 20, 20, 1, 599040, 0x37d8173b
+0, 21, 21, 1, 599040, 0x8a4f90e1
+0, 22, 22, 1, 599040, 0x40f98f6d
+0, 23, 23, 1, 599040, 0xc060b193
+0, 24, 24, 1, 599040, 0xa53c3bc1
+0, 25, 25, 1, 599040, 0x5a9556d6
+0, 26, 26, 1, 599040, 0x37582393
+0, 27, 27, 1, 599040, 0x376acd14
+0, 28, 28, 1, 599040, 0x81ee1e64
+0, 29, 29, 1, 599040, 0xff2a600c
diff --git a/tests/ref/fate/hevc-conformance-DBLK_C_SONY_3 b/tests/ref/fate/hevc-conformance-DBLK_C_SONY_3
new file mode 100644
index 0000000..823988d
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-DBLK_C_SONY_3
@@ -0,0 +1,31 @@
+#tb 0: 1/25
+0, 0, 0, 1, 599040, 0x57369bf4
+0, 1, 1, 1, 599040, 0x319aab9c
+0, 2, 2, 1, 599040, 0xbc1b7698
+0, 3, 3, 1, 599040, 0x05cea248
+0, 4, 4, 1, 599040, 0xdca73743
+0, 5, 5, 1, 599040, 0x5b5a9f70
+0, 6, 6, 1, 599040, 0x16c51b34
+0, 7, 7, 1, 599040, 0x734fe724
+0, 8, 8, 1, 599040, 0x48e4e0ba
+0, 9, 9, 1, 599040, 0xf1423cc1
+0, 10, 10, 1, 599040, 0xb4bb68b1
+0, 11, 11, 1, 599040, 0x54a77ad6
+0, 12, 12, 1, 599040, 0x6e0dfce3
+0, 13, 13, 1, 599040, 0x7ca687e3
+0, 14, 14, 1, 599040, 0xf9ac2443
+0, 15, 15, 1, 599040, 0xe35b8d34
+0, 16, 16, 1, 599040, 0xef4bbe9f
+0, 17, 17, 1, 599040, 0x21eb418e
+0, 18, 18, 1, 599040, 0xae6df30f
+0, 19, 19, 1, 599040, 0x743500af
+0, 20, 20, 1, 599040, 0x7fba1ce1
+0, 21, 21, 1, 599040, 0x45793eae
+0, 22, 22, 1, 599040, 0x1f7e3467
+0, 23, 23, 1, 599040, 0x7400c7c3
+0, 24, 24, 1, 599040, 0xcf79806d
+0, 25, 25, 1, 599040, 0x324ea91d
+0, 26, 26, 1, 599040, 0x9c8cae92
+0, 27, 27, 1, 599040, 0x70bfc368
+0, 28, 28, 1, 599040, 0x46a0f8ff
+0, 29, 29, 1, 599040, 0xd864208a
diff --git a/tests/ref/fate/hevc-conformance-DBLK_D_VIXS_1 b/tests/ref/fate/hevc-conformance-DBLK_D_VIXS_1
new file mode 100644
index 0000000..3d9e43b
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-DBLK_D_VIXS_1
@@ -0,0 +1,9 @@
+#tb 0: 1/25
+0, 0, 0, 1, 1382400, 0x6ef5c76e
+0, 1, 1, 1, 1382400, 0x975238be
+0, 2, 2, 1, 1382400, 0xe5529a79
+0, 3, 3, 1, 1382400, 0x639641d4
+0, 4, 4, 1, 1382400, 0x566eb1df
+0, 5, 5, 1, 1382400, 0x4fd4b46a
+0, 6, 6, 1, 1382400, 0xfb4a6a0e
+0, 7, 7, 1, 1382400, 0x4485af32
diff --git a/tests/ref/fate/hevc-conformance-DBLK_D_VIXS_2 b/tests/ref/fate/hevc-conformance-DBLK_D_VIXS_2
new file mode 100644
index 0000000..2bdc548
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-DBLK_D_VIXS_2
@@ -0,0 +1,9 @@
+#tb 0: 1/25
+0, 0, 0, 1, 1382400, 0x6ef5c76e
+0, 1, 1, 1, 1382400, 0x1e1926b1
+0, 2, 2, 1, 1382400, 0x69888786
+0, 3, 3, 1, 1382400, 0x1f193659
+0, 4, 4, 1, 1382400, 0x566eb1df
+0, 5, 5, 1, 1382400, 0x49b3a668
+0, 6, 6, 1, 1382400, 0x1b774ed8
+0, 7, 7, 1, 1382400, 0x2296a2bc
diff --git a/tests/ref/fate/hevc-conformance-DBLK_E_VIXS_1 b/tests/ref/fate/hevc-conformance-DBLK_E_VIXS_1
new file mode 100644
index 0000000..c3ebaf2
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-DBLK_E_VIXS_1
@@ -0,0 +1,9 @@
+#tb 0: 1/25
+0, 0, 0, 1, 1382400, 0x7119bbe5
+0, 1, 1, 1, 1382400, 0xbeda2c83
+0, 2, 2, 1, 1382400, 0x2cbe6669
+0, 3, 3, 1, 1382400, 0x3cee2619
+0, 4, 4, 1, 1382400, 0x93e388e3
+0, 5, 5, 1, 1382400, 0x5e286889
+0, 6, 6, 1, 1382400, 0x4718f29c
+0, 7, 7, 1, 1382400, 0xbedf4dbd
diff --git a/tests/ref/fate/hevc-conformance-DBLK_E_VIXS_2 b/tests/ref/fate/hevc-conformance-DBLK_E_VIXS_2
new file mode 100644
index 0000000..4c8b07d
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-DBLK_E_VIXS_2
@@ -0,0 +1,9 @@
+#tb 0: 1/25
+0, 0, 0, 1, 1382400, 0xecfdf606
+0, 1, 1, 1, 1382400, 0x0b0382e1
+0, 2, 2, 1, 1382400, 0xbef3afd6
+0, 3, 3, 1, 1382400, 0x6a2bcabb
+0, 4, 4, 1, 1382400, 0x663f991c
+0, 5, 5, 1, 1382400, 0xb49b94d8
+0, 6, 6, 1, 1382400, 0x07399433
+0, 7, 7, 1, 1382400, 0x9cca09df
diff --git a/tests/ref/fate/hevc-conformance-DBLK_F_VIXS_1 b/tests/ref/fate/hevc-conformance-DBLK_F_VIXS_1
new file mode 100644
index 0000000..59f51ef
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-DBLK_F_VIXS_1
@@ -0,0 +1,9 @@
+#tb 0: 1/25
+0, 0, 0, 1, 1382400, 0xea27f7bd
+0, 1, 1, 1, 1382400, 0xce3d7b4c
+0, 2, 2, 1, 1382400, 0xaea4970e
+0, 3, 3, 1, 1382400, 0xcbc7c89f
+0, 4, 4, 1, 1382400, 0xe5367019
+0, 5, 5, 1, 1382400, 0xb92ca18e
+0, 6, 6, 1, 1382400, 0xde046be1
+0, 7, 7, 1, 1382400, 0x1ae6e393
diff --git a/tests/ref/fate/hevc-conformance-DBLK_F_VIXS_2 b/tests/ref/fate/hevc-conformance-DBLK_F_VIXS_2
new file mode 100644
index 0000000..3ff62e5
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-DBLK_F_VIXS_2
@@ -0,0 +1,9 @@
+#tb 0: 1/25
+0, 0, 0, 1, 1382400, 0xea27f7bd
+0, 1, 1, 1, 1382400, 0x423e555b
+0, 2, 2, 1, 1382400, 0x87898ae0
+0, 3, 3, 1, 1382400, 0xfee4beab
+0, 4, 4, 1, 1382400, 0xe5367019
+0, 5, 5, 1, 1382400, 0x3e74b3aa
+0, 6, 6, 1, 1382400, 0x4d8ab61a
+0, 7, 7, 1, 1382400, 0x22500e13
diff --git a/tests/ref/fate/hevc-conformance-DBLK_G_VIXS_1 b/tests/ref/fate/hevc-conformance-DBLK_G_VIXS_1
new file mode 100644
index 0000000..4b9793b
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-DBLK_G_VIXS_1
@@ -0,0 +1,9 @@
+#tb 0: 1/25
+0, 0, 0, 1, 1382400, 0xecfdf606
+0, 1, 1, 1, 1382400, 0x7607799b
+0, 2, 2, 1, 1382400, 0x67fb98e4
+0, 3, 3, 1, 1382400, 0xf2dce07f
+0, 4, 4, 1, 1382400, 0x663f991c
+0, 5, 5, 1, 1382400, 0x3877aeb0
+0, 6, 6, 1, 1382400, 0x73409282
+0, 7, 7, 1, 1382400, 0x766c10b1
diff --git a/tests/ref/fate/hevc-conformance-DBLK_G_VIXS_2 b/tests/ref/fate/hevc-conformance-DBLK_G_VIXS_2
new file mode 100644
index 0000000..4c8b07d
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-DBLK_G_VIXS_2
@@ -0,0 +1,9 @@
+#tb 0: 1/25
+0, 0, 0, 1, 1382400, 0xecfdf606
+0, 1, 1, 1, 1382400, 0x0b0382e1
+0, 2, 2, 1, 1382400, 0xbef3afd6
+0, 3, 3, 1, 1382400, 0x6a2bcabb
+0, 4, 4, 1, 1382400, 0x663f991c
+0, 5, 5, 1, 1382400, 0xb49b94d8
+0, 6, 6, 1, 1382400, 0x07399433
+0, 7, 7, 1, 1382400, 0x9cca09df
diff --git a/tests/ref/fate/hevc-conformance-DELTAQP_B_SONY_3 b/tests/ref/fate/hevc-conformance-DELTAQP_B_SONY_3
new file mode 100644
index 0000000..3ba3bb5
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-DELTAQP_B_SONY_3
@@ -0,0 +1,31 @@
+#tb 0: 1/25
+0, 0, 0, 1, 599040, 0x7ea9597c
+0, 1, 1, 1, 599040, 0x3e7365e4
+0, 2, 2, 1, 599040, 0x4a9149c9
+0, 3, 3, 1, 599040, 0x3b1f6549
+0, 4, 4, 1, 599040, 0x3e35f616
+0, 5, 5, 1, 599040, 0x843c7951
+0, 6, 6, 1, 599040, 0xa2adb299
+0, 7, 7, 1, 599040, 0xb9dda682
+0, 8, 8, 1, 599040, 0x9a5e7355
+0, 9, 9, 1, 599040, 0xc4bafa8c
+0, 10, 10, 1, 599040, 0xc4ec160e
+0, 11, 11, 1, 599040, 0x538421a3
+0, 12, 12, 1, 599040, 0xb294a96e
+0, 13, 13, 1, 599040, 0x9bb217df
+0, 14, 14, 1, 599040, 0xbe70c870
+0, 15, 15, 1, 599040, 0xa4e319a8
+0, 16, 16, 1, 599040, 0x3a4c702d
+0, 17, 17, 1, 599040, 0x9f790906
+0, 18, 18, 1, 599040, 0xbbfdb8d6
+0, 19, 19, 1, 599040, 0x0965c0ed
+0, 20, 20, 1, 599040, 0x6993e1f1
+0, 21, 21, 1, 599040, 0xc1cc1df9
+0, 22, 22, 1, 599040, 0xe570c390
+0, 23, 23, 1, 599040, 0x422f6fd7
+0, 24, 24, 1, 599040, 0x9c89298c
+0, 25, 25, 1, 599040, 0x5ece4193
+0, 26, 26, 1, 599040, 0x142a4f2f
+0, 27, 27, 1, 599040, 0xa5356c63
+0, 28, 28, 1, 599040, 0x8458a378
+0, 29, 29, 1, 599040, 0xc149ed56
diff --git a/tests/ref/fate/hevc-conformance-DELTAQP_C_SONY_3 b/tests/ref/fate/hevc-conformance-DELTAQP_C_SONY_3
new file mode 100644
index 0000000..d616bac
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-DELTAQP_C_SONY_3
@@ -0,0 +1,31 @@
+#tb 0: 1/25
+0, 0, 0, 1, 599040, 0xcb2969c5
+0, 1, 1, 1, 599040, 0xd9825d1f
+0, 2, 2, 1, 599040, 0x5ff4245a
+0, 3, 3, 1, 599040, 0xd34e7bcb
+0, 4, 4, 1, 599040, 0x032e1b8b
+0, 5, 5, 1, 599040, 0x5ba1873c
+0, 6, 6, 1, 599040, 0xa0b725ad
+0, 7, 7, 1, 599040, 0x9cade6a6
+0, 8, 8, 1, 599040, 0xe41bee5a
+0, 9, 9, 1, 599040, 0x9de4340f
+0, 10, 10, 1, 599040, 0xb966282a
+0, 11, 11, 1, 599040, 0x52fd5300
+0, 12, 12, 1, 599040, 0x8e6d6753
+0, 13, 13, 1, 599040, 0x2011759b
+0, 14, 14, 1, 599040, 0x5da5b7af
+0, 15, 15, 1, 599040, 0x090e298c
+0, 16, 16, 1, 599040, 0xfd618263
+0, 17, 17, 1, 599040, 0xdaf4ef69
+0, 18, 18, 1, 599040, 0x0349d1a0
+0, 19, 19, 1, 599040, 0x75a35caf
+0, 20, 20, 1, 599040, 0x4544918e
+0, 21, 21, 1, 599040, 0xbca15836
+0, 22, 22, 1, 599040, 0x443bc611
+0, 23, 23, 1, 599040, 0xc380beaf
+0, 24, 24, 1, 599040, 0x01a581ca
+0, 25, 25, 1, 599040, 0x1690835f
+0, 26, 26, 1, 599040, 0x871e9c3b
+0, 27, 27, 1, 599040, 0xf4c20a25
+0, 28, 28, 1, 599040, 0x86d8f2df
+0, 29, 29, 1, 599040, 0x7690bd56
diff --git a/tests/ref/fate/hevc-conformance-DSLICE_A_HHI_5 b/tests/ref/fate/hevc-conformance-DSLICE_A_HHI_5
new file mode 100644
index 0000000..6cd113b
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-DSLICE_A_HHI_5
@@ -0,0 +1,51 @@
+#tb 0: 1/25
+0, 0, 0, 1, 3110400, 0xdc18cd12
+0, 1, 1, 1, 3110400, 0x42f7020d
+0, 2, 2, 1, 3110400, 0x6ac4421a
+0, 3, 3, 1, 3110400, 0xdbf78c86
+0, 4, 4, 1, 3110400, 0x123f9c50
+0, 5, 5, 1, 3110400, 0x9356a73f
+0, 6, 6, 1, 3110400, 0xc54a446b
+0, 7, 7, 1, 3110400, 0xdfa92401
+0, 8, 8, 1, 3110400, 0xd3226c6a
+0, 9, 9, 1, 3110400, 0xa0bd149a
+0, 10, 10, 1, 3110400, 0xc38c58cc
+0, 11, 11, 1, 3110400, 0xf1871f13
+0, 12, 12, 1, 3110400, 0xfdf151d5
+0, 13, 13, 1, 3110400, 0x65ca7286
+0, 14, 14, 1, 3110400, 0xac2d80dc
+0, 15, 15, 1, 3110400, 0x3e024908
+0, 16, 16, 1, 3110400, 0x22a66454
+0, 17, 17, 1, 3110400, 0x83b6cac8
+0, 18, 18, 1, 3110400, 0xe1bccc50
+0, 19, 19, 1, 3110400, 0x76be567e
+0, 20, 20, 1, 3110400, 0x743c4335
+0, 21, 21, 1, 3110400, 0xd3d28565
+0, 22, 22, 1, 3110400, 0x2ab3a5a2
+0, 23, 23, 1, 3110400, 0x9141f68e
+0, 24, 24, 1, 3110400, 0xe90fac3b
+0, 25, 25, 1, 3110400, 0xdc8e496d
+0, 26, 26, 1, 3110400, 0x4ea216b9
+0, 27, 27, 1, 3110400, 0xd1f8a08e
+0, 28, 28, 1, 3110400, 0x2b512b98
+0, 29, 29, 1, 3110400, 0x6af060b6
+0, 30, 30, 1, 3110400, 0x69389c02
+0, 31, 31, 1, 3110400, 0x7a8cef2f
+0, 32, 32, 1, 3110400, 0x8f5bd7eb
+0, 33, 33, 1, 3110400, 0x3960d741
+0, 34, 34, 1, 3110400, 0x86c2c23b
+0, 35, 35, 1, 3110400, 0x6d0d258a
+0, 36, 36, 1, 3110400, 0xaff6795b
+0, 37, 37, 1, 3110400, 0x97b9cb1e
+0, 38, 38, 1, 3110400, 0x5966d391
+0, 39, 39, 1, 3110400, 0xb9c90726
+0, 40, 40, 1, 3110400, 0x3ab5836d
+0, 41, 41, 1, 3110400, 0xcc3c95e7
+0, 42, 42, 1, 3110400, 0x190df1ce
+0, 43, 43, 1, 3110400, 0x64e6f266
+0, 44, 44, 1, 3110400, 0x98dfdcdd
+0, 45, 45, 1, 3110400, 0xd8889aff
+0, 46, 46, 1, 3110400, 0x969775b8
+0, 47, 47, 1, 3110400, 0x8f3dec20
+0, 48, 48, 1, 3110400, 0xbd2b80ca
+0, 49, 49, 1, 3110400, 0x68baa6f7
diff --git a/tests/ref/fate/hevc-conformance-DSLICE_B_HHI_5 b/tests/ref/fate/hevc-conformance-DSLICE_B_HHI_5
new file mode 100644
index 0000000..7626d76
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-DSLICE_B_HHI_5
@@ -0,0 +1,51 @@
+#tb 0: 1/25
+0, 0, 0, 1, 3110400, 0x96995c57
+0, 1, 1, 1, 3110400, 0x2924a10f
+0, 2, 2, 1, 3110400, 0x892e146c
+0, 3, 3, 1, 3110400, 0x9b0b8733
+0, 4, 4, 1, 3110400, 0xb09ffc2d
+0, 5, 5, 1, 3110400, 0x588e04a0
+0, 6, 6, 1, 3110400, 0xa9ed178c
+0, 7, 7, 1, 3110400, 0x54254788
+0, 8, 8, 1, 3110400, 0x4fa444bc
+0, 9, 9, 1, 3110400, 0xe97d958a
+0, 10, 10, 1, 3110400, 0x8e168461
+0, 11, 11, 1, 3110400, 0xc39e551f
+0, 12, 12, 1, 3110400, 0xb5649a69
+0, 13, 13, 1, 3110400, 0x64eb3085
+0, 14, 14, 1, 3110400, 0xb4485019
+0, 15, 15, 1, 3110400, 0x989e4c47
+0, 16, 16, 1, 3110400, 0x0ff21984
+0, 17, 17, 1, 3110400, 0xe81b3ddd
+0, 18, 18, 1, 3110400, 0x6404610f
+0, 19, 19, 1, 3110400, 0xa61c3403
+0, 20, 20, 1, 3110400, 0x033ca068
+0, 21, 21, 1, 3110400, 0x3513dff4
+0, 22, 22, 1, 3110400, 0xe903a3c2
+0, 23, 23, 1, 3110400, 0xd40b3248
+0, 24, 24, 1, 3110400, 0xa257fb35
+0, 25, 25, 1, 3110400, 0x6fcab221
+0, 26, 26, 1, 3110400, 0x079a34c7
+0, 27, 27, 1, 3110400, 0x7308ecbc
+0, 28, 28, 1, 3110400, 0x1cf2dffb
+0, 29, 29, 1, 3110400, 0x59a0a84d
+0, 30, 30, 1, 3110400, 0x6b76450f
+0, 31, 31, 1, 3110400, 0x27de01f3
+0, 32, 32, 1, 3110400, 0x8541fe8b
+0, 33, 33, 1, 3110400, 0x07b740d9
+0, 34, 34, 1, 3110400, 0x735d36e9
+0, 35, 35, 1, 3110400, 0x0336ac98
+0, 36, 36, 1, 3110400, 0xab9f7d33
+0, 37, 37, 1, 3110400, 0xc5f62e67
+0, 38, 38, 1, 3110400, 0x68d6c250
+0, 39, 39, 1, 3110400, 0xaf26c339
+0, 40, 40, 1, 3110400, 0xfa920d0f
+0, 41, 41, 1, 3110400, 0xac9c6a89
+0, 42, 42, 1, 3110400, 0xa0d0cbd0
+0, 43, 43, 1, 3110400, 0x9d517b81
+0, 44, 44, 1, 3110400, 0x3c3b2b89
+0, 45, 45, 1, 3110400, 0x3cf50b0c
+0, 46, 46, 1, 3110400, 0xee319ebe
+0, 47, 47, 1, 3110400, 0x5b7c3397
+0, 48, 48, 1, 3110400, 0x1a089921
+0, 49, 49, 1, 3110400, 0x69718487
diff --git a/tests/ref/fate/hevc-conformance-DSLICE_C_HHI_5 b/tests/ref/fate/hevc-conformance-DSLICE_C_HHI_5
new file mode 100644
index 0000000..c4275cb
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-DSLICE_C_HHI_5
@@ -0,0 +1,51 @@
+#tb 0: 1/25
+0, 0, 0, 1, 3110400, 0x62a2ceab
+0, 1, 1, 1, 3110400, 0x5e4d6adc
+0, 2, 2, 1, 3110400, 0x4ad0955d
+0, 3, 3, 1, 3110400, 0x17fd7b7c
+0, 4, 4, 1, 3110400, 0xe8270ac1
+0, 5, 5, 1, 3110400, 0xbc32bf86
+0, 6, 6, 1, 3110400, 0x13cc365c
+0, 7, 7, 1, 3110400, 0xef503eb5
+0, 8, 8, 1, 3110400, 0xcc9506f4
+0, 9, 9, 1, 3110400, 0xdc213a9e
+0, 10, 10, 1, 3110400, 0xe567c736
+0, 11, 11, 1, 3110400, 0x0a79aad4
+0, 12, 12, 1, 3110400, 0x61773cff
+0, 13, 13, 1, 3110400, 0x2e93a037
+0, 14, 14, 1, 3110400, 0xf419a7bf
+0, 15, 15, 1, 3110400, 0xa57b06bf
+0, 16, 16, 1, 3110400, 0x6e94960a
+0, 17, 17, 1, 3110400, 0x11f22564
+0, 18, 18, 1, 3110400, 0x850e5f7c
+0, 19, 19, 1, 3110400, 0xdfad06af
+0, 20, 20, 1, 3110400, 0xf2912aee
+0, 21, 21, 1, 3110400, 0x57e1c391
+0, 22, 22, 1, 3110400, 0xc8976a8f
+0, 23, 23, 1, 3110400, 0x88fb8b68
+0, 24, 24, 1, 3110400, 0xbe0e314b
+0, 25, 25, 1, 3110400, 0x33ae23f8
+0, 26, 26, 1, 3110400, 0x4db83c5c
+0, 27, 27, 1, 3110400, 0xa5f71a9d
+0, 28, 28, 1, 3110400, 0x34bb4f19
+0, 29, 29, 1, 3110400, 0xb1fee8d9
+0, 30, 30, 1, 3110400, 0x369990b7
+0, 31, 31, 1, 3110400, 0x6bfdbd4a
+0, 32, 32, 1, 3110400, 0x709dd60d
+0, 33, 33, 1, 3110400, 0x4213781c
+0, 34, 34, 1, 3110400, 0x7810dadd
+0, 35, 35, 1, 3110400, 0x1bc02bc6
+0, 36, 36, 1, 3110400, 0x760ed4aa
+0, 37, 37, 1, 3110400, 0xe2b45e4d
+0, 38, 38, 1, 3110400, 0x517b8d0a
+0, 39, 39, 1, 3110400, 0xf145ed7e
+0, 40, 40, 1, 3110400, 0xd8cbc454
+0, 41, 41, 1, 3110400, 0xa80f26f7
+0, 42, 42, 1, 3110400, 0x340a418d
+0, 43, 43, 1, 3110400, 0x5a0f7264
+0, 44, 44, 1, 3110400, 0xf2936a6d
+0, 45, 45, 1, 3110400, 0x841e715b
+0, 46, 46, 1, 3110400, 0xb17e4131
+0, 47, 47, 1, 3110400, 0x40e3ba7b
+0, 48, 48, 1, 3110400, 0x610254f7
+0, 49, 49, 1, 3110400, 0x76aa8b44
diff --git a/tests/ref/fate/hevc-conformance-ENTP_A_LG_2 b/tests/ref/fate/hevc-conformance-ENTP_A_LG_2
new file mode 100644
index 0000000..5697619
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-ENTP_A_LG_2
@@ -0,0 +1,51 @@
+#tb 0: 1/25
+0, 0, 0, 1, 599040, 0x866449d5
+0, 1, 1, 1, 599040, 0x6a8919f0
+0, 2, 2, 1, 599040, 0x5bec3742
+0, 3, 3, 1, 599040, 0x0e66f78b
+0, 4, 4, 1, 599040, 0x798e543b
+0, 5, 5, 1, 599040, 0x342467e0
+0, 6, 6, 1, 599040, 0x2cb393e1
+0, 7, 7, 1, 599040, 0x2f326539
+0, 8, 8, 1, 599040, 0x8ac6eb6a
+0, 9, 9, 1, 599040, 0x810a887b
+0, 10, 10, 1, 599040, 0x4feb2d60
+0, 11, 11, 1, 599040, 0xd32165ff
+0, 12, 12, 1, 599040, 0x46e505e1
+0, 13, 13, 1, 599040, 0x2d917014
+0, 14, 14, 1, 599040, 0xb504f112
+0, 15, 15, 1, 599040, 0x0fca37ce
+0, 16, 16, 1, 599040, 0x2d5a269d
+0, 17, 17, 1, 599040, 0x3928ef6d
+0, 18, 18, 1, 599040, 0x94397312
+0, 19, 19, 1, 599040, 0xc1c1257b
+0, 20, 20, 1, 599040, 0x4e23adcc
+0, 21, 21, 1, 599040, 0x3eaef1e0
+0, 22, 22, 1, 599040, 0x5e66fa14
+0, 23, 23, 1, 599040, 0x2adfa0c2
+0, 24, 24, 1, 599040, 0xf888db90
+0, 25, 25, 1, 599040, 0xab3a6418
+0, 26, 26, 1, 599040, 0x7689d0a2
+0, 27, 27, 1, 599040, 0x2f5746bf
+0, 28, 28, 1, 599040, 0xad2cf3da
+0, 29, 29, 1, 599040, 0x32f2854e
+0, 30, 30, 1, 599040, 0xb73cf7db
+0, 31, 31, 1, 599040, 0xbe996991
+0, 32, 32, 1, 599040, 0xe66501c8
+0, 33, 33, 1, 599040, 0x12d1bc13
+0, 34, 34, 1, 599040, 0x06e103d5
+0, 35, 35, 1, 599040, 0x49af0680
+0, 36, 36, 1, 599040, 0xdbf128b0
+0, 37, 37, 1, 599040, 0xa1ac770d
+0, 38, 38, 1, 599040, 0x99156429
+0, 39, 39, 1, 599040, 0x8ce1a9a7
+0, 40, 40, 1, 599040, 0x14067700
+0, 41, 41, 1, 599040, 0xcdedccee
+0, 42, 42, 1, 599040, 0x09c12765
+0, 43, 43, 1, 599040, 0x7979a1be
+0, 44, 44, 1, 599040, 0xbd3148d1
+0, 45, 45, 1, 599040, 0xc83f9aac
+0, 46, 46, 1, 599040, 0x91acbae4
+0, 47, 47, 1, 599040, 0xd230907a
+0, 48, 48, 1, 599040, 0x3f6c31f6
+0, 49, 49, 1, 599040, 0x84496e55
diff --git a/tests/ref/fate/hevc-conformance-ENTP_B_LG_2 b/tests/ref/fate/hevc-conformance-ENTP_B_LG_2
new file mode 100644
index 0000000..0251f30
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-ENTP_B_LG_2
@@ -0,0 +1,51 @@
+#tb 0: 1/25
+0, 0, 0, 1, 599040, 0x95a24137
+0, 1, 1, 1, 599040, 0x7d7f2b75
+0, 2, 2, 1, 599040, 0xd9fb2120
+0, 3, 3, 1, 599040, 0x14d50590
+0, 4, 4, 1, 599040, 0xe3d1b70e
+0, 5, 5, 1, 599040, 0x57708a86
+0, 6, 6, 1, 599040, 0xae56a720
+0, 7, 7, 1, 599040, 0x74c18679
+0, 8, 8, 1, 599040, 0x6422d2a7
+0, 9, 9, 1, 599040, 0xf587702b
+0, 10, 10, 1, 599040, 0x0f630fe0
+0, 11, 11, 1, 599040, 0x4e3537dd
+0, 12, 12, 1, 599040, 0xa645e9c1
+0, 13, 13, 1, 599040, 0x35ab4155
+0, 14, 14, 1, 599040, 0x4b78ba34
+0, 15, 15, 1, 599040, 0xa9a9e572
+0, 16, 16, 1, 599040, 0x6d57f10f
+0, 17, 17, 1, 599040, 0xffb8e333
+0, 18, 18, 1, 599040, 0x7b2d6319
+0, 19, 19, 1, 599040, 0xcf3319aa
+0, 20, 20, 1, 599040, 0xb0d097ee
+0, 21, 21, 1, 599040, 0xf042f780
+0, 22, 22, 1, 599040, 0xfafafdcb
+0, 23, 23, 1, 599040, 0xc8c1c452
+0, 24, 24, 1, 599040, 0x83c4d488
+0, 25, 25, 1, 599040, 0x81a8fd08
+0, 26, 26, 1, 599040, 0x2cb0c333
+0, 27, 27, 1, 599040, 0xa7bf4e52
+0, 28, 28, 1, 599040, 0x5b7ed8e9
+0, 29, 29, 1, 599040, 0x4ff03464
+0, 30, 30, 1, 599040, 0x54a700c2
+0, 31, 31, 1, 599040, 0x7dbb63aa
+0, 32, 32, 1, 599040, 0xda26288e
+0, 33, 33, 1, 599040, 0x8074da41
+0, 34, 34, 1, 599040, 0xa32b2ab2
+0, 35, 35, 1, 599040, 0x51b457fb
+0, 36, 36, 1, 599040, 0x05e34953
+0, 37, 37, 1, 599040, 0x68c762d6
+0, 38, 38, 1, 599040, 0x11bf469e
+0, 39, 39, 1, 599040, 0xc2fdadaf
+0, 40, 40, 1, 599040, 0x05588da0
+0, 41, 41, 1, 599040, 0x8855f927
+0, 42, 42, 1, 599040, 0x11c85d5a
+0, 43, 43, 1, 599040, 0x7a0aede5
+0, 44, 44, 1, 599040, 0x39dc4f7d
+0, 45, 45, 1, 599040, 0x388f81d6
+0, 46, 46, 1, 599040, 0x2afa830d
+0, 47, 47, 1, 599040, 0xd7f26886
+0, 48, 48, 1, 599040, 0xb8e12aef
+0, 49, 49, 1, 599040, 0x73f7582c
diff --git a/tests/ref/fate/hevc-conformance-ENTP_C_LG_3 b/tests/ref/fate/hevc-conformance-ENTP_C_LG_3
new file mode 100644
index 0000000..3c0946e
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-ENTP_C_LG_3
@@ -0,0 +1,51 @@
+#tb 0: 1/25
+0, 0, 0, 1, 3110400, 0xaea1c3d6
+0, 1, 1, 1, 3110400, 0x665b4f52
+0, 2, 2, 1, 3110400, 0xc7da58a2
+0, 3, 3, 1, 3110400, 0x1dda6461
+0, 4, 4, 1, 3110400, 0x1d8d6eaf
+0, 5, 5, 1, 3110400, 0x7a29911a
+0, 6, 6, 1, 3110400, 0x0dce92c9
+0, 7, 7, 1, 3110400, 0x79c84570
+0, 8, 8, 1, 3110400, 0x736ef1e7
+0, 9, 9, 1, 3110400, 0x9dd86492
+0, 10, 10, 1, 3110400, 0x0ea31a1b
+0, 11, 11, 1, 3110400, 0x0d84fdc8
+0, 12, 12, 1, 3110400, 0x06ed89a7
+0, 13, 13, 1, 3110400, 0xfaea4fd6
+0, 14, 14, 1, 3110400, 0xe787abe8
+0, 15, 15, 1, 3110400, 0x050b653a
+0, 16, 16, 1, 3110400, 0x35cc1ec1
+0, 17, 17, 1, 3110400, 0x86a43e07
+0, 18, 18, 1, 3110400, 0xa6ab021e
+0, 19, 19, 1, 3110400, 0x491e0efa
+0, 20, 20, 1, 3110400, 0x8f210c38
+0, 21, 21, 1, 3110400, 0x637af0d0
+0, 22, 22, 1, 3110400, 0x47a59197
+0, 23, 23, 1, 3110400, 0x53e04637
+0, 24, 24, 1, 3110400, 0x7b99325e
+0, 25, 25, 1, 3110400, 0x972aa252
+0, 26, 26, 1, 3110400, 0xe76ef917
+0, 27, 27, 1, 3110400, 0x7a25babc
+0, 28, 28, 1, 3110400, 0x3bee3c5c
+0, 29, 29, 1, 3110400, 0xbae82bcb
+0, 30, 30, 1, 3110400, 0x5b65c1e5
+0, 31, 31, 1, 3110400, 0xa546266f
+0, 32, 32, 1, 3110400, 0x5c5b9b8e
+0, 33, 33, 1, 3110400, 0xec29c804
+0, 34, 34, 1, 3110400, 0x384efc7d
+0, 35, 35, 1, 3110400, 0x6c1aaa23
+0, 36, 36, 1, 3110400, 0x55494f9f
+0, 37, 37, 1, 3110400, 0xa9c56fec
+0, 38, 38, 1, 3110400, 0x49c29ef2
+0, 39, 39, 1, 3110400, 0xac24fdd4
+0, 40, 40, 1, 3110400, 0x403d8213
+0, 41, 41, 1, 3110400, 0xf2d8aefe
+0, 42, 42, 1, 3110400, 0x2884f0e1
+0, 43, 43, 1, 3110400, 0x69a0a781
+0, 44, 44, 1, 3110400, 0x3ab6114c
+0, 45, 45, 1, 3110400, 0x1d4425a2
+0, 46, 46, 1, 3110400, 0x59f8970a
+0, 47, 47, 1, 3110400, 0xfe0a05a9
+0, 48, 48, 1, 3110400, 0x50b9be4f
+0, 49, 49, 1, 3110400, 0x3e1b65bd
diff --git a/tests/ref/fate/hevc-conformance-EXT_A_ericsson_3 b/tests/ref/fate/hevc-conformance-EXT_A_ericsson_3
new file mode 100644
index 0000000..bf4616a
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-EXT_A_ericsson_3
@@ -0,0 +1,4 @@
+#tb 0: 1/25
+0, 0, 0, 1, 149760, 0x8ce7200b
+0, 1, 1, 1, 149760, 0xf97412f6
+0, 2, 2, 1, 149760, 0x0ea132c4
diff --git a/tests/ref/fate/hevc-conformance-IPRED_A_docomo_2 b/tests/ref/fate/hevc-conformance-IPRED_A_docomo_2
new file mode 100644
index 0000000..33878fd
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-IPRED_A_docomo_2
@@ -0,0 +1,21 @@
+#tb 0: 1/25
+0, 0, 0, 1, 599040, 0xac658d10
+0, 1, 1, 1, 599040, 0xe3f65389
+0, 2, 2, 1, 599040, 0xfbd644b0
+0, 3, 3, 1, 599040, 0x3ac49569
+0, 4, 4, 1, 599040, 0x75abc5e2
+0, 5, 5, 1, 599040, 0xe787ddcd
+0, 6, 6, 1, 599040, 0x1df5f293
+0, 7, 7, 1, 599040, 0xa87774aa
+0, 8, 8, 1, 599040, 0x42b2bec6
+0, 9, 9, 1, 599040, 0x89f22378
+0, 10, 10, 1, 599040, 0x0d4e5397
+0, 11, 11, 1, 599040, 0xf4430d13
+0, 12, 12, 1, 599040, 0xfd2ff520
+0, 13, 13, 1, 599040, 0x21bf374b
+0, 14, 14, 1, 599040, 0xcba1032e
+0, 15, 15, 1, 599040, 0x58247f24
+0, 16, 16, 1, 599040, 0x7985788a
+0, 17, 17, 1, 599040, 0x3306488e
+0, 18, 18, 1, 599040, 0x8bcbf22e
+0, 19, 19, 1, 599040, 0xb7a7ae5c
diff --git a/tests/ref/fate/hevc-conformance-IPRED_B_Nokia_3 b/tests/ref/fate/hevc-conformance-IPRED_B_Nokia_3
new file mode 100644
index 0000000..4de7c3c
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-IPRED_B_Nokia_3
@@ -0,0 +1,2 @@
+#tb 0: 1/25
+0, 0, 0, 1, 3110400, 0x11ef5ddd
diff --git a/tests/ref/fate/hevc-conformance-IPRED_C_Mitsubishi_2 b/tests/ref/fate/hevc-conformance-IPRED_C_Mitsubishi_2
new file mode 100644
index 0000000..bff448b
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-IPRED_C_Mitsubishi_2
@@ -0,0 +1,5 @@
+#tb 0: 1/25
+0, 0, 0, 1, 599040, 0x9a8664e6
+0, 1, 1, 1, 599040, 0x72f15982
+0, 2, 2, 1, 599040, 0xc6610a7b
+0, 3, 3, 1, 599040, 0x091d3a93
diff --git a/tests/ref/fate/hevc-conformance-LS_A_Orange_2 b/tests/ref/fate/hevc-conformance-LS_A_Orange_2
new file mode 100644
index 0000000..4dd4ad4
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-LS_A_Orange_2
@@ -0,0 +1,10 @@
+#tb 0: 1/25
+0, 0, 0, 1, 149760, 0x94a51701
+0, 1, 1, 1, 149760, 0x67c71885
+0, 2, 2, 1, 149760, 0x218f1751
+0, 3, 3, 1, 149760, 0x56951bef
+0, 4, 4, 1, 149760, 0x76aec81e
+0, 5, 5, 1, 149760, 0x20df61ac
+0, 6, 6, 1, 149760, 0x2eacf616
+0, 7, 7, 1, 149760, 0x06322ce2
+0, 8, 8, 1, 149760, 0xf14aa104
diff --git a/tests/ref/fate/hevc-conformance-LS_B_ORANGE_3 b/tests/ref/fate/hevc-conformance-LS_B_ORANGE_3
new file mode 100644
index 0000000..34dc379
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-LS_B_ORANGE_3
@@ -0,0 +1,26 @@
+#tb 0: 1/25
+0, 0, 0, 1, 599040, 0x25267761
+0, 1, 1, 1, 599040, 0x4b4b6846
+0, 2, 2, 1, 599040, 0x78e251e8
+0, 3, 3, 1, 599040, 0xd5b261b0
+0, 4, 4, 1, 599040, 0x2c4cf4e1
+0, 5, 5, 1, 599040, 0x67dc648f
+0, 6, 6, 1, 599040, 0x3c43bffc
+0, 7, 7, 1, 599040, 0x43dca917
+0, 8, 8, 1, 599040, 0x86c9915e
+0, 9, 9, 1, 599040, 0xcfc4f95c
+0, 10, 10, 1, 599040, 0x1ad40bab
+0, 11, 11, 1, 599040, 0x88b5419e
+0, 12, 12, 1, 599040, 0x94e89a06
+0, 13, 13, 1, 599040, 0x3c68f4a6
+0, 14, 14, 1, 599040, 0xc573ac93
+0, 15, 15, 1, 599040, 0x3c401779
+0, 16, 16, 1, 599040, 0x33358319
+0, 17, 17, 1, 599040, 0xbecb022e
+0, 18, 18, 1, 599040, 0x824ca6c1
+0, 19, 19, 1, 599040, 0x9d13a2b8
+0, 20, 20, 1, 599040, 0xbdd4b44b
+0, 21, 21, 1, 599040, 0x7e43e7e9
+0, 22, 22, 1, 599040, 0x88c39a97
+0, 23, 23, 1, 599040, 0xe0462f05
+0, 24, 24, 1, 599040, 0xc5651fd1
diff --git a/tests/ref/fate/hevc-conformance-MAXBINS_A_TI_4 b/tests/ref/fate/hevc-conformance-MAXBINS_A_TI_4
new file mode 100644
index 0000000..9110cf6
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-MAXBINS_A_TI_4
@@ -0,0 +1,3 @@
+#tb 0: 1/25
+0, 0, 0, 1, 149760, 0x9cad90f9
+0, 1, 1, 1, 149760, 0x7deeab1c
diff --git a/tests/ref/fate/hevc-conformance-MAXBINS_B_TI_4 b/tests/ref/fate/hevc-conformance-MAXBINS_B_TI_4
new file mode 100644
index 0000000..5cad961
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-MAXBINS_B_TI_4
@@ -0,0 +1,4 @@
+#tb 0: 1/25
+0, 0, 0, 1, 149760, 0x211e8487
+0, 1, 1, 1, 149760, 0xa53b13d8
+0, 2, 2, 1, 149760, 0xb63cc103
diff --git a/tests/ref/fate/hevc-conformance-MAXBINS_C_TI_4 b/tests/ref/fate/hevc-conformance-MAXBINS_C_TI_4
new file mode 100644
index 0000000..2eb3843
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-MAXBINS_C_TI_4
@@ -0,0 +1,4 @@
+#tb 0: 1/25
+0, 0, 0, 1, 149760, 0xa8d7adfa
+0, 1, 1, 1, 149760, 0x76d1ddfe
+0, 2, 2, 1, 149760, 0x56599cae
diff --git a/tests/ref/fate/hevc-conformance-MERGE_A_TI_3 b/tests/ref/fate/hevc-conformance-MERGE_A_TI_3
new file mode 100644
index 0000000..0ab6acc
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-MERGE_A_TI_3
@@ -0,0 +1,9 @@
+#tb 0: 1/25
+0, 0, 0, 1, 149760, 0x8edb27d7
+0, 1, 1, 1, 149760, 0x16eb25a8
+0, 2, 2, 1, 149760, 0xcfff29c8
+0, 3, 3, 1, 149760, 0x4c9721e9
+0, 4, 4, 1, 149760, 0xee52e28d
+0, 5, 5, 1, 149760, 0xc25d9657
+0, 6, 6, 1, 149760, 0x0f644c82
+0, 7, 7, 1, 149760, 0x6f57aea1
diff --git a/tests/ref/fate/hevc-conformance-MERGE_B_TI_3 b/tests/ref/fate/hevc-conformance-MERGE_B_TI_3
new file mode 100644
index 0000000..2f9395f
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-MERGE_B_TI_3
@@ -0,0 +1,9 @@
+#tb 0: 1/25
+0, 0, 0, 1, 149760, 0x8edb27d7
+0, 1, 1, 1, 149760, 0xb5932505
+0, 2, 2, 1, 149760, 0xa5b20e66
+0, 3, 3, 1, 149760, 0x0d9f17cb
+0, 4, 4, 1, 149760, 0xf2b1dc80
+0, 5, 5, 1, 149760, 0xab8c8272
+0, 6, 6, 1, 149760, 0x50662cf4
+0, 7, 7, 1, 149760, 0x83cc8d5f
diff --git a/tests/ref/fate/hevc-conformance-MERGE_C_TI_3 b/tests/ref/fate/hevc-conformance-MERGE_C_TI_3
new file mode 100644
index 0000000..bcc5a1a
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-MERGE_C_TI_3
@@ -0,0 +1,9 @@
+#tb 0: 1/25
+0, 0, 0, 1, 149760, 0x8edb27d7
+0, 1, 1, 1, 149760, 0x88cb1216
+0, 2, 2, 1, 149760, 0x6d1024da
+0, 3, 3, 1, 149760, 0x90b13981
+0, 4, 4, 1, 149760, 0x4296ed51
+0, 5, 5, 1, 149760, 0x4da5926f
+0, 6, 6, 1, 149760, 0xa74b4368
+0, 7, 7, 1, 149760, 0x518fb0fc
diff --git a/tests/ref/fate/hevc-conformance-MERGE_D_TI_3 b/tests/ref/fate/hevc-conformance-MERGE_D_TI_3
new file mode 100644
index 0000000..7b4df26
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-MERGE_D_TI_3
@@ -0,0 +1,9 @@
+#tb 0: 1/25
+0, 0, 0, 1, 149760, 0x8edb27d7
+0, 1, 1, 1, 149760, 0x3220183c
+0, 2, 2, 1, 149760, 0x43a21acc
+0, 3, 3, 1, 149760, 0x7bde17f9
+0, 4, 4, 1, 149760, 0x98a1cece
+0, 5, 5, 1, 149760, 0x3d7b64b9
+0, 6, 6, 1, 149760, 0xd9311172
+0, 7, 7, 1, 149760, 0x90d192a3
diff --git a/tests/ref/fate/hevc-conformance-MERGE_E_TI_3 b/tests/ref/fate/hevc-conformance-MERGE_E_TI_3
new file mode 100644
index 0000000..8491172
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-MERGE_E_TI_3
@@ -0,0 +1,9 @@
+#tb 0: 1/25
+0, 0, 0, 1, 149760, 0x8edb27d7
+0, 1, 1, 1, 149760, 0x187419b5
+0, 2, 2, 1, 149760, 0x61100980
+0, 3, 3, 1, 149760, 0xd799123e
+0, 4, 4, 1, 149760, 0x9011c8d0
+0, 5, 5, 1, 149760, 0xeafe7d99
+0, 6, 6, 1, 149760, 0x94f32245
+0, 7, 7, 1, 149760, 0x8185910a
diff --git a/tests/ref/fate/hevc-conformance-MERGE_F_MTK_4 b/tests/ref/fate/hevc-conformance-MERGE_F_MTK_4
new file mode 100644
index 0000000..34a0979
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-MERGE_F_MTK_4
@@ -0,0 +1,42 @@
+#tb 0: 1/25
+0, 0, 0, 1, 149760, 0xcfffa013
+0, 1, 1, 1, 149760, 0xec800e71
+0, 2, 2, 1, 149760, 0x9fb014c7
+0, 3, 3, 1, 149760, 0xfd7a48a8
+0, 4, 4, 1, 149760, 0x99816bb5
+0, 5, 5, 1, 149760, 0x8645acaa
+0, 6, 6, 1, 149760, 0xd2a8e04b
+0, 7, 7, 1, 149760, 0xf96f038d
+0, 8, 8, 1, 149760, 0x82c62409
+0, 9, 9, 1, 149760, 0x64907b29
+0, 10, 10, 1, 149760, 0xfe29990e
+0, 11, 11, 1, 149760, 0xce2dc52d
+0, 12, 12, 1, 149760, 0x164fb2c5
+0, 13, 13, 1, 149760, 0xbcf8ca2d
+0, 14, 14, 1, 149760, 0xe59dc9bc
+0, 15, 15, 1, 149760, 0x2ab10400
+0, 16, 16, 1, 149760, 0xef111c81
+0, 17, 17, 1, 149760, 0xd08466b1
+0, 18, 18, 1, 149760, 0x6d356ff0
+0, 19, 19, 1, 149760, 0x16a59175
+0, 20, 20, 1, 149760, 0xd7888866
+0, 21, 21, 1, 149760, 0x2b22b943
+0, 22, 22, 1, 149760, 0x3b4fc3fe
+0, 23, 23, 1, 149760, 0x4ec8ee47
+0, 24, 24, 1, 149760, 0x0126f17b
+0, 25, 25, 1, 149760, 0x1176ad14
+0, 26, 26, 1, 149760, 0x2d4da75f
+0, 27, 27, 1, 149760, 0x144bb9e4
+0, 28, 28, 1, 149760, 0x5176a21b
+0, 29, 29, 1, 149760, 0x5e3fe673
+0, 30, 30, 1, 149760, 0xa533db65
+0, 31, 31, 1, 149760, 0x3009f3f8
+0, 32, 32, 1, 149760, 0xd4437e12
+0, 33, 33, 1, 149760, 0x5b03cd64
+0, 34, 34, 1, 149760, 0xdc40d49b
+0, 35, 35, 1, 149760, 0xf8cef0f6
+0, 36, 36, 1, 149760, 0x241be1b7
+0, 37, 37, 1, 149760, 0x23830404
+0, 38, 38, 1, 149760, 0x6ef7087e
+0, 39, 39, 1, 149760, 0xaf351e5b
+0, 40, 40, 1, 149760, 0x4cf40a64
diff --git a/tests/ref/fate/hevc-conformance-MERGE_G_HHI_4 b/tests/ref/fate/hevc-conformance-MERGE_G_HHI_4
new file mode 100644
index 0000000..2e88350
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-MERGE_G_HHI_4
@@ -0,0 +1,3 @@
+#tb 0: 1/25
+0, 0, 0, 1, 599040, 0x65433cfe
+0, 1, 1, 1, 599040, 0x9309e2c5
diff --git a/tests/ref/fate/hevc-conformance-MVCLIP_A_qualcomm_3 b/tests/ref/fate/hevc-conformance-MVCLIP_A_qualcomm_3
new file mode 100644
index 0000000..6756221
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-MVCLIP_A_qualcomm_3
@@ -0,0 +1,6 @@
+#tb 0: 1/25
+0, 0, 0, 1, 149760, 0xa5b11720
+0, 1, 1, 1, 149760, 0x42e52c6e
+0, 2, 2, 1, 149760, 0x27b15a30
+0, 3, 3, 1, 149760, 0x4d759826
+0, 4, 4, 1, 149760, 0xfb6daf0c
diff --git a/tests/ref/fate/hevc-conformance-MVDL1ZERO_A_docomo_3 b/tests/ref/fate/hevc-conformance-MVDL1ZERO_A_docomo_3
new file mode 100644
index 0000000..2019db2
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-MVDL1ZERO_A_docomo_3
@@ -0,0 +1,501 @@
+#tb 0: 1/25
+0, 0, 0, 1, 599040, 0x9b27dc7d
+0, 1, 1, 1, 599040, 0x796cdd26
+0, 2, 2, 1, 599040, 0xd3c9dca9
+0, 3, 3, 1, 599040, 0xf7b2876a
+0, 4, 4, 1, 599040, 0x296701c8
+0, 5, 5, 1, 599040, 0xf9a80f9a
+0, 6, 6, 1, 599040, 0x7cbe9656
+0, 7, 7, 1, 599040, 0x17093be8
+0, 8, 8, 1, 599040, 0x2a0e196e
+0, 9, 9, 1, 599040, 0x3492c809
+0, 10, 10, 1, 599040, 0xbc5523f3
+0, 11, 11, 1, 599040, 0xf618ff66
+0, 12, 12, 1, 599040, 0x07060c9d
+0, 13, 13, 1, 599040, 0xd5a8fb5d
+0, 14, 14, 1, 599040, 0x780e18b9
+0, 15, 15, 1, 599040, 0xff553fbd
+0, 16, 16, 1, 599040, 0x715cce2d
+0, 17, 17, 1, 599040, 0x8a834c19
+0, 18, 18, 1, 599040, 0xbc4a0c21
+0, 19, 19, 1, 599040, 0xc85fed31
+0, 20, 20, 1, 599040, 0xcbb97b56
+0, 21, 21, 1, 599040, 0x518111dd
+0, 22, 22, 1, 599040, 0x5a680f48
+0, 23, 23, 1, 599040, 0x02956f28
+0, 24, 24, 1, 599040, 0x10845ef6
+0, 25, 25, 1, 599040, 0x2ad3c6d7
+0, 26, 26, 1, 599040, 0xa9f725e9
+0, 27, 27, 1, 599040, 0xb835f470
+0, 28, 28, 1, 599040, 0x693bf01d
+0, 29, 29, 1, 599040, 0x50bf3b77
+0, 30, 30, 1, 599040, 0x304873e3
+0, 31, 31, 1, 599040, 0x707a6af9
+0, 32, 32, 1, 599040, 0x50bf2017
+0, 33, 33, 1, 599040, 0x2c583f11
+0, 34, 34, 1, 599040, 0xe738080b
+0, 35, 35, 1, 599040, 0x549984e6
+0, 36, 36, 1, 599040, 0xa22e8a96
+0, 37, 37, 1, 599040, 0xc9f222cd
+0, 38, 38, 1, 599040, 0x28d944bc
+0, 39, 39, 1, 599040, 0x2e366350
+0, 40, 40, 1, 599040, 0xbcc2eb12
+0, 41, 41, 1, 599040, 0x074d3fdd
+0, 42, 42, 1, 599040, 0x0e0bd820
+0, 43, 43, 1, 599040, 0xf078af68
+0, 44, 44, 1, 599040, 0xaeed7222
+0, 45, 45, 1, 599040, 0xb66100cd
+0, 46, 46, 1, 599040, 0x848cd1c5
+0, 47, 47, 1, 599040, 0xa6bf930c
+0, 48, 48, 1, 599040, 0x32501b56
+0, 49, 49, 1, 599040, 0x2498d992
+0, 50, 50, 1, 599040, 0x03481b78
+0, 51, 51, 1, 599040, 0x551d7c11
+0, 52, 52, 1, 599040, 0xfbdc629d
+0, 53, 53, 1, 599040, 0x1f438ded
+0, 54, 54, 1, 599040, 0x4d25ce07
+0, 55, 55, 1, 599040, 0x4fe8f8aa
+0, 56, 56, 1, 599040, 0x5d65d790
+0, 57, 57, 1, 599040, 0xfcba4efb
+0, 58, 58, 1, 599040, 0x50b483a3
+0, 59, 59, 1, 599040, 0x12fd4b31
+0, 60, 60, 1, 599040, 0x71014417
+0, 61, 61, 1, 599040, 0xeed88bc4
+0, 62, 62, 1, 599040, 0xb2d4710d
+0, 63, 63, 1, 599040, 0xbe4dfe69
+0, 64, 64, 1, 599040, 0x9b7844b6
+0, 65, 65, 1, 599040, 0xe2e691bf
+0, 66, 66, 1, 599040, 0xb24200dc
+0, 67, 67, 1, 599040, 0xf29cb5bf
+0, 68, 68, 1, 599040, 0x90350310
+0, 69, 69, 1, 599040, 0xbe1cc3c1
+0, 70, 70, 1, 599040, 0xaae58f97
+0, 71, 71, 1, 599040, 0x0d5cb388
+0, 72, 72, 1, 599040, 0x0fa734e3
+0, 73, 73, 1, 599040, 0xaa41543a
+0, 74, 74, 1, 599040, 0x3e6e1d4b
+0, 75, 75, 1, 599040, 0x6426e543
+0, 76, 76, 1, 599040, 0xe65ad058
+0, 77, 77, 1, 599040, 0xf7f1744d
+0, 78, 78, 1, 599040, 0xa8fa32da
+0, 79, 79, 1, 599040, 0xa2c80e49
+0, 80, 80, 1, 599040, 0x22b972e9
+0, 81, 81, 1, 599040, 0x2462823b
+0, 82, 82, 1, 599040, 0xa7fd0432
+0, 83, 83, 1, 599040, 0x38d22ea4
+0, 84, 84, 1, 599040, 0xb472f4d6
+0, 85, 85, 1, 599040, 0x36c107a0
+0, 86, 86, 1, 599040, 0x9abb5ce0
+0, 87, 87, 1, 599040, 0x74b2861c
+0, 88, 88, 1, 599040, 0xba3d04d3
+0, 89, 89, 1, 599040, 0x65132373
+0, 90, 90, 1, 599040, 0x63585754
+0, 91, 91, 1, 599040, 0xa6c0f4d4
+0, 92, 92, 1, 599040, 0xc2cf9c33
+0, 93, 93, 1, 599040, 0xdf6d16af
+0, 94, 94, 1, 599040, 0x94566b11
+0, 95, 95, 1, 599040, 0x8070818d
+0, 96, 96, 1, 599040, 0x4acc92c1
+0, 97, 97, 1, 599040, 0xb520033c
+0, 98, 98, 1, 599040, 0xc82e7058
+0, 99, 99, 1, 599040, 0xb23367bc
+0, 100, 100, 1, 599040, 0x1fa25586
+0, 101, 101, 1, 599040, 0x2b2abbb8
+0, 102, 102, 1, 599040, 0xb9b74546
+0, 103, 103, 1, 599040, 0x4c4a2ef9
+0, 104, 104, 1, 599040, 0x5eb54025
+0, 105, 105, 1, 599040, 0x1e1cbcc6
+0, 106, 106, 1, 599040, 0xc3bf1017
+0, 107, 107, 1, 599040, 0xdbda1761
+0, 108, 108, 1, 599040, 0x19241b7c
+0, 109, 109, 1, 599040, 0x791dda93
+0, 110, 110, 1, 599040, 0x444a152f
+0, 111, 111, 1, 599040, 0x0b69d08b
+0, 112, 112, 1, 599040, 0xd024abae
+0, 113, 113, 1, 599040, 0x724e0d78
+0, 114, 114, 1, 599040, 0x648f9c09
+0, 115, 115, 1, 599040, 0xee114298
+0, 116, 116, 1, 599040, 0x92d1e98f
+0, 117, 117, 1, 599040, 0xb623cb10
+0, 118, 118, 1, 599040, 0xf8e9b414
+0, 119, 119, 1, 599040, 0xe47a0981
+0, 120, 120, 1, 599040, 0xdc78d28d
+0, 121, 121, 1, 599040, 0xd36d9ad5
+0, 122, 122, 1, 599040, 0xe7bea48e
+0, 123, 123, 1, 599040, 0x0dd39d1d
+0, 124, 124, 1, 599040, 0xb66a18ee
+0, 125, 125, 1, 599040, 0x6085d265
+0, 126, 126, 1, 599040, 0xb9ef646b
+0, 127, 127, 1, 599040, 0x544140a4
+0, 128, 128, 1, 599040, 0x9c546327
+0, 129, 129, 1, 599040, 0xd74d4a8e
+0, 130, 130, 1, 599040, 0x98a504e0
+0, 131, 131, 1, 599040, 0x88849351
+0, 132, 132, 1, 599040, 0xa519f6c7
+0, 133, 133, 1, 599040, 0xc548df7f
+0, 134, 134, 1, 599040, 0x8e690444
+0, 135, 135, 1, 599040, 0x5edbdced
+0, 136, 136, 1, 599040, 0xd3e189c2
+0, 137, 137, 1, 599040, 0x286d44a2
+0, 138, 138, 1, 599040, 0xe946f83e
+0, 139, 139, 1, 599040, 0xdc94ae6d
+0, 140, 140, 1, 599040, 0x5d4e95dc
+0, 141, 141, 1, 599040, 0x2c03280f
+0, 142, 142, 1, 599040, 0x368c6b23
+0, 143, 143, 1, 599040, 0x2fc5d2ee
+0, 144, 144, 1, 599040, 0x85e8f3ec
+0, 145, 145, 1, 599040, 0xd1fdcf69
+0, 146, 146, 1, 599040, 0xa663cf5a
+0, 147, 147, 1, 599040, 0x5d644057
+0, 148, 148, 1, 599040, 0xfdd039e0
+0, 149, 149, 1, 599040, 0x9cdb6369
+0, 150, 150, 1, 599040, 0x3c4ca86b
+0, 151, 151, 1, 599040, 0x27ac4d91
+0, 152, 152, 1, 599040, 0x3f13a8bb
+0, 153, 153, 1, 599040, 0xbcd984c5
+0, 154, 154, 1, 599040, 0xa55eb124
+0, 155, 155, 1, 599040, 0xb09c4a47
+0, 156, 156, 1, 599040, 0x0da7fd48
+0, 157, 157, 1, 599040, 0xa01dc374
+0, 158, 158, 1, 599040, 0xe428b3b0
+0, 159, 159, 1, 599040, 0xff3fcc43
+0, 160, 160, 1, 599040, 0xbc5491c1
+0, 161, 161, 1, 599040, 0x34e51a66
+0, 162, 162, 1, 599040, 0xb63f5acd
+0, 163, 163, 1, 599040, 0xe12f417d
+0, 164, 164, 1, 599040, 0x789bb191
+0, 165, 165, 1, 599040, 0x5fdeaa57
+0, 166, 166, 1, 599040, 0x65034250
+0, 167, 167, 1, 599040, 0xab577632
+0, 168, 168, 1, 599040, 0x1338c7eb
+0, 169, 169, 1, 599040, 0x5a84b078
+0, 170, 170, 1, 599040, 0x9f3fd6c2
+0, 171, 171, 1, 599040, 0x23cd7f3f
+0, 172, 172, 1, 599040, 0x43701c5c
+0, 173, 173, 1, 599040, 0x72eff5aa
+0, 174, 174, 1, 599040, 0x858a7280
+0, 175, 175, 1, 599040, 0x5d1da2b1
+0, 176, 176, 1, 599040, 0x2b6fae7b
+0, 177, 177, 1, 599040, 0x3d96cd3f
+0, 178, 178, 1, 599040, 0x5d6d48e5
+0, 179, 179, 1, 599040, 0x829023ee
+0, 180, 180, 1, 599040, 0xeafa5127
+0, 181, 181, 1, 599040, 0x1adf2830
+0, 182, 182, 1, 599040, 0x35f07617
+0, 183, 183, 1, 599040, 0x7aa691e2
+0, 184, 184, 1, 599040, 0xd11b3ed2
+0, 185, 185, 1, 599040, 0x69c12b52
+0, 186, 186, 1, 599040, 0x34fb8557
+0, 187, 187, 1, 599040, 0xd06c84ff
+0, 188, 188, 1, 599040, 0x26338170
+0, 189, 189, 1, 599040, 0x3d24f1e9
+0, 190, 190, 1, 599040, 0x28a99f46
+0, 191, 191, 1, 599040, 0x22421eea
+0, 192, 192, 1, 599040, 0xc53b57eb
+0, 193, 193, 1, 599040, 0x752433b8
+0, 194, 194, 1, 599040, 0x6332eaaa
+0, 195, 195, 1, 599040, 0x559d273f
+0, 196, 196, 1, 599040, 0xe9811056
+0, 197, 197, 1, 599040, 0x61acf706
+0, 198, 198, 1, 599040, 0x3893c930
+0, 199, 199, 1, 599040, 0x5d6d3f58
+0, 200, 200, 1, 599040, 0xb645df35
+0, 201, 201, 1, 599040, 0x6af7f2eb
+0, 202, 202, 1, 599040, 0xeb456cc5
+0, 203, 203, 1, 599040, 0x32abac64
+0, 204, 204, 1, 599040, 0x1327da04
+0, 205, 205, 1, 599040, 0x73ca53b9
+0, 206, 206, 1, 599040, 0xe940d23e
+0, 207, 207, 1, 599040, 0xc6fdf611
+0, 208, 208, 1, 599040, 0xc72e4309
+0, 209, 209, 1, 599040, 0xecab46a1
+0, 210, 210, 1, 599040, 0xb248b91e
+0, 211, 211, 1, 599040, 0xe9aeb62c
+0, 212, 212, 1, 599040, 0x5827cf39
+0, 213, 213, 1, 599040, 0x763a74d6
+0, 214, 214, 1, 599040, 0x232e397c
+0, 215, 215, 1, 599040, 0xe2ef8213
+0, 216, 216, 1, 599040, 0xddcbe94f
+0, 217, 217, 1, 599040, 0xe8a8919a
+0, 218, 218, 1, 599040, 0x5860fae0
+0, 219, 219, 1, 599040, 0x525b1a95
+0, 220, 220, 1, 599040, 0x50e36027
+0, 221, 221, 1, 599040, 0xd05ee599
+0, 222, 222, 1, 599040, 0xc1e7b87b
+0, 223, 223, 1, 599040, 0x2edfa52c
+0, 224, 224, 1, 599040, 0xca147244
+0, 225, 225, 1, 599040, 0x9e0a77b7
+0, 226, 226, 1, 599040, 0x88ac8035
+0, 227, 227, 1, 599040, 0xe34c890a
+0, 228, 228, 1, 599040, 0xbe4feadd
+0, 229, 229, 1, 599040, 0xd5a7503d
+0, 230, 230, 1, 599040, 0xae18e82d
+0, 231, 231, 1, 599040, 0x66cf3881
+0, 232, 232, 1, 599040, 0x9f08a65c
+0, 233, 233, 1, 599040, 0xeb3e1a58
+0, 234, 234, 1, 599040, 0x2b83004a
+0, 235, 235, 1, 599040, 0x65be32c9
+0, 236, 236, 1, 599040, 0x231586fa
+0, 237, 237, 1, 599040, 0x7e5724fb
+0, 238, 238, 1, 599040, 0xfebe47b6
+0, 239, 239, 1, 599040, 0xfeeb9a38
+0, 240, 240, 1, 599040, 0x44e90683
+0, 241, 241, 1, 599040, 0x546d03f4
+0, 242, 242, 1, 599040, 0x211a534e
+0, 243, 243, 1, 599040, 0x12d2a800
+0, 244, 244, 1, 599040, 0xa6022d19
+0, 245, 245, 1, 599040, 0x6bedd152
+0, 246, 246, 1, 599040, 0x6f7de80b
+0, 247, 247, 1, 599040, 0x778f0771
+0, 248, 248, 1, 599040, 0xe63e4241
+0, 249, 249, 1, 599040, 0xa0298023
+0, 250, 250, 1, 599040, 0xc4c5b8b2
+0, 251, 251, 1, 599040, 0xcca64f1c
+0, 252, 252, 1, 599040, 0xfec4d1a0
+0, 253, 253, 1, 599040, 0xcb7c4b80
+0, 254, 254, 1, 599040, 0x0795f7b7
+0, 255, 255, 1, 599040, 0x5f45706c
+0, 256, 256, 1, 599040, 0x927f04d8
+0, 257, 257, 1, 599040, 0x4c201f08
+0, 258, 258, 1, 599040, 0xdb447b37
+0, 259, 259, 1, 599040, 0xae33725e
+0, 260, 260, 1, 599040, 0x474281af
+0, 261, 261, 1, 599040, 0xe198764e
+0, 262, 262, 1, 599040, 0xb226916f
+0, 263, 263, 1, 599040, 0x8a7156a5
+0, 264, 264, 1, 599040, 0x5fe639ab
+0, 265, 265, 1, 599040, 0xaa62b79e
+0, 266, 266, 1, 599040, 0x94618e23
+0, 267, 267, 1, 599040, 0x47ba12f0
+0, 268, 268, 1, 599040, 0xd33c215e
+0, 269, 269, 1, 599040, 0x581e0537
+0, 270, 270, 1, 599040, 0x19dce924
+0, 271, 271, 1, 599040, 0x95329055
+0, 272, 272, 1, 599040, 0x6d2eb80f
+0, 273, 273, 1, 599040, 0x11d5e940
+0, 274, 274, 1, 599040, 0x30aec978
+0, 275, 275, 1, 599040, 0xd742df04
+0, 276, 276, 1, 599040, 0xef9ef4ae
+0, 277, 277, 1, 599040, 0x51d8fb34
+0, 278, 278, 1, 599040, 0xbb6e070a
+0, 279, 279, 1, 599040, 0x785a9813
+0, 280, 280, 1, 599040, 0xb94d8771
+0, 281, 281, 1, 599040, 0x8bd2fe53
+0, 282, 282, 1, 599040, 0x6b600868
+0, 283, 283, 1, 599040, 0x4b1d6a6f
+0, 284, 284, 1, 599040, 0x974f6365
+0, 285, 285, 1, 599040, 0xebefa21d
+0, 286, 286, 1, 599040, 0x8ce62dad
+0, 287, 287, 1, 599040, 0x7a6e6e1b
+0, 288, 288, 1, 599040, 0x3746d218
+0, 289, 289, 1, 599040, 0xc1aa50d9
+0, 290, 290, 1, 599040, 0xda60f976
+0, 291, 291, 1, 599040, 0x98274aa8
+0, 292, 292, 1, 599040, 0xdf09c760
+0, 293, 293, 1, 599040, 0xeb485b8f
+0, 294, 294, 1, 599040, 0xad76453b
+0, 295, 295, 1, 599040, 0x6eaee19a
+0, 296, 296, 1, 599040, 0x464e9cc8
+0, 297, 297, 1, 599040, 0xccd0bd12
+0, 298, 298, 1, 599040, 0xc7345e2b
+0, 299, 299, 1, 599040, 0xe51dd0a9
+0, 300, 300, 1, 599040, 0x11b9586b
+0, 301, 301, 1, 599040, 0xcb2c85b8
+0, 302, 302, 1, 599040, 0x024ce62d
+0, 303, 303, 1, 599040, 0x8c1da4eb
+0, 304, 304, 1, 599040, 0x9924ed3f
+0, 305, 305, 1, 599040, 0xc8f89a61
+0, 306, 306, 1, 599040, 0x52db38f2
+0, 307, 307, 1, 599040, 0xf1baca44
+0, 308, 308, 1, 599040, 0x8d1b322e
+0, 309, 309, 1, 599040, 0x5e8a990e
+0, 310, 310, 1, 599040, 0xfe281b7c
+0, 311, 311, 1, 599040, 0x065ced47
+0, 312, 312, 1, 599040, 0x962087db
+0, 313, 313, 1, 599040, 0x2e932805
+0, 314, 314, 1, 599040, 0x9a4b4946
+0, 315, 315, 1, 599040, 0x504bea02
+0, 316, 316, 1, 599040, 0xff97cf64
+0, 317, 317, 1, 599040, 0xcca9a61c
+0, 318, 318, 1, 599040, 0x1ab70ff5
+0, 319, 319, 1, 599040, 0x99ed2919
+0, 320, 320, 1, 599040, 0xa02f40d2
+0, 321, 321, 1, 599040, 0x8a1d83c2
+0, 322, 322, 1, 599040, 0xaacec6c2
+0, 323, 323, 1, 599040, 0x4f6fe261
+0, 324, 324, 1, 599040, 0x1dde4745
+0, 325, 325, 1, 599040, 0xa17bdf95
+0, 326, 326, 1, 599040, 0xcb5b56b3
+0, 327, 327, 1, 599040, 0x7088cdd4
+0, 328, 328, 1, 599040, 0xca02bafb
+0, 329, 329, 1, 599040, 0x3c5ca543
+0, 330, 330, 1, 599040, 0x4ab80de3
+0, 331, 331, 1, 599040, 0x75edb57b
+0, 332, 332, 1, 599040, 0x772ef858
+0, 333, 333, 1, 599040, 0xd7fa8d9f
+0, 334, 334, 1, 599040, 0xbc515acc
+0, 335, 335, 1, 599040, 0xb1b66d54
+0, 336, 336, 1, 599040, 0x40290b6a
+0, 337, 337, 1, 599040, 0xd1ff952e
+0, 338, 338, 1, 599040, 0x5641abf7
+0, 339, 339, 1, 599040, 0x3411e0fd
+0, 340, 340, 1, 599040, 0xed4abbaf
+0, 341, 341, 1, 599040, 0x34d40ea4
+0, 342, 342, 1, 599040, 0xa9983db0
+0, 343, 343, 1, 599040, 0x58dc8d9a
+0, 344, 344, 1, 599040, 0x24a989a2
+0, 345, 345, 1, 599040, 0xc9d1dcdd
+0, 346, 346, 1, 599040, 0x6df3031f
+0, 347, 347, 1, 599040, 0xa67339d9
+0, 348, 348, 1, 599040, 0x545b3ed1
+0, 349, 349, 1, 599040, 0xb4d98187
+0, 350, 350, 1, 599040, 0xdd2f8588
+0, 351, 351, 1, 599040, 0x2aee5737
+0, 352, 352, 1, 599040, 0xe7c90c87
+0, 353, 353, 1, 599040, 0xb547f0bc
+0, 354, 354, 1, 599040, 0x69cc594a
+0, 355, 355, 1, 599040, 0xa01adf9c
+0, 356, 356, 1, 599040, 0x77021bc9
+0, 357, 357, 1, 599040, 0x1cd7e74b
+0, 358, 358, 1, 599040, 0x4d284292
+0, 359, 359, 1, 599040, 0xe57fd832
+0, 360, 360, 1, 599040, 0x76992cf7
+0, 361, 361, 1, 599040, 0x88156158
+0, 362, 362, 1, 599040, 0xc872db18
+0, 363, 363, 1, 599040, 0xc0487bf4
+0, 364, 364, 1, 599040, 0x9f3aab7b
+0, 365, 365, 1, 599040, 0xfddd1c86
+0, 366, 366, 1, 599040, 0x2a991cff
+0, 367, 367, 1, 599040, 0x97e3623f
+0, 368, 368, 1, 599040, 0x69e5900a
+0, 369, 369, 1, 599040, 0x7a5167ec
+0, 370, 370, 1, 599040, 0x74bf045a
+0, 371, 371, 1, 599040, 0x5b2c1554
+0, 372, 372, 1, 599040, 0xc7e9c2e1
+0, 373, 373, 1, 599040, 0x9d76e364
+0, 374, 374, 1, 599040, 0x2c365ed8
+0, 375, 375, 1, 599040, 0x3b7bb213
+0, 376, 376, 1, 599040, 0x00a34fa9
+0, 377, 377, 1, 599040, 0x0a82f6b8
+0, 378, 378, 1, 599040, 0x34f8cf6b
+0, 379, 379, 1, 599040, 0x283a256f
+0, 380, 380, 1, 599040, 0x89dfe63a
+0, 381, 381, 1, 599040, 0x757c7bc3
+0, 382, 382, 1, 599040, 0xbcbf4f4a
+0, 383, 383, 1, 599040, 0x45fe93d3
+0, 384, 384, 1, 599040, 0xa93c4724
+0, 385, 385, 1, 599040, 0x25862ef7
+0, 386, 386, 1, 599040, 0xff94b8eb
+0, 387, 387, 1, 599040, 0x9d350c21
+0, 388, 388, 1, 599040, 0x90d6cce5
+0, 389, 389, 1, 599040, 0x5c3e51c8
+0, 390, 390, 1, 599040, 0x8f966096
+0, 391, 391, 1, 599040, 0xddc8ad04
+0, 392, 392, 1, 599040, 0xb64a170a
+0, 393, 393, 1, 599040, 0xfb8fa0c6
+0, 394, 394, 1, 599040, 0x99fa48dc
+0, 395, 395, 1, 599040, 0xd62e9344
+0, 396, 396, 1, 599040, 0x55ff8d51
+0, 397, 397, 1, 599040, 0x1e9809bd
+0, 398, 398, 1, 599040, 0x00f0122d
+0, 399, 399, 1, 599040, 0x5af2911e
+0, 400, 400, 1, 599040, 0xbfcd6c1d
+0, 401, 401, 1, 599040, 0xd809c652
+0, 402, 402, 1, 599040, 0xee36969a
+0, 403, 403, 1, 599040, 0x9c0ed842
+0, 404, 404, 1, 599040, 0x4e07a2b0
+0, 405, 405, 1, 599040, 0xa5b3202b
+0, 406, 406, 1, 599040, 0x4c1add0e
+0, 407, 407, 1, 599040, 0x489b2fa9
+0, 408, 408, 1, 599040, 0xa088c512
+0, 409, 409, 1, 599040, 0x4f6121ac
+0, 410, 410, 1, 599040, 0x1959f62b
+0, 411, 411, 1, 599040, 0x2d51a5c4
+0, 412, 412, 1, 599040, 0x95e70f4f
+0, 413, 413, 1, 599040, 0x4eab3c11
+0, 414, 414, 1, 599040, 0xf2c2b9b5
+0, 415, 415, 1, 599040, 0x62f50ffe
+0, 416, 416, 1, 599040, 0x2104d2f8
+0, 417, 417, 1, 599040, 0x42a8b39f
+0, 418, 418, 1, 599040, 0x857f1fe6
+0, 419, 419, 1, 599040, 0x6ac5190d
+0, 420, 420, 1, 599040, 0x228d7a0b
+0, 421, 421, 1, 599040, 0x0042ef94
+0, 422, 422, 1, 599040, 0x4a83e001
+0, 423, 423, 1, 599040, 0xc43fec08
+0, 424, 424, 1, 599040, 0x5e029548
+0, 425, 425, 1, 599040, 0xbc89dea9
+0, 426, 426, 1, 599040, 0x6c5d88cf
+0, 427, 427, 1, 599040, 0x3a5dabfb
+0, 428, 428, 1, 599040, 0x876e1e54
+0, 429, 429, 1, 599040, 0x55715da8
+0, 430, 430, 1, 599040, 0x199c039b
+0, 431, 431, 1, 599040, 0x0286f71e
+0, 432, 432, 1, 599040, 0xf9a244a1
+0, 433, 433, 1, 599040, 0xf5655275
+0, 434, 434, 1, 599040, 0xde3dba0c
+0, 435, 435, 1, 599040, 0x617f8963
+0, 436, 436, 1, 599040, 0x0fe0e661
+0, 437, 437, 1, 599040, 0x8ba905ea
+0, 438, 438, 1, 599040, 0xb2812b34
+0, 439, 439, 1, 599040, 0x32d61c8b
+0, 440, 440, 1, 599040, 0xb7603400
+0, 441, 441, 1, 599040, 0x232c278f
+0, 442, 442, 1, 599040, 0xdf61c27d
+0, 443, 443, 1, 599040, 0xa053482f
+0, 444, 444, 1, 599040, 0x109724d3
+0, 445, 445, 1, 599040, 0x49d36800
+0, 446, 446, 1, 599040, 0x4a103bff
+0, 447, 447, 1, 599040, 0x7cd3813b
+0, 448, 448, 1, 599040, 0xeef677d7
+0, 449, 449, 1, 599040, 0xc5ad66c2
+0, 450, 450, 1, 599040, 0xa06e472d
+0, 451, 451, 1, 599040, 0x53182cc5
+0, 452, 452, 1, 599040, 0x9e62bfc0
+0, 453, 453, 1, 599040, 0x93515843
+0, 454, 454, 1, 599040, 0x5e0778d7
+0, 455, 455, 1, 599040, 0x957a6d55
+0, 456, 456, 1, 599040, 0x0bc26b3d
+0, 457, 457, 1, 599040, 0x5e0bc514
+0, 458, 458, 1, 599040, 0x7f717a98
+0, 459, 459, 1, 599040, 0x8497968c
+0, 460, 460, 1, 599040, 0x8fb527b8
+0, 461, 461, 1, 599040, 0x8580e487
+0, 462, 462, 1, 599040, 0x59b2d7cc
+0, 463, 463, 1, 599040, 0x5fbc38d7
+0, 464, 464, 1, 599040, 0xb1ba014e
+0, 465, 465, 1, 599040, 0x10481d8f
+0, 466, 466, 1, 599040, 0xd42e42e0
+0, 467, 467, 1, 599040, 0x14a361c1
+0, 468, 468, 1, 599040, 0x58378917
+0, 469, 469, 1, 599040, 0xaeb99a82
+0, 470, 470, 1, 599040, 0x5666ef55
+0, 471, 471, 1, 599040, 0xbd0ce495
+0, 472, 472, 1, 599040, 0xf13af36c
+0, 473, 473, 1, 599040, 0x55e8b101
+0, 474, 474, 1, 599040, 0x4e2966b4
+0, 475, 475, 1, 599040, 0xd973e873
+0, 476, 476, 1, 599040, 0x72d55685
+0, 477, 477, 1, 599040, 0x48eee8c2
+0, 478, 478, 1, 599040, 0x61291b38
+0, 479, 479, 1, 599040, 0x91f839f8
+0, 480, 480, 1, 599040, 0x0a4e9585
+0, 481, 481, 1, 599040, 0x02e0f1f0
+0, 482, 482, 1, 599040, 0xc104009c
+0, 483, 483, 1, 599040, 0x9417127e
+0, 484, 484, 1, 599040, 0x4630302e
+0, 485, 485, 1, 599040, 0x692141ea
+0, 486, 486, 1, 599040, 0x1ebed0bd
+0, 487, 487, 1, 599040, 0x362544a8
+0, 488, 488, 1, 599040, 0xd9cbef36
+0, 489, 489, 1, 599040, 0x54cda997
+0, 490, 490, 1, 599040, 0x79463ed1
+0, 491, 491, 1, 599040, 0xe95b66eb
+0, 492, 492, 1, 599040, 0x5bdaa63e
+0, 493, 493, 1, 599040, 0x72ced562
+0, 494, 494, 1, 599040, 0xcb2bdc53
+0, 495, 495, 1, 599040, 0x4ff80855
+0, 496, 496, 1, 599040, 0x68515ba6
+0, 497, 497, 1, 599040, 0x56228d2d
+0, 498, 498, 1, 599040, 0xb72a68ed
+0, 499, 499, 1, 599040, 0x111cc604
diff --git a/tests/ref/fate/hevc-conformance-MVEDGE_A_qualcomm_3 b/tests/ref/fate/hevc-conformance-MVEDGE_A_qualcomm_3
new file mode 100644
index 0000000..0db06c5
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-MVEDGE_A_qualcomm_3
@@ -0,0 +1,18 @@
+#tb 0: 1/25
+0, 0, 0, 1, 149760, 0x1d68213a
+0, 1, 1, 1, 149760, 0x9cc81d30
+0, 2, 2, 1, 149760, 0xa3cf6438
+0, 3, 3, 1, 149760, 0x6acf213a
+0, 4, 4, 1, 149760, 0x0f75ce7b
+0, 5, 5, 1, 149760, 0x5e0286a7
+0, 6, 6, 1, 149760, 0xc62cd2b0
+0, 7, 7, 1, 149760, 0x7d9af3ac
+0, 8, 8, 1, 149760, 0x9d58afc7
+0, 9, 9, 1, 149760, 0x91c5ad7f
+0, 10, 10, 1, 149760, 0xc43c5b0a
+0, 11, 11, 1, 149760, 0x6b8cc1a5
+0, 12, 12, 1, 149760, 0x4cebb13e
+0, 13, 13, 1, 149760, 0xca136846
+0, 14, 14, 1, 149760, 0xba22e581
+0, 15, 15, 1, 149760, 0x2844ddd3
+0, 16, 16, 1, 149760, 0xf943399e
diff --git a/tests/ref/fate/hevc-conformance-NUT_A_ericsson_4 b/tests/ref/fate/hevc-conformance-NUT_A_ericsson_4
new file mode 100644
index 0000000..fe65880
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-NUT_A_ericsson_4
@@ -0,0 +1,35 @@
+#tb 0: 1/25
+0, 0, 0, 1, 149760, 0x8ce7200b
+0, 1, 1, 1, 149760, 0x73610669
+0, 2, 2, 1, 149760, 0x42942047
+0, 3, 3, 1, 149760, 0x57334d85
+0, 4, 4, 1, 149760, 0xdd97fbb3
+0, 5, 5, 1, 149760, 0x10469b12
+0, 6, 6, 1, 149760, 0x9b4231f0
+0, 7, 7, 1, 149760, 0x2b295a52
+0, 8, 8, 1, 149760, 0xdaf7c29f
+0, 9, 9, 1, 149760, 0x6798d072
+0, 10, 10, 1, 149760, 0xf77ae91e
+0, 11, 11, 1, 149760, 0xe2d516c9
+0, 12, 12, 1, 149760, 0x5cf0b221
+0, 13, 13, 1, 149760, 0x1d34991e
+0, 14, 14, 1, 149760, 0xb730d93a
+0, 15, 15, 1, 149760, 0x643b1861
+0, 16, 16, 1, 149760, 0x436586ff
+0, 17, 17, 1, 149760, 0xa65d9b80
+0, 18, 18, 1, 149760, 0x1d395210
+0, 19, 19, 1, 149760, 0x0580f2be
+0, 20, 20, 1, 149760, 0x8e4cea96
+0, 21, 21, 1, 149760, 0x6c98d019
+0, 22, 22, 1, 149760, 0x842803c8
+0, 23, 23, 1, 149760, 0xddc196ee
+0, 24, 24, 1, 149760, 0x89e45523
+0, 25, 25, 1, 149760, 0x2a36b008
+0, 26, 26, 1, 149760, 0x14a319f7
+0, 27, 27, 1, 149760, 0x7394854c
+0, 28, 28, 1, 149760, 0x26dcf933
+0, 29, 29, 1, 149760, 0x5b000b7e
+0, 30, 30, 1, 149760, 0x6e76bded
+0, 31, 31, 1, 149760, 0x0284d92d
+0, 32, 32, 1, 149760, 0xf14a25e0
+0, 33, 33, 1, 149760, 0x10c03d98
diff --git a/tests/ref/fate/hevc-conformance-PICSIZE_A_Bossen_1 b/tests/ref/fate/hevc-conformance-PICSIZE_A_Bossen_1
new file mode 100644
index 0000000..4c09ca5
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-PICSIZE_A_Bossen_1
@@ -0,0 +1,11 @@
+#tb 0: 1/25
+0, 0, 0, 1, 13368960, 0x830b3a1d
+0, 1, 1, 1, 13368960, 0x120ca009
+0, 2, 2, 1, 13368960, 0xc94e0d86
+0, 3, 3, 1, 13368960, 0x3e97d237
+0, 4, 4, 1, 13368960, 0x1caaa873
+0, 5, 5, 1, 13368960, 0xc6af86c6
+0, 6, 6, 1, 13368960, 0x277ee61a
+0, 7, 7, 1, 13368960, 0x7832ef4e
+0, 8, 8, 1, 13368960, 0x328142e9
+0, 9, 9, 1, 13368960, 0xbe22f686
diff --git a/tests/ref/fate/hevc-conformance-PICSIZE_B_Bossen_1 b/tests/ref/fate/hevc-conformance-PICSIZE_B_Bossen_1
new file mode 100644
index 0000000..a3ab7c8
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-PICSIZE_B_Bossen_1
@@ -0,0 +1,11 @@
+#tb 0: 1/25
+0, 0, 0, 1, 13368960, 0xe1e32c3d
+0, 1, 1, 1, 13368960, 0x75a503d3
+0, 2, 2, 1, 13368960, 0x71f33a0a
+0, 3, 3, 1, 13368960, 0xd9fe5306
+0, 4, 4, 1, 13368960, 0x2528926a
+0, 5, 5, 1, 13368960, 0x4ae4e500
+0, 6, 6, 1, 13368960, 0x01949c16
+0, 7, 7, 1, 13368960, 0x57b6ea2f
+0, 8, 8, 1, 13368960, 0xfd2b2055
+0, 9, 9, 1, 13368960, 0xc4246a9b
diff --git a/tests/ref/fate/hevc-conformance-PICSIZE_C_Bossen_1 b/tests/ref/fate/hevc-conformance-PICSIZE_C_Bossen_1
new file mode 100644
index 0000000..10520d1
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-PICSIZE_C_Bossen_1
@@ -0,0 +1,11 @@
+#tb 0: 1/25
+0, 0, 0, 1, 3339072, 0x28be238d
+0, 1, 1, 1, 3339072, 0x43b62aae
+0, 2, 2, 1, 3339072, 0x36259da6
+0, 3, 3, 1, 3339072, 0xd0dbbc1e
+0, 4, 4, 1, 3339072, 0x20df7c7c
+0, 5, 5, 1, 3339072, 0xb8872e77
+0, 6, 6, 1, 3339072, 0xceb4cce4
+0, 7, 7, 1, 3339072, 0x4ffa1dab
+0, 8, 8, 1, 3339072, 0x1c687703
+0, 9, 9, 1, 3339072, 0x5a0fa46f
diff --git a/tests/ref/fate/hevc-conformance-PICSIZE_D_Bossen_1 b/tests/ref/fate/hevc-conformance-PICSIZE_D_Bossen_1
new file mode 100644
index 0000000..6f1c4fb
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-PICSIZE_D_Bossen_1
@@ -0,0 +1,11 @@
+#tb 0: 1/25
+0, 0, 0, 1, 3339072, 0xcb16f53e
+0, 1, 1, 1, 3339072, 0x6f1da8ec
+0, 2, 2, 1, 3339072, 0x978dae98
+0, 3, 3, 1, 3339072, 0x34becc01
+0, 4, 4, 1, 3339072, 0x9c900137
+0, 5, 5, 1, 3339072, 0x02fe1d40
+0, 6, 6, 1, 3339072, 0xda9703b6
+0, 7, 7, 1, 3339072, 0x73e5ff5a
+0, 8, 8, 1, 3339072, 0xeec94fab
+0, 9, 9, 1, 3339072, 0xf4a36fc5
diff --git a/tests/ref/fate/hevc-conformance-PMERGE_A_TI_3 b/tests/ref/fate/hevc-conformance-PMERGE_A_TI_3
new file mode 100644
index 0000000..8491172
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-PMERGE_A_TI_3
@@ -0,0 +1,9 @@
+#tb 0: 1/25
+0, 0, 0, 1, 149760, 0x8edb27d7
+0, 1, 1, 1, 149760, 0x187419b5
+0, 2, 2, 1, 149760, 0x61100980
+0, 3, 3, 1, 149760, 0xd799123e
+0, 4, 4, 1, 149760, 0x9011c8d0
+0, 5, 5, 1, 149760, 0xeafe7d99
+0, 6, 6, 1, 149760, 0x94f32245
+0, 7, 7, 1, 149760, 0x8185910a
diff --git a/tests/ref/fate/hevc-conformance-PMERGE_B_TI_3 b/tests/ref/fate/hevc-conformance-PMERGE_B_TI_3
new file mode 100644
index 0000000..1f15a02
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-PMERGE_B_TI_3
@@ -0,0 +1,9 @@
+#tb 0: 1/25
+0, 0, 0, 1, 149760, 0x8edb27d7
+0, 1, 1, 1, 149760, 0xcebf1b76
+0, 2, 2, 1, 149760, 0x33930fb0
+0, 3, 3, 1, 149760, 0xb2933277
+0, 4, 4, 1, 149760, 0x2ff5fd5d
+0, 5, 5, 1, 149760, 0x6616a17a
+0, 6, 6, 1, 149760, 0x3abc48ad
+0, 7, 7, 1, 149760, 0xc12491ef
diff --git a/tests/ref/fate/hevc-conformance-PMERGE_C_TI_3 b/tests/ref/fate/hevc-conformance-PMERGE_C_TI_3
new file mode 100644
index 0000000..bf474cc
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-PMERGE_C_TI_3
@@ -0,0 +1,9 @@
+#tb 0: 1/25
+0, 0, 0, 1, 149760, 0x8edb27d7
+0, 1, 1, 1, 149760, 0x2c271a9b
+0, 2, 2, 1, 149760, 0x53e419f3
+0, 3, 3, 1, 149760, 0x96c92a29
+0, 4, 4, 1, 149760, 0x62d5e85b
+0, 5, 5, 1, 149760, 0xea307d47
+0, 6, 6, 1, 149760, 0x9cc40dec
+0, 7, 7, 1, 149760, 0x37d977fa
diff --git a/tests/ref/fate/hevc-conformance-PMERGE_D_TI_3 b/tests/ref/fate/hevc-conformance-PMERGE_D_TI_3
new file mode 100644
index 0000000..2af0e1f
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-PMERGE_D_TI_3
@@ -0,0 +1,9 @@
+#tb 0: 1/25
+0, 0, 0, 1, 149760, 0x8edb27d7
+0, 1, 1, 1, 149760, 0xf11a32ce
+0, 2, 2, 1, 149760, 0x0802237c
+0, 3, 3, 1, 149760, 0x366621a7
+0, 4, 4, 1, 149760, 0x89aacefd
+0, 5, 5, 1, 149760, 0xb3837d16
+0, 6, 6, 1, 149760, 0x5f822072
+0, 7, 7, 1, 149760, 0x24cb9377
diff --git a/tests/ref/fate/hevc-conformance-PMERGE_E_TI_3 b/tests/ref/fate/hevc-conformance-PMERGE_E_TI_3
new file mode 100644
index 0000000..df97237
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-PMERGE_E_TI_3
@@ -0,0 +1,9 @@
+#tb 0: 1/25
+0, 0, 0, 1, 149760, 0x8edb27d7
+0, 1, 1, 1, 149760, 0xea7b30bf
+0, 2, 2, 1, 149760, 0x273d092a
+0, 3, 3, 1, 149760, 0xef4e0ff0
+0, 4, 4, 1, 149760, 0x9805e02c
+0, 5, 5, 1, 149760, 0xdeb17cbc
+0, 6, 6, 1, 149760, 0xe5c903a4
+0, 7, 7, 1, 149760, 0x838d66b9
diff --git a/tests/ref/fate/hevc-conformance-POC_A_Bossen_3 b/tests/ref/fate/hevc-conformance-POC_A_Bossen_3
new file mode 100644
index 0000000..885d0e4
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-POC_A_Bossen_3
@@ -0,0 +1,6 @@
+#tb 0: 1/25
+0, 0, 0, 1, 149760, 0xda17acd4
+0, 1, 1, 1, 149760, 0x1691b47f
+0, 2, 2, 1, 149760, 0xeebeac0c
+0, 3, 3, 1, 149760, 0x895c9f62
+0, 4, 4, 1, 149760, 0x9e2077e8
diff --git a/tests/ref/fate/hevc-conformance-PPS_A_qualcomm_7 b/tests/ref/fate/hevc-conformance-PPS_A_qualcomm_7
new file mode 100644
index 0000000..ef57f74
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-PPS_A_qualcomm_7
@@ -0,0 +1,82 @@
+#tb 0: 1/25
+0, 0, 0, 1, 599040, 0x87159328
+0, 1, 1, 1, 599040, 0x825672ff
+0, 2, 2, 1, 599040, 0x2f4224ff
+0, 3, 3, 1, 599040, 0x4be431ff
+0, 4, 4, 1, 599040, 0xa0118b14
+0, 5, 5, 1, 599040, 0x488aac33
+0, 6, 6, 1, 599040, 0x1edd0d4e
+0, 7, 7, 1, 599040, 0x7f4562a2
+0, 8, 8, 1, 599040, 0xe177a7d4
+0, 9, 9, 1, 599040, 0x32d2fd58
+0, 10, 10, 1, 599040, 0x81d50c36
+0, 11, 11, 1, 599040, 0xdf32810d
+0, 12, 12, 1, 599040, 0xc4f50543
+0, 13, 13, 1, 599040, 0x777bfdce
+0, 14, 14, 1, 599040, 0x01db8731
+0, 15, 15, 1, 599040, 0x74ae2b2c
+0, 16, 16, 1, 599040, 0x424e130a
+0, 17, 17, 1, 599040, 0x7002f7c8
+0, 18, 18, 1, 599040, 0xde098c5b
+0, 19, 19, 1, 599040, 0x072ca0e3
+0, 20, 20, 1, 599040, 0x6c50e3ba
+0, 21, 21, 1, 599040, 0xa398c530
+0, 22, 22, 1, 599040, 0xcd8a780a
+0, 23, 23, 1, 599040, 0x7c849e63
+0, 24, 24, 1, 599040, 0xb70e2a1f
+0, 25, 25, 1, 599040, 0xc00d893c
+0, 26, 26, 1, 599040, 0x5da32c94
+0, 27, 27, 1, 599040, 0xc3177b8c
+0, 28, 28, 1, 599040, 0x06668480
+0, 29, 29, 1, 599040, 0xbceeac78
+0, 30, 30, 1, 599040, 0x162d5cd1
+0, 31, 31, 1, 599040, 0x071b71c4
+0, 32, 32, 1, 599040, 0xfe61e0b2
+0, 33, 33, 1, 599040, 0xe78c121f
+0, 34, 34, 1, 599040, 0x3b47c051
+0, 35, 35, 1, 599040, 0x10c1eedd
+0, 36, 36, 1, 599040, 0x09cf2d2c
+0, 37, 37, 1, 599040, 0xc4272450
+0, 38, 38, 1, 599040, 0x3a9e0db7
+0, 39, 39, 1, 599040, 0xe62595ad
+0, 40, 40, 1, 599040, 0xc03669a5
+0, 41, 41, 1, 599040, 0x4fbb058e
+0, 42, 42, 1, 599040, 0xaaee8771
+0, 43, 43, 1, 599040, 0xcc4f3a71
+0, 44, 44, 1, 599040, 0xc5717c31
+0, 45, 45, 1, 599040, 0xe2bc02fc
+0, 46, 46, 1, 599040, 0x380e06eb
+0, 47, 47, 1, 599040, 0x15d4ba04
+0, 48, 48, 1, 599040, 0xb9204342
+0, 49, 49, 1, 599040, 0xb9d9a246
+0, 50, 50, 1, 599040, 0xb5611280
+0, 51, 51, 1, 599040, 0xc80e3909
+0, 52, 52, 1, 599040, 0xef93ecbd
+0, 53, 53, 1, 599040, 0xdd6b435e
+0, 54, 54, 1, 599040, 0x1622f253
+0, 55, 55, 1, 599040, 0x41cd55a6
+0, 56, 56, 1, 599040, 0x7ed864e7
+0, 57, 57, 1, 599040, 0x1604c563
+0, 58, 58, 1, 599040, 0x1d5a3dc9
+0, 59, 59, 1, 599040, 0xa904a8a5
+0, 60, 60, 1, 599040, 0x19c43226
+0, 61, 61, 1, 599040, 0x60d803e0
+0, 62, 62, 1, 599040, 0xe862b0e0
+0, 63, 63, 1, 599040, 0x37c76c51
+0, 64, 64, 1, 599040, 0x8528cc3c
+0, 65, 65, 1, 599040, 0x03ece1f9
+0, 66, 66, 1, 599040, 0x8f0ef28e
+0, 67, 67, 1, 599040, 0x92164007
+0, 68, 68, 1, 599040, 0x9d3c2ecf
+0, 69, 69, 1, 599040, 0xacf536d4
+0, 70, 70, 1, 599040, 0xbdf6165f
+0, 71, 71, 1, 599040, 0xbc19f80a
+0, 72, 72, 1, 599040, 0x128a6480
+0, 73, 73, 1, 599040, 0xb487c333
+0, 74, 74, 1, 599040, 0x8dc350fa
+0, 75, 75, 1, 599040, 0x0043fe96
+0, 76, 76, 1, 599040, 0x47b502a5
+0, 77, 77, 1, 599040, 0xf62b761f
+0, 78, 78, 1, 599040, 0x608f63c3
+0, 79, 79, 1, 599040, 0xe285d93d
+0, 80, 80, 1, 599040, 0x1c3404cf
diff --git a/tests/ref/fate/hevc-conformance-PS_A_VIDYO_3 b/tests/ref/fate/hevc-conformance-PS_A_VIDYO_3
new file mode 100644
index 0000000..8f7e5e6
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-PS_A_VIDYO_3
@@ -0,0 +1,26 @@
+#tb 0: 1/25
+0, 0, 0, 1, 149760, 0x88619f80
+0, 1, 1, 1, 149760, 0x550bdaf0
+0, 2, 2, 1, 149760, 0x4121f7a2
+0, 3, 3, 1, 149760, 0x210b1d07
+0, 4, 4, 1, 149760, 0x731b7758
+0, 5, 5, 1, 149760, 0x17adb789
+0, 6, 6, 1, 149760, 0x98b2f080
+0, 7, 7, 1, 149760, 0xc0be1f2a
+0, 8, 8, 1, 149760, 0xc01e387a
+0, 9, 9, 1, 149760, 0xd932822b
+0, 10, 10, 1, 149760, 0x16c0a1df
+0, 11, 11, 1, 149760, 0x5aa6c005
+0, 12, 12, 1, 149760, 0xd3aab602
+0, 13, 13, 1, 149760, 0x4e6ecab1
+0, 14, 14, 1, 149760, 0x8a86f1f2
+0, 15, 15, 1, 149760, 0x2ed21e1b
+0, 16, 16, 1, 149760, 0x80892f24
+0, 17, 17, 1, 149760, 0xb8a952ef
+0, 18, 18, 1, 149760, 0x557e57fb
+0, 19, 19, 1, 149760, 0x2b825b2c
+0, 20, 20, 1, 149760, 0x30b69b5e
+0, 21, 21, 1, 149760, 0x802ebf08
+0, 22, 22, 1, 149760, 0x95aadc8e
+0, 23, 23, 1, 149760, 0x4d4c02b7
+0, 24, 24, 1, 149760, 0x3fdd1762
diff --git a/tests/ref/fate/hevc-conformance-PS_B_VIDYO_3 b/tests/ref/fate/hevc-conformance-PS_B_VIDYO_3
new file mode 100644
index 0000000..8f7e5e6
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-PS_B_VIDYO_3
@@ -0,0 +1,26 @@
+#tb 0: 1/25
+0, 0, 0, 1, 149760, 0x88619f80
+0, 1, 1, 1, 149760, 0x550bdaf0
+0, 2, 2, 1, 149760, 0x4121f7a2
+0, 3, 3, 1, 149760, 0x210b1d07
+0, 4, 4, 1, 149760, 0x731b7758
+0, 5, 5, 1, 149760, 0x17adb789
+0, 6, 6, 1, 149760, 0x98b2f080
+0, 7, 7, 1, 149760, 0xc0be1f2a
+0, 8, 8, 1, 149760, 0xc01e387a
+0, 9, 9, 1, 149760, 0xd932822b
+0, 10, 10, 1, 149760, 0x16c0a1df
+0, 11, 11, 1, 149760, 0x5aa6c005
+0, 12, 12, 1, 149760, 0xd3aab602
+0, 13, 13, 1, 149760, 0x4e6ecab1
+0, 14, 14, 1, 149760, 0x8a86f1f2
+0, 15, 15, 1, 149760, 0x2ed21e1b
+0, 16, 16, 1, 149760, 0x80892f24
+0, 17, 17, 1, 149760, 0xb8a952ef
+0, 18, 18, 1, 149760, 0x557e57fb
+0, 19, 19, 1, 149760, 0x2b825b2c
+0, 20, 20, 1, 149760, 0x30b69b5e
+0, 21, 21, 1, 149760, 0x802ebf08
+0, 22, 22, 1, 149760, 0x95aadc8e
+0, 23, 23, 1, 149760, 0x4d4c02b7
+0, 24, 24, 1, 149760, 0x3fdd1762
diff --git a/tests/ref/fate/hevc-conformance-RAP_A_docomo_4 b/tests/ref/fate/hevc-conformance-RAP_A_docomo_4
new file mode 100644
index 0000000..268f4cd
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-RAP_A_docomo_4
@@ -0,0 +1,87 @@
+#tb 0: 1/25
+0, 0, 0, 1, 149760, 0x1ae5f13d
+0, 1, 1, 1, 149760, 0x0a6ad0e3
+0, 2, 2, 1, 149760, 0x2415af05
+0, 3, 3, 1, 149760, 0xf50f6eef
+0, 4, 4, 1, 149760, 0xef65835c
+0, 5, 5, 1, 149760, 0x4929b5cb
+0, 6, 6, 1, 149760, 0x165c6f55
+0, 7, 7, 1, 149760, 0x9caaa249
+0, 8, 8, 1, 149760, 0x6c25c4cf
+0, 9, 9, 1, 149760, 0x4678cef0
+0, 10, 10, 1, 149760, 0x72e04433
+0, 11, 11, 1, 149760, 0x36f8aa9d
+0, 12, 12, 1, 149760, 0x255189ad
+0, 13, 13, 1, 149760, 0x712d7f7f
+0, 14, 14, 1, 149760, 0x4d088988
+0, 15, 15, 1, 149760, 0xc0da3925
+0, 16, 16, 1, 149760, 0x9990db7c
+0, 17, 17, 1, 149760, 0xb02cc0e8
+0, 18, 18, 1, 149760, 0x3e859d8f
+0, 19, 19, 1, 149760, 0xce786bc1
+0, 20, 20, 1, 149760, 0x87555e5f
+0, 21, 21, 1, 149760, 0x3c95fb7e
+0, 22, 22, 1, 149760, 0xf092b65e
+0, 23, 23, 1, 149760, 0x7db2c04c
+0, 24, 24, 1, 149760, 0x7d39eb21
+0, 25, 25, 1, 149760, 0x2cfd7d57
+0, 26, 26, 1, 149760, 0xb1902c06
+0, 27, 27, 1, 149760, 0xe0eae1d7
+0, 28, 28, 1, 149760, 0xf8212977
+0, 29, 29, 1, 149760, 0x6cb31328
+0, 30, 30, 1, 149760, 0x862ab736
+0, 31, 31, 1, 149760, 0xc7a87f44
+0, 32, 32, 1, 149760, 0x8ff7a1a1
+0, 33, 33, 1, 149760, 0xd7bee49b
+0, 34, 34, 1, 149760, 0x1925db84
+0, 35, 35, 1, 149760, 0xf32a7dc6
+0, 36, 36, 1, 149760, 0x02a1e3b6
+0, 37, 37, 1, 149760, 0xb6398aad
+0, 38, 38, 1, 149760, 0xa3756e2d
+0, 39, 39, 1, 149760, 0xf90f3732
+0, 40, 40, 1, 149760, 0x3b05115a
+0, 41, 41, 1, 149760, 0x81ca9bdb
+0, 42, 42, 1, 149760, 0xa75ee938
+0, 43, 43, 1, 149760, 0x9e5c232f
+0, 44, 44, 1, 149760, 0x64cb04e9
+0, 45, 45, 1, 149760, 0x4064df52
+0, 46, 46, 1, 149760, 0x47fa0afc
+0, 47, 47, 1, 149760, 0xd209252e
+0, 48, 48, 1, 149760, 0x2f811f02
+0, 49, 49, 1, 149760, 0x733b6721
+0, 50, 50, 1, 149760, 0x30b12427
+0, 51, 51, 1, 149760, 0xdf58d3e2
+0, 52, 52, 1, 149760, 0xc144d7be
+0, 53, 53, 1, 149760, 0x48f0ac79
+0, 54, 54, 1, 149760, 0xb8d8a2c6
+0, 55, 55, 1, 149760, 0x2a7d916d
+0, 56, 56, 1, 149760, 0xd9d38cd5
+0, 57, 57, 1, 149760, 0xd7c7f9a6
+0, 58, 58, 1, 149760, 0x64d0df7a
+0, 59, 59, 1, 149760, 0x4e365cff
+0, 60, 60, 1, 149760, 0x74bc2a8b
+0, 61, 61, 1, 149760, 0x70a7cd2b
+0, 62, 62, 1, 149760, 0x0836b51e
+0, 63, 63, 1, 149760, 0xbc37b5d7
+0, 64, 64, 1, 149760, 0xb6d651e5
+0, 65, 65, 1, 149760, 0x7aa0e35f
+0, 66, 66, 1, 149760, 0x0fbc89a3
+0, 67, 67, 1, 149760, 0x2ca2f2a6
+0, 68, 68, 1, 149760, 0xf742c5c5
+0, 69, 69, 1, 149760, 0x4117208f
+0, 70, 70, 1, 149760, 0xec392efb
+0, 71, 71, 1, 149760, 0xbfba5063
+0, 72, 72, 1, 149760, 0xb2499f48
+0, 73, 73, 1, 149760, 0xf1183244
+0, 74, 74, 1, 149760, 0x364a6400
+0, 75, 75, 1, 149760, 0xfcfddf36
+0, 76, 76, 1, 149760, 0xbcc1b37e
+0, 77, 77, 1, 149760, 0xab364748
+0, 78, 78, 1, 149760, 0xebb27fcd
+0, 79, 79, 1, 149760, 0xe2e7a723
+0, 80, 80, 1, 149760, 0xf671b5e0
+0, 81, 81, 1, 149760, 0xbf0cc349
+0, 82, 82, 1, 149760, 0xf195d868
+0, 83, 83, 1, 149760, 0xe0097460
+0, 84, 84, 1, 149760, 0x3d4c1812
+0, 85, 85, 1, 149760, 0x133cd867
diff --git a/tests/ref/fate/hevc-conformance-RAP_B_Bossen_1 b/tests/ref/fate/hevc-conformance-RAP_B_Bossen_1
new file mode 100644
index 0000000..4bea997
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-RAP_B_Bossen_1
@@ -0,0 +1,84 @@
+#tb 0: 1/25
+0, 0, 0, 1, 149760, 0xb989ae7a
+0, 1, 1, 1, 149760, 0x4765caed
+0, 2, 2, 1, 149760, 0xd908c148
+0, 3, 3, 1, 149760, 0xf6ebd66c
+0, 4, 4, 1, 149760, 0x5d5ea14b
+0, 5, 5, 1, 149760, 0xcc939a7c
+0, 6, 6, 1, 149760, 0xa91b8243
+0, 7, 7, 1, 149760, 0x61926618
+0, 8, 8, 1, 149760, 0xe440099c
+0, 9, 9, 1, 149760, 0x18b88a73
+0, 10, 10, 1, 149760, 0xa669f2a9
+0, 11, 11, 1, 149760, 0xc2f6af3a
+0, 12, 12, 1, 149760, 0x02465354
+0, 13, 13, 1, 149760, 0x54e51ff9
+0, 14, 14, 1, 149760, 0xb9f3c056
+0, 15, 15, 1, 149760, 0x050274f9
+0, 16, 16, 1, 149760, 0xd7a413c1
+0, 17, 17, 1, 149760, 0x6e92cda4
+0, 18, 18, 1, 149760, 0x9cb86d4d
+0, 19, 19, 1, 149760, 0x95f440a3
+0, 20, 20, 1, 149760, 0x6dabd616
+0, 21, 21, 1, 149760, 0xd6a0b62d
+0, 22, 22, 1, 149760, 0x585c811b
+0, 23, 23, 1, 149760, 0x50a4d6fc
+0, 24, 24, 1, 149760, 0xe419eb23
+0, 25, 25, 1, 149760, 0x1f0fc316
+0, 26, 26, 1, 149760, 0xf61dc981
+0, 27, 27, 1, 149760, 0xff34d001
+0, 28, 28, 1, 149760, 0x598be76c
+0, 29, 29, 1, 149760, 0xbb50a4d6
+0, 30, 30, 1, 149760, 0x2add9abd
+0, 31, 31, 1, 149760, 0xd74185c7
+0, 32, 32, 1, 149760, 0xcdad6e8e
+0, 33, 33, 1, 149760, 0x54d704ad
+0, 34, 34, 1, 149760, 0xe52e7fc0
+0, 35, 35, 1, 149760, 0xdb331061
+0, 36, 36, 1, 149760, 0x7dacb973
+0, 37, 37, 1, 149760, 0xfc8d5670
+0, 38, 38, 1, 149760, 0xca9024cd
+0, 39, 39, 1, 149760, 0x7fc9bbc2
+0, 40, 40, 1, 149760, 0xe9c386a9
+0, 41, 41, 1, 149760, 0xd0dd1a21
+0, 42, 42, 1, 149760, 0x4b57d734
+0, 43, 43, 1, 149760, 0x55607afc
+0, 44, 44, 1, 149760, 0x567c3e8b
+0, 45, 45, 1, 149760, 0x312eda16
+0, 46, 46, 1, 149760, 0xafcbacf8
+0, 47, 47, 1, 149760, 0xcbde8420
+0, 48, 48, 1, 149760, 0x88a2f29e
+0, 49, 49, 1, 149760, 0x417bf220
+0, 50, 50, 1, 149760, 0xa454835a
+0, 51, 51, 1, 149760, 0x16bf2871
+0, 52, 52, 1, 149760, 0x51253402
+0, 53, 53, 1, 149760, 0x13822dfd
+0, 54, 54, 1, 149760, 0x5e099d3d
+0, 55, 55, 1, 149760, 0xcc19fe87
+0, 56, 56, 1, 149760, 0x7f5f6ce2
+0, 57, 57, 1, 149760, 0x79797a94
+0, 58, 58, 1, 149760, 0x16f26086
+0, 59, 59, 1, 149760, 0x01aedea3
+0, 60, 60, 1, 149760, 0xcafd3221
+0, 61, 61, 1, 149760, 0xcbd61c1f
+0, 62, 62, 1, 149760, 0xf46839e5
+0, 63, 63, 1, 149760, 0x87fb61ee
+0, 64, 64, 1, 149760, 0x3362678b
+0, 65, 65, 1, 149760, 0x6e7fc851
+0, 66, 66, 1, 149760, 0x33f96449
+0, 67, 67, 1, 149760, 0xd9d05007
+0, 68, 68, 1, 149760, 0x477f2cf2
+0, 69, 69, 1, 149760, 0xe1f9ccd0
+0, 70, 70, 1, 149760, 0xb3ba8cfb
+0, 71, 71, 1, 149760, 0x64787995
+0, 72, 72, 1, 149760, 0xc10de4c4
+0, 73, 73, 1, 149760, 0x18dd343f
+0, 74, 74, 1, 149760, 0xa1c51358
+0, 75, 75, 1, 149760, 0x91fe6361
+0, 76, 76, 1, 149760, 0xeec85f94
+0, 77, 77, 1, 149760, 0x00a57402
+0, 78, 78, 1, 149760, 0x4e88cc16
+0, 79, 79, 1, 149760, 0xdbd51976
+0, 80, 80, 1, 149760, 0xfebf6b1a
+0, 81, 81, 1, 149760, 0x052546d2
+0, 82, 82, 1, 149760, 0x046cd73b
diff --git a/tests/ref/fate/hevc-conformance-RPLM_A_qualcomm_4 b/tests/ref/fate/hevc-conformance-RPLM_A_qualcomm_4
new file mode 100644
index 0000000..372d120
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-RPLM_A_qualcomm_4
@@ -0,0 +1,301 @@
+#tb 0: 1/25
+0, 0, 0, 1, 149760, 0xdb5e3b56
+0, 1, 1, 1, 149760, 0xd5320970
+0, 2, 2, 1, 149760, 0x9387ed18
+0, 3, 3, 1, 149760, 0x3ab6fde8
+0, 4, 4, 1, 149760, 0xf5d39a39
+0, 5, 5, 1, 149760, 0xf8c15b34
+0, 6, 6, 1, 149760, 0x12261fdc
+0, 7, 7, 1, 149760, 0x8ed03f57
+0, 8, 8, 1, 149760, 0x04d29f74
+0, 9, 9, 1, 149760, 0x86daf75e
+0, 10, 10, 1, 149760, 0x85d817a4
+0, 11, 11, 1, 149760, 0xf9c97006
+0, 12, 12, 1, 149760, 0x60baf6ad
+0, 13, 13, 1, 149760, 0x7272aa6b
+0, 14, 14, 1, 149760, 0x18e00ede
+0, 15, 15, 1, 149760, 0x60592cfe
+0, 16, 16, 1, 149760, 0x7d49650d
+0, 17, 17, 1, 149760, 0x865e7b22
+0, 18, 18, 1, 149760, 0xad6a33e4
+0, 19, 19, 1, 149760, 0x7c8ab573
+0, 20, 20, 1, 149760, 0x0c7d8afa
+0, 21, 21, 1, 149760, 0xb0e567a3
+0, 22, 22, 1, 149760, 0x3c2ccbf1
+0, 23, 23, 1, 149760, 0x0804aead
+0, 24, 24, 1, 149760, 0x0dcb6756
+0, 25, 25, 1, 149760, 0x99bc82dd
+0, 26, 26, 1, 149760, 0x4d2907f1
+0, 27, 27, 1, 149760, 0xc4c330ff
+0, 28, 28, 1, 149760, 0x6c73cef4
+0, 29, 29, 1, 149760, 0xbaa82ab1
+0, 30, 30, 1, 149760, 0xeea3d591
+0, 31, 31, 1, 149760, 0x8240d007
+0, 32, 32, 1, 149760, 0x698f11e4
+0, 33, 33, 1, 149760, 0x46700948
+0, 34, 34, 1, 149760, 0x819e62d9
+0, 35, 35, 1, 149760, 0x0cfe1471
+0, 36, 36, 1, 149760, 0xf30dc9da
+0, 37, 37, 1, 149760, 0x81ea3390
+0, 38, 38, 1, 149760, 0x85bc8dec
+0, 39, 39, 1, 149760, 0x01d3451a
+0, 40, 40, 1, 149760, 0x626dc94b
+0, 41, 41, 1, 149760, 0xf50f2a66
+0, 42, 42, 1, 149760, 0x6294bc3e
+0, 43, 43, 1, 149760, 0x41427bc1
+0, 44, 44, 1, 149760, 0xe200ecf3
+0, 45, 45, 1, 149760, 0xc44785c5
+0, 46, 46, 1, 149760, 0xadc8c3cf
+0, 47, 47, 1, 149760, 0x6c57fb6d
+0, 48, 48, 1, 149760, 0x139cddc1
+0, 49, 49, 1, 149760, 0xc5c9def6
+0, 50, 50, 1, 149760, 0xa8da3f7b
+0, 51, 51, 1, 149760, 0x21823d13
+0, 52, 52, 1, 149760, 0x00e265fd
+0, 53, 53, 1, 149760, 0x289f21d2
+0, 54, 54, 1, 149760, 0xa96d8d0b
+0, 55, 55, 1, 149760, 0x4e50b434
+0, 56, 56, 1, 149760, 0x4e469eae
+0, 57, 57, 1, 149760, 0x62a258af
+0, 58, 58, 1, 149760, 0xc61beb2b
+0, 59, 59, 1, 149760, 0x15d7853b
+0, 60, 60, 1, 149760, 0xd5b8941b
+0, 61, 61, 1, 149760, 0x6312a7c5
+0, 62, 62, 1, 149760, 0x2da74d59
+0, 63, 63, 1, 149760, 0x5fd72bc7
+0, 64, 64, 1, 149760, 0x4035f027
+0, 65, 65, 1, 149760, 0xbe9992e2
+0, 66, 66, 1, 149760, 0xb96093b8
+0, 67, 67, 1, 149760, 0x1024bd43
+0, 68, 68, 1, 149760, 0x1376a3fe
+0, 69, 69, 1, 149760, 0xdf93ec7f
+0, 70, 70, 1, 149760, 0x17d27bfa
+0, 71, 71, 1, 149760, 0x440cb7aa
+0, 72, 72, 1, 149760, 0x8b230df3
+0, 73, 73, 1, 149760, 0x2526130e
+0, 74, 74, 1, 149760, 0x77926a77
+0, 75, 75, 1, 149760, 0x8562bddc
+0, 76, 76, 1, 149760, 0xda86bb2e
+0, 77, 77, 1, 149760, 0x2b4f921b
+0, 78, 78, 1, 149760, 0xf13bca77
+0, 79, 79, 1, 149760, 0x53e76b99
+0, 80, 80, 1, 149760, 0x29a2f5bb
+0, 81, 81, 1, 149760, 0x83a8c4f8
+0, 82, 82, 1, 149760, 0xbe6d8f45
+0, 83, 83, 1, 149760, 0x03d3bf96
+0, 84, 84, 1, 149760, 0x3a0bd29e
+0, 85, 85, 1, 149760, 0xdb656a22
+0, 86, 86, 1, 149760, 0x557b020e
+0, 87, 87, 1, 149760, 0x573ee5f2
+0, 88, 88, 1, 149760, 0x5484faea
+0, 89, 89, 1, 149760, 0x06bb73ae
+0, 90, 90, 1, 149760, 0x3d4049fa
+0, 91, 91, 1, 149760, 0xe574eedb
+0, 92, 92, 1, 149760, 0x1c46205d
+0, 93, 93, 1, 149760, 0x0c5c322e
+0, 94, 94, 1, 149760, 0x2bbeed95
+0, 95, 95, 1, 149760, 0x225897dc
+0, 96, 96, 1, 149760, 0x0a39aa8b
+0, 97, 97, 1, 149760, 0x3242e156
+0, 98, 98, 1, 149760, 0x1790ee85
+0, 99, 99, 1, 149760, 0x55ef9dac
+0, 100, 100, 1, 149760, 0x98e1c49e
+0, 101, 101, 1, 149760, 0x479a84b5
+0, 102, 102, 1, 149760, 0x1711b4f9
+0, 103, 103, 1, 149760, 0xd7d25fce
+0, 104, 104, 1, 149760, 0x7bde1977
+0, 105, 105, 1, 149760, 0x25777a4d
+0, 106, 106, 1, 149760, 0x7b55ed5f
+0, 107, 107, 1, 149760, 0xb28e59e6
+0, 108, 108, 1, 149760, 0x8314281a
+0, 109, 109, 1, 149760, 0x3a5ceeb3
+0, 110, 110, 1, 149760, 0x33760ed8
+0, 111, 111, 1, 149760, 0x19332370
+0, 112, 112, 1, 149760, 0xf25d1f68
+0, 113, 113, 1, 149760, 0x4d665712
+0, 114, 114, 1, 149760, 0x3e310eb7
+0, 115, 115, 1, 149760, 0xafa3c1bb
+0, 116, 116, 1, 149760, 0xf0b7a7ec
+0, 117, 117, 1, 149760, 0xa88a747a
+0, 118, 118, 1, 149760, 0x7b7e6e85
+0, 119, 119, 1, 149760, 0xbc8f8ede
+0, 120, 120, 1, 149760, 0x449f7d2f
+0, 121, 121, 1, 149760, 0x9bc70c53
+0, 122, 122, 1, 149760, 0x8544dc98
+0, 123, 123, 1, 149760, 0xef687641
+0, 124, 124, 1, 149760, 0x0c962219
+0, 125, 125, 1, 149760, 0x4325ae76
+0, 126, 126, 1, 149760, 0xcec7a18c
+0, 127, 127, 1, 149760, 0x941ee8a2
+0, 128, 128, 1, 149760, 0x3eaf3f55
+0, 129, 129, 1, 149760, 0x5b571274
+0, 130, 130, 1, 149760, 0x0532488a
+0, 131, 131, 1, 149760, 0x893fbaf7
+0, 132, 132, 1, 149760, 0xd0155ddf
+0, 133, 133, 1, 149760, 0x83ec86ee
+0, 134, 134, 1, 149760, 0xedffba86
+0, 135, 135, 1, 149760, 0x838c19de
+0, 136, 136, 1, 149760, 0x8482639d
+0, 137, 137, 1, 149760, 0x9501004d
+0, 138, 138, 1, 149760, 0x1db0525f
+0, 139, 139, 1, 149760, 0x8b431467
+0, 140, 140, 1, 149760, 0x972e7d24
+0, 141, 141, 1, 149760, 0xd8151b94
+0, 142, 142, 1, 149760, 0x1ded6a85
+0, 143, 143, 1, 149760, 0x03497fe2
+0, 144, 144, 1, 149760, 0x07427bb7
+0, 145, 145, 1, 149760, 0x33c085ef
+0, 146, 146, 1, 149760, 0x0feda1d0
+0, 147, 147, 1, 149760, 0xf86930e7
+0, 148, 148, 1, 149760, 0x42c2ea09
+0, 149, 149, 1, 149760, 0xcfb76b86
+0, 150, 150, 1, 149760, 0x672e2fce
+0, 151, 151, 1, 149760, 0xb006ec79
+0, 152, 152, 1, 149760, 0xdbc8511c
+0, 153, 153, 1, 149760, 0x3278b299
+0, 154, 154, 1, 149760, 0xd19fe063
+0, 155, 155, 1, 149760, 0x13bb8951
+0, 156, 156, 1, 149760, 0xec5cfe36
+0, 157, 157, 1, 149760, 0x9381a0e7
+0, 158, 158, 1, 149760, 0x304cf3c0
+0, 159, 159, 1, 149760, 0xd380511c
+0, 160, 160, 1, 149760, 0xbd1abe11
+0, 161, 161, 1, 149760, 0x7b220293
+0, 162, 162, 1, 149760, 0xbbe85931
+0, 163, 163, 1, 149760, 0x316e422a
+0, 164, 164, 1, 149760, 0x5e5db530
+0, 165, 165, 1, 149760, 0xc48d6ddb
+0, 166, 166, 1, 149760, 0x9adf5d65
+0, 167, 167, 1, 149760, 0x2adb94de
+0, 168, 168, 1, 149760, 0xbc052746
+0, 169, 169, 1, 149760, 0xac4d3569
+0, 170, 170, 1, 149760, 0x3cd8fdee
+0, 171, 171, 1, 149760, 0x34bfd6ed
+0, 172, 172, 1, 149760, 0xf72fec4b
+0, 173, 173, 1, 149760, 0xf8c5b374
+0, 174, 174, 1, 149760, 0x28ff7382
+0, 175, 175, 1, 149760, 0xac3b49f4
+0, 176, 176, 1, 149760, 0x9d995a62
+0, 177, 177, 1, 149760, 0xe0b292f1
+0, 178, 178, 1, 149760, 0x4edbd05d
+0, 179, 179, 1, 149760, 0x4fd5038b
+0, 180, 180, 1, 149760, 0x899d2101
+0, 181, 181, 1, 149760, 0x0733f804
+0, 182, 182, 1, 149760, 0xe4297100
+0, 183, 183, 1, 149760, 0x5aff9292
+0, 184, 184, 1, 149760, 0x41eda25c
+0, 185, 185, 1, 149760, 0xb4d7aaf2
+0, 186, 186, 1, 149760, 0xbd99fade
+0, 187, 187, 1, 149760, 0xdea6d265
+0, 188, 188, 1, 149760, 0xa2d3bdcd
+0, 189, 189, 1, 149760, 0x38f8a729
+0, 190, 190, 1, 149760, 0x0a356f1b
+0, 191, 191, 1, 149760, 0x865411a5
+0, 192, 192, 1, 149760, 0xd6720a40
+0, 193, 193, 1, 149760, 0xf40589f9
+0, 194, 194, 1, 149760, 0x0646106d
+0, 195, 195, 1, 149760, 0x88e55688
+0, 196, 196, 1, 149760, 0xda2fce82
+0, 197, 197, 1, 149760, 0xc823200b
+0, 198, 198, 1, 149760, 0xc9513041
+0, 199, 199, 1, 149760, 0x798d0e88
+0, 200, 200, 1, 149760, 0xb6d4f15a
+0, 201, 201, 1, 149760, 0xab5b24a4
+0, 202, 202, 1, 149760, 0x9888aa8d
+0, 203, 203, 1, 149760, 0xbf13bbf4
+0, 204, 204, 1, 149760, 0x5450bb23
+0, 205, 205, 1, 149760, 0x12aec398
+0, 206, 206, 1, 149760, 0xa5e1579a
+0, 207, 207, 1, 149760, 0xbeeb07e1
+0, 208, 208, 1, 149760, 0x209a9f1b
+0, 209, 209, 1, 149760, 0x4d3d1c1a
+0, 210, 210, 1, 149760, 0xb4edd703
+0, 211, 211, 1, 149760, 0xc71adf66
+0, 212, 212, 1, 149760, 0x40006d36
+0, 213, 213, 1, 149760, 0x1c5485c9
+0, 214, 214, 1, 149760, 0xa3d8c9a1
+0, 215, 215, 1, 149760, 0x9bfac6de
+0, 216, 216, 1, 149760, 0xed3b0782
+0, 217, 217, 1, 149760, 0x8f075ce2
+0, 218, 218, 1, 149760, 0xb744fa07
+0, 219, 219, 1, 149760, 0xa9356722
+0, 220, 220, 1, 149760, 0xd792bd01
+0, 221, 221, 1, 149760, 0xa124618b
+0, 222, 222, 1, 149760, 0x7492bb54
+0, 223, 223, 1, 149760, 0x67dcefca
+0, 224, 224, 1, 149760, 0x8a7f716d
+0, 225, 225, 1, 149760, 0x7775bb01
+0, 226, 226, 1, 149760, 0xe4a845e5
+0, 227, 227, 1, 149760, 0x79a3962d
+0, 228, 228, 1, 149760, 0x4f395ad7
+0, 229, 229, 1, 149760, 0x3948ce05
+0, 230, 230, 1, 149760, 0x037e6c07
+0, 231, 231, 1, 149760, 0x91881ae9
+0, 232, 232, 1, 149760, 0x937e2545
+0, 233, 233, 1, 149760, 0xdc892763
+0, 234, 234, 1, 149760, 0x96ebd47f
+0, 235, 235, 1, 149760, 0xfecbf8c6
+0, 236, 236, 1, 149760, 0xe1443808
+0, 237, 237, 1, 149760, 0xe0cd36c0
+0, 238, 238, 1, 149760, 0xb485eb4d
+0, 239, 239, 1, 149760, 0x36edf31f
+0, 240, 240, 1, 149760, 0x988bb97f
+0, 241, 241, 1, 149760, 0xc266c616
+0, 242, 242, 1, 149760, 0x7ec4c3f4
+0, 243, 243, 1, 149760, 0xedf5e2ff
+0, 244, 244, 1, 149760, 0xbdd351e3
+0, 245, 245, 1, 149760, 0x900e194e
+0, 246, 246, 1, 149760, 0x5dc7daad
+0, 247, 247, 1, 149760, 0x1ce37e7e
+0, 248, 248, 1, 149760, 0x15982333
+0, 249, 249, 1, 149760, 0x976bb72e
+0, 250, 250, 1, 149760, 0x0b42e05e
+0, 251, 251, 1, 149760, 0xffbcc758
+0, 252, 252, 1, 149760, 0x6377782d
+0, 253, 253, 1, 149760, 0x8aa42a80
+0, 254, 254, 1, 149760, 0x8e0ab3fd
+0, 255, 255, 1, 149760, 0xdfdd49d4
+0, 256, 256, 1, 149760, 0x2659a6cb
+0, 257, 257, 1, 149760, 0x1e9a3d51
+0, 258, 258, 1, 149760, 0x7a66d80d
+0, 259, 259, 1, 149760, 0x5756a9e9
+0, 260, 260, 1, 149760, 0x0fa8d6dd
+0, 261, 261, 1, 149760, 0x885799a5
+0, 262, 262, 1, 149760, 0xb8d02df7
+0, 263, 263, 1, 149760, 0xd2e2800c
+0, 264, 264, 1, 149760, 0xa26ee27a
+0, 265, 265, 1, 149760, 0x7c86750f
+0, 266, 266, 1, 149760, 0xb4694ea1
+0, 267, 267, 1, 149760, 0x89d0b75a
+0, 268, 268, 1, 149760, 0x92b9af80
+0, 269, 269, 1, 149760, 0x107dd610
+0, 270, 270, 1, 149760, 0x8ad35f55
+0, 271, 271, 1, 149760, 0xccc32cb1
+0, 272, 272, 1, 149760, 0xd08ce4ff
+0, 273, 273, 1, 149760, 0x30bd8d0a
+0, 274, 274, 1, 149760, 0x01b74d14
+0, 275, 275, 1, 149760, 0x79aa7a3b
+0, 276, 276, 1, 149760, 0x5f7a40fc
+0, 277, 277, 1, 149760, 0x8837643e
+0, 278, 278, 1, 149760, 0xb6b66baa
+0, 279, 279, 1, 149760, 0xf4ae17cd
+0, 280, 280, 1, 149760, 0xe0d2546a
+0, 281, 281, 1, 149760, 0x0e118751
+0, 282, 282, 1, 149760, 0x0732e19c
+0, 283, 283, 1, 149760, 0x9cfe27b3
+0, 284, 284, 1, 149760, 0x1c77b242
+0, 285, 285, 1, 149760, 0x25be3938
+0, 286, 286, 1, 149760, 0x735ce859
+0, 287, 287, 1, 149760, 0x2bca0f6e
+0, 288, 288, 1, 149760, 0xcce3eb48
+0, 289, 289, 1, 149760, 0xf3556dd8
+0, 290, 290, 1, 149760, 0xcb2cecb4
+0, 291, 291, 1, 149760, 0x9c489742
+0, 292, 292, 1, 149760, 0xbe25370d
+0, 293, 293, 1, 149760, 0x798ff17f
+0, 294, 294, 1, 149760, 0x2f1a46c4
+0, 295, 295, 1, 149760, 0x7d119bd6
+0, 296, 296, 1, 149760, 0x42ceab74
+0, 297, 297, 1, 149760, 0x6fcbe2ef
+0, 298, 298, 1, 149760, 0x290fe6da
+0, 299, 299, 1, 149760, 0x6b280a24
diff --git a/tests/ref/fate/hevc-conformance-RPLM_B_qualcomm_4 b/tests/ref/fate/hevc-conformance-RPLM_B_qualcomm_4
new file mode 100644
index 0000000..a34dcc0
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-RPLM_B_qualcomm_4
@@ -0,0 +1,301 @@
+#tb 0: 1/25
+0, 0, 0, 1, 149760, 0x82ff0cca
+0, 1, 1, 1, 149760, 0xcd05ba17
+0, 2, 2, 1, 149760, 0x33a5b924
+0, 3, 3, 1, 149760, 0xc0a8d82f
+0, 4, 4, 1, 149760, 0xa18c8ce6
+0, 5, 5, 1, 149760, 0x4d3c4902
+0, 6, 6, 1, 149760, 0xf118cb2a
+0, 7, 7, 1, 149760, 0xb37643c0
+0, 8, 8, 1, 149760, 0x0d6f8a70
+0, 9, 9, 1, 149760, 0xeaebd0f0
+0, 10, 10, 1, 149760, 0x81cce277
+0, 11, 11, 1, 149760, 0x85f216cc
+0, 12, 12, 1, 149760, 0x799cc7c7
+0, 13, 13, 1, 149760, 0x575f76da
+0, 14, 14, 1, 149760, 0x79e10395
+0, 15, 15, 1, 149760, 0x80f62423
+0, 16, 16, 1, 149760, 0x13657087
+0, 17, 17, 1, 149760, 0xcd147ae1
+0, 18, 18, 1, 149760, 0xcee71159
+0, 19, 19, 1, 149760, 0x6fa7b8d5
+0, 20, 20, 1, 149760, 0xd90bd038
+0, 21, 21, 1, 149760, 0x13eead73
+0, 22, 22, 1, 149760, 0xe2eddfc8
+0, 23, 23, 1, 149760, 0x1f07a4f6
+0, 24, 24, 1, 149760, 0x90b25f59
+0, 25, 25, 1, 149760, 0xd0dd86ba
+0, 26, 26, 1, 149760, 0x3008066c
+0, 27, 27, 1, 149760, 0x74ec54dd
+0, 28, 28, 1, 149760, 0xa423046c
+0, 29, 29, 1, 149760, 0x8a410bca
+0, 30, 30, 1, 149760, 0x55337573
+0, 31, 31, 1, 149760, 0x55d3623c
+0, 32, 32, 1, 149760, 0x699d234b
+0, 33, 33, 1, 149760, 0xbcd029b6
+0, 34, 34, 1, 149760, 0xa56e6600
+0, 35, 35, 1, 149760, 0x1dfc4a28
+0, 36, 36, 1, 149760, 0x9a72d671
+0, 37, 37, 1, 149760, 0xc01812ae
+0, 38, 38, 1, 149760, 0x8ef428c2
+0, 39, 39, 1, 149760, 0x6e79de92
+0, 40, 40, 1, 149760, 0xf315ba7c
+0, 41, 41, 1, 149760, 0xa678caff
+0, 42, 42, 1, 149760, 0xbd2049c0
+0, 43, 43, 1, 149760, 0x649323ea
+0, 44, 44, 1, 149760, 0x686eb3a4
+0, 45, 45, 1, 149760, 0x89725136
+0, 46, 46, 1, 149760, 0xc4db7e6f
+0, 47, 47, 1, 149760, 0xf6f0d823
+0, 48, 48, 1, 149760, 0x44b3a07a
+0, 49, 49, 1, 149760, 0xf23c221d
+0, 50, 50, 1, 149760, 0x858f11ef
+0, 51, 51, 1, 149760, 0xcd5311c4
+0, 52, 52, 1, 149760, 0x72c9297d
+0, 53, 53, 1, 149760, 0xf6acd772
+0, 54, 54, 1, 149760, 0x8c0f91ed
+0, 55, 55, 1, 149760, 0x7ef6f2be
+0, 56, 56, 1, 149760, 0x1237a677
+0, 57, 57, 1, 149760, 0x66e461f9
+0, 58, 58, 1, 149760, 0x3e06e1b3
+0, 59, 59, 1, 149760, 0xa6f6065c
+0, 60, 60, 1, 149760, 0x16e38cc0
+0, 61, 61, 1, 149760, 0x05762de1
+0, 62, 62, 1, 149760, 0xbda617c5
+0, 63, 63, 1, 149760, 0x75b904a9
+0, 64, 64, 1, 149760, 0x2f8bf179
+0, 65, 65, 1, 149760, 0x9be6a533
+0, 66, 66, 1, 149760, 0xf4eb99e8
+0, 67, 67, 1, 149760, 0xf3a68b9a
+0, 68, 68, 1, 149760, 0x34b86f19
+0, 69, 69, 1, 149760, 0x6a71cc04
+0, 70, 70, 1, 149760, 0xe206a202
+0, 71, 71, 1, 149760, 0xdfa8dea6
+0, 72, 72, 1, 149760, 0x8ef7fb73
+0, 73, 73, 1, 149760, 0x67a8de32
+0, 74, 74, 1, 149760, 0xc8c16870
+0, 75, 75, 1, 149760, 0xf5e5d04d
+0, 76, 76, 1, 149760, 0x79d0cc8d
+0, 77, 77, 1, 149760, 0xcd80a22b
+0, 78, 78, 1, 149760, 0x12dce452
+0, 79, 79, 1, 149760, 0x0586aa3d
+0, 80, 80, 1, 149760, 0x5a4d0c1e
+0, 81, 81, 1, 149760, 0x25dbe94e
+0, 82, 82, 1, 149760, 0x3236bbe8
+0, 83, 83, 1, 149760, 0x3b4bc068
+0, 84, 84, 1, 149760, 0x3f32c299
+0, 85, 85, 1, 149760, 0x5b0738e5
+0, 86, 86, 1, 149760, 0x0c1d0c80
+0, 87, 87, 1, 149760, 0x76ace6f5
+0, 88, 88, 1, 149760, 0xc738ff39
+0, 89, 89, 1, 149760, 0x0f078335
+0, 90, 90, 1, 149760, 0x0e941631
+0, 91, 91, 1, 149760, 0x284ee7d6
+0, 92, 92, 1, 149760, 0xce9b49b8
+0, 93, 93, 1, 149760, 0x7c132570
+0, 94, 94, 1, 149760, 0xa983dc5e
+0, 95, 95, 1, 149760, 0x994e4d69
+0, 96, 96, 1, 149760, 0xb8f599ed
+0, 97, 97, 1, 149760, 0xee81b454
+0, 98, 98, 1, 149760, 0xf27bdeee
+0, 99, 99, 1, 149760, 0xc7628895
+0, 100, 100, 1, 149760, 0x003521d1
+0, 101, 101, 1, 149760, 0x7ed9b167
+0, 102, 102, 1, 149760, 0x47598b95
+0, 103, 103, 1, 149760, 0x879b347e
+0, 104, 104, 1, 149760, 0x55f8f8c1
+0, 105, 105, 1, 149760, 0xdddc5dda
+0, 106, 106, 1, 149760, 0xc531c9a1
+0, 107, 107, 1, 149760, 0x28ef0e7e
+0, 108, 108, 1, 149760, 0x4c090cbd
+0, 109, 109, 1, 149760, 0x5818f270
+0, 110, 110, 1, 149760, 0x89ea1f0e
+0, 111, 111, 1, 149760, 0x263925ef
+0, 112, 112, 1, 149760, 0x4e7d45b8
+0, 113, 113, 1, 149760, 0xa98dbf77
+0, 114, 114, 1, 149760, 0xaa0239b3
+0, 115, 115, 1, 149760, 0x4eaa2226
+0, 116, 116, 1, 149760, 0x9927c7f9
+0, 117, 117, 1, 149760, 0x17f09e34
+0, 118, 118, 1, 149760, 0x45cc73e9
+0, 119, 119, 1, 149760, 0x21836e14
+0, 120, 120, 1, 149760, 0x14c38cf6
+0, 121, 121, 1, 149760, 0x18ee35ee
+0, 122, 122, 1, 149760, 0x4f55f781
+0, 123, 123, 1, 149760, 0x85556339
+0, 124, 124, 1, 149760, 0xc41e3261
+0, 125, 125, 1, 149760, 0xed34ba27
+0, 126, 126, 1, 149760, 0x91e7841c
+0, 127, 127, 1, 149760, 0x1605bd75
+0, 128, 128, 1, 149760, 0xb5af2fbc
+0, 129, 129, 1, 149760, 0x9024b2d8
+0, 130, 130, 1, 149760, 0xda8d3c03
+0, 131, 131, 1, 149760, 0xc23a9686
+0, 132, 132, 1, 149760, 0xf9c8686b
+0, 133, 133, 1, 149760, 0xec09b569
+0, 134, 134, 1, 149760, 0x398df9bb
+0, 135, 135, 1, 149760, 0x716c2934
+0, 136, 136, 1, 149760, 0x0a6ea078
+0, 137, 137, 1, 149760, 0x777739fe
+0, 138, 138, 1, 149760, 0x80417304
+0, 139, 139, 1, 149760, 0xe0a5c378
+0, 140, 140, 1, 149760, 0x9565a659
+0, 141, 141, 1, 149760, 0xdf6f1938
+0, 142, 142, 1, 149760, 0xe60d5639
+0, 143, 143, 1, 149760, 0xa89fa739
+0, 144, 144, 1, 149760, 0xd1529b40
+0, 145, 145, 1, 149760, 0x48a7d440
+0, 146, 146, 1, 149760, 0x5946afbb
+0, 147, 147, 1, 149760, 0x2cad2855
+0, 148, 148, 1, 149760, 0x7ac1d993
+0, 149, 149, 1, 149760, 0x0841a016
+0, 150, 150, 1, 149760, 0x35ea4bd2
+0, 151, 151, 1, 149760, 0x5371effa
+0, 152, 152, 1, 149760, 0xd6445a37
+0, 153, 153, 1, 149760, 0x782ea184
+0, 154, 154, 1, 149760, 0x919c2013
+0, 155, 155, 1, 149760, 0x0ea79614
+0, 156, 156, 1, 149760, 0x1ac0e835
+0, 157, 157, 1, 149760, 0x32a36ada
+0, 158, 158, 1, 149760, 0x6b0ad17c
+0, 159, 159, 1, 149760, 0xcd442d19
+0, 160, 160, 1, 149760, 0x0dd1df50
+0, 161, 161, 1, 149760, 0xe26b248f
+0, 162, 162, 1, 149760, 0x490348bb
+0, 163, 163, 1, 149760, 0x638b547e
+0, 164, 164, 1, 149760, 0xb2cbe2ca
+0, 165, 165, 1, 149760, 0xc6cfaa86
+0, 166, 166, 1, 149760, 0xe2317842
+0, 167, 167, 1, 149760, 0xe6e7cd9b
+0, 168, 168, 1, 149760, 0x55bf48cb
+0, 169, 169, 1, 149760, 0xefee6ea0
+0, 170, 170, 1, 149760, 0x2bb127fa
+0, 171, 171, 1, 149760, 0xebbf0725
+0, 172, 172, 1, 149760, 0xb40718a1
+0, 173, 173, 1, 149760, 0x33c8e7da
+0, 174, 174, 1, 149760, 0xfeea8d03
+0, 175, 175, 1, 149760, 0x52f47fa9
+0, 176, 176, 1, 149760, 0xb08fa2f6
+0, 177, 177, 1, 149760, 0xc9adcd96
+0, 178, 178, 1, 149760, 0xb8981cc2
+0, 179, 179, 1, 149760, 0x547b1eaa
+0, 180, 180, 1, 149760, 0x10733813
+0, 181, 181, 1, 149760, 0x14edfa3d
+0, 182, 182, 1, 149760, 0x28ae8eb3
+0, 183, 183, 1, 149760, 0x9b94a69c
+0, 184, 184, 1, 149760, 0x42f67a2a
+0, 185, 185, 1, 149760, 0x1ead65e6
+0, 186, 186, 1, 149760, 0x30b99840
+0, 187, 187, 1, 149760, 0xafdebbda
+0, 188, 188, 1, 149760, 0xc31cda7f
+0, 189, 189, 1, 149760, 0xe7afdfa8
+0, 190, 190, 1, 149760, 0xc8358146
+0, 191, 191, 1, 149760, 0xb8ea3a3b
+0, 192, 192, 1, 149760, 0xebbb2c0e
+0, 193, 193, 1, 149760, 0xe911c057
+0, 194, 194, 1, 149760, 0x843f3082
+0, 195, 195, 1, 149760, 0xd18f6dcb
+0, 196, 196, 1, 149760, 0xd0f67de3
+0, 197, 197, 1, 149760, 0xa7077645
+0, 198, 198, 1, 149760, 0xb7432bef
+0, 199, 199, 1, 149760, 0x9e3284ee
+0, 200, 200, 1, 149760, 0x931ec601
+0, 201, 201, 1, 149760, 0xd0f92a35
+0, 202, 202, 1, 149760, 0x2141c549
+0, 203, 203, 1, 149760, 0x46abf101
+0, 204, 204, 1, 149760, 0x92069ea7
+0, 205, 205, 1, 149760, 0xbf0dd536
+0, 206, 206, 1, 149760, 0xc0c34245
+0, 207, 207, 1, 149760, 0xd9f60e8b
+0, 208, 208, 1, 149760, 0xe20cb181
+0, 209, 209, 1, 149760, 0xdf58fbd2
+0, 210, 210, 1, 149760, 0xe047e805
+0, 211, 211, 1, 149760, 0xe6dd0520
+0, 212, 212, 1, 149760, 0xa7a1a7dd
+0, 213, 213, 1, 149760, 0x6bd6d799
+0, 214, 214, 1, 149760, 0x9fcbda54
+0, 215, 215, 1, 149760, 0xe9b8bf5a
+0, 216, 216, 1, 149760, 0x818d2b8d
+0, 217, 217, 1, 149760, 0x021c5b55
+0, 218, 218, 1, 149760, 0x0da93d94
+0, 219, 219, 1, 149760, 0x7d66b00d
+0, 220, 220, 1, 149760, 0xf84ab99e
+0, 221, 221, 1, 149760, 0xbc866ed2
+0, 222, 222, 1, 149760, 0x8075f6fa
+0, 223, 223, 1, 149760, 0x64540cad
+0, 224, 224, 1, 149760, 0xf3e28d9a
+0, 225, 225, 1, 149760, 0xb88fef8b
+0, 226, 226, 1, 149760, 0x1c782c83
+0, 227, 227, 1, 149760, 0xb89e4047
+0, 228, 228, 1, 149760, 0x593815a7
+0, 229, 229, 1, 149760, 0xa41a68d1
+0, 230, 230, 1, 149760, 0x7fdc56e5
+0, 231, 231, 1, 149760, 0xea8a0533
+0, 232, 232, 1, 149760, 0xc74709cc
+0, 233, 233, 1, 149760, 0xecca373c
+0, 234, 234, 1, 149760, 0x1dae228f
+0, 235, 235, 1, 149760, 0xbb900da8
+0, 236, 236, 1, 149760, 0xf71e4935
+0, 237, 237, 1, 149760, 0x8587d747
+0, 238, 238, 1, 149760, 0x5382afdd
+0, 239, 239, 1, 149760, 0x4075dea6
+0, 240, 240, 1, 149760, 0x1ccde8f2
+0, 241, 241, 1, 149760, 0x8065ed82
+0, 242, 242, 1, 149760, 0x0726bb8a
+0, 243, 243, 1, 149760, 0xedf2172c
+0, 244, 244, 1, 149760, 0x552cce61
+0, 245, 245, 1, 149760, 0x32851927
+0, 246, 246, 1, 149760, 0x15e8ae45
+0, 247, 247, 1, 149760, 0x9265625c
+0, 248, 248, 1, 149760, 0x11612465
+0, 249, 249, 1, 149760, 0x9f5586fa
+0, 250, 250, 1, 149760, 0x77f295a1
+0, 251, 251, 1, 149760, 0xb0757b88
+0, 252, 252, 1, 149760, 0xa0bd3d9c
+0, 253, 253, 1, 149760, 0x12471db6
+0, 254, 254, 1, 149760, 0x5c329d6b
+0, 255, 255, 1, 149760, 0x62f32654
+0, 256, 256, 1, 149760, 0xeafeb1f0
+0, 257, 257, 1, 149760, 0x707f6647
+0, 258, 258, 1, 149760, 0xe8acda33
+0, 259, 259, 1, 149760, 0x1e9dcb1b
+0, 260, 260, 1, 149760, 0x984a4a40
+0, 261, 261, 1, 149760, 0x066b9585
+0, 262, 262, 1, 149760, 0x5e2d2091
+0, 263, 263, 1, 149760, 0x6a6a5172
+0, 264, 264, 1, 149760, 0xc4c4fe94
+0, 265, 265, 1, 149760, 0x6ed2c46b
+0, 266, 266, 1, 149760, 0x810f27f8
+0, 267, 267, 1, 149760, 0xc27ca970
+0, 268, 268, 1, 149760, 0xfd3dae79
+0, 269, 269, 1, 149760, 0x9744ce6d
+0, 270, 270, 1, 149760, 0x45772f2a
+0, 271, 271, 1, 149760, 0x482ed805
+0, 272, 272, 1, 149760, 0x9606c429
+0, 273, 273, 1, 149760, 0x79a9ca8a
+0, 274, 274, 1, 149760, 0xf625806e
+0, 275, 275, 1, 149760, 0x0c9eed01
+0, 276, 276, 1, 149760, 0xb0007687
+0, 277, 277, 1, 149760, 0x620a7b35
+0, 278, 278, 1, 149760, 0x5d6fa9dc
+0, 279, 279, 1, 149760, 0x92c86275
+0, 280, 280, 1, 149760, 0xca1886f0
+0, 281, 281, 1, 149760, 0x6363a557
+0, 282, 282, 1, 149760, 0x32ab19ca
+0, 283, 283, 1, 149760, 0xa6113c10
+0, 284, 284, 1, 149760, 0x257fd46a
+0, 285, 285, 1, 149760, 0xb8af4e28
+0, 286, 286, 1, 149760, 0x9716d086
+0, 287, 287, 1, 149760, 0x0cc14c4d
+0, 288, 288, 1, 149760, 0xd194f150
+0, 289, 289, 1, 149760, 0xb7cd7cf8
+0, 290, 290, 1, 149760, 0xae1bb1a3
+0, 291, 291, 1, 149760, 0xb4cc355f
+0, 292, 292, 1, 149760, 0x617c1ecb
+0, 293, 293, 1, 149760, 0xf2d1f288
+0, 294, 294, 1, 149760, 0x109bcb52
+0, 295, 295, 1, 149760, 0xe61a97dd
+0, 296, 296, 1, 149760, 0xc629ac10
+0, 297, 297, 1, 149760, 0xb91acded
+0, 298, 298, 1, 149760, 0x54ccb321
+0, 299, 299, 1, 149760, 0x1ad3c115
diff --git a/tests/ref/fate/hevc-conformance-RPS_A_docomo_4 b/tests/ref/fate/hevc-conformance-RPS_A_docomo_4
new file mode 100644
index 0000000..e29a74b
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-RPS_A_docomo_4
@@ -0,0 +1,45 @@
+#tb 0: 1/25
+0, 0, 0, 1, 149760, 0x8edb27d7
+0, 1, 1, 1, 149760, 0x0bdf13f8
+0, 2, 2, 1, 149760, 0x45e702c7
+0, 3, 3, 1, 149760, 0x7a3a0c9a
+0, 4, 4, 1, 149760, 0xab0ed81d
+0, 5, 5, 1, 149760, 0xe2d4722a
+0, 6, 6, 1, 149760, 0x1df1f103
+0, 7, 7, 1, 149760, 0xdde42fb8
+0, 8, 8, 1, 149760, 0xfe2eb624
+0, 9, 9, 1, 149760, 0x121ff262
+0, 10, 10, 1, 149760, 0x64e5e7ba
+0, 11, 11, 1, 149760, 0x61b40e67
+0, 12, 12, 1, 149760, 0x8ceeb33f
+0, 13, 13, 1, 149760, 0xcbff6fc5
+0, 14, 14, 1, 149760, 0x07d6f767
+0, 15, 15, 1, 149760, 0x5cff14a5
+0, 16, 16, 1, 149760, 0x5c336ca3
+0, 17, 17, 1, 149760, 0x424990cd
+0, 18, 18, 1, 149760, 0x2c423459
+0, 19, 19, 1, 149760, 0xaff700ac
+0, 20, 20, 1, 149760, 0xaab9e6f4
+0, 21, 21, 1, 149760, 0x7979bfd4
+0, 22, 22, 1, 149760, 0x5096ee11
+0, 23, 23, 1, 149760, 0x4f02d1d0
+0, 24, 24, 1, 149760, 0x0c6468d2
+0, 25, 25, 1, 149760, 0x707e9307
+0, 26, 26, 1, 149760, 0xf4a71dc8
+0, 27, 27, 1, 149760, 0xbefc67f0
+0, 28, 28, 1, 149760, 0x05b8f3a9
+0, 29, 29, 1, 149760, 0xcd080a46
+0, 30, 30, 1, 149760, 0x1b5ab043
+0, 31, 31, 1, 149760, 0xd4b896e2
+0, 32, 32, 1, 149760, 0xbd342d08
+0, 33, 33, 1, 149760, 0x0b993f3c
+0, 34, 34, 1, 149760, 0xd89190e2
+0, 35, 35, 1, 149760, 0x507f2663
+0, 36, 36, 1, 149760, 0x6994c08f
+0, 37, 37, 1, 149760, 0xcf0209b2
+0, 38, 38, 1, 149760, 0x9695327c
+0, 39, 39, 1, 149760, 0x7116fdb3
+0, 40, 40, 1, 149760, 0x1294b154
+0, 41, 41, 1, 149760, 0x7ed1f716
+0, 42, 42, 1, 149760, 0xdc4880da
+0, 43, 43, 1, 149760, 0xa5955d35
diff --git a/tests/ref/fate/hevc-conformance-RPS_B_qualcomm_5 b/tests/ref/fate/hevc-conformance-RPS_B_qualcomm_5
new file mode 100644
index 0000000..3b24e75
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-RPS_B_qualcomm_5
@@ -0,0 +1,301 @@
+#tb 0: 1/25
+0, 0, 0, 1, 149760, 0xdb5e3b56
+0, 1, 1, 1, 149760, 0xe328e677
+0, 2, 2, 1, 149760, 0x8f18f4c0
+0, 3, 3, 1, 149760, 0xf48de64c
+0, 4, 4, 1, 149760, 0x2937ad23
+0, 5, 5, 1, 149760, 0x93f166d2
+0, 6, 6, 1, 149760, 0x80e4e9c2
+0, 7, 7, 1, 149760, 0xb2a35da7
+0, 8, 8, 1, 149760, 0xf4fbb5c2
+0, 9, 9, 1, 149760, 0x2193bd91
+0, 10, 10, 1, 149760, 0xd4eec3b4
+0, 11, 11, 1, 149760, 0xb2e20b91
+0, 12, 12, 1, 149760, 0xaf8d17dc
+0, 13, 13, 1, 149760, 0x2189ac78
+0, 14, 14, 1, 149760, 0x52b8130f
+0, 15, 15, 1, 149760, 0xdfbc2f0a
+0, 16, 16, 1, 149760, 0x4c0269cf
+0, 17, 17, 1, 149760, 0xf99bb7d2
+0, 18, 18, 1, 149760, 0xada1495f
+0, 19, 19, 1, 149760, 0x57c42893
+0, 20, 20, 1, 149760, 0x022d29ca
+0, 21, 21, 1, 149760, 0x9883a271
+0, 22, 22, 1, 149760, 0xc8c132d7
+0, 23, 23, 1, 149760, 0xa97f8b43
+0, 24, 24, 1, 149760, 0x1bc187fa
+0, 25, 25, 1, 149760, 0x7b93951b
+0, 26, 26, 1, 149760, 0x88fd367c
+0, 27, 27, 1, 149760, 0x29471b92
+0, 28, 28, 1, 149760, 0x3ba820f1
+0, 29, 29, 1, 149760, 0x0a223169
+0, 30, 30, 1, 149760, 0x70fee1d5
+0, 31, 31, 1, 149760, 0x5f5cf053
+0, 32, 32, 1, 149760, 0x698f11e4
+0, 33, 33, 1, 149760, 0x65314fd4
+0, 34, 34, 1, 149760, 0x7a689450
+0, 35, 35, 1, 149760, 0x28774ca0
+0, 36, 36, 1, 149760, 0x0751f804
+0, 37, 37, 1, 149760, 0x875a6fb9
+0, 38, 38, 1, 149760, 0xde1f5309
+0, 39, 39, 1, 149760, 0x82701dd6
+0, 40, 40, 1, 149760, 0x13a2f45e
+0, 41, 41, 1, 149760, 0xfc3b140c
+0, 42, 42, 1, 149760, 0x4518ab47
+0, 43, 43, 1, 149760, 0xe5459482
+0, 44, 44, 1, 149760, 0x4cfafc6e
+0, 45, 45, 1, 149760, 0xc7cd5e43
+0, 46, 46, 1, 149760, 0x1ee79746
+0, 47, 47, 1, 149760, 0xccc73c83
+0, 48, 48, 1, 149760, 0xd9ecafc7
+0, 49, 49, 1, 149760, 0x65221c9d
+0, 50, 50, 1, 149760, 0x219b0b4b
+0, 51, 51, 1, 149760, 0x9d1e2010
+0, 52, 52, 1, 149760, 0x11685e16
+0, 53, 53, 1, 149760, 0x37eb1297
+0, 54, 54, 1, 149760, 0x99088778
+0, 55, 55, 1, 149760, 0xb41cbf25
+0, 56, 56, 1, 149760, 0x56f78bda
+0, 57, 57, 1, 149760, 0x6c284868
+0, 58, 58, 1, 149760, 0x37f245b9
+0, 59, 59, 1, 149760, 0x79682de2
+0, 60, 60, 1, 149760, 0x5a04f379
+0, 61, 61, 1, 149760, 0xfecc668b
+0, 62, 62, 1, 149760, 0x29328d8c
+0, 63, 63, 1, 149760, 0x8aff3ad7
+0, 64, 64, 1, 149760, 0x4035f027
+0, 65, 65, 1, 149760, 0xe7cead1d
+0, 66, 66, 1, 149760, 0x18578492
+0, 67, 67, 1, 149760, 0xd3ab3f9d
+0, 68, 68, 1, 149760, 0x6f866e38
+0, 69, 69, 1, 149760, 0x6a47800c
+0, 70, 70, 1, 149760, 0x01c6305e
+0, 71, 71, 1, 149760, 0x489ab5a8
+0, 72, 72, 1, 149760, 0xb2570787
+0, 73, 73, 1, 149760, 0xb0d5d478
+0, 74, 74, 1, 149760, 0x88484ccc
+0, 75, 75, 1, 149760, 0xb4c6be2c
+0, 76, 76, 1, 149760, 0x461d874c
+0, 77, 77, 1, 149760, 0x3be464b0
+0, 78, 78, 1, 149760, 0x06aa9443
+0, 79, 79, 1, 149760, 0xe0e625a3
+0, 80, 80, 1, 149760, 0x17e2daeb
+0, 81, 81, 1, 149760, 0x58a1a350
+0, 82, 82, 1, 149760, 0xcd4983ce
+0, 83, 83, 1, 149760, 0x90459a42
+0, 84, 84, 1, 149760, 0x899dedaa
+0, 85, 85, 1, 149760, 0x814e3529
+0, 86, 86, 1, 149760, 0x5795a2e5
+0, 87, 87, 1, 149760, 0xcedb245c
+0, 88, 88, 1, 149760, 0x37f9dd30
+0, 89, 89, 1, 149760, 0x320d899e
+0, 90, 90, 1, 149760, 0x6a33ffca
+0, 91, 91, 1, 149760, 0x6620b9eb
+0, 92, 92, 1, 149760, 0xfc8b1e1b
+0, 93, 93, 1, 149760, 0x835a0dd9
+0, 94, 94, 1, 149760, 0xcee4a9b0
+0, 95, 95, 1, 149760, 0x2c2972f0
+0, 96, 96, 1, 149760, 0x0a39aa8b
+0, 97, 97, 1, 149760, 0xa8a9c0bf
+0, 98, 98, 1, 149760, 0xd563c087
+0, 99, 99, 1, 149760, 0xb0f88320
+0, 100, 100, 1, 149760, 0x0ffffd6b
+0, 101, 101, 1, 149760, 0x95269e8c
+0, 102, 102, 1, 149760, 0xd0d4acd9
+0, 103, 103, 1, 149760, 0x7cf06805
+0, 104, 104, 1, 149760, 0xa5192bbe
+0, 105, 105, 1, 149760, 0x2fed928b
+0, 106, 106, 1, 149760, 0x549edd04
+0, 107, 107, 1, 149760, 0xa42b55d7
+0, 108, 108, 1, 149760, 0xeab32579
+0, 109, 109, 1, 149760, 0x95a727c3
+0, 110, 110, 1, 149760, 0x76714576
+0, 111, 111, 1, 149760, 0x5efc352a
+0, 112, 112, 1, 149760, 0x154a2c06
+0, 113, 113, 1, 149760, 0x516faf62
+0, 114, 114, 1, 149760, 0x622b6d64
+0, 115, 115, 1, 149760, 0x2ada08a9
+0, 116, 116, 1, 149760, 0xf24efa06
+0, 117, 117, 1, 149760, 0x5979b33e
+0, 118, 118, 1, 149760, 0x2130a282
+0, 119, 119, 1, 149760, 0x1ee8b3d1
+0, 120, 120, 1, 149760, 0x840c6913
+0, 121, 121, 1, 149760, 0xa37049b8
+0, 122, 122, 1, 149760, 0x8d95efb0
+0, 123, 123, 1, 149760, 0x22d3afb2
+0, 124, 124, 1, 149760, 0x113d6c6f
+0, 125, 125, 1, 149760, 0xb407014d
+0, 126, 126, 1, 149760, 0x33a8e5c9
+0, 127, 127, 1, 149760, 0x2689ced2
+0, 128, 128, 1, 149760, 0x3eaf3f55
+0, 129, 129, 1, 149760, 0x93ad7fa5
+0, 130, 130, 1, 149760, 0x30c15154
+0, 131, 131, 1, 149760, 0xdce68c7a
+0, 132, 132, 1, 149760, 0xea092d4c
+0, 133, 133, 1, 149760, 0xed679468
+0, 134, 134, 1, 149760, 0x9128c0d5
+0, 135, 135, 1, 149760, 0xd4f121ba
+0, 136, 136, 1, 149760, 0xe5e228f0
+0, 137, 137, 1, 149760, 0x8246dae3
+0, 138, 138, 1, 149760, 0x8a3b430c
+0, 139, 139, 1, 149760, 0x9a8edc3d
+0, 140, 140, 1, 149760, 0x68b0af97
+0, 141, 141, 1, 149760, 0x90d54b52
+0, 142, 142, 1, 149760, 0xd6395796
+0, 143, 143, 1, 149760, 0x70986b40
+0, 144, 144, 1, 149760, 0xc0b4a9c8
+0, 145, 145, 1, 149760, 0x760b973b
+0, 146, 146, 1, 149760, 0xe8fe9846
+0, 147, 147, 1, 149760, 0x61062c97
+0, 148, 148, 1, 149760, 0x9148e99b
+0, 149, 149, 1, 149760, 0x962c6a1e
+0, 150, 150, 1, 149760, 0x57bb088f
+0, 151, 151, 1, 149760, 0x2b0fa8c5
+0, 152, 152, 1, 149760, 0x00f932fc
+0, 153, 153, 1, 149760, 0x4cc58697
+0, 154, 154, 1, 149760, 0xd2bf178f
+0, 155, 155, 1, 149760, 0xc510c1cd
+0, 156, 156, 1, 149760, 0xc48e0192
+0, 157, 157, 1, 149760, 0xa03e7fe5
+0, 158, 158, 1, 149760, 0xb68ce060
+0, 159, 159, 1, 149760, 0x653951c8
+0, 160, 160, 1, 149760, 0xbd1abe11
+0, 161, 161, 1, 149760, 0xad7a2366
+0, 162, 162, 1, 149760, 0xb018279e
+0, 163, 163, 1, 149760, 0xd5994bff
+0, 164, 164, 1, 149760, 0x3eb7e082
+0, 165, 165, 1, 149760, 0x87257b3a
+0, 166, 166, 1, 149760, 0x12fc4c4d
+0, 167, 167, 1, 149760, 0x9fbfa94d
+0, 168, 168, 1, 149760, 0x61714cae
+0, 169, 169, 1, 149760, 0xae291b59
+0, 170, 170, 1, 149760, 0x8f161442
+0, 171, 171, 1, 149760, 0x603cf3a5
+0, 172, 172, 1, 149760, 0xf9f214a0
+0, 173, 173, 1, 149760, 0xbbf5dcb9
+0, 174, 174, 1, 149760, 0x8af1a1ab
+0, 175, 175, 1, 149760, 0x16f581e5
+0, 176, 176, 1, 149760, 0xdadd8eed
+0, 177, 177, 1, 149760, 0x2f1acd8e
+0, 178, 178, 1, 149760, 0xa28bd660
+0, 179, 179, 1, 149760, 0x7902dd67
+0, 180, 180, 1, 149760, 0x9b771dc2
+0, 181, 181, 1, 149760, 0x0fc82bda
+0, 182, 182, 1, 149760, 0xd6128167
+0, 183, 183, 1, 149760, 0xe57b7a2f
+0, 184, 184, 1, 149760, 0x1e158d0e
+0, 185, 185, 1, 149760, 0x682c7c60
+0, 186, 186, 1, 149760, 0x32096bbe
+0, 187, 187, 1, 149760, 0x297652f2
+0, 188, 188, 1, 149760, 0x056c7432
+0, 189, 189, 1, 149760, 0x0469b39a
+0, 190, 190, 1, 149760, 0x00044bc9
+0, 191, 191, 1, 149760, 0x766c0bad
+0, 192, 192, 1, 149760, 0xd6720a40
+0, 193, 193, 1, 149760, 0x814895eb
+0, 194, 194, 1, 149760, 0x1a84fcbc
+0, 195, 195, 1, 149760, 0x8b9442aa
+0, 196, 196, 1, 149760, 0x290187d1
+0, 197, 197, 1, 149760, 0x8f87294f
+0, 198, 198, 1, 149760, 0x8c49a125
+0, 199, 199, 1, 149760, 0xe169806a
+0, 200, 200, 1, 149760, 0x18c0e2f1
+0, 201, 201, 1, 149760, 0xb92b0e67
+0, 202, 202, 1, 149760, 0x98d2acef
+0, 203, 203, 1, 149760, 0x179eeaec
+0, 204, 204, 1, 149760, 0xa054a7bb
+0, 205, 205, 1, 149760, 0x5f78d160
+0, 206, 206, 1, 149760, 0x09f9a40f
+0, 207, 207, 1, 149760, 0xfb4a59f5
+0, 208, 208, 1, 149760, 0xdc5ca1f2
+0, 209, 209, 1, 149760, 0xf2254927
+0, 210, 210, 1, 149760, 0xfda4fab3
+0, 211, 211, 1, 149760, 0x45ab23cc
+0, 212, 212, 1, 149760, 0x1f69c006
+0, 213, 213, 1, 149760, 0x326bb5a1
+0, 214, 214, 1, 149760, 0x810dad28
+0, 215, 215, 1, 149760, 0x96dfc515
+0, 216, 216, 1, 149760, 0xc685fd80
+0, 217, 217, 1, 149760, 0x18da42f4
+0, 218, 218, 1, 149760, 0x11773807
+0, 219, 219, 1, 149760, 0x3f54c458
+0, 220, 220, 1, 149760, 0xa5dff146
+0, 221, 221, 1, 149760, 0x4bc3ffcb
+0, 222, 222, 1, 149760, 0x84801971
+0, 223, 223, 1, 149760, 0x2ff65539
+0, 224, 224, 1, 149760, 0x8a7f716d
+0, 225, 225, 1, 149760, 0xe7e8cdd0
+0, 226, 226, 1, 149760, 0xc8567d5f
+0, 227, 227, 1, 149760, 0x63986bcd
+0, 228, 228, 1, 149760, 0x8817f648
+0, 229, 229, 1, 149760, 0xa0152e36
+0, 230, 230, 1, 149760, 0x2eca851e
+0, 231, 231, 1, 149760, 0x09c0f0cb
+0, 232, 232, 1, 149760, 0xf1c81b23
+0, 233, 233, 1, 149760, 0x93096c98
+0, 234, 234, 1, 149760, 0x1fe47331
+0, 235, 235, 1, 149760, 0x79c0b70e
+0, 236, 236, 1, 149760, 0xb1929b60
+0, 237, 237, 1, 149760, 0xb42ea35a
+0, 238, 238, 1, 149760, 0x42d5bf86
+0, 239, 239, 1, 149760, 0xa83efbd4
+0, 240, 240, 1, 149760, 0xbdd2f313
+0, 241, 241, 1, 149760, 0x85a5dbd4
+0, 242, 242, 1, 149760, 0xc475b180
+0, 243, 243, 1, 149760, 0x63911e68
+0, 244, 244, 1, 149760, 0x5b79baab
+0, 245, 245, 1, 149760, 0xa22d310e
+0, 246, 246, 1, 149760, 0x243ef7b5
+0, 247, 247, 1, 149760, 0x813fdc95
+0, 248, 248, 1, 149760, 0xbb7d19fa
+0, 249, 249, 1, 149760, 0x199ae62c
+0, 250, 250, 1, 149760, 0x7a4ce5b2
+0, 251, 251, 1, 149760, 0xd632a9d3
+0, 252, 252, 1, 149760, 0xc07b75fe
+0, 253, 253, 1, 149760, 0x5bae6a88
+0, 254, 254, 1, 149760, 0x29b411e0
+0, 255, 255, 1, 149760, 0x78706cbe
+0, 256, 256, 1, 149760, 0x2659a6cb
+0, 257, 257, 1, 149760, 0xefb170f8
+0, 258, 258, 1, 149760, 0x9dd107b8
+0, 259, 259, 1, 149760, 0xf38b5ce5
+0, 260, 260, 1, 149760, 0xd7e0f10e
+0, 261, 261, 1, 149760, 0x080b9e49
+0, 262, 262, 1, 149760, 0xa2274c3b
+0, 263, 263, 1, 149760, 0x3d3376c9
+0, 264, 264, 1, 149760, 0xe04719e3
+0, 265, 265, 1, 149760, 0xfe4123e3
+0, 266, 266, 1, 149760, 0x769a3cf6
+0, 267, 267, 1, 149760, 0xaf0be9e6
+0, 268, 268, 1, 149760, 0xe9baa873
+0, 269, 269, 1, 149760, 0x4f5fb405
+0, 270, 270, 1, 149760, 0x207b401e
+0, 271, 271, 1, 149760, 0xb1483351
+0, 272, 272, 1, 149760, 0x5fe3dc9f
+0, 273, 273, 1, 149760, 0xb35dcae7
+0, 274, 274, 1, 149760, 0x8cc69de4
+0, 275, 275, 1, 149760, 0xd6e29308
+0, 276, 276, 1, 149760, 0xf8f53227
+0, 277, 277, 1, 149760, 0xaf483e80
+0, 278, 278, 1, 149760, 0x287cdfc9
+0, 279, 279, 1, 149760, 0xf72b93eb
+0, 280, 280, 1, 149760, 0x09c26976
+0, 281, 281, 1, 149760, 0xae58601f
+0, 282, 282, 1, 149760, 0x7f951546
+0, 283, 283, 1, 149760, 0x81e742b2
+0, 284, 284, 1, 149760, 0xb16554a6
+0, 285, 285, 1, 149760, 0xcdafc4c0
+0, 286, 286, 1, 149760, 0x0bb335bc
+0, 287, 287, 1, 149760, 0xe1e4ba60
+0, 288, 288, 1, 149760, 0xcce3eb48
+0, 289, 289, 1, 149760, 0x8b8992a9
+0, 290, 290, 1, 149760, 0x0a5ff2f6
+0, 291, 291, 1, 149760, 0xb04b8ed1
+0, 292, 292, 1, 149760, 0x0c874aae
+0, 293, 293, 1, 149760, 0x19d6f138
+0, 294, 294, 1, 149760, 0x30e322f2
+0, 295, 295, 1, 149760, 0x67a5700c
+0, 296, 296, 1, 149760, 0xb65bd462
+0, 297, 297, 1, 149760, 0xe267d09e
+0, 298, 298, 1, 149760, 0x8824c043
+0, 299, 299, 1, 149760, 0x680cfc20
diff --git a/tests/ref/fate/hevc-conformance-RPS_C_ericsson_4 b/tests/ref/fate/hevc-conformance-RPS_C_ericsson_4
new file mode 100644
index 0000000..e97e7ea
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-RPS_C_ericsson_4
@@ -0,0 +1,41 @@
+#tb 0: 1/25
+0, 0, 0, 1, 149760, 0x8ce7200b
+0, 1, 1, 1, 149760, 0x85340cda
+0, 2, 2, 1, 149760, 0x16fd1f91
+0, 3, 3, 1, 149760, 0x7d8d312d
+0, 4, 4, 1, 149760, 0xae6ed875
+0, 5, 5, 1, 149760, 0xccac730a
+0, 6, 6, 1, 149760, 0x3d321c3f
+0, 7, 7, 1, 149760, 0x18e05688
+0, 8, 8, 1, 149760, 0x23fec4de
+0, 9, 9, 1, 149760, 0x3e0de0ca
+0, 10, 10, 1, 149760, 0x4789e861
+0, 11, 11, 1, 149760, 0x34550f71
+0, 12, 12, 1, 149760, 0xb0b1b4a7
+0, 13, 13, 1, 149760, 0xb9b8967e
+0, 14, 14, 1, 149760, 0x92e7f3c5
+0, 15, 15, 1, 149760, 0x61c0f62e
+0, 16, 16, 1, 149760, 0x819648c5
+0, 17, 17, 1, 149760, 0xe0286f95
+0, 18, 18, 1, 149760, 0xc2d85311
+0, 19, 19, 1, 149760, 0xbb07ec4e
+0, 20, 20, 1, 149760, 0xe073f10b
+0, 21, 21, 1, 149760, 0xd2e8c52f
+0, 22, 22, 1, 149760, 0x12020583
+0, 23, 23, 1, 149760, 0x0dfecaba
+0, 24, 24, 1, 149760, 0xe35f8ee5
+0, 25, 25, 1, 149760, 0x267bbf14
+0, 26, 26, 1, 149760, 0x371037a8
+0, 27, 27, 1, 149760, 0x3d188434
+0, 28, 28, 1, 149760, 0xce81fd31
+0, 29, 29, 1, 149760, 0xfbbf2801
+0, 30, 30, 1, 149760, 0x9af9d1b6
+0, 31, 31, 1, 149760, 0x14e2feea
+0, 32, 32, 1, 149760, 0x83f04b3a
+0, 33, 33, 1, 149760, 0xfc30687f
+0, 34, 34, 1, 149760, 0xaec2be07
+0, 35, 35, 1, 149760, 0xc7da6926
+0, 36, 36, 1, 149760, 0x50d20e8e
+0, 37, 37, 1, 149760, 0xd0fa63e9
+0, 38, 38, 1, 149760, 0x9d15906a
+0, 39, 39, 1, 149760, 0x4c685317
diff --git a/tests/ref/fate/hevc-conformance-RPS_D_ericsson_5 b/tests/ref/fate/hevc-conformance-RPS_D_ericsson_5
new file mode 100644
index 0000000..2851704
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-RPS_D_ericsson_5
@@ -0,0 +1,69 @@
+#tb 0: 1/25
+0, 0, 0, 1, 149760, 0x8ce7200b
+0, 1, 1, 1, 149760, 0x73610669
+0, 2, 2, 1, 149760, 0xc01620f4
+0, 3, 3, 1, 149760, 0x847a4297
+0, 4, 4, 1, 149760, 0xb4d3e870
+0, 5, 5, 1, 149760, 0xc2dd98a6
+0, 6, 6, 1, 149760, 0xefd02009
+0, 7, 7, 1, 149760, 0x3ae86ed0
+0, 8, 8, 1, 149760, 0x92f3cfb6
+0, 9, 9, 1, 149760, 0x0393e437
+0, 10, 10, 1, 149760, 0x6b29ea60
+0, 11, 11, 1, 149760, 0x9cb1216a
+0, 12, 12, 1, 149760, 0x82c2b1c4
+0, 13, 13, 1, 149760, 0x74899241
+0, 14, 14, 1, 149760, 0xa561f720
+0, 15, 15, 1, 149760, 0x339a11f6
+0, 16, 16, 1, 149760, 0x6bd9772b
+0, 17, 17, 1, 149760, 0x0a0c7c7d
+0, 18, 18, 1, 149760, 0x38426f65
+0, 19, 19, 1, 149760, 0x134ee7b3
+0, 20, 20, 1, 149760, 0xe436e35c
+0, 21, 21, 1, 149760, 0x4174d949
+0, 22, 22, 1, 149760, 0x44e60f0d
+0, 23, 23, 1, 149760, 0xbb6fb0a4
+0, 24, 24, 1, 149760, 0x715a653e
+0, 25, 25, 1, 149760, 0xad11b160
+0, 26, 26, 1, 149760, 0xfa6b368e
+0, 27, 27, 1, 149760, 0x60ff970f
+0, 28, 28, 1, 149760, 0x16430649
+0, 29, 29, 1, 149760, 0xa6cc0767
+0, 30, 30, 1, 149760, 0x59b0c566
+0, 31, 31, 1, 149760, 0xc9e3dfa9
+0, 32, 32, 1, 149760, 0x82873917
+0, 33, 33, 1, 149760, 0xc49e5d22
+0, 34, 34, 1, 149760, 0x416890a8
+0, 35, 35, 1, 149760, 0x386e57e8
+0, 36, 36, 1, 149760, 0x1c27e9d7
+0, 37, 37, 1, 149760, 0x85425596
+0, 38, 38, 1, 149760, 0xe6107df8
+0, 39, 39, 1, 149760, 0x056a3977
+0, 40, 40, 1, 149760, 0x753cf7f7
+0, 41, 41, 1, 149760, 0xc4005218
+0, 42, 42, 1, 149760, 0xce7edcf2
+0, 43, 43, 1, 149760, 0x93465fee
+0, 44, 44, 1, 149760, 0xa21b040a
+0, 45, 45, 1, 149760, 0xd82a53d5
+0, 46, 46, 1, 149760, 0x8f8fd3ae
+0, 47, 47, 1, 149760, 0x52420da5
+0, 48, 48, 1, 149760, 0xa899a9be
+0, 49, 49, 1, 149760, 0xcd85e363
+0, 50, 50, 1, 149760, 0x1a9240c4
+0, 51, 51, 1, 149760, 0xf0b11a36
+0, 52, 52, 1, 149760, 0xcf175809
+0, 53, 53, 1, 149760, 0x24afecc2
+0, 54, 54, 1, 149760, 0x874f7176
+0, 55, 55, 1, 149760, 0xb126dff9
+0, 56, 56, 1, 149760, 0x825ba060
+0, 57, 57, 1, 149760, 0x18c55eed
+0, 58, 58, 1, 149760, 0xf09b03f0
+0, 59, 59, 1, 149760, 0xf4dafd64
+0, 60, 60, 1, 149760, 0x08b49190
+0, 61, 61, 1, 149760, 0xcf336dc7
+0, 62, 62, 1, 149760, 0x51c65c08
+0, 63, 63, 1, 149760, 0x6cfe3433
+0, 64, 64, 1, 149760, 0x4b0af196
+0, 65, 65, 1, 149760, 0xffaeb2db
+0, 66, 66, 1, 149760, 0xa990a19f
+0, 67, 67, 1, 149760, 0x7ed944a3
diff --git a/tests/ref/fate/hevc-conformance-RPS_E_qualcomm_5 b/tests/ref/fate/hevc-conformance-RPS_E_qualcomm_5
new file mode 100644
index 0000000..82c25e1
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-RPS_E_qualcomm_5
@@ -0,0 +1,301 @@
+#tb 0: 1/25
+0, 0, 0, 1, 149760, 0x8edb27d7
+0, 1, 1, 1, 149760, 0xd62a31bc
+0, 2, 2, 1, 149760, 0xec822f84
+0, 3, 3, 1, 149760, 0x7a0a0f25
+0, 4, 4, 1, 149760, 0x461dd882
+0, 5, 5, 1, 149760, 0x62777923
+0, 6, 6, 1, 149760, 0x063c2559
+0, 7, 7, 1, 149760, 0x03b34c02
+0, 8, 8, 1, 149760, 0xe999bdad
+0, 9, 9, 1, 149760, 0x3285f731
+0, 10, 10, 1, 149760, 0x1f8ffaaa
+0, 11, 11, 1, 149760, 0xd7c956f4
+0, 12, 12, 1, 149760, 0xb9e3da56
+0, 13, 13, 1, 149760, 0x1200953f
+0, 14, 14, 1, 149760, 0x06c212cc
+0, 15, 15, 1, 149760, 0xaaa84f01
+0, 16, 16, 1, 149760, 0x7a606de8
+0, 17, 17, 1, 149760, 0x47e49e5a
+0, 18, 18, 1, 149760, 0x666a3370
+0, 19, 19, 1, 149760, 0x187b6b6c
+0, 20, 20, 1, 149760, 0x3c8f0ef4
+0, 21, 21, 1, 149760, 0xc3e59d36
+0, 22, 22, 1, 149760, 0xecb40b3b
+0, 23, 23, 1, 149760, 0x0ae9e31e
+0, 24, 24, 1, 149760, 0xd324746b
+0, 25, 25, 1, 149760, 0xc337c3d5
+0, 26, 26, 1, 149760, 0xd3883c16
+0, 27, 27, 1, 149760, 0xa28b836c
+0, 28, 28, 1, 149760, 0x1cd61f86
+0, 29, 29, 1, 149760, 0x52b51344
+0, 30, 30, 1, 149760, 0x3980a396
+0, 31, 31, 1, 149760, 0x85d0e262
+0, 32, 32, 1, 149760, 0xbd342d08
+0, 33, 33, 1, 149760, 0xc6114038
+0, 34, 34, 1, 149760, 0xc3ab6ca9
+0, 35, 35, 1, 149760, 0x6db56aa7
+0, 36, 36, 1, 149760, 0x22df9ab0
+0, 37, 37, 1, 149760, 0xfa6d2caf
+0, 38, 38, 1, 149760, 0xc1b64e52
+0, 39, 39, 1, 149760, 0x4b9c1d64
+0, 40, 40, 1, 149760, 0xbab6de8f
+0, 41, 41, 1, 149760, 0xfc0e1193
+0, 42, 42, 1, 149760, 0x8fa0a268
+0, 43, 43, 1, 149760, 0x80cf5e07
+0, 44, 44, 1, 149760, 0xe9720cd6
+0, 45, 45, 1, 149760, 0xa9bb2593
+0, 46, 46, 1, 149760, 0xc2e3e7c6
+0, 47, 47, 1, 149760, 0xc9a4ffd6
+0, 48, 48, 1, 149760, 0x9acebbe2
+0, 49, 49, 1, 149760, 0xb3a6bee1
+0, 50, 50, 1, 149760, 0xd1f12057
+0, 51, 51, 1, 149760, 0x9a2306c0
+0, 52, 52, 1, 149760, 0xd1ee37ff
+0, 53, 53, 1, 149760, 0xb0e1dca1
+0, 54, 54, 1, 149760, 0x35646e46
+0, 55, 55, 1, 149760, 0x803baac5
+0, 56, 56, 1, 149760, 0x7ee17b15
+0, 57, 57, 1, 149760, 0x03274ce1
+0, 58, 58, 1, 149760, 0xf3db2fea
+0, 59, 59, 1, 149760, 0xc3c4ff33
+0, 60, 60, 1, 149760, 0x0fc4786e
+0, 61, 61, 1, 149760, 0x27505756
+0, 62, 62, 1, 149760, 0x4c797266
+0, 63, 63, 1, 149760, 0xeba43f1b
+0, 64, 64, 1, 149760, 0x1ae5f13d
+0, 65, 65, 1, 149760, 0x97e186b1
+0, 66, 66, 1, 149760, 0xc0556895
+0, 67, 67, 1, 149760, 0x4e4d18ed
+0, 68, 68, 1, 149760, 0x39811c80
+0, 69, 69, 1, 149760, 0x6bca8c2f
+0, 70, 70, 1, 149760, 0x27ec4807
+0, 71, 71, 1, 149760, 0x50cea38b
+0, 72, 72, 1, 149760, 0x7ec4c09d
+0, 73, 73, 1, 149760, 0xb2a8afee
+0, 74, 74, 1, 149760, 0x0e943cbf
+0, 75, 75, 1, 149760, 0x7c119ea8
+0, 76, 76, 1, 149760, 0x71e194e5
+0, 77, 77, 1, 149760, 0x6a5d792d
+0, 78, 78, 1, 149760, 0xb8aeb406
+0, 79, 79, 1, 149760, 0x263767f2
+0, 80, 80, 1, 149760, 0xcfbef5ae
+0, 81, 81, 1, 149760, 0xad7eb01c
+0, 82, 82, 1, 149760, 0x612d937d
+0, 83, 83, 1, 149760, 0x90a591fd
+0, 84, 84, 1, 149760, 0x582a60dd
+0, 85, 85, 1, 149760, 0x2640124e
+0, 86, 86, 1, 149760, 0x1c12b037
+0, 87, 87, 1, 149760, 0xc916c4e7
+0, 88, 88, 1, 149760, 0x43d2bfe6
+0, 89, 89, 1, 149760, 0xdc7460c4
+0, 90, 90, 1, 149760, 0xc46e21a8
+0, 91, 91, 1, 149760, 0xe08dbd50
+0, 92, 92, 1, 149760, 0xf40bceed
+0, 93, 93, 1, 149760, 0x0ab01b81
+0, 94, 94, 1, 149760, 0xe6ab1f16
+0, 95, 95, 1, 149760, 0x6b4f6a62
+0, 96, 96, 1, 149760, 0x8ff7a1a1
+0, 97, 97, 1, 149760, 0x079be281
+0, 98, 98, 1, 149760, 0xa24bc187
+0, 99, 99, 1, 149760, 0xfbed7e79
+0, 100, 100, 1, 149760, 0xa27c2048
+0, 101, 101, 1, 149760, 0xe6119831
+0, 102, 102, 1, 149760, 0xc75684c6
+0, 103, 103, 1, 149760, 0x76575ef4
+0, 104, 104, 1, 149760, 0xebd32a7e
+0, 105, 105, 1, 149760, 0x6e5c703a
+0, 106, 106, 1, 149760, 0x3c43d0b3
+0, 107, 107, 1, 149760, 0xcc3354af
+0, 108, 108, 1, 149760, 0xa7bc26f3
+0, 109, 109, 1, 149760, 0xb04b0400
+0, 110, 110, 1, 149760, 0x3e5d3995
+0, 111, 111, 1, 149760, 0x549331ae
+0, 112, 112, 1, 149760, 0xd39031c0
+0, 113, 113, 1, 149760, 0xada1a1bd
+0, 114, 114, 1, 149760, 0xd08a4bcb
+0, 115, 115, 1, 149760, 0xcbefb4fa
+0, 116, 116, 1, 149760, 0xb311a7e0
+0, 117, 117, 1, 149760, 0xab23a6f2
+0, 118, 118, 1, 149760, 0xa90a6dfb
+0, 119, 119, 1, 149760, 0xafcc72b7
+0, 120, 120, 1, 149760, 0xe7c48044
+0, 121, 121, 1, 149760, 0x4449cf72
+0, 122, 122, 1, 149760, 0xfe4ba9d7
+0, 123, 123, 1, 149760, 0x76623bda
+0, 124, 124, 1, 149760, 0x8d071b0b
+0, 125, 125, 1, 149760, 0x777aaefa
+0, 126, 126, 1, 149760, 0xab995bab
+0, 127, 127, 1, 149760, 0xfd0e8e0c
+0, 128, 128, 1, 149760, 0xb6d651e5
+0, 129, 129, 1, 149760, 0x0646c2d0
+0, 130, 130, 1, 149760, 0xefc2561a
+0, 131, 131, 1, 149760, 0xaa86dcd1
+0, 132, 132, 1, 149760, 0x0caf821e
+0, 133, 133, 1, 149760, 0x55a5e7fa
+0, 134, 134, 1, 149760, 0x1a011bae
+0, 135, 135, 1, 149760, 0xe7a922b2
+0, 136, 136, 1, 149760, 0x4b968175
+0, 137, 137, 1, 149760, 0xc0bc1018
+0, 138, 138, 1, 149760, 0x58775461
+0, 139, 139, 1, 149760, 0x77dad082
+0, 140, 140, 1, 149760, 0x995e78d7
+0, 141, 141, 1, 149760, 0xc6360898
+0, 142, 142, 1, 149760, 0xbd0b48ce
+0, 143, 143, 1, 149760, 0x6d076602
+0, 144, 144, 1, 149760, 0xc3459e98
+0, 145, 145, 1, 149760, 0x8e53625e
+0, 146, 146, 1, 149760, 0xd1ba7915
+0, 147, 147, 1, 149760, 0xf41a48e7
+0, 148, 148, 1, 149760, 0xc3fbdcc3
+0, 149, 149, 1, 149760, 0x1f726dcf
+0, 150, 150, 1, 149760, 0x6f882d61
+0, 151, 151, 1, 149760, 0x2e02c8c5
+0, 152, 152, 1, 149760, 0x35ed54c6
+0, 153, 153, 1, 149760, 0x11dd8c48
+0, 154, 154, 1, 149760, 0xc95bf20b
+0, 155, 155, 1, 149760, 0x64f96433
+0, 156, 156, 1, 149760, 0x1ab5d8d5
+0, 157, 157, 1, 149760, 0x3af856f0
+0, 158, 158, 1, 149760, 0xdaa3bd1b
+0, 159, 159, 1, 149760, 0x25c64816
+0, 160, 160, 1, 149760, 0x6a4cc5d7
+0, 161, 161, 1, 149760, 0xf8e815f5
+0, 162, 162, 1, 149760, 0xa0bf431e
+0, 163, 163, 1, 149760, 0x09567fc4
+0, 164, 164, 1, 149760, 0x2d9408d7
+0, 165, 165, 1, 149760, 0xe09fff24
+0, 166, 166, 1, 149760, 0x6d58a81b
+0, 167, 167, 1, 149760, 0x0280e181
+0, 168, 168, 1, 149760, 0x465e63d1
+0, 169, 169, 1, 149760, 0xedb432a0
+0, 170, 170, 1, 149760, 0xdff70d73
+0, 171, 171, 1, 149760, 0x9386fdb4
+0, 172, 172, 1, 149760, 0xdcb03cb9
+0, 173, 173, 1, 149760, 0x3538dbd4
+0, 174, 174, 1, 149760, 0xc637709d
+0, 175, 175, 1, 149760, 0x7a1a6681
+0, 176, 176, 1, 149760, 0x403ca1e0
+0, 177, 177, 1, 149760, 0xe562d48a
+0, 178, 178, 1, 149760, 0x90a2e933
+0, 179, 179, 1, 149760, 0x0e9e167a
+0, 180, 180, 1, 149760, 0x2da90c4d
+0, 181, 181, 1, 149760, 0x2ce92218
+0, 182, 182, 1, 149760, 0x164a613d
+0, 183, 183, 1, 149760, 0x336d9e2e
+0, 184, 184, 1, 149760, 0x598986e6
+0, 185, 185, 1, 149760, 0xd0039cfc
+0, 186, 186, 1, 149760, 0x8e74c5e6
+0, 187, 187, 1, 149760, 0xb95fa63c
+0, 188, 188, 1, 149760, 0xc688c596
+0, 189, 189, 1, 149760, 0x4757034b
+0, 190, 190, 1, 149760, 0xc9ac948a
+0, 191, 191, 1, 149760, 0x580b9d60
+0, 192, 192, 1, 149760, 0xf39031d6
+0, 193, 193, 1, 149760, 0x2d68ad7b
+0, 194, 194, 1, 149760, 0xf72815ea
+0, 195, 195, 1, 149760, 0xc16323fa
+0, 196, 196, 1, 149760, 0x8a65665e
+0, 197, 197, 1, 149760, 0xcf1d5a89
+0, 198, 198, 1, 149760, 0x03f3011a
+0, 199, 199, 1, 149760, 0x24c47cbc
+0, 200, 200, 1, 149760, 0xcc89db6d
+0, 201, 201, 1, 149760, 0xd8332e3c
+0, 202, 202, 1, 149760, 0x8a73af5f
+0, 203, 203, 1, 149760, 0x9079e1c5
+0, 204, 204, 1, 149760, 0x7b70b098
+0, 205, 205, 1, 149760, 0x8a0fc720
+0, 206, 206, 1, 149760, 0x92644eef
+0, 207, 207, 1, 149760, 0x75cc5f7a
+0, 208, 208, 1, 149760, 0xf04b9756
+0, 209, 209, 1, 149760, 0x156b33cd
+0, 210, 210, 1, 149760, 0x4876d087
+0, 211, 211, 1, 149760, 0x393c01c8
+0, 212, 212, 1, 149760, 0x29b0a5d9
+0, 213, 213, 1, 149760, 0xd76249a1
+0, 214, 214, 1, 149760, 0xb946135e
+0, 215, 215, 1, 149760, 0x4968f245
+0, 216, 216, 1, 149760, 0xb91e27b2
+0, 217, 217, 1, 149760, 0x485bfa6c
+0, 218, 218, 1, 149760, 0xe7f9fe28
+0, 219, 219, 1, 149760, 0x46a6a837
+0, 220, 220, 1, 149760, 0xd2cf971c
+0, 221, 221, 1, 149760, 0xcb518e01
+0, 222, 222, 1, 149760, 0x7870fcd4
+0, 223, 223, 1, 149760, 0x8af73981
+0, 224, 224, 1, 149760, 0xa90281a7
+0, 225, 225, 1, 149760, 0x3fd9c634
+0, 226, 226, 1, 149760, 0x5c4e7e8a
+0, 227, 227, 1, 149760, 0x520d80e9
+0, 228, 228, 1, 149760, 0xd94a7e31
+0, 229, 229, 1, 149760, 0x2a846f4e
+0, 230, 230, 1, 149760, 0x71f027f1
+0, 231, 231, 1, 149760, 0x6edbe368
+0, 232, 232, 1, 149760, 0x5c9923eb
+0, 233, 233, 1, 149760, 0xff230eab
+0, 234, 234, 1, 149760, 0xc7a5ca99
+0, 235, 235, 1, 149760, 0x50732f2a
+0, 236, 236, 1, 149760, 0xa9f3c8bc
+0, 237, 237, 1, 149760, 0x7fa53464
+0, 238, 238, 1, 149760, 0xe4c2edcd
+0, 239, 239, 1, 149760, 0x43f1e758
+0, 240, 240, 1, 149760, 0xdb6b153b
+0, 241, 241, 1, 149760, 0x0979d792
+0, 242, 242, 1, 149760, 0xaae4a6fd
+0, 243, 243, 1, 149760, 0x7ffd1046
+0, 244, 244, 1, 149760, 0x083becd8
+0, 245, 245, 1, 149760, 0xba86428d
+0, 246, 246, 1, 149760, 0xd4cf652a
+0, 247, 247, 1, 149760, 0xe518a1e4
+0, 248, 248, 1, 149760, 0xfbcf0017
+0, 249, 249, 1, 149760, 0xd827b5b1
+0, 250, 250, 1, 149760, 0x6b95eb0d
+0, 251, 251, 1, 149760, 0x625bf8f9
+0, 252, 252, 1, 149760, 0xde17b8b8
+0, 253, 253, 1, 149760, 0xfd731e76
+0, 254, 254, 1, 149760, 0xae0ce756
+0, 255, 255, 1, 149760, 0x15ec506d
+0, 256, 256, 1, 149760, 0xfc9dba5c
+0, 257, 257, 1, 149760, 0x87e46ba1
+0, 258, 258, 1, 149760, 0x31f1d787
+0, 259, 259, 1, 149760, 0xfbde528e
+0, 260, 260, 1, 149760, 0x152becf8
+0, 261, 261, 1, 149760, 0x008386d7
+0, 262, 262, 1, 149760, 0x53c00ef9
+0, 263, 263, 1, 149760, 0x322d4f0b
+0, 264, 264, 1, 149760, 0xd31bf0ec
+0, 265, 265, 1, 149760, 0x66b5097e
+0, 266, 266, 1, 149760, 0xa9cd719f
+0, 267, 267, 1, 149760, 0x427cdc52
+0, 268, 268, 1, 149760, 0x6647dabc
+0, 269, 269, 1, 149760, 0x651df15f
+0, 270, 270, 1, 149760, 0x4ce124c7
+0, 271, 271, 1, 149760, 0x8ad42ad7
+0, 272, 272, 1, 149760, 0x7303ce98
+0, 273, 273, 1, 149760, 0x0c8ad3ab
+0, 274, 274, 1, 149760, 0x86859065
+0, 275, 275, 1, 149760, 0x97f23fc7
+0, 276, 276, 1, 149760, 0x6fde3d1a
+0, 277, 277, 1, 149760, 0xca12860e
+0, 278, 278, 1, 149760, 0xd0c98709
+0, 279, 279, 1, 149760, 0x8f234c79
+0, 280, 280, 1, 149760, 0xbc6987fa
+0, 281, 281, 1, 149760, 0x40246698
+0, 282, 282, 1, 149760, 0x7f83b9ad
+0, 283, 283, 1, 149760, 0x87a3596b
+0, 284, 284, 1, 149760, 0x0ba5d7f6
+0, 285, 285, 1, 149760, 0x2a015c97
+0, 286, 286, 1, 149760, 0xa1a73e7b
+0, 287, 287, 1, 149760, 0x3c1d8178
+0, 288, 288, 1, 149760, 0x2207f0b6
+0, 289, 289, 1, 149760, 0x1f56738a
+0, 290, 290, 1, 149760, 0x0014e5b6
+0, 291, 291, 1, 149760, 0xe0113ffa
+0, 292, 292, 1, 149760, 0x7df23683
+0, 293, 293, 1, 149760, 0x2a1afb23
+0, 294, 294, 1, 149760, 0x072ced03
+0, 295, 295, 1, 149760, 0x7afca5d3
+0, 296, 296, 1, 149760, 0x6055b3da
+0, 297, 297, 1, 149760, 0xa785c79c
+0, 298, 298, 1, 149760, 0x3606db52
+0, 299, 299, 1, 149760, 0x007fdd05
diff --git a/tests/ref/fate/hevc-conformance-RQT_A_HHI_4 b/tests/ref/fate/hevc-conformance-RQT_A_HHI_4
new file mode 100644
index 0000000..5f2b9da
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-RQT_A_HHI_4
@@ -0,0 +1,3 @@
+#tb 0: 1/25
+0, 0, 0, 1, 599040, 0x5c0f5423
+0, 1, 1, 1, 599040, 0x3d23be58
diff --git a/tests/ref/fate/hevc-conformance-RQT_B_HHI_4 b/tests/ref/fate/hevc-conformance-RQT_B_HHI_4
new file mode 100644
index 0000000..dcf2691
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-RQT_B_HHI_4
@@ -0,0 +1,3 @@
+#tb 0: 1/25
+0, 0, 0, 1, 599040, 0x69854954
+0, 1, 1, 1, 599040, 0x695ebc85
diff --git a/tests/ref/fate/hevc-conformance-RQT_C_HHI_4 b/tests/ref/fate/hevc-conformance-RQT_C_HHI_4
new file mode 100644
index 0000000..2e88350
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-RQT_C_HHI_4
@@ -0,0 +1,3 @@
+#tb 0: 1/25
+0, 0, 0, 1, 599040, 0x65433cfe
+0, 1, 1, 1, 599040, 0x9309e2c5
diff --git a/tests/ref/fate/hevc-conformance-RQT_D_HHI_4 b/tests/ref/fate/hevc-conformance-RQT_D_HHI_4
new file mode 100644
index 0000000..7f73896
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-RQT_D_HHI_4
@@ -0,0 +1,3 @@
+#tb 0: 1/25
+0, 0, 0, 1, 599040, 0x88d741bf
+0, 1, 1, 1, 599040, 0xbbd9ab22
diff --git a/tests/ref/fate/hevc-conformance-RQT_E_HHI_4 b/tests/ref/fate/hevc-conformance-RQT_E_HHI_4
new file mode 100644
index 0000000..f062318
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-RQT_E_HHI_4
@@ -0,0 +1,3 @@
+#tb 0: 1/25
+0, 0, 0, 1, 599040, 0xce2e511d
+0, 1, 1, 1, 599040, 0xe55192d0
diff --git a/tests/ref/fate/hevc-conformance-RQT_F_HHI_4 b/tests/ref/fate/hevc-conformance-RQT_F_HHI_4
new file mode 100644
index 0000000..26bf5ac
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-RQT_F_HHI_4
@@ -0,0 +1,3 @@
+#tb 0: 1/25
+0, 0, 0, 1, 599040, 0x65433cfe
+0, 1, 1, 1, 599040, 0x6f99cc5f
diff --git a/tests/ref/fate/hevc-conformance-RQT_G_HHI_4 b/tests/ref/fate/hevc-conformance-RQT_G_HHI_4
new file mode 100644
index 0000000..d36ea01
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-RQT_G_HHI_4
@@ -0,0 +1,3 @@
+#tb 0: 1/25
+0, 0, 0, 1, 599040, 0x5c0f5423
+0, 1, 1, 1, 599040, 0xe805b181
diff --git a/tests/ref/fate/hevc-conformance-SAO_A_MediaTek_4 b/tests/ref/fate/hevc-conformance-SAO_A_MediaTek_4
new file mode 100644
index 0000000..01226d9
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-SAO_A_MediaTek_4
@@ -0,0 +1,61 @@
+#tb 0: 1/25
+0, 0, 0, 1, 149760, 0x304198c2
+0, 1, 1, 1, 149760, 0xe765e30d
+0, 2, 2, 1, 149760, 0x0130a054
+0, 3, 3, 1, 149760, 0x169ed0c3
+0, 4, 4, 1, 149760, 0x334881a5
+0, 5, 5, 1, 149760, 0x06cadd37
+0, 6, 6, 1, 149760, 0x5ec4a7ee
+0, 7, 7, 1, 149760, 0x595fd534
+0, 8, 8, 1, 149760, 0xa1d97197
+0, 9, 9, 1, 149760, 0xf79a9d84
+0, 10, 10, 1, 149760, 0x10d84f28
+0, 11, 11, 1, 149760, 0xab375848
+0, 12, 12, 1, 149760, 0x3079f8ca
+0, 13, 13, 1, 149760, 0xac101dfb
+0, 14, 14, 1, 149760, 0x5354f852
+0, 15, 15, 1, 149760, 0x64d709d5
+0, 16, 16, 1, 149760, 0xff669ff2
+0, 17, 17, 1, 149760, 0xd20dd474
+0, 18, 18, 1, 149760, 0x32439e22
+0, 19, 19, 1, 149760, 0x3ae5a118
+0, 20, 20, 1, 149760, 0xebe245ef
+0, 21, 21, 1, 149760, 0x9d046e35
+0, 22, 22, 1, 149760, 0x2e5b2347
+0, 23, 23, 1, 149760, 0x0e683e86
+0, 24, 24, 1, 149760, 0xccc1019e
+0, 25, 25, 1, 149760, 0x42a9571a
+0, 26, 26, 1, 149760, 0x8999386c
+0, 27, 27, 1, 149760, 0x3d164645
+0, 28, 28, 1, 149760, 0x657afc5e
+0, 29, 29, 1, 149760, 0x06f832f9
+0, 30, 30, 1, 149760, 0xfbedfe1e
+0, 31, 31, 1, 149760, 0x1edc2fc5
+0, 32, 32, 1, 149760, 0xe1cee4e7
+0, 33, 33, 1, 149760, 0x43a823e0
+0, 34, 34, 1, 149760, 0xc2f42916
+0, 35, 35, 1, 149760, 0x51db1483
+0, 36, 36, 1, 149760, 0x54a9d6bf
+0, 37, 37, 1, 149760, 0x7324e246
+0, 38, 38, 1, 149760, 0x2523cc9d
+0, 39, 39, 1, 149760, 0xfa3bdce3
+0, 40, 40, 1, 149760, 0xcf9fb7bb
+0, 41, 41, 1, 149760, 0xe914e23c
+0, 42, 42, 1, 149760, 0x6c9fd72a
+0, 43, 43, 1, 149760, 0x3580cca9
+0, 44, 44, 1, 149760, 0x1d4ec5c0
+0, 45, 45, 1, 149760, 0x52c4d418
+0, 46, 46, 1, 149760, 0xb728ae3e
+0, 47, 47, 1, 149760, 0x6616ae50
+0, 48, 48, 1, 149760, 0x6f1a919d
+0, 49, 49, 1, 149760, 0x6e76b774
+0, 50, 50, 1, 149760, 0x6075b37d
+0, 51, 51, 1, 149760, 0xeeb7b8df
+0, 52, 52, 1, 149760, 0xfd979056
+0, 53, 53, 1, 149760, 0xc0fda5ee
+0, 54, 54, 1, 149760, 0xd1329055
+0, 55, 55, 1, 149760, 0x9b179f0f
+0, 56, 56, 1, 149760, 0x7461850a
+0, 57, 57, 1, 149760, 0xe63a86ea
+0, 58, 58, 1, 149760, 0xe85c6f94
+0, 59, 59, 1, 149760, 0x0b857d13
diff --git a/tests/ref/fate/hevc-conformance-SAO_B_MediaTek_5 b/tests/ref/fate/hevc-conformance-SAO_B_MediaTek_5
new file mode 100644
index 0000000..9da0268
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-SAO_B_MediaTek_5
@@ -0,0 +1,61 @@
+#tb 0: 1/25
+0, 0, 0, 1, 599040, 0xe56f6a5c
+0, 1, 1, 1, 599040, 0x31ec1bb9
+0, 2, 2, 1, 599040, 0xf3ce0311
+0, 3, 3, 1, 599040, 0x1ae1c223
+0, 4, 4, 1, 599040, 0x4369499d
+0, 5, 5, 1, 599040, 0xd7366bd6
+0, 6, 6, 1, 599040, 0x6d3a9099
+0, 7, 7, 1, 599040, 0x49dea495
+0, 8, 8, 1, 599040, 0x375640e7
+0, 9, 9, 1, 599040, 0x76b6f9b0
+0, 10, 10, 1, 599040, 0x7d1f48cf
+0, 11, 11, 1, 599040, 0x4a01899c
+0, 12, 12, 1, 599040, 0x34ff06e6
+0, 13, 13, 1, 599040, 0x270d874f
+0, 14, 14, 1, 599040, 0x5a091d5c
+0, 15, 15, 1, 599040, 0x36406961
+0, 16, 16, 1, 599040, 0xd32f2687
+0, 17, 17, 1, 599040, 0x8d533cb5
+0, 18, 18, 1, 599040, 0x5f189f98
+0, 19, 19, 1, 599040, 0x32b76de3
+0, 20, 20, 1, 599040, 0x2dd0e738
+0, 21, 21, 1, 599040, 0xbc24fe31
+0, 22, 22, 1, 599040, 0xfd5e6578
+0, 23, 23, 1, 599040, 0x23ea676c
+0, 24, 24, 1, 599040, 0xa86d1f70
+0, 25, 25, 1, 599040, 0xef35e81e
+0, 26, 26, 1, 599040, 0x19e5b355
+0, 27, 27, 1, 599040, 0x9dab17b3
+0, 28, 28, 1, 599040, 0x1aebe590
+0, 29, 29, 1, 599040, 0x6fd9b16e
+0, 30, 30, 1, 599040, 0xd2f3087b
+0, 31, 31, 1, 599040, 0x4bdc5019
+0, 32, 32, 1, 599040, 0xeccd10a0
+0, 33, 33, 1, 599040, 0x1eacd33c
+0, 34, 34, 1, 599040, 0xc73d2b6d
+0, 35, 35, 1, 599040, 0xe1305f2b
+0, 36, 36, 1, 599040, 0xb66c5e54
+0, 37, 37, 1, 599040, 0x0ac17870
+0, 38, 38, 1, 599040, 0x9d976180
+0, 39, 39, 1, 599040, 0x0be7d418
+0, 40, 40, 1, 599040, 0x5c4fb909
+0, 41, 41, 1, 599040, 0x7a4de7c2
+0, 42, 42, 1, 599040, 0x9c0d3ed3
+0, 43, 43, 1, 599040, 0xf9b2ba7e
+0, 44, 44, 1, 599040, 0x78e77b58
+0, 45, 45, 1, 599040, 0xc30ead17
+0, 46, 46, 1, 599040, 0x647c9095
+0, 47, 47, 1, 599040, 0x070d61a3
+0, 48, 48, 1, 599040, 0x0ec33c61
+0, 49, 49, 1, 599040, 0x0adcf4f3
+0, 50, 50, 1, 599040, 0x5cbb5aa6
+0, 51, 51, 1, 599040, 0xb9f99f74
+0, 52, 52, 1, 599040, 0xebc3c13e
+0, 53, 53, 1, 599040, 0x40e76036
+0, 54, 54, 1, 599040, 0xf08d2df3
+0, 55, 55, 1, 599040, 0x47442b55
+0, 56, 56, 1, 599040, 0x147622c1
+0, 57, 57, 1, 599040, 0xc95508a3
+0, 58, 58, 1, 599040, 0x361b8995
+0, 59, 59, 1, 599040, 0x51086ed4
diff --git a/tests/ref/fate/hevc-conformance-SAO_C_Samsung_4 b/tests/ref/fate/hevc-conformance-SAO_C_Samsung_4
new file mode 100644
index 0000000..f87921d
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-SAO_C_Samsung_4
@@ -0,0 +1,61 @@
+#tb 0: 1/25
+0, 0, 0, 1, 149760, 0xf923a1a0
+0, 1, 1, 1, 149760, 0x614d851a
+0, 2, 2, 1, 149760, 0xc3976ce4
+0, 3, 3, 1, 149760, 0x39925bdc
+0, 4, 4, 1, 149760, 0x86067422
+0, 5, 5, 1, 149760, 0x60dc6078
+0, 6, 6, 1, 149760, 0xac79a412
+0, 7, 7, 1, 149760, 0x3b1bab1e
+0, 8, 8, 1, 149760, 0x7562555f
+0, 9, 9, 1, 149760, 0xf0a2385f
+0, 10, 10, 1, 149760, 0xd2661fa6
+0, 11, 11, 1, 149760, 0x89b30a0a
+0, 12, 12, 1, 149760, 0x3c59f8cb
+0, 13, 13, 1, 149760, 0x70e4da0a
+0, 14, 14, 1, 149760, 0x5e60caa8
+0, 15, 15, 1, 149760, 0x9828a7e0
+0, 16, 16, 1, 149760, 0x11e069a1
+0, 17, 17, 1, 149760, 0xe98a55c2
+0, 18, 18, 1, 149760, 0xaa9f64e5
+0, 19, 19, 1, 149760, 0x03c32cea
+0, 20, 20, 1, 149760, 0x869e0f6e
+0, 21, 21, 1, 149760, 0x54baeff8
+0, 22, 22, 1, 149760, 0xf1f8cc04
+0, 23, 23, 1, 149760, 0x1724aafb
+0, 24, 24, 1, 149760, 0xaf01b9f8
+0, 25, 25, 1, 149760, 0xb1b5bbe9
+0, 26, 26, 1, 149760, 0xd9e6d5a4
+0, 27, 27, 1, 149760, 0x8351ca2d
+0, 28, 28, 1, 149760, 0x38dceffe
+0, 29, 29, 1, 149760, 0x3bffe1c4
+0, 30, 30, 1, 149760, 0x4075b534
+0, 31, 31, 1, 149760, 0x0e8fb246
+0, 32, 32, 1, 149760, 0x70fceafb
+0, 33, 33, 1, 149760, 0x940bec8d
+0, 34, 34, 1, 149760, 0x7d34f896
+0, 35, 35, 1, 149760, 0x39a1d77f
+0, 36, 36, 1, 149760, 0x9755e104
+0, 37, 37, 1, 149760, 0xd584cb48
+0, 38, 38, 1, 149760, 0x06ecdd44
+0, 39, 39, 1, 149760, 0x0226a40d
+0, 40, 40, 1, 149760, 0xb53aaf56
+0, 41, 41, 1, 149760, 0xdad4a984
+0, 42, 42, 1, 149760, 0xa58c9eb0
+0, 43, 43, 1, 149760, 0x7330bde6
+0, 44, 44, 1, 149760, 0x98fcabd9
+0, 45, 45, 1, 149760, 0x9570b74a
+0, 46, 46, 1, 149760, 0x3c1eab60
+0, 47, 47, 1, 149760, 0x2038a069
+0, 48, 48, 1, 149760, 0x672fa347
+0, 49, 49, 1, 149760, 0xa7328b16
+0, 50, 50, 1, 149760, 0x677b6a87
+0, 51, 51, 1, 149760, 0xb036b028
+0, 52, 52, 1, 149760, 0x7a7f9966
+0, 53, 53, 1, 149760, 0xc34b7c39
+0, 54, 54, 1, 149760, 0xb44345ed
+0, 55, 55, 1, 149760, 0x90193c4a
+0, 56, 56, 1, 149760, 0x90986e7b
+0, 57, 57, 1, 149760, 0x5e8e6545
+0, 58, 58, 1, 149760, 0x3ac7758e
+0, 59, 59, 1, 149760, 0x4dd271fb
diff --git a/tests/ref/fate/hevc-conformance-SAO_D_Samsung_4 b/tests/ref/fate/hevc-conformance-SAO_D_Samsung_4
new file mode 100644
index 0000000..ce1cefe
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-SAO_D_Samsung_4
@@ -0,0 +1,61 @@
+#tb 0: 1/25
+0, 0, 0, 1, 149760, 0x0d2edbbc
+0, 1, 1, 1, 149760, 0x4830af95
+0, 2, 2, 1, 149760, 0x39e8d3bb
+0, 3, 3, 1, 149760, 0x3cc8d639
+0, 4, 4, 1, 149760, 0xfcfe8415
+0, 5, 5, 1, 149760, 0xa6cf9a48
+0, 6, 6, 1, 149760, 0x0fe191b3
+0, 7, 7, 1, 149760, 0x71d26e20
+0, 8, 8, 1, 149760, 0x1ee5541a
+0, 9, 9, 1, 149760, 0x4ac56652
+0, 10, 10, 1, 149760, 0x967e7c2c
+0, 11, 11, 1, 149760, 0x2011ba0c
+0, 12, 12, 1, 149760, 0x2da4bc05
+0, 13, 13, 1, 149760, 0x6354fac2
+0, 14, 14, 1, 149760, 0x799e66ce
+0, 15, 15, 1, 149760, 0x2ca24940
+0, 16, 16, 1, 149760, 0x2a102e28
+0, 17, 17, 1, 149760, 0x652edcce
+0, 18, 18, 1, 149760, 0xb1c34a9a
+0, 19, 19, 1, 149760, 0xfae6ce90
+0, 20, 20, 1, 149760, 0xf42fddbf
+0, 21, 21, 1, 149760, 0x2a8532c3
+0, 22, 22, 1, 149760, 0xbe43addc
+0, 23, 23, 1, 149760, 0x3545f94a
+0, 24, 24, 1, 149760, 0xa35fa6fa
+0, 25, 25, 1, 149760, 0xfed8577f
+0, 26, 26, 1, 149760, 0xac03b492
+0, 27, 27, 1, 149760, 0x1fbdabc9
+0, 28, 28, 1, 149760, 0x99707175
+0, 29, 29, 1, 149760, 0x95e69481
+0, 30, 30, 1, 149760, 0xd68412d8
+0, 31, 31, 1, 149760, 0x9f900e37
+0, 32, 32, 1, 149760, 0x7e6eceba
+0, 33, 33, 1, 149760, 0xd1ca85af
+0, 34, 34, 1, 149760, 0x352b1d50
+0, 35, 35, 1, 149760, 0xdef3e377
+0, 36, 36, 1, 149760, 0x08efcc16
+0, 37, 37, 1, 149760, 0xc20a7c74
+0, 38, 38, 1, 149760, 0xa8e45939
+0, 39, 39, 1, 149760, 0x322546cf
+0, 40, 40, 1, 149760, 0xf7167766
+0, 41, 41, 1, 149760, 0x959f808f
+0, 42, 42, 1, 149760, 0xcca5ccc3
+0, 43, 43, 1, 149760, 0x18789407
+0, 44, 44, 1, 149760, 0xf6c97e87
+0, 45, 45, 1, 149760, 0x58aaba55
+0, 46, 46, 1, 149760, 0xc3529005
+0, 47, 47, 1, 149760, 0x3847adb4
+0, 48, 48, 1, 149760, 0xa4d589db
+0, 49, 49, 1, 149760, 0x9c50dd88
+0, 50, 50, 1, 149760, 0xad087c44
+0, 51, 51, 1, 149760, 0x4a6b656d
+0, 52, 52, 1, 149760, 0x6ec79bcf
+0, 53, 53, 1, 149760, 0x82756cb6
+0, 54, 54, 1, 149760, 0x8b3a9a6a
+0, 55, 55, 1, 149760, 0x775c0430
+0, 56, 56, 1, 149760, 0xbaa08d27
+0, 57, 57, 1, 149760, 0x686cd03f
+0, 58, 58, 1, 149760, 0x1b10dc94
+0, 59, 59, 1, 149760, 0xde81e414
diff --git a/tests/ref/fate/hevc-conformance-SAO_E_Canon_4 b/tests/ref/fate/hevc-conformance-SAO_E_Canon_4
new file mode 100644
index 0000000..92aa7f4
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-SAO_E_Canon_4
@@ -0,0 +1,17 @@
+#tb 0: 1/25
+0, 0, 0, 1, 149760, 0x1613b277
+0, 1, 1, 1, 149760, 0xf92d5543
+0, 2, 2, 1, 149760, 0xf119ba8e
+0, 3, 3, 1, 149760, 0xbce35d0a
+0, 4, 4, 1, 149760, 0x0f4dc325
+0, 5, 5, 1, 149760, 0xc95379ae
+0, 6, 6, 1, 149760, 0xbf4e9b84
+0, 7, 7, 1, 149760, 0x3a7c3cdf
+0, 8, 8, 1, 149760, 0x8d5e8895
+0, 9, 9, 1, 149760, 0x3128397e
+0, 10, 10, 1, 149760, 0x4389dee6
+0, 11, 11, 1, 149760, 0x8a6a7236
+0, 12, 12, 1, 149760, 0x638049ef
+0, 13, 13, 1, 149760, 0x0075da54
+0, 14, 14, 1, 149760, 0x5fd84a25
+0, 15, 15, 1, 149760, 0xfbd4af2b
diff --git a/tests/ref/fate/hevc-conformance-SAO_F_Canon_3 b/tests/ref/fate/hevc-conformance-SAO_F_Canon_3
new file mode 100644
index 0000000..cf24055
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-SAO_F_Canon_3
@@ -0,0 +1,17 @@
+#tb 0: 1/25
+0, 0, 0, 1, 149760, 0x92b5107a
+0, 1, 1, 1, 149760, 0x97eb31ef
+0, 2, 2, 1, 149760, 0xeb743e30
+0, 3, 3, 1, 149760, 0x5fc53434
+0, 4, 4, 1, 149760, 0x75fb1d63
+0, 5, 5, 1, 149760, 0xba0aeb27
+0, 6, 6, 1, 149760, 0x3f0f1780
+0, 7, 7, 1, 149760, 0xf5d0f052
+0, 8, 8, 1, 149760, 0x598ee54e
+0, 9, 9, 1, 149760, 0x09fcf908
+0, 10, 10, 1, 149760, 0x68209041
+0, 11, 11, 1, 149760, 0x05f519e9
+0, 12, 12, 1, 149760, 0xfdecf9b3
+0, 13, 13, 1, 149760, 0x40c96df8
+0, 14, 14, 1, 149760, 0x4b3d1b7b
+0, 15, 15, 1, 149760, 0xc0691cd9
diff --git a/tests/ref/fate/hevc-conformance-SAO_G_Canon_3 b/tests/ref/fate/hevc-conformance-SAO_G_Canon_3
new file mode 100644
index 0000000..5ce6772
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-SAO_G_Canon_3
@@ -0,0 +1,17 @@
+#tb 0: 1/25
+0, 0, 0, 1, 149760, 0xc4f239e0
+0, 1, 1, 1, 149760, 0xf57a2e44
+0, 2, 2, 1, 149760, 0xbf1e9995
+0, 3, 3, 1, 149760, 0x5fa25087
+0, 4, 4, 1, 149760, 0x709b4c3f
+0, 5, 5, 1, 149760, 0x63abbd5c
+0, 6, 6, 1, 149760, 0xbd87092a
+0, 7, 7, 1, 149760, 0x59156f4a
+0, 8, 8, 1, 149760, 0xf8ed7d88
+0, 9, 9, 1, 149760, 0xdac1cecf
+0, 10, 10, 1, 149760, 0x7ba3b408
+0, 11, 11, 1, 149760, 0xad4bd5f5
+0, 12, 12, 1, 149760, 0x4b1f83c6
+0, 13, 13, 1, 149760, 0x7329797f
+0, 14, 14, 1, 149760, 0x1d201f16
+0, 15, 15, 1, 149760, 0xde263a30
diff --git a/tests/ref/fate/hevc-conformance-SDH_A_Orange_3 b/tests/ref/fate/hevc-conformance-SDH_A_Orange_3
new file mode 100644
index 0000000..caf90ee
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-SDH_A_Orange_3
@@ -0,0 +1,3 @@
+#tb 0: 1/25
+0, 0, 0, 1, 3110400, 0x0117aa5d
+0, 1, 1, 1, 3110400, 0xa737bc56
diff --git a/tests/ref/fate/hevc-conformance-SLICES_A_Rovi_3 b/tests/ref/fate/hevc-conformance-SLICES_A_Rovi_3
new file mode 100644
index 0000000..f884f7f
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-SLICES_A_Rovi_3
@@ -0,0 +1,10 @@
+#tb 0: 1/25
+0, 0, 0, 1, 460800, 0x7f06cb02
+0, 1, 1, 1, 460800, 0x1ad483aa
+0, 2, 2, 1, 460800, 0x1bbbc991
+0, 3, 3, 1, 460800, 0x8fe7afa5
+0, 4, 4, 1, 460800, 0xe609cb0b
+0, 5, 5, 1, 460800, 0xcc65fec8
+0, 6, 6, 1, 460800, 0xa0601519
+0, 7, 7, 1, 460800, 0x8b0d3002
+0, 8, 8, 1, 460800, 0x7b1191af
diff --git a/tests/ref/fate/hevc-conformance-SLIST_A_Sony_4 b/tests/ref/fate/hevc-conformance-SLIST_A_Sony_4
new file mode 100644
index 0000000..ebb65c3
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-SLIST_A_Sony_4
@@ -0,0 +1,66 @@
+#tb 0: 1/25
+0, 0, 0, 1, 599040, 0xbd0eb43e
+0, 1, 1, 1, 599040, 0x4c3a98b5
+0, 2, 2, 1, 599040, 0x105410dc
+0, 3, 3, 1, 599040, 0xffaff69c
+0, 4, 4, 1, 599040, 0x39cb22ea
+0, 5, 5, 1, 599040, 0xa19296c3
+0, 6, 6, 1, 599040, 0x84cad39d
+0, 7, 7, 1, 599040, 0x5dc5c5a9
+0, 8, 8, 1, 599040, 0xc6a2c0dd
+0, 9, 9, 1, 599040, 0xeb5947bf
+0, 10, 10, 1, 599040, 0x9f8f9ce5
+0, 11, 11, 1, 599040, 0xdce5be4e
+0, 12, 12, 1, 599040, 0x07141c84
+0, 13, 13, 1, 599040, 0x3a05273d
+0, 14, 14, 1, 599040, 0xa16a112c
+0, 15, 15, 1, 599040, 0x6fa79123
+0, 16, 16, 1, 599040, 0xbda4cf46
+0, 17, 17, 1, 599040, 0xa5a81a05
+0, 18, 18, 1, 599040, 0x7370af29
+0, 19, 19, 1, 599040, 0xbd70e89e
+0, 20, 20, 1, 599040, 0xe7850613
+0, 21, 21, 1, 599040, 0xfaa8cf89
+0, 22, 22, 1, 599040, 0x30a78a21
+0, 23, 23, 1, 599040, 0x5520a8cf
+0, 24, 24, 1, 599040, 0xbcd93ea7
+0, 25, 25, 1, 599040, 0xd8ce632c
+0, 26, 26, 1, 599040, 0x87c6476f
+0, 27, 27, 1, 599040, 0xf6799dcc
+0, 28, 28, 1, 599040, 0xc0370664
+0, 29, 29, 1, 599040, 0x17196bd3
+0, 30, 30, 1, 599040, 0xe7ae6de3
+0, 31, 31, 1, 599040, 0x0345bc72
+0, 32, 32, 1, 599040, 0x7b86141e
+0, 33, 33, 1, 599040, 0x65564792
+0, 34, 34, 1, 599040, 0xf90c7f54
+0, 35, 35, 1, 599040, 0x00ce2f3c
+0, 36, 36, 1, 599040, 0xe6b185f2
+0, 37, 37, 1, 599040, 0x513942f1
+0, 38, 38, 1, 599040, 0x7c27b03a
+0, 39, 39, 1, 599040, 0xa201fea3
+0, 40, 40, 1, 599040, 0x5023fd92
+0, 41, 41, 1, 599040, 0xe05ba218
+0, 42, 42, 1, 599040, 0x84b61765
+0, 43, 43, 1, 599040, 0xfa6c8f65
+0, 44, 44, 1, 599040, 0xede8ef78
+0, 45, 45, 1, 599040, 0xcd2763f2
+0, 46, 46, 1, 599040, 0xb83e3bc6
+0, 47, 47, 1, 599040, 0x99fb3a3e
+0, 48, 48, 1, 599040, 0x3dd1e5ac
+0, 49, 49, 1, 599040, 0x776d7464
+0, 50, 50, 1, 599040, 0xaea89891
+0, 51, 51, 1, 599040, 0xfc0f1ec9
+0, 52, 52, 1, 599040, 0x2621f36f
+0, 53, 53, 1, 599040, 0x41101bbc
+0, 54, 54, 1, 599040, 0x7a5d4d0e
+0, 55, 55, 1, 599040, 0xc04fb148
+0, 56, 56, 1, 599040, 0x889d8186
+0, 57, 57, 1, 599040, 0x26f091bf
+0, 58, 58, 1, 599040, 0xe6644a2d
+0, 59, 59, 1, 599040, 0xd48efb7f
+0, 60, 60, 1, 599040, 0xe25204e3
+0, 61, 61, 1, 599040, 0x928f2efd
+0, 62, 62, 1, 599040, 0x535a4f2d
+0, 63, 63, 1, 599040, 0x2672ad63
+0, 64, 64, 1, 599040, 0x194f1463
diff --git a/tests/ref/fate/hevc-conformance-SLIST_B_Sony_8 b/tests/ref/fate/hevc-conformance-SLIST_B_Sony_8
new file mode 100644
index 0000000..fc39039
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-SLIST_B_Sony_8
@@ -0,0 +1,66 @@
+#tb 0: 1/25
+0, 0, 0, 1, 599040, 0xbd0eb43e
+0, 1, 1, 1, 599040, 0x3ea696c4
+0, 2, 2, 1, 599040, 0x866beffc
+0, 3, 3, 1, 599040, 0x89622860
+0, 4, 4, 1, 599040, 0x416bcaf8
+0, 5, 5, 1, 599040, 0x4098709b
+0, 6, 6, 1, 599040, 0x8d1ef343
+0, 7, 7, 1, 599040, 0xbd1bbc79
+0, 8, 8, 1, 599040, 0xc6a2c0dd
+0, 9, 9, 1, 599040, 0x438cc40e
+0, 10, 10, 1, 599040, 0xb666a438
+0, 11, 11, 1, 599040, 0x114580e4
+0, 12, 12, 1, 599040, 0xb75c41dc
+0, 13, 13, 1, 599040, 0x52e1e32f
+0, 14, 14, 1, 599040, 0x22835865
+0, 15, 15, 1, 599040, 0xfb0e0003
+0, 16, 16, 1, 599040, 0xebcb1ef9
+0, 17, 17, 1, 599040, 0xd6939619
+0, 18, 18, 1, 599040, 0xe22afdd8
+0, 19, 19, 1, 599040, 0xff4a248f
+0, 20, 20, 1, 599040, 0x9fc3878e
+0, 21, 21, 1, 599040, 0xce2f6499
+0, 22, 22, 1, 599040, 0x04aa9986
+0, 23, 23, 1, 599040, 0x68ba9838
+0, 24, 24, 1, 599040, 0x62e950a9
+0, 25, 25, 1, 599040, 0x5161526d
+0, 26, 26, 1, 599040, 0xcdde709e
+0, 27, 27, 1, 599040, 0x8c48ded1
+0, 28, 28, 1, 599040, 0x3451ecbb
+0, 29, 29, 1, 599040, 0xfc5a5fca
+0, 30, 30, 1, 599040, 0x7c0090fe
+0, 31, 31, 1, 599040, 0xbc4eb1de
+0, 32, 32, 1, 599040, 0x5350cf4f
+0, 33, 33, 1, 599040, 0x175152d6
+0, 34, 34, 1, 599040, 0xcf65acea
+0, 35, 35, 1, 599040, 0x099a7298
+0, 36, 36, 1, 599040, 0x31b7a2a2
+0, 37, 37, 1, 599040, 0xd6a71415
+0, 38, 38, 1, 599040, 0xe68880e7
+0, 39, 39, 1, 599040, 0x0c7d0373
+0, 40, 40, 1, 599040, 0xfb56ac78
+0, 41, 41, 1, 599040, 0x1177b0dd
+0, 42, 42, 1, 599040, 0x1393026f
+0, 43, 43, 1, 599040, 0xc6346b58
+0, 44, 44, 1, 599040, 0x2949cd11
+0, 45, 45, 1, 599040, 0xff867f22
+0, 46, 46, 1, 599040, 0xef196e4d
+0, 47, 47, 1, 599040, 0x17a2332c
+0, 48, 48, 1, 599040, 0x45d59fbc
+0, 49, 49, 1, 599040, 0x5f51575c
+0, 50, 50, 1, 599040, 0x6049a451
+0, 51, 51, 1, 599040, 0x4d6086ac
+0, 52, 52, 1, 599040, 0xd709596b
+0, 53, 53, 1, 599040, 0xacdbc22f
+0, 54, 54, 1, 599040, 0x45c11bb5
+0, 55, 55, 1, 599040, 0x608a7c7e
+0, 56, 56, 1, 599040, 0x242a67c9
+0, 57, 57, 1, 599040, 0x2d186d8a
+0, 58, 58, 1, 599040, 0x07ed9fd5
+0, 59, 59, 1, 599040, 0xaee9a49b
+0, 60, 60, 1, 599040, 0xaeb2b2a2
+0, 61, 61, 1, 599040, 0x4ca2d84b
+0, 62, 62, 1, 599040, 0x4254b5f6
+0, 63, 63, 1, 599040, 0x105c7a25
+0, 64, 64, 1, 599040, 0x87b51bce
diff --git a/tests/ref/fate/hevc-conformance-SLIST_C_Sony_3 b/tests/ref/fate/hevc-conformance-SLIST_C_Sony_3
new file mode 100644
index 0000000..482e56f
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-SLIST_C_Sony_3
@@ -0,0 +1,66 @@
+#tb 0: 1/25
+0, 0, 0, 1, 599040, 0xc3e98658
+0, 1, 1, 1, 599040, 0x621fa0b7
+0, 2, 2, 1, 599040, 0x53b2e637
+0, 3, 3, 1, 599040, 0x1db118c2
+0, 4, 4, 1, 599040, 0xa25003ba
+0, 5, 5, 1, 599040, 0x51de524b
+0, 6, 6, 1, 599040, 0x5f01f648
+0, 7, 7, 1, 599040, 0x43d8c9cb
+0, 8, 8, 1, 599040, 0xf7f6c7f6
+0, 9, 9, 1, 599040, 0xb08885ec
+0, 10, 10, 1, 599040, 0x1e6e91a7
+0, 11, 11, 1, 599040, 0x18549abd
+0, 12, 12, 1, 599040, 0xef523cbc
+0, 13, 13, 1, 599040, 0x87985e99
+0, 14, 14, 1, 599040, 0x37521482
+0, 15, 15, 1, 599040, 0xe9fbc0ce
+0, 16, 16, 1, 599040, 0x20bab233
+0, 17, 17, 1, 599040, 0xbe3525e6
+0, 18, 18, 1, 599040, 0xace46e50
+0, 19, 19, 1, 599040, 0xf709b3a9
+0, 20, 20, 1, 599040, 0xf2690bc8
+0, 21, 21, 1, 599040, 0x7eacdec3
+0, 22, 22, 1, 599040, 0xaed66c65
+0, 23, 23, 1, 599040, 0x066b2fa6
+0, 24, 24, 1, 599040, 0x5dc050bd
+0, 25, 25, 1, 599040, 0x170e7de1
+0, 26, 26, 1, 599040, 0x2ccd7b16
+0, 27, 27, 1, 599040, 0x4f7bc972
+0, 28, 28, 1, 599040, 0x72d7f274
+0, 29, 29, 1, 599040, 0x44d2396e
+0, 30, 30, 1, 599040, 0xe4dc9b54
+0, 31, 31, 1, 599040, 0xfacba54d
+0, 32, 32, 1, 599040, 0x7b86141e
+0, 33, 33, 1, 599040, 0x65564792
+0, 34, 34, 1, 599040, 0xf90c7f54
+0, 35, 35, 1, 599040, 0x00ce2f3c
+0, 36, 36, 1, 599040, 0xe6b185f2
+0, 37, 37, 1, 599040, 0x513942f1
+0, 38, 38, 1, 599040, 0x7c27b03a
+0, 39, 39, 1, 599040, 0xa201fea3
+0, 40, 40, 1, 599040, 0x5023fd92
+0, 41, 41, 1, 599040, 0xe05ba218
+0, 42, 42, 1, 599040, 0x84b61765
+0, 43, 43, 1, 599040, 0xfa6c8f65
+0, 44, 44, 1, 599040, 0xede8ef78
+0, 45, 45, 1, 599040, 0xcd2763f2
+0, 46, 46, 1, 599040, 0xb83e3bc6
+0, 47, 47, 1, 599040, 0x99fb3a3e
+0, 48, 48, 1, 599040, 0x3dd1e5ac
+0, 49, 49, 1, 599040, 0x776d7464
+0, 50, 50, 1, 599040, 0xaea89891
+0, 51, 51, 1, 599040, 0xfc0f1ec9
+0, 52, 52, 1, 599040, 0x2621f36f
+0, 53, 53, 1, 599040, 0x41101bbc
+0, 54, 54, 1, 599040, 0x7a5d4d0e
+0, 55, 55, 1, 599040, 0xc04fb148
+0, 56, 56, 1, 599040, 0x889d8186
+0, 57, 57, 1, 599040, 0x26f091bf
+0, 58, 58, 1, 599040, 0xe6644a2d
+0, 59, 59, 1, 599040, 0xd48efb7f
+0, 60, 60, 1, 599040, 0xe25204e3
+0, 61, 61, 1, 599040, 0x928f2efd
+0, 62, 62, 1, 599040, 0x535a4f2d
+0, 63, 63, 1, 599040, 0x2672ad63
+0, 64, 64, 1, 599040, 0x194f1463
diff --git a/tests/ref/fate/hevc-conformance-SLIST_D_Sony_9 b/tests/ref/fate/hevc-conformance-SLIST_D_Sony_9
new file mode 100644
index 0000000..384f81f
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-SLIST_D_Sony_9
@@ -0,0 +1,66 @@
+#tb 0: 1/25
+0, 0, 0, 1, 599040, 0xf3038515
+0, 1, 1, 1, 599040, 0xb1bc9386
+0, 2, 2, 1, 599040, 0xa069e86f
+0, 3, 3, 1, 599040, 0xdf7c4cb7
+0, 4, 4, 1, 599040, 0xefaa2ac5
+0, 5, 5, 1, 599040, 0x81c67c18
+0, 6, 6, 1, 599040, 0xeb1a0669
+0, 7, 7, 1, 599040, 0xbab3c0b8
+0, 8, 8, 1, 599040, 0x82b99936
+0, 9, 9, 1, 599040, 0x027a90d1
+0, 10, 10, 1, 599040, 0x5d6d7489
+0, 11, 11, 1, 599040, 0xeaaf6d39
+0, 12, 12, 1, 599040, 0x7788f8fa
+0, 13, 13, 1, 599040, 0x654393e8
+0, 14, 14, 1, 599040, 0xc6c2237c
+0, 15, 15, 1, 599040, 0x8b16d890
+0, 16, 16, 1, 599040, 0x2c36eed0
+0, 17, 17, 1, 599040, 0x02792aa8
+0, 18, 18, 1, 599040, 0xf4088e47
+0, 19, 19, 1, 599040, 0xea9796ad
+0, 20, 20, 1, 599040, 0xa4aecc01
+0, 21, 21, 1, 599040, 0x2ec8c1c4
+0, 22, 22, 1, 599040, 0xcfa87d49
+0, 23, 23, 1, 599040, 0x012b62f1
+0, 24, 24, 1, 599040, 0xd8b72ae0
+0, 25, 25, 1, 599040, 0xe0ca1977
+0, 26, 26, 1, 599040, 0x3f048981
+0, 27, 27, 1, 599040, 0xe416a928
+0, 28, 28, 1, 599040, 0xdfef9086
+0, 29, 29, 1, 599040, 0xd810cd6a
+0, 30, 30, 1, 599040, 0x11fab789
+0, 31, 31, 1, 599040, 0x90a890d5
+0, 32, 32, 1, 599040, 0x0dabef8d
+0, 33, 33, 1, 599040, 0x7a32557d
+0, 34, 34, 1, 599040, 0xc3427914
+0, 35, 35, 1, 599040, 0x65266a45
+0, 36, 36, 1, 599040, 0x8b5e9213
+0, 37, 37, 1, 599040, 0x4e2e2b0a
+0, 38, 38, 1, 599040, 0xaebdb406
+0, 39, 39, 1, 599040, 0xca35eadb
+0, 40, 40, 1, 599040, 0xb711adc7
+0, 41, 41, 1, 599040, 0x594d28b9
+0, 42, 42, 1, 599040, 0x27fec3c9
+0, 43, 43, 1, 599040, 0x35fe73ce
+0, 44, 44, 1, 599040, 0x3069c845
+0, 45, 45, 1, 599040, 0x2df2a12d
+0, 46, 46, 1, 599040, 0x96d42f5c
+0, 47, 47, 1, 599040, 0x95d9319b
+0, 48, 48, 1, 599040, 0x4f8c92aa
+0, 49, 49, 1, 599040, 0x29620b31
+0, 50, 50, 1, 599040, 0x3d1441f7
+0, 51, 51, 1, 599040, 0x7040914d
+0, 52, 52, 1, 599040, 0x95a73274
+0, 53, 53, 1, 599040, 0xda51c6c7
+0, 54, 54, 1, 599040, 0x41592676
+0, 55, 55, 1, 599040, 0xf21c682b
+0, 56, 56, 1, 599040, 0x5d6b65cf
+0, 57, 57, 1, 599040, 0x13fc6e8e
+0, 58, 58, 1, 599040, 0xe05ec001
+0, 59, 59, 1, 599040, 0x06113d89
+0, 60, 60, 1, 599040, 0x1d74bd0d
+0, 61, 61, 1, 599040, 0x757ffab3
+0, 62, 62, 1, 599040, 0x0599c7fb
+0, 63, 63, 1, 599040, 0x8aaa91ed
+0, 64, 64, 1, 599040, 0x79582f08
diff --git a/tests/ref/fate/hevc-conformance-STRUCT_A_Samsung_5 b/tests/ref/fate/hevc-conformance-STRUCT_A_Samsung_5
new file mode 100644
index 0000000..da5cfa1
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-STRUCT_A_Samsung_5
@@ -0,0 +1,61 @@
+#tb 0: 1/25
+0, 0, 0, 1, 149760, 0x479fa7ca
+0, 1, 1, 1, 149760, 0x761fb3a3
+0, 2, 2, 1, 149760, 0xa0f4cd97
+0, 3, 3, 1, 149760, 0x22a0c92b
+0, 4, 4, 1, 149760, 0xdedc8cb2
+0, 5, 5, 1, 149760, 0x38da8674
+0, 6, 6, 1, 149760, 0xe5d77e68
+0, 7, 7, 1, 149760, 0x31cc6196
+0, 8, 8, 1, 149760, 0xdb70f4d3
+0, 9, 9, 1, 149760, 0x966b6f89
+0, 10, 10, 1, 149760, 0x2297ff66
+0, 11, 11, 1, 149760, 0x2a2fa4e7
+0, 12, 12, 1, 149760, 0x217442b7
+0, 13, 13, 1, 149760, 0x5341ff7f
+0, 14, 14, 1, 149760, 0xb413af37
+0, 15, 15, 1, 149760, 0x61c86ce5
+0, 16, 16, 1, 149760, 0x6b1a0c63
+0, 17, 17, 1, 149760, 0x4596d2e5
+0, 18, 18, 1, 149760, 0xafc0abbd
+0, 19, 19, 1, 149760, 0xb9197a81
+0, 20, 20, 1, 149760, 0xf67d43f3
+0, 21, 21, 1, 149760, 0xe7ef11f2
+0, 22, 22, 1, 149760, 0x89180592
+0, 23, 23, 1, 149760, 0xf6900816
+0, 24, 24, 1, 149760, 0x7cb2f3c0
+0, 25, 25, 1, 149760, 0x71c269f5
+0, 26, 26, 1, 149760, 0x19720666
+0, 27, 27, 1, 149760, 0x5794f402
+0, 28, 28, 1, 149760, 0xe08bf8d2
+0, 29, 29, 1, 149760, 0x11638859
+0, 30, 30, 1, 149760, 0x5024fddc
+0, 31, 31, 1, 149760, 0x8b3d4a37
+0, 32, 32, 1, 149760, 0x5f727144
+0, 33, 33, 1, 149760, 0xb6cf2d76
+0, 34, 34, 1, 149760, 0xf528b070
+0, 35, 35, 1, 149760, 0x3e95f116
+0, 36, 36, 1, 149760, 0x1db5f92a
+0, 37, 37, 1, 149760, 0xf8331667
+0, 38, 38, 1, 149760, 0x57ca4161
+0, 39, 39, 1, 149760, 0x7add32bd
+0, 40, 40, 1, 149760, 0x4b84af44
+0, 41, 41, 1, 149760, 0xf3e1eeaf
+0, 42, 42, 1, 149760, 0x0d602ea8
+0, 43, 43, 1, 149760, 0x420bfdf8
+0, 44, 44, 1, 149760, 0x6e2eb72f
+0, 45, 45, 1, 149760, 0x0450e4ba
+0, 46, 46, 1, 149760, 0xbfa60971
+0, 47, 47, 1, 149760, 0x89791529
+0, 48, 48, 1, 149760, 0x4e32e37b
+0, 49, 49, 1, 149760, 0x273f0927
+0, 50, 50, 1, 149760, 0x0373f961
+0, 51, 51, 1, 149760, 0x5f105bd2
+0, 52, 52, 1, 149760, 0x6b1b290a
+0, 53, 53, 1, 149760, 0xeaad4ccb
+0, 54, 54, 1, 149760, 0xeb21c2e6
+0, 55, 55, 1, 149760, 0x342ff483
+0, 56, 56, 1, 149760, 0x0ac70398
+0, 57, 57, 1, 149760, 0x5366fd7c
+0, 58, 58, 1, 149760, 0xc05249b6
+0, 59, 59, 1, 149760, 0x32279e70
diff --git a/tests/ref/fate/hevc-conformance-STRUCT_B_Samsung_4 b/tests/ref/fate/hevc-conformance-STRUCT_B_Samsung_4
new file mode 100644
index 0000000..c03111c
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-STRUCT_B_Samsung_4
@@ -0,0 +1,61 @@
+#tb 0: 1/25
+0, 0, 0, 1, 599040, 0x4b489a60
+0, 1, 1, 1, 599040, 0x80369c9a
+0, 2, 2, 1, 599040, 0x33189b1a
+0, 3, 3, 1, 599040, 0x01d73abb
+0, 4, 4, 1, 599040, 0xd5de0ab7
+0, 5, 5, 1, 599040, 0xf7b9f1c3
+0, 6, 6, 1, 599040, 0xe72b6446
+0, 7, 7, 1, 599040, 0xf78cc5d6
+0, 8, 8, 1, 599040, 0x9c6d33a2
+0, 9, 9, 1, 599040, 0xacb6cb08
+0, 10, 10, 1, 599040, 0x2a215019
+0, 11, 11, 1, 599040, 0xcd89d5be
+0, 12, 12, 1, 599040, 0x60403ebb
+0, 13, 13, 1, 599040, 0xc5c62e88
+0, 14, 14, 1, 599040, 0x93403d23
+0, 15, 15, 1, 599040, 0x6b86071d
+0, 16, 16, 1, 599040, 0xfaaad32f
+0, 17, 17, 1, 599040, 0x68651db5
+0, 18, 18, 1, 599040, 0xfbedeba6
+0, 19, 19, 1, 599040, 0x7fa3a0c0
+0, 20, 20, 1, 599040, 0x76b34545
+0, 21, 21, 1, 599040, 0x34e4c1cd
+0, 22, 22, 1, 599040, 0xfad3eda9
+0, 23, 23, 1, 599040, 0xf4324901
+0, 24, 24, 1, 599040, 0x991b4fde
+0, 25, 25, 1, 599040, 0xd9d7823d
+0, 26, 26, 1, 599040, 0xd8a80ca5
+0, 27, 27, 1, 599040, 0x19ae0251
+0, 28, 28, 1, 599040, 0xfa68cda7
+0, 29, 29, 1, 599040, 0xb9c72f07
+0, 30, 30, 1, 599040, 0xf1df5f78
+0, 31, 31, 1, 599040, 0xda75192b
+0, 32, 32, 1, 599040, 0x1102b6e6
+0, 33, 33, 1, 599040, 0x259ec490
+0, 34, 34, 1, 599040, 0xee1dabe5
+0, 35, 35, 1, 599040, 0xf6bf5454
+0, 36, 36, 1, 599040, 0x058061be
+0, 37, 37, 1, 599040, 0x2f9aebeb
+0, 38, 38, 1, 599040, 0x169c0bff
+0, 39, 39, 1, 599040, 0xeffb5a9f
+0, 40, 40, 1, 599040, 0xb3bbebac
+0, 41, 41, 1, 599040, 0x174af746
+0, 42, 42, 1, 599040, 0x8359db57
+0, 43, 43, 1, 599040, 0xdd7693ad
+0, 44, 44, 1, 599040, 0x05aebad4
+0, 45, 45, 1, 599040, 0xc34fd8bc
+0, 46, 46, 1, 599040, 0x2798f32e
+0, 47, 47, 1, 599040, 0x319b9b8c
+0, 48, 48, 1, 599040, 0xa28d783f
+0, 49, 49, 1, 599040, 0x5c79026f
+0, 50, 50, 1, 599040, 0xd4ae9b08
+0, 51, 51, 1, 599040, 0x79b19064
+0, 52, 52, 1, 599040, 0xe773bd75
+0, 53, 53, 1, 599040, 0xfbeda52a
+0, 54, 54, 1, 599040, 0x2ed916e6
+0, 55, 55, 1, 599040, 0xd3243fe7
+0, 56, 56, 1, 599040, 0xfdbc20e8
+0, 57, 57, 1, 599040, 0x80983226
+0, 58, 58, 1, 599040, 0x51c66b23
+0, 59, 59, 1, 599040, 0x30816b80
diff --git a/tests/ref/fate/hevc-conformance-TILES_A_Cisco_2 b/tests/ref/fate/hevc-conformance-TILES_A_Cisco_2
new file mode 100644
index 0000000..63c9722
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-TILES_A_Cisco_2
@@ -0,0 +1,101 @@
+#tb 0: 1/25
+0, 0, 0, 1, 3110400, 0xfc052e85
+0, 1, 1, 1, 3110400, 0xfb49bf20
+0, 2, 2, 1, 3110400, 0x549eef2b
+0, 3, 3, 1, 3110400, 0xc3857801
+0, 4, 4, 1, 3110400, 0xb27d6aea
+0, 5, 5, 1, 3110400, 0xa52e1d58
+0, 6, 6, 1, 3110400, 0x02d348e6
+0, 7, 7, 1, 3110400, 0x45a9c47c
+0, 8, 8, 1, 3110400, 0xc308e886
+0, 9, 9, 1, 3110400, 0x43cd6ed6
+0, 10, 10, 1, 3110400, 0x29a054ce
+0, 11, 11, 1, 3110400, 0x76fbd08e
+0, 12, 12, 1, 3110400, 0x8638d5e2
+0, 13, 13, 1, 3110400, 0xfb4b7823
+0, 14, 14, 1, 3110400, 0x66185e15
+0, 15, 15, 1, 3110400, 0x82eaea0a
+0, 16, 16, 1, 3110400, 0x5895f1c6
+0, 17, 17, 1, 3110400, 0x0a28a1c7
+0, 18, 18, 1, 3110400, 0x37f2ecc8
+0, 19, 19, 1, 3110400, 0x0ad8b6c1
+0, 20, 20, 1, 3110400, 0x90300dcb
+0, 21, 21, 1, 3110400, 0x9731112d
+0, 22, 22, 1, 3110400, 0x5078ba88
+0, 23, 23, 1, 3110400, 0xdcfbacae
+0, 24, 24, 1, 3110400, 0x40769123
+0, 25, 25, 1, 3110400, 0xa09f4d29
+0, 26, 26, 1, 3110400, 0xa3749feb
+0, 27, 27, 1, 3110400, 0xb04c36ae
+0, 28, 28, 1, 3110400, 0x4d30c177
+0, 29, 29, 1, 3110400, 0xe247070a
+0, 30, 30, 1, 3110400, 0x84c669d5
+0, 31, 31, 1, 3110400, 0x3e0529e6
+0, 32, 32, 1, 3110400, 0xd0d58b7a
+0, 33, 33, 1, 3110400, 0x05de0ffa
+0, 34, 34, 1, 3110400, 0x7d10a27f
+0, 35, 35, 1, 3110400, 0x87dd43fe
+0, 36, 36, 1, 3110400, 0xc6f39e98
+0, 37, 37, 1, 3110400, 0x9bf5a18b
+0, 38, 38, 1, 3110400, 0x4880f4e6
+0, 39, 39, 1, 3110400, 0xbba7a2fd
+0, 40, 40, 1, 3110400, 0x82fe2a14
+0, 41, 41, 1, 3110400, 0x7e701e1c
+0, 42, 42, 1, 3110400, 0x23cdbc0c
+0, 43, 43, 1, 3110400, 0xf15977e6
+0, 44, 44, 1, 3110400, 0x50df6fe2
+0, 45, 45, 1, 3110400, 0x8913ddde
+0, 46, 46, 1, 3110400, 0x633c8c0e
+0, 47, 47, 1, 3110400, 0xea604347
+0, 48, 48, 1, 3110400, 0xa5049365
+0, 49, 49, 1, 3110400, 0x35da77a8
+0, 50, 50, 1, 3110400, 0xcfa4af57
+0, 51, 51, 1, 3110400, 0x5a3bfe64
+0, 52, 52, 1, 3110400, 0x91f9ee34
+0, 53, 53, 1, 3110400, 0x21b0df73
+0, 54, 54, 1, 3110400, 0x7807baf2
+0, 55, 55, 1, 3110400, 0x96dbaf03
+0, 56, 56, 1, 3110400, 0xb8d29f57
+0, 57, 57, 1, 3110400, 0x1a04f732
+0, 58, 58, 1, 3110400, 0x54a34b35
+0, 59, 59, 1, 3110400, 0x4850a07a
+0, 60, 60, 1, 3110400, 0x7010be29
+0, 61, 61, 1, 3110400, 0x7178d2e7
+0, 62, 62, 1, 3110400, 0x17483898
+0, 63, 63, 1, 3110400, 0x4c55872a
+0, 64, 64, 1, 3110400, 0xe67b0f06
+0, 65, 65, 1, 3110400, 0x958789cf
+0, 66, 66, 1, 3110400, 0x5cd6ba06
+0, 67, 67, 1, 3110400, 0xb7852fe2
+0, 68, 68, 1, 3110400, 0x8b67bd9f
+0, 69, 69, 1, 3110400, 0x9555c0ff
+0, 70, 70, 1, 3110400, 0x6b99aab7
+0, 71, 71, 1, 3110400, 0xcab904b7
+0, 72, 72, 1, 3110400, 0xeb915c25
+0, 73, 73, 1, 3110400, 0xd3066bd8
+0, 74, 74, 1, 3110400, 0xa2d45cb5
+0, 75, 75, 1, 3110400, 0x011db978
+0, 76, 76, 1, 3110400, 0xf35b9f2c
+0, 77, 77, 1, 3110400, 0x6afd3bde
+0, 78, 78, 1, 3110400, 0xa1ad77b7
+0, 79, 79, 1, 3110400, 0x8b4d3823
+0, 80, 80, 1, 3110400, 0xd806be79
+0, 81, 81, 1, 3110400, 0x29dcff87
+0, 82, 82, 1, 3110400, 0x202fb0f7
+0, 83, 83, 1, 3110400, 0xacfc7d1d
+0, 84, 84, 1, 3110400, 0xf04bdcb8
+0, 85, 85, 1, 3110400, 0x89cef288
+0, 86, 86, 1, 3110400, 0x657315e2
+0, 87, 87, 1, 3110400, 0x1615cb5f
+0, 88, 88, 1, 3110400, 0xc6986395
+0, 89, 89, 1, 3110400, 0x6b77258e
+0, 90, 90, 1, 3110400, 0xcd9975ae
+0, 91, 91, 1, 3110400, 0x5044fd0f
+0, 92, 92, 1, 3110400, 0x20dd1132
+0, 93, 93, 1, 3110400, 0xdb5a0b84
+0, 94, 94, 1, 3110400, 0xf40d29ae
+0, 95, 95, 1, 3110400, 0xe88bffed
+0, 96, 96, 1, 3110400, 0x3e50146a
+0, 97, 97, 1, 3110400, 0xaacd9bfa
+0, 98, 98, 1, 3110400, 0x270b2c2a
+0, 99, 99, 1, 3110400, 0xc727f760
diff --git a/tests/ref/fate/hevc-conformance-TILES_B_Cisco_1 b/tests/ref/fate/hevc-conformance-TILES_B_Cisco_1
new file mode 100644
index 0000000..9c37121
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-TILES_B_Cisco_1
@@ -0,0 +1,101 @@
+#tb 0: 1/25
+0, 0, 0, 1, 3110400, 0x3471f473
+0, 1, 1, 1, 3110400, 0xb371a3e8
+0, 2, 2, 1, 3110400, 0x6d83c623
+0, 3, 3, 1, 3110400, 0x62d68b96
+0, 4, 4, 1, 3110400, 0xa8ed6ea9
+0, 5, 5, 1, 3110400, 0xcabe52be
+0, 6, 6, 1, 3110400, 0xbbb23578
+0, 7, 7, 1, 3110400, 0xb1609c77
+0, 8, 8, 1, 3110400, 0x61e7c2a7
+0, 9, 9, 1, 3110400, 0x6d8b34ad
+0, 10, 10, 1, 3110400, 0xde0dfa96
+0, 11, 11, 1, 3110400, 0x48c2b0b0
+0, 12, 12, 1, 3110400, 0x647b6f90
+0, 13, 13, 1, 3110400, 0xd37f2dda
+0, 14, 14, 1, 3110400, 0x1b0dd122
+0, 15, 15, 1, 3110400, 0x0b050786
+0, 16, 16, 1, 3110400, 0xcd9ce7e5
+0, 17, 17, 1, 3110400, 0xb92a4ee4
+0, 18, 18, 1, 3110400, 0x4fa4d97c
+0, 19, 19, 1, 3110400, 0x109777eb
+0, 20, 20, 1, 3110400, 0xc3d2236a
+0, 21, 21, 1, 3110400, 0x1cd12d07
+0, 22, 22, 1, 3110400, 0xdd1ef75d
+0, 23, 23, 1, 3110400, 0xd00c0906
+0, 24, 24, 1, 3110400, 0x8de79207
+0, 25, 25, 1, 3110400, 0x18017e1e
+0, 26, 26, 1, 3110400, 0x4329f68a
+0, 27, 27, 1, 3110400, 0x6a402bae
+0, 28, 28, 1, 3110400, 0x90eb1a20
+0, 29, 29, 1, 3110400, 0xe3474876
+0, 30, 30, 1, 3110400, 0xd652e216
+0, 31, 31, 1, 3110400, 0xeb458ebb
+0, 32, 32, 1, 3110400, 0xc5aff075
+0, 33, 33, 1, 3110400, 0xcb4d72e7
+0, 34, 34, 1, 3110400, 0x5504d9c5
+0, 35, 35, 1, 3110400, 0xcd0147b4
+0, 36, 36, 1, 3110400, 0xe2f0001e
+0, 37, 37, 1, 3110400, 0xa2199fe5
+0, 38, 38, 1, 3110400, 0x2f269683
+0, 39, 39, 1, 3110400, 0x7cf11244
+0, 40, 40, 1, 3110400, 0xf39cb39d
+0, 41, 41, 1, 3110400, 0x0e195a06
+0, 42, 42, 1, 3110400, 0x195e31e3
+0, 43, 43, 1, 3110400, 0xc43cd272
+0, 44, 44, 1, 3110400, 0x9dc1c4ea
+0, 45, 45, 1, 3110400, 0x846cd55f
+0, 46, 46, 1, 3110400, 0xe9468052
+0, 47, 47, 1, 3110400, 0xc5bb38ff
+0, 48, 48, 1, 3110400, 0xd1886697
+0, 49, 49, 1, 3110400, 0x23f2012b
+0, 50, 50, 1, 3110400, 0x669d63ff
+0, 51, 51, 1, 3110400, 0xced83804
+0, 52, 52, 1, 3110400, 0x005f5f3d
+0, 53, 53, 1, 3110400, 0x772efc80
+0, 54, 54, 1, 3110400, 0x94012838
+0, 55, 55, 1, 3110400, 0x99770054
+0, 56, 56, 1, 3110400, 0x8654c655
+0, 57, 57, 1, 3110400, 0xed3d19f4
+0, 58, 58, 1, 3110400, 0x8efc2172
+0, 59, 59, 1, 3110400, 0x9aaf930d
+0, 60, 60, 1, 3110400, 0xbe32f43e
+0, 61, 61, 1, 3110400, 0x6008f53e
+0, 62, 62, 1, 3110400, 0xb87897b9
+0, 63, 63, 1, 3110400, 0xe2406eb1
+0, 64, 64, 1, 3110400, 0xbdfa067b
+0, 65, 65, 1, 3110400, 0x82a16dbd
+0, 66, 66, 1, 3110400, 0x909aa5f0
+0, 67, 67, 1, 3110400, 0xc63836b5
+0, 68, 68, 1, 3110400, 0xaf7ad199
+0, 69, 69, 1, 3110400, 0xfa010078
+0, 70, 70, 1, 3110400, 0x00c0c24e
+0, 71, 71, 1, 3110400, 0xbda7cc4e
+0, 72, 72, 1, 3110400, 0xda97f9d5
+0, 73, 73, 1, 3110400, 0xd359e94a
+0, 74, 74, 1, 3110400, 0xcd48c131
+0, 75, 75, 1, 3110400, 0xb52ca032
+0, 76, 76, 1, 3110400, 0x55a69650
+0, 77, 77, 1, 3110400, 0x7241c1a9
+0, 78, 78, 1, 3110400, 0xf06c5744
+0, 79, 79, 1, 3110400, 0xe1befd73
+0, 80, 80, 1, 3110400, 0xe8ffea92
+0, 81, 81, 1, 3110400, 0xd76e40b6
+0, 82, 82, 1, 3110400, 0xbf5f5b4c
+0, 83, 83, 1, 3110400, 0x0eb8d128
+0, 84, 84, 1, 3110400, 0x453dd680
+0, 85, 85, 1, 3110400, 0x7114fada
+0, 86, 86, 1, 3110400, 0xa3b4e7a8
+0, 87, 87, 1, 3110400, 0xbca356f0
+0, 88, 88, 1, 3110400, 0x80a83fa3
+0, 89, 89, 1, 3110400, 0x713a33d4
+0, 90, 90, 1, 3110400, 0x4fda8aea
+0, 91, 91, 1, 3110400, 0x31ed1a88
+0, 92, 92, 1, 3110400, 0x736312a0
+0, 93, 93, 1, 3110400, 0x60aff0c5
+0, 94, 94, 1, 3110400, 0xee66bd76
+0, 95, 95, 1, 3110400, 0xe8f9a352
+0, 96, 96, 1, 3110400, 0xb51520de
+0, 97, 97, 1, 3110400, 0xd0542466
+0, 98, 98, 1, 3110400, 0x92c2f3e1
+0, 99, 99, 1, 3110400, 0xbbe1839a
diff --git a/tests/ref/fate/hevc-conformance-TMVP_A_MS_2 b/tests/ref/fate/hevc-conformance-TMVP_A_MS_2
new file mode 100644
index 0000000..a626af8
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-TMVP_A_MS_2
@@ -0,0 +1,18 @@
+#tb 0: 1/25
+0, 0, 0, 1, 149760, 0xdb5e3b56
+0, 1, 1, 1, 149760, 0x496f2a41
+0, 2, 2, 1, 149760, 0x0690ee0a
+0, 3, 3, 1, 149760, 0x5648fb4e
+0, 4, 4, 1, 149760, 0xd58bbe51
+0, 5, 5, 1, 149760, 0x647c4520
+0, 6, 6, 1, 149760, 0x0e361335
+0, 7, 7, 1, 149760, 0xd1a4289b
+0, 8, 8, 1, 149760, 0x04d29f74
+0, 9, 9, 1, 149760, 0x3bbffc55
+0, 10, 10, 1, 149760, 0xefe30f2b
+0, 11, 11, 1, 149760, 0x3a336f52
+0, 12, 12, 1, 149760, 0x0dffed51
+0, 13, 13, 1, 149760, 0x5a9db757
+0, 14, 14, 1, 149760, 0x5e7313c5
+0, 15, 15, 1, 149760, 0xbffb3a0e
+0, 16, 16, 1, 149760, 0x073966e9
diff --git a/tests/ref/fate/hevc-conformance-TSCL_A_VIDYO_5 b/tests/ref/fate/hevc-conformance-TSCL_A_VIDYO_5
new file mode 100644
index 0000000..84d4219
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-TSCL_A_VIDYO_5
@@ -0,0 +1,74 @@
+#tb 0: 1/25
+0, 0, 0, 1, 149760, 0xcfffa013
+0, 1, 1, 1, 149760, 0x5166146a
+0, 2, 2, 1, 149760, 0xc3cc318e
+0, 3, 3, 1, 149760, 0xcedf65a0
+0, 4, 4, 1, 149760, 0x10c97bd4
+0, 5, 5, 1, 149760, 0xd9d5c4ab
+0, 6, 6, 1, 149760, 0x5112e11d
+0, 7, 7, 1, 149760, 0xde3803d6
+0, 8, 8, 1, 149760, 0x82c62409
+0, 9, 9, 1, 149760, 0x69a587f2
+0, 10, 10, 1, 149760, 0x90e2ac16
+0, 11, 11, 1, 149760, 0xdc2ed2ba
+0, 12, 12, 1, 149760, 0xcabec51f
+0, 13, 13, 1, 149760, 0x915de948
+0, 14, 14, 1, 149760, 0xd824e422
+0, 15, 15, 1, 149760, 0x10f91769
+0, 16, 16, 1, 149760, 0xf8ea1f0a
+0, 17, 17, 1, 149760, 0x88306494
+0, 18, 18, 1, 149760, 0x4b667403
+0, 19, 19, 1, 149760, 0x190b939f
+0, 20, 20, 1, 149760, 0xe754929d
+0, 21, 21, 1, 149760, 0xdd1eb9b5
+0, 22, 22, 1, 149760, 0x5ef1c64b
+0, 23, 23, 1, 149760, 0xab92e9f9
+0, 24, 24, 1, 149760, 0x873fec38
+0, 25, 25, 1, 149760, 0x1f0ca11f
+0, 26, 26, 1, 149760, 0xa2f591ca
+0, 27, 27, 1, 149760, 0x2713a994
+0, 28, 28, 1, 149760, 0xfbdba1f9
+0, 29, 29, 1, 149760, 0x3742ed2e
+0, 30, 30, 1, 149760, 0xf43fe43c
+0, 31, 31, 1, 149760, 0xa84ff250
+0, 32, 32, 1, 149760, 0xd4437e12
+0, 33, 33, 1, 149760, 0xcf08c736
+0, 34, 34, 1, 149760, 0x0cedd0d6
+0, 35, 35, 1, 149760, 0xc317e9bc
+0, 36, 36, 1, 149760, 0x0dcbd636
+0, 37, 37, 1, 149760, 0x4e6501b0
+0, 38, 38, 1, 149760, 0x5f9c02bb
+0, 39, 39, 1, 149760, 0x43052939
+0, 40, 40, 1, 149760, 0x8ec12318
+0, 41, 41, 1, 149760, 0xc51577f3
+0, 42, 42, 1, 149760, 0xbda1775b
+0, 43, 43, 1, 149760, 0x62b7b2a2
+0, 44, 44, 1, 149760, 0x5dd68203
+0, 45, 45, 1, 149760, 0xe004b4bf
+0, 46, 46, 1, 149760, 0x1469769f
+0, 47, 47, 1, 149760, 0x96f57e0a
+0, 48, 48, 1, 149760, 0x75e58819
+0, 49, 49, 1, 149760, 0xf826a158
+0, 50, 50, 1, 149760, 0xf789a3bd
+0, 51, 51, 1, 149760, 0x9d8fb09a
+0, 52, 52, 1, 149760, 0x1d33bbe5
+0, 53, 53, 1, 149760, 0x7e93e014
+0, 54, 54, 1, 149760, 0x04ade2e6
+0, 55, 55, 1, 149760, 0xb93a2c32
+0, 56, 56, 1, 149760, 0x5fa73dc3
+0, 57, 57, 1, 149760, 0xa70099ee
+0, 58, 58, 1, 149760, 0xcc5aaf3e
+0, 59, 59, 1, 149760, 0x4e83f938
+0, 60, 60, 1, 149760, 0x9faae668
+0, 61, 61, 1, 149760, 0x7a5cbf24
+0, 62, 62, 1, 149760, 0x4b23714c
+0, 63, 63, 1, 149760, 0x55d246ad
+0, 64, 64, 1, 149760, 0xd3378be9
+0, 65, 65, 1, 149760, 0xf5ef9731
+0, 66, 66, 1, 149760, 0xc4ba3ad7
+0, 67, 67, 1, 149760, 0xd9182d2c
+0, 68, 68, 1, 149760, 0x0ff5eaa5
+0, 69, 69, 1, 149760, 0xefe21a58
+0, 70, 70, 1, 149760, 0x4cad2a57
+0, 71, 71, 1, 149760, 0x24a35d1a
+0, 72, 72, 1, 149760, 0xeb1b6a6e
diff --git a/tests/ref/fate/hevc-conformance-TSCL_B_VIDYO_4 b/tests/ref/fate/hevc-conformance-TSCL_B_VIDYO_4
new file mode 100644
index 0000000..6ee24ac
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-TSCL_B_VIDYO_4
@@ -0,0 +1,74 @@
+#tb 0: 1/25
+0, 0, 0, 1, 149760, 0x88619f80
+0, 1, 1, 1, 149760, 0x550bdaf0
+0, 2, 2, 1, 149760, 0x99440a14
+0, 3, 3, 1, 149760, 0xcc2c2049
+0, 4, 4, 1, 149760, 0x46927368
+0, 5, 5, 1, 149760, 0x53cdb3fe
+0, 6, 6, 1, 149760, 0x654df025
+0, 7, 7, 1, 149760, 0x024d24bc
+0, 8, 8, 1, 149760, 0x409138c2
+0, 9, 9, 1, 149760, 0xfbb47c48
+0, 10, 10, 1, 149760, 0x18caa19d
+0, 11, 11, 1, 149760, 0x0f88c2e5
+0, 12, 12, 1, 149760, 0x1c16aa2d
+0, 13, 13, 1, 149760, 0x60bfcce8
+0, 14, 14, 1, 149760, 0x1c38e3d3
+0, 15, 15, 1, 149760, 0x0d5b044a
+0, 16, 16, 1, 149760, 0x93d21593
+0, 17, 17, 1, 149760, 0xdf283910
+0, 18, 18, 1, 149760, 0x03324c23
+0, 19, 19, 1, 149760, 0x3b175b7b
+0, 20, 20, 1, 149760, 0xb91b9a7e
+0, 21, 21, 1, 149760, 0x734fbbe7
+0, 22, 22, 1, 149760, 0xfc3fea48
+0, 23, 23, 1, 149760, 0x6609103e
+0, 24, 24, 1, 149760, 0x3f5916fa
+0, 25, 25, 1, 149760, 0x08e43f4d
+0, 26, 26, 1, 149760, 0xc84e5471
+0, 27, 27, 1, 149760, 0xbd4e5c8d
+0, 28, 28, 1, 149760, 0x4a4d3995
+0, 29, 29, 1, 149760, 0x662163c0
+0, 30, 30, 1, 149760, 0xda28671f
+0, 31, 31, 1, 149760, 0x19e1878e
+0, 32, 32, 1, 149760, 0x19807e67
+0, 33, 33, 1, 149760, 0xf7aea3b6
+0, 34, 34, 1, 149760, 0x53f482c9
+0, 35, 35, 1, 149760, 0x7184b3ae
+0, 36, 36, 1, 149760, 0xb425b53d
+0, 37, 37, 1, 149760, 0xfb7cce6e
+0, 38, 38, 1, 149760, 0x820bc1ef
+0, 39, 39, 1, 149760, 0xbb0de30a
+0, 40, 40, 1, 149760, 0xbdcb0af2
+0, 41, 41, 1, 149760, 0xf2404ff7
+0, 42, 42, 1, 149760, 0xd6636f0a
+0, 43, 43, 1, 149760, 0x0e908b06
+0, 44, 44, 1, 149760, 0x36a158f4
+0, 45, 45, 1, 149760, 0x178d5bbd
+0, 46, 46, 1, 149760, 0xba9a6d14
+0, 47, 47, 1, 149760, 0x89145886
+0, 48, 48, 1, 149760, 0x6ec26794
+0, 49, 49, 1, 149760, 0xf6ac7551
+0, 50, 50, 1, 149760, 0xc829c66f
+0, 51, 51, 1, 149760, 0x64d50d50
+0, 52, 52, 1, 149760, 0x215dd855
+0, 53, 53, 1, 149760, 0x8b2ffec3
+0, 54, 54, 1, 149760, 0x1a0b7bcd
+0, 55, 55, 1, 149760, 0x14a5ad0e
+0, 56, 56, 1, 149760, 0x88c34286
+0, 57, 57, 1, 149760, 0xe2706fa9
+0, 58, 58, 1, 149760, 0x8de2decf
+0, 59, 59, 1, 149760, 0x1b37e5d7
+0, 60, 60, 1, 149760, 0xaf8d175a
+0, 61, 61, 1, 149760, 0x0f4aec5f
+0, 62, 62, 1, 149760, 0x3818df10
+0, 63, 63, 1, 149760, 0xe791d309
+0, 64, 64, 1, 149760, 0x6ad9aa0d
+0, 65, 65, 1, 149760, 0x1e1ab8a1
+0, 66, 66, 1, 149760, 0xd0ef526a
+0, 67, 67, 1, 149760, 0x45da3cf1
+0, 68, 68, 1, 149760, 0x3cb4eee6
+0, 69, 69, 1, 149760, 0x3e816ebc
+0, 70, 70, 1, 149760, 0x29d45e93
+0, 71, 71, 1, 149760, 0x824b5bc2
+0, 72, 72, 1, 149760, 0x015e6fd2
diff --git a/tests/ref/fate/hevc-conformance-TSKIP_A_MS_2 b/tests/ref/fate/hevc-conformance-TSKIP_A_MS_2
new file mode 100644
index 0000000..1226e11
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-TSKIP_A_MS_2
@@ -0,0 +1,18 @@
+#tb 0: 1/25
+0, 0, 0, 1, 1382400, 0xaea37937
+0, 1, 1, 1, 1382400, 0x39d687d0
+0, 2, 2, 1, 1382400, 0x8ea04595
+0, 3, 3, 1, 1382400, 0x5d5a40d2
+0, 4, 4, 1, 1382400, 0x6915eb4e
+0, 5, 5, 1, 1382400, 0xe8bb612d
+0, 6, 6, 1, 1382400, 0xd331085a
+0, 7, 7, 1, 1382400, 0x2193bc30
+0, 8, 8, 1, 1382400, 0xaeb19418
+0, 9, 9, 1, 1382400, 0xb524eac3
+0, 10, 10, 1, 1382400, 0x141908a2
+0, 11, 11, 1, 1382400, 0x527ab6ac
+0, 12, 12, 1, 1382400, 0xe9a73d9f
+0, 13, 13, 1, 1382400, 0x2eb0aa14
+0, 14, 14, 1, 1382400, 0x6981af42
+0, 15, 15, 1, 1382400, 0xbb0bbd7a
+0, 16, 16, 1, 1382400, 0xf0779b81
diff --git a/tests/ref/fate/hevc-conformance-WPP_A_ericsson_MAIN10_2 b/tests/ref/fate/hevc-conformance-WPP_A_ericsson_MAIN10_2
new file mode 100644
index 0000000..fe46c99
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-WPP_A_ericsson_MAIN10_2
@@ -0,0 +1,49 @@
+#tb 0: 1/25
+0, 0, 0, 1, 299520, 0xa3f96d63
+0, 1, 1, 1, 299520, 0x5f788f3f
+0, 2, 2, 1, 299520, 0x41c7d0ae
+0, 3, 3, 1, 299520, 0x14a9175c
+0, 4, 4, 1, 299520, 0x5215ed5f
+0, 5, 5, 1, 299520, 0xffa5ab17
+0, 6, 6, 1, 299520, 0x7d179b2b
+0, 7, 7, 1, 299520, 0x87280332
+0, 8, 8, 1, 299520, 0xca5e278f
+0, 9, 9, 1, 299520, 0x89d59325
+0, 10, 10, 1, 299520, 0x6593cfa5
+0, 11, 11, 1, 299520, 0x216ce552
+0, 12, 12, 1, 299520, 0x4494f2ac
+0, 13, 13, 1, 299520, 0xc9aafeb4
+0, 14, 14, 1, 299520, 0xe93a43ab
+0, 15, 15, 1, 299520, 0x89bdba99
+0, 16, 16, 1, 299520, 0xdc529079
+0, 17, 17, 1, 299520, 0xfbc29de7
+0, 18, 18, 1, 299520, 0xa8c6c853
+0, 19, 19, 1, 299520, 0xd552dc1f
+0, 20, 20, 1, 299520, 0x60a7d5d9
+0, 21, 21, 1, 299520, 0x4b784987
+0, 22, 22, 1, 299520, 0xec9bd2a0
+0, 23, 23, 1, 299520, 0x71e1d437
+0, 24, 24, 1, 299520, 0x5776a225
+0, 25, 25, 1, 299520, 0x01598543
+0, 26, 26, 1, 299520, 0x8abb1f7b
+0, 27, 27, 1, 299520, 0xa3a0bb58
+0, 28, 28, 1, 299520, 0x4a718127
+0, 29, 29, 1, 299520, 0x6b1647bc
+0, 30, 30, 1, 299520, 0x7b653009
+0, 31, 31, 1, 299520, 0xca15d4be
+0, 32, 32, 1, 299520, 0xf8075689
+0, 33, 33, 1, 299520, 0x2717f2e6
+0, 34, 34, 1, 299520, 0x53ad6267
+0, 35, 35, 1, 299520, 0x29fedd49
+0, 36, 36, 1, 299520, 0x4e8aa5db
+0, 37, 37, 1, 299520, 0xca316c94
+0, 38, 38, 1, 299520, 0x8071fd57
+0, 39, 39, 1, 299520, 0xc9915cd3
+0, 40, 40, 1, 299520, 0xab335447
+0, 41, 41, 1, 299520, 0xf733a390
+0, 42, 42, 1, 299520, 0x1fa14afb
+0, 43, 43, 1, 299520, 0xe5d7ae71
+0, 44, 44, 1, 299520, 0xb48c2ee6
+0, 45, 45, 1, 299520, 0xe288ebcc
+0, 46, 46, 1, 299520, 0xa4000bdd
+0, 47, 47, 1, 299520, 0xf3fdee3a
diff --git a/tests/ref/fate/hevc-conformance-WPP_A_ericsson_MAIN_2 b/tests/ref/fate/hevc-conformance-WPP_A_ericsson_MAIN_2
new file mode 100644
index 0000000..497c802
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-WPP_A_ericsson_MAIN_2
@@ -0,0 +1,49 @@
+#tb 0: 1/25
+0, 0, 0, 1, 149760, 0xfbb3d914
+0, 1, 1, 1, 149760, 0xdccd707b
+0, 2, 2, 1, 149760, 0x32008963
+0, 3, 3, 1, 149760, 0x0fcdd808
+0, 4, 4, 1, 149760, 0x69f0e1a5
+0, 5, 5, 1, 149760, 0x1be36c09
+0, 6, 6, 1, 149760, 0x18a1588f
+0, 7, 7, 1, 149760, 0xdc46acd8
+0, 8, 8, 1, 149760, 0xec46760a
+0, 9, 9, 1, 149760, 0xe87fc7b5
+0, 10, 10, 1, 149760, 0x7c78d960
+0, 11, 11, 1, 149760, 0x73e2ea91
+0, 12, 12, 1, 149760, 0x9164db8c
+0, 13, 13, 1, 149760, 0x31a6124b
+0, 14, 14, 1, 149760, 0x8a143aed
+0, 15, 15, 1, 149760, 0x15a364f4
+0, 16, 16, 1, 149760, 0x93b8560e
+0, 17, 17, 1, 149760, 0xc2aa985c
+0, 18, 18, 1, 149760, 0xe83ca4da
+0, 19, 19, 1, 149760, 0x6c79cb07
+0, 20, 20, 1, 149760, 0x2c24c739
+0, 21, 21, 1, 149760, 0x6a60f769
+0, 22, 22, 1, 149760, 0x13f00ad1
+0, 23, 23, 1, 149760, 0x59dd330d
+0, 24, 24, 1, 149760, 0x8815348c
+0, 25, 25, 1, 149760, 0x88576cd4
+0, 26, 26, 1, 149760, 0xfa3d6b9c
+0, 27, 27, 1, 149760, 0x810c8145
+0, 28, 28, 1, 149760, 0xf2357fcc
+0, 29, 29, 1, 149760, 0xc885a093
+0, 30, 30, 1, 149760, 0x5939a048
+0, 31, 31, 1, 149760, 0x9f93a489
+0, 32, 32, 1, 149760, 0xc11a879e
+0, 33, 33, 1, 149760, 0x5221c04b
+0, 34, 34, 1, 149760, 0x7dcdca90
+0, 35, 35, 1, 149760, 0xfdd8df1e
+0, 36, 36, 1, 149760, 0x3a88c802
+0, 37, 37, 1, 149760, 0x50ff1081
+0, 38, 38, 1, 149760, 0x6388f458
+0, 39, 39, 1, 149760, 0x85623a2b
+0, 40, 40, 1, 149760, 0x1bfd34a4
+0, 41, 41, 1, 149760, 0xb6037b88
+0, 42, 42, 1, 149760, 0xd24e65c7
+0, 43, 43, 1, 149760, 0xd2bd8fac
+0, 44, 44, 1, 149760, 0x602f64d0
+0, 45, 45, 1, 149760, 0x59415d5e
+0, 46, 46, 1, 149760, 0x9faf5737
+0, 47, 47, 1, 149760, 0x66ce56a9
diff --git a/tests/ref/fate/hevc-conformance-WPP_B_ericsson_MAIN10_2 b/tests/ref/fate/hevc-conformance-WPP_B_ericsson_MAIN10_2
new file mode 100644
index 0000000..d199d38
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-WPP_B_ericsson_MAIN10_2
@@ -0,0 +1,49 @@
+#tb 0: 1/25
+0, 0, 0, 1, 299520, 0x66b3cef3
+0, 1, 1, 1, 299520, 0x99df880f
+0, 2, 2, 1, 299520, 0xb4a03801
+0, 3, 3, 1, 299520, 0x1510c9e2
+0, 4, 4, 1, 299520, 0x42fe77b1
+0, 5, 5, 1, 299520, 0x815e1727
+0, 6, 6, 1, 299520, 0x6dd002f4
+0, 7, 7, 1, 299520, 0x2650e944
+0, 8, 8, 1, 299520, 0x3268c1e9
+0, 9, 9, 1, 299520, 0xced41a5f
+0, 10, 10, 1, 299520, 0x91334b97
+0, 11, 11, 1, 299520, 0xc5bb7ff6
+0, 12, 12, 1, 299520, 0x26e27c35
+0, 13, 13, 1, 299520, 0x482da6cb
+0, 14, 14, 1, 299520, 0xfe742e8e
+0, 15, 15, 1, 299520, 0x3f395752
+0, 16, 16, 1, 299520, 0x189936e5
+0, 17, 17, 1, 299520, 0x56a58a07
+0, 18, 18, 1, 299520, 0x798d8de9
+0, 19, 19, 1, 299520, 0x5d8e947f
+0, 20, 20, 1, 299520, 0x65477654
+0, 21, 21, 1, 299520, 0x5012d167
+0, 22, 22, 1, 299520, 0xe889bb27
+0, 23, 23, 1, 299520, 0x4611c1e6
+0, 24, 24, 1, 299520, 0xb093402b
+0, 25, 25, 1, 299520, 0xddc065d8
+0, 26, 26, 1, 299520, 0x6986e1d9
+0, 27, 27, 1, 299520, 0x0e539004
+0, 28, 28, 1, 299520, 0x4768f9ed
+0, 29, 29, 1, 299520, 0xfad20b53
+0, 30, 30, 1, 299520, 0x82f9c996
+0, 31, 31, 1, 299520, 0x6b366d79
+0, 32, 32, 1, 299520, 0x5a35d42e
+0, 33, 33, 1, 299520, 0xf3849013
+0, 34, 34, 1, 299520, 0x6b8eae50
+0, 35, 35, 1, 299520, 0x0f854274
+0, 36, 36, 1, 299520, 0x31685299
+0, 37, 37, 1, 299520, 0x77357bfb
+0, 38, 38, 1, 299520, 0xd67f1807
+0, 39, 39, 1, 299520, 0x371e7eb6
+0, 40, 40, 1, 299520, 0xe2ee3531
+0, 41, 41, 1, 299520, 0x50f242f1
+0, 42, 42, 1, 299520, 0x265ed919
+0, 43, 43, 1, 299520, 0xad496c85
+0, 44, 44, 1, 299520, 0xb2aef047
+0, 45, 45, 1, 299520, 0xac5c4451
+0, 46, 46, 1, 299520, 0x2b26a0cb
+0, 47, 47, 1, 299520, 0x5738d837
diff --git a/tests/ref/fate/hevc-conformance-WPP_B_ericsson_MAIN_2 b/tests/ref/fate/hevc-conformance-WPP_B_ericsson_MAIN_2
new file mode 100644
index 0000000..bb61b10
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-WPP_B_ericsson_MAIN_2
@@ -0,0 +1,49 @@
+#tb 0: 1/25
+0, 0, 0, 1, 149760, 0x3772de54
+0, 1, 1, 1, 149760, 0x571d885e
+0, 2, 2, 1, 149760, 0x71576f09
+0, 3, 3, 1, 149760, 0xf0724ce0
+0, 4, 4, 1, 149760, 0x2cc6e355
+0, 5, 5, 1, 149760, 0x0ca14365
+0, 6, 6, 1, 149760, 0x5aeb4b4d
+0, 7, 7, 1, 149760, 0xb018561c
+0, 8, 8, 1, 149760, 0x8fb07521
+0, 9, 9, 1, 149760, 0x9e1ccc5b
+0, 10, 10, 1, 149760, 0x0cf3de9f
+0, 11, 11, 1, 149760, 0x918cf512
+0, 12, 12, 1, 149760, 0x9a60e5c4
+0, 13, 13, 1, 149760, 0xc3b01d10
+0, 14, 14, 1, 149760, 0x929b34a6
+0, 15, 15, 1, 149760, 0x1f9462ac
+0, 16, 16, 1, 149760, 0xcadf511e
+0, 17, 17, 1, 149760, 0x318e9af6
+0, 18, 18, 1, 149760, 0x0860a371
+0, 19, 19, 1, 149760, 0x13e3c4d1
+0, 20, 20, 1, 149760, 0xfa27cbf6
+0, 21, 21, 1, 149760, 0x407ffed5
+0, 22, 22, 1, 149760, 0xa3c00c3b
+0, 23, 23, 1, 149760, 0x926938c6
+0, 24, 24, 1, 149760, 0xf5792acf
+0, 25, 25, 1, 149760, 0x66e16a48
+0, 26, 26, 1, 149760, 0xd46e7041
+0, 27, 27, 1, 149760, 0x814c84ee
+0, 28, 28, 1, 149760, 0x165b750a
+0, 29, 29, 1, 149760, 0x24ad9df0
+0, 30, 30, 1, 149760, 0x11189e4e
+0, 31, 31, 1, 149760, 0xb841a5b6
+0, 32, 32, 1, 149760, 0xea738605
+0, 33, 33, 1, 149760, 0xbbf0ca3f
+0, 34, 34, 1, 149760, 0xcfb5d03c
+0, 35, 35, 1, 149760, 0x0654f0b7
+0, 36, 36, 1, 149760, 0x1c2cd18d
+0, 37, 37, 1, 149760, 0x9a4602ae
+0, 38, 38, 1, 149760, 0xf2a2ff5a
+0, 39, 39, 1, 149760, 0x9c153c77
+0, 40, 40, 1, 149760, 0x5ed23e56
+0, 41, 41, 1, 149760, 0x1eb58383
+0, 42, 42, 1, 149760, 0x725e70f2
+0, 43, 43, 1, 149760, 0x652aa56c
+0, 44, 44, 1, 149760, 0x7f736ad2
+0, 45, 45, 1, 149760, 0x0827700a
+0, 46, 46, 1, 149760, 0x76a06370
+0, 47, 47, 1, 149760, 0xa7fe6f9d
diff --git a/tests/ref/fate/hevc-conformance-WPP_C_ericsson_MAIN10_2 b/tests/ref/fate/hevc-conformance-WPP_C_ericsson_MAIN10_2
new file mode 100644
index 0000000..b1e6312
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-WPP_C_ericsson_MAIN10_2
@@ -0,0 +1,49 @@
+#tb 0: 1/25
+0, 0, 0, 1, 299520, 0xbc71d699
+0, 1, 1, 1, 299520, 0x3207e1f9
+0, 2, 2, 1, 299520, 0xdd2087b5
+0, 3, 3, 1, 299520, 0xb512c976
+0, 4, 4, 1, 299520, 0x22957011
+0, 5, 5, 1, 299520, 0x8ce04965
+0, 6, 6, 1, 299520, 0x9cf37cba
+0, 7, 7, 1, 299520, 0xd52f8b2d
+0, 8, 8, 1, 299520, 0x2f55a94d
+0, 9, 9, 1, 299520, 0x53d3cc42
+0, 10, 10, 1, 299520, 0xbc33f3a1
+0, 11, 11, 1, 299520, 0x5e67d0de
+0, 12, 12, 1, 299520, 0x5708ecc5
+0, 13, 13, 1, 299520, 0x104869c0
+0, 14, 14, 1, 299520, 0xaf2a8638
+0, 15, 15, 1, 299520, 0xbdf1d001
+0, 16, 16, 1, 299520, 0xa3f71579
+0, 17, 17, 1, 299520, 0x68cedb09
+0, 18, 18, 1, 299520, 0xa4262d4d
+0, 19, 19, 1, 299520, 0x99320c8d
+0, 20, 20, 1, 299520, 0x57be6268
+0, 21, 21, 1, 299520, 0xc7e14cfc
+0, 22, 22, 1, 299520, 0x3d906541
+0, 23, 23, 1, 299520, 0x804b2f29
+0, 24, 24, 1, 299520, 0x93cf0ae2
+0, 25, 25, 1, 299520, 0x0fd2f932
+0, 26, 26, 1, 299520, 0xf869a25c
+0, 27, 27, 1, 299520, 0xa2dc56cd
+0, 28, 28, 1, 299520, 0x075b14a7
+0, 29, 29, 1, 299520, 0x233b0085
+0, 30, 30, 1, 299520, 0x80a69c4c
+0, 31, 31, 1, 299520, 0xf45f21af
+0, 32, 32, 1, 299520, 0x88dcab6e
+0, 33, 33, 1, 299520, 0xc1df3e99
+0, 34, 34, 1, 299520, 0xac298452
+0, 35, 35, 1, 299520, 0x6b4cc1e3
+0, 36, 36, 1, 299520, 0xfd39c597
+0, 37, 37, 1, 299520, 0xe60f808c
+0, 38, 38, 1, 299520, 0x27c47830
+0, 39, 39, 1, 299520, 0x4fd9ec76
+0, 40, 40, 1, 299520, 0x3249e084
+0, 41, 41, 1, 299520, 0x40632223
+0, 42, 42, 1, 299520, 0x9b68d213
+0, 43, 43, 1, 299520, 0x9e210ed8
+0, 44, 44, 1, 299520, 0x54489508
+0, 45, 45, 1, 299520, 0xc799df16
+0, 46, 46, 1, 299520, 0x020b2211
+0, 47, 47, 1, 299520, 0xcc1a1683
diff --git a/tests/ref/fate/hevc-conformance-WPP_C_ericsson_MAIN_2 b/tests/ref/fate/hevc-conformance-WPP_C_ericsson_MAIN_2
new file mode 100644
index 0000000..49c4f21
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-WPP_C_ericsson_MAIN_2
@@ -0,0 +1,49 @@
+#tb 0: 1/25
+0, 0, 0, 1, 149760, 0x0948e521
+0, 1, 1, 1, 149760, 0x37afb384
+0, 2, 2, 1, 149760, 0xe1864c4a
+0, 3, 3, 1, 149760, 0x143344eb
+0, 4, 4, 1, 149760, 0x34cce612
+0, 5, 5, 1, 149760, 0x45ce60b3
+0, 6, 6, 1, 149760, 0x17b36585
+0, 7, 7, 1, 149760, 0x6447ebe5
+0, 8, 8, 1, 149760, 0x0f4282c7
+0, 9, 9, 1, 149760, 0xa0c3dab3
+0, 10, 10, 1, 149760, 0x0f3ceb7c
+0, 11, 11, 1, 149760, 0xb861f311
+0, 12, 12, 1, 149760, 0x620fe482
+0, 13, 13, 1, 149760, 0xa3dc1603
+0, 14, 14, 1, 149760, 0x6b7a3a6c
+0, 15, 15, 1, 149760, 0x01d16e5e
+0, 16, 16, 1, 149760, 0xe12f6009
+0, 17, 17, 1, 149760, 0xc96d98bd
+0, 18, 18, 1, 149760, 0x542e9f47
+0, 19, 19, 1, 149760, 0x5bcbc3b8
+0, 20, 20, 1, 149760, 0x3be2c63a
+0, 21, 21, 1, 149760, 0xd63df815
+0, 22, 22, 1, 149760, 0x5c210d61
+0, 23, 23, 1, 149760, 0xc7fb33b8
+0, 24, 24, 1, 149760, 0xa9f13508
+0, 25, 25, 1, 149760, 0xbf636172
+0, 26, 26, 1, 149760, 0xf1966847
+0, 27, 27, 1, 149760, 0xcc0579eb
+0, 28, 28, 1, 149760, 0x467673cb
+0, 29, 29, 1, 149760, 0x4dbca3f2
+0, 30, 30, 1, 149760, 0xada29bc9
+0, 31, 31, 1, 149760, 0x2983a0d5
+0, 32, 32, 1, 149760, 0x3864832a
+0, 33, 33, 1, 149760, 0x6a06b61d
+0, 34, 34, 1, 149760, 0x90a0d994
+0, 35, 35, 1, 149760, 0x3c58f375
+0, 36, 36, 1, 149760, 0x365bd42a
+0, 37, 37, 1, 149760, 0x5665f25f
+0, 38, 38, 1, 149760, 0x75d8fe8f
+0, 39, 39, 1, 149760, 0xc67e3508
+0, 40, 40, 1, 149760, 0x2e7b428b
+0, 41, 41, 1, 149760, 0x59cf741c
+0, 42, 42, 1, 149760, 0x2cc77eb4
+0, 43, 43, 1, 149760, 0x4957970a
+0, 44, 44, 1, 149760, 0xa69f7323
+0, 45, 45, 1, 149760, 0xaf1f6772
+0, 46, 46, 1, 149760, 0x864a5a76
+0, 47, 47, 1, 149760, 0x57795407
diff --git a/tests/ref/fate/hevc-conformance-WPP_D_ericsson_MAIN10_2 b/tests/ref/fate/hevc-conformance-WPP_D_ericsson_MAIN10_2
new file mode 100644
index 0000000..83cf10c
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-WPP_D_ericsson_MAIN10_2
@@ -0,0 +1,49 @@
+#tb 0: 1/25
+0, 0, 0, 1, 46080, 0xc50ed6b4
+0, 1, 1, 1, 46080, 0x2aeac52d
+0, 2, 2, 1, 46080, 0xe3e36cd3
+0, 3, 3, 1, 46080, 0x81c6b317
+0, 4, 4, 1, 46080, 0x20e24e33
+0, 5, 5, 1, 46080, 0xc4a64f17
+0, 6, 6, 1, 46080, 0xf95a5014
+0, 7, 7, 1, 46080, 0x8d9e9a26
+0, 8, 8, 1, 46080, 0x5f0f4592
+0, 9, 9, 1, 46080, 0xa1b54f9f
+0, 10, 10, 1, 46080, 0x3d5c3673
+0, 11, 11, 1, 46080, 0xca6e5e83
+0, 12, 12, 1, 46080, 0x93eca575
+0, 13, 13, 1, 46080, 0xf84bab2b
+0, 14, 14, 1, 46080, 0xf22599d1
+0, 15, 15, 1, 46080, 0xf916673f
+0, 16, 16, 1, 46080, 0xbb11a29b
+0, 17, 17, 1, 46080, 0x047e1dd7
+0, 18, 18, 1, 46080, 0x9a975834
+0, 19, 19, 1, 46080, 0xa3fe84d4
+0, 20, 20, 1, 46080, 0x08e1c2f4
+0, 21, 21, 1, 46080, 0xbbbcf81b
+0, 22, 22, 1, 46080, 0x4abb0255
+0, 23, 23, 1, 46080, 0x20052dda
+0, 24, 24, 1, 46080, 0x10290ef3
+0, 25, 25, 1, 46080, 0x9e7633d0
+0, 26, 26, 1, 46080, 0x60d0fb3a
+0, 27, 27, 1, 46080, 0xe0209fb3
+0, 28, 28, 1, 46080, 0xea006c44
+0, 29, 29, 1, 46080, 0xe0b84e96
+0, 30, 30, 1, 46080, 0x35e507d7
+0, 31, 31, 1, 46080, 0x4107fcd6
+0, 32, 32, 1, 46080, 0x1b34af49
+0, 33, 33, 1, 46080, 0x4ab91078
+0, 34, 34, 1, 46080, 0x130750dd
+0, 35, 35, 1, 46080, 0x592dbe41
+0, 36, 36, 1, 46080, 0xfd39cf6b
+0, 37, 37, 1, 46080, 0xbe9ee5b7
+0, 38, 38, 1, 46080, 0x25ebde48
+0, 39, 39, 1, 46080, 0x2becd45c
+0, 40, 40, 1, 46080, 0x9b5fdfdb
+0, 41, 41, 1, 46080, 0xededa5f5
+0, 42, 42, 1, 46080, 0x476bc4e5
+0, 43, 43, 1, 46080, 0x4a4a0a4e
+0, 44, 44, 1, 46080, 0x1324f41b
+0, 45, 45, 1, 46080, 0xc503cfc8
+0, 46, 46, 1, 46080, 0x53f7c74c
+0, 47, 47, 1, 46080, 0xc861b5a3
diff --git a/tests/ref/fate/hevc-conformance-WPP_D_ericsson_MAIN_2 b/tests/ref/fate/hevc-conformance-WPP_D_ericsson_MAIN_2
new file mode 100644
index 0000000..6e6fc32
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-WPP_D_ericsson_MAIN_2
@@ -0,0 +1,49 @@
+#tb 0: 1/25
+0, 0, 0, 1, 23040, 0x6977dbca
+0, 1, 1, 1, 23040, 0xd9bfcb5c
+0, 2, 2, 1, 23040, 0xbdd5a346
+0, 3, 3, 1, 23040, 0x021877cd
+0, 4, 4, 1, 23040, 0xb8a45933
+0, 5, 5, 1, 23040, 0xc289338e
+0, 6, 6, 1, 23040, 0x6968e57d
+0, 7, 7, 1, 23040, 0x1142c50c
+0, 8, 8, 1, 23040, 0xcf86c357
+0, 9, 9, 1, 23040, 0xf73de7ec
+0, 10, 10, 1, 23040, 0x2103ed06
+0, 11, 11, 1, 23040, 0xf0ecc0e2
+0, 12, 12, 1, 23040, 0xa7b1971f
+0, 13, 13, 1, 23040, 0x4454871a
+0, 14, 14, 1, 23040, 0xc5088346
+0, 15, 15, 1, 23040, 0x89189469
+0, 16, 16, 1, 23040, 0x320d977a
+0, 17, 17, 1, 23040, 0xbdc0a95b
+0, 18, 18, 1, 23040, 0xbcfec5c9
+0, 19, 19, 1, 23040, 0xb68ceb37
+0, 20, 20, 1, 23040, 0x41a60b0c
+0, 21, 21, 1, 23040, 0x0e662b47
+0, 22, 22, 1, 23040, 0x0e2440b7
+0, 23, 23, 1, 23040, 0x77415a77
+0, 24, 24, 1, 23040, 0x62936fdf
+0, 25, 25, 1, 23040, 0xaa987f9d
+0, 26, 26, 1, 23040, 0xaf0c8764
+0, 27, 27, 1, 23040, 0x645c913e
+0, 28, 28, 1, 23040, 0x2f249b06
+0, 29, 29, 1, 23040, 0xb54fb546
+0, 30, 30, 1, 23040, 0xc669c247
+0, 31, 31, 1, 23040, 0xe308bb8f
+0, 32, 32, 1, 23040, 0xb920b69d
+0, 33, 33, 1, 23040, 0x86d5c0ff
+0, 34, 34, 1, 23040, 0x7d5ec3e4
+0, 35, 35, 1, 23040, 0x5ca1cdb0
+0, 36, 36, 1, 23040, 0xdc11cf9e
+0, 37, 37, 1, 23040, 0x1a7fd0d5
+0, 38, 38, 1, 23040, 0x9884d5cd
+0, 39, 39, 1, 23040, 0xcafbd5fb
+0, 40, 40, 1, 23040, 0xc670ceb7
+0, 41, 41, 1, 23040, 0x63cecef7
+0, 42, 42, 1, 23040, 0xfe29c28c
+0, 43, 43, 1, 23040, 0x368dc66e
+0, 44, 44, 1, 23040, 0x2ec7c4de
+0, 45, 45, 1, 23040, 0x8954c9d6
+0, 46, 46, 1, 23040, 0xff89ca68
+0, 47, 47, 1, 23040, 0x5ae0b290
diff --git a/tests/ref/fate/hevc-conformance-WPP_E_ericsson_MAIN10_2 b/tests/ref/fate/hevc-conformance-WPP_E_ericsson_MAIN10_2
new file mode 100644
index 0000000..dbf6f78
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-WPP_E_ericsson_MAIN10_2
@@ -0,0 +1,49 @@
+#tb 0: 1/25
+0, 0, 0, 1, 92160, 0x591c992e
+0, 1, 1, 1, 92160, 0xe7a8cd8b
+0, 2, 2, 1, 92160, 0x2e7528bb
+0, 3, 3, 1, 92160, 0x92438eae
+0, 4, 4, 1, 92160, 0x15cc21b9
+0, 5, 5, 1, 92160, 0x3f14a50e
+0, 6, 6, 1, 92160, 0xdbc712e7
+0, 7, 7, 1, 92160, 0x277b2d3f
+0, 8, 8, 1, 92160, 0x05478988
+0, 9, 9, 1, 92160, 0x46888b9c
+0, 10, 10, 1, 92160, 0xb1f46d1b
+0, 11, 11, 1, 92160, 0xa86771fa
+0, 12, 12, 1, 92160, 0x1294944a
+0, 13, 13, 1, 92160, 0xe134cd44
+0, 14, 14, 1, 92160, 0x5fdbf1fb
+0, 15, 15, 1, 92160, 0x01f04b2e
+0, 16, 16, 1, 92160, 0x50989c28
+0, 17, 17, 1, 92160, 0x3202cf37
+0, 18, 18, 1, 92160, 0x67fbdb0f
+0, 19, 19, 1, 92160, 0x4d453062
+0, 20, 20, 1, 92160, 0x799c3e16
+0, 21, 21, 1, 92160, 0xdda76a94
+0, 22, 22, 1, 92160, 0x392d0fc9
+0, 23, 23, 1, 92160, 0x1196e850
+0, 24, 24, 1, 92160, 0x8758d8a9
+0, 25, 25, 1, 92160, 0xb632c2b3
+0, 26, 26, 1, 92160, 0xf3ba5e47
+0, 27, 27, 1, 92160, 0x3ae40182
+0, 28, 28, 1, 92160, 0xf285e2eb
+0, 29, 29, 1, 92160, 0x826aee47
+0, 30, 30, 1, 92160, 0xe06ba18b
+0, 31, 31, 1, 92160, 0xf34b6ef5
+0, 32, 32, 1, 92160, 0xf94045ab
+0, 33, 33, 1, 92160, 0xd0ae63f4
+0, 34, 34, 1, 92160, 0x4c35afc1
+0, 35, 35, 1, 92160, 0x9a150816
+0, 36, 36, 1, 92160, 0x1a4214d4
+0, 37, 37, 1, 92160, 0x9f042653
+0, 38, 38, 1, 92160, 0xf69a40a8
+0, 39, 39, 1, 92160, 0xb8462c18
+0, 40, 40, 1, 92160, 0xf42d4748
+0, 41, 41, 1, 92160, 0x4968dc19
+0, 42, 42, 1, 92160, 0xc8e6001f
+0, 43, 43, 1, 92160, 0xebb42677
+0, 44, 44, 1, 92160, 0x3fb805dd
+0, 45, 45, 1, 92160, 0x1953cfc1
+0, 46, 46, 1, 92160, 0x633108f4
+0, 47, 47, 1, 92160, 0x65aedf42
diff --git a/tests/ref/fate/hevc-conformance-WPP_E_ericsson_MAIN_2 b/tests/ref/fate/hevc-conformance-WPP_E_ericsson_MAIN_2
new file mode 100644
index 0000000..ac478c6
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-WPP_E_ericsson_MAIN_2
@@ -0,0 +1,49 @@
+#tb 0: 1/25
+0, 0, 0, 1, 46080, 0xcd234724
+0, 1, 1, 1, 46080, 0x66649579
+0, 2, 2, 1, 46080, 0x4317d38d
+0, 3, 3, 1, 46080, 0x308dfc39
+0, 4, 4, 1, 46080, 0xe08e3015
+0, 5, 5, 1, 46080, 0xaa0a3e44
+0, 6, 6, 1, 46080, 0x491b61cf
+0, 7, 7, 1, 46080, 0x9c5a9749
+0, 8, 8, 1, 46080, 0x4384ae34
+0, 9, 9, 1, 46080, 0xfd2bf2c1
+0, 10, 10, 1, 46080, 0xf29b18d7
+0, 11, 11, 1, 46080, 0xc1912df5
+0, 12, 12, 1, 46080, 0x9cc3344b
+0, 13, 13, 1, 46080, 0x41c062a3
+0, 14, 14, 1, 46080, 0xa5ec8417
+0, 15, 15, 1, 46080, 0x94e5aed6
+0, 16, 16, 1, 46080, 0x1af6ce24
+0, 17, 17, 1, 46080, 0xd73c0272
+0, 18, 18, 1, 46080, 0xb7b41c50
+0, 19, 19, 1, 46080, 0x7fa442dc
+0, 20, 20, 1, 46080, 0x513e5f5a
+0, 21, 21, 1, 46080, 0x46a1848b
+0, 22, 22, 1, 46080, 0xcf31a1c4
+0, 23, 23, 1, 46080, 0x3ee8c90c
+0, 24, 24, 1, 46080, 0xc54fdd27
+0, 25, 25, 1, 46080, 0x59830556
+0, 26, 26, 1, 46080, 0xf8c70cc7
+0, 27, 27, 1, 46080, 0x44a519f9
+0, 28, 28, 1, 46080, 0xdd0323d3
+0, 29, 29, 1, 46080, 0x93874212
+0, 30, 30, 1, 46080, 0xba8e4d8e
+0, 31, 31, 1, 46080, 0x5c3f4fb0
+0, 32, 32, 1, 46080, 0x37084bf2
+0, 33, 33, 1, 46080, 0xad256b1b
+0, 34, 34, 1, 46080, 0x862b7a7d
+0, 35, 35, 1, 46080, 0x4a2e8d56
+0, 36, 36, 1, 46080, 0xe99d8f5a
+0, 37, 37, 1, 46080, 0xe41a9456
+0, 38, 38, 1, 46080, 0xe7339f1c
+0, 39, 39, 1, 46080, 0xfa38a6c3
+0, 40, 40, 1, 46080, 0x219e97d2
+0, 41, 41, 1, 46080, 0x652d9cc2
+0, 42, 42, 1, 46080, 0x40bf8f94
+0, 43, 43, 1, 46080, 0x2fee9e23
+0, 44, 44, 1, 46080, 0xeea39203
+0, 45, 45, 1, 46080, 0x69819b5c
+0, 46, 46, 1, 46080, 0x511ba0b5
+0, 47, 47, 1, 46080, 0x85fd892f
diff --git a/tests/ref/fate/hevc-conformance-WPP_F_ericsson_MAIN10_2 b/tests/ref/fate/hevc-conformance-WPP_F_ericsson_MAIN10_2
new file mode 100644
index 0000000..2f103b7
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-WPP_F_ericsson_MAIN10_2
@@ -0,0 +1,49 @@
+#tb 0: 1/25
+0, 0, 0, 1, 138240, 0x99f196ae
+0, 1, 1, 1, 138240, 0x45f407de
+0, 2, 2, 1, 138240, 0xdaef815b
+0, 3, 3, 1, 138240, 0x6812ba5a
+0, 4, 4, 1, 138240, 0x1099912d
+0, 5, 5, 1, 138240, 0xf58ee932
+0, 6, 6, 1, 138240, 0x79df05d8
+0, 7, 7, 1, 138240, 0xa0813719
+0, 8, 8, 1, 138240, 0xe9c7c5c0
+0, 9, 9, 1, 138240, 0xe8c5aba3
+0, 10, 10, 1, 138240, 0x7f0ed0b6
+0, 11, 11, 1, 138240, 0x1bdcfd20
+0, 12, 12, 1, 138240, 0x3b1fc007
+0, 13, 13, 1, 138240, 0xf6a9d270
+0, 14, 14, 1, 138240, 0x3a2d47d4
+0, 15, 15, 1, 138240, 0xbeb9685f
+0, 16, 16, 1, 138240, 0x4cb6eb4a
+0, 17, 17, 1, 138240, 0xa456dcdf
+0, 18, 18, 1, 138240, 0x2933f8e1
+0, 19, 19, 1, 138240, 0x27de28e9
+0, 20, 20, 1, 138240, 0x557c0e51
+0, 21, 21, 1, 138240, 0x6f106540
+0, 22, 22, 1, 138240, 0xf78421a4
+0, 23, 23, 1, 138240, 0xa94029a7
+0, 24, 24, 1, 138240, 0xacfa2b8b
+0, 25, 25, 1, 138240, 0x32e7d347
+0, 26, 26, 1, 138240, 0xe4c17fac
+0, 27, 27, 1, 138240, 0x47e61949
+0, 28, 28, 1, 138240, 0xd248e34b
+0, 29, 29, 1, 138240, 0xb747dc2c
+0, 30, 30, 1, 138240, 0x3a0eaf61
+0, 31, 31, 1, 138240, 0x4e254b5f
+0, 32, 32, 1, 138240, 0xf434f578
+0, 33, 33, 1, 138240, 0xe799308e
+0, 34, 34, 1, 138240, 0xb3e67c89
+0, 35, 35, 1, 138240, 0xb6ceb379
+0, 36, 36, 1, 138240, 0xd70bea99
+0, 37, 37, 1, 138240, 0xad0717a8
+0, 38, 38, 1, 138240, 0x2b50f085
+0, 39, 39, 1, 138240, 0xb334e518
+0, 40, 40, 1, 138240, 0xe7311c3a
+0, 41, 41, 1, 138240, 0x7c46dc19
+0, 42, 42, 1, 138240, 0x18c20dfa
+0, 43, 43, 1, 138240, 0x8bc0f6ae
+0, 44, 44, 1, 138240, 0x91a8c381
+0, 45, 45, 1, 138240, 0x2ba57297
+0, 46, 46, 1, 138240, 0x99d982f0
+0, 47, 47, 1, 138240, 0x0f84942a
diff --git a/tests/ref/fate/hevc-conformance-WPP_F_ericsson_MAIN_2 b/tests/ref/fate/hevc-conformance-WPP_F_ericsson_MAIN_2
new file mode 100644
index 0000000..6256d96
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-WPP_F_ericsson_MAIN_2
@@ -0,0 +1,49 @@
+#tb 0: 1/25
+0, 0, 0, 1, 69120, 0x28326a13
+0, 1, 1, 1, 69120, 0x1f41a4a7
+0, 2, 2, 1, 69120, 0x803ceeb4
+0, 3, 3, 1, 69120, 0x1eba4049
+0, 4, 4, 1, 69120, 0x61a25512
+0, 5, 5, 1, 69120, 0x4db37e41
+0, 6, 6, 1, 69120, 0x00f69308
+0, 7, 7, 1, 69120, 0x7478c70f
+0, 8, 8, 1, 69120, 0xba1bd40b
+0, 9, 9, 1, 69120, 0x31d416bc
+0, 10, 10, 1, 69120, 0xd0c042bd
+0, 11, 11, 1, 69120, 0xe7a75aba
+0, 12, 12, 1, 69120, 0xb4235b4c
+0, 13, 13, 1, 69120, 0xaad387c3
+0, 14, 14, 1, 69120, 0xb97aab7a
+0, 15, 15, 1, 69120, 0x1acdda47
+0, 16, 16, 1, 69120, 0x2c95f726
+0, 17, 17, 1, 69120, 0xba3f2ebb
+0, 18, 18, 1, 69120, 0x15fc4901
+0, 19, 19, 1, 69120, 0x56387074
+0, 20, 20, 1, 69120, 0xe9638772
+0, 21, 21, 1, 69120, 0x344db5ec
+0, 22, 22, 1, 69120, 0xf54bd087
+0, 23, 23, 1, 69120, 0x5b35fbe4
+0, 24, 24, 1, 69120, 0x052c0947
+0, 25, 25, 1, 69120, 0xe562417c
+0, 26, 26, 1, 69120, 0x502a4776
+0, 27, 27, 1, 69120, 0x46b05919
+0, 28, 28, 1, 69120, 0x103161a1
+0, 29, 29, 1, 69120, 0xd83e8318
+0, 30, 30, 1, 69120, 0xd7ce8fb1
+0, 31, 31, 1, 69120, 0xda3f8ac5
+0, 32, 32, 1, 69120, 0xecd17de1
+0, 33, 33, 1, 69120, 0x7beeab11
+0, 34, 34, 1, 69120, 0xb295b81f
+0, 35, 35, 1, 69120, 0x785ec9ab
+0, 36, 36, 1, 69120, 0x58a3c317
+0, 37, 37, 1, 69120, 0x05feda91
+0, 38, 38, 1, 69120, 0xd21fdcab
+0, 39, 39, 1, 69120, 0x0d6ce0ee
+0, 40, 40, 1, 69120, 0x40ddc715
+0, 41, 41, 1, 69120, 0x5489d3e1
+0, 42, 42, 1, 69120, 0x7f57c42b
+0, 43, 43, 1, 69120, 0xd470cca3
+0, 44, 44, 1, 69120, 0xfb80c51c
+0, 45, 45, 1, 69120, 0x76b1d068
+0, 46, 46, 1, 69120, 0x5b01d81e
+0, 47, 47, 1, 69120, 0x21cfc241
diff --git a/tests/ref/fate/hevc-conformance-WP_A_MAIN10_Toshiba_3 b/tests/ref/fate/hevc-conformance-WP_A_MAIN10_Toshiba_3
new file mode 100644
index 0000000..b2dadba
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-WP_A_MAIN10_Toshiba_3
@@ -0,0 +1,257 @@
+#tb 0: 1/25
+0, 0, 0, 1, 299520, 0x7750edc7
+0, 1, 1, 1, 299520, 0x97fb359b
+0, 2, 2, 1, 299520, 0x89ac22bc
+0, 3, 3, 1, 299520, 0x4f7e0ecc
+0, 4, 4, 1, 299520, 0x7367f210
+0, 5, 5, 1, 299520, 0x5c2274e3
+0, 6, 6, 1, 299520, 0x11f26352
+0, 7, 7, 1, 299520, 0x2c712fcc
+0, 8, 8, 1, 299520, 0x44d700aa
+0, 9, 9, 1, 299520, 0x7426fc80
+0, 10, 10, 1, 299520, 0xd31d2fef
+0, 11, 11, 1, 299520, 0xd7c8d389
+0, 12, 12, 1, 299520, 0x2a8283e7
+0, 13, 13, 1, 299520, 0x429f5e44
+0, 14, 14, 1, 299520, 0x5c818504
+0, 15, 15, 1, 299520, 0x1057090e
+0, 16, 16, 1, 299520, 0x61404e77
+0, 17, 17, 1, 299520, 0x8ce43ed3
+0, 18, 18, 1, 299520, 0xf08e6c4d
+0, 19, 19, 1, 299520, 0xb133a69f
+0, 20, 20, 1, 299520, 0xd1be15a5
+0, 21, 21, 1, 299520, 0xe875543f
+0, 22, 22, 1, 299520, 0x0310f356
+0, 23, 23, 1, 299520, 0x5ee0a7d9
+0, 24, 24, 1, 299520, 0xacd092bb
+0, 25, 25, 1, 299520, 0x878ef783
+0, 26, 26, 1, 299520, 0xed9a2c06
+0, 27, 27, 1, 299520, 0x0a4cb661
+0, 28, 28, 1, 299520, 0x69aed89b
+0, 29, 29, 1, 299520, 0xaa75d081
+0, 30, 30, 1, 299520, 0x4c0402c6
+0, 31, 31, 1, 299520, 0x7050b8f8
+0, 32, 32, 1, 299520, 0x20cf8db8
+0, 33, 33, 1, 299520, 0xa615d0cb
+0, 34, 34, 1, 299520, 0x3170b77f
+0, 35, 35, 1, 299520, 0x781f17a5
+0, 36, 36, 1, 299520, 0x8767468b
+0, 37, 37, 1, 299520, 0x8f291a78
+0, 38, 38, 1, 299520, 0x87534588
+0, 39, 39, 1, 299520, 0xb4861cee
+0, 40, 40, 1, 299520, 0x38b6ba36
+0, 41, 41, 1, 299520, 0x757ebda4
+0, 42, 42, 1, 299520, 0xeccca3c0
+0, 43, 43, 1, 299520, 0x8af415a3
+0, 44, 44, 1, 299520, 0x37064dea
+0, 45, 45, 1, 299520, 0xfea46d66
+0, 46, 46, 1, 299520, 0x038d776f
+0, 47, 47, 1, 299520, 0x2b905161
+0, 48, 48, 1, 299520, 0x60230f44
+0, 49, 49, 1, 299520, 0x828f8991
+0, 50, 50, 1, 299520, 0x7c5ded06
+0, 51, 51, 1, 299520, 0xef38fd3a
+0, 52, 52, 1, 299520, 0x4c08ea42
+0, 53, 53, 1, 299520, 0x66dd9974
+0, 54, 54, 1, 299520, 0x4af1e690
+0, 55, 55, 1, 299520, 0x3fce05be
+0, 56, 56, 1, 299520, 0x07ccca7a
+0, 57, 57, 1, 299520, 0x1113a830
+0, 58, 58, 1, 299520, 0xe095faa8
+0, 59, 59, 1, 299520, 0x01da87b4
+0, 60, 60, 1, 299520, 0xecd3ea56
+0, 61, 61, 1, 299520, 0x8b80d26b
+0, 62, 62, 1, 299520, 0x625b4844
+0, 63, 63, 1, 299520, 0x1f96bc19
+0, 64, 64, 1, 299520, 0x8de15c59
+0, 65, 65, 1, 299520, 0x8de15c59
+0, 66, 66, 1, 299520, 0xe0f88d0d
+0, 67, 67, 1, 299520, 0xe0f88d0d
+0, 68, 68, 1, 299520, 0xf951adca
+0, 69, 69, 1, 299520, 0x3159e1a0
+0, 70, 70, 1, 299520, 0xa3b9764d
+0, 71, 71, 1, 299520, 0xa294c4db
+0, 72, 72, 1, 299520, 0x9ddd0aa8
+0, 73, 73, 1, 299520, 0x47702302
+0, 74, 74, 1, 299520, 0xebd66219
+0, 75, 75, 1, 299520, 0x9daa6030
+0, 76, 76, 1, 299520, 0x74aad521
+0, 77, 77, 1, 299520, 0x74aad521
+0, 78, 78, 1, 299520, 0x6be83092
+0, 79, 79, 1, 299520, 0x87e19ded
+0, 80, 80, 1, 299520, 0x41f4552c
+0, 81, 81, 1, 299520, 0xdbbd4643
+0, 82, 82, 1, 299520, 0x85505e9d
+0, 83, 83, 1, 299520, 0x33692949
+0, 84, 84, 1, 299520, 0x2d3ded88
+0, 85, 85, 1, 299520, 0x211ed3d4
+0, 86, 86, 1, 299520, 0x9dd3c6b8
+0, 87, 87, 1, 299520, 0x96016144
+0, 88, 88, 1, 299520, 0xdb86dd3a
+0, 89, 89, 1, 299520, 0x2a07d782
+0, 90, 90, 1, 299520, 0x4baeac21
+0, 91, 91, 1, 299520, 0x9426dbd3
+0, 92, 92, 1, 299520, 0x69203a74
+0, 93, 93, 1, 299520, 0x69203a74
+0, 94, 94, 1, 299520, 0xcb3e55c2
+0, 95, 95, 1, 299520, 0xbbc8dea2
+0, 96, 96, 1, 299520, 0x19b27f0d
+0, 97, 97, 1, 299520, 0x0edb8988
+0, 98, 98, 1, 299520, 0x0b3a8feb
+0, 99, 99, 1, 299520, 0xa2a3a4b4
+0, 100, 100, 1, 299520, 0xeb26e563
+0, 101, 101, 1, 299520, 0xd3fb037e
+0, 102, 102, 1, 299520, 0x106089ed
+0, 103, 103, 1, 299520, 0x606fb6ed
+0, 104, 104, 1, 299520, 0x6e14a326
+0, 105, 105, 1, 299520, 0x875cfdab
+0, 106, 106, 1, 299520, 0xa1f316f9
+0, 107, 107, 1, 299520, 0x444fff4a
+0, 108, 108, 1, 299520, 0x9c7b6c8a
+0, 109, 109, 1, 299520, 0xffd0ffa3
+0, 110, 110, 1, 299520, 0x278941d9
+0, 111, 111, 1, 299520, 0x05a1552f
+0, 112, 112, 1, 299520, 0x5b564fbc
+0, 113, 113, 1, 299520, 0x25ffb96d
+0, 114, 114, 1, 299520, 0x6e389daf
+0, 115, 115, 1, 299520, 0x1b48132b
+0, 116, 116, 1, 299520, 0xcc9b5df0
+0, 117, 117, 1, 299520, 0xe8895d00
+0, 118, 118, 1, 299520, 0x35ea30df
+0, 119, 119, 1, 299520, 0x8dcf07b4
+0, 120, 120, 1, 299520, 0x1cf3780e
+0, 121, 121, 1, 299520, 0x5f1a6062
+0, 122, 122, 1, 299520, 0xe2ac4ed0
+0, 123, 123, 1, 299520, 0x07fe56aa
+0, 124, 124, 1, 299520, 0xe892eab8
+0, 125, 125, 1, 299520, 0xdeda11d7
+0, 126, 126, 1, 299520, 0xc8134b3f
+0, 127, 127, 1, 299520, 0x8baa039a
+0, 128, 128, 1, 299520, 0x8ec71908
+0, 129, 129, 1, 299520, 0x8ec71908
+0, 130, 130, 1, 299520, 0x73ae1f71
+0, 131, 131, 1, 299520, 0xb615e210
+0, 132, 132, 1, 299520, 0x7afe31e6
+0, 133, 133, 1, 299520, 0x38362f5b
+0, 134, 134, 1, 299520, 0xbb7c2fad
+0, 135, 135, 1, 299520, 0xe08720c1
+0, 136, 136, 1, 299520, 0xb1118297
+0, 137, 137, 1, 299520, 0x33740a04
+0, 138, 138, 1, 299520, 0x567c1e9c
+0, 139, 139, 1, 299520, 0x3911af2a
+0, 140, 140, 1, 299520, 0xec64ec95
+0, 141, 141, 1, 299520, 0x83128903
+0, 142, 142, 1, 299520, 0xd11a7835
+0, 143, 143, 1, 299520, 0xd96bc851
+0, 144, 144, 1, 299520, 0x726696ba
+0, 145, 145, 1, 299520, 0x35c6b8e4
+0, 146, 146, 1, 299520, 0xd238e317
+0, 147, 147, 1, 299520, 0xf28c861b
+0, 148, 148, 1, 299520, 0x5d49132b
+0, 149, 149, 1, 299520, 0xcbadef81
+0, 150, 150, 1, 299520, 0x1fbcfda6
+0, 151, 151, 1, 299520, 0xa18a07b6
+0, 152, 152, 1, 299520, 0xa1631bb5
+0, 153, 153, 1, 299520, 0xcb80f2d6
+0, 154, 154, 1, 299520, 0x88b23aae
+0, 155, 155, 1, 299520, 0xbaa50ebe
+0, 156, 156, 1, 299520, 0x1bc7151d
+0, 157, 157, 1, 299520, 0x7254b9a4
+0, 158, 158, 1, 299520, 0xd66682cb
+0, 159, 159, 1, 299520, 0x846c055b
+0, 160, 160, 1, 299520, 0x4d0ac94f
+0, 161, 161, 1, 299520, 0xf9a01b25
+0, 162, 162, 1, 299520, 0x193dc288
+0, 163, 163, 1, 299520, 0xf43fb875
+0, 164, 164, 1, 299520, 0xf4fd6452
+0, 165, 165, 1, 299520, 0xafcdfb2a
+0, 166, 166, 1, 299520, 0x5c342ad7
+0, 167, 167, 1, 299520, 0xfe7943ec
+0, 168, 168, 1, 299520, 0xc7e8a82d
+0, 169, 169, 1, 299520, 0x99b1ed3f
+0, 170, 170, 1, 299520, 0x4decbdb8
+0, 171, 171, 1, 299520, 0x3cb0ccc2
+0, 172, 172, 1, 299520, 0x3b210547
+0, 173, 173, 1, 299520, 0xb8dee8bf
+0, 174, 174, 1, 299520, 0x75124e85
+0, 175, 175, 1, 299520, 0xbd390ba5
+0, 176, 176, 1, 299520, 0x5030302d
+0, 177, 177, 1, 299520, 0x38a4c990
+0, 178, 178, 1, 299520, 0x6d091561
+0, 179, 179, 1, 299520, 0x4598d16a
+0, 180, 180, 1, 299520, 0xa60c8a7c
+0, 181, 181, 1, 299520, 0x1987b4ab
+0, 182, 182, 1, 299520, 0x3fc66893
+0, 183, 183, 1, 299520, 0x3fc66893
+0, 184, 184, 1, 299520, 0x84694e9d
+0, 185, 185, 1, 299520, 0x84694e9d
+0, 186, 186, 1, 299520, 0xa736933c
+0, 187, 187, 1, 299520, 0x994e35f8
+0, 188, 188, 1, 299520, 0x80999aab
+0, 189, 189, 1, 299520, 0x5cf09e35
+0, 190, 190, 1, 299520, 0x8678f05d
+0, 191, 191, 1, 299520, 0xe4ca13df
+0, 192, 192, 1, 299520, 0x0ab1fc5b
+0, 193, 193, 1, 299520, 0x949977a6
+0, 194, 194, 1, 299520, 0x0ab1fc5b
+0, 195, 195, 1, 299520, 0xb5677d4e
+0, 196, 196, 1, 299520, 0xefd5e34c
+0, 197, 197, 1, 299520, 0xfb5875da
+0, 198, 198, 1, 299520, 0x3520759c
+0, 199, 199, 1, 299520, 0xc30dbfb6
+0, 200, 200, 1, 299520, 0xcedb09c4
+0, 201, 201, 1, 299520, 0xced1dc4a
+0, 202, 202, 1, 299520, 0xcf7d3425
+0, 203, 203, 1, 299520, 0xede92113
+0, 204, 204, 1, 299520, 0x6ca1204e
+0, 205, 205, 1, 299520, 0x04a46f67
+0, 206, 206, 1, 299520, 0x1bd8fe03
+0, 207, 207, 1, 299520, 0x11dab44d
+0, 208, 208, 1, 299520, 0xc0d1109c
+0, 209, 209, 1, 299520, 0x9e19c78f
+0, 210, 210, 1, 299520, 0xcffab4cb
+0, 211, 211, 1, 299520, 0x07582785
+0, 212, 212, 1, 299520, 0x43182694
+0, 213, 213, 1, 299520, 0x76f8c058
+0, 214, 214, 1, 299520, 0x895cbd03
+0, 215, 215, 1, 299520, 0xec9f9014
+0, 216, 216, 1, 299520, 0xd9cc6c00
+0, 217, 217, 1, 299520, 0xf15c775e
+0, 218, 218, 1, 299520, 0xe4b60e06
+0, 219, 219, 1, 299520, 0x5d825ea9
+0, 220, 220, 1, 299520, 0xd39d2f4a
+0, 221, 221, 1, 299520, 0x9b8dfedc
+0, 222, 222, 1, 299520, 0xc851ce8f
+0, 223, 223, 1, 299520, 0xdc399f09
+0, 224, 224, 1, 299520, 0xbce817c6
+0, 225, 225, 1, 299520, 0x48cc865e
+0, 226, 226, 1, 299520, 0xf875c060
+0, 227, 227, 1, 299520, 0xb3b4b0a3
+0, 228, 228, 1, 299520, 0xce683731
+0, 229, 229, 1, 299520, 0xeddd5126
+0, 230, 230, 1, 299520, 0x2ecf505e
+0, 231, 231, 1, 299520, 0x631c4af2
+0, 232, 232, 1, 299520, 0x1cc7742e
+0, 233, 233, 1, 299520, 0xc5124083
+0, 234, 234, 1, 299520, 0x4a851970
+0, 235, 235, 1, 299520, 0xbfad7925
+0, 236, 236, 1, 299520, 0x92058c0e
+0, 237, 237, 1, 299520, 0x7ecd39b5
+0, 238, 238, 1, 299520, 0x58887a74
+0, 239, 239, 1, 299520, 0xb0825813
+0, 240, 240, 1, 299520, 0xbc763455
+0, 241, 241, 1, 299520, 0x3b259a45
+0, 242, 242, 1, 299520, 0xb200177c
+0, 243, 243, 1, 299520, 0x1cb15851
+0, 244, 244, 1, 299520, 0xd73a92cd
+0, 245, 245, 1, 299520, 0xe43419cf
+0, 246, 246, 1, 299520, 0xf0facff1
+0, 247, 247, 1, 299520, 0xc931e638
+0, 248, 248, 1, 299520, 0xc33e31e7
+0, 249, 249, 1, 299520, 0x03b43a26
+0, 250, 250, 1, 299520, 0x85d64d60
+0, 251, 251, 1, 299520, 0x86a8848c
+0, 252, 252, 1, 299520, 0x5f09afaf
+0, 253, 253, 1, 299520, 0xb7e92098
+0, 254, 254, 1, 299520, 0xf1957fad
+0, 255, 255, 1, 299520, 0xf29dc4b0
diff --git a/tests/ref/fate/hevc-conformance-WP_A_Toshiba_3 b/tests/ref/fate/hevc-conformance-WP_A_Toshiba_3
new file mode 100644
index 0000000..a8c5df3
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-WP_A_Toshiba_3
@@ -0,0 +1,257 @@
+#tb 0: 1/25
+0, 0, 0, 1, 149760, 0xf4bafc83
+0, 1, 1, 1, 149760, 0x611ca492
+0, 2, 2, 1, 149760, 0x8fa9bbb1
+0, 3, 3, 1, 149760, 0x3926aed3
+0, 4, 4, 1, 149760, 0x33e4f7f0
+0, 5, 5, 1, 149760, 0x03cc4fab
+0, 6, 6, 1, 149760, 0xbfae58e5
+0, 7, 7, 1, 149760, 0x0e6f1fea
+0, 8, 8, 1, 149760, 0x5a2ed57e
+0, 9, 9, 1, 149760, 0x5513cc3a
+0, 10, 10, 1, 149760, 0xd610ccca
+0, 11, 11, 1, 149760, 0xbf27617f
+0, 12, 12, 1, 149760, 0x878cd03b
+0, 13, 13, 1, 149760, 0x7b7ec3e9
+0, 14, 14, 1, 149760, 0xdaff0ba7
+0, 15, 15, 1, 149760, 0xce3be576
+0, 16, 16, 1, 149760, 0x16d32b84
+0, 17, 17, 1, 149760, 0xb7f6a144
+0, 18, 18, 1, 149760, 0x4dfb9b67
+0, 19, 19, 1, 149760, 0x29cb06ba
+0, 20, 20, 1, 149760, 0xcee5f14c
+0, 21, 21, 1, 149760, 0xe05bde26
+0, 22, 22, 1, 149760, 0xf717e789
+0, 23, 23, 1, 149760, 0xbbbf0ce8
+0, 24, 24, 1, 149760, 0x0e3ccfb1
+0, 25, 25, 1, 149760, 0x84204399
+0, 26, 26, 1, 149760, 0x02063b2b
+0, 27, 27, 1, 149760, 0xa4198aab
+0, 28, 28, 1, 149760, 0x4a4075aa
+0, 29, 29, 1, 149760, 0x1869435b
+0, 30, 30, 1, 149760, 0x04a12a8b
+0, 31, 31, 1, 149760, 0x7ab3f640
+0, 32, 32, 1, 149760, 0xba55f83a
+0, 33, 33, 1, 149760, 0xa8abaa48
+0, 34, 34, 1, 149760, 0x25483cb4
+0, 35, 35, 1, 149760, 0xc6925d6d
+0, 36, 36, 1, 149760, 0xc944b04d
+0, 37, 37, 1, 149760, 0xd7093017
+0, 38, 38, 1, 149760, 0x8d11c574
+0, 39, 39, 1, 149760, 0xdbaab3e1
+0, 40, 40, 1, 149760, 0xb412a3d9
+0, 41, 41, 1, 149760, 0x37b918a6
+0, 42, 42, 1, 149760, 0x6f6e7575
+0, 43, 43, 1, 149760, 0x059a55de
+0, 44, 44, 1, 149760, 0xe75aa6e6
+0, 45, 45, 1, 149760, 0x627394bf
+0, 46, 46, 1, 149760, 0xbcf99ab9
+0, 47, 47, 1, 149760, 0x29c52e30
+0, 48, 48, 1, 149760, 0x22056e1a
+0, 49, 49, 1, 149760, 0xf272fa39
+0, 50, 50, 1, 149760, 0x4b89033e
+0, 51, 51, 1, 149760, 0x0a59e138
+0, 52, 52, 1, 149760, 0x61a1a6c8
+0, 53, 53, 1, 149760, 0xe5414697
+0, 54, 54, 1, 149760, 0x6db38ec2
+0, 55, 55, 1, 149760, 0x2d09b0ba
+0, 56, 56, 1, 149760, 0x014a751e
+0, 57, 57, 1, 149760, 0x3e6f78d6
+0, 58, 58, 1, 149760, 0xed483aab
+0, 59, 59, 1, 149760, 0xcf366ee0
+0, 60, 60, 1, 149760, 0x4fc5e2dc
+0, 61, 61, 1, 149760, 0xf2a16393
+0, 62, 62, 1, 149760, 0xaa7ff5be
+0, 63, 63, 1, 149760, 0xa8c4c963
+0, 64, 64, 1, 149760, 0x3af766cf
+0, 65, 65, 1, 149760, 0x3af766cf
+0, 66, 66, 1, 149760, 0x11de29e7
+0, 67, 67, 1, 149760, 0x3aa137c0
+0, 68, 68, 1, 149760, 0x6f5bf4c4
+0, 69, 69, 1, 149760, 0xa5b8f392
+0, 70, 70, 1, 149760, 0x106ee459
+0, 71, 71, 1, 149760, 0x65dd99cc
+0, 72, 72, 1, 149760, 0x96facd15
+0, 73, 73, 1, 149760, 0x3355cb07
+0, 74, 74, 1, 149760, 0xe994f26b
+0, 75, 75, 1, 149760, 0xe955f0d5
+0, 76, 76, 1, 149760, 0xb740949e
+0, 77, 77, 1, 149760, 0x0b95963b
+0, 78, 78, 1, 149760, 0xdf7cf302
+0, 79, 79, 1, 149760, 0x8805c30d
+0, 80, 80, 1, 149760, 0xc30c832a
+0, 81, 81, 1, 149760, 0x696836a7
+0, 82, 82, 1, 149760, 0x696836a7
+0, 83, 83, 1, 149760, 0x4c7e0e68
+0, 84, 84, 1, 149760, 0xfee52485
+0, 85, 85, 1, 149760, 0xebbe8381
+0, 86, 86, 1, 149760, 0xb30ff0a9
+0, 87, 87, 1, 149760, 0x4ddafbfb
+0, 88, 88, 1, 149760, 0x5449c902
+0, 89, 89, 1, 149760, 0x79e61161
+0, 90, 90, 1, 149760, 0x72f1a340
+0, 91, 91, 1, 149760, 0xf98bae64
+0, 92, 92, 1, 149760, 0x253dd19f
+0, 93, 93, 1, 149760, 0x253dd19f
+0, 94, 94, 1, 149760, 0xc16e6af4
+0, 95, 95, 1, 149760, 0x66f2a539
+0, 96, 96, 1, 149760, 0xfccfd340
+0, 97, 97, 1, 149760, 0xd76a28c9
+0, 98, 98, 1, 149760, 0x38797af0
+0, 99, 99, 1, 149760, 0x06165c19
+0, 100, 100, 1, 149760, 0x9afee257
+0, 101, 101, 1, 149760, 0x1b2ce435
+0, 102, 102, 1, 149760, 0xb3e2de89
+0, 103, 103, 1, 149760, 0xb585e81f
+0, 104, 104, 1, 149760, 0x6743ece6
+0, 105, 105, 1, 149760, 0xfe5a001f
+0, 106, 106, 1, 149760, 0x064a778f
+0, 107, 107, 1, 149760, 0x99907eef
+0, 108, 108, 1, 149760, 0x1b9ec247
+0, 109, 109, 1, 149760, 0x52adad6c
+0, 110, 110, 1, 149760, 0xf5176bd9
+0, 111, 111, 1, 149760, 0xefdfa365
+0, 112, 112, 1, 149760, 0xa2e8447f
+0, 113, 113, 1, 149760, 0x3ea43a87
+0, 114, 114, 1, 149760, 0xbe643579
+0, 115, 115, 1, 149760, 0x518ae330
+0, 116, 116, 1, 149760, 0x49d815e6
+0, 117, 117, 1, 149760, 0xbfbb1bf0
+0, 118, 118, 1, 149760, 0x19596f6f
+0, 119, 119, 1, 149760, 0x4f6cbeec
+0, 120, 120, 1, 149760, 0xdd3f7460
+0, 121, 121, 1, 149760, 0xf2bb54f3
+0, 122, 122, 1, 149760, 0xb9d5d7cd
+0, 123, 123, 1, 149760, 0xe62736a5
+0, 124, 124, 1, 149760, 0x29c6f950
+0, 125, 125, 1, 149760, 0x99e1faed
+0, 126, 126, 1, 149760, 0x5c149afe
+0, 127, 127, 1, 149760, 0xb4118f9b
+0, 128, 128, 1, 149760, 0x262d7f30
+0, 129, 129, 1, 149760, 0x262d7f30
+0, 130, 130, 1, 149760, 0x13e286ed
+0, 131, 131, 1, 149760, 0xee6b3447
+0, 132, 132, 1, 149760, 0x9e749867
+0, 133, 133, 1, 149760, 0xdbca6bab
+0, 134, 134, 1, 149760, 0x154c9331
+0, 135, 135, 1, 149760, 0x653a3058
+0, 136, 136, 1, 149760, 0x739c1e57
+0, 137, 137, 1, 149760, 0x8e05e122
+0, 138, 138, 1, 149760, 0xe21f583a
+0, 139, 139, 1, 149760, 0xa58149fc
+0, 140, 140, 1, 149760, 0x90bd3787
+0, 141, 141, 1, 149760, 0x385aa42a
+0, 142, 142, 1, 149760, 0xf2589fc6
+0, 143, 143, 1, 149760, 0xd5233b3b
+0, 144, 144, 1, 149760, 0x2cc2d9cc
+0, 145, 145, 1, 149760, 0xb9b0eeef
+0, 146, 146, 1, 149760, 0xa9a60da9
+0, 147, 147, 1, 149760, 0xb854378a
+0, 148, 148, 1, 149760, 0xa76e2c37
+0, 149, 149, 1, 149760, 0xbe5c0542
+0, 150, 150, 1, 149760, 0x4d78b907
+0, 151, 151, 1, 149760, 0x6119f5d7
+0, 152, 152, 1, 149760, 0x195ae3c8
+0, 153, 153, 1, 149760, 0x35e9de61
+0, 154, 154, 1, 149760, 0x99f0df3b
+0, 155, 155, 1, 149760, 0x1a0ebfee
+0, 156, 156, 1, 149760, 0x4ece0a87
+0, 157, 157, 1, 149760, 0x670773b9
+0, 158, 158, 1, 149760, 0xae8c2789
+0, 159, 159, 1, 149760, 0xa145e3f8
+0, 160, 160, 1, 149760, 0x130d2ea3
+0, 161, 161, 1, 149760, 0x9afdf6dc
+0, 162, 162, 1, 149760, 0x8f8ed056
+0, 163, 163, 1, 149760, 0x8d50ad5c
+0, 164, 164, 1, 149760, 0x50b41bbb
+0, 165, 165, 1, 149760, 0xe8a89c0b
+0, 166, 166, 1, 149760, 0x4862c664
+0, 167, 167, 1, 149760, 0x9f99193f
+0, 168, 168, 1, 149760, 0x3d2ea4d8
+0, 169, 169, 1, 149760, 0xfcb83723
+0, 170, 170, 1, 149760, 0x2e135fe9
+0, 171, 171, 1, 149760, 0xcd059eeb
+0, 172, 172, 1, 149760, 0xcc2914ab
+0, 173, 173, 1, 149760, 0x63a4cf21
+0, 174, 174, 1, 149760, 0x0bdf9666
+0, 175, 175, 1, 149760, 0x8fcd46d9
+0, 176, 176, 1, 149760, 0xa2a94d81
+0, 177, 177, 1, 149760, 0x72da1124
+0, 178, 178, 1, 149760, 0x4faf50a2
+0, 179, 179, 1, 149760, 0x52168ea8
+0, 180, 180, 1, 149760, 0x766cd6e4
+0, 181, 181, 1, 149760, 0x9a76dd3f
+0, 182, 182, 1, 149760, 0xacf745bb
+0, 183, 183, 1, 149760, 0xacf745bb
+0, 184, 184, 1, 149760, 0x5d0f5914
+0, 185, 185, 1, 149760, 0x5d0f5914
+0, 186, 186, 1, 149760, 0x491b5959
+0, 187, 187, 1, 149760, 0xce9bf07f
+0, 188, 188, 1, 149760, 0x45123e08
+0, 189, 189, 1, 149760, 0x7ec1ced4
+0, 190, 190, 1, 149760, 0x7ec1ced4
+0, 191, 191, 1, 149760, 0xd383e72e
+0, 192, 192, 1, 149760, 0x29558d4c
+0, 193, 193, 1, 149760, 0xdcea6ec3
+0, 194, 194, 1, 149760, 0x29558d4c
+0, 195, 195, 1, 149760, 0x55b305ad
+0, 196, 196, 1, 149760, 0x68326c39
+0, 197, 197, 1, 149760, 0x89c8c0f7
+0, 198, 198, 1, 149760, 0x1fb33243
+0, 199, 199, 1, 149760, 0xa07b14e8
+0, 200, 200, 1, 149760, 0x6b37b02f
+0, 201, 201, 1, 149760, 0x7453171e
+0, 202, 202, 1, 149760, 0xec95ce93
+0, 203, 203, 1, 149760, 0xdbb0481b
+0, 204, 204, 1, 149760, 0xe44eaafd
+0, 205, 205, 1, 149760, 0xcdf5dfd5
+0, 206, 206, 1, 149760, 0x42695b4e
+0, 207, 207, 1, 149760, 0xe4e26db0
+0, 208, 208, 1, 149760, 0xada778f6
+0, 209, 209, 1, 149760, 0x77dab36a
+0, 210, 210, 1, 149760, 0xcabeb23d
+0, 211, 211, 1, 149760, 0x43d21021
+0, 212, 212, 1, 149760, 0xe4a5280c
+0, 213, 213, 1, 149760, 0xeb408a99
+0, 214, 214, 1, 149760, 0x0751fc6c
+0, 215, 215, 1, 149760, 0x2e770c68
+0, 216, 216, 1, 149760, 0x5a799fb0
+0, 217, 217, 1, 149760, 0x0e2e22dd
+0, 218, 218, 1, 149760, 0x276e6e88
+0, 219, 219, 1, 149760, 0xf83b9da4
+0, 220, 220, 1, 149760, 0xd4599290
+0, 221, 221, 1, 149760, 0xd4599290
+0, 222, 222, 1, 149760, 0xcf41ec75
+0, 223, 223, 1, 149760, 0x84af0bfc
+0, 224, 224, 1, 149760, 0x59db5c12
+0, 225, 225, 1, 149760, 0x0405a92a
+0, 226, 226, 1, 149760, 0xfde2c0fe
+0, 227, 227, 1, 149760, 0x96a68bab
+0, 228, 228, 1, 149760, 0x7e9d4983
+0, 229, 229, 1, 149760, 0x27b724c9
+0, 230, 230, 1, 149760, 0x402cdb15
+0, 231, 231, 1, 149760, 0x0d89328b
+0, 232, 232, 1, 149760, 0x08847a7e
+0, 233, 233, 1, 149760, 0x8eb7f52f
+0, 234, 234, 1, 149760, 0x49bf75bb
+0, 235, 235, 1, 149760, 0xbd6c77e3
+0, 236, 236, 1, 149760, 0x9eb5a5c0
+0, 237, 237, 1, 149760, 0xb5900c9b
+0, 238, 238, 1, 149760, 0xa9278bd6
+0, 239, 239, 1, 149760, 0x688d4c01
+0, 240, 240, 1, 149760, 0xe2669ce6
+0, 241, 241, 1, 149760, 0xb80590b9
+0, 242, 242, 1, 149760, 0xcdcc0036
+0, 243, 243, 1, 149760, 0xad653077
+0, 244, 244, 1, 149760, 0xe87179ae
+0, 245, 245, 1, 149760, 0x91553e8b
+0, 246, 246, 1, 149760, 0xd254f2b4
+0, 247, 247, 1, 149760, 0xe284e289
+0, 248, 248, 1, 149760, 0x09118405
+0, 249, 249, 1, 149760, 0x5f46d196
+0, 250, 250, 1, 149760, 0xfee1f4be
+0, 251, 251, 1, 149760, 0xbccf48bc
+0, 252, 252, 1, 149760, 0x48327792
+0, 253, 253, 1, 149760, 0x3d893b3c
+0, 254, 254, 1, 149760, 0xb2ae071d
+0, 255, 255, 1, 149760, 0x278e0be3
diff --git a/tests/ref/fate/hevc-conformance-WP_B_Toshiba_3 b/tests/ref/fate/hevc-conformance-WP_B_Toshiba_3
new file mode 100644
index 0000000..7dbc72b
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-WP_B_Toshiba_3
@@ -0,0 +1,257 @@
+#tb 0: 1/25
+0, 0, 0, 1, 149760, 0xd8bf0c39
+0, 1, 1, 1, 149760, 0xad390a29
+0, 2, 2, 1, 149760, 0x0d310906
+0, 3, 3, 1, 149760, 0x03bcb5ac
+0, 4, 4, 1, 149760, 0x6c38226f
+0, 5, 5, 1, 149760, 0xc7d898b6
+0, 6, 6, 1, 149760, 0x1e031118
+0, 7, 7, 1, 149760, 0x7a2437f2
+0, 8, 8, 1, 149760, 0x524d616a
+0, 9, 9, 1, 149760, 0x001ac80e
+0, 10, 10, 1, 149760, 0x6fe323e4
+0, 11, 11, 1, 149760, 0x2a95a125
+0, 12, 12, 1, 149760, 0x212316e4
+0, 13, 13, 1, 149760, 0x7984e2ed
+0, 14, 14, 1, 149760, 0xb0a4a95c
+0, 15, 15, 1, 149760, 0x100566ae
+0, 16, 16, 1, 149760, 0xb21b2344
+0, 17, 17, 1, 149760, 0x0578bca2
+0, 18, 18, 1, 149760, 0xf7523964
+0, 19, 19, 1, 149760, 0x38d2ca9e
+0, 20, 20, 1, 149760, 0x77890564
+0, 21, 21, 1, 149760, 0xbdba85df
+0, 22, 22, 1, 149760, 0x646ae92d
+0, 23, 23, 1, 149760, 0xfcbb58b9
+0, 24, 24, 1, 149760, 0x0122aa96
+0, 25, 25, 1, 149760, 0x60f8e1ee
+0, 26, 26, 1, 149760, 0x3fc2d587
+0, 27, 27, 1, 149760, 0xdb622c12
+0, 28, 28, 1, 149760, 0xa8df64cf
+0, 29, 29, 1, 149760, 0x12f8d6c8
+0, 30, 30, 1, 149760, 0xf6703c4d
+0, 31, 31, 1, 149760, 0x66ef211d
+0, 32, 32, 1, 149760, 0x821b02f6
+0, 33, 33, 1, 149760, 0xc87f48a0
+0, 34, 34, 1, 149760, 0xb816ad51
+0, 35, 35, 1, 149760, 0x238e6fa0
+0, 36, 36, 1, 149760, 0x0fc06010
+0, 37, 37, 1, 149760, 0x749c71dc
+0, 38, 38, 1, 149760, 0x88c69718
+0, 39, 39, 1, 149760, 0x4b29aeb1
+0, 40, 40, 1, 149760, 0xaaefb509
+0, 41, 41, 1, 149760, 0x2975fda6
+0, 42, 42, 1, 149760, 0x613ec356
+0, 43, 43, 1, 149760, 0xf1e46db6
+0, 44, 44, 1, 149760, 0x8c8aec07
+0, 45, 45, 1, 149760, 0xb9a8be75
+0, 46, 46, 1, 149760, 0xfdce756a
+0, 47, 47, 1, 149760, 0x9c76f148
+0, 48, 48, 1, 149760, 0x5d1862dd
+0, 49, 49, 1, 149760, 0x42ae08bf
+0, 50, 50, 1, 149760, 0xc28f9247
+0, 51, 51, 1, 149760, 0x719d321c
+0, 52, 52, 1, 149760, 0x1520a7bc
+0, 53, 53, 1, 149760, 0x4fb98c9a
+0, 54, 54, 1, 149760, 0x88d410a6
+0, 55, 55, 1, 149760, 0x807ac417
+0, 56, 56, 1, 149760, 0x6de5f4ab
+0, 57, 57, 1, 149760, 0x678613c7
+0, 58, 58, 1, 149760, 0xe7d12abf
+0, 59, 59, 1, 149760, 0x23955076
+0, 60, 60, 1, 149760, 0x298d1bce
+0, 61, 61, 1, 149760, 0x18d4605d
+0, 62, 62, 1, 149760, 0x3a606618
+0, 63, 63, 1, 149760, 0x861fcb5a
+0, 64, 64, 1, 149760, 0xc6622a90
+0, 65, 65, 1, 149760, 0x62d4cd48
+0, 66, 66, 1, 149760, 0x991430e6
+0, 67, 67, 1, 149760, 0x6316503c
+0, 68, 68, 1, 149760, 0xdf2d29f2
+0, 69, 69, 1, 149760, 0xeeeb307a
+0, 70, 70, 1, 149760, 0xade9ae1d
+0, 71, 71, 1, 149760, 0x54734581
+0, 72, 72, 1, 149760, 0x5ccd7389
+0, 73, 73, 1, 149760, 0xf0588bf8
+0, 74, 74, 1, 149760, 0xf18e44e5
+0, 75, 75, 1, 149760, 0x4512602b
+0, 76, 76, 1, 149760, 0x9aac8281
+0, 77, 77, 1, 149760, 0x69bdad58
+0, 78, 78, 1, 149760, 0x04ffe580
+0, 79, 79, 1, 149760, 0x28bfe45f
+0, 80, 80, 1, 149760, 0xd7ce93b0
+0, 81, 81, 1, 149760, 0xa880b1d4
+0, 82, 82, 1, 149760, 0xf38298d0
+0, 83, 83, 1, 149760, 0x2ae05958
+0, 84, 84, 1, 149760, 0xa892151b
+0, 85, 85, 1, 149760, 0xed2cef63
+0, 86, 86, 1, 149760, 0x678fc6f5
+0, 87, 87, 1, 149760, 0xfcbaa892
+0, 88, 88, 1, 149760, 0x48cc722b
+0, 89, 89, 1, 149760, 0x32cd8975
+0, 90, 90, 1, 149760, 0x05ad8586
+0, 91, 91, 1, 149760, 0x62a0fb36
+0, 92, 92, 1, 149760, 0x41df8d45
+0, 93, 93, 1, 149760, 0x80bd938d
+0, 94, 94, 1, 149760, 0xafe414b0
+0, 95, 95, 1, 149760, 0x3077d51d
+0, 96, 96, 1, 149760, 0x65148cef
+0, 97, 97, 1, 149760, 0xadb76ef0
+0, 98, 98, 1, 149760, 0x889c3051
+0, 99, 99, 1, 149760, 0xe83b227e
+0, 100, 100, 1, 149760, 0xc373f5e0
+0, 101, 101, 1, 149760, 0x6ffa2a5f
+0, 102, 102, 1, 149760, 0x6eef18f5
+0, 103, 103, 1, 149760, 0x1b1ba6e4
+0, 104, 104, 1, 149760, 0x88e316a4
+0, 105, 105, 1, 149760, 0x4c0697f4
+0, 106, 106, 1, 149760, 0x5eb30515
+0, 107, 107, 1, 149760, 0xeeff8fa3
+0, 108, 108, 1, 149760, 0x653a07a9
+0, 109, 109, 1, 149760, 0x3faf44a8
+0, 110, 110, 1, 149760, 0xe33f740e
+0, 111, 111, 1, 149760, 0x6bea0f49
+0, 112, 112, 1, 149760, 0x4d5aa784
+0, 113, 113, 1, 149760, 0x0c85ea00
+0, 114, 114, 1, 149760, 0xf64fc40b
+0, 115, 115, 1, 149760, 0xf222e3b4
+0, 116, 116, 1, 149760, 0x6b3be6bc
+0, 117, 117, 1, 149760, 0x91447dfb
+0, 118, 118, 1, 149760, 0xfd0dd98c
+0, 119, 119, 1, 149760, 0x468eb01a
+0, 120, 120, 1, 149760, 0x928a720a
+0, 121, 121, 1, 149760, 0x0b3f576b
+0, 122, 122, 1, 149760, 0x430493df
+0, 123, 123, 1, 149760, 0x375d2221
+0, 124, 124, 1, 149760, 0x50d0a88c
+0, 125, 125, 1, 149760, 0x54363ffb
+0, 126, 126, 1, 149760, 0xc243c434
+0, 127, 127, 1, 149760, 0x26fe8f5c
+0, 128, 128, 1, 149760, 0xd936485c
+0, 129, 129, 1, 149760, 0xd936485c
+0, 130, 130, 1, 149760, 0xa0cabe5a
+0, 131, 131, 1, 149760, 0xf0956484
+0, 132, 132, 1, 149760, 0x14cda6ee
+0, 133, 133, 1, 149760, 0x0b7ada70
+0, 134, 134, 1, 149760, 0x113f0ec5
+0, 135, 135, 1, 149760, 0xc1364acc
+0, 136, 136, 1, 149760, 0x0c768a6a
+0, 137, 137, 1, 149760, 0x94fd7a00
+0, 138, 138, 1, 149760, 0x624a5ebb
+0, 139, 139, 1, 149760, 0xdd5008a0
+0, 140, 140, 1, 149760, 0xc380626c
+0, 141, 141, 1, 149760, 0xb0974c02
+0, 142, 142, 1, 149760, 0x68be6c1e
+0, 143, 143, 1, 149760, 0xb8d24677
+0, 144, 144, 1, 149760, 0x1efe195c
+0, 145, 145, 1, 149760, 0x29e9153a
+0, 146, 146, 1, 149760, 0x1b6057b7
+0, 147, 147, 1, 149760, 0x959a4461
+0, 148, 148, 1, 149760, 0x4e3d33a9
+0, 149, 149, 1, 149760, 0x206e7899
+0, 150, 150, 1, 149760, 0xcb7da081
+0, 151, 151, 1, 149760, 0xc650ed7b
+0, 152, 152, 1, 149760, 0x82832d10
+0, 153, 153, 1, 149760, 0xdf9c6218
+0, 154, 154, 1, 149760, 0xcc3489c7
+0, 155, 155, 1, 149760, 0xd284a4a1
+0, 156, 156, 1, 149760, 0x7099451c
+0, 157, 157, 1, 149760, 0xec26fc56
+0, 158, 158, 1, 149760, 0x105a496f
+0, 159, 159, 1, 149760, 0xb8756fe8
+0, 160, 160, 1, 149760, 0xb1a509df
+0, 161, 161, 1, 149760, 0x135f8f7e
+0, 162, 162, 1, 149760, 0x3419098d
+0, 163, 163, 1, 149760, 0xa55dad5f
+0, 164, 164, 1, 149760, 0x326ba794
+0, 165, 165, 1, 149760, 0x5401b03c
+0, 166, 166, 1, 149760, 0x3ace76ee
+0, 167, 167, 1, 149760, 0x140191ac
+0, 168, 168, 1, 149760, 0x3e3ca195
+0, 169, 169, 1, 149760, 0x2a8b3622
+0, 170, 170, 1, 149760, 0x9e33c765
+0, 171, 171, 1, 149760, 0xf7795367
+0, 172, 172, 1, 149760, 0xa7909e25
+0, 173, 173, 1, 149760, 0x44a5a014
+0, 174, 174, 1, 149760, 0x919bb07c
+0, 175, 175, 1, 149760, 0xd353b9a7
+0, 176, 176, 1, 149760, 0x4c3dda24
+0, 177, 177, 1, 149760, 0x1428eafb
+0, 178, 178, 1, 149760, 0x9d9fa613
+0, 179, 179, 1, 149760, 0x661475c6
+0, 180, 180, 1, 149760, 0x5f6f4180
+0, 181, 181, 1, 149760, 0xf50a4b4c
+0, 182, 182, 1, 149760, 0xf6373eb9
+0, 183, 183, 1, 149760, 0x0ab24b74
+0, 184, 184, 1, 149760, 0x6b3d58b0
+0, 185, 185, 1, 149760, 0xc4c8bd05
+0, 186, 186, 1, 149760, 0x0df172c6
+0, 187, 187, 1, 149760, 0x81a85144
+0, 188, 188, 1, 149760, 0x7f926ee5
+0, 189, 189, 1, 149760, 0x3a355d45
+0, 190, 190, 1, 149760, 0x9f645c90
+0, 191, 191, 1, 149760, 0xf42674ea
+0, 192, 192, 1, 149760, 0xa6e943ab
+0, 193, 193, 1, 149760, 0xede16b49
+0, 194, 194, 1, 149760, 0xf80c9957
+0, 195, 195, 1, 149760, 0xa7a44665
+0, 196, 196, 1, 149760, 0x08f17b20
+0, 197, 197, 1, 149760, 0x0319e942
+0, 198, 198, 1, 149760, 0xab69057c
+0, 199, 199, 1, 149760, 0xb98814f4
+0, 200, 200, 1, 149760, 0xa172e6d0
+0, 201, 201, 1, 149760, 0x6cd35cd1
+0, 202, 202, 1, 149760, 0x7352b4b9
+0, 203, 203, 1, 149760, 0x07cbdedd
+0, 204, 204, 1, 149760, 0xbe7aa3c8
+0, 205, 205, 1, 149760, 0xdcbc8993
+0, 206, 206, 1, 149760, 0x0c5dbf95
+0, 207, 207, 1, 149760, 0x107e4f2c
+0, 208, 208, 1, 149760, 0xc650e333
+0, 209, 209, 1, 149760, 0x46abae6f
+0, 210, 210, 1, 149760, 0x0e41309d
+0, 211, 211, 1, 149760, 0x831e19a1
+0, 212, 212, 1, 149760, 0xd1955874
+0, 213, 213, 1, 149760, 0x486c41bb
+0, 214, 214, 1, 149760, 0xba020143
+0, 215, 215, 1, 149760, 0x3ebedef4
+0, 216, 216, 1, 149760, 0xda7bc235
+0, 217, 217, 1, 149760, 0x0abcb13e
+0, 218, 218, 1, 149760, 0xdf5159ac
+0, 219, 219, 1, 149760, 0x4e39d893
+0, 220, 220, 1, 149760, 0x393f382d
+0, 221, 221, 1, 149760, 0x92556867
+0, 222, 222, 1, 149760, 0x2daf47a8
+0, 223, 223, 1, 149760, 0x792a4448
+0, 224, 224, 1, 149760, 0x429e05ad
+0, 225, 225, 1, 149760, 0x89caaa32
+0, 226, 226, 1, 149760, 0xa70ec97b
+0, 227, 227, 1, 149760, 0xce0d24b7
+0, 228, 228, 1, 149760, 0x04be745d
+0, 229, 229, 1, 149760, 0xfb04d3d2
+0, 230, 230, 1, 149760, 0x5b472952
+0, 231, 231, 1, 149760, 0x6cd704b5
+0, 232, 232, 1, 149760, 0x18b0db7e
+0, 233, 233, 1, 149760, 0xdfb24e07
+0, 234, 234, 1, 149760, 0x6d9bae45
+0, 235, 235, 1, 149760, 0xf2eb5756
+0, 236, 236, 1, 149760, 0xdf858203
+0, 237, 237, 1, 149760, 0xdcd4822f
+0, 238, 238, 1, 149760, 0x80ceabaf
+0, 239, 239, 1, 149760, 0x8bd1a92f
+0, 240, 240, 1, 149760, 0x981a61ca
+0, 241, 241, 1, 149760, 0x5fa92603
+0, 242, 242, 1, 149760, 0xbb28f8da
+0, 243, 243, 1, 149760, 0x1710666d
+0, 244, 244, 1, 149760, 0xf928099a
+0, 245, 245, 1, 149760, 0x2e0ae9cb
+0, 246, 246, 1, 149760, 0xcf0e402c
+0, 247, 247, 1, 149760, 0x48e5b987
+0, 248, 248, 1, 149760, 0x7dc42853
+0, 249, 249, 1, 149760, 0x25f4aef0
+0, 250, 250, 1, 149760, 0x5f1d37b3
+0, 251, 251, 1, 149760, 0xb2fabf9f
+0, 252, 252, 1, 149760, 0xe87348ee
+0, 253, 253, 1, 149760, 0xbe9ec00f
+0, 254, 254, 1, 149760, 0xd67d1fb2
+0, 255, 255, 1, 149760, 0x92db1ca8
diff --git a/tests/ref/fate/hevc-conformance-WP_MAIN10_B_Toshiba_3 b/tests/ref/fate/hevc-conformance-WP_MAIN10_B_Toshiba_3
new file mode 100644
index 0000000..332c7df
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-WP_MAIN10_B_Toshiba_3
@@ -0,0 +1,257 @@
+#tb 0: 1/25
+0, 0, 0, 1, 299520, 0x6ecba46b
+0, 1, 1, 1, 299520, 0x54e6ef0a
+0, 2, 2, 1, 299520, 0x7a4d46c5
+0, 3, 3, 1, 299520, 0xccd57f4e
+0, 4, 4, 1, 299520, 0xbe0cb48d
+0, 5, 5, 1, 299520, 0x10e7b49f
+0, 6, 6, 1, 299520, 0x81aa72e2
+0, 7, 7, 1, 299520, 0x5bf7b51f
+0, 8, 8, 1, 299520, 0xfcedee4a
+0, 9, 9, 1, 299520, 0x586c99b6
+0, 10, 10, 1, 299520, 0x414ca13c
+0, 11, 11, 1, 299520, 0x3f0162f2
+0, 12, 12, 1, 299520, 0x4d450c05
+0, 13, 13, 1, 299520, 0x0a58bd84
+0, 14, 14, 1, 299520, 0x26e8394d
+0, 15, 15, 1, 299520, 0xfd78121b
+0, 16, 16, 1, 299520, 0x6afeaf44
+0, 17, 17, 1, 299520, 0x3e9a9270
+0, 18, 18, 1, 299520, 0x58b889ca
+0, 19, 19, 1, 299520, 0x0245ba62
+0, 20, 20, 1, 299520, 0xddecc5ab
+0, 21, 21, 1, 299520, 0x32cf3cd9
+0, 22, 22, 1, 299520, 0x5c0a0440
+0, 23, 23, 1, 299520, 0x9d3e2fee
+0, 24, 24, 1, 299520, 0x2894c708
+0, 25, 25, 1, 299520, 0x25be67d5
+0, 26, 26, 1, 299520, 0xe3ece9d6
+0, 27, 27, 1, 299520, 0xcc98e38b
+0, 28, 28, 1, 299520, 0xc448c794
+0, 29, 29, 1, 299520, 0xb4f75575
+0, 30, 30, 1, 299520, 0xac74a437
+0, 31, 31, 1, 299520, 0x09c7f2e2
+0, 32, 32, 1, 299520, 0xbfaed8ab
+0, 33, 33, 1, 299520, 0xb077d700
+0, 34, 34, 1, 299520, 0x6efa0545
+0, 35, 35, 1, 299520, 0xb8c1802d
+0, 36, 36, 1, 299520, 0x794774f8
+0, 37, 37, 1, 299520, 0x1098f4ff
+0, 38, 38, 1, 299520, 0x80ab8bfc
+0, 39, 39, 1, 299520, 0xc324c3bc
+0, 40, 40, 1, 299520, 0x1eee77cd
+0, 41, 41, 1, 299520, 0x7147e72e
+0, 42, 42, 1, 299520, 0x1a34883c
+0, 43, 43, 1, 299520, 0x74e93e31
+0, 44, 44, 1, 299520, 0x89410382
+0, 45, 45, 1, 299520, 0xfcce0ce1
+0, 46, 46, 1, 299520, 0x07bb33c6
+0, 47, 47, 1, 299520, 0xc1ee7318
+0, 48, 48, 1, 299520, 0xd1c4bd2d
+0, 49, 49, 1, 299520, 0xa670cfae
+0, 50, 50, 1, 299520, 0x718de79b
+0, 51, 51, 1, 299520, 0x85e40b78
+0, 52, 52, 1, 299520, 0x15362e72
+0, 53, 53, 1, 299520, 0xc6e523fa
+0, 54, 54, 1, 299520, 0x3e536edd
+0, 55, 55, 1, 299520, 0x9312996e
+0, 56, 56, 1, 299520, 0x9456d53c
+0, 57, 57, 1, 299520, 0x7bc01398
+0, 58, 58, 1, 299520, 0x5a40bcb4
+0, 59, 59, 1, 299520, 0xcfe126ce
+0, 60, 60, 1, 299520, 0xd9e1adf1
+0, 61, 61, 1, 299520, 0x9027b1ae
+0, 62, 62, 1, 299520, 0x4c1372fb
+0, 63, 63, 1, 299520, 0xe475a00b
+0, 64, 64, 1, 299520, 0x945bc646
+0, 65, 65, 1, 299520, 0xc33dbab3
+0, 66, 66, 1, 299520, 0x9e4afb82
+0, 67, 67, 1, 299520, 0x1bffa858
+0, 68, 68, 1, 299520, 0x3bc78ad7
+0, 69, 69, 1, 299520, 0xa096e683
+0, 70, 70, 1, 299520, 0xb889aa23
+0, 71, 71, 1, 299520, 0x8ffad857
+0, 72, 72, 1, 299520, 0x59d3cc7c
+0, 73, 73, 1, 299520, 0x47d1377a
+0, 74, 74, 1, 299520, 0xea73e864
+0, 75, 75, 1, 299520, 0x0994bd5c
+0, 76, 76, 1, 299520, 0xdf779d85
+0, 77, 77, 1, 299520, 0x8238cfa7
+0, 78, 78, 1, 299520, 0x8f2e94cc
+0, 79, 79, 1, 299520, 0x9e0b0df8
+0, 80, 80, 1, 299520, 0x98ac1ce5
+0, 81, 81, 1, 299520, 0xc1c293ed
+0, 82, 82, 1, 299520, 0x1f1dfedb
+0, 83, 83, 1, 299520, 0xe7297d56
+0, 84, 84, 1, 299520, 0xa1390726
+0, 85, 85, 1, 299520, 0xf0e828e8
+0, 86, 86, 1, 299520, 0x108b8291
+0, 87, 87, 1, 299520, 0xd8830efb
+0, 88, 88, 1, 299520, 0xeee3d2f0
+0, 89, 89, 1, 299520, 0xa35d5b29
+0, 90, 90, 1, 299520, 0xa14d0840
+0, 91, 91, 1, 299520, 0xfa894a56
+0, 92, 92, 1, 299520, 0xd50005b5
+0, 93, 93, 1, 299520, 0xba625134
+0, 94, 94, 1, 299520, 0xce7dd782
+0, 95, 95, 1, 299520, 0x9e04e32f
+0, 96, 96, 1, 299520, 0x07e6d466
+0, 97, 97, 1, 299520, 0x4e66e1d4
+0, 98, 98, 1, 299520, 0x80aa6be6
+0, 99, 99, 1, 299520, 0xa4564be8
+0, 100, 100, 1, 299520, 0x7d34e443
+0, 101, 101, 1, 299520, 0xd5a08c86
+0, 102, 102, 1, 299520, 0xa73e63e8
+0, 103, 103, 1, 299520, 0x93937eb2
+0, 104, 104, 1, 299520, 0x0c08ba8f
+0, 105, 105, 1, 299520, 0x1d6b1a8c
+0, 106, 106, 1, 299520, 0x2e0272b4
+0, 107, 107, 1, 299520, 0x47177676
+0, 108, 108, 1, 299520, 0x6af7ffce
+0, 109, 109, 1, 299520, 0x0564a4bc
+0, 110, 110, 1, 299520, 0x7f664100
+0, 111, 111, 1, 299520, 0x6decd6ae
+0, 112, 112, 1, 299520, 0xb2d94adc
+0, 113, 113, 1, 299520, 0x55d33809
+0, 114, 114, 1, 299520, 0x5b126674
+0, 115, 115, 1, 299520, 0xd25d5750
+0, 116, 116, 1, 299520, 0x789a7f89
+0, 117, 117, 1, 299520, 0xdd082ab2
+0, 118, 118, 1, 299520, 0x3e6132ee
+0, 119, 119, 1, 299520, 0xe48209ca
+0, 120, 120, 1, 299520, 0x707d3b24
+0, 121, 121, 1, 299520, 0x8af19539
+0, 122, 122, 1, 299520, 0x0bbb4c38
+0, 123, 123, 1, 299520, 0xaaba4bd6
+0, 124, 124, 1, 299520, 0xa325d79e
+0, 125, 125, 1, 299520, 0x2bd4b64a
+0, 126, 126, 1, 299520, 0xab0c59a7
+0, 127, 127, 1, 299520, 0x260a56fc
+0, 128, 128, 1, 299520, 0xa1a55847
+0, 129, 129, 1, 299520, 0xa1a55847
+0, 130, 130, 1, 299520, 0x01438514
+0, 131, 131, 1, 299520, 0xa511e8bd
+0, 132, 132, 1, 299520, 0x7ebfd5b9
+0, 133, 133, 1, 299520, 0xdf4f1365
+0, 134, 134, 1, 299520, 0x6266911a
+0, 135, 135, 1, 299520, 0xe8eefcab
+0, 136, 136, 1, 299520, 0x7e74ca0d
+0, 137, 137, 1, 299520, 0x4b21d349
+0, 138, 138, 1, 299520, 0xa8b9ef41
+0, 139, 139, 1, 299520, 0x3187ee5b
+0, 140, 140, 1, 299520, 0x3fadb935
+0, 141, 141, 1, 299520, 0x8dca0391
+0, 142, 142, 1, 299520, 0x68215cc6
+0, 143, 143, 1, 299520, 0x7c81f366
+0, 144, 144, 1, 299520, 0x1a976381
+0, 145, 145, 1, 299520, 0x8ac095f4
+0, 146, 146, 1, 299520, 0xf5f8752b
+0, 147, 147, 1, 299520, 0xd8c03c80
+0, 148, 148, 1, 299520, 0x445a2e07
+0, 149, 149, 1, 299520, 0xddb83c6f
+0, 150, 150, 1, 299520, 0xc6dfe76a
+0, 151, 151, 1, 299520, 0x860a120f
+0, 152, 152, 1, 299520, 0x1ec91a95
+0, 153, 153, 1, 299520, 0x0180cc49
+0, 154, 154, 1, 299520, 0x63a115e3
+0, 155, 155, 1, 299520, 0x8848e971
+0, 156, 156, 1, 299520, 0x49246622
+0, 157, 157, 1, 299520, 0x3169db32
+0, 158, 158, 1, 299520, 0xcf01d8a3
+0, 159, 159, 1, 299520, 0x57a1a9c1
+0, 160, 160, 1, 299520, 0x517670eb
+0, 161, 161, 1, 299520, 0x4e2e6b5a
+0, 162, 162, 1, 299520, 0x06240a68
+0, 163, 163, 1, 299520, 0xa0d076a1
+0, 164, 164, 1, 299520, 0xb73c4515
+0, 165, 165, 1, 299520, 0x9f523268
+0, 166, 166, 1, 299520, 0x6fdcc6a2
+0, 167, 167, 1, 299520, 0xf3f5b69f
+0, 168, 168, 1, 299520, 0xce33a286
+0, 169, 169, 1, 299520, 0xce46e834
+0, 170, 170, 1, 299520, 0x14a6fe0d
+0, 171, 171, 1, 299520, 0x39a8145f
+0, 172, 172, 1, 299520, 0x91981d47
+0, 173, 173, 1, 299520, 0x1507d9be
+0, 174, 174, 1, 299520, 0x4525d4a2
+0, 175, 175, 1, 299520, 0x95e058ab
+0, 176, 176, 1, 299520, 0x8de2438a
+0, 177, 177, 1, 299520, 0xf43dc0ff
+0, 178, 178, 1, 299520, 0xaf232f4b
+0, 179, 179, 1, 299520, 0x8adabd81
+0, 180, 180, 1, 299520, 0x1e837b72
+0, 181, 181, 1, 299520, 0xb79f811d
+0, 182, 182, 1, 299520, 0x1532fb05
+0, 183, 183, 1, 299520, 0x2e3f6341
+0, 184, 184, 1, 299520, 0x10c82269
+0, 185, 185, 1, 299520, 0x8c39bd0c
+0, 186, 186, 1, 299520, 0x64fefe7b
+0, 187, 187, 1, 299520, 0x3ef6d5c7
+0, 188, 188, 1, 299520, 0x571c1edc
+0, 189, 189, 1, 299520, 0xe9e1584c
+0, 190, 190, 1, 299520, 0xd150a0db
+0, 191, 191, 1, 299520, 0x5d140f2d
+0, 192, 192, 1, 299520, 0xea00f302
+0, 193, 193, 1, 299520, 0xdd4e0fc4
+0, 194, 194, 1, 299520, 0x51c760fa
+0, 195, 195, 1, 299520, 0x68d5d26e
+0, 196, 196, 1, 299520, 0xde594a02
+0, 197, 197, 1, 299520, 0xac6d361a
+0, 198, 198, 1, 299520, 0xef6506ae
+0, 199, 199, 1, 299520, 0x744737a8
+0, 200, 200, 1, 299520, 0x2bd0834b
+0, 201, 201, 1, 299520, 0x348a8d0f
+0, 202, 202, 1, 299520, 0x93e165c8
+0, 203, 203, 1, 299520, 0x208d305c
+0, 204, 204, 1, 299520, 0xb927ed9a
+0, 205, 205, 1, 299520, 0xd252b13a
+0, 206, 206, 1, 299520, 0x11a59b2d
+0, 207, 207, 1, 299520, 0xc27785d0
+0, 208, 208, 1, 299520, 0x5c654cb5
+0, 209, 209, 1, 299520, 0x3d03a387
+0, 210, 210, 1, 299520, 0xdb0dc19d
+0, 211, 211, 1, 299520, 0x2ef3bbba
+0, 212, 212, 1, 299520, 0x7d36cd79
+0, 213, 213, 1, 299520, 0xa9ceca1e
+0, 214, 214, 1, 299520, 0x33db4d99
+0, 215, 215, 1, 299520, 0x8d28a55e
+0, 216, 216, 1, 299520, 0x554864a6
+0, 217, 217, 1, 299520, 0x6a336557
+0, 218, 218, 1, 299520, 0xd2285832
+0, 219, 219, 1, 299520, 0x9509f5f8
+0, 220, 220, 1, 299520, 0x8e479b03
+0, 221, 221, 1, 299520, 0x9513a8c3
+0, 222, 222, 1, 299520, 0x81080fac
+0, 223, 223, 1, 299520, 0x6c447b69
+0, 224, 224, 1, 299520, 0xbf4c2fbd
+0, 225, 225, 1, 299520, 0x1a77306e
+0, 226, 226, 1, 299520, 0xd485864b
+0, 227, 227, 1, 299520, 0x4e87b787
+0, 228, 228, 1, 299520, 0xe28e7153
+0, 229, 229, 1, 299520, 0x2ab24b9b
+0, 230, 230, 1, 299520, 0xffcb7357
+0, 231, 231, 1, 299520, 0x5e1e2b7e
+0, 232, 232, 1, 299520, 0x58d39e6d
+0, 233, 233, 1, 299520, 0x4a2b836a
+0, 234, 234, 1, 299520, 0xa1728e1e
+0, 235, 235, 1, 299520, 0x33e5bdd4
+0, 236, 236, 1, 299520, 0x3b144d98
+0, 237, 237, 1, 299520, 0xe72c4de2
+0, 238, 238, 1, 299520, 0x031350cb
+0, 239, 239, 1, 299520, 0x146fba58
+0, 240, 240, 1, 299520, 0x1b6679c7
+0, 241, 241, 1, 299520, 0x27e9d545
+0, 242, 242, 1, 299520, 0x5105beeb
+0, 243, 243, 1, 299520, 0x80284fd3
+0, 244, 244, 1, 299520, 0x426a5d65
+0, 245, 245, 1, 299520, 0xdcc33f89
+0, 246, 246, 1, 299520, 0x29e805ec
+0, 247, 247, 1, 299520, 0x89a09ed9
+0, 248, 248, 1, 299520, 0x60ad258c
+0, 249, 249, 1, 299520, 0xb44ee9b1
+0, 250, 250, 1, 299520, 0x184d6a88
+0, 251, 251, 1, 299520, 0xb4c8cefe
+0, 252, 252, 1, 299520, 0x358a0407
+0, 253, 253, 1, 299520, 0xa5cb97eb
+0, 254, 254, 1, 299520, 0x3d6a096e
+0, 255, 255, 1, 299520, 0xcb266e78
diff --git a/tests/ref/fate/hevc-conformance-cip_B_NEC_2 b/tests/ref/fate/hevc-conformance-cip_B_NEC_2
new file mode 100644
index 0000000..016f0f1
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-cip_B_NEC_2
@@ -0,0 +1,6 @@
+#tb 0: 1/25
+0, 0, 0, 1, 149760, 0xcbda260f
+0, 1, 1, 1, 149760, 0xbd8d32a9
+0, 2, 2, 1, 149760, 0x39562006
+0, 3, 3, 1, 149760, 0xbc62475b
+0, 4, 4, 1, 149760, 0x1bf1fb79
diff --git a/tests/ref/fate/hevc-conformance-ipcm_A_NEC_2 b/tests/ref/fate/hevc-conformance-ipcm_A_NEC_2
new file mode 100644
index 0000000..145f590
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-ipcm_A_NEC_2
@@ -0,0 +1,2 @@
+#tb 0: 1/25
+0, 0, 0, 1, 149760, 0x2356474c
diff --git a/tests/ref/fate/hevc-conformance-ipcm_B_NEC_2 b/tests/ref/fate/hevc-conformance-ipcm_B_NEC_2
new file mode 100644
index 0000000..d917cbc
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-ipcm_B_NEC_2
@@ -0,0 +1,2 @@
+#tb 0: 1/25
+0, 0, 0, 1, 149760, 0xc80d43f8
diff --git a/tests/ref/fate/hevc-conformance-ipcm_C_NEC_2 b/tests/ref/fate/hevc-conformance-ipcm_C_NEC_2
new file mode 100644
index 0000000..6c89cea
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-ipcm_C_NEC_2
@@ -0,0 +1,2 @@
+#tb 0: 1/25
+0, 0, 0, 1, 149760, 0xb92d38ee
diff --git a/tests/ref/fate/hevc-conformance-ipcm_D_NEC_2 b/tests/ref/fate/hevc-conformance-ipcm_D_NEC_2
new file mode 100644
index 0000000..2ccff05
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-ipcm_D_NEC_2
@@ -0,0 +1,2 @@
+#tb 0: 1/25
+0, 0, 0, 1, 149760, 0xa24d17f8
diff --git a/tests/ref/fate/utvideoenc_rgb_left b/tests/ref/fate/utvideoenc_rgb_left
index 99d1182..87d5f27 100644
--- a/tests/ref/fate/utvideoenc_rgb_left
+++ b/tests/ref/fate/utvideoenc_rgb_left
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1/25
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 182328, cd084b244939d7e0008d8e5ab3429dc1
0, 1, 1, 1, 182336, c9c40672750f372134185901147fb776
0, 2, 2, 1, 182956, c728911ca73225f2dc7453533c9be95e
diff --git a/tests/ref/fate/utvideoenc_rgb_median b/tests/ref/fate/utvideoenc_rgb_median
index 5983ddf..3d4c22b 100644
--- a/tests/ref/fate/utvideoenc_rgb_median
+++ b/tests/ref/fate/utvideoenc_rgb_median
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1/25
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 182160, abcf4f477f74b696faca2fcff1f62aa9
0, 1, 1, 1, 182104, 7cbcf339fa40c24522067295b39d637f
0, 2, 2, 1, 183108, dfc2c418f4379a89654c16b34ff19446
diff --git a/tests/ref/fate/utvideoenc_rgb_none b/tests/ref/fate/utvideoenc_rgb_none
index d6c6962..207c688 100644
--- a/tests/ref/fate/utvideoenc_rgb_none
+++ b/tests/ref/fate/utvideoenc_rgb_none
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1/25
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 301052, 8645cb98470205cceea3c2026223b69f
0, 1, 1, 1, 301068, 9123c3c31ac0bc0832bb07e8c6d5b372
0, 2, 2, 1, 300840, 394aa034eba2b306efa8171efc5fb960
diff --git a/tests/ref/fate/utvideoenc_rgba_left b/tests/ref/fate/utvideoenc_rgba_left
index 757febe..79a4ba7 100644
--- a/tests/ref/fate/utvideoenc_rgba_left
+++ b/tests/ref/fate/utvideoenc_rgba_left
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1/25
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 195264, 5869dee2126d98ecc1fab1e69720906a
0, 1, 1, 1, 195272, 1bd08dcde1061b0d9273bdc6dd901382
0, 2, 2, 1, 195892, 2b3fc3632bcd1cc44f777fb97a56f79b
diff --git a/tests/ref/fate/utvideoenc_rgba_median b/tests/ref/fate/utvideoenc_rgba_median
index 1198a33..88adb0c 100644
--- a/tests/ref/fate/utvideoenc_rgba_median
+++ b/tests/ref/fate/utvideoenc_rgba_median
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1/25
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 195096, 29ad3287ab4d7f4d46968c6d38ba049b
0, 1, 1, 1, 195040, 2c7b4f5f0aee96dca6dc30ce01b3c74d
0, 2, 2, 1, 196044, 7ffc6ab3c4a2eee436ef6a59c72ffb04
diff --git a/tests/ref/fate/utvideoenc_rgba_none b/tests/ref/fate/utvideoenc_rgba_none
index 555409f..3221277 100644
--- a/tests/ref/fate/utvideoenc_rgba_none
+++ b/tests/ref/fate/utvideoenc_rgba_none
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1/25
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 301312, 6912d70f7c20db0b5079a99443ffe65c
0, 1, 1, 1, 301328, 53f1b7d3c2f87ecfe9c9d305771421c5
0, 2, 2, 1, 301100, 7040f2b50dc10b2565fa899ba007983d
diff --git a/tests/ref/fate/utvideoenc_yuv420_left b/tests/ref/fate/utvideoenc_yuv420_left
index cec5a28..0ce4f9d 100644
--- a/tests/ref/fate/utvideoenc_yuv420_left
+++ b/tests/ref/fate/utvideoenc_yuv420_left
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1/25
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 59796, a7136363bc4b9ac663178e5c7f24bae7
0, 1, 1, 1, 60012, d296cf24776234599e22526598de838c
0, 2, 2, 1, 61040, e889f81df51b75acf8131de97f9da4e3
diff --git a/tests/ref/fate/utvideoenc_yuv420_median b/tests/ref/fate/utvideoenc_yuv420_median
index ddd074b..a730f48 100644
--- a/tests/ref/fate/utvideoenc_yuv420_median
+++ b/tests/ref/fate/utvideoenc_yuv420_median
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1/25
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 62876, c21650baa099fb2dfd35d4f8ddce16d1
0, 1, 1, 1, 62832, 034a1996d13c15ee0bf482ddc398aac9
0, 2, 2, 1, 64076, 1f39fd5fc926195b90a3374682a80eac
diff --git a/tests/ref/fate/utvideoenc_yuv420_none b/tests/ref/fate/utvideoenc_yuv420_none
index 555eee2..b960760 100644
--- a/tests/ref/fate/utvideoenc_yuv420_none
+++ b/tests/ref/fate/utvideoenc_yuv420_none
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1/25
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 144508, 83af3948090ebb44a0091815e4edc61e
0, 1, 1, 1, 144496, 950742e357ee489fcda4f783b8df3b4c
0, 2, 2, 1, 144376, 4b818cf0a50e9338fea26101073e445e
diff --git a/tests/ref/fate/utvideoenc_yuv422_left b/tests/ref/fate/utvideoenc_yuv422_left
index d9afc2c..069a221 100644
--- a/tests/ref/fate/utvideoenc_yuv422_left
+++ b/tests/ref/fate/utvideoenc_yuv422_left
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1/25
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 91788, e14e576f1f9abd095f13ceca627adb59
0, 1, 1, 1, 92140, 4b7db11c2d35fa91ff1b6f65c184e3fa
0, 2, 2, 1, 93268, 6ef5cb83a4db2afbf14467cbc4b6c4f7
diff --git a/tests/ref/fate/utvideoenc_yuv422_median b/tests/ref/fate/utvideoenc_yuv422_median
index e1c8fcd..cb9ca44 100644
--- a/tests/ref/fate/utvideoenc_yuv422_median
+++ b/tests/ref/fate/utvideoenc_yuv422_median
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1/25
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 89732, 698174b0d0d68e98774363ca7926f6e1
0, 1, 1, 1, 89652, f0789b7c32ef44207dfc5a454bb5ccee
0, 2, 2, 1, 90868, 6df1dcb1957efca736e88adfbad8557b
diff --git a/tests/ref/fate/utvideoenc_yuv422_none b/tests/ref/fate/utvideoenc_yuv422_none
index ca77177..d15235c 100644
--- a/tests/ref/fate/utvideoenc_yuv422_none
+++ b/tests/ref/fate/utvideoenc_yuv422_none
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1/25
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 191800, 0e1d199f87997ba47e98596b6087d7d4
0, 1, 1, 1, 191820, b35714d0635214095ac06d35da00ed32
0, 2, 2, 1, 191668, 8336829e44f5b90034e5da33dcd27f1f
diff --git a/tests/ref/fate/vcr2 b/tests/ref/fate/vcr2
new file mode 100644
index 0000000..ab70d29
--- /dev/null
+++ b/tests/ref/fate/vcr2
@@ -0,0 +1,158 @@
+#tb 0: 12/539
+0, 0, 0, 1, 38016, 0x50e93e0d
+0, 3, 3, 1, 38016, 0x6ac8627d
+0, 6, 6, 1, 38016, 0x6f38661e
+0, 9, 9, 1, 38016, 0x18bb3e23
+0, 12, 12, 1, 38016, 0x2029f4da
+0, 15, 15, 1, 38016, 0xa981eeb9
+0, 18, 18, 1, 38016, 0x65c636ef
+0, 21, 21, 1, 38016, 0x8218f178
+0, 24, 24, 1, 38016, 0xc3986e18
+0, 27, 27, 1, 38016, 0xac871f50
+0, 30, 30, 1, 38016, 0xe83ed617
+0, 33, 33, 1, 38016, 0xe87c4132
+0, 36, 36, 1, 38016, 0x9e03c321
+0, 39, 39, 1, 38016, 0x81f06a6e
+0, 42, 42, 1, 38016, 0x4ce15039
+0, 45, 45, 1, 38016, 0x398dfbdd
+0, 48, 48, 1, 38016, 0x3049218c
+0, 51, 51, 1, 38016, 0x6d90bb3f
+0, 54, 54, 1, 38016, 0x5b61ae57
+0, 57, 57, 1, 38016, 0xaf17011d
+0, 60, 60, 1, 38016, 0xb6c13da6
+0, 63, 63, 1, 38016, 0xb58135cf
+0, 66, 66, 1, 38016, 0x051c33ce
+0, 69, 69, 1, 38016, 0xda950393
+0, 72, 72, 1, 38016, 0x76f7ea61
+0, 75, 75, 1, 38016, 0xcba6f5c8
+0, 78, 78, 1, 38016, 0x2ac20405
+0, 81, 81, 1, 38016, 0x6c790a1b
+0, 84, 84, 1, 38016, 0x8525413b
+0, 87, 87, 1, 38016, 0xef2e46a5
+0, 90, 90, 1, 38016, 0x32c16c28
+0, 93, 93, 1, 38016, 0x9fb0755f
+0, 96, 96, 1, 38016, 0xdfd7a1e2
+0, 99, 99, 1, 38016, 0xa91eb2d0
+0, 102, 102, 1, 38016, 0xb7bed869
+0, 105, 105, 1, 38016, 0x0263da70
+0, 108, 108, 1, 38016, 0x1403cf83
+0, 111, 111, 1, 38016, 0xb766f81a
+0, 114, 114, 1, 38016, 0x85abd4e0
+0, 117, 117, 1, 38016, 0xfc30c171
+0, 120, 120, 1, 38016, 0xb53bb9e5
+0, 123, 123, 1, 38016, 0xe93ca93c
+0, 126, 126, 1, 38016, 0xfa9db507
+0, 129, 129, 1, 38016, 0xd4da8492
+0, 132, 132, 1, 38016, 0x951cb041
+0, 135, 135, 1, 38016, 0x64fb9a09
+0, 138, 138, 1, 38016, 0x8f89b841
+0, 141, 141, 1, 38016, 0x9ee4b6df
+0, 144, 144, 1, 38016, 0xd733ae27
+0, 147, 147, 1, 38016, 0x2a1ab87d
+0, 150, 150, 1, 38016, 0x4853bf88
+0, 153, 153, 1, 38016, 0x701da865
+0, 156, 156, 1, 38016, 0x074d8248
+0, 159, 159, 1, 38016, 0xa1b4b019
+0, 162, 162, 1, 38016, 0x33f798c7
+0, 165, 165, 1, 38016, 0x5091bd66
+0, 168, 168, 1, 38016, 0x9dc0bf08
+0, 171, 171, 1, 38016, 0x83cff4c3
+0, 174, 174, 1, 38016, 0xce551295
+0, 177, 177, 1, 38016, 0x3c334a45
+0, 180, 180, 1, 38016, 0xd6e669ae
+0, 183, 183, 1, 38016, 0x08817cb0
+0, 186, 186, 1, 38016, 0x3d399508
+0, 189, 189, 1, 38016, 0xaf49a306
+0, 192, 192, 1, 38016, 0x6b77e02c
+0, 195, 195, 1, 38016, 0x34a6cc72
+0, 198, 198, 1, 38016, 0x0303e6bb
+0, 201, 201, 1, 38016, 0x3995eee2
+0, 204, 204, 1, 38016, 0x8eefd136
+0, 207, 207, 1, 38016, 0xd69ad171
+0, 210, 210, 1, 38016, 0xed98bff6
+0, 213, 213, 1, 38016, 0x606ba5ef
+0, 216, 216, 1, 38016, 0xbce4afaa
+0, 219, 219, 1, 38016, 0xa5baac40
+0, 222, 222, 1, 38016, 0x7a15929f
+0, 225, 225, 1, 38016, 0x0374cdec
+0, 228, 228, 1, 38016, 0xf482e941
+0, 231, 231, 1, 38016, 0xced1c9e3
+0, 234, 234, 1, 38016, 0x638fd91f
+0, 237, 237, 1, 38016, 0xced5d802
+0, 240, 240, 1, 38016, 0x330adeeb
+0, 243, 243, 1, 38016, 0x7a70f93e
+0, 246, 246, 1, 38016, 0x25c0dac1
+0, 249, 249, 1, 38016, 0x6f9401cf
+0, 252, 252, 1, 38016, 0x01632a5b
+0, 255, 255, 1, 38016, 0x6eedd857
+0, 258, 258, 1, 38016, 0xcfad1017
+0, 261, 261, 1, 38016, 0x38071e53
+0, 264, 264, 1, 38016, 0xc7c3013f
+0, 267, 267, 1, 38016, 0x1f41fe19
+0, 270, 270, 1, 38016, 0x9662e170
+0, 273, 273, 1, 38016, 0xec19ecfc
+0, 276, 276, 1, 38016, 0xab419765
+0, 279, 279, 1, 38016, 0xe784d98b
+0, 282, 282, 1, 38016, 0x93c1a4bf
+0, 285, 285, 1, 38016, 0xf2e4c9b4
+0, 288, 288, 1, 38016, 0x7cb6c1ff
+0, 291, 291, 1, 38016, 0x6fb36837
+0, 294, 294, 1, 38016, 0x6fb64665
+0, 297, 297, 1, 38016, 0xf24eaba9
+0, 300, 300, 1, 38016, 0x3866d28b
+0, 303, 303, 1, 38016, 0x807e829c
+0, 306, 306, 1, 38016, 0xf25fcbbb
+0, 309, 309, 1, 38016, 0xc28ba68f
+0, 312, 312, 1, 38016, 0x65ef8def
+0, 315, 315, 1, 38016, 0xc4646ee4
+0, 318, 318, 1, 38016, 0x3cb76962
+0, 321, 321, 1, 38016, 0xe5500136
+0, 324, 324, 1, 38016, 0xb086aa05
+0, 327, 327, 1, 38016, 0xde9fd4c3
+0, 330, 330, 1, 38016, 0xcae0d11b
+0, 333, 333, 1, 38016, 0x6cd3ee1a
+0, 336, 336, 1, 38016, 0x38981b85
+0, 339, 339, 1, 38016, 0xbe742f68
+0, 342, 342, 1, 38016, 0x29c41fc7
+0, 345, 345, 1, 38016, 0x43612eaf
+0, 348, 348, 1, 38016, 0x199dba2f
+0, 351, 351, 1, 38016, 0xb434f64d
+0, 354, 354, 1, 38016, 0x36f2fd8c
+0, 357, 357, 1, 38016, 0xc1075321
+0, 360, 360, 1, 38016, 0x7eabeab8
+0, 363, 363, 1, 38016, 0x7fcd5127
+0, 366, 366, 1, 38016, 0x37ddb544
+0, 369, 369, 1, 38016, 0x5dee2700
+0, 372, 372, 1, 38016, 0x46deb355
+0, 375, 375, 1, 38016, 0xb2496a7c
+0, 378, 378, 1, 38016, 0xfaf3b134
+0, 381, 381, 1, 38016, 0x42e9dbe1
+0, 384, 384, 1, 38016, 0x699fc6e0
+0, 387, 387, 1, 38016, 0x43ba68ae
+0, 390, 390, 1, 38016, 0xffd21579
+0, 393, 393, 1, 38016, 0xdd979741
+0, 396, 396, 1, 38016, 0x789c89aa
+0, 399, 399, 1, 38016, 0x40be024e
+0, 402, 402, 1, 38016, 0xa60c291d
+0, 405, 405, 1, 38016, 0xa8d253e9
+0, 408, 408, 1, 38016, 0x16d7f60e
+0, 411, 411, 1, 38016, 0xf1d21a57
+0, 414, 414, 1, 38016, 0x5e80e3bd
+0, 417, 417, 1, 38016, 0xceec0529
+0, 420, 420, 1, 38016, 0x1ff9c462
+0, 423, 423, 1, 38016, 0x51c168d2
+0, 426, 426, 1, 38016, 0xf61f2059
+0, 429, 429, 1, 38016, 0xb22fa794
+0, 432, 432, 1, 38016, 0xb81ec7d5
+0, 435, 435, 1, 38016, 0x7555d1df
+0, 438, 438, 1, 38016, 0x860d9de3
+0, 441, 441, 1, 38016, 0x9b19a66f
+0, 444, 444, 1, 38016, 0xec52d405
+0, 447, 447, 1, 38016, 0x2da4d05b
+0, 450, 450, 1, 38016, 0xf15bf060
+0, 453, 453, 1, 38016, 0xfabcc24a
+0, 456, 456, 1, 38016, 0xc159f63a
+0, 459, 459, 1, 38016, 0x0b97fcc1
+0, 462, 462, 1, 38016, 0xe0c063a2
+0, 465, 465, 1, 38016, 0x7bda9bec
+0, 468, 468, 1, 38016, 0xbe99a923
diff --git a/tests/ref/fate/vp8-sign-bias b/tests/ref/fate/vp8-sign-bias
index 38843c0..b503de8 100644
--- a/tests/ref/fate/vp8-sign-bias
+++ b/tests/ref/fate/vp8-sign-bias
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1/24
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 614880, 12ce23b288485be3ddbc1db28c21517f
0, 2, 2, 1, 614880, ce352e1079535ea058c0e9ad50f7cdb8
0, 3, 3, 1, 614880, 9f6bf2739a027dfd12c81586cf75d3a3
diff --git a/tests/ref/fate/vp8-size-change b/tests/ref/fate/vp8-size-change
index 1fba74e..f581c99 100644
--- a/tests/ref/fate/vp8-size-change
+++ b/tests/ref/fate/vp8-size-change
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1/30
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 3110400, 7dde8cd136ab4b04a95d9856b941697e
0, 1, 1, 1, 3110400, aa885f78cb6374b5bfcc66a4fc57026f
0, 2, 2, 1, 3110400, b69b7b56f549a3f9b0a603940bac85ed
diff --git a/tests/ref/fate/vp8-test-vector-001 b/tests/ref/fate/vp8-test-vector-001
index 64accc4..ef38aa8 100644
--- a/tests/ref/fate/vp8-test-vector-001
+++ b/tests/ref/fate/vp8-test-vector-001
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1/30
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 38016, 83c78b5db579710f61f9354d5c51e8c8
0, 1, 1, 1, 38016, 8d089d226f52d6cdaffdb3fcc080b75b
0, 2, 2, 1, 38016, acaae81ca812145e85e0be83bdf54226
diff --git a/tests/ref/fate/vp8-test-vector-002 b/tests/ref/fate/vp8-test-vector-002
index d42674a..55149b0 100644
--- a/tests/ref/fate/vp8-test-vector-002
+++ b/tests/ref/fate/vp8-test-vector-002
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1/24
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 38016, 872e9922f37f0e92c767d33e0a15b8e0
0, 1, 1, 1, 38016, ea5ad6c6ee4355018fc0ba83b5172836
0, 2, 2, 1, 38016, fe744612b2167c9ba6e1dc81c031e16a
diff --git a/tests/ref/fate/vp8-test-vector-003 b/tests/ref/fate/vp8-test-vector-003
index 504766f..ffe3896 100644
--- a/tests/ref/fate/vp8-test-vector-003
+++ b/tests/ref/fate/vp8-test-vector-003
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1/24
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 38016, 96e6ce168b5ef377053e86ab5484e7f9
0, 1, 1, 1, 38016, 10fd750292d8522ab7ee577043604789
0, 2, 2, 1, 38016, e040995173dc5c85abbbe38f6823ff9a
diff --git a/tests/ref/fate/vp8-test-vector-004 b/tests/ref/fate/vp8-test-vector-004
index f402372..f7f5313 100644
--- a/tests/ref/fate/vp8-test-vector-004
+++ b/tests/ref/fate/vp8-test-vector-004
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1/30
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 38016, 83c78b5db579710f61f9354d5c51e8c8
0, 1, 1, 1, 38016, d173eb8a8211a05672b43206609c9034
0, 2, 2, 1, 38016, 204e3e91613d647d30244c00fa2b9563
diff --git a/tests/ref/fate/vp8-test-vector-005 b/tests/ref/fate/vp8-test-vector-005
index 3569dee..3368c70 100644
--- a/tests/ref/fate/vp8-test-vector-005
+++ b/tests/ref/fate/vp8-test-vector-005
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1/24
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 38016, e7a4be434df4bb524ba56a03cba901f4
0, 1, 1, 1, 38016, d903ade6d49e51485627c044fbb2190c
0, 2, 2, 1, 38016, af07ee39629b852870104cb9a9dde9e3
diff --git a/tests/ref/fate/vp8-test-vector-006 b/tests/ref/fate/vp8-test-vector-006
index 38b92c4..28c249c 100644
--- a/tests/ref/fate/vp8-test-vector-006
+++ b/tests/ref/fate/vp8-test-vector-006
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1/24
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 37697, 9ca5df27b0158aca2a38dff946f58c41
0, 1, 1, 1, 37697, 627129a99538ec1ac51be910ca92ebc4
0, 2, 2, 1, 37697, 6c2df1f21af317aa5bb68b161ca96c70
diff --git a/tests/ref/fate/vp8-test-vector-007 b/tests/ref/fate/vp8-test-vector-007
index 8d9b912..a0cb441 100644
--- a/tests/ref/fate/vp8-test-vector-007
+++ b/tests/ref/fate/vp8-test-vector-007
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1/30
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 38016, 98bd0af6928c144888a9c320270e9f0e
0, 1, 1, 1, 38016, 9ff7cff703d58481acd233451388377c
0, 2, 2, 1, 38016, e4cd8815527846cc782ea61ef5a46e49
diff --git a/tests/ref/fate/vp8-test-vector-008 b/tests/ref/fate/vp8-test-vector-008
index 9be8d73..0503c4e 100644
--- a/tests/ref/fate/vp8-test-vector-008
+++ b/tests/ref/fate/vp8-test-vector-008
@@ -1,3 +1,7 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1/23
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 1907424, 7146d3a72b6cb8e43ee5280ef8d661fe
0, 1, 1, 1, 1907424, 5a537e9710158efb5ad2683a1d3b4c72
diff --git a/tests/ref/fate/vp8-test-vector-009 b/tests/ref/fate/vp8-test-vector-009
index fae204d..f41f014 100644
--- a/tests/ref/fate/vp8-test-vector-009
+++ b/tests/ref/fate/vp8-test-vector-009
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1/24
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 38016, b3a3121c796a60c88988fef5240a07fe
0, 1, 1, 1, 38016, f25147764829cf837e00b8fd6383e2c4
0, 2, 2, 1, 38016, 1b1552291a89c97d5deea145ab0ac0cd
diff --git a/tests/ref/fate/vp8-test-vector-010 b/tests/ref/fate/vp8-test-vector-010
index b250ad9..2feeb63 100644
--- a/tests/ref/fate/vp8-test-vector-010
+++ b/tests/ref/fate/vp8-test-vector-010
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1/30
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 115200, 3441ec1a9b9d325c9aeda44e3b68377d
0, 1, 1, 1, 115200, bff86a84fd673394f45c09d19a1ee0ac
0, 2, 2, 1, 115200, 8cd920f0de408e8cd883f9241680ff80
diff --git a/tests/ref/fate/vp8-test-vector-011 b/tests/ref/fate/vp8-test-vector-011
index d591ec7..adf7235 100644
--- a/tests/ref/fate/vp8-test-vector-011
+++ b/tests/ref/fate/vp8-test-vector-011
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1/30
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 38016, 83c78b5db579710f61f9354d5c51e8c8
0, 1, 1, 1, 38016, 9b755a63c7c5352660a265f6e24991e1
0, 2, 2, 1, 38016, a591f0b04447d6d6dd9bb990502594aa
diff --git a/tests/ref/fate/vp8-test-vector-012 b/tests/ref/fate/vp8-test-vector-012
index 4d5adcb..3de64b6 100644
--- a/tests/ref/fate/vp8-test-vector-012
+++ b/tests/ref/fate/vp8-test-vector-012
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1/30
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 38016, cc3069a59b6f4319761af2b39923a6e5
0, 1, 1, 1, 38016, c0bc935941d994c6af6a864f02a90a62
0, 2, 2, 1, 38016, 5b6073ce4a03967aa87e56dfa27e32c2
diff --git a/tests/ref/fate/vp8-test-vector-013 b/tests/ref/fate/vp8-test-vector-013
index de7c0b3..e31e6e6 100644
--- a/tests/ref/fate/vp8-test-vector-013
+++ b/tests/ref/fate/vp8-test-vector-013
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1/30
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 38016, ad137b9eae93daed28fe31fd5165b4d0
0, 1, 1, 1, 38016, 7cd527f647680c0eb305050d27fb8092
0, 2, 2, 1, 38016, f306e07a2e86c82a8cc1333be3812326
diff --git a/tests/ref/fate/vp8-test-vector-014 b/tests/ref/fate/vp8-test-vector-014
index 4341e59..689e24b 100644
--- a/tests/ref/fate/vp8-test-vector-014
+++ b/tests/ref/fate/vp8-test-vector-014
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1/30
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 37697, 7a0356dc950e79744d79c98e391ebee9
0, 1, 1, 1, 37697, 96e221e75c290dd847b8e55865073366
0, 2, 2, 1, 37697, 67638290841837c90f180a01094f9191
diff --git a/tests/ref/fate/vp8-test-vector-015 b/tests/ref/fate/vp8-test-vector-015
index b32f233..766c931 100644
--- a/tests/ref/fate/vp8-test-vector-015
+++ b/tests/ref/fate/vp8-test-vector-015
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1/30
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 115200, 6b4c7cc0c6a7218362e43cffef6618c9
0, 1, 1, 1, 115200, e132a7b1bb4fb15b1019092aedc0e599
0, 2, 2, 1, 115200, b36975db60f24088d95385ff7e8b7b8a
diff --git a/tests/ref/fate/vp8-test-vector-016 b/tests/ref/fate/vp8-test-vector-016
index 291e7fe..4da7ff3 100644
--- a/tests/ref/fate/vp8-test-vector-016
+++ b/tests/ref/fate/vp8-test-vector-016
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1/30
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 38016, 905a823da31f71f9c25ebb8dfc9ddd3c
0, 1, 1, 1, 38016, 9a1b97859b2f774954dbf96f45a22a0a
0, 2, 2, 1, 38016, f0f5651b32577549dc2e6e3050125229
diff --git a/tests/ref/fate/vp8-test-vector-017 b/tests/ref/fate/vp8-test-vector-017
index a8ccda8..0d3fbea 100644
--- a/tests/ref/fate/vp8-test-vector-017
+++ b/tests/ref/fate/vp8-test-vector-017
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1/30
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 38016, 905a823da31f71f9c25ebb8dfc9ddd3c
0, 1, 1, 1, 38016, f0f411dd067bff05d5d9c64e3f52a4b1
0, 2, 2, 1, 38016, c8696f8fa56b4adf18f3db0c384d968f
diff --git a/tests/ref/fate/vp9-00-quantizer-00 b/tests/ref/fate/vp9-00-quantizer-00
index 2aa81b4..e2afb9c 100644
--- a/tests/ref/fate/vp9-00-quantizer-00
+++ b/tests/ref/fate/vp9-00-quantizer-00
@@ -1,3 +1,7 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 152064, c3fbb7abbdb5bd4ed4a7e34768c17df1
0, 1, 1, 1, 152064, 08203c2595bdb2d58ead6f921345d699
diff --git a/tests/ref/fate/vp9-00-quantizer-01 b/tests/ref/fate/vp9-00-quantizer-01
index 6f12349..4d9b081 100644
--- a/tests/ref/fate/vp9-00-quantizer-01
+++ b/tests/ref/fate/vp9-00-quantizer-01
@@ -1,3 +1,7 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 152064, f041b870cf9236d5f22e2b08a77d5958
0, 1, 1, 1, 152064, cbdb7526986ae15592891488c9afc84c
diff --git a/tests/ref/fate/vp9-00-quantizer-02 b/tests/ref/fate/vp9-00-quantizer-02
index 1ab0ed0..09e6299 100644
--- a/tests/ref/fate/vp9-00-quantizer-02
+++ b/tests/ref/fate/vp9-00-quantizer-02
@@ -1,3 +1,7 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 152064, 98048cfdb4af5059f4085c5acc94ef8f
0, 1, 1, 1, 152064, 8160183e1eed1d0af4427be216b8b9f7
diff --git a/tests/ref/fate/vp9-00-quantizer-03 b/tests/ref/fate/vp9-00-quantizer-03
index e458d68..0c22157 100644
--- a/tests/ref/fate/vp9-00-quantizer-03
+++ b/tests/ref/fate/vp9-00-quantizer-03
@@ -1,3 +1,7 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 152064, 15c548208f5eda243a151a42f4d64855
0, 1, 1, 1, 152064, e96d463dc8e9b27b1c2ec40f77eee6ef
diff --git a/tests/ref/fate/vp9-00-quantizer-04 b/tests/ref/fate/vp9-00-quantizer-04
index 60ec047..730a012 100644
--- a/tests/ref/fate/vp9-00-quantizer-04
+++ b/tests/ref/fate/vp9-00-quantizer-04
@@ -1,3 +1,7 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 152064, 928c64a0747ac57ab50c1520d694fea7
0, 1, 1, 1, 152064, a6f6daa293231e95ef30ed168f582c84
diff --git a/tests/ref/fate/vp9-00-quantizer-05 b/tests/ref/fate/vp9-00-quantizer-05
index 81f3cfb..0f2dd7a 100644
--- a/tests/ref/fate/vp9-00-quantizer-05
+++ b/tests/ref/fate/vp9-00-quantizer-05
@@ -1,3 +1,7 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 152064, 082460718b7d7046c8fb23184b7f71ca
0, 1, 1, 1, 152064, 4a41aad51c40a92df72333e13f47d3fe
diff --git a/tests/ref/fate/vp9-00-quantizer-06 b/tests/ref/fate/vp9-00-quantizer-06
index d06fa0c..c6c1282 100644
--- a/tests/ref/fate/vp9-00-quantizer-06
+++ b/tests/ref/fate/vp9-00-quantizer-06
@@ -1,3 +1,7 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 152064, cfca1bed96ff62a69b2d841fda01c6b9
0, 1, 1, 1, 152064, 9b4d61f1b998745c108f8eb67925e03d
diff --git a/tests/ref/fate/vp9-00-quantizer-07 b/tests/ref/fate/vp9-00-quantizer-07
index afce0ab..cdc6ec5 100644
--- a/tests/ref/fate/vp9-00-quantizer-07
+++ b/tests/ref/fate/vp9-00-quantizer-07
@@ -1,3 +1,7 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 152064, 6f5122064bead9d9882bec2698a6ed9c
0, 1, 1, 1, 152064, 50dae67d2f57a76eece210dee8b6df9e
diff --git a/tests/ref/fate/vp9-00-quantizer-08 b/tests/ref/fate/vp9-00-quantizer-08
index 8092995..f405cef 100644
--- a/tests/ref/fate/vp9-00-quantizer-08
+++ b/tests/ref/fate/vp9-00-quantizer-08
@@ -1,3 +1,7 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 152064, eb3d6985fcda5d93dd62d53354e8a093
0, 1, 1, 1, 152064, 5b1f5b7780b4cafe1f75e56a0b526643
diff --git a/tests/ref/fate/vp9-00-quantizer-09 b/tests/ref/fate/vp9-00-quantizer-09
index fd25ec5..bc5e86a 100644
--- a/tests/ref/fate/vp9-00-quantizer-09
+++ b/tests/ref/fate/vp9-00-quantizer-09
@@ -1,3 +1,7 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 152064, d7ccaf28c59875fe91983def5490d2b1
0, 1, 1, 1, 152064, bd98fe9492054826748de840b4495309
diff --git a/tests/ref/fate/vp9-00-quantizer-10 b/tests/ref/fate/vp9-00-quantizer-10
index 61c3fb8..93e46a9 100644
--- a/tests/ref/fate/vp9-00-quantizer-10
+++ b/tests/ref/fate/vp9-00-quantizer-10
@@ -1,3 +1,7 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 152064, 20dda6231f9801c9c237c6d09d9939b6
0, 1, 1, 1, 152064, 23c91e93807fb9a4ed5bd5bdd449d99f
diff --git a/tests/ref/fate/vp9-00-quantizer-11 b/tests/ref/fate/vp9-00-quantizer-11
index 6da2316..0924f54 100644
--- a/tests/ref/fate/vp9-00-quantizer-11
+++ b/tests/ref/fate/vp9-00-quantizer-11
@@ -1,3 +1,7 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 152064, 960833315ebcdee97f46c4d98d0f3fef
0, 1, 1, 1, 152064, eec40507d17b64b7895a61cb87b2096a
diff --git a/tests/ref/fate/vp9-00-quantizer-12 b/tests/ref/fate/vp9-00-quantizer-12
index 492b07a..9213e9d 100644
--- a/tests/ref/fate/vp9-00-quantizer-12
+++ b/tests/ref/fate/vp9-00-quantizer-12
@@ -1,3 +1,7 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 152064, 6533224d3b6ba1ec0dd973bbe56c6349
0, 1, 1, 1, 152064, 12ceadc6d28327a24a75f8c40b6084d1
diff --git a/tests/ref/fate/vp9-00-quantizer-13 b/tests/ref/fate/vp9-00-quantizer-13
index 2b9e635..80d1a6c 100644
--- a/tests/ref/fate/vp9-00-quantizer-13
+++ b/tests/ref/fate/vp9-00-quantizer-13
@@ -1,3 +1,7 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 152064, 7268de6756014f79a56dcf010c52a97f
0, 1, 1, 1, 152064, 9e39e9b0e2295b8460dfa05f44762771
diff --git a/tests/ref/fate/vp9-00-quantizer-14 b/tests/ref/fate/vp9-00-quantizer-14
index 861dc3b..e7ab21d 100644
--- a/tests/ref/fate/vp9-00-quantizer-14
+++ b/tests/ref/fate/vp9-00-quantizer-14
@@ -1,3 +1,7 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 152064, 57e9e333c641fa952f7485b788df225a
0, 1, 1, 1, 152064, 551f0cea83dcdf4540c3983736757874
diff --git a/tests/ref/fate/vp9-00-quantizer-15 b/tests/ref/fate/vp9-00-quantizer-15
index a6c3c59..842ab6e 100644
--- a/tests/ref/fate/vp9-00-quantizer-15
+++ b/tests/ref/fate/vp9-00-quantizer-15
@@ -1,3 +1,7 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 152064, 17a0a2842856b9e89aede237648d5dda
0, 1, 1, 1, 152064, c9fcade888a38621bebe3d4b41664245
diff --git a/tests/ref/fate/vp9-00-quantizer-16 b/tests/ref/fate/vp9-00-quantizer-16
index 9f049e5..7478558 100644
--- a/tests/ref/fate/vp9-00-quantizer-16
+++ b/tests/ref/fate/vp9-00-quantizer-16
@@ -1,3 +1,7 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 152064, 6cc2089e9a3d352fe10b59ccd935c677
0, 1, 1, 1, 152064, d165bf7b9cb901e121a65038758d8613
diff --git a/tests/ref/fate/vp9-00-quantizer-17 b/tests/ref/fate/vp9-00-quantizer-17
index 6642088..3a5b1c1 100644
--- a/tests/ref/fate/vp9-00-quantizer-17
+++ b/tests/ref/fate/vp9-00-quantizer-17
@@ -1,3 +1,7 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 152064, bc80511c83162c09661f155cd29f6dd8
0, 1, 1, 1, 152064, a62f1cbdb3f86d2fb4c880cfd917def5
diff --git a/tests/ref/fate/vp9-00-quantizer-18 b/tests/ref/fate/vp9-00-quantizer-18
index a456e71..baf3bc3 100644
--- a/tests/ref/fate/vp9-00-quantizer-18
+++ b/tests/ref/fate/vp9-00-quantizer-18
@@ -1,3 +1,7 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 152064, b2d350f6faa41cb50c2e8a9907d0f4a5
0, 1, 1, 1, 152064, 39b4380d16bc8e093dd4dba475175fb3
diff --git a/tests/ref/fate/vp9-00-quantizer-19 b/tests/ref/fate/vp9-00-quantizer-19
index 5daf04b..2ba95e1 100644
--- a/tests/ref/fate/vp9-00-quantizer-19
+++ b/tests/ref/fate/vp9-00-quantizer-19
@@ -1,3 +1,7 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 152064, 441e09be3c15fcb240afd74bb7a10a72
0, 1, 1, 1, 152064, 32ae5dac876ca5d5ae6ab7c74f4dc25d
diff --git a/tests/ref/fate/vp9-00-quantizer-20 b/tests/ref/fate/vp9-00-quantizer-20
index 550df97..8119688 100644
--- a/tests/ref/fate/vp9-00-quantizer-20
+++ b/tests/ref/fate/vp9-00-quantizer-20
@@ -1,3 +1,7 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 152064, 7786eb9944dba0553e129133523a98c1
0, 1, 1, 1, 152064, 206d888f8453427f10a40aa8bf5f6df0
diff --git a/tests/ref/fate/vp9-00-quantizer-21 b/tests/ref/fate/vp9-00-quantizer-21
index 61dac5a..0e94992 100644
--- a/tests/ref/fate/vp9-00-quantizer-21
+++ b/tests/ref/fate/vp9-00-quantizer-21
@@ -1,3 +1,7 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 152064, aab95e195be71feca050a839d7b3154d
0, 1, 1, 1, 152064, 02a05d699bbbdc477e34bb0dad9f0391
diff --git a/tests/ref/fate/vp9-00-quantizer-22 b/tests/ref/fate/vp9-00-quantizer-22
index 1a7e309..90533aa 100644
--- a/tests/ref/fate/vp9-00-quantizer-22
+++ b/tests/ref/fate/vp9-00-quantizer-22
@@ -1,3 +1,7 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 152064, 41f853c3ee2d4611b645cc643d82e287
0, 1, 1, 1, 152064, 1c240c653110ff8609ca0f0287a6496d
diff --git a/tests/ref/fate/vp9-00-quantizer-23 b/tests/ref/fate/vp9-00-quantizer-23
index d636956..d16d198 100644
--- a/tests/ref/fate/vp9-00-quantizer-23
+++ b/tests/ref/fate/vp9-00-quantizer-23
@@ -1,3 +1,7 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 152064, bc5b07369df50c8f97ce1a377fe513cf
0, 1, 1, 1, 152064, ce62ddb4f3e305d0f8587ae8bb44cc79
diff --git a/tests/ref/fate/vp9-00-quantizer-24 b/tests/ref/fate/vp9-00-quantizer-24
index fe3b8bd..eccdfd6 100644
--- a/tests/ref/fate/vp9-00-quantizer-24
+++ b/tests/ref/fate/vp9-00-quantizer-24
@@ -1,3 +1,7 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 152064, 982d54041221c977b6f0e37a9236cc76
0, 1, 1, 1, 152064, 57631e7f13f645c834e2944ebfd6d40e
diff --git a/tests/ref/fate/vp9-00-quantizer-25 b/tests/ref/fate/vp9-00-quantizer-25
index 84f35ee..70a76b3 100644
--- a/tests/ref/fate/vp9-00-quantizer-25
+++ b/tests/ref/fate/vp9-00-quantizer-25
@@ -1,3 +1,7 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 152064, b0fb55f3f2f56b3d27038e83c10123ce
0, 1, 1, 1, 152064, 9fcac3becdcc2d30d778a55eca4c2018
diff --git a/tests/ref/fate/vp9-00-quantizer-26 b/tests/ref/fate/vp9-00-quantizer-26
index 0fa04db..d9308dc 100644
--- a/tests/ref/fate/vp9-00-quantizer-26
+++ b/tests/ref/fate/vp9-00-quantizer-26
@@ -1,3 +1,7 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 152064, 4f645e0f354da77b9e2f2a6753c361da
0, 1, 1, 1, 152064, b7542998ec298273ca662bc9b658d10e
diff --git a/tests/ref/fate/vp9-00-quantizer-27 b/tests/ref/fate/vp9-00-quantizer-27
index f56606c..d2efd69 100644
--- a/tests/ref/fate/vp9-00-quantizer-27
+++ b/tests/ref/fate/vp9-00-quantizer-27
@@ -1,3 +1,7 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 152064, 6edc96a3747cad43828397045764206e
0, 1, 1, 1, 152064, 5fbc65d20fdca1abd69079851ce676d3
diff --git a/tests/ref/fate/vp9-00-quantizer-28 b/tests/ref/fate/vp9-00-quantizer-28
index b8946b0..85919fc 100644
--- a/tests/ref/fate/vp9-00-quantizer-28
+++ b/tests/ref/fate/vp9-00-quantizer-28
@@ -1,3 +1,7 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 152064, 5db3e910e70da38bb91d01d73acc33dd
0, 1, 1, 1, 152064, b920ee7f7e61b7fdf9f44b1f738d0292
diff --git a/tests/ref/fate/vp9-00-quantizer-29 b/tests/ref/fate/vp9-00-quantizer-29
index e5780ee..cc6eae7 100644
--- a/tests/ref/fate/vp9-00-quantizer-29
+++ b/tests/ref/fate/vp9-00-quantizer-29
@@ -1,3 +1,7 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 152064, 3cb3e310be5305077efa6216f6f10654
0, 1, 1, 1, 152064, 692d3e098af5978fe1a898ebc1a66a7a
diff --git a/tests/ref/fate/vp9-00-quantizer-30 b/tests/ref/fate/vp9-00-quantizer-30
index 91fa4e0..4f26b58 100644
--- a/tests/ref/fate/vp9-00-quantizer-30
+++ b/tests/ref/fate/vp9-00-quantizer-30
@@ -1,3 +1,7 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 152064, e3b3cea66ea38c5dfba1aa73bb4c611d
0, 1, 1, 1, 152064, 42bb3e54b19c3f4c4f7ee3a6ba012e19
diff --git a/tests/ref/fate/vp9-00-quantizer-31 b/tests/ref/fate/vp9-00-quantizer-31
index 3cf3af8..4c9bf96 100644
--- a/tests/ref/fate/vp9-00-quantizer-31
+++ b/tests/ref/fate/vp9-00-quantizer-31
@@ -1,3 +1,7 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 152064, 2523e9ecfd3781eafcd7da192dc105e9
0, 1, 1, 1, 152064, 6d5feea012b9a1f51fc643633e728764
diff --git a/tests/ref/fate/vp9-00-quantizer-32 b/tests/ref/fate/vp9-00-quantizer-32
index 13616fc..ef49c4e 100644
--- a/tests/ref/fate/vp9-00-quantizer-32
+++ b/tests/ref/fate/vp9-00-quantizer-32
@@ -1,3 +1,7 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 152064, 0a0305eba36500ebf6cc6cc0f01f5a3b
0, 1, 1, 1, 152064, 2c76bcd6763467f9057a726fbcf50ab1
diff --git a/tests/ref/fate/vp9-00-quantizer-33 b/tests/ref/fate/vp9-00-quantizer-33
index ad3e5b8..374c44e 100644
--- a/tests/ref/fate/vp9-00-quantizer-33
+++ b/tests/ref/fate/vp9-00-quantizer-33
@@ -1,3 +1,7 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 152064, c68433e0e94047c220be9b629334f744
0, 1, 1, 1, 152064, fcfa4dff7a39bc9c5e315849ecbb46ea
diff --git a/tests/ref/fate/vp9-00-quantizer-34 b/tests/ref/fate/vp9-00-quantizer-34
index aee58f8..aa9c833 100644
--- a/tests/ref/fate/vp9-00-quantizer-34
+++ b/tests/ref/fate/vp9-00-quantizer-34
@@ -1,3 +1,7 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 152064, ad9dc2f912c137b014a33e2792c88a25
0, 1, 1, 1, 152064, 11221ee4ea5c776f43af68756682cd5a
diff --git a/tests/ref/fate/vp9-00-quantizer-35 b/tests/ref/fate/vp9-00-quantizer-35
index fbb68f7..820725b 100644
--- a/tests/ref/fate/vp9-00-quantizer-35
+++ b/tests/ref/fate/vp9-00-quantizer-35
@@ -1,3 +1,7 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 152064, 75031f898cccf303a64ab46b1f815389
0, 1, 1, 1, 152064, a4fc864e7fbc470dfcab6207e0eea152
diff --git a/tests/ref/fate/vp9-00-quantizer-36 b/tests/ref/fate/vp9-00-quantizer-36
index d5bcad6..4a39a13 100644
--- a/tests/ref/fate/vp9-00-quantizer-36
+++ b/tests/ref/fate/vp9-00-quantizer-36
@@ -1,3 +1,7 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 152064, c7824af009fde6cafdd8d39fae6bb6cf
0, 1, 1, 1, 152064, 516a82d5fc4dfa3daf713ed2ec36041b
diff --git a/tests/ref/fate/vp9-00-quantizer-37 b/tests/ref/fate/vp9-00-quantizer-37
index 2a030b4..96e526f 100644
--- a/tests/ref/fate/vp9-00-quantizer-37
+++ b/tests/ref/fate/vp9-00-quantizer-37
@@ -1,3 +1,7 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 152064, a2e5c820fd9733e18f9349fb658ca281
0, 1, 1, 1, 152064, fb23e0bc64728a492a33d985032f21b8
diff --git a/tests/ref/fate/vp9-00-quantizer-38 b/tests/ref/fate/vp9-00-quantizer-38
index d5e7076..9f61d33 100644
--- a/tests/ref/fate/vp9-00-quantizer-38
+++ b/tests/ref/fate/vp9-00-quantizer-38
@@ -1,3 +1,7 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 152064, 8347bfb891317e89ef66781d6c28e24f
0, 1, 1, 1, 152064, a5722f824d32deac042513a1a7dcdcd0
diff --git a/tests/ref/fate/vp9-00-quantizer-39 b/tests/ref/fate/vp9-00-quantizer-39
index 464d265..396a1a3 100644
--- a/tests/ref/fate/vp9-00-quantizer-39
+++ b/tests/ref/fate/vp9-00-quantizer-39
@@ -1,3 +1,7 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 152064, 018968f97fac3bdff146cf22c1da5ef0
0, 1, 1, 1, 152064, ca8b09b01e5132183395e238f1c7901e
diff --git a/tests/ref/fate/vp9-00-quantizer-40 b/tests/ref/fate/vp9-00-quantizer-40
index 69b230e..dc77394 100644
--- a/tests/ref/fate/vp9-00-quantizer-40
+++ b/tests/ref/fate/vp9-00-quantizer-40
@@ -1,3 +1,7 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 152064, 792660f6589ad5340be4bd0554435866
0, 1, 1, 1, 152064, 68c84c8a15d679e0a73678b93215c62c
diff --git a/tests/ref/fate/vp9-00-quantizer-41 b/tests/ref/fate/vp9-00-quantizer-41
index 0dd4500..667549c 100644
--- a/tests/ref/fate/vp9-00-quantizer-41
+++ b/tests/ref/fate/vp9-00-quantizer-41
@@ -1,3 +1,7 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 152064, a456bdfc6c1c07b4cb3a3848843743b9
0, 1, 1, 1, 152064, fe41a12b8cb6bc5667ba2179e076f3b0
diff --git a/tests/ref/fate/vp9-00-quantizer-42 b/tests/ref/fate/vp9-00-quantizer-42
index bf8125c..c7fbfbc 100644
--- a/tests/ref/fate/vp9-00-quantizer-42
+++ b/tests/ref/fate/vp9-00-quantizer-42
@@ -1,3 +1,7 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 152064, f016dd8431694d989700fb1ba71a5b2d
0, 1, 1, 1, 152064, e89c3c5b935157b40f2fb0ab92415828
diff --git a/tests/ref/fate/vp9-00-quantizer-43 b/tests/ref/fate/vp9-00-quantizer-43
index dd12578..090ce6f 100644
--- a/tests/ref/fate/vp9-00-quantizer-43
+++ b/tests/ref/fate/vp9-00-quantizer-43
@@ -1,3 +1,7 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 152064, 7b8ab82625f3006bac89d4fb5197e71c
0, 1, 1, 1, 152064, 18bd3716045563dfba2c72b640b3274b
diff --git a/tests/ref/fate/vp9-00-quantizer-44 b/tests/ref/fate/vp9-00-quantizer-44
index 7917184..130b5fa 100644
--- a/tests/ref/fate/vp9-00-quantizer-44
+++ b/tests/ref/fate/vp9-00-quantizer-44
@@ -1,3 +1,7 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 152064, 66fde04d8320c750e56406feefd29979
0, 1, 1, 1, 152064, f9d01d8fc1722ec345e624e14b404215
diff --git a/tests/ref/fate/vp9-00-quantizer-45 b/tests/ref/fate/vp9-00-quantizer-45
index a15e6f5..5cb7105 100644
--- a/tests/ref/fate/vp9-00-quantizer-45
+++ b/tests/ref/fate/vp9-00-quantizer-45
@@ -1,3 +1,7 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 152064, cc97597b015896d73f3e60e7ae44c4da
0, 1, 1, 1, 152064, fea98bc508f92135641ab99762444b14
diff --git a/tests/ref/fate/vp9-00-quantizer-46 b/tests/ref/fate/vp9-00-quantizer-46
index 8eccf6b..cb51f72 100644
--- a/tests/ref/fate/vp9-00-quantizer-46
+++ b/tests/ref/fate/vp9-00-quantizer-46
@@ -1,3 +1,7 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 152064, 79ed95c741178bb3c0954f1f6f8e21a3
0, 1, 1, 1, 152064, f02a06a5e2b5b7619c9a52c5bea0564d
diff --git a/tests/ref/fate/vp9-00-quantizer-47 b/tests/ref/fate/vp9-00-quantizer-47
index 0616f1f..0bf90b4 100644
--- a/tests/ref/fate/vp9-00-quantizer-47
+++ b/tests/ref/fate/vp9-00-quantizer-47
@@ -1,3 +1,7 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 152064, 9b98e948b8c2a822f21bd8419e6f4410
0, 1, 1, 1, 152064, 491382d68c16c2a3c6f1746598bc4a97
diff --git a/tests/ref/fate/vp9-00-quantizer-48 b/tests/ref/fate/vp9-00-quantizer-48
index ebdb986..2604a53 100644
--- a/tests/ref/fate/vp9-00-quantizer-48
+++ b/tests/ref/fate/vp9-00-quantizer-48
@@ -1,3 +1,7 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 152064, f0f095b0edae7262f44d7ed7ef84ded4
0, 1, 1, 1, 152064, 0e833889ccac81d60251007d1baf6500
diff --git a/tests/ref/fate/vp9-00-quantizer-49 b/tests/ref/fate/vp9-00-quantizer-49
index cf287fa..3403d1d 100644
--- a/tests/ref/fate/vp9-00-quantizer-49
+++ b/tests/ref/fate/vp9-00-quantizer-49
@@ -1,3 +1,7 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 152064, 6c1b7b7827617fb9b8417aca2cfdbcaa
0, 1, 1, 1, 152064, 4c1fc8a89297fdcf79f0faabd42b8684
diff --git a/tests/ref/fate/vp9-00-quantizer-50 b/tests/ref/fate/vp9-00-quantizer-50
index 2e88104..f2cdc8e 100644
--- a/tests/ref/fate/vp9-00-quantizer-50
+++ b/tests/ref/fate/vp9-00-quantizer-50
@@ -1,3 +1,7 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 152064, ca6142db68463487bc28c888ab38476c
0, 1, 1, 1, 152064, 02a71153ec70f569524c3d814cb62f86
diff --git a/tests/ref/fate/vp9-00-quantizer-51 b/tests/ref/fate/vp9-00-quantizer-51
index 6d7fadb..87ab57e 100644
--- a/tests/ref/fate/vp9-00-quantizer-51
+++ b/tests/ref/fate/vp9-00-quantizer-51
@@ -1,3 +1,7 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 152064, eece2627df1ddf0872256eb92352e179
0, 1, 1, 1, 152064, 0ee9f221246ad747250e4b5e8ba586e2
diff --git a/tests/ref/fate/vp9-00-quantizer-52 b/tests/ref/fate/vp9-00-quantizer-52
index 244b7a8..f3a14d1 100644
--- a/tests/ref/fate/vp9-00-quantizer-52
+++ b/tests/ref/fate/vp9-00-quantizer-52
@@ -1,3 +1,7 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 152064, 7290039d974c4e50db9d69f9864bcdbe
0, 1, 1, 1, 152064, 264765de9d02503038a4da54133b9f85
diff --git a/tests/ref/fate/vp9-00-quantizer-53 b/tests/ref/fate/vp9-00-quantizer-53
index bced29d..784925d 100644
--- a/tests/ref/fate/vp9-00-quantizer-53
+++ b/tests/ref/fate/vp9-00-quantizer-53
@@ -1,3 +1,7 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 152064, 917af24da66f143a56a01eb2c2254285
0, 1, 1, 1, 152064, 45a05d3bc644420519619e4115662a70
diff --git a/tests/ref/fate/vp9-00-quantizer-54 b/tests/ref/fate/vp9-00-quantizer-54
index 5716f8e..daa6f5d 100644
--- a/tests/ref/fate/vp9-00-quantizer-54
+++ b/tests/ref/fate/vp9-00-quantizer-54
@@ -1,3 +1,7 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 152064, 6fea2820bb10a9dec9add4d2452b01f5
0, 1, 1, 1, 152064, 74675169a4bfc2ff5463c4db5d85a79f
diff --git a/tests/ref/fate/vp9-00-quantizer-55 b/tests/ref/fate/vp9-00-quantizer-55
index a6e796e..0a48cf9 100644
--- a/tests/ref/fate/vp9-00-quantizer-55
+++ b/tests/ref/fate/vp9-00-quantizer-55
@@ -1,3 +1,7 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 152064, 11e5d196f6537fb7d85988d90195e556
0, 1, 1, 1, 152064, 8536106795f7c93c5a43a11493527469
diff --git a/tests/ref/fate/vp9-00-quantizer-56 b/tests/ref/fate/vp9-00-quantizer-56
index 8da0182..f1f6069 100644
--- a/tests/ref/fate/vp9-00-quantizer-56
+++ b/tests/ref/fate/vp9-00-quantizer-56
@@ -1,3 +1,7 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 152064, 40839b7a3a40ec10f96b8a75224f646d
0, 1, 1, 1, 152064, 11408dd73e8c45ddaab99f5c9650102b
diff --git a/tests/ref/fate/vp9-00-quantizer-57 b/tests/ref/fate/vp9-00-quantizer-57
index 10526d2..499b57e 100644
--- a/tests/ref/fate/vp9-00-quantizer-57
+++ b/tests/ref/fate/vp9-00-quantizer-57
@@ -1,3 +1,7 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 152064, d0e9fa03dd48da4592ebaadb4e3794e0
0, 1, 1, 1, 152064, 5172e29b1e04cd543833d6a68aab297c
diff --git a/tests/ref/fate/vp9-00-quantizer-58 b/tests/ref/fate/vp9-00-quantizer-58
index 2b02267..2a10350 100644
--- a/tests/ref/fate/vp9-00-quantizer-58
+++ b/tests/ref/fate/vp9-00-quantizer-58
@@ -1,3 +1,7 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 152064, bef4a27d460e7697e038fe6f1c8bd597
0, 1, 1, 1, 152064, 124674686cafc5f2ff5bc7ea412b8f3b
diff --git a/tests/ref/fate/vp9-00-quantizer-59 b/tests/ref/fate/vp9-00-quantizer-59
index 2ea4328..8ae9bd3 100644
--- a/tests/ref/fate/vp9-00-quantizer-59
+++ b/tests/ref/fate/vp9-00-quantizer-59
@@ -1,3 +1,7 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 152064, ae9d99e9d16ef20073300559566844ae
0, 1, 1, 1, 152064, da9405e5a6bfe4ed18d927ba2004008e
diff --git a/tests/ref/fate/vp9-00-quantizer-60 b/tests/ref/fate/vp9-00-quantizer-60
index b042f3a..a409462 100644
--- a/tests/ref/fate/vp9-00-quantizer-60
+++ b/tests/ref/fate/vp9-00-quantizer-60
@@ -1,3 +1,7 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 152064, 9e66bb8e1b5e206ea4afe4bf2d335ac5
0, 1, 1, 1, 152064, 092b74c905c12c1e87e90f5a79857736
diff --git a/tests/ref/fate/vp9-00-quantizer-61 b/tests/ref/fate/vp9-00-quantizer-61
index cc8e72a..92aa67f 100644
--- a/tests/ref/fate/vp9-00-quantizer-61
+++ b/tests/ref/fate/vp9-00-quantizer-61
@@ -1,3 +1,7 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 152064, d062dc6be246c8042744018765ef50a8
0, 1, 1, 1, 152064, 45fd9cbacb6a91060a7e49a58a85869d
diff --git a/tests/ref/fate/vp9-00-quantizer-62 b/tests/ref/fate/vp9-00-quantizer-62
index 8811574..d17d3d6 100644
--- a/tests/ref/fate/vp9-00-quantizer-62
+++ b/tests/ref/fate/vp9-00-quantizer-62
@@ -1,3 +1,7 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 152064, 62f7e42fe653e81c5a65a25389e045b5
0, 1, 1, 1, 152064, cb0cdd0b25689e0a43328550011d960d
diff --git a/tests/ref/fate/vp9-00-quantizer-63 b/tests/ref/fate/vp9-00-quantizer-63
index ab62af8..d7765be 100644
--- a/tests/ref/fate/vp9-00-quantizer-63
+++ b/tests/ref/fate/vp9-00-quantizer-63
@@ -1,3 +1,7 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 152064, 8467643dceff827e04acd82eeff1d1b0
0, 1, 1, 1, 152064, c786f49d66f4dfd685dea9605821a19f
diff --git a/tests/ref/fate/vp9-01-sharpness-1 b/tests/ref/fate/vp9-01-sharpness-1
index 3e26060..02e6e16 100644
--- a/tests/ref/fate/vp9-01-sharpness-1
+++ b/tests/ref/fate/vp9-01-sharpness-1
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 152064, a2e5c820fd9733e18f9349fb658ca281
0, 1, 1, 1, 152064, aa20a75be3a316193496706c9f760d08
0, 2, 2, 1, 152064, 95567be97a64d3c9efe45f2524116a2e
diff --git a/tests/ref/fate/vp9-01-sharpness-2 b/tests/ref/fate/vp9-01-sharpness-2
index e598727..51238c1 100644
--- a/tests/ref/fate/vp9-01-sharpness-2
+++ b/tests/ref/fate/vp9-01-sharpness-2
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 152064, a2e5c820fd9733e18f9349fb658ca281
0, 1, 1, 1, 152064, cd94572239817ae7c9b07de739c3272b
0, 2, 2, 1, 152064, 383cf752d457e122b5ff49d08960208e
diff --git a/tests/ref/fate/vp9-01-sharpness-3 b/tests/ref/fate/vp9-01-sharpness-3
index 29e8f55..e1af6f6 100644
--- a/tests/ref/fate/vp9-01-sharpness-3
+++ b/tests/ref/fate/vp9-01-sharpness-3
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 152064, a2e5c820fd9733e18f9349fb658ca281
0, 1, 1, 1, 152064, 0d487a146393a0b8b84b4be1b371b507
0, 2, 2, 1, 152064, 68372e191eba620a431cfff226026ac3
diff --git a/tests/ref/fate/vp9-01-sharpness-4 b/tests/ref/fate/vp9-01-sharpness-4
index e6a9893..977095f 100644
--- a/tests/ref/fate/vp9-01-sharpness-4
+++ b/tests/ref/fate/vp9-01-sharpness-4
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 152064, a2e5c820fd9733e18f9349fb658ca281
0, 1, 1, 1, 152064, 8bad76c55b5149169d64ce6512521de6
0, 2, 2, 1, 152064, c1d986e1f9bf46382e598ba289b9bd7c
diff --git a/tests/ref/fate/vp9-01-sharpness-5 b/tests/ref/fate/vp9-01-sharpness-5
index 8440700..c0cf715 100644
--- a/tests/ref/fate/vp9-01-sharpness-5
+++ b/tests/ref/fate/vp9-01-sharpness-5
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 152064, a2e5c820fd9733e18f9349fb658ca281
0, 1, 1, 1, 152064, f1ce0a5d57a46c9ff1331804b7b03fdb
0, 2, 2, 1, 152064, 0364a085b06bee6b980189cf5378eda9
diff --git a/tests/ref/fate/vp9-01-sharpness-6 b/tests/ref/fate/vp9-01-sharpness-6
index 116273c..2e52d32 100644
--- a/tests/ref/fate/vp9-01-sharpness-6
+++ b/tests/ref/fate/vp9-01-sharpness-6
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 152064, a2e5c820fd9733e18f9349fb658ca281
0, 1, 1, 1, 152064, 45d9ca07ed04210b1ebc743169bc8ec4
0, 2, 2, 1, 152064, 5b646cc309a711f1d8814f925002d8c4
diff --git a/tests/ref/fate/vp9-01-sharpness-7 b/tests/ref/fate/vp9-01-sharpness-7
index d682bb5..b2b5fda 100644
--- a/tests/ref/fate/vp9-01-sharpness-7
+++ b/tests/ref/fate/vp9-01-sharpness-7
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 152064, a2e5c820fd9733e18f9349fb658ca281
0, 1, 1, 1, 152064, f719d0be18d16a448b4e7da3e2d9bf28
0, 2, 2, 1, 152064, 83ee8ebc0ca796782a2376a76f2ffc26
diff --git a/tests/ref/fate/vp9-02-size-08x08 b/tests/ref/fate/vp9-02-size-08x08
index 70d2c16..403a131 100644
--- a/tests/ref/fate/vp9-02-size-08x08
+++ b/tests/ref/fate/vp9-02-size-08x08
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 96, 52def242c36123e5a8f5f53d6a971399
0, 1, 1, 1, 96, 79c93360fbd47179400414bbfee0901c
0, 2, 2, 1, 96, c3b1947c79537baa7838905276276a91
diff --git a/tests/ref/fate/vp9-02-size-08x10 b/tests/ref/fate/vp9-02-size-08x10
index 0d8c0d8..01d8818 100644
--- a/tests/ref/fate/vp9-02-size-08x10
+++ b/tests/ref/fate/vp9-02-size-08x10
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 120, ea3e0f807304b0eb2d3e329b0124f75c
0, 1, 1, 1, 120, 8d13cf682d63e7eb13094f55d67fc458
0, 2, 2, 1, 120, e729cc6c3684c94a8f6118c618efc3ea
diff --git a/tests/ref/fate/vp9-02-size-08x16 b/tests/ref/fate/vp9-02-size-08x16
index 5bdc9f7..d72aafc 100644
--- a/tests/ref/fate/vp9-02-size-08x16
+++ b/tests/ref/fate/vp9-02-size-08x16
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 192, 0553e56a9d89aea496421885aab491f5
0, 1, 1, 1, 192, b2a14cf676f7ebf3c50450050f76ad16
0, 2, 2, 1, 192, a308d981e09b50571fb0c8ebdcefe505
diff --git a/tests/ref/fate/vp9-02-size-08x18 b/tests/ref/fate/vp9-02-size-08x18
index a4aa018..8615d7b 100644
--- a/tests/ref/fate/vp9-02-size-08x18
+++ b/tests/ref/fate/vp9-02-size-08x18
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 216, 4c41f93b1b280b37bc77d7047435eaa4
0, 1, 1, 1, 216, c9c80fdba2ebc2b8c3490ae35e34f84f
0, 2, 2, 1, 216, 089d86acb3263fa5ef4f591a7f44556d
diff --git a/tests/ref/fate/vp9-02-size-08x32 b/tests/ref/fate/vp9-02-size-08x32
index 2d72ba3..55ab620 100644
--- a/tests/ref/fate/vp9-02-size-08x32
+++ b/tests/ref/fate/vp9-02-size-08x32
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 384, f92a7777fd69aa2f2914d9a41c4828ba
0, 1, 1, 1, 384, 62e1cc73487d2249a88a60e35a22d9c7
0, 2, 2, 1, 384, aa2619b605cb65eda15fdd99d5775550
diff --git a/tests/ref/fate/vp9-02-size-08x34 b/tests/ref/fate/vp9-02-size-08x34
index 102eb47..bdcedbf 100644
--- a/tests/ref/fate/vp9-02-size-08x34
+++ b/tests/ref/fate/vp9-02-size-08x34
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 408, f3f2cd8f157466ff23dace85d77367ce
0, 1, 1, 1, 408, 639d9b70a14062e95559c12d2b597f91
0, 2, 2, 1, 408, b2ee07a6656af583f19593229fa11848
diff --git a/tests/ref/fate/vp9-02-size-08x64 b/tests/ref/fate/vp9-02-size-08x64
index d4f827a..3226dfa 100644
--- a/tests/ref/fate/vp9-02-size-08x64
+++ b/tests/ref/fate/vp9-02-size-08x64
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 768, 764bd02b781a38c621a109c12f3d9393
0, 1, 1, 1, 768, 79496bd2b9212026af816b3b7a0587d5
0, 2, 2, 1, 768, 2a3afd47ba3d075033fd94d5c3746c45
diff --git a/tests/ref/fate/vp9-02-size-08x66 b/tests/ref/fate/vp9-02-size-08x66
index 675e0f2..7aaa369 100644
--- a/tests/ref/fate/vp9-02-size-08x66
+++ b/tests/ref/fate/vp9-02-size-08x66
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 792, df20e8df89449fe50bb610e95a449a95
0, 1, 1, 1, 792, 18f1a66d463274d1b0489f3a50e86857
0, 2, 2, 1, 792, b0cc102875a94c9a92e53826617adbe9
diff --git a/tests/ref/fate/vp9-02-size-10x08 b/tests/ref/fate/vp9-02-size-10x08
index d4fa723..5708cd3 100644
--- a/tests/ref/fate/vp9-02-size-10x08
+++ b/tests/ref/fate/vp9-02-size-10x08
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 120, e1e66a88615da98523ef887f1463fc42
0, 1, 1, 1, 120, 549842fa98c8faf572882d38b0aae390
0, 2, 2, 1, 120, 17ee85785517705fdc78c6122a4b2548
diff --git a/tests/ref/fate/vp9-02-size-10x10 b/tests/ref/fate/vp9-02-size-10x10
index d46eaa0..a60e36b 100644
--- a/tests/ref/fate/vp9-02-size-10x10
+++ b/tests/ref/fate/vp9-02-size-10x10
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 150, 083d638f2e147295d817bb14fff5e4f4
0, 1, 1, 1, 150, 6dbdc445b6fd6bb99f2025cc2a40977e
0, 2, 2, 1, 150, 41714089383b181d64fbfa7de5904608
diff --git a/tests/ref/fate/vp9-02-size-10x16 b/tests/ref/fate/vp9-02-size-10x16
index c66861c..659d491 100644
--- a/tests/ref/fate/vp9-02-size-10x16
+++ b/tests/ref/fate/vp9-02-size-10x16
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 240, fab07d6209d2413e0a434e1aaaa12154
0, 1, 1, 1, 240, f9ffffdb96f98527ba2e553d1265edbb
0, 2, 2, 1, 240, 56a992264cf7da2b23dd97435e9d0365
diff --git a/tests/ref/fate/vp9-02-size-10x18 b/tests/ref/fate/vp9-02-size-10x18
index 8cee77d..d4069c9 100644
--- a/tests/ref/fate/vp9-02-size-10x18
+++ b/tests/ref/fate/vp9-02-size-10x18
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 270, 0e9182e214aae732d94d007e5fe44888
0, 1, 1, 1, 270, 2630e2674b5611d68218fddac08815e2
0, 2, 2, 1, 270, d5cdd7d6a3de17939f60bb60ef6877da
diff --git a/tests/ref/fate/vp9-02-size-10x32 b/tests/ref/fate/vp9-02-size-10x32
index 5736e55..f5ec31c 100644
--- a/tests/ref/fate/vp9-02-size-10x32
+++ b/tests/ref/fate/vp9-02-size-10x32
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 480, 622e6407a051ea08706394d03330ffbf
0, 1, 1, 1, 480, 1841a0daf7c3ef7be94e01fdb1d3968a
0, 2, 2, 1, 480, 37790e6cb2415f7add0ac5d3ab354755
diff --git a/tests/ref/fate/vp9-02-size-10x34 b/tests/ref/fate/vp9-02-size-10x34
index c41d03b..950b04e 100644
--- a/tests/ref/fate/vp9-02-size-10x34
+++ b/tests/ref/fate/vp9-02-size-10x34
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 510, bfeeaf51f972fd0dfe9ee757083cbb54
0, 1, 1, 1, 510, 10cd4ed6d762004846412d9cd0caa407
0, 2, 2, 1, 510, 04cca4008d656ed180de88dd2ddb4f21
diff --git a/tests/ref/fate/vp9-02-size-10x64 b/tests/ref/fate/vp9-02-size-10x64
index eff631f..04a5e7e 100644
--- a/tests/ref/fate/vp9-02-size-10x64
+++ b/tests/ref/fate/vp9-02-size-10x64
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 960, 835254d0eecb17bed1f2b0f3a1638165
0, 1, 1, 1, 960, c0c95ce9890eab339a0e0f8b26cb095c
0, 2, 2, 1, 960, f0337d645ade07cb716952b0d19352e8
diff --git a/tests/ref/fate/vp9-02-size-10x66 b/tests/ref/fate/vp9-02-size-10x66
index a138dba..f26965a 100644
--- a/tests/ref/fate/vp9-02-size-10x66
+++ b/tests/ref/fate/vp9-02-size-10x66
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 990, 1bd8b2d3bf679c4b925780bf82e12fae
0, 1, 1, 1, 990, a0254b4cd4928fe1080cd6f8828288a9
0, 2, 2, 1, 990, e416e99644cca481dc2806708d716ecb
diff --git a/tests/ref/fate/vp9-02-size-16x08 b/tests/ref/fate/vp9-02-size-16x08
index 611e99d..84e9b17 100644
--- a/tests/ref/fate/vp9-02-size-16x08
+++ b/tests/ref/fate/vp9-02-size-16x08
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 192, 68dccd167f9aa18df0840ebb8715eb68
0, 1, 1, 1, 192, 65c90bb99fdbee7abf21031d34cb18dc
0, 2, 2, 1, 192, 9ef1feb2dcbd4d73f3ee84e9e1cd2668
diff --git a/tests/ref/fate/vp9-02-size-16x10 b/tests/ref/fate/vp9-02-size-16x10
index 766ad34..8490e4e 100644
--- a/tests/ref/fate/vp9-02-size-16x10
+++ b/tests/ref/fate/vp9-02-size-16x10
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 240, fb3cad61d7d9eb511758dbf87dd8abe1
0, 1, 1, 1, 240, 4fbc1aa5559c8db2930803893bd6ba75
0, 2, 2, 1, 240, 2d8e2ee04dcc6097ca9e3f27070cdcc8
diff --git a/tests/ref/fate/vp9-02-size-16x16 b/tests/ref/fate/vp9-02-size-16x16
index da03844..fb6f0c8 100644
--- a/tests/ref/fate/vp9-02-size-16x16
+++ b/tests/ref/fate/vp9-02-size-16x16
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 384, b5c9daafa548e54a8e33e9881fda33f4
0, 1, 1, 1, 384, 1193acd7ea4b7aac968e35ef83c64378
0, 2, 2, 1, 384, cd0e42c0b5a8b3be6f0e1d224062bf99
diff --git a/tests/ref/fate/vp9-02-size-16x18 b/tests/ref/fate/vp9-02-size-16x18
index 789122f..fadce55 100644
--- a/tests/ref/fate/vp9-02-size-16x18
+++ b/tests/ref/fate/vp9-02-size-16x18
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 432, 5156b11cd9995d0c1638c9b0d2b0786c
0, 1, 1, 1, 432, ef78557f93fb3ea770c7d49ab60edf21
0, 2, 2, 1, 432, f31fb9bb14566e4538a45ac7bf398b2a
diff --git a/tests/ref/fate/vp9-02-size-16x32 b/tests/ref/fate/vp9-02-size-16x32
index 88bab47..02a2676 100644
--- a/tests/ref/fate/vp9-02-size-16x32
+++ b/tests/ref/fate/vp9-02-size-16x32
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 768, c73d611490a5ddec6c690589deaf5e86
0, 1, 1, 1, 768, 5d8eaeb222aa64abda59ce7b09b2f6d9
0, 2, 2, 1, 768, 34321856b8dd5bbb9b63db04d3532289
diff --git a/tests/ref/fate/vp9-02-size-16x34 b/tests/ref/fate/vp9-02-size-16x34
index 79c278e..97e527f 100644
--- a/tests/ref/fate/vp9-02-size-16x34
+++ b/tests/ref/fate/vp9-02-size-16x34
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 816, b8bf711d9a1ce49180ed56407c8a4b0a
0, 1, 1, 1, 816, 0457929b06ce46aec63d66bd38586e3f
0, 2, 2, 1, 816, 3b5f417ee5a936797a6f0d138b8ed73b
diff --git a/tests/ref/fate/vp9-02-size-16x64 b/tests/ref/fate/vp9-02-size-16x64
index 13e8ea1..63dbf24 100644
--- a/tests/ref/fate/vp9-02-size-16x64
+++ b/tests/ref/fate/vp9-02-size-16x64
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 1536, 925fdc485f3baa1ed145ae391519d7fd
0, 1, 1, 1, 1536, d37af656da2d7a727c8451773495d5ed
0, 2, 2, 1, 1536, 8a0f207a99e46f3d3b2aaa3f1b061981
diff --git a/tests/ref/fate/vp9-02-size-16x66 b/tests/ref/fate/vp9-02-size-16x66
index 1b4b3d7..f7d0102 100644
--- a/tests/ref/fate/vp9-02-size-16x66
+++ b/tests/ref/fate/vp9-02-size-16x66
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 1584, c7b0d91f362dff0a581434af6e902d43
0, 1, 1, 1, 1584, d8b016ef59c6bc193b29d1c714f342c1
0, 2, 2, 1, 1584, c520bd8d4b81aafc7687befff66c7396
diff --git a/tests/ref/fate/vp9-02-size-18x08 b/tests/ref/fate/vp9-02-size-18x08
index 249640b..08aabcc 100644
--- a/tests/ref/fate/vp9-02-size-18x08
+++ b/tests/ref/fate/vp9-02-size-18x08
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 216, 3219af4ef540636b0f67a989e9966059
0, 1, 1, 1, 216, 1a3655c2cfd2ee332bc89da5b3faf778
0, 2, 2, 1, 216, d638d5b361a6d81440e26993ed86c97d
diff --git a/tests/ref/fate/vp9-02-size-18x10 b/tests/ref/fate/vp9-02-size-18x10
index 6678d1f..9323a14 100644
--- a/tests/ref/fate/vp9-02-size-18x10
+++ b/tests/ref/fate/vp9-02-size-18x10
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 270, bf574489e9360b6475aa012c747e7924
0, 1, 1, 1, 270, 851100301c2937312a6fd32f5aab5a09
0, 2, 2, 1, 270, 0f7c1209e44ea7cd4df12d82f9224684
diff --git a/tests/ref/fate/vp9-02-size-18x16 b/tests/ref/fate/vp9-02-size-18x16
index 09d266e..a3a91b9 100644
--- a/tests/ref/fate/vp9-02-size-18x16
+++ b/tests/ref/fate/vp9-02-size-18x16
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 432, 9535aaa2ea26fbdc16e7fe9cba3fc9b4
0, 1, 1, 1, 432, 7f6e7ca33c0b27ff052dc2ab6721e37d
0, 2, 2, 1, 432, d37e3f169457a9c7f2a197353e39d3d6
diff --git a/tests/ref/fate/vp9-02-size-18x18 b/tests/ref/fate/vp9-02-size-18x18
index fb2322a..b90faf3 100644
--- a/tests/ref/fate/vp9-02-size-18x18
+++ b/tests/ref/fate/vp9-02-size-18x18
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 486, 83790b0e7004d8d89b7134ee1a88d885
0, 1, 1, 1, 486, 0baf0bf556ae56d2f4b04567e6ac7ed9
0, 2, 2, 1, 486, c648854a4d49f7e407a2450cf4ba292a
diff --git a/tests/ref/fate/vp9-02-size-18x32 b/tests/ref/fate/vp9-02-size-18x32
index e528048..b7bd74b 100644
--- a/tests/ref/fate/vp9-02-size-18x32
+++ b/tests/ref/fate/vp9-02-size-18x32
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 864, 62eabc8819ded6ddba2c3a5029497cf0
0, 1, 1, 1, 864, b760182fddf8bc05f149e80bbcb2c281
0, 2, 2, 1, 864, 0c44be0472ebd2653ce9fb174c6180ab
diff --git a/tests/ref/fate/vp9-02-size-18x34 b/tests/ref/fate/vp9-02-size-18x34
index c6ddbbd..0f46da7 100644
--- a/tests/ref/fate/vp9-02-size-18x34
+++ b/tests/ref/fate/vp9-02-size-18x34
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 918, 612cc424eaae924cb25c7732c422f752
0, 1, 1, 1, 918, 010e8c2a814862529fcf8d7771ba2d7f
0, 2, 2, 1, 918, 7d791b7a5916738998f77586339d5840
diff --git a/tests/ref/fate/vp9-02-size-18x64 b/tests/ref/fate/vp9-02-size-18x64
index 99ec59e..172422c 100644
--- a/tests/ref/fate/vp9-02-size-18x64
+++ b/tests/ref/fate/vp9-02-size-18x64
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 1728, 72c74de547d9ed1b17bc962dbd5e0bb1
0, 1, 1, 1, 1728, 462849f9e2204738e9f08b40e682a6ae
0, 2, 2, 1, 1728, f0ee17692fd816747b11d5737b511cda
diff --git a/tests/ref/fate/vp9-02-size-18x66 b/tests/ref/fate/vp9-02-size-18x66
index e8cf87c..c400956 100644
--- a/tests/ref/fate/vp9-02-size-18x66
+++ b/tests/ref/fate/vp9-02-size-18x66
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 1782, c3fc4a1593b9cc2f3752106af8539386
0, 1, 1, 1, 1782, 7f2ffe6bc1750f6749bb5ad12cbaf34b
0, 2, 2, 1, 1782, 2539b10a981d59ef54efd77cd7276aaa
diff --git a/tests/ref/fate/vp9-02-size-32x08 b/tests/ref/fate/vp9-02-size-32x08
index ffc678f..2df5adc 100644
--- a/tests/ref/fate/vp9-02-size-32x08
+++ b/tests/ref/fate/vp9-02-size-32x08
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 384, c7b30cde5664387b0f7a80d9b01e4fe2
0, 1, 1, 1, 384, 2228a2a4e54ab5145525e5803c314dcd
0, 2, 2, 1, 384, 8c048469eba24f3163c36b7461b3b42a
diff --git a/tests/ref/fate/vp9-02-size-32x10 b/tests/ref/fate/vp9-02-size-32x10
index 0469c7c..f5f45fb 100644
--- a/tests/ref/fate/vp9-02-size-32x10
+++ b/tests/ref/fate/vp9-02-size-32x10
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 480, 7c5b5df373ebfd31d210ff910e02213b
0, 1, 1, 1, 480, c5b0a5e3eceb792b15818324a43aa2a8
0, 2, 2, 1, 480, 1d9c0eafd4638dfe4fe308174fde2faf
diff --git a/tests/ref/fate/vp9-02-size-32x16 b/tests/ref/fate/vp9-02-size-32x16
index 76f7860..4aac211 100644
--- a/tests/ref/fate/vp9-02-size-32x16
+++ b/tests/ref/fate/vp9-02-size-32x16
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 768, 7c2818db2632e5c5beee17e7105d9209
0, 1, 1, 1, 768, cead72bd22995e98b54a91c7b4a20975
0, 2, 2, 1, 768, eb6baee5d65d778052c88ba5db2f9174
diff --git a/tests/ref/fate/vp9-02-size-32x18 b/tests/ref/fate/vp9-02-size-32x18
index 08201db..2b30219 100644
--- a/tests/ref/fate/vp9-02-size-32x18
+++ b/tests/ref/fate/vp9-02-size-32x18
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 864, 9da5409d344e7b8380688569e54803a5
0, 1, 1, 1, 864, 9b51e14e2e624ee2b430e9eaf1a48798
0, 2, 2, 1, 864, b8811779f363b9a595e3a92737771ea9
diff --git a/tests/ref/fate/vp9-02-size-32x32 b/tests/ref/fate/vp9-02-size-32x32
index 01f414f..e9de2ed 100644
--- a/tests/ref/fate/vp9-02-size-32x32
+++ b/tests/ref/fate/vp9-02-size-32x32
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 1536, 117915db1856cee26f05a609c8c8de2e
0, 1, 1, 1, 1536, 943771a98b26b174e88ed1f4e872e504
0, 2, 2, 1, 1536, 3e0d2585e1f1cb540998d107aca5c395
diff --git a/tests/ref/fate/vp9-02-size-32x34 b/tests/ref/fate/vp9-02-size-32x34
index efbe847..e1e00fd 100644
--- a/tests/ref/fate/vp9-02-size-32x34
+++ b/tests/ref/fate/vp9-02-size-32x34
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 1632, 770582911fd0095ebbeae384e87665ac
0, 1, 1, 1, 1632, f99d7e3131f04413cba2f9de6818976d
0, 2, 2, 1, 1632, 3bfbb8c9c48f24cd596973a6deb33a3f
diff --git a/tests/ref/fate/vp9-02-size-32x64 b/tests/ref/fate/vp9-02-size-32x64
index d14a6a4..c39c88d 100644
--- a/tests/ref/fate/vp9-02-size-32x64
+++ b/tests/ref/fate/vp9-02-size-32x64
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 3072, caa8471a8b381d53c3e8fc627946a871
0, 1, 1, 1, 3072, 2cba86ea14c0f28e242625b08f5e9b88
0, 2, 2, 1, 3072, cea0440ff6569fc82c3030e0340fb649
diff --git a/tests/ref/fate/vp9-02-size-32x66 b/tests/ref/fate/vp9-02-size-32x66
index 4e8c426..d036df1 100644
--- a/tests/ref/fate/vp9-02-size-32x66
+++ b/tests/ref/fate/vp9-02-size-32x66
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 3168, 920ea4b8a00d41489d122d641d6e4fe5
0, 1, 1, 1, 3168, 8bfc8d452a79f2978b8e973b77cbf8a8
0, 2, 2, 1, 3168, 09f3f0d31d3377a844fa5385d9b36b9f
diff --git a/tests/ref/fate/vp9-02-size-34x08 b/tests/ref/fate/vp9-02-size-34x08
index 23fa1ee..5869186 100644
--- a/tests/ref/fate/vp9-02-size-34x08
+++ b/tests/ref/fate/vp9-02-size-34x08
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 408, c14f2ba5b4582c9d3a488976814691b3
0, 1, 1, 1, 408, 4387a4dce19007b7efb810b5a4069749
0, 2, 2, 1, 408, ecfe868d28f4861a5612edfd57447a02
diff --git a/tests/ref/fate/vp9-02-size-34x10 b/tests/ref/fate/vp9-02-size-34x10
index b7aad33..a2ce10e 100644
--- a/tests/ref/fate/vp9-02-size-34x10
+++ b/tests/ref/fate/vp9-02-size-34x10
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 510, fd7212b519783cf4831ce4bff91f2312
0, 1, 1, 1, 510, 9768722ee939d80a6716865fdebca33d
0, 2, 2, 1, 510, 328ee0f774eeafde00dcc4b9a8f4e9af
diff --git a/tests/ref/fate/vp9-02-size-34x16 b/tests/ref/fate/vp9-02-size-34x16
index 6630d73..0c8dc67 100644
--- a/tests/ref/fate/vp9-02-size-34x16
+++ b/tests/ref/fate/vp9-02-size-34x16
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 816, e443c43101be00470c6a61c1a2995b5a
0, 1, 1, 1, 816, 1e79b1b46ec704d360b5fb725913b0f1
0, 2, 2, 1, 816, 6d5e77cafab6bc43498980c515d299d3
diff --git a/tests/ref/fate/vp9-02-size-34x18 b/tests/ref/fate/vp9-02-size-34x18
index 787f4ff..8c92b2d 100644
--- a/tests/ref/fate/vp9-02-size-34x18
+++ b/tests/ref/fate/vp9-02-size-34x18
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 918, ab7eabb355e5163e7451945018fadebd
0, 1, 1, 1, 918, b9a77cc0c769535808996a6de7b374ff
0, 2, 2, 1, 918, bd773f11d89091b3c9ebc22d8291dd49
diff --git a/tests/ref/fate/vp9-02-size-34x32 b/tests/ref/fate/vp9-02-size-34x32
index 242e9ef..a9f804e 100644
--- a/tests/ref/fate/vp9-02-size-34x32
+++ b/tests/ref/fate/vp9-02-size-34x32
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 1632, 7e334867e27046fabf0f39365311c38c
0, 1, 1, 1, 1632, d2a49216ecedea62f546e54c1552f163
0, 2, 2, 1, 1632, f66e10d1779533e5b6e2b98369134833
diff --git a/tests/ref/fate/vp9-02-size-34x34 b/tests/ref/fate/vp9-02-size-34x34
index 10ae9c2..4bed149 100644
--- a/tests/ref/fate/vp9-02-size-34x34
+++ b/tests/ref/fate/vp9-02-size-34x34
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 1734, 1bb98ba89abf6b86f47a851f8126e1ff
0, 1, 1, 1, 1734, b960cc795c179afe7eec360c57fddd7f
0, 2, 2, 1, 1734, a93cd094a80c542ecb7b6ac7720c5eff
diff --git a/tests/ref/fate/vp9-02-size-34x64 b/tests/ref/fate/vp9-02-size-34x64
index 432f93c..ac61f27 100644
--- a/tests/ref/fate/vp9-02-size-34x64
+++ b/tests/ref/fate/vp9-02-size-34x64
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 3264, 3856635223f578e1e7f7e7250a53cb8d
0, 1, 1, 1, 3264, ee8d7c3a0ea165420d7e733b9e59219a
0, 2, 2, 1, 3264, 3d33f06bac22131f04e3411fc216dc02
diff --git a/tests/ref/fate/vp9-02-size-34x66 b/tests/ref/fate/vp9-02-size-34x66
index e28d80c..2bc9eb6 100644
--- a/tests/ref/fate/vp9-02-size-34x66
+++ b/tests/ref/fate/vp9-02-size-34x66
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 3366, bf4e568217906ee4b58dc4707bee8ef6
0, 1, 1, 1, 3366, f823f8c7b6e47ba43215f3becd35208e
0, 2, 2, 1, 3366, 1d986d65b502e77764428e21e77503a6
diff --git a/tests/ref/fate/vp9-02-size-64x08 b/tests/ref/fate/vp9-02-size-64x08
index 92d64e9..e1e01ee 100644
--- a/tests/ref/fate/vp9-02-size-64x08
+++ b/tests/ref/fate/vp9-02-size-64x08
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 768, d801797c94039b0a166d46e151ec912c
0, 1, 1, 1, 768, 161ec22caa3689b214d9ab993424584b
0, 2, 2, 1, 768, 499b589ecf1873e388c256ce948eabb9
diff --git a/tests/ref/fate/vp9-02-size-64x10 b/tests/ref/fate/vp9-02-size-64x10
index 47f46af..046e7ee 100644
--- a/tests/ref/fate/vp9-02-size-64x10
+++ b/tests/ref/fate/vp9-02-size-64x10
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 960, 97eb5fd0599d482662eb0a1def5c5ef2
0, 1, 1, 1, 960, dfdc1b61b478dcca8d411021486aa2ec
0, 2, 2, 1, 960, 2cf560f068bdcb9e345951739091808e
diff --git a/tests/ref/fate/vp9-02-size-64x16 b/tests/ref/fate/vp9-02-size-64x16
index 50920f2..16cb5dd 100644
--- a/tests/ref/fate/vp9-02-size-64x16
+++ b/tests/ref/fate/vp9-02-size-64x16
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 1536, a43068a364cc42619e62406dcf17ddfc
0, 1, 1, 1, 1536, 94691f93299bbf5b6ba3022b02b3e069
0, 2, 2, 1, 1536, 3c8fc275490b4daf63ef6d8f9b7f81f6
diff --git a/tests/ref/fate/vp9-02-size-64x18 b/tests/ref/fate/vp9-02-size-64x18
index ec9bc2d..427acca 100644
--- a/tests/ref/fate/vp9-02-size-64x18
+++ b/tests/ref/fate/vp9-02-size-64x18
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 1728, adf7e84a351847683f6a8dd177019e29
0, 1, 1, 1, 1728, 8227cf283a27277fbab3d7826e340337
0, 2, 2, 1, 1728, a5551b16db948e395537310d12128e76
diff --git a/tests/ref/fate/vp9-02-size-64x32 b/tests/ref/fate/vp9-02-size-64x32
index 51ce4ad..a0f033e 100644
--- a/tests/ref/fate/vp9-02-size-64x32
+++ b/tests/ref/fate/vp9-02-size-64x32
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 3072, 931ab6a2482c3e84bc7ef8dfbc251307
0, 1, 1, 1, 3072, 3552a9d8470a64ed627a6dbb799b7811
0, 2, 2, 1, 3072, cae1863fc606a0e3df3e708b7eefdf99
diff --git a/tests/ref/fate/vp9-02-size-64x34 b/tests/ref/fate/vp9-02-size-64x34
index 7f9c0f3..a852272 100644
--- a/tests/ref/fate/vp9-02-size-64x34
+++ b/tests/ref/fate/vp9-02-size-64x34
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 3264, 68d00958a78e6252dd75d632806e2022
0, 1, 1, 1, 3264, f7b6266e74200a669eecd241db787ee2
0, 2, 2, 1, 3264, c8b88d43aee037857310edeb74bc66f4
diff --git a/tests/ref/fate/vp9-02-size-64x64 b/tests/ref/fate/vp9-02-size-64x64
index 8d32eae..418febe 100644
--- a/tests/ref/fate/vp9-02-size-64x64
+++ b/tests/ref/fate/vp9-02-size-64x64
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 6144, 35f17db9076fa20368fddfa01543c746
0, 1, 1, 1, 6144, 61cd775dfc177262da9a91d3912e6718
0, 2, 2, 1, 6144, 8b8cf175f91425d703332b22b46c1c0e
diff --git a/tests/ref/fate/vp9-02-size-64x66 b/tests/ref/fate/vp9-02-size-64x66
index b7e5f13..d358bd6 100644
--- a/tests/ref/fate/vp9-02-size-64x66
+++ b/tests/ref/fate/vp9-02-size-64x66
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 6336, 88587de65acfc85ff56daac8ef5d12e6
0, 1, 1, 1, 6336, be41f6c788b929b5b6b27c5674f40abd
0, 2, 2, 1, 6336, 04ab3f88ca062a6911405fd84c7e9de4
diff --git a/tests/ref/fate/vp9-02-size-66x08 b/tests/ref/fate/vp9-02-size-66x08
index 6fe4e6f..426f91b 100644
--- a/tests/ref/fate/vp9-02-size-66x08
+++ b/tests/ref/fate/vp9-02-size-66x08
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 792, 3b16847e60786706fc339abc452746ff
0, 1, 1, 1, 792, 365a5951cb127d6df183fe5d5000f493
0, 2, 2, 1, 792, 6d4bceb815ca7717c4a3f86a6670703a
diff --git a/tests/ref/fate/vp9-02-size-66x10 b/tests/ref/fate/vp9-02-size-66x10
index 0f85573..8e0133a 100644
--- a/tests/ref/fate/vp9-02-size-66x10
+++ b/tests/ref/fate/vp9-02-size-66x10
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 990, 7cbd8c6b2fb35c0c3063cb7a379944c9
0, 1, 1, 1, 990, 14062e74b98bed1ca982f408bc14326c
0, 2, 2, 1, 990, f6d6868d849aa74b27df1c5f40c7096e
diff --git a/tests/ref/fate/vp9-02-size-66x16 b/tests/ref/fate/vp9-02-size-66x16
index 08937c2..4bdc1ba 100644
--- a/tests/ref/fate/vp9-02-size-66x16
+++ b/tests/ref/fate/vp9-02-size-66x16
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 1584, fa2f292d273c37dc2804a70d1cae1e9d
0, 1, 1, 1, 1584, ba75d90652c021bc7ca061352e6e94ce
0, 2, 2, 1, 1584, e65d9a205bd17d100e50c7b6a7ea772d
diff --git a/tests/ref/fate/vp9-02-size-66x18 b/tests/ref/fate/vp9-02-size-66x18
index b550f36..3b395dd 100644
--- a/tests/ref/fate/vp9-02-size-66x18
+++ b/tests/ref/fate/vp9-02-size-66x18
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 1782, fda5ad9bf70a51b3a41bdcabf2cce32a
0, 1, 1, 1, 1782, 91916fb20ad542a7a3ad276e6505f9b0
0, 2, 2, 1, 1782, e18e5d11aec483c76afd68f7e64415a4
diff --git a/tests/ref/fate/vp9-02-size-66x32 b/tests/ref/fate/vp9-02-size-66x32
index 3e48bed..14b9cb0 100644
--- a/tests/ref/fate/vp9-02-size-66x32
+++ b/tests/ref/fate/vp9-02-size-66x32
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 3168, 013cd22aea6bfeccc8ec809abd52be5c
0, 1, 1, 1, 3168, 0980adfb0ef879b3c960797272f025ad
0, 2, 2, 1, 3168, d1411ffa0429befb8c71d3ab45acee92
diff --git a/tests/ref/fate/vp9-02-size-66x34 b/tests/ref/fate/vp9-02-size-66x34
index fce01c4..79bc91c 100644
--- a/tests/ref/fate/vp9-02-size-66x34
+++ b/tests/ref/fate/vp9-02-size-66x34
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 3366, 6821eb3fcd1d10db32eff70468dcf9c1
0, 1, 1, 1, 3366, ed0094d347d9f250d46b4903cbc14801
0, 2, 2, 1, 3366, fd018555dc9a62b8074d46e7c0fd0b40
diff --git a/tests/ref/fate/vp9-02-size-66x64 b/tests/ref/fate/vp9-02-size-66x64
index 4fb7c22..a89e10f 100644
--- a/tests/ref/fate/vp9-02-size-66x64
+++ b/tests/ref/fate/vp9-02-size-66x64
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 6336, 929086fbb3e117bd53110b64c1ee915b
0, 1, 1, 1, 6336, 9ed45f5e40dd2393434e14a0c0160c63
0, 2, 2, 1, 6336, 5cdade692b1baf23e61896da18e3e44f
diff --git a/tests/ref/fate/vp9-02-size-66x66 b/tests/ref/fate/vp9-02-size-66x66
index c181479..73aa4e7 100644
--- a/tests/ref/fate/vp9-02-size-66x66
+++ b/tests/ref/fate/vp9-02-size-66x66
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 6534, 69f9028d52f95d2e7f986c57b19fc018
0, 1, 1, 1, 6534, 068e611f62b3f6222f6b1699748c8fbf
0, 2, 2, 1, 6534, 3d3fec78ff2274241a7958f17a773a19
diff --git a/tests/ref/fate/vp9-03-deltaq b/tests/ref/fate/vp9-03-deltaq
index 914704c..293abad 100644
--- a/tests/ref/fate/vp9-03-deltaq
+++ b/tests/ref/fate/vp9-03-deltaq
@@ -1,3 +1,7 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1/30
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 126720, 2f90d606edc511c8c960530dd915cb98
0, 1, 1, 1, 126720, 7fd451a057d6341b2b0d116f59e41a13
diff --git a/tests/ref/fate/vp9-03-size-196x196 b/tests/ref/fate/vp9-03-size-196x196
index d7c62e1..1c4156b 100644
--- a/tests/ref/fate/vp9-03-size-196x196
+++ b/tests/ref/fate/vp9-03-size-196x196
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 57624, 14cc1c34b8106e35238d4650a9123852
0, 1, 1, 1, 57624, 66e0bb9136ea24e30b781a4610b428a1
0, 2, 2, 1, 57624, 8e36679c20a3a3e974fdacf7a9343817
diff --git a/tests/ref/fate/vp9-03-size-196x198 b/tests/ref/fate/vp9-03-size-196x198
index 72908cd..294c7de 100644
--- a/tests/ref/fate/vp9-03-size-196x198
+++ b/tests/ref/fate/vp9-03-size-196x198
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 58212, d2bd2dfaf2ac22b3f2499844f228d89a
0, 1, 1, 1, 58212, e066448baeb39da04b22d4d2ebd27b0a
0, 2, 2, 1, 58212, aace53c0ecca2596c51dd5e70da7abc4
diff --git a/tests/ref/fate/vp9-03-size-196x200 b/tests/ref/fate/vp9-03-size-196x200
index 98fb8b9..d0882e5 100644
--- a/tests/ref/fate/vp9-03-size-196x200
+++ b/tests/ref/fate/vp9-03-size-196x200
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 58800, b2f2ac3e3833ae1b4dd075fe00210373
0, 1, 1, 1, 58800, c0cce05e56a07111fe62553fa3a87074
0, 2, 2, 1, 58800, 626aab3de03242073e03504e166b4697
diff --git a/tests/ref/fate/vp9-03-size-196x202 b/tests/ref/fate/vp9-03-size-196x202
index 016e6eb..20f46ea 100644
--- a/tests/ref/fate/vp9-03-size-196x202
+++ b/tests/ref/fate/vp9-03-size-196x202
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 59388, 7109d2ef160828ece26337f36fcfc092
0, 1, 1, 1, 59388, bdaa6612f81a956d9b20d55a04df8346
0, 2, 2, 1, 59388, 15eb75495d2713a64415b990b058d5ca
diff --git a/tests/ref/fate/vp9-03-size-196x208 b/tests/ref/fate/vp9-03-size-196x208
index 8b04856..b1ffd8f 100644
--- a/tests/ref/fate/vp9-03-size-196x208
+++ b/tests/ref/fate/vp9-03-size-196x208
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 61152, efa2a2a76a0fe709a78e491346cfcf29
0, 1, 1, 1, 61152, 97de85e21b408878853fa870104707d7
0, 2, 2, 1, 61152, 419bd1157e156d3059190d6b561c57dd
diff --git a/tests/ref/fate/vp9-03-size-196x210 b/tests/ref/fate/vp9-03-size-196x210
index 3d3f552..7248874 100644
--- a/tests/ref/fate/vp9-03-size-196x210
+++ b/tests/ref/fate/vp9-03-size-196x210
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 61740, fccc18714a9ed3840bd6e9c6ca4858e5
0, 1, 1, 1, 61740, a8f6eb43cf6ed670eb180c5051de06f7
0, 2, 2, 1, 61740, 6a9baf9eae6e799deaefd6e801f7ace3
diff --git a/tests/ref/fate/vp9-03-size-196x224 b/tests/ref/fate/vp9-03-size-196x224
index 45acadb6..fb49188 100644
--- a/tests/ref/fate/vp9-03-size-196x224
+++ b/tests/ref/fate/vp9-03-size-196x224
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 65856, 13263674ea5aa619250dfd139bda872f
0, 1, 1, 1, 65856, 39f5cbd8917f2b3a1df8cf2b786266de
0, 2, 2, 1, 65856, f9aade31f9e3065f3d5b8645ef099ac6
diff --git a/tests/ref/fate/vp9-03-size-196x226 b/tests/ref/fate/vp9-03-size-196x226
index a3f93da..0ef318a 100644
--- a/tests/ref/fate/vp9-03-size-196x226
+++ b/tests/ref/fate/vp9-03-size-196x226
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 66444, 5cb240f10761f59687612ed589759800
0, 1, 1, 1, 66444, 9d8d5b57336ddfa5c9c5100a0302197d
0, 2, 2, 1, 66444, 9db74997d23b16f527c63e88795331dc
diff --git a/tests/ref/fate/vp9-03-size-198x196 b/tests/ref/fate/vp9-03-size-198x196
index 544f4fa..2d02a49 100644
--- a/tests/ref/fate/vp9-03-size-198x196
+++ b/tests/ref/fate/vp9-03-size-198x196
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 58212, c980866a6f17d4107ce128ee112d74cf
0, 1, 1, 1, 58212, d4d5d2a10e73f1d09919355dc4d63d48
0, 2, 2, 1, 58212, 82c76ed020acb68ff9d8bd81899aa6f8
diff --git a/tests/ref/fate/vp9-03-size-198x198 b/tests/ref/fate/vp9-03-size-198x198
index d6e6009..f458f53 100644
--- a/tests/ref/fate/vp9-03-size-198x198
+++ b/tests/ref/fate/vp9-03-size-198x198
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 58806, ee0760611da9938e72f551d219671c76
0, 1, 1, 1, 58806, c512cb8a864c25318254438c7170f373
0, 2, 2, 1, 58806, aaea10aeb7dfd1f9f6dc77adccfcd56f
diff --git a/tests/ref/fate/vp9-03-size-198x200 b/tests/ref/fate/vp9-03-size-198x200
index c980922..176b9d9 100644
--- a/tests/ref/fate/vp9-03-size-198x200
+++ b/tests/ref/fate/vp9-03-size-198x200
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 59400, fb0e8171b0f91d9b2ceb5430db27a67b
0, 1, 1, 1, 59400, 73f121e6aa0e6290cfd06ac9b033c772
0, 2, 2, 1, 59400, 4113897efc44f49f5169a579bee03596
diff --git a/tests/ref/fate/vp9-03-size-198x202 b/tests/ref/fate/vp9-03-size-198x202
index 7147c95..371a874 100644
--- a/tests/ref/fate/vp9-03-size-198x202
+++ b/tests/ref/fate/vp9-03-size-198x202
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 59994, f5e1cf4cc56742fadddf42189a3f65e3
0, 1, 1, 1, 59994, f3e8ca2c8deb29a6b5bfe415b39c901e
0, 2, 2, 1, 59994, 89c513049e41e145bca46a7f7119567c
diff --git a/tests/ref/fate/vp9-03-size-198x208 b/tests/ref/fate/vp9-03-size-198x208
index 2dfed23..95b2e06 100644
--- a/tests/ref/fate/vp9-03-size-198x208
+++ b/tests/ref/fate/vp9-03-size-198x208
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 61776, d45b561f81cbfcca8a1dddbc2bf8ca31
0, 1, 1, 1, 61776, 3664f63b2e59e380622caadb7a05545e
0, 2, 2, 1, 61776, 0662fa199512320704efecc10af1aaa4
diff --git a/tests/ref/fate/vp9-03-size-198x210 b/tests/ref/fate/vp9-03-size-198x210
index 7221fe9..1e2790a 100644
--- a/tests/ref/fate/vp9-03-size-198x210
+++ b/tests/ref/fate/vp9-03-size-198x210
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 62370, 8525a27170982c059d5904c1af3b43fb
0, 1, 1, 1, 62370, c4eb329733913360384d3917a58f6f36
0, 2, 2, 1, 62370, ec118b87c9cba0e4bd89fd43567cca4e
diff --git a/tests/ref/fate/vp9-03-size-198x224 b/tests/ref/fate/vp9-03-size-198x224
index 15d944e..7cccf9b 100644
--- a/tests/ref/fate/vp9-03-size-198x224
+++ b/tests/ref/fate/vp9-03-size-198x224
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 66528, 5f69230bfd8bb485bd85552b18339fc0
0, 1, 1, 1, 66528, f5c365774fc1d0bffd5025ce2e931aaf
0, 2, 2, 1, 66528, 2898234103c3624e6470ae82c916e000
diff --git a/tests/ref/fate/vp9-03-size-198x226 b/tests/ref/fate/vp9-03-size-198x226
index 8036ad3..81136e6 100644
--- a/tests/ref/fate/vp9-03-size-198x226
+++ b/tests/ref/fate/vp9-03-size-198x226
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 67122, 412c33a8fd71c99e68e6701b050b107c
0, 1, 1, 1, 67122, 8e69483ff8a094096dd550b30be20dde
0, 2, 2, 1, 67122, b8df87ab3d2613be31a3743e34d7e794
diff --git a/tests/ref/fate/vp9-03-size-200x196 b/tests/ref/fate/vp9-03-size-200x196
index daa72fc..670d115 100644
--- a/tests/ref/fate/vp9-03-size-200x196
+++ b/tests/ref/fate/vp9-03-size-200x196
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 58800, 651a0627c6cdaee8b46e1f8c4121a368
0, 1, 1, 1, 58800, 3e63075148df16f69c933cf6c63e078c
0, 2, 2, 1, 58800, edf18e52b7d52af2bb7594ed358542d8
diff --git a/tests/ref/fate/vp9-03-size-200x198 b/tests/ref/fate/vp9-03-size-200x198
index 5735262..fd37506 100644
--- a/tests/ref/fate/vp9-03-size-200x198
+++ b/tests/ref/fate/vp9-03-size-200x198
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 59400, d4b3578d800c747bcabaa484a140ffb0
0, 1, 1, 1, 59400, a40f6f8c384c5dc3d5546d960bb6d9e5
0, 2, 2, 1, 59400, e270ae8754d9906dd88b1c7d05280801
diff --git a/tests/ref/fate/vp9-03-size-200x200 b/tests/ref/fate/vp9-03-size-200x200
index d4d8aa1..d5806a1 100644
--- a/tests/ref/fate/vp9-03-size-200x200
+++ b/tests/ref/fate/vp9-03-size-200x200
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 60000, b339f4e563afadb25f43b8c05b12dc03
0, 1, 1, 1, 60000, 3bd5280e7fb42400085b0b1dbba1905e
0, 2, 2, 1, 60000, acf1c84cabff763fe2073d2c1f183bfc
diff --git a/tests/ref/fate/vp9-03-size-200x202 b/tests/ref/fate/vp9-03-size-200x202
index fbaea3a..3f6ee8b 100644
--- a/tests/ref/fate/vp9-03-size-200x202
+++ b/tests/ref/fate/vp9-03-size-200x202
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 60600, c4a13df44e66f06961dd72fc990439e9
0, 1, 1, 1, 60600, 81c73b8d3806ad96af8f422914a253f8
0, 2, 2, 1, 60600, 05f77526125e802be9cb306e375ded6e
diff --git a/tests/ref/fate/vp9-03-size-200x208 b/tests/ref/fate/vp9-03-size-200x208
index 9e354f1..ea1cb0c 100644
--- a/tests/ref/fate/vp9-03-size-200x208
+++ b/tests/ref/fate/vp9-03-size-200x208
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 62400, 702748bec18c500dd41d93ae74b11d56
0, 1, 1, 1, 62400, 4fb542190dab2fd673724d47451ff6ee
0, 2, 2, 1, 62400, dbb4d27d52797dab67e39d32092c9d44
diff --git a/tests/ref/fate/vp9-03-size-200x210 b/tests/ref/fate/vp9-03-size-200x210
index ed8f2b8..7c459d2 100644
--- a/tests/ref/fate/vp9-03-size-200x210
+++ b/tests/ref/fate/vp9-03-size-200x210
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 63000, 31ef44bd12ae702f306c55eba10d2ba7
0, 1, 1, 1, 63000, 83e9d913f5aa058d79a81047ca45e4a2
0, 2, 2, 1, 63000, b5e21313b859f1e2c67aaac5fefc9f68
diff --git a/tests/ref/fate/vp9-03-size-200x224 b/tests/ref/fate/vp9-03-size-200x224
index 082fe91..19a786c 100644
--- a/tests/ref/fate/vp9-03-size-200x224
+++ b/tests/ref/fate/vp9-03-size-200x224
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 67200, 315d69847bf752a84231a368278eb0b6
0, 1, 1, 1, 67200, d245738f8627fc345ab38a547bc7d352
0, 2, 2, 1, 67200, 982681cdca448919c2eead94435772ad
diff --git a/tests/ref/fate/vp9-03-size-200x226 b/tests/ref/fate/vp9-03-size-200x226
index ffdda6b..dd7967d 100644
--- a/tests/ref/fate/vp9-03-size-200x226
+++ b/tests/ref/fate/vp9-03-size-200x226
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 67800, e45b6b9dce4a8509b7d26bc3cfdf7c86
0, 1, 1, 1, 67800, ddb9d5033ecfa2d6e9a5505dce374bda
0, 2, 2, 1, 67800, 52c495d3137143e0bce9382fe5506057
diff --git a/tests/ref/fate/vp9-03-size-202x196 b/tests/ref/fate/vp9-03-size-202x196
index eecdae5..1af7c58 100644
--- a/tests/ref/fate/vp9-03-size-202x196
+++ b/tests/ref/fate/vp9-03-size-202x196
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 59388, 1261466179df96099e598e46c50fa7c1
0, 1, 1, 1, 59388, cc0fe373cd0399cf0c95edf92d9ab01f
0, 2, 2, 1, 59388, 7a2dc0afd06ecfcf54321fb759f57601
diff --git a/tests/ref/fate/vp9-03-size-202x198 b/tests/ref/fate/vp9-03-size-202x198
index 4962640..d51ee96 100644
--- a/tests/ref/fate/vp9-03-size-202x198
+++ b/tests/ref/fate/vp9-03-size-202x198
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 59994, 181edc4ebeeff7f0527b93b84d5d8efb
0, 1, 1, 1, 59994, 132c71b634fb67eed51fcdef1775b6b2
0, 2, 2, 1, 59994, fd41144770765fc893adc5843ebe32e4
diff --git a/tests/ref/fate/vp9-03-size-202x200 b/tests/ref/fate/vp9-03-size-202x200
index 40dd8d4..f75e192 100644
--- a/tests/ref/fate/vp9-03-size-202x200
+++ b/tests/ref/fate/vp9-03-size-202x200
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 60600, 20c41d4a1271183dbbc7a44e6b90ea80
0, 1, 1, 1, 60600, bd8c1fba8d8742f4d98b7d5097c8c828
0, 2, 2, 1, 60600, 55cbe06a925009c1b1f9b609b60b4c1d
diff --git a/tests/ref/fate/vp9-03-size-202x202 b/tests/ref/fate/vp9-03-size-202x202
index 0c68d9b..af7cb9a 100644
--- a/tests/ref/fate/vp9-03-size-202x202
+++ b/tests/ref/fate/vp9-03-size-202x202
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 61206, 610cef52d35e9c641f2b8c10489c3d12
0, 1, 1, 1, 61206, 1f84062e607d4798b0544739fe0da99c
0, 2, 2, 1, 61206, ea379947b5c52ea3989dfc3f47c729d9
diff --git a/tests/ref/fate/vp9-03-size-202x208 b/tests/ref/fate/vp9-03-size-202x208
index 0dad7a3..cc85d27 100644
--- a/tests/ref/fate/vp9-03-size-202x208
+++ b/tests/ref/fate/vp9-03-size-202x208
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 63024, d2128e290be81bb0700ebe19e3faed4f
0, 1, 1, 1, 63024, dccaecb7e4ddb7e4224221a659af2a43
0, 2, 2, 1, 63024, be8e0966aaf3a9fe9164f63695dc3b62
diff --git a/tests/ref/fate/vp9-03-size-202x210 b/tests/ref/fate/vp9-03-size-202x210
index bf21057..d51fcc6 100644
--- a/tests/ref/fate/vp9-03-size-202x210
+++ b/tests/ref/fate/vp9-03-size-202x210
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 63630, e4663a28cabbfdd3815efda2d38debcc
0, 1, 1, 1, 63630, 3cc7dbec64e9f697f40d740a72c09fc7
0, 2, 2, 1, 63630, f108981e0ce9c6c501b9ac61d0f1ba44
diff --git a/tests/ref/fate/vp9-03-size-202x224 b/tests/ref/fate/vp9-03-size-202x224
index 22542f8..0a36bd3 100644
--- a/tests/ref/fate/vp9-03-size-202x224
+++ b/tests/ref/fate/vp9-03-size-202x224
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 67872, 1d318f05310f6d40646f23c62c7eafe4
0, 1, 1, 1, 67872, 42870bd73e1a0c5d84b986db3d24f0f0
0, 2, 2, 1, 67872, afaac676150286143c6fec7992a81467
diff --git a/tests/ref/fate/vp9-03-size-202x226 b/tests/ref/fate/vp9-03-size-202x226
index cb3f5b7..6bc31f9 100644
--- a/tests/ref/fate/vp9-03-size-202x226
+++ b/tests/ref/fate/vp9-03-size-202x226
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 68478, 5aa0f439c58c6335cd86d4238a8c4b68
0, 1, 1, 1, 68478, 3616cc306ec05f89d9b0db63200e4abf
0, 2, 2, 1, 68478, 424e98f8ec0ebf2a326a917ee0159bbe
diff --git a/tests/ref/fate/vp9-03-size-208x196 b/tests/ref/fate/vp9-03-size-208x196
index c64c283..b06557f 100644
--- a/tests/ref/fate/vp9-03-size-208x196
+++ b/tests/ref/fate/vp9-03-size-208x196
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 61152, 6195975181969789e101a83a555d13f7
0, 1, 1, 1, 61152, 2aca5e3307d68a5e969564a943b8e723
0, 2, 2, 1, 61152, aee4b00472ee0b6b7a13e31069181db4
diff --git a/tests/ref/fate/vp9-03-size-208x198 b/tests/ref/fate/vp9-03-size-208x198
index f64ea46..84da7dd 100644
--- a/tests/ref/fate/vp9-03-size-208x198
+++ b/tests/ref/fate/vp9-03-size-208x198
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 61776, 1f1fa3cdf865d8c75183f4ba6203b675
0, 1, 1, 1, 61776, ead33ead8fea5bd5d831a79f4c75a590
0, 2, 2, 1, 61776, 9a406b4464989fd4bb7cbcb1b18aeaa7
diff --git a/tests/ref/fate/vp9-03-size-208x200 b/tests/ref/fate/vp9-03-size-208x200
index 326e543..0943abf 100644
--- a/tests/ref/fate/vp9-03-size-208x200
+++ b/tests/ref/fate/vp9-03-size-208x200
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 62400, ff2dda3ddbe8b461d960baba0ad132bf
0, 1, 1, 1, 62400, d6935ac8f2250316f498e8f01afa04fd
0, 2, 2, 1, 62400, 57173ebaef7b21698c62fa959cb40ead
diff --git a/tests/ref/fate/vp9-03-size-208x202 b/tests/ref/fate/vp9-03-size-208x202
index 4d1f413..b181224 100644
--- a/tests/ref/fate/vp9-03-size-208x202
+++ b/tests/ref/fate/vp9-03-size-208x202
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 63024, e5164f87feadf4b65257f578affc3e04
0, 1, 1, 1, 63024, 6aee5a3b6c3a096dfc1594762b2b248f
0, 2, 2, 1, 63024, cb1c9dce6fdf7372e0eb2397251f0ade
diff --git a/tests/ref/fate/vp9-03-size-208x208 b/tests/ref/fate/vp9-03-size-208x208
index 25caefb..7bcbfdc 100644
--- a/tests/ref/fate/vp9-03-size-208x208
+++ b/tests/ref/fate/vp9-03-size-208x208
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 64896, 6bff7c1f4c5ef8412ebf669852c70de6
0, 1, 1, 1, 64896, fdfd7a2308de9509a41fed2880a8f0f5
0, 2, 2, 1, 64896, d8b464811e9c3b8a6db9cc277ac88c59
diff --git a/tests/ref/fate/vp9-03-size-208x210 b/tests/ref/fate/vp9-03-size-208x210
index 077ce0d..7dbccf6 100644
--- a/tests/ref/fate/vp9-03-size-208x210
+++ b/tests/ref/fate/vp9-03-size-208x210
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 65520, b15c7e98ddd137237b062cb51667522f
0, 1, 1, 1, 65520, 00c594c68b19ef39a79a38e86853dc64
0, 2, 2, 1, 65520, e6742abe3d2c178af4298e121391c299
diff --git a/tests/ref/fate/vp9-03-size-208x224 b/tests/ref/fate/vp9-03-size-208x224
index be2af41..70d64ea 100644
--- a/tests/ref/fate/vp9-03-size-208x224
+++ b/tests/ref/fate/vp9-03-size-208x224
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 69888, 479d07bb96905ad7d5f0ec3ee12b41ba
0, 1, 1, 1, 69888, 4b6555aaed8e5a45879773f1bf87962e
0, 2, 2, 1, 69888, c5f42cb796dd7b6622957016ca6b502f
diff --git a/tests/ref/fate/vp9-03-size-208x226 b/tests/ref/fate/vp9-03-size-208x226
index 713fb80..7d9020c 100644
--- a/tests/ref/fate/vp9-03-size-208x226
+++ b/tests/ref/fate/vp9-03-size-208x226
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 70512, 33aa4af6153570518c59960a0c959053
0, 1, 1, 1, 70512, 024fa27dee80ad199528052aaa8d42c7
0, 2, 2, 1, 70512, b949ef118c7e7e62a8b88e2308219ef9
diff --git a/tests/ref/fate/vp9-03-size-210x196 b/tests/ref/fate/vp9-03-size-210x196
index 6591b75..a6813b4 100644
--- a/tests/ref/fate/vp9-03-size-210x196
+++ b/tests/ref/fate/vp9-03-size-210x196
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 61740, 5c69f80da667bfd20394995e93e4cd2b
0, 1, 1, 1, 61740, 13363cd8e52ca8c1053db1c84c111bc9
0, 2, 2, 1, 61740, 108976afdf99f59276d6f89879e3bdc3
diff --git a/tests/ref/fate/vp9-03-size-210x198 b/tests/ref/fate/vp9-03-size-210x198
index c16718d..c14d20c 100644
--- a/tests/ref/fate/vp9-03-size-210x198
+++ b/tests/ref/fate/vp9-03-size-210x198
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 62370, d83ee2413e701ae405a2b74863d4c5a9
0, 1, 1, 1, 62370, f2ebc0f7dc171e0e5d2911c7ee2df5e1
0, 2, 2, 1, 62370, e189ef4d8add227352a0d6ee62748ee7
diff --git a/tests/ref/fate/vp9-03-size-210x200 b/tests/ref/fate/vp9-03-size-210x200
index 6469672..873525b 100644
--- a/tests/ref/fate/vp9-03-size-210x200
+++ b/tests/ref/fate/vp9-03-size-210x200
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 63000, 2465560246c1ee24d937cb9cbc1422f1
0, 1, 1, 1, 63000, 8926b628dcdf2182516822c7d0d778ec
0, 2, 2, 1, 63000, 9bd14d3ebc7fe81c4223116de1b9c2ec
diff --git a/tests/ref/fate/vp9-03-size-210x202 b/tests/ref/fate/vp9-03-size-210x202
index 65439e5..91e229e 100644
--- a/tests/ref/fate/vp9-03-size-210x202
+++ b/tests/ref/fate/vp9-03-size-210x202
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 63630, 5d01848aee2b324f2e356627f9c39532
0, 1, 1, 1, 63630, b671fe34bc0e5a682baff929d26ea627
0, 2, 2, 1, 63630, e9a40f87ca5aaa5af9772e286feb9063
diff --git a/tests/ref/fate/vp9-03-size-210x208 b/tests/ref/fate/vp9-03-size-210x208
index 9510358..a77ac5f 100644
--- a/tests/ref/fate/vp9-03-size-210x208
+++ b/tests/ref/fate/vp9-03-size-210x208
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 65520, 1156d318c00d299cf5bdc7e485966dab
0, 1, 1, 1, 65520, a8094f8f1e7e04e54251bee8c4c800ce
0, 2, 2, 1, 65520, e2a07d99ffe1cfe6b9fce36e93677fe1
diff --git a/tests/ref/fate/vp9-03-size-210x210 b/tests/ref/fate/vp9-03-size-210x210
index 6882c0d..fa9f158 100644
--- a/tests/ref/fate/vp9-03-size-210x210
+++ b/tests/ref/fate/vp9-03-size-210x210
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 66150, b65725c68978bdaaafdf735dfbafa9e3
0, 1, 1, 1, 66150, 35be2f16bd5dedc9d3f7a016f0d71701
0, 2, 2, 1, 66150, 8c2873a97b51510d7449869e24a348f5
diff --git a/tests/ref/fate/vp9-03-size-210x224 b/tests/ref/fate/vp9-03-size-210x224
index 63519b1..1e1d225 100644
--- a/tests/ref/fate/vp9-03-size-210x224
+++ b/tests/ref/fate/vp9-03-size-210x224
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 70560, bb903b926c4b34ae336e21d65ad8fd25
0, 1, 1, 1, 70560, c4c0bc3b112487e994d22176817ace3c
0, 2, 2, 1, 70560, 24e699f7a92ab1b0fe12e0b747470b5b
diff --git a/tests/ref/fate/vp9-03-size-210x226 b/tests/ref/fate/vp9-03-size-210x226
index 445d53d..5563363 100644
--- a/tests/ref/fate/vp9-03-size-210x226
+++ b/tests/ref/fate/vp9-03-size-210x226
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 71190, 03707b2f5c392933f7336f380423a0a1
0, 1, 1, 1, 71190, b388553c79573555a3b660f5e36d4e36
0, 2, 2, 1, 71190, a1a7fd8ba7fb0fe7733cdf5440c7c1f3
diff --git a/tests/ref/fate/vp9-03-size-224x196 b/tests/ref/fate/vp9-03-size-224x196
index ab442fc..1275e9e 100644
--- a/tests/ref/fate/vp9-03-size-224x196
+++ b/tests/ref/fate/vp9-03-size-224x196
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 65856, 3ffc096f1b42b4d319d4a9efbefc7625
0, 1, 1, 1, 65856, 78b3655d5cad30fa6b2c2d8fd29463de
0, 2, 2, 1, 65856, ab197553d9599b2a03aff62d1d694848
diff --git a/tests/ref/fate/vp9-03-size-224x198 b/tests/ref/fate/vp9-03-size-224x198
index 54abb1a..39e0825 100644
--- a/tests/ref/fate/vp9-03-size-224x198
+++ b/tests/ref/fate/vp9-03-size-224x198
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 66528, cf35dffc80946e87bb9d3e18aab9d320
0, 1, 1, 1, 66528, a76ac92f05e9b097f8ac5882e1ffe656
0, 2, 2, 1, 66528, faa1e8a11c9df3e9c9a9dafbebea6d04
diff --git a/tests/ref/fate/vp9-03-size-224x200 b/tests/ref/fate/vp9-03-size-224x200
index f5c8ed8..8fbc5b1 100644
--- a/tests/ref/fate/vp9-03-size-224x200
+++ b/tests/ref/fate/vp9-03-size-224x200
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 67200, 0819e6d715c9b4d94f05f63a7ca86199
0, 1, 1, 1, 67200, 9b9a4b01ed4c8a93687e45245b3092a3
0, 2, 2, 1, 67200, 3a076f5b8dba60552e84a391ee04d1c7
diff --git a/tests/ref/fate/vp9-03-size-224x202 b/tests/ref/fate/vp9-03-size-224x202
index 33bf0bb..3e212ac 100644
--- a/tests/ref/fate/vp9-03-size-224x202
+++ b/tests/ref/fate/vp9-03-size-224x202
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 67872, e1e3b4af5910383ff6f66b6ab1a29544
0, 1, 1, 1, 67872, 8668ef92b72f35728ebb456665d48b95
0, 2, 2, 1, 67872, dffc7c28f86f07bf28451292990e9594
diff --git a/tests/ref/fate/vp9-03-size-224x208 b/tests/ref/fate/vp9-03-size-224x208
index 3eb03ff..a925e1a 100644
--- a/tests/ref/fate/vp9-03-size-224x208
+++ b/tests/ref/fate/vp9-03-size-224x208
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 69888, 85f08afadfd1204d4131b9ee9c8cc10b
0, 1, 1, 1, 69888, f893de5432a082b3dffcf7499827f548
0, 2, 2, 1, 69888, cb81e0d7b657bc5a4a9cf8ad75a76a77
diff --git a/tests/ref/fate/vp9-03-size-224x210 b/tests/ref/fate/vp9-03-size-224x210
index 673cb66..3c59459 100644
--- a/tests/ref/fate/vp9-03-size-224x210
+++ b/tests/ref/fate/vp9-03-size-224x210
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 70560, 427421e5fd2087c6ff7b87a27982332f
0, 1, 1, 1, 70560, b68311fd44e189e4174ac357d5415068
0, 2, 2, 1, 70560, 2c822ff45be7a1ea412d21ff82c7bc1d
diff --git a/tests/ref/fate/vp9-03-size-224x224 b/tests/ref/fate/vp9-03-size-224x224
index 5a3c1a3..610578b 100644
--- a/tests/ref/fate/vp9-03-size-224x224
+++ b/tests/ref/fate/vp9-03-size-224x224
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 75264, bedd5d2725ffff06a50e23841bc2dfb8
0, 1, 1, 1, 75264, 8c363f68b0b30f507563516aa99e23ac
0, 2, 2, 1, 75264, 9cb7d51ca4439614dc3f5980507a4d32
diff --git a/tests/ref/fate/vp9-03-size-224x226 b/tests/ref/fate/vp9-03-size-224x226
index 53a8fa8..874e595 100644
--- a/tests/ref/fate/vp9-03-size-224x226
+++ b/tests/ref/fate/vp9-03-size-224x226
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 75936, dca556e648a576b3973fbe4b34d0328c
0, 1, 1, 1, 75936, 34a49e4aba4aca5c76ab0f751341c32b
0, 2, 2, 1, 75936, 4b7cc6d500b273efe7e30fc3a3946f74
diff --git a/tests/ref/fate/vp9-03-size-226x196 b/tests/ref/fate/vp9-03-size-226x196
index 15f171a..43d55b9 100644
--- a/tests/ref/fate/vp9-03-size-226x196
+++ b/tests/ref/fate/vp9-03-size-226x196
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 66444, 4757a31842453f806de2f2256329547e
0, 1, 1, 1, 66444, fe5fb955a4143091c5bfae7c4a4afe0f
0, 2, 2, 1, 66444, 93766c5a03d71f99afb7705add7b63f0
diff --git a/tests/ref/fate/vp9-03-size-226x198 b/tests/ref/fate/vp9-03-size-226x198
index acf2511..fe2c477 100644
--- a/tests/ref/fate/vp9-03-size-226x198
+++ b/tests/ref/fate/vp9-03-size-226x198
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 67122, b97087eb8c53cf56dc44576912654fb2
0, 1, 1, 1, 67122, 219bb68a59dc166806a5b5689a943b66
0, 2, 2, 1, 67122, 67b2ec19dd3b74d828b51912c25249d6
diff --git a/tests/ref/fate/vp9-03-size-226x200 b/tests/ref/fate/vp9-03-size-226x200
index ec78516..b16c531 100644
--- a/tests/ref/fate/vp9-03-size-226x200
+++ b/tests/ref/fate/vp9-03-size-226x200
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 67800, 0ae27db338f73f37eaed806b1c789593
0, 1, 1, 1, 67800, 3f69273752f43699a3bc7b22a88cc3aa
0, 2, 2, 1, 67800, ce0dfafb59910241d2b1a2275a2c2143
diff --git a/tests/ref/fate/vp9-03-size-226x202 b/tests/ref/fate/vp9-03-size-226x202
index 4ef5936..818038d 100644
--- a/tests/ref/fate/vp9-03-size-226x202
+++ b/tests/ref/fate/vp9-03-size-226x202
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 68478, 0cd2876640e71de3a6df7839bd6f0b51
0, 1, 1, 1, 68478, f887db6839c0cddd1ea9ae6bfd2cc16d
0, 2, 2, 1, 68478, ff2a890cf4c4973bf181ba8424c2eadc
diff --git a/tests/ref/fate/vp9-03-size-226x208 b/tests/ref/fate/vp9-03-size-226x208
index cc9b00c..cda6f99 100644
--- a/tests/ref/fate/vp9-03-size-226x208
+++ b/tests/ref/fate/vp9-03-size-226x208
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 70512, 6006cac6628cf9e7cea58aec07471b06
0, 1, 1, 1, 70512, f7e994921248b6933920c984880ec96c
0, 2, 2, 1, 70512, c0aeeb9d2009538d8d5e837f45e1542d
diff --git a/tests/ref/fate/vp9-03-size-226x210 b/tests/ref/fate/vp9-03-size-226x210
index a800558..fa83e1d 100644
--- a/tests/ref/fate/vp9-03-size-226x210
+++ b/tests/ref/fate/vp9-03-size-226x210
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 71190, a6c1b7686202f5cc64335f92be595309
0, 1, 1, 1, 71190, 3e573d4c693a39c5d6cd46b8873e99bb
0, 2, 2, 1, 71190, d2388f6f641c8ddec98f11493f1a1390
diff --git a/tests/ref/fate/vp9-03-size-226x224 b/tests/ref/fate/vp9-03-size-226x224
index 7b0b33d..50d81cb 100644
--- a/tests/ref/fate/vp9-03-size-226x224
+++ b/tests/ref/fate/vp9-03-size-226x224
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 75936, 80fb3a643384386beadc0991f171669d
0, 1, 1, 1, 75936, 65a4a51163f49a75f8eeecd94cb2ba47
0, 2, 2, 1, 75936, d5b2aac9889d2991b83fd4360ada0258
diff --git a/tests/ref/fate/vp9-03-size-226x226 b/tests/ref/fate/vp9-03-size-226x226
index 6f9d9e67..88b3c43 100644
--- a/tests/ref/fate/vp9-03-size-226x226
+++ b/tests/ref/fate/vp9-03-size-226x226
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 76614, f2370fc802dafdf5082beffc1907a9c6
0, 1, 1, 1, 76614, aad6de7b986234a1d621935b272501c9
0, 2, 2, 1, 76614, 8a6d3784e22e3b4f735e78916fbc3821
diff --git a/tests/ref/fate/vp9-2pass-akiyo b/tests/ref/fate/vp9-2pass-akiyo
index ad5a2cf..2f32092 100644
--- a/tests/ref/fate/vp9-2pass-akiyo
+++ b/tests/ref/fate/vp9-2pass-akiyo
@@ -1,4 +1,8 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 1, 152064, 043ce065a309514e1e8ebdcbb3c2458b
0, 1, 1, 1, 152064, 8579c9cffd95b11db86158e518b2e34a
0, 2, 2, 1, 152064, ebbba105e499604f5e69b8aa48fe86f4
diff --git a/tests/ref/fate/vp9-parallelmode-akiyo b/tests/ref/fate/vp9-parallelmode-akiyo
new file mode 100644
index 0000000..9668c54
--- /dev/null
+++ b/tests/ref/fate/vp9-parallelmode-akiyo
@@ -0,0 +1,30 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
+#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
+0, 0, 0, 1, 152064, f5bc602db15c69545307e56990f9f9f7
+0, 1, 1, 1, 152064, b56428b6f97669938c8b9b05458fca70
+0, 2, 2, 1, 152064, b56428b6f97669938c8b9b05458fca70
+0, 3, 3, 1, 152064, 3098d2eb9129beddb6975e3ae332a4ab
+0, 4, 4, 1, 152064, 6719f3a6c22f05dc53dd3906e4154bd7
+0, 5, 5, 1, 152064, 8cd9a12761e35f67c278949cd3aee88f
+0, 6, 6, 1, 152064, 8cd9a12761e35f67c278949cd3aee88f
+0, 7, 7, 1, 152064, 0160dec415234d39f148e91f72d264ab
+0, 8, 8, 1, 152064, 9f90d96d67d9e9b3716abe2a3faa854e
+0, 9, 9, 1, 152064, 1edb312f9d0be7835b964a3ffa014759
+0, 10, 10, 1, 152064, 7614fd674609afccacd355aa2f714c75
+0, 11, 11, 1, 152064, cb46868706dd246878bebf354aff66f4
+0, 12, 12, 1, 152064, da36fe96cb4956036f890bb2f6d05b98
+0, 13, 13, 1, 152064, af0a178c68b719b369c8fa8537d38e65
+0, 14, 14, 1, 152064, ff03dbc436376fc60ac240cd6c4fc518
+0, 15, 15, 1, 152064, b0bf25e139556bd9067616db7e4f47b5
+0, 16, 16, 1, 152064, e70d5480c1f82fc877bbe1a8093f807a
+0, 17, 17, 1, 152064, 622fb43e6ff63834f0f680a68b49f6e6
+0, 18, 18, 1, 152064, c331ebba15f2290f174533dbffb3c27b
+0, 19, 19, 1, 152064, 15cb153425c55f7065fb36606c48972e
+0, 20, 20, 1, 152064, b95c7699639c51b08b3615ef7fa7046c
+0, 21, 21, 1, 152064, b4774148c71c9c184bda5a18294e459c
+0, 22, 22, 1, 152064, 795b7ce4c5e0dc343bd8f80ad6c1a454
+0, 23, 23, 1, 152064, 19163601b7b6138e2940cf28f6df6c7f
+0, 24, 24, 1, 152064, b9b388e0892c52df0680a30bfa954506
diff --git a/tests/ref/fate/vp9-segmentation-akiyo b/tests/ref/fate/vp9-segmentation-akiyo
deleted file mode 100644
index 372cc8d..0000000
--- a/tests/ref/fate/vp9-segmentation-akiyo
+++ /dev/null
@@ -1,51 +0,0 @@
-#tb 0: 1001/30000
-0, 0, 0, 1, 152064, 20cf714300c5e28ffb77bf9c682129bc
-0, 1, 1, 1, 152064, 2f271e4de29f87d6b90511fbafdf9fbb
-0, 2, 2, 1, 152064, 2f271e4de29f87d6b90511fbafdf9fbb
-0, 3, 3, 1, 152064, a88532a043f5f2c6bce729a8e20ee5af
-0, 4, 4, 1, 152064, 8d7b5482ed8072a7c95d722783773436
-0, 5, 5, 1, 152064, 04872d8619b163b5e0c20123ccddf7dc
-0, 6, 6, 1, 152064, ed6d9677782aa6e87b6576541391557f
-0, 7, 7, 1, 152064, 689f71108e9bf024cd9ccf48800dcdc7
-0, 8, 8, 1, 152064, f7c555792884499bb62a8e739b201739
-0, 9, 9, 1, 152064, 7fed82c38ce428a178c56f6131eff5ec
-0, 10, 10, 1, 152064, fb638e587ade05baa027bb63edc7ec7c
-0, 11, 11, 1, 152064, 319295f5aa44661a80570e844050156a
-0, 12, 12, 1, 152064, de2d8635966a1cd57290eac449a5fb4b
-0, 13, 13, 1, 152064, 9ac3d711a00aac6b17004bb6451e4cab
-0, 14, 14, 1, 152064, d12eced084e72b5230493e2dc2de0f0a
-0, 15, 15, 1, 152064, 197761d11407fed723a63b8e28cb8e19
-0, 16, 16, 1, 152064, 28d8e807bc142b74f1eaf30dbbf1b7bd
-0, 17, 17, 1, 152064, abe88f1f7490d13ba3def9511beaceec
-0, 18, 18, 1, 152064, 7d297b9c989ebc0408fd41b14900242a
-0, 19, 19, 1, 152064, d5e7adfa2b207d860feff5c894585fd1
-0, 20, 20, 1, 152064, aea3e9de9de237f8379785f3467dc9c9
-0, 21, 21, 1, 152064, 211967cd949c1d83a8cc4c8267aa6034
-0, 22, 22, 1, 152064, 3f49bf8e0434114c15b867be2d53d283
-0, 23, 23, 1, 152064, 8d5e629c0e941ca6f049ed2bb59d09a8
-0, 24, 24, 1, 152064, d359620957877534bc94cd137dc652fe
-0, 25, 25, 1, 152064, 83610fc1969fdfa267e7e462a83ea40c
-0, 26, 26, 1, 152064, b2d20dcc3f77a238ce7210991eebe1a7
-0, 27, 27, 1, 152064, a42ad37808f30e1d968882bf42e9c641
-0, 28, 28, 1, 152064, 55084cded938266a2c3c658dcc162781
-0, 29, 29, 1, 152064, e392a3a7d33e10e95fc9cdf0a2080eac
-0, 30, 30, 1, 152064, 73977c4827463c17e63c0769bb90722f
-0, 31, 31, 1, 152064, cb5dd87344af7d6fd4ed0e06cb90d9c2
-0, 32, 32, 1, 152064, 533338860124e392cef2039468c22f75
-0, 33, 33, 1, 152064, da30f077490042367502a6fe11a46e0f
-0, 34, 34, 1, 152064, 860ab1bfbd3fe6a27bee5ef8c4e0b600
-0, 35, 35, 1, 152064, 339ec3863eaed689d46289ffe47bc45d
-0, 36, 36, 1, 152064, ffa6c990577093106796ed0dee56c483
-0, 37, 37, 1, 152064, 3fcdc2bc064c79f35ea81a715ff089d0
-0, 38, 38, 1, 152064, adaef9ec97e23a542db22bcd23c740bd
-0, 39, 39, 1, 152064, ddcff4bd2c9579181182eb49add0ce3c
-0, 40, 40, 1, 152064, b3b039c84cffb9272c8ddf9086748696
-0, 41, 41, 1, 152064, 70939a961ec1e4697031b79e7ebb7919
-0, 42, 42, 1, 152064, 6b3ff2e003749c6ffeb2d71edecf884c
-0, 43, 43, 1, 152064, 5e4efc96971f81218c472482b5a79374
-0, 44, 44, 1, 152064, 279132c87d81a5747824b06423bf6785
-0, 45, 45, 1, 152064, 1da48caa08007523aab41a56e21dd99b
-0, 46, 46, 1, 152064, 36ecffb2bfcb587d2556fddcbbd3448b
-0, 47, 47, 1, 152064, 7823e3c86cd5a05c2959c7ef4d1cfa89
-0, 48, 48, 1, 152064, b53f78afbad1a43f7aea58814eacd824
-0, 49, 49, 1, 152064, b9b127b4bc54123bec19b2f4a3fa157c
diff --git a/tests/ref/fate/vp9-segmentation-aq-akiyo b/tests/ref/fate/vp9-segmentation-aq-akiyo
new file mode 100644
index 0000000..5c931b6
--- /dev/null
+++ b/tests/ref/fate/vp9-segmentation-aq-akiyo
@@ -0,0 +1,30 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
+#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
+0, 0, 0, 1, 152064, b208eac12f0ae74a812bc9e314bdfac7
+0, 1, 1, 1, 152064, ebb2259451c3acf3ad6379d1f4092efb
+0, 2, 2, 1, 152064, 33de46060afd14aa359b7bd0d9ff1be8
+0, 3, 3, 1, 152064, 33de46060afd14aa359b7bd0d9ff1be8
+0, 4, 4, 1, 152064, 5d087d8df10fd406d59172710ea0341a
+0, 5, 5, 1, 152064, 3570ed7fb90ac9b5335b97adf0539e94
+0, 6, 6, 1, 152064, 68a8c56b889a3befc75c9ec4293c7fda
+0, 7, 7, 1, 152064, f871f7c0456f644cfb0ec896132a097f
+0, 8, 8, 1, 152064, 14e939bfeb2b878e0782a7ce68ecd214
+0, 9, 9, 1, 152064, bd3e97881ebece0f876d46d067c6a7ff
+0, 10, 10, 1, 152064, a20529c091ef3e68a901c574371224b3
+0, 11, 11, 1, 152064, 5253f16c8b0329d33d38d275124487fb
+0, 12, 12, 1, 152064, c9c2f7d8835e620709a53ff8adfe72bf
+0, 13, 13, 1, 152064, dc8f1df0d7ab8e4f9daf2ccfd96de855
+0, 14, 14, 1, 152064, d09d43208d4de7f81d54f48cff310b6f
+0, 15, 15, 1, 152064, 0dcf7212075c1f15219690ad6ffe2940
+0, 16, 16, 1, 152064, 3b52e3eb4f972318c6912dd29a95dcf3
+0, 17, 17, 1, 152064, aa1414343067749fbd743ace93553492
+0, 18, 18, 1, 152064, 6951cb7a78e0a03f9a3f6264084de6dc
+0, 19, 19, 1, 152064, 5324f2f03c4d5fe35446561af654e9ec
+0, 20, 20, 1, 152064, dff11b046a02ca34c6b1aecc857632ec
+0, 21, 21, 1, 152064, 971182c013c1524d4864fd946b8c1550
+0, 22, 22, 1, 152064, 3306f1dcd5760ba92dd9cec8bfc21b08
+0, 23, 23, 1, 152064, f1f7b13c33332fece576b4d175f91832
+0, 24, 24, 1, 152064, 9e66573fbfe847149eb32e8a9c242c18
diff --git a/tests/ref/fate/vp9-segmentation-sf-akiyo b/tests/ref/fate/vp9-segmentation-sf-akiyo
new file mode 100644
index 0000000..0fdb3f2
--- /dev/null
+++ b/tests/ref/fate/vp9-segmentation-sf-akiyo
@@ -0,0 +1,30 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
+#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
+0, 0, 0, 1, 152064, f4e04a0f92fab3a52d858bb222807ac0
+0, 1, 1, 1, 152064, 493cb96b8202a1518c6c9bdb848540e4
+0, 2, 2, 1, 152064, 60b5b63f832cff119a43de82102758f4
+0, 3, 3, 1, 152064, 0d9bd42e279d480603f9c670f0a8ffe3
+0, 4, 4, 1, 152064, 25ca563f233688f32f40fec985a116a2
+0, 5, 5, 1, 152064, dd14b43d538708a91de41606703dbe1c
+0, 6, 6, 1, 152064, 01bb23cb43960ff185a97ea79936d3b4
+0, 7, 7, 1, 152064, 85045c4310ee80cd12979bdea4f3f86e
+0, 8, 8, 1, 152064, c8e015ea13359a05483de349313a6686
+0, 9, 9, 1, 152064, 8dbb0406bf6fe19c30a9c9253fcdfe7f
+0, 10, 10, 1, 152064, 84881463643069036d03e8120a5f15e9
+0, 11, 11, 1, 152064, 9abcd3f2f86ff31f8d357389b330df59
+0, 12, 12, 1, 152064, 19ada6395c4e656578d2ceeaba291bb2
+0, 13, 13, 1, 152064, fc29773a6f32eed2bfa44143f8f505b1
+0, 14, 14, 1, 152064, 5e56bd91f5e3d1457c124b5702bdc3b6
+0, 15, 15, 1, 152064, 5b920d73e301adb6c45699a209f09a33
+0, 16, 16, 1, 152064, 4d06ec294270638c6abdd1c2303b34fc
+0, 17, 17, 1, 152064, dc99797067851f74708d7e6ff54367d8
+0, 18, 18, 1, 152064, 5df68b49124219592b043916affb1311
+0, 19, 19, 1, 152064, cfb52d101fad76acb1bb0d48c513bffd
+0, 20, 20, 1, 152064, 206dbd55680b8a83d8bafe33c54c3e36
+0, 21, 21, 1, 152064, 171f2e26771db631788065eecf6c44d9
+0, 22, 22, 1, 152064, b10809dcf9ecfdb4f86a6f3236ac273e
+0, 23, 23, 1, 152064, b354107bdea9bd011b09d9f4a32d4e89
+0, 24, 24, 1, 152064, 0c18be13dc6fbf79a613f2b24bb301c1
diff --git a/tests/ref/fate/vp9-tiling-pedestrian b/tests/ref/fate/vp9-tiling-pedestrian
index 23c760e..2915323 100644
--- a/tests/ref/fate/vp9-tiling-pedestrian
+++ b/tests/ref/fate/vp9-tiling-pedestrian
@@ -1,3 +1,7 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
#tb 0: 1/1000
+#stream#, dts, pts, duration, size, hash
0, 0, 0, 0, 3110400, 1e6c2e768a5107e57e6d626f0511193a
0, 40, 40, 0, 3110400, 972d3e2b5ee2e3b0907218a243e4cb7d
diff --git a/tests/ref/fate/wmv8-drm b/tests/ref/fate/wmv8-drm
index 31291d3..12d8fbb 100644
--- a/tests/ref/fate/wmv8-drm
+++ b/tests/ref/fate/wmv8-drm
@@ -128,4 +128,3 @@
0, 160, 160, 1, 84480, 0x13962590
0, 161, 161, 1, 84480, 0xde79482f
0, 162, 162, 1, 84480, 0x7d1ca064
-0, 163, 163, 1, 84480, 0x0998a064
diff --git a/tests/ref/lavf-fate/ogg_vp3 b/tests/ref/lavf-fate/ogg_vp3
index b77476d..9e9cc7e 100644
--- a/tests/ref/lavf-fate/ogg_vp3
+++ b/tests/ref/lavf-fate/ogg_vp3
@@ -1,3 +1,3 @@
-adbe6c30bdfe934dc5ae397f4db2960d *./tests/data/lavf-fate/lavf.ogg
-417644 ./tests/data/lavf-fate/lavf.ogg
+4bd51dac3194fa88ae33767c25b4b1e6 *./tests/data/lavf-fate/lavf.ogg
+417621 ./tests/data/lavf-fate/lavf.ogg
./tests/data/lavf-fate/lavf.ogg CRC=0x037e3e79
diff --git a/tests/ref/seek/acodec-mp2 b/tests/ref/seek/acodec-mp2
index 8de3676..62abab4 100644
--- a/tests/ref/seek/acodec-mp2
+++ b/tests/ref/seek/acodec-mp2
@@ -1,6 +1,6 @@
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 0 size: 417
ret: 0 st:-1 flags:0 ts:-1.000000
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 0 size: 417
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 0 size: 440
ret: 0 st:-1 flags:1 ts: 1.894167
ret: 0 st: 0 flags:1 dts: 1.880816 pts: 1.880816 pos: 30093 size: 418
ret: 0 st: 0 flags:0 ts: 0.788334
@@ -18,7 +18,7 @@
ret: 0 st:-1 flags:1 ts: 1.047503
ret: 0 st: 0 flags:1 dts: 1.044898 pts: 1.044898 pos: 16718 size: 418
ret: 0 st: 0 flags:0 ts:-0.058330
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 0 size: 417
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 0 size: 440
ret: 0 st: 0 flags:1 ts: 2.835837
ret: 0 st: 0 flags:1 dts: 2.821224 pts: 2.821224 pos: 45139 size: 418
ret: 0 st:-1 flags:0 ts: 1.730004
@@ -26,7 +26,7 @@
ret: 0 st:-1 flags:1 ts: 0.624171
ret: 0 st: 0 flags:1 dts: 0.600816 pts: 0.600816 pos: 9613 size: 418
ret: 0 st: 0 flags:0 ts:-0.481662
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 0 size: 417
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 0 size: 440
ret: 0 st: 0 flags:1 ts: 2.412505
ret: 0 st: 0 flags:1 dts: 2.403265 pts: 2.403265 pos: 38452 size: 418
ret: 0 st:-1 flags:0 ts: 1.306672
@@ -34,7 +34,7 @@
ret: 0 st:-1 flags:1 ts: 0.200839
ret: 0 st: 0 flags:1 dts: 0.182857 pts: 0.182857 pos: 2925 size: 418
ret: 0 st: 0 flags:0 ts:-0.904994
-ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 0 size: 417
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 0 size: 440
ret: 0 st: 0 flags:1 ts: 1.989173
ret: 0 st: 0 flags:1 dts: 1.985306 pts: 1.985306 pos: 31764 size: 418
ret: 0 st:-1 flags:0 ts: 0.883340
diff --git a/tests/ref/vsynth/vsynth1-h261-trellis b/tests/ref/vsynth/vsynth1-h261-trellis
new file mode 100644
index 0000000..77cb589
--- /dev/null
+++ b/tests/ref/vsynth/vsynth1-h261-trellis
@@ -0,0 +1,4 @@
+7af82b4b3f99416f839ebc9714306dad *tests/data/fate/vsynth1-h261-trellis.avi
+655412 tests/data/fate/vsynth1-h261-trellis.avi
+70ceba944548ba680b1101c91707ea25 *tests/data/fate/vsynth1-h261-trellis.out.rawvideo
+stddev: 8.75 PSNR: 29.28 MAXDIFF: 90 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth/vsynth2-h261-trellis b/tests/ref/vsynth/vsynth2-h261-trellis
new file mode 100644
index 0000000..36cab4c
--- /dev/null
+++ b/tests/ref/vsynth/vsynth2-h261-trellis
@@ -0,0 +1,4 @@
+5c0670e3d07043b1209136d6fbd6bb8d *tests/data/fate/vsynth2-h261-trellis.avi
+184582 tests/data/fate/vsynth2-h261-trellis.avi
+f9df8cd110a2f3d9706dd2f29a1d0a89 *tests/data/fate/vsynth2-h261-trellis.out.rawvideo
+stddev: 6.32 PSNR: 32.11 MAXDIFF: 89 bytes: 7603200/ 7603200
diff --git a/tests/tiny_psnr.c b/tests/tiny_psnr.c
index 5d01065..b4fc02c 100644
--- a/tests/tiny_psnr.c
+++ b/tests/tiny_psnr.c
@@ -22,8 +22,12 @@
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
+#include <math.h>
+#include <float.h>
+#include <limits.h>
#include "libavutil/intfloat.h"
+#include "libavutil/intreadwrite.h"
#define FFMIN(a, b) ((a) > (b) ? (b) : (a))
#define F 100
@@ -121,17 +125,22 @@
return v.f;
}
+static double get_f64l(uint8_t *p)
+{
+ return av_int2double(AV_RL64(p));
+}
+
static int run_psnr(FILE *f[2], int len, int shift, int skip_bytes)
{
int i, j;
uint64_t sse = 0;
- uint64_t dev;
+ double sse_d = 0.0;
uint8_t buf[2][SIZE];
- uint64_t psnr;
int64_t max = (1LL << (8 * len)) - 1;
int size0 = 0;
int size1 = 0;
- int maxdist = 0;
+ uint64_t maxdist = 0;
+ double maxdist_d = 0.0;
int noseek;
noseek = fseek(f[0], 0, SEEK_SET) ||
@@ -168,23 +177,42 @@
int s1 = fread(buf[1], 1, SIZE, f[1]);
for (j = 0; j < FFMIN(s0, s1); j += len) {
- int64_t a = buf[0][j];
- int64_t b = buf[1][j];
- int dist;
- if (len == 2) {
- a = get_s16l(buf[0] + j);
- b = get_s16l(buf[1] + j);
- } else if (len == 4) {
- a = get_f32l(buf[0] + j) * (1 << 24);
- b = get_f32l(buf[1] + j) * (1 << 24);
- } else {
- a = buf[0][j];
- b = buf[1][j];
+ switch (len) {
+ case 1:
+ case 2: {
+ int64_t a = buf[0][j];
+ int64_t b = buf[1][j];
+ int dist;
+ if (len == 2) {
+ a = get_s16l(buf[0] + j);
+ b = get_s16l(buf[1] + j);
+ } else {
+ a = buf[0][j];
+ b = buf[1][j];
+ }
+ sse += (a - b) * (a - b);
+ dist = abs(a - b);
+ if (dist > maxdist)
+ maxdist = dist;
+ break;
}
- sse += (a - b) * (a - b);
- dist = abs(a - b);
- if (dist > maxdist)
- maxdist = dist;
+ case 4:
+ case 8: {
+ double dist, a, b;
+ if (len == 8) {
+ a = get_f64l(buf[0] + j);
+ b = get_f64l(buf[1] + j);
+ } else {
+ a = get_f32l(buf[0] + j);
+ b = get_f32l(buf[1] + j);
+ }
+ dist = fabs(a - b);
+ sse_d += (a - b) * (a - b);
+ if (dist > maxdist_d)
+ maxdist_d = dist;
+ break;
+ }
+ }
}
size0 += s0;
size1 += s1;
@@ -195,18 +223,44 @@
i = FFMIN(size0, size1) / len;
if (!i)
i = 1;
- dev = int_sqrt(((sse / i) * F * F) + (((sse % i) * F * F) + i / 2) / i);
- if (sse)
- psnr = ((2 * log16(max << 16) + log16(i) - log16(sse)) *
- 284619LL * F + (1LL << 31)) / (1LL << 32);
- else
- psnr = 1000 * F - 1; // floating point free infinity :)
+ switch (len) {
+ case 1:
+ case 2: {
+ uint64_t psnr;
+ uint64_t dev = int_sqrt(((sse / i) * F * F) + (((sse % i) * F * F) + i / 2) / i);
+ if (sse)
+ psnr = ((2 * log16(max << 16) + log16(i) - log16(sse)) *
+ 284619LL * F + (1LL << 31)) / (1LL << 32);
+ else
+ psnr = 1000 * F - 1; // floating point free infinity :)
- printf("stddev:%5d.%02d PSNR:%3d.%02d MAXDIFF:%5d bytes:%9d/%9d\n",
- (int)(dev / F), (int)(dev % F),
- (int)(psnr / F), (int)(psnr % F),
- maxdist, size0, size1);
- return psnr;
+ printf("stddev:%5d.%02d PSNR:%3d.%02d MAXDIFF:%5"PRIu64" bytes:%9d/%9d\n",
+ (int)(dev / F), (int)(dev % F),
+ (int)(psnr / F), (int)(psnr % F),
+ maxdist, size0, size1);
+ return psnr;
+ }
+ case 4:
+ case 8: {
+ char psnr_str[64];
+ double psnr = INT_MAX;
+ double dev = sqrt(sse_d / i);
+ uint64_t scale = (len == 4) ? (1ULL << 24) : (1ULL << 32);
+
+ if (sse_d) {
+ psnr = 2 * log(DBL_MAX) - log(i / sse_d);
+ snprintf(psnr_str, sizeof(psnr_str), "%5.02f", psnr);
+ } else
+ snprintf(psnr_str, sizeof(psnr_str), "inf");
+
+ maxdist = maxdist_d * scale;
+
+ printf("stddev:%10.2f PSNR:%s MAXDIFF:%10"PRIu64" bytes:%9d/%9d\n",
+ dev * scale, psnr_str, maxdist, size0, size1);
+ return psnr;
+ }
+ }
+ return -1;
}
int main(int argc, char *argv[])
@@ -227,6 +281,8 @@
len = 2;
} else if (!strcmp(argv[3], "f32")) {
len = 4;
+ } else if (!strcmp(argv[3], "f64")) {
+ len = 8;
} else {
char *end;
len = strtol(argv[3], &end, 0);
diff --git a/tools/probetest.c b/tools/probetest.c
index b13c6f9..dd1a0bc 100644
--- a/tools/probetest.c
+++ b/tools/probetest.c
@@ -23,10 +23,17 @@
#include "libavformat/avformat.h"
#include "libavcodec/put_bits.h"
#include "libavutil/lfg.h"
+#include "libavutil/timer.h"
-static int score_array[1000]; //this must be larger than the number of formats
+#define MAX_FORMATS 1000 //this must be larger than the number of formats
+static int score_array[MAX_FORMATS];
+static int64_t time_array[MAX_FORMATS];
static int failures = 0;
+#ifndef AV_READ_TIME
+#define AV_READ_TIME(x) 0
+#endif
+
static void probe(AVProbeData *pd, int type, int p, int size)
{
int i = 0;
@@ -36,7 +43,10 @@
if (fmt->flags & AVFMT_NOFILE)
continue;
if (fmt->read_probe) {
- int score = fmt->read_probe(pd);
+ int score;
+ int64_t start = AV_READ_TIME();
+ score = fmt->read_probe(pd);
+ time_array[i] += AV_READ_TIME() - start;
if (score > score_array[i] && score > AVPROBE_SCORE_MAX / 4) {
score_array[i] = score;
fprintf(stderr,
@@ -49,6 +59,22 @@
}
}
+static void print_times(void)
+{
+ int i = 0;
+ AVInputFormat *fmt = NULL;
+
+ while ((fmt = av_iformat_next(fmt))) {
+ if (fmt->flags & AVFMT_NOFILE)
+ continue;
+ if (time_array[i] > 1000000) {
+ fprintf(stderr, "%12"PRIu64" cycles, %12s\n",
+ time_array[i], fmt->name);
+ }
+ i++;
+ }
+}
+
int main(int argc, char **argv)
{
unsigned int p, i, type, size, retry;
@@ -141,5 +167,7 @@
}
}
}
+ if(AV_READ_TIME())
+ print_times();
return failures;
}
diff --git a/version.sh b/version.sh
index 8d084c2..92edcb9 100755
--- a/version.sh
+++ b/version.sh
@@ -1,5 +1,7 @@
#!/bin/sh
+# Usage: version.sh <ffmpeg-root-dir> <output-version.h> <extra-version>
+
# check for git short hash
if ! test "$revision"; then
revision=$(cd "$1" && git describe --tags --match N 2> /dev/null)
@@ -40,9 +42,17 @@
fi
NEW_REVISION="#define FFMPEG_VERSION \"$version\""
-OLD_REVISION=$(cat version.h 2> /dev/null)
+OLD_REVISION=$(cat "$2" 2> /dev/null | head -3 | tail -1)
-# Update version.h only on revision changes to avoid spurious rebuilds
+# String used for preprocessor guard
+GUARD=$(echo "$2" | sed 's/\//_/' | sed 's/\./_/' | tr '[:lower:]' '[:upper:]' | sed 's/LIB//')
+
+# Update version header only on revision changes to avoid spurious rebuilds
if test "$NEW_REVISION" != "$OLD_REVISION"; then
- echo "$NEW_REVISION" > "$2"
+ cat << EOF > "$2"
+#ifndef $GUARD
+#define $GUARD
+$NEW_REVISION
+#endif /* $GUARD */
+EOF
fi