-ffmpeg (7:2.4.3~trusty1) trusty; urgency=medium
+ffmpeg (7:2.5.0~trusty1.1) trusty; urgency=medium
- * New bugfix release
+ * Enable libvo-aacenc in odd chance it's used
- -- Doug McMahon <mc631man@gmail.com> Fri, 07 Nov 2014 14:38:48 -0500
+ -- Doug McMahon <mc631man@gmail.com> Sat, 06 Dec 2014 08:32:16 -0500
+
+ffmpeg (7:2.5.0~trusty1) trusty; urgency=medium
+
+ * Let's test xcbgrab: XCB-based screen capture
+ * Link ffserver in case of value
+
+ -- Doug McMahon <mc631man@gmail.com> Thu, 04 Dec 2014 08:49:38 -0500
+
+ffmpeg (7:2.5.0~trusty) trusty; urgency=medium
+
+ * New upstream release 2.5
+
+ -- Doug McMahon <mc631man@gmail.com> Thu, 04 Dec 2014 08:02:31 -0500
ffmpeg (7:2.4.2~trusty1.1) trusty; urgency=medium
libtheora-dev,
libva-dev [!hurd-any],
libvdpau-dev,
+ libvo-aacenc-dev,
libvorbis-dev,
libvpx-dev (>= 0.9.6),
libx11-dev,
libx265-dev,
libxext-dev,
libxfixes-dev,
+ libxcb-shm0-dev,
+ libxcb-xfixes0-dev,
libxvidcore-dev,
libxvmc-dev,
texi2html,
/opt/ffmpeg/bin/ffmpeg /usr/bin/ffmpeg
/opt/ffmpeg/bin/ffplay /usr/bin/ffplay
/opt/ffmpeg/bin/ffprobe /usr/bin/ffprobe
+/opt/ffmpeg/bin/ffserver /usr/bin/ffserver
#DEBHELPER#
Entries are sorted chronologically from oldest to youngest within each release,
releases are sorted from youngest to oldest.
-version <next>:
-
-version 2.4.3:
-- avcodec/svq1dec: zero terminate embedded message before printing
-- avcodec/cook: check that the subpacket sizes fit in block_align
-- avcodec/g2meet: check tile dimensions to avoid integer overflow
-- avcodec/utils: Align dimensions by at least their chroma sub-sampling factors.
-- avcodec/dnxhddec: treat pix_fmt like width/height
-- avcodec/dxa: check dimensions
-- avcodec/dirac_arith: fix integer overflow
-- avcodec/diracdec: Tighter checks on CODEBLOCKS_X/Y
-- avcodec/diracdec: Use 64bit in calculation of codeblock coordinates
-- avcodec/sgidec: fix count check
-- avcodec/sgidec: fix linesize for 16bit
-- avcodec/hevc_ps: Check default display window bitstream and skip if invalid
-- avcodec/tiffenc: properly compute packet size
-- lavd: export all symbols with av_ prefix
-- avformat/mxfdec: Fix termination of mxf_data_essence_container_uls
-- postproc: fix qp count
-- postproc/postprocess: fix quant store for fq mode
-- vf_drawtext: add missing clear of pointers after av_expr_free()
-- utvideoenc: properly set slice height/last line
-- swresample: fix sample drop loop end condition
-- resample: Avoid off-by-1 errors in PTS calcs.
-- imc: fix order of operations in coefficients read
-- hevc_mvs: make sure to always initialize the temporal MV fully
-- hevc_mvs: initialize the temporal MV in case of missing reference
-
-version 2.4.2:
-- avcodec/on2avc: Check number of channels
-- avcodec/hevc: fix chroma transform_add size
-- avcodec/h264: Check mode before considering mixed mode intra prediction
-- avformat/mpegts: use a padded buffer in read_sl_header()
-- avformat/mpegts: Check desc_len / get8() return code
-- avcodec/vorbisdec: Fix off by 1 error in ptns_to_read
-- sdp: add support for H.261
-- avcodec/svq3: Do not memcpy AVFrame
-- avcodec/smc: fix off by 1 error
-- avcodec/qpeg: fix off by 1 error in MV bounds check
-- avcodec/gifdec: factorize interleave end handling out
-- avcodec/cinepak: fix integer underflow
-- avcodec/pngdec: Check bits per pixel before setting monoblack pixel format
-- avcodec/pngdec: Calculate MPNG bytewidth more defensively
-- avcodec/tiff: more completely check bpp/bppcount
-- avcodec/mmvideo: Bounds check 2nd line of HHV Intra blocks
-- avcodec/h263dec: Fix decoding messenger.h263
-- avcodec/utils: Add case for jv to avcodec_align_dimensions2()
-- avcodec/mjpegdec: check bits per pixel for changes similar to dimensions
-- avcodec/jpeglsdec: Check run value more completely in ls_decode_line()
-- avformat/hlsenc: export inner muxer timebase
-- configure: add noexecstack to linker options if supported.
-- avcodec/ac3enc_template: fix out of array read
-- avutil/x86/cpu: fix cpuid sub-leaf selection
-- avformat/img2dec: enable generic seeking for image pipes
-- avformat/img2dec: initialize pkt->pos for image pipes
-- avformat/img2dec: pass error code and signal EOF
-- avformat/img2dec: fix error code at EOF for pipes
-- libavutil/opt: fix av_opt_set_channel_layout() to access correct memory address
-- tests/fate-run.sh: Cat .err file in case of error with V>0
-- avformat/riffenc: Filter out "BottomUp" in ff_put_bmp_header()
-- avcodec/webp: fix default palette color 0xff000000 -> 0x00000000
-- avcodec/asvenc: fix AAN scaling
-- Fix compile error on arm4/arm5 platform
-
-
-version 2.4.1:
-- swscale: Allow chroma samples to be above and to the left of luma samples
-- avcodec/libilbc: support for latest git of libilbc
-- avcodec/webp: treat out-of-bound palette index as translucent black
-- vf_deshake: rename Transform.vector to Transform.vec to avoid compiler confusion
-- apetag: Fix APE tag size check
-- tools/crypto_bench: fix build when AV_READ_TIME is unavailable
+version 2.5:
+- HEVC/H.265 RTP payload format (draft v6) packetizer
+- SUP/PGS subtitle demuxer
+- ffprobe -show_pixel_formats option
+- CAST128 symmetric block cipher, ECB mode
+- STL subtitle demuxer and decoder
+- libutvideo YUV 4:2:2 10bit support
+- XCB-based screen-grabber
+- UDP-Lite support (RFC 3828)
+- xBR scaling filter
+- AVFoundation screen capturing support
+- ffserver supports codec private options
+- creating DASH compatible fragmented MP4, MPEG-DASH segmenting muxer
+- WebP muxer with animated WebP support
+- zygoaudio decoding support
+- APNG demuxer
+- postproc visualization support
version 2.4:
documentation accompanying your program if you only distribute executables.
You must also indicate any changes including additions and deletions to
those three files in the documentation.
+ tests/reference.pnm is under the expat license
external libraries
avfoundation.m Thilo Borgmann
+ decklink* Deti Fliegl
dshow.c Roger Pack (CC rogerdpack@gmail.com)
fbdev_enc.c Lukasz Marek
gdigrab.c Roger Pack (CC rogerdpack@gmail.com)
aiffdec.c Baptiste Coudurier, Matthieu Bouron
aiffenc.c Baptiste Coudurier, Matthieu Bouron
ape.c Kostya Shishkov
+ apngdec.c Benoit Fouet
ass* Aurelien Jacobs
astdec.c Paul B Mahol
astenc.c James Almer
rtmp* Kostya Shishkov
rtp.c, rtpenc.c Martin Storsjo
rtpdec_h261.*, rtpenc_h261.* Thomas Volkert
- rtpdec_hevc.* Thomas Volkert
+ rtpdec_hevc.*, rtpenc_hevc.* Thomas Volkert
rtpdec_asf.* Ronald S. Bultje
rtpenc_mpv.*, rtpenc_aac.* Martin Storsjo
rtsp.c Luca Barbato
libssh.c Lukasz Marek
mms*.c Ronald S. Bultje
udp.c Luca Abeni
+ icecast.c Marvin Scholz
libswresample
OBJS-ffmpeg-$(HAVE_VDPAU_X11) += ffmpeg_vdpau.o
OBJS-ffmpeg-$(HAVE_DXVA2_LIB) += ffmpeg_dxva2.o
OBJS-ffmpeg-$(CONFIG_VDA) += ffmpeg_vda.o
+OBJS-ffserver += ffserver_config.o
TESTTOOLS = audiogen videogen rotozoom tiny_psnr tiny_ssim base64
HOSTPROGS := $(TESTTOOLS:%=tests/%) doc/print_options
### Examples
-Conding examples are available in the **doc/example** directory.
+Coding examples are available in the **doc/examples** directory.
## License
┌────────────────────────────────────────┐
- │ RELEASE NOTES for FFmpeg 2.4 "Fresnel" │
+ │ RELEASE NOTES for FFmpeg 2.5 "Bohr" │
└────────────────────────────────────────┘
- The FFmpeg Project proudly presents FFmpeg 2.4 "Fresnel", just 2 months
- after the release of 2.3. Since this wasn't a long time ago, the Changelog
+ The FFmpeg Project proudly presents FFmpeg 2.5 "Bohr", just 2.5 months
+ after the release of 2.4. Since this wasn't a long time ago, the Changelog
is a bit short this time.
- The most important thing in this release is the major version bump of the
- libraries. This means that this release is neither ABI-compatible nor
- fully API-compatible. But on the other hand it is aligned with the Libav
- 11 release series, and will as a result probably end up being maintained for
- a long time.
-
As usual, if you have any question on this release or any FFmpeg related
topic, feel free to join us on the #ffmpeg IRC channel (on
irc.freenode.net).
│ 🔨 API Information │
└────────────────────────────┘
- FFmpeg 2.4 includes the following library versions:
+ FFmpeg 2.5 includes the following library versions:
+
+ • libavutil 54.15.100
+ • libavcodec 56.13.100
+ • libavformat 56.15.102
+ • libavdevice 56. 3.100
+ • libavfilter 5. 2.103
+ • libswscale 3. 1.101
+ • libswresample 1. 1.100
+ • libpostproc 53. 3.100
- • libavutil 54.7.100
- • libavcodec 56.1.100
- • libavformat 56.4.101
- • libavdevice 56.0.100
- • libavfilter 5.1.100
- • libswscale 3.0.100
- • libswresample 1.1.100
- • libpostproc 53.0.100
+ Important API changes since 2.4:
- Important API changes since 2.3:
+ • avpriv_dv_frame_profile2() has been deprecated
- • The new field mime_type was added to AVProbeData, which can
- cause crashes, if it is not initialized.
- • Some deprecated functions were removed.
- • The avfilter_graph_parse function was made compatible with Libav.
- • The Matroska demuxer now outputs verbatim ASS packets.
Please refer to the doc/APIchanges file for more information.
│ ★ List of New Features │
└────────────────────────────┘
+ ┌────────────────────────────┐
+ │ ffprobe │
+ └────────────────────────────┘
+
+ • -show_pixel_formats option
+
+ ┌────────────────────────────┐
+ │ ffserver │
+ └────────────────────────────┘
+
+ • codec private options support
+
+ ┌────────────────────────────┐
+ │ libavcodec │
+ └────────────────────────────┘
+
+ • STL subtitle decoder
+ • libutvideo YUV 4:2:2 10bit support
+ • animated WebP decoding support
+ • zygoaudio decoding support
+
+ ┌────────────────────────────┐
+ │ libavdevice │
+ └────────────────────────────┘
+
+ • XCB-based screen-grabber
+ • AVFoundation screen capturing support
+
┌────────────────────────────┐
│ libavformat │
└────────────────────────────┘
- • Icecast protocol.
- • API for live metadata updates through event flags.
- • UTF-16 support in text subtitles formats.
- • The ASS muxer now reorders the Dialogue events properly.
- • support for H.261 RTP payload format (RFC 4587)
- • HEVC/H.265 RTP payload format (draft v6) depacketizer
+ • HEVC/H.265 RTP payload format (draft v6) packetizer
+ • SUP/PGS subtitle demuxer
+ • STL subtitle demuxer
+ • UDP-Lite support (RFC 3828)
+ • creating DASH compatible fragmented MP4, MPEG-DASH segmenting muxer
+ • WebP muxer
+ • APNG demuxer
┌────────────────────────────┐
│ libavfilter │
└────────────────────────────┘
- • Ported lenscorrection filter from frei0r filter.
- • Large optimizations in dctdnoiz to make it usable.
- • Added codecview filter to visualize information exported by some codecs.
- • Added silenceremove filter.
+ • xBR scaling filter
┌────────────────────────────┐
│ libavutil │
└────────────────────────────┘
- • Added clip() function in eval.
+ • CAST128 symmetric block cipher, ECB mode
+
+ ┌────────────────────────────┐
+ │ libpostproc │
+ └────────────────────────────┘
+
+ • visualization support
┌────────────────────────────┐
│ ⚠ Behaviour changes │
└────────────────────────────┘
-
- • dctdnoiz filter now uses a block size of 8x8 instead of 16x16 by default
- • -vismv option is deprecated in favor of the codecview filter
- • libmodplug is now detected through pkg-config
- • HTML documentation generation through texi2html is deprecated in
- favor of makeinfo/texi2any
- • ICY metadata are now requested by default with the HTTP protocol
(po->name && !strcmp(optname, po->name)))
return i;
- if (po->flags & HAS_ARG)
+ if (!po->name || po->flags & HAS_ARG)
i++;
}
return 0;
report_file = fopen(filename.str, "w");
if (!report_file) {
+ int ret = AVERROR(errno);
av_log(NULL, AV_LOG_ERROR, "Failed to open report \"%s\": %s\n",
filename.str, strerror(errno));
- return AVERROR(errno);
+ return ret;
}
av_log_set_callback(log_callback_report);
av_log(NULL, AV_LOG_INFO,
int show_filters(void *optctx, const char *opt, const char *arg)
{
- const AVFilter av_unused(*filter) = NULL;
+#if CONFIG_AVFILTER
+ const AVFilter *filter = NULL;
char descr[64], *descr_cur;
int i, j;
const AVFilterPad *pad;
" V = Video input/output\n"
" N = Dynamic number and/or type of input/output\n"
" | = Source or sink filter\n");
-#if CONFIG_AVFILTER
while ((filter = avfilter_next(filter))) {
descr_cur = descr;
for (i = 0; i < 2; i++) {
filter->process_command ? 'C' : '.',
filter->name, descr, filter->description);
}
+#else
+ printf("No filters available: libavfilter disabled\n");
#endif
return 0;
}
FILE *f = av_fopen_utf8(filename, "rb");
if (!f) {
+ ret = AVERROR(errno);
av_log(NULL, AV_LOG_ERROR, "Cannot read file '%s': %s\n", filename,
strerror(errno));
- return AVERROR(errno);
+ return ret;
}
fseek(f, 0, SEEK_END);
*size = ftell(f);
fseek(f, 0, SEEK_SET);
if (*size == (size_t)-1) {
+ ret = AVERROR(errno);
av_log(NULL, AV_LOG_ERROR, "IO error: %s\n", strerror(errno));
fclose(f);
- return AVERROR(errno);
+ return ret;
}
*bufptr = av_malloc(*size + 1);
if (!*bufptr) {
if (ret < *size) {
av_free(*bufptr);
if (ferror(f)) {
+ ret = AVERROR(errno);
av_log(NULL, AV_LOG_ERROR, "Error while reading file '%s': %s\n",
filename, strerror(errno));
- ret = AVERROR(errno);
} else
ret = AVERROR_EOF;
} else {
switch (check_stream_specifier(s, st, p + 1)) {
case 1: *p = 0; break;
case 0: continue;
- default: return NULL;
+ default: exit_program(1);
}
if (av_opt_find(&cc, t->key, NULL, flags, AV_OPT_SEARCH_FAKE_OBJ) ||
}
return array;
}
+
+#if CONFIG_AVDEVICE
+static int print_device_sources(AVInputFormat *fmt, AVDictionary *opts)
+{
+ int ret, i;
+ AVFormatContext *dev = NULL;
+ AVDeviceInfoList *device_list = NULL;
+ AVDictionary *tmp_opts = NULL;
+
+ if (!fmt || !fmt->priv_class || !AV_IS_INPUT_DEVICE(fmt->priv_class->category))
+ return AVERROR(EINVAL);
+
+ printf("Audo-detected sources for %s:\n", fmt->name);
+ if (!fmt->get_device_list) {
+ ret = AVERROR(ENOSYS);
+ printf("Cannot list sources. Not implemented.\n");
+ goto fail;
+ }
+
+ /* TODO: avformat_open_input calls read_header callback which is not necessary.
+ Function like avformat_alloc_output_context2 for input could be helpful here. */
+ av_dict_copy(&tmp_opts, opts, 0);
+ if ((ret = avformat_open_input(&dev, NULL, fmt, &tmp_opts)) < 0) {
+ printf("Cannot open device: %s.\n", fmt->name);
+ goto fail;
+ }
+
+ if ((ret = avdevice_list_devices(dev, &device_list)) < 0) {
+ printf("Cannot list sources.\n");
+ goto fail;
+ }
+
+ for (i = 0; i < device_list->nb_devices; i++) {
+ printf("%s %s [%s]\n", device_list->default_device == i ? "*" : " ",
+ device_list->devices[i]->device_name, device_list->devices[i]->device_description);
+ }
+
+ fail:
+ av_dict_free(&tmp_opts);
+ avdevice_free_list_devices(&device_list);
+ avformat_close_input(&dev);
+ return ret;
+}
+
+static int print_device_sinks(AVOutputFormat *fmt, AVDictionary *opts)
+{
+ int ret, i;
+ AVFormatContext *dev = NULL;
+ AVDeviceInfoList *device_list = NULL;
+ AVDictionary *tmp_opts = NULL;
+
+ if (!fmt || !fmt->priv_class || !AV_IS_OUTPUT_DEVICE(fmt->priv_class->category))
+ return AVERROR(EINVAL);
+
+ printf("Audo-detected sinks for %s:\n", fmt->name);
+ if (!fmt->get_device_list) {
+ ret = AVERROR(ENOSYS);
+ printf("Cannot list sinks. Not implemented.\n");
+ goto fail;
+ }
+
+ if ((ret = avformat_alloc_output_context2(&dev, fmt, NULL, NULL)) < 0) {
+ printf("Cannot open device: %s.\n", fmt->name);
+ goto fail;
+ }
+ av_dict_copy(&tmp_opts, opts, 0);
+ av_opt_set_dict2(dev, &tmp_opts, AV_OPT_SEARCH_CHILDREN);
+
+ if ((ret = avdevice_list_devices(dev, &device_list)) < 0) {
+ printf("Cannot list sinks.\n");
+ goto fail;
+ }
+
+ for (i = 0; i < device_list->nb_devices; i++) {
+ printf("%s %s [%s]\n", device_list->default_device == i ? "*" : " ",
+ device_list->devices[i]->device_name, device_list->devices[i]->device_description);
+ }
+
+ fail:
+ av_dict_free(&tmp_opts);
+ avdevice_free_list_devices(&device_list);
+ avformat_free_context(dev);
+ return ret;
+}
+
+static int show_sinks_sources_parse_arg(const char *arg, char **dev, AVDictionary **opts)
+{
+ int ret;
+ if (arg) {
+ char *opts_str = NULL;
+ av_assert0(dev && opts);
+ *dev = av_strdup(arg);
+ if (!*dev)
+ return AVERROR(ENOMEM);
+ if ((opts_str = strchr(*dev, ','))) {
+ *(opts_str++) = '\0';
+ if (opts_str[0] && ((ret = av_dict_parse_string(opts, opts_str, "=", ":", 0)) < 0)) {
+ av_freep(dev);
+ return ret;
+ }
+ }
+ } else
+ printf("\nDevice name is not provided.\n"
+ "You can pass devicename[,opt1=val1[,opt2=val2...]] as an argument.\n\n");
+ return 0;
+}
+
+int show_sources(void *optctx, const char *opt, const char *arg)
+{
+ AVInputFormat *fmt = NULL;
+ char *dev = NULL;
+ AVDictionary *opts = NULL;
+ int ret = 0;
+ int error_level = av_log_get_level();
+
+ av_log_set_level(AV_LOG_ERROR);
+
+ if ((ret = show_sinks_sources_parse_arg(arg, &dev, &opts)) < 0)
+ goto fail;
+
+ do {
+ fmt = av_input_audio_device_next(fmt);
+ if (fmt) {
+ if (!strcmp(fmt->name, "lavfi"))
+ continue; //it's pointless to probe lavfi
+ if (dev && strcmp(fmt->name, dev))
+ continue;
+ print_device_sources(fmt, opts);
+ }
+ } while (fmt);
+ do {
+ fmt = av_input_video_device_next(fmt);
+ if (fmt) {
+ if (dev && strcmp(fmt->name, dev))
+ continue;
+ print_device_sources(fmt, opts);
+ }
+ } while (fmt);
+ fail:
+ av_dict_free(&opts);
+ av_free(dev);
+ av_log_set_level(error_level);
+ return ret;
+}
+
+int show_sinks(void *optctx, const char *opt, const char *arg)
+{
+ AVOutputFormat *fmt = NULL;
+ char *dev = NULL;
+ AVDictionary *opts = NULL;
+ int ret = 0;
+ int error_level = av_log_get_level();
+
+ av_log_set_level(AV_LOG_ERROR);
+
+ if ((ret = show_sinks_sources_parse_arg(arg, &dev, &opts)) < 0)
+ goto fail;
+
+ do {
+ fmt = av_output_audio_device_next(fmt);
+ if (fmt) {
+ if (dev && strcmp(fmt->name, dev))
+ continue;
+ print_device_sinks(fmt, opts);
+ }
+ } while (fmt);
+ do {
+ fmt = av_output_video_device_next(fmt);
+ if (fmt) {
+ if (dev && strcmp(fmt->name, dev))
+ continue;
+ print_device_sinks(fmt, opts);
+ }
+ } while (fmt);
+ fail:
+ av_dict_free(&opts);
+ av_free(dev);
+ av_log_set_level(error_level);
+ return ret;
+}
+#endif
*/
int show_devices(void *optctx, const char *opt, const char *arg);
+#if CONFIG_AVDEVICE
+/**
+ * Print a listing containing audodetected sinks of the output device.
+ * Device name with options may be passed as an argument to limit results.
+ */
+int show_sinks(void *optctx, const char *opt, const char *arg);
+
+/**
+ * Print a listing containing audodetected sources of the input device.
+ * Device name with options may be passed as an argument to limit results.
+ */
+int show_sources(void *optctx, const char *opt, const char *arg);
+#endif
+
/**
* Print a listing containing all the codecs supported by the
* program.
{ "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
+#if CONFIG_AVDEVICE
+ { "sources" , OPT_EXIT | HAS_ARG, { .func_arg = show_sources },
+ "list sources of the input device", "device" },
+ { "sinks" , OPT_EXIT | HAS_ARG, { .func_arg = show_sinks },
+ "list sinks of the output device", "device" },
+#endif
* not mutexes */
typedef CRITICAL_SECTION pthread_mutex_t;
-/* This is the CONDITIONAL_VARIABLE typedef for using Window's native
- * conditional variables on kernels 6.0+.
- * MinGW does not currently have this typedef. */
+/* This is the CONDITION_VARIABLE typedef for using Windows' native
+ * conditional variables on kernels 6.0+. */
+#if HAVE_CONDITION_VARIABLE_PTR
+typedef CONDITION_VARIABLE pthread_cond_t;
+#else
typedef struct pthread_cond_t {
- void *ptr;
+ void *Ptr;
} pthread_cond_t;
+#endif
-/* function pointers to conditional variable API on windows 6.0+ kernels */
-#if _WIN32_WINNT < 0x0600
-static void (WINAPI *cond_broadcast)(pthread_cond_t *cond);
-static void (WINAPI *cond_init)(pthread_cond_t *cond);
-static void (WINAPI *cond_signal)(pthread_cond_t *cond);
-static BOOL (WINAPI *cond_wait)(pthread_cond_t *cond, pthread_mutex_t *mutex,
- DWORD milliseconds);
-#else
-#define cond_init InitializeConditionVariable
-#define cond_broadcast WakeAllConditionVariable
-#define cond_signal WakeConditionVariable
-#define cond_wait SleepConditionVariableCS
-
-#define CreateEvent(a, reset, init, name) \
- CreateEventEx(a, name, \
- (reset ? CREATE_EVENT_MANUAL_RESET : 0) | \
- (init ? CREATE_EVENT_INITIAL_SET : 0), \
- EVENT_ALL_ACCESS)
-// CreateSemaphoreExA seems to be desktop-only, but as long as we don't
-// use named semaphores, it doesn't matter if we use the W version.
-#define CreateSemaphore(a, b, c, d) \
- CreateSemaphoreExW(a, b, c, d, 0, SEMAPHORE_ALL_ACCESS)
+#if _WIN32_WINNT >= 0x0600
#define InitializeCriticalSection(x) InitializeCriticalSectionEx(x, 0, 0)
#define WaitForSingleObject(a, b) WaitForSingleObjectEx(a, b, FALSE)
#endif
return 0;
}
+#if _WIN32_WINNT >= 0x0600
+static inline int pthread_cond_init(pthread_cond_t *cond, const void *unused_attr)
+{
+ InitializeConditionVariable(cond);
+ return 0;
+}
+
+/* native condition variables do not destroy */
+static inline void pthread_cond_destroy(pthread_cond_t *cond)
+{
+ return;
+}
+
+static inline void pthread_cond_broadcast(pthread_cond_t *cond)
+{
+ WakeAllConditionVariable(cond);
+}
+
+static inline int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
+{
+ SleepConditionVariableCS(cond, mutex, INFINITE);
+ return 0;
+}
+
+static inline void pthread_cond_signal(pthread_cond_t *cond)
+{
+ WakeConditionVariable(cond);
+}
+
+#else // _WIN32_WINNT < 0x0600
/* for pre-Windows 6.0 platforms we need to define and use our own condition
* variable and api */
typedef struct win32_cond_t {
volatile int is_broadcast;
} win32_cond_t;
+/* function pointers to conditional variable API on windows 6.0+ kernels */
+static void (WINAPI *cond_broadcast)(pthread_cond_t *cond);
+static void (WINAPI *cond_init)(pthread_cond_t *cond);
+static void (WINAPI *cond_signal)(pthread_cond_t *cond);
+static BOOL (WINAPI *cond_wait)(pthread_cond_t *cond, pthread_mutex_t *mutex,
+ DWORD milliseconds);
+
static av_unused int pthread_cond_init(pthread_cond_t *cond, const void *unused_attr)
{
win32_cond_t *win32_cond = NULL;
win32_cond = av_mallocz(sizeof(win32_cond_t));
if (!win32_cond)
return ENOMEM;
- cond->ptr = win32_cond;
+ cond->Ptr = win32_cond;
win32_cond->semaphore = CreateSemaphore(NULL, 0, 0x7fffffff, NULL);
if (!win32_cond->semaphore)
return ENOMEM;
static av_unused void pthread_cond_destroy(pthread_cond_t *cond)
{
- win32_cond_t *win32_cond = cond->ptr;
+ win32_cond_t *win32_cond = cond->Ptr;
/* native condition variables do not destroy */
if (cond_init)
return;
pthread_mutex_destroy(&win32_cond->mtx_waiter_count);
pthread_mutex_destroy(&win32_cond->mtx_broadcast);
av_freep(&win32_cond);
- cond->ptr = NULL;
+ cond->Ptr = NULL;
}
static av_unused void pthread_cond_broadcast(pthread_cond_t *cond)
{
- win32_cond_t *win32_cond = cond->ptr;
+ win32_cond_t *win32_cond = cond->Ptr;
int have_waiter;
if (cond_broadcast) {
static av_unused int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
{
- win32_cond_t *win32_cond = cond->ptr;
+ win32_cond_t *win32_cond = cond->Ptr;
int last_waiter;
if (cond_wait) {
cond_wait(cond, mutex, INFINITE);
static av_unused void pthread_cond_signal(pthread_cond_t *cond)
{
- win32_cond_t *win32_cond = cond->ptr;
+ win32_cond_t *win32_cond = cond->Ptr;
int have_waiter;
if (cond_signal) {
cond_signal(cond);
pthread_mutex_unlock(&win32_cond->mtx_broadcast);
}
+#endif
static av_unused void w32thread_init(void)
{
--enable-libx264 enable H.264 encoding via x264 [no]
--enable-libx265 enable HEVC encoding via x265 [no]
--enable-libxavs enable AVS encoding via xavs [no]
+ --enable-libxcb enable X11 grabbing using XCB [auto]
+ --enable-libxcb-shm enable X11 grabbing shm communication [auto]
+ --enable-libxcb-xfixes enable X11 grabbing mouse rendering [auto]
+ --enable-libxcb-shape enable X11 grabbing shape rendering [auto]
--enable-libxvid enable Xvid encoding via xvidcore,
native MPEG-4/Xvid encoder exists [no]
--enable-libzmq enable message passing via libzmq [no]
--enable-libzvbi enable teletext support via libzvbi [no]
--disable-lzma disable lzma [autodetect]
- --enable-decklink enable Blackmagick DeckLink output [no]
+ --enable-decklink enable Blackmagick DeckLink I/O support [no]
--enable-openal enable OpenAL 1.1 capture support [no]
--enable-opencl enable OpenCL code
--enable-opengl enable OpenGL rendering [no]
--enable-openssl enable openssl [no]
- --enable-x11grab enable X11 grabbing [no]
+ --disable-sdl disable sdl [autodetect]
+ --enable-x11grab enable X11 grabbing (legacy) [no]
--disable-xlib disable xlib [autodetect]
--disable-zlib disable zlib [autodetect]
check_lib_cpp "$headers" "$classes" "$@" || die "ERROR: $name not found"
}
-require_pkg_config(){
+use_pkg_config(){
pkg="$1"
- check_pkg_config "$@" || die "ERROR: $pkg not found"
+ check_pkg_config "$@" || return 1
add_cflags $(get_safe ${pkg}_cflags)
add_extralibs $(get_safe ${pkg}_libs)
}
+require_pkg_config(){
+ use_pkg_config "$@" || die "ERROR: $pkg not found using pkg-config$pkg_config_fail_message"
+}
+
require_libfreetype(){
log require_libfreetype "$@"
pkg="freetype2"
libx264
libx265
libxavs
+ libxcb
+ libxcb_shm
+ libxcb_shape
+ libxcb_xfixes
libxvid
libzmq
libzvbi
opencl
opengl
openssl
+ sdl
x11grab
xlib
zlib
BUILTIN_LIST="
atomic_cas_ptr
+ atomic_compare_exchange
machine_rw_barrier
MemoryBarrier
mm_empty
sys_un_h
sys_videoio_h
termios_h
+ udplite_h
unistd_h
windows_h
winsock2_h
exp2
exp2f
expf
- fminf
isinf
isnan
ldexpf
gettimeofday
glob
glXGetProcAddress
+ gmtime_r
inet_aton
isatty
jack_port_get_latency_range
lzo1x_999_compress
mach_absolute_time
MapViewOfFile
+ MoveFileExA
memalign
mkstemp
mmap
"
TYPES_LIST="
+ CONDITION_VARIABLE_Ptr
socklen_t
struct_addrinfo
struct_group_source_req
symver_if_any="symver_asm_label symver_gnu_asm"
# threading support
-atomics_gcc_if="sync_val_compare_and_swap"
+atomics_gcc_if_any="sync_val_compare_and_swap atomic_compare_exchange"
atomics_suncc_if="atomic_cas_ptr machine_rw_barrier"
atomics_win32_if="MemoryBarrier"
atomics_native_if_any="$ATOMICS_LIST"
amv_decoder_select="sp5x_decoder exif"
amv_encoder_select="aandcttables mpegvideoenc"
ape_decoder_select="bswapdsp llauddsp"
+apng_decoder_select="zlib"
asv1_decoder_select="blockdsp bswapdsp idctdsp"
asv1_encoder_select="bswapdsp fdctdsp pixblockdsp"
asv2_decoder_select="blockdsp bswapdsp idctdsp"
avisynth_demuxer_deps="avisynth"
avisynth_demuxer_select="riffdec"
caf_demuxer_select="riffdec"
+dash_muxer_select="mp4_muxer"
dirac_demuxer_select="dirac_parser"
dts_demuxer_select="dca_parser"
dtshd_demuxer_select="dca_parser"
mmf_muxer_select="riffenc"
mov_demuxer_select="riffdec"
mov_demuxer_suggest="zlib"
-mov_muxer_select="riffenc rtpenc_chain"
+mov_muxer_select="riffenc rtpenc_chain ac3_parser"
mp3_demuxer_select="mpegaudio_parser"
mp4_muxer_select="mov_muxer"
mpegts_muxer_select="adts_muxer latm_muxer"
# indevs / outdevs
alsa_indev_deps="alsa_asoundlib_h snd_pcm_htimestamp"
alsa_outdev_deps="alsa_asoundlib_h"
-avfoundation_indev_extralibs="-framework CoreVideo -framework Foundation -framework AVFoundation -framework CoreMedia"
+avfoundation_indev_extralibs="-framework CoreVideo -framework Foundation -framework AVFoundation -framework CoreMedia -framework CoreGraphics"
avfoundation_indev_select="avfoundation"
bktr_indev_deps_any="dev_bktr_ioctl_bt848_h machine_ioctl_bt848_h dev_video_bktr_ioctl_bt848_h dev_ic_bt8xx_h"
caca_outdev_deps="libcaca"
decklink_outdev_deps="decklink pthreads"
decklink_outdev_extralibs="-lstdc++"
+decklink_indev_deps="decklink pthreads"
+decklink_indev_extralibs="-lstdc++"
dshow_indev_deps="IBaseFilter"
dshow_indev_extralibs="-lpsapi -lole32 -lstrmiids -luuid"
dv1394_indev_deps="dv1394"
xv_outdev_deps="X11_extensions_Xvlib_h XvGetPortAttribute"
xv_outdev_extralibs="-lXv -lX11 -lXext"
x11grab_indev_deps="x11grab"
+x11grab_xcb_indev_deps="libxcb"
# protocols
bluray_protocol_deps="libbluray"
tls_protocol_deps_any="openssl gnutls"
tls_protocol_select="tcp_protocol"
udp_protocol_select="network"
+udplite_protocol_select="network"
unix_protocol_deps="sys_un_h"
unix_protocol_select="network"
# filters
-aconvert_filter_deps="swresample"
amovie_filter_deps="avcodec avformat"
aresample_filter_deps="swresample"
ass_filter_deps="libass"
ebur128_filter_deps="gpl"
flite_filter_deps="libflite"
frei0r_filter_deps="frei0r dlopen"
-frei0r_filter_extralibs='$ldl'
frei0r_src_filter_deps="frei0r dlopen"
-frei0r_src_filter_extralibs='$ldl'
geq_filter_deps="gpl"
histeq_filter_deps="gpl"
hqdn3d_filter_deps="gpl"
interlace_filter_deps="gpl"
kerndeint_filter_deps="gpl"
ladspa_filter_deps="ladspa dlopen"
-ladspa_filter_extralibs='$ldl'
mcdeint_filter_deps="avcodec gpl"
movie_filter_deps="avcodec avformat"
-mp_filter_deps="gpl avcodec swscale inline_asm"
+mp_filter_deps="gpl avcodec swscale"
mpdecimate_filter_deps="gpl"
mpdecimate_filter_select="pixelutils"
mptestsrc_filter_deps="gpl"
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
+ add_cppflags -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2
+ add_cflags -fno-strict-overflow -fstack-protector-all
+ add_ldflags -Wl,-z,relro -Wl,-z,now
;;
?*)
die "Unknown toolchain $toolchain"
enabled cross_compile || host_cc_default=$cc
set_default host_cc
+pkg_config_fail_message=""
if ! $pkg_config --version >/dev/null 2>&1; then
warn "$pkg_config not found, library detection may fail."
pkg_config=false
+elif is_in -static $cc $LDFLAGS && ! is_in --static $pkg_config $pkg_config_flags; then
+ pkg_config_fail_message="
+Note: When building a static binary, add --pkg-config-flags=\"--static\"."
fi
if test $doxygen != $doxygen_default && \
# 4509: "This form of conditional instruction is deprecated"
_flags="-nologo -ignore 4509"
_flags_filter=armasm_flags
- elif $_cc 2>&1 | grep -q Microsoft; then
- _type=msvc
+ elif $_cc 2>&1 | grep -q Intel; then
+ _type=icl
_ident=$($cc 2>&1 | head -n1)
- _DEPCMD='$(DEP$(1)) $(DEP$(1)FLAGS) $($(1)DEP_FLAGS) $< 2>&1 | awk '\''/including/ { sub(/^.*file: */, ""); gsub(/\\/, "/"); if (!match($$0, / /)) print "$@:", $$0 }'\'' > $(@:.o=.d)'
- _DEPFLAGS='$(CPPFLAGS) $(CFLAGS) -showIncludes -Zs'
+ _depflags='-QMMD -QMF$(@:.o=.d) -QMT$@'
+ # Not only is O3 broken on 13.x+ but it is slower on all previous
+ # versions (tested) as well.
_cflags_speed="-O2"
- _cflags_size="-O1"
+ _cflags_size="-O1 -Oi" # -O1 without -Oi miscompiles stuff
if $_cc 2>&1 | grep -q Linker; then
_ld_o='-out:$@'
else
_ld_o='-Fe$@'
fi
_cc_o='-Fo$@'
- _cc_e='-P -Fi$@'
- _flags_filter=msvc_flags
+ _cc_e='-P'
+ _flags_filter=icl_flags
_ld_lib='lib%.a'
_ld_path='-libpath:'
- _flags='-nologo'
- _cflags='-D_USE_MATH_DEFINES -D_CRT_SECURE_NO_WARNINGS -Dinline=__inline -FIstdlib.h -Dstrtoll=_strtoi64'
+ # -Qdiag-error to make icl error when seeing certain unknown arguments
+ _flags='-nologo -Qdiag-error:4044,10157'
+ # -Qvec- -Qsimd- to prevent miscompilation, -GS, fp:precise for consistency
+ # with MSVC which enables it by default.
+ _cflags='-D_USE_MATH_DEFINES -FIstdlib.h -Dstrtoll=_strtoi64 -Qms0 -Qvec- -Qsimd- -GS -fp:precise'
if [ $pfx = hostcc ]; then
append _cflags -Dsnprintf=_snprintf
fi
disable stripping
- elif $_cc 2>&1 | grep -q Intel; then
- _type=icl
+ elif $_cc 2>&1 | grep -q Microsoft; then
+ _type=msvc
_ident=$($cc 2>&1 | head -n1)
- _depflags='-QMMD -QMF$(@:.o=.d) -QMT$@'
- # Not only is O3 broken on 13.x+ but it is slower on all previous
- # versions (tested) as well.
+ _DEPCMD='$(DEP$(1)) $(DEP$(1)FLAGS) $($(1)DEP_FLAGS) $< 2>&1 | awk '\''/including/ { sub(/^.*file: */, ""); gsub(/\\/, "/"); if (!match($$0, / /)) print "$@:", $$0 }'\'' > $(@:.o=.d)'
+ _DEPFLAGS='$(CPPFLAGS) $(CFLAGS) -showIncludes -Zs'
_cflags_speed="-O2"
- _cflags_size="-O1 -Oi" # -O1 without -Oi miscompiles stuff
+ _cflags_size="-O1"
if $_cc 2>&1 | grep -q Linker; then
_ld_o='-out:$@'
else
_ld_o='-Fe$@'
fi
_cc_o='-Fo$@'
- _cc_e='-P'
- _flags_filter=icl_flags
+ _cc_e='-P -Fi$@'
+ _flags_filter=msvc_flags
_ld_lib='lib%.a'
_ld_path='-libpath:'
- # -Qdiag-error to make icl error when seeing certain unknown arguments
- _flags='-nologo -Qdiag-error:4044,10157'
- # -Qvec- -Qsimd- to prevent miscompilation, -GS, fp:precise for consistency
- # with MSVC which enables it by default.
- _cflags='-D_USE_MATH_DEFINES -FIstdlib.h -Dstrtoll=_strtoi64 -Qms0 -Qvec- -Qsimd- -GS -fp:precise'
+ _flags='-nologo'
+ _cflags='-D_USE_MATH_DEFINES -D_CRT_SECURE_NO_WARNINGS -Dinline=__inline -FIstdlib.h -Dstrtoll=_strtoi64'
if [ $pfx = hostcc ]; then
append _cflags -Dsnprintf=_snprintf
fi
+ disable stripping
elif $_cc --version 2>/dev/null | grep -q ^cparser; then
_type=cparser
_ident=$($_cc --version | head -n1)
;;
x86)
check_64bit x86_32 x86_64 'sizeof(void *) > 4'
+ # Treat x32 as x64 for now. Note it also needs spic=$shared
+ test "$subarch" = "x86_32" && check_cpp_condition stddef.h 'defined(__x86_64__)' &&
+ subarch=x86_64
if test "$subarch" = "x86_64"; then
spic=$shared
fi
enabled shared && ! enabled small && check_cmd $windres --version && enable gnu_windres
check_ldflags -Wl,--nxcompat
check_ldflags -Wl,--dynamicbase
+ enabled x86_32 && check_ldflags -Wl,--large-address-aware
shlibdir_default="$bindir_default"
SLIBPREF=""
SLIBSUF=".dll"
# Cannot build both shared and static libs with MSVC or icl.
disable static
fi
+ enabled x86_32 && check_ldflags -LARGEADDRESSAWARE
shlibdir_default="$bindir_default"
SLIBPREF=""
SLIBSUF=".dll"
eval ${pfx}libc_type=solaris
add_${pfx}cppflags -D__EXTENSIONS__ -D_XOPEN_SOURCE=600
fi
+ check_${pfx}cc <<EOF
+#include <time.h>
+void *v = localtime_r;
+EOF
+test "$?" != 0 && check_${pfx}cc -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600 <<EOF && add_${pfx}cppflags -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600
+#include <time.h>
+void *v = localtime_r;
+EOF
+
}
probe_libc
od -t x1 $TMPO | grep -q '42 *49 *47 *45' && enable bigendian
if [ "$cpu" = "power7" ] || [ "$cpu" = "power8" ] ;then
- if ! enabled bigendian ;then
+ if ! enabled bigendian && enabled altivec ;then
enable vsx
fi
fi
if enabled gcc; then
case $($cc -dumpversion) in
- 4.[3-8].*) check_cflags -fno-optimize-sibling-calls ;;
+ 4.[3-9].*) check_cflags -fno-optimize-sibling-calls ;;
esac
fi
ldl=-ldl
fi
+frei0r_filter_extralibs='$ldl'
+frei0r_src_filter_extralibs='$ldl'
+ladspa_filter_extralibs='$ldl'
+
if ! disabled network; then
check_func getaddrinfo $network_extralibs
check_func getservbyport $network_extralibs
fi
check_builtin atomic_cas_ptr atomic.h "void **ptr; void *oldval, *newval; atomic_cas_ptr(ptr, oldval, newval)"
+check_builtin atomic_compare_exchange "" "int *ptr, *oldval; int newval; __atomic_compare_exchange_n(ptr, oldval, newval, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)"
check_builtin machine_rw_barrier mbarrier.h "__machine_rw_barrier()"
check_builtin MemoryBarrier windows.h "MemoryBarrier()"
check_builtin sarestart signal.h "SA_RESTART"
check_func ${malloc_prefix}posix_memalign && enable posix_memalign
check_func access
-check_func_headers time.h clock_gettime || { check_func_headers time.h clock_gettime -lrt && add_extralibs -lrt; }
+check_func_headers time.h clock_gettime || { check_func_headers time.h clock_gettime -lrt && add_extralibs -lrt && LIBRT="-lrt"; }
check_func fcntl
check_func fork
check_func gethrtime
check_func getopt
check_func getrusage
check_func gettimeofday
+check_func gmtime_r
check_func isatty
check_func localtime_r
check_func mach_absolute_time
check_func mmap
check_func mprotect
# Solaris has nanosleep in -lrt, OpenSolaris no longer needs that
-check_func_headers time.h nanosleep || { check_func_headers time.h nanosleep -lrt && add_extralibs -lrt; }
+check_func_headers time.h nanosleep || { check_func_headers time.h nanosleep -lrt && add_extralibs -lrt && LIBRT="-lrt"; }
check_func sched_getaffinity
check_func setrlimit
check_struct "sys/stat.h" "struct stat" st_mtim.tv_nsec -D_BSD_SOURCE
check_func_headers windows.h GetProcessTimes
check_func_headers windows.h GetSystemTimeAsFileTime
check_func_headers windows.h MapViewOfFile
+check_func_headers windows.h MoveFileExA
check_func_headers windows.h PeekNamedPipe
check_func_headers windows.h SetConsoleTextAttribute
check_func_headers windows.h Sleep
check_func_headers windows.h VirtualAlloc
+check_struct windows.h "CONDITION_VARIABLE" Ptr
check_func_headers glob.h glob
enabled xlib &&
check_func_headers "X11/Xlib.h X11/extensions/Xvlib.h" XvGetPortAttribute -lXv -lX11 -lXext
check_header libcrystalhd/libcrystalhd_if.h
check_header mach/mach_time.h
check_header malloc.h
+check_header net/udplite.h
check_header poll.h
check_header sys/mman.h
check_header sys/param.h
atan2f_args=2
ldexpf_args=2
powf_args=2
-fminf_args=2
for func in $MATH_FUNCS; do
eval check_mathfunc $func \${${func}_args:-1}
enabled libopencore_amrnb && require libopencore_amrnb opencore-amrnb/interf_dec.h Decoder_Interface_init -lopencore-amrnb
enabled libopencore_amrwb && require libopencore_amrwb opencore-amrwb/dec_if.h D_IF_init -lopencore-amrwb
enabled libopencv && require_pkg_config opencv opencv/cxcore.h cvCreateImageHeader
-enabled libopenjpeg && { check_lib openjpeg-1.5/openjpeg.h opj_version -lopenjpeg -DOPJ_STATIC ||
+enabled libopenjpeg && { check_lib openjpeg.h opj_version -lopenmj2 -DOPJ_STATIC ||
+ check_lib openjpeg-1.5/openjpeg.h opj_version -lopenjpeg -DOPJ_STATIC ||
check_lib openjpeg.h opj_version -lopenjpeg -DOPJ_STATIC ||
die "ERROR: libopenjpeg not found"; }
enabled libopus && require_pkg_config opus opus_multistream.h opus_multistream_decoder_create
enabled librtmp && require_pkg_config librtmp librtmp/rtmp.h RTMP_Socket
enabled libschroedinger && require_pkg_config schroedinger-1.0 schroedinger/schro.h schro_init
enabled libshine && require_pkg_config shine shine/layer3.h shine_encode_buffer
-enabled libsmbclient && { { check_pkg_config smbclient libsmbclient.h smbc_init &&
- require_pkg_config smbclient libsmbclient.h smbc_init; } ||
- require smbclient libsmbclient.h smbc_init -lsmbclient; }
+enabled libsmbclient && { check_pkg_config smbclient libsmbclient.h smbc_init ||
+ require smbclient libsmbclient.h smbc_init -lsmbclient; }
enabled libsoxr && require libsoxr soxr.h soxr_create -lsoxr
enabled libssh && require_pkg_config libssh libssh/sftp.h sftp_init
enabled libspeex && require_pkg_config speex speex/speex.h speex_decoder_init -lspeex
enabled libvpx_vp9_decoder && { check_lib2 "vpx/vpx_decoder.h vpx/vp8dx.h" "vpx_codec_vp9_dx" -lvpx || disable libvpx_vp9_decoder; }
enabled libvpx_vp9_encoder && { check_lib2 "vpx/vpx_encoder.h vpx/vp8cx.h" "vpx_codec_vp9_cx VP9E_SET_AQ_MODE" -lvpx || disable libvpx_vp9_encoder; } }
enabled libwavpack && require libwavpack wavpack/wavpack.h WavpackOpenFileOutput -lwavpack
-enabled libwebp && require_pkg_config libwebp webp/encode.h WebPGetEncoderVersion &&
- { check_code cc webp/encode.h "WebPPicture wp; wp.use_argb++" ||
- die "ERROR: libwebp too old."; }
-enabled libx264 && require libx264 x264.h x264_encoder_encode -lx264 &&
+enabled libwebp && require_pkg_config "libwebp >= 0.2.0" webp/encode.h WebPGetEncoderVersion
+enabled libx264 && { use_pkg_config x264 "stdint.h x264.h" x264_encoder_encode ||
+ { require libx264 x264.h x264_encoder_encode -lx264 &&
+ warn "using libx264 without pkg-config"; } } &&
{ check_cpp_condition x264.h "X264_BUILD >= 118" ||
die "ERROR: libx264 must be installed and version must be >= 0.118."; }
enabled libx265 && require_pkg_config x265 x265.h x265_encoder_encode &&
enable libdc1394_1; } ||
die "ERROR: No version of libdc1394 found "
fi
-
-SDL_CONFIG="${cross_prefix}sdl-config"
-if check_pkg_config sdl SDL_events.h SDL_PollEvent; then
- check_cpp_condition SDL.h "(SDL_MAJOR_VERSION<<16 | SDL_MINOR_VERSION<<8 | SDL_PATCHLEVEL) >= 0x010201" $sdl_cflags &&
- check_cpp_condition SDL.h "(SDL_MAJOR_VERSION<<16 | SDL_MINOR_VERSION<<8 | SDL_PATCHLEVEL) < 0x010300" $sdl_cflags &&
- enable sdl
-else
- if "${SDL_CONFIG}" --version > /dev/null 2>&1; then
- sdl_cflags=$("${SDL_CONFIG}" --cflags)
- sdl_libs=$("${SDL_CONFIG}" --libs)
- check_func_headers SDL_version.h SDL_Linked_Version $sdl_cflags $sdl_libs &&
- check_cpp_condition SDL.h "(SDL_MAJOR_VERSION<<16 | SDL_MINOR_VERSION<<8 | SDL_PATCHLEVEL) >= 0x010201" $sdl_cflags &&
- check_cpp_condition SDL.h "(SDL_MAJOR_VERSION<<16 | SDL_MINOR_VERSION<<8 | SDL_PATCHLEVEL) < 0x010300" $sdl_cflags &&
- enable sdl
- fi
+if ! disabled sdl; then
+ SDL_CONFIG="${cross_prefix}sdl-config"
+ if check_pkg_config sdl SDL_events.h SDL_PollEvent; then
+ check_cpp_condition SDL.h "(SDL_MAJOR_VERSION<<16 | SDL_MINOR_VERSION<<8 | SDL_PATCHLEVEL) >= 0x010201" $sdl_cflags &&
+ check_cpp_condition SDL.h "(SDL_MAJOR_VERSION<<16 | SDL_MINOR_VERSION<<8 | SDL_PATCHLEVEL) < 0x010300" $sdl_cflags &&
+ enable sdl
+ else
+ if "${SDL_CONFIG}" --version > /dev/null 2>&1; then
+ sdl_cflags=$("${SDL_CONFIG}" --cflags)
+ sdl_libs=$("${SDL_CONFIG}" --libs)
+ check_func_headers SDL_version.h SDL_Linked_Version $sdl_cflags $sdl_libs &&
+ check_cpp_condition SDL.h "(SDL_MAJOR_VERSION<<16 | SDL_MINOR_VERSION<<8 | SDL_PATCHLEVEL) >= 0x010201" $sdl_cflags &&
+ check_cpp_condition SDL.h "(SDL_MAJOR_VERSION<<16 | SDL_MINOR_VERSION<<8 | SDL_PATCHLEVEL) < 0x010300" $sdl_cflags &&
+ enable sdl
+ elif enabled sdl ; then
+ die "ERROR: SDL not found"
+ else
+ disable sdl
+ fi
+ fi
fi
enabled sdl && add_cflags $sdl_cflags && add_extralibs $sdl_libs
check_code cc linux/videodev2.h "struct v4l2_frmsizeenum vfse; vfse.discrete.width = 0;" && enable_safe struct_v4l2_frmivalenum_discrete
check_header sys/videoio.h
+check_code cc sys/videoio.h "struct v4l2_frmsizeenum vfse; vfse.discrete.width = 0;" && enable_safe struct_v4l2_frmivalenum_discrete
check_func_headers "windows.h vfw.h" capCreateCaptureWindow "$vfwcap_indev_extralibs"
# check that WM_CAP_DRIVER_CONNECT is defined to the proper value
enabled xlib &&
check_lib X11/Xlib.h XOpenDisplay -lX11 || disable xlib
-enabled x11grab &&
-require Xext X11/extensions/XShm.h XShmCreateImage -lXext &&
-require Xfixes X11/extensions/Xfixes.h XFixesGetCursorImage -lXfixes &&
-{ enabled xlib || die "ERROR: Xlib not found"; }
+if ! disabled libxcb; then
+ check_pkg_config xcb xcb/xcb.h xcb_connect || {
+ enabled libxcb && die "ERROR: libxcb not found";
+ } && disable x11grab && enable libxcb
+
+if enabled libxcb; then
+ disabled libxcb_shm || {
+ check_pkg_config xcb-shm xcb/shm.h xcb_shm_attach || {
+ enabled libxcb_shm && die "ERROR: libxcb_shm not found";
+ } && check_header sys/shm.h && enable libxcb_shm; }
+
+ disabled libxcb_xfixes || {
+ check_pkg_config xcb-xfixes xcb/xfixes.h xcb_xfixes_get_cursor_image || {
+ enabled libxcb_xfixes && die "ERROR: libxcb_xfixes not found";
+ } && enable libxcb_xfixes; }
+
+ disabled libxcb_shape || {
+ check_pkg_config xcb-shape xcb/shape.h xcb_shape_get_rectangles || {
+ enabled libxcb_shape && die "ERROR: libxcb_shape not found";
+ } && enable libxcb_shape; }
+
+ add_cflags $xcb_cflags $xcb_shm_cflags $xcb_xfixes_cflags $xcb_shape_cflags
+ add_extralibs $xcb_libs $xcb_shm_libs $xcb_xfixes_libs $xcb_shape_libs
+fi
+fi
+
+if enabled x11grab; then
+ enabled xlib || die "ERROR: Xlib not found"
+ require Xext X11/extensions/XShm.h XShmCreateImage -lXext
+ require Xfixes X11/extensions/Xfixes.h XFixesGetCursorImage -lXfixes
+fi
check_func_headers "windows.h" CreateDIBSection "$gdigrab_indev_extralibs"
enabled zlib && add_cppflags -DZLIB_CONST
# conditional library dependencies, in linking order
-enabled aconvert_filter && prepend avfilter_deps "swresample"
enabled amovie_filter && prepend avfilter_deps "avformat avcodec"
enabled aresample_filter && prepend avfilter_deps "swresample"
enabled asyncts_filter && prepend avfilter_deps "avresample"
EOF
}
-pkgconfig_generate libavutil "FFmpeg utility library" "$LIBAVUTIL_VERSION" "$LIBM"
+pkgconfig_generate libavutil "FFmpeg utility library" "$LIBAVUTIL_VERSION" "$LIBRT $LIBM"
pkgconfig_generate libavcodec "FFmpeg codec library" "$LIBAVCODEC_VERSION" "$extralibs"
pkgconfig_generate libavformat "FFmpeg container format library" "$LIBAVFORMAT_VERSION" "$extralibs"
pkgconfig_generate libavdevice "FFmpeg device handling library" "$LIBAVDEVICE_VERSION" "$extralibs"
API changes, most recent first:
+2014-11-21 - ab922f9 - lavu 54.15.100 - dict.h
+ Add av_dict_get_string().
+
+2014-11-18 - a54a51c - lavu 54.14.100 - float_dsp.h
+ Add avpriv_float_dsp_alloc().
+
+2014-11-16 - 6690d4c3 - lavf 56.13.100 - avformat.h
+ Add AVStream.recommended_encoder_configuration with accessors.
+
+2014-11-16 - bee5844d - lavu 54.13.100 - opt.h
+ Add av_opt_serialize().
+
+2014-11-16 - eec69332 - lavu 54.12.100 - opt.h
+ Add av_opt_is_set_to_default().
+
+2014-11-06 - 44fa267 / 5e80fb7 - lavc 56.11.100 / 56.6.0 - vorbis_parser.h
+ Add a public API for parsing vorbis packets.
+
+2014-10-15 - 17085a0 / 7ea1b34 - lavc 56.7.100 / 56.5.0 - avcodec.h
+ Replace AVCodecContext.time_base used for decoding
+ with AVCodecContext.framerate.
+
+2014-10-15 - 51c810e / d565fef1 - lavc 56.6.100 / 56.4.0 - avcodec.h
+ Add AV_HWACCEL_FLAG_IGNORE_LEVEL flag to av_vdpau_bind_context().
+
+2014-10-13 - da21895 / 2df0c32e - lavc 56.5.100 / 56.3.0 - avcodec.h
+ Add AVCodecContext.initial_padding. Deprecate the use of AVCodecContext.delay
+ for audio encoding.
+
+2014-10-08 - bb44f7d / 5a419b2 - lavu 54.10.100 / 54.4.0 - pixdesc.h
+ Add API to return the name of frame and context color properties.
+
+2014-10-06 - a61899a / e3e158e - lavc 56.3.100 / 56.2.0 - vdpau.h
+ Add av_vdpau_bind_context(). This function should now be used for creating
+ (or resetting) a AVVDPAUContext instead of av_vdpau_alloc_context().
+
+2014-10-02 - cdd6f05 - lavc 56.2.100 - avcodec.h
+2014-10-02 - cdd6f05 - lavu 54.9.100 - frame.h
+ Add AV_FRAME_DATA_SKIP_SAMPLES. Add lavc CODEC_FLAG2_SKIP_MANUAL and
+ AVOption "skip_manual", which makes lavc export skip information via
+ AV_FRAME_DATA_SKIP_SAMPLES AVFrame side data, instead of skipping and
+ discarding samples automatically.
+
+2014-10-02 - 0d92b0d - lavu 54.8.100 - avstring.h
+ Add av_match_list()
+
+2014-09-24 - ac68295 - libpostproc 53.1.100
+ Add visualization support
+
+2014-09-19 - 6edd6a4 - lavc 56.1.101 - dv_profile.h
+ deprecate avpriv_dv_frame_profile2(), which was made public by accident.
+
-------- 8< --------- FFmpeg 2.4 was cut here -------- 8< ---------
2014-05-11 - 14aef38 / 66e6c8a - lavu 52.83.100 / 53.14.0 - pixfmt.h
Add AV_PIX_FMT_VDA for new-style VDA acceleration.
-2014-05-xx - xxxxxxx - lavu 52.82.0 - fifo.h
+2014-05-xx - xxxxxxx - lavu 52.82.100 - fifo.h
Add av_fifo_freep() function.
-2014-05-02 - ba52fb11 - lavu 52.81.0 - opt.h
+2014-05-02 - ba52fb11 - lavu 52.81.100 - opt.h
Add av_opt_set_dict2() function.
2014-05-01 - e77b985 / a2941c8 - lavc 55.60.103 / 55.50.3 - avcodec.h
avresample_read() are now uint8_t** instead of void**.
Libavresample is now stable.
+2012-09-26 - 3ba0dab7 / 1384df64 - lavf 54.29.101 / 56.06.3 - avformat.h
+ Add AVFormatContext.avoid_negative_ts.
+
2012-09-24 - 46a3595 / a42aada - lavc 54.59.100 / 54.28.0 - avcodec.h
Add avcodec_free_frame(). This function must now
be used for freeing an AVFrame.
# This could be handy for archiving the generated documentation or
# if some version control system is used.
-PROJECT_NUMBER = 2.4.3
+PROJECT_NUMBER = 2.5
# With the PROJECT_LOGO tag one can specify a logo or icon that is included
# in the documentation. The maximum height of the logo should not exceed 55
The option @code{-bsfs} of the ff* tools will display the list of
all the supported bitstream filters included in your build.
-Below is a description of the currently available bitstream filters.
+The ff* tools have a -bsf option applied per stream, taking a
+comma-separated list of filters, whose parameters follow the filter
+name after a '='.
+
+@example
+ffmpeg -i INPUT -c:v copy -bsf:v filter1[=opt1=str1/opt2=str2][,filter2] OUTPUT
+@end example
+
+Below is a description of the currently available bitstream filters,
+with their parameters, if any.
@section aac_adtstoasc
Damages the contents of packets without damaging the container. Can be
used for fuzzing or testing error resilience/concealment.
+Parameters:
+A numeral string, whose value is related to how often output bytes will
+be modified. Therefore, values below or equal to 0 are forbidden, and
+the lower the more frequent bytes will be modified, with 1 meaning
+every byte is modified.
+
@example
-ffmpeg -i INPUT -c copy -bsf noise output.mkv
+ffmpeg -i INPUT -c copy -bsf noise[=1] output.mkv
@end example
+applies the modification to every byte.
@section remove_extra
@item global_header
Place global headers in extradata instead of every keyframe.
@item bitexact
-Use only bitexact stuff (except (I)DCT).
+Only write platform-, build- and time-independent data. (except (I)DCT).
+This ensures that file and data checksums are reproducible and match between
+platforms. Its primary use is for regression testing.
@item aic
Apply H263 advanced intra coding / mpeg4 ac prediction.
@item cbp
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.
+
+@item codec_whitelist @var{list} (@emph{input})
+"," separated List of allowed decoders. By default all are allowed.
+
+@item dump_separator @var{string} (@emph{input})
+Separator used to separate the fields printed on the command line about the
+Stream parameters.
+For example to separate the fields with newlines and indention:
+@example
+ffprobe -dump_separator "
+ " -i ~/videos/matrixbench_mpeg2.mpg
+@end example
+
@end table
@c man end CODEC OPTIONS
numbers (without 0x prefix) separated by comas, for example @code{0d00ee,
ee450d, 101010, eaeaea, 0ce60b, ec14ed, ebff0b, 0d617a, 7b7b7b, d1d1d1,
7b2a0e, 0d950c, 0f007b, cf0dec, cfa80c, 7c127b}.
+
+@item ifo_palette
+Specify the IFO file from which the global palette is obtained.
+(experimental)
+
+@item forced_subs_only
+Only decode subtitle entries marked as forced. Some titles have forced
+and non-forced subtitles in the same track. Setting this flag to @code{1}
+will only keep the forced subtitles. Default value is @code{0}.
@end table
@section libzvbi-teletext
The total bitrate of the variant that the stream belongs to is
available in a metadata key named "variant_bitrate".
+@section apng
+
+Animated Portable Network Graphics demuxer.
+
+This demuxer is used to demux APNG files.
+All headers, but the PNG signature, up to (but not including) the first
+fcTL chunk are transmitted as extradata.
+Frames are then split as being all the chunks between two fcTL ones, or
+between the last fcTL and IEND chunks.
+
+@table @option
+@item -ignore_loop @var{bool}
+Ignore the loop variable in the file if set.
+@item -max_fps @var{int}
+Maximum framerate in frames per second (0 for no limit).
+@item -default_fps @var{int}
+Default framerate in frames per second when none is specified in the file
+(0 meaning as fast as possible).
+@end table
+
@section asf
Advanced Systems Format demuxer.
Enable the use of Periodic Intra Refresh instead of IDR frames when set
to 1.
+@item avcintra-class (@emph{class})
+Configure the encoder to generate AVC-Intra.
+Valid values are 50,100 and 200
+
@item bluray-compat (@emph{bluray-compat})
Configure the encoder to be compatible with the bluray standard.
It is a shorthand for setting "bluray-compat=1 force-cfr=1".
Encoding ffpresets for common usages are provided so they can be used with the
general presets system (e.g. passing the @option{pre} option).
+@section libx265
+
+x265 H.265/HEVC encoder wrapper.
+
+This encoder requires the presence of the libx265 headers and library
+during configuration. You need to explicitly configure the build with
+@option{--enable-libx265}.
+
+@subsection Options
+
+@table @option
+@item preset
+Set the x265 preset.
+
+@item tune
+Set the x265 tune parameter.
+
+@item x265-params
+Set x265 options using a list of @var{key}=@var{value} couples separated
+by ":". See @command{x265 --help} for a list of options.
+
+For example to specify libx265 encoding options with @option{-x265-params}:
+
+@example
+ffmpeg -i input -c:v libx265 -x265-params crf=26:psy-rd=1 output.mp4
+@end example
+@end table
+
@section libxvid
Xvid MPEG-4 Part 2 encoder wrapper.
avpkt.size = fread(inbuf, 1, AUDIO_INBUF_SIZE, f);
while (avpkt.size > 0) {
+ int i, ch;
int got_frame = 0;
if (!decoded_frame) {
}
if (got_frame) {
/* if a frame has been decoded, output it */
- int data_size = av_samples_get_buffer_size(NULL, c->channels,
- decoded_frame->nb_samples,
- c->sample_fmt, 1);
+ int data_size = av_get_bytes_per_sample(c->sample_fmt);
if (data_size < 0) {
/* This should not occur, checking just for paranoia */
fprintf(stderr, "Failed to calculate data size\n");
exit(1);
}
- fwrite(decoded_frame->data[0], 1, data_size, outfile);
+ for (i=0; i<decoded_frame->nb_samples; i++)
+ for (ch=0; ch<c->channels; ch++)
+ fwrite(decoded_frame->data[ch] + data_size*i, 1, data_size, outfile);
}
avpkt.size -= len;
avpkt.data += len;
video_encode_example("test.h264", AV_CODEC_ID_H264);
} else if (!strcmp(output_type, "mp2")) {
audio_encode_example("test.mp2");
- audio_decode_example("test.sw", "test.mp2");
+ audio_decode_example("test.pcm", "test.mp2");
} else if (!strcmp(output_type, "mpg")) {
video_encode_example("test.mpg", AV_CODEC_ID_MPEG1VIDEO);
video_decode_example("test%02d.pgm", "test.mpg");
/** 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 we are at the end of the file, flush the decoder below. */
if (error == AVERROR_EOF)
*finished = 1;
else {
/* prepare packet for muxing */
enc_pkt.stream_index = stream_index;
- enc_pkt.dts = av_rescale_q_rnd(enc_pkt.dts,
- ofmt_ctx->streams[stream_index]->codec->time_base,
- ofmt_ctx->streams[stream_index]->time_base,
- AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);
- enc_pkt.pts = av_rescale_q_rnd(enc_pkt.pts,
- ofmt_ctx->streams[stream_index]->codec->time_base,
- ofmt_ctx->streams[stream_index]->time_base,
- AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);
- enc_pkt.duration = av_rescale_q(enc_pkt.duration,
- ofmt_ctx->streams[stream_index]->codec->time_base,
- ofmt_ctx->streams[stream_index]->time_base);
+ av_packet_rescale_ts(&enc_pkt,
+ ofmt_ctx->streams[stream_index]->codec->time_base,
+ ofmt_ctx->streams[stream_index]->time_base);
av_log(NULL, AV_LOG_DEBUG, "Muxing frame\n");
/* mux encoded frame */
ret = AVERROR(ENOMEM);
break;
}
- packet.dts = av_rescale_q_rnd(packet.dts,
- ifmt_ctx->streams[stream_index]->time_base,
- ifmt_ctx->streams[stream_index]->codec->time_base,
- AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);
- packet.pts = av_rescale_q_rnd(packet.pts,
- ifmt_ctx->streams[stream_index]->time_base,
- ifmt_ctx->streams[stream_index]->codec->time_base,
- AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);
+ av_packet_rescale_ts(&packet,
+ ifmt_ctx->streams[stream_index]->time_base,
+ ifmt_ctx->streams[stream_index]->codec->time_base);
dec_func = (type == AVMEDIA_TYPE_VIDEO) ? avcodec_decode_video2 :
avcodec_decode_audio4;
ret = dec_func(ifmt_ctx->streams[stream_index]->codec, frame,
}
} else {
/* remux this frame without reencoding */
- packet.dts = av_rescale_q_rnd(packet.dts,
- ifmt_ctx->streams[stream_index]->time_base,
- ofmt_ctx->streams[stream_index]->time_base,
- AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);
- packet.pts = av_rescale_q_rnd(packet.pts,
- ifmt_ctx->streams[stream_index]->time_base,
- ofmt_ctx->streams[stream_index]->time_base,
- AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);
+ av_packet_rescale_ts(&packet,
+ ifmt_ctx->streams[stream_index]->time_base,
+ ofmt_ctx->streams[stream_index]->time_base);
ret = av_interleaved_write_frame(ofmt_ctx, &packet);
if (ret < 0)
@end example
@item -dframes @var{number} (@emph{output})
-Set the number of data frames to record. This is an alias for @code{-frames:d}.
+Set the number of data frames to output. This is an alias for @code{-frames:d}.
@item -frames[:@var{stream_specifier}] @var{framecount} (@emph{output,per-stream})
Stop writing to the stream after @var{framecount} frames.
@table @option
@item -vframes @var{number} (@emph{output})
-Set the number of video frames to record. This is an alias for @code{-frames:v}.
+Set the number of video frames to output. This is an alias for @code{-frames:v}.
@item -r[:@var{stream_specifier}] @var{fps} (@emph{input/output,per-stream})
Set frame rate (Hz value, fraction or abbreviation).
@table @option
@item -aframes @var{number} (@emph{output})
-Set the number of audio frames to record. This is an alias for @code{-frames:a}.
+Set the number of audio frames to output. This is an alias for @code{-frames:a}.
@item -ar[:@var{stream_specifier}] @var{freq} (@emph{input/output,per-stream})
Set the audio sampling frequency. For output streams it is set by
default to the frequency of the corresponding input stream. For input
is enabled) the output timestamps may mismatch with the input
timestamps even when this option is selected.
+@item -start_at_zero
+When used with @option{copyts}, shift input timestamps so they start at zero.
+
+This means that using e.g. @code{-ss 50} will make output timestamps start at
+50 seconds, regardless of what timestamp the input file started at.
+
@item -copytb @var{mode}
Specify how to set the encoder timebase when stream copying. @var{mode} is an
integer numeric value, and can assume one of the following values:
Set frame size (WxH or abbreviation), needed for videos which do
not contain a header with the frame size like raw YUV. This option
has been deprecated in favor of private options, try -video_size.
+@item -fs
+Start in fullscreen mode.
@item -an
Disable audio.
@item -vn
Disable video.
+@item -sn
+Disable subtitles.
@item -ss @var{pos}
Seek to a given position in seconds.
@item -t @var{duration}
the audio/video synchronisation drift. It is on by default, to
explicitly disable it you need to specify @code{-nostats}.
-@item -bug
-Work around bugs.
@item -fast
Non-spec-compliant optimizations.
@item -genpts
Generate pts.
-@item -rtp_tcp
-Force RTP/TCP protocol usage instead of RTP/UDP. It is only meaningful
-if you are streaming with the RTSP protocol.
@item -sync @var{type}
Set the master clock to audio (@code{type=audio}), video
(@code{type=video}) or external (@code{type=ext}). Default is audio. The
quality broadcast) it is necessary to change that. This option is mainly
used for debugging purposes.
@item -threads @var{count}
-Set the thread count.
+Set the thread count. By default, @command{ffplay} automatically detects a
+suitable number of threads to use.
@item -ast @var{audio_stream_number}
Select the desired audio stream number, counting from 0. The number
refers to the list of all the input audio streams. If it is greater
Force a specific subtitle decoder.
@item -autorotate
-Automatically rotate the video according to presentation metadata. Set by
-default, use -noautorotate to disable.
+Automatically rotate the video according to presentation metadata. Enabled by
+default, use @option{-noautorotate} to disable it.
+
+@item -framedrop
+Drop video frames if video is out of sync. Enabled by default if the master
+clock is not set to video. Use this option to enable frame dropping for all
+master clock sources, use @option{-noframedrop} to disable it.
+
+@item -infbuf
+Do not limit the input buffer size, read as much data as possible from the
+input as soon as possible. Enabled by default for realtime streams, where data
+may be dropped if not read in time. Use this option to enable infinite buffers
+for all inputs, use @option{-noinfbuf} to disable it.
+
@end table
@section While playing
equivalent of setting both @option{-show_program_version} and
@option{-show_library_versions} options.
+@item -show_pixel_formats
+Show information about all pixel formats supported by FFmpeg.
+
+Pixel format information for each format is printed within a section
+with name "PIXEL_FORMAT".
+
@item -bitexact
Force bitexact output, useful to produce output which is not dependent
on the specific build.
<xsd:sequence>
<xsd:element name="program_version" type="ffprobe:programVersionType" minOccurs="0" maxOccurs="1" />
<xsd:element name="library_versions" type="ffprobe:libraryVersionsType" minOccurs="0" maxOccurs="1" />
+ <xsd:element name="pixel_formats" type="ffprobe:pixelFormatsType" minOccurs="0" maxOccurs="1" />
<xsd:element name="packets" type="ffprobe:packetsType" minOccurs="0" maxOccurs="1" />
<xsd:element name="frames" type="ffprobe:framesType" minOccurs="0" maxOccurs="1" />
+ <xsd:element name="packets_and_frames" type="ffprobe:packetsAndFramesType" minOccurs="0" maxOccurs="1" />
<xsd:element name="programs" type="ffprobe:programsType" minOccurs="0" maxOccurs="1" />
<xsd:element name="streams" type="ffprobe:streamsType" minOccurs="0" maxOccurs="1" />
<xsd:element name="chapters" type="ffprobe:chaptersType" minOccurs="0" maxOccurs="1" />
</xsd:sequence>
</xsd:complexType>
+ <xsd:complexType name="packetsAndFramesType">
+ <xsd:sequence>
+ <xsd:choice minOccurs="0" maxOccurs="unbounded">
+ <xsd:element name="packet" type="ffprobe:packetType" 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>
+
<xsd:complexType name="packetType">
<xsd:attribute name="codec_type" type="xsd:string" use="required" />
<xsd:attribute name="stream_index" type="xsd:int" use="required" />
<xsd:attribute name="level" type="xsd:int"/>
<xsd:attribute name="color_range" type="xsd:string"/>
<xsd:attribute name="color_space" type="xsd:string"/>
+ <xsd:attribute name="color_transfer" type="xsd:string"/>
+ <xsd:attribute name="color_primaries" type="xsd:string"/>
+ <xsd:attribute name="chroma_location" type="xsd:string"/>
<xsd:attribute name="timecode" type="xsd:string"/>
<!-- audio attributes -->
<xsd:element name="library_version" type="ffprobe:libraryVersionType" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
+
+ <xsd:complexType name="pixelFormatFlagsType">
+ <xsd:attribute name="big_endian" type="xsd:int" use="required"/>
+ <xsd:attribute name="palette" type="xsd:int" use="required"/>
+ <xsd:attribute name="bitstream" type="xsd:int" use="required"/>
+ <xsd:attribute name="hwaccel" type="xsd:int" use="required"/>
+ <xsd:attribute name="planar" type="xsd:int" use="required"/>
+ <xsd:attribute name="rgb" type="xsd:int" use="required"/>
+ <xsd:attribute name="pseudopal" type="xsd:int" use="required"/>
+ <xsd:attribute name="alpha" type="xsd:int" use="required"/>
+ </xsd:complexType>
+
+ <xsd:complexType name="pixelFormatComponentType">
+ <xsd:attribute name="index" type="xsd:int" use="required"/>
+ <xsd:attribute name="bit_depth" type="xsd:int" use="required"/>
+ </xsd:complexType>
+
+ <xsd:complexType name="pixelFormatComponentsType">
+ <xsd:sequence>
+ <xsd:element name="component" type="ffprobe:pixelFormatComponentType" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="pixelFormatType">
+ <xsd:sequence>
+ <xsd:element name="flags" type="ffprobe:pixelFormatFlagsType" minOccurs="0" maxOccurs="1"/>
+ <xsd:element name="components" type="ffprobe:pixelFormatComponentsType" minOccurs="0" maxOccurs="1"/>
+ </xsd:sequence>
+
+ <xsd:attribute name="name" type="xsd:string" use="required"/>
+ <xsd:attribute name="nb_components" type="xsd:int" use="required"/>
+ <xsd:attribute name="log2_chroma_w" type="xsd:int"/>
+ <xsd:attribute name="log2_chroma_h" type="xsd:int"/>
+ <xsd:attribute name="bits_per_pixel" type="xsd:int"/>
+ </xsd:complexType>
+
+ <xsd:complexType name="pixelFormatsType">
+ <xsd:sequence>
+ <xsd:element name="pixel_format" type="ffprobe:pixelFormatType" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:complexType>
</xsd:schema>
Set no-daemon mode. This option is currently ignored since now
@command{ffserver} will always work in no-daemon mode, and is
deprecated.
+
+@item UseDefaults
+@item NoDefaults
+Control whether default codec options are used for the all streams or not.
+Each stream may overwrite this setting for its own. Default is @var{UseDefaults}.
+The lastest occurrence overrides previous if multiple definitions.
@end table
@section Feed section
@item Metadata @var{key} @var{value}
Set metadata value on the output stream.
+@item UseDefaults
+@item NoDefaults
+Control whether default codec options are used for the stream or not.
+Default is @var{UseDefaults} unless disabled globally.
+
@item NoAudio
@item NoVideo
Suppress audio/video.
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 AVOptionAudio [@var{codec}:]@var{option} @var{value} (@emph{encoding,audio})
+Set generic or private option for audio stream.
+Private option must be prefixed with codec name or codec must be defined before.
@item AVPresetAudio @var{preset} (@emph{encoding,audio})
Set preset for audio stream.
@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 AVOptionVideo [@var{codec}:]@var{option} @var{value} (@emph{encoding,video})
+Set generic or private option for video stream.
+Private option must be prefixed with codec name or codec must be defined before.
@item AVPresetVideo @var{preset} (@emph{encoding,video})
Set preset for video stream.
Show version.
@item -formats
-Show available formats.
+Show available formats (including devices).
+
+@item -devices
+Show available devices.
@item -codecs
Show all codecs known to libavcodec.
@item -colors
Show recognized color names.
+@item -sources @var{device}[,@var{opt1}=@var{val1}[,@var{opt2}=@var{val2}]...]
+Show autodetected sources of the intput device.
+Some devices may provide system-dependent source names that cannot be autodetected.
+The returned list cannot be assumed to be always complete.
+@example
+ffmpeg -sources pulse,server=192.168.0.4
+@end example
+
+@item -sinks @var{device}[,@var{opt1}=@var{val1}[,@var{opt2}=@var{val2}]...]
+Show autodetected sinks of the output device.
+Some devices may provide system-dependent sink names that cannot be autodetected.
+The returned list cannot be assumed to be always complete.
+@example
+ffmpeg -sinks pulse,server=192.168.0.4
+@end example
+
@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
@item pos
the position in the file of the input frame, NAN if unknown
+
+@item w
+@item h
+width and height of the input frame if video
@end table
Additionally, these filters support an @option{enable} command that can be used
Below is a description of the currently available audio filters.
-@section aconvert
-
-Convert the input audio format to the specified formats.
-
-@emph{This filter is deprecated. Use @ref{aformat} instead.}
-
-The filter accepts a string of the form:
-"@var{sample_format}:@var{channel_layout}".
-
-@var{sample_format} specifies the sample format, and can be a string or the
-corresponding numeric value defined in @file{libavutil/samplefmt.h}. Use 'p'
-suffix for a planar sample format.
-
-@var{channel_layout} specifies the channel layout, and can be a string
-or the corresponding number value defined in @file{libavutil/channel_layout.h}.
-
-The special parameter "auto", signifies that the filter will
-automatically select the output format depending on the output filter.
-
-@subsection Examples
-
-@itemize
-@item
-Convert input to float, planar, stereo:
-@example
-aconvert=fltp:stereo
-@end example
-
-@item
-Convert input to unsigned 8-bit, automatically select out channel layout:
-@example
-aconvert=u8:auto
-@end example
-@end itemize
-
@section adelay
Delay one or more audio channels.
Mix channels with specific gain levels. The filter accepts the output
channel layout followed by a set of channels definitions.
-This filter is also designed to remap efficiently the channels of an audio
+This filter is also designed to efficiently remap the channels of an audio
stream.
The filter accepts parameters of the form:
-"@var{l}:@var{outdef}:@var{outdef}:..."
+"@var{l}|@var{outdef}|@var{outdef}|..."
@table @option
@item l
For example, if you want to down-mix from stereo to mono, but with a bigger
factor for the left channel:
@example
-pan=1:c0=0.9*c0+0.1*c1
+pan=1c|c0=0.9*c0+0.1*c1
@end example
A customized down-mix to stereo that works automatically for 3-, 4-, 5- and
7-channels surround:
@example
-pan=stereo: FL < FL + 0.5*FC + 0.6*BL + 0.6*SL : FR < FR + 0.5*FC + 0.6*BR + 0.6*SR
+pan=stereo| FL < FL + 0.5*FC + 0.6*BL + 0.6*SL | FR < FR + 0.5*FC + 0.6*BR + 0.6*SR
@end example
Note that @command{ffmpeg} integrates a default down-mix (and up-mix) system
For example, if you have a 5.1 source and want a stereo audio stream by
dropping the extra channels:
@example
-pan="stereo: c0=FL : c1=FR"
+pan="stereo| c0=FL | c1=FR"
@end example
Given the same source, you can also switch front left and front right channels
and keep the input channel layout:
@example
-pan="5.1: c0=c1 : c1=c0 : c2=c2 : c3=c3 : c4=c4 : c5=c5"
+pan="5.1| c0=c1 | c1=c0 | c2=c2 | c3=c3 | c4=c4 | c5=c5"
@end example
If the input is a stereo audio stream, you can mute the front left channel (and
still keep the stereo channel layout) with:
@example
-pan="stereo:c1=c1"
+pan="stereo|c1=c1"
@end example
Still with a stereo audio stream input, you can copy the right channel in both
front left and right:
@example
-pan="stereo: c0=FR : c1=FR"
+pan="stereo| c0=FR | c1=FR"
@end example
@section replaygain
and libavformat to work. On the other hand, it is limited to ASS (Advanced
Substation Alpha) subtitles files.
+This filter accepts the following option in addition to the common options from
+the @ref{subtitles} filter:
+
+@table @option
+@item shaping
+Set the shaping engine
+
+Available values are:
+@table @samp
+@item auto
+The default libass shaping engine, which is the best available.
+@item simple
+Fast, font-agnostic shaper that can do only substitutions
+@item complex
+Slower shaper using OpenType for substitutions and positioning
+@end table
+
+The default is @code{auto}.
+@end table
+
@section bbox
Compute the bounding box for the non-black pixels in the input frame
@item
Print the date of a real-time encoding (see strftime(3)):
@example
-drawtext='fontfile=FreeSans.ttf:text=%@{localtime:%a %b %d %Y@}'
+drawtext='fontfile=FreeSans.ttf:text=%@{localtime\:%a %b %d %Y@}'
@end example
@item
which @code{fieldmatch} is based on. While the semantic and usage are very
close, some behaviour and options names can differ.
+The @ref{decimate} filter currently only works for constant frame rate input.
+Do not use @code{fieldmatch} and @ref{decimate} if your input has mixed
+telecined and progressive content with changing framerate.
+
The filter accepts the following options:
@table @option
@example
geq=r='X/W*r(X,Y)':g='(1-X/W)*g(X,Y)':b='(H-Y)/H*b(X,Y)'
@end example
+
+@item
+Create a radial gradient that is the same size as the input (also see
+the @ref{vignette} filter):
+@example
+geq=lum=255*gauss((X/W-0.5)*3)*gauss((Y/H-0.5)*3)/gauss(0)/gauss(0),format=gray
+@end example
+
+@item
+Create a linear gradient to use as a mask for another filter, then
+compose with @ref{overlay}. In this example the video will gradually
+become more blurry from the top to the bottom of the y-axis as defined
+by the linear gradient:
+@example
+ffmpeg -i input.mp4 -filter_complex "geq=lum=255*(Y/H),format=gray[grad];[0:v]boxblur=4[blur];[blur][grad]alphamerge[alpha];[0:v][alpha]overlay" output.mp4
+@end example
@end itemize
@section gradfun
Detect video interlacing type.
-This filter tries to detect if the input is interlaced or progressive,
-top or bottom field first.
+This filter tries to detect if the input frames as interlaced, progressive,
+top or bottom field first. It will also try and detect fields that are
+repeated between adjacent frames (a sign of telecine).
+
+Single frame detection considers only immediately adjacent frames when classifying each frame.
+Multiple frame detection incorporates the classification history of previous frames.
+
+The filter will log these metadata values:
+
+@table @option
+@item single.current_frame
+Detected type of current frame using single-frame detection. One of:
+``tff'' (top field first), ``bff'' (bottom field first),
+``progressive'', or ``undetermined''
+
+@item single.tff
+Cumulative number of frames detected as top field first using single-frame detection.
+
+@item multiple.tff
+Cumulative number of frames detected as top field first using multiple-frame detection.
+
+@item single.bff
+Cumulative number of frames detected as bottom field first using single-frame detection.
+
+@item multiple.current_frame
+Detected type of current frame using multiple-frame detection. One of:
+``tff'' (top field first), ``bff'' (bottom field first),
+``progressive'', or ``undetermined''
+
+@item multiple.bff
+Cumulative number of frames detected as bottom field first using multiple-frame detection.
+
+@item single.progressive
+Cumulative number of frames detected as progressive using single-frame detection.
+
+@item multiple.progressive
+Cumulative number of frames detected as progressive using multiple-frame detection.
+
+@item single.undetermined
+Cumulative number of frames that could not be classified using single-frame detection.
+
+@item multiple.undetermined
+Cumulative number of frames that could not be classified using multiple-frame detection.
+
+@item repeated.current_frame
+Which field in the current frame is repeated from the last. One of ``neither'', ``top'', or ``bottom''.
+
+@item repeated.neither
+Cumulative number of frames with no repeated field.
+
+@item repeated.top
+Cumulative number of frames with the top field repeated from the previous frame's top field.
+
+@item repeated.bottom
+Cumulative number of frames with the bottom field repeated from the previous frame's bottom field.
+@end table
The filter accepts the following options:
Set interlacing threshold.
@item prog_thres
Set progressive threshold.
+@item repeat_thres
+Threshold for repeated field detection.
+@item half_life
+Number of frames after which a given frame's contribution to the
+statistics is halved (i.e., it contributes only 0.5 to it's
+classification). The default of 0 means that all frames seen are given
+full weight of 1.0 forever.
@end table
@section il
Refer to the official libopencv documentation for more precise
information:
-@url{http://opencv.willowgarage.com/documentation/c/image_filtering.html}
+@url{http://docs.opencv.org/master/modules/imgproc/doc/filtering.html}
Several libopencv filters are supported; see the following subsections.
@item y3
Set coordinates expression for top left, top right, bottom left and bottom right corners.
Default values are @code{0:0:W:0:0:H:W:H} with which perspective will remain unchanged.
+If the @code{sense} option is set to @code{source}, then the specified points will be sent
+to the corners of the destination. If the @code{sense} option is set to @code{destination},
+then the corners of the source will be sent to the specified coordinates.
The expressions can use the following variables:
@end table
Default value is @samp{linear}.
+
+@item sense
+Set interpretation of coordinate options.
+
+It accepts the following values:
+@table @samp
+@item 0, source
+
+Send point in the source specified by the given coordinates to
+the corners of the destination.
+
+@item 1, destination
+
+Send the corners of the source to the point in the destination specified
+by the given coordinates.
+
+Default value is @samp{source}.
+@end table
@end table
@section phase
@end itemize
+@anchor{unsharp}
@section unsharp
Sharpen or blur the input video.
apply/compensate them. Together with the @ref{vidstabdetect}
filter this can be used to deshake videos. See also
@url{http://public.hronopik.de/vid.stab}. It is important to also use
-the unsharp filter, see below.
+the @ref{unsharp} filter, see below.
To enable compilation of this filter you need to configure FFmpeg with
@code{--enable-libvidstab}.
@table @option
@item input
Set path to the file used to read the transforms. Default value is
-@file{transforms.trf}).
+@file{transforms.trf}.
@item smoothing
Set the number of frames (value*2 + 1) used for lowpass filtering the
For example a number of 10 means that 21 frames are used (10 in the
past and 10 in the future) to smoothen the motion in the video. A
-larger values leads to a smoother video, but limits the acceleration
-of the camera (pan/tilt movements). 0 is a special case where a
-static camera is simulated.
+larger value leads to a smoother video, but limits the acceleration of
+the camera (pan/tilt movements). 0 is a special case where a static
+camera is simulated.
@item optalgo
Set the camera path optimization algorithm.
Invert transforms if set to 1. Default value is 0.
@item relative
-Consider transforms as relative to previsou frame if set to 1,
+Consider transforms as relative to previous frame if set to 1,
absolute if set to 0. Default value is 0.
@item zoom
ffmpeg -i inp.mpeg -vf vidstabtransform,unsharp=5:5:0.8:3:3:0.4 inp_stabilized.mpeg
@end example
-Note the use of the unsharp filter which is always recommended.
+Note the use of the @ref{unsharp} filter which is always recommended.
@item
Zoom in a bit more and load transform data from a given file:
Default value is @samp{all}.
@end table
+@section xbr
+Apply the xBR high-quality magnification filter which is designed for pixel
+art. It follows a set of edge-detection rules, see
+@url{http://www.libretro.com/forums/viewtopic.php?f=6&t=134}.
+
+It accepts the following option:
+
+@table @option
+@item n
+Set the scaling dimension: @code{2} for @code{2xBR}, @code{3} for
+@code{3xBR} and @code{4} for @code{4xBR}.
+Default is @code{3}.
+@end table
+
@anchor{yadif}
@section yadif
Enable RTP MP4A-LATM payload.
@item nobuffer
Reduce the latency introduced by optional buffering
+@item bitexact
+Only write platform-, build- and time-independent data.
+This ensures that file and data checksums are reproducible and match between
+platforms. Its primary use is for regression testing.
@end table
@item seek2any @var{integer} (@emph{input})
Specifying a positive offset means that the corresponding streams are
delayed bt the time duration specified in @var{offset}. Default value
is @code{0} (meaning that no offset is applied).
+
+@item format_whitelist @var{list} (@emph{input})
+"," separated List of allowed demuxers. By default all are allowed.
+
+@item dump_separator @var{string} (@emph{input})
+Separator used to separate the fields printed on the command line about the
+Stream parameters.
+For example to separate the fields with newlines and indention:
+@example
+ffprobe -dump_separator "
+ " -i ~/videos/matrixbench_mpeg2.mpg
+@end example
@end table
@c man end FORMAT OPTIONS
@item Sony Wave64 (W64) @tab X @tab X
@item SoX native format @tab X @tab X
@item SUN AU format @tab X @tab X
+@item SUP raw PGS subtitles @tab @tab X
@item Text files @tab @tab X
@item THP @tab @tab X
@tab Used on the Nintendo GameCube.
@item PJS (Phoenix) @tab @tab X @tab @tab X
@item RealText @tab @tab X @tab @tab X
@item SAMI @tab @tab X @tab @tab X
+@item Spruce format (STL) @tab @tab X @tab @tab X
@item SSA/ASS @tab X @tab X @tab X @tab X
@item SubRip (SRT) @tab X @tab X @tab X @tab X
@item SubViewer v1 @tab @tab X @tab @tab X
AVFoundation is the currently recommended framework by Apple for streamgrabbing on OSX >= 10.7 as well as on iOS.
The older QTKit framework has been marked deprecated since OSX version 10.7.
-The filename passed as input is parsed to contain either a device name or index.
-The device index can also be given by using -video_device_index.
-A given device index will override any given device name.
-If the desired device consists of numbers only, use -video_device_index to identify it.
-The default device will be chosen if an empty string or the device name "default" is given.
-The available devices can be enumerated by using -list_devices.
-The pixel format can be set using -pixel_format.
-Available formats:
- monob, rgb555be, rgb555le, rgb565be, rgb565le, rgb24, bgr24, 0rgb, bgr0, 0bgr, rgb0,
+The input filename has to be given in the following syntax:
+@example
+-i "[[VIDEO]:[AUDIO]]"
+@end example
+The first entry selects the video input while the latter selects the audio input.
+The stream has to be specified by the device name or the device index as shown by the device list.
+Alternatively, the video and/or audio input device can be chosen by index using the
+@option{
+ -video_device_index <INDEX>
+}
+and/or
+@option{
+ -audio_device_index <INDEX>
+}
+, overriding any
+device name or index given in the input filename.
+
+All available devices can be enumerated by using @option{-list_devices true}, listing
+all device names and corresponding indices.
+
+There are two device name aliases:
+@table @code
+
+@item default
+Select the AVFoundation default device of the corresponding type.
+
+@item none
+Do not record the corresponding media type.
+This is equivalent to specifying an empty device name or index.
+
+@end table
+
+@subsection Options
+
+AVFoundation supports the following options:
+
+@table @option
+
+@item -list_devices <TRUE|FALSE>
+If set to true, a list of all available input devices is given showing all
+device names and indices.
+
+@item -video_device_index <INDEX>
+Specify the video device by its index. Overrides anything given in the input filename.
+
+@item -audio_device_index <INDEX>
+Specify the audio device by its index. Overrides anything given in the input filename.
+
+@item -pixel_format <FORMAT>
+Request the video device to use a specific pixel format.
+If the specified format is not supported, a list of available formats is given
+und the first one in this list is used instead. Available pixel formats are:
+@code{monob, rgb555be, rgb555le, rgb565be, rgb565le, rgb24, bgr24, 0rgb, bgr0, 0bgr, rgb0,
bgr48be, uyvy422, yuva444p, yuva444p16le, yuv444p, yuv422p16, yuv422p10, yuv444p10,
- yuv420p, nv12, yuyv422, gray
+ yuv420p, nv12, yuyv422, gray}
+@end table
+
+@subsection Examples
+
+@itemize
+
+@item
+Print the list of AVFoundation supported devices and exit:
@example
-ffmpeg -f avfoundation -i "0" out.mpg
+$ ffmpeg -f avfoundation -list_devices true -i ""
@end example
+@item
+Record video from video device 0 and audio from audio device 0 into out.avi:
@example
-ffmpeg -f avfoundation -video_device_index 0 -i "" out.mpg
+$ ffmpeg -f avfoundation -i "0:0" out.avi
@end example
+@item
+Record video from video device 2 and audio from audio device 1 into out.avi:
@example
-ffmpeg -f avfoundation -pixel_format bgr0 -i "default" out.mpg
+$ ffmpeg -f avfoundation -video_device_index 2 -i ":1" out.avi
@end example
+@item
+Record video from the system default video device using the pixel format bgr0 and do not record any audio into out.avi:
@example
-ffmpeg -f avfoundation -list_devices true -i ""
+$ ffmpeg -f avfoundation -pixel_format bgr0 -i "default:none" out.avi
@end example
+@end itemize
+
@section bktr
BSD video input device.
It may be necessary to disable it for remote displays.
@end table
+@section decklink
+
+The decklink input device provides capture capabilities for Blackmagic
+DeckLink devices.
+
+To enable this input device, you need the Blackmagic DeckLink SDK and you
+need to configure with the appropriate @code{--extra-cflags}
+and @code{--extra-ldflags}.
+On Windows, you need to run the IDL files through @command{widl}.
+
+DeckLink is very picky about the formats it supports. Pixel format is always
+uyvy422, framerate and video size must be determined for your device with
+@command{-list_formats 1}. Audio sample rate is always 48 kHz and the number
+of channels currently is limited to 2 (stereo).
+
+@subsection Options
+
+@table @option
+
+@item list_devices
+If set to @option{true}, print a list of devices and exit.
+Defaults to @option{false}.
+
+@item list_formats
+If set to @option{true}, print a list of supported formats and exit.
+Defaults to @option{false}.
+
+@end table
+
+@subsection Examples
+
+@itemize
+
+@item
+List input devices:
+@example
+ffmpeg -f decklink -list_devices 1 -i dummy
+@end example
+
+@item
+List supported formats:
+@example
+ffmpeg -f decklink -list_formats 1 -i 'Intensity Pro'
+@end example
+
+@item
+Capture video clip at 1080i50 (format 11):
+@example
+ffmpeg -f decklink -i 'Intensity Pro@@11' -acodec copy -vcodec copy output.avi
+@end example
+
+@end itemize
+
+
@c man end INPUT DEVICES
Apple HTTP Live Streaming muxer that segments MPEG-TS according to
the HTTP Live Streaming (HLS) specification.
-It creates a playlist file and numbered segment files. The output
-filename specifies the playlist filename; the segment filenames
-receive the same basename as the playlist, a sequential number and
-a .ts extension.
+It creates a playlist file, and one or more segment files. The output filename
+specifies the playlist filename.
+
+By default, the muxer creates a file for each segment produced. These files
+have the same name as the playlist, followed by a sequential number and a
+.ts extension.
For example, to convert an input file with @command{ffmpeg}:
@example
ffmpeg -i in.nut out.m3u8
@end example
+This example will produce the playlist, @file{out.m3u8}, and segment files:
+@file{out0.ts}, @file{out1.ts}, @file{out2.ts}, etc.
See also the @ref{segment} muxer, which provides a more generic and
flexible implementation of a segmenter, and can be used to perform HLS
Set the maximum number of playlist entries. If set to 0 the list file
will contain all the segments. Default value is 5.
+@item hls_ts_options @var{options_list}
+Set output format options using a :-separated list of key=value
+parameters. Values containing @code{:} special characters must be
+escaped.
+
@item hls_wrap @var{wrap}
Set the number after which the segment filename number (the number
specified in each segment file) wraps. If set to 0 the number will be
Start the playlist sequence number from @var{number}. Default value is
0.
+@item hls_allow_cache @var{allowcache}
+Explicitly set whether the client MAY (1) or MUST NOT (0) cache media segments.
+
@item hls_base_url @var{baseurl}
Append @var{baseurl} to every entry in the playlist.
Useful to generate playlists with absolute paths.
and it is not to be confused with the segment filename sequence number
which can be cyclic, for example if the @option{wrap} option is
specified.
+
+@item hls_flags single_file
+If this flag is set, the muxer will store all segments in a single MPEG-TS
+file, and will use byte ranges in the playlist. HLS playlists generated with
+this way will have the version number 4.
+For example:
+@example
+ffmpeg -i in.nut -hls_flags single_file out.m3u8
+@end example
+Will produce the playlist, @file{out.m3u8}, and a single segment file,
+@file{out.ts}.
@end table
@anchor{ico}
mdat atom, and the moov atom only describes the tracks but has
a zero duration.
-Files written with this option set do not work in QuickTime.
This option is implicitly set when writing ismv (Smooth Streaming) files.
@item -movflags separate_moof
Write a separate moof (movie fragment) atom for each track. Normally,
set, only the QuickTime chapter track will be written. Nero chapters can
cause failures when the file is reprocessed with certain tagging programs, like
mp3Tag 2.61a and iTunes 11.3, most likely other versions are affected as well.
+@item -movflags omit_tfhd_offset
+Do not write any absolute base_data_offset in tfhd atoms. This avoids
+tying fragments to absolute byte positions in the file/streams.
+@item -movflags default_base_moof
+Similarly to the omit_tfhd_offset, this flag avoids writing the
+absolute base_data_offset field in tfhd atoms, but does so by using
+the new default-base-is-moof flag instead. This flag is new from
+14496-12:2012. This may make the fragments easier to parse in certain
+circumstances (avoiding basing track fragment location calculations
+on the implicit end of the previous track fragment).
@end table
@subsection Example
@section mp3
-The MP3 muxer writes a raw MP3 stream with an ID3v2 header at the beginning and
-optionally an ID3v1 tag at the end. ID3v2.3 and ID3v2.4 are supported, the
-@code{id3v2_version} option controls which one is used. Setting
-@code{id3v2_version} to 0 will disable the ID3v2 header completely. The legacy
-ID3v1 tag is not written by default, but may be enabled with the
-@code{write_id3v1} option.
-
-The muxer may also write a Xing frame at the beginning, which contains the
-number of frames in the file. It is useful for computing duration of VBR files.
-The Xing frame is written if the output stream is seekable and if the
-@code{write_xing} option is set to 1 (the default).
-
-The muxer supports writing ID3v2 attached pictures (APIC frames). The pictures
-are supplied to the muxer in form of a video stream with a single packet. There
-can be any number of those streams, each will correspond to a single APIC frame.
-The stream metadata tags @var{title} and @var{comment} map to APIC
-@var{description} and @var{picture type} respectively. See
+The MP3 muxer writes a raw MP3 stream with the following optional features:
+@itemize @bullet
+@item
+An ID3v2 metadata header at the beginning (enabled by default). Versions 2.3 and
+2.4 are supported, the @code{id3v2_version} private option controls which one is
+used (3 or 4). Setting @code{id3v2_version} to 0 disables the ID3v2 header
+completely.
+
+The muxer supports writing attached pictures (APIC frames) to the ID3v2 header.
+The pictures are supplied to the muxer in form of a video stream with a single
+packet. There can be any number of those streams, each will correspond to a
+single APIC frame. The stream metadata tags @var{title} and @var{comment} map
+to APIC @var{description} and @var{picture type} respectively. See
@url{http://id3.org/id3v2.4.0-frames} for allowed picture types.
Note that the APIC frames must be written at the beginning, so the muxer will
buffer the audio frames until it gets all the pictures. It is therefore advised
to provide the pictures as soon as possible to avoid excessive buffering.
+@item
+A Xing/LAME frame right after the ID3v2 header (if present). It is enabled by
+default, but will be written only if the output is seekable. The
+@code{write_xing} private option can be used to disable it. The frame contains
+various information that may be useful to the decoder, like the audio duration
+or encoder delay.
+
+@item
+A legacy ID3v1 tag at the end of the file (disabled by default). It may be
+enabled with the @code{write_id3v1} private option, but as its capabilities are
+very limited, its usage is not recommended.
+@end itemize
+
Examples:
Write an mp3 with an ID3v2.3 header and an ID3v1 footer:
#include <string.h>
#include <float.h>
+// print_options is build for the host, os_support.h isn't needed and is setup
+// for the target. without this build breaks on mingw
+#define AVFORMAT_OS_SUPPORT_H
+
#include "libavformat/avformat.h"
#include "libavformat/options_table.h"
#include "libavcodec/avcodec.h"
@item
If @option{localrtcpport} (the local RTCP port) is not set it will be
-set to the the local RTP port value plus 1.
+set to the local RTP port value plus 1.
@end enumerate
@section rtsp
# 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.
+# General Public License for more details.
#
-# You should have received a copy of the GNU Lesser General Public
+# 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
similar filter. We'll pick edgedetect, but any other should do. You can look
for others using the `./ffmpeg -v 0 -filters|grep ' V->V '` command.
- - cp libavfilter/vf_{edgedetect,foobar}.c
- - sed -i s/edgedetect/foobar/g -i libavfilter/vf_foobar.c
- - sed -i s/EdgeDetect/Foobar/g -i libavfilter/vf_foobar.c
+ - sed 's/edgedetect/foobar/g;s/EdgeDetect/Foobar/g' libavfilter/vf_edgedetect.c > libavfilter/vf_foobar.c
- edit libavfilter/Makefile, and add an entry for "foobar" following the
pattern of the other filters.
- edit libavfilter/allfilters.c, and add an entry for "foobar" following the
pattern of the other filters.
- ./configure ...
- make -j<whatever> ffmpeg
- - ./ffmpeg -i tests/lena.pnm -vf foobar foobar.png
+ - ./ffmpeg -i http://samples.ffmpeg.org/image-samples/lena.pnm -vf foobar foobar.png
+ Note here: you can obviously use a random local image instead of a remote URL.
If everything went right, you should get a foobar.png with Lena edge-detected.
}
ost->bitstream_filters = NULL;
av_frame_free(&ost->filtered_frame);
+ av_frame_free(&ost->last_frame);
av_parser_close(ost->parser);
while (bsfc) {
AVPacket new_pkt = *pkt;
- int a = av_bitstream_filter_filter(bsfc, avctx, NULL,
+ AVDictionaryEntry *bsf_arg = av_dict_get(ost->bsf_args,
+ bsfc->filter->name,
+ NULL, 0);
+ int a = av_bitstream_filter_filter(bsfc, avctx,
+ bsf_arg ? bsf_arg->value : NULL,
&new_pkt.data, &new_pkt.size,
pkt->data, pkt->size,
pkt->flags & AV_PKT_FLAG_KEY);
}
if (!(s->oformat->flags & AVFMT_NOTIMESTAMPS)) {
+ if (pkt->dts != AV_NOPTS_VALUE &&
+ pkt->pts != AV_NOPTS_VALUE &&
+ pkt->dts > pkt->pts) {
+ av_log(s, AV_LOG_WARNING, "Invalid DTS: %"PRId64" PTS: %"PRId64" in output stream %d:%d, replacing by guess\n",
+ pkt->dts, pkt->pts,
+ ost->file_index, ost->st->index);
+ pkt->pts =
+ pkt->dts = pkt->pts + pkt->dts + ost->last_mux_dts + 1
+ - FFMIN3(pkt->pts, pkt->dts, ost->last_mux_dts + 1)
+ - FFMAX3(pkt->pts, pkt->dts, ost->last_mux_dts + 1);
+ }
if(
(avctx->codec_type == AVMEDIA_TYPE_AUDIO || avctx->codec_type == AVMEDIA_TYPE_VIDEO) &&
pkt->dts != AV_NOPTS_VALUE &&
pkt->dts = max;
}
}
- if (pkt->dts != AV_NOPTS_VALUE &&
- pkt->pts != AV_NOPTS_VALUE &&
- pkt->dts > pkt->pts) {
- av_log(s, AV_LOG_WARNING, "Invalid DTS: %"PRId64" PTS: %"PRId64" in output stream %d:%d\n",
- pkt->dts, pkt->pts,
- ost->file_index, ost->st->index);
- pkt->pts = AV_NOPTS_VALUE;
- pkt->dts = AV_NOPTS_VALUE;
- }
}
ost->last_mux_dts = pkt->dts;
static void do_video_out(AVFormatContext *s,
OutputStream *ost,
- AVFrame *in_picture)
+ AVFrame *next_picture)
{
int ret, format_video_sync;
AVPacket pkt;
AVCodecContext *enc = ost->enc_ctx;
AVCodecContext *mux_enc = ost->st->codec;
- int nb_frames, i;
- double sync_ipts, delta;
+ int nb_frames, nb0_frames, i;
+ double sync_ipts, delta, delta0;
double duration = 0;
int frame_size = 0;
InputStream *ist = NULL;
if(ist && ist->st->start_time != AV_NOPTS_VALUE && ist->st->first_dts != AV_NOPTS_VALUE && ost->frame_rate.num)
duration = 1/(av_q2d(ost->frame_rate) * av_q2d(enc->time_base));
- sync_ipts = in_picture->pts;
- delta = sync_ipts - ost->sync_opts + duration;
+ if (!ost->filters_script &&
+ !ost->filters &&
+ next_picture &&
+ ist &&
+ lrintf(av_frame_get_pkt_duration(next_picture) * av_q2d(ist->st->time_base) / av_q2d(enc->time_base)) > 0) {
+ duration = lrintf(av_frame_get_pkt_duration(next_picture) * av_q2d(ist->st->time_base) / av_q2d(enc->time_base));
+ }
+
+ sync_ipts = next_picture->pts;
+ delta0 = sync_ipts - ost->sync_opts;
+ delta = delta0 + duration;
/* by default, we output a single frame */
+ nb0_frames = 0;
nb_frames = 1;
format_video_sync = video_sync_method;
}
}
+ if (delta0 < 0 &&
+ delta > 0 &&
+ format_video_sync != VSYNC_PASSTHROUGH &&
+ format_video_sync != VSYNC_DROP) {
+ double cor = FFMIN(-delta0, duration);
+ av_log(NULL, AV_LOG_WARNING, "Past duration %f too large\n", -delta0);
+ sync_ipts += cor;
+ duration -= cor;
+ delta0 += cor;
+ }
+
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;
+ delta0 = 0;
ost->sync_opts = lrint(sync_ipts);
}
case VSYNC_CFR:
// FIXME set to 0.5 after we fix some dts/pts bugs like in avidec.c
if (delta < -1.1)
nb_frames = 0;
- else if (delta > 1.1)
+ else if (delta > 1.1) {
nb_frames = lrintf(delta);
+ if (delta0 > 1.1)
+ nb0_frames = lrintf(delta0 - 0.6);
+ }
break;
case VSYNC_VFR:
if (delta <= -0.6)
}
nb_frames = FFMIN(nb_frames, ost->max_frames - ost->frame_number);
- if (nb_frames == 0) {
+ nb0_frames = FFMIN(nb0_frames, nb_frames);
+ if (nb0_frames == 0 && ost->last_droped) {
nb_frames_drop++;
av_log(NULL, AV_LOG_VERBOSE,
"*** dropping frame %d from stream %d at ts %"PRId64"\n",
- ost->frame_number, ost->st->index, in_picture->pts);
- return;
- } else if (nb_frames > 1) {
+ ost->frame_number, ost->st->index, ost->last_frame->pts);
+ }
+ if (nb_frames > (nb0_frames && ost->last_droped) + (nb_frames > nb0_frames)) {
if (nb_frames > dts_error_threshold * 30) {
av_log(NULL, AV_LOG_ERROR, "%d frame duplication too large, skipping\n", nb_frames - 1);
nb_frames_drop++;
return;
}
- nb_frames_dup += nb_frames - 1;
+ nb_frames_dup += nb_frames - (nb0_frames && ost->last_droped) - (nb_frames > nb0_frames);
av_log(NULL, AV_LOG_VERBOSE, "*** %d dup!\n", nb_frames - 1);
}
+ ost->last_droped = nb_frames == nb0_frames;
/* duplicates frame if needed */
for (i = 0; i < nb_frames; i++) {
+ AVFrame *in_picture;
av_init_packet(&pkt);
pkt.data = NULL;
pkt.size = 0;
+ if (i < nb0_frames && ost->last_frame) {
+ in_picture = ost->last_frame;
+ } else
+ in_picture = next_picture;
+
in_picture->pts = ost->sync_opts;
#if 1
/* raw pictures are written as AVPicture structure to
avoid any copies. We support temporarily the older
method. */
- mux_enc->coded_frame->interlaced_frame = in_picture->interlaced_frame;
- mux_enc->coded_frame->top_field_first = in_picture->top_field_first;
- if (mux_enc->coded_frame->interlaced_frame)
- mux_enc->field_order = mux_enc->coded_frame->top_field_first ? AV_FIELD_TB:AV_FIELD_BT;
+ if (in_picture->interlaced_frame)
+ mux_enc->field_order = in_picture->top_field_first ? AV_FIELD_TB:AV_FIELD_BT;
else
mux_enc->field_order = AV_FIELD_PROGRESSIVE;
pkt.data = (uint8_t *)in_picture;
mux_enc->field_order = AV_FIELD_PROGRESSIVE;
in_picture->quality = enc->global_quality;
- if (!enc->me_threshold)
- in_picture->pict_type = 0;
+ in_picture->pict_type = 0;
pts_time = in_picture->pts != AV_NOPTS_VALUE ?
in_picture->pts * av_q2d(enc->time_base) : NAN;
if (vstats_filename && frame_size)
do_video_stats(ost, frame_size);
}
+
+ if (!ost->last_frame)
+ ost->last_frame = av_frame_alloc();
+ av_frame_unref(ost->last_frame);
+ av_frame_ref(ost->last_frame, next_picture);
}
static double psnr(double d)
if (data_size && total_size>0 && total_size >= data_size)
percent = 100.0 * (total_size - data_size) / data_size;
- av_log(NULL, AV_LOG_INFO, "\n");
av_log(NULL, AV_LOG_INFO, "video:%1.0fkB audio:%1.0fkB subtitle:%1.0fkB other streams:%1.0fkB global headers:%1.0fkB muxing overhead: ",
video_size / 1024.0,
audio_size / 1024.0,
if (av_stream_get_end_pts(ost->st) != AV_NOPTS_VALUE)
pts = FFMAX(pts, av_rescale_q(av_stream_get_end_pts(ost->st),
ost->st->time_base, AV_TIME_BASE_Q));
+ if (is_last_report)
+ nb_frames_drop += ost->last_droped;
}
secs = pts / AV_TIME_BASE;
av_bprintf(&buf_script, "drop_frames=%d\n", nb_frames_drop);
if (print_stats || is_last_report) {
+ const char end = is_last_report ? '\n' : '\r';
if (print_stats==1 && AV_LOG_INFO > av_log_get_level()) {
- fprintf(stderr, "%s \r", buf);
+ fprintf(stderr, "%s %c", buf, end);
} else
- av_log(NULL, AV_LOG_INFO, "%s \r", buf);
+ av_log(NULL, AV_LOG_INFO, "%s %c", buf, end);
fflush(stderr);
}
if (*got_output || ret<0 || pkt->size)
decode_error_stat[ret<0] ++;
+ if (*got_output && ret >= 0) {
+ if (ist->dec_ctx->width != decoded_frame->width ||
+ ist->dec_ctx->height != decoded_frame->height ||
+ ist->dec_ctx->pix_fmt != decoded_frame->format) {
+ av_log(NULL, AV_LOG_DEBUG, "Frame parameters mismatch context %d,%d,%d != %d,%d,%d\n",
+ decoded_frame->width,
+ decoded_frame->height,
+ decoded_frame->format,
+ ist->dec_ctx->width,
+ ist->dec_ctx->height,
+ ist->dec_ctx->pix_fmt);
+ }
+ }
+
if (!*got_output || ret < 0) {
if (!pkt->size) {
for (i = 0; i < ist->nb_filters; i++)
ret = decode_video (ist, &avpkt, &got_output);
if (avpkt.duration) {
duration = av_rescale_q(avpkt.duration, ist->st->time_base, AV_TIME_BASE_Q);
- } else if(ist->dec_ctx->time_base.num != 0 && ist->dec_ctx->time_base.den != 0) {
+ } else if(ist->dec_ctx->framerate.num != 0 && ist->dec_ctx->framerate.den != 0) {
int ticks= av_stream_get_parser(ist->st) ? av_stream_get_parser(ist->st)->repeat_pict+1 : ist->dec_ctx->ticks_per_frame;
duration = ((int64_t)AV_TIME_BASE *
- ist->dec_ctx->time_base.num * ticks) /
- ist->dec_ctx->time_base.den;
+ ist->dec_ctx->framerate.den * ticks) /
+ ist->dec_ctx->framerate.num / ist->dec_ctx->ticks_per_frame;
} else
duration = 0;
ist->next_dts = av_rescale_q(next_dts + 1, av_inv_q(ist->framerate), time_base_q);
} else if (pkt->duration) {
ist->next_dts += av_rescale_q(pkt->duration, ist->st->time_base, AV_TIME_BASE_Q);
- } else if(ist->dec_ctx->time_base.num != 0) {
+ } else if(ist->dec_ctx->framerate.num != 0) {
int ticks= av_stream_get_parser(ist->st) ? av_stream_get_parser(ist->st)->repeat_pict + 1 : ist->dec_ctx->ticks_per_frame;
ist->next_dts += ((int64_t)AV_TIME_BASE *
- ist->dec_ctx->time_base.num * ticks) /
- ist->dec_ctx->time_base.den;
+ ist->dec_ctx->framerate.den * ticks) /
+ ist->dec_ctx->framerate.num / ist->dec_ctx->ticks_per_frame;
}
break;
}
av_reduce(&enc_ctx->time_base.num, &enc_ctx->time_base.den,
enc_ctx->time_base.num, enc_ctx->time_base.den, INT_MAX);
+ if (ist->st->nb_side_data) {
+ ost->st->side_data = av_realloc_array(NULL, ist->st->nb_side_data,
+ sizeof(*ist->st->side_data));
+ if (!ost->st->side_data)
+ return AVERROR(ENOMEM);
+
+ for (j = 0; j < ist->st->nb_side_data; j++) {
+ const AVPacketSideData *sd_src = &ist->st->side_data[j];
+ AVPacketSideData *sd_dst = &ost->st->side_data[j];
+
+ sd_dst->data = av_malloc(sd_src->size);
+ if (!sd_dst->data)
+ return AVERROR(ENOMEM);
+ memcpy(sd_dst->data, sd_src->data, sd_src->size);
+ sd_dst->size = sd_src->size;
+ sd_dst->type = sd_src->type;
+ ost->st->nb_side_data++;
+ }
+ }
+
ost->parser = av_parser_init(enc_ctx->codec_id);
switch (enc_ctx->codec_type) {
enc_ctx->frame_size = dec_ctx->frame_size;
enc_ctx->audio_service_type = dec_ctx->audio_service_type;
enc_ctx->block_align = dec_ctx->block_align;
+ enc_ctx->initial_padding = dec_ctx->delay;
+#if FF_API_AUDIOENC_DELAY
enc_ctx->delay = dec_ctx->delay;
+#endif
if((enc_ctx->block_align == 1 || enc_ctx->block_align == 1152 || enc_ctx->block_align == 576) && enc_ctx->codec_id == AV_CODEC_ID_MP3)
enc_ctx->block_align= 0;
if(enc_ctx->codec_id == AV_CODEC_ID_AC3)
av_log(NULL, AV_LOG_WARNING, "The bitrate parameter is set too low."
" It takes bits/s as argument, not kbits/s\n");
} else {
- if (av_opt_set_dict(ost->enc_ctx, &ost->encoder_opts) < 0) {
+ ret = av_opt_set_dict(ost->enc_ctx, &ost->encoder_opts);
+ if (ret < 0) {
av_log(NULL, AV_LOG_FATAL,
"Error setting up codec context options.\n");
- exit_program(1);
+ return ret;
}
}
OutputStream *ost = output_streams[i];
int64_t opts = av_rescale_q(ost->st->cur_dts, ost->st->time_base,
AV_TIME_BASE_Q);
- if (!ost->unavailable && !ost->finished && opts < opts_min) {
+ if (!ost->finished && opts < opts_min) {
opts_min = opts;
- ost_min = ost;
+ ost_min = ost->unavailable ? NULL : ost;
}
}
return ost_min;
if (pkt.dts != AV_NOPTS_VALUE)
pkt.dts *= ist->ts_scale;
- if (pkt.dts != AV_NOPTS_VALUE && ist->next_dts == AV_NOPTS_VALUE && !copy_ts
+ if ((ist->dec_ctx->codec_type == AVMEDIA_TYPE_VIDEO ||
+ ist->dec_ctx->codec_type == AVMEDIA_TYPE_AUDIO) &&
+ pkt.dts != AV_NOPTS_VALUE && ist->next_dts == AV_NOPTS_VALUE && !copy_ts
&& (is->iformat->flags & AVFMT_TS_DISCONT) && ifile->last_ts != AV_NOPTS_VALUE) {
int64_t pkt_dts = av_rescale_q(pkt.dts, ist->st->time_base, AV_TIME_BASE_Q);
int64_t delta = pkt_dts - ifile->last_ts;
- if(delta < -1LL*dts_delta_threshold*AV_TIME_BASE ||
- (delta > 1LL*dts_delta_threshold*AV_TIME_BASE &&
- ist->dec_ctx->codec_type != AVMEDIA_TYPE_SUBTITLE)){
+ if (delta < -1LL*dts_delta_threshold*AV_TIME_BASE ||
+ delta > 1LL*dts_delta_threshold*AV_TIME_BASE){
ifile->ts_offset -= delta;
av_log(NULL, AV_LOG_DEBUG,
"Inter stream timestamp discontinuity %"PRId64", new offset= %"PRId64"\n",
}
}
- if (pkt.dts != AV_NOPTS_VALUE && ist->next_dts != AV_NOPTS_VALUE &&
+ if ((ist->dec_ctx->codec_type == AVMEDIA_TYPE_VIDEO ||
+ ist->dec_ctx->codec_type == AVMEDIA_TYPE_AUDIO) &&
+ pkt.dts != AV_NOPTS_VALUE && ist->next_dts != AV_NOPTS_VALUE &&
!copy_ts) {
int64_t pkt_dts = av_rescale_q(pkt.dts, ist->st->time_base, AV_TIME_BASE_Q);
int64_t delta = pkt_dts - ist->next_dts;
if (is->iformat->flags & AVFMT_TS_DISCONT) {
if (delta < -1LL*dts_delta_threshold*AV_TIME_BASE ||
- (delta > 1LL*dts_delta_threshold*AV_TIME_BASE &&
- ist->dec_ctx->codec_type != AVMEDIA_TYPE_SUBTITLE) ||
+ delta > 1LL*dts_delta_threshold*AV_TIME_BASE ||
pkt_dts + AV_TIME_BASE/10 < FFMAX(ist->pts, ist->dts)) {
ifile->ts_offset -= delta;
av_log(NULL, AV_LOG_DEBUG,
}
} else {
if ( delta < -1LL*dts_error_threshold*AV_TIME_BASE ||
- (delta > 1LL*dts_error_threshold*AV_TIME_BASE && ist->dec_ctx->codec_type != AVMEDIA_TYPE_SUBTITLE)) {
+ delta > 1LL*dts_error_threshold*AV_TIME_BASE) {
av_log(NULL, AV_LOG_WARNING, "DTS %"PRId64", next:%"PRId64" st:%d invalid dropping\n", pkt.dts, ist->next_dts, pkt.stream_index);
pkt.dts = AV_NOPTS_VALUE;
}
int64_t pkt_pts = av_rescale_q(pkt.pts, ist->st->time_base, AV_TIME_BASE_Q);
delta = pkt_pts - ist->next_dts;
if ( delta < -1LL*dts_error_threshold*AV_TIME_BASE ||
- (delta > 1LL*dts_error_threshold*AV_TIME_BASE && ist->dec_ctx->codec_type != AVMEDIA_TYPE_SUBTITLE)) {
+ delta > 1LL*dts_error_threshold*AV_TIME_BASE) {
av_log(NULL, AV_LOG_WARNING, "PTS %"PRId64", next:%"PRId64" invalid dropping st:%d\n", pkt.pts, ist->next_dts, pkt.stream_index);
pkt.pts = AV_NOPTS_VALUE;
}
av_dict_free(&ost->encoder_opts);
av_dict_free(&ost->swr_opts);
av_dict_free(&ost->resample_opts);
+ av_dict_free(&ost->bsf_args);
}
}
}
GetProcessTimes(proc, &c, &e, &k, &u);
return ((int64_t) u.dwHighDateTime << 32 | u.dwLowDateTime) / 10;
#else
- return av_gettime();
+ return av_gettime_relative();
#endif
}
AVCodec *enc;
int64_t max_frames;
AVFrame *filtered_frame;
+ AVFrame *last_frame;
+ int last_droped;
/* video only */
AVRational frame_rate;
AVDictionary *encoder_opts;
AVDictionary *swr_opts;
AVDictionary *resample_opts;
+ AVDictionary *bsf_args;
char *apad;
OSTFinished finished; /* no more packets should be written for this stream */
int unavailable; /* true if the steram is unavailable (possibly temporarily) */
extern int do_hex_dump;
extern int do_pkt_dump;
extern int copy_ts;
+extern int start_at_zero;
extern int copy_tb;
extern int debug_ts;
extern int exit_on_error;
extern int frame_bits_per_raw_sample;
extern AVIOContext *progress_avio;
extern float max_error_rate;
+extern int vdpau_api_ver;
extern const AVIOInterruptCB int_cb;
snprintf(name, sizeof(name), "pixel format for output stream %d:%d",
ost->file_index, ost->index);
ret = avfilter_graph_create_filter(&filter,
- avfilter_get_by_name("format"),
- "format", pix_fmts, NULL,
- fg->graph);
+ avfilter_get_by_name("format"),
+ "format", pix_fmts, NULL, fg->graph);
av_freep(&pix_fmts);
if (ret < 0)
return ret;
ist->sub2video.frame = av_frame_alloc();
if (!ist->sub2video.frame)
return AVERROR(ENOMEM);
+ ist->sub2video.last_pts = INT64_MIN;
return 0;
}
AVBPrint args;
char name[255];
int ret, pad_idx = 0;
+ int64_t tsoffset = 0;
if (ist->dec_ctx->codec_type == AVMEDIA_TYPE_AUDIO) {
av_log(NULL, AV_LOG_ERROR, "Cannot connect video filter to audio input\n");
snprintf(name, sizeof(name), "trim for input stream %d:%d",
ist->file_index, ist->st->index);
+ if (copy_ts) {
+ tsoffset = f->start_time == AV_NOPTS_VALUE ? 0 : f->start_time;
+ if (!start_at_zero && f->ctx->start_time != AV_NOPTS_VALUE)
+ tsoffset += f->ctx->start_time;
+ }
ret = insert_trim(((f->start_time == AV_NOPTS_VALUE) || !f->accurate_seek) ?
- AV_NOPTS_VALUE : 0, f->recording_time, &last_filter, &pad_idx, name);
+ AV_NOPTS_VALUE : tsoffset, f->recording_time,
+ &last_filter, &pad_idx, name);
if (ret < 0)
return ret;
AVBPrint args;
char name[255];
int ret, pad_idx = 0;
+ int64_t tsoffset = 0;
if (ist->dec_ctx->codec_type != AVMEDIA_TYPE_AUDIO) {
av_log(NULL, AV_LOG_ERROR, "Cannot connect audio filter to non audio input\n");
snprintf(name, sizeof(name), "trim for input stream %d:%d",
ist->file_index, ist->st->index);
+ if (copy_ts) {
+ tsoffset = f->start_time == AV_NOPTS_VALUE ? 0 : f->start_time;
+ if (!start_at_zero && f->ctx->start_time != AV_NOPTS_VALUE)
+ tsoffset += f->ctx->start_time;
+ }
ret = insert_trim(((f->start_time == AV_NOPTS_VALUE) || !f->accurate_seek) ?
- AV_NOPTS_VALUE : 0, f->recording_time, &last_filter, &pad_idx, name);
+ AV_NOPTS_VALUE : tsoffset, f->recording_time,
+ &last_filter, &pad_idx, name);
if (ret < 0)
return ret;
int do_hex_dump = 0;
int do_pkt_dump = 0;
int copy_ts = 0;
+int start_at_zero = 0;
int copy_tb = -1;
int debug_ts = 0;
int exit_on_error = 0;
char buf[128];
int64_t recording_timestamp = parse_time_or_die(opt, arg, 0) / 1E6;
struct tm time = *gmtime((time_t*)&recording_timestamp);
- strftime(buf, sizeof(buf), "creation_time=%FT%T%z", &time);
+ if (!strftime(buf, sizeof(buf), "creation_time=%FT%T%z", &time))
+ return -1;
parse_option(o, "metadata", buf, options);
av_log(NULL, AV_LOG_WARNING, "%s is deprecated, set the 'creation_time' metadata "
MATCH_PER_STREAM_OPT(fix_sub_duration, i, ist->fix_sub_duration, ic, st);
MATCH_PER_STREAM_OPT(canvas_sizes, str, canvas_size, ic, st);
if (canvas_size &&
- av_parse_video_size(&dec->width, &dec->height, canvas_size) < 0) {
+ av_parse_video_size(&ist->dec_ctx->width, &ist->dec_ctx->height, canvas_size) < 0) {
av_log(NULL, AV_LOG_FATAL, "Invalid canvas size: %s.\n", canvas_size);
exit_program(1);
}
char * video_codec_name = NULL;
char * audio_codec_name = NULL;
char *subtitle_codec_name = NULL;
+ int scan_all_pmts_set = 0;
if (o->format) {
if (!(file_iformat = av_find_input_format(o->format))) {
ic->flags |= AVFMT_FLAG_NONBLOCK;
ic->interrupt_callback = int_cb;
+ if (!av_dict_get(o->g->format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE)) {
+ av_dict_set(&o->g->format_opts, "scan_all_pmts", "1", AV_DICT_DONT_OVERWRITE);
+ scan_all_pmts_set = 1;
+ }
/* open the input file with generic avformat function */
err = avformat_open_input(&ic, filename, file_iformat, &o->g->format_opts);
if (err < 0) {
print_error(filename, err);
exit_program(1);
}
+ if (scan_all_pmts_set)
+ av_dict_set(&o->g->format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE);
remove_avoptions(&o->g->format_opts, o->g->codec_opts);
assert_avoptions(o->g->format_opts);
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->ts_offset = o->input_ts_offset - (copy_ts ? (start_at_zero && ic->start_time != AV_NOPTS_VALUE ? ic->start_time : 0) : timestamp);
f->nb_streams = ic->nb_streams;
f->rate_emu = o->rate_emu;
f->accurate_seek = o->accurate_seek;
MATCH_PER_STREAM_OPT(bitstream_filters, str, bsf, oc, st);
while (bsf) {
+ char *arg = NULL;
if (next = strchr(bsf, ','))
*next++ = 0;
+ if (arg = strchr(bsf, '='))
+ *arg++ = 0;
if (!(bsfc = av_bitstream_filter_init(bsf))) {
av_log(NULL, AV_LOG_FATAL, "Unknown bitstream filter %s\n", bsf);
exit_program(1);
bsfc_prev->next = bsfc;
else
ost->bitstream_filters = bsfc;
+ av_dict_set(&ost->bsf_args, bsfc->filter->name, arg, 0);
bsfc_prev = bsfc;
bsf = next;
av_log(NULL, AV_LOG_FATAL, "Invalid framerate value: %s\n", frame_rate);
exit_program(1);
}
+ if (frame_rate && video_sync_method == VSYNC_PASSTHROUGH)
+ av_log(NULL, AV_LOG_ERROR, "Using -vsync 0 and -r can produce invalid output files\n");
MATCH_PER_STREAM_OPT(frame_aspect_ratios, str, frame_aspect_ratio, oc, st);
if (frame_aspect_ratio) {
AVStream *st;
OutputStream *ost;
AVCodec *codec;
- AVCodecContext *avctx;
+ const char *enc_config;
codec = avcodec_find_encoder(ic->streams[i]->codec->codec_id);
+ if (!codec) {
+ av_log(s, AV_LOG_ERROR, "no encoder found for codec id %i\n", ic->streams[i]->codec->codec_id);
+ return AVERROR(EINVAL);
+ }
+ if (codec->type == AVMEDIA_TYPE_AUDIO)
+ opt_audio_codec(o, "c:a", codec->name);
+ else if (codec->type == AVMEDIA_TYPE_VIDEO)
+ opt_video_codec(o, "c:v", codec->name);
ost = new_output_stream(o, s, codec->type, -1);
st = ost->st;
- avctx = st->codec;
- ost->enc = codec;
- // FIXME: a more elegant solution is needed
- memcpy(st, ic->streams[i], sizeof(AVStream));
- st->cur_dts = 0;
- st->info = av_malloc(sizeof(*st->info));
- memcpy(st->info, ic->streams[i]->info, sizeof(*st->info));
- st->codec= avctx;
- avcodec_copy_context(st->codec, ic->streams[i]->codec);
+ avcodec_get_context_defaults3(st->codec, codec);
+ enc_config = av_stream_get_recommended_encoder_configuration(ic->streams[i]);
+ if (enc_config) {
+ AVDictionary *opts = NULL;
+ av_dict_parse_string(&opts, enc_config, "=", ",", 0);
+ av_opt_set_dict2(st->codec, &opts, AV_OPT_SEARCH_CHILDREN);
+ av_dict_free(&opts);
+ }
if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO && !ost->stream_copy)
choose_sample_fmt(st, codec);
else if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO && !ost->stream_copy)
choose_pixel_fmt(st, st->codec, codec, st->codec->pix_fmt);
avcodec_copy_context(ost->enc_ctx, st->codec);
+ if (enc_config)
+ av_dict_parse_string(&ost->encoder_opts, enc_config, "=", ",", 0);
}
avformat_close_input(&ic);
if (o->stop_time != INT64_MAX && o->recording_time == INT64_MAX) {
int64_t start_time = o->start_time == AV_NOPTS_VALUE ? 0 : o->start_time;
if (o->stop_time <= start_time) {
- av_log(NULL, AV_LOG_WARNING, "-to value smaller than -ss; ignoring -to.\n");
- o->stop_time = INT64_MAX;
+ av_log(NULL, AV_LOG_ERROR, "-to value smaller than -ss; aborting.\n");
+ exit_program(1);
} else {
o->recording_time = o->stop_time - start_time;
}
"add metadata", "string=string" },
{ "dframes", HAS_ARG | OPT_PERFILE | OPT_EXPERT |
OPT_OUTPUT, { .func_arg = opt_data_frames },
- "set the number of data frames to record", "number" },
+ "set the number of data frames to output", "number" },
{ "benchmark", OPT_BOOL | OPT_EXPERT, { &do_benchmark },
"add timings for benchmarking" },
{ "benchmark_all", OPT_BOOL | OPT_EXPERT, { &do_benchmark_all },
"audio drift threshold", "threshold" },
{ "copyts", OPT_BOOL | OPT_EXPERT, { ©_ts },
"copy timestamps" },
+ { "start_at_zero", OPT_BOOL | OPT_EXPERT, { &start_at_zero },
+ "shift input timestamps to start at 0 when using copyts" },
{ "copytb", HAS_ARG | OPT_INT | OPT_EXPERT, { ©_tb },
"copy input stream time base when stream copying", "mode" },
{ "shortest", OPT_BOOL | OPT_EXPERT | OPT_OFFSET |
{ "copypriorss", OPT_INT | HAS_ARG | OPT_EXPERT | OPT_SPEC | OPT_OUTPUT, { .off = OFFSET(copy_prior_start) },
"copy or discard frames before start time" },
{ "frames", OPT_INT64 | HAS_ARG | OPT_SPEC | OPT_OUTPUT, { .off = OFFSET(max_frames) },
- "set the number of frames to record", "number" },
+ "set the number of frames to output", "number" },
{ "tag", OPT_STRING | HAS_ARG | OPT_SPEC |
OPT_EXPERT | OPT_OUTPUT | OPT_INPUT, { .off = OFFSET(codec_tags) },
"force codec tag/fourcc", "fourcc/tag" },
/* video options */
{ "vframes", OPT_VIDEO | HAS_ARG | OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_video_frames },
- "set the number of video frames to record", "number" },
+ "set the number of video frames to output", "number" },
{ "r", OPT_VIDEO | HAS_ARG | OPT_STRING | OPT_SPEC |
OPT_INPUT | OPT_OUTPUT, { .off = OFFSET(frame_rates) },
"set frame rate (Hz value, fraction or abbreviation)", "rate" },
{ "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" },
+#if HAVE_VDPAU_X11
+ { "vdpau_api_ver", HAS_ARG | OPT_INT | OPT_EXPERT, { &vdpau_api_ver }, "" },
+#endif
/* audio options */
{ "aframes", OPT_AUDIO | HAS_ARG | OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_audio_frames },
- "set the number of audio frames to record", "number" },
+ "set the number of audio frames to output", "number" },
{ "aq", OPT_AUDIO | HAS_ARG | OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_audio_qscale },
"set audio quality (codec-specific)", "quality", },
{ "ar", OPT_AUDIO | HAS_ARG | OPT_INT | OPT_SPEC |
VdpGetErrorString *get_error_string;
VdpGetInformationString *get_information_string;
VdpDeviceDestroy *device_destroy;
+#if 1 // for ffmpegs older vdpau API, not the oldest though
VdpDecoderCreate *decoder_create;
VdpDecoderDestroy *decoder_destroy;
VdpDecoderRender *decoder_render;
+#endif
VdpVideoSurfaceCreate *video_surface_create;
VdpVideoSurfaceDestroy *video_surface_destroy;
VdpVideoSurfaceGetBitsYCbCr *video_surface_get_bits;
VdpYCbCrFormat vdpau_format;
} VDPAUContext;
+int vdpau_api_ver = 2;
+
static void vdpau_uninit(AVCodecContext *s)
{
InputStream *ist = s->opaque;
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);
+ if (vdpau_api_ver == 1) {
+ 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);
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;
+ if (vdpau_api_ver == 1) {
+ vdpau_ctx = av_vdpau_alloc_context();
+ if (!vdpau_ctx)
+ goto fail;
+ vdpau_ctx->render = ctx->decoder_render;
- s->hwaccel_context = vdpau_ctx;
+ s->hwaccel_context = vdpau_ctx;
+ } else
+ if (av_vdpau_bind_context(s, ctx->device, ctx->get_proc_address, 0))
+ goto fail;
ctx->get_information_string(&vendor);
av_log(NULL, AV_LOG_VERBOSE, "Using VDPAU -- %s -- on X11 display %s, "
return AVERROR(EINVAL);
}
-int vdpau_init(AVCodecContext *s)
+static int vdpau_old_init(AVCodecContext *s)
{
InputStream *ist = s->opaque;
int loglevel = (ist->hwaccel_id == HWACCEL_AUTO) ? AV_LOG_VERBOSE : AV_LOG_ERROR;
return 0;
}
+
+int vdpau_init(AVCodecContext *s)
+{
+ InputStream *ist = s->opaque;
+
+ if (vdpau_api_ver == 1)
+ return vdpau_old_init(s);
+
+ if (!ist->hwaccel_ctx) {
+ int ret = vdpau_alloc(s);
+ if (ret < 0)
+ return ret;
+ }
+
+ ist->hwaccel_get_buffer = vdpau_get_buffer;
+ ist->hwaccel_retrieve_data = vdpau_retrieve_data;
+
+ return 0;
+}
#define VIDEO_PICTURE_QUEUE_SIZE 3
#define SUBPICTURE_QUEUE_SIZE 16
-
-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 */
- int allocated;
- int reallocate;
- int serial;
-
- AVRational sar;
-} VideoPicture;
-
-typedef struct SubPicture {
- double pts; /* presentation time stamp for this picture */
- AVSubtitle sub;
- int serial;
-} SubPicture;
+#define SAMPLE_QUEUE_SIZE 9
+#define FRAME_QUEUE_SIZE FFMAX(SAMPLE_QUEUE_SIZE, FFMAX(VIDEO_PICTURE_QUEUE_SIZE, SUBPICTURE_QUEUE_SIZE))
typedef struct AudioParams {
int freq;
int *queue_serial; /* pointer to the current packet queue serial, used for obsolete clock detection */
} Clock;
+/* Common struct for handling all types of decoded data and allocated render buffers. */
+typedef struct Frame {
+ AVFrame *frame;
+ AVSubtitle sub;
+ int serial;
+ double pts; /* presentation timestamp for the frame */
+ double duration; /* estimated duration of the frame */
+ int64_t pos; /* byte position of the frame in the input file */
+ SDL_Overlay *bmp;
+ int allocated;
+ int reallocate;
+ int width;
+ int height;
+ AVRational sar;
+} Frame;
+
+typedef struct FrameQueue {
+ Frame queue[FRAME_QUEUE_SIZE];
+ int rindex;
+ int windex;
+ int size;
+ int max_size;
+ int keep_last;
+ int rindex_shown;
+ SDL_mutex *mutex;
+ SDL_cond *cond;
+ PacketQueue *pktq;
+} FrameQueue;
+
enum {
AV_SYNC_AUDIO_MASTER, /* default choice */
AV_SYNC_VIDEO_MASTER,
AV_SYNC_EXTERNAL_CLOCK, /* synchronize to an external clock */
};
+typedef struct Decoder {
+ AVPacket pkt;
+ AVPacket pkt_temp;
+ PacketQueue *queue;
+ AVCodecContext *avctx;
+ int pkt_serial;
+ int finished;
+ int flushed;
+ int packet_pending;
+ SDL_cond *empty_queue_cond;
+ int64_t start_pts;
+ AVRational start_pts_tb;
+ int64_t next_pts;
+ AVRational next_pts_tb;
+} Decoder;
+
typedef struct VideoState {
SDL_Thread *read_tid;
SDL_Thread *video_tid;
+ SDL_Thread *audio_tid;
AVInputFormat *iformat;
int no_background;
int abort_request;
int read_pause_return;
AVFormatContext *ic;
int realtime;
- int audio_finished;
- int video_finished;
Clock audclk;
Clock vidclk;
Clock extclk;
+ FrameQueue pictq;
+ FrameQueue subpq;
+ FrameQueue sampq;
+
+ Decoder auddec;
+ Decoder viddec;
+ Decoder subdec;
+
int audio_stream;
int av_sync_type;
unsigned int audio_buf1_size;
int audio_buf_index; /* in bytes */
int audio_write_buf_size;
- int audio_buf_frames_pending;
- AVPacket audio_pkt_temp;
- AVPacket audio_pkt;
- int audio_pkt_temp_serial;
- int audio_last_serial;
struct AudioParams audio_src;
#if CONFIG_AVFILTER
struct AudioParams audio_filter_src;
struct SwrContext *swr_ctx;
int frame_drops_early;
int frame_drops_late;
- AVFrame *frame;
- int64_t audio_frame_next_pts;
enum ShowMode {
SHOW_MODE_NONE = -1, SHOW_MODE_VIDEO = 0, SHOW_MODE_WAVES, SHOW_MODE_RDFT, SHOW_MODE_NB
int subtitle_stream;
AVStream *subtitle_st;
PacketQueue subtitleq;
- SubPicture subpq[SUBPICTURE_QUEUE_SIZE];
- int subpq_size, subpq_rindex, subpq_windex;
- SDL_mutex *subpq_mutex;
- SDL_cond *subpq_cond;
double frame_timer;
double frame_last_returned_time;
int video_stream;
AVStream *video_st;
PacketQueue videoq;
- int64_t video_current_pos; // current displayed file pos
double max_frame_duration; // maximum duration of a frame - above this, we consider the jump a timestamp discontinuity
- VideoPicture pictq[VIDEO_PICTURE_QUEUE_SIZE];
- int pictq_size, pictq_rindex, pictq_windex, pictq_rindex_shown;
- SDL_mutex *pictq_mutex;
- SDL_cond *pictq_cond;
#if !CONFIG_AVFILTER
struct SwsContext *img_convert_ctx;
#endif
static int av_sync_type = AV_SYNC_AUDIO_MASTER;
static int64_t start_time = AV_NOPTS_VALUE;
static int64_t duration = AV_NOPTS_VALUE;
-static int workaround_bugs = 1;
static int fast = 0;
static int genpts = 0;
static int lowres = 0;
return 0;
}
+static void free_picture(Frame *vp);
+
static int packet_queue_put_private(PacketQueue *q, AVPacket *pkt)
{
MyAVPacketList *pkt1;
return ret;
}
+static void decoder_init(Decoder *d, AVCodecContext *avctx, PacketQueue *queue, SDL_cond *empty_queue_cond) {
+ memset(d, 0, sizeof(Decoder));
+ d->avctx = avctx;
+ d->queue = queue;
+ d->empty_queue_cond = empty_queue_cond;
+ d->start_pts = AV_NOPTS_VALUE;
+}
+
+static int decoder_decode_frame(Decoder *d, AVFrame *frame, AVSubtitle *sub) {
+ int got_frame = 0;
+
+ d->flushed = 0;
+
+ do {
+ int ret = -1;
+
+ if (d->queue->abort_request)
+ return -1;
+
+ if (!d->packet_pending || d->queue->serial != d->pkt_serial) {
+ AVPacket pkt;
+ do {
+ if (d->queue->nb_packets == 0)
+ SDL_CondSignal(d->empty_queue_cond);
+ if (packet_queue_get(d->queue, &pkt, 1, &d->pkt_serial) < 0)
+ return -1;
+ if (pkt.data == flush_pkt.data) {
+ avcodec_flush_buffers(d->avctx);
+ d->finished = 0;
+ d->flushed = 1;
+ d->next_pts = d->start_pts;
+ d->next_pts_tb = d->start_pts_tb;
+ }
+ } while (pkt.data == flush_pkt.data || d->queue->serial != d->pkt_serial);
+ av_free_packet(&d->pkt);
+ d->pkt_temp = d->pkt = pkt;
+ d->packet_pending = 1;
+ }
+
+ switch (d->avctx->codec_type) {
+ case AVMEDIA_TYPE_VIDEO:
+ ret = avcodec_decode_video2(d->avctx, frame, &got_frame, &d->pkt_temp);
+ if (got_frame) {
+ if (decoder_reorder_pts == -1) {
+ frame->pts = av_frame_get_best_effort_timestamp(frame);
+ } else if (decoder_reorder_pts) {
+ frame->pts = frame->pkt_pts;
+ } else {
+ frame->pts = frame->pkt_dts;
+ }
+ }
+ break;
+ case AVMEDIA_TYPE_AUDIO:
+ ret = avcodec_decode_audio4(d->avctx, frame, &got_frame, &d->pkt_temp);
+ if (got_frame) {
+ AVRational tb = (AVRational){1, frame->sample_rate};
+ if (frame->pts != AV_NOPTS_VALUE)
+ frame->pts = av_rescale_q(frame->pts, d->avctx->time_base, tb);
+ else if (frame->pkt_pts != AV_NOPTS_VALUE)
+ frame->pts = av_rescale_q(frame->pkt_pts, av_codec_get_pkt_timebase(d->avctx), tb);
+ else if (d->next_pts != AV_NOPTS_VALUE)
+ frame->pts = av_rescale_q(d->next_pts, d->next_pts_tb, tb);
+ if (frame->pts != AV_NOPTS_VALUE) {
+ d->next_pts = frame->pts + frame->nb_samples;
+ d->next_pts_tb = tb;
+ }
+ }
+ break;
+ case AVMEDIA_TYPE_SUBTITLE:
+ ret = avcodec_decode_subtitle2(d->avctx, sub, &got_frame, &d->pkt_temp);
+ break;
+ }
+
+ if (ret < 0) {
+ d->packet_pending = 0;
+ } else {
+ d->pkt_temp.dts =
+ d->pkt_temp.pts = AV_NOPTS_VALUE;
+ if (d->pkt_temp.data) {
+ if (d->avctx->codec_type != AVMEDIA_TYPE_AUDIO)
+ ret = d->pkt_temp.size;
+ d->pkt_temp.data += ret;
+ d->pkt_temp.size -= ret;
+ if (d->pkt_temp.size <= 0)
+ d->packet_pending = 0;
+ } else {
+ if (!got_frame) {
+ d->packet_pending = 0;
+ d->finished = d->pkt_serial;
+ }
+ }
+ }
+ } while (!got_frame && !d->finished);
+
+ return got_frame;
+}
+
+static void decoder_destroy(Decoder *d) {
+ av_free_packet(&d->pkt);
+}
+
+static void frame_queue_unref_item(Frame *vp)
+{
+ av_frame_unref(vp->frame);
+ avsubtitle_free(&vp->sub);
+}
+
+static int frame_queue_init(FrameQueue *f, PacketQueue *pktq, int max_size, int keep_last)
+{
+ int i;
+ memset(f, 0, sizeof(FrameQueue));
+ if (!(f->mutex = SDL_CreateMutex()))
+ return AVERROR(ENOMEM);
+ if (!(f->cond = SDL_CreateCond()))
+ return AVERROR(ENOMEM);
+ f->pktq = pktq;
+ f->max_size = FFMIN(max_size, FRAME_QUEUE_SIZE);
+ f->keep_last = !!keep_last;
+ for (i = 0; i < f->max_size; i++)
+ if (!(f->queue[i].frame = av_frame_alloc()))
+ return AVERROR(ENOMEM);
+ return 0;
+}
+
+static void frame_queue_destory(FrameQueue *f)
+{
+ int i;
+ for (i = 0; i < f->max_size; i++) {
+ Frame *vp = &f->queue[i];
+ frame_queue_unref_item(vp);
+ av_frame_free(&vp->frame);
+ free_picture(vp);
+ }
+ SDL_DestroyMutex(f->mutex);
+ SDL_DestroyCond(f->cond);
+}
+
+static void frame_queue_signal(FrameQueue *f)
+{
+ SDL_LockMutex(f->mutex);
+ SDL_CondSignal(f->cond);
+ SDL_UnlockMutex(f->mutex);
+}
+
+static Frame *frame_queue_peek(FrameQueue *f)
+{
+ return &f->queue[(f->rindex + f->rindex_shown) % f->max_size];
+}
+
+static Frame *frame_queue_peek_next(FrameQueue *f)
+{
+ return &f->queue[(f->rindex + f->rindex_shown + 1) % f->max_size];
+}
+
+static Frame *frame_queue_peek_last(FrameQueue *f)
+{
+ return &f->queue[f->rindex];
+}
+
+static Frame *frame_queue_peek_writable(FrameQueue *f)
+{
+ /* wait until we have space to put a new frame */
+ SDL_LockMutex(f->mutex);
+ while (f->size >= f->max_size &&
+ !f->pktq->abort_request) {
+ SDL_CondWait(f->cond, f->mutex);
+ }
+ SDL_UnlockMutex(f->mutex);
+
+ if (f->pktq->abort_request)
+ return NULL;
+
+ return &f->queue[f->windex];
+}
+
+static Frame *frame_queue_peek_readable(FrameQueue *f)
+{
+ /* wait until we have a readable a new frame */
+ SDL_LockMutex(f->mutex);
+ while (f->size - f->rindex_shown <= 0 &&
+ !f->pktq->abort_request) {
+ SDL_CondWait(f->cond, f->mutex);
+ }
+ SDL_UnlockMutex(f->mutex);
+
+ if (f->pktq->abort_request)
+ return NULL;
+
+ return &f->queue[(f->rindex + f->rindex_shown) % f->max_size];
+}
+
+static void frame_queue_push(FrameQueue *f)
+{
+ if (++f->windex == f->max_size)
+ f->windex = 0;
+ SDL_LockMutex(f->mutex);
+ f->size++;
+ SDL_CondSignal(f->cond);
+ SDL_UnlockMutex(f->mutex);
+}
+
+static void frame_queue_next(FrameQueue *f)
+{
+ if (f->keep_last && !f->rindex_shown) {
+ f->rindex_shown = 1;
+ return;
+ }
+ frame_queue_unref_item(&f->queue[f->rindex]);
+ if (++f->rindex == f->max_size)
+ f->rindex = 0;
+ SDL_LockMutex(f->mutex);
+ f->size--;
+ SDL_CondSignal(f->cond);
+ SDL_UnlockMutex(f->mutex);
+}
+
+/* jump back to the previous frame if available by resetting rindex_shown */
+static int frame_queue_prev(FrameQueue *f)
+{
+ int ret = f->rindex_shown;
+ f->rindex_shown = 0;
+ return ret;
+}
+
+/* return the number of undisplayed frames in the queue */
+static int frame_queue_nb_remaining(FrameQueue *f)
+{
+ return f->size - f->rindex_shown;
+}
+
+/* return last shown position */
+static int64_t frame_queue_last_pos(FrameQueue *f)
+{
+ Frame *fp = &f->queue[f->rindex];
+ if (f->rindex_shown && fp->serial == f->pktq->serial)
+ return fp->pos;
+ else
+ return -1;
+}
+
static inline void fill_rectangle(SDL_Surface *screen,
int x, int y, int w, int h, int color, int update)
{
}
}
-static void free_picture(VideoPicture *vp)
+static void free_picture(Frame *vp)
{
if (vp->bmp) {
SDL_FreeYUVOverlay(vp->bmp);
}
}
-static void free_subpicture(SubPicture *sp)
-{
- avsubtitle_free(&sp->sub);
-}
-
static void calculate_display_rect(SDL_Rect *rect,
int scr_xleft, int scr_ytop, int scr_width, int scr_height,
int pic_width, int pic_height, AVRational pic_sar)
static void video_image_display(VideoState *is)
{
- VideoPicture *vp;
- SubPicture *sp;
+ Frame *vp;
+ Frame *sp;
AVPicture pict;
SDL_Rect rect;
int i;
- vp = &is->pictq[(is->pictq_rindex + is->pictq_rindex_shown) % VIDEO_PICTURE_QUEUE_SIZE];
+ vp = frame_queue_peek(&is->pictq);
if (vp->bmp) {
if (is->subtitle_st) {
- if (is->subpq_size > 0) {
- sp = &is->subpq[is->subpq_rindex];
+ if (frame_queue_nb_remaining(&is->subpq) > 0) {
+ sp = frame_queue_peek(&is->subpq);
if (vp->pts >= sp->pts + ((float) sp->sub.start_display_time / 1000)) {
SDL_LockYUVOverlay (vp->bmp);
static void stream_close(VideoState *is)
{
- int i;
/* XXX: use a special url_shutdown call to abort parse cleanly */
is->abort_request = 1;
SDL_WaitThread(is->read_tid, NULL);
packet_queue_destroy(&is->subtitleq);
/* free all pictures */
- 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);
- SDL_DestroyCond(is->pictq_cond);
- SDL_DestroyMutex(is->subpq_mutex);
- SDL_DestroyCond(is->subpq_cond);
+ frame_queue_destory(&is->pictq);
+ frame_queue_destory(&is->sampq);
+ frame_queue_destory(&is->subpq);
SDL_DestroyCond(is->continue_read_thread);
#if !CONFIG_AVFILTER
sws_freeContext(is->img_convert_ctx);
default_height = rect.h;
}
-static int video_open(VideoState *is, int force_set_video_mode, VideoPicture *vp)
+static int video_open(VideoState *is, int force_set_video_mode, Frame *vp)
{
int flags = SDL_HWSURFACE | SDL_ASYNCBLIT | SDL_HWACCEL;
int w,h;
return delay;
}
-static double vp_duration(VideoState *is, VideoPicture *vp, VideoPicture *nextvp) {
+static double vp_duration(VideoState *is, Frame *vp, Frame *nextvp) {
if (vp->serial == nextvp->serial) {
double duration = nextvp->pts - vp->pts;
if (isnan(duration) || duration <= 0 || duration > is->max_frame_duration)
}
}
-/* return the number of undisplayed pictures in the queue */
-static int pictq_nb_remaining(VideoState *is) {
- return is->pictq_size - is->pictq_rindex_shown;
-}
-
-/* jump back to the previous picture if available by resetting rindex_shown */
-static int pictq_prev_picture(VideoState *is) {
- int ret = is->pictq_rindex_shown;
- is->pictq_rindex_shown = 0;
- return ret;
-}
-
-static void pictq_next_picture(VideoState *is) {
- if (!is->pictq_rindex_shown) {
- is->pictq_rindex_shown = 1;
- return;
- }
- /* update queue size and signal for next picture */
- if (++is->pictq_rindex == VIDEO_PICTURE_QUEUE_SIZE)
- is->pictq_rindex = 0;
-
- SDL_LockMutex(is->pictq_mutex);
- is->pictq_size--;
- SDL_CondSignal(is->pictq_cond);
- SDL_UnlockMutex(is->pictq_mutex);
-}
-
static void update_video_pts(VideoState *is, double pts, int64_t pos, int serial) {
/* update current video pts */
set_clock(&is->vidclk, pts, serial);
sync_clock_to_slave(&is->extclk, &is->vidclk);
- is->video_current_pos = pos;
}
/* called to display each frame */
VideoState *is = opaque;
double time;
- SubPicture *sp, *sp2;
+ Frame *sp, *sp2;
if (!is->paused && get_master_sync_type(is) == AV_SYNC_EXTERNAL_CLOCK && is->realtime)
check_external_clock_speed(is);
if (is->video_st) {
int redisplay = 0;
if (is->force_refresh)
- redisplay = pictq_prev_picture(is);
+ redisplay = frame_queue_prev(&is->pictq);
retry:
- if (pictq_nb_remaining(is) == 0) {
+ if (frame_queue_nb_remaining(&is->pictq) == 0) {
// nothing to do, no picture to display in the queue
} else {
double last_duration, duration, delay;
- VideoPicture *vp, *lastvp;
+ Frame *vp, *lastvp;
/* dequeue the picture */
- lastvp = &is->pictq[is->pictq_rindex];
- vp = &is->pictq[(is->pictq_rindex + is->pictq_rindex_shown) % VIDEO_PICTURE_QUEUE_SIZE];
+ lastvp = frame_queue_peek_last(&is->pictq);
+ vp = frame_queue_peek(&is->pictq);
if (vp->serial != is->videoq.serial) {
- pictq_next_picture(is);
- is->video_current_pos = -1;
+ frame_queue_next(&is->pictq);
redisplay = 0;
goto retry;
}
if (delay > 0 && time - is->frame_timer > AV_SYNC_THRESHOLD_MAX)
is->frame_timer = time;
- SDL_LockMutex(is->pictq_mutex);
+ SDL_LockMutex(is->pictq.mutex);
if (!redisplay && !isnan(vp->pts))
update_video_pts(is, vp->pts, vp->pos, vp->serial);
- SDL_UnlockMutex(is->pictq_mutex);
+ SDL_UnlockMutex(is->pictq.mutex);
- if (pictq_nb_remaining(is) > 1) {
- VideoPicture *nextvp = &is->pictq[(is->pictq_rindex + is->pictq_rindex_shown + 1) % VIDEO_PICTURE_QUEUE_SIZE];
+ if (frame_queue_nb_remaining(&is->pictq) > 1) {
+ Frame *nextvp = frame_queue_peek_next(&is->pictq);
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++;
- pictq_next_picture(is);
+ frame_queue_next(&is->pictq);
redisplay = 0;
goto retry;
}
}
if (is->subtitle_st) {
- while (is->subpq_size > 0) {
- sp = &is->subpq[is->subpq_rindex];
+ while (frame_queue_nb_remaining(&is->subpq) > 0) {
+ sp = frame_queue_peek(&is->subpq);
- if (is->subpq_size > 1)
- sp2 = &is->subpq[(is->subpq_rindex + 1) % SUBPICTURE_QUEUE_SIZE];
+ if (frame_queue_nb_remaining(&is->subpq) > 1)
+ sp2 = frame_queue_peek_next(&is->subpq);
else
sp2 = NULL;
|| (is->vidclk.pts > (sp->pts + ((float) sp->sub.end_display_time / 1000)))
|| (sp2 && is->vidclk.pts > (sp2->pts + ((float) sp2->sub.start_display_time / 1000))))
{
- free_subpicture(sp);
-
- /* update queue size and signal for next picture */
- if (++is->subpq_rindex == SUBPICTURE_QUEUE_SIZE)
- is->subpq_rindex = 0;
-
- SDL_LockMutex(is->subpq_mutex);
- is->subpq_size--;
- SDL_CondSignal(is->subpq_cond);
- SDL_UnlockMutex(is->subpq_mutex);
+ frame_queue_next(&is->subpq);
} else {
break;
}
if (!display_disable && is->show_mode == SHOW_MODE_VIDEO)
video_display(is);
- pictq_next_picture(is);
+ frame_queue_next(&is->pictq);
if (is->step && !is->paused)
stream_toggle_pause(is);
potential locking problems */
static void alloc_picture(VideoState *is)
{
- VideoPicture *vp;
+ Frame *vp;
int64_t bufferdiff;
- vp = &is->pictq[is->pictq_windex];
+ vp = &is->pictq.queue[is->pictq.windex];
free_picture(vp);
do_exit(is);
}
- SDL_LockMutex(is->pictq_mutex);
+ SDL_LockMutex(is->pictq.mutex);
vp->allocated = 1;
- SDL_CondSignal(is->pictq_cond);
- SDL_UnlockMutex(is->pictq_mutex);
+ SDL_CondSignal(is->pictq.cond);
+ SDL_UnlockMutex(is->pictq.mutex);
}
static void duplicate_right_border_pixels(SDL_Overlay *bmp) {
static int queue_picture(VideoState *is, AVFrame *src_frame, double pts, double duration, int64_t pos, int serial)
{
- VideoPicture *vp;
+ Frame *vp;
#if defined(DEBUG_SYNC) && 0
printf("frame_type=%c pts=%0.3f\n",
av_get_picture_type_char(src_frame->pict_type), pts);
#endif
- /* wait until we have space to put a new picture */
- SDL_LockMutex(is->pictq_mutex);
-
- while (is->pictq_size >= VIDEO_PICTURE_QUEUE_SIZE &&
- !is->videoq.abort_request) {
- SDL_CondWait(is->pictq_cond, is->pictq_mutex);
- }
- SDL_UnlockMutex(is->pictq_mutex);
-
- if (is->videoq.abort_request)
+ if (!(vp = frame_queue_peek_writable(&is->pictq)))
return -1;
- vp = &is->pictq[is->pictq_windex];
-
vp->sar = src_frame->sample_aspect_ratio;
/* alloc or resize hardware picture buffer */
SDL_PushEvent(&event);
/* wait until the picture is allocated */
- SDL_LockMutex(is->pictq_mutex);
+ SDL_LockMutex(is->pictq.mutex);
while (!vp->allocated && !is->videoq.abort_request) {
- SDL_CondWait(is->pictq_cond, is->pictq_mutex);
+ SDL_CondWait(is->pictq.cond, is->pictq.mutex);
}
/* if the queue is aborted, we have to pop the pending ALLOC event or wait for the allocation to complete */
if (is->videoq.abort_request && SDL_PeepEvents(&event, 1, SDL_GETEVENT, SDL_EVENTMASK(FF_ALLOC_EVENT)) != 1) {
while (!vp->allocated && !is->abort_request) {
- SDL_CondWait(is->pictq_cond, is->pictq_mutex);
+ SDL_CondWait(is->pictq.cond, is->pictq.mutex);
}
}
- SDL_UnlockMutex(is->pictq_mutex);
+ SDL_UnlockMutex(is->pictq.mutex);
if (is->videoq.abort_request)
return -1;
vp->serial = serial;
/* now we can update the picture count */
- if (++is->pictq_windex == VIDEO_PICTURE_QUEUE_SIZE)
- is->pictq_windex = 0;
- SDL_LockMutex(is->pictq_mutex);
- is->pictq_size++;
- SDL_UnlockMutex(is->pictq_mutex);
+ frame_queue_push(&is->pictq);
}
return 0;
}
-static int get_video_frame(VideoState *is, AVFrame *frame, AVPacket *pkt, int *serial)
+static int get_video_frame(VideoState *is, AVFrame *frame)
{
int got_picture;
- if (packet_queue_get(&is->videoq, pkt, 1, serial) < 0)
+ if ((got_picture = decoder_decode_frame(&is->viddec, frame, NULL)) < 0)
return -1;
- if (pkt->data == flush_pkt.data) {
- avcodec_flush_buffers(is->video_st->codec);
- return 0;
- }
-
- if(avcodec_decode_video2(is->video_st->codec, frame, &got_picture, pkt) < 0)
- return 0;
-
- if (!got_picture && !pkt->data)
- is->video_finished = *serial;
-
if (got_picture) {
- int ret = 1;
double dpts = NAN;
- if (decoder_reorder_pts == -1) {
- frame->pts = av_frame_get_best_effort_timestamp(frame);
- } else if (decoder_reorder_pts) {
- frame->pts = frame->pkt_pts;
- } else {
- frame->pts = frame->pkt_dts;
- }
-
if (frame->pts != AV_NOPTS_VALUE)
dpts = av_q2d(is->video_st->time_base) * frame->pts;
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->viddec.pkt_serial == is->vidclk.serial &&
is->videoq.nb_packets) {
is->frame_drops_early++;
av_frame_unref(frame);
- ret = 0;
+ got_picture = 0;
}
}
}
-
- return ret;
}
- return 0;
+
+ return got_picture;
}
#if CONFIG_AVFILTER
}
#endif /* CONFIG_AVFILTER */
+static int audio_thread(void *arg)
+{
+ VideoState *is = arg;
+ AVFrame *frame = av_frame_alloc();
+ Frame *af;
+#if CONFIG_AVFILTER
+ int last_serial = -1;
+ int64_t dec_channel_layout;
+ int reconfigure;
+#endif
+ int got_frame = 0;
+ AVRational tb;
+ int ret = 0;
+
+ if (!frame)
+ return AVERROR(ENOMEM);
+
+ do {
+ if ((got_frame = decoder_decode_frame(&is->auddec, frame, NULL)) < 0)
+ goto the_end;
+
+ if (got_frame) {
+ tb = (AVRational){1, frame->sample_rate};
+
+#if CONFIG_AVFILTER
+ dec_channel_layout = get_valid_channel_layout(frame->channel_layout, av_frame_get_channels(frame));
+
+ reconfigure =
+ cmp_audio_fmts(is->audio_filter_src.fmt, is->audio_filter_src.channels,
+ frame->format, av_frame_get_channels(frame)) ||
+ is->audio_filter_src.channel_layout != dec_channel_layout ||
+ is->audio_filter_src.freq != frame->sample_rate ||
+ is->auddec.pkt_serial != last_serial;
+
+ if (reconfigure) {
+ char buf1[1024], buf2[1024];
+ av_get_channel_layout_string(buf1, sizeof(buf1), -1, is->audio_filter_src.channel_layout);
+ av_get_channel_layout_string(buf2, sizeof(buf2), -1, dec_channel_layout);
+ av_log(NULL, AV_LOG_DEBUG,
+ "Audio frame changed from rate:%d ch:%d fmt:%s layout:%s serial:%d to rate:%d ch:%d fmt:%s layout:%s serial:%d\n",
+ is->audio_filter_src.freq, is->audio_filter_src.channels, av_get_sample_fmt_name(is->audio_filter_src.fmt), buf1, last_serial,
+ frame->sample_rate, av_frame_get_channels(frame), av_get_sample_fmt_name(frame->format), buf2, is->auddec.pkt_serial);
+
+ is->audio_filter_src.fmt = frame->format;
+ is->audio_filter_src.channels = av_frame_get_channels(frame);
+ is->audio_filter_src.channel_layout = dec_channel_layout;
+ is->audio_filter_src.freq = frame->sample_rate;
+ last_serial = is->auddec.pkt_serial;
+
+ if ((ret = configure_audio_filters(is, afilters, 1)) < 0)
+ goto the_end;
+ }
+
+ if ((ret = av_buffersrc_add_frame(is->in_audio_filter, frame)) < 0)
+ goto the_end;
+
+ while ((ret = av_buffersink_get_frame_flags(is->out_audio_filter, frame, 0)) >= 0) {
+ tb = is->out_audio_filter->inputs[0]->time_base;
+#endif
+ if (!(af = frame_queue_peek_writable(&is->sampq)))
+ goto the_end;
+
+ af->pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
+ af->pos = av_frame_get_pkt_pos(frame);
+ af->serial = is->auddec.pkt_serial;
+ af->duration = av_q2d((AVRational){frame->nb_samples, frame->sample_rate});
+
+ av_frame_move_ref(af->frame, frame);
+ frame_queue_push(&is->sampq);
+
+#if CONFIG_AVFILTER
+ if (is->audioq.serial != is->auddec.pkt_serial)
+ break;
+ }
+ if (ret == AVERROR_EOF)
+ is->auddec.finished = is->auddec.pkt_serial;
+#endif
+ }
+ } while (ret >= 0 || ret == AVERROR(EAGAIN) || ret == AVERROR_EOF);
+ the_end:
+#if CONFIG_AVFILTER
+ avfilter_graph_free(&is->agraph);
+#endif
+ av_frame_free(&frame);
+ return ret;
+}
+
static int video_thread(void *arg)
{
- AVPacket pkt = { 0 };
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);
#endif
for (;;) {
- while (is->paused && !is->videoq.abort_request)
- SDL_Delay(10);
-
- av_free_packet(&pkt);
-
- ret = get_video_frame(is, frame, &pkt, &serial);
+ ret = get_video_frame(is, frame);
if (ret < 0)
goto the_end;
if (!ret)
if ( last_w != frame->width
|| last_h != frame->height
|| last_format != frame->format
- || last_serial != serial
+ || last_serial != is->viddec.pkt_serial
|| last_vfilter_idx != is->vfilter_idx) {
av_log(NULL, AV_LOG_DEBUG,
"Video frame changed from size:%dx%d format:%s serial:%d to size:%dx%d format:%s serial:%d\n",
last_w, last_h,
(const char *)av_x_if_null(av_get_pix_fmt_name(last_format), "none"), last_serial,
frame->width, frame->height,
- (const char *)av_x_if_null(av_get_pix_fmt_name(frame->format), "none"), serial);
+ (const char *)av_x_if_null(av_get_pix_fmt_name(frame->format), "none"), is->viddec.pkt_serial);
avfilter_graph_free(&graph);
graph = avfilter_graph_alloc();
if ((ret = configure_video_filters(graph, is, vfilters_list ? vfilters_list[is->vfilter_idx] : NULL, frame)) < 0) {
last_w = frame->width;
last_h = frame->height;
last_format = frame->format;
- last_serial = serial;
+ last_serial = is->viddec.pkt_serial;
last_vfilter_idx = is->vfilter_idx;
frame_rate = filt_out->inputs[0]->frame_rate;
}
ret = av_buffersink_get_frame_flags(filt_out, frame, 0);
if (ret < 0) {
if (ret == AVERROR_EOF)
- is->video_finished = serial;
+ is->viddec.finished = is->viddec.pkt_serial;
ret = 0;
break;
}
#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);
+ ret = queue_picture(is, frame, pts, duration, av_frame_get_pkt_pos(frame), is->viddec.pkt_serial);
av_frame_unref(frame);
#if CONFIG_AVFILTER
}
#if CONFIG_AVFILTER
avfilter_graph_free(&graph);
#endif
- av_free_packet(&pkt);
av_frame_free(&frame);
return 0;
}
static int subtitle_thread(void *arg)
{
VideoState *is = arg;
- SubPicture *sp;
- AVPacket pkt1, *pkt = &pkt1;
+ Frame *sp;
int got_subtitle;
- int serial;
double pts;
int i, j;
int r, g, b, y, u, v, a;
for (;;) {
- while (is->paused && !is->subtitleq.abort_request) {
- SDL_Delay(10);
- }
- if (packet_queue_get(&is->subtitleq, pkt, 1, &serial) < 0)
- break;
-
- if (pkt->data == flush_pkt.data) {
- avcodec_flush_buffers(is->subtitle_st->codec);
- continue;
- }
- SDL_LockMutex(is->subpq_mutex);
- while (is->subpq_size >= SUBPICTURE_QUEUE_SIZE &&
- !is->subtitleq.abort_request) {
- SDL_CondWait(is->subpq_cond, is->subpq_mutex);
- }
- SDL_UnlockMutex(is->subpq_mutex);
-
- if (is->subtitleq.abort_request)
+ if (!(sp = frame_queue_peek_writable(&is->subpq)))
return 0;
- sp = &is->subpq[is->subpq_windex];
+ if ((got_subtitle = decoder_decode_frame(&is->subdec, NULL, &sp->sub)) < 0)
+ break;
- /* NOTE: ipts is the PTS of the _first_ picture beginning in
- this packet, if any */
pts = 0;
- if (pkt->pts != AV_NOPTS_VALUE)
- pts = av_q2d(is->subtitle_st->time_base) * pkt->pts;
- avcodec_decode_subtitle2(is->subtitle_st->codec, &sp->sub,
- &got_subtitle, pkt);
if (got_subtitle && sp->sub.format == 0) {
if (sp->sub.pts != AV_NOPTS_VALUE)
pts = sp->sub.pts / (double)AV_TIME_BASE;
sp->pts = pts;
- sp->serial = serial;
+ sp->serial = is->subdec.pkt_serial;
for (i = 0; i < sp->sub.num_rects; i++)
{
}
/* now we can update the picture count */
- if (++is->subpq_windex == SUBPICTURE_QUEUE_SIZE)
- is->subpq_windex = 0;
- SDL_LockMutex(is->subpq_mutex);
- is->subpq_size++;
- SDL_UnlockMutex(is->subpq_mutex);
+ frame_queue_push(&is->subpq);
} else if (got_subtitle) {
avsubtitle_free(&sp->sub);
}
- av_free_packet(pkt);
}
return 0;
}
*/
static int audio_decode_frame(VideoState *is)
{
- AVPacket *pkt_temp = &is->audio_pkt_temp;
- AVPacket *pkt = &is->audio_pkt;
- AVCodecContext *dec = is->audio_st->codec;
- int len1, data_size, resampled_data_size;
+ int data_size, resampled_data_size;
int64_t dec_channel_layout;
- int got_frame;
av_unused double audio_clock0;
int wanted_nb_samples;
- AVRational tb;
- int ret;
- int reconfigure;
+ Frame *af;
- for (;;) {
- /* 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 = av_frame_alloc()))
- return AVERROR(ENOMEM);
- } else {
- av_frame_unref(is->frame);
- }
+ if (is->paused)
+ return -1;
- if (is->audioq.serial != is->audio_pkt_temp_serial)
- break;
+ do {
+ if (!(af = frame_queue_peek_readable(&is->sampq)))
+ return -1;
+ frame_queue_next(&is->sampq);
+ } while (af->serial != is->audioq.serial);
+
+ data_size = av_samples_get_buffer_size(NULL, av_frame_get_channels(af->frame),
+ af->frame->nb_samples,
+ af->frame->format, 1);
+
+ dec_channel_layout =
+ (af->frame->channel_layout && av_frame_get_channels(af->frame) == av_get_channel_layout_nb_channels(af->frame->channel_layout)) ?
+ af->frame->channel_layout : av_get_default_channel_layout(av_frame_get_channels(af->frame));
+ wanted_nb_samples = synchronize_audio(is, af->frame->nb_samples);
+
+ if (af->frame->format != is->audio_src.fmt ||
+ dec_channel_layout != is->audio_src.channel_layout ||
+ af->frame->sample_rate != is->audio_src.freq ||
+ (wanted_nb_samples != af->frame->nb_samples && !is->swr_ctx)) {
+ swr_free(&is->swr_ctx);
+ is->swr_ctx = swr_alloc_set_opts(NULL,
+ is->audio_tgt.channel_layout, is->audio_tgt.fmt, is->audio_tgt.freq,
+ dec_channel_layout, af->frame->format, af->frame->sample_rate,
+ 0, NULL);
+ if (!is->swr_ctx || swr_init(is->swr_ctx) < 0) {
+ av_log(NULL, AV_LOG_ERROR,
+ "Cannot create sample rate converter for conversion of %d Hz %s %d channels to %d Hz %s %d channels!\n",
+ af->frame->sample_rate, av_get_sample_fmt_name(af->frame->format), av_frame_get_channels(af->frame),
+ is->audio_tgt.freq, av_get_sample_fmt_name(is->audio_tgt.fmt), is->audio_tgt.channels);
+ swr_free(&is->swr_ctx);
+ return -1;
+ }
+ is->audio_src.channel_layout = dec_channel_layout;
+ is->audio_src.channels = av_frame_get_channels(af->frame);
+ is->audio_src.freq = af->frame->sample_rate;
+ is->audio_src.fmt = af->frame->format;
+ }
- if (is->paused)
+ if (is->swr_ctx) {
+ const uint8_t **in = (const uint8_t **)af->frame->extended_data;
+ uint8_t **out = &is->audio_buf1;
+ int out_count = (int64_t)wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate + 256;
+ int out_size = av_samples_get_buffer_size(NULL, is->audio_tgt.channels, out_count, is->audio_tgt.fmt, 0);
+ int len2;
+ if (out_size < 0) {
+ av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size() failed\n");
+ return -1;
+ }
+ if (wanted_nb_samples != af->frame->nb_samples) {
+ if (swr_set_compensation(is->swr_ctx, (wanted_nb_samples - af->frame->nb_samples) * is->audio_tgt.freq / af->frame->sample_rate,
+ wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate) < 0) {
+ av_log(NULL, AV_LOG_ERROR, "swr_set_compensation() failed\n");
return -1;
-
- if (!is->audio_buf_frames_pending) {
- len1 = avcodec_decode_audio4(dec, is->frame, &got_frame, pkt_temp);
- if (len1 < 0) {
- /* if error, we skip the frame */
- pkt_temp->size = 0;
- break;
- }
-
- pkt_temp->dts =
- pkt_temp->pts = AV_NOPTS_VALUE;
- pkt_temp->data += len1;
- pkt_temp->size -= len1;
- if (pkt_temp->data && pkt_temp->size <= 0 || !pkt_temp->data && !got_frame)
- pkt_temp->stream_index = -1;
- if (!pkt_temp->data && !got_frame)
- is->audio_finished = is->audio_pkt_temp_serial;
-
- if (!got_frame)
- continue;
-
- tb = (AVRational){1, is->frame->sample_rate};
- if (is->frame->pts != AV_NOPTS_VALUE)
- is->frame->pts = av_rescale_q(is->frame->pts, dec->time_base, tb);
- else if (is->frame->pkt_pts != AV_NOPTS_VALUE)
- is->frame->pts = av_rescale_q(is->frame->pkt_pts, is->audio_st->time_base, tb);
- else if (is->audio_frame_next_pts != AV_NOPTS_VALUE)
-#if CONFIG_AVFILTER
- is->frame->pts = av_rescale_q(is->audio_frame_next_pts, (AVRational){1, is->audio_filter_src.freq}, tb);
-#else
- is->frame->pts = av_rescale_q(is->audio_frame_next_pts, (AVRational){1, is->audio_src.freq}, tb);
-#endif
-
- if (is->frame->pts != AV_NOPTS_VALUE)
- is->audio_frame_next_pts = is->frame->pts + is->frame->nb_samples;
-
-#if CONFIG_AVFILTER
- dec_channel_layout = get_valid_channel_layout(is->frame->channel_layout, av_frame_get_channels(is->frame));
-
- reconfigure =
- cmp_audio_fmts(is->audio_filter_src.fmt, is->audio_filter_src.channels,
- is->frame->format, av_frame_get_channels(is->frame)) ||
- is->audio_filter_src.channel_layout != dec_channel_layout ||
- is->audio_filter_src.freq != is->frame->sample_rate ||
- is->audio_pkt_temp_serial != is->audio_last_serial;
-
- if (reconfigure) {
- char buf1[1024], buf2[1024];
- av_get_channel_layout_string(buf1, sizeof(buf1), -1, is->audio_filter_src.channel_layout);
- av_get_channel_layout_string(buf2, sizeof(buf2), -1, dec_channel_layout);
- av_log(NULL, AV_LOG_DEBUG,
- "Audio frame changed from rate:%d ch:%d fmt:%s layout:%s serial:%d to rate:%d ch:%d fmt:%s layout:%s serial:%d\n",
- is->audio_filter_src.freq, is->audio_filter_src.channels, av_get_sample_fmt_name(is->audio_filter_src.fmt), buf1, is->audio_last_serial,
- is->frame->sample_rate, av_frame_get_channels(is->frame), av_get_sample_fmt_name(is->frame->format), buf2, is->audio_pkt_temp_serial);
-
- is->audio_filter_src.fmt = is->frame->format;
- is->audio_filter_src.channels = av_frame_get_channels(is->frame);
- is->audio_filter_src.channel_layout = dec_channel_layout;
- is->audio_filter_src.freq = is->frame->sample_rate;
- is->audio_last_serial = is->audio_pkt_temp_serial;
-
- if ((ret = configure_audio_filters(is, afilters, 1)) < 0)
- return ret;
- }
-
- if ((ret = av_buffersrc_add_frame(is->in_audio_filter, is->frame)) < 0)
- return ret;
-#endif
- }
-#if CONFIG_AVFILTER
- if ((ret = av_buffersink_get_frame_flags(is->out_audio_filter, is->frame, 0)) < 0) {
- if (ret == AVERROR(EAGAIN)) {
- is->audio_buf_frames_pending = 0;
- continue;
- }
- if (ret == AVERROR_EOF)
- is->audio_finished = is->audio_pkt_temp_serial;
- return ret;
}
- is->audio_buf_frames_pending = 1;
- tb = is->out_audio_filter->inputs[0]->time_base;
-#endif
-
- data_size = av_samples_get_buffer_size(NULL, av_frame_get_channels(is->frame),
- is->frame->nb_samples,
- is->frame->format, 1);
-
- dec_channel_layout =
- (is->frame->channel_layout && av_frame_get_channels(is->frame) == av_get_channel_layout_nb_channels(is->frame->channel_layout)) ?
- is->frame->channel_layout : av_get_default_channel_layout(av_frame_get_channels(is->frame));
- wanted_nb_samples = synchronize_audio(is, is->frame->nb_samples);
-
- if (is->frame->format != is->audio_src.fmt ||
- dec_channel_layout != is->audio_src.channel_layout ||
- is->frame->sample_rate != is->audio_src.freq ||
- (wanted_nb_samples != is->frame->nb_samples && !is->swr_ctx)) {
- swr_free(&is->swr_ctx);
- is->swr_ctx = swr_alloc_set_opts(NULL,
- is->audio_tgt.channel_layout, is->audio_tgt.fmt, is->audio_tgt.freq,
- dec_channel_layout, is->frame->format, is->frame->sample_rate,
- 0, NULL);
- if (!is->swr_ctx || swr_init(is->swr_ctx) < 0) {
- av_log(NULL, AV_LOG_ERROR,
- "Cannot create sample rate converter for conversion of %d Hz %s %d channels to %d Hz %s %d channels!\n",
- is->frame->sample_rate, av_get_sample_fmt_name(is->frame->format), av_frame_get_channels(is->frame),
- is->audio_tgt.freq, av_get_sample_fmt_name(is->audio_tgt.fmt), is->audio_tgt.channels);
- break;
- }
- is->audio_src.channel_layout = dec_channel_layout;
- is->audio_src.channels = av_frame_get_channels(is->frame);
- is->audio_src.freq = is->frame->sample_rate;
- is->audio_src.fmt = is->frame->format;
- }
-
- if (is->swr_ctx) {
- const uint8_t **in = (const uint8_t **)is->frame->extended_data;
- uint8_t **out = &is->audio_buf1;
- int out_count = (int64_t)wanted_nb_samples * is->audio_tgt.freq / is->frame->sample_rate + 256;
- int out_size = av_samples_get_buffer_size(NULL, is->audio_tgt.channels, out_count, is->audio_tgt.fmt, 0);
- int len2;
- if (out_size < 0) {
- av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size() failed\n");
- break;
- }
- if (wanted_nb_samples != is->frame->nb_samples) {
- if (swr_set_compensation(is->swr_ctx, (wanted_nb_samples - is->frame->nb_samples) * is->audio_tgt.freq / is->frame->sample_rate,
- wanted_nb_samples * is->audio_tgt.freq / is->frame->sample_rate) < 0) {
- av_log(NULL, AV_LOG_ERROR, "swr_set_compensation() failed\n");
- break;
- }
- }
- av_fast_malloc(&is->audio_buf1, &is->audio_buf1_size, out_size);
- if (!is->audio_buf1)
- return AVERROR(ENOMEM);
- len2 = swr_convert(is->swr_ctx, out, out_count, in, is->frame->nb_samples);
- if (len2 < 0) {
- av_log(NULL, AV_LOG_ERROR, "swr_convert() failed\n");
- break;
- }
- if (len2 == out_count) {
- av_log(NULL, AV_LOG_WARNING, "audio buffer is probably too small\n");
- swr_init(is->swr_ctx);
- }
- is->audio_buf = is->audio_buf1;
- resampled_data_size = len2 * is->audio_tgt.channels * av_get_bytes_per_sample(is->audio_tgt.fmt);
- } else {
- is->audio_buf = is->frame->data[0];
- resampled_data_size = data_size;
- }
-
- audio_clock0 = is->audio_clock;
- /* update the audio clock with the pts */
- if (is->frame->pts != AV_NOPTS_VALUE)
- is->audio_clock = is->frame->pts * av_q2d(tb) + (double) is->frame->nb_samples / is->frame->sample_rate;
- else
- is->audio_clock = NAN;
- is->audio_clock_serial = is->audio_pkt_temp_serial;
-#ifdef DEBUG
- {
- static double last_clock;
- printf("audio: delay=%0.3f clock=%0.3f clock0=%0.3f\n",
- is->audio_clock - last_clock,
- is->audio_clock, audio_clock0);
- last_clock = is->audio_clock;
- }
-#endif
- return resampled_data_size;
}
-
- /* free the current packet */
- if (pkt->data)
- av_free_packet(pkt);
- memset(pkt_temp, 0, sizeof(*pkt_temp));
- pkt_temp->stream_index = -1;
-
- if (is->audioq.abort_request) {
+ av_fast_malloc(&is->audio_buf1, &is->audio_buf1_size, out_size);
+ if (!is->audio_buf1)
+ return AVERROR(ENOMEM);
+ len2 = swr_convert(is->swr_ctx, out, out_count, in, af->frame->nb_samples);
+ if (len2 < 0) {
+ av_log(NULL, AV_LOG_ERROR, "swr_convert() failed\n");
return -1;
}
-
- if (is->audioq.nb_packets == 0)
- SDL_CondSignal(is->continue_read_thread);
-
- /* read next packet */
- if ((packet_queue_get(&is->audioq, pkt, 1, &is->audio_pkt_temp_serial)) < 0)
- return -1;
-
- if (pkt->data == flush_pkt.data) {
- avcodec_flush_buffers(dec);
- is->audio_buf_frames_pending = 0;
- is->audio_frame_next_pts = AV_NOPTS_VALUE;
- if ((is->ic->iformat->flags & (AVFMT_NOBINSEARCH | AVFMT_NOGENSEARCH | AVFMT_NO_BYTE_SEEK)) && !is->ic->iformat->read_seek)
- is->audio_frame_next_pts = is->audio_st->start_time;
+ if (len2 == out_count) {
+ av_log(NULL, AV_LOG_WARNING, "audio buffer is probably too small\n");
+ if (swr_init(is->swr_ctx) < 0)
+ swr_free(&is->swr_ctx);
}
+ is->audio_buf = is->audio_buf1;
+ resampled_data_size = len2 * is->audio_tgt.channels * av_get_bytes_per_sample(is->audio_tgt.fmt);
+ } else {
+ is->audio_buf = af->frame->data[0];
+ resampled_data_size = data_size;
+ }
- *pkt_temp = *pkt;
+ audio_clock0 = is->audio_clock;
+ /* update the audio clock with the pts */
+ if (!isnan(af->pts))
+ is->audio_clock = af->pts + (double) af->frame->nb_samples / af->frame->sample_rate;
+ else
+ is->audio_clock = NAN;
+ is->audio_clock_serial = af->serial;
+#ifdef DEBUG
+ {
+ static double last_clock;
+ printf("audio: delay=%0.3f clock=%0.3f clock0=%0.3f\n",
+ is->audio_clock - last_clock,
+ is->audio_clock, audio_clock0);
+ last_clock = is->audio_clock;
}
+#endif
+ return resampled_data_size;
}
/* prepare a new audio buffer */
AVDictionaryEntry *t = NULL;
int sample_rate, nb_channels;
int64_t channel_layout;
- int ret;
+ int ret = 0;
int stream_lowres = lowres;
if (stream_index < 0 || stream_index >= ic->nb_streams)
}
avctx->codec_id = codec->id;
- avctx->workaround_bugs = workaround_bugs;
if(stream_lowres > av_codec_get_max_lowres(codec)){
av_log(avctx, AV_LOG_WARNING, "The maximum value for lowres supported by the decoder is %d\n",
av_codec_get_max_lowres(codec));
av_dict_set_int(&opts, "lowres", stream_lowres, 0);
if (avctx->codec_type == AVMEDIA_TYPE_VIDEO || avctx->codec_type == AVMEDIA_TYPE_AUDIO)
av_dict_set(&opts, "refcounted_frames", "1", 0);
- if (avcodec_open2(avctx, codec, &opts) < 0)
- return -1;
+ if ((ret = avcodec_open2(avctx, codec, &opts)) < 0) {
+ goto fail;
+ }
if ((t = av_dict_get(opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
- return AVERROR_OPTION_NOT_FOUND;
+ ret = AVERROR_OPTION_NOT_FOUND;
+ goto fail;
}
ic->streams[stream_index]->discard = AVDISCARD_DEFAULT;
is->audio_filter_src.channel_layout = get_valid_channel_layout(avctx->channel_layout, avctx->channels);
is->audio_filter_src.fmt = avctx->sample_fmt;
if ((ret = configure_audio_filters(is, afilters, 0)) < 0)
- return ret;
+ goto fail;
link = is->out_audio_filter->inputs[0];
sample_rate = link->sample_rate;
nb_channels = link->channels;
/* prepare audio output */
if ((ret = audio_open(is, channel_layout, nb_channels, sample_rate, &is->audio_tgt)) < 0)
- return ret;
+ goto fail;
is->audio_hw_buf_size = ret;
is->audio_src = is->audio_tgt;
is->audio_buf_size = 0;
we correct audio sync only if larger than this threshold */
is->audio_diff_threshold = (double)(is->audio_hw_buf_size) / is->audio_tgt.bytes_per_sec;
- memset(&is->audio_pkt, 0, sizeof(is->audio_pkt));
- memset(&is->audio_pkt_temp, 0, sizeof(is->audio_pkt_temp));
- is->audio_pkt_temp.stream_index = -1;
-
is->audio_stream = stream_index;
is->audio_st = ic->streams[stream_index];
packet_queue_start(&is->audioq);
+ decoder_init(&is->auddec, avctx, &is->audioq, is->continue_read_thread);
+ if ((is->ic->iformat->flags & (AVFMT_NOBINSEARCH | AVFMT_NOGENSEARCH | AVFMT_NO_BYTE_SEEK)) && !is->ic->iformat->read_seek) {
+ is->auddec.start_pts = is->audio_st->start_time;
+ is->auddec.start_pts_tb = is->audio_st->time_base;
+ }
+ is->audio_tid = SDL_CreateThread(audio_thread, is);
SDL_PauseAudio(0);
break;
case AVMEDIA_TYPE_VIDEO:
is->video_st = ic->streams[stream_index];
packet_queue_start(&is->videoq);
+ decoder_init(&is->viddec, avctx, &is->videoq, is->continue_read_thread);
is->video_tid = SDL_CreateThread(video_thread, is);
is->queue_attachments_req = 1;
break;
case AVMEDIA_TYPE_SUBTITLE:
is->subtitle_stream = stream_index;
is->subtitle_st = ic->streams[stream_index];
- packet_queue_start(&is->subtitleq);
+ packet_queue_start(&is->subtitleq);
+ decoder_init(&is->subdec, avctx, &is->subtitleq, is->continue_read_thread);
is->subtitle_tid = SDL_CreateThread(subtitle_thread, is);
break;
default:
break;
}
- return 0;
+
+fail:
+ av_dict_free(&opts);
+
+ return ret;
}
static void stream_component_close(VideoState *is, int stream_index)
switch (avctx->codec_type) {
case AVMEDIA_TYPE_AUDIO:
packet_queue_abort(&is->audioq);
-
+ frame_queue_signal(&is->sampq);
SDL_CloseAudio();
+ SDL_WaitThread(is->audio_tid, NULL);
+ decoder_destroy(&is->auddec);
packet_queue_flush(&is->audioq);
- av_free_packet(&is->audio_pkt);
swr_free(&is->swr_ctx);
av_freep(&is->audio_buf1);
is->audio_buf1_size = 0;
is->audio_buf = NULL;
- av_frame_free(&is->frame);
if (is->rdft) {
av_rdft_end(is->rdft);
is->rdft = NULL;
is->rdft_bits = 0;
}
-#if CONFIG_AVFILTER
- avfilter_graph_free(&is->agraph);
-#endif
break;
case AVMEDIA_TYPE_VIDEO:
packet_queue_abort(&is->videoq);
/* note: we also signal this mutex to make sure we deblock the
video thread in all cases */
- SDL_LockMutex(is->pictq_mutex);
- SDL_CondSignal(is->pictq_cond);
- SDL_UnlockMutex(is->pictq_mutex);
+ frame_queue_signal(&is->pictq);
SDL_WaitThread(is->video_tid, NULL);
+ decoder_destroy(&is->viddec);
packet_queue_flush(&is->videoq);
break;
case AVMEDIA_TYPE_SUBTITLE:
/* note: we also signal this mutex to make sure we deblock the
video thread in all cases */
- SDL_LockMutex(is->subpq_mutex);
- SDL_CondSignal(is->subpq_cond);
- SDL_UnlockMutex(is->subpq_mutex);
+ frame_queue_signal(&is->subpq);
SDL_WaitThread(is->subtitle_tid, NULL);
+ decoder_destroy(&is->subdec);
packet_queue_flush(&is->subtitleq);
break;
default:
AVDictionary **opts;
int orig_nb_streams;
SDL_mutex *wait_mutex = SDL_CreateMutex();
+ int scan_all_pmts_set = 0;
memset(st_index, -1, sizeof(st_index));
is->last_video_stream = is->video_stream = -1;
ic = avformat_alloc_context();
ic->interrupt_callback.callback = decode_interrupt_cb;
ic->interrupt_callback.opaque = is;
+ if (!av_dict_get(format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE)) {
+ av_dict_set(&format_opts, "scan_all_pmts", "1", AV_DICT_DONT_OVERWRITE);
+ scan_all_pmts_set = 1;
+ }
err = avformat_open_input(&ic, is->filename, is->iformat, &format_opts);
if (err < 0) {
print_error(is->filename, err);
ret = -1;
goto fail;
}
+ if (scan_all_pmts_set)
+ av_dict_set(&format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE);
+
if ((t = av_dict_get(format_opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
ret = AVERROR_OPTION_NOT_FOUND;
orig_nb_streams = ic->nb_streams;
err = avformat_find_stream_info(ic, opts);
+
+ for (i = 0; i < orig_nb_streams; i++)
+ av_dict_free(&opts[i]);
+ av_freep(&opts);
+
if (err < 0) {
av_log(NULL, AV_LOG_WARNING,
"%s: could not find codec parameters\n", is->filename);
ret = -1;
goto fail;
}
- for (i = 0; i < orig_nb_streams; i++)
- av_dict_free(&opts[i]);
- av_freep(&opts);
if (ic->pb)
ic->pb->eof_reached = 0; // FIXME hack, ffplay maybe should not use avio_feof() to test for the end
continue;
}
if (!is->paused &&
- (!is->audio_st || is->audio_finished == is->audioq.serial) &&
- (!is->video_st || (is->video_finished == is->videoq.serial && pictq_nb_remaining(is) == 0))) {
+ (!is->audio_st || (is->auddec.finished == is->audioq.serial && frame_queue_nb_remaining(&is->sampq) == 0)) &&
+ (!is->video_st || (is->viddec.finished == is->videoq.serial && frame_queue_nb_remaining(&is->pictq) == 0))) {
if (loop != 1 && (!loop || --loop)) {
stream_seek(is, start_time != AV_NOPTS_VALUE ? start_time : 0, 0, 0);
} else if (autoexit) {
goto fail;
}
}
- if (eof) {
- if (is->video_stream >= 0)
- packet_queue_put_nullpacket(&is->videoq, is->video_stream);
- if (is->audio_stream >= 0)
- packet_queue_put_nullpacket(&is->audioq, is->audio_stream);
- if (is->subtitle_stream >= 0)
- packet_queue_put_nullpacket(&is->subtitleq, is->subtitle_stream);
- SDL_Delay(10);
- eof=0;
- continue;
- }
ret = av_read_frame(ic, pkt);
if (ret < 0) {
- if (ret == AVERROR_EOF || avio_feof(ic->pb))
+ if ((ret == AVERROR_EOF || avio_feof(ic->pb)) && !eof) {
+ if (is->video_stream >= 0)
+ packet_queue_put_nullpacket(&is->videoq, is->video_stream);
+ if (is->audio_stream >= 0)
+ packet_queue_put_nullpacket(&is->audioq, is->audio_stream);
+ if (is->subtitle_stream >= 0)
+ packet_queue_put_nullpacket(&is->subtitleq, is->subtitle_stream);
eof = 1;
+ }
if (ic->pb && ic->pb->error)
break;
SDL_LockMutex(wait_mutex);
SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
SDL_UnlockMutex(wait_mutex);
continue;
+ } else {
+ eof = 0;
}
/* check if packet is in play range specified by user, then queue, otherwise discard */
stream_start_time = ic->streams[pkt->stream_index]->start_time;
stream_component_close(is, is->video_stream);
if (is->subtitle_stream >= 0)
stream_component_close(is, is->subtitle_stream);
- if (is->ic) {
- avformat_close_input(&is->ic);
+ if (ic) {
+ avformat_close_input(&ic);
+ is->ic = NULL;
}
if (ret != 0) {
is->xleft = 0;
/* start video display */
- is->pictq_mutex = SDL_CreateMutex();
- is->pictq_cond = SDL_CreateCond();
-
- is->subpq_mutex = SDL_CreateMutex();
- is->subpq_cond = SDL_CreateCond();
+ if (frame_queue_init(&is->pictq, &is->videoq, VIDEO_PICTURE_QUEUE_SIZE, 1) < 0)
+ goto fail;
+ if (frame_queue_init(&is->subpq, &is->subtitleq, SUBPICTURE_QUEUE_SIZE, 0) < 0)
+ goto fail;
+ if (frame_queue_init(&is->sampq, &is->audioq, SAMPLE_QUEUE_SIZE, 1) < 0)
+ goto fail;
packet_queue_init(&is->videoq);
packet_queue_init(&is->audioq);
init_clock(&is->audclk, &is->audioq.serial);
init_clock(&is->extclk, &is->extclk.serial);
is->audio_clock_serial = -1;
- is->audio_last_serial = -1;
is->av_sync_type = av_sync_type;
is->read_tid = SDL_CreateThread(read_thread, is);
if (!is->read_tid) {
- av_free(is);
+fail:
+ stream_close(is);
return NULL;
}
return is;
/* OS X needs to reallocate the SDL overlays */
int i;
for (i = 0; i < VIDEO_PICTURE_QUEUE_SIZE; i++)
- is->pictq[i].reallocate = 1;
+ is->pictq.queue[i].reallocate = 1;
#endif
is_full_screen = !is_full_screen;
video_open(is, 1, NULL);
incr = -60.0;
do_seek:
if (seek_by_bytes) {
- if (cur_stream->video_stream >= 0 && cur_stream->video_current_pos >= 0) {
- pos = cur_stream->video_current_pos;
- } else if (cur_stream->audio_stream >= 0 && cur_stream->audio_pkt.pos >= 0) {
- pos = cur_stream->audio_pkt.pos;
- } else
+ pos = -1;
+ if (pos < 0 && cur_stream->video_stream >= 0)
+ pos = frame_queue_last_pos(&cur_stream->pictq);
+ if (pos < 0 && cur_stream->audio_stream >= 0)
+ pos = frame_queue_last_pos(&cur_stream->sampq);
+ if (pos < 0)
pos = avio_tell(cur_stream->ic->pb);
if (cur_stream->ic->bit_rate)
incr *= cur_stream->ic->bit_rate / 8.0;
break;
case SDL_VIDEORESIZE:
screen = SDL_SetVideoMode(FFMIN(16383, event.resize.w), event.resize.h, 0,
- SDL_HWSURFACE|SDL_RESIZABLE|SDL_ASYNCBLIT|SDL_HWACCEL);
+ SDL_HWSURFACE|(is_full_screen?SDL_FULLSCREEN:SDL_RESIZABLE)|SDL_ASYNCBLIT|SDL_HWACCEL);
if (!screen) {
av_log(NULL, AV_LOG_FATAL, "Failed to set video mode\n");
do_exit(cur_stream);
{ "f", HAS_ARG, { .func_arg = opt_format }, "force format", "fmt" },
{ "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO, { .func_arg = opt_frame_pix_fmt }, "set pixel format", "format" },
{ "stats", OPT_BOOL | OPT_EXPERT, { &show_status }, "show status", "" },
- { "bug", OPT_INT | HAS_ARG | OPT_EXPERT, { &workaround_bugs }, "workaround bugs", "" },
{ "fast", OPT_BOOL | OPT_EXPERT, { &fast }, "non spec compliant optimizations", "" },
{ "genpts", OPT_BOOL | OPT_EXPERT, { &genpts }, "generate pts", "" },
{ "drp", OPT_INT | HAS_ARG | OPT_EXPERT, { &decoder_reorder_pts }, "let decoder reorder pts 0=off 1=on -1=auto", ""},
static int do_show_data = 0;
static int do_show_program_version = 0;
static int do_show_library_versions = 0;
+static int do_show_pixel_formats = 0;
+static int do_show_pixel_format_flags = 0;
+static int do_show_pixel_format_components = 0;
static int do_show_chapter_tags = 0;
static int do_show_format_tags = 0;
SECTION_ID_PACKET,
SECTION_ID_PACKETS,
SECTION_ID_PACKETS_AND_FRAMES,
+ SECTION_ID_PIXEL_FORMAT,
+ SECTION_ID_PIXEL_FORMAT_FLAGS,
+ SECTION_ID_PIXEL_FORMAT_COMPONENT,
+ SECTION_ID_PIXEL_FORMAT_COMPONENTS,
+ SECTION_ID_PIXEL_FORMATS,
SECTION_ID_PROGRAM_STREAM_DISPOSITION,
SECTION_ID_PROGRAM_STREAM_TAGS,
SECTION_ID_PROGRAM,
[SECTION_ID_PACKETS] = { SECTION_ID_PACKETS, "packets", SECTION_FLAG_IS_ARRAY, { SECTION_ID_PACKET, -1} },
[SECTION_ID_PACKETS_AND_FRAMES] = { SECTION_ID_PACKETS_AND_FRAMES, "packets_and_frames", SECTION_FLAG_IS_ARRAY, { SECTION_ID_PACKET, -1} },
[SECTION_ID_PACKET] = { SECTION_ID_PACKET, "packet", 0, { -1 } },
+ [SECTION_ID_PIXEL_FORMATS] = { SECTION_ID_PIXEL_FORMATS, "pixel_formats", SECTION_FLAG_IS_ARRAY, { SECTION_ID_PIXEL_FORMAT, -1 } },
+ [SECTION_ID_PIXEL_FORMAT] = { SECTION_ID_PIXEL_FORMAT, "pixel_format", 0, { SECTION_ID_PIXEL_FORMAT_FLAGS, SECTION_ID_PIXEL_FORMAT_COMPONENTS, -1 } },
+ [SECTION_ID_PIXEL_FORMAT_FLAGS] = { SECTION_ID_PIXEL_FORMAT_FLAGS, "flags", 0, { -1 }, .unique_name = "pixel_format_flags" },
+ [SECTION_ID_PIXEL_FORMAT_COMPONENTS] = { SECTION_ID_PIXEL_FORMAT_COMPONENTS, "components", SECTION_FLAG_IS_ARRAY, {SECTION_ID_PIXEL_FORMAT_COMPONENT, -1 }, .unique_name = "pixel_format_components" },
+ [SECTION_ID_PIXEL_FORMAT_COMPONENT] = { SECTION_ID_PIXEL_FORMAT_COMPONENT, "component", 0, { -1 } },
[SECTION_ID_PROGRAM_STREAM_DISPOSITION] = { SECTION_ID_PROGRAM_STREAM_DISPOSITION, "disposition", 0, { -1 }, .unique_name = "program_stream_disposition" },
[SECTION_ID_PROGRAM_STREAM_TAGS] = { SECTION_ID_PROGRAM_STREAM_TAGS, "tags", SECTION_FLAG_HAS_VARIABLE_FIELDS, { -1 }, .element_name = "tag", .unique_name = "program_stream_tags" },
[SECTION_ID_PROGRAM] = { SECTION_ID_PROGRAM, "program", 0, { SECTION_ID_PROGRAM_TAGS, SECTION_ID_PROGRAM_STREAMS, -1 } },
[SECTION_ID_PROGRAMS] = { SECTION_ID_PROGRAMS, "programs", SECTION_FLAG_IS_ARRAY, { SECTION_ID_PROGRAM, -1 } },
[SECTION_ID_ROOT] = { SECTION_ID_ROOT, "root", SECTION_FLAG_IS_WRAPPER,
{ SECTION_ID_CHAPTERS, SECTION_ID_FORMAT, SECTION_ID_FRAMES, SECTION_ID_PROGRAMS, SECTION_ID_STREAMS,
- SECTION_ID_PACKETS, SECTION_ID_ERROR, SECTION_ID_PROGRAM_VERSION, SECTION_ID_LIBRARY_VERSIONS, -1} },
+ SECTION_ID_PACKETS, SECTION_ID_ERROR, SECTION_ID_PROGRAM_VERSION, SECTION_ID_LIBRARY_VERSIONS,
+ SECTION_ID_PIXEL_FORMATS, -1} },
[SECTION_ID_STREAMS] = { SECTION_ID_STREAMS, "streams", SECTION_FLAG_IS_ARRAY, { SECTION_ID_STREAM, -1 } },
[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" },
else print_str_opt("pix_fmt", "unknown");
print_int("level", dec_ctx->level);
if (dec_ctx->color_range != AVCOL_RANGE_UNSPECIFIED)
- print_str ("color_range", dec_ctx->color_range == AVCOL_RANGE_MPEG ? "tv": "pc");
+ print_str ("color_range", av_color_range_name(dec_ctx->color_range));
else
print_str_opt("color_range", "N/A");
s = av_get_colorspace_name(dec_ctx->colorspace);
if (s) print_str ("color_space", s);
else print_str_opt("color_space", "unknown");
+
+ if (dec_ctx->color_trc != AVCOL_TRC_UNSPECIFIED)
+ print_str("color_transfer", av_color_transfer_name(dec_ctx->color_trc));
+ else
+ print_str_opt("color_transfer", av_color_transfer_name(dec_ctx->color_trc));
+
+ if (dec_ctx->color_primaries != AVCOL_PRI_UNSPECIFIED)
+ print_str("color_primaries", av_color_primaries_name(dec_ctx->color_primaries));
+ else
+ print_str_opt("color_primaries", av_color_primaries_name(dec_ctx->color_primaries));
+
+ if (dec_ctx->chroma_sample_location != AVCHROMA_LOC_UNSPECIFIED)
+ print_str("chroma_location", av_chroma_location_name(dec_ctx->chroma_sample_location));
+ else
+ print_str_opt("chroma_location", av_chroma_location_name(dec_ctx->chroma_sample_location));
+
if (dec_ctx->timecode_frame_start >= 0) {
char tcbuf[AV_TIMECODE_STR_SIZE];
av_timecode_make_mpeg_tc_string(tcbuf, dec_ctx->timecode_frame_start);
AVFormatContext *fmt_ctx = NULL;
AVDictionaryEntry *t;
AVDictionary **opts;
+ int scan_all_pmts_set = 0;
+ if (!av_dict_get(format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE)) {
+ av_dict_set(&format_opts, "scan_all_pmts", "1", AV_DICT_DONT_OVERWRITE);
+ scan_all_pmts_set = 1;
+ }
if ((err = avformat_open_input(&fmt_ctx, filename,
iformat, &format_opts)) < 0) {
print_error(filename, err);
return err;
}
+ if (scan_all_pmts_set)
+ av_dict_set(&format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE);
if ((t = av_dict_get(format_opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
return AVERROR_OPTION_NOT_FOUND;
writer_print_section_footer(w);
}
+#define PRINT_PIX_FMT_FLAG(flagname, name) \
+ do { \
+ print_int(name, !!(pixdesc->flags & AV_PIX_FMT_FLAG_##flagname)); \
+ } while (0)
+
+static void ffprobe_show_pixel_formats(WriterContext *w)
+{
+ const AVPixFmtDescriptor *pixdesc = NULL;
+ int i, n;
+
+ writer_print_section_header(w, SECTION_ID_PIXEL_FORMATS);
+ while (pixdesc = av_pix_fmt_desc_next(pixdesc)) {
+ writer_print_section_header(w, SECTION_ID_PIXEL_FORMAT);
+ print_str("name", pixdesc->name);
+ print_int("nb_components", pixdesc->nb_components);
+ if ((pixdesc->nb_components >= 3) && !(pixdesc->flags & AV_PIX_FMT_FLAG_RGB)) {
+ print_int ("log2_chroma_w", pixdesc->log2_chroma_w);
+ print_int ("log2_chroma_h", pixdesc->log2_chroma_h);
+ } else {
+ print_str_opt("log2_chroma_w", "N/A");
+ print_str_opt("log2_chroma_h", "N/A");
+ }
+ n = av_get_bits_per_pixel(pixdesc);
+ if (n) print_int ("bits_per_pixel", n);
+ else print_str_opt("bits_per_pixel", "N/A");
+ if (do_show_pixel_format_flags) {
+ writer_print_section_header(w, SECTION_ID_PIXEL_FORMAT_FLAGS);
+ PRINT_PIX_FMT_FLAG(BE, "big_endian");
+ PRINT_PIX_FMT_FLAG(PAL, "palette");
+ PRINT_PIX_FMT_FLAG(BITSTREAM, "bitstream");
+ PRINT_PIX_FMT_FLAG(HWACCEL, "hwaccel");
+ PRINT_PIX_FMT_FLAG(PLANAR, "planar");
+ PRINT_PIX_FMT_FLAG(RGB, "rgb");
+ PRINT_PIX_FMT_FLAG(PSEUDOPAL, "pseudopal");
+ PRINT_PIX_FMT_FLAG(ALPHA, "alpha");
+ writer_print_section_footer(w);
+ }
+ if (do_show_pixel_format_components && (pixdesc->nb_components > 0)) {
+ writer_print_section_header(w, SECTION_ID_PIXEL_FORMAT_COMPONENTS);
+ for (i = 0; i < pixdesc->nb_components; i++) {
+ writer_print_section_header(w, SECTION_ID_PIXEL_FORMAT_COMPONENT);
+ print_int("index", i + 1);
+ print_int("bit_depth", pixdesc->comp[i].depth_minus1 + 1);
+ writer_print_section_footer(w);
+ }
+ writer_print_section_footer(w);
+ }
+ writer_print_section_footer(w);
+ }
+ writer_print_section_footer(w);
+}
+
static int opt_format(void *optctx, const char *opt, const char *arg)
{
iformat = av_find_input_format(arg);
DEFINE_OPT_SHOW_SECTION(frames, FRAMES);
DEFINE_OPT_SHOW_SECTION(library_versions, LIBRARY_VERSIONS);
DEFINE_OPT_SHOW_SECTION(packets, PACKETS);
+DEFINE_OPT_SHOW_SECTION(pixel_formats, PIXEL_FORMATS);
DEFINE_OPT_SHOW_SECTION(program_version, PROGRAM_VERSION);
DEFINE_OPT_SHOW_SECTION(streams, STREAMS);
DEFINE_OPT_SHOW_SECTION(programs, PROGRAMS);
{ "show_program_version", 0, {(void*)&opt_show_program_version}, "show ffprobe version" },
{ "show_library_versions", 0, {(void*)&opt_show_library_versions}, "show library versions" },
{ "show_versions", 0, {(void*)&opt_show_versions}, "show program and library versions" },
+ { "show_pixel_formats", 0, {(void*)&opt_show_pixel_formats}, "show pixel format descriptions" },
{ "show_private_data", OPT_BOOL, {(void*)&show_private_data}, "show private data" },
{ "private", OPT_BOOL, {(void*)&show_private_data}, "same as show_private_data" },
{ "bitexact", OPT_BOOL, {&do_bitexact}, "force bitexact output" },
SET_DO_SHOW(FRAMES, frames);
SET_DO_SHOW(LIBRARY_VERSIONS, library_versions);
SET_DO_SHOW(PACKETS, packets);
+ SET_DO_SHOW(PIXEL_FORMATS, pixel_formats);
+ SET_DO_SHOW(PIXEL_FORMAT_FLAGS, pixel_format_flags);
+ SET_DO_SHOW(PIXEL_FORMAT_COMPONENTS, pixel_format_components);
SET_DO_SHOW(PROGRAM_VERSION, program_version);
SET_DO_SHOW(PROGRAMS, programs);
SET_DO_SHOW(STREAMS, streams);
ffprobe_show_program_version(wctx);
if (do_show_library_versions)
ffprobe_show_library_versions(wctx);
+ if (do_show_pixel_formats)
+ ffprobe_show_pixel_formats(wctx);
if (!input_filename &&
((do_show_format || do_show_programs || do_show_streams || do_show_chapters || do_show_packets || do_show_error) ||
- (!do_show_program_version && !do_show_library_versions))) {
+ (!do_show_program_version && !do_show_library_versions && !do_show_pixel_formats))) {
show_usage();
av_log(NULL, AV_LOG_ERROR, "You have to specify one input file.\n");
av_log(NULL, AV_LOG_ERROR, "Use -h to get full help or, even better, run 'man %s'.\n", program_name);
#include "libavutil/dict.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/mathematics.h"
-#include "libavutil/pixdesc.h"
#include "libavutil/random_seed.h"
#include "libavutil/parseutils.h"
#include "libavutil/opt.h"
#include <signal.h>
#include "cmdutils.h"
+#include "ffserver_config.h"
const char program_name[] = "ffserver";
const int program_birth_year = 2000;
"RTSP_SEND_PACKET",
};
-#define MAX_STREAMS 20
-
#define IOBUFFER_INIT_SIZE 8192
/* timeouts are in ms */
int pts_stream_index; /* stream we choose as clock reference */
int64_t cur_clock; /* current clock reference value in us */
/* output format handling */
- struct FFStream *stream;
+ struct FFServerStream *stream;
/* -1 is invalid stream */
- int feed_streams[MAX_STREAMS]; /* index of streams in the feed */
- int switch_feed_streams[MAX_STREAMS]; /* index of streams in the feed */
+ int feed_streams[FFSERVER_MAX_STREAMS]; /* index of streams in the feed */
+ int switch_feed_streams[FFSERVER_MAX_STREAMS]; /* index of streams in the feed */
int switch_pending;
- AVFormatContext fmt_ctx; /* instance of FFStream for one user */
+ AVFormatContext fmt_ctx; /* instance of FFServerStream for one user */
int last_packet_sent; /* true if last data packet was sent */
int suppress_log;
DataRateData datarate;
/* RTP state specific */
enum RTSPLowerTransport rtp_protocol;
char session_id[32]; /* session id */
- AVFormatContext *rtp_ctx[MAX_STREAMS];
+ AVFormatContext *rtp_ctx[FFSERVER_MAX_STREAMS];
/* RTP/UDP specific */
- URLContext *rtp_handles[MAX_STREAMS];
+ URLContext *rtp_handles[FFSERVER_MAX_STREAMS];
/* RTP/TCP specific */
struct HTTPContext *rtsp_c;
uint8_t *packet_buffer, *packet_buffer_ptr, *packet_buffer_end;
} HTTPContext;
-/* each generated stream is described here */
-enum StreamType {
- STREAM_TYPE_LIVE,
- STREAM_TYPE_STATUS,
- STREAM_TYPE_REDIRECT,
-};
-
-enum IPAddressAction {
- IP_ALLOW = 1,
- IP_DENY,
-};
-
-typedef struct IPAddressACL {
- struct IPAddressACL *next;
- enum IPAddressAction action;
- /* These are in host order */
- struct in_addr first;
- struct in_addr last;
-} IPAddressACL;
-
-/* description of each stream of the ffserver.conf file */
-typedef struct FFStream {
- enum StreamType stream_type;
- char filename[1024]; /* stream filename */
- struct FFStream *feed; /* feed we are using (can be null if
- coming from file) */
- AVDictionary *in_opts; /* input parameters */
- AVDictionary *metadata; /* metadata to set on the stream */
- AVInputFormat *ifmt; /* if non NULL, force input format */
- AVOutputFormat *fmt;
- IPAddressACL *acl;
- char dynamic_acl[1024];
- int nb_streams;
- int prebuffer; /* Number of milliseconds early to start */
- int64_t max_time; /* Number of milliseconds to run */
- int send_on_key;
- AVStream *streams[MAX_STREAMS];
- int feed_streams[MAX_STREAMS]; /* index of streams in the feed */
- char feed_filename[1024]; /* file name of the feed storage, or
- input file name for a stream */
- pid_t pid; /* Of ffmpeg process */
- time_t pid_start; /* Of ffmpeg process */
- char **child_argv;
- struct FFStream *next;
- unsigned bandwidth; /* bandwidth, in kbits/s */
- /* RTSP options */
- char *rtsp_option;
- /* multicast specific */
- int is_multicast;
- struct in_addr multicast_ip;
- int multicast_port; /* first port used for multicast */
- int multicast_ttl;
- int loop; /* if true, send the stream in loops (only meaningful if file) */
-
- /* feed specific */
- int feed_opened; /* true if someone is writing to the feed */
- int is_feed; /* true if it is a feed */
- int readonly; /* True if writing is prohibited to the file */
- int truncate; /* True if feeder connection truncate the feed file */
- int conns_served;
- int64_t bytes_served;
- int64_t feed_max_size; /* maximum storage size, zero means unlimited */
- int64_t feed_write_index; /* current write position in feed (it wraps around) */
- int64_t feed_size; /* current size of feed */
- struct FFStream *next_feed;
-} FFStream;
-
typedef struct FeedData {
long long data_count;
float avg_frame_size; /* frame size averaged over last frames with exponential mean */
} FeedData;
-static struct sockaddr_in my_http_addr;
-static struct sockaddr_in my_rtsp_addr;
-
-static char logfilename[1024];
static HTTPContext *first_http_ctx;
-static FFStream *first_feed; /* contains only feeds */
-static FFStream *first_stream; /* contains all streams, including feeds */
+
+static FFServerConfig config = {
+ .nb_max_http_connections = 2000,
+ .nb_max_connections = 5,
+ .max_bandwidth = 1000,
+ .use_defaults = 1,
+};
static void new_connection(int server_fd, int is_rtsp);
static void close_connection(HTTPContext *c);
static void rtsp_cmd_interrupt(HTTPContext *c, const char *url, RTSPMessageHeader *h, int pause_only);
/* SDP handling */
-static int prepare_sdp_description(FFStream *stream, uint8_t **pbuffer,
+static int prepare_sdp_description(FFServerStream *stream, uint8_t **pbuffer,
struct in_addr my_ip);
/* RTP handling */
static HTTPContext *rtp_new_connection(struct sockaddr_in *from_addr,
- FFStream *stream, const char *session_id,
+ FFServerStream *stream, const char *session_id,
enum RTSPLowerTransport rtp_protocol);
static int rtp_new_av_stream(HTTPContext *c,
int stream_index, struct sockaddr_in *dest_addr,
static const char *my_program_name;
-static const char *config_filename;
-
-static int ffserver_debug;
static int no_launch;
static int need_to_start_children;
/* maximum number of simultaneous HTTP connections */
-static unsigned int nb_max_http_connections = 2000;
-static unsigned int nb_max_connections = 5;
static unsigned int nb_connections;
-static uint64_t max_bandwidth = 1000;
static uint64_t current_bandwidth;
static int64_t cur_time; // Making this global saves on passing it around everywhere
ffm->file_size = file_size;
}
-/* FIXME: make ffserver work with IPv6 */
-/* resolve host with also IP address parsing */
-static int resolve_host(struct in_addr *sin_addr, const char *hostname)
-{
-
- if (!ff_inet_aton(hostname, sin_addr)) {
-#if HAVE_GETADDRINFO
- struct addrinfo *ai, *cur;
- struct addrinfo hints = { 0 };
- hints.ai_family = AF_INET;
- if (getaddrinfo(hostname, NULL, &hints, &ai))
- return -1;
- /* getaddrinfo returns a linked list of addrinfo structs.
- * Even if we set ai_family = AF_INET above, make sure
- * that the returned one actually is of the correct type. */
- for (cur = ai; cur; cur = cur->ai_next) {
- if (cur->ai_family == AF_INET) {
- *sin_addr = ((struct sockaddr_in *)cur->ai_addr)->sin_addr;
- freeaddrinfo(ai);
- return 0;
- }
- }
- freeaddrinfo(ai);
- return -1;
-#else
- struct hostent *hp;
- hp = gethostbyname(hostname);
- if (!hp)
- return -1;
- memcpy(sin_addr, hp->h_addr_list[0], sizeof(struct in_addr));
-#endif
- }
- return 0;
-}
-
static char *ctime1(char *buf2, int buf_size)
{
time_t ti;
}
-static void start_children(FFStream *feed)
+static void start_children(FFServerStream *feed)
{
if (no_launch)
return;
for (i = 3; i < 256; i++)
close(i);
- if (!ffserver_debug) {
+ if (!config.debug) {
if (!freopen("/dev/null", "r", stdin))
http_log("failed to redirect STDIN to /dev/null\n;");
if (!freopen("/dev/null", "w", stdout))
/* start all multicast streams */
static void start_multicast(void)
{
- FFStream *stream;
+ FFServerStream *stream;
char session_id[32];
HTTPContext *rtp_c;
struct sockaddr_in dest_addr = {0};
int default_port, stream_index;
default_port = 6000;
- for(stream = first_stream; stream; stream = stream->next) {
+ for(stream = config.first_stream; stream; stream = stream->next) {
if (stream->is_multicast) {
unsigned random0 = av_lfg_get(&random_state);
unsigned random1 = av_lfg_get(&random_state);
struct pollfd *poll_table, *poll_entry;
HTTPContext *c, *c_next;
- if(!(poll_table = av_mallocz_array(nb_max_http_connections + 2, sizeof(*poll_table)))) {
- http_log("Impossible to allocate a poll table handling %d connections.\n", nb_max_http_connections);
+ if(!(poll_table = av_mallocz_array(config.nb_max_http_connections + 2, sizeof(*poll_table)))) {
+ http_log("Impossible to allocate a poll table handling %d connections.\n", config.nb_max_http_connections);
return -1;
}
- if (my_http_addr.sin_port) {
- server_fd = socket_open_listen(&my_http_addr);
+ if (config.http_addr.sin_port) {
+ server_fd = socket_open_listen(&config.http_addr);
if (server_fd < 0) {
av_free(poll_table);
return -1;
}
}
- if (my_rtsp_addr.sin_port) {
- rtsp_server_fd = socket_open_listen(&my_rtsp_addr);
+ if (config.rtsp_addr.sin_port) {
+ rtsp_server_fd = socket_open_listen(&config.rtsp_addr);
if (rtsp_server_fd < 0) {
av_free(poll_table);
closesocket(server_fd);
http_log("FFserver started.\n");
- start_children(first_feed);
+ start_children(config.first_feed);
start_multicast();
if (need_to_start_children) {
need_to_start_children = 0;
- start_children(first_feed);
+ start_children(config.first_feed);
}
/* now handle the events */
"<p>The server is too busy to serve your request at this time.</p>\r\n"
"<p>The number of current connections is %u, and this exceeds the limit of %u.</p>\r\n"
"</body></html>\r\n",
- nb_connections, nb_max_connections);
+ nb_connections, config.nb_max_connections);
av_assert0(len < sizeof(buffer));
if (send(fd, buffer, len, 0) < len)
av_log(NULL, AV_LOG_WARNING, "Could not send too-busy reply, send() failed\n");
if (ff_socket_nonblock(fd, 1) < 0)
av_log(NULL, AV_LOG_WARNING, "ff_socket_nonblock failed\n");
- if (nb_connections >= nb_max_connections) {
+ if (nb_connections >= config.nb_max_connections) {
http_send_too_busy_reply(fd);
goto fail;
}
fail:
if (c) {
- av_free(c->buffer);
+ av_freep(&c->buffer);
av_free(c);
}
closesocket(fd);
if (ctx) {
av_write_trailer(ctx);
av_dict_free(&ctx->metadata);
- av_free(ctx->streams[0]);
- av_free(ctx);
+ av_freep(&ctx->streams[0]);
+ av_freep(&ctx);
}
h = c->rtp_handles[i];
if (h)
}
for(i=0; i<ctx->nb_streams; i++)
- av_free(ctx->streams[i]);
+ av_freep(&ctx->streams[i]);
av_freep(&ctx->streams);
av_freep(&ctx->priv_data);
av_freep(&c->pb_buffer);
av_freep(&c->packet_buffer);
- av_free(c->buffer);
+ av_freep(&c->buffer);
av_free(c);
nb_connections--;
}
return 0;
}
-static int find_stream_in_feed(FFStream *feed, AVCodecContext *codec, int bit_rate)
+static int find_stream_in_feed(FFServerStream *feed, AVCodecContext *codec, int bit_rate)
{
int i;
int best_bitrate = 100000000;
static int modify_current_stream(HTTPContext *c, char *rates)
{
int i;
- FFStream *req = c->stream;
+ FFServerStream *req = c->stream;
int action_required = 0;
/* Not much we can do for a feed */
*pp = p;
}
-static void get_arg(char *buf, int buf_size, const char **pp)
-{
- const char *p;
- char *q;
- int quote;
-
- p = *pp;
- while (av_isspace(*p)) p++;
- q = buf;
- quote = 0;
- if (*p == '\"' || *p == '\'')
- quote = *p++;
- for(;;) {
- if (quote) {
- if (*p == quote)
- break;
- } else {
- if (av_isspace(*p))
- break;
- }
- if (*p == '\0')
- break;
- if ((q - buf) < buf_size - 1)
- *q++ = *p;
- p++;
- }
- *q = '\0';
- if (quote && *p == quote)
- p++;
- *pp = p;
-}
-
-static void parse_acl_row(FFStream *stream, FFStream* feed, IPAddressACL *ext_acl,
- const char *p, const char *filename, int line_num)
-{
- char arg[1024];
- IPAddressACL acl;
- int errors = 0;
-
- get_arg(arg, sizeof(arg), &p);
- if (av_strcasecmp(arg, "allow") == 0)
- acl.action = IP_ALLOW;
- else if (av_strcasecmp(arg, "deny") == 0)
- acl.action = IP_DENY;
- else {
- fprintf(stderr, "%s:%d: ACL action '%s' is not ALLOW or DENY\n",
- filename, line_num, arg);
- errors++;
- }
-
- get_arg(arg, sizeof(arg), &p);
-
- if (resolve_host(&acl.first, arg) != 0) {
- fprintf(stderr, "%s:%d: ACL refers to invalid host or IP address '%s'\n",
- filename, line_num, arg);
- errors++;
- } else
- acl.last = acl.first;
-
- get_arg(arg, sizeof(arg), &p);
-
- if (arg[0]) {
- if (resolve_host(&acl.last, arg) != 0) {
- fprintf(stderr, "%s:%d: ACL refers to invalid host or IP address '%s'\n",
- filename, line_num, arg);
- errors++;
- }
- }
-
- if (!errors) {
- IPAddressACL *nacl = av_mallocz(sizeof(*nacl));
- IPAddressACL **naclp = 0;
-
- acl.next = 0;
- *nacl = acl;
-
- if (stream)
- naclp = &stream->acl;
- else if (feed)
- naclp = &feed->acl;
- else if (ext_acl)
- naclp = &ext_acl;
- else {
- fprintf(stderr, "%s:%d: ACL found not in <stream> or <feed>\n",
- filename, line_num);
- errors++;
- }
-
- if (naclp) {
- while (*naclp)
- naclp = &(*naclp)->next;
-
- *naclp = nacl;
- } else
- av_free(nacl);
- }
-}
-
-
-static IPAddressACL* parse_dynamic_acl(FFStream *stream, HTTPContext *c)
+static FFServerIPAddressACL* parse_dynamic_acl(FFServerStream *stream, HTTPContext *c)
{
FILE* f;
char line[1024];
char cmd[1024];
- IPAddressACL *acl = NULL;
+ FFServerIPAddressACL *acl = NULL;
int line_num = 0;
const char *p;
return NULL;
}
- acl = av_mallocz(sizeof(IPAddressACL));
+ acl = av_mallocz(sizeof(FFServerIPAddressACL));
/* Build ACL */
for(;;) {
p++;
if (*p == '\0' || *p == '#')
continue;
- get_arg(cmd, sizeof(cmd), &p);
+ ffserver_get_arg(cmd, sizeof(cmd), &p);
if (!av_strcasecmp(cmd, "ACL"))
- parse_acl_row(NULL, NULL, acl, p, stream->dynamic_acl, line_num);
+ ffserver_parse_acl_row(NULL, NULL, acl, p, stream->dynamic_acl, line_num);
}
fclose(f);
return acl;
}
-static void free_acl_list(IPAddressACL *in_acl)
+static void free_acl_list(FFServerIPAddressACL *in_acl)
{
- IPAddressACL *pacl,*pacl2;
+ FFServerIPAddressACL *pacl, *pacl2;
pacl = in_acl;
while(pacl) {
}
}
-static int validate_acl_list(IPAddressACL *in_acl, HTTPContext *c)
+static int validate_acl_list(FFServerIPAddressACL *in_acl, HTTPContext *c)
{
- enum IPAddressAction last_action = IP_DENY;
- IPAddressACL *acl;
+ enum FFServerIPAddressAction last_action = IP_DENY;
+ FFServerIPAddressACL *acl;
struct in_addr *src = &c->from_addr.sin_addr;
unsigned long src_addr = src->s_addr;
return (last_action == IP_DENY) ? 1 : 0;
}
-static int validate_acl(FFStream *stream, HTTPContext *c)
+static int validate_acl(FFServerStream *stream, HTTPContext *c)
{
int ret = 0;
- IPAddressACL *acl;
-
+ FFServerIPAddressACL *acl;
/* if stream->acl is null validate_acl_list will return 1 */
ret = validate_acl_list(stream->acl, c);
char file1[1024];
char file2[1024];
char *p;
- FFStream *stream;
+ FFServerStream *stream;
/* compute filename by matching without the file extensions */
av_strlcpy(file1, filename, sizeof(file1));
p = strrchr(file1, '.');
if (p)
*p = '\0';
- for(stream = first_stream; stream; stream = stream->next) {
+ for(stream = config.first_stream; stream; stream = stream->next) {
av_strlcpy(file2, stream->filename, sizeof(file2));
p = strrchr(file2, '.');
if (p)
char protocol[32];
char msg[1024];
const char *mime_type;
- FFStream *stream;
+ FFServerStream *stream;
int i;
char ratebuf[32];
const char *useragent = 0;
av_strlcpy(c->protocol, protocol, sizeof(c->protocol));
- if (ffserver_debug)
+ if (config.debug)
http_log("%s - - New connection: %s %s\n", inet_ntoa(c->from_addr.sin_addr), cmd, url);
/* find the filename and the optional info string in the request */
redir_type = REDIR_ASX;
filename[strlen(filename)-1] = 'f';
} else if (av_match_ext(filename, "asf") &&
- (!useragent || av_strncasecmp(useragent, "NSPlayer", 8) != 0)) {
+ (!useragent || av_strncasecmp(useragent, "NSPlayer", 8))) {
/* if this isn't WMP or lookalike, return the redirector file */
redir_type = REDIR_ASF;
} else if (av_match_ext(filename, "rpm,ram")) {
if (!strlen(filename))
av_strlcpy(filename, "index.html", sizeof(filename) - 1);
- stream = first_stream;
+ stream = config.first_stream;
while (stream) {
if (!strcmp(stream->filename, filename) && validate_acl(stream, c))
break;
goto send_error;
}
- if (c->post == 0 && max_bandwidth < current_bandwidth) {
+ if (c->post == 0 && config.max_bandwidth < current_bandwidth) {
c->http_error = 503;
q = c->buffer;
snprintf(q, c->buffer_size,
"<p>The server is too busy to serve your request at this time.</p>\r\n"
"<p>The bandwidth being served (including your stream) is %"PRIu64"kbit/sec, "
"and this exceeds the limit of %"PRIu64"kbit/sec.</p>\r\n"
- "</body></html>\r\n", current_bandwidth, max_bandwidth);
+ "</body></html>\r\n", current_bandwidth, config.max_bandwidth);
q += strlen(q);
/* prepare output buffer */
c->buffer_ptr = c->buffer;
/* XXX: incorrect MIME type ? */
"Content-type: application/x-rtsp\r\n"
"\r\n"
- "rtsp://%s:%d/%s\r\n", hostname, ntohs(my_rtsp_addr.sin_port), filename);
+ "rtsp://%s:%d/%s\r\n", hostname, ntohs(config.rtsp_addr.sin_port), filename);
q += strlen(q);
}
break;
static void compute_status(HTTPContext *c)
{
HTTPContext *c1;
- FFStream *stream;
+ FFServerStream *stream;
char *p;
time_t ti;
int i, len;
avio_printf(pb, "<h2>Available Streams</h2>\n");
avio_printf(pb, "<table cellspacing=0 cellpadding=4>\n");
avio_printf(pb, "<tr><th valign=top>Path<th align=left>Served<br>Conns<th><br>bytes<th valign=top>Format<th>Bit rate<br>kbits/s<th align=left>Video<br>kbits/s<th><br>Codec<th align=left>Audio<br>kbits/s<th><br>Codec<th align=left valign=top>Feed\n");
- stream = first_stream;
+ stream = config.first_stream;
while (stream) {
char sfilename[1024];
char *eosf;
}
avio_printf(pb, "</table>\n");
- stream = first_stream;
+ stream = config.first_stream;
while (stream) {
if (stream->feed == stream) {
avio_printf(pb, "<h2>Feed %s</h2>", stream->filename);
avio_printf(pb, "<h2>Connection Status</h2>\n");
avio_printf(pb, "Number of connections: %d / %d<br>\n",
- nb_connections, nb_max_connections);
+ nb_connections, config.nb_max_connections);
avio_printf(pb, "Bandwidth in use: %"PRIu64"k / %"PRIu64"k<br>\n",
- current_bandwidth, max_bandwidth);
+ current_bandwidth, config.max_bandwidth);
avio_printf(pb, "<table>\n");
avio_printf(pb, "<tr><th>#<th>File<th>IP<th>Proto<th>State<th>Target bits/sec<th>Actual bits/sec<th>Bytes transferred\n");
for(i=0;i<c->stream->nb_streams;i++) {
AVStream *src;
c->fmt_ctx.streams[i] = av_mallocz(sizeof(AVStream));
- /* if file or feed, then just take streams from FFStream struct */
+ /* if file or feed, then just take streams from FFServerStream struct */
if (!c->stream->feed ||
c->stream->feed == c->stream)
src = c->stream->streams[i];
c->state = HTTPSTATE_SEND_DATA_TRAILER;
}
+ av_freep(&c->pb_buffer);
len = avio_close_dyn_buf(ctx->pb, &c->pb_buffer);
c->cur_frame_bytes = len;
c->buffer_ptr = c->pb_buffer;
ret = http_prepare_data(c);
if (ret < 0)
return -1;
- else if (ret != 0)
+ else if (ret)
/* state change requested */
break;
} else {
}
if (c->buffer_ptr >= c->buffer_end) {
- FFStream *feed = c->stream;
+ FFServerStream *feed = c->stream;
/* a packet has been received : write it in the store, except
if header */
if (c->data_count > FFM_PACKET_SIZE) {
s->pb = pb;
if (avformat_open_input(&s, c->stream->feed_filename, fmt_in, NULL) < 0) {
- av_free(pb);
+ av_freep(&pb);
goto fail;
}
/* Now we have the actual streams */
if (s->nb_streams != feed->nb_streams) {
avformat_close_input(&s);
- av_free(pb);
+ av_freep(&pb);
http_log("Feed '%s' stream number does not match registered feed\n",
c->stream->feed_filename);
goto fail;
}
avformat_close_input(&s);
- av_free(pb);
+ av_freep(&pb);
}
c->buffer_ptr = c->buffer;
}
}
/* check version name */
- if (strcmp(protocol, "RTSP/1.0") != 0) {
+ if (strcmp(protocol, "RTSP/1.0")) {
rtsp_reply_error(c, RTSP_STATUS_VERSION);
goto the_end;
}
return 0;
}
-static int prepare_sdp_description(FFStream *stream, uint8_t **pbuffer,
+static int prepare_sdp_description(FFServerStream *stream, uint8_t **pbuffer,
struct in_addr my_ip)
{
AVFormatContext *avc;
av_sdp_create(&avc, 1, *pbuffer, 2048);
sdp_done:
- av_free(avc->streams);
+ av_freep(&avc->streams);
av_dict_free(&avc->metadata);
av_free(avc);
av_free(avs);
static void rtsp_cmd_describe(HTTPContext *c, const char *url)
{
- FFStream *stream;
+ FFServerStream *stream;
char path1[1024];
const char *path;
uint8_t *content;
if (*path == '/')
path++;
- for(stream = first_stream; stream; stream = stream->next) {
+ for(stream = config.first_stream; stream; stream = stream->next) {
if (!stream->is_feed &&
stream->fmt && !strcmp(stream->fmt->name, "rtp") &&
!strcmp(path, stream->filename)) {
static void rtsp_cmd_setup(HTTPContext *c, const char *url,
RTSPMessageHeader *h)
{
- FFStream *stream;
+ FFServerStream *stream;
int stream_index, rtp_port, rtcp_port;
char buf[1024];
char path1[1024];
path++;
/* now check each stream */
- for(stream = first_stream; stream; stream = stream->next) {
+ for(stream = config.first_stream; stream; stream = stream->next) {
if (!stream->is_feed &&
stream->fmt && !strcmp(stream->fmt->name, "rtp")) {
/* accept aggregate filenames only if single stream */
/* RTP handling */
static HTTPContext *rtp_new_connection(struct sockaddr_in *from_addr,
- FFStream *stream, const char *session_id,
+ FFServerStream *stream, const char *session_id,
enum RTSPLowerTransport rtp_protocol)
{
HTTPContext *c = NULL;
/* XXX: should output a warning page when coming
close to the connection limit */
- if (nb_connections >= nb_max_connections)
+ if (nb_connections >= config.nb_max_connections)
goto fail;
/* add a new connection */
fail:
if (c) {
- av_free(c->buffer);
+ av_freep(&c->buffer);
av_free(c);
}
return NULL;
/********************************************************************/
/* ffserver initialization */
-static AVStream *add_av_stream1(FFStream *stream, AVCodecContext *codec, int copy)
+static AVStream *add_av_stream1(FFServerStream *stream, AVCodecContext *codec, int copy)
{
AVStream *fst;
if (!fst)
return NULL;
if (copy) {
- fst->codec = avcodec_alloc_context3(NULL);
- memcpy(fst->codec, codec, sizeof(AVCodecContext));
- if (codec->extradata_size) {
- fst->codec->extradata = av_mallocz(codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
- memcpy(fst->codec->extradata, codec->extradata,
- codec->extradata_size);
- }
+ fst->codec = avcodec_alloc_context3(codec->codec);
+ avcodec_copy_context(fst->codec, codec);
} else {
/* live streams must use the actual feed's codec since it may be
* updated later to carry extradata needed by them.
}
/* return the stream number in the feed */
-static int add_av_stream(FFStream *feed, AVStream *st)
+static int add_av_stream(FFServerStream *feed, AVStream *st)
{
AVStream *fst;
AVCodecContext *av, *av1;
av = st->codec;
for(i=0;i<feed->nb_streams;i++) {
- st = feed->streams[i];
- av1 = st->codec;
+ av1 = feed->streams[i]->codec;
if (av1->codec_id == av->codec_id &&
av1->codec_type == av->codec_type &&
av1->bit_rate == av->bit_rate) {
fst = add_av_stream1(feed, av, 0);
if (!fst)
return -1;
+ if (av_stream_get_recommended_encoder_configuration(st))
+ av_stream_set_recommended_encoder_configuration(fst,
+ av_strdup(av_stream_get_recommended_encoder_configuration(st)));
return feed->nb_streams - 1;
}
-static void remove_stream(FFStream *stream)
+static void remove_stream(FFServerStream *stream)
{
- FFStream **ps;
- ps = &first_stream;
+ FFServerStream **ps;
+ ps = &config.first_stream;
while (*ps) {
if (*ps == stream)
*ps = (*ps)->next;
/* compute the needed AVStream for each file */
static void build_file_streams(void)
{
- FFStream *stream, *stream_next;
+ FFServerStream *stream, *stream_next;
int i, ret;
/* gather all streams */
- for(stream = first_stream; stream; stream = stream_next) {
+ for(stream = config.first_stream; stream; stream = stream_next) {
AVFormatContext *infile = NULL;
stream_next = stream->next;
if (stream->stream_type == STREAM_TYPE_LIVE &&
/* compute the needed AVStream for each feed */
static void build_feed_streams(void)
{
- FFStream *stream, *feed;
+ FFServerStream *stream, *feed;
int i;
/* gather all streams */
- for(stream = first_stream; stream; stream = stream->next) {
+ for(stream = config.first_stream; stream; stream = stream->next) {
feed = stream->feed;
if (feed) {
if (stream->is_feed) {
}
/* create feed files if needed */
- for(feed = first_feed; feed; feed = feed->next_feed) {
+ for(feed = config.first_feed; feed; feed = feed->next_feed) {
int fd;
if (avio_check(feed->feed_filename, AVIO_FLAG_READ) > 0) {
{
unsigned bandwidth;
int i;
- FFStream *stream;
+ FFServerStream *stream;
- for(stream = first_stream; stream; stream = stream->next) {
+ for(stream = config.first_stream; stream; stream = stream->next) {
bandwidth = 0;
for(i=0;i<stream->nb_streams;i++) {
AVStream *st = stream->streams[i];
}
}
-/* add a codec and set the default parameters */
-static void add_codec(FFStream *stream, AVCodecContext *av)
-{
- AVStream *st;
-
- if(stream->nb_streams >= FF_ARRAY_ELEMS(stream->streams))
- return;
-
- /* compute default parameters */
- switch(av->codec_type) {
- case AVMEDIA_TYPE_AUDIO:
- if (av->bit_rate == 0)
- av->bit_rate = 64000;
- if (av->sample_rate == 0)
- av->sample_rate = 22050;
- if (av->channels == 0)
- av->channels = 1;
- break;
- case AVMEDIA_TYPE_VIDEO:
- if (av->bit_rate == 0)
- av->bit_rate = 64000;
- if (av->time_base.num == 0){
- av->time_base.den = 5;
- av->time_base.num = 1;
- }
- if (av->width == 0 || av->height == 0) {
- av->width = 160;
- av->height = 128;
- }
- /* Bitrate tolerance is less for streaming */
- if (av->bit_rate_tolerance == 0)
- av->bit_rate_tolerance = FFMAX(av->bit_rate / 4,
- (int64_t)av->bit_rate*av->time_base.num/av->time_base.den);
- if (av->qmin == 0)
- av->qmin = 3;
- if (av->qmax == 0)
- av->qmax = 31;
- if (av->max_qdiff == 0)
- av->max_qdiff = 3;
- av->qcompress = 0.5;
- av->qblur = 0.5;
-
- if (!av->nsse_weight)
- av->nsse_weight = 8;
-
- av->frame_skip_cmp = FF_CMP_DCTMAX;
- if (!av->me_method)
- av->me_method = ME_EPZS;
- av->rc_buffer_aggressivity = 1.0;
-
- if (!av->rc_eq)
- av->rc_eq = av_strdup("tex^qComp");
- if (!av->i_quant_factor)
- av->i_quant_factor = -0.8;
- if (!av->b_quant_factor)
- av->b_quant_factor = 1.25;
- if (!av->b_quant_offset)
- av->b_quant_offset = 1.25;
- if (!av->rc_max_rate)
- av->rc_max_rate = av->bit_rate * 2;
-
- if (av->rc_max_rate && !av->rc_buffer_size) {
- av->rc_buffer_size = av->rc_max_rate;
- }
-
-
- break;
- default:
- abort();
- }
-
- st = av_mallocz(sizeof(AVStream));
- if (!st)
- return;
- st->codec = avcodec_alloc_context3(NULL);
- stream->streams[stream->nb_streams++] = st;
- memcpy(st->codec, av, sizeof(AVCodecContext));
-}
-
-static enum AVCodecID opt_codec(const char *name, enum AVMediaType type)
-{
- AVCodec *codec = avcodec_find_encoder_by_name(name);
-
- if (!codec || codec->type != type)
- return AV_CODEC_ID_NONE;
- return codec->id;
-}
-
-static int ffserver_opt_default(const char *opt, const char *arg,
- AVCodecContext *avctx, int type)
-{
- int ret = 0;
- const AVOption *o = av_opt_find(avctx, opt, NULL, type, 0);
- if(o)
- ret = av_opt_set(avctx, opt, arg, 0);
- return ret;
-}
-
-static int ffserver_opt_preset(const char *arg,
- AVCodecContext *avctx, int type,
- enum AVCodecID *audio_id, enum AVCodecID *video_id)
-{
- FILE *f=NULL;
- char filename[1000], tmp[1000], tmp2[1000], line[1000];
- int ret = 0;
- AVCodec *codec = avcodec_find_encoder(avctx->codec_id);
-
- if (!(f = get_preset_file(filename, sizeof(filename), arg, 0,
- codec ? codec->name : NULL))) {
- fprintf(stderr, "File for preset '%s' not found\n", arg);
- return 1;
- }
-
- while(!feof(f)){
- int e= fscanf(f, "%999[^\n]\n", line) - 1;
- if(line[0] == '#' && !e)
- continue;
- e|= sscanf(line, "%999[^=]=%999[^\n]\n", tmp, tmp2) - 2;
- if(e){
- fprintf(stderr, "%s: Invalid syntax: '%s'\n", filename, line);
- ret = 1;
- break;
- }
- if(!strcmp(tmp, "acodec")){
- *audio_id = opt_codec(tmp2, AVMEDIA_TYPE_AUDIO);
- }else if(!strcmp(tmp, "vcodec")){
- *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){
- fprintf(stderr, "%s: Invalid option or argument: '%s', parsed as '%s' = '%s'\n", filename, line, tmp, tmp2);
- ret = 1;
- break;
- }
- }
-
- fclose(f);
-
- return ret;
-}
-
-static AVOutputFormat *ffserver_guess_format(const char *short_name, const char *filename, const char *mime_type)
-{
- AVOutputFormat *fmt = av_guess_format(short_name, filename, mime_type);
-
- if (fmt) {
- AVOutputFormat *stream_fmt;
- char stream_format_name[64];
-
- snprintf(stream_format_name, sizeof(stream_format_name), "%s_stream", fmt->name);
- stream_fmt = av_guess_format(stream_format_name, NULL, NULL);
-
- if (stream_fmt)
- fmt = stream_fmt;
- }
-
- return fmt;
-}
-
-static void report_config_error(const char *filename, int line_num, int log_level, int *errors, const char *fmt, ...)
-{
- va_list vl;
- va_start(vl, fmt);
- av_log(NULL, log_level, "%s:%d: ", filename, line_num);
- av_vlog(NULL, log_level, fmt, vl);
- va_end(vl);
-
- (*errors)++;
-}
-
-static int parse_ffconfig(const char *filename)
-{
- FILE *f;
- char line[1024];
- char cmd[64];
- char arg[1024], arg2[1024];
- const char *p;
- int val, errors, warnings, line_num;
- FFStream **last_stream, *stream, *redirect;
- 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) {
- ret = AVERROR(errno);
- av_log(NULL, AV_LOG_ERROR, "Could not open the configuration file '%s'\n", filename);
- return ret;
- }
-
- errors = warnings = 0;
- line_num = 0;
- first_stream = NULL;
- last_stream = &first_stream;
- first_feed = NULL;
- last_feed = &first_feed;
- stream = NULL;
- feed = NULL;
- redirect = NULL;
- audio_id = AV_CODEC_ID_NONE;
- video_id = AV_CODEC_ID_NONE;
-#define ERROR(...) report_config_error(filename, line_num, AV_LOG_ERROR, &errors, __VA_ARGS__)
-#define WARNING(...) report_config_error(filename, line_num, AV_LOG_WARNING, &warnings, __VA_ARGS__)
-
- for(;;) {
- if (fgets(line, sizeof(line), f) == NULL)
- break;
- line_num++;
- p = line;
- while (av_isspace(*p))
- p++;
- if (*p == '\0' || *p == '#')
- continue;
-
- get_arg(cmd, sizeof(cmd), &p);
-
- if (!av_strcasecmp(cmd, "Port") || !av_strcasecmp(cmd, "HTTPPort")) {
- if (!av_strcasecmp(cmd, "Port"))
- WARNING("Port option is deprecated, use HTTPPort instead\n");
- get_arg(arg, sizeof(arg), &p);
- val = atoi(arg);
- if (val < 1 || val > 65536) {
- ERROR("Invalid port: %s\n", arg);
- }
- if (val < 1024)
- WARNING("Trying to use IETF assigned system port: %d\n", val);
- my_http_addr.sin_port = htons(val);
- } else if (!av_strcasecmp(cmd, "HTTPBindAddress") || !av_strcasecmp(cmd, "BindAddress")) {
- if (!av_strcasecmp(cmd, "BindAddress"))
- WARNING("BindAddress option is deprecated, use HTTPBindAddress instead\n");
- get_arg(arg, sizeof(arg), &p);
- if (resolve_host(&my_http_addr.sin_addr, arg) != 0) {
- ERROR("%s:%d: Invalid host/IP address: %s\n", arg);
- }
- } else if (!av_strcasecmp(cmd, "NoDaemon")) {
- WARNING("NoDaemon option has no effect, you should remove it\n");
- } else if (!av_strcasecmp(cmd, "RTSPPort")) {
- get_arg(arg, sizeof(arg), &p);
- val = atoi(arg);
- if (val < 1 || val > 65536) {
- ERROR("%s:%d: Invalid port: %s\n", arg);
- }
- my_rtsp_addr.sin_port = htons(atoi(arg));
- } else if (!av_strcasecmp(cmd, "RTSPBindAddress")) {
- get_arg(arg, sizeof(arg), &p);
- if (resolve_host(&my_rtsp_addr.sin_addr, arg) != 0) {
- ERROR("Invalid host/IP address: %s\n", arg);
- }
- } else if (!av_strcasecmp(cmd, "MaxHTTPConnections")) {
- get_arg(arg, sizeof(arg), &p);
- val = atoi(arg);
- if (val < 1 || val > 65536) {
- ERROR("Invalid MaxHTTPConnections: %s\n", arg);
- }
- nb_max_http_connections = val;
- } else if (!av_strcasecmp(cmd, "MaxClients")) {
- get_arg(arg, sizeof(arg), &p);
- val = atoi(arg);
- if (val < 1 || val > nb_max_http_connections) {
- ERROR("Invalid MaxClients: %s\n", arg);
- } else {
- nb_max_connections = val;
- }
- } else if (!av_strcasecmp(cmd, "MaxBandwidth")) {
- int64_t llval;
- get_arg(arg, sizeof(arg), &p);
- llval = strtoll(arg, NULL, 10);
- if (llval < 10 || llval > 10000000) {
- ERROR("Invalid MaxBandwidth: %s\n", arg);
- } else
- max_bandwidth = llval;
- } else if (!av_strcasecmp(cmd, "CustomLog")) {
- if (!ffserver_debug)
- get_arg(logfilename, sizeof(logfilename), &p);
- } else if (!av_strcasecmp(cmd, "<Feed")) {
- /*********************************************/
- /* Feed related options */
- char *q;
- if (stream || feed) {
- ERROR("Already in a tag\n");
- } else {
- feed = av_mallocz(sizeof(FFStream));
- if (!feed) {
- ret = AVERROR(ENOMEM);
- goto end;
- }
- get_arg(feed->filename, sizeof(feed->filename), &p);
- q = strrchr(feed->filename, '>');
- if (*q)
- *q = '\0';
-
- for (s = first_feed; s; s = s->next) {
- if (!strcmp(feed->filename, s->filename)) {
- ERROR("Feed '%s' already registered\n", s->filename);
- }
- }
-
- feed->fmt = av_guess_format("ffm", NULL, NULL);
- /* default feed file */
- snprintf(feed->feed_filename, sizeof(feed->feed_filename),
- "/tmp/%s.ffm", feed->filename);
- feed->feed_max_size = 5 * 1024 * 1024;
- feed->is_feed = 1;
- feed->feed = feed; /* self feeding :-) */
-
- /* add in stream list */
- *last_stream = feed;
- last_stream = &feed->next;
- /* add in feed list */
- *last_feed = feed;
- last_feed = &feed->next_feed;
- }
- } else if (!av_strcasecmp(cmd, "Launch")) {
- if (feed) {
- int i;
-
- feed->child_argv = av_mallocz(64 * sizeof(char *));
- 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);
- if (!feed->child_argv[i]) {
- ret = AVERROR(ENOMEM);
- goto end;
- }
- }
- } else if (!av_strcasecmp(cmd, "File") || !av_strcasecmp(cmd, "ReadOnlyFile")) {
- if (feed) {
- get_arg(feed->feed_filename, sizeof(feed->feed_filename), &p);
- feed->readonly = !av_strcasecmp(cmd, "ReadOnlyFile");
- } 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);
- /* assume Truncate is true in case no argument is specified */
- if (!arg[0]) {
- feed->truncate = 1;
- } else {
- 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) {
- char *p1;
- double fsize;
-
- get_arg(arg, sizeof(arg), &p);
- p1 = arg;
- fsize = strtod(p1, &p1);
- switch(av_toupper(*p1)) {
- case 'K':
- fsize *= 1024;
- break;
- case 'M':
- fsize *= 1024 * 1024;
- break;
- case 'G':
- fsize *= 1024 * 1024 * 1024;
- break;
- }
- feed->feed_max_size = (int64_t)fsize;
- if (feed->feed_max_size < FFM_PACKET_SIZE*4) {
- ERROR("Feed max file size is too small, must be at least %d\n", FFM_PACKET_SIZE*4);
- }
- }
- } else if (!av_strcasecmp(cmd, "</Feed>")) {
- if (!feed) {
- ERROR("No corresponding <Feed> for </Feed>\n");
- }
- feed = NULL;
- } else if (!av_strcasecmp(cmd, "<Stream")) {
- /*********************************************/
- /* Stream related options */
- char *q;
- if (stream || feed) {
- ERROR("Already in a tag\n");
- } else {
- FFStream *s;
- stream = av_mallocz(sizeof(FFStream));
- if (!stream) {
- ret = AVERROR(ENOMEM);
- goto end;
- }
- get_arg(stream->filename, sizeof(stream->filename), &p);
- q = strrchr(stream->filename, '>');
- if (q)
- *q = '\0';
-
- for (s = first_stream; s; s = s->next) {
- if (!strcmp(stream->filename, s->filename)) {
- ERROR("Stream '%s' already registered\n", s->filename);
- }
- }
-
- stream->fmt = ffserver_guess_format(NULL, stream->filename, NULL);
- avcodec_get_context_defaults3(&video_enc, NULL);
- avcodec_get_context_defaults3(&audio_enc, NULL);
-
- audio_id = AV_CODEC_ID_NONE;
- video_id = AV_CODEC_ID_NONE;
- if (stream->fmt) {
- audio_id = stream->fmt->audio_codec;
- video_id = stream->fmt->video_codec;
- }
-
- *last_stream = stream;
- last_stream = &stream->next;
- }
- } else if (!av_strcasecmp(cmd, "Feed")) {
- get_arg(arg, sizeof(arg), &p);
- if (stream) {
- FFStream *sfeed;
-
- sfeed = first_feed;
- while (sfeed) {
- if (!strcmp(sfeed->filename, arg))
- break;
- sfeed = sfeed->next_feed;
- }
- if (!sfeed)
- ERROR("Feed with name '%s' for stream '%s' is not defined\n", arg, stream->filename);
- else
- stream->feed = sfeed;
- }
- } else if (!av_strcasecmp(cmd, "Format")) {
- get_arg(arg, sizeof(arg), &p);
- if (stream) {
- if (!strcmp(arg, "status")) {
- stream->stream_type = STREAM_TYPE_STATUS;
- stream->fmt = NULL;
- } else {
- stream->stream_type = STREAM_TYPE_LIVE;
- /* JPEG cannot be used here, so use single frame MJPEG */
- if (!strcmp(arg, "jpeg"))
- strcpy(arg, "mjpeg");
- stream->fmt = ffserver_guess_format(arg, NULL, NULL);
- if (!stream->fmt) {
- ERROR("Unknown Format: %s\n", arg);
- }
- }
- if (stream->fmt) {
- audio_id = stream->fmt->audio_codec;
- video_id = stream->fmt->video_codec;
- }
- }
- } else if (!av_strcasecmp(cmd, "InputFormat")) {
- get_arg(arg, sizeof(arg), &p);
- if (stream) {
- stream->ifmt = av_find_input_format(arg);
- if (!stream->ifmt) {
- ERROR("Unknown input format: %s\n", arg);
- }
- }
- } else if (!av_strcasecmp(cmd, "FaviconURL")) {
- if (stream && stream->stream_type == STREAM_TYPE_STATUS) {
- get_arg(stream->feed_filename, sizeof(stream->feed_filename), &p);
- } else {
- ERROR("FaviconURL only permitted for status streams\n");
- }
- } else if (!av_strcasecmp(cmd, "Author") ||
- !av_strcasecmp(cmd, "Comment") ||
- !av_strcasecmp(cmd, "Copyright") ||
- !av_strcasecmp(cmd, "Title")) {
- get_arg(arg, sizeof(arg), &p);
-
- if (stream) {
- char key[32];
- int i, ret;
-
- for (i = 0; i < strlen(cmd); i++)
- key[i] = av_tolower(cmd[i]);
- key[i] = 0;
- WARNING("'%s' option in configuration file is deprecated, "
- "use 'Metadata %s VALUE' instead\n", cmd, key);
- if ((ret = av_dict_set(&stream->metadata, key, arg, 0)) < 0) {
- ERROR("Could not set metadata '%s' to value '%s': %s\n",
- key, arg, av_err2str(ret));
- }
- }
- } else if (!av_strcasecmp(cmd, "Metadata")) {
- get_arg(arg, sizeof(arg), &p);
- get_arg(arg2, sizeof(arg2), &p);
- if (stream) {
- int ret;
- if ((ret = av_dict_set(&stream->metadata, arg, arg2, 0)) < 0) {
- ERROR("Could not set metadata '%s' to value '%s': %s\n",
- arg, arg2, av_err2str(ret));
- }
- }
- } else if (!av_strcasecmp(cmd, "Preroll")) {
- get_arg(arg, sizeof(arg), &p);
- if (stream)
- stream->prebuffer = atof(arg) * 1000;
- } else if (!av_strcasecmp(cmd, "StartSendOnKey")) {
- if (stream)
- stream->send_on_key = 1;
- } else if (!av_strcasecmp(cmd, "AudioCodec")) {
- get_arg(arg, sizeof(arg), &p);
- audio_id = opt_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_codec(arg, AVMEDIA_TYPE_VIDEO);
- if (video_id == AV_CODEC_ID_NONE) {
- ERROR("Unknown VideoCodec: %s\n", arg);
- }
- } else if (!av_strcasecmp(cmd, "MaxTime")) {
- get_arg(arg, sizeof(arg), &p);
- if (stream)
- stream->max_time = atof(arg) * 1000;
- } else if (!av_strcasecmp(cmd, "AudioBitRate")) {
- get_arg(arg, sizeof(arg), &p);
- if (stream)
- audio_enc.bit_rate = lrintf(atof(arg) * 1000);
- } else if (!av_strcasecmp(cmd, "AudioChannels")) {
- get_arg(arg, sizeof(arg), &p);
- if (stream)
- audio_enc.channels = atoi(arg);
- } else if (!av_strcasecmp(cmd, "AudioSampleRate")) {
- get_arg(arg, sizeof(arg), &p);
- if (stream)
- audio_enc.sample_rate = atoi(arg);
- } else if (!av_strcasecmp(cmd, "VideoBitRateRange")) {
- if (stream) {
- int minrate, maxrate;
-
- get_arg(arg, sizeof(arg), &p);
-
- if (sscanf(arg, "%d-%d", &minrate, &maxrate) == 2) {
- video_enc.rc_min_rate = minrate * 1000;
- video_enc.rc_max_rate = maxrate * 1000;
- } else {
- ERROR("Incorrect format for VideoBitRateRange -- should be <min>-<max>: %s\n", arg);
- }
- }
- } else if (!av_strcasecmp(cmd, "Debug")) {
- if (stream) {
- get_arg(arg, sizeof(arg), &p);
- video_enc.debug = strtol(arg,0,0);
- }
- } else if (!av_strcasecmp(cmd, "Strict")) {
- if (stream) {
- get_arg(arg, sizeof(arg), &p);
- video_enc.strict_std_compliance = atoi(arg);
- }
- } else if (!av_strcasecmp(cmd, "VideoBufferSize")) {
- if (stream) {
- get_arg(arg, sizeof(arg), &p);
- video_enc.rc_buffer_size = atoi(arg) * 8*1024;
- }
- } else if (!av_strcasecmp(cmd, "VideoBitRateTolerance")) {
- if (stream) {
- get_arg(arg, sizeof(arg), &p);
- video_enc.bit_rate_tolerance = atoi(arg) * 1000;
- }
- } else if (!av_strcasecmp(cmd, "VideoBitRate")) {
- get_arg(arg, sizeof(arg), &p);
- if (stream) {
- video_enc.bit_rate = atoi(arg) * 1000;
- }
- } else if (!av_strcasecmp(cmd, "VideoSize")) {
- get_arg(arg, sizeof(arg), &p);
- if (stream) {
- 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")) {
- get_arg(arg, sizeof(arg), &p);
- if (stream) {
- AVRational frame_rate;
- if (av_parse_video_rate(&frame_rate, arg) < 0) {
- ERROR("Incorrect frame rate: %s\n", arg);
- } else {
- video_enc.time_base.num = frame_rate.den;
- video_enc.time_base.den = frame_rate.num;
- }
- }
- } else if (!av_strcasecmp(cmd, "PixelFormat")) {
- get_arg(arg, sizeof(arg), &p);
- if (stream) {
- video_enc.pix_fmt = av_get_pix_fmt(arg);
- if (video_enc.pix_fmt == AV_PIX_FMT_NONE) {
- ERROR("Unknown pixel format: %s\n", arg);
- }
- }
- } else if (!av_strcasecmp(cmd, "VideoGopSize")) {
- get_arg(arg, sizeof(arg), &p);
- if (stream)
- video_enc.gop_size = atoi(arg);
- } else if (!av_strcasecmp(cmd, "VideoIntraOnly")) {
- if (stream)
- video_enc.gop_size = 1;
- } else if (!av_strcasecmp(cmd, "VideoHighQuality")) {
- if (stream)
- video_enc.mb_decision = FF_MB_DECISION_BITS;
- } else if (!av_strcasecmp(cmd, "Video4MotionVector")) {
- if (stream) {
- video_enc.mb_decision = FF_MB_DECISION_BITS; //FIXME remove
- video_enc.flags |= CODEC_FLAG_4MV;
- }
- } else if (!av_strcasecmp(cmd, "AVOptionVideo") ||
- !av_strcasecmp(cmd, "AVOptionAudio")) {
- AVCodecContext *avctx;
- int type;
- get_arg(arg, sizeof(arg), &p);
- get_arg(arg2, sizeof(arg2), &p);
- if (!av_strcasecmp(cmd, "AVOptionVideo")) {
- avctx = &video_enc;
- type = AV_OPT_FLAG_VIDEO_PARAM;
- } else {
- avctx = &audio_enc;
- type = AV_OPT_FLAG_AUDIO_PARAM;
- }
- if (ffserver_opt_default(arg, arg2, avctx, type|AV_OPT_FLAG_ENCODING_PARAM)) {
- ERROR("Error setting %s option to %s %s\n", cmd, arg, arg2);
- }
- } else if (!av_strcasecmp(cmd, "AVPresetVideo") ||
- !av_strcasecmp(cmd, "AVPresetAudio")) {
- AVCodecContext *avctx;
- int type;
- get_arg(arg, sizeof(arg), &p);
- if (!av_strcasecmp(cmd, "AVPresetVideo")) {
- avctx = &video_enc;
- video_enc.codec_id = video_id;
- type = AV_OPT_FLAG_VIDEO_PARAM;
- } else {
- avctx = &audio_enc;
- audio_enc.codec_id = audio_id;
- type = AV_OPT_FLAG_AUDIO_PARAM;
- }
- if (ffserver_opt_preset(arg, avctx, type|AV_OPT_FLAG_ENCODING_PARAM, &audio_id, &video_id)) {
- ERROR("AVPreset error: %s\n", arg);
- }
- } else if (!av_strcasecmp(cmd, "VideoTag")) {
- get_arg(arg, sizeof(arg), &p);
- if ((strlen(arg) == 4) && stream)
- video_enc.codec_tag = MKTAG(arg[0], arg[1], arg[2], arg[3]);
- } else if (!av_strcasecmp(cmd, "BitExact")) {
- if (stream)
- video_enc.flags |= CODEC_FLAG_BITEXACT;
- } else if (!av_strcasecmp(cmd, "DctFastint")) {
- if (stream)
- video_enc.dct_algo = FF_DCT_FASTINT;
- } else if (!av_strcasecmp(cmd, "IdctSimple")) {
- if (stream)
- video_enc.idct_algo = FF_IDCT_SIMPLE;
- } else if (!av_strcasecmp(cmd, "Qscale")) {
- get_arg(arg, sizeof(arg), &p);
- if (stream) {
- video_enc.flags |= CODEC_FLAG_QSCALE;
- video_enc.global_quality = FF_QP2LAMBDA * atoi(arg);
- }
- } else if (!av_strcasecmp(cmd, "VideoQDiff")) {
- get_arg(arg, sizeof(arg), &p);
- if (stream) {
- video_enc.max_qdiff = atoi(arg);
- if (video_enc.max_qdiff < 1 || video_enc.max_qdiff > 31) {
- ERROR("VideoQDiff out of range\n");
- }
- }
- } else if (!av_strcasecmp(cmd, "VideoQMax")) {
- get_arg(arg, sizeof(arg), &p);
- if (stream) {
- video_enc.qmax = atoi(arg);
- if (video_enc.qmax < 1 || video_enc.qmax > 31) {
- ERROR("VideoQMax out of range\n");
- }
- }
- } else if (!av_strcasecmp(cmd, "VideoQMin")) {
- get_arg(arg, sizeof(arg), &p);
- if (stream) {
- video_enc.qmin = atoi(arg);
- if (video_enc.qmin < 1 || video_enc.qmin > 31) {
- ERROR("VideoQMin out of range\n");
- }
- }
- } else if (!av_strcasecmp(cmd, "LumiMask")) {
- get_arg(arg, sizeof(arg), &p);
- if (stream)
- video_enc.lumi_masking = atof(arg);
- } else if (!av_strcasecmp(cmd, "DarkMask")) {
- get_arg(arg, sizeof(arg), &p);
- if (stream)
- video_enc.dark_masking = atof(arg);
- } else if (!av_strcasecmp(cmd, "NoVideo")) {
- video_id = AV_CODEC_ID_NONE;
- } else if (!av_strcasecmp(cmd, "NoAudio")) {
- audio_id = AV_CODEC_ID_NONE;
- } else if (!av_strcasecmp(cmd, "ACL")) {
- parse_acl_row(stream, feed, NULL, p, filename, line_num);
- } else if (!av_strcasecmp(cmd, "DynamicACL")) {
- if (stream) {
- get_arg(stream->dynamic_acl, sizeof(stream->dynamic_acl), &p);
- }
- } else if (!av_strcasecmp(cmd, "RTSPOption")) {
- get_arg(arg, sizeof(arg), &p);
- if (stream) {
- av_freep(&stream->rtsp_option);
- stream->rtsp_option = av_strdup(arg);
- }
- } else if (!av_strcasecmp(cmd, "MulticastAddress")) {
- get_arg(arg, sizeof(arg), &p);
- if (stream) {
- if (resolve_host(&stream->multicast_ip, arg) != 0) {
- ERROR("Invalid host/IP address: %s\n", arg);
- }
- stream->is_multicast = 1;
- stream->loop = 1; /* default is looping */
- }
- } else if (!av_strcasecmp(cmd, "MulticastPort")) {
- get_arg(arg, sizeof(arg), &p);
- if (stream)
- stream->multicast_port = atoi(arg);
- } else if (!av_strcasecmp(cmd, "MulticastTTL")) {
- get_arg(arg, sizeof(arg), &p);
- if (stream)
- stream->multicast_ttl = atoi(arg);
- } else if (!av_strcasecmp(cmd, "NoLoop")) {
- if (stream)
- stream->loop = 0;
- } else if (!av_strcasecmp(cmd, "</Stream>")) {
- if (!stream) {
- ERROR("No corresponding <Stream> for </Stream>\n");
- } else {
- if (stream->feed && stream->fmt && strcmp(stream->fmt->name, "ffm") != 0) {
- if (audio_id != AV_CODEC_ID_NONE) {
- audio_enc.codec_type = AVMEDIA_TYPE_AUDIO;
- audio_enc.codec_id = audio_id;
- add_codec(stream, &audio_enc);
- }
- if (video_id != AV_CODEC_ID_NONE) {
- video_enc.codec_type = AVMEDIA_TYPE_VIDEO;
- video_enc.codec_id = video_id;
- add_codec(stream, &video_enc);
- }
- }
- stream = NULL;
- }
- } else if (!av_strcasecmp(cmd, "<Redirect")) {
- /*********************************************/
- char *q;
- if (stream || feed || redirect) {
- ERROR("Already in a tag\n");
- } else {
- redirect = av_mallocz(sizeof(FFStream));
- if (!redirect) {
- ret = AVERROR(ENOMEM);
- goto end;
- }
- *last_stream = redirect;
- last_stream = &redirect->next;
-
- get_arg(redirect->filename, sizeof(redirect->filename), &p);
- q = strrchr(redirect->filename, '>');
- if (*q)
- *q = '\0';
- redirect->stream_type = STREAM_TYPE_REDIRECT;
- }
- } else if (!av_strcasecmp(cmd, "URL")) {
- if (redirect)
- get_arg(redirect->feed_filename, sizeof(redirect->feed_filename), &p);
- } else if (!av_strcasecmp(cmd, "</Redirect>")) {
- if (!redirect) {
- ERROR("No corresponding <Redirect> for </Redirect>\n");
- } else {
- if (!redirect->feed_filename[0]) {
- ERROR("No URL found for <Redirect>\n");
- }
- redirect = NULL;
- }
- } else if (!av_strcasecmp(cmd, "LoadModule")) {
- ERROR("Loadable modules no longer supported\n");
- } else {
- ERROR("Incorrect keyword: '%s'\n", cmd);
- }
- }
-#undef ERROR
-
-end:
- fclose(f);
- if (ret < 0)
- return ret;
- if (errors)
- return AVERROR(EINVAL);
- else
- return 0;
-}
-
static void handle_child_exit(int sig)
{
pid_t pid;
int status;
while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
- FFStream *feed;
+ FFServerStream *feed;
- for (feed = first_feed; feed; feed = feed->next) {
+ for (feed = config.first_feed; feed; feed = feed->next) {
if (feed->pid == pid) {
int uptime = time(0) - feed->pid_start;
if (uptime < 30)
/* Turn off any more restarts */
- feed->child_argv = 0;
+ ffserver_free_child_args(&feed->child_argv);
}
}
}
static void opt_debug(void)
{
- ffserver_debug = 1;
- logfilename[0] = '-';
+ config.debug = 1;
+ snprintf(config.logfilename, sizeof(config.logfilename), "-");
}
void show_help_default(const char *opt, const char *arg)
#include "cmdutils_common_opts.h"
{ "n", OPT_BOOL, {(void *)&no_launch }, "enable no-launch mode" },
{ "d", 0, {(void*)opt_debug}, "enable debug mode" },
- { "f", HAS_ARG | OPT_STRING, {(void*)&config_filename }, "use configfile instead of /etc/ffserver.conf", "configfile" },
+ { "f", HAS_ARG | OPT_STRING, {(void*)&config.filename }, "use configfile instead of /etc/ffserver.conf", "configfile" },
{ NULL },
};
struct sigaction sigact = { { 0 } };
int ret = 0;
- config_filename = av_strdup("/etc/ffserver.conf");
+ config.filename = av_strdup("/etc/ffserver.conf");
parse_loglevel(argc, argv, options);
av_register_all();
sigact.sa_flags = SA_NOCLDSTOP | SA_RESTART;
sigaction(SIGCHLD, &sigact, 0);
- if ((ret = parse_ffconfig(config_filename)) < 0) {
+ if ((ret = ffserver_parse_ffconfig(config.filename, &config)) < 0) {
fprintf(stderr, "Error reading configuration file '%s': %s\n",
- config_filename, av_err2str(ret));
+ config.filename, av_err2str(ret));
exit(1);
}
- av_freep(&config_filename);
+ av_freep(&config.filename);
/* open log file if needed */
- if (logfilename[0] != '\0') {
- if (!strcmp(logfilename, "-"))
+ if (config.logfilename[0] != '\0') {
+ if (!strcmp(config.logfilename, "-"))
logfile = stdout;
else
- logfile = fopen(logfilename, "a");
+ logfile = fopen(config.logfilename, "a");
av_log_set_callback(http_av_log);
}
--- /dev/null
+/*
+ * Copyright (c) 2000, 2001, 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
+ */
+
+#include <float.h>
+#include "libavutil/opt.h"
+#include "libavutil/parseutils.h"
+#include "libavutil/avstring.h"
+#include "libavutil/pixdesc.h"
+#include "libavutil/avassert.h"
+
+// FIXME those are internal headers, ffserver _really_ shouldn't use them
+#include "libavformat/ffm.h"
+
+#include "cmdutils.h"
+#include "ffserver_config.h"
+
+#define MAX_CHILD_ARGS 64
+
+static int ffserver_save_avoption(const char *opt, const char *arg, int type,
+ FFServerConfig *config);
+static void vreport_config_error(const char *filename, int line_num, int log_level,
+ int *errors, const char *fmt, va_list vl);
+static void report_config_error(const char *filename, int line_num, int log_level,
+ int *errors, const char *fmt, ...);
+
+#define ERROR(...) report_config_error(config->filename, config->line_num,\
+ AV_LOG_ERROR, &config->errors, __VA_ARGS__)
+#define WARNING(...) report_config_error(config->filename, config->line_num,\
+ AV_LOG_WARNING, &config->warnings, __VA_ARGS__)
+
+/* FIXME: make ffserver work with IPv6 */
+/* resolve host with also IP address parsing */
+static int resolve_host(struct in_addr *sin_addr, const char *hostname)
+{
+
+ if (!ff_inet_aton(hostname, sin_addr)) {
+#if HAVE_GETADDRINFO
+ struct addrinfo *ai, *cur;
+ struct addrinfo hints = { 0 };
+ hints.ai_family = AF_INET;
+ if (getaddrinfo(hostname, NULL, &hints, &ai))
+ return -1;
+ /* getaddrinfo returns a linked list of addrinfo structs.
+ * Even if we set ai_family = AF_INET above, make sure
+ * that the returned one actually is of the correct type. */
+ for (cur = ai; cur; cur = cur->ai_next) {
+ if (cur->ai_family == AF_INET) {
+ *sin_addr = ((struct sockaddr_in *)cur->ai_addr)->sin_addr;
+ freeaddrinfo(ai);
+ return 0;
+ }
+ }
+ freeaddrinfo(ai);
+ return -1;
+#else
+ struct hostent *hp;
+ hp = gethostbyname(hostname);
+ if (!hp)
+ return -1;
+ memcpy(sin_addr, hp->h_addr_list[0], sizeof(struct in_addr));
+#endif
+ }
+ return 0;
+}
+
+void ffserver_get_arg(char *buf, int buf_size, const char **pp)
+{
+ const char *p;
+ char *q;
+ int quote;
+
+ p = *pp;
+ while (av_isspace(*p)) p++;
+ q = buf;
+ quote = 0;
+ if (*p == '\"' || *p == '\'')
+ quote = *p++;
+ for(;;) {
+ if (quote) {
+ if (*p == quote)
+ break;
+ } else {
+ if (av_isspace(*p))
+ break;
+ }
+ if (*p == '\0')
+ break;
+ if ((q - buf) < buf_size - 1)
+ *q++ = *p;
+ p++;
+ }
+ *q = '\0';
+ if (quote && *p == quote)
+ p++;
+ *pp = p;
+}
+
+void ffserver_parse_acl_row(FFServerStream *stream, FFServerStream* feed,
+ FFServerIPAddressACL *ext_acl,
+ const char *p, const char *filename, int line_num)
+{
+ char arg[1024];
+ FFServerIPAddressACL acl;
+ int errors = 0;
+
+ ffserver_get_arg(arg, sizeof(arg), &p);
+ if (av_strcasecmp(arg, "allow") == 0)
+ acl.action = IP_ALLOW;
+ else if (av_strcasecmp(arg, "deny") == 0)
+ acl.action = IP_DENY;
+ else {
+ fprintf(stderr, "%s:%d: ACL action '%s' is not ALLOW or DENY\n",
+ filename, line_num, arg);
+ errors++;
+ }
+
+ ffserver_get_arg(arg, sizeof(arg), &p);
+
+ if (resolve_host(&acl.first, arg)) {
+ fprintf(stderr, "%s:%d: ACL refers to invalid host or IP address '%s'\n",
+ filename, line_num, arg);
+ errors++;
+ } else
+ acl.last = acl.first;
+
+ ffserver_get_arg(arg, sizeof(arg), &p);
+
+ if (arg[0]) {
+ if (resolve_host(&acl.last, arg)) {
+ fprintf(stderr,
+ "%s:%d: ACL refers to invalid host or IP address '%s'\n",
+ filename, line_num, arg);
+ errors++;
+ }
+ }
+
+ if (!errors) {
+ FFServerIPAddressACL *nacl = av_mallocz(sizeof(*nacl));
+ FFServerIPAddressACL **naclp = 0;
+
+ acl.next = 0;
+ *nacl = acl;
+
+ if (stream)
+ naclp = &stream->acl;
+ else if (feed)
+ naclp = &feed->acl;
+ else if (ext_acl)
+ naclp = &ext_acl;
+ else {
+ fprintf(stderr, "%s:%d: ACL found not in <stream> or <feed>\n",
+ filename, line_num);
+ errors++;
+ }
+
+ if (naclp) {
+ while (*naclp)
+ naclp = &(*naclp)->next;
+
+ *naclp = nacl;
+ } else
+ av_free(nacl);
+ }
+}
+
+/* add a codec and set the default parameters */
+static void add_codec(FFServerStream *stream, AVCodecContext *av,
+ FFServerConfig *config)
+{
+ AVStream *st;
+ AVDictionary **opts, *recommended = NULL;
+ char *enc_config;
+
+ if(stream->nb_streams >= FF_ARRAY_ELEMS(stream->streams))
+ return;
+
+ opts = av->codec_type == AVMEDIA_TYPE_AUDIO ?
+ &config->audio_opts : &config->video_opts;
+ av_dict_copy(&recommended, *opts, 0);
+ av_opt_set_dict2(av->priv_data, opts, AV_OPT_SEARCH_CHILDREN);
+ av_opt_set_dict2(av, opts, AV_OPT_SEARCH_CHILDREN);
+ if (av_dict_count(*opts))
+ av_log(NULL, AV_LOG_WARNING,
+ "Something is wrong, %d options are not set!\n", av_dict_count(*opts));
+
+ if (config->stream_use_defaults) {
+ //TODO: reident
+ /* compute default parameters */
+ switch(av->codec_type) {
+ case AVMEDIA_TYPE_AUDIO:
+ if (!av_dict_get(recommended, "ab", NULL, 0)) {
+ av->bit_rate = 64000;
+ av_dict_set_int(&recommended, "ab", av->bit_rate, 0);
+ WARNING("Setting default value for audio bit rate = %d. "
+ "Use NoDefaults to disable it.\n",
+ av->bit_rate);
+ }
+ if (!av_dict_get(recommended, "ar", NULL, 0)) {
+ av->sample_rate = 22050;
+ av_dict_set_int(&recommended, "ar", av->sample_rate, 0);
+ WARNING("Setting default value for audio sample rate = %d. "
+ "Use NoDefaults to disable it.\n",
+ av->sample_rate);
+ }
+ if (!av_dict_get(recommended, "ac", NULL, 0)) {
+ av->channels = 1;
+ av_dict_set_int(&recommended, "ac", av->channels, 0);
+ WARNING("Setting default value for audio channel count = %d. "
+ "Use NoDefaults to disable it.\n",
+ av->channels);
+ }
+ break;
+ case AVMEDIA_TYPE_VIDEO:
+ if (!av_dict_get(recommended, "b", NULL, 0)) {
+ av->bit_rate = 64000;
+ av_dict_set_int(&recommended, "b", av->bit_rate, 0);
+ WARNING("Setting default value for video bit rate = %d. "
+ "Use NoDefaults to disable it.\n",
+ av->bit_rate);
+ }
+ if (!av_dict_get(recommended, "time_base", NULL, 0)){
+ av->time_base.den = 5;
+ av->time_base.num = 1;
+ av_dict_set(&recommended, "time_base", "1/5", 0);
+ WARNING("Setting default value for video frame rate = %d. "
+ "Use NoDefaults to disable it.\n",
+ av->time_base.den);
+ }
+ if (!av_dict_get(recommended, "video_size", NULL, 0)) {
+ av->width = 160;
+ av->height = 128;
+ av_dict_set(&recommended, "video_size", "160x128", 0);
+ WARNING("Setting default value for video size = %dx%d. "
+ "Use NoDefaults to disable it.\n",
+ av->width, av->height);
+ }
+ /* Bitrate tolerance is less for streaming */
+ if (!av_dict_get(recommended, "bt", NULL, 0)) {
+ av->bit_rate_tolerance = FFMAX(av->bit_rate / 4,
+ (int64_t)av->bit_rate*av->time_base.num/av->time_base.den);
+ av_dict_set_int(&recommended, "bt", av->bit_rate_tolerance, 0);
+ WARNING("Setting default value for video bit rate tolerance = %d. "
+ "Use NoDefaults to disable it.\n",
+ av->bit_rate_tolerance);
+ }
+
+ if (!av_dict_get(recommended, "rc_eq", NULL, 0)) {
+ av->rc_eq = av_strdup("tex^qComp");
+ av_dict_set(&recommended, "rc_eq", "tex^qComp", 0);
+ WARNING("Setting default value for video rate control equation = %s. "
+ "Use NoDefaults to disable it.\n",
+ av->rc_eq);
+ }
+ if (!av_dict_get(recommended, "maxrate", NULL, 0)) {
+ av->rc_max_rate = av->bit_rate * 2;
+ av_dict_set_int(&recommended, "maxrate", av->rc_max_rate, 0);
+ WARNING("Setting default value for video max rate = %d. "
+ "Use NoDefaults to disable it.\n",
+ av->rc_max_rate);
+ }
+
+ if (av->rc_max_rate && !av_dict_get(recommended, "bufsize", NULL, 0)) {
+ av->rc_buffer_size = av->rc_max_rate;
+ av_dict_set_int(&recommended, "bufsize", av->rc_buffer_size, 0);
+ WARNING("Setting default value for video buffer size = %d. "
+ "Use NoDefaults to disable it.\n",
+ av->rc_buffer_size);
+ }
+ break;
+ default:
+ abort();
+ }
+ } else {
+ switch(av->codec_type) {
+ case AVMEDIA_TYPE_AUDIO:
+ if (av->bit_rate == 0)
+ report_config_error(config->filename, config->line_num, AV_LOG_ERROR,
+ &config->errors, "audio bit rate is not set\n");
+ if (av->sample_rate == 0)
+ report_config_error(config->filename, config->line_num, AV_LOG_ERROR,
+ &config->errors, "audio sample rate is not set\n");
+ break;
+ case AVMEDIA_TYPE_VIDEO:
+ if (av->width == 0 || av->height == 0)
+ report_config_error(config->filename, config->line_num, AV_LOG_ERROR,
+ &config->errors, "video size is not set\n");
+ break;
+ default:
+ av_assert0(0);
+ }
+ }
+
+ st = av_mallocz(sizeof(AVStream));
+ if (!st)
+ return;
+ av_dict_get_string(recommended, &enc_config, '=', ',');
+ av_dict_free(&recommended);
+ av_stream_set_recommended_encoder_configuration(st, enc_config);
+ st->codec = av;
+ stream->streams[stream->nb_streams++] = st;
+}
+
+static int ffserver_set_codec(AVCodecContext *ctx, const char *codec_name, FFServerConfig *config)
+{
+ int ret;
+ AVCodec *codec = avcodec_find_encoder_by_name(codec_name);
+ if (!codec || codec->type != ctx->codec_type) {
+ report_config_error(config->filename, config->line_num, AV_LOG_ERROR,
+ &config->errors, "Invalid codec name: %s\n", codec_name);
+ return 0;
+ }
+ if (ctx->codec_id == AV_CODEC_ID_NONE && !ctx->priv_data) {
+ if ((ret = avcodec_get_context_defaults3(ctx, codec)) < 0)
+ return ret;
+ ctx->codec = codec;
+ }
+ if (ctx->codec_id != codec->id)
+ report_config_error(config->filename, config->line_num, AV_LOG_ERROR, &config->errors,
+ "Inconsistent configuration: trying to set %s codec option, but %s codec is used previously\n",
+ codec_name, avcodec_get_name(ctx->codec_id));
+ return 0;
+}
+
+static int ffserver_opt_preset(const char *arg, int type, FFServerConfig *config)
+{
+ FILE *f=NULL;
+ char filename[1000], tmp[1000], tmp2[1000], line[1000];
+ int ret = 0;
+ AVCodecContext *avctx;
+ const AVCodec *codec;
+
+ switch(type) {
+ case AV_OPT_FLAG_AUDIO_PARAM:
+ avctx = config->dummy_actx;
+ break;
+ case AV_OPT_FLAG_VIDEO_PARAM:
+ avctx = config->dummy_vctx;
+ break;
+ default:
+ av_assert0(0);
+ }
+ codec = avcodec_find_encoder(avctx->codec_id);
+
+ if (!(f = get_preset_file(filename, sizeof(filename), arg, 0,
+ codec ? codec->name : NULL))) {
+ av_log(NULL, AV_LOG_ERROR, "File for preset '%s' not found\n", arg);
+ return AVERROR(EINVAL);
+ }
+
+ while(!feof(f)){
+ int e= fscanf(f, "%999[^\n]\n", line) - 1;
+ if(line[0] == '#' && !e)
+ continue;
+ e|= sscanf(line, "%999[^=]=%999[^\n]\n", tmp, tmp2) - 2;
+ if(e){
+ av_log(NULL, AV_LOG_ERROR, "%s: Invalid syntax: '%s'\n", filename, line);
+ ret = AVERROR(EINVAL);
+ break;
+ }
+ if ((!strcmp(tmp, "acodec") && avctx->codec_type == AVMEDIA_TYPE_AUDIO) ||
+ !strcmp(tmp, "vcodec") && avctx->codec_type == AVMEDIA_TYPE_VIDEO)
+ {
+ if (ffserver_set_codec(avctx, tmp2, config) < 0)
+ break;
+ } else if (!strcmp(tmp, "scodec")) {
+ av_log(NULL, AV_LOG_ERROR, "Subtitles preset found.\n");
+ ret = AVERROR(EINVAL);
+ break;
+ } else if (ffserver_save_avoption(tmp, tmp2, type, config) < 0)
+ break;
+ }
+
+ fclose(f);
+
+ return ret;
+}
+
+static AVOutputFormat *ffserver_guess_format(const char *short_name, const char *filename, const char *mime_type)
+{
+ AVOutputFormat *fmt = av_guess_format(short_name, filename, mime_type);
+
+ if (fmt) {
+ AVOutputFormat *stream_fmt;
+ char stream_format_name[64];
+
+ snprintf(stream_format_name, sizeof(stream_format_name), "%s_stream",
+ fmt->name);
+ stream_fmt = av_guess_format(stream_format_name, NULL, NULL);
+
+ if (stream_fmt)
+ fmt = stream_fmt;
+ }
+
+ return fmt;
+}
+
+static void vreport_config_error(const char *filename, int line_num, int log_level, int *errors, const char *fmt, va_list vl)
+{
+ av_log(NULL, log_level, "%s:%d: ", filename, line_num);
+ av_vlog(NULL, log_level, fmt, vl);
+ if (errors)
+ (*errors)++;
+}
+
+static void report_config_error(const char *filename, int line_num, int log_level, int *errors, const char *fmt, ...)
+{
+ va_list vl;
+ va_start(vl, fmt);
+ vreport_config_error(filename, line_num, log_level, errors, fmt, vl);
+ va_end(vl);
+}
+
+static int ffserver_set_int_param(int *dest, const char *value, int factor, int min, int max,
+ FFServerConfig *config, const char *error_msg, ...)
+{
+ int tmp;
+ char *tailp;
+ if (!value || !value[0])
+ goto error;
+ errno = 0;
+ tmp = strtol(value, &tailp, 0);
+ if (tmp < min || tmp > max)
+ goto error;
+ if (factor) {
+ if (FFABS(tmp) > INT_MAX / FFABS(factor))
+ goto error;
+ tmp *= factor;
+ }
+ if (tailp[0] || errno)
+ goto error;
+ if (dest)
+ *dest = tmp;
+ return 0;
+ error:
+ if (config) {
+ va_list vl;
+ va_start(vl, error_msg);
+ vreport_config_error(config->filename, config->line_num, AV_LOG_ERROR,
+ &config->errors, error_msg, vl);
+ va_end(vl);
+ }
+ return AVERROR(EINVAL);
+}
+
+static int ffserver_set_float_param(float *dest, const char *value, float factor, float min, float max,
+ FFServerConfig *config, const char *error_msg, ...)
+{
+ double tmp;
+ char *tailp;
+ if (!value || !value[0])
+ goto error;
+ errno = 0;
+ tmp = strtod(value, &tailp);
+ if (tmp < min || tmp > max)
+ goto error;
+ if (factor)
+ tmp *= factor;
+ if (tailp[0] || errno)
+ goto error;
+ if (dest)
+ *dest = tmp;
+ return 0;
+ error:
+ if (config) {
+ va_list vl;
+ va_start(vl, error_msg);
+ vreport_config_error(config->filename, config->line_num, AV_LOG_ERROR,
+ &config->errors, error_msg, vl);
+ va_end(vl);
+ }
+ return AVERROR(EINVAL);
+}
+
+static int ffserver_save_avoption(const char *opt, const char *arg, int type, FFServerConfig *config)
+{
+ static int hinted = 0;
+ int ret = 0;
+ AVDictionaryEntry *e;
+ const AVOption *o = NULL;
+ const char *option = NULL;
+ const char *codec_name = NULL;
+ char buff[1024];
+ AVCodecContext *ctx;
+ AVDictionary **dict;
+ enum AVCodecID guessed_codec_id;
+
+ switch (type) {
+ case AV_OPT_FLAG_VIDEO_PARAM:
+ ctx = config->dummy_vctx;
+ dict = &config->video_opts;
+ guessed_codec_id = config->guessed_video_codec_id != AV_CODEC_ID_NONE ?
+ config->guessed_video_codec_id : AV_CODEC_ID_H264;
+ break;
+ case AV_OPT_FLAG_AUDIO_PARAM:
+ ctx = config->dummy_actx;
+ dict = &config->audio_opts;
+ guessed_codec_id = config->guessed_audio_codec_id != AV_CODEC_ID_NONE ?
+ config->guessed_audio_codec_id : AV_CODEC_ID_AAC;
+ break;
+ default:
+ av_assert0(0);
+ }
+
+ if (strchr(opt, ':')) {
+ //explicit private option
+ snprintf(buff, sizeof(buff), "%s", opt);
+ codec_name = buff;
+ option = strchr(buff, ':');
+ buff[option - buff] = '\0';
+ option++;
+ if ((ret = ffserver_set_codec(ctx, codec_name, config)) < 0)
+ return ret;
+ if (!ctx->codec || !ctx->priv_data)
+ return -1;
+ } else {
+ option = opt;
+ }
+
+ o = av_opt_find(ctx, option, NULL, type | AV_OPT_FLAG_ENCODING_PARAM, AV_OPT_SEARCH_CHILDREN);
+ if (!o && (!strcmp(option, "time_base") || !strcmp(option, "pixel_format") ||
+ !strcmp(option, "video_size") || !strcmp(option, "codec_tag")))
+ o = av_opt_find(ctx, option, NULL, 0, 0);
+ if (!o) {
+ report_config_error(config->filename, config->line_num, AV_LOG_ERROR,
+ &config->errors, "Option not found: %s\n", opt);
+ if (!hinted && ctx->codec_id == AV_CODEC_ID_NONE) {
+ hinted = 1;
+ report_config_error(config->filename, config->line_num, AV_LOG_ERROR, NULL,
+ "If '%s' is a codec private option, then prefix it with codec name, "
+ "for example '%s:%s %s' or define codec earlier.\n",
+ opt, avcodec_get_name(guessed_codec_id) ,opt, arg);
+ }
+ } else if ((ret = av_opt_set(ctx, option, arg, AV_OPT_SEARCH_CHILDREN)) < 0) {
+ report_config_error(config->filename, config->line_num, AV_LOG_ERROR,
+ &config->errors, "Invalid value for option %s (%s): %s\n", opt,
+ arg, av_err2str(ret));
+ } else if ((e = av_dict_get(*dict, option, NULL, 0))) {
+ if ((o->type == AV_OPT_TYPE_FLAGS) && arg && (arg[0] == '+' || arg[0] == '-'))
+ return av_dict_set(dict, option, arg, AV_DICT_APPEND);
+ report_config_error(config->filename, config->line_num, AV_LOG_ERROR,
+ &config->errors,
+ "Redeclaring value of the option %s, previous value: %s\n",
+ opt, e->value);
+ } else if (av_dict_set(dict, option, arg, 0) < 0) {
+ return AVERROR(ENOMEM);
+ }
+ return 0;
+}
+
+static int ffserver_save_avoption_int(const char *opt, int64_t arg,
+ int type, FFServerConfig *config)
+{
+ char buf[22];
+ snprintf(buf, sizeof(buf), "%"PRId64, arg);
+ return ffserver_save_avoption(opt, buf, type, config);
+}
+
+static int ffserver_parse_config_global(FFServerConfig *config, const char *cmd,
+ const char **p)
+{
+ int val;
+ char arg[1024];
+ if (!av_strcasecmp(cmd, "Port") || !av_strcasecmp(cmd, "HTTPPort")) {
+ if (!av_strcasecmp(cmd, "Port"))
+ WARNING("Port option is deprecated, use HTTPPort instead\n");
+ ffserver_get_arg(arg, sizeof(arg), p);
+ ffserver_set_int_param(&val, arg, 0, 1, 65535, config,
+ "Invalid port: %s\n", arg);
+ if (val < 1024)
+ WARNING("Trying to use IETF assigned system port: %d\n", val);
+ config->http_addr.sin_port = htons(val);
+ } else if (!av_strcasecmp(cmd, "HTTPBindAddress") || !av_strcasecmp(cmd, "BindAddress")) {
+ if (!av_strcasecmp(cmd, "BindAddress"))
+ WARNING("BindAddress option is deprecated, use HTTPBindAddress instead\n");
+ ffserver_get_arg(arg, sizeof(arg), p);
+ if (resolve_host(&config->http_addr.sin_addr, arg))
+ ERROR("Invalid host/IP address: %s\n", arg);
+ } else if (!av_strcasecmp(cmd, "NoDaemon")) {
+ WARNING("NoDaemon option has no effect, you should remove it\n");
+ } else if (!av_strcasecmp(cmd, "RTSPPort")) {
+ ffserver_get_arg(arg, sizeof(arg), p);
+ ffserver_set_int_param(&val, arg, 0, 1, 65535, config,
+ "Invalid port: %s\n", arg);
+ config->rtsp_addr.sin_port = htons(val);
+ } else if (!av_strcasecmp(cmd, "RTSPBindAddress")) {
+ ffserver_get_arg(arg, sizeof(arg), p);
+ if (resolve_host(&config->rtsp_addr.sin_addr, arg))
+ ERROR("Invalid host/IP address: %s\n", arg);
+ } else if (!av_strcasecmp(cmd, "MaxHTTPConnections")) {
+ ffserver_get_arg(arg, sizeof(arg), p);
+ ffserver_set_int_param(&val, arg, 0, 1, 65535, config,
+ "Invalid MaxHTTPConnections: %s\n", arg);
+ config->nb_max_http_connections = val;
+ if (config->nb_max_connections > config->nb_max_http_connections)
+ ERROR("Inconsistent configuration: MaxClients(%d) > MaxHTTPConnections(%d)\n",
+ config->nb_max_connections, config->nb_max_http_connections);
+ } else if (!av_strcasecmp(cmd, "MaxClients")) {
+ ffserver_get_arg(arg, sizeof(arg), p);
+ ffserver_set_int_param(&val, arg, 0, 1, 65535, config,
+ "Invalid MaxClients: %s\n", arg);
+ config->nb_max_connections = val;
+ if (config->nb_max_connections > config->nb_max_http_connections)
+ ERROR("Inconsistent configuration: MaxClients(%d) > MaxHTTPConnections(%d)\n",
+ config->nb_max_connections, config->nb_max_http_connections);
+ } else if (!av_strcasecmp(cmd, "MaxBandwidth")) {
+ int64_t llval;
+ char *tailp;
+ ffserver_get_arg(arg, sizeof(arg), p);
+ errno = 0;
+ llval = strtoll(arg, &tailp, 10);
+ if (llval < 10 || llval > 10000000 || tailp[0] || errno)
+ ERROR("Invalid MaxBandwidth: %s\n", arg);
+ else
+ config->max_bandwidth = llval;
+ } else if (!av_strcasecmp(cmd, "CustomLog")) {
+ if (!config->debug)
+ ffserver_get_arg(config->logfilename, sizeof(config->logfilename), p);
+ } else if (!av_strcasecmp(cmd, "LoadModule")) {
+ ERROR("Loadable modules are no longer supported\n");
+ } else if (!av_strcasecmp(cmd, "NoDefaults")) {
+ config->use_defaults = 0;
+ } else if (!av_strcasecmp(cmd, "UseDefaults")) {
+ config->use_defaults = 1;
+ } else
+ ERROR("Incorrect keyword: '%s'\n", cmd);
+ return 0;
+}
+
+static int ffserver_parse_config_feed(FFServerConfig *config, const char *cmd, const char **p,
+ FFServerStream **pfeed)
+{
+ FFServerStream *feed;
+ char arg[1024];
+ av_assert0(pfeed);
+ feed = *pfeed;
+ if (!av_strcasecmp(cmd, "<Feed")) {
+ char *q;
+ FFServerStream *s;
+ feed = av_mallocz(sizeof(FFServerStream));
+ if (!feed)
+ return AVERROR(ENOMEM);
+ ffserver_get_arg(feed->filename, sizeof(feed->filename), p);
+ q = strrchr(feed->filename, '>');
+ if (*q)
+ *q = '\0';
+
+ for (s = config->first_feed; s; s = s->next) {
+ if (!strcmp(feed->filename, s->filename))
+ ERROR("Feed '%s' already registered\n", s->filename);
+ }
+
+ feed->fmt = av_guess_format("ffm", NULL, NULL);
+ /* default feed file */
+ snprintf(feed->feed_filename, sizeof(feed->feed_filename),
+ "/tmp/%s.ffm", feed->filename);
+ feed->feed_max_size = 5 * 1024 * 1024;
+ feed->is_feed = 1;
+ feed->feed = feed; /* self feeding :-) */
+ *pfeed = feed;
+ return 0;
+ }
+ av_assert0(feed);
+ if (!av_strcasecmp(cmd, "Launch")) {
+ int i;
+
+ feed->child_argv = av_mallocz_array(MAX_CHILD_ARGS, sizeof(char *));
+ if (!feed->child_argv)
+ return AVERROR(ENOMEM);
+ for (i = 0; i < MAX_CHILD_ARGS - 2; i++) {
+ ffserver_get_arg(arg, sizeof(arg), p);
+ if (!arg[0])
+ break;
+
+ feed->child_argv[i] = av_strdup(arg);
+ if (!feed->child_argv[i])
+ return AVERROR(ENOMEM);
+ }
+
+ feed->child_argv[i] =
+ av_asprintf("http://%s:%d/%s",
+ (config->http_addr.sin_addr.s_addr == INADDR_ANY) ? "127.0.0.1" :
+ inet_ntoa(config->http_addr.sin_addr), ntohs(config->http_addr.sin_port),
+ feed->filename);
+ if (!feed->child_argv[i])
+ return AVERROR(ENOMEM);
+ } else if (!av_strcasecmp(cmd, "ACL")) {
+ ffserver_parse_acl_row(NULL, feed, NULL, *p, config->filename,
+ config->line_num);
+ } else if (!av_strcasecmp(cmd, "File") || !av_strcasecmp(cmd, "ReadOnlyFile")) {
+ ffserver_get_arg(feed->feed_filename, sizeof(feed->feed_filename), p);
+ feed->readonly = !av_strcasecmp(cmd, "ReadOnlyFile");
+ } else if (!av_strcasecmp(cmd, "Truncate")) {
+ ffserver_get_arg(arg, sizeof(arg), p);
+ /* assume Truncate is true in case no argument is specified */
+ if (!arg[0]) {
+ feed->truncate = 1;
+ } else {
+ 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")) {
+ char *p1;
+ double fsize;
+
+ ffserver_get_arg(arg, sizeof(arg), p);
+ p1 = arg;
+ fsize = strtod(p1, &p1);
+ switch(av_toupper(*p1)) {
+ case 'K':
+ fsize *= 1024;
+ break;
+ case 'M':
+ fsize *= 1024 * 1024;
+ break;
+ case 'G':
+ fsize *= 1024 * 1024 * 1024;
+ break;
+ default:
+ ERROR("Invalid file size: %s\n", arg);
+ break;
+ }
+ feed->feed_max_size = (int64_t)fsize;
+ if (feed->feed_max_size < FFM_PACKET_SIZE*4)
+ ERROR("Feed max file size is too small, must be at least %d\n",
+ FFM_PACKET_SIZE*4);
+ } else if (!av_strcasecmp(cmd, "</Feed>")) {
+ *pfeed = NULL;
+ } else {
+ ERROR("Invalid entry '%s' inside <Feed></Feed>\n", cmd);
+ }
+ return 0;
+}
+
+static int ffserver_parse_config_stream(FFServerConfig *config, const char *cmd, const char **p,
+ FFServerStream **pstream)
+{
+ char arg[1024], arg2[1024];
+ FFServerStream *stream;
+ int val;
+
+ av_assert0(pstream);
+ stream = *pstream;
+
+ if (!av_strcasecmp(cmd, "<Stream")) {
+ char *q;
+ FFServerStream *s;
+ stream = av_mallocz(sizeof(FFServerStream));
+ if (!stream)
+ return AVERROR(ENOMEM);
+ config->dummy_actx = avcodec_alloc_context3(NULL);
+ config->dummy_vctx = avcodec_alloc_context3(NULL);
+ if (!config->dummy_vctx || !config->dummy_actx) {
+ av_free(stream);
+ avcodec_free_context(&config->dummy_vctx);
+ avcodec_free_context(&config->dummy_actx);
+ return AVERROR(ENOMEM);
+ }
+ config->dummy_actx->codec_type = AVMEDIA_TYPE_AUDIO;
+ config->dummy_vctx->codec_type = AVMEDIA_TYPE_VIDEO;
+ ffserver_get_arg(stream->filename, sizeof(stream->filename), p);
+ q = strrchr(stream->filename, '>');
+ if (q)
+ *q = '\0';
+
+ for (s = config->first_stream; s; s = s->next) {
+ if (!strcmp(stream->filename, s->filename))
+ ERROR("Stream '%s' already registered\n", s->filename);
+ }
+
+ stream->fmt = ffserver_guess_format(NULL, stream->filename, NULL);
+ if (stream->fmt) {
+ config->guessed_audio_codec_id = stream->fmt->audio_codec;
+ config->guessed_video_codec_id = stream->fmt->video_codec;
+ } else {
+ config->guessed_audio_codec_id = AV_CODEC_ID_NONE;
+ config->guessed_video_codec_id = AV_CODEC_ID_NONE;
+ }
+ config->stream_use_defaults = config->use_defaults;
+ *pstream = stream;
+ return 0;
+ }
+ av_assert0(stream);
+ if (!av_strcasecmp(cmd, "Feed")) {
+ FFServerStream *sfeed;
+ ffserver_get_arg(arg, sizeof(arg), p);
+ sfeed = config->first_feed;
+ while (sfeed) {
+ if (!strcmp(sfeed->filename, arg))
+ break;
+ sfeed = sfeed->next_feed;
+ }
+ if (!sfeed)
+ ERROR("Feed with name '%s' for stream '%s' is not defined\n", arg,
+ stream->filename);
+ else
+ stream->feed = sfeed;
+ } else if (!av_strcasecmp(cmd, "Format")) {
+ ffserver_get_arg(arg, sizeof(arg), p);
+ if (!strcmp(arg, "status")) {
+ stream->stream_type = STREAM_TYPE_STATUS;
+ stream->fmt = NULL;
+ } else {
+ stream->stream_type = STREAM_TYPE_LIVE;
+ /* JPEG cannot be used here, so use single frame MJPEG */
+ if (!strcmp(arg, "jpeg"))
+ strcpy(arg, "mjpeg");
+ stream->fmt = ffserver_guess_format(arg, NULL, NULL);
+ if (!stream->fmt)
+ ERROR("Unknown Format: %s\n", arg);
+ }
+ if (stream->fmt) {
+ config->guessed_audio_codec_id = stream->fmt->audio_codec;
+ config->guessed_video_codec_id = stream->fmt->video_codec;
+ }
+ } else if (!av_strcasecmp(cmd, "InputFormat")) {
+ ffserver_get_arg(arg, sizeof(arg), p);
+ stream->ifmt = av_find_input_format(arg);
+ if (!stream->ifmt)
+ ERROR("Unknown input format: %s\n", arg);
+ } else if (!av_strcasecmp(cmd, "FaviconURL")) {
+ if (stream->stream_type == STREAM_TYPE_STATUS)
+ ffserver_get_arg(stream->feed_filename,
+ sizeof(stream->feed_filename), p);
+ else
+ ERROR("FaviconURL only permitted for status streams\n");
+ } else if (!av_strcasecmp(cmd, "Author") ||
+ !av_strcasecmp(cmd, "Comment") ||
+ !av_strcasecmp(cmd, "Copyright") ||
+ !av_strcasecmp(cmd, "Title")) {
+ char key[32];
+ int i;
+ ffserver_get_arg(arg, sizeof(arg), p);
+ for (i = 0; i < strlen(cmd); i++)
+ key[i] = av_tolower(cmd[i]);
+ key[i] = 0;
+ WARNING("'%s' option in configuration file is deprecated, "
+ "use 'Metadata %s VALUE' instead\n", cmd, key);
+ if (av_dict_set(&stream->metadata, key, arg, 0) < 0)
+ goto nomem;
+ } else if (!av_strcasecmp(cmd, "Metadata")) {
+ ffserver_get_arg(arg, sizeof(arg), p);
+ ffserver_get_arg(arg2, sizeof(arg2), p);
+ if (av_dict_set(&stream->metadata, arg, arg2, 0) < 0)
+ goto nomem;
+ } else if (!av_strcasecmp(cmd, "Preroll")) {
+ ffserver_get_arg(arg, sizeof(arg), p);
+ stream->prebuffer = atof(arg) * 1000;
+ } else if (!av_strcasecmp(cmd, "StartSendOnKey")) {
+ stream->send_on_key = 1;
+ } else if (!av_strcasecmp(cmd, "AudioCodec")) {
+ ffserver_get_arg(arg, sizeof(arg), p);
+ ffserver_set_codec(config->dummy_actx, arg, config);
+ } else if (!av_strcasecmp(cmd, "VideoCodec")) {
+ ffserver_get_arg(arg, sizeof(arg), p);
+ ffserver_set_codec(config->dummy_vctx, arg, config);
+ } else if (!av_strcasecmp(cmd, "MaxTime")) {
+ ffserver_get_arg(arg, sizeof(arg), p);
+ stream->max_time = atof(arg) * 1000;
+ } else if (!av_strcasecmp(cmd, "AudioBitRate")) {
+ float f;
+ ffserver_get_arg(arg, sizeof(arg), p);
+ ffserver_set_float_param(&f, arg, 1000, -FLT_MAX, FLT_MAX, config,
+ "Invalid %s: %s\n", cmd, arg);
+ if (ffserver_save_avoption_int("ab", (int64_t)lrintf(f), AV_OPT_FLAG_AUDIO_PARAM, config) < 0)
+ goto nomem;
+ } else if (!av_strcasecmp(cmd, "AudioChannels")) {
+ ffserver_get_arg(arg, sizeof(arg), p);
+ if (ffserver_save_avoption("ac", arg, AV_OPT_FLAG_AUDIO_PARAM, config) < 0)
+ goto nomem;
+ } else if (!av_strcasecmp(cmd, "AudioSampleRate")) {
+ ffserver_get_arg(arg, sizeof(arg), p);
+ if (ffserver_save_avoption("ar", arg, AV_OPT_FLAG_AUDIO_PARAM, config) < 0)
+ goto nomem;
+ } else if (!av_strcasecmp(cmd, "VideoBitRateRange")) {
+ int minrate, maxrate;
+ char *dash;
+ ffserver_get_arg(arg, sizeof(arg), p);
+ dash = strchr(arg, '-');
+ if (dash) {
+ *dash = '\0';
+ dash++;
+ if (ffserver_set_int_param(&minrate, arg, 1000, 0, INT_MAX, config, "Invalid %s: %s", cmd, arg) >= 0 &&
+ ffserver_set_int_param(&maxrate, dash, 1000, 0, INT_MAX, config, "Invalid %s: %s", cmd, arg) >= 0) {
+ if (ffserver_save_avoption_int("minrate", minrate, AV_OPT_FLAG_VIDEO_PARAM, config) < 0 ||
+ ffserver_save_avoption_int("maxrate", maxrate, AV_OPT_FLAG_VIDEO_PARAM, config) < 0)
+ goto nomem;
+ }
+ } else
+ ERROR("Incorrect format for VideoBitRateRange -- should be "
+ "<min>-<max>: %s\n", arg);
+ } else if (!av_strcasecmp(cmd, "Debug")) {
+ ffserver_get_arg(arg, sizeof(arg), p);
+ if (ffserver_save_avoption("debug", arg, AV_OPT_FLAG_AUDIO_PARAM, config) < 0 ||
+ ffserver_save_avoption("debug", arg, AV_OPT_FLAG_VIDEO_PARAM, config) < 0)
+ goto nomem;
+ } else if (!av_strcasecmp(cmd, "Strict")) {
+ ffserver_get_arg(arg, sizeof(arg), p);
+ if (ffserver_save_avoption("strict", arg, AV_OPT_FLAG_AUDIO_PARAM, config) < 0 ||
+ ffserver_save_avoption("strict", arg, AV_OPT_FLAG_VIDEO_PARAM, config) < 0)
+ goto nomem;
+ } else if (!av_strcasecmp(cmd, "VideoBufferSize")) {
+ ffserver_get_arg(arg, sizeof(arg), p);
+ ffserver_set_int_param(&val, arg, 8*1024, 0, INT_MAX, config,
+ "Invalid %s: %s", cmd, arg);
+ if (ffserver_save_avoption_int("bufsize", val, AV_OPT_FLAG_VIDEO_PARAM, config) < 0)
+ goto nomem;
+ } else if (!av_strcasecmp(cmd, "VideoBitRateTolerance")) {
+ ffserver_get_arg(arg, sizeof(arg), p);
+ ffserver_set_int_param(&val, arg, 1000, INT_MIN, INT_MAX, config,
+ "Invalid %s: %s", cmd, arg);
+ if (ffserver_save_avoption_int("bt", val, AV_OPT_FLAG_VIDEO_PARAM, config) < 0)
+ goto nomem;
+ } else if (!av_strcasecmp(cmd, "VideoBitRate")) {
+ ffserver_get_arg(arg, sizeof(arg), p);
+ ffserver_set_int_param(&val, arg, 1000, INT_MIN, INT_MAX, config,
+ "Invalid %s: %s", cmd, arg);
+ if (ffserver_save_avoption_int("b", val, AV_OPT_FLAG_VIDEO_PARAM, config) < 0)
+ goto nomem;
+ } else if (!av_strcasecmp(cmd, "VideoSize")) {
+ int ret, w, h;
+ ffserver_get_arg(arg, sizeof(arg), p);
+ ret = av_parse_video_size(&w, &h, arg);
+ if (ret < 0)
+ ERROR("Invalid video size '%s'\n", arg);
+ else {
+ if (w % 2 || h % 2)
+ WARNING("Image size is not a multiple of 2\n");
+ if (ffserver_save_avoption("video_size", arg, AV_OPT_FLAG_VIDEO_PARAM, config) < 0)
+ goto nomem;
+ }
+ } else if (!av_strcasecmp(cmd, "VideoFrameRate")) {
+ ffserver_get_arg(&arg[2], sizeof(arg) - 2, p);
+ arg[0] = '1'; arg[1] = '/';
+ if (ffserver_save_avoption("time_base", arg, AV_OPT_FLAG_VIDEO_PARAM, config) < 0)
+ goto nomem;
+ } else if (!av_strcasecmp(cmd, "PixelFormat")) {
+ enum AVPixelFormat pix_fmt;
+ ffserver_get_arg(arg, sizeof(arg), p);
+ pix_fmt = av_get_pix_fmt(arg);
+ if (pix_fmt == AV_PIX_FMT_NONE)
+ ERROR("Unknown pixel format: %s\n", arg);
+ else if (ffserver_save_avoption("pixel_format", arg, AV_OPT_FLAG_VIDEO_PARAM, config) < 0)
+ goto nomem;
+ } else if (!av_strcasecmp(cmd, "VideoGopSize")) {
+ ffserver_get_arg(arg, sizeof(arg), p);
+ if (ffserver_save_avoption("g", arg, AV_OPT_FLAG_VIDEO_PARAM, config) < 0)
+ goto nomem;
+ } else if (!av_strcasecmp(cmd, "VideoIntraOnly")) {
+ if (ffserver_save_avoption("g", "1", AV_OPT_FLAG_VIDEO_PARAM, config) < 0)
+ goto nomem;
+ } else if (!av_strcasecmp(cmd, "VideoHighQuality")) {
+ if (ffserver_save_avoption("mbd", "+bits", AV_OPT_FLAG_VIDEO_PARAM, config) < 0)
+ goto nomem;
+ } else if (!av_strcasecmp(cmd, "Video4MotionVector")) {
+ if (ffserver_save_avoption("mbd", "+bits", AV_OPT_FLAG_VIDEO_PARAM, config) < 0 || //FIXME remove
+ ffserver_save_avoption("flags", "+mv4", AV_OPT_FLAG_VIDEO_PARAM, config) < 0)
+ goto nomem;
+ } else if (!av_strcasecmp(cmd, "AVOptionVideo") ||
+ !av_strcasecmp(cmd, "AVOptionAudio")) {
+ int ret;
+ ffserver_get_arg(arg, sizeof(arg), p);
+ ffserver_get_arg(arg2, sizeof(arg2), p);
+ if (!av_strcasecmp(cmd, "AVOptionVideo"))
+ ret = ffserver_save_avoption(arg, arg2, AV_OPT_FLAG_VIDEO_PARAM, config);
+ else
+ ret = ffserver_save_avoption(arg, arg2, AV_OPT_FLAG_AUDIO_PARAM, config);
+ if (ret < 0)
+ goto nomem;
+ } else if (!av_strcasecmp(cmd, "AVPresetVideo") ||
+ !av_strcasecmp(cmd, "AVPresetAudio")) {
+ ffserver_get_arg(arg, sizeof(arg), p);
+ if (!av_strcasecmp(cmd, "AVPresetVideo"))
+ ffserver_opt_preset(arg, AV_OPT_FLAG_VIDEO_PARAM, config);
+ else
+ ffserver_opt_preset(arg, AV_OPT_FLAG_AUDIO_PARAM, config);
+ } else if (!av_strcasecmp(cmd, "VideoTag")) {
+ ffserver_get_arg(arg, sizeof(arg), p);
+ if (strlen(arg) == 4 &&
+ ffserver_save_avoption_int("codec_tag", MKTAG(arg[0], arg[1], arg[2], arg[3]),
+ AV_OPT_FLAG_VIDEO_PARAM, config) < 0)
+ goto nomem;
+ } else if (!av_strcasecmp(cmd, "BitExact")) {
+ if (ffserver_save_avoption("flags", "+bitexact", AV_OPT_FLAG_VIDEO_PARAM, config) < 0)
+ goto nomem;
+ } else if (!av_strcasecmp(cmd, "DctFastint")) {
+ if (ffserver_save_avoption("dct", "fastint", AV_OPT_FLAG_VIDEO_PARAM, config) < 0)
+ goto nomem;
+ } else if (!av_strcasecmp(cmd, "IdctSimple")) {
+ if (ffserver_save_avoption("idct", "simple", AV_OPT_FLAG_VIDEO_PARAM, config) < 0)
+ goto nomem;
+ } else if (!av_strcasecmp(cmd, "Qscale")) {
+ ffserver_get_arg(arg, sizeof(arg), p);
+ ffserver_set_int_param(&val, arg, 0, INT_MIN, INT_MAX, config,
+ "Invalid Qscale: %s\n", arg);
+ if (ffserver_save_avoption("flags", "+qscale", AV_OPT_FLAG_VIDEO_PARAM, config) < 0 ||
+ ffserver_save_avoption_int("global_quality", FF_QP2LAMBDA * val,
+ AV_OPT_FLAG_VIDEO_PARAM, config) < 0)
+ goto nomem;
+ } else if (!av_strcasecmp(cmd, "VideoQDiff")) {
+ ffserver_get_arg(arg, sizeof(arg), p);
+ if (ffserver_save_avoption("qdiff", arg, AV_OPT_FLAG_VIDEO_PARAM, config) < 0)
+ goto nomem;
+ } else if (!av_strcasecmp(cmd, "VideoQMax")) {
+ ffserver_get_arg(arg, sizeof(arg), p);
+ if (ffserver_save_avoption("qmax", arg, AV_OPT_FLAG_VIDEO_PARAM, config) < 0)
+ goto nomem;
+ } else if (!av_strcasecmp(cmd, "VideoQMin")) {
+ ffserver_get_arg(arg, sizeof(arg), p);
+ if (ffserver_save_avoption("qmin", arg, AV_OPT_FLAG_VIDEO_PARAM, config) < 0)
+ goto nomem;
+ } else if (!av_strcasecmp(cmd, "LumiMask")) {
+ ffserver_get_arg(arg, sizeof(arg), p);
+ if (ffserver_save_avoption("lumi_mask", arg, AV_OPT_FLAG_VIDEO_PARAM, config) < 0)
+ goto nomem;
+ } else if (!av_strcasecmp(cmd, "DarkMask")) {
+ ffserver_get_arg(arg, sizeof(arg), p);
+ if (ffserver_save_avoption("dark_mask", arg, AV_OPT_FLAG_VIDEO_PARAM, config) < 0)
+ goto nomem;
+ } else if (!av_strcasecmp(cmd, "NoVideo")) {
+ config->no_video = 1;
+ } else if (!av_strcasecmp(cmd, "NoAudio")) {
+ config->no_audio = 1;
+ } else if (!av_strcasecmp(cmd, "ACL")) {
+ ffserver_parse_acl_row(stream, NULL, NULL, *p, config->filename,
+ config->line_num);
+ } else if (!av_strcasecmp(cmd, "DynamicACL")) {
+ ffserver_get_arg(stream->dynamic_acl, sizeof(stream->dynamic_acl), p);
+ } else if (!av_strcasecmp(cmd, "RTSPOption")) {
+ ffserver_get_arg(arg, sizeof(arg), p);
+ av_freep(&stream->rtsp_option);
+ stream->rtsp_option = av_strdup(arg);
+ } else if (!av_strcasecmp(cmd, "MulticastAddress")) {
+ ffserver_get_arg(arg, sizeof(arg), p);
+ if (resolve_host(&stream->multicast_ip, arg))
+ ERROR("Invalid host/IP address: %s\n", arg);
+ stream->is_multicast = 1;
+ stream->loop = 1; /* default is looping */
+ } else if (!av_strcasecmp(cmd, "MulticastPort")) {
+ ffserver_get_arg(arg, sizeof(arg), p);
+ ffserver_set_int_param(&val, arg, 0, 1, 65535, config,
+ "Invalid MulticastPort: %s\n", arg);
+ stream->multicast_port = val;
+ } else if (!av_strcasecmp(cmd, "MulticastTTL")) {
+ ffserver_get_arg(arg, sizeof(arg), p);
+ ffserver_set_int_param(&val, arg, 0, INT_MIN, INT_MAX, config,
+ "Invalid MulticastTTL: %s\n", arg);
+ stream->multicast_ttl = val;
+ } else if (!av_strcasecmp(cmd, "NoLoop")) {
+ stream->loop = 0;
+ } else if (!av_strcasecmp(cmd, "</Stream>")) {
+ config->stream_use_defaults &= 1;
+ if (stream->feed && stream->fmt && strcmp(stream->fmt->name, "ffm")) {
+ if (config->dummy_actx->codec_id == AV_CODEC_ID_NONE)
+ config->dummy_actx->codec_id = config->guessed_audio_codec_id;
+ if (!config->no_audio && config->dummy_actx->codec_id != AV_CODEC_ID_NONE) {
+ AVCodecContext *audio_enc = avcodec_alloc_context3(avcodec_find_encoder(config->dummy_actx->codec_id));
+ add_codec(stream, audio_enc, config);
+ }
+ if (config->dummy_vctx->codec_id == AV_CODEC_ID_NONE)
+ config->dummy_vctx->codec_id = config->guessed_video_codec_id;
+ if (!config->no_video && config->dummy_vctx->codec_id != AV_CODEC_ID_NONE) {
+ AVCodecContext *video_enc = avcodec_alloc_context3(avcodec_find_encoder(config->dummy_vctx->codec_id));
+ add_codec(stream, video_enc, config);
+ }
+ }
+ av_dict_free(&config->video_opts);
+ av_dict_free(&config->audio_opts);
+ avcodec_free_context(&config->dummy_vctx);
+ avcodec_free_context(&config->dummy_actx);
+ *pstream = NULL;
+ } else if (!av_strcasecmp(cmd, "File") || !av_strcasecmp(cmd, "ReadOnlyFile")) {
+ ffserver_get_arg(stream->feed_filename, sizeof(stream->feed_filename),
+ p);
+ } else if (!av_strcasecmp(cmd, "UseDefaults")) {
+ if (config->stream_use_defaults > 1)
+ WARNING("Multiple UseDefaults/NoDefaults entries.\n");
+ config->stream_use_defaults = 3;
+ } else if (!av_strcasecmp(cmd, "NoDefaults")) {
+ if (config->stream_use_defaults > 1)
+ WARNING("Multiple UseDefaults/NoDefaults entries.\n");
+ config->stream_use_defaults = 2;
+ } else {
+ ERROR("Invalid entry '%s' inside <Stream></Stream>\n", cmd);
+ }
+ return 0;
+ nomem:
+ av_log(NULL, AV_LOG_ERROR, "Out of memory. Aborting.\n");
+ av_dict_free(&config->video_opts);
+ av_dict_free(&config->audio_opts);
+ avcodec_free_context(&config->dummy_vctx);
+ avcodec_free_context(&config->dummy_actx);
+ return AVERROR(ENOMEM);
+}
+
+static int ffserver_parse_config_redirect(FFServerConfig *config, const char *cmd, const char **p,
+ FFServerStream **predirect)
+{
+ FFServerStream *redirect;
+ av_assert0(predirect);
+ redirect = *predirect;
+
+ if (!av_strcasecmp(cmd, "<Redirect")) {
+ char *q;
+ redirect = av_mallocz(sizeof(FFServerStream));
+ if (!redirect)
+ return AVERROR(ENOMEM);
+
+ ffserver_get_arg(redirect->filename, sizeof(redirect->filename), p);
+ q = strrchr(redirect->filename, '>');
+ if (*q)
+ *q = '\0';
+ redirect->stream_type = STREAM_TYPE_REDIRECT;
+ *predirect = redirect;
+ return 0;
+ }
+ av_assert0(redirect);
+ if (!av_strcasecmp(cmd, "URL")) {
+ ffserver_get_arg(redirect->feed_filename,
+ sizeof(redirect->feed_filename), p);
+ } else if (!av_strcasecmp(cmd, "</Redirect>")) {
+ if (!redirect->feed_filename[0])
+ ERROR("No URL found for <Redirect>\n");
+ *predirect = NULL;
+ } else {
+ ERROR("Invalid entry '%s' inside <Redirect></Redirect>\n", cmd);
+ }
+ return 0;
+}
+
+int ffserver_parse_ffconfig(const char *filename, FFServerConfig *config)
+{
+ FILE *f;
+ char line[1024];
+ char cmd[64];
+ const char *p;
+ FFServerStream **last_stream, *stream = NULL, *redirect = NULL;
+ FFServerStream **last_feed, *feed = NULL;
+ int ret = 0;
+
+ av_assert0(config);
+
+ config->line_num = 0;
+ f = fopen(filename, "r");
+ if (!f) {
+ ret = AVERROR(errno);
+ av_log(NULL, AV_LOG_ERROR,
+ "Could not open the configuration file '%s'\n", filename);
+ return ret;
+ }
+
+ config->first_stream = NULL;
+ last_stream = &config->first_stream;
+ config->first_feed = NULL;
+ last_feed = &config->first_feed;
+ config->errors = config->warnings = 0;
+
+ for(;;) {
+ if (fgets(line, sizeof(line), f) == NULL)
+ break;
+ config->line_num++;
+ p = line;
+ while (av_isspace(*p))
+ p++;
+ if (*p == '\0' || *p == '#')
+ continue;
+
+ ffserver_get_arg(cmd, sizeof(cmd), &p);
+
+ if (feed || !av_strcasecmp(cmd, "<Feed")) {
+ int opening = !av_strcasecmp(cmd, "<Feed");
+ if (opening && (stream || feed || redirect)) {
+ ERROR("Already in a tag\n");
+ } else {
+ if ((ret = ffserver_parse_config_feed(config, cmd, &p, &feed)) < 0)
+ break;
+ if (opening) {
+ /* add in stream list */
+ *last_stream = feed;
+ last_stream = &feed->next;
+ /* add in feed list */
+ *last_feed = feed;
+ last_feed = &feed->next_feed;
+ }
+ }
+ } else if (stream || !av_strcasecmp(cmd, "<Stream")) {
+ int opening = !av_strcasecmp(cmd, "<Stream");
+ if (opening && (stream || feed || redirect)) {
+ ERROR("Already in a tag\n");
+ } else {
+ if ((ret = ffserver_parse_config_stream(config, cmd, &p, &stream)) < 0)
+ break;
+ if (opening) {
+ /* add in stream list */
+ *last_stream = stream;
+ last_stream = &stream->next;
+ }
+ }
+ } else if (redirect || !av_strcasecmp(cmd, "<Redirect")) {
+ int opening = !av_strcasecmp(cmd, "<Redirect");
+ if (opening && (stream || feed || redirect))
+ ERROR("Already in a tag\n");
+ else {
+ if ((ret = ffserver_parse_config_redirect(config, cmd, &p, &redirect)) < 0)
+ break;
+ if (opening) {
+ /* add in stream list */
+ *last_stream = redirect;
+ last_stream = &redirect->next;
+ }
+ }
+ } else {
+ ffserver_parse_config_global(config, cmd, &p);
+ }
+ }
+ if (stream || feed || redirect)
+ ERROR("Not closed tag %s\n", stream ? "<Stream>" : (feed ? "<Feed>" : "<Redirect>"));
+
+ fclose(f);
+ if (ret < 0)
+ return ret;
+ if (config->errors)
+ return AVERROR(EINVAL);
+ else
+ return 0;
+}
+
+#undef ERROR
+#undef WARNING
+
+void ffserver_free_child_args(void *argsp)
+{
+ int i;
+ char **args;
+ if (!argsp)
+ return;
+ args = *(char ***)argsp;
+ if (!args)
+ return;
+ for (i = 0; i < MAX_CHILD_ARGS; i++)
+ av_free(args[i]);
+ av_freep(argsp);
+}
--- /dev/null
+/*
+ * Copyright (c) 2000, 2001, 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
+ */
+
+#ifndef FFSERVER_CONFIG_H
+#define FFSERVER_CONFIG_H
+
+#include "libavutil/dict.h"
+#include "libavformat/avformat.h"
+#include "libavformat/network.h"
+
+#define FFSERVER_MAX_STREAMS 20
+
+/* each generated stream is described here */
+enum FFServerStreamType {
+ STREAM_TYPE_LIVE,
+ STREAM_TYPE_STATUS,
+ STREAM_TYPE_REDIRECT,
+};
+
+enum FFServerIPAddressAction {
+ IP_ALLOW = 1,
+ IP_DENY,
+};
+
+typedef struct FFServerIPAddressACL {
+ struct FFServerIPAddressACL *next;
+ enum FFServerIPAddressAction action;
+ /* These are in host order */
+ struct in_addr first;
+ struct in_addr last;
+} FFServerIPAddressACL;
+
+/* description of each stream of the ffserver.conf file */
+typedef struct FFServerStream {
+ enum FFServerStreamType stream_type;
+ char filename[1024]; /* stream filename */
+ struct FFServerStream *feed; /* feed we are using (can be null if coming from file) */
+ AVDictionary *in_opts; /* input parameters */
+ AVDictionary *metadata; /* metadata to set on the stream */
+ AVInputFormat *ifmt; /* if non NULL, force input format */
+ AVOutputFormat *fmt;
+ FFServerIPAddressACL *acl;
+ char dynamic_acl[1024];
+ int nb_streams;
+ int prebuffer; /* Number of milliseconds early to start */
+ int64_t max_time; /* Number of milliseconds to run */
+ int send_on_key;
+ AVStream *streams[FFSERVER_MAX_STREAMS];
+ int feed_streams[FFSERVER_MAX_STREAMS]; /* index of streams in the feed */
+ char feed_filename[1024]; /* file name of the feed storage, or
+ input file name for a stream */
+ pid_t pid; /* Of ffmpeg process */
+ time_t pid_start; /* Of ffmpeg process */
+ char **child_argv;
+ struct FFServerStream *next;
+ unsigned bandwidth; /* bandwidth, in kbits/s */
+ /* RTSP options */
+ char *rtsp_option;
+ /* multicast specific */
+ int is_multicast;
+ struct in_addr multicast_ip;
+ int multicast_port; /* first port used for multicast */
+ int multicast_ttl;
+ int loop; /* if true, send the stream in loops (only meaningful if file) */
+
+ /* feed specific */
+ int feed_opened; /* true if someone is writing to the feed */
+ int is_feed; /* true if it is a feed */
+ int readonly; /* True if writing is prohibited to the file */
+ int truncate; /* True if feeder connection truncate the feed file */
+ int conns_served;
+ int64_t bytes_served;
+ int64_t feed_max_size; /* maximum storage size, zero means unlimited */
+ int64_t feed_write_index; /* current write position in feed (it wraps around) */
+ int64_t feed_size; /* current size of feed */
+ struct FFServerStream *next_feed;
+} FFServerStream;
+
+typedef struct FFServerConfig {
+ char *filename;
+ FFServerStream *first_feed; /* contains only feeds */
+ FFServerStream *first_stream; /* contains all streams, including feeds */
+ unsigned int nb_max_http_connections;
+ unsigned int nb_max_connections;
+ uint64_t max_bandwidth;
+ int debug;
+ char logfilename[1024];
+ struct sockaddr_in http_addr;
+ struct sockaddr_in rtsp_addr;
+ int errors;
+ int warnings;
+ int use_defaults;
+ // Following variables MUST NOT be used outside configuration parsing code.
+ enum AVCodecID guessed_audio_codec_id;
+ enum AVCodecID guessed_video_codec_id;
+ AVDictionary *video_opts; /* AVOptions for video encoder */
+ AVDictionary *audio_opts; /* AVOptions for audio encoder */
+ AVCodecContext *dummy_actx; /* Used internally to test audio AVOptions. */
+ AVCodecContext *dummy_vctx; /* Used internally to test video AVOptions. */
+ int no_audio;
+ int no_video;
+ int line_num;
+ int stream_use_defaults;
+} FFServerConfig;
+
+void ffserver_get_arg(char *buf, int buf_size, const char **pp);
+
+void ffserver_parse_acl_row(FFServerStream *stream, FFServerStream* feed,
+ FFServerIPAddressACL *ext_acl,
+ const char *p, const char *filename, int line_num);
+
+int ffserver_parse_ffconfig(const char *filename, FFServerConfig *config);
+
+void ffserver_free_child_args(void *argsp);
+
+#endif /* FFSERVER_CONFIG_H */
}
}
-static int decode_p_block(FourXContext *f, uint16_t *dst, uint16_t *src,
+static int decode_p_block(FourXContext *f, uint16_t *dst, const uint16_t *src,
int log2w, int log2h, int stride)
{
- const int index = size2index[log2h][log2w];
- const int h = 1 << log2h;
- int code = get_vlc2(&f->gb,
- block_type_vlc[1 - (f->version > 1)][index].table,
- BLOCK_TYPE_VLC_BITS, 1);
- uint16_t *start = f->last_frame_buffer;
- uint16_t *end = start + stride * (f->avctx->height - h + 1) - (1 << log2w);
- int ret;
- int scale = 1;
+ int index, h, code, ret, scale = 1;
+ uint16_t *start, *end;
unsigned dc = 0;
- av_assert0(code >= 0 && code <= 6 && log2w >= 0);
+ av_assert0(log2w >= 0 && log2h >= 0);
+
+ index = size2index[log2h][log2w];
+ av_assert0(index >= 0);
+
+ h = 1 << log2h;
+ code = get_vlc2(&f->gb, block_type_vlc[1 - (f->version > 1)][index].table,
+ BLOCK_TYPE_VLC_BITS, 1);
+ av_assert0(code >= 0 && code <= 6);
+
+ start = f->last_frame_buffer;
+ end = start + stride * (f->avctx->height - h + 1) - (1 << log2w);
if (code == 1) {
log2h--;
vda.h \
vdpau.h \
version.h \
+ vorbis_parser.h \
xvmc.h \
OBJS = allcodecs.o \
resample.o \
resample2.o \
utils.o \
+ vorbis_parser.o \
+ xiph.o \
# subsystems
OBJS-$(CONFIG_AANDCTTABLES) += aandcttab.o
OBJS-$(CONFIG_LPC) += lpc.o
OBJS-$(CONFIG_LSP) += lsp.o
OBJS-$(CONFIG_MDCT) += mdct_fixed.o mdct_float.o mdct_fixed_32.o
-OBJS-$(CONFIG_ME_CMP) += me_cmp.o dsputil_compat.o
+OBJS-$(CONFIG_ME_CMP) += me_cmp.o
OBJS-$(CONFIG_MPEG_ER) += mpeg_er.o
OBJS-$(CONFIG_MPEGAUDIO) += mpegaudio.o mpegaudiodata.o \
mpegaudiodecheader.o
OBJS-$(CONFIG_ANM_DECODER) += anm.o
OBJS-$(CONFIG_ANSI_DECODER) += ansi.o cga_data.o
OBJS-$(CONFIG_APE_DECODER) += apedec.o
+OBJS-$(CONFIG_APNG_DECODER) += png.o pngdec.o pngdsp.o
OBJS-$(CONFIG_SSA_DECODER) += assdec.o ass.o ass_split.o
OBJS-$(CONFIG_SSA_ENCODER) += assenc.o ass.o
OBJS-$(CONFIG_ASS_DECODER) += assdec.o ass.o ass_split.o
OBJS-$(CONFIG_JACOSUB_DECODER) += jacosubdec.o ass.o
OBJS-$(CONFIG_JPEG2000_ENCODER) += j2kenc.o mqcenc.o mqc.o jpeg2000.o \
jpeg2000dwt.o
-OBJS-$(CONFIG_JPEG2000_DECODER) += jpeg2000dec.o jpeg2000.o \
+OBJS-$(CONFIG_JPEG2000_DECODER) += jpeg2000dec.o jpeg2000.o jpeg2000dsp.o \
jpeg2000dwt.o mqcdec.o mqc.o
OBJS-$(CONFIG_JPEGLS_DECODER) += jpeglsdec.o jpegls.o
OBJS-$(CONFIG_JPEGLS_ENCODER) += jpeglsenc.o jpegls.o
OBJS-$(CONFIG_SP5X_DECODER) += sp5xdec.o
OBJS-$(CONFIG_SRT_DECODER) += srtdec.o ass.o
OBJS-$(CONFIG_SRT_ENCODER) += srtenc.o ass_split.o
+OBJS-$(CONFIG_STL_DECODER) += textdec.o ass.o
OBJS-$(CONFIG_SUBRIP_DECODER) += srtdec.o ass.o
OBJS-$(CONFIG_SUBRIP_ENCODER) += srtenc.o ass_split.o
OBJS-$(CONFIG_SUBVIEWER1_DECODER) += textdec.o ass.o
OBJS-$(CONFIG_TARGA_DECODER) += targa.o
OBJS-$(CONFIG_TARGA_ENCODER) += targaenc.o rle.o
OBJS-$(CONFIG_TARGA_Y216_DECODER) += targa_y216dec.o
-OBJS-$(CONFIG_THEORA_DECODER) += xiph.o
OBJS-$(CONFIG_TIERTEXSEQVIDEO_DECODER) += tiertexseqv.o
OBJS-$(CONFIG_TIFF_DECODER) += tiff.o lzw.o faxcompr.o tiff_data.o tiff_common.o
OBJS-$(CONFIG_TIFF_ENCODER) += tiffenc.o rle.o lzwenc.o tiff_data.o
OBJS-$(CONFIG_V210X_DECODER) += v210x.o
OBJS-$(CONFIG_VB_DECODER) += vb.o
OBJS-$(CONFIG_VBLE_DECODER) += vble.o
-OBJS-$(CONFIG_VC1_DECODER) += vc1dec.o vc1.o vc1data.o vc1dsp.o \
+OBJS-$(CONFIG_VC1_DECODER) += vc1dec.o vc1_block.o vc1_loopfilter.o \
+ vc1_mc.o vc1_pred.o vc1.o vc1data.o \
+ vc1dsp.o \
msmpeg4dec.o msmpeg4.o msmpeg4data.o \
wmv2dsp.o
OBJS-$(CONFIG_VCR1_DECODER) += vcr1.o
OBJS-$(CONFIG_VMDVIDEO_DECODER) += vmdvideo.o
OBJS-$(CONFIG_VMNC_DECODER) += vmnc.o
OBJS-$(CONFIG_VORBIS_DECODER) += vorbisdec.o vorbisdsp.o vorbis.o \
- vorbis_data.o xiph.o
+ vorbis_data.o
OBJS-$(CONFIG_VORBIS_ENCODER) += vorbisenc.o vorbis.o \
vorbis_data.o
OBJS-$(CONFIG_VP3_DECODER) += vp3.o
OBJS-$(CONFIG_ADTS_MUXER) += mpeg4audio.o
OBJS-$(CONFIG_CAF_DEMUXER) += mpeg4audio.o mpegaudiodata.o \
ac3tab.o
-OBJS-$(CONFIG_FLAC_DEMUXER) += flac.o flacdata.o vorbis_data.o \
- vorbis_parser.o xiph.o
+OBJS-$(CONFIG_FLAC_DEMUXER) += flac.o flacdata.o vorbis_data.o
OBJS-$(CONFIG_FLAC_MUXER) += flac.o flacdata.o vorbis_data.o
OBJS-$(CONFIG_FLV_DEMUXER) += mpeg4audio.o
OBJS-$(CONFIG_GXF_DEMUXER) += mpeg12data.o
OBJS-$(CONFIG_IFF_DEMUXER) += iff.o
OBJS-$(CONFIG_ISMV_MUXER) += mpeg4audio.o mpegaudiodata.o
OBJS-$(CONFIG_LATM_MUXER) += mpeg4audio.o
-OBJS-$(CONFIG_MATROSKA_AUDIO_MUXER) += xiph.o mpeg4audio.o vorbis_data.o \
+OBJS-$(CONFIG_MATROSKA_AUDIO_MUXER) += mpeg4audio.o vorbis_data.o \
flac.o flacdata.o
-OBJS-$(CONFIG_MATROSKA_DEMUXER) += mpeg4audio.o mpegaudiodata.o \
- vorbis_parser.o xiph.o
+OBJS-$(CONFIG_MATROSKA_DEMUXER) += mpeg4audio.o mpegaudiodata.o
OBJS-$(CONFIG_MATROSKA_MUXER) += mpeg4audio.o mpegaudiodata.o \
- flac.o flacdata.o vorbis_data.o xiph.o
+ flac.o flacdata.o vorbis_data.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
OBJS-$(CONFIG_MPEGTS_DEMUXER) += mpeg4audio.o mpegaudiodata.o
OBJS-$(CONFIG_MXF_MUXER) += dnxhddata.o
OBJS-$(CONFIG_NUT_MUXER) += mpegaudiodata.o
-OBJS-$(CONFIG_OGA_MUXER) += xiph.o flac.o flacdata.o
-OBJS-$(CONFIG_OGG_DEMUXER) += xiph.o flac.o flacdata.o \
- mpeg12data.o vorbis_parser.o \
+OBJS-$(CONFIG_OGA_MUXER) += flac.o flacdata.o
+OBJS-$(CONFIG_OGG_DEMUXER) += mpeg12data.o \
dirac.o vorbis_data.o
-OBJS-$(CONFIG_OGG_MUXER) += xiph.o flac.o flacdata.o \
+OBJS-$(CONFIG_OGG_MUXER) += flac.o flacdata.o \
vorbis_data.o
-OBJS-$(CONFIG_RTP_MUXER) += mpeg4audio.o xiph.o
+OBJS-$(CONFIG_RTP_MUXER) += mpeg4audio.o
OBJS-$(CONFIG_RTPDEC) += mjpeg.o
OBJS-$(CONFIG_SPDIF_DEMUXER) += aacadtsdec.o mpeg4audio.o
OBJS-$(CONFIG_SPDIF_MUXER) += dca.o
OBJS-$(CONFIG_TAK_DEMUXER) += tak.o
OBJS-$(CONFIG_WEBM_MUXER) += mpeg4audio.o mpegaudiodata.o \
- xiph.o flac.o flacdata.o \
+ flac.o flacdata.o \
vorbis_data.o
-OBJS-$(CONFIG_WEBM_DASH_MANIFEST_DEMUXER) += vorbis_parser.o xiph.o
OBJS-$(CONFIG_WTV_DEMUXER) += mpeg4audio.o mpegaudiodata.o
# libavfilter dependencies
OBJS-$(CONFIG_LIBVO_AMRWBENC_ENCODER) += libvo-amrwbenc.o
OBJS-$(CONFIG_LIBVORBIS_DECODER) += libvorbisdec.o
OBJS-$(CONFIG_LIBVORBIS_ENCODER) += libvorbisenc.o \
- vorbis_data.o vorbis_parser.o xiph.o
+ vorbis_data.o
OBJS-$(CONFIG_LIBVPX_VP8_DECODER) += libvpxdec.o
OBJS-$(CONFIG_LIBVPX_VP8_ENCODER) += libvpxenc.o
OBJS-$(CONFIG_LIBVPX_VP9_DECODER) += libvpxdec.o libvpx.o
OBJS-$(CONFIG_VC1_PARSER) += vc1_parser.o vc1.o vc1data.o vc1dsp.o \
msmpeg4.o msmpeg4data.o mpeg4video.o \
h263.o
-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
* channel element - generic struct for SCE/CPE/CCE/LFE
*/
typedef struct ChannelElement {
+ int present;
// CPE specific
int common_window; ///< Set if channels share a common 'IndividualChannelStream' in bitstream.
int ms_mode; ///< Signals mid/side stereo flags coding mode (used by encoder)
ChannelElement *che[4][MAX_ELEM_ID];
ChannelElement *tag_che_map[4][MAX_ELEM_ID];
int tags_mapped;
+ int warned_remapping_once;
/** @} */
/**
FFTContext mdct_ld;
FFTContext mdct_ltp;
FmtConvertContext fmt_conv;
- AVFloatDSPContext fdsp;
+ AVFloatDSPContext *fdsp;
int random_state;
/** @} */
* If we seem to have encountered such a stream, transfer
* the LFE[0] element to the SCE[1]'s mapping */
if (ac->tags_mapped == tags_per_config[ac->oc[1].m4ac.chan_config] - 1 && (type == TYPE_LFE || type == TYPE_SCE)) {
+ if (!ac->warned_remapping_once && (type != TYPE_LFE || elem_id != 0)) {
+ av_log(ac->avctx, AV_LOG_WARNING,
+ "This stream seems to incorrectly report its last channel as %s[%d], mapping to LFE[0]\n",
+ type == TYPE_SCE ? "SCE" : "LFE", elem_id);
+ ac->warned_remapping_once++;
+ }
ac->tags_mapped++;
return ac->tag_che_map[type][elem_id] = ac->che[TYPE_LFE][0];
}
return ac->tag_che_map[TYPE_CPE][elem_id] = ac->che[TYPE_CPE][1];
}
case 4:
+ /* Some streams incorrectly code 4.0 audio as
+ * SCE[0] CPE[0] LFE[0]
+ * instead of
+ * SCE[0] CPE[0] SCE[1].
+ * If we seem to have encountered such a stream, transfer
+ * the SCE[1] element to the LFE[0]'s mapping */
+ if (ac->tags_mapped == tags_per_config[ac->oc[1].m4ac.chan_config] - 1 && (type == TYPE_LFE || type == TYPE_SCE)) {
+ if (!ac->warned_remapping_once && (type != TYPE_SCE || elem_id != 1)) {
+ av_log(ac->avctx, AV_LOG_WARNING,
+ "This stream seems to incorrectly report its last channel as %s[%d], mapping to SCE[1]\n",
+ type == TYPE_SCE ? "SCE" : "LFE", elem_id);
+ ac->warned_remapping_once++;
+ }
+ ac->tags_mapped++;
+ return ac->tag_che_map[type][elem_id] = ac->che[TYPE_SCE][1];
+ }
if (ac->tags_mapped == 2 &&
ac->oc[1].m4ac.chan_config == 4 &&
type == TYPE_SCE) {
syn_ele = TYPE_LFE;
break;
default:
+ // AAC_CHANNEL_OFF has no channel map
av_assert0(0);
}
layout_map[0][0] = syn_ele;
ff_aac_sbr_init();
ff_fmt_convert_init(&ac->fmt_conv, avctx);
- avpriv_float_dsp_init(&ac->fdsp, avctx->flags & CODEC_FLAG_BITEXACT);
+ ac->fdsp = avpriv_float_dsp_alloc(avctx->flags & CODEC_FLAG_BITEXACT);
+ if (!ac->fdsp) {
+ return AVERROR(ENOMEM);
+ }
ac->random_state = 0x1f2e3d4c;
int ms_present)
{
int idx;
+ int max_idx = cpe->ch[0].ics.num_window_groups * cpe->ch[0].ics.max_sfb;
if (ms_present == 1) {
- for (idx = 0;
- idx < cpe->ch[0].ics.num_window_groups * cpe->ch[0].ics.max_sfb;
- idx++)
+ for (idx = 0; idx < max_idx; idx++)
cpe->ms_mask[idx] = get_bits1(gb);
} else if (ms_present == 2) {
- memset(cpe->ms_mask, 1, sizeof(cpe->ms_mask[0]) * cpe->ch[0].ics.num_window_groups * cpe->ch[0].ics.max_sfb);
+ memset(cpe->ms_mask, 1, max_idx * sizeof(cpe->ms_mask[0]));
}
}
cfo[k] = ac->random_state;
}
- band_energy = ac->fdsp.scalarproduct_float(cfo, cfo, off_len);
+ band_energy = ac->fdsp->scalarproduct_float(cfo, cfo, off_len);
scale = sf[idx] / sqrtf(band_energy);
- ac->fdsp.vector_fmul_scalar(cfo, cfo, scale, off_len);
+ ac->fdsp->vector_fmul_scalar(cfo, cfo, scale, off_len);
}
} else {
const float *vq = ff_aac_codebook_vector_vals[cbt_m1];
}
} while (len -= 2);
- ac->fdsp.vector_fmul_scalar(cfo, cfo, sf[idx], off_len);
+ ac->fdsp->vector_fmul_scalar(cfo, cfo, sf[idx], off_len);
}
}
cpe->ch[0].band_type[idx] < NOISE_BT &&
cpe->ch[1].band_type[idx] < NOISE_BT) {
for (group = 0; group < ics->group_len[g]; group++) {
- ac->fdsp.butterflies_float(ch0 + group * 128 + offsets[i],
+ ac->fdsp->butterflies_float(ch0 + group * 128 + offsets[i],
ch1 + group * 128 + offsets[i],
offsets[i+1] - offsets[i]);
}
c *= 1 - 2 * cpe->ms_mask[idx];
scale = c * sce1->sf[idx];
for (group = 0; group < ics->group_len[g]; group++)
- ac->fdsp.vector_fmul_scalar(coef1 + group * 128 + offsets[i],
+ ac->fdsp->vector_fmul_scalar(coef1 + group * 128 + offsets[i],
coef0 + group * 128 + offsets[i],
scale,
offsets[i + 1] - offsets[i]);
{
int crc_flag = 0;
int res = cnt;
- switch (get_bits(gb, 4)) { // extension type
+ int type = get_bits(gb, 4);
+
+ if (ac->avctx->debug & FF_DEBUG_STARTCODE)
+ av_log(ac->avctx, AV_LOG_DEBUG, "extension type: %d len:%d\n", type, cnt);
+
+ switch (type) { // extension type
case EXT_SBR_DATA_CRC:
crc_flag++;
case EXT_SBR_DATA:
const float *swindow_prev = ics->use_kb_window[1] ? ff_aac_kbd_short_128 : ff_sine_128;
if (ics->window_sequence[0] != LONG_STOP_SEQUENCE) {
- ac->fdsp.vector_fmul(in, in, lwindow_prev, 1024);
+ ac->fdsp->vector_fmul(in, in, lwindow_prev, 1024);
} else {
memset(in, 0, 448 * sizeof(float));
- ac->fdsp.vector_fmul(in + 448, in + 448, swindow_prev, 128);
+ ac->fdsp->vector_fmul(in + 448, in + 448, swindow_prev, 128);
}
if (ics->window_sequence[0] != LONG_START_SEQUENCE) {
- ac->fdsp.vector_fmul_reverse(in + 1024, in + 1024, lwindow, 1024);
+ ac->fdsp->vector_fmul_reverse(in + 1024, in + 1024, lwindow, 1024);
} else {
- ac->fdsp.vector_fmul_reverse(in + 1024 + 448, in + 1024 + 448, swindow, 128);
+ ac->fdsp->vector_fmul_reverse(in + 1024 + 448, in + 1024 + 448, swindow, 128);
memset(in + 1024 + 576, 0, 448 * sizeof(float));
}
ac->mdct_ltp.mdct_calc(&ac->mdct_ltp, out, in);
if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
memcpy(saved_ltp, saved, 512 * sizeof(float));
memset(saved_ltp + 576, 0, 448 * sizeof(float));
- ac->fdsp.vector_fmul_reverse(saved_ltp + 448, ac->buf_mdct + 960, &swindow[64], 64);
+ ac->fdsp->vector_fmul_reverse(saved_ltp + 448, ac->buf_mdct + 960, &swindow[64], 64);
for (i = 0; i < 64; i++)
saved_ltp[i + 512] = ac->buf_mdct[1023 - i] * swindow[63 - i];
} else if (ics->window_sequence[0] == LONG_START_SEQUENCE) {
memcpy(saved_ltp, ac->buf_mdct + 512, 448 * sizeof(float));
memset(saved_ltp + 576, 0, 448 * sizeof(float));
- ac->fdsp.vector_fmul_reverse(saved_ltp + 448, ac->buf_mdct + 960, &swindow[64], 64);
+ ac->fdsp->vector_fmul_reverse(saved_ltp + 448, ac->buf_mdct + 960, &swindow[64], 64);
for (i = 0; i < 64; i++)
saved_ltp[i + 512] = ac->buf_mdct[1023 - i] * swindow[63 - i];
} else { // LONG_STOP or ONLY_LONG
- ac->fdsp.vector_fmul_reverse(saved_ltp, ac->buf_mdct + 512, &lwindow[512], 512);
+ ac->fdsp->vector_fmul_reverse(saved_ltp, ac->buf_mdct + 512, &lwindow[512], 512);
for (i = 0; i < 512; i++)
saved_ltp[i + 512] = ac->buf_mdct[1023 - i] * lwindow[511 - i];
}
*/
if ((ics->window_sequence[1] == ONLY_LONG_SEQUENCE || ics->window_sequence[1] == LONG_STOP_SEQUENCE) &&
(ics->window_sequence[0] == ONLY_LONG_SEQUENCE || ics->window_sequence[0] == LONG_START_SEQUENCE)) {
- ac->fdsp.vector_fmul_window( out, saved, buf, lwindow_prev, 512);
+ ac->fdsp->vector_fmul_window( out, saved, buf, lwindow_prev, 512);
} else {
memcpy( out, saved, 448 * sizeof(float));
if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
- ac->fdsp.vector_fmul_window(out + 448 + 0*128, saved + 448, buf + 0*128, swindow_prev, 64);
- ac->fdsp.vector_fmul_window(out + 448 + 1*128, buf + 0*128 + 64, buf + 1*128, swindow, 64);
- ac->fdsp.vector_fmul_window(out + 448 + 2*128, buf + 1*128 + 64, buf + 2*128, swindow, 64);
- ac->fdsp.vector_fmul_window(out + 448 + 3*128, buf + 2*128 + 64, buf + 3*128, swindow, 64);
- ac->fdsp.vector_fmul_window(temp, buf + 3*128 + 64, buf + 4*128, swindow, 64);
+ ac->fdsp->vector_fmul_window(out + 448 + 0*128, saved + 448, buf + 0*128, swindow_prev, 64);
+ ac->fdsp->vector_fmul_window(out + 448 + 1*128, buf + 0*128 + 64, buf + 1*128, swindow, 64);
+ ac->fdsp->vector_fmul_window(out + 448 + 2*128, buf + 1*128 + 64, buf + 2*128, swindow, 64);
+ ac->fdsp->vector_fmul_window(out + 448 + 3*128, buf + 2*128 + 64, buf + 3*128, swindow, 64);
+ ac->fdsp->vector_fmul_window(temp, buf + 3*128 + 64, buf + 4*128, swindow, 64);
memcpy( out + 448 + 4*128, temp, 64 * sizeof(float));
} else {
- ac->fdsp.vector_fmul_window(out + 448, saved + 448, buf, swindow_prev, 64);
+ ac->fdsp->vector_fmul_window(out + 448, saved + 448, buf, swindow_prev, 64);
memcpy( out + 576, buf + 64, 448 * sizeof(float));
}
}
// buffer update
if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
memcpy( saved, temp + 64, 64 * sizeof(float));
- ac->fdsp.vector_fmul_window(saved + 64, buf + 4*128 + 64, buf + 5*128, swindow, 64);
- ac->fdsp.vector_fmul_window(saved + 192, buf + 5*128 + 64, buf + 6*128, swindow, 64);
- ac->fdsp.vector_fmul_window(saved + 320, buf + 6*128 + 64, buf + 7*128, swindow, 64);
+ ac->fdsp->vector_fmul_window(saved + 64, buf + 4*128 + 64, buf + 5*128, swindow, 64);
+ ac->fdsp->vector_fmul_window(saved + 192, buf + 5*128 + 64, buf + 6*128, swindow, 64);
+ ac->fdsp->vector_fmul_window(saved + 320, buf + 6*128 + 64, buf + 7*128, swindow, 64);
memcpy( saved + 448, buf + 7*128 + 64, 64 * sizeof(float));
} else if (ics->window_sequence[0] == LONG_START_SEQUENCE) {
memcpy( saved, buf + 512, 448 * sizeof(float));
if (ics->use_kb_window[1]) {
// AAC LD uses a low overlap sine window instead of a KBD window
memcpy(out, saved, 192 * sizeof(float));
- ac->fdsp.vector_fmul_window(out + 192, saved + 192, buf, ff_sine_128, 64);
+ ac->fdsp->vector_fmul_window(out + 192, saved + 192, buf, ff_sine_128, 64);
memcpy( out + 320, buf + 64, 192 * sizeof(float));
} else {
- ac->fdsp.vector_fmul_window(out, saved, buf, ff_sine_512, 256);
+ ac->fdsp->vector_fmul_window(out, saved, buf, ff_sine_512, 256);
}
// buffer update
for (type = 3; type >= 0; type--) {
for (i = 0; i < MAX_ELEM_ID; i++) {
ChannelElement *che = ac->che[type][i];
- if (che) {
+ if (che && che->present) {
if (type <= TYPE_CPE)
apply_channel_coupling(ac, che, type, i, BEFORE_TNS, apply_dependent_coupling);
if (ac->oc[1].m4ac.object_type == AOT_AAC_LTP) {
}
if (type <= TYPE_CCE)
apply_channel_coupling(ac, che, type, i, AFTER_IMDCT, apply_independent_coupling);
+ che->present = 0;
+ } else if (che) {
+ av_log(ac->avctx, AV_LOG_VERBOSE, "ChannelElement %d.%d missing \n", type, i);
}
}
}
elem_type, elem_id);
return AVERROR_INVALIDDATA;
}
+ che->present = 1;
if (aot != AOT_ER_AAC_ELD)
skip_bits(gb, 4);
switch (elem_type) {
while ((elem_type = get_bits(gb, 3)) != TYPE_END) {
elem_id = get_bits(gb, 4);
+ if (avctx->debug & FF_DEBUG_STARTCODE)
+ av_log(avctx, AV_LOG_DEBUG, "Elem type:%x id:%x\n", elem_type, elem_id);
+
if (elem_type < TYPE_DSE) {
if (!(che=get_che(ac, elem_type, elem_id))) {
av_log(ac->avctx, AV_LOG_ERROR, "channel element %d.%d is not allocated\n",
goto fail;
}
samples = 1024;
+ che->present = 1;
}
switch (elem_type) {
ff_mdct_end(&ac->mdct_small);
ff_mdct_end(&ac->mdct_ld);
ff_mdct_end(&ac->mdct_ltp);
+ av_freep(&ac->fdsp);
return 0;
}
.version = LIBAVUTIL_VERSION_INT,
};
+static const AVProfile profiles[] = {
+ { FF_PROFILE_AAC_MAIN, "Main" },
+ { FF_PROFILE_AAC_LOW, "LC" },
+ { FF_PROFILE_AAC_SSR, "SSR" },
+ { FF_PROFILE_AAC_LTP, "LTP" },
+ { FF_PROFILE_AAC_HE, "HE-AAC" },
+ { FF_PROFILE_AAC_HE_V2, "HE-AACv2" },
+ { FF_PROFILE_AAC_LD, "LD" },
+ { FF_PROFILE_AAC_ELD, "ELD" },
+ { FF_PROFILE_UNKNOWN },
+};
+
AVCodec ff_aac_decoder = {
.name = "aac",
.long_name = NULL_IF_CONFIG_SMALL("AAC (Advanced Audio Coding)"),
.channel_layouts = aac_channel_layout,
.flush = flush,
.priv_class = &aac_decoder_class,
+ .profiles = profiles,
};
/*
.capabilities = CODEC_CAP_CHANNEL_CONF | CODEC_CAP_DR1,
.channel_layouts = aac_channel_layout,
.flush = flush,
+ .profiles = profiles,
};
int i;
float *output = sce->ret_buf;
- apply_window[sce->ics.window_sequence[0]](&s->fdsp, sce, audio);
+ apply_window[sce->ics.window_sequence[0]](s->fdsp, sce, audio);
if (sce->ics.window_sequence[0] != EIGHT_SHORT_SEQUENCE)
s->mdct1024.mdct_calc(&s->mdct1024, sce->coeffs, output);
ics->group_len[w] = wi[ch].grouping[w];
apply_window_and_mdct(s, &cpe->ch[ch], overlap);
+ if (isnan(cpe->ch->coeffs[0])) {
+ av_log(avctx, AV_LOG_ERROR, "Input contains NaN\n");
+ return AVERROR(EINVAL);
+ }
}
start_ch += chans;
}
ff_psy_preprocess_end(s->psypp);
av_freep(&s->buffer.samples);
av_freep(&s->cpe);
+ av_freep(&s->fdsp);
ff_af_queue_close(&s->afq);
return 0;
}
{
int ret = 0;
- avpriv_float_dsp_init(&s->fdsp, avctx->flags & CODEC_FLAG_BITEXACT);
+ s->fdsp = avpriv_float_dsp_alloc(avctx->flags & CODEC_FLAG_BITEXACT);
+ if (!s->fdsp)
+ return AVERROR(ENOMEM);
// window init
ff_kbd_window_init(ff_aac_kbd_long_1024, 4.0, 1024);
for (i = 0; i < 428; i++)
ff_aac_pow34sf_tab[i] = sqrt(ff_aac_pow2sf_tab[i] * sqrt(ff_aac_pow2sf_tab[i]));
- avctx->delay = 1024;
+ avctx->initial_padding = 1024;
ff_af_queue_init(avctx, &s->afq);
return 0;
PutBitContext pb;
FFTContext mdct1024; ///< long (1024 samples) frame transform context
FFTContext mdct128; ///< short (128 samples) frame transform context
- AVFloatDSPContext fdsp;
+ AVFloatDSPContext *fdsp;
float *planar_samples[6]; ///< saved preprocessed input
int samplerate_index; ///< MPEG-4 samplerate index
static int sbr_make_f_master(AACContext *ac, SpectralBandReplication *sbr,
SpectrumParameters *spectrum)
{
- unsigned int temp, max_qmf_subbands;
+ unsigned int temp, max_qmf_subbands = 0;
unsigned int start_min, stop_min;
int k;
const int8_t *sbr_offset_ptr;
k = sbr->n_master;
} while (sb != sbr->kx[1] + sbr->m[1]);
- if (sbr->num_patches > 1 && sbr->patch_num_subbands[sbr->num_patches-1] < 3)
+ if (sbr->num_patches > 1 &&
+ sbr->patch_num_subbands[sbr->num_patches - 1] < 3)
sbr->num_patches--;
return 0;
memcpy(q_temp[i + 2*ch_data->t_env[0]], sbr->q_m[0], m_max * sizeof(sbr->q_m[0][0]));
}
} else if (h_SL) {
- memcpy(g_temp[2*ch_data->t_env[0]], g_temp[2*ch_data->t_env_num_env_old], 4*sizeof(g_temp[0]));
- memcpy(q_temp[2*ch_data->t_env[0]], q_temp[2*ch_data->t_env_num_env_old], 4*sizeof(q_temp[0]));
+ for (i = 0; i < 4; i++) {
+ memcpy(g_temp[i + 2 * ch_data->t_env[0]],
+ g_temp[i + 2 * ch_data->t_env_num_env_old],
+ sizeof(g_temp[0]));
+ memcpy(q_temp[i + 2 * ch_data->t_env[0]],
+ q_temp[i + 2 * ch_data->t_env_num_env_old],
+ sizeof(q_temp[0]));
+ }
}
for (e = 0; e < ch_data->bs_num_env; e++) {
}
for (ch = 0; ch < nch; ch++) {
/* decode channel */
- sbr_qmf_analysis(&ac->fdsp, &sbr->mdct_ana, &sbr->dsp, ch ? R : L, sbr->data[ch].analysis_filterbank_samples,
+ 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,
nch = 2;
}
- sbr_qmf_synthesis(&sbr->mdct, &sbr->dsp, &ac->fdsp,
+ sbr_qmf_synthesis(&sbr->mdct, &sbr->dsp, ac->fdsp,
L, sbr->X[0], sbr->qmf_filter_scratch,
sbr->data[0].synthesis_filterbank_samples,
&sbr->data[0].synthesis_filterbank_samples_offset,
downsampled);
if (nch == 2)
- sbr_qmf_synthesis(&sbr->mdct, &sbr->dsp, &ac->fdsp,
+ sbr_qmf_synthesis(&sbr->mdct, &sbr->dsp, ac->fdsp,
R, sbr->X[1], sbr->qmf_filter_scratch,
sbr->data[1].synthesis_filterbank_samples,
&sbr->data[1].synthesis_filterbank_samples_offset,
ld1 {v30.16b}, [x10]
mov x7, #-8
movrel x12, pmmp
- ldr x3, [x3, x2, lsl #3]
+ ldr x4, [x3, x2, lsl #3]
+ add x3, x3, x4
movrel x13, mppm
movrel x14, X(ff_cos_16)
ld1 {v31.16b}, [x11]
endfunc
const fft_tab_neon
- .quad fft4_neon
- .quad fft8_neon
- .quad fft16_neon
- .quad fft32_neon
- .quad fft64_neon
- .quad fft128_neon
- .quad fft256_neon
- .quad fft512_neon
- .quad fft1024_neon
- .quad fft2048_neon
- .quad fft4096_neon
- .quad fft8192_neon
- .quad fft16384_neon
- .quad fft32768_neon
- .quad fft65536_neon
+ .quad fft4_neon - fft_tab_neon
+ .quad fft8_neon - fft_tab_neon
+ .quad fft16_neon - fft_tab_neon
+ .quad fft32_neon - fft_tab_neon
+ .quad fft64_neon - fft_tab_neon
+ .quad fft128_neon - fft_tab_neon
+ .quad fft256_neon - fft_tab_neon
+ .quad fft512_neon - fft_tab_neon
+ .quad fft1024_neon - fft_tab_neon
+ .quad fft2048_neon - fft_tab_neon
+ .quad fft4096_neon - fft_tab_neon
+ .quad fft8192_neon - fft_tab_neon
+ .quad fft16384_neon - fft_tab_neon
+ .quad fft32768_neon - fft_tab_neon
+ .quad fft65536_neon - fft_tab_neon
endconst
const pmmp, align=4
uzp1 v12.4s, v4.4s, v5.4s // exp[11 - 14].re
uzp2 v13.4s, v4.4s, v5.4s // exp[11 - 14].im
zip1 v14.4s, v6.4s, v7.4s // exp[5,10].re/exp[5,10].im
- add x5, x5, x3, lsl #3
- ldr x5, [x5]
+ ldr x6, [x5, x3, lsl #3]
+ add x5, x5, x6
mov x10, x0
blr x5
ldp x20, x30, [sp]
endfunc
const fft_tab_neon
- .quad fft15_neon
- .quad fft30_neon
- .quad fft60_neon
- .quad fft120_neon
- .quad fft240_neon
- .quad fft480_neon
- .quad fft960_neon
+ .quad fft15_neon - fft_tab_neon
+ .quad fft30_neon - fft_tab_neon
+ .quad fft60_neon - fft_tab_neon
+ .quad fft120_neon - fft_tab_neon
+ .quad fft240_neon - fft_tab_neon
+ .quad fft480_neon - fft_tab_neon
+ .quad fft960_neon - fft_tab_neon
endconst
function ff_celt_imdct_half_neon, export=1
#if (USE_FIXED)
s->fdsp = avpriv_alloc_fixed_dsp(avctx->flags & CODEC_FLAG_BITEXACT);
#else
- avpriv_float_dsp_init(&s->fdsp, avctx->flags & CODEC_FLAG_BITEXACT);
+ s->fdsp = avpriv_float_dsp_alloc(avctx->flags & CODEC_FLAG_BITEXACT);
#endif
ff_ac3dsp_init(&s->ac3dsp, avctx->flags & CODEC_FLAG_BITEXACT);
s->fdsp->vector_fmul_window_scaled(s->outptr[ch - 1], s->delay[ch - 1],
s->tmp_output, s->window, 128, 8);
#else
- s->fdsp.vector_fmul_window(s->outptr[ch - 1], s->delay[ch - 1],
+ s->fdsp->vector_fmul_window(s->outptr[ch - 1], s->delay[ch - 1],
s->tmp_output, s->window, 128);
#endif
for (i = 0; i < 128; i++)
s->fdsp->vector_fmul_window_scaled(s->outptr[ch - 1], s->delay[ch - 1],
s->tmp_output, s->window, 128, 8);
#else
- s->fdsp.vector_fmul_window(s->outptr[ch - 1], s->delay[ch - 1],
+ s->fdsp->vector_fmul_window(s->outptr[ch - 1], s->delay[ch - 1],
s->tmp_output, s->window, 128);
#endif
memcpy(s->delay[ch - 1], s->tmp_output + 128, 128 * sizeof(FFTSample));
AC3DecodeContext *s = avctx->priv_data;
ff_mdct_end(&s->imdct_512);
ff_mdct_end(&s->imdct_256);
-#if (USE_FIXED)
av_freep(&s->fdsp);
-#endif
return 0;
}
#if USE_FIXED
AVFixedDSPContext *fdsp;
#else
- AVFloatDSPContext fdsp;
+ AVFloatDSPContext *fdsp;
#endif
AC3DSPContext ac3dsp;
FmtConvertContext fmt_conv; ///< optimized conversion functions
av_freep(&s->qmant_buffer);
av_freep(&s->cpl_coord_exp_buffer);
av_freep(&s->cpl_coord_mant_buffer);
+ av_freep(&s->fdsp);
for (blk = 0; blk < s->num_blocks; blk++) {
AC3Block *block = &s->blocks[blk];
av_freep(&block->mdct_coef);
return ret;
avctx->frame_size = AC3_BLOCK_SIZE * s->num_blocks;
- avctx->delay = AC3_BLOCK_SIZE;
+ avctx->initial_padding = AC3_BLOCK_SIZE;
s->bitstream_mode = avctx->audio_service_type;
if (s->bitstream_mode == AV_AUDIO_SERVICE_TYPE_KARAOKE)
#define AC3ENC_OPT_NOT_INDICATED 0
#define AC3ENC_OPT_MODE_ON 2
#define AC3ENC_OPT_MODE_OFF 1
+#define AC3ENC_OPT_DSUREX_DPLIIZ 3
/* specific option values */
#define AC3ENC_OPT_LARGE_ROOM 1
#define AC3ENC_OPT_SMALL_ROOM 2
#define AC3ENC_OPT_DOWNMIX_LTRT 1
#define AC3ENC_OPT_DOWNMIX_LORO 2
+#define AC3ENC_OPT_DOWNMIX_DPLII 3 // reserved value in A/52, but used by encoders to indicate DPL2
#define AC3ENC_OPT_ADCONV_STANDARD 0
#define AC3ENC_OPT_ADCONV_HDCD 1
AVCodecContext *avctx; ///< parent AVCodecContext
PutBitContext pb; ///< bitstream writer context
AudioDSPContext adsp;
- AVFloatDSPContext fdsp;
+ AVFloatDSPContext *fdsp;
MECmpContext mecc;
AC3DSPContext ac3dsp; ///< AC-3 optimized functions
FFTContext mdct; ///< FFT context for MDCT calculation
av_cold int ff_ac3_float_encode_init(AVCodecContext *avctx)
{
AC3EncodeContext *s = avctx->priv_data;
- avpriv_float_dsp_init(&s->fdsp, avctx->flags & CODEC_FLAG_BITEXACT);
+ s->fdsp = avpriv_float_dsp_alloc(avctx->flags & CODEC_FLAG_BITEXACT);
+ if (!s->fdsp)
+ return AVERROR(ENOMEM);
return ff_ac3_encode_init(avctx);
}
{"off", "Not Dolby Surround Encoded", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_MODE_OFF }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dsur_mode"},
{"original", "Original Bit Stream", OFFSET(original), AV_OPT_TYPE_INT, {.i64 = AC3ENC_OPT_NONE }, AC3ENC_OPT_NONE, 1, AC3ENC_PARAM},
/* extended bitstream information */
-{"dmix_mode", "Preferred Stereo Downmix Mode", OFFSET(preferred_stereo_downmix), AV_OPT_TYPE_INT, {.i64 = AC3ENC_OPT_NONE }, AC3ENC_OPT_NONE, AC3ENC_OPT_DOWNMIX_LORO, AC3ENC_PARAM, "dmix_mode"},
+{"dmix_mode", "Preferred Stereo Downmix Mode", OFFSET(preferred_stereo_downmix), AV_OPT_TYPE_INT, {.i64 = AC3ENC_OPT_NONE }, AC3ENC_OPT_NONE, AC3ENC_OPT_DOWNMIX_DPLII, AC3ENC_PARAM, "dmix_mode"},
{"notindicated", "Not Indicated (default)", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_NOT_INDICATED }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dmix_mode"},
{"ltrt", "Lt/Rt Downmix Preferred", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_DOWNMIX_LTRT }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dmix_mode"},
{"loro", "Lo/Ro Downmix Preferred", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_DOWNMIX_LORO }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dmix_mode"},
+ {"dplii", "Dolby Pro Logic II Downmix Preferred", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_DOWNMIX_DPLII }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dmix_mode"},
{"ltrt_cmixlev", "Lt/Rt Center Mix Level", OFFSET(ltrt_center_mix_level), AV_OPT_TYPE_FLOAT, {.dbl = -1.0 }, -1.0, 2.0, AC3ENC_PARAM},
{"ltrt_surmixlev", "Lt/Rt Surround Mix Level", OFFSET(ltrt_surround_mix_level), AV_OPT_TYPE_FLOAT, {.dbl = -1.0 }, -1.0, 2.0, AC3ENC_PARAM},
{"loro_cmixlev", "Lo/Ro Center Mix Level", OFFSET(loro_center_mix_level), AV_OPT_TYPE_FLOAT, {.dbl = -1.0 }, -1.0, 2.0, AC3ENC_PARAM},
{"loro_surmixlev", "Lo/Ro Surround Mix Level", OFFSET(loro_surround_mix_level), AV_OPT_TYPE_FLOAT, {.dbl = -1.0 }, -1.0, 2.0, AC3ENC_PARAM},
-{"dsurex_mode", "Dolby Surround EX Mode", OFFSET(dolby_surround_ex_mode), AV_OPT_TYPE_INT, {.i64 = AC3ENC_OPT_NONE }, AC3ENC_OPT_NONE, AC3ENC_OPT_MODE_ON, AC3ENC_PARAM, "dsurex_mode"},
+{"dsurex_mode", "Dolby Surround EX Mode", OFFSET(dolby_surround_ex_mode), AV_OPT_TYPE_INT, {.i64 = AC3ENC_OPT_NONE }, AC3ENC_OPT_NONE, AC3ENC_OPT_DSUREX_DPLIIZ, AC3ENC_PARAM, "dsurex_mode"},
{"notindicated", "Not Indicated (default)", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_NOT_INDICATED }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dsurex_mode"},
{"on", "Dolby Surround EX Encoded", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_MODE_ON }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dsurex_mode"},
{"off", "Not Dolby Surround EX Encoded", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_MODE_OFF }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dsurex_mode"},
+ {"dpliiz", "Dolby Pro Logic IIz-encoded", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_DSUREX_DPLIIZ }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dsurex_mode"},
{"dheadphone_mode", "Dolby Headphone Mode", OFFSET(dolby_headphone_mode), AV_OPT_TYPE_INT, {.i64 = AC3ENC_OPT_NONE }, AC3ENC_OPT_NONE, AC3ENC_OPT_MODE_ON, AC3ENC_PARAM, "dheadphone_mode"},
{"notindicated", "Not Indicated (default)", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_NOT_INDICATED }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dheadphone_mode"},
{"on", "Dolby Headphone Encoded", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_MODE_ON }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dheadphone_mode"},
const SampleType *input_samples = &s->planar_samples[ch][blk * AC3_BLOCK_SIZE];
#if CONFIG_AC3ENC_FLOAT
- s->fdsp.vector_fmul(s->windowed_samples, input_samples,
+ s->fdsp->vector_fmul(s->windowed_samples, input_samples,
s->mdct_window, AC3_WINDOW_SIZE);
#else
s->ac3dsp.apply_window_int16(s->windowed_samples, input_samples,
ff_ac3_output_frame(s, avpkt->data);
if (frame->pts != AV_NOPTS_VALUE)
- avpkt->pts = frame->pts - ff_samples_to_time_base(avctx, avctx->delay);
+ avpkt->pts = frame->pts - ff_samples_to_time_base(avctx, avctx->initial_padding);
*got_packet_ptr = 1;
return 0;
int s0, s1, s2, d;
int max = 0;
int min = 0;
- int data[BLOCK_SAMPLES];
s1 = prev->s1;
s2 = prev->s2;
for (i = 0, j = 0; j < 32; i += channels, j++) {
s0 = wav[i];
d = ((s0 << COEFF_BITS) - c->coeff[0] * s1 - c->coeff[1] * s2) >> COEFF_BITS;
- data[j] = d;
if (max < d)
max = d;
if (min > d)
s2 = s1;
s1 = s0;
}
- prev->s1 = s1;
- prev->s2 = s2;
if (max == 0 && min == 0) {
+ prev->s1 = s1;
+ prev->s2 = s2;
memset(adx, 0, BLOCK_SIZE);
return;
}
AV_WB16(adx, scale);
init_put_bits(&pb, adx + 2, 16);
- for (i = 0; i < BLOCK_SAMPLES; i++)
- put_sbits(&pb, 4, av_clip(data[i] / scale, -8, 7));
+
+ s1 = prev->s1;
+ s2 = prev->s2;
+ for (i = 0, j = 0; j < 32; i += channels, j++) {
+ d = ((wav[i] << COEFF_BITS) - c->coeff[0] * s1 - c->coeff[1] * s2) >> COEFF_BITS;
+
+ d = av_clip(ROUNDED_DIV(d, scale), -8, 7);
+
+ put_sbits(&pb, 4, d);
+
+ s0 = ((d << COEFF_BITS) * scale + c->coeff[0] * s1 + c->coeff[1] * s2) >> COEFF_BITS;
+ s2 = s1;
+ s1 = s0;
+ }
+ prev->s1 = s1;
+ prev->s2 = s2;
+
flush_put_bits(&pb);
}
// write extra bits if needed
if (s->extra_bits) {
- uint32_t mask = (1 << s->extra_bits) - 1;
for (i = 0; i < s->frame_size; i++) {
for (j = 0; j < channels; j++) {
- put_bits(pb, s->extra_bits, s->predictor_buf[j][i] & mask);
+ put_bits(pb, s->extra_bits, s->predictor_buf[j][i]);
}
}
}
// TODO: determine when this will actually help. for now it's not used.
if (prediction_type == 15) {
// 2nd pass 1st order filter
- int32_t *residual = s->predictor_buf[channels];
+ int32_t *residual = s->predictor_buf[i];
for (j = s->frame_size - 1; j > 0; j--)
residual[j] -= residual[j - 1];
}
REGISTER_ENCDEC (AMV, amv);
REGISTER_DECODER(ANM, anm);
REGISTER_DECODER(ANSI, ansi);
+ REGISTER_DECODER(APNG, apng);
REGISTER_ENCDEC (ASV1, asv1);
REGISTER_ENCDEC (ASV2, asv2);
REGISTER_DECODER(AURA, aura);
REGISTER_DECODER(REALTEXT, realtext);
REGISTER_DECODER(SAMI, sami);
REGISTER_ENCDEC (SRT, srt);
+ REGISTER_DECODER(STL, stl);
REGISTER_ENCDEC (SUBRIP, subrip);
REGISTER_DECODER(SUBVIEWER, subviewer);
REGISTER_DECODER(SUBVIEWER1, subviewer1);
#include "asm.h"
void put_pixels_clamped_mvi_asm(const int16_t *block, uint8_t *pixels,
- int line_size);
+ ptrdiff_t line_size);
void add_pixels_clamped_mvi_asm(const int16_t *block, uint8_t *pixels,
- int line_size);
+ ptrdiff_t line_size);
void (*put_pixels_clamped_axp_p)(const int16_t *block, uint8_t *pixels,
- int line_size);
+ ptrdiff_t line_size);
void (*add_pixels_clamped_axp_p)(const int16_t *block, uint8_t *pixels,
- int line_size);
+ ptrdiff_t line_size);
#if 0
/* These functions were the base for the optimized assembler routines,
#include <stdint.h>
extern void (*put_pixels_clamped_axp_p)(const int16_t *block, uint8_t *pixels,
- int line_size);
+ ptrdiff_t line_size);
extern void (*add_pixels_clamped_axp_p)(const int16_t *block, uint8_t *pixels,
- int line_size);
+ ptrdiff_t line_size);
void ff_simple_idct_axp(int16_t *block);
void ff_simple_idct_put_axp(uint8_t *dest, int line_size, int16_t *block);
/************************************************************************
* void put_pixels_clamped_mvi_asm(const int16_t *block, uint8_t *pixels,
- * int line_size)
+ * ptrdiff_t line_size)
*/
.align 6
.globl put_pixels_clamped_mvi_asm
/************************************************************************
* void add_pixels_clamped_mvi_asm(const int16_t *block, uint8_t *pixels,
- * int line_size)
+ * ptrdiff_t line_size)
*/
.align 6
.globl add_pixels_clamped_mvi_asm
return AVERROR(ENOMEM);
bytestream2_init(&s->gb, avctx->extradata, avctx->extradata_size);
- if (bytestream2_get_bytes_left(&s->gb) < 16 * 8 + 4 * 256)
+ if (bytestream2_get_bytes_left(&s->gb) < 16 * 8 + 4 * 256) {
+ av_frame_free(&s->frame);
return AVERROR_INVALIDDATA;
+ }
bytestream2_skipu(&s->gb, 16 * 8);
for (i = 0; i < 256; i++)
s->fg = DEFAULT_FG_COLOR;
s->bg = DEFAULT_BG_COLOR;
- if (!avctx->width || !avctx->height)
- ff_set_dimensions(avctx, 80 << 3, 25 << 4);
-
+ if (!avctx->width || !avctx->height) {
+ int ret = ff_set_dimensions(avctx, 80 << 3, 25 << 4);
+ if (ret < 0)
+ return ret;
+ }
return 0;
}
--- /dev/null
+/*
+ * APNG common header
+ * Copyright (c) 2014 Benoit Fouet
+ *
+ * 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
+ * APNG common header
+ */
+
+#ifndef AVCODEC_APNG_H
+#define AVCODEC_APNG_H
+
+enum {
+ APNG_DISPOSE_OP_NONE = 0,
+ APNG_DISPOSE_OP_BACKGROUND = 1,
+ APNG_DISPOSE_OP_PREVIOUS = 2,
+};
+
+enum {
+ APNG_BLEND_OP_SOURCE = 0,
+ APNG_BLEND_OP_OVER = 1,
+};
+
+#endif /* AVCODEC_APNG_H */
void ff_flac_lpc_16_arm(int32_t *samples, const int coeffs[32], int order,
int qlevel, int len);
-av_cold void ff_flacdsp_init_arm(FLACDSPContext *c, enum AVSampleFormat fmt,
+av_cold void ff_flacdsp_init_arm(FLACDSPContext *c, enum AVSampleFormat fmt, int channels,
int bps)
{
if (bps <= 16 && CONFIG_FLAC_DECODER)
#include "config.h"
#include "libavutil/arm/asm.S"
-@ void ff_add_pixels_clamped_arm(int16_t *block, uint8_t *dest, int stride)
+@ void ff_add_pixels_clamped_arm(int16_t *block, uint8_t *dest, ptrdiff_t stride)
function ff_add_pixels_clamped_arm, export=1, align=5
push {r4-r10}
mov r10, #8
#include "idctdsp_arm.h"
void ff_add_pixels_clamped_arm(const int16_t *block, uint8_t *dest,
- int line_size);
+ ptrdiff_t line_size);
/* XXX: those functions should be suppressed ASAP when all IDCTs are
* converted */
#include "idctdsp_arm.h"
void ff_add_pixels_clamped_armv6(const int16_t *block, uint8_t *pixels,
- int line_size);
+ ptrdiff_t line_size);
av_cold void ff_idctdsp_init_armv6(IDCTDSPContext *c, AVCodecContext *avctx,
unsigned high_bit_depth)
#include "idct.h"
#include "idctdsp_arm.h"
-void ff_add_pixels_clamped_neon(const int16_t *, uint8_t *, int);
-void ff_put_pixels_clamped_neon(const int16_t *, uint8_t *, int);
-void ff_put_signed_pixels_clamped_neon(const int16_t *, uint8_t *, int);
+void ff_add_pixels_clamped_neon(const int16_t *, uint8_t *, ptrdiff_t);
+void ff_put_pixels_clamped_neon(const int16_t *, uint8_t *, ptrdiff_t);
+void ff_put_signed_pixels_clamped_neon(const int16_t *, uint8_t *, ptrdiff_t);
av_cold void ff_idctdsp_init_neon(IDCTDSPContext *c, AVCodecContext *avctx,
unsigned high_bit_depth)
#include "libavcodec/mpegvideo.h"
int ff_pix_abs16_armv6(MpegEncContext *s, uint8_t *blk1, uint8_t *blk2,
- int line_size, int h);
+ ptrdiff_t stride, int h);
int ff_pix_abs16_x2_armv6(MpegEncContext *s, uint8_t *blk1, uint8_t *blk2,
- int line_size, int h);
+ ptrdiff_t stride, int h);
int ff_pix_abs16_y2_armv6(MpegEncContext *s, uint8_t *blk1, uint8_t *blk2,
- int line_size, int h);
+ ptrdiff_t stride, int h);
int ff_pix_abs8_armv6(MpegEncContext *s, uint8_t *blk1, uint8_t *blk2,
- int line_size, int h);
+ ptrdiff_t stride, int h);
int ff_sse16_armv6(MpegEncContext *s, uint8_t *blk1, uint8_t *blk2,
- int line_size, int h);
+ ptrdiff_t stride, int h);
av_cold void ff_me_cmp_init_arm(MECmpContext *c, AVCodecContext *avctx)
{
{
avctx->subtitle_header = av_asprintf(
"[Script Info]\r\n"
+ "; Script generated by FFmpeg/Lavc%s\r\n"
"ScriptType: v4.00+\r\n"
"PlayResX: 384\r\n"
"PlayResY: 288\r\n"
"\r\n"
"[V4+ Styles]\r\n"
- "Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, AlphaLevel, Encoding\r\n"
- "Style: Default,%s,%d,&H%x,&H%x,&H%x,&H%x,%d,%d,%d,1,1,0,%d,10,10,10,0,0\r\n"
+
+ /* ASSv4 header */
+ "Format: Name, "
+ "Fontname, Fontsize, "
+ "PrimaryColour, SecondaryColour, OutlineColour, BackColour, "
+ "Bold, Italic, Underline, StrikeOut, "
+ "ScaleX, ScaleY, "
+ "Spacing, Angle, "
+ "BorderStyle, Outline, Shadow, "
+ "Alignment, MarginL, MarginR, MarginV, "
+ "Encoding\r\n"
+
+ "Style: "
+ "Default," /* Name */
+ "%s,%d," /* Font{name,size} */
+ "&H%x,&H%x,&H%x,&H%x," /* {Primary,Secondary,Outline,Back}Colour */
+ "%d,%d,%d,0," /* Bold, Italic, Underline, StrikeOut */
+ "100,100," /* Scale{X,Y} */
+ "0,0," /* Spacing, Angle */
+ "1,1,0," /* BorderStyle, Outline, Shadow */
+ "%d,10,10,10," /* Alignment, Margin[LRV] */
+ "0\r\n" /* Encoding */
+
"\r\n"
"[Events]\r\n"
- "Format: Layer, Start, End, Style, Text\r\n",
+ "Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text\r\n",
+ !(avctx->flags & CODEC_FLAG_BITEXACT) ? AV_STRINGIFY(LIBAVCODEC_VERSION) : "",
font, font_size, color, color, back_color, back_color,
-bold, -italic, -underline, alignment);
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,,0,0,0,,");
}
dlen = strcspn(dialog, "\n");
return ret;
}
+int ff_ass_add_rect_bprint(AVSubtitle *sub, AVBPrint *buf,
+ int ts_start, int duration)
+{
+ av_bprintf(buf, "\r\n");
+ if (!av_bprint_is_complete(buf))
+ return AVERROR(ENOMEM);
+ return ff_ass_add_rect(sub, buf->str, ts_start, duration, 0);
+}
+
void ff_ass_bprint_text_event(AVBPrint *buf, const char *p, int size,
const char *linebreaks, int keep_ass_markup)
{
av_bprint_chars(buf, *p, 1);
}
}
- av_bprintf(buf, "\r\n");
}
int ff_ass_add_rect(AVSubtitle *sub, const char *dialog,
int ts_start, int duration, int raw);
+/**
+ * Same as ff_ass_add_rect_bprint, but taking an AVBPrint buffer instead of a
+ * string, and assuming raw=0.
+ */
+int ff_ass_add_rect_bprint(AVSubtitle *sub, AVBPrint *buf,
+ int ts_start, int duration);
+
/**
* Add an ASS dialog line to an AVBPrint buffer.
*
int size;
int offset;
int offset_count;
- ASSFields fields[10];
+ ASSFields fields[24];
} ASSSection;
static const ASSSection ass_sections[] = {
.size = sizeof(ASSStyle),
.offset = offsetof(ASS, styles),
.offset_count = offsetof(ASS, styles_count),
- .fields = {{"Name", ASS_STR, offsetof(ASSStyle, name) },
- {"Fontname", ASS_STR, offsetof(ASSStyle, font_name) },
- {"Fontsize", ASS_INT, offsetof(ASSStyle, font_size) },
- {"PrimaryColour",ASS_COLOR,offsetof(ASSStyle, primary_color)},
- {"BackColour", ASS_COLOR,offsetof(ASSStyle, back_color) },
- {"Bold", ASS_INT, offsetof(ASSStyle, bold) },
- {"Italic", ASS_INT, offsetof(ASSStyle, italic) },
- {"Underline", ASS_INT, offsetof(ASSStyle, underline) },
- {"Alignment", ASS_INT, offsetof(ASSStyle, alignment) },
+ .fields = {{"Name", ASS_STR, offsetof(ASSStyle, name) },
+ {"Fontname", ASS_STR, offsetof(ASSStyle, font_name) },
+ {"Fontsize", ASS_INT, offsetof(ASSStyle, font_size) },
+ {"PrimaryColour", ASS_COLOR, offsetof(ASSStyle, primary_color) },
+ {"SecondaryColour", ASS_COLOR, offsetof(ASSStyle, secondary_color)},
+ {"OutlineColour", ASS_COLOR, offsetof(ASSStyle, outline_color) },
+ {"BackColour", ASS_COLOR, offsetof(ASSStyle, back_color) },
+ {"Bold", ASS_INT, offsetof(ASSStyle, bold) },
+ {"Italic", ASS_INT, offsetof(ASSStyle, italic) },
+ {"Underline", ASS_INT, offsetof(ASSStyle, underline) },
+ {"StrikeOut", ASS_INT, offsetof(ASSStyle, strikeout) },
+ {"ScaleX", ASS_FLT, offsetof(ASSStyle, scalex) },
+ {"ScaleY", ASS_FLT, offsetof(ASSStyle, scaley) },
+ {"Spacing", ASS_FLT, offsetof(ASSStyle, spacing) },
+ {"Angle", ASS_FLT, offsetof(ASSStyle, angle) },
+ {"BorderStyle", ASS_INT, offsetof(ASSStyle, border_style) },
+ {"Outline", ASS_FLT, offsetof(ASSStyle, outline) },
+ {"Shadow", ASS_FLT, offsetof(ASSStyle, shadow) },
+ {"Alignment", ASS_INT, offsetof(ASSStyle, alignment) },
+ {"MarginL", ASS_INT, offsetof(ASSStyle, margin_l) },
+ {"MarginR", ASS_INT, offsetof(ASSStyle, margin_r) },
+ {"MarginV", ASS_INT, offsetof(ASSStyle, margin_v) },
+ {"Encoding", ASS_INT, offsetof(ASSStyle, encoding) },
{0},
}
},
.size = sizeof(ASSStyle),
.offset = offsetof(ASS, styles),
.offset_count = offsetof(ASS, styles_count),
- .fields = {{"Name", ASS_STR, offsetof(ASSStyle, name) },
- {"Fontname", ASS_STR, offsetof(ASSStyle, font_name) },
- {"Fontsize", ASS_INT, offsetof(ASSStyle, font_size) },
- {"PrimaryColour",ASS_COLOR,offsetof(ASSStyle, primary_color)},
- {"BackColour", ASS_COLOR,offsetof(ASSStyle, back_color) },
- {"Bold", ASS_INT, offsetof(ASSStyle, bold) },
- {"Italic", ASS_INT, offsetof(ASSStyle, italic) },
- {"Alignment", ASS_ALGN, offsetof(ASSStyle, alignment) },
+ .fields = {{"Name", ASS_STR, offsetof(ASSStyle, name) },
+ {"Fontname", ASS_STR, offsetof(ASSStyle, font_name) },
+ {"Fontsize", ASS_INT, offsetof(ASSStyle, font_size) },
+ {"PrimaryColour", ASS_COLOR, offsetof(ASSStyle, primary_color) },
+ {"SecondaryColour", ASS_COLOR, offsetof(ASSStyle, secondary_color)},
+ {"TertiaryColour", ASS_COLOR, offsetof(ASSStyle, outline_color) },
+ {"BackColour", ASS_COLOR, offsetof(ASSStyle, back_color) },
+ {"Bold", ASS_INT, offsetof(ASSStyle, bold) },
+ {"Italic", ASS_INT, offsetof(ASSStyle, italic) },
+ {"BorderStyle", ASS_INT, offsetof(ASSStyle, border_style) },
+ {"Outline", ASS_FLT, offsetof(ASSStyle, outline) },
+ {"Shadow", ASS_FLT, offsetof(ASSStyle, shadow) },
+ {"Alignment", ASS_ALGN, offsetof(ASSStyle, alignment) },
+ {"MarginL", ASS_INT, offsetof(ASSStyle, margin_l) },
+ {"MarginR", ASS_INT, offsetof(ASSStyle, margin_r) },
+ {"MarginV", ASS_INT, offsetof(ASSStyle, margin_v) },
+ {"AlphaLevel", ASS_INT, offsetof(ASSStyle, alpha_level) },
+ {"Encoding", ASS_INT, offsetof(ASSStyle, encoding) },
{0},
}
},
.size = sizeof(ASSDialog),
.offset = offsetof(ASS, dialogs),
.offset_count = offsetof(ASS, dialogs_count),
- .fields = {{"Layer", ASS_INT, offsetof(ASSDialog, layer) },
- {"Start", ASS_TIMESTAMP, offsetof(ASSDialog, start) },
- {"End", ASS_TIMESTAMP, offsetof(ASSDialog, end) },
- {"Style", ASS_STR, offsetof(ASSDialog, style) },
- {"Text", ASS_STR, offsetof(ASSDialog, text) },
+ .fields = {{"Layer", ASS_INT, offsetof(ASSDialog, layer) },
+ {"Start", ASS_TIMESTAMP, offsetof(ASSDialog, start) },
+ {"End", ASS_TIMESTAMP, offsetof(ASSDialog, end) },
+ {"Style", ASS_STR, offsetof(ASSDialog, style) },
+ {"Name", ASS_STR, offsetof(ASSDialog, name) },
+ {"MarginL", ASS_INT, offsetof(ASSDialog, margin_l)},
+ {"MarginR", ASS_INT, offsetof(ASSDialog, margin_r)},
+ {"MarginV", ASS_INT, offsetof(ASSDialog, margin_v)},
+ {"Effect", ASS_STR, offsetof(ASSDialog, effect) },
+ {"Text", ASS_STR, offsetof(ASSDialog, text) },
{0},
}
},
return buf;
}
+static int *get_default_field_orders(const ASSSection *section)
+{
+ int i;
+ int *order = av_malloc(FF_ARRAY_ELEMS(section->fields) * sizeof(*order));
+
+ if (!order)
+ return NULL;
+ for (i = 0; section->fields[i].name; i++)
+ order[i] = i;
+ while (i < FF_ARRAY_ELEMS(section->fields))
+ order[i] = -1;
+ return order;
+}
+
static const char *ass_split_section(ASSSplitContext *ctx, const char *buf)
{
const ASSSection *section = &ass_sections[ctx->current_section];
} else if (section->format_header && !order) {
len = strlen(section->format_header);
if (strncmp(buf, section->format_header, len) || buf[len] != ':')
- return NULL;
+ goto next_line;
buf += len + 1;
while (!is_eol(*buf)) {
buf = skip_space(buf);
if (!strncmp(buf, section->fields_header, len) && buf[len] == ':') {
uint8_t *ptr, *struct_ptr = realloc_section_array(ctx);
if (!struct_ptr) return NULL;
+
+ /* No format header line found so far, assume default */
+ if (!order) {
+ order = get_default_field_orders(section);
+ if (!order)
+ return NULL;
+ ctx->field_order[ctx->current_section] = order;
+ }
+
buf += len + 1;
for (i=0; !is_eol(*buf) && i < *number; i++) {
int last = i == *number - 1;
}
}
}
+next_line:
buf += strcspn(buf, "\n");
buf += !!*buf;
}
char *font_name; /**< font face (case sensitive) */
int font_size; /**< font height */
int primary_color; /**< color that a subtitle will normally appear in */
+ int secondary_color;
+ int outline_color; /**< color for outline in ASS, called tertiary in SSA */
int back_color; /**< color of the subtitle outline or shadow */
int bold; /**< whether text is bold (1) or not (0) */
int italic; /**< whether text is italic (1) or not (0) */
int underline; /**< whether text is underlined (1) or not (0) */
+ int strikeout;
+ float scalex;
+ float scaley;
+ float spacing;
+ float angle;
+ int border_style;
+ float outline;
+ float shadow;
int alignment; /**< position of the text (left, center, top...),
defined after the layout of the numpad
(1-3 sub, 4-6 mid, 7-9 top) */
+ int margin_l;
+ int margin_r;
+ int margin_v;
+ int alpha_level;
+ int encoding;
} ASSStyle;
/**
int start; /**< start time of the dialog in centiseconds */
int end; /**< end time of the dialog in centiseconds */
char *style; /**< name of the ASSStyle to use with this dialog */
+ char *name;
+ int margin_l;
+ int margin_r;
+ int margin_v;
+ char *effect;
char *text; /**< actual text which will be displayed as a subtitle,
can include style override control codes (see
ff_ass_split_override_codes()) */
}
}
-static inline void asv2_put_level(PutBitContext *pb, int level)
+static inline void asv2_put_level(ASV1Context *a, PutBitContext *pb, int level)
{
unsigned int index = level + 31;
put_bits(pb, ff_asv2_level_tab[index][1], ff_asv2_level_tab[index][0]);
} else {
put_bits(pb, ff_asv2_level_tab[31][1], ff_asv2_level_tab[31][0]);
+ if (level < -128 || level > 127) {
+ av_log(a->avctx, AV_LOG_WARNING, "Cliping level %d, increase qscale\n", level);
+ level = av_clip_int8(level);
+ }
asv2_put_bits(pb, 8, level & 0xFF);
}
}
if (ccp) {
if (ccp & 8)
- asv2_put_level(&a->pb, block[index + 0]);
+ asv2_put_level(a, &a->pb, block[index + 0]);
if (ccp & 4)
- asv2_put_level(&a->pb, block[index + 8]);
+ asv2_put_level(a, &a->pb, block[index + 8]);
if (ccp & 2)
- asv2_put_level(&a->pb, block[index + 1]);
+ asv2_put_level(a, &a->pb, block[index + 1]);
if (ccp & 1)
- asv2_put_level(&a->pb, block[index + 9]);
+ asv2_put_level(a, &a->pb, block[index + 9]);
}
}
}
DECLARE_ALIGNED(32, float, high)[512];
float* bands[3];
FFTContext mdct_ctx[3];
- AVFloatDSPContext fdsp;
+ AVFloatDSPContext *fdsp;
} AT1Ctx;
/** size of the transform in samples in the long mode for each QMF band */
at1_imdct(q, &q->spec[pos], &su->spectrum[0][ref_pos + start_pos], nbits, band_num);
/* overlap and window */
- q->fdsp.vector_fmul_window(&q->bands[band_num][start_pos], prev_buf,
+ q->fdsp->vector_fmul_window(&q->bands[band_num][start_pos], prev_buf,
&su->spectrum[0][ref_pos + start_pos], ff_sine_32, 16);
prev_buf = &su->spectrum[0][ref_pos+start_pos + 16];
ff_mdct_end(&q->mdct_ctx[1]);
ff_mdct_end(&q->mdct_ctx[2]);
+ av_freep(&q->fdsp);
+
return 0;
}
ff_atrac_generate_tables();
- avpriv_float_dsp_init(&q->fdsp, avctx->flags & CODEC_FLAG_BITEXACT);
+ q->fdsp = avpriv_float_dsp_alloc(avctx->flags & CODEC_FLAG_BITEXACT);
q->bands[0] = q->low;
q->bands[1] = q->mid;
AtracGCContext gainc_ctx;
FFTContext mdct_ctx;
FmtConvertContext fmt_conv;
- AVFloatDSPContext fdsp;
+ AVFloatDSPContext *fdsp;
} ATRAC3Context;
static DECLARE_ALIGNED(32, float, mdct_window)[MDCT_SIZE];
q->mdct_ctx.imdct_calc(&q->mdct_ctx, output, input);
/* Perform windowing on the output. */
- q->fdsp.vector_fmul(output, output, mdct_window, MDCT_SIZE);
+ q->fdsp->vector_fmul(output, output, mdct_window, MDCT_SIZE);
}
/*
{
ATRAC3Context *q = avctx->priv_data;
- av_free(q->units);
- av_free(q->decoded_bytes_buffer);
+ av_freep(&q->units);
+ av_freep(&q->decoded_bytes_buffer);
+ av_freep(&q->fdsp);
ff_mdct_end(&q->mdct_ctx);
}
ff_atrac_init_gain_compensation(&q->gainc_ctx, 4, 3);
- avpriv_float_dsp_init(&q->fdsp, avctx->flags & CODEC_FLAG_BITEXACT);
+ q->fdsp = avpriv_float_dsp_alloc(avctx->flags & CODEC_FLAG_BITEXACT);
ff_fmt_convert_init(&q->fmt_conv, avctx);
q->units = av_mallocz_array(avctx->channels, sizeof(*q->units));
- if (!q->units) {
+ if (!q->units || !q->fdsp) {
atrac3_decode_close(avctx);
return AVERROR(ENOMEM);
}
{
int mode, sb, j, i, diff, maxdiff, fi, delta, pred;
Atrac3pWaveParam *wsrc, *wref;
- int refwaves[48];
+ int refwaves[48] = { 0 };
Atrac3pWavesData *dst = ctx->channels[ch_num].tones_info;
Atrac3pWavesData *ref = ctx->channels[0].tones_info;
typedef struct ATRAC3PContext {
GetBitContext gb;
- AVFloatDSPContext fdsp;
+ AVFloatDSPContext *fdsp;
DECLARE_ALIGNED(32, float, samples)[2][ATRAC3P_FRAME_SAMPLES]; ///< quantized MDCT spectrum
DECLARE_ALIGNED(32, float, mdct_buf)[2][ATRAC3P_FRAME_SAMPLES]; ///< output of the IMDCT
static av_cold int atrac3p_decode_close(AVCodecContext *avctx)
{
- av_free(((ATRAC3PContext *)(avctx->priv_data))->ch_units);
+ ATRAC3PContext *ctx = avctx->priv_data;
+
+ av_freep(&ctx->ch_units);
+ av_freep(&ctx->fdsp);
return 0;
}
ff_atrac3p_init_vlcs();
- avpriv_float_dsp_init(&ctx->fdsp, avctx->flags & CODEC_FLAG_BITEXACT);
-
/* initialize IPQF */
ff_mdct_init(&ctx->ipqf_dct_ctx, 5, 1, 32.0 / 32768.0);
ctx->my_channel_layout = avctx->channel_layout;
ctx->ch_units = av_mallocz_array(ctx->num_channel_blocks, sizeof(*ctx->ch_units));
+ ctx->fdsp = avpriv_float_dsp_alloc(avctx->flags & CODEC_FLAG_BITEXACT);
- if (!ctx->ch_units) {
+ if (!ctx->ch_units || !ctx->fdsp) {
atrac3p_decode_close(avctx);
return AVERROR(ENOMEM);
}
for (ch = 0; ch < num_channels; ch++) {
for (sb = 0; sb < ch_unit->num_subbands; sb++) {
/* inverse transform and windowing */
- ff_atrac3p_imdct(&ctx->fdsp, &ctx->mdct_ctx,
+ ff_atrac3p_imdct(ctx->fdsp, &ctx->mdct_ctx,
&ctx->samples[ch][sb * ATRAC3P_SUBBAND_SAMPLES],
&ctx->mdct_buf[ch][sb * ATRAC3P_SUBBAND_SAMPLES],
(ch_unit->channels[ch].wnd_shape_prev[sb] << 1) +
for (sb = 0; sb < ch_unit->num_subbands; sb++)
if (ch_unit->channels[ch].tones_info[sb].num_wavs ||
ch_unit->channels[ch].tones_info_prev[sb].num_wavs) {
- ff_atrac3p_generate_tones(ch_unit, &ctx->fdsp, ch, sb,
+ ff_atrac3p_generate_tones(ch_unit, ctx->fdsp, ch, sb,
&ctx->time_buf[ch][sb * 128]);
}
}
av_cold void ff_af_queue_init(AVCodecContext *avctx, AudioFrameQueue *afq)
{
afq->avctx = avctx;
- afq->remaining_delay = avctx->delay;
- afq->remaining_samples = avctx->delay;
+ afq->remaining_delay = avctx->initial_padding;
+ afq->remaining_samples = avctx->initial_padding;
afq->frame_count = 0;
}
#include "version.h"
-#if FF_API_FAST_MALLOC
-// to provide fast_*alloc
-#include "libavutil/mem.h"
-#endif
-
/**
* @defgroup libavc Encoding/Decoding Library
* @{
AV_CODEC_ID_HEVC = MKBETAG('H','2','6','5'),
#define AV_CODEC_ID_H265 AV_CODEC_ID_HEVC
AV_CODEC_ID_VP7 = MKBETAG('V','P','7','0'),
+ AV_CODEC_ID_APNG = MKBETAG('A','P','N','G'),
/* various PCM "codecs" */
AV_CODEC_ID_FIRST_AUDIO = 0x10000, ///< A dummy id pointing at the start of audio codecs
AV_CODEC_ID_JACOSUB = MKBETAG('J','S','U','B'),
AV_CODEC_ID_SAMI = MKBETAG('S','A','M','I'),
AV_CODEC_ID_REALTEXT = MKBETAG('R','T','X','T'),
+ AV_CODEC_ID_STL = MKBETAG('S','p','T','L'),
AV_CODEC_ID_SUBVIEWER1 = MKBETAG('S','b','V','1'),
AV_CODEC_ID_SUBVIEWER = MKBETAG('S','u','b','V'),
AV_CODEC_ID_SUBRIP = MKBETAG('S','R','i','p'),
/**
* This struct describes the properties of a single codec described by an
* AVCodecID.
- * @see avcodec_get_descriptor()
+ * @see avcodec_descriptor_get()
*/
typedef struct AVCodecDescriptor {
enum AVCodecID id;
#define CODEC_FLAG2_CHUNKS 0x00008000 ///< Input bitstream might be truncated at a packet boundaries instead of only at frame boundaries.
#define CODEC_FLAG2_SHOW_ALL 0x00400000 ///< Show all frames before the first keyframe
#define CODEC_FLAG2_EXPORT_MVS 0x10000000 ///< Export motion vectors through frame side data
+#define CODEC_FLAG2_SKIP_MANUAL 0x20000000 ///< Do not skip samples and export skip information as frame side data
/* Unsupported options :
* Syntax Arithmetic coding (SAC)
* of which frame timestamps are represented. For fixed-fps content,
* timebase should be 1/framerate and timestamp increments should be
* identically 1.
+ * This often, but not always is the inverse of the frame rate or field rate
+ * for video.
* - encoding: MUST be set by user.
- * - decoding: Set by libavcodec.
+ * - decoding: the use of this field for decoding is deprecated.
+ * Use framerate instead.
*/
AVRational time_base;
* encoded input.
*
* Audio:
- * For encoding, this is the number of "priming" samples added by the
- * encoder to the beginning of the stream. The decoded output will be
- * delayed by this many samples relative to the input to the encoder (or
- * more, if the decoder adds its own padding).
- * The timestamps on the output packets are adjusted by the encoder so
- * that they always refer to the first sample of the data actually
- * contained in the packet, including any added padding.
- * E.g. if the timebase is 1/samplerate and the timestamp of the first
- * input sample is 0, the timestamp of the first output packet will be
- * -delay.
+ * For encoding, this field is unused (see initial_padding).
*
* For decoding, this is the number of samples the decoder needs to
* output before the decoder's output is valid. When seeking, you should
* @param fmt is the list of formats which are supported by the codec,
* it is terminated by -1 as 0 is a valid format, the formats are ordered by quality.
* The first is always the native one.
+ * @note The callback may be called again immediately if initialization for
+ * the selected (hardware-accelerated) pixel format failed.
+ * @warning Behavior is undefined if the callback returns a value not
+ * in the fmt list of formats.
* @return the chosen format
* - encoding: unused
* - decoding: Set by user, if not set the native format will be chosen.
*/
int noise_reduction;
+#if FF_API_MPV_OPT
/**
- * Motion estimation threshold below which no motion estimation is
- * performed, but instead the user specified motion vectors are used.
- *
- * - encoding: Set by user.
- * - decoding: unused
+ * @deprecated this field is unused
*/
+ attribute_deprecated
int me_threshold;
/**
- * Macroblock threshold below which the user specified macroblock types will be used.
- * - encoding: Set by user.
- * - decoding: unused
+ * @deprecated this field is unused
*/
+ attribute_deprecated
int mb_threshold;
+#endif
/**
* precision of the intra DC coefficient - 8
*/
int skip_bottom;
+#if FF_API_MPV_OPT
/**
- * Border processing masking, raises the quantizer for mbs on the borders
- * of the picture.
- * - encoding: Set by user.
- * - decoding: unused
+ * @deprecated use encoder private options instead
*/
+ attribute_deprecated
float border_masking;
+#endif
/**
* minimum MB lagrange multipler
*/
int max_qdiff;
+#if FF_API_MPV_OPT
/**
- * ratecontrol qmin qmax limiting method
- * 0-> clipping, 1-> use a nice continuous function to limit qscale within qmin/qmax.
- * - encoding: Set by user.
- * - decoding: unused
+ * @deprecated use encoder private options instead
*/
+ attribute_deprecated
float rc_qsquish;
+ attribute_deprecated
float rc_qmod_amp;
+ attribute_deprecated
int rc_qmod_freq;
+#endif
/**
* decoder bitstream buffer size
int rc_override_count;
RcOverride *rc_override;
+#if FF_API_MPV_OPT
/**
- * rate control equation
- * - encoding: Set by user
- * - decoding: unused
+ * @deprecated use encoder private options instead
*/
+ attribute_deprecated
const char *rc_eq;
+#endif
/**
* maximum bitrate
*/
int rc_min_rate;
- float rc_buffer_aggressivity;
-
+#if FF_API_MPV_OPT
/**
- * initial complexity for pass1 ratecontrol
- * - encoding: Set by user.
- * - decoding: unused
+ * @deprecated use encoder private options instead
*/
+ attribute_deprecated
+ float rc_buffer_aggressivity;
+
+ attribute_deprecated
float rc_initial_cplx;
+#endif
/**
* Ratecontrol attempt to use, at maximum, <value> of what can be used without an underflow.
*/
int context_model;
+#if FF_API_MPV_OPT
/**
- * minimum Lagrange multiplier
- * - encoding: Set by user.
- * - decoding: unused
+ * @deprecated use encoder private options instead
*/
+ attribute_deprecated
int lmin;
/**
- * maximum Lagrange multiplier
- * - encoding: Set by user.
- * - decoding: unused
+ * @deprecated use encoder private options instead
*/
+ attribute_deprecated
int lmax;
+#endif
/**
* frame skip threshold
*/
int side_data_only_packets;
+ /**
+ * Audio only. The number of "priming" samples (padding) inserted by the
+ * encoder at the beginning of the audio. I.e. this number of leading
+ * decoded samples must be discarded by the caller to get the original audio
+ * without leading padding.
+ *
+ * - decoding: unused
+ * - encoding: Set by libavcodec. The timestamps on the output packets are
+ * adjusted by the encoder so that they always refer to the
+ * first sample of the data actually contained in the packet,
+ * including any added padding. E.g. if the timebase is
+ * 1/samplerate and the timestamp of the first input sample is
+ * 0, the timestamp of the first output packet will be
+ * -initial_padding.
+ */
+ int initial_padding;
+
+ /**
+ * - decoding: For codecs that store a framerate value in the compressed
+ * bitstream, the decoder may export it here. { 0, 1} when
+ * unknown.
+ * - encoding: unused
+ */
+ AVRational framerate;
+
/**
* Timebase in which pkt_dts/pts and AVPacket.dts/pts are.
* Code outside libavcodec should access this field using:
* - decoding: unused.
*/
uint16_t *chroma_intra_matrix;
+
+ /**
+ * dump format separator.
+ * can be ", " or "\n " or anything else
+ * Code outside libavcodec should access this field using AVOptions
+ * (NO direct access).
+ * - encoding: Set by user.
+ * - decoding: Set by user.
+ */
+ uint8_t *dump_separator;
+
+ /**
+ * ',' separated list of allowed decoders.
+ * If NULL then all are allowed
+ * - encoding: unused
+ * - decoding: set by user through AVOPtions (NO direct access)
+ */
+ char *codec_whitelist;
} AVCodecContext;
AVRational av_codec_get_pkt_timebase (const AVCodecContext *avctx);
struct MpegEncContext;
/**
- * AVHWAccel.
+ * @defgroup lavc_hwaccel AVHWAccel
+ * @{
*/
typedef struct AVHWAccel {
/**
int priv_data_size;
} AVHWAccel;
+/**
+ * Hardware acceleration should be used for decoding even if the codec level
+ * used is unknown or higher than the maximum supported level reported by the
+ * hardware driver.
+ */
+#define AV_HWACCEL_FLAG_IGNORE_LEVEL (1 << 0)
+
+/**
+ * @}
+ */
+
/**
* @defgroup lavc_picture AVPicture
*
/**
* Register a user provided lock manager supporting the operations
- * specified by AVLockOp. mutex points to a (void *) where the
- * lockmgr should store/get a pointer to a user allocated mutex. It's
- * NULL upon AV_LOCK_CREATE and != NULL for all other ops.
- *
- * @param cb User defined callback. Note: FFmpeg may invoke calls to this
- * callback during the call to av_lockmgr_register().
- * Thus, the application must be prepared to handle that.
- * If cb is set to NULL the lockmgr will be unregistered.
- * Also note that during unregistration the previously registered
- * lockmgr callback may also be invoked.
+ * specified by AVLockOp. The "mutex" argument to the function points
+ * to a (void *) where the lockmgr should store/get a pointer to a user
+ * allocated mutex. It is NULL upon AV_LOCK_CREATE and equal to the
+ * value left by the last call for all other ops. If the lock manager is
+ * unable to perform the op then it should leave the mutex in the same
+ * state as when it was called and return a non-zero value. However,
+ * when called with AV_LOCK_DESTROY the mutex will always be assumed to
+ * have been successfully destroyed. If av_lockmgr_register succeeds
+ * it will return a non-negative value, if it fails it will return a
+ * negative value and destroy all mutex and unregister all callbacks.
+ * av_lockmgr_register is not thread-safe, it must be called from a
+ * single thread before any calls which make use of locking are used.
+ *
+ * @param cb User defined callback. av_lockmgr_register invokes calls
+ * to this callback and the previously registered callback.
+ * The callback will be used to create more than one mutex
+ * each of which must be backed by its own underlying locking
+ * mechanism (i.e. do not use a single static object to
+ * implement your lock manager). If cb is set to NULL the
+ * lockmgr will be unregistered.
*/
int av_lockmgr_register(int (*cb)(void **mutex, enum AVLockOp op));
void av_destruct_packet(AVPacket *pkt)
{
- av_free(pkt->data);
- pkt->data = NULL;
+ av_freep(&pkt->data);
pkt->size = 0;
}
{
int i;
for (i = 0; i < pkt->side_data_elems; i++)
- av_free(pkt->side_data[i].data);
+ av_freep(&pkt->side_data[i].data);
av_freep(&pkt->side_data);
pkt->side_data_elems = 0;
}
void avpicture_free(AVPicture *picture)
{
- av_free(picture->data[0]);
+ av_freep(&picture->data[0]);
}
void av_picture_copy(AVPicture *dst, const AVPicture *src,
return AVERROR(ENOMEM);
avctx->pix_fmt = AV_PIX_FMT_PAL8;
- ff_set_dimensions(avctx, 318, 198);
- return 0;
+ return ff_set_dimensions(avctx, 318, 198);
}
static av_cold int avs_decode_end(AVCodecContext *avctx)
static av_cold int avui_encode_init(AVCodecContext *avctx)
{
- 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");
return AVERROR(EINVAL);
}
- if (!avctx->coded_frame) {
- av_log(avctx, AV_LOG_ERROR, "Could not allocate frame.\n");
- return AVERROR(ENOMEM);
- }
if (!(avctx->extradata = av_mallocz(24 + FF_INPUT_BUFFER_PADDING_SIZE)))
return AVERROR(ENOMEM);
avctx->extradata_size = 24;
avctx->extradata[19] = 1;
}
+ avctx->coded_frame = av_frame_alloc();
+ if (!avctx->coded_frame) {
+ av_log(avctx, AV_LOG_ERROR, "Could not allocate frame.\n");
+ return AVERROR(ENOMEM);
+ }
return 0;
}
static av_cold int bfi_decode_close(AVCodecContext *avctx)
{
BFIContext *bfi = avctx->priv_data;
- av_free(bfi->dst);
+ av_freep(&bfi->dst);
return 0;
}
AVBitStreamFilterContext *av_bitstream_filter_init(const char *name)
{
- AVBitStreamFilter *bsf = first_bitstream_filter;
+ AVBitStreamFilter *bsf = NULL;
- while (bsf) {
+ while (bsf = av_bitstream_filter_next(bsf)) {
if (!strcmp(name, bsf->name)) {
AVBitStreamFilterContext *bsfc =
av_mallocz(sizeof(AVBitStreamFilterContext));
bsf->priv_data_size ? av_mallocz(bsf->priv_data_size) : NULL;
return bsfc;
}
- bsf = bsf->next;
}
return NULL;
}
#include "golomb.h"
#include "h264chroma.h"
#include "idctdsp.h"
+#include "internal.h"
#include "mathops.h"
#include "qpeldsp.h"
#include "cavs.h"
{
int den = h->scale_den[FFMAX(src->ref, 0)];
- *d_x = (src->x * distp * den + 256 + (src->x >> 31)) >> 9;
- *d_y = (src->y * distp * den + 256 + (src->y >> 31)) >> 9;
+ *d_x = (src->x * distp * den + 256 + FF_SIGNBIT(src->x)) >> 9;
+ *d_y = (src->y * distp * den + 256 + FF_SIGNBIT(src->y)) >> 9;
}
static inline void mv_pred_median(AVSContext *h,
av_frame_free(&h->DPB[0].f);
av_frame_free(&h->DPB[1].f);
- av_free(h->top_qp);
- av_free(h->top_mv[0]);
- av_free(h->top_mv[1]);
- av_free(h->top_pred_Y);
- av_free(h->top_border_y);
- av_free(h->top_border_u);
- av_free(h->top_border_v);
- av_free(h->col_mv);
- av_free(h->col_type_base);
- av_free(h->block);
+ av_freep(&h->top_qp);
+ av_freep(&h->top_mv[0]);
+ av_freep(&h->top_mv[1]);
+ av_freep(&h->top_pred_Y);
+ av_freep(&h->top_border_y);
+ av_freep(&h->top_border_u);
+ av_freep(&h->top_border_v);
+ av_freep(&h->col_mv);
+ av_freep(&h->col_type_base);
+ av_freep(&h->block);
av_freep(&h->edge_emu_buffer);
return 0;
}
{
cavs_vector *pmv_bw = pmv_fw + MV_BWD_OFFS;
int den = h->direct_den[col_mv->ref];
- int m = col_mv->x >> 31;
+ int m = FF_SIGNBIT(col_mv->x);
pmv_fw->dist = h->dist[1];
pmv_bw->dist = h->dist[0];
/* scale the co-located motion vector according to its temporal span */
pmv_fw->x = (((den + (den * col_mv->x * pmv_fw->dist ^ m) - m - 1) >> 14) ^ m) - m;
pmv_bw->x = m - (((den + (den * col_mv->x * pmv_bw->dist ^ m) - m - 1) >> 14) ^ m);
- m = col_mv->y >> 31;
+ m = FF_SIGNBIT(col_mv->y);
pmv_fw->y = (((den + (den * col_mv->y * pmv_fw->dist ^ m) - m - 1) >> 14) ^ m) - m;
pmv_bw->y = m - (((den + (den * col_mv->y * pmv_bw->dist ^ m) - m - 1) >> 14) ^ m);
}
h->low_delay = get_bits1(&h->gb);
h->mb_width = (h->width + 15) >> 4;
h->mb_height = (h->height + 15) >> 4;
- h->avctx->time_base.den = ff_mpeg12_frame_rate_tab[frame_rate_code].num;
- h->avctx->time_base.num = ff_mpeg12_frame_rate_tab[frame_rate_code].den;
+ h->avctx->framerate = ff_mpeg12_frame_rate_tab[frame_rate_code];
h->avctx->width = h->width;
h->avctx->height = h->height;
if (!h->top_qp)
static av_cold int cng_decode_close(AVCodecContext *avctx)
{
CNGContext *p = avctx->priv_data;
- av_free(p->refl_coef);
- av_free(p->target_refl_coef);
- av_free(p->lpc_coef);
- av_free(p->filter_out);
- av_free(p->excitation);
+ av_freep(&p->refl_coef);
+ av_freep(&p->target_refl_coef);
+ av_freep(&p->lpc_coef);
+ av_freep(&p->filter_out);
+ av_freep(&p->excitation);
return 0;
}
.props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS,
.mime_types= MT("image/x-xwindowdump"),
},
+ {
+ .id = AV_CODEC_ID_APNG,
+ .type = AVMEDIA_TYPE_VIDEO,
+ .name = "apng",
+ .long_name = NULL_IF_CONFIG_SMALL("APNG (Animated Portable Network Graphics) image"),
+ .props = AV_CODEC_PROP_LOSSLESS,
+ .mime_types= MT("image/png"),
+ },
/* various PCM "codecs" */
{
.long_name = NULL_IF_CONFIG_SMALL("RealText subtitle"),
.props = AV_CODEC_PROP_TEXT_SUB,
},
+ {
+ .id = AV_CODEC_ID_STL,
+ .type = AVMEDIA_TYPE_SUBTITLE,
+ .name = "stl",
+ .long_name = NULL_IF_CONFIG_SMALL("Spruce subtitle format"),
+ .props = AV_CODEC_PROP_TEXT_SUB,
+ },
{
.id = AV_CODEC_ID_SUBVIEWER1,
.type = AVMEDIA_TYPE_SUBTITLE,
q->avctx = avctx;
/* Take care of the codec specific extradata. */
- if (extradata_size <= 0) {
+ if (extradata_size < 8) {
av_log(avctx, AV_LOG_ERROR, "Necessary extradata missing!\n");
return AVERROR_INVALIDDATA;
}
av_bitstream_filter_close(priv->bsfc);
}
- av_free(priv->sps_pps_buf);
+ av_freep(&priv->sps_pps_buf);
av_frame_free (&priv->pic);
#include "dca.h"
#include "put_bits.h"
-const uint32_t avpriv_dca_sample_rates[16] =
-{
+const uint32_t avpriv_dca_sample_rates[16] = {
0, 8000, 16000, 32000, 0, 0, 11025, 22050, 44100, 0, 0,
12000, 24000, 48000, 96000, 192000
};
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include "parser.h"
#include "dca.h"
#include "get_bits.h"
+#include "parser.h"
typedef struct DCAParseContext {
ParseContext pc;
} DCAParseContext;
#define IS_MARKER(state, i, buf, buf_size) \
- ((state == DCA_MARKER_14B_LE && (i < buf_size-2) && (buf[i+1] & 0xF0) == 0xF0 && buf[i+2] == 0x07) \
- || (state == DCA_MARKER_14B_BE && (i < buf_size-2) && buf[i+1] == 0x07 && (buf[i+2] & 0xF0) == 0xF0) \
- || state == DCA_MARKER_RAW_LE || state == DCA_MARKER_RAW_BE || state == DCA_HD_MARKER)
+ ((state == DCA_MARKER_14B_LE && (i < buf_size - 2) && (buf[i + 1] & 0xF0) == 0xF0 && buf[i + 2] == 0x07) || \
+ (state == DCA_MARKER_14B_BE && (i < buf_size - 2) && buf[i + 1] == 0x07 && (buf[i + 2] & 0xF0) == 0xF0) || \
+ state == DCA_MARKER_RAW_LE || state == DCA_MARKER_RAW_BE || state == DCA_HD_MARKER)
/**
* Find the end of the current frame in the bitstream.
* @return the position of the first byte of the next frame, or -1
*/
-static int dca_find_frame_end(DCAParseContext * pc1, const uint8_t * buf,
+static int dca_find_frame_end(DCAParseContext *pc1, const uint8_t *buf,
int buf_size)
{
int start_found, i;
ParseContext *pc = &pc1->pc;
start_found = pc->frame_start_found;
- state = pc->state;
+ state = pc->state;
i = 0;
if (!start_found) {
state = (state << 8) | buf[i];
if (IS_MARKER(state, i, buf, buf_size)) {
if (!pc1->lastmarker || state == pc1->lastmarker || pc1->lastmarker == DCA_HD_MARKER) {
- start_found = 1;
+ start_found = 1;
pc1->lastmarker = state;
i++;
break;
if (state == DCA_HD_MARKER && !pc1->hd_pos)
pc1->hd_pos = pc1->size;
if (IS_MARKER(state, i, buf, buf_size) && (state == pc1->lastmarker || pc1->lastmarker == DCA_HD_MARKER)) {
- if(pc1->framesize > pc1->size)
+ if (pc1->framesize > pc1->size)
continue;
pc->frame_start_found = 0;
- pc->state = -1;
- pc1->size = 0;
+ pc->state = -1;
+ pc1->size = 0;
return i - 3;
}
}
}
pc->frame_start_found = start_found;
- pc->state = state;
+ pc->state = state;
return END_NOT_FOUND;
}
-static av_cold int dca_parse_init(AVCodecParserContext * s)
+static av_cold int dca_parse_init(AVCodecParserContext *s)
{
DCAParseContext *pc1 = s->priv_data;
return AVERROR_INVALIDDATA;
skip_bits(&gb, 6);
- sr_code = get_bits(&gb, 4);
+ sr_code = get_bits(&gb, 4);
*sample_rate = avpriv_dca_sample_rates[sr_code];
if (*sample_rate == 0)
return AVERROR_INVALIDDATA;
return 0;
}
-static int dca_parse(AVCodecParserContext * s,
- AVCodecContext * avctx,
- const uint8_t ** poutbuf, int *poutbuf_size,
- const uint8_t * buf, int buf_size)
+static int dca_parse(AVCodecParserContext *s, AVCodecContext *avctx,
+ const uint8_t **poutbuf, int *poutbuf_size,
+ const uint8_t *buf, int buf_size)
{
DCAParseContext *pc1 = s->priv_data;
ParseContext *pc = &pc1->pc;
next = dca_find_frame_end(pc1, buf, buf_size);
if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) {
- *poutbuf = NULL;
+ *poutbuf = NULL;
*poutbuf_size = 0;
return buf_size;
}
/* read the duration and sample rate from the frame header */
if (!dca_parse_params(buf, buf_size, &duration, &sample_rate, &pc1->framesize)) {
- s->duration = duration;
+ s->duration = duration;
avctx->sample_rate = sample_rate;
} else
s->duration = 0;
- *poutbuf = buf;
+ *poutbuf = buf;
*poutbuf_size = buf_size;
return next;
}
#define AVCODEC_DCADATA_H
#include <stdint.h>
+
#include "libavutil/mem.h"
/* Generic tables */
-static const uint32_t dca_bit_rates[32] =
-{
- 32000, 56000, 64000, 96000, 112000, 128000,
- 192000, 224000, 256000, 320000, 384000,
- 448000, 512000, 576000, 640000, 768000,
- 896000, 1024000, 1152000, 1280000, 1344000,
+static const uint32_t dca_bit_rates[32] = {
+ 32000, 56000, 64000, 96000, 112000, 128000,
+ 192000, 224000, 256000, 320000, 384000,
+ 448000, 512000, 576000, 640000, 768000,
+ 896000, 1024000, 1152000, 1280000, 1344000,
1408000, 1411200, 1472000, 1536000, 1920000,
- 2048000, 3072000, 3840000, 1/*open*/, 2/*variable*/, 3/*lossless*/
+ 2048000, 3072000, 3840000, 1 /* open */, 2 /* variable */, 3 /* lossless */
};
-static const uint8_t dca_channels[16] =
-{
+static const uint8_t dca_channels[16] = {
1, 2, 2, 2, 2, 3, 3, 4, 4, 5, 6, 6, 6, 7, 8, 8
};
-static const uint8_t dca_bits_per_sample[7] =
-{
+static const uint8_t dca_bits_per_sample[7] = {
16, 16, 20, 20, 0, 24, 24
};
-
-/* Adpcm data */
+/* ADPCM data */
/* 16bits signed fractional Q13 binary codes */
-static const int16_t adpcm_vb[4096][4] =
-{
- { 9928, -2618, -1093, -1263 },
- { 11077, -2876, -1747, -308 },
- { 10503, -1082, -1426, -1167 },
- { 9337, -2403, -1495, 274 },
- { 10698, -2529, -532, -1122 },
- { 10368, -3974, -1264, -750 },
- { 10070, -3667, 346, 863 },
- { 10278, -3093, 311, -576 },
- { 9894, -1330, -1428, -860 },
- { 10544, -1923, -1058, -971 },
- { 10996, -1632, -841, -1404 },
- { 11832, -3465, 1658, -1990 },
- { 10852, -688, -2658, -499 },
- { 10546, -1749, -147, -1733 },
- { 10801, -1004, -708, -1453 },
- { 10588, -441, -2113, -952 },
- { 10141, -3331, -582, -1432 },
- { 9608, -2590, 383, 258 },
- { 11422, -3265, 229, -1544 },
- { 10460, -1338, -713, -1568 },
- { 10306, -1721, -1660, -603 },
- { 9580, -1812, -1235, -1061 },
- { 11471, -2285, -1617, -607 },
- { 10081, -2225, -1408, -868 },
- { 10715, -2624, -1367, -704 },
- { 10616, -1871, -2770, -35 },
- { 9352, -2340, -1024, -1566 },
- { 11065, -1458, -1926, -735 },
- { 11334, -2056, -1041, -1144 },
- { 9825, -2048, -794, -1536 },
- { 11850, -2695, -1123, -867 },
- { 10654, -2226, -1891, -373 },
- { 10024, -1557, -808, -1069 },
- { 11142, -1266, -3238, 128 },
- { 11729, -3282, -514, -1011 },
- { 11402, -2094, -2335, -189 },
- { 10195, -3658, 181, -1875 },
- { 11431, -2626, -404, -1377 },
- { 11001, -3868, -619, -1077 },
- { 10894, -2559, 274, -1758 },
- { 9633, -1482, -2253, -773 },
- { 11245, -3321, 830, -1972 },
- { 9768, -2701, -199, -1859 },
- { 10500, -2042, 525, -2043 },
- { 11669, -4069, 293, -1468 },
- { 9192, -1991, -583, -61 },
- { 10057, -3220, -2015, -473 },
- { 9497, -2315, -2490, -467 },
- { 10455, -3069, -1194, -1007 },
- { 9994, -1936, -60, -1225 },
- { 9295, -2156, -1761, -1134 },
- { 10085, -3748, -1026, 197 },
- { 9334, -2360, 804, -351 },
- { 11561, -2553, 1352, -2313 },
- { 12837, -3998, 1195, -1958 },
- { 10114, -1100, -2414, -394 },
- { 9341, -2530, 315, 755 },
- { 10131, -3164, 1411, -674 },
- { 9535, -905, -1551, 579 },
- { 11717, -1519, -3051, 91 },
- { 9824, -2911, -2775, 192 },
- { 9662, -2934, -561, 1450 },
- { 11085, -3392, -1298, -659 },
- { 8955, -2102, -1899, 703 },
- { 8607, -1742, -4348, 814 },
- { 7640, -2063, -3617, 52 },
- { 7074, -826, -4325, 4375 },
- { 7714, 584, -4238, 1927 },
- { 6355, -952, -4912, 3127 },
- { 7069, -660, -6413, 4087 },
- { 8313, -132, -2964, -876 },
- { 6952, -1422, -3962, -24 },
- { 9299, -734, -3088, -263 },
- { 9484, -574, -4513, 466 },
- { 7246, -91, -3735, -704 },
- { 8325, -1417, -3090, -530 },
- { 6469, -1226, -4757, 829 },
- { 6652, -368, -5682, 1393 },
- { 7971, -1278, -2284, 1205 },
- { 7229, -699, -3556, 1840 },
- { 7994, 1284, -2729, 732 },
- { 9005, -698, -4522, 2189 },
- { 6963, 197, -2727, 380 },
- { 8527, 135, -3991, -213 },
- { 8840, 934, -3014, -567 },
- { 10125, 418, -3284, -371 },
- { 6367, 361, -2318, 2554 },
- { 7892, 172, -5247, 4673 },
- { 6674, 387, -5424, 4398 },
- { 6240, 684, -4047, 1219 },
- { 11170, -794, -5081, 1195 },
- { 11765, -648, -6265, 2052 },
- { 10845, -775, -3837, 366 },
- { 12496, -689, -8260, 3562 },
- { 7893, -1166, -4972, 988 },
- { 8592, 1052, -5986, 3087 },
- { 7277, 1874, -5685, 3579 },
- { 6900, 2016, -4809, 3491 },
- { 8530, -2405, -3250, 1986 },
- { 9426, 494, -7067, 5038 },
- { 10285, 564, -8210, 5370 },
- { 8749, -2207, -3980, 2852 },
- { 9653, -2686, -4300, 1400 },
- { 9770, -2286, -5663, 4233 },
- { 8490, -4, -7048, 4496 },
- { 7697, -1209, -5328, 3183 },
- { 6451, 801, -4324, -554 },
- { 7387, 1806, -5265, 545 },
- { 7450, -2302, -4445, 1418 },
- { 8817, -1370, -5827, 2168 },
- { 10324, -2406, -5629, 2579 },
- { 8863, -2578, -3537, 467 },
- { 6901, -1624, -3169, 3392 },
- { 7846, 156, -6948, 3381 },
- { 7928, -1115, -5972, 4816 },
- { 6089, -599, -4368, -320 },
- { 7833, 1246, -3960, -621 },
- { 8931, 2521, -6768, 2052 },
- { 8900, 1944, -4126, 40 },
- { 7661, -34, -2855, 2480 },
- { 5873, 474, -3262, 3712 },
- { 7535, -234, -4699, 216 },
- { 5856, 143, -5142, 73 },
- { 8944, -106, -5874, 3663 },
- { 7134, 426, -5879, 2895 },
- { 10199, 1011, -4762, 369 },
- { 8454, 264, -5971, 1291 },
- { 7822, -2449, -4333, 4540 },
- { 6200, -2758, -2632, 1497 },
- { 6070, -4315, -2699, 414 },
- { 7047, -3739, -3210, 1060 },
- { 5675, -3801, -2717, -407 },
- { 4789, -4063, -2628, -744 },
- { 4023, -3366, -3133, -726 },
- { 4296, -2407, -3381, -513 },
- { 4388, -2931, -2820, 1512 },
- { 4559, -4233, -1941, 1976 },
- { 6702, -3208, -1755, 1680 },
- { 4416, -3521, -1052, 2984 },
- { 7154, -4266, -1203, 3732 },
- { 3625, -4242, -3244, 1395 },
- { 6518, -2856, -1304, 2887 },
- { 6170, -1949, -3014, 3973 },
- { 5189, -2451, -4020, 3477 },
- { 6218, -2988, -1921, 3844 },
- { 4827, -3688, -1928, 3343 },
- { 6668, -3991, -2805, 3095 },
- { 5297, -3115, -3684, 2390 },
- { 5354, -4614, -2662, 1504 },
- { 4196, -3091, -4147, 1135 },
- { 3540, -2893, -4007, 100 },
- { 5569, -1602, -4007, 1909 },
- { 4341, -2091, -4272, 252 },
- { 5559, -2878, -3832, 498 },
- { 4548, -4479, -2898, -27 },
- { 5176, -2494, -4635, 1476 },
- { 3294, -3485, -3738, 716 },
- { 4920, -1229, -4195, -365 },
- { 3257, -3518, -3349, 2862 },
- { 5286, -1948, -3485, -778 },
- { 6502, -3051, -152, 2854 },
- { 5864, -4192, -1076, 3451 },
- { 4656, -3122, -3448, 179 },
- { 5907, -754, -1596, 3116 },
- { 7229, -3680, -1590, 2892 },
- { 5107, -3888, -3364, 806 },
- { 6764, -2635, -3450, 134 },
- { 5258, -2827, -2844, -1052 },
- { 5798, -1725, -4305, 205 },
- { 5404, -1213, -3362, 449 },
- { 6224, -2738, -3046, -581 },
- { 4223, -2438, -2725, 3745 },
- { 4751, -3411, -2123, 116 },
- { 3868, -3000, -3954, 2297 },
- { 6819, -2899, -4277, 2825 },
- { 4207, -4754, -2808, 865 },
- { 4804, -1494, -1997, 4688 },
- { 5282, -2213, -548, 3559 },
- { 5580, -1912, -566, 4370 },
- { 6168, -2857, -672, 4053 },
- { 6583, -4515, -2850, 1670 },
- { 6511, -3093, -3988, 1421 },
- { 4646, -1790, -1443, 3650 },
- { 5915, -924, -2020, 896 },
- { 7814, -4181, -3152, 2007 },
- { 6190, -2238, -4817, 2279 },
- { 4737, -4034, -3288, 1835 },
- { 8161, -3633, -3423, 3137 },
- { 7415, -2351, -2088, 4290 },
- { 4106, -2517, -62, 2905 },
- { 4909, -3145, -614, 4112 },
- { 4938, -3281, -397, 1100 },
- { -173, 919, 1589, -5363 },
- { -13, 796, -295, -6655 },
- { -1860, -829, 1141, -4555 },
- { 2298, -838, -664, -5005 },
- { -884, -1097, 2074, -4613 },
- { -101, 281, 2846, -4535 },
- { 1166, 453, 2429, -5910 },
- { 879, -664, 2370, -5452 },
- { 1415, -370, -1699, -4727 },
- { -1413, 1277, -669, -6649 },
- { 2133, 304, -968, -4624 },
- { 380, 586, -2087, -4892 },
- { 1336, 275, -82, -5789 },
- { -2459, 1057, -34, -5416 },
- { 2278, -1758, 866, -5653 },
- { 1945, -2295, -149, -5302 },
- { 1287, -3525, 996, -5255 },
- { 2297, 803, 1177, -6067 },
- { 187, -180, -619, -6202 },
- { -793, -2537, 1554, -5057 },
- { -2703, -204, -629, -5853 },
- { -1007, -146, 313, -5582 },
- { 830, 357, 869, -6363 },
- { -228, -575, -3177, -4433 },
- { -1001, -1553, -142, -5708 },
- { -1644, 1683, 1721, -4533 },
- { 893, 1924, -15, -5791 },
- { 2195, 2061, -262, -5471 },
- { 3031, 270, 311, -5096 },
- { 1912, 1638, -1523, -4677 },
- { -3142, -55, 253, -4914 },
- { 356, -1680, 343, -6123 },
- { -2241, -1734, -976, -5939 },
- { -2196, -2893, 547, -4938 },
- { -1245, 126, -1916, -5419 },
- { -249, -3755, -1422, -5594 },
- { 575, -2683, -1926, -4566 },
- { -762, 1885, 192, -5880 },
- { -811, -2562, -1068, -6013 },
- { -2264, -3086, -976, -4775 },
- { 70, -1215, 2880, -4410 },
- { 714, -3760, 2916, -4691 },
- { -244, -3404, 1740, -4493 },
- { 684, -5137, -328, -5608 },
- { -529, -3825, -1786, -4535 },
- { -713, -4743, -1118, -5546 },
- { 2718, -3788, 1798, -5708 },
- { -1639, -3679, -1564, -6095 },
- { 1693, -2642, -1389, -4539 },
- { 505, -1573, -1651, -4878 },
- { -835, -2256, -1941, -5352 },
- { 1464, -411, 1993, -6441 },
- { 493, -3184, -145, -6148 },
- { -1413, 499, -1617, -6479 },
- { -294, 1722, -1419, -5725 },
- { -2937, -1528, -175, -4624 },
- { -594, -5911, -56, -6146 },
- { -300, -4275, 1156, -5947 },
- { 552, -2643, 2669, -3959 },
- { 905, -4158, 1789, -5809 },
- { 1336, -2009, 2108, -5903 },
- { 1555, -3600, 1110, -6759 },
- { -1294, -3464, 77, -6084 },
- { -1139, -4006, -1270, -4181 },
- { -5094, -3296, 1092, -2847 },
- { -5503, -2883, 1984, -2067 },
- { -4671, -4218, -1417, -4132 },
- { -3763, -3818, 1262, -3082 },
- { -5132, -3430, 2928, -728 },
- { -5957, -2877, 1251, -2446 },
- { -4425, -2319, -212, -4276 },
- { -6201, -1993, 1774, -2182 },
- { -5500, -3836, 2201, -1396 },
- { -6934, -2334, 2366, -1293 },
- { -6124, -4140, 1337, -1977 },
- { -6553, -4186, 1756, -1325 },
- { -5126, -1258, 744, -3656 },
- { -5167, -1390, 1581, -2895 },
- { -4525, -3398, 2429, -1865 },
- { -4076, -3183, 2027, -2510 },
- { -6191, -3274, 1838, -1814 },
- { -4454, -2753, 2723, -1185 },
- { -6655, -4797, 251, -2595 },
- { -6332, -2232, 1832, 217 },
- { -5869, -1698, 134, 340 },
- { -6614, -1045, 2126, -1932 },
- { -4859, -2107, 2010, -2435 },
- { -6274, -1622, 2808, -1374 },
- { -3119, -3209, 521, -3988 },
- { -5676, -2082, -420, -2711 },
- { -7073, -3623, 696, -2343 },
- { -5986, -4224, 572, -2454 },
- { -4340, -4521, 882, -2771 },
- { -6178, -1933, 535, -1444 },
- { -4923, -4163, 1744, -2066 },
- { -6410, -1519, 1058, -2683 },
- { -5077, -1185, 856, -2216 },
- { -7091, -2444, 687, -2597 },
- { -5284, -2165, 3239, -993 },
- { -4763, -1497, 197, -3179 },
- { -4128, -4958, -396, -3578 },
- { -5054, -3878, -647, -2672 },
- { -7005, -3348, 1679, -1579 },
- { -5767, -1017, 2582, -1915 },
- { -7069, -2787, 1331, -2070 },
- { -5532, -2296, 706, -2950 },
- { -5059, -3543, -821, -3637 },
- { -6639, -1835, 1016, -696 },
- { -5611, -5220, -694, -3371 },
- { -5994, -2803, 2933, -729 },
- { -5948, -619, 1596, -2676 },
- { -5486, -4419, 153, -3265 },
- { -4329, -3440, 1646, -1439 },
- { -4083, -3978, 177, -3569 },
- { -4289, -2599, 1224, -3075 },
- { -5707, -3253, 1912, -759 },
- { -6606, -3437, 2562, -571 },
- { -5254, -2444, 769, -352 },
- { -6545, -3154, 582, -1103 },
- { -5328, -2241, 2566, -1775 },
- { -7216, -1936, 1538, -1983 },
- { -3730, -2451, 426, -3869 },
- { -5110, -1385, 2031, -1169 },
- { -6470, -2715, 269, -3123 },
- { -5806, -2480, -97, -3832 },
- { -3683, -4916, -490, -4330 },
- { -6341, -2083, -669, -115 },
- { -4913, -4079, -837, -4673 },
- { -3274, -2497, 2334, -2652 },
- { -1286, -1731, 2550, -3756 },
- { -3375, -877, 926, -3977 },
- { -2525, -2079, 2879, -2625 },
- { -5308, -504, 3111, -1607 },
- { -4904, 460, 4093, -1232 },
- { -1993, 1616, 4656, -1913 },
- { -3481, -1176, 3119, -2236 },
- { -4132, -1502, 2339, -2545 },
- { -2542, 1151, 3569, -2550 },
- { -4381, 430, 3147, -2082 },
- { -3888, 867, 3899, -1657 },
- { -2861, 1290, 4202, -1979 },
- { -3893, -253, 2363, -2764 },
- { -1705, 688, 3827, -2923 },
- { -2223, 2312, 3700, -3148 },
- { -1986, -720, 5021, -795 },
- { -3177, 242, 1952, -3352 },
- { -1854, 1509, 2528, -3815 },
- { -3173, 97, 5019, -706 },
- { -2689, -145, 1375, -3915 },
- { -4838, -385, 2488, -2427 },
- { -4557, -355, 1603, -3060 },
- { -3522, 1832, 3292, -2674 },
- { -3769, 780, 2378, -2704 },
- { -4323, -1932, 3414, -1169 },
- { -2740, 1158, 2729, -3273 },
- { -3647, 210, 1464, -2892 },
- { -2342, -2097, 1513, -3727 },
- { -4422, -1242, 3130, -1833 },
- { -1308, -1039, 4290, -1875 },
- { -1754, -2535, 3298, -2314 },
- { -4102, -186, 4037, -1094 },
- { -1008, 1570, 3290, 171 },
- { -3322, -2621, 2791, -1536 },
- { -2539, -2597, 3442, -1672 },
- { -3411, -2015, 3670, -1174 },
- { -2097, 730, 5581, -1399 },
- { -1510, -74, 4820, -2004 },
- { -4086, -868, 4425, -771 },
- { -956, -986, 3640, -2925 },
- { -2087, -1250, 3464, -2458 },
- { -3308, -2411, 1334, -3667 },
- { -2264, -389, 4004, -1854 },
- { -680, 239, 4058, -3388 },
- { -1357, 30, 2993, -3658 },
- { -3601, -552, 1177, -1136 },
- { -2641, 442, 4374, -1625 },
- { -2525, 770, 1640, -3895 },
- { -3172, -891, 3893, -1608 },
- { -2996, 13, 3277, -2414 },
- { -899, 1055, 4470, -2501 },
- { -422, -584, 3475, -3787 },
- { -1978, -593, 2566, -3415 },
- { -3150, -1280, 2362, -3047 },
- { -3592, 224, 1026, -3932 },
- { -4840, -1189, 3633, -879 },
- { -3952, -2255, 2916, -1826 },
- { -1695, 28, 1810, -349 },
- { -745, -2484, 3308, -3293 },
- { -1016, 1563, 5365, -1823 },
- { -2172, -1787, 4266, -1287 },
- { -1241, -1951, 3982, -2413 },
- { -2009, -2639, 2330, -3480 },
- { 5105, -1618, -2588, -2015 },
- { 6497, -1523, -3218, -910 },
- { 6526, -2305, -2029, -1790 },
- { 5289, -99, -3436, -400 },
- { 5781, -1623, -1577, -2617 },
- { 5259, -670, -3125, -1700 },
- { 6343, -1256, -331, -3222 },
- { 7967, -678, -2195, -1462 },
- { 6119, -695, -2988, -1538 },
- { 6108, 494, -3359, -1548 },
- { 5067, 969, -2328, -2707 },
- { 7595, -435, -1497, -2056 },
- { 6929, -719, -2420, -1665 },
- { 5190, 584, -2982, -2103 },
- { 6106, -444, -1411, -2739 },
- { 5584, 289, -1804, -2803 },
- { 5276, 227, -1180, -3361 },
- { 7544, -1525, -1834, -1725 },
- { 5986, -1470, -2606, -1701 },
- { 5096, -765, -1712, -3006 },
- { 5423, -149, -3933, -1157 },
- { 7651, 26, -2445, -1507 },
- { 4745, -464, -1735, -2362 },
- { 5352, -1011, -1094, -1999 },
- { 6300, -672, -542, -1950 },
- { 6675, -1020, -1318, -1059 },
- { 7218, -2036, -603, -2462 },
- { 7755, -1514, -2430, -1229 },
- { 5041, 449, -1056, -2405 },
- { 6710, -2277, -1344, -2284 },
- { 6824, -1347, -2254, 251 },
- { 6068, -1857, -983, -1316 },
- { 5603, -2177, -2730, -1477 },
- { 5838, -1059, -3604, -970 },
- { 5076, -789, -335, -2413 },
- { 6191, -1634, -2000, -2129 },
- { 5092, -1292, -2543, -1034 },
- { 5305, 435, -1710, -1850 },
- { 6140, 561, -2176, -2380 },
- { 6752, 348, -2496, -1890 },
- { 6405, 273, -1098, -2778 },
- { 6942, -1340, -496, -1381 },
- { 5238, -687, -2454, -2349 },
- { 6959, -882, -1833, -2061 },
- { 6292, -253, -2125, -2199 },
- { 5838, -574, -759, -3215 },
- { 6954, -1484, -640, -2771 },
- { 7498, -1706, -1210, -2154 },
- { 6772, -1003, -1235, -2532 },
- { 6014, 228, -2154, -1108 },
- { 6943, -2178, -2644, -1122 },
- { 7262, -763, -3056, -1090 },
- { 6273, -1478, -1072, 177 },
- { 4734, 425, -2912, 357 },
- { 7129, 168, -1537, -2327 },
- { 7204, -434, -746, -2660 },
- { 6879, 57, -3087, -1310 },
- { 4623, -610, -718, -3459 },
- { 6565, -543, -1998, -339 },
- { 4752, -277, -2066, -1405 },
- { 7435, -1416, -1904, -505 },
- { 4076, 150, -1222, -3556 },
- { 7082, -28, -1456, -1174 },
- { 5941, -446, -1326, -1158 },
- { 3870, -1648, -2474, -2589 },
- { 858, 37, -3387, -3721 },
- { 3557, -1503, -1664, -3383 },
- { 3336, -1972, -3079, -2216 },
- { 3186, 60, -4185, -863 },
- { 3456, -773, -3066, -2457 },
- { 4131, -913, -2060, -2601 },
- { 4431, -691, -4114, -972 },
- { 3461, -334, -3680, -1751 },
- { 2006, -459, -2214, -3827 },
- { 1322, 32, -2816, -3203 },
- { 4425, -1897, -2791, -1946 },
- { 4504, 23, -3421, -1909 },
- { 3090, -885, -2366, -3264 },
- { 3209, -2363, -3730, -834 },
- { 3312, -1471, -3641, -1579 },
- { 4184, -1669, -3323, -1248 },
- { 2190, -931, -3302, -2944 },
- { 2947, -229, -4791, -1195 },
- { 2020, -1626, -2700, -3125 },
- { 2214, -326, -4352, -1683 },
- { 3286, -2619, -2412, -2458 },
- { 1000, -2571, -4129, -2158 },
- { 2496, -2627, -3611, -1433 },
- { 2043, -2191, -2167, -3827 },
- { 2571, -2544, -1915, -3222 },
- { 2022, -1501, -3856, -2165 },
- { 2685, -1180, -1461, -4038 },
- { 1610, -2313, -4391, -1173 },
- { 2340, -2490, -4215, -516 },
- { 1742, -2615, -3632, -2146 },
- { 523, -1293, -4246, -2442 },
- { 3725, -2723, -3014, -1576 },
- { 3554, -1381, -4200, -824 },
- { 1291, -1594, -4777, -1430 },
- { 1452, 515, -2960, -3830 },
- { 4264, -894, -3305, -1826 },
- { 2606, -1452, -4522, -966 },
- { 1196, -830, -4807, -1816 },
- { 1054, -775, -2616, -4071 },
- { 4206, 415, -4344, -1132 },
- { 3044, 491, -4126, -1934 },
- { 988, -901, -3353, -3443 },
- { 1729, -3063, -2267, -3370 },
- { 3915, 912, -2989, -2387 },
- { 3781, 300, -2457, -3050 },
- { 2712, 924, -1350, -1206 },
- { 4230, 405, -2343, 665 },
- { 1878, -873, -225, -29 },
- { 3510, 56, -1334, -3420 },
- { 2850, 1447, -2651, -3150 },
- { 1510, -706, -4125, -2483 },
- { 3115, 793, -1692, -3894 },
- { 2667, 213, -2973, -2786 },
- { 1184, -2384, -3051, -3173 },
- { 2139, 796, -2079, -3697 },
- { 1464, -1483, -3726, -2754 },
- { 2407, -1148, -3915, -1569 },
- { 2612, -1779, -3217, -2271 },
- { 2406, -2870, -2937, -2496 },
- { 2140, 126, -3646, -2758 },
- { 2952, -1036, 268, -1423 },
- { 93, -1931, -3841, -3535 },
- { 389, -2953, -3383, -3343 },
- { 8652, -5511, -1662, 565 },
- { 7427, -2791, -2535, -842 },
- { 8541, -4253, -1407, -988 },
- { 8018, -3203, -2998, 105 },
- { 7231, -3926, -958, 1308 },
- { 7331, -3690, -363, 2586 },
- { 6803, -3646, -2226, -903 },
- { 8163, -2811, -477, -2235 },
- { 9356, -3818, -1685, -684 },
- { 8466, -2854, -302, -698 },
- { 8458, -3224, 517, 279 },
- { 8074, -2619, -1326, 2596 },
- { 8779, -2761, -2527, -441 },
- { 6533, -2887, -899, -696 },
- { 7394, -2305, -1642, -120 },
- { 8281, -3780, -22, 1305 },
- { 9158, -4413, -779, 901 },
- { 9031, -5240, -1109, 1678 },
- { 8717, -3650, 410, -1075 },
- { 7317, -3197, -818, -2264 },
- { 7934, -2385, -1214, -1886 },
- { 8256, -4441, -291, -587 },
- { 7358, -3395, 1090, -270 },
- { 9446, -4910, -1343, -473 },
- { 8187, -4726, -808, 1166 },
- { 7504, -3845, -47, 267 },
- { 8029, -2146, -1283, -383 },
- { 7461, -2705, -853, 783 },
- { 9367, -3636, -645, -354 },
- { 8955, -3473, -308, -1947 },
- { 8676, -2683, -2099, 1485 },
- { 7481, -3003, -871, -444 },
- { 8015, -2839, -1673, 1175 },
- { 6947, -4643, -1527, -1047 },
- { 7622, -2575, -137, -960 },
- { 9388, -4279, -707, -1322 },
- { 8382, -5259, -1283, -565 },
- { 6856, -4138, -1030, 630 },
- { 8659, -2571, -1124, -1666 },
- { 8763, -3807, -537, 2543 },
- { 8049, -3578, -2186, -604 },
- { 8272, -2351, -1985, -1214 },
- { 6855, -3796, -1527, -1631 },
- { 7178, -2896, -1600, -1756 },
- { 7040, -2888, -89, -1586 },
- { 6261, -3403, -264, 998 },
- { 7756, -4699, -1543, -834 },
- { 7682, -4622, -758, -1721 },
- { 8839, -4232, -2932, 1959 },
- { 9363, -4679, -1956, 39 },
- { 7883, -3616, -1414, -1432 },
- { 8828, -3188, -1356, -1312 },
- { 7746, -3987, -121, -2424 },
- { 9262, -3256, -693, 818 },
- { 7670, -3420, -148, 3504 },
- { 7344, -3183, 608, 1595 },
- { 8976, -4139, -1848, 1304 },
- { 6708, -4131, 33, -852 },
- { 7840, -4429, -2275, 79 },
- { 8980, -3858, -2838, 453 },
- { 7815, -4604, -2563, 944 },
- { 8372, -4422, -1783, 3071 },
- { 8623, -5128, -1754, 2888 },
- { 7462, -3281, 889, 920 },
- { 8416, -59, -1320, -1825 },
- { 7928, -1488, -414, -2499 },
- { 8110, -977, -1047, -2042 },
- { 8278, -687, -1597, -1550 },
- { 7988, -174, -977, -2106 },
- { 8609, -1547, -1628, -1527 },
- { 9000, -1798, -946, -1761 },
- { 8954, -872, -1404, -1594 },
- { 8939, 466, -748, -1212 },
- { 9549, -329, -177, -1360 },
- { 9411, -18, -1126, -1568 },
- { 8859, -782, -488, -1338 },
- { 8955, -218, -43, -1209 },
- { 9131, -69, -453, -1001 },
- { 9069, -1519, -1091, -1199 },
- { 9247, -1309, -566, -1146 },
- { 8528, -1617, -287, -1313 },
- { 7763, -745, -149, -2040 },
- { 8294, -343, 257, -2633 },
- { 10149, -893, -552, -1649 },
- { 9398, -915, 218, -2042 },
- { 9703, -1194, -675, -1592 },
- { 9586, -700, -427, -1710 },
- { 8930, 497, -1445, -1218 },
- { 9285, -1323, -163, -1552 },
- { 8431, -1289, -985, -1404 },
- { 8965, -655, 653, -1483 },
- { 9542, -1001, -951, -1128 },
- { 9205, -647, -37, -882 },
- { 8603, -56, 514, -1793 },
- { 9300, -12, -1324, -567 },
- { 8773, 238, -184, -1456 },
- { 9941, -1306, -69, -1792 },
- { 9360, 279, -376, -1919 },
- { 9180, -285, 95, -2170 },
- { 9922, -501, -970, -1570 },
- { 8341, -1493, -856, -2092 },
- { 8780, -981, -850, -1014 },
- { 9721, -548, -1504, -1094 },
- { 9973, -1493, 482, -2105 },
- { 8707, -333, -1027, -1087 },
- { 9098, -469, -315, -1723 },
- { 8879, -1050, -661, -2020 },
- { 8857, 602, -866, -1918 },
- { 8945, -1025, -2154, -1071 },
- { 8484, -1930, -468, -2179 },
- { 9177, -1903, -224, -2112 },
- { 8652, -137, -2097, -1214 },
- { 9063, -973, -1405, -772 },
- { 9328, -456, 662, -2469 },
- { 10101, -697, 127, -2113 },
- { 9685, 811, -2359, -1024 },
- { 8586, -94, -460, -1982 },
- { 7924, -141, -509, -2513 },
- { 7773, -669, -107, -2835 },
- { 8636, -1064, -46, -2409 },
- { 9748, 596, -1815, -1349 },
- { 8924, 304, 547, -2614 },
- { 9442, 746, -1153, -1679 },
- { 9454, -278, -529, -1976 },
- { 8488, 561, -32, -2160 },
- { 10083, -63, -1544, -1364 },
- { 9390, -1278, 568, -1131 },
- { 9740, -49, -2253, -910 },
- { 3636, -2391, -1115, -3614 },
- { 6014, -3204, -1902, -1808 },
- { 5787, -3497, -1116, -2590 },
- { 4365, -3046, -1632, -2668 },
- { 4733, -2192, -2029, -2468 },
- { 5412, -2753, -1633, -2464 },
- { 4455, -3375, -767, -3399 },
- { 4456, -1644, -983, -2841 },
- { 4039, -2523, 38, -3967 },
- { 3406, -2662, 72, -4757 },
- { 4279, -2005, 1055, -4399 },
- { 4321, -1377, -860, -3786 },
- { 3743, -5739, -651, -3047 },
- { 3528, -5510, 361, -4060 },
- { 6496, -4886, -136, -2689 },
- { 4513, -5254, 551, -4010 },
- { 6557, -3413, -92, -3063 },
- { 4186, -2059, 187, 47 },
- { 6210, -4117, -1256, -1985 },
- { 6038, -4343, 351, -2124 },
- { 4305, -4780, -2077, -1897 },
- { 4480, -3815, -2228, -1533 },
- { 5582, -3689, 1221, -3429 },
- { 5532, -4874, 1195, -2765 },
- { 6518, -2853, -905, -2568 },
- { 5467, -2192, 470, -4115 },
- { 4139, -1577, 240, -3493 },
- { 5281, -1926, -729, -3340 },
- { 5214, -2870, 1359, -4289 },
- { 3046, -3510, -1536, -3214 },
- { 5433, -2881, -1230, -1184 },
- { 4861, -3932, -1071, -2791 },
- { 5693, -4234, -1906, -1502 },
- { 4004, -3935, -1804, -2383 },
- { 3728, -3792, 681, -4773 },
- { 3621, -3030, -1951, -2598 },
- { 5133, -3903, 44, -3700 },
- { 3561, -3451, 1183, -5301 },
- { 5026, -2762, -2341, -1780 },
- { 5841, -2492, -467, -3210 },
- { 5591, -1791, 497, -2472 },
- { 5054, -3898, -1822, -2097 },
- { 5813, -2792, 83, -1469 },
- { 4432, -4497, 1670, -5193 },
- { 5338, -4653, -1109, -2200 },
- { 3239, -4401, -648, -3655 },
- { 2147, -3598, -1200, -4242 },
- { 4417, -2271, -1552, -3210 },
- { 6494, -4360, 852, -3565 },
- { 2393, -6358, -856, -4524 },
- { 4959, -4196, -847, -1403 },
- { 4924, -5438, -226, -3026 },
- { 4254, -5303, -1306, -2424 },
- { 4121, -3126, -2334, -1981 },
- { 3437, -4443, -1464, -2953 },
- { 3203, -3459, -529, -4339 },
- { 5896, -5945, 543, -3246 },
- { 1987, -4733, -220, -4863 },
- { 4358, -4431, -514, -3081 },
- { 4583, -2416, -492, -2287 },
- { 2943, -5035, 419, -4927 },
- { 5358, -5129, 987, -4309 },
- { 4460, -3392, 1752, -5634 },
- { 3415, -4633, 1507, -5945 },
- { 811, -4692, -445, 2333 },
- { 1009, -5613, -1857, 1360 },
- { 1338, -2712, -2720, 3036 },
- { 1002, -3754, -2582, 2344 },
- { 750, -4608, -2334, 714 },
- { 2043, -3207, -2822, 2173 },
- { -140, -4654, -2953, 357 },
- { -54, -4026, -2376, 2695 },
- { 1858, -5022, -717, 2287 },
- { 2064, -3894, -722, 3255 },
- { 2727, -4558, -332, 2603 },
- { 1810, -5378, 283, 1826 },
- { 3935, -4326, 762, 3383 },
- { -767, -4697, -2510, 1922 },
- { 2146, -4312, -3090, 1641 },
- { 54, -5881, -2114, 921 },
- { 1992, -5766, -640, 1574 },
- { 1200, -5371, -1114, 1828 },
- { 2973, -5337, 34, 2266 },
- { 1531, -5018, -2817, 1192 },
- { 3078, -4570, 117, 1990 },
- { 924, -4286, -1388, 2713 },
- { 142, -5058, -2848, 1487 },
- { -106, -6180, -881, 842 },
- { 673, -5433, -229, 1596 },
- { 783, -5710, -2784, 562 },
- { 1935, -5729, -2009, 856 },
- { -410, -3375, -3326, 2734 },
- { 234, -3000, -2628, 3260 },
- { 733, -3405, -3806, 1589 },
- { 771, -4285, -3544, 1314 },
- { 1192, -3563, -3960, 2178 },
- { 206, -5555, -1250, 1546 },
- { -130, -3815, -1210, 3041 },
- { 646, -3940, -393, 2992 },
- { -184, -4931, -1767, 1925 },
- { 2746, -5120, -2275, 1464 },
- { 2440, -3731, -3352, 2729 },
- { -490, -4942, -3779, 997 },
- { 68, -2636, -4167, 3778 },
- { 48, -3986, -4118, 2106 },
- { -978, -5486, -1336, 1390 },
- { 1126, -5297, -855, 640 },
- { -472, -3975, -3622, 1557 },
- { 2456, -5344, -1523, 1648 },
- { -774, -5652, -2417, 1147 },
- { 995, -6122, -812, 1132 },
- { 3282, -4571, -1763, 2175 },
- { 3655, -3862, -676, 3568 },
- { 3038, -3647, -1672, 3381 },
- { 2595, -2964, -2772, 3263 },
- { 4176, -3353, -1148, 4354 },
- { 1603, -3442, -1500, 3444 },
- { 828, -6226, -1783, 678 },
- { 1421, -3333, -3080, 3403 },
- { 1121, -4727, -1924, 1984 },
- { -186, -5083, -682, 1796 },
- { 819, -2778, -3488, 530 },
- { 421, -2873, -3832, 2596 },
- { 2164, -4263, -1605, 2282 },
- { 585, -4437, -682, -491 },
- { -644, -4452, -1157, 2325 },
- { 1991, -4299, 210, 2834 },
- { 2135, -3632, -2113, 665 },
- { -7482, -2724, -2662, -1380 },
- { -6983, -2166, -3756, -3509 },
- { -7085, -1439, -2397, -3112 },
- { -7760, -3049, -3319, -2822 },
- { -8413, -2760, -4406, -3298 },
- { -5995, -3943, -1260, -3750 },
- { -7879, -1554, -3464, -2606 },
- { -6314, -2034, -3878, -1681 },
- { -8849, -2084, -1399, -1231 },
- { -7153, -2602, -1384, -817 },
- { -8041, -2571, -407, -2785 },
- { -7246, -2233, -1578, 260 },
- { -7336, -3883, -4061, -1342 },
- { -7619, -3908, -2342, 382 },
- { -8684, -3724, -1662, -727 },
- { -7850, -2922, -1770, -3449 },
- { -6766, -2034, -1293, -1988 },
- { -6895, -2116, -968, -3744 },
- { -7136, -5147, -2618, -2809 },
- { -8224, -3724, -2519, -1589 },
- { -6711, -2750, -3021, -219 },
- { -8059, -1638, -1102, -3175 },
- { -8710, -4839, -3963, -3143 },
- { -9363, -4965, -3257, -1002 },
- { -6099, -1751, -3157, -395 },
- { -6453, -3216, -4597, -483 },
- { -7879, -5477, -839, -2638 },
- { -7202, -4038, -526, -2856 },
- { -8022, -1228, -1910, -1646 },
- { -9117, -1393, -1582, -2535 },
- { -9095, -2693, -636, -2605 },
- { -9076, -2580, -3481, -2519 },
- { -8327, -4859, -2422, 83 },
- { -8368, -2129, -2324, -2173 },
- { -8554, -4563, -3842, -2007 },
- { -10462, -4261, -1934, -2084 },
- { -9717, -3187, -2294, -1896 },
- { -9625, -3889, -3020, -3224 },
- { -9857, -4955, -4239, -2184 },
- { -9752, -2351, -2277, -3129 },
- { -7219, -1302, -2639, -1603 },
- { -7477, -4360, -3718, -559 },
- { -5680, -2033, -2326, -3078 },
- { -10190, -5548, -4643, -3601 },
- { -9431, -4121, -879, -2479 },
- { -8365, -5450, -2020, -1439 },
- { -6289, -5178, -1605, -3845 },
- { -8319, -3866, -687, -2792 },
- { -8131, -1031, -3608, -3947 },
- { -10510, -2560, -1199, -2082 },
- { -11015, -3640, -2748, -3041 },
- { -8762, -5022, -5231, -1162 },
- { -10153, -2715, -4648, -4859 },
- { -7930, -5205, -1900, -3600 },
- { -9561, -3548, -4812, -3722 },
- { -7663, -4709, -1180, -1475 },
- { -9073, -5707, -1815, -2980 },
- { -8602, -2363, -2675, -3770 },
- { -9967, -5614, -3575, -3838 },
- { -8324, -1005, -2131, -3254 },
- { -10331, -5737, -2550, -2940 },
- { -8234, -3354, -3361, -4479 },
- { -8140, -1951, -4526, -4545 },
- { -6679, -2662, -2284, -4182 },
- { -1122, -1514, -6427, -212 },
- { 54, -1660, -5424, -1404 },
- { 254, -2778, -5222, 846 },
- { -267, -1661, -6577, 814 },
- { -305, -2021, -5759, 1484 },
- { -1791, -2446, -6867, -86 },
- { -2929, -3158, -6603, -1799 },
- { -1391, -3189, -5557, -1053 },
- { -1602, -884, -6767, -1213 },
- { -361, -318, -6219, -44 },
- { -4078, -2635, -5523, -433 },
- { -956, 478, -4382, 1470 },
- { -3300, -2462, -6021, -2721 },
- { 708, -2434, -5085, -540 },
- { -2435, -3607, -5647, -2110 },
- { -491, -1134, -4681, -2886 },
- { 87, -3435, -4641, -1194 },
- { -586, -2927, -4784, 366 },
- { -1394, -2326, -6021, 350 },
- { 97, -2519, -4678, -2120 },
- { -1547, -1907, -5069, -2993 },
- { 268, -3724, -4719, 127 },
- { -827, -1190, -5912, 1144 },
- { -3959, -2322, -6898, -1974 },
- { -2728, -2228, -6426, -562 },
- { -456, -666, -5785, -1609 },
- { 531, -1096, -5731, -656 },
- { -3569, -688, -3915, 110 },
- { -4752, -1725, -4393, -377 },
- { -3210, -3315, -6960, -840 },
- { -688, -3416, -4971, 1221 },
- { -1833, 77, -6491, -2434 },
- { -239, -255, -6850, -886 },
- { -2112, -1490, -6291, -2689 },
- { -1544, -4579, -5198, -1261 },
- { -2771, -4014, -5520, 683 },
- { -1635, -2829, -5512, 1214 },
- { -958, -2582, -4823, 2360 },
- { -2077, -4566, -4642, 365 },
- { -3112, -4214, -5960, -823 },
- { -2467, -2510, -4858, 1467 },
- { -1561, -3399, -5822, 211 },
- { -775, -1081, -4424, 2636 },
- { -1263, 25, -6378, -1392 },
- { -3476, -366, -5417, -1393 },
- { -3176, -1476, -4149, 1466 },
- { -2479, 518, -4448, -257 },
- { -2992, 158, -4660, -1279 },
- { -1320, -3872, -4479, 1147 },
- { -1475, -312, -5318, 539 },
- { -3527, -1679, -5860, -1681 },
- { -3397, -3438, -5593, 1866 },
- { -4089, -2439, -4763, 1275 },
- { -748, -4513, -4687, -48 },
- { -2166, -4531, -4691, -2856 },
- { -2385, -853, -6035, -627 },
- { -1194, -4091, -4472, -1963 },
- { -682, -3234, -4084, -3033 },
- { -3255, -5015, -5328, -12 },
- { -2313, -3436, -4601, -155 },
- { -2792, -1038, -6947, -2019 },
- { -1244, -1526, -5771, -1882 },
- { -4679, -3731, -5506, 283 },
- { -3062, -66, -3558, -758 },
- { -4895, -1187, 4751, 3728 },
- { -7600, -2752, 3320, 4613 },
- { -5703, -2975, 3944, 2659 },
- { -4972, -1257, -246, 2952 },
- { -4221, -2487, 1702, 4295 },
- { -2900, -1529, 2458, 4935 },
- { -5061, 407, 2416, 4050 },
- { -6931, -3478, 2761, 2213 },
- { -6037, -3921, 3192, 1866 },
- { -6113, -811, 2407, 3782 },
- { -5878, -1716, 1207, 3478 },
- { -5953, -2853, 2207, 2712 },
- { -6807, -3223, 2749, 3595 },
- { -3272, -3157, 1389, 3788 },
- { -5368, -1904, 1980, 5077 },
- { -7235, -1398, 3075, 4548 },
- { -4765, -3487, 2755, 2796 },
- { -7658, -4435, 2694, 2582 },
- { -6997, -4282, 456, 3832 },
- { -5563, -3115, -63, 3713 },
- { -4244, -4220, 1450, 2767 },
- { -3801, -2194, 190, 4303 },
- { -5458, -4119, 1958, 2274 },
- { -7300, -3469, 3514, 3193 },
- { -4594, -2067, 775, 4752 },
- { -3389, -1654, 1464, 5412 },
- { -4845, -3483, 964, 3437 },
- { -6007, -2818, 1666, 4659 },
- { -8709, -5007, 1757, 3287 },
- { -5833, -4389, 1025, 3171 },
- { -5788, -1780, 3944, 3661 },
- { -4430, -920, 1938, 4753 },
- { -7066, -1857, 4591, 4538 },
- { -3549, -513, 1427, 5317 },
- { -7517, -1220, 2883, 3049 },
- { -7605, -2687, 1874, 2735 },
- { -8718, -4035, 2676, 3730 },
- { -7990, -3907, 1185, 2607 },
- { -6058, -1744, 3349, 5157 },
- { -5954, 565, 3161, 3250 },
- { -6478, -612, 1930, 2271 },
- { -6535, -1445, -2, 1618 },
- { -8963, -4151, 1192, 4044 },
- { -7227, -3570, 1600, 4234 },
- { -4674, 79, 595, 3015 },
- { -3974, 430, 2727, 5137 },
- { -5299, 9, 3714, 4779 },
- { -6779, -2699, -8, 2436 },
- { -7016, -1145, 1293, 2310 },
- { -6955, -3312, 1534, 1801 },
- { -4025, 740, 1850, 4054 },
- { -9589, -3460, 4154, 5270 },
- { -4404, -1181, 4298, 5173 },
- { -7356, -4583, -18, 2644 },
- { -6516, -1235, 4439, 6234 },
- { -3453, -301, 4344, 4464 },
- { -4643, 1530, 3315, 4340 },
- { -4575, -2557, 3754, 3682 },
- { -3643, -3501, 2051, 2997 },
- { -5412, -2475, 2301, 1579 },
- { -5846, 259, 1360, 2348 },
- { -5258, -1358, 1050, 838 },
- { -5542, -219, 6377, 5750 },
- { -5713, -2952, 922, 899 },
- { -2049, -1135, 5206, 1033 },
- { -1693, -1886, 4835, -106 },
- { -2344, -3504, 4232, -13 },
- { -2475, -2334, 5043, 1126 },
- { -787, -2549, 3880, 2138 },
- { -3159, -2341, 4830, 2887 },
- { -1780, -1009, 6240, 2061 },
- { -4327, -3363, 2818, 886 },
- { -3376, -2743, 4104, 207 },
- { -3250, -4640, 2718, 1498 },
- { -382, -1075, 4382, 3460 },
- { -2416, -4168, 3530, 816 },
- { -1756, -2708, 4861, 622 },
- { -1879, -2097, 5156, 2889 },
- { -2496, -2418, 3722, 2671 },
- { -2717, -3252, 3341, 1944 },
- { -4063, -4091, 3306, 267 },
- { -3549, -3808, 3747, 842 },
- { -2635, 546, 5794, 1894 },
- { -1857, -1121, 4383, 3964 },
- { -2226, -2166, 3489, 3678 },
- { -3492, -660, 5323, 1063 },
- { -3033, -3130, 4382, 1828 },
- { -2703, -625, 6369, 2851 },
- { -1656, -2842, 4584, -528 },
- { -4781, -2622, 4390, 2097 },
- { -413, -2045, 5081, 3035 },
- { -3810, -2662, 4532, 1095 },
- { -3144, -1858, 5215, 1880 },
- { -3562, -1795, 4928, 670 },
- { -4800, -1509, 5189, 1859 },
- { -1085, -3832, 4169, 900 },
- { -1969, -3270, 2857, 2878 },
- { -4267, -4140, 3176, 1805 },
- { -5145, -3727, 3524, 1168 },
- { -1346, -1876, 5501, 1748 },
- { -4998, -2945, 3699, 338 },
- { -3458, -3096, 3406, -635 },
- { -1751, -3209, 3508, 395 },
- { -2507, 170, 5987, 705 },
- { -3756, -1072, 5647, 3536 },
- { -2870, -1439, 5026, 3212 },
- { -3913, -3225, 3669, 2144 },
- { -3739, 226, 5747, 764 },
- { -2052, -820, 5266, 3093 },
- { -3214, -3820, 2409, 2391 },
- { -4398, -2588, 3501, -218 },
- { -4484, -1763, 4180, -198 },
- { -3368, -1525, 4362, -134 },
- { -2407, 224, 4905, 3533 },
- { -1369, -2937, 4728, 1788 },
- { -4848, -1707, 4159, 851 },
- { -3454, -1749, 4281, 3230 },
- { -1990, -3853, 3487, 1735 },
- { -3117, 92, 6155, 4075 },
- { -2676, -2472, 4078, -589 },
- { -1547, -2012, 2626, 1835 },
- { -4275, -588, 4824, 725 },
- { -601, -2249, 3736, 3548 },
- { -4060, -61, 5333, 3097 },
- { -4303, 7, 6551, 3054 },
- { -5003, -1029, 5786, 3319 },
- { -2810, -728, 5392, 199 },
- { -1232, -200, 5228, 3121 },
- { 2621, 165, -6255, 298 },
- { 3669, 537, -6844, 1564 },
- { 1598, -1190, -6235, 2523 },
- { 2164, -32, -6894, 1383 },
- { 853, -1597, -6069, 1449 },
- { 1377, -1661, -5266, 108 },
- { 2660, 48, -5172, -517 },
- { 1903, -391, -5677, 1010 },
- { 3792, 206, -5274, -11 },
- { 1239, 2776, -2929, 2721 },
- { 4071, 149, -7259, 3125 },
- { 1436, -480, -6156, -196 },
- { 1373, -1960, -5005, 3122 },
- { 3413, -1271, -5176, 3283 },
- { 3060, -68, -6495, 2238 },
- { 2700, -2075, -4681, 91 },
- { 2928, -1728, -5168, 1858 },
- { 4424, 828, -4471, 88 },
- { 2672, -2604, -4038, 2753 },
- { 5223, -123, -6749, 2295 },
- { 4237, -420, -5538, 1353 },
- { 4744, -1281, -4097, 4708 },
- { 1103, -2764, -4751, 2024 },
- { 3747, -1913, -3911, 3960 },
- { 2470, -1416, -5542, 615 },
- { 4847, -1354, -5334, 1733 },
- { 5336, 88, -7593, 4007 },
- { 2388, -2880, -4807, 1037 },
- { 4495, 1391, -5685, -139 },
- { 5253, 1637, -6450, 1533 },
- { 1199, 795, -5515, 1261 },
- { 1397, -1259, -4252, 3838 },
- { 746, 70, -6640, 604 },
- { 1584, 166, -4972, 3072 },
- { 380, -999, -5397, 2267 },
- { 2974, 1707, -3242, 5360 },
- { 5202, -403, -5453, 2832 },
- { 3718, -1731, -4760, 714 },
- { 4150, -975, -4792, 61 },
- { 2925, -818, -4841, 15 },
- { 5301, 577, -4006, 3259 },
- { 5265, 1986, -5679, 3028 },
- { 3752, 1928, -4509, 3729 },
- { 3278, 1925, -6370, 1247 },
- { 5107, 1721, -4853, 3127 },
- { 3279, 2982, -2515, 4005 },
- { 4622, 668, -6204, 759 },
- { 6034, 317, -5763, 4818 },
- { -558, 57, -3785, 2817 },
- { 4476, 1616, -3965, 4536 },
- { 5953, 2056, -8215, 2715 },
- { 4387, 2613, -7463, 868 },
- { 5834, 1088, -4736, 4924 },
- { 6473, -856, -6991, 4172 },
- { 4959, -293, -5162, 76 },
- { 2731, -843, -6119, 3847 },
- { 3245, 1202, -6833, 616 },
- { 2553, 1383, -3829, 3859 },
- { 4332, 2099, -3480, 3622 },
- { 2110, 2683, -2728, 3990 },
- { 876, 1167, -3290, 3466 },
- { 3991, 1709, -2410, 4077 },
- { 5105, 939, -2584, 3256 },
- { 4719, 688, -1566, 3040 },
- { -3632, 4335, 1266, -3303 },
- { -4956, 3207, 1312, -2806 },
- { -4669, 2627, 2663, -2435 },
- { -4282, 3708, 2303, -3038 },
- { -4536, 2297, -175, -3350 },
- { -5234, 2503, -139, -880 },
- { -3978, 1512, 1092, -3619 },
- { -4519, 4649, 1363, -2455 },
- { -5118, 3132, 1961, -1577 },
- { -5196, 3379, -182, -1378 },
- { -6420, 4486, 2397, -1993 },
- { -5030, 5046, 1292, -1118 },
- { -4559, 2573, -927, -1406 },
- { -3501, 3730, 691, -4930 },
- { -4364, 2758, 1007, -3909 },
- { -4026, 2839, -1559, -2340 },
- { -5037, 4053, 836, -1571 },
- { -4727, 5136, 1110, -3588 },
- { -5245, 2799, -999, -2164 },
- { -4954, 1501, 422, -3963 },
- { -5994, 2726, 1462, -2833 },
- { -5621, 5159, 2038, -2512 },
- { -4991, 2291, 1917, -3151 },
- { -5469, 4382, -148, -2978 },
- { -5858, 1983, 807, -2720 },
- { -4709, 3556, 952, -467 },
- { -2489, 2362, 1714, -4230 },
- { -4717, 5004, -1180, -3672 },
- { -5914, 3653, 1359, -1317 },
- { -5506, 2995, 780, -1059 },
- { -5287, 3945, 2480, -2293 },
- { -3849, 4358, 322, -1770 },
- { -3911, 3570, 252, -3185 },
- { -3660, 5128, 158, -3719 },
- { -4599, 3277, -503, -2727 },
- { -3673, 3760, -1252, -3339 },
- { -5161, 2337, 388, -1943 },
- { -3529, 2216, 2156, -3080 },
- { -4309, 4331, 1808, -1460 },
- { -4782, 3820, 480, -2504 },
- { -4166, 3544, -378, -1567 },
- { -5572, 2466, -418, -2909 },
- { -6096, 2930, 119, -1878 },
- { -5963, 3554, 1011, -2233 },
- { -6433, 4335, 935, -2930 },
- { -5004, 3314, -1352, -3430 },
- { -6042, 3463, -1008, -3940 },
- { -4671, 2214, -640, -5040 },
- { -2795, 3759, 1412, -3803 },
- { -3647, 4436, 729, -515 },
- { -3594, 1033, 56, -4148 },
- { -2908, 3027, 2889, -3485 },
- { -3338, 2234, 313, -4285 },
- { -3825, 4497, -561, -2634 },
- { -6167, 3012, -48, -3149 },
- { -4828, 3515, -969, -4475 },
- { -5789, 2757, -539, -4173 },
- { -2452, 3067, 564, -4249 },
- { -4921, 1358, 1331, -2889 },
- { -3127, 4239, -1045, -1523 },
- { -4780, 2326, -1118, -3446 },
- { -3908, 5546, 152, -2622 },
- { -6972, 2976, 337, -2809 },
- { -4839, 4613, -35, -4077 },
- { -1408, 4822, -1149, -4997 },
- { -981, 4979, -912, -6304 },
- { -2098, 5689, -888, -2878 },
- { -3343, 4814, -657, -4434 },
- { -2461, 3601, -967, -4869 },
- { -2652, 3944, 87, -5520 },
- { -1104, 6076, 174, -6407 },
- { 355, 5370, -1721, -5869 },
- { 1242, 4497, -1107, -5091 },
- { -89, 4002, -1491, -5182 },
- { 1059, 5693, -1591, -4905 },
- { 1323, 4682, -2078, -4768 },
- { 818, 3996, -549, -5468 },
- { -287, 4529, 929, -5543 },
- { -919, 5519, -2791, -2844 },
- { -1407, 5679, -3289, -3974 },
- { -189, 6530, -3547, -4002 },
- { -900, 7039, -3371, -4855 },
- { -2983, 7211, -363, -4835 },
- { -814, 6503, -104, -5106 },
- { -2386, 6896, 809, -4919 },
- { 845, 4492, 352, -6621 },
- { -1998, 7237, -1646, -4231 },
- { -3380, 6251, 471, -4577 },
- { -1908, 7059, 84, -5726 },
- { -340, 6346, -803, -6265 },
- { -2279, 5834, -47, -4633 },
- { -1532, 5286, -1748, -1901 },
- { -2757, 6188, -453, -3415 },
- { -1255, 6405, -2043, -6357 },
- { 918, 5581, -121, -5667 },
- { 1840, 5336, -821, -5034 },
- { -2475, 4992, -1825, -3104 },
- { -2413, 5606, -1789, -4298 },
- { 132, 5128, -2389, -4442 },
- { 223, 6400, -2653, -4742 },
- { -673, 5012, 680, -4582 },
- { -1657, 6624, -349, -3596 },
- { -755, 6289, -1860, -3978 },
- { -572, 6894, -1946, -5207 },
- { -1141, 4756, -2665, -5586 },
- { -1073, 4269, -431, -4030 },
- { 186, 5761, 916, -5868 },
- { -1907, 4836, 1017, -5106 },
- { -963, 3363, -1248, -6348 },
- { -3262, 4774, -1818, -5858 },
- { 847, 3812, -2538, -4302 },
- { -1223, 5903, 1360, -5479 },
- { -1094, 6923, -1244, -2381 },
- { 267, 6276, -709, -2846 },
- { -157, 5840, 1124, -4266 },
- { 889, 3206, -910, -5305 },
- { -1736, 3344, 582, -4838 },
- { -2357, 5676, -2695, -6277 },
- { -1916, 6901, -986, -5397 },
- { -3062, 6028, -695, -5687 },
- { 1836, 3566, -1357, -5226 },
- { -2176, 4938, 646, -3872 },
- { -2199, 3055, -208, -6124 },
- { -236, 3032, -821, -5325 },
- { -3989, 7277, -565, -3899 },
- { -595, 4362, 74, -5975 },
- { 684, 5874, -841, -4424 },
- { -2731, 6305, -2389, -5465 },
- { -5775, 1325, -56, -2528 },
- { -7029, -534, -1890, -3278 },
- { -5798, -15, -2734, -2210 },
- { -5504, -1198, -353, -3659 },
- { -5079, 960, -894, -4336 },
- { -6073, -36, -133, -3014 },
- { -5782, -259, -1025, -3986 },
- { -6843, 1262, -807, -1639 },
- { -5263, -918, -3290, -579 },
- { -4840, 461, -2158, -533 },
- { -6014, -50, -620, 504 },
- { -5843, 241, -1359, -282 },
- { -5898, 577, 769, -3271 },
- { -6833, -946, -466, -3347 },
- { -6026, 1459, -512, -729 },
- { -7361, 747, -388, -1110 },
- { -6391, 2142, -1160, -2513 },
- { -6995, 304, 498, -2673 },
- { -6757, 679, -386, -433 },
- { -5222, 1688, -1093, -1032 },
- { -5019, 575, 184, -3627 },
- { -4237, 628, -3507, -1243 },
- { -7479, -456, -1722, -1486 },
- { -6464, 713, -1273, -1153 },
- { -6255, 1682, -606, -3607 },
- { -7033, 1497, -71, -1955 },
- { -6694, 1556, -1721, -3214 },
- { -6114, -356, 813, -2575 },
- { -5308, 632, -1851, -1636 },
- { -5742, -911, -1733, 383 },
- { -6083, -387, -2313, -879 },
- { -6535, -530, -1505, -2083 },
- { -4896, 1223, -2750, -1816 },
- { -6392, -463, -3247, -2093 },
- { -5373, 1264, -2706, -3042 },
- { -3894, -1390, -1020, -891 },
- { -6179, 1168, -1966, -1922 },
- { -5162, 1668, -1617, -1916 },
- { -6453, 920, -1169, -2432 },
- { -6130, 2005, -536, -1519 },
- { -6552, -98, -518, -1938 },
- { -7528, 355, -1101, -1772 },
- { -5745, 610, -247, -1360 },
- { -7003, 177, -2064, -1958 },
- { -6956, -570, -2220, -4225 },
- { -7830, 791, -1394, -2774 },
- { -7634, 480, -3171, -4224 },
- { -7913, 1154, -350, -2381 },
- { -5063, 1704, -1804, -2977 },
- { -4887, -524, -2703, 188 },
- { -5551, 406, -1620, -3063 },
- { -7109, 1342, 381, -3021 },
- { -6846, 631, -458, -3398 },
- { -4606, -605, 11, -3930 },
- { -8134, -225, -1738, -2648 },
- { -7043, 402, -2734, -3059 },
- { -7417, 1825, -2545, -4389 },
- { -6971, -236, -1031, -665 },
- { -5752, 2111, -1632, -3808 },
- { -7660, -78, -624, -3135 },
- { -6358, 619, -1951, -3911 },
- { -8134, 408, -1935, -3695 },
- { -6335, 1911, -2368, -4505 },
- { -7116, 2163, -344, -2753 },
- { 2357, 4488, 2220, -5682 },
- { 1385, 3206, 2300, -5305 },
- { 1419, 2557, 5203, -3516 },
- { 262, 4315, 3920, -1847 },
- { 3316, 3187, 1612, -5609 },
- { 1729, 2350, 1673, -6068 },
- { 1603, 6126, 1467, -2839 },
- { -1339, 3316, 3691, -3530 },
- { -563, 4618, 3180, -4548 },
- { 463, 4624, 3111, -5614 },
- { 1246, 5455, 3356, -5720 },
- { 480, 2149, 5422, -2893 },
- { 1768, 4827, 913, -5579 },
- { -149, 5381, 4366, -3297 },
- { 985, 3672, 2644, -92 },
- { -258, 2911, 5817, -2213 },
- { 3428, 3289, 3351, -3541 },
- { -666, 3295, 4727, -2869 },
- { 35, 6641, 4160, -4052 },
- { 623, 6787, 3156, -4560 },
- { 2654, 4360, 4676, -4632 },
- { 1386, 5246, 4834, -4497 },
- { 3488, 4574, 3856, -5946 },
- { 383, 4481, 4168, -4110 },
- { 1753, 3652, 4288, -3326 },
- { 1344, 4905, 2508, -4660 },
- { 1580, 4106, 3104, -2224 },
- { 2027, 5038, 1683, -1554 },
- { 446, 3699, 5872, -3013 },
- { 4637, 4087, 3578, -5018 },
- { 2629, 3560, 5331, -4900 },
- { 1527, 6674, 2523, -4131 },
- { -1437, 2804, 2528, -4464 },
- { -229, 3355, 2016, -5537 },
- { 3666, 3418, 4374, -4581 },
- { 1192, 3799, 923, -6596 },
- { 2040, 2956, 448, -5322 },
- { 2468, 5768, 4029, -5869 },
- { 3438, 6516, 3529, -6667 },
- { 2737, 5495, 680, -5535 },
- { 3896, 5727, 1801, -4958 },
- { 4988, 4957, 3592, -6518 },
- { -542, 4416, 5794, -2787 },
- { 4136, 4354, 2064, -4696 },
- { 3067, 5936, 1207, -3396 },
- { 2789, 4966, 2405, -3854 },
- { 1731, 3270, 3251, -1063 },
- { 1767, 5537, 2084, -2349 },
- { 465, 3116, 4532, -837 },
- { 1499, 2627, 4610, -2212 },
- { 122, 3095, 3642, -3552 },
- { 2542, 2866, 2705, -6402 },
- { 3134, 4323, 698, -4785 },
- { 731, 1859, 3112, -5242 },
- { 2553, 2980, 3241, -4846 },
- { 1329, 5310, 1607, -6624 },
- { 2468, 1858, 3476, -1034 },
- { -172, 4996, 2000, -5562 },
- { 2621, 4220, 1574, -3386 },
- { -333, 1832, 3362, -4117 },
- { 2169, 6762, 3065, -6225 },
- { 2844, 5528, 3223, -4765 },
- { 526, 5175, 1644, -4267 },
- { 2922, 4426, 2414, -2610 },
- { 452, 1399, -4516, -2636 },
- { 2872, 1720, -4667, -1435 },
- { 1279, 702, -5424, -1984 },
- { 2187, 870, -5021, -1341 },
- { 583, -144, -4628, -2464 },
- { 3, 2237, -5284, -2827 },
- { -19, 1005, -5460, -1819 },
- { 2897, 2084, -5885, -515 },
- { -400, 3370, -5527, -2947 },
- { 1505, 2593, -5518, -1802 },
- { 1341, 4534, -5094, -1899 },
- { 3241, 3670, -5493, -1252 },
- { -1287, 921, -5994, -1675 },
- { 627, 408, -6652, -364 },
- { -260, 1127, -4849, -3247 },
- { 371, 3400, -5976, -2285 },
- { 1533, 1566, -6373, -610 },
- { 2462, 4274, -6184, -1254 },
- { 1782, 3363, -6222, -1381 },
- { 572, 4650, -5673, -2754 },
- { 2674, 3414, -4460, -2154 },
- { 3614, 3820, -6883, -398 },
- { 1136, -1, -5511, -1112 },
- { -1773, 1137, -5647, -2377 },
- { -753, 2104, -6085, -2565 },
- { -204, 3025, -4731, -1418 },
- { -1486, 1438, -4380, -216 },
- { 302, 858, -5786, -264 },
- { 3486, 1495, -5234, -783 },
- { 888, 2327, -3423, -3720 },
- { -259, 772, -6596, -1311 },
- { -1197, 2073, -5174, -1826 },
- { 1500, 3470, -4462, -2645 },
- { 3072, 1960, -3277, -2264 },
- { 1841, 952, -4324, -2340 },
- { 1994, 2200, -3940, -2923 },
- { -1782, 1699, -4667, -1075 },
- { -1464, 2906, -3468, -375 },
- { 366, 2380, -3747, 1467 },
- { -545, 1645, -4619, 376 },
- { 1724, 2350, -2374, -3512 },
- { 3184, 2628, -2996, -3275 },
- { 734, 2010, -6239, -1479 },
- { 524, 3756, -4496, -3263 },
- { 1492, 3570, -3494, -3600 },
- { -932, 618, -5389, -2894 },
- { -133, 2161, -4083, -3267 },
- { 786, 774, -3279, -3731 },
- { 1078, 803, -3843, -3007 },
- { -332, 3405, -3347, 40 },
- { -17, 6, -4005, -3690 },
- { -189, 4372, -4488, -2561 },
- { -450, 3846, -3790, -1370 },
- { 362, 2212, -5272, -15 },
- { -1529, 791, -6802, -2296 },
- { 2145, 4241, -4474, 376 },
- { 1813, 2426, -2932, -2726 },
- { -542, 4557, -3140, -1080 },
- { 1192, 3784, -4371, -20 },
- { 2784, 5188, -6399, -1394 },
- { 431, 4561, -3673, -1398 },
- { 1382, 3096, -4083, 1253 },
- { 1209, 4224, -2930, 1500 },
- { 2798, 2684, -6676, -606 },
- { -2396, 1510, -5381, -2713 },
- { -2625, 2542, -4032, -2880 },
- { -1231, 3967, -4098, -2886 },
- { -1393, 2374, -3862, -4525 },
- { -2495, 1665, -1637, -5445 },
- { -3854, 1759, -1750, -4944 },
- { -2373, 1668, -2856, -6251 },
- { -2668, 1981, -886, -4557 },
- { -2927, 4427, -3451, -6172 },
- { -1925, 2596, -4696, -2527 },
- { -3202, 2847, -3928, -5896 },
- { -3332, 1665, -5025, -3412 },
- { -3212, 3115, -4155, -4062 },
- { -1013, 3205, -5133, -3751 },
- { -2022, 4595, -3947, -5611 },
- { -3556, 1755, -3715, -2300 },
- { -1784, 4114, -2723, -1773 },
- { -3586, 4081, -2733, -4942 },
- { -1608, 3685, -4154, -4573 },
- { -3368, 4042, -4452, -6227 },
- { -1407, 3881, -5729, -3719 },
- { -2751, 3281, -5077, -4999 },
- { -3791, 2410, -4906, -5288 },
- { -730, 2303, -4217, -3755 },
- { -1812, 2311, -5492, -3709 },
- { -610, 4336, -3915, -3783 },
- { -2841, 4337, -4278, -4430 },
- { -1662, 4666, -4661, -3964 },
- { -589, 5209, -4923, -3682 },
- { -4155, 2234, -4076, -4218 },
- { -3951, 2770, -2665, -2805 },
- { -2302, 3228, -3717, -1908 },
- { -3129, 4373, -2264, -2851 },
- { -447, 1363, -3578, -4323 },
- { -2648, 4237, -3159, -3071 },
- { -4072, 3241, -3541, -4605 },
- { -4507, 3458, -2339, -3838 },
- { -1646, 997, -4926, -3970 },
- { -3025, 1614, -3940, -1242 },
- { -1337, 1756, -3163, -5529 },
- { -3203, 1865, -3282, -4354 },
- { -1646, 2118, -2203, -6018 },
- { 174, 1871, -2707, -4639 },
- { -2607, 1485, -4778, -4750 },
- { -2199, 3991, -3134, -4879 },
- { -2962, 3323, -2816, -2419 },
- { -5286, 2495, -4548, -5395 },
- { -2810, 3710, -2274, -4211 },
- { -330, 3006, -2993, -4678 },
- { -1187, 2411, -2743, -5196 },
- { -664, 4033, -3101, -5641 },
- { -1458, 3602, -2816, -5371 },
- { -4116, 4923, -3321, -5630 },
- { -4165, 2528, -2592, -4798 },
- { -2759, 3080, -2333, -5719 },
- { -5157, 3011, -5526, -6348 },
- { -3095, 2126, -5881, -4234 },
- { -4377, 3849, -3600, -6099 },
- { -1994, 4947, -5235, -4753 },
- { -1067, 600, -3258, -5133 },
- { -4992, 3302, -2208, -5051 },
- { -3377, 2981, -1655, -4815 },
- { -3325, 2446, -1787, -6116 },
- { -2341, 2737, -3240, -6347 },
- { -2258, -3732, 3710, -1235 },
- { -1558, -3849, 2694, -3012 },
- { -599, -4837, 3050, -2951 },
- { -2246, -5433, 2798, -1910 },
- { -2255, -4989, 3260, 270 },
- { -3026, -5353, 2693, -1036 },
- { -1151, -6097, 1097, -3782 },
- { -3391, -6012, 2130, -1303 },
- { -2850, -4422, 3375, -480 },
- { -1138, -3779, 1491, -4162 },
- { -551, -3892, 3787, -2082 },
- { -3221, -3676, 3144, -1202 },
- { -3023, -5196, 2650, 605 },
- { -1756, -5729, 2646, 321 },
- { -2693, -4409, 494, -4797 },
- { -1913, -4573, 3372, -1730 },
- { -1277, -3604, 4061, -993 },
- { -420, -4993, 1351, -4796 },
- { -3052, -5333, 1435, -1242 },
- { -602, -5034, 3869, -1141 },
- { -2436, -4680, 1665, -3019 },
- { -2657, -3658, 1459, -3391 },
- { -1220, -6246, 2749, -525 },
- { -3838, -4844, 2265, -1735 },
- { -1247, -5679, 3356, -1417 },
- { -917, -5448, 3342, 105 },
- { -1756, -6839, 2276, -2350 },
- { -412, -5206, 1764, -3539 },
- { -1439, -6915, 1442, -3750 },
- { -1381, -4439, 3863, -282 },
- { -3482, -4953, 2726, -336 },
- { -1376, -5931, 1714, -1987 },
- { -1716, -4405, 2608, 105 },
- { -1590, -5191, 2652, -2704 },
- { -2149, -6442, 2453, -1263 },
- { -3426, -3832, 2334, -1829 },
- { -2747, -5948, 2362, -173 },
- { -2435, -3267, 2966, -1710 },
- { -3979, -4282, 2705, -775 },
- { -356, -4238, 2544, -4343 },
- { -1363, -6471, 2817, -1836 },
- { -2878, -5117, 218, -3149 },
- { -3539, -5196, 1710, -2356 },
- { -2888, -4537, 2746, -1701 },
- { -1870, -4439, 1496, -4121 },
- { -1486, -3388, 3349, -2145 },
- { -3333, -4138, 1467, -2876 },
- { -345, -5340, 1012, -1190 },
- { -1672, -4992, 2289, -1029 },
- { -2146, -5528, 3038, -635 },
- { -316, -3656, 3426, -3152 },
- { -2695, -5812, 2336, -2050 },
- { -2067, -6052, 737, -3258 },
- { -2664, -4205, -350, -1266 },
- { -617, -5406, 80, -4853 },
- { -2418, -3825, 1853, -1326 },
- { -1961, -4339, 583, -4315 },
- { -1495, -5141, -133, -5205 },
- { -3208, -6440, 1691, -2069 },
- { -2632, -3633, 2325, -2761 },
- { -2624, -5670, 1252, -3676 },
- { -3687, -5608, 687, -2833 },
- { -3320, -5707, 16, -3877 },
- { -2738, -6112, 84, -5135 },
- { 2277, -5661, 3076, 843 },
- { 1555, -5769, 2821, -5236 },
- { 536, -6381, 603, -4910 },
- { 734, -4609, 3314, -4092 },
- { 1836, -4547, 3267, -4322 },
- { -13, -5976, 3752, -1607 },
- { 1423, -6318, 2336, 398 },
- { 365, -7779, 1498, -534 },
- { 2104, -8366, 2946, -1345 },
- { 143, -5545, 1898, -3756 },
- { 655, -6852, 1430, 148 },
- { 4, -6653, 2397, -59 },
- { 2346, -5996, 4562, -934 },
- { 1229, -7104, 2963, -598 },
- { -528, -7048, 2887, -1790 },
- { 1451, -6857, 3900, -1637 },
- { 554, -6018, 3336, 9 },
- { 3278, -5758, 4034, 129 },
- { 3541, -7145, 4905, -1575 },
- { 2339, -6907, 3464, -301 },
- { 2775, -7301, 1667, -3894 },
- { 539, -7887, 991, -4156 },
- { 2115, -7421, 3131, -3075 },
- { 2803, -8546, 2564, -5836 },
- { 2869, -5833, 1620, -4561 },
- { 2591, -7281, 3215, -4719 },
- { -1228, -8477, 706, -4782 },
- { 1967, -5243, 4813, -1940 },
- { 701, -7010, 2273, -3893 },
- { 915, -8470, 1918, -5620 },
- { -94, -6715, 156, -3873 },
- { 1074, -5607, 4389, -1017 },
- { 2739, -6551, 1227, -3521 },
- { 725, -7835, 2701, -1291 },
- { -493, -7475, 2263, -1075 },
- { -412, -6508, 2984, -744 },
- { 665, -5451, 3725, -2692 },
- { 1499, -8129, 3564, -2072 },
- { 2870, -6333, 4487, -2108 },
- { 706, -5007, 3911, -152 },
- { -482, -8660, 1483, -2900 },
- { 2481, -6596, 2518, -1715 },
- { 1403, -6414, 1398, -5387 },
- { 652, -6267, 583, -5942 },
- { 694, -7540, 646, -6272 },
- { 2275, -7614, 256, -5015 },
- { 1416, -9727, 1900, -3153 },
- { 2760, -6433, 3875, -3771 },
- { 2325, -11196, 2182, -5155 },
- { 1223, -11061, 1377, -5097 },
- { 108, -10603, 307, -4952 },
- { -118, -8268, 1650, -1572 },
- { 1839, -7943, 1755, -612 },
- { 2501, -9056, 981, -2969 },
- { 2902, -8476, 1491, -5780 },
- { 1995, -11175, 1585, -3643 },
- { 696, -8212, 828, -2474 },
- { 1526, -8649, 1380, -1210 },
- { 461, -7253, 3222, -2229 },
- { 2966, -8641, 4121, -3271 },
- { 833, -6039, 2361, -1086 },
- { 3565, -7312, 1980, -5427 },
- { 2850, -8671, 3760, -1846 },
- { 2643, -7281, 2163, -173 },
- { 3463, -3706, -3132, -923 },
- { 1315, -3825, -3443, 2 },
- { 2594, -4083, -3815, 670 },
- { 1826, -4291, -2741, -155 },
- { 868, -3749, -4175, -298 },
- { 2008, -4237, -3897, -517 },
- { 1242, -3493, -4335, -1335 },
- { -88, -4142, -3390, -1529 },
- { 2176, -3488, -3822, -975 },
- { 1706, -5188, -3415, -637 },
- { 2717, -6159, -2333, -882 },
- { 1276, -3978, -4361, 537 },
- { 2471, -5556, -2866, -208 },
- { 799, -4673, -4086, 56 },
- { 1901, -4786, -3533, 270 },
- { 3036, -3902, -3606, -333 },
- { 2249, -3317, -4319, -144 },
- { 2594, -4207, -2105, -2930 },
- { 4008, -4774, -2626, -902 },
- { 1038, -3659, -3496, -2454 },
- { 2725, -3597, -3298, -1535 },
- { 1662, -5803, -2813, 175 },
- { 705, -3757, -3441, -1484 },
- { 1860, -5987, -2821, -886 },
- { 3786, -4918, -2199, -1929 },
- { 3683, -4235, -2547, -1287 },
- { 2531, -4896, -2956, -1593 },
- { 1005, -5585, -3324, -180 },
- { 1625, -5229, -1756, -3642 },
- { 1494, -5041, -2989, -2685 },
- { 2718, -4655, -3224, -867 },
- { 2374, -6640, -1745, -2975 },
- { 2133, -6436, -2477, -1499 },
- { 1833, -4418, -3523, -1512 },
- { 1128, -4910, -2658, -1106 },
- { 689, -4777, -2831, -2085 },
- { 3593, -5280, -2627, -315 },
- { 3264, -3771, -2673, -1861 },
- { 3202, -5602, -2409, 402 },
- { 552, -4618, -2221, -3002 },
- { 3095, -5356, -2666, -1083 },
- { 3401, -4609, -3146, 45 },
- { 3051, -4662, -2192, -2232 },
- { 2798, -5552, -2462, -1941 },
- { 2354, -5815, -2223, -2619 },
- { 192, -3708, -2807, -2658 },
- { 1886, -4226, -1862, -3529 },
- { 2526, -3976, -2819, -2332 },
- { 1577, -3870, -2711, -2806 },
- { 1288, -5588, -3382, -1403 },
- { 2711, -5399, -1564, -3253 },
- { 1459, -5492, -2222, -322 },
- { 2823, -5091, -2886, 776 },
- { 3559, -5821, -2109, -1360 },
- { 1587, -6331, -2760, -1909 },
- { 2139, -5213, -2874, -2120 },
- { 1318, -4337, -3695, -2098 },
- { 821, -4471, -1849, -565 },
- { 3329, -4782, -1725, -89 },
- { 582, -4914, -4105, -1119 },
- { 417, -4144, -4072, -2529 },
- { -199, -3803, -2765, -4042 },
- { 2731, -4283, -2143, 1 },
- { 2911, -6187, -1951, -2116 },
- { 1573, -6094, -493, -2838 },
- { 2081, -6927, -864, -3211 },
- { 1058, -7826, 79, -364 },
- { 3147, -5570, -684, -978 },
- { 3572, -5856, 1060, 1824 },
- { 1143, -6702, -1478, 338 },
- { 2341, -7220, -88, 260 },
- { 3639, -6861, 668, 815 },
- { 2227, -6268, -1706, 446 },
- { 3390, -6082, -353, 1302 },
- { 1123, -7556, -1237, -430 },
- { 1729, -7742, 729, -218 },
- { 1457, -6774, 587, 579 },
- { 505, -6919, -569, 371 },
- { 1106, -7245, 78, 158 },
- { 2755, -6745, -1122, 338 },
- { 3069, -6040, -1415, 986 },
- { 2174, -7064, -1430, -283 },
- { 1390, -8626, -446, -3031 },
- { 3534, -6890, -431, 547 },
- { 2267, -9618, 475, -2994 },
- { 3672, -7673, 75, -115 },
- { 2131, -7560, -1206, -750 },
- { 2972, -7477, -685, -262 },
- { 1604, -6637, -672, 699 },
- { 1666, -7577, -577, -240 },
- { 1591, -6554, -2158, -94 },
- { 2348, -6286, -353, 1123 },
- { 2017, -8810, -412, -1805 },
- { 2892, -6713, -1765, -554 },
- { 2500, -6828, -1995, -1197 },
- { 3877, -6639, -224, -1655 },
- { 2392, -7872, -91, -333 },
- { 3562, -7370, -532, -2836 },
- { 2552, -7614, 164, -1805 },
- { 990, -6104, 218, 438 },
- { 910, -7861, 312, -1195 },
- { 1472, -6327, 372, -640 },
- { 1576, -7143, -1983, -843 },
- { 422, -7625, -457, -278 },
- { 1797, -8532, 405, -1011 },
- { 1088, -7396, -238, -2277 },
- { 3209, -6753, -1431, -2072 },
- { 2617, -6839, 100, -2573 },
- { 2575, -8573, -387, -3188 },
- { 3618, -6971, -1190, -321 },
- { 2205, -7361, -1695, -2008 },
- { 2985, -6297, 1464, 1179 },
- { 2804, -7310, 1053, 338 },
- { 1362, -6074, -1163, -840 },
- { 3336, -6325, -1794, 21 },
- { 2836, -8109, 818, -329 },
- { 2791, -5879, 560, 1546 },
- { 2392, -6064, 135, 100 },
- { 1838, -6194, 596, 1085 },
- { 1926, -7515, -414, -4901 },
- { 3225, -7298, -1202, -1189 },
- { 3960, -7558, -659, -719 },
- { 3442, -6647, -1692, -1095 },
- { 3381, -6441, 262, -886 },
- { 1431, -8150, -1186, -1406 },
- { 340, -8498, -150, -899 },
- { 3004, -8149, -260, -953 },
- { 2749, -6611, 563, 873 },
- { -6647, -1325, -4517, -4691 },
- { -6005, -1657, -4089, -3797 },
- { -3157, 588, -5213, -3068 },
- { -3311, -1425, -6329, -3726 },
- { -5866, -819, -3857, -2744 },
- { -5001, -1799, -1075, -4621 },
- { -5330, -2650, -2672, -4664 },
- { -4930, -539, -2363, -4010 },
- { -2984, 10, -3863, -5749 },
- { -1055, -2106, -3713, -4267 },
- { -5476, -502, -4279, -6504 },
- { -5231, -1543, -5018, -6425 },
- { -5134, -363, -3165, -5109 },
- { -3953, -771, -4107, -6393 },
- { -2159, -563, -3652, -5342 },
- { -3888, -2321, -919, -5057 },
- { -1236, -597, -4235, -4193 },
- { -4053, 675, -3083, -6174 },
- { -2793, -1089, -5396, -3460 },
- { -3000, -44, -2209, -6575 },
- { -3336, -1531, -4313, -5160 },
- { -2127, 128, -4851, -3692 },
- { -3321, 136, -2067, -5660 },
- { -5215, 1404, -4374, -4356 },
- { -2747, 400, -6340, -3691 },
- { -3926, -599, -5361, -5006 },
- { -2875, -2592, -5143, -4092 },
- { -4991, -1958, -5322, -4891 },
- { -4965, -1318, -6652, -5333 },
- { -4920, -1691, -3388, -5561 },
- { -3644, -3354, -2688, -5982 },
- { -5076, -919, -4563, -2984 },
- { -6114, 250, -3884, -3915 },
- { -4014, 744, -3973, -1924 },
- { -5543, -1041, -5557, -3847 },
- { -4711, -1352, -5649, -2603 },
- { -3362, 775, -5305, -4879 },
- { -5001, 107, -3554, -2888 },
- { -6258, -1651, -6356, -6566 },
- { -4529, 407, -5003, -3865 },
- { -5154, 550, -5278, -5465 },
- { -4195, -467, -1894, -3129 },
- { -5022, 1127, -3349, -3314 },
- { -6075, 1250, -4313, -5641 },
- { -2677, -2283, -2312, -5903 },
- { -4113, 193, -1195, -4833 },
- { -3940, -1048, -1389, -5079 },
- { -3703, 917, -4043, -4451 },
- { -3366, -4231, -1534, -5488 },
- { -3326, -3583, -2091, -4903 },
- { -5144, 1254, -2532, -4949 },
- { -5982, -870, -2545, -4555 },
- { -3925, -157, -5367, -2281 },
- { -6419, -746, -5668, -4371 },
- { -5787, 518, -7096, -5805 },
- { -4258, 954, -6453, -4321 },
- { -4771, -695, -4158, -1639 },
- { -7078, -760, -5195, -5877 },
- { -7348, 83, -4101, -4586 },
- { -2430, 184, -2874, -1679 },
- { -2284, -3943, -2924, -5034 },
- { -1804, -1785, -3002, -4710 },
- { -4399, -2772, -1815, -4637 },
- { -6340, -2626, -2824, -5191 },
- { -4998, -5168, -3480, 1905 },
- { -3958, -5492, -1599, 1579 },
- { -2471, -3755, -276, 3182 },
- { -3033, -5779, -1063, 1554 },
- { -2936, -4829, -1290, 2386 },
- { -1835, -5073, -3051, 1299 },
- { -1724, -3771, -3935, 2324 },
- { -5070, -2550, -3692, 768 },
- { -4326, -5333, -297, 1878 },
- { -3472, -5619, -3094, 992 },
- { -3027, -4384, -3038, 2265 },
- { -3201, -5332, 67, 2200 },
- { -1681, -4373, -1947, 2461 },
- { -3221, -3329, -4238, 2564 },
- { -1262, -2968, -2915, 3227 },
- { -3419, -1878, -3373, 2110 },
- { -2244, -5583, -2012, 1288 },
- { -1971, -5266, -990, 1812 },
- { -2975, -2778, -452, 4063 },
- { -2198, -1165, -3298, 2965 },
- { -4782, -4894, -4767, 664 },
- { -6002, -3950, -2806, 2025 },
- { -3142, -3162, -2859, 3295 },
- { -3262, -3340, -4123, 1596 },
- { -4014, -3918, -1955, 3361 },
- { -1700, -3463, -1346, 3449 },
- { -4245, -4445, -4743, 1644 },
- { -4180, -3969, -401, 3281 },
- { -2782, -5240, -4117, 1156 },
- { -5744, -4040, -1439, 3470 },
- { -5063, -4663, -323, 3172 },
- { -4531, -3319, -844, 3988 },
- { -6226, -5125, -2064, 2976 },
- { -3115, -3267, -1531, 3898 },
- { -4628, -4421, -2864, 2808 },
- { -4559, -2989, -3442, 2024 },
- { -1775, -4487, -656, 2477 },
- { -2664, -1865, -1884, 4081 },
- { -1828, -2575, -3894, 3378 },
- { -6441, -3677, -2025, 1677 },
- { -4141, -2156, -1191, 3474 },
- { -4802, -1623, -1727, 2160 },
- { -5474, -2745, -1475, 2498 },
- { -3664, -1056, -1975, 2491 },
- { -4672, -3062, -2235, 2933 },
- { -4205, -5960, -2849, 1517 },
- { -4995, -5708, -1739, 1805 },
- { -4892, -6080, -4793, 872 },
- { -4270, -4172, -4263, 2185 },
- { -4687, -1470, -2905, 1023 },
- { -6446, -5017, -3919, 1000 },
- { -6046, -5538, -3943, 2006 },
- { -6028, -3750, -3953, 771 },
- { -5959, -4582, -5024, 824 },
- { -5818, -2576, -2249, 1326 },
- { -5659, -5345, -1119, 2500 },
- { -3346, -4155, 606, 2749 },
- { -5680, -4827, -2501, 1838 },
- { -6193, -2543, -1295, 840 },
- { -6871, -4925, -3512, 1801 },
- { -5605, -1788, -1895, 779 },
- { -3922, -5712, -4644, 510 },
- { -4745, -3869, -4533, 99 },
- { -2984, -4907, -399, 1497 },
- { 1847, -478, 3061, -5812 },
- { 4450, -1116, 3609, -6570 },
- { 3139, 99, 3007, -5532 },
- { 2590, -3782, 3138, -4770 },
- { 1881, 1204, 5778, -3404 },
- { 3631, 2060, 5566, -5038 },
- { 3461, 1961, 5167, -3800 },
- { 2947, 273, 4536, -4389 },
- { 4453, -1730, 5788, -4370 },
- { 4032, 1805, 2666, -4534 },
- { 3487, -944, 2313, -6028 },
- { 1313, 34, 4210, -4067 },
- { 5632, -1502, 5825, -5855 },
- { 7736, -547, 4879, -5476 },
- { 4906, -1512, 4760, -5760 },
- { 3843, 447, 1091, -4958 },
- { 2982, -1135, 5442, -4386 },
- { 3579, 271, 3031, -6770 },
- { 3932, -211, 4688, -5507 },
- { 4411, 1720, 2387, -5584 },
- { 5379, -479, 4575, -6280 },
- { 3613, -362, 2012, -4885 },
- { 3744, -2013, 4493, -5073 },
- { 5693, 109, 4379, -3362 },
- { 5475, -621, 5317, -3985 },
- { 6411, -673, 5708, -4752 },
- { 4933, -796, 7262, -4290 },
- { 2804, 444, 6276, -3655 },
- { 4120, -517, 6078, -4531 },
- { 5119, 841, 3486, -3910 },
- { 4738, 1539, 3525, -2970 },
- { 5086, 370, 5895, -5640 },
- { 4235, 2716, 4589, -5044 },
- { 3691, 682, 6199, -4700 },
- { 6111, -570, 6271, -6528 },
- { 2611, 1277, 3756, -4802 },
- { 4395, 970, 3807, -5879 },
- { 5225, 2299, 3242, -4333 },
- { 5144, 1778, 4946, -5545 },
- { 2989, -3016, 3247, -5495 },
- { 2983, 920, 2071, -6059 },
- { 5270, -903, 4434, -2350 },
- { 6415, -585, 3970, -3554 },
- { 3866, -197, 5216, -2884 },
- { 3767, -1298, 6702, -3315 },
- { 6299, 2620, 5284, -6824 },
- { 6654, 646, 3653, -4927 },
- { 4770, 3047, 5160, -6287 },
- { 5364, 434, 2919, -5207 },
- { 2998, 1344, 4801, -2456 },
- { 3896, 1013, 3773, -1864 },
- { 2115, 655, 2999, -6344 },
- { 5170, -981, 2849, -4464 },
- { 2735, -2159, 2717, -5776 },
- { 2430, -1952, 4392, -4559 },
- { 6143, -1180, 3659, -4746 },
- { 4978, -1483, 1726, -4875 },
- { 3486, -2383, 3306, -4301 },
- { 1434, -1372, 4171, -4770 },
- { 3354, -2627, 1525, -5093 },
- { 6790, 2386, 3995, -5909 },
- { 1475, -2674, 3451, -4204 },
- { 1999, -3494, 3693, -5556 },
- { 4764, -2848, 2856, -5589 },
- { -3677, 5131, 2827, -2934 },
- { -2844, 7078, 2852, -3580 },
- { -3902, 6434, 4118, -1911 },
- { -1769, 7530, 3492, -3541 },
- { -1937, 5679, -447, -1127 },
- { -2456, 4680, 4196, -2407 },
- { -2778, 8241, 1698, -4288 },
- { -2876, 6104, 5182, -2387 },
- { -2802, 7341, 4463, -2938 },
- { -1025, 6267, 4752, -3201 },
- { -2349, 5413, 2041, -3794 },
- { -2252, 8225, 2856, -4269 },
- { -1465, 4967, 4976, -2500 },
- { -636, 7565, 3517, -4233 },
- { -1905, 5618, 3904, -2942 },
- { -302, 6816, 3343, -3316 },
- { -2210, 4156, 2817, -3511 },
- { -717, 6568, 1863, -2951 },
- { -3873, 5682, 2164, -575 },
- { -2878, 5835, 440, -2597 },
- { -3228, 7701, 2610, -2514 },
- { -3608, 8888, 3377, -2468 },
- { -2582, 9717, 2519, -3126 },
- { -5238, 6202, 2866, -2831 },
- { -3428, 7370, 3056, -335 },
- { -1681, 8836, 1210, -2010 },
- { -3276, 6724, 1156, -3930 },
- { -894, 8149, 827, -1258 },
- { -2965, 8631, 2549, -1320 },
- { -3961, 6902, 3581, 55 },
- { -1894, 7745, 1750, -841 },
- { -821, 6844, 850, -676 },
- { -608, 6948, -4, -1376 },
- { 615, 6524, 1089, -1147 },
- { -2972, 5668, 1091, -489 },
- { -157, 4649, 2904, -413 },
- { 673, 5121, 1498, -66 },
- { -390, 5902, 1611, -245 },
- { -2349, 5478, 4772, -1320 },
- { 88, 6798, 1972, -1859 },
- { -1213, 5120, 2991, 200 },
- { -2347, 6040, 2839, 376 },
- { -578, 5976, 3364, -1796 },
- { -1391, 5872, 3002, -965 },
- { -564, 4496, 3946, -1186 },
- { -2299, 6386, 3135, -2176 },
- { -2131, 5641, 2011, 1223 },
- { -772, 5807, 1124, 895 },
- { -2837, 6758, 2297, -740 },
- { -3091, 6298, 1415, -2126 },
- { -4197, 6036, 1843, -3022 },
- { -41, 6459, 92, 344 },
- { -2241, 6860, 2095, -4396 },
- { -1931, 7088, 2117, -2135 },
- { -2375, 4422, 1688, -3169 },
- { -1742, 6674, 1538, -119 },
- { -4818, 7749, 4192, -1577 },
- { -2004, 5672, 193, -430 },
- { -3825, 6042, 2128, -1898 },
- { -1108, 8033, 2119, -3013 },
- { -2370, 5453, 1721, 266 },
- { -1570, 7134, 614, -2638 },
- { -1519, 8752, 3503, -4330 },
- { -2050, 3845, 2907, -1126 },
- { 5085, 4412, -335, -1923 },
- { 3618, 1423, -613, -4012 },
- { 4481, 3729, 589, -4631 },
- { 4270, 3216, -1763, -3168 },
- { 4241, 1796, -1701, -2796 },
- { 4787, 2338, -487, -3639 },
- { 2915, 3429, -621, -4753 },
- { 5175, 1660, -1265, -3223 },
- { 4280, 4057, -684, -4079 },
- { 4980, 4419, -1455, -2719 },
- { 5436, 2464, 387, -4197 },
- { 4507, 4018, 1121, -3314 },
- { 6020, 2401, -413, -3201 },
- { 4200, 3789, -333, -2813 },
- { 5229, 2493, -1194, -1878 },
- { 5851, 2695, -492, -2292 },
- { 5743, 3288, -697, -1221 },
- { 5692, 2612, 979, -2227 },
- { 5085, 2067, 1046, -1214 },
- { 3163, 2240, -2098, -3435 },
- { 5228, 1898, 145, -2397 },
- { 5860, 3976, -418, -2872 },
- { 6008, 3399, 1027, -3506 },
- { 4126, 2035, 1865, -893 },
- { 5375, 3596, 511, -2362 },
- { 1937, 1493, -852, -122 },
- { 3473, 4849, 547, -2603 },
- { 4631, 2977, 1141, -1768 },
- { 6149, 3050, -71, -1886 },
- { 4069, 4353, -289, -1429 },
- { 2884, 1225, -1388, 365 },
- { 5485, 2518, -235, -571 },
- { 1216, 4375, 1443, 398 },
- { 4988, 3106, 107, -1435 },
- { 4511, 2801, 307, -444 },
- { 3235, 4386, 327, -676 },
- { 2055, 3708, 1657, -305 },
- { 5839, 2374, 290, -1385 },
- { 5110, 3305, 1936, -4206 },
- { 6416, 2920, 338, -2736 },
- { 3350, 2824, -1269, -3881 },
- { 4840, 1815, 464, 186 },
- { 2399, 3332, 238, 1238 },
- { 3516, 1363, 1582, 688 },
- { 3582, 1874, 154, -4770 },
- { 3261, 2878, 886, 283 },
- { 3877, 2658, -327, 884 },
- { 4151, 3436, 2173, -2923 },
- { 3592, 3674, 1281, -1295 },
- { 4561, 3730, -1114, -1747 },
- { 4595, 3625, -558, -575 },
- { 2577, 2348, 2267, 120 },
- { 5242, 3299, 32, -3412 },
- { 4264, 3637, 709, -2320 },
- { 6556, 3570, -838, -2472 },
- { 5745, 4014, -940, -1973 },
- { 5629, 4475, 477, -3328 },
- { 5269, 3199, 1682, -3085 },
- { 4432, 2416, 1145, -3299 },
- { 4465, 2505, 2162, -2186 },
- { 4643, 4941, -88, -2885 },
- { 4568, 5231, 552, -3915 },
- { 5667, 3075, -1406, -2963 },
- { 5418, 5259, -771, -2818 },
- { -256, -7875, 511, -471 },
- { -1813, -7971, -424, -396 },
- { -306, -7006, 862, 282 },
- { -2306, -6422, -1440, 508 },
- { -245, -6787, 375, -100 },
- { -1309, -6065, -20, 779 },
- { -1656, -6047, -641, 1307 },
- { -1496, -6522, 964, 726 },
- { -2291, -6588, -202, 795 },
- { -762, -7522, 1454, -558 },
- { -2270, -7004, -834, -580 },
- { -1139, -7078, 259, 362 },
- { -2535, -7568, -1040, 49 },
- { -3786, -7280, 934, -476 },
- { -3336, -6368, 606, 1056 },
- { -3602, -6924, 52, 714 },
- { -2278, -6550, 1674, 204 },
- { -2855, -5765, 930, 1530 },
- { -2889, -7325, -215, 305 },
- { -2749, -6080, -237, 1452 },
- { -985, -6667, 1577, 400 },
- { -2036, -6083, 380, 1267 },
- { -2077, -7460, 380, -30 },
- { -1775, -7175, 1540, -386 },
- { -3065, -6927, 989, 168 },
- { -2836, -7602, 117, -3392 },
- { -1058, -6396, 593, -3078 },
- { -844, -6062, 999, -236 },
- { -3261, -6951, 1491, -720 },
- { -2186, -8484, 75, -1287 },
- { -2882, -7756, 456, -510 },
- { -1800, -6879, 960, -1183 },
- { -2554, -7241, 1614, -1474 },
- { -2608, -5305, 392, 851 },
- { -2973, -6562, -859, 858 },
- { -2640, -5989, 1031, -416 },
- { -977, -8366, 705, -1434 },
- { -1213, -7409, -77, -1390 },
- { -1335, -6657, 2125, -123 },
- { -2544, -6862, 1852, -737 },
- { -3235, -6422, 1752, -103 },
- { -1300, -7557, 939, -348 },
- { -3476, -7579, 202, -109 },
- { -2482, -6572, 753, 619 },
- { -2554, -8136, -648, -429 },
- { -1012, -7870, -3, -421 },
- { -3604, -6247, 32, -3102 },
- { -1486, -7271, 2013, -1021 },
- { -578, -6799, -523, 405 },
- { -2841, -5948, 1644, 911 },
- { -2411, -7473, 1084, -484 },
- { -2238, -6033, 294, -1059 },
- { -3459, -6470, -201, -790 },
- { -2027, -6009, 1833, 805 },
- { -1433, -8047, 1531, -1754 },
- { -3258, -7884, 763, -1422 },
- { -1544, -6928, -729, 478 },
- { -2314, -8415, 74, -3757 },
- { -3201, -5684, 95, -2214 },
- { -2423, -8694, 725, -3631 },
- { -3545, -7071, 1162, -1798 },
- { -294, -9662, 403, -2274 },
- { -2290, -5460, 1196, 402 },
- { -1603, -6713, 903, -2363 },
- { 4121, 2491, -3142, -2482 },
- { 4500, 3305, -3671, -1567 },
- { 5973, 3172, -1348, -534 },
- { 4830, 3379, -1549, 643 },
- { 5214, 3938, -2641, -2302 },
- { 4639, 4826, -5532, -847 },
- { 5639, 2731, -2170, -963 },
- { 6084, 3487, -3525, -1346 },
- { 5971, 3154, -2190, -2316 },
- { 5618, 4865, -6927, 116 },
- { 5345, 3568, -7391, 709 },
- { 5429, 5078, -3811, -1524 },
- { 6960, 2037, -3515, -1096 },
- { 7092, 2531, -4557, -588 },
- { 6061, 4247, -5651, -478 },
- { 4595, 3684, -4907, -827 },
- { 7497, 3213, -3048, -424 },
- { 5996, 2137, -3098, -1745 },
- { 6198, 5199, -2223, -2274 },
- { 6888, 2851, -2768, -1675 },
- { 6114, 4210, -2316, -954 },
- { 7127, 4242, -3041, -1408 },
- { 6126, 3668, -1517, -1427 },
- { 6245, 6129, -4225, -1186 },
- { 6816, 3213, -2101, -964 },
- { 5345, 5276, -2643, -847 },
- { 6592, 4665, -4338, 484 },
- { 6746, 3751, -3443, 124 },
- { 5453, 1980, -2738, 2606 },
- { 4662, 2179, -4226, -1059 },
- { 5571, 3208, -3554, 174 },
- { 5256, 4447, -1815, -1481 },
- { 5400, 2570, -1210, 235 },
- { 7056, 2549, -2674, 318 },
- { 4574, 4340, -2892, -130 },
- { 6203, 4587, -3273, -305 },
- { 5103, 1925, -2715, -2137 },
- { 3905, 4296, -1700, 247 },
- { 4421, 4605, -3299, 811 },
- { 5671, 1273, -3870, -924 },
- { 5486, 1805, -4901, 133 },
- { 6437, 2578, -1828, -106 },
- { 5530, 5253, -5058, 1223 },
- { 4816, 2025, -1215, 1443 },
- { 3457, 3525, -2456, 3217 },
- { 3316, 2595, -1108, 2459 },
- { 3068, 3810, -2207, 1926 },
- { 6351, 5436, -6470, 600 },
- { 6324, 4240, -5365, 2416 },
- { 4851, 4774, -4075, 1878 },
- { 4900, 3679, -5198, 1078 },
- { 8347, 3633, -4565, -171 },
- { 5244, 5718, -3853, 173 },
- { 3960, 3492, -2939, 2105 },
- { 6070, 3473, -2351, 161 },
- { 8228, 3034, -3360, -901 },
- { 7006, 3985, -1940, -1926 },
- { 7123, 4681, -4301, -878 },
- { 5122, 4097, -1851, -449 },
- { 6200, 2060, -2251, 1049 },
- { 7106, 3844, -7209, 2625 },
- { 7108, 3370, -6734, 533 },
- { 6859, 2849, -3992, 1360 },
- { 5458, 2278, -3253, 1131 },
- { -1072, -2109, 4783, -1073 },
- { -319, -2604, 4257, -2418 },
- { 2466, 1300, 3476, -314 },
- { 2847, -1502, 5296, -141 },
- { 1667, -1273, 5559, -2725 },
- { 2877, -3402, 6434, 204 },
- { 53, -2637, 5275, -1181 },
- { 1091, -2215, 5803, -1549 },
- { 2397, -922, 4327, 1182 },
- { 219, -3747, 4647, -1564 },
- { -29, -2705, 4812, 1277 },
- { 1499, -2608, 5648, 1407 },
- { 2139, -2399, 4202, 2791 },
- { -426, -2064, 5528, 151 },
- { 2560, -2803, 6179, -2806 },
- { 4537, -2479, 3797, 1095 },
- { 888, -3357, 5341, -415 },
- { 4460, -1814, 5388, -1227 },
- { 3920, -3268, 6364, -703 },
- { 3343, -4698, 4410, 784 },
- { 309, -1897, 6306, 1223 },
- { 958, -3318, 4254, -3167 },
- { -99, 1596, 6018, -1983 },
- { -429, -853, 6407, 878 },
- { 1170, -1322, 6290, -417 },
- { 2288, -505, 6303, -1999 },
- { 3312, -1674, 6749, -2494 },
- { -415, -3401, 4721, -371 },
- { -189, -1210, 4844, -2002 },
- { 888, -4142, 4377, 130 },
- { 2469, -4381, 5398, -2492 },
- { 2879, -2912, 5094, -2598 },
- { -717, -617, 5650, -685 },
- { 1470, -3863, 5352, -1684 },
- { 3935, -96, 3823, -730 },
- { 3769, -430, 3168, 694 },
- { 2556, 385, 3539, 512 },
- { 77, -1415, 5111, 2655 },
- { 2724, -2158, 6715, -822 },
- { 1832, 1001, 5385, -1900 },
- { 900, 2198, 4464, -559 },
- { 441, 69, 5921, -1743 },
- { -1161, 738, 6732, -308 },
- { 257, 2035, 4091, 736 },
- { 1607, 1288, 4355, -23 },
- { -13, 1316, 4180, 1672 },
- { 1511, 1336, 3057, 1435 },
- { 2189, -3813, 4530, 939 },
- { 3632, -706, 2646, 1375 },
- { 4266, -3761, 4241, 1077 },
- { 3101, -427, 5273, -1202 },
- { 2293, 276, 4810, -313 },
- { 3430, -1851, 3101, 2045 },
- { 3453, -2979, 5142, 942 },
- { 1683, -3281, 4802, 2002 },
- { 3954, -4715, 5611, 578 },
- { 1272, -155, 5085, 454 },
- { 128, -194, 5095, 1409 },
- { 820, 880, 5797, -2658 },
- { -1095, 656, 5774, 1095 },
- { 813, -1669, 4320, -3251 },
- { -119, 518, 6372, -651 },
- { 2922, -4299, 6115, -877 },
- { 4205, -4273, 4004, 2642 },
- { -1211, -3892, 224, 3127 },
- { -34, -4371, 1321, 2318 },
- { 77, -6326, 1201, 828 },
- { 3995, -3775, 1958, 3233 },
- { 178, -3301, 1985, 3318 },
- { 2330, -3801, 1033, 3195 },
- { 1413, -5536, 826, 1709 },
- { 2468, -3499, 3653, 3631 },
- { 741, -4617, 1723, 2008 },
- { 1246, -3043, 2978, 3949 },
- { -343, -4308, 2258, 2189 },
- { -682, -4640, 454, 2272 },
- { 1236, -4829, 2491, 1642 },
- { -512, -3766, 1182, 3052 },
- { 119, -3939, 3712, 971 },
- { -1145, -4624, 1360, 2281 },
- { 101, -4746, 2866, 1255 },
- { -1500, -5455, 539, 1637 },
- { -969, -5909, 1414, 1128 },
- { -1261, -4939, -231, 2022 },
- { -226, -5345, 1207, 705 },
- { 2712, -5109, 3205, 1866 },
- { -476, -5913, 273, 1208 },
- { -2039, -4464, 624, 2545 },
- { -2351, -3930, 2019, 2673 },
- { -2675, -4849, 1522, 1990 },
- { -1524, -3461, 1446, 3204 },
- { 477, -5314, 1710, 1577 },
- { 656, -3729, 2346, 2511 },
- { 550, -5917, 1975, 1040 },
- { 1728, -4704, 3067, 1058 },
- { -9, -5247, 506, 1760 },
- { -574, -5135, 1675, 1672 },
- { 2129, -3781, 3444, 2313 },
- { 1144, -4439, 2214, 2529 },
- { 1292, -4160, 3185, 1833 },
- { 2445, -3262, 2534, 3227 },
- { 2266, -4401, 2023, 2400 },
- { -587, -3602, 3408, 2067 },
- { -885, -4951, 3228, 1174 },
- { -728, -2711, 2807, 3552 },
- { 1019, -3043, 3195, 2954 },
- { 1888, -4615, 1140, 2454 },
- { 660, -5616, 754, 800 },
- { -1975, -5371, 1649, 1585 },
- { -1544, -5436, 2422, 1081 },
- { -422, -5882, 2390, 750 },
- { 1336, -5557, 2441, 1230 },
- { 136, -4001, 267, 2854 },
- { -522, -3289, 2226, 2728 },
- { -971, -4580, 2471, 708 },
- { 704, -5306, 3300, 1001 },
- { 325, -3464, 3555, 2398 },
- { 794, -3686, 848, 3169 },
- { 660, -3017, 4584, 3242 },
- { -1486, -3978, 2170, 1644 },
- { -1615, -4650, 2688, 1844 },
- { 750, -4578, 538, 2239 },
- { 1668, -5849, 1455, 1031 },
- { 3486, -4681, 2030, 2183 },
- { 2642, -5429, 1696, 1761 },
- { 4491, -4502, 3538, 2767 },
- { 3545, -4528, 3514, 2982 },
- { 3269, -3676, 2758, 3966 },
- { 5572, 1146, 209, -3379 },
- { 7459, 1053, 593, -1896 },
- { 4480, 200, -310, -4259 },
- { 5577, -939, 242, -3992 },
- { 8142, 442, 1257, -3083 },
- { 5442, 1261, 1424, -3236 },
- { 6260, -183, 3125, -2532 },
- { 7179, 889, 1618, -2548 },
- { 6416, 932, 2379, -2487 },
- { 7094, 2560, 961, -3392 },
- { 7322, 463, 2732, -3735 },
- { 6632, 1577, 1912, -3272 },
- { 6312, 1349, 3028, -3460 },
- { 6105, 386, 1213, -977 },
- { 5478, 1158, 1114, -486 },
- { 6493, 410, 1686, -2180 },
- { 6378, 1881, 1333, -2240 },
- { 5711, 812, 1958, -1300 },
- { 6844, 877, 730, -1189 },
- { 6824, -245, 2249, -2000 },
- { 7515, 1521, 1251, -3058 },
- { 6697, 1051, 1300, -1749 },
- { 6476, 1425, 811, -2773 },
- { 7350, 465, -76, -2849 },
- { 6975, 2095, 567, -2492 },
- { 4691, 1736, 2660, -2289 },
- { 7837, 1456, 340, -2767 },
- { 7930, 507, 838, -2074 },
- { 6106, 1502, 766, -1110 },
- { 4891, -659, 835, -3954 },
- { 7250, 141, 1369, -1523 },
- { 7651, 67, 1651, -2298 },
- { 7364, -305, 601, -3132 },
- { 7179, 193, 2491, -2871 },
- { 6504, -272, 2167, -1322 },
- { 4456, 983, 2300, -421 },
- { 4817, 457, 1695, 371 },
- { 6914, 555, 850, -3159 },
- { 5904, 1030, 202, -1959 },
- { 6258, 880, 2233, -4503 },
- { 6029, 10, 2130, -3600 },
- { 6449, 985, 1129, -3963 },
- { 6616, -18, -111, -3285 },
- { 4496, 775, 817, -4276 },
- { 6134, 2338, 1470, -2973 },
- { 6911, 152, 430, -1946 },
- { 4053, 991, 3218, -1193 },
- { 5435, 1285, 3124, -2412 },
- { 5507, 1836, 1935, -1988 },
- { 5240, 689, 2189, -2670 },
- { 6638, 1719, 606, -1799 },
- { 5556, -180, 129, -2595 },
- { 5644, 1918, 1281, -4316 },
- { 6410, 1088, -282, -3117 },
- { 6503, 1841, 312, -3514 },
- { 6947, 20, 1358, -3886 },
- { 5464, 2109, 2398, -3194 },
- { 5616, -407, 2140, -498 },
- { 6121, 2707, 2379, -4096 },
- { 7303, 1846, 2266, -4095 },
- { 5444, 470, 2718, -1553 },
- { 5817, -645, 3285, -1349 },
- { 5625, 1427, 1103, -1991 },
- { 6041, -806, 1196, -2943 },
- { 3050, -5722, 4070, -5460 },
- { 3420, -4386, 4078, -5155 },
- { 6020, -3982, 7268, -2689 },
- { 7502, -4317, 7894, -3973 },
- { 4156, -3558, 5247, -4316 },
- { 4725, -4401, 7290, -1540 },
- { 6688, -5122, 8216, -3210 },
- { 9176, -6576, 9276, -4963 },
- { 8706, -5708, 7987, -4621 },
- { 7060, -3535, 6532, -3308 },
- { 5600, -2719, 5363, -1568 },
- { 4661, -2803, 6263, -4716 },
- { 3673, -3636, 6147, -3433 },
- { 5305, -2585, 6073, -2638 },
- { 7614, -1962, 6079, -5266 },
- { 6760, -3366, 7382, -4322 },
- { 6385, -3883, 4797, -1353 },
- { 8182, -5120, 4298, -4641 },
- { 9130, -6198, 4975, -3063 },
- { 7421, -5436, 5576, -3713 },
- { 3483, -4898, 5443, -2745 },
- { 4907, -5643, 6390, -4105 },
- { 8119, -7008, 7992, -6764 },
- { 6528, -6122, 6967, -5590 },
- { 5890, -4190, 6624, -5688 },
- { 6815, -7934, 7275, -5456 },
- { 5434, -4306, 5169, -5378 },
- { 4364, -6436, 5376, -2604 },
- { 8152, -3404, 5913, -5048 },
- { 7983, -4863, 4262, -2461 },
- { 8023, -6188, 6238, -5062 },
- { 6753, -3692, 3935, -3723 },
- { 6826, -4760, 3284, -4051 },
- { 7224, -7423, 4492, -3875 },
- { 6904, -2590, 6587, -6248 },
- { 6106, -1944, 7345, -5506 },
- { 4956, -2990, 7808, -3146 },
- { 6908, -6885, 5949, -1288 },
- { 7162, -6058, 3419, -3401 },
- { 7015, -7080, 6907, -3018 },
- { 6971, -6832, 5646, -3273 },
- { 8014, -5546, 5471, -1544 },
- { 6792, -2220, 5105, -2879 },
- { 8494, -3974, 4408, -3999 },
- { 9591, -4866, 6027, -4558 },
- { 5264, -5161, 6101, -738 },
- { 5803, -6141, 5197, -5231 },
- { 4657, -6822, 3232, -5189 },
- { 4791, -5135, 3809, -4665 },
- { 6108, -5103, 2379, -3873 },
- { 4680, -3909, 3234, -5093 },
- { 5802, -3853, 3795, -4984 },
- { 4360, -7483, 4802, -3877 },
- { 5429, -7517, 5911, -3717 },
- { 6866, -2280, 4880, -4634 },
- { 10131, -4628, 4414, -4092 },
- { 10811, -5189, 7746, -5337 },
- { 5663, -8941, 5287, -5680 },
- { 8023, -5991, 7403, -2796 },
- { 9669, -6919, 6525, -4932 },
- { 7275, -3796, 4962, -2547 },
- { 8848, -4806, 5677, -3080 },
- { 8128, -4308, 7749, -6569 },
- { 4032, -5196, 2282, -6239 },
- { 6593, 700, -229, 304 },
- { 8260, 539, -66, -1259 },
- { 6605, 176, -814, -109 },
- { 8057, 0, -1, -136 },
- { 7382, -38, -484, -1129 },
- { 8373, -929, 682, -454 },
- { 7674, 690, -1278, 546 },
- { 7326, -517, 406, -1283 },
- { 7612, -1715, -1167, 1175 },
- { 8590, 441, -782, -710 },
- { 8572, -1202, -291, 260 },
- { 7308, -147, -1785, 414 },
- { 6787, -353, -672, 934 },
- { 5177, -133, 179, 82 },
- { 4161, -34, 447, 1497 },
- { 5997, -902, 1533, -121 },
- { 5727, -871, -1370, 945 },
- { 8386, -252, 293, -823 },
- { 6573, -1354, 682, 616 },
- { 7650, -2096, 725, 457 },
- { 8122, 78, 636, -1400 },
- { 8421, 428, -1620, 131 },
- { 7341, -1292, -717, 186 },
- { 7998, -49, -720, 266 },
- { 5987, -351, 669, 844 },
- { 7314, -1620, 250, -603 },
- { 7219, -1562, -572, 1994 },
- { 8682, -358, -290, -388 },
- { 5810, 155, -178, 1199 },
- { 7246, -12, 1042, -786 },
- { 7357, -923, 1468, -475 },
- { 7801, 621, -212, -724 },
- { 5346, -514, 1210, 1356 },
- { 8459, 36, -127, -779 },
- { 6878, -2429, 854, 1750 },
- { 7280, -1401, -1353, 2845 },
- { 7579, -2148, -1463, 2087 },
- { 6637, 946, -872, 750 },
- { 4807, -1100, 1289, 2602 },
- { 4495, 219, 1551, 1128 },
- { 7639, 506, 446, -1107 },
- { 6359, 188, 1009, -115 },
- { 6641, -1820, 1655, 723 },
- { 5394, -2382, 1604, 2542 },
- { 6021, -2644, 2396, 1407 },
- { 4698, 882, 245, 1525 },
- { 8103, 573, -798, -349 },
- { 8045, -519, 997, -1092 },
- { 7571, -122, 227, -338 },
- { 5347, -1200, 630, 1718 },
- { 7070, 790, 218, -544 },
- { 7440, 728, -527, -20 },
- { 6402, -355, 197, -736 },
- { 4031, 771, 866, 1895 },
- { 6009, 896, 445, -31 },
- { 5160, 1098, -856, 1784 },
- { 7980, -886, -1293, 1396 },
- { 6318, -1361, 2423, 252 },
- { 7547, -699, 133, 506 },
- { 8562, -2344, 940, 264 },
- { 5890, 1187, -1425, 2194 },
- { 6558, -645, -1311, 2621 },
- { 4634, -1671, 2075, 1623 },
- { 5614, 105, -816, 2376 },
- { 6646, 1558, -1365, 630 },
- { 6998, 1150, -2117, -990 },
- { 6555, 2311, -1093, -1783 },
- { 6682, 1430, -2391, -1940 },
- { 7861, 1555, -2977, -1188 },
- { 6745, 1723, -459, -2085 },
- { 7504, 1229, -1666, -2060 },
- { 7937, 671, -2128, -1529 },
- { 7139, 991, -735, -2632 },
- { 6867, 1592, -1303, -2324 },
- { 6401, 2230, -1732, -2508 },
- { 7201, 2184, -2169, -1988 },
- { 6636, 2190, -995, -2840 },
- { 7620, 2306, -2089, -651 },
- { 7584, 1875, -1438, -631 },
- { 9214, 1561, -2464, -1139 },
- { 6154, 1318, -1237, -2917 },
- { 7917, 2847, -1797, -1599 },
- { 8309, 2029, -2555, -465 },
- { 8204, 1282, -584, -2405 },
- { 8440, 1035, -1147, -1137 },
- { 7107, 1858, -60, -1568 },
- { 6781, 2912, -873, -1463 },
- { 7603, 1316, -319, -1249 },
- { 7833, 1335, -78, -1849 },
- { 7930, 1141, -1016, -695 },
- { 7883, 1610, -1017, -1314 },
- { 8069, 1409, -1811, -196 },
- { 8319, 1031, -582, -1590 },
- { 5948, 1537, -2153, -2373 },
- { 8684, 1171, -1871, -850 },
- { 8357, 2484, -2411, -1292 },
- { 6516, 2092, -193, -1167 },
- { 6112, 1697, 22, -525 },
- { 7161, 703, -602, -1879 },
- { 6047, 2351, -807, -219 },
- { 8072, 1854, -1817, -1553 },
- { 6956, 1304, 76, -1011 },
- { 6607, 1481, -544, -162 },
- { 6958, 2541, -265, -1938 },
- { 6416, 2514, -777, -850 },
- { 7272, 2110, -899, -1171 },
- { 7741, 2153, -283, -2614 },
- { 6482, 2041, -1758, -1221 },
- { 6762, 940, -1862, -2281 },
- { 5610, 1194, -1691, -1561 },
- { 7833, 2164, -823, -1952 },
- { 5460, 1438, -848, 1189 },
- { 6011, 1377, -771, -1557 },
- { 7679, 544, -1134, -2214 },
- { 7209, 1292, -2714, -1564 },
- { 5567, 1200, -404, -169 },
- { 5853, 1461, -1465, -518 },
- { 6782, 689, -844, -860 },
- { 7330, 1337, -1152, -71 },
- { 7189, 1506, -653, -685 },
- { 6860, 2116, -1403, -240 },
- { 8804, 1516, -1391, -1760 },
- { 7210, 2689, -1498, -989 },
- { 7030, 3022, -1441, -2083 },
- { 5649, 1836, -407, 525 },
- { 7451, 3099, -717, -2464 },
- { 7384, 1656, -2007, 398 },
- { 6504, 707, -1919, -134 },
- { -1851, 3639, -2279, -695 },
- { -4037, 1644, -77, 1329 },
- { -4025, 1960, -1565, -567 },
- { -3430, 2495, -795, 368 },
- { -4771, 2480, 993, 756 },
- { -3431, 2058, -2539, -971 },
- { -3802, 3418, 380, 217 },
- { -3074, 3350, -1652, -1056 },
- { -3705, 326, -1650, 1535 },
- { -3122, 1281, -1192, 1607 },
- { -4601, 1367, -968, 53 },
- { -3808, 958, 44, 2560 },
- { -2079, 2530, -1485, 1166 },
- { -3707, 343, -2889, 180 },
- { -5249, 1431, -31, 688 },
- { -4990, 125, -704, 1270 },
- { -2771, 1334, -2446, 746 },
- { -2292, 994, -1527, 2630 },
- { -1261, 3070, -2519, 268 },
- { -2544, 3890, -1057, -552 },
- { -4421, 255, -1980, 530 },
- { -2951, 454, -13, 3643 },
- { -2262, 1815, -370, 2880 },
- { -2383, 3657, -649, 576 },
- { -3541, -161, -1389, 2550 },
- { -4241, 1575, 1325, 2561 },
- { -2767, 4037, 1221, 1578 },
- { -3748, 2697, 1148, 1801 },
- { -4686, 2385, -220, 0 },
- { -1531, 1645, -2751, 1327 },
- { -45, 4032, -799, 2298 },
- { -2915, 2280, 709, 2495 },
- { -1199, 3278, -406, 2346 },
- { -2471, 116, -2706, 2060 },
- { -2440, 2173, -2894, -344 },
- { -3375, 2287, 1781, 3226 },
- { -2153, 3568, 1827, 2918 },
- { -862, 2267, -1626, 2527 },
- { -2698, 1135, 301, 4239 },
- { -2364, 2123, 1010, 3710 },
- { -2447, 3281, -81, 1408 },
- { -2660, 4735, 472, 258 },
- { -1053, 3097, 2682, 2398 },
- { -3366, -1037, -1152, -868 },
- { -643, 4242, 2212, 1259 },
- { 971, 3991, 934, 643 },
- { -1617, 2002, 2139, 2195 },
- { -4897, 972, 784, 1719 },
- { -1275, 2992, 1039, 3821 },
- { -392, 4973, -209, 1821 },
- { -1028, 4718, -1479, -137 },
- { 50, 3914, 553, 2210 },
- { 678, 4364, 359, 1303 },
- { -582, 4911, 514, 1671 },
- { 1276, 3914, -1252, 2934 },
- { -1496, 3984, 857, 2330 },
- { 772, 4744, -655, 2332 },
- { -799, 5283, -439, 624 },
- { 1341, 2937, 650, 2027 },
- { -1739, 4892, 1275, 1702 },
- { -892, 2596, -151, 3951 },
- { -3532, 1090, 1292, 32 },
- { 321, 3146, 2647, 1475 },
- { 264, 4199, -1591, 1317 },
- { -452, -2357, 2266, 4192 },
- { 3022, -1033, -2389, 5678 },
- { -1162, -1342, 3543, 4990 },
- { -474, -1477, -1223, 5016 },
- { -699, -2857, 900, 3835 },
- { -461, -2255, -117, 4626 },
- { 1204, -2062, -1211, 4403 },
- { 2192, -3035, -337, 3966 },
- { 108, -831, 279, 5643 },
- { 1457, -620, -2908, 5276 },
- { -2527, -78, 1085, 5460 },
- { -1978, -1918, -949, 4733 },
- { 32, 367, -1904, 5166 },
- { 1890, -1665, 440, 4752 },
- { -518, -348, 2816, 4891 },
- { 3695, -2490, -1374, 4603 },
- { 246, -1965, 3549, 3969 },
- { 1100, -3111, 656, 3737 },
- { -1379, 870, -414, 4575 },
- { 628, -357, -1227, 6179 },
- { -1129, -1318, -2457, 4576 },
- { -425, -98, -73, 6336 },
- { 367, -887, 2990, 4207 },
- { 2091, -1251, 2444, 3557 },
- { -1759, -1610, 2046, 5273 },
- { 3210, 1414, -20, 2616 },
- { 3303, -2636, 1005, 4237 },
- { -327, -3107, -640, 3687 },
- { -197, 764, 572, 5486 },
- { 646, -767, 1388, 5464 },
- { 104, 2742, -228, 3907 },
- { -236, 1829, -579, 4585 },
- { -2150, -474, -1525, 4006 },
- { -23, -2632, -2400, 3892 },
- { -12, -1739, -2910, 4867 },
- { -2310, -368, -102, 4583 },
- { -1991, -2061, 533, 4531 },
- { 3884, -1446, -153, 4393 },
- { 1568, 14, -289, 5268 },
- { -1376, -253, -2797, 3417 },
- { 3193, -2577, 2475, 3566 },
- { 3418, 617, 1350, 1857 },
- { 3792, -24, -272, 3370 },
- { 153, 1159, 2906, 2877 },
- { 511, 2162, 1548, 2741 },
- { 262, 819, -2791, 3734 },
- { 4232, -2015, 1486, 3477 },
- { 2943, -1110, -1014, 5480 },
- { 2842, 369, 703, 3476 },
- { 3011, 1634, -933, 3553 },
- { 4412, -1548, -942, 5021 },
- { -1405, 593, 2372, 5267 },
- { 2093, 2129, 896, 2365 },
- { 4845, -1980, 0, 3823 },
- { -2140, 81, 3278, 5637 },
- { 1484, 2665, -324, 3653 },
- { 10, 192, 1620, 5291 },
- { 2152, 738, -2269, 5000 },
- { 2102, 2748, -1652, 4707 },
- { 2855, -2131, -387, 5188 },
- { 1173, 676, 1338, 3277 },
- { 2340, -2329, -2064, 4095 },
- { 861, -2024, 1296, 5055 },
- { 2189, 3225, -695, 2626 },
- { 6196, -7079, 1943, -822 },
- { 4547, -4813, 3261, 1856 },
- { 4243, -6904, 3443, 448 },
- { 4581, -7503, 946, 506 },
- { 6626, -7754, 3427, 470 },
- { 3407, -9088, 3269, -1496 },
- { 4079, -6464, 2304, 777 },
- { 5621, -9336, 2684, -768 },
- { 5351, -6464, 5238, -214 },
- { 5961, -8007, 1724, -3091 },
- { 4213, -8067, 603, -246 },
- { 7208, -7403, 3168, -1738 },
- { 6098, -7700, 329, -1379 },
- { 6525, -6735, 4248, -1072 },
- { 6073, -6241, 2167, -2378 },
- { 4609, -9218, 3051, -1033 },
- { 6813, -7283, 1581, -1897 },
- { 6126, -6275, 2789, 681 },
- { 4423, -6538, 1621, -1692 },
- { 6272, -8298, 3167, -1855 },
- { 6172, -8558, 4498, -1169 },
- { 4844, -8588, 1647, -366 },
- { 6209, -8807, 1581, -369 },
- { 5389, -8059, 550, -192 },
- { 6654, -9775, 2504, -1063 },
- { 7103, -7998, 806, 530 },
- { 5662, -6736, 1565, -3620 },
- { 4165, -9564, 4191, -2131 },
- { 4526, -7181, 576, -2875 },
- { 4633, -8623, 2807, -4742 },
- { 3709, -7794, 1815, 34 },
- { 3634, -8622, 2313, -826 },
- { 6991, -8447, 2063, -3198 },
- { 7757, -9486, 2255, -558 },
- { 4149, -7778, 4728, -1696 },
- { 5767, -7427, 1113, 707 },
- { 4592, -6261, 2329, 1864 },
- { 3159, -10498, 1677, -4273 },
- { 3534, -9010, 2437, -3565 },
- { 4479, -10821, 2715, -4942 },
- { 3207, -9805, 3054, -3886 },
- { 4627, -8189, 3018, -2354 },
- { 5527, -10566, 3244, -2749 },
- { 4346, -10127, 3335, -3084 },
- { 6132, -10085, 3316, -1308 },
- { 5629, -9704, 2178, -3058 },
- { 3603, -8538, 1246, -624 },
- { 3737, -8488, 395, -3167 },
- { 5465, -11414, 2810, -4640 },
- { 5306, -7745, 2721, -3988 },
- { 7000, -9111, 1695, -1409 },
- { 6663, -7741, 2466, -4079 },
- { 4083, -7175, 1836, -4831 },
- { 3613, -9926, 1342, -3455 },
- { 6588, -8033, 457, -258 },
- { 4720, -8102, 17, -1209 },
- { 7414, -8709, 1294, -344 },
- { 5437, -10030, 4043, -1704 },
- { 4862, -9281, 1558, -1431 },
- { 6800, -6403, 5113, 862 },
- { 4623, -8242, 2667, -228 },
- { 5919, -5083, 3348, 2135 },
- { 5985, -8889, 2733, -5105 },
- { 5029, -5767, 4407, 719 },
- { 354, -6158, -838, -3001 },
- { 351, -5943, -2104, -1534 },
- { -633, -7190, -25, -4798 },
- { -1595, -7235, -3812, -1400 },
- { 103, -6197, -2933, -78 },
- { -1722, -5020, -3441, -4333 },
- { -1963, -5644, -4365, -270 },
- { -846, -5743, -3477, 196 },
- { -191, -5348, -4054, -469 },
- { -2515, -7754, -3495, -818 },
- { -2090, -6710, -2701, 117 },
- { -546, -7036, -1398, 163 },
- { -278, -7091, -2662, -536 },
- { -622, -7962, -2731, -1464 },
- { -1555, -8118, -3612, -2057 },
- { -1094, -6280, -2314, 505 },
- { -2556, -8538, -4024, -2247 },
- { 109, -7134, -3107, -1823 },
- { -900, -6954, -3340, -717 },
- { -605, -7113, -3656, -2154 },
- { 837, -6263, -3211, -2177 },
- { -417, -5810, -3871, -1469 },
- { -1318, -5649, -4207, -3198 },
- { 413, -6765, -2082, -33 },
- { -3101, -6450, -4362, -766 },
- { 755, -6489, -2967, -846 },
- { 1117, -7106, -2452, -1352 },
- { -1202, -8387, -3072, -2897 },
- { -365, -4894, -3561, -2937 },
- { -2372, -8776, -265, -4441 },
- { -1224, -8678, -896, -5074 },
- { -755, -10096, -600, -6623 },
- { 300, -8206, -225, -4568 },
- { -1176, -6824, -2633, -3527 },
- { -2006, -5443, -1526, -5849 },
- { -1115, -5540, -2363, -4785 },
- { 1059, -6812, -2543, -2654 },
- { -1976, -6861, -3062, -5508 },
- { -379, -5328, -2321, -3624 },
- { -2108, -5860, -4518, -1915 },
- { -379, -7885, -1329, -594 },
- { 774, -5389, -581, -5213 },
- { -2601, -5083, -1849, -4921 },
- { -176, -5580, 74, -5075 },
- { -204, -6780, -190, -6232 },
- { 418, -7594, -1987, -820 },
- { -1873, -8529, -2926, -1609 },
- { 1340, -6362, -919, -4975 },
- { 577, -7990, -2044, -1873 },
- { -2572, -7413, -1745, -2224 },
- { -2037, -7030, -1461, -7138 },
- { -2559, -8756, -2039, -5836 },
- { -2079, -6764, -1209, -5669 },
- { -1613, -7801, -2006, -685 },
- { -1865, -6583, -722, -3529 },
- { -589, -6358, -1377, -1003 },
- { -540, -7514, -1331, -3542 },
- { 419, -6192, -1677, -4927 },
- { -2786, -8763, -2966, -5065 },
- { -2172, -8411, -1726, -4675 },
- { -3382, -9833, -3497, -5722 },
- { -2433, -10169, -2077, -5775 },
- { -424, -9451, -1096, -3658 },
- { -537, -8522, -910, -1897 },
- { -5550, 2807, 1683, -693 },
- { -6395, 635, 3573, -1246 },
- { -7544, 2280, 2140, 44 },
- { -8751, 1136, 2951, -794 },
- { -5605, 2709, 2052, 916 },
- { -7650, 654, 869, 135 },
- { -6939, 967, 1409, 870 },
- { -7834, 2123, 3310, 974 },
- { -6935, 2818, 1274, -1678 },
- { -5605, 2233, 1013, 471 },
- { -7095, 1849, 1648, 198 },
- { -6636, 1634, 712, -37 },
- { -7279, 978, 296, -315 },
- { -7664, 3504, 3292, -216 },
- { -7836, 1209, 1221, -257 },
- { -7913, 2201, 1765, -1529 },
- { -7077, 3783, 2632, -1407 },
- { -5565, 1645, 1410, -622 },
- { -6494, 2879, 1181, -759 },
- { -7073, 3137, 3010, 550 },
- { -7249, 1839, 847, -805 },
- { -6630, 2197, 282, -1096 },
- { -8836, 1573, 1988, -1090 },
- { -7809, 1274, 836, -1198 },
- { -7895, 2970, 3511, -1097 },
- { -6960, 1664, 1356, -2442 },
- { -6582, 2866, 2273, 307 },
- { -7221, 821, 2851, -1435 },
- { -6015, 1703, 2001, -2367 },
- { -8082, 1034, 2103, 239 },
- { -5952, 1912, 301, -465 },
- { -6099, 841, 379, 567 },
- { -6343, 50, 494, 658 },
- { -6586, 983, 591, -893 },
- { -5500, 869, 2187, -2479 },
- { -6482, 60, 1545, -979 },
- { -6705, 515, 1974, -53 },
- { -6460, 1755, 1325, -1275 },
- { -6093, 2617, 2465, -623 },
- { -7330, 2161, 594, -2115 },
- { -7324, 762, 1593, -2004 },
- { -6385, 679, 1510, -2514 },
- { -6159, 241, 2976, -1631 },
- { -8583, 3030, 4045, -162 },
- { -6299, 66, 2209, -2103 },
- { -5428, 1279, 3267, -1846 },
- { -6438, 1335, 2728, -1631 },
- { -8012, 1070, 2428, -1151 },
- { -6201, 2781, 2349, -1918 },
- { -5918, 1139, 3121, -148 },
- { -6314, 2481, 3137, -1808 },
- { -7180, 1722, 2435, -1602 },
- { -6750, 1829, 3763, -1145 },
- { -6713, 1777, 2221, 1212 },
- { -7479, 1835, 3627, -479 },
- { -7299, 10, 2406, -1593 },
- { -8249, 3129, 996, -2870 },
- { -8374, 1534, 1333, -1882 },
- { -7507, 3353, 1598, -2299 },
- { -7379, 2701, 2326, -1167 },
- { -8440, 2276, 2796, -542 },
- { -10348, 1527, 2649, -1165 },
- { -8184, 3614, 2574, -1738 },
- { -5539, 1574, 1733, 1138 },
- { 9404, -7652, 67, 79 },
- { 8654, -3972, 1358, -60 },
- { 8617, -4794, 117, 2318 },
- { 7886, -4505, 1784, 1200 },
- { 8636, -6125, 3879, -1003 },
- { 9654, -6836, 1816, 205 },
- { 9374, -6553, 913, 1875 },
- { 8020, -6150, 1134, 2390 },
- { 7786, -4970, 2078, -1857 },
- { 8691, -6119, 711, 708 },
- { 9039, -5568, 2944, -1902 },
- { 9955, -5048, 1433, -601 },
- { 8089, -6927, 3093, -2846 },
- { 8487, -7024, 2415, 19 },
- { 9388, -5287, 3577, -2655 },
- { 8591, -7371, 2300, -996 },
- { 9104, -4763, 1453, -2558 },
- { 7615, -5457, 596, 164 },
- { 9860, -7047, 3433, -614 },
- { 8756, -4404, 2235, -964 },
- { 9462, -4660, 299, -1822 },
- { 10119, -5550, 2689, -1273 },
- { 10915, -7471, 2705, -1007 },
- { 11433, -7090, 1410, -1198 },
- { 9882, -7431, 2965, -1895 },
- { 7628, -5219, 769, -2661 },
- { 8169, -5318, 2262, 70 },
- { 8846, -6320, 1939, -754 },
- { 7147, -5593, 1248, -971 },
- { 10652, -5485, 935, 137 },
- { 7778, -6533, 2564, -1932 },
- { 8878, -5173, 1214, -361 },
- { 9828, -4943, 282, 510 },
- { 10042, -6134, 3895, -1914 },
- { 7965, -6630, 3566, -433 },
- { 8573, -4502, 3574, -1209 },
- { 8398, -4801, 1031, -1347 },
- { 10136, -7772, 2612, 1547 },
- { 9890, -7280, 1768, -1083 },
- { 8407, -6585, -706, -58 },
- { 7976, -7582, 229, -131 },
- { 10481, -8866, 1166, -147 },
- { 10914, -4342, 3189, -2412 },
- { 10440, -5198, -104, -1109 },
- { 11227, -6530, 2381, -2449 },
- { 8487, -8064, 1086, 230 },
- { 9975, -6123, -857, -134 },
- { 8339, -6498, 1232, -2337 },
- { 11042, -4506, 1119, -2098 },
- { 12563, -5592, 1837, -2062 },
- { 11801, -5590, 632, -1296 },
- { 10152, -5617, 1511, -1917 },
- { 7800, -6473, 51, -1337 },
- { 7941, -5560, 2438, -3270 },
- { 6554, -3834, 2100, 1476 },
- { 9065, -5520, -226, -1120 },
- { 10794, -7120, -243, 122 },
- { 10429, -6968, 272, -806 },
- { 8942, -8914, 1442, -392 },
- { 9969, -5051, 2033, -2953 },
- { 7275, -4152, 3058, -64 },
- { 11127, -5488, 4589, -3227 },
- { 9626, -6666, 2739, -2958 },
- { 6943, -5362, 4470, 1008 },
- { -7456, -967, 2936, -1002 },
- { -8622, -333, 6962, 2606 },
- { -7486, -3392, 3668, 1287 },
- { -8053, -827, 5148, 1097 },
- { -6610, 454, 4952, 96 },
- { -7701, -1982, 3161, -468 },
- { -7307, -1132, 4071, -36 },
- { -8125, -271, 5199, 3862 },
- { -9182, -1950, 2813, 1878 },
- { -9855, -952, 4794, 3010 },
- { -7241, 1431, 4202, 2468 },
- { -9646, 157, 4766, 1046 },
- { -9371, 1230, 6009, 2958 },
- { -11514, -64, 8630, 5248 },
- { -6766, 565, 2766, 2140 },
- { -8426, -9, 2852, 1271 },
- { -11291, -1113, 5087, 2937 },
- { -8297, 2092, 4495, 1264 },
- { -9983, 735, 3809, -51 },
- { -9048, -1000, 3191, -308 },
- { -7331, -1987, 2655, 1391 },
- { -7144, -21, 4333, 2161 },
- { -6032, -1540, 3543, 896 },
- { -7987, -1036, 1985, 1529 },
- { -9264, 2004, 5194, 290 },
- { -11308, -840, 5754, 1654 },
- { -9130, -2398, 4292, 2973 },
- { -6248, 838, 3563, 1223 },
- { -6819, -2760, 3511, 119 },
- { -7213, -2006, 4364, 762 },
- { -5431, -1047, 4533, 166 },
- { -7098, -641, 2021, 639 },
- { -8628, -2249, 3588, 399 },
- { -6352, -1498, 3560, -648 },
- { -7033, -2190, 4870, 2562 },
- { -7405, -46, 3772, -581 },
- { -6104, 796, 5143, 1965 },
- { -5787, 943, 5784, 3030 },
- { -8367, 1465, 7192, 4097 },
- { -8259, 789, 5694, 1963 },
- { -10614, -1899, 5748, 2645 },
- { -8258, -805, 3698, 2275 },
- { -6877, -972, 6431, 3160 },
- { -6483, 363, 7018, 3129 },
- { -6283, -1358, 5191, 1524 },
- { -8853, -3157, 4119, 1741 },
- { -6086, -267, 3883, -835 },
- { -7254, 1032, 6613, 4017 },
- { -11470, -3350, 4649, 3426 },
- { -6743, 481, 6148, 1239 },
- { -5394, -166, 5309, 3165 },
- { -7958, 1068, 4268, -240 },
- { -10520, 2256, 7916, 2828 },
- { -5132, -4, 5739, 1176 },
- { -8643, 120, 3255, -629 },
- { -9631, 1974, 8870, 4362 },
- { -10663, -1221, 3733, 589 },
- { -8224, -1843, 5806, 2655 },
- { -8282, 1255, 8647, 3478 },
- { -12311, -1505, 9043, 6256 },
- { -11312, -856, 7136, 4681 },
- { -11944, -722, 7941, 3309 },
- { -7868, -463, 6846, 4196 },
- { -8679, -241, 7410, 5347 },
- { 6759, -4680, -508, 1220 },
- { 5176, -6111, 944, 121 },
- { 6843, -5667, -1368, -533 },
- { 5616, -5884, -1471, -695 },
- { 6030, -5089, -1808, -940 },
- { 7444, -5463, -52, 1881 },
- { 4207, -6079, -506, 1571 },
- { 6785, -4410, -649, 3084 },
- { 4838, -5214, 2026, 2998 },
- { 4201, -5790, 645, 1811 },
- { 6930, -5129, -1940, 1698 },
- { 6332, -4627, 692, 3027 },
- { 6285, -4314, -106, 3644 },
- { 6255, -5450, -1975, 742 },
- { 4199, -4676, -459, 1796 },
- { 5592, -5500, 1345, 1300 },
- { 4358, -5556, -2236, 114 },
- { 4620, -5875, -1563, 888 },
- { 4892, -7550, -327, -419 },
- { 4734, -7085, 7, 613 },
- { 3883, -5562, -1969, 1080 },
- { 5610, -4990, -204, 834 },
- { 4117, -6482, -1271, 341 },
- { 6585, -5107, 892, 1169 },
- { 6632, -3683, 302, 3002 },
- { 6326, -5351, -983, -1250 },
- { 4382, -7192, -730, -158 },
- { 5227, -6540, -451, 1123 },
- { 5468, -6472, -870, -1471 },
- { 5191, -6402, -1365, -127 },
- { 7407, -6317, -973, -336 },
- { 4611, -6530, -820, -1980 },
- { 4963, -5159, -2050, -966 },
- { 4414, -5691, -211, -998 },
- { 5954, -5873, 750, -1749 },
- { 4394, -4796, -1268, 254 },
- { 7161, -6214, -1010, 689 },
- { 4965, -3598, 2372, 1711 },
- { 6248, -6180, 981, 864 },
- { 6473, -5336, 525, -600 },
- { 4591, -6864, -1131, -900 },
- { 6314, -6440, -1021, -375 },
- { 5838, -6209, -1199, 944 },
- { 5308, -5283, -2100, 1267 },
- { 4342, -5860, -1637, -1356 },
- { 5680, -4388, -1227, -104 },
- { 4900, -4098, 1449, 4046 },
- { 4677, -4284, -106, 3190 },
- { 7574, -6173, -848, 1859 },
- { 6493, -7207, -131, 726 },
- { 5513, -5261, -2117, 4 },
- { 6191, -7352, -193, -505 },
- { 5885, -4333, 324, -134 },
- { 6162, -6081, -312, -2044 },
- { 4216, -6200, -1810, -572 },
- { 5652, -7035, -696, -197 },
- { 7131, -7189, -366, -60 },
- { 5032, -4803, -1514, 2832 },
- { 7386, -4610, -606, 3489 },
- { 4211, -5031, 1221, 3047 },
- { 4050, -4653, 1584, 1469 },
- { 6852, -5302, -1861, 206 },
- { 7736, -4816, -1794, 3359 },
- { 6290, -3439, 1522, 2454 },
- { 1768, 5990, -5560, -2594 },
- { 3903, 5326, -1530, -1501 },
- { 2472, 3738, -2117, -4240 },
- { 3260, 5448, -904, -4733 },
- { 1435, 7297, -3676, -4102 },
- { 4096, 5951, -656, -3312 },
- { 2178, 6009, -3146, -3724 },
- { 3787, 5493, -5473, -1633 },
- { 2998, 7286, -3334, -3571 },
- { 2894, 6576, -4708, -2804 },
- { 830, 6163, -4286, -3348 },
- { 4755, 5569, -1730, -2739 },
- { 4604, 6065, -3562, -2605 },
- { 2749, 5141, -3986, -2775 },
- { 3942, 4875, -2143, -3340 },
- { 2819, 8517, -2004, -2724 },
- { 2146, 6298, -689, -3093 },
- { 5196, 6504, -3393, -1475 },
- { 1851, 8386, -1748, -1420 },
- { 3474, 8572, -3534, -2688 },
- { 4503, 7560, -3561, -2245 },
- { 4433, 6219, -2393, -1575 },
- { 3506, 7248, -2275, -1977 },
- { 3490, 7409, -3147, -604 },
- { 4214, 6447, -3520, 516 },
- { 619, 7034, -829, -1705 },
- { 1732, 7395, -356, -2208 },
- { 1226, 5204, -3294, -3732 },
- { 2027, 5619, -1813, -4146 },
- { 3078, 5877, 47, -2651 },
- { 1654, 5458, 424, -682 },
- { 3163, 5464, -2026, -270 },
- { 2884, 5375, -685, -530 },
- { 2950, 7286, -35, -2967 },
- { 1986, 5066, -597, 482 },
- { 3459, 4308, -3845, -2333 },
- { 3155, 7037, -1346, -4345 },
- { 2193, 6696, -717, -1319 },
- { 3677, 5089, -3892, -487 },
- { 2186, 5136, -4186, -1492 },
- { 773, 5796, -917, 817 },
- { 2489, 6546, -3570, -2117 },
- { 1223, 6469, -1362, -33 },
- { 271, 6061, -1466, -1725 },
- { 2540, 5171, -1847, 1032 },
- { 2548, 5251, -2697, 1677 },
- { 771, 7600, -768, -632 },
- { 4710, 6647, -4736, -1275 },
- { 1369, 5917, -2971, -1056 },
- { 163, 5239, -3499, -2275 },
- { 2104, 4285, -3211, -3286 },
- { 1107, 7411, -1972, -1671 },
- { 2196, 7262, -2310, -1926 },
- { -244, 6439, -1745, -839 },
- { 3293, 3832, -2890, -3000 },
- { 419, 6443, -379, -407 },
- { 3077, 4930, -1156, -2869 },
- { 2131, 5874, -2330, 224 },
- { 690, 6538, -2212, -2841 },
- { 1602, 4421, -2515, 1542 },
- { 3318, 9373, -3032, -3477 },
- { 5646, 7462, -5153, -1463 },
- { 4139, 7137, -1539, -3321 },
- { 3481, 9077, -1645, -3653 },
- { -7747, 375, -106, -543 },
- { -8587, -1379, -586, -461 },
- { -10146, -892, 2094, 694 },
- { -8103, 382, 504, -325 },
- { -8548, -92, 94, -656 },
- { -7460, 38, 152, 388 },
- { -8266, -271, -459, -883 },
- { -7935, -664, -1026, -802 },
- { -8341, -109, 853, 161 },
- { -8802, -1355, 1099, 630 },
- { -8957, -6, 1108, -669 },
- { -7260, -1520, -43, -407 },
- { -7555, -174, 668, -2562 },
- { -9014, -126, 227, -1191 },
- { -8184, 769, 290, -1375 },
- { -9476, 55, 962, -1528 },
- { -8679, 541, 755, -1030 },
- { -9842, -1626, 838, -1588 },
- { -8513, -702, 788, -1998 },
- { -10101, -1558, -366, -1841 },
- { -8135, 78, 1479, -1813 },
- { -9128, -454, 313, -1786 },
- { -7554, -1084, 831, -2442 },
- { -7576, -701, 2068, -1665 },
- { -7791, -1481, 1587, -1808 },
- { -6701, -596, -97, 802 },
- { -7418, -15, 684, -963 },
- { -7127, -477, -139, -426 },
- { -8097, -110, -36, -264 },
- { -7620, -1922, -590, -101 },
- { -7647, -1201, 279, 660 },
- { -7856, -1974, 758, -2271 },
- { -8496, -167, 2232, -1143 },
- { -8506, -1359, 624, -740 },
- { -7274, -1052, 1062, -139 },
- { -7800, -217, 91, -1794 },
- { -7030, -1694, -955, 615 },
- { -9020, -1864, 101, -2182 },
- { -9400, -740, 598, -667 },
- { -8448, -1184, 2024, -1272 },
- { -8812, -570, -897, -2384 },
- { -10559, -1286, 538, -1536 },
- { -8728, -888, -1089, -1397 },
- { -7080, -1185, 636, -1252 },
- { -9880, 233, 2344, -782 },
- { -7952, -1326, -378, -1947 },
- { -7207, -378, 1408, -2237 },
- { -8467, -1545, 902, -1987 },
- { -9163, -1474, 924, -1739 },
- { -8159, -992, -77, -2744 },
- { -8343, 148, -423, -1573 },
- { -9105, -649, -254, -1214 },
- { -8939, 456, 281, -1905 },
- { -8837, 179, -394, -2634 },
- { -9145, 757, 1547, -1319 },
- { -9775, -723, 441, -1680 },
- { -8910, -686, 1529, -1525 },
- { -9492, -1134, 2064, -938 },
- { -6111, -943, 677, -31 },
- { -7411, -613, -814, 46 },
- { -9479, -922, -430, -2061 },
- { -11298, -1268, 1318, -1117 },
- { -8190, 832, 671, -2214 },
- { -10453, -550, 1672, -886 },
- { 1044, 9353, -1651, -5423 },
- { 1034, 8149, -455, -6166 },
- { 761, 8293, -3214, -4838 },
- { 938, 8077, 164, -5130 },
- { 1295, 8673, 2582, -5490 },
- { -314, 7973, -2395, -5231 },
- { -507, 9012, -2497, -5775 },
- { 2396, 8314, -1022, -4673 },
- { -1516, 8501, 1950, -4969 },
- { -308, 7401, 1549, -4866 },
- { -112, 8340, 3003, -4920 },
- { -50, 9315, 1371, -5666 },
- { -659, 9449, 2496, -5547 },
- { 2573, 9148, -2270, -4783 },
- { 830, 7104, -438, -3907 },
- { 522, 10672, -677, -6483 },
- { -1190, 10108, -510, -6518 },
- { -427, 8271, -579, -6315 },
- { 1602, 8113, -1927, -4418 },
- { -2266, 8180, 448, -5190 },
- { -1633, 8816, -226, -5771 },
- { 759, 9481, -105, -5813 },
- { 2254, 6679, -466, -5662 },
- { -88, 6946, 895, -5958 },
- { -1705, 10009, 1394, -5574 },
- { 748, 7943, 540, -6692 },
- { 1411, 7009, 232, -6145 },
- { 697, 7290, -1221, -5342 },
- { -1764, 10580, 1944, -3981 },
- { -1334, 9124, 1195, -3903 },
- { -905, 10067, 635, -5039 },
- { 664, 10680, 49, -4625 },
- { 1374, 9536, -777, -3591 },
- { 252, 9698, -597, -2931 },
- { 824, 9164, -1014, -2144 },
- { 2438, 10569, -2289, -4424 },
- { 2101, 7102, 507, -3614 },
- { 294, 8051, -432, -1518 },
- { -665, 10337, 547, -2852 },
- { 1168, 11989, -492, -5427 },
- { 1344, 6416, 302, -5061 },
- { -1727, 12264, 1507, -4543 },
- { 674, 10889, -902, -3605 },
- { -582, 9504, 300, -3618 },
- { 641, 7654, 689, -2109 },
- { 2065, 9243, 508, -4367 },
- { 1055, 8373, 688, -3144 },
- { -641, 8185, 986, -3307 },
- { 1120, 7426, 1785, -3757 },
- { 1660, 8070, -593, -3104 },
- { 2002, 9467, -1722, -3475 },
- { 2361, 8368, 100, -3709 },
- { -772, 7845, -613, -4988 },
- { 1485, 7430, 1896, -6127 },
- { -432, 7823, -947, -2882 },
- { 313, 11122, -760, -4871 },
- { 412, 8412, -283, -4231 },
- { 1585, 10402, -1884, -3267 },
- { 321, 6952, 773, -3016 },
- { -105, 9014, 121, -2249 },
- { 1585, 10313, -977, -4812 },
- { 1619, 11869, 1306, -6876 },
- { -1168, 8886, -81, -2500 },
- { -395, 10886, 733, -6490 },
- { -4949, 4274, 3992, -1054 },
- { -4241, 5299, 4262, -1584 },
- { -2710, 3862, 4552, -1673 },
- { -4608, 2472, 3672, -1715 },
- { -2843, 2816, 4003, -2326 },
- { -5229, 2964, 5636, 90 },
- { -4924, 3442, 5015, -1096 },
- { -1281, 3313, 5537, -2066 },
- { -3808, 1939, 4351, -919 },
- { -1915, 2585, 4939, -1614 },
- { -3470, 1843, 5562, -682 },
- { -3800, 870, 5827, 144 },
- { -4985, 1452, 4728, -709 },
- { -3745, 2750, 7220, 259 },
- { -1875, 1900, 6514, -826 },
- { -4329, 1574, 7192, 1304 },
- { -5408, 1444, 6208, 631 },
- { -3327, 5312, 5707, -1541 },
- { -6966, 3334, 4034, 1028 },
- { -7484, 4245, 4218, -212 },
- { -6567, 5839, 4539, -512 },
- { -5715, 5935, 3747, -1186 },
- { -6410, 4881, 3356, -1610 },
- { -5146, 2590, 2850, 2172 },
- { -5196, 4095, 2569, -373 },
- { -5043, 6025, 4318, 692 },
- { -5525, 4884, 3513, 370 },
- { -6804, 7533, 5812, -488 },
- { -5657, 2480, 4061, 1234 },
- { -3155, 1472, 6071, 1188 },
- { -3427, 5217, 3442, 858 },
- { -4698, 3013, 5517, 2586 },
- { -4449, 2226, 5418, 3580 },
- { -6395, 3547, 5487, 2028 },
- { -3500, 5019, 4787, 1 },
- { -4038, 2578, 3073, 3151 },
- { -2750, 1955, 4469, 3856 },
- { -5696, 1659, 6118, 2469 },
- { -4350, 1241, 6840, 3126 },
- { -5565, 5058, 5196, 1314 },
- { -1642, 4190, 3948, 607 },
- { -1233, 4108, 4850, -640 },
- { -997, 3428, 3239, 1378 },
- { -6488, 2741, 6926, 2792 },
- { -4188, 3763, 4235, 2018 },
- { -3210, 3224, 5646, 1427 },
- { -5526, 6909, 5070, -627 },
- { -2815, 3994, 3425, 1903 },
- { -2163, 2734, 5423, 145 },
- { -4149, 4247, 2355, 734 },
- { -410, 2521, 4138, -16 },
- { -2411, 2385, 4927, 2105 },
- { -6077, 3591, 3114, 594 },
- { -4186, 4834, 5926, -1004 },
- { -7315, 3369, 5966, 448 },
- { -7042, 5721, 5771, 238 },
- { -4466, 3907, 3535, -1751 },
- { -2116, 3970, 6163, -1392 },
- { -7239, 2143, 8407, 3630 },
- { -5431, 4486, 6486, -42 },
- { -1874, 1617, 6333, 519 },
- { -6478, 2629, 4634, -505 },
- { -7784, 2342, 7216, 1365 },
- { -1154, 1432, 4831, 1544 },
- { -4964, -5801, 1797, 506 },
- { -4436, -6905, 1059, -1237 },
- { -5400, -6886, 884, -290 },
- { -6259, -7103, 523, -227 },
- { -4819, -6450, 1412, -450 },
- { -4056, -6213, 1725, -943 },
- { -5642, -6091, 1357, 605 },
- { -4196, -5678, 2187, -173 },
- { -4726, -5126, 2470, 321 },
- { -6642, -5091, 1507, -1005 },
- { -5304, -5250, 1944, 1579 },
- { -7179, -5520, 1468, -425 },
- { -6033, -4895, 1876, -955 },
- { -6595, -5143, 2207, 1291 },
- { -4224, -4943, 1846, 1792 },
- { -7128, -6950, 539, 724 },
- { -4369, -4901, 2590, 1103 },
- { -7413, -5696, 1712, 1440 },
- { -5885, -6821, 418, 871 },
- { -6828, -5599, 710, -1563 },
- { -6123, -5817, 1358, 1631 },
- { -5291, -5622, 578, 2138 },
- { -7171, -6004, 347, 2208 },
- { -6083, -5251, 2132, 425 },
- { -4329, -5721, 407, -2993 },
- { -5326, -5056, 1119, -1837 },
- { -5485, -5856, 185, -2389 },
- { -6529, -5178, 403, -697 },
- { -6719, -4412, 2726, 871 },
- { -5126, -5629, 1835, -771 },
- { -5622, -4361, 2973, 858 },
- { -5282, -5895, 45, -335 },
- { -4357, -5656, 1696, -1558 },
- { -7139, -6659, 627, -409 },
- { -4415, -6328, 35, 1306 },
- { -7639, -6110, 1134, 197 },
- { -3626, -5592, 2019, 901 },
- { -3547, -5064, 1176, 1738 },
- { -5075, -3899, 2087, 266 },
- { -4086, -6311, 1479, 360 },
- { -6210, -5220, -199, -1477 },
- { -3910, -5063, 1356, -15 },
- { -7616, -4977, 461, 2401 },
- { -6118, -6131, 1258, -563 },
- { -6127, -4968, 1286, -27 },
- { -4121, -5852, 1113, 1476 },
- { -5157, -4881, 1162, -662 },
- { -4637, -5031, 1179, 709 },
- { -5509, -5452, -397, 1224 },
- { -4597, -6861, 646, 467 },
- { -6247, -4043, 468, 278 },
- { -5336, -6465, 874, -1472 },
- { -6998, -6346, 78, -1798 },
- { -4915, -4530, 2756, -203 },
- { -6048, -4373, 1468, 1052 },
- { -4273, -7100, 942, -323 },
- { -6552, -4287, 2351, 69 },
- { -6954, -4613, 722, 1521 },
- { -4201, -5361, 763, -1562 },
- { -6881, -5596, -748, 669 },
- { -6695, -3547, -34, 1299 },
- { -3981, -5728, 84, 111 },
- { -4663, -4809, 2173, -1031 },
- { -6599, -6077, 1303, 256 },
- { -7596, -4265, -5791, -4140 },
- { -6610, -2758, -5288, -3936 },
- { -5880, -3865, -6563, -3088 },
- { -7228, -5510, -7677, -3912 },
- { -8854, -6553, -8318, -5361 },
- { -9362, -5249, -6413, -4319 },
- { -4418, -3110, -6368, -4358 },
- { -5544, -4203, -6863, -5013 },
- { -3056, -4316, -5567, -3181 },
- { -3078, -5999, -5051, -2657 },
- { -5884, -6292, -5756, -4013 },
- { -4825, -4549, -5535, -4053 },
- { -4443, -6126, -5316, -1368 },
- { -3972, -6341, -6098, -2686 },
- { -5751, -2781, -5398, -6230 },
- { -4466, -6135, -5570, -3679 },
- { -4291, -5992, -3564, -5189 },
- { -7189, -4429, -7279, -6082 },
- { -5076, -4433, -2748, -5366 },
- { -6225, -2825, -6833, -5663 },
- { -2989, -4792, -3960, -4492 },
- { -7836, -7773, -7722, -5741 },
- { -6559, -5703, -5844, -5589 },
- { -7612, -5438, -4136, -3774 },
- { -4218, -4176, -6591, -2333 },
- { -4837, -5063, -6581, 322 },
- { -6590, -5990, -2980, -3847 },
- { -5558, -2971, -5489, -1932 },
- { -7001, -5323, -4975, -1697 },
- { -4694, -2688, -6904, -3044 },
- { -8511, -5379, -5767, -2549 },
- { -7548, -5412, -6522, -2572 },
- { -6597, -4973, -6423, -1274 },
- { -6415, -4022, -5168, -1072 },
- { -5528, -5530, -7218, -2345 },
- { -4845, -4805, -5943, -1227 },
- { -6049, -7150, -6744, -2161 },
- { -9061, -7299, -8542, -4375 },
- { -5010, -5546, -5416, -82 },
- { -4135, -4205, -5109, -3373 },
- { -3311, -5869, -4007, -5061 },
- { -5993, -6472, -3962, -4718 },
- { -2966, -5832, -2821, -6305 },
- { -4851, -5152, -2067, -3930 },
- { -3620, -4441, -3362, -5836 },
- { -4469, -5221, -4534, -5592 },
- { -4022, -6335, -4321, -6107 },
- { -4899, -4503, -3084, -3725 },
- { -4490, -8276, -4620, -6236 },
- { -6591, -4342, -7365, -4063 },
- { -6498, -5057, -5553, 485 },
- { -6060, -2714, -7093, -4144 },
- { -6199, -7774, -7094, -4057 },
- { -7536, -6424, -6415, -4265 },
- { -7439, -2454, -6348, -4827 },
- { -5333, -7565, -4417, -4639 },
- { -4353, -7103, -4197, -2689 },
- { -5229, -6549, -5129, -6804 },
- { -6129, -7701, -5236, -4836 },
- { -6797, -3983, -3884, -4406 },
- { -6624, -4467, -4745, -5052 },
- { -3324, -7596, -2720, -6553 },
- { -5473, -6284, -1704, -4511 },
- { -4131, -7263, -3180, -5196 },
- { -7116, -5565, -3469, 685 },
- { -6002, -6021, -3858, 576 },
- { -3144, -8203, -1291, -434 },
- { -6096, -7027, -4004, 1353 },
- { -3943, -7709, -2344, -36 },
- { -4510, -6767, -2642, 631 },
- { -3657, -11541, -2570, -3984 },
- { -5959, -8854, -1333, -867 },
- { -6699, -8866, -1606, -344 },
- { -3836, -7961, -2334, -2028 },
- { -3430, -8045, -3037, -672 },
- { -3868, -9184, -3635, -1819 },
- { -4258, -9060, -2621, -1008 },
- { -3595, -8693, -2022, -752 },
- { -4573, -8048, -3166, -2622 },
- { -4852, -7903, -1405, 256 },
- { -4591, -7057, -1560, 965 },
- { -6963, -7655, -980, 808 },
- { -5179, -6641, -3356, 1196 },
- { -7102, -6941, -2798, 2123 },
- { -6867, -5834, -3320, -770 },
- { -5977, -7369, -2500, -778 },
- { -6160, -6400, -934, -2543 },
- { -6741, -7608, -355, -1289 },
- { -6856, -6466, -1433, -1643 },
- { -4786, -6292, -4970, 376 },
- { -5407, -8866, -2255, -400 },
- { -3814, -6506, -1387, -3620 },
- { -4998, -6137, -1200, -4092 },
- { -5123, -9557, -2849, -1306 },
- { -4259, -6444, -4395, -338 },
- { -5221, -6810, -883, 1225 },
- { -6137, -6215, -2165, 554 },
- { -3895, -6557, -3176, -1829 },
- { -3886, -8188, -87, -954 },
- { -7243, -6707, -2216, -316 },
- { -5592, -7606, 85, -432 },
- { -3957, -7945, -504, -144 },
- { -4617, -7624, 218, -312 },
- { -4797, -8737, -844, -1051 },
- { -4478, -8516, -1401, -454 },
- { -4557, -7058, -302, -2332 },
- { -6623, -7736, -271, -50 },
- { -3157, -7532, -1111, -2207 },
- { -3590, -7300, -1271, 517 },
- { -4442, -7306, -507, 590 },
- { -6458, -7524, -2807, 666 },
- { -4991, -8466, -3363, -785 },
- { -7474, -7541, -1056, -1839 },
- { -7501, -8316, -938, -180 },
- { -5329, -7739, -579, -2341 },
- { -4549, -7063, -176, -3539 },
- { -5191, -8612, -1504, -4250 },
- { -3083, -7058, -2251, 32 },
- { -4003, -7043, -1093, -791 },
- { -5523, -8093, -678, -114 },
- { -3022, -10265, -2070, -3109 },
- { -3905, -6274, -182, -3652 },
- { -3269, -9217, -551, -2650 },
- { -3138, -9314, -1726, -1704 },
- { -4420, -10339, -1744, -3459 },
- { -4163, -8609, -2298, -4113 },
- { -5566, -6505, -1241, -463 },
- { -3130, -9746, -2352, -4884 },
- { -7825, -3439, 1451, -1468 },
- { -8451, -3318, 2360, -435 },
- { -8462, -4130, 1438, -1024 },
- { -9425, -4564, 1328, -689 },
- { -11014, -3202, 2278, 2080 },
- { -8269, -2761, -146, -440 },
- { -7497, -2618, -166, 413 },
- { -8250, -3060, 522, -2133 },
- { -8365, -5366, 1347, -451 },
- { -8589, -3979, 2943, 714 },
- { -8111, -2572, 1272, -1748 },
- { -7830, -5193, 605, -1484 },
- { -8119, -4736, 2141, 256 },
- { -7724, -4769, 1463, -812 },
- { -7363, -3911, 2540, 4 },
- { -7974, -3397, 2363, 1366 },
- { -7359, -4204, 1752, -958 },
- { -7622, -3505, 660, 916 },
- { -9934, -3665, 3165, 828 },
- { -8721, -4162, 62, 1718 },
- { -9433, -4768, 2722, 1234 },
- { -7960, -4496, 138, 1528 },
- { -8198, -3454, -443, 631 },
- { -7756, -2246, 655, 1137 },
- { -8841, -3145, 1113, 829 },
- { -7817, -3298, 1251, 230 },
- { -9413, -2733, 323, -1862 },
- { -9408, -4168, 1270, 1549 },
- { -9037, -3892, -942, 283 },
- { -8255, -3849, 1301, 1762 },
- { -9057, -3987, -41, -682 },
- { -9441, -4187, 2019, -111 },
- { -9740, -3178, 1602, -871 },
- { -8344, -2474, 1461, 1506 },
- { -9752, -2925, 1996, 1243 },
- { -9199, -3796, 180, 537 },
- { -9060, -2405, 1140, -1562 },
- { -9348, -2376, 309, -162 },
- { -10786, -3182, -5, -1500 },
- { -8142, -4540, -434, -826 },
- { -7528, -2341, 1104, -73 },
- { -9360, -2658, 3062, 56 },
- { -8267, -2335, 2000, -1193 },
- { -12169, -3154, 1287, -640 },
- { -11398, -2120, 946, -1163 },
- { -8940, -4559, 328, -1696 },
- { -11025, -4213, 2813, 840 },
- { -9224, -3581, 2224, 2039 },
- { -8943, -3337, 1248, -1298 },
- { -7900, -4042, 485, -2080 },
- { -9221, -1947, 2191, -880 },
- { -10762, -1800, 2516, -324 },
- { -10095, -2238, 981, -1335 },
- { -11908, -2808, 3255, 645 },
- { -10640, -4105, 1283, -595 },
- { -7663, -2863, 2467, -797 },
- { -10712, -3854, 3710, 1538 },
- { -10823, -2893, 1408, -801 },
- { -9874, -3832, 256, -1638 },
- { -10394, -3391, 2315, -94 },
- { -11525, -4079, 4153, 2122 },
- { -9546, -2088, 1541, 481 },
- { -8731, -2433, 1042, 2160 },
- { -7852, -3977, -1370, 1677 },
- { 7072, -3420, 1398, -1741 },
- { 6180, -1976, 1280, -3557 },
- { 7692, -1793, 2844, -1700 },
- { 8363, -1773, 3104, -2679 },
- { 9213, -3266, 3756, -3542 },
- { 9650, -2644, 1426, -1318 },
- { 7712, -2796, 3686, -1975 },
- { 7316, -3517, 2821, -622 },
- { 7434, -2594, 2305, -2264 },
- { 7237, -1797, 255, -3114 },
- { 8663, -1983, 1338, -3056 },
- { 6616, -952, 4059, -2652 },
- { 8823, -1327, 1362, -1356 },
- { 9938, -1722, 1287, -2362 },
- { 7207, -1057, 1913, -1315 },
- { 7508, -1585, 870, -1982 },
- { 8217, -3680, 1417, -3170 },
- { 8329, -2541, 1684, -585 },
- { 8062, -2335, 252, -2800 },
- { 8204, -4108, 3097, -2569 },
- { 7701, -3367, 576, -3008 },
- { 7350, -786, 2414, -2129 },
- { 6948, -2568, 1607, -225 },
- { 7684, -2387, 1308, -3449 },
- { 8306, -3458, 2394, -1454 },
- { 8438, -2781, 1043, -1362 },
- { 9175, -2076, 2144, -1987 },
- { 8347, -2709, 3489, -4301 },
- { 5696, -2377, 2870, 851 },
- { 8825, -1243, 2219, -2603 },
- { 8801, -1614, 584, -2513 },
- { 8413, -384, 1421, -2244 },
- { 9228, -3050, 3279, -2164 },
- { 6342, -2698, 3547, -107 },
- { 10053, -2476, 2837, -3168 },
- { 7439, -604, 3177, -3991 },
- { 7749, -1064, 4329, -4855 },
- { 8655, -2177, 2252, -3519 },
- { 8490, -228, 1958, -3233 },
- { 10513, -2968, 1911, -2340 },
- { 8146, -862, 1884, -1723 },
- { 7788, -666, 3004, -2891 },
- { 7785, -1620, 4133, -3417 },
- { 10262, -3731, 3455, -2971 },
- { 8570, -905, 4519, -4649 },
- { 9129, -2562, 463, -2465 },
- { 9451, -3587, 1904, -3056 },
- { 6549, -2236, 3010, -4523 },
- { 7175, -2684, 2967, -3458 },
- { 9872, -3278, 1054, -2472 },
- { 9153, -931, 1217, -2565 },
- { 8789, -3469, 753, -2568 },
- { 6683, -3791, 1797, -3968 },
- { 6801, -1977, 2311, -452 },
- { 6336, -1572, 2612, -3264 },
- { 7996, -1008, 730, -2964 },
- { 7521, -1059, 1573, -3694 },
- { 8148, -3973, 2600, -3572 },
- { 7765, -1532, 2528, -3856 },
- { 7404, -3918, 4472, -143 },
- { 8894, -1398, 3299, -3685 },
- { 5768, -2041, 1487, -637 },
- { 5131, -2865, 2463, -811 },
- { 6439, -1568, 3500, -1550 },
- { -8878, -6798, -5319, -1452 },
- { -6332, -9713, -3112, -990 },
- { -8444, -6316, -3694, -687 },
- { -6123, -10840, -3637, -4358 },
- { -4784, -9580, -4577, -2581 },
- { -6108, -10515, -4859, -2524 },
- { -7605, -7518, -2327, -2797 },
- { -9662, -8775, -2467, -2010 },
- { -6494, -7523, -4715, -118 },
- { -8290, -8982, -1672, -317 },
- { -8798, -11051, -3888, -1426 },
- { -6273, -6623, -6791, -142 },
- { -8313, -7668, -2141, -1275 },
- { -6453, -8412, -3589, -4102 },
- { -6747, -7750, -5690, -2498 },
- { -7814, -6693, -3174, -2446 },
- { -10383, -10130, -3931, -2364 },
- { -10606, -8467, -5539, -2772 },
- { -9475, -6671, -3305, -2271 },
- { -8982, -9457, -5635, -4005 },
- { -10111, -7965, -6515, -4180 },
- { -7301, -6479, -5364, 720 },
- { -9543, -8999, -7921, -912 },
- { -9534, -8562, -3469, -384 },
- { -7601, -10344, -3205, -1127 },
- { -8088, -8620, -4954, -2888 },
- { -8202, -8406, -7038, -3775 },
- { -7312, -8324, -3334, -1775 },
- { -8566, -9262, -8071, -4174 },
- { -7068, -11300, -5573, -2907 },
- { -8295, -8952, -4366, -1544 },
- { -11104, -10210, -2285, -384 },
- { -5213, -7520, -5008, -1339 },
- { -5889, -7940, -5987, -1385 },
- { -10816, -8201, -4153, -1485 },
- { -10277, -8919, -6315, -1652 },
- { -5888, -10320, -3821, -1733 },
- { -10497, -7181, -6083, -3032 },
- { -7721, -9724, -6591, -5336 },
- { -5688, -7894, -3486, -2552 },
- { -10014, -10500, -3247, -820 },
- { -6301, -8765, -4506, -2923 },
- { -8261, -7847, -6213, -1552 },
- { -10212, -7481, -8113, -3954 },
- { -6938, -10874, -6074, -4703 },
- { -7183, -10968, -4446, -1773 },
- { -7120, -9193, -1966, -2509 },
- { -6234, -9263, -2313, -4284 },
- { -8503, -9857, -2429, -608 },
- { -9372, -7844, -8391, -2120 },
- { -7951, -7157, -6535, -11 },
- { -7256, -9473, -2172, -660 },
- { -10063, -9612, -2515, -15 },
- { -6684, -9134, -6109, -4206 },
- { -8204, -11932, -5220, -2306 },
- { -9710, -6706, -4115, -3275 },
- { -6855, -7078, -2409, -4447 },
- { -7344, -7673, -4479, -4116 },
- { -8851, -6842, -4927, -2948 },
- { -8927, -10452, -5633, -2194 },
- { -8627, -9002, -7176, -1575 },
- { -8209, -9722, -7021, -3324 },
- { -3770, -10249, -3623, -4816 },
- { -8183, -7465, -4090, 646 },
- { -8163, -7149, 200, 498 },
- { -8289, -6266, 686, -206 },
- { -10030, -6241, -1032, -1864 },
- { -8793, -8327, -773, -169 },
- { -9149, -6215, 969, -15 },
- { -8303, -5859, -7, 2006 },
- { -9682, -7283, 255, 1322 },
- { -9293, -7227, 71, -231 },
- { -8525, -6215, 287, -837 },
- { -10477, -5379, 1159, 1449 },
- { -10726, -7856, -130, 102 },
- { -8694, -7461, -1210, 690 },
- { -9367, -5324, 1103, 3170 },
- { -10686, -8055, -831, 1633 },
- { -9201, -6873, -2704, 2258 },
- { -8421, -5358, -1405, 226 },
- { -9066, -5830, -307, -1571 },
- { -11150, -7381, -2746, -900 },
- { -9978, -5925, -2006, -437 },
- { -9464, -4741, -273, 1061 },
- { -10543, -6684, -1113, 1660 },
- { -10073, -5576, 1083, -269 },
- { -8826, -5763, 1600, 1486 },
- { -10445, -9071, -1253, -64 },
- { -12085, -5799, 2, 769 },
- { -12939, -6663, 1650, 1437 },
- { -10932, -6434, -1252, -649 },
- { -11650, -7826, -2053, 710 },
- { -12122, -6733, -1889, -731 },
- { -9093, -6095, -2463, -842 },
- { -10977, -4364, 469, 420 },
- { -11488, -6908, -521, 893 },
- { -9669, -5478, -842, 337 },
- { -10606, -5203, -632, -1361 },
- { -10198, -6284, 1662, 1277 },
- { -10135, -5292, 2435, 3493 },
- { -11027, -6561, 655, 56 },
- { -10977, -5030, 1127, -358 },
- { -12766, -3986, 1348, -335 },
- { -14244, -7731, 264, 317 },
- { -15124, -10309, -508, 1447 },
- { -12821, -8638, -608, 137 },
- { -13076, -8693, -2852, -431 },
- { -11156, -5546, -2252, -1600 },
- { -8692, -7366, -819, -1223 },
- { -12507, -9816, -1714, -121 },
- { -10712, -6666, 544, 3349 },
- { -12462, -5890, -2491, -2318 },
- { -12468, -7226, 437, 232 },
- { -11300, -5226, 2068, 687 },
- { -11994, -8320, -626, 2728 },
- { -12222, -5476, 1142, 18 },
- { -10277, -8122, -2418, 2003 },
- { -13418, -6115, -3563, -2802 },
- { -14759, -9834, -1243, 21 },
- { -13699, -5665, 1525, 507 },
- { -16269, -9476, -701, 163 },
- { -12677, -5437, -247, -1019 },
- { -11827, -4295, -181, -1243 },
- { -12847, -4496, 2984, 1123 },
- { -13860, -7915, -1166, -547 },
- { -12276, -8145, -2290, -1527 },
- { -11417, -4830, 2983, 1854 },
- { -11793, -6002, 1163, 1940 },
- { 11443, -4920, -3235, 3151 },
- { 11300, -6616, -1506, 1175 },
- { 9198, -4628, -2060, 2390 },
- { 10532, -4027, -643, 912 },
- { 9902, -3573, -1606, 1327 },
- { 9653, -3536, -2240, 1869 },
- { 9948, -5171, -423, 2662 },
- { 12316, -4004, -1989, 281 },
- { 12125, -4800, -1265, -163 },
- { 10650, -2617, -2337, 1462 },
- { 9909, -4968, -2376, 916 },
- { 12944, -4647, -1958, 460 },
- { 12988, -5283, -1141, 41 },
- { 12321, -2915, -3621, 1025 },
- { 11449, -2894, -2728, 351 },
- { 12087, -3041, -2002, -32 },
- { 11558, -4031, -1343, -399 },
- { 12983, -3740, -3516, 1245 },
- { 12099, -2515, -2752, 225 },
- { 12515, -3465, -2701, 550 },
- { 14683, -5022, -5272, 2996 },
- { 12260, -3383, -1215, -528 },
- { 13810, -5422, -2443, 1166 },
- { 13421, -5378, -1886, 721 },
- { 12961, -4259, -2594, 796 },
- { 12266, -2104, -4768, 1591 },
- { 13523, -4710, -3045, 1342 },
- { 12437, -2099, -5610, 2117 },
- { 11850, -2183, -3497, 661 },
- { 12275, -3936, -597, -697 },
- { 12459, -5253, -517, -544 },
- { 12835, -4094, -1322, -168 },
- { 14360, -5677, -3305, 1859 },
- { 13905, -4552, -4309, 2117 },
- { 11559, -3412, -1847, -81 },
- { 13379, -3167, -5764, 2746 },
- { 11910, -1634, -4342, 1052 },
- { 12662, -4742, 71, -974 },
- { 13057, -3254, -4424, 1705 },
- { 15046, -5706, -4851, 3019 },
- { 14162, -4142, -5514, 2843 },
- { 12764, -1845, -6684, 2888 },
- { 13714, -2374, -7838, 3857 },
- { 13295, -1663, -8293, 4073 },
- { 10032, -4152, -3403, 1421 },
- { 10942, -5386, -2222, 950 },
- { 10532, -6385, -1750, 1925 },
- { 10273, -5972, -1534, 643 },
- { 10605, -4782, -1695, 27 },
- { 10988, -5153, -1123, -341 },
- { 11629, -5884, -1060, 48 },
- { 10441, -4045, -2431, 311 },
- { 10788, -3595, -4171, 1807 },
- { 12110, -5686, -2127, 976 },
- { 11746, -4773, -2639, 891 },
- { 11541, -5299, -3031, 1732 },
- { 11416, -2559, -5359, 2198 },
- { 11583, -5376, -704, 677 },
- { 10416, -3214, -3516, 872 },
- { 9651, -5435, -1618, 3255 },
- { 9973, -5133, -996, 3923 },
- { 11707, -4643, -430, -796 },
- { 10994, -2709, -3587, 2302 },
- { 10716, -5118, -645, 270 },
- { 14100, -10314, 1095, 1531 },
- { 12944, -8049, 1105, -741 },
- { 13276, -7035, -511, 274 },
- { 14008, -7254, -283, 139 },
- { 11594, -6536, -91, 1671 },
- { 11732, -8645, 746, 15 },
- { 14613, -7085, -1578, 1183 },
- { 13083, -6224, -750, -4 },
- { 13988, -6256, -1592, 820 },
- { 14678, -8683, 441, 126 },
- { 15571, -8872, -521, 1139 },
- { 15642, -9533, 341, 697 },
- { 15960, -9586, -168, 1121 },
- { 15464, -10239, 1433, -1 },
- { 14934, -7887, -1046, 1080 },
- { 15252, -7630, -1899, 1628 },
- { 15485, -8384, -1234, 1484 },
- { 15962, -8638, -1815, 1931 },
- { 16501, -10664, 398, 1167 },
- { 16146, -10145, 411, 918 },
- { 14573, -7475, -697, 601 },
- { 14302, -7996, 28, 257 },
- { 14769, -6792, -2286, 1574 },
- { 14144, -6137, -2169, 1257 },
- { 14770, -6271, -3111, 1933 },
- { 14110, -8312, 1083, -531 },
- { 15235, -6991, -2993, 2174 },
- { 13222, -5805, 547, -891 },
- { 14796, -8762, 1254, -246 },
- { 16040, -9181, -1005, 1551 },
- { 16487, -10086, -373, 1420 },
- { 15077, -9479, 966, 51 },
- { 13026, -6468, 932, -1080 },
- { 12703, -6152, -33, -573 },
- { 15641, -6810, -4128, 2874 },
- { 13282, -7673, 1583, -1283 },
- { 12373, -7150, 1512, -917 },
- { 12992, -7751, -678, 783 },
- { 10907, -6858, -313, 2597 },
- { 13026, -8963, 125, 2152 },
- { 12770, -9946, 1957, -505 },
- { 12482, -6849, -1268, 833 },
- { 13790, -6181, -138, -279 },
- { 12709, -8382, 2044, 227 },
- { 12244, -6630, 203, -457 },
- { 14209, -6816, -1032, 632 },
- { 15134, -8267, -288, 640 },
- { 13619, -6157, -1090, 356 },
- { 14044, -7413, 725, -484 },
- { 12958, -7753, 2585, -1980 },
- { 13188, -8396, 2306, -1558 },
- { 14379, -9980, 2132, -688 },
- { 14275, -9857, 1162, 179 },
- { 13690, -8648, 1621, -889 },
- { 11770, -6829, -746, 278 },
- { 12732, -8202, 286, 90 },
- { 13630, -10146, 1867, -207 },
- { 12072, -8740, 1299, -645 },
- { 12852, -9492, 1226, 62 },
- { 11792, -7382, -54, -116 },
- { 13779, -9014, 487, 351 },
- { 11951, -7729, 121, 834 },
- { 11970, -9781, 2276, -4 },
- { 12680, -7984, 2787, -787 },
- { 13300, -14488, 6408, -1927 },
- { 13635, -15355, 9153, -3073 },
- { 12804, -13566, 5517, -1625 },
- { 16624, -10854, 1690, 28 },
- { 20387, -18532, 6162, -261 },
- { 16515, -12642, 3392, -519 },
- { 15800, -11095, 2151, -202 },
- { 16824, -11790, 1651, 599 },
- { 17604, -13213, 2563, 538 },
- { 17892, -14177, 3562, 147 },
- { 16987, -11399, 869, 1052 },
- { 17003, -12456, 2442, 265 },
- { 21657, -21806, 9198, -1250 },
- { 16825, -13341, 3980, -686 },
- { 17525, -12714, 1887, 805 },
- { 16419, -11034, 1216, 617 },
- { 20931, -19939, 7469, -684 },
- { 18452, -15390, 4573, -191 },
- { 14778, -10077, 2841, -1209 },
- { 17402, -13319, 3042, 160 },
- { 19365, -17922, 7087, -1061 },
- { 16298, -11941, 2810, -351 },
- { 19087, -16176, 4775, -84 },
- { 17666, -12289, 938, 1224 },
- { 18581, -15894, 5132, -430 },
- { 19823, -16717, 4142, 545 },
- { 19960, -19423, 8400, -1492 },
- { 18973, -16817, 5906, -594 },
- { 19079, -15431, 3528, 503 },
- { 16667, -12485, 4467, -1302 },
- { 19791, -17797, 6196, -529 },
- { 20005, -17606, 5354, -20 },
- { 20123, -18599, 6886, -728 },
- { 19068, -14805, 2394, 1105 },
- { 14443, -13723, 5631, -2029 },
- { 14730, -14231, 5631, -1450 },
- { 16089, -15959, 7271, -2029 },
- { 13473, -11200, 3236, -924 },
- { 14413, -10902, 2347, -267 },
- { 17666, -18662, 11381, -3496 },
- { 14749, -11042, 3305, -275 },
- { 15304, -10486, 1869, -240 },
- { 14809, -12126, 3369, -616 },
- { 16896, -16561, 7307, -1845 },
- { 15782, -14336, 5380, -1264 },
- { 16395, -15520, 6415, -1588 },
- { 13681, -11114, 2584, -320 },
- { 14244, -12326, 4480, -1632 },
- { 15247, -13119, 4265, -898 },
- { 13987, -12091, 3469, -597 },
- { 13941, -12770, 4240, -839 },
- { 13771, -13627, 5252, -1384 },
- { 15010, -16074, 7592, -2249 },
- { 15852, -17226, 8619, -2655 },
- { 18921, -16916, 6875, -1501 },
- { 14909, -11678, 2768, -295 },
- { 18988, -18353, 8424, -2070 },
- { 15457, -15080, 6218, -1513 },
- { 14916, -15512, 6949, -1883 },
- { 18108, -14702, 4681, -701 },
- { 17600, -15733, 5616, -775 },
- { 14070, -13683, 6472, -2626 },
- { 13832, -11914, 5201, -2232 },
- { 18846, -19009, 9192, -1961 },
- { -11981, -10994, -6324, -2264 },
- { -10976, -9047, -6546, -3828 },
- { -11288, -10532, -7014, -4191 },
- { -10139, -10189, -7799, -2688 },
- { -10555, -9988, -9181, -2040 },
- { -11596, -11339, -10022, -2707 },
- { -13400, -13395, -11306, -4206 },
- { -9774, -12281, -7466, -4133 },
- { -10842, -13125, -8777, -4956 },
- { -11964, -15082, -9779, -5095 },
- { -9382, -10188, -9053, -4927 },
- { -11562, -11296, -3651, -985 },
- { -9287, -10083, -7918, -4069 },
- { -12821, -16556, -11410, -6195 },
- { -12628, -8959, -4521, -1113 },
- { -13845, -11581, -3649, -681 },
- { -12685, -10269, -5483, -1275 },
- { -14988, -12874, -5107, -1189 },
- { -13761, -11367, -6202, -1804 },
- { -13225, -11249, -7820, -3354 },
- { -14809, -11992, -3202, -312 },
- { -15620, -15519, -10210, -3433 },
- { -12954, -10200, -3139, -611 },
- { -11536, -9981, -5284, -923 },
- { -13034, -12417, -4612, -1098 },
- { -16911, -15505, -6123, -1352 },
- { -17396, -17685, -8330, -2171 },
- { -14120, -10764, -2265, -99 },
- { -12598, -7367, -5406, -3530 },
- { -14143, -12793, -10909, -5226 },
- { -14692, -16871, -11626, -5554 },
- { -12581, -11197, -9194, -3837 },
- { -16752, -16726, -9746, -2808 },
- { -10600, -10358, -6560, -1227 },
- { -14573, -13312, -8957, -3393 },
- { -10172, -8463, -8579, -3387 },
- { -11418, -12421, -5522, -1842 },
- { -11855, -14204, -6669, -2625 },
- { -13308, -8191, -3941, -2194 },
- { -10007, -12266, -5022, -1811 },
- { -13532, -15771, -9497, -3175 },
- { -11760, -11148, -10339, -5529 },
- { -12149, -12763, -11198, -3697 },
- { -12029, -12119, -8555, -1792 },
- { -16995, -19957, -11447, -3471 },
- { -13144, -14504, -9988, -3191 },
- { -9938, -11064, -6139, -3162 },
- { -8873, -11550, -8294, -6550 },
- { -9303, -13010, -6150, -2711 },
- { -15463, -10469, -1766, -170 },
- { -15985, -11693, -3007, -650 },
- { -17142, -10671, -1434, 47 },
- { -16063, -13858, -4817, -1058 },
- { -19446, -19599, -9594, -2464 },
- { -20076, -18744, -8313, -1889 },
- { -15047, -16085, -7590, -2250 },
- { -13481, -16195, -8552, -2998 },
- { -13829, -14869, -6704, -1932 },
- { -16357, -18484, -9802, -2959 },
- { -10551, -8393, -9303, -5070 },
- { -11345, -9156, -5641, -3107 },
- { -13217, -13449, -9270, -4541 },
- { -11988, -13732, -9995, -6374 },
- { -11007, -9519, -5168, -4107 },
- { 9930, -7858, 8061, -4375 },
- { 8274, -7867, 5992, -2096 },
- { 9692, -9675, 7621, -3670 },
- { 9589, -8110, 6509, -3010 },
- { 12617, -11976, 10122, -5360 },
- { 11867, -8895, 7948, -5323 },
- { 10388, -10482, 9234, -4324 },
- { 8188, -8220, 7810, -2737 },
- { 10407, -8787, 4806, -1930 },
- { 10348, -8845, 9233, -6614 },
- { 9422, -7091, 4820, -2878 },
- { 9758, -9796, 5584, -2256 },
- { 10188, -7994, 5347, -3343 },
- { 11133, -7455, 4015, -2306 },
- { 10676, -10744, 6093, -2629 },
- { 11522, -12184, 7848, -3375 },
- { 8805, -9883, 5317, -3071 },
- { 9498, -9654, 6555, -3592 },
- { 10488, -8008, 4066, -1252 },
- { 11261, -8930, 6068, -2738 },
- { 12180, -10397, 5027, -1531 },
- { 9138, -8531, 3601, -1959 },
- { 8107, -8380, 4970, -2061 },
- { 9737, -13248, 6438, -2617 },
- { 11178, -10423, 2622, -522 },
- { 9572, -12372, 5199, -2019 },
- { 12057, -12144, 4147, -1099 },
- { 9047, -9925, 2516, -665 },
- { 10790, -8030, 5882, -4386 },
- { 7199, -8426, 6337, -2841 },
- { 7778, -8285, 3529, -3442 },
- { 7559, -10569, 3484, -1332 },
- { 9404, -8115, 7484, -5541 },
- { 7792, -11976, 5546, -2573 },
- { 9313, -10264, 7661, -5195 },
- { 6701, -10725, 4370, -1784 },
- { 4918, -11361, 4507, -4527 },
- { 5147, -12305, 3978, -5556 },
- { 6525, -9899, 4481, -3129 },
- { 7538, -12855, 6060, -4826 },
- { 8659, -12111, 7159, -4430 },
- { 8440, -11304, 4547, -1747 },
- { 9216, -10918, 3507, -1195 },
- { 6165, -9254, 4771, -4677 },
- { 9163, -11019, 5637, -4935 },
- { 13441, -11509, 6676, -2434 },
- { 7912, -9398, 6663, -4048 },
- { 11723, -13745, 8131, -4148 },
- { 6065, -10257, 5005, -6327 },
- { 11618, -12417, 5336, -1894 },
- { 8891, -13924, 8407, -6131 },
- { 9622, -12563, 7908, -5109 },
- { 11479, -10315, 8349, -3991 },
- { 11676, -14103, 6611, -2330 },
- { 11951, -8953, 3829, -1550 },
- { 10486, -8044, 10493, -5920 },
- { 11801, -10769, 9763, -5305 },
- { 6109, -8676, 5827, -1346 },
- { 7030, -9611, 5624, -5761 },
- { 12808, -12886, 8683, -4148 },
- { 13213, -10464, 6381, -3189 },
- { 11796, -13681, 10703, -6075 },
- { 9639, -7949, 9625, -3944 },
- { 8538, -6997, 5309, 453 }
+static const int16_t adpcm_vb[4096][4] = {
+ { 9928, -2618, -1093, -1263 },
+ { 11077, -2876, -1747, -308 },
+ { 10503, -1082, -1426, -1167 },
+ { 9337, -2403, -1495, 274 },
+ { 10698, -2529, -532, -1122 },
+ { 10368, -3974, -1264, -750 },
+ { 10070, -3667, 346, 863 },
+ { 10278, -3093, 311, -576 },
+ { 9894, -1330, -1428, -860 },
+ { 10544, -1923, -1058, -971 },
+ { 10996, -1632, -841, -1404 },
+ { 11832, -3465, 1658, -1990 },
+ { 10852, -688, -2658, -499 },
+ { 10546, -1749, -147, -1733 },
+ { 10801, -1004, -708, -1453 },
+ { 10588, -441, -2113, -952 },
+ { 10141, -3331, -582, -1432 },
+ { 9608, -2590, 383, 258 },
+ { 11422, -3265, 229, -1544 },
+ { 10460, -1338, -713, -1568 },
+ { 10306, -1721, -1660, -603 },
+ { 9580, -1812, -1235, -1061 },
+ { 11471, -2285, -1617, -607 },
+ { 10081, -2225, -1408, -868 },
+ { 10715, -2624, -1367, -704 },
+ { 10616, -1871, -2770, -35 },
+ { 9352, -2340, -1024, -1566 },
+ { 11065, -1458, -1926, -735 },
+ { 11334, -2056, -1041, -1144 },
+ { 9825, -2048, -794, -1536 },
+ { 11850, -2695, -1123, -867 },
+ { 10654, -2226, -1891, -373 },
+ { 10024, -1557, -808, -1069 },
+ { 11142, -1266, -3238, 128 },
+ { 11729, -3282, -514, -1011 },
+ { 11402, -2094, -2335, -189 },
+ { 10195, -3658, 181, -1875 },
+ { 11431, -2626, -404, -1377 },
+ { 11001, -3868, -619, -1077 },
+ { 10894, -2559, 274, -1758 },
+ { 9633, -1482, -2253, -773 },
+ { 11245, -3321, 830, -1972 },
+ { 9768, -2701, -199, -1859 },
+ { 10500, -2042, 525, -2043 },
+ { 11669, -4069, 293, -1468 },
+ { 9192, -1991, -583, -61 },
+ { 10057, -3220, -2015, -473 },
+ { 9497, -2315, -2490, -467 },
+ { 10455, -3069, -1194, -1007 },
+ { 9994, -1936, -60, -1225 },
+ { 9295, -2156, -1761, -1134 },
+ { 10085, -3748, -1026, 197 },
+ { 9334, -2360, 804, -351 },
+ { 11561, -2553, 1352, -2313 },
+ { 12837, -3998, 1195, -1958 },
+ { 10114, -1100, -2414, -394 },
+ { 9341, -2530, 315, 755 },
+ { 10131, -3164, 1411, -674 },
+ { 9535, -905, -1551, 579 },
+ { 11717, -1519, -3051, 91 },
+ { 9824, -2911, -2775, 192 },
+ { 9662, -2934, -561, 1450 },
+ { 11085, -3392, -1298, -659 },
+ { 8955, -2102, -1899, 703 },
+ { 8607, -1742, -4348, 814 },
+ { 7640, -2063, -3617, 52 },
+ { 7074, -826, -4325, 4375 },
+ { 7714, 584, -4238, 1927 },
+ { 6355, -952, -4912, 3127 },
+ { 7069, -660, -6413, 4087 },
+ { 8313, -132, -2964, -876 },
+ { 6952, -1422, -3962, -24 },
+ { 9299, -734, -3088, -263 },
+ { 9484, -574, -4513, 466 },
+ { 7246, -91, -3735, -704 },
+ { 8325, -1417, -3090, -530 },
+ { 6469, -1226, -4757, 829 },
+ { 6652, -368, -5682, 1393 },
+ { 7971, -1278, -2284, 1205 },
+ { 7229, -699, -3556, 1840 },
+ { 7994, 1284, -2729, 732 },
+ { 9005, -698, -4522, 2189 },
+ { 6963, 197, -2727, 380 },
+ { 8527, 135, -3991, -213 },
+ { 8840, 934, -3014, -567 },
+ { 10125, 418, -3284, -371 },
+ { 6367, 361, -2318, 2554 },
+ { 7892, 172, -5247, 4673 },
+ { 6674, 387, -5424, 4398 },
+ { 6240, 684, -4047, 1219 },
+ { 11170, -794, -5081, 1195 },
+ { 11765, -648, -6265, 2052 },
+ { 10845, -775, -3837, 366 },
+ { 12496, -689, -8260, 3562 },
+ { 7893, -1166, -4972, 988 },
+ { 8592, 1052, -5986, 3087 },
+ { 7277, 1874, -5685, 3579 },
+ { 6900, 2016, -4809, 3491 },
+ { 8530, -2405, -3250, 1986 },
+ { 9426, 494, -7067, 5038 },
+ { 10285, 564, -8210, 5370 },
+ { 8749, -2207, -3980, 2852 },
+ { 9653, -2686, -4300, 1400 },
+ { 9770, -2286, -5663, 4233 },
+ { 8490, -4, -7048, 4496 },
+ { 7697, -1209, -5328, 3183 },
+ { 6451, 801, -4324, -554 },
+ { 7387, 1806, -5265, 545 },
+ { 7450, -2302, -4445, 1418 },
+ { 8817, -1370, -5827, 2168 },
+ { 10324, -2406, -5629, 2579 },
+ { 8863, -2578, -3537, 467 },
+ { 6901, -1624, -3169, 3392 },
+ { 7846, 156, -6948, 3381 },
+ { 7928, -1115, -5972, 4816 },
+ { 6089, -599, -4368, -320 },
+ { 7833, 1246, -3960, -621 },
+ { 8931, 2521, -6768, 2052 },
+ { 8900, 1944, -4126, 40 },
+ { 7661, -34, -2855, 2480 },
+ { 5873, 474, -3262, 3712 },
+ { 7535, -234, -4699, 216 },
+ { 5856, 143, -5142, 73 },
+ { 8944, -106, -5874, 3663 },
+ { 7134, 426, -5879, 2895 },
+ { 10199, 1011, -4762, 369 },
+ { 8454, 264, -5971, 1291 },
+ { 7822, -2449, -4333, 4540 },
+ { 6200, -2758, -2632, 1497 },
+ { 6070, -4315, -2699, 414 },
+ { 7047, -3739, -3210, 1060 },
+ { 5675, -3801, -2717, -407 },
+ { 4789, -4063, -2628, -744 },
+ { 4023, -3366, -3133, -726 },
+ { 4296, -2407, -3381, -513 },
+ { 4388, -2931, -2820, 1512 },
+ { 4559, -4233, -1941, 1976 },
+ { 6702, -3208, -1755, 1680 },
+ { 4416, -3521, -1052, 2984 },
+ { 7154, -4266, -1203, 3732 },
+ { 3625, -4242, -3244, 1395 },
+ { 6518, -2856, -1304, 2887 },
+ { 6170, -1949, -3014, 3973 },
+ { 5189, -2451, -4020, 3477 },
+ { 6218, -2988, -1921, 3844 },
+ { 4827, -3688, -1928, 3343 },
+ { 6668, -3991, -2805, 3095 },
+ { 5297, -3115, -3684, 2390 },
+ { 5354, -4614, -2662, 1504 },
+ { 4196, -3091, -4147, 1135 },
+ { 3540, -2893, -4007, 100 },
+ { 5569, -1602, -4007, 1909 },
+ { 4341, -2091, -4272, 252 },
+ { 5559, -2878, -3832, 498 },
+ { 4548, -4479, -2898, -27 },
+ { 5176, -2494, -4635, 1476 },
+ { 3294, -3485, -3738, 716 },
+ { 4920, -1229, -4195, -365 },
+ { 3257, -3518, -3349, 2862 },
+ { 5286, -1948, -3485, -778 },
+ { 6502, -3051, -152, 2854 },
+ { 5864, -4192, -1076, 3451 },
+ { 4656, -3122, -3448, 179 },
+ { 5907, -754, -1596, 3116 },
+ { 7229, -3680, -1590, 2892 },
+ { 5107, -3888, -3364, 806 },
+ { 6764, -2635, -3450, 134 },
+ { 5258, -2827, -2844, -1052 },
+ { 5798, -1725, -4305, 205 },
+ { 5404, -1213, -3362, 449 },
+ { 6224, -2738, -3046, -581 },
+ { 4223, -2438, -2725, 3745 },
+ { 4751, -3411, -2123, 116 },
+ { 3868, -3000, -3954, 2297 },
+ { 6819, -2899, -4277, 2825 },
+ { 4207, -4754, -2808, 865 },
+ { 4804, -1494, -1997, 4688 },
+ { 5282, -2213, -548, 3559 },
+ { 5580, -1912, -566, 4370 },
+ { 6168, -2857, -672, 4053 },
+ { 6583, -4515, -2850, 1670 },
+ { 6511, -3093, -3988, 1421 },
+ { 4646, -1790, -1443, 3650 },
+ { 5915, -924, -2020, 896 },
+ { 7814, -4181, -3152, 2007 },
+ { 6190, -2238, -4817, 2279 },
+ { 4737, -4034, -3288, 1835 },
+ { 8161, -3633, -3423, 3137 },
+ { 7415, -2351, -2088, 4290 },
+ { 4106, -2517, -62, 2905 },
+ { 4909, -3145, -614, 4112 },
+ { 4938, -3281, -397, 1100 },
+ { -173, 919, 1589, -5363 },
+ { -13, 796, -295, -6655 },
+ { -1860, -829, 1141, -4555 },
+ { 2298, -838, -664, -5005 },
+ { -884, -1097, 2074, -4613 },
+ { -101, 281, 2846, -4535 },
+ { 1166, 453, 2429, -5910 },
+ { 879, -664, 2370, -5452 },
+ { 1415, -370, -1699, -4727 },
+ { -1413, 1277, -669, -6649 },
+ { 2133, 304, -968, -4624 },
+ { 380, 586, -2087, -4892 },
+ { 1336, 275, -82, -5789 },
+ { -2459, 1057, -34, -5416 },
+ { 2278, -1758, 866, -5653 },
+ { 1945, -2295, -149, -5302 },
+ { 1287, -3525, 996, -5255 },
+ { 2297, 803, 1177, -6067 },
+ { 187, -180, -619, -6202 },
+ { -793, -2537, 1554, -5057 },
+ { -2703, -204, -629, -5853 },
+ { -1007, -146, 313, -5582 },
+ { 830, 357, 869, -6363 },
+ { -228, -575, -3177, -4433 },
+ { -1001, -1553, -142, -5708 },
+ { -1644, 1683, 1721, -4533 },
+ { 893, 1924, -15, -5791 },
+ { 2195, 2061, -262, -5471 },
+ { 3031, 270, 311, -5096 },
+ { 1912, 1638, -1523, -4677 },
+ { -3142, -55, 253, -4914 },
+ { 356, -1680, 343, -6123 },
+ { -2241, -1734, -976, -5939 },
+ { -2196, -2893, 547, -4938 },
+ { -1245, 126, -1916, -5419 },
+ { -249, -3755, -1422, -5594 },
+ { 575, -2683, -1926, -4566 },
+ { -762, 1885, 192, -5880 },
+ { -811, -2562, -1068, -6013 },
+ { -2264, -3086, -976, -4775 },
+ { 70, -1215, 2880, -4410 },
+ { 714, -3760, 2916, -4691 },
+ { -244, -3404, 1740, -4493 },
+ { 684, -5137, -328, -5608 },
+ { -529, -3825, -1786, -4535 },
+ { -713, -4743, -1118, -5546 },
+ { 2718, -3788, 1798, -5708 },
+ { -1639, -3679, -1564, -6095 },
+ { 1693, -2642, -1389, -4539 },
+ { 505, -1573, -1651, -4878 },
+ { -835, -2256, -1941, -5352 },
+ { 1464, -411, 1993, -6441 },
+ { 493, -3184, -145, -6148 },
+ { -1413, 499, -1617, -6479 },
+ { -294, 1722, -1419, -5725 },
+ { -2937, -1528, -175, -4624 },
+ { -594, -5911, -56, -6146 },
+ { -300, -4275, 1156, -5947 },
+ { 552, -2643, 2669, -3959 },
+ { 905, -4158, 1789, -5809 },
+ { 1336, -2009, 2108, -5903 },
+ { 1555, -3600, 1110, -6759 },
+ { -1294, -3464, 77, -6084 },
+ { -1139, -4006, -1270, -4181 },
+ { -5094, -3296, 1092, -2847 },
+ { -5503, -2883, 1984, -2067 },
+ { -4671, -4218, -1417, -4132 },
+ { -3763, -3818, 1262, -3082 },
+ { -5132, -3430, 2928, -728 },
+ { -5957, -2877, 1251, -2446 },
+ { -4425, -2319, -212, -4276 },
+ { -6201, -1993, 1774, -2182 },
+ { -5500, -3836, 2201, -1396 },
+ { -6934, -2334, 2366, -1293 },
+ { -6124, -4140, 1337, -1977 },
+ { -6553, -4186, 1756, -1325 },
+ { -5126, -1258, 744, -3656 },
+ { -5167, -1390, 1581, -2895 },
+ { -4525, -3398, 2429, -1865 },
+ { -4076, -3183, 2027, -2510 },
+ { -6191, -3274, 1838, -1814 },
+ { -4454, -2753, 2723, -1185 },
+ { -6655, -4797, 251, -2595 },
+ { -6332, -2232, 1832, 217 },
+ { -5869, -1698, 134, 340 },
+ { -6614, -1045, 2126, -1932 },
+ { -4859, -2107, 2010, -2435 },
+ { -6274, -1622, 2808, -1374 },
+ { -3119, -3209, 521, -3988 },
+ { -5676, -2082, -420, -2711 },
+ { -7073, -3623, 696, -2343 },
+ { -5986, -4224, 572, -2454 },
+ { -4340, -4521, 882, -2771 },
+ { -6178, -1933, 535, -1444 },
+ { -4923, -4163, 1744, -2066 },
+ { -6410, -1519, 1058, -2683 },
+ { -5077, -1185, 856, -2216 },
+ { -7091, -2444, 687, -2597 },
+ { -5284, -2165, 3239, -993 },
+ { -4763, -1497, 197, -3179 },
+ { -4128, -4958, -396, -3578 },
+ { -5054, -3878, -647, -2672 },
+ { -7005, -3348, 1679, -1579 },
+ { -5767, -1017, 2582, -1915 },
+ { -7069, -2787, 1331, -2070 },
+ { -5532, -2296, 706, -2950 },
+ { -5059, -3543, -821, -3637 },
+ { -6639, -1835, 1016, -696 },
+ { -5611, -5220, -694, -3371 },
+ { -5994, -2803, 2933, -729 },
+ { -5948, -619, 1596, -2676 },
+ { -5486, -4419, 153, -3265 },
+ { -4329, -3440, 1646, -1439 },
+ { -4083, -3978, 177, -3569 },
+ { -4289, -2599, 1224, -3075 },
+ { -5707, -3253, 1912, -759 },
+ { -6606, -3437, 2562, -571 },
+ { -5254, -2444, 769, -352 },
+ { -6545, -3154, 582, -1103 },
+ { -5328, -2241, 2566, -1775 },
+ { -7216, -1936, 1538, -1983 },
+ { -3730, -2451, 426, -3869 },
+ { -5110, -1385, 2031, -1169 },
+ { -6470, -2715, 269, -3123 },
+ { -5806, -2480, -97, -3832 },
+ { -3683, -4916, -490, -4330 },
+ { -6341, -2083, -669, -115 },
+ { -4913, -4079, -837, -4673 },
+ { -3274, -2497, 2334, -2652 },
+ { -1286, -1731, 2550, -3756 },
+ { -3375, -877, 926, -3977 },
+ { -2525, -2079, 2879, -2625 },
+ { -5308, -504, 3111, -1607 },
+ { -4904, 460, 4093, -1232 },
+ { -1993, 1616, 4656, -1913 },
+ { -3481, -1176, 3119, -2236 },
+ { -4132, -1502, 2339, -2545 },
+ { -2542, 1151, 3569, -2550 },
+ { -4381, 430, 3147, -2082 },
+ { -3888, 867, 3899, -1657 },
+ { -2861, 1290, 4202, -1979 },
+ { -3893, -253, 2363, -2764 },
+ { -1705, 688, 3827, -2923 },
+ { -2223, 2312, 3700, -3148 },
+ { -1986, -720, 5021, -795 },
+ { -3177, 242, 1952, -3352 },
+ { -1854, 1509, 2528, -3815 },
+ { -3173, 97, 5019, -706 },
+ { -2689, -145, 1375, -3915 },
+ { -4838, -385, 2488, -2427 },
+ { -4557, -355, 1603, -3060 },
+ { -3522, 1832, 3292, -2674 },
+ { -3769, 780, 2378, -2704 },
+ { -4323, -1932, 3414, -1169 },
+ { -2740, 1158, 2729, -3273 },
+ { -3647, 210, 1464, -2892 },
+ { -2342, -2097, 1513, -3727 },
+ { -4422, -1242, 3130, -1833 },
+ { -1308, -1039, 4290, -1875 },
+ { -1754, -2535, 3298, -2314 },
+ { -4102, -186, 4037, -1094 },
+ { -1008, 1570, 3290, 171 },
+ { -3322, -2621, 2791, -1536 },
+ { -2539, -2597, 3442, -1672 },
+ { -3411, -2015, 3670, -1174 },
+ { -2097, 730, 5581, -1399 },
+ { -1510, -74, 4820, -2004 },
+ { -4086, -868, 4425, -771 },
+ { -956, -986, 3640, -2925 },
+ { -2087, -1250, 3464, -2458 },
+ { -3308, -2411, 1334, -3667 },
+ { -2264, -389, 4004, -1854 },
+ { -680, 239, 4058, -3388 },
+ { -1357, 30, 2993, -3658 },
+ { -3601, -552, 1177, -1136 },
+ { -2641, 442, 4374, -1625 },
+ { -2525, 770, 1640, -3895 },
+ { -3172, -891, 3893, -1608 },
+ { -2996, 13, 3277, -2414 },
+ { -899, 1055, 4470, -2501 },
+ { -422, -584, 3475, -3787 },
+ { -1978, -593, 2566, -3415 },
+ { -3150, -1280, 2362, -3047 },
+ { -3592, 224, 1026, -3932 },
+ { -4840, -1189, 3633, -879 },
+ { -3952, -2255, 2916, -1826 },
+ { -1695, 28, 1810, -349 },
+ { -745, -2484, 3308, -3293 },
+ { -1016, 1563, 5365, -1823 },
+ { -2172, -1787, 4266, -1287 },
+ { -1241, -1951, 3982, -2413 },
+ { -2009, -2639, 2330, -3480 },
+ { 5105, -1618, -2588, -2015 },
+ { 6497, -1523, -3218, -910 },
+ { 6526, -2305, -2029, -1790 },
+ { 5289, -99, -3436, -400 },
+ { 5781, -1623, -1577, -2617 },
+ { 5259, -670, -3125, -1700 },
+ { 6343, -1256, -331, -3222 },
+ { 7967, -678, -2195, -1462 },
+ { 6119, -695, -2988, -1538 },
+ { 6108, 494, -3359, -1548 },
+ { 5067, 969, -2328, -2707 },
+ { 7595, -435, -1497, -2056 },
+ { 6929, -719, -2420, -1665 },
+ { 5190, 584, -2982, -2103 },
+ { 6106, -444, -1411, -2739 },
+ { 5584, 289, -1804, -2803 },
+ { 5276, 227, -1180, -3361 },
+ { 7544, -1525, -1834, -1725 },
+ { 5986, -1470, -2606, -1701 },
+ { 5096, -765, -1712, -3006 },
+ { 5423, -149, -3933, -1157 },
+ { 7651, 26, -2445, -1507 },
+ { 4745, -464, -1735, -2362 },
+ { 5352, -1011, -1094, -1999 },
+ { 6300, -672, -542, -1950 },
+ { 6675, -1020, -1318, -1059 },
+ { 7218, -2036, -603, -2462 },
+ { 7755, -1514, -2430, -1229 },
+ { 5041, 449, -1056, -2405 },
+ { 6710, -2277, -1344, -2284 },
+ { 6824, -1347, -2254, 251 },
+ { 6068, -1857, -983, -1316 },
+ { 5603, -2177, -2730, -1477 },
+ { 5838, -1059, -3604, -970 },
+ { 5076, -789, -335, -2413 },
+ { 6191, -1634, -2000, -2129 },
+ { 5092, -1292, -2543, -1034 },
+ { 5305, 435, -1710, -1850 },
+ { 6140, 561, -2176, -2380 },
+ { 6752, 348, -2496, -1890 },
+ { 6405, 273, -1098, -2778 },
+ { 6942, -1340, -496, -1381 },
+ { 5238, -687, -2454, -2349 },
+ { 6959, -882, -1833, -2061 },
+ { 6292, -253, -2125, -2199 },
+ { 5838, -574, -759, -3215 },
+ { 6954, -1484, -640, -2771 },
+ { 7498, -1706, -1210, -2154 },
+ { 6772, -1003, -1235, -2532 },
+ { 6014, 228, -2154, -1108 },
+ { 6943, -2178, -2644, -1122 },
+ { 7262, -763, -3056, -1090 },
+ { 6273, -1478, -1072, 177 },
+ { 4734, 425, -2912, 357 },
+ { 7129, 168, -1537, -2327 },
+ { 7204, -434, -746, -2660 },
+ { 6879, 57, -3087, -1310 },
+ { 4623, -610, -718, -3459 },
+ { 6565, -543, -1998, -339 },
+ { 4752, -277, -2066, -1405 },
+ { 7435, -1416, -1904, -505 },
+ { 4076, 150, -1222, -3556 },
+ { 7082, -28, -1456, -1174 },
+ { 5941, -446, -1326, -1158 },
+ { 3870, -1648, -2474, -2589 },
+ { 858, 37, -3387, -3721 },
+ { 3557, -1503, -1664, -3383 },
+ { 3336, -1972, -3079, -2216 },
+ { 3186, 60, -4185, -863 },
+ { 3456, -773, -3066, -2457 },
+ { 4131, -913, -2060, -2601 },
+ { 4431, -691, -4114, -972 },
+ { 3461, -334, -3680, -1751 },
+ { 2006, -459, -2214, -3827 },
+ { 1322, 32, -2816, -3203 },
+ { 4425, -1897, -2791, -1946 },
+ { 4504, 23, -3421, -1909 },
+ { 3090, -885, -2366, -3264 },
+ { 3209, -2363, -3730, -834 },
+ { 3312, -1471, -3641, -1579 },
+ { 4184, -1669, -3323, -1248 },
+ { 2190, -931, -3302, -2944 },
+ { 2947, -229, -4791, -1195 },
+ { 2020, -1626, -2700, -3125 },
+ { 2214, -326, -4352, -1683 },
+ { 3286, -2619, -2412, -2458 },
+ { 1000, -2571, -4129, -2158 },
+ { 2496, -2627, -3611, -1433 },
+ { 2043, -2191, -2167, -3827 },
+ { 2571, -2544, -1915, -3222 },
+ { 2022, -1501, -3856, -2165 },
+ { 2685, -1180, -1461, -4038 },
+ { 1610, -2313, -4391, -1173 },
+ { 2340, -2490, -4215, -516 },
+ { 1742, -2615, -3632, -2146 },
+ { 523, -1293, -4246, -2442 },
+ { 3725, -2723, -3014, -1576 },
+ { 3554, -1381, -4200, -824 },
+ { 1291, -1594, -4777, -1430 },
+ { 1452, 515, -2960, -3830 },
+ { 4264, -894, -3305, -1826 },
+ { 2606, -1452, -4522, -966 },
+ { 1196, -830, -4807, -1816 },
+ { 1054, -775, -2616, -4071 },
+ { 4206, 415, -4344, -1132 },
+ { 3044, 491, -4126, -1934 },
+ { 988, -901, -3353, -3443 },
+ { 1729, -3063, -2267, -3370 },
+ { 3915, 912, -2989, -2387 },
+ { 3781, 300, -2457, -3050 },
+ { 2712, 924, -1350, -1206 },
+ { 4230, 405, -2343, 665 },
+ { 1878, -873, -225, -29 },
+ { 3510, 56, -1334, -3420 },
+ { 2850, 1447, -2651, -3150 },
+ { 1510, -706, -4125, -2483 },
+ { 3115, 793, -1692, -3894 },
+ { 2667, 213, -2973, -2786 },
+ { 1184, -2384, -3051, -3173 },
+ { 2139, 796, -2079, -3697 },
+ { 1464, -1483, -3726, -2754 },
+ { 2407, -1148, -3915, -1569 },
+ { 2612, -1779, -3217, -2271 },
+ { 2406, -2870, -2937, -2496 },
+ { 2140, 126, -3646, -2758 },
+ { 2952, -1036, 268, -1423 },
+ { 93, -1931, -3841, -3535 },
+ { 389, -2953, -3383, -3343 },
+ { 8652, -5511, -1662, 565 },
+ { 7427, -2791, -2535, -842 },
+ { 8541, -4253, -1407, -988 },
+ { 8018, -3203, -2998, 105 },
+ { 7231, -3926, -958, 1308 },
+ { 7331, -3690, -363, 2586 },
+ { 6803, -3646, -2226, -903 },
+ { 8163, -2811, -477, -2235 },
+ { 9356, -3818, -1685, -684 },
+ { 8466, -2854, -302, -698 },
+ { 8458, -3224, 517, 279 },
+ { 8074, -2619, -1326, 2596 },
+ { 8779, -2761, -2527, -441 },
+ { 6533, -2887, -899, -696 },
+ { 7394, -2305, -1642, -120 },
+ { 8281, -3780, -22, 1305 },
+ { 9158, -4413, -779, 901 },
+ { 9031, -5240, -1109, 1678 },
+ { 8717, -3650, 410, -1075 },
+ { 7317, -3197, -818, -2264 },
+ { 7934, -2385, -1214, -1886 },
+ { 8256, -4441, -291, -587 },
+ { 7358, -3395, 1090, -270 },
+ { 9446, -4910, -1343, -473 },
+ { 8187, -4726, -808, 1166 },
+ { 7504, -3845, -47, 267 },
+ { 8029, -2146, -1283, -383 },
+ { 7461, -2705, -853, 783 },
+ { 9367, -3636, -645, -354 },
+ { 8955, -3473, -308, -1947 },
+ { 8676, -2683, -2099, 1485 },
+ { 7481, -3003, -871, -444 },
+ { 8015, -2839, -1673, 1175 },
+ { 6947, -4643, -1527, -1047 },
+ { 7622, -2575, -137, -960 },
+ { 9388, -4279, -707, -1322 },
+ { 8382, -5259, -1283, -565 },
+ { 6856, -4138, -1030, 630 },
+ { 8659, -2571, -1124, -1666 },
+ { 8763, -3807, -537, 2543 },
+ { 8049, -3578, -2186, -604 },
+ { 8272, -2351, -1985, -1214 },
+ { 6855, -3796, -1527, -1631 },
+ { 7178, -2896, -1600, -1756 },
+ { 7040, -2888, -89, -1586 },
+ { 6261, -3403, -264, 998 },
+ { 7756, -4699, -1543, -834 },
+ { 7682, -4622, -758, -1721 },
+ { 8839, -4232, -2932, 1959 },
+ { 9363, -4679, -1956, 39 },
+ { 7883, -3616, -1414, -1432 },
+ { 8828, -3188, -1356, -1312 },
+ { 7746, -3987, -121, -2424 },
+ { 9262, -3256, -693, 818 },
+ { 7670, -3420, -148, 3504 },
+ { 7344, -3183, 608, 1595 },
+ { 8976, -4139, -1848, 1304 },
+ { 6708, -4131, 33, -852 },
+ { 7840, -4429, -2275, 79 },
+ { 8980, -3858, -2838, 453 },
+ { 7815, -4604, -2563, 944 },
+ { 8372, -4422, -1783, 3071 },
+ { 8623, -5128, -1754, 2888 },
+ { 7462, -3281, 889, 920 },
+ { 8416, -59, -1320, -1825 },
+ { 7928, -1488, -414, -2499 },
+ { 8110, -977, -1047, -2042 },
+ { 8278, -687, -1597, -1550 },
+ { 7988, -174, -977, -2106 },
+ { 8609, -1547, -1628, -1527 },
+ { 9000, -1798, -946, -1761 },
+ { 8954, -872, -1404, -1594 },
+ { 8939, 466, -748, -1212 },
+ { 9549, -329, -177, -1360 },
+ { 9411, -18, -1126, -1568 },
+ { 8859, -782, -488, -1338 },
+ { 8955, -218, -43, -1209 },
+ { 9131, -69, -453, -1001 },
+ { 9069, -1519, -1091, -1199 },
+ { 9247, -1309, -566, -1146 },
+ { 8528, -1617, -287, -1313 },
+ { 7763, -745, -149, -2040 },
+ { 8294, -343, 257, -2633 },
+ { 10149, -893, -552, -1649 },
+ { 9398, -915, 218, -2042 },
+ { 9703, -1194, -675, -1592 },
+ { 9586, -700, -427, -1710 },
+ { 8930, 497, -1445, -1218 },
+ { 9285, -1323, -163, -1552 },
+ { 8431, -1289, -985, -1404 },
+ { 8965, -655, 653, -1483 },
+ { 9542, -1001, -951, -1128 },
+ { 9205, -647, -37, -882 },
+ { 8603, -56, 514, -1793 },
+ { 9300, -12, -1324, -567 },
+ { 8773, 238, -184, -1456 },
+ { 9941, -1306, -69, -1792 },
+ { 9360, 279, -376, -1919 },
+ { 9180, -285, 95, -2170 },
+ { 9922, -501, -970, -1570 },
+ { 8341, -1493, -856, -2092 },
+ { 8780, -981, -850, -1014 },
+ { 9721, -548, -1504, -1094 },
+ { 9973, -1493, 482, -2105 },
+ { 8707, -333, -1027, -1087 },
+ { 9098, -469, -315, -1723 },
+ { 8879, -1050, -661, -2020 },
+ { 8857, 602, -866, -1918 },
+ { 8945, -1025, -2154, -1071 },
+ { 8484, -1930, -468, -2179 },
+ { 9177, -1903, -224, -2112 },
+ { 8652, -137, -2097, -1214 },
+ { 9063, -973, -1405, -772 },
+ { 9328, -456, 662, -2469 },
+ { 10101, -697, 127, -2113 },
+ { 9685, 811, -2359, -1024 },
+ { 8586, -94, -460, -1982 },
+ { 7924, -141, -509, -2513 },
+ { 7773, -669, -107, -2835 },
+ { 8636, -1064, -46, -2409 },
+ { 9748, 596, -1815, -1349 },
+ { 8924, 304, 547, -2614 },
+ { 9442, 746, -1153, -1679 },
+ { 9454, -278, -529, -1976 },
+ { 8488, 561, -32, -2160 },
+ { 10083, -63, -1544, -1364 },
+ { 9390, -1278, 568, -1131 },
+ { 9740, -49, -2253, -910 },
+ { 3636, -2391, -1115, -3614 },
+ { 6014, -3204, -1902, -1808 },
+ { 5787, -3497, -1116, -2590 },
+ { 4365, -3046, -1632, -2668 },
+ { 4733, -2192, -2029, -2468 },
+ { 5412, -2753, -1633, -2464 },
+ { 4455, -3375, -767, -3399 },
+ { 4456, -1644, -983, -2841 },
+ { 4039, -2523, 38, -3967 },
+ { 3406, -2662, 72, -4757 },
+ { 4279, -2005, 1055, -4399 },
+ { 4321, -1377, -860, -3786 },
+ { 3743, -5739, -651, -3047 },
+ { 3528, -5510, 361, -4060 },
+ { 6496, -4886, -136, -2689 },
+ { 4513, -5254, 551, -4010 },
+ { 6557, -3413, -92, -3063 },
+ { 4186, -2059, 187, 47 },
+ { 6210, -4117, -1256, -1985 },
+ { 6038, -4343, 351, -2124 },
+ { 4305, -4780, -2077, -1897 },
+ { 4480, -3815, -2228, -1533 },
+ { 5582, -3689, 1221, -3429 },
+ { 5532, -4874, 1195, -2765 },
+ { 6518, -2853, -905, -2568 },
+ { 5467, -2192, 470, -4115 },
+ { 4139, -1577, 240, -3493 },
+ { 5281, -1926, -729, -3340 },
+ { 5214, -2870, 1359, -4289 },
+ { 3046, -3510, -1536, -3214 },
+ { 5433, -2881, -1230, -1184 },
+ { 4861, -3932, -1071, -2791 },
+ { 5693, -4234, -1906, -1502 },
+ { 4004, -3935, -1804, -2383 },
+ { 3728, -3792, 681, -4773 },
+ { 3621, -3030, -1951, -2598 },
+ { 5133, -3903, 44, -3700 },
+ { 3561, -3451, 1183, -5301 },
+ { 5026, -2762, -2341, -1780 },
+ { 5841, -2492, -467, -3210 },
+ { 5591, -1791, 497, -2472 },
+ { 5054, -3898, -1822, -2097 },
+ { 5813, -2792, 83, -1469 },
+ { 4432, -4497, 1670, -5193 },
+ { 5338, -4653, -1109, -2200 },
+ { 3239, -4401, -648, -3655 },
+ { 2147, -3598, -1200, -4242 },
+ { 4417, -2271, -1552, -3210 },
+ { 6494, -4360, 852, -3565 },
+ { 2393, -6358, -856, -4524 },
+ { 4959, -4196, -847, -1403 },
+ { 4924, -5438, -226, -3026 },
+ { 4254, -5303, -1306, -2424 },
+ { 4121, -3126, -2334, -1981 },
+ { 3437, -4443, -1464, -2953 },
+ { 3203, -3459, -529, -4339 },
+ { 5896, -5945, 543, -3246 },
+ { 1987, -4733, -220, -4863 },
+ { 4358, -4431, -514, -3081 },
+ { 4583, -2416, -492, -2287 },
+ { 2943, -5035, 419, -4927 },
+ { 5358, -5129, 987, -4309 },
+ { 4460, -3392, 1752, -5634 },
+ { 3415, -4633, 1507, -5945 },
+ { 811, -4692, -445, 2333 },
+ { 1009, -5613, -1857, 1360 },
+ { 1338, -2712, -2720, 3036 },
+ { 1002, -3754, -2582, 2344 },
+ { 750, -4608, -2334, 714 },
+ { 2043, -3207, -2822, 2173 },
+ { -140, -4654, -2953, 357 },
+ { -54, -4026, -2376, 2695 },
+ { 1858, -5022, -717, 2287 },
+ { 2064, -3894, -722, 3255 },
+ { 2727, -4558, -332, 2603 },
+ { 1810, -5378, 283, 1826 },
+ { 3935, -4326, 762, 3383 },
+ { -767, -4697, -2510, 1922 },
+ { 2146, -4312, -3090, 1641 },
+ { 54, -5881, -2114, 921 },
+ { 1992, -5766, -640, 1574 },
+ { 1200, -5371, -1114, 1828 },
+ { 2973, -5337, 34, 2266 },
+ { 1531, -5018, -2817, 1192 },
+ { 3078, -4570, 117, 1990 },
+ { 924, -4286, -1388, 2713 },
+ { 142, -5058, -2848, 1487 },
+ { -106, -6180, -881, 842 },
+ { 673, -5433, -229, 1596 },
+ { 783, -5710, -2784, 562 },
+ { 1935, -5729, -2009, 856 },
+ { -410, -3375, -3326, 2734 },
+ { 234, -3000, -2628, 3260 },
+ { 733, -3405, -3806, 1589 },
+ { 771, -4285, -3544, 1314 },
+ { 1192, -3563, -3960, 2178 },
+ { 206, -5555, -1250, 1546 },
+ { -130, -3815, -1210, 3041 },
+ { 646, -3940, -393, 2992 },
+ { -184, -4931, -1767, 1925 },
+ { 2746, -5120, -2275, 1464 },
+ { 2440, -3731, -3352, 2729 },
+ { -490, -4942, -3779, 997 },
+ { 68, -2636, -4167, 3778 },
+ { 48, -3986, -4118, 2106 },
+ { -978, -5486, -1336, 1390 },
+ { 1126, -5297, -855, 640 },
+ { -472, -3975, -3622, 1557 },
+ { 2456, -5344, -1523, 1648 },
+ { -774, -5652, -2417, 1147 },
+ { 995, -6122, -812, 1132 },
+ { 3282, -4571, -1763, 2175 },
+ { 3655, -3862, -676, 3568 },
+ { 3038, -3647, -1672, 3381 },
+ { 2595, -2964, -2772, 3263 },
+ { 4176, -3353, -1148, 4354 },
+ { 1603, -3442, -1500, 3444 },
+ { 828, -6226, -1783, 678 },
+ { 1421, -3333, -3080, 3403 },
+ { 1121, -4727, -1924, 1984 },
+ { -186, -5083, -682, 1796 },
+ { 819, -2778, -3488, 530 },
+ { 421, -2873, -3832, 2596 },
+ { 2164, -4263, -1605, 2282 },
+ { 585, -4437, -682, -491 },
+ { -644, -4452, -1157, 2325 },
+ { 1991, -4299, 210, 2834 },
+ { 2135, -3632, -2113, 665 },
+ { -7482, -2724, -2662, -1380 },
+ { -6983, -2166, -3756, -3509 },
+ { -7085, -1439, -2397, -3112 },
+ { -7760, -3049, -3319, -2822 },
+ { -8413, -2760, -4406, -3298 },
+ { -5995, -3943, -1260, -3750 },
+ { -7879, -1554, -3464, -2606 },
+ { -6314, -2034, -3878, -1681 },
+ { -8849, -2084, -1399, -1231 },
+ { -7153, -2602, -1384, -817 },
+ { -8041, -2571, -407, -2785 },
+ { -7246, -2233, -1578, 260 },
+ { -7336, -3883, -4061, -1342 },
+ { -7619, -3908, -2342, 382 },
+ { -8684, -3724, -1662, -727 },
+ { -7850, -2922, -1770, -3449 },
+ { -6766, -2034, -1293, -1988 },
+ { -6895, -2116, -968, -3744 },
+ { -7136, -5147, -2618, -2809 },
+ { -8224, -3724, -2519, -1589 },
+ { -6711, -2750, -3021, -219 },
+ { -8059, -1638, -1102, -3175 },
+ { -8710, -4839, -3963, -3143 },
+ { -9363, -4965, -3257, -1002 },
+ { -6099, -1751, -3157, -395 },
+ { -6453, -3216, -4597, -483 },
+ { -7879, -5477, -839, -2638 },
+ { -7202, -4038, -526, -2856 },
+ { -8022, -1228, -1910, -1646 },
+ { -9117, -1393, -1582, -2535 },
+ { -9095, -2693, -636, -2605 },
+ { -9076, -2580, -3481, -2519 },
+ { -8327, -4859, -2422, 83 },
+ { -8368, -2129, -2324, -2173 },
+ { -8554, -4563, -3842, -2007 },
+ { -10462, -4261, -1934, -2084 },
+ { -9717, -3187, -2294, -1896 },
+ { -9625, -3889, -3020, -3224 },
+ { -9857, -4955, -4239, -2184 },
+ { -9752, -2351, -2277, -3129 },
+ { -7219, -1302, -2639, -1603 },
+ { -7477, -4360, -3718, -559 },
+ { -5680, -2033, -2326, -3078 },
+ { -10190, -5548, -4643, -3601 },
+ { -9431, -4121, -879, -2479 },
+ { -8365, -5450, -2020, -1439 },
+ { -6289, -5178, -1605, -3845 },
+ { -8319, -3866, -687, -2792 },
+ { -8131, -1031, -3608, -3947 },
+ { -10510, -2560, -1199, -2082 },
+ { -11015, -3640, -2748, -3041 },
+ { -8762, -5022, -5231, -1162 },
+ { -10153, -2715, -4648, -4859 },
+ { -7930, -5205, -1900, -3600 },
+ { -9561, -3548, -4812, -3722 },
+ { -7663, -4709, -1180, -1475 },
+ { -9073, -5707, -1815, -2980 },
+ { -8602, -2363, -2675, -3770 },
+ { -9967, -5614, -3575, -3838 },
+ { -8324, -1005, -2131, -3254 },
+ { -10331, -5737, -2550, -2940 },
+ { -8234, -3354, -3361, -4479 },
+ { -8140, -1951, -4526, -4545 },
+ { -6679, -2662, -2284, -4182 },
+ { -1122, -1514, -6427, -212 },
+ { 54, -1660, -5424, -1404 },
+ { 254, -2778, -5222, 846 },
+ { -267, -1661, -6577, 814 },
+ { -305, -2021, -5759, 1484 },
+ { -1791, -2446, -6867, -86 },
+ { -2929, -3158, -6603, -1799 },
+ { -1391, -3189, -5557, -1053 },
+ { -1602, -884, -6767, -1213 },
+ { -361, -318, -6219, -44 },
+ { -4078, -2635, -5523, -433 },
+ { -956, 478, -4382, 1470 },
+ { -3300, -2462, -6021, -2721 },
+ { 708, -2434, -5085, -540 },
+ { -2435, -3607, -5647, -2110 },
+ { -491, -1134, -4681, -2886 },
+ { 87, -3435, -4641, -1194 },
+ { -586, -2927, -4784, 366 },
+ { -1394, -2326, -6021, 350 },
+ { 97, -2519, -4678, -2120 },
+ { -1547, -1907, -5069, -2993 },
+ { 268, -3724, -4719, 127 },
+ { -827, -1190, -5912, 1144 },
+ { -3959, -2322, -6898, -1974 },
+ { -2728, -2228, -6426, -562 },
+ { -456, -666, -5785, -1609 },
+ { 531, -1096, -5731, -656 },
+ { -3569, -688, -3915, 110 },
+ { -4752, -1725, -4393, -377 },
+ { -3210, -3315, -6960, -840 },
+ { -688, -3416, -4971, 1221 },
+ { -1833, 77, -6491, -2434 },
+ { -239, -255, -6850, -886 },
+ { -2112, -1490, -6291, -2689 },
+ { -1544, -4579, -5198, -1261 },
+ { -2771, -4014, -5520, 683 },
+ { -1635, -2829, -5512, 1214 },
+ { -958, -2582, -4823, 2360 },
+ { -2077, -4566, -4642, 365 },
+ { -3112, -4214, -5960, -823 },
+ { -2467, -2510, -4858, 1467 },
+ { -1561, -3399, -5822, 211 },
+ { -775, -1081, -4424, 2636 },
+ { -1263, 25, -6378, -1392 },
+ { -3476, -366, -5417, -1393 },
+ { -3176, -1476, -4149, 1466 },
+ { -2479, 518, -4448, -257 },
+ { -2992, 158, -4660, -1279 },
+ { -1320, -3872, -4479, 1147 },
+ { -1475, -312, -5318, 539 },
+ { -3527, -1679, -5860, -1681 },
+ { -3397, -3438, -5593, 1866 },
+ { -4089, -2439, -4763, 1275 },
+ { -748, -4513, -4687, -48 },
+ { -2166, -4531, -4691, -2856 },
+ { -2385, -853, -6035, -627 },
+ { -1194, -4091, -4472, -1963 },
+ { -682, -3234, -4084, -3033 },
+ { -3255, -5015, -5328, -12 },
+ { -2313, -3436, -4601, -155 },
+ { -2792, -1038, -6947, -2019 },
+ { -1244, -1526, -5771, -1882 },
+ { -4679, -3731, -5506, 283 },
+ { -3062, -66, -3558, -758 },
+ { -4895, -1187, 4751, 3728 },
+ { -7600, -2752, 3320, 4613 },
+ { -5703, -2975, 3944, 2659 },
+ { -4972, -1257, -246, 2952 },
+ { -4221, -2487, 1702, 4295 },
+ { -2900, -1529, 2458, 4935 },
+ { -5061, 407, 2416, 4050 },
+ { -6931, -3478, 2761, 2213 },
+ { -6037, -3921, 3192, 1866 },
+ { -6113, -811, 2407, 3782 },
+ { -5878, -1716, 1207, 3478 },
+ { -5953, -2853, 2207, 2712 },
+ { -6807, -3223, 2749, 3595 },
+ { -3272, -3157, 1389, 3788 },
+ { -5368, -1904, 1980, 5077 },
+ { -7235, -1398, 3075, 4548 },
+ { -4765, -3487, 2755, 2796 },
+ { -7658, -4435, 2694, 2582 },
+ { -6997, -4282, 456, 3832 },
+ { -5563, -3115, -63, 3713 },
+ { -4244, -4220, 1450, 2767 },
+ { -3801, -2194, 190, 4303 },
+ { -5458, -4119, 1958, 2274 },
+ { -7300, -3469, 3514, 3193 },
+ { -4594, -2067, 775, 4752 },
+ { -3389, -1654, 1464, 5412 },
+ { -4845, -3483, 964, 3437 },
+ { -6007, -2818, 1666, 4659 },
+ { -8709, -5007, 1757, 3287 },
+ { -5833, -4389, 1025, 3171 },
+ { -5788, -1780, 3944, 3661 },
+ { -4430, -920, 1938, 4753 },
+ { -7066, -1857, 4591, 4538 },
+ { -3549, -513, 1427, 5317 },
+ { -7517, -1220, 2883, 3049 },
+ { -7605, -2687, 1874, 2735 },
+ { -8718, -4035, 2676, 3730 },
+ { -7990, -3907, 1185, 2607 },
+ { -6058, -1744, 3349, 5157 },
+ { -5954, 565, 3161, 3250 },
+ { -6478, -612, 1930, 2271 },
+ { -6535, -1445, -2, 1618 },
+ { -8963, -4151, 1192, 4044 },
+ { -7227, -3570, 1600, 4234 },
+ { -4674, 79, 595, 3015 },
+ { -3974, 430, 2727, 5137 },
+ { -5299, 9, 3714, 4779 },
+ { -6779, -2699, -8, 2436 },
+ { -7016, -1145, 1293, 2310 },
+ { -6955, -3312, 1534, 1801 },
+ { -4025, 740, 1850, 4054 },
+ { -9589, -3460, 4154, 5270 },
+ { -4404, -1181, 4298, 5173 },
+ { -7356, -4583, -18, 2644 },
+ { -6516, -1235, 4439, 6234 },
+ { -3453, -301, 4344, 4464 },
+ { -4643, 1530, 3315, 4340 },
+ { -4575, -2557, 3754, 3682 },
+ { -3643, -3501, 2051, 2997 },
+ { -5412, -2475, 2301, 1579 },
+ { -5846, 259, 1360, 2348 },
+ { -5258, -1358, 1050, 838 },
+ { -5542, -219, 6377, 5750 },
+ { -5713, -2952, 922, 899 },
+ { -2049, -1135, 5206, 1033 },
+ { -1693, -1886, 4835, -106 },
+ { -2344, -3504, 4232, -13 },
+ { -2475, -2334, 5043, 1126 },
+ { -787, -2549, 3880, 2138 },
+ { -3159, -2341, 4830, 2887 },
+ { -1780, -1009, 6240, 2061 },
+ { -4327, -3363, 2818, 886 },
+ { -3376, -2743, 4104, 207 },
+ { -3250, -4640, 2718, 1498 },
+ { -382, -1075, 4382, 3460 },
+ { -2416, -4168, 3530, 816 },
+ { -1756, -2708, 4861, 622 },
+ { -1879, -2097, 5156, 2889 },
+ { -2496, -2418, 3722, 2671 },
+ { -2717, -3252, 3341, 1944 },
+ { -4063, -4091, 3306, 267 },
+ { -3549, -3808, 3747, 842 },
+ { -2635, 546, 5794, 1894 },
+ { -1857, -1121, 4383, 3964 },
+ { -2226, -2166, 3489, 3678 },
+ { -3492, -660, 5323, 1063 },
+ { -3033, -3130, 4382, 1828 },
+ { -2703, -625, 6369, 2851 },
+ { -1656, -2842, 4584, -528 },
+ { -4781, -2622, 4390, 2097 },
+ { -413, -2045, 5081, 3035 },
+ { -3810, -2662, 4532, 1095 },
+ { -3144, -1858, 5215, 1880 },
+ { -3562, -1795, 4928, 670 },
+ { -4800, -1509, 5189, 1859 },
+ { -1085, -3832, 4169, 900 },
+ { -1969, -3270, 2857, 2878 },
+ { -4267, -4140, 3176, 1805 },
+ { -5145, -3727, 3524, 1168 },
+ { -1346, -1876, 5501, 1748 },
+ { -4998, -2945, 3699, 338 },
+ { -3458, -3096, 3406, -635 },
+ { -1751, -3209, 3508, 395 },
+ { -2507, 170, 5987, 705 },
+ { -3756, -1072, 5647, 3536 },
+ { -2870, -1439, 5026, 3212 },
+ { -3913, -3225, 3669, 2144 },
+ { -3739, 226, 5747, 764 },
+ { -2052, -820, 5266, 3093 },
+ { -3214, -3820, 2409, 2391 },
+ { -4398, -2588, 3501, -218 },
+ { -4484, -1763, 4180, -198 },
+ { -3368, -1525, 4362, -134 },
+ { -2407, 224, 4905, 3533 },
+ { -1369, -2937, 4728, 1788 },
+ { -4848, -1707, 4159, 851 },
+ { -3454, -1749, 4281, 3230 },
+ { -1990, -3853, 3487, 1735 },
+ { -3117, 92, 6155, 4075 },
+ { -2676, -2472, 4078, -589 },
+ { -1547, -2012, 2626, 1835 },
+ { -4275, -588, 4824, 725 },
+ { -601, -2249, 3736, 3548 },
+ { -4060, -61, 5333, 3097 },
+ { -4303, 7, 6551, 3054 },
+ { -5003, -1029, 5786, 3319 },
+ { -2810, -728, 5392, 199 },
+ { -1232, -200, 5228, 3121 },
+ { 2621, 165, -6255, 298 },
+ { 3669, 537, -6844, 1564 },
+ { 1598, -1190, -6235, 2523 },
+ { 2164, -32, -6894, 1383 },
+ { 853, -1597, -6069, 1449 },
+ { 1377, -1661, -5266, 108 },
+ { 2660, 48, -5172, -517 },
+ { 1903, -391, -5677, 1010 },
+ { 3792, 206, -5274, -11 },
+ { 1239, 2776, -2929, 2721 },
+ { 4071, 149, -7259, 3125 },
+ { 1436, -480, -6156, -196 },
+ { 1373, -1960, -5005, 3122 },
+ { 3413, -1271, -5176, 3283 },
+ { 3060, -68, -6495, 2238 },
+ { 2700, -2075, -4681, 91 },
+ { 2928, -1728, -5168, 1858 },
+ { 4424, 828, -4471, 88 },
+ { 2672, -2604, -4038, 2753 },
+ { 5223, -123, -6749, 2295 },
+ { 4237, -420, -5538, 1353 },
+ { 4744, -1281, -4097, 4708 },
+ { 1103, -2764, -4751, 2024 },
+ { 3747, -1913, -3911, 3960 },
+ { 2470, -1416, -5542, 615 },
+ { 4847, -1354, -5334, 1733 },
+ { 5336, 88, -7593, 4007 },
+ { 2388, -2880, -4807, 1037 },
+ { 4495, 1391, -5685, -139 },
+ { 5253, 1637, -6450, 1533 },
+ { 1199, 795, -5515, 1261 },
+ { 1397, -1259, -4252, 3838 },
+ { 746, 70, -6640, 604 },
+ { 1584, 166, -4972, 3072 },
+ { 380, -999, -5397, 2267 },
+ { 2974, 1707, -3242, 5360 },
+ { 5202, -403, -5453, 2832 },
+ { 3718, -1731, -4760, 714 },
+ { 4150, -975, -4792, 61 },
+ { 2925, -818, -4841, 15 },
+ { 5301, 577, -4006, 3259 },
+ { 5265, 1986, -5679, 3028 },
+ { 3752, 1928, -4509, 3729 },
+ { 3278, 1925, -6370, 1247 },
+ { 5107, 1721, -4853, 3127 },
+ { 3279, 2982, -2515, 4005 },
+ { 4622, 668, -6204, 759 },
+ { 6034, 317, -5763, 4818 },
+ { -558, 57, -3785, 2817 },
+ { 4476, 1616, -3965, 4536 },
+ { 5953, 2056, -8215, 2715 },
+ { 4387, 2613, -7463, 868 },
+ { 5834, 1088, -4736, 4924 },
+ { 6473, -856, -6991, 4172 },
+ { 4959, -293, -5162, 76 },
+ { 2731, -843, -6119, 3847 },
+ { 3245, 1202, -6833, 616 },
+ { 2553, 1383, -3829, 3859 },
+ { 4332, 2099, -3480, 3622 },
+ { 2110, 2683, -2728, 3990 },
+ { 876, 1167, -3290, 3466 },
+ { 3991, 1709, -2410, 4077 },
+ { 5105, 939, -2584, 3256 },
+ { 4719, 688, -1566, 3040 },
+ { -3632, 4335, 1266, -3303 },
+ { -4956, 3207, 1312, -2806 },
+ { -4669, 2627, 2663, -2435 },
+ { -4282, 3708, 2303, -3038 },
+ { -4536, 2297, -175, -3350 },
+ { -5234, 2503, -139, -880 },
+ { -3978, 1512, 1092, -3619 },
+ { -4519, 4649, 1363, -2455 },
+ { -5118, 3132, 1961, -1577 },
+ { -5196, 3379, -182, -1378 },
+ { -6420, 4486, 2397, -1993 },
+ { -5030, 5046, 1292, -1118 },
+ { -4559, 2573, -927, -1406 },
+ { -3501, 3730, 691, -4930 },
+ { -4364, 2758, 1007, -3909 },
+ { -4026, 2839, -1559, -2340 },
+ { -5037, 4053, 836, -1571 },
+ { -4727, 5136, 1110, -3588 },
+ { -5245, 2799, -999, -2164 },
+ { -4954, 1501, 422, -3963 },
+ { -5994, 2726, 1462, -2833 },
+ { -5621, 5159, 2038, -2512 },
+ { -4991, 2291, 1917, -3151 },
+ { -5469, 4382, -148, -2978 },
+ { -5858, 1983, 807, -2720 },
+ { -4709, 3556, 952, -467 },
+ { -2489, 2362, 1714, -4230 },
+ { -4717, 5004, -1180, -3672 },
+ { -5914, 3653, 1359, -1317 },
+ { -5506, 2995, 780, -1059 },
+ { -5287, 3945, 2480, -2293 },
+ { -3849, 4358, 322, -1770 },
+ { -3911, 3570, 252, -3185 },
+ { -3660, 5128, 158, -3719 },
+ { -4599, 3277, -503, -2727 },
+ { -3673, 3760, -1252, -3339 },
+ { -5161, 2337, 388, -1943 },
+ { -3529, 2216, 2156, -3080 },
+ { -4309, 4331, 1808, -1460 },
+ { -4782, 3820, 480, -2504 },
+ { -4166, 3544, -378, -1567 },
+ { -5572, 2466, -418, -2909 },
+ { -6096, 2930, 119, -1878 },
+ { -5963, 3554, 1011, -2233 },
+ { -6433, 4335, 935, -2930 },
+ { -5004, 3314, -1352, -3430 },
+ { -6042, 3463, -1008, -3940 },
+ { -4671, 2214, -640, -5040 },
+ { -2795, 3759, 1412, -3803 },
+ { -3647, 4436, 729, -515 },
+ { -3594, 1033, 56, -4148 },
+ { -2908, 3027, 2889, -3485 },
+ { -3338, 2234, 313, -4285 },
+ { -3825, 4497, -561, -2634 },
+ { -6167, 3012, -48, -3149 },
+ { -4828, 3515, -969, -4475 },
+ { -5789, 2757, -539, -4173 },
+ { -2452, 3067, 564, -4249 },
+ { -4921, 1358, 1331, -2889 },
+ { -3127, 4239, -1045, -1523 },
+ { -4780, 2326, -1118, -3446 },
+ { -3908, 5546, 152, -2622 },
+ { -6972, 2976, 337, -2809 },
+ { -4839, 4613, -35, -4077 },
+ { -1408, 4822, -1149, -4997 },
+ { -981, 4979, -912, -6304 },
+ { -2098, 5689, -888, -2878 },
+ { -3343, 4814, -657, -4434 },
+ { -2461, 3601, -967, -4869 },
+ { -2652, 3944, 87, -5520 },
+ { -1104, 6076, 174, -6407 },
+ { 355, 5370, -1721, -5869 },
+ { 1242, 4497, -1107, -5091 },
+ { -89, 4002, -1491, -5182 },
+ { 1059, 5693, -1591, -4905 },
+ { 1323, 4682, -2078, -4768 },
+ { 818, 3996, -549, -5468 },
+ { -287, 4529, 929, -5543 },
+ { -919, 5519, -2791, -2844 },
+ { -1407, 5679, -3289, -3974 },
+ { -189, 6530, -3547, -4002 },
+ { -900, 7039, -3371, -4855 },
+ { -2983, 7211, -363, -4835 },
+ { -814, 6503, -104, -5106 },
+ { -2386, 6896, 809, -4919 },
+ { 845, 4492, 352, -6621 },
+ { -1998, 7237, -1646, -4231 },
+ { -3380, 6251, 471, -4577 },
+ { -1908, 7059, 84, -5726 },
+ { -340, 6346, -803, -6265 },
+ { -2279, 5834, -47, -4633 },
+ { -1532, 5286, -1748, -1901 },
+ { -2757, 6188, -453, -3415 },
+ { -1255, 6405, -2043, -6357 },
+ { 918, 5581, -121, -5667 },
+ { 1840, 5336, -821, -5034 },
+ { -2475, 4992, -1825, -3104 },
+ { -2413, 5606, -1789, -4298 },
+ { 132, 5128, -2389, -4442 },
+ { 223, 6400, -2653, -4742 },
+ { -673, 5012, 680, -4582 },
+ { -1657, 6624, -349, -3596 },
+ { -755, 6289, -1860, -3978 },
+ { -572, 6894, -1946, -5207 },
+ { -1141, 4756, -2665, -5586 },
+ { -1073, 4269, -431, -4030 },
+ { 186, 5761, 916, -5868 },
+ { -1907, 4836, 1017, -5106 },
+ { -963, 3363, -1248, -6348 },
+ { -3262, 4774, -1818, -5858 },
+ { 847, 3812, -2538, -4302 },
+ { -1223, 5903, 1360, -5479 },
+ { -1094, 6923, -1244, -2381 },
+ { 267, 6276, -709, -2846 },
+ { -157, 5840, 1124, -4266 },
+ { 889, 3206, -910, -5305 },
+ { -1736, 3344, 582, -4838 },
+ { -2357, 5676, -2695, -6277 },
+ { -1916, 6901, -986, -5397 },
+ { -3062, 6028, -695, -5687 },
+ { 1836, 3566, -1357, -5226 },
+ { -2176, 4938, 646, -3872 },
+ { -2199, 3055, -208, -6124 },
+ { -236, 3032, -821, -5325 },
+ { -3989, 7277, -565, -3899 },
+ { -595, 4362, 74, -5975 },
+ { 684, 5874, -841, -4424 },
+ { -2731, 6305, -2389, -5465 },
+ { -5775, 1325, -56, -2528 },
+ { -7029, -534, -1890, -3278 },
+ { -5798, -15, -2734, -2210 },
+ { -5504, -1198, -353, -3659 },
+ { -5079, 960, -894, -4336 },
+ { -6073, -36, -133, -3014 },
+ { -5782, -259, -1025, -3986 },
+ { -6843, 1262, -807, -1639 },
+ { -5263, -918, -3290, -579 },
+ { -4840, 461, -2158, -533 },
+ { -6014, -50, -620, 504 },
+ { -5843, 241, -1359, -282 },
+ { -5898, 577, 769, -3271 },
+ { -6833, -946, -466, -3347 },
+ { -6026, 1459, -512, -729 },
+ { -7361, 747, -388, -1110 },
+ { -6391, 2142, -1160, -2513 },
+ { -6995, 304, 498, -2673 },
+ { -6757, 679, -386, -433 },
+ { -5222, 1688, -1093, -1032 },
+ { -5019, 575, 184, -3627 },
+ { -4237, 628, -3507, -1243 },
+ { -7479, -456, -1722, -1486 },
+ { -6464, 713, -1273, -1153 },
+ { -6255, 1682, -606, -3607 },
+ { -7033, 1497, -71, -1955 },
+ { -6694, 1556, -1721, -3214 },
+ { -6114, -356, 813, -2575 },
+ { -5308, 632, -1851, -1636 },
+ { -5742, -911, -1733, 383 },
+ { -6083, -387, -2313, -879 },
+ { -6535, -530, -1505, -2083 },
+ { -4896, 1223, -2750, -1816 },
+ { -6392, -463, -3247, -2093 },
+ { -5373, 1264, -2706, -3042 },
+ { -3894, -1390, -1020, -891 },
+ { -6179, 1168, -1966, -1922 },
+ { -5162, 1668, -1617, -1916 },
+ { -6453, 920, -1169, -2432 },
+ { -6130, 2005, -536, -1519 },
+ { -6552, -98, -518, -1938 },
+ { -7528, 355, -1101, -1772 },
+ { -5745, 610, -247, -1360 },
+ { -7003, 177, -2064, -1958 },
+ { -6956, -570, -2220, -4225 },
+ { -7830, 791, -1394, -2774 },
+ { -7634, 480, -3171, -4224 },
+ { -7913, 1154, -350, -2381 },
+ { -5063, 1704, -1804, -2977 },
+ { -4887, -524, -2703, 188 },
+ { -5551, 406, -1620, -3063 },
+ { -7109, 1342, 381, -3021 },
+ { -6846, 631, -458, -3398 },
+ { -4606, -605, 11, -3930 },
+ { -8134, -225, -1738, -2648 },
+ { -7043, 402, -2734, -3059 },
+ { -7417, 1825, -2545, -4389 },
+ { -6971, -236, -1031, -665 },
+ { -5752, 2111, -1632, -3808 },
+ { -7660, -78, -624, -3135 },
+ { -6358, 619, -1951, -3911 },
+ { -8134, 408, -1935, -3695 },
+ { -6335, 1911, -2368, -4505 },
+ { -7116, 2163, -344, -2753 },
+ { 2357, 4488, 2220, -5682 },
+ { 1385, 3206, 2300, -5305 },
+ { 1419, 2557, 5203, -3516 },
+ { 262, 4315, 3920, -1847 },
+ { 3316, 3187, 1612, -5609 },
+ { 1729, 2350, 1673, -6068 },
+ { 1603, 6126, 1467, -2839 },
+ { -1339, 3316, 3691, -3530 },
+ { -563, 4618, 3180, -4548 },
+ { 463, 4624, 3111, -5614 },
+ { 1246, 5455, 3356, -5720 },
+ { 480, 2149, 5422, -2893 },
+ { 1768, 4827, 913, -5579 },
+ { -149, 5381, 4366, -3297 },
+ { 985, 3672, 2644, -92 },
+ { -258, 2911, 5817, -2213 },
+ { 3428, 3289, 3351, -3541 },
+ { -666, 3295, 4727, -2869 },
+ { 35, 6641, 4160, -4052 },
+ { 623, 6787, 3156, -4560 },
+ { 2654, 4360, 4676, -4632 },
+ { 1386, 5246, 4834, -4497 },
+ { 3488, 4574, 3856, -5946 },
+ { 383, 4481, 4168, -4110 },
+ { 1753, 3652, 4288, -3326 },
+ { 1344, 4905, 2508, -4660 },
+ { 1580, 4106, 3104, -2224 },
+ { 2027, 5038, 1683, -1554 },
+ { 446, 3699, 5872, -3013 },
+ { 4637, 4087, 3578, -5018 },
+ { 2629, 3560, 5331, -4900 },
+ { 1527, 6674, 2523, -4131 },
+ { -1437, 2804, 2528, -4464 },
+ { -229, 3355, 2016, -5537 },
+ { 3666, 3418, 4374, -4581 },
+ { 1192, 3799, 923, -6596 },
+ { 2040, 2956, 448, -5322 },
+ { 2468, 5768, 4029, -5869 },
+ { 3438, 6516, 3529, -6667 },
+ { 2737, 5495, 680, -5535 },
+ { 3896, 5727, 1801, -4958 },
+ { 4988, 4957, 3592, -6518 },
+ { -542, 4416, 5794, -2787 },
+ { 4136, 4354, 2064, -4696 },
+ { 3067, 5936, 1207, -3396 },
+ { 2789, 4966, 2405, -3854 },
+ { 1731, 3270, 3251, -1063 },
+ { 1767, 5537, 2084, -2349 },
+ { 465, 3116, 4532, -837 },
+ { 1499, 2627, 4610, -2212 },
+ { 122, 3095, 3642, -3552 },
+ { 2542, 2866, 2705, -6402 },
+ { 3134, 4323, 698, -4785 },
+ { 731, 1859, 3112, -5242 },
+ { 2553, 2980, 3241, -4846 },
+ { 1329, 5310, 1607, -6624 },
+ { 2468, 1858, 3476, -1034 },
+ { -172, 4996, 2000, -5562 },
+ { 2621, 4220, 1574, -3386 },
+ { -333, 1832, 3362, -4117 },
+ { 2169, 6762, 3065, -6225 },
+ { 2844, 5528, 3223, -4765 },
+ { 526, 5175, 1644, -4267 },
+ { 2922, 4426, 2414, -2610 },
+ { 452, 1399, -4516, -2636 },
+ { 2872, 1720, -4667, -1435 },
+ { 1279, 702, -5424, -1984 },
+ { 2187, 870, -5021, -1341 },
+ { 583, -144, -4628, -2464 },
+ { 3, 2237, -5284, -2827 },
+ { -19, 1005, -5460, -1819 },
+ { 2897, 2084, -5885, -515 },
+ { -400, 3370, -5527, -2947 },
+ { 1505, 2593, -5518, -1802 },
+ { 1341, 4534, -5094, -1899 },
+ { 3241, 3670, -5493, -1252 },
+ { -1287, 921, -5994, -1675 },
+ { 627, 408, -6652, -364 },
+ { -260, 1127, -4849, -3247 },
+ { 371, 3400, -5976, -2285 },
+ { 1533, 1566, -6373, -610 },
+ { 2462, 4274, -6184, -1254 },
+ { 1782, 3363, -6222, -1381 },
+ { 572, 4650, -5673, -2754 },
+ { 2674, 3414, -4460, -2154 },
+ { 3614, 3820, -6883, -398 },
+ { 1136, -1, -5511, -1112 },
+ { -1773, 1137, -5647, -2377 },
+ { -753, 2104, -6085, -2565 },
+ { -204, 3025, -4731, -1418 },
+ { -1486, 1438, -4380, -216 },
+ { 302, 858, -5786, -264 },
+ { 3486, 1495, -5234, -783 },
+ { 888, 2327, -3423, -3720 },
+ { -259, 772, -6596, -1311 },
+ { -1197, 2073, -5174, -1826 },
+ { 1500, 3470, -4462, -2645 },
+ { 3072, 1960, -3277, -2264 },
+ { 1841, 952, -4324, -2340 },
+ { 1994, 2200, -3940, -2923 },
+ { -1782, 1699, -4667, -1075 },
+ { -1464, 2906, -3468, -375 },
+ { 366, 2380, -3747, 1467 },
+ { -545, 1645, -4619, 376 },
+ { 1724, 2350, -2374, -3512 },
+ { 3184, 2628, -2996, -3275 },
+ { 734, 2010, -6239, -1479 },
+ { 524, 3756, -4496, -3263 },
+ { 1492, 3570, -3494, -3600 },
+ { -932, 618, -5389, -2894 },
+ { -133, 2161, -4083, -3267 },
+ { 786, 774, -3279, -3731 },
+ { 1078, 803, -3843, -3007 },
+ { -332, 3405, -3347, 40 },
+ { -17, 6, -4005, -3690 },
+ { -189, 4372, -4488, -2561 },
+ { -450, 3846, -3790, -1370 },
+ { 362, 2212, -5272, -15 },
+ { -1529, 791, -6802, -2296 },
+ { 2145, 4241, -4474, 376 },
+ { 1813, 2426, -2932, -2726 },
+ { -542, 4557, -3140, -1080 },
+ { 1192, 3784, -4371, -20 },
+ { 2784, 5188, -6399, -1394 },
+ { 431, 4561, -3673, -1398 },
+ { 1382, 3096, -4083, 1253 },
+ { 1209, 4224, -2930, 1500 },
+ { 2798, 2684, -6676, -606 },
+ { -2396, 1510, -5381, -2713 },
+ { -2625, 2542, -4032, -2880 },
+ { -1231, 3967, -4098, -2886 },
+ { -1393, 2374, -3862, -4525 },
+ { -2495, 1665, -1637, -5445 },
+ { -3854, 1759, -1750, -4944 },
+ { -2373, 1668, -2856, -6251 },
+ { -2668, 1981, -886, -4557 },
+ { -2927, 4427, -3451, -6172 },
+ { -1925, 2596, -4696, -2527 },
+ { -3202, 2847, -3928, -5896 },
+ { -3332, 1665, -5025, -3412 },
+ { -3212, 3115, -4155, -4062 },
+ { -1013, 3205, -5133, -3751 },
+ { -2022, 4595, -3947, -5611 },
+ { -3556, 1755, -3715, -2300 },
+ { -1784, 4114, -2723, -1773 },
+ { -3586, 4081, -2733, -4942 },
+ { -1608, 3685, -4154, -4573 },
+ { -3368, 4042, -4452, -6227 },
+ { -1407, 3881, -5729, -3719 },
+ { -2751, 3281, -5077, -4999 },
+ { -3791, 2410, -4906, -5288 },
+ { -730, 2303, -4217, -3755 },
+ { -1812, 2311, -5492, -3709 },
+ { -610, 4336, -3915, -3783 },
+ { -2841, 4337, -4278, -4430 },
+ { -1662, 4666, -4661, -3964 },
+ { -589, 5209, -4923, -3682 },
+ { -4155, 2234, -4076, -4218 },
+ { -3951, 2770, -2665, -2805 },
+ { -2302, 3228, -3717, -1908 },
+ { -3129, 4373, -2264, -2851 },
+ { -447, 1363, -3578, -4323 },
+ { -2648, 4237, -3159, -3071 },
+ { -4072, 3241, -3541, -4605 },
+ { -4507, 3458, -2339, -3838 },
+ { -1646, 997, -4926, -3970 },
+ { -3025, 1614, -3940, -1242 },
+ { -1337, 1756, -3163, -5529 },
+ { -3203, 1865, -3282, -4354 },
+ { -1646, 2118, -2203, -6018 },
+ { 174, 1871, -2707, -4639 },
+ { -2607, 1485, -4778, -4750 },
+ { -2199, 3991, -3134, -4879 },
+ { -2962, 3323, -2816, -2419 },
+ { -5286, 2495, -4548, -5395 },
+ { -2810, 3710, -2274, -4211 },
+ { -330, 3006, -2993, -4678 },
+ { -1187, 2411, -2743, -5196 },
+ { -664, 4033, -3101, -5641 },
+ { -1458, 3602, -2816, -5371 },
+ { -4116, 4923, -3321, -5630 },
+ { -4165, 2528, -2592, -4798 },
+ { -2759, 3080, -2333, -5719 },
+ { -5157, 3011, -5526, -6348 },
+ { -3095, 2126, -5881, -4234 },
+ { -4377, 3849, -3600, -6099 },
+ { -1994, 4947, -5235, -4753 },
+ { -1067, 600, -3258, -5133 },
+ { -4992, 3302, -2208, -5051 },
+ { -3377, 2981, -1655, -4815 },
+ { -3325, 2446, -1787, -6116 },
+ { -2341, 2737, -3240, -6347 },
+ { -2258, -3732, 3710, -1235 },
+ { -1558, -3849, 2694, -3012 },
+ { -599, -4837, 3050, -2951 },
+ { -2246, -5433, 2798, -1910 },
+ { -2255, -4989, 3260, 270 },
+ { -3026, -5353, 2693, -1036 },
+ { -1151, -6097, 1097, -3782 },
+ { -3391, -6012, 2130, -1303 },
+ { -2850, -4422, 3375, -480 },
+ { -1138, -3779, 1491, -4162 },
+ { -551, -3892, 3787, -2082 },
+ { -3221, -3676, 3144, -1202 },
+ { -3023, -5196, 2650, 605 },
+ { -1756, -5729, 2646, 321 },
+ { -2693, -4409, 494, -4797 },
+ { -1913, -4573, 3372, -1730 },
+ { -1277, -3604, 4061, -993 },
+ { -420, -4993, 1351, -4796 },
+ { -3052, -5333, 1435, -1242 },
+ { -602, -5034, 3869, -1141 },
+ { -2436, -4680, 1665, -3019 },
+ { -2657, -3658, 1459, -3391 },
+ { -1220, -6246, 2749, -525 },
+ { -3838, -4844, 2265, -1735 },
+ { -1247, -5679, 3356, -1417 },
+ { -917, -5448, 3342, 105 },
+ { -1756, -6839, 2276, -2350 },
+ { -412, -5206, 1764, -3539 },
+ { -1439, -6915, 1442, -3750 },
+ { -1381, -4439, 3863, -282 },
+ { -3482, -4953, 2726, -336 },
+ { -1376, -5931, 1714, -1987 },
+ { -1716, -4405, 2608, 105 },
+ { -1590, -5191, 2652, -2704 },
+ { -2149, -6442, 2453, -1263 },
+ { -3426, -3832, 2334, -1829 },
+ { -2747, -5948, 2362, -173 },
+ { -2435, -3267, 2966, -1710 },
+ { -3979, -4282, 2705, -775 },
+ { -356, -4238, 2544, -4343 },
+ { -1363, -6471, 2817, -1836 },
+ { -2878, -5117, 218, -3149 },
+ { -3539, -5196, 1710, -2356 },
+ { -2888, -4537, 2746, -1701 },
+ { -1870, -4439, 1496, -4121 },
+ { -1486, -3388, 3349, -2145 },
+ { -3333, -4138, 1467, -2876 },
+ { -345, -5340, 1012, -1190 },
+ { -1672, -4992, 2289, -1029 },
+ { -2146, -5528, 3038, -635 },
+ { -316, -3656, 3426, -3152 },
+ { -2695, -5812, 2336, -2050 },
+ { -2067, -6052, 737, -3258 },
+ { -2664, -4205, -350, -1266 },
+ { -617, -5406, 80, -4853 },
+ { -2418, -3825, 1853, -1326 },
+ { -1961, -4339, 583, -4315 },
+ { -1495, -5141, -133, -5205 },
+ { -3208, -6440, 1691, -2069 },
+ { -2632, -3633, 2325, -2761 },
+ { -2624, -5670, 1252, -3676 },
+ { -3687, -5608, 687, -2833 },
+ { -3320, -5707, 16, -3877 },
+ { -2738, -6112, 84, -5135 },
+ { 2277, -5661, 3076, 843 },
+ { 1555, -5769, 2821, -5236 },
+ { 536, -6381, 603, -4910 },
+ { 734, -4609, 3314, -4092 },
+ { 1836, -4547, 3267, -4322 },
+ { -13, -5976, 3752, -1607 },
+ { 1423, -6318, 2336, 398 },
+ { 365, -7779, 1498, -534 },
+ { 2104, -8366, 2946, -1345 },
+ { 143, -5545, 1898, -3756 },
+ { 655, -6852, 1430, 148 },
+ { 4, -6653, 2397, -59 },
+ { 2346, -5996, 4562, -934 },
+ { 1229, -7104, 2963, -598 },
+ { -528, -7048, 2887, -1790 },
+ { 1451, -6857, 3900, -1637 },
+ { 554, -6018, 3336, 9 },
+ { 3278, -5758, 4034, 129 },
+ { 3541, -7145, 4905, -1575 },
+ { 2339, -6907, 3464, -301 },
+ { 2775, -7301, 1667, -3894 },
+ { 539, -7887, 991, -4156 },
+ { 2115, -7421, 3131, -3075 },
+ { 2803, -8546, 2564, -5836 },
+ { 2869, -5833, 1620, -4561 },
+ { 2591, -7281, 3215, -4719 },
+ { -1228, -8477, 706, -4782 },
+ { 1967, -5243, 4813, -1940 },
+ { 701, -7010, 2273, -3893 },
+ { 915, -8470, 1918, -5620 },
+ { -94, -6715, 156, -3873 },
+ { 1074, -5607, 4389, -1017 },
+ { 2739, -6551, 1227, -3521 },
+ { 725, -7835, 2701, -1291 },
+ { -493, -7475, 2263, -1075 },
+ { -412, -6508, 2984, -744 },
+ { 665, -5451, 3725, -2692 },
+ { 1499, -8129, 3564, -2072 },
+ { 2870, -6333, 4487, -2108 },
+ { 706, -5007, 3911, -152 },
+ { -482, -8660, 1483, -2900 },
+ { 2481, -6596, 2518, -1715 },
+ { 1403, -6414, 1398, -5387 },
+ { 652, -6267, 583, -5942 },
+ { 694, -7540, 646, -6272 },
+ { 2275, -7614, 256, -5015 },
+ { 1416, -9727, 1900, -3153 },
+ { 2760, -6433, 3875, -3771 },
+ { 2325, -11196, 2182, -5155 },
+ { 1223, -11061, 1377, -5097 },
+ { 108, -10603, 307, -4952 },
+ { -118, -8268, 1650, -1572 },
+ { 1839, -7943, 1755, -612 },
+ { 2501, -9056, 981, -2969 },
+ { 2902, -8476, 1491, -5780 },
+ { 1995, -11175, 1585, -3643 },
+ { 696, -8212, 828, -2474 },
+ { 1526, -8649, 1380, -1210 },
+ { 461, -7253, 3222, -2229 },
+ { 2966, -8641, 4121, -3271 },
+ { 833, -6039, 2361, -1086 },
+ { 3565, -7312, 1980, -5427 },
+ { 2850, -8671, 3760, -1846 },
+ { 2643, -7281, 2163, -173 },
+ { 3463, -3706, -3132, -923 },
+ { 1315, -3825, -3443, 2 },
+ { 2594, -4083, -3815, 670 },
+ { 1826, -4291, -2741, -155 },
+ { 868, -3749, -4175, -298 },
+ { 2008, -4237, -3897, -517 },
+ { 1242, -3493, -4335, -1335 },
+ { -88, -4142, -3390, -1529 },
+ { 2176, -3488, -3822, -975 },
+ { 1706, -5188, -3415, -637 },
+ { 2717, -6159, -2333, -882 },
+ { 1276, -3978, -4361, 537 },
+ { 2471, -5556, -2866, -208 },
+ { 799, -4673, -4086, 56 },
+ { 1901, -4786, -3533, 270 },
+ { 3036, -3902, -3606, -333 },
+ { 2249, -3317, -4319, -144 },
+ { 2594, -4207, -2105, -2930 },
+ { 4008, -4774, -2626, -902 },
+ { 1038, -3659, -3496, -2454 },
+ { 2725, -3597, -3298, -1535 },
+ { 1662, -5803, -2813, 175 },
+ { 705, -3757, -3441, -1484 },
+ { 1860, -5987, -2821, -886 },
+ { 3786, -4918, -2199, -1929 },
+ { 3683, -4235, -2547, -1287 },
+ { 2531, -4896, -2956, -1593 },
+ { 1005, -5585, -3324, -180 },
+ { 1625, -5229, -1756, -3642 },
+ { 1494, -5041, -2989, -2685 },
+ { 2718, -4655, -3224, -867 },
+ { 2374, -6640, -1745, -2975 },
+ { 2133, -6436, -2477, -1499 },
+ { 1833, -4418, -3523, -1512 },
+ { 1128, -4910, -2658, -1106 },
+ { 689, -4777, -2831, -2085 },
+ { 3593, -5280, -2627, -315 },
+ { 3264, -3771, -2673, -1861 },
+ { 3202, -5602, -2409, 402 },
+ { 552, -4618, -2221, -3002 },
+ { 3095, -5356, -2666, -1083 },
+ { 3401, -4609, -3146, 45 },
+ { 3051, -4662, -2192, -2232 },
+ { 2798, -5552, -2462, -1941 },
+ { 2354, -5815, -2223, -2619 },
+ { 192, -3708, -2807, -2658 },
+ { 1886, -4226, -1862, -3529 },
+ { 2526, -3976, -2819, -2332 },
+ { 1577, -3870, -2711, -2806 },
+ { 1288, -5588, -3382, -1403 },
+ { 2711, -5399, -1564, -3253 },
+ { 1459, -5492, -2222, -322 },
+ { 2823, -5091, -2886, 776 },
+ { 3559, -5821, -2109, -1360 },
+ { 1587, -6331, -2760, -1909 },
+ { 2139, -5213, -2874, -2120 },
+ { 1318, -4337, -3695, -2098 },
+ { 821, -4471, -1849, -565 },
+ { 3329, -4782, -1725, -89 },
+ { 582, -4914, -4105, -1119 },
+ { 417, -4144, -4072, -2529 },
+ { -199, -3803, -2765, -4042 },
+ { 2731, -4283, -2143, 1 },
+ { 2911, -6187, -1951, -2116 },
+ { 1573, -6094, -493, -2838 },
+ { 2081, -6927, -864, -3211 },
+ { 1058, -7826, 79, -364 },
+ { 3147, -5570, -684, -978 },
+ { 3572, -5856, 1060, 1824 },
+ { 1143, -6702, -1478, 338 },
+ { 2341, -7220, -88, 260 },
+ { 3639, -6861, 668, 815 },
+ { 2227, -6268, -1706, 446 },
+ { 3390, -6082, -353, 1302 },
+ { 1123, -7556, -1237, -430 },
+ { 1729, -7742, 729, -218 },
+ { 1457, -6774, 587, 579 },
+ { 505, -6919, -569, 371 },
+ { 1106, -7245, 78, 158 },
+ { 2755, -6745, -1122, 338 },
+ { 3069, -6040, -1415, 986 },
+ { 2174, -7064, -1430, -283 },
+ { 1390, -8626, -446, -3031 },
+ { 3534, -6890, -431, 547 },
+ { 2267, -9618, 475, -2994 },
+ { 3672, -7673, 75, -115 },
+ { 2131, -7560, -1206, -750 },
+ { 2972, -7477, -685, -262 },
+ { 1604, -6637, -672, 699 },
+ { 1666, -7577, -577, -240 },
+ { 1591, -6554, -2158, -94 },
+ { 2348, -6286, -353, 1123 },
+ { 2017, -8810, -412, -1805 },
+ { 2892, -6713, -1765, -554 },
+ { 2500, -6828, -1995, -1197 },
+ { 3877, -6639, -224, -1655 },
+ { 2392, -7872, -91, -333 },
+ { 3562, -7370, -532, -2836 },
+ { 2552, -7614, 164, -1805 },
+ { 990, -6104, 218, 438 },
+ { 910, -7861, 312, -1195 },
+ { 1472, -6327, 372, -640 },
+ { 1576, -7143, -1983, -843 },
+ { 422, -7625, -457, -278 },
+ { 1797, -8532, 405, -1011 },
+ { 1088, -7396, -238, -2277 },
+ { 3209, -6753, -1431, -2072 },
+ { 2617, -6839, 100, -2573 },
+ { 2575, -8573, -387, -3188 },
+ { 3618, -6971, -1190, -321 },
+ { 2205, -7361, -1695, -2008 },
+ { 2985, -6297, 1464, 1179 },
+ { 2804, -7310, 1053, 338 },
+ { 1362, -6074, -1163, -840 },
+ { 3336, -6325, -1794, 21 },
+ { 2836, -8109, 818, -329 },
+ { 2791, -5879, 560, 1546 },
+ { 2392, -6064, 135, 100 },
+ { 1838, -6194, 596, 1085 },
+ { 1926, -7515, -414, -4901 },
+ { 3225, -7298, -1202, -1189 },
+ { 3960, -7558, -659, -719 },
+ { 3442, -6647, -1692, -1095 },
+ { 3381, -6441, 262, -886 },
+ { 1431, -8150, -1186, -1406 },
+ { 340, -8498, -150, -899 },
+ { 3004, -8149, -260, -953 },
+ { 2749, -6611, 563, 873 },
+ { -6647, -1325, -4517, -4691 },
+ { -6005, -1657, -4089, -3797 },
+ { -3157, 588, -5213, -3068 },
+ { -3311, -1425, -6329, -3726 },
+ { -5866, -819, -3857, -2744 },
+ { -5001, -1799, -1075, -4621 },
+ { -5330, -2650, -2672, -4664 },
+ { -4930, -539, -2363, -4010 },
+ { -2984, 10, -3863, -5749 },
+ { -1055, -2106, -3713, -4267 },
+ { -5476, -502, -4279, -6504 },
+ { -5231, -1543, -5018, -6425 },
+ { -5134, -363, -3165, -5109 },
+ { -3953, -771, -4107, -6393 },
+ { -2159, -563, -3652, -5342 },
+ { -3888, -2321, -919, -5057 },
+ { -1236, -597, -4235, -4193 },
+ { -4053, 675, -3083, -6174 },
+ { -2793, -1089, -5396, -3460 },
+ { -3000, -44, -2209, -6575 },
+ { -3336, -1531, -4313, -5160 },
+ { -2127, 128, -4851, -3692 },
+ { -3321, 136, -2067, -5660 },
+ { -5215, 1404, -4374, -4356 },
+ { -2747, 400, -6340, -3691 },
+ { -3926, -599, -5361, -5006 },
+ { -2875, -2592, -5143, -4092 },
+ { -4991, -1958, -5322, -4891 },
+ { -4965, -1318, -6652, -5333 },
+ { -4920, -1691, -3388, -5561 },
+ { -3644, -3354, -2688, -5982 },
+ { -5076, -919, -4563, -2984 },
+ { -6114, 250, -3884, -3915 },
+ { -4014, 744, -3973, -1924 },
+ { -5543, -1041, -5557, -3847 },
+ { -4711, -1352, -5649, -2603 },
+ { -3362, 775, -5305, -4879 },
+ { -5001, 107, -3554, -2888 },
+ { -6258, -1651, -6356, -6566 },
+ { -4529, 407, -5003, -3865 },
+ { -5154, 550, -5278, -5465 },
+ { -4195, -467, -1894, -3129 },
+ { -5022, 1127, -3349, -3314 },
+ { -6075, 1250, -4313, -5641 },
+ { -2677, -2283, -2312, -5903 },
+ { -4113, 193, -1195, -4833 },
+ { -3940, -1048, -1389, -5079 },
+ { -3703, 917, -4043, -4451 },
+ { -3366, -4231, -1534, -5488 },
+ { -3326, -3583, -2091, -4903 },
+ { -5144, 1254, -2532, -4949 },
+ { -5982, -870, -2545, -4555 },
+ { -3925, -157, -5367, -2281 },
+ { -6419, -746, -5668, -4371 },
+ { -5787, 518, -7096, -5805 },
+ { -4258, 954, -6453, -4321 },
+ { -4771, -695, -4158, -1639 },
+ { -7078, -760, -5195, -5877 },
+ { -7348, 83, -4101, -4586 },
+ { -2430, 184, -2874, -1679 },
+ { -2284, -3943, -2924, -5034 },
+ { -1804, -1785, -3002, -4710 },
+ { -4399, -2772, -1815, -4637 },
+ { -6340, -2626, -2824, -5191 },
+ { -4998, -5168, -3480, 1905 },
+ { -3958, -5492, -1599, 1579 },
+ { -2471, -3755, -276, 3182 },
+ { -3033, -5779, -1063, 1554 },
+ { -2936, -4829, -1290, 2386 },
+ { -1835, -5073, -3051, 1299 },
+ { -1724, -3771, -3935, 2324 },
+ { -5070, -2550, -3692, 768 },
+ { -4326, -5333, -297, 1878 },
+ { -3472, -5619, -3094, 992 },
+ { -3027, -4384, -3038, 2265 },
+ { -3201, -5332, 67, 2200 },
+ { -1681, -4373, -1947, 2461 },
+ { -3221, -3329, -4238, 2564 },
+ { -1262, -2968, -2915, 3227 },
+ { -3419, -1878, -3373, 2110 },
+ { -2244, -5583, -2012, 1288 },
+ { -1971, -5266, -990, 1812 },
+ { -2975, -2778, -452, 4063 },
+ { -2198, -1165, -3298, 2965 },
+ { -4782, -4894, -4767, 664 },
+ { -6002, -3950, -2806, 2025 },
+ { -3142, -3162, -2859, 3295 },
+ { -3262, -3340, -4123, 1596 },
+ { -4014, -3918, -1955, 3361 },
+ { -1700, -3463, -1346, 3449 },
+ { -4245, -4445, -4743, 1644 },
+ { -4180, -3969, -401, 3281 },
+ { -2782, -5240, -4117, 1156 },
+ { -5744, -4040, -1439, 3470 },
+ { -5063, -4663, -323, 3172 },
+ { -4531, -3319, -844, 3988 },
+ { -6226, -5125, -2064, 2976 },
+ { -3115, -3267, -1531, 3898 },
+ { -4628, -4421, -2864, 2808 },
+ { -4559, -2989, -3442, 2024 },
+ { -1775, -4487, -656, 2477 },
+ { -2664, -1865, -1884, 4081 },
+ { -1828, -2575, -3894, 3378 },
+ { -6441, -3677, -2025, 1677 },
+ { -4141, -2156, -1191, 3474 },
+ { -4802, -1623, -1727, 2160 },
+ { -5474, -2745, -1475, 2498 },
+ { -3664, -1056, -1975, 2491 },
+ { -4672, -3062, -2235, 2933 },
+ { -4205, -5960, -2849, 1517 },
+ { -4995, -5708, -1739, 1805 },
+ { -4892, -6080, -4793, 872 },
+ { -4270, -4172, -4263, 2185 },
+ { -4687, -1470, -2905, 1023 },
+ { -6446, -5017, -3919, 1000 },
+ { -6046, -5538, -3943, 2006 },
+ { -6028, -3750, -3953, 771 },
+ { -5959, -4582, -5024, 824 },
+ { -5818, -2576, -2249, 1326 },
+ { -5659, -5345, -1119, 2500 },
+ { -3346, -4155, 606, 2749 },
+ { -5680, -4827, -2501, 1838 },
+ { -6193, -2543, -1295, 840 },
+ { -6871, -4925, -3512, 1801 },
+ { -5605, -1788, -1895, 779 },
+ { -3922, -5712, -4644, 510 },
+ { -4745, -3869, -4533, 99 },
+ { -2984, -4907, -399, 1497 },
+ { 1847, -478, 3061, -5812 },
+ { 4450, -1116, 3609, -6570 },
+ { 3139, 99, 3007, -5532 },
+ { 2590, -3782, 3138, -4770 },
+ { 1881, 1204, 5778, -3404 },
+ { 3631, 2060, 5566, -5038 },
+ { 3461, 1961, 5167, -3800 },
+ { 2947, 273, 4536, -4389 },
+ { 4453, -1730, 5788, -4370 },
+ { 4032, 1805, 2666, -4534 },
+ { 3487, -944, 2313, -6028 },
+ { 1313, 34, 4210, -4067 },
+ { 5632, -1502, 5825, -5855 },
+ { 7736, -547, 4879, -5476 },
+ { 4906, -1512, 4760, -5760 },
+ { 3843, 447, 1091, -4958 },
+ { 2982, -1135, 5442, -4386 },
+ { 3579, 271, 3031, -6770 },
+ { 3932, -211, 4688, -5507 },
+ { 4411, 1720, 2387, -5584 },
+ { 5379, -479, 4575, -6280 },
+ { 3613, -362, 2012, -4885 },
+ { 3744, -2013, 4493, -5073 },
+ { 5693, 109, 4379, -3362 },
+ { 5475, -621, 5317, -3985 },
+ { 6411, -673, 5708, -4752 },
+ { 4933, -796, 7262, -4290 },
+ { 2804, 444, 6276, -3655 },
+ { 4120, -517, 6078, -4531 },
+ { 5119, 841, 3486, -3910 },
+ { 4738, 1539, 3525, -2970 },
+ { 5086, 370, 5895, -5640 },
+ { 4235, 2716, 4589, -5044 },
+ { 3691, 682, 6199, -4700 },
+ { 6111, -570, 6271, -6528 },
+ { 2611, 1277, 3756, -4802 },
+ { 4395, 970, 3807, -5879 },
+ { 5225, 2299, 3242, -4333 },
+ { 5144, 1778, 4946, -5545 },
+ { 2989, -3016, 3247, -5495 },
+ { 2983, 920, 2071, -6059 },
+ { 5270, -903, 4434, -2350 },
+ { 6415, -585, 3970, -3554 },
+ { 3866, -197, 5216, -2884 },
+ { 3767, -1298, 6702, -3315 },
+ { 6299, 2620, 5284, -6824 },
+ { 6654, 646, 3653, -4927 },
+ { 4770, 3047, 5160, -6287 },
+ { 5364, 434, 2919, -5207 },
+ { 2998, 1344, 4801, -2456 },
+ { 3896, 1013, 3773, -1864 },
+ { 2115, 655, 2999, -6344 },
+ { 5170, -981, 2849, -4464 },
+ { 2735, -2159, 2717, -5776 },
+ { 2430, -1952, 4392, -4559 },
+ { 6143, -1180, 3659, -4746 },
+ { 4978, -1483, 1726, -4875 },
+ { 3486, -2383, 3306, -4301 },
+ { 1434, -1372, 4171, -4770 },
+ { 3354, -2627, 1525, -5093 },
+ { 6790, 2386, 3995, -5909 },
+ { 1475, -2674, 3451, -4204 },
+ { 1999, -3494, 3693, -5556 },
+ { 4764, -2848, 2856, -5589 },
+ { -3677, 5131, 2827, -2934 },
+ { -2844, 7078, 2852, -3580 },
+ { -3902, 6434, 4118, -1911 },
+ { -1769, 7530, 3492, -3541 },
+ { -1937, 5679, -447, -1127 },
+ { -2456, 4680, 4196, -2407 },
+ { -2778, 8241, 1698, -4288 },
+ { -2876, 6104, 5182, -2387 },
+ { -2802, 7341, 4463, -2938 },
+ { -1025, 6267, 4752, -3201 },
+ { -2349, 5413, 2041, -3794 },
+ { -2252, 8225, 2856, -4269 },
+ { -1465, 4967, 4976, -2500 },
+ { -636, 7565, 3517, -4233 },
+ { -1905, 5618, 3904, -2942 },
+ { -302, 6816, 3343, -3316 },
+ { -2210, 4156, 2817, -3511 },
+ { -717, 6568, 1863, -2951 },
+ { -3873, 5682, 2164, -575 },
+ { -2878, 5835, 440, -2597 },
+ { -3228, 7701, 2610, -2514 },
+ { -3608, 8888, 3377, -2468 },
+ { -2582, 9717, 2519, -3126 },
+ { -5238, 6202, 2866, -2831 },
+ { -3428, 7370, 3056, -335 },
+ { -1681, 8836, 1210, -2010 },
+ { -3276, 6724, 1156, -3930 },
+ { -894, 8149, 827, -1258 },
+ { -2965, 8631, 2549, -1320 },
+ { -3961, 6902, 3581, 55 },
+ { -1894, 7745, 1750, -841 },
+ { -821, 6844, 850, -676 },
+ { -608, 6948, -4, -1376 },
+ { 615, 6524, 1089, -1147 },
+ { -2972, 5668, 1091, -489 },
+ { -157, 4649, 2904, -413 },
+ { 673, 5121, 1498, -66 },
+ { -390, 5902, 1611, -245 },
+ { -2349, 5478, 4772, -1320 },
+ { 88, 6798, 1972, -1859 },
+ { -1213, 5120, 2991, 200 },
+ { -2347, 6040, 2839, 376 },
+ { -578, 5976, 3364, -1796 },
+ { -1391, 5872, 3002, -965 },
+ { -564, 4496, 3946, -1186 },
+ { -2299, 6386, 3135, -2176 },
+ { -2131, 5641, 2011, 1223 },
+ { -772, 5807, 1124, 895 },
+ { -2837, 6758, 2297, -740 },
+ { -3091, 6298, 1415, -2126 },
+ { -4197, 6036, 1843, -3022 },
+ { -41, 6459, 92, 344 },
+ { -2241, 6860, 2095, -4396 },
+ { -1931, 7088, 2117, -2135 },
+ { -2375, 4422, 1688, -3169 },
+ { -1742, 6674, 1538, -119 },
+ { -4818, 7749, 4192, -1577 },
+ { -2004, 5672, 193, -430 },
+ { -3825, 6042, 2128, -1898 },
+ { -1108, 8033, 2119, -3013 },
+ { -2370, 5453, 1721, 266 },
+ { -1570, 7134, 614, -2638 },
+ { -1519, 8752, 3503, -4330 },
+ { -2050, 3845, 2907, -1126 },
+ { 5085, 4412, -335, -1923 },
+ { 3618, 1423, -613, -4012 },
+ { 4481, 3729, 589, -4631 },
+ { 4270, 3216, -1763, -3168 },
+ { 4241, 1796, -1701, -2796 },
+ { 4787, 2338, -487, -3639 },
+ { 2915, 3429, -621, -4753 },
+ { 5175, 1660, -1265, -3223 },
+ { 4280, 4057, -684, -4079 },
+ { 4980, 4419, -1455, -2719 },
+ { 5436, 2464, 387, -4197 },
+ { 4507, 4018, 1121, -3314 },
+ { 6020, 2401, -413, -3201 },
+ { 4200, 3789, -333, -2813 },
+ { 5229, 2493, -1194, -1878 },
+ { 5851, 2695, -492, -2292 },
+ { 5743, 3288, -697, -1221 },
+ { 5692, 2612, 979, -2227 },
+ { 5085, 2067, 1046, -1214 },
+ { 3163, 2240, -2098, -3435 },
+ { 5228, 1898, 145, -2397 },
+ { 5860, 3976, -418, -2872 },
+ { 6008, 3399, 1027, -3506 },
+ { 4126, 2035, 1865, -893 },
+ { 5375, 3596, 511, -2362 },
+ { 1937, 1493, -852, -122 },
+ { 3473, 4849, 547, -2603 },
+ { 4631, 2977, 1141, -1768 },
+ { 6149, 3050, -71, -1886 },
+ { 4069, 4353, -289, -1429 },
+ { 2884, 1225, -1388, 365 },
+ { 5485, 2518, -235, -571 },
+ { 1216, 4375, 1443, 398 },
+ { 4988, 3106, 107, -1435 },
+ { 4511, 2801, 307, -444 },
+ { 3235, 4386, 327, -676 },
+ { 2055, 3708, 1657, -305 },
+ { 5839, 2374, 290, -1385 },
+ { 5110, 3305, 1936, -4206 },
+ { 6416, 2920, 338, -2736 },
+ { 3350, 2824, -1269, -3881 },
+ { 4840, 1815, 464, 186 },
+ { 2399, 3332, 238, 1238 },
+ { 3516, 1363, 1582, 688 },
+ { 3582, 1874, 154, -4770 },
+ { 3261, 2878, 886, 283 },
+ { 3877, 2658, -327, 884 },
+ { 4151, 3436, 2173, -2923 },
+ { 3592, 3674, 1281, -1295 },
+ { 4561, 3730, -1114, -1747 },
+ { 4595, 3625, -558, -575 },
+ { 2577, 2348, 2267, 120 },
+ { 5242, 3299, 32, -3412 },
+ { 4264, 3637, 709, -2320 },
+ { 6556, 3570, -838, -2472 },
+ { 5745, 4014, -940, -1973 },
+ { 5629, 4475, 477, -3328 },
+ { 5269, 3199, 1682, -3085 },
+ { 4432, 2416, 1145, -3299 },
+ { 4465, 2505, 2162, -2186 },
+ { 4643, 4941, -88, -2885 },
+ { 4568, 5231, 552, -3915 },
+ { 5667, 3075, -1406, -2963 },
+ { 5418, 5259, -771, -2818 },
+ { -256, -7875, 511, -471 },
+ { -1813, -7971, -424, -396 },
+ { -306, -7006, 862, 282 },
+ { -2306, -6422, -1440, 508 },
+ { -245, -6787, 375, -100 },
+ { -1309, -6065, -20, 779 },
+ { -1656, -6047, -641, 1307 },
+ { -1496, -6522, 964, 726 },
+ { -2291, -6588, -202, 795 },
+ { -762, -7522, 1454, -558 },
+ { -2270, -7004, -834, -580 },
+ { -1139, -7078, 259, 362 },
+ { -2535, -7568, -1040, 49 },
+ { -3786, -7280, 934, -476 },
+ { -3336, -6368, 606, 1056 },
+ { -3602, -6924, 52, 714 },
+ { -2278, -6550, 1674, 204 },
+ { -2855, -5765, 930, 1530 },
+ { -2889, -7325, -215, 305 },
+ { -2749, -6080, -237, 1452 },
+ { -985, -6667, 1577, 400 },
+ { -2036, -6083, 380, 1267 },
+ { -2077, -7460, 380, -30 },
+ { -1775, -7175, 1540, -386 },
+ { -3065, -6927, 989, 168 },
+ { -2836, -7602, 117, -3392 },
+ { -1058, -6396, 593, -3078 },
+ { -844, -6062, 999, -236 },
+ { -3261, -6951, 1491, -720 },
+ { -2186, -8484, 75, -1287 },
+ { -2882, -7756, 456, -510 },
+ { -1800, -6879, 960, -1183 },
+ { -2554, -7241, 1614, -1474 },
+ { -2608, -5305, 392, 851 },
+ { -2973, -6562, -859, 858 },
+ { -2640, -5989, 1031, -416 },
+ { -977, -8366, 705, -1434 },
+ { -1213, -7409, -77, -1390 },
+ { -1335, -6657, 2125, -123 },
+ { -2544, -6862, 1852, -737 },
+ { -3235, -6422, 1752, -103 },
+ { -1300, -7557, 939, -348 },
+ { -3476, -7579, 202, -109 },
+ { -2482, -6572, 753, 619 },
+ { -2554, -8136, -648, -429 },
+ { -1012, -7870, -3, -421 },
+ { -3604, -6247, 32, -3102 },
+ { -1486, -7271, 2013, -1021 },
+ { -578, -6799, -523, 405 },
+ { -2841, -5948, 1644, 911 },
+ { -2411, -7473, 1084, -484 },
+ { -2238, -6033, 294, -1059 },
+ { -3459, -6470, -201, -790 },
+ { -2027, -6009, 1833, 805 },
+ { -1433, -8047, 1531, -1754 },
+ { -3258, -7884, 763, -1422 },
+ { -1544, -6928, -729, 478 },
+ { -2314, -8415, 74, -3757 },
+ { -3201, -5684, 95, -2214 },
+ { -2423, -8694, 725, -3631 },
+ { -3545, -7071, 1162, -1798 },
+ { -294, -9662, 403, -2274 },
+ { -2290, -5460, 1196, 402 },
+ { -1603, -6713, 903, -2363 },
+ { 4121, 2491, -3142, -2482 },
+ { 4500, 3305, -3671, -1567 },
+ { 5973, 3172, -1348, -534 },
+ { 4830, 3379, -1549, 643 },
+ { 5214, 3938, -2641, -2302 },
+ { 4639, 4826, -5532, -847 },
+ { 5639, 2731, -2170, -963 },
+ { 6084, 3487, -3525, -1346 },
+ { 5971, 3154, -2190, -2316 },
+ { 5618, 4865, -6927, 116 },
+ { 5345, 3568, -7391, 709 },
+ { 5429, 5078, -3811, -1524 },
+ { 6960, 2037, -3515, -1096 },
+ { 7092, 2531, -4557, -588 },
+ { 6061, 4247, -5651, -478 },
+ { 4595, 3684, -4907, -827 },
+ { 7497, 3213, -3048, -424 },
+ { 5996, 2137, -3098, -1745 },
+ { 6198, 5199, -2223, -2274 },
+ { 6888, 2851, -2768, -1675 },
+ { 6114, 4210, -2316, -954 },
+ { 7127, 4242, -3041, -1408 },
+ { 6126, 3668, -1517, -1427 },
+ { 6245, 6129, -4225, -1186 },
+ { 6816, 3213, -2101, -964 },
+ { 5345, 5276, -2643, -847 },
+ { 6592, 4665, -4338, 484 },
+ { 6746, 3751, -3443, 124 },
+ { 5453, 1980, -2738, 2606 },
+ { 4662, 2179, -4226, -1059 },
+ { 5571, 3208, -3554, 174 },
+ { 5256, 4447, -1815, -1481 },
+ { 5400, 2570, -1210, 235 },
+ { 7056, 2549, -2674, 318 },
+ { 4574, 4340, -2892, -130 },
+ { 6203, 4587, -3273, -305 },
+ { 5103, 1925, -2715, -2137 },
+ { 3905, 4296, -1700, 247 },
+ { 4421, 4605, -3299, 811 },
+ { 5671, 1273, -3870, -924 },
+ { 5486, 1805, -4901, 133 },
+ { 6437, 2578, -1828, -106 },
+ { 5530, 5253, -5058, 1223 },
+ { 4816, 2025, -1215, 1443 },
+ { 3457, 3525, -2456, 3217 },
+ { 3316, 2595, -1108, 2459 },
+ { 3068, 3810, -2207, 1926 },
+ { 6351, 5436, -6470, 600 },
+ { 6324, 4240, -5365, 2416 },
+ { 4851, 4774, -4075, 1878 },
+ { 4900, 3679, -5198, 1078 },
+ { 8347, 3633, -4565, -171 },
+ { 5244, 5718, -3853, 173 },
+ { 3960, 3492, -2939, 2105 },
+ { 6070, 3473, -2351, 161 },
+ { 8228, 3034, -3360, -901 },
+ { 7006, 3985, -1940, -1926 },
+ { 7123, 4681, -4301, -878 },
+ { 5122, 4097, -1851, -449 },
+ { 6200, 2060, -2251, 1049 },
+ { 7106, 3844, -7209, 2625 },
+ { 7108, 3370, -6734, 533 },
+ { 6859, 2849, -3992, 1360 },
+ { 5458, 2278, -3253, 1131 },
+ { -1072, -2109, 4783, -1073 },
+ { -319, -2604, 4257, -2418 },
+ { 2466, 1300, 3476, -314 },
+ { 2847, -1502, 5296, -141 },
+ { 1667, -1273, 5559, -2725 },
+ { 2877, -3402, 6434, 204 },
+ { 53, -2637, 5275, -1181 },
+ { 1091, -2215, 5803, -1549 },
+ { 2397, -922, 4327, 1182 },
+ { 219, -3747, 4647, -1564 },
+ { -29, -2705, 4812, 1277 },
+ { 1499, -2608, 5648, 1407 },
+ { 2139, -2399, 4202, 2791 },
+ { -426, -2064, 5528, 151 },
+ { 2560, -2803, 6179, -2806 },
+ { 4537, -2479, 3797, 1095 },
+ { 888, -3357, 5341, -415 },
+ { 4460, -1814, 5388, -1227 },
+ { 3920, -3268, 6364, -703 },
+ { 3343, -4698, 4410, 784 },
+ { 309, -1897, 6306, 1223 },
+ { 958, -3318, 4254, -3167 },
+ { -99, 1596, 6018, -1983 },
+ { -429, -853, 6407, 878 },
+ { 1170, -1322, 6290, -417 },
+ { 2288, -505, 6303, -1999 },
+ { 3312, -1674, 6749, -2494 },
+ { -415, -3401, 4721, -371 },
+ { -189, -1210, 4844, -2002 },
+ { 888, -4142, 4377, 130 },
+ { 2469, -4381, 5398, -2492 },
+ { 2879, -2912, 5094, -2598 },
+ { -717, -617, 5650, -685 },
+ { 1470, -3863, 5352, -1684 },
+ { 3935, -96, 3823, -730 },
+ { 3769, -430, 3168, 694 },
+ { 2556, 385, 3539, 512 },
+ { 77, -1415, 5111, 2655 },
+ { 2724, -2158, 6715, -822 },
+ { 1832, 1001, 5385, -1900 },
+ { 900, 2198, 4464, -559 },
+ { 441, 69, 5921, -1743 },
+ { -1161, 738, 6732, -308 },
+ { 257, 2035, 4091, 736 },
+ { 1607, 1288, 4355, -23 },
+ { -13, 1316, 4180, 1672 },
+ { 1511, 1336, 3057, 1435 },
+ { 2189, -3813, 4530, 939 },
+ { 3632, -706, 2646, 1375 },
+ { 4266, -3761, 4241, 1077 },
+ { 3101, -427, 5273, -1202 },
+ { 2293, 276, 4810, -313 },
+ { 3430, -1851, 3101, 2045 },
+ { 3453, -2979, 5142, 942 },
+ { 1683, -3281, 4802, 2002 },
+ { 3954, -4715, 5611, 578 },
+ { 1272, -155, 5085, 454 },
+ { 128, -194, 5095, 1409 },
+ { 820, 880, 5797, -2658 },
+ { -1095, 656, 5774, 1095 },
+ { 813, -1669, 4320, -3251 },
+ { -119, 518, 6372, -651 },
+ { 2922, -4299, 6115, -877 },
+ { 4205, -4273, 4004, 2642 },
+ { -1211, -3892, 224, 3127 },
+ { -34, -4371, 1321, 2318 },
+ { 77, -6326, 1201, 828 },
+ { 3995, -3775, 1958, 3233 },
+ { 178, -3301, 1985, 3318 },
+ { 2330, -3801, 1033, 3195 },
+ { 1413, -5536, 826, 1709 },
+ { 2468, -3499, 3653, 3631 },
+ { 741, -4617, 1723, 2008 },
+ { 1246, -3043, 2978, 3949 },
+ { -343, -4308, 2258, 2189 },
+ { -682, -4640, 454, 2272 },
+ { 1236, -4829, 2491, 1642 },
+ { -512, -3766, 1182, 3052 },
+ { 119, -3939, 3712, 971 },
+ { -1145, -4624, 1360, 2281 },
+ { 101, -4746, 2866, 1255 },
+ { -1500, -5455, 539, 1637 },
+ { -969, -5909, 1414, 1128 },
+ { -1261, -4939, -231, 2022 },
+ { -226, -5345, 1207, 705 },
+ { 2712, -5109, 3205, 1866 },
+ { -476, -5913, 273, 1208 },
+ { -2039, -4464, 624, 2545 },
+ { -2351, -3930, 2019, 2673 },
+ { -2675, -4849, 1522, 1990 },
+ { -1524, -3461, 1446, 3204 },
+ { 477, -5314, 1710, 1577 },
+ { 656, -3729, 2346, 2511 },
+ { 550, -5917, 1975, 1040 },
+ { 1728, -4704, 3067, 1058 },
+ { -9, -5247, 506, 1760 },
+ { -574, -5135, 1675, 1672 },
+ { 2129, -3781, 3444, 2313 },
+ { 1144, -4439, 2214, 2529 },
+ { 1292, -4160, 3185, 1833 },
+ { 2445, -3262, 2534, 3227 },
+ { 2266, -4401, 2023, 2400 },
+ { -587, -3602, 3408, 2067 },
+ { -885, -4951, 3228, 1174 },
+ { -728, -2711, 2807, 3552 },
+ { 1019, -3043, 3195, 2954 },
+ { 1888, -4615, 1140, 2454 },
+ { 660, -5616, 754, 800 },
+ { -1975, -5371, 1649, 1585 },
+ { -1544, -5436, 2422, 1081 },
+ { -422, -5882, 2390, 750 },
+ { 1336, -5557, 2441, 1230 },
+ { 136, -4001, 267, 2854 },
+ { -522, -3289, 2226, 2728 },
+ { -971, -4580, 2471, 708 },
+ { 704, -5306, 3300, 1001 },
+ { 325, -3464, 3555, 2398 },
+ { 794, -3686, 848, 3169 },
+ { 660, -3017, 4584, 3242 },
+ { -1486, -3978, 2170, 1644 },
+ { -1615, -4650, 2688, 1844 },
+ { 750, -4578, 538, 2239 },
+ { 1668, -5849, 1455, 1031 },
+ { 3486, -4681, 2030, 2183 },
+ { 2642, -5429, 1696, 1761 },
+ { 4491, -4502, 3538, 2767 },
+ { 3545, -4528, 3514, 2982 },
+ { 3269, -3676, 2758, 3966 },
+ { 5572, 1146, 209, -3379 },
+ { 7459, 1053, 593, -1896 },
+ { 4480, 200, -310, -4259 },
+ { 5577, -939, 242, -3992 },
+ { 8142, 442, 1257, -3083 },
+ { 5442, 1261, 1424, -3236 },
+ { 6260, -183, 3125, -2532 },
+ { 7179, 889, 1618, -2548 },
+ { 6416, 932, 2379, -2487 },
+ { 7094, 2560, 961, -3392 },
+ { 7322, 463, 2732, -3735 },
+ { 6632, 1577, 1912, -3272 },
+ { 6312, 1349, 3028, -3460 },
+ { 6105, 386, 1213, -977 },
+ { 5478, 1158, 1114, -486 },
+ { 6493, 410, 1686, -2180 },
+ { 6378, 1881, 1333, -2240 },
+ { 5711, 812, 1958, -1300 },
+ { 6844, 877, 730, -1189 },
+ { 6824, -245, 2249, -2000 },
+ { 7515, 1521, 1251, -3058 },
+ { 6697, 1051, 1300, -1749 },
+ { 6476, 1425, 811, -2773 },
+ { 7350, 465, -76, -2849 },
+ { 6975, 2095, 567, -2492 },
+ { 4691, 1736, 2660, -2289 },
+ { 7837, 1456, 340, -2767 },
+ { 7930, 507, 838, -2074 },
+ { 6106, 1502, 766, -1110 },
+ { 4891, -659, 835, -3954 },
+ { 7250, 141, 1369, -1523 },
+ { 7651, 67, 1651, -2298 },
+ { 7364, -305, 601, -3132 },
+ { 7179, 193, 2491, -2871 },
+ { 6504, -272, 2167, -1322 },
+ { 4456, 983, 2300, -421 },
+ { 4817, 457, 1695, 371 },
+ { 6914, 555, 850, -3159 },
+ { 5904, 1030, 202, -1959 },
+ { 6258, 880, 2233, -4503 },
+ { 6029, 10, 2130, -3600 },
+ { 6449, 985, 1129, -3963 },
+ { 6616, -18, -111, -3285 },
+ { 4496, 775, 817, -4276 },
+ { 6134, 2338, 1470, -2973 },
+ { 6911, 152, 430, -1946 },
+ { 4053, 991, 3218, -1193 },
+ { 5435, 1285, 3124, -2412 },
+ { 5507, 1836, 1935, -1988 },
+ { 5240, 689, 2189, -2670 },
+ { 6638, 1719, 606, -1799 },
+ { 5556, -180, 129, -2595 },
+ { 5644, 1918, 1281, -4316 },
+ { 6410, 1088, -282, -3117 },
+ { 6503, 1841, 312, -3514 },
+ { 6947, 20, 1358, -3886 },
+ { 5464, 2109, 2398, -3194 },
+ { 5616, -407, 2140, -498 },
+ { 6121, 2707, 2379, -4096 },
+ { 7303, 1846, 2266, -4095 },
+ { 5444, 470, 2718, -1553 },
+ { 5817, -645, 3285, -1349 },
+ { 5625, 1427, 1103, -1991 },
+ { 6041, -806, 1196, -2943 },
+ { 3050, -5722, 4070, -5460 },
+ { 3420, -4386, 4078, -5155 },
+ { 6020, -3982, 7268, -2689 },
+ { 7502, -4317, 7894, -3973 },
+ { 4156, -3558, 5247, -4316 },
+ { 4725, -4401, 7290, -1540 },
+ { 6688, -5122, 8216, -3210 },
+ { 9176, -6576, 9276, -4963 },
+ { 8706, -5708, 7987, -4621 },
+ { 7060, -3535, 6532, -3308 },
+ { 5600, -2719, 5363, -1568 },
+ { 4661, -2803, 6263, -4716 },
+ { 3673, -3636, 6147, -3433 },
+ { 5305, -2585, 6073, -2638 },
+ { 7614, -1962, 6079, -5266 },
+ { 6760, -3366, 7382, -4322 },
+ { 6385, -3883, 4797, -1353 },
+ { 8182, -5120, 4298, -4641 },
+ { 9130, -6198, 4975, -3063 },
+ { 7421, -5436, 5576, -3713 },
+ { 3483, -4898, 5443, -2745 },
+ { 4907, -5643, 6390, -4105 },
+ { 8119, -7008, 7992, -6764 },
+ { 6528, -6122, 6967, -5590 },
+ { 5890, -4190, 6624, -5688 },
+ { 6815, -7934, 7275, -5456 },
+ { 5434, -4306, 5169, -5378 },
+ { 4364, -6436, 5376, -2604 },
+ { 8152, -3404, 5913, -5048 },
+ { 7983, -4863, 4262, -2461 },
+ { 8023, -6188, 6238, -5062 },
+ { 6753, -3692, 3935, -3723 },
+ { 6826, -4760, 3284, -4051 },
+ { 7224, -7423, 4492, -3875 },
+ { 6904, -2590, 6587, -6248 },
+ { 6106, -1944, 7345, -5506 },
+ { 4956, -2990, 7808, -3146 },
+ { 6908, -6885, 5949, -1288 },
+ { 7162, -6058, 3419, -3401 },
+ { 7015, -7080, 6907, -3018 },
+ { 6971, -6832, 5646, -3273 },
+ { 8014, -5546, 5471, -1544 },
+ { 6792, -2220, 5105, -2879 },
+ { 8494, -3974, 4408, -3999 },
+ { 9591, -4866, 6027, -4558 },
+ { 5264, -5161, 6101, -738 },
+ { 5803, -6141, 5197, -5231 },
+ { 4657, -6822, 3232, -5189 },
+ { 4791, -5135, 3809, -4665 },
+ { 6108, -5103, 2379, -3873 },
+ { 4680, -3909, 3234, -5093 },
+ { 5802, -3853, 3795, -4984 },
+ { 4360, -7483, 4802, -3877 },
+ { 5429, -7517, 5911, -3717 },
+ { 6866, -2280, 4880, -4634 },
+ { 10131, -4628, 4414, -4092 },
+ { 10811, -5189, 7746, -5337 },
+ { 5663, -8941, 5287, -5680 },
+ { 8023, -5991, 7403, -2796 },
+ { 9669, -6919, 6525, -4932 },
+ { 7275, -3796, 4962, -2547 },
+ { 8848, -4806, 5677, -3080 },
+ { 8128, -4308, 7749, -6569 },
+ { 4032, -5196, 2282, -6239 },
+ { 6593, 700, -229, 304 },
+ { 8260, 539, -66, -1259 },
+ { 6605, 176, -814, -109 },
+ { 8057, 0, -1, -136 },
+ { 7382, -38, -484, -1129 },
+ { 8373, -929, 682, -454 },
+ { 7674, 690, -1278, 546 },
+ { 7326, -517, 406, -1283 },
+ { 7612, -1715, -1167, 1175 },
+ { 8590, 441, -782, -710 },
+ { 8572, -1202, -291, 260 },
+ { 7308, -147, -1785, 414 },
+ { 6787, -353, -672, 934 },
+ { 5177, -133, 179, 82 },
+ { 4161, -34, 447, 1497 },
+ { 5997, -902, 1533, -121 },
+ { 5727, -871, -1370, 945 },
+ { 8386, -252, 293, -823 },
+ { 6573, -1354, 682, 616 },
+ { 7650, -2096, 725, 457 },
+ { 8122, 78, 636, -1400 },
+ { 8421, 428, -1620, 131 },
+ { 7341, -1292, -717, 186 },
+ { 7998, -49, -720, 266 },
+ { 5987, -351, 669, 844 },
+ { 7314, -1620, 250, -603 },
+ { 7219, -1562, -572, 1994 },
+ { 8682, -358, -290, -388 },
+ { 5810, 155, -178, 1199 },
+ { 7246, -12, 1042, -786 },
+ { 7357, -923, 1468, -475 },
+ { 7801, 621, -212, -724 },
+ { 5346, -514, 1210, 1356 },
+ { 8459, 36, -127, -779 },
+ { 6878, -2429, 854, 1750 },
+ { 7280, -1401, -1353, 2845 },
+ { 7579, -2148, -1463, 2087 },
+ { 6637, 946, -872, 750 },
+ { 4807, -1100, 1289, 2602 },
+ { 4495, 219, 1551, 1128 },
+ { 7639, 506, 446, -1107 },
+ { 6359, 188, 1009, -115 },
+ { 6641, -1820, 1655, 723 },
+ { 5394, -2382, 1604, 2542 },
+ { 6021, -2644, 2396, 1407 },
+ { 4698, 882, 245, 1525 },
+ { 8103, 573, -798, -349 },
+ { 8045, -519, 997, -1092 },
+ { 7571, -122, 227, -338 },
+ { 5347, -1200, 630, 1718 },
+ { 7070, 790, 218, -544 },
+ { 7440, 728, -527, -20 },
+ { 6402, -355, 197, -736 },
+ { 4031, 771, 866, 1895 },
+ { 6009, 896, 445, -31 },
+ { 5160, 1098, -856, 1784 },
+ { 7980, -886, -1293, 1396 },
+ { 6318, -1361, 2423, 252 },
+ { 7547, -699, 133, 506 },
+ { 8562, -2344, 940, 264 },
+ { 5890, 1187, -1425, 2194 },
+ { 6558, -645, -1311, 2621 },
+ { 4634, -1671, 2075, 1623 },
+ { 5614, 105, -816, 2376 },
+ { 6646, 1558, -1365, 630 },
+ { 6998, 1150, -2117, -990 },
+ { 6555, 2311, -1093, -1783 },
+ { 6682, 1430, -2391, -1940 },
+ { 7861, 1555, -2977, -1188 },
+ { 6745, 1723, -459, -2085 },
+ { 7504, 1229, -1666, -2060 },
+ { 7937, 671, -2128, -1529 },
+ { 7139, 991, -735, -2632 },
+ { 6867, 1592, -1303, -2324 },
+ { 6401, 2230, -1732, -2508 },
+ { 7201, 2184, -2169, -1988 },
+ { 6636, 2190, -995, -2840 },
+ { 7620, 2306, -2089, -651 },
+ { 7584, 1875, -1438, -631 },
+ { 9214, 1561, -2464, -1139 },
+ { 6154, 1318, -1237, -2917 },
+ { 7917, 2847, -1797, -1599 },
+ { 8309, 2029, -2555, -465 },
+ { 8204, 1282, -584, -2405 },
+ { 8440, 1035, -1147, -1137 },
+ { 7107, 1858, -60, -1568 },
+ { 6781, 2912, -873, -1463 },
+ { 7603, 1316, -319, -1249 },
+ { 7833, 1335, -78, -1849 },
+ { 7930, 1141, -1016, -695 },
+ { 7883, 1610, -1017, -1314 },
+ { 8069, 1409, -1811, -196 },
+ { 8319, 1031, -582, -1590 },
+ { 5948, 1537, -2153, -2373 },
+ { 8684, 1171, -1871, -850 },
+ { 8357, 2484, -2411, -1292 },
+ { 6516, 2092, -193, -1167 },
+ { 6112, 1697, 22, -525 },
+ { 7161, 703, -602, -1879 },
+ { 6047, 2351, -807, -219 },
+ { 8072, 1854, -1817, -1553 },
+ { 6956, 1304, 76, -1011 },
+ { 6607, 1481, -544, -162 },
+ { 6958, 2541, -265, -1938 },
+ { 6416, 2514, -777, -850 },
+ { 7272, 2110, -899, -1171 },
+ { 7741, 2153, -283, -2614 },
+ { 6482, 2041, -1758, -1221 },
+ { 6762, 940, -1862, -2281 },
+ { 5610, 1194, -1691, -1561 },
+ { 7833, 2164, -823, -1952 },
+ { 5460, 1438, -848, 1189 },
+ { 6011, 1377, -771, -1557 },
+ { 7679, 544, -1134, -2214 },
+ { 7209, 1292, -2714, -1564 },
+ { 5567, 1200, -404, -169 },
+ { 5853, 1461, -1465, -518 },
+ { 6782, 689, -844, -860 },
+ { 7330, 1337, -1152, -71 },
+ { 7189, 1506, -653, -685 },
+ { 6860, 2116, -1403, -240 },
+ { 8804, 1516, -1391, -1760 },
+ { 7210, 2689, -1498, -989 },
+ { 7030, 3022, -1441, -2083 },
+ { 5649, 1836, -407, 525 },
+ { 7451, 3099, -717, -2464 },
+ { 7384, 1656, -2007, 398 },
+ { 6504, 707, -1919, -134 },
+ { -1851, 3639, -2279, -695 },
+ { -4037, 1644, -77, 1329 },
+ { -4025, 1960, -1565, -567 },
+ { -3430, 2495, -795, 368 },
+ { -4771, 2480, 993, 756 },
+ { -3431, 2058, -2539, -971 },
+ { -3802, 3418, 380, 217 },
+ { -3074, 3350, -1652, -1056 },
+ { -3705, 326, -1650, 1535 },
+ { -3122, 1281, -1192, 1607 },
+ { -4601, 1367, -968, 53 },
+ { -3808, 958, 44, 2560 },
+ { -2079, 2530, -1485, 1166 },
+ { -3707, 343, -2889, 180 },
+ { -5249, 1431, -31, 688 },
+ { -4990, 125, -704, 1270 },
+ { -2771, 1334, -2446, 746 },
+ { -2292, 994, -1527, 2630 },
+ { -1261, 3070, -2519, 268 },
+ { -2544, 3890, -1057, -552 },
+ { -4421, 255, -1980, 530 },
+ { -2951, 454, -13, 3643 },
+ { -2262, 1815, -370, 2880 },
+ { -2383, 3657, -649, 576 },
+ { -3541, -161, -1389, 2550 },
+ { -4241, 1575, 1325, 2561 },
+ { -2767, 4037, 1221, 1578 },
+ { -3748, 2697, 1148, 1801 },
+ { -4686, 2385, -220, 0 },
+ { -1531, 1645, -2751, 1327 },
+ { -45, 4032, -799, 2298 },
+ { -2915, 2280, 709, 2495 },
+ { -1199, 3278, -406, 2346 },
+ { -2471, 116, -2706, 2060 },
+ { -2440, 2173, -2894, -344 },
+ { -3375, 2287, 1781, 3226 },
+ { -2153, 3568, 1827, 2918 },
+ { -862, 2267, -1626, 2527 },
+ { -2698, 1135, 301, 4239 },
+ { -2364, 2123, 1010, 3710 },
+ { -2447, 3281, -81, 1408 },
+ { -2660, 4735, 472, 258 },
+ { -1053, 3097, 2682, 2398 },
+ { -3366, -1037, -1152, -868 },
+ { -643, 4242, 2212, 1259 },
+ { 971, 3991, 934, 643 },
+ { -1617, 2002, 2139, 2195 },
+ { -4897, 972, 784, 1719 },
+ { -1275, 2992, 1039, 3821 },
+ { -392, 4973, -209, 1821 },
+ { -1028, 4718, -1479, -137 },
+ { 50, 3914, 553, 2210 },
+ { 678, 4364, 359, 1303 },
+ { -582, 4911, 514, 1671 },
+ { 1276, 3914, -1252, 2934 },
+ { -1496, 3984, 857, 2330 },
+ { 772, 4744, -655, 2332 },
+ { -799, 5283, -439, 624 },
+ { 1341, 2937, 650, 2027 },
+ { -1739, 4892, 1275, 1702 },
+ { -892, 2596, -151, 3951 },
+ { -3532, 1090, 1292, 32 },
+ { 321, 3146, 2647, 1475 },
+ { 264, 4199, -1591, 1317 },
+ { -452, -2357, 2266, 4192 },
+ { 3022, -1033, -2389, 5678 },
+ { -1162, -1342, 3543, 4990 },
+ { -474, -1477, -1223, 5016 },
+ { -699, -2857, 900, 3835 },
+ { -461, -2255, -117, 4626 },
+ { 1204, -2062, -1211, 4403 },
+ { 2192, -3035, -337, 3966 },
+ { 108, -831, 279, 5643 },
+ { 1457, -620, -2908, 5276 },
+ { -2527, -78, 1085, 5460 },
+ { -1978, -1918, -949, 4733 },
+ { 32, 367, -1904, 5166 },
+ { 1890, -1665, 440, 4752 },
+ { -518, -348, 2816, 4891 },
+ { 3695, -2490, -1374, 4603 },
+ { 246, -1965, 3549, 3969 },
+ { 1100, -3111, 656, 3737 },
+ { -1379, 870, -414, 4575 },
+ { 628, -357, -1227, 6179 },
+ { -1129, -1318, -2457, 4576 },
+ { -425, -98, -73, 6336 },
+ { 367, -887, 2990, 4207 },
+ { 2091, -1251, 2444, 3557 },
+ { -1759, -1610, 2046, 5273 },
+ { 3210, 1414, -20, 2616 },
+ { 3303, -2636, 1005, 4237 },
+ { -327, -3107, -640, 3687 },
+ { -197, 764, 572, 5486 },
+ { 646, -767, 1388, 5464 },
+ { 104, 2742, -228, 3907 },
+ { -236, 1829, -579, 4585 },
+ { -2150, -474, -1525, 4006 },
+ { -23, -2632, -2400, 3892 },
+ { -12, -1739, -2910, 4867 },
+ { -2310, -368, -102, 4583 },
+ { -1991, -2061, 533, 4531 },
+ { 3884, -1446, -153, 4393 },
+ { 1568, 14, -289, 5268 },
+ { -1376, -253, -2797, 3417 },
+ { 3193, -2577, 2475, 3566 },
+ { 3418, 617, 1350, 1857 },
+ { 3792, -24, -272, 3370 },
+ { 153, 1159, 2906, 2877 },
+ { 511, 2162, 1548, 2741 },
+ { 262, 819, -2791, 3734 },
+ { 4232, -2015, 1486, 3477 },
+ { 2943, -1110, -1014, 5480 },
+ { 2842, 369, 703, 3476 },
+ { 3011, 1634, -933, 3553 },
+ { 4412, -1548, -942, 5021 },
+ { -1405, 593, 2372, 5267 },
+ { 2093, 2129, 896, 2365 },
+ { 4845, -1980, 0, 3823 },
+ { -2140, 81, 3278, 5637 },
+ { 1484, 2665, -324, 3653 },
+ { 10, 192, 1620, 5291 },
+ { 2152, 738, -2269, 5000 },
+ { 2102, 2748, -1652, 4707 },
+ { 2855, -2131, -387, 5188 },
+ { 1173, 676, 1338, 3277 },
+ { 2340, -2329, -2064, 4095 },
+ { 861, -2024, 1296, 5055 },
+ { 2189, 3225, -695, 2626 },
+ { 6196, -7079, 1943, -822 },
+ { 4547, -4813, 3261, 1856 },
+ { 4243, -6904, 3443, 448 },
+ { 4581, -7503, 946, 506 },
+ { 6626, -7754, 3427, 470 },
+ { 3407, -9088, 3269, -1496 },
+ { 4079, -6464, 2304, 777 },
+ { 5621, -9336, 2684, -768 },
+ { 5351, -6464, 5238, -214 },
+ { 5961, -8007, 1724, -3091 },
+ { 4213, -8067, 603, -246 },
+ { 7208, -7403, 3168, -1738 },
+ { 6098, -7700, 329, -1379 },
+ { 6525, -6735, 4248, -1072 },
+ { 6073, -6241, 2167, -2378 },
+ { 4609, -9218, 3051, -1033 },
+ { 6813, -7283, 1581, -1897 },
+ { 6126, -6275, 2789, 681 },
+ { 4423, -6538, 1621, -1692 },
+ { 6272, -8298, 3167, -1855 },
+ { 6172, -8558, 4498, -1169 },
+ { 4844, -8588, 1647, -366 },
+ { 6209, -8807, 1581, -369 },
+ { 5389, -8059, 550, -192 },
+ { 6654, -9775, 2504, -1063 },
+ { 7103, -7998, 806, 530 },
+ { 5662, -6736, 1565, -3620 },
+ { 4165, -9564, 4191, -2131 },
+ { 4526, -7181, 576, -2875 },
+ { 4633, -8623, 2807, -4742 },
+ { 3709, -7794, 1815, 34 },
+ { 3634, -8622, 2313, -826 },
+ { 6991, -8447, 2063, -3198 },
+ { 7757, -9486, 2255, -558 },
+ { 4149, -7778, 4728, -1696 },
+ { 5767, -7427, 1113, 707 },
+ { 4592, -6261, 2329, 1864 },
+ { 3159, -10498, 1677, -4273 },
+ { 3534, -9010, 2437, -3565 },
+ { 4479, -10821, 2715, -4942 },
+ { 3207, -9805, 3054, -3886 },
+ { 4627, -8189, 3018, -2354 },
+ { 5527, -10566, 3244, -2749 },
+ { 4346, -10127, 3335, -3084 },
+ { 6132, -10085, 3316, -1308 },
+ { 5629, -9704, 2178, -3058 },
+ { 3603, -8538, 1246, -624 },
+ { 3737, -8488, 395, -3167 },
+ { 5465, -11414, 2810, -4640 },
+ { 5306, -7745, 2721, -3988 },
+ { 7000, -9111, 1695, -1409 },
+ { 6663, -7741, 2466, -4079 },
+ { 4083, -7175, 1836, -4831 },
+ { 3613, -9926, 1342, -3455 },
+ { 6588, -8033, 457, -258 },
+ { 4720, -8102, 17, -1209 },
+ { 7414, -8709, 1294, -344 },
+ { 5437, -10030, 4043, -1704 },
+ { 4862, -9281, 1558, -1431 },
+ { 6800, -6403, 5113, 862 },
+ { 4623, -8242, 2667, -228 },
+ { 5919, -5083, 3348, 2135 },
+ { 5985, -8889, 2733, -5105 },
+ { 5029, -5767, 4407, 719 },
+ { 354, -6158, -838, -3001 },
+ { 351, -5943, -2104, -1534 },
+ { -633, -7190, -25, -4798 },
+ { -1595, -7235, -3812, -1400 },
+ { 103, -6197, -2933, -78 },
+ { -1722, -5020, -3441, -4333 },
+ { -1963, -5644, -4365, -270 },
+ { -846, -5743, -3477, 196 },
+ { -191, -5348, -4054, -469 },
+ { -2515, -7754, -3495, -818 },
+ { -2090, -6710, -2701, 117 },
+ { -546, -7036, -1398, 163 },
+ { -278, -7091, -2662, -536 },
+ { -622, -7962, -2731, -1464 },
+ { -1555, -8118, -3612, -2057 },
+ { -1094, -6280, -2314, 505 },
+ { -2556, -8538, -4024, -2247 },
+ { 109, -7134, -3107, -1823 },
+ { -900, -6954, -3340, -717 },
+ { -605, -7113, -3656, -2154 },
+ { 837, -6263, -3211, -2177 },
+ { -417, -5810, -3871, -1469 },
+ { -1318, -5649, -4207, -3198 },
+ { 413, -6765, -2082, -33 },
+ { -3101, -6450, -4362, -766 },
+ { 755, -6489, -2967, -846 },
+ { 1117, -7106, -2452, -1352 },
+ { -1202, -8387, -3072, -2897 },
+ { -365, -4894, -3561, -2937 },
+ { -2372, -8776, -265, -4441 },
+ { -1224, -8678, -896, -5074 },
+ { -755, -10096, -600, -6623 },
+ { 300, -8206, -225, -4568 },
+ { -1176, -6824, -2633, -3527 },
+ { -2006, -5443, -1526, -5849 },
+ { -1115, -5540, -2363, -4785 },
+ { 1059, -6812, -2543, -2654 },
+ { -1976, -6861, -3062, -5508 },
+ { -379, -5328, -2321, -3624 },
+ { -2108, -5860, -4518, -1915 },
+ { -379, -7885, -1329, -594 },
+ { 774, -5389, -581, -5213 },
+ { -2601, -5083, -1849, -4921 },
+ { -176, -5580, 74, -5075 },
+ { -204, -6780, -190, -6232 },
+ { 418, -7594, -1987, -820 },
+ { -1873, -8529, -2926, -1609 },
+ { 1340, -6362, -919, -4975 },
+ { 577, -7990, -2044, -1873 },
+ { -2572, -7413, -1745, -2224 },
+ { -2037, -7030, -1461, -7138 },
+ { -2559, -8756, -2039, -5836 },
+ { -2079, -6764, -1209, -5669 },
+ { -1613, -7801, -2006, -685 },
+ { -1865, -6583, -722, -3529 },
+ { -589, -6358, -1377, -1003 },
+ { -540, -7514, -1331, -3542 },
+ { 419, -6192, -1677, -4927 },
+ { -2786, -8763, -2966, -5065 },
+ { -2172, -8411, -1726, -4675 },
+ { -3382, -9833, -3497, -5722 },
+ { -2433, -10169, -2077, -5775 },
+ { -424, -9451, -1096, -3658 },
+ { -537, -8522, -910, -1897 },
+ { -5550, 2807, 1683, -693 },
+ { -6395, 635, 3573, -1246 },
+ { -7544, 2280, 2140, 44 },
+ { -8751, 1136, 2951, -794 },
+ { -5605, 2709, 2052, 916 },
+ { -7650, 654, 869, 135 },
+ { -6939, 967, 1409, 870 },
+ { -7834, 2123, 3310, 974 },
+ { -6935, 2818, 1274, -1678 },
+ { -5605, 2233, 1013, 471 },
+ { -7095, 1849, 1648, 198 },
+ { -6636, 1634, 712, -37 },
+ { -7279, 978, 296, -315 },
+ { -7664, 3504, 3292, -216 },
+ { -7836, 1209, 1221, -257 },
+ { -7913, 2201, 1765, -1529 },
+ { -7077, 3783, 2632, -1407 },
+ { -5565, 1645, 1410, -622 },
+ { -6494, 2879, 1181, -759 },
+ { -7073, 3137, 3010, 550 },
+ { -7249, 1839, 847, -805 },
+ { -6630, 2197, 282, -1096 },
+ { -8836, 1573, 1988, -1090 },
+ { -7809, 1274, 836, -1198 },
+ { -7895, 2970, 3511, -1097 },
+ { -6960, 1664, 1356, -2442 },
+ { -6582, 2866, 2273, 307 },
+ { -7221, 821, 2851, -1435 },
+ { -6015, 1703, 2001, -2367 },
+ { -8082, 1034, 2103, 239 },
+ { -5952, 1912, 301, -465 },
+ { -6099, 841, 379, 567 },
+ { -6343, 50, 494, 658 },
+ { -6586, 983, 591, -893 },
+ { -5500, 869, 2187, -2479 },
+ { -6482, 60, 1545, -979 },
+ { -6705, 515, 1974, -53 },
+ { -6460, 1755, 1325, -1275 },
+ { -6093, 2617, 2465, -623 },
+ { -7330, 2161, 594, -2115 },
+ { -7324, 762, 1593, -2004 },
+ { -6385, 679, 1510, -2514 },
+ { -6159, 241, 2976, -1631 },
+ { -8583, 3030, 4045, -162 },
+ { -6299, 66, 2209, -2103 },
+ { -5428, 1279, 3267, -1846 },
+ { -6438, 1335, 2728, -1631 },
+ { -8012, 1070, 2428, -1151 },
+ { -6201, 2781, 2349, -1918 },
+ { -5918, 1139, 3121, -148 },
+ { -6314, 2481, 3137, -1808 },
+ { -7180, 1722, 2435, -1602 },
+ { -6750, 1829, 3763, -1145 },
+ { -6713, 1777, 2221, 1212 },
+ { -7479, 1835, 3627, -479 },
+ { -7299, 10, 2406, -1593 },
+ { -8249, 3129, 996, -2870 },
+ { -8374, 1534, 1333, -1882 },
+ { -7507, 3353, 1598, -2299 },
+ { -7379, 2701, 2326, -1167 },
+ { -8440, 2276, 2796, -542 },
+ { -10348, 1527, 2649, -1165 },
+ { -8184, 3614, 2574, -1738 },
+ { -5539, 1574, 1733, 1138 },
+ { 9404, -7652, 67, 79 },
+ { 8654, -3972, 1358, -60 },
+ { 8617, -4794, 117, 2318 },
+ { 7886, -4505, 1784, 1200 },
+ { 8636, -6125, 3879, -1003 },
+ { 9654, -6836, 1816, 205 },
+ { 9374, -6553, 913, 1875 },
+ { 8020, -6150, 1134, 2390 },
+ { 7786, -4970, 2078, -1857 },
+ { 8691, -6119, 711, 708 },
+ { 9039, -5568, 2944, -1902 },
+ { 9955, -5048, 1433, -601 },
+ { 8089, -6927, 3093, -2846 },
+ { 8487, -7024, 2415, 19 },
+ { 9388, -5287, 3577, -2655 },
+ { 8591, -7371, 2300, -996 },
+ { 9104, -4763, 1453, -2558 },
+ { 7615, -5457, 596, 164 },
+ { 9860, -7047, 3433, -614 },
+ { 8756, -4404, 2235, -964 },
+ { 9462, -4660, 299, -1822 },
+ { 10119, -5550, 2689, -1273 },
+ { 10915, -7471, 2705, -1007 },
+ { 11433, -7090, 1410, -1198 },
+ { 9882, -7431, 2965, -1895 },
+ { 7628, -5219, 769, -2661 },
+ { 8169, -5318, 2262, 70 },
+ { 8846, -6320, 1939, -754 },
+ { 7147, -5593, 1248, -971 },
+ { 10652, -5485, 935, 137 },
+ { 7778, -6533, 2564, -1932 },
+ { 8878, -5173, 1214, -361 },
+ { 9828, -4943, 282, 510 },
+ { 10042, -6134, 3895, -1914 },
+ { 7965, -6630, 3566, -433 },
+ { 8573, -4502, 3574, -1209 },
+ { 8398, -4801, 1031, -1347 },
+ { 10136, -7772, 2612, 1547 },
+ { 9890, -7280, 1768, -1083 },
+ { 8407, -6585, -706, -58 },
+ { 7976, -7582, 229, -131 },
+ { 10481, -8866, 1166, -147 },
+ { 10914, -4342, 3189, -2412 },
+ { 10440, -5198, -104, -1109 },
+ { 11227, -6530, 2381, -2449 },
+ { 8487, -8064, 1086, 230 },
+ { 9975, -6123, -857, -134 },
+ { 8339, -6498, 1232, -2337 },
+ { 11042, -4506, 1119, -2098 },
+ { 12563, -5592, 1837, -2062 },
+ { 11801, -5590, 632, -1296 },
+ { 10152, -5617, 1511, -1917 },
+ { 7800, -6473, 51, -1337 },
+ { 7941, -5560, 2438, -3270 },
+ { 6554, -3834, 2100, 1476 },
+ { 9065, -5520, -226, -1120 },
+ { 10794, -7120, -243, 122 },
+ { 10429, -6968, 272, -806 },
+ { 8942, -8914, 1442, -392 },
+ { 9969, -5051, 2033, -2953 },
+ { 7275, -4152, 3058, -64 },
+ { 11127, -5488, 4589, -3227 },
+ { 9626, -6666, 2739, -2958 },
+ { 6943, -5362, 4470, 1008 },
+ { -7456, -967, 2936, -1002 },
+ { -8622, -333, 6962, 2606 },
+ { -7486, -3392, 3668, 1287 },
+ { -8053, -827, 5148, 1097 },
+ { -6610, 454, 4952, 96 },
+ { -7701, -1982, 3161, -468 },
+ { -7307, -1132, 4071, -36 },
+ { -8125, -271, 5199, 3862 },
+ { -9182, -1950, 2813, 1878 },
+ { -9855, -952, 4794, 3010 },
+ { -7241, 1431, 4202, 2468 },
+ { -9646, 157, 4766, 1046 },
+ { -9371, 1230, 6009, 2958 },
+ { -11514, -64, 8630, 5248 },
+ { -6766, 565, 2766, 2140 },
+ { -8426, -9, 2852, 1271 },
+ { -11291, -1113, 5087, 2937 },
+ { -8297, 2092, 4495, 1264 },
+ { -9983, 735, 3809, -51 },
+ { -9048, -1000, 3191, -308 },
+ { -7331, -1987, 2655, 1391 },
+ { -7144, -21, 4333, 2161 },
+ { -6032, -1540, 3543, 896 },
+ { -7987, -1036, 1985, 1529 },
+ { -9264, 2004, 5194, 290 },
+ { -11308, -840, 5754, 1654 },
+ { -9130, -2398, 4292, 2973 },
+ { -6248, 838, 3563, 1223 },
+ { -6819, -2760, 3511, 119 },
+ { -7213, -2006, 4364, 762 },
+ { -5431, -1047, 4533, 166 },
+ { -7098, -641, 2021, 639 },
+ { -8628, -2249, 3588, 399 },
+ { -6352, -1498, 3560, -648 },
+ { -7033, -2190, 4870, 2562 },
+ { -7405, -46, 3772, -581 },
+ { -6104, 796, 5143, 1965 },
+ { -5787, 943, 5784, 3030 },
+ { -8367, 1465, 7192, 4097 },
+ { -8259, 789, 5694, 1963 },
+ { -10614, -1899, 5748, 2645 },
+ { -8258, -805, 3698, 2275 },
+ { -6877, -972, 6431, 3160 },
+ { -6483, 363, 7018, 3129 },
+ { -6283, -1358, 5191, 1524 },
+ { -8853, -3157, 4119, 1741 },
+ { -6086, -267, 3883, -835 },
+ { -7254, 1032, 6613, 4017 },
+ { -11470, -3350, 4649, 3426 },
+ { -6743, 481, 6148, 1239 },
+ { -5394, -166, 5309, 3165 },
+ { -7958, 1068, 4268, -240 },
+ { -10520, 2256, 7916, 2828 },
+ { -5132, -4, 5739, 1176 },
+ { -8643, 120, 3255, -629 },
+ { -9631, 1974, 8870, 4362 },
+ { -10663, -1221, 3733, 589 },
+ { -8224, -1843, 5806, 2655 },
+ { -8282, 1255, 8647, 3478 },
+ { -12311, -1505, 9043, 6256 },
+ { -11312, -856, 7136, 4681 },
+ { -11944, -722, 7941, 3309 },
+ { -7868, -463, 6846, 4196 },
+ { -8679, -241, 7410, 5347 },
+ { 6759, -4680, -508, 1220 },
+ { 5176, -6111, 944, 121 },
+ { 6843, -5667, -1368, -533 },
+ { 5616, -5884, -1471, -695 },
+ { 6030, -5089, -1808, -940 },
+ { 7444, -5463, -52, 1881 },
+ { 4207, -6079, -506, 1571 },
+ { 6785, -4410, -649, 3084 },
+ { 4838, -5214, 2026, 2998 },
+ { 4201, -5790, 645, 1811 },
+ { 6930, -5129, -1940, 1698 },
+ { 6332, -4627, 692, 3027 },
+ { 6285, -4314, -106, 3644 },
+ { 6255, -5450, -1975, 742 },
+ { 4199, -4676, -459, 1796 },
+ { 5592, -5500, 1345, 1300 },
+ { 4358, -5556, -2236, 114 },
+ { 4620, -5875, -1563, 888 },
+ { 4892, -7550, -327, -419 },
+ { 4734, -7085, 7, 613 },
+ { 3883, -5562, -1969, 1080 },
+ { 5610, -4990, -204, 834 },
+ { 4117, -6482, -1271, 341 },
+ { 6585, -5107, 892, 1169 },
+ { 6632, -3683, 302, 3002 },
+ { 6326, -5351, -983, -1250 },
+ { 4382, -7192, -730, -158 },
+ { 5227, -6540, -451, 1123 },
+ { 5468, -6472, -870, -1471 },
+ { 5191, -6402, -1365, -127 },
+ { 7407, -6317, -973, -336 },
+ { 4611, -6530, -820, -1980 },
+ { 4963, -5159, -2050, -966 },
+ { 4414, -5691, -211, -998 },
+ { 5954, -5873, 750, -1749 },
+ { 4394, -4796, -1268, 254 },
+ { 7161, -6214, -1010, 689 },
+ { 4965, -3598, 2372, 1711 },
+ { 6248, -6180, 981, 864 },
+ { 6473, -5336, 525, -600 },
+ { 4591, -6864, -1131, -900 },
+ { 6314, -6440, -1021, -375 },
+ { 5838, -6209, -1199, 944 },
+ { 5308, -5283, -2100, 1267 },
+ { 4342, -5860, -1637, -1356 },
+ { 5680, -4388, -1227, -104 },
+ { 4900, -4098, 1449, 4046 },
+ { 4677, -4284, -106, 3190 },
+ { 7574, -6173, -848, 1859 },
+ { 6493, -7207, -131, 726 },
+ { 5513, -5261, -2117, 4 },
+ { 6191, -7352, -193, -505 },
+ { 5885, -4333, 324, -134 },
+ { 6162, -6081, -312, -2044 },
+ { 4216, -6200, -1810, -572 },
+ { 5652, -7035, -696, -197 },
+ { 7131, -7189, -366, -60 },
+ { 5032, -4803, -1514, 2832 },
+ { 7386, -4610, -606, 3489 },
+ { 4211, -5031, 1221, 3047 },
+ { 4050, -4653, 1584, 1469 },
+ { 6852, -5302, -1861, 206 },
+ { 7736, -4816, -1794, 3359 },
+ { 6290, -3439, 1522, 2454 },
+ { 1768, 5990, -5560, -2594 },
+ { 3903, 5326, -1530, -1501 },
+ { 2472, 3738, -2117, -4240 },
+ { 3260, 5448, -904, -4733 },
+ { 1435, 7297, -3676, -4102 },
+ { 4096, 5951, -656, -3312 },
+ { 2178, 6009, -3146, -3724 },
+ { 3787, 5493, -5473, -1633 },
+ { 2998, 7286, -3334, -3571 },
+ { 2894, 6576, -4708, -2804 },
+ { 830, 6163, -4286, -3348 },
+ { 4755, 5569, -1730, -2739 },
+ { 4604, 6065, -3562, -2605 },
+ { 2749, 5141, -3986, -2775 },
+ { 3942, 4875, -2143, -3340 },
+ { 2819, 8517, -2004, -2724 },
+ { 2146, 6298, -689, -3093 },
+ { 5196, 6504, -3393, -1475 },
+ { 1851, 8386, -1748, -1420 },
+ { 3474, 8572, -3534, -2688 },
+ { 4503, 7560, -3561, -2245 },
+ { 4433, 6219, -2393, -1575 },
+ { 3506, 7248, -2275, -1977 },
+ { 3490, 7409, -3147, -604 },
+ { 4214, 6447, -3520, 516 },
+ { 619, 7034, -829, -1705 },
+ { 1732, 7395, -356, -2208 },
+ { 1226, 5204, -3294, -3732 },
+ { 2027, 5619, -1813, -4146 },
+ { 3078, 5877, 47, -2651 },
+ { 1654, 5458, 424, -682 },
+ { 3163, 5464, -2026, -270 },
+ { 2884, 5375, -685, -530 },
+ { 2950, 7286, -35, -2967 },
+ { 1986, 5066, -597, 482 },
+ { 3459, 4308, -3845, -2333 },
+ { 3155, 7037, -1346, -4345 },
+ { 2193, 6696, -717, -1319 },
+ { 3677, 5089, -3892, -487 },
+ { 2186, 5136, -4186, -1492 },
+ { 773, 5796, -917, 817 },
+ { 2489, 6546, -3570, -2117 },
+ { 1223, 6469, -1362, -33 },
+ { 271, 6061, -1466, -1725 },
+ { 2540, 5171, -1847, 1032 },
+ { 2548, 5251, -2697, 1677 },
+ { 771, 7600, -768, -632 },
+ { 4710, 6647, -4736, -1275 },
+ { 1369, 5917, -2971, -1056 },
+ { 163, 5239, -3499, -2275 },
+ { 2104, 4285, -3211, -3286 },
+ { 1107, 7411, -1972, -1671 },
+ { 2196, 7262, -2310, -1926 },
+ { -244, 6439, -1745, -839 },
+ { 3293, 3832, -2890, -3000 },
+ { 419, 6443, -379, -407 },
+ { 3077, 4930, -1156, -2869 },
+ { 2131, 5874, -2330, 224 },
+ { 690, 6538, -2212, -2841 },
+ { 1602, 4421, -2515, 1542 },
+ { 3318, 9373, -3032, -3477 },
+ { 5646, 7462, -5153, -1463 },
+ { 4139, 7137, -1539, -3321 },
+ { 3481, 9077, -1645, -3653 },
+ { -7747, 375, -106, -543 },
+ { -8587, -1379, -586, -461 },
+ { -10146, -892, 2094, 694 },
+ { -8103, 382, 504, -325 },
+ { -8548, -92, 94, -656 },
+ { -7460, 38, 152, 388 },
+ { -8266, -271, -459, -883 },
+ { -7935, -664, -1026, -802 },
+ { -8341, -109, 853, 161 },
+ { -8802, -1355, 1099, 630 },
+ { -8957, -6, 1108, -669 },
+ { -7260, -1520, -43, -407 },
+ { -7555, -174, 668, -2562 },
+ { -9014, -126, 227, -1191 },
+ { -8184, 769, 290, -1375 },
+ { -9476, 55, 962, -1528 },
+ { -8679, 541, 755, -1030 },
+ { -9842, -1626, 838, -1588 },
+ { -8513, -702, 788, -1998 },
+ { -10101, -1558, -366, -1841 },
+ { -8135, 78, 1479, -1813 },
+ { -9128, -454, 313, -1786 },
+ { -7554, -1084, 831, -2442 },
+ { -7576, -701, 2068, -1665 },
+ { -7791, -1481, 1587, -1808 },
+ { -6701, -596, -97, 802 },
+ { -7418, -15, 684, -963 },
+ { -7127, -477, -139, -426 },
+ { -8097, -110, -36, -264 },
+ { -7620, -1922, -590, -101 },
+ { -7647, -1201, 279, 660 },
+ { -7856, -1974, 758, -2271 },
+ { -8496, -167, 2232, -1143 },
+ { -8506, -1359, 624, -740 },
+ { -7274, -1052, 1062, -139 },
+ { -7800, -217, 91, -1794 },
+ { -7030, -1694, -955, 615 },
+ { -9020, -1864, 101, -2182 },
+ { -9400, -740, 598, -667 },
+ { -8448, -1184, 2024, -1272 },
+ { -8812, -570, -897, -2384 },
+ { -10559, -1286, 538, -1536 },
+ { -8728, -888, -1089, -1397 },
+ { -7080, -1185, 636, -1252 },
+ { -9880, 233, 2344, -782 },
+ { -7952, -1326, -378, -1947 },
+ { -7207, -378, 1408, -2237 },
+ { -8467, -1545, 902, -1987 },
+ { -9163, -1474, 924, -1739 },
+ { -8159, -992, -77, -2744 },
+ { -8343, 148, -423, -1573 },
+ { -9105, -649, -254, -1214 },
+ { -8939, 456, 281, -1905 },
+ { -8837, 179, -394, -2634 },
+ { -9145, 757, 1547, -1319 },
+ { -9775, -723, 441, -1680 },
+ { -8910, -686, 1529, -1525 },
+ { -9492, -1134, 2064, -938 },
+ { -6111, -943, 677, -31 },
+ { -7411, -613, -814, 46 },
+ { -9479, -922, -430, -2061 },
+ { -11298, -1268, 1318, -1117 },
+ { -8190, 832, 671, -2214 },
+ { -10453, -550, 1672, -886 },
+ { 1044, 9353, -1651, -5423 },
+ { 1034, 8149, -455, -6166 },
+ { 761, 8293, -3214, -4838 },
+ { 938, 8077, 164, -5130 },
+ { 1295, 8673, 2582, -5490 },
+ { -314, 7973, -2395, -5231 },
+ { -507, 9012, -2497, -5775 },
+ { 2396, 8314, -1022, -4673 },
+ { -1516, 8501, 1950, -4969 },
+ { -308, 7401, 1549, -4866 },
+ { -112, 8340, 3003, -4920 },
+ { -50, 9315, 1371, -5666 },
+ { -659, 9449, 2496, -5547 },
+ { 2573, 9148, -2270, -4783 },
+ { 830, 7104, -438, -3907 },
+ { 522, 10672, -677, -6483 },
+ { -1190, 10108, -510, -6518 },
+ { -427, 8271, -579, -6315 },
+ { 1602, 8113, -1927, -4418 },
+ { -2266, 8180, 448, -5190 },
+ { -1633, 8816, -226, -5771 },
+ { 759, 9481, -105, -5813 },
+ { 2254, 6679, -466, -5662 },
+ { -88, 6946, 895, -5958 },
+ { -1705, 10009, 1394, -5574 },
+ { 748, 7943, 540, -6692 },
+ { 1411, 7009, 232, -6145 },
+ { 697, 7290, -1221, -5342 },
+ { -1764, 10580, 1944, -3981 },
+ { -1334, 9124, 1195, -3903 },
+ { -905, 10067, 635, -5039 },
+ { 664, 10680, 49, -4625 },
+ { 1374, 9536, -777, -3591 },
+ { 252, 9698, -597, -2931 },
+ { 824, 9164, -1014, -2144 },
+ { 2438, 10569, -2289, -4424 },
+ { 2101, 7102, 507, -3614 },
+ { 294, 8051, -432, -1518 },
+ { -665, 10337, 547, -2852 },
+ { 1168, 11989, -492, -5427 },
+ { 1344, 6416, 302, -5061 },
+ { -1727, 12264, 1507, -4543 },
+ { 674, 10889, -902, -3605 },
+ { -582, 9504, 300, -3618 },
+ { 641, 7654, 689, -2109 },
+ { 2065, 9243, 508, -4367 },
+ { 1055, 8373, 688, -3144 },
+ { -641, 8185, 986, -3307 },
+ { 1120, 7426, 1785, -3757 },
+ { 1660, 8070, -593, -3104 },
+ { 2002, 9467, -1722, -3475 },
+ { 2361, 8368, 100, -3709 },
+ { -772, 7845, -613, -4988 },
+ { 1485, 7430, 1896, -6127 },
+ { -432, 7823, -947, -2882 },
+ { 313, 11122, -760, -4871 },
+ { 412, 8412, -283, -4231 },
+ { 1585, 10402, -1884, -3267 },
+ { 321, 6952, 773, -3016 },
+ { -105, 9014, 121, -2249 },
+ { 1585, 10313, -977, -4812 },
+ { 1619, 11869, 1306, -6876 },
+ { -1168, 8886, -81, -2500 },
+ { -395, 10886, 733, -6490 },
+ { -4949, 4274, 3992, -1054 },
+ { -4241, 5299, 4262, -1584 },
+ { -2710, 3862, 4552, -1673 },
+ { -4608, 2472, 3672, -1715 },
+ { -2843, 2816, 4003, -2326 },
+ { -5229, 2964, 5636, 90 },
+ { -4924, 3442, 5015, -1096 },
+ { -1281, 3313, 5537, -2066 },
+ { -3808, 1939, 4351, -919 },
+ { -1915, 2585, 4939, -1614 },
+ { -3470, 1843, 5562, -682 },
+ { -3800, 870, 5827, 144 },
+ { -4985, 1452, 4728, -709 },
+ { -3745, 2750, 7220, 259 },
+ { -1875, 1900, 6514, -826 },
+ { -4329, 1574, 7192, 1304 },
+ { -5408, 1444, 6208, 631 },
+ { -3327, 5312, 5707, -1541 },
+ { -6966, 3334, 4034, 1028 },
+ { -7484, 4245, 4218, -212 },
+ { -6567, 5839, 4539, -512 },
+ { -5715, 5935, 3747, -1186 },
+ { -6410, 4881, 3356, -1610 },
+ { -5146, 2590, 2850, 2172 },
+ { -5196, 4095, 2569, -373 },
+ { -5043, 6025, 4318, 692 },
+ { -5525, 4884, 3513, 370 },
+ { -6804, 7533, 5812, -488 },
+ { -5657, 2480, 4061, 1234 },
+ { -3155, 1472, 6071, 1188 },
+ { -3427, 5217, 3442, 858 },
+ { -4698, 3013, 5517, 2586 },
+ { -4449, 2226, 5418, 3580 },
+ { -6395, 3547, 5487, 2028 },
+ { -3500, 5019, 4787, 1 },
+ { -4038, 2578, 3073, 3151 },
+ { -2750, 1955, 4469, 3856 },
+ { -5696, 1659, 6118, 2469 },
+ { -4350, 1241, 6840, 3126 },
+ { -5565, 5058, 5196, 1314 },
+ { -1642, 4190, 3948, 607 },
+ { -1233, 4108, 4850, -640 },
+ { -997, 3428, 3239, 1378 },
+ { -6488, 2741, 6926, 2792 },
+ { -4188, 3763, 4235, 2018 },
+ { -3210, 3224, 5646, 1427 },
+ { -5526, 6909, 5070, -627 },
+ { -2815, 3994, 3425, 1903 },
+ { -2163, 2734, 5423, 145 },
+ { -4149, 4247, 2355, 734 },
+ { -410, 2521, 4138, -16 },
+ { -2411, 2385, 4927, 2105 },
+ { -6077, 3591, 3114, 594 },
+ { -4186, 4834, 5926, -1004 },
+ { -7315, 3369, 5966, 448 },
+ { -7042, 5721, 5771, 238 },
+ { -4466, 3907, 3535, -1751 },
+ { -2116, 3970, 6163, -1392 },
+ { -7239, 2143, 8407, 3630 },
+ { -5431, 4486, 6486, -42 },
+ { -1874, 1617, 6333, 519 },
+ { -6478, 2629, 4634, -505 },
+ { -7784, 2342, 7216, 1365 },
+ { -1154, 1432, 4831, 1544 },
+ { -4964, -5801, 1797, 506 },
+ { -4436, -6905, 1059, -1237 },
+ { -5400, -6886, 884, -290 },
+ { -6259, -7103, 523, -227 },
+ { -4819, -6450, 1412, -450 },
+ { -4056, -6213, 1725, -943 },
+ { -5642, -6091, 1357, 605 },
+ { -4196, -5678, 2187, -173 },
+ { -4726, -5126, 2470, 321 },
+ { -6642, -5091, 1507, -1005 },
+ { -5304, -5250, 1944, 1579 },
+ { -7179, -5520, 1468, -425 },
+ { -6033, -4895, 1876, -955 },
+ { -6595, -5143, 2207, 1291 },
+ { -4224, -4943, 1846, 1792 },
+ { -7128, -6950, 539, 724 },
+ { -4369, -4901, 2590, 1103 },
+ { -7413, -5696, 1712, 1440 },
+ { -5885, -6821, 418, 871 },
+ { -6828, -5599, 710, -1563 },
+ { -6123, -5817, 1358, 1631 },
+ { -5291, -5622, 578, 2138 },
+ { -7171, -6004, 347, 2208 },
+ { -6083, -5251, 2132, 425 },
+ { -4329, -5721, 407, -2993 },
+ { -5326, -5056, 1119, -1837 },
+ { -5485, -5856, 185, -2389 },
+ { -6529, -5178, 403, -697 },
+ { -6719, -4412, 2726, 871 },
+ { -5126, -5629, 1835, -771 },
+ { -5622, -4361, 2973, 858 },
+ { -5282, -5895, 45, -335 },
+ { -4357, -5656, 1696, -1558 },
+ { -7139, -6659, 627, -409 },
+ { -4415, -6328, 35, 1306 },
+ { -7639, -6110, 1134, 197 },
+ { -3626, -5592, 2019, 901 },
+ { -3547, -5064, 1176, 1738 },
+ { -5075, -3899, 2087, 266 },
+ { -4086, -6311, 1479, 360 },
+ { -6210, -5220, -199, -1477 },
+ { -3910, -5063, 1356, -15 },
+ { -7616, -4977, 461, 2401 },
+ { -6118, -6131, 1258, -563 },
+ { -6127, -4968, 1286, -27 },
+ { -4121, -5852, 1113, 1476 },
+ { -5157, -4881, 1162, -662 },
+ { -4637, -5031, 1179, 709 },
+ { -5509, -5452, -397, 1224 },
+ { -4597, -6861, 646, 467 },
+ { -6247, -4043, 468, 278 },
+ { -5336, -6465, 874, -1472 },
+ { -6998, -6346, 78, -1798 },
+ { -4915, -4530, 2756, -203 },
+ { -6048, -4373, 1468, 1052 },
+ { -4273, -7100, 942, -323 },
+ { -6552, -4287, 2351, 69 },
+ { -6954, -4613, 722, 1521 },
+ { -4201, -5361, 763, -1562 },
+ { -6881, -5596, -748, 669 },
+ { -6695, -3547, -34, 1299 },
+ { -3981, -5728, 84, 111 },
+ { -4663, -4809, 2173, -1031 },
+ { -6599, -6077, 1303, 256 },
+ { -7596, -4265, -5791, -4140 },
+ { -6610, -2758, -5288, -3936 },
+ { -5880, -3865, -6563, -3088 },
+ { -7228, -5510, -7677, -3912 },
+ { -8854, -6553, -8318, -5361 },
+ { -9362, -5249, -6413, -4319 },
+ { -4418, -3110, -6368, -4358 },
+ { -5544, -4203, -6863, -5013 },
+ { -3056, -4316, -5567, -3181 },
+ { -3078, -5999, -5051, -2657 },
+ { -5884, -6292, -5756, -4013 },
+ { -4825, -4549, -5535, -4053 },
+ { -4443, -6126, -5316, -1368 },
+ { -3972, -6341, -6098, -2686 },
+ { -5751, -2781, -5398, -6230 },
+ { -4466, -6135, -5570, -3679 },
+ { -4291, -5992, -3564, -5189 },
+ { -7189, -4429, -7279, -6082 },
+ { -5076, -4433, -2748, -5366 },
+ { -6225, -2825, -6833, -5663 },
+ { -2989, -4792, -3960, -4492 },
+ { -7836, -7773, -7722, -5741 },
+ { -6559, -5703, -5844, -5589 },
+ { -7612, -5438, -4136, -3774 },
+ { -4218, -4176, -6591, -2333 },
+ { -4837, -5063, -6581, 322 },
+ { -6590, -5990, -2980, -3847 },
+ { -5558, -2971, -5489, -1932 },
+ { -7001, -5323, -4975, -1697 },
+ { -4694, -2688, -6904, -3044 },
+ { -8511, -5379, -5767, -2549 },
+ { -7548, -5412, -6522, -2572 },
+ { -6597, -4973, -6423, -1274 },
+ { -6415, -4022, -5168, -1072 },
+ { -5528, -5530, -7218, -2345 },
+ { -4845, -4805, -5943, -1227 },
+ { -6049, -7150, -6744, -2161 },
+ { -9061, -7299, -8542, -4375 },
+ { -5010, -5546, -5416, -82 },
+ { -4135, -4205, -5109, -3373 },
+ { -3311, -5869, -4007, -5061 },
+ { -5993, -6472, -3962, -4718 },
+ { -2966, -5832, -2821, -6305 },
+ { -4851, -5152, -2067, -3930 },
+ { -3620, -4441, -3362, -5836 },
+ { -4469, -5221, -4534, -5592 },
+ { -4022, -6335, -4321, -6107 },
+ { -4899, -4503, -3084, -3725 },
+ { -4490, -8276, -4620, -6236 },
+ { -6591, -4342, -7365, -4063 },
+ { -6498, -5057, -5553, 485 },
+ { -6060, -2714, -7093, -4144 },
+ { -6199, -7774, -7094, -4057 },
+ { -7536, -6424, -6415, -4265 },
+ { -7439, -2454, -6348, -4827 },
+ { -5333, -7565, -4417, -4639 },
+ { -4353, -7103, -4197, -2689 },
+ { -5229, -6549, -5129, -6804 },
+ { -6129, -7701, -5236, -4836 },
+ { -6797, -3983, -3884, -4406 },
+ { -6624, -4467, -4745, -5052 },
+ { -3324, -7596, -2720, -6553 },
+ { -5473, -6284, -1704, -4511 },
+ { -4131, -7263, -3180, -5196 },
+ { -7116, -5565, -3469, 685 },
+ { -6002, -6021, -3858, 576 },
+ { -3144, -8203, -1291, -434 },
+ { -6096, -7027, -4004, 1353 },
+ { -3943, -7709, -2344, -36 },
+ { -4510, -6767, -2642, 631 },
+ { -3657, -11541, -2570, -3984 },
+ { -5959, -8854, -1333, -867 },
+ { -6699, -8866, -1606, -344 },
+ { -3836, -7961, -2334, -2028 },
+ { -3430, -8045, -3037, -672 },
+ { -3868, -9184, -3635, -1819 },
+ { -4258, -9060, -2621, -1008 },
+ { -3595, -8693, -2022, -752 },
+ { -4573, -8048, -3166, -2622 },
+ { -4852, -7903, -1405, 256 },
+ { -4591, -7057, -1560, 965 },
+ { -6963, -7655, -980, 808 },
+ { -5179, -6641, -3356, 1196 },
+ { -7102, -6941, -2798, 2123 },
+ { -6867, -5834, -3320, -770 },
+ { -5977, -7369, -2500, -778 },
+ { -6160, -6400, -934, -2543 },
+ { -6741, -7608, -355, -1289 },
+ { -6856, -6466, -1433, -1643 },
+ { -4786, -6292, -4970, 376 },
+ { -5407, -8866, -2255, -400 },
+ { -3814, -6506, -1387, -3620 },
+ { -4998, -6137, -1200, -4092 },
+ { -5123, -9557, -2849, -1306 },
+ { -4259, -6444, -4395, -338 },
+ { -5221, -6810, -883, 1225 },
+ { -6137, -6215, -2165, 554 },
+ { -3895, -6557, -3176, -1829 },
+ { -3886, -8188, -87, -954 },
+ { -7243, -6707, -2216, -316 },
+ { -5592, -7606, 85, -432 },
+ { -3957, -7945, -504, -144 },
+ { -4617, -7624, 218, -312 },
+ { -4797, -8737, -844, -1051 },
+ { -4478, -8516, -1401, -454 },
+ { -4557, -7058, -302, -2332 },
+ { -6623, -7736, -271, -50 },
+ { -3157, -7532, -1111, -2207 },
+ { -3590, -7300, -1271, 517 },
+ { -4442, -7306, -507, 590 },
+ { -6458, -7524, -2807, 666 },
+ { -4991, -8466, -3363, -785 },
+ { -7474, -7541, -1056, -1839 },
+ { -7501, -8316, -938, -180 },
+ { -5329, -7739, -579, -2341 },
+ { -4549, -7063, -176, -3539 },
+ { -5191, -8612, -1504, -4250 },
+ { -3083, -7058, -2251, 32 },
+ { -4003, -7043, -1093, -791 },
+ { -5523, -8093, -678, -114 },
+ { -3022, -10265, -2070, -3109 },
+ { -3905, -6274, -182, -3652 },
+ { -3269, -9217, -551, -2650 },
+ { -3138, -9314, -1726, -1704 },
+ { -4420, -10339, -1744, -3459 },
+ { -4163, -8609, -2298, -4113 },
+ { -5566, -6505, -1241, -463 },
+ { -3130, -9746, -2352, -4884 },
+ { -7825, -3439, 1451, -1468 },
+ { -8451, -3318, 2360, -435 },
+ { -8462, -4130, 1438, -1024 },
+ { -9425, -4564, 1328, -689 },
+ { -11014, -3202, 2278, 2080 },
+ { -8269, -2761, -146, -440 },
+ { -7497, -2618, -166, 413 },
+ { -8250, -3060, 522, -2133 },
+ { -8365, -5366, 1347, -451 },
+ { -8589, -3979, 2943, 714 },
+ { -8111, -2572, 1272, -1748 },
+ { -7830, -5193, 605, -1484 },
+ { -8119, -4736, 2141, 256 },
+ { -7724, -4769, 1463, -812 },
+ { -7363, -3911, 2540, 4 },
+ { -7974, -3397, 2363, 1366 },
+ { -7359, -4204, 1752, -958 },
+ { -7622, -3505, 660, 916 },
+ { -9934, -3665, 3165, 828 },
+ { -8721, -4162, 62, 1718 },
+ { -9433, -4768, 2722, 1234 },
+ { -7960, -4496, 138, 1528 },
+ { -8198, -3454, -443, 631 },
+ { -7756, -2246, 655, 1137 },
+ { -8841, -3145, 1113, 829 },
+ { -7817, -3298, 1251, 230 },
+ { -9413, -2733, 323, -1862 },
+ { -9408, -4168, 1270, 1549 },
+ { -9037, -3892, -942, 283 },
+ { -8255, -3849, 1301, 1762 },
+ { -9057, -3987, -41, -682 },
+ { -9441, -4187, 2019, -111 },
+ { -9740, -3178, 1602, -871 },
+ { -8344, -2474, 1461, 1506 },
+ { -9752, -2925, 1996, 1243 },
+ { -9199, -3796, 180, 537 },
+ { -9060, -2405, 1140, -1562 },
+ { -9348, -2376, 309, -162 },
+ { -10786, -3182, -5, -1500 },
+ { -8142, -4540, -434, -826 },
+ { -7528, -2341, 1104, -73 },
+ { -9360, -2658, 3062, 56 },
+ { -8267, -2335, 2000, -1193 },
+ { -12169, -3154, 1287, -640 },
+ { -11398, -2120, 946, -1163 },
+ { -8940, -4559, 328, -1696 },
+ { -11025, -4213, 2813, 840 },
+ { -9224, -3581, 2224, 2039 },
+ { -8943, -3337, 1248, -1298 },
+ { -7900, -4042, 485, -2080 },
+ { -9221, -1947, 2191, -880 },
+ { -10762, -1800, 2516, -324 },
+ { -10095, -2238, 981, -1335 },
+ { -11908, -2808, 3255, 645 },
+ { -10640, -4105, 1283, -595 },
+ { -7663, -2863, 2467, -797 },
+ { -10712, -3854, 3710, 1538 },
+ { -10823, -2893, 1408, -801 },
+ { -9874, -3832, 256, -1638 },
+ { -10394, -3391, 2315, -94 },
+ { -11525, -4079, 4153, 2122 },
+ { -9546, -2088, 1541, 481 },
+ { -8731, -2433, 1042, 2160 },
+ { -7852, -3977, -1370, 1677 },
+ { 7072, -3420, 1398, -1741 },
+ { 6180, -1976, 1280, -3557 },
+ { 7692, -1793, 2844, -1700 },
+ { 8363, -1773, 3104, -2679 },
+ { 9213, -3266, 3756, -3542 },
+ { 9650, -2644, 1426, -1318 },
+ { 7712, -2796, 3686, -1975 },
+ { 7316, -3517, 2821, -622 },
+ { 7434, -2594, 2305, -2264 },
+ { 7237, -1797, 255, -3114 },
+ { 8663, -1983, 1338, -3056 },
+ { 6616, -952, 4059, -2652 },
+ { 8823, -1327, 1362, -1356 },
+ { 9938, -1722, 1287, -2362 },
+ { 7207, -1057, 1913, -1315 },
+ { 7508, -1585, 870, -1982 },
+ { 8217, -3680, 1417, -3170 },
+ { 8329, -2541, 1684, -585 },
+ { 8062, -2335, 252, -2800 },
+ { 8204, -4108, 3097, -2569 },
+ { 7701, -3367, 576, -3008 },
+ { 7350, -786, 2414, -2129 },
+ { 6948, -2568, 1607, -225 },
+ { 7684, -2387, 1308, -3449 },
+ { 8306, -3458, 2394, -1454 },
+ { 8438, -2781, 1043, -1362 },
+ { 9175, -2076, 2144, -1987 },
+ { 8347, -2709, 3489, -4301 },
+ { 5696, -2377, 2870, 851 },
+ { 8825, -1243, 2219, -2603 },
+ { 8801, -1614, 584, -2513 },
+ { 8413, -384, 1421, -2244 },
+ { 9228, -3050, 3279, -2164 },
+ { 6342, -2698, 3547, -107 },
+ { 10053, -2476, 2837, -3168 },
+ { 7439, -604, 3177, -3991 },
+ { 7749, -1064, 4329, -4855 },
+ { 8655, -2177, 2252, -3519 },
+ { 8490, -228, 1958, -3233 },
+ { 10513, -2968, 1911, -2340 },
+ { 8146, -862, 1884, -1723 },
+ { 7788, -666, 3004, -2891 },
+ { 7785, -1620, 4133, -3417 },
+ { 10262, -3731, 3455, -2971 },
+ { 8570, -905, 4519, -4649 },
+ { 9129, -2562, 463, -2465 },
+ { 9451, -3587, 1904, -3056 },
+ { 6549, -2236, 3010, -4523 },
+ { 7175, -2684, 2967, -3458 },
+ { 9872, -3278, 1054, -2472 },
+ { 9153, -931, 1217, -2565 },
+ { 8789, -3469, 753, -2568 },
+ { 6683, -3791, 1797, -3968 },
+ { 6801, -1977, 2311, -452 },
+ { 6336, -1572, 2612, -3264 },
+ { 7996, -1008, 730, -2964 },
+ { 7521, -1059, 1573, -3694 },
+ { 8148, -3973, 2600, -3572 },
+ { 7765, -1532, 2528, -3856 },
+ { 7404, -3918, 4472, -143 },
+ { 8894, -1398, 3299, -3685 },
+ { 5768, -2041, 1487, -637 },
+ { 5131, -2865, 2463, -811 },
+ { 6439, -1568, 3500, -1550 },
+ { -8878, -6798, -5319, -1452 },
+ { -6332, -9713, -3112, -990 },
+ { -8444, -6316, -3694, -687 },
+ { -6123, -10840, -3637, -4358 },
+ { -4784, -9580, -4577, -2581 },
+ { -6108, -10515, -4859, -2524 },
+ { -7605, -7518, -2327, -2797 },
+ { -9662, -8775, -2467, -2010 },
+ { -6494, -7523, -4715, -118 },
+ { -8290, -8982, -1672, -317 },
+ { -8798, -11051, -3888, -1426 },
+ { -6273, -6623, -6791, -142 },
+ { -8313, -7668, -2141, -1275 },
+ { -6453, -8412, -3589, -4102 },
+ { -6747, -7750, -5690, -2498 },
+ { -7814, -6693, -3174, -2446 },
+ { -10383, -10130, -3931, -2364 },
+ { -10606, -8467, -5539, -2772 },
+ { -9475, -6671, -3305, -2271 },
+ { -8982, -9457, -5635, -4005 },
+ { -10111, -7965, -6515, -4180 },
+ { -7301, -6479, -5364, 720 },
+ { -9543, -8999, -7921, -912 },
+ { -9534, -8562, -3469, -384 },
+ { -7601, -10344, -3205, -1127 },
+ { -8088, -8620, -4954, -2888 },
+ { -8202, -8406, -7038, -3775 },
+ { -7312, -8324, -3334, -1775 },
+ { -8566, -9262, -8071, -4174 },
+ { -7068, -11300, -5573, -2907 },
+ { -8295, -8952, -4366, -1544 },
+ { -11104, -10210, -2285, -384 },
+ { -5213, -7520, -5008, -1339 },
+ { -5889, -7940, -5987, -1385 },
+ { -10816, -8201, -4153, -1485 },
+ { -10277, -8919, -6315, -1652 },
+ { -5888, -10320, -3821, -1733 },
+ { -10497, -7181, -6083, -3032 },
+ { -7721, -9724, -6591, -5336 },
+ { -5688, -7894, -3486, -2552 },
+ { -10014, -10500, -3247, -820 },
+ { -6301, -8765, -4506, -2923 },
+ { -8261, -7847, -6213, -1552 },
+ { -10212, -7481, -8113, -3954 },
+ { -6938, -10874, -6074, -4703 },
+ { -7183, -10968, -4446, -1773 },
+ { -7120, -9193, -1966, -2509 },
+ { -6234, -9263, -2313, -4284 },
+ { -8503, -9857, -2429, -608 },
+ { -9372, -7844, -8391, -2120 },
+ { -7951, -7157, -6535, -11 },
+ { -7256, -9473, -2172, -660 },
+ { -10063, -9612, -2515, -15 },
+ { -6684, -9134, -6109, -4206 },
+ { -8204, -11932, -5220, -2306 },
+ { -9710, -6706, -4115, -3275 },
+ { -6855, -7078, -2409, -4447 },
+ { -7344, -7673, -4479, -4116 },
+ { -8851, -6842, -4927, -2948 },
+ { -8927, -10452, -5633, -2194 },
+ { -8627, -9002, -7176, -1575 },
+ { -8209, -9722, -7021, -3324 },
+ { -3770, -10249, -3623, -4816 },
+ { -8183, -7465, -4090, 646 },
+ { -8163, -7149, 200, 498 },
+ { -8289, -6266, 686, -206 },
+ { -10030, -6241, -1032, -1864 },
+ { -8793, -8327, -773, -169 },
+ { -9149, -6215, 969, -15 },
+ { -8303, -5859, -7, 2006 },
+ { -9682, -7283, 255, 1322 },
+ { -9293, -7227, 71, -231 },
+ { -8525, -6215, 287, -837 },
+ { -10477, -5379, 1159, 1449 },
+ { -10726, -7856, -130, 102 },
+ { -8694, -7461, -1210, 690 },
+ { -9367, -5324, 1103, 3170 },
+ { -10686, -8055, -831, 1633 },
+ { -9201, -6873, -2704, 2258 },
+ { -8421, -5358, -1405, 226 },
+ { -9066, -5830, -307, -1571 },
+ { -11150, -7381, -2746, -900 },
+ { -9978, -5925, -2006, -437 },
+ { -9464, -4741, -273, 1061 },
+ { -10543, -6684, -1113, 1660 },
+ { -10073, -5576, 1083, -269 },
+ { -8826, -5763, 1600, 1486 },
+ { -10445, -9071, -1253, -64 },
+ { -12085, -5799, 2, 769 },
+ { -12939, -6663, 1650, 1437 },
+ { -10932, -6434, -1252, -649 },
+ { -11650, -7826, -2053, 710 },
+ { -12122, -6733, -1889, -731 },
+ { -9093, -6095, -2463, -842 },
+ { -10977, -4364, 469, 420 },
+ { -11488, -6908, -521, 893 },
+ { -9669, -5478, -842, 337 },
+ { -10606, -5203, -632, -1361 },
+ { -10198, -6284, 1662, 1277 },
+ { -10135, -5292, 2435, 3493 },
+ { -11027, -6561, 655, 56 },
+ { -10977, -5030, 1127, -358 },
+ { -12766, -3986, 1348, -335 },
+ { -14244, -7731, 264, 317 },
+ { -15124, -10309, -508, 1447 },
+ { -12821, -8638, -608, 137 },
+ { -13076, -8693, -2852, -431 },
+ { -11156, -5546, -2252, -1600 },
+ { -8692, -7366, -819, -1223 },
+ { -12507, -9816, -1714, -121 },
+ { -10712, -6666, 544, 3349 },
+ { -12462, -5890, -2491, -2318 },
+ { -12468, -7226, 437, 232 },
+ { -11300, -5226, 2068, 687 },
+ { -11994, -8320, -626, 2728 },
+ { -12222, -5476, 1142, 18 },
+ { -10277, -8122, -2418, 2003 },
+ { -13418, -6115, -3563, -2802 },
+ { -14759, -9834, -1243, 21 },
+ { -13699, -5665, 1525, 507 },
+ { -16269, -9476, -701, 163 },
+ { -12677, -5437, -247, -1019 },
+ { -11827, -4295, -181, -1243 },
+ { -12847, -4496, 2984, 1123 },
+ { -13860, -7915, -1166, -547 },
+ { -12276, -8145, -2290, -1527 },
+ { -11417, -4830, 2983, 1854 },
+ { -11793, -6002, 1163, 1940 },
+ { 11443, -4920, -3235, 3151 },
+ { 11300, -6616, -1506, 1175 },
+ { 9198, -4628, -2060, 2390 },
+ { 10532, -4027, -643, 912 },
+ { 9902, -3573, -1606, 1327 },
+ { 9653, -3536, -2240, 1869 },
+ { 9948, -5171, -423, 2662 },
+ { 12316, -4004, -1989, 281 },
+ { 12125, -4800, -1265, -163 },
+ { 10650, -2617, -2337, 1462 },
+ { 9909, -4968, -2376, 916 },
+ { 12944, -4647, -1958, 460 },
+ { 12988, -5283, -1141, 41 },
+ { 12321, -2915, -3621, 1025 },
+ { 11449, -2894, -2728, 351 },
+ { 12087, -3041, -2002, -32 },
+ { 11558, -4031, -1343, -399 },
+ { 12983, -3740, -3516, 1245 },
+ { 12099, -2515, -2752, 225 },
+ { 12515, -3465, -2701, 550 },
+ { 14683, -5022, -5272, 2996 },
+ { 12260, -3383, -1215, -528 },
+ { 13810, -5422, -2443, 1166 },
+ { 13421, -5378, -1886, 721 },
+ { 12961, -4259, -2594, 796 },
+ { 12266, -2104, -4768, 1591 },
+ { 13523, -4710, -3045, 1342 },
+ { 12437, -2099, -5610, 2117 },
+ { 11850, -2183, -3497, 661 },
+ { 12275, -3936, -597, -697 },
+ { 12459, -5253, -517, -544 },
+ { 12835, -4094, -1322, -168 },
+ { 14360, -5677, -3305, 1859 },
+ { 13905, -4552, -4309, 2117 },
+ { 11559, -3412, -1847, -81 },
+ { 13379, -3167, -5764, 2746 },
+ { 11910, -1634, -4342, 1052 },
+ { 12662, -4742, 71, -974 },
+ { 13057, -3254, -4424, 1705 },
+ { 15046, -5706, -4851, 3019 },
+ { 14162, -4142, -5514, 2843 },
+ { 12764, -1845, -6684, 2888 },
+ { 13714, -2374, -7838, 3857 },
+ { 13295, -1663, -8293, 4073 },
+ { 10032, -4152, -3403, 1421 },
+ { 10942, -5386, -2222, 950 },
+ { 10532, -6385, -1750, 1925 },
+ { 10273, -5972, -1534, 643 },
+ { 10605, -4782, -1695, 27 },
+ { 10988, -5153, -1123, -341 },
+ { 11629, -5884, -1060, 48 },
+ { 10441, -4045, -2431, 311 },
+ { 10788, -3595, -4171, 1807 },
+ { 12110, -5686, -2127, 976 },
+ { 11746, -4773, -2639, 891 },
+ { 11541, -5299, -3031, 1732 },
+ { 11416, -2559, -5359, 2198 },
+ { 11583, -5376, -704, 677 },
+ { 10416, -3214, -3516, 872 },
+ { 9651, -5435, -1618, 3255 },
+ { 9973, -5133, -996, 3923 },
+ { 11707, -4643, -430, -796 },
+ { 10994, -2709, -3587, 2302 },
+ { 10716, -5118, -645, 270 },
+ { 14100, -10314, 1095, 1531 },
+ { 12944, -8049, 1105, -741 },
+ { 13276, -7035, -511, 274 },
+ { 14008, -7254, -283, 139 },
+ { 11594, -6536, -91, 1671 },
+ { 11732, -8645, 746, 15 },
+ { 14613, -7085, -1578, 1183 },
+ { 13083, -6224, -750, -4 },
+ { 13988, -6256, -1592, 820 },
+ { 14678, -8683, 441, 126 },
+ { 15571, -8872, -521, 1139 },
+ { 15642, -9533, 341, 697 },
+ { 15960, -9586, -168, 1121 },
+ { 15464, -10239, 1433, -1 },
+ { 14934, -7887, -1046, 1080 },
+ { 15252, -7630, -1899, 1628 },
+ { 15485, -8384, -1234, 1484 },
+ { 15962, -8638, -1815, 1931 },
+ { 16501, -10664, 398, 1167 },
+ { 16146, -10145, 411, 918 },
+ { 14573, -7475, -697, 601 },
+ { 14302, -7996, 28, 257 },
+ { 14769, -6792, -2286, 1574 },
+ { 14144, -6137, -2169, 1257 },
+ { 14770, -6271, -3111, 1933 },
+ { 14110, -8312, 1083, -531 },
+ { 15235, -6991, -2993, 2174 },
+ { 13222, -5805, 547, -891 },
+ { 14796, -8762, 1254, -246 },
+ { 16040, -9181, -1005, 1551 },
+ { 16487, -10086, -373, 1420 },
+ { 15077, -9479, 966, 51 },
+ { 13026, -6468, 932, -1080 },
+ { 12703, -6152, -33, -573 },
+ { 15641, -6810, -4128, 2874 },
+ { 13282, -7673, 1583, -1283 },
+ { 12373, -7150, 1512, -917 },
+ { 12992, -7751, -678, 783 },
+ { 10907, -6858, -313, 2597 },
+ { 13026, -8963, 125, 2152 },
+ { 12770, -9946, 1957, -505 },
+ { 12482, -6849, -1268, 833 },
+ { 13790, -6181, -138, -279 },
+ { 12709, -8382, 2044, 227 },
+ { 12244, -6630, 203, -457 },
+ { 14209, -6816, -1032, 632 },
+ { 15134, -8267, -288, 640 },
+ { 13619, -6157, -1090, 356 },
+ { 14044, -7413, 725, -484 },
+ { 12958, -7753, 2585, -1980 },
+ { 13188, -8396, 2306, -1558 },
+ { 14379, -9980, 2132, -688 },
+ { 14275, -9857, 1162, 179 },
+ { 13690, -8648, 1621, -889 },
+ { 11770, -6829, -746, 278 },
+ { 12732, -8202, 286, 90 },
+ { 13630, -10146, 1867, -207 },
+ { 12072, -8740, 1299, -645 },
+ { 12852, -9492, 1226, 62 },
+ { 11792, -7382, -54, -116 },
+ { 13779, -9014, 487, 351 },
+ { 11951, -7729, 121, 834 },
+ { 11970, -9781, 2276, -4 },
+ { 12680, -7984, 2787, -787 },
+ { 13300, -14488, 6408, -1927 },
+ { 13635, -15355, 9153, -3073 },
+ { 12804, -13566, 5517, -1625 },
+ { 16624, -10854, 1690, 28 },
+ { 20387, -18532, 6162, -261 },
+ { 16515, -12642, 3392, -519 },
+ { 15800, -11095, 2151, -202 },
+ { 16824, -11790, 1651, 599 },
+ { 17604, -13213, 2563, 538 },
+ { 17892, -14177, 3562, 147 },
+ { 16987, -11399, 869, 1052 },
+ { 17003, -12456, 2442, 265 },
+ { 21657, -21806, 9198, -1250 },
+ { 16825, -13341, 3980, -686 },
+ { 17525, -12714, 1887, 805 },
+ { 16419, -11034, 1216, 617 },
+ { 20931, -19939, 7469, -684 },
+ { 18452, -15390, 4573, -191 },
+ { 14778, -10077, 2841, -1209 },
+ { 17402, -13319, 3042, 160 },
+ { 19365, -17922, 7087, -1061 },
+ { 16298, -11941, 2810, -351 },
+ { 19087, -16176, 4775, -84 },
+ { 17666, -12289, 938, 1224 },
+ { 18581, -15894, 5132, -430 },
+ { 19823, -16717, 4142, 545 },
+ { 19960, -19423, 8400, -1492 },
+ { 18973, -16817, 5906, -594 },
+ { 19079, -15431, 3528, 503 },
+ { 16667, -12485, 4467, -1302 },
+ { 19791, -17797, 6196, -529 },
+ { 20005, -17606, 5354, -20 },
+ { 20123, -18599, 6886, -728 },
+ { 19068, -14805, 2394, 1105 },
+ { 14443, -13723, 5631, -2029 },
+ { 14730, -14231, 5631, -1450 },
+ { 16089, -15959, 7271, -2029 },
+ { 13473, -11200, 3236, -924 },
+ { 14413, -10902, 2347, -267 },
+ { 17666, -18662, 11381, -3496 },
+ { 14749, -11042, 3305, -275 },
+ { 15304, -10486, 1869, -240 },
+ { 14809, -12126, 3369, -616 },
+ { 16896, -16561, 7307, -1845 },
+ { 15782, -14336, 5380, -1264 },
+ { 16395, -15520, 6415, -1588 },
+ { 13681, -11114, 2584, -320 },
+ { 14244, -12326, 4480, -1632 },
+ { 15247, -13119, 4265, -898 },
+ { 13987, -12091, 3469, -597 },
+ { 13941, -12770, 4240, -839 },
+ { 13771, -13627, 5252, -1384 },
+ { 15010, -16074, 7592, -2249 },
+ { 15852, -17226, 8619, -2655 },
+ { 18921, -16916, 6875, -1501 },
+ { 14909, -11678, 2768, -295 },
+ { 18988, -18353, 8424, -2070 },
+ { 15457, -15080, 6218, -1513 },
+ { 14916, -15512, 6949, -1883 },
+ { 18108, -14702, 4681, -701 },
+ { 17600, -15733, 5616, -775 },
+ { 14070, -13683, 6472, -2626 },
+ { 13832, -11914, 5201, -2232 },
+ { 18846, -19009, 9192, -1961 },
+ { -11981, -10994, -6324, -2264 },
+ { -10976, -9047, -6546, -3828 },
+ { -11288, -10532, -7014, -4191 },
+ { -10139, -10189, -7799, -2688 },
+ { -10555, -9988, -9181, -2040 },
+ { -11596, -11339, -10022, -2707 },
+ { -13400, -13395, -11306, -4206 },
+ { -9774, -12281, -7466, -4133 },
+ { -10842, -13125, -8777, -4956 },
+ { -11964, -15082, -9779, -5095 },
+ { -9382, -10188, -9053, -4927 },
+ { -11562, -11296, -3651, -985 },
+ { -9287, -10083, -7918, -4069 },
+ { -12821, -16556, -11410, -6195 },
+ { -12628, -8959, -4521, -1113 },
+ { -13845, -11581, -3649, -681 },
+ { -12685, -10269, -5483, -1275 },
+ { -14988, -12874, -5107, -1189 },
+ { -13761, -11367, -6202, -1804 },
+ { -13225, -11249, -7820, -3354 },
+ { -14809, -11992, -3202, -312 },
+ { -15620, -15519, -10210, -3433 },
+ { -12954, -10200, -3139, -611 },
+ { -11536, -9981, -5284, -923 },
+ { -13034, -12417, -4612, -1098 },
+ { -16911, -15505, -6123, -1352 },
+ { -17396, -17685, -8330, -2171 },
+ { -14120, -10764, -2265, -99 },
+ { -12598, -7367, -5406, -3530 },
+ { -14143, -12793, -10909, -5226 },
+ { -14692, -16871, -11626, -5554 },
+ { -12581, -11197, -9194, -3837 },
+ { -16752, -16726, -9746, -2808 },
+ { -10600, -10358, -6560, -1227 },
+ { -14573, -13312, -8957, -3393 },
+ { -10172, -8463, -8579, -3387 },
+ { -11418, -12421, -5522, -1842 },
+ { -11855, -14204, -6669, -2625 },
+ { -13308, -8191, -3941, -2194 },
+ { -10007, -12266, -5022, -1811 },
+ { -13532, -15771, -9497, -3175 },
+ { -11760, -11148, -10339, -5529 },
+ { -12149, -12763, -11198, -3697 },
+ { -12029, -12119, -8555, -1792 },
+ { -16995, -19957, -11447, -3471 },
+ { -13144, -14504, -9988, -3191 },
+ { -9938, -11064, -6139, -3162 },
+ { -8873, -11550, -8294, -6550 },
+ { -9303, -13010, -6150, -2711 },
+ { -15463, -10469, -1766, -170 },
+ { -15985, -11693, -3007, -650 },
+ { -17142, -10671, -1434, 47 },
+ { -16063, -13858, -4817, -1058 },
+ { -19446, -19599, -9594, -2464 },
+ { -20076, -18744, -8313, -1889 },
+ { -15047, -16085, -7590, -2250 },
+ { -13481, -16195, -8552, -2998 },
+ { -13829, -14869, -6704, -1932 },
+ { -16357, -18484, -9802, -2959 },
+ { -10551, -8393, -9303, -5070 },
+ { -11345, -9156, -5641, -3107 },
+ { -13217, -13449, -9270, -4541 },
+ { -11988, -13732, -9995, -6374 },
+ { -11007, -9519, -5168, -4107 },
+ { 9930, -7858, 8061, -4375 },
+ { 8274, -7867, 5992, -2096 },
+ { 9692, -9675, 7621, -3670 },
+ { 9589, -8110, 6509, -3010 },
+ { 12617, -11976, 10122, -5360 },
+ { 11867, -8895, 7948, -5323 },
+ { 10388, -10482, 9234, -4324 },
+ { 8188, -8220, 7810, -2737 },
+ { 10407, -8787, 4806, -1930 },
+ { 10348, -8845, 9233, -6614 },
+ { 9422, -7091, 4820, -2878 },
+ { 9758, -9796, 5584, -2256 },
+ { 10188, -7994, 5347, -3343 },
+ { 11133, -7455, 4015, -2306 },
+ { 10676, -10744, 6093, -2629 },
+ { 11522, -12184, 7848, -3375 },
+ { 8805, -9883, 5317, -3071 },
+ { 9498, -9654, 6555, -3592 },
+ { 10488, -8008, 4066, -1252 },
+ { 11261, -8930, 6068, -2738 },
+ { 12180, -10397, 5027, -1531 },
+ { 9138, -8531, 3601, -1959 },
+ { 8107, -8380, 4970, -2061 },
+ { 9737, -13248, 6438, -2617 },
+ { 11178, -10423, 2622, -522 },
+ { 9572, -12372, 5199, -2019 },
+ { 12057, -12144, 4147, -1099 },
+ { 9047, -9925, 2516, -665 },
+ { 10790, -8030, 5882, -4386 },
+ { 7199, -8426, 6337, -2841 },
+ { 7778, -8285, 3529, -3442 },
+ { 7559, -10569, 3484, -1332 },
+ { 9404, -8115, 7484, -5541 },
+ { 7792, -11976, 5546, -2573 },
+ { 9313, -10264, 7661, -5195 },
+ { 6701, -10725, 4370, -1784 },
+ { 4918, -11361, 4507, -4527 },
+ { 5147, -12305, 3978, -5556 },
+ { 6525, -9899, 4481, -3129 },
+ { 7538, -12855, 6060, -4826 },
+ { 8659, -12111, 7159, -4430 },
+ { 8440, -11304, 4547, -1747 },
+ { 9216, -10918, 3507, -1195 },
+ { 6165, -9254, 4771, -4677 },
+ { 9163, -11019, 5637, -4935 },
+ { 13441, -11509, 6676, -2434 },
+ { 7912, -9398, 6663, -4048 },
+ { 11723, -13745, 8131, -4148 },
+ { 6065, -10257, 5005, -6327 },
+ { 11618, -12417, 5336, -1894 },
+ { 8891, -13924, 8407, -6131 },
+ { 9622, -12563, 7908, -5109 },
+ { 11479, -10315, 8349, -3991 },
+ { 11676, -14103, 6611, -2330 },
+ { 11951, -8953, 3829, -1550 },
+ { 10486, -8044, 10493, -5920 },
+ { 11801, -10769, 9763, -5305 },
+ { 6109, -8676, 5827, -1346 },
+ { 7030, -9611, 5624, -5761 },
+ { 12808, -12886, 8683, -4148 },
+ { 13213, -10464, 6381, -3189 },
+ { 11796, -13681, 10703, -6075 },
+ { 9639, -7949, 9625, -3944 },
+ { 8538, -6997, 5309, 453 }
};
/* quantization tables */
static const uint32_t scale_factor_quant6[64] = {
- 1, 2, 2, 3, 3, 4, 6, 7,
- 10, 12, 16, 20, 26, 34, 44, 56,
- 72, 93, 120, 155, 200, 257, 331, 427,
- 550, 708, 912, 1175, 1514, 1950, 2512, 3236,
- 4169, 5370, 6918, 8913, 11482, 14791, 19055, 24547,
- 31623, 40738, 52481, 67608, 87096, 112202, 144544, 186209,
- 239883, 309030, 398107, 512861, 660693, 851138, 1096478, 1412538,
- 1819701, 2344229, 3019952, 3890451, 5011872, 6456542, 8317638, 0
+ 1, 2, 2, 3, 3, 4, 6, 7,
+ 10, 12, 16, 20, 26, 34, 44, 56,
+ 72, 93, 120, 155, 200, 257, 331, 427,
+ 550, 708, 912, 1175, 1514, 1950, 2512, 3236,
+ 4169, 5370, 6918, 8913, 11482, 14791, 19055, 24547,
+ 31623, 40738, 52481, 67608, 87096, 112202, 144544, 186209,
+ 239883, 309030, 398107, 512861, 660693, 851138, 1096478, 1412538,
+ 1819701, 2344229, 3019952, 3890451, 5011872, 6456542, 8317638, 0
};
static const uint32_t scale_factor_quant7[128] = {
- 1, 1, 2, 2, 2, 2, 3, 3,
- 3, 4, 4, 5, 6, 7, 7, 8,
- 10, 11, 12, 14, 16, 18, 20, 23,
- 26, 30, 34, 38, 44, 50, 56, 64,
- 72, 82, 93, 106, 120, 136, 155, 176,
- 200, 226, 257, 292, 331, 376, 427, 484,
- 550, 624, 708, 804, 912, 1035, 1175, 1334,
- 1514, 1718, 1950, 2213, 2512, 2851, 3236, 3673,
- 4169, 4732, 5370, 6095, 6918, 7852, 8913, 10116,
- 11482, 13032, 14791, 16788, 19055, 21627, 24547, 27861,
- 31623, 35892, 40738, 46238, 52481, 59566, 67608, 76736,
- 87096, 98855, 112202, 127350, 144544, 164059, 186209, 211349,
- 239883, 272270, 309030, 350752, 398107, 451856, 512861, 582103,
- 660693, 749894, 851138, 966051, 1096478, 1244515, 1412538, 1603245,
- 1819701, 2065380, 2344229, 2660725, 3019952, 3427678, 3890451, 4415704,
- 5011872, 5688529, 6456542, 7328245, 8317638, 0, 0, 0
+ 1, 1, 2, 2, 2, 2, 3, 3,
+ 3, 4, 4, 5, 6, 7, 7, 8,
+ 10, 11, 12, 14, 16, 18, 20, 23,
+ 26, 30, 34, 38, 44, 50, 56, 64,
+ 72, 82, 93, 106, 120, 136, 155, 176,
+ 200, 226, 257, 292, 331, 376, 427, 484,
+ 550, 624, 708, 804, 912, 1035, 1175, 1334,
+ 1514, 1718, 1950, 2213, 2512, 2851, 3236, 3673,
+ 4169, 4732, 5370, 6095, 6918, 7852, 8913, 10116,
+ 11482, 13032, 14791, 16788, 19055, 21627, 24547, 27861,
+ 31623, 35892, 40738, 46238, 52481, 59566, 67608, 76736,
+ 87096, 98855, 112202, 127350, 144544, 164059, 186209, 211349,
+ 239883, 272270, 309030, 350752, 398107, 451856, 512861, 582103,
+ 660693, 749894, 851138, 966051, 1096478, 1244515, 1412538, 1603245,
+ 1819701, 2065380, 2344229, 2660725, 3019952, 3427678, 3890451, 4415704,
+ 5011872, 5688529, 6456542, 7328245, 8317638, 0, 0, 0
};
/* 20bits unsigned fractional binary codes */
static const uint32_t lossy_quant[32] = {
- 0, 6710886, 4194304, 3355443, 2474639, 2097152, 1761608, 1426063,
- 796918, 461373, 251658, 146801, 79692, 46137, 27263, 16777,
- 10486, 5872, 3355, 1887, 1258, 713, 336, 168,
- 84, 42, 21, 0, 0, 0, 0, 0
+ 0, 6710886, 4194304, 3355443, 2474639, 2097152, 1761608, 1426063,
+ 796918, 461373, 251658, 146801, 79692, 46137, 27263, 16777,
+ 10486, 5872, 3355, 1887, 1258, 713, 336, 168,
+ 84, 42, 21, 0, 0, 0, 0, 0
};
static const float lossy_quant_d[32] = {
/* 20bits unsigned fractional binary codes */
static const uint32_t lossless_quant[32] = {
- 0, 4194304, 2097152, 1384120, 1048576, 696254, 524288, 348127,
- 262144, 131072, 65431, 33026, 16450, 8208, 4100, 2049,
- 1024, 512, 256, 128, 64, 32, 16, 8,
- 4, 2, 1, 0, 0, 0, 0, 0
+ 0, 4194304, 2097152, 1384120, 1048576, 696254, 524288, 348127,
+ 262144, 131072, 65431, 33026, 16450, 8208, 4100, 2049,
+ 1024, 512, 256, 128, 64, 32, 16, 8,
+ 4, 2, 1, 0, 0, 0, 0, 0
};
static const float lossless_quant_d[32] = {
- 0, 1.0, 0.5, 0.33, 0.25, 0.166, 0.125,
- 0.083, 0.0625, 0.03125, 0.0156, 7.874E-3, 3.922E-3, 1.957E-3,
+ 0, 1.0, 0.5, 0.33, 0.25, 0.166, 0.125,
+ 0.083, 0.0625, 0.03125, 0.0156, 7.874E-3, 3.922E-3, 1.957E-3,
9.775E-4, 4.885E-4, 2.442E-4, 1.221E-4, 6.104E-5, 3.052E-5, 1.526E-5,
7.629E-6, 3.815E-6, 1.907E-6, 9.537E-7, 4.768E-7, 2.384E-7, 0,
0, 0, 0, 0
};
-
/* Vector quantization tables */
-DECLARE_ALIGNED(8, static const int8_t, high_freq_vq)[1024][32] =
-{
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- { -4, -2, 2, 1,-16,-10, 1, 3, 1, 0, 6, 1, -3, 7, 1,-22,
- 2, -4, -3, 11, 14, 6, -1, 1,-13, 29,-28, 10, 10, -8, 0, -9 },
- { -8, 8, -7, 10, -3,-12, -5, -8, 1, -2, 9, -2, -5,-18, 1, 9,
- -8, -8, 3, 41, 7, -9, -9, 22,-42,-29, 14,-18,-14,-32, 1,-15 },
- {-16, 8, 15, 16,-16, 5, 2, 7, -6,-16, -7, 1, 1, -3, -2, 0,
- 8, 20,-26,-11, 2,-17, 0, -3,-34,-37, 10, 44, -2, 22, 2, -4 },
- { 7, 14, 5, 6, 15, -1, 3, -3, -9,-23, -5,-14, 8, -1,-14, -6,
- -5, -8, 54, 31, -6, 18, 2,-19, -2,-11,-30, -6,-19, 2, -2,-14 },
- { 1, 2, -2, -1, -3, -3, 1, -5, 1, -3, -4, -8, 5, -4, 0, 1,
- 3, 7, -5, -4, -3,-12, 3, -2, -3, 12,-53,-51, 6, -1, 6, 8 },
- { 0, -1, 5, 1, -6, -8, 7, 5,-18, -4, -1, 1, 0, -3, -3,-14,
- -1, -6, 0,-14, -1, -1, 5, -3,-11, 1,-20, 10, 2, 19, -2, -2 },
- { 2, 4, 3, 0, 5, 0, 3, 1, -2, 0, -6, -3, -4, -5, -3, -3,
- -7, 0,-34, 4,-43, 17, 0,-53,-13, -7, 24, 14, 5,-18, 9,-20 },
- { 1, 0, -3, 2, 3, -5, -2, 7,-21, 5,-25, 23, 11,-28, 2, 1,
- -11, 9, 13, -6,-12, 5, 7, 2, 4,-11, -6, -1, 8, 0, 1, -2 },
- { 2, -4, -6, -4, 0, -5,-29, 13, -6,-22, -3,-43, 12,-41, 5, 24,
- 18, -9,-36, -6, 4, -7, -4, 13, 4,-15, -1, -5, 1, 2, -5, 4 },
- { 0, -1, 13, -6, -5, 1, 0, -3, 1, -5, 19,-22, 31,-27, 4,-15,
- -6, 15, 9,-13, 1, -9, 10,-17, 4, -1, -1, 4, 2, 0, -3, -5 },
- { -7, 3, -8, 13, 19,-12, 8,-19, -3, -2,-24, 31, 14, 0, 7,-13,
- -18, 0, 3, 6, 13, -2, 1,-12,-21, 9, -2, 30, 21,-14, 2,-14 },
- { -3, -7, 8, -1, -2, -9, 6, 1, -7, 7, 13, 3, -1,-10, 30, 4,
- -10, 12, 5, 6,-13, -7, -4, -2, -2, 7, -3, -6, 3, 4, 1, 2 },
- { -8, 9, 2, -3, -5, 2, 0, 9, 3, 7, -4,-16,-13, 3, 23,-27,
- 18, 46,-38, 6, 4, 43, -1, 0, 8, -7, -4, -1, 11, -7, 6, -3 },
- { 1, 1, 18, -8, -6, 0, 3, 4, 22, -3, -4, -2, -4,-11, 40, -7,
- -3,-13,-14, -7,-10, 14, 7, 5,-14, 11, -5, 7, 21, -2, 9, -3 },
- { 0, 0, -2, 4, -2, 0, 2, 0, -1, 2, -1, 0, 0, 2, 2, 2,
- -1, 1, -3, -1,-15, -2,-63,-27,-21,-47,-14, 1,-14, 10, 0, 2 },
- { 1, 0, -4, 0, -3, -9, 4, 2, 6, -6, 0, -5, 11, -7,-15, 6,
- -7, -6, 3, 7,-15, -5, 23,-13, -6, 12, -8, 9, 2, -3, 3, 4 },
- { 6, 0, 3, 0, -2, -4, 2, 1, 1, -1, 1, -2, -1, -4,-22,-15,
- -46,-66, 10, 20, 2,-17, 12, -6, 1, -2, -2, 0, 1, -5, 1, 2 },
- { -1, 0, 0, 1, 0, -4, 0, 1,-10, -3, -8, 5, 7,-11, 2,-11,
- 29,-25, 11, 10, 0, -1, 5, -7, -2, -5, -2, 4, 4, -3, 5, -2 },
- { 1, -1, -1, -3, -2, 1, -8, -3, 2, -2, 4, -5, -1, -7, -2, 1,
- -14, -7, 3,-30,-15,-14, 3, -4, -1, 3,-13, -1, -3, 1, 2, 3 },
- { -1, -2, -3, 2, 2, -3, 3, 1, -3, 2, 0, -4, 6, 5, -5, 10,
- -57, 3, 22,-50, 1, -2, -5, -6, -1, 5, 1, 2, 2, 1, -2, 2 },
- { 2, 0, -1, -7, 2, 1, 3, 2, 0, 4, 3, -2, 3, -3, 4, -4,
- 24,-35, -3, 38, -6, -5, 15, 20, 3, 16, -7, -5, 0, -4, -5, 0 },
- { 0, 1, 0, 0, 0, -1, -1, 1, 1, -1, 1, -2, 0, 0, 0, 0,
- 0, -1, -2, -1, -5, -2,-43, -3, 46,-52,-10, 7, -8, 11, -2, -1 },
- { 0, 0, -1, 0, -1, 2,-41, 33,-44,-48,-15,-26, -9, 6, 3, 3,
- -3, 2, 2, 2, 2, -1, -1, -2, 1, 3, 0, 0, 5, 2, 3, 1 },
- { -4, 1, 6, 1, -6, -1, -2, 1,-14, -4, 0, -5, -2, 2, -2, 0,
- -6, 1, 0, 8,-21, 32, -3,-36, -6, -2, -1, -7, 3, 0, 1, -6 },
- { -3, -2, 3, 0, 2, 2, 8, -4, -4, 6, 2, 1, 3, -6, 4, 3,
- 13, 0,-12, -1, 25,-20, -2,-23,-15, 7, -3,-11, -3, 6, -1, 0 },
- { 0, 0, -3, -1, 0, 0, -2, -1, -2, -2, 1, -1, 0, 0, 10, 3,
- -2, 3, 3, -7, -6, -5, 0, -4,-60,-16, -6, 38, 5, 6, -5, 0 },
- { 0, 1, 0, 0, 0, 0, 0, 0, 1, -1, -1, 0, 1, 0, 0, 1,
- 0, 0, -1, 0, -8, 2, -9, 10, 40, 31,-56,-21, 4, 20, -4, 7 },
- { -2, -2, 0, 4, -3, -1, 7, 3, 1, 3, -8, 0, 3, 1, 2, 5,
- 1, -2, 14, 5, 4, 5, 5, 5, -5, 9,-66, 0,-20, -2, -8, 4 },
- { -2, -1, 4, -1, -8, -2, -4, -1, -3, -3, 2, -7, -3, 5, 7, -2,
- 45, 31,-17,-16, -2, -2, -1,-22, 1, -1, -3, 3, 5, -3, 5, -1 },
- { -4, 0, 7, 5, 8, 7, 2, 9, -9, -9, -7,-11, -3, -8, 17, -4,
- 34, 32, 18, 22, 1, 2, 1, -7, -5, 6, -1, 6, 4, 10, -2, -7 },
- { 6, 0, 14, 9, 6, -1, -2, -3, 4, -6, -8, 4, 7, -1, 28, 38,
- 15, -1, 16,-11, 5, 8, 4,-10, 3,-10,-17, 5, 3, 3, 3, 1 },
- { 1, 1, 2, -1, 2, 1, 0, 0, -1, 0, 0, -2, 1, -3, 0, 1,
- 2, -2, -4, -2, 0, -1, 1, -3, 1, 1, 1, -1, 8, 8, 66, 33 },
- { -5, 2, -3, -7, 2, -8, -4, 10, 17,-18, -7, 4, -4, -7, -6, -6,
- -5, 5,-12, 2, 0, 6, 8, -2, 1, 4,-11, 2, 1, 8, 31, 19 },
- { 6, 9, 16, -6, -6, -1, -2, -3,-11, -2, 7, 7, 17, 3, 4, 10,
- 2, 5,-13, 8, 7, 1, 4, 5, 7, 6, 7, -8, 9, -8, 33, 6 },
- { 3, -1, 1, 0, -7, -5, 0, 14, -7, 1, -7, 1, 2, -4, 7, 10,
- -16, 12, 1, -6, 3, 8, -1, 10,-13, -6,-12,-23, 12, -3, 30, 14 },
- { -2,-15, 0, 8, 3,-19, 5, -3, 2, 3, 13, 7, 14, -3,-10, 0,
- 8, 5, -6,-16, -8, -8, 14, 2, -1, 1, -9,-11, 11, -5, 27, 9 },
- { -8, 6, -4, 4, -4, -1, 5, 4, 1, -7, -5, -4,-15, 1, 9, 0,
- 8, 4, 1,-17, 11, -2,-19, -1, -6, -8, 3,-12, 3,-17, 33,-10 },
- { -3, -1, 2, 7, 7, -2, 9, 8,-18, -1,-13,-10, -3, -3, 11, 8,
- -2,-12, -8, 1, 4, 9, 14, 10, -3, 0, 2, 1, -2, 3, 31, 10 },
- { -3,-10, 8, -1, -5,-11, 7, -5, 3, 6, 1, 4,-16, 10, 5, -4,
- -2,-10, -1, 13, 6, -5, -7, 12, 7, -3,-17, 1, 12, -4, 29, 8 },
- { 1, 2, 5, 2, -6, -7, 0, -1, 6, -1, 10, 6, -4, 5, 2, 2,
- -2, -8, -6,-11, 14,-13, 27, 3, -2,-12, 5,-16, 2,-26, 20, 15 },
- { -1, -3, -5, -3, -3, 6, -1, 3, -5, 1, 7, 2, 1, 0, -1, -1,
- 0, -1, 9, 7, -6, -3, 4, -5, -4, 8, -8,-25, -8, -4, 34, 23 },
- { -1, -2, 1, 1, -1, -2, -1, 1, -1, 0, 0, 0, 0, -2, -1, 1,
- 0, 2, 1, -1, 4, 0, 0, 1, -1, 0, 5, 3, 12, -9, 68,-16 },
- { 10, 0, -8, 14, -6, 1,-12, 0, 0, -3, -5,-11, -6, 12, 9,-10,
- -3, 5, 0, 7, 11, 2, 4, -3, -8, -3, 7, 4, 3, -3, 34, 4 },
- {-12, 13, -5, 7,-11, -2, -1, 1, -4,-14,-21, 3, -3, -3, -4, -7,
- -9, -4, 3,-17, -2,-13, 10, -2, 12, -4, 0, -9, 1, -5, 31, 10 },
- {-10, 6, 5, 6, 4, -7, 10, 0,-28, -3, 0,-11, -1, -5, 16,-10,
- -16, 7, 20, 2, -4, 2, -5, 0, 15, 6, 5,-10, 7, -9, 20, 4 },
- { 1, -7, -2, -7, 4, -3, -2, -7, -1,-14, 6,-16, 4, -5, -4, -6,
- -5, 0, -2, 2, -6, 9, -5, 4,-18, 8,-10, 8, 15, 0, 32, 1 },
- { -5, 7, -3, 7, 15, -4, 0,-16, 9, 5, -5, 5, 4, -3,-12, -9,
- -18, 10, 2, 2, -3, 7, 3, -1, 6, -9,-10, 3, 15, -4, 35, -7 },
- { -1,-10, 2, 2, -4, -2, 10, 2, -1, 2, -2, 1, -1,-14,-11, 3,
- -8, 5, -8, -2, 6, -1, -7, 1, 7, 5, 7, 8, 30, -4, 30, 14 },
- { 2, -2, 1, 2, 3, -8, 3, 0, -2, 0, -9, 2, 1, 4, -6, -1,
- -2, 5, 0, 1, -2, 12, 6, -3, 9, -3, 4,-12, 21,-39, 24, -2 },
- { 3, 5, 1, -2, -2, -2, -3, 6, -8, -2,-11, -8, -1, 4, 2, 2,
- -4,-10, 12, -5,-11, 1,-15,-34,-11, -7,-11, -1, 7,-14, 38, -1 },
- { -4, 4, 8, 9, 8, 1, -5, -9, 4, -2, 15, -4, 11,-15, 20, -1,
- -1, -3, 4, -9, -2, -2, -2, 8, 6, 12, -5, 0, 11,-12, 27, -4 },
- { 0, 8, -4, 3,-11, 6,-11, 2, 3, 0, 5, -8, -7, -6, -9,-21,
- 4,-11, -1,-16, -7, 16, -3, 7, -7, 4, -5, 0, 11, -7, 31, 3 },
- { 1, 3, 4, 11,-11, -2, -3, -6, 6, 5, 0, 3, -9, -6, 4, -4,
- 0, 4, -8, 13, -6,-13, -1, -5, -1, 4, 0, 0, 9,-22, 24, 18 },
- { -7, 3, 10,-13, -6, 6, -6, 6, 22, 1, 0,-14, 2, 3, 7, -1,
- 8, 20, -1, 5, -4, 13, 9, -9, -9, 6, 0, -4, 0, -8, 31, -4 },
- { -3, -4, 0, 1, 7, 3, -7, 0, 5, -2, 1, 3, 3, 1, -5, -2,
- 5, 2,-11, 4, 0, -1, 12, 0, -3,-13, 15, 8, -6,-27, 34, 0 },
- { -3, -3, 10, -4, 2, -1, -3, 0, -1, -1, -4, 2, 6, -2, 12, 1,
- 3, -6, -7, -6, -5, 4,-19, -6, -8,-34, -4, -8, 10, -7, 23, 10 },
- { -7, 0, -1, -6, 8, 4, -4, 2, -5, -8, -7, -9, -8, 5, 9, 7,
- -6, 1,-12,-12, -1,-16, 5, 0, 16, 3, -7, -8, 27, -4, 23, 15 },
- { -8, 4, 8, 5, 6, 11, -3, 5, 3, -1,-11, 6, -5, 0, 2, -6,
- -3, -6, 4, -1, 5, -5,-12, -6, 7, -5, 9, 3, 6, -7, 29, 1 },
- { 1, 3, -2, -2, -6, -2, 1, 6, -6, -3, 1, 2, 3, 4, 1, 5,
- -1, 0, 4, 2, 11, 6, 2, -3, 13, -9,-19, 18,-15,-10, 36, 21 },
- { -3, -3, 2, -1, -7, 6, -4, 1, -3, -1, -2, 2, 3, -7, -3, 0,
- -2, 0, -2, 6,-19, 3, -8, 2, -6, 7, -1, 0, 29, -6, 28,-10 },
- { -5, 1, -3, -7,-12, -4, 1, 1, -1, 13,-10, -1, -9, -5,-13, 6,
- 13, 3, -4, 2, 3, 11, 2, 6,-25,-16, -6, 0, 14, -1, 27, 16 },
- { -6, -1, -7, -5, -2, -5, -5, -1, 9, 1, 0, 3, -8,-12, -6, 5,
- -6, 5, 3, -9, 1, 4, -7,-10, -9, -7,-17, -5,-15,-23, 25, 3 },
- { -8, -2, 9, -3, -4, 3, -1, 8, -7, -7, -5, -4, -2, 9, 4, -1,
- -7, -4, -5,-16, 3, -6, 18,-13, -9, 16,-15, 8, 15,-10, 24, 5 },
- { 1,-38, 2, 34, 9, 10, 11, 2, 2, -6, 3, 2, -2, 5, 4, -7,
- -1, 1, 4, 0, 3, 1, -8, -1, -6, 5, 4, 2, -4, 5, 2, -1 },
- { 1,-22, 15, 18, -2, 10,-16, -9, -8,-11, 8, 4, 0, 7,-14, -5,
- -1, -7, 12, 17, 9, 5, -7, -4,-12, -6, 7, 0, 7, 2, -2, 1 },
- {-11,-29, 7, 10, 19, -1, -8, -9, 7, 1, 9, 6, 8, -7,-14, 8,
- -3,-11,-13, 0, -7,-23, -2, -8, 12, 9, 2, 14, 19, 1, -1, 5 },
- {-24,-27,-11, 36, 2, 6, -3, 4, -6, 8, 0, 12, -1, -4, -6, 3,
- 4, -1, 2, -3, -2, 3, 2, -1, -2, -4, 0, -1, -2, 7, 2, 3 },
- { -9,-24, 11, 13,-10,-12, 12, -2, 7, 4, 8, 13, -3, -3, 2, 9,
- -3, -4, 4, 13, 5, 13, -6, -3, 1, 15, 7, -3, 0, 19, -2, -9 },
- { -8,-15, 7, 14, -4, -5, 2,-18,-19, -2, 2, 17, 16, 6,-10, 10,
- -9, 14, -1, -5, -1, -6, -7, 2, 9, 11, 13, 6, -5,-12, 3, 2 },
- {-10,-37, 13, 1, 3,-14, 0,-20, 4, -3, 8, 2, -2, -3, -9, -5,
- -3,-17, -1, 13,-11, 2, -6, 4, 4, 0, 3, 1, -9, -4, -5, -4 },
- { -2,-22, -5, 46, -8, 5, 9,-11, 8, 7, 7, -1, -1, -2, -7, 2,
- -3, 3, -1, -2, 7, 0, 2, -1, 1, -2, -2, -3, 6, 0, -4, -6 },
- {-16,-27, 15, 16, -4, 14, -7,-26, 2, -2, 6, 5, -3, 11, 0, 2,
- 3, 9, -7, -1, 2, -4, -4, -1, 6, 10, 1, 1, -3, -2, 3, 0 },
- { -3,-22, 10, 26, 1, 2, -3, 3, 17, -3, -7, 9, 1,-21, -4, 5,
- 3, 0, -7, -6, 3, 3, -8, -7, -9, 3, 7, 1, -8, 12, 6, -7 },
- { -9,-25, 3, 18, 9, -6,-11, 0, -5,-12, 9, -8, -7, -6, -6, 22,
- 2, -6, -3, 15, 3, 2, -2, 9, 14,-10, -7, 15, 13, 6, -2, 11 },
- { 5,-20, -5, 28, 11, 10, -4, -4, 0, -7, 3, 5, 2, -5, -8, 2,
- 6, 10, 9, -9,-18, 3, 14, 1, 3, -3, -1, -6, 7, 7, 2, -1 },
- { -8,-30, 7, 12, 10, 8, 7,-13,-16, 0, 1, -1, -6,-11,-15, 4,
- 1, -2, 10,-15, 1, 11, -2, 8, 9, -7, -7, 9, -5, 2, 7,-18 },
- {-10,-32, 10, 11, 3, -1, 3, -5, 5, 2, 14, -6, 3, 1, 5,-15,
- -11, 6, 20, 4, 0,-12, -7, 3, 1, -1, 10, 6, -1, -9, -4, -1 },
- { 1,-25,-14, 12,-11, 9, 9,-16,-24,-17, 22, -9, 11,-30, -3, -4,
- 6, -7, 9, 2, -1, -5, -6, 2, -1, -1, 10, 1, -3, 3, 4, 8 },
- {-14,-26, -6, 9, 8, 17,-11,-24, -7, -4, -8, -2, 10, 2, 2, -1,
- 2, 13, 12, -7, 4, -6,-10, 6, 6,-13,-11, -7,-16, 0, -2, 5 },
- { -4,-30,-13, 12, 16, -6, 12,-16,-13, 5, 15, -2, -2,-10, -7, 7,
- 11, -1, -4, -2, -4, 7, 4, -8, 1, 3, 0, 11, 3, -2, -5, 4 },
- { -4,-21, 20, 22, 2, 20, -8, 1,-12, -5, -9, 4,-10,-17, -3, -8,
- -3, 3,-12, 1, -3, 0, 7, 4, 7, 7, -3, 7, 5, 3, 1, -5 },
- {-12,-20, 2, 29, 11, -6, 9, -7, -6, -4, 0, 6, 17,-13, -2,-10,
- -17, -1,-18, 2, 0, 14, -6, 1, 0, 3, 2,-10, 1, -5, -2, 5 },
- { 16,-37, -1, 26, -2,-14, 1, -5,-14, 2, 2, 3, 6, 1, 1, 4,
- 0, -1, 0, -2, -2, 4, 9, -6, 0, -2, 10, -7, -2, 4, 1, 0 },
- { -9,-24,-12, 5, 5, 3,-17,-14, 4, 3, 2, -4, 10,-22, -8, -3,
- 6, 1, 12, -8, 4, 1, 9, -1, 18, -3, 6, 5, 3, -5, 9, -5 },
- {-14,-33, -2, 20,-13,-10, 2, -7, -1, 11, -9, -8, 18, -3, 1, 8,
- 0, -2, 10, 7, -2,-13, 9, -3, -4, 5, -2, -2, -1, -5, 1, -7 },
- {-10,-23, 8, 14, 1, 7, 1, -3, -7, 4, 1, 1, 8, -7, 15,-14,
- 13, 14, 2, 5,-13, -5, -8, -1, 6, 3, 6, 9, 6, 15, 14, 5 },
- {-13,-25,-10, 13,-17,-24, -7,-13, -6,-10, -8, 2, 0,-13,-10, -4,
- -8, 4, -9, 9, -4, 4, -3, -3, 3, 3, -5, -9, 1, -2, 11, 2 },
- {-12,-23, 1, 18,-11, -2, 5, 9, -5, 5, 14, -9, -3, -2, -6, 2,
- -2, 11,-13, 1, -3, 11, -9, -4, -2, -6, 8, 10, 1, 4, 2, 1 },
- { -5,-18, 16, 22, 2, 0, 8, -6, -9, -7, 10,-16, 23, 10,-11, -1,
- 7, 2, 7, 2, 1, -5, 6, 1, 0, -4, 9, 2, -3, 1, 0, -4 },
- { -3,-26, 14, 11, 2, -9, 17, -2, -1, -5,-16, -9, -5, 10,-13, 1,
- 6, 12, 10, 11, 0, 0, -3,-14, 6, -2, 0, 4, -5, -1, -7, -1 },
- {-10,-33, 1, 8, 11, -5, 1, -6, 7, 4, 5, 6, 1, -2,-10, -5,
- -6, 12,-11, 5,-10, 4, 12, -1, -1, -3, 4, -1, 9, 0, 16,-17 },
- {-14,-37, 7, 7, -2, 5, -8,-11, 2,-13, 4,-19, 1, 8, 8, 4,
- -9, 2, -4, 3, 12, 2, 4, -4, -8, 8, 1, 4, 8, -1, 6, -2 },
- { -6,-30, 18, 17, 1,-22, -3, 4, -7,-10, 7, 0, -8, 8, -1, 4,
- 2, 8, 6, -2, 2, 7, 4, 4, 3, -6, 2, 1, -3, 1, -1, -5 },
- {-17,-18, -3, 22, -8, 1, 9, -2,-17, 20, -5, -5,-12, -5, 4, -5,
- -9, 8, -2, 16, -3, 0, 19, -8, 8, 1, 2, -4, 0, 11, 0, -3 },
- { -9,-23, 3, 10, 4, 4, -3, -2, -2, -2, 1,-22, 11, 0, -2, 5,
- -2, 14, -9,-11, -4, 7, 5, 32, 1, -3, -7, 0, 21, -9, 7, -6 },
- { 0, 0, 0, 2, -1, 1, 0, 1, 3, 0, 0, 1, 0, 1, 0, 1,
- -3, 0, -1, -2, 0, -1, -1, -3, -1, 1, -4, 1, -1, -5,-69,-19 },
- { -3, -5, -8,-12, 4, -3,-19,-11, -5, 0,-14, 7, 18, -6, 7, 22,
- 8, 14, 15, 10, 3, -1, -3, 5, -1, 7, -7, 1, -6, 3,-26,-11 },
- { -1, -6, 4, -4, -5,-16, 0, -6, -3, 11, 1, 0, 9, 5, 16, 3,
- -4,-33, -4, 4, -7, 0, 1, 6,-11, -2,-13, -2,-18, 20,-25,-16 },
- { 4, 0, -1, 0, -5, 1, 0, 2, 0, 11,-10, 4,-10, 7, 16, 2,
- 16, 15, 2, -1, 2, 9, 2, 8, -3, -5, -2, 0, -3, 0,-33, -2 },
- { -3,-15, 10, 10, -9, -1, 7, 3, 5, -5, -8, -8, -3, 15, -9, 4,
- 12, 13,-13,-14, 10, -6, 9, 22,-27, 23, -1, 5,-24, 2,-30, 5 },
- { 0, -2, 7, -5, -5, 3, 5, 3, -3, -5, 2, 1, -4, 3, -3, -1,
- 1, -2, 10, 22, -3, -4, -2, -2, -7, 3, 8, 1, 14, 4,-37, 9 },
- { -3, -4, -1, 1, -4, 0, 6, 2, 6, -7,-10,-10, -1, -4, 11, -3,
- 7, -6, 4,-12, -1, 5, 1, -7, 10, -6, 17, -4, 8, 3,-40, 13 },
- { 2, 12, 4, -7, 14, -3, 16, -2, 18, 2, 13, 5, 5, 1, 11, -1,
- 0, 9, 2, -6, -1, 2, -6, 2, -5, 3, 5, 1, -1, 1,-32, -7 },
- {-16, 11, 7, -4, 2, -5, -9, 9, 11, 11, 15,-13,-11, 11, 9, 4,
- 3, -8,-10, 12, 12, 0, 0,-16, -9, 13, 2, 9, 4,-13,-33, 3 },
- { 6, 4, 5, 4, 3, -1, 5, 6, 4, 2,-11, -1,-15,-11, -1, 1,
- 11, -3, -2, 24, -4, -6,-25,-10,-15, -8, 0, 0, -5, 4,-30, 2 },
- { 10, -3, -6, 1, -9, -5, 6, 9,-10, -3, 8, -1, 4, -1, 11,-11,
- 3, 9, 11, -3, 6,-17, 5, -8,-33, 9,-13, 19, -2, 9,-25, 2 },
- { 0, 0, -1, -3, 0, -2, 1, 0, 0, 2, 1, 0, -2, 0, -1, 2,
- 0, -1, 4, -1, 2, -3, 4, -2, 3, 3, 1, 0,-15, 12,-63, 27 },
- { -2, 14, 9, -1, 3, 0, 1, 1,-19, 15, 3, 4, 0,-10, 1, -5,
- 3, 0, -5,-10, 2,-16, -4, 8,-12, -6, 7, -5,-10, -1,-33, -4 },
- { 0, 3, 1, 3, 1, 2, 4, 4, 9, -6, -8, -5, 1,-12, 3, 8,
- -10, 6, -1, 1, 13, -5, -5, 2, -4, 13,-18,-10, -7, -9,-33, 10 },
- { -6, -3,-12, 5, -1, 11, -6, 0, -2, 1, 2, -7, 3, 1, 3, -2,
- 1, 8,-10, 7, -1, -3, 3, 0, 13, 1, 6, 7,-16, -7,-39, 8 },
- { -6, -1, 11, 6, -3, 8, 3, -5, 3, 0, -5, -2, -6, -3, -4, 2,
- -3, 13,-11, 1, 7, 5, 19, -5, -3,-15, -1, 7, -1, 6,-33, 8 },
- { -7, 3, -4, -3, -4, 1, 6, -5, -5, 6, -8, -1, -7, 4, -1, -6,
- -2, 1, 7, 0, 1, 1, -5, 2, -2, 0,-13, -2,-31,-14,-39,-12 },
- {-10, 9, 0, -3, 1, -1, -1, 0, 1, -5, -1, -4, -2, 5, 2, -7,
- 18, -8, -2,-19, -7, -7,-12,-14,-11, -1, -9,-13, -7,-12,-31, -9 },
- { -3,-16, 10, 9, 1,-10,-12, 2, -2, 2, 7, -3, -3, 1, -4, -5,
- -9, 5, 7, 3, -1, 4,-11, -8, 4, 13,-10, 13, 10, -4,-36, 1 },
- { -7,-12, 4,-20, -7, -7, 2, 11, -1, -2, 3,-12, 1, 0, -6, -7,
- 6, 4, 13, 3, -3, 4, 3, -6,-12, 5, -5,-22,-13, -8,-37, -6 },
- { -7, 5, 3, 5, 7, 9,-14, -3, 10, 17, -1, 1,-12, 5, -6, 0,
- -4, -9, 0,-11,-14, 3, 13, 6,-25, -8,-12, 4,-10, 18,-30, -1 },
- {-10, 6,-10, 6, 6, 1,-10, 0, -7, 5, -2, 17,-18, -4, 0, -3,
- -16, -6, -3, -8, 5, 1, -4, 6, -7, 16, 6, 10, -1, 0,-32,-11 },
- { -1, 9, 9, -5, 4, 9, 6, 9, -4, -2, 7, 11, 4, 2, -5, -4,
- -6, 0, 2, -3, -1, 5, 10, 0, 12,-10,-18, -3, -1, 14,-33, 2 },
- { 4, -8,-18, -4, -5,-11, 4,-10, -4, 9, 13,-12, 1, -6, 1, 2,
- 4, -9, 8, 3, -6, 21, 13, -1, -2, 1, -2, 6, -7, 0,-30, 1 },
- { 6, -1, 2, -3, -1, -4, 6, -4, 0, 4, 2, 2, -9, 2, 6, 3,
- -2, 4, -1, 9, -6, 0, 7, -8, 5, 19, -2, 9, -5, 2,-33, -8 },
- { 2, 1, 12, -5, -8, 8, 3, -2, -4, 1, -2, 5, -4, -9, -8, -8,
- 7,-11, -4, 6,-10, 7, -1, -1, -2, -1, 16, 32, -7, 20,-33, -6 },
- {-18, 2, 6, 13, 9, 9, -1, 3,-17, 24, -2, -6, 28, 8, -2, 6,
- 3,-10,-34,-16,-13, -4,-15,-11,-12, -3,-10, 4, -8, 4,-31, -4 },
- {-11, 0, 18, 2,-16, -9,-13, -2, -2,-12, -3,-22, 30, 0, 8, 3,
- 9, -4,-16, 1, 0,-11, 15, -2, -4, 6, -5, 6, 1, 2,-25,-12 },
- { 14, -1, 5, 7, 3,-15, -8, 1, 5, -2, 12, 13, 11,-25, 3, 1,
- 0, -2, -4,-16,-23, 0, -5,-17, 7, 5, -9, 6, -5, 2,-32, -7 },
- { 3, -1, 6, 14, 2,-12, -9, -9, 4, 7, 4, 6, 5, -8, 4, 2,
- 4, 5, -2, 8, 8, -6, 0, 10,-20, -1, 3, -1, 8, 23,-33, -5 },
- { -3, 11, -6, 3, -4, 5, 7, 3, 4, 5, -2, 3, -1, 30, 6, 1,
- 8, -6, 0, 0, -9, 6, -9, 4, 2, 9, -6, 1,-12, 0,-34, 18 },
- {-17, 13, 0, 1, 9, -4,-11, 0, 7, 0,-10, -4, -1, 6, -6, 4,
- 1, 6, -9, 3, -5, -6,-11, 2, -4, 14, 23, -3, 2, 5,-30, 12 },
- {-14, 5,-27, 2, 0, 7, 1, 4, 30, 8, 7, 5, 1, -1, 0, 5,
- 8,-10, 48,-11, 12, 33, 6, 8,-15, 20, -2, -5, 32, 5,-19, 10 },
- {-16, -4,-12, -7, -2, 0, 8, -6,-20,-18, 16, -3, 0, 31, -2, 11,
- 2, -9, 49,-19,-12,-23, 10, 26, 16, -2, 4,-21,-14, 13,-11, -9 },
- { -5, -9, -1, 3, -5,-21, 2, 10, 0, 0, 10,-21, -7, 7,-26, -9,
- 22, 32, 58, 11, -3, 11, -5, -8,-13, 6, -5, -9, 1, 10, 14, -8 },
- { 7, 7, 10, 3, -2, -1,-11,-11, -6,-43, -3, 14,-19,-18, 19, 18,
- -32, 10, 45, -6, 6, 21,-20,-12, 2, 4, 6, 6, -4, 3, 3, 1 },
- { 21, 22, -3, -2,-11, -6, -1, -2, 8, 8, 32,-21, 7, 28, -4, -6,
- -3, -2, 50, 2, 2, 27, -5, -8, 12, 7, -5, -1, -4,-17, 27, 6 },
- { 13, 7, 2, -6,-12, 2,-10, -5,-17, 11, 4, 17,-12, -2, 5,-17,
- 37,-16, 48,-14,-18, 29, 8, 24, 11, -5, -9, 11, -1, 1,-13, -3 },
- { 1, 1, -1, 2, 0, 0, 0, -1, 1, -1, 7, 2, -3, 3, 0, 6,
- 2, 10, 54,-25, 7, 54, -5, -6, -1,-15, 9, 13,-24,-15,-12, 3 },
- { 21, 5, 8, 3, -3, -4, -2, -4, 3,-11, -5, -8, 9, 16, 8, -9,
- -10, -3, 46,-46, 2, 1,-10, 10, 17, 11,-20,-36, 10, 14, 0, -5 },
- { 7,-13, -6, -9,-24, 45, 2, 8, 8, 0, 17, 20, 12,-24, 1, -7,
- -15, -3, 46,-13, -2, 20, 1,-13,-11,-13, 2, 15, 1, 10, -1, 3 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, -2, -1,
- -16, -9, 31,-69,-34, 26, 7, 17, -1, -6, -1, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -4,
- -5,-20, 18,-82, 22, 3, -7, 9, 4, 6, 2, -4, -1, 0, -2, 2 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, -1,
- 15, -5, 62,-36, 4, 52, -7, 5, 0, 6, 1, 2, 1, 1, -1, 0 },
- { 3,-19, 19,-20, 13, -4,-11, 8, 8,-16, 10, 1,-14, 30, 1,-33,
- 10,-11, 45,-30, 3, -4, -3,-13, 7, 12, 3,-22, 3, -2, -4, -2 },
- { -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 1,
- 11, 8, 70, 48,-10, 21, 4, 9, -9, -9, -4, -6, 0, -1, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0,
- 2, -1, 80, 2,-15,-36,-10, -5, -2, 8, -2, 2, 0, 0, 0, 0 },
- { 10, 8, -8, -8,-24, 12, -1, 0, 20, 9, -1, -2, 2, -2, 12,-10,
- -2,-13, 35,-43, 44, 15,-10,-25, 4, 10, -3, -5, -5, 7, -1, 3 },
- { 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, -2, -1,
- -18, 9, 49,-72, 7, -8, 7, -5, 2, 3, 2, -2, 1, -2, -3, 1 },
- { -1, 4, -3, 10, 19, 4, 3, 20, 6,-24, 6, 9, 8, 15, 18, 18,
- -36, 19, 57,-11, 4, -3, 8, 7, 2, -3, -2, -9,-15, -2, 12, -4 },
- { 20, 3, 11, -9, -4, 22, 42,-25, 1, 5,-10,-19, 0, 9,-16, 5,
- 2, 10, 44,-29, 17, -3, -9, -2, -1, 8, 14, -7, -1, 16, -5, 1 },
- { -7, 16,-11, 12, 6, 33,-15, 14,-23, 2,-26, 8, 2, 10, 0, -5,
- 8, -8, 38,-38, -4, 5, 5, 5, 1, 22,-15, 7, 6, 0, 4, 28 },
- { -1,-12, 2, 10, -2, 0, 7, 17, 12, 22, -4, 10, 25, 29, 5, 18,
- 4, 1, 27,-39, 31, 17, 2, 2, 22,-23, 13, 16, 1, -7, -4, -5 },
- { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, -2, 0,-14, 0,
- -7,-11, 49,-22, -4, 19, 17,-39, 4,-29, 10, 2, 36, -4, 23, -1 },
- { -2, -2, -2, -2, 1, 15, -5, -7,-16, -8,-19, 16, -3,-20, 36, -9,
- -3, 20, 39,-20, 0, 2, 27,-16, 10, 10,-14,-22,-16, -3, 13, -8 },
- { 5, -9, 6,-25, 7, 37, 13,-10, -5, 3, -5, 7, 18,-22, -7, 9,
- -5, -4, 50,-11, -4, -5, -5, 8, -4, -2, -4,-27, 14, 20, 7, -9 },
- { 0,-14,-10,-27,-14,-17, -6, 26, 10, 2, 14,-12, -5, 0, 8, 9,
- 0,-28, 55, -7,-12, -7, 4,-10, 10, 7,-12, 11, 3, 5, 9, -8 },
- { 2, 23, 4, -2, -1,-20, -2, 14, 10, -9, -9,-24, 10, 0, 11,-12,
- 12, 11, 49,-25, -2, 29, 7,-13, 21,-10, 11,-17, 3, 1, -8, 5 },
- { 3, 0,-14, -6, 18, -2, 17, -9,-19, 9, -5, 9, 14, 6, 19, -3,
- 27, 1, 41,-21, 20,-15, 33, 0, 26, 14, 7, 10, 3, 20, -3,-12 },
- { -1, 16, 15, -8, 3, -8, -8, 21, -5,-16,-29, 4, 1, -6, -4,-28,
- 2, 31, 37,-26, -2, 13, 24, 8, -9, -6,-29, 10, 7, 2, 7, 8 },
- {-10,-10, 11, 13,-32, 2, 16, 9, 14, 23,-15,-13, 24, 13, 4,-27,
- 14, 12, 31,-18, 17, 23, -2, -7,-14, 9,-17, -6,-10, 20, 9, 6 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0,
- 5, 1, 89, 8, 10, -6, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, -1,
- 4, -7, 64,-50, 7, 37, 2, 5, 0, 0, 0, 0, 0, 0, 0, 0 },
- { -2, 5, 3, -4, -4, -3, 2, -3, 3, -3, 5, 4, 1, -6, -1, 1,
- 6, -2, 50,-35, -7, 43, 7, -7, -5,-26, 24, 21, 3,-15, 5, 6 },
- { -8, 21,-19, 33, -8, 22,-11, 17, 3, 0, 0, -2, 1, -3, 6, -1,
- 10, -8, 4,-11, -4, -5, 0, 8, -4, 3, 1, -4, 4, 2, 8, 4 },
- { -7, 5,-20, 9,-22, 3,-14, 1, 6, 13, 23, -2, -4, -7, 2, 0,
- 11, 4, 6, 3, -7,-11, -7, 4, 5, 5,-12, 8, 2, 4, 7, -3 },
- { -7, 6, -4, 20,-20, 16, -2, 7, 6, 16, 11, 12, -7, -7, 5, 3,
- -9, -4, 1, 2, 5, 2, 1, -9, -2,-17, -4, 6,-10, 7, -7, -6 },
- { -9, 18,-17, 12,-24, 1, -1, 4, 14, 9, 4, 3, 2, 8,-12,-14,
- 4, -8, -4, 7, 7, 6, -1, 13, -9, -4, -1, 1, 0, -4, 15, 8 },
- {-25, 2,-11, 6, -5, 24,-28, -5, 8, 12, -2, 6, 8, -3, 8, -9,
- -1, -5, -1, -5, 6, -1, -1, -1, -4, 8,-12, -2,-13, 7, 2, 1 },
- {-14, 14,-18, 20,-10, 12, -2, 9, 1, 0, 12, -2, 15,-10, 26,-17,
- 16,-11, 10,-10, 9, -2, 4, -8, 2, -3, 4, 4, 2, -3, -5, 1 },
- {-18, 12,-18, 21, -6, 12, -6, 13,-25, 18, 1, 11, -9, -5, 0, 10,
- -5, 3, -3, 8, -9, 7, 4, 2, -9, 0, 5, 0, 2, -3, 9, -8 },
- { -4, 16, 1, 18,-30, 9, 1, 6, -8, 13, 13,-12, -6, -1, 13, 7,
- 6, 2,-15, -3, 5, 5, 1, -6, 1, -5, 0, 2,-16, 0, 3, -4 },
- {-21, 1, -2, 6,-43, 18, -1, 5, -1, 4, 6, -2, -1, -3, -1, -3,
- 0, 1, 2, -9, 0, -1, 0, -2, 0, -1, -1, -2, 6, 0, 1, -2 },
- {-23, 10, 4, 7,-32,-11,-18, 2, -2, -7, -6, -3, -3,-12, 19, 3,
- -5, -6, 16, -6, 16, 2, 16, 16, 8, -2, 13, 8,-15,-11, 2, 10 },
- { -8, 2,-13, 2,-29, 24,-20, 19, 1, 10, -4, 10, 1, 2, -9, 11,
- -1, -2, 9, -5, 19, -7, 16, -9, -2,-18, 11, 1, 1, 0, 7, -3 },
- { -6, 3, 4, 13,-26, 10,-10, 28, -7, 28, 1, 7, 0,-14, 5, 7,
- 4, -4, 3, -2, 3, 3,-11, 7, 6, 4, 0, -1, 2, -1, -3, 2 },
- { -6, 16,-31, 13,-10, 17, -6, 4,-14, 4, 4, -1,-10, 12, -5, 1,
- -14, 15, 0, -8, 1, -5, 3, 3, 9, -5, 7,-20, 7, 4, 11, -5 },
- {-19, 3,-17, 14,-12, 16,-22, 18, 14, 8, -2, 4, 10, 12,-14, 4,
- -3, 2, 3, 7, -7, 7, -6, 2, -2, -4, -5, 0, -5, -2, 2, 1 },
- { -9, -7,-11, 24,-36, -9,-11, 5, 7,-12,-13, 18, -2, 20, 1, -4,
- -1,-10, 15, -6, 14, 1, 0, 2, 1, 2, -9,-16,-11, 7, 13, 0 },
- {-24, 24,-18, 18,-22, 14,-11, 13,-12, 11,-10, 11, -7, 11, -5, -4,
- -1, 1, 5, 2, 3, -1, 1, -5, 7, -4, 5, -6, 8, -7, 8, -6 },
- { -6, 18,-22, 22, 5, 11, -1, 6, 19, 22, 8, 4, -8, 20, -2, 15,
- -6,-18, 0,-33, -9,-12, -1, 6, 5, 2, 5, 5, -5,-17, -3, -3 },
- { 1, 11,-16, 9,-18, 11, -4, 18, 20, 26,-10, 8, 1,-11, 8, -4,
- 0, 7, 3, 5, 2, 2, 10, -2, -4, 4, -4, -2, 1, -4, -5, -1 },
- {-10, 6, -1, 18,-17, 27, -3, 10, -2, 12, -7, -9, 1, 1, -1, 7,
- -12, -1, -7, -6, -1, 8, 3,-15, 8, 9, 3, -7, 4, -1, 1, -1 },
- {-14, 6,-16, 22, 2, 5, 0, 5,-18, 11, 6, -3, 22,-20, -9, -3,
- 6, -6, -7,-15, 1, 15, -8, 11, 8, -3, -8, 1, -8, 2, 6, -2 },
- {-21, 5,-19, 19, -7, 4, -7, 0, -8, 6, 12, 5, -3,-22,-13, -6,
- -1, -3, -2,-14, 6, -3, 1, -8, -7, -5, -6, 11, -3,-10, -5, 2 },
- { -1, 9,-12, 15, -6, 6,-19, 14, -9, 11, 3, 12,-17, -3, 8, -4,
- -3, -4, 1, -5, 4, 5, -7,-15, -7, 15, -6, -5, 1, -5, -3, 1 },
- {-12, 20,-15, 20,-14, 3,-14, 9, -6, 33,-13, 6, -2, 8, -6, 7,
- -5, -6, -3, -3, 0, 8, -3, -3, 1, -2, 2, 2, 6, -5, -5, -2 },
- { -7, 12,-18, 12,-18, 10, -4, 8, 2, 4, 8, 9, 0, 3, -8, 3,
- 6,-12, -4, 1, 25, -5, -9, 6, -7, 0, -9, -7, 3, -5, -4, -4 },
- {-18, 12,-10, 11,-22, 0,-15, 5, -2, 2, -3, 6, -4, -4, -3,-15,
- -2, -3, 21, 6,-12,-11, 19, 3, 3,-14, 7, 0,-11,-22,-10, 0 },
- {-15, 2,-30, 15,-17, 13,-16, 8, -7, 10, -8, 2, 11, 3, 10, -7,
- 7,-22, 12,-10, 3,-12, 6,-10, 12,-10, 7, -8, 5, 2, 9, 1 },
- { -9, 11,-14, 6,-10, 21, 5, 12, -5, 5, 7, 21, 6, 2, -2, -1,
- -1, 4, 2,-20,-18, -1,-14, 3, -1, 4, -7, 10, 1, 11, 4, -4 },
- {-22, 8,-30, 13,-21, -4, 4, -1, 12, 9, -2, -3, 2, -6, 4,-13,
- -2, 8, 8, 1, -7, 3, -4, -5, -1, -7, -2, 8, 8, 7, 8, 0 },
- { -6, -4,-35, 16,-13, 15,-11, 14, -7, 9, -1, 11, 7, 0, 13, 10,
- -1, 8, 1, 1, -2, 8, -1, 2, 2, 3,-10, -1, 7,-13, -3, -7 },
- {-15, 7,-16, 14,-18, 17, -6, 14, 3, 4, 7, -3, 10,-22, 5,-15,
- 4, -4,-11, 15,-15, 11,-11, 20, 1, 0, 2, 1, 11, -3, 11, -7 },
- {-12, 3, 5, 16,-37, -1, 15, 15,-15, 10, 3,-10, 1, 15, 7,-15,
- -13, 8, 9, -3, 2, 12, -8, 2, -5, 0, -3, 4, 5, -9, -4, 5 },
- {-16, 26, -4, 14,-22, 26, 6, -3, -8, 4, 21, 6, 16, -4,-11, 7,
- -10, 3, 3, 7, -4, 2, -9, 8, -2, 2, 5, -2, -4, -2, 7, -1 },
- { -7,-10, 4, 3, 2, -4,-12,-10, -4, -5, 16, 19,-16, 1, 2, -9,
- -10, 0, 9, 7, -8, 3, 12, 8, -6,-11,-13, -1, -3,-20, 6, -5 },
- {-14,-17, 3, -5, 14,-12,-12, 8, -6,-25, 21, 21, 10, -8,-12, 4,
- 10, -4, 3, -9, 11, 9, 0, 4, 2,-15, 1,-14, 4, 1, 0, -4 },
- { -4, -9, -3, -1, 6, 3, -6, 6,-10, -4, 14, 8, 2, -3,-12,-19,
- 0, 11,-20, 1, 6, -2,-27, -6, 10,-17,-14,-17, -9, 8, -8, 3 },
- {-12,-13, 16, -4, -2, 12, -7,-11, 2,-13, 3, 7,-16,-18, -1,-12,
- -2, 1,-12, -9, -2, -6, 2, 9,-22, -3, -4,-14, -7, 7, -1, 2 },
- { -7, -8, -8, 15, 15, 18, 15, 16, -4,-37, 11, 15,-12, -1, -3, 3,
- 6, 6, 0, -5, -3, -5, 9, 1, 1,-11, -1, -8, -6, 2, 3, 0 },
- { -6, 7, -5,-12, 13, 10,-18, -4, -3,-21, 6, 16,-15, -7,-12, -9,
- 1,-12, -1, 10, -2, -1, -3, 4, -4, 1,-16, -1, 12, -9, 5, 9 },
- {-14, -5, 9, 3, 4, 26,-28, 3, -6,-24, 4, 5, 3, 13, 5, -1,
- 3, -1, 3, 1, 1, -5, 3, 0, -7, -8, -7, -3, 3, -5, 4, 0 },
- { -4, 2,-10, -6, 25, 26, -6, 10, -6, -8, 15, 11, -6, -3, 2, -7,
- 5, 14, 9, -1, 0,-12, 4, -4,-10, 1, -3, 3, -2, -2, -6, -1 },
- {-10, 8,-15,-10, 19, 17, -8, 0, -3, -7, 7, 5,-13, -1, 7, -7,
- 1, 13,-12,-13, 17,-12, 1, 26,-18, -3, -5, -6, 4, 5, 8, 1 },
- { 2, -5, 3, 0, 0, 0, 2, -3, -2, -5, 7, 13, -4, 9, 0, -5,
- 4, -1,-11, -8, -4, 0,-13, 2,-47,-23, -8,-11, -4, 4, -2, -3 },
- {-18, -4, 4, 5, -1, 17,-12, -8, 1,-12, 7, 20,-12, 3, -2,-11,
- 16, 12, -6, 1,-13,-16, -6, -3, -3, -5, 4,-12, -5, -9, 10, 1 },
- {-11, 0, 4, 7, 7, 8, 3, -1, 3,-19, 32, 8,-19, -8, 2, 4,
- -12, 15,-16, 3, 1, 9, -2, 1, -2, 8, 5, 6, -4, -1, 11, -8 },
- { 3, -1, 4, -2, 14, 32, -9,-23,-10,-12, 22, 15, -1, -2, 10, 0,
- 4, 6, -8, 4,-15, -2, -1, -4, 0, -8, 4, 1, -8, 3, 4, 1 },
- {-17,-12, 6, -8, 16, 13,-20, -8, -1,-16, 10, 21,-19, 11, -9, -5,
- 7, 18, -6, 7, -7,-18, 13, 2, -2, 8,-12, -9, 2, 4, -5, 16 },
- { 4, 0, 17,-11, 12, 7,-12, 5, -1,-25, 30, -8, -7, -6, -4, -7,
- 9, 8, 7, 3, 3,-16, 8, 0, -2, -2,-18, -3, -4, -5, 1, 4 },
- { -3, -6, 6,-16, 17, 6, -3, 2, -9,-17, 12, 11, 11, 2,-20, 8,
- 1, 1, 0, 2, -2, -6,-21,-13, -9,-15, -1, -8, -6, -8, 0, -2 },
- {-11, -7, 6, -9, 3, 6, 8, 16, 4, -5, 23, 26,-10, -3, 4, 0,
- 2, 2, -4, 4, -2,-12, 12, 10,-11, 0,-10,-16, 3, 0, 0,-10 },
- { -5,-16, 10, -6, 27, 13, -3, 4, -2,-13, 15, 5, 2, 5, 3, -4,
- 13, 12,-11, -7, 0, 1, 11, 12, 2, 13,-15, -8, 9, -2, 3, 8 },
- { -5, -8, 4, 3, 9, 3,-11, 10, 14,-25, 14, 8, -2, 5,-12,-21,
- 2, 10, -7, 2, -3, 2, 0, 2, -1, -3, -5, -6, -1,-16, 2, 8 },
- { -1, 5, 1,-11, 5, 9, -7, 8,-13,-12, 4, 12, -4, 1, -1, -1,
- 27, 29, 10, 15, 2, -6, -3, 4,-21, 10, -9,-11, -6, -1, -9, -3 },
- { -6, -3, -1, -6, 11, -5, 0, -2, -5,-31, 11, 3, -1, 5, -3, 4,
- 5, 7,-10, 5,-10,-13, 4, 12,-15, -2, 2, -7, 1, -9, -3,-10 },
- { -3, -7, 17, -8, -5, 36, 8, -7, -8,-20, 12, 8, 1, -1, 3, 0,
- 1, 4,-10, 3, 1, 4, -2, -3, -2, -3,-10, 4, -1, -7, 3, 2 },
- {-13, -3, -5, 9, 22, 6,-23, 3,-10, -7, 17, 17, 18,-14, -8, -8,
- 2, 4, -8, 2, -3, -8, 6, 4, -1, 7, 0, 0, -3, 0,-12, -3 },
- { -3,-10,-15, -3, 9, 3,-23, -9,-13,-18, 12, 13, -2, 0, 1, 8,
- -1, 2, -7,-12, -5, 14, 2, 1,-22, 6,-10, -8, -9, 28, -7,-14 },
- { -3, 1, 2, -1, 13, 7, -2, -7, 1, -3, 6, 9, -3, -2, 4, -2,
- 2, 1,-10, -2, -2,-22, -2, -7,-10, -5,-11,-27,-12,-16, 4, -7 },
- { 2, -6, -3, 1, 8, 0, -2, 12, -3, -4, 58, 15,-10, -4, -2, 2,
- -2, 0, -2, -6, 2, 4, -1, 1, -4, 1, -1, -5, -4, -3, 3, 1 },
- { 10, -1, 0, 5, 21, 7,-14, 6, -3,-16, 15, 17,-16, 13, 3, -6,
- -4, 6,-12, -5, 1, -4, -7, -8, 2, 3, -6, 6, -1, -8, 5, 4 },
- { -6, -2, -8,-11, 15, 10, 0, 8, -6,-15, 33, 8, -2, 18,-15,-11,
- 5, -1, 0, 15,-15, -4, -4, -1, 10, 7,-13, 4, -4, 0, 8, 3 },
- { -7, -2, 0, -2, 0, -2, -4, -5,-14,-16, 12, 38, 7, 12, 6, -4,
- 0, -1, 0, 3, -2, -6, 0, 2, -9, 1, 0, -1, 0, -2, 4, 1 },
- { -8, -4, 18, 1, 14, 5,-12, -3, 20,-17, 5, 19,-11, -8, 11, -3,
- 3, 9, -7, -8, 9,-17, 2, 15,-10,-11, 5, -5, 7, 15, -6, -2 },
- { -7, 2, 38, 5, 19, 16, -5, 4,-13,-20, 0, 4, -4, 6, 4, 2,
- -7, 6, -8, -2, -5, -7, 6, 3, -4, -3, -2, -3, 7, -6, -4, 0 },
- {-11,-12, 8,-15, -3, 14, -7,-22,-11, 2, 22, 14,-19, 2,-19, -6,
- 1, 3,-18, 14, 2, -6, -2, -8, -3, -6, 5, -7, -8, -4, 1, 1 },
- { 8, 7, 25,-21, 12, -6, -5, -4,-10, 6, 0, 10, 1,-12, 18, -5,
- -15, 4, 1, 14, -1, 5, 8, -7, 1, -7, -3, 9, 10, 1, -1, 0 },
- { 9, 10, 32,-15, 8, 2, 11, -7,-18, -8, 2, -6, -9,-16, -3, 3,
- -1, 3, 1, -5, 4, -2, 1, -8, 0, -6, -3,-11, 1, 5, 0, 0 },
- { 14, 0, 23,-25, 22, 3, 7, 10, 0, -2, 7, 8, 0, 10, 0, 0,
- 3, 2, 3,-10, 0, 10, 0, -7, 0, 10, -1, -5, -7, 1, -1, 2 },
- { 12, 0, 25,-18, -5, -4, 13,-10, 3, -6, 7, 21, 0,-16, 3,-10,
- -6, 5, -7, -3, 2, 5, 3, -6, 4, 9, -8, 12, -2, 3, 2, 4 },
- { 31, 15, 27,-20, 10, -7, 15,-10, 9, -8, 4, -5, 3, -3, 5, 6,
- 11, -2,-12, -2, 6, -2, 1, 2, -1, -1, 1, 1, 3, 1, 1, 2 },
- { 12, -4, 13,-23, 12, -6, 2, 4, -3, 13, 6, -7, 5,-19, -7, 18,
- 1, -7, 7, 1, 16, -7, 3, 0, 3, 0,-12, 8,-11, 9, 4, 7 },
- { 29, 1, 3,-22, -5, 6, 0, 12,-14, 11, 1, 6, -3, 4, 6, -2,
- 4,-13, 12, 1, 1, 3,-11, 9,-10, -1, -7, 16,-11, -1, 3, 9 },
- { 4, 4, 36,-23, -5, -8,-15, 1, -6, 3, 13, -1, -5, -7, 4, 9,
- 2,-11, -3, 5, 1, 3, -6, -1, -4, -4, -2, 2, 3, -1, -5, -2 },
- { 19, 10, 6,-17, 2, -4, -2, -4, -3, 13, 2, 2,-13, -7, -3,-11,
- 9, -6, 1, -9, -5, 4, -5, -9,-18, -7,-11, 9, 4,-11, 8, 4 },
- { 16, -3, 9,-16, 18, -2,-12,-16,-11, 11,-18, 16,-13, 6, 2, 8,
- 3, 8, -4,-16, 10,-11, -1, -3, -8, 5, -9, -4, 9, -4, 0, -3 },
- { 14, 15, 3,-23, -5, 7, -8, -6, 2, 17, 2, 12, -8,-12, 13, -1,
- -9, 3, 1, 1, 19, 15, 4, -1, 1, 2, -3, 2, -3, 1, 5, 3 },
- { 32, 5,-10,-47, -5, -1, 4, 11, -7, 0, 2, -2, 1, -7, 6, -4,
- 6, 2, -4, -2, 2, -2, 0, -4, 1, -6, -5, 2, -2, -1, -3, -4 },
- { 20, 8, 10,-21, -7, -9,-16, 12, 1, 4, 6, -5, 9,-11, -7, 4,
- -11, 28, -3, 2, 4, -6, 10, -8, -5, -5, -9, 9, -2, -1, 6, -5 },
- { 38, 3, 23,-25, -6,-18, 3,-10, -8, 6,-10, 1,-10, 2, 2, 0,
- -7, 2, -4, 5, -1, 8, -3, 0, 3, 3, -1, 1, 0, -4, -4, 0 },
- { 20, 5, 16,-22, 24,-18, 2,-12,-14, -7, -3, 10, 2, 7,-10, 2,
- -8, 1, 8, -1, 4, 1, 4, -2, 5, -9,-18, -8,-13, 5,-11, 10 },
- { 14, 8,-12,-16, 9,-11, -3, -6,-25, -7, 6, 5, -7,-16, 10, 2,
- -7, -1, -9, -3, 16, 4, 3, 3, -3, -3,-15, 13, -3, 4, 13, -7 },
- { 16, -9, 19,-23, 7,-19, -3, -5,-15, 11,-21, 21,-16, 18, -1, 6,
- 10,-10, 18,-14, 16,-15, 6, -5, -9, 5,-17, 13,-10, 13, 0, 10 },
- { 8, -4, 4,-24, 8,-21,-18, 9,-11, 4, -6, 17, 5, -9, -2, -2,
- 2, 15, -2, -3, -2, 1, 7,-13, 15,-10, -8,-11, 3, 3, -1, -1 },
- { 14, 17, 6,-32, 5,-17, -2, 0, 15, -1, -5, 16, 1, -5, -2, 9,
- -3, 8, 4, -2, -2, -4, -3, 1, 0, 7, -3, 4, -5, 0, -7, 2 },
- { 24, 6, 22,-12, 8, 3,-14, 4, -7, 8, 6, 5, 6, 1, 6,-12,
- 15, 10, 4, 11, 9, 6, -7, -4, 10, -9, 2, -1, -5, 11, 15, 3 },
- { 17, 12, 3,-23, 5, -1, -2, 1, -9, -1, -3, 1, 8, 1, -5, 17,
- 11, 0, -2,-11, 7, 4, 0,-27, -7, 1, 2, -8, 9, 7, 5, 3 },
- { 12, 10, 12,-10, -4, 5, -1, 2,-24, 5, -8, 2, 6,-17, 19, 5,
- 12, -2, 16, -7, -6,-14, 4, 1, -3, 13,-16, 5, -1, 4, 1, 1 },
- { 31, 9, 11,-17, 10, -3, -7, 7, 1, 2, 2, 4, -3, -1, 11, 4,
- -5, -8, 1, 4, 15, -6,-28, 1, 8, 3, -6, 5, 17, -2, 2, -4 },
- { 11, 19, 16,-26, 0, -7, -7, 2,-13,-15,-12, 9, -3, 27, 8, 4,
- -6, 1, 4, -6, 11, -1, -6, -7, -3, 0, -6, 4, -6, -7, -3, -1 },
- { 10, 18, 16,-32, 19, -9, -4, -3, -7, 8, 8, -3,-11, -2, -6,-16,
- 13, 13, -6, -1, 10, -2, -2, -9, 0, -3, 9, 4, 11, -2, -6, 6 },
- { 9, 4, 19,-33, 4, 7,-12, 36, -3, -1, 8, -2, 2, -8, -9, -4,
- -8, 0, 1, -1, 0, -4, -4, 3, 0, 3, 6, 0, -6, 2, 0, -2 },
- { 25, 7, 15,-12, 2,-24, -1, 24, -4, 4, 9, 0, -2, -9, 4, 6,
- 3, 13, -3, 1, 5, -1, -3, -5, -1, 7, -2, 3, 4, 4, 1, 0 },
- { 19, 6, 8,-20, 9, -9, 5, -4,-13, 7, 11, -3, 5,-13, -9, 6,
- -11, -1, 0, 4, 11, 26, 3, 6, -7, 12, 6, -3, 1, -9, 7, 1 },
- { 15, 6, 19,-23, -3, -9, 3, 16, -6, -4, 6, -5,-10, 1, 16,-14,
- 2, 0, 2,-13, -3, 8, -6, 3, 1, 1, 2, -5, 12, -4, -8, -3 },
- { 14, 4, 16,-20, 1, 12, 0, 6, -3, 9, 4, 16, 10,-16, 5, 7,
- 5, -4, -4,-18, -3,-11, -4, 4, -7, 3, 13, 7, 3, 3, 2, -7 },
- { 22, 3, -1,-30, 18, -3, -9, 9, -2, 11,-16, -2,-14, 12, 0, 4,
- -5, 4, -1, 3,-20, 12, 4,-10, -2, -2,-12,-12, 10, 6, 11, -3 },
- { 15, 7, 2,-21, 5, 4, 9, -9,-33, 7, 7, 3, -6,-14, -8, 10,
- 12, 0, 2, -1, 5, 4, -2, 0, -7, 0, 2, 4, 0, 1, -3, 8 },
- { -7, 0, 12, 3, 0, -6, 8, -4, 0, 2, 14,-15, 2, -7,-31, -3,
- 14, 0, 14,-15, -1, -4,-15, 10, 1, -3, 1, 2, 5, 2, -8, 1 },
- { -2, 5, 1, 0, -3, 3, 3, -6, -1, 2, -4, 1,-19, 0,-11, 18,
- 11, 10, 21, 5, 6, 2, 10, 3, -6, 0, -2, 13, 5, -1, -2, 9 },
- { -9, 1, -5, 0, 0,-15, 8, 4, 8, 3, 8, 12,-13, -2,-39, -2,
- 4, -4, 5, -3, -4, 3, -3, 3, 10, 5, 3, 2, -3, 5, -2, 8 },
- { -9, 6, 6, -8, 12,-12, 23,-18, 4,-15, -5, 2,-20, 13, -7, 7,
- 7,-12, 14,-12, 6, 1, 1, -3, -8, 9, 0, 1, -7, 3, 7, -6 },
- {-18, 13, 4, 3,-10,-30,-10, -6,-14, 1, -7, -4,-35, 5,-25, 11,
- 9, 8, 19, -4, -7, -3,-18, -8, 1, 5, 10, -4,-14, -9, 3, -4 },
- { -6, -1, 4, -9, -9, 4, 20, 0, 0, 3, 11, 7,-16,-17,-20, 11,
- -6,-14, 1, 4, 19, 2, -8, 6,-15, 3, 6, -5,-14, 3, 7, 2 },
- { 1, 6, -2, -8, -5, -3, 3, -8, 21, 1, 3, 16,-14, -2, -9, -4,
- 13, -2, 18, 14, 14, 19,-13, 5,-10, 2, -3, 3, 5, 5, 1, -1 },
- { -1, -5, -6, -2,-11, -7, 5, -4, 5, -1, 0, 3, -3, 2,-19, 18,
- 16, 4, 14,-22, -2,-11,-22, 1, -1, 11, 1, 2, 11,-10, 7,-12 },
- { 1, 4, 5, -1, -9, -5, 1, 12, 5, 6, 12, 9,-24, 23, 1, 20,
- 14,-11, 13, 5, -2, -2, 5, 6, 2, 1, -9, 6, 10, 5, -4, 11 },
- { -1, -1, 1, 7, -3, -4, 8,-16, 15, -1, -7, 9,-22,-11,-11, 10,
- 16, 9, -2, 4, 13, 10, 6, 16, 4, 7, 1, -8, -7,-14, -7, 4 },
- { 1, 3, -6, 0, 15, -9, -4, 0, 4, 6, 12, 9, -6, -5,-22, 17,
- 7,-11, 15, -5, 1, 3,-19, 0,-15, -3, 16, 5, 5, -7,-11, 12 },
- { -2, -1, 13, 2, 4,-24, 37, -5, -2, -6, 12, 7, -2,-23, -4, 9,
- 2, -3, 3, 2, 3, 3,-14, 11, 0, -4, -2, -2, 3, 10,-10, 4 },
- { 2, 9, 8, -6,-28, 14, 28,-11, 18,-11, 0, 2, -2, 4,-12, 3,
- 6, 0, 7, -7, -6, 2, 5, -1, -1, -1, 5, 2, 3, 0, -3, 9 },
- { -7, 14, 5,-10, -3, 7, 4, -5, 7, -8, -7, 4,-12, 14,-16, 25,
- 3, 0, 1, -5, 12,-10, 0,-10, 0, 12, 12, 17, 12, 10, -1, 0 },
- { -4, -2, 5, -2,-17, -3, 5, -5, 7,-17, 1, 5, -4, 4,-20, 0,
- 11,-15, 13, -8, 10, 1, 1, 5,-12, 9, -8, 0, 6, -1,-11, 4 },
- { -3, 12, 13,-15, -7, -7, 0, 5, 33, 3, 3, -6,-13, -7,-15, 10,
- 3, 3, 3, -5, 2, 7, -1, 0,-12, 2, 11, -6, -9, 0, 5, 11 },
- { -8, 5, 10, -7,-14, -4, 13, 0, 18, -3, -6, 7, 1, -6, 0, 21,
- 8, -7, 10, -8, -3, 17, -9, 0, -5, 1, 4, 8, -3, 11, -5, 0 },
- { -8, 8, -3, -8, 8,-11, 16,-16, 17, 0, 8, 16,-17, 10,-16, 10,
- -8, 6, 11, 0, 10, 7, 4, 5, 7, -5, -5, -6, -7, -5, -1, 16 },
- { -6, 0, 6, 1, -8, -8, 8, -7, -5,-10,-11, 8,-19, 6, -7, 13,
- 5, -3, 4, -8, 7, -1,-18, 9, 0, -5, 6, 26, 3, 8, 2, 4 },
- { -2, -2, 23, -2,-20, 2, 7, -7, -6,-15, 3, 9,-19, -2,-10, 7,
- -2, 7, 9, 11, 0, 4, -4, 6, 9, -2, 4, -3, 4, 3, 2, 8 },
- { -6, 12, 10,-10, -7, 4, 17, 11, -6, 1, 12, 11,-18, 8,-12, 4,
- 1, 13, 6,-13, 23, 9, -5, 8, -2, -5, 1, 3, 0, -2, -4, 4 },
- { 7, 1, 7,-17, -8, 8, -1, -7, 5, -6, 4, -3,-16, 9,-24, 18,
- -3, 10, 13,-11, -6,-11, -4, 10, 0, 11, 8, 2, 6, -5,-11, 4 },
- { -4, 1, -5,-10, 0, -3, 9, -2, 4, -1, 1, 5,-41,-10, -7, 4,
- -3, 3, 1, 0,-12, 4, -3, 0, 2, -1, -2, -5, 3, 2, -7, 5 },
- { -2, 1, 4, 4, -3, -6, 1, 0, 12, -5, 11, 0,-17, -3, -1, 11,
- 4, 1, 27,-12, 0,-14, 2,-15, -3, -9, 0, -7, -3, 15, -8, 6 },
- { -6, 4, 9, 2, 4, 3, 7,-10, 28, 1, -2, 48, 7, 0,-10, 10,
- 1, -9, 2, -1, 0, 3, -5, 5, -4, -2, 7, 7, 1, 3, 2, 5 },
- { -3, 3, -1, 3, -9, 0, -1, 3, 2, -6, 39,-14,-12, 5,-19, 21,
- 7, -6, 4, -1, -4, 0, -4, 1, 0, -9, 1, 10, 0, -2, 0, 7 },
- { 4, 2,-29, 12, 5, -3, 16, -6, 15,-13, -4, -1,-13, 22,-16, 17,
- 16, 4, 9, -4, 4, -6, -4, 11, -8, 7, 8, 4, 3, -3, -7,-13 },
- { 0, 3, 3, -6, -4, 0, 9, 0, 5, 0, 10, 10, 4,-13,-12, 16,
- 23, -4,-12, -6, -4, 20, 2, 0, -4, 23, 1, 8, 11, -4, -5, 15 },
- { -6, 4,-15, -9, -1,-19, 12,-30,-17, -4, 1,-13,-13, 4, -3, 26,
- 5,-25, 11,-14, -6,-13, 0, -7, 9, 2, 8, -1, -8, 1, -8, 13 },
- { 1, 6, 1, -4, -4, 1, 2, 0, -3, 2, 10, 6, -6, -2,-11, 4,
- 32, 15, 15,-47, -8, 3,-12, 4, -5, 4, -1, 0, -5, 5, 1, -7 },
- { 2, -1, 0, 0, -1, -6, 0, -6, 4, -4, 5, 9, -5, 1, -3, 51,
- 4, -5, 4,-14, -1, -4, -3, 1, -4, -1, 0, 2, -8, 0, 1, 2 },
- { 0, 4, -2, -7, -2, -9, 6, -8, 11, -3, -6, 3,-11, -8,-12, 8,
- 11, 5, 19, 3,-24, 19,-14, 11, -5,-18, -8,-12, -5, -4, -1, 4 },
- { 16, 9, 10, 14,-18, -2,-18,-27, 10, -5, 12, 14, 4, 0, -2, -6,
- -12, -7, -1, 3, 4, 7, 11, 10, 5, -5, -7,-16, -3, -6, 6, 9 },
- { 7, 15, -9, 10,-19, 4, -5,-37, -2, -4, 8, 2, 4, -1, 1, 9,
- -5, -5,-12, 1, -1, -8, 3, -3, 4, 6, 9, 3, 3, -1, 2, 4 },
- { 13, 17, 3, 9, -7, -7,-15,-17, -8,-13, -4, -8, 19, 2, 16, 25,
- 7, 15, 2, 16, -5, -6,-10, -9, -7, -6, -2, -7, 7, 2, 4, 5 },
- { 24, 7, 9, 8,-13, -2, 0, -4, 1,-13, 3, 6, 7, 10, -4, 15,
- 5, 7, -4, 5, -5, 3, 13, -7, 5, 15,-11, -2, 7, 5, 8, 6 },
- { 17, 6,-15, 23, -2, -1, -6, -2, 0, -4, 11, -3, 12, 15, 6, -8,
- -15, 10, -9, 7, -1,-11, 2, -8, -4, 3, 4,-10, 4, 4, 11, 1 },
- { 21, 12, -3, 6, -8, 8,-11, -8, -5, -5, 3, 7, -1, -5, 12, 15,
- -10,-11, 3, 15, 8, 4, 2,-15, 0, 14, 1, -8, -1, 3, 10, -7 },
- { 16, 12, 5, 13, -6, 15,-23, 0,-17, -9, 0, 4, -9, 13, 6, 18,
- 0, 0, -4, -1, 0, 14, 5, -1, 8, -4, -8, -6, 5, -2, -2, 0 },
- { 14, 16, -1, 12,-15, -9, -6,-20, 4, 6, 8, 9, 3, 1, -9, -4,
- -1,-11, 9, 11,-12, 1,-14, -7, 2, -8, 11, 9, -4, 10, 4,-16 },
- { 13, 10, 3, 7, 0, -8,-33, -6, 4, -4, 19, -2, 14, 6, 5, 7,
- 6, -3, -1,-10,-10, -9, 4, -3, 5, 9, 2, 2, 10, 9, -2, -3 },
- { 11, 10, 25, 18, -1, -6,-21,-21,-11,-16, 6, 5, 14, 4, 8, 7,
- 0,-10, -7, -9, -5, -4, 3, -1, 1, 6, -1, 6, -2, 2, -3, -9 },
- { 15, 9, 5, 22,-17, 15, -9, 7, 7, -9, 13, 9, 10, -1, 8, -3,
- -2, 6, 1, 17, 8,-14, 7, -3, 12, 9, 1, 0, 1, -5, 17,-18 },
- { 25, 19,-17, 12, -4,-10, 1,-13,-19, -7, -3, 9, 6, -2, 3, 1,
- 4, -2,-11,-14, -1, -7, -5, -9, 7, -1, -3, 4, -5, 1, 0, -1 },
- { 20, 8, -3,-10,-24, 3, -6, -2, 0,-12, 14, 6, 7, 11, 4, 7,
- -12, -5, -8,-10, 5, -1, -4, 4, 16, 7,-14, 6, -1, -2, -7,-11 },
- { 16, 18, 17, 1,-15, -6, -5, -3, -1,-19, 8, -2, 2, 8, 12,-19,
- -12, 8, 0, -3, -1, -1, 4,-14, 9, -1,-12, -1, -7, 10, -3, 5 },
- { 18, 12, -7, 7, 0, -3,-13, 0, -1, -4, 9, -2, 6, -1, 0, 1,
- 15,-21, 1, -8, 25,-19, 13, -9, 2, 12, 5, -7, -3, -1, -3, 1 },
- { 13, 16, -4, 9, -2, 2, -1,-19, -7, -4, 18, -6, 14, 18, -5, 4,
- -6, -3,-19,-14, -1,-12, 10, 6, 7, 17,-12,-13,-10, -4, 5, 4 },
- { 27, 17, 4, 14, -9, -2, -4, -8, 0, -6, 14,-11, -7, 2, -3, -3,
- -2, -3,-13, 12, 16, 1, -5, -9,-10,-11, -2, 3, -7, 5, 11, -7 },
- { 7, 17,-16, -2,-14,-28, -7, -8, 15,-10, 7, 15, 8, 17, 13, -1,
- 4, -7,-12,-11, 0, 0, 2, 3, -3, 7, -6, 6, 1,-16, 1, -2 },
- { 23, 11, -9, 15,-23, -4, -6, -4, 2, -9, -7, 9, -8, 3,-13, -4,
- 8, 18, -6, -2, 1, -5, 6,-14, -5, -2, -6, -5, -3, -2, 4, -5 },
- { 12, 13, 18, 18,-35, 2, 7,-17, 3,-11, 6, 9, -3, -2, 10, -4,
- 3, 3, -2, -7, 0, 2, -4, 0, -4, 0, -6, 5, 10, 4, -3, -1 },
- { 19, 11, 1, 20,-14, 4, -9,-13, -2, 11, 0, 17, -1, -1, -1, -1,
- -5, -8, 0, 5, -1, -8, 5, -1, 3, 2,-12, 21, -2,-24, 5, 7 },
- { 15, 15,-15, 17,-14,-22, 3, -4,-11, -3, -7, 1, 18, 10, 1, 10,
- -6, -3, 8, 2, -7, 0, -2, 1, 1, 2, -9, -2, 1, 2, -3, 4 },
- { 45, 13, 8, 17, -5, 2,-16, 2, 8, -2, 8,-15, 4, 5, -1, 7,
- -6, -2, -6, 2, -3, 0, 0, -9, -1, 7, 2, 3, -3, -3, -1, 5 },
- { 1, 18, -8, 18,-12,-10, 3, 4,-22,-12, 20, 8, -3, 9, 2, 10,
- -10, -3, 9, 3, 6, -3, 10, -1, -3, 2, -2, 4, 2, 3, -3,-18 },
- { 9, 10, -5, 9,-35,-21,-18,-16, -1,-12, -6, -7,-15,-19, 12, 4,
- 4, 9, -7, 2, 14, 1, 4, 0, -1, 6, -7, 2, 1, 1, -4, 4 },
- { 31, 8,-17, 35, -8, 1, -5, -6, -7, -6, 10, -2, -3, 6, 9, 3,
- -6, -2, 3, 3, 5, -3, 0, 6, 0, 1, -5, -3, -2, -4, -1, 0 },
- { 18, 4, -8, 7, -8,-15, -1,-16, 12, 18, 3, 19, 2, 4, 8, 8,
- 0, -5, -8,-12, 10, -5, 0, 1, 0, 4, -3, 16, 11, 11, -2, -6 },
- { 27, 15,-17,-10,-23,-22, -1,-14, -4, -7, 20, -2, -7, 6, 15, -5,
- 32, 4, 9,-11, -3, -8, 11, -4, -1, -4, -8, -6, -4, -5, -2, -7 },
- { 22, 4, -7, 2,-15,-11,-17,-10, 2, 0, 15, 11, 7, 12, -8, 6,
- -10,-18, -6,-12, 7, 3, 22, 3, -7, 14, -5, -2,-13, -7, -1, -7 },
- { 18, 13, 9, 24, -4,-19, -9,-11, 13, 8, 2, 4, -1, 8, 14, 10,
- -12, 0, 0, 5, 10, 5, 4, -1, 5, 1, -1, 11, 2, -4, 0, -9 },
- { 15, 19, -5, 1, -4,-10, -8,-27, 6, 8, 5, 10, 4, 11, 5, -5,
- -11, 0,-11,-14, -4, -9, -8, -8, 6, -9, 4, -5, -1, 1, 5, -4 },
- { 18, 1,-13, 14,-14, 9,-15, -7, 12, 1, 13, -4,-20, 12, 10, 12,
- -12, 7, 1,-13, 10, -6, 5, -3, 4, 8, 10,-13, -3, -6, 9, -3 },
- { 19,-14, 5, -8, -6, 2, -5, 5, -3, -1,-28, 11, 18, -6, -4, -2,
- 11, 14,-43,-42, 9, 2, 20,-23, 6, 32, 0, 5, 0, 6, 9, 5 },
- { 8, 11,-14, -1, 7, 12, -7, 2,-16, 2, 10, -3, -1, -7, -7, -1,
- 1,-10,-60,-23,-18, 42,-13, 9, 18,-11, 0, 1, 0, 2, -5, 1 },
- { -5, -1, 2, 0, 3, -3, 3, -2, -6, 0, -3, -3, 7, 2, 0, -2,
- -2, 3,-34,-15, 37, 47, 10, 20, 9, 1, 3,-21,-25,-33,-14, 8 },
- { 5, 6, 2, -2, -2, -2, 6, 5, -5, 7, -3, 1, -5,-13, 9, 3,
- -17,-19, -2,-79,-12, -7, -8, -6, -2, -2, -1, -1, -7,-13, 6, -1 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1,
- 0, 3, 4,-87, 6,-11, 16, -9, -1, 8, 0, 5, 0, 1, 2, 1 },
- { -5, 6, 2,-24, 5, -9, -7, 0, 7, 3, -3, 16,-14,-16, 0, 18,
- 15, -9,-14,-28,-17, 53, 14, -6,-28, -1, -3,-10, -7,-14, 19,-15 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -3, 0,
- -13, 0,-53, 3,-22, 63, 19, 16, 1,-11, 0, -3, 0, -3, 0, 1 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1,
- -1, -6,-43,-43, -2, 65,-13, -4, 9, 1, 1, 2, 1, 0, 0, 1 },
- { 0, 1, 0, 0, -1, 0, 1, 1, 0, 0, 1, 2, -1, -1, -3, -1,
- -23, 1,-61,-55, 3,-28, -6, -4, -4, 8, 2, 1, 1, -1, 0, 0 },
- { 0, 1, -1, 1, -1, 0, -1, 0, 1, -1, 0, 1, -1, 0, -9, -4,
- -48,-19,-52,-46, 11,-12, 5,-14, 0,-10, 0, 0, -1, -2, -1, 0 },
- { 0, -3, -1, -4, 2, -1, -7, 3, 1, 3, -1, 1, -3, 0, -7, 0,
- 3, -7,-61,-51, -4,-21,-16,-21,-11, 14, -7, 8, 3, -5, 1, 2 },
- { 0, 0, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, -1, 9, -3,
- 56,-11, -6,-67, -1, 13, 0, 7, 1, -9, -1, -1, 0, 0, 1, 0 },
- { 14, 9, -2, 14,-10,-10, 9, -5, 1, -8,-23, 30, 8, -7, 23, 8,
- 2, 10, -1,-27,-17, 57, 22, 4, -5, 2,-12, -6, 2, -7, -4, -9 },
- { 1, 5, 12, -2, -2, -3, 2, -3, 6, 0, 4, -2, -8, -6, 0, 16,
- -15, 29,-55,-29,-24, 29, 3, 10, 6, 13, 10, -5, 21, 11,-14, 5 },
- { 4, 2, 26, -6, 10, 11,-23,-10,-27,-20, 3,-24,-11,-10,-13, 25,
- -10, 5, -9,-36, -7, 43, 3,-13, 6, 13, -2, 0, 1, 3, -3, -4 },
- { -1, 0, -1, 0, 0, 0, 0, -1, 1, 0, -1, 0, 0, 0, -1, 1,
- -12, 12,-26,-64,-15, 29, 37, -7, -3,-12, -5, 14, 8, -8,-10, -2 },
- { 19, -4,-11,-16, 8, 14, 5, 19, 3, 22,-11,-21, -1, -6,-11, 11,
- 10,-24,-23,-40, -8, 20, 17, 5, 13, -6, 3, 14,-20, -8, 3, 28 },
- { 2,-12, 10,-14,-18, 26,-22, 4, -2, 5,-21, 8, 3, 1, 19, 0,
- -12, 24,-14,-40, 15, 29,-15, 6, 15, 1,-19, 2, 4, 7,-12, -3 },
- { 0, 17, 13, 7, -5,-11, 2,-19, 3, 38,-21, -3, -6, -4, 7, 1,
- 1, -5,-40,-10, -2, 35, 8, 8,-10, -8, -9, 33, 4, 4, 0, -2 },
- { -2,-12, 7, 29,-24, 2, 16, -1, -7, 16, 10, -2, -2, -2, 13, -2,
- -37, 15,-22,-40,-11, 33, 10, -1, 8, 10, 6, 8, 9, 0,-12, 2 },
- { 15, -8, -9, -2, 7,-17, 7, 19, 14, 4, 12, 27, 11, 10, 4, 11,
- -15, 14,-13,-48, 5, 18, 0, -9,-36,-11, 2, 4, 5, 5,-15,-12 },
- {-12, 0, 3, 4, 7, -5, 5,-14,-24,-18, -6,-15, -8,-20, 1, -7,
- -33,-28,-40,-38,-18,-10, -5, 17,-12, 4, 3, -5, 5,-13, 4, -7 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1,
- -3, -9,-49,-60, -5, 45, -1, 6, 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1,
- -3, -9,-49,-60, -5, 45, -1, 6, 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0,
- 3, -2, 9,-29,-11, 55, 8, 32,-36,-13, -7, 37, 4, 11, 0, 3 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 4, -1,-39, -4,-30, 63, 28,-17, -6, 10, 7,-14, -9, 11, 9, 7 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1,
- 13, -2,-50,-32, 22, 51, 4, 7, 6, 11,-20,-13, 9, -5, 21, -4 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1,
- -3, -9,-49,-60, -5, 45, -1, 6, 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1,
- -3, -9,-49,-60, -5, 45, -1, 6, 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0,
- 3, -2, 9,-29,-11, 55, 8, 32,-36,-13, -7, 37, 4, 11, 0, 3 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 4, -1,-39, -4,-30, 63, 28,-17, -6, 10, 7,-14, -9, 11, 9, 7 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1,
- 13, -2,-50,-32, 22, 51, 4, 7, 6, 11,-20,-13, 9, -5, 21, -4 },
- { -8, 2, 1, 22,-31, -6,-25, -3, -3, 1,-15,-11, -2, -3, 4,-13,
- -9, 15,-18, 37, -7,-37, 12,-13,-11,-25,-10,-11,-22, 7, 16, 7 },
- { 14, 10, 4,-10, -1, -5, -7, -3, 16, 13, -5,-15, 5, 11, -1, 8,
- -27, 7,-12, 49, 17,-22, 9, -2, -9, -1, 2,-15, -1, 41,-18,-17 },
- { -4, -9,-15, -3, 3, 4, 4, 2, 7, -3, -7, -8, -5, 17,-19, -7,
- 36, -9,-38, 17, 1,-48, 11,-18,-13, -2, -8, 4,-10, -5, 21, 11 },
- { 15,-13, 4, 2, 1, -5, -2, 1,-10, 7, -1, 3, -6, 0, 11,-11,
- 8, 20,-17, 51,-17,-41, 2, 15, 4, 8, -2, 16,-32, -1, 17, 6 },
- { -8, 8,-18, -5, 4, 6, -3, 8, 0, -4, 2, 0, -1, -4, 5, 8,
- 30, 30, -8, 70, 2, 8, 2, 0, 7, 1, 13, -1, -6, -7,-11, 2 },
- { -8, -7, 9,-10,-13, 6,-11,-14, 13, 25,-26, 5, 2, -5, -5, 5,
- -8, 4, 0, 33, 12,-38, -4, 6, 13, 6, 25, 34, -1, 25,-19, -5 },
- { 18, 3,-17, 4, -8, 7, 20, 1, -1, 5, -5, -2, -8, 8,-35, 15,
- 24, 43, -5, 51, 5,-12, -3, 1, -2, 3, -3, -3, -9, 8, -9, 2 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
- 2, 10, 24, 76, -2,-22, 11, -1, 4, 33, 4, 1, -1, 1, 2, 0 },
- { 0, -1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 2, 0,
- 24, 13, 32, 70, 26, 5,-21, -9, -6,-15, 2, -2, 2, 4, 1, 1 },
- { 5, -4,-11, 4, -4, 22, 10, -2, 13,-11, -4,-21,-17, 0, -7, 4,
- 10,-34, 11, 52, 2,-46, -5, 0, 0, -1, 2, 4, -9, 1, 1, -7 },
- { 0, 1, 1, 0, -1, 0, 1, 0, 1, 1, 0, 1, 0, 0, -3, 1,
- -8, 9, -1, 64,-13,-61, -3, 3, -5, 10, 1, 3, -1, -1, -1, -1 },
- { 0, 1, 0, -1, 0, -1, 0, 0, 1, 0, 0, 0, 1, 1, 2, 1,
- 10, -2,-31, 79,-10, 27, 0, -1, 3, 8, 1, 1, 0, -1, 0, -1 },
- { 3, 12, 10, 26,-19, 10, -9, 6, -4,-15, 10, 3,-16, 6, 11,-19,
- 3, 10, 18, 44, 5,-30, 5, -9, 21, 4, 20, 10, 14,-25, 8,-17 },
- { 0, 0, 0, 1, -1, 0, -1, 0, 1, 0, 1, 1, 0, 0, -6, -2,
- 8, -8, 13, 69, 26,-19,-25,-17, 16, 6,-12, 22, 2, -6, 9, 5 },
- { 0, -1, 0, 1, 0, -1, -1, 0, 0, 1, -2, 1, 0, 0, -4, -1,
- -34,-15,-33, 56, 9,-42, 9, 10, 6, 9, -8,-11, 0, -6, 15, 5 },
- { 10, 2,-14, -3,-15,-35, -1, 7,-18, 14, 8, -1,-15,-26, 6,-15,
- -18, 22, 9, 33, 0,-32, -9, 3,-11, 7, 4, -1, 5, 30, 9, 1 },
- { 4, 15, 0, 6, -5,-11, 9, 6, 6, 6, 14, 2, -1, 10,-24,-25,
- -2, -4, -1, 37, 2,-29, 14, -9, 22, 17, -2, 33, 10,-25, 11,-11 },
- { 0, 5, 2, 18,-12, 21, 22, 33, -7, 21, -9, -7, 7,-15, -7, 16,
- 7, 0,-14, 44, 10,-25, 5, -4, 15, -8, 10, -4, 5, 9, -1, 16 },
- { 3, 13, 12, 12, 8, 25,-23, 8,-22, -3,-18, -8, 15, 12, 9, 19,
- 0, 0, -9, 49,-27,-15, -9,-15, 12, -8,-16, -7, 13, 5, 13, 2 },
- { 12, -6, 7, -2, 20, -9,-14, 12, 13, -5,-17, 22, -8, -4, 2, 7,
- -13, -2,-15, 43, -5,-30, 27, 4, 10,-27, 5, 27,-10,-10,-18, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
- -1, 10,-18, 70, -2,-52, -1, -7, 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
- -1, 10,-18, 70, -2,-52, -1, -7, 0, 0, 0, 0, 0, 0, 0, 0 },
- { 15,-13,-20, 16, 2, 13, 5,-11, -8, -5, -3, 2, 24,-23, 30, -7,
- 11, 30,-15, 43, 5,-15, 15, -3,-14, 1,-23, 8, 3, 9, 4,-11 },
- { 0, -1, 0, 1, 0, -1, -1, 0, 0, 1, -2, 1, 0, 0, -4, -1,
- -34,-15,-33, 56, 9,-42, 9, 10, 6, 9, -8,-11, 0, -6, 15, 5 },
- { 10, 2,-14, -3,-15,-35, -1, 7,-18, 14, 8, -1,-15,-26, 6,-15,
- -18, 22, 9, 33, 0,-32, -9, 3,-11, 7, 4, -1, 5, 30, 9, 1 },
- { 4, 15, 0, 6, -5,-11, 9, 6, 6, 6, 14, 2, -1, 10,-24,-25,
- -2, -4, -1, 37, 2,-29, 14, -9, 22, 17, -2, 33, 10,-25, 11,-11 },
- { 0, 5, 2, 18,-12, 21, 22, 33, -7, 21, -9, -7, 7,-15, -7, 16,
- 7, 0,-14, 44, 10,-25, 5, -4, 15, -8, 10, -4, 5, 9, -1, 16 },
- { 3, 13, 12, 12, 8, 25,-23, 8,-22, -3,-18, -8, 15, 12, 9, 19,
- 0, 0, -9, 49,-27,-15, -9,-15, 12, -8,-16, -7, 13, 5, 13, 2 },
- { 12, -6, 7, -2, 20, -9,-14, 12, 13, -5,-17, 22, -8, -4, 2, 7,
- -13, -2,-15, 43, -5,-30, 27, 4, 10,-27, 5, 27,-10,-10,-18, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
- -1, 10,-18, 70, -2,-52, -1, -7, 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
- -1, 10,-18, 70, -2,-52, -1, -7, 0, 0, 0, 0, 0, 0, 0, 0 },
- { 15,-13,-20, 16, 2, 13, 5,-11, -8, -5, -3, 2, 24,-23, 30, -7,
- 11, 30,-15, 43, 5,-15, 15, -3,-14, 1,-23, 8, 3, 9, 4,-11 },
- { 16,-18, 7, -4, 31,-15, -9,-13, 20,-12, -6, 0, 12, -6, -2, 4,
- 3, -3, -1, 0, 1, 3, 3, -2, 1, 6, 4, 0, -3, 2, -5, 1 },
- { 38, -5,-13, -4, 8,-15, 11, 1, 2, -4, -1, 9, 13, 4,-12, -7,
- 0, -2, 7, 2, -6, -2, -3, -2, 3, -4, 6, 15, 1, 1,-11, -2 },
- { 47,-22, 9,-26, 3, -5, 2, -7, 4, -2, 2, -2, 3, 0, 3, -4,
- 3, -3, 2, -3, 7, -3, -1, 1, 1, -5, 5, 0, 2, -5, -3, -2 },
- { 14,-16, 2, -6, 7, -2, -7, -4, -4, -7, 14, -3, 7,-19,-14,-17,
- -29, 6, 26, 16, -5, 13, -4, -1, 21, 14, 1, 3, -6, 0, -7, -1 },
- { 29,-11, 5, -3, 4, 11, 4,-10, 1,-22, -3,-10, 5, 4, 2, 8,
- -2, -7,-12,-12, -8, -3,-18, -2, -9, -5, -1, -3, 2,-14,-14, 7 },
- { 28,-12, 5, 3, 9, -7, 0, -2, 2, 1, 4, 0, -7, -3, -2, 4,
- 4, 14, 8, -1, -4, 14, -7, 17, -2, -2, -9, 2, 19, -7, 9, -8 },
- { 31,-18,-22, 8, 15, -5,-10,-15, 1, 10, 6, 7, 6, -8, 2, -1,
- 12, -3, 3, -1, 1, 5, -6, -4, 0, 1, 7,-10, -2, 4, -3, -4 },
- { 53,-30, -4, 12, 2, 3, -3, -3, 0, 1, 6, 5, -5, -4, -7, 1,
- 0, 2, 1, 3, 1, 5, 0, 2, 2, -1, 0, 4, 2, 0, -2, 0 },
- { 27,-18, -3, -2, 4, -8, 3, -2,-11, 2, 10, -8, -8, -4, 0, -2,
- 8, 0, 9, 0,-16, 11, 1, -6, 13, -3,-10,-13,-15, 25, 1, 0 },
- { 35, -5, -1, -8, 23, 11,-14, -3, 2, -2, 8, -6, 17, -2, 7, 0,
- -2, 10,-17, 13, -2, -2, 11, 11,-14, 2, -2, -3, -8, -1,-12, -5 },
- { 29, -9, 7, 3, 2,-10, 0, 3, 9, 0, -3, 5, 1,-10, 10, -5,
- 3, 6,-20, -9, -6, -4, 1, 0, 12, 17, -8, 9, 3, -1, -9, 0 },
- { 15,-16, 18,-19, 16,-15, 17,-18, 13,-16, 17,-14, 15, -9, 13,-17,
- 9, -7, 4, -5, 3, -4, -3, 0, -6, 7, -9, 7, -2, 7, -9, 9 },
- { 21,-10, 7, -2, 12, -7, 13,-17, 11, -2, 20, 3, 5,-11, -6, -6,
- -15, 0, -9, 5,-11, 7, -1, 7, 8,-10, -9, 3, -5, 9, -8, -2 },
- { 23,-22, 15, -5, 16, -4, -3,-12, 9, 3, -1, -2, -8, 2, -2,-16,
- 3, 4, -2, -6, -7, 12, -8, 2,-14, 2, -7, 11, -2, 6, -4, -1 },
- { 34,-17, -4, 8, 4, -6, 1, 8, 4, 16, 3, 6, 12, -1, -1,-15,
- 6, 4, -7, -6, 6, 0, 2, 1, -2, 2, 3, 3, -3, -2, 8, -6 },
- { 18,-18, 2, -2, 10, 1, 18,-23, -3,-10, 0, 4, 20,-19, -3, -4,
- 2, 8, 6, 1, -3, 1, 1, 3, 5, -1,-11, 3, -7, 5, -1, 1 },
- { 15,-14, 2, 3, 10, -8, 12,-13, 13,-15, 6, -8, -4,-10, 14, -9,
- 24, 2, -7,-18, 13,-11, 8, 14, -6, -2, 3, -1, -4, 7, -7, -4 },
- { 20,-12, 13, 5, -1,-10, 15, -6, 8, -1, -3,-10, 17, 0, -6,-19,
- 2, -1, 8, -3,-16, 0, -3, 2, -2, 0, 8, -9, 0, 1,-10, -9 },
- { 32, 0, -9, -5, -1, 5, 13,-11, 8, 3, 11,-11, 0, -8, -2,-14,
- 7, 10, 6, -5, 1, 10, 2, 12,-10, 4, 4, 6, 4, 0, -7,-10 },
- { 16,-14, 10, -7, 11,-11, 11,-11, 18,-13, 8,-15, 16,-11, 13, -9,
- 8, -7, 12,-11, 7, -6, 3, -5, 9, -5, 4, -1, 7, -4, 8, -3 },
- { 24,-27, -1, 5, 8, -5, 12, 7, 4, -3, 3, -1, -9,-11,-13, -5,
- 10, 0,-13, 7, 1, -5, 4, -9, 7, -3, 13, 2, -5, -3,-17, -2 },
- { 23,-19, 15, 1,-10,-18,-12, -6, 8, -3, 12, 0,-12,-10, -4, -4,
- 8,-10, 4, 2, -2, -8, 13, -3, -2, -6, 2, -3, 5, -2, 2, 11 },
- { 25,-12, 4, 2, 24, -3, 3, -6, 14, 11, 0,-21, -3, -3, 1, -8,
- 7, 0, 0, 3, 3, -6, -7, 6, 2, 1, -4, 5, -1, 10, -2, 9 },
- { 24, -8, -6, 7, 16,-12, 13, -1, 11,-21, 2, -6, 3,-12, 0, 9,
- 4, 11, -7, 1, 4, 1, -8, 3, 3, -6, 3, 3, 0, -8, 8, 4 },
- { 25,-21, 13, 14, 13,-18, 4, -3, 0, -5, -4, 5, -3, 0, 4, 12,
- 7, 3, 5, -5, 2, -2, 3,-10, 2, -9,-15, 6, 1, 7, -5, 1 },
- { 23,-16, -2, 10, 4, -1, 3, 1, 32, 3, -5, -2, 9, 10, -1, -4,
- -6, 2, 9, -1, 14, 12, -6, -1,-17, -2, -4, -9, -7, -6, -8, 3 },
- { 50, -8, 5, 2,-11, 10, 0, 0, 6, -3, 7, 0, -3, -2, -3, 0,
- 6, -4, 2, -5, -9, 0, 3, 10, 1, -7, -2, -3, -6, -9, 1, -2 },
- { 28,-17, 0, -2, 2, -9, 1, 5, -4, -1, 0, 0, 19,-27, 5,-12,
- 7,-14, -3, -6, 10, -2, -4, -2, 4, -5, -2, -7, 1, 7, -9, 4 },
- { 22,-19, -6, -6, 3,-22, 3, 5, 20, -8,-14, -5, 1, 1, 20, 2,
- 16, 6, 3, 14, 4, 3, 5, 1, 5, -7,-10, -6, 3, -6, 1,-14 },
- { 29,-14, -8, 13, 8,-10, -6, 4, 4, -6, 5, -7, 1, 12, 14, 11,
- -7, 1, 2, -9,-11, -9, 0, 4, -1, 7, 10, 4, 4, 20, -1,-11 },
- { 18, -9, 4, 1, 7,-29, 12, 1, -1, -9, -2, -1, -2, 2, 9, -8,
- -13, 5, 4,-13, -4, 2, -5, -7, -6, 14,-10,-34, -3, 1, -3,-13 },
- { 38, -9, 24, 8, 11, 4, -6,-11, -2,-12, 1, 1,-11, -8, -5, -2,
- -15, -8, 8, 0, 1, -7, 5, 4, -1, 8, -2, 11, -3, -1, -5, -5 },
- {-20, 11, -4, 24,-11, 1, 15, 4, 0,-28,-10, -1, 10, 10, -6, 5,
- -6, 2, 7, -2, 1, -2, -6, -3, -7, 1, 2, 12, -1, 7, 0, -2 },
- { -9, 10,-23, 27, -4,-17, 20, -6, 14,-17, 5, -1, 5, -9, -7, 5,
- -6, 4, -2, 9, 0, 8, 0, 1, -3, -3, -5, -8, 5, -2, -2, 12 },
- {-10, 19, 4, 9, 1,-16, 17, -2, 9,-29,-16,-11, -4, 7, -5, 4,
- -1, -3, 3, 2, 3, -4, 5,-12, -2, 6, 5, -4, 4, 1, 4, 10 },
- {-20, 10,-24, 14, -5, 11, 9, 0, 16,-20, 10, -5, -6, -6, -1, 2,
- -4, 5,-16, 8, -2, 5, 5,-11, 9,-11, 4,-11, -1, -1, 4, 3 },
- { -9, 11, 3, 19, 24, 4, 5,-14, 30,-17, -4, -2,-17, 7, 2, 3,
- 1, 3, -7, -4, 2, -3, 1, 4, -1, -1, 3,-12, -2, 3, -3, 10 },
- {-19, 18, 11, 19, 19, 19, 10, 4, 13, 6, 5, 4, 8, 3, -2, 12,
- -6, -2, 7, -6, 15, 12, 16, 16, 18, -3, -4,-20, 0, 10, -9, -3 },
- {-21, 9, 20, 12, 0, -3, 5, -9, 15,-13, 5, -5, -6, 24, 2, 9,
- -5, 2, -7, 2, 5, 7, -5, 2, 15, 3, 1, -1, -4, -2, 7, 0 },
- {-18, 16, 13, 15, 2,-10, 14,-11, 4,-11, 5, 12, 12, 20, 8, 30,
- 2, 11, -9, 7, 0, -3,-16, -5, -6, 5, -4,-21, 0, 5, 6, 1 },
- {-26, 8,-13, 9, 6,-10, 2,-11, 7, -4, 6,-19,-11, -6,-12, 16,
- 0, 5, -7, 8, 5, 6, 17, -9, 10,-10, 5, -3,-11, 2, 4, 10 },
- {-11, 17, -3, 22, -5, 18, 3, 1, 4, -5, 14,-27, 5, -7, -4, -5,
- -10, 11, 1, 15, 1, 1, -6, -5, 10,-22, -7, -7,-15, 13, -4, 5 },
- {-17, 14, -7, 13, 3, 0, 13, -6, 9,-14,-22, -1, 1, 19, 14, -3,
- 4,-13,-13, 2, -4, 8, -2, -2, 13,-12, 13,-12, -7, -5, -3, 6 },
- {-17, 17, -1, 33, 6, 3, 9,-16, 3,-14, -8, 6,-17, 8, 3, 13,
- 8, -6, 3, 1, -2, 0, -2, 8, 4, 9, 13,-10, 4,-17, 0, -6 },
- {-20, 7, 7, 21, 1, -3, 7, -3, -2,-12, 9, -7, 2, -3, 14, 1,
- -1, -7, 12,-10, 5,-20, 11, -2, 0,-24,-17, 6, 6, -4, 3, -1 },
- { -8, 10, 6, 7, -1, -6, 28, -6, 10,-33, 1,-20, 0,-12, 10, 1,
- -6, 8, -3, -1,-10, 8, 5, 0, 10, -2, 8, 16, -5, -3, -7, 4 },
- {-17, 13, 3, 15, 1, -5, 27, -5, 6, -6, 12, 2, -4, 8, -1, -3,
- -2, 12,-15, 3, 4, 1, 2, -9, 0,-16,-21, 2, -4, 16, -7, 4 },
- {-15, 20, 8, 17, 5,-14, 15,-11, 21,-11, 13,-13, 2,-15,-13, 1,
- -5, 5, 2, 10, -9, 4, -1, 3, 2, -4, 13, -5, 1, -4, 5, -3 },
- {-21, 8, 2, 16, -1, 2, 15,-16, 13,-12,-12, -7, -8, 2, -7, 11,
- -8, 5, 2, -7, 16, -4, 1, -7, 3,-15, 6, -5, -8, 2, -8, 5 },
- {-15, 17, -6, 3, -3, 3, 9, -7, 14,-23, 11, 1, -1, 4, 7, 6,
- -1,-14, 7, 6, -8, 5, 1,-15, 10, -9, 2, -3, -1, 4,-10, -4 },
- {-10, 18, 3, 11, 1, 4, 14,-14, 7, -4, 15,-10, 10,-11, 10, -4,
- 5,-14, 10, 4, 15,-12, 15,-13, 20,-15, 14,-15, 8,-11, 4, -6 },
- { -7, 23, 2, 20, 7, 8, 19, -5, 9,-16, -8,-17, -5, 1, 5, -6,
- -8, 1, -6, -4, 10, 6, 6, 2,-11, -4, 0, 2, 4, 7, 9, -4 },
- {-15, 20, -5, 22, 11, -8, 9, -5, 10,-13, -8, 8, 2, -2, -3, 7,
- 6, 10, 1, 2, -5, -9, 1, 10, 16,-22, -7, 0, 7, 7, 6, 1 },
- {-26, 19, -5, 3, 5, 25, 18, -5, 9,-14, -8, -6, -2, -6, 2, 3,
- -8, -2, -7, 7, -3, 7, 3, 4, -8, 0, 1, -8, -4, -2, -2, 1 },
- {-20, 14,-10, 6, -3, 7, 8,-32, -2, -7, -2,-10, 16,-12, -9, 15,
- -2, -5, -6, 2, -7, 5, 9, 1, 6, -7, -1, 0, -2, -4, -7, 3 },
- {-14, 16, 4, 11, -8, 1, 23, -4, 17,-13,-10, 1, 12, 9, 12, -4,
- 7, -1, -1, 5, -8, -6, 3, 3, -6, -3,-18, 0, 18, 20, 4, -2 },
- {-33, 19,-10, 30, 15, 2, -3, -1, -4,-14, 7, -7, -1, 7, -8, 9,
- -1, -3, -5, 2, 2, 4, 0, 5, 0, 0, 2, 3, 3, -3, -3, 4 },
- { -6, 20, 0, 5, 17,-10, 18,-17, 9,-16, 4,-13, -6, 2,-14, 14,
- -28, 9,-12, 25, -4, 7, 7, -8, 6, -6, -2,-10, 2,-11, -1, 2 },
- {-12, 14, 12, 52, -3, 5, -5, 4, 8,-13, 2, -5, -4, 2, -2, -1,
- -2, 3, 3, 5, 2, 3, 0, 1, -5, 2, -4, -3, 1, -5, -2, 0 },
- {-13, 6, 9, 24, 0, 8, 14,-15, 18, -9,-11, -8, 3, 15, -2, -4,
- -9, 4, -3, 12, 14,-13, 11, -4, 2, -4, 0, -6, -6, -6,-14, -1 },
- {-10, 28, 3, 12, 9, 3, 11,-28, 6,-11, -7, 4, 0, 7, 8, -9,
- 0, -6, 0,-16, 4, 7, 4, 4, 7, 3, 4, -7, 0, -3,-10, 6 },
- {-11, 14, -2, 19, -1, -1, 7, 9, -2,-27, 10,-14, 15, -4, 12, -4,
- 2, -2, -6, 12, -6, 0, -5, -4, -5, 1, 3,-11, 5, -9, 3, -8 },
- {-18, 7, 13, 16, -4, 3, 9,-10, 10,-10, -3,-22, -4,-12, 3,-16,
- 0, -3,-16, 8,-11, 1, 10, -7, 15, 3, 0, -1,-13, 8, 1, 6 },
- {-20, 10,-10, 10, 8, -1, 6, 0, 16,-12, 9,-10, -1, -5, -4,-13,
- 13, 16, -8, 12, -2, 14, 18, 13, 0,-16, 2, -5, -5, -5, -4, 3 },
- {-14, 5, -7,-17, 5,-13, 23, 20, -4, -1, 1, -6, 13, 5, -1, 4,
- -14, -2, -7, 8, 3, 2, 2, -7, 2, -1, 4, 7, 3, -9, -1, -5 },
- {-19, 3,-24,-28, -9, -7, 19, 3, 2, 19, 7, 5,-13, 8,-15,-17,
- 3,-11, 4, 13, 3, 2, -1, -3, -4, -4, 2, 0, -5, -6, 6, 2 },
- {-17, 18,-30,-20, -2, -3, 1, 15, -1,-11, 6, -4, 11, 11, -4, -5,
- -10, 0, 0, 1, 3, -7, 8, 2, 5, 1, 5, -5, 1, 6, 4, 1 },
- { -6, 1,-30,-25, -1, -8, -2, -9,-17, 16, 3, -1, -2, -9, -6, -7,
- -3, 12, 6, -4,-10, 0, 10, -8, -6, -5, -3,-11, -4, 0, -1, -3 },
- { -1, -1,-34,-28, 1,-10, 2, 9, 4, 16, 2, 6, 14, 17, 0, 7,
- -4, 4, 4, 4, 0, 1, -1, -5, 8, 1, -4, 1, -9, -2, 5, 6 },
- {-11, 14, 1,-31, -7,-24, 9, 7, 6, 5,-13, 1, -1, 3, 4, -1,
- -2, -8, -6, 3, 5, -4, -6, 7, -2, 5, 3, 3, 0, 0, -5, 2 },
- {-25, 8,-11,-18, 1, -4, 8, -3, -4, 15, 6, -5, 8, 2, 3, 4,
- -4, 5, 6, 8, -7, 6, 1,-11,-15,-13, 9, -4,-14, 10, 12, 7 },
- {-20, 11,-15,-25, 3, 4, 18, 13, -4, -5, -9, -1, -5, -2, -2, -7,
- 16, 5, -4, -5, -7, -2, -3, -9, 11, -2, 0, -7,-17, -6,-11, 6 },
- {-11, 18, -5,-20,-15, -3, 9, 11,-20, 12, 5, 5, 11, -3, 7, 1,
- 10, -6, -3, -3, 3, 3, 14, -7, 10,-17, 9,-11, -2, -6, 7,-12 },
- {-20, 8,-14,-17, -9,-13, -3, 0,-27,-14, -3,-14, 4, 3, 6, -6,
- 7, 4, 23, 9, 11, 9, 3, -4, 9, 2, 4, -1, -6, 1, -8,-11 },
- { -9, 14, 2,-37, -7, 13, 6,-11, -6, 9, 18,-11, -6, 2, 12, 4,
- -1, 3, 1, -2, -2, 1, -9, -4, -2, -3, 3, 5, -6, 0, -2, -8 },
- {-29, 8, -1,-13, -2, 8, 23, 2,-10, 7, 13, -6, -5, 11, 13, 0,
- -10,-13, 11,-12,-10, 6, 4, 6, 4, 3, 6, -5, -9, -2, -1, 3 },
- {-18, 6,-10,-55, -4,-11, -2, 0, 1, -3, -9, -6, 3, -2, -1, 6,
- 3, -1, 3, 1, -4, -7, -2, 6, 3, -2, -1, -3, -2, 0, 4, 1 },
- {-14, 5, 3,-21, -8,-16, -4, -2,-11, 27, 15,-20, 3, 0, 1, 1,
- 2, -5, -5, 4, 1, -9, 5, -3, 3, 0, -4, -2,-11, -4, -3, 7 },
- {-17, -1, -9,-17, -8,-18, 12,-13, -9, 13, -3, 3, 3, -3, 1, -2,
- 0, 16, -9, 6, 12, 9, 5, 11, 2,-15, 1, -4,-16, 7, -4,-12 },
- {-18, 8, -6,-11, -8, -7, 13, 7, 1, 6, 8, -1, 21, -4, 14, 15,
- 18, -4, -3, 15, 0, 9, 4, 7, 3, -1, 9, -2, 0, 7, -8, 2 },
- {-10, 7,-18,-29, 3, 12, 12, 9, 11, 4, -1,-15, 1, -1, 8, -2,
- -2, 10,-15, -1, 0, 6, 12, -6, -1, 10, -6, -3,-11, -4, 9, -6 },
- {-14, 14, -9,-21,-12, -2, -1, -7, -5,-10, 5, -8, 0, 6, 9,-11,
- 11, -3, -5, 3, 8, 15, -2, -4,-22, 4, -6, 12, 2, 13, 6, -7 },
- {-12, 11, -5,-29,-25, 4, 12,-13,-11, -7, 4, 2, 2, -5, 5, 8,
- 7, -5, -5, 6, 3,-10, 1, -6, 6, -6, -5, -1, -2, -4, 7, 6 },
- {-15, 11, -5,-16, 0,-13, 26,-23, -6, -3, 5, -2, -2, 21, -6, -3,
- -5, -1, 6, -1, 0,-13, 2, -3, -9, -1, -4, -3, 5, -4, 12,-16 },
- { -9, 9, -1,-17, -3, -6, 12, 6,-18, -2, 11,-14, -6, 3, 14,-12,
- -11, -5, 14, 2, 5, -8, -4,-11, 2, -5, 16, 6, -7, -4, 8, 13 },
- {-13, 5, 3,-28,-14, 0, 6, 23, 5, 4, -1,-17, 1, -3, 0, 0,
- 5, 4, 0,-18, 14, 10, 4, 2, 5, -2, 4, -3, 2, 0, 2, 0 },
- {-15, 4,-13,-16, -3,-12, -2, 2, 7, 10, 9, 3, 11, 4, 23, 14,
- 9, 16, 4, 1,-12, -3, 4, -7,-15, -7,-10,-14, -6, -8, -1, -6 },
- { -7, 10, -5,-10, -3,-13, 16, -1,-12, 7, -3,-12, 2, 13, 13, 2,
- 17, 15,-13, 1, -5, -2, 3, -1, 1, -3, 6, -3,-12,-16, 7, -7 },
- {-11, -5,-12,-30, -6,-22, 1, 4, -6, -3, 12, 6, 7, 0, 16, 6,
- -2, 0,-22, -2, -9, 2,-13, 8, 6, -8, 4, -7, -1, -6, 4, 6 },
- {-14, 5, 1,-27, -4, 2, 1, 14,-11, -7, -8, -4, 1, 8, 0, -6,
- -13, 11,-12, -7, -5, 1, 10, 7, 3, -2, 0, 6, -8, 2, 10, -1 },
- {-10, 10,-25,-13,-20, -4, 19, 3, 13, 5, 5, 7, -8, 2, 4, 2,
- 3, -1, -1, -9, 14, 10, 9, 14, 3, 3, -6, 0, -5, 4, 1, -1 },
- { -9, 15,-18,-17, 4,-11, 6, 7,-12, 8, -1,-11, 2, 3, 7, 16,
- -3, -9, 7,-12, 23, 0, 6, 7,-14, -9, 8, 1, -2, 6, -2, -1 },
- { -6, 9,-16,-26,-14,-11, 9, -6, 5, -2, 13, 17, 21, 7, 18,-19,
- 6,-23, -2,-15, -2, 2,-10, -8, 2, 1, -2, 4, -3, -4, -5, -4 },
- { 0, 6, -5,-28,-17,-32, 2,-10, 11, 3, -5, 9, 10, 3, 11, 11,
- -3, 12, -2, 2, 4, -6, 9, -4, -4, -4, -4, -9, 2, 0, 2, 4 },
- { 0, -8,-18,-34, -9, -7, -4,-11, 10, 15, 11, -1, -8, 15, 6,-13,
- 9, 2, -4,-12, 0, -1, 19, 12, 6, 5, 0, -3,-10,-12, 3, -5 },
- {-10, 6, -9,-17,-12,-11, 9, -6, 11, 11, 18, -7, 0, 16, 4, 2,
- -6, 3,-12, -1, 0, 1, -5,-22, -2,-12, 0, 6, 17, 5, 5, 6 },
- { 12, -5, 7, 1, -5, -2, -1, 2, 2, -4, -3, -3, -3, -2,-29, 11,
- 5,-13,-73, 24, 12, 4,-14,-10, 5, 1, 0,-11, -7, -7, 7, 3 },
- { 10, -3, -1, -3, 4,-11, -5, -2, -8, 7, 9, 2, -8, -6, 6, 7,
- 21, 17,-54, 47,-14,-10, 14, 19, 13, 21, -4, 3, 1, 2, -4, 2 },
- {-12, 4,-16,-12, 5, -9, -4, 19, -7,-22,-22,-17, 3, 0, -6, 8,
- 23, -4,-55,-28, 2,-26, 2, 1, 4, 0,-13, 6, 0, 10, -7,-11 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, -1,
- 35, -1,-67,-35,-24,-24, -6, 2, 2, -2, 1, 3, 2, 0, -1, 1 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 5, 0,
- 41, -4,-73,-15, 18, 4, 17, 8, -1,-16, -1, -2, 1, 0, 0, 0 },
- { -4, -4, 4, 6, -1, 2,-16,-10,-15,-10, 21, -2, -6, -2, 14, -7,
- 10, -5,-55, 34,-12, 11,-13, -2, 2, 28,-26, 0, 7, 4, 21, -7 },
- { 2, 1, 15,-22, 10, -3, 14, -6, -2, 15, -2, -7, 20, 6,-15, -7,
- 23, 10,-60, 8, -4, 29,-22, 2,-13, 9,-10, 12, -1, -3, 4, 7 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, -1, -2, 11, -5,
- -21,-11,-60,-27,-17,-39, 6, 36, 0, -8, 2, 2, 0, 0, -2, 3 },
- { 2, -5, 9,-17, -1, 2, -3, -6, 8, 12, 7, -6,-33,-11,-14,-40,
- 10, 36,-46, 0,-19, 5, 0,-10, 3, 12, -6, -8, 6,-12, -7, 1 },
- { 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, -1, 0, 1, 0, -2, 0,
- 4, -2,-87, -3, -2, 2, -2, 20, 2, 6, -1, 6, 0, 0, 2, -1 },
- { 1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, -1, 0, 0, 1,
- 1, 7,-76, 41, -7,-24, 0, -6, 3, 6, 0, -2, -1, 1, 0, 0 },
- { 0, -3, 4, 2, 3, 2, 2, 0, 3, -1, 4, 0, -1, 4, -2, -4,
- -32,-11,-64,-29, -9,-43, 2,-11, -1, -7, 0, -4, -2, -2, -2, 2 },
- { 10,-20, 3, -3, 13, 13, 0, -4, 2, 7, -8, 7, -2, 2,-20,-20,
- -19, 3,-47,-18,-16, -6,-15,-42,-17, 14, -6, 8, 12,-10, 11,-12 },
- { -3, -2, -2, -1, -1, 4, -3, -1, -6, -2, 3, 2, -3, 6, -1, -9,
- 10, 13,-68, -9, 26, 3, 5, 3,-21, 10,-15, 21,-22, 19, 11,-14 },
- { 1, 5, 18,-19,-29,-13, -2, 18,-10, 20, 2, 10,-10, 11, 1, 8,
- -16,-17,-41, 10,-14,-25, 0,-14,-19, 17, 7,-12, 14,-11, 14, 5 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, -1,-43, 5,
- 6,-12,-48, 19, 8,-38, -8, -3, 22,-21,-10, 15, 20, -9, -5, 8 },
- { 0, 0, 0, 0, -1, 1, -1, 0, 0, 0, 0, 0, 0, 0, 6, -3,
- 22,-14,-71,-24, -2,-33, 23, 7, -8, 7, -3, 2, -4, 1, -8, -2 },
- { 1, 0, -1, 2, 0, -2, 0, 0, -1, 0, 4, 0, 26, -1, 10,-11,
- -17,-32,-58, 14,-14,-11, -2, 15, 2, -8, 12, 10, -9, 13,-33,-14 },
- { 15,-17,-19, 7, -8,-15,-32,-22, 7, 12, 18, 0, 0,-15, -4, 16,
- 37, -2,-46, 11, 2, -8,-10, -8, 14, 9, -4, 5, 7,-17, 4, 3 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2, 0,
- -5, 3,-85, 23, -9,-17, -2, -2, 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2, 0,
- -5, 3,-85, 23, -9,-17, -2, -2, 0, 0, 0, 0, 0, 0, 0, 0 },
- { 1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, -1, 0, 0, 1,
- 1, 7,-76, 41, -7,-24, 0, -6, 3, 6, 0, -2, -1, 1, 0, 0 },
- { 0, -3, 4, 2, 3, 2, 2, 0, 3, -1, 4, 0, -1, 4, -2, -4,
- -32,-11,-64,-29, -9,-43, 2,-11, -1, -7, 0, -4, -2, -2, -2, 2 },
- { 10,-20, 3, -3, 13, 13, 0, -4, 2, 7, -8, 7, -2, 2,-20,-20,
- -19, 3,-47,-18,-16, -6,-15,-42,-17, 14, -6, 8, 12,-10, 11,-12 },
- { -3, -2, -2, -1, -1, 4, -3, -1, -6, -2, 3, 2, -3, 6, -1, -9,
- 10, 13,-68, -9, 26, 3, 5, 3,-21, 10,-15, 21,-22, 19, 11,-14 },
- { 1, 5, 18,-19,-29,-13, -2, 18,-10, 20, 2, 10,-10, 11, 1, 8,
- -16,-17,-41, 10,-14,-25, 0,-14,-19, 17, 7,-12, 14,-11, 14, 5 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, -1,-43, 5,
- 6,-12,-48, 19, 8,-38, -8, -3, 22,-21,-10, 15, 20, -9, -5, 8 },
- { 0, 0, 0, 0, -1, 1, -1, 0, 0, 0, 0, 0, 0, 0, 6, -3,
- 22,-14,-71,-24, -2,-33, 23, 7, -8, 7, -3, 2, -4, 1, -8, -2 },
- { 1, 0, -1, 2, 0, -2, 0, 0, -1, 0, 4, 0, 26, -1, 10,-11,
- -17,-32,-58, 14,-14,-11, -2, 15, 2, -8, 12, 10, -9, 13,-33,-14 },
- { 15,-17,-19, 7, -8,-15,-32,-22, 7, 12, 18, 0, 0,-15, -4, 16,
- 37, -2,-46, 11, 2, -8,-10, -8, 14, 9, -4, 5, 7,-17, 4, 3 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2, 0,
- -5, 3,-85, 23, -9,-17, -2, -2, 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2, 0,
- -5, 3,-85, 23, -9,-17, -2, -2, 0, 0, 0, 0, 0, 0, 0, 0 },
- { 16, 65, -2, -2, 4, 3, 0, -7, 3, 1, 3, 1, 0, 5, 1, -5,
- 0, 2, -1, 3, 0, 0, -1, -2, 6, 0, -2, 0, 0, -1, 1, 1 },
- { 5, 37, -4, 8, -4, -1, 9, 17, 6, -7, 5, -1, 11, 6, -4, 7,
- -2, 4, 1, -3, 11, 3, 3, -9, 6, 0, -2, -4, -5, 4,-12,-11 },
- { 15, 24,-14, 2, 6, 17, 26, 5, 8, 11, -9, -7, -6, -8, 3, -5,
- 9, 10, -3, 10, 0, 1, 4, -9, 4, 9, 3, 0, 4, 0, -5, 3 },
- { 9, 36, -9, -8, 7, 7, 4, 3, -1,-16, -2, 7, -5, -6, 6, 12,
- -11,-12, 9, -1, -3, -9, 12, 6, -6, 2, 2, 5, 0, 5, 6, -6 },
- { 25, 39, -5, 24, 3, 10, 3, -6, 13, -8, 3, -7, 2,-10, -5, 2,
- -2, 3, 5, -2, 1, 5, -2, 3, -4, 1, -5, -4, 0, 1, -2, 0 },
- { 16, 27, -1, 0,-14, 6, 4, -5, 7, -2, -6, 0, -3, -5, 2, -1,
- -1,-19, 5, -8, 0, 11, 12, 5, 0, 3, 10, 6,-14, 14,-13,-15 },
- { 12, 23,-14, 2, 1, 4, -3, 16, 7, -8, 2, -8, 8, 6, -8, -7,
- -3, 0, 2, 8,-13, 7, 13, -6, -4, 6,-13,-16, 14, 11, -7, 5 },
- { 16, 28, -7, -1, 6, -3, 9, 0, -7, 3, 0, 3,-12, 20, 8, 9,
- 8, 23, 8,-13, -2, 4, 9, 3, -5, 13, 5, -2, 12, 14, 5, -1 },
- { 19, 37, 19, 5, 7, 5, 10, 5, 19, 10, 14, 0, 2, 5, 1, -4,
- -4, 2, 2, -5, -2, -1, 2, -6, -4, -4, -5, -3, 2, -2, -2, -2 },
- { 24, 21, 1,-11,-10, 17,-14, 14, 6, -1, -6, -1, 0,-13, -1,-12,
- -2, -5, 6, -4,-12, 14, 5, -2, -8, -8, 15, -7,-30,-12, 4, 0 },
- { 11, 26, -3, 3, 5, -1, -2, 3, -2, 10, 15, -4, 10,-28, 10,-17,
- -8, 1, 2, -7, -1, -6,-15, -1, 4, 5, -7, 9, 0, -5, -4, 4 },
- { 18, 32, 1, 2, -7, 4, 15, 2, -9, -2, 12,-11, 7, 11, 13, 2,
- 0, 5, 9,-10, 16, 3, -3, 5, -9,-23, 2, -2, -1, 5, 2, 11 },
- { 35, 24,-20, 2, 4, -1, 5, 14,-10, -9, 8, -7, 0, 5, -7, -7,
- 11, 1, 5, 3, 2, 0, -2, 3, 0, 1, 4, 0, -2, -8, 0, -4 },
- { 9, 35, -1, 2, -1,-19, -3, 12, -1, 8, 8,-13, -1, -2, 2, 5,
- -8, -1, 13, -2, 11, 1, 0,-10, 0, -3, -7, 2, 1,-12, 3, 12 },
- { 20, 27,-12,-12, 7, 4, -1,-13, -1, -9, 2, 13,-11, 5, 7, -9,
- 9, 1, 1, 8, -9, 0, -6, 7, 4, 2, -2, 7, 3, -2, 1, -9 },
- { 8, 37,-20, -5, 0,-21, 10, -8, 3, 19, -9, 7, -3, -8, 10, -2,
- 0, 5, 6, -4, -2, -1, 0, -7, 6, 1, 0, 4, -5, 6, -8, 2 },
- { 8, 27, 1, -3, -5, 1, 6, 0, 15, 2, 17, -1, 3,-17, 10, 5,
- 5, -6, -6, 6,-10, 18, -5, 0, 0, 13, 7, 10, -5, -6, -2, -4 },
- { 14, 29,-20, -4, -3, 1, -5, -1, 2, 12,-10, -3, 4,-18, 4, 14,
- -4, -1, -9, 15, -2, 2, -5, -3, 2, 9, -2,-14, -3, 4, -4, -7 },
- { 23, 23,-23,-11, 27, 4, 4, -1, 7, 0, -5, 9, 2,-11, 3, 7,
- -2, -5, 2, -7, -7, 13, -3, -6, 2, 3, 3, -4, -1, -8, 5, -2 },
- { 16, 26, -6, 8, -9, -1, -2, -1, -8, 4, -2, 0,-12, 9, -1, 0,
- -17, -9, 30, -5,-15,-16,-13, 0, 10,-11, -7, -3, -1, 0,-11, -2 },
- { 12, 32, -4, -5, 10, 19,-10, 4,-12, 5, -6, 9,-12, -6, -6, -8,
- 4, 1, 3, 0, 8, 0, -3, -4, -7, -4, 10, 8, 6, 5, -1, 4 },
- { 46, 42, -3,-14, -2, -6, 6, -2, -5, -1, -3, -3, 1, -1, 3, 1,
- 1, 4, -1, 2, 3, 1, -2, 6, 0, -1, -2, 4, -2, -1, 2, 2 },
- { 9, 33,-13, 4,-11, 3, -8, 22, 12, -2, 4, 0,-16, 5, 4, -1,
- 7, -6, -9, 1, 7, 5, 0, -5, 5, -1, 10, 3, -2, -1, 3, -2 },
- { 9, 30, 6, -3, 6, 1, -7, 5, 11, 14, 7, 1, 0, 2, 2, -1,
- 8, 7, -6,-13,-10, -2, 1, -6, 10, 7, 6, 5, -2, -5, -1,-16 },
- { 9, 28,-11,-10, 9,-10, 15, 8, 4, 9, -4, -7, 0, -5, 9, 8,
- -7, 2,-15,-23, 4, -4, 4, 16, -8, -3, 0, -8, 14, 5, -3, 15 },
- { 17, 26, -5, -5, -1, -8, 20, 18, -7, -2, 4, -7, -8, -5, -4, 16,
- 0, 0, -7, -2,-13, -5, -2, 3, 12, 1, 3, -5, 2, 2, 0, -1 },
- { 11, 37, 7,-23, 6, -1, 15, 13, 4, -9, 7, 5, 3, -3, -5, -8,
- -2, 3, -5, -1, -8, 7, 2, 13, 1, 3, 0, -3, -1, 2, 0, -2 },
- { 21, 33, 7, 20, 21,-10, 6, -5, -5, -6, -9, 2, 10, 0, 8, -4,
- 10, 2, -2, -2, 0,-10, -6, -2, 0, -5, 3,-11, 3, -9, -3, 1 },
- { 6, 30,-15, -8, 16, 1, 4, 6, 4, 5, 8, -3, 8, -9, -1, -6,
- 8, 2, -2, 4, -2, 5, 11,-21, 3,-10, 16,-11, 24, 10, 14, -6 },
- { 15, 36, -3, -9,-20, 12, 0, -7,-18, -4, -8, -9, 9, -7, -3, -1,
- 2, 7, -5, -8, 6, 2, 2, -1, 7, 1, 1, -3, 3, -4, -8, 1 },
- { 16, 34, 21, 3, -9, 10, 7, 9, -7, 1, -4, -9, -4, -5, -5, 3,
- 3,-19, 1, 5, 4, -2, -6, -5,-10,-11, -8, -2, 2, -5, -8, -7 },
- { 28, 29, -3, 18, -2, 0, -6, 12, -2, 10,-11, -4,-13,-12, -6, -4,
- 0, 4, -1, -8, 6, 4, 12, 11, 10, 10, -3, -6, 1, 2, 1, 7 },
- { 3, 8, 22, -8, 3, 36, -8, -1, 9, 6,-13,-14, 8, -1, 1, 2,
- -2, -8, 0, 3, 1, 2, -1, 5, -1, -8, 0, -2, 2, 2, -1, 1 },
- { 0, 6, 0, 0, 4, 13, -7,-16, -6, 15,-14,-21, -9,-10,-10, -6,
- -21, 5, 4, 2, 12, 4, 12, 11, -4, -6, -6,-10, -7,-18, 1, 4 },
- { -1, 3, 10, 1, -1, 15, 4, -7,-16, 3, 0,-22, 10, 2, -3, -2,
- 13, 5, -8, 16, -5, 4, 0,-11,-10,-22, 0, -4,-17, 5, 2, 1 },
- { 12, 8, -4, -9, 14, 40,-21, 0, 1,-15,-10,-12, 12, 6,-10, 2,
- 8, 6,-12,-10,-11, 1, 0,-11, 2, 1, 13, 0, 6, 3, 8, 4 },
- {-10, 3, 5, -4, -3, 3, 0, -9, 2, 8,-22,-23, 17, 8,-17, -3,
- 14, -8, -4, 1, -8, 3, 0, 5, -1, -3, -2, -4, 1,-10, 0, -2 },
- { 0, -1, 5, -7, 4, 12, -2, 0, -7, 2,-16,-15, 12, 21, -7, -4,
- 7, -7,-11,-15, -7, -9, -5, -8, 0, -6, 8, -3, -8, 22, -7, -9 },
- { 7, 19, 4, -9, 24, 22, 2, -6, 8, 13,-14,-20, -4, 11, 8, -4,
- -1, 2, 0, -7, 5,-17, -3, 3, -6, 5, 3, 4, -5, -7, -3, 14 },
- { -2, 6, 2, 8, -2, 5, -4, -2,-10, 3,-45,-30, -3, -3,-12, -4,
- -3, -3, -1, 9, -6, -6, 5, -4, 0, 5, -1, -2, -1, 0, -6, -1 },
- { -3, 14,-16,-10, 10, 0, -2,-40, -9, 12, 2,-19, 15, -4, 4, 3,
- 3, -4, 7, 1, -4, -5, 0, 4, -1, 0, -9, -2, -4, -1, -2, 0 },
- { 7, 16, 2, -7, 8, 2, 0, 1, 5, 21,-10,-26, 7, 2, -9, -7,
- -3,-16, 8, 5, 5, -6, 10, 4,-14, -6, 5, 3, -2, -2, -4, 1 },
- { -9, 14, -1, 3, 3, 11, 1, -5, -3, 13,-16,-18, 20, 6, -5, 0,
- -3, 2, 8, 4,-19, -9, 12, 0, -8, 2, 2, 1, 6, 13, -7,-11 },
- { 2, 5, 16, -4, 19, 15, 4, 0,-11, 7,-10,-10,-16, 18,-11,-12,
- -9, -4, 7, -4, -4,-17, 1, 1, -8, -3, -3, 5, -2, -6,-11, -5 },
- { 2, 12, 0, -9,-10, 14, 6, 2, -3, 2,-12,-28, 12, 1, -1, 2,
- 0, -3, -4, 7, 16, 5, -7, 8, -4, -3, -1, 3,-12, 4,-17, -5 },
- { -4, 7, 11, 6, 1, 14, -4, -6, 5, 5, -6,-24, 23, -9,-15, 13,
- -7, -9,-15, 10, -1, 8, -5, 1, 12, 6, 2, 0, 4, -2, 9,-10 },
- { 1, 5, 11, 3, 6, 12, -3, 8,-21, 5, -7,-20, 12, -2, -9, -3,
- 17, -7, -8, -9,-14, 3,-13, 18, -8, 9, 2, -8, 4, -8, -5, -2 },
- { -3, -3, -1, 5, -2, 15, 3, 2, 1, -8, 1,-39, -6, 13,-13, 0,
- -2, -5, -6, -3, 0, -5, -2, 15, -9, 5, -3, -6, -2, 7, 0,-13 },
- { 2, 8, 5,-12,-13, 22, 8,-16, 11, 5, -2,-32, -2, -4, 11, 5,
- 5, -6, 1, 3, 1, 5, 3, 6, -5, 4, 4, -8, 8, 4, 1, 3 },
- { 13, 9, 5, -4, 9, 18,-11, 2, -1, 15,-10,-19, -2, 14, 0,-10,
- 1, 1,-18, 3, 2, -6, -8, 20, 7, -8, 16, 9, 9,-13, -3, -2 },
- {-13, 11, 11, -9,-10, 13, -3,-18, 2, 10, 5,-21, 6, 15,-11,-21,
- 3, 14, 0,-12, 9, -1, -2, -4, 3, -3, -9, -8, -5, -2, -8, 2 },
- { 3, 3, 11, 4, 0, 13, 1, -8, 10, 13, -6,-26, 2, 12, -3, -5,
- 12, -2, 1, 8, -7,-17,-19, 5, 10, 7, -3, 2, -3, 0, 5, 0 },
- { 5, 0, 3, -3, -9, 5,-15, -5, -5, 17, -5,-31, 0, 13, 13, 5,
- -1, -6,-14, 7, -8, 9,-14, -2,-16, -4, -4, -6, 6, -6,-10, 6 },
- { 13, 3, 1, 7, -3, 4, -1, -2, -1, 4, -8,-32, -1, -4, 0, 3,
- -10, 7, 10,-10, 4, -1, 6, 2,-16, -9, 4, 3, 13,-23, -3, -4 },
- { 4, 11, -4, -9, 4, 11,-12,-12,-12, 6, 1,-28, -3, 14, 18, -2,
- -12, 7, 15, -3, -5, -7, -3, 2, -6, 4, 4, -2, -5, -3, 2,-13 },
- { 8, 7, -7, 0, 13, 7, -8, -7, 8, 36,-10,-22, 3, 23, -3,-10,
- -3, 11, 1, -7, 3, 3, -1, -7, -4, 2, 3, 2, 5, 3, -4, -1 },
- { -1, 1, 13, 1, -6, -1, -6, -9,-18, 17, -5,-37, -1, -1, -6, -4,
- 1, -6,-15, 2, 17, -9, 0, -3, 0, 4, 0, -5, 0, 4, 1, -5 },
- { 0, 14, 5, 0, -7, 2, -6, 17, -6, -9, 7,-16, -5, 23,-14,-13,
- 8,-15, 11, 10,-11,-13,-33, -5, -2, 1, 6, 8, 0,-13, -9, 5 },
- { 11, 7, -2, -8, 9, 11, 25,-14, 7, 3, -1,-33, 14, 8, -6,-19,
- 3, 3, 2, -1, -3, -1, -2,-10, -3, 1, 2, 1, 4, 2, -3, 4 },
- { -2, 8, 4, -2, 9, 13, -4, -2,-15, -3, 19,-37, 9, 25, -9, 2,
- -5, -2, -2, -4, 4, 2, 2, 0, 3, 3, 3, 5, -2, -3, -4, -3 },
- { 10, 13, -1,-15, 4, 6,-18, -4, 25, 1,-23,-17, 15, 13, -8, -8,
- 7, 4, -5, 3, 6, 9, -7, 6, 0, -5, 8, 0, -6, -1, -2, -2 },
- { 1, 3, 9, -5, 27, 15, -9,-31, -1, 23, -2, -9, 1, 8, -1, -7,
- -2, -8, -4, -4, -2, -1, 3, 5, 0, 0, -1, 1, -7, 7, -3, -3 },
- { -8, 7, 3, -6, 8, 3,-11, -2, 36, 14, 1,-30, 6, 10,-12, -6,
- -6, -2, -4, -3, -5, 0, 9, 4, -5, -5, -8, 12, 4, -3, 1, -8 },
- { -2, 9, 33, 0, 12, -3, -7, -4, -4, -1, 6,-25, 11, -6, -9,-11,
- -2, -4, -2, 6, -1, -3, -6, 15, -6, 3, 10, -4, 1, 0, 5, 8 },
- {-22,-21, -9,-19, -5, -7,-12,-15, -8, 9,-19, 14, -7, -4, 5, -8,
- -2, 7, 1, -3, 4, -4, 6, 11, 2, 6, -3, -5, 2, -2, 0, -3 },
- {-32,-13, 3,-24, 3, -8, 4, 1,-10, 14,-15, 0, 4, 6, -1, 6,
- 7, -1, 6, 4, -3,-17, 1, 4, -6, -1, 1, 0, 3, 3, -7, -4 },
- {-32,-11, 7, -8,-12, 13, -5,-22, -4, 12,-16, 2, 0, 4, 0, 1,
- 0, 6, -5, -8, 2, 6, 5, 0, -3, -6, 5, 6, 5, 5, 13, -4 },
- {-44,-33, 6, -4, 2, 0, -9, 10, 3, 4, 7, 0, -1, 7, 5, 1,
- 1, -3, 1, 6, -1, 0, 2, 3, -4, 0, 0, 1, 0, -1, -2, -1 },
- {-30,-18,-24, -8, 5, 0, -2, 14, 7, 0, 1, 12, 6, 4, -9, 7,
- 5, 7,-11, -5, 1, -8, -1, 2, 2, -9, 7, -1, 7, 5, 6, 6 },
- {-22,-20,-13, -9, 20, -3, 10, -8, 6, -4, 2, -7, 10, 8, 0, -1,
- 2, -3, 6,-19, 2, 4, 3, 3, -7, 2, -1, -6, 1, 1, 6, -2 },
- {-27, -8, -1, 3, -1,-11, 24, 4, -1, 1, -8, 8, 5,-11, 15, -3,
- -15, -1, -1,-13, -1, 1, -5, 5, 2, 3, -9, 0, 4, 3, -7, 6 },
- {-33,-16, -1, -8, 10,-23, 6, 13, -1, -3, -9, 0, 5, -7, -5,-12,
- -2, 3, 3, 6, -2, -3, 2, -3, 9, -6, -3, -2, 0, 5, -3, -4 },
- {-22,-17, 11, -3, 3, 1, -1, -5, 17, 2,-15, -2, 10, -9, 6, 14,
- -16,-12, 20, -1, -7, 6, -3,-12, 1, 10,-10, -1, 7, -3, -1, 10 },
- {-28,-13, 1, -3, -1, -1, 0, 3, 3, 5, 1, 10,-10, -3, 7, 2,
- 4, 19, -1, -1, 10, 5, -8, 1, 11,-15, -4, -3, -5, 4,-13, 3 },
- {-22,-13, 42,-20, 5,-13, 7,-11, 1, 1, -1, 1, 6, 3, 6,-11,
- 3, 3, -2, 0, -4, 4, -3, -1, -5, 2, 0, 0, -9, -1, 4, 4 },
- {-26,-15, -2, -6, -4, -2, 16, 8, 21, 8, 1, -3,-10, 7, -8,-12,
- -5, 12, -9, 3, -2, -3, 18, 1,-12,-15, -4, 5, -3, 0, 12, 7 },
- {-26,-16, 5, 6, 14, -3, 15, 6, 1, -7,-13, 16,-15, 5, 11, -2,
- 9, -7, -4, -2, 0, 0, -2, 7, -8, -6, -5, 2, 7, -3, 2, 12 },
- {-31,-17, -8,-30, 4, 14, 6, -6, 6,-11, 0, 3, -4, 0, 0, -4,
- 0, -4, 1, 4, 3, 4, 0, -5, 3, 2, 2, 0, 2, 1, 3, 5 },
- {-61,-10, 4, 10, 4, 7, 0, -3, 0, 1, 0, -3, 0, 1, 0, -2,
- -1, 1, 2, -2, 4, -3, 1, 1, -1, 1, -2, -4, -4, 4, 0, 0 },
- {-28,-13, -8, -4, 3, -3, 2, 1, 11, 14, 3, 9, 1, 13, 3, 5,
- -3, -2, -2,-12,-14, -9,-11,-15,-12, -5, -4,-12, 3, -3, 0, -5 },
- {-41, 0, 12,-24, 13, 4, 5, 16, -5, -4, 0, 0, 13, -4, 1, -9,
- 9, -6, -1, 6, -2, 5, 2, 9, 6, -9, -8, 8, -2, -3, -6, -4 },
- {-26,-19, -2,-15, 4,-14, 6, 0, 26, 20, 8, 9, 9, 3, -4, -5,
- -8, 1, 0, -1, 5, 9, 3, 4, 4, 7, 1, 3, -2, -2,-10, 0 },
- {-29,-18, 9, -4, 1, -5,-14,-12, 5,-10, -5, 4, -5, 0, -1, -1,
- 4, -5, 7,-16,-11, 2, 7,-15, 2, -4, 6, -4, -6, 7, -3, 7 },
- {-27,-16, 9,-14, 3, -8, 9, 0, 7, -4, -3, -7, 0,-10, -1, 2,
- 1, -2, 15,-10, 14, 7, 6, 17, 3, -4, 3,-10, 8, -8, 3, 11 },
- {-21,-20, -8, -8, 4, 5, -3, -2, 0, -5, 14,-10, 11, -4, 13, 0,
- 5,-11, 19,-18, 18, 3, -5, -3, -4, -8, 11,-10, 10, 3, 4, -9 },
- {-35,-15, 13,-12, 4, 0, -2, -4,-12, -3, -8,-24, -7, 1, 7, 8,
- -3, 0, -2, -1, 3, -2, -2, -6, 8, 1, 0, 1, -6, -1, 2, -6 },
- {-19,-14, 13,-10, 9, -1, 1, 3,-12, 5,-16, 7, 13, 9, 4, -4,
- 6, -5, 4, 9, -3, 17, -4, 12,-11, -6, -5, -6, 13, 2, 7, -9 },
- {-34, -8, -4, 1, 2, -1, 3, 6,-20,-11, 8, -1, 4, 2, -9, 4,
- -4, -5, 16, 10, -4, 14,-13, 1, -6, 0, 2,-10, 0, -3, -3, 7 },
- {-36,-10, -8, -3, 2, -2, 14, -4, -1, -7, -4, 10, -1, -3, 15,-11,
- 0, 2, 3, -1, 4, 0, 8, -1, 0, 18,-11, -5, 15, -5, 13,-12 },
- {-22,-13, 14,-20, 15, 25, 16, 10, 8, -2,-10, -5, -1, -8, 11, 8,
- -1, -2, -4, 1, 2, -1, -7, 0, 0, 0, -3, 0, 2, -1, 0, 2 },
- {-31,-22, 7, 6, -2, 5,-20, 14, -6, 7, 0, 14, 3, -7, 3, -6,
- -2, 1, -3, -5, 1,-10, 1,-24, 6, -2, 3, -7, 1, -7, 8, 7 },
- {-25,-20, -3, -9, 10, 6, 12, 7, 5, 4, -3, 6, -1, -5, -6, -8,
- 3, 5, 6, 5,-10, 10, -4,-15,-15, -2, -9, 2, 18, 1, 8, 12 },
- {-24,-19, -2, -4, -7, 11, 6, 9, 16, 2, -7, 18, 6, -7, 6, 6,
- -2, -9, 3, 12, -2, 3, -1, 6, 7, 8, 0, 8,-11, 8, 4, 2 },
- {-26,-20,-12,-12, -2, -3, 1, -5, -1, -2, 0, 3, 7, 9, -2, 2,
- 9, 22, 13, 4, -4, -1, -2,-14, 5, 15, -8, -5, -7,-11,-14, -6 },
- {-21,-18, -1, -4, 0, 3, 7, -2, 10, 8, -8, -1, 15, 1, -9, 3,
- 1, 3, -5, -2, 2, 4, 0, -1, 10, 2,-19, -8, 8, 30, -7, 8 },
- {-25, -6, 26, 4, -8, 4, -2, 21, 5, -4,-16, 5, 13, 4,-10, -1,
- -6, -2, 2,-10,-13, 1, 3, -3, -6, -8, 2, 11, 1, -7, 0, 5 },
- { 0, -1, -2, 19,-12,-48, -6, 11, 8, -2, -4, -2, -7, 5, -3, 2,
- -2, -1, -1, -7, 0, -3, -3, -4, -4, 4, 1, 3, -3, -1, -2, -5 },
- {-11, -8,-28, 18, 16,-24, -8, 19, 4, 8,-12, 9, -4, -2, 4, -7,
- 6, 2, 3, 3, -4, 0, 1, -6, -4, -2, 2, 6, 0, -3, 1,-16 },
- { -9, -5,-26, 7, -3,-37,-16, -2, 2, -7, 4,-13, 0, -4, -6, -5,
- -6, -4, 0, 3, 4, -3, -4, -4, 4, -3, 9, -4, -2, 2, 7, -4 },
- { 2, 9,-18, 7, 29,-24, -1, 7, 14, 10, 3, -3, -2, -5, 6,-10,
- -6, -3, -8, 0, 5, 1, 4, 3,-12, 2, 6, 1, 3, 4, 1, -3 },
- {-20, 2, 8, 20, -9,-24, -4, 18, 3, 11, -1,-11, 6, 9, -1, -3,
- 1, -1,-15, 3, 15, 9, 3, 2,-13, 2, -8, 8, 1, -1, 1, -8 },
- {-12, 5,-11, 6, 19,-26,-17, -6, 4, 14, 6, -8, 9, 5, -6, -5,
- 2, -1, 20, 1,-11,-10,-18, 20, -7, 0, -3, 4, 2, 0, 10, 4 },
- {-15, 1, -2, 13, -8,-21,-22, 4, 4, 3, 3, -7,-31, 4,-10,-14,
- 0, 8, 4, 5, 8, 11, 2, -8, 6, 7, 0, -2, 6, 8, 8, 7 },
- {-13,-10, -9, 12, 19,-16, -3, -2, 9, 2, 11,-29, -1, 9, 4, -3,
- 1,-10,-10, 16, 1, 7, -7, -6, -4, -1, -5, 3, 6, 0, 3, 1 },
- {-17, -1, -5, 19, 12, -9,-21, -5, 2, 12, -7, -7, -3, 8, 7, -2,
- 6, -9, -9, 1, -4, 1, 1, 3,-14, 2, -8, 0, 10, 1,-12, -6 },
- {-13, -5, 8, 15, 0,-20, -2, 20, 8, -8, 8,-19, 12, 10, 2,-11,
- 0, 12, 1,-11, 0,-11,-15, 5,-11, 2, 4, -4,-11, 5, -4, -5 },
- { 3,-11, -7, 8, 0,-17,-26, 15, 19, -7, 10, -9, -5, -5, 14,-25,
- 0, -8, 2, -9, -3, 9, 1, -6, 4, -4, 3, -9, -1, 6, 2, 2 },
- {-12, 5, 5, 9, 14,-18,-19, 4, 2, 16, 14,-21,-15, -9, -1, 16,
- 12,-11,-10, -5, -7, 4, 15, -8, -5, -1, 1, 14, 13, -7, -1, -4 },
- {-10, -5, -1, 8, 7,-23,-10, 14, 6, 11, 10,-16, -3, 16, 6, 0,
- 0, 9, 6, -2, -7, 1, 22, 5, 3, -8, 0, 3, -2,-10, 3, 0 },
- { -2,-14, 2, 16, 15,-17,-17, 6, 19, 4,-10,-15, -1, 15, 11,-14,
- -8, 5, 8, 8, -2, -8,-11, 10, 10, -8,-14, 2, 13, 4, -2,-12 },
- {-10, 3, 6, 4, 19,-23,-19, 1, 4, -9,-30, 3, -6, 18, 0, 2,
- 0,-11, 0, 3, 7, -2, 8, 5, 2, -3, 6, -9, 1, -4, 7, -6 },
- { 9, 5, -2, 21, 20,-33,-13, 7,-10, 8, 8,-15, -6, -4, 1, 5,
- 3, 7, -2, -9, -1, 4, -6, 1, 0, 9, -1, -5, 2, 1, -3, 3 },
- { -9, -3, 3, 15, -3,-30, -7, -7,-25, 6, 2, -6, 1, 19, 1,-12,
- 1, -8,-13, 9, 13, 1, 8, 2, 5, 15, -2, 3, -9, 0, -4, 4 },
- { -6,-12,-17, 25, 22,-13,-10, 9, 2, 11, -7,-16, 4, 6, 1, 0,
- 0, 18, -4, -5, 4, -2, -1, -5, 0, -4, 6, 1, 6, -1, 7, 0 },
- { -1, 0,-10, 8, 8,-27, 0, -2, 29, 16, -2, -4, 9, -1, 2, 0,
- 6, 10, 6, 4, 2, -7, 9,-18, 3, 3, 3,-10, 17, 10, 9, -6 },
- { -3,-12, -6, 11, 20,-32, 5, 21, 3, -4, -9, 2,-10, 1, 7, -4,
- 5, 0, 0, -1, -8, -9, -7, 4,-10, 5, 0, 2, -5, 4, 9, 1 },
- { -5, -1, -5, 1, 2,-19,-13, 1, 6, 12, 2,-16,-17, 11, 10, 13,
- 16,-12,-11, 3, -6, 0, 6, 4, -3, 1, 8, 2, 5,-11, 3,-14 },
- {-19, 5, 10, 11, 2,-23, -9, 16, -2, 7, 0,-11, -7, 10, 6, -7,
- 26,-15, -4, 8, 6, -4, 7, -9,-15, 1, 8, -4, 4, 2,-12, 16 },
- {-11, 1, 11, -4, 1,-31,-13, -1, 8, 5, 4, -2, 0, 13, 7,-17,
- 7,-10, -6, 1, 4, -1, 2, -9, -4, 9, 3, 3, -4, -5, 3, 4 },
- { -3, 1, 10, -1, 0,-15,-22, 4, 40,-11, -4, -3,-14, 9, 11, -1,
- 9, -1, -6, 6, 3, -6, 0, 0,-12, 7, -2, 0, 9, 3, 1, 3 },
- { -1, -1, -1, 14, 8,-24,-14, -8, 5, 8, 5,-12,-17, 8, 2, 7,
- 10, -8, 0, 4, -6, -6,-10, 8, 4,-12, 3, -9,-12, 5, 4, -3 },
- { -5, 1,-11, 8, 9,-24, 0, 2, 2, 14,-12,-13, 1, 6, 7, 0,
- 7, -6, 9, 26, 11,-14, 8, 10, 1, 9, 0, 11, -2, 6, 2,-10 },
- {-13, 1, 4, 34, 19,-17,-15, 0, 3, -2, -7, -1, 0, -3, -3, -1,
- 1, -1,-10, 8, 5, 0, -8, 4,-17, 9, -2, 0, 0, 6, 2, -3 },
- { -6, -4, 1, 2, 2,-14,-29, 0, 9, 34, -3, -5,-14, 6,-10, -9,
- -5, -1, 0, 3, 3, 0, 1, -1, -2, -1, -1, -3, -3, -4, 3, -3 },
- { -4, 6, 3, 14, 14, -8,-29, 31, 11, 14, -4, -5, -6, 10, 6, -9,
- -1,-11, -7, 1, 7, 4, 1, -6, 4, 0, 10, -7, -5, -1, 2, 4 },
- { -4, -4, -2, 14, 6,-32, -6,-14, 14, -5,-11, 10,-18, -4, 6, -8,
- 9, 5, -4, 1, -4, 5, -2, -9, 3, 5, 2,-10, -6,-17, 3, 17 },
- {-16, 9, 21, 19, 4,-20,-17, 14, 9, 15, -6,-17, -1, 1, 6, -3,
- 1, 1, 8, -3, -6, 6, 9, 4, 9, -9, -5, 1, -1, 0, -1, 2 },
- { -7, -5, 3, 19, 1,-20, -9, 14, 21, -7,-18, -9, 26, -7,-17, -7,
- 12, 6, 0, -9, -6, 14, 9, -9, -8, 4, 15, -7, -9, -1, 9, 1 },
- {-20, 30, -6, 11, 24, -4, 0, -6, -2, 8, -4, 12, -8,-17, 0, 5,
- -4, 1, -1, 3, -3, 5, 3, 3, 7, -2, -3, -2, 4, 0, 0, -1 },
- {-35, 17, 6, 1, -9, -1,-16, 3,-20,-13, 8, 7, -4, -7, -4,-20,
- 7, 12, -5, 5, -5,-11, 12, -1, 15, -9, -6, 16, -4, -9,-13, 4 },
- {-21, 36,-19, 9, 0, -7, -8, 9, -4, -3, 3, 0, 7, -8, -2, -2,
- -11, 13, -1, 5, -3, 7, 2, 3, -1, -2, -5, 1, -1, -2, -5, -3 },
- {-12, 33, -4, 1,-12, -9, 0,-13, -1, 2, -8, 4,-10, 6,-16, -7,
- -1, -4,-10, 15, -1, 0, -5, -8, 5, 5, -3, 0, 2, -7, 1, -7 },
- {-14, 32, 5, -7,-15, 3, -5, 8, 14, 5, 9, 13, 3, 18, -3, 7,
- 4,-10,-10, 10, -1, 2, 0, -2,-11, 5, -3, -4, 2, 2, 7, 4 },
- {-14, 34, 1, 20, -1,-12, 0, -3, -7, -4, 7, 18, 9, -3, 14, -7,
- -9,-20, -7, -4,-13, 12, 1, 12, 5, -6, 2, -4, 0,-15, 1, 3 },
- {-21, 23, 7, -8, 3,-13, -3, 0, -6, -2, -7, 6,-12, 9, -6, -2,
- -2, -4, -1, 6, 9, 5, -9, 15, 0, 8, -8, 7, 6,-15, 3, -5 },
- {-27, 32, -1, -4, -2, 4,-10, 12, -3, 8, 13, 7, 0,-15, 4, -2,
- 3, 5, 7, -4, 9,-12, -1, -2, -1, -4, 0, -4, 2, -5, 6, -6 },
- {-17, 29, 15, 0, -1, -4,-10, 13, 12, -1, -8,-10,-10, 4, 7, -2,
- 6, -5,-13, 19, 6, 1, -7, 2, -9, -2, 12, -4, -8, -3, 2, 4 },
- {-38, 27, 16,-15, -6, 3, -7, -4, 0, -1, 6, -2, -3, -6, 6, -6,
- -3, 0, 2, 0, -4, 6, 1, -1, 0, 4, -1, 3, 4, 1, -2, 5 },
- {-33, 40, -4, 2, 1, 0, 0,-10,-14, 0, -7, 4, -1, 3, -2, 5,
- 7, 6, -1, 4, 1, 3, 1, -7, 1, -4, 5, 7, 0, 4, 3, -4 },
- {-20, 25, 12, -4, 16, -4, 2, 2,-14, -2, -3, 29, -1, 1, 3, 1,
- 9, -5, 2, -8, -3, 1, -7, -2, -7, 1, 0, 4, 16, -2, -1, -1 },
- {-10, 30, 17, 3, -5, -2, 0, -5,-22, 4, 5, 5, -3,-18, -6, 10,
- -5, -7, 2, 8, 7, -7,-11, -2, 0, -3, 3, 2, 11, -4, 4, -4 },
- {-11, 30, 11, 4, -3, -8, 1, -2, 4, 18, 3, 1, -1, 0, -8, -4,
- -3, 10, 13, 14, 5, -5, 1, 1,-10, 2, 15, 4, 9, -1, -5, -3 },
- {-17, 32, 18,-18, -3, -5, 6, 10, 1,-15, -5, 9, 8,-12,-10, -6,
- 11, 9, -5, -8, -7, 10, 5,-10,-14, -4, -3, 1, 9,-11, 2, 1 },
- {-13, 28,-11, -1, 2,-16, -2, 7,-24, 0, 3, 6, 3, -1, -8, -7,
- -12, 2, 2,-20, 10, 4, 0,-13, -2, -2, 1, 8,-14, 0, 4, 1 },
- {-14, 23, 12, 8, 8,-26, 2, -4,-14, 13,-14, 15, 3, -9, -1,-13,
- -10, -2,-10, 6,-16, 12, 8, 0, 9,-10, -7, -4, -4, 7, -8, 8 },
- {-20, 45, 10,-14, 4, 16, 8, -9, 1, -8, 10, 5, -7, -2, 2, -5,
- -1, 0, -5, 4, -6, -2, 4, 1, 3, 4, -4, 2, -2, -2, 5, 1 },
- {-20, 26, -4, 1, 7, 4, -8, 1, -5,-13, 2, 13, -7, -3, 6, -6,
- 22, 0, 5, 11, -4,-11, 8, -9, 2, -2, -4, -2, 2,-13, -4, -8 },
- {-28, 18, 17, 3, -8,-23,-16, -6, 5,-10, 14, 10, 5, -1, -8, 4,
- -2, 13, -3, -2, 3, 4, 3, -2, -3, -4, 0, 1, 3, 4, 0, 4 },
- {-12, 32, -6,-16, 18, 12,-16, 0, 7, 13, -4, 5, -8, -1, -3, 4,
- 6, -2, -1,-13, 4, -1, 3, 12, -3,-10, 1, 6, 8,-11, -2, 4 },
- {-18, 26, 2, 5, 0, -9,-17, 14, 5, 1, 7, -3, -8, -3, 11, 7,
- -5,-12, -8, 7, 0, -7, 2,-12, -9, 13,-11, 9, 6,-11, -5, 11 },
- {-24, 22,-15, -9, 8, 1, -7,-12, -9, 3, 11, 15, 14,-11, 12,-15,
- -5, 7, -2, 0, -8, 3, 3, -1, 2, 11,-11, 14, -6, 13, 1, -6 },
- {-20, 28, 18, -4, -6, -5, 12, 14, 2, 10,-13, -6, -8, -6,-13, -1,
- -26, 22, -3,-14, 6, 0, 10,-15,-13, -9, 6, -7, 1, -5, -4, -1 },
- {-19, 26, -8, -3,-14, -6, -9, -4, -8, 15, -8, 3,-12, -4, -2, -7,
- -5, 3, 13, -3, -4,-25, 4, -1, 5,-12, -1,-13, 5, 2, 0, 6 },
- {-18, 43, 14, -8, 1,-23, -2, -2, 1, 3, -7, 0, 0, 8, -1, -3,
- -5, 1, 5, 2, 0, -2, -2, -2, 1, -1, -1, -7, 0, 3, -3, 9 },
- {-11, 30, 10,-14, 3, 1, 10,-11, 1, -7, -4, 14, 2, 1, -9, 1,
- -11, -2, -7, 5,-11, 1, 3, 14, 1,-16, -8, 3, -5, 7, -4, 4 },
- {-18, 24, 6, 3, 8, 7,-22, -7, -7, 3, -8, 4, 23, 9, 3, -1,
- 3, 6, 7, -1, -7, 6, 4, 1, -3, 1, -6, -1, 2, -7, 3, 3 },
- {-15, 38, -7, -1,-11, 2,-17,-24, 24, 8, 7, -4, -5, 2, 2, -7,
- 1, 4, 0, -9, 5, 0, -1, 1, -1, -5, -6, 3, 0, 7, 8, -3 },
- {-14, 22, 1, -5, 9,-12, -9, -5, -6, 5, 7, 8, -1, -4, -9, -3,
- -33,-16, -9, -1, 12,-11, 17, -7, -3, -1, -7, 3, 2, -3, 16, -4 },
- {-14, 20, 6, 4,-10, -4, -4, -4, 1, -7, 2, 6, 8,-12, 4, 1,
- -1, 12, 10, 3,-14,-10, -3, 18, -2, 33, -5,-17, 17, -5, 9, 7 },
- {-12, 23, 13, 0,-11, -8,-11, 12, -5, -9,-16, 11, 6, 4, 12, -5,
- 5,-13, 7,-12, -3, 1, 2, 12, 1, -4, -1, 5, 4, 11,-12, -3 },
- { 15, 2, 14, 7, 1, 2, 1, 12, 10, 23, 4, 6,-20,-10, 4, 26,
- -6, 13, 4, 3, 2,-11, 5, -7,-10, 4, 9, 1, 10, -4, 11, 4 },
- { 17, 15, 31, 17, 18, 16, 11, 24, 2, 4, 2, 3, -8, -3, 7, -3,
- -5, -7, -2, -6, -4, -5, -4, -1, -4, -2, -5, -6, 2, -1, 4, -2 },
- { 16, 8, 15, 14, 3, 7, 21, 9, 8, 15, 21, 6, 8, 12, 5, -5,
- 7, -3, 10, 2, -3, 8, 6, 0, 5, 5, 6, -3, 2, 4, 0, -5 },
- { 5, -4, 6, 12, 6, 13, 24, 17, -5, 17, -1, -6, -7,-10, -8,-18,
- 3, -2, 2, 7,-15,-11, 12, -3, -2, -2, -4, -7, 2, 0, 5, 5 },
- { 10, -6, 8, 11, 12, 20, 22,-11, -3, 15, -3, 15, -2, -2, 0, 2,
- 5, -8, 4, -5, -9, -4, -1, 2, -1, -3, 1, 3, 13, -1, 9, 7 },
- { -5, 8, 5, 11, 14, -5, 14, -9, 2, 35, 8, 15, 1, -2, 2, -2,
- 4, -9, -3,-14,-12, -2, -2, -4, -2, -8, -3, 1, -6, 3, 10, 0 },
- { 16, 0, -6, 15, -3, 4, 4, 3, 3, 20, 5, -4, 10, 9, -9, -3,
- -10, -2, -7, 11,-11,-10, 17, -1, 3,-15, 2, 9,-15,-10, 16, 10 },
- { 14, 4, -7, 19, 3, 0, 19, 8, 16, 34, -9, 6,-13, -1, 6, 5,
- -1, -2, 4, 3, 2, 1, 1, -1, 0, -7, 2, -1, 1, 0, 6, -1 },
- { 1, 6, 9, 13, 9, 10, 15, 16, 10, 18, 13, 17, 3, -1, -7, 2,
- -15,-11,-10, -4,-13, -6,-17,-13, -6,-14, 1,-10, 6, 4, -1, -1 },
- { 13, 1, 7, 10, 14, 13, -7, 5, 5, 28, 14, 14, -2, 2, 3, -3,
- -13, -4, 10, -9, 19, -4, -3, 4, -5, -5, 0, 5, -5, 0, 3, -4 },
- { 1, 0, 6, 22, 9, 18, 18, -3, 5, 10, 12, -2, 1, -3, -8,-12,
- 9,-10, -7, 1, -1, 19, 0, 2, -8,-11,-10, 9, 6, 11, 0, 3 },
- { 10, 11, 19, 44, 0, 14, 1, -7, 6, 22, 2, -1, 9, 2, 0, -4,
- 4, 0, -6, -6, 3, 0, 0, -2, 2, -5, 1, -2, 0, 1, 1, 1 },
- { 5, 7, 0, 32, 30, 26, 5, 4, -7, -3, 15, -6, 3,-10, 7, 6,
- -8, -7, 2,-13, -5, -1, -3, 7, 3, -2, -8, 0, 6, 4, 5, 0 },
- { 9, 8, -2, 4, 2, 11, 4, 29, -5, 14, 8, -5,-14, 8, 0, 9,
- 8,-10, 5,-15, -6, -9, 9, -1, 18,-16, 9,-21, -3,-13, -2, 8 },
- { 25, 7, -9, 23, 20, 18, 6, 16, -9, 8, 8, -5, 11, 13, -8, 7,
- 4, 10, -2, -1, -7, -9, -7, -9, -4, 1, 1, -5,-10, 8, 4, -5 },
- { 9, 2, 16, 14, -5, 14, 1, 0,-21, 17, -1, 9, 12, -3, -3, 4,
- -4, 14, 10, 3, 0,-10, 7, 4, 4,-11, 2, 4, -1, -3, 9, -1 },
- { 17, 8, 11, 26, 15, -3, 14, -1, 12, 9, 10, -8, 8,-18,-11, -3,
- -14, -7, 7, -3, -3, -4, 1, -7, -3, 2, -3, 16, 10, 0, 9, 6 },
- { 9, 8, 3, 8, 18, 14, 11, 1, 10, 6, 1, -4,-16, -2, 14, -2,
- 1, 8, 12, 14, 3, -3, 8, 8, 12,-15, 3, -3, 3, -2, 14, 10 },
- { 22, -3,-11, 13, -7, 11, 4, 11, 3, 14, 0, -6, -2, -9, 4, 2,
- -2, 0, -5,-27,-10, 3, -1, 5, 8,-24, -3,-11, -3, 2, 11, -1 },
- { 19, 2, 8, 36, 5, -6, 3, 15, -3, -4, -5, 14,-10, 1,-12,-10,
- -3, -4, 3, -2, 1, -8, 4, 3, 5, -3, 0, 4, 8, -2, 8, 4 },
- { 8, 14, 15, 9, -4, 10, 5, 11, 9, 10, 8, 9,-15, 15, 6, -8,
- -10,-13, 5, -8,-20,-13, -6,-11, -1, -3, -6, -4, -1, 0, 13, 15 },
- { -2, -1, 9, 12, 2, 2, 13, 3,-23, 33, 15, 2, -4, -1, 3, 8,
- 8, 6, 6, -7, 8, 6, 9, -1, 3, -8, 0, -4, 1, -8, 11, -1 },
- { 6, 5, -6, 16, 2, -3, 31, 21, -9, 12, 0, -1, -4, 1,-12, 3,
- -13,-18, 2,-11, -9, 2, -8, -6, 11, -3, -1, 0, -1, 0, 13, 5 },
- { 5, -1, 2, 0, 25, 5, 10, 16, -5, 21, 14, 12, 13, 2, -5, 5,
- 5, -3, -2,-14, 0,-12, 7, 11, -1, -7, 19, -1, -1, -1, 8, -1 },
- { 10, 7, 3, 11, 0, 8, 22, 3, 3, 19, -4, 12, 15, 9, 5, 15,
- 2, 1, 2,-10,-10, 0, 2, -1, 0, 1,-12, -1, 21, 16, 9, -7 },
- { 11, -4, -5, 24, -7, 11, 20, 11,-15, 18, 5,-13,-15, 0, -5, 9,
- 1, 0, -1, -9, 4, -8, 6, -8, 1, -2, -7, 20, 9, 3, 9, 3 },
- { 20, 0,-12, -6, 9, 31, 9, 12, 8, 27, 15, 7,-16, 5, -3, -7,
- -1, -9, -2, -7, -3, 4, -8, -3, 3, -6, -2, -2, -3, -6, -1, 2 },
- { 6, -6, 48, 8, -3, 19, 12, 11, -7, 2, 3, 0, -1, 1, 8, -4,
- 4, -6, 0, -4, -4, -3, 3, 6, 3,-13, -8, 5, -3, -7, 8, 5 },
- { 7, -2, 6, 11, 12, 2, 14, 4, -5, 12, 2, 9, 4, 2, 0, -1,
- 2, 0,-15, -9,-16, -2, 8,-17, -5,-22,-19, -5, -1,-10, 1, -2 },
- { 11, -9, 3, 12, 6, 6, 1, 17, -6, 19, 14, 7, -7, -1, -1, -9,
- 9,-11,-17, 0, -6, 16, 0, 1, 9,-24, 3, 3, -9, -3, 3, -2 },
- { 9, 0, 1, 8, 1, 7, 2, -5, -3, 8, -1, 7, 2, 6, -3, -6,
- 5, -2, 6, -2, -4, -3, 0, -3, 13,-50, 1, -2, 2, 4, 4, 3 },
- { 7, 0, 26, 21, -4, 2, 17, 8, 7, 11, -7, 1, -1,-15, -1,-15,
- -11, -4,-17, -4, 1, -7, 3, 6, 3, -9, 2, 3, 6, 10, 6, 12 },
- { 1, -2, 2, -1,-10, -4, 6, -3, -5, -2, -8, 2, 2, 2, 8, 0,
- 1, 1, 6, 0, 11, 13, 3, 4, 0,-12, 11, -5, 19, 20, 2, 5 },
- { 5, 3,-13, -2, 1,-12, 11, -7,-12, 7, 10, 0, 7, 0, -2, 4,
- -6, -9,-11,-12,-23, 12, 10, -3, 0, 6, 19, -1, 24, 18, 9, 12 },
- { 6, -3, 2, 5, 2, 2, -2, -5, -8,-11, -4, 3, -8, -4, 5, -3,
- -16, -4, 3,-12, -4, 3, 32, 7, 2, 8, 32,-18, -1, 12, 1, 7 },
- { 0, -8, -1, 0, -8, 7, -8, -1, -1, 4,-12, -1, 3, 0, 1,-18,
- 8, 8,-14,-10,-11, 19, 9, 5, -7, 6, 8, -4, 26, 12, -1, 6 },
- { 3, 5,-14, 7, 14, 8, 20,-13,-16,-10, -2, 17, -7, 4, -8, -9,
- 14, -5, 3, -4,-12, 7, 14,-10,-19,-20, 35, 8, 13, 14, -2, 9 },
- { -2, -4, -1, 1, -3, 0, -1, 1, 2, 2, 6, 0, 0, 4, 5, -2,
- 3, 3, 3, -2, -7, -3, -3, -1, 6, -2, 29, 22, 13, 34, 0, 14 },
- { -3, -9, 3, 1, 5, -4, 2, 0, 7, -9, 0, 2, -5, -3, 0, 6,
- -1, -1, -1, 2, 2, 4, 8, 7, 20, -6, 7, 16, 33, 20, 6, -1 },
- {-11, 1, -3, -3,-11, 3, -9,-25, -1,-16, 4, -8, 15, 1, -2, 7,
- 8, 23, 2, 18,-13, 16, 3, -7, 6, 3, 16, -8, 12, 16, 3, 4 },
- { 0, 5, 5, -5, 1, -1, 2, -3, -2, 1,-13, 2, 2, 10, 6, 7,
- 18, 18, 7, 9, 8, 9, 21, 14, 7, 12, 15, 14, 15, 12, 11, 5 },
- { 1, -5, 11, -2, 17, 8, 3, 0, -1, 6, 11, -7, 6, 6, 7, 5,
- -15, 14, 1, 11, 4, 10, 12, 1, 2, 4, 30, 1, 11, 1, 6, 13 },
- { 2, 4, 3, -7, 5, 8,-11, 7, -5, 9,-10, 6, 8,-10, -3, 10,
- 1,-29, -4,-26, 5, -8, 13, 4, 3, 6, 35, 1, 3, 6, 3, 0 },
- { -2, 1, 0, 0, -1, -3, -7, -3, -9, -3, -1, -6, 3, 4, 4, 0,
- 5, -1, -2, -2, -1, -4,-10, 8, 0, -6, 10, -4, 46, 12, 2, 28 },
- { 4, -1, 4, 1, 0, 4, -2, -2, -2, -1, 2, -4, 1, 5, 0, -3,
- 1, 1, -2, 0, 1, -2, -1, -1, 3, -6, 35,-11, 13, 53, -3, -1 },
- { -5, -2, 0,-13,-16, 5,-12,-11, 1,-30, 3,-18,-24, -8, -5,-19,
- 1, -3, -8, 7, -7, -8, 15,-19, 4, 10, 30, 24, 6, 1, -9, 10 },
- { -4, 8, -7, -4, -6, 12, -1, -9, -4, 2, -9, 3, 2, -2, 4, 2,
- 22, 9, 4, -5, 0, 5, -2, -9, -3, 1, 18,-12, 18, 16, 4, 16 },
- { -5, -8, -3, -5, -3, 6, -7, -3, -2, -5, -3, 1, 2, 2, 4, -6,
- 10, 3, 12, -3, 20, 0, 27, -4, 16, 5, 18, -3, 23, 4, 12, 11 },
- { 0, 1, 0, 1, -2, 1, 2, 1, -1, 0, -2, 2, -2, -4, 1, -2,
- -2, -1, -5, -2, 0, 0, -2, 2, 9, 7, 63, 5, 12, -1, 1, 0 },
- { 4, -3, -7, -5,-11, -5,-12,-10,-10,-12,-15,-12,-14,-14, 1, 1,
- 10,-10, 16, 6, 2, 9, 11, 9, 9, 8, 12, -1, 13, 12, 6, 3 },
- { 7, -3, -2, 4, 6, -8, 2, -3,-12, -5, -9, -8,-10, 15, -2, -4,
- 8, 9, 7,-13,-18, 34, -5, 7, 12, 22, 16,-11, 13, 25,-15,-11 },
- { -3, -2, 0, -4, 1, 0, -3,-13, -7, 13, 12, -7,-10, 13, 19, 6,
- 16, 15,-12,-15, -3, 34, 1, 5, 1, -9, 11, 21, 8, 17, -5, -6 },
- { 3, -5, 0, -4, 0, 4,-11, 4, -7, -3, -1, -8, 3, -2, 2, 1,
- 11, 5, 6, 14, -3, 2, -4, -7, 0, 31, 15, -2, 24, 11, 5, 4 },
- { -1, -4, -9, 5, -8,-18, -4, -9,-20,-18, 7,-14,-16, 3, 8, -3,
- 29, 11,-13,-13, 7, 1, 17, 6, 6, 21, 11, 1, 14, -8, 2, 5 },
- { -3, 8,-10, -6, 12, 2, 1, 3, 3, 3, 3, -6, -8,-14, 15, -5,
- 16, 4, 16, 0, 7, -1, 0, 16, 2, 1, 22, 4, 19, 13,-11, 1 },
- { 2, -3, 10, 20, -4, -1, -8, 5, -8, -9, -6, -2, -4, -7, 8,-10,
- 0, 8, -6, 1, -8, 14, 13, 5, 17, -6, 26, -1, 7, -1, 0, 12 },
- { -4, -7,-31, -2, -7, -1, 5, -5, -5,-12, 4, -7, -6, 3, 15, -2,
- 5, -2, 7, -1, 10, 7, 8, -1, 14, 20, 14, 9, 16, 16, 8, 24 },
- { -7, 0, -3, -6, 1, 3,-13, -6, -4, -4, -5, -9, -1,-10, -4, -8,
- 2, 0, -1, 1, 24, 24, 21, 31, 5, 2, 11, 12, 7, 4, 3, 6 },
- { -3, -5, 6, -4, -3, -1, 2, -1, -2, 1, 0, -8, -1, 2, 0, -4,
- 6, 22, -1, -5, 8, 12, -1, -2, 28, 27, 20,-27, 14, 1, 2, -3 },
- { 1, -5, -2, -2, 6, -2, 9, 1, -2, -5, 3, 4, 11, 5, 2, 8,
- -3, -1, 1, -2, -3, -5, 5, 8, 49, 12, 8, -3, 9, 20, 12, 17 },
- { -6, 0, 1, 7, 0, 9, -2, -4, 8, 0, -2,-10, 0, 7, 21, -1,
- 0, 1, 17, -7, -5, 2, 4, 16, -2, 17, 14,-20, 15, 14, 4, 15 },
- { 0, 3, -4, 9, -4, 0, 6, 4, -6, -6, -5, -7, 2, -9,-10, -2,
- -5, 0, -3,-21, 9, 14,-11, 13, 29, 2, 25, 4, 22, -1, 2, -3 },
- { 2, 12,-11, 2, 16, 9, -4, 7, 1,-10,-15, 11, -4, 3, -2, 4,
- 4, -5,-10, 1, 4, 19,-15, 6, -4, -2, 30, -7, 11, 21,-12, 5 },
- { -2, -3, -2, 4, -1, -5, -3, -7, -5, 1, 0, -6, 1, -6, 7, 0,
- 8, -7, -3, -2, 2, 14, 2, -3,-26, -1, 26, 22, 32, 1, -2, 6 },
- { 1,-38, -1,-20, -2, -3, -6, -4, 2, 2, 7, 0, 3, 5, 3, 10,
- 6, 1, -3, -5, 7, 5, -5, -4, 8, 3, 1,-14, -1, -9, -5, -4 },
- { -5,-26, -7,-19,-10, -5,-11, 5,-11,-25, -8,-14, -9,-16, -8, -6,
- -17,-14, -1, -1, 6, 2, 2, 2, 3, 0, 2, 8, -8, 3, 0, -3 },
- { 17,-49, -3,-23, -1, 11, 7, 3, 4, -4, 0, 0, -1, 4, 2, 4,
- -2, -4, 2, -2, -1, -2, 2, 0, 0, -1, 0, 0, 1, 2, 0, 0 },
- { 4,-34, -6, -9, 1, 21, -7, 3, -2, -1, -3, 18, 2,-16, 7, -3,
- 8, 7, -5, 7, 2, 4, 8, -6, -7, -2, -5, -1, 4, 1, 2, -4 },
- { 5,-29, 13, -2,-14, 3, 1, 18,-15, 4, -8, 8,-10, 8, 2, 1,
- -8, 15, 3,-10, -4, -4, -2, 0, -3, -4, 2, -3, -4, -3, 12, -6 },
- { 13,-20, 3,-18,-17, 4,-14, 13, 28, 11, -8, -6, 16, 6, 0, 10,
- 3, 4, -9, 13, 5, -7, 12, -5, 0, -7, 5, 1, 3, 3, 2, 1 },
- { 3,-27, -5,-11,-21,-11,-12, 0, -5, 7,-22, 1, 3, 5, 0, -5,
- 8, 7, 1, -5, -7, 2, -5, 4, 1, 3, -8, -2, 0, 4, -2, 6 },
- { 31,-45, 0, -1,-12, 1, 2, -6, 4, 3, -1, 3, 3, 0, 5, 3,
- -5, 12, 4, 6, 2, 1, -2, 1, 3, 2, 5, 2, 2, 2, 3, -1 },
- { 9,-45, 6, 5, -1,-17, -2, 18, -3, 2, 0, 1, 0, -1, 10, 8,
- -7, -2, -5, -8, 6, -1, 0, 4, 6, -3, 12, -1, -2, 0, 5, -7 },
- { 3,-26, -2,-12,-12, 2,-10, 16, -3, 12, 4, 5, 11, 8,-16,-17,
- -2, -3, -3, 2, 5, -9, 13, 1, 10, 11, 3, 5, -2, 2, 2, -7 },
- { 8,-26, 32, -7, -5, 22, 2, 14,-10, -8, -7, 3, 3, 7, 0, -5,
- 0, -1, -3, 0, 8, 4, -5, -7, 6, -1, 4, 8, 1, 1, 7, -6 },
- { 4,-31, 2,-14, 2, 0, 1, 8, -6, -1, 17, -3, 13, -6, 5,-10,
- -2,-10, -2,-10, -3, 7, 1, 5, -8, 8,-14, -3,-15, 7,-10, -6 },
- { 16,-27, 13, -4,-23, 7, -9, 6, -7, 5, 4, 2, -1, -3, 23,-18,
- 7, 0, -3, 4, -3, 9, -6, -2, -1, 8, -6, 2, 6, -3, 2, -2 },
- { -1,-35, -2, -8, 11, -1, -7, -3, -2, 11, 7, 6, -6,-10, 9, 6,
- -3, -5, -6, -3, 9, 16,-16, -9,-20, 12, 3, 5, -3, 1, -9, 4 },
- { 2,-24, 1,-12,-16, 5, -4, 3, -4, -1,-11,-11, -8,-14, 14, 10,
- -8, 20, 8, -3,-11, 1, 1, -4, -4, -7, -3, 15, 2, -6, -2, 7 },
- { 9,-21, 2,-19, -7, -5, -8, 25, 3, 17, 5, -3, 9,-12, 8, 2,
- -4, 3, 3, 1, 11, -9, -4, -3, 4, 3,-22, 6, 4, 6, 11, -5 },
- { 16,-23, 13,-17,-21,-12, 5, 9,-20, 7, 6, -6, 0, 2, -9, 6,
- -6,-13, -7, -1, 5, -3, 5, -7,-10, 1, 0, 8, -9, 11, 0, -8 },
- { 10,-26, -9, -7,-19, -4, 6, 16, -7, 5, -4, 4, 8, 0, 4, -1,
- 6, -7, 1, -8,-11, 10,-14, 0,-16, 6, -3, 5, -1, 14, 12, 1 },
- { 8,-27, 12,-14, -1, -1,-19, 10,-11, 21,-14, 9, -8, -3, 8, -1,
- 12,-13, 3, -4, -2, 0, -9, 0, -7, 2, -3, 12, 1, -3, 3, 1 },
- { 18,-20,-14,-14,-16, -3,-24, 6,-17, 2, -3,-11, 2, -3, 12, 10,
- 10, 1, 10, 7, 8, 5, 5, 4, -1, 7, 2, 2, 0, 4, 7, 0 },
- { 0,-30, 9,-16,-18, 15, 12, -3, 4, -4, -5,-11, -4,-12,-10, 0,
- 2, -2, -4, -1, 2, 0, -1, -6, 2, -3, 4, -5, 7, 3, 5, 7 },
- { 25,-24, -1, -6, -9, 6,-13, -2, 3, 15, -3, 11, 4, -8,-11, 2,
- 0, -9, -2, 7, 4, 8, 5, -8, 5, 6, -1,-11,-15, -5, 0, 11 },
- { 0,-34, -7,-11, -7, 9, -3, 19, 4, -8, 3,-11, 11, -3, -9, 12,
- 9, 9, 2, 1, -7, 1, -3, 0, -6, -2, -1, 3, 0, -7, -2, -5 },
- { 6,-34, -4, -5, -3, -9, 2, 9, -1, 9, -5, -3,-26,-12, 8, -6,
- -7, 11, -8, 4, 4, 1, -1, 0, 8, 9, -4, 7, -1, 1, -3, -1 },
- { 3,-30, 5, 6,-10, 3, -7, 6, 3, 3,-26,-19, -3, 1, 7, 5,
- -4, -5, 6, 10, 13,-10, 4, -7, -4, 5, -3, 9, -6, 3, 9, 5 },
- { 4,-24, 9,-19, 2, -4, -5, 8, -3, 2, 0,-15, -1, 9, -4, 22,
- 6, 9, 3, 7, 11, -9, 0, -3, 4, 5, -5, 10, -8, 5, -7, -3 },
- { 8,-27, 7, -3, -1, 2, -9, 13, 7, 12, -4, -6, -6, 5, 0, 7,
- 5, 1, 15, -3, -4, 0, -5, -2, 7, -5, -7, 1, -2, 13, -8, 13 },
- { 17,-22,-15,-11, -8, 16,-14, 18, 2, -1, 14, -7, 14, -6, -6, -7,
- -8, 17, 6, 4, 4, -7, -5, -9,-14, -6, -1, 9, -3, 1, 6, -5 },
- { 25,-30, 2,-12,-13, 18,-18, 16, 8, -3, 10, -8, -3, -1, -6, 3,
- -5, -7, 4, 6, 7, 1, 1,-11, -5, 6, 2, -4, 9, -1, -5, -2 },
- { 7,-23, 7,-15, -1, -3, -1, 0,-10, 12, 2, 5, -4, 0, 4, 6,
- -1, 5, -9, -1, -1, -7, 1, 17, 9,-17,-16, 8, 4,-14, 11, 14 },
- { 0,-31, 7,-13, 3,-11, -7, 6, 1,-11, 8, -7, 15, -3, 16,-11,
- -1,-15, 16, -3, 5, 0, -2, -2, -6, 11, 5, 6, 5, -5, 6, 3 },
- { 13,-24, -2,-20,-10, 7, -3, -1, 15, 2, 6, -5, -7,-10,-20, 1,
- -4, 14, 8, -2, 3,-13, -3, 1, -4, 1, -3, 2, 8, -7, 16, -4 },
- { 1, -2, -2, -3, -4, -7, 0, 3, 6, 7, 3, 2, 1, -2, -1, 0,
- -6, 4, 2, -4, -3, -4, 5, 9, 5, 0, -3, -3, -4, -7,-31,-50 },
- { -1, -3, 7, 2, -1, 2, 4, 6, 0, 10, -2, 0,-20, -6, -3, 9,
- -20,-22, -1, -1, 15, 9,-12, 10,-13,-20, 12, 3, 5, 6, -7,-26 },
- { 0, 4, -2,-14,-12, 6,-13, 11,-10, 3, 22, 6, 16, -2, -5, 1,
- -3,-11, 0, -7, 5, -5, 0, 1, -1, -6, 8, 8, 10, 9, -5,-27 },
- { -5, 10, -2, 7, 9, -9, 5, -9, 5, 4,-15, 14, 1, 3,-10, 5,
- 0, -2, 7, 3,-13, 6, 9, -6, 5,-14,-17, -1, 11, 14, -2,-26 },
- { 0, 6, -3, 0, -8, 6, 0, 1, 4, -8, 2, -5, 4, 7, 15, 11,
- 9, 19, -2, 14, -8, 7, -1, 3, -3, -3,-10, -2, 12, -2,-12,-29 },
- {-12, -5, 0, -3, -2, 6, 3, -3, 2, -2, 1, 11, 2, -7, 5, 1,
- 2, -2,-14, 0, -1, -5, 3, 8,-28,-26, 6, -6, 3, 8,-10,-27 },
- { -1, -3, 6, 2, 4, 15, 1, 0, 2, -2, -2, 13, 3, 6, 0, 6,
- -1, -4, -1, -5, 8, -1, 5, -5,-15, 11, -8, -5, 14, -6,-14,-29 },
- { -5, -6, 0, 1, 0, 6, -3, 2, -5, -1, 5, -3, 2,-10, 3, 4,
- 3, 0, 13, -3, -1, 4, -4, -6, 2, 9, 8, 2, -3, 28,-11,-31 },
- { 1, -4,-10, -9, -4, -3,-15, -6, 1, 5, -3, -6, 5, -6,-22, 27,
- -13, 5, 3, -7, -4, 20, -7,-12, -1,-24, -4,-13, -8,-11,-15,-21 },
- { -6, -4, 19, -6, 2, 11, -6, 1, -3,-10, 9, -9, 12,-10, 2, 1,
- -9, 1, 15, 7, -5, 5,-29,-35, 4,-30, 9, 9, 19, 17, 2,-17 },
- { -3, 3, -3, 1, 2, 5, -1, 5, -2, -3, 1, -3, -8, 3, -4, -2,
- -4, -1, 12, 0, 2, -8, -6, -4, 16, -1,-14, -2, 25, -6,-15,-36 },
- { 0, -1, 3, -4, -4, -1, 7, -4, 8, 0, 10, 9, -4, 1, 10, -1,
- -3,-13, -5, -4, -1, -4, 8, 11, 14, -7, -5, 16, 12, 13, -1,-28 },
- { 1, -2, 2, -3, -8, 10, 4, 9, 12, 3, 5, 0, 8, -3, -6, 2,
- 16,-11, 11, 0, 1, 6, 1, 18,-10,-16, -1, -4, 5,-14,-15,-20 },
- { 1,-12, 5, 4, -7, 8, -1,-17, -2, -9,-14,-11, 6, -9, 5, -4,
- 3, -2, 7, 18, -5, 5, 6, -1,-11, -2,-10, -3, 8, -3, -2,-32 },
- {-12, 5, 20, -5, -6,-11, -6, -6,-13, 4, -6, 19, -8, 2, 3, -9,
- -4, -4, -1, 9, -1, 21, -1, 7, 15,-10, -1, -3, 9, -3, 2,-24 },
- { 0, -3, 2, -6, 4, -1, -9, -2, -1, -3, 6, -1, -5, -6, -5, -8,
- 0, -2, -6, 9, -4, 3, 2,-13, 1, -7, 23,-13, 4, -3,-15,-33 },
- { -7, 2,-15, 11,-10, 14, 0,-11, 3, -1, 12, -4, -4, 9, 11,-13,
- -13, -3,-14, 1, 3, 6, -5, 8, 0, 5, 5,-10, 4, 5, -6,-30 },
- { -6, 4, 0, -5, 4, 1, -1, -1, 3, 6, 5, -2, -5, 0, -2, 5,
- -4, -2, -4, -2, 4, 7, -7, -1, 1, -4, -3,-19, 37, 12, 10,-40 },
- { -7, 2, -7,-12, 17, 11, -7, 2, 2, 3, 1, -1, 3, 4, -2, -5,
- 9, -9, 6, 4, 9, 12, 11, -5, 2, -1, 0, 9, 5, -7, -2,-24 },
- { -7, 6, 1, 3, 1, 0, 6, 0, 4,-12, -2, -2, 1, -9, 10, -2,
- 11, -1, 21,-12, 15, -5, 10, -5, 5, -5, 14, -6, 5, -7, -3,-29 },
- { -2, 0, -5, -2, -3, 1, -3, 0, 4, 2, 3, 0, 2, -2, 7, -2,
- 3, -5, 2, -1, 6, -4, 0, -3, 8,-11, 19, -8, 22,-34, 13,-35 },
- { -1, -3, -1, 9, 11, -3, -3, -1, 7, 18, 11, -5, 2,-12,-11, 18,
- 9, -5, 1, -6, -9, 12, 1, -3, -3, -9,-14, 9, 9, 8, -6,-26 },
- { 0, 5, -5, -1, -1, -2, 4, 6, 8, 2, -1, -2, 5, 1, -5, -4,
- 1, 1, 18, 1, 7,-10, 3, -2, 12, -1,-15, 9, 12,-14, 13,-38 },
- { 3, 0, -8, -1, 0, 8, -9, -3, -8, 16, 3, 16, -5, -9, 0, -1,
- -7, -1, -4, 13, 7, 0, 1, 2, -1,-16, 0, -2, 1, 8, -8,-28 },
- { 7, 9, -5, -3, -2, 2, 0, 3, 11, -6, -4, -2, -2, -5, 28,-18,
- -6, 2, 15,-10,-15,-10, -2, 0, -2, -2, 4, -3, 7, 11, 5,-30 },
- { 9, 0, -7, -1, -4, -7, 2, 2, 9, -2, 2, 3, -8, -6, -6, 3,
- -10, 4, 10, 5, 21, -4, 14,-18, 1, 3,-10, -2, 6, 14, -8,-26 },
- {-14, -1, 2, 3, -3, 7, 1,-22, -1, -1, 0, 1, 12,-14, 3, -5,
- 0, 10, -3, 1, -5, 12, -3, 10, -8,-22,-11,-13, -7,-10,-13,-25 },
- { -2, -5, -4, -4, -9,-18, 9, -3, -5, 17, 13, 5, 6, 11, 3, 8,
- 20, 4, 2, 9, 8, 5, 6, 1, 7, -7, -6, -2, -7, 0,-17,-23 },
- { -5, -5, 2, 0, 6, 2, -2, 2, -3, 4, 4, 0, -5, -2, -4, 6,
- 8, 10, -1, 1, -5, 5,-14, -2,-11, 8, 6, 25, 7, -1, 0,-43 },
- { -4, 0, 4, -2, 7, 0, 3, 17, 5, 2, -5, 1, 21, 3, -2,-10,
- -16, -9, 7,-12, 9, -8, 2, 5, -5,-10, -2,-11, -5, -1, -9,-30 },
- { -2, 3, 1, -4, -1, 0, 8, 1, 12, 4, -1, -1, 3,-17, 13, 9,
- 0, 7, -6, -5, 9, 1, 5, 4,-10,-18, 0, 14, 11, -4,-16,-28 },
- { -1, 0, 2, -1, 4, 1, -1, 1, -1, -2, -1, -2, 3, 0, 0, -1,
- -1, 1, 2, -2, 3, 3, -2, 4, -2, -1, -6, 1, -1, -1, 6,-70 },
- { 7, 3,-11, -1, 12, -4,-14, 4, 4, -4, 4, -2, 2,-12, -4, 15,
- -17, -4, -3, 6, 8, -5, 22,-22, 5,-11, 15, -4, 4, -1,-21, -1 },
- { 10, -2,-13, 11, 4, 14, 4, 9, 8, 8, 19, 15, 14, 15, 5, 10,
- 8, 15, -5, 4, 14, -8, 1, 1, 2, 1, -1, -3, 21, 8,-29, 13 },
- { -6, 0, -6, 6, -1, 2, 8, -4, -5, 4, -4, -5, 0, -2, -4, 0,
- 9, -2, 1, -2, 26,-19, 21,-10, 4, 1, -8, 5, 22,-10,-13, 15 },
- { 11, -5, 1, 0, 6, 3, 7, -2, -2, -3, -5, -1, -2, -6, 1, 1,
- -8, -5,-13, 13, -2, -3, -1, -9,-28, 4, 2,-11, 18,-20,-24, 9 },
- { 7, 4, -3, 6, 6, -6, -7, -5, -7, -4, -4, 0, -7, -5, -6, -5,
- 2,-13,-12, 2, 0, 5, 18, 15,-13, -7, 13,-20, 16,-10,-19, 6 },
- { 5, -8, -1, 5, 10, 2, -1,-10,-11, 23, 8, -5, -8, 4, -5, -4,
- -5, -5,-11, -8, 5, 1, 7, -9, -9, -6, 12, 14, 17,-12,-22, 3 },
- { -5, -8, -3, 3, 12, -1, 0, -4, -5, 1, 1, 6, 1, 5, -5, 7,
- -2, 7, 1, 6, 6, 2, 0, -5, 17, -4, -5,-24, 13,-20,-27, 14 },
- { -1, 2, -3, 1, -3, 1, -3, 0, -2, 3, -2, 1, 2, -1, -2, -1,
- -2, -5, 5, -2, 0, -7, 1, -6, 8, 8, 11, -5, 24,-43,-13, 2 },
- { -2, 4, 7, -3, -4, 4, 13, -4, 0, 0, -2, 9, 0, -3, -6, 1,
- -7, 1, -1, 10, 0, 5, -1,-24, 25,-15, 7, 2, 22,-10,-21, 0 },
- { -5, 2, 6, -2, 13, 3, 5,-12,-11, 16, 6, 10, -5, 0, -3, 6,
- 5, -5, -5, 10, 12, 10, 11, -7, 8,-14, 2,-15, 13,-14, -8, -3 },
- { 5, 6, -7, -5, 5, 2, 9, 5, 0, -1, -4, 2, 8, 0, 3, 5,
- -12, 3, -3, -6, 2, -1, -5, 14, 11,-20,-21,-25, 24, -1,-10, 6 },
- { -5, 5, -2, 9, 4, -4, -1, -6, 11, -6, 5, 0, 2, -3, 6, -1,
- -17,-18, -4,-13, 9, -1, 9, -7, -4, -8, 2, -3, 12,-31,-18, 5 },
- { -7,-11, 6, -8, 4, -3,-12, 0, -1, -6, -3, 0, 5, 9, 7, 2,
- 1, -8, -6, 8, 2, -5, 7, -1, 16,-10, 16,-12, 18, -1,-25,-12 },
- { 3,-12, 1, 2, -2,-18, -8,-15,-10, -9, 2, -7, 11,-11, 2, -1,
- -1, -1, -9, -6, 3,-14, -2, -1, 2,-13, -7, -9, 19, -5,-17, 2 },
- { 7, 1, -8, 7, 17,-13,-10, 5, 7, 1, -6, 4, 9, -4, 0, 3,
- 8, 1,-14, -9, 4, 7, -9, 0, 6, -5,-12, -2, 25, -2,-19, 1 },
- { 7, -3, 6, -3, 1, 6, -7, 0, 10, 0, 4, -5,-17, -4, 4, -1,
- 0, -3, -7, 19, 24, -1, 21, 8, 10, 9, 8, -1, 23, -2,-18, -2 },
- { 3, -3, 0, 5, 8, -2, -9, 2, 9, 6, 19, 8, 2, 6, -9, -2,
- -4, -3, -8, 7, -7, -8, 5, 4, 26, -6, 7, 18, 24, 0,-13, 4 },
- { 0,-13,-11, -1, 3, -9, 5, 4, -7, 3, 0, 2, -1, 4, -5, 2,
- 9, -2,-11, 15, 1,-21, 1, -1, 0, 4,-14, -4, 24,-16,-13, 1 },
- { 1, -9, -8, 0, 0, -4, 11, -1, 14, 16, 0, 17, -2, -9,-12, 0,
- -1,-14, -9,-14, 0, -2, 19, 4, 6, 4, 4,-11, 8,-17,-19, -5 },
- { -3, 1, 2, 12, -4,-18, -1, -4, -7, 14, -3, 2, 0, -7, -8, 12,
- -5, -9, 14, 12, -9, -2, 4, -6, 4, 18, -1,-25, 22, 2,-23, -5 },
- { -2, 0, 0, 0, 1, 3, 5, -1, 5, -2, -2, 2, -3, 0, 1, 2,
- 0, -1, 2, -1, -9, -6, -7, -4, -2, 4, -7, -5, 64, -3,-25, 4 },
- { 12, -2, -3, 0, 8, -9, 13, -7, 6, -3,-12, 12, 15, -9, -4, 2,
- 9, -4,-12, 3, 14, 1, 7,-15, 15, 0, -6,-12, 0, -3,-20, 6 },
- { 2, -1, -4, 5, 9, 6, -7, 2, -2, -7, -2, 0, -1,-18, -4, -6,
- -15, -5, 11, 5,-10, -1, 2, 7, 12,-19, -7, 8, 21, -4,-15, 4 },
- { 4, 2, 5, 5, -5, 1, 3, 2, -8, 13, 0, -5, -2,-14,-11, 6,
- 2, 17, 8,-13, 26, -2, 5,-15, -4,-14, 12, -9, 13,-21,-23, -4 },
- { 2, -3, -2, -3, 3, -2, 6, 9, -9, 13, 4, 2, 12, -3, -3, 1,
- -17,-22, -3, 4, 3, -2, 1, -9, 1, -6, 11,-13, 14, 0,-15, 6 },
- {-16, -4, 17, -2,-20,-11, 11, 10, 5, -8, 16, 2,-17,-14, 11, 11,
- -6,-11, -7, 12, 12,-10, -6, 5, 8, -4, -2, -5, 28, 3,-13, 4 },
- { 0, -3, 3, -7, 6, 8,-12, 20,-19, 18,-11, 10, -5, 0, -9, 11,
- 3, 0, -2, 9, -7, -5, 18, 3, -2,-16, 1, 6, 12, -7,-16, 1 },
- { 4, 1, 5, -5, 15, 2, -8, 3, 5,-11, 15, -3, 8, -8, -1, 7,
- 4, 7, -2, 6, -9, 5, 12, 2, 33, -2, -6,-18, 4, 0,-18, 11 },
- { 3, -1, 1, -1, 0, 1, 4, -1, -5, 0, 1, 0, 4, 2, -1, 4,
- -3, 2, 0, -2, 4, 6, -1, 6, 42, 19, -4,-37, 19, 1,-15, -4 },
- { 2, 0, -5, 0, 10, 0, 0, -5, 3, 0, 0, -3, -3, 0, 2, -4,
- -10, 2, -6, 4, 4, 1, 27, -7, 17,-34, 5, -9, 15,-16, -7, -5 },
- { -2, 7, 7, -2, 9, -2,-15, 11, 11, 7, 5, 1, 15, 1, -9, 31,
- 2,-15, 2, 4, 3, 4, -1, -8, 2, -7, 6,-17, 11,-14,-11, 2 },
- { 1, 1,-11, 9, 9, -6,-14,-11,-10, 8, -3, 11, 16, -9, -8,-13,
- -8, 9, 0, 6, 6, -2, 13, -8, -2, 3, 13, -3, 10, -6,-17, 4 },
- { 14, 5, 4, -6,-12, 10, -7, 8, 21, -8,-30, 15, -2, 1, 11, -9,
- -5, 1, 0, -1, -1, -6, -2, 3, -5, 7, 9, 5, -5, 2, 0, 1 },
- { -1, 2, 20,-17,-15, 3, 3, 7, 11,-17,-13, -6, -3, 18, 17,-15,
- -4, -4, -5, 22, 14,-14, -2,-10, -7, 11, 8, -7, -3, 0, -7, 11 },
- { 7,-11, -7, -8,-14, 22, 5, 2, 6, 13,-12, -2, 10, 3, 0,-21,
- -4, 20, 3, 10, 21,-10,-12, 8, 11, 2, -5, 2, 1, 3, -1, 15 },
- { -1, -2, -1, -2,-13, 8, -4, 0, 7, -2,-17, 8, 18, 5, 3, 8,
- -8, -2, 3, -4, 14,-18,-13, 14, 15,-13, -1, -2, 4, 11, 1, 12 },
- { 13, -6, -4,-16,-17, 16, 21, -2, 5,-11, -9, 19, 21,-17, -3,-17,
- 3, 12, 8,-12, -6, 1, -7, 9, 9, -7, -5, -1, -3, 5, -6, -4 },
- { 11, 5, 12,-20, -6, 10, 4, 12, 8, -5,-10, 15, 13, 14, 10,-15,
- -13, 1, 6, 14, 15,-17,-13, 4, -5, 10, 7, -6, -8, -3, -4, 12 },
- { 25, -1, 7, -5, -7, 11, 1, 17, 13,-15,-14, -4, 5, 3, 8, -3,
- -2, 2, 0, 6, 16,-12, -6, -4, 4, -3, 7,-10, -3, -7,-13, 7 },
- { -8, 10, -3,-13, 5, 2, 4, 9, 9,-17,-13, 2, 11, 1, 6, -4,
- 8,-10, 4, 1, 19,-15, -4, 12, 31, 7, -5,-17, -4, 9, -2, 7 },
- { 14, -6, -6, -6,-14, 13, 17, -5, 4,-14, -9, 7, 7, -9, 3,-16,
- -15, 11, 11, 6, 4,-11,-19, 3, 5, 8, 13,-14,-14, 3, -4, 12 },
- { -2, -4, 10, -4, -7, -1, 27, 5, 2,-16,-18, 4, 12, -2, -3, -2,
- -1, 1, -8,-12, 3, -4, 8, 15, 2, 4, 9,-13,-14, 9, -7, 5 },
- { 4, 2,-10, -5, -7, 2, 1, 4, -1, -6,-15, 6, 1, 10, 5,-10,
- -9, -1, 13, -3, 5,-21,-11, 8, 8, 5, 27,-21,-18, -5, -1, 15 },
- { 11, 1,-16, -8,-11, 0, 5, -8,-12,-13,-17, 22, 4, -6, -1,-18,
- -10, 0, 19, 2, -2, -8, -7, -3, 2, -2, -9,-17, -5, 4, 4, 10 },
- { 8, -6,-19, -5, -4, 12, 14, 15, 10, -9, -1, -9, 19, 12, 0, -1,
- 2, 4, 7, 9, 16,-16,-14, 9, -4, 3, 1, 0, -2, 10, -1, -1 },
- { 12, -8, 12, -9, 0, 25, 7, 9, 2,-31, -9, -4, 15, 4, -5, 1,
- -10, 11, 8, 10, 0, -6, 5, 11, -1, -6, 4,-10, -9, 6, 4, 5 },
- { 14, 6,-17, -2, 17, 12, -9, 2, 0,-25,-14, 5, 20, 14, 8,-20,
- 5, 2, -2, -3, 9,-13, -3, -1, -6, 3, 7, -6, 0, 2, 3, 1 },
- { 8, 4,-15, -3, 10, 18, -4, 13, 8,-22,-10, 9, 19,-15, 7, -5,
- -13, 12, -4, 9, 2, -9, -6, 0, 2, 1, -9, -6, 6, 1, -1, 11 },
- { 4, 1, 4, -5,-10, 18, 7, 2, -4, -9,-11, 0, 32, -7, 4,-16,
- -1, 0, 6, 3, 6, -3,-14, 16, 9, -2, 7, -1, 0, -5, 5, -3 },
- { -3, 2, 3, -8, -6, 4, 6, 2, 4,-12,-15, 2, 8, 8, 9, -3,
- -18, 6, 34, 11, 12,-15, -1, 2, 9, 2, -4, -4, 2, 4, 2, -3 },
- { 18, -6,-12, -8, -1, 15, 20, -4, -1,-11, -5, 6, 6,-11,-15, -7,
- 3, 7, 10, 2, 8,-10, -5, 8, 15, -5, 5,-17,-13, 13, 11, 7 },
- { 8, -4, -6, -1,-14, -3, 6, -2, 1, -5, -1, 10, 10,-15, 5, 0,
- -10, -4, -3, 7, -4,-19,-15, 27, 11, 18, 3,-19, -2, 6, 0, 12 },
- { 12, 0, -5, 0, 4, -5, 1, 5, 10, -7,-11, 21, 29, 1, -2, 1,
- -4,-11, -1, 13, 11,-20, -1, 4, 4, 4, -5, 6,-13, -2, 11, 9 },
- { 2, -7, -7, -3,-10, -1, 20, 12, 1,-19,-19, -1, 5, 4, -7,-25,
- 14, 1, -3, 2, 12, -4, -3, -3, -2, 6, 1, 0, 3, 2, 5, -1 },
- { 12, -8, 3,-12,-10, 10, 13, 0, 23,-14,-18, 10, 0, 15, 3,-12,
- -3, -5, 5, -4, 2,-14,-10, 8, 2, 9, -1,-11, -3, 5, 13, 2 },
- { 9, -6, 7, -7,-30, 17, 6, 13, 1,-14, 0, -1, 6, -9, 8, 3,
- -4, 0, -1, -7, -5,-13,-19, -3, -4, 4, -6, -2,-13, 1, -2, 3 },
- { 10, 1, 3,-18,-26, 17, 4,-16, 4, -3,-13, -4, -6,-11, -4,-21,
- 7, 8, 2, 5, 13, -6, 1, 5, 8, 7, 9, -6, -6, 1, -1, 2 },
- { -3, -1, 0, -2, -2, 0, -1, 3, 4,-14, -8, -9, 13, 2, 50,-23,
- -8, 8, 7, 11, 16, 3, -7, 0, -2, 6, 5, -1, 1, -2, 4, 3 },
- { 1, 3, 1, 1, -6, 3, 6, 6, 2, -2, -3, 10, 2, -8, -5, -5,
- 5, 4, 4, -2, 10, -8,-40, -1, 21, 8, 3, -4, -1, 13, 4, 7 },
- { 2, 0, -4, -8, 5, 2, 7, -5, 5, -8, -4, -1, 12, 2, 12,-13,
- -9, 0, 1,-12, 9,-43, 1, -5, 12, 1, 3, 6, 1, -1, 3, -2 },
- { 6, -2, -1, 1, 0, 4, 8, 14, 4, -7,-23, -5, 23,-17, -6,-15,
- -8, 7, 10, -1, 7,-16, 4, -6, 2, 3, -3, -3, -1, 8, -1, 4 },
- { 10, 4, -4, 1, 7, -3, 2, 11, 4, -6, -3, 8, 5, 4, 1,-45,
- -6, -4, 4, 2, 1,-14,-10, 1, 1, 6, 2, -8, -1, -3, 3, 3 },
- { 1, -1, 2, -3, -8, 9, 3, 3, -2, -5, -8, 8, 7, -7, -4, -6,
- 5, -9, 11, -2, 46, -5, -1, 9, -2, 0, 3, -5, -3, -5, 7, 0 },
- { -4, 1, -2, -1,-11, 11, 8, -3, -2,-10, 0, 4, 9, 9,-17,-17,
- -34, -4, -5, -7, -3,-12, -3, 11, 18, 3, -2, -5,-18, -5, -3, 6 },
- { 7, -5, -3, 1, -4, -3, -5, -1, 2, 5, -2, 3,-10, 12,-18, -5,
- -10, 12, -9, 4, -6, 2, 0, 16,-17, 15, 14,-12,-10, -2, -9, -1 },
- { 4, -5, -3, -5, -3, -1, 7, 18, -7, 12, 3, 5, -8, -4,-20, 1,
- -25, 1, -8, 13,-10, 8,-19, -1, -8, 10, 6, -9, -1, 0, 12, 4 },
- { -4, 5, 0, -1, 2, 5, -8, -2, -6, 4, -8, 9, 3, 2, -7, 4,
- -25, 13,-23, 10, 14, 15,-11, 3,-18, 4, 16, -4, 1,-10,-10, 3 },
- { 5, -3, -1, -3, 4, 1, -3, -4, -5, 1,-12, 14, -7, 11,-15, 6,
- -6, 24, -4, 13, -1, 15,-13, 8, 3, 7, -5, 2, 2, 0, 3, -7 },
- { -3, 1, 0, 8, 6, -1, 6, 5, -5, -2,-12, 4, 0, -2, -3, 5,
- -6, 0, -8, 9,-10, 4,-28, 12,-20, 11,-13, 7,-18, 1,-11, 1 },
- { 1, -4,-15, 5, 0,-13, -5, 13,-11, 4, -4, -5, 5,-14,-16, 0,
- -14, 5,-20, 12, 10, -7, -5, 6, 6, 22, 6, -4, -2, 3, 8, 11 },
- { 13,-11, -2, 16, 16, -7, 0, 20, -7, -1, 0, 5, -9, 12, -2, -5,
- -22, 5,-10, 12, -6, 11, 9, 21, -8, 15, 4, 0, -8, -4, -4, 10 },
- { 18, -4,-13, 0, 1,-15, -1, -3, 2, 10, -1, 6, 1, -4,-20, -5,
- -8, 6, -8, 17, -5, 5,-10, 8,-22, 6, -5, -2, 8,-17, 8, 2 },
- { 1, -2, -9, 6,-31, -8, -8, 8, 0, 5, -9, -4, 2, 3,-12, 11,
- -18, 10, -5, 3,-11, 13, -6, 11, -3, 12, -7, 3, -9, -1, 2, 11 },
- { -9, -6, 21, -8,-15, 4,-11, 12,-11, 17, -1, 2, -6, 0,-15, 13,
- -12, 19, 0, 2, -6, -3, -9, 10, 3, 17, -2, 5,-10, -3, 0, 1 },
- { 4, -6, 5,-10, 1, -5, 1, 0, 0, 0, 2, 7, -2, 2, -2, 0,
- -4, 3, -4, 1,-12, 6,-49, 16,-10, 13, 0, -2, 8, 6, 1, 8 },
- { 5, -8, -7, 9, 13, -5, 7, 0, 10, 11, -4, -3, -1, 13,-14, 6,
- -15, -6,-14, 16, 15, 1,-18, -4,-20, 20, -7, -1, -9, -2,-10, 10 },
- {-12, 4, 0, 10, 0, 3, 8, 4,-27, -1, -2, 19, -4, 2,-13, 3,
- 1, 9,-12, 1,-22, 19, -5, 4, -9, 12, 2, -9, -8, 11, -3, 7 },
- { 4, -5, 11, -6, 17,-17, 5, -4, -2, -6, 1, -5, 2, 4,-14, 6,
- -20, 19,-20, 12,-21, 5,-14, 13, -2, 11, 4, -3, 0,-10, -4, -2 },
- { -2, -1, -3, 8, -9, -7,-22, -3,-24, 13, -2, 10,-15, 5, -9, 4,
- -7, 0, -5, 15, -8, 11,-13, 6, -4, 19, -8, 12, -4, 6, 9, 7 },
- { 2, -3, 2, -1, 0, 3, 1, 2, 1, -4, -2, -3, 1, 5,-12, 6,
- -16, 14,-23, 10,-14, 17,-15, 16, -2, 9,-25, 9,-10, 16, 4, 9 },
- { -3, 7, -8, -3, 2, 2, -4, -8, -9, 10, 3,-11, 25,-10,-28, 27,
- -9, 7,-13, 9, -2, 4,-12, -8,-14, 6, 7,-10, 3, 3, -3, 5 },
- { -8, -3, 1,-10, 8, -3, -9, -4, 13, 7, 2, 4,-10, 4, 3, 7,
- -18, 2,-22, 15, 4, 20, -7, 5, -6, 13, -1, 4, -7, -6, 6, 13 },
- { -2, 3, 0, 2, -4, -2, 0, 0, 1, 2, -2, -5, 0, 1, -4, 0,
- -2, -3, 1, 2, -1, 2, -8, -1,-24, 68, -3, 8, 3, 3, -1, -1 },
- {-15, -2, -9, -7, -1, 8,-14, 8, 3, 6, 0, -1, -8, 8,-23, 2,
- -14, 17,-15, 8, -4, 7,-18, 0, -8, -3, -1, -4,-10, 4, -1, 4 },
- { 8, 0, 2, -7, 0, 5, 1, 3,-11, 4, -8, 14, 3, 20, 1, 26,
- -11, 13,-13, 20, -2, 0, -8, 2, -6, 6, -1, 9, 3, -6, -3, 10 },
- { 5, 0, -1, -7, 10, 1, -3, 5, 4, 7, -5, -1, -3, -1, 12, -3,
- -15, 7, -9, 22,-19, 8, -9, 4,-23, 13,-14, 6, -6,-14, -4, 7 },
- { 14, -5, -8,-10, 25, 3,-23, -7,-28, 0, -1, -9, 4, 1,-13, 20,
- -8, 10,-16, 8, 12,-13,-21, 5,-13, 11, -2, 1, 12, -7, 2,-10 },
- { -5, -4, 9, 5, -6, 35, -7, 8, 15, 2, -1, -9, -6, 2,-18, 7,
- -15, 6, -3, 2, 8, 12,-30, 7, -4, 20, 2, 6, 13, -6, -4, 0 },
- { 1, 8, -9, 9, -5, 12, -9, 16, -9, 16,-17, 14,-13, 15,-18, 14,
- -15, 17,-12, 14,-13, 7,-16, 13, -9, 5,-11, 10, -9, 6,-12, 13 },
- {-10, -4, 5, 3, 1, 6, 8,-14, -5, 15, 7, 4, 8, 7,-22, 8,
- -7, -8,-15, 26, 1, 13, -3, 17, -5, 9, -2, 4, -6, 3, -8, 9 },
- { 8, -3, 2, 3, 3, 1, -2, -1,-11, 8, -4, 0, -6, -5, -1, 13,
- -37, 9, 1, -6,-10, -2,-10, 11, 8, 13, -3, -2, -6, 8, -4, 13 },
- { 3, 2, -3, -4, -4, 7, -8, 9, -8, 9,-20, 12,-19, 15,-18, 17,
- -15, 7, -1, 20,-11, 6, -6, 3, 1, 9, 2,-14, -2, -2, 2, 1 },
- { -7, 1, -1, -3, -6, 4, 4, -3, 3, -1, 5, -4, 3, 2, -1, 9,
- -59, 5, -4, 30, 3, 3, -2, -3, -1, 2, 2, 1, -1, -1, -2, 1 },
- { 0, -3, 2, 0, -1, -8, 0, 2, -3, 4, -4, 1, 10, 6, -6, 8,
- -7, 4, 10, 11,-41, 27,-20, 3, -3, 8, 1, 11, -5, -8, 0, 4 },
- { 5, 1, 4, -2, 1, 2, -1, 6, -7, 2, 11, 4, 0, 0, -8, 7,
- -10, 0, 0, 8, 2, 10, -1, 1, -2, 44, -2,-21,-12, -3, -1, 2 },
- { -4, 4, -2, -2, 6, -8, 2, 1,-10, 14, 8, 6, 5, 1, -2, 4,
- -13, 4, 2, 5, 10, -2,-21, 32, -3, 18, 9, -6, -9, -9, 10, 2 },
- { 9,-16, -6, -2, 1, 4, 22, 2, -2, 1, -3, -2, -9, 3, 16, 19,
- -24, -6, -6, -5, -8, -7, 8, -7, -1,-12, 5, -3, 0, 4, 2, -3 },
- { 10, 3,-16, -4, -1, 13, 4, 4, 1, -3, 1, -6,-14, 18, 3, 8,
- -8,-28,-16, 4, 4, 2, 12, 7, 9, -4, -4, 5, -1, -1, 2, 2 },
- { -5,-13,-22, -3, -8, 21, -2, -9, 21, -4, -9, 5, -8, 15, 5, 1,
- -5, -9, -7, -2, -5, -5, -1, -5, -5, -5, 3, 10, -4, 0, -7, -2 },
- { 5,-10,-18, 2, 20, 4, 13,-10, 8,-15,-11, -3, -1, 16, 10, 9,
- -8, 6, 7, -5, 6, 11, 5, 17, -4, 7,-11, 5, -3, -6, 2, 1 },
- { 3, -5,-19, 1, 1, -3, -2,-25,-11,-17, 0,-13, -4, 10, 10, 2,
- -5, 4, 0, 3, -3, -5,-10, -2, 13,-22, 0, 3,-11, -5, 7, -1 },
- { 12,-14,-29, 6, -1, 10, 7,-17,-12, 14, 3, 9, -9, 9, 7, 6,
- -3,-13, 0, 5, 3, -1, -6, -1, 0, 2, 4,-12, -5, -1, 2, 11 },
- { 12,-15, -7, -2,-12, 17, 20,-16, -2,-12, -6, 15, -6, 12, 11, 9,
- 7, -6, 7, -4,-19, 6, 2, 2, 3,-11,-10, -4, -5, -3, 3, 2 },
- { 11,-22, -6, 0, 8, 18, 3,-11, -4, -7,-15,-17,-12, 6, 16, 4,
- -9, 4, -5, 3, 6,-16, 10, -7, -7, -3, 5, 0, 1,-15, -4, 5 },
- { 12,-22,-16, 5, -6, 8, 12, -4, -9,-17,-11, 3, 5, 8,-17, 0,
- 11, -4,-13, -6, 2, -1, -1, 3, 3,-11,-12, -1, 1, 1, 12, -2 },
- { 8,-10,-33, -5, -3, -6, 1, -7, -8, -4, -6, -1, 5, -4, -6,-12,
- -16, -8, 11, 8,-14, 7, 12, 11, 4,-14, -3, 6, -7, -5, -3, 3 },
- { 0, -8, -7, 2, -4, 24, 2, -9,-11, -3, -7, 11,-12, 17, 1, -1,
- 3, -5, -7, 12, 4, 11, 0, 3, 2,-18, -3, 4, 7, -6, 3, 15 },
- { 10,-15,-16, -2, -4, -9, 7,-15, -6, 2,-16, 13, -8, 7, 19,-21,
- -4,-12, -9, -3, -3, 6, 11, -3, -1,-19, 3, -7, -9, -4, 3, -6 },
- { -5,-10,-21, 0, -3, -7, 18,-21, 15, -5,-12, -4,-13, 2, 6, -9,
- -9,-11, -4, 13, -3, 6, 4, -1, 7, -9, -4, 9, 5, 2, 6, 3 },
- { 15, -1,-27, -2, 10, 3, 7, -8, 9, -2, 7, 1, -2, -5, 18, 9,
- -11,-17, -2, 7, -9, 11, 10, 0, -8, 6,-16, -3, 2, -7, 3, 11 },
- { 4, -9,-39, 19, 6,-13, 13, -5, -5,-15, -2, 9, 0, 4, 14, 6,
- -10, -4, -5, 2, -4, -2, 5,-11, 3, 3, -2, -2, -7, 9, 7,-10 },
- { 5,-11, -8, 10, -2, 12, 16, 0, 12, -2, -6, 8, 14, 8, 7, 1,
- 18,-30, 4, 10, -4, -6, 2,-11, 9,-10, -8, 5, 0, 0, -7, 6 },
- { -1,-16,-10, 11, 0, 13, 12, -4, -4, -5,-21, 12, 4, 13, 14, -7,
- 6,-16,-13, 8, 2, 9, 15,-12, 1, -9,-22, 10, -9, 9, 9, -7 },
- { 4,-12,-27, 1, -2, 11, 15, 3, 14,-14, -9, 0, -9, 16, 22, 10,
- 16,-10, 5, -5, -9, 1, 1, 6, 6, -4, 2,-17, -5, -6,-15, -1 },
- { 7,-12,-17, 1, -9, 5, 20, -7, 3, 23, -8, -8, -8, -1, 13, 17,
- -7,-13, 4, -4, 7, 14, 8, 11, -3, -3, 4, 0, 4, 6, -1, -9 },
- { 7,-15,-15, -4, 10, 12, 3,-13, 6, 14, 9, -8,-15, 14, 23, -5,
- -10, -5, 1, 15,-10, -7, 1, 9, 4,-13,-10, 10, 7, -3, 2, 3 },
- { 4,-10,-14, 0, 3, 4, 0, -9, -3, -4,-11, 2,-17, 8, 2, 15,
- 6,-12,-12, 15, -5, 17, 18, 3, -3, -3, -4, -6, -8, 13, 4, 10 },
- { -2,-18,-26, 10, -4, 10, 13, 4, -4,-16, -7,-17, -3, 5, -4, 2,
- -15,-10, -1, -8, -7, -3, 2, 2, 8,-10, -7, 2, 2, -4, 4, -1 },
- { 4,-19, -5, -1, -1, -6, 2, -8, 10,-16,-28, -6, 8, -1, 11, 28,
- 2,-10, -4, 6, -6, 6, 11, 15, -4, -2, 7, 3, 7, -7, 4, 1 },
- { -3, -6,-10, -5, 13, 18, 10,-15, -5, -3,-13, 5, 1, 2, 18, -5,
- -10,-10, -7, 4, 2, 1, 5, 4, 2, 5, 4, 8, -9,-17, 7, 7 },
- { 20,-12, -2, -4, 5, 14, 7,-11, -1,-16, -6, -4,-11, 17, 14, 0,
- -8,-10, -8, 10, 3, 5, 10,-16, 3, -8,-14, 10, 3, 9, 0, 3 },
- { 12,-10,-36, 0, 7, 15, 2,-16, 2, -1, 0, -1, 5, 4, 5, -3,
- 1,-10, 5, -1,-15, -3,-12, 12, 2, 5, -1, 5, 6, -3, -2, 2 },
- { 17,-15,-31, 23, -4, 15, -2, -3, 6, -7, -5, 1,-12, 4, 6, 8,
- -10, 8, 3, 5, -4, 1, 5, 3, -1, -4, -3, 1, 10, -4, -2, -2 },
- { 6,-18, -5, 12, 10, 12, 14,-11, 15, 2, -9, -6, -5, -2, -9, 4,
- -5,-28, -4, 14, 0,-16, 9, 14, -1, 3, -4, -4, 2, 1, 0, 4 },
- { -5,-14,-31, 8, 16, 7, 13,-13, 5, 6,-16, 10, -5, 2, -2, 2,
- 14, -5, 8, -5, 7,-16, 6,-13, -5, 0, -5, 8, -3, -1, 4, 3 },
- { 1, -2, -1, 0, 6, 5, 2, -4, -3, -1, 0, 1, 4, 2, 43, 28,
- -12,-35, -2, -2, -7, -1, 0, 2, -1, -2, -2, 1, -4, 0, -2, 3 },
- { 2, -9,-22, 12, 3, 3, -7, -4,-19,-22,-14, -4, -1, 21, 9, -3,
- -15,-16,-13, 1,-11, 4, -9, 1, -7, -1, -1, 0, -2, 9,-13, -3 },
- { -1, -3,-23, 0, 2, 12, 3, -9, -4, 7, 3, 9,-10, 1, 27, 28,
- 0, 9,-15, -2, -2, 1, 6, 8, -8, 7, -3, 20, 0, 0, -1, -6 },
- { -1, 11, 8, -2, 1, 5, -6, -1, 4, 2, -4, 0, -1, -5, 4, -6,
- -10,-12, 19, 1, -7, 9, -8, -9,-16,-11, -2, 12, 14, 4, 4, 34 },
- { 17, 7, -6, 1, 4,-10, -5, 4,-11, 3,-18, 4, 14,-13, -3, 1,
- 0, 0,-11, 0, 7,-17, -4, 4,-11, -6, -8, 18, 0, 0, 0, 26 },
- { -6, -7, -1, -1, 11, -8, 1, 3, 2, 11, -6, -6, 10, -3, 1, -3,
- 7, 4,-12, -8, 0, -9, 8,-22, -5, 0, -6, 22, -2, 11,-13, 24 },
- { -3, 4, 0, 3, 9, 10, -1, 3, -9,-12, 1, -5, 18, 0, -3, 8,
- 25, 15, -8, 2, 2, -2, 4, 8, 9, -1, -5, 10, -3, 1, -1, 23 },
- { -5, 2, -9, -1, -3, 0, 3, -1,-10, -4, 0,-13, 16, 9, -1,-14,
- 2, 6, -2, -6, -5, -2, -7, 7, 5, 3, 11, -2,-14, 0, -9, 30 },
- { 4, 6, 6, 5, -3, -1, 4, 5, 10, 0, 5, -4, 7,-11, 14, 14,
- 7, 34, -9, 0,-10, 22, -7, -1, 7, -9, 2, -8, 0, -7, -5, 29 },
- { -4, 3, -1, -4, -3, 5, 1, -4, 0, 2, 4, 2, 1, -1,-10, 1,
- 6, -6, -4, 1, 4, -3, -3, -5, 0, 3, 7,-12, 0, -2,-10, 55 },
- { 5, 9, -1, 0, 4, 9,-21, -9, 4, 2, 6, -7, 11, -7, 1, -5,
- 0, -4, 2, -3,-13, -8, 0, -9, -4, 2, 16, -2,-15, -7,-11, 31 },
- { 8, 2, -1, 0, 3, -5, -5, 5, 1, -1, -9, 1, 0, -6, -2, -1,
- 5, 2, 0, 0, 12, 20,-19, 1, 8,-12,-11, 0, 6, -5, 2, 31 },
- { -1, -1, -2, 1, -1, 3, -9, -5, 8, -2, 5, -1, 0, -2, 4, -2,
- -3,-12, 0, -2, 3, 0, 9, 4, -1, 21, -8, 3, -4, 9, -6, 30 },
- { -4, 0, -7, 17, 10,-12, -2,-10,-12, -3, 10, 0, 11, -4,-13, -3,
- 5, 6, 10, 7, -8, 0, -7,-13, 1, 0, -2, 7,-12, 4, -3, 24 },
- {-13, 9, 4, -2, 2, -4,-14, -1, -3, -5,-10, 4, 13, -2, 5, 13,
- 8, 3, -2, 1, 5, -6, 7,-18,-10, 1, -1, 5, 4, 1, 0, 25 },
- { -5, -1, 18, 12, 8, 8,-16, -1, 1, 1, 1, -4, -5, 3, 3, 4,
- 4,-11,-12,-16, -6, 2, 12,-13, 0, 9, 7, 9, -9, 0,-10, 24 },
- { -4, 1, -3, 0, 2, -4, 4, 1, 5, 0, -3, 2, -3, -2, 2, -1,
- 1, 4, -1, -2, -2, 1, -1, -1, -4, -1, -4, -2, -6, 6, 12, 69 },
- { 8, 5, 11, 0,-15, -4, 13, 6, 0, -4, 9, 1, -5, -3, 15, 0,
- 1, 6, -5, 0, 1, 6, 5, 8, 0, 7, 1, -1, -4,-11, -9, 41 },
- { -4, -9, 32, -6, 0, 7, -4, 6, -6, 1, -6, -2, 4, -8, -5, -3,
- -16, -1, -2, -6, 1, 15, 0, 21, 3, -3, -4, 3,-12, 16, 2, 27 },
- { -6, -5, 1, -9, -5, 3, 7, -3, 5, 5, 14, 13, 20, -7, -1, 12,
- -1, 10,-11,-11, -7, -4,-14, 7,-14, 13, 22, 18, -1, 0, 14, 28 },
- { -8, 3, -2, 0, 5, 6, -1, -4, 1, 3, -7, 3, 1,-15, 4, -9,
- 22,-10, -9, -4, 1, 8, -4, 9,-15, 2, -6, -4,-16, 12,-10, 23 },
- { 0, 0, 2, 0, -1, 3, -3, -1, 3, -5, 7, 1, 5, -5, -8, 1,
- 13,-15, -5, -7, 12, -6, -2, 3, 10, -5, -8, 17, -5,-11,-14, 23 },
- { -7, -4, 6, -4, 5, -6, -5, 2, -4, 11, 9, -4, 2, -2, -4, 6,
- 15, 3, -3, 18,-15, -2, -6, 3, 3,-20, 17, 11, -4, 2, 3, 29 },
- { 6, 1, -6, 2, 3, 0, 0, -3, 3, 3, -1, 3, -4, -6, -6, -7,
- -3, -2, -7, -2, -4, 5, 3, -5,-20,-13, -4, 10,-14,-29, 14, 37 },
- { 3, 4, 3, -6, -4, 5, 0, 3, 2, 3, 0, -2, 4, 0, -3, -5,
- -4, 4, -4, 4, 4, 3, 1, -4, -4, -9,-14, 20,-30, 3,-18, 33 },
- { 0, 2, 5, -2, -4, -2, -1, 2, -6, -3, -2, -2, 2, -5, -1, 4,
- 3, 2, -3, 0, -1, -1,-10, -7, 2, -4,-18, 2,-37, -1, 12, 40 },
- { -7, 2, -1, 0, -2, 4, -8, 1, -4, 12, 7, 4, 15, -7, 1, -9,
- 18, 0, 12,-17, -3, -1, 0, 0, 0, 2, -6, 0, -4, -3, -1, 26 },
- { -6, 4, 8, -5, -6, -2, 2, -1, 1, -1,-15, 8, 7, -1,-17, -4,
- 1, 5, 6,-11, -6, 14, 17, -5,-15, 11, 8, 0, -3,-15, -6, 28 },
- { -1, 0, 0, 0, 1, 0, -1, 0, 1, 3, 2, -2, 3, -1, -1, 2,
- 2, -1, -1, -7, 1, 2, -9, 0, -1, -4,-18, 7,-10, 49,-13, 32 },
- { -1, -3, 4, 1, 2, -5, 1, -7, -1, 5, -9, 4, 4, 25, 1, -1,
- 2, -5, 2, -7, 17, -2, 10, -5, 0, 2,-15, 3, -9, 7, -9, 30 },
- { -5, -1, 0, 2, 1, -1, 2, 5,-33, 3, -5, 14, 11, 7, 5, -3,
- 2, -8, -4, -2, -7, -6, 4, -8, -1, -8, 2, -2, -8, -1, -4, 27 },
- { -1, 0, -1, -2, 1, -1, -2, -1, 2, 0, 1, 2, 2, 4, 1, 3,
- 4, 2, 1, -7, -4, 1, -3, -4,-35,-25, 17, 10, -3,-26, -7, 32 },
- { -5, 1, 6, -2, 6, 6, -9, 3, -1, -4, 5, -4, -2, -2, -9, 2,
- -5, 2, 2, 4, 3, 5, -5,-16,-31,-12,-11, 2,-19, 20, -2, 21 },
- { -5, 2, 7, -7, -7, 5, -7, 2, 0, 0, -4, 3, -1, 0, -1, -2,
- 0, -3, 5,-11, -8, -3, -7, -7, 28,-11, -7, 0,-16,-11, -4, 29 },
- { 2, 1, -3, -2, -1, 3, 4, 0, 1, 0, -1, -5, 4, -5,-12, 2,
- -2, -5,-22, -2, -1, 11, 8, -7,-12, 0,-34, 6, -5, 11, -8, 19 },
- { -1, -3, 5, 11, 18, -2, -2, -5, -2, 4, -1, 8, 5, -6, 1, -1,
- 2, 8, 4, -5, -8, -2, 5,-18, 7, 12, 7, 19,-18, 2, -6,-13 },
- { 9, 0, 0, 5, 4, 3, -6, 4, 1, -4, 5, -1, -4, 8, 8, 6,
- -8, -6, 0, 6, -3, 3, 5, -3, 17, 31, 16, 10,-13, 0, -9,-19 },
- { 12,-10, 2, -2, -2, -1, -3, 6,-12, -5, -2, 14,-16, 4, 12, 12,
- 17, 4, 7,-16, 7, -6, 11, 7, 7, 2,-25, 23,-24, 5, -7, -9 },
- { 10, 4, 13, 10, 10, 3, -6, 3, 3, 2, -1, -6, 8, 4, 10, 0,
- 1, 2, -4, 2, -3, -8, 0, -1, 9, 9,-10, -3,-29, 1, -1,-27 },
- { 2, 2, 0, 7, 9, -2,-10, -1, -1, 1, -9, -5, 8, 4, 1, 2,
- -10, 1, 13, 12, -3, 15, -9, 2, -7, 1,-10, 23,-20,-18, -9,-15 },
- { -3, -5, -1, 8, 0, -5, -1, 4, 7, -1, -7, 2, -8, -5, 11, 7,
- -6, 3, -3, -9, 7, 9,-22, 1, 6, -4, 14, 27,-25,-14, 3, -5 },
- { 1, 3, 8, 4, 7, 6, 12,-17,-15, 1, -8,-10, 7,-14, -8, 6,
- -2, -2,-11,-11, -7, 13, -2, -2, 4, 5, -5, 13,-23, -6,-17, -8 },
- { -5, 4,-14, -5, -4, -5, 6, 5, -8, -5, -2,-11, -7,-12, 3,-11,
- 2, -6, 4,-10, -5, -7, 14, 5, 23, 11, 7, 12,-16, -6, -4,-16 },
- { 5, 6, 2, 5, -2, -5, -5, -6, -5,-19,-13, -1, -3,-13, 5, 0,
- 6, -2, -2, -6, -7, -7, -1, -9, 4, 14, 17,-12,-27, 3, 0, -1 },
- { 7, -1, 9,-10, 8, 2, -7, -2, 5, 2, -3, -7, 3, 0, 6, 4,
- 12, 5, 11, 14,-13, -1, 8, 1, 13, 9, 12, 12,-18,-14,-11,-16 },
- { -7, -5, -6, -5, 0, -1, -3, 2, 2, 1, 4, 9, 2, 3, 5, -2,
- 2, 1, 8, 0, 3, 0, -2, 2, 1, 7, 29, 0,-36, -5, -9,-21 },
- { 14, -6, -9, 0, -1, -8, -8,-11, 2, 2, -9,-12, 12, -4, 5, 3,
- -5, -9, 11, -1, -3, 12,-21, -3, 12, 5, 3, 11,-18,-15, 1, -2 },
- { -1, 3, -9, -3, 7, -7,-18, 2, 4, 12,-10, 2, 8, -3,-14, 13,
- 17, -5, 5, -9, 13, -3, -7,-18, 17, -2, 5, 7,-20, -3, -6,-11 },
- { -3, 3, 3, -1, 1, -6, -5, 1, 5, -3,-14, -6, -5, -8, 14, -6,
- 7, -1, 5, 1, 15, -1, -7, -4, 6,-11, 9, -2,-37, 16, -7, -3 },
- { -1, 0, 6, 1, -3, -9, 0, 11, -8, 2, -2, 0, 5, 2, 12,-10,
- 10, 13, 2, 7, -6, 2,-10,-10, 21, -5, 5, 5,-12,-23, 3,-14 },
- { 6, 0, -2, 1, 0, 1, 0, -4, 1, 1, 8, -2, 2, -5, -2, 1,
- 8, -4, -1, -1, 4, -1, 2, 6, 32, 1, -5,-20,-40, -4,-18,-14 },
- { 2, 2, -7, -2, 4, 4, -1, 2, 0, -2, -4, -7, 3, 5, 0, -5,
- 1, 2, -6, 4, -1, -2, -1,-15, 8, 3, 9, 46, -7,-18, 6,-11 },
- { 5, 5, 16, 21, 3,-11, -4, 11,-12, 2, 4,-12, -1, 11, 8, 1,
- -4, 11,-11,-21, 1, 1,-11, 3, 13, 1, 5, 12,-25, 1, -3, -2 },
- { 1, 6, -7, 4, 2, 3, 1, -5, 8, 9,-15, 3, -3,-14, 17, 4,
- -8, 14, -2, -8, -4, 5, 8, -7, 8, 9, 7, 6,-29,-17, 8, 4 },
- { -7, -7, 4, 0, 13, 1, 0, 4, 4,-16,-10, -7, 5, 9,-15,-10,
- -10, 8, -4, -1,-11, -1,-10,-15, 3, 3, 14, 10,-19, 2,-18,-12 },
- { -4, 0, 2, 0, 5, -2, -9, 0, 4, -4, 2, -1, -2, 2, -4, 9,
- 2, -6, -4, -2, -1, -3, -3, -1, 2, 5, -1, 11,-24,-44, -9,-15 },
- { -1,-10, 6, 21, 11, 15, -7, 10,-14, -9, -8, -8, 4, 6, 19, 1,
- -6, 1, -5,-17, -8,-10, 9, 5, 11, 18, -1, 10,-16, -7, -9, -8 },
- { 3, -5, 0, 0, -2, -2, -6, 4, -4, 1, -1, 0, 7, -3, 4, -4,
- -7, 7, 17,-20, 6, 4, 1, -6,-12, 31, 13, 19,-14,-10, -7, -2 },
- { -2, 6,-10, 3, 9, 6,-14, 15, 2, -5, 2,-11, 9, -8, 4, 6,
- 20,-15, -3, -3, -1, 32,-21, 6, 1, 9, 11, 17,-19, 6, -1, -3 },
- { 8, 10, -2, 0, -8,-16, 7, 7, 6, 10, 4,-14, 7, -6, 21, -7,
- 10, 5, 5, 0, -7, 2, -6, 0, -7, 11, -9, 15,-20, -7,-11, 2 },
- { 0, -7, 5, 2, 0, -3, -6, -4, -2, -1, -4, -5,-13, -1, 27, -9,
- -6,-11, -7, 1, 11, -4, -4,-14, -2, 11, 6, 10,-19, -6,-15, 2 },
- { 0, 7, -1, 2, -7,-15, -2, -3, 13, -5, -5, 12, 3, 0, 5, -5,
- -22, 2, 7, 22, 13, 0, -1, 2, 3, 2, -7, 7,-27, -4, -4,-12 },
- { 11, 1,-16, 6,-15, 1, 3, 2, 0, 2, -3, 2, 5, -2, -5, 9,
- 5, -3, 3, -2,-11, 3, 9, 6, 9, 3, -1, 12,-41, 8, -6, 9 },
- { 3, -7, 3, 2, 5, 5, 0, -1, 1, 3, -5, -2,-13, 7, -1, -2,
- -2, -6, 4, -6, 0, 2, -2, 2, 4, 1, -4, 1,-47,-21, 7, -6 },
- { 3, 16, -7, 13, -4, -2, 10, -3, -1, 18,-13, 7,-13, -4, 8, 4,
- 8, 9, -5, 13, 8, -5, 3, -6, 7, 18, -8, 10,-25, -3,-12,-12 },
- { 1, -1, -1, 0, 2, 5, -5, -3, 0, -5, -1, 0, -4, -8, -2, 3,
- 2, -2,-17, -6, -4, 1, 33, -6,-20, -6, 8, 31,-26, -8, -1, -4 },
- { 3, -3, -3, 5, -3, -2, 1, 7, 0, 3, 6, 3, 6, -2, 9, 15,
- -10, -3,-15, -5, -3, -4, -6,-30, 17, -8, -2, 2,-20, 0, -8, -2 },
- { -2, -1, -1, -1, 3, -5, -2, -3, 4, -2, 0, 5, 8, -3, 1, -4,
- 1, 1, -3, 4, 4,-14, 3, 11, -5, 3, -3, 7, -3, 13, 23,-16 },
- { 2, -6, 1, -3, 5, 0, -6,-11, -7, -4, -1, 2, -7, -1, -1, 7,
- 1, -2, 6, 12, -6, 8,-13, 17, 25,-23,-19, -7,-12, 9, 16,-17 },
- { 9, 4, 4, 4, -3, -1, 6, -2, -3, 0, 13, -4, -7, 14, 1, -7,
- 0, -5, 3,-19, -3, 5, 3, 9, -1, 9,-13, 13,-17, 4, 21,-26 },
- { 0, -5, 0, 0, -4, -5, 2, -6, -4, 5, -7, 10, 0, 2, 0, -2,
- -2, 0, 4, -6, 7, -2, 6, 5, -5, 2,-12, 1,-29, 29, 27, 12 },
- { 9,-10,-22, 6, -1, -1, 9,-14,-12, -2, 1, -1, 10,-11,-16, 0,
- 3, 11, 13,-14, -9, -2, -1, 6, 4,-14, 0,-10, -2, 16, 17,-11 },
- { 2, 0, -1, -2, 4, 3, -6, -2, 1, -1, 1, 3, -4, 1, 3, -4,
- -1, -1, 4, -1, 1, 0, 1, 6, -5, -7, 2, 1,-47, -3, 50,-17 },
- { 8, -4,-11, -7, 11, 11, 14, -7, 12, -7, 6, 2, 13, -6, -3, -2,
- -14, 6, 6, 6, 0, 2, -1, 5,-20, 2, -1, 4, -5, 6, 21,-11 },
- { -2, -9, 3, 0, -6, 7, 8, -8, 1, -3, 4, 1, 5, -2, -3, -7,
- 4, 7,-12, -9, -2, 10, -6, 13, 6, 5, 20, 2,-15, 9, 28, -7 },
- { 0, -5, -6, -6, -6, 1, -6, 6, -2, 4, 8, -3, 12, -1, -4, -2,
- 6, 16,-14, 9,-14, -2, -8,-27, -3, 18, -1, -7, -3, 8, 23,-23 },
- { 1, 4, -9, -1, -5, 10, -2, 1,-11, 1, -9, 4, 7, 14, -9, -2,
- -3, 2, -5, -1, -6,-10, -7, 11, 20, 2, 3,-19, 3, 15, 30, -9 },
- { 7, 2,-14, -4, 0, -2, 5, 2, 5, -2, 8, -3, -7, 6, 6,-11,
- -14, 1, 10, -1, -7, -8, 1, 10, 3, -6,-15,-12,-17, 4, 30, -6 },
- { 4, 2, 1, -2, 3, 0, 1, 0, 2, 0, 1, 6, -7, 0, 3, 4,
- 4, -4, -2, -5, -2, 2, -1, -2, 0, -2,-11, -7, -3, 42, 24,-14 },
- { 4, 1, 3, 2, 0, -2, -3, -2, 2, -1, 4, 11, -2, 2, 3, -4,
- -5, 9, 2, -4, -9, 5, 8, -1, -7, 1, 24,-13,-28, 20, 15,-22 },
- { -3, 7, 6, 3, -2, -5,-10, -2, -2, -1, -6, -6, -2,-14,-16, -6,
- -5, 0, 18, 0, 9, 1, 7,-13, -5, -6, -9, 11,-15, 9, 22,-11 },
- { 9, -2, 6, 5, 2, 9,-10, 1, 1, 5, -4, 12, 2, 2,-10, -7,
- -4, -6, 7, 9, 6, 15, 6, 6,-10, 10, 5,-13, -5, 6, 24,-12 },
- { 1, 3, -3, -3, 8, 1, -6, 2, -5, -3, 7, 2, 14, 6, 9, -6,
- -5, -4, 27, 7, -3, 8, -6, 3, -8, 8, 22, -5, -6, -2, 22,-17 },
- { -2, -2, 3, 10, 9, 9, 12,-15, -1,-11,-13, 3, -2, 1, -3,-11,
- 7, 9, 16, -3,-10, -5, -5, 1, 8, -3, 9, 9, -5, 3, 31,-12 },
- { 7, -5, 10, -4, -8, 2, 16, -2, 10, 10, -3, -2, 3, -8, -3, 3,
- -13, -6, 15, 20, -9, -3,-12, 1, -2,-16, 8, 8, -1, 16, 22, -5 },
- { 5, -3,-15, -2, 12, -8, 8, -5, 2, -8, 20,-18, 14, -4, 3, 3,
- 7,-13,-16, 1,-10, 7, 16, 7, 4,-14, -4, -5, -9, 8, 23, -6 },
- { 5, -4, -5, -4, 1, 8, 4, -7, -5, 8, 10, 6, -6,-10, -2, 6,
- 9,-17,-14, 11, 12, -3,-13, -7, 2, 18, 3,-25,-16, 18, 22, -5 },
- { 5, 6, -7,-20, -4, 2, 8, 4,-24, -4, 1, 4, -5, -2, 1,-10,
- -2, 9, 3, -4, -3, -4, -4, -4, 10, 10, 3, 0, -6, 25, 21,-11 },
- { 0, 7, -1, 14, -6, -4,-10, 5, 4, 4, 4, -5, 3, 4, -1, -7,
- 8,-19, 0, 6, 2, 3,-18, -3, -6, 2, 8, 14,-26, 22, 27,-13 },
- { -2, -6, 7, -5, 12, -7, 8, -1, 3, -2, 4, 1, 8, -2, 0, 14,
- 6, -5, 6, -4, -7, 7,-21, 8, 1, 8, -9, -4, -3, 11, 25,-13 },
- { 4, 4, -1, -6, 4, 9, -8, 1, -3,-10, -2, 0, 15, -9,-16, 11,
- 1, 1, 6, 3, -9, -5, 16, 26, 1,-14, 1, -3,-14, 7, 15, -9 },
- {-12, -2, -9,-13, 2, 6, 14, 0, 1, 0, -1,-13, 0, 10, -1, 6,
- 9, -7, 8, 8, 19, 6, -1, 9, 10, -4, 1, -7,-22, -2, 29, -7 },
- { 2, 4, 13,-12, -8, -4, -5, 13, 12, -5, -3, -3, -4, 1, -1, 10,
- 15, -6, -1,-11,-30, 4, 15, -1, 9, -7, 0, -2, -7, 10, 25,-16 },
- { 7,-15, -7, -7, -1, -5, -5,-11,-20, 10, 3,-10, -3, 5, 20, -4,
- 0, -2, -2, 17, 2, 0, -3, 3, 6, 5, -1,-12, -3, 15, 22,-16 },
- { 4, -1, 3, 4, -5, 0, -1, -5,-24,-29, 4, -9, 1, -3, 0, 0,
- 0, -4, 7, -4, -4, -4, 3, 1, -6, 5, -3, -5,-10, 3, 25,-10 },
- { -2, -1, -1, 4, 4, -1, 2, 0, -4, -4, 2, -1, -3, -1, -2, -2,
- 1, -3, -5, -1, 2, -3, -4, -4, -3, 5, -9, 1,-11, 7, 46,-46 },
- { 0, -9, 3, 4, 4, 3, -5, -6, 5, -4, 4, -2, 1, 7, -4,-10,
- 13, 1, 3, -6, 4, -4, 7, 2,-19,-25, -3,-16,-12, 16, 20, -1 },
- { 18, 6, 4,-12, 0,-14, 9, -6, -1, -4, -5, 2, 1, 12, 4, 2,
- 7, 0, 2, 5,-11, -5, -2, 2, -4, 10, 0, -9, -7, 9, 25, -8 },
- { 5, 0, -6, 5, 6, 3, 3,-10, -5, 1, -1, 4, 3,-11, -8, 5,
- 4, -5, 5, -5, -7, -5, 11, 5, 20, -8,-16, 21, -4, 27, 23, -5 }
+DECLARE_ALIGNED(8, static const int8_t, high_freq_vq)[1024][32] = {
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { -4, -2, 2, 1,-16,-10, 1, 3, 1, 0, 6, 1, -3, 7, 1,-22,
+ 2, -4, -3, 11, 14, 6, -1, 1,-13, 29,-28, 10, 10, -8, 0, -9 },
+ { -8, 8, -7, 10, -3,-12, -5, -8, 1, -2, 9, -2, -5,-18, 1, 9,
+ -8, -8, 3, 41, 7, -9, -9, 22,-42,-29, 14,-18,-14,-32, 1,-15 },
+ {-16, 8, 15, 16,-16, 5, 2, 7, -6,-16, -7, 1, 1, -3, -2, 0,
+ 8, 20,-26,-11, 2,-17, 0, -3,-34,-37, 10, 44, -2, 22, 2, -4 },
+ { 7, 14, 5, 6, 15, -1, 3, -3, -9,-23, -5,-14, 8, -1,-14, -6,
+ -5, -8, 54, 31, -6, 18, 2,-19, -2,-11,-30, -6,-19, 2, -2,-14 },
+ { 1, 2, -2, -1, -3, -3, 1, -5, 1, -3, -4, -8, 5, -4, 0, 1,
+ 3, 7, -5, -4, -3,-12, 3, -2, -3, 12,-53,-51, 6, -1, 6, 8 },
+ { 0, -1, 5, 1, -6, -8, 7, 5,-18, -4, -1, 1, 0, -3, -3,-14,
+ -1, -6, 0,-14, -1, -1, 5, -3,-11, 1,-20, 10, 2, 19, -2, -2 },
+ { 2, 4, 3, 0, 5, 0, 3, 1, -2, 0, -6, -3, -4, -5, -3, -3,
+ -7, 0,-34, 4,-43, 17, 0,-53,-13, -7, 24, 14, 5,-18, 9,-20 },
+ { 1, 0, -3, 2, 3, -5, -2, 7,-21, 5,-25, 23, 11,-28, 2, 1,
+ -11, 9, 13, -6,-12, 5, 7, 2, 4,-11, -6, -1, 8, 0, 1, -2 },
+ { 2, -4, -6, -4, 0, -5,-29, 13, -6,-22, -3,-43, 12,-41, 5, 24,
+ 18, -9,-36, -6, 4, -7, -4, 13, 4,-15, -1, -5, 1, 2, -5, 4 },
+ { 0, -1, 13, -6, -5, 1, 0, -3, 1, -5, 19,-22, 31,-27, 4,-15,
+ -6, 15, 9,-13, 1, -9, 10,-17, 4, -1, -1, 4, 2, 0, -3, -5 },
+ { -7, 3, -8, 13, 19,-12, 8,-19, -3, -2,-24, 31, 14, 0, 7,-13,
+ -18, 0, 3, 6, 13, -2, 1,-12,-21, 9, -2, 30, 21,-14, 2,-14 },
+ { -3, -7, 8, -1, -2, -9, 6, 1, -7, 7, 13, 3, -1,-10, 30, 4,
+ -10, 12, 5, 6,-13, -7, -4, -2, -2, 7, -3, -6, 3, 4, 1, 2 },
+ { -8, 9, 2, -3, -5, 2, 0, 9, 3, 7, -4,-16,-13, 3, 23,-27,
+ 18, 46,-38, 6, 4, 43, -1, 0, 8, -7, -4, -1, 11, -7, 6, -3 },
+ { 1, 1, 18, -8, -6, 0, 3, 4, 22, -3, -4, -2, -4,-11, 40, -7,
+ -3,-13,-14, -7,-10, 14, 7, 5,-14, 11, -5, 7, 21, -2, 9, -3 },
+ { 0, 0, -2, 4, -2, 0, 2, 0, -1, 2, -1, 0, 0, 2, 2, 2,
+ -1, 1, -3, -1,-15, -2,-63,-27,-21,-47,-14, 1,-14, 10, 0, 2 },
+ { 1, 0, -4, 0, -3, -9, 4, 2, 6, -6, 0, -5, 11, -7,-15, 6,
+ -7, -6, 3, 7,-15, -5, 23,-13, -6, 12, -8, 9, 2, -3, 3, 4 },
+ { 6, 0, 3, 0, -2, -4, 2, 1, 1, -1, 1, -2, -1, -4,-22,-15,
+ -46,-66, 10, 20, 2,-17, 12, -6, 1, -2, -2, 0, 1, -5, 1, 2 },
+ { -1, 0, 0, 1, 0, -4, 0, 1,-10, -3, -8, 5, 7,-11, 2,-11,
+ 29,-25, 11, 10, 0, -1, 5, -7, -2, -5, -2, 4, 4, -3, 5, -2 },
+ { 1, -1, -1, -3, -2, 1, -8, -3, 2, -2, 4, -5, -1, -7, -2, 1,
+ -14, -7, 3,-30,-15,-14, 3, -4, -1, 3,-13, -1, -3, 1, 2, 3 },
+ { -1, -2, -3, 2, 2, -3, 3, 1, -3, 2, 0, -4, 6, 5, -5, 10,
+ -57, 3, 22,-50, 1, -2, -5, -6, -1, 5, 1, 2, 2, 1, -2, 2 },
+ { 2, 0, -1, -7, 2, 1, 3, 2, 0, 4, 3, -2, 3, -3, 4, -4,
+ 24,-35, -3, 38, -6, -5, 15, 20, 3, 16, -7, -5, 0, -4, -5, 0 },
+ { 0, 1, 0, 0, 0, -1, -1, 1, 1, -1, 1, -2, 0, 0, 0, 0,
+ 0, -1, -2, -1, -5, -2,-43, -3, 46,-52,-10, 7, -8, 11, -2, -1 },
+ { 0, 0, -1, 0, -1, 2,-41, 33,-44,-48,-15,-26, -9, 6, 3, 3,
+ -3, 2, 2, 2, 2, -1, -1, -2, 1, 3, 0, 0, 5, 2, 3, 1 },
+ { -4, 1, 6, 1, -6, -1, -2, 1,-14, -4, 0, -5, -2, 2, -2, 0,
+ -6, 1, 0, 8,-21, 32, -3,-36, -6, -2, -1, -7, 3, 0, 1, -6 },
+ { -3, -2, 3, 0, 2, 2, 8, -4, -4, 6, 2, 1, 3, -6, 4, 3,
+ 13, 0,-12, -1, 25,-20, -2,-23,-15, 7, -3,-11, -3, 6, -1, 0 },
+ { 0, 0, -3, -1, 0, 0, -2, -1, -2, -2, 1, -1, 0, 0, 10, 3,
+ -2, 3, 3, -7, -6, -5, 0, -4,-60,-16, -6, 38, 5, 6, -5, 0 },
+ { 0, 1, 0, 0, 0, 0, 0, 0, 1, -1, -1, 0, 1, 0, 0, 1,
+ 0, 0, -1, 0, -8, 2, -9, 10, 40, 31,-56,-21, 4, 20, -4, 7 },
+ { -2, -2, 0, 4, -3, -1, 7, 3, 1, 3, -8, 0, 3, 1, 2, 5,
+ 1, -2, 14, 5, 4, 5, 5, 5, -5, 9,-66, 0,-20, -2, -8, 4 },
+ { -2, -1, 4, -1, -8, -2, -4, -1, -3, -3, 2, -7, -3, 5, 7, -2,
+ 45, 31,-17,-16, -2, -2, -1,-22, 1, -1, -3, 3, 5, -3, 5, -1 },
+ { -4, 0, 7, 5, 8, 7, 2, 9, -9, -9, -7,-11, -3, -8, 17, -4,
+ 34, 32, 18, 22, 1, 2, 1, -7, -5, 6, -1, 6, 4, 10, -2, -7 },
+ { 6, 0, 14, 9, 6, -1, -2, -3, 4, -6, -8, 4, 7, -1, 28, 38,
+ 15, -1, 16,-11, 5, 8, 4,-10, 3,-10,-17, 5, 3, 3, 3, 1 },
+ { 1, 1, 2, -1, 2, 1, 0, 0, -1, 0, 0, -2, 1, -3, 0, 1,
+ 2, -2, -4, -2, 0, -1, 1, -3, 1, 1, 1, -1, 8, 8, 66, 33 },
+ { -5, 2, -3, -7, 2, -8, -4, 10, 17,-18, -7, 4, -4, -7, -6, -6,
+ -5, 5,-12, 2, 0, 6, 8, -2, 1, 4,-11, 2, 1, 8, 31, 19 },
+ { 6, 9, 16, -6, -6, -1, -2, -3,-11, -2, 7, 7, 17, 3, 4, 10,
+ 2, 5,-13, 8, 7, 1, 4, 5, 7, 6, 7, -8, 9, -8, 33, 6 },
+ { 3, -1, 1, 0, -7, -5, 0, 14, -7, 1, -7, 1, 2, -4, 7, 10,
+ -16, 12, 1, -6, 3, 8, -1, 10,-13, -6,-12,-23, 12, -3, 30, 14 },
+ { -2,-15, 0, 8, 3,-19, 5, -3, 2, 3, 13, 7, 14, -3,-10, 0,
+ 8, 5, -6,-16, -8, -8, 14, 2, -1, 1, -9,-11, 11, -5, 27, 9 },
+ { -8, 6, -4, 4, -4, -1, 5, 4, 1, -7, -5, -4,-15, 1, 9, 0,
+ 8, 4, 1,-17, 11, -2,-19, -1, -6, -8, 3,-12, 3,-17, 33,-10 },
+ { -3, -1, 2, 7, 7, -2, 9, 8,-18, -1,-13,-10, -3, -3, 11, 8,
+ -2,-12, -8, 1, 4, 9, 14, 10, -3, 0, 2, 1, -2, 3, 31, 10 },
+ { -3,-10, 8, -1, -5,-11, 7, -5, 3, 6, 1, 4,-16, 10, 5, -4,
+ -2,-10, -1, 13, 6, -5, -7, 12, 7, -3,-17, 1, 12, -4, 29, 8 },
+ { 1, 2, 5, 2, -6, -7, 0, -1, 6, -1, 10, 6, -4, 5, 2, 2,
+ -2, -8, -6,-11, 14,-13, 27, 3, -2,-12, 5,-16, 2,-26, 20, 15 },
+ { -1, -3, -5, -3, -3, 6, -1, 3, -5, 1, 7, 2, 1, 0, -1, -1,
+ 0, -1, 9, 7, -6, -3, 4, -5, -4, 8, -8,-25, -8, -4, 34, 23 },
+ { -1, -2, 1, 1, -1, -2, -1, 1, -1, 0, 0, 0, 0, -2, -1, 1,
+ 0, 2, 1, -1, 4, 0, 0, 1, -1, 0, 5, 3, 12, -9, 68,-16 },
+ { 10, 0, -8, 14, -6, 1,-12, 0, 0, -3, -5,-11, -6, 12, 9,-10,
+ -3, 5, 0, 7, 11, 2, 4, -3, -8, -3, 7, 4, 3, -3, 34, 4 },
+ {-12, 13, -5, 7,-11, -2, -1, 1, -4,-14,-21, 3, -3, -3, -4, -7,
+ -9, -4, 3,-17, -2,-13, 10, -2, 12, -4, 0, -9, 1, -5, 31, 10 },
+ {-10, 6, 5, 6, 4, -7, 10, 0,-28, -3, 0,-11, -1, -5, 16,-10,
+ -16, 7, 20, 2, -4, 2, -5, 0, 15, 6, 5,-10, 7, -9, 20, 4 },
+ { 1, -7, -2, -7, 4, -3, -2, -7, -1,-14, 6,-16, 4, -5, -4, -6,
+ -5, 0, -2, 2, -6, 9, -5, 4,-18, 8,-10, 8, 15, 0, 32, 1 },
+ { -5, 7, -3, 7, 15, -4, 0,-16, 9, 5, -5, 5, 4, -3,-12, -9,
+ -18, 10, 2, 2, -3, 7, 3, -1, 6, -9,-10, 3, 15, -4, 35, -7 },
+ { -1,-10, 2, 2, -4, -2, 10, 2, -1, 2, -2, 1, -1,-14,-11, 3,
+ -8, 5, -8, -2, 6, -1, -7, 1, 7, 5, 7, 8, 30, -4, 30, 14 },
+ { 2, -2, 1, 2, 3, -8, 3, 0, -2, 0, -9, 2, 1, 4, -6, -1,
+ -2, 5, 0, 1, -2, 12, 6, -3, 9, -3, 4,-12, 21,-39, 24, -2 },
+ { 3, 5, 1, -2, -2, -2, -3, 6, -8, -2,-11, -8, -1, 4, 2, 2,
+ -4,-10, 12, -5,-11, 1,-15,-34,-11, -7,-11, -1, 7,-14, 38, -1 },
+ { -4, 4, 8, 9, 8, 1, -5, -9, 4, -2, 15, -4, 11,-15, 20, -1,
+ -1, -3, 4, -9, -2, -2, -2, 8, 6, 12, -5, 0, 11,-12, 27, -4 },
+ { 0, 8, -4, 3,-11, 6,-11, 2, 3, 0, 5, -8, -7, -6, -9,-21,
+ 4,-11, -1,-16, -7, 16, -3, 7, -7, 4, -5, 0, 11, -7, 31, 3 },
+ { 1, 3, 4, 11,-11, -2, -3, -6, 6, 5, 0, 3, -9, -6, 4, -4,
+ 0, 4, -8, 13, -6,-13, -1, -5, -1, 4, 0, 0, 9,-22, 24, 18 },
+ { -7, 3, 10,-13, -6, 6, -6, 6, 22, 1, 0,-14, 2, 3, 7, -1,
+ 8, 20, -1, 5, -4, 13, 9, -9, -9, 6, 0, -4, 0, -8, 31, -4 },
+ { -3, -4, 0, 1, 7, 3, -7, 0, 5, -2, 1, 3, 3, 1, -5, -2,
+ 5, 2,-11, 4, 0, -1, 12, 0, -3,-13, 15, 8, -6,-27, 34, 0 },
+ { -3, -3, 10, -4, 2, -1, -3, 0, -1, -1, -4, 2, 6, -2, 12, 1,
+ 3, -6, -7, -6, -5, 4,-19, -6, -8,-34, -4, -8, 10, -7, 23, 10 },
+ { -7, 0, -1, -6, 8, 4, -4, 2, -5, -8, -7, -9, -8, 5, 9, 7,
+ -6, 1,-12,-12, -1,-16, 5, 0, 16, 3, -7, -8, 27, -4, 23, 15 },
+ { -8, 4, 8, 5, 6, 11, -3, 5, 3, -1,-11, 6, -5, 0, 2, -6,
+ -3, -6, 4, -1, 5, -5,-12, -6, 7, -5, 9, 3, 6, -7, 29, 1 },
+ { 1, 3, -2, -2, -6, -2, 1, 6, -6, -3, 1, 2, 3, 4, 1, 5,
+ -1, 0, 4, 2, 11, 6, 2, -3, 13, -9,-19, 18,-15,-10, 36, 21 },
+ { -3, -3, 2, -1, -7, 6, -4, 1, -3, -1, -2, 2, 3, -7, -3, 0,
+ -2, 0, -2, 6,-19, 3, -8, 2, -6, 7, -1, 0, 29, -6, 28,-10 },
+ { -5, 1, -3, -7,-12, -4, 1, 1, -1, 13,-10, -1, -9, -5,-13, 6,
+ 13, 3, -4, 2, 3, 11, 2, 6,-25,-16, -6, 0, 14, -1, 27, 16 },
+ { -6, -1, -7, -5, -2, -5, -5, -1, 9, 1, 0, 3, -8,-12, -6, 5,
+ -6, 5, 3, -9, 1, 4, -7,-10, -9, -7,-17, -5,-15,-23, 25, 3 },
+ { -8, -2, 9, -3, -4, 3, -1, 8, -7, -7, -5, -4, -2, 9, 4, -1,
+ -7, -4, -5,-16, 3, -6, 18,-13, -9, 16,-15, 8, 15,-10, 24, 5 },
+ { 1,-38, 2, 34, 9, 10, 11, 2, 2, -6, 3, 2, -2, 5, 4, -7,
+ -1, 1, 4, 0, 3, 1, -8, -1, -6, 5, 4, 2, -4, 5, 2, -1 },
+ { 1,-22, 15, 18, -2, 10,-16, -9, -8,-11, 8, 4, 0, 7,-14, -5,
+ -1, -7, 12, 17, 9, 5, -7, -4,-12, -6, 7, 0, 7, 2, -2, 1 },
+ {-11,-29, 7, 10, 19, -1, -8, -9, 7, 1, 9, 6, 8, -7,-14, 8,
+ -3,-11,-13, 0, -7,-23, -2, -8, 12, 9, 2, 14, 19, 1, -1, 5 },
+ {-24,-27,-11, 36, 2, 6, -3, 4, -6, 8, 0, 12, -1, -4, -6, 3,
+ 4, -1, 2, -3, -2, 3, 2, -1, -2, -4, 0, -1, -2, 7, 2, 3 },
+ { -9,-24, 11, 13,-10,-12, 12, -2, 7, 4, 8, 13, -3, -3, 2, 9,
+ -3, -4, 4, 13, 5, 13, -6, -3, 1, 15, 7, -3, 0, 19, -2, -9 },
+ { -8,-15, 7, 14, -4, -5, 2,-18,-19, -2, 2, 17, 16, 6,-10, 10,
+ -9, 14, -1, -5, -1, -6, -7, 2, 9, 11, 13, 6, -5,-12, 3, 2 },
+ {-10,-37, 13, 1, 3,-14, 0,-20, 4, -3, 8, 2, -2, -3, -9, -5,
+ -3,-17, -1, 13,-11, 2, -6, 4, 4, 0, 3, 1, -9, -4, -5, -4 },
+ { -2,-22, -5, 46, -8, 5, 9,-11, 8, 7, 7, -1, -1, -2, -7, 2,
+ -3, 3, -1, -2, 7, 0, 2, -1, 1, -2, -2, -3, 6, 0, -4, -6 },
+ {-16,-27, 15, 16, -4, 14, -7,-26, 2, -2, 6, 5, -3, 11, 0, 2,
+ 3, 9, -7, -1, 2, -4, -4, -1, 6, 10, 1, 1, -3, -2, 3, 0 },
+ { -3,-22, 10, 26, 1, 2, -3, 3, 17, -3, -7, 9, 1,-21, -4, 5,
+ 3, 0, -7, -6, 3, 3, -8, -7, -9, 3, 7, 1, -8, 12, 6, -7 },
+ { -9,-25, 3, 18, 9, -6,-11, 0, -5,-12, 9, -8, -7, -6, -6, 22,
+ 2, -6, -3, 15, 3, 2, -2, 9, 14,-10, -7, 15, 13, 6, -2, 11 },
+ { 5,-20, -5, 28, 11, 10, -4, -4, 0, -7, 3, 5, 2, -5, -8, 2,
+ 6, 10, 9, -9,-18, 3, 14, 1, 3, -3, -1, -6, 7, 7, 2, -1 },
+ { -8,-30, 7, 12, 10, 8, 7,-13,-16, 0, 1, -1, -6,-11,-15, 4,
+ 1, -2, 10,-15, 1, 11, -2, 8, 9, -7, -7, 9, -5, 2, 7,-18 },
+ {-10,-32, 10, 11, 3, -1, 3, -5, 5, 2, 14, -6, 3, 1, 5,-15,
+ -11, 6, 20, 4, 0,-12, -7, 3, 1, -1, 10, 6, -1, -9, -4, -1 },
+ { 1,-25,-14, 12,-11, 9, 9,-16,-24,-17, 22, -9, 11,-30, -3, -4,
+ 6, -7, 9, 2, -1, -5, -6, 2, -1, -1, 10, 1, -3, 3, 4, 8 },
+ {-14,-26, -6, 9, 8, 17,-11,-24, -7, -4, -8, -2, 10, 2, 2, -1,
+ 2, 13, 12, -7, 4, -6,-10, 6, 6,-13,-11, -7,-16, 0, -2, 5 },
+ { -4,-30,-13, 12, 16, -6, 12,-16,-13, 5, 15, -2, -2,-10, -7, 7,
+ 11, -1, -4, -2, -4, 7, 4, -8, 1, 3, 0, 11, 3, -2, -5, 4 },
+ { -4,-21, 20, 22, 2, 20, -8, 1,-12, -5, -9, 4,-10,-17, -3, -8,
+ -3, 3,-12, 1, -3, 0, 7, 4, 7, 7, -3, 7, 5, 3, 1, -5 },
+ {-12,-20, 2, 29, 11, -6, 9, -7, -6, -4, 0, 6, 17,-13, -2,-10,
+ -17, -1,-18, 2, 0, 14, -6, 1, 0, 3, 2,-10, 1, -5, -2, 5 },
+ { 16,-37, -1, 26, -2,-14, 1, -5,-14, 2, 2, 3, 6, 1, 1, 4,
+ 0, -1, 0, -2, -2, 4, 9, -6, 0, -2, 10, -7, -2, 4, 1, 0 },
+ { -9,-24,-12, 5, 5, 3,-17,-14, 4, 3, 2, -4, 10,-22, -8, -3,
+ 6, 1, 12, -8, 4, 1, 9, -1, 18, -3, 6, 5, 3, -5, 9, -5 },
+ {-14,-33, -2, 20,-13,-10, 2, -7, -1, 11, -9, -8, 18, -3, 1, 8,
+ 0, -2, 10, 7, -2,-13, 9, -3, -4, 5, -2, -2, -1, -5, 1, -7 },
+ {-10,-23, 8, 14, 1, 7, 1, -3, -7, 4, 1, 1, 8, -7, 15,-14,
+ 13, 14, 2, 5,-13, -5, -8, -1, 6, 3, 6, 9, 6, 15, 14, 5 },
+ {-13,-25,-10, 13,-17,-24, -7,-13, -6,-10, -8, 2, 0,-13,-10, -4,
+ -8, 4, -9, 9, -4, 4, -3, -3, 3, 3, -5, -9, 1, -2, 11, 2 },
+ {-12,-23, 1, 18,-11, -2, 5, 9, -5, 5, 14, -9, -3, -2, -6, 2,
+ -2, 11,-13, 1, -3, 11, -9, -4, -2, -6, 8, 10, 1, 4, 2, 1 },
+ { -5,-18, 16, 22, 2, 0, 8, -6, -9, -7, 10,-16, 23, 10,-11, -1,
+ 7, 2, 7, 2, 1, -5, 6, 1, 0, -4, 9, 2, -3, 1, 0, -4 },
+ { -3,-26, 14, 11, 2, -9, 17, -2, -1, -5,-16, -9, -5, 10,-13, 1,
+ 6, 12, 10, 11, 0, 0, -3,-14, 6, -2, 0, 4, -5, -1, -7, -1 },
+ {-10,-33, 1, 8, 11, -5, 1, -6, 7, 4, 5, 6, 1, -2,-10, -5,
+ -6, 12,-11, 5,-10, 4, 12, -1, -1, -3, 4, -1, 9, 0, 16,-17 },
+ {-14,-37, 7, 7, -2, 5, -8,-11, 2,-13, 4,-19, 1, 8, 8, 4,
+ -9, 2, -4, 3, 12, 2, 4, -4, -8, 8, 1, 4, 8, -1, 6, -2 },
+ { -6,-30, 18, 17, 1,-22, -3, 4, -7,-10, 7, 0, -8, 8, -1, 4,
+ 2, 8, 6, -2, 2, 7, 4, 4, 3, -6, 2, 1, -3, 1, -1, -5 },
+ {-17,-18, -3, 22, -8, 1, 9, -2,-17, 20, -5, -5,-12, -5, 4, -5,
+ -9, 8, -2, 16, -3, 0, 19, -8, 8, 1, 2, -4, 0, 11, 0, -3 },
+ { -9,-23, 3, 10, 4, 4, -3, -2, -2, -2, 1,-22, 11, 0, -2, 5,
+ -2, 14, -9,-11, -4, 7, 5, 32, 1, -3, -7, 0, 21, -9, 7, -6 },
+ { 0, 0, 0, 2, -1, 1, 0, 1, 3, 0, 0, 1, 0, 1, 0, 1,
+ -3, 0, -1, -2, 0, -1, -1, -3, -1, 1, -4, 1, -1, -5,-69,-19 },
+ { -3, -5, -8,-12, 4, -3,-19,-11, -5, 0,-14, 7, 18, -6, 7, 22,
+ 8, 14, 15, 10, 3, -1, -3, 5, -1, 7, -7, 1, -6, 3,-26,-11 },
+ { -1, -6, 4, -4, -5,-16, 0, -6, -3, 11, 1, 0, 9, 5, 16, 3,
+ -4,-33, -4, 4, -7, 0, 1, 6,-11, -2,-13, -2,-18, 20,-25,-16 },
+ { 4, 0, -1, 0, -5, 1, 0, 2, 0, 11,-10, 4,-10, 7, 16, 2,
+ 16, 15, 2, -1, 2, 9, 2, 8, -3, -5, -2, 0, -3, 0,-33, -2 },
+ { -3,-15, 10, 10, -9, -1, 7, 3, 5, -5, -8, -8, -3, 15, -9, 4,
+ 12, 13,-13,-14, 10, -6, 9, 22,-27, 23, -1, 5,-24, 2,-30, 5 },
+ { 0, -2, 7, -5, -5, 3, 5, 3, -3, -5, 2, 1, -4, 3, -3, -1,
+ 1, -2, 10, 22, -3, -4, -2, -2, -7, 3, 8, 1, 14, 4,-37, 9 },
+ { -3, -4, -1, 1, -4, 0, 6, 2, 6, -7,-10,-10, -1, -4, 11, -3,
+ 7, -6, 4,-12, -1, 5, 1, -7, 10, -6, 17, -4, 8, 3,-40, 13 },
+ { 2, 12, 4, -7, 14, -3, 16, -2, 18, 2, 13, 5, 5, 1, 11, -1,
+ 0, 9, 2, -6, -1, 2, -6, 2, -5, 3, 5, 1, -1, 1,-32, -7 },
+ {-16, 11, 7, -4, 2, -5, -9, 9, 11, 11, 15,-13,-11, 11, 9, 4,
+ 3, -8,-10, 12, 12, 0, 0,-16, -9, 13, 2, 9, 4,-13,-33, 3 },
+ { 6, 4, 5, 4, 3, -1, 5, 6, 4, 2,-11, -1,-15,-11, -1, 1,
+ 11, -3, -2, 24, -4, -6,-25,-10,-15, -8, 0, 0, -5, 4,-30, 2 },
+ { 10, -3, -6, 1, -9, -5, 6, 9,-10, -3, 8, -1, 4, -1, 11,-11,
+ 3, 9, 11, -3, 6,-17, 5, -8,-33, 9,-13, 19, -2, 9,-25, 2 },
+ { 0, 0, -1, -3, 0, -2, 1, 0, 0, 2, 1, 0, -2, 0, -1, 2,
+ 0, -1, 4, -1, 2, -3, 4, -2, 3, 3, 1, 0,-15, 12,-63, 27 },
+ { -2, 14, 9, -1, 3, 0, 1, 1,-19, 15, 3, 4, 0,-10, 1, -5,
+ 3, 0, -5,-10, 2,-16, -4, 8,-12, -6, 7, -5,-10, -1,-33, -4 },
+ { 0, 3, 1, 3, 1, 2, 4, 4, 9, -6, -8, -5, 1,-12, 3, 8,
+ -10, 6, -1, 1, 13, -5, -5, 2, -4, 13,-18,-10, -7, -9,-33, 10 },
+ { -6, -3,-12, 5, -1, 11, -6, 0, -2, 1, 2, -7, 3, 1, 3, -2,
+ 1, 8,-10, 7, -1, -3, 3, 0, 13, 1, 6, 7,-16, -7,-39, 8 },
+ { -6, -1, 11, 6, -3, 8, 3, -5, 3, 0, -5, -2, -6, -3, -4, 2,
+ -3, 13,-11, 1, 7, 5, 19, -5, -3,-15, -1, 7, -1, 6,-33, 8 },
+ { -7, 3, -4, -3, -4, 1, 6, -5, -5, 6, -8, -1, -7, 4, -1, -6,
+ -2, 1, 7, 0, 1, 1, -5, 2, -2, 0,-13, -2,-31,-14,-39,-12 },
+ {-10, 9, 0, -3, 1, -1, -1, 0, 1, -5, -1, -4, -2, 5, 2, -7,
+ 18, -8, -2,-19, -7, -7,-12,-14,-11, -1, -9,-13, -7,-12,-31, -9 },
+ { -3,-16, 10, 9, 1,-10,-12, 2, -2, 2, 7, -3, -3, 1, -4, -5,
+ -9, 5, 7, 3, -1, 4,-11, -8, 4, 13,-10, 13, 10, -4,-36, 1 },
+ { -7,-12, 4,-20, -7, -7, 2, 11, -1, -2, 3,-12, 1, 0, -6, -7,
+ 6, 4, 13, 3, -3, 4, 3, -6,-12, 5, -5,-22,-13, -8,-37, -6 },
+ { -7, 5, 3, 5, 7, 9,-14, -3, 10, 17, -1, 1,-12, 5, -6, 0,
+ -4, -9, 0,-11,-14, 3, 13, 6,-25, -8,-12, 4,-10, 18,-30, -1 },
+ {-10, 6,-10, 6, 6, 1,-10, 0, -7, 5, -2, 17,-18, -4, 0, -3,
+ -16, -6, -3, -8, 5, 1, -4, 6, -7, 16, 6, 10, -1, 0,-32,-11 },
+ { -1, 9, 9, -5, 4, 9, 6, 9, -4, -2, 7, 11, 4, 2, -5, -4,
+ -6, 0, 2, -3, -1, 5, 10, 0, 12,-10,-18, -3, -1, 14,-33, 2 },
+ { 4, -8,-18, -4, -5,-11, 4,-10, -4, 9, 13,-12, 1, -6, 1, 2,
+ 4, -9, 8, 3, -6, 21, 13, -1, -2, 1, -2, 6, -7, 0,-30, 1 },
+ { 6, -1, 2, -3, -1, -4, 6, -4, 0, 4, 2, 2, -9, 2, 6, 3,
+ -2, 4, -1, 9, -6, 0, 7, -8, 5, 19, -2, 9, -5, 2,-33, -8 },
+ { 2, 1, 12, -5, -8, 8, 3, -2, -4, 1, -2, 5, -4, -9, -8, -8,
+ 7,-11, -4, 6,-10, 7, -1, -1, -2, -1, 16, 32, -7, 20,-33, -6 },
+ {-18, 2, 6, 13, 9, 9, -1, 3,-17, 24, -2, -6, 28, 8, -2, 6,
+ 3,-10,-34,-16,-13, -4,-15,-11,-12, -3,-10, 4, -8, 4,-31, -4 },
+ {-11, 0, 18, 2,-16, -9,-13, -2, -2,-12, -3,-22, 30, 0, 8, 3,
+ 9, -4,-16, 1, 0,-11, 15, -2, -4, 6, -5, 6, 1, 2,-25,-12 },
+ { 14, -1, 5, 7, 3,-15, -8, 1, 5, -2, 12, 13, 11,-25, 3, 1,
+ 0, -2, -4,-16,-23, 0, -5,-17, 7, 5, -9, 6, -5, 2,-32, -7 },
+ { 3, -1, 6, 14, 2,-12, -9, -9, 4, 7, 4, 6, 5, -8, 4, 2,
+ 4, 5, -2, 8, 8, -6, 0, 10,-20, -1, 3, -1, 8, 23,-33, -5 },
+ { -3, 11, -6, 3, -4, 5, 7, 3, 4, 5, -2, 3, -1, 30, 6, 1,
+ 8, -6, 0, 0, -9, 6, -9, 4, 2, 9, -6, 1,-12, 0,-34, 18 },
+ {-17, 13, 0, 1, 9, -4,-11, 0, 7, 0,-10, -4, -1, 6, -6, 4,
+ 1, 6, -9, 3, -5, -6,-11, 2, -4, 14, 23, -3, 2, 5,-30, 12 },
+ {-14, 5,-27, 2, 0, 7, 1, 4, 30, 8, 7, 5, 1, -1, 0, 5,
+ 8,-10, 48,-11, 12, 33, 6, 8,-15, 20, -2, -5, 32, 5,-19, 10 },
+ {-16, -4,-12, -7, -2, 0, 8, -6,-20,-18, 16, -3, 0, 31, -2, 11,
+ 2, -9, 49,-19,-12,-23, 10, 26, 16, -2, 4,-21,-14, 13,-11, -9 },
+ { -5, -9, -1, 3, -5,-21, 2, 10, 0, 0, 10,-21, -7, 7,-26, -9,
+ 22, 32, 58, 11, -3, 11, -5, -8,-13, 6, -5, -9, 1, 10, 14, -8 },
+ { 7, 7, 10, 3, -2, -1,-11,-11, -6,-43, -3, 14,-19,-18, 19, 18,
+ -32, 10, 45, -6, 6, 21,-20,-12, 2, 4, 6, 6, -4, 3, 3, 1 },
+ { 21, 22, -3, -2,-11, -6, -1, -2, 8, 8, 32,-21, 7, 28, -4, -6,
+ -3, -2, 50, 2, 2, 27, -5, -8, 12, 7, -5, -1, -4,-17, 27, 6 },
+ { 13, 7, 2, -6,-12, 2,-10, -5,-17, 11, 4, 17,-12, -2, 5,-17,
+ 37,-16, 48,-14,-18, 29, 8, 24, 11, -5, -9, 11, -1, 1,-13, -3 },
+ { 1, 1, -1, 2, 0, 0, 0, -1, 1, -1, 7, 2, -3, 3, 0, 6,
+ 2, 10, 54,-25, 7, 54, -5, -6, -1,-15, 9, 13,-24,-15,-12, 3 },
+ { 21, 5, 8, 3, -3, -4, -2, -4, 3,-11, -5, -8, 9, 16, 8, -9,
+ -10, -3, 46,-46, 2, 1,-10, 10, 17, 11,-20,-36, 10, 14, 0, -5 },
+ { 7,-13, -6, -9,-24, 45, 2, 8, 8, 0, 17, 20, 12,-24, 1, -7,
+ -15, -3, 46,-13, -2, 20, 1,-13,-11,-13, 2, 15, 1, 10, -1, 3 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, -2, -1,
+ -16, -9, 31,-69,-34, 26, 7, 17, -1, -6, -1, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -4,
+ -5,-20, 18,-82, 22, 3, -7, 9, 4, 6, 2, -4, -1, 0, -2, 2 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, -1,
+ 15, -5, 62,-36, 4, 52, -7, 5, 0, 6, 1, 2, 1, 1, -1, 0 },
+ { 3,-19, 19,-20, 13, -4,-11, 8, 8,-16, 10, 1,-14, 30, 1,-33,
+ 10,-11, 45,-30, 3, -4, -3,-13, 7, 12, 3,-22, 3, -2, -4, -2 },
+ { -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 1,
+ 11, 8, 70, 48,-10, 21, 4, 9, -9, -9, -4, -6, 0, -1, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0,
+ 2, -1, 80, 2,-15,-36,-10, -5, -2, 8, -2, 2, 0, 0, 0, 0 },
+ { 10, 8, -8, -8,-24, 12, -1, 0, 20, 9, -1, -2, 2, -2, 12,-10,
+ -2,-13, 35,-43, 44, 15,-10,-25, 4, 10, -3, -5, -5, 7, -1, 3 },
+ { 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, -2, -1,
+ -18, 9, 49,-72, 7, -8, 7, -5, 2, 3, 2, -2, 1, -2, -3, 1 },
+ { -1, 4, -3, 10, 19, 4, 3, 20, 6,-24, 6, 9, 8, 15, 18, 18,
+ -36, 19, 57,-11, 4, -3, 8, 7, 2, -3, -2, -9,-15, -2, 12, -4 },
+ { 20, 3, 11, -9, -4, 22, 42,-25, 1, 5,-10,-19, 0, 9,-16, 5,
+ 2, 10, 44,-29, 17, -3, -9, -2, -1, 8, 14, -7, -1, 16, -5, 1 },
+ { -7, 16,-11, 12, 6, 33,-15, 14,-23, 2,-26, 8, 2, 10, 0, -5,
+ 8, -8, 38,-38, -4, 5, 5, 5, 1, 22,-15, 7, 6, 0, 4, 28 },
+ { -1,-12, 2, 10, -2, 0, 7, 17, 12, 22, -4, 10, 25, 29, 5, 18,
+ 4, 1, 27,-39, 31, 17, 2, 2, 22,-23, 13, 16, 1, -7, -4, -5 },
+ { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, -2, 0,-14, 0,
+ -7,-11, 49,-22, -4, 19, 17,-39, 4,-29, 10, 2, 36, -4, 23, -1 },
+ { -2, -2, -2, -2, 1, 15, -5, -7,-16, -8,-19, 16, -3,-20, 36, -9,
+ -3, 20, 39,-20, 0, 2, 27,-16, 10, 10,-14,-22,-16, -3, 13, -8 },
+ { 5, -9, 6,-25, 7, 37, 13,-10, -5, 3, -5, 7, 18,-22, -7, 9,
+ -5, -4, 50,-11, -4, -5, -5, 8, -4, -2, -4,-27, 14, 20, 7, -9 },
+ { 0,-14,-10,-27,-14,-17, -6, 26, 10, 2, 14,-12, -5, 0, 8, 9,
+ 0,-28, 55, -7,-12, -7, 4,-10, 10, 7,-12, 11, 3, 5, 9, -8 },
+ { 2, 23, 4, -2, -1,-20, -2, 14, 10, -9, -9,-24, 10, 0, 11,-12,
+ 12, 11, 49,-25, -2, 29, 7,-13, 21,-10, 11,-17, 3, 1, -8, 5 },
+ { 3, 0,-14, -6, 18, -2, 17, -9,-19, 9, -5, 9, 14, 6, 19, -3,
+ 27, 1, 41,-21, 20,-15, 33, 0, 26, 14, 7, 10, 3, 20, -3,-12 },
+ { -1, 16, 15, -8, 3, -8, -8, 21, -5,-16,-29, 4, 1, -6, -4,-28,
+ 2, 31, 37,-26, -2, 13, 24, 8, -9, -6,-29, 10, 7, 2, 7, 8 },
+ {-10,-10, 11, 13,-32, 2, 16, 9, 14, 23,-15,-13, 24, 13, 4,-27,
+ 14, 12, 31,-18, 17, 23, -2, -7,-14, 9,-17, -6,-10, 20, 9, 6 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0,
+ 5, 1, 89, 8, 10, -6, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, -1,
+ 4, -7, 64,-50, 7, 37, 2, 5, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { -2, 5, 3, -4, -4, -3, 2, -3, 3, -3, 5, 4, 1, -6, -1, 1,
+ 6, -2, 50,-35, -7, 43, 7, -7, -5,-26, 24, 21, 3,-15, 5, 6 },
+ { -8, 21,-19, 33, -8, 22,-11, 17, 3, 0, 0, -2, 1, -3, 6, -1,
+ 10, -8, 4,-11, -4, -5, 0, 8, -4, 3, 1, -4, 4, 2, 8, 4 },
+ { -7, 5,-20, 9,-22, 3,-14, 1, 6, 13, 23, -2, -4, -7, 2, 0,
+ 11, 4, 6, 3, -7,-11, -7, 4, 5, 5,-12, 8, 2, 4, 7, -3 },
+ { -7, 6, -4, 20,-20, 16, -2, 7, 6, 16, 11, 12, -7, -7, 5, 3,
+ -9, -4, 1, 2, 5, 2, 1, -9, -2,-17, -4, 6,-10, 7, -7, -6 },
+ { -9, 18,-17, 12,-24, 1, -1, 4, 14, 9, 4, 3, 2, 8,-12,-14,
+ 4, -8, -4, 7, 7, 6, -1, 13, -9, -4, -1, 1, 0, -4, 15, 8 },
+ {-25, 2,-11, 6, -5, 24,-28, -5, 8, 12, -2, 6, 8, -3, 8, -9,
+ -1, -5, -1, -5, 6, -1, -1, -1, -4, 8,-12, -2,-13, 7, 2, 1 },
+ {-14, 14,-18, 20,-10, 12, -2, 9, 1, 0, 12, -2, 15,-10, 26,-17,
+ 16,-11, 10,-10, 9, -2, 4, -8, 2, -3, 4, 4, 2, -3, -5, 1 },
+ {-18, 12,-18, 21, -6, 12, -6, 13,-25, 18, 1, 11, -9, -5, 0, 10,
+ -5, 3, -3, 8, -9, 7, 4, 2, -9, 0, 5, 0, 2, -3, 9, -8 },
+ { -4, 16, 1, 18,-30, 9, 1, 6, -8, 13, 13,-12, -6, -1, 13, 7,
+ 6, 2,-15, -3, 5, 5, 1, -6, 1, -5, 0, 2,-16, 0, 3, -4 },
+ {-21, 1, -2, 6,-43, 18, -1, 5, -1, 4, 6, -2, -1, -3, -1, -3,
+ 0, 1, 2, -9, 0, -1, 0, -2, 0, -1, -1, -2, 6, 0, 1, -2 },
+ {-23, 10, 4, 7,-32,-11,-18, 2, -2, -7, -6, -3, -3,-12, 19, 3,
+ -5, -6, 16, -6, 16, 2, 16, 16, 8, -2, 13, 8,-15,-11, 2, 10 },
+ { -8, 2,-13, 2,-29, 24,-20, 19, 1, 10, -4, 10, 1, 2, -9, 11,
+ -1, -2, 9, -5, 19, -7, 16, -9, -2,-18, 11, 1, 1, 0, 7, -3 },
+ { -6, 3, 4, 13,-26, 10,-10, 28, -7, 28, 1, 7, 0,-14, 5, 7,
+ 4, -4, 3, -2, 3, 3,-11, 7, 6, 4, 0, -1, 2, -1, -3, 2 },
+ { -6, 16,-31, 13,-10, 17, -6, 4,-14, 4, 4, -1,-10, 12, -5, 1,
+ -14, 15, 0, -8, 1, -5, 3, 3, 9, -5, 7,-20, 7, 4, 11, -5 },
+ {-19, 3,-17, 14,-12, 16,-22, 18, 14, 8, -2, 4, 10, 12,-14, 4,
+ -3, 2, 3, 7, -7, 7, -6, 2, -2, -4, -5, 0, -5, -2, 2, 1 },
+ { -9, -7,-11, 24,-36, -9,-11, 5, 7,-12,-13, 18, -2, 20, 1, -4,
+ -1,-10, 15, -6, 14, 1, 0, 2, 1, 2, -9,-16,-11, 7, 13, 0 },
+ {-24, 24,-18, 18,-22, 14,-11, 13,-12, 11,-10, 11, -7, 11, -5, -4,
+ -1, 1, 5, 2, 3, -1, 1, -5, 7, -4, 5, -6, 8, -7, 8, -6 },
+ { -6, 18,-22, 22, 5, 11, -1, 6, 19, 22, 8, 4, -8, 20, -2, 15,
+ -6,-18, 0,-33, -9,-12, -1, 6, 5, 2, 5, 5, -5,-17, -3, -3 },
+ { 1, 11,-16, 9,-18, 11, -4, 18, 20, 26,-10, 8, 1,-11, 8, -4,
+ 0, 7, 3, 5, 2, 2, 10, -2, -4, 4, -4, -2, 1, -4, -5, -1 },
+ {-10, 6, -1, 18,-17, 27, -3, 10, -2, 12, -7, -9, 1, 1, -1, 7,
+ -12, -1, -7, -6, -1, 8, 3,-15, 8, 9, 3, -7, 4, -1, 1, -1 },
+ {-14, 6,-16, 22, 2, 5, 0, 5,-18, 11, 6, -3, 22,-20, -9, -3,
+ 6, -6, -7,-15, 1, 15, -8, 11, 8, -3, -8, 1, -8, 2, 6, -2 },
+ {-21, 5,-19, 19, -7, 4, -7, 0, -8, 6, 12, 5, -3,-22,-13, -6,
+ -1, -3, -2,-14, 6, -3, 1, -8, -7, -5, -6, 11, -3,-10, -5, 2 },
+ { -1, 9,-12, 15, -6, 6,-19, 14, -9, 11, 3, 12,-17, -3, 8, -4,
+ -3, -4, 1, -5, 4, 5, -7,-15, -7, 15, -6, -5, 1, -5, -3, 1 },
+ {-12, 20,-15, 20,-14, 3,-14, 9, -6, 33,-13, 6, -2, 8, -6, 7,
+ -5, -6, -3, -3, 0, 8, -3, -3, 1, -2, 2, 2, 6, -5, -5, -2 },
+ { -7, 12,-18, 12,-18, 10, -4, 8, 2, 4, 8, 9, 0, 3, -8, 3,
+ 6,-12, -4, 1, 25, -5, -9, 6, -7, 0, -9, -7, 3, -5, -4, -4 },
+ {-18, 12,-10, 11,-22, 0,-15, 5, -2, 2, -3, 6, -4, -4, -3,-15,
+ -2, -3, 21, 6,-12,-11, 19, 3, 3,-14, 7, 0,-11,-22,-10, 0 },
+ {-15, 2,-30, 15,-17, 13,-16, 8, -7, 10, -8, 2, 11, 3, 10, -7,
+ 7,-22, 12,-10, 3,-12, 6,-10, 12,-10, 7, -8, 5, 2, 9, 1 },
+ { -9, 11,-14, 6,-10, 21, 5, 12, -5, 5, 7, 21, 6, 2, -2, -1,
+ -1, 4, 2,-20,-18, -1,-14, 3, -1, 4, -7, 10, 1, 11, 4, -4 },
+ {-22, 8,-30, 13,-21, -4, 4, -1, 12, 9, -2, -3, 2, -6, 4,-13,
+ -2, 8, 8, 1, -7, 3, -4, -5, -1, -7, -2, 8, 8, 7, 8, 0 },
+ { -6, -4,-35, 16,-13, 15,-11, 14, -7, 9, -1, 11, 7, 0, 13, 10,
+ -1, 8, 1, 1, -2, 8, -1, 2, 2, 3,-10, -1, 7,-13, -3, -7 },
+ {-15, 7,-16, 14,-18, 17, -6, 14, 3, 4, 7, -3, 10,-22, 5,-15,
+ 4, -4,-11, 15,-15, 11,-11, 20, 1, 0, 2, 1, 11, -3, 11, -7 },
+ {-12, 3, 5, 16,-37, -1, 15, 15,-15, 10, 3,-10, 1, 15, 7,-15,
+ -13, 8, 9, -3, 2, 12, -8, 2, -5, 0, -3, 4, 5, -9, -4, 5 },
+ {-16, 26, -4, 14,-22, 26, 6, -3, -8, 4, 21, 6, 16, -4,-11, 7,
+ -10, 3, 3, 7, -4, 2, -9, 8, -2, 2, 5, -2, -4, -2, 7, -1 },
+ { -7,-10, 4, 3, 2, -4,-12,-10, -4, -5, 16, 19,-16, 1, 2, -9,
+ -10, 0, 9, 7, -8, 3, 12, 8, -6,-11,-13, -1, -3,-20, 6, -5 },
+ {-14,-17, 3, -5, 14,-12,-12, 8, -6,-25, 21, 21, 10, -8,-12, 4,
+ 10, -4, 3, -9, 11, 9, 0, 4, 2,-15, 1,-14, 4, 1, 0, -4 },
+ { -4, -9, -3, -1, 6, 3, -6, 6,-10, -4, 14, 8, 2, -3,-12,-19,
+ 0, 11,-20, 1, 6, -2,-27, -6, 10,-17,-14,-17, -9, 8, -8, 3 },
+ {-12,-13, 16, -4, -2, 12, -7,-11, 2,-13, 3, 7,-16,-18, -1,-12,
+ -2, 1,-12, -9, -2, -6, 2, 9,-22, -3, -4,-14, -7, 7, -1, 2 },
+ { -7, -8, -8, 15, 15, 18, 15, 16, -4,-37, 11, 15,-12, -1, -3, 3,
+ 6, 6, 0, -5, -3, -5, 9, 1, 1,-11, -1, -8, -6, 2, 3, 0 },
+ { -6, 7, -5,-12, 13, 10,-18, -4, -3,-21, 6, 16,-15, -7,-12, -9,
+ 1,-12, -1, 10, -2, -1, -3, 4, -4, 1,-16, -1, 12, -9, 5, 9 },
+ {-14, -5, 9, 3, 4, 26,-28, 3, -6,-24, 4, 5, 3, 13, 5, -1,
+ 3, -1, 3, 1, 1, -5, 3, 0, -7, -8, -7, -3, 3, -5, 4, 0 },
+ { -4, 2,-10, -6, 25, 26, -6, 10, -6, -8, 15, 11, -6, -3, 2, -7,
+ 5, 14, 9, -1, 0,-12, 4, -4,-10, 1, -3, 3, -2, -2, -6, -1 },
+ {-10, 8,-15,-10, 19, 17, -8, 0, -3, -7, 7, 5,-13, -1, 7, -7,
+ 1, 13,-12,-13, 17,-12, 1, 26,-18, -3, -5, -6, 4, 5, 8, 1 },
+ { 2, -5, 3, 0, 0, 0, 2, -3, -2, -5, 7, 13, -4, 9, 0, -5,
+ 4, -1,-11, -8, -4, 0,-13, 2,-47,-23, -8,-11, -4, 4, -2, -3 },
+ {-18, -4, 4, 5, -1, 17,-12, -8, 1,-12, 7, 20,-12, 3, -2,-11,
+ 16, 12, -6, 1,-13,-16, -6, -3, -3, -5, 4,-12, -5, -9, 10, 1 },
+ {-11, 0, 4, 7, 7, 8, 3, -1, 3,-19, 32, 8,-19, -8, 2, 4,
+ -12, 15,-16, 3, 1, 9, -2, 1, -2, 8, 5, 6, -4, -1, 11, -8 },
+ { 3, -1, 4, -2, 14, 32, -9,-23,-10,-12, 22, 15, -1, -2, 10, 0,
+ 4, 6, -8, 4,-15, -2, -1, -4, 0, -8, 4, 1, -8, 3, 4, 1 },
+ {-17,-12, 6, -8, 16, 13,-20, -8, -1,-16, 10, 21,-19, 11, -9, -5,
+ 7, 18, -6, 7, -7,-18, 13, 2, -2, 8,-12, -9, 2, 4, -5, 16 },
+ { 4, 0, 17,-11, 12, 7,-12, 5, -1,-25, 30, -8, -7, -6, -4, -7,
+ 9, 8, 7, 3, 3,-16, 8, 0, -2, -2,-18, -3, -4, -5, 1, 4 },
+ { -3, -6, 6,-16, 17, 6, -3, 2, -9,-17, 12, 11, 11, 2,-20, 8,
+ 1, 1, 0, 2, -2, -6,-21,-13, -9,-15, -1, -8, -6, -8, 0, -2 },
+ {-11, -7, 6, -9, 3, 6, 8, 16, 4, -5, 23, 26,-10, -3, 4, 0,
+ 2, 2, -4, 4, -2,-12, 12, 10,-11, 0,-10,-16, 3, 0, 0,-10 },
+ { -5,-16, 10, -6, 27, 13, -3, 4, -2,-13, 15, 5, 2, 5, 3, -4,
+ 13, 12,-11, -7, 0, 1, 11, 12, 2, 13,-15, -8, 9, -2, 3, 8 },
+ { -5, -8, 4, 3, 9, 3,-11, 10, 14,-25, 14, 8, -2, 5,-12,-21,
+ 2, 10, -7, 2, -3, 2, 0, 2, -1, -3, -5, -6, -1,-16, 2, 8 },
+ { -1, 5, 1,-11, 5, 9, -7, 8,-13,-12, 4, 12, -4, 1, -1, -1,
+ 27, 29, 10, 15, 2, -6, -3, 4,-21, 10, -9,-11, -6, -1, -9, -3 },
+ { -6, -3, -1, -6, 11, -5, 0, -2, -5,-31, 11, 3, -1, 5, -3, 4,
+ 5, 7,-10, 5,-10,-13, 4, 12,-15, -2, 2, -7, 1, -9, -3,-10 },
+ { -3, -7, 17, -8, -5, 36, 8, -7, -8,-20, 12, 8, 1, -1, 3, 0,
+ 1, 4,-10, 3, 1, 4, -2, -3, -2, -3,-10, 4, -1, -7, 3, 2 },
+ {-13, -3, -5, 9, 22, 6,-23, 3,-10, -7, 17, 17, 18,-14, -8, -8,
+ 2, 4, -8, 2, -3, -8, 6, 4, -1, 7, 0, 0, -3, 0,-12, -3 },
+ { -3,-10,-15, -3, 9, 3,-23, -9,-13,-18, 12, 13, -2, 0, 1, 8,
+ -1, 2, -7,-12, -5, 14, 2, 1,-22, 6,-10, -8, -9, 28, -7,-14 },
+ { -3, 1, 2, -1, 13, 7, -2, -7, 1, -3, 6, 9, -3, -2, 4, -2,
+ 2, 1,-10, -2, -2,-22, -2, -7,-10, -5,-11,-27,-12,-16, 4, -7 },
+ { 2, -6, -3, 1, 8, 0, -2, 12, -3, -4, 58, 15,-10, -4, -2, 2,
+ -2, 0, -2, -6, 2, 4, -1, 1, -4, 1, -1, -5, -4, -3, 3, 1 },
+ { 10, -1, 0, 5, 21, 7,-14, 6, -3,-16, 15, 17,-16, 13, 3, -6,
+ -4, 6,-12, -5, 1, -4, -7, -8, 2, 3, -6, 6, -1, -8, 5, 4 },
+ { -6, -2, -8,-11, 15, 10, 0, 8, -6,-15, 33, 8, -2, 18,-15,-11,
+ 5, -1, 0, 15,-15, -4, -4, -1, 10, 7,-13, 4, -4, 0, 8, 3 },
+ { -7, -2, 0, -2, 0, -2, -4, -5,-14,-16, 12, 38, 7, 12, 6, -4,
+ 0, -1, 0, 3, -2, -6, 0, 2, -9, 1, 0, -1, 0, -2, 4, 1 },
+ { -8, -4, 18, 1, 14, 5,-12, -3, 20,-17, 5, 19,-11, -8, 11, -3,
+ 3, 9, -7, -8, 9,-17, 2, 15,-10,-11, 5, -5, 7, 15, -6, -2 },
+ { -7, 2, 38, 5, 19, 16, -5, 4,-13,-20, 0, 4, -4, 6, 4, 2,
+ -7, 6, -8, -2, -5, -7, 6, 3, -4, -3, -2, -3, 7, -6, -4, 0 },
+ {-11,-12, 8,-15, -3, 14, -7,-22,-11, 2, 22, 14,-19, 2,-19, -6,
+ 1, 3,-18, 14, 2, -6, -2, -8, -3, -6, 5, -7, -8, -4, 1, 1 },
+ { 8, 7, 25,-21, 12, -6, -5, -4,-10, 6, 0, 10, 1,-12, 18, -5,
+ -15, 4, 1, 14, -1, 5, 8, -7, 1, -7, -3, 9, 10, 1, -1, 0 },
+ { 9, 10, 32,-15, 8, 2, 11, -7,-18, -8, 2, -6, -9,-16, -3, 3,
+ -1, 3, 1, -5, 4, -2, 1, -8, 0, -6, -3,-11, 1, 5, 0, 0 },
+ { 14, 0, 23,-25, 22, 3, 7, 10, 0, -2, 7, 8, 0, 10, 0, 0,
+ 3, 2, 3,-10, 0, 10, 0, -7, 0, 10, -1, -5, -7, 1, -1, 2 },
+ { 12, 0, 25,-18, -5, -4, 13,-10, 3, -6, 7, 21, 0,-16, 3,-10,
+ -6, 5, -7, -3, 2, 5, 3, -6, 4, 9, -8, 12, -2, 3, 2, 4 },
+ { 31, 15, 27,-20, 10, -7, 15,-10, 9, -8, 4, -5, 3, -3, 5, 6,
+ 11, -2,-12, -2, 6, -2, 1, 2, -1, -1, 1, 1, 3, 1, 1, 2 },
+ { 12, -4, 13,-23, 12, -6, 2, 4, -3, 13, 6, -7, 5,-19, -7, 18,
+ 1, -7, 7, 1, 16, -7, 3, 0, 3, 0,-12, 8,-11, 9, 4, 7 },
+ { 29, 1, 3,-22, -5, 6, 0, 12,-14, 11, 1, 6, -3, 4, 6, -2,
+ 4,-13, 12, 1, 1, 3,-11, 9,-10, -1, -7, 16,-11, -1, 3, 9 },
+ { 4, 4, 36,-23, -5, -8,-15, 1, -6, 3, 13, -1, -5, -7, 4, 9,
+ 2,-11, -3, 5, 1, 3, -6, -1, -4, -4, -2, 2, 3, -1, -5, -2 },
+ { 19, 10, 6,-17, 2, -4, -2, -4, -3, 13, 2, 2,-13, -7, -3,-11,
+ 9, -6, 1, -9, -5, 4, -5, -9,-18, -7,-11, 9, 4,-11, 8, 4 },
+ { 16, -3, 9,-16, 18, -2,-12,-16,-11, 11,-18, 16,-13, 6, 2, 8,
+ 3, 8, -4,-16, 10,-11, -1, -3, -8, 5, -9, -4, 9, -4, 0, -3 },
+ { 14, 15, 3,-23, -5, 7, -8, -6, 2, 17, 2, 12, -8,-12, 13, -1,
+ -9, 3, 1, 1, 19, 15, 4, -1, 1, 2, -3, 2, -3, 1, 5, 3 },
+ { 32, 5,-10,-47, -5, -1, 4, 11, -7, 0, 2, -2, 1, -7, 6, -4,
+ 6, 2, -4, -2, 2, -2, 0, -4, 1, -6, -5, 2, -2, -1, -3, -4 },
+ { 20, 8, 10,-21, -7, -9,-16, 12, 1, 4, 6, -5, 9,-11, -7, 4,
+ -11, 28, -3, 2, 4, -6, 10, -8, -5, -5, -9, 9, -2, -1, 6, -5 },
+ { 38, 3, 23,-25, -6,-18, 3,-10, -8, 6,-10, 1,-10, 2, 2, 0,
+ -7, 2, -4, 5, -1, 8, -3, 0, 3, 3, -1, 1, 0, -4, -4, 0 },
+ { 20, 5, 16,-22, 24,-18, 2,-12,-14, -7, -3, 10, 2, 7,-10, 2,
+ -8, 1, 8, -1, 4, 1, 4, -2, 5, -9,-18, -8,-13, 5,-11, 10 },
+ { 14, 8,-12,-16, 9,-11, -3, -6,-25, -7, 6, 5, -7,-16, 10, 2,
+ -7, -1, -9, -3, 16, 4, 3, 3, -3, -3,-15, 13, -3, 4, 13, -7 },
+ { 16, -9, 19,-23, 7,-19, -3, -5,-15, 11,-21, 21,-16, 18, -1, 6,
+ 10,-10, 18,-14, 16,-15, 6, -5, -9, 5,-17, 13,-10, 13, 0, 10 },
+ { 8, -4, 4,-24, 8,-21,-18, 9,-11, 4, -6, 17, 5, -9, -2, -2,
+ 2, 15, -2, -3, -2, 1, 7,-13, 15,-10, -8,-11, 3, 3, -1, -1 },
+ { 14, 17, 6,-32, 5,-17, -2, 0, 15, -1, -5, 16, 1, -5, -2, 9,
+ -3, 8, 4, -2, -2, -4, -3, 1, 0, 7, -3, 4, -5, 0, -7, 2 },
+ { 24, 6, 22,-12, 8, 3,-14, 4, -7, 8, 6, 5, 6, 1, 6,-12,
+ 15, 10, 4, 11, 9, 6, -7, -4, 10, -9, 2, -1, -5, 11, 15, 3 },
+ { 17, 12, 3,-23, 5, -1, -2, 1, -9, -1, -3, 1, 8, 1, -5, 17,
+ 11, 0, -2,-11, 7, 4, 0,-27, -7, 1, 2, -8, 9, 7, 5, 3 },
+ { 12, 10, 12,-10, -4, 5, -1, 2,-24, 5, -8, 2, 6,-17, 19, 5,
+ 12, -2, 16, -7, -6,-14, 4, 1, -3, 13,-16, 5, -1, 4, 1, 1 },
+ { 31, 9, 11,-17, 10, -3, -7, 7, 1, 2, 2, 4, -3, -1, 11, 4,
+ -5, -8, 1, 4, 15, -6,-28, 1, 8, 3, -6, 5, 17, -2, 2, -4 },
+ { 11, 19, 16,-26, 0, -7, -7, 2,-13,-15,-12, 9, -3, 27, 8, 4,
+ -6, 1, 4, -6, 11, -1, -6, -7, -3, 0, -6, 4, -6, -7, -3, -1 },
+ { 10, 18, 16,-32, 19, -9, -4, -3, -7, 8, 8, -3,-11, -2, -6,-16,
+ 13, 13, -6, -1, 10, -2, -2, -9, 0, -3, 9, 4, 11, -2, -6, 6 },
+ { 9, 4, 19,-33, 4, 7,-12, 36, -3, -1, 8, -2, 2, -8, -9, -4,
+ -8, 0, 1, -1, 0, -4, -4, 3, 0, 3, 6, 0, -6, 2, 0, -2 },
+ { 25, 7, 15,-12, 2,-24, -1, 24, -4, 4, 9, 0, -2, -9, 4, 6,
+ 3, 13, -3, 1, 5, -1, -3, -5, -1, 7, -2, 3, 4, 4, 1, 0 },
+ { 19, 6, 8,-20, 9, -9, 5, -4,-13, 7, 11, -3, 5,-13, -9, 6,
+ -11, -1, 0, 4, 11, 26, 3, 6, -7, 12, 6, -3, 1, -9, 7, 1 },
+ { 15, 6, 19,-23, -3, -9, 3, 16, -6, -4, 6, -5,-10, 1, 16,-14,
+ 2, 0, 2,-13, -3, 8, -6, 3, 1, 1, 2, -5, 12, -4, -8, -3 },
+ { 14, 4, 16,-20, 1, 12, 0, 6, -3, 9, 4, 16, 10,-16, 5, 7,
+ 5, -4, -4,-18, -3,-11, -4, 4, -7, 3, 13, 7, 3, 3, 2, -7 },
+ { 22, 3, -1,-30, 18, -3, -9, 9, -2, 11,-16, -2,-14, 12, 0, 4,
+ -5, 4, -1, 3,-20, 12, 4,-10, -2, -2,-12,-12, 10, 6, 11, -3 },
+ { 15, 7, 2,-21, 5, 4, 9, -9,-33, 7, 7, 3, -6,-14, -8, 10,
+ 12, 0, 2, -1, 5, 4, -2, 0, -7, 0, 2, 4, 0, 1, -3, 8 },
+ { -7, 0, 12, 3, 0, -6, 8, -4, 0, 2, 14,-15, 2, -7,-31, -3,
+ 14, 0, 14,-15, -1, -4,-15, 10, 1, -3, 1, 2, 5, 2, -8, 1 },
+ { -2, 5, 1, 0, -3, 3, 3, -6, -1, 2, -4, 1,-19, 0,-11, 18,
+ 11, 10, 21, 5, 6, 2, 10, 3, -6, 0, -2, 13, 5, -1, -2, 9 },
+ { -9, 1, -5, 0, 0,-15, 8, 4, 8, 3, 8, 12,-13, -2,-39, -2,
+ 4, -4, 5, -3, -4, 3, -3, 3, 10, 5, 3, 2, -3, 5, -2, 8 },
+ { -9, 6, 6, -8, 12,-12, 23,-18, 4,-15, -5, 2,-20, 13, -7, 7,
+ 7,-12, 14,-12, 6, 1, 1, -3, -8, 9, 0, 1, -7, 3, 7, -6 },
+ {-18, 13, 4, 3,-10,-30,-10, -6,-14, 1, -7, -4,-35, 5,-25, 11,
+ 9, 8, 19, -4, -7, -3,-18, -8, 1, 5, 10, -4,-14, -9, 3, -4 },
+ { -6, -1, 4, -9, -9, 4, 20, 0, 0, 3, 11, 7,-16,-17,-20, 11,
+ -6,-14, 1, 4, 19, 2, -8, 6,-15, 3, 6, -5,-14, 3, 7, 2 },
+ { 1, 6, -2, -8, -5, -3, 3, -8, 21, 1, 3, 16,-14, -2, -9, -4,
+ 13, -2, 18, 14, 14, 19,-13, 5,-10, 2, -3, 3, 5, 5, 1, -1 },
+ { -1, -5, -6, -2,-11, -7, 5, -4, 5, -1, 0, 3, -3, 2,-19, 18,
+ 16, 4, 14,-22, -2,-11,-22, 1, -1, 11, 1, 2, 11,-10, 7,-12 },
+ { 1, 4, 5, -1, -9, -5, 1, 12, 5, 6, 12, 9,-24, 23, 1, 20,
+ 14,-11, 13, 5, -2, -2, 5, 6, 2, 1, -9, 6, 10, 5, -4, 11 },
+ { -1, -1, 1, 7, -3, -4, 8,-16, 15, -1, -7, 9,-22,-11,-11, 10,
+ 16, 9, -2, 4, 13, 10, 6, 16, 4, 7, 1, -8, -7,-14, -7, 4 },
+ { 1, 3, -6, 0, 15, -9, -4, 0, 4, 6, 12, 9, -6, -5,-22, 17,
+ 7,-11, 15, -5, 1, 3,-19, 0,-15, -3, 16, 5, 5, -7,-11, 12 },
+ { -2, -1, 13, 2, 4,-24, 37, -5, -2, -6, 12, 7, -2,-23, -4, 9,
+ 2, -3, 3, 2, 3, 3,-14, 11, 0, -4, -2, -2, 3, 10,-10, 4 },
+ { 2, 9, 8, -6,-28, 14, 28,-11, 18,-11, 0, 2, -2, 4,-12, 3,
+ 6, 0, 7, -7, -6, 2, 5, -1, -1, -1, 5, 2, 3, 0, -3, 9 },
+ { -7, 14, 5,-10, -3, 7, 4, -5, 7, -8, -7, 4,-12, 14,-16, 25,
+ 3, 0, 1, -5, 12,-10, 0,-10, 0, 12, 12, 17, 12, 10, -1, 0 },
+ { -4, -2, 5, -2,-17, -3, 5, -5, 7,-17, 1, 5, -4, 4,-20, 0,
+ 11,-15, 13, -8, 10, 1, 1, 5,-12, 9, -8, 0, 6, -1,-11, 4 },
+ { -3, 12, 13,-15, -7, -7, 0, 5, 33, 3, 3, -6,-13, -7,-15, 10,
+ 3, 3, 3, -5, 2, 7, -1, 0,-12, 2, 11, -6, -9, 0, 5, 11 },
+ { -8, 5, 10, -7,-14, -4, 13, 0, 18, -3, -6, 7, 1, -6, 0, 21,
+ 8, -7, 10, -8, -3, 17, -9, 0, -5, 1, 4, 8, -3, 11, -5, 0 },
+ { -8, 8, -3, -8, 8,-11, 16,-16, 17, 0, 8, 16,-17, 10,-16, 10,
+ -8, 6, 11, 0, 10, 7, 4, 5, 7, -5, -5, -6, -7, -5, -1, 16 },
+ { -6, 0, 6, 1, -8, -8, 8, -7, -5,-10,-11, 8,-19, 6, -7, 13,
+ 5, -3, 4, -8, 7, -1,-18, 9, 0, -5, 6, 26, 3, 8, 2, 4 },
+ { -2, -2, 23, -2,-20, 2, 7, -7, -6,-15, 3, 9,-19, -2,-10, 7,
+ -2, 7, 9, 11, 0, 4, -4, 6, 9, -2, 4, -3, 4, 3, 2, 8 },
+ { -6, 12, 10,-10, -7, 4, 17, 11, -6, 1, 12, 11,-18, 8,-12, 4,
+ 1, 13, 6,-13, 23, 9, -5, 8, -2, -5, 1, 3, 0, -2, -4, 4 },
+ { 7, 1, 7,-17, -8, 8, -1, -7, 5, -6, 4, -3,-16, 9,-24, 18,
+ -3, 10, 13,-11, -6,-11, -4, 10, 0, 11, 8, 2, 6, -5,-11, 4 },
+ { -4, 1, -5,-10, 0, -3, 9, -2, 4, -1, 1, 5,-41,-10, -7, 4,
+ -3, 3, 1, 0,-12, 4, -3, 0, 2, -1, -2, -5, 3, 2, -7, 5 },
+ { -2, 1, 4, 4, -3, -6, 1, 0, 12, -5, 11, 0,-17, -3, -1, 11,
+ 4, 1, 27,-12, 0,-14, 2,-15, -3, -9, 0, -7, -3, 15, -8, 6 },
+ { -6, 4, 9, 2, 4, 3, 7,-10, 28, 1, -2, 48, 7, 0,-10, 10,
+ 1, -9, 2, -1, 0, 3, -5, 5, -4, -2, 7, 7, 1, 3, 2, 5 },
+ { -3, 3, -1, 3, -9, 0, -1, 3, 2, -6, 39,-14,-12, 5,-19, 21,
+ 7, -6, 4, -1, -4, 0, -4, 1, 0, -9, 1, 10, 0, -2, 0, 7 },
+ { 4, 2,-29, 12, 5, -3, 16, -6, 15,-13, -4, -1,-13, 22,-16, 17,
+ 16, 4, 9, -4, 4, -6, -4, 11, -8, 7, 8, 4, 3, -3, -7,-13 },
+ { 0, 3, 3, -6, -4, 0, 9, 0, 5, 0, 10, 10, 4,-13,-12, 16,
+ 23, -4,-12, -6, -4, 20, 2, 0, -4, 23, 1, 8, 11, -4, -5, 15 },
+ { -6, 4,-15, -9, -1,-19, 12,-30,-17, -4, 1,-13,-13, 4, -3, 26,
+ 5,-25, 11,-14, -6,-13, 0, -7, 9, 2, 8, -1, -8, 1, -8, 13 },
+ { 1, 6, 1, -4, -4, 1, 2, 0, -3, 2, 10, 6, -6, -2,-11, 4,
+ 32, 15, 15,-47, -8, 3,-12, 4, -5, 4, -1, 0, -5, 5, 1, -7 },
+ { 2, -1, 0, 0, -1, -6, 0, -6, 4, -4, 5, 9, -5, 1, -3, 51,
+ 4, -5, 4,-14, -1, -4, -3, 1, -4, -1, 0, 2, -8, 0, 1, 2 },
+ { 0, 4, -2, -7, -2, -9, 6, -8, 11, -3, -6, 3,-11, -8,-12, 8,
+ 11, 5, 19, 3,-24, 19,-14, 11, -5,-18, -8,-12, -5, -4, -1, 4 },
+ { 16, 9, 10, 14,-18, -2,-18,-27, 10, -5, 12, 14, 4, 0, -2, -6,
+ -12, -7, -1, 3, 4, 7, 11, 10, 5, -5, -7,-16, -3, -6, 6, 9 },
+ { 7, 15, -9, 10,-19, 4, -5,-37, -2, -4, 8, 2, 4, -1, 1, 9,
+ -5, -5,-12, 1, -1, -8, 3, -3, 4, 6, 9, 3, 3, -1, 2, 4 },
+ { 13, 17, 3, 9, -7, -7,-15,-17, -8,-13, -4, -8, 19, 2, 16, 25,
+ 7, 15, 2, 16, -5, -6,-10, -9, -7, -6, -2, -7, 7, 2, 4, 5 },
+ { 24, 7, 9, 8,-13, -2, 0, -4, 1,-13, 3, 6, 7, 10, -4, 15,
+ 5, 7, -4, 5, -5, 3, 13, -7, 5, 15,-11, -2, 7, 5, 8, 6 },
+ { 17, 6,-15, 23, -2, -1, -6, -2, 0, -4, 11, -3, 12, 15, 6, -8,
+ -15, 10, -9, 7, -1,-11, 2, -8, -4, 3, 4,-10, 4, 4, 11, 1 },
+ { 21, 12, -3, 6, -8, 8,-11, -8, -5, -5, 3, 7, -1, -5, 12, 15,
+ -10,-11, 3, 15, 8, 4, 2,-15, 0, 14, 1, -8, -1, 3, 10, -7 },
+ { 16, 12, 5, 13, -6, 15,-23, 0,-17, -9, 0, 4, -9, 13, 6, 18,
+ 0, 0, -4, -1, 0, 14, 5, -1, 8, -4, -8, -6, 5, -2, -2, 0 },
+ { 14, 16, -1, 12,-15, -9, -6,-20, 4, 6, 8, 9, 3, 1, -9, -4,
+ -1,-11, 9, 11,-12, 1,-14, -7, 2, -8, 11, 9, -4, 10, 4,-16 },
+ { 13, 10, 3, 7, 0, -8,-33, -6, 4, -4, 19, -2, 14, 6, 5, 7,
+ 6, -3, -1,-10,-10, -9, 4, -3, 5, 9, 2, 2, 10, 9, -2, -3 },
+ { 11, 10, 25, 18, -1, -6,-21,-21,-11,-16, 6, 5, 14, 4, 8, 7,
+ 0,-10, -7, -9, -5, -4, 3, -1, 1, 6, -1, 6, -2, 2, -3, -9 },
+ { 15, 9, 5, 22,-17, 15, -9, 7, 7, -9, 13, 9, 10, -1, 8, -3,
+ -2, 6, 1, 17, 8,-14, 7, -3, 12, 9, 1, 0, 1, -5, 17,-18 },
+ { 25, 19,-17, 12, -4,-10, 1,-13,-19, -7, -3, 9, 6, -2, 3, 1,
+ 4, -2,-11,-14, -1, -7, -5, -9, 7, -1, -3, 4, -5, 1, 0, -1 },
+ { 20, 8, -3,-10,-24, 3, -6, -2, 0,-12, 14, 6, 7, 11, 4, 7,
+ -12, -5, -8,-10, 5, -1, -4, 4, 16, 7,-14, 6, -1, -2, -7,-11 },
+ { 16, 18, 17, 1,-15, -6, -5, -3, -1,-19, 8, -2, 2, 8, 12,-19,
+ -12, 8, 0, -3, -1, -1, 4,-14, 9, -1,-12, -1, -7, 10, -3, 5 },
+ { 18, 12, -7, 7, 0, -3,-13, 0, -1, -4, 9, -2, 6, -1, 0, 1,
+ 15,-21, 1, -8, 25,-19, 13, -9, 2, 12, 5, -7, -3, -1, -3, 1 },
+ { 13, 16, -4, 9, -2, 2, -1,-19, -7, -4, 18, -6, 14, 18, -5, 4,
+ -6, -3,-19,-14, -1,-12, 10, 6, 7, 17,-12,-13,-10, -4, 5, 4 },
+ { 27, 17, 4, 14, -9, -2, -4, -8, 0, -6, 14,-11, -7, 2, -3, -3,
+ -2, -3,-13, 12, 16, 1, -5, -9,-10,-11, -2, 3, -7, 5, 11, -7 },
+ { 7, 17,-16, -2,-14,-28, -7, -8, 15,-10, 7, 15, 8, 17, 13, -1,
+ 4, -7,-12,-11, 0, 0, 2, 3, -3, 7, -6, 6, 1,-16, 1, -2 },
+ { 23, 11, -9, 15,-23, -4, -6, -4, 2, -9, -7, 9, -8, 3,-13, -4,
+ 8, 18, -6, -2, 1, -5, 6,-14, -5, -2, -6, -5, -3, -2, 4, -5 },
+ { 12, 13, 18, 18,-35, 2, 7,-17, 3,-11, 6, 9, -3, -2, 10, -4,
+ 3, 3, -2, -7, 0, 2, -4, 0, -4, 0, -6, 5, 10, 4, -3, -1 },
+ { 19, 11, 1, 20,-14, 4, -9,-13, -2, 11, 0, 17, -1, -1, -1, -1,
+ -5, -8, 0, 5, -1, -8, 5, -1, 3, 2,-12, 21, -2,-24, 5, 7 },
+ { 15, 15,-15, 17,-14,-22, 3, -4,-11, -3, -7, 1, 18, 10, 1, 10,
+ -6, -3, 8, 2, -7, 0, -2, 1, 1, 2, -9, -2, 1, 2, -3, 4 },
+ { 45, 13, 8, 17, -5, 2,-16, 2, 8, -2, 8,-15, 4, 5, -1, 7,
+ -6, -2, -6, 2, -3, 0, 0, -9, -1, 7, 2, 3, -3, -3, -1, 5 },
+ { 1, 18, -8, 18,-12,-10, 3, 4,-22,-12, 20, 8, -3, 9, 2, 10,
+ -10, -3, 9, 3, 6, -3, 10, -1, -3, 2, -2, 4, 2, 3, -3,-18 },
+ { 9, 10, -5, 9,-35,-21,-18,-16, -1,-12, -6, -7,-15,-19, 12, 4,
+ 4, 9, -7, 2, 14, 1, 4, 0, -1, 6, -7, 2, 1, 1, -4, 4 },
+ { 31, 8,-17, 35, -8, 1, -5, -6, -7, -6, 10, -2, -3, 6, 9, 3,
+ -6, -2, 3, 3, 5, -3, 0, 6, 0, 1, -5, -3, -2, -4, -1, 0 },
+ { 18, 4, -8, 7, -8,-15, -1,-16, 12, 18, 3, 19, 2, 4, 8, 8,
+ 0, -5, -8,-12, 10, -5, 0, 1, 0, 4, -3, 16, 11, 11, -2, -6 },
+ { 27, 15,-17,-10,-23,-22, -1,-14, -4, -7, 20, -2, -7, 6, 15, -5,
+ 32, 4, 9,-11, -3, -8, 11, -4, -1, -4, -8, -6, -4, -5, -2, -7 },
+ { 22, 4, -7, 2,-15,-11,-17,-10, 2, 0, 15, 11, 7, 12, -8, 6,
+ -10,-18, -6,-12, 7, 3, 22, 3, -7, 14, -5, -2,-13, -7, -1, -7 },
+ { 18, 13, 9, 24, -4,-19, -9,-11, 13, 8, 2, 4, -1, 8, 14, 10,
+ -12, 0, 0, 5, 10, 5, 4, -1, 5, 1, -1, 11, 2, -4, 0, -9 },
+ { 15, 19, -5, 1, -4,-10, -8,-27, 6, 8, 5, 10, 4, 11, 5, -5,
+ -11, 0,-11,-14, -4, -9, -8, -8, 6, -9, 4, -5, -1, 1, 5, -4 },
+ { 18, 1,-13, 14,-14, 9,-15, -7, 12, 1, 13, -4,-20, 12, 10, 12,
+ -12, 7, 1,-13, 10, -6, 5, -3, 4, 8, 10,-13, -3, -6, 9, -3 },
+ { 19,-14, 5, -8, -6, 2, -5, 5, -3, -1,-28, 11, 18, -6, -4, -2,
+ 11, 14,-43,-42, 9, 2, 20,-23, 6, 32, 0, 5, 0, 6, 9, 5 },
+ { 8, 11,-14, -1, 7, 12, -7, 2,-16, 2, 10, -3, -1, -7, -7, -1,
+ 1,-10,-60,-23,-18, 42,-13, 9, 18,-11, 0, 1, 0, 2, -5, 1 },
+ { -5, -1, 2, 0, 3, -3, 3, -2, -6, 0, -3, -3, 7, 2, 0, -2,
+ -2, 3,-34,-15, 37, 47, 10, 20, 9, 1, 3,-21,-25,-33,-14, 8 },
+ { 5, 6, 2, -2, -2, -2, 6, 5, -5, 7, -3, 1, -5,-13, 9, 3,
+ -17,-19, -2,-79,-12, -7, -8, -6, -2, -2, -1, -1, -7,-13, 6, -1 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1,
+ 0, 3, 4,-87, 6,-11, 16, -9, -1, 8, 0, 5, 0, 1, 2, 1 },
+ { -5, 6, 2,-24, 5, -9, -7, 0, 7, 3, -3, 16,-14,-16, 0, 18,
+ 15, -9,-14,-28,-17, 53, 14, -6,-28, -1, -3,-10, -7,-14, 19,-15 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -3, 0,
+ -13, 0,-53, 3,-22, 63, 19, 16, 1,-11, 0, -3, 0, -3, 0, 1 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1,
+ -1, -6,-43,-43, -2, 65,-13, -4, 9, 1, 1, 2, 1, 0, 0, 1 },
+ { 0, 1, 0, 0, -1, 0, 1, 1, 0, 0, 1, 2, -1, -1, -3, -1,
+ -23, 1,-61,-55, 3,-28, -6, -4, -4, 8, 2, 1, 1, -1, 0, 0 },
+ { 0, 1, -1, 1, -1, 0, -1, 0, 1, -1, 0, 1, -1, 0, -9, -4,
+ -48,-19,-52,-46, 11,-12, 5,-14, 0,-10, 0, 0, -1, -2, -1, 0 },
+ { 0, -3, -1, -4, 2, -1, -7, 3, 1, 3, -1, 1, -3, 0, -7, 0,
+ 3, -7,-61,-51, -4,-21,-16,-21,-11, 14, -7, 8, 3, -5, 1, 2 },
+ { 0, 0, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, -1, 9, -3,
+ 56,-11, -6,-67, -1, 13, 0, 7, 1, -9, -1, -1, 0, 0, 1, 0 },
+ { 14, 9, -2, 14,-10,-10, 9, -5, 1, -8,-23, 30, 8, -7, 23, 8,
+ 2, 10, -1,-27,-17, 57, 22, 4, -5, 2,-12, -6, 2, -7, -4, -9 },
+ { 1, 5, 12, -2, -2, -3, 2, -3, 6, 0, 4, -2, -8, -6, 0, 16,
+ -15, 29,-55,-29,-24, 29, 3, 10, 6, 13, 10, -5, 21, 11,-14, 5 },
+ { 4, 2, 26, -6, 10, 11,-23,-10,-27,-20, 3,-24,-11,-10,-13, 25,
+ -10, 5, -9,-36, -7, 43, 3,-13, 6, 13, -2, 0, 1, 3, -3, -4 },
+ { -1, 0, -1, 0, 0, 0, 0, -1, 1, 0, -1, 0, 0, 0, -1, 1,
+ -12, 12,-26,-64,-15, 29, 37, -7, -3,-12, -5, 14, 8, -8,-10, -2 },
+ { 19, -4,-11,-16, 8, 14, 5, 19, 3, 22,-11,-21, -1, -6,-11, 11,
+ 10,-24,-23,-40, -8, 20, 17, 5, 13, -6, 3, 14,-20, -8, 3, 28 },
+ { 2,-12, 10,-14,-18, 26,-22, 4, -2, 5,-21, 8, 3, 1, 19, 0,
+ -12, 24,-14,-40, 15, 29,-15, 6, 15, 1,-19, 2, 4, 7,-12, -3 },
+ { 0, 17, 13, 7, -5,-11, 2,-19, 3, 38,-21, -3, -6, -4, 7, 1,
+ 1, -5,-40,-10, -2, 35, 8, 8,-10, -8, -9, 33, 4, 4, 0, -2 },
+ { -2,-12, 7, 29,-24, 2, 16, -1, -7, 16, 10, -2, -2, -2, 13, -2,
+ -37, 15,-22,-40,-11, 33, 10, -1, 8, 10, 6, 8, 9, 0,-12, 2 },
+ { 15, -8, -9, -2, 7,-17, 7, 19, 14, 4, 12, 27, 11, 10, 4, 11,
+ -15, 14,-13,-48, 5, 18, 0, -9,-36,-11, 2, 4, 5, 5,-15,-12 },
+ {-12, 0, 3, 4, 7, -5, 5,-14,-24,-18, -6,-15, -8,-20, 1, -7,
+ -33,-28,-40,-38,-18,-10, -5, 17,-12, 4, 3, -5, 5,-13, 4, -7 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1,
+ -3, -9,-49,-60, -5, 45, -1, 6, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1,
+ -3, -9,-49,-60, -5, 45, -1, 6, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0,
+ 3, -2, 9,-29,-11, 55, 8, 32,-36,-13, -7, 37, 4, 11, 0, 3 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 4, -1,-39, -4,-30, 63, 28,-17, -6, 10, 7,-14, -9, 11, 9, 7 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1,
+ 13, -2,-50,-32, 22, 51, 4, 7, 6, 11,-20,-13, 9, -5, 21, -4 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1,
+ -3, -9,-49,-60, -5, 45, -1, 6, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1,
+ -3, -9,-49,-60, -5, 45, -1, 6, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0,
+ 3, -2, 9,-29,-11, 55, 8, 32,-36,-13, -7, 37, 4, 11, 0, 3 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 4, -1,-39, -4,-30, 63, 28,-17, -6, 10, 7,-14, -9, 11, 9, 7 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1,
+ 13, -2,-50,-32, 22, 51, 4, 7, 6, 11,-20,-13, 9, -5, 21, -4 },
+ { -8, 2, 1, 22,-31, -6,-25, -3, -3, 1,-15,-11, -2, -3, 4,-13,
+ -9, 15,-18, 37, -7,-37, 12,-13,-11,-25,-10,-11,-22, 7, 16, 7 },
+ { 14, 10, 4,-10, -1, -5, -7, -3, 16, 13, -5,-15, 5, 11, -1, 8,
+ -27, 7,-12, 49, 17,-22, 9, -2, -9, -1, 2,-15, -1, 41,-18,-17 },
+ { -4, -9,-15, -3, 3, 4, 4, 2, 7, -3, -7, -8, -5, 17,-19, -7,
+ 36, -9,-38, 17, 1,-48, 11,-18,-13, -2, -8, 4,-10, -5, 21, 11 },
+ { 15,-13, 4, 2, 1, -5, -2, 1,-10, 7, -1, 3, -6, 0, 11,-11,
+ 8, 20,-17, 51,-17,-41, 2, 15, 4, 8, -2, 16,-32, -1, 17, 6 },
+ { -8, 8,-18, -5, 4, 6, -3, 8, 0, -4, 2, 0, -1, -4, 5, 8,
+ 30, 30, -8, 70, 2, 8, 2, 0, 7, 1, 13, -1, -6, -7,-11, 2 },
+ { -8, -7, 9,-10,-13, 6,-11,-14, 13, 25,-26, 5, 2, -5, -5, 5,
+ -8, 4, 0, 33, 12,-38, -4, 6, 13, 6, 25, 34, -1, 25,-19, -5 },
+ { 18, 3,-17, 4, -8, 7, 20, 1, -1, 5, -5, -2, -8, 8,-35, 15,
+ 24, 43, -5, 51, 5,-12, -3, 1, -2, 3, -3, -3, -9, 8, -9, 2 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
+ 2, 10, 24, 76, -2,-22, 11, -1, 4, 33, 4, 1, -1, 1, 2, 0 },
+ { 0, -1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 2, 0,
+ 24, 13, 32, 70, 26, 5,-21, -9, -6,-15, 2, -2, 2, 4, 1, 1 },
+ { 5, -4,-11, 4, -4, 22, 10, -2, 13,-11, -4,-21,-17, 0, -7, 4,
+ 10,-34, 11, 52, 2,-46, -5, 0, 0, -1, 2, 4, -9, 1, 1, -7 },
+ { 0, 1, 1, 0, -1, 0, 1, 0, 1, 1, 0, 1, 0, 0, -3, 1,
+ -8, 9, -1, 64,-13,-61, -3, 3, -5, 10, 1, 3, -1, -1, -1, -1 },
+ { 0, 1, 0, -1, 0, -1, 0, 0, 1, 0, 0, 0, 1, 1, 2, 1,
+ 10, -2,-31, 79,-10, 27, 0, -1, 3, 8, 1, 1, 0, -1, 0, -1 },
+ { 3, 12, 10, 26,-19, 10, -9, 6, -4,-15, 10, 3,-16, 6, 11,-19,
+ 3, 10, 18, 44, 5,-30, 5, -9, 21, 4, 20, 10, 14,-25, 8,-17 },
+ { 0, 0, 0, 1, -1, 0, -1, 0, 1, 0, 1, 1, 0, 0, -6, -2,
+ 8, -8, 13, 69, 26,-19,-25,-17, 16, 6,-12, 22, 2, -6, 9, 5 },
+ { 0, -1, 0, 1, 0, -1, -1, 0, 0, 1, -2, 1, 0, 0, -4, -1,
+ -34,-15,-33, 56, 9,-42, 9, 10, 6, 9, -8,-11, 0, -6, 15, 5 },
+ { 10, 2,-14, -3,-15,-35, -1, 7,-18, 14, 8, -1,-15,-26, 6,-15,
+ -18, 22, 9, 33, 0,-32, -9, 3,-11, 7, 4, -1, 5, 30, 9, 1 },
+ { 4, 15, 0, 6, -5,-11, 9, 6, 6, 6, 14, 2, -1, 10,-24,-25,
+ -2, -4, -1, 37, 2,-29, 14, -9, 22, 17, -2, 33, 10,-25, 11,-11 },
+ { 0, 5, 2, 18,-12, 21, 22, 33, -7, 21, -9, -7, 7,-15, -7, 16,
+ 7, 0,-14, 44, 10,-25, 5, -4, 15, -8, 10, -4, 5, 9, -1, 16 },
+ { 3, 13, 12, 12, 8, 25,-23, 8,-22, -3,-18, -8, 15, 12, 9, 19,
+ 0, 0, -9, 49,-27,-15, -9,-15, 12, -8,-16, -7, 13, 5, 13, 2 },
+ { 12, -6, 7, -2, 20, -9,-14, 12, 13, -5,-17, 22, -8, -4, 2, 7,
+ -13, -2,-15, 43, -5,-30, 27, 4, 10,-27, 5, 27,-10,-10,-18, 0 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
+ -1, 10,-18, 70, -2,-52, -1, -7, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
+ -1, 10,-18, 70, -2,-52, -1, -7, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 15,-13,-20, 16, 2, 13, 5,-11, -8, -5, -3, 2, 24,-23, 30, -7,
+ 11, 30,-15, 43, 5,-15, 15, -3,-14, 1,-23, 8, 3, 9, 4,-11 },
+ { 0, -1, 0, 1, 0, -1, -1, 0, 0, 1, -2, 1, 0, 0, -4, -1,
+ -34,-15,-33, 56, 9,-42, 9, 10, 6, 9, -8,-11, 0, -6, 15, 5 },
+ { 10, 2,-14, -3,-15,-35, -1, 7,-18, 14, 8, -1,-15,-26, 6,-15,
+ -18, 22, 9, 33, 0,-32, -9, 3,-11, 7, 4, -1, 5, 30, 9, 1 },
+ { 4, 15, 0, 6, -5,-11, 9, 6, 6, 6, 14, 2, -1, 10,-24,-25,
+ -2, -4, -1, 37, 2,-29, 14, -9, 22, 17, -2, 33, 10,-25, 11,-11 },
+ { 0, 5, 2, 18,-12, 21, 22, 33, -7, 21, -9, -7, 7,-15, -7, 16,
+ 7, 0,-14, 44, 10,-25, 5, -4, 15, -8, 10, -4, 5, 9, -1, 16 },
+ { 3, 13, 12, 12, 8, 25,-23, 8,-22, -3,-18, -8, 15, 12, 9, 19,
+ 0, 0, -9, 49,-27,-15, -9,-15, 12, -8,-16, -7, 13, 5, 13, 2 },
+ { 12, -6, 7, -2, 20, -9,-14, 12, 13, -5,-17, 22, -8, -4, 2, 7,
+ -13, -2,-15, 43, -5,-30, 27, 4, 10,-27, 5, 27,-10,-10,-18, 0 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
+ -1, 10,-18, 70, -2,-52, -1, -7, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
+ -1, 10,-18, 70, -2,-52, -1, -7, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 15,-13,-20, 16, 2, 13, 5,-11, -8, -5, -3, 2, 24,-23, 30, -7,
+ 11, 30,-15, 43, 5,-15, 15, -3,-14, 1,-23, 8, 3, 9, 4,-11 },
+ { 16,-18, 7, -4, 31,-15, -9,-13, 20,-12, -6, 0, 12, -6, -2, 4,
+ 3, -3, -1, 0, 1, 3, 3, -2, 1, 6, 4, 0, -3, 2, -5, 1 },
+ { 38, -5,-13, -4, 8,-15, 11, 1, 2, -4, -1, 9, 13, 4,-12, -7,
+ 0, -2, 7, 2, -6, -2, -3, -2, 3, -4, 6, 15, 1, 1,-11, -2 },
+ { 47,-22, 9,-26, 3, -5, 2, -7, 4, -2, 2, -2, 3, 0, 3, -4,
+ 3, -3, 2, -3, 7, -3, -1, 1, 1, -5, 5, 0, 2, -5, -3, -2 },
+ { 14,-16, 2, -6, 7, -2, -7, -4, -4, -7, 14, -3, 7,-19,-14,-17,
+ -29, 6, 26, 16, -5, 13, -4, -1, 21, 14, 1, 3, -6, 0, -7, -1 },
+ { 29,-11, 5, -3, 4, 11, 4,-10, 1,-22, -3,-10, 5, 4, 2, 8,
+ -2, -7,-12,-12, -8, -3,-18, -2, -9, -5, -1, -3, 2,-14,-14, 7 },
+ { 28,-12, 5, 3, 9, -7, 0, -2, 2, 1, 4, 0, -7, -3, -2, 4,
+ 4, 14, 8, -1, -4, 14, -7, 17, -2, -2, -9, 2, 19, -7, 9, -8 },
+ { 31,-18,-22, 8, 15, -5,-10,-15, 1, 10, 6, 7, 6, -8, 2, -1,
+ 12, -3, 3, -1, 1, 5, -6, -4, 0, 1, 7,-10, -2, 4, -3, -4 },
+ { 53,-30, -4, 12, 2, 3, -3, -3, 0, 1, 6, 5, -5, -4, -7, 1,
+ 0, 2, 1, 3, 1, 5, 0, 2, 2, -1, 0, 4, 2, 0, -2, 0 },
+ { 27,-18, -3, -2, 4, -8, 3, -2,-11, 2, 10, -8, -8, -4, 0, -2,
+ 8, 0, 9, 0,-16, 11, 1, -6, 13, -3,-10,-13,-15, 25, 1, 0 },
+ { 35, -5, -1, -8, 23, 11,-14, -3, 2, -2, 8, -6, 17, -2, 7, 0,
+ -2, 10,-17, 13, -2, -2, 11, 11,-14, 2, -2, -3, -8, -1,-12, -5 },
+ { 29, -9, 7, 3, 2,-10, 0, 3, 9, 0, -3, 5, 1,-10, 10, -5,
+ 3, 6,-20, -9, -6, -4, 1, 0, 12, 17, -8, 9, 3, -1, -9, 0 },
+ { 15,-16, 18,-19, 16,-15, 17,-18, 13,-16, 17,-14, 15, -9, 13,-17,
+ 9, -7, 4, -5, 3, -4, -3, 0, -6, 7, -9, 7, -2, 7, -9, 9 },
+ { 21,-10, 7, -2, 12, -7, 13,-17, 11, -2, 20, 3, 5,-11, -6, -6,
+ -15, 0, -9, 5,-11, 7, -1, 7, 8,-10, -9, 3, -5, 9, -8, -2 },
+ { 23,-22, 15, -5, 16, -4, -3,-12, 9, 3, -1, -2, -8, 2, -2,-16,
+ 3, 4, -2, -6, -7, 12, -8, 2,-14, 2, -7, 11, -2, 6, -4, -1 },
+ { 34,-17, -4, 8, 4, -6, 1, 8, 4, 16, 3, 6, 12, -1, -1,-15,
+ 6, 4, -7, -6, 6, 0, 2, 1, -2, 2, 3, 3, -3, -2, 8, -6 },
+ { 18,-18, 2, -2, 10, 1, 18,-23, -3,-10, 0, 4, 20,-19, -3, -4,
+ 2, 8, 6, 1, -3, 1, 1, 3, 5, -1,-11, 3, -7, 5, -1, 1 },
+ { 15,-14, 2, 3, 10, -8, 12,-13, 13,-15, 6, -8, -4,-10, 14, -9,
+ 24, 2, -7,-18, 13,-11, 8, 14, -6, -2, 3, -1, -4, 7, -7, -4 },
+ { 20,-12, 13, 5, -1,-10, 15, -6, 8, -1, -3,-10, 17, 0, -6,-19,
+ 2, -1, 8, -3,-16, 0, -3, 2, -2, 0, 8, -9, 0, 1,-10, -9 },
+ { 32, 0, -9, -5, -1, 5, 13,-11, 8, 3, 11,-11, 0, -8, -2,-14,
+ 7, 10, 6, -5, 1, 10, 2, 12,-10, 4, 4, 6, 4, 0, -7,-10 },
+ { 16,-14, 10, -7, 11,-11, 11,-11, 18,-13, 8,-15, 16,-11, 13, -9,
+ 8, -7, 12,-11, 7, -6, 3, -5, 9, -5, 4, -1, 7, -4, 8, -3 },
+ { 24,-27, -1, 5, 8, -5, 12, 7, 4, -3, 3, -1, -9,-11,-13, -5,
+ 10, 0,-13, 7, 1, -5, 4, -9, 7, -3, 13, 2, -5, -3,-17, -2 },
+ { 23,-19, 15, 1,-10,-18,-12, -6, 8, -3, 12, 0,-12,-10, -4, -4,
+ 8,-10, 4, 2, -2, -8, 13, -3, -2, -6, 2, -3, 5, -2, 2, 11 },
+ { 25,-12, 4, 2, 24, -3, 3, -6, 14, 11, 0,-21, -3, -3, 1, -8,
+ 7, 0, 0, 3, 3, -6, -7, 6, 2, 1, -4, 5, -1, 10, -2, 9 },
+ { 24, -8, -6, 7, 16,-12, 13, -1, 11,-21, 2, -6, 3,-12, 0, 9,
+ 4, 11, -7, 1, 4, 1, -8, 3, 3, -6, 3, 3, 0, -8, 8, 4 },
+ { 25,-21, 13, 14, 13,-18, 4, -3, 0, -5, -4, 5, -3, 0, 4, 12,
+ 7, 3, 5, -5, 2, -2, 3,-10, 2, -9,-15, 6, 1, 7, -5, 1 },
+ { 23,-16, -2, 10, 4, -1, 3, 1, 32, 3, -5, -2, 9, 10, -1, -4,
+ -6, 2, 9, -1, 14, 12, -6, -1,-17, -2, -4, -9, -7, -6, -8, 3 },
+ { 50, -8, 5, 2,-11, 10, 0, 0, 6, -3, 7, 0, -3, -2, -3, 0,
+ 6, -4, 2, -5, -9, 0, 3, 10, 1, -7, -2, -3, -6, -9, 1, -2 },
+ { 28,-17, 0, -2, 2, -9, 1, 5, -4, -1, 0, 0, 19,-27, 5,-12,
+ 7,-14, -3, -6, 10, -2, -4, -2, 4, -5, -2, -7, 1, 7, -9, 4 },
+ { 22,-19, -6, -6, 3,-22, 3, 5, 20, -8,-14, -5, 1, 1, 20, 2,
+ 16, 6, 3, 14, 4, 3, 5, 1, 5, -7,-10, -6, 3, -6, 1,-14 },
+ { 29,-14, -8, 13, 8,-10, -6, 4, 4, -6, 5, -7, 1, 12, 14, 11,
+ -7, 1, 2, -9,-11, -9, 0, 4, -1, 7, 10, 4, 4, 20, -1,-11 },
+ { 18, -9, 4, 1, 7,-29, 12, 1, -1, -9, -2, -1, -2, 2, 9, -8,
+ -13, 5, 4,-13, -4, 2, -5, -7, -6, 14,-10,-34, -3, 1, -3,-13 },
+ { 38, -9, 24, 8, 11, 4, -6,-11, -2,-12, 1, 1,-11, -8, -5, -2,
+ -15, -8, 8, 0, 1, -7, 5, 4, -1, 8, -2, 11, -3, -1, -5, -5 },
+ {-20, 11, -4, 24,-11, 1, 15, 4, 0,-28,-10, -1, 10, 10, -6, 5,
+ -6, 2, 7, -2, 1, -2, -6, -3, -7, 1, 2, 12, -1, 7, 0, -2 },
+ { -9, 10,-23, 27, -4,-17, 20, -6, 14,-17, 5, -1, 5, -9, -7, 5,
+ -6, 4, -2, 9, 0, 8, 0, 1, -3, -3, -5, -8, 5, -2, -2, 12 },
+ {-10, 19, 4, 9, 1,-16, 17, -2, 9,-29,-16,-11, -4, 7, -5, 4,
+ -1, -3, 3, 2, 3, -4, 5,-12, -2, 6, 5, -4, 4, 1, 4, 10 },
+ {-20, 10,-24, 14, -5, 11, 9, 0, 16,-20, 10, -5, -6, -6, -1, 2,
+ -4, 5,-16, 8, -2, 5, 5,-11, 9,-11, 4,-11, -1, -1, 4, 3 },
+ { -9, 11, 3, 19, 24, 4, 5,-14, 30,-17, -4, -2,-17, 7, 2, 3,
+ 1, 3, -7, -4, 2, -3, 1, 4, -1, -1, 3,-12, -2, 3, -3, 10 },
+ {-19, 18, 11, 19, 19, 19, 10, 4, 13, 6, 5, 4, 8, 3, -2, 12,
+ -6, -2, 7, -6, 15, 12, 16, 16, 18, -3, -4,-20, 0, 10, -9, -3 },
+ {-21, 9, 20, 12, 0, -3, 5, -9, 15,-13, 5, -5, -6, 24, 2, 9,
+ -5, 2, -7, 2, 5, 7, -5, 2, 15, 3, 1, -1, -4, -2, 7, 0 },
+ {-18, 16, 13, 15, 2,-10, 14,-11, 4,-11, 5, 12, 12, 20, 8, 30,
+ 2, 11, -9, 7, 0, -3,-16, -5, -6, 5, -4,-21, 0, 5, 6, 1 },
+ {-26, 8,-13, 9, 6,-10, 2,-11, 7, -4, 6,-19,-11, -6,-12, 16,
+ 0, 5, -7, 8, 5, 6, 17, -9, 10,-10, 5, -3,-11, 2, 4, 10 },
+ {-11, 17, -3, 22, -5, 18, 3, 1, 4, -5, 14,-27, 5, -7, -4, -5,
+ -10, 11, 1, 15, 1, 1, -6, -5, 10,-22, -7, -7,-15, 13, -4, 5 },
+ {-17, 14, -7, 13, 3, 0, 13, -6, 9,-14,-22, -1, 1, 19, 14, -3,
+ 4,-13,-13, 2, -4, 8, -2, -2, 13,-12, 13,-12, -7, -5, -3, 6 },
+ {-17, 17, -1, 33, 6, 3, 9,-16, 3,-14, -8, 6,-17, 8, 3, 13,
+ 8, -6, 3, 1, -2, 0, -2, 8, 4, 9, 13,-10, 4,-17, 0, -6 },
+ {-20, 7, 7, 21, 1, -3, 7, -3, -2,-12, 9, -7, 2, -3, 14, 1,
+ -1, -7, 12,-10, 5,-20, 11, -2, 0,-24,-17, 6, 6, -4, 3, -1 },
+ { -8, 10, 6, 7, -1, -6, 28, -6, 10,-33, 1,-20, 0,-12, 10, 1,
+ -6, 8, -3, -1,-10, 8, 5, 0, 10, -2, 8, 16, -5, -3, -7, 4 },
+ {-17, 13, 3, 15, 1, -5, 27, -5, 6, -6, 12, 2, -4, 8, -1, -3,
+ -2, 12,-15, 3, 4, 1, 2, -9, 0,-16,-21, 2, -4, 16, -7, 4 },
+ {-15, 20, 8, 17, 5,-14, 15,-11, 21,-11, 13,-13, 2,-15,-13, 1,
+ -5, 5, 2, 10, -9, 4, -1, 3, 2, -4, 13, -5, 1, -4, 5, -3 },
+ {-21, 8, 2, 16, -1, 2, 15,-16, 13,-12,-12, -7, -8, 2, -7, 11,
+ -8, 5, 2, -7, 16, -4, 1, -7, 3,-15, 6, -5, -8, 2, -8, 5 },
+ {-15, 17, -6, 3, -3, 3, 9, -7, 14,-23, 11, 1, -1, 4, 7, 6,
+ -1,-14, 7, 6, -8, 5, 1,-15, 10, -9, 2, -3, -1, 4,-10, -4 },
+ {-10, 18, 3, 11, 1, 4, 14,-14, 7, -4, 15,-10, 10,-11, 10, -4,
+ 5,-14, 10, 4, 15,-12, 15,-13, 20,-15, 14,-15, 8,-11, 4, -6 },
+ { -7, 23, 2, 20, 7, 8, 19, -5, 9,-16, -8,-17, -5, 1, 5, -6,
+ -8, 1, -6, -4, 10, 6, 6, 2,-11, -4, 0, 2, 4, 7, 9, -4 },
+ {-15, 20, -5, 22, 11, -8, 9, -5, 10,-13, -8, 8, 2, -2, -3, 7,
+ 6, 10, 1, 2, -5, -9, 1, 10, 16,-22, -7, 0, 7, 7, 6, 1 },
+ {-26, 19, -5, 3, 5, 25, 18, -5, 9,-14, -8, -6, -2, -6, 2, 3,
+ -8, -2, -7, 7, -3, 7, 3, 4, -8, 0, 1, -8, -4, -2, -2, 1 },
+ {-20, 14,-10, 6, -3, 7, 8,-32, -2, -7, -2,-10, 16,-12, -9, 15,
+ -2, -5, -6, 2, -7, 5, 9, 1, 6, -7, -1, 0, -2, -4, -7, 3 },
+ {-14, 16, 4, 11, -8, 1, 23, -4, 17,-13,-10, 1, 12, 9, 12, -4,
+ 7, -1, -1, 5, -8, -6, 3, 3, -6, -3,-18, 0, 18, 20, 4, -2 },
+ {-33, 19,-10, 30, 15, 2, -3, -1, -4,-14, 7, -7, -1, 7, -8, 9,
+ -1, -3, -5, 2, 2, 4, 0, 5, 0, 0, 2, 3, 3, -3, -3, 4 },
+ { -6, 20, 0, 5, 17,-10, 18,-17, 9,-16, 4,-13, -6, 2,-14, 14,
+ -28, 9,-12, 25, -4, 7, 7, -8, 6, -6, -2,-10, 2,-11, -1, 2 },
+ {-12, 14, 12, 52, -3, 5, -5, 4, 8,-13, 2, -5, -4, 2, -2, -1,
+ -2, 3, 3, 5, 2, 3, 0, 1, -5, 2, -4, -3, 1, -5, -2, 0 },
+ {-13, 6, 9, 24, 0, 8, 14,-15, 18, -9,-11, -8, 3, 15, -2, -4,
+ -9, 4, -3, 12, 14,-13, 11, -4, 2, -4, 0, -6, -6, -6,-14, -1 },
+ {-10, 28, 3, 12, 9, 3, 11,-28, 6,-11, -7, 4, 0, 7, 8, -9,
+ 0, -6, 0,-16, 4, 7, 4, 4, 7, 3, 4, -7, 0, -3,-10, 6 },
+ {-11, 14, -2, 19, -1, -1, 7, 9, -2,-27, 10,-14, 15, -4, 12, -4,
+ 2, -2, -6, 12, -6, 0, -5, -4, -5, 1, 3,-11, 5, -9, 3, -8 },
+ {-18, 7, 13, 16, -4, 3, 9,-10, 10,-10, -3,-22, -4,-12, 3,-16,
+ 0, -3,-16, 8,-11, 1, 10, -7, 15, 3, 0, -1,-13, 8, 1, 6 },
+ {-20, 10,-10, 10, 8, -1, 6, 0, 16,-12, 9,-10, -1, -5, -4,-13,
+ 13, 16, -8, 12, -2, 14, 18, 13, 0,-16, 2, -5, -5, -5, -4, 3 },
+ {-14, 5, -7,-17, 5,-13, 23, 20, -4, -1, 1, -6, 13, 5, -1, 4,
+ -14, -2, -7, 8, 3, 2, 2, -7, 2, -1, 4, 7, 3, -9, -1, -5 },
+ {-19, 3,-24,-28, -9, -7, 19, 3, 2, 19, 7, 5,-13, 8,-15,-17,
+ 3,-11, 4, 13, 3, 2, -1, -3, -4, -4, 2, 0, -5, -6, 6, 2 },
+ {-17, 18,-30,-20, -2, -3, 1, 15, -1,-11, 6, -4, 11, 11, -4, -5,
+ -10, 0, 0, 1, 3, -7, 8, 2, 5, 1, 5, -5, 1, 6, 4, 1 },
+ { -6, 1,-30,-25, -1, -8, -2, -9,-17, 16, 3, -1, -2, -9, -6, -7,
+ -3, 12, 6, -4,-10, 0, 10, -8, -6, -5, -3,-11, -4, 0, -1, -3 },
+ { -1, -1,-34,-28, 1,-10, 2, 9, 4, 16, 2, 6, 14, 17, 0, 7,
+ -4, 4, 4, 4, 0, 1, -1, -5, 8, 1, -4, 1, -9, -2, 5, 6 },
+ {-11, 14, 1,-31, -7,-24, 9, 7, 6, 5,-13, 1, -1, 3, 4, -1,
+ -2, -8, -6, 3, 5, -4, -6, 7, -2, 5, 3, 3, 0, 0, -5, 2 },
+ {-25, 8,-11,-18, 1, -4, 8, -3, -4, 15, 6, -5, 8, 2, 3, 4,
+ -4, 5, 6, 8, -7, 6, 1,-11,-15,-13, 9, -4,-14, 10, 12, 7 },
+ {-20, 11,-15,-25, 3, 4, 18, 13, -4, -5, -9, -1, -5, -2, -2, -7,
+ 16, 5, -4, -5, -7, -2, -3, -9, 11, -2, 0, -7,-17, -6,-11, 6 },
+ {-11, 18, -5,-20,-15, -3, 9, 11,-20, 12, 5, 5, 11, -3, 7, 1,
+ 10, -6, -3, -3, 3, 3, 14, -7, 10,-17, 9,-11, -2, -6, 7,-12 },
+ {-20, 8,-14,-17, -9,-13, -3, 0,-27,-14, -3,-14, 4, 3, 6, -6,
+ 7, 4, 23, 9, 11, 9, 3, -4, 9, 2, 4, -1, -6, 1, -8,-11 },
+ { -9, 14, 2,-37, -7, 13, 6,-11, -6, 9, 18,-11, -6, 2, 12, 4,
+ -1, 3, 1, -2, -2, 1, -9, -4, -2, -3, 3, 5, -6, 0, -2, -8 },
+ {-29, 8, -1,-13, -2, 8, 23, 2,-10, 7, 13, -6, -5, 11, 13, 0,
+ -10,-13, 11,-12,-10, 6, 4, 6, 4, 3, 6, -5, -9, -2, -1, 3 },
+ {-18, 6,-10,-55, -4,-11, -2, 0, 1, -3, -9, -6, 3, -2, -1, 6,
+ 3, -1, 3, 1, -4, -7, -2, 6, 3, -2, -1, -3, -2, 0, 4, 1 },
+ {-14, 5, 3,-21, -8,-16, -4, -2,-11, 27, 15,-20, 3, 0, 1, 1,
+ 2, -5, -5, 4, 1, -9, 5, -3, 3, 0, -4, -2,-11, -4, -3, 7 },
+ {-17, -1, -9,-17, -8,-18, 12,-13, -9, 13, -3, 3, 3, -3, 1, -2,
+ 0, 16, -9, 6, 12, 9, 5, 11, 2,-15, 1, -4,-16, 7, -4,-12 },
+ {-18, 8, -6,-11, -8, -7, 13, 7, 1, 6, 8, -1, 21, -4, 14, 15,
+ 18, -4, -3, 15, 0, 9, 4, 7, 3, -1, 9, -2, 0, 7, -8, 2 },
+ {-10, 7,-18,-29, 3, 12, 12, 9, 11, 4, -1,-15, 1, -1, 8, -2,
+ -2, 10,-15, -1, 0, 6, 12, -6, -1, 10, -6, -3,-11, -4, 9, -6 },
+ {-14, 14, -9,-21,-12, -2, -1, -7, -5,-10, 5, -8, 0, 6, 9,-11,
+ 11, -3, -5, 3, 8, 15, -2, -4,-22, 4, -6, 12, 2, 13, 6, -7 },
+ {-12, 11, -5,-29,-25, 4, 12,-13,-11, -7, 4, 2, 2, -5, 5, 8,
+ 7, -5, -5, 6, 3,-10, 1, -6, 6, -6, -5, -1, -2, -4, 7, 6 },
+ {-15, 11, -5,-16, 0,-13, 26,-23, -6, -3, 5, -2, -2, 21, -6, -3,
+ -5, -1, 6, -1, 0,-13, 2, -3, -9, -1, -4, -3, 5, -4, 12,-16 },
+ { -9, 9, -1,-17, -3, -6, 12, 6,-18, -2, 11,-14, -6, 3, 14,-12,
+ -11, -5, 14, 2, 5, -8, -4,-11, 2, -5, 16, 6, -7, -4, 8, 13 },
+ {-13, 5, 3,-28,-14, 0, 6, 23, 5, 4, -1,-17, 1, -3, 0, 0,
+ 5, 4, 0,-18, 14, 10, 4, 2, 5, -2, 4, -3, 2, 0, 2, 0 },
+ {-15, 4,-13,-16, -3,-12, -2, 2, 7, 10, 9, 3, 11, 4, 23, 14,
+ 9, 16, 4, 1,-12, -3, 4, -7,-15, -7,-10,-14, -6, -8, -1, -6 },
+ { -7, 10, -5,-10, -3,-13, 16, -1,-12, 7, -3,-12, 2, 13, 13, 2,
+ 17, 15,-13, 1, -5, -2, 3, -1, 1, -3, 6, -3,-12,-16, 7, -7 },
+ {-11, -5,-12,-30, -6,-22, 1, 4, -6, -3, 12, 6, 7, 0, 16, 6,
+ -2, 0,-22, -2, -9, 2,-13, 8, 6, -8, 4, -7, -1, -6, 4, 6 },
+ {-14, 5, 1,-27, -4, 2, 1, 14,-11, -7, -8, -4, 1, 8, 0, -6,
+ -13, 11,-12, -7, -5, 1, 10, 7, 3, -2, 0, 6, -8, 2, 10, -1 },
+ {-10, 10,-25,-13,-20, -4, 19, 3, 13, 5, 5, 7, -8, 2, 4, 2,
+ 3, -1, -1, -9, 14, 10, 9, 14, 3, 3, -6, 0, -5, 4, 1, -1 },
+ { -9, 15,-18,-17, 4,-11, 6, 7,-12, 8, -1,-11, 2, 3, 7, 16,
+ -3, -9, 7,-12, 23, 0, 6, 7,-14, -9, 8, 1, -2, 6, -2, -1 },
+ { -6, 9,-16,-26,-14,-11, 9, -6, 5, -2, 13, 17, 21, 7, 18,-19,
+ 6,-23, -2,-15, -2, 2,-10, -8, 2, 1, -2, 4, -3, -4, -5, -4 },
+ { 0, 6, -5,-28,-17,-32, 2,-10, 11, 3, -5, 9, 10, 3, 11, 11,
+ -3, 12, -2, 2, 4, -6, 9, -4, -4, -4, -4, -9, 2, 0, 2, 4 },
+ { 0, -8,-18,-34, -9, -7, -4,-11, 10, 15, 11, -1, -8, 15, 6,-13,
+ 9, 2, -4,-12, 0, -1, 19, 12, 6, 5, 0, -3,-10,-12, 3, -5 },
+ {-10, 6, -9,-17,-12,-11, 9, -6, 11, 11, 18, -7, 0, 16, 4, 2,
+ -6, 3,-12, -1, 0, 1, -5,-22, -2,-12, 0, 6, 17, 5, 5, 6 },
+ { 12, -5, 7, 1, -5, -2, -1, 2, 2, -4, -3, -3, -3, -2,-29, 11,
+ 5,-13,-73, 24, 12, 4,-14,-10, 5, 1, 0,-11, -7, -7, 7, 3 },
+ { 10, -3, -1, -3, 4,-11, -5, -2, -8, 7, 9, 2, -8, -6, 6, 7,
+ 21, 17,-54, 47,-14,-10, 14, 19, 13, 21, -4, 3, 1, 2, -4, 2 },
+ {-12, 4,-16,-12, 5, -9, -4, 19, -7,-22,-22,-17, 3, 0, -6, 8,
+ 23, -4,-55,-28, 2,-26, 2, 1, 4, 0,-13, 6, 0, 10, -7,-11 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, -1,
+ 35, -1,-67,-35,-24,-24, -6, 2, 2, -2, 1, 3, 2, 0, -1, 1 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 5, 0,
+ 41, -4,-73,-15, 18, 4, 17, 8, -1,-16, -1, -2, 1, 0, 0, 0 },
+ { -4, -4, 4, 6, -1, 2,-16,-10,-15,-10, 21, -2, -6, -2, 14, -7,
+ 10, -5,-55, 34,-12, 11,-13, -2, 2, 28,-26, 0, 7, 4, 21, -7 },
+ { 2, 1, 15,-22, 10, -3, 14, -6, -2, 15, -2, -7, 20, 6,-15, -7,
+ 23, 10,-60, 8, -4, 29,-22, 2,-13, 9,-10, 12, -1, -3, 4, 7 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, -1, -2, 11, -5,
+ -21,-11,-60,-27,-17,-39, 6, 36, 0, -8, 2, 2, 0, 0, -2, 3 },
+ { 2, -5, 9,-17, -1, 2, -3, -6, 8, 12, 7, -6,-33,-11,-14,-40,
+ 10, 36,-46, 0,-19, 5, 0,-10, 3, 12, -6, -8, 6,-12, -7, 1 },
+ { 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, -1, 0, 1, 0, -2, 0,
+ 4, -2,-87, -3, -2, 2, -2, 20, 2, 6, -1, 6, 0, 0, 2, -1 },
+ { 1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, -1, 0, 0, 1,
+ 1, 7,-76, 41, -7,-24, 0, -6, 3, 6, 0, -2, -1, 1, 0, 0 },
+ { 0, -3, 4, 2, 3, 2, 2, 0, 3, -1, 4, 0, -1, 4, -2, -4,
+ -32,-11,-64,-29, -9,-43, 2,-11, -1, -7, 0, -4, -2, -2, -2, 2 },
+ { 10,-20, 3, -3, 13, 13, 0, -4, 2, 7, -8, 7, -2, 2,-20,-20,
+ -19, 3,-47,-18,-16, -6,-15,-42,-17, 14, -6, 8, 12,-10, 11,-12 },
+ { -3, -2, -2, -1, -1, 4, -3, -1, -6, -2, 3, 2, -3, 6, -1, -9,
+ 10, 13,-68, -9, 26, 3, 5, 3,-21, 10,-15, 21,-22, 19, 11,-14 },
+ { 1, 5, 18,-19,-29,-13, -2, 18,-10, 20, 2, 10,-10, 11, 1, 8,
+ -16,-17,-41, 10,-14,-25, 0,-14,-19, 17, 7,-12, 14,-11, 14, 5 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, -1,-43, 5,
+ 6,-12,-48, 19, 8,-38, -8, -3, 22,-21,-10, 15, 20, -9, -5, 8 },
+ { 0, 0, 0, 0, -1, 1, -1, 0, 0, 0, 0, 0, 0, 0, 6, -3,
+ 22,-14,-71,-24, -2,-33, 23, 7, -8, 7, -3, 2, -4, 1, -8, -2 },
+ { 1, 0, -1, 2, 0, -2, 0, 0, -1, 0, 4, 0, 26, -1, 10,-11,
+ -17,-32,-58, 14,-14,-11, -2, 15, 2, -8, 12, 10, -9, 13,-33,-14 },
+ { 15,-17,-19, 7, -8,-15,-32,-22, 7, 12, 18, 0, 0,-15, -4, 16,
+ 37, -2,-46, 11, 2, -8,-10, -8, 14, 9, -4, 5, 7,-17, 4, 3 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2, 0,
+ -5, 3,-85, 23, -9,-17, -2, -2, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2, 0,
+ -5, 3,-85, 23, -9,-17, -2, -2, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, -1, 0, 0, 1,
+ 1, 7,-76, 41, -7,-24, 0, -6, 3, 6, 0, -2, -1, 1, 0, 0 },
+ { 0, -3, 4, 2, 3, 2, 2, 0, 3, -1, 4, 0, -1, 4, -2, -4,
+ -32,-11,-64,-29, -9,-43, 2,-11, -1, -7, 0, -4, -2, -2, -2, 2 },
+ { 10,-20, 3, -3, 13, 13, 0, -4, 2, 7, -8, 7, -2, 2,-20,-20,
+ -19, 3,-47,-18,-16, -6,-15,-42,-17, 14, -6, 8, 12,-10, 11,-12 },
+ { -3, -2, -2, -1, -1, 4, -3, -1, -6, -2, 3, 2, -3, 6, -1, -9,
+ 10, 13,-68, -9, 26, 3, 5, 3,-21, 10,-15, 21,-22, 19, 11,-14 },
+ { 1, 5, 18,-19,-29,-13, -2, 18,-10, 20, 2, 10,-10, 11, 1, 8,
+ -16,-17,-41, 10,-14,-25, 0,-14,-19, 17, 7,-12, 14,-11, 14, 5 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, -1,-43, 5,
+ 6,-12,-48, 19, 8,-38, -8, -3, 22,-21,-10, 15, 20, -9, -5, 8 },
+ { 0, 0, 0, 0, -1, 1, -1, 0, 0, 0, 0, 0, 0, 0, 6, -3,
+ 22,-14,-71,-24, -2,-33, 23, 7, -8, 7, -3, 2, -4, 1, -8, -2 },
+ { 1, 0, -1, 2, 0, -2, 0, 0, -1, 0, 4, 0, 26, -1, 10,-11,
+ -17,-32,-58, 14,-14,-11, -2, 15, 2, -8, 12, 10, -9, 13,-33,-14 },
+ { 15,-17,-19, 7, -8,-15,-32,-22, 7, 12, 18, 0, 0,-15, -4, 16,
+ 37, -2,-46, 11, 2, -8,-10, -8, 14, 9, -4, 5, 7,-17, 4, 3 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2, 0,
+ -5, 3,-85, 23, -9,-17, -2, -2, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2, 0,
+ -5, 3,-85, 23, -9,-17, -2, -2, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 16, 65, -2, -2, 4, 3, 0, -7, 3, 1, 3, 1, 0, 5, 1, -5,
+ 0, 2, -1, 3, 0, 0, -1, -2, 6, 0, -2, 0, 0, -1, 1, 1 },
+ { 5, 37, -4, 8, -4, -1, 9, 17, 6, -7, 5, -1, 11, 6, -4, 7,
+ -2, 4, 1, -3, 11, 3, 3, -9, 6, 0, -2, -4, -5, 4,-12,-11 },
+ { 15, 24,-14, 2, 6, 17, 26, 5, 8, 11, -9, -7, -6, -8, 3, -5,
+ 9, 10, -3, 10, 0, 1, 4, -9, 4, 9, 3, 0, 4, 0, -5, 3 },
+ { 9, 36, -9, -8, 7, 7, 4, 3, -1,-16, -2, 7, -5, -6, 6, 12,
+ -11,-12, 9, -1, -3, -9, 12, 6, -6, 2, 2, 5, 0, 5, 6, -6 },
+ { 25, 39, -5, 24, 3, 10, 3, -6, 13, -8, 3, -7, 2,-10, -5, 2,
+ -2, 3, 5, -2, 1, 5, -2, 3, -4, 1, -5, -4, 0, 1, -2, 0 },
+ { 16, 27, -1, 0,-14, 6, 4, -5, 7, -2, -6, 0, -3, -5, 2, -1,
+ -1,-19, 5, -8, 0, 11, 12, 5, 0, 3, 10, 6,-14, 14,-13,-15 },
+ { 12, 23,-14, 2, 1, 4, -3, 16, 7, -8, 2, -8, 8, 6, -8, -7,
+ -3, 0, 2, 8,-13, 7, 13, -6, -4, 6,-13,-16, 14, 11, -7, 5 },
+ { 16, 28, -7, -1, 6, -3, 9, 0, -7, 3, 0, 3,-12, 20, 8, 9,
+ 8, 23, 8,-13, -2, 4, 9, 3, -5, 13, 5, -2, 12, 14, 5, -1 },
+ { 19, 37, 19, 5, 7, 5, 10, 5, 19, 10, 14, 0, 2, 5, 1, -4,
+ -4, 2, 2, -5, -2, -1, 2, -6, -4, -4, -5, -3, 2, -2, -2, -2 },
+ { 24, 21, 1,-11,-10, 17,-14, 14, 6, -1, -6, -1, 0,-13, -1,-12,
+ -2, -5, 6, -4,-12, 14, 5, -2, -8, -8, 15, -7,-30,-12, 4, 0 },
+ { 11, 26, -3, 3, 5, -1, -2, 3, -2, 10, 15, -4, 10,-28, 10,-17,
+ -8, 1, 2, -7, -1, -6,-15, -1, 4, 5, -7, 9, 0, -5, -4, 4 },
+ { 18, 32, 1, 2, -7, 4, 15, 2, -9, -2, 12,-11, 7, 11, 13, 2,
+ 0, 5, 9,-10, 16, 3, -3, 5, -9,-23, 2, -2, -1, 5, 2, 11 },
+ { 35, 24,-20, 2, 4, -1, 5, 14,-10, -9, 8, -7, 0, 5, -7, -7,
+ 11, 1, 5, 3, 2, 0, -2, 3, 0, 1, 4, 0, -2, -8, 0, -4 },
+ { 9, 35, -1, 2, -1,-19, -3, 12, -1, 8, 8,-13, -1, -2, 2, 5,
+ -8, -1, 13, -2, 11, 1, 0,-10, 0, -3, -7, 2, 1,-12, 3, 12 },
+ { 20, 27,-12,-12, 7, 4, -1,-13, -1, -9, 2, 13,-11, 5, 7, -9,
+ 9, 1, 1, 8, -9, 0, -6, 7, 4, 2, -2, 7, 3, -2, 1, -9 },
+ { 8, 37,-20, -5, 0,-21, 10, -8, 3, 19, -9, 7, -3, -8, 10, -2,
+ 0, 5, 6, -4, -2, -1, 0, -7, 6, 1, 0, 4, -5, 6, -8, 2 },
+ { 8, 27, 1, -3, -5, 1, 6, 0, 15, 2, 17, -1, 3,-17, 10, 5,
+ 5, -6, -6, 6,-10, 18, -5, 0, 0, 13, 7, 10, -5, -6, -2, -4 },
+ { 14, 29,-20, -4, -3, 1, -5, -1, 2, 12,-10, -3, 4,-18, 4, 14,
+ -4, -1, -9, 15, -2, 2, -5, -3, 2, 9, -2,-14, -3, 4, -4, -7 },
+ { 23, 23,-23,-11, 27, 4, 4, -1, 7, 0, -5, 9, 2,-11, 3, 7,
+ -2, -5, 2, -7, -7, 13, -3, -6, 2, 3, 3, -4, -1, -8, 5, -2 },
+ { 16, 26, -6, 8, -9, -1, -2, -1, -8, 4, -2, 0,-12, 9, -1, 0,
+ -17, -9, 30, -5,-15,-16,-13, 0, 10,-11, -7, -3, -1, 0,-11, -2 },
+ { 12, 32, -4, -5, 10, 19,-10, 4,-12, 5, -6, 9,-12, -6, -6, -8,
+ 4, 1, 3, 0, 8, 0, -3, -4, -7, -4, 10, 8, 6, 5, -1, 4 },
+ { 46, 42, -3,-14, -2, -6, 6, -2, -5, -1, -3, -3, 1, -1, 3, 1,
+ 1, 4, -1, 2, 3, 1, -2, 6, 0, -1, -2, 4, -2, -1, 2, 2 },
+ { 9, 33,-13, 4,-11, 3, -8, 22, 12, -2, 4, 0,-16, 5, 4, -1,
+ 7, -6, -9, 1, 7, 5, 0, -5, 5, -1, 10, 3, -2, -1, 3, -2 },
+ { 9, 30, 6, -3, 6, 1, -7, 5, 11, 14, 7, 1, 0, 2, 2, -1,
+ 8, 7, -6,-13,-10, -2, 1, -6, 10, 7, 6, 5, -2, -5, -1,-16 },
+ { 9, 28,-11,-10, 9,-10, 15, 8, 4, 9, -4, -7, 0, -5, 9, 8,
+ -7, 2,-15,-23, 4, -4, 4, 16, -8, -3, 0, -8, 14, 5, -3, 15 },
+ { 17, 26, -5, -5, -1, -8, 20, 18, -7, -2, 4, -7, -8, -5, -4, 16,
+ 0, 0, -7, -2,-13, -5, -2, 3, 12, 1, 3, -5, 2, 2, 0, -1 },
+ { 11, 37, 7,-23, 6, -1, 15, 13, 4, -9, 7, 5, 3, -3, -5, -8,
+ -2, 3, -5, -1, -8, 7, 2, 13, 1, 3, 0, -3, -1, 2, 0, -2 },
+ { 21, 33, 7, 20, 21,-10, 6, -5, -5, -6, -9, 2, 10, 0, 8, -4,
+ 10, 2, -2, -2, 0,-10, -6, -2, 0, -5, 3,-11, 3, -9, -3, 1 },
+ { 6, 30,-15, -8, 16, 1, 4, 6, 4, 5, 8, -3, 8, -9, -1, -6,
+ 8, 2, -2, 4, -2, 5, 11,-21, 3,-10, 16,-11, 24, 10, 14, -6 },
+ { 15, 36, -3, -9,-20, 12, 0, -7,-18, -4, -8, -9, 9, -7, -3, -1,
+ 2, 7, -5, -8, 6, 2, 2, -1, 7, 1, 1, -3, 3, -4, -8, 1 },
+ { 16, 34, 21, 3, -9, 10, 7, 9, -7, 1, -4, -9, -4, -5, -5, 3,
+ 3,-19, 1, 5, 4, -2, -6, -5,-10,-11, -8, -2, 2, -5, -8, -7 },
+ { 28, 29, -3, 18, -2, 0, -6, 12, -2, 10,-11, -4,-13,-12, -6, -4,
+ 0, 4, -1, -8, 6, 4, 12, 11, 10, 10, -3, -6, 1, 2, 1, 7 },
+ { 3, 8, 22, -8, 3, 36, -8, -1, 9, 6,-13,-14, 8, -1, 1, 2,
+ -2, -8, 0, 3, 1, 2, -1, 5, -1, -8, 0, -2, 2, 2, -1, 1 },
+ { 0, 6, 0, 0, 4, 13, -7,-16, -6, 15,-14,-21, -9,-10,-10, -6,
+ -21, 5, 4, 2, 12, 4, 12, 11, -4, -6, -6,-10, -7,-18, 1, 4 },
+ { -1, 3, 10, 1, -1, 15, 4, -7,-16, 3, 0,-22, 10, 2, -3, -2,
+ 13, 5, -8, 16, -5, 4, 0,-11,-10,-22, 0, -4,-17, 5, 2, 1 },
+ { 12, 8, -4, -9, 14, 40,-21, 0, 1,-15,-10,-12, 12, 6,-10, 2,
+ 8, 6,-12,-10,-11, 1, 0,-11, 2, 1, 13, 0, 6, 3, 8, 4 },
+ {-10, 3, 5, -4, -3, 3, 0, -9, 2, 8,-22,-23, 17, 8,-17, -3,
+ 14, -8, -4, 1, -8, 3, 0, 5, -1, -3, -2, -4, 1,-10, 0, -2 },
+ { 0, -1, 5, -7, 4, 12, -2, 0, -7, 2,-16,-15, 12, 21, -7, -4,
+ 7, -7,-11,-15, -7, -9, -5, -8, 0, -6, 8, -3, -8, 22, -7, -9 },
+ { 7, 19, 4, -9, 24, 22, 2, -6, 8, 13,-14,-20, -4, 11, 8, -4,
+ -1, 2, 0, -7, 5,-17, -3, 3, -6, 5, 3, 4, -5, -7, -3, 14 },
+ { -2, 6, 2, 8, -2, 5, -4, -2,-10, 3,-45,-30, -3, -3,-12, -4,
+ -3, -3, -1, 9, -6, -6, 5, -4, 0, 5, -1, -2, -1, 0, -6, -1 },
+ { -3, 14,-16,-10, 10, 0, -2,-40, -9, 12, 2,-19, 15, -4, 4, 3,
+ 3, -4, 7, 1, -4, -5, 0, 4, -1, 0, -9, -2, -4, -1, -2, 0 },
+ { 7, 16, 2, -7, 8, 2, 0, 1, 5, 21,-10,-26, 7, 2, -9, -7,
+ -3,-16, 8, 5, 5, -6, 10, 4,-14, -6, 5, 3, -2, -2, -4, 1 },
+ { -9, 14, -1, 3, 3, 11, 1, -5, -3, 13,-16,-18, 20, 6, -5, 0,
+ -3, 2, 8, 4,-19, -9, 12, 0, -8, 2, 2, 1, 6, 13, -7,-11 },
+ { 2, 5, 16, -4, 19, 15, 4, 0,-11, 7,-10,-10,-16, 18,-11,-12,
+ -9, -4, 7, -4, -4,-17, 1, 1, -8, -3, -3, 5, -2, -6,-11, -5 },
+ { 2, 12, 0, -9,-10, 14, 6, 2, -3, 2,-12,-28, 12, 1, -1, 2,
+ 0, -3, -4, 7, 16, 5, -7, 8, -4, -3, -1, 3,-12, 4,-17, -5 },
+ { -4, 7, 11, 6, 1, 14, -4, -6, 5, 5, -6,-24, 23, -9,-15, 13,
+ -7, -9,-15, 10, -1, 8, -5, 1, 12, 6, 2, 0, 4, -2, 9,-10 },
+ { 1, 5, 11, 3, 6, 12, -3, 8,-21, 5, -7,-20, 12, -2, -9, -3,
+ 17, -7, -8, -9,-14, 3,-13, 18, -8, 9, 2, -8, 4, -8, -5, -2 },
+ { -3, -3, -1, 5, -2, 15, 3, 2, 1, -8, 1,-39, -6, 13,-13, 0,
+ -2, -5, -6, -3, 0, -5, -2, 15, -9, 5, -3, -6, -2, 7, 0,-13 },
+ { 2, 8, 5,-12,-13, 22, 8,-16, 11, 5, -2,-32, -2, -4, 11, 5,
+ 5, -6, 1, 3, 1, 5, 3, 6, -5, 4, 4, -8, 8, 4, 1, 3 },
+ { 13, 9, 5, -4, 9, 18,-11, 2, -1, 15,-10,-19, -2, 14, 0,-10,
+ 1, 1,-18, 3, 2, -6, -8, 20, 7, -8, 16, 9, 9,-13, -3, -2 },
+ {-13, 11, 11, -9,-10, 13, -3,-18, 2, 10, 5,-21, 6, 15,-11,-21,
+ 3, 14, 0,-12, 9, -1, -2, -4, 3, -3, -9, -8, -5, -2, -8, 2 },
+ { 3, 3, 11, 4, 0, 13, 1, -8, 10, 13, -6,-26, 2, 12, -3, -5,
+ 12, -2, 1, 8, -7,-17,-19, 5, 10, 7, -3, 2, -3, 0, 5, 0 },
+ { 5, 0, 3, -3, -9, 5,-15, -5, -5, 17, -5,-31, 0, 13, 13, 5,
+ -1, -6,-14, 7, -8, 9,-14, -2,-16, -4, -4, -6, 6, -6,-10, 6 },
+ { 13, 3, 1, 7, -3, 4, -1, -2, -1, 4, -8,-32, -1, -4, 0, 3,
+ -10, 7, 10,-10, 4, -1, 6, 2,-16, -9, 4, 3, 13,-23, -3, -4 },
+ { 4, 11, -4, -9, 4, 11,-12,-12,-12, 6, 1,-28, -3, 14, 18, -2,
+ -12, 7, 15, -3, -5, -7, -3, 2, -6, 4, 4, -2, -5, -3, 2,-13 },
+ { 8, 7, -7, 0, 13, 7, -8, -7, 8, 36,-10,-22, 3, 23, -3,-10,
+ -3, 11, 1, -7, 3, 3, -1, -7, -4, 2, 3, 2, 5, 3, -4, -1 },
+ { -1, 1, 13, 1, -6, -1, -6, -9,-18, 17, -5,-37, -1, -1, -6, -4,
+ 1, -6,-15, 2, 17, -9, 0, -3, 0, 4, 0, -5, 0, 4, 1, -5 },
+ { 0, 14, 5, 0, -7, 2, -6, 17, -6, -9, 7,-16, -5, 23,-14,-13,
+ 8,-15, 11, 10,-11,-13,-33, -5, -2, 1, 6, 8, 0,-13, -9, 5 },
+ { 11, 7, -2, -8, 9, 11, 25,-14, 7, 3, -1,-33, 14, 8, -6,-19,
+ 3, 3, 2, -1, -3, -1, -2,-10, -3, 1, 2, 1, 4, 2, -3, 4 },
+ { -2, 8, 4, -2, 9, 13, -4, -2,-15, -3, 19,-37, 9, 25, -9, 2,
+ -5, -2, -2, -4, 4, 2, 2, 0, 3, 3, 3, 5, -2, -3, -4, -3 },
+ { 10, 13, -1,-15, 4, 6,-18, -4, 25, 1,-23,-17, 15, 13, -8, -8,
+ 7, 4, -5, 3, 6, 9, -7, 6, 0, -5, 8, 0, -6, -1, -2, -2 },
+ { 1, 3, 9, -5, 27, 15, -9,-31, -1, 23, -2, -9, 1, 8, -1, -7,
+ -2, -8, -4, -4, -2, -1, 3, 5, 0, 0, -1, 1, -7, 7, -3, -3 },
+ { -8, 7, 3, -6, 8, 3,-11, -2, 36, 14, 1,-30, 6, 10,-12, -6,
+ -6, -2, -4, -3, -5, 0, 9, 4, -5, -5, -8, 12, 4, -3, 1, -8 },
+ { -2, 9, 33, 0, 12, -3, -7, -4, -4, -1, 6,-25, 11, -6, -9,-11,
+ -2, -4, -2, 6, -1, -3, -6, 15, -6, 3, 10, -4, 1, 0, 5, 8 },
+ {-22,-21, -9,-19, -5, -7,-12,-15, -8, 9,-19, 14, -7, -4, 5, -8,
+ -2, 7, 1, -3, 4, -4, 6, 11, 2, 6, -3, -5, 2, -2, 0, -3 },
+ {-32,-13, 3,-24, 3, -8, 4, 1,-10, 14,-15, 0, 4, 6, -1, 6,
+ 7, -1, 6, 4, -3,-17, 1, 4, -6, -1, 1, 0, 3, 3, -7, -4 },
+ {-32,-11, 7, -8,-12, 13, -5,-22, -4, 12,-16, 2, 0, 4, 0, 1,
+ 0, 6, -5, -8, 2, 6, 5, 0, -3, -6, 5, 6, 5, 5, 13, -4 },
+ {-44,-33, 6, -4, 2, 0, -9, 10, 3, 4, 7, 0, -1, 7, 5, 1,
+ 1, -3, 1, 6, -1, 0, 2, 3, -4, 0, 0, 1, 0, -1, -2, -1 },
+ {-30,-18,-24, -8, 5, 0, -2, 14, 7, 0, 1, 12, 6, 4, -9, 7,
+ 5, 7,-11, -5, 1, -8, -1, 2, 2, -9, 7, -1, 7, 5, 6, 6 },
+ {-22,-20,-13, -9, 20, -3, 10, -8, 6, -4, 2, -7, 10, 8, 0, -1,
+ 2, -3, 6,-19, 2, 4, 3, 3, -7, 2, -1, -6, 1, 1, 6, -2 },
+ {-27, -8, -1, 3, -1,-11, 24, 4, -1, 1, -8, 8, 5,-11, 15, -3,
+ -15, -1, -1,-13, -1, 1, -5, 5, 2, 3, -9, 0, 4, 3, -7, 6 },
+ {-33,-16, -1, -8, 10,-23, 6, 13, -1, -3, -9, 0, 5, -7, -5,-12,
+ -2, 3, 3, 6, -2, -3, 2, -3, 9, -6, -3, -2, 0, 5, -3, -4 },
+ {-22,-17, 11, -3, 3, 1, -1, -5, 17, 2,-15, -2, 10, -9, 6, 14,
+ -16,-12, 20, -1, -7, 6, -3,-12, 1, 10,-10, -1, 7, -3, -1, 10 },
+ {-28,-13, 1, -3, -1, -1, 0, 3, 3, 5, 1, 10,-10, -3, 7, 2,
+ 4, 19, -1, -1, 10, 5, -8, 1, 11,-15, -4, -3, -5, 4,-13, 3 },
+ {-22,-13, 42,-20, 5,-13, 7,-11, 1, 1, -1, 1, 6, 3, 6,-11,
+ 3, 3, -2, 0, -4, 4, -3, -1, -5, 2, 0, 0, -9, -1, 4, 4 },
+ {-26,-15, -2, -6, -4, -2, 16, 8, 21, 8, 1, -3,-10, 7, -8,-12,
+ -5, 12, -9, 3, -2, -3, 18, 1,-12,-15, -4, 5, -3, 0, 12, 7 },
+ {-26,-16, 5, 6, 14, -3, 15, 6, 1, -7,-13, 16,-15, 5, 11, -2,
+ 9, -7, -4, -2, 0, 0, -2, 7, -8, -6, -5, 2, 7, -3, 2, 12 },
+ {-31,-17, -8,-30, 4, 14, 6, -6, 6,-11, 0, 3, -4, 0, 0, -4,
+ 0, -4, 1, 4, 3, 4, 0, -5, 3, 2, 2, 0, 2, 1, 3, 5 },
+ {-61,-10, 4, 10, 4, 7, 0, -3, 0, 1, 0, -3, 0, 1, 0, -2,
+ -1, 1, 2, -2, 4, -3, 1, 1, -1, 1, -2, -4, -4, 4, 0, 0 },
+ {-28,-13, -8, -4, 3, -3, 2, 1, 11, 14, 3, 9, 1, 13, 3, 5,
+ -3, -2, -2,-12,-14, -9,-11,-15,-12, -5, -4,-12, 3, -3, 0, -5 },
+ {-41, 0, 12,-24, 13, 4, 5, 16, -5, -4, 0, 0, 13, -4, 1, -9,
+ 9, -6, -1, 6, -2, 5, 2, 9, 6, -9, -8, 8, -2, -3, -6, -4 },
+ {-26,-19, -2,-15, 4,-14, 6, 0, 26, 20, 8, 9, 9, 3, -4, -5,
+ -8, 1, 0, -1, 5, 9, 3, 4, 4, 7, 1, 3, -2, -2,-10, 0 },
+ {-29,-18, 9, -4, 1, -5,-14,-12, 5,-10, -5, 4, -5, 0, -1, -1,
+ 4, -5, 7,-16,-11, 2, 7,-15, 2, -4, 6, -4, -6, 7, -3, 7 },
+ {-27,-16, 9,-14, 3, -8, 9, 0, 7, -4, -3, -7, 0,-10, -1, 2,
+ 1, -2, 15,-10, 14, 7, 6, 17, 3, -4, 3,-10, 8, -8, 3, 11 },
+ {-21,-20, -8, -8, 4, 5, -3, -2, 0, -5, 14,-10, 11, -4, 13, 0,
+ 5,-11, 19,-18, 18, 3, -5, -3, -4, -8, 11,-10, 10, 3, 4, -9 },
+ {-35,-15, 13,-12, 4, 0, -2, -4,-12, -3, -8,-24, -7, 1, 7, 8,
+ -3, 0, -2, -1, 3, -2, -2, -6, 8, 1, 0, 1, -6, -1, 2, -6 },
+ {-19,-14, 13,-10, 9, -1, 1, 3,-12, 5,-16, 7, 13, 9, 4, -4,
+ 6, -5, 4, 9, -3, 17, -4, 12,-11, -6, -5, -6, 13, 2, 7, -9 },
+ {-34, -8, -4, 1, 2, -1, 3, 6,-20,-11, 8, -1, 4, 2, -9, 4,
+ -4, -5, 16, 10, -4, 14,-13, 1, -6, 0, 2,-10, 0, -3, -3, 7 },
+ {-36,-10, -8, -3, 2, -2, 14, -4, -1, -7, -4, 10, -1, -3, 15,-11,
+ 0, 2, 3, -1, 4, 0, 8, -1, 0, 18,-11, -5, 15, -5, 13,-12 },
+ {-22,-13, 14,-20, 15, 25, 16, 10, 8, -2,-10, -5, -1, -8, 11, 8,
+ -1, -2, -4, 1, 2, -1, -7, 0, 0, 0, -3, 0, 2, -1, 0, 2 },
+ {-31,-22, 7, 6, -2, 5,-20, 14, -6, 7, 0, 14, 3, -7, 3, -6,
+ -2, 1, -3, -5, 1,-10, 1,-24, 6, -2, 3, -7, 1, -7, 8, 7 },
+ {-25,-20, -3, -9, 10, 6, 12, 7, 5, 4, -3, 6, -1, -5, -6, -8,
+ 3, 5, 6, 5,-10, 10, -4,-15,-15, -2, -9, 2, 18, 1, 8, 12 },
+ {-24,-19, -2, -4, -7, 11, 6, 9, 16, 2, -7, 18, 6, -7, 6, 6,
+ -2, -9, 3, 12, -2, 3, -1, 6, 7, 8, 0, 8,-11, 8, 4, 2 },
+ {-26,-20,-12,-12, -2, -3, 1, -5, -1, -2, 0, 3, 7, 9, -2, 2,
+ 9, 22, 13, 4, -4, -1, -2,-14, 5, 15, -8, -5, -7,-11,-14, -6 },
+ {-21,-18, -1, -4, 0, 3, 7, -2, 10, 8, -8, -1, 15, 1, -9, 3,
+ 1, 3, -5, -2, 2, 4, 0, -1, 10, 2,-19, -8, 8, 30, -7, 8 },
+ {-25, -6, 26, 4, -8, 4, -2, 21, 5, -4,-16, 5, 13, 4,-10, -1,
+ -6, -2, 2,-10,-13, 1, 3, -3, -6, -8, 2, 11, 1, -7, 0, 5 },
+ { 0, -1, -2, 19,-12,-48, -6, 11, 8, -2, -4, -2, -7, 5, -3, 2,
+ -2, -1, -1, -7, 0, -3, -3, -4, -4, 4, 1, 3, -3, -1, -2, -5 },
+ {-11, -8,-28, 18, 16,-24, -8, 19, 4, 8,-12, 9, -4, -2, 4, -7,
+ 6, 2, 3, 3, -4, 0, 1, -6, -4, -2, 2, 6, 0, -3, 1,-16 },
+ { -9, -5,-26, 7, -3,-37,-16, -2, 2, -7, 4,-13, 0, -4, -6, -5,
+ -6, -4, 0, 3, 4, -3, -4, -4, 4, -3, 9, -4, -2, 2, 7, -4 },
+ { 2, 9,-18, 7, 29,-24, -1, 7, 14, 10, 3, -3, -2, -5, 6,-10,
+ -6, -3, -8, 0, 5, 1, 4, 3,-12, 2, 6, 1, 3, 4, 1, -3 },
+ {-20, 2, 8, 20, -9,-24, -4, 18, 3, 11, -1,-11, 6, 9, -1, -3,
+ 1, -1,-15, 3, 15, 9, 3, 2,-13, 2, -8, 8, 1, -1, 1, -8 },
+ {-12, 5,-11, 6, 19,-26,-17, -6, 4, 14, 6, -8, 9, 5, -6, -5,
+ 2, -1, 20, 1,-11,-10,-18, 20, -7, 0, -3, 4, 2, 0, 10, 4 },
+ {-15, 1, -2, 13, -8,-21,-22, 4, 4, 3, 3, -7,-31, 4,-10,-14,
+ 0, 8, 4, 5, 8, 11, 2, -8, 6, 7, 0, -2, 6, 8, 8, 7 },
+ {-13,-10, -9, 12, 19,-16, -3, -2, 9, 2, 11,-29, -1, 9, 4, -3,
+ 1,-10,-10, 16, 1, 7, -7, -6, -4, -1, -5, 3, 6, 0, 3, 1 },
+ {-17, -1, -5, 19, 12, -9,-21, -5, 2, 12, -7, -7, -3, 8, 7, -2,
+ 6, -9, -9, 1, -4, 1, 1, 3,-14, 2, -8, 0, 10, 1,-12, -6 },
+ {-13, -5, 8, 15, 0,-20, -2, 20, 8, -8, 8,-19, 12, 10, 2,-11,
+ 0, 12, 1,-11, 0,-11,-15, 5,-11, 2, 4, -4,-11, 5, -4, -5 },
+ { 3,-11, -7, 8, 0,-17,-26, 15, 19, -7, 10, -9, -5, -5, 14,-25,
+ 0, -8, 2, -9, -3, 9, 1, -6, 4, -4, 3, -9, -1, 6, 2, 2 },
+ {-12, 5, 5, 9, 14,-18,-19, 4, 2, 16, 14,-21,-15, -9, -1, 16,
+ 12,-11,-10, -5, -7, 4, 15, -8, -5, -1, 1, 14, 13, -7, -1, -4 },
+ {-10, -5, -1, 8, 7,-23,-10, 14, 6, 11, 10,-16, -3, 16, 6, 0,
+ 0, 9, 6, -2, -7, 1, 22, 5, 3, -8, 0, 3, -2,-10, 3, 0 },
+ { -2,-14, 2, 16, 15,-17,-17, 6, 19, 4,-10,-15, -1, 15, 11,-14,
+ -8, 5, 8, 8, -2, -8,-11, 10, 10, -8,-14, 2, 13, 4, -2,-12 },
+ {-10, 3, 6, 4, 19,-23,-19, 1, 4, -9,-30, 3, -6, 18, 0, 2,
+ 0,-11, 0, 3, 7, -2, 8, 5, 2, -3, 6, -9, 1, -4, 7, -6 },
+ { 9, 5, -2, 21, 20,-33,-13, 7,-10, 8, 8,-15, -6, -4, 1, 5,
+ 3, 7, -2, -9, -1, 4, -6, 1, 0, 9, -1, -5, 2, 1, -3, 3 },
+ { -9, -3, 3, 15, -3,-30, -7, -7,-25, 6, 2, -6, 1, 19, 1,-12,
+ 1, -8,-13, 9, 13, 1, 8, 2, 5, 15, -2, 3, -9, 0, -4, 4 },
+ { -6,-12,-17, 25, 22,-13,-10, 9, 2, 11, -7,-16, 4, 6, 1, 0,
+ 0, 18, -4, -5, 4, -2, -1, -5, 0, -4, 6, 1, 6, -1, 7, 0 },
+ { -1, 0,-10, 8, 8,-27, 0, -2, 29, 16, -2, -4, 9, -1, 2, 0,
+ 6, 10, 6, 4, 2, -7, 9,-18, 3, 3, 3,-10, 17, 10, 9, -6 },
+ { -3,-12, -6, 11, 20,-32, 5, 21, 3, -4, -9, 2,-10, 1, 7, -4,
+ 5, 0, 0, -1, -8, -9, -7, 4,-10, 5, 0, 2, -5, 4, 9, 1 },
+ { -5, -1, -5, 1, 2,-19,-13, 1, 6, 12, 2,-16,-17, 11, 10, 13,
+ 16,-12,-11, 3, -6, 0, 6, 4, -3, 1, 8, 2, 5,-11, 3,-14 },
+ {-19, 5, 10, 11, 2,-23, -9, 16, -2, 7, 0,-11, -7, 10, 6, -7,
+ 26,-15, -4, 8, 6, -4, 7, -9,-15, 1, 8, -4, 4, 2,-12, 16 },
+ {-11, 1, 11, -4, 1,-31,-13, -1, 8, 5, 4, -2, 0, 13, 7,-17,
+ 7,-10, -6, 1, 4, -1, 2, -9, -4, 9, 3, 3, -4, -5, 3, 4 },
+ { -3, 1, 10, -1, 0,-15,-22, 4, 40,-11, -4, -3,-14, 9, 11, -1,
+ 9, -1, -6, 6, 3, -6, 0, 0,-12, 7, -2, 0, 9, 3, 1, 3 },
+ { -1, -1, -1, 14, 8,-24,-14, -8, 5, 8, 5,-12,-17, 8, 2, 7,
+ 10, -8, 0, 4, -6, -6,-10, 8, 4,-12, 3, -9,-12, 5, 4, -3 },
+ { -5, 1,-11, 8, 9,-24, 0, 2, 2, 14,-12,-13, 1, 6, 7, 0,
+ 7, -6, 9, 26, 11,-14, 8, 10, 1, 9, 0, 11, -2, 6, 2,-10 },
+ {-13, 1, 4, 34, 19,-17,-15, 0, 3, -2, -7, -1, 0, -3, -3, -1,
+ 1, -1,-10, 8, 5, 0, -8, 4,-17, 9, -2, 0, 0, 6, 2, -3 },
+ { -6, -4, 1, 2, 2,-14,-29, 0, 9, 34, -3, -5,-14, 6,-10, -9,
+ -5, -1, 0, 3, 3, 0, 1, -1, -2, -1, -1, -3, -3, -4, 3, -3 },
+ { -4, 6, 3, 14, 14, -8,-29, 31, 11, 14, -4, -5, -6, 10, 6, -9,
+ -1,-11, -7, 1, 7, 4, 1, -6, 4, 0, 10, -7, -5, -1, 2, 4 },
+ { -4, -4, -2, 14, 6,-32, -6,-14, 14, -5,-11, 10,-18, -4, 6, -8,
+ 9, 5, -4, 1, -4, 5, -2, -9, 3, 5, 2,-10, -6,-17, 3, 17 },
+ {-16, 9, 21, 19, 4,-20,-17, 14, 9, 15, -6,-17, -1, 1, 6, -3,
+ 1, 1, 8, -3, -6, 6, 9, 4, 9, -9, -5, 1, -1, 0, -1, 2 },
+ { -7, -5, 3, 19, 1,-20, -9, 14, 21, -7,-18, -9, 26, -7,-17, -7,
+ 12, 6, 0, -9, -6, 14, 9, -9, -8, 4, 15, -7, -9, -1, 9, 1 },
+ {-20, 30, -6, 11, 24, -4, 0, -6, -2, 8, -4, 12, -8,-17, 0, 5,
+ -4, 1, -1, 3, -3, 5, 3, 3, 7, -2, -3, -2, 4, 0, 0, -1 },
+ {-35, 17, 6, 1, -9, -1,-16, 3,-20,-13, 8, 7, -4, -7, -4,-20,
+ 7, 12, -5, 5, -5,-11, 12, -1, 15, -9, -6, 16, -4, -9,-13, 4 },
+ {-21, 36,-19, 9, 0, -7, -8, 9, -4, -3, 3, 0, 7, -8, -2, -2,
+ -11, 13, -1, 5, -3, 7, 2, 3, -1, -2, -5, 1, -1, -2, -5, -3 },
+ {-12, 33, -4, 1,-12, -9, 0,-13, -1, 2, -8, 4,-10, 6,-16, -7,
+ -1, -4,-10, 15, -1, 0, -5, -8, 5, 5, -3, 0, 2, -7, 1, -7 },
+ {-14, 32, 5, -7,-15, 3, -5, 8, 14, 5, 9, 13, 3, 18, -3, 7,
+ 4,-10,-10, 10, -1, 2, 0, -2,-11, 5, -3, -4, 2, 2, 7, 4 },
+ {-14, 34, 1, 20, -1,-12, 0, -3, -7, -4, 7, 18, 9, -3, 14, -7,
+ -9,-20, -7, -4,-13, 12, 1, 12, 5, -6, 2, -4, 0,-15, 1, 3 },
+ {-21, 23, 7, -8, 3,-13, -3, 0, -6, -2, -7, 6,-12, 9, -6, -2,
+ -2, -4, -1, 6, 9, 5, -9, 15, 0, 8, -8, 7, 6,-15, 3, -5 },
+ {-27, 32, -1, -4, -2, 4,-10, 12, -3, 8, 13, 7, 0,-15, 4, -2,
+ 3, 5, 7, -4, 9,-12, -1, -2, -1, -4, 0, -4, 2, -5, 6, -6 },
+ {-17, 29, 15, 0, -1, -4,-10, 13, 12, -1, -8,-10,-10, 4, 7, -2,
+ 6, -5,-13, 19, 6, 1, -7, 2, -9, -2, 12, -4, -8, -3, 2, 4 },
+ {-38, 27, 16,-15, -6, 3, -7, -4, 0, -1, 6, -2, -3, -6, 6, -6,
+ -3, 0, 2, 0, -4, 6, 1, -1, 0, 4, -1, 3, 4, 1, -2, 5 },
+ {-33, 40, -4, 2, 1, 0, 0,-10,-14, 0, -7, 4, -1, 3, -2, 5,
+ 7, 6, -1, 4, 1, 3, 1, -7, 1, -4, 5, 7, 0, 4, 3, -4 },
+ {-20, 25, 12, -4, 16, -4, 2, 2,-14, -2, -3, 29, -1, 1, 3, 1,
+ 9, -5, 2, -8, -3, 1, -7, -2, -7, 1, 0, 4, 16, -2, -1, -1 },
+ {-10, 30, 17, 3, -5, -2, 0, -5,-22, 4, 5, 5, -3,-18, -6, 10,
+ -5, -7, 2, 8, 7, -7,-11, -2, 0, -3, 3, 2, 11, -4, 4, -4 },
+ {-11, 30, 11, 4, -3, -8, 1, -2, 4, 18, 3, 1, -1, 0, -8, -4,
+ -3, 10, 13, 14, 5, -5, 1, 1,-10, 2, 15, 4, 9, -1, -5, -3 },
+ {-17, 32, 18,-18, -3, -5, 6, 10, 1,-15, -5, 9, 8,-12,-10, -6,
+ 11, 9, -5, -8, -7, 10, 5,-10,-14, -4, -3, 1, 9,-11, 2, 1 },
+ {-13, 28,-11, -1, 2,-16, -2, 7,-24, 0, 3, 6, 3, -1, -8, -7,
+ -12, 2, 2,-20, 10, 4, 0,-13, -2, -2, 1, 8,-14, 0, 4, 1 },
+ {-14, 23, 12, 8, 8,-26, 2, -4,-14, 13,-14, 15, 3, -9, -1,-13,
+ -10, -2,-10, 6,-16, 12, 8, 0, 9,-10, -7, -4, -4, 7, -8, 8 },
+ {-20, 45, 10,-14, 4, 16, 8, -9, 1, -8, 10, 5, -7, -2, 2, -5,
+ -1, 0, -5, 4, -6, -2, 4, 1, 3, 4, -4, 2, -2, -2, 5, 1 },
+ {-20, 26, -4, 1, 7, 4, -8, 1, -5,-13, 2, 13, -7, -3, 6, -6,
+ 22, 0, 5, 11, -4,-11, 8, -9, 2, -2, -4, -2, 2,-13, -4, -8 },
+ {-28, 18, 17, 3, -8,-23,-16, -6, 5,-10, 14, 10, 5, -1, -8, 4,
+ -2, 13, -3, -2, 3, 4, 3, -2, -3, -4, 0, 1, 3, 4, 0, 4 },
+ {-12, 32, -6,-16, 18, 12,-16, 0, 7, 13, -4, 5, -8, -1, -3, 4,
+ 6, -2, -1,-13, 4, -1, 3, 12, -3,-10, 1, 6, 8,-11, -2, 4 },
+ {-18, 26, 2, 5, 0, -9,-17, 14, 5, 1, 7, -3, -8, -3, 11, 7,
+ -5,-12, -8, 7, 0, -7, 2,-12, -9, 13,-11, 9, 6,-11, -5, 11 },
+ {-24, 22,-15, -9, 8, 1, -7,-12, -9, 3, 11, 15, 14,-11, 12,-15,
+ -5, 7, -2, 0, -8, 3, 3, -1, 2, 11,-11, 14, -6, 13, 1, -6 },
+ {-20, 28, 18, -4, -6, -5, 12, 14, 2, 10,-13, -6, -8, -6,-13, -1,
+ -26, 22, -3,-14, 6, 0, 10,-15,-13, -9, 6, -7, 1, -5, -4, -1 },
+ {-19, 26, -8, -3,-14, -6, -9, -4, -8, 15, -8, 3,-12, -4, -2, -7,
+ -5, 3, 13, -3, -4,-25, 4, -1, 5,-12, -1,-13, 5, 2, 0, 6 },
+ {-18, 43, 14, -8, 1,-23, -2, -2, 1, 3, -7, 0, 0, 8, -1, -3,
+ -5, 1, 5, 2, 0, -2, -2, -2, 1, -1, -1, -7, 0, 3, -3, 9 },
+ {-11, 30, 10,-14, 3, 1, 10,-11, 1, -7, -4, 14, 2, 1, -9, 1,
+ -11, -2, -7, 5,-11, 1, 3, 14, 1,-16, -8, 3, -5, 7, -4, 4 },
+ {-18, 24, 6, 3, 8, 7,-22, -7, -7, 3, -8, 4, 23, 9, 3, -1,
+ 3, 6, 7, -1, -7, 6, 4, 1, -3, 1, -6, -1, 2, -7, 3, 3 },
+ {-15, 38, -7, -1,-11, 2,-17,-24, 24, 8, 7, -4, -5, 2, 2, -7,
+ 1, 4, 0, -9, 5, 0, -1, 1, -1, -5, -6, 3, 0, 7, 8, -3 },
+ {-14, 22, 1, -5, 9,-12, -9, -5, -6, 5, 7, 8, -1, -4, -9, -3,
+ -33,-16, -9, -1, 12,-11, 17, -7, -3, -1, -7, 3, 2, -3, 16, -4 },
+ {-14, 20, 6, 4,-10, -4, -4, -4, 1, -7, 2, 6, 8,-12, 4, 1,
+ -1, 12, 10, 3,-14,-10, -3, 18, -2, 33, -5,-17, 17, -5, 9, 7 },
+ {-12, 23, 13, 0,-11, -8,-11, 12, -5, -9,-16, 11, 6, 4, 12, -5,
+ 5,-13, 7,-12, -3, 1, 2, 12, 1, -4, -1, 5, 4, 11,-12, -3 },
+ { 15, 2, 14, 7, 1, 2, 1, 12, 10, 23, 4, 6,-20,-10, 4, 26,
+ -6, 13, 4, 3, 2,-11, 5, -7,-10, 4, 9, 1, 10, -4, 11, 4 },
+ { 17, 15, 31, 17, 18, 16, 11, 24, 2, 4, 2, 3, -8, -3, 7, -3,
+ -5, -7, -2, -6, -4, -5, -4, -1, -4, -2, -5, -6, 2, -1, 4, -2 },
+ { 16, 8, 15, 14, 3, 7, 21, 9, 8, 15, 21, 6, 8, 12, 5, -5,
+ 7, -3, 10, 2, -3, 8, 6, 0, 5, 5, 6, -3, 2, 4, 0, -5 },
+ { 5, -4, 6, 12, 6, 13, 24, 17, -5, 17, -1, -6, -7,-10, -8,-18,
+ 3, -2, 2, 7,-15,-11, 12, -3, -2, -2, -4, -7, 2, 0, 5, 5 },
+ { 10, -6, 8, 11, 12, 20, 22,-11, -3, 15, -3, 15, -2, -2, 0, 2,
+ 5, -8, 4, -5, -9, -4, -1, 2, -1, -3, 1, 3, 13, -1, 9, 7 },
+ { -5, 8, 5, 11, 14, -5, 14, -9, 2, 35, 8, 15, 1, -2, 2, -2,
+ 4, -9, -3,-14,-12, -2, -2, -4, -2, -8, -3, 1, -6, 3, 10, 0 },
+ { 16, 0, -6, 15, -3, 4, 4, 3, 3, 20, 5, -4, 10, 9, -9, -3,
+ -10, -2, -7, 11,-11,-10, 17, -1, 3,-15, 2, 9,-15,-10, 16, 10 },
+ { 14, 4, -7, 19, 3, 0, 19, 8, 16, 34, -9, 6,-13, -1, 6, 5,
+ -1, -2, 4, 3, 2, 1, 1, -1, 0, -7, 2, -1, 1, 0, 6, -1 },
+ { 1, 6, 9, 13, 9, 10, 15, 16, 10, 18, 13, 17, 3, -1, -7, 2,
+ -15,-11,-10, -4,-13, -6,-17,-13, -6,-14, 1,-10, 6, 4, -1, -1 },
+ { 13, 1, 7, 10, 14, 13, -7, 5, 5, 28, 14, 14, -2, 2, 3, -3,
+ -13, -4, 10, -9, 19, -4, -3, 4, -5, -5, 0, 5, -5, 0, 3, -4 },
+ { 1, 0, 6, 22, 9, 18, 18, -3, 5, 10, 12, -2, 1, -3, -8,-12,
+ 9,-10, -7, 1, -1, 19, 0, 2, -8,-11,-10, 9, 6, 11, 0, 3 },
+ { 10, 11, 19, 44, 0, 14, 1, -7, 6, 22, 2, -1, 9, 2, 0, -4,
+ 4, 0, -6, -6, 3, 0, 0, -2, 2, -5, 1, -2, 0, 1, 1, 1 },
+ { 5, 7, 0, 32, 30, 26, 5, 4, -7, -3, 15, -6, 3,-10, 7, 6,
+ -8, -7, 2,-13, -5, -1, -3, 7, 3, -2, -8, 0, 6, 4, 5, 0 },
+ { 9, 8, -2, 4, 2, 11, 4, 29, -5, 14, 8, -5,-14, 8, 0, 9,
+ 8,-10, 5,-15, -6, -9, 9, -1, 18,-16, 9,-21, -3,-13, -2, 8 },
+ { 25, 7, -9, 23, 20, 18, 6, 16, -9, 8, 8, -5, 11, 13, -8, 7,
+ 4, 10, -2, -1, -7, -9, -7, -9, -4, 1, 1, -5,-10, 8, 4, -5 },
+ { 9, 2, 16, 14, -5, 14, 1, 0,-21, 17, -1, 9, 12, -3, -3, 4,
+ -4, 14, 10, 3, 0,-10, 7, 4, 4,-11, 2, 4, -1, -3, 9, -1 },
+ { 17, 8, 11, 26, 15, -3, 14, -1, 12, 9, 10, -8, 8,-18,-11, -3,
+ -14, -7, 7, -3, -3, -4, 1, -7, -3, 2, -3, 16, 10, 0, 9, 6 },
+ { 9, 8, 3, 8, 18, 14, 11, 1, 10, 6, 1, -4,-16, -2, 14, -2,
+ 1, 8, 12, 14, 3, -3, 8, 8, 12,-15, 3, -3, 3, -2, 14, 10 },
+ { 22, -3,-11, 13, -7, 11, 4, 11, 3, 14, 0, -6, -2, -9, 4, 2,
+ -2, 0, -5,-27,-10, 3, -1, 5, 8,-24, -3,-11, -3, 2, 11, -1 },
+ { 19, 2, 8, 36, 5, -6, 3, 15, -3, -4, -5, 14,-10, 1,-12,-10,
+ -3, -4, 3, -2, 1, -8, 4, 3, 5, -3, 0, 4, 8, -2, 8, 4 },
+ { 8, 14, 15, 9, -4, 10, 5, 11, 9, 10, 8, 9,-15, 15, 6, -8,
+ -10,-13, 5, -8,-20,-13, -6,-11, -1, -3, -6, -4, -1, 0, 13, 15 },
+ { -2, -1, 9, 12, 2, 2, 13, 3,-23, 33, 15, 2, -4, -1, 3, 8,
+ 8, 6, 6, -7, 8, 6, 9, -1, 3, -8, 0, -4, 1, -8, 11, -1 },
+ { 6, 5, -6, 16, 2, -3, 31, 21, -9, 12, 0, -1, -4, 1,-12, 3,
+ -13,-18, 2,-11, -9, 2, -8, -6, 11, -3, -1, 0, -1, 0, 13, 5 },
+ { 5, -1, 2, 0, 25, 5, 10, 16, -5, 21, 14, 12, 13, 2, -5, 5,
+ 5, -3, -2,-14, 0,-12, 7, 11, -1, -7, 19, -1, -1, -1, 8, -1 },
+ { 10, 7, 3, 11, 0, 8, 22, 3, 3, 19, -4, 12, 15, 9, 5, 15,
+ 2, 1, 2,-10,-10, 0, 2, -1, 0, 1,-12, -1, 21, 16, 9, -7 },
+ { 11, -4, -5, 24, -7, 11, 20, 11,-15, 18, 5,-13,-15, 0, -5, 9,
+ 1, 0, -1, -9, 4, -8, 6, -8, 1, -2, -7, 20, 9, 3, 9, 3 },
+ { 20, 0,-12, -6, 9, 31, 9, 12, 8, 27, 15, 7,-16, 5, -3, -7,
+ -1, -9, -2, -7, -3, 4, -8, -3, 3, -6, -2, -2, -3, -6, -1, 2 },
+ { 6, -6, 48, 8, -3, 19, 12, 11, -7, 2, 3, 0, -1, 1, 8, -4,
+ 4, -6, 0, -4, -4, -3, 3, 6, 3,-13, -8, 5, -3, -7, 8, 5 },
+ { 7, -2, 6, 11, 12, 2, 14, 4, -5, 12, 2, 9, 4, 2, 0, -1,
+ 2, 0,-15, -9,-16, -2, 8,-17, -5,-22,-19, -5, -1,-10, 1, -2 },
+ { 11, -9, 3, 12, 6, 6, 1, 17, -6, 19, 14, 7, -7, -1, -1, -9,
+ 9,-11,-17, 0, -6, 16, 0, 1, 9,-24, 3, 3, -9, -3, 3, -2 },
+ { 9, 0, 1, 8, 1, 7, 2, -5, -3, 8, -1, 7, 2, 6, -3, -6,
+ 5, -2, 6, -2, -4, -3, 0, -3, 13,-50, 1, -2, 2, 4, 4, 3 },
+ { 7, 0, 26, 21, -4, 2, 17, 8, 7, 11, -7, 1, -1,-15, -1,-15,
+ -11, -4,-17, -4, 1, -7, 3, 6, 3, -9, 2, 3, 6, 10, 6, 12 },
+ { 1, -2, 2, -1,-10, -4, 6, -3, -5, -2, -8, 2, 2, 2, 8, 0,
+ 1, 1, 6, 0, 11, 13, 3, 4, 0,-12, 11, -5, 19, 20, 2, 5 },
+ { 5, 3,-13, -2, 1,-12, 11, -7,-12, 7, 10, 0, 7, 0, -2, 4,
+ -6, -9,-11,-12,-23, 12, 10, -3, 0, 6, 19, -1, 24, 18, 9, 12 },
+ { 6, -3, 2, 5, 2, 2, -2, -5, -8,-11, -4, 3, -8, -4, 5, -3,
+ -16, -4, 3,-12, -4, 3, 32, 7, 2, 8, 32,-18, -1, 12, 1, 7 },
+ { 0, -8, -1, 0, -8, 7, -8, -1, -1, 4,-12, -1, 3, 0, 1,-18,
+ 8, 8,-14,-10,-11, 19, 9, 5, -7, 6, 8, -4, 26, 12, -1, 6 },
+ { 3, 5,-14, 7, 14, 8, 20,-13,-16,-10, -2, 17, -7, 4, -8, -9,
+ 14, -5, 3, -4,-12, 7, 14,-10,-19,-20, 35, 8, 13, 14, -2, 9 },
+ { -2, -4, -1, 1, -3, 0, -1, 1, 2, 2, 6, 0, 0, 4, 5, -2,
+ 3, 3, 3, -2, -7, -3, -3, -1, 6, -2, 29, 22, 13, 34, 0, 14 },
+ { -3, -9, 3, 1, 5, -4, 2, 0, 7, -9, 0, 2, -5, -3, 0, 6,
+ -1, -1, -1, 2, 2, 4, 8, 7, 20, -6, 7, 16, 33, 20, 6, -1 },
+ {-11, 1, -3, -3,-11, 3, -9,-25, -1,-16, 4, -8, 15, 1, -2, 7,
+ 8, 23, 2, 18,-13, 16, 3, -7, 6, 3, 16, -8, 12, 16, 3, 4 },
+ { 0, 5, 5, -5, 1, -1, 2, -3, -2, 1,-13, 2, 2, 10, 6, 7,
+ 18, 18, 7, 9, 8, 9, 21, 14, 7, 12, 15, 14, 15, 12, 11, 5 },
+ { 1, -5, 11, -2, 17, 8, 3, 0, -1, 6, 11, -7, 6, 6, 7, 5,
+ -15, 14, 1, 11, 4, 10, 12, 1, 2, 4, 30, 1, 11, 1, 6, 13 },
+ { 2, 4, 3, -7, 5, 8,-11, 7, -5, 9,-10, 6, 8,-10, -3, 10,
+ 1,-29, -4,-26, 5, -8, 13, 4, 3, 6, 35, 1, 3, 6, 3, 0 },
+ { -2, 1, 0, 0, -1, -3, -7, -3, -9, -3, -1, -6, 3, 4, 4, 0,
+ 5, -1, -2, -2, -1, -4,-10, 8, 0, -6, 10, -4, 46, 12, 2, 28 },
+ { 4, -1, 4, 1, 0, 4, -2, -2, -2, -1, 2, -4, 1, 5, 0, -3,
+ 1, 1, -2, 0, 1, -2, -1, -1, 3, -6, 35,-11, 13, 53, -3, -1 },
+ { -5, -2, 0,-13,-16, 5,-12,-11, 1,-30, 3,-18,-24, -8, -5,-19,
+ 1, -3, -8, 7, -7, -8, 15,-19, 4, 10, 30, 24, 6, 1, -9, 10 },
+ { -4, 8, -7, -4, -6, 12, -1, -9, -4, 2, -9, 3, 2, -2, 4, 2,
+ 22, 9, 4, -5, 0, 5, -2, -9, -3, 1, 18,-12, 18, 16, 4, 16 },
+ { -5, -8, -3, -5, -3, 6, -7, -3, -2, -5, -3, 1, 2, 2, 4, -6,
+ 10, 3, 12, -3, 20, 0, 27, -4, 16, 5, 18, -3, 23, 4, 12, 11 },
+ { 0, 1, 0, 1, -2, 1, 2, 1, -1, 0, -2, 2, -2, -4, 1, -2,
+ -2, -1, -5, -2, 0, 0, -2, 2, 9, 7, 63, 5, 12, -1, 1, 0 },
+ { 4, -3, -7, -5,-11, -5,-12,-10,-10,-12,-15,-12,-14,-14, 1, 1,
+ 10,-10, 16, 6, 2, 9, 11, 9, 9, 8, 12, -1, 13, 12, 6, 3 },
+ { 7, -3, -2, 4, 6, -8, 2, -3,-12, -5, -9, -8,-10, 15, -2, -4,
+ 8, 9, 7,-13,-18, 34, -5, 7, 12, 22, 16,-11, 13, 25,-15,-11 },
+ { -3, -2, 0, -4, 1, 0, -3,-13, -7, 13, 12, -7,-10, 13, 19, 6,
+ 16, 15,-12,-15, -3, 34, 1, 5, 1, -9, 11, 21, 8, 17, -5, -6 },
+ { 3, -5, 0, -4, 0, 4,-11, 4, -7, -3, -1, -8, 3, -2, 2, 1,
+ 11, 5, 6, 14, -3, 2, -4, -7, 0, 31, 15, -2, 24, 11, 5, 4 },
+ { -1, -4, -9, 5, -8,-18, -4, -9,-20,-18, 7,-14,-16, 3, 8, -3,
+ 29, 11,-13,-13, 7, 1, 17, 6, 6, 21, 11, 1, 14, -8, 2, 5 },
+ { -3, 8,-10, -6, 12, 2, 1, 3, 3, 3, 3, -6, -8,-14, 15, -5,
+ 16, 4, 16, 0, 7, -1, 0, 16, 2, 1, 22, 4, 19, 13,-11, 1 },
+ { 2, -3, 10, 20, -4, -1, -8, 5, -8, -9, -6, -2, -4, -7, 8,-10,
+ 0, 8, -6, 1, -8, 14, 13, 5, 17, -6, 26, -1, 7, -1, 0, 12 },
+ { -4, -7,-31, -2, -7, -1, 5, -5, -5,-12, 4, -7, -6, 3, 15, -2,
+ 5, -2, 7, -1, 10, 7, 8, -1, 14, 20, 14, 9, 16, 16, 8, 24 },
+ { -7, 0, -3, -6, 1, 3,-13, -6, -4, -4, -5, -9, -1,-10, -4, -8,
+ 2, 0, -1, 1, 24, 24, 21, 31, 5, 2, 11, 12, 7, 4, 3, 6 },
+ { -3, -5, 6, -4, -3, -1, 2, -1, -2, 1, 0, -8, -1, 2, 0, -4,
+ 6, 22, -1, -5, 8, 12, -1, -2, 28, 27, 20,-27, 14, 1, 2, -3 },
+ { 1, -5, -2, -2, 6, -2, 9, 1, -2, -5, 3, 4, 11, 5, 2, 8,
+ -3, -1, 1, -2, -3, -5, 5, 8, 49, 12, 8, -3, 9, 20, 12, 17 },
+ { -6, 0, 1, 7, 0, 9, -2, -4, 8, 0, -2,-10, 0, 7, 21, -1,
+ 0, 1, 17, -7, -5, 2, 4, 16, -2, 17, 14,-20, 15, 14, 4, 15 },
+ { 0, 3, -4, 9, -4, 0, 6, 4, -6, -6, -5, -7, 2, -9,-10, -2,
+ -5, 0, -3,-21, 9, 14,-11, 13, 29, 2, 25, 4, 22, -1, 2, -3 },
+ { 2, 12,-11, 2, 16, 9, -4, 7, 1,-10,-15, 11, -4, 3, -2, 4,
+ 4, -5,-10, 1, 4, 19,-15, 6, -4, -2, 30, -7, 11, 21,-12, 5 },
+ { -2, -3, -2, 4, -1, -5, -3, -7, -5, 1, 0, -6, 1, -6, 7, 0,
+ 8, -7, -3, -2, 2, 14, 2, -3,-26, -1, 26, 22, 32, 1, -2, 6 },
+ { 1,-38, -1,-20, -2, -3, -6, -4, 2, 2, 7, 0, 3, 5, 3, 10,
+ 6, 1, -3, -5, 7, 5, -5, -4, 8, 3, 1,-14, -1, -9, -5, -4 },
+ { -5,-26, -7,-19,-10, -5,-11, 5,-11,-25, -8,-14, -9,-16, -8, -6,
+ -17,-14, -1, -1, 6, 2, 2, 2, 3, 0, 2, 8, -8, 3, 0, -3 },
+ { 17,-49, -3,-23, -1, 11, 7, 3, 4, -4, 0, 0, -1, 4, 2, 4,
+ -2, -4, 2, -2, -1, -2, 2, 0, 0, -1, 0, 0, 1, 2, 0, 0 },
+ { 4,-34, -6, -9, 1, 21, -7, 3, -2, -1, -3, 18, 2,-16, 7, -3,
+ 8, 7, -5, 7, 2, 4, 8, -6, -7, -2, -5, -1, 4, 1, 2, -4 },
+ { 5,-29, 13, -2,-14, 3, 1, 18,-15, 4, -8, 8,-10, 8, 2, 1,
+ -8, 15, 3,-10, -4, -4, -2, 0, -3, -4, 2, -3, -4, -3, 12, -6 },
+ { 13,-20, 3,-18,-17, 4,-14, 13, 28, 11, -8, -6, 16, 6, 0, 10,
+ 3, 4, -9, 13, 5, -7, 12, -5, 0, -7, 5, 1, 3, 3, 2, 1 },
+ { 3,-27, -5,-11,-21,-11,-12, 0, -5, 7,-22, 1, 3, 5, 0, -5,
+ 8, 7, 1, -5, -7, 2, -5, 4, 1, 3, -8, -2, 0, 4, -2, 6 },
+ { 31,-45, 0, -1,-12, 1, 2, -6, 4, 3, -1, 3, 3, 0, 5, 3,
+ -5, 12, 4, 6, 2, 1, -2, 1, 3, 2, 5, 2, 2, 2, 3, -1 },
+ { 9,-45, 6, 5, -1,-17, -2, 18, -3, 2, 0, 1, 0, -1, 10, 8,
+ -7, -2, -5, -8, 6, -1, 0, 4, 6, -3, 12, -1, -2, 0, 5, -7 },
+ { 3,-26, -2,-12,-12, 2,-10, 16, -3, 12, 4, 5, 11, 8,-16,-17,
+ -2, -3, -3, 2, 5, -9, 13, 1, 10, 11, 3, 5, -2, 2, 2, -7 },
+ { 8,-26, 32, -7, -5, 22, 2, 14,-10, -8, -7, 3, 3, 7, 0, -5,
+ 0, -1, -3, 0, 8, 4, -5, -7, 6, -1, 4, 8, 1, 1, 7, -6 },
+ { 4,-31, 2,-14, 2, 0, 1, 8, -6, -1, 17, -3, 13, -6, 5,-10,
+ -2,-10, -2,-10, -3, 7, 1, 5, -8, 8,-14, -3,-15, 7,-10, -6 },
+ { 16,-27, 13, -4,-23, 7, -9, 6, -7, 5, 4, 2, -1, -3, 23,-18,
+ 7, 0, -3, 4, -3, 9, -6, -2, -1, 8, -6, 2, 6, -3, 2, -2 },
+ { -1,-35, -2, -8, 11, -1, -7, -3, -2, 11, 7, 6, -6,-10, 9, 6,
+ -3, -5, -6, -3, 9, 16,-16, -9,-20, 12, 3, 5, -3, 1, -9, 4 },
+ { 2,-24, 1,-12,-16, 5, -4, 3, -4, -1,-11,-11, -8,-14, 14, 10,
+ -8, 20, 8, -3,-11, 1, 1, -4, -4, -7, -3, 15, 2, -6, -2, 7 },
+ { 9,-21, 2,-19, -7, -5, -8, 25, 3, 17, 5, -3, 9,-12, 8, 2,
+ -4, 3, 3, 1, 11, -9, -4, -3, 4, 3,-22, 6, 4, 6, 11, -5 },
+ { 16,-23, 13,-17,-21,-12, 5, 9,-20, 7, 6, -6, 0, 2, -9, 6,
+ -6,-13, -7, -1, 5, -3, 5, -7,-10, 1, 0, 8, -9, 11, 0, -8 },
+ { 10,-26, -9, -7,-19, -4, 6, 16, -7, 5, -4, 4, 8, 0, 4, -1,
+ 6, -7, 1, -8,-11, 10,-14, 0,-16, 6, -3, 5, -1, 14, 12, 1 },
+ { 8,-27, 12,-14, -1, -1,-19, 10,-11, 21,-14, 9, -8, -3, 8, -1,
+ 12,-13, 3, -4, -2, 0, -9, 0, -7, 2, -3, 12, 1, -3, 3, 1 },
+ { 18,-20,-14,-14,-16, -3,-24, 6,-17, 2, -3,-11, 2, -3, 12, 10,
+ 10, 1, 10, 7, 8, 5, 5, 4, -1, 7, 2, 2, 0, 4, 7, 0 },
+ { 0,-30, 9,-16,-18, 15, 12, -3, 4, -4, -5,-11, -4,-12,-10, 0,
+ 2, -2, -4, -1, 2, 0, -1, -6, 2, -3, 4, -5, 7, 3, 5, 7 },
+ { 25,-24, -1, -6, -9, 6,-13, -2, 3, 15, -3, 11, 4, -8,-11, 2,
+ 0, -9, -2, 7, 4, 8, 5, -8, 5, 6, -1,-11,-15, -5, 0, 11 },
+ { 0,-34, -7,-11, -7, 9, -3, 19, 4, -8, 3,-11, 11, -3, -9, 12,
+ 9, 9, 2, 1, -7, 1, -3, 0, -6, -2, -1, 3, 0, -7, -2, -5 },
+ { 6,-34, -4, -5, -3, -9, 2, 9, -1, 9, -5, -3,-26,-12, 8, -6,
+ -7, 11, -8, 4, 4, 1, -1, 0, 8, 9, -4, 7, -1, 1, -3, -1 },
+ { 3,-30, 5, 6,-10, 3, -7, 6, 3, 3,-26,-19, -3, 1, 7, 5,
+ -4, -5, 6, 10, 13,-10, 4, -7, -4, 5, -3, 9, -6, 3, 9, 5 },
+ { 4,-24, 9,-19, 2, -4, -5, 8, -3, 2, 0,-15, -1, 9, -4, 22,
+ 6, 9, 3, 7, 11, -9, 0, -3, 4, 5, -5, 10, -8, 5, -7, -3 },
+ { 8,-27, 7, -3, -1, 2, -9, 13, 7, 12, -4, -6, -6, 5, 0, 7,
+ 5, 1, 15, -3, -4, 0, -5, -2, 7, -5, -7, 1, -2, 13, -8, 13 },
+ { 17,-22,-15,-11, -8, 16,-14, 18, 2, -1, 14, -7, 14, -6, -6, -7,
+ -8, 17, 6, 4, 4, -7, -5, -9,-14, -6, -1, 9, -3, 1, 6, -5 },
+ { 25,-30, 2,-12,-13, 18,-18, 16, 8, -3, 10, -8, -3, -1, -6, 3,
+ -5, -7, 4, 6, 7, 1, 1,-11, -5, 6, 2, -4, 9, -1, -5, -2 },
+ { 7,-23, 7,-15, -1, -3, -1, 0,-10, 12, 2, 5, -4, 0, 4, 6,
+ -1, 5, -9, -1, -1, -7, 1, 17, 9,-17,-16, 8, 4,-14, 11, 14 },
+ { 0,-31, 7,-13, 3,-11, -7, 6, 1,-11, 8, -7, 15, -3, 16,-11,
+ -1,-15, 16, -3, 5, 0, -2, -2, -6, 11, 5, 6, 5, -5, 6, 3 },
+ { 13,-24, -2,-20,-10, 7, -3, -1, 15, 2, 6, -5, -7,-10,-20, 1,
+ -4, 14, 8, -2, 3,-13, -3, 1, -4, 1, -3, 2, 8, -7, 16, -4 },
+ { 1, -2, -2, -3, -4, -7, 0, 3, 6, 7, 3, 2, 1, -2, -1, 0,
+ -6, 4, 2, -4, -3, -4, 5, 9, 5, 0, -3, -3, -4, -7,-31,-50 },
+ { -1, -3, 7, 2, -1, 2, 4, 6, 0, 10, -2, 0,-20, -6, -3, 9,
+ -20,-22, -1, -1, 15, 9,-12, 10,-13,-20, 12, 3, 5, 6, -7,-26 },
+ { 0, 4, -2,-14,-12, 6,-13, 11,-10, 3, 22, 6, 16, -2, -5, 1,
+ -3,-11, 0, -7, 5, -5, 0, 1, -1, -6, 8, 8, 10, 9, -5,-27 },
+ { -5, 10, -2, 7, 9, -9, 5, -9, 5, 4,-15, 14, 1, 3,-10, 5,
+ 0, -2, 7, 3,-13, 6, 9, -6, 5,-14,-17, -1, 11, 14, -2,-26 },
+ { 0, 6, -3, 0, -8, 6, 0, 1, 4, -8, 2, -5, 4, 7, 15, 11,
+ 9, 19, -2, 14, -8, 7, -1, 3, -3, -3,-10, -2, 12, -2,-12,-29 },
+ {-12, -5, 0, -3, -2, 6, 3, -3, 2, -2, 1, 11, 2, -7, 5, 1,
+ 2, -2,-14, 0, -1, -5, 3, 8,-28,-26, 6, -6, 3, 8,-10,-27 },
+ { -1, -3, 6, 2, 4, 15, 1, 0, 2, -2, -2, 13, 3, 6, 0, 6,
+ -1, -4, -1, -5, 8, -1, 5, -5,-15, 11, -8, -5, 14, -6,-14,-29 },
+ { -5, -6, 0, 1, 0, 6, -3, 2, -5, -1, 5, -3, 2,-10, 3, 4,
+ 3, 0, 13, -3, -1, 4, -4, -6, 2, 9, 8, 2, -3, 28,-11,-31 },
+ { 1, -4,-10, -9, -4, -3,-15, -6, 1, 5, -3, -6, 5, -6,-22, 27,
+ -13, 5, 3, -7, -4, 20, -7,-12, -1,-24, -4,-13, -8,-11,-15,-21 },
+ { -6, -4, 19, -6, 2, 11, -6, 1, -3,-10, 9, -9, 12,-10, 2, 1,
+ -9, 1, 15, 7, -5, 5,-29,-35, 4,-30, 9, 9, 19, 17, 2,-17 },
+ { -3, 3, -3, 1, 2, 5, -1, 5, -2, -3, 1, -3, -8, 3, -4, -2,
+ -4, -1, 12, 0, 2, -8, -6, -4, 16, -1,-14, -2, 25, -6,-15,-36 },
+ { 0, -1, 3, -4, -4, -1, 7, -4, 8, 0, 10, 9, -4, 1, 10, -1,
+ -3,-13, -5, -4, -1, -4, 8, 11, 14, -7, -5, 16, 12, 13, -1,-28 },
+ { 1, -2, 2, -3, -8, 10, 4, 9, 12, 3, 5, 0, 8, -3, -6, 2,
+ 16,-11, 11, 0, 1, 6, 1, 18,-10,-16, -1, -4, 5,-14,-15,-20 },
+ { 1,-12, 5, 4, -7, 8, -1,-17, -2, -9,-14,-11, 6, -9, 5, -4,
+ 3, -2, 7, 18, -5, 5, 6, -1,-11, -2,-10, -3, 8, -3, -2,-32 },
+ {-12, 5, 20, -5, -6,-11, -6, -6,-13, 4, -6, 19, -8, 2, 3, -9,
+ -4, -4, -1, 9, -1, 21, -1, 7, 15,-10, -1, -3, 9, -3, 2,-24 },
+ { 0, -3, 2, -6, 4, -1, -9, -2, -1, -3, 6, -1, -5, -6, -5, -8,
+ 0, -2, -6, 9, -4, 3, 2,-13, 1, -7, 23,-13, 4, -3,-15,-33 },
+ { -7, 2,-15, 11,-10, 14, 0,-11, 3, -1, 12, -4, -4, 9, 11,-13,
+ -13, -3,-14, 1, 3, 6, -5, 8, 0, 5, 5,-10, 4, 5, -6,-30 },
+ { -6, 4, 0, -5, 4, 1, -1, -1, 3, 6, 5, -2, -5, 0, -2, 5,
+ -4, -2, -4, -2, 4, 7, -7, -1, 1, -4, -3,-19, 37, 12, 10,-40 },
+ { -7, 2, -7,-12, 17, 11, -7, 2, 2, 3, 1, -1, 3, 4, -2, -5,
+ 9, -9, 6, 4, 9, 12, 11, -5, 2, -1, 0, 9, 5, -7, -2,-24 },
+ { -7, 6, 1, 3, 1, 0, 6, 0, 4,-12, -2, -2, 1, -9, 10, -2,
+ 11, -1, 21,-12, 15, -5, 10, -5, 5, -5, 14, -6, 5, -7, -3,-29 },
+ { -2, 0, -5, -2, -3, 1, -3, 0, 4, 2, 3, 0, 2, -2, 7, -2,
+ 3, -5, 2, -1, 6, -4, 0, -3, 8,-11, 19, -8, 22,-34, 13,-35 },
+ { -1, -3, -1, 9, 11, -3, -3, -1, 7, 18, 11, -5, 2,-12,-11, 18,
+ 9, -5, 1, -6, -9, 12, 1, -3, -3, -9,-14, 9, 9, 8, -6,-26 },
+ { 0, 5, -5, -1, -1, -2, 4, 6, 8, 2, -1, -2, 5, 1, -5, -4,
+ 1, 1, 18, 1, 7,-10, 3, -2, 12, -1,-15, 9, 12,-14, 13,-38 },
+ { 3, 0, -8, -1, 0, 8, -9, -3, -8, 16, 3, 16, -5, -9, 0, -1,
+ -7, -1, -4, 13, 7, 0, 1, 2, -1,-16, 0, -2, 1, 8, -8,-28 },
+ { 7, 9, -5, -3, -2, 2, 0, 3, 11, -6, -4, -2, -2, -5, 28,-18,
+ -6, 2, 15,-10,-15,-10, -2, 0, -2, -2, 4, -3, 7, 11, 5,-30 },
+ { 9, 0, -7, -1, -4, -7, 2, 2, 9, -2, 2, 3, -8, -6, -6, 3,
+ -10, 4, 10, 5, 21, -4, 14,-18, 1, 3,-10, -2, 6, 14, -8,-26 },
+ {-14, -1, 2, 3, -3, 7, 1,-22, -1, -1, 0, 1, 12,-14, 3, -5,
+ 0, 10, -3, 1, -5, 12, -3, 10, -8,-22,-11,-13, -7,-10,-13,-25 },
+ { -2, -5, -4, -4, -9,-18, 9, -3, -5, 17, 13, 5, 6, 11, 3, 8,
+ 20, 4, 2, 9, 8, 5, 6, 1, 7, -7, -6, -2, -7, 0,-17,-23 },
+ { -5, -5, 2, 0, 6, 2, -2, 2, -3, 4, 4, 0, -5, -2, -4, 6,
+ 8, 10, -1, 1, -5, 5,-14, -2,-11, 8, 6, 25, 7, -1, 0,-43 },
+ { -4, 0, 4, -2, 7, 0, 3, 17, 5, 2, -5, 1, 21, 3, -2,-10,
+ -16, -9, 7,-12, 9, -8, 2, 5, -5,-10, -2,-11, -5, -1, -9,-30 },
+ { -2, 3, 1, -4, -1, 0, 8, 1, 12, 4, -1, -1, 3,-17, 13, 9,
+ 0, 7, -6, -5, 9, 1, 5, 4,-10,-18, 0, 14, 11, -4,-16,-28 },
+ { -1, 0, 2, -1, 4, 1, -1, 1, -1, -2, -1, -2, 3, 0, 0, -1,
+ -1, 1, 2, -2, 3, 3, -2, 4, -2, -1, -6, 1, -1, -1, 6,-70 },
+ { 7, 3,-11, -1, 12, -4,-14, 4, 4, -4, 4, -2, 2,-12, -4, 15,
+ -17, -4, -3, 6, 8, -5, 22,-22, 5,-11, 15, -4, 4, -1,-21, -1 },
+ { 10, -2,-13, 11, 4, 14, 4, 9, 8, 8, 19, 15, 14, 15, 5, 10,
+ 8, 15, -5, 4, 14, -8, 1, 1, 2, 1, -1, -3, 21, 8,-29, 13 },
+ { -6, 0, -6, 6, -1, 2, 8, -4, -5, 4, -4, -5, 0, -2, -4, 0,
+ 9, -2, 1, -2, 26,-19, 21,-10, 4, 1, -8, 5, 22,-10,-13, 15 },
+ { 11, -5, 1, 0, 6, 3, 7, -2, -2, -3, -5, -1, -2, -6, 1, 1,
+ -8, -5,-13, 13, -2, -3, -1, -9,-28, 4, 2,-11, 18,-20,-24, 9 },
+ { 7, 4, -3, 6, 6, -6, -7, -5, -7, -4, -4, 0, -7, -5, -6, -5,
+ 2,-13,-12, 2, 0, 5, 18, 15,-13, -7, 13,-20, 16,-10,-19, 6 },
+ { 5, -8, -1, 5, 10, 2, -1,-10,-11, 23, 8, -5, -8, 4, -5, -4,
+ -5, -5,-11, -8, 5, 1, 7, -9, -9, -6, 12, 14, 17,-12,-22, 3 },
+ { -5, -8, -3, 3, 12, -1, 0, -4, -5, 1, 1, 6, 1, 5, -5, 7,
+ -2, 7, 1, 6, 6, 2, 0, -5, 17, -4, -5,-24, 13,-20,-27, 14 },
+ { -1, 2, -3, 1, -3, 1, -3, 0, -2, 3, -2, 1, 2, -1, -2, -1,
+ -2, -5, 5, -2, 0, -7, 1, -6, 8, 8, 11, -5, 24,-43,-13, 2 },
+ { -2, 4, 7, -3, -4, 4, 13, -4, 0, 0, -2, 9, 0, -3, -6, 1,
+ -7, 1, -1, 10, 0, 5, -1,-24, 25,-15, 7, 2, 22,-10,-21, 0 },
+ { -5, 2, 6, -2, 13, 3, 5,-12,-11, 16, 6, 10, -5, 0, -3, 6,
+ 5, -5, -5, 10, 12, 10, 11, -7, 8,-14, 2,-15, 13,-14, -8, -3 },
+ { 5, 6, -7, -5, 5, 2, 9, 5, 0, -1, -4, 2, 8, 0, 3, 5,
+ -12, 3, -3, -6, 2, -1, -5, 14, 11,-20,-21,-25, 24, -1,-10, 6 },
+ { -5, 5, -2, 9, 4, -4, -1, -6, 11, -6, 5, 0, 2, -3, 6, -1,
+ -17,-18, -4,-13, 9, -1, 9, -7, -4, -8, 2, -3, 12,-31,-18, 5 },
+ { -7,-11, 6, -8, 4, -3,-12, 0, -1, -6, -3, 0, 5, 9, 7, 2,
+ 1, -8, -6, 8, 2, -5, 7, -1, 16,-10, 16,-12, 18, -1,-25,-12 },
+ { 3,-12, 1, 2, -2,-18, -8,-15,-10, -9, 2, -7, 11,-11, 2, -1,
+ -1, -1, -9, -6, 3,-14, -2, -1, 2,-13, -7, -9, 19, -5,-17, 2 },
+ { 7, 1, -8, 7, 17,-13,-10, 5, 7, 1, -6, 4, 9, -4, 0, 3,
+ 8, 1,-14, -9, 4, 7, -9, 0, 6, -5,-12, -2, 25, -2,-19, 1 },
+ { 7, -3, 6, -3, 1, 6, -7, 0, 10, 0, 4, -5,-17, -4, 4, -1,
+ 0, -3, -7, 19, 24, -1, 21, 8, 10, 9, 8, -1, 23, -2,-18, -2 },
+ { 3, -3, 0, 5, 8, -2, -9, 2, 9, 6, 19, 8, 2, 6, -9, -2,
+ -4, -3, -8, 7, -7, -8, 5, 4, 26, -6, 7, 18, 24, 0,-13, 4 },
+ { 0,-13,-11, -1, 3, -9, 5, 4, -7, 3, 0, 2, -1, 4, -5, 2,
+ 9, -2,-11, 15, 1,-21, 1, -1, 0, 4,-14, -4, 24,-16,-13, 1 },
+ { 1, -9, -8, 0, 0, -4, 11, -1, 14, 16, 0, 17, -2, -9,-12, 0,
+ -1,-14, -9,-14, 0, -2, 19, 4, 6, 4, 4,-11, 8,-17,-19, -5 },
+ { -3, 1, 2, 12, -4,-18, -1, -4, -7, 14, -3, 2, 0, -7, -8, 12,
+ -5, -9, 14, 12, -9, -2, 4, -6, 4, 18, -1,-25, 22, 2,-23, -5 },
+ { -2, 0, 0, 0, 1, 3, 5, -1, 5, -2, -2, 2, -3, 0, 1, 2,
+ 0, -1, 2, -1, -9, -6, -7, -4, -2, 4, -7, -5, 64, -3,-25, 4 },
+ { 12, -2, -3, 0, 8, -9, 13, -7, 6, -3,-12, 12, 15, -9, -4, 2,
+ 9, -4,-12, 3, 14, 1, 7,-15, 15, 0, -6,-12, 0, -3,-20, 6 },
+ { 2, -1, -4, 5, 9, 6, -7, 2, -2, -7, -2, 0, -1,-18, -4, -6,
+ -15, -5, 11, 5,-10, -1, 2, 7, 12,-19, -7, 8, 21, -4,-15, 4 },
+ { 4, 2, 5, 5, -5, 1, 3, 2, -8, 13, 0, -5, -2,-14,-11, 6,
+ 2, 17, 8,-13, 26, -2, 5,-15, -4,-14, 12, -9, 13,-21,-23, -4 },
+ { 2, -3, -2, -3, 3, -2, 6, 9, -9, 13, 4, 2, 12, -3, -3, 1,
+ -17,-22, -3, 4, 3, -2, 1, -9, 1, -6, 11,-13, 14, 0,-15, 6 },
+ {-16, -4, 17, -2,-20,-11, 11, 10, 5, -8, 16, 2,-17,-14, 11, 11,
+ -6,-11, -7, 12, 12,-10, -6, 5, 8, -4, -2, -5, 28, 3,-13, 4 },
+ { 0, -3, 3, -7, 6, 8,-12, 20,-19, 18,-11, 10, -5, 0, -9, 11,
+ 3, 0, -2, 9, -7, -5, 18, 3, -2,-16, 1, 6, 12, -7,-16, 1 },
+ { 4, 1, 5, -5, 15, 2, -8, 3, 5,-11, 15, -3, 8, -8, -1, 7,
+ 4, 7, -2, 6, -9, 5, 12, 2, 33, -2, -6,-18, 4, 0,-18, 11 },
+ { 3, -1, 1, -1, 0, 1, 4, -1, -5, 0, 1, 0, 4, 2, -1, 4,
+ -3, 2, 0, -2, 4, 6, -1, 6, 42, 19, -4,-37, 19, 1,-15, -4 },
+ { 2, 0, -5, 0, 10, 0, 0, -5, 3, 0, 0, -3, -3, 0, 2, -4,
+ -10, 2, -6, 4, 4, 1, 27, -7, 17,-34, 5, -9, 15,-16, -7, -5 },
+ { -2, 7, 7, -2, 9, -2,-15, 11, 11, 7, 5, 1, 15, 1, -9, 31,
+ 2,-15, 2, 4, 3, 4, -1, -8, 2, -7, 6,-17, 11,-14,-11, 2 },
+ { 1, 1,-11, 9, 9, -6,-14,-11,-10, 8, -3, 11, 16, -9, -8,-13,
+ -8, 9, 0, 6, 6, -2, 13, -8, -2, 3, 13, -3, 10, -6,-17, 4 },
+ { 14, 5, 4, -6,-12, 10, -7, 8, 21, -8,-30, 15, -2, 1, 11, -9,
+ -5, 1, 0, -1, -1, -6, -2, 3, -5, 7, 9, 5, -5, 2, 0, 1 },
+ { -1, 2, 20,-17,-15, 3, 3, 7, 11,-17,-13, -6, -3, 18, 17,-15,
+ -4, -4, -5, 22, 14,-14, -2,-10, -7, 11, 8, -7, -3, 0, -7, 11 },
+ { 7,-11, -7, -8,-14, 22, 5, 2, 6, 13,-12, -2, 10, 3, 0,-21,
+ -4, 20, 3, 10, 21,-10,-12, 8, 11, 2, -5, 2, 1, 3, -1, 15 },
+ { -1, -2, -1, -2,-13, 8, -4, 0, 7, -2,-17, 8, 18, 5, 3, 8,
+ -8, -2, 3, -4, 14,-18,-13, 14, 15,-13, -1, -2, 4, 11, 1, 12 },
+ { 13, -6, -4,-16,-17, 16, 21, -2, 5,-11, -9, 19, 21,-17, -3,-17,
+ 3, 12, 8,-12, -6, 1, -7, 9, 9, -7, -5, -1, -3, 5, -6, -4 },
+ { 11, 5, 12,-20, -6, 10, 4, 12, 8, -5,-10, 15, 13, 14, 10,-15,
+ -13, 1, 6, 14, 15,-17,-13, 4, -5, 10, 7, -6, -8, -3, -4, 12 },
+ { 25, -1, 7, -5, -7, 11, 1, 17, 13,-15,-14, -4, 5, 3, 8, -3,
+ -2, 2, 0, 6, 16,-12, -6, -4, 4, -3, 7,-10, -3, -7,-13, 7 },
+ { -8, 10, -3,-13, 5, 2, 4, 9, 9,-17,-13, 2, 11, 1, 6, -4,
+ 8,-10, 4, 1, 19,-15, -4, 12, 31, 7, -5,-17, -4, 9, -2, 7 },
+ { 14, -6, -6, -6,-14, 13, 17, -5, 4,-14, -9, 7, 7, -9, 3,-16,
+ -15, 11, 11, 6, 4,-11,-19, 3, 5, 8, 13,-14,-14, 3, -4, 12 },
+ { -2, -4, 10, -4, -7, -1, 27, 5, 2,-16,-18, 4, 12, -2, -3, -2,
+ -1, 1, -8,-12, 3, -4, 8, 15, 2, 4, 9,-13,-14, 9, -7, 5 },
+ { 4, 2,-10, -5, -7, 2, 1, 4, -1, -6,-15, 6, 1, 10, 5,-10,
+ -9, -1, 13, -3, 5,-21,-11, 8, 8, 5, 27,-21,-18, -5, -1, 15 },
+ { 11, 1,-16, -8,-11, 0, 5, -8,-12,-13,-17, 22, 4, -6, -1,-18,
+ -10, 0, 19, 2, -2, -8, -7, -3, 2, -2, -9,-17, -5, 4, 4, 10 },
+ { 8, -6,-19, -5, -4, 12, 14, 15, 10, -9, -1, -9, 19, 12, 0, -1,
+ 2, 4, 7, 9, 16,-16,-14, 9, -4, 3, 1, 0, -2, 10, -1, -1 },
+ { 12, -8, 12, -9, 0, 25, 7, 9, 2,-31, -9, -4, 15, 4, -5, 1,
+ -10, 11, 8, 10, 0, -6, 5, 11, -1, -6, 4,-10, -9, 6, 4, 5 },
+ { 14, 6,-17, -2, 17, 12, -9, 2, 0,-25,-14, 5, 20, 14, 8,-20,
+ 5, 2, -2, -3, 9,-13, -3, -1, -6, 3, 7, -6, 0, 2, 3, 1 },
+ { 8, 4,-15, -3, 10, 18, -4, 13, 8,-22,-10, 9, 19,-15, 7, -5,
+ -13, 12, -4, 9, 2, -9, -6, 0, 2, 1, -9, -6, 6, 1, -1, 11 },
+ { 4, 1, 4, -5,-10, 18, 7, 2, -4, -9,-11, 0, 32, -7, 4,-16,
+ -1, 0, 6, 3, 6, -3,-14, 16, 9, -2, 7, -1, 0, -5, 5, -3 },
+ { -3, 2, 3, -8, -6, 4, 6, 2, 4,-12,-15, 2, 8, 8, 9, -3,
+ -18, 6, 34, 11, 12,-15, -1, 2, 9, 2, -4, -4, 2, 4, 2, -3 },
+ { 18, -6,-12, -8, -1, 15, 20, -4, -1,-11, -5, 6, 6,-11,-15, -7,
+ 3, 7, 10, 2, 8,-10, -5, 8, 15, -5, 5,-17,-13, 13, 11, 7 },
+ { 8, -4, -6, -1,-14, -3, 6, -2, 1, -5, -1, 10, 10,-15, 5, 0,
+ -10, -4, -3, 7, -4,-19,-15, 27, 11, 18, 3,-19, -2, 6, 0, 12 },
+ { 12, 0, -5, 0, 4, -5, 1, 5, 10, -7,-11, 21, 29, 1, -2, 1,
+ -4,-11, -1, 13, 11,-20, -1, 4, 4, 4, -5, 6,-13, -2, 11, 9 },
+ { 2, -7, -7, -3,-10, -1, 20, 12, 1,-19,-19, -1, 5, 4, -7,-25,
+ 14, 1, -3, 2, 12, -4, -3, -3, -2, 6, 1, 0, 3, 2, 5, -1 },
+ { 12, -8, 3,-12,-10, 10, 13, 0, 23,-14,-18, 10, 0, 15, 3,-12,
+ -3, -5, 5, -4, 2,-14,-10, 8, 2, 9, -1,-11, -3, 5, 13, 2 },
+ { 9, -6, 7, -7,-30, 17, 6, 13, 1,-14, 0, -1, 6, -9, 8, 3,
+ -4, 0, -1, -7, -5,-13,-19, -3, -4, 4, -6, -2,-13, 1, -2, 3 },
+ { 10, 1, 3,-18,-26, 17, 4,-16, 4, -3,-13, -4, -6,-11, -4,-21,
+ 7, 8, 2, 5, 13, -6, 1, 5, 8, 7, 9, -6, -6, 1, -1, 2 },
+ { -3, -1, 0, -2, -2, 0, -1, 3, 4,-14, -8, -9, 13, 2, 50,-23,
+ -8, 8, 7, 11, 16, 3, -7, 0, -2, 6, 5, -1, 1, -2, 4, 3 },
+ { 1, 3, 1, 1, -6, 3, 6, 6, 2, -2, -3, 10, 2, -8, -5, -5,
+ 5, 4, 4, -2, 10, -8,-40, -1, 21, 8, 3, -4, -1, 13, 4, 7 },
+ { 2, 0, -4, -8, 5, 2, 7, -5, 5, -8, -4, -1, 12, 2, 12,-13,
+ -9, 0, 1,-12, 9,-43, 1, -5, 12, 1, 3, 6, 1, -1, 3, -2 },
+ { 6, -2, -1, 1, 0, 4, 8, 14, 4, -7,-23, -5, 23,-17, -6,-15,
+ -8, 7, 10, -1, 7,-16, 4, -6, 2, 3, -3, -3, -1, 8, -1, 4 },
+ { 10, 4, -4, 1, 7, -3, 2, 11, 4, -6, -3, 8, 5, 4, 1,-45,
+ -6, -4, 4, 2, 1,-14,-10, 1, 1, 6, 2, -8, -1, -3, 3, 3 },
+ { 1, -1, 2, -3, -8, 9, 3, 3, -2, -5, -8, 8, 7, -7, -4, -6,
+ 5, -9, 11, -2, 46, -5, -1, 9, -2, 0, 3, -5, -3, -5, 7, 0 },
+ { -4, 1, -2, -1,-11, 11, 8, -3, -2,-10, 0, 4, 9, 9,-17,-17,
+ -34, -4, -5, -7, -3,-12, -3, 11, 18, 3, -2, -5,-18, -5, -3, 6 },
+ { 7, -5, -3, 1, -4, -3, -5, -1, 2, 5, -2, 3,-10, 12,-18, -5,
+ -10, 12, -9, 4, -6, 2, 0, 16,-17, 15, 14,-12,-10, -2, -9, -1 },
+ { 4, -5, -3, -5, -3, -1, 7, 18, -7, 12, 3, 5, -8, -4,-20, 1,
+ -25, 1, -8, 13,-10, 8,-19, -1, -8, 10, 6, -9, -1, 0, 12, 4 },
+ { -4, 5, 0, -1, 2, 5, -8, -2, -6, 4, -8, 9, 3, 2, -7, 4,
+ -25, 13,-23, 10, 14, 15,-11, 3,-18, 4, 16, -4, 1,-10,-10, 3 },
+ { 5, -3, -1, -3, 4, 1, -3, -4, -5, 1,-12, 14, -7, 11,-15, 6,
+ -6, 24, -4, 13, -1, 15,-13, 8, 3, 7, -5, 2, 2, 0, 3, -7 },
+ { -3, 1, 0, 8, 6, -1, 6, 5, -5, -2,-12, 4, 0, -2, -3, 5,
+ -6, 0, -8, 9,-10, 4,-28, 12,-20, 11,-13, 7,-18, 1,-11, 1 },
+ { 1, -4,-15, 5, 0,-13, -5, 13,-11, 4, -4, -5, 5,-14,-16, 0,
+ -14, 5,-20, 12, 10, -7, -5, 6, 6, 22, 6, -4, -2, 3, 8, 11 },
+ { 13,-11, -2, 16, 16, -7, 0, 20, -7, -1, 0, 5, -9, 12, -2, -5,
+ -22, 5,-10, 12, -6, 11, 9, 21, -8, 15, 4, 0, -8, -4, -4, 10 },
+ { 18, -4,-13, 0, 1,-15, -1, -3, 2, 10, -1, 6, 1, -4,-20, -5,
+ -8, 6, -8, 17, -5, 5,-10, 8,-22, 6, -5, -2, 8,-17, 8, 2 },
+ { 1, -2, -9, 6,-31, -8, -8, 8, 0, 5, -9, -4, 2, 3,-12, 11,
+ -18, 10, -5, 3,-11, 13, -6, 11, -3, 12, -7, 3, -9, -1, 2, 11 },
+ { -9, -6, 21, -8,-15, 4,-11, 12,-11, 17, -1, 2, -6, 0,-15, 13,
+ -12, 19, 0, 2, -6, -3, -9, 10, 3, 17, -2, 5,-10, -3, 0, 1 },
+ { 4, -6, 5,-10, 1, -5, 1, 0, 0, 0, 2, 7, -2, 2, -2, 0,
+ -4, 3, -4, 1,-12, 6,-49, 16,-10, 13, 0, -2, 8, 6, 1, 8 },
+ { 5, -8, -7, 9, 13, -5, 7, 0, 10, 11, -4, -3, -1, 13,-14, 6,
+ -15, -6,-14, 16, 15, 1,-18, -4,-20, 20, -7, -1, -9, -2,-10, 10 },
+ {-12, 4, 0, 10, 0, 3, 8, 4,-27, -1, -2, 19, -4, 2,-13, 3,
+ 1, 9,-12, 1,-22, 19, -5, 4, -9, 12, 2, -9, -8, 11, -3, 7 },
+ { 4, -5, 11, -6, 17,-17, 5, -4, -2, -6, 1, -5, 2, 4,-14, 6,
+ -20, 19,-20, 12,-21, 5,-14, 13, -2, 11, 4, -3, 0,-10, -4, -2 },
+ { -2, -1, -3, 8, -9, -7,-22, -3,-24, 13, -2, 10,-15, 5, -9, 4,
+ -7, 0, -5, 15, -8, 11,-13, 6, -4, 19, -8, 12, -4, 6, 9, 7 },
+ { 2, -3, 2, -1, 0, 3, 1, 2, 1, -4, -2, -3, 1, 5,-12, 6,
+ -16, 14,-23, 10,-14, 17,-15, 16, -2, 9,-25, 9,-10, 16, 4, 9 },
+ { -3, 7, -8, -3, 2, 2, -4, -8, -9, 10, 3,-11, 25,-10,-28, 27,
+ -9, 7,-13, 9, -2, 4,-12, -8,-14, 6, 7,-10, 3, 3, -3, 5 },
+ { -8, -3, 1,-10, 8, -3, -9, -4, 13, 7, 2, 4,-10, 4, 3, 7,
+ -18, 2,-22, 15, 4, 20, -7, 5, -6, 13, -1, 4, -7, -6, 6, 13 },
+ { -2, 3, 0, 2, -4, -2, 0, 0, 1, 2, -2, -5, 0, 1, -4, 0,
+ -2, -3, 1, 2, -1, 2, -8, -1,-24, 68, -3, 8, 3, 3, -1, -1 },
+ {-15, -2, -9, -7, -1, 8,-14, 8, 3, 6, 0, -1, -8, 8,-23, 2,
+ -14, 17,-15, 8, -4, 7,-18, 0, -8, -3, -1, -4,-10, 4, -1, 4 },
+ { 8, 0, 2, -7, 0, 5, 1, 3,-11, 4, -8, 14, 3, 20, 1, 26,
+ -11, 13,-13, 20, -2, 0, -8, 2, -6, 6, -1, 9, 3, -6, -3, 10 },
+ { 5, 0, -1, -7, 10, 1, -3, 5, 4, 7, -5, -1, -3, -1, 12, -3,
+ -15, 7, -9, 22,-19, 8, -9, 4,-23, 13,-14, 6, -6,-14, -4, 7 },
+ { 14, -5, -8,-10, 25, 3,-23, -7,-28, 0, -1, -9, 4, 1,-13, 20,
+ -8, 10,-16, 8, 12,-13,-21, 5,-13, 11, -2, 1, 12, -7, 2,-10 },
+ { -5, -4, 9, 5, -6, 35, -7, 8, 15, 2, -1, -9, -6, 2,-18, 7,
+ -15, 6, -3, 2, 8, 12,-30, 7, -4, 20, 2, 6, 13, -6, -4, 0 },
+ { 1, 8, -9, 9, -5, 12, -9, 16, -9, 16,-17, 14,-13, 15,-18, 14,
+ -15, 17,-12, 14,-13, 7,-16, 13, -9, 5,-11, 10, -9, 6,-12, 13 },
+ {-10, -4, 5, 3, 1, 6, 8,-14, -5, 15, 7, 4, 8, 7,-22, 8,
+ -7, -8,-15, 26, 1, 13, -3, 17, -5, 9, -2, 4, -6, 3, -8, 9 },
+ { 8, -3, 2, 3, 3, 1, -2, -1,-11, 8, -4, 0, -6, -5, -1, 13,
+ -37, 9, 1, -6,-10, -2,-10, 11, 8, 13, -3, -2, -6, 8, -4, 13 },
+ { 3, 2, -3, -4, -4, 7, -8, 9, -8, 9,-20, 12,-19, 15,-18, 17,
+ -15, 7, -1, 20,-11, 6, -6, 3, 1, 9, 2,-14, -2, -2, 2, 1 },
+ { -7, 1, -1, -3, -6, 4, 4, -3, 3, -1, 5, -4, 3, 2, -1, 9,
+ -59, 5, -4, 30, 3, 3, -2, -3, -1, 2, 2, 1, -1, -1, -2, 1 },
+ { 0, -3, 2, 0, -1, -8, 0, 2, -3, 4, -4, 1, 10, 6, -6, 8,
+ -7, 4, 10, 11,-41, 27,-20, 3, -3, 8, 1, 11, -5, -8, 0, 4 },
+ { 5, 1, 4, -2, 1, 2, -1, 6, -7, 2, 11, 4, 0, 0, -8, 7,
+ -10, 0, 0, 8, 2, 10, -1, 1, -2, 44, -2,-21,-12, -3, -1, 2 },
+ { -4, 4, -2, -2, 6, -8, 2, 1,-10, 14, 8, 6, 5, 1, -2, 4,
+ -13, 4, 2, 5, 10, -2,-21, 32, -3, 18, 9, -6, -9, -9, 10, 2 },
+ { 9,-16, -6, -2, 1, 4, 22, 2, -2, 1, -3, -2, -9, 3, 16, 19,
+ -24, -6, -6, -5, -8, -7, 8, -7, -1,-12, 5, -3, 0, 4, 2, -3 },
+ { 10, 3,-16, -4, -1, 13, 4, 4, 1, -3, 1, -6,-14, 18, 3, 8,
+ -8,-28,-16, 4, 4, 2, 12, 7, 9, -4, -4, 5, -1, -1, 2, 2 },
+ { -5,-13,-22, -3, -8, 21, -2, -9, 21, -4, -9, 5, -8, 15, 5, 1,
+ -5, -9, -7, -2, -5, -5, -1, -5, -5, -5, 3, 10, -4, 0, -7, -2 },
+ { 5,-10,-18, 2, 20, 4, 13,-10, 8,-15,-11, -3, -1, 16, 10, 9,
+ -8, 6, 7, -5, 6, 11, 5, 17, -4, 7,-11, 5, -3, -6, 2, 1 },
+ { 3, -5,-19, 1, 1, -3, -2,-25,-11,-17, 0,-13, -4, 10, 10, 2,
+ -5, 4, 0, 3, -3, -5,-10, -2, 13,-22, 0, 3,-11, -5, 7, -1 },
+ { 12,-14,-29, 6, -1, 10, 7,-17,-12, 14, 3, 9, -9, 9, 7, 6,
+ -3,-13, 0, 5, 3, -1, -6, -1, 0, 2, 4,-12, -5, -1, 2, 11 },
+ { 12,-15, -7, -2,-12, 17, 20,-16, -2,-12, -6, 15, -6, 12, 11, 9,
+ 7, -6, 7, -4,-19, 6, 2, 2, 3,-11,-10, -4, -5, -3, 3, 2 },
+ { 11,-22, -6, 0, 8, 18, 3,-11, -4, -7,-15,-17,-12, 6, 16, 4,
+ -9, 4, -5, 3, 6,-16, 10, -7, -7, -3, 5, 0, 1,-15, -4, 5 },
+ { 12,-22,-16, 5, -6, 8, 12, -4, -9,-17,-11, 3, 5, 8,-17, 0,
+ 11, -4,-13, -6, 2, -1, -1, 3, 3,-11,-12, -1, 1, 1, 12, -2 },
+ { 8,-10,-33, -5, -3, -6, 1, -7, -8, -4, -6, -1, 5, -4, -6,-12,
+ -16, -8, 11, 8,-14, 7, 12, 11, 4,-14, -3, 6, -7, -5, -3, 3 },
+ { 0, -8, -7, 2, -4, 24, 2, -9,-11, -3, -7, 11,-12, 17, 1, -1,
+ 3, -5, -7, 12, 4, 11, 0, 3, 2,-18, -3, 4, 7, -6, 3, 15 },
+ { 10,-15,-16, -2, -4, -9, 7,-15, -6, 2,-16, 13, -8, 7, 19,-21,
+ -4,-12, -9, -3, -3, 6, 11, -3, -1,-19, 3, -7, -9, -4, 3, -6 },
+ { -5,-10,-21, 0, -3, -7, 18,-21, 15, -5,-12, -4,-13, 2, 6, -9,
+ -9,-11, -4, 13, -3, 6, 4, -1, 7, -9, -4, 9, 5, 2, 6, 3 },
+ { 15, -1,-27, -2, 10, 3, 7, -8, 9, -2, 7, 1, -2, -5, 18, 9,
+ -11,-17, -2, 7, -9, 11, 10, 0, -8, 6,-16, -3, 2, -7, 3, 11 },
+ { 4, -9,-39, 19, 6,-13, 13, -5, -5,-15, -2, 9, 0, 4, 14, 6,
+ -10, -4, -5, 2, -4, -2, 5,-11, 3, 3, -2, -2, -7, 9, 7,-10 },
+ { 5,-11, -8, 10, -2, 12, 16, 0, 12, -2, -6, 8, 14, 8, 7, 1,
+ 18,-30, 4, 10, -4, -6, 2,-11, 9,-10, -8, 5, 0, 0, -7, 6 },
+ { -1,-16,-10, 11, 0, 13, 12, -4, -4, -5,-21, 12, 4, 13, 14, -7,
+ 6,-16,-13, 8, 2, 9, 15,-12, 1, -9,-22, 10, -9, 9, 9, -7 },
+ { 4,-12,-27, 1, -2, 11, 15, 3, 14,-14, -9, 0, -9, 16, 22, 10,
+ 16,-10, 5, -5, -9, 1, 1, 6, 6, -4, 2,-17, -5, -6,-15, -1 },
+ { 7,-12,-17, 1, -9, 5, 20, -7, 3, 23, -8, -8, -8, -1, 13, 17,
+ -7,-13, 4, -4, 7, 14, 8, 11, -3, -3, 4, 0, 4, 6, -1, -9 },
+ { 7,-15,-15, -4, 10, 12, 3,-13, 6, 14, 9, -8,-15, 14, 23, -5,
+ -10, -5, 1, 15,-10, -7, 1, 9, 4,-13,-10, 10, 7, -3, 2, 3 },
+ { 4,-10,-14, 0, 3, 4, 0, -9, -3, -4,-11, 2,-17, 8, 2, 15,
+ 6,-12,-12, 15, -5, 17, 18, 3, -3, -3, -4, -6, -8, 13, 4, 10 },
+ { -2,-18,-26, 10, -4, 10, 13, 4, -4,-16, -7,-17, -3, 5, -4, 2,
+ -15,-10, -1, -8, -7, -3, 2, 2, 8,-10, -7, 2, 2, -4, 4, -1 },
+ { 4,-19, -5, -1, -1, -6, 2, -8, 10,-16,-28, -6, 8, -1, 11, 28,
+ 2,-10, -4, 6, -6, 6, 11, 15, -4, -2, 7, 3, 7, -7, 4, 1 },
+ { -3, -6,-10, -5, 13, 18, 10,-15, -5, -3,-13, 5, 1, 2, 18, -5,
+ -10,-10, -7, 4, 2, 1, 5, 4, 2, 5, 4, 8, -9,-17, 7, 7 },
+ { 20,-12, -2, -4, 5, 14, 7,-11, -1,-16, -6, -4,-11, 17, 14, 0,
+ -8,-10, -8, 10, 3, 5, 10,-16, 3, -8,-14, 10, 3, 9, 0, 3 },
+ { 12,-10,-36, 0, 7, 15, 2,-16, 2, -1, 0, -1, 5, 4, 5, -3,
+ 1,-10, 5, -1,-15, -3,-12, 12, 2, 5, -1, 5, 6, -3, -2, 2 },
+ { 17,-15,-31, 23, -4, 15, -2, -3, 6, -7, -5, 1,-12, 4, 6, 8,
+ -10, 8, 3, 5, -4, 1, 5, 3, -1, -4, -3, 1, 10, -4, -2, -2 },
+ { 6,-18, -5, 12, 10, 12, 14,-11, 15, 2, -9, -6, -5, -2, -9, 4,
+ -5,-28, -4, 14, 0,-16, 9, 14, -1, 3, -4, -4, 2, 1, 0, 4 },
+ { -5,-14,-31, 8, 16, 7, 13,-13, 5, 6,-16, 10, -5, 2, -2, 2,
+ 14, -5, 8, -5, 7,-16, 6,-13, -5, 0, -5, 8, -3, -1, 4, 3 },
+ { 1, -2, -1, 0, 6, 5, 2, -4, -3, -1, 0, 1, 4, 2, 43, 28,
+ -12,-35, -2, -2, -7, -1, 0, 2, -1, -2, -2, 1, -4, 0, -2, 3 },
+ { 2, -9,-22, 12, 3, 3, -7, -4,-19,-22,-14, -4, -1, 21, 9, -3,
+ -15,-16,-13, 1,-11, 4, -9, 1, -7, -1, -1, 0, -2, 9,-13, -3 },
+ { -1, -3,-23, 0, 2, 12, 3, -9, -4, 7, 3, 9,-10, 1, 27, 28,
+ 0, 9,-15, -2, -2, 1, 6, 8, -8, 7, -3, 20, 0, 0, -1, -6 },
+ { -1, 11, 8, -2, 1, 5, -6, -1, 4, 2, -4, 0, -1, -5, 4, -6,
+ -10,-12, 19, 1, -7, 9, -8, -9,-16,-11, -2, 12, 14, 4, 4, 34 },
+ { 17, 7, -6, 1, 4,-10, -5, 4,-11, 3,-18, 4, 14,-13, -3, 1,
+ 0, 0,-11, 0, 7,-17, -4, 4,-11, -6, -8, 18, 0, 0, 0, 26 },
+ { -6, -7, -1, -1, 11, -8, 1, 3, 2, 11, -6, -6, 10, -3, 1, -3,
+ 7, 4,-12, -8, 0, -9, 8,-22, -5, 0, -6, 22, -2, 11,-13, 24 },
+ { -3, 4, 0, 3, 9, 10, -1, 3, -9,-12, 1, -5, 18, 0, -3, 8,
+ 25, 15, -8, 2, 2, -2, 4, 8, 9, -1, -5, 10, -3, 1, -1, 23 },
+ { -5, 2, -9, -1, -3, 0, 3, -1,-10, -4, 0,-13, 16, 9, -1,-14,
+ 2, 6, -2, -6, -5, -2, -7, 7, 5, 3, 11, -2,-14, 0, -9, 30 },
+ { 4, 6, 6, 5, -3, -1, 4, 5, 10, 0, 5, -4, 7,-11, 14, 14,
+ 7, 34, -9, 0,-10, 22, -7, -1, 7, -9, 2, -8, 0, -7, -5, 29 },
+ { -4, 3, -1, -4, -3, 5, 1, -4, 0, 2, 4, 2, 1, -1,-10, 1,
+ 6, -6, -4, 1, 4, -3, -3, -5, 0, 3, 7,-12, 0, -2,-10, 55 },
+ { 5, 9, -1, 0, 4, 9,-21, -9, 4, 2, 6, -7, 11, -7, 1, -5,
+ 0, -4, 2, -3,-13, -8, 0, -9, -4, 2, 16, -2,-15, -7,-11, 31 },
+ { 8, 2, -1, 0, 3, -5, -5, 5, 1, -1, -9, 1, 0, -6, -2, -1,
+ 5, 2, 0, 0, 12, 20,-19, 1, 8,-12,-11, 0, 6, -5, 2, 31 },
+ { -1, -1, -2, 1, -1, 3, -9, -5, 8, -2, 5, -1, 0, -2, 4, -2,
+ -3,-12, 0, -2, 3, 0, 9, 4, -1, 21, -8, 3, -4, 9, -6, 30 },
+ { -4, 0, -7, 17, 10,-12, -2,-10,-12, -3, 10, 0, 11, -4,-13, -3,
+ 5, 6, 10, 7, -8, 0, -7,-13, 1, 0, -2, 7,-12, 4, -3, 24 },
+ {-13, 9, 4, -2, 2, -4,-14, -1, -3, -5,-10, 4, 13, -2, 5, 13,
+ 8, 3, -2, 1, 5, -6, 7,-18,-10, 1, -1, 5, 4, 1, 0, 25 },
+ { -5, -1, 18, 12, 8, 8,-16, -1, 1, 1, 1, -4, -5, 3, 3, 4,
+ 4,-11,-12,-16, -6, 2, 12,-13, 0, 9, 7, 9, -9, 0,-10, 24 },
+ { -4, 1, -3, 0, 2, -4, 4, 1, 5, 0, -3, 2, -3, -2, 2, -1,
+ 1, 4, -1, -2, -2, 1, -1, -1, -4, -1, -4, -2, -6, 6, 12, 69 },
+ { 8, 5, 11, 0,-15, -4, 13, 6, 0, -4, 9, 1, -5, -3, 15, 0,
+ 1, 6, -5, 0, 1, 6, 5, 8, 0, 7, 1, -1, -4,-11, -9, 41 },
+ { -4, -9, 32, -6, 0, 7, -4, 6, -6, 1, -6, -2, 4, -8, -5, -3,
+ -16, -1, -2, -6, 1, 15, 0, 21, 3, -3, -4, 3,-12, 16, 2, 27 },
+ { -6, -5, 1, -9, -5, 3, 7, -3, 5, 5, 14, 13, 20, -7, -1, 12,
+ -1, 10,-11,-11, -7, -4,-14, 7,-14, 13, 22, 18, -1, 0, 14, 28 },
+ { -8, 3, -2, 0, 5, 6, -1, -4, 1, 3, -7, 3, 1,-15, 4, -9,
+ 22,-10, -9, -4, 1, 8, -4, 9,-15, 2, -6, -4,-16, 12,-10, 23 },
+ { 0, 0, 2, 0, -1, 3, -3, -1, 3, -5, 7, 1, 5, -5, -8, 1,
+ 13,-15, -5, -7, 12, -6, -2, 3, 10, -5, -8, 17, -5,-11,-14, 23 },
+ { -7, -4, 6, -4, 5, -6, -5, 2, -4, 11, 9, -4, 2, -2, -4, 6,
+ 15, 3, -3, 18,-15, -2, -6, 3, 3,-20, 17, 11, -4, 2, 3, 29 },
+ { 6, 1, -6, 2, 3, 0, 0, -3, 3, 3, -1, 3, -4, -6, -6, -7,
+ -3, -2, -7, -2, -4, 5, 3, -5,-20,-13, -4, 10,-14,-29, 14, 37 },
+ { 3, 4, 3, -6, -4, 5, 0, 3, 2, 3, 0, -2, 4, 0, -3, -5,
+ -4, 4, -4, 4, 4, 3, 1, -4, -4, -9,-14, 20,-30, 3,-18, 33 },
+ { 0, 2, 5, -2, -4, -2, -1, 2, -6, -3, -2, -2, 2, -5, -1, 4,
+ 3, 2, -3, 0, -1, -1,-10, -7, 2, -4,-18, 2,-37, -1, 12, 40 },
+ { -7, 2, -1, 0, -2, 4, -8, 1, -4, 12, 7, 4, 15, -7, 1, -9,
+ 18, 0, 12,-17, -3, -1, 0, 0, 0, 2, -6, 0, -4, -3, -1, 26 },
+ { -6, 4, 8, -5, -6, -2, 2, -1, 1, -1,-15, 8, 7, -1,-17, -4,
+ 1, 5, 6,-11, -6, 14, 17, -5,-15, 11, 8, 0, -3,-15, -6, 28 },
+ { -1, 0, 0, 0, 1, 0, -1, 0, 1, 3, 2, -2, 3, -1, -1, 2,
+ 2, -1, -1, -7, 1, 2, -9, 0, -1, -4,-18, 7,-10, 49,-13, 32 },
+ { -1, -3, 4, 1, 2, -5, 1, -7, -1, 5, -9, 4, 4, 25, 1, -1,
+ 2, -5, 2, -7, 17, -2, 10, -5, 0, 2,-15, 3, -9, 7, -9, 30 },
+ { -5, -1, 0, 2, 1, -1, 2, 5,-33, 3, -5, 14, 11, 7, 5, -3,
+ 2, -8, -4, -2, -7, -6, 4, -8, -1, -8, 2, -2, -8, -1, -4, 27 },
+ { -1, 0, -1, -2, 1, -1, -2, -1, 2, 0, 1, 2, 2, 4, 1, 3,
+ 4, 2, 1, -7, -4, 1, -3, -4,-35,-25, 17, 10, -3,-26, -7, 32 },
+ { -5, 1, 6, -2, 6, 6, -9, 3, -1, -4, 5, -4, -2, -2, -9, 2,
+ -5, 2, 2, 4, 3, 5, -5,-16,-31,-12,-11, 2,-19, 20, -2, 21 },
+ { -5, 2, 7, -7, -7, 5, -7, 2, 0, 0, -4, 3, -1, 0, -1, -2,
+ 0, -3, 5,-11, -8, -3, -7, -7, 28,-11, -7, 0,-16,-11, -4, 29 },
+ { 2, 1, -3, -2, -1, 3, 4, 0, 1, 0, -1, -5, 4, -5,-12, 2,
+ -2, -5,-22, -2, -1, 11, 8, -7,-12, 0,-34, 6, -5, 11, -8, 19 },
+ { -1, -3, 5, 11, 18, -2, -2, -5, -2, 4, -1, 8, 5, -6, 1, -1,
+ 2, 8, 4, -5, -8, -2, 5,-18, 7, 12, 7, 19,-18, 2, -6,-13 },
+ { 9, 0, 0, 5, 4, 3, -6, 4, 1, -4, 5, -1, -4, 8, 8, 6,
+ -8, -6, 0, 6, -3, 3, 5, -3, 17, 31, 16, 10,-13, 0, -9,-19 },
+ { 12,-10, 2, -2, -2, -1, -3, 6,-12, -5, -2, 14,-16, 4, 12, 12,
+ 17, 4, 7,-16, 7, -6, 11, 7, 7, 2,-25, 23,-24, 5, -7, -9 },
+ { 10, 4, 13, 10, 10, 3, -6, 3, 3, 2, -1, -6, 8, 4, 10, 0,
+ 1, 2, -4, 2, -3, -8, 0, -1, 9, 9,-10, -3,-29, 1, -1,-27 },
+ { 2, 2, 0, 7, 9, -2,-10, -1, -1, 1, -9, -5, 8, 4, 1, 2,
+ -10, 1, 13, 12, -3, 15, -9, 2, -7, 1,-10, 23,-20,-18, -9,-15 },
+ { -3, -5, -1, 8, 0, -5, -1, 4, 7, -1, -7, 2, -8, -5, 11, 7,
+ -6, 3, -3, -9, 7, 9,-22, 1, 6, -4, 14, 27,-25,-14, 3, -5 },
+ { 1, 3, 8, 4, 7, 6, 12,-17,-15, 1, -8,-10, 7,-14, -8, 6,
+ -2, -2,-11,-11, -7, 13, -2, -2, 4, 5, -5, 13,-23, -6,-17, -8 },
+ { -5, 4,-14, -5, -4, -5, 6, 5, -8, -5, -2,-11, -7,-12, 3,-11,
+ 2, -6, 4,-10, -5, -7, 14, 5, 23, 11, 7, 12,-16, -6, -4,-16 },
+ { 5, 6, 2, 5, -2, -5, -5, -6, -5,-19,-13, -1, -3,-13, 5, 0,
+ 6, -2, -2, -6, -7, -7, -1, -9, 4, 14, 17,-12,-27, 3, 0, -1 },
+ { 7, -1, 9,-10, 8, 2, -7, -2, 5, 2, -3, -7, 3, 0, 6, 4,
+ 12, 5, 11, 14,-13, -1, 8, 1, 13, 9, 12, 12,-18,-14,-11,-16 },
+ { -7, -5, -6, -5, 0, -1, -3, 2, 2, 1, 4, 9, 2, 3, 5, -2,
+ 2, 1, 8, 0, 3, 0, -2, 2, 1, 7, 29, 0,-36, -5, -9,-21 },
+ { 14, -6, -9, 0, -1, -8, -8,-11, 2, 2, -9,-12, 12, -4, 5, 3,
+ -5, -9, 11, -1, -3, 12,-21, -3, 12, 5, 3, 11,-18,-15, 1, -2 },
+ { -1, 3, -9, -3, 7, -7,-18, 2, 4, 12,-10, 2, 8, -3,-14, 13,
+ 17, -5, 5, -9, 13, -3, -7,-18, 17, -2, 5, 7,-20, -3, -6,-11 },
+ { -3, 3, 3, -1, 1, -6, -5, 1, 5, -3,-14, -6, -5, -8, 14, -6,
+ 7, -1, 5, 1, 15, -1, -7, -4, 6,-11, 9, -2,-37, 16, -7, -3 },
+ { -1, 0, 6, 1, -3, -9, 0, 11, -8, 2, -2, 0, 5, 2, 12,-10,
+ 10, 13, 2, 7, -6, 2,-10,-10, 21, -5, 5, 5,-12,-23, 3,-14 },
+ { 6, 0, -2, 1, 0, 1, 0, -4, 1, 1, 8, -2, 2, -5, -2, 1,
+ 8, -4, -1, -1, 4, -1, 2, 6, 32, 1, -5,-20,-40, -4,-18,-14 },
+ { 2, 2, -7, -2, 4, 4, -1, 2, 0, -2, -4, -7, 3, 5, 0, -5,
+ 1, 2, -6, 4, -1, -2, -1,-15, 8, 3, 9, 46, -7,-18, 6,-11 },
+ { 5, 5, 16, 21, 3,-11, -4, 11,-12, 2, 4,-12, -1, 11, 8, 1,
+ -4, 11,-11,-21, 1, 1,-11, 3, 13, 1, 5, 12,-25, 1, -3, -2 },
+ { 1, 6, -7, 4, 2, 3, 1, -5, 8, 9,-15, 3, -3,-14, 17, 4,
+ -8, 14, -2, -8, -4, 5, 8, -7, 8, 9, 7, 6,-29,-17, 8, 4 },
+ { -7, -7, 4, 0, 13, 1, 0, 4, 4,-16,-10, -7, 5, 9,-15,-10,
+ -10, 8, -4, -1,-11, -1,-10,-15, 3, 3, 14, 10,-19, 2,-18,-12 },
+ { -4, 0, 2, 0, 5, -2, -9, 0, 4, -4, 2, -1, -2, 2, -4, 9,
+ 2, -6, -4, -2, -1, -3, -3, -1, 2, 5, -1, 11,-24,-44, -9,-15 },
+ { -1,-10, 6, 21, 11, 15, -7, 10,-14, -9, -8, -8, 4, 6, 19, 1,
+ -6, 1, -5,-17, -8,-10, 9, 5, 11, 18, -1, 10,-16, -7, -9, -8 },
+ { 3, -5, 0, 0, -2, -2, -6, 4, -4, 1, -1, 0, 7, -3, 4, -4,
+ -7, 7, 17,-20, 6, 4, 1, -6,-12, 31, 13, 19,-14,-10, -7, -2 },
+ { -2, 6,-10, 3, 9, 6,-14, 15, 2, -5, 2,-11, 9, -8, 4, 6,
+ 20,-15, -3, -3, -1, 32,-21, 6, 1, 9, 11, 17,-19, 6, -1, -3 },
+ { 8, 10, -2, 0, -8,-16, 7, 7, 6, 10, 4,-14, 7, -6, 21, -7,
+ 10, 5, 5, 0, -7, 2, -6, 0, -7, 11, -9, 15,-20, -7,-11, 2 },
+ { 0, -7, 5, 2, 0, -3, -6, -4, -2, -1, -4, -5,-13, -1, 27, -9,
+ -6,-11, -7, 1, 11, -4, -4,-14, -2, 11, 6, 10,-19, -6,-15, 2 },
+ { 0, 7, -1, 2, -7,-15, -2, -3, 13, -5, -5, 12, 3, 0, 5, -5,
+ -22, 2, 7, 22, 13, 0, -1, 2, 3, 2, -7, 7,-27, -4, -4,-12 },
+ { 11, 1,-16, 6,-15, 1, 3, 2, 0, 2, -3, 2, 5, -2, -5, 9,
+ 5, -3, 3, -2,-11, 3, 9, 6, 9, 3, -1, 12,-41, 8, -6, 9 },
+ { 3, -7, 3, 2, 5, 5, 0, -1, 1, 3, -5, -2,-13, 7, -1, -2,
+ -2, -6, 4, -6, 0, 2, -2, 2, 4, 1, -4, 1,-47,-21, 7, -6 },
+ { 3, 16, -7, 13, -4, -2, 10, -3, -1, 18,-13, 7,-13, -4, 8, 4,
+ 8, 9, -5, 13, 8, -5, 3, -6, 7, 18, -8, 10,-25, -3,-12,-12 },
+ { 1, -1, -1, 0, 2, 5, -5, -3, 0, -5, -1, 0, -4, -8, -2, 3,
+ 2, -2,-17, -6, -4, 1, 33, -6,-20, -6, 8, 31,-26, -8, -1, -4 },
+ { 3, -3, -3, 5, -3, -2, 1, 7, 0, 3, 6, 3, 6, -2, 9, 15,
+ -10, -3,-15, -5, -3, -4, -6,-30, 17, -8, -2, 2,-20, 0, -8, -2 },
+ { -2, -1, -1, -1, 3, -5, -2, -3, 4, -2, 0, 5, 8, -3, 1, -4,
+ 1, 1, -3, 4, 4,-14, 3, 11, -5, 3, -3, 7, -3, 13, 23,-16 },
+ { 2, -6, 1, -3, 5, 0, -6,-11, -7, -4, -1, 2, -7, -1, -1, 7,
+ 1, -2, 6, 12, -6, 8,-13, 17, 25,-23,-19, -7,-12, 9, 16,-17 },
+ { 9, 4, 4, 4, -3, -1, 6, -2, -3, 0, 13, -4, -7, 14, 1, -7,
+ 0, -5, 3,-19, -3, 5, 3, 9, -1, 9,-13, 13,-17, 4, 21,-26 },
+ { 0, -5, 0, 0, -4, -5, 2, -6, -4, 5, -7, 10, 0, 2, 0, -2,
+ -2, 0, 4, -6, 7, -2, 6, 5, -5, 2,-12, 1,-29, 29, 27, 12 },
+ { 9,-10,-22, 6, -1, -1, 9,-14,-12, -2, 1, -1, 10,-11,-16, 0,
+ 3, 11, 13,-14, -9, -2, -1, 6, 4,-14, 0,-10, -2, 16, 17,-11 },
+ { 2, 0, -1, -2, 4, 3, -6, -2, 1, -1, 1, 3, -4, 1, 3, -4,
+ -1, -1, 4, -1, 1, 0, 1, 6, -5, -7, 2, 1,-47, -3, 50,-17 },
+ { 8, -4,-11, -7, 11, 11, 14, -7, 12, -7, 6, 2, 13, -6, -3, -2,
+ -14, 6, 6, 6, 0, 2, -1, 5,-20, 2, -1, 4, -5, 6, 21,-11 },
+ { -2, -9, 3, 0, -6, 7, 8, -8, 1, -3, 4, 1, 5, -2, -3, -7,
+ 4, 7,-12, -9, -2, 10, -6, 13, 6, 5, 20, 2,-15, 9, 28, -7 },
+ { 0, -5, -6, -6, -6, 1, -6, 6, -2, 4, 8, -3, 12, -1, -4, -2,
+ 6, 16,-14, 9,-14, -2, -8,-27, -3, 18, -1, -7, -3, 8, 23,-23 },
+ { 1, 4, -9, -1, -5, 10, -2, 1,-11, 1, -9, 4, 7, 14, -9, -2,
+ -3, 2, -5, -1, -6,-10, -7, 11, 20, 2, 3,-19, 3, 15, 30, -9 },
+ { 7, 2,-14, -4, 0, -2, 5, 2, 5, -2, 8, -3, -7, 6, 6,-11,
+ -14, 1, 10, -1, -7, -8, 1, 10, 3, -6,-15,-12,-17, 4, 30, -6 },
+ { 4, 2, 1, -2, 3, 0, 1, 0, 2, 0, 1, 6, -7, 0, 3, 4,
+ 4, -4, -2, -5, -2, 2, -1, -2, 0, -2,-11, -7, -3, 42, 24,-14 },
+ { 4, 1, 3, 2, 0, -2, -3, -2, 2, -1, 4, 11, -2, 2, 3, -4,
+ -5, 9, 2, -4, -9, 5, 8, -1, -7, 1, 24,-13,-28, 20, 15,-22 },
+ { -3, 7, 6, 3, -2, -5,-10, -2, -2, -1, -6, -6, -2,-14,-16, -6,
+ -5, 0, 18, 0, 9, 1, 7,-13, -5, -6, -9, 11,-15, 9, 22,-11 },
+ { 9, -2, 6, 5, 2, 9,-10, 1, 1, 5, -4, 12, 2, 2,-10, -7,
+ -4, -6, 7, 9, 6, 15, 6, 6,-10, 10, 5,-13, -5, 6, 24,-12 },
+ { 1, 3, -3, -3, 8, 1, -6, 2, -5, -3, 7, 2, 14, 6, 9, -6,
+ -5, -4, 27, 7, -3, 8, -6, 3, -8, 8, 22, -5, -6, -2, 22,-17 },
+ { -2, -2, 3, 10, 9, 9, 12,-15, -1,-11,-13, 3, -2, 1, -3,-11,
+ 7, 9, 16, -3,-10, -5, -5, 1, 8, -3, 9, 9, -5, 3, 31,-12 },
+ { 7, -5, 10, -4, -8, 2, 16, -2, 10, 10, -3, -2, 3, -8, -3, 3,
+ -13, -6, 15, 20, -9, -3,-12, 1, -2,-16, 8, 8, -1, 16, 22, -5 },
+ { 5, -3,-15, -2, 12, -8, 8, -5, 2, -8, 20,-18, 14, -4, 3, 3,
+ 7,-13,-16, 1,-10, 7, 16, 7, 4,-14, -4, -5, -9, 8, 23, -6 },
+ { 5, -4, -5, -4, 1, 8, 4, -7, -5, 8, 10, 6, -6,-10, -2, 6,
+ 9,-17,-14, 11, 12, -3,-13, -7, 2, 18, 3,-25,-16, 18, 22, -5 },
+ { 5, 6, -7,-20, -4, 2, 8, 4,-24, -4, 1, 4, -5, -2, 1,-10,
+ -2, 9, 3, -4, -3, -4, -4, -4, 10, 10, 3, 0, -6, 25, 21,-11 },
+ { 0, 7, -1, 14, -6, -4,-10, 5, 4, 4, 4, -5, 3, 4, -1, -7,
+ 8,-19, 0, 6, 2, 3,-18, -3, -6, 2, 8, 14,-26, 22, 27,-13 },
+ { -2, -6, 7, -5, 12, -7, 8, -1, 3, -2, 4, 1, 8, -2, 0, 14,
+ 6, -5, 6, -4, -7, 7,-21, 8, 1, 8, -9, -4, -3, 11, 25,-13 },
+ { 4, 4, -1, -6, 4, 9, -8, 1, -3,-10, -2, 0, 15, -9,-16, 11,
+ 1, 1, 6, 3, -9, -5, 16, 26, 1,-14, 1, -3,-14, 7, 15, -9 },
+ {-12, -2, -9,-13, 2, 6, 14, 0, 1, 0, -1,-13, 0, 10, -1, 6,
+ 9, -7, 8, 8, 19, 6, -1, 9, 10, -4, 1, -7,-22, -2, 29, -7 },
+ { 2, 4, 13,-12, -8, -4, -5, 13, 12, -5, -3, -3, -4, 1, -1, 10,
+ 15, -6, -1,-11,-30, 4, 15, -1, 9, -7, 0, -2, -7, 10, 25,-16 },
+ { 7,-15, -7, -7, -1, -5, -5,-11,-20, 10, 3,-10, -3, 5, 20, -4,
+ 0, -2, -2, 17, 2, 0, -3, 3, 6, 5, -1,-12, -3, 15, 22,-16 },
+ { 4, -1, 3, 4, -5, 0, -1, -5,-24,-29, 4, -9, 1, -3, 0, 0,
+ 0, -4, 7, -4, -4, -4, 3, 1, -6, 5, -3, -5,-10, 3, 25,-10 },
+ { -2, -1, -1, 4, 4, -1, 2, 0, -4, -4, 2, -1, -3, -1, -2, -2,
+ 1, -3, -5, -1, 2, -3, -4, -4, -3, 5, -9, 1,-11, 7, 46,-46 },
+ { 0, -9, 3, 4, 4, 3, -5, -6, 5, -4, 4, -2, 1, 7, -4,-10,
+ 13, 1, 3, -6, 4, -4, 7, 2,-19,-25, -3,-16,-12, 16, 20, -1 },
+ { 18, 6, 4,-12, 0,-14, 9, -6, -1, -4, -5, 2, 1, 12, 4, 2,
+ 7, 0, 2, 5,-11, -5, -2, 2, -4, 10, 0, -9, -7, 9, 25, -8 },
+ { 5, 0, -6, 5, 6, 3, 3,-10, -5, 1, -1, 4, 3,-11, -8, 5,
+ 4, -5, 5, -5, -7, -5, 11, 5, 20, -8,-16, 21, -4, 27, 23, -5 }
};
+/* FIR filter coefficients, they can be cut on half and maybe use float instead of double */
-/* FIR filter coefficients, they can be cut on half and maybe use float instead of double*/
-
-DECLARE_ALIGNED(16, static const float, fir_32bands_perfect)[] =
-{
-+1.135985195E-010,
-+7.018770981E-011,
--1.608403011E-008,
--5.083275667E-008,
--1.543309907E-007,
--3.961981463E-007,
--7.342250683E-007,
--3.970030775E-007,
--4.741137047E-007,
--6.022448247E-007,
--6.628192182E-007,
--6.982898526E-007,
--7.020648809E-007,
--6.767839409E-007,
--6.262345096E-007,
--5.564140224E-007,
-+7.003467317E-007,
-+8.419976893E-007,
-+9.742954035E-007,
-+1.085227950E-006,
-+1.162929266E-006,
-+1.194632091E-006,
-+1.179182050E-006,
-+1.033426656E-006,
-+9.451737242E-007,
-+1.975324267E-006,
-+1.190443072E-006,
-+5.234479659E-007,
-+2.014677420E-007,
-+7.834767501E-008,
--6.702406963E-010,
--1.613285505E-009,
--2.682709610E-009,
--3.399493131E-009,
-+1.314406006E-008,
-+7.506701927E-009,
-+2.788728892E-008,
-+1.444918922E-007,
-+3.132386439E-007,
-+1.399798180E-006,
-+2.032118118E-006,
-+2.715013807E-006,
-+3.453840463E-006,
-+4.195037945E-006,
-+4.896494374E-006,
-+5.516381407E-006,
-+6.015239251E-006,
-+6.361419310E-006,
-+8.006985809E-006,
-+8.087732567E-006,
-+7.941360309E-006,
-+7.568834008E-006,
-+6.986399967E-006,
-+6.225028756E-006,
-+5.315936960E-006,
-+4.429412002E-006,
-+3.332600045E-006,
-+8.427224429E-007,
-+4.341498823E-007,
-+9.458596395E-008,
-+2.975164826E-008,
-+6.402664354E-008,
--3.246264413E-008,
--3.809887872E-008,
-+8.434094667E-008,
-+6.437721822E-008,
-+1.189317118E-006,
-+2.497214155E-006,
-+3.617151151E-006,
-+3.157242645E-006,
-+2.319611212E-006,
-+7.869333785E-006,
-+9.826449968E-006,
-+1.177108606E-005,
-+1.379448349E-005,
-+1.571428584E-005,
-+1.743183020E-005,
-+1.884208177E-005,
-+1.987093310E-005,
-+2.042970118E-005,
--3.144468428E-005,
--3.334947178E-005,
--3.460439257E-005,
--3.515914432E-005,
--3.495384954E-005,
--3.397853652E-005,
--3.225446198E-005,
--2.978993689E-005,
--2.677291741E-005,
--1.806914770E-005,
--1.776598037E-005,
--1.661818715E-005,
--1.207003334E-005,
--6.993315310E-006,
--5.633860383E-007,
--9.984935332E-007,
--1.470520488E-006,
--1.853591357E-006,
-+7.198007665E-007,
-+3.086857760E-006,
-+6.084746474E-006,
-+9.561075785E-006,
-+1.309637537E-005,
-+2.263354872E-005,
-+2.847247197E-005,
-+3.415624451E-005,
-+3.946387005E-005,
-+4.425736552E-005,
-+4.839275425E-005,
-+5.176846025E-005,
-+5.429694284E-005,
-+5.595519906E-005,
-+4.916387297E-006,
-+9.299508747E-006,
-+1.356193479E-005,
-+1.751866148E-005,
-+2.093936746E-005,
-+2.362549276E-005,
-+2.537086584E-005,
-+2.618136386E-005,
-+2.554462844E-005,
-+3.018750249E-005,
-+2.570833203E-005,
-+1.985177369E-005,
-+1.191342653E-005,
-+2.525620175E-006,
--1.521241393E-005,
--1.617751332E-005,
-+1.992636317E-005,
-+1.774702469E-005,
-+4.624524081E-005,
-+5.610509834E-005,
-+6.568001118E-005,
-+7.513730816E-005,
-+8.413690375E-005,
-+8.757545584E-005,
-+9.517164290E-005,
-+1.020687996E-004,
-+1.084438481E-004,
-+1.140582463E-004,
-+1.187910311E-004,
-+1.224978914E-004,
-+1.250260248E-004,
-+1.262027217E-004,
-+1.226499153E-004,
-+1.213575742E-004,
-+1.180980107E-004,
-+1.126275165E-004,
-+1.047207043E-004,
-+9.417100227E-005,
-+8.078388782E-005,
-+6.447290798E-005,
-+4.491530854E-005,
-+2.470704203E-005,
--1.714242217E-006,
--3.193307566E-005,
--6.541742187E-005,
--1.024175072E-004,
--1.312203676E-004,
--1.774113771E-004,
--2.233728592E-004,
--2.682086197E-004,
--3.347633174E-004,
--3.906481725E-004,
--4.490280990E-004,
--5.099929986E-004,
--5.729619297E-004,
--6.358824321E-004,
--7.021900383E-004,
--7.698345580E-004,
--8.385353722E-004,
--9.078957955E-004,
--9.775133803E-004,
--1.046945457E-003,
--1.115717343E-003,
--1.183370827E-003,
--1.252829796E-003,
--1.316190348E-003,
--1.376571832E-003,
--1.433344092E-003,
--1.485876855E-003,
--1.533520175E-003,
--1.575609902E-003,
--1.611457788E-003,
--1.640390139E-003,
--1.661288203E-003,
--1.674512983E-003,
--1.678415807E-003,
--1.672798418E-003,
--1.656501088E-003,
--1.633993932E-003,
--1.593449386E-003,
-+1.542080659E-003,
-+1.479332102E-003,
-+1.395521569E-003,
-+1.303116791E-003,
-+1.196175464E-003,
-+1.073757303E-003,
-+9.358961834E-004,
-+7.817269652E-004,
-+6.114174030E-004,
-+4.244441516E-004,
-+2.206075296E-004,
--2.719412748E-007,
--2.382978710E-004,
--4.935106263E-004,
--7.658848190E-004,
--1.055365428E-003,
--1.361547387E-003,
--1.684492454E-003,
--2.023874084E-003,
--2.379294252E-003,
--2.750317100E-003,
--3.136433195E-003,
--3.537061159E-003,
--3.951539751E-003,
--4.379155114E-003,
--4.819062538E-003,
--5.270531867E-003,
--5.732392892E-003,
--6.203945260E-003,
--6.683901884E-003,
--7.170005701E-003,
--7.664063945E-003,
--8.162760176E-003,
--8.665001951E-003,
--9.170533158E-003,
--9.676489048E-003,
--1.018219907E-002,
--1.068630442E-002,
--1.118756086E-002,
--1.168460958E-002,
--1.217562053E-002,
--1.265939046E-002,
--1.313448418E-002,
--1.359948888E-002,
--1.405300573E-002,
--1.449365262E-002,
--1.492007636E-002,
--1.533095632E-002,
--1.572482102E-002,
--1.610082202E-002,
--1.645756140E-002,
--1.679391414E-002,
--1.710879989E-002,
--1.740120351E-002,
--1.767017506E-002,
--1.791484281E-002,
--1.813439466E-002,
--1.832821220E-002,
--1.849545911E-002,
--1.863567345E-002,
--1.874836907E-002,
--1.883326657E-002,
--1.889026538E-002,
--1.891860925E-002,
-+1.891860925E-002,
-+1.889026538E-002,
-+1.883326657E-002,
-+1.874836907E-002,
-+1.863567345E-002,
-+1.849545911E-002,
-+1.832821220E-002,
-+1.813439466E-002,
-+1.791484281E-002,
-+1.767017506E-002,
-+1.740120351E-002,
-+1.710879989E-002,
-+1.679391414E-002,
-+1.645756140E-002,
-+1.610082202E-002,
-+1.572482102E-002,
-+1.533095632E-002,
-+1.492007636E-002,
-+1.449365262E-002,
-+1.405300573E-002,
-+1.359948888E-002,
-+1.313448418E-002,
-+1.265939046E-002,
-+1.217562053E-002,
-+1.168460958E-002,
-+1.118756086E-002,
-+1.068630442E-002,
-+1.018219907E-002,
-+9.676489048E-003,
-+9.170533158E-003,
-+8.665001951E-003,
-+8.162760176E-003,
-+7.664063945E-003,
-+7.170005701E-003,
-+6.683901884E-003,
-+6.203945260E-003,
-+5.732392892E-003,
-+5.270531867E-003,
-+4.819062538E-003,
-+4.379155114E-003,
-+3.951539751E-003,
-+3.537061159E-003,
-+3.136433195E-003,
-+2.750317100E-003,
-+2.379294252E-003,
-+2.023874084E-003,
-+1.684492454E-003,
-+1.361547387E-003,
-+1.055365428E-003,
-+7.658848190E-004,
-+4.935106263E-004,
-+2.382978710E-004,
-+2.719412748E-007,
--2.206075296E-004,
--4.244441516E-004,
--6.114174030E-004,
--7.817269652E-004,
--9.358961834E-004,
--1.073757303E-003,
--1.196175464E-003,
--1.303116791E-003,
--1.395521569E-003,
--1.479332102E-003,
--1.542080659E-003,
-+1.593449386E-003,
-+1.633993932E-003,
-+1.656501088E-003,
-+1.672798418E-003,
-+1.678415807E-003,
-+1.674512983E-003,
-+1.661288203E-003,
-+1.640390139E-003,
-+1.611457788E-003,
-+1.575609902E-003,
-+1.533520175E-003,
-+1.485876855E-003,
-+1.433344092E-003,
-+1.376571832E-003,
-+1.316190348E-003,
-+1.252829796E-003,
-+1.183370827E-003,
-+1.115717343E-003,
-+1.046945457E-003,
-+9.775133803E-004,
-+9.078957955E-004,
-+8.385353722E-004,
-+7.698345580E-004,
-+7.021900383E-004,
-+6.358824321E-004,
-+5.729619297E-004,
-+5.099929986E-004,
-+4.490280990E-004,
-+3.906481725E-004,
-+3.347633174E-004,
-+2.682086197E-004,
-+2.233728592E-004,
-+1.774113771E-004,
-+1.312203676E-004,
-+1.024175072E-004,
-+6.541742187E-005,
-+3.193307566E-005,
-+1.714242217E-006,
--2.470704203E-005,
--4.491530854E-005,
--6.447290798E-005,
--8.078388782E-005,
--9.417100227E-005,
--1.047207043E-004,
--1.126275165E-004,
--1.180980107E-004,
--1.213575742E-004,
--1.226499153E-004,
--1.262027217E-004,
--1.250260248E-004,
--1.224978914E-004,
--1.187910311E-004,
--1.140582463E-004,
--1.084438481E-004,
--1.020687996E-004,
--9.517164290E-005,
--8.757545584E-005,
--8.413690375E-005,
--7.513730816E-005,
--6.568001118E-005,
--5.610509834E-005,
--4.624524081E-005,
--1.774702469E-005,
--1.992636317E-005,
-+1.617751332E-005,
-+1.521241393E-005,
--2.525620175E-006,
--1.191342653E-005,
--1.985177369E-005,
--2.570833203E-005,
--3.018750249E-005,
--2.554462844E-005,
--2.618136386E-005,
--2.537086584E-005,
--2.362549276E-005,
--2.093936746E-005,
--1.751866148E-005,
--1.356193479E-005,
--9.299508747E-006,
--4.916387297E-006,
--5.595519906E-005,
--5.429694284E-005,
--5.176846025E-005,
--4.839275425E-005,
--4.425736552E-005,
--3.946387005E-005,
--3.415624451E-005,
--2.847247197E-005,
--2.263354872E-005,
--1.309637537E-005,
--9.561075785E-006,
--6.084746474E-006,
--3.086857760E-006,
--7.198007665E-007,
-+1.853591357E-006,
-+1.470520488E-006,
-+9.984935332E-007,
-+5.633860383E-007,
-+6.993315310E-006,
-+1.207003334E-005,
-+1.661818715E-005,
-+1.776598037E-005,
-+1.806914770E-005,
-+2.677291741E-005,
-+2.978993689E-005,
-+3.225446198E-005,
-+3.397853652E-005,
-+3.495384954E-005,
-+3.515914432E-005,
-+3.460439257E-005,
-+3.334947178E-005,
-+3.144468428E-005,
--2.042970118E-005,
--1.987093310E-005,
--1.884208177E-005,
--1.743183020E-005,
--1.571428584E-005,
--1.379448349E-005,
--1.177108606E-005,
--9.826449968E-006,
--7.869333785E-006,
--2.319611212E-006,
--3.157242645E-006,
--3.617151151E-006,
--2.497214155E-006,
--1.189317118E-006,
--6.437721822E-008,
--8.434094667E-008,
-+3.809887872E-008,
-+3.246264413E-008,
--6.402664354E-008,
--2.975164826E-008,
--9.458596395E-008,
--4.341498823E-007,
--8.427224429E-007,
--3.332600045E-006,
--4.429412002E-006,
--5.315936960E-006,
--6.225028756E-006,
--6.986399967E-006,
--7.568834008E-006,
--7.941360309E-006,
--8.087732567E-006,
--8.006985809E-006,
--6.361419310E-006,
--6.015239251E-006,
--5.516381407E-006,
--4.896494374E-006,
--4.195037945E-006,
--3.453840463E-006,
--2.715013807E-006,
--2.032118118E-006,
--1.399798180E-006,
--3.132386439E-007,
--1.444918922E-007,
--2.788728892E-008,
--7.506701927E-009,
--1.314406006E-008,
-+3.399493131E-009,
-+2.682709610E-009,
-+1.613285505E-009,
-+6.702406963E-010,
--7.834767501E-008,
--2.014677420E-007,
--5.234479659E-007,
--1.190443072E-006,
--1.975324267E-006,
--9.451737242E-007,
--1.033426656E-006,
--1.179182050E-006,
--1.194632091E-006,
--1.162929266E-006,
--1.085227950E-006,
--9.742954035E-007,
--8.419976893E-007,
--7.003467317E-007,
-+5.564140224E-007,
-+6.262345096E-007,
-+6.767839409E-007,
-+7.020648809E-007,
-+6.982898526E-007,
-+6.628192182E-007,
-+6.022448247E-007,
-+4.741137047E-007,
-+3.970030775E-007,
-+7.342250683E-007,
-+3.961981463E-007,
-+1.543309907E-007,
-+5.083275667E-008,
-+1.608403011E-008,
--7.018770981E-011,
--1.135985195E-010
+DECLARE_ALIGNED(16, static const float, fir_32bands_perfect)[] = {
+ +1.135985195E-010,
+ +7.018770981E-011,
+ -1.608403011E-008,
+ -5.083275667E-008,
+ -1.543309907E-007,
+ -3.961981463E-007,
+ -7.342250683E-007,
+ -3.970030775E-007,
+ -4.741137047E-007,
+ -6.022448247E-007,
+ -6.628192182E-007,
+ -6.982898526E-007,
+ -7.020648809E-007,
+ -6.767839409E-007,
+ -6.262345096E-007,
+ -5.564140224E-007,
+ +7.003467317E-007,
+ +8.419976893E-007,
+ +9.742954035E-007,
+ +1.085227950E-006,
+ +1.162929266E-006,
+ +1.194632091E-006,
+ +1.179182050E-006,
+ +1.033426656E-006,
+ +9.451737242E-007,
+ +1.975324267E-006,
+ +1.190443072E-006,
+ +5.234479659E-007,
+ +2.014677420E-007,
+ +7.834767501E-008,
+ -6.702406963E-010,
+ -1.613285505E-009,
+ -2.682709610E-009,
+ -3.399493131E-009,
+ +1.314406006E-008,
+ +7.506701927E-009,
+ +2.788728892E-008,
+ +1.444918922E-007,
+ +3.132386439E-007,
+ +1.399798180E-006,
+ +2.032118118E-006,
+ +2.715013807E-006,
+ +3.453840463E-006,
+ +4.195037945E-006,
+ +4.896494374E-006,
+ +5.516381407E-006,
+ +6.015239251E-006,
+ +6.361419310E-006,
+ +8.006985809E-006,
+ +8.087732567E-006,
+ +7.941360309E-006,
+ +7.568834008E-006,
+ +6.986399967E-006,
+ +6.225028756E-006,
+ +5.315936960E-006,
+ +4.429412002E-006,
+ +3.332600045E-006,
+ +8.427224429E-007,
+ +4.341498823E-007,
+ +9.458596395E-008,
+ +2.975164826E-008,
+ +6.402664354E-008,
+ -3.246264413E-008,
+ -3.809887872E-008,
+ +8.434094667E-008,
+ +6.437721822E-008,
+ +1.189317118E-006,
+ +2.497214155E-006,
+ +3.617151151E-006,
+ +3.157242645E-006,
+ +2.319611212E-006,
+ +7.869333785E-006,
+ +9.826449968E-006,
+ +1.177108606E-005,
+ +1.379448349E-005,
+ +1.571428584E-005,
+ +1.743183020E-005,
+ +1.884208177E-005,
+ +1.987093310E-005,
+ +2.042970118E-005,
+ -3.144468428E-005,
+ -3.334947178E-005,
+ -3.460439257E-005,
+ -3.515914432E-005,
+ -3.495384954E-005,
+ -3.397853652E-005,
+ -3.225446198E-005,
+ -2.978993689E-005,
+ -2.677291741E-005,
+ -1.806914770E-005,
+ -1.776598037E-005,
+ -1.661818715E-005,
+ -1.207003334E-005,
+ -6.993315310E-006,
+ -5.633860383E-007,
+ -9.984935332E-007,
+ -1.470520488E-006,
+ -1.853591357E-006,
+ +7.198007665E-007,
+ +3.086857760E-006,
+ +6.084746474E-006,
+ +9.561075785E-006,
+ +1.309637537E-005,
+ +2.263354872E-005,
+ +2.847247197E-005,
+ +3.415624451E-005,
+ +3.946387005E-005,
+ +4.425736552E-005,
+ +4.839275425E-005,
+ +5.176846025E-005,
+ +5.429694284E-005,
+ +5.595519906E-005,
+ +4.916387297E-006,
+ +9.299508747E-006,
+ +1.356193479E-005,
+ +1.751866148E-005,
+ +2.093936746E-005,
+ +2.362549276E-005,
+ +2.537086584E-005,
+ +2.618136386E-005,
+ +2.554462844E-005,
+ +3.018750249E-005,
+ +2.570833203E-005,
+ +1.985177369E-005,
+ +1.191342653E-005,
+ +2.525620175E-006,
+ -1.521241393E-005,
+ -1.617751332E-005,
+ +1.992636317E-005,
+ +1.774702469E-005,
+ +4.624524081E-005,
+ +5.610509834E-005,
+ +6.568001118E-005,
+ +7.513730816E-005,
+ +8.413690375E-005,
+ +8.757545584E-005,
+ +9.517164290E-005,
+ +1.020687996E-004,
+ +1.084438481E-004,
+ +1.140582463E-004,
+ +1.187910311E-004,
+ +1.224978914E-004,
+ +1.250260248E-004,
+ +1.262027217E-004,
+ +1.226499153E-004,
+ +1.213575742E-004,
+ +1.180980107E-004,
+ +1.126275165E-004,
+ +1.047207043E-004,
+ +9.417100227E-005,
+ +8.078388782E-005,
+ +6.447290798E-005,
+ +4.491530854E-005,
+ +2.470704203E-005,
+ -1.714242217E-006,
+ -3.193307566E-005,
+ -6.541742187E-005,
+ -1.024175072E-004,
+ -1.312203676E-004,
+ -1.774113771E-004,
+ -2.233728592E-004,
+ -2.682086197E-004,
+ -3.347633174E-004,
+ -3.906481725E-004,
+ -4.490280990E-004,
+ -5.099929986E-004,
+ -5.729619297E-004,
+ -6.358824321E-004,
+ -7.021900383E-004,
+ -7.698345580E-004,
+ -8.385353722E-004,
+ -9.078957955E-004,
+ -9.775133803E-004,
+ -1.046945457E-003,
+ -1.115717343E-003,
+ -1.183370827E-003,
+ -1.252829796E-003,
+ -1.316190348E-003,
+ -1.376571832E-003,
+ -1.433344092E-003,
+ -1.485876855E-003,
+ -1.533520175E-003,
+ -1.575609902E-003,
+ -1.611457788E-003,
+ -1.640390139E-003,
+ -1.661288203E-003,
+ -1.674512983E-003,
+ -1.678415807E-003,
+ -1.672798418E-003,
+ -1.656501088E-003,
+ -1.633993932E-003,
+ -1.593449386E-003,
+ +1.542080659E-003,
+ +1.479332102E-003,
+ +1.395521569E-003,
+ +1.303116791E-003,
+ +1.196175464E-003,
+ +1.073757303E-003,
+ +9.358961834E-004,
+ +7.817269652E-004,
+ +6.114174030E-004,
+ +4.244441516E-004,
+ +2.206075296E-004,
+ -2.719412748E-007,
+ -2.382978710E-004,
+ -4.935106263E-004,
+ -7.658848190E-004,
+ -1.055365428E-003,
+ -1.361547387E-003,
+ -1.684492454E-003,
+ -2.023874084E-003,
+ -2.379294252E-003,
+ -2.750317100E-003,
+ -3.136433195E-003,
+ -3.537061159E-003,
+ -3.951539751E-003,
+ -4.379155114E-003,
+ -4.819062538E-003,
+ -5.270531867E-003,
+ -5.732392892E-003,
+ -6.203945260E-003,
+ -6.683901884E-003,
+ -7.170005701E-003,
+ -7.664063945E-003,
+ -8.162760176E-003,
+ -8.665001951E-003,
+ -9.170533158E-003,
+ -9.676489048E-003,
+ -1.018219907E-002,
+ -1.068630442E-002,
+ -1.118756086E-002,
+ -1.168460958E-002,
+ -1.217562053E-002,
+ -1.265939046E-002,
+ -1.313448418E-002,
+ -1.359948888E-002,
+ -1.405300573E-002,
+ -1.449365262E-002,
+ -1.492007636E-002,
+ -1.533095632E-002,
+ -1.572482102E-002,
+ -1.610082202E-002,
+ -1.645756140E-002,
+ -1.679391414E-002,
+ -1.710879989E-002,
+ -1.740120351E-002,
+ -1.767017506E-002,
+ -1.791484281E-002,
+ -1.813439466E-002,
+ -1.832821220E-002,
+ -1.849545911E-002,
+ -1.863567345E-002,
+ -1.874836907E-002,
+ -1.883326657E-002,
+ -1.889026538E-002,
+ -1.891860925E-002,
+ +1.891860925E-002,
+ +1.889026538E-002,
+ +1.883326657E-002,
+ +1.874836907E-002,
+ +1.863567345E-002,
+ +1.849545911E-002,
+ +1.832821220E-002,
+ +1.813439466E-002,
+ +1.791484281E-002,
+ +1.767017506E-002,
+ +1.740120351E-002,
+ +1.710879989E-002,
+ +1.679391414E-002,
+ +1.645756140E-002,
+ +1.610082202E-002,
+ +1.572482102E-002,
+ +1.533095632E-002,
+ +1.492007636E-002,
+ +1.449365262E-002,
+ +1.405300573E-002,
+ +1.359948888E-002,
+ +1.313448418E-002,
+ +1.265939046E-002,
+ +1.217562053E-002,
+ +1.168460958E-002,
+ +1.118756086E-002,
+ +1.068630442E-002,
+ +1.018219907E-002,
+ +9.676489048E-003,
+ +9.170533158E-003,
+ +8.665001951E-003,
+ +8.162760176E-003,
+ +7.664063945E-003,
+ +7.170005701E-003,
+ +6.683901884E-003,
+ +6.203945260E-003,
+ +5.732392892E-003,
+ +5.270531867E-003,
+ +4.819062538E-003,
+ +4.379155114E-003,
+ +3.951539751E-003,
+ +3.537061159E-003,
+ +3.136433195E-003,
+ +2.750317100E-003,
+ +2.379294252E-003,
+ +2.023874084E-003,
+ +1.684492454E-003,
+ +1.361547387E-003,
+ +1.055365428E-003,
+ +7.658848190E-004,
+ +4.935106263E-004,
+ +2.382978710E-004,
+ +2.719412748E-007,
+ -2.206075296E-004,
+ -4.244441516E-004,
+ -6.114174030E-004,
+ -7.817269652E-004,
+ -9.358961834E-004,
+ -1.073757303E-003,
+ -1.196175464E-003,
+ -1.303116791E-003,
+ -1.395521569E-003,
+ -1.479332102E-003,
+ -1.542080659E-003,
+ +1.593449386E-003,
+ +1.633993932E-003,
+ +1.656501088E-003,
+ +1.672798418E-003,
+ +1.678415807E-003,
+ +1.674512983E-003,
+ +1.661288203E-003,
+ +1.640390139E-003,
+ +1.611457788E-003,
+ +1.575609902E-003,
+ +1.533520175E-003,
+ +1.485876855E-003,
+ +1.433344092E-003,
+ +1.376571832E-003,
+ +1.316190348E-003,
+ +1.252829796E-003,
+ +1.183370827E-003,
+ +1.115717343E-003,
+ +1.046945457E-003,
+ +9.775133803E-004,
+ +9.078957955E-004,
+ +8.385353722E-004,
+ +7.698345580E-004,
+ +7.021900383E-004,
+ +6.358824321E-004,
+ +5.729619297E-004,
+ +5.099929986E-004,
+ +4.490280990E-004,
+ +3.906481725E-004,
+ +3.347633174E-004,
+ +2.682086197E-004,
+ +2.233728592E-004,
+ +1.774113771E-004,
+ +1.312203676E-004,
+ +1.024175072E-004,
+ +6.541742187E-005,
+ +3.193307566E-005,
+ +1.714242217E-006,
+ -2.470704203E-005,
+ -4.491530854E-005,
+ -6.447290798E-005,
+ -8.078388782E-005,
+ -9.417100227E-005,
+ -1.047207043E-004,
+ -1.126275165E-004,
+ -1.180980107E-004,
+ -1.213575742E-004,
+ -1.226499153E-004,
+ -1.262027217E-004,
+ -1.250260248E-004,
+ -1.224978914E-004,
+ -1.187910311E-004,
+ -1.140582463E-004,
+ -1.084438481E-004,
+ -1.020687996E-004,
+ -9.517164290E-005,
+ -8.757545584E-005,
+ -8.413690375E-005,
+ -7.513730816E-005,
+ -6.568001118E-005,
+ -5.610509834E-005,
+ -4.624524081E-005,
+ -1.774702469E-005,
+ -1.992636317E-005,
+ +1.617751332E-005,
+ +1.521241393E-005,
+ -2.525620175E-006,
+ -1.191342653E-005,
+ -1.985177369E-005,
+ -2.570833203E-005,
+ -3.018750249E-005,
+ -2.554462844E-005,
+ -2.618136386E-005,
+ -2.537086584E-005,
+ -2.362549276E-005,
+ -2.093936746E-005,
+ -1.751866148E-005,
+ -1.356193479E-005,
+ -9.299508747E-006,
+ -4.916387297E-006,
+ -5.595519906E-005,
+ -5.429694284E-005,
+ -5.176846025E-005,
+ -4.839275425E-005,
+ -4.425736552E-005,
+ -3.946387005E-005,
+ -3.415624451E-005,
+ -2.847247197E-005,
+ -2.263354872E-005,
+ -1.309637537E-005,
+ -9.561075785E-006,
+ -6.084746474E-006,
+ -3.086857760E-006,
+ -7.198007665E-007,
+ +1.853591357E-006,
+ +1.470520488E-006,
+ +9.984935332E-007,
+ +5.633860383E-007,
+ +6.993315310E-006,
+ +1.207003334E-005,
+ +1.661818715E-005,
+ +1.776598037E-005,
+ +1.806914770E-005,
+ +2.677291741E-005,
+ +2.978993689E-005,
+ +3.225446198E-005,
+ +3.397853652E-005,
+ +3.495384954E-005,
+ +3.515914432E-005,
+ +3.460439257E-005,
+ +3.334947178E-005,
+ +3.144468428E-005,
+ -2.042970118E-005,
+ -1.987093310E-005,
+ -1.884208177E-005,
+ -1.743183020E-005,
+ -1.571428584E-005,
+ -1.379448349E-005,
+ -1.177108606E-005,
+ -9.826449968E-006,
+ -7.869333785E-006,
+ -2.319611212E-006,
+ -3.157242645E-006,
+ -3.617151151E-006,
+ -2.497214155E-006,
+ -1.189317118E-006,
+ -6.437721822E-008,
+ -8.434094667E-008,
+ +3.809887872E-008,
+ +3.246264413E-008,
+ -6.402664354E-008,
+ -2.975164826E-008,
+ -9.458596395E-008,
+ -4.341498823E-007,
+ -8.427224429E-007,
+ -3.332600045E-006,
+ -4.429412002E-006,
+ -5.315936960E-006,
+ -6.225028756E-006,
+ -6.986399967E-006,
+ -7.568834008E-006,
+ -7.941360309E-006,
+ -8.087732567E-006,
+ -8.006985809E-006,
+ -6.361419310E-006,
+ -6.015239251E-006,
+ -5.516381407E-006,
+ -4.896494374E-006,
+ -4.195037945E-006,
+ -3.453840463E-006,
+ -2.715013807E-006,
+ -2.032118118E-006,
+ -1.399798180E-006,
+ -3.132386439E-007,
+ -1.444918922E-007,
+ -2.788728892E-008,
+ -7.506701927E-009,
+ -1.314406006E-008,
+ +3.399493131E-009,
+ +2.682709610E-009,
+ +1.613285505E-009,
+ +6.702406963E-010,
+ -7.834767501E-008,
+ -2.014677420E-007,
+ -5.234479659E-007,
+ -1.190443072E-006,
+ -1.975324267E-006,
+ -9.451737242E-007,
+ -1.033426656E-006,
+ -1.179182050E-006,
+ -1.194632091E-006,
+ -1.162929266E-006,
+ -1.085227950E-006,
+ -9.742954035E-007,
+ -8.419976893E-007,
+ -7.003467317E-007,
+ +5.564140224E-007,
+ +6.262345096E-007,
+ +6.767839409E-007,
+ +7.020648809E-007,
+ +6.982898526E-007,
+ +6.628192182E-007,
+ +6.022448247E-007,
+ +4.741137047E-007,
+ +3.970030775E-007,
+ +7.342250683E-007,
+ +3.961981463E-007,
+ +1.543309907E-007,
+ +5.083275667E-008,
+ +1.608403011E-008,
+ -7.018770981E-011,
+ -1.135985195E-010
};
-DECLARE_ALIGNED(16, static const float, fir_32bands_nonperfect)[] =
-{
--1.390191784E-007,
--1.693738625E-007,
--2.030677564E-007,
--2.404238444E-007,
--2.818143514E-007,
--3.276689142E-007,
--3.784752209E-007,
--4.347855338E-007,
--4.972276315E-007,
--5.665120852E-007,
--6.434325428E-007,
--7.288739425E-007,
--8.238164355E-007,
--9.293416952E-007,
--1.046637067E-006,
--1.176999604E-006,
--1.321840614E-006,
--1.482681114E-006,
--1.661159786E-006,
--1.859034001E-006,
--2.078171747E-006,
--2.320550948E-006,
--2.588257530E-006,
--2.883470643E-006,
--3.208459020E-006,
--3.565570978E-006,
--3.957220997E-006,
--4.385879038E-006,
--4.854050530E-006,
--5.364252502E-006,
--5.918994248E-006,
--6.520755960E-006,
--7.171964626E-006,
--7.874960829E-006,
--8.631964192E-006,
--9.445050637E-006,
--1.031611009E-005,
--1.124680875E-005,
--1.223855270E-005,
--1.329243969E-005,
--1.440921824E-005,
--1.558924305E-005,
--1.683242772E-005,
--1.813820381E-005,
--1.950545993E-005,
--2.093250441E-005,
--2.241701623E-005,
--2.395598858E-005,
--2.554569073E-005,
--2.718161704E-005,
--2.885844333E-005,
--3.056998685E-005,
--3.230916263E-005,
--3.406793985E-005,
--3.583733633E-005,
--3.760734762E-005,
--3.936696885E-005,
--4.110412556E-005,
--4.280570283E-005,
--4.445751256E-005,
--4.604430433E-005,
--4.754976908E-005,
--4.895655002E-005,
--5.024627535E-005,
-+5.139957648E-005,
-+5.239612074E-005,
-+5.321469871E-005,
-+5.383323878E-005,
-+5.422891263E-005,
-+5.437819709E-005,
-+5.425697600E-005,
-+5.384063843E-005,
-+5.310418419E-005,
-+5.202236207E-005,
-+5.056979353E-005,
-+4.872112549E-005,
-+4.645117951E-005,
-+4.373511547E-005,
-+4.054862075E-005,
-+3.686808850E-005,
-+3.267079956E-005,
-+2.793515523E-005,
-+2.264085742E-005,
-+1.676913780E-005,
-+1.030297699E-005,
-+3.227306706E-006,
--4.470633485E-006,
--1.280130618E-005,
--2.177240640E-005,
--3.138873581E-005,
--4.165195787E-005,
--5.256036457E-005,
--6.410864444E-005,
--7.628766616E-005,
--8.908427117E-005,
--1.024810626E-004,
--1.164562127E-004,
--1.309833024E-004,
--1.460311323E-004,
--1.615635992E-004,
--1.775395358E-004,
--1.939126523E-004,
--2.106313768E-004,
--2.276388550E-004,
--2.448728774E-004,
--2.622658503E-004,
--2.797449124E-004,
--2.972317743E-004,
--3.146430245E-004,
--3.318900708E-004,
--3.488793736E-004,
--3.655125911E-004,
--3.816867538E-004,
--3.972945851E-004,
--4.122247046E-004,
--4.263620067E-004,
--4.395879805E-004,
--4.517810594E-004,
--4.628172028E-004,
--4.725702747E-004,
--4.809123348E-004,
--4.877146275E-004,
--4.928477574E-004,
--4.961824161E-004,
--4.975944757E-004,
--4.969481961E-004,
--4.941228544E-004,
--4.889960401E-004,
-+4.814492422E-004,
-+4.713678791E-004,
-+4.586426076E-004,
-+4.431701091E-004,
-+4.248536134E-004,
-+4.036037717E-004,
-+3.793396754E-004,
-+3.519894381E-004,
-+3.214911267E-004,
-+2.877934603E-004,
-+2.508567995E-004,
-+2.106537577E-004,
-+1.671699720E-004,
-+1.204049113E-004,
-+7.037253090E-005,
-+1.710198012E-005,
--3.936182839E-005,
--9.895755647E-005,
--1.616069785E-004,
--2.272142592E-004,
--2.956659591E-004,
--3.668301215E-004,
--4.405563814E-004,
--5.166754709E-004,
--5.949990009E-004,
--6.753197522E-004,
--7.574109477E-004,
--8.410271257E-004,
--9.259034996E-004,
--1.011756598E-003,
--1.098284614E-003,
--1.185167348E-003,
--1.272067428E-003,
--1.358630019E-003,
--1.444484224E-003,
--1.529243193E-003,
--1.612505526E-003,
--1.693855622E-003,
--1.772865304E-003,
--1.849094522E-003,
--1.922092517E-003,
--1.991399564E-003,
--2.056547208E-003,
--2.117061289E-003,
--2.172462177E-003,
--2.222266514E-003,
--2.265989315E-003,
--2.303145360E-003,
--2.333251061E-003,
--2.355825622E-003,
--2.370394068E-003,
--2.376487479E-003,
--2.373647178E-003,
--2.361423569E-003,
--2.339380793E-003,
--2.307097195E-003,
--2.264167881E-003,
--2.210205887E-003,
--2.144844970E-003,
--2.067740774E-003,
--1.978572691E-003,
--1.877046190E-003,
--1.762894331E-003,
--1.635878929E-003,
-+1.495792647E-003,
-+1.342460280E-003,
-+1.175740734E-003,
-+9.955273708E-004,
-+8.017504588E-004,
-+5.943773431E-004,
-+3.734139318E-004,
-+1.389056415E-004,
--1.090620208E-004,
--3.703625989E-004,
--6.448282511E-004,
--9.322494152E-004,
--1.232374110E-003,
--1.544908970E-003,
--1.869517611E-003,
--2.205822384E-003,
--2.553403843E-003,
--2.911801683E-003,
--3.280514618E-003,
--3.659002949E-003,
--4.046686925E-003,
--4.442950245E-003,
--4.847140983E-003,
--5.258570891E-003,
--5.676518660E-003,
--6.100233644E-003,
--6.528933067E-003,
--6.961807609E-003,
--7.398022339E-003,
--7.836719044E-003,
--8.277016692E-003,
--8.718019351E-003,
--9.158811532E-003,
--9.598465636E-003,
--1.003604382E-002,
--1.047059800E-002,
--1.090117730E-002,
--1.132682897E-002,
--1.174659748E-002,
--1.215953380E-002,
--1.256469358E-002,
--1.296114177E-002,
--1.334795821E-002,
--1.372423489E-002,
--1.408908330E-002,
--1.444163360E-002,
--1.478104480E-002,
--1.510649733E-002,
--1.541720331E-002,
--1.571240649E-002,
--1.599138230E-002,
--1.625344716E-002,
--1.649795473E-002,
--1.672429405E-002,
--1.693190821E-002,
--1.712027565E-002,
--1.728892699E-002,
--1.743743755E-002,
--1.756543480E-002,
--1.767260395E-002,
--1.775865816E-002,
--1.782339066E-002,
--1.786663756E-002,
--1.788828894E-002,
-+1.788828894E-002,
-+1.786663756E-002,
-+1.782339066E-002,
-+1.775865816E-002,
-+1.767260395E-002,
-+1.756543480E-002,
-+1.743743755E-002,
-+1.728892699E-002,
-+1.712027565E-002,
-+1.693190821E-002,
-+1.672429405E-002,
-+1.649795473E-002,
-+1.625344716E-002,
-+1.599138230E-002,
-+1.571240649E-002,
-+1.541720331E-002,
-+1.510649733E-002,
-+1.478104480E-002,
-+1.444163360E-002,
-+1.408908330E-002,
-+1.372423489E-002,
-+1.334795821E-002,
-+1.296114177E-002,
-+1.256469358E-002,
-+1.215953380E-002,
-+1.174659748E-002,
-+1.132682897E-002,
-+1.090117730E-002,
-+1.047059800E-002,
-+1.003604382E-002,
-+9.598465636E-003,
-+9.158811532E-003,
-+8.718019351E-003,
-+8.277016692E-003,
-+7.836719044E-003,
-+7.398022339E-003,
-+6.961807609E-003,
-+6.528933067E-003,
-+6.100233644E-003,
-+5.676518660E-003,
-+5.258570891E-003,
-+4.847140983E-003,
-+4.442950245E-003,
-+4.046686925E-003,
-+3.659002949E-003,
-+3.280514618E-003,
-+2.911801683E-003,
-+2.553403843E-003,
-+2.205822384E-003,
-+1.869517611E-003,
-+1.544908970E-003,
-+1.232374110E-003,
-+9.322494152E-004,
-+6.448282511E-004,
-+3.703625989E-004,
-+1.090620208E-004,
--1.389056415E-004,
--3.734139318E-004,
--5.943773431E-004,
--8.017504588E-004,
--9.955273708E-004,
--1.175740734E-003,
--1.342460280E-003,
--1.495792647E-003,
-+1.635878929E-003,
-+1.762894331E-003,
-+1.877046190E-003,
-+1.978572691E-003,
-+2.067740774E-003,
-+2.144844970E-003,
-+2.210205887E-003,
-+2.264167881E-003,
-+2.307097195E-003,
-+2.339380793E-003,
-+2.361423569E-003,
-+2.373647178E-003,
-+2.376487479E-003,
-+2.370394068E-003,
-+2.355825622E-003,
-+2.333251061E-003,
-+2.303145360E-003,
-+2.265989315E-003,
-+2.222266514E-003,
-+2.172462177E-003,
-+2.117061289E-003,
-+2.056547208E-003,
-+1.991399564E-003,
-+1.922092517E-003,
-+1.849094522E-003,
-+1.772865304E-003,
-+1.693855622E-003,
-+1.612505526E-003,
-+1.529243193E-003,
-+1.444484224E-003,
-+1.358630019E-003,
-+1.272067428E-003,
-+1.185167348E-003,
-+1.098284614E-003,
-+1.011756598E-003,
-+9.259034996E-004,
-+8.410271257E-004,
-+7.574109477E-004,
-+6.753197522E-004,
-+5.949990009E-004,
-+5.166754709E-004,
-+4.405563814E-004,
-+3.668301215E-004,
-+2.956659591E-004,
-+2.272142592E-004,
-+1.616069785E-004,
-+9.895755647E-005,
-+3.936182839E-005,
--1.710198012E-005,
--7.037253090E-005,
--1.204049113E-004,
--1.671699720E-004,
--2.106537577E-004,
--2.508567995E-004,
--2.877934603E-004,
--3.214911267E-004,
--3.519894381E-004,
--3.793396754E-004,
--4.036037717E-004,
--4.248536134E-004,
--4.431701091E-004,
--4.586426076E-004,
--4.713678791E-004,
--4.814492422E-004,
-+4.889960401E-004,
-+4.941228544E-004,
-+4.969481961E-004,
-+4.975944757E-004,
-+4.961824161E-004,
-+4.928477574E-004,
-+4.877146275E-004,
-+4.809123348E-004,
-+4.725702747E-004,
-+4.628172028E-004,
-+4.517810594E-004,
-+4.395879805E-004,
-+4.263620067E-004,
-+4.122247046E-004,
-+3.972945851E-004,
-+3.816867538E-004,
-+3.655125911E-004,
-+3.488793736E-004,
-+3.318900708E-004,
-+3.146430245E-004,
-+2.972317743E-004,
-+2.797449124E-004,
-+2.622658503E-004,
-+2.448728774E-004,
-+2.276388550E-004,
-+2.106313768E-004,
-+1.939126523E-004,
-+1.775395358E-004,
-+1.615635992E-004,
-+1.460311323E-004,
-+1.309833024E-004,
-+1.164562127E-004,
-+1.024810626E-004,
-+8.908427117E-005,
-+7.628766616E-005,
-+6.410864444E-005,
-+5.256036457E-005,
-+4.165195787E-005,
-+3.138873581E-005,
-+2.177240640E-005,
-+1.280130618E-005,
-+4.470633485E-006,
--3.227306706E-006,
--1.030297699E-005,
--1.676913780E-005,
--2.264085742E-005,
--2.793515523E-005,
--3.267079956E-005,
--3.686808850E-005,
--4.054862075E-005,
--4.373511547E-005,
--4.645117951E-005,
--4.872112549E-005,
--5.056979353E-005,
--5.202236207E-005,
--5.310418419E-005,
--5.384063843E-005,
--5.425697600E-005,
--5.437819709E-005,
--5.422891263E-005,
--5.383323878E-005,
--5.321469871E-005,
--5.239612074E-005,
--5.139957648E-005,
-+5.024627535E-005,
-+4.895655002E-005,
-+4.754976908E-005,
-+4.604430433E-005,
-+4.445751256E-005,
-+4.280570283E-005,
-+4.110412556E-005,
-+3.936696885E-005,
-+3.760734762E-005,
-+3.583733633E-005,
-+3.406793985E-005,
-+3.230916263E-005,
-+3.056998685E-005,
-+2.885844333E-005,
-+2.718161704E-005,
-+2.554569073E-005,
-+2.395598858E-005,
-+2.241701623E-005,
-+2.093250441E-005,
-+1.950545993E-005,
-+1.813820381E-005,
-+1.683242772E-005,
-+1.558924305E-005,
-+1.440921824E-005,
-+1.329243969E-005,
-+1.223855270E-005,
-+1.124680875E-005,
-+1.031611009E-005,
-+9.445050637E-006,
-+8.631964192E-006,
-+7.874960829E-006,
-+7.171964626E-006,
-+6.520755960E-006,
-+5.918994248E-006,
-+5.364252502E-006,
-+4.854050530E-006,
-+4.385879038E-006,
-+3.957220997E-006,
-+3.565570978E-006,
-+3.208459020E-006,
-+2.883470643E-006,
-+2.588257530E-006,
-+2.320550948E-006,
-+2.078171747E-006,
-+1.859034001E-006,
-+1.661159786E-006,
-+1.482681114E-006,
-+1.321840614E-006,
-+1.176999604E-006,
-+1.046637067E-006,
-+9.293416952E-007,
-+8.238164355E-007,
-+7.288739425E-007,
-+6.434325428E-007,
-+5.665120852E-007,
-+4.972276315E-007,
-+4.347855338E-007,
-+3.784752209E-007,
-+3.276689142E-007,
-+2.818143514E-007,
-+2.404238444E-007,
-+2.030677564E-007,
-+1.693738625E-007,
-+1.390191784E-007
+DECLARE_ALIGNED(16, static const float, fir_32bands_nonperfect)[] = {
+ -1.390191784E-007,
+ -1.693738625E-007,
+ -2.030677564E-007,
+ -2.404238444E-007,
+ -2.818143514E-007,
+ -3.276689142E-007,
+ -3.784752209E-007,
+ -4.347855338E-007,
+ -4.972276315E-007,
+ -5.665120852E-007,
+ -6.434325428E-007,
+ -7.288739425E-007,
+ -8.238164355E-007,
+ -9.293416952E-007,
+ -1.046637067E-006,
+ -1.176999604E-006,
+ -1.321840614E-006,
+ -1.482681114E-006,
+ -1.661159786E-006,
+ -1.859034001E-006,
+ -2.078171747E-006,
+ -2.320550948E-006,
+ -2.588257530E-006,
+ -2.883470643E-006,
+ -3.208459020E-006,
+ -3.565570978E-006,
+ -3.957220997E-006,
+ -4.385879038E-006,
+ -4.854050530E-006,
+ -5.364252502E-006,
+ -5.918994248E-006,
+ -6.520755960E-006,
+ -7.171964626E-006,
+ -7.874960829E-006,
+ -8.631964192E-006,
+ -9.445050637E-006,
+ -1.031611009E-005,
+ -1.124680875E-005,
+ -1.223855270E-005,
+ -1.329243969E-005,
+ -1.440921824E-005,
+ -1.558924305E-005,
+ -1.683242772E-005,
+ -1.813820381E-005,
+ -1.950545993E-005,
+ -2.093250441E-005,
+ -2.241701623E-005,
+ -2.395598858E-005,
+ -2.554569073E-005,
+ -2.718161704E-005,
+ -2.885844333E-005,
+ -3.056998685E-005,
+ -3.230916263E-005,
+ -3.406793985E-005,
+ -3.583733633E-005,
+ -3.760734762E-005,
+ -3.936696885E-005,
+ -4.110412556E-005,
+ -4.280570283E-005,
+ -4.445751256E-005,
+ -4.604430433E-005,
+ -4.754976908E-005,
+ -4.895655002E-005,
+ -5.024627535E-005,
+ +5.139957648E-005,
+ +5.239612074E-005,
+ +5.321469871E-005,
+ +5.383323878E-005,
+ +5.422891263E-005,
+ +5.437819709E-005,
+ +5.425697600E-005,
+ +5.384063843E-005,
+ +5.310418419E-005,
+ +5.202236207E-005,
+ +5.056979353E-005,
+ +4.872112549E-005,
+ +4.645117951E-005,
+ +4.373511547E-005,
+ +4.054862075E-005,
+ +3.686808850E-005,
+ +3.267079956E-005,
+ +2.793515523E-005,
+ +2.264085742E-005,
+ +1.676913780E-005,
+ +1.030297699E-005,
+ +3.227306706E-006,
+ -4.470633485E-006,
+ -1.280130618E-005,
+ -2.177240640E-005,
+ -3.138873581E-005,
+ -4.165195787E-005,
+ -5.256036457E-005,
+ -6.410864444E-005,
+ -7.628766616E-005,
+ -8.908427117E-005,
+ -1.024810626E-004,
+ -1.164562127E-004,
+ -1.309833024E-004,
+ -1.460311323E-004,
+ -1.615635992E-004,
+ -1.775395358E-004,
+ -1.939126523E-004,
+ -2.106313768E-004,
+ -2.276388550E-004,
+ -2.448728774E-004,
+ -2.622658503E-004,
+ -2.797449124E-004,
+ -2.972317743E-004,
+ -3.146430245E-004,
+ -3.318900708E-004,
+ -3.488793736E-004,
+ -3.655125911E-004,
+ -3.816867538E-004,
+ -3.972945851E-004,
+ -4.122247046E-004,
+ -4.263620067E-004,
+ -4.395879805E-004,
+ -4.517810594E-004,
+ -4.628172028E-004,
+ -4.725702747E-004,
+ -4.809123348E-004,
+ -4.877146275E-004,
+ -4.928477574E-004,
+ -4.961824161E-004,
+ -4.975944757E-004,
+ -4.969481961E-004,
+ -4.941228544E-004,
+ -4.889960401E-004,
+ +4.814492422E-004,
+ +4.713678791E-004,
+ +4.586426076E-004,
+ +4.431701091E-004,
+ +4.248536134E-004,
+ +4.036037717E-004,
+ +3.793396754E-004,
+ +3.519894381E-004,
+ +3.214911267E-004,
+ +2.877934603E-004,
+ +2.508567995E-004,
+ +2.106537577E-004,
+ +1.671699720E-004,
+ +1.204049113E-004,
+ +7.037253090E-005,
+ +1.710198012E-005,
+ -3.936182839E-005,
+ -9.895755647E-005,
+ -1.616069785E-004,
+ -2.272142592E-004,
+ -2.956659591E-004,
+ -3.668301215E-004,
+ -4.405563814E-004,
+ -5.166754709E-004,
+ -5.949990009E-004,
+ -6.753197522E-004,
+ -7.574109477E-004,
+ -8.410271257E-004,
+ -9.259034996E-004,
+ -1.011756598E-003,
+ -1.098284614E-003,
+ -1.185167348E-003,
+ -1.272067428E-003,
+ -1.358630019E-003,
+ -1.444484224E-003,
+ -1.529243193E-003,
+ -1.612505526E-003,
+ -1.693855622E-003,
+ -1.772865304E-003,
+ -1.849094522E-003,
+ -1.922092517E-003,
+ -1.991399564E-003,
+ -2.056547208E-003,
+ -2.117061289E-003,
+ -2.172462177E-003,
+ -2.222266514E-003,
+ -2.265989315E-003,
+ -2.303145360E-003,
+ -2.333251061E-003,
+ -2.355825622E-003,
+ -2.370394068E-003,
+ -2.376487479E-003,
+ -2.373647178E-003,
+ -2.361423569E-003,
+ -2.339380793E-003,
+ -2.307097195E-003,
+ -2.264167881E-003,
+ -2.210205887E-003,
+ -2.144844970E-003,
+ -2.067740774E-003,
+ -1.978572691E-003,
+ -1.877046190E-003,
+ -1.762894331E-003,
+ -1.635878929E-003,
+ +1.495792647E-003,
+ +1.342460280E-003,
+ +1.175740734E-003,
+ +9.955273708E-004,
+ +8.017504588E-004,
+ +5.943773431E-004,
+ +3.734139318E-004,
+ +1.389056415E-004,
+ -1.090620208E-004,
+ -3.703625989E-004,
+ -6.448282511E-004,
+ -9.322494152E-004,
+ -1.232374110E-003,
+ -1.544908970E-003,
+ -1.869517611E-003,
+ -2.205822384E-003,
+ -2.553403843E-003,
+ -2.911801683E-003,
+ -3.280514618E-003,
+ -3.659002949E-003,
+ -4.046686925E-003,
+ -4.442950245E-003,
+ -4.847140983E-003,
+ -5.258570891E-003,
+ -5.676518660E-003,
+ -6.100233644E-003,
+ -6.528933067E-003,
+ -6.961807609E-003,
+ -7.398022339E-003,
+ -7.836719044E-003,
+ -8.277016692E-003,
+ -8.718019351E-003,
+ -9.158811532E-003,
+ -9.598465636E-003,
+ -1.003604382E-002,
+ -1.047059800E-002,
+ -1.090117730E-002,
+ -1.132682897E-002,
+ -1.174659748E-002,
+ -1.215953380E-002,
+ -1.256469358E-002,
+ -1.296114177E-002,
+ -1.334795821E-002,
+ -1.372423489E-002,
+ -1.408908330E-002,
+ -1.444163360E-002,
+ -1.478104480E-002,
+ -1.510649733E-002,
+ -1.541720331E-002,
+ -1.571240649E-002,
+ -1.599138230E-002,
+ -1.625344716E-002,
+ -1.649795473E-002,
+ -1.672429405E-002,
+ -1.693190821E-002,
+ -1.712027565E-002,
+ -1.728892699E-002,
+ -1.743743755E-002,
+ -1.756543480E-002,
+ -1.767260395E-002,
+ -1.775865816E-002,
+ -1.782339066E-002,
+ -1.786663756E-002,
+ -1.788828894E-002,
+ +1.788828894E-002,
+ +1.786663756E-002,
+ +1.782339066E-002,
+ +1.775865816E-002,
+ +1.767260395E-002,
+ +1.756543480E-002,
+ +1.743743755E-002,
+ +1.728892699E-002,
+ +1.712027565E-002,
+ +1.693190821E-002,
+ +1.672429405E-002,
+ +1.649795473E-002,
+ +1.625344716E-002,
+ +1.599138230E-002,
+ +1.571240649E-002,
+ +1.541720331E-002,
+ +1.510649733E-002,
+ +1.478104480E-002,
+ +1.444163360E-002,
+ +1.408908330E-002,
+ +1.372423489E-002,
+ +1.334795821E-002,
+ +1.296114177E-002,
+ +1.256469358E-002,
+ +1.215953380E-002,
+ +1.174659748E-002,
+ +1.132682897E-002,
+ +1.090117730E-002,
+ +1.047059800E-002,
+ +1.003604382E-002,
+ +9.598465636E-003,
+ +9.158811532E-003,
+ +8.718019351E-003,
+ +8.277016692E-003,
+ +7.836719044E-003,
+ +7.398022339E-003,
+ +6.961807609E-003,
+ +6.528933067E-003,
+ +6.100233644E-003,
+ +5.676518660E-003,
+ +5.258570891E-003,
+ +4.847140983E-003,
+ +4.442950245E-003,
+ +4.046686925E-003,
+ +3.659002949E-003,
+ +3.280514618E-003,
+ +2.911801683E-003,
+ +2.553403843E-003,
+ +2.205822384E-003,
+ +1.869517611E-003,
+ +1.544908970E-003,
+ +1.232374110E-003,
+ +9.322494152E-004,
+ +6.448282511E-004,
+ +3.703625989E-004,
+ +1.090620208E-004,
+ -1.389056415E-004,
+ -3.734139318E-004,
+ -5.943773431E-004,
+ -8.017504588E-004,
+ -9.955273708E-004,
+ -1.175740734E-003,
+ -1.342460280E-003,
+ -1.495792647E-003,
+ +1.635878929E-003,
+ +1.762894331E-003,
+ +1.877046190E-003,
+ +1.978572691E-003,
+ +2.067740774E-003,
+ +2.144844970E-003,
+ +2.210205887E-003,
+ +2.264167881E-003,
+ +2.307097195E-003,
+ +2.339380793E-003,
+ +2.361423569E-003,
+ +2.373647178E-003,
+ +2.376487479E-003,
+ +2.370394068E-003,
+ +2.355825622E-003,
+ +2.333251061E-003,
+ +2.303145360E-003,
+ +2.265989315E-003,
+ +2.222266514E-003,
+ +2.172462177E-003,
+ +2.117061289E-003,
+ +2.056547208E-003,
+ +1.991399564E-003,
+ +1.922092517E-003,
+ +1.849094522E-003,
+ +1.772865304E-003,
+ +1.693855622E-003,
+ +1.612505526E-003,
+ +1.529243193E-003,
+ +1.444484224E-003,
+ +1.358630019E-003,
+ +1.272067428E-003,
+ +1.185167348E-003,
+ +1.098284614E-003,
+ +1.011756598E-003,
+ +9.259034996E-004,
+ +8.410271257E-004,
+ +7.574109477E-004,
+ +6.753197522E-004,
+ +5.949990009E-004,
+ +5.166754709E-004,
+ +4.405563814E-004,
+ +3.668301215E-004,
+ +2.956659591E-004,
+ +2.272142592E-004,
+ +1.616069785E-004,
+ +9.895755647E-005,
+ +3.936182839E-005,
+ -1.710198012E-005,
+ -7.037253090E-005,
+ -1.204049113E-004,
+ -1.671699720E-004,
+ -2.106537577E-004,
+ -2.508567995E-004,
+ -2.877934603E-004,
+ -3.214911267E-004,
+ -3.519894381E-004,
+ -3.793396754E-004,
+ -4.036037717E-004,
+ -4.248536134E-004,
+ -4.431701091E-004,
+ -4.586426076E-004,
+ -4.713678791E-004,
+ -4.814492422E-004,
+ +4.889960401E-004,
+ +4.941228544E-004,
+ +4.969481961E-004,
+ +4.975944757E-004,
+ +4.961824161E-004,
+ +4.928477574E-004,
+ +4.877146275E-004,
+ +4.809123348E-004,
+ +4.725702747E-004,
+ +4.628172028E-004,
+ +4.517810594E-004,
+ +4.395879805E-004,
+ +4.263620067E-004,
+ +4.122247046E-004,
+ +3.972945851E-004,
+ +3.816867538E-004,
+ +3.655125911E-004,
+ +3.488793736E-004,
+ +3.318900708E-004,
+ +3.146430245E-004,
+ +2.972317743E-004,
+ +2.797449124E-004,
+ +2.622658503E-004,
+ +2.448728774E-004,
+ +2.276388550E-004,
+ +2.106313768E-004,
+ +1.939126523E-004,
+ +1.775395358E-004,
+ +1.615635992E-004,
+ +1.460311323E-004,
+ +1.309833024E-004,
+ +1.164562127E-004,
+ +1.024810626E-004,
+ +8.908427117E-005,
+ +7.628766616E-005,
+ +6.410864444E-005,
+ +5.256036457E-005,
+ +4.165195787E-005,
+ +3.138873581E-005,
+ +2.177240640E-005,
+ +1.280130618E-005,
+ +4.470633485E-006,
+ -3.227306706E-006,
+ -1.030297699E-005,
+ -1.676913780E-005,
+ -2.264085742E-005,
+ -2.793515523E-005,
+ -3.267079956E-005,
+ -3.686808850E-005,
+ -4.054862075E-005,
+ -4.373511547E-005,
+ -4.645117951E-005,
+ -4.872112549E-005,
+ -5.056979353E-005,
+ -5.202236207E-005,
+ -5.310418419E-005,
+ -5.384063843E-005,
+ -5.425697600E-005,
+ -5.437819709E-005,
+ -5.422891263E-005,
+ -5.383323878E-005,
+ -5.321469871E-005,
+ -5.239612074E-005,
+ -5.139957648E-005,
+ +5.024627535E-005,
+ +4.895655002E-005,
+ +4.754976908E-005,
+ +4.604430433E-005,
+ +4.445751256E-005,
+ +4.280570283E-005,
+ +4.110412556E-005,
+ +3.936696885E-005,
+ +3.760734762E-005,
+ +3.583733633E-005,
+ +3.406793985E-005,
+ +3.230916263E-005,
+ +3.056998685E-005,
+ +2.885844333E-005,
+ +2.718161704E-005,
+ +2.554569073E-005,
+ +2.395598858E-005,
+ +2.241701623E-005,
+ +2.093250441E-005,
+ +1.950545993E-005,
+ +1.813820381E-005,
+ +1.683242772E-005,
+ +1.558924305E-005,
+ +1.440921824E-005,
+ +1.329243969E-005,
+ +1.223855270E-005,
+ +1.124680875E-005,
+ +1.031611009E-005,
+ +9.445050637E-006,
+ +8.631964192E-006,
+ +7.874960829E-006,
+ +7.171964626E-006,
+ +6.520755960E-006,
+ +5.918994248E-006,
+ +5.364252502E-006,
+ +4.854050530E-006,
+ +4.385879038E-006,
+ +3.957220997E-006,
+ +3.565570978E-006,
+ +3.208459020E-006,
+ +2.883470643E-006,
+ +2.588257530E-006,
+ +2.320550948E-006,
+ +2.078171747E-006,
+ +1.859034001E-006,
+ +1.661159786E-006,
+ +1.482681114E-006,
+ +1.321840614E-006,
+ +1.176999604E-006,
+ +1.046637067E-006,
+ +9.293416952E-007,
+ +8.238164355E-007,
+ +7.288739425E-007,
+ +6.434325428E-007,
+ +5.665120852E-007,
+ +4.972276315E-007,
+ +4.347855338E-007,
+ +3.784752209E-007,
+ +3.276689142E-007,
+ +2.818143514E-007,
+ +2.404238444E-007,
+ +2.030677564E-007,
+ +1.693738625E-007,
+ +1.390191784E-007
};
/* pre-scale lfe fir coefficients */
#define SCALE(c) ((c) / (256.0f * 32768.0f))
-DECLARE_ALIGNED(16, static const float, lfe_fir_64)[] =
-{
+DECLARE_ALIGNED(16, static const float, lfe_fir_64)[] = {
SCALE(2.658434386830777e-4), SCALE(9.029330685734748e-3),
SCALE(7.939263433218002e-2), SCALE(2.425158768892288e-1),
SCALE(3.430179357528686e-1), SCALE(2.398228943347931e-1),
SCALE(3.165979683399200e-2), SCALE(1.527829794213176e-3),
};
-DECLARE_ALIGNED(16, static const float, lfe_fir_128)[] =
-{
+DECLARE_ALIGNED(16, static const float, lfe_fir_128)[] = {
SCALE(0.00053168571), SCALE(0.15878495574), SCALE(0.68603444099), SCALE(0.15492856503),
SCALE(0.00016358691), SCALE(0.16269733012), SCALE(0.68591803312), SCALE(0.15112841129),
SCALE(0.00018878609), SCALE(0.16666537523), SCALE(0.68568539619), SCALE(0.14738474786),
* 3) [-14.875 to 0] with resolution of 0.125 dB
*/
static const uint16_t dca_dmixtable[242] = {
- 0, 33, 35, 37, 39, 41, 44, 46,
- 49, 52, 55, 58, 62, 65, 69, 73,
- 78, 82, 87, 92, 98, 104, 110, 116,
- 123, 130, 138, 146, 155, 164, 174, 184,
- 195, 207, 219, 232, 246, 260, 276, 292,
- 309, 328, 347, 368, 389, 413, 437, 463,
- 490, 519, 550, 583, 617, 654, 693, 734,
- 777, 823, 872, 924, 978, 1036, 1066, 1098,
- 1130, 1163, 1197, 1232, 1268, 1305, 1343, 1382,
- 1422, 1464, 1506, 1550, 1596, 1642, 1690, 1740,
- 1790, 1843, 1896, 1952, 2009, 2068, 2128, 2190,
- 2254, 2320, 2388, 2457, 2529, 2603, 2679, 2757,
- 2838, 2920, 3006, 3093, 3184, 3277, 3372, 3471,
- 3572, 3677, 3784, 3894, 4008, 4125, 4246, 4370,
- 4497, 4629, 4764, 4903, 5046, 5193, 5345, 5501,
- 5662, 5827, 5912, 5997, 6084, 6172, 6262, 6353,
- 6445, 6538, 6633, 6729, 6827, 6925, 7026, 7128,
- 7231, 7336, 7442, 7550, 7659, 7771, 7883, 7997,
- 8113, 8231, 8350, 8471, 8594, 8719, 8845, 8973,
- 9103, 9235, 9369, 9505, 9643, 9783, 9924, 10068,
+ 0, 33, 35, 37, 39, 41, 44, 46,
+ 49, 52, 55, 58, 62, 65, 69, 73,
+ 78, 82, 87, 92, 98, 104, 110, 116,
+ 123, 130, 138, 146, 155, 164, 174, 184,
+ 195, 207, 219, 232, 246, 260, 276, 292,
+ 309, 328, 347, 368, 389, 413, 437, 463,
+ 490, 519, 550, 583, 617, 654, 693, 734,
+ 777, 823, 872, 924, 978, 1036, 1066, 1098,
+ 1130, 1163, 1197, 1232, 1268, 1305, 1343, 1382,
+ 1422, 1464, 1506, 1550, 1596, 1642, 1690, 1740,
+ 1790, 1843, 1896, 1952, 2009, 2068, 2128, 2190,
+ 2254, 2320, 2388, 2457, 2529, 2603, 2679, 2757,
+ 2838, 2920, 3006, 3093, 3184, 3277, 3372, 3471,
+ 3572, 3677, 3784, 3894, 4008, 4125, 4246, 4370,
+ 4497, 4629, 4764, 4903, 5046, 5193, 5345, 5501,
+ 5662, 5827, 5912, 5997, 6084, 6172, 6262, 6353,
+ 6445, 6538, 6633, 6729, 6827, 6925, 7026, 7128,
+ 7231, 7336, 7442, 7550, 7659, 7771, 7883, 7997,
+ 8113, 8231, 8350, 8471, 8594, 8719, 8845, 8973,
+ 9103, 9235, 9369, 9505, 9643, 9783, 9924, 10068,
10214, 10362, 10512, 10665, 10819, 10976, 11135, 11297,
11460, 11627, 11795, 11966, 12139, 12315, 12494, 12675,
12859, 13045, 13234, 13426, 13621, 13818, 14018, 14222,
};
/* downmix coeffs
-
- TABLE 9
-______________________________________
-Down-mix coefficients for 8-channel source
-audio (5 + 3 format)
- lt
- cen- rt lt ctr rt
-lt ter ctr center
- rt srd srd srd
-______________________________________
-1 0.71 0.74 1.0 0.71 0.71 0.58 0.58 0.58
-2 left 1.0 0.89 0.71 0.46 0.71 0.50
- rt 0.45 0.71 0.89 1.0 0.50 0.71
-3 lt 1.0 0.89 0.71 0.45
- rt 0.45 0.71 0.89 1.0
- srd 0.71 0.71 0.71
-4 lt 1.0 0.89 0.71 0.45
- rt 0.45 0.71 0.89 1.0
- lt srd 1.0 0.71
- rt srd 0.71 0.71
-4 lt 1.0 0.5
- ctr 0.87 1.0 0.87
- rt 0.5 1.0
- srd 0.71 0.71 0.71
-5 lt 1.0 0.5
- ctr 0.87 1.0 0.87
- rt 0.5 1.0
- lt srd 1.0 0.71
- rt srd 0.71 1.0
-6 lt 1.0 0.5
- lt ctr 0.87 0.71
- rt ctr 0.71 0.87
- rt 0.5 1.0
- lt srd 1.0 0.71
- rt srd 0.71 1.0
-6 lt 1.0 0.5
- ctr 0.86 1.0 0.86
- rt 0.5 1.0
- lt srd 1.0
- ctr srd 1.0
- rt srd 1.0
-7 lt 1.0
- lt ctr 1.0
- ctr 1.0
- rt ctr 1.0
- rt 1.0
- lt srd 1.0 0.71
- rt srd 0.71 1.0
-7 lt 1.0 0.5
- lt ctr 0.87 0.71
- rt ctr 0.71 0.87
- rt 0.5 1.0
- lt srd 1.0
- ctr srd 1.0
- rt srd 1.0
-8 lt 1.0 0.5
- lt ctr 0.87 0.71
- rt ctr 0.71 0.87
- rt 0.5 1.0
- lt 1 srd 0.87 0.35
- lt 2 srd 0.5 0.61
- rt 2 srd 0.61 0.50
- rt 2 srd 0.35 0.87
-
- Generation of Lt Rt
-
-In the case when the playback system has analog or digital surround multi-channel capability, a down matrix from 5, 4, or 3 channel to Lt Rt may be desirable. In the case when the number of decoded audio channels exceeds 5, 4 or 3 respectively a first stage down mix to 5, 4 or 3 chs should be used as described above.
-
-The down matrixing equations for 5-channel source audio to a two-channel Lt Rt playback system are given by:
-
-Left left+0.7*center-0.7*(lt surround+rt surround)
-
-Right=right+0.7*center+0.7*(lt surround+rt surround)
-
-Embedded mixing to 2-channel
-
-One concern arising from the proliferation of multi-channel audio systems is that most home systems presently have only two channel playback capability. To accommodate this a fixed 2-channel down matrix processes is commonly used following the multi-channel decoding stage. However, for music only applications the image quality etc. of the down matrixed signal may not match that of an equivalent stereo recording found on CD.
-
-The concept of embedded mixing is to allow the producer to dynamically specify the matrixing coefficients within the audio frame itself. In this way the stereo down mix at the decoder may be better matched to a 2-channel playback environment.
-
-CHS*2, 7-bit down mix indexes (MCOEFFS) are transmitted along with the multi-channel audio once in every frame. The indexes are converted to attenuation factors using a 7 bit LUT. The 2-ch down mix equations are as follows,
-
-Left Ch=sum (MCOEFF[n]*Ch[n]) for n=1, CHS
-
-Right Ch sum (MCOEFF[n+CHS]*Ch[n]) for n=1, CHS
-
-where Ch(n) represents the subband samples in the (n)th audio channel.
-
-
-*/
+ *
+ * TABLE 9
+ * ______________________________________
+ * Down-mix coefficients for 8-channel source
+ * audio (5 + 3 format)
+ * lt
+ * cen- rt lt ctr rt
+ * lt ter ctr center
+ * rt srd srd srd
+ * ______________________________________
+ * 1 0.71 0.74 1.0 0.71 0.71 0.58 0.58 0.58
+ * 2 left 1.0 0.89 0.71 0.46 0.71 0.50
+ * rt 0.45 0.71 0.89 1.0 0.50 0.71
+ * 3 lt 1.0 0.89 0.71 0.45
+ * rt 0.45 0.71 0.89 1.0
+ * srd 0.71 0.71 0.71
+ * 4 lt 1.0 0.89 0.71 0.45
+ * rt 0.45 0.71 0.89 1.0
+ * lt srd 1.0 0.71
+ * rt srd 0.71 0.71
+ * 4 lt 1.0 0.5
+ * ctr 0.87 1.0 0.87
+ * rt 0.5 1.0
+ * srd 0.71 0.71 0.71
+ * 5 lt 1.0 0.5
+ * ctr 0.87 1.0 0.87
+ * rt 0.5 1.0
+ * lt srd 1.0 0.71
+ * rt srd 0.71 1.0
+ * 6 lt 1.0 0.5
+ * lt ctr 0.87 0.71
+ * rt ctr 0.71 0.87
+ * rt 0.5 1.0
+ * lt srd 1.0 0.71
+ * rt srd 0.71 1.0
+ * 6 lt 1.0 0.5
+ * ctr 0.86 1.0 0.86
+ * rt 0.5 1.0
+ * lt srd 1.0
+ * ctr srd 1.0
+ * rt srd 1.0
+ * 7 lt 1.0
+ * lt ctr 1.0
+ * ctr 1.0
+ * rt ctr 1.0
+ * rt 1.0
+ * lt srd 1.0 0.71
+ * rt srd 0.71 1.0
+ * 7 lt 1.0 0.5
+ * lt ctr 0.87 0.71
+ * rt ctr 0.71 0.87
+ * rt 0.5 1.0
+ * lt srd 1.0
+ * ctr srd 1.0
+ * rt srd 1.0
+ * 8 lt 1.0 0.5
+ * lt ctr 0.87 0.71
+ * rt ctr 0.71 0.87
+ * rt 0.5 1.0
+ * lt 1 srd 0.87 0.35
+ * lt 2 srd 0.5 0.61
+ * rt 2 srd 0.61 0.50
+ * rt 2 srd 0.35 0.87
+ *
+ * Generation of Lt Rt
+ *
+ * In the case when the playback system has analog or digital surround
+ * multi-channel capability, a down matrix from 5, 4, or 3 channel to
+ * Lt Rt may be desirable. In the case when the number of decoded audio
+ * channels exceeds 5, 4 or 3 respectively a first stage down mix to 5,
+ * 4 or 3 chs should be used as described above.
+ *
+ * The down matrixing equations for 5-channel source audio to a
+ * two-channel Lt Rt playback system are given by:
+ *
+ * Left = left + 0.7 * center - 0.7 * (lt surround + rt surround)
+ *
+ * Right = right + 0.7 * center + 0.7 * (lt surround + rt surround)
+ *
+ * Embedded mixing to 2-channel
+ *
+ * One concern arising from the proliferation of multi-channel audio
+ * systems is that most home systems presently have only two channel
+ * playback capability. To accommodate this a fixed 2-channel down
+ * matrix processes is commonly used following the multi-channel
+ * decoding stage. However, for music only applications the image
+ * quality etc. of the down matrixed signal may not match that of an
+ * equivalent stereo recording found on CD.
+ *
+ * The concept of embedded mixing is to allow the producer to
+ * dynamically specify the matrixing coefficients within the audio
+ * frame itself. In this way the stereo down mix at the decoder may be
+ * better matched to a 2-channel playback environment.
+ *
+ * CHS*2, 7-bit down mix indexes (MCOEFFS) are transmitted along with
+ * the multi-channel audio once in every frame. The indexes are
+ * converted to attenuation factors using a 7 bit LUT. The 2-ch down
+ * mix equations are as follows,
+ *
+ * Left Ch = sum (MCOEFF[n] * Ch[n]) for n=1, CHS
+ *
+ * Right Ch = sum (MCOEFF[n + CHS] * Ch[n]) for n=1, CHS
+ *
+ * where Ch(n) represents the subband samples in the (n)th audio channel.
+ */
#endif /* AVCODEC_DCADATA_H */
#include "libavutil/mathematics.h"
#include "libavutil/opt.h"
#include "libavutil/samplefmt.h"
+
#include "avcodec.h"
-#include "fft.h"
-#include "get_bits.h"
-#include "dcadata.h"
-#include "dcahuff.h"
#include "dca.h"
-#include "mathops.h"
-#include "synth_filter.h"
+#include "dcadata.h"
#include "dcadsp.h"
+#include "dcahuff.h"
+#include "fft.h"
#include "fmtconvert.h"
+#include "get_bits.h"
#include "internal.h"
+#include "mathops.h"
+#include "synth_filter.h"
#if ARCH_ARM
# include "arm/dca.h"
};
static const int8_t dca_channel_reorder_lfe[][9] = {
- { 0, -1, -1, -1, -1, -1, -1, -1, -1},
- { 0, 1, -1, -1, -1, -1, -1, -1, -1},
- { 0, 1, -1, -1, -1, -1, -1, -1, -1},
- { 0, 1, -1, -1, -1, -1, -1, -1, -1},
- { 0, 1, -1, -1, -1, -1, -1, -1, -1},
- { 2, 0, 1, -1, -1, -1, -1, -1, -1},
- { 0, 1, 3, -1, -1, -1, -1, -1, -1},
- { 2, 0, 1, 4, -1, -1, -1, -1, -1},
- { 0, 1, 3, 4, -1, -1, -1, -1, -1},
- { 2, 0, 1, 4, 5, -1, -1, -1, -1},
- { 3, 4, 0, 1, 5, 6, -1, -1, -1},
- { 2, 0, 1, 4, 5, 6, -1, -1, -1},
- { 0, 6, 4, 5, 2, 3, -1, -1, -1},
- { 4, 2, 5, 0, 1, 6, 7, -1, -1},
- { 5, 6, 0, 1, 7, 3, 8, 4, -1},
- { 4, 2, 5, 0, 1, 6, 8, 7, -1},
+ { 0, -1, -1, -1, -1, -1, -1, -1, -1 },
+ { 0, 1, -1, -1, -1, -1, -1, -1, -1 },
+ { 0, 1, -1, -1, -1, -1, -1, -1, -1 },
+ { 0, 1, -1, -1, -1, -1, -1, -1, -1 },
+ { 0, 1, -1, -1, -1, -1, -1, -1, -1 },
+ { 2, 0, 1, -1, -1, -1, -1, -1, -1 },
+ { 0, 1, 3, -1, -1, -1, -1, -1, -1 },
+ { 2, 0, 1, 4, -1, -1, -1, -1, -1 },
+ { 0, 1, 3, 4, -1, -1, -1, -1, -1 },
+ { 2, 0, 1, 4, 5, -1, -1, -1, -1 },
+ { 3, 4, 0, 1, 5, 6, -1, -1, -1 },
+ { 2, 0, 1, 4, 5, 6, -1, -1, -1 },
+ { 0, 6, 4, 5, 2, 3, -1, -1, -1 },
+ { 4, 2, 5, 0, 1, 6, 7, -1, -1 },
+ { 5, 6, 0, 1, 7, 3, 8, 4, -1 },
+ { 4, 2, 5, 0, 1, 6, 8, 7, -1 },
};
static const int8_t dca_channel_reorder_lfe_xch[][9] = {
- { 0, 2, -1, -1, -1, -1, -1, -1, -1},
- { 0, 1, 3, -1, -1, -1, -1, -1, -1},
- { 0, 1, 3, -1, -1, -1, -1, -1, -1},
- { 0, 1, 3, -1, -1, -1, -1, -1, -1},
- { 0, 1, 3, -1, -1, -1, -1, -1, -1},
- { 2, 0, 1, 4, -1, -1, -1, -1, -1},
- { 0, 1, 3, 4, -1, -1, -1, -1, -1},
- { 2, 0, 1, 4, 5, -1, -1, -1, -1},
- { 0, 1, 4, 5, 3, -1, -1, -1, -1},
- { 2, 0, 1, 5, 6, 4, -1, -1, -1},
- { 3, 4, 0, 1, 6, 7, 5, -1, -1},
- { 2, 0, 1, 4, 5, 6, 7, -1, -1},
- { 0, 6, 4, 5, 2, 3, 7, -1, -1},
- { 4, 2, 5, 0, 1, 7, 8, 6, -1},
- { 5, 6, 0, 1, 8, 3, 9, 4, 7},
- { 4, 2, 5, 0, 1, 6, 9, 8, 7},
+ { 0, 2, -1, -1, -1, -1, -1, -1, -1 },
+ { 0, 1, 3, -1, -1, -1, -1, -1, -1 },
+ { 0, 1, 3, -1, -1, -1, -1, -1, -1 },
+ { 0, 1, 3, -1, -1, -1, -1, -1, -1 },
+ { 0, 1, 3, -1, -1, -1, -1, -1, -1 },
+ { 2, 0, 1, 4, -1, -1, -1, -1, -1 },
+ { 0, 1, 3, 4, -1, -1, -1, -1, -1 },
+ { 2, 0, 1, 4, 5, -1, -1, -1, -1 },
+ { 0, 1, 4, 5, 3, -1, -1, -1, -1 },
+ { 2, 0, 1, 5, 6, 4, -1, -1, -1 },
+ { 3, 4, 0, 1, 6, 7, 5, -1, -1 },
+ { 2, 0, 1, 4, 5, 6, 7, -1, -1 },
+ { 0, 6, 4, 5, 2, 3, 7, -1, -1 },
+ { 4, 2, 5, 0, 1, 7, 8, 6, -1 },
+ { 5, 6, 0, 1, 8, 3, 9, 4, 7 },
+ { 4, 2, 5, 0, 1, 6, 9, 8, 7 },
};
static const int8_t dca_channel_reorder_nolfe[][9] = {
- { 0, -1, -1, -1, -1, -1, -1, -1, -1},
- { 0, 1, -1, -1, -1, -1, -1, -1, -1},
- { 0, 1, -1, -1, -1, -1, -1, -1, -1},
- { 0, 1, -1, -1, -1, -1, -1, -1, -1},
- { 0, 1, -1, -1, -1, -1, -1, -1, -1},
- { 2, 0, 1, -1, -1, -1, -1, -1, -1},
- { 0, 1, 2, -1, -1, -1, -1, -1, -1},
- { 2, 0, 1, 3, -1, -1, -1, -1, -1},
- { 0, 1, 2, 3, -1, -1, -1, -1, -1},
- { 2, 0, 1, 3, 4, -1, -1, -1, -1},
- { 2, 3, 0, 1, 4, 5, -1, -1, -1},
- { 2, 0, 1, 3, 4, 5, -1, -1, -1},
- { 0, 5, 3, 4, 1, 2, -1, -1, -1},
- { 3, 2, 4, 0, 1, 5, 6, -1, -1},
- { 4, 5, 0, 1, 6, 2, 7, 3, -1},
- { 3, 2, 4, 0, 1, 5, 7, 6, -1},
+ { 0, -1, -1, -1, -1, -1, -1, -1, -1 },
+ { 0, 1, -1, -1, -1, -1, -1, -1, -1 },
+ { 0, 1, -1, -1, -1, -1, -1, -1, -1 },
+ { 0, 1, -1, -1, -1, -1, -1, -1, -1 },
+ { 0, 1, -1, -1, -1, -1, -1, -1, -1 },
+ { 2, 0, 1, -1, -1, -1, -1, -1, -1 },
+ { 0, 1, 2, -1, -1, -1, -1, -1, -1 },
+ { 2, 0, 1, 3, -1, -1, -1, -1, -1 },
+ { 0, 1, 2, 3, -1, -1, -1, -1, -1 },
+ { 2, 0, 1, 3, 4, -1, -1, -1, -1 },
+ { 2, 3, 0, 1, 4, 5, -1, -1, -1 },
+ { 2, 0, 1, 3, 4, 5, -1, -1, -1 },
+ { 0, 5, 3, 4, 1, 2, -1, -1, -1 },
+ { 3, 2, 4, 0, 1, 5, 6, -1, -1 },
+ { 4, 5, 0, 1, 6, 2, 7, 3, -1 },
+ { 3, 2, 4, 0, 1, 5, 7, 6, -1 },
};
static const int8_t dca_channel_reorder_nolfe_xch[][9] = {
- { 0, 1, -1, -1, -1, -1, -1, -1, -1},
- { 0, 1, 2, -1, -1, -1, -1, -1, -1},
- { 0, 1, 2, -1, -1, -1, -1, -1, -1},
- { 0, 1, 2, -1, -1, -1, -1, -1, -1},
- { 0, 1, 2, -1, -1, -1, -1, -1, -1},
- { 2, 0, 1, 3, -1, -1, -1, -1, -1},
- { 0, 1, 2, 3, -1, -1, -1, -1, -1},
- { 2, 0, 1, 3, 4, -1, -1, -1, -1},
- { 0, 1, 3, 4, 2, -1, -1, -1, -1},
- { 2, 0, 1, 4, 5, 3, -1, -1, -1},
- { 2, 3, 0, 1, 5, 6, 4, -1, -1},
- { 2, 0, 1, 3, 4, 5, 6, -1, -1},
- { 0, 5, 3, 4, 1, 2, 6, -1, -1},
- { 3, 2, 4, 0, 1, 6, 7, 5, -1},
- { 4, 5, 0, 1, 7, 2, 8, 3, 6},
- { 3, 2, 4, 0, 1, 5, 8, 7, 6},
+ { 0, 1, -1, -1, -1, -1, -1, -1, -1 },
+ { 0, 1, 2, -1, -1, -1, -1, -1, -1 },
+ { 0, 1, 2, -1, -1, -1, -1, -1, -1 },
+ { 0, 1, 2, -1, -1, -1, -1, -1, -1 },
+ { 0, 1, 2, -1, -1, -1, -1, -1, -1 },
+ { 2, 0, 1, 3, -1, -1, -1, -1, -1 },
+ { 0, 1, 2, 3, -1, -1, -1, -1, -1 },
+ { 2, 0, 1, 3, 4, -1, -1, -1, -1 },
+ { 0, 1, 3, 4, 2, -1, -1, -1, -1 },
+ { 2, 0, 1, 4, 5, 3, -1, -1, -1 },
+ { 2, 3, 0, 1, 5, 6, 4, -1, -1 },
+ { 2, 0, 1, 3, 4, 5, 6, -1, -1 },
+ { 0, 5, 3, 4, 1, 2, 6, -1, -1 },
+ { 3, 2, 4, 0, 1, 6, 7, 5, -1 },
+ { 4, 5, 0, 1, 7, 2, 8, 3, 6 },
+ { 3, 2, 4, 0, 1, 5, 8, 7, 6 },
};
#define DCA_DOLBY 101 /* FIXME */
int profile;
int debug_flag; ///< used for suppressing repeated error messages output
- AVFloatDSPContext fdsp;
+ AVFloatDSPContext *fdsp;
FFTContext imdct;
SynthFilterContext synth;
DCADSPContext dcadsp;
return;
dca_bitalloc_index.offset = 1;
- dca_bitalloc_index.wrap = 2;
+ dca_bitalloc_index.wrap = 2;
for (i = 0; i < 5; i++) {
- dca_bitalloc_index.vlc[i].table = &dca_table[dca_vlc_offs[i]];
+ dca_bitalloc_index.vlc[i].table = &dca_table[dca_vlc_offs[i]];
dca_bitalloc_index.vlc[i].table_allocated = dca_vlc_offs[i + 1] - dca_vlc_offs[i];
init_vlc(&dca_bitalloc_index.vlc[i], bitalloc_12_vlc_bits[i], 12,
bitalloc_12_bits[i], 1, 1,
bitalloc_12_codes[i], 2, 2, INIT_VLC_USE_NEW_STATIC);
}
dca_scalefactor.offset = -64;
- dca_scalefactor.wrap = 2;
+ dca_scalefactor.wrap = 2;
for (i = 0; i < 5; i++) {
- dca_scalefactor.vlc[i].table = &dca_table[dca_vlc_offs[i + 5]];
+ dca_scalefactor.vlc[i].table = &dca_table[dca_vlc_offs[i + 5]];
dca_scalefactor.vlc[i].table_allocated = dca_vlc_offs[i + 6] - dca_vlc_offs[i + 5];
init_vlc(&dca_scalefactor.vlc[i], SCALES_VLC_BITS, 129,
scales_bits[i], 1, 1,
scales_codes[i], 2, 2, INIT_VLC_USE_NEW_STATIC);
}
dca_tmode.offset = 0;
- dca_tmode.wrap = 1;
+ dca_tmode.wrap = 1;
for (i = 0; i < 4; i++) {
- dca_tmode.vlc[i].table = &dca_table[dca_vlc_offs[i + 10]];
+ dca_tmode.vlc[i].table = &dca_table[dca_vlc_offs[i + 10]];
dca_tmode.vlc[i].table_allocated = dca_vlc_offs[i + 11] - dca_vlc_offs[i + 10];
init_vlc(&dca_tmode.vlc[i], tmode_vlc_bits[i], 4,
tmode_bits[i], 1, 1,
if (s->prim_channels > DCA_PRIM_CHANNELS_MAX)
s->prim_channels = DCA_PRIM_CHANNELS_MAX;
-
for (i = base_channel; i < s->prim_channels; i++) {
s->subband_activity[i] = get_bits(&s->gb, 5) + 2;
if (s->subband_activity[i] > DCA_SUBBANDS)
#endif
/* Primary audio coding header */
- s->subframes = get_bits(&s->gb, 4) + 1;
+ s->subframes = get_bits(&s->gb, 4) + 1;
return dca_parse_audio_coding_header(s, 0, 0);
}
-
static inline int get_scale(GetBitContext *gb, int level, int value, int log2range)
{
if (level < 5) {
/* huffman encoded */
value += get_bitalloc(gb, &dca_scalefactor, level);
- value = av_clip(value, 0, (1 << log2range) - 1);
+ value = av_clip(value, 0, (1 << log2range) - 1);
} else if (level < 8) {
if (level + 1 > log2range) {
skip_bits(gb, level + 1 - log2range);
if (s->scalefactor_huffman[j] == 6) {
scale_table = scale_factor_quant7;
- log_size = 7;
+ log_size = 7;
} else {
scale_table = scale_factor_quant6;
- log_size = 6;
+ log_size = 6;
}
/* When huffman coded, only the difference is encoded */
if (!base_channel && s->lfe) {
int quant7;
/* LFE samples */
- int lfe_samples = 2 * s->lfe * (4 + block_index);
+ int lfe_samples = 2 * s->lfe * (4 + block_index);
int lfe_end_sample = 2 * s->lfe * (4 + block_index + s->subsubframes[s->current_subframe]);
float lfe_scale;
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]);
if (!base_channel && s->lfe) {
- int lfe_samples = 2 * s->lfe * (4 + block_index);
+ int lfe_samples = 2 * s->lfe * (4 + block_index);
int lfe_end_sample = 2 * s->lfe * (4 + block_index + s->subsubframes[s->current_subframe]);
av_log(s->avctx, AV_LOG_DEBUG, "LFE samples:\n");
/* Select decimation filter */
if (decimation_select == 1) {
- idx = 1;
+ idx = 1;
prCoeff = lfe_fir_128;
} else {
- idx = 0;
+ idx = 0;
prCoeff = lfe_fir_64;
}
/* Interpolation */
}
if (lfe_present) {
int lf_buf = dca_lfe_index[srcfmt];
- int lf_idx = dca_channels [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];
}
}
-
#ifndef decode_blockcodes
/* Very compact version of the block code decoder that does not use table
* look-up but is slightly slower */
for (i = 0; i < 4; i++) {
int div = FASTDIV(code, levels);
values[i] = code - offset - div * levels;
- code = div;
+ code = div;
}
return code;
/* Deal with transients */
int sfi = s->transition_mode[k][l] && subsubframe >= s->transition_mode[k][l];
rscale[l] = quant_step_size * s->scale_factor[k][l][sfi] *
- s->scalefactor_adj[k][sel];
+ s->scalefactor_adj[k][sel];
if (abits >= 11 || !dca_smpl_bitalloc[abits].vlc[sel].table) {
if (abits <= 7) {
block_code1 = get_bits(&s->gb, size);
block_code2 = get_bits(&s->gb, size);
- err = decode_blockcodes(block_code1, block_code2,
- levels, block + 8 * l);
+ err = decode_blockcodes(block_code1, block_code2,
+ levels, block + 8 * l);
if (err) {
av_log(s->avctx, AV_LOG_ERROR,
"ERROR: block code look-up failed\n");
/* Huffman coded */
for (m = 0; m < 8; m++)
block[8 * l + m] = get_bitalloc(&s->gb,
- &dca_smpl_bitalloc[abits], sel);
+ &dca_smpl_bitalloc[abits], sel);
}
-
}
}
/* 32 subbands QMF */
for (k = 0; k < s->prim_channels; k++) {
-/* static float pcm_to_double[8] = { 32768.0, 32768.0, 524288.0, 524288.0,
- 0, 8388608.0, 8388608.0 };*/
if (s->channel_order_tab[k] >= 0)
qmf_32_subbands(s, k, subband_samples[k],
s->samples_chanptr[s->channel_order_tab[k]],
- M_SQRT1_2 / 32768.0 /* pcm_to_double[s->source_pcm_res] */);
+ M_SQRT1_2 / 32768.0);
}
/* Generate LFE samples for this subsubframe FIXME!!! */
return 0;
}
-
static int dca_subframe_footer(DCAContext *s, int base_channel)
{
int in, out, aux_data_count, aux_data_end, reserved;
// 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);
+ 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,
int embedded_stereo = 0;
int embedded_6ch = 0;
int drc_code_present;
- int av_uninit(extensions_mask);
+ int extensions_mask = 0;
int i, j;
if (get_bits_left(&s->gb) < 16)
skip_bits_long(&s->gb, num_dec_ch * 5); // remap codes
}
}
-
} else {
skip_bits(&s->gb, 3); // representation type
}
}
switch (get_bits(&s->gb, 2)) {
- case 0: extensions_mask = get_bits(&s->gb, 12); break;
- case 1: extensions_mask = DCA_EXT_EXSS_XLL; break;
- case 2: extensions_mask = DCA_EXT_EXSS_LBR; break;
- case 3: extensions_mask = 0; /* aux coding */ break;
+ case 0:
+ extensions_mask = get_bits(&s->gb, 12);
+ break;
+ case 1:
+ extensions_mask = DCA_EXT_EXSS_XLL;
+ break;
+ case 2:
+ extensions_mask = DCA_EXT_EXSS_LBR;
+ break;
+ case 3:
+ extensions_mask = 0; /* aux coding */
+ break;
}
/* not parsed further, we were only interested in the extensions mask */
{
AVFrame *frame = data;
const uint8_t *buf = avpkt->data;
- int buf_size = avpkt->size;
+ int buf_size = avpkt->size;
int channel_mask;
int channel_layout;
int lfe_samples;
}
if ((ret = dca_parse_frame_header(s)) < 0) {
- //seems like the frame is corrupt, try with the next one
+ // seems like the frame is corrupt, try with the next one
return ret;
}
- //set AVCodec values with parsed data
+ // set AVCodec values with parsed data
avctx->sample_rate = s->sample_rate;
avctx->bit_rate = s->bit_rate;
/* only scan for extensions if ext_descr was unknown or indicated a
* supported XCh extension */
if (s->core_ext_mask < 0 || s->core_ext_mask & (DCA_EXT_XCH | DCA_EXT_XXCH)) {
-
/* if ext_descr was unknown, clear s->core_ext_mask so that the
* extensions scan can fill it up */
s->core_ext_mask = FFMAX(s->core_ext_mask, 0);
/* extension amode(number of channels in extension) should be 1 */
/* AFAIK XCh is not used for more channels */
if ((ext_amode = get_bits(&s->gb, 4)) != 1) {
- av_log(avctx, AV_LOG_ERROR, "XCh extension amode %d not"
- " supported!\n", ext_amode);
+ av_log(avctx, AV_LOG_ERROR,
+ "XCh extension amode %d not supported!\n",
+ ext_amode);
continue;
}
if (s->channel_order_tab[s->xch_base_channel] < 0)
return AVERROR_INVALIDDATA;
} else {
- channels = num_core_channels + !!s->lfe;
+ channels = num_core_channels + !!s->lfe;
s->xch_present = 0; /* disable further xch processing */
if (s->lfe) {
avctx->channel_layout |= AV_CH_LOW_FREQUENCY;
if (num_core_channels + !!s->lfe > 2 &&
avctx->request_channel_layout == AV_CH_LAYOUT_STEREO) {
- channels = 2;
- s->output = s->prim_channels == 2 ? s->amode : DCA_STEREO;
+ channels = 2;
+ s->output = s->prim_channels == 2 ? s->amode : DCA_STEREO;
avctx->channel_layout = AV_CH_LAYOUT_STEREO;
}
else if (avctx->request_channel_layout & AV_CH_LAYOUT_NATIVE) {
frame->nb_samples = 256 * (s->sample_blocks / 8);
if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
return ret;
- samples_flt = (float **)frame->extended_data;
+ samples_flt = (float **) frame->extended_data;
/* allocate buffer for extra channels if downmixing */
if (avctx->channels < full_channels) {
if (!s->extra_channels_buffer)
return AVERROR(ENOMEM);
- ret = av_samples_fill_arrays((uint8_t **)s->extra_channels, NULL,
+ ret = av_samples_fill_arrays((uint8_t **) s->extra_channels, NULL,
s->extra_channels_buffer,
full_channels - channels,
frame->nb_samples, avctx->sample_fmt, 0);
float *back_chan = s->samples_chanptr[s->channel_order_tab[s->xch_base_channel]];
float *lt_chan = s->samples_chanptr[s->channel_order_tab[s->xch_base_channel - 2]];
float *rt_chan = s->samples_chanptr[s->channel_order_tab[s->xch_base_channel - 1]];
- s->fdsp.vector_fmac_scalar(lt_chan, back_chan, -M_SQRT1_2, 256);
- s->fdsp.vector_fmac_scalar(rt_chan, back_chan, -M_SQRT1_2, 256);
+ s->fdsp->vector_fmac_scalar(lt_chan, back_chan, -M_SQRT1_2, 256);
+ s->fdsp->vector_fmac_scalar(rt_chan, back_chan, -M_SQRT1_2, 256);
}
/* If stream contains XXCH, we might need to undo an embedded downmix */
scale = s->xxch_dmix_coeff[j][k];
if (scale != 0.0) {
dst_chan = s->samples_chanptr[achan];
- s->fdsp.vector_fmac_scalar(dst_chan, src_chan,
+ s->fdsp->vector_fmac_scalar(dst_chan, src_chan,
-scale, 256);
}
}
return buf_size;
}
-
-
/**
* DCA initialization
*
s->avctx = avctx;
dca_init_vlcs();
- avpriv_float_dsp_init(&s->fdsp, avctx->flags & CODEC_FLAG_BITEXACT);
+ s->fdsp = avpriv_float_dsp_alloc(avctx->flags & CODEC_FLAG_BITEXACT);
+ if (!s->fdsp)
+ return AVERROR(ENOMEM);
+
ff_mdct_init(&s->imdct, 6, 1, 1.0);
ff_synth_filter_init(&s->synth);
ff_dcadsp_init(&s->dcadsp);
DCAContext *s = avctx->priv_data;
ff_mdct_end(&s->imdct);
av_freep(&s->extra_channels_buffer);
+ av_freep(&s->fdsp);
return 0;
}
};
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 },
+ { "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 },
};
*/
#include "config.h"
+
#include "libavutil/attributes.h"
#include "libavutil/intreadwrite.h"
+
#include "dcadsp.h"
static void decode_hf_c(float dst[DCA_SUBBANDS][8],
}
}
-static inline void
-dca_lfe_fir(float *out, const float *in, const float *coefs,
- int decifactor)
+static inline void dca_lfe_fir(float *out, const float *in, const float *coefs,
+ int decifactor)
{
float *out2 = out + 2 * decifactor - 1;
int num_coeffs = 256 / decifactor;
float v0 = 0.0;
float v1 = 0.0;
for (j = 0; j < num_coeffs; j++, coefs++) {
- v0 += in[-j] * *coefs;
+ v0 += in[-j] * *coefs;
v1 += in[j + 1 - num_coeffs] * *coefs;
}
*out++ = v0;
}
synth->synth_filter_float(imdct, synth_buf_ptr, synth_buf_offset,
- synth_buf2, window, samples_out, raXin, scale);
+ synth_buf2, window, samples_out, raXin,
+ scale);
samples_out += 32;
}
}
av_cold void ff_dcadsp_init(DCADSPContext *s)
{
- s->lfe_fir[0] = dca_lfe_fir0_c;
- s->lfe_fir[1] = dca_lfe_fir1_c;
+ s->lfe_fir[0] = dca_lfe_fir0_c;
+ s->lfe_fir[1] = dca_lfe_fir1_c;
s->qmf_32_subbands = dca_qmf_32_subbands;
- s->decode_hf = decode_hf_c;
- if (ARCH_ARM) ff_dcadsp_init_arm(s);
- if (ARCH_X86) ff_dcadsp_init_x86(s);
+ s->decode_hf = decode_hf_c;
+
+ if (ARCH_ARM)
+ ff_dcadsp_init_arm(s);
+ if (ARCH_X86)
+ ff_dcadsp_init_x86(s);
}
#define TMODE_COUNT 4
static const uint8_t tmode_vlc_bits[TMODE_COUNT] = { 3, 3, 3, 2 };
static const uint16_t tmode_codes[TMODE_COUNT][4] = {
- { 0x0000, 0x0002, 0x0006, 0x0007 },
- { 0x0002, 0x0006, 0x0007, 0x0000 },
- { 0x0006, 0x0007, 0x0000, 0x0002 },
- { 0x0000, 0x0001, 0x0002, 0x0003 }
+ { 0x0000, 0x0002, 0x0006, 0x0007 },
+ { 0x0002, 0x0006, 0x0007, 0x0000 },
+ { 0x0006, 0x0007, 0x0000, 0x0002 },
+ { 0x0000, 0x0001, 0x0002, 0x0003 }
};
+
static const uint8_t tmode_bits[TMODE_COUNT][4] = {
- { 1, 2, 3, 3 },
- { 2, 3, 3, 1 },
- { 3, 3, 1, 2 },
- { 2, 2, 2, 2 }
+ { 1, 2, 3, 3 },
+ { 2, 3, 3, 1 },
+ { 3, 3, 1, 2 },
+ { 2, 2, 2, 2 }
};
-
-#define BITALLOC_12_COUNT 5
+#define BITALLOC_12_COUNT 5
#define BITALLOC_12_VLC_BITS 9
static const uint8_t bitalloc_12_vlc_bits[BITALLOC_12_COUNT] = {
- 9, 7, 7, 9, 9
+ 9, 7, 7, 9, 9
};
+
static const uint16_t bitalloc_12_codes[BITALLOC_12_COUNT][12] = {
- {
- 0x0000, 0x0002, 0x0006, 0x000E, 0x001E, 0x003E, 0x00FF, 0x00FE,
- 0x01FB, 0x01FA, 0x01F9, 0x01F8,
- },
- {
- 0x0001, 0x0000, 0x0002, 0x000F, 0x000C, 0x001D, 0x0039, 0x0038,
- 0x0037, 0x0036, 0x0035, 0x0034,
- },
- {
- 0x0000, 0x0007, 0x0005, 0x0004, 0x0002, 0x000D, 0x000C, 0x0006,
- 0x000F, 0x001D, 0x0039, 0x0038,
- },
- {
- 0x0003, 0x0002, 0x0000, 0x0002, 0x0006, 0x000E, 0x001E, 0x003E,
- 0x007E, 0x00FE, 0x01FF, 0x01FE,
- },
- {
- 0x0001, 0x0000, 0x0002, 0x0006, 0x000E, 0x003F, 0x003D, 0x007C,
- 0x0079, 0x0078, 0x00FB, 0x00FA,
- }
+ { 0x0000, 0x0002, 0x0006, 0x000E, 0x001E, 0x003E, 0x00FF, 0x00FE,
+ 0x01FB, 0x01FA, 0x01F9, 0x01F8, },
+ { 0x0001, 0x0000, 0x0002, 0x000F, 0x000C, 0x001D, 0x0039, 0x0038,
+ 0x0037, 0x0036, 0x0035, 0x0034, },
+ { 0x0000, 0x0007, 0x0005, 0x0004, 0x0002, 0x000D, 0x000C, 0x0006,
+ 0x000F, 0x001D, 0x0039, 0x0038, },
+ { 0x0003, 0x0002, 0x0000, 0x0002, 0x0006, 0x000E, 0x001E, 0x003E,
+ 0x007E, 0x00FE, 0x01FF, 0x01FE, },
+ { 0x0001, 0x0000, 0x0002, 0x0006, 0x000E, 0x003F, 0x003D, 0x007C,
+ 0x0079, 0x0078, 0x00FB, 0x00FA, }
};
+
static const uint8_t bitalloc_12_bits[BITALLOC_12_COUNT][12] = {
- { 1, 2, 3, 4, 5, 6, 8, 8, 9, 9, 9, 9 },
- { 1, 2, 3, 5, 5, 6, 7, 7, 7, 7, 7, 7 },
- { 2, 3, 3, 3, 3, 4, 4, 4, 5, 6, 7, 7 },
- { 2, 2, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10 },
- { 1, 2, 3, 4, 5, 7, 7, 8, 8, 8, 9, 9 }
+ { 1, 2, 3, 4, 5, 6, 8, 8, 9, 9, 9, 9 },
+ { 1, 2, 3, 5, 5, 6, 7, 7, 7, 7, 7, 7 },
+ { 2, 3, 3, 3, 3, 4, 4, 4, 5, 6, 7, 7 },
+ { 2, 2, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10 },
+ { 1, 2, 3, 4, 5, 7, 7, 8, 8, 8, 9, 9 }
};
-
-#define SCALES_COUNT 5
+#define SCALES_COUNT 5
#define SCALES_VLC_BITS 9
static const uint16_t scales_codes[SCALES_COUNT][129] = {
- {
- 0x3AB0, 0x3AB2, 0x3AB4, 0x3AB6, 0x3AB8, 0x3ABA, 0x3ABC, 0x3ABE,
- 0x3AC0, 0x3AC2, 0x3AC4, 0x3AC6, 0x3AC8, 0x3ACA, 0x3ACC, 0x3ACE,
- 0x3AD0, 0x3AD2, 0x3AD4, 0x3AD6, 0x3AD8, 0x3ADA, 0x3ADC, 0x3ADE,
- 0x3AE0, 0x3AE2, 0x3AE4, 0x3AE6, 0x3AE8, 0x3AEA, 0x3AEC, 0x3AEE,
- 0x3AF0, 0x3AF2, 0x3AF4, 0x3AF6, 0x3AF8, 0x3AFA, 0x3AFC, 0x3AFE,
- 0x0540, 0x0542, 0x0544, 0x0546, 0x0548, 0x054A, 0x054C, 0x054E,
- 0x0558, 0x055E, 0x02AD, 0x0154, 0x0754, 0x03A8, 0x0056, 0x0028,
- 0x00E8, 0x004A, 0x000B, 0x003B, 0x0013, 0x0003, 0x000F, 0x0005,
- 0x0001, 0x0006, 0x0000, 0x0008, 0x001C, 0x0004, 0x0024, 0x004B,
- 0x00E9, 0x0029, 0x0057, 0x03A9, 0x0755, 0x0155, 0x02AE, 0x055F,
- 0x0559, 0x054F, 0x054D, 0x054B, 0x0549, 0x0547, 0x0545, 0x0543,
- 0x0541, 0x3AFF, 0x3AFD, 0x3AFB, 0x3AF9, 0x3AF7, 0x3AF5, 0x3AF3,
- 0x3AF1, 0x3AEF, 0x3AED, 0x3AEB, 0x3AE9, 0x3AE7, 0x3AE5, 0x3AE3,
- 0x3AE1, 0x3ADF, 0x3ADD, 0x3ADB, 0x3AD9, 0x3AD7, 0x3AD5, 0x3AD3,
- 0x3AD1, 0x3ACF, 0x3ACD, 0x3ACB, 0x3AC9, 0x3AC7, 0x3AC5, 0x3AC3,
- 0x3AC1, 0x3ABF, 0x3ABD, 0x3ABB, 0x3AB9, 0x3AB7, 0x3AB5, 0x3AB3,
- 0x3AB1,
- },
- {
- 0x0F60, 0x0F62, 0x0F64, 0x0F66, 0x0F68, 0x0F6A, 0x0F6C, 0x0F6E,
- 0x0F70, 0x0F72, 0x0F74, 0x0F76, 0x0F78, 0x0F7A, 0x0F7C, 0x0F7E,
- 0x0F80, 0x0F82, 0x0F84, 0x0F86, 0x0F88, 0x0F8A, 0x0F8C, 0x0F8E,
- 0x0F90, 0x0F92, 0x0F94, 0x0F96, 0x0F98, 0x0F9A, 0x0F9C, 0x0F9E,
- 0x0FA0, 0x0FA2, 0x0FA4, 0x0FA6, 0x0FA8, 0x0FAA, 0x0FAC, 0x0FAE,
- 0x0FB0, 0x0FB2, 0x0FB4, 0x0FB6, 0x0FB8, 0x0FBA, 0x0FBC, 0x0FBE,
- 0x07A0, 0x07A2, 0x03D2, 0x01EA, 0x00FC, 0x007F, 0x001C, 0x000C,
- 0x0004, 0x0034, 0x0010, 0x001B, 0x0009, 0x000B, 0x000E, 0x0001,
- 0x0003, 0x0002, 0x000F, 0x000C, 0x000A, 0x0000, 0x0011, 0x0035,
- 0x0005, 0x000D, 0x001D, 0x003C, 0x00FD, 0x01EB, 0x03D3, 0x07A3,
- 0x07A1, 0x0FBF, 0x0FBD, 0x0FBB, 0x0FB9, 0x0FB7, 0x0FB5, 0x0FB3,
- 0x0FB1, 0x0FAF, 0x0FAD, 0x0FAB, 0x0FA9, 0x0FA7, 0x0FA5, 0x0FA3,
- 0x0FA1, 0x0F9F, 0x0F9D, 0x0F9B, 0x0F99, 0x0F97, 0x0F95, 0x0F93,
- 0x0F91, 0x0F8F, 0x0F8D, 0x0F8B, 0x0F89, 0x0F87, 0x0F85, 0x0F83,
- 0x0F81, 0x0F7F, 0x0F7D, 0x0F7B, 0x0F79, 0x0F77, 0x0F75, 0x0F73,
- 0x0F71, 0x0F6F, 0x0F6D, 0x0F6B, 0x0F69, 0x0F67, 0x0F65, 0x0F63,
- 0x0F61,
- },
- {
- 0x51D0, 0x51D2, 0x51D4, 0x51D6, 0x51D8, 0x51DA, 0x51DC, 0x51DE,
- 0x51E0, 0x51E2, 0x51E4, 0x51E6, 0x51E8, 0x51EA, 0x51EC, 0x51EE,
- 0x51F0, 0x51F2, 0x51F4, 0x51F6, 0x51F8, 0x51FA, 0x51FC, 0x51FE,
- 0x70C0, 0x70C2, 0x70C4, 0x70C6, 0x70C8, 0x70CA, 0x70CC, 0x70CE,
- 0x70EC, 0x10EA, 0x3868, 0x3877, 0x0876, 0x1C35, 0x0434, 0x0A34,
- 0x0E1B, 0x021B, 0x051B, 0x070F, 0x010F, 0x0380, 0x0080, 0x0140,
- 0x01C1, 0x0041, 0x00A1, 0x00E2, 0x0022, 0x0052, 0x0072, 0x0012,
- 0x002A, 0x003A, 0x000A, 0x0016, 0x001E, 0x0006, 0x000C, 0x0000,
- 0x0004, 0x0001, 0x000D, 0x0007, 0x001F, 0x0017, 0x000B, 0x003B,
- 0x002B, 0x0013, 0x0073, 0x0053, 0x0023, 0x00E3, 0x00A2, 0x0042,
- 0x01C2, 0x0141, 0x0081, 0x0381, 0x028C, 0x010C, 0x051C, 0x021C,
- 0x0E1C, 0x0A35, 0x0435, 0x1C3A, 0x0877, 0x0874, 0x3869, 0x10EB,
- 0x70ED, 0x70CF, 0x70CD, 0x70CB, 0x70C9, 0x70C7, 0x70C5, 0x70C3,
- 0x70C1, 0x51FF, 0x51FD, 0x51FB, 0x51F9, 0x51F7, 0x51F5, 0x51F3,
- 0x51F1, 0x51EF, 0x51ED, 0x51EB, 0x51E9, 0x51E7, 0x51E5, 0x51E3,
- 0x51E1, 0x51DF, 0x51DD, 0x51DB, 0x51D9, 0x51D7, 0x51D5, 0x51D3,
- 0x51D1,
- },
- {
- 0x6F64, 0x6F66, 0x6F68, 0x6F6A, 0x6F6C, 0x6F6E, 0x6F70, 0x6F72,
- 0x6F74, 0x6F76, 0x6F78, 0x6F7A, 0x6F7C, 0x6F7E, 0x6F80, 0x6F82,
- 0x6F84, 0x6F86, 0x6F88, 0x6F8A, 0x6F8C, 0x6F8E, 0x6F90, 0x6F92,
- 0x6F94, 0x6F96, 0x6F98, 0x6F9A, 0x6F9C, 0x6F9E, 0x6FA0, 0x6FA2,
- 0x6FA4, 0x6FA6, 0x6FA8, 0x6FAA, 0x6FAC, 0x6FAE, 0x6FB0, 0x6FB2,
- 0x6FB4, 0x6FB6, 0x17B4, 0x37DC, 0x0BDB, 0x1BEF, 0x05EE, 0x0DF8,
- 0x02F8, 0x06FD, 0x017D, 0x037F, 0x00BF, 0x0040, 0x00C0, 0x0021,
- 0x0061, 0x0011, 0x0031, 0x0009, 0x0019, 0x0006, 0x000E, 0x0004,
- 0x0000, 0x0005, 0x000F, 0x0007, 0x001A, 0x000A, 0x0036, 0x0016,
- 0x006E, 0x002E, 0x00C1, 0x0041, 0x01BC, 0x00BC, 0x037A, 0x017A,
- 0x02F9, 0x0DF9, 0x05EF, 0x05EC, 0x1BD8, 0x37DD, 0x17B5, 0x6FB7,
- 0x6FB5, 0x6FB3, 0x6FB1, 0x6FAF, 0x6FAD, 0x6FAB, 0x6FA9, 0x6FA7,
- 0x6FA5, 0x6FA3, 0x6FA1, 0x6F9F, 0x6F9D, 0x6F9B, 0x6F99, 0x6F97,
- 0x6F95, 0x6F93, 0x6F91, 0x6F8F, 0x6F8D, 0x6F8B, 0x6F89, 0x6F87,
- 0x6F85, 0x6F83, 0x6F81, 0x6F7F, 0x6F7D, 0x6F7B, 0x6F79, 0x6F77,
- 0x6F75, 0x6F73, 0x6F71, 0x6F6F, 0x6F6D, 0x6F6B, 0x6F69, 0x6F67,
- 0x6F65,
- },
- {
- 0xDF54, 0xDF56, 0xDFC8, 0xDFCA, 0xDFCC, 0xDFCE, 0xDFD0, 0xDFD2,
- 0xDFD4, 0xDFD6, 0xDFD8, 0xDFDA, 0xDFDC, 0xDFDE, 0xDFE0, 0xDFE2,
- 0x0FE8, 0x2FEA, 0x6FA8, 0x6FF6, 0x07F5, 0x07F7, 0x37D2, 0x37F9,
- 0x03F8, 0x0BF8, 0x0BFB, 0x1BEB, 0x01FA, 0x05FA, 0x09FA, 0x0DFA,
- 0x0DFF, 0x00FF, 0x02FF, 0x06FB, 0x007C, 0x017C, 0x027C, 0x027F,
- 0x003C, 0x00BC, 0x013C, 0x01BC, 0x001C, 0x005C, 0x009C, 0x00DC,
- 0x000C, 0x002C, 0x004C, 0x006C, 0x0004, 0x0014, 0x0024, 0x0034,
- 0x0000, 0x0008, 0x0010, 0x0018, 0x001E, 0x0002, 0x0006, 0x000A,
- 0x000E, 0x000B, 0x0007, 0x0003, 0x001F, 0x0019, 0x0011, 0x0009,
- 0x0001, 0x0035, 0x0025, 0x0015, 0x0005, 0x006D, 0x004D, 0x002D,
- 0x000D, 0x00DD, 0x009D, 0x005D, 0x001D, 0x01BD, 0x013D, 0x00BD,
- 0x003D, 0x037C, 0x027D, 0x017D, 0x007D, 0x06FC, 0x04FC, 0x02FC,
- 0x00FC, 0x0DFB, 0x09FB, 0x05FB, 0x01FB, 0x1BF8, 0x1BE8, 0x0BF9,
- 0x03F9, 0x37FA, 0x37D3, 0x17F4, 0x07F6, 0x6FF7, 0x6FA9, 0x2FEB,
- 0x0FE9, 0xDFE3, 0xDFE1, 0xDFDF, 0xDFDD, 0xDFDB, 0xDFD9, 0xDFD7,
- 0xDFD5, 0xDFD3, 0xDFD1, 0xDFCF, 0xDFCD, 0xDFCB, 0xDFC9, 0xDF57,
- 0xDF55,
- }
+ { 0x3AB0, 0x3AB2, 0x3AB4, 0x3AB6, 0x3AB8, 0x3ABA, 0x3ABC, 0x3ABE,
+ 0x3AC0, 0x3AC2, 0x3AC4, 0x3AC6, 0x3AC8, 0x3ACA, 0x3ACC, 0x3ACE,
+ 0x3AD0, 0x3AD2, 0x3AD4, 0x3AD6, 0x3AD8, 0x3ADA, 0x3ADC, 0x3ADE,
+ 0x3AE0, 0x3AE2, 0x3AE4, 0x3AE6, 0x3AE8, 0x3AEA, 0x3AEC, 0x3AEE,
+ 0x3AF0, 0x3AF2, 0x3AF4, 0x3AF6, 0x3AF8, 0x3AFA, 0x3AFC, 0x3AFE,
+ 0x0540, 0x0542, 0x0544, 0x0546, 0x0548, 0x054A, 0x054C, 0x054E,
+ 0x0558, 0x055E, 0x02AD, 0x0154, 0x0754, 0x03A8, 0x0056, 0x0028,
+ 0x00E8, 0x004A, 0x000B, 0x003B, 0x0013, 0x0003, 0x000F, 0x0005,
+ 0x0001, 0x0006, 0x0000, 0x0008, 0x001C, 0x0004, 0x0024, 0x004B,
+ 0x00E9, 0x0029, 0x0057, 0x03A9, 0x0755, 0x0155, 0x02AE, 0x055F,
+ 0x0559, 0x054F, 0x054D, 0x054B, 0x0549, 0x0547, 0x0545, 0x0543,
+ 0x0541, 0x3AFF, 0x3AFD, 0x3AFB, 0x3AF9, 0x3AF7, 0x3AF5, 0x3AF3,
+ 0x3AF1, 0x3AEF, 0x3AED, 0x3AEB, 0x3AE9, 0x3AE7, 0x3AE5, 0x3AE3,
+ 0x3AE1, 0x3ADF, 0x3ADD, 0x3ADB, 0x3AD9, 0x3AD7, 0x3AD5, 0x3AD3,
+ 0x3AD1, 0x3ACF, 0x3ACD, 0x3ACB, 0x3AC9, 0x3AC7, 0x3AC5, 0x3AC3,
+ 0x3AC1, 0x3ABF, 0x3ABD, 0x3ABB, 0x3AB9, 0x3AB7, 0x3AB5, 0x3AB3,
+ 0x3AB1, },
+ { 0x0F60, 0x0F62, 0x0F64, 0x0F66, 0x0F68, 0x0F6A, 0x0F6C, 0x0F6E,
+ 0x0F70, 0x0F72, 0x0F74, 0x0F76, 0x0F78, 0x0F7A, 0x0F7C, 0x0F7E,
+ 0x0F80, 0x0F82, 0x0F84, 0x0F86, 0x0F88, 0x0F8A, 0x0F8C, 0x0F8E,
+ 0x0F90, 0x0F92, 0x0F94, 0x0F96, 0x0F98, 0x0F9A, 0x0F9C, 0x0F9E,
+ 0x0FA0, 0x0FA2, 0x0FA4, 0x0FA6, 0x0FA8, 0x0FAA, 0x0FAC, 0x0FAE,
+ 0x0FB0, 0x0FB2, 0x0FB4, 0x0FB6, 0x0FB8, 0x0FBA, 0x0FBC, 0x0FBE,
+ 0x07A0, 0x07A2, 0x03D2, 0x01EA, 0x00FC, 0x007F, 0x001C, 0x000C,
+ 0x0004, 0x0034, 0x0010, 0x001B, 0x0009, 0x000B, 0x000E, 0x0001,
+ 0x0003, 0x0002, 0x000F, 0x000C, 0x000A, 0x0000, 0x0011, 0x0035,
+ 0x0005, 0x000D, 0x001D, 0x003C, 0x00FD, 0x01EB, 0x03D3, 0x07A3,
+ 0x07A1, 0x0FBF, 0x0FBD, 0x0FBB, 0x0FB9, 0x0FB7, 0x0FB5, 0x0FB3,
+ 0x0FB1, 0x0FAF, 0x0FAD, 0x0FAB, 0x0FA9, 0x0FA7, 0x0FA5, 0x0FA3,
+ 0x0FA1, 0x0F9F, 0x0F9D, 0x0F9B, 0x0F99, 0x0F97, 0x0F95, 0x0F93,
+ 0x0F91, 0x0F8F, 0x0F8D, 0x0F8B, 0x0F89, 0x0F87, 0x0F85, 0x0F83,
+ 0x0F81, 0x0F7F, 0x0F7D, 0x0F7B, 0x0F79, 0x0F77, 0x0F75, 0x0F73,
+ 0x0F71, 0x0F6F, 0x0F6D, 0x0F6B, 0x0F69, 0x0F67, 0x0F65, 0x0F63,
+ 0x0F61, },
+ { 0x51D0, 0x51D2, 0x51D4, 0x51D6, 0x51D8, 0x51DA, 0x51DC, 0x51DE,
+ 0x51E0, 0x51E2, 0x51E4, 0x51E6, 0x51E8, 0x51EA, 0x51EC, 0x51EE,
+ 0x51F0, 0x51F2, 0x51F4, 0x51F6, 0x51F8, 0x51FA, 0x51FC, 0x51FE,
+ 0x70C0, 0x70C2, 0x70C4, 0x70C6, 0x70C8, 0x70CA, 0x70CC, 0x70CE,
+ 0x70EC, 0x10EA, 0x3868, 0x3877, 0x0876, 0x1C35, 0x0434, 0x0A34,
+ 0x0E1B, 0x021B, 0x051B, 0x070F, 0x010F, 0x0380, 0x0080, 0x0140,
+ 0x01C1, 0x0041, 0x00A1, 0x00E2, 0x0022, 0x0052, 0x0072, 0x0012,
+ 0x002A, 0x003A, 0x000A, 0x0016, 0x001E, 0x0006, 0x000C, 0x0000,
+ 0x0004, 0x0001, 0x000D, 0x0007, 0x001F, 0x0017, 0x000B, 0x003B,
+ 0x002B, 0x0013, 0x0073, 0x0053, 0x0023, 0x00E3, 0x00A2, 0x0042,
+ 0x01C2, 0x0141, 0x0081, 0x0381, 0x028C, 0x010C, 0x051C, 0x021C,
+ 0x0E1C, 0x0A35, 0x0435, 0x1C3A, 0x0877, 0x0874, 0x3869, 0x10EB,
+ 0x70ED, 0x70CF, 0x70CD, 0x70CB, 0x70C9, 0x70C7, 0x70C5, 0x70C3,
+ 0x70C1, 0x51FF, 0x51FD, 0x51FB, 0x51F9, 0x51F7, 0x51F5, 0x51F3,
+ 0x51F1, 0x51EF, 0x51ED, 0x51EB, 0x51E9, 0x51E7, 0x51E5, 0x51E3,
+ 0x51E1, 0x51DF, 0x51DD, 0x51DB, 0x51D9, 0x51D7, 0x51D5, 0x51D3,
+ 0x51D1, },
+ { 0x6F64, 0x6F66, 0x6F68, 0x6F6A, 0x6F6C, 0x6F6E, 0x6F70, 0x6F72,
+ 0x6F74, 0x6F76, 0x6F78, 0x6F7A, 0x6F7C, 0x6F7E, 0x6F80, 0x6F82,
+ 0x6F84, 0x6F86, 0x6F88, 0x6F8A, 0x6F8C, 0x6F8E, 0x6F90, 0x6F92,
+ 0x6F94, 0x6F96, 0x6F98, 0x6F9A, 0x6F9C, 0x6F9E, 0x6FA0, 0x6FA2,
+ 0x6FA4, 0x6FA6, 0x6FA8, 0x6FAA, 0x6FAC, 0x6FAE, 0x6FB0, 0x6FB2,
+ 0x6FB4, 0x6FB6, 0x17B4, 0x37DC, 0x0BDB, 0x1BEF, 0x05EE, 0x0DF8,
+ 0x02F8, 0x06FD, 0x017D, 0x037F, 0x00BF, 0x0040, 0x00C0, 0x0021,
+ 0x0061, 0x0011, 0x0031, 0x0009, 0x0019, 0x0006, 0x000E, 0x0004,
+ 0x0000, 0x0005, 0x000F, 0x0007, 0x001A, 0x000A, 0x0036, 0x0016,
+ 0x006E, 0x002E, 0x00C1, 0x0041, 0x01BC, 0x00BC, 0x037A, 0x017A,
+ 0x02F9, 0x0DF9, 0x05EF, 0x05EC, 0x1BD8, 0x37DD, 0x17B5, 0x6FB7,
+ 0x6FB5, 0x6FB3, 0x6FB1, 0x6FAF, 0x6FAD, 0x6FAB, 0x6FA9, 0x6FA7,
+ 0x6FA5, 0x6FA3, 0x6FA1, 0x6F9F, 0x6F9D, 0x6F9B, 0x6F99, 0x6F97,
+ 0x6F95, 0x6F93, 0x6F91, 0x6F8F, 0x6F8D, 0x6F8B, 0x6F89, 0x6F87,
+ 0x6F85, 0x6F83, 0x6F81, 0x6F7F, 0x6F7D, 0x6F7B, 0x6F79, 0x6F77,
+ 0x6F75, 0x6F73, 0x6F71, 0x6F6F, 0x6F6D, 0x6F6B, 0x6F69, 0x6F67,
+ 0x6F65, },
+ { 0xDF54, 0xDF56, 0xDFC8, 0xDFCA, 0xDFCC, 0xDFCE, 0xDFD0, 0xDFD2,
+ 0xDFD4, 0xDFD6, 0xDFD8, 0xDFDA, 0xDFDC, 0xDFDE, 0xDFE0, 0xDFE2,
+ 0x0FE8, 0x2FEA, 0x6FA8, 0x6FF6, 0x07F5, 0x07F7, 0x37D2, 0x37F9,
+ 0x03F8, 0x0BF8, 0x0BFB, 0x1BEB, 0x01FA, 0x05FA, 0x09FA, 0x0DFA,
+ 0x0DFF, 0x00FF, 0x02FF, 0x06FB, 0x007C, 0x017C, 0x027C, 0x027F,
+ 0x003C, 0x00BC, 0x013C, 0x01BC, 0x001C, 0x005C, 0x009C, 0x00DC,
+ 0x000C, 0x002C, 0x004C, 0x006C, 0x0004, 0x0014, 0x0024, 0x0034,
+ 0x0000, 0x0008, 0x0010, 0x0018, 0x001E, 0x0002, 0x0006, 0x000A,
+ 0x000E, 0x000B, 0x0007, 0x0003, 0x001F, 0x0019, 0x0011, 0x0009,
+ 0x0001, 0x0035, 0x0025, 0x0015, 0x0005, 0x006D, 0x004D, 0x002D,
+ 0x000D, 0x00DD, 0x009D, 0x005D, 0x001D, 0x01BD, 0x013D, 0x00BD,
+ 0x003D, 0x037C, 0x027D, 0x017D, 0x007D, 0x06FC, 0x04FC, 0x02FC,
+ 0x00FC, 0x0DFB, 0x09FB, 0x05FB, 0x01FB, 0x1BF8, 0x1BE8, 0x0BF9,
+ 0x03F9, 0x37FA, 0x37D3, 0x17F4, 0x07F6, 0x6FF7, 0x6FA9, 0x2FEB,
+ 0x0FE9, 0xDFE3, 0xDFE1, 0xDFDF, 0xDFDD, 0xDFDB, 0xDFD9, 0xDFD7,
+ 0xDFD5, 0xDFD3, 0xDFD1, 0xDFCF, 0xDFCD, 0xDFCB, 0xDFC9, 0xDF57,
+ 0xDF55, }
};
static const uint8_t scales_bits[SCALES_COUNT][129] = {
- {
- 14, 14, 14, 14, 14, 14, 14, 14,
- 14, 14, 14, 14, 14, 14, 14, 14,
- 14, 14, 14, 14, 14, 14, 14, 14,
- 14, 14, 14, 14, 14, 14, 14, 14,
- 14, 14, 14, 14, 14, 14, 14, 14,
- 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 12, 11, 11, 10, 9, 8,
- 8, 7, 6, 6, 5, 4, 4, 3,
- 2, 3, 3, 4, 5, 5, 6, 7,
- 8, 8, 9, 10, 11, 11, 12, 13,
- 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 14, 14, 14, 14, 14, 14, 14,
- 14, 14, 14, 14, 14, 14, 14, 14,
- 14, 14, 14, 14, 14, 14, 14, 14,
- 14, 14, 14, 14, 14, 14, 14, 14,
- 14, 14, 14, 14, 14, 14, 14, 14,
- 14,
- },
- {
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 14, 14, 13, 12, 11, 10, 8, 7,
- 6, 6, 5, 5, 4, 4, 4, 3,
- 3, 3, 4, 4, 4, 4, 5, 6,
- 6, 7, 8, 9, 11, 12, 13, 14,
- 14, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15,
- },
- {
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 14, 14, 14, 13, 13, 12, 12,
- 12, 11, 11, 11, 10, 10, 9, 9,
- 9, 8, 8, 8, 7, 7, 7, 6,
- 6, 6, 5, 5, 5, 4, 4, 3,
- 3, 3, 4, 4, 5, 5, 5, 6,
- 6, 6, 7, 7, 7, 8, 8, 8,
- 9, 9, 9, 10, 10, 10, 11, 11,
- 12, 12, 12, 13, 13, 13, 14, 14,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15,
- },
- {
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 14, 14, 13, 13, 12, 12,
- 11, 11, 10, 10, 9, 8, 8, 7,
- 7, 6, 6, 5, 5, 4, 4, 3,
- 2, 3, 4, 4, 5, 5, 6, 6,
- 7, 7, 8, 8, 9, 9, 10, 10,
- 11, 12, 12, 12, 13, 14, 14, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15,
- },
- {
- 16, 16, 16, 16, 16, 16, 16, 16,
- 16, 16, 16, 16, 16, 16, 16, 16,
- 15, 15, 15, 15, 14, 14, 14, 14,
- 13, 13, 13, 13, 12, 12, 12, 12,
- 12, 11, 11, 11, 10, 10, 10, 10,
- 9, 9, 9, 9, 8, 8, 8, 8,
- 7, 7, 7, 7, 6, 6, 6, 6,
- 5, 5, 5, 5, 5, 4, 4, 4,
- 4, 4, 4, 4, 5, 5, 5, 5,
- 5, 6, 6, 6, 6, 7, 7, 7,
- 7, 8, 8, 8, 8, 9, 9, 9,
- 9, 10, 10, 10, 10, 11, 11, 11,
- 11, 12, 12, 12, 12, 13, 13, 13,
- 13, 14, 14, 14, 14, 15, 15, 15,
- 15, 16, 16, 16, 16, 16, 16, 16,
- 16, 16, 16, 16, 16, 16, 16, 16,
- 16,
- }
+ { 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 12, 11, 11, 10, 9, 8,
+ 8, 7, 6, 6, 5, 4, 4, 3,
+ 2, 3, 3, 4, 5, 5, 6, 7,
+ 8, 8, 9, 10, 11, 11, 12, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, },
+ { 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 14, 14, 13, 12, 11, 10, 8, 7,
+ 6, 6, 5, 5, 4, 4, 4, 3,
+ 3, 3, 4, 4, 4, 4, 5, 6,
+ 6, 7, 8, 9, 11, 12, 13, 14,
+ 14, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, },
+ { 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 14, 14, 14, 13, 13, 12, 12,
+ 12, 11, 11, 11, 10, 10, 9, 9,
+ 9, 8, 8, 8, 7, 7, 7, 6,
+ 6, 6, 5, 5, 5, 4, 4, 3,
+ 3, 3, 4, 4, 5, 5, 5, 6,
+ 6, 6, 7, 7, 7, 8, 8, 8,
+ 9, 9, 9, 10, 10, 10, 11, 11,
+ 12, 12, 12, 13, 13, 13, 14, 14,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, },
+ { 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 14, 14, 13, 13, 12, 12,
+ 11, 11, 10, 10, 9, 8, 8, 7,
+ 7, 6, 6, 5, 5, 4, 4, 3,
+ 2, 3, 4, 4, 5, 5, 6, 6,
+ 7, 7, 8, 8, 9, 9, 10, 10,
+ 11, 12, 12, 12, 13, 14, 14, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, },
+ { 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 15, 15, 15, 15, 14, 14, 14, 14,
+ 13, 13, 13, 13, 12, 12, 12, 12,
+ 12, 11, 11, 11, 10, 10, 10, 10,
+ 9, 9, 9, 9, 8, 8, 8, 8,
+ 7, 7, 7, 7, 6, 6, 6, 6,
+ 5, 5, 5, 5, 5, 4, 4, 4,
+ 4, 4, 4, 4, 5, 5, 5, 5,
+ 5, 6, 6, 6, 6, 7, 7, 7,
+ 7, 8, 8, 8, 8, 9, 9, 9,
+ 9, 10, 10, 10, 10, 11, 11, 11,
+ 11, 12, 12, 12, 12, 13, 13, 13,
+ 13, 14, 14, 14, 14, 15, 15, 15,
+ 15, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16,
+ }
};
-static const uint16_t bitalloc_3_codes[3] =
-{
+static const uint16_t bitalloc_3_codes[3] = {
0x0003, 0x0000, 0x0002,
};
-static const uint8_t bitalloc_3_bits[3] =
-{
- 2, 1, 2,
+
+static const uint8_t bitalloc_3_bits[3] = {
+ 2, 1, 2,
};
-static const uint16_t bitalloc_5_codes_a[5] =
-{
+static const uint16_t bitalloc_5_codes_a[5] = {
0x000F, 0x0006, 0x0000, 0x0002, 0x000E,
};
-static const uint16_t bitalloc_5_codes_b[5] =
-{
+
+static const uint16_t bitalloc_5_codes_b[5] = {
0x0007, 0x0001, 0x0002, 0x0000, 0x0006,
};
-static const uint16_t bitalloc_5_codes_c[5] =
-{
+
+static const uint16_t bitalloc_5_codes_c[5] = {
0x0007, 0x0005, 0x0000, 0x0004, 0x0006,
};
-static const uint8_t bitalloc_5_bits_a[5] =
-{
- 4, 3, 1, 2, 4,
+
+static const uint8_t bitalloc_5_bits_a[5] = {
+ 4, 3, 1, 2, 4,
};
-static const uint8_t bitalloc_5_bits_b[5] =
-{
- 3, 2, 2, 2, 3,
+
+static const uint8_t bitalloc_5_bits_b[5] = {
+ 3, 2, 2, 2, 3,
};
-static const uint8_t bitalloc_5_bits_c[5] =
-{
- 3, 3, 1, 3, 3,
+
+static const uint8_t bitalloc_5_bits_c[5] = {
+ 3, 3, 1, 3, 3,
};
-static const uint16_t bitalloc_7_codes_a[7] =
-{
+static const uint16_t bitalloc_7_codes_a[7] = {
0x001E, 0x000E, 0x0005, 0x0000, 0x0006, 0x0004, 0x001F,
};
-static const uint16_t bitalloc_7_codes_b[7] =
-{
+
+static const uint16_t bitalloc_7_codes_b[7] = {
0x0014, 0x000B, 0x0000, 0x0003, 0x0001, 0x0004, 0x0015,
};
-static const uint16_t bitalloc_7_codes_c[7] =
-{
+
+static const uint16_t bitalloc_7_codes_c[7] = {
0x0000, 0x0002, 0x0001, 0x0003, 0x0002, 0x0003, 0x0001,
};
-static const uint8_t bitalloc_7_bits_a[7] =
-{
- 5, 4, 3, 1, 3, 3, 5,
+
+static const uint8_t bitalloc_7_bits_a[7] = {
+ 5, 4, 3, 1, 3, 3, 5,
};
-static const uint8_t bitalloc_7_bits_b[7] =
-{
- 5, 4, 2, 2, 2, 3, 5,
+
+static const uint8_t bitalloc_7_bits_b[7] = {
+ 5, 4, 2, 2, 2, 3, 5,
};
-static const uint8_t bitalloc_7_bits_c[7] =
-{
- 4, 4, 2, 2, 2, 4, 4,
+
+static const uint8_t bitalloc_7_bits_c[7] = {
+ 4, 4, 2, 2, 2, 4, 4,
};
-static const uint16_t bitalloc_9_codes_a[9] =
-{
+static const uint16_t bitalloc_9_codes_a[9] = {
0x0030, 0x0019, 0x0009, 0x0005, 0x0000, 0x0007, 0x000D, 0x0008,
0x0031,
};
-static const uint16_t bitalloc_9_codes_b[9] =
-{
+
+static const uint16_t bitalloc_9_codes_b[9] = {
0x0018, 0x001A, 0x0002, 0x0007, 0x0002, 0x0000, 0x0003, 0x001B,
0x0019,
};
-static const uint16_t bitalloc_9_codes_c[9] =
-{
+
+static const uint16_t bitalloc_9_codes_c[9] = {
0x001C, 0x000F, 0x0002, 0x0007, 0x0002, 0x0000, 0x0006, 0x0006,
0x001D,
};
-static const uint8_t bitalloc_9_bits_a[9] =
-{
- 6, 5, 4, 3, 1, 3, 4, 4, 6,
+
+static const uint8_t bitalloc_9_bits_a[9] = {
+ 6, 5, 4, 3, 1, 3, 4, 4, 6,
};
-static const uint8_t bitalloc_9_bits_b[9] =
-{
- 5, 5, 3, 3, 2, 2, 3, 5, 5,
+
+static const uint8_t bitalloc_9_bits_b[9] = {
+ 5, 5, 3, 3, 2, 2, 3, 5, 5,
};
-static const uint8_t bitalloc_9_bits_c[9] =
-{
- 6, 5, 3, 3, 2, 2, 3, 4, 6,
+
+static const uint8_t bitalloc_9_bits_c[9] = {
+ 6, 5, 3, 3, 2, 2, 3, 4, 6,
};
-static const uint16_t bitalloc_13_codes_a[13] =
-{
+static const uint16_t bitalloc_13_codes_a[13] = {
0x0070, 0x002E, 0x0039, 0x001D, 0x000C, 0x000F, 0x0000, 0x0004,
0x000D, 0x000A, 0x0016, 0x002F, 0x0071,
};
-static const uint16_t bitalloc_13_codes_b[13] =
-{
+
+static const uint16_t bitalloc_13_codes_b[13] = {
0x0038, 0x0010, 0x001D, 0x0007, 0x000F, 0x0005, 0x0000, 0x0006,
0x0002, 0x0009, 0x0006, 0x0011, 0x0039,
};
-static const uint16_t bitalloc_13_codes_c[13] =
-{
+
+static const uint16_t bitalloc_13_codes_c[13] = {
0x0004, 0x001A, 0x0003, 0x000E, 0x0000, 0x0003, 0x0005, 0x0004,
0x0002, 0x000F, 0x000C, 0x001B, 0x0005,
};
-static const uint8_t bitalloc_13_bits_a[13] =
-{
+
+static const uint8_t bitalloc_13_bits_a[13] = {
7, 6, 6, 5, 4, 4, 1, 3, 4, 4, 5, 6, 7,
};
-static const uint8_t bitalloc_13_bits_b[13] =
-{
+
+static const uint8_t bitalloc_13_bits_b[13] = {
6, 5, 5, 4, 4, 3, 2, 3, 3, 4, 4, 5, 6,
};
-static const uint8_t bitalloc_13_bits_c[13] =
-{
+
+static const uint8_t bitalloc_13_bits_c[13] = {
5, 5, 4, 4, 3, 3, 3, 3, 3, 4, 4, 5, 5,
};
-static const uint16_t bitalloc_17_codes_a[17] =
-{
+static const uint16_t bitalloc_17_codes_a[17] = {
0x0154, 0x00AB, 0x002B, 0x000B, 0x0003, 0x000A, 0x0001, 0x0006,
0x0001, 0x0007, 0x0004, 0x000B, 0x0000, 0x0004, 0x0014, 0x0054,
0x0155,
};
-static const uint16_t bitalloc_17_codes_b[17] =
-{
+
+static const uint16_t bitalloc_17_codes_b[17] = {
0x007C, 0x003F, 0x0019, 0x000D, 0x001C, 0x0008, 0x000F, 0x0005,
0x0000, 0x0006, 0x0002, 0x0009, 0x001D, 0x000E, 0x001E, 0x0018,
0x007D,
};
-static const uint16_t bitalloc_17_codes_c[17] =
-{
+
+static const uint16_t bitalloc_17_codes_c[17] = {
0x002C, 0x0017, 0x0005, 0x001C, 0x0003, 0x000A, 0x000F, 0x0003,
0x0006, 0x0004, 0x0000, 0x000B, 0x0004, 0x001D, 0x000A, 0x0004,
0x002D,
};
-static const uint16_t bitalloc_17_codes_d[17] =
-{
+
+static const uint16_t bitalloc_17_codes_d[17] = {
0x0100, 0x0102, 0x0082, 0x0042, 0x0022, 0x0012, 0x000A, 0x0006,
0x0000, 0x0007, 0x000B, 0x0013, 0x0023, 0x0043, 0x0083, 0x0103,
0x0101,
};
-static const uint16_t bitalloc_17_codes_e[17] =
-{
+
+static const uint16_t bitalloc_17_codes_e[17] = {
0x00E8, 0x00F6, 0x0075, 0x0034, 0x003B, 0x001B, 0x001F, 0x0004,
0x0000, 0x0005, 0x000C, 0x001C, 0x003C, 0x0035, 0x007A, 0x00F7,
0x00E9,
};
-static const uint16_t bitalloc_17_codes_f[17] =
-{
+
+static const uint16_t bitalloc_17_codes_f[17] = {
0x0004, 0x0003, 0x001E, 0x0001, 0x0001, 0x000E, 0x0001, 0x0004,
0x0006, 0x0005, 0x0002, 0x000F, 0x0006, 0x000E, 0x001F, 0x0000,
0x0005,
};
-static const uint16_t bitalloc_17_codes_g[17] =
-{
+
+static const uint16_t bitalloc_17_codes_g[17] = {
0x0060, 0x007E, 0x0031, 0x0019, 0x000D, 0x0004, 0x0000, 0x0006,
0x0002, 0x0007, 0x0001, 0x0005, 0x000E, 0x001E, 0x003E, 0x007F,
0x0061,
};
-static const uint8_t bitalloc_17_bits_a[17] =
-{
+
+static const uint8_t bitalloc_17_bits_a[17] = {
12, 11, 9, 7, 5, 4, 3, 3, 2, 3, 3, 4, 4, 6, 8, 10,
12,
};
-static const uint8_t bitalloc_17_bits_b[17] =
-{
- 8, 7, 6, 5, 5, 4, 4, 3, 2, 3, 3, 4, 5, 5, 6, 6,
- 8,
+
+static const uint8_t bitalloc_17_bits_b[17] = {
+ 8, 7, 6, 5, 5, 4, 4, 3, 2, 3, 3, 4, 5, 5, 6, 6,
+ 8,
};
-static const uint8_t bitalloc_17_bits_c[17] =
-{
- 7, 6, 5, 5, 4, 4, 4, 3, 3, 3, 3, 4, 4, 5, 5, 5,
- 7,
+
+static const uint8_t bitalloc_17_bits_c[17] = {
+ 7, 6, 5, 5, 4, 4, 4, 3, 3, 3, 3, 4, 4, 5, 5, 5,
+ 7,
};
-static const uint8_t bitalloc_17_bits_d[17] =
-{
- 9, 9, 8, 7, 6, 5, 4, 3, 1, 3, 4, 5, 6, 7, 8, 9,
- 9,
+
+static const uint8_t bitalloc_17_bits_d[17] = {
+ 9, 9, 8, 7, 6, 5, 4, 3, 1, 3, 4, 5, 6, 7, 8, 9,
+ 9,
};
-static const uint8_t bitalloc_17_bits_e[17] =
-{
- 8, 8, 7, 6, 6, 5, 5, 3, 1, 3, 4, 5, 6, 6, 7, 8,
- 8,
+
+static const uint8_t bitalloc_17_bits_e[17] = {
+ 8, 8, 7, 6, 6, 5, 5, 3, 1, 3, 4, 5, 6, 6, 7, 8,
+ 8,
};
-static const uint8_t bitalloc_17_bits_f[17] =
-{
- 8, 7, 6, 5, 4, 4, 3, 3, 3, 3, 3, 4, 4, 5, 6, 6,
- 8,
+
+static const uint8_t bitalloc_17_bits_f[17] = {
+ 8, 7, 6, 5, 4, 4, 3, 3, 3, 3, 3, 4, 4, 5, 6, 6,
+ 8,
};
-static const uint8_t bitalloc_17_bits_g[17] =
-{
- 8, 8, 7, 6, 5, 4, 3, 3, 2, 3, 3, 4, 5, 6, 7, 8,
- 8,
+
+static const uint8_t bitalloc_17_bits_g[17] = {
+ 8, 8, 7, 6, 5, 4, 3, 3, 2, 3, 3, 4, 5, 6, 7, 8,
+ 8,
};
-static const uint16_t bitalloc_25_codes_a[25] =
-{
+static const uint16_t bitalloc_25_codes_a[25] = {
0x2854, 0x142B, 0x050B, 0x0143, 0x00A2, 0x0052, 0x002E, 0x0015,
0x0004, 0x000E, 0x0000, 0x0003, 0x0006, 0x0004, 0x0001, 0x000F,
0x0005, 0x0016, 0x002F, 0x0053, 0x00A3, 0x00A0, 0x0284, 0x0A14,
0x2855,
};
-static const uint16_t bitalloc_25_codes_b[25] =
-{
+
+static const uint16_t bitalloc_25_codes_b[25] = {
0x001C, 0x000F, 0x0005, 0x0000, 0x0030, 0x0036, 0x000E, 0x0019,
0x0001, 0x0008, 0x000E, 0x0001, 0x0005, 0x0002, 0x000F, 0x0009,
0x0006, 0x001A, 0x000F, 0x0037, 0x0031, 0x0001, 0x0006, 0x0004,
0x001D,
};
-static const uint16_t bitalloc_25_codes_c[25] =
-{
+
+static const uint16_t bitalloc_25_codes_c[25] = {
0x004C, 0x0027, 0x006D, 0x0028, 0x0037, 0x000E, 0x0015, 0x0000,
0x0005, 0x0008, 0x000B, 0x000E, 0x0001, 0x000F, 0x000C, 0x0009,
0x0006, 0x0001, 0x001A, 0x000F, 0x0008, 0x0029, 0x0012, 0x006C,
0x004D,
};
-static const uint16_t bitalloc_25_codes_d[25] =
-{
+
+static const uint16_t bitalloc_25_codes_d[25] = {
0x0780, 0x0782, 0x03C2, 0x01E2, 0x00FE, 0x0079, 0x003D, 0x001C,
0x000C, 0x0004, 0x0000, 0x0006, 0x0002, 0x0007, 0x0001, 0x0005,
0x000D, 0x001D, 0x003E, 0x007E, 0x00FF, 0x01E3, 0x03C3, 0x0783,
0x0781,
};
-static const uint16_t bitalloc_25_codes_e[25] =
-{
+
+static const uint16_t bitalloc_25_codes_e[25] = {
0x003C, 0x0092, 0x0018, 0x001F, 0x004E, 0x000D, 0x0025, 0x0004,
0x0010, 0x0000, 0x000A, 0x0002, 0x0003, 0x0003, 0x000B, 0x0001,
0x0011, 0x0005, 0x0026, 0x000E, 0x004F, 0x0048, 0x0019, 0x0093,
0x003D,
};
-static const uint16_t bitalloc_25_codes_f[25] =
-{
+
+static const uint16_t bitalloc_25_codes_f[25] = {
0x0324, 0x0193, 0x00CE, 0x0065, 0x0024, 0x000C, 0x0013, 0x0004,
0x0007, 0x000A, 0x000D, 0x000F, 0x0001, 0x0000, 0x000E, 0x000B,
0x0008, 0x0005, 0x0018, 0x000D, 0x0025, 0x0066, 0x00CF, 0x00C8,
0x0325,
};
-static const uint16_t bitalloc_25_codes_g[25] =
-{
+
+static const uint16_t bitalloc_25_codes_g[25] = {
0x03A8, 0x03AE, 0x01D5, 0x0094, 0x0014, 0x004B, 0x000B, 0x003B,
0x0013, 0x0003, 0x000F, 0x0005, 0x0001, 0x0006, 0x0000, 0x0008,
0x001C, 0x0004, 0x0024, 0x0074, 0x0015, 0x0095, 0x01D6, 0x03AF,
0x03A9,
};
-static const uint8_t bitalloc_25_bits_a[25] =
-{
+
+static const uint8_t bitalloc_25_bits_a[25] = {
14, 13, 11, 9, 8, 7, 6, 5, 4, 4, 3, 3, 3, 3, 3, 4,
4, 5, 6, 7, 8, 8, 10, 12, 14,
};
-static const uint8_t bitalloc_25_bits_b[25] =
-{
- 9, 8, 7, 6, 6, 6, 5, 5, 4, 4, 4, 3, 3, 3, 4, 4,
- 4, 5, 5, 6, 6, 6, 7, 7, 9,
+
+static const uint8_t bitalloc_25_bits_b[25] = {
+ 9, 8, 7, 6, 6, 6, 5, 5, 4, 4, 4, 3, 3, 3, 4, 4,
+ 4, 5, 5, 6, 6, 6, 7, 7, 9,
};
-static const uint8_t bitalloc_25_bits_c[25] =
-{
- 8, 7, 7, 6, 6, 5, 5, 4, 4, 4, 4, 4, 3, 4, 4, 4,
- 4, 4, 5, 5, 5, 6, 6, 7, 8,
+
+static const uint8_t bitalloc_25_bits_c[25] = {
+ 8, 7, 7, 6, 6, 5, 5, 4, 4, 4, 4, 4, 3, 4, 4, 4,
+ 4, 4, 5, 5, 5, 6, 6, 7, 8,
};
-static const uint8_t bitalloc_25_bits_d[25] =
-{
+
+static const uint8_t bitalloc_25_bits_d[25] = {
12, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 3, 2, 3, 3, 4,
5, 6, 7, 8, 9, 10, 11, 12, 12,
};
-static const uint8_t bitalloc_25_bits_e[25] =
-{
- 8, 8, 7, 7, 7, 6, 6, 5, 5, 4, 4, 3, 2, 3, 4, 4,
- 5, 5, 6, 6, 7, 7, 7, 8, 8,
+
+static const uint8_t bitalloc_25_bits_e[25] = {
+ 8, 8, 7, 7, 7, 6, 6, 5, 5, 4, 4, 3, 2, 3, 4, 4,
+ 5, 5, 6, 6, 7, 7, 7, 8, 8,
};
-static const uint8_t bitalloc_25_bits_f[25] =
-{
+
+static const uint8_t bitalloc_25_bits_f[25] = {
10, 9, 8, 7, 6, 5, 5, 4, 4, 4, 4, 4, 3, 3, 4, 4,
4, 4, 5, 5, 6, 7, 8, 8, 10,
};
-static const uint8_t bitalloc_25_bits_g[25] =
-{
+
+static const uint8_t bitalloc_25_bits_g[25] = {
10, 10, 9, 8, 7, 7, 6, 6, 5, 4, 4, 3, 2, 3, 3, 4,
5, 5, 6, 7, 7, 8, 9, 10, 10,
};
-static const uint16_t bitalloc_33_codes_a[33] =
-{
+static const uint16_t bitalloc_33_codes_a[33] = {
0x1580, 0x1582, 0x0AC2, 0x0562, 0x02B2, 0x015E, 0x00AD, 0x0054,
0x001C, 0x003C, 0x000F, 0x001F, 0x0008, 0x000B, 0x000D, 0x0000,
0x0002, 0x0001, 0x000E, 0x000C, 0x0009, 0x0006, 0x0014, 0x003D,
0x001D, 0x0055, 0x00AE, 0x015F, 0x02B3, 0x0563, 0x0AC3, 0x1583,
0x1581,
};
-static const uint16_t bitalloc_33_codes_b[33] =
-{
+
+static const uint16_t bitalloc_33_codes_b[33] = {
0x030C, 0x0187, 0x006D, 0x0028, 0x0037, 0x0066, 0x0015, 0x0031,
0x0000, 0x000B, 0x0012, 0x001A, 0x0001, 0x0007, 0x000A, 0x000E,
0x0001, 0x000F, 0x000B, 0x0008, 0x0004, 0x001B, 0x0013, 0x000C,
0x0001, 0x0032, 0x001A, 0x0067, 0x0060, 0x0029, 0x00C2, 0x006C,
0x030D,
};
-static const uint16_t bitalloc_33_codes_c[33] =
-{
+
+static const uint16_t bitalloc_33_codes_c[33] = {
0x00CC, 0x0067, 0x0005, 0x0070, 0x0003, 0x001A, 0x0039, 0x003F,
0x000A, 0x0012, 0x0018, 0x001D, 0x0001, 0x0003, 0x0007, 0x000A,
0x000D, 0x000B, 0x0008, 0x0004, 0x0002, 0x001E, 0x0019, 0x0013,
0x000B, 0x0000, 0x003E, 0x001B, 0x0018, 0x0071, 0x0032, 0x0004,
0x00CD,
};
-static const uint16_t bitalloc_33_codes_d[33] =
-{
+
+static const uint16_t bitalloc_33_codes_d[33] = {
0x3AF8, 0x3AFA, 0x1D7E, 0x0EBC, 0x075C, 0x03AC, 0x01D4, 0x0094,
0x0014, 0x004B, 0x000B, 0x003B, 0x0013, 0x0003, 0x000F, 0x0005,
0x0001, 0x0006, 0x0000, 0x0008, 0x001C, 0x0004, 0x0024, 0x0074,
0x0015, 0x0095, 0x01D5, 0x03AD, 0x075D, 0x0EBD, 0x1D7F, 0x3AFB,
0x3AF9,
};
-static const uint16_t bitalloc_33_codes_e[33] =
-{
+
+static const uint16_t bitalloc_33_codes_e[33] = {
0x01C8, 0x01E6, 0x0064, 0x00E2, 0x00E5, 0x0030, 0x0033, 0x0073,
0x007A, 0x001A, 0x003A, 0x0002, 0x001A, 0x001F, 0x0007, 0x0001,
0x0002, 0x0002, 0x000C, 0x0000, 0x001B, 0x0003, 0x003B, 0x001B,
0x007B, 0x0078, 0x0070, 0x0031, 0x00F2, 0x00E3, 0x0065, 0x01E7,
0x01C9,
};
-static const uint16_t bitalloc_33_codes_f[33] =
-{
+
+static const uint16_t bitalloc_33_codes_f[33] = {
0x0724, 0x0393, 0x01CE, 0x00E5, 0x002C, 0x0008, 0x0017, 0x003E,
0x0005, 0x0014, 0x001D, 0x0000, 0x0003, 0x0006, 0x0008, 0x000B,
0x000D, 0x000C, 0x0009, 0x0007, 0x0004, 0x0001, 0x001E, 0x0015,
0x000A, 0x003F, 0x0038, 0x0009, 0x002D, 0x00E6, 0x01CF, 0x01C8,
0x0725,
};
-static const uint16_t bitalloc_33_codes_g[33] =
-{
+
+static const uint16_t bitalloc_33_codes_g[33] = {
0x0284, 0x0042, 0x0140, 0x0143, 0x003E, 0x00BE, 0x0011, 0x0051,
0x0009, 0x0029, 0x0005, 0x0015, 0x0000, 0x0008, 0x000E, 0x0002,
0x0006, 0x0003, 0x000F, 0x0009, 0x0001, 0x0016, 0x0006, 0x002E,
0x000E, 0x005E, 0x001E, 0x00BF, 0x003F, 0x0020, 0x0141, 0x0043,
0x0285,
};
-static const uint8_t bitalloc_33_bits_a[33] =
-{
+
+static const uint8_t bitalloc_33_bits_a[33] = {
13, 13, 12, 11, 10, 9, 8, 7, 6, 6, 5, 5, 4, 4, 4, 3,
3, 3, 4, 4, 4, 4, 5, 6, 6, 7, 8, 9, 10, 11, 12, 13,
13,
};
-static const uint8_t bitalloc_33_bits_b[33] =
-{
+
+static const uint8_t bitalloc_33_bits_b[33] = {
10, 9, 8, 7, 7, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4,
3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 7, 7, 7, 8, 8,
10,
};
-static const uint8_t bitalloc_33_bits_c[33] =
-{
- 9, 8, 7, 7, 6, 6, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 7, 7, 7,
- 9,
+
+static const uint8_t bitalloc_33_bits_c[33] = {
+ 9, 8, 7, 7, 6, 6, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 7, 7, 7,
+ 9,
};
-static const uint8_t bitalloc_33_bits_d[33] =
-{
+
+static const uint8_t bitalloc_33_bits_d[33] = {
14, 14, 13, 12, 11, 10, 9, 8, 7, 7, 6, 6, 5, 4, 4, 3,
2, 3, 3, 4, 5, 5, 6, 7, 7, 8, 9, 10, 11, 12, 13, 14,
14,
};
-static const uint8_t bitalloc_33_bits_e[33] =
-{
- 9, 9, 8, 8, 8, 7, 7, 7, 7, 6, 6, 5, 5, 5, 4, 3,
- 2, 3, 4, 4, 5, 5, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9,
- 9,
+
+static const uint8_t bitalloc_33_bits_e[33] = {
+ 9, 9, 8, 8, 8, 7, 7, 7, 7, 6, 6, 5, 5, 5, 4, 3,
+ 2, 3, 4, 4, 5, 5, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9,
+ 9,
};
-static const uint8_t bitalloc_33_bits_f[33] =
-{
+
+static const uint8_t bitalloc_33_bits_f[33] = {
11, 10, 9, 8, 7, 6, 6, 6, 5, 5, 5, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 8, 9, 9,
11,
};
-static const uint8_t bitalloc_33_bits_g[33] =
-{
+
+static const uint8_t bitalloc_33_bits_g[33] = {
10, 9, 9, 9, 8, 8, 7, 7, 6, 6, 5, 5, 4, 4, 4, 3,
3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 8, 9, 9,
10,
};
-static const uint16_t bitalloc_65_codes_a[65] =
-{
+static const uint16_t bitalloc_65_codes_a[65] = {
0x9E5C, 0x9E5E, 0x4F2C, 0x2794, 0x13C4, 0x1E44, 0x09E3, 0x0F23,
0x04F3, 0x0792, 0x027E, 0x03CE, 0x013D, 0x01E5, 0x009C, 0x00CC,
0x0040, 0x0058, 0x0067, 0x001E, 0x0021, 0x002D, 0x003D, 0x0007,
0x0790, 0x04F0, 0x09E4, 0x1E45, 0x13C5, 0x2795, 0x4F2D, 0x9E5F,
0x9E5D,
};
-static const uint16_t bitalloc_65_codes_b[65] =
-{
+
+static const uint16_t bitalloc_65_codes_b[65] = {
0x0A8C, 0x0547, 0x01B5, 0x0008, 0x00DB, 0x0152, 0x0005, 0x000B,
0x008E, 0x00AE, 0x00E4, 0x0003, 0x0037, 0x0039, 0x0055, 0x006C,
0x0073, 0x0003, 0x0015, 0x001D, 0x0028, 0x0030, 0x0037, 0x003E,
0x008F, 0x006C, 0x000A, 0x0153, 0x0150, 0x0009, 0x02A2, 0x01B4,
0x0A8D,
};
-static const uint16_t bitalloc_65_codes_c[65] =
-{
+
+static const uint16_t bitalloc_65_codes_c[65] = {
0x045C, 0x022F, 0x03F5, 0x01BC, 0x01FB, 0x0059, 0x00D0, 0x00DF,
0x000A, 0x002D, 0x002F, 0x0052, 0x0069, 0x0078, 0x007F, 0x000A,
0x0010, 0x001C, 0x0023, 0x002A, 0x0035, 0x003A, 0x003D, 0x0000,
0x000B, 0x00FC, 0x00D1, 0x008A, 0x0058, 0x01BD, 0x0116, 0x03F4,
0x045D,
};
-static const uint16_t bitalloc_65_codes_d[65] =
-{
+
+static const uint16_t bitalloc_65_codes_d[65] = {
0x70B0, 0x70B2, 0x70B4, 0x2852, 0x385B, 0x142E, 0x1C2E, 0x0A15,
0x0E14, 0x0214, 0x0704, 0x0104, 0x010B, 0x0383, 0x0083, 0x0143,
0x01C3, 0x0043, 0x00A2, 0x00E2, 0x0022, 0x0052, 0x0072, 0x0012,
0x0E15, 0x0A16, 0x1C2F, 0x142F, 0x1428, 0x2853, 0x70B5, 0x70B3,
0x70B1,
};
-static const uint16_t bitalloc_65_codes_e[65] =
-{
+
+static const uint16_t bitalloc_65_codes_e[65] = {
0x032C, 0x0332, 0x0378, 0x037E, 0x008C, 0x014A, 0x0188, 0x0197,
0x019E, 0x01BD, 0x0044, 0x0047, 0x00AA, 0x00C5, 0x00CD, 0x00DC,
0x001C, 0x002C, 0x0053, 0x0063, 0x0068, 0x0008, 0x000F, 0x0017,
0x019F, 0x0198, 0x0189, 0x014B, 0x008D, 0x037F, 0x0379, 0x0333,
0x032D,
};
-static const uint16_t bitalloc_65_codes_f[65] =
-{
+
+static const uint16_t bitalloc_65_codes_f[65] = {
0x0FE0, 0x0FE2, 0x0FE8, 0x0FEA, 0x0FEC, 0x0FEE, 0x0FF0, 0x0FF2,
0x0FF4, 0x2FF2, 0x07F2, 0x07FB, 0x03F6, 0x0BFA, 0x0BFD, 0x01FF,
0x05FF, 0x02FC, 0x007C, 0x017C, 0x003C, 0x00BC, 0x001C, 0x005C,
0x0FF5, 0x0FF3, 0x0FF1, 0x0FEF, 0x0FED, 0x0FEB, 0x0FE9, 0x0FE3,
0x0FE1,
};
-static const uint16_t bitalloc_65_codes_g[65] =
-{
+
+static const uint16_t bitalloc_65_codes_g[65] = {
0x010C, 0x038A, 0x0608, 0x0786, 0x0084, 0x0087, 0x0302, 0x0305,
0x0040, 0x00E0, 0x00E3, 0x0183, 0x001E, 0x005E, 0x009E, 0x00DE,
0x00F1, 0x0011, 0x0039, 0x0061, 0x0079, 0x0009, 0x001D, 0x0031,
0x0041, 0x03C2, 0x0303, 0x01C4, 0x0085, 0x0787, 0x0609, 0x038B,
0x010D,
};
-static const uint8_t bitalloc_65_bits_a[65] =
-{
+
+static const uint8_t bitalloc_65_bits_a[65] = {
16, 16, 15, 14, 13, 13, 12, 12, 11, 11, 10, 10, 9, 9, 8, 8,
7, 7, 7, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 4, 4,
4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 7, 7,
7, 8, 8, 9, 9, 10, 10, 11, 11, 11, 12, 13, 13, 14, 15, 16,
16,
};
-static const uint8_t bitalloc_65_bits_b[65] =
-{
+
+static const uint8_t bitalloc_65_bits_b[65] = {
12, 11, 10, 9, 9, 9, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7,
7, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 4,
4, 4, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6,
6, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 9, 9, 9, 10, 10,
12,
};
-static const uint8_t bitalloc_65_bits_c[65] =
-{
+
+static const uint8_t bitalloc_65_bits_c[65] = {
11, 10, 10, 9, 9, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 6,
6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6,
6, 6, 6, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 10,
11,
};
-static const uint8_t bitalloc_65_bits_d[65] =
-{
+
+static const uint8_t bitalloc_65_bits_d[65] = {
15, 15, 15, 14, 14, 13, 13, 12, 12, 11, 11, 10, 10, 10, 9, 9,
9, 8, 8, 8, 7, 7, 7, 6, 6, 6, 5, 5, 5, 4, 4, 3,
3, 3, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8,
8, 9, 9, 10, 10, 10, 11, 11, 12, 12, 13, 13, 13, 14, 15, 15,
15,
};
-static const uint8_t bitalloc_65_bits_e[65] =
-{
+
+static const uint8_t bitalloc_65_bits_e[65] = {
10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8,
7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 5, 5, 5, 5, 4, 4,
3, 3, 4, 5, 5, 5, 5, 6, 6, 6, 6, 6, 7, 7, 7, 7,
7, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 10, 10, 10,
10,
};
-static const uint8_t bitalloc_65_bits_f[65] =
-{
+
+static const uint8_t bitalloc_65_bits_f[65] = {
14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 13, 13, 12, 12, 12, 11,
11, 10, 9, 9, 8, 8, 7, 7, 6, 6, 5, 5, 4, 4, 4, 3,
3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10,
10, 11, 11, 12, 12, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14,
14,
};
-static const uint8_t bitalloc_65_bits_g[65] =
-{
+
+static const uint8_t bitalloc_65_bits_g[65] = {
11, 11, 11, 11, 10, 10, 10, 10, 9, 9, 9, 9, 8, 8, 8, 8,
8, 7, 7, 7, 7, 6, 6, 6, 6, 5, 5, 5, 5, 4, 4, 4,
4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7,
11,
};
-static const uint16_t bitalloc_129_codes_a[129] =
-{
+static const uint16_t bitalloc_129_codes_a[129] = {
0x0660, 0x0666, 0x06EC, 0x0722, 0x0760, 0x076E, 0x004C, 0x004E,
0x00F4, 0x010A, 0x0148, 0x0156, 0x01D4, 0x01F2, 0x0331, 0x0370,
0x0377, 0x0396, 0x03B1, 0x0024, 0x0064, 0x007B, 0x008A, 0x00A5,
0x00F5, 0x004F, 0x004D, 0x076F, 0x0761, 0x0723, 0x06ED, 0x0667,
0x0661,
};
-static const uint16_t bitalloc_129_codes_b[129] =
-{
+
+static const uint16_t bitalloc_129_codes_b[129] = {
0x29DC, 0x14EF, 0x0455, 0x0E9C, 0x022B, 0x0489, 0x0740, 0x074F,
0x0172, 0x0245, 0x0247, 0x030A, 0x03A1, 0x001C, 0x008B, 0x00D6,
0x010C, 0x0148, 0x014F, 0x0186, 0x01D1, 0x0008, 0x000F, 0x0046,
0x0173, 0x0114, 0x0741, 0x053A, 0x0488, 0x0E9D, 0x0A76, 0x0454,
0x29DD,
};
-static const uint16_t bitalloc_129_codes_c[129] =
-{
+
+static const uint16_t bitalloc_129_codes_c[129] = {
0x0E5C, 0x072F, 0x001D, 0x0724, 0x000F, 0x010D, 0x0324, 0x0393,
0x03E9, 0x0080, 0x0087, 0x00FA, 0x0164, 0x0193, 0x01DE, 0x01F5,
0x0010, 0x002A, 0x0041, 0x0064, 0x0073, 0x008E, 0x00A4, 0x00B3,
0x0006, 0x03E8, 0x0325, 0x01CA, 0x010C, 0x0725, 0x0396, 0x001C,
0x0E5D,
};
-static const uint16_t bitalloc_129_codes_d[129] =
-{
+
+static const uint16_t bitalloc_129_codes_d[129] = {
0xA598, 0xA59A, 0xA59C, 0xA59E, 0xC598, 0xE586, 0x3ACC, 0x52CA,
0x62CD, 0x0D48, 0x1D67, 0x2978, 0x3167, 0x3966, 0x06A5, 0x0EBC,
0x14BD, 0x1CB1, 0x0350, 0x0353, 0x075F, 0x0A5F, 0x0C5E, 0x0E5E,
0x72C2, 0x52CB, 0x3ACD, 0xE587, 0xC599, 0xA59F, 0xA59D, 0xA59B,
0xA599,
};
-static const uint16_t bitalloc_129_codes_e[129] =
-{
+
+static const uint16_t bitalloc_129_codes_e[129] = {
0xA13C, 0xC720, 0xA13F, 0xA13E, 0xA13D, 0xE722, 0x5090, 0x6393,
0x7392, 0x2849, 0x31CE, 0x39CE, 0x1425, 0x18E5, 0x1CE5, 0x0844,
0x0A1C, 0x0C7C, 0x036C, 0x0423, 0x050F, 0x063F, 0x01B7, 0x0216,
0x7393, 0x7390, 0x5091, 0xE723, 0xC724, 0xC725, 0xC722, 0xC723,
0xC721,
};
-static const uint16_t bitalloc_129_codes_f[129] =
-{
+
+static const uint16_t bitalloc_129_codes_f[129] = {
0x762C, 0x3B17, 0x1555, 0x0608, 0x0AAB, 0x0FF2, 0x0305, 0x0307,
0x0763, 0x0046, 0x010C, 0x01BC, 0x02AB, 0x03B6, 0x03FD, 0x0080,
0x0087, 0x00DF, 0x0156, 0x01D9, 0x01F8, 0x01FF, 0x002A, 0x0041,
0x07F8, 0x0554, 0x0306, 0x0FF3, 0x0EC4, 0x0609, 0x1D8A, 0x1554,
0x762D,
};
-static const uint16_t bitalloc_129_codes_g[129] =
-{
+
+static const uint16_t bitalloc_129_codes_g[129] = {
0x1E20, 0x1E5E, 0x031C, 0x051A, 0x0718, 0x0916, 0x0B14, 0x0D12,
0x0F11, 0x0090, 0x018F, 0x028E, 0x038D, 0x048C, 0x058B, 0x068A,
0x0789, 0x0049, 0x00C8, 0x0148, 0x01C7, 0x0247, 0x02C6, 0x0346,
0x0F2E, 0x0D13, 0x0B15, 0x0917, 0x0719, 0x051B, 0x031D, 0x1E5F,
0x1E21,
};
-static const uint8_t bitalloc_129_bits_a[129] =
-{
+
+static const uint8_t bitalloc_129_bits_a[129] = {
11, 11, 11, 11, 11, 11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7,
10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11,
11,
};
-static const uint8_t bitalloc_129_bits_b[129] =
-{
+
+static const uint8_t bitalloc_129_bits_b[129] = {
14, 13, 12, 12, 11, 11, 11, 11, 10, 10, 10, 10, 10, 9, 9, 9,
9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6,
9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 11, 11, 11, 12, 12, 12,
14,
};
-static const uint8_t bitalloc_129_bits_c[129] =
-{
+
+static const uint8_t bitalloc_129_bits_c[129] = {
13, 12, 11, 11, 10, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6,
8, 8, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11, 11,
13,
};
-static const uint8_t bitalloc_129_bits_d[129] =
-{
+
+static const uint8_t bitalloc_129_bits_d[129] = {
16, 16, 16, 16, 16, 16, 15, 15, 15, 14, 14, 14, 14, 14, 13, 13,
13, 13, 12, 12, 12, 12, 12, 12, 11, 11, 11, 11, 11, 10, 10, 10,
10, 10, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 7, 7,
13, 13, 13, 14, 14, 14, 14, 14, 15, 15, 15, 16, 16, 16, 16, 16,
16,
};
-static const uint8_t bitalloc_129_bits_e[129] =
-{
+
+static const uint8_t bitalloc_129_bits_e[129] = {
16, 16, 16, 16, 16, 16, 15, 15, 15, 14, 14, 14, 13, 13, 13, 12,
12, 12, 11, 11, 11, 11, 10, 10, 10, 10, 10, 9, 9, 9, 9, 9,
8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6,
12, 12, 13, 13, 13, 14, 14, 14, 15, 15, 15, 16, 16, 16, 16, 16,
16,
};
-static const uint8_t bitalloc_129_bits_f[129] =
-{
+
+static const uint8_t bitalloc_129_bits_f[129] = {
15, 14, 13, 12, 12, 12, 11, 11, 11, 10, 10, 10, 10, 10, 10, 9,
9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6,
9, 9, 9, 10, 10, 10, 10, 10, 11, 11, 11, 12, 12, 12, 13, 13,
15,
};
-static const uint8_t bitalloc_129_bits_g[129] =
-{
+
+static const uint8_t bitalloc_129_bits_g[129] = {
13, 13, 12, 12, 12, 12, 12, 12, 12, 11, 11, 11, 11, 11, 11, 11,
11, 10, 10, 10, 10, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9,
9, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7,
13,
};
-static const uint8_t bitalloc_sizes[10] = { 3, 5, 7, 9, 13, 17, 25, 33, 65, 129 };
+static const uint8_t bitalloc_sizes[10] = {
+ 3, 5, 7, 9, 13, 17, 25, 33, 65, 129
+};
-static const int8_t bitalloc_offsets[10] =
- { -1, -2, -3, -4, -6, -8, -12, -16, -32, -64 };
+static const int8_t bitalloc_offsets[10] = {
+ -1, -2, -3, -4, -6, -8, -12, -16, -32, -64
+};
static const uint8_t bitalloc_maxbits[10][7] = {
{ 2 },
{ 9, 9, 9, 9, 9, 9, 9 }
};
-static const uint16_t* const bitalloc_codes[10][8] = {
- { bitalloc_3_codes, NULL },
- { bitalloc_5_codes_a, bitalloc_5_codes_b, bitalloc_5_codes_c, NULL },
- { bitalloc_7_codes_a, bitalloc_7_codes_b, bitalloc_7_codes_c, NULL },
- { bitalloc_9_codes_a, bitalloc_9_codes_b, bitalloc_9_codes_c, NULL },
- { bitalloc_13_codes_a, bitalloc_13_codes_b, bitalloc_13_codes_c, NULL },
- { bitalloc_17_codes_a, bitalloc_17_codes_b, bitalloc_17_codes_c, bitalloc_17_codes_d,
- bitalloc_17_codes_e, bitalloc_17_codes_f, bitalloc_17_codes_g, NULL },
- { bitalloc_25_codes_a, bitalloc_25_codes_b, bitalloc_25_codes_c, bitalloc_25_codes_d,
- bitalloc_25_codes_e, bitalloc_25_codes_f, bitalloc_25_codes_g, NULL },
- { bitalloc_33_codes_a, bitalloc_33_codes_b, bitalloc_33_codes_c, bitalloc_33_codes_d,
- bitalloc_33_codes_e, bitalloc_33_codes_f, bitalloc_33_codes_g, NULL },
- { bitalloc_65_codes_a, bitalloc_65_codes_b, bitalloc_65_codes_c, bitalloc_65_codes_d,
- bitalloc_65_codes_e, bitalloc_65_codes_f, bitalloc_65_codes_g, NULL },
- { bitalloc_129_codes_a, bitalloc_129_codes_b, bitalloc_129_codes_c, bitalloc_129_codes_d,
- bitalloc_129_codes_e, bitalloc_129_codes_f, bitalloc_129_codes_g, NULL }
-};
-
-static const uint8_t* const bitalloc_bits[10][8] = {
- { bitalloc_3_bits, NULL },
- { bitalloc_5_bits_a, bitalloc_5_bits_b, bitalloc_5_bits_c, NULL },
- { bitalloc_7_bits_a, bitalloc_7_bits_b, bitalloc_7_bits_c, NULL },
- { bitalloc_9_bits_a, bitalloc_9_bits_b, bitalloc_9_bits_c, NULL },
- { bitalloc_13_bits_a, bitalloc_13_bits_b, bitalloc_13_bits_c, NULL },
- { bitalloc_17_bits_a, bitalloc_17_bits_b, bitalloc_17_bits_c, bitalloc_17_bits_d,
- bitalloc_17_bits_e, bitalloc_17_bits_f, bitalloc_17_bits_g, NULL },
- { bitalloc_25_bits_a, bitalloc_25_bits_b, bitalloc_25_bits_c, bitalloc_25_bits_d,
- bitalloc_25_bits_e, bitalloc_25_bits_f, bitalloc_25_bits_g, NULL },
- { bitalloc_33_bits_a, bitalloc_33_bits_b, bitalloc_33_bits_c, bitalloc_33_bits_d,
- bitalloc_33_bits_e, bitalloc_33_bits_f, bitalloc_33_bits_g, NULL },
- { bitalloc_65_bits_a, bitalloc_65_bits_b, bitalloc_65_bits_c, bitalloc_65_bits_d,
- bitalloc_65_bits_e, bitalloc_65_bits_f, bitalloc_65_bits_g, NULL },
- { bitalloc_129_bits_a, bitalloc_129_bits_b, bitalloc_129_bits_c, bitalloc_129_bits_d,
- bitalloc_129_bits_e, bitalloc_129_bits_f, bitalloc_129_bits_g, NULL }
+static const uint16_t *const bitalloc_codes[10][8] = {
+ { bitalloc_3_codes, NULL },
+ { bitalloc_5_codes_a, bitalloc_5_codes_b, bitalloc_5_codes_c, NULL },
+ { bitalloc_7_codes_a, bitalloc_7_codes_b, bitalloc_7_codes_c, NULL },
+ { bitalloc_9_codes_a, bitalloc_9_codes_b, bitalloc_9_codes_c, NULL },
+ { bitalloc_13_codes_a, bitalloc_13_codes_b, bitalloc_13_codes_c, NULL },
+ { bitalloc_17_codes_a, bitalloc_17_codes_b, bitalloc_17_codes_c, bitalloc_17_codes_d,
+ bitalloc_17_codes_e, bitalloc_17_codes_f, bitalloc_17_codes_g, NULL },
+ { bitalloc_25_codes_a, bitalloc_25_codes_b, bitalloc_25_codes_c, bitalloc_25_codes_d,
+ bitalloc_25_codes_e, bitalloc_25_codes_f, bitalloc_25_codes_g, NULL },
+ { bitalloc_33_codes_a, bitalloc_33_codes_b, bitalloc_33_codes_c, bitalloc_33_codes_d,
+ bitalloc_33_codes_e, bitalloc_33_codes_f, bitalloc_33_codes_g, NULL },
+ { bitalloc_65_codes_a, bitalloc_65_codes_b, bitalloc_65_codes_c, bitalloc_65_codes_d,
+ bitalloc_65_codes_e, bitalloc_65_codes_f, bitalloc_65_codes_g, NULL },
+ { bitalloc_129_codes_a, bitalloc_129_codes_b, bitalloc_129_codes_c, bitalloc_129_codes_d,
+ bitalloc_129_codes_e, bitalloc_129_codes_f, bitalloc_129_codes_g, NULL }
+};
+
+static const uint8_t *const bitalloc_bits[10][8] = {
+ { bitalloc_3_bits, NULL },
+ { bitalloc_5_bits_a, bitalloc_5_bits_b, bitalloc_5_bits_c, NULL },
+ { bitalloc_7_bits_a, bitalloc_7_bits_b, bitalloc_7_bits_c, NULL },
+ { bitalloc_9_bits_a, bitalloc_9_bits_b, bitalloc_9_bits_c, NULL },
+ { bitalloc_13_bits_a, bitalloc_13_bits_b, bitalloc_13_bits_c, NULL },
+ { bitalloc_17_bits_a, bitalloc_17_bits_b, bitalloc_17_bits_c, bitalloc_17_bits_d,
+ bitalloc_17_bits_e, bitalloc_17_bits_f, bitalloc_17_bits_g, NULL },
+ { bitalloc_25_bits_a, bitalloc_25_bits_b, bitalloc_25_bits_c, bitalloc_25_bits_d,
+ bitalloc_25_bits_e, bitalloc_25_bits_f, bitalloc_25_bits_g, NULL },
+ { bitalloc_33_bits_a, bitalloc_33_bits_b, bitalloc_33_bits_c, bitalloc_33_bits_d,
+ bitalloc_33_bits_e, bitalloc_33_bits_f, bitalloc_33_bits_g, NULL },
+ { bitalloc_65_bits_a, bitalloc_65_bits_b, bitalloc_65_bits_c, bitalloc_65_bits_d,
+ bitalloc_65_bits_e, bitalloc_65_bits_f, bitalloc_65_bits_g, NULL },
+ { bitalloc_129_bits_a, bitalloc_129_bits_b, bitalloc_129_bits_c, bitalloc_129_bits_d,
+ bitalloc_129_bits_e, bitalloc_129_bits_f, bitalloc_129_bits_g, NULL }
};
#endif /* AVCODEC_DCAHUFF_H */
#elif ARCH_X86
#include "x86/dct-test.c"
#else
-static const struct algo fdct_tab_arch[] = { 0 };
-static const struct algo idct_tab_arch[] = { 0 };
+static const struct algo fdct_tab_arch[] = { { 0 } };
+static const struct algo idct_tab_arch[] = { { 0 } };
#endif
#define AANSCALE_BITS 12
s->csc2 = av_malloc_array(n / 2, sizeof(FFTSample));
if (ff_rdft_init(&s->rdft, nbits, inverse == DCT_III) < 0) {
- av_free(s->csc2);
+ av_freep(&s->csc2);
return -1;
}
av_cold void ff_dct_end(DCTContext *s)
{
ff_rdft_end(&s->rdft);
- av_free(s->csc2);
+ av_freep(&s->csc2);
}
/* [DIRAC_STD] Table 10.3 values 9-10 */
frame_rate = dirac_frame_rate[source->frame_rate_index - 9];
}
- av_reduce(&avctx->time_base.num, &avctx->time_base.den,
- frame_rate.den, frame_rate.num, 1 << 30);
+ avctx->framerate = frame_rate;
/* [DIRAC_STD] 10.3.6 Pixel Aspect Ratio.
* pixel_aspect_ratio(video_params) */
range_times_prob = (c->range * prob_zero) >> 16;
-#if HAVE_FAST_CMOV && HAVE_INLINE_ASM && HAVE_6REGS
+#if ARCH_X86 && HAVE_FAST_CMOV && HAVE_INLINE_ASM && HAVE_6REGS
low -= range_times_prob << 16;
range -= range_times_prob;
bit = 0;
void *new_buffer =
av_fast_realloc(pc->buffer, &pc->buffer_size,
pc->index + (*buf_size - pc->sync_offset));
+ if (!new_buffer)
+ return AVERROR(ENOMEM);
pc->buffer = new_buffer;
memcpy(pc->buffer + pc->index, (*buf + pc->sync_offset),
*buf_size - pc->sync_offset);
DiracParseUnit pu1, pu;
void *new_buffer = av_fast_realloc(pc->buffer, &pc->buffer_size,
pc->index + next);
+ if (!new_buffer)
+ return AVERROR(ENOMEM);
pc->buffer = new_buffer;
memcpy(pc->buffer + pc->index, *buf, next);
pc->index += next;
DiracParseContext *pc = s->priv_data;
if (pc->buffer_size > 0)
- av_free(pc->buffer);
+ av_freep(&pc->buffer);
}
AVCodecParser ff_dirac_parser = {
for (i = 1; i < 64; ++i) {
int j = scantable[i];
- int sign = block[j] >> 31;
+ int sign = FF_SIGNBIT(block[j]);
int level = (block[j] ^ sign) - sign;
level = level * qmat[j] >> DNX10BIT_QMAT_SHIFT;
block[j] = (level ^ sign) - sign;
index = ff_dnxhd_get_cid_table(ctx->cid);
av_assert0(index >= 0);
+
ctx->cid_table = &ff_dnxhd_cid_table[index];
ctx->m.avctx = avctx;
if(i) {
AVRational q = av_d2q(av_int2float(i), 4096);
if (q.num > 0 && q.den > 0)
- avctx->time_base = av_inv_q(q);
+ avctx->framerate = q;
}
}
+++ /dev/null
-/*
- * DSP utils
- * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
- * Copyright (c) 2002-2004 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
- */
-
-/**
- * @file
- * DSP utils.
- * This is deprecated
- */
-
-#ifndef AVCODEC_DSPUTIL_H
-#define AVCODEC_DSPUTIL_H
-
-#include "avcodec.h"
-#include "version.h"
-#include "me_cmp.h"
-
-#if FF_API_DSPUTIL
-
-/* minimum alignment rules ;)
- * If you notice errors in the align stuff, need more alignment for some ASM code
- * for some CPU or need to use a function with less aligned data then send a mail
- * to the ffmpeg-devel mailing list, ...
- *
- * !warning These alignments might not match reality, (missing attribute((align))
- * stuff somewhere possible).
- * I (Michael) did not check them, these are just the alignments which I think
- * could be reached easily ...
- *
- * !future video codecs might need functions with less strict alignment
- */
-
-struct MpegEncContext;
-
-/**
- * DSPContext.
- */
-typedef struct DSPContext {
- int (*sum_abs_dctelem)(int16_t *block /* align 16 */);
-
- me_cmp_func sad[6]; /* identical to pix_absAxA except additional void * */
- me_cmp_func sse[6];
- me_cmp_func hadamard8_diff[6];
- me_cmp_func dct_sad[6];
- me_cmp_func quant_psnr[6];
- me_cmp_func bit[6];
- me_cmp_func rd[6];
- me_cmp_func vsad[6];
- me_cmp_func vsse[6];
- me_cmp_func nsse[6];
- me_cmp_func w53[6];
- me_cmp_func w97[6];
- me_cmp_func dct_max[6];
- me_cmp_func dct264_sad[6];
-
- me_cmp_func me_pre_cmp[6];
- me_cmp_func me_cmp[6];
- me_cmp_func me_sub_cmp[6];
- me_cmp_func mb_cmp[6];
- me_cmp_func ildct_cmp[6]; // only width 16 used
- me_cmp_func frame_skip_cmp[6]; // only width 8 used
-
- me_cmp_func pix_abs[2][4];
-} DSPContext;
-
-attribute_deprecated void avpriv_dsputil_init(DSPContext* p, AVCodecContext *avctx);
-
-#endif
-#endif /* AVCODEC_DSPUTIL_H */
#include "simple_idct.h"
/* XXX: also include quantization */
-RL_VLC_ELEM ff_dv_rl_vlc[1184];
+RL_VLC_ELEM ff_dv_rl_vlc[1664];
static inline void dv_calc_mb_coordinates(const AVDVProfile *d, int chan,
int seq, int slot, uint16_t *tbl)
int ff_dv_init_dynamic_tables(DVVideoContext *ctx, const AVDVProfile *d)
{
int j, i, c, s, p;
- uint32_t *factor1, *factor2;
- const int *iweight1, *iweight2;
p = i = 0;
for (c = 0; c < d->n_difchan; c++) {
}
}
- factor1 = &ctx->idct_factor[0];
- factor2 = &ctx->idct_factor[DV_PROFILE_IS_HD(d) ? 4096 : 2816];
- if (d->height == 720) {
- iweight1 = &ff_dv_iweight_720_y[0];
- iweight2 = &ff_dv_iweight_720_c[0];
- } else {
- iweight1 = &ff_dv_iweight_1080_y[0];
- iweight2 = &ff_dv_iweight_1080_c[0];
- }
- if (DV_PROFILE_IS_HD(d)) {
- for (c = 0; c < 4; c++) {
- for (s = 0; s < 16; s++) {
- for (i = 0; i < 64; i++) {
- *factor1++ = (dv100_qstep[s] << (c + 9)) * iweight1[i];
- *factor2++ = (dv100_qstep[s] << (c + 9)) * iweight2[i];
- }
- }
- }
- } else {
- iweight1 = &ff_dv_iweight_88[0];
- for (j = 0; j < 2; j++, iweight1 = &ff_dv_iweight_248[0]) {
- for (s = 0; s < 22; s++) {
- for (i = c = 0; c < 4; c++) {
- for (; i < dv_quant_areas[c]; i++) {
- *factor1 = iweight1[i] << (ff_dv_quant_shifts[s][c] + 1);
- *factor2++ = (*factor1++) << 1;
- }
- }
- }
- }
- }
-
return 0;
}
* to accelerate the parsing of partial codes */
init_vlc(&dv_vlc, TEX_VLC_BITS, j, new_dv_vlc_len,
1, 1, new_dv_vlc_bits, 2, 2, 0);
- av_assert1(dv_vlc.table_size == 1184);
+ av_assert1(dv_vlc.table_size == 1664);
for (i = 0; i < dv_vlc.table_size; i++) {
int code = dv_vlc.table[i][0];
*/
#define DV_MAX_BPM 8
-#define TEX_VLC_BITS 9
+#define TEX_VLC_BITS 10
-extern RL_VLC_ELEM ff_dv_rl_vlc[1184];
+extern RL_VLC_ELEM ff_dv_rl_vlc[1664];
int ff_dv_init_dynamic_tables(DVVideoContext *s, const AVDVProfile *d);
+
int ff_dvvideo_init(AVCodecContext *avctx);
static inline int dv_work_pool_size(const AVDVProfile *d)
#endif /* CONFIG_DVPROFILE */
-const AVDVProfile* avpriv_dv_frame_profile2(AVCodecContext* codec, const AVDVProfile *sys,
+const AVDVProfile* ff_dv_frame_profile(AVCodecContext* codec, const AVDVProfile *sys,
const uint8_t *frame, unsigned buf_size)
{
#if CONFIG_DVPROFILE
return NULL;
}
+#if FF_API_DV_FRAME_PROFILE
+const AVDVProfile* avpriv_dv_frame_profile2(AVCodecContext* codec, const AVDVProfile *sys,
+ const uint8_t *frame, unsigned buf_size)
+{
+ return ff_dv_frame_profile(codec, sys, frame, buf_size);
+}
+#endif
+
const AVDVProfile *av_dv_frame_profile(const AVDVProfile *sys,
const uint8_t *frame, unsigned buf_size)
{
- return avpriv_dv_frame_profile2(NULL, sys, frame, buf_size);
+ return ff_dv_frame_profile(NULL, sys, frame, buf_size);
}
const AVDVProfile *av_dv_codec_profile(int width, int height,
const uint8_t (*audio_shuffle)[9]; /* PCM shuffling table */
} AVDVProfile;
+#if FF_API_DV_FRAME_PROFILE
+/**
+ * @deprecated use av_dv_frame_profile()
+ */
+attribute_deprecated
const AVDVProfile* avpriv_dv_frame_profile2(AVCodecContext* codec, const AVDVProfile *sys,
const uint8_t* frame, unsigned buf_size);
+#endif
/**
* Get a DV profile for the provided compressed frame.
#ifndef AVCODEC_DV_PROFILE_INTERNAL_H
#define AVCODEC_DV_PROFILE_INTERNAL_H
+#include "dv_profile.h"
+
/**
* Print all allowed DV profiles into logctx at specified logging level.
*/
void ff_dv_print_profiles(void *logctx, int loglevel);
+/**
+ * Get a DV profile for the provided compressed frame.
+ */
+const AVDVProfile* ff_dv_frame_profile(AVCodecContext* codec, const AVDVProfile *sys,
+ const uint8_t *frame, unsigned buf_size);
+
#endif /* AVCODEC_DV_PROFILE_INTERNAL_H */
obj2 = *obj2_ptr;
while (obj2 != object) {
- assert(obj2);
+ av_assert0(obj2);
obj2_ptr = &obj2->next;
obj2 = *obj2_ptr;
}
*obj2_ptr = obj2->next;
- av_free(obj2);
+ av_freep(&obj2);
}
}
}
region->display_list = display->region_list_next;
- av_free(display);
+ av_freep(&display);
}
}
static void delete_cluts(DVBSubContext *ctx)
{
- DVBSubCLUT *clut;
-
while (ctx->clut_list) {
- clut = ctx->clut_list;
+ DVBSubCLUT *clut = ctx->clut_list;
ctx->clut_list = clut->next;
- av_free(clut);
+ av_freep(&clut);
}
}
static void delete_objects(DVBSubContext *ctx)
{
- DVBSubObject *object;
-
while (ctx->object_list) {
- object = ctx->object_list;
+ DVBSubObject *object = ctx->object_list;
ctx->object_list = object->next;
- av_free(object);
+ av_freep(&object);
}
}
static void delete_regions(DVBSubContext *ctx)
{
- DVBSubRegion *region;
-
while (ctx->region_list) {
- region = ctx->region_list;
+ DVBSubRegion *region = ctx->region_list;
ctx->region_list = region->next;
delete_region_display_list(ctx, region);
- av_free(region->pbuf);
- av_free(region);
+ av_freep(®ion->pbuf);
+ av_freep(®ion);
}
}
display = ctx->display_list;
ctx->display_list = display->next;
- av_free(display);
+ av_freep(&display);
}
return 0;
return pixels_read;
}
- if (map_table)
- bits = map_table[0];
- else
- bits = 0;
- while (run_length-- > 0 && pixels_read < dbuf_len) {
- *destbuf++ = bits;
- pixels_read++;
- }
+ bits = 0;
} else {
bits = *(*srcbuf)++;
-
- if (non_mod == 1 && bits == 1)
- pixels_read += run_length;
+ }
+ if (non_mod == 1 && bits == 1)
+ pixels_read += run_length;
+ else {
if (map_table)
bits = map_table[bits];
- else while (run_length-- > 0 && pixels_read < dbuf_len) {
+ while (run_length-- > 0 && pixels_read < dbuf_len) {
*destbuf++ = bits;
pixels_read++;
}
return pixels_read;
}
-static void save_subtitle_set(AVCodecContext *avctx, AVSubtitle *sub, int *got_output)
+static int save_subtitle_set(AVCodecContext *avctx, AVSubtitle *sub, int *got_output)
{
DVBSubContext *ctx = avctx->priv_data;
DVBSubRegionDisplay *display;
uint32_t *clut_table;
int i;
int offset_x=0, offset_y=0;
+ int ret = 0;
if (display_def) {
/* Not touching AVSubtitles again*/
if(sub->num_rects) {
avpriv_request_sample(ctx, "Different Version of Segment asked Twice\n");
- return;
+ return AVERROR_PATCHWELCOME;
}
for (display = ctx->display_list; display; display = display->next) {
region = get_region(ctx, display->region_id);
if (sub->num_rects > 0) {
sub->rects = av_mallocz_array(sizeof(*sub->rects), sub->num_rects);
+ if (!sub->rects) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+
for(i=0; i<sub->num_rects; i++)
sub->rects[i] = av_mallocz(sizeof(*sub->rects[i]));
}
rect->pict.data[1] = av_mallocz(AVPALETTE_SIZE);
+ if (!rect->pict.data[1]) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
memcpy(rect->pict.data[1], clut_table, (1 << region->depth) * sizeof(uint32_t));
rect->pict.data[0] = av_malloc(region->buf_size);
+ if (!rect->pict.data[0]) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+
memcpy(rect->pict.data[0], region->pbuf, region->buf_size);
i++;
}
}
+
+ return 0;
+fail:
+ if (sub->rects) {
+ for(i=0; i<sub->num_rects; i++) {
+ rect = sub->rects[i];
+ if (rect) {
+ av_freep(&rect->pict.data[0]);
+ av_freep(&rect->pict.data[1]);
+ }
+ av_freep(&sub->rects[i]);
+ }
+ av_freep(&sub->rects);
+ }
+ sub->num_rects = 0;
+ return ret;
}
static void dvbsub_parse_pixel_data_block(AVCodecContext *avctx, DVBSubObjectDisplay *display,
tmp_display_list = display->next;
- av_free(display);
+ av_freep(&display);
}
}
png_save2(filename, pbuf, width, height);
- av_free(pbuf);
+ av_freep(&pbuf);
}
fileno_index++;
const uint8_t ff_dv_quant_offset[4] = { 6, 3, 0, 1 };
-const int ff_dv_iweight_88[64] = {
- 32768, 16710, 16710, 17735, 17015, 17735, 18197, 18079,
- 18079, 18197, 18725, 18559, 19196, 18559, 18725, 19284,
- 19108, 19692, 19692, 19108, 19284, 21400, 19645, 20262,
- 20214, 20262, 19645, 21400, 22733, 21845, 20867, 20815,
- 20815, 20867, 21845, 22733, 23173, 23173, 21400, 21400,
- 21400, 23173, 23173, 24600, 23764, 22017, 22017, 23764,
- 24600, 25267, 24457, 22672, 24457, 25267, 25971, 25191,
- 25191, 25971, 26715, 27962, 26715, 29642, 29642, 31536,
-};
-const int ff_dv_iweight_248[64] = {
- 32768, 17735, 16710, 18079, 18725, 21400, 17735, 19196,
- 19108, 21845, 16384, 17735, 18725, 21400, 16710, 18079,
- 20262, 23173, 18197, 19692, 18725, 20262, 20815, 23764,
- 17735, 19196, 19108, 21845, 20262, 23173, 18197, 19692,
- 21400, 24457, 19284, 20867, 21400, 23173, 22017, 25191,
- 18725, 20262, 20815, 23764, 21400, 24457, 19284, 20867,
- 24457, 27962, 22733, 24600, 25971, 29642, 21400, 23173,
- 22017, 25191, 24457, 27962, 22733, 24600, 25971, 29642,
-};
-
-/**
- * The "inverse" DV100 weights are actually just the spec weights (zig-zagged).
- */
-const int ff_dv_iweight_1080_y[64] = {
- 128, 16, 16, 17, 17, 17, 18, 18,
- 18, 18, 18, 18, 19, 18, 18, 19,
- 19, 19, 19, 19, 19, 42, 38, 40,
- 40, 40, 38, 42, 44, 43, 41, 41,
- 41, 41, 43, 44, 45, 45, 42, 42,
- 42, 45, 45, 48, 46, 43, 43, 46,
- 48, 49, 48, 44, 48, 49, 101, 98,
- 98, 101, 104, 109, 104, 116, 116, 123,
-};
-const int ff_dv_iweight_1080_c[64] = {
- 128, 16, 16, 17, 17, 17, 25, 25,
- 25, 25, 26, 25, 26, 25, 26, 26,
- 26, 27, 27, 26, 26, 42, 38, 40,
- 40, 40, 38, 42, 44, 43, 41, 41,
- 41, 41, 43, 44, 91, 91, 84, 84,
- 84, 91, 91, 96, 93, 86, 86, 93,
- 96, 197, 191, 177, 191, 197, 203, 197,
- 197, 203, 209, 219, 209, 232, 232, 246,
-};
-const int ff_dv_iweight_720_y[64] = {
- 128, 16, 16, 17, 17, 17, 18, 18,
- 18, 18, 18, 18, 19, 18, 18, 19,
- 19, 19, 19, 19, 19, 42, 38, 40,
- 40, 40, 38, 42, 44, 43, 41, 41,
- 41, 41, 43, 44, 68, 68, 63, 63,
- 63, 68, 68, 96, 92, 86, 86, 92,
- 96, 98, 96, 88, 96, 98, 202, 196,
- 196, 202, 208, 218, 208, 232, 232, 246,
-};
-const int ff_dv_iweight_720_c[64] = {
- 128, 24, 24, 26, 26, 26, 36, 36,
- 36, 36, 36, 36, 38, 36, 36, 38,
- 38, 38, 38, 38, 38, 84, 76, 80,
- 80, 80, 76, 84, 88, 86, 82, 82,
- 82, 82, 86, 88, 182, 182, 168, 168,
- 168, 182, 182, 192, 186, 192, 172, 186,
- 192, 394, 382, 354, 382, 394, 406, 394,
- 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
extern const uint8_t ff_dv_quant_shifts[22][4];
extern const uint8_t ff_dv_quant_offset[4];
-extern const int ff_dv_iweight_88[64];
-extern const int ff_dv_iweight_248[64];
-extern const int ff_dv_iweight_1080_y[64];
-extern const int ff_dv_iweight_1080_c[64];
-extern const int ff_dv_iweight_720_y[64];
-extern const int ff_dv_iweight_720_c[64];
-
#define NB_DV_VLC 409
extern const uint16_t ff_dv_vlc_bits[NB_DV_VLC];
#include "avcodec.h"
#include "dv.h"
+#include "dv_profile_internal.h"
#include "dvdata.h"
#include "get_bits.h"
#include "idctdsp.h"
static const int dv_iweight_bits = 14;
+static const uint16_t dv_iweight_88[64] = {
+ 32768, 16705, 16705, 17734, 17032, 17734, 18205, 18081,
+ 18081, 18205, 18725, 18562, 19195, 18562, 18725, 19266,
+ 19091, 19705, 19705, 19091, 19266, 21407, 19643, 20267,
+ 20228, 20267, 19643, 21407, 22725, 21826, 20853, 20806,
+ 20806, 20853, 21826, 22725, 23170, 23170, 21407, 21400,
+ 21407, 23170, 23170, 24598, 23786, 22018, 22018, 23786,
+ 24598, 25251, 24465, 22654, 24465, 25251, 25972, 25172,
+ 25172, 25972, 26722, 27969, 26722, 29692, 29692, 31521,
+};
+static const uint16_t dv_iweight_248[64] = {
+ 32768, 16384, 16705, 16705, 17734, 17734, 17734, 17734,
+ 18081, 18081, 18725, 18725, 21407, 21407, 19091, 19091,
+ 19195, 19195, 18205, 18205, 18725, 18725, 19705, 19705,
+ 20267, 20267, 21826, 21826, 23170, 23170, 20806, 20806,
+ 20267, 20267, 19266, 19266, 21407, 21407, 20853, 20853,
+ 21400, 21400, 23786, 23786, 24465, 24465, 22018, 22018,
+ 23170, 23170, 22725, 22725, 24598, 24598, 24465, 24465,
+ 25172, 25172, 27969, 27969, 25972, 25972, 29692, 29692
+};
+
+/**
+ * The "inverse" DV100 weights are actually just the spec weights (zig-zagged).
+ */
+static const uint16_t dv_iweight_1080_y[64] = {
+ 128, 16, 16, 17, 17, 17, 18, 18,
+ 18, 18, 18, 18, 19, 18, 18, 19,
+ 19, 19, 19, 19, 19, 42, 38, 40,
+ 40, 40, 38, 42, 44, 43, 41, 41,
+ 41, 41, 43, 44, 45, 45, 42, 42,
+ 42, 45, 45, 48, 46, 43, 43, 46,
+ 48, 49, 48, 44, 48, 49, 101, 98,
+ 98, 101, 104, 109, 104, 116, 116, 123,
+};
+static const uint16_t dv_iweight_1080_c[64] = {
+ 128, 16, 16, 17, 17, 17, 25, 25,
+ 25, 25, 26, 25, 26, 25, 26, 26,
+ 26, 27, 27, 26, 26, 42, 38, 40,
+ 40, 40, 38, 42, 44, 43, 41, 41,
+ 41, 41, 43, 44, 91, 91, 84, 84,
+ 84, 91, 91, 96, 93, 86, 86, 93,
+ 96, 197, 191, 177, 191, 197, 203, 197,
+ 197, 203, 209, 219, 209, 232, 232, 246,
+};
+static const uint16_t dv_iweight_720_y[64] = {
+ 128, 16, 16, 17, 17, 17, 18, 18,
+ 18, 18, 18, 18, 19, 18, 18, 19,
+ 19, 19, 19, 19, 19, 42, 38, 40,
+ 40, 40, 38, 42, 44, 43, 41, 41,
+ 41, 41, 43, 44, 68, 68, 63, 63,
+ 63, 68, 68, 96, 92, 86, 86, 92,
+ 96, 98, 96, 88, 96, 98, 202, 196,
+ 196, 202, 208, 218, 208, 232, 232, 246,
+};
+const uint16_t dv_iweight_720_c[64] = {
+ 128, 24, 24, 26, 26, 26, 36, 36,
+ 36, 36, 36, 36, 38, 36, 36, 38,
+ 38, 38, 38, 38, 38, 84, 76, 80,
+ 80, 80, 76, 84, 88, 86, 82, 82,
+ 82, 82, 86, 88, 182, 182, 168, 168,
+ 168, 182, 182, 192, 186, 192, 172, 186,
+ 192, 394, 382, 354, 382, 394, 406, 394,
+ 394, 406, 418, 438, 418, 464, 464, 492,
+};
+
+static void dv_init_weight_tables(DVVideoContext *ctx, const AVDVProfile *d)
+{
+ int j, i, c, s;
+ uint32_t *factor1 = &ctx->idct_factor[0],
+ *factor2 = &ctx->idct_factor[DV_PROFILE_IS_HD(d) ? 4096 : 2816];
+
+ if (DV_PROFILE_IS_HD(d)) {
+ /* quantization quanta by QNO for DV100 */
+ static const uint8_t dv100_qstep[16] = {
+ 1, /* QNO = 0 and 1 both have no quantization */
+ 1,
+ 2, 3, 4, 5, 6, 7, 8, 16, 18, 20, 22, 24, 28, 52
+ };
+ const uint16_t *iweight1, *iweight2;
+
+ if (d->height == 720) {
+ iweight1 = &dv_iweight_720_y[0];
+ iweight2 = &dv_iweight_720_c[0];
+ } else {
+ iweight1 = &dv_iweight_1080_y[0];
+ iweight2 = &dv_iweight_1080_c[0];
+ }
+ for (c = 0; c < 4; c++) {
+ for (s = 0; s < 16; s++) {
+ for (i = 0; i < 64; i++) {
+ *factor1++ = (dv100_qstep[s] << (c + 9)) * iweight1[i];
+ *factor2++ = (dv100_qstep[s] << (c + 9)) * iweight2[i];
+ }
+ }
+ }
+ } else {
+ static const uint8_t dv_quant_areas[4] = { 6, 21, 43, 64 };
+ const uint16_t *iweight1 = &dv_iweight_88[0];
+ for (j = 0; j < 2; j++, iweight1 = &dv_iweight_248[0]) {
+ for (s = 0; s < 22; s++) {
+ for (i = c = 0; c < 4; c++) {
+ for (; i < dv_quant_areas[c]; i++) {
+ *factor1 = iweight1[i] << (ff_dv_quant_shifts[s][c] + 1);
+ *factor2++ = (*factor1++) << 1;
+ }
+ }
+ }
+ }
+ }
+}
+
static av_cold int dvvideo_decode_init(AVCodecContext *avctx)
{
DVVideoContext *s = avctx->priv_data;
int apt, is16_9, ret;
const AVDVProfile *sys;
- sys = avpriv_dv_frame_profile2(avctx, s->sys, buf, buf_size);
+ sys = ff_dv_frame_profile(avctx, s->sys, buf, buf_size);
if (!sys || buf_size < sys->frame_size) {
av_log(avctx, AV_LOG_ERROR, "could not find dv frame profile\n");
return -1; /* NOTE: we only accept several full frames */
av_log(avctx, AV_LOG_ERROR, "Error initializing the work tables.\n");
return ret;
}
+ dv_init_weight_tables(s, sys);
s->sys = sys;
}
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;
+ avctx->framerate = av_inv_q(s->sys->time_base);
ret = ff_set_dimensions(avctx, s->sys->width, s->sys->height);
if (ret < 0)
if (*vsc_pack == dv_video_control) {
apt = buf[4] & 0x07;
is16_9 = (vsc_pack[2] & 0x07) == 0x02 ||
- (!apt && (vsc_pack[2] & 0x07) == 0x07);
+ (!apt && (vsc_pack[2] & 0x07) == 0x07);
ff_set_sar(avctx, s->sys->sar[is16_9]);
}
#include "libavutil/opt.h"
#include "libavutil/imgutils.h"
#include "libavutil/avstring.h"
+#include "libavutil/bswap.h"
typedef struct DVDSubContext
{
AVClass *class;
uint32_t palette[16];
char *palette_str;
+ char *ifo_str;
int has_palette;
uint8_t colormap[4];
uint8_t alpha[256];
uint8_t *buf;
int buf_size;
+ int forced_subs_only;
#ifdef DEBUG
int sub_id;
#endif
if (!is_menu && find_smallest_bounding_rectangle(sub) == 0)
goto no_subtitle;
+ if (ctx->forced_subs_only && !(sub->rects[0]->flags & AV_SUBTITLE_FLAG_FORCED))
+ goto no_subtitle;
+
#if defined(DEBUG)
{
char ppm_name[32];
}
}
+static int parse_ifo_palette(DVDSubContext *ctx, char *p)
+{
+ FILE *ifo;
+ char ifostr[12];
+ uint32_t sp_pgci, pgci, off_pgc, pgc;
+ uint8_t r, g, b, yuv[65], *buf;
+ int i, y, cb, cr, r_add, g_add, b_add;
+ int ret = 0;
+ const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP;
+
+ ctx->has_palette = 0;
+ if ((ifo = fopen(p, "r")) == NULL) {
+ av_log(ctx, AV_LOG_WARNING, "Unable to open IFO file \"%s\": %s\n", p, strerror(errno));
+ return AVERROR_EOF;
+ }
+ if (fread(ifostr, 12, 1, ifo) != 1 || memcmp(ifostr, "DVDVIDEO-VTS", 12)) {
+ av_log(ctx, AV_LOG_WARNING, "\"%s\" is not a proper IFO file\n", p);
+ ret = AVERROR_INVALIDDATA;
+ goto end;
+ }
+ if (fseek(ifo, 0xCC, SEEK_SET) == -1) {
+ ret = AVERROR(errno);
+ goto end;
+ }
+ if (fread(&sp_pgci, 4, 1, ifo) == 1) {
+ pgci = av_be2ne32(sp_pgci) * 2048;
+ if (fseek(ifo, pgci + 0x0C, SEEK_SET) == -1) {
+ ret = AVERROR(errno);
+ goto end;
+ }
+ if (fread(&off_pgc, 4, 1, ifo) == 1) {
+ pgc = pgci + av_be2ne32(off_pgc);
+ if (fseek(ifo, pgc + 0xA4, SEEK_SET) == -1) {
+ ret = AVERROR(errno);
+ goto end;
+ }
+ if (fread(yuv, 64, 1, ifo) == 1) {
+ buf = yuv;
+ for(i=0; i<16; i++) {
+ y = *++buf;
+ cr = *++buf;
+ cb = *++buf;
+ YUV_TO_RGB1_CCIR(cb, cr);
+ YUV_TO_RGB2_CCIR(r, g, b, y);
+ ctx->palette[i] = (r << 16) + (g << 8) + b;
+ buf++;
+ }
+ ctx->has_palette = 1;
+ }
+ }
+ }
+ if (ctx->has_palette == 0) {
+ av_log(ctx, AV_LOG_WARNING, "Failed to read palette from IFO file \"%s\"\n", p);
+ ret = AVERROR_INVALIDDATA;
+ }
+end:
+ fclose(ifo);
+ return ret;
+}
+
static int dvdsub_parse_extradata(AVCodecContext *avctx)
{
DVDSubContext *ctx = (DVDSubContext*) avctx->priv_data;
char *dataorig, *data;
+ int ret = 1;
if (!avctx->extradata || !avctx->extradata_size)
return 1;
} else if (strncmp("size:", data, 5) == 0) {
int w, h;
if (sscanf(data + 5, "%dx%d", &w, &h) == 2) {
- int ret = ff_set_dimensions(avctx, w, h);
- if (ret < 0) {
- av_free(dataorig);
- return ret;
- }
+ ret = ff_set_dimensions(avctx, w, h);
+ if (ret < 0)
+ goto fail;
}
}
data += strspn(data, "\n\r");
}
+fail:
av_free(dataorig);
- return 1;
+ return ret;
}
static av_cold int dvdsub_init(AVCodecContext *avctx)
if ((ret = dvdsub_parse_extradata(avctx)) < 0)
return ret;
+ if (ctx->ifo_str)
+ parse_ifo_palette(ctx, ctx->ifo_str);
if (ctx->palette_str)
parse_palette(ctx, ctx->palette_str);
if (ctx->has_palette) {
}
#define OFFSET(field) offsetof(DVDSubContext, field)
-#define VD AV_OPT_FLAG_SUBTITLE_PARAM | AV_OPT_FLAG_DECODING_PARAM
+#define SD AV_OPT_FLAG_SUBTITLE_PARAM | AV_OPT_FLAG_DECODING_PARAM
static const AVOption options[] = {
- { "palette", "set the global palette", OFFSET(palette_str), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, VD },
+ { "palette", "set the global palette", OFFSET(palette_str), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, SD },
+ { "ifo_palette", "obtain the global palette from .IFO file", OFFSET(ifo_str), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, SD },
+ { "forced_subs_only", "Only show forced subtitles", OFFSET(forced_subs_only), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, SD},
{ NULL }
};
static const AVClass dvdsub_class = {
.init = dvvideo_encode_init,
.encode2 = dvvideo_encode_frame,
.close = dvvideo_encode_close,
- .capabilities = CODEC_CAP_SLICE_THREADS,
+ .capabilities = CODEC_CAP_SLICE_THREADS | CODEC_CAP_FRAME_THREADS | CODEC_CAP_INTRA_ONLY,
.pix_fmts = (const enum AVPixelFormat[]) {
AV_PIX_FMT_YUV411P, AV_PIX_FMT_YUV422P,
AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE
V = pic->data[2];
for (h = 0; h < avctx->height; h += 4) {
for (w = 0; w < avctx->width; w += 4) {
- AV_COPY32(Y1 + w, src);
- AV_COPY32(Y2 + w, src + 4);
- AV_COPY32(Y3 + w, src + 8);
- AV_COPY32(Y4 + w, src + 12);
+ AV_COPY32U(Y1 + w, src);
+ AV_COPY32U(Y2 + w, src + 4);
+ AV_COPY32U(Y3 + w, src + 8);
+ AV_COPY32U(Y4 + w, src + 12);
U[w >> 2] = src[16] + 0x80;
V[w >> 2] = src[17] + 0x80;
src += 18;
{
GetByteContext gb;
GetBitContext gb2;
- int nslices, slice, slice_height, ref_slice_height;
+ int nslices, slice, slice_height;
int cur_y, next_y;
uint32_t off, slice_size;
uint8_t *Y, *U, *V;
return AVERROR_INVALIDDATA;
}
- if (!nslices || avctx->height % nslices) {
+ if (!nslices) {
avpriv_request_sample(avctx, "%d slices for %dx%d", nslices,
avctx->width, avctx->height);
return AVERROR_PATCHWELCOME;
}
- ref_slice_height = avctx->height / nslices;
if ((avctx->width & 3) || (avctx->height & 3)) {
avpriv_request_sample(avctx, "Frame dimensions %dx%d",
avctx->width, avctx->height);
V = pic->data[2];
cur_y = 0;
- next_y = ref_slice_height;
for (slice = 0; slice < nslices; slice++) {
slice_size = bytestream2_get_le32(&gb);
+ next_y = ((slice + 1) * avctx->height) / nslices;
slice_height = (next_y & ~3) - (cur_y & ~3);
if (slice_size > src_size - off) {
av_log(avctx, AV_LOG_ERROR,
V += pic->linesize[2] * (slice_height >> 2);
off += slice_size;
cur_y = next_y;
- next_y += ref_slice_height;
}
return 0;
{
GetByteContext gb;
GetBitContext gb2;
- int nslices, slice, slice_height, ref_slice_height;
+ int nslices, slice, slice_height;
int cur_y, next_y;
uint32_t off, slice_size;
uint8_t *Y, *U, *V;
return AVERROR_INVALIDDATA;
}
- if (!nslices || avctx->height % nslices) {
+ if (!nslices) {
avpriv_request_sample(avctx, "%d slices for %dx%d", nslices,
avctx->width, avctx->height);
return AVERROR_PATCHWELCOME;
}
- ref_slice_height = avctx->height / nslices;
if ((avctx->width & 1) || (avctx->height & 1)) {
avpriv_request_sample(avctx, "Frame dimensions %dx%d",
avctx->width, avctx->height);
V = pic->data[2];
cur_y = 0;
- next_y = ref_slice_height;
for (slice = 0; slice < nslices; slice++) {
slice_size = bytestream2_get_le32(&gb);
+ next_y = ((slice + 1) * avctx->height) / nslices;
slice_height = (next_y & ~1) - (cur_y & ~1);
if (slice_size > src_size - off) {
av_log(avctx, AV_LOG_ERROR,
V += pic->linesize[2] * (slice_height >> 1);
off += slice_size;
cur_y = next_y;
- next_y += ref_slice_height;
}
return 0;
fps = AV_RL16(&buf[10]);
if (fps > 0)
- s->avctx->time_base = (AVRational){ 1, fps };
+ s->avctx->framerate = (AVRational){ fps, 1 };
pal_start = AV_RL16(&buf[12]);
pal_count = AV_RL16(&buf[14]);
inter = (chunk_type == MADm_TAG || chunk_type == MADe_TAG);
bytestream2_skip(&gb, 10);
- av_reduce(&avctx->time_base.num, &avctx->time_base.den,
+ av_reduce(&avctx->framerate.den, &avctx->framerate.num,
bytestream2_get_le16(&gb), 1000, 1<<30);
width = bytestream2_get_le16(&gb);
{
MadContext *t = avctx->priv_data;
av_frame_free(&t->last_frame);
- av_free(t->bitstream_buf);
+ av_freep(&t->bitstream_buf);
return 0;
}
s->avctx = avctx;
ff_init_scantable_permutation(idct_permutation, FF_IDCT_PERM_NONE);
ff_init_scantable(idct_permutation, &s->scantable, ff_zigzag_direct);
- avctx->time_base = (AVRational){1, 15};
+ avctx->framerate = (AVRational){ 15, 1 };
avctx->pix_fmt = AV_PIX_FMT_YUV420P;
return 0;
}
{
TgvContext *s = avctx->priv_data;
s->avctx = avctx;
- avctx->time_base = (AVRational){1, 15};
+ avctx->framerate = (AVRational){ 15, 1 };
avctx->pix_fmt = AV_PIX_FMT_PAL8;
s->last_frame = av_frame_alloc();
TgvContext *s = avctx->priv_data;
av_frame_free(&s->last_frame);
av_freep(&s->frame_buffer);
- av_free(s->mv_codebook);
- av_free(s->block_codebook);
+ av_freep(&s->mv_codebook);
+ av_freep(&s->block_codebook);
return 0;
}
ff_init_scantable_permutation(s->idsp.idct_permutation, FF_IDCT_PERM_NONE);
ff_init_scantable(s->idsp.idct_permutation, &s->intra_scantable, ff_zigzag_direct);
s->qscale = 1;
- avctx->time_base = (AVRational){1, 15};
+ avctx->framerate = (AVRational){ 15, 1 };
avctx->pix_fmt = AV_PIX_FMT_YUV420P;
ff_mpeg12_init_vlcs();
return 0;
static av_cold int tqi_decode_end(AVCodecContext *avctx)
{
TqiContext *t = avctx->priv_data;
- av_free(t->bitstream_buf);
+ av_freep(&t->bitstream_buf);
return 0;
}
int best_score = 256 * 256 * 256 * 64;
int best_pred = 0;
const int mot_index = (mb_x + mb_y * mot_stride) * mot_step;
- int prev_x, prev_y, prev_ref;
+ int prev_x = 0, prev_y = 0, prev_ref = 0;
if ((mb_x ^ mb_y ^ pass) & 1)
continue;
void ff_er_frame_end(ERContext *s)
{
- int *linesize = s->cur_pic.f->linesize;
+ int *linesize = NULL;
int i, mb_x, mb_y, error, error_type, dc_error, mv_error, ac_error;
int distance;
int threshold_part[4] = { 100, 100, 100 };
(s->avctx->skip_top + s->avctx->skip_bottom)) {
return;
}
+ linesize = s->cur_pic.f->linesize;
for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
int status = s->error_status_table[mb_x + (s->mb_height - 1) * s->mb_stride];
if (status != 0x7F)
Escape124Context *s = avctx->priv_data;
for (i = 0; i < 3; i++)
- av_free(s->codebooks[i].blocks);
+ av_freep(&s->codebooks[i].blocks);
av_frame_free(&s->frame);
// This function reads a maximum of 22 bits; the callers
// guard this function appropriately
unsigned block_index, depth;
-
- if (get_bits1(gb)) {
+ int value = get_bits1(gb);
+ if (value) {
static const char transitions[3][2] = { {2, 1}, {0, 2}, {1, 0} };
- *codebook_index = transitions[*codebook_index][get_bits1(gb)];
+ value = get_bits1(gb);
+ *codebook_index = transitions[*codebook_index][value];
}
depth = s->codebooks[*codebook_index].depth;
cb_size = s->num_superblocks << cb_depth;
}
}
- av_free(s->codebooks[i].blocks);
+ av_freep(&s->codebooks[i].blocks);
s->codebooks[i] = unpack_codebook(&gb, cb_depth, cb_size);
if (!s->codebooks[i].blocks)
return -1;
int32_t im, int32_t iM, uint64_t *hcode)
{
GetBitContext gbit;
-
- init_get_bits8(&gbit, gb->buffer, bytestream2_get_bytes_left(gb));
+ int ret = init_get_bits8(&gbit, gb->buffer, bytestream2_get_bytes_left(gb));
+ if (ret < 0)
+ return ret;
for (; im <= iM; im++) {
uint64_t l = hcode[im] = get_bits(&gbit, 6);
return 0;
{
- FFV1Context bak = *fdst;
+ ThreadFrame picture = fdst->picture, last_picture = fdst->last_picture;
+ uint8_t (*initial_states[MAX_QUANT_TABLES])[32];
+ struct FFV1Context *slice_context[MAX_SLICES];
+ memcpy(initial_states, fdst->initial_states, sizeof(fdst->initial_states));
+ memcpy(slice_context, fdst->slice_context , sizeof(fdst->slice_context));
+
memcpy(fdst, fsrc, sizeof(*fdst));
- memcpy(fdst->initial_states, bak.initial_states, sizeof(fdst->initial_states));
- memcpy(fdst->slice_context, bak.slice_context , sizeof(fdst->slice_context));
- fdst->picture = bak.picture;
- fdst->last_picture = bak.last_picture;
+ memcpy(fdst->initial_states, initial_states, sizeof(fdst->initial_states));
+ memcpy(fdst->slice_context, slice_context , sizeof(fdst->slice_context));
+ fdst->picture = picture;
+ fdst->last_picture = last_picture;
for (i = 0; i<fdst->num_h_slices * fdst->num_v_slices; i++) {
FFV1Context *fssrc = fsrc->slice_context[i];
FFV1Context *fsdst = fdst->slice_context[i];
best_len[k] = len;
best_state[i][k] = j;
}
- for (m = 0; m < 256; m++)
+ for (m = 1; m < 256; m++)
if (occ[m]) {
newocc[ one_state[ m]] += occ[m] * p;
newocc[256 - one_state[256 - m]] += occ[m] * (1 - p);
return AVERROR_INVALIDDATA;
}
- if (tsize < 32) {
+ if (!tsize)
+ skip_cursor = 1;
+
+ if (!skip_cursor && tsize < 32) {
av_log(avctx, AV_LOG_WARNING,
"Cursor data too small. Skipping cursor.\n");
skip_cursor = 1;
/* Cursor position. */
cur_x = AV_RL16(src + 33);
cur_y = AV_RL16(src + 35);
- if (cur_x > avctx->width || cur_y > avctx->height) {
+ if (!skip_cursor && (cur_x > avctx->width || cur_y > avctx->height)) {
av_log(avctx, AV_LOG_WARNING,
"Invalid cursor position: (%d,%d). Skipping cusor.\n",
cur_x, cur_y);
skip_cursor = 1;
}
- if (AV_RL16(src + 37) != 32 || AV_RL16(src + 39) != 32) {
+ if (!skip_cursor && (AV_RL16(src + 37) != 32 || AV_RL16(src + 39) != 32)) {
av_log(avctx, AV_LOG_WARNING,
"Invalid cursor size. Skipping cursor.\n");
skip_cursor = 1;
return count;
}
-int avpriv_flac_is_extradata_valid(AVCodecContext *avctx,
+int ff_flac_is_extradata_valid(AVCodecContext *avctx,
enum FLACExtradataFormat *format,
uint8_t **streaminfo_start)
{
avctx->channel_layout = 0;
}
-void avpriv_flac_parse_streaminfo(AVCodecContext *avctx, struct FLACStreaminfo *s,
+void ff_flac_parse_streaminfo(AVCodecContext *avctx, struct FLACStreaminfo *s,
const uint8_t *buffer)
{
GetBitContext gb;
skip_bits_long(&gb, 64); /* md5 sum */
skip_bits_long(&gb, 64); /* md5 sum */
}
+
+#if LIBAVCODEC_VERSION_MAJOR < 57
+void avpriv_flac_parse_streaminfo(AVCodecContext *avctx, struct FLACStreaminfo *s,
+ const uint8_t *buffer)
+{
+ ff_flac_parse_streaminfo(avctx, s, buffer);
+}
+
+int avpriv_flac_is_extradata_valid(AVCodecContext *avctx,
+ enum FLACExtradataFormat *format,
+ uint8_t **streaminfo_start)
+{
+ return ff_flac_is_extradata_valid(avctx, format, streaminfo_start);
+}
+#endif
* @param[out] s where parsed information is stored
* @param[in] buffer pointer to start of 34-byte streaminfo data
*/
+void ff_flac_parse_streaminfo(AVCodecContext *avctx, struct FLACStreaminfo *s,
+ const uint8_t *buffer);
+
+#if LIBAVCODEC_VERSION_MAJOR < 57
void avpriv_flac_parse_streaminfo(AVCodecContext *avctx, struct FLACStreaminfo *s,
const uint8_t *buffer);
+int avpriv_flac_is_extradata_valid(AVCodecContext *avctx,
+ enum FLACExtradataFormat *format,
+ uint8_t **streaminfo_start);
+#endif
/**
* Validate the FLAC extradata.
* @param[out] streaminfo_start pointer to start of 34-byte STREAMINFO data.
* @return 1 if valid, 0 if not valid.
*/
-int avpriv_flac_is_extradata_valid(AVCodecContext *avctx,
- enum FLACExtradataFormat *format,
- uint8_t **streaminfo_start);
+int ff_flac_is_extradata_valid(AVCodecContext *avctx,
+ enum FLACExtradataFormat *format,
+ uint8_t **streaminfo_start);
/**
* Calculate an estimate for the maximum frame size based on verbatim mode.
curr = temp;
}
av_fifo_freep(&fpc->fifo_buf);
- av_free(fpc->wrap_buf);
+ av_freep(&fpc->wrap_buf);
}
AVCodecParser ff_flac_parser = {
#include <limits.h>
#include "libavutil/avassert.h"
-#include "libavutil/channel_layout.h"
#include "libavutil/crc.h"
#include "avcodec.h"
#include "internal.h"
if (!avctx->extradata)
return 0;
- if (!avpriv_flac_is_extradata_valid(avctx, &format, &streaminfo))
+ if (!ff_flac_is_extradata_valid(avctx, &format, &streaminfo))
return AVERROR_INVALIDDATA;
/* initialize based on the demuxer-supplied streamdata header */
- avpriv_flac_parse_streaminfo(avctx, (FLACStreaminfo *)s, streaminfo);
+ ff_flac_parse_streaminfo(avctx, (FLACStreaminfo *)s, streaminfo);
ret = allocate_buffers(s);
if (ret < 0)
return ret;
flac_set_bps(s);
- ff_flacdsp_init(&s->dsp, avctx->sample_fmt, s->bps);
+ ff_flacdsp_init(&s->dsp, avctx->sample_fmt, s->channels, s->bps);
s->got_streaminfo = 1;
return 0;
metadata_size != FLAC_STREAMINFO_SIZE) {
return AVERROR_INVALIDDATA;
}
- avpriv_flac_parse_streaminfo(s->avctx, (FLACStreaminfo *)s, &buf[8]);
+ ff_flac_parse_streaminfo(s->avctx, (FLACStreaminfo *)s, &buf[8]);
ret = allocate_buffers(s);
if (ret < 0)
return ret;
flac_set_bps(s);
- ff_flacdsp_init(&s->dsp, s->avctx->sample_fmt, s->bps);
+ ff_flacdsp_init(&s->dsp, s->avctx->sample_fmt, s->channels, s->bps);
s->got_streaminfo = 1;
return 0;
if (get_bits1(&s->gb)) {
int left = get_bits_left(&s->gb);
- if ( left < 0 ||
+ if ( left <= 0 ||
(left < bps && !show_bits_long(&s->gb, left)) ||
!show_bits_long(&s->gb, bps)) {
av_log(s->avctx, AV_LOG_ERROR,
ret = allocate_buffers(s);
if (ret < 0)
return ret;
- ff_flacdsp_init(&s->dsp, s->avctx->sample_fmt, s->bps);
s->got_streaminfo = 1;
dump_headers(s->avctx, (FLACStreaminfo *)s);
}
+ ff_flacdsp_init(&s->dsp, s->avctx->sample_fmt, s->channels, s->bps);
// dump_headers(s->avctx, (FLACStreaminfo *)s);
}
-av_cold void ff_flacdsp_init(FLACDSPContext *c, enum AVSampleFormat fmt,
+av_cold void ff_flacdsp_init(FLACDSPContext *c, enum AVSampleFormat fmt, int channels,
int bps)
{
if (bps > 16) {
}
if (ARCH_ARM)
- ff_flacdsp_init_arm(c, fmt, bps);
+ ff_flacdsp_init_arm(c, fmt, channels, bps);
if (ARCH_X86)
- ff_flacdsp_init_x86(c, fmt, bps);
+ ff_flacdsp_init_x86(c, fmt, channels, bps);
}
const int32_t coefs[32], int shift);
} FLACDSPContext;
-void ff_flacdsp_init(FLACDSPContext *c, enum AVSampleFormat fmt, int bps);
-void ff_flacdsp_init_arm(FLACDSPContext *c, enum AVSampleFormat fmt, int bps);
-void ff_flacdsp_init_x86(FLACDSPContext *c, enum AVSampleFormat fmt, int bps);
+void ff_flacdsp_init(FLACDSPContext *c, enum AVSampleFormat fmt, int channels, int bps);
+void ff_flacdsp_init_arm(FLACDSPContext *c, enum AVSampleFormat fmt, int channels, int bps);
+void ff_flacdsp_init_x86(FLACDSPContext *c, enum AVSampleFormat fmt, int channels, int bps);
#endif /* AVCODEC_FLACDSP_H */
s->options.max_prediction_order, FF_LPC_TYPE_LEVINSON);
ff_bswapdsp_init(&s->bdsp);
- ff_flacdsp_init(&s->flac_dsp, avctx->sample_fmt,
+ ff_flacdsp_init(&s->flac_dsp, avctx->sample_fmt, channels,
avctx->bits_per_raw_sample);
dprint_compression_options(s);
if ((avctx->width > 4095) || (avctx->height > 4095)) {
av_log(avctx, AV_LOG_ERROR,
- "Input dimensions too large, input must be max 4096x4096 !\n");
+ "Input dimensions too large, input must be max 4095x4095 !\n");
return -1;
}
if ((avctx->width < 16) || (avctx->height < 16)) {
deflateEnd(&s->zstream);
- av_free(s->encbuffer);
- av_free(s->previous_frame);
- av_free(s->tmpblock);
+ av_freep(&s->encbuffer);
+ av_freep(&s->previous_frame);
+ av_freep(&s->tmpblock);
av_frame_free(&avctx->coded_frame);
magic = bytestream2_get_be32(&bc);
if ((magic & ~0xF) != MKBETAG('G', '2', 'M', '0') ||
- (magic & 0xF) < 2 || (magic & 0xF) > 4) {
+ (magic & 0xF) < 2 || (magic & 0xF) > 5) {
av_log(avctx, AV_LOG_ERROR, "Wrong magic %08X\n", magic);
return AVERROR_INVALIDDATA;
}
- if ((magic & 0xF) != 4) {
+ if ((magic & 0xF) < 4) {
av_log(avctx, AV_LOG_ERROR, "G2M2 and G2M3 are not yet supported\n");
return AVERROR(ENOSYS);
}
a common packet size for VoIP applications */
avctx->frame_size = 320;
}
- avctx->delay = 22;
+ avctx->initial_padding = 22;
if (avctx->trellis) {
/* validate trellis */
}
if (frame->pts != AV_NOPTS_VALUE)
- avpkt->pts = frame->pts - ff_samples_to_time_base(avctx, avctx->delay);
+ avpkt->pts = frame->pts - ff_samples_to_time_base(avctx, avctx->initial_padding);
*got_packet_ptr = 1;
return 0;
}
i += 32;
s->picture_number = (s->picture_number & ~31) + i;
- s->avctx->time_base = (AVRational) { 1001, 30000 };
+ s->avctx->framerate = (AVRational) { 30000, 1001 };
/* PTYPE starts here */
skip_bits1(&s->gb); /* split screen off */
#if !FF_API_ASPECT_EXTENDED
#define FF_ASPECT_EXTENDED 15
#endif
+#define INT_BIT (CHAR_BIT * sizeof(int))
// 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
#include "vdpau_internal.h"
#include "thread.h"
+static enum AVPixelFormat h263_get_format(AVCodecContext *avctx)
+{
+ if (avctx->codec->id == AV_CODEC_ID_MSS2)
+ return AV_PIX_FMT_YUV420P;
+
+ return avctx->pix_fmt = ff_get_format(avctx, avctx->codec->pix_fmts);
+}
+
av_cold int ff_h263_decode_init(AVCodecContext *avctx)
{
MpegEncContext *s = avctx->priv_data;
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 = ff_get_format(avctx, avctx->codec->pix_fmts);
s->unrestricted_mv = 1;
/* select sub codec */
if (avctx->codec->id != AV_CODEC_ID_H263 &&
avctx->codec->id != AV_CODEC_ID_H263P &&
avctx->codec->id != AV_CODEC_ID_MPEG4) {
+ avctx->pix_fmt = h263_get_format(avctx);
ff_mpv_idct_init(s);
if ((ret = ff_mpv_common_init(s)) < 0)
return ret;
}
if (s->workaround_bugs & FF_BUG_AUTODETECT) {
- if (s->padding_bug_score > -2 && !s->data_partitioning)
+ if (
+ (s->padding_bug_score > -2 && !s->data_partitioning))
s->workaround_bugs |= FF_BUG_NO_PADDING;
else
s->workaround_bugs &= ~FF_BUG_NO_PADDING;
return ret;
}
- if (!s->context_initialized)
+ if (!s->context_initialized) {
+ avctx->pix_fmt = h263_get_format(avctx);
if ((ret = ff_mpv_common_init(s)) < 0)
return ret;
+ }
if (!s->current_picture_ptr || s->current_picture_ptr->f->data[0]) {
int i = ff_find_unused_picture(s, 0);
if ((ret = ff_mpv_common_frame_size_change(s)))
return ret;
+
+ if (avctx->pix_fmt != h263_get_format(avctx)) {
+ av_log(avctx, AV_LOG_ERROR, "format change not supported\n");
+ avctx->pix_fmt = AV_PIX_FMT_NONE;
+ return AVERROR_UNKNOWN;
+ }
}
if (s->codec_id == AV_CODEC_ID_H263 ||
if (rotation) {
av_display_rotation_set((int32_t *)rotation->data, angle);
av_display_matrix_flip((int32_t *)rotation->data,
- h->sei_vflip, h->sei_hflip);
+ h->sei_hflip, h->sei_vflip);
}
}
#define CABAC(h) 1
#define UNCHECKED_BITSTREAM_READER 1
+#define INT_BIT (CHAR_BIT * sizeof(int))
#include "libavutil/attributes.h"
#include "libavutil/avassert.h"
return FFMAX(0, bottom);
}
-static inline void get_lowest_part_y(H264Context *h, int refs[2][48], int n,
+static inline void get_lowest_part_y(H264Context *h, int16_t refs[2][48], int n,
int height, int y_offset, int list0,
int list1, int *nrefs)
{
{
const int mb_xy = h->mb_xy;
const int mb_type = h->cur_pic.mb_type[mb_xy];
- int refs[2][48];
+ int16_t refs[2][48];
int nrefs[2] = { 0 };
int ref, list;
#include "avcodec.h"
typedef struct H264BSFContext {
+ int32_t sps_offset;
+ int32_t pps_offset;
uint8_t length_size;
uint8_t new_idr;
- uint8_t idr_sps_pps_seen;
+ uint8_t idr_sps_seen;
+ uint8_t idr_pps_seen;
int extradata_parsed;
} H264BSFContext;
return 0;
}
-static int h264_extradata_to_annexb(AVCodecContext *avctx, const int padding)
+static int h264_extradata_to_annexb(H264BSFContext *ctx, AVCodecContext *avctx, const int padding)
{
uint16_t unit_size;
uint64_t total_size = 0;
static const uint8_t nalu_header[4] = { 0, 0, 0, 1 };
int length_size = (*extradata++ & 0x3) + 1; // retrieve length coded size
+ ctx->sps_offset = ctx->pps_offset = -1;
+
/* retrieve sps and pps unit(s) */
unit_nb = *extradata++ & 0x1f; /* number of sps unit(s) */
if (!unit_nb) {
goto pps;
} else {
+ ctx->sps_offset = 0;
sps_seen = 1;
}
pps:
if (!unit_nb && !sps_done++) {
unit_nb = *extradata++; /* number of pps unit(s) */
- if (unit_nb)
+ if (unit_nb) {
+ ctx->pps_offset = (extradata - 1) - (avctx->extradata + 4);
pps_seen = 1;
+ }
}
}
if (out)
- memset(out + total_size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
+ memset(out + total_size, 0, padding);
if (!sps_seen)
av_log(avctx, AV_LOG_WARNING,
/* retrieve sps and pps NAL units from extradata */
if (!ctx->extradata_parsed) {
- ret = h264_extradata_to_annexb(avctx, FF_INPUT_BUFFER_PADDING_SIZE);
+ ret = h264_extradata_to_annexb(ctx, avctx, FF_INPUT_BUFFER_PADDING_SIZE);
if (ret < 0)
return ret;
ctx->length_size = ret;
ctx->new_idr = 1;
- ctx->idr_sps_pps_seen = 0;
+ ctx->idr_sps_seen = 0;
+ ctx->idr_pps_seen = 0;
ctx->extradata_parsed = 1;
}
if (buf + nal_size > buf_end || nal_size < 0)
goto fail;
- if (unit_type == 7 || unit_type == 8)
- ctx->idr_sps_pps_seen = 1;
+ if (unit_type == 7)
+ ctx->idr_sps_seen = ctx->new_idr = 1;
+ else if (unit_type == 8) {
+ ctx->idr_pps_seen = ctx->new_idr = 1;
+ /* if SPS has not been seen yet, prepend the AVCC one to PPS */
+ if (!ctx->idr_sps_seen) {
+ if (ctx->sps_offset == -1)
+ av_log(avctx, AV_LOG_WARNING, "SPS not present in the stream, nor in AVCC, stream may be unreadable\n");
+ else {
+ if ((ret = alloc_and_copy(poutbuf, poutbuf_size,
+ avctx->extradata + ctx->sps_offset,
+ ctx->pps_offset != -1 ? ctx->pps_offset : avctx->extradata_size - ctx->sps_offset,
+ buf, nal_size)) < 0)
+ goto fail;
+ ctx->idr_sps_seen = 1;
+ goto next_nal;
+ }
+ }
+ }
/* if this is a new IDR picture following an IDR picture, reset the idr flag.
* Just check first_mb_in_slice to be 0 as this is the simplest solution.
ctx->new_idr = 1;
/* prepend only to the first type 5 NAL unit of an IDR picture, if no sps/pps are already present */
- if (ctx->new_idr && unit_type == 5 && !ctx->idr_sps_pps_seen) {
+ if (ctx->new_idr && unit_type == 5 && !ctx->idr_sps_seen && !ctx->idr_pps_seen) {
if ((ret=alloc_and_copy(poutbuf, poutbuf_size,
avctx->extradata, avctx->extradata_size,
buf, nal_size)) < 0)
goto fail;
ctx->new_idr = 0;
+ /* if only SPS has been seen, also insert PPS */
+ } else if (ctx->new_idr && unit_type == 5 && ctx->idr_sps_seen && !ctx->idr_pps_seen) {
+ if (ctx->pps_offset == -1) {
+ av_log(avctx, AV_LOG_WARNING, "PPS not present in the stream, nor in AVCC, stream may be unreadable\n");
+ if ((ret = alloc_and_copy(poutbuf, poutbuf_size,
+ NULL, 0, buf, nal_size)) < 0)
+ goto fail;
+ } else if ((ret = alloc_and_copy(poutbuf, poutbuf_size,
+ avctx->extradata + ctx->pps_offset, avctx->extradata_size - ctx->pps_offset,
+ buf, nal_size)) < 0)
+ goto fail;
} else {
if ((ret=alloc_and_copy(poutbuf, poutbuf_size,
NULL, 0, buf, nal_size)) < 0)
goto fail;
if (!ctx->new_idr && unit_type == 1) {
ctx->new_idr = 1;
- ctx->idr_sps_pps_seen = 0;
+ ctx->idr_sps_seen = 0;
+ ctx->idr_pps_seen = 0;
}
}
+next_nal:
buf += nal_size;
cumul_size += nal_size + ctx->length_size;
} while (cumul_size < buf_size);
parse_nal_units(s, avctx, buf, buf_size);
+ if (avctx->framerate.num)
+ avctx->time_base = av_inv_q(av_mul_q(avctx->framerate, (AVRational){avctx->ticks_per_frame, 1}));
if (h->sei_cpb_removal_delay >= 0) {
s->dts_sync_point = h->sei_buffering_period_present;
s->dts_ref_dts_delta = h->sei_cpb_removal_delay;
int i;
uint32_t state = -1;
int has_sps = 0;
+ int has_pps = 0;
for (i = 0; i <= buf_size; i++) {
if ((state & 0xFFFFFF1F) == 0x107)
has_sps = 1;
+ if ((state & 0xFFFFFF1F) == 0x108)
+ has_pps = 1;
/* if ((state&0xFFFFFF1F) == 0x101 ||
* (state&0xFFFFFF1F) == 0x102 ||
* (state&0xFFFFFF1F) == 0x105) {
* }
*/
- if ((state & 0xFFFFFF00) == 0x100 && (state & 0xFFFFFF1F) != 0x107 &&
- (state & 0xFFFFFF1F) != 0x108 && (state & 0xFFFFFF1F) != 0x109) {
+ if ((state & 0xFFFFFF00) == 0x100 && ((state & 0xFFFFFF1F) != 0x106 || has_pps) &&
+ (state & 0xFFFFFF1F) != 0x107 && (state & 0xFFFFFF1F) != 0x108 &&
+ (state & 0xFFFFFF1F) != 0x109 && (state & 0xFFFFFF1F) != 0x10d &&
+ (state & 0xFFFFFF1F) != 0x10f) {
if (has_sps) {
while (i > 4 && buf[i - 5] == 0)
i--;
H264Context *h = s->priv_data;
ParseContext *pc = &h->parse_context;
- av_free(pc->buffer);
+ av_freep(&pc->buffer);
ff_h264_free_context(h);
}
#include "internal.h"
#include "avcodec.h"
#include "h264.h"
-#include "h264data.h" //FIXME FIXME FIXME (just for zigzag_scan)
+#include "h264data.h"
#include "golomb.h"
#define MAX_LOG2_MAX_FRAME_NUM (12 + 4)
#define MIN_LOG2_MAX_FRAME_NUM 4
-static const AVRational pixel_aspect[17] = {
- { 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 },
-};
-
#define QP(qP, depth) ((qP) + 6 * ((depth) - 8))
#define CHROMA_QP_TABLE_END(d) \
if (aspect_ratio_idc == EXTENDED_SAR) {
sps->sar.num = get_bits(&h->gb, 16);
sps->sar.den = get_bits(&h->gb, 16);
- } else if (aspect_ratio_idc < FF_ARRAY_ELEMS(pixel_aspect)) {
- sps->sar = pixel_aspect[aspect_ratio_idc];
+ } else if (aspect_ratio_idc < FF_ARRAY_ELEMS(ff_h264_pixel_aspect)) {
+ sps->sar = ff_h264_pixel_aspect[aspect_ratio_idc];
} else {
av_log(h->avctx, AV_LOG_ERROR, "illegal aspect ratio\n");
return AVERROR_INVALIDDATA;
int ff_h264_decode_sei(H264Context *h)
{
- while (get_bits_left(&h->gb) > 16) {
+ while (get_bits_left(&h->gb) > 16 && show_bits(&h->gb, 16)) {
int type = 0;
unsigned size = 0;
unsigned next;
int64_t den = h->sps.time_scale;
if (h->x264_build < 44U)
den *= 2;
- av_reduce(&h->avctx->time_base.num, &h->avctx->time_base.den,
- h->sps.num_units_in_tick, den, 1 << 30);
+ av_reduce(&h->avctx->framerate.den, &h->avctx->framerate.num,
+ h->sps.num_units_in_tick * h->avctx->ticks_per_frame, den, 1 << 30);
}
if (reinit)
{ MB_TYPE_8x8 | MB_TYPE_P0L0 | MB_TYPE_P0L1 | MB_TYPE_P1L0 | MB_TYPE_P1L1, 4, },
};
+static const AVRational ff_h264_pixel_aspect[17] = {
+ { 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 },
+};
#endif /* AVCODEC_H264DATA_H */
}
if (num != 0 && den != 0)
- av_reduce(&s->avctx->time_base.num, &s->avctx->time_base.den,
+ av_reduce(&s->avctx->framerate.den, &s->avctx->framerate.num,
num, den, 1 << 30);
return 0;
static int 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,
- int cbf_luma, int *cbf_cb, int *cbf_cr)
+ int blk_idx, int cbf_luma, int *cbf_cb, int *cbf_cr)
{
HEVCLocalContext *lc = s->HEVClc;
const int log2_trafo_size_c = log2_trafo_size - s->sps->hshift[1];
ptrdiff_t stride = s->frame->linesize[1];
int hshift = s->sps->hshift[1];
int vshift = s->sps->vshift[1];
- int16_t *coeffs_y = lc->tu.coeffs[0];
- int16_t *coeffs = lc->tu.coeffs[1];
+ int16_t *coeffs_y = (int16_t*)lc->edge_emu_buffer;
+ int16_t *coeffs = (int16_t*)lc->edge_emu_buffer2;
int size = 1 << log2_trafo_size_c;
uint8_t *dst = &s->frame->data[1][(y0 >> vshift) * stride +
ptrdiff_t stride = s->frame->linesize[2];
int hshift = s->sps->hshift[2];
int vshift = s->sps->vshift[2];
- int16_t *coeffs_y = lc->tu.coeffs[0];
- int16_t *coeffs = lc->tu.coeffs[1];
+ int16_t *coeffs_y = (int16_t*)lc->edge_emu_buffer;
+ int16_t *coeffs = (int16_t*)lc->edge_emu_buffer2;
int size = 1 << log2_trafo_size_c;
uint8_t *dst = &s->frame->data[2][(y0 >> vshift) * stride +
}
ret = hls_transform_unit(s, x0, y0, xBase, yBase, cb_xBase, cb_yBase,
- log2_cb_size, log2_trafo_size, trafo_depth,
+ log2_cb_size, log2_trafo_size,
blk_idx, cbf_luma, cbf_cb, cbf_cr);
if (ret < 0)
return ret;
int block_w, int block_h, AVFrame *ref1, const Mv *mv1, struct MvField *current_mv)
{
HEVCLocalContext *lc = s->HEVClc;
- DECLARE_ALIGNED(16, int16_t, tmp[MAX_PB_SIZE * MAX_PB_SIZE]);
ptrdiff_t src0stride = ref0->linesize[0];
ptrdiff_t src1stride = ref1->linesize[0];
int pic_width = s->sps->width;
src1stride = edge_emu_stride;
}
- s->hevcdsp.put_hevc_qpel[idx][!!my0][!!mx0](tmp, src0, src0stride,
+ s->hevcdsp.put_hevc_qpel[idx][!!my0][!!mx0](lc->tmp, src0, src0stride,
block_h, mx0, my0, block_w);
if (!weight_flag)
- s->hevcdsp.put_hevc_qpel_bi[idx][!!my1][!!mx1](dst, dststride, src1, src1stride, tmp,
+ s->hevcdsp.put_hevc_qpel_bi[idx][!!my1][!!mx1](dst, dststride, src1, src1stride, lc->tmp,
block_h, mx1, my1, block_w);
else
- s->hevcdsp.put_hevc_qpel_bi_w[idx][!!my1][!!mx1](dst, dststride, src1, src1stride, tmp,
+ s->hevcdsp.put_hevc_qpel_bi_w[idx][!!my1][!!mx1](dst, dststride, src1, src1stride, lc->tmp,
block_h, 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]],
static void chroma_mc_bi(HEVCContext *s, uint8_t *dst0, ptrdiff_t dststride, AVFrame *ref0, AVFrame *ref1,
int x_off, int y_off, int block_w, int block_h, struct MvField *current_mv, int cidx)
{
- DECLARE_ALIGNED(16, int16_t, tmp [MAX_PB_SIZE * MAX_PB_SIZE]);
HEVCLocalContext *lc = s->HEVClc;
uint8_t *src1 = ref0->data[cidx+1];
uint8_t *src2 = ref1->data[cidx+1];
src2stride = edge_emu_stride;
}
- s->hevcdsp.put_hevc_epel[idx][!!my0][!!mx0](tmp, src1, src1stride,
+ s->hevcdsp.put_hevc_epel[idx][!!my0][!!mx0](lc->tmp, src1, src1stride,
block_h, _mx0, _my0, block_w);
if (!weight_flag)
s->hevcdsp.put_hevc_epel_bi[idx][!!my1][!!mx1](dst0, s->frame->linesize[cidx+1],
- src2, src2stride, tmp,
+ src2, src2stride, lc->tmp,
block_h, _mx1, _my1, block_w);
else
s->hevcdsp.put_hevc_epel_bi_w[idx][!!my1][!!mx1](dst0, s->frame->linesize[cidx+1],
- src2, src2stride, tmp,
+ src2, src2stride, lc->tmp,
block_h,
s->sh.chroma_log2_weight_denom,
s->sh.chroma_weight_l0[current_mv->ref_idx[0]][cidx],
static void hevc_await_progress(HEVCContext *s, HEVCFrame *ref,
const Mv *mv, int y0, int height)
{
- int y = (mv->y >> 2) + y0 + height + 9;
+ int y = FFMAX(0, (mv->y >> 2) + y0 + height + 9);
if (s->threads_type == FF_THREAD_FRAME )
ff_thread_await_progress(&ref->tf, y, 0);
}
+static void hevc_luma_mv_mpv_mode(HEVCContext *s, int x0, int y0, int nPbW,
+ int nPbH, int log2_cb_size, int part_idx,
+ int merge_idx, MvField *mv)
+{
+ HEVCLocalContext *lc = s->HEVClc;
+ enum InterPredIdc inter_pred_idc = PRED_L0;
+ int mvp_flag;
+
+ ff_hevc_set_neighbour_available(s, x0, y0, nPbW, nPbH);
+ mv->pred_flag = 0;
+ 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])
+ mv->ref_idx[0]= ff_hevc_ref_idx_lx_decode(s, s->sh.nb_refs[L0]);
+
+ mv->pred_flag = PF_L0;
+ ff_hevc_hls_mvd_coding(s, x0, y0, 0);
+ mvp_flag = ff_hevc_mvp_lx_flag_decode(s);
+ ff_hevc_luma_mv_mvp_mode(s, x0, y0, nPbW, nPbH, log2_cb_size,
+ part_idx, merge_idx, mv, mvp_flag, 0);
+ mv->mv[0].x += lc->pu.mvd.x;
+ mv->mv[0].y += lc->pu.mvd.y;
+ }
+
+ if (inter_pred_idc != PRED_L0) {
+ if (s->sh.nb_refs[L1])
+ mv->ref_idx[1]= ff_hevc_ref_idx_lx_decode(s, s->sh.nb_refs[L1]);
+
+ if (s->sh.mvd_l1_zero_flag == 1 && inter_pred_idc == PRED_BI) {
+ AV_ZERO32(&lc->pu.mvd);
+ } else {
+ ff_hevc_hls_mvd_coding(s, x0, y0, 1);
+ }
+
+ mv->pred_flag += PF_L1;
+ mvp_flag = ff_hevc_mvp_lx_flag_decode(s);
+ ff_hevc_luma_mv_mvp_mode(s, x0, y0, nPbW, nPbH, log2_cb_size,
+ part_idx, merge_idx, mv, mvp_flag, 1);
+ mv->mv[1].x += lc->pu.mvd.x;
+ mv->mv[1].y += lc->pu.mvd.y;
+ }
+}
+
static void hls_prediction_unit(HEVCContext *s, int x0, int y0,
int nPbW, int nPbH,
int log2_cb_size, int partIdx, int idx)
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)) {
+ int skip_flag = SAMPLE_CTB(s->skip_flag, x_cb, y_cb);
+
+ if (!skip_flag)
+ lc->pu.merge_flag = ff_hevc_merge_flag_decode(s);
+
+ if (skip_flag || 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,
- 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 (j = 0; j < nPbH >> s->sps->log2_min_pu_size; j++)
- for (i = 0; i < nPbW >> s->sps->log2_min_pu_size; i++)
- 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 (j = 0; j < nPbH >> s->sps->log2_min_pu_size; j++)
- for (i = 0; i < nPbW >> s->sps->log2_min_pu_size; i++)
- 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);
- current_mv.pred_flag = 0;
- 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 = PF_L0;
- 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) {
- AV_ZERO32(&lc->pu.mvd);
- } else {
- ff_hevc_hls_mvd_coding(s, x0, y0, 1);
- }
+ ff_hevc_luma_mv_merge_mode(s, x0, y0, nPbW, nPbH, log2_cb_size,
+ partIdx, merge_idx, ¤t_mv);
+ } else {
+ hevc_luma_mv_mpv_mode(s, x0, y0, nPbW, nPbH, log2_cb_size,
+ partIdx, merge_idx, ¤t_mv);
+ }
- current_mv.pred_flag += PF_L1;
- 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;
- x_pu = x0 >> s->sps->log2_min_pu_size;
- y_pu = y0 >> s->sps->log2_min_pu_size;
-
- for(j = 0; j < nPbH >> s->sps->log2_min_pu_size; j++)
- for (i = 0; i < nPbW >> s->sps->log2_min_pu_size; i++)
- tab_mvf[(y_pu + j) * min_pu_width + x_pu + i] = current_mv;
- }
- }
+ for (j = 0; j < nPbH >> s->sps->log2_min_pu_size; j++)
+ for (i = 0; i < nPbW >> s->sps->log2_min_pu_size; i++)
+ tab_mvf[(y_pu + j) * min_pu_width + x_pu + i] = current_mv;
if (current_mv.pred_flag & PF_L0) {
ref0 = refPicList[0].ref[current_mv.ref_idx[0]];
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++)
if (!s->sh.disable_deblocking_filter_flag)
ff_hevc_deblocking_boundary_strengths(s, x0, y0, log2_cb_size);
} else {
+ int pcm_flag = 0;
+
if (s->sh.slice_type != I_SLICE)
lc->cu.pred_mode = ff_hevc_pred_mode_decode(s);
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);
+ pcm_flag = ff_hevc_pcm_flag_decode(s);
}
- if (lc->cu.pcm_flag) {
+ if (pcm_flag) {
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)
}
}
- if (!lc->cu.pcm_flag) {
+ if (!pcm_flag) {
+ int rqt_root_cbf = 1;
+
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);
+ rqt_root_cbf = ff_hevc_no_residual_syntax_flag_decode(s);
}
- if (lc->cu.rqt_root_cbf) {
+ if (rqt_root_cbf) {
const static int cbf[2] = { 0 };
lc->cu.max_trafo_depth = lc->cu.pred_mode == MODE_INTRA ?
s->sps->max_transform_hierarchy_depth_intra + lc->cu.intra_split_flag :
lc->qPy_pred = lc->qp_y;
}
- set_ct_depth(s, x0, y0, log2_cb_size, lc->ct.depth);
+ set_ct_depth(s, x0, y0, log2_cb_size, lc->ct_depth);
return 0;
}
int qp_block_mask = (1<<(s->sps->log2_ctb_size - s->pps->diff_cu_qp_delta_depth)) - 1;
int split_cu;
- lc->ct.depth = cb_depth;
+ 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) {
av_display_rotation_set((int32_t *)rotation->data, angle);
av_display_matrix_flip((int32_t *)rotation->data,
- s->sei_vflip, s->sei_hflip);
+ s->sei_hflip, s->sei_vflip);
}
return 0;
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
} PredictionUnit;
typedef struct TransformUnit {
- DECLARE_ALIGNED(32, int16_t, coeffs[2][MAX_TB_SIZE * MAX_TB_SIZE]);
int cu_qp_delta;
int res_scale_val;
} 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 stat_coeff[4];
/* +7 is for subpixel interpolation, *2 for high bit depths */
DECLARE_ALIGNED(32, uint8_t, edge_emu_buffer)[(MAX_PB_SIZE + 7) * EDGE_EMU_BUFFER_STRIDE * 2];
DECLARE_ALIGNED(32, uint8_t, edge_emu_buffer2)[(MAX_PB_SIZE + 7) * EDGE_EMU_BUFFER_STRIDE * 2];
+ DECLARE_ALIGNED(16, int16_t, tmp [MAX_PB_SIZE * MAX_PB_SIZE]);
- CodingTree ct;
+ int ct_depth;
CodingUnit cu;
PredictionUnit pu;
NeighbourAvailable na;
{
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))
+ 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 vshift = s->sps->vshift[c_idx];
uint8_t *dst = &s->frame->data[c_idx][(y0 >> vshift) * stride +
((x0 >> hshift) << s->sps->pixel_shift)];
- int16_t *coeffs = lc->tu.coeffs[c_idx > 0];
+ int16_t *coeffs = (int16_t*)(c_idx ? lc->edge_emu_buffer2 : lc->edge_emu_buffer);
uint8_t significant_coeff_group_flag[8][8] = {{0}};
int explicit_rdpcm_flag = 0;
int explicit_rdpcm_dir_flag;
}
}
if (lc->tu.cross_pf) {
- int16_t *coeffs_y = lc->tu.coeffs[0];
+ int16_t *coeffs_y = (int16_t*)lc->edge_emu_buffer;
for (i = 0; i < (trafo_size * trafo_size); i++) {
coeffs[i] = coeffs[i] + ((lc->tu.res_scale_val * coeffs_y[i]) >> 3);
// 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;
+ Mv mv_l0_col = { 0 }, mv_l1_col = { 0 };
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) ?
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);
+ if (sps->num_long_term_ref_pics_sps > 31U) {
+ av_log(0, AV_LOG_ERROR, "num_long_term_ref_pics_sps %d is out of range.\n",
+ sps->num_long_term_ref_pics_sps);
+ goto err;
+ }
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);
}
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;
+ memset(&sps->pic_conf_win, 0, sizeof(sps->pic_conf_win));
+ memset(&sps->output_window, 0, sizeof(sps->output_window));
sps->output_width = sps->width;
sps->output_height = sps->height;
}
int pps_range_extensions_flag = get_bits1(gb);
/* int pps_extension_7bits = */ get_bits(gb, 7);
if (sps->ptl.general_ptl.profile_idc == FF_PROFILE_HEVC_REXT && pps_range_extensions_flag) {
- pps_range_extensions(s, pps, sps);
+ if ((ret = pps_range_extensions(s, pps, sps)) < 0)
+ goto err;
}
}
}
}
-static void FUNC(transform_add4x4)(uint8_t *_dst, int16_t *coeffs,
- ptrdiff_t stride)
+static av_always_inline void FUNC(transquant_bypass)(uint8_t *_dst, int16_t *coeffs,
+ ptrdiff_t stride, int size)
{
int x, y;
pixel *dst = (pixel *)_dst;
stride /= sizeof(pixel);
- for (y = 0; y < 4; y++) {
- for (x = 0; x < 4; x++) {
+ for (y = 0; y < size; y++) {
+ for (x = 0; x < size; x++) {
dst[x] = av_clip_pixel(dst[x] + *coeffs);
coeffs++;
}
}
}
-static void FUNC(transform_add8x8)(uint8_t *_dst, int16_t *coeffs,
+static void FUNC(transform_add4x4)(uint8_t *_dst, int16_t *coeffs,
ptrdiff_t stride)
{
- int x, y;
- pixel *dst = (pixel *)_dst;
-
- stride /= sizeof(pixel);
+ FUNC(transquant_bypass)(_dst, coeffs, stride, 4);
+}
- for (y = 0; y < 8; y++) {
- for (x = 0; x < 8; x++) {
- dst[x] = av_clip_pixel(dst[x] + *coeffs);
- coeffs++;
- }
- dst += stride;
- }
+static void FUNC(transform_add8x8)(uint8_t *_dst, int16_t *coeffs,
+ ptrdiff_t stride)
+{
+ FUNC(transquant_bypass)(_dst, coeffs, stride, 8);
}
static void FUNC(transform_add16x16)(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] = av_clip_pixel(dst[x] + *coeffs);
- coeffs++;
- }
- dst += stride;
- }
+ FUNC(transquant_bypass)(_dst, coeffs, stride, 16);
}
static void FUNC(transform_add32x32)(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] = av_clip_pixel(dst[x] + *coeffs);
- coeffs++;
- }
- dst += stride;
- }
+ FUNC(transquant_bypass)(_dst, coeffs, stride, 32);
}
#include <string.h>
+#include "libavutil/imgutils.h"
#include "libavutil/internal.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/mem.h"
static av_cold int hnm_decode_init(AVCodecContext *avctx)
{
Hnm4VideoContext *hnm = avctx->priv_data;
+ int ret;
if (avctx->extradata_size < 1) {
av_log(avctx, AV_LOG_ERROR,
return AVERROR_INVALIDDATA;
}
+ ret = av_image_check_size(avctx->width, avctx->height, 0, avctx);
+ if (ret < 0)
+ return ret;
+
hnm->version = avctx->extradata[0];
avctx->pix_fmt = AV_PIX_FMT_PAL8;
hnm->width = avctx->width;
return 0;
}
+static av_cold int decode_end(AVCodecContext *avctx)
+{
+ HYuvContext *s = avctx->priv_data;
+ int i;
+
+ ff_huffyuv_common_end(s);
+ av_freep(&s->bitstream_buffer);
+
+ for (i = 0; i < 8; i++)
+ ff_free_vlc(&s->vlc[i]);
+
+ return 0;
+}
+
static av_cold int decode_init(AVCodecContext *avctx)
{
HYuvContext *s = avctx->priv_data;
if ((ret = read_huffman_tables(s, avctx->extradata + 4,
avctx->extradata_size - 4)) < 0)
- return ret;
+ goto error;
} else {
switch (avctx->bits_per_coded_sample & 7) {
case 1:
s->context = 0;
if ((ret = read_old_huffman_tables(s)) < 0)
- return ret;
+ goto error;
}
if (s->version <= 2) {
s->alpha = 1;
break;
default:
- return AVERROR_INVALIDDATA;
+ ret = AVERROR_INVALIDDATA;
+ goto error;
}
av_pix_fmt_get_chroma_sub_sample(avctx->pix_fmt,
&s->chroma_h_shift,
avctx->pix_fmt = AV_PIX_FMT_YUVA420P16;
break;
default:
- return AVERROR_INVALIDDATA;
+ ret = AVERROR_INVALIDDATA;
+ goto error;
}
}
if ((avctx->pix_fmt == AV_PIX_FMT_YUV422P || avctx->pix_fmt == AV_PIX_FMT_YUV420P) && avctx->width & 1) {
av_log(avctx, AV_LOG_ERROR, "width must be even for this colorspace\n");
- return AVERROR_INVALIDDATA;
+ ret = AVERROR_INVALIDDATA;
+ goto error;
}
if (s->predictor == MEDIAN && avctx->pix_fmt == AV_PIX_FMT_YUV422P &&
avctx->width % 4) {
av_log(avctx, AV_LOG_ERROR, "width must be a multiple of 4 "
"for this combination of colorspace and predictor type.\n");
- return AVERROR_INVALIDDATA;
+ ret = AVERROR_INVALIDDATA;
+ goto error;
}
if ((ret = ff_huffyuv_alloc_temp(s)) < 0) {
ff_huffyuv_common_end(s);
- return ret;
+ goto error;
}
return 0;
+ error:
+ decode_end(avctx);
+ return ret;
}
static av_cold int decode_init_thread_copy(AVCodecContext *avctx)
if (s->predictor == PLANE) {
if (s->bitstream_bpp != 32)
left[A] = 0;
- if ((y & s->interlaced) == 0 &&
- y < s->height - 1 - s->interlaced) {
+ if (y < s->height - 1 - s->interlaced) {
s->hdsp.add_bytes(p->data[0] + p->linesize[0] * y,
p->data[0] + p->linesize[0] * y +
- fake_ystride, fake_ystride);
+ fake_ystride, 4 * width);
}
}
}
return (get_bits_count(&s->gb) + 31) / 32 * 4 + table_size;
}
-static av_cold int decode_end(AVCodecContext *avctx)
-{
- HYuvContext *s = avctx->priv_data;
- int i;
-
- ff_huffyuv_common_end(s);
- av_freep(&s->bitstream_buffer);
-
- for (i = 0; i < 8; i++)
- ff_free_vlc(&s->vlc[i]);
-
- return 0;
-}
-
AVCodec ff_huffyuv_decoder = {
.name = "huffyuv",
.long_name = NULL_IF_CONFIG_SMALL("Huffyuv / HuffYUV"),
#define AVCODEC_HUFFYUVDSP_H
#include <stdint.h>
+#include "config.h"
#if HAVE_BIGENDIAN
#define B 3
}
}
-void (*ff_put_pixels_clamped)(const int16_t *block, uint8_t *pixels, int line_size);
-void (*ff_add_pixels_clamped)(const int16_t *block, uint8_t *pixels, int line_size);
+void (*ff_put_pixels_clamped)(const int16_t *block, uint8_t *pixels, ptrdiff_t line_size);
+void (*ff_add_pixels_clamped)(const int16_t *block, uint8_t *pixels, ptrdiff_t line_size);
static void put_pixels_clamped_c(const int16_t *block, uint8_t *av_restrict pixels,
- int line_size)
+ ptrdiff_t line_size)
{
int i;
static void put_signed_pixels_clamped_c(const int16_t *block,
uint8_t *av_restrict pixels,
- int line_size)
+ ptrdiff_t line_size)
{
int i, j;
}
static void add_pixels_clamped_c(const int16_t *block, uint8_t *av_restrict pixels,
- int line_size)
+ ptrdiff_t line_size)
{
int i;
/* pixel ops : interface with DCT */
void (*put_pixels_clamped)(const int16_t *block /* align 16 */,
uint8_t *pixels /* align 8 */,
- int line_size);
+ ptrdiff_t line_size);
void (*put_signed_pixels_clamped)(const int16_t *block /* align 16 */,
uint8_t *pixels /* align 8 */,
- int line_size);
+ ptrdiff_t line_size);
void (*add_pixels_clamped)(const int16_t *block /* align 16 */,
uint8_t *pixels /* align 8 */,
- int line_size);
+ ptrdiff_t line_size);
void (*idct)(int16_t *block /* align 16 */);
enum idct_permutation_type perm_type;
} IDCTDSPContext;
-extern void (*ff_put_pixels_clamped)(const int16_t *block, uint8_t *pixels, int line_size);
-extern void (*ff_add_pixels_clamped)(const int16_t *block, uint8_t *pixels, int line_size);
+extern void (*ff_put_pixels_clamped)(const int16_t *block, uint8_t *pixels, ptrdiff_t line_size);
+extern void (*ff_add_pixels_clamped)(const int16_t *block, uint8_t *pixels, ptrdiff_t line_size);
void ff_idctdsp_init(IDCTDSPContext *c, AVCodecContext *avctx);
return c;
init_fail:
- ff_iir_filter_free_coeffs(c);
+ ff_iir_filter_free_coeffsp(&c);
return NULL;
}
}
}
-av_cold void ff_iir_filter_free_state(struct FFIIRFilterState *state)
+av_cold void ff_iir_filter_free_statep(struct FFIIRFilterState **state)
{
- av_free(state);
+ av_freep(state);
}
-av_cold void ff_iir_filter_free_coeffs(struct FFIIRFilterCoeffs *coeffs)
+av_cold void ff_iir_filter_free_coeffsp(struct FFIIRFilterCoeffs **coeffsp)
{
+ struct FFIIRFilterCoeffs *coeffs = *coeffsp;
if(coeffs){
- av_free(coeffs->cx);
- av_free(coeffs->cy);
+ av_freep(&coeffs->cx);
+ av_freep(&coeffs->cy);
}
- av_free(coeffs);
+ av_freep(coeffsp);
}
void ff_iir_filter_init(FFIIRFilterContext *f) {
for (i = 0; i < SIZE; i++)
printf("%6d %6d\n", x[i], y[i]);
- ff_iir_filter_free_coeffs(fcoeffs);
- ff_iir_filter_free_state(fstate);
+ ff_iir_filter_free_coeffsp(&fcoeffs);
+ ff_iir_filter_free_statep(&fstate);
return 0;
}
#endif /* TEST */
*
* @param coeffs pointer allocated with ff_iir_filter_init_coeffs()
*/
-void ff_iir_filter_free_coeffs(struct FFIIRFilterCoeffs *coeffs);
+void ff_iir_filter_free_coeffsp(struct FFIIRFilterCoeffs **coeffs);
/**
- * Free filter state.
+ * Free and zero filter state.
*
- * @param state pointer allocated with ff_iir_filter_init_state()
+ * @param state pointer to pointer allocated with ff_iir_filter_init_state()
*/
-void ff_iir_filter_free_state(struct FFIIRFilterState *state);
+void ff_iir_filter_free_statep(struct FFIIRFilterState **state);
/**
* Perform IIR filtering on signed 16-bit input samples.
GetBitContext gb;
BswapDSPContext bdsp;
- AVFloatDSPContext fdsp;
+ AVFloatDSPContext *fdsp;
FFTContext fft;
DECLARE_ALIGNED(32, FFTComplex, samples)[COEFFS / 2];
float *out_samples;
return ret;
}
ff_bswapdsp_init(&q->bdsp);
- avpriv_float_dsp_init(&q->fdsp, avctx->flags & CODEC_FLAG_BITEXACT);
+ q->fdsp = avpriv_float_dsp_alloc(avctx->flags & CODEC_FLAG_BITEXACT);
+ if (!q->fdsp) {
+ ff_fft_end(&q->fft);
+
+ return AVERROR(ENOMEM);
+ }
+
avctx->sample_fmt = AV_SAMPLE_FMT_FLTP;
avctx->channel_layout = avctx->channels == 1 ? AV_CH_LAYOUT_MONO
: AV_CH_LAYOUT_STEREO;
}
if (avctx->channels == 2) {
- q->fdsp.butterflies_float((float *)frame->extended_data[0],
+ q->fdsp->butterflies_float((float *)frame->extended_data[0],
(float *)frame->extended_data[1], COEFFS);
}
return IMC_BLOCK_SIZE * avctx->channels;
}
-
static av_cold int imc_decode_close(AVCodecContext * avctx)
{
IMCContext *q = avctx->priv_data;
ff_fft_end(&q->fft);
+ av_freep(&q->fdsp);
return 0;
}
int i;
int j;
int out = 0;
- int c;
- int t;
if (width & 1)
return AVERROR_INVALIDDATA;
/* first line contain absolute values, other lines contain deltas */
while (out < width) {
- c = ir2_get_code(&ctx->gb);
+ int c = ir2_get_code(&ctx->gb);
if (c >= 0x80) { /* we have a run */
c -= 0x7F;
if (out + c*2 > width)
for (j = 1; j < height; j++) {
out = 0;
while (out < width) {
- c = ir2_get_code(&ctx->gb);
+ int c = ir2_get_code(&ctx->gb);
if (c >= 0x80) { /* we have a skip */
c -= 0x7F;
if (out + c*2 > width)
out++;
}
} else { /* add two deltas from table */
- t = dst[out - pitch] + (table[c * 2] - 128);
+ int t = dst[out - pitch] + (table[c * 2] - 128);
t = av_clip_uint8(t);
dst[out] = t;
out++;
#define FF_SANE_NB_CHANNELS 63U
+#define FF_SIGNBIT(x) ((x) >> CHAR_BIT * sizeof(x) - 1)
+
#if HAVE_AVX
# define STRIDE_ALIGN 32
#elif HAVE_SIMD_ALIGN_16
s->modified_quant ? " MQ" : "",
s->loop_filter ? " LOOP" : "",
s->h263_slice_structured ? " SS" : "",
- s->avctx->time_base.den, s->avctx->time_base.num
+ s->avctx->framerate.num, s->avctx->framerate.den
);
}
}
s->width = width;
s->height = height;
s->avctx->sample_aspect_ratio= (AVRational){12,11};
- s->avctx->time_base= (AVRational){1001, 30000};
+ s->avctx->framerate = (AVRational){ 30000, 1001 };
} else {
int ufep;
if(s->custom_pcf){
int gcd;
- s->avctx->time_base.den= 1800000;
- s->avctx->time_base.num= 1000 + get_bits1(&s->gb);
- s->avctx->time_base.num*= get_bits(&s->gb, 7);
- if(s->avctx->time_base.num == 0){
+ s->avctx->framerate.num = 1800000;
+ s->avctx->framerate.den = 1000 + get_bits1(&s->gb);
+ s->avctx->framerate.den *= get_bits(&s->gb, 7);
+ if(s->avctx->framerate.den == 0){
av_log(s, AV_LOG_ERROR, "zero framerate\n");
return -1;
}
- gcd= av_gcd(s->avctx->time_base.den, s->avctx->time_base.num);
- s->avctx->time_base.den /= gcd;
- s->avctx->time_base.num /= gcd;
+ gcd= av_gcd(s->avctx->framerate.den, s->avctx->framerate.num);
+ s->avctx->framerate.den /= gcd;
+ s->avctx->framerate.num /= gcd;
}else{
- s->avctx->time_base= (AVRational){1001, 30000};
+ s->avctx->framerate = (AVRational){ 30000, 1001 };
}
}
#include "jacosub.h"
#include "libavutil/avstring.h"
#include "libavutil/bprint.h"
+#include "libavutil/time_internal.h"
#undef time
time_t now = time(0);
struct tm ltime;
-#if HAVE_LOCALTIME_R
localtime_r(&now, <ime);
-#else
- ltime = *localtime(&now);
-#endif
strftime(buf, sizeof(buf), arg, <ime);
av_bprintf(dst, "%s", buf);
return 0;
if (i == FF_ARRAY_ELEMS(ass_codes_map))
av_bprintf(dst, "%c", *src++);
}
- av_bprintf(dst, "\r\n");
}
static int jacosub_decode_frame(AVCodecContext *avctx,
void *data, int *got_sub_ptr, AVPacket *avpkt)
{
+ int ret;
AVSubtitle *sub = data;
const char *ptr = avpkt->data;
if (*ptr) {
AVBPrint buffer;
- char *dec_sub;
// skip timers
ptr = jss_skip_whitespace(ptr);
av_bprint_init(&buffer, JSS_MAX_LINESIZE, JSS_MAX_LINESIZE);
jacosub_to_ass(avctx, &buffer, ptr);
- av_bprint_finalize(&buffer, &dec_sub);
- ff_ass_add_rect(sub, dec_sub, avpkt->pts, avpkt->duration, 0);
- av_free(dec_sub);
+ ret = ff_ass_add_rect_bprint(sub, &buffer, avpkt->pts, avpkt->duration);
+ av_bprint_finalize(&buffer, NULL);
+ if (ret < 0)
+ return ret;
}
end:
for (j = 0; j < 2; j++)
band->coord[1][j] = ff_jpeg2000_ceildiv(band->coord[1][j], dy);
- band->prec = av_mallocz_array(reslevel->num_precincts_x *
- (uint64_t)reslevel->num_precincts_y,
- sizeof(*band->prec));
- if (!band->prec)
+ if (reslevel->num_precincts_x * (uint64_t)reslevel->num_precincts_y > INT_MAX) {
+ band->prec = NULL;
return AVERROR(ENOMEM);
-
+ }
nb_precincts = reslevel->num_precincts_x * reslevel->num_precincts_y;
+ band->prec = av_mallocz_array(nb_precincts, sizeof(*band->prec));
+ if (!band->prec)
+ return AVERROR(ENOMEM);
for (precno = 0; precno < nb_precincts; precno++) {
Jpeg2000Prec *prec = band->prec + precno;
+ int nb_codeblocks;
/* TODO: Explain formula for JPEG200 DCINEMA. */
/* TODO: Verify with previous count of codeblocks per band */
if (!prec->zerobits)
return AVERROR(ENOMEM);
- prec->cblk = av_mallocz_array(prec->nb_codeblocks_width *
- (uint64_t)prec->nb_codeblocks_height,
- sizeof(*prec->cblk));
+ if (prec->nb_codeblocks_width * (uint64_t)prec->nb_codeblocks_height > INT_MAX) {
+ prec->cblk = NULL;
+ return AVERROR(ENOMEM);
+ }
+ nb_codeblocks = prec->nb_codeblocks_width * prec->nb_codeblocks_height;
+ prec->cblk = av_mallocz_array(nb_codeblocks, sizeof(*prec->cblk));
if (!prec->cblk)
return AVERROR(ENOMEM);
- for (cblkno = 0; cblkno < prec->nb_codeblocks_width * prec->nb_codeblocks_height; cblkno++) {
+ for (cblkno = 0; cblkno < nb_codeblocks; cblkno++) {
Jpeg2000Cblk *cblk = prec->cblk + cblkno;
uint16_t Cx0, Cy0;
#include "internal.h"
#include "thread.h"
#include "jpeg2000.h"
+#include "jpeg2000dsp.h"
#define JP2_SIG_TYPE 0x6A502020
#define JP2_SIG_VALUE 0x0D0A870A
int curtileno;
Jpeg2000Tile *tile;
+ Jpeg2000DSPContext dsp;
/*options parameters*/
int reduction_factor;
}
}
-/* Inverse ICT parameters in float and integer.
- * int value = (float value) * (1<<16) */
-static const float f_ict_params[4] = {
- 1.402f,
- 0.34413f,
- 0.71414f,
- 1.772f
-};
-static const int i_ict_params[4] = {
- 91881,
- 22553,
- 46802,
- 116130
-};
-
-static void mct_decode(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile)
+static inline void mct_decode(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile)
{
int i, csize = 1;
- int32_t *src[3], i0, i1, i2;
- float *srcf[3], i0f, i1f, i2f;
+ void *src[3];
for (i = 1; i < 3; i++)
if (tile->codsty[0].transform != tile->codsty[i].transform) {
for (i = 0; i < 3; i++)
if (tile->codsty[0].transform == FF_DWT97)
- srcf[i] = tile->comp[i].f_data;
+ src[i] = tile->comp[i].f_data;
else
- src [i] = tile->comp[i].i_data;
+ src[i] = tile->comp[i].i_data;
for (i = 0; i < 2; i++)
csize *= tile->comp[0].coord[i][1] - tile->comp[0].coord[i][0];
- switch (tile->codsty[0].transform) {
- case FF_DWT97:
- for (i = 0; i < csize; i++) {
- i0f = *srcf[0] + (f_ict_params[0] * *srcf[2]);
- i1f = *srcf[0] - (f_ict_params[1] * *srcf[1])
- - (f_ict_params[2] * *srcf[2]);
- i2f = *srcf[0] + (f_ict_params[3] * *srcf[1]);
- *srcf[0]++ = i0f;
- *srcf[1]++ = i1f;
- *srcf[2]++ = i2f;
- }
- break;
- case FF_DWT97_INT:
- for (i = 0; i < csize; i++) {
- i0 = *src[0] + (((i_ict_params[0] * *src[2]) + (1 << 15)) >> 16);
- i1 = *src[0] - (((i_ict_params[1] * *src[1]) + (1 << 15)) >> 16)
- - (((i_ict_params[2] * *src[2]) + (1 << 15)) >> 16);
- i2 = *src[0] + (((i_ict_params[3] * *src[1]) + (1 << 15)) >> 16);
- *src[0]++ = i0;
- *src[1]++ = i1;
- *src[2]++ = i2;
- }
- break;
- case FF_DWT53:
- for (i = 0; i < csize; i++) {
- i1 = *src[0] - (*src[2] + *src[1] >> 2);
- i0 = i1 + *src[2];
- i2 = i1 + *src[1];
- *src[0]++ = i0;
- *src[1]++ = i1;
- *src[2]++ = i2;
- }
- break;
- }
+ s->dsp.mct_decode[tile->codsty[0].transform](src[0], src[1], src[2], csize);
}
static int jpeg2000_decode_tile(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile,
return 0;
}
+static av_cold int jpeg2000_decode_init(AVCodecContext *avctx)
+{
+ Jpeg2000DecoderContext *s = avctx->priv_data;
+
+ ff_jpeg2000dsp_init(&s->dsp);
+
+ return 0;
+}
+
static int jpeg2000_decode_frame(AVCodecContext *avctx, void *data,
int *got_frame, AVPacket *avpkt)
{
.capabilities = CODEC_CAP_FRAME_THREADS,
.priv_data_size = sizeof(Jpeg2000DecoderContext),
.init_static_data = jpeg2000_init_static_data,
+ .init = jpeg2000_decode_init,
.decode = jpeg2000_decode_frame,
.priv_class = &jpeg2000_class,
.max_lowres = 5,
--- /dev/null
+/*
+ * JPEG 2000 DSP functions
+ * Copyright (c) 2007 Kamil Nowosad
+ * Copyright (c) 2013 Nicolas Bertrand <nicoinattendu@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 "config.h"
+#include "libavutil/attributes.h"
+#include "jpeg2000dsp.h"
+
+/* Inverse ICT parameters in float and integer.
+ * int value = (float value) * (1<<16) */
+static const float f_ict_params[4] = {
+ 1.402f,
+ 0.34413f,
+ 0.71414f,
+ 1.772f
+};
+
+static const int i_ict_params[4] = {
+ 91881,
+ 22553,
+ 46802,
+ 116130
+};
+
+static void ict_float(void *_src0, void *_src1, void *_src2, int csize)
+{
+ float *src0 = _src0, *src1 = _src1, *src2 = _src2;
+ float i0f, i1f, i2f;
+ int i;
+
+ for (i = 0; i < csize; i++) {
+ i0f = *src0 + (f_ict_params[0] * *src2);
+ i1f = *src0 - (f_ict_params[1] * *src1)
+ - (f_ict_params[2] * *src2);
+ i2f = *src0 + (f_ict_params[3] * *src1);
+ *src0++ = i0f;
+ *src1++ = i1f;
+ *src2++ = i2f;
+ }
+}
+
+static void ict_int(void *_src0, void *_src1, void *_src2, int csize)
+{
+ int32_t *src0 = _src0, *src1 = _src1, *src2 = _src2;
+ int32_t i0, i1, i2;
+ int i;
+
+ for (i = 0; i < csize; i++) {
+ i0 = *src0 + (((i_ict_params[0] * *src2) + (1 << 15)) >> 16);
+ i1 = *src0 - (((i_ict_params[1] * *src1) + (1 << 15)) >> 16)
+ - (((i_ict_params[2] * *src2) + (1 << 15)) >> 16);
+ i2 = *src0 + (((i_ict_params[3] * *src1) + (1 << 15)) >> 16);
+ *src0++ = i0;
+ *src1++ = i1;
+ *src2++ = i2;
+ }
+}
+
+static void rct_int(void *_src0, void *_src1, void *_src2, int csize)
+{
+ int32_t *src0 = _src0, *src1 = _src1, *src2 = _src2;
+ int32_t i0, i1, i2;
+ int i;
+
+ for (i = 0; i < csize; i++) {
+ i1 = *src0 - (*src2 + *src1 >> 2);
+ i0 = i1 + *src2;
+ i2 = i1 + *src1;
+ *src0++ = i0;
+ *src1++ = i1;
+ *src2++ = i2;
+ }
+}
+
+av_cold void ff_jpeg2000dsp_init(Jpeg2000DSPContext *c)
+{
+ c->mct_decode[FF_DWT97] = ict_float;
+ c->mct_decode[FF_DWT53] = rct_int;
+ c->mct_decode[FF_DWT97_INT] = ict_int;
+}
/*
- * copyright (c) 2005 Michael Niedermayer <michaelni@gmx.at>
+ * JPEG 2000 DSP functions
+ * Copyright (c) 2007 Kamil Nowosad
+ * Copyright (c) 2013 Nicolas Bertrand <nicoinattendu@gmail.com>
*
* This file is part of FFmpeg.
*
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef AVUTIL_INTFLOAT_READWRITE_H
-#define AVUTIL_INTFLOAT_READWRITE_H
+#ifndef AVCODEC_JPEG2000DSP_H
+#define AVCODEC_JPEG2000DSP_H
#include <stdint.h>
+#include "jpeg2000dwt.h"
-#include "attributes.h"
-#include "version.h"
+typedef struct Jpeg2000DSPContext {
+ void (*mct_decode[FF_DWT_NB])(void *src0, void *src1, void *src2, int csize);
+} Jpeg2000DSPContext;
-#if FF_API_INTFLOAT
-/* IEEE 80 bits extended float */
-typedef struct AVExtFloat {
- uint8_t exponent[2];
- uint8_t mantissa[8];
-} AVExtFloat;
+void ff_jpeg2000dsp_init(Jpeg2000DSPContext *c);
-attribute_deprecated double av_int2dbl(int64_t v) av_const;
-attribute_deprecated float av_int2flt(int32_t v) av_const;
-attribute_deprecated double av_ext2dbl(const AVExtFloat ext) av_const;
-attribute_deprecated int64_t av_dbl2int(double d) av_const;
-attribute_deprecated int32_t av_flt2int(float d) av_const;
-attribute_deprecated AVExtFloat av_dbl2ext(double d) av_const;
-#endif /* FF_API_INTFLOAT */
-
-#endif /* AVUTIL_INTFLOAT_READWRITE_H */
+#endif /* AVCODEC_JPEG2000DSP_H */
enum DWTType {
FF_DWT97,
FF_DWT53,
- FF_DWT97_INT
+ FF_DWT97_INT,
+ FF_DWT_NB
};
typedef struct DWTContext {
}
val = get_bits_long(gb, bits);
- val |= 1 << bits;
+ val |= 1U << bits;
*value = val - 1;
lag_decode_arith_plane(l, p->data[0], avctx->width, avctx->height,
p->linesize[0], buf + offset_ry,
buf_size - offset_ry);
- lag_decode_arith_plane(l, p->data[1], avctx->width / 2,
+ lag_decode_arith_plane(l, p->data[1], (avctx->width + 1) / 2,
avctx->height, p->linesize[1],
buf + offset_gu, buf_size - offset_gu);
- lag_decode_arith_plane(l, p->data[2], avctx->width / 2,
+ lag_decode_arith_plane(l, p->data[2], (avctx->width + 1) / 2,
avctx->height, p->linesize[2],
buf + offset_bv, buf_size - offset_bv);
break;
lag_decode_arith_plane(l, p->data[0], avctx->width, avctx->height,
p->linesize[0], buf + offset_ry,
buf_size - offset_ry);
- lag_decode_arith_plane(l, p->data[2], avctx->width / 2,
- avctx->height / 2, p->linesize[2],
+ lag_decode_arith_plane(l, p->data[2], (avctx->width + 1) / 2,
+ (avctx->height + 1) / 2, p->linesize[2],
buf + offset_gu, buf_size - offset_gu);
- lag_decode_arith_plane(l, p->data[1], avctx->width / 2,
- avctx->height / 2, p->linesize[1],
+ lag_decode_arith_plane(l, p->data[1], (avctx->width + 1) / 2,
+ (avctx->height + 1) / 2, p->linesize[1],
buf + offset_bv, buf_size - offset_bv);
break;
default:
int uqvq, ret;
unsigned int mthread_inlen, mthread_outlen;
unsigned int len = buf_size;
+ int linesize;
if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
return ret;
case AV_CODEC_ID_MSZH:
switch (c->compression) {
case COMP_MSZH:
- if (c->imgtype == IMGTYPE_RGB24 && len == width * height * 3 ||
+ if (c->imgtype == IMGTYPE_RGB24 && len == FFALIGN(width * 3, 4) * height ||
c->imgtype == IMGTYPE_YUV111 && len == width * height * 3) {
;
} else if (c->flags & FLAG_MULTITHREAD) {
}
break;
case IMGTYPE_RGB24:
+ linesize = len < FFALIGN(3 * width, 4) * height ? 3 * width : FFALIGN(3 * width, 4);
for (row = height - 1; row >= 0; row--) {
pixel_ptr = row * frame->linesize[0];
memcpy(outptr + pixel_ptr, encoded, 3 * width);
- encoded += 3 * width;
+ encoded += linesize;
}
break;
case IMGTYPE_YUV411:
}
}
- avctx->delay = FAAC_DELAY_SAMPLES;
+ avctx->initial_padding = FAAC_DELAY_SAMPLES;
ff_af_queue_init(avctx, &s->afq);
return 0;
#include "avcodec.h"
#include "internal.h"
+/* The version macro is introduced the same time as the setting enum was
+ * changed, so this check should suffice. */
+#ifndef AACDECODER_LIB_VL0
+#define AAC_PCM_MAX_OUTPUT_CHANNELS AAC_PCM_OUTPUT_CHANNELS
+#endif
+
enum ConcealMethod {
CONCEAL_METHOD_SPECTRAL_MUTING = 0,
CONCEAL_METHOD_NOISE_SUBSTITUTION = 1,
const AVClass *class;
HANDLE_AACDECODER handle;
int initialized;
+ uint8_t *decoder_buffer;
+ uint8_t *anc_buffer;
enum ConcealMethod conceal_method;
+ int drc_level;
+ int drc_boost;
+ int drc_heavy;
+ int drc_cut;
} FDKAACDecContext;
+
+#define DMX_ANC_BUFFSIZE 128
+#define DECODER_MAX_CHANNELS 6
+#define DECODER_BUFFSIZE 2048 * sizeof(INT_PCM)
+
#define OFFSET(x) offsetof(FDKAACDecContext, x)
#define AD AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_DECODING_PARAM
static const AVOption fdk_aac_dec_options[] = {
{ "spectral", "Spectral muting", 0, AV_OPT_TYPE_CONST, { .i64 = CONCEAL_METHOD_SPECTRAL_MUTING }, INT_MIN, INT_MAX, AD, "conceal" },
{ "noise", "Noise Substitution", 0, AV_OPT_TYPE_CONST, { .i64 = CONCEAL_METHOD_NOISE_SUBSTITUTION }, INT_MIN, INT_MAX, AD, "conceal" },
{ "energy", "Energy Interpolation", 0, AV_OPT_TYPE_CONST, { .i64 = CONCEAL_METHOD_ENERGY_INTERPOLATION }, INT_MIN, INT_MAX, AD, "conceal" },
+ { "drc_boost", "Dynamic Range Control: boost, where [0] is none and [127] is max boost",
+ OFFSET(drc_boost), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 127, AD, NULL },
+ { "drc_cut", "Dynamic Range Control: attenuation factor, where [0] is none and [127] is max compression",
+ OFFSET(drc_cut), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 127, AD, NULL },
+ { "drc_level", "Dynamic Range Control: reference level, quantized to 0.25dB steps where [0] is 0dB and [127] is -31.75dB",
+ OFFSET(drc_level), AV_OPT_TYPE_INT, { .i64 = -1}, -1, 127, AD, NULL },
+ { "drc_heavy", "Dynamic Range Control: heavy compression, where [1] is on (RF mode) and [0] is off",
+ OFFSET(drc_heavy), AV_OPT_TYPE_INT, { .i64 = -1}, -1, 1, AD, NULL },
{ NULL }
};
{
FDKAACDecContext *s = avctx->priv_data;
CStreamInfo *info = aacDecoder_GetStreamInfo(s->handle);
- int channel_counts[9] = { 0 };
+ int channel_counts[0x24] = { 0 };
int i, ch_error = 0;
uint64_t ch_layout = 0;
for (i = 0; i < info->numChannels; i++) {
AUDIO_CHANNEL_TYPE ctype = info->pChannelType[i];
- if (ctype <= ACT_NONE || ctype > ACT_TOP) {
+ if (ctype <= ACT_NONE || ctype > FF_ARRAY_ELEMS(channel_counts)) {
av_log(avctx, AV_LOG_WARNING, "unknown channel type\n");
break;
}
if (s->handle)
aacDecoder_Close(s->handle);
+ av_freep(&s->decoder_buffer);
+ av_freep(&s->anc_buffer);
return 0;
}
{
FDKAACDecContext *s = avctx->priv_data;
AAC_DECODER_ERROR err;
+ int ret;
s->handle = aacDecoder_Open(avctx->extradata_size ? TT_MP4_RAW : TT_MP4_ADTS, 1);
if (!s->handle) {
return AVERROR_UNKNOWN;
}
+ if (avctx->request_channel_layout > 0 &&
+ avctx->request_channel_layout != AV_CH_LAYOUT_NATIVE) {
+ int downmix_channels = -1;
+
+ switch (avctx->request_channel_layout) {
+ case AV_CH_LAYOUT_STEREO:
+ case AV_CH_LAYOUT_STEREO_DOWNMIX:
+ downmix_channels = 2;
+ break;
+ case AV_CH_LAYOUT_MONO:
+ downmix_channels = 1;
+ break;
+ default:
+ av_log(avctx, AV_LOG_WARNING, "Invalid request_channel_layout\n");
+ break;
+ }
+
+ if (downmix_channels != -1) {
+ if (aacDecoder_SetParam(s->handle, AAC_PCM_MAX_OUTPUT_CHANNELS,
+ downmix_channels) != AAC_DEC_OK) {
+ av_log(avctx, AV_LOG_WARNING, "Unable to set output channels in the decoder\n");
+ } else {
+ s->anc_buffer = av_malloc(DMX_ANC_BUFFSIZE);
+ if (!s->anc_buffer) {
+ av_log(avctx, AV_LOG_ERROR, "Unable to allocate ancillary buffer for the decoder\n");
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+ if (aacDecoder_AncDataInit(s->handle, s->anc_buffer, DMX_ANC_BUFFSIZE)) {
+ av_log(avctx, AV_LOG_ERROR, "Unable to register downmix ancillary buffer in the decoder\n");
+ ret = AVERROR_UNKNOWN;
+ goto fail;
+ }
+ }
+ }
+ }
+
+ if (s->drc_boost != -1) {
+ if (aacDecoder_SetParam(s->handle, AAC_DRC_BOOST_FACTOR, s->drc_boost) != AAC_DEC_OK) {
+ av_log(avctx, AV_LOG_ERROR, "Unable to set DRC boost factor in the decoder\n");
+ return AVERROR_UNKNOWN;
+ }
+ }
+
+ if (s->drc_cut != -1) {
+ if (aacDecoder_SetParam(s->handle, AAC_DRC_ATTENUATION_FACTOR, s->drc_cut) != AAC_DEC_OK) {
+ av_log(avctx, AV_LOG_ERROR, "Unable to set DRC attenuation factor in the decoder\n");
+ return AVERROR_UNKNOWN;
+ }
+ }
+
+ if (s->drc_level != -1) {
+ if (aacDecoder_SetParam(s->handle, AAC_DRC_REFERENCE_LEVEL, s->drc_level) != AAC_DEC_OK) {
+ av_log(avctx, AV_LOG_ERROR, "Unable to set DRC reference level in the decoder\n");
+ return AVERROR_UNKNOWN;
+ }
+ }
+
+ if (s->drc_heavy != -1) {
+ if (aacDecoder_SetParam(s->handle, AAC_DRC_HEAVY_COMPRESSION, s->drc_heavy) != AAC_DEC_OK) {
+ av_log(avctx, AV_LOG_ERROR, "Unable to set DRC heavy compression in the decoder\n");
+ return AVERROR_UNKNOWN;
+ }
+ }
+
avctx->sample_fmt = AV_SAMPLE_FMT_S16;
return 0;
+fail:
+ fdk_aac_decode_close(avctx);
+ return ret;
}
static int fdk_aac_decode_frame(AVCodecContext *avctx, void *data,
frame->nb_samples = avctx->frame_size;
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);
+
+ if (s->anc_buffer) {
+ buf_size = DECODER_BUFFSIZE * DECODER_MAX_CHANNELS;
+ buf = s->decoder_buffer;
+ } else {
+ buf = frame->extended_data[0];
+ buf_size = avctx->channels * frame->nb_samples *
+ av_get_bytes_per_sample(avctx->sample_fmt);
+ }
} else {
- buf_size = 50 * 1024;
- buf = tmpptr = av_malloc(buf_size);
- if (!buf)
+ buf_size = DECODER_BUFFSIZE * DECODER_MAX_CHANNELS;
+
+ if (!s->decoder_buffer)
+ s->decoder_buffer = av_malloc(buf_size);
+ if (!s->decoder_buffer)
return AVERROR(ENOMEM);
+
+ buf = tmpptr = s->decoder_buffer;
}
err = aacDecoder_DecodeFrame(s->handle, (INT_PCM *) buf, buf_size, 0);
frame->nb_samples = avctx->frame_size;
if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
goto end;
- memcpy(frame->extended_data[0], tmpptr,
+ }
+ if (s->decoder_buffer) {
+ memcpy(frame->extended_data[0], buf,
avctx->channels * avctx->frame_size *
av_get_bytes_per_sample(avctx->sample_fmt));
+
+ if (!s->anc_buffer)
+ av_freep(&s->decoder_buffer);
}
*got_frame_ptr = 1;
ret = avpkt->size - valid;
end:
- av_free(tmpptr);
return ret;
}
}
avctx->frame_size = info.frameLength;
- avctx->delay = info.encoderDelay;
+ avctx->initial_padding = info.encoderDelay;
ff_af_queue_init(avctx, &s->afq);
if (avctx->flags & CODEC_FLAG_GLOBAL_HEADER) {
int abr;
float *samples_flt[2];
AudioFrameQueue afq;
- AVFloatDSPContext fdsp;
+ AVFloatDSPContext *fdsp;
} LAMEContext;
av_freep(&s->samples_flt[0]);
av_freep(&s->samples_flt[1]);
av_freep(&s->buffer);
+ av_freep(&s->fdsp);
ff_af_queue_close(&s->afq);
lame_set_out_samplerate(s->gfp, avctx->sample_rate);
/* algorithmic quality */
- if (avctx->compression_level == FF_COMPRESSION_DEFAULT)
- lame_set_quality(s->gfp, 5);
- else
+ if (avctx->compression_level != FF_COMPRESSION_DEFAULT)
lame_set_quality(s->gfp, avctx->compression_level);
/* rate control */
}
/* get encoder delay */
- avctx->delay = lame_get_encoder_delay(s->gfp) + 528 + 1;
+ avctx->initial_padding = lame_get_encoder_delay(s->gfp) + 528 + 1;
ff_af_queue_init(avctx, &s->afq);
avctx->frame_size = lame_get_framesize(s->gfp);
if (ret < 0)
goto error;
- avpriv_float_dsp_init(&s->fdsp, avctx->flags & CODEC_FLAG_BITEXACT);
+ s->fdsp = avpriv_float_dsp_alloc(avctx->flags & CODEC_FLAG_BITEXACT);
+ if (!s->fdsp) {
+ ret = AVERROR(ENOMEM);
+ goto error;
+ }
+
return 0;
error:
return AVERROR(EINVAL);
}
for (ch = 0; ch < avctx->channels; ch++) {
- s->fdsp.vector_fmul_scalar(s->samples_flt[ch],
+ s->fdsp->vector_fmul_scalar(s->samples_flt[ch],
(const float *)frame->data[ch],
32768.0f,
FFALIGN(frame->nb_samples, 8));
}
avctx->frame_size = 160;
- avctx->delay = 50;
+ avctx->initial_padding = 50;
ff_af_queue_init(avctx, &s->afq);
s->enc_state = Encoder_Interface_init(s->enc_dtx);
return AVERROR(ENOMEM);
memcpy(flush_buf, samples, frame->nb_samples * sizeof(*flush_buf));
samples = flush_buf;
- if (frame->nb_samples < avctx->frame_size - avctx->delay)
+ if (frame->nb_samples < avctx->frame_size - avctx->initial_padding)
s->enc_last_frame = -1;
}
if ((ret = ff_af_queue_add(&s->afq, frame)) < 0) {
bytestream_put_buffer(&p, "OpusHead", 8);
bytestream_put_byte(&p, 1); /* Version */
bytestream_put_byte(&p, channels);
- bytestream_put_le16(&p, avctx->delay); /* Lookahead samples at 48kHz */
+ bytestream_put_le16(&p, avctx->initial_padding); /* Lookahead samples at 48kHz */
bytestream_put_le32(&p, avctx->sample_rate); /* Original sample rate */
bytestream_put_le16(&p, 0); /* Gain of 0dB is recommended. */
/* FIXME: Opus can handle up to 255 channels. However, the mapping for
* anything greater than 8 is undefined. */
- if (avctx->channels > 8)
- av_log(avctx, AV_LOG_WARNING,
+ if (avctx->channels > 8) {
+ av_log(avctx, AV_LOG_ERROR,
"Channel layout undefined for %d channels.\n", avctx->channels);
-
+ return AVERROR_PATCHWELCOME;
+ }
if (!avctx->bit_rate) {
/* Sane default copied from opusenc */
avctx->bit_rate = 64000 * opus->stream_count +
goto fail;
}
- ret = opus_multistream_encoder_ctl(enc, OPUS_GET_LOOKAHEAD(&avctx->delay));
+ ret = opus_multistream_encoder_ctl(enc, OPUS_GET_LOOKAHEAD(&avctx->initial_padding));
if (ret != OPUS_OK)
av_log(avctx, AV_LOG_WARNING,
"Unable to get number of lookahead samples: %s\n",
int discard_padding;
if (frame) {
- ff_af_queue_add(&opus->afq, frame);
+ ret = ff_af_queue_add(&opus->afq, frame);
+ if (ret < 0)
+ return ret;
if (frame->nb_samples < opus->opts.packet_size) {
audio = opus->samples;
memcpy(audio, frame->data[0], frame->nb_samples * sample_size);
return;
}
- avctx->time_base.den = p_schro_params->format->frame_rate_numerator;
- avctx->time_base.num = p_schro_params->format->frame_rate_denominator;
+ avctx->framerate.num = p_schro_params->format->frame_rate_numerator;
+ avctx->framerate.den = p_schro_params->format->frame_rate_denominator;
}
static int libschroedinger_decode_frame(AVCodecContext *avctx,
SpeexStereoState stereo;
void *dec_state;
int frame_size;
+ int pktsize;
} LibSpeexContext;
av_log(avctx, AV_LOG_WARNING, "Invalid Speex header\n");
}
if (avctx->codec_tag == MKTAG('S', 'P', 'X', 'N')) {
+ int quality;
if (!avctx->extradata || avctx->extradata && avctx->extradata_size < 47) {
av_log(avctx, AV_LOG_ERROR, "Missing or invalid extradata.\n");
return AVERROR_INVALIDDATA;
}
- if (avctx->extradata[37] != 10) {
- av_log(avctx, AV_LOG_ERROR, "Unsupported quality mode.\n");
+
+ quality = avctx->extradata[37];
+ if (quality > 10) {
+ av_log(avctx, AV_LOG_ERROR, "Unsupported quality mode %d.\n", quality);
return AVERROR_PATCHWELCOME;
}
+
+ s->pktsize = ((const int[]){5,10,15,20,20,28,28,38,38,46,62})[quality];
+
spx_mode = 0;
} else if (header) {
avctx->sample_rate = header->rate;
*got_frame_ptr = 0;
return buf_size;
}
+ if (s->pktsize && buf_size == 62)
+ buf_size = s->pktsize;
/* set new buffer */
speex_bits_read_from(&s->bits, buf, buf_size);
- consumed = buf_size;
+ consumed = avpkt->size;
}
/* decode a single frame */
s->header.frames_per_packet = s->frames_per_packet;
/* set encoding delay */
- speex_encoder_ctl(s->enc_state, SPEEX_GET_LOOKAHEAD, &avctx->delay);
+ speex_encoder_ctl(s->enc_state, SPEEX_GET_LOOKAHEAD, &avctx->initial_padding);
ff_af_queue_init(avctx, &s->afq);
/* create header packet bytes from header struct */
int ret;
avctx->frame_size = TWOLAME_SAMPLES_PER_FRAME;
- avctx->delay = 512 - 32 + 1;
+ avctx->initial_padding = 512 - 32 + 1;
s->glopts = twolame_init();
if (!s->glopts)
if (ret < 0) // twolame error
return AVERROR_UNKNOWN;
- avpkt->duration = ff_samples_to_time_base(avctx, frame->nb_samples);
if (frame) {
+ avpkt->duration = ff_samples_to_time_base(avctx, frame->nb_samples);
if (frame->pts != AV_NOPTS_VALUE)
- avpkt->pts = frame->pts - ff_samples_to_time_base(avctx, avctx->delay);
+ avpkt->pts = frame->pts - ff_samples_to_time_base(avctx, avctx->initial_padding);
} else {
avpkt->pts = s->next_pts;
}
int format;
int begin_ret;
- if (avctx->extradata_size != 4*4) {
- av_log(avctx, AV_LOG_ERROR, "Extradata size mismatch.\n");
+ if (avctx->extradata_size != 16 && avctx->extradata_size != 8 ) {
+ av_log(avctx, AV_LOG_ERROR, "Extradata size (%d) mismatch.\n", avctx->extradata_size);
return -1;
}
avctx->pix_fmt = AV_PIX_FMT_RGB32;
format = UTVF_NFCC_BGRA_BU;
break;
+#ifdef UTVF_UQY2
+ case MKTAG('U', 'Q', 'Y', '2'):
+ avctx->pix_fmt = AV_PIX_FMT_YUV422P10;
+ format = UTVF_v210;
+ break;
+#endif
default:
av_log(avctx, AV_LOG_ERROR,
"Not a Ut Video FOURCC: %X\n", avctx->codec_tag);
/* Only allocate the buffer once */
utv->buf_size = avpicture_get_size(avctx->pix_fmt, avctx->width, avctx->height);
+#ifdef UTVF_UQY2
+ if (format == UTVF_v210)
+ utv->buf_size += avctx->height * ((avctx->width + 47) / 48) * 128; // the linesize used by the decoder, this does not seem to be exported
+#endif
utv->buffer = (uint8_t *)av_malloc(utv->buf_size * sizeof(uint8_t));
if (utv->buffer == NULL) {
pic->linesize[0] = w * 2;
pic->data[0] = utv->buffer;
break;
+ case AV_PIX_FMT_YUV422P10: {
+ uint16_t *y, *u, *v;
+ int i,j;
+ int linesize = ((w + 47) / 48) * 128;
+
+ pic->linesize[0] = w * 2;
+ pic->linesize[1] =
+ pic->linesize[2] = w;
+ pic->data[0] = utv->buffer + linesize * h;
+ pic->data[1] = pic->data[0] + h*pic->linesize[0];
+ pic->data[2] = pic->data[1] + h*pic->linesize[1];
+ y = (uint16_t*)pic->data[0];
+ u = (uint16_t*)pic->data[1];
+ v = (uint16_t*)pic->data[2];
+ for (j = 0; j < h; j++) {
+ const uint8_t *in = utv->buffer + j * linesize;
+
+ for (i = 0; i + 1 < w; i += 6, in += 4) {
+ unsigned a,b;
+ a = AV_RL32(in);
+ in += 4;
+ b = AV_RL32(in);
+ *u++ = (a ) & 0x3FF;
+ *y++ = (a>>10) & 0x3FF;
+ *v++ = (a>>20) & 0x3FF;
+ *y++ = (b ) & 0x3FF;
+
+ if (i + 3 >= w)
+ break;
+
+ in += 4;
+ a = AV_RL32(in);
+ *u++ = (b>>10) & 0x3FF;
+ *y++ = (b>>20) & 0x3FF;
+ *v++ = (a ) & 0x3FF;
+ *y++ = (a>>10) & 0x3FF;
+
+ if (i + 5 >= w)
+ break;
+
+ in += 4;
+ b = AV_RL32(in);
+ *u++ = (a>>20) & 0x3FF;
+ *y++ = (b ) & 0x3FF;
+ *v++ = (b>>10) & 0x3FF;
+ *y++ = (b>>20) & 0x3FF;
+ }
+ }
+ break;
+ }
case AV_PIX_FMT_BGR24:
case AV_PIX_FMT_RGB32:
/* Make the linesize negative, since Ut Video uses bottom-up BGR */
int index, ret;
avctx->frame_size = FRAME_SIZE;
- avctx->delay = ENC_DELAY;
+ avctx->initial_padding = ENC_DELAY;
s->last_frame = 2;
ff_af_queue_init(avctx, &s->afq);
s->last_bitrate = avctx->bit_rate;
avctx->frame_size = 320;
- avctx->delay = 80;
+ avctx->initial_padding = 80;
s->state = E_IF_init();
}
if (frame->pts != AV_NOPTS_VALUE)
- avpkt->pts = frame->pts - ff_samples_to_time_base(avctx, avctx->delay);
+ avpkt->pts = frame->pts - ff_samples_to_time_base(avctx, avctx->initial_padding);
avpkt->size = size;
*got_packet_ptr = 1;
static int oggvorbis_decode_init(AVCodecContext *avccontext) {
OggVorbisDecContext *context = avccontext->priv_data ;
uint8_t *p= avccontext->extradata;
- int i, hsizes[3];
+ int i, hsizes[3], ret;
unsigned char *headers[3], *extradata = avccontext->extradata;
- vorbis_info_init(&context->vi) ;
- vorbis_comment_init(&context->vc) ;
-
if(! avccontext->extradata_size || ! p) {
av_log(avccontext, AV_LOG_ERROR, "vorbis extradata absent\n");
- return -1;
+ return AVERROR(EINVAL);
}
+ vorbis_info_init(&context->vi) ;
+ vorbis_comment_init(&context->vc) ;
+
if(p[0] == 0 && p[1] == 30) {
for(i = 0; i < 3; i++){
hsizes[i] = bytestream_get_be16((const uint8_t **)&p);
if(offset >= avccontext->extradata_size - 1) {
av_log(avccontext, AV_LOG_ERROR,
"vorbis header sizes damaged\n");
- return -1;
+ ret = AVERROR_INVALIDDATA;
+ goto error;
}
hsizes[i] += *p;
offset++;
} else {
av_log(avccontext, AV_LOG_ERROR,
"vorbis initial header len is wrong: %d\n", *p);
- return -1;
+ ret = AVERROR_INVALIDDATA;
+ goto error;
}
for(i=0; i<3; i++){
context->op.packet = headers[i];
if(vorbis_synthesis_headerin(&context->vi, &context->vc, &context->op)<0){
av_log(avccontext, AV_LOG_ERROR, "%d. vorbis header damaged\n", i+1);
- return -1;
+ ret = AVERROR_INVALIDDATA;
+ goto error;
}
}
vorbis_block_init(&context->vd, &context->vb);
return 0 ;
+
+ error:
+ vorbis_info_clear(&context->vi);
+ vorbis_comment_clear(&context->vc) ;
+ return ret;
}
int dsp_initialized; /**< vd has been initialized */
vorbis_comment vc; /**< VorbisComment info */
double iblock; /**< impulse block bias option */
- VorbisParseContext vp; /**< parse context to get durations */
+ AVVorbisParseContext *vp; /**< parse context to get durations */
AudioFrameQueue afq; /**< frame queue for timestamps */
} LibvorbisEncContext;
ff_af_queue_close(&s->afq);
av_freep(&avctx->extradata);
+ av_vorbis_parse_free(&s->vp);
+
return 0;
}
offset += header_code.bytes;
av_assert0(offset == avctx->extradata_size);
- if ((ret = avpriv_vorbis_parse_extradata(avctx, &s->vp)) < 0) {
+ s->vp = av_vorbis_parse_init(avctx->extradata, avctx->extradata_size);
+ if (!s->vp) {
av_log(avctx, AV_LOG_ERROR, "invalid extradata\n");
return ret;
}
avpkt->pts = ff_samples_to_time_base(avctx, op.granulepos);
- duration = avpriv_vorbis_parse_frame(&s->vp, avpkt->data, avpkt->size);
+ duration = av_vorbis_parse_frame(s->vp, avpkt->data, avpkt->size);
if (duration > 0) {
/* we do not know encoder delay until we get the first packet from
* libvorbis, so we have to update the AudioFrameQueue counts */
- if (!avctx->delay && s->afq.frames) {
- avctx->delay = duration;
+ if (!avctx->initial_padding && s->afq.frames) {
+ avctx->initial_padding = duration;
av_assert0(!s->afq.remaining_delay);
s->afq.frames->duration += duration;
if (s->afq.frames->pts != AV_NOPTS_VALUE)
.init = libvorbis_encode_init,
.encode2 = libvorbis_encode_frame,
.close = libvorbis_encode_close,
- .capabilities = CODEC_CAP_DELAY,
+ .capabilities = CODEC_CAP_DELAY | CODEC_CAP_SMALL_LAST_FRAME,
.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
AV_SAMPLE_FMT_NONE },
.priv_class = &vorbis_class,
return AVERROR(EINVAL);
}
- avctx->pix_fmt = AV_PIX_FMT_YUV420P;
return 0;
}
+// returns 0 on success, AVERROR_INVALIDDATA otherwise
+static int set_pix_fmt(AVCodecContext *avctx, struct vpx_image *img) {
+ if (avctx->codec_id == AV_CODEC_ID_VP8 && img->fmt != VPX_IMG_FMT_I420)
+ return AVERROR_INVALIDDATA;
+ switch (img->fmt) {
+ case VPX_IMG_FMT_I420:
+ avctx->pix_fmt = AV_PIX_FMT_YUV420P;
+ return 0;
+#if CONFIG_LIBVPX_VP9_DECODER
+ case VPX_IMG_FMT_I422:
+ avctx->pix_fmt = AV_PIX_FMT_YUV422P;
+ return 0;
+ case VPX_IMG_FMT_I444:
+ avctx->pix_fmt = AV_PIX_FMT_YUV444P;
+ return 0;
+#ifdef VPX_IMG_FMT_HIGHBITDEPTH
+ case VPX_IMG_FMT_I42016:
+ if (img->bit_depth == 10) {
+ avctx->pix_fmt = AV_PIX_FMT_YUV420P10LE;
+ return 0;
+ } else if (img->bit_depth == 12) {
+ avctx->pix_fmt = AV_PIX_FMT_YUV420P12LE;
+ return 0;
+ } else {
+ return AVERROR_INVALIDDATA;
+ }
+ case VPX_IMG_FMT_I42216:
+ if (img->bit_depth == 10) {
+ avctx->pix_fmt = AV_PIX_FMT_YUV422P10LE;
+ return 0;
+ } else if (img->bit_depth == 12) {
+ avctx->pix_fmt = AV_PIX_FMT_YUV422P12LE;
+ return 0;
+ } else {
+ return AVERROR_INVALIDDATA;
+ }
+ case VPX_IMG_FMT_I44416:
+ if (img->bit_depth == 10) {
+ avctx->pix_fmt = AV_PIX_FMT_YUV444P10LE;
+ return 0;
+ } else if (img->bit_depth == 12) {
+ avctx->pix_fmt = AV_PIX_FMT_YUV444P12LE;
+ return 0;
+ } else {
+ return AVERROR_INVALIDDATA;
+ }
+#endif
+#endif
+ default:
+ return AVERROR_INVALIDDATA;
+ }
+}
+
static int vp8_decode(AVCodecContext *avctx,
void *data, int *got_frame, AVPacket *avpkt)
{
}
if ((img = vpx_codec_get_frame(&ctx->decoder, &iter))) {
- if (img->fmt != VPX_IMG_FMT_I420) {
- av_log(avctx, AV_LOG_ERROR, "Unsupported output colorspace (%d)\n",
- img->fmt);
- return AVERROR_INVALIDDATA;
+ if ((ret = set_pix_fmt(avctx, img)) < 0) {
+#ifdef VPX_IMG_FMT_HIGHBITDEPTH
+ av_log(avctx, AV_LOG_ERROR, "Unsupported output colorspace (%d) / bit_depth (%d)\n",
+ img->fmt, img->bit_depth);
+#else
+ av_log(avctx, AV_LOG_ERROR, "Unsupported output colorspace (%d) / bit_depth (%d)\n",
+ img->fmt, 8);
+#endif
+ return ret;
}
if ((int) img->d_w != avctx->width || (int) img->d_h != avctx->height) {
int lag_in_frames;
int error_resilient;
int crf;
+ int static_thresh;
int max_intra_rate;
// VP9-only
codecctl_int(avctx, VP8E_SET_NOISE_SENSITIVITY, avctx->noise_reduction);
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);
+#if FF_API_MPV_OPT
+ FF_DISABLE_DEPRECATION_WARNINGS
+ if (avctx->mb_threshold) {
+ av_log(avctx, AV_LOG_WARNING, "The mb_threshold option is deprecated, "
+ "use the static-thresh private option instead.\n");
+ ctx->static_thresh = avctx->mb_threshold;
+ }
+ FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+ codecctl_int(avctx, VP8E_SET_STATIC_THRESHOLD, ctx->static_thresh);
if (ctx->crf >= 0)
codecctl_int(avctx, VP8E_SET_CQ_LEVEL, ctx->crf);
if (ctx->max_intra_rate >= 0)
av_log(avctx, AV_LOG_ERROR,
"Data buffer alloc (%"SIZE_SPECIFIER" bytes) failed\n",
cx_frame->sz);
- av_free(cx_frame);
+ av_freep(&cx_frame);
return AVERROR(ENOMEM);
}
memcpy(cx_frame->buf, pkt->data.frame.buf, pkt->data.frame.sz);
}
if (rawimg_alpha) {
- av_free(rawimg_alpha->planes[VPX_PLANE_U]);
- av_free(rawimg_alpha->planes[VPX_PLANE_V]);
+ av_freep(&rawimg_alpha->planes[VPX_PLANE_U]);
+ av_freep(&rawimg_alpha->planes[VPX_PLANE_V]);
}
*got_packet = !!coded_size;
"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 = -1}, -1, 63, VE }, \
+ { "static-thresh", "A change threshold on blocks below which they will be skipped by the encoder", OFFSET(static_thresh), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, VE }, \
#define LEGACY_OPTIONS \
{"speed", "", offsetof(VP8Context, cpu_used), AV_OPT_TYPE_INT, {.i64 = 1}, -16, 16, VE}, \
int chroma_warning; // chroma linesize mismatch warning has been printed
int conversion_warning; // pixel format conversion warning has been printed
WebPConfig config; // libwebp configuration
+ AVFrame *ref;
+ int cr_size;
+ int cr_threshold;
} LibWebPContext;
static int libwebp_error_to_averror(int err)
LibWebPContext *s = avctx->priv_data;
int ret;
- if (avctx->global_quality < 0)
- avctx->global_quality = 75 * FF_QP2LAMBDA;
- s->quality = av_clipf(avctx->global_quality / (float)FF_QP2LAMBDA,
- 0.0f, 100.0f);
+ if (avctx->global_quality >= 0)
+ s->quality = av_clipf(avctx->global_quality / (float)FF_QP2LAMBDA,
+ 0.0f, 100.0f);
if (avctx->compression_level < 0 || avctx->compression_level > 6) {
av_log(avctx, AV_LOG_WARNING, "invalid compression level: %d\n",
pic->argb = (uint32_t *)frame->data[0];
pic->argb_stride = frame->linesize[0] / 4;
} else {
- if (frame->linesize[1] != frame->linesize[2]) {
- if (!s->chroma_warning) {
+ if (frame->linesize[1] != frame->linesize[2] || s->cr_threshold) {
+ if (!s->chroma_warning && !s->cr_threshold) {
av_log(avctx, AV_LOG_WARNING,
"Copying frame due to differing chroma linesizes.\n");
s->chroma_warning = 1;
alt_frame->width = frame->width;
alt_frame->height = frame->height;
alt_frame->format = frame->format;
+ if (s->cr_threshold)
+ alt_frame->format = AV_PIX_FMT_YUVA420P;
ret = av_frame_get_buffer(alt_frame, 32);
if (ret < 0)
goto end;
+ alt_frame->format = frame->format;
av_frame_copy(alt_frame, frame);
frame = alt_frame;
+ if (s->cr_threshold) {
+ int x,y, x2, y2, p;
+ int bs = s->cr_size;
+
+ if (!s->ref) {
+ s->ref = av_frame_clone(frame);
+ if (!s->ref) {
+ ret = AVERROR(ENOMEM);
+ goto end;
+ }
+ }
+
+ alt_frame->format = AV_PIX_FMT_YUVA420P;
+ for (y = 0; y < frame->height; y+= bs) {
+ for (x = 0; x < frame->width; x+= bs) {
+ int skip;
+ int sse = 0;
+ for (p = 0; p < 3; p++) {
+ int bs2 = bs >> !!p;
+ int w = FF_CEIL_RSHIFT(frame->width , !!p);
+ int h = FF_CEIL_RSHIFT(frame->height, !!p);
+ int xs = x >> !!p;
+ int ys = y >> !!p;
+ for (y2 = ys; y2 < FFMIN(ys + bs2, h); y2++) {
+ for (x2 = xs; x2 < FFMIN(xs + bs2, w); x2++) {
+ int diff = frame->data[p][frame->linesize[p] * y2 + x2]
+ -s->ref->data[p][frame->linesize[p] * y2 + x2];
+ sse += diff*diff;
+ }
+ }
+ }
+ skip = sse < s->cr_threshold && frame->data[3] != s->ref->data[3];
+ if (!skip)
+ for (p = 0; p < 3; p++) {
+ int bs2 = bs >> !!p;
+ int w = FF_CEIL_RSHIFT(frame->width , !!p);
+ int h = FF_CEIL_RSHIFT(frame->height, !!p);
+ int xs = x >> !!p;
+ int ys = y >> !!p;
+ for (y2 = ys; y2 < FFMIN(ys + bs2, h); y2++) {
+ memcpy(&s->ref->data[p][frame->linesize[p] * y2 + xs],
+ & frame->data[p][frame->linesize[p] * y2 + xs], FFMIN(bs2, w-xs));
+ }
+ }
+ for (y2 = y; y2 < FFMIN(y+bs, frame->height); y2++) {
+ memset(&frame->data[3][frame->linesize[3] * y2 + x],
+ skip ? 0 : 255,
+ FFMIN(bs, frame->width-x));
+ }
+ }
+ }
+ }
}
+
pic->use_argb = 0;
pic->y = frame->data[0];
pic->u = frame->data[1];
pic->v = frame->data[2];
pic->y_stride = frame->linesize[0];
pic->uv_stride = frame->linesize[1];
- if (avctx->pix_fmt == AV_PIX_FMT_YUVA420P) {
+ if (frame->format == AV_PIX_FMT_YUVA420P) {
pic->colorspace = WEBP_YUV420A;
pic->a = frame->data[3];
pic->a_stride = frame->linesize[3];
+ if (alt_frame)
+ WebPCleanupTransparentArea(pic);
} else {
pic->colorspace = WEBP_YUV420;
}
return ret;
}
+static int libwebp_encode_close(AVCodecContext *avctx)
+{
+ LibWebPContext *s = avctx->priv_data;
+
+ av_frame_free(&s->ref);
+
+ return 0;
+}
+
#define OFFSET(x) offsetof(LibWebPContext, x)
#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
static const AVOption options[] = {
{ "drawing", "hand or line drawing, with high-contrast details", 0, AV_OPT_TYPE_CONST, { .i64 = WEBP_PRESET_DRAWING }, 0, 0, VE, "preset" },
{ "icon", "small-sized colorful images", 0, AV_OPT_TYPE_CONST, { .i64 = WEBP_PRESET_ICON }, 0, 0, VE, "preset" },
{ "text", "text-like", 0, AV_OPT_TYPE_CONST, { .i64 = WEBP_PRESET_TEXT }, 0, 0, VE, "preset" },
+ { "cr_threshold","Conditional replenishment threshold", OFFSET(cr_threshold), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, VE },
+ { "cr_size" ,"Conditional replenishment block size", OFFSET(cr_size) , AV_OPT_TYPE_INT, { .i64 = 16 }, 0, 256, VE },
+ { "quality" ,"Quality", OFFSET(quality), AV_OPT_TYPE_FLOAT, { .dbl = 75 }, 0, 100, VE },
{ NULL },
};
+
static const AVClass class = {
.class_name = "libwebp",
.item_name = av_default_item_name,
.priv_data_size = sizeof(LibWebPContext),
.init = libwebp_encode_init,
.encode2 = libwebp_encode_frame,
+ .close = libwebp_encode_close,
.pix_fmts = (const enum AVPixelFormat[]) {
AV_PIX_FMT_RGB32,
AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUVA420P,
int slice_max_size;
char *stats;
int nal_hrd;
+ int avcintra_class;
char *x264_params;
} X264Context;
static int encode_nals(AVCodecContext *ctx, AVPacket *pkt,
- x264_nal_t *nals, int nnal)
+ const x264_nal_t *nals, int nnal)
{
X264Context *x4 = ctx->priv_data;
uint8_t *p;
frame->pict_type == AV_PICTURE_TYPE_P ? X264_TYPE_P :
frame->pict_type == AV_PICTURE_TYPE_B ? X264_TYPE_B :
X264_TYPE_AUTO;
+
+ if (x4->avcintra_class < 0) {
if (x4->params.b_interlaced && x4->params.b_tff != frame->top_field_first) {
x4->params.b_tff = frame->top_field_first;
x264_encoder_reconfig(x4->enc, &x4->params);
x4->params.rc.f_rf_constant_max = x4->crf_max;
x264_encoder_reconfig(x4->enc, &x4->params);
}
+ }
side_data = av_frame_get_side_data(frame, AV_FRAME_DATA_STEREO3D);
if (side_data) {
X264Context *x4 = avctx->priv_data;
av_freep(&avctx->extradata);
- av_free(x4->sei);
+ av_freep(&x4->sei);
if (x4->enc)
x264_encoder_close(x4->enc);
x4->params.b_bluray_compat = x4->bluray_compat;
x4->params.b_vfr_input = 0;
}
+ if (x4->avcintra_class >= 0)
+#if X264_BUILD >= 142
+ x4->params.i_avcintra_class = x4->avcintra_class;
+#else
+ av_log(avctx, AV_LOG_ERROR,
+ "x264 too old for AVC Intra, at least version 142 needed\n");
+#endif
if (x4->b_bias != INT_MIN)
x4->params.i_bframe_bias = x4->b_bias;
if (x4->b_pyramid >= 0)
{ "none", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = X264_NAL_HRD_NONE}, INT_MIN, INT_MAX, VE, "nal-hrd" },
{ "vbr", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = X264_NAL_HRD_VBR}, INT_MIN, INT_MAX, VE, "nal-hrd" },
{ "cbr", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = X264_NAL_HRD_CBR}, INT_MIN, INT_MAX, VE, "nal-hrd" },
+ { "avcintra-class","AVC-Intra class 50/100/200", OFFSET(avcintra_class),AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 200 , VE},
{ "x264-params", "Override the x264 configuration using a :-separated list of key=value parameters", OFFSET(x264_params), AV_OPT_TYPE_STRING, { 0 }, 0, 0, VE },
{ NULL },
};
ctx->params->fpsDenom = avctx->time_base.num * avctx->ticks_per_frame;
ctx->params->sourceWidth = avctx->width;
ctx->params->sourceHeight = avctx->height;
+ ctx->params->bEnablePsnr = !!(avctx->flags & CODEC_FLAG_PSNR);
if (avctx->sample_aspect_ratio.num > 0 && avctx->sample_aspect_ratio.den > 0) {
av_reduce(&sar_num, &sar_den,
XavsContext *x4 = avctx->priv_data;
av_freep(&avctx->extradata);
- av_free(x4->sei);
+ av_freep(&x4->sei);
av_freep(&x4->pts_buffer);
if (x4->enc)
static av_cold int xvid_encode_init(AVCodecContext *avctx)
{
- int xerr, i;
+ int xerr, i, ret = -1;
int xvid_flags = avctx->flags;
struct xvid_context *x = avctx->priv_data;
uint16_t *intra, *inter;
if (!x->twopassbuffer || !x->old_twopassbuffer) {
av_log(avctx, AV_LOG_ERROR,
"Xvid: Cannot allocate 2-pass log buffers\n");
+ ret = AVERROR(ENOMEM);
goto fail;
}
x->twopassbuffer[0] =
rc2pass2.bitrate = avctx->bit_rate;
fd = av_tempfile("xvidff.", &x->twopassfile, 0, avctx);
- if (fd == -1) {
+ if (fd < 0) {
av_log(avctx, AV_LOG_ERROR, "Xvid: Cannot write 2-pass pipe\n");
+ ret = fd;
goto fail;
}
x->twopassfd = fd;
if (!avctx->stats_in) {
av_log(avctx, AV_LOG_ERROR,
"Xvid: No 2-pass information loaded for second pass\n");
+ ret = AVERROR(EINVAL);
goto fail;
}
- if (strlen(avctx->stats_in) >
- write(fd, avctx->stats_in, strlen(avctx->stats_in))) {
+ ret = write(fd, avctx->stats_in, strlen(avctx->stats_in));
+ if (ret == -1)
+ ret = AVERROR(errno);
+ else if (strlen(avctx->stats_in) > ret) {
av_log(avctx, AV_LOG_ERROR, "Xvid: Cannot write to 2-pass pipe\n");
- goto fail;
+ ret = AVERROR(EIO);
}
+ if (ret < 0)
+ goto fail;
rc2pass2.filename = x->twopassfile;
plugins[xvid_enc_create.num_plugins].func = xvid_plugin_2pass2;
x->encoder_handle = xvid_enc_create.handle;
avctx->coded_frame = av_frame_alloc();
- if (!avctx->coded_frame)
- return AVERROR(ENOMEM);
+ if (!avctx->coded_frame) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
return 0;
fail:
xvid_encode_close(avctx);
- return -1;
+ return ret;
}
static int xvid_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
av_freep(&x->twopassfile);
av_freep(&x->intra_matrix);
av_freep(&x->inter_matrix);
+ av_frame_free(&avctx->coded_frame);
return 0;
}
(rce->header_bits + rce->mv_bits + 7) / 8);
if (write(fd, tmp, strlen(tmp)) < 0) {
+ int ret = AVERROR(errno);
av_log(NULL, AV_LOG_ERROR, "Error %s writing 2pass logfile\n", strerror(errno));
av_free(tmp_name);
close(fd);
- return AVERROR(errno);
+ return ret;
}
}
/* 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);
+ av_bprintf(&buf, "\r\n");
if (!av_bprint_is_complete(&buf)) {
av_bprint_finalize(&buf, NULL);
/**
* Calculate scalar product of v1 and v2,
* and v1[i] += v3[i] * mul
- * @param len length of vectors, should be multiple of 16
+ * @param len length of vectors, should be multiple of 8
*/
int32_t (*scalarproduct_and_madd_int16)(int16_t *v1 /* align 16 */,
const int16_t *v2,
int omethod, int max_shift, int zero_shift)
{
double autoc[MAX_LPC_ORDER+1];
- double ref[MAX_LPC_ORDER];
+ double ref[MAX_LPC_ORDER] = { 0 };
double lpc[MAX_LPC_ORDER][MAX_LPC_ORDER];
int i, j, pass = 0;
int opt_order;
}
if (lpc_type == FF_LPC_TYPE_CHOLESKY) {
- LLSModel m[2];
+ LLSModel *m = s->lls_models;
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));
#include <stdint.h>
#include "libavutil/avassert.h"
+#include "libavutil/lls.h"
#define ORDER_METHOD_EST 0
#define ORDER_METHOD_2LEVEL 1
*/
void (*lpc_compute_autocorr)(const double *data, int len, int lag,
double *autoc);
+
+ // TODO: these should be allocated to reduce ABI compatibility issues
+ LLSModel lls_models[2];
} LPCContext;
int normalize)
{
int i, j;
- LPC_TYPE err;
+ LPC_TYPE err = 0;
LPC_TYPE *lpc_last = lpc;
av_assert2(normalize || !fail);
uint32_t ff_square_tab[512] = { 0, };
static int sse4_c(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
- int line_size, int h)
+ ptrdiff_t stride, int h)
{
int s = 0, i;
uint32_t *sq = ff_square_tab + 256;
s += sq[pix1[1] - pix2[1]];
s += sq[pix1[2] - pix2[2]];
s += sq[pix1[3] - pix2[3]];
- pix1 += line_size;
- pix2 += line_size;
+ pix1 += stride;
+ pix2 += stride;
}
return s;
}
static int sse8_c(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
- int line_size, int h)
+ ptrdiff_t stride, int h)
{
int s = 0, i;
uint32_t *sq = ff_square_tab + 256;
s += sq[pix1[5] - pix2[5]];
s += sq[pix1[6] - pix2[6]];
s += sq[pix1[7] - pix2[7]];
- pix1 += line_size;
- pix2 += line_size;
+ pix1 += stride;
+ pix2 += stride;
}
return s;
}
static int sse16_c(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
- int line_size, int h)
+ ptrdiff_t stride, int h)
{
int s = 0, i;
uint32_t *sq = ff_square_tab + 256;
s += sq[pix1[14] - pix2[14]];
s += sq[pix1[15] - pix2[15]];
- pix1 += line_size;
- pix2 += line_size;
+ pix1 += stride;
+ pix2 += stride;
}
return s;
}
#define avg4(a, b, c, d) ((a + b + c + d + 2) >> 2)
static inline int pix_abs16_c(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
- int line_size, int h)
+ ptrdiff_t stride, int h)
{
int s = 0, i;
s += abs(pix1[13] - pix2[13]);
s += abs(pix1[14] - pix2[14]);
s += abs(pix1[15] - pix2[15]);
- pix1 += line_size;
- pix2 += line_size;
+ pix1 += stride;
+ pix2 += stride;
}
return s;
}
static int pix_abs16_x2_c(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
- int line_size, int h)
+ ptrdiff_t stride, int h)
{
int s = 0, i;
s += abs(pix1[13] - avg2(pix2[13], pix2[14]));
s += abs(pix1[14] - avg2(pix2[14], pix2[15]));
s += abs(pix1[15] - avg2(pix2[15], pix2[16]));
- pix1 += line_size;
- pix2 += line_size;
+ pix1 += stride;
+ pix2 += stride;
}
return s;
}
static int pix_abs16_y2_c(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
- int line_size, int h)
+ ptrdiff_t stride, int h)
{
int s = 0, i;
- uint8_t *pix3 = pix2 + line_size;
+ uint8_t *pix3 = pix2 + stride;
for (i = 0; i < h; i++) {
s += abs(pix1[0] - avg2(pix2[0], pix3[0]));
s += abs(pix1[13] - avg2(pix2[13], pix3[13]));
s += abs(pix1[14] - avg2(pix2[14], pix3[14]));
s += abs(pix1[15] - avg2(pix2[15], pix3[15]));
- pix1 += line_size;
- pix2 += line_size;
- pix3 += line_size;
+ pix1 += stride;
+ pix2 += stride;
+ pix3 += stride;
}
return s;
}
static int pix_abs16_xy2_c(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
- int line_size, int h)
+ ptrdiff_t stride, int h)
{
int s = 0, i;
- uint8_t *pix3 = pix2 + line_size;
+ uint8_t *pix3 = pix2 + stride;
for (i = 0; i < h; i++) {
s += abs(pix1[0] - avg4(pix2[0], pix2[1], pix3[0], pix3[1]));
s += abs(pix1[13] - avg4(pix2[13], pix2[14], pix3[13], pix3[14]));
s += abs(pix1[14] - avg4(pix2[14], pix2[15], pix3[14], pix3[15]));
s += abs(pix1[15] - avg4(pix2[15], pix2[16], pix3[15], pix3[16]));
- pix1 += line_size;
- pix2 += line_size;
- pix3 += line_size;
+ pix1 += stride;
+ pix2 += stride;
+ pix3 += stride;
}
return s;
}
static inline int pix_abs8_c(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
- int line_size, int h)
+ ptrdiff_t stride, int h)
{
int s = 0, i;
s += abs(pix1[5] - pix2[5]);
s += abs(pix1[6] - pix2[6]);
s += abs(pix1[7] - pix2[7]);
- pix1 += line_size;
- pix2 += line_size;
+ pix1 += stride;
+ pix2 += stride;
}
return s;
}
static int pix_abs8_x2_c(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
- int line_size, int h)
+ ptrdiff_t stride, int h)
{
int s = 0, i;
s += abs(pix1[5] - avg2(pix2[5], pix2[6]));
s += abs(pix1[6] - avg2(pix2[6], pix2[7]));
s += abs(pix1[7] - avg2(pix2[7], pix2[8]));
- pix1 += line_size;
- pix2 += line_size;
+ pix1 += stride;
+ pix2 += stride;
}
return s;
}
static int pix_abs8_y2_c(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
- int line_size, int h)
+ ptrdiff_t stride, int h)
{
int s = 0, i;
- uint8_t *pix3 = pix2 + line_size;
+ uint8_t *pix3 = pix2 + stride;
for (i = 0; i < h; i++) {
s += abs(pix1[0] - avg2(pix2[0], pix3[0]));
s += abs(pix1[5] - avg2(pix2[5], pix3[5]));
s += abs(pix1[6] - avg2(pix2[6], pix3[6]));
s += abs(pix1[7] - avg2(pix2[7], pix3[7]));
- pix1 += line_size;
- pix2 += line_size;
- pix3 += line_size;
+ pix1 += stride;
+ pix2 += stride;
+ pix3 += stride;
}
return s;
}
static int pix_abs8_xy2_c(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
- int line_size, int h)
+ ptrdiff_t stride, int h)
{
int s = 0, i;
- uint8_t *pix3 = pix2 + line_size;
+ uint8_t *pix3 = pix2 + stride;
for (i = 0; i < h; i++) {
s += abs(pix1[0] - avg4(pix2[0], pix2[1], pix3[0], pix3[1]));
s += abs(pix1[5] - avg4(pix2[5], pix2[6], pix3[5], pix3[6]));
s += abs(pix1[6] - avg4(pix2[6], pix2[7], pix3[6], pix3[7]));
s += abs(pix1[7] - avg4(pix2[7], pix2[8], pix3[7], pix3[8]));
- pix1 += line_size;
- pix2 += line_size;
- pix3 += line_size;
+ pix1 += stride;
+ pix2 += stride;
+ pix3 += stride;
}
return s;
}
-static int nsse16_c(MpegEncContext *c, uint8_t *s1, uint8_t *s2, int stride, int h)
+static int nsse16_c(MpegEncContext *c, uint8_t *s1, uint8_t *s2,
+ ptrdiff_t stride, int h)
{
int score1 = 0, score2 = 0, x, y;
return score1 + FFABS(score2) * 8;
}
-static int nsse8_c(MpegEncContext *c, uint8_t *s1, uint8_t *s2, int stride, int h)
+static int nsse8_c(MpegEncContext *c, uint8_t *s1, uint8_t *s2,
+ ptrdiff_t stride, int h)
{
int score1 = 0, score2 = 0, x, y;
}
static int zero_cmp(MpegEncContext *s, uint8_t *a, uint8_t *b,
- int stride, int h)
+ ptrdiff_t stride, int h)
{
return 0;
}
#define BUTTERFLYA(x, y) (FFABS((x) + (y)) + FFABS((x) - (y)))
static int hadamard8_diff8x8_c(MpegEncContext *s, uint8_t *dst,
- uint8_t *src, int stride, int h)
+ uint8_t *src, ptrdiff_t stride, int h)
{
int i, temp[64], sum = 0;
}
static int hadamard8_intra8x8_c(MpegEncContext *s, uint8_t *src,
- uint8_t *dummy, int stride, int h)
+ uint8_t *dummy, ptrdiff_t stride, int h)
{
int i, temp[64], sum = 0;
}
static int dct_sad8x8_c(MpegEncContext *s, uint8_t *src1,
- uint8_t *src2, int stride, int h)
+ uint8_t *src2, ptrdiff_t stride, int h)
{
LOCAL_ALIGNED_16(int16_t, temp, [64]);
}
static int dct264_sad8x8_c(MpegEncContext *s, uint8_t *src1,
- uint8_t *src2, int stride, int h)
+ uint8_t *src2, ptrdiff_t stride, int h)
{
int16_t dct[8][8];
int i, sum = 0;
#endif
static int dct_max8x8_c(MpegEncContext *s, uint8_t *src1,
- uint8_t *src2, int stride, int h)
+ uint8_t *src2, ptrdiff_t stride, int h)
{
LOCAL_ALIGNED_16(int16_t, temp, [64]);
int sum = 0, i;
}
static int quant_psnr8x8_c(MpegEncContext *s, uint8_t *src1,
- uint8_t *src2, int stride, int h)
+ uint8_t *src2, ptrdiff_t stride, int h)
{
LOCAL_ALIGNED_16(int16_t, temp, [64 * 2]);
int16_t *const bak = temp + 64;
}
static int rd8x8_c(MpegEncContext *s, uint8_t *src1, uint8_t *src2,
- int stride, int h)
+ ptrdiff_t stride, int h)
{
const uint8_t *scantable = s->intra_scantable.permutated;
LOCAL_ALIGNED_16(int16_t, temp, [64]);
}
static int bit8x8_c(MpegEncContext *s, uint8_t *src1, uint8_t *src2,
- int stride, int h)
+ ptrdiff_t stride, int h)
{
const uint8_t *scantable = s->intra_scantable.permutated;
LOCAL_ALIGNED_16(int16_t, temp, [64]);
#define VSAD_INTRA(size) \
static int vsad_intra ## size ## _c(MpegEncContext *c, \
uint8_t *s, uint8_t *dummy, \
- int stride, int h) \
+ ptrdiff_t stride, int h) \
{ \
int score = 0, x, y; \
\
#define VSAD(size) \
static int vsad ## size ## _c(MpegEncContext *c, \
uint8_t *s1, uint8_t *s2, \
- int stride, int h) \
+ ptrdiff_t stride, int h) \
{ \
int score = 0, x, y; \
\
#define VSSE_INTRA(size) \
static int vsse_intra ## size ## _c(MpegEncContext *c, \
uint8_t *s, uint8_t *dummy, \
- int stride, int h) \
+ ptrdiff_t stride, int h) \
{ \
int score = 0, x, y; \
\
#define VSSE(size) \
static int vsse ## size ## _c(MpegEncContext *c, uint8_t *s1, uint8_t *s2, \
- int stride, int h) \
+ ptrdiff_t stride, int h) \
{ \
int score = 0, x, y; \
\
#define WRAPPER8_16_SQ(name8, name16) \
static int name16(MpegEncContext *s, uint8_t *dst, uint8_t *src, \
- int stride, int h) \
+ ptrdiff_t stride, int h) \
{ \
int score = 0; \
\
* width < 8 are neither used nor implemented. */
typedef int (*me_cmp_func)(struct MpegEncContext *c,
uint8_t *blk1 /* align width (8 or 16) */,
- uint8_t *blk2 /* align 1 */, int line_size, int h);
+ uint8_t *blk2 /* align 1 */, ptrdiff_t stride,
+ int h);
typedef struct MECmpContext {
int (*sum_abs_dctelem)(int16_t *block /* align 16 */);
// italic, bold, underline, strike-through
#define MICRODVD_STYLES "ibus"
+/* some samples have lines that start with a / indicating non persistent italic
+ * marker */
+static char *check_for_italic_slash_marker(struct microdvd_tag *tags, char *s)
+{
+ if (*s == '/') {
+ struct microdvd_tag tag = tags[indexof(MICRODVD_TAGS, 'y')];
+ tag.key = 'y';
+ tag.data1 |= 1 << 0 /* 'i' position in MICRODVD_STYLES */;
+ microdvd_set_tag(tags, tag);
+ s++;
+ }
+ return s;
+}
+
static char *microdvd_load_tags(struct microdvd_tag *tags, char *s)
{
+ s = check_for_italic_slash_marker(tags, s);
+
while (*s == '{') {
char *start = s;
char tag_char = *(s + 1);
case 'C':
tag.persistent = MICRODVD_PERSISTENT_ON;
case 'c':
- if (*s == '$')
+ while (*s == '$' || *s == '#')
s++;
tag.data1 = strtol(s, &s, 16) & 0x00ffffff;
if (*s != '}')
microdvd_set_tag(tags, tag);
s++;
}
- return s;
+ return check_for_italic_slash_marker(tags, s);
}
static void microdvd_open_tags(AVBPrint *new_line, struct microdvd_tag *tags)
{
AVSubtitle *sub = data;
AVBPrint new_line;
- char c;
- char *decoded_sub;
char *line = avpkt->data;
char *end = avpkt->data + avpkt->size;
struct microdvd_tag tags[sizeof(MICRODVD_TAGS) - 1] = {{0}};
if (avpkt->size <= 0)
return avpkt->size;
- /* To be removed later */
- if (sscanf(line, "{%*d}{%*[0123456789]}%c", &c) == 1 &&
- line[avpkt->size - 1] == '\n') {
- av_log(avctx, AV_LOG_ERROR, "AVPacket is not clean (contains timing "
- "information and a trailing line break). You need to upgrade "
- "your libavformat or sanitize your packet.\n");
- return AVERROR_INVALIDDATA;
- }
-
av_bprint_init(&new_line, 0, 2048);
// subtitle content
}
}
if (new_line.len) {
- av_bprintf(&new_line, "\r\n");
-
- av_bprint_finalize(&new_line, &decoded_sub);
- if (*decoded_sub) {
- int64_t start = avpkt->pts;
- int64_t duration = avpkt->duration;
- int ts_start = av_rescale_q(start, avctx->time_base, (AVRational){1,100});
- int ts_duration = duration != -1 ?
- av_rescale_q(duration, avctx->time_base, (AVRational){1,100}) : -1;
- ff_ass_add_rect(sub, decoded_sub, ts_start, ts_duration, 0);
- }
- av_free(decoded_sub);
+ int ret;
+ int64_t start = avpkt->pts;
+ int64_t duration = avpkt->duration;
+ int ts_start = av_rescale_q(start, avctx->time_base, (AVRational){1,100});
+ int ts_duration = duration != -1 ?
+ av_rescale_q(duration, avctx->time_base, (AVRational){1,100}) : -1;
+
+ ret = ff_ass_add_rect_bprint(sub, &new_line, ts_start, ts_duration);
+ av_bprint_finalize(&new_line, NULL);
+ if (ret < 0)
+ return ret;
}
*got_sub_ptr = sub->num_rects > 0;
*/
if ((ics->window_sequence[1] == ONLY_LONG_SEQUENCE || ics->window_sequence[1] == LONG_STOP_SEQUENCE) &&
(ics->window_sequence[0] == ONLY_LONG_SEQUENCE || ics->window_sequence[0] == LONG_START_SEQUENCE)) {
- ac->fdsp.vector_fmul_window( out, saved, buf, lwindow_prev, 512);
+ ac->fdsp->vector_fmul_window( out, saved, buf, lwindow_prev, 512);
} else {
{
float *buf1 = saved;
}
}
} else {
- ac->fdsp.vector_fmul_window(out + 448, saved + 448, buf, swindow_prev, 64);
+ ac->fdsp->vector_fmul_window(out + 448, saved + 448, buf, swindow_prev, 64);
{
float *buf1 = buf + 64;
float *buf2 = out + 576;
// buffer update
if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
- ac->fdsp.vector_fmul_window(saved + 64, buf + 4*128 + 64, buf + 5*128, swindow, 64);
- ac->fdsp.vector_fmul_window(saved + 192, buf + 5*128 + 64, buf + 6*128, swindow, 64);
- ac->fdsp.vector_fmul_window(saved + 320, buf + 6*128 + 64, buf + 7*128, swindow, 64);
+ ac->fdsp->vector_fmul_window(saved + 64, buf + 4*128 + 64, buf + 5*128, swindow, 64);
+ ac->fdsp->vector_fmul_window(saved + 192, buf + 5*128 + 64, buf + 6*128, swindow, 64);
+ ac->fdsp->vector_fmul_window(saved + 320, buf + 6*128 + 64, buf + 7*128, swindow, 64);
{
float *buf1 = buf + 7*128 + 64;
float *buf2 = saved + 448;
: "memory"
);
- ac->fdsp.vector_fmul_reverse(saved_ltp + 448, ac->buf_mdct + 960, &swindow[64], 64);
+ ac->fdsp->vector_fmul_reverse(saved_ltp + 448, ac->buf_mdct + 960, &swindow[64], 64);
for (i = 0; i < 16; i++){
/* loop unrolled 4 times */
__asm__ volatile (
: [loop_end]"r"(loop_end)
: "memory"
);
- ac->fdsp.vector_fmul_reverse(saved_ltp + 448, ac->buf_mdct + 960, &swindow[64], 64);
+ ac->fdsp->vector_fmul_reverse(saved_ltp + 448, ac->buf_mdct + 960, &swindow[64], 64);
for (i = 0; i < 16; i++){
/* loop unrolled 8 times */
__asm__ volatile (
}
} else { // LONG_STOP or ONLY_LONG
float *ptr1, *ptr2, *ptr3;
- ac->fdsp.vector_fmul_reverse(saved_ltp, ac->buf_mdct + 512, &lwindow[512], 512);
+ ac->fdsp->vector_fmul_reverse(saved_ltp, ac->buf_mdct + 512, &lwindow[512], 512);
ptr1 = &saved_ltp[512];
ptr2 = &ac->buf_mdct[1023];
int ff_mjpeg_decode_sof(MJpegDecodeContext *s)
{
- int len, nb_components, i, width, height, bits, pix_fmt_id, ret;
+ int len, nb_components, i, width, height, bits, ret;
+ unsigned pix_fmt_id;
int h_count[MAX_COMPONENTS];
int v_count[MAX_COMPONENTS];
s->avctx->bits_per_raw_sample =
bits = get_bits(&s->gb, 8);
+ if (bits > 16 || bits < 1) {
+ av_log(s->avctx, AV_LOG_ERROR, "bits %d is invalid\n", bits);
+ return AVERROR_INVALIDDATA;
+ }
+
if (s->pegasus_rct)
bits = 9;
if (bits == 9 && !s->pegasus_rct)
else if (!s->lossless)
s->rgb = 0;
/* XXX: not complete test ! */
- pix_fmt_id = (s->h_count[0] << 28) | (s->v_count[0] << 24) |
+ pix_fmt_id = ((unsigned)s->h_count[0] << 28) | (s->v_count[0] << 24) |
(s->h_count[1] << 20) | (s->v_count[1] << 16) |
(s->h_count[2] << 12) | (s->v_count[2] << 8) |
(s->h_count[3] << 4) | s->v_count[3];
av_assert0(s->nb_components == 4);
break;
case 0x22111122:
+ case 0x22111111:
if (s->adobe_transform == 0 && s->bits <= 8) {
s->avctx->pix_fmt = AV_PIX_FMT_GBRAP;
- s->upscale_v = 6;
- s->upscale_h = 6;
- s->chroma_height = s->height;
+ s->upscale_v |= 6;
+ s->upscale_h |= 6;
} else if (s->adobe_transform == 2 && s->bits <= 8) {
s->avctx->pix_fmt = AV_PIX_FMT_YUVA444P;
- s->upscale_v = 6;
- s->upscale_h = 6;
- s->chroma_height = s->height;
+ s->upscale_v |= 6;
+ s->upscale_h |= 6;
s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG;
} else {
if (s->bits <= 8) s->avctx->pix_fmt = AV_PIX_FMT_YUVA420P;
else
goto unk_pixfmt;
s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG;
- s->chroma_height = s->height;
break;
case 0x22221100:
case 0x22112200:
else
goto unk_pixfmt;
s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG;
- s->chroma_height = (s->height + 1) / 2;
break;
case 0x11000000:
case 0x13000000:
break;
case 0x12111100:
case 0x14121200:
+ case 0x14111100:
case 0x22211100:
case 0x22112100:
- if (s->bits <= 8) s->avctx->pix_fmt = s->cs_itu601 ? AV_PIX_FMT_YUV440P : AV_PIX_FMT_YUVJ440P;
- else
- goto unk_pixfmt;
- s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG;
- s->chroma_height = (s->height + 1) / 2;
+ if (s->component_id[0] == 'Q' && s->component_id[1] == 'F' && s->component_id[2] == 'A') {
+ if (s->bits <= 8) s->avctx->pix_fmt = AV_PIX_FMT_GBRP;
+ else
+ goto unk_pixfmt;
+ s->upscale_v |= 3;
+ } else {
+ if (pix_fmt_id == 0x14111100)
+ s->upscale_v |= 6;
+ if (s->bits <= 8) s->avctx->pix_fmt = s->cs_itu601 ? AV_PIX_FMT_YUV440P : AV_PIX_FMT_YUVJ440P;
+ else
+ goto unk_pixfmt;
+ s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG;
+ }
break;
case 0x21111100:
- if (s->bits <= 8) s->avctx->pix_fmt = s->cs_itu601 ? AV_PIX_FMT_YUV422P : AV_PIX_FMT_YUVJ422P;
- else s->avctx->pix_fmt = AV_PIX_FMT_YUV422P16;
- s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG;
+ if (s->component_id[0] == 'Q' && s->component_id[1] == 'F' && s->component_id[2] == 'A') {
+ if (s->bits <= 8) s->avctx->pix_fmt = AV_PIX_FMT_GBRP;
+ else
+ goto unk_pixfmt;
+ s->upscale_h |= 3;
+ } else {
+ if (s->bits <= 8) s->avctx->pix_fmt = s->cs_itu601 ? AV_PIX_FMT_YUV422P : AV_PIX_FMT_YUVJ422P;
+ else s->avctx->pix_fmt = AV_PIX_FMT_YUV422P16;
+ s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG;
+ }
break;
case 0x22121100:
case 0x22111200:
break;
case 0x22111100:
case 0x42111100:
+ case 0x24111100:
if (s->bits <= 8) s->avctx->pix_fmt = s->cs_itu601 ? AV_PIX_FMT_YUV420P : AV_PIX_FMT_YUVJ420P;
else s->avctx->pix_fmt = AV_PIX_FMT_YUV420P16;
s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG;
if (pix_fmt_id == 0x42111100) {
+ if (s->bits > 8)
+ goto unk_pixfmt;
s->upscale_h = 6;
- s->chroma_height = (s->height + 1) / 2;
+ } else if (pix_fmt_id == 0x24111100) {
+ if (s->bits > 8)
+ goto unk_pixfmt;
+ s->upscale_v = 6;
}
break;
case 0x41111100:
break;
default:
unk_pixfmt:
- av_log(s->avctx, AV_LOG_ERROR, "Unhandled pixel format 0x%x\n", pix_fmt_id);
+ av_log(s->avctx, AV_LOG_ERROR, "Unhandled pixel format 0x%x bits:%d\n", pix_fmt_id, s->bits);
s->upscale_h = s->upscale_v = 0;
return AVERROR_PATCHWELCOME;
}
}
if (!Al) {
+ // s->coefs_finished is a bitmask for coefficients coded
+ // ss and se are parameters telling start and end coefficients
s->coefs_finished[c] |= (2ULL << se) - (1ULL << ss);
last_scan = !~s->coefs_finished[c];
}
}
if (id == AV_RB32("LJIF")) {
+ int rgb = s->rgb;
+ int pegasus_rct = s->pegasus_rct;
if (s->avctx->debug & FF_DEBUG_PICT_INFO)
av_log(s->avctx, AV_LOG_INFO,
"Pegasus lossless jpeg header found\n");
skip_bits(&s->gb, 16); /* unknown always 0? */
switch (i=get_bits(&s->gb, 8)) {
case 1:
- s->rgb = 1;
- s->pegasus_rct = 0;
+ rgb = 1;
+ pegasus_rct = 0;
break;
case 2:
- s->rgb = 1;
- s->pegasus_rct = 1;
+ rgb = 1;
+ pegasus_rct = 1;
break;
default:
av_log(s->avctx, AV_LOG_ERROR, "unknown colorspace %d\n", i);
}
+
len -= 9;
+ if (s->got_picture)
+ if (rgb != s->rgb || pegasus_rct != s->pegasus_rct) {
+ av_log(s->avctx, AV_LOG_WARNING, "Mismatching LJIF tag\n");
+ goto out;
+ }
+
+ s->rgb = rgb;
+ s->pegasus_rct = pegasus_rct;
+
goto out;
}
if (id == AV_RL32("colr") && len > 0) {
avctx->pix_fmt == AV_PIX_FMT_YUVJ420P ||
avctx->pix_fmt == AV_PIX_FMT_YUV420P ||
avctx->pix_fmt == AV_PIX_FMT_YUV420P16||
+ avctx->pix_fmt == AV_PIX_FMT_YUVA420P ||
+ avctx->pix_fmt == AV_PIX_FMT_YUVA420P16||
+ avctx->pix_fmt == AV_PIX_FMT_GBRP ||
avctx->pix_fmt == AV_PIX_FMT_GBRAP
);
avcodec_get_chroma_sub_sample(s->avctx->pix_fmt, &hshift, &vshift);
for (p = 0; p<4; p++) {
uint8_t *line = s->picture_ptr->data[p];
int w = s->width;
+ int h = s->height;
if (!(s->upscale_h & (1<<p)))
continue;
- if (p==1 || p==2)
- w >>= hshift;
+ if (p==1 || p==2) {
+ w = FF_CEIL_RSHIFT(w, hshift);
+ h = FF_CEIL_RSHIFT(h, vshift);
+ }
+ if (s->upscale_v & (1<<p))
+ h = (h+1)>>1;
av_assert0(w > 0);
- for (i = 0; i < s->chroma_height; i++) {
+ for (i = 0; i < h; i++) {
if (is16bit) ((uint16_t*)line)[w - 1] = ((uint16_t*)line)[(w - 1) / 2];
else line[w - 1] = line[(w - 1) / 2];
for (index = w - 2; index > 0; index--) {
avctx->pix_fmt == AV_PIX_FMT_YUV444P ||
avctx->pix_fmt == AV_PIX_FMT_YUVJ422P ||
avctx->pix_fmt == AV_PIX_FMT_YUV422P ||
+ avctx->pix_fmt == AV_PIX_FMT_YUVJ420P ||
+ avctx->pix_fmt == AV_PIX_FMT_YUV420P ||
+ avctx->pix_fmt == AV_PIX_FMT_YUV440P ||
+ avctx->pix_fmt == AV_PIX_FMT_YUVJ440P ||
avctx->pix_fmt == AV_PIX_FMT_YUVA444P ||
+ avctx->pix_fmt == AV_PIX_FMT_YUVA420P ||
+ avctx->pix_fmt == AV_PIX_FMT_YUVA420P16||
+ avctx->pix_fmt == AV_PIX_FMT_GBRP ||
avctx->pix_fmt == AV_PIX_FMT_GBRAP
);
avcodec_get_chroma_sub_sample(s->avctx->pix_fmt, &hshift, &vshift);
for (p = 0; p < 4; p++) {
- uint8_t *dst = &((uint8_t *)s->picture_ptr->data[p])[(s->height - 1) * s->linesize[p]];
+ uint8_t *dst;
int w = s->width;
+ int h = s->height;
if (!(s->upscale_v & (1<<p)))
continue;
- if (p==1 || p==2)
+ if (p==1 || p==2) {
w = FF_CEIL_RSHIFT(w, hshift);
- for (i = s->height - 1; i; i--) {
+ h = FF_CEIL_RSHIFT(h, vshift);
+ }
+ dst = &((uint8_t *)s->picture_ptr->data[p])[(h - 1) * s->linesize[p]];
+ for (i = h - 1; i; i--) {
uint8_t *src1 = &((uint8_t *)s->picture_ptr->data[p])[i / 2 * s->linesize[p]];
uint8_t *src2 = &((uint8_t *)s->picture_ptr->data[p])[(i + 1) / 2 * s->linesize[p]];
- if (src1 == src2 || i == s->height - 1) {
+ if (src1 == src2 || i == h - 1) {
memcpy(dst, src1, w);
} else {
for (index = 0; index < w; index++)
int progressive;
int rgb;
int upscale_h;
- int chroma_height;
int upscale_v;
int rct; /* standard rct */
int pegasus_rct; /* pegasus reversible colorspace transform */
void ff_mjpeg_encode_close(MpegEncContext *s)
{
- av_free(s->mjpeg_ctx);
+ av_freep(&s->mjpeg_ctx);
}
static void encode_block(MpegEncContext *s, int16_t *block, int n)
}
#if CONFIG_MJPEG_ENCODER
+FF_MPV_GENERIC_CLASS(mjpeg)
+
AVCodec ff_mjpeg_encoder = {
.name = "mjpeg",
.long_name = NULL_IF_CONFIG_SMALL("MJPEG (Motion JPEG)"),
.pix_fmts = (const enum AVPixelFormat[]){
AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_NONE
},
+ .priv_class = &mjpeg_class,
};
#endif
#if CONFIG_AMV_ENCODER
+FF_MPV_GENERIC_CLASS(amv)
+
AVCodec ff_amv_encoder = {
.name = "amv",
.long_name = NULL_IF_CONFIG_SMALL("AMV Video"),
.pix_fmts = (const enum AVPixelFormat[]){
AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_NONE
},
+ .priv_class = &amv_class,
};
#endif
/** Maximum number of substreams that can be decoded.
* MLP's limit is 2. TrueHD supports at least up to 3.
*/
-#define MAX_SUBSTREAMS 3
+#define MAX_SUBSTREAMS 4
/** which multiple of 48000 the maximum sample rate is */
#define MAX_RATEFACTOR 4
return layout;
}
+static int ff_mlp_get_major_sync_size(const uint8_t * buf, int bufsize)
+{
+ int has_extension, extensions = 0;
+ int size = 28;
+ if (bufsize < 28)
+ return -1;
+
+ if (AV_RB32(buf) == 0xf8726fba) {
+ has_extension = buf[25] & 1;
+ if (has_extension) {
+ extensions = buf[26] >> 4;
+ size += 2 + extensions * 2;
+ }
+ }
+ return size;
+}
+
/** Read a major sync info header - contains high level information about
* the stream - sample rate, channel arrangement etc. Most of this
* information is not actually necessary for decoding, only for playback.
int ff_mlp_read_major_sync(void *log, MLPHeaderInfo *mh, GetBitContext *gb)
{
- int ratebits, channel_arrangement;
+ int ratebits, channel_arrangement, header_size;
uint16_t checksum;
av_assert1(get_bits_count(gb) == 0);
- if (gb->size_in_bits < 28 << 3) {
+ header_size = ff_mlp_get_major_sync_size(gb->buffer, gb->size_in_bits >> 3);
+ if (header_size < 0 || gb->size_in_bits < header_size << 3) {
av_log(log, AV_LOG_ERROR, "packet too short, unable to read major sync\n");
return -1;
}
- checksum = ff_mlp_checksum16(gb->buffer, 26);
- if (checksum != AV_RL16(gb->buffer+26)) {
+ checksum = ff_mlp_checksum16(gb->buffer, header_size - 2);
+ if (checksum != AV_RL16(gb->buffer+header_size-2)) {
av_log(log, AV_LOG_ERROR, "major sync info header checksum error\n");
return AVERROR_INVALIDDATA;
}
return AVERROR_INVALIDDATA;
mh->stream_type = get_bits(gb, 8);
+ mh->header_size = header_size;
if (mh->stream_type == 0xbb) {
mh->group1_bits = mlp_quants[get_bits(gb, 4)];
mh->num_substreams = get_bits(gb, 4);
- skip_bits_long(gb, 4 + 11 * 8);
+ skip_bits_long(gb, 4 + (header_size - 17) * 8);
return 0;
}
typedef struct MLPHeaderInfo
{
int stream_type; ///< 0xBB for MLP, 0xBA for TrueHD
+ int header_size; ///< Size of the major sync header, in bytes
int group1_bits; ///< The bit depth of the first substream
int group2_bits; ///< Bit depth of the second substream (MLP only)
/// Whether the LSBs of the matrix output are encoded in the bitstream.
uint8_t lsb_bypass[MAX_MATRICES];
/// Matrix coefficients, stored as 2.14 fixed point.
- int32_t matrix_coeff[MAX_MATRICES][MAX_CHANNELS];
+ DECLARE_ALIGNED(32, int32_t, matrix_coeff)[MAX_MATRICES][MAX_CHANNELS];
/// Left shift to apply to noise values in 0x31eb substreams.
uint8_t matrix_noise_shift[MAX_MATRICES];
//@}
/// Current access unit being read has a major sync.
int is_major_sync_unit;
+ /// Size of the major sync unit, in bytes
+ int major_sync_header_size;
+
/// Set if a valid major sync block has been read. Otherwise no decoding is possible.
uint8_t params_valid;
int8_t noise_buffer[MAX_BLOCKSIZE_POW2];
int8_t bypassed_lsbs[MAX_BLOCKSIZE][MAX_CHANNELS];
- int32_t sample_buffer[MAX_BLOCKSIZE][MAX_CHANNELS];
+ DECLARE_ALIGNED(32, int32_t, sample_buffer)[MAX_BLOCKSIZE][MAX_CHANNELS];
MLPDSPContext dsp;
} MLPDecodeContext;
return AVERROR_PATCHWELCOME;
}
+ m->major_sync_header_size = mh.header_size;
+
m->access_unit_size = mh.access_unit_size;
m->access_unit_size_pow2 = mh.access_unit_size_pow2;
m->num_substreams = mh.num_substreams;
- m->max_decoded_substream = m->num_substreams - 1;
+
+ /* limit to decoding 3 substreams, as the 4th is used by Dolby Atmos for non-audio data */
+ m->max_decoded_substream = FFMIN(m->num_substreams - 1, 2);
m->avctx->sample_rate = mh.group1_samplerate;
m->avctx->frame_size = mh.access_unit_size;
ch_assign = av_get_channel_layout_channel_index(s->ch_layout,
channel);
}
- if ((unsigned)ch_assign > s->max_matrix_channel) {
+ if (ch_assign < 0 || ch_assign > s->max_matrix_channel) {
avpriv_request_sample(m->avctx,
"Assignment of matrix channel %d to invalid output channel %d",
ch, ch_assign);
s->noisegen_seed = seed;
}
+/** Write the audio data into the output buffer. */
-/** Apply the channel matrices in turn to reconstruct the original audio
- * samples. */
-
-static void rematrix_channels(MLPDecodeContext *m, unsigned int substr)
+static int output_data(MLPDecodeContext *m, unsigned int substr,
+ AVFrame *frame, int *got_frame_ptr)
{
+ AVCodecContext *avctx = m->avctx;
SubStream *s = &m->substream[substr];
unsigned int mat;
unsigned int maxchan;
+ int ret;
+ int is32 = (m->avctx->sample_fmt == AV_SAMPLE_FMT_S32);
+
+ if (m->avctx->channels != s->max_matrix_channel + 1) {
+ av_log(m->avctx, AV_LOG_ERROR, "channel count mismatch\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (!s->blockpos) {
+ av_log(avctx, AV_LOG_ERROR, "No samples to output.\n");
+ return AVERROR_INVALIDDATA;
+ }
maxchan = s->max_matrix_channel;
if (!s->noise_type) {
fill_noise_buffer(m, substr);
}
+ /* Apply the channel matrices in turn to reconstruct the original audio
+ * samples. */
for (mat = 0; mat < s->num_primitive_matrices; mat++) {
unsigned int dest_ch = s->matrix_out_ch[mat];
m->dsp.mlp_rematrix_channel(&m->sample_buffer[0][0],
m->access_unit_size_pow2,
MSB_MASK(s->quant_step_size[dest_ch]));
}
-}
-
-/** Write the audio data into the output buffer. */
-
-static int output_data(MLPDecodeContext *m, unsigned int substr,
- AVFrame *frame, int *got_frame_ptr)
-{
- AVCodecContext *avctx = m->avctx;
- SubStream *s = &m->substream[substr];
- int ret;
- int is32 = (m->avctx->sample_fmt == AV_SAMPLE_FMT_S32);
-
- if (m->avctx->channels != s->max_matrix_channel + 1) {
- av_log(m->avctx, AV_LOG_ERROR, "channel count mismatch\n");
- return AVERROR_INVALIDDATA;
- }
-
- if (!s->blockpos) {
- av_log(avctx, AV_LOG_ERROR, "No samples to output.\n");
- return AVERROR_INVALIDDATA;
- }
/* get output buffer */
frame->nb_samples = s->blockpos;
if (read_major_sync(m, &gb) < 0)
goto error;
m->is_major_sync_unit = 1;
- header_size += 28;
+ header_size += m->major_sync_header_size;
}
if (!m->params_valid) {
buf += substream_data_len[substr];
}
- rematrix_channels(m, m->max_decoded_substream);
-
if ((ret = output_data(m, m->max_decoded_substream, data, got_frame_ptr)) < 0)
return ret;
typedef struct MmContext {
AVCodecContext *avctx;
AVFrame *frame;
- int palette[AVPALETTE_COUNT];
+ unsigned int palette[AVPALETTE_COUNT];
GetByteContext gb;
} MmContext;
int uvdxy; /* no, it might not be used uninitialized */
if(dxy){
if(qpel){
- c->qpel_put[size][dxy](c->temp, ref[0] + x + y*stride, stride); //FIXME prototype (add h)
+ if (h << size == 16) {
+ c->qpel_put[size][dxy](c->temp, ref[0] + x + y*stride, stride); //FIXME prototype (add h)
+ } else if (size == 0 && h == 8) {
+ c->qpel_put[1][dxy](c->temp , ref[0] + x + y*stride , stride);
+ c->qpel_put[1][dxy](c->temp + 8, ref[0] + x + y*stride + 8, stride);
+ } else
+ av_assert2(0);
if(chroma){
int cx= hx/2;
int cy= hy/2;
#include "motion_est_template.c"
static int zero_cmp(MpegEncContext *s, uint8_t *a, uint8_t *b,
- int stride, int h)
+ ptrdiff_t stride, int h)
{
return 0;
}
pic->mc_mb_var[s->mb_stride * mb_y + mb_x] = (vard+128)>>8;
c->mc_mb_var_sum_temp += (vard+128)>>8;
- if(mb_type){
- int p_score= FFMIN(vard, varc-500+(s->lambda2>>FF_LAMBDA_SHIFT)*100);
- int i_score= varc-500+(s->lambda2>>FF_LAMBDA_SHIFT)*20;
- c->scene_change_score+= ff_sqrt(p_score) - ff_sqrt(i_score);
-
- if(mb_type == CANDIDATE_MB_TYPE_INTER){
- c->sub_motion_search(s, &mx, &my, dmin, 0, 0, 0, 16);
- set_p_mv_tables(s, mx, my, 1);
- }else{
- mx <<=shift;
- my <<=shift;
- }
- if(mb_type == CANDIDATE_MB_TYPE_INTER4V){
- h263_mv4_search(s, mx, my, shift);
-
- set_p_mv_tables(s, mx, my, 0);
- }
- if(mb_type == CANDIDATE_MB_TYPE_INTER_I){
- interlaced_search(s, 0, s->p_field_mv_table, s->p_field_select_table, mx, my, 1);
- }
- }else if(c->avctx->mb_decision > FF_MB_DECISION_SIMPLE){
+ if (c->avctx->mb_decision > FF_MB_DECISION_SIMPLE) {
int p_score= FFMIN(vard, varc-500+(s->lambda2>>FF_LAMBDA_SHIFT)*100);
int i_score= varc-500+(s->lambda2>>FF_LAMBDA_SHIFT)*20;
c->scene_change_score+= ff_sqrt(p_score) - ff_sqrt(i_score);
text++;
}
- av_bprintf(buf, "\r\n");
return 0;
}
void *data, int *got_sub_ptr, AVPacket *avpkt)
{
AVSubtitle *sub = data;
- int ts_start, ts_end;
+ int ret, ts_start, ts_end;
AVBPrint buf;
const char *ptr = avpkt->data;
const char *end;
// Note that the spec recommends lines be no longer than 2048 characters.
av_bprint_init(&buf, 0, AV_BPRINT_SIZE_UNLIMITED);
text_to_ass(&buf, ptr, end);
-
- if (!av_bprint_is_complete(&buf))
- return AVERROR(ENOMEM);
-
- ff_ass_add_rect(sub, buf.str, ts_start, ts_end-ts_start, 0);
- *got_sub_ptr = sub->num_rects > 0;
+ ret = ff_ass_add_rect_bprint(sub, &buf, ts_start, ts_end-ts_start);
av_bprint_finalize(&buf, NULL);
+ if (ret < 0)
+ return ret;
+ *got_sub_ptr = sub->num_rects > 0;
return avpkt->size;
}
{
int i, j, k, cbp, val, mb_type, motion_type;
const int mb_block_count = 4 + (1 << s->chroma_format);
+ int ret;
av_dlog(s->avctx, "decode_mb: x=%d y=%d\n", s->mb_x, s->mb_y);
mb_type = s->current_picture.mb_type[s->mb_width + (s->mb_y - 1) * s->mb_stride - 1];
if (IS_INTRA(mb_type)) {
av_log(s->avctx, AV_LOG_ERROR, "skip with previntra\n");
- return -1;
+ return AVERROR_INVALIDDATA;
}
s->current_picture.mb_type[s->mb_x + s->mb_y * s->mb_stride] =
mb_type | MB_TYPE_SKIP;
av_log(s->avctx, AV_LOG_ERROR,
"invalid mb type in I Frame at %d %d\n",
s->mb_x, s->mb_y);
- return -1;
+ return AVERROR_INVALIDDATA;
}
mb_type = MB_TYPE_QUANT | MB_TYPE_INTRA;
} else {
if (mb_type < 0) {
av_log(s->avctx, AV_LOG_ERROR,
"invalid mb type in P Frame at %d %d\n", s->mb_x, s->mb_y);
- return -1;
+ return AVERROR_INVALIDDATA;
}
mb_type = ptype2mb_type[mb_type];
break;
if (mb_type < 0) {
av_log(s->avctx, AV_LOG_ERROR,
"invalid mb type in B Frame at %d %d\n", s->mb_x, s->mb_y);
- return -1;
+ return AVERROR_INVALIDDATA;
}
mb_type = btype2mb_type[mb_type];
break;
mpeg2_fast_decode_block_intra(s, *s->pblocks[i], i);
} else {
for (i = 0; i < mb_block_count; i++)
- if (mpeg2_decode_block_intra(s, *s->pblocks[i], i) < 0)
- return -1;
+ if ((ret = mpeg2_decode_block_intra(s, *s->pblocks[i], i)) < 0)
+ return ret;
}
} else {
for (i = 0; i < 6; i++)
- if (mpeg1_decode_block_intra(s, *s->pblocks[i], i) < 0)
- return -1;
+ if ((ret = mpeg1_decode_block_intra(s, *s->pblocks[i], i)) < 0)
+ return ret;
}
} else {
if (mb_type & MB_TYPE_ZERO_MV) {
case MT_DMV:
if (s->progressive_sequence){
av_log(s->avctx, AV_LOG_ERROR, "MT_DMV in progressive_sequence\n");
- return -1;
+ return AVERROR_INVALIDDATA;
}
s->mv_type = MV_TYPE_DMV;
for (i = 0; i < 2; i++) {
default:
av_log(s->avctx, AV_LOG_ERROR,
"00 motion_type at %d %d\n", s->mb_x, s->mb_y);
- return -1;
+ return AVERROR_INVALIDDATA;
}
}
if (cbp <= 0) {
av_log(s->avctx, AV_LOG_ERROR,
"invalid cbp %d at %d %d\n", cbp, s->mb_x, s->mb_y);
- return -1;
+ return AVERROR_INVALIDDATA;
}
// if 1, we memcpy blocks in xvmcvideo
for (i = 0; i < mb_block_count; i++) {
if (cbp & (1 << 11)) {
- if (mpeg2_decode_block_non_intra(s, *s->pblocks[i], i) < 0)
- return -1;
+ if ((ret = mpeg2_decode_block_non_intra(s, *s->pblocks[i], i)) < 0)
+ return ret;
} else {
s->block_last_index[i] = -1;
}
} else {
for (i = 0; i < 6; i++) {
if (cbp & 32) {
- if (mpeg1_decode_block_inter(s, *s->pblocks[i], i) < 0)
- return -1;
+ if ((ret = mpeg1_decode_block_inter(s, *s->pblocks[i], i)) < 0)
+ return ret;
} else {
s->block_last_index[i] = -1;
}
MpegEncContext *s2 = &s->mpeg_enc_ctx;
ff_mpv_decode_defaults(s2);
+
+ if ( avctx->codec_tag != AV_RL32("VCR2")
+ && avctx->codec_tag != AV_RL32("BW10"))
+ avctx->coded_width = avctx->coded_height = 0; // do not trust dimensions from input
ff_mpv_decode_init(s2, avctx);
s->mpeg_enc_ctx.avctx = avctx;
if (avctx->codec_id == AV_CODEC_ID_MPEG1VIDEO) {
// MPEG-1 fps
- avctx->time_base.den = ff_mpeg12_frame_rate_tab[s->frame_rate_index].num;
- avctx->time_base.num = ff_mpeg12_frame_rate_tab[s->frame_rate_index].den;
+ avctx->framerate = ff_mpeg12_frame_rate_tab[s->frame_rate_index];
// MPEG-1 aspect
avctx->sample_aspect_ratio = av_d2q(1.0 / ff_mpeg1_aspect[s->aspect_ratio_info], 255);
avctx->ticks_per_frame = 1;
} else { // MPEG-2
// MPEG-2 fps
- av_reduce(&s->avctx->time_base.den,
- &s->avctx->time_base.num,
- ff_mpeg12_frame_rate_tab[s->frame_rate_index].num * s1->frame_rate_ext.num * 2,
+ av_reduce(&s->avctx->framerate.num,
+ &s->avctx->framerate.den,
+ ff_mpeg12_frame_rate_tab[s->frame_rate_index].num * s1->frame_rate_ext.num,
ff_mpeg12_frame_rate_tab[s->frame_rate_index].den * s1->frame_rate_ext.den,
1 << 30);
avctx->ticks_per_frame = 2;
ref = get_bits(&s->gb, 10); /* temporal ref */
s->pict_type = get_bits(&s->gb, 3);
if (s->pict_type == 0 || s->pict_type > 3)
- return -1;
+ return AVERROR_INVALIDDATA;
vbv_delay = get_bits(&s->gb, 16);
s->vbv_delay = vbv_delay;
s->full_pel[0] = get_bits1(&s->gb);
f_code = get_bits(&s->gb, 3);
if (f_code == 0 && (avctx->err_recognition & (AV_EF_BITSTREAM|AV_EF_COMPLIANT)))
- return -1;
+ return AVERROR_INVALIDDATA;
f_code += !f_code;
s->mpeg_f_code[0][0] = f_code;
s->mpeg_f_code[0][1] = f_code;
s->full_pel[1] = get_bits1(&s->gb);
f_code = get_bits(&s->gb, 3);
if (f_code == 0 && (avctx->err_recognition & (AV_EF_BITSTREAM|AV_EF_COMPLIANT)))
- return -1;
+ return AVERROR_INVALIDDATA;
f_code += !f_code;
s->mpeg_f_code[1][0] = f_code;
s->mpeg_f_code[1][1] = f_code;
int v = get_bits(&s->gb, 8);
if (v == 0) {
av_log(s->avctx, AV_LOG_ERROR, "matrix damaged\n");
- return -1;
+ return AVERROR_INVALIDDATA;
}
if (intra && i == 0 && v != 8) {
av_log(s->avctx, AV_LOG_DEBUG, "intra matrix specifies invalid DC quantizer %d, ignoring\n", v);
{
AVCodecContext *avctx = s->avctx;
Mpeg1Context *s1 = (Mpeg1Context *) s;
+ int ret;
/* start frame decoding */
if (s->first_field || s->picture_structure == PICT_FRAME) {
AVFrameSideData *pan_scan;
- if (ff_mpv_frame_start(s, avctx) < 0)
- return -1;
+ if ((ret = ff_mpv_frame_start(s, avctx)) < 0)
+ return ret;
ff_mpeg_er_frame_start(s);
}
if (avctx->hwaccel) {
- if (avctx->hwaccel->start_frame(avctx, buf, buf_size) < 0)
- return -1;
+ if ((ret = avctx->hwaccel->start_frame(avctx, buf, buf_size)) < 0)
+ return ret;
}
return 0;
AVCodecContext *avctx = s->avctx;
const int lowres = s->avctx->lowres;
const int field_pic = s->picture_structure != PICT_FRAME;
+ int ret;
s->resync_mb_x =
s->resync_mb_y = -1;
if (s->qscale == 0) {
av_log(s->avctx, AV_LOG_ERROR, "qscale == 0\n");
- return -1;
+ return AVERROR_INVALIDDATA;
}
/* extra slice info */
MBINCR_VLC_BITS, 2);
if (code < 0) {
av_log(s->avctx, AV_LOG_ERROR, "first mb_incr damaged\n");
- return -1;
+ return AVERROR_INVALIDDATA;
}
if (code >= 33) {
if (code == 33)
if (s->mb_x >= (unsigned) s->mb_width) {
av_log(s->avctx, AV_LOG_ERROR, "initial skip overflow\n");
- return -1;
+ return AVERROR_INVALIDDATA;
}
if (avctx->hwaccel && avctx->hwaccel->decode_slice) {
if ((CONFIG_MPEG1_XVMC_HWACCEL || CONFIG_MPEG2_XVMC_HWACCEL) && s->pack_pblocks)
ff_xvmc_init_block(s); // set s->block
- if (mpeg_decode_mb(s, s->block) < 0)
- return -1;
+ if ((ret = mpeg_decode_mb(s, s->block)) < 0)
+ return ret;
// Note motion_val is normally NULL unless we want to extract the MVs.
if (s->current_picture.motion_val[0] && !s->encoding) {
MBINCR_VLC_BITS, 2);
if (code < 0) {
av_log(s->avctx, AV_LOG_ERROR, "mb incr damaged\n");
- return -1;
+ return AVERROR_INVALIDDATA;
}
if (code >= 33) {
if (code == 33) {
if (s->pict_type == AV_PICTURE_TYPE_I) {
av_log(s->avctx, AV_LOG_ERROR,
"skipped MB in I frame at %d %d\n", s->mb_x, s->mb_y);
- return -1;
+ return AVERROR_INVALIDDATA;
}
/* skip mb */
if (s->aspect_ratio_info == 0) {
av_log(avctx, AV_LOG_ERROR, "aspect ratio has forbidden 0 value\n");
if (avctx->err_recognition & (AV_EF_BITSTREAM | AV_EF_COMPLIANT))
- return -1;
+ return AVERROR_INVALIDDATA;
}
s->frame_rate_index = get_bits(&s->gb, 4);
- if (s->frame_rate_index == 0 || s->frame_rate_index > 13)
- return -1;
+ if (s->frame_rate_index == 0 || s->frame_rate_index > 13) {
+ av_log(avctx, AV_LOG_WARNING, "frame_rate_index %d is invalid\n", s->frame_rate_index);
+ s->frame_rate_index = 1;
+ }
s->bit_rate = get_bits(&s->gb, 18) * 400;
- if (get_bits1(&s->gb) == 0) /* marker */
- return -1;
+ if (get_bits1(&s->gb) == 0) { /* marker */
+ av_log(avctx, AV_LOG_ERROR, "Marker in sequence header missing\n");
+ return AVERROR_INVALIDDATA;
+ }
s->width = width;
s->height = height;
if (show_bits(&s->gb, 23) != 0) {
av_log(s->avctx, AV_LOG_ERROR, "sequence header damaged\n");
- return -1;
+ return AVERROR_INVALIDDATA;
}
/* We set MPEG-2 parameters so that it emulates MPEG-1. */
s->low_delay = 1;
if (s->avctx->debug & FF_DEBUG_PICT_INFO)
- av_log(s->avctx, AV_LOG_DEBUG, "vbv buffer: %d, bitrate:%d\n",
- s->avctx->rc_buffer_size, s->bit_rate);
+ av_log(s->avctx, AV_LOG_DEBUG, "vbv buffer: %d, bitrate:%d, aspect_ratio_info: %d \n",
+ s->avctx->rc_buffer_size, s->bit_rate, s->aspect_ratio_info);
return 0;
}
Mpeg1Context *s1 = avctx->priv_data;
MpegEncContext *s = &s1->mpeg_enc_ctx;
int i, v;
+ int ret;
/* start new MPEG-1 context decoding */
s->out_format = FMT_MPEG1;
setup_hwaccel_for_pixfmt(avctx);
ff_mpv_idct_init(s);
- if (ff_mpv_common_init(s) < 0)
- return -1;
+ if ((ret = ff_mpv_common_init(s)) < 0)
+ return ret;
s1->mpeg_enc_ctx_allocated = 1;
for (i = 0; i < 64; i++) {
if (mb_y >= s2->mb_height) {
av_log(s2->avctx, AV_LOG_ERROR,
"slice below image (%d >= %d)\n", mb_y, s2->mb_height);
- return -1;
+ return AVERROR_INVALIDDATA;
}
if (!s2->last_picture_ptr) {
if (s->first_slice) {
skip_frame = 0;
s->first_slice = 0;
- if (mpeg_field_start(s2, buf, buf_size) < 0)
- return -1;
+ if ((ret = mpeg_field_start(s2, buf, buf_size)) < 0)
+ return ret;
}
if (!s2->current_picture_ptr) {
av_log(avctx, AV_LOG_ERROR,
static inline void encode_dc(MpegEncContext *s, int diff, int component)
{
- if (((unsigned) (diff + 255)) >= 511) {
+ unsigned int diff_u = diff + 255;
+ if (diff_u >= 511) {
int index;
if (diff < 0) {
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);
- if (ret < 0)
+ if (ret < -1)
av_log(avctx, AV_LOG_WARNING, "Failed to parse extradata\n");
}
check_marker(gb, "before time_increment_resolution");
- s->avctx->time_base.den = get_bits(gb, 16);
- 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->avctx->framerate.num = get_bits(gb, 16);
+ if (!s->avctx->framerate.num) {
+ av_log(s->avctx, AV_LOG_ERROR, "framerate==0\n");
+ return AVERROR_INVALIDDATA;
}
- ctx->time_increment_bits = av_log2(s->avctx->time_base.den - 1) + 1;
+ ctx->time_increment_bits = av_log2(s->avctx->framerate.num - 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, ctx->time_increment_bits);
+ s->avctx->framerate.den = get_bits(gb, ctx->time_increment_bits);
else
- s->avctx->time_base.num = 1;
+ s->avctx->framerate.den = 1;
+
+ s->avctx->time_base = av_inv_q(av_mul_q(s->avctx->framerate, (AVRational){s->avctx->ticks_per_frame, 1}));
ctx->t_frame = 0;
"%d sprite_warping_points\n",
ctx->num_sprite_warping_points);
ctx->num_sprite_warping_points = 0;
- return -1;
+ return AVERROR_INVALIDDATA;
}
s->sprite_warping_accuracy = get_bits(gb, 2);
ctx->sprite_brightness_change = get_bits1(gb);
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->avctx->framerate.den, s->avctx->framerate.num,
ctx->time_increment_bits,
s->quant_precision,
s->progressive_sequence,
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 (s->avctx->framerate.num && 4*s->avctx->framerate.num < 1<<ctx->time_increment_bits) {
+ s->avctx->framerate.num = 1<<ctx->time_increment_bits;
+ s->avctx->time_base = av_inv_q(av_mul_q(s->avctx->framerate, (AVRational){s->avctx->ticks_per_frame, 1}));
}
}
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;
+ s->time = s->time_base * s->avctx->framerate.num + 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->framerate.num;
}
}
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->time = (s->last_time_base + time_incr) * s->avctx->framerate.num + 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 ||
}
}
- if (s->avctx->time_base.num)
- pts = ROUNDED_DIV(s->time, s->avctx->time_base.num);
+ if (s->avctx->framerate.den)
+ pts = ROUNDED_DIV(s->time, s->avctx->framerate.den);
else
pts = AV_NOPTS_VALUE;
if (s->avctx->debug&FF_DEBUG_PTS)
if (get_bits_left(gb) < 3) {
av_log(s->avctx, AV_LOG_ERROR, "Header truncated\n");
- return -1;
+ return AVERROR_INVALIDDATA;
}
ctx->intra_dc_threshold = ff_mpeg4_dc_threshold[get_bits(gb, 3)];
if (!s->progressive_sequence) {
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
+ return AVERROR_INVALIDDATA; // makes no sense to continue, as there is nothing left from the image then
}
if (s->pict_type != AV_PICTURE_TYPE_I) {
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
+ return AVERROR_INVALIDDATA; // makes no sense to continue, as there is nothing left from the image then
}
} else
s->f_code = 1;
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
+ return AVERROR_INVALIDDATA; // makes no sense to continue, as the MV decoding will break very quickly
}
} else
s->b_code = 1;
{
MpegEncContext *s = &ctx->m;
unsigned startcode, v;
+ int ret;
/* search next start code */
align_get_bits(gb);
}
if (startcode >= 0x120 && startcode <= 0x12F) {
- if (decode_vol_header(ctx, gb) < 0)
- return -1;
+ if ((ret = decode_vol_header(ctx, gb)) < 0)
+ return ret;
} else if (startcode == USER_DATA_STARTCODE) {
decode_user_data(ctx, gb);
} else if (startcode == GOP_STARTCODE) {
if (i > 4)
s->header_count = -2;
} else {
+ int header_threshold = avctx->codec_id != AV_CODEC_ID_NONE && avctx->codec_id != codec_id;
if((state&SAME_HEADER_MASK) != (s->header&SAME_HEADER_MASK) && s->header)
s->header_count= -3;
s->header= state;
s->header_count++;
s->frame_size = ret-4;
- if (s->header_count > 0 + (avctx->codec_id != AV_CODEC_ID_NONE && avctx->codec_id != codec_id)) {
+ if (s->header_count > header_threshold) {
avctx->sample_rate= sr;
avctx->channels = channels;
s1->duration = frame_size;
avctx->codec_id = codec_id;
if (s->no_bitrate || !avctx->bit_rate) {
s->no_bitrate = 1;
- avctx->bit_rate += (bit_rate - avctx->bit_rate) / s->header_count;
+ avctx->bit_rate += (bit_rate - avctx->bit_rate) / (s->header_count - header_threshold);
}
}
break;
.id = AV_CODEC_ID_MP1,
.priv_data_size = sizeof(MPADecodeContext),
.init = decode_init,
+ .close = decode_close,
.decode = decode_frame,
.capabilities = CODEC_CAP_DR1,
.flush = flush,
.priv_data_size = sizeof(MPADecodeContext),
.init = decode_init,
.decode = decode_frame,
+ .close = decode_close,
.capabilities = CODEC_CAP_DR1,
.flush = flush,
.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
.id = AV_CODEC_ID_MP3,
.priv_data_size = sizeof(MPADecodeContext),
.init = decode_init,
+ .close = decode_close,
.decode = decode_frame,
.capabilities = CODEC_CAP_DR1,
.flush = flush,
.id = AV_CODEC_ID_MP3ADU,
.priv_data_size = sizeof(MPADecodeContext),
.init = decode_init,
+ .close = decode_close,
.decode = decode_frame_adu,
.capabilities = CODEC_CAP_DR1,
.flush = flush,
int err_recognition;
AVCodecContext* avctx;
MPADSPContext mpadsp;
- AVFloatDSPContext fdsp;
+ AVFloatDSPContext *fdsp;
AVFrame *frame;
} MPADecodeContext;
}
}
+#if USE_FLOATS
+static av_cold int decode_close(AVCodecContext * avctx)
+{
+ MPADecodeContext *s = avctx->priv_data;
+ av_freep(&s->fdsp);
+
+ return 0;
+}
+#endif
+
static av_cold int decode_init(AVCodecContext * avctx)
{
static int initialized_tables = 0;
s->avctx = avctx;
- avpriv_float_dsp_init(&s->fdsp, avctx->flags & CODEC_FLAG_BITEXACT);
+ s->fdsp = avpriv_float_dsp_alloc(avctx->flags & CODEC_FLAG_BITEXACT);
+ if (!s->fdsp)
+ return AVERROR(ENOMEM);
+
ff_mpadsp_init(&s->mpadsp);
if (avctx->request_sample_fmt == OUT_FMT &&
/* NOTE: the 1/sqrt(2) normalization factor is included in the
global gain */
#if USE_FLOATS
- s->fdsp.butterflies_float(g0->sb_hybrid, g1->sb_hybrid, 576);
+ s->fdsp->butterflies_float(g0->sb_hybrid, g1->sb_hybrid, 576);
#else
tab0 = g0->sb_hybrid;
tab1 = g1->sb_hybrid;
int i;
for (i = 0; i < s->frames; i++)
- av_free(s->mp3decctx[i]);
+ av_freep(&s->mp3decctx[i]);
return 0;
}
bitrate = bitrate / 1000;
s->nb_channels = channels;
avctx->frame_size = MPA_FRAME_SIZE;
- avctx->delay = 512 - 32 + 1;
+ avctx->initial_padding = 512 - 32 + 1;
/* encoding freq */
s->lsf = 0;
encode_frame(s, bit_alloc, padding);
if (frame->pts != AV_NOPTS_VALUE)
- avpkt->pts = frame->pts - ff_samples_to_time_base(avctx, avctx->delay);
+ avpkt->pts = frame->pts - ff_samples_to_time_base(avctx, avctx->initial_padding);
avpkt->size = put_bits_count(&s->pb) / 8;
*got_packet_ptr = 1;
// FIXME can parameters change on I-frames?
// in that case dst may need a reinit
if (!s->context_initialized) {
+ int err;
memcpy(s, s1, sizeof(MpegEncContext));
s->avctx = dst;
// s->picture_range_start += MAX_PICTURE_COUNT;
// s->picture_range_end += MAX_PICTURE_COUNT;
ff_mpv_idct_init(s);
- if((ret = ff_mpv_common_init(s)) < 0){
+ if((err = ff_mpv_common_init(s)) < 0){
memset(s, 0, sizeof(MpegEncContext));
s->avctx = dst;
- return ret;
+ return err;
}
}
}
#ifndef AVCODEC_MPEGVIDEO_H
#define AVCODEC_MPEGVIDEO_H
+#include <float.h>
+
#include "avcodec.h"
#include "blockdsp.h"
#include "error_resilience.h"
int mpv_flags; ///< flags set by private options
int quantizer_noise_shaping;
+ /**
+ * ratecontrol qmin qmax limiting method
+ * 0-> clipping, 1-> use a nice continuous function to limit qscale within qmin/qmax.
+ */
+ float rc_qsquish;
+ float rc_qmod_amp;
+ int rc_qmod_freq;
+ float rc_initial_cplx;
+ float rc_buffer_aggressivity;
+ float border_masking;
+ int lmin, lmax;
+
+ char *rc_eq;
+
/* temp buffers for rate control */
float *cplx_tab, *bits_tab;
#define FF_MPV_FLAG_NAQ 0x0010
#define FF_MPV_FLAG_MV0 0x0020
+#ifndef FF_MPV_OFFSET
#define FF_MPV_OFFSET(x) offsetof(MpegEncContext, x)
+#endif
#define FF_MPV_OPT_FLAGS (AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM)
#define FF_MPV_COMMON_OPTS \
{ "mpv_flags", "Flags common for all mpegvideo-based encoders.", FF_MPV_OFFSET(mpv_flags), AV_OPT_TYPE_FLAGS, { .i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS, "mpv_flags" },\
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 },\
{ "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 },
+ FF_MPV_OFFSET(error_rate), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, FF_MPV_OPT_FLAGS },\
+{"qsquish", "how to keep quantizer between qmin and qmax (0 = clip, 1 = use differentiable function)", \
+ FF_MPV_OFFSET(rc_qsquish), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, 0, 99, FF_MPV_OPT_FLAGS}, \
+{"rc_qmod_amp", "experimental quantizer modulation", FF_MPV_OFFSET(rc_qmod_amp), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, -FLT_MAX, FLT_MAX, FF_MPV_OPT_FLAGS}, \
+{"rc_qmod_freq", "experimental quantizer modulation", FF_MPV_OFFSET(rc_qmod_freq), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS}, \
+{"rc_eq", "Set rate control equation. When computing the expression, besides the standard functions " \
+ "defined in the section 'Expression Evaluation', the following functions are available: " \
+ "bits2qp(bits), qp2bits(qp). Also the following constants are available: iTex pTex tex mv " \
+ "fCode iCount mcVar var isI isP isB avgQP qComp avgIITex avgPITex avgPPTex avgBPTex avgTex.", \
+ FF_MPV_OFFSET(rc_eq), AV_OPT_TYPE_STRING, .flags = FF_MPV_OPT_FLAGS }, \
+{"rc_init_cplx", "initial complexity for 1-pass encoding", FF_MPV_OFFSET(rc_initial_cplx), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, -FLT_MAX, FLT_MAX, FF_MPV_OPT_FLAGS}, \
+{"rc_buf_aggressivity", "currently useless", FF_MPV_OFFSET(rc_buffer_aggressivity), AV_OPT_TYPE_FLOAT, {.dbl = 1.0 }, -FLT_MAX, FLT_MAX, FF_MPV_OPT_FLAGS}, \
+{"border_mask", "increase the quantizer for macroblocks close to borders", FF_MPV_OFFSET(border_masking), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, -FLT_MAX, FLT_MAX, FF_MPV_OPT_FLAGS}, \
+{"lmin", "minimum Lagrange factor (VBR)", FF_MPV_OFFSET(lmin), AV_OPT_TYPE_INT, {.i64 = 2*FF_QP2LAMBDA }, 0, INT_MAX, FF_MPV_OPT_FLAGS }, \
+{"lmax", "maximum Lagrange factor (VBR)", FF_MPV_OFFSET(lmax), AV_OPT_TYPE_INT, {.i64 = 31*FF_QP2LAMBDA }, 0, INT_MAX, FF_MPV_OPT_FLAGS }, \
extern const AVOption ff_mpv_generic_options[];
void ff_mpeg1_encode_picture_header(MpegEncContext *s, int picture_number);
void ff_mpeg1_encode_mb(MpegEncContext *s,
- int16_t block[6][64],
+ int16_t block[8][64],
int motion_x, int motion_y);
void ff_mpeg1_encode_init(MpegEncContext *s);
void ff_mpeg1_encode_slice_header(MpegEncContext *s);
fdsp->fdct == ff_jpeg_fdct_islow_10) {
for (i = 0; i < 64; i++) {
const int j = s->idsp.idct_permutation[i];
+ int64_t den = (int64_t) qscale * quant_matrix[j];
/* 16 <= qscale * quant_matrix[i] <= 7905
* Assume x = ff_aanscales[i] * qscale * quant_matrix[i]
* 19952 <= x <= 249205026
* (1 << 36) / 19952 >= (1 << 36) / (x) >= (1 << 36) / 249205026
* 3444240 >= (1 << 36) / (x) >= 275 */
- qmat[qscale][i] = (int)((UINT64_C(1) << QMAT_SHIFT) /
- (qscale * quant_matrix[j]));
+ qmat[qscale][i] = (int)((UINT64_C(1) << QMAT_SHIFT) / den);
}
} else if (fdsp->fdct == ff_fdct_ifast) {
for (i = 0; i < 64; i++) {
const int j = s->idsp.idct_permutation[i];
+ int64_t den = ff_aanscales[i] * (int64_t) qscale * quant_matrix[j];
/* 16 <= qscale * quant_matrix[i] <= 7905
* Assume x = ff_aanscales[i] * qscale * quant_matrix[i]
* 19952 <= x <= 249205026
* (1 << 36) / 19952 >= (1 << 36) / (x) >= (1 << 36) / 249205026
* 3444240 >= (1 << 36) / (x) >= 275 */
- qmat[qscale][i] = (int)((UINT64_C(1) << (QMAT_SHIFT + 14)) /
- (ff_aanscales[i] * (int64_t)qscale * quant_matrix[j]));
+ qmat[qscale][i] = (int)((UINT64_C(1) << (QMAT_SHIFT + 14)) / den);
}
} else {
for (i = 0; i < 64; i++) {
const int j = s->idsp.idct_permutation[i];
+ int64_t den = (int64_t) qscale * quant_matrix[j];
/* We can safely suppose that 16 <= quant_matrix[i] <= 255
* Assume x = qscale * quant_matrix[i]
* So 16 <= x <= 7905
* so (1 << 19) / 16 >= (1 << 19) / (x) >= (1 << 19) / 7905
* so 32768 >= (1 << 19) / (x) >= 67 */
- qmat[qscale][i] = (int)((UINT64_C(1) << QMAT_SHIFT) /
- (qscale * quant_matrix[j]));
+ qmat[qscale][i] = (int)((UINT64_C(1) << QMAT_SHIFT) / den);
//qmat [qscale][i] = (1 << QMAT_SHIFT_MMX) /
// (qscale * quant_matrix[i]);
- qmat16[qscale][0][i] = (1 << QMAT_SHIFT_MMX) /
- (qscale * quant_matrix[j]);
+ qmat16[qscale][0][i] = (1 << QMAT_SHIFT_MMX) / den;
if (qmat16[qscale][0][i] == 0 ||
qmat16[qscale][0][i] == 128 * 256)
/* Fixed QSCALE */
s->fixed_qscale = !!(avctx->flags & CODEC_FLAG_QSCALE);
+#if FF_API_MPV_OPT
+ FF_DISABLE_DEPRECATION_WARNINGS
+ if (avctx->border_masking != 0.0)
+ s->border_masking = avctx->border_masking;
+ FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+
s->adaptive_quant = (s->avctx->lumi_masking ||
s->avctx->dark_masking ||
s->avctx->temporal_cplx_masking ||
s->avctx->spatial_cplx_masking ||
s->avctx->p_masking ||
- s->avctx->border_masking ||
+ s->border_masking ||
(s->mpv_flags & FF_MPV_FLAG_QP_RD)) &&
!s->fixed_qscale;
return -1;
}
- i = (INT_MAX / 2 + 128) >> 8;
- if (avctx->mb_threshold >= i) {
- av_log(avctx, AV_LOG_ERROR, "mb_threshold too large, max is %d\n",
- i - 1);
- return -1;
- }
-
if (avctx->b_frame_strategy && (avctx->flags & CODEC_FLAG_PASS2)) {
av_log(avctx, AV_LOG_INFO,
"notice: b_frame_strategy only affects the first pass\n");
FF_ENABLE_DEPRECATION_WARNINGS
#endif
+#if FF_API_MPV_OPT
+ FF_DISABLE_DEPRECATION_WARNINGS
+ if (avctx->rc_qsquish != 0.0)
+ s->rc_qsquish = avctx->rc_qsquish;
+ if (avctx->rc_qmod_amp != 0.0)
+ s->rc_qmod_amp = avctx->rc_qmod_amp;
+ if (avctx->rc_qmod_freq)
+ s->rc_qmod_freq = avctx->rc_qmod_freq;
+ if (avctx->rc_buffer_aggressivity != 1.0)
+ s->rc_buffer_aggressivity = avctx->rc_buffer_aggressivity;
+ if (avctx->rc_initial_cplx != 0.0)
+ s->rc_initial_cplx = avctx->rc_initial_cplx;
+ if (avctx->lmin)
+ s->lmin = avctx->lmin;
+ if (avctx->lmax)
+ s->lmax = avctx->lmax;
+
+ if (avctx->rc_eq) {
+ av_freep(&s->rc_eq);
+ s->rc_eq = av_strdup(avctx->rc_eq);
+ if (!s->rc_eq)
+ return AVERROR(ENOMEM);
+ }
+ 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 (pic_arg) {
- if (!pic_arg->buf[0])
- direct = 0;
- if (pic_arg->linesize[0] != s->linesize)
- direct = 0;
- if (pic_arg->linesize[1] != s->uvlinesize)
- direct = 0;
- if (pic_arg->linesize[2] != s->uvlinesize)
+ if (!pic_arg->buf[0] ||
+ pic_arg->linesize[0] != s->linesize ||
+ pic_arg->linesize[1] != s->uvlinesize ||
+ pic_arg->linesize[2] != s->uvlinesize)
direct = 0;
if ((s->width & 15) || (s->height & 15))
direct = 0;
av_dlog(s->avctx, "%d %d %"PTRDIFF_SPECIFIER" %"PTRDIFF_SPECIFIER"\n", pic_arg->linesize[0],
pic_arg->linesize[1], s->linesize, s->uvlinesize);
- if (direct) {
- i = ff_find_unused_picture(s, 1);
- if (i < 0)
- return i;
+ i = ff_find_unused_picture(s, direct);
+ if (i < 0)
+ return i;
- pic = &s->picture[i];
- pic->reference = 3;
+ pic = &s->picture[i];
+ pic->reference = 3;
+ if (direct) {
if ((ret = av_frame_ref(pic->f, pic_arg)) < 0)
return ret;
if (ff_alloc_picture(s, pic, 1) < 0) {
return -1;
}
} else {
- i = ff_find_unused_picture(s, 0);
- if (i < 0)
- return i;
-
- pic = &s->picture[i];
- pic->reference = 3;
-
if (ff_alloc_picture(s, pic, 0) < 0) {
return -1;
}
/* output? */
if (s->new_picture.f->data[0]) {
- if ((ret = ff_alloc_packet2(avctx, pkt, s->mb_width*s->mb_height*(MAX_MB_BYTES+100)+10000)) < 0)
+ int growing_buffer = context_count == 1 && !pkt->data && !s->data_partitioning;
+ int pkt_size = growing_buffer ? FFMAX(s->mb_width*s->mb_height*64+10000, avctx->internal->byte_buffer_size) - FF_INPUT_BUFFER_PADDING_SIZE
+ :
+ s->mb_width*s->mb_height*(MAX_MB_BYTES+100)+10000;
+ if ((ret = ff_alloc_packet2(avctx, pkt, pkt_size)) < 0)
return ret;
if (s->mb_info) {
s->mb_info_ptr = av_packet_new_side_data(pkt,
if (ret < 0)
return ret;
vbv_retry:
- if (encode_picture(s, s->picture_number) < 0)
+ ret = encode_picture(s, s->picture_number);
+ if (growing_buffer) {
+ av_assert0(s->pb.buf == avctx->internal->byte_buffer);
+ pkt->data = s->pb.buf;
+ pkt->size = avctx->internal->byte_buffer_size;
+ }
+ if (ret < 0)
return -1;
avctx->header_bits = s->header_bits;
if (avctx->rc_buffer_size) {
RateControlContext *rcc = &s->rc_context;
- int max_size = rcc->buffer_index * avctx->rc_max_available_vbv_use;
+ int max_size = FFMAX(rcc->buffer_index * avctx->rc_max_available_vbv_use, rcc->buffer_index - 500);
if (put_bits_count(&s->pb) > max_size &&
- s->lambda < s->avctx->lmax) {
+ s->lambda < s->lmax) {
s->next_lambda = FFMAX(s->lambda + 1, s->lambda *
(s->qscale + 1) / s->qscale);
if (s->adaptive_quant) {
PutBitContext *pb = &s->thread_context[i]->pb;
init_put_bits(pb, pb->buf, pb->buf_end - pb->buf);
}
+ av_log(s->avctx, AV_LOG_VERBOSE, "reencoding frame due to VBV\n");
goto vbv_retry;
}
int dmin= INT_MAX;
int dir;
+ if ( s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb)>>3) < MAX_MB_BYTES
+ && s->slice_context_count == 1
+ && s->pb.buf == s->avctx->internal->byte_buffer) {
+ int new_size = s->avctx->internal->byte_buffer_size
+ + s->avctx->internal->byte_buffer_size/4
+ + s->mb_width*MAX_MB_BYTES;
+ int lastgob_pos = s->ptr_lastgob - s->pb.buf;
+ int vbv_pos = s->vbv_delay_ptr - s->pb.buf;
+
+ uint8_t *new_buffer = NULL;
+ int new_buffer_size = 0;
+
+ av_fast_padded_malloc(&new_buffer, &new_buffer_size, new_size);
+ if (new_buffer) {
+ memcpy(new_buffer, s->avctx->internal->byte_buffer, s->avctx->internal->byte_buffer_size);
+ av_free(s->avctx->internal->byte_buffer);
+ s->avctx->internal->byte_buffer = new_buffer;
+ s->avctx->internal->byte_buffer_size = new_buffer_size;
+ rebase_put_bits(&s->pb, new_buffer, new_buffer_size);
+ s->ptr_lastgob = s->pb.buf + lastgob_pos;
+ s->vbv_delay_ptr = s->pb.buf + vbv_pos;
+ }
+ }
if(s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb)>>3) < MAX_MB_BYTES){
av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n");
return -1;
did_set_size=1;
}
frame_rate_index = buf[3] & 0xf;
- pc->frame_rate.den = avctx->time_base.den = ff_mpeg12_frame_rate_tab[frame_rate_index].num;
- pc->frame_rate.num = avctx->time_base.num = ff_mpeg12_frame_rate_tab[frame_rate_index].den;
+ pc->frame_rate = avctx->framerate = ff_mpeg12_frame_rate_tab[frame_rate_index];
bit_rate = (buf[4]<<10) | (buf[5]<<2) | (buf[6]>>6);
avctx->codec_id = AV_CODEC_ID_MPEG1VIDEO;
+ avctx->ticks_per_frame = 1;
}
break;
case EXT_START_CODE:
bit_rate = (bit_rate&0x3FFFF) | (bit_rate_ext << 18);
if(did_set_size)
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->framerate.num = pc->frame_rate.num * (frame_rate_ext_n + 1);
+ avctx->framerate.den = pc->frame_rate.den * (frame_rate_ext_d + 1);
avctx->codec_id = AV_CODEC_ID_MPEG2VIDEO;
+ avctx->ticks_per_frame = 2;
}
break;
case 0x8: /* picture coding extension */
((avctx->codec_id == AV_CODEC_ID_MPEG1VIDEO && bit_rate != 0x3FFFF) || vbv_delay != 0xFFFF)) {
avctx->bit_rate = 400*bit_rate;
}
+#if FF_API_AVCTX_TIMEBASE
+ if (avctx->framerate.num)
+ avctx->time_base = av_inv_q(av_mul_q(avctx->framerate, (AVRational){avctx->ticks_per_frame, 1}));
+#endif
}
static int mpegvideo_parse(AVCodecParserContext *s,
function should be negligible for uncorrupted streams */
mpegvideo_extract_headers(s, avctx, buf, buf_size);
av_dlog(NULL, "pict_type=%d frame_rate=%0.3f repeat_pict=%d\n",
- s->pict_type, (double)avctx->time_base.den / avctx->time_base.num, s->repeat_pict);
+ s->pict_type, av_q2d(avctx->framerate), s->repeat_pict);
*poutbuf = buf;
*poutbuf_size = buf_size;
}
}
- av_bprintf(buf, "\r\n");
return 0;
}
static int mpl2_decode_frame(AVCodecContext *avctx, void *data,
int *got_sub_ptr, AVPacket *avpkt)
{
+ int ret = 0;
AVBPrint buf;
AVSubtitle *sub = data;
const char *ptr = avpkt->data;
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 && !mpl2_event_to_ass(&buf, ptr)) {
- if (!av_bprint_is_complete(&buf)) {
- av_bprint_finalize(&buf, NULL);
- return AVERROR(ENOMEM);
- }
- ff_ass_add_rect(sub, buf.str, ts_start, ts_duration, 0);
- }
- *got_sub_ptr = sub->num_rects > 0;
+ if (ptr && avpkt->size > 0 && *ptr && !mpl2_event_to_ass(&buf, ptr))
+ ret = ff_ass_add_rect_bprint(sub, &buf, ts_start, ts_duration);
av_bprint_finalize(&buf, NULL);
+ if (ret < 0)
+ return ret;
+ *got_sub_ptr = sub->num_rects > 0;
return avpkt->size;
}
return AVERROR(ENOMEM);
ret = ff_mss12_decode_init(&c->ctx, 0, &c->sc, NULL);
+ if (ret < 0)
+ av_frame_free(&c->pic);
avctx->pix_fmt = AV_PIX_FMT_PAL8;
AVLFG random_state;
GetBitContext gb;
float scale_bias;
- AVFloatDSPContext fdsp;
+ AVFloatDSPContext *fdsp;
FFTContext imdct_ctx;
DECLARE_ALIGNED(32, float, imdct_buf)[2][NELLY_BUF_LEN];
float *imdct_out;
(NELLY_BUF_LEN - NELLY_FILL_LEN) * sizeof(float));
s->imdct_ctx.imdct_half(&s->imdct_ctx, s->imdct_out, aptr);
- s->fdsp.vector_fmul_window(aptr, s->imdct_prev + NELLY_BUF_LEN / 2,
+ s->fdsp->vector_fmul_window(aptr, s->imdct_prev + NELLY_BUF_LEN / 2,
s->imdct_out, ff_sine_128,
NELLY_BUF_LEN / 2);
FFSWAP(float *, s->imdct_out, s->imdct_prev);
av_lfg_init(&s->random_state, 0);
ff_mdct_init(&s->imdct_ctx, 8, 1, 1.0);
- avpriv_float_dsp_init(&s->fdsp, avctx->flags & CODEC_FLAG_BITEXACT);
+ s->fdsp = avpriv_float_dsp_alloc(avctx->flags & CODEC_FLAG_BITEXACT);
+ if (!s->fdsp)
+ return AVERROR(ENOMEM);
s->scale_bias = 1.0/(32768*8);
avctx->sample_fmt = AV_SAMPLE_FMT_FLT;
NellyMoserDecodeContext *s = avctx->priv_data;
ff_mdct_end(&s->imdct_ctx);
+ av_freep(&s->fdsp);
return 0;
}
typedef struct NellyMoserEncodeContext {
AVCodecContext *avctx;
int last_frame;
- AVFloatDSPContext fdsp;
+ AVFloatDSPContext *fdsp;
FFTContext mdct_ctx;
AudioFrameQueue afq;
DECLARE_ALIGNED(32, float, mdct_out)[NELLY_SAMPLES];
uint8_t (*path)[OPT_SIZE];
} NellyMoserEncodeContext;
-static float pow_table[POW_TABLE_SIZE]; ///< -pow(2, -i / 2048.0 - 3.0);
+static float pow_table[POW_TABLE_SIZE]; ///< pow(2, -i / 2048.0 - 3.0);
static const uint8_t sf_lut[96] = {
0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4,
float *in1 = s->buf + NELLY_BUF_LEN;
float *in2 = s->buf + 2 * NELLY_BUF_LEN;
- s->fdsp.vector_fmul (s->in_buff, in0, ff_sine_128, NELLY_BUF_LEN);
- s->fdsp.vector_fmul_reverse(s->in_buff + NELLY_BUF_LEN, in1, ff_sine_128, NELLY_BUF_LEN);
+ s->fdsp->vector_fmul (s->in_buff, in0, ff_sine_128, NELLY_BUF_LEN);
+ s->fdsp->vector_fmul_reverse(s->in_buff + NELLY_BUF_LEN, in1, ff_sine_128, NELLY_BUF_LEN);
s->mdct_ctx.mdct_calc(&s->mdct_ctx, s->mdct_out, s->in_buff);
- s->fdsp.vector_fmul (s->in_buff, in1, ff_sine_128, NELLY_BUF_LEN);
- s->fdsp.vector_fmul_reverse(s->in_buff + NELLY_BUF_LEN, in2, ff_sine_128, NELLY_BUF_LEN);
+ s->fdsp->vector_fmul (s->in_buff, in1, ff_sine_128, NELLY_BUF_LEN);
+ s->fdsp->vector_fmul_reverse(s->in_buff + NELLY_BUF_LEN, in2, ff_sine_128, NELLY_BUF_LEN);
s->mdct_ctx.mdct_calc(&s->mdct_ctx, s->mdct_out + NELLY_BUF_LEN, s->in_buff);
}
ff_mdct_end(&s->mdct_ctx);
if (s->avctx->trellis) {
- av_free(s->opt);
- av_free(s->path);
+ av_freep(&s->opt);
+ av_freep(&s->path);
}
ff_af_queue_close(&s->afq);
+ av_freep(&s->fdsp);
return 0;
}
}
avctx->frame_size = NELLY_SAMPLES;
- avctx->delay = NELLY_BUF_LEN;
+ avctx->initial_padding = NELLY_BUF_LEN;
ff_af_queue_init(avctx, &s->afq);
s->avctx = avctx;
if ((ret = ff_mdct_init(&s->mdct_ctx, 8, 0, 32768.0)) < 0)
goto error;
- avpriv_float_dsp_init(&s->fdsp, avctx->flags & CODEC_FLAG_BITEXACT);
+ s->fdsp = avpriv_float_dsp_alloc(avctx->flags & CODEC_FLAG_BITEXACT);
+ if (!s->fdsp) {
+ ret = AVERROR(ENOMEM);
+ goto error;
+ }
/* Generate overlap window */
ff_init_ff_sine_windows(7);
for (i = 0; i < POW_TABLE_SIZE; i++)
- pow_table[i] = -pow(2, -i / 2048.0 - 3.0 + POW_TABLE_OFFSET);
+ pow_table[i] = pow(2, -i / 2048.0 - 3.0 + POW_TABLE_OFFSET);
if (s->avctx->trellis) {
s->opt = av_malloc(NELLY_BANDS * OPT_SIZE * sizeof(float ));
typedef struct On2AVCContext {
AVCodecContext *avctx;
- AVFloatDSPContext fdsp;
+ AVFloatDSPContext *fdsp;
FFTContext mdct, mdct_half, mdct_small;
FFTContext fft128, fft256, fft512, fft1024;
void (*wtf)(struct On2AVCContext *ctx, float *out, float *in, int size);
}
memcpy(out, saved, 448 * sizeof(float));
- c->fdsp.vector_fmul_window(wout, saved + 448, buf, c->short_win, 64);
+ c->fdsp->vector_fmul_window(wout, saved + 448, buf, c->short_win, 64);
memcpy(wout + 128, buf + 64, 448 * sizeof(float));
memcpy(saved, buf + 512, 448 * sizeof(float));
memcpy(saved + 448, buf + 7*128 + 64, 64 * sizeof(float));
c->prev_window_type == WINDOW_TYPE_LONG_STOP) &&
(c->window_type == WINDOW_TYPE_LONG ||
c->window_type == WINDOW_TYPE_LONG_START)) {
- c->fdsp.vector_fmul_window(out, saved, buf, c->long_win, 512);
+ c->fdsp->vector_fmul_window(out, saved, buf, c->long_win, 512);
} else {
float *wout = out + 448;
memcpy(out, saved, 448 * sizeof(float));
if (c->window_type == WINDOW_TYPE_8SHORT) {
- c->fdsp.vector_fmul_window(wout + 0*128, saved + 448, buf + 0*128, c->short_win, 64);
- c->fdsp.vector_fmul_window(wout + 1*128, buf + 0*128 + 64, buf + 1*128, c->short_win, 64);
- c->fdsp.vector_fmul_window(wout + 2*128, buf + 1*128 + 64, buf + 2*128, c->short_win, 64);
- c->fdsp.vector_fmul_window(wout + 3*128, buf + 2*128 + 64, buf + 3*128, c->short_win, 64);
- c->fdsp.vector_fmul_window(temp, buf + 3*128 + 64, buf + 4*128, c->short_win, 64);
+ c->fdsp->vector_fmul_window(wout + 0*128, saved + 448, buf + 0*128, c->short_win, 64);
+ c->fdsp->vector_fmul_window(wout + 1*128, buf + 0*128 + 64, buf + 1*128, c->short_win, 64);
+ c->fdsp->vector_fmul_window(wout + 2*128, buf + 1*128 + 64, buf + 2*128, c->short_win, 64);
+ c->fdsp->vector_fmul_window(wout + 3*128, buf + 2*128 + 64, buf + 3*128, c->short_win, 64);
+ c->fdsp->vector_fmul_window(temp, buf + 3*128 + 64, buf + 4*128, c->short_win, 64);
memcpy(wout + 4*128, temp, 64 * sizeof(float));
} else {
- c->fdsp.vector_fmul_window(wout, saved + 448, buf, c->short_win, 64);
+ c->fdsp->vector_fmul_window(wout, saved + 448, buf, c->short_win, 64);
memcpy(wout + 128, buf + 64, 448 * sizeof(float));
}
}
switch (c->window_type) {
case WINDOW_TYPE_8SHORT:
memcpy(saved, temp + 64, 64 * sizeof(float));
- c->fdsp.vector_fmul_window(saved + 64, buf + 4*128 + 64, buf + 5*128, c->short_win, 64);
- c->fdsp.vector_fmul_window(saved + 192, buf + 5*128 + 64, buf + 6*128, c->short_win, 64);
- c->fdsp.vector_fmul_window(saved + 320, buf + 6*128 + 64, buf + 7*128, c->short_win, 64);
+ c->fdsp->vector_fmul_window(saved + 64, buf + 4*128 + 64, buf + 5*128, c->short_win, 64);
+ c->fdsp->vector_fmul_window(saved + 192, buf + 5*128 + 64, buf + 6*128, c->short_win, 64);
+ c->fdsp->vector_fmul_window(saved + 320, buf + 6*128 + 64, buf + 7*128, c->short_win, 64);
memcpy(saved + 448, buf + 7*128 + 64, 64 * sizeof(float));
break;
case WINDOW_TYPE_LONG_START:
ff_fft_init(&c->fft256, 7, 0);
ff_fft_init(&c->fft512, 8, 1);
ff_fft_init(&c->fft1024, 9, 1);
- avpriv_float_dsp_init(&c->fdsp, avctx->flags & CODEC_FLAG_BITEXACT);
+ c->fdsp = avpriv_float_dsp_alloc(avctx->flags & CODEC_FLAG_BITEXACT);
+ if (!c->fdsp)
+ return AVERROR(ENOMEM);
if (init_vlc(&c->scale_diff, 9, ON2AVC_SCALE_DIFFS,
ff_on2avc_scale_diff_bits, 1, 1,
ff_on2avc_scale_diff_codes, 4, 4, 0)) {
- av_log(avctx, AV_LOG_ERROR, "Cannot init VLC\n");
- return AVERROR(ENOMEM);
+ goto vlc_fail;
}
for (i = 1; i < 9; i++) {
int idx = i - 1;
ff_on2avc_quad_cb_bits[idx], 1, 1,
ff_on2avc_quad_cb_codes[idx], 4, 4,
ff_on2avc_quad_cb_syms[idx], 2, 2, 0)) {
- av_log(avctx, AV_LOG_ERROR, "Cannot init VLC\n");
- on2avc_free_vlcs(c);
- return AVERROR(ENOMEM);
+ goto vlc_fail;
}
}
for (i = 9; i < 16; i++) {
ff_on2avc_pair_cb_bits[idx], 1, 1,
ff_on2avc_pair_cb_codes[idx], 2, 2,
ff_on2avc_pair_cb_syms[idx], 2, 2, 0)) {
- av_log(avctx, AV_LOG_ERROR, "Cannot init VLC\n");
- on2avc_free_vlcs(c);
- return AVERROR(ENOMEM);
+ goto vlc_fail;
}
}
return 0;
+vlc_fail:
+ av_log(avctx, AV_LOG_ERROR, "Cannot init VLC\n");
+ on2avc_free_vlcs(c);
+ av_freep(&c->fdsp);
+ return AVERROR(ENOMEM);
}
static av_cold int on2avc_decode_close(AVCodecContext *avctx)
ff_fft_end(&c->fft512);
ff_fft_end(&c->fft1024);
+ av_freep(&c->fdsp);
+
on2avc_free_vlcs(c);
return 0;
#include "avcodec.h"
#include "internal.h"
#include "libavutil/avassert.h"
+#include "libavutil/internal.h"
#include "libavutil/mem.h"
#include "libavutil/opt.h"
#include <float.h> /* FLT_MIN, FLT_MAX */
s->av_class = &av_codec_context_class;
s->codec_type = codec ? codec->type : AVMEDIA_TYPE_UNKNOWN;
- if (codec)
+ if (codec) {
+ s->codec = codec;
s->codec_id = codec->id;
+ }
if(s->codec_type == AVMEDIA_TYPE_AUDIO)
flags= AV_OPT_FLAG_AUDIO_PARAM;
av_opt_set_defaults2(s, flags, flags);
s->time_base = (AVRational){0,1};
+ s->framerate = (AVRational){ 0, 1 };
+ s->pkt_timebase = (AVRational){ 0, 1 };
s->get_buffer2 = avcodec_default_get_buffer2;
s->get_format = avcodec_default_get_format;
s->execute = avcodec_default_execute;
s->sample_aspect_ratio = (AVRational){0,1};
s->pix_fmt = AV_PIX_FMT_NONE;
s->sample_fmt = AV_SAMPLE_FMT_NONE;
- s->timecode_frame_start = -1;
s->reordered_opaque = AV_NOPTS_VALUE;
if(codec && codec->priv_data_size){
av_freep(&avctx->extradata);
av_freep(&avctx->subtitle_header);
+ av_freep(&avctx->intra_matrix);
+ av_freep(&avctx->inter_matrix);
+ av_freep(&avctx->rc_override);
av_freep(pavctx);
}
av_opt_free(dest);
memcpy(dest, src, sizeof(*dest));
+ av_opt_copy(dest, src);
dest->priv_data = orig_priv_data;
dest->internal = NULL;
/* reallocate values that should be allocated separately */
- dest->rc_eq = NULL;
dest->extradata = NULL;
dest->intra_matrix = NULL;
dest->inter_matrix = NULL;
dest->rc_override = NULL;
dest->subtitle_header = NULL;
- if (src->rc_eq) {
- dest->rc_eq = av_strdup(src->rc_eq);
- if (!dest->rc_eq)
- return AVERROR(ENOMEM);
- }
#define alloc_and_copy_or_fail(obj, size, pad) \
if (src->obj && size > 0) { \
av_freep(&dest->intra_matrix);
av_freep(&dest->inter_matrix);
av_freep(&dest->extradata);
+#if FF_API_MPV_OPT
+ FF_DISABLE_DEPRECATION_WARNINGS
av_freep(&dest->rc_eq);
+ FF_ENABLE_DEPRECATION_WARNINGS
+#endif
return AVERROR(ENOMEM);
}
{"chunks", "Frame data might be split into multiple chunks", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG2_CHUNKS }, INT_MIN, INT_MAX, V|D, "flags2"},
{"showall", "Show all frames before the first keyframe", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG2_SHOW_ALL }, INT_MIN, INT_MAX, V|D, "flags2"},
{"export_mvs", "export motion vectors through frame side data", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG2_EXPORT_MVS}, INT_MIN, INT_MAX, V|D, "flags2"},
+{"skip_manual", "do not skip samples and export skip information as frame side data", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG2_SKIP_MANUAL}, INT_MIN, INT_MAX, V|D, "flags2"},
{"me_method", "set motion estimation method", OFFSET(me_method), AV_OPT_TYPE_INT, {.i64 = ME_EPZS }, INT_MIN, INT_MAX, V|E, "me_method"},
{"zero", "zero motion estimation (fastest)", 0, AV_OPT_TYPE_CONST, {.i64 = ME_ZERO }, INT_MIN, INT_MAX, V|E, "me_method" },
{"full", "full motion estimation (slowest)", 0, AV_OPT_TYPE_CONST, {.i64 = ME_FULL }, INT_MIN, INT_MAX, V|E, "me_method" },
{"extradata_size", NULL, OFFSET(extradata_size), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
{"time_base", NULL, OFFSET(time_base), AV_OPT_TYPE_RATIONAL, {.dbl = 0}, INT_MIN, INT_MAX},
{"g", "set the group of picture (GOP) size", OFFSET(gop_size), AV_OPT_TYPE_INT, {.i64 = 12 }, INT_MIN, INT_MAX, V|E},
-{"ar", "set audio sampling rate (in Hz)", OFFSET(sample_rate), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, A|D|E},
-{"ac", "set number of audio channels", OFFSET(channels), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, A|D|E},
+{"ar", "set audio sampling rate (in Hz)", OFFSET(sample_rate), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX, A|D|E},
+{"ac", "set number of audio channels", OFFSET(channels), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX, A|D|E},
{"cutoff", "set cutoff bandwidth", OFFSET(cutoff), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, A|E},
{"frame_size", NULL, OFFSET(frame_size), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, A|E},
{"frame_number", NULL, OFFSET(frame_number), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
{"has_b_frames", NULL, OFFSET(has_b_frames), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
{"block_align", NULL, OFFSET(block_align), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
{"mpeg_quant", "use MPEG quantizers instead of H.263", OFFSET(mpeg_quant), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
-{"qsquish", "how to keep quantizer between qmin and qmax (0 = clip, 1 = use differentiable function)", OFFSET(rc_qsquish), AV_OPT_TYPE_FLOAT, {.dbl = DEFAULT }, 0, 99, V|E},
-{"rc_qmod_amp", "experimental quantizer modulation", OFFSET(rc_qmod_amp), AV_OPT_TYPE_FLOAT, {.dbl = DEFAULT }, -FLT_MAX, FLT_MAX, V|E},
-{"rc_qmod_freq", "experimental quantizer modulation", OFFSET(rc_qmod_freq), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
+#if FF_API_MPV_OPT
+{"qsquish", "deprecated, use encoder private options instead", OFFSET(rc_qsquish), AV_OPT_TYPE_FLOAT, {.dbl = DEFAULT }, 0, 99, V|E},
+{"rc_qmod_amp", "deprecated, use encoder private options instead", OFFSET(rc_qmod_amp), AV_OPT_TYPE_FLOAT, {.dbl = DEFAULT }, -FLT_MAX, FLT_MAX, V|E},
+{"rc_qmod_freq", "deprecated, use encoder private options instead", OFFSET(rc_qmod_freq), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
+#endif
{"rc_override_count", NULL, OFFSET(rc_override_count), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
-{"rc_eq", "Set rate control equation. When computing the expression, besides the standard functions "
- "defined in the section 'Expression Evaluation', the following functions are available: "
- "bits2qp(bits), qp2bits(qp). Also the following constants are available: iTex pTex tex mv "
- "fCode iCount mcVar var isI isP isB avgQP qComp avgIITex avgPITex avgPPTex avgBPTex avgTex.",
- OFFSET(rc_eq), AV_OPT_TYPE_STRING, {.str = NULL}, CHAR_MIN, CHAR_MAX, V|E},
+#if FF_API_MPV_OPT
+{"rc_eq", "deprecated, use encoder private options instead", OFFSET(rc_eq), AV_OPT_TYPE_STRING, {.str = NULL}, CHAR_MIN, CHAR_MAX, V|E},
+#endif
{"maxrate", "maximum bitrate (in bits/s). Used for VBV together with bufsize.", OFFSET(rc_max_rate), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX, V|A|E},
{"minrate", "minimum bitrate (in bits/s). Most useful in setting up a CBR encode. It is of little use otherwise.",
OFFSET(rc_min_rate), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|A|E},
{"bufsize", "set ratecontrol buffer size (in bits)", OFFSET(rc_buffer_size), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, A|V|E},
-{"rc_buf_aggressivity", "currently useless", OFFSET(rc_buffer_aggressivity), AV_OPT_TYPE_FLOAT, {.dbl = 1.0 }, -FLT_MAX, FLT_MAX, V|E},
+#if FF_API_MPV_OPT
+{"rc_buf_aggressivity", "deprecated, use encoder private options instead", OFFSET(rc_buffer_aggressivity), AV_OPT_TYPE_FLOAT, {.dbl = 1.0 }, -FLT_MAX, FLT_MAX, V|E},
+#endif
{"i_qfactor", "QP factor between P- and I-frames", OFFSET(i_quant_factor), AV_OPT_TYPE_FLOAT, {.dbl = -0.8 }, -FLT_MAX, FLT_MAX, V|E},
{"i_qoffset", "QP offset between P- and I-frames", OFFSET(i_quant_offset), AV_OPT_TYPE_FLOAT, {.dbl = 0.0 }, -FLT_MAX, FLT_MAX, V|E},
-{"rc_init_cplx", "initial complexity for 1-pass encoding", OFFSET(rc_initial_cplx), AV_OPT_TYPE_FLOAT, {.dbl = DEFAULT }, -FLT_MAX, FLT_MAX, V|E},
+#if FF_API_MPV_OPT
+{"rc_init_cplx", "deprecated, use encoder private options instead", OFFSET(rc_initial_cplx), AV_OPT_TYPE_FLOAT, {.dbl = DEFAULT }, -FLT_MAX, FLT_MAX, V|E},
+#endif
{"dct", "DCT algorithm", OFFSET(dct_algo), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX, V|E, "dct"},
{"auto", "autoselect a good one (default)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_AUTO }, INT_MIN, INT_MAX, V|E, "dct"},
{"fastint", "fast integer", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_FASTINT }, INT_MIN, INT_MAX, V|E, "dct"},
{"rd", "use best rate distortion", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MB_DECISION_RD }, INT_MIN, INT_MAX, V|E, "mbd"},
{"stream_codec_tag", NULL, OFFSET(stream_codec_tag), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
{"sc_threshold", "scene change threshold", OFFSET(scenechange_threshold), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
-{"lmin", "minimum Lagrange factor (VBR)", OFFSET(lmin), AV_OPT_TYPE_INT, {.i64 = 2*FF_QP2LAMBDA }, 0, INT_MAX, V|E},
-{"lmax", "maximum Lagrange factor (VBR)", OFFSET(lmax), AV_OPT_TYPE_INT, {.i64 = 31*FF_QP2LAMBDA }, 0, INT_MAX, V|E},
+#if FF_API_MPV_OPT
+{"lmin", "deprecated, use encoder private options instead", OFFSET(lmin), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, V|E},
+{"lmax", "deprecated, use encoder private options instead", OFFSET(lmax), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, V|E},
+#endif
{"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"},
#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"},
+#if FF_API_MPV_OPT
{"me_threshold", "motion estimation threshold", OFFSET(me_threshold), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
{"mb_threshold", "macroblock threshold", OFFSET(mb_threshold), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
+#endif
{"dc", "intra_dc_precision", OFFSET(intra_dc_precision), AV_OPT_TYPE_INT, {.i64 = 0 }, -8, 16, V|E},
{"nssew", "nsse weight", OFFSET(nsse_weight), AV_OPT_TYPE_INT, {.i64 = 8 }, INT_MIN, INT_MAX, V|E},
{"skip_top", "number of macroblock rows at the top which are skipped", OFFSET(skip_top), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|D},
{"skip_factor", "frame skip factor", OFFSET(frame_skip_factor), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
{"skip_exp", "frame skip exponent", OFFSET(frame_skip_exp), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
{"skipcmp", "frame skip compare function", OFFSET(frame_skip_cmp), AV_OPT_TYPE_INT, {.i64 = FF_CMP_DCTMAX }, INT_MIN, INT_MAX, V|E, "cmp_func"},
-{"border_mask", "increase the quantizer for macroblocks close to borders", OFFSET(border_masking), AV_OPT_TYPE_FLOAT, {.dbl = DEFAULT }, -FLT_MAX, FLT_MAX, V|E},
+#if FF_API_MPV_OPT
+{"border_mask", "deprecated, use encoder private options instead", OFFSET(border_masking), AV_OPT_TYPE_FLOAT, {.dbl = DEFAULT }, -FLT_MAX, FLT_MAX, V|E},
+#endif
{"mblmin", "minimum macroblock Lagrange factor (VBR)", OFFSET(mb_lmin), AV_OPT_TYPE_INT, {.i64 = FF_QP2LAMBDA * 2 }, 1, FF_LAMBDA_MAX, V|E},
{"mblmax", "maximum macroblock Lagrange factor (VBR)", OFFSET(mb_lmax), AV_OPT_TYPE_INT, {.i64 = FF_QP2LAMBDA * 31 }, 1, FF_LAMBDA_MAX, V|E},
{"mepc", "motion estimation bitrate penalty compensation (1.0 = 256)", OFFSET(me_penalty_compensation), AV_OPT_TYPE_INT, {.i64 = 256 }, INT_MIN, INT_MAX, V|E},
{"compression_level", NULL, OFFSET(compression_level), AV_OPT_TYPE_INT, {.i64 = FF_COMPRESSION_DEFAULT }, INT_MIN, INT_MAX, V|A|E},
{"min_prediction_order", NULL, OFFSET(min_prediction_order), AV_OPT_TYPE_INT, {.i64 = -1 }, INT_MIN, INT_MAX, A|E},
{"max_prediction_order", NULL, OFFSET(max_prediction_order), AV_OPT_TYPE_INT, {.i64 = -1 }, INT_MIN, INT_MAX, A|E},
-{"timecode_frame_start", "GOP timecode frame start number, in non-drop-frame format", OFFSET(timecode_frame_start), AV_OPT_TYPE_INT64, {.i64 = 0 }, 0, INT64_MAX, V|E},
+{"timecode_frame_start", "GOP timecode frame start number, in non-drop-frame format", OFFSET(timecode_frame_start), AV_OPT_TYPE_INT64, {.i64 = -1 }, -1, INT64_MAX, V|E},
#if FF_API_REQUEST_CHANNELS
{"request_channels", "set desired number of audio channels", OFFSET(request_channels), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX, A|D},
#endif
{"smpte240m", "SMPTE 240 M", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_SMPTE240M }, INT_MIN, INT_MAX, V|E|D, "color_primaries_type"},
{"film", "Film", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_FILM }, INT_MIN, INT_MAX, V|E|D, "color_primaries_type"},
{"bt2020", "BT.2020", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_BT2020 }, INT_MIN, INT_MAX, V|E|D, "color_primaries_type"},
-{"color_trc", "color transfert characteristic", OFFSET(color_trc), AV_OPT_TYPE_INT, {.i64 = AVCOL_TRC_UNSPECIFIED }, 1, AVCOL_TRC_NB-1, V|E|D, "color_trc_type"},
+{"color_trc", "color transfer characteristics", OFFSET(color_trc), AV_OPT_TYPE_INT, {.i64 = AVCOL_TRC_UNSPECIFIED }, 1, AVCOL_TRC_NB-1, V|E|D, "color_trc_type"},
{"bt709", "BT.709", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_BT709 }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
{"unspecified", "Unspecified", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_UNSPECIFIED }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
-{"gamma22", "Gamma 2.2", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_GAMMA22 }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
-{"gamma28", "Gamma 2.8", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_GAMMA28 }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
+{"gamma22", "BT.470 M", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_GAMMA22 }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
+{"gamma28", "BT.470 BG", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_GAMMA28 }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
{"smpte170m", "SMPTE 170 M", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_SMPTE170M }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
{"smpte240m", "SMPTE 240 M", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_SMPTE240M }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
{"linear", "Linear", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_LINEAR }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
-{"log", "SMPTE 240 M", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_LOG }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
-{"log_sqrt", "SMPTE 240 M", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_LOG_SQRT }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
-{"iec61966_2_4", "SMPTE 240 M", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_IEC61966_2_4 }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
+{"log", "Log", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_LOG }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
+{"log_sqrt", "Log square root", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_LOG_SQRT }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
+{"iec61966_2_4", "IEC 61966-2-4", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_IEC61966_2_4 }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
{"bt1361", "BT.1361", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_BT1361_ECG }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
-{"iec61966_2_1", "SMPTE 240 M", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_IEC61966_2_1 }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
+{"iec61966_2_1", "IEC 61966-2-1", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_IEC61966_2_1 }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
{"bt2020_10bit", "BT.2020 - 10 bit", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_BT2020_10 }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
{"bt2020_12bit", "BT.2020 - 12 bit", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_BT2020_12 }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
-{"colorspace", "colorspace", OFFSET(colorspace), AV_OPT_TYPE_INT, {.i64 = AVCOL_SPC_UNSPECIFIED }, 1, AVCOL_SPC_NB-1, V|E|D, "colorspace_type"},
+{"colorspace", "color space", OFFSET(colorspace), AV_OPT_TYPE_INT, {.i64 = AVCOL_SPC_UNSPECIFIED }, 0, AVCOL_SPC_NB-1, V|E|D, "colorspace_type"},
{"rgb", "RGB", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_RGB }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"},
{"bt709", "BT.709", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_BT709 }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"},
{"unspecified", "Unspecified", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_UNSPECIFIED }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"},
-{"fcc", "FourCC", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_FCC }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"},
+{"fcc", "FCC", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_FCC }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"},
{"bt470bg", "BT.470 BG", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_BT470BG }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"},
{"smpte170m", "SMPTE 170 M", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_SMPTE170M }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"},
{"smpte240m", "SMPTE 240 M", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_SMPTE240M }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"},
{"unspecified", "Unspecified", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_UNSPECIFIED }, INT_MIN, INT_MAX, V|E|D, "color_range_type"},
{"mpeg", "MPEG (219*2^(n-8))", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_MPEG }, INT_MIN, INT_MAX, V|E|D, "color_range_type"},
{"jpeg", "JPEG (2^n-1)", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_JPEG }, INT_MIN, INT_MAX, V|E|D, "color_range_type"},
-{"chroma_sample_location", NULL, OFFSET(chroma_sample_location), AV_OPT_TYPE_INT, {.i64 = AVCHROMA_LOC_UNSPECIFIED }, 0, AVCHROMA_LOC_NB-1, V|E|D},
+{"chroma_sample_location", "chroma sample location", OFFSET(chroma_sample_location), AV_OPT_TYPE_INT, {.i64 = AVCHROMA_LOC_UNSPECIFIED }, 0, AVCHROMA_LOC_NB-1, V|E|D, "chroma_sample_location_type"},
+{"unspecified", "Unspecified", 0, AV_OPT_TYPE_CONST, {.i64 = AVCHROMA_LOC_UNSPECIFIED }, INT_MIN, INT_MAX, V|E|D, "chroma_sample_location_type"},
+{"left", "Left", 0, AV_OPT_TYPE_CONST, {.i64 = AVCHROMA_LOC_LEFT }, INT_MIN, INT_MAX, V|E|D, "chroma_sample_location_type"},
+{"center", "Center", 0, AV_OPT_TYPE_CONST, {.i64 = AVCHROMA_LOC_CENTER }, INT_MIN, INT_MAX, V|E|D, "chroma_sample_location_type"},
+{"topleft", "Top-left", 0, AV_OPT_TYPE_CONST, {.i64 = AVCHROMA_LOC_TOPLEFT }, INT_MIN, INT_MAX, V|E|D, "chroma_sample_location_type"},
+{"top", "Top", 0, AV_OPT_TYPE_CONST, {.i64 = AVCHROMA_LOC_TOP }, INT_MIN, INT_MAX, V|E|D, "chroma_sample_location_type"},
+{"bottomleft", "Bottom-left", 0, AV_OPT_TYPE_CONST, {.i64 = AVCHROMA_LOC_BOTTOMLEFT }, INT_MIN, INT_MAX, V|E|D, "chroma_sample_location_type"},
+{"bottom", "Bottom", 0, AV_OPT_TYPE_CONST, {.i64 = AVCHROMA_LOC_BOTTOM }, INT_MIN, INT_MAX, V|E|D, "chroma_sample_location_type"},
{"log_level_offset", "set the log level offset", OFFSET(log_level_offset), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX },
{"slices", "number of slices, used in parallelized encoding", OFFSET(slices), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, V|E},
{"thread_type", "select multithreading type", OFFSET(thread_type), AV_OPT_TYPE_FLAGS, {.i64 = FF_THREAD_SLICE|FF_THREAD_FRAME }, 0, INT_MAX, V|A|E|D, "thread_type"},
{"bb", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AV_FIELD_BB }, 0, 0, V|D|E, "field_order" },
{"tb", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AV_FIELD_TB }, 0, 0, V|D|E, "field_order" },
{"bt", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AV_FIELD_BT }, 0, 0, V|D|E, "field_order" },
+{"dump_separator", "set information dump field separator", OFFSET(dump_separator), AV_OPT_TYPE_STRING, {.str = NULL}, CHAR_MIN, CHAR_MAX, A|V|S|D|E},
+{"codec_whitelist", "List of decoders that are allowed to be used", OFFSET(codec_whitelist), AV_OPT_TYPE_STRING, { .str = NULL }, CHAR_MIN, CHAR_MAX, A|V|S|D },
+{"pixel_format", "set pixel format", OFFSET(pix_fmt), AV_OPT_TYPE_PIXEL_FMT, {.i64=AV_PIX_FMT_NONE}, -1, INT_MAX, 0 },
+{"video_size", "set video size", OFFSET(width), AV_OPT_TYPE_IMAGE_SIZE, {.str=NULL}, 0, INT_MAX, 0 },
{NULL},
};
OpusContext *s)
{
static const uint8_t default_channel_map[2] = { 0, 1 };
- uint8_t default_extradata[19] = {
- 'O', 'p', 'u', 's', 'H', 'e', 'a', 'd',
- 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- };
int (*channel_reorder)(int, int) = channel_reorder_unknown;
"Multichannel configuration without extradata.\n");
return AVERROR(EINVAL);
}
- default_extradata[9] = (avctx->channels == 1) ? 1 : 2;
- extradata = default_extradata;
- extradata_size = sizeof(default_extradata);
+ extradata = opus_default_extradata;
+ extradata_size = sizeof(opus_default_extradata);
} else {
extradata = avctx->extradata;
extradata_size = avctx->extradata_size;
avctx->delay = AV_RL16(extradata + 10);
- channels = extradata[9];
+ channels = avctx->extradata ? extradata[9] : (avctx->channels == 1) ? 1 : 2;
if (!channels) {
av_log(avctx, AV_LOG_ERROR, "Zero channel count specified in the extadata\n");
return AVERROR_INVALIDDATA;
#define ROUND_MUL16(a,b) ((MUL16(a, b) + 16384) >> 15)
#define opus_ilog(i) (av_log2(i) + !!(i))
+#define OPUS_TS_HEADER 0x7FE0 // 0x3ff (11 bits)
+#define OPUS_TS_MASK 0xFFE0 // top 11 bits
+
+static const uint8_t opus_default_extradata[30] = {
+ 'O', 'p', 'u', 's', 'H', 'e', 'a', 'd',
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
enum OpusMode {
OPUS_MODE_SILK,
OPUS_MODE_HYBRID,
int nb_streams;
int nb_stereo_streams;
- AVFloatDSPContext fdsp;
+ AVFloatDSPContext *fdsp;
int16_t gain_i;
float gain;
// constant values that do not change during context lifetime
AVCodecContext *avctx;
CeltIMDCTContext *imdct[4];
- AVFloatDSPContext dsp;
+ AVFloatDSPContext *dsp;
int output_channels;
// values that have inter-frame effect and must be reset on flush
/* stereo -> mono downmix */
if (s->output_channels < s->coded_channels) {
- s->dsp.vector_fmac_scalar(s->coeffs[0], s->coeffs[1], 1.0, FFALIGN(frame_size, 16));
+ s->dsp->vector_fmac_scalar(s->coeffs[0], s->coeffs[1], 1.0, FFALIGN(frame_size, 16));
imdct_scale = 0.5;
} else if (s->output_channels > s->coded_channels)
memcpy(s->coeffs[1], s->coeffs[0], frame_size * sizeof(float));
imdct->imdct_half(imdct, dst + CELT_OVERLAP / 2, s->coeffs[i] + j,
s->blocks, imdct_scale);
- s->dsp.vector_fmul_window(dst, dst, dst + CELT_OVERLAP / 2,
+ s->dsp->vector_fmul_window(dst, dst, dst + CELT_OVERLAP / 2,
celt_window, CELT_OVERLAP / 2);
}
for (i = 0; i < FF_ARRAY_ELEMS(s->imdct); i++)
ff_celt_imdct_uninit(&s->imdct[i]);
+ av_freep(&s->dsp);
av_freep(ps);
}
goto fail;
}
- avpriv_float_dsp_init(&s->dsp, avctx->flags & CODEC_FLAG_BITEXACT);
+ s->dsp = avpriv_float_dsp_alloc(avctx->flags & CODEC_FLAG_BITEXACT);
+ if (!s->dsp) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
ff_celt_flush(s);
#include "avcodec.h"
#include "opus.h"
+#include "parser.h"
+#include "bytestream.h"
typedef struct OpusParseContext {
OpusContext ctx;
OpusPacket pkt;
int extradata_parsed;
+ ParseContext pc;
+ int ts_framing;
} OpusParseContext;
-static int opus_parse(AVCodecParserContext *ctx, AVCodecContext *avctx,
- const uint8_t **poutbuf, int *poutbuf_size,
- const uint8_t *buf, int buf_size)
+static const uint8_t *parse_opus_ts_header(const uint8_t *start, int *payload_len, int buf_len)
+{
+ const uint8_t *buf = start + 1;
+ int start_trim_flag, end_trim_flag, control_extension_flag, control_extension_length;
+ uint8_t flags;
+
+ GetByteContext gb;
+ bytestream2_init(&gb, buf, buf_len);
+
+ flags = bytestream2_get_byte(&gb);
+ start_trim_flag = (flags >> 4) & 1;
+ end_trim_flag = (flags >> 3) & 1;
+ control_extension_flag = (flags >> 2) & 1;
+
+ *payload_len = 0;
+ while (bytestream2_peek_byte(&gb) == 0xff)
+ *payload_len += bytestream2_get_byte(&gb);
+
+ *payload_len += bytestream2_get_byte(&gb);
+
+ if (start_trim_flag)
+ bytestream2_skip(&gb, 2);
+ if (end_trim_flag)
+ bytestream2_skip(&gb, 2);
+ if (control_extension_flag) {
+ control_extension_length = bytestream2_get_byte(&gb);
+ bytestream2_skip(&gb, control_extension_length);
+ }
+
+ return buf + bytestream2_tell(&gb);
+}
+
+/**
+ * Find the end of the current frame in the bitstream.
+ * @return the position of the first byte of the next frame, or -1
+ */
+static int opus_find_frame_end(AVCodecParserContext *ctx, AVCodecContext *avctx,
+ const uint8_t *buf, int buf_size, int *header_len)
{
OpusParseContext *s = ctx->priv_data;
- int ret;
+ ParseContext *pc = &s->pc;
+ int ret, start_found, i = 0, payload_len = 0;
+ const uint8_t *payload;
+ uint32_t state;
+ uint16_t hdr;
+ *header_len = 0;
if (!buf_size)
return 0;
+ start_found = pc->frame_start_found;
+ state = pc->state;
+ payload = buf;
+
+ /* Check if we're using Opus in MPEG-TS framing */
+ if (!s->ts_framing && buf_size > 2) {
+ hdr = AV_RB16(buf);
+ if ((hdr & OPUS_TS_MASK) == OPUS_TS_HEADER)
+ s->ts_framing = 1;
+ }
+
+ if (s->ts_framing && !start_found) {
+ for (i = 0; i < buf_size-2; i++) {
+ state = (state << 8) | payload[i];
+ if ((state & OPUS_TS_MASK) == OPUS_TS_HEADER) {
+ payload = parse_opus_ts_header(payload, &payload_len, buf_size - i);
+ *header_len = payload - buf;
+ start_found = 1;
+ break;
+ }
+ }
+ }
+
+ if (!s->ts_framing)
+ payload_len = buf_size;
+
if (avctx->extradata && !s->extradata_parsed) {
ret = ff_opus_parse_extradata(avctx, &s->ctx);
if (ret < 0) {
av_log(avctx, AV_LOG_ERROR, "Error parsing Ogg extradata.\n");
- goto fail;
+ return AVERROR_INVALIDDATA;
}
av_freep(&s->ctx.channel_maps);
s->extradata_parsed = 1;
}
- ret = ff_opus_parse_packet(&s->pkt, buf, buf_size, s->ctx.nb_streams > 1);
- if (ret < 0) {
- av_log(avctx, AV_LOG_ERROR, "Error parsing Opus packet header.\n");
- goto fail;
+ if (payload_len <= buf_size && (!s->ts_framing || start_found)) {
+ ret = ff_opus_parse_packet(&s->pkt, payload, payload_len, s->ctx.nb_streams > 1);
+ if (ret < 0) {
+ av_log(avctx, AV_LOG_ERROR, "Error parsing Opus packet header.\n");
+ pc->frame_start_found = 0;
+ return AVERROR_INVALIDDATA;
+ }
+
+ ctx->duration = s->pkt.frame_count * s->pkt.frame_duration;
}
- ctx->duration = s->pkt.frame_count * s->pkt.frame_duration;
+ if (s->ts_framing) {
+ if (start_found) {
+ if (payload_len + *header_len <= buf_size) {
+ pc->frame_start_found = 0;
+ pc->state = -1;
+ return payload_len + *header_len;
+ }
+ }
+
+ pc->frame_start_found = start_found;
+ pc->state = state;
+ return END_NOT_FOUND;
+ }
-fail:
- *poutbuf = buf;
- *poutbuf_size = buf_size;
return buf_size;
}
+static int opus_parse(AVCodecParserContext *ctx, AVCodecContext *avctx,
+ const uint8_t **poutbuf, int *poutbuf_size,
+ const uint8_t *buf, int buf_size)
+{
+ OpusParseContext *s = ctx->priv_data;
+ ParseContext *pc = &s->pc;
+ int next, header_len;
+
+ next = opus_find_frame_end(ctx, avctx, buf, buf_size, &header_len);
+
+ if (s->ts_framing && next != AVERROR_INVALIDDATA &&
+ ff_combine_frame(pc, next, &buf, &buf_size) < 0) {
+ *poutbuf = NULL;
+ *poutbuf_size = 0;
+ return buf_size;
+ }
+
+ if (next == AVERROR_INVALIDDATA){
+ *poutbuf = NULL;
+ *poutbuf_size = 0;
+ return buf_size;
+ }
+
+ *poutbuf = buf + header_len;
+ *poutbuf_size = buf_size - header_len;
+ return next;
+}
+
AVCodecParser ff_opus_parser = {
.codec_ids = { AV_CODEC_ID_OPUS },
.priv_data_size = sizeof(OpusParseContext),
.parser_parse = opus_parse,
+ .parser_close = ff_parse_close
};
av_log(avctx, AV_LOG_ERROR, "Error parsing the packet header.\n");
return ret;
}
+ if (coded_samples != s->packet.frame_count * s->packet.frame_duration) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Mismatching coded sample count in substream %d.\n", i);
+ return AVERROR_INVALIDDATA;
+ }
+
s->silk_samplerate = get_silk_samplerate(s->packet.config);
}
}
if (c->gain_i) {
- c->fdsp.vector_fmul_scalar((float*)frame->extended_data[i],
+ c->fdsp->vector_fmul_scalar((float*)frame->extended_data[i],
(float*)frame->extended_data[i],
c->gain, FFALIGN(decoded_samples, 8));
}
c->nb_streams = 0;
av_freep(&c->channel_maps);
+ av_freep(&c->fdsp);
return 0;
}
avctx->sample_fmt = AV_SAMPLE_FMT_FLTP;
avctx->sample_rate = 48000;
- avpriv_float_dsp_init(&c->fdsp, 0);
+ c->fdsp = avpriv_float_dsp_alloc(0);
+ if (!c->fdsp)
+ return AVERROR(ENOMEM);
/* find out the channel configuration */
ret = ff_opus_parse_extradata(avctx, c);
s->redundancy_output[j] = s->redundancy_buf[j];
}
- s->fdsp = &c->fdsp;
+ s->fdsp = c->fdsp;
s->swr =swr_alloc();
if (!s->swr)
if (s) {
if (s->parser->parser_close)
s->parser->parser_close(s);
- av_free(s->priv_data);
+ av_freep(&s->priv_data);
av_free(s);
}
}
GetByteContext gb;
int i;
uint8_t t;
- int samples;
bytestream2_init(&gb, src, blocks * s->block_size);
switch (avctx->bits_per_coded_sample) {
- case 16:
+ case 16: {
#if HAVE_BIGENDIAN
bytestream2_get_buffer(&gb, dst16, blocks * s->block_size);
dst16 += blocks * s->block_size / 2;
#else
- samples = blocks * avctx->channels;
+ int samples = blocks * avctx->channels;
do {
*dst16++ = bytestream2_get_be16u(&gb);
} while (--samples);
#endif
return dst16;
+ }
case 20:
if (avctx->channels == 1) {
do {
#include "avcodec.h"
#include "bytestream.h"
#include "internal.h"
+#include "apng.h"
#include "png.h"
#include "pngdsp.h"
#include "thread.h"
AVCodecContext *avctx;
GetByteContext gb;
+ ThreadFrame previous_picture;
ThreadFrame last_picture;
ThreadFrame picture;
int state;
int width, height;
+ int cur_w, cur_h;
+ int x_offset, y_offset;
+ uint8_t dispose_op, blend_op;
int bit_depth;
int color_type;
int compression_type;
int bits_per_pixel;
int bpp;
+ int frame_id;
uint8_t *image_buf;
int image_linesize;
uint32_t palette[256];
/* would write off the end of the array if we let it process
* the last pixel with bpp=3 */
int w = bpp == 4 ? size : size - 3;
- dsp->add_paeth_prediction(dst + i, src + i, last + i, w - i, bpp);
- i = w;
+ if (w > i) {
+ dsp->add_paeth_prediction(dst + i, src + i, last + i, w - i, bpp);
+ i = w;
+ }
}
ff_add_png_paeth_prediction(dst + i, src + i, last + i, size - i, bpp);
break;
int got_line;
if (!s->interlace_type) {
- ptr = s->image_buf + s->image_linesize * s->y;
- if (s->y == 0)
- last_row = s->last_row;
- else
- last_row = ptr - s->image_linesize;
-
- png_filter_row(&s->dsp, ptr, s->crow_buf[0], s->crow_buf + 1,
- last_row, s->row_size, s->bpp);
+ ptr = s->image_buf + s->image_linesize * (s->y + s->y_offset) + s->x_offset * s->bpp;
+ if (s->y == 0)
+ last_row = s->last_row;
+ else
+ last_row = ptr - s->image_linesize;
+
+ png_filter_row(&s->dsp, ptr, s->crow_buf[0], s->crow_buf + 1,
+ last_row, s->row_size, s->bpp);
/* loco lags by 1 row so that it doesn't interfere with top prediction */
if (s->filter_type == PNG_FILTER_TYPE_LOCO && s->y > 0) {
if (s->bit_depth == 16) {
}
}
s->y++;
- if (s->y == s->height) {
+ if (s->y == s->cur_h) {
s->state |= PNG_ALLIMAGE;
if (s->filter_type == PNG_FILTER_TYPE_LOCO) {
if (s->bit_depth == 16) {
} else {
got_line = 0;
for (;;) {
- ptr = s->image_buf + s->image_linesize * s->y;
+ ptr = s->image_buf + s->image_linesize * (s->y + s->y_offset) + s->x_offset * s->bpp;
if ((ff_png_pass_ymask[s->pass] << (s->y & 7)) & 0x80) {
/* if we already read one row, it is time to stop to
* wait for the next one */
got_line = 1;
}
if ((png_pass_dsp_ymask[s->pass] << (s->y & 7)) & 0x80) {
- png_put_interlaced_row(ptr, s->width, s->bits_per_pixel, s->pass,
+ png_put_interlaced_row(ptr, s->cur_w, s->bits_per_pixel, s->pass,
s->color_type, s->last_row);
}
s->y++;
- if (s->y == s->height) {
+ if (s->y == s->cur_h) {
memset(s->last_row, 0, s->row_size);
for (;;) {
if (s->pass == NB_PASSES - 1) {
s->y = 0;
s->pass_row_size = ff_png_pass_row_size(s->pass,
s->bits_per_pixel,
- s->width);
+ s->cur_w);
s->crow_size = s->pass_row_size + 1;
if (s->pass_row_size != 0)
break;
return 0;
}
-static int decode_frame(AVCodecContext *avctx,
- void *data, int *got_frame,
- AVPacket *avpkt)
+static int decode_ihdr_chunk(AVCodecContext *avctx, PNGDecContext *s,
+ uint32_t length)
{
- PNGDecContext *const s = avctx->priv_data;
- const uint8_t *buf = avpkt->data;
- int buf_size = avpkt->size;
- AVFrame *p;
- AVDictionary *metadata = NULL;
- uint32_t tag, length;
- int64_t sig;
- int ret;
+ if (length != 13)
+ return AVERROR_INVALIDDATA;
- ff_thread_release_buffer(avctx, &s->last_picture);
- FFSWAP(ThreadFrame, s->picture, s->last_picture);
- p = s->picture.f;
+ if (s->state & PNG_IDAT) {
+ av_log(avctx, AV_LOG_ERROR, "IHDR after IDAT\n");
+ return AVERROR_INVALIDDATA;
+ }
- bytestream2_init(&s->gb, buf, buf_size);
+ s->width = s->cur_w = bytestream2_get_be32(&s->gb);
+ s->height = s->cur_h = bytestream2_get_be32(&s->gb);
+ if (av_image_check_size(s->width, s->height, 0, avctx)) {
+ s->width = s->height = 0;
+ av_log(avctx, AV_LOG_ERROR, "Invalid image size\n");
+ return AVERROR_INVALIDDATA;
+ }
+ s->bit_depth = bytestream2_get_byte(&s->gb);
+ s->color_type = bytestream2_get_byte(&s->gb);
+ s->compression_type = bytestream2_get_byte(&s->gb);
+ s->filter_type = bytestream2_get_byte(&s->gb);
+ s->interlace_type = bytestream2_get_byte(&s->gb);
+ bytestream2_skip(&s->gb, 4); /* crc */
+ s->state |= PNG_IHDR;
+ if (avctx->debug & FF_DEBUG_PICT_INFO)
+ av_log(avctx, AV_LOG_DEBUG, "width=%d height=%d depth=%d color_type=%d "
+ "compression_type=%d filter_type=%d interlace_type=%d\n",
+ s->width, s->height, s->bit_depth, s->color_type,
+ s->compression_type, s->filter_type, s->interlace_type);
- /* check signature */
- sig = bytestream2_get_be64(&s->gb);
- if (sig != PNGSIG &&
- sig != MNGSIG) {
- av_log(avctx, AV_LOG_ERROR, "Missing png signature\n");
+ return 0;
+}
+
+static int decode_phys_chunk(AVCodecContext *avctx, PNGDecContext *s)
+{
+ if (s->state & PNG_IDAT) {
+ av_log(avctx, AV_LOG_ERROR, "pHYs after IDAT\n");
return AVERROR_INVALIDDATA;
}
+ avctx->sample_aspect_ratio.num = bytestream2_get_be32(&s->gb);
+ avctx->sample_aspect_ratio.den = bytestream2_get_be32(&s->gb);
+ if (avctx->sample_aspect_ratio.num < 0 || avctx->sample_aspect_ratio.den < 0)
+ avctx->sample_aspect_ratio = (AVRational){ 0, 1 };
+ bytestream2_skip(&s->gb, 1); /* unit specifier */
+ bytestream2_skip(&s->gb, 4); /* crc */
- s->y = s->state = 0;
+ return 0;
+}
- /* init the zlib */
- s->zstream.zalloc = ff_png_zalloc;
- s->zstream.zfree = ff_png_zfree;
- s->zstream.opaque = NULL;
- ret = inflateInit(&s->zstream);
- if (ret != Z_OK) {
- av_log(avctx, AV_LOG_ERROR, "inflateInit returned error %d\n", ret);
- return AVERROR_EXTERNAL;
+static int decode_idat_chunk(AVCodecContext *avctx, PNGDecContext *s,
+ uint32_t length, AVFrame *p)
+{
+ int ret;
+
+ if (!(s->state & PNG_IHDR)) {
+ av_log(avctx, AV_LOG_ERROR, "IDAT without IHDR\n");
+ return AVERROR_INVALIDDATA;
}
- for (;;) {
- if (bytestream2_get_bytes_left(&s->gb) <= 0) {
- av_log(avctx, AV_LOG_ERROR, "%d bytes left\n", bytestream2_get_bytes_left(&s->gb));
- if ( s->state & PNG_ALLIMAGE
- && avctx->strict_std_compliance <= FF_COMPLIANCE_NORMAL)
- goto exit_loop;
- goto fail;
+ if (!(s->state & PNG_IDAT)) {
+ /* init image info */
+ avctx->width = s->width;
+ avctx->height = s->height;
+
+ s->channels = ff_png_get_nb_channels(s->color_type);
+ s->bits_per_pixel = s->bit_depth * s->channels;
+ s->bpp = (s->bits_per_pixel + 7) >> 3;
+ s->row_size = (s->cur_w * s->bits_per_pixel + 7) >> 3;
+
+ if ((s->bit_depth == 2 || s->bit_depth == 4 || s->bit_depth == 8) &&
+ s->color_type == PNG_COLOR_TYPE_RGB) {
+ avctx->pix_fmt = AV_PIX_FMT_RGB24;
+ } else if ((s->bit_depth == 2 || s->bit_depth == 4 || s->bit_depth == 8) &&
+ s->color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
+ avctx->pix_fmt = AV_PIX_FMT_RGBA;
+ } else if ((s->bit_depth == 2 || s->bit_depth == 4 || s->bit_depth == 8) &&
+ s->color_type == PNG_COLOR_TYPE_GRAY) {
+ avctx->pix_fmt = AV_PIX_FMT_GRAY8;
+ } else if (s->bit_depth == 16 &&
+ s->color_type == PNG_COLOR_TYPE_GRAY) {
+ avctx->pix_fmt = AV_PIX_FMT_GRAY16BE;
+ } else if (s->bit_depth == 16 &&
+ s->color_type == PNG_COLOR_TYPE_RGB) {
+ avctx->pix_fmt = AV_PIX_FMT_RGB48BE;
+ } else if (s->bit_depth == 16 &&
+ s->color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
+ avctx->pix_fmt = AV_PIX_FMT_RGBA64BE;
+ } else if ((s->bits_per_pixel == 1 || s->bits_per_pixel == 2 || s->bits_per_pixel == 4 || s->bits_per_pixel == 8) &&
+ s->color_type == PNG_COLOR_TYPE_PALETTE) {
+ avctx->pix_fmt = AV_PIX_FMT_PAL8;
+ } else if (s->bit_depth == 1 && s->bits_per_pixel == 1) {
+ avctx->pix_fmt = AV_PIX_FMT_MONOBLACK;
+ } else if (s->bit_depth == 8 &&
+ s->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {
+ avctx->pix_fmt = AV_PIX_FMT_YA8;
+ } else if (s->bit_depth == 16 &&
+ s->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {
+ avctx->pix_fmt = AV_PIX_FMT_YA16BE;
+ } else {
+ av_log(avctx, AV_LOG_ERROR, "unsupported bit depth %d "
+ "and color type %d\n",
+ s->bit_depth, s->color_type);
+ return AVERROR_INVALIDDATA;
}
- length = bytestream2_get_be32(&s->gb);
- if (length > 0x7fffffff || length > bytestream2_get_bytes_left(&s->gb)) {
- av_log(avctx, AV_LOG_ERROR, "chunk too big\n");
- goto fail;
+ if ((ret = ff_thread_get_buffer(avctx, &s->picture, AV_GET_BUFFER_FLAG_REF)) < 0)
+ return ret;
+ ff_thread_finish_setup(avctx);
+
+ p->pict_type = AV_PICTURE_TYPE_I;
+ p->key_frame = 1;
+ p->interlaced_frame = !!s->interlace_type;
+
+ /* compute the compressed row size */
+ if (!s->interlace_type) {
+ s->crow_size = s->row_size + 1;
+ } else {
+ s->pass = 0;
+ s->pass_row_size = ff_png_pass_row_size(s->pass,
+ s->bits_per_pixel,
+ s->cur_w);
+ s->crow_size = s->pass_row_size + 1;
}
- tag = bytestream2_get_le32(&s->gb);
- if (avctx->debug & FF_DEBUG_STARTCODE)
- av_log(avctx, AV_LOG_DEBUG, "png: tag=%c%c%c%c length=%u\n",
- (tag & 0xff),
- ((tag >> 8) & 0xff),
- ((tag >> 16) & 0xff),
- ((tag >> 24) & 0xff), length);
- switch (tag) {
- case MKTAG('I', 'H', 'D', 'R'):
- if (length != 13)
- goto fail;
- s->width = bytestream2_get_be32(&s->gb);
- s->height = bytestream2_get_be32(&s->gb);
- if (av_image_check_size(s->width, s->height, 0, avctx)) {
- s->width = s->height = 0;
- av_log(avctx, AV_LOG_ERROR, "Invalid image size\n");
- goto fail;
- }
- s->bit_depth = bytestream2_get_byte(&s->gb);
- s->color_type = bytestream2_get_byte(&s->gb);
- s->compression_type = bytestream2_get_byte(&s->gb);
- s->filter_type = bytestream2_get_byte(&s->gb);
- s->interlace_type = bytestream2_get_byte(&s->gb);
- bytestream2_skip(&s->gb, 4); /* crc */
- s->state |= PNG_IHDR;
- if (avctx->debug & FF_DEBUG_PICT_INFO)
- av_log(avctx, AV_LOG_DEBUG, "width=%d height=%d depth=%d color_type=%d "
- "compression_type=%d filter_type=%d interlace_type=%d\n",
- s->width, s->height, s->bit_depth, s->color_type,
- s->compression_type, s->filter_type, s->interlace_type);
- break;
- case MKTAG('p', 'H', 'Y', 's'):
- if (s->state & PNG_IDAT) {
- av_log(avctx, AV_LOG_ERROR, "pHYs after IDAT\n");
- goto fail;
- }
- avctx->sample_aspect_ratio.num = bytestream2_get_be32(&s->gb);
- avctx->sample_aspect_ratio.den = bytestream2_get_be32(&s->gb);
- if (avctx->sample_aspect_ratio.num < 0 || avctx->sample_aspect_ratio.den < 0)
- avctx->sample_aspect_ratio = (AVRational){ 0, 1 };
- bytestream2_skip(&s->gb, 1); /* unit specifier */
- bytestream2_skip(&s->gb, 4); /* crc */
- break;
- case MKTAG('I', 'D', 'A', 'T'):
- if (!(s->state & PNG_IHDR)) {
- av_log(avctx, AV_LOG_ERROR, "IDAT without IHDR\n");
- goto fail;
- }
- if (!(s->state & PNG_IDAT)) {
- /* init image info */
- avctx->width = s->width;
- avctx->height = s->height;
-
- s->channels = ff_png_get_nb_channels(s->color_type);
- s->bits_per_pixel = s->bit_depth * s->channels;
- s->bpp = (s->bits_per_pixel + 7) >> 3;
- s->row_size = (avctx->width * s->bits_per_pixel + 7) >> 3;
-
- if ((s->bit_depth == 2 || s->bit_depth == 4 || s->bit_depth == 8) &&
- s->color_type == PNG_COLOR_TYPE_RGB) {
- avctx->pix_fmt = AV_PIX_FMT_RGB24;
- } else if ((s->bit_depth == 2 || s->bit_depth == 4 || s->bit_depth == 8) &&
- s->color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
- avctx->pix_fmt = AV_PIX_FMT_RGBA;
- } else if ((s->bit_depth == 2 || s->bit_depth == 4 || s->bit_depth == 8) &&
- s->color_type == PNG_COLOR_TYPE_GRAY) {
- avctx->pix_fmt = AV_PIX_FMT_GRAY8;
- } else if (s->bit_depth == 16 &&
- s->color_type == PNG_COLOR_TYPE_GRAY) {
- avctx->pix_fmt = AV_PIX_FMT_GRAY16BE;
- } else if (s->bit_depth == 16 &&
- s->color_type == PNG_COLOR_TYPE_RGB) {
- avctx->pix_fmt = AV_PIX_FMT_RGB48BE;
- } else if (s->bit_depth == 16 &&
- s->color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
- avctx->pix_fmt = AV_PIX_FMT_RGBA64BE;
- } else if ((s->bits_per_pixel == 1 || s->bits_per_pixel == 2 || s->bits_per_pixel == 4 || s->bits_per_pixel == 8) &&
- s->color_type == PNG_COLOR_TYPE_PALETTE) {
- avctx->pix_fmt = AV_PIX_FMT_PAL8;
- } else if (s->bit_depth == 1 && s->bits_per_pixel == 1) {
- avctx->pix_fmt = AV_PIX_FMT_MONOBLACK;
- } else if (s->bit_depth == 8 &&
- s->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {
- avctx->pix_fmt = AV_PIX_FMT_YA8;
- } else if (s->bit_depth == 16 &&
- s->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {
- avctx->pix_fmt = AV_PIX_FMT_YA16BE;
- } else {
- av_log(avctx, AV_LOG_ERROR, "unsupported bit depth %d "
- "and color type %d\n",
- s->bit_depth, s->color_type);
- goto fail;
- }
+ av_dlog(avctx, "row_size=%d crow_size =%d\n",
+ s->row_size, s->crow_size);
+ s->image_buf = p->data[0];
+ s->image_linesize = p->linesize[0];
+ /* copy the palette if needed */
+ if (avctx->pix_fmt == AV_PIX_FMT_PAL8)
+ memcpy(p->data[1], s->palette, 256 * sizeof(uint32_t));
+ /* empty row is used if differencing to the first row */
+ av_fast_padded_mallocz(&s->last_row, &s->last_row_size, s->row_size);
+ if (!s->last_row)
+ return AVERROR_INVALIDDATA;
+ if (s->interlace_type ||
+ s->color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
+ av_fast_padded_malloc(&s->tmp_row, &s->tmp_row_size, s->row_size);
+ if (!s->tmp_row)
+ return AVERROR_INVALIDDATA;
+ }
+ /* compressed row */
+ av_fast_padded_malloc(&s->buffer, &s->buffer_size, s->row_size + 16);
+ if (!s->buffer)
+ return AVERROR(ENOMEM);
+
+ /* we want crow_buf+1 to be 16-byte aligned */
+ s->crow_buf = s->buffer + 15;
+ s->zstream.avail_out = s->crow_size;
+ s->zstream.next_out = s->crow_buf;
+ }
+ s->state |= PNG_IDAT;
+ if ((ret = png_decode_idat(s, length)) < 0)
+ return ret;
+ bytestream2_skip(&s->gb, 4); /* crc */
- if (ff_thread_get_buffer(avctx, &s->picture, AV_GET_BUFFER_FLAG_REF) < 0)
- goto fail;
- ff_thread_finish_setup(avctx);
+ return 0;
+}
- p->pict_type = AV_PICTURE_TYPE_I;
- p->key_frame = 1;
- p->interlaced_frame = !!s->interlace_type;
+static int decode_plte_chunk(AVCodecContext *avctx, PNGDecContext *s,
+ uint32_t length)
+{
+ int n, i, r, g, b;
- /* compute the compressed row size */
- if (!s->interlace_type) {
- s->crow_size = s->row_size + 1;
- } else {
- s->pass = 0;
- s->pass_row_size = ff_png_pass_row_size(s->pass,
- s->bits_per_pixel,
- s->width);
- s->crow_size = s->pass_row_size + 1;
- }
- av_dlog(avctx, "row_size=%d crow_size =%d\n",
- s->row_size, s->crow_size);
- s->image_buf = p->data[0];
- s->image_linesize = p->linesize[0];
- /* copy the palette if needed */
- if (avctx->pix_fmt == AV_PIX_FMT_PAL8)
- memcpy(p->data[1], s->palette, 256 * sizeof(uint32_t));
- /* empty row is used if differencing to the first row */
- av_fast_padded_mallocz(&s->last_row, &s->last_row_size, s->row_size);
- if (!s->last_row)
- goto fail;
- if (s->interlace_type ||
- s->color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
- av_fast_padded_malloc(&s->tmp_row, &s->tmp_row_size, s->row_size);
- if (!s->tmp_row)
- goto fail;
- }
- /* compressed row */
- av_fast_padded_malloc(&s->buffer, &s->buffer_size, s->row_size + 16);
- if (!s->buffer)
- goto fail;
-
- /* we want crow_buf+1 to be 16-byte aligned */
- s->crow_buf = s->buffer + 15;
- s->zstream.avail_out = s->crow_size;
- s->zstream.next_out = s->crow_buf;
- }
- s->state |= PNG_IDAT;
- if (png_decode_idat(s, length) < 0)
- goto fail;
- bytestream2_skip(&s->gb, 4); /* crc */
- break;
- case MKTAG('P', 'L', 'T', 'E'):
- {
- int n, i, r, g, b;
+ if ((length % 3) != 0 || length > 256 * 3)
+ return AVERROR_INVALIDDATA;
+ /* read the palette */
+ n = length / 3;
+ for (i = 0; i < n; i++) {
+ r = bytestream2_get_byte(&s->gb);
+ g = bytestream2_get_byte(&s->gb);
+ b = bytestream2_get_byte(&s->gb);
+ s->palette[i] = (0xFFU << 24) | (r << 16) | (g << 8) | b;
+ }
+ for (; i < 256; i++)
+ s->palette[i] = (0xFFU << 24);
+ s->state |= PNG_PLTE;
+ bytestream2_skip(&s->gb, 4); /* crc */
- if ((length % 3) != 0 || length > 256 * 3)
- goto skip_tag;
- /* read the palette */
- n = length / 3;
- for (i = 0; i < n; i++) {
- r = bytestream2_get_byte(&s->gb);
- g = bytestream2_get_byte(&s->gb);
- b = bytestream2_get_byte(&s->gb);
- s->palette[i] = (0xFFU << 24) | (r << 16) | (g << 8) | b;
- }
- for (; i < 256; i++)
- s->palette[i] = (0xFFU << 24);
- s->state |= PNG_PLTE;
- bytestream2_skip(&s->gb, 4); /* crc */
- }
- break;
- case MKTAG('t', 'R', 'N', 'S'):
- {
- int v, i;
+ return 0;
+}
- /* read the transparency. XXX: Only palette mode supported */
- if (s->color_type != PNG_COLOR_TYPE_PALETTE ||
- length > 256 ||
- !(s->state & PNG_PLTE))
- goto skip_tag;
- for (i = 0; i < length; i++) {
- v = bytestream2_get_byte(&s->gb);
- s->palette[i] = (s->palette[i] & 0x00ffffff) | (v << 24);
- }
- bytestream2_skip(&s->gb, 4); /* crc */
- }
- break;
- case MKTAG('t', 'E', 'X', 't'):
- if (decode_text_chunk(s, length, 0, &metadata) < 0)
- av_log(avctx, AV_LOG_WARNING, "Broken tEXt chunk\n");
- bytestream2_skip(&s->gb, length + 4);
- break;
- case MKTAG('z', 'T', 'X', 't'):
- if (decode_text_chunk(s, length, 1, &metadata) < 0)
- av_log(avctx, AV_LOG_WARNING, "Broken zTXt chunk\n");
- bytestream2_skip(&s->gb, length + 4);
- break;
- case MKTAG('I', 'E', 'N', 'D'):
- if (!(s->state & PNG_ALLIMAGE))
- av_log(avctx, AV_LOG_ERROR, "IEND without all image\n");
- if (!(s->state & (PNG_ALLIMAGE|PNG_IDAT))) {
- goto fail;
- }
- bytestream2_skip(&s->gb, 4); /* crc */
- goto exit_loop;
- default:
- /* skip tag */
-skip_tag:
- bytestream2_skip(&s->gb, length + 4);
- break;
- }
+static int decode_trns_chunk(AVCodecContext *avctx, PNGDecContext *s,
+ uint32_t length)
+{
+ int v, i;
+
+ /* read the transparency. XXX: Only palette mode supported */
+ if (s->color_type != PNG_COLOR_TYPE_PALETTE ||
+ length > 256 ||
+ !(s->state & PNG_PLTE))
+ return AVERROR_INVALIDDATA;
+ for (i = 0; i < length; i++) {
+ v = bytestream2_get_byte(&s->gb);
+ s->palette[i] = (s->palette[i] & 0x00ffffff) | (v << 24);
}
-exit_loop:
+ bytestream2_skip(&s->gb, 4); /* crc */
+
+ return 0;
+}
- if (s->bits_per_pixel == 1 && s->color_type == PNG_COLOR_TYPE_PALETTE){
+static void handle_small_bpp(PNGDecContext *s, AVFrame *p)
+{
+ if (s->bits_per_pixel == 1 && s->color_type == PNG_COLOR_TYPE_PALETTE) {
int i, j, k;
uint8_t *pd = p->data[0];
for (j = 0; j < s->height; j++) {
}
pd += s->image_linesize;
}
- }
- if (s->bits_per_pixel == 2){
+ } else if (s->bits_per_pixel == 2) {
int i, j;
uint8_t *pd = p->data[0];
for (j = 0; j < s->height; j++) {
i = s->width / 4;
- if (s->color_type == PNG_COLOR_TYPE_PALETTE){
+ if (s->color_type == PNG_COLOR_TYPE_PALETTE) {
if ((s->width&3) >= 3) pd[4*i + 2]= (pd[i] >> 2) & 3;
if ((s->width&3) >= 2) pd[4*i + 1]= (pd[i] >> 4) & 3;
if ((s->width&3) >= 1) pd[4*i + 0]= pd[i] >> 6;
}
pd += s->image_linesize;
}
- }
- if (s->bits_per_pixel == 4){
+ } else if (s->bits_per_pixel == 4) {
int i, j;
uint8_t *pd = p->data[0];
for (j = 0; j < s->height; j++) {
i = s->width/2;
- if (s->color_type == PNG_COLOR_TYPE_PALETTE){
+ if (s->color_type == PNG_COLOR_TYPE_PALETTE) {
if (s->width&1) pd[2*i+0]= pd[i]>>4;
for (i--; i >= 0; i--) {
- pd[2*i + 1] = pd[i] & 15;
- pd[2*i + 0] = pd[i] >> 4;
- }
+ pd[2*i + 1] = pd[i] & 15;
+ pd[2*i + 0] = pd[i] >> 4;
+ }
} else {
if (s->width & 1) pd[2*i + 0]= (pd[i] >> 4) * 0x11;
for (i--; i >= 0; i--) {
pd += s->image_linesize;
}
}
+}
+
+static int decode_fctl_chunk(AVCodecContext *avctx, PNGDecContext *s,
+ uint32_t length)
+{
+ uint32_t sequence_number;
+
+ if (length != 26)
+ return AVERROR_INVALIDDATA;
+
+ sequence_number = bytestream2_get_be32(&s->gb);
+ s->cur_w = bytestream2_get_be32(&s->gb);
+ s->cur_h = bytestream2_get_be32(&s->gb);
+ s->x_offset = bytestream2_get_be32(&s->gb);
+ s->y_offset = bytestream2_get_be32(&s->gb);
+ bytestream2_skip(&s->gb, 4); /* delay_num (2), delay_den (2) */
+ s->dispose_op = bytestream2_get_byte(&s->gb);
+ s->blend_op = bytestream2_get_byte(&s->gb);
+ bytestream2_skip(&s->gb, 4); /* crc */
+
+ if (sequence_number == 0 &&
+ (s->cur_w != s->width ||
+ s->cur_h != s->height ||
+ s->x_offset != 0 ||
+ s->y_offset != 0) ||
+ s->cur_w <= 0 || s->cur_h <= 0 ||
+ s->x_offset < 0 || s->y_offset < 0 ||
+ s->cur_w > s->width - s->x_offset|| s->cur_h > s->height - s->y_offset)
+ return AVERROR_INVALIDDATA;
+
+ /* always (re)start with a clean frame */
+ if (sequence_number == 0) {
+ s->dispose_op = APNG_DISPOSE_OP_BACKGROUND;
+ s->frame_id = 0;
+ } else {
+ s->frame_id++;
+ if (s->frame_id == 1 && s->dispose_op == APNG_DISPOSE_OP_PREVIOUS)
+ /* previous for the second frame is the first frame */
+ s->dispose_op = APNG_DISPOSE_OP_NONE;
+ }
+
+ return 0;
+}
+
+static void handle_p_frame_png(PNGDecContext *s, AVFrame *p)
+{
+ int i, j;
+ uint8_t *pd = p->data[0];
+ uint8_t *pd_last = s->last_picture.f->data[0];
+ int ls = FFMIN(av_image_get_linesize(p->format, s->width, 0), s->width * s->bpp);
+
+ ff_thread_await_progress(&s->last_picture, INT_MAX, 0);
+ for (j = 0; j < s->height; j++) {
+ for (i = 0; i < ls; i++)
+ pd[i] += pd_last[i];
+ pd += s->image_linesize;
+ pd_last += s->image_linesize;
+ }
+}
+
+// divide by 255 and round to nearest
+// apply a fast variant: (X+127)/255 = ((X+127)*257+257)>>16 = ((X+128)*257)>>16
+#define FAST_DIV255(x) ((((x) + 128) * 257) >> 16)
+
+static int handle_p_frame_apng(AVCodecContext *avctx, PNGDecContext *s,
+ AVFrame *p)
+{
+ int i, j;
+ uint8_t *pd = p->data[0];
+ uint8_t *pd_last = s->last_picture.f->data[0];
+ uint8_t *pd_last_region = s->dispose_op == APNG_DISPOSE_OP_PREVIOUS ?
+ s->previous_picture.f->data[0] : s->last_picture.f->data[0];
+ int ls = FFMIN(av_image_get_linesize(p->format, s->width, 0), s->width * s->bpp);
+
+ if (s->blend_op == APNG_BLEND_OP_OVER &&
+ avctx->pix_fmt != AV_PIX_FMT_RGBA && avctx->pix_fmt != AV_PIX_FMT_ARGB) {
+ avpriv_request_sample(avctx, "Blending with pixel format %s",
+ av_get_pix_fmt_name(avctx->pix_fmt));
+ return AVERROR_PATCHWELCOME;
+ }
+
+ ff_thread_await_progress(&s->last_picture, INT_MAX, 0);
+ if (s->dispose_op == APNG_DISPOSE_OP_PREVIOUS)
+ ff_thread_await_progress(&s->previous_picture, INT_MAX, 0);
+
+ for (j = 0; j < s->y_offset; j++) {
+ for (i = 0; i < ls; i++)
+ pd[i] = pd_last[i];
+ pd += s->image_linesize;
+ pd_last += s->image_linesize;
+ }
+
+ if (s->dispose_op != APNG_DISPOSE_OP_BACKGROUND && s->blend_op == APNG_BLEND_OP_OVER) {
+ uint8_t ri, gi, bi, ai;
+
+ pd_last_region += s->y_offset * s->image_linesize;
+ if (avctx->pix_fmt == AV_PIX_FMT_RGBA) {
+ ri = 0;
+ gi = 1;
+ bi = 2;
+ ai = 3;
+ } else {
+ ri = 3;
+ gi = 2;
+ bi = 1;
+ ai = 0;
+ }
+
+ for (j = s->y_offset; j < s->y_offset + s->cur_h; j++) {
+ for (i = 0; i < s->x_offset * s->bpp; i++)
+ pd[i] = pd_last[i];
+ for (; i < (s->x_offset + s->cur_w) * s->bpp; i += s->bpp) {
+ uint8_t alpha = pd[i+ai];
+
+ /* output = alpha * foreground + (1-alpha) * background */
+ switch (alpha) {
+ case 0:
+ pd[i+ri] = pd_last_region[i+ri];
+ pd[i+gi] = pd_last_region[i+gi];
+ pd[i+bi] = pd_last_region[i+bi];
+ pd[i+ai] = 0xff;
+ break;
+ case 255:
+ break;
+ default:
+ pd[i+ri] = FAST_DIV255(alpha * pd[i+ri] + (255 - alpha) * pd_last_region[i+ri]);
+ pd[i+gi] = FAST_DIV255(alpha * pd[i+gi] + (255 - alpha) * pd_last_region[i+gi]);
+ pd[i+bi] = FAST_DIV255(alpha * pd[i+bi] + (255 - alpha) * pd_last_region[i+bi]);
+ pd[i+ai] = 0xff;
+ break;
+ }
+ }
+ for (; i < ls; i++)
+ pd[i] = pd_last[i];
+ pd += s->image_linesize;
+ pd_last += s->image_linesize;
+ pd_last_region += s->image_linesize;
+ }
+ } else {
+ for (j = s->y_offset; j < s->y_offset + s->cur_h; j++) {
+ for (i = 0; i < s->x_offset * s->bpp; i++)
+ pd[i] = pd_last[i];
+ for (i = (s->x_offset + s->cur_w) * s->bpp; i < ls; i++)
+ pd[i] = pd_last[i];
+ pd += s->image_linesize;
+ pd_last += s->image_linesize;
+ }
+ }
+
+ for (j = s->y_offset + s->cur_h; j < s->height; j++) {
+ for (i = 0; i < ls; i++)
+ pd[i] = pd_last[i];
+ pd += s->image_linesize;
+ pd_last += s->image_linesize;
+ }
+
+ return 0;
+}
+
+static int decode_frame_common(AVCodecContext *avctx, PNGDecContext *s,
+ AVFrame *p, AVPacket *avpkt)
+{
+ AVDictionary *metadata = NULL;
+ uint32_t tag, length;
+ int decode_next_dat = 0;
+ int ret = AVERROR_INVALIDDATA;
+ AVFrame *ref;
+
+ for (;;) {
+ length = bytestream2_get_bytes_left(&s->gb);
+ if (length <= 0) {
+ if (CONFIG_APNG_DECODER && avctx->codec_id == AV_CODEC_ID_APNG && length == 0) {
+ if (!(s->state & PNG_IDAT))
+ return 0;
+ else
+ goto exit_loop;
+ }
+ av_log(avctx, AV_LOG_ERROR, "%d bytes left\n", length);
+ if ( s->state & PNG_ALLIMAGE
+ && avctx->strict_std_compliance <= FF_COMPLIANCE_NORMAL)
+ goto exit_loop;
+ goto fail;
+ }
+
+ length = bytestream2_get_be32(&s->gb);
+ if (length > 0x7fffffff || length > bytestream2_get_bytes_left(&s->gb)) {
+ av_log(avctx, AV_LOG_ERROR, "chunk too big\n");
+ goto fail;
+ }
+ tag = bytestream2_get_le32(&s->gb);
+ if (avctx->debug & FF_DEBUG_STARTCODE)
+ av_log(avctx, AV_LOG_DEBUG, "png: tag=%c%c%c%c length=%u\n",
+ (tag & 0xff),
+ ((tag >> 8) & 0xff),
+ ((tag >> 16) & 0xff),
+ ((tag >> 24) & 0xff), length);
+ switch (tag) {
+ case MKTAG('I', 'H', 'D', 'R'):
+ if (decode_ihdr_chunk(avctx, s, length) < 0)
+ goto fail;
+ break;
+ case MKTAG('p', 'H', 'Y', 's'):
+ if (decode_phys_chunk(avctx, s) < 0)
+ goto fail;
+ break;
+ case MKTAG('f', 'c', 'T', 'L'):
+ if (!CONFIG_APNG_DECODER || avctx->codec_id != AV_CODEC_ID_APNG)
+ goto skip_tag;
+ if ((ret = decode_fctl_chunk(avctx, s, length)) < 0)
+ goto fail;
+ decode_next_dat = 1;
+ break;
+ case MKTAG('f', 'd', 'A', 'T'):
+ if (!CONFIG_APNG_DECODER || avctx->codec_id != AV_CODEC_ID_APNG)
+ goto skip_tag;
+ if (!decode_next_dat)
+ goto fail;
+ bytestream2_get_be32(&s->gb);
+ length -= 4;
+ /* fallthrough */
+ case MKTAG('I', 'D', 'A', 'T'):
+ if (CONFIG_APNG_DECODER && avctx->codec_id == AV_CODEC_ID_APNG && !decode_next_dat)
+ goto skip_tag;
+ if (decode_idat_chunk(avctx, s, length, p) < 0)
+ goto fail;
+ break;
+ case MKTAG('P', 'L', 'T', 'E'):
+ if (decode_plte_chunk(avctx, s, length) < 0)
+ goto skip_tag;
+ break;
+ case MKTAG('t', 'R', 'N', 'S'):
+ if (decode_trns_chunk(avctx, s, length) < 0)
+ goto skip_tag;
+ break;
+ case MKTAG('t', 'E', 'X', 't'):
+ if (decode_text_chunk(s, length, 0, &metadata) < 0)
+ av_log(avctx, AV_LOG_WARNING, "Broken tEXt chunk\n");
+ bytestream2_skip(&s->gb, length + 4);
+ break;
+ case MKTAG('z', 'T', 'X', 't'):
+ if (decode_text_chunk(s, length, 1, &metadata) < 0)
+ av_log(avctx, AV_LOG_WARNING, "Broken zTXt chunk\n");
+ bytestream2_skip(&s->gb, length + 4);
+ break;
+ case MKTAG('I', 'E', 'N', 'D'):
+ if (!(s->state & PNG_ALLIMAGE))
+ av_log(avctx, AV_LOG_ERROR, "IEND without all image\n");
+ if (!(s->state & (PNG_ALLIMAGE|PNG_IDAT))) {
+ goto fail;
+ }
+ bytestream2_skip(&s->gb, 4); /* crc */
+ goto exit_loop;
+ default:
+ /* skip tag */
+skip_tag:
+ bytestream2_skip(&s->gb, length + 4);
+ break;
+ }
+ }
+exit_loop:
+
+ if (s->bits_per_pixel <= 4)
+ handle_small_bpp(s, p);
/* handle p-frames only if a predecessor frame is available */
- if (s->last_picture.f->data[0]) {
+ ref = s->dispose_op == APNG_DISPOSE_OP_PREVIOUS ?
+ s->previous_picture.f : s->last_picture.f;
+ if (ref->data[0]) {
if ( !(avpkt->flags & AV_PKT_FLAG_KEY) && avctx->codec_tag != AV_RL32("MPNG")
- && s->last_picture.f->width == p->width
- && s->last_picture.f->height== p->height
- && s->last_picture.f->format== p->format
+ && ref->width == p->width
+ && ref->height== p->height
+ && ref->format== p->format
) {
- int i, j;
- uint8_t *pd = p->data[0];
- uint8_t *pd_last = s->last_picture.f->data[0];
- int ls = FFMIN(av_image_get_linesize(p->format, s->width, 0), s->width * s->bpp);
-
- ff_thread_await_progress(&s->last_picture, INT_MAX, 0);
- for (j = 0; j < s->height; j++) {
- for (i = 0; i < ls; i++)
- pd[i] += pd_last[i];
- pd += s->image_linesize;
- pd_last += s->image_linesize;
- }
+ if (CONFIG_PNG_DECODER && avctx->codec_id != AV_CODEC_ID_APNG)
+ handle_p_frame_png(s, p);
+ else if (CONFIG_APNG_DECODER &&
+ avctx->codec_id == AV_CODEC_ID_APNG &&
+ (ret = handle_p_frame_apng(avctx, s, p)) < 0)
+ goto fail;
}
}
ff_thread_report_progress(&s->picture, INT_MAX, 0);
av_frame_set_metadata(p, metadata);
metadata = NULL;
+ return 0;
+
+fail:
+ av_dict_free(&metadata);
+ ff_thread_report_progress(&s->picture, INT_MAX, 0);
+ return ret;
+}
+
+#if CONFIG_PNG_DECODER
+static int decode_frame_png(AVCodecContext *avctx,
+ void *data, int *got_frame,
+ AVPacket *avpkt)
+{
+ PNGDecContext *const s = avctx->priv_data;
+ const uint8_t *buf = avpkt->data;
+ int buf_size = avpkt->size;
+ AVFrame *p;
+ int64_t sig;
+ int ret;
+
+ ff_thread_release_buffer(avctx, &s->last_picture);
+ FFSWAP(ThreadFrame, s->picture, s->last_picture);
+ p = s->picture.f;
+
+ bytestream2_init(&s->gb, buf, buf_size);
+
+ /* check signature */
+ sig = bytestream2_get_be64(&s->gb);
+ if (sig != PNGSIG &&
+ sig != MNGSIG) {
+ av_log(avctx, AV_LOG_ERROR, "Missing png signature\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ s->y = s->state = 0;
+
+ /* init the zlib */
+ s->zstream.zalloc = ff_png_zalloc;
+ s->zstream.zfree = ff_png_zfree;
+ s->zstream.opaque = NULL;
+ ret = inflateInit(&s->zstream);
+ if (ret != Z_OK) {
+ av_log(avctx, AV_LOG_ERROR, "inflateInit returned error %d\n", ret);
+ return AVERROR_EXTERNAL;
+ }
+
+ if ((ret = decode_frame_common(avctx, s, p, avpkt)) < 0)
+ goto the_end;
if ((ret = av_frame_ref(data, s->picture.f)) < 0)
return ret;
inflateEnd(&s->zstream);
s->crow_buf = NULL;
return ret;
-fail:
- av_dict_free(&metadata);
- ff_thread_report_progress(&s->picture, INT_MAX, 0);
- ret = AVERROR_INVALIDDATA;
- goto the_end;
}
+#endif
+
+#if CONFIG_APNG_DECODER
+static int decode_frame_apng(AVCodecContext *avctx,
+ void *data, int *got_frame,
+ AVPacket *avpkt)
+{
+ PNGDecContext *const s = avctx->priv_data;
+ int ret;
+ AVFrame *p;
+ ThreadFrame tmp;
+
+ ff_thread_release_buffer(avctx, &s->previous_picture);
+ tmp = s->previous_picture;
+ s->previous_picture = s->last_picture;
+ s->last_picture = s->picture;
+ s->picture = tmp;
+ p = s->picture.f;
+
+ if (!(s->state & PNG_IHDR)) {
+ if (!avctx->extradata_size)
+ return AVERROR_INVALIDDATA;
+
+ /* only init fields, there is no zlib use in extradata */
+ s->zstream.zalloc = ff_png_zalloc;
+ s->zstream.zfree = ff_png_zfree;
+
+ bytestream2_init(&s->gb, avctx->extradata, avctx->extradata_size);
+ if ((ret = decode_frame_common(avctx, s, p, avpkt)) < 0)
+ goto end;
+ }
+
+ /* reset state for a new frame */
+ if ((ret = inflateInit(&s->zstream)) != Z_OK) {
+ av_log(avctx, AV_LOG_ERROR, "inflateInit returned error %d\n", ret);
+ ret = AVERROR_EXTERNAL;
+ goto end;
+ }
+ s->y = 0;
+ s->state &= ~(PNG_IDAT | PNG_ALLIMAGE);
+ bytestream2_init(&s->gb, avpkt->data, avpkt->size);
+ if ((ret = decode_frame_common(avctx, s, p, avpkt)) < 0)
+ goto end;
+
+ if (!(s->state & PNG_ALLIMAGE))
+ av_log(avctx, AV_LOG_WARNING, "Frame did not contain a complete image\n");
+ if (!(s->state & (PNG_ALLIMAGE|PNG_IDAT))) {
+ ret = AVERROR_INVALIDDATA;
+ goto end;
+ }
+ if ((ret = av_frame_ref(data, s->picture.f)) < 0)
+ goto end;
+
+ *got_frame = 1;
+ ret = bytestream2_tell(&s->gb);
+
+end:
+ inflateEnd(&s->zstream);
+ return ret;
+}
+#endif
static int update_thread_context(AVCodecContext *dst, const AVCodecContext *src)
{
PNGDecContext *psrc = src->priv_data;
PNGDecContext *pdst = dst->priv_data;
+ int ret;
if (dst == src)
return 0;
+ pdst->frame_id = psrc->frame_id;
+
ff_thread_release_buffer(dst, &pdst->picture);
- if (psrc->picture.f->data[0])
- return ff_thread_ref_frame(&pdst->picture, &psrc->picture);
+ if (psrc->picture.f->data[0] &&
+ (ret = ff_thread_ref_frame(&pdst->picture, &psrc->picture)) < 0)
+ return ret;
+ if (CONFIG_APNG_DECODER && dst->codec_id == AV_CODEC_ID_APNG) {
+ ff_thread_release_buffer(dst, &pdst->last_picture);
+ if (psrc->last_picture.f->data[0])
+ return ff_thread_ref_frame(&pdst->last_picture, &psrc->last_picture);
+ }
return 0;
}
PNGDecContext *s = avctx->priv_data;
s->avctx = avctx;
+ s->previous_picture.f = av_frame_alloc();
s->last_picture.f = av_frame_alloc();
s->picture.f = av_frame_alloc();
- if (!s->last_picture.f || !s->picture.f)
+ if (!s->previous_picture.f || !s->last_picture.f || !s->picture.f) {
+ av_frame_free(&s->previous_picture.f);
+ av_frame_free(&s->last_picture.f);
+ av_frame_free(&s->picture.f);
return AVERROR(ENOMEM);
+ }
if (!avctx->internal->is_copy) {
avctx->internal->allocate_progress = 1;
{
PNGDecContext *s = avctx->priv_data;
+ ff_thread_release_buffer(avctx, &s->previous_picture);
+ av_frame_free(&s->previous_picture.f);
ff_thread_release_buffer(avctx, &s->last_picture);
av_frame_free(&s->last_picture.f);
ff_thread_release_buffer(avctx, &s->picture);
return 0;
}
+#if CONFIG_APNG_DECODER
+AVCodec ff_apng_decoder = {
+ .name = "apng",
+ .long_name = NULL_IF_CONFIG_SMALL("APNG (Animated Portable Network Graphics) image"),
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = AV_CODEC_ID_APNG,
+ .priv_data_size = sizeof(PNGDecContext),
+ .init = png_dec_init,
+ .close = png_dec_end,
+ .decode = decode_frame_apng,
+ .init_thread_copy = ONLY_IF_THREADS_ENABLED(png_dec_init),
+ .update_thread_context = ONLY_IF_THREADS_ENABLED(update_thread_context),
+ .capabilities = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS /*| CODEC_CAP_DRAW_HORIZ_BAND*/,
+};
+#endif
+
+#if CONFIG_PNG_DECODER
AVCodec ff_png_decoder = {
.name = "png",
.long_name = NULL_IF_CONFIG_SMALL("PNG (Portable Network Graphics) image"),
.priv_data_size = sizeof(PNGDecContext),
.init = png_dec_init,
.close = png_dec_end,
- .decode = decode_frame,
+ .decode = decode_frame_png,
.init_thread_copy = ONLY_IF_THREADS_ENABLED(png_dec_init),
.update_thread_context = ONLY_IF_THREADS_ENABLED(update_thread_context),
.capabilities = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS /*| CODEC_CAP_DRAW_HORIZ_BAND*/,
};
+#endif
#include <stdint.h>
typedef struct PNGDSPContext {
- void (*add_bytes_l2)(uint8_t *dst /* align 16 */,
+ void (*add_bytes_l2)(uint8_t *dst,
uint8_t *src1 /* align 16 */,
- uint8_t *src2 /* align 16 */, int w);
+ uint8_t *src2, int w);
/* this might write to dst[w] */
void (*add_paeth_prediction)(uint8_t *dst, uint8_t *src,
*/
#include "libavutil/mem.h"
+#include "libavutil/ppc/types_altivec.h"
+#include "libavutil/ppc/util_altivec.h"
/* this code assume that stride % 16 == 0 */
#define CHROMA_MC8_ALTIVEC_CORE(BIAS1, BIAS2) \
- vsrc2ssH = (vec_s16)vec_mergeh(zero_u8v,(vec_u8)vsrc2uc);\
- vsrc3ssH = (vec_s16)vec_mergeh(zero_u8v,(vec_u8)vsrc3uc);\
+ vsrc2ssH = (vec_s16)VEC_MERGEH(zero_u8v,(vec_u8)vsrc2uc);\
+ vsrc3ssH = (vec_s16)VEC_MERGEH(zero_u8v,(vec_u8)vsrc3uc);\
\
psum = vec_mladd(vA, vsrc0ssH, BIAS1);\
psum = vec_mladd(vB, vsrc1ssH, psum);\
#define CHROMA_MC8_ALTIVEC_CORE_SIMPLE \
\
- vsrc0ssH = (vec_s16)vec_mergeh(zero_u8v,(vec_u8)vsrc0uc);\
- vsrc1ssH = (vec_s16)vec_mergeh(zero_u8v,(vec_u8)vsrc1uc);\
+ vsrc0ssH = (vec_s16)VEC_MERGEH(zero_u8v,(vec_u8)vsrc0uc);\
+ vsrc1ssH = (vec_s16)VEC_MERGEH(zero_u8v,(vec_u8)vsrc1uc);\
\
psum = vec_mladd(vA, vsrc0ssH, v32ss);\
psum = vec_mladd(vE, vsrc1ssH, psum);\
#define noop(a) a
#define add28(a) vec_add(v28ss, a)
+#if HAVE_BIGENDIAN
+#define GET_VSRC1(vs0, off, b, perm0, s){ \
+ vec_u8 vsrcCuc, vsrcDuc; \
+ vsrcCuc = vec_ld(off, s); \
+ if (loadSecond){ \
+ vsrcDuc = vec_ld(off + b, s); \
+ } else \
+ vsrcDuc = vsrcCuc; \
+ \
+ vs0 = vec_perm(vsrcCuc, vsrcDuc, perm0); \
+}
+#define GET_VSRC(vs0, vs1, off, b, perm0, perm1, s){ \
+ vec_u8 vsrcCuc, vsrcDuc; \
+ vsrcCuc = vec_ld(off, s); \
+ if (loadSecond){ \
+ vsrcDuc = vec_ld(off + b, s); \
+ } else \
+ vsrcDuc = vsrcCuc; \
+ \
+ vs0 = vec_perm(vsrcCuc, vsrcDuc, perm0); \
+ if (reallyBadAlign){ \
+ vs1 = vsrcDuc; \
+ } else \
+ vs1 = vec_perm(vsrcCuc, vsrcDuc, perm1); \
+ }
+
+#else
+
+#define GET_VSRC1(vs0, off, b, perm0, s){ \
+ vs0 = vec_vsx_ld(off, s); \
+ }
+#define GET_VSRC(vs0, vs1, off, b, perm0, perm1, s){ \
+ vs0 = vec_vsx_ld(off, s); \
+ vs1 = vec_vsx_ld(off + 1, s); \
+ }
+#endif /* HAVE_BIGENDIAN */
+
#ifdef PREFIX_h264_chroma_mc8_altivec
static void PREFIX_h264_chroma_mc8_altivec(uint8_t * dst, uint8_t * src,
int stride, int h, int x, int y) {
(( x) * ( y))};
register int i;
vec_u8 fperm;
- const vec_s32 vABCD = vec_ld(0, ABCD);
- const vec_s16 vA = vec_splat((vec_s16)vABCD, 1);
- const vec_s16 vB = vec_splat((vec_s16)vABCD, 3);
- const vec_s16 vC = vec_splat((vec_s16)vABCD, 5);
- const vec_s16 vD = vec_splat((vec_s16)vABCD, 7);
LOAD_ZERO;
+ const vec_s32 vABCD = vec_ld(0, ABCD);
+ const vec_s16 vA = VEC_SPLAT16(vABCD, 1);
+ const vec_s16 vB = VEC_SPLAT16(vABCD, 3);
+ const vec_s16 vC = VEC_SPLAT16(vABCD, 5);
+ const vec_s16 vD = VEC_SPLAT16(vABCD, 7);
const vec_s16 v32ss = vec_sl(vec_splat_s16(1),vec_splat_u16(5));
const vec_u16 v6us = vec_splat_u16(6);
- register int loadSecond = (((unsigned long)src) % 16) <= 7 ? 0 : 1;
- register int reallyBadAlign = (((unsigned long)src) % 16) == 15 ? 1 : 0;
- vec_u8 vsrcAuc, av_uninit(vsrcBuc), vsrcperm0, vsrcperm1;
+ vec_u8 vsrcperm0, vsrcperm1;
vec_u8 vsrc0uc, vsrc1uc;
vec_s16 vsrc0ssH, vsrc1ssH;
- vec_u8 vsrcCuc, vsrc2uc, vsrc3uc;
+ vec_u8 vsrc2uc, vsrc3uc;
vec_s16 vsrc2ssH, vsrc3ssH, psum;
vec_u8 vdst, ppsum, vfdst, fsum;
+#if HAVE_BIGENDIAN
+ register int loadSecond = (((unsigned long)src) % 16) <= 7 ? 0 : 1;
+ register int reallyBadAlign = (((unsigned long)src) % 16) == 15 ? 1 : 0;
+ vsrcperm0 = vec_lvsl(0, src);
+ vsrcperm1 = vec_lvsl(1, src);
+#endif
if (((unsigned long)dst) % 16 == 0) {
fperm = (vec_u8){0x10, 0x11, 0x12, 0x13,
0x1C, 0x1D, 0x1E, 0x1F};
}
- vsrcAuc = vec_ld(0, src);
-
- if (loadSecond)
- vsrcBuc = vec_ld(16, src);
- vsrcperm0 = vec_lvsl(0, src);
- vsrcperm1 = vec_lvsl(1, src);
-
- vsrc0uc = vec_perm(vsrcAuc, vsrcBuc, vsrcperm0);
- if (reallyBadAlign)
- vsrc1uc = vsrcBuc;
- else
- vsrc1uc = vec_perm(vsrcAuc, vsrcBuc, vsrcperm1);
+ GET_VSRC(vsrc0uc, vsrc1uc, 0, 16, vsrcperm0, vsrcperm1, src);
- vsrc0ssH = (vec_s16)vec_mergeh(zero_u8v,(vec_u8)vsrc0uc);
- vsrc1ssH = (vec_s16)vec_mergeh(zero_u8v,(vec_u8)vsrc1uc);
+ vsrc0ssH = (vec_s16)VEC_MERGEH(zero_u8v,(vec_u8)vsrc0uc);
+ vsrc1ssH = (vec_s16)VEC_MERGEH(zero_u8v,(vec_u8)vsrc1uc);
if (ABCD[3]) {
- if (!loadSecond) {// -> !reallyBadAlign
- for (i = 0 ; i < h ; i++) {
- vsrcCuc = vec_ld(stride + 0, src);
- vsrc2uc = vec_perm(vsrcCuc, vsrcCuc, vsrcperm0);
- vsrc3uc = vec_perm(vsrcCuc, vsrcCuc, vsrcperm1);
-
- CHROMA_MC8_ALTIVEC_CORE(v32ss, noop)
- }
- } else {
- vec_u8 vsrcDuc;
- for (i = 0 ; i < h ; i++) {
- vsrcCuc = vec_ld(stride + 0, src);
- vsrcDuc = vec_ld(stride + 16, src);
- vsrc2uc = vec_perm(vsrcCuc, vsrcDuc, vsrcperm0);
- if (reallyBadAlign)
- vsrc3uc = vsrcDuc;
- else
- vsrc3uc = vec_perm(vsrcCuc, vsrcDuc, vsrcperm1);
-
- CHROMA_MC8_ALTIVEC_CORE(v32ss, noop)
- }
+ for (i = 0 ; i < h ; i++) {
+ GET_VSRC(vsrc2uc, vsrc3uc, stride, 16, vsrcperm0, vsrcperm1, src);
+ CHROMA_MC8_ALTIVEC_CORE(v32ss, noop);
}
} else {
const vec_s16 vE = vec_add(vB, vC);
if (ABCD[2]) { // x == 0 B == 0
- if (!loadSecond) {// -> !reallyBadAlign
- for (i = 0 ; i < h ; i++) {
- vsrcCuc = vec_ld(stride + 0, src);
- vsrc1uc = vec_perm(vsrcCuc, vsrcCuc, vsrcperm0);
- CHROMA_MC8_ALTIVEC_CORE_SIMPLE
-
- vsrc0uc = vsrc1uc;
- }
- } else {
- vec_u8 vsrcDuc;
- for (i = 0 ; i < h ; i++) {
- vsrcCuc = vec_ld(stride + 0, src);
- vsrcDuc = vec_ld(stride + 15, src);
- vsrc1uc = vec_perm(vsrcCuc, vsrcDuc, vsrcperm0);
- CHROMA_MC8_ALTIVEC_CORE_SIMPLE
-
- vsrc0uc = vsrc1uc;
- }
+ for (i = 0 ; i < h ; i++) {
+ GET_VSRC1(vsrc1uc, stride, 15, vsrcperm0, src);
+ CHROMA_MC8_ALTIVEC_CORE_SIMPLE;
+ vsrc0uc = vsrc1uc;
}
} else { // y == 0 C == 0
- if (!loadSecond) {// -> !reallyBadAlign
- for (i = 0 ; i < h ; i++) {
- vsrcCuc = vec_ld(0, src);
- vsrc0uc = vec_perm(vsrcCuc, vsrcCuc, vsrcperm0);
- vsrc1uc = vec_perm(vsrcCuc, vsrcCuc, vsrcperm1);
-
- CHROMA_MC8_ALTIVEC_CORE_SIMPLE
- }
- } else {
- vec_u8 vsrcDuc;
- for (i = 0 ; i < h ; i++) {
- vsrcCuc = vec_ld(0, src);
- vsrcDuc = vec_ld(15, src);
- vsrc0uc = vec_perm(vsrcCuc, vsrcDuc, vsrcperm0);
- if (reallyBadAlign)
- vsrc1uc = vsrcDuc;
- else
- vsrc1uc = vec_perm(vsrcCuc, vsrcDuc, vsrcperm1);
-
- CHROMA_MC8_ALTIVEC_CORE_SIMPLE
- }
+ for (i = 0 ; i < h ; i++) {
+ GET_VSRC(vsrc0uc, vsrc1uc, 0, 15, vsrcperm0, vsrcperm1, src);
+ CHROMA_MC8_ALTIVEC_CORE_SIMPLE;
}
}
}
(( x) * ( y))};
register int i;
vec_u8 fperm;
- const vec_s32 vABCD = vec_ld(0, ABCD);
- const vec_s16 vA = vec_splat((vec_s16)vABCD, 1);
- const vec_s16 vB = vec_splat((vec_s16)vABCD, 3);
- const vec_s16 vC = vec_splat((vec_s16)vABCD, 5);
- const vec_s16 vD = vec_splat((vec_s16)vABCD, 7);
LOAD_ZERO;
+ const vec_s32 vABCD = vec_ld(0, ABCD);
+ const vec_s16 vA = VEC_SPLAT16(vABCD, 1);
+ const vec_s16 vB = VEC_SPLAT16(vABCD, 3);
+ const vec_s16 vC = VEC_SPLAT16(vABCD, 5);
+ const vec_s16 vD = VEC_SPLAT16(vABCD, 7);
const vec_s16 v28ss = vec_sub(vec_sl(vec_splat_s16(1),vec_splat_u16(5)),vec_splat_s16(4));
const vec_u16 v6us = vec_splat_u16(6);
- register int loadSecond = (((unsigned long)src) % 16) <= 7 ? 0 : 1;
- register int reallyBadAlign = (((unsigned long)src) % 16) == 15 ? 1 : 0;
- vec_u8 vsrcAuc, av_uninit(vsrcBuc), vsrcperm0, vsrcperm1;
+ vec_u8 vsrcperm0, vsrcperm1;
vec_u8 vsrc0uc, vsrc1uc;
vec_s16 vsrc0ssH, vsrc1ssH;
- vec_u8 vsrcCuc, vsrc2uc, vsrc3uc;
+ vec_u8 vsrc2uc, vsrc3uc;
vec_s16 vsrc2ssH, vsrc3ssH, psum;
vec_u8 vdst, ppsum, vfdst, fsum;
+#if HAVE_BIGENDIAN
+ register int loadSecond = (((unsigned long)src) % 16) <= 7 ? 0 : 1;
+ register int reallyBadAlign = (((unsigned long)src) % 16) == 15 ? 1 : 0;
+ vsrcperm0 = vec_lvsl(0, src);
+ vsrcperm1 = vec_lvsl(1, src);
+#endif
if (((unsigned long)dst) % 16 == 0) {
fperm = (vec_u8){0x10, 0x11, 0x12, 0x13,
0x1C, 0x1D, 0x1E, 0x1F};
}
- vsrcAuc = vec_ld(0, src);
-
- if (loadSecond)
- vsrcBuc = vec_ld(16, src);
- vsrcperm0 = vec_lvsl(0, src);
- vsrcperm1 = vec_lvsl(1, src);
-
- vsrc0uc = vec_perm(vsrcAuc, vsrcBuc, vsrcperm0);
- if (reallyBadAlign)
- vsrc1uc = vsrcBuc;
- else
- vsrc1uc = vec_perm(vsrcAuc, vsrcBuc, vsrcperm1);
-
- vsrc0ssH = (vec_s16)vec_mergeh(zero_u8v, (vec_u8)vsrc0uc);
- vsrc1ssH = (vec_s16)vec_mergeh(zero_u8v, (vec_u8)vsrc1uc);
-
- if (!loadSecond) {// -> !reallyBadAlign
- for (i = 0 ; i < h ; i++) {
-
-
- vsrcCuc = vec_ld(stride + 0, src);
+ GET_VSRC(vsrc0uc, vsrc1uc, 0, 16, vsrcperm0, vsrcperm1, src);
- vsrc2uc = vec_perm(vsrcCuc, vsrcCuc, vsrcperm0);
- vsrc3uc = vec_perm(vsrcCuc, vsrcCuc, vsrcperm1);
+ vsrc0ssH = (vec_s16)VEC_MERGEH(zero_u8v, (vec_u8)vsrc0uc);
+ vsrc1ssH = (vec_s16)VEC_MERGEH(zero_u8v, (vec_u8)vsrc1uc);
- CHROMA_MC8_ALTIVEC_CORE(vec_splat_s16(0), add28)
- }
- } else {
- vec_u8 vsrcDuc;
- for (i = 0 ; i < h ; i++) {
- vsrcCuc = vec_ld(stride + 0, src);
- vsrcDuc = vec_ld(stride + 16, src);
-
- vsrc2uc = vec_perm(vsrcCuc, vsrcDuc, vsrcperm0);
- if (reallyBadAlign)
- vsrc3uc = vsrcDuc;
- else
- vsrc3uc = vec_perm(vsrcCuc, vsrcDuc, vsrcperm1);
-
- CHROMA_MC8_ALTIVEC_CORE(vec_splat_s16(0), add28)
- }
+ for (i = 0 ; i < h ; i++) {
+ GET_VSRC(vsrc2uc, vsrc3uc, stride, 16, vsrcperm0, vsrcperm1, src);
+ CHROMA_MC8_ALTIVEC_CORE(vec_splat_s16(0), add28);
}
}
#endif
b2 = vec_mergeh( a1, a3 ); \
b3 = vec_mergel( a1, a3 )
+#if HAVE_BIGENDIAN
+#define vdst_load(d) \
+ vdst_orig = vec_ld(0, dst); \
+ vdst = vec_perm(vdst_orig, zero_u8v, vdst_mask);
+#else
+#define vdst_load(d) vdst = vec_vsx_ld(0, dst)
+#endif
+
#define VEC_LOAD_U8_ADD_S16_STORE_U8(va) \
- vdst_orig = vec_ld(0, dst); \
- vdst = vec_perm(vdst_orig, zero_u8v, vdst_mask); \
- vdst_ss = (vec_s16) vec_mergeh(zero_u8v, vdst); \
+ vdst_load(); \
+ vdst_ss = (vec_s16) VEC_MERGEH(zero_u8v, vdst); \
va = vec_add(va, vdst_ss); \
va_u8 = vec_packsu(va, zero_s16v); \
va_u32 = vec_splat((vec_u32)va_u8, 0); \
d7 = vec_sub(b0v, b7v); \
}
+#if HAVE_BIGENDIAN
+#define GET_2PERM(ldv, stv, d) \
+ ldv = vec_lvsl(0, d); \
+ stv = vec_lvsr(8, d);
+#define dstv_load(d) \
+ vec_u8 hv = vec_ld( 0, d ); \
+ vec_u8 lv = vec_ld( 7, d); \
+ vec_u8 dstv = vec_perm( hv, lv, (vec_u8)perm_ldv );
+#define dest_unligned_store(d) \
+ vec_u8 edgehv; \
+ vec_u8 bodyv = vec_perm( idstsum8, idstsum8, perm_stv ); \
+ vec_u8 edgelv = vec_perm( sel, zero_u8v, perm_stv ); \
+ lv = vec_sel( lv, bodyv, edgelv ); \
+ vec_st( lv, 7, d ); \
+ hv = vec_ld( 0, d ); \
+ edgehv = vec_perm( zero_u8v, sel, perm_stv ); \
+ hv = vec_sel( hv, bodyv, edgehv ); \
+ vec_st( hv, 0, d );
+#else
+
+#define GET_2PERM(ldv, stv, d) {}
+#define dstv_load(d) vec_u8 dstv = vec_vsx_ld(0, d)
+#define dest_unligned_store(d)\
+ vec_u8 dst8 = vec_perm((vec_u8)idstsum8, dstv, vcprm(2,3,s2,s3));\
+ vec_vsx_st(dst8, 0, d)
+#endif /* HAVE_BIGENDIAN */
+
#define ALTIVEC_STORE_SUM_CLIP(dest, idctv, perm_ldv, perm_stv, sel) { \
/* unaligned load */ \
- vec_u8 hv = vec_ld( 0, dest ); \
- vec_u8 lv = vec_ld( 7, dest ); \
- vec_u8 dstv = vec_perm( hv, lv, (vec_u8)perm_ldv ); \
+ dstv_load(dest); \
vec_s16 idct_sh6 = vec_sra(idctv, sixv); \
- vec_u16 dst16 = (vec_u16)vec_mergeh(zero_u8v, dstv); \
+ vec_u16 dst16 = (vec_u16)VEC_MERGEH(zero_u8v, dstv); \
vec_s16 idstsum = vec_adds(idct_sh6, (vec_s16)dst16); \
vec_u8 idstsum8 = vec_packsu(zero_s16v, idstsum); \
- vec_u8 edgehv; \
/* unaligned store */ \
- vec_u8 bodyv = vec_perm( idstsum8, idstsum8, perm_stv );\
- vec_u8 edgelv = vec_perm( sel, zero_u8v, perm_stv ); \
- lv = vec_sel( lv, bodyv, edgelv ); \
- vec_st( lv, 7, dest ); \
- hv = vec_ld( 0, dest ); \
- edgehv = vec_perm( zero_u8v, sel, perm_stv ); \
- hv = vec_sel( hv, bodyv, edgehv ); \
- vec_st( hv, 0, dest ); \
- }
+ dest_unligned_store(dest);\
+}
static void h264_idct8_add_altivec(uint8_t *dst, int16_t *dct, int stride)
{
vec_s16 d0, d1, d2, d3, d4, d5, d6, d7;
vec_s16 idct0, idct1, idct2, idct3, idct4, idct5, idct6, idct7;
- vec_u8 perm_ldv = vec_lvsl(0, dst);
- vec_u8 perm_stv = vec_lvsr(8, dst);
+ vec_u8 perm_ldv, perm_stv;
+ GET_2PERM(perm_ldv, perm_stv, dst);
const vec_u16 onev = vec_splat_u16(1);
const vec_u16 twov = vec_splat_u16(2);
{
vec_s16 dc16;
vec_u8 dcplus, dcminus, v0, v1, v2, v3, aligner;
+ vec_s32 v_dc32;
LOAD_ZERO;
DECLARE_ALIGNED(16, int, dc);
int i;
dc = (block[0] + 32) >> 6;
block[0] = 0;
- dc16 = vec_splat((vec_s16) vec_lde(0, &dc), 1);
+ v_dc32 = vec_lde(0, &dc);
+ dc16 = VEC_SPLAT16((vec_s16)v_dc32, 1);
if (size == 4)
- dc16 = vec_sld(dc16, zero_s16v, 8);
+ dc16 = VEC_SLD16(dc16, zero_s16v, 8);
dcplus = vec_packsu(dc16, zero_s16v);
dcminus = vec_packsu(vec_sub(zero_s16v, dc16), zero_s16v);
aligner = vec_lvsr(0, dst);
+#if !HAVE_BIGENDIAN
+ aligner = vec_perm(aligner, zero_u8v, vcswapc());
+#endif
dcplus = vec_perm(dcplus, dcplus, aligner);
dcminus = vec_perm(dcminus, dcminus, aligner);
temp[2] = offset;
vtemp = (vec_s16)vec_ld(0, temp);
+#if !HAVE_BIGENDIAN
+ vtemp =(vec_s16)vec_perm(vtemp, vtemp, vcswapi2s(0,1,2,3));
+#endif
vlog2_denom = (vec_u16)vec_splat(vtemp, 1);
vweight = vec_splat(vtemp, 3);
voffset = vec_splat(vtemp, 5);
for (y = 0; y < height; y++) {
vblock = vec_ld(0, block);
- v0 = (vec_s16)vec_mergeh(zero_u8v, vblock);
- v1 = (vec_s16)vec_mergel(zero_u8v, vblock);
+ v0 = (vec_s16)VEC_MERGEH(zero_u8v, vblock);
+ v1 = (vec_s16)VEC_MERGEL(zero_u8v, vblock);
if (w == 16 || aligned) {
v0 = vec_mladd(v0, vweight, zero_s16v);
temp[3] = offset;
vtemp = (vec_s16)vec_ld(0, temp);
+#if !HAVE_BIGENDIAN
+ vtemp =(vec_s16)vec_perm(vtemp, vtemp, vcswapi2s(0,1,2,3));
+#endif
vlog2_denom = (vec_u16)vec_splat(vtemp, 1);
vweights = vec_splat(vtemp, 3);
vweightd = vec_splat(vtemp, 5);
vdst = vec_ld(0, dst);
vsrc = vec_ld(0, src);
- v0 = (vec_s16)vec_mergeh(zero_u8v, vdst);
- v1 = (vec_s16)vec_mergel(zero_u8v, vdst);
- v2 = (vec_s16)vec_mergeh(zero_u8v, vsrc);
- v3 = (vec_s16)vec_mergel(zero_u8v, vsrc);
+ v0 = (vec_s16)VEC_MERGEH(zero_u8v, vdst);
+ v1 = (vec_s16)VEC_MERGEL(zero_u8v, vdst);
+ v2 = (vec_s16)VEC_MERGEH(zero_u8v, vsrc);
+ v3 = (vec_s16)VEC_MERGEL(zero_u8v, vsrc);
if (w == 8) {
if (src_aligned)
OPNAME ## pixels ## SIZE ## _l2_ ## CODETYPE(dst, halfV, halfHV, stride, SIZE, SIZE);\
}\
+#if HAVE_BIGENDIAN
+#define put_unligned_store(s, dest) { \
+ tmp1 = vec_ld(0, dest); \
+ mask = vec_lvsl(0, dest); \
+ tmp2 = vec_ld(15, dest); \
+ edges = vec_perm(tmp2, tmp1, mask); \
+ align = vec_lvsr(0, dest); \
+ tmp2 = vec_perm(s, edges, align); \
+ tmp1 = vec_perm(edges, s, align); \
+ vec_st(tmp2, 15, dest); \
+ vec_st(tmp1, 0 , dest); \
+ }
+#else
+#define put_unligned_store(s, dest) vec_vsx_st(s, 0, dest);
+#endif /* HAVE_BIGENDIAN */
+
static inline void put_pixels16_l2_altivec( uint8_t * dst, const uint8_t * src1,
const uint8_t * src2, int dst_stride,
int src_stride1, int h)
{
int i;
- vec_u8 a, b, d, tmp1, tmp2, mask, mask_, edges, align;
-
+ vec_u8 a, b, d, mask_;
+#if HAVE_BIGENDIAN
+ vec_u8 tmp1, tmp2, mask, edges, align;
mask_ = vec_lvsl(0, src2);
+#endif
for (i = 0; i < h; i++) {
-
- tmp1 = vec_ld(i * src_stride1, src1);
- mask = vec_lvsl(i * src_stride1, src1);
- tmp2 = vec_ld(i * src_stride1 + 15, src1);
-
- a = vec_perm(tmp1, tmp2, mask);
-
- tmp1 = vec_ld(i * 16, src2);
- tmp2 = vec_ld(i * 16 + 15, src2);
-
- b = vec_perm(tmp1, tmp2, mask_);
-
- tmp1 = vec_ld(0, dst);
- mask = vec_lvsl(0, dst);
- tmp2 = vec_ld(15, dst);
-
+ a = unaligned_load(i * src_stride1, src1);
+ b = load_with_perm_vec(i * 16, src2, mask_);
d = vec_avg(a, b);
-
- edges = vec_perm(tmp2, tmp1, mask);
-
- align = vec_lvsr(0, dst);
-
- tmp2 = vec_perm(d, edges, align);
- tmp1 = vec_perm(edges, d, align);
-
- vec_st(tmp2, 15, dst);
- vec_st(tmp1, 0 , dst);
-
+ put_unligned_store(d, dst);
dst += dst_stride;
}
}
+#if HAVE_BIGENDIAN
+#define avg_unligned_store(s, dest){ \
+ tmp1 = vec_ld(0, dest); \
+ mask = vec_lvsl(0, dest); \
+ tmp2 = vec_ld(15, dest); \
+ a = vec_avg(vec_perm(tmp1, tmp2, mask), s); \
+ edges = vec_perm(tmp2, tmp1, mask); \
+ align = vec_lvsr(0, dest); \
+ tmp2 = vec_perm(a, edges, align); \
+ tmp1 = vec_perm(edges, a, align); \
+ vec_st(tmp2, 15, dest); \
+ vec_st(tmp1, 0 , dest); \
+ }
+#else
+#define avg_unligned_store(s, dest){ \
+ a = vec_avg(vec_vsx_ld(0, dst), s); \
+ vec_vsx_st(a, 0, dst); \
+ }
+#endif /* HAVE_BIGENDIAN */
+
static inline void avg_pixels16_l2_altivec( uint8_t * dst, const uint8_t * src1,
const uint8_t * src2, int dst_stride,
int src_stride1, int h)
{
int i;
- vec_u8 a, b, d, tmp1, tmp2, mask, mask_, edges, align;
+ vec_u8 a, b, d, mask_;
+#if HAVE_BIGENDIAN
+ vec_u8 tmp1, tmp2, mask, edges, align;
mask_ = vec_lvsl(0, src2);
+#endif
for (i = 0; i < h; i++) {
-
- tmp1 = vec_ld(i * src_stride1, src1);
- mask = vec_lvsl(i * src_stride1, src1);
- tmp2 = vec_ld(i * src_stride1 + 15, src1);
-
- a = vec_perm(tmp1, tmp2, mask);
-
- tmp1 = vec_ld(i * 16, src2);
- tmp2 = vec_ld(i * 16 + 15, src2);
-
- b = vec_perm(tmp1, tmp2, mask_);
-
- tmp1 = vec_ld(0, dst);
- mask = vec_lvsl(0, dst);
- tmp2 = vec_ld(15, dst);
-
- d = vec_avg(vec_perm(tmp1, tmp2, mask), vec_avg(a, b));
-
- edges = vec_perm(tmp2, tmp1, mask);
-
- align = vec_lvsr(0, dst);
-
- tmp2 = vec_perm(d, edges, align);
- tmp1 = vec_perm(edges, d, align);
-
- vec_st(tmp2, 15, dst);
- vec_st(tmp1, 0 , dst);
-
+ a = unaligned_load(i * src_stride1, src1);
+ b = load_with_perm_vec(i * 16, src2, mask_);
+ d = vec_avg(a, b);
+ avg_unligned_store(d, dst);
dst += dst_stride;
}
}
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include "config.h"
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
#include "libavutil/mem.h"
+#include "libavutil/ppc/types_altivec.h"
+#include "libavutil/ppc/util_altivec.h"
#ifdef DEBUG
#define ASSERT_ALIGNED(ptr) assert(((unsigned long)ptr&0x0000000F));
#define ASSERT_ALIGNED(ptr) ;
#endif
+#if HAVE_BIGENDIAN
+#define load_alignment(s, ali, pm2, pm1, pp0, pp1, pp2, pp3){\
+ vec_u8 srcR1 = vec_ld(-2, s);\
+ vec_u8 srcR2 = vec_ld(14, s);\
+ switch (ali) {\
+ default: {\
+ srcM2 = vec_perm(srcR1, srcR2, pm2);\
+ srcM1 = vec_perm(srcR1, srcR2, pm1);\
+ srcP0 = vec_perm(srcR1, srcR2, pp0);\
+ srcP1 = vec_perm(srcR1, srcR2, pp1);\
+ srcP2 = vec_perm(srcR1, srcR2, pp2);\
+ srcP3 = vec_perm(srcR1, srcR2, pp3);\
+ } break;\
+ case 11: {\
+ srcM2 = vec_perm(srcR1, srcR2, pm2);\
+ srcM1 = vec_perm(srcR1, srcR2, pm1);\
+ srcP0 = vec_perm(srcR1, srcR2, pp0);\
+ srcP1 = vec_perm(srcR1, srcR2, pp1);\
+ srcP2 = vec_perm(srcR1, srcR2, pp2);\
+ srcP3 = srcR2;\
+ } break;\
+ case 12: {\
+ vec_u8 srcR3 = vec_ld(30, s);\
+ srcM2 = vec_perm(srcR1, srcR2, pm2);\
+ srcM1 = vec_perm(srcR1, srcR2, pm1);\
+ srcP0 = vec_perm(srcR1, srcR2, pp0);\
+ srcP1 = vec_perm(srcR1, srcR2, pp1);\
+ srcP2 = srcR2;\
+ srcP3 = vec_perm(srcR2, srcR3, pp3);\
+ } break;\
+ case 13: {\
+ vec_u8 srcR3 = vec_ld(30, s);\
+ srcM2 = vec_perm(srcR1, srcR2, pm2);\
+ srcM1 = vec_perm(srcR1, srcR2, pm1);\
+ srcP0 = vec_perm(srcR1, srcR2, pp0);\
+ srcP1 = srcR2;\
+ srcP2 = vec_perm(srcR2, srcR3, pp2);\
+ srcP3 = vec_perm(srcR2, srcR3, pp3);\
+ } break;\
+ case 14: {\
+ vec_u8 srcR3 = vec_ld(30, s);\
+ srcM2 = vec_perm(srcR1, srcR2, pm2);\
+ srcM1 = vec_perm(srcR1, srcR2, pm1);\
+ srcP0 = srcR2;\
+ srcP1 = vec_perm(srcR2, srcR3, pp1);\
+ srcP2 = vec_perm(srcR2, srcR3, pp2);\
+ srcP3 = vec_perm(srcR2, srcR3, pp3);\
+ } break;\
+ case 15: {\
+ vec_u8 srcR3 = vec_ld(30, s);\
+ srcM2 = vec_perm(srcR1, srcR2, pm2);\
+ srcM1 = srcR2;\
+ srcP0 = vec_perm(srcR2, srcR3, pp0);\
+ srcP1 = vec_perm(srcR2, srcR3, pp1);\
+ srcP2 = vec_perm(srcR2, srcR3, pp2);\
+ srcP3 = vec_perm(srcR2, srcR3, pp3);\
+ } break;\
+ }\
+ }
+#else
+#define load_alignment(s, ali, pm2, pm1, pp0, pp1, pp2, pp3){\
+ srcM2 = vec_vsx_ld(-2, s);\
+ srcM1 = vec_vsx_ld(-1, s);\
+ srcP0 = vec_vsx_ld(0, s);\
+ srcP1 = vec_vsx_ld(1, s);\
+ srcP2 = vec_vsx_ld(2, s);\
+ srcP3 = vec_vsx_ld(3, s);\
+ }
+#endif /* HAVE_BIGENDIAN */
+
/* this code assume stride % 16 == 0 */
#ifdef PREFIX_h264_qpel16_h_lowpass_altivec
static void PREFIX_h264_qpel16_h_lowpass_altivec(uint8_t *dst,
register int i;
LOAD_ZERO;
- const vec_u8 permM2 = vec_lvsl(-2, src);
- const vec_u8 permM1 = vec_lvsl(-1, src);
- const vec_u8 permP0 = vec_lvsl(+0, src);
- const vec_u8 permP1 = vec_lvsl(+1, src);
- const vec_u8 permP2 = vec_lvsl(+2, src);
- const vec_u8 permP3 = vec_lvsl(+3, src);
+ vec_u8 permM2, permM1, permP0, permP1, permP2, permP3;
const vec_s16 v5ss = vec_splat_s16(5);
const vec_u16 v5us = vec_splat_u16(5);
const vec_s16 v20ss = vec_sl(vec_splat_s16(5),vec_splat_u16(2));
vec_u8 sum, fsum;
+#if HAVE_BIGENDIAN
+ permM2 = vec_lvsl(-2, src);
+ permM1 = vec_lvsl(-1, src);
+ permP0 = vec_lvsl(+0, src);
+ permP1 = vec_lvsl(+1, src);
+ permP2 = vec_lvsl(+2, src);
+ permP3 = vec_lvsl(+3, src);
+#endif /* HAVE_BIGENDIAN */
+
for (i = 0 ; i < 16 ; i ++) {
- vec_u8 srcR1 = vec_ld(-2, src);
- vec_u8 srcR2 = vec_ld(14, src);
-
- switch (align) {
- default: {
- srcM2 = vec_perm(srcR1, srcR2, permM2);
- srcM1 = vec_perm(srcR1, srcR2, permM1);
- srcP0 = vec_perm(srcR1, srcR2, permP0);
- srcP1 = vec_perm(srcR1, srcR2, permP1);
- srcP2 = vec_perm(srcR1, srcR2, permP2);
- srcP3 = vec_perm(srcR1, srcR2, permP3);
- } break;
- case 11: {
- srcM2 = vec_perm(srcR1, srcR2, permM2);
- srcM1 = vec_perm(srcR1, srcR2, permM1);
- srcP0 = vec_perm(srcR1, srcR2, permP0);
- srcP1 = vec_perm(srcR1, srcR2, permP1);
- srcP2 = vec_perm(srcR1, srcR2, permP2);
- srcP3 = srcR2;
- } break;
- case 12: {
- vec_u8 srcR3 = vec_ld(30, src);
- srcM2 = vec_perm(srcR1, srcR2, permM2);
- srcM1 = vec_perm(srcR1, srcR2, permM1);
- srcP0 = vec_perm(srcR1, srcR2, permP0);
- srcP1 = vec_perm(srcR1, srcR2, permP1);
- srcP2 = srcR2;
- srcP3 = vec_perm(srcR2, srcR3, permP3);
- } break;
- case 13: {
- vec_u8 srcR3 = vec_ld(30, src);
- srcM2 = vec_perm(srcR1, srcR2, permM2);
- srcM1 = vec_perm(srcR1, srcR2, permM1);
- srcP0 = vec_perm(srcR1, srcR2, permP0);
- srcP1 = srcR2;
- srcP2 = vec_perm(srcR2, srcR3, permP2);
- srcP3 = vec_perm(srcR2, srcR3, permP3);
- } break;
- case 14: {
- vec_u8 srcR3 = vec_ld(30, src);
- srcM2 = vec_perm(srcR1, srcR2, permM2);
- srcM1 = vec_perm(srcR1, srcR2, permM1);
- srcP0 = srcR2;
- srcP1 = vec_perm(srcR2, srcR3, permP1);
- srcP2 = vec_perm(srcR2, srcR3, permP2);
- srcP3 = vec_perm(srcR2, srcR3, permP3);
- } break;
- case 15: {
- vec_u8 srcR3 = vec_ld(30, src);
- srcM2 = vec_perm(srcR1, srcR2, permM2);
- srcM1 = srcR2;
- srcP0 = vec_perm(srcR2, srcR3, permP0);
- srcP1 = vec_perm(srcR2, srcR3, permP1);
- srcP2 = vec_perm(srcR2, srcR3, permP2);
- srcP3 = vec_perm(srcR2, srcR3, permP3);
- } break;
- }
-
- srcP0A = (vec_s16) vec_mergeh(zero_u8v, srcP0);
- srcP0B = (vec_s16) vec_mergel(zero_u8v, srcP0);
- srcP1A = (vec_s16) vec_mergeh(zero_u8v, srcP1);
- srcP1B = (vec_s16) vec_mergel(zero_u8v, srcP1);
-
- srcP2A = (vec_s16) vec_mergeh(zero_u8v, srcP2);
- srcP2B = (vec_s16) vec_mergel(zero_u8v, srcP2);
- srcP3A = (vec_s16) vec_mergeh(zero_u8v, srcP3);
- srcP3B = (vec_s16) vec_mergel(zero_u8v, srcP3);
-
- srcM1A = (vec_s16) vec_mergeh(zero_u8v, srcM1);
- srcM1B = (vec_s16) vec_mergel(zero_u8v, srcM1);
- srcM2A = (vec_s16) vec_mergeh(zero_u8v, srcM2);
- srcM2B = (vec_s16) vec_mergel(zero_u8v, srcM2);
+ load_alignment(src, align, permM2, permM1, permP0, permP1, permP2, permP3);
+
+ srcP0A = (vec_s16) VEC_MERGEH(zero_u8v, srcP0);
+ srcP0B = (vec_s16) VEC_MERGEL(zero_u8v, srcP0);
+ srcP1A = (vec_s16) VEC_MERGEH(zero_u8v, srcP1);
+ srcP1B = (vec_s16) VEC_MERGEL(zero_u8v, srcP1);
+
+ srcP2A = (vec_s16) VEC_MERGEH(zero_u8v, srcP2);
+ srcP2B = (vec_s16) VEC_MERGEL(zero_u8v, srcP2);
+ srcP3A = (vec_s16) VEC_MERGEH(zero_u8v, srcP3);
+ srcP3B = (vec_s16) VEC_MERGEL(zero_u8v, srcP3);
+
+ srcM1A = (vec_s16) VEC_MERGEH(zero_u8v, srcM1);
+ srcM1B = (vec_s16) VEC_MERGEL(zero_u8v, srcM1);
+ srcM2A = (vec_s16) VEC_MERGEH(zero_u8v, srcM2);
+ srcM2B = (vec_s16) VEC_MERGEL(zero_u8v, srcM2);
sum1A = vec_adds(srcP0A, srcP1A);
sum1B = vec_adds(srcP0B, srcP1B);
register int i;
LOAD_ZERO;
- const vec_u8 perm = vec_lvsl(0, src);
+ vec_u8 perm;
+#if HAVE_BIGENDIAN
+ perm = vec_lvsl(0, src);
+#endif
const vec_s16 v20ss = vec_sl(vec_splat_s16(5),vec_splat_u16(2));
const vec_u16 v5us = vec_splat_u16(5);
const vec_s16 v5ss = vec_splat_s16(5);
const uint8_t *srcbis = src - (srcStride * 2);
- const vec_u8 srcM2a = vec_ld(0, srcbis);
- const vec_u8 srcM2b = vec_ld(16, srcbis);
- const vec_u8 srcM2 = vec_perm(srcM2a, srcM2b, perm);
- //srcbis += srcStride;
- const vec_u8 srcM1a = vec_ld(0, srcbis += srcStride);
- const vec_u8 srcM1b = vec_ld(16, srcbis);
- const vec_u8 srcM1 = vec_perm(srcM1a, srcM1b, perm);
- //srcbis += srcStride;
- const vec_u8 srcP0a = vec_ld(0, srcbis += srcStride);
- const vec_u8 srcP0b = vec_ld(16, srcbis);
- const vec_u8 srcP0 = vec_perm(srcP0a, srcP0b, perm);
- //srcbis += srcStride;
- const vec_u8 srcP1a = vec_ld(0, srcbis += srcStride);
- const vec_u8 srcP1b = vec_ld(16, srcbis);
- const vec_u8 srcP1 = vec_perm(srcP1a, srcP1b, perm);
- //srcbis += srcStride;
- const vec_u8 srcP2a = vec_ld(0, srcbis += srcStride);
- const vec_u8 srcP2b = vec_ld(16, srcbis);
- const vec_u8 srcP2 = vec_perm(srcP2a, srcP2b, perm);
- //srcbis += srcStride;
-
- vec_s16 srcM2ssA = (vec_s16) vec_mergeh(zero_u8v, srcM2);
- vec_s16 srcM2ssB = (vec_s16) vec_mergel(zero_u8v, srcM2);
- vec_s16 srcM1ssA = (vec_s16) vec_mergeh(zero_u8v, srcM1);
- vec_s16 srcM1ssB = (vec_s16) vec_mergel(zero_u8v, srcM1);
- vec_s16 srcP0ssA = (vec_s16) vec_mergeh(zero_u8v, srcP0);
- vec_s16 srcP0ssB = (vec_s16) vec_mergel(zero_u8v, srcP0);
- vec_s16 srcP1ssA = (vec_s16) vec_mergeh(zero_u8v, srcP1);
- vec_s16 srcP1ssB = (vec_s16) vec_mergel(zero_u8v, srcP1);
- vec_s16 srcP2ssA = (vec_s16) vec_mergeh(zero_u8v, srcP2);
- vec_s16 srcP2ssB = (vec_s16) vec_mergel(zero_u8v, srcP2);
+ const vec_u8 srcM2 = load_with_perm_vec(0, srcbis, perm);
+ srcbis += srcStride;
+ const vec_u8 srcM1 = load_with_perm_vec(0, srcbis, perm);
+ srcbis += srcStride;
+ const vec_u8 srcP0 = load_with_perm_vec(0, srcbis, perm);
+ srcbis += srcStride;
+ const vec_u8 srcP1 = load_with_perm_vec(0, srcbis, perm);
+ srcbis += srcStride;
+ const vec_u8 srcP2 = load_with_perm_vec(0, srcbis, perm);
+ srcbis += srcStride;
+
+ vec_s16 srcM2ssA = (vec_s16) VEC_MERGEH(zero_u8v, srcM2);
+ vec_s16 srcM2ssB = (vec_s16) VEC_MERGEL(zero_u8v, srcM2);
+ vec_s16 srcM1ssA = (vec_s16) VEC_MERGEH(zero_u8v, srcM1);
+ vec_s16 srcM1ssB = (vec_s16) VEC_MERGEL(zero_u8v, srcM1);
+ vec_s16 srcP0ssA = (vec_s16) VEC_MERGEH(zero_u8v, srcP0);
+ vec_s16 srcP0ssB = (vec_s16) VEC_MERGEL(zero_u8v, srcP0);
+ vec_s16 srcP1ssA = (vec_s16) VEC_MERGEH(zero_u8v, srcP1);
+ vec_s16 srcP1ssB = (vec_s16) VEC_MERGEL(zero_u8v, srcP1);
+ vec_s16 srcP2ssA = (vec_s16) VEC_MERGEH(zero_u8v, srcP2);
+ vec_s16 srcP2ssB = (vec_s16) VEC_MERGEL(zero_u8v, srcP2);
vec_s16 pp1A, pp1B, pp2A, pp2B, pp3A, pp3B,
psumA, psumB, sumA, sumB,
srcP3ssA, srcP3ssB,
sum1A, sum1B, sum2A, sum2B, sum3A, sum3B;
- vec_u8 sum, fsum, srcP3a, srcP3b, srcP3;
+ vec_u8 sum, fsum, srcP3;
for (i = 0 ; i < 16 ; i++) {
- srcP3a = vec_ld(0, srcbis += srcStride);
- srcP3b = vec_ld(16, srcbis);
- srcP3 = vec_perm(srcP3a, srcP3b, perm);
- srcP3ssA = (vec_s16) vec_mergeh(zero_u8v, srcP3);
- srcP3ssB = (vec_s16) vec_mergel(zero_u8v, srcP3);
- //srcbis += srcStride;
+ srcP3 = load_with_perm_vec(0, srcbis, perm);
+ srcbis += srcStride;
+
+ srcP3ssA = (vec_s16) VEC_MERGEH(zero_u8v, srcP3);
+ srcP3ssB = (vec_s16) VEC_MERGEL(zero_u8v, srcP3);
sum1A = vec_adds(srcP0ssA, srcP1ssA);
sum1B = vec_adds(srcP0ssB, srcP1ssB);
{
register int i;
LOAD_ZERO;
- const vec_u8 permM2 = vec_lvsl(-2, src);
- const vec_u8 permM1 = vec_lvsl(-1, src);
- const vec_u8 permP0 = vec_lvsl(+0, src);
- const vec_u8 permP1 = vec_lvsl(+1, src);
- const vec_u8 permP2 = vec_lvsl(+2, src);
- const vec_u8 permP3 = vec_lvsl(+3, src);
+ vec_u8 permM2, permM1, permP0, permP1, permP2, permP3;
const vec_s16 v20ss = vec_sl(vec_splat_s16(5),vec_splat_u16(2));
const vec_u32 v10ui = vec_splat_u32(10);
const vec_s16 v5ss = vec_splat_s16(5);
vec_u8 fsum, sumv, sum;
vec_s16 ssume, ssumo;
+#if HAVE_BIGENDIAN
+ permM2 = vec_lvsl(-2, src);
+ permM1 = vec_lvsl(-1, src);
+ permP0 = vec_lvsl(+0, src);
+ permP1 = vec_lvsl(+1, src);
+ permP2 = vec_lvsl(+2, src);
+ permP3 = vec_lvsl(+3, src);
+#endif /* HAVE_BIGENDIAN */
+
src -= (2 * srcStride);
for (i = 0 ; i < 21 ; i ++) {
vec_u8 srcM2, srcM1, srcP0, srcP1, srcP2, srcP3;
- vec_u8 srcR1 = vec_ld(-2, src);
- vec_u8 srcR2 = vec_ld(14, src);
-
- switch (align) {
- default: {
- srcM2 = vec_perm(srcR1, srcR2, permM2);
- srcM1 = vec_perm(srcR1, srcR2, permM1);
- srcP0 = vec_perm(srcR1, srcR2, permP0);
- srcP1 = vec_perm(srcR1, srcR2, permP1);
- srcP2 = vec_perm(srcR1, srcR2, permP2);
- srcP3 = vec_perm(srcR1, srcR2, permP3);
- } break;
- case 11: {
- srcM2 = vec_perm(srcR1, srcR2, permM2);
- srcM1 = vec_perm(srcR1, srcR2, permM1);
- srcP0 = vec_perm(srcR1, srcR2, permP0);
- srcP1 = vec_perm(srcR1, srcR2, permP1);
- srcP2 = vec_perm(srcR1, srcR2, permP2);
- srcP3 = srcR2;
- } break;
- case 12: {
- vec_u8 srcR3 = vec_ld(30, src);
- srcM2 = vec_perm(srcR1, srcR2, permM2);
- srcM1 = vec_perm(srcR1, srcR2, permM1);
- srcP0 = vec_perm(srcR1, srcR2, permP0);
- srcP1 = vec_perm(srcR1, srcR2, permP1);
- srcP2 = srcR2;
- srcP3 = vec_perm(srcR2, srcR3, permP3);
- } break;
- case 13: {
- vec_u8 srcR3 = vec_ld(30, src);
- srcM2 = vec_perm(srcR1, srcR2, permM2);
- srcM1 = vec_perm(srcR1, srcR2, permM1);
- srcP0 = vec_perm(srcR1, srcR2, permP0);
- srcP1 = srcR2;
- srcP2 = vec_perm(srcR2, srcR3, permP2);
- srcP3 = vec_perm(srcR2, srcR3, permP3);
- } break;
- case 14: {
- vec_u8 srcR3 = vec_ld(30, src);
- srcM2 = vec_perm(srcR1, srcR2, permM2);
- srcM1 = vec_perm(srcR1, srcR2, permM1);
- srcP0 = srcR2;
- srcP1 = vec_perm(srcR2, srcR3, permP1);
- srcP2 = vec_perm(srcR2, srcR3, permP2);
- srcP3 = vec_perm(srcR2, srcR3, permP3);
- } break;
- case 15: {
- vec_u8 srcR3 = vec_ld(30, src);
- srcM2 = vec_perm(srcR1, srcR2, permM2);
- srcM1 = srcR2;
- srcP0 = vec_perm(srcR2, srcR3, permP0);
- srcP1 = vec_perm(srcR2, srcR3, permP1);
- srcP2 = vec_perm(srcR2, srcR3, permP2);
- srcP3 = vec_perm(srcR2, srcR3, permP3);
- } break;
- }
-
- srcP0A = (vec_s16) vec_mergeh(zero_u8v, srcP0);
- srcP0B = (vec_s16) vec_mergel(zero_u8v, srcP0);
- srcP1A = (vec_s16) vec_mergeh(zero_u8v, srcP1);
- srcP1B = (vec_s16) vec_mergel(zero_u8v, srcP1);
-
- srcP2A = (vec_s16) vec_mergeh(zero_u8v, srcP2);
- srcP2B = (vec_s16) vec_mergel(zero_u8v, srcP2);
- srcP3A = (vec_s16) vec_mergeh(zero_u8v, srcP3);
- srcP3B = (vec_s16) vec_mergel(zero_u8v, srcP3);
-
- srcM1A = (vec_s16) vec_mergeh(zero_u8v, srcM1);
- srcM1B = (vec_s16) vec_mergel(zero_u8v, srcM1);
- srcM2A = (vec_s16) vec_mergeh(zero_u8v, srcM2);
- srcM2B = (vec_s16) vec_mergel(zero_u8v, srcM2);
+
+ load_alignment(src, align, permM2, permM1, permP0, permP1, permP2, permP3);
+
+ srcP0A = (vec_s16) VEC_MERGEH(zero_u8v, srcP0);
+ srcP0B = (vec_s16) VEC_MERGEL(zero_u8v, srcP0);
+ srcP1A = (vec_s16) VEC_MERGEH(zero_u8v, srcP1);
+ srcP1B = (vec_s16) VEC_MERGEL(zero_u8v, srcP1);
+
+ srcP2A = (vec_s16) VEC_MERGEH(zero_u8v, srcP2);
+ srcP2B = (vec_s16) VEC_MERGEL(zero_u8v, srcP2);
+ srcP3A = (vec_s16) VEC_MERGEH(zero_u8v, srcP3);
+ srcP3B = (vec_s16) VEC_MERGEL(zero_u8v, srcP3);
+
+ srcM1A = (vec_s16) VEC_MERGEH(zero_u8v, srcM1);
+ srcM1B = (vec_s16) VEC_MERGEL(zero_u8v, srcM1);
+ srcM2A = (vec_s16) VEC_MERGEH(zero_u8v, srcM2);
+ srcM2B = (vec_s16) VEC_MERGEL(zero_u8v, srcM2);
sum1A = vec_adds(srcP0A, srcP1A);
sum1B = vec_adds(srcP0B, srcP1B);
const vec_s16 sum1B = vec_adds(tmpP0ssB, tmpP1ssB);
const vec_s16 sum2A = vec_adds(tmpM1ssA, tmpP2ssA);
const vec_s16 sum2B = vec_adds(tmpM1ssB, tmpP2ssB);
- const vec_s16 sum3A = vec_adds(tmpM2ssA, tmpP3ssA);
- const vec_s16 sum3B = vec_adds(tmpM2ssB, tmpP3ssB);
+ vec_s16 sum3A = vec_adds(tmpM2ssA, tmpP3ssA);
+ vec_s16 sum3B = vec_adds(tmpM2ssB, tmpP3ssB);
tmpbis += tmpStride;
pp2Be = vec_mule(sum2B, v5ss);
pp2Bo = vec_mulo(sum2B, v5ss);
- pp3Ae = vec_sra((vec_s32)sum3A, v16ui);
pp3Ao = vec_mulo(sum3A, v1ss);
- pp3Be = vec_sra((vec_s32)sum3B, v16ui);
pp3Bo = vec_mulo(sum3B, v1ss);
+#if !HAVE_BIGENDIAN
+ sum3A = (vec_s16)vec_perm(sum3A, sum3A,vcswapi2s(0,1,2,3));
+ sum3B = (vec_s16)vec_perm(sum3B, sum3B,vcswapi2s(0,1,2,3));
+#endif
+ pp3Ae = vec_sra((vec_s32)sum3A, v16ui);
+ pp3Be = vec_sra((vec_s32)sum3B, v16ui);
pp1cAe = vec_add(pp1Ae, v512si);
pp1cAo = vec_add(pp1Ao, v512si);
/* next one assumes that ((line_size % 16) == 0) */
void ff_put_pixels16_altivec(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
{
- register vector unsigned char pixelsv1, pixelsv2;
- register vector unsigned char pixelsv1B, pixelsv2B;
- register vector unsigned char pixelsv1C, pixelsv2C;
- register vector unsigned char pixelsv1D, pixelsv2D;
+ register vector unsigned char pixelsv1;
+ register vector unsigned char pixelsv1B;
+ register vector unsigned char pixelsv1C;
+ register vector unsigned char pixelsv1D;
- register vector unsigned char perm = vec_lvsl(0, pixels);
int i;
register ptrdiff_t line_size_2 = line_size << 1;
register ptrdiff_t line_size_3 = line_size + line_size_2;
// -funroll-loops w/ this is bad - 74 cycles again.
// all this is on a 7450, tuning for the 7450
for (i = 0; i < h; i += 4) {
- pixelsv1 = vec_ld( 0, pixels);
- pixelsv2 = vec_ld(15, pixels);
- pixelsv1B = vec_ld(line_size, pixels);
- pixelsv2B = vec_ld(15 + line_size, pixels);
- pixelsv1C = vec_ld(line_size_2, pixels);
- pixelsv2C = vec_ld(15 + line_size_2, pixels);
- pixelsv1D = vec_ld(line_size_3, pixels);
- pixelsv2D = vec_ld(15 + line_size_3, pixels);
- vec_st(vec_perm(pixelsv1, pixelsv2, perm),
- 0, (unsigned char*)block);
- vec_st(vec_perm(pixelsv1B, pixelsv2B, perm),
- line_size, (unsigned char*)block);
- vec_st(vec_perm(pixelsv1C, pixelsv2C, perm),
- line_size_2, (unsigned char*)block);
- vec_st(vec_perm(pixelsv1D, pixelsv2D, perm),
- line_size_3, (unsigned char*)block);
+ pixelsv1 = unaligned_load( 0, pixels);
+ pixelsv1B = unaligned_load(line_size, pixels);
+ pixelsv1C = unaligned_load(line_size_2, pixels);
+ pixelsv1D = unaligned_load(line_size_3, pixels);
+ VEC_ST(pixelsv1, 0, (unsigned char*)block);
+ VEC_ST(pixelsv1B, line_size, (unsigned char*)block);
+ VEC_ST(pixelsv1C, line_size_2, (unsigned char*)block);
+ VEC_ST(pixelsv1D, line_size_3, (unsigned char*)block);
pixels+=line_size_4;
block +=line_size_4;
}
#define op_avg(a,b) a = ( ((a)|(b)) - ((((a)^(b))&0xFEFEFEFEUL)>>1) )
void ff_avg_pixels16_altivec(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
{
- register vector unsigned char pixelsv1, pixelsv2, pixelsv, blockv;
- register vector unsigned char perm = vec_lvsl(0, pixels);
- int i;
+ register vector unsigned char pixelsv, blockv;
+ int i;
for (i = 0; i < h; i++) {
- pixelsv1 = vec_ld( 0, pixels);
- pixelsv2 = vec_ld(16,pixels);
blockv = vec_ld(0, block);
- pixelsv = vec_perm(pixelsv1, pixelsv2, perm);
+ pixelsv = VEC_LD( 0, pixels);
blockv = vec_avg(blockv,pixelsv);
vec_st(blockv, 0, (unsigned char*)block);
pixels+=line_size;
int rightside = ((unsigned long)block & 0x0000000F);
blockv = vec_ld(0, block);
- pixelsv1 = vec_ld( 0, pixels);
- pixelsv2 = vec_ld(16, pixels);
- pixelsv = vec_perm(pixelsv1, pixelsv2, vec_lvsl(0, pixels));
+ pixelsv = VEC_LD( 0, pixels);
if (rightside) {
pixelsv = vec_perm(blockv, pixelsv, vcprm(0,1,s0,s1));
{
register int i;
register vector unsigned char pixelsv1, pixelsv2, pixelsavg;
- register vector unsigned char blockv, temp1, temp2;
+ register vector unsigned char blockv;
register vector unsigned short pixelssum1, pixelssum2, temp3;
register const vector unsigned char vczero = (const vector unsigned char)vec_splat_u8(0);
register const vector unsigned short vctwo = (const vector unsigned short)vec_splat_u16(2);
- temp1 = vec_ld(0, pixels);
- temp2 = vec_ld(16, pixels);
- pixelsv1 = vec_perm(temp1, temp2, vec_lvsl(0, pixels));
- if ((((unsigned long)pixels) & 0x0000000F) == 0x0000000F) {
- pixelsv2 = temp2;
- } else {
- pixelsv2 = vec_perm(temp1, temp2, vec_lvsl(1, pixels));
- }
- pixelsv1 = vec_mergeh(vczero, pixelsv1);
- pixelsv2 = vec_mergeh(vczero, pixelsv2);
+ pixelsv1 = VEC_LD(0, pixels);
+ pixelsv2 = VEC_LD(1, pixels);
+ pixelsv1 = VEC_MERGEH(vczero, pixelsv1);
+ pixelsv2 = VEC_MERGEH(vczero, pixelsv2);
+
pixelssum1 = vec_add((vector unsigned short)pixelsv1,
(vector unsigned short)pixelsv2);
pixelssum1 = vec_add(pixelssum1, vctwo);
int rightside = ((unsigned long)block & 0x0000000F);
blockv = vec_ld(0, block);
- temp1 = vec_ld(line_size, pixels);
- temp2 = vec_ld(line_size + 16, pixels);
- pixelsv1 = vec_perm(temp1, temp2, vec_lvsl(line_size, pixels));
- if (((((unsigned long)pixels) + line_size) & 0x0000000F) == 0x0000000F) {
- pixelsv2 = temp2;
- } else {
- pixelsv2 = vec_perm(temp1, temp2, vec_lvsl(line_size + 1, pixels));
- }
-
- pixelsv1 = vec_mergeh(vczero, pixelsv1);
- pixelsv2 = vec_mergeh(vczero, pixelsv2);
+ pixelsv1 = unaligned_load(line_size, pixels);
+ pixelsv2 = unaligned_load(line_size+1, pixels);
+ pixelsv1 = VEC_MERGEH(vczero, pixelsv1);
+ pixelsv2 = VEC_MERGEH(vczero, pixelsv2);
pixelssum2 = vec_add((vector unsigned short)pixelsv1,
(vector unsigned short)pixelsv2);
temp3 = vec_add(pixelssum1, pixelssum2);
{
register int i;
register vector unsigned char pixelsv1, pixelsv2, pixelsavg;
- register vector unsigned char blockv, temp1, temp2;
+ register vector unsigned char blockv;
register vector unsigned short pixelssum1, pixelssum2, temp3;
register const vector unsigned char vczero = (const vector unsigned char)vec_splat_u8(0);
register const vector unsigned short vcone = (const vector unsigned short)vec_splat_u16(1);
register const vector unsigned short vctwo = (const vector unsigned short)vec_splat_u16(2);
- temp1 = vec_ld(0, pixels);
- temp2 = vec_ld(16, pixels);
- pixelsv1 = vec_perm(temp1, temp2, vec_lvsl(0, pixels));
- if ((((unsigned long)pixels) & 0x0000000F) == 0x0000000F) {
- pixelsv2 = temp2;
- } else {
- pixelsv2 = vec_perm(temp1, temp2, vec_lvsl(1, pixels));
- }
- pixelsv1 = vec_mergeh(vczero, pixelsv1);
- pixelsv2 = vec_mergeh(vczero, pixelsv2);
+ pixelsv1 = VEC_LD(0, pixels);
+ pixelsv2 = VEC_LD(1, pixels);
+ pixelsv1 = VEC_MERGEH(vczero, pixelsv1);
+ pixelsv2 = VEC_MERGEH(vczero, pixelsv2);
pixelssum1 = vec_add((vector unsigned short)pixelsv1,
(vector unsigned short)pixelsv2);
pixelssum1 = vec_add(pixelssum1, vcone);
int rightside = ((unsigned long)block & 0x0000000F);
blockv = vec_ld(0, block);
- temp1 = vec_ld(line_size, pixels);
- temp2 = vec_ld(line_size + 16, pixels);
- pixelsv1 = vec_perm(temp1, temp2, vec_lvsl(line_size, pixels));
- if (((((unsigned long)pixels) + line_size) & 0x0000000F) == 0x0000000F) {
- pixelsv2 = temp2;
- } else {
- pixelsv2 = vec_perm(temp1, temp2, vec_lvsl(line_size + 1, pixels));
- }
-
- pixelsv1 = vec_mergeh(vczero, pixelsv1);
- pixelsv2 = vec_mergeh(vczero, pixelsv2);
+ pixelsv1 = unaligned_load(line_size, pixels);
+ pixelsv2 = unaligned_load(line_size+1, pixels);
+ pixelsv1 = VEC_MERGEH(vczero, pixelsv1);
+ pixelsv2 = VEC_MERGEH(vczero, pixelsv2);
pixelssum2 = vec_add((vector unsigned short)pixelsv1,
(vector unsigned short)pixelsv2);
temp3 = vec_add(pixelssum1, pixelssum2);
{
register int i;
register vector unsigned char pixelsv1, pixelsv2, pixelsv3, pixelsv4;
- register vector unsigned char blockv, temp1, temp2;
+ register vector unsigned char blockv;
register vector unsigned short temp3, temp4,
pixelssum1, pixelssum2, pixelssum3, pixelssum4;
register const vector unsigned char vczero = (const vector unsigned char)vec_splat_u8(0);
register const vector unsigned short vctwo = (const vector unsigned short)vec_splat_u16(2);
- temp1 = vec_ld(0, pixels);
- temp2 = vec_ld(16, pixels);
- pixelsv1 = vec_perm(temp1, temp2, vec_lvsl(0, pixels));
- if ((((unsigned long)pixels) & 0x0000000F) == 0x0000000F) {
- pixelsv2 = temp2;
- } else {
- pixelsv2 = vec_perm(temp1, temp2, vec_lvsl(1, pixels));
- }
- pixelsv3 = vec_mergel(vczero, pixelsv1);
- pixelsv4 = vec_mergel(vczero, pixelsv2);
- pixelsv1 = vec_mergeh(vczero, pixelsv1);
- pixelsv2 = vec_mergeh(vczero, pixelsv2);
+ pixelsv1 = VEC_LD(0, pixels);
+ pixelsv2 = VEC_LD(1, pixels);
+ pixelsv3 = VEC_MERGEL(vczero, pixelsv1);
+ pixelsv4 = VEC_MERGEL(vczero, pixelsv2);
+ pixelsv1 = VEC_MERGEH(vczero, pixelsv1);
+ pixelsv2 = VEC_MERGEH(vczero, pixelsv2);
pixelssum3 = vec_add((vector unsigned short)pixelsv3,
(vector unsigned short)pixelsv4);
pixelssum3 = vec_add(pixelssum3, vctwo);
for (i = 0; i < h ; i++) {
blockv = vec_ld(0, block);
- temp1 = vec_ld(line_size, pixels);
- temp2 = vec_ld(line_size + 16, pixels);
- pixelsv1 = vec_perm(temp1, temp2, vec_lvsl(line_size, pixels));
- if (((((unsigned long)pixels) + line_size) & 0x0000000F) == 0x0000000F) {
- pixelsv2 = temp2;
- } else {
- pixelsv2 = vec_perm(temp1, temp2, vec_lvsl(line_size + 1, pixels));
- }
-
- pixelsv3 = vec_mergel(vczero, pixelsv1);
- pixelsv4 = vec_mergel(vczero, pixelsv2);
- pixelsv1 = vec_mergeh(vczero, pixelsv1);
- pixelsv2 = vec_mergeh(vczero, pixelsv2);
+ pixelsv1 = unaligned_load(line_size, pixels);
+ pixelsv2 = unaligned_load(line_size+1, pixels);
+ pixelsv3 = VEC_MERGEL(vczero, pixelsv1);
+ pixelsv4 = VEC_MERGEL(vczero, pixelsv2);
+ pixelsv1 = VEC_MERGEH(vczero, pixelsv1);
+ pixelsv2 = VEC_MERGEH(vczero, pixelsv2);
pixelssum4 = vec_add((vector unsigned short)pixelsv3,
(vector unsigned short)pixelsv4);
pixelssum2 = vec_add((vector unsigned short)pixelsv1,
{
register int i;
register vector unsigned char pixelsv1, pixelsv2, pixelsv3, pixelsv4;
- register vector unsigned char blockv, temp1, temp2;
+ register vector unsigned char blockv;
register vector unsigned short temp3, temp4,
pixelssum1, pixelssum2, pixelssum3, pixelssum4;
register const vector unsigned char vczero = (const vector unsigned char)vec_splat_u8(0);
register const vector unsigned short vcone = (const vector unsigned short)vec_splat_u16(1);
register const vector unsigned short vctwo = (const vector unsigned short)vec_splat_u16(2);
- temp1 = vec_ld(0, pixels);
- temp2 = vec_ld(16, pixels);
- pixelsv1 = vec_perm(temp1, temp2, vec_lvsl(0, pixels));
- if ((((unsigned long)pixels) & 0x0000000F) == 0x0000000F) {
- pixelsv2 = temp2;
- } else {
- pixelsv2 = vec_perm(temp1, temp2, vec_lvsl(1, pixels));
- }
- pixelsv3 = vec_mergel(vczero, pixelsv1);
- pixelsv4 = vec_mergel(vczero, pixelsv2);
- pixelsv1 = vec_mergeh(vczero, pixelsv1);
- pixelsv2 = vec_mergeh(vczero, pixelsv2);
+ pixelsv1 = VEC_LD(0, pixels);
+ pixelsv2 = VEC_LD(1, pixels);
+ pixelsv3 = VEC_MERGEL(vczero, pixelsv1);
+ pixelsv4 = VEC_MERGEL(vczero, pixelsv2);
+ pixelsv1 = VEC_MERGEH(vczero, pixelsv1);
+ pixelsv2 = VEC_MERGEH(vczero, pixelsv2);
pixelssum3 = vec_add((vector unsigned short)pixelsv3,
(vector unsigned short)pixelsv4);
pixelssum3 = vec_add(pixelssum3, vcone);
pixelssum1 = vec_add(pixelssum1, vcone);
for (i = 0; i < h ; i++) {
- blockv = vec_ld(0, block);
-
- temp1 = vec_ld(line_size, pixels);
- temp2 = vec_ld(line_size + 16, pixels);
- pixelsv1 = vec_perm(temp1, temp2, vec_lvsl(line_size, pixels));
- if (((((unsigned long)pixels) + line_size) & 0x0000000F) == 0x0000000F) {
- pixelsv2 = temp2;
- } else {
- pixelsv2 = vec_perm(temp1, temp2, vec_lvsl(line_size + 1, pixels));
- }
-
- pixelsv3 = vec_mergel(vczero, pixelsv1);
- pixelsv4 = vec_mergel(vczero, pixelsv2);
- pixelsv1 = vec_mergeh(vczero, pixelsv1);
- pixelsv2 = vec_mergeh(vczero, pixelsv2);
+ pixelsv1 = unaligned_load(line_size, pixels);
+ pixelsv2 = unaligned_load(line_size+1, pixels);
+ pixelsv3 = VEC_MERGEL(vczero, pixelsv1);
+ pixelsv4 = VEC_MERGEL(vczero, pixelsv2);
+ pixelsv1 = VEC_MERGEH(vczero, pixelsv1);
+ pixelsv2 = VEC_MERGEH(vczero, pixelsv2);
pixelssum4 = vec_add((vector unsigned short)pixelsv3,
(vector unsigned short)pixelsv4);
pixelssum2 = vec_add((vector unsigned short)pixelsv1,
blockv = vec_packsu(temp3, temp4);
- vec_st(blockv, 0, block);
+ VEC_ST(blockv, 0, block);
block += line_size;
pixels += line_size;
{
register int i;
register vector unsigned char pixelsv1, pixelsv2, pixelsavg;
- register vector unsigned char blockv, temp1, temp2, blocktemp;
+ register vector unsigned char blockv, blocktemp;
register vector unsigned short pixelssum1, pixelssum2, temp3;
register const vector unsigned char vczero = (const vector unsigned char)
register const vector unsigned short vctwo = (const vector unsigned short)
vec_splat_u16(2);
- temp1 = vec_ld(0, pixels);
- temp2 = vec_ld(16, pixels);
- pixelsv1 = vec_perm(temp1, temp2, vec_lvsl(0, pixels));
- if ((((unsigned long)pixels) & 0x0000000F) == 0x0000000F) {
- pixelsv2 = temp2;
- } else {
- pixelsv2 = vec_perm(temp1, temp2, vec_lvsl(1, pixels));
- }
- pixelsv1 = vec_mergeh(vczero, pixelsv1);
- pixelsv2 = vec_mergeh(vczero, pixelsv2);
+ pixelsv1 = VEC_LD(0, pixels);
+ pixelsv2 = VEC_LD(1, pixels);
+ pixelsv1 = VEC_MERGEH(vczero, pixelsv1);
+ pixelsv2 = VEC_MERGEH(vczero, pixelsv2);
pixelssum1 = vec_add((vector unsigned short)pixelsv1,
(vector unsigned short)pixelsv2);
pixelssum1 = vec_add(pixelssum1, vctwo);
int rightside = ((unsigned long)block & 0x0000000F);
blockv = vec_ld(0, block);
- temp1 = vec_ld(line_size, pixels);
- temp2 = vec_ld(line_size + 16, pixels);
- pixelsv1 = vec_perm(temp1, temp2, vec_lvsl(line_size, pixels));
- if (((((unsigned long)pixels) + line_size) & 0x0000000F) == 0x0000000F) {
- pixelsv2 = temp2;
- } else {
- pixelsv2 = vec_perm(temp1, temp2, vec_lvsl(line_size + 1, pixels));
- }
+ pixelsv1 = unaligned_load(line_size, pixels);
+ pixelsv2 = unaligned_load(line_size+1, pixels);
- pixelsv1 = vec_mergeh(vczero, pixelsv1);
- pixelsv2 = vec_mergeh(vczero, pixelsv2);
+ pixelsv1 = VEC_MERGEH(vczero, pixelsv1);
+ pixelsv2 = VEC_MERGEH(vczero, pixelsv2);
pixelssum2 = vec_add((vector unsigned short)pixelsv1,
(vector unsigned short)pixelsv2);
temp3 = vec_add(pixelssum1, pixelssum2);
#include "libavutil/ppc/types_altivec.h"
#include "libavcodec/lossless_audiodsp.h"
+#if HAVE_BIGENDIAN
+#define GET_T(tt0,tt1,src,a,b){ \
+ a = vec_ld(16, src); \
+ tt0 = vec_perm(b, a, align); \
+ b = vec_ld(32, src); \
+ tt1 = vec_perm(a, b, align); \
+ }
+#else
+#define GET_T(tt0,tt1,src,a,b){ \
+ tt0 = vec_vsx_ld(0, src); \
+ tt1 = vec_vsx_ld(16, src); \
+ }
+#endif
+
#if HAVE_ALTIVEC
static int32_t scalarproduct_and_madd_int16_altivec(int16_t *v1,
const int16_t *v2,
LOAD_ZERO;
vec_s16 *pv1 = (vec_s16 *) v1;
register vec_s16 muls = { mul, mul, mul, mul, mul, mul, mul, mul };
- register vec_s16 t0, t1, i0, i1, i4;
- register vec_s16 i2 = vec_ld(0, v2), i3 = vec_ld(0, v3);
+ register vec_s16 t0, t1, i0, i1, i4, i2, i3;
register vec_s32 res = zero_s32v;
+#if HAVE_BIGENDIAN
register vec_u8 align = vec_lvsl(0, v2);
+ i2 = vec_ld(0, v2);
+ i3 = vec_ld(0, v3);
+#endif
int32_t ires;
order >>= 4;
do {
- i1 = vec_ld(16, v2);
- t0 = vec_perm(i2, i1, align);
- i2 = vec_ld(32, v2);
- t1 = vec_perm(i1, i2, align);
+ GET_T(t0,t1,v2,i1,i2);
i0 = pv1[0];
i1 = pv1[1];
res = vec_msum(t0, i0, res);
res = vec_msum(t1, i1, res);
- i4 = vec_ld(16, v3);
- t0 = vec_perm(i3, i4, align);
- i3 = vec_ld(32, v3);
- t1 = vec_perm(i4, i3, align);
+ GET_T(t0,t1,v3,i4,i3);
pv1[0] = vec_mladd(t0, muls, i0);
pv1[1] = vec_mladd(t1, muls, i1);
pv1 += 2;
#include "libavcodec/me_cmp.h"
#if HAVE_ALTIVEC
+
+#if HAVE_BIGENDIAN
+#define GET_PERM(per1, per2, pix) {\
+ per1 = vec_lvsl(0, pix);\
+ per2 = vec_add(per1, vec_splat_u8(1));\
+}
+#define LOAD_PIX(v, iv, pix, per1, per2) {\
+ vector unsigned char pix2l = vec_ld(0, pix);\
+ vector unsigned char pix2r = vec_ld(16, pix);\
+ v = vec_perm(pix2l, pix2r, per1);\
+ iv = vec_perm(pix2l, pix2r, per2);\
+}
+#else
+#define GET_PERM(per1, per2, pix) {}
+#define LOAD_PIX(v, iv, pix, per1, per2) {\
+ v = vec_vsx_ld(0, pix);\
+ iv = vec_vsx_ld(1, pix);\
+}
+#endif
static int sad16_x2_altivec(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
- int line_size, int h)
+ ptrdiff_t stride, int h)
{
- int i, s = 0;
+ int i;
+ int __attribute__((aligned(16))) s = 0;
const vector unsigned char zero =
(const vector unsigned char) vec_splat_u8(0);
- vector unsigned char perm1 = vec_lvsl(0, pix2);
- vector unsigned char perm2 = vec_add(perm1, vec_splat_u8(1));
vector unsigned int sad = (vector unsigned int) vec_splat_u32(0);
vector signed int sumdiffs;
+ vector unsigned char perm1, perm2, pix2v, pix2iv;
+ GET_PERM(perm1, perm2, pix2);
for (i = 0; i < h; i++) {
/* Read unaligned pixels into our vectors. The vectors are as follows:
* pix1v: pix1[0] - pix1[15]
* pix2v: pix2[0] - pix2[15] pix2iv: pix2[1] - pix2[16] */
vector unsigned char pix1v = vec_ld(0, pix1);
- vector unsigned char pix2l = vec_ld(0, pix2);
- vector unsigned char pix2r = vec_ld(16, pix2);
- vector unsigned char pix2v = vec_perm(pix2l, pix2r, perm1);
- vector unsigned char pix2iv = vec_perm(pix2l, pix2r, perm2);
+ LOAD_PIX(pix2v, pix2iv, pix2, perm1, perm2);
/* Calculate the average vector. */
vector unsigned char avgv = vec_avg(pix2v, pix2iv);
/* Add each 4 pixel group together and put 4 results into sad. */
sad = vec_sum4s(t5, sad);
- pix1 += line_size;
- pix2 += line_size;
+ pix1 += stride;
+ pix2 += stride;
}
/* Sum up the four partial sums, and put the result into s. */
sumdiffs = vec_sums((vector signed int) sad, (vector signed int) zero);
}
static int sad16_y2_altivec(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
- int line_size, int h)
+ ptrdiff_t stride, int h)
{
- int i, s = 0;
+ int i;
+ int __attribute__((aligned(16))) s = 0;
const vector unsigned char zero =
(const vector unsigned char) vec_splat_u8(0);
- vector unsigned char perm = vec_lvsl(0, pix2);
vector unsigned char pix1v, pix3v, avgv, t5;
vector unsigned int sad = (vector unsigned int) vec_splat_u32(0);
vector signed int sumdiffs;
- uint8_t *pix3 = pix2 + line_size;
- /* Due to the fact that pix3 = pix2 + line_size, the pix3 of one
+ uint8_t *pix3 = pix2 + stride;
+
+ /* Due to the fact that pix3 = pix2 + stride, the pix3 of one
* iteration becomes pix2 in the next iteration. We can use this
* fact to avoid a potentially expensive unaligned read, each
* time around the loop.
* Read unaligned pixels into our vectors. The vectors are as follows:
* pix2v: pix2[0] - pix2[15]
* Split the pixel vectors into shorts. */
- vector unsigned char pix2l = vec_ld(0, pix2);
- vector unsigned char pix2r = vec_ld(15, pix2);
- vector unsigned char pix2v = vec_perm(pix2l, pix2r, perm);
+ vector unsigned char pix2v = VEC_LD(0, pix2);
for (i = 0; i < h; i++) {
/* Read unaligned pixels into our vectors. The vectors are as follows:
* pix1v: pix1[0] - pix1[15]
* pix3v: pix3[0] - pix3[15] */
pix1v = vec_ld(0, pix1);
-
- pix2l = vec_ld(0, pix3);
- pix2r = vec_ld(15, pix3);
- pix3v = vec_perm(pix2l, pix2r, perm);
+ pix3v = VEC_LD(0, pix3);
/* Calculate the average vector. */
avgv = vec_avg(pix2v, pix3v);
/* Add each 4 pixel group together and put 4 results into sad. */
sad = vec_sum4s(t5, sad);
- pix1 += line_size;
+ pix1 += stride;
pix2v = pix3v;
- pix3 += line_size;
+ pix3 += stride;
}
/* Sum up the four partial sums, and put the result into s. */
}
static int sad16_xy2_altivec(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
- int line_size, int h)
+ ptrdiff_t stride, int h)
{
- int i, s = 0;
- uint8_t *pix3 = pix2 + line_size;
+ int i;
+ int __attribute__((aligned(16))) s = 0;
+ uint8_t *pix3 = pix2 + stride;
const vector unsigned char zero =
(const vector unsigned char) vec_splat_u8(0);
const vector unsigned short two =
(const vector unsigned short) vec_splat_u16(2);
vector unsigned char avgv, t5;
- vector unsigned char perm1 = vec_lvsl(0, pix2);
- vector unsigned char perm2 = vec_add(perm1, vec_splat_u8(1));
vector unsigned char pix1v, pix3v, pix3iv;
vector unsigned short pix3lv, pix3hv, pix3ilv, pix3ihv;
vector unsigned short avghv, avglv;
vector unsigned int sad = (vector unsigned int) vec_splat_u32(0);
vector signed int sumdiffs;
+ vector unsigned char perm1, perm2, pix2v, pix2iv;
+ GET_PERM(perm1, perm2, pix2);
- /* Due to the fact that pix3 = pix2 + line_size, the pix3 of one
+ /* Due to the fact that pix3 = pix2 + stride, the pix3 of one
* iteration becomes pix2 in the next iteration. We can use this
* fact to avoid a potentially expensive unaligned read, as well
* as some splitting, and vector addition each time around the loop.
* Read unaligned pixels into our vectors. The vectors are as follows:
* pix2v: pix2[0] - pix2[15] pix2iv: pix2[1] - pix2[16]
* Split the pixel vectors into shorts. */
- vector unsigned char pix2l = vec_ld(0, pix2);
- vector unsigned char pix2r = vec_ld(16, pix2);
- vector unsigned char pix2v = vec_perm(pix2l, pix2r, perm1);
- vector unsigned char pix2iv = vec_perm(pix2l, pix2r, perm2);
-
+ LOAD_PIX(pix2v, pix2iv, pix2, perm1, perm2);
vector unsigned short pix2hv =
- (vector unsigned short) vec_mergeh(zero, pix2v);
+ (vector unsigned short) VEC_MERGEH(zero, pix2v);
vector unsigned short pix2lv =
- (vector unsigned short) vec_mergel(zero, pix2v);
+ (vector unsigned short) VEC_MERGEL(zero, pix2v);
vector unsigned short pix2ihv =
- (vector unsigned short) vec_mergeh(zero, pix2iv);
+ (vector unsigned short) VEC_MERGEH(zero, pix2iv);
vector unsigned short pix2ilv =
- (vector unsigned short) vec_mergel(zero, pix2iv);
+ (vector unsigned short) VEC_MERGEL(zero, pix2iv);
+
vector unsigned short t1 = vec_add(pix2hv, pix2ihv);
vector unsigned short t2 = vec_add(pix2lv, pix2ilv);
vector unsigned short t3, t4;
* pix1v: pix1[0] - pix1[15]
* pix3v: pix3[0] - pix3[15] pix3iv: pix3[1] - pix3[16] */
pix1v = vec_ld(0, pix1);
-
- pix2l = vec_ld(0, pix3);
- pix2r = vec_ld(16, pix3);
- pix3v = vec_perm(pix2l, pix2r, perm1);
- pix3iv = vec_perm(pix2l, pix2r, perm2);
+ LOAD_PIX(pix3v, pix3iv, pix3, perm1, perm2);
/* Note that AltiVec does have vec_avg, but this works on vector pairs
* and rounds up. We could do avg(avg(a, b), avg(c, d)), but the
* vectors of shorts and do the averaging by hand. */
/* Split the pixel vectors into shorts. */
- pix3hv = (vector unsigned short) vec_mergeh(zero, pix3v);
- pix3lv = (vector unsigned short) vec_mergel(zero, pix3v);
- pix3ihv = (vector unsigned short) vec_mergeh(zero, pix3iv);
- pix3ilv = (vector unsigned short) vec_mergel(zero, pix3iv);
+ pix3hv = (vector unsigned short) VEC_MERGEH(zero, pix3v);
+ pix3lv = (vector unsigned short) VEC_MERGEL(zero, pix3v);
+ pix3ihv = (vector unsigned short) VEC_MERGEH(zero, pix3iv);
+ pix3ilv = (vector unsigned short) VEC_MERGEL(zero, pix3iv);
/* Do the averaging on them. */
t3 = vec_add(pix3hv, pix3ihv);
/* Add each 4 pixel group together and put 4 results into sad. */
sad = vec_sum4s(t5, sad);
- pix1 += line_size;
- pix3 += line_size;
+ pix1 += stride;
+ pix3 += stride;
/* Transfer the calculated values for pix3 into pix2. */
t1 = t3;
t2 = t4;
}
static int sad16_altivec(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
- int line_size, int h)
+ ptrdiff_t stride, int h)
{
- int i, s;
+ int i;
+ int __attribute__((aligned(16))) s;
const vector unsigned int zero =
(const vector unsigned int) vec_splat_u32(0);
- vector unsigned char perm = vec_lvsl(0, pix2);
vector unsigned int sad = (vector unsigned int) vec_splat_u32(0);
vector signed int sumdiffs;
for (i = 0; i < h; i++) {
/* Read potentially unaligned pixels into t1 and t2. */
- vector unsigned char pix2l = vec_ld(0, pix2);
- vector unsigned char pix2r = vec_ld(15, pix2);
- vector unsigned char t1 = vec_ld(0, pix1);
- vector unsigned char t2 = vec_perm(pix2l, pix2r, perm);
+ vector unsigned char t1 =vec_ld(0, pix1);
+ vector unsigned char t2 = VEC_LD(0, pix2);
/* Calculate a sum of abs differences vector. */
vector unsigned char t3 = vec_max(t1, t2);
/* Add each 4 pixel group together and put 4 results into sad. */
sad = vec_sum4s(t5, sad);
- pix1 += line_size;
- pix2 += line_size;
+ pix1 += stride;
+ pix2 += stride;
}
/* Sum up the four partial sums, and put the result into s. */
}
static int sad8_altivec(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
- int line_size, int h)
+ ptrdiff_t stride, int h)
{
- int i, s;
+ int i;
+ int __attribute__((aligned(16))) s;
const vector unsigned int zero =
(const vector unsigned int) vec_splat_u32(0);
const vector unsigned char permclear =
(vector unsigned char)
{ 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0 };
- vector unsigned char perm1 = vec_lvsl(0, pix1);
- vector unsigned char perm2 = vec_lvsl(0, pix2);
vector unsigned int sad = (vector unsigned int) vec_splat_u32(0);
vector signed int sumdiffs;
/* Read potentially unaligned pixels into t1 and t2.
* Since we're reading 16 pixels, and actually only want 8,
* mask out the last 8 pixels. The 0s don't change the sum. */
- vector unsigned char pix1l = vec_ld(0, pix1);
- vector unsigned char pix1r = vec_ld(7, pix1);
- vector unsigned char pix2l = vec_ld(0, pix2);
- vector unsigned char pix2r = vec_ld(7, pix2);
- vector unsigned char t1 = vec_and(vec_perm(pix1l, pix1r, perm1),
- permclear);
- vector unsigned char t2 = vec_and(vec_perm(pix2l, pix2r, perm2),
- permclear);
+ vector unsigned char pix1l = VEC_LD(0, pix1);
+ vector unsigned char pix2l = VEC_LD(0, pix2);
+ vector unsigned char t1 = vec_and(pix1l, permclear);
+ vector unsigned char t2 = vec_and(pix2l, permclear);
/* Calculate a sum of abs differences vector. */
vector unsigned char t3 = vec_max(t1, t2);
/* Add each 4 pixel group together and put 4 results into sad. */
sad = vec_sum4s(t5, sad);
- pix1 += line_size;
- pix2 += line_size;
+ pix1 += stride;
+ pix2 += stride;
}
/* Sum up the four partial sums, and put the result into s. */
/* Sum of Squared Errors for an 8x8 block, AltiVec-enhanced.
* It's the sad8_altivec code above w/ squaring added. */
static int sse8_altivec(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
- int line_size, int h)
+ ptrdiff_t stride, int h)
{
- int i, s;
+ int i;
+ int __attribute__((aligned(16))) s;
const vector unsigned int zero =
(const vector unsigned int) vec_splat_u32(0);
const vector unsigned char permclear =
(vector unsigned char)
{ 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0 };
- vector unsigned char perm1 = vec_lvsl(0, pix1);
- vector unsigned char perm2 = vec_lvsl(0, pix2);
vector unsigned int sum = (vector unsigned int) vec_splat_u32(0);
vector signed int sumsqr;
/* Read potentially unaligned pixels into t1 and t2.
* Since we're reading 16 pixels, and actually only want 8,
* mask out the last 8 pixels. The 0s don't change the sum. */
- vector unsigned char pix1l = vec_ld(0, pix1);
- vector unsigned char pix1r = vec_ld(7, pix1);
- vector unsigned char pix2l = vec_ld(0, pix2);
- vector unsigned char pix2r = vec_ld(7, pix2);
- vector unsigned char t1 = vec_and(vec_perm(pix1l, pix1r, perm1),
- permclear);
- vector unsigned char t2 = vec_and(vec_perm(pix2l, pix2r, perm2),
- permclear);
+ vector unsigned char t1 = vec_and(VEC_LD(0, pix1), permclear);
+ vector unsigned char t2 = vec_and(VEC_LD(0, pix2), permclear);
/* Since we want to use unsigned chars, we can take advantage
* of the fact that abs(a - b) ^ 2 = (a - b) ^ 2. */
/* Square the values and add them to our sum. */
sum = vec_msum(t5, t5, sum);
- pix1 += line_size;
- pix2 += line_size;
+ pix1 += stride;
+ pix2 += stride;
}
/* Sum up the four partial sums, and put the result into s. */
/* Sum of Squared Errors for a 16x16 block, AltiVec-enhanced.
* It's the sad16_altivec code above w/ squaring added. */
static int sse16_altivec(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
- int line_size, int h)
+ ptrdiff_t stride, int h)
{
- int i, s;
+ int i;
+ int __attribute__((aligned(16))) s;
const vector unsigned int zero =
(const vector unsigned int) vec_splat_u32(0);
- vector unsigned char perm = vec_lvsl(0, pix2);
vector unsigned int sum = (vector unsigned int) vec_splat_u32(0);
vector signed int sumsqr;
for (i = 0; i < h; i++) {
/* Read potentially unaligned pixels into t1 and t2. */
- vector unsigned char pix2l = vec_ld(0, pix2);
- vector unsigned char pix2r = vec_ld(15, pix2);
vector unsigned char t1 = vec_ld(0, pix1);
- vector unsigned char t2 = vec_perm(pix2l, pix2r, perm);
+ vector unsigned char t2 = VEC_LD(0, pix2);
/* Since we want to use unsigned chars, we can take advantage
* of the fact that abs(a - b) ^ 2 = (a - b) ^ 2. */
/* Square the values and add them to our sum. */
sum = vec_msum(t5, t5, sum);
- pix1 += line_size;
- pix2 += line_size;
+ pix1 += stride;
+ pix2 += stride;
}
/* Sum up the four partial sums, and put the result into s. */
sumsqr = vec_sums((vector signed int) sum, (vector signed int) zero);
sumsqr = vec_splat(sumsqr, 3);
- vec_ste(sumsqr, 0, &s);
+ vec_ste(sumsqr, 0, &s);
return s;
}
static int hadamard8_diff8x8_altivec(MpegEncContext *s, uint8_t *dst,
- uint8_t *src, int stride, int h)
+ uint8_t *src, ptrdiff_t stride, int h)
{
- int sum;
+ int __attribute__((aligned(16))) sum;
register const vector unsigned char vzero =
(const vector unsigned char) vec_splat_u8(0);
register vector signed short temp0, temp1, temp2, temp3, temp4,
{ 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 };
+
#define ONEITERBUTTERFLY(i, res) \
{ \
- register vector unsigned char src1 = vec_ld(stride * i, src); \
- register vector unsigned char src2 = vec_ld(stride * i + 15, src); \
- register vector unsigned char srcO = \
- vec_perm(src1, src2, vec_lvsl(stride * i, src)); \
- register vector unsigned char dst1 = vec_ld(stride * i, dst); \
- register vector unsigned char dst2 = vec_ld(stride * i + 15, dst); \
- register vector unsigned char dstO = \
- vec_perm(dst1, dst2, vec_lvsl(stride * i, dst)); \
+ register vector unsigned char srcO = unaligned_load(stride * i, src); \
+ register vector unsigned char dstO = unaligned_load(stride * i, dst);\
\
/* Promote the unsigned chars to signed shorts. */ \
/* We're in the 8x8 function, we only care for the first 8. */ \
register vector signed short srcV = \
- (vector signed short) vec_mergeh((vector signed char) vzero, \
+ (vector signed short) VEC_MERGEH((vector signed char) vzero, \
(vector signed char) srcO); \
register vector signed short dstV = \
- (vector signed short) vec_mergeh((vector signed char) vzero, \
+ (vector signed short) VEC_MERGEH((vector signed char) vzero, \
(vector signed char) dstO); \
\
/* subtractions inside the first butterfly */ \
register vector signed short op3 = vec_perm(but2, but2, perm3); \
res = vec_mladd(but2, vprod3, op3); \
}
+
ONEITERBUTTERFLY(0, temp0);
ONEITERBUTTERFLY(1, temp1);
ONEITERBUTTERFLY(2, temp2);
vsum = vec_sum4s(vec_abs(line7C), vsum);
vsum = vec_sums(vsum, (vector signed int) vzero);
vsum = vec_splat(vsum, 3);
+
vec_ste(vsum, 0, &sum);
}
return sum;
* but xlc goes to around 660 on the regular C code...
*/
static int hadamard8_diff16x8_altivec(MpegEncContext *s, uint8_t *dst,
- uint8_t *src, int stride, int h)
+ uint8_t *src, ptrdiff_t stride, int h)
{
- int sum;
+ int __attribute__((aligned(16))) sum;
register vector signed short
temp0 __asm__ ("v0"),
temp1 __asm__ ("v1"),
#define ONEITERBUTTERFLY(i, res1, res2) \
{ \
- register vector unsigned char src1 __asm__ ("v22") = \
- vec_ld(stride * i, src); \
- register vector unsigned char src2 __asm__ ("v23") = \
- vec_ld(stride * i + 16, src); \
register vector unsigned char srcO __asm__ ("v22") = \
- vec_perm(src1, src2, vec_lvsl(stride * i, src)); \
- register vector unsigned char dst1 __asm__ ("v24") = \
- vec_ld(stride * i, dst); \
- register vector unsigned char dst2 __asm__ ("v25") = \
- vec_ld(stride * i + 16, dst); \
+ unaligned_load(stride * i, src); \
register vector unsigned char dstO __asm__ ("v23") = \
- vec_perm(dst1, dst2, vec_lvsl(stride * i, dst)); \
+ unaligned_load(stride * i, dst);\
\
/* Promote the unsigned chars to signed shorts. */ \
register vector signed short srcV __asm__ ("v24") = \
- (vector signed short) vec_mergeh((vector signed char) vzero, \
+ (vector signed short) VEC_MERGEH((vector signed char) vzero, \
(vector signed char) srcO); \
register vector signed short dstV __asm__ ("v25") = \
- (vector signed short) vec_mergeh((vector signed char) vzero, \
+ (vector signed short) VEC_MERGEH((vector signed char) vzero, \
(vector signed char) dstO); \
register vector signed short srcW __asm__ ("v26") = \
- (vector signed short) vec_mergel((vector signed char) vzero, \
+ (vector signed short) VEC_MERGEL((vector signed char) vzero, \
(vector signed char) srcO); \
register vector signed short dstW __asm__ ("v27") = \
- (vector signed short) vec_mergel((vector signed char) vzero, \
+ (vector signed short) VEC_MERGEL((vector signed char) vzero, \
(vector signed char) dstO); \
\
/* subtractions inside the first butterfly */ \
res1 = vec_mladd(but2, vprod3, op3); \
res2 = vec_mladd(but2S, vprod3, op3S); \
}
+
ONEITERBUTTERFLY(0, temp0, temp0S);
ONEITERBUTTERFLY(1, temp1, temp1S);
ONEITERBUTTERFLY(2, temp2, temp2S);
vsum = vec_sum4s(vec_abs(line7CS), vsum);
vsum = vec_sums(vsum, (vector signed int) vzero);
vsum = vec_splat(vsum, 3);
+
vec_ste(vsum, 0, &sum);
}
return sum;
}
static int hadamard8_diff16_altivec(MpegEncContext *s, uint8_t *dst,
- uint8_t *src, int stride, int h)
+ uint8_t *src, ptrdiff_t stride, int h)
{
int score = hadamard8_diff16x8_altivec(s, dst, src, stride, 8);
#if HAVE_ALTIVEC
+#if HAVE_VSX
+static int pix_norm1_altivec(uint8_t *pix, int line_size)
+{
+ int i, s = 0;
+ const vector unsigned int zero =
+ (const vector unsigned int) vec_splat_u32(0);
+ vector unsigned int sv = (vector unsigned int) vec_splat_u32(0);
+ vector signed int sum;
+
+ for (i = 0; i < 16; i++) {
+ /* Read the potentially unaligned pixels. */
+ //vector unsigned char pixl = vec_ld(0, pix);
+ //vector unsigned char pixr = vec_ld(15, pix);
+ //vector unsigned char pixv = vec_perm(pixl, pixr, perm);
+ vector unsigned char pixv = vec_vsx_ld(0, pix);
+
+ /* Square the values, and add them to our sum. */
+ sv = vec_msum(pixv, pixv, sv);
+
+ pix += line_size;
+ }
+ /* Sum up the four partial sums, and put the result into s. */
+ sum = vec_sums((vector signed int) sv, (vector signed int) zero);
+ sum = vec_splat(sum, 3);
+ vec_vsx_st(sum, 0, &s);
+ return s;
+}
+#else
static int pix_norm1_altivec(uint8_t *pix, int line_size)
{
int i, s = 0;
return s;
}
+#endif /* HAVE_VSX */
+
+#if HAVE_VSX
+static int pix_sum_altivec(uint8_t *pix, int line_size)
+{
+ int i, s;
+ const vector unsigned int zero =
+ (const vector unsigned int) vec_splat_u32(0);
+ vector unsigned int sad = (vector unsigned int) vec_splat_u32(0);
+ vector signed int sumdiffs;
+
+ for (i = 0; i < 16; i++) {
+ /* Read the potentially unaligned 16 pixels into t1. */
+ //vector unsigned char pixl = vec_ld(0, pix);
+ //vector unsigned char pixr = vec_ld(15, pix);
+ //vector unsigned char t1 = vec_perm(pixl, pixr, perm);
+ vector unsigned char t1 = vec_vsx_ld(0, pix);
+
+ /* Add each 4 pixel group together and put 4 results into sad. */
+ sad = vec_sum4s(t1, sad);
+
+ pix += line_size;
+ }
+ /* Sum up the four partial sums, and put the result into s. */
+ sumdiffs = vec_sums((vector signed int) sad, (vector signed int) zero);
+ sumdiffs = vec_splat(sumdiffs, 3);
+ vec_vsx_st(sumdiffs, 0, &s);
+ return s;
+}
+#else
static int pix_sum_altivec(uint8_t *pix, int line_size)
{
int i, s;
return s;
}
+#endif /* HAVE_VSX */
+
#endif /* HAVE_ALTIVEC */
av_cold void ff_mpegvideoencdsp_init_ppc(MpegvideoEncDSPContext *c,
#if HAVE_ALTIVEC
+#if HAVE_VSX
+static void get_pixels_altivec(int16_t *restrict block, const uint8_t *pixels,
+ ptrdiff_t line_size)
+{
+ int i;
+ vector unsigned char perm =
+ (vector unsigned char) {0x00,0x10, 0x01,0x11,0x02,0x12,0x03,0x13,\
+ 0x04,0x14,0x05,0x15,0x06,0x16,0x07,0x17};
+ const vector unsigned char zero =
+ (const vector unsigned char) vec_splat_u8(0);
+
+ for (i = 0; i < 8; i++) {
+ /* Read potentially unaligned pixels.
+ * We're reading 16 pixels, and actually only want 8,
+ * but we simply ignore the extras. */
+ vector unsigned char bytes = vec_vsx_ld(0, pixels);
+
+ // Convert the bytes into shorts.
+ //vector signed short shorts = (vector signed short) vec_perm(zero, bytes, perm);
+ vector signed short shorts = (vector signed short) vec_perm(bytes, zero, perm);
+
+ // Save the data to the block, we assume the block is 16-byte aligned.
+ vec_vsx_st(shorts, i * 16, (vector signed short *) block);
+
+ pixels += line_size;
+ }
+}
+#else
static void get_pixels_altivec(int16_t *restrict block, const uint8_t *pixels,
ptrdiff_t line_size)
{
}
}
+#endif /* HAVE_VSX */
+
+#if HAVE_VSX
+static void diff_pixels_altivec(int16_t *restrict block, const uint8_t *s1,
+ const uint8_t *s2, int stride)
+{
+ int i;
+ const vector unsigned char zero =
+ (const vector unsigned char) vec_splat_u8(0);
+ vector signed short shorts1, shorts2;
+
+ for (i = 0; i < 4; i++) {
+ /* Read potentially unaligned pixels.
+ * We're reading 16 pixels, and actually only want 8,
+ * but we simply ignore the extras. */
+ vector unsigned char bytes = vec_vsx_ld(0, s1);
+
+ // Convert the bytes into shorts.
+ shorts1 = (vector signed short) vec_mergeh(bytes, zero);
+
+ // Do the same for the second block of pixels.
+ bytes =vec_vsx_ld(0, s2);
+
+ // Convert the bytes into shorts.
+ shorts2 = (vector signed short) vec_mergeh(bytes, zero);
+
+ // Do the subtraction.
+ shorts1 = vec_sub(shorts1, shorts2);
+
+ // Save the data to the block, we assume the block is 16-byte aligned.
+ vec_vsx_st(shorts1, 0, (vector signed short *) block);
+
+ s1 += stride;
+ s2 += stride;
+ block += 8;
+
+ /* The code below is a copy of the code above...
+ * This is a manual unroll. */
+
+ /* Read potentially unaligned pixels.
+ * We're reading 16 pixels, and actually only want 8,
+ * but we simply ignore the extras. */
+ bytes = vec_vsx_ld(0, s1);
+
+ // Convert the bytes into shorts.
+ shorts1 = (vector signed short) vec_mergeh(bytes, zero);
+
+ // Do the same for the second block of pixels.
+ bytes = vec_vsx_ld(0, s2);
+
+ // Convert the bytes into shorts.
+ shorts2 = (vector signed short) vec_mergeh(bytes, zero);
+
+ // Do the subtraction.
+ shorts1 = vec_sub(shorts1, shorts2);
+
+ // Save the data to the block, we assume the block is 16-byte aligned.
+ vec_vsx_st(shorts1, 0, (vector signed short *) block);
+
+ s1 += stride;
+ s2 += stride;
+ block += 8;
+ }
+}
+#else
static void diff_pixels_altivec(int16_t *restrict block, const uint8_t *s1,
const uint8_t *s2, int stride)
{
}
}
+#endif /* HAVE_VSX */
+
#endif /* HAVE_ALTIVEC */
av_cold void ff_pixblockdsp_init_ppc(PixblockDSPContext *c,
if (ctx->tdata) {
for (i = 0; i < avctx->thread_count; i++)
- av_free(ctx->tdata[i].nodes);
+ av_freep(&ctx->tdata[i].nodes);
}
av_freep(&ctx->tdata);
av_freep(&ctx->slice_q);
return AVERROR(EINVAL);
}
if (ctx->profile == PRORES_PROFILE_AUTO) {
- ctx->profile = av_pix_fmt_desc_get(avctx->pix_fmt)->flags & AV_PIX_FMT_FLAG_ALPHA
+ const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
+ ctx->profile = (desc->flags & AV_PIX_FMT_FLAG_ALPHA ||
+ !(desc->log2_chroma_w + desc->log2_chroma_h))
? PRORES_PROFILE_4444 : PRORES_PROFILE_HQ;
av_log(avctx, AV_LOG_INFO, "Autoselected %s. It can be overridden "
"through -profile option.\n", ctx->profile == PRORES_PROFILE_4444
- ? "4:4:4:4 profile because of the alpha channel"
+ ? "4:4:4:4 profile because of the used input colorspace"
: "HQ profile to keep best quality");
}
if (av_pix_fmt_desc_get(avctx->pix_fmt)->flags & AV_PIX_FMT_FLAG_ALPHA) {
av_cold void ff_psy_preprocess_end(struct FFPsyPreprocessContext *ctx)
{
int i;
- ff_iir_filter_free_coeffs(ctx->fcoeffs);
+ ff_iir_filter_free_coeffsp(&ctx->fcoeffs);
if (ctx->fstate)
for (i = 0; i < ctx->avctx->channels; i++)
- ff_iir_filter_free_state(ctx->fstate[i]);
+ ff_iir_filter_free_statep(&ctx->fstate[i]);
av_freep(&ctx->fstate);
av_free(ctx);
}
if (dst != src) {
dst->time_base = src->time_base;
+ dst->framerate = src->framerate;
dst->width = src->width;
dst->height = src->height;
dst->pix_fmt = src->pix_fmt;
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;
+ int err = av_reallocp_array(&dst->slice_offset, src->slice_count,
+ sizeof(*dst->slice_offset));
+ if (err < 0)
+ return err;
}
memcpy(dst->slice_offset, src->slice_offset,
src->slice_count * sizeof(*dst->slice_offset));
p->frame = av_frame_alloc();
if (!p->frame) {
- err = AVERROR(ENOMEM);
av_freep(©);
+ err = AVERROR(ENOMEM);
goto error;
}
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(&c->workers);
av_freep(&avctx->internal->thread_ctx);
}
s->bit_buf = 0;
}
+/**
+ * Rebase the bit writer onto a reallocated buffer.
+ *
+ * @param buffer the buffer where to put bits
+ * @param buffer_size the size in bytes of buffer,
+ * must be larger than the previous size
+ */
+static inline void rebase_put_bits(PutBitContext *s, uint8_t *buffer,
+ int buffer_size)
+{
+ av_assert0(8*buffer_size > s->size_in_bits);
+
+ s->buf_end = buffer + buffer_size;
+ s->buf_ptr = buffer + (s->buf_ptr - s->buf);
+ s->buf = buffer;
+ s->size_in_bits = 8 * buffer_size;
+}
+
/**
* @return the total number of bits written to the bitstream.
*/
return -1;
}
avctx->frame_size = NBLOCKS * BLOCKSIZE;
- avctx->delay = avctx->frame_size;
+ avctx->initial_padding = avctx->frame_size;
avctx->bit_rate = 8000;
ractx = avctx->priv_data;
ractx->lpc_coef[0] = ractx->lpc_tables[0];
#define RA288_BLOCKS_PER_FRAME 32
typedef struct {
- AVFloatDSPContext fdsp;
+ AVFloatDSPContext *fdsp;
DECLARE_ALIGNED(32, float, sp_lpc)[FFALIGN(36, 16)]; ///< LPC coefficients for speech data (spec: A)
DECLARE_ALIGNED(32, float, gain_lpc)[FFALIGN(10, 16)]; ///< LPC coefficients for gain (spec: GB)
float gain_rec[11];
} RA288Context;
+static av_cold int ra288_decode_close(AVCodecContext *avctx)
+{
+ RA288Context *ractx = avctx->priv_data;
+
+ av_freep(&ractx->fdsp);
+
+ return 0;
+}
+
static av_cold int ra288_decode_init(AVCodecContext *avctx)
{
RA288Context *ractx = avctx->priv_data;
return AVERROR_PATCHWELCOME;
}
- avpriv_float_dsp_init(&ractx->fdsp, avctx->flags & CODEC_FLAG_BITEXACT);
+ ractx->fdsp = avpriv_float_dsp_alloc(avctx->flags & CODEC_FLAG_BITEXACT);
+ if (!ractx->fdsp)
+ return AVERROR(ENOMEM);
return 0;
}
av_assert2(order>=0);
- ractx->fdsp.vector_fmul(work, window, hist, FFALIGN(order + n + non_rec, 16));
+ ractx->fdsp->vector_fmul(work, window, hist, FFALIGN(order + n + non_rec, 16));
convolve(buffer1, work + order , n , order);
convolve(buffer2, work + order + n, non_rec, order);
do_hybrid_window(ractx, order, n, non_rec, temp, hist, rec, window);
if (!compute_lpc_coefs(temp, order, lpc, 0, 1, 1))
- ractx->fdsp.vector_fmul(lpc, lpc, tab, FFALIGN(order, 16));
+ ractx->fdsp->vector_fmul(lpc, lpc, tab, FFALIGN(order, 16));
memmove(hist, hist + n, move_size*sizeof(*hist));
}
.priv_data_size = sizeof(RA288Context),
.init = ra288_decode_init,
.decode = ra288_decode_frame,
+ .close = ra288_decode_close,
.capabilities = CODEC_CAP_DR1,
};
}
res = av_expr_parse(&rcc->rc_eq_eval,
- s->avctx->rc_eq ? s->avctx->rc_eq : "tex^qComp",
+ s->rc_eq ? s->rc_eq : "tex^qComp",
const_names, func1_names, func1,
NULL, NULL, 0, s->avctx);
if (res < 0) {
- av_log(s->avctx, AV_LOG_ERROR, "Error parsing rc_eq \"%s\"\n", s->avctx->rc_eq);
+ av_log(s->avctx, AV_LOG_ERROR, "Error parsing rc_eq \"%s\"\n", s->rc_eq);
return res;
}
return -1;
}
/* init stuff with the user specified complexity */
- if (s->avctx->rc_initial_cplx) {
+ if (s->rc_initial_cplx) {
for (i = 0; i < 60 * 30; i++) {
- double bits = s->avctx->rc_initial_cplx * (i / 10000.0 + 1.0) * s->mb_num;
+ double bits = s->rc_initial_cplx * (i / 10000.0 + 1.0) * s->mb_num;
RateControlEntry rce;
if (i % ((s->gop_size + 3) / 4) == 0)
bits = av_expr_eval(rcc->rc_eq_eval, const_values, rce);
if (isnan(bits)) {
- av_log(s->avctx, AV_LOG_ERROR, "Error evaluating rc_eq \"%s\"\n", s->avctx->rc_eq);
+ av_log(s->avctx, AV_LOG_ERROR, "Error evaluating rc_eq \"%s\"\n", s->rc_eq);
return -1;
}
*/
static void get_qminmax(int *qmin_ret, int *qmax_ret, MpegEncContext *s, int pict_type)
{
- int qmin = s->avctx->lmin;
- int qmax = s->avctx->lmax;
+ int qmin = s->lmin;
+ int qmax = s->lmax;
assert(qmin <= qmax);
get_qminmax(&qmin, &qmax, s, pict_type);
/* modulation */
- if (s->avctx->rc_qmod_freq &&
- frame_num % s->avctx->rc_qmod_freq == 0 &&
+ if (s->rc_qmod_freq &&
+ frame_num % s->rc_qmod_freq == 0 &&
pict_type == AV_PICTURE_TYPE_P)
- q *= s->avctx->rc_qmod_amp;
+ q *= s->rc_qmod_amp;
/* buffer overflow/underflow protection */
if (buffer_size) {
d = 1.0;
else if (d < 0.0001)
d = 0.0001;
- q *= pow(d, 1.0 / s->avctx->rc_buffer_aggressivity);
+ q *= pow(d, 1.0 / s->rc_buffer_aggressivity);
q_limit = bits2qp(rce,
FFMAX((min_rate - buffer_size + rcc->buffer_index) *
d = 1.0;
else if (d < 0.0001)
d = 0.0001;
- q /= pow(d, 1.0 / s->avctx->rc_buffer_aggressivity);
+ q /= pow(d, 1.0 / s->rc_buffer_aggressivity);
q_limit = bits2qp(rce,
FFMAX(rcc->buffer_index *
}
av_dlog(s, "q:%f max:%f min:%f size:%f index:%f agr:%f\n",
q, max_rate, min_rate, buffer_size, rcc->buffer_index,
- s->avctx->rc_buffer_aggressivity);
- if (s->avctx->rc_qsquish == 0.0 || qmin == qmax) {
+ s->rc_buffer_aggressivity);
+ if (s->rc_qsquish == 0.0 || qmin == qmax) {
if (q < qmin)
q = qmin;
else if (q > qmax)
const float temp_cplx_masking = s->avctx->temporal_cplx_masking;
const float spatial_cplx_masking = s->avctx->spatial_cplx_masking;
const float p_masking = s->avctx->p_masking;
- const float border_masking = s->avctx->border_masking;
+ const float border_masking = s->border_masking;
float bits_sum = 0.0;
float cplx_sum = 0.0;
float *cplx_tab = s->cplx_tab;
context->frame_size = avpicture_get_size(avctx->pix_fmt, avctx->width,
avctx->height);
}
+ if (context->frame_size < 0)
+ return context->frame_size;
+
need_copy = !avpkt->buf || context->is_2_4_bpp || context->is_yuv2 || context->is_lt_16bpp;
frame->pict_type = AV_PICTURE_TYPE_I;
}
p++;
}
- av_bprintf(buf, "\r\n");
return 0;
}
static int realtext_decode_frame(AVCodecContext *avctx,
void *data, int *got_sub_ptr, AVPacket *avpkt)
{
+ int ret = 0;
AVSubtitle *sub = data;
const char *ptr = avpkt->data;
AVBPrint buf;
// note: no need to rescale pts & duration since they are in the same
// timebase as ASS (1/100)
if (ptr && avpkt->size > 0 && !rt_event_to_ass(&buf, ptr))
- ff_ass_add_rect(sub, buf.str, avpkt->pts, avpkt->duration, 0);
- *got_sub_ptr = sub->num_rects > 0;
+ ret = ff_ass_add_rect_bprint(sub, &buf, avpkt->pts, avpkt->duration);
av_bprint_finalize(&buf, NULL);
+ if (ret < 0)
+ return ret;
+ *got_sub_ptr = sub->num_rects > 0;
return avpkt->size;
}
{
Rl2Context *s = avctx->priv_data;
- av_free(s->back_frame);
+ av_freep(&s->back_frame);
return 0;
}
return 0;
}
}
- if (context->input_frames < 8) {
+ if (context->input_frames < 8)
in = context->frame_buffer;
- }
if (stereo) {
context->lastSample[0] &= 0xFF00;
FFSWAP(motion_vect *, enc->last_motion4, enc->this_motion4);
FFSWAP(motion_vect *, enc->last_motion8, enc->this_motion8);
- av_free(tempData->cel_evals);
- av_free(tempData->closest_cb2);
+ av_freep(&tempData->cel_evals);
+ av_freep(&tempData->closest_cb2);
enc->framesSinceKeyframe++;
av_frame_free(&enc->current_frame);
av_frame_free(&enc->last_frame);
- av_free(enc->tmpData);
- av_free(enc->this_motion4);
- av_free(enc->last_motion4);
- av_free(enc->this_motion8);
- av_free(enc->last_motion8);
+ av_freep(&enc->tmpData);
+ av_freep(&enc->this_motion4);
+ av_freep(&enc->last_motion4);
+ av_freep(&enc->this_motion8);
+ av_freep(&enc->last_motion8);
return 0;
}
RV34DecContext *r = avctx->priv_data;
int ret;
+ if (avctx->extradata_size < 2) {
+ av_log(avctx, AV_LOG_ERROR, "Extradata is too small.\n");
+ return AVERROR(EINVAL);
+ }
r->rv30 = 1;
if ((ret = ff_rv34_decode_init(avctx)) < 0)
return ret;
- if(avctx->extradata_size < 2){
- av_log(avctx, AV_LOG_ERROR, "Extradata is too small.\n");
- return -1;
- }
r->max_rpr = avctx->extradata[1] & 7;
if(avctx->extradata_size < 2*r->max_rpr + 8){
av_bprint_clear(&sami->full);
if (sami->source.len)
av_bprintf(&sami->full, "{\\i1}%s{\\i0}\\N", sami->source.str);
- av_bprintf(&sami->full, "%s\r\n", sami->content.str);
+ av_bprintf(&sami->full, "%s", sami->content.str);
end:
av_free(dupsrc);
int ts_start = av_rescale_q(avpkt->pts, avctx->time_base, (AVRational){1,100});
int ts_duration = avpkt->duration != -1 ?
av_rescale_q(avpkt->duration, avctx->time_base, (AVRational){1,100}) : -1;
- ff_ass_add_rect(sub, sami->full.str, ts_start, ts_duration, 0);
+ int ret = ff_ass_add_rect_bprint(sub, &sami->full, ts_start, ts_duration);
+ if (ret < 0)
+ return ret;
}
*got_sub_ptr = sub->num_rects > 0;
return avpkt->size;
if (bitshift > 31) {
av_log(avctx, AV_LOG_ERROR, "bitshift %d is invalid\n",
bitshift);
- return AVERROR_PATCHWELCOME;
+ return AVERROR_INVALIDDATA;
}
s->bitshift = bitshift;
break;
/* decode huffman trees from extradata */
if(avctx->extradata_size < 16){
av_log(avctx, AV_LOG_ERROR, "Extradata missing!\n");
+ decode_end(avctx);
return AVERROR(EINVAL);
}
dst_data[1] = src_data[1];
}
+static av_cold int smvjpeg_decode_end(AVCodecContext *avctx)
+{
+ SMVJpegDecodeContext *s = avctx->priv_data;
+ MJpegDecodeContext *jpg = &s->jpg;
+ int ret;
+
+ jpg->picture_ptr = NULL;
+ av_frame_free(&s->picture[0]);
+ av_frame_free(&s->picture[1]);
+ ret = avcodec_close(s->avctx);
+ av_freep(&s->avctx);
+ return ret;
+}
+
static av_cold int smvjpeg_decode_init(AVCodecContext *avctx)
{
SMVJpegDecodeContext *s = avctx->priv_data;
return AVERROR(ENOMEM);
s->picture[1] = av_frame_alloc();
- if (!s->picture[1])
+ if (!s->picture[1]) {
+ av_frame_free(&s->picture[0]);
return AVERROR(ENOMEM);
+ }
s->jpg.picture_ptr = s->picture[0];
}
av_dict_free(&thread_opt);
+ if (ret < 0)
+ smvjpeg_decode_end(avctx);
return ret;
}
return ret;
}
-static av_cold int smvjpeg_decode_end(AVCodecContext *avctx)
-{
- SMVJpegDecodeContext *s = avctx->priv_data;
- MJpegDecodeContext *jpg = &s->jpg;
- int ret;
-
- jpg->picture_ptr = NULL;
- av_frame_free(&s->picture[0]);
- av_frame_free(&s->picture[1]);
- ret = avcodec_close(s->avctx);
- av_freep(&s->avctx);
- return ret;
-}
-
static const AVClass smvjpegdec_class = {
.class_name = "SMVJPEG decoder",
.item_name = av_default_item_name,
}
}
-void ff_snow_pred_block(SnowContext *s, uint8_t *dst, uint8_t *tmp, ptrdiff_t stride, int sx, int sy, int b_w, int b_h, BlockNode *block, int plane_index, int w, int h){
+void ff_snow_pred_block(SnowContext *s, uint8_t *dst, uint8_t *tmp, ptrdiff_t stride, int sx, int sy, int b_w, int b_h, const BlockNode *block, int plane_index, int w, int h){
if(block->type & BLOCK_INTRA){
int x, y;
const unsigned color = block->color[plane_index];
if(s->last_picture[s->max_ref_frames-1]->data[0]){
av_frame_unref(s->last_picture[s->max_ref_frames-1]);
for(i=0; i<9; i++)
- if(s->halfpel_plane[s->max_ref_frames-1][1+i/3][i%3])
+ if(s->halfpel_plane[s->max_ref_frames-1][1+i/3][i%3]) {
av_free(s->halfpel_plane[s->max_ref_frames-1][1+i/3][i%3] - EDGE_WIDTH*(1+s->current_picture->linesize[i%3]));
+ s->halfpel_plane[s->max_ref_frames-1][1+i/3][i%3] = NULL;
+ }
}
}
#include "rangecoder.h"
#include "mathops.h"
+
+#define FF_MPV_OFFSET(x) (offsetof(MpegEncContext, x) + offsetof(SnowContext, m))
#include "mpegvideo.h"
#include "h264qpel.h"
int ff_snow_alloc_blocks(SnowContext *s);
int ff_snow_frame_start(SnowContext *s);
void ff_snow_pred_block(SnowContext *s, uint8_t *dst, uint8_t *tmp, ptrdiff_t stride,
- int sx, int sy, int b_w, int b_h, BlockNode *block,
+ int sx, int sy, int b_w, int b_h, const BlockNode *block,
int plane_index, int w, int h);
int ff_snow_get_buffer(SnowContext *s, AVFrame *frame);
/* common inline functions */
decomposition_count, y);
}
-static inline int w_c(struct MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, int line_size,
+static inline int w_c(struct MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, ptrdiff_t line_size,
int w, int h, int type)
{
int s, i, j;
return s >> 9;
}
-static int w53_8_c(struct MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h)
+static int w53_8_c(struct MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, ptrdiff_t line_size, int h)
{
return w_c(v, pix1, pix2, line_size, 8, h, 1);
}
-static int w97_8_c(struct MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h)
+static int w97_8_c(struct MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, ptrdiff_t line_size, int h)
{
return w_c(v, pix1, pix2, line_size, 8, h, 0);
}
-static int w53_16_c(struct MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h)
+static int w53_16_c(struct MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, ptrdiff_t line_size, int h)
{
return w_c(v, pix1, pix2, line_size, 16, h, 1);
}
-static int w97_16_c(struct MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h)
+static int w97_16_c(struct MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, ptrdiff_t line_size, int h)
{
return w_c(v, pix1, pix2, line_size, 16, h, 0);
}
-int ff_w53_32_c(struct MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h)
+int ff_w53_32_c(struct MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, ptrdiff_t line_size, int h)
{
return w_c(v, pix1, pix2, line_size, 32, h, 1);
}
-int ff_w97_32_c(struct MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h)
+int ff_w97_32_c(struct MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, ptrdiff_t line_size, int h)
{
return w_c(v, pix1, pix2, line_size, 32, h, 0);
}
#ifndef AVCODEC_SNOW_DWT_H
#define AVCODEC_SNOW_DWT_H
+#include <stddef.h>
#include <stdint.h>
typedef int DWTELEM;
int src_y, int src_stride, slice_buffer *sb,
int add, uint8_t *dst8);
-int ff_w53_32_c(struct MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h);
-int ff_w97_32_c(struct MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h);
+int ff_w53_32_c(struct MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, ptrdiff_t line_size, int h);
+int ff_w97_32_c(struct MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, ptrdiff_t line_size, int h);
void ff_spatial_dwt(int *buffer, int *temp, int width, int height, int stride,
int type, int decomposition_count);
ff_snow_common_end(s);
ff_rate_control_uninit(&s->m);
av_frame_free(&s->input_picture);
- av_free(avctx->stats_out);
+ av_freep(&avctx->stats_out);
return 0;
}
#define OFFSET(x) offsetof(SnowContext, x)
#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
static const AVOption options[] = {
+ FF_MPV_COMMON_OPTS
{ "memc_only", "Only do ME/MC (I frames -> ref, P frame -> ME+MC).", OFFSET(memc_only), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE },
{ "no_bitstream", "Skip final bitstream writeout.", OFFSET(no_bitstream), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE },
{ NULL },
char param[PARAM_NUMBER][128];
} SrtStack;
-static const char *srt_to_ass(AVCodecContext *avctx, char *out, char *out_end,
- const char *in, int x1, int y1, int x2, int y2)
+static void rstrip_spaces_buf(AVBPrint *buf)
+{
+ while (buf->len > 0 && buf->str[buf->len - 1] == ' ')
+ buf->str[--buf->len] = 0;
+}
+
+static void srt_to_ass(AVCodecContext *avctx, AVBPrint *dst,
+ const char *in, int x1, int y1, int x2, int y2)
{
char *param, buffer[128], tmp[128];
int len, tag_close, sptr = 1, line_start = 1, an = 0, end = 0;
if (x1 >= 0 && y1 >= 0) {
if (x2 >= 0 && y2 >= 0 && (x2 != x1 || y2 != y1))
- snprintf(out, out_end-out,
- "{\\an1}{\\move(%d,%d,%d,%d)}", x1, y1, x2, y2);
+ av_bprintf(dst, "{\\an1}{\\move(%d,%d,%d,%d)}", x1, y1, x2, y2);
else
- snprintf(out, out_end-out, "{\\an1}{\\pos(%d,%d)}", x1, y1);
- out += strlen(out);
+ av_bprintf(dst, "{\\an1}{\\pos(%d,%d)}", x1, y1);
}
- for (; out < out_end && !end && *in; in++) {
+ for (; !end && *in; in++) {
switch (*in) {
case '\r':
break;
end = 1;
break;
}
- while (out[-1] == ' ')
- out--;
- snprintf(out, out_end-out, "\\N");
- if(out<out_end) out += strlen(out);
+ rstrip_spaces_buf(dst);
+ av_bprintf(dst, "\\N");
line_start = 1;
break;
case ' ':
if (!line_start)
- *out++ = *in;
+ av_bprint_chars(dst, *in, 1);
break;
case '{': /* skip all {\xxx} substrings except for {\an%d}
and all microdvd like styles such as {Y:xxx} */
(len = 0, sscanf(in, "{%*1[CcFfoPSsYy]:%*[^}]}%n", &len) >= 0 && len > 0)) {
in += len - 1;
} else
- *out++ = *in;
+ av_bprint_chars(dst, *in, 1);
break;
case '<':
tag_close = in[1] == '/';
if (stack[sptr-1].param[i][0])
for (j=sptr-2; j>=0; j--)
if (stack[j].param[i][0]) {
- snprintf(out, out_end-out,
- "%s", stack[j].param[i]);
- if(out<out_end) out += strlen(out);
+ av_bprintf(dst, "%s", stack[j].param[i]);
break;
}
} else {
param++;
}
for (i=0; i<PARAM_NUMBER; i++)
- if (stack[sptr].param[i][0]) {
- snprintf(out, out_end-out,
- "%s", stack[sptr].param[i]);
- if(out<out_end) out += strlen(out);
- }
+ if (stack[sptr].param[i][0])
+ av_bprintf(dst, "%s", stack[sptr].param[i]);
}
} else if (!buffer[1] && strspn(buffer, "bisu") == 1) {
- snprintf(out, out_end-out,
- "{\\%c%d}", buffer[0], !tag_close);
- if(out<out_end) out += strlen(out);
+ av_bprintf(dst, "{\\%c%d}", buffer[0], !tag_close);
} else {
unknown = 1;
snprintf(tmp, sizeof(tmp), "</%s>", buffer);
sptr--;
} else if (unknown && !strstr(in, tmp)) {
in -= len + tag_close;
- *out++ = *in;
+ av_bprint_chars(dst, *in, 1);
} else
av_strlcpy(stack[sptr++].tag, buffer,
sizeof(stack[0].tag));
}
}
default:
- *out++ = *in;
+ av_bprint_chars(dst, *in, 1);
break;
}
if (*in != ' ' && *in != '\r' && *in != '\n')
line_start = 0;
}
- out = FFMIN(out, out_end-3);
- while (!strncmp(out-2, "\\N", 2))
- out -= 2;
- while (out[-1] == ' ')
- out--;
- snprintf(out, out_end-out, "\r\n");
- return in;
-}
-
-static const char *read_ts(const char *buf, int *ts_start, int *ts_end,
- int *x1, int *y1, int *x2, int *y2)
-{
- int i, hs, ms, ss, he, me, se;
-
- for (i=0; i<2; i++) {
- /* try to read timestamps in either the first or second line */
- int c = sscanf(buf, "%d:%2d:%2d%*1[,.]%3d --> %d:%2d:%2d%*1[,.]%3d"
- "%*[ ]X1:%u X2:%u Y1:%u Y2:%u",
- &hs, &ms, &ss, ts_start, &he, &me, &se, ts_end,
- x1, x2, y1, y2);
- buf += strcspn(buf, "\n");
- buf += !!*buf;
- if (c >= 8) {
- *ts_start = 100*(ss + 60*(ms + 60*hs)) + *ts_start/10;
- *ts_end = 100*(se + 60*(me + 60*he)) + *ts_end /10;
- return buf;
- }
- }
- return NULL;
+ while (dst->len >= 2 && !strncmp(&dst->str[dst->len - 2], "\\N", 2))
+ dst->len -= 2;
+ dst->str[dst->len] = 0;
+ rstrip_spaces_buf(dst);
}
static int srt_decode_frame(AVCodecContext *avctx,
void *data, int *got_sub_ptr, AVPacket *avpkt)
{
AVSubtitle *sub = data;
+ AVBPrint buffer;
int ts_start, ts_end, x1 = -1, y1 = -1, x2 = -1, y2 = -1;
- char buffer[2048];
- const char *ptr = avpkt->data;
- const char *end = avpkt->data + avpkt->size;
- int size;
+ int size, ret;
const uint8_t *p = av_packet_get_side_data(avpkt, AV_PKT_DATA_SUBTITLE_POSITION, &size);
if (p && size == 16) {
if (avpkt->size <= 0)
return avpkt->size;
- while (ptr < end && *ptr) {
- if (avctx->codec->id == AV_CODEC_ID_SRT) {
- ptr = read_ts(ptr, &ts_start, &ts_end, &x1, &y1, &x2, &y2);
- if (!ptr)
- break;
- } else {
+ av_bprint_init(&buffer, 0, AV_BPRINT_SIZE_UNLIMITED);
+
+ // TODO: reindent
// Do final divide-by-10 outside rescale to force rounding down.
ts_start = av_rescale_q(avpkt->pts,
avctx->time_base,
ts_end = av_rescale_q(avpkt->pts + avpkt->duration,
avctx->time_base,
(AVRational){1,100});
- }
- ptr = srt_to_ass(avctx, buffer, buffer+sizeof(buffer), ptr,
- x1, y1, x2, y2);
- ff_ass_add_rect(sub, buffer, ts_start, ts_end-ts_start, 0);
- }
+
+ srt_to_ass(avctx, &buffer, avpkt->data, x1, y1, x2, y2);
+ ret = ff_ass_add_rect_bprint(sub, &buffer, ts_start, ts_end-ts_start);
+ av_bprint_finalize(&buffer, NULL);
+ if (ret < 0)
+ return ret;
*got_sub_ptr = sub->num_rects > 0;
return avpkt->size;
/* deprecated decoder */
AVCodec ff_srt_decoder = {
.name = "srt",
- .long_name = NULL_IF_CONFIG_SMALL("SubRip subtitle with embedded timing"),
+ .long_name = NULL_IF_CONFIG_SMALL("SubRip subtitle"),
.type = AVMEDIA_TYPE_SUBTITLE,
- .id = AV_CODEC_ID_SRT,
+ .id = AV_CODEC_ID_SUBRIP,
.init = ff_ass_subtitle_header_default,
.decode = srt_decode_frame,
};
AVCodecContext *avctx;
ASSSplitContext *ass_ctx;
AVBPrint buffer;
- unsigned timestamp_end;
- int count;
char stack[SRT_STACK_SIZE];
int stack_ptr;
int alignment_applied;
static void srt_move_cb(void *priv, int x1, int y1, int x2, int y2,
int t1, int t2)
{
- SRTContext *s = priv;
-
- if (s->avctx->codec->id == AV_CODEC_ID_SRT) {
- char buffer[32];
- int len = snprintf(buffer, sizeof(buffer),
- " X1:%03u X2:%03u Y1:%03u Y2:%03u", x1, x2, y1, y2);
- 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;
- }
+ // TODO: add a AV_PKT_DATA_SUBTITLE_POSITION side data when a new subtitles
+ // encoding API passing the AVPacket is available.
}
static void srt_end_cb(void *priv)
{
- SRTContext *s = priv;
-
srt_stack_push_pop(priv, 0, 1);
- if (s->avctx->codec->id == AV_CODEC_ID_SRT)
- srt_print(priv, "\r\n\r\n");
}
static const ASSCodesCallbacks srt_callbacks = {
dialog = ff_ass_split_dialog(s->ass_ctx, sub->rects[i]->ass, 0, &num);
for (; dialog && num--; dialog++) {
- if (avctx->codec->id == AV_CODEC_ID_SRT) {
- int sh, sm, ss, sc = 10 * dialog->start;
- int eh, em, es, ec = 10 * dialog->end;
- sh = sc/3600000; sc -= 3600000*sh;
- sm = sc/ 60000; sc -= 60000*sm;
- ss = sc/ 1000; sc -= 1000*ss;
- eh = ec/3600000; ec -= 3600000*eh;
- em = ec/ 60000; ec -= 60000*em;
- 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->timestamp_end = s->buffer.len - 2;
- }
s->alignment_applied = 0;
srt_style_apply(s, dialog->style);
ff_ass_split_override_codes(&srt_callbacks, s, dialog->text);
/* deprecated encoder */
AVCodec ff_srt_encoder = {
.name = "srt",
- .long_name = NULL_IF_CONFIG_SMALL("SubRip subtitle with embedded timing"),
+ .long_name = NULL_IF_CONFIG_SMALL("SubRip subtitle"),
.type = AVMEDIA_TYPE_SUBTITLE,
- .id = AV_CODEC_ID_SRT,
+ .id = AV_CODEC_ID_SUBRIP,
.priv_data_size = sizeof(SRTContext),
.init = srt_encode_init,
.encode_sub = srt_encode_frame,
}
}
- av_bprintf(buf, "\r\n");
return 0;
}
static int subviewer_decode_frame(AVCodecContext *avctx,
void *data, int *got_sub_ptr, AVPacket *avpkt)
{
- char c;
+ int ret = 0;
AVSubtitle *sub = data;
const char *ptr = avpkt->data;
AVBPrint buf;
- /* To be removed later */
- if (ptr && sscanf(ptr, "%*u:%*u:%*u.%*u,%*u:%*u:%*u.%*u%c", &c) == 1) {
- av_log(avctx, AV_LOG_ERROR, "AVPacket is not clean (contains timing "
- "information). You need to upgrade your libavformat or "
- "sanitize your packet.\n");
- return AVERROR_INVALIDDATA;
- }
-
av_bprint_init(&buf, 0, AV_BPRINT_SIZE_UNLIMITED);
// note: no need to rescale pts & duration since they are in the same
// timebase as ASS (1/100)
if (ptr && avpkt->size > 0 && !subviewer_event_to_ass(&buf, ptr))
- ff_ass_add_rect(sub, buf.str, avpkt->pts, avpkt->duration, 0);
- *got_sub_ptr = sub->num_rects > 0;
+ ret = ff_ass_add_rect_bprint(sub, &buf, avpkt->pts, avpkt->duration);
av_bprint_finalize(&buf, NULL);
+ if (ret < 0)
+ return ret;
+ *got_sub_ptr = sub->num_rects > 0;
return avpkt->size;
}
case AV_PIX_FMT_PAL8 :
s->maptype = RMT_EQUAL_RGB;
s->maplength = 3 * 256;
+ /* fall-through */
case AV_PIX_FMT_GRAY8:
s->depth = 8;
break;
int w = 2 << (level + 2 >> 1);
int h = 2 << (level + 1 >> 1);
int size = w * h;
- int16_t block[7][256];
+ int16_t (*block)[256] = s->encoded_block_levels[level];
const int8_t *codebook_sum, *codebook;
const uint16_t(*mean_vlc)[2];
const uint8_t(*multistage_vlc)[2];
int c_block_width;
int c_block_height;
+ DECLARE_ALIGNED(16, int16_t, encoded_block_levels)[6][7][256];
+
uint16_t *mb_type;
uint32_t *dummy;
int16_t (*motion_val8[3])[2];
static int text_decode_frame(AVCodecContext *avctx, void *data,
int *got_sub_ptr, AVPacket *avpkt)
{
+ int ret = 0;
AVBPrint buf;
AVSubtitle *sub = data;
const char *ptr = avpkt->data;
av_bprint_init(&buf, 0, AV_BPRINT_SIZE_UNLIMITED);
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);
- }
- ff_ass_add_rect(sub, buf.str, ts_start, ts_duration, 0);
+ ret = ff_ass_add_rect_bprint(sub, &buf, ts_start, ts_duration);
}
- *got_sub_ptr = sub->num_rects > 0;
av_bprint_finalize(&buf, NULL);
+ if (ret < 0)
+ return ret;
+ *got_sub_ptr = sub->num_rects > 0;
return avpkt->size;
}
};
#endif
-#if CONFIG_VPLAYER_DECODER || CONFIG_PJS_DECODER || CONFIG_SUBVIEWER1_DECODER
+#if CONFIG_VPLAYER_DECODER || CONFIG_PJS_DECODER || CONFIG_SUBVIEWER1_DECODER || CONFIG_STL_DECODER
static int linebreak_init(AVCodecContext *avctx)
{
};
#endif
+#if CONFIG_STL_DECODER
+#define stl_options options
+DECLARE_CLASS(stl);
+
+AVCodec ff_stl_decoder = {
+ .name = "stl",
+ .long_name = NULL_IF_CONFIG_SMALL("Spruce subtitle format"),
+ .priv_data_size = sizeof(TextContext),
+ .type = AVMEDIA_TYPE_SUBTITLE,
+ .id = AV_CODEC_ID_STL,
+ .decode = text_decode_frame,
+ .init = linebreak_init,
+ .priv_class = &stl_decoder_class,
+};
+#endif
+
#if CONFIG_PJS_DECODER
#define pjs_options options
DECLARE_CLASS(pjs);
#include <zlib.h>
#endif
#if CONFIG_LZMA
+#define LZMA_API_STATIC
#include <lzma.h>
#endif
}
dst = s->yuv_line;
stride = 0;
- width = s->width * s->subsampling[1] + 2*(s->width / s->subsampling[0]);
+
+ width = (s->width - 1) / s->subsampling[0] + 1;
+ width = width * s->subsampling[0] * s->subsampling[1] + 2*width;
av_assert0(width <= bytes_per_row);
av_assert0(s->bpp == 24);
}
int bytes_per_row;
uint32_t res[2] = { s->dpi, 1 }; // image resolution (72/1)
uint16_t bpp_tab[4];
- int ret = -1;
+ int ret = 0;
int is_yuv = 0, alpha = 0;
int shift_h, shift_v;
int packet_size;
offset = ptr;
bytestream_put_le32(&ptr, 0);
+ if (strips > INT_MAX / FFMAX(sizeof(s->strip_sizes[0]), sizeof(s->strip_offsets[0]))) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
av_fast_padded_mallocz(&s->strip_sizes , &s->strip_sizes_size , sizeof(s->strip_sizes [0]) * strips);
av_fast_padded_mallocz(&s->strip_offsets, &s->strip_offsets_size, sizeof(s->strip_offsets[0]) * strips);
}
}
if (s->compr == TIFF_LZW)
- av_free(s->lzws);
+ av_freep(&s->lzws);
}
s->num_entries = 0;
av_free(l->last);
av_free(l->clast);
for (i = 0; i < TM2_NUM_STREAMS; i++)
- av_free(l->tokens[i]);
+ av_freep(&l->tokens[i]);
if (l->Y1) {
- av_free(l->Y1_base);
- av_free(l->U1_base);
- av_free(l->V1_base);
- av_free(l->Y2_base);
- av_free(l->U2_base);
- av_free(l->V2_base);
+ av_freep(&l->Y1_base);
+ av_freep(&l->U1_base);
+ av_freep(&l->V1_base);
+ av_freep(&l->Y2_base);
+ av_freep(&l->U2_base);
+ av_freep(&l->V2_base);
}
av_freep(&l->buffer);
l->buffer_size = 0;
TTAContext *s = avctx->priv_data;
if (s->bps < 3)
- av_free(s->decode_buffer);
+ av_freep(&s->decode_buffer);
s->decode_buffer = NULL;
av_freep(&s->ch_ctx);
mdct->imdct_half(mdct, buf1 + bsize * j, in + bsize * j);
- tctx->fdsp.vector_fmul_window(out2, prev_buf + (bsize - wsize) / 2,
+ tctx->fdsp->vector_fmul_window(out2, prev_buf + (bsize - wsize) / 2,
buf1 + bsize * j,
ff_sine_windows[av_log2(wsize)],
wsize / 2);
size1 * sizeof(*out2));
memcpy(out2 + size1, &tctx->curr_frame[2 * mtab->size],
size2 * sizeof(*out2));
- tctx->fdsp.butterflies_float(out1, out2, mtab->size);
+ tctx->fdsp->butterflies_float(out1, out2, mtab->size);
}
}
bits->bark_use_hist[i][j], i,
tctx->tmp_buf, gain[sub * i + j], ftype);
- tctx->fdsp.vector_fmul(chunk + block_size * j,
+ tctx->fdsp->vector_fmul(chunk + block_size * j,
chunk + block_size * j,
tctx->tmp_buf, block_size);
}
dec_lpc_spectrum_inv(tctx, lsp, ftype, tctx->tmp_buf);
for (j = 0; j < mtab->fmode[ftype].sub; j++) {
- tctx->fdsp.vector_fmul(chunk, chunk, tctx->tmp_buf, block_size);
+ tctx->fdsp->vector_fmul(chunk, chunk, tctx->tmp_buf, block_size);
chunk += block_size;
}
}
for (i = 0; i < 3; i++) {
ff_mdct_end(&tctx->mdct_ctx[i]);
- av_free(tctx->cos_tabs[i]);
+ av_freep(&tctx->cos_tabs[i]);
}
- av_free(tctx->curr_frame);
- av_free(tctx->spectrum);
- av_free(tctx->prev_frame);
- av_free(tctx->tmp_buf);
+ av_freep(&tctx->curr_frame);
+ av_freep(&tctx->spectrum);
+ av_freep(&tctx->prev_frame);
+ av_freep(&tctx->tmp_buf);
+ av_freep(&tctx->fdsp);
return 0;
}
return AVERROR_INVALIDDATA;
}
- avpriv_float_dsp_init(&tctx->fdsp, avctx->flags & CODEC_FLAG_BITEXACT);
+ tctx->fdsp = avpriv_float_dsp_alloc(avctx->flags & CODEC_FLAG_BITEXACT);
+ if (!tctx->fdsp) {
+ ff_twinvq_decode_close(avctx);
+ return AVERROR(ENOMEM);
+ }
if ((ret = init_mdct_win(tctx))) {
av_log(avctx, AV_LOG_ERROR, "Error initializing MDCT\n");
ff_twinvq_decode_close(avctx);
typedef struct TwinVQContext {
AVCodecContext *avctx;
- AVFloatDSPContext fdsp;
+ AVFloatDSPContext *fdsp;
FFTContext mdct_ctx[3];
const TwinVQModeTab *mtab;
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)
+ if (min_size <= *size && *p)
return 0;
min_size = FFMAX(17 * min_size / 16 + 32, min_size);
av_free(*p);
int i;
int w_align = 1;
int h_align = 1;
- AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(s->pix_fmt);
+ AVPixFmtDescriptor const *desc = av_pix_fmt_desc_get(s->pix_fmt);
if (desc) {
w_align = 1 << desc->log2_chroma_w;
int ff_init_buffer_info(AVCodecContext *avctx, AVFrame *frame)
{
AVPacket *pkt = avctx->internal->pkt;
+ int i;
+ static const struct {
+ enum AVPacketSideDataType packet;
+ enum AVFrameSideDataType frame;
+ } sd[] = {
+ { AV_PKT_DATA_REPLAYGAIN , AV_FRAME_DATA_REPLAYGAIN },
+ { AV_PKT_DATA_DISPLAYMATRIX, AV_FRAME_DATA_DISPLAYMATRIX },
+ { AV_PKT_DATA_STEREO3D, AV_FRAME_DATA_STEREO3D },
+ };
if (pkt) {
- uint8_t *packet_sd;
- AVFrameSideData *frame_sd;
- int size;
frame->pkt_pts = pkt->pts;
av_frame_set_pkt_pos (frame, pkt->pos);
av_frame_set_pkt_duration(frame, pkt->duration);
av_frame_set_pkt_size (frame, pkt->size);
- /* copy the replaygain data to the output frame */
- packet_sd = av_packet_get_side_data(pkt, AV_PKT_DATA_REPLAYGAIN, &size);
- if (packet_sd) {
- frame_sd = av_frame_new_side_data(frame, AV_FRAME_DATA_REPLAYGAIN, size);
- if (!frame_sd)
- return AVERROR(ENOMEM);
-
- memcpy(frame_sd->data, packet_sd, size);
- }
-
- /* copy the displaymatrix to the output frame */
- packet_sd = av_packet_get_side_data(pkt, AV_PKT_DATA_DISPLAYMATRIX, &size);
- if (packet_sd) {
- frame_sd = av_frame_new_side_data(frame, AV_FRAME_DATA_DISPLAYMATRIX, size);
- if (!frame_sd)
- return AVERROR(ENOMEM);
-
- memcpy(frame_sd->data, packet_sd, size);
- }
-
- /* copy the stereo3d format to the output frame */
- packet_sd = av_packet_get_side_data(pkt, AV_PKT_DATA_STEREO3D, &size);
- if (packet_sd) {
- frame_sd = av_frame_new_side_data(frame, AV_FRAME_DATA_STEREO3D, size);
- if (!frame_sd)
- return AVERROR(ENOMEM);
-
- memcpy(frame_sd->data, packet_sd, size);
+ for (i = 0; i < FF_ARRAY_ELEMS(sd); i++) {
+ int size;
+ uint8_t *packet_sd = av_packet_get_side_data(pkt, sd[i].packet, &size);
+ if (packet_sd) {
+ AVFrameSideData *frame_sd = av_frame_new_side_data(frame,
+ sd[i].frame,
+ size);
+ if (!frame_sd)
+ return AVERROR(ENOMEM);
+
+ memcpy(frame_sd->data, packet_sd, size);
+ }
}
} else {
frame->pkt_pts = AV_NOPTS_VALUE;
return NULL;
}
+static int setup_hwaccel(AVCodecContext *avctx,
+ const enum AVPixelFormat fmt,
+ const char *name)
+{
+ AVHWAccel *hwa = find_hwaccel(avctx->codec_id, fmt);
+ int ret = 0;
+
+ if (!hwa) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Could not find an AVHWAccel for the pixel format: %s",
+ name);
+ return AVERROR(ENOENT);
+ }
+
+ if (hwa->priv_data_size) {
+ avctx->internal->hwaccel_priv_data = av_mallocz(hwa->priv_data_size);
+ if (!avctx->internal->hwaccel_priv_data)
+ return AVERROR(ENOMEM);
+ }
+
+ if (hwa->init) {
+ ret = hwa->init(avctx);
+ if (ret < 0) {
+ av_freep(&avctx->internal->hwaccel_priv_data);
+ return ret;
+ }
+ }
+
+ avctx->hwaccel = hwa;
+
+ return 0;
+}
int ff_get_format(AVCodecContext *avctx, const enum AVPixelFormat *fmt)
{
const AVPixFmtDescriptor *desc;
- enum AVPixelFormat ret = avctx->get_format(avctx, fmt);
+ enum AVPixelFormat *choices;
+ enum AVPixelFormat ret;
+ unsigned n = 0;
+
+ while (fmt[n] != AV_PIX_FMT_NONE)
+ ++n;
- desc = av_pix_fmt_desc_get(ret);
- if (!desc)
+ choices = av_malloc_array(n + 1, sizeof(*choices));
+ if (!choices)
return AV_PIX_FMT_NONE;
- if (avctx->hwaccel && avctx->hwaccel->uninit)
- avctx->hwaccel->uninit(avctx);
- av_freep(&avctx->internal->hwaccel_priv_data);
- avctx->hwaccel = NULL;
+ memcpy(choices, fmt, (n + 1) * sizeof(*choices));
- if (desc->flags & AV_PIX_FMT_FLAG_HWACCEL &&
- !(avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU)) {
- AVHWAccel *hwaccel;
- int err;
+ for (;;) {
+ if (avctx->hwaccel && avctx->hwaccel->uninit)
+ avctx->hwaccel->uninit(avctx);
+ av_freep(&avctx->internal->hwaccel_priv_data);
+ avctx->hwaccel = NULL;
- hwaccel = find_hwaccel(avctx->codec_id, ret);
- if (!hwaccel) {
- av_log(avctx, AV_LOG_ERROR,
- "Could not find an AVHWAccel for the pixel format: %s",
- desc->name);
- return AV_PIX_FMT_NONE;
- }
+ ret = avctx->get_format(avctx, choices);
- if (hwaccel->priv_data_size) {
- avctx->internal->hwaccel_priv_data = av_mallocz(hwaccel->priv_data_size);
- if (!avctx->internal->hwaccel_priv_data)
- return AV_PIX_FMT_NONE;
+ desc = av_pix_fmt_desc_get(ret);
+ if (!desc) {
+ ret = AV_PIX_FMT_NONE;
+ break;
}
- if (hwaccel->init) {
- err = hwaccel->init(avctx);
- if (err < 0) {
- av_freep(&avctx->internal->hwaccel_priv_data);
- return AV_PIX_FMT_NONE;
- }
- }
- avctx->hwaccel = hwaccel;
+ if (!(desc->flags & AV_PIX_FMT_FLAG_HWACCEL))
+ break;
+ if (avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU)
+ break;
+
+ if (!setup_hwaccel(avctx, ret, desc->name))
+ break;
+
+ /* Remove failed hwaccel from choices */
+ for (n = 0; choices[n] != ret; n++)
+ av_assert0(choices[n] != AV_PIX_FMT_NONE);
+
+ do
+ choices[n] = choices[n + 1];
+ while (choices[n++] != AV_PIX_FMT_NONE);
}
+ av_freep(&choices);
return ret;
}
return codec->max_lowres;
}
-static void avcodec_get_subtitle_defaults(AVSubtitle *sub)
+static void get_subtitle_defaults(AVSubtitle *sub)
{
memset(sub, 0, sizeof(*sub));
sub->pts = AV_NOPTS_VALUE;
if ((ret = av_opt_set_dict(avctx, &tmp)) < 0)
goto free_and_end;
+ if (avctx->codec_whitelist && av_match_list(codec->name, avctx->codec_whitelist, ',') <= 0) {
+ av_log(avctx, AV_LOG_ERROR, "Codec (%s) not on whitelist\n", codec->name);
+ ret = AVERROR(EINVAL);
+ goto free_and_end;
+ }
+
// 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))) {
ret = AVERROR(EINVAL);
goto free_and_end;
}
+ if (avctx->codec->pix_fmts[i] == AV_PIX_FMT_YUVJ420P ||
+ avctx->codec->pix_fmts[i] == AV_PIX_FMT_YUVJ411P ||
+ avctx->codec->pix_fmts[i] == AV_PIX_FMT_YUVJ422P ||
+ avctx->codec->pix_fmts[i] == AV_PIX_FMT_YUVJ440P ||
+ avctx->codec->pix_fmts[i] == AV_PIX_FMT_YUVJ444P)
+ avctx->color_range = AVCOL_RANGE_JPEG;
}
if (avctx->codec->supported_samplerates) {
for (i = 0; avctx->codec->supported_samplerates[i] != 0; i++)
ret=0;
+#if FF_API_AUDIOENC_DELAY
+ if (av_codec_is_encoder(avctx->codec))
+ avctx->delay = avctx->initial_padding;
+#endif
+
if (av_codec_is_decoder(avctx->codec)) {
if (!avctx->bit_rate)
avctx->bit_rate = get_bit_rate(avctx);
#if CONFIG_ICONV
iconv_t cd = iconv_open("UTF-8", avctx->sub_charenc);
if (cd == (iconv_t)-1) {
+ ret = AVERROR(errno);
av_log(avctx, AV_LOG_ERROR, "Unable to open iconv context "
"with input character encoding \"%s\"\n", avctx->sub_charenc);
- ret = AVERROR(errno);
goto free_and_end;
}
iconv_close(cd);
}
}
}
+
+#if FF_API_AVCTX_TIMEBASE
+ if (avctx->framerate.num > 0 && avctx->framerate.den > 0)
+ avctx->time_base = av_inv_q(av_mul_q(avctx->framerate, (AVRational){avctx->ticks_per_frame, 1}));
+#endif
}
end:
ff_unlock_avcodec();
return ret;
free_and_end:
av_dict_free(&tmp);
+ if (codec->priv_class && codec->priv_data_size)
+ av_opt_free(avctx->priv_data);
av_freep(&avctx->priv_data);
if (avctx->internal) {
av_frame_free(&avctx->internal->to_free);
av_frame_free(&padded_frame);
av_free(extended_frame);
+#if FF_API_AUDIOENC_DELAY
+ avctx->delay = avctx->initial_padding;
+#endif
+
return ret;
}
* make sure it's set correctly */
av_assert0(!picture->extended_data || picture->extended_data == picture->data);
+#if FF_API_AVCTX_TIMEBASE
+ if (avctx->framerate.num > 0 && avctx->framerate.den > 0)
+ avctx->time_base = av_inv_q(av_mul_q(avctx->framerate, (AVRational){avctx->ticks_per_frame, 1}));
+#endif
+
return ret;
}
uint8_t *side;
int side_size;
uint32_t discard_padding = 0;
+ uint8_t skip_reason = 0;
+ uint8_t discard_reason = 0;
// copy to ensure we do not change avpkt
AVPacket tmp = *avpkt;
int did_split = av_packet_split_side_data(&tmp);
av_log(avctx, AV_LOG_DEBUG, "skip %d samples due to side data\n",
avctx->internal->skip_samples);
discard_padding = AV_RL32(side + 4);
+ skip_reason = AV_RL8(side + 8);
+ discard_reason = AV_RL8(side + 9);
}
- if (avctx->internal->skip_samples && *got_frame_ptr) {
+ if (avctx->internal->skip_samples && *got_frame_ptr &&
+ !(avctx->flags2 & CODEC_FLAG2_SKIP_MANUAL)) {
if(frame->nb_samples <= avctx->internal->skip_samples){
*got_frame_ptr = 0;
avctx->internal->skip_samples -= frame->nb_samples;
}
}
- if (discard_padding > 0 && discard_padding <= frame->nb_samples && *got_frame_ptr) {
+ if (discard_padding > 0 && discard_padding <= frame->nb_samples && *got_frame_ptr &&
+ !(avctx->flags2 & CODEC_FLAG2_SKIP_MANUAL)) {
if (discard_padding == frame->nb_samples) {
*got_frame_ptr = 0;
} else {
frame->nb_samples -= discard_padding;
}
}
+
+ if ((avctx->flags2 & CODEC_FLAG2_SKIP_MANUAL) && *got_frame_ptr) {
+ AVFrameSideData *fside = av_frame_new_side_data(frame, AV_FRAME_DATA_SKIP_SAMPLES, 10);
+ if (fside) {
+ AV_WL32(fside->data, avctx->internal->skip_samples);
+ AV_WL32(fside->data + 4, discard_padding);
+ AV_WL8(fside->data + 8, skip_reason);
+ AV_WL8(fside->data + 9, discard_reason);
+ avctx->internal->skip_samples = 0;
+ }
+ }
fail:
avctx->internal->pkt = NULL;
if (did_split) {
if (iconv(cd, &inb, &inl, &outb, &outl) == (size_t)-1 ||
iconv(cd, NULL, NULL, &outb, &outl) == (size_t)-1 ||
outl >= outpkt->size || inl != 0) {
+ ret = FFMIN(AVERROR(errno), -1);
av_log(avctx, AV_LOG_ERROR, "Unable to recode subtitle event \"%s\" "
"from %s to UTF-8\n", inpkt->data, avctx->sub_charenc);
av_free_packet(&tmp);
- ret = AVERROR(errno);
goto end;
}
outpkt->size -= outl;
}
*got_sub_ptr = 0;
- avcodec_get_subtitle_defaults(sub);
+ get_subtitle_defaults(sub);
if ((avctx->codec->capabilities & CODEC_CAP_DELAY) || avpkt->size) {
AVPacket pkt_recoded;
const char *profile = NULL;
const AVCodec *p;
int bitrate;
+ int new_line = 0;
AVRational display_aspect_ratio;
+ const char *separator = enc->dump_separator ? (const char *)enc->dump_separator : ", ";
if (!buf || buf_size <= 0)
return;
if (profile)
snprintf(buf + strlen(buf), buf_size - strlen(buf), " (%s)", profile);
+
if (enc->codec_tag) {
char tag_buf[32];
av_get_codec_tag_string(tag_buf, sizeof(tag_buf), enc->codec_tag);
switch (enc->codec_type) {
case AVMEDIA_TYPE_VIDEO:
- if (enc->pix_fmt != AV_PIX_FMT_NONE) {
+ {
char detail[256] = "(";
- const char *colorspace_name;
+
+ av_strlcat(buf, separator, buf_size);
+
snprintf(buf + strlen(buf), buf_size - strlen(buf),
- ", %s",
+ "%s", enc->pix_fmt == AV_PIX_FMT_NONE ? "none" :
av_get_pix_fmt_name(enc->pix_fmt));
- if (enc->bits_per_raw_sample &&
+ if (enc->bits_per_raw_sample && enc->pix_fmt != AV_PIX_FMT_NONE &&
enc->bits_per_raw_sample <= av_pix_fmt_desc_get(enc->pix_fmt)->comp[0].depth_minus1)
av_strlcatf(detail, sizeof(detail), "%d bpc, ", enc->bits_per_raw_sample);
if (enc->color_range != AVCOL_RANGE_UNSPECIFIED)
- av_strlcatf(detail, sizeof(detail),
- enc->color_range == AVCOL_RANGE_MPEG ? "tv, ": "pc, ");
+ av_strlcatf(detail, sizeof(detail), "%s, ",
+ av_color_range_name(enc->color_range));
+
+ if (enc->colorspace != AVCOL_SPC_UNSPECIFIED ||
+ enc->color_primaries != AVCOL_PRI_UNSPECIFIED ||
+ enc->color_trc != AVCOL_TRC_UNSPECIFIED) {
+ if (enc->colorspace != (int)enc->color_primaries ||
+ enc->colorspace != (int)enc->color_trc) {
+ new_line = 1;
+ av_strlcatf(detail, sizeof(detail), "%s/%s/%s, ",
+ av_color_space_name(enc->colorspace),
+ av_color_primaries_name(enc->color_primaries),
+ av_color_transfer_name(enc->color_trc));
+ } else
+ av_strlcatf(detail, sizeof(detail), "%s, ",
+ av_get_colorspace_name(enc->colorspace));
+ }
- colorspace_name = av_get_colorspace_name(enc->colorspace);
- if (colorspace_name)
- av_strlcatf(detail, sizeof(detail), "%s, ", colorspace_name);
+ if (av_log_get_level() >= AV_LOG_DEBUG &&
+ enc->chroma_sample_location != AVCHROMA_LOC_UNSPECIFIED)
+ av_strlcatf(detail, sizeof(detail), "%s, ",
+ av_chroma_location_name(enc->chroma_sample_location));
if (strlen(detail) > 1) {
detail[strlen(detail) - 2] = 0;
av_strlcatf(buf, buf_size, "%s)", detail);
}
}
+
if (enc->width) {
+ av_strlcat(buf, new_line ? separator : ", ", buf_size);
+
snprintf(buf + strlen(buf), buf_size - strlen(buf),
- ", %dx%d",
+ "%dx%d",
enc->width, enc->height);
+
+ if (av_log_get_level() >= AV_LOG_VERBOSE &&
+ (enc->width != enc->coded_width ||
+ enc->height != enc->coded_height))
+ snprintf(buf + strlen(buf), buf_size - strlen(buf),
+ " (%dx%d)", enc->coded_width, enc->coded_height);
+
if (enc->sample_aspect_ratio.num) {
av_reduce(&display_aspect_ratio.num, &display_aspect_ratio.den,
enc->width * enc->sample_aspect_ratio.num,
}
break;
case AVMEDIA_TYPE_AUDIO:
+ av_strlcat(buf, separator, buf_size);
+
if (enc->sample_rate) {
snprintf(buf + strlen(buf), buf_size - strlen(buf),
- ", %d Hz", enc->sample_rate);
+ "%d Hz, ", enc->sample_rate);
}
- av_strlcat(buf, ", ", buf_size);
av_get_channel_layout_string(buf + strlen(buf), buf_size - strlen(buf), enc->channels, enc->channel_layout);
if (enc->sample_fmt != AV_SAMPLE_FMT_NONE) {
snprintf(buf + strlen(buf), buf_size - strlen(buf),
case AV_CODEC_ID_MP1: return 384;
case AV_CODEC_ID_ATRAC1: return 512;
case AV_CODEC_ID_ATRAC3: return 1024;
+ case AV_CODEC_ID_ATRAC3P: return 2048;
case AV_CODEC_ID_MP2:
case AV_CODEC_ID_MUSEPACK7: return 1152;
case AV_CODEC_ID_AC3: return 1536;
int av_lockmgr_register(int (*cb)(void **mutex, enum AVLockOp op))
{
if (lockmgr_cb) {
- if (lockmgr_cb(&codec_mutex, AV_LOCK_DESTROY))
- return -1;
- if (lockmgr_cb(&avformat_mutex, AV_LOCK_DESTROY))
- return -1;
+ // There is no good way to rollback a failure to destroy the
+ // mutex, so we ignore failures.
+ lockmgr_cb(&codec_mutex, AV_LOCK_DESTROY);
+ lockmgr_cb(&avformat_mutex, AV_LOCK_DESTROY);
+ lockmgr_cb = NULL;
+ codec_mutex = NULL;
+ avformat_mutex = NULL;
+ }
+
+ if (cb) {
+ void *new_codec_mutex = NULL;
+ void *new_avformat_mutex = NULL;
+ int err;
+ if (err = cb(&new_codec_mutex, AV_LOCK_CREATE)) {
+ return err > 0 ? AVERROR_UNKNOWN : err;
+ }
+ if (err = cb(&new_avformat_mutex, AV_LOCK_CREATE)) {
+ // Ignore failures to destroy the newly created mutex.
+ cb(&new_codec_mutex, AV_LOCK_DESTROY);
+ return err > 0 ? AVERROR_UNKNOWN : err;
+ }
+ lockmgr_cb = cb;
+ codec_mutex = new_codec_mutex;
+ avformat_mutex = new_avformat_mutex;
}
- lockmgr_cb = cb;
-
- if (lockmgr_cb) {
- if (lockmgr_cb(&codec_mutex, AV_LOCK_CREATE))
- return -1;
- if (lockmgr_cb(&avformat_mutex, AV_LOCK_CREATE))
- return -1;
- }
return 0;
}
if ((*lockmgr_cb)(&codec_mutex, AV_LOCK_RELEASE))
return -1;
}
+
return 0;
}
ret = av_bprint_finalize(buf, &str);
if (ret < 0)
return ret;
+ if (!av_bprint_is_complete(buf)) {
+ av_free(str);
+ return AVERROR(ENOMEM);
+ }
+
avctx->extradata = str;
/* Note: the string is NUL terminated (so extradata can be read as a
* string), but the ending character is not accounted in the size (in
*fsym = he[0].sym;
return 0;
}
- if (he[0].len > 32)
- return -1;
last = 255;
while (he[last].len == 255 && last)
last--;
+ if (he[last].len > 32)
+ return -1;
+
code = 1;
for (i = last; i >= 0; i--) {
codes[i] = code >> (32 - he[i].len);
A = bsrc[i];
}
bsrc += stride;
- if (slice_height == 1)
+ if (slice_height <= 1)
continue;
// second line - first element has top prediction, the rest uses median
C = bsrc[-stride];
A = bsrc[stride + i];
}
bsrc += stride2;
- if (slice_height == 1)
+ if (slice_height <= 1)
continue;
// second line - first element has top prediction, the rest uses median
C = bsrc[-stride2];
#include "avcodec.h"
#include "bytestream.h"
#include "internal.h"
+#include "v210enc.h"
+
+#define CLIP(v) av_clip(v, 4, 1019)
+#define CLIP8(v) av_clip(v, 1, 254)
+
+#define WRITE_PIXELS(a, b, c) \
+ do { \
+ val = CLIP(*a++); \
+ val |= (CLIP(*b++) << 10) | \
+ (CLIP(*c++) << 20); \
+ AV_WL32(dst, val); \
+ dst += 4; \
+ } while (0)
+
+#define WRITE_PIXELS8(a, b, c) \
+ do { \
+ val = (CLIP8(*a++) << 2); \
+ val |= (CLIP8(*b++) << 12) | \
+ (CLIP8(*c++) << 22); \
+ AV_WL32(dst, val); \
+ dst += 4; \
+ } while (0)
+
+static void v210_planar_pack_8_c(const uint8_t *y, const uint8_t *u,
+ const uint8_t *v, uint8_t *dst, ptrdiff_t width)
+{
+ uint32_t val;
+ int i;
+
+ /* unroll this to match the assembly */
+ for( i = 0; i < width-11; i += 12 ){
+ WRITE_PIXELS8(u, y, v);
+ WRITE_PIXELS8(y, u, y);
+ WRITE_PIXELS8(v, y, u);
+ WRITE_PIXELS8(y, v, y);
+ WRITE_PIXELS8(u, y, v);
+ WRITE_PIXELS8(y, u, y);
+ WRITE_PIXELS8(v, y, u);
+ WRITE_PIXELS8(y, v, y);
+ }
+}
+
+static void v210_planar_pack_10_c(const uint16_t *y, const uint16_t *u,
+ const uint16_t *v, uint8_t *dst, ptrdiff_t width)
+{
+ uint32_t val;
+ int i;
+
+ for( i = 0; i < width-5; i += 6 ){
+ WRITE_PIXELS(u, y, v);
+ WRITE_PIXELS(y, u, y);
+ WRITE_PIXELS(v, y, u);
+ WRITE_PIXELS(y, v, y);
+ }
+}
static av_cold int encode_init(AVCodecContext *avctx)
{
+ V210EncContext *s = avctx->priv_data;
+
if (avctx->width & 1) {
av_log(avctx, AV_LOG_ERROR, "v210 needs even width\n");
return AVERROR(EINVAL);
}
- if (avctx->bits_per_raw_sample != 10)
- av_log(avctx, AV_LOG_WARNING, "bits per raw sample: %d != 10-bit\n",
- avctx->bits_per_raw_sample);
-
avctx->coded_frame = av_frame_alloc();
if (!avctx->coded_frame)
return AVERROR(ENOMEM);
avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
+ s->pack_line_8 = v210_planar_pack_8_c;
+ s->pack_line_10 = v210_planar_pack_10_c;
+
+ if (ARCH_X86)
+ ff_v210enc_init_x86(s);
+
return 0;
}
static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
const AVFrame *pic, int *got_packet)
{
+ V210EncContext *s = avctx->priv_data;
+
int aligned_width = ((avctx->width + 47) / 48) * 48;
int stride = aligned_width * 8 / 3;
int line_padding = stride - ((avctx->width * 8 + 11) / 12) * 4;
int h, w, ret;
- const uint16_t *y = (const uint16_t*)pic->data[0];
- const uint16_t *u = (const uint16_t*)pic->data[1];
- const uint16_t *v = (const uint16_t*)pic->data[2];
- PutByteContext p;
+ uint8_t *dst;
- if ((ret = ff_alloc_packet2(avctx, pkt, avctx->height * stride)) < 0)
+ if ((ret = ff_alloc_packet(pkt, avctx->height * stride)) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "Error getting output packet.\n");
return ret;
+ }
- bytestream2_init_writer(&p, pkt->data, pkt->size);
+ dst = pkt->data;
+
+ if (pic->format == AV_PIX_FMT_YUV422P10) {
+ const uint16_t *y = (const uint16_t*)pic->data[0];
+ const uint16_t *u = (const uint16_t*)pic->data[1];
+ const uint16_t *v = (const uint16_t*)pic->data[2];
+ for (h = 0; h < avctx->height; h++) {
+ uint32_t val;
+ w = (avctx->width / 6) * 6;
+ s->pack_line_10(y, u, v, dst, w);
+
+ y += w;
+ u += w >> 1;
+ v += w >> 1;
+ dst += (w / 6) * 16;
+ if (w < avctx->width - 1) {
+ WRITE_PIXELS(u, y, v);
+
+ val = CLIP(*y++);
+ if (w == avctx->width - 2) {
+ AV_WL32(dst, val);
+ dst += 4;
+ }
+ }
+ if (w < avctx->width - 3) {
+ val |= (CLIP(*u++) << 10) | (CLIP(*y++) << 20);
+ AV_WL32(dst, val);
+ dst += 4;
-#define CLIP(v) av_clip(v, 4, 1019)
+ val = CLIP(*v++) | (CLIP(*y++) << 10);
+ AV_WL32(dst, val);
+ dst += 4;
+ }
-#define WRITE_PIXELS(a, b, c) \
- do { \
- val = CLIP(*a++); \
- val |= (CLIP(*b++) << 10) | \
- (CLIP(*c++) << 20); \
- bytestream2_put_le32u(&p, val); \
- } while (0)
+ memset(dst, 0, line_padding);
+ dst += line_padding;
- for (h = 0; h < avctx->height; h++) {
- uint32_t val;
- for (w = 0; w < avctx->width - 5; w += 6) {
- WRITE_PIXELS(u, y, v);
- WRITE_PIXELS(y, u, y);
- WRITE_PIXELS(v, y, u);
- WRITE_PIXELS(y, v, y);
+ y += pic->linesize[0] / 2 - avctx->width;
+ u += pic->linesize[1] / 2 - avctx->width / 2;
+ v += pic->linesize[2] / 2 - avctx->width / 2;
}
- if (w < avctx->width - 1) {
- WRITE_PIXELS(u, y, v);
-
- val = CLIP(*y++);
- if (w == avctx->width - 2)
- bytestream2_put_le32u(&p, val);
+ }
+ else if(pic->format == AV_PIX_FMT_YUV422P) {
+ const uint8_t *y = pic->data[0];
+ const uint8_t *u = pic->data[1];
+ const uint8_t *v = pic->data[2];
+ for (h = 0; h < avctx->height; h++) {
+ uint32_t val;
+ w = (avctx->width / 12) * 12;
+ s->pack_line_8(y, u, v, dst, w);
+
+ y += w;
+ u += w >> 1;
+ v += w >> 1;
+ dst += (w / 12) * 32;
+
+ for( ; w < avctx->width-5; w += 6 ){
+ WRITE_PIXELS8(u, y, v);
+ WRITE_PIXELS8(y, u, y);
+ WRITE_PIXELS8(v, y, u);
+ WRITE_PIXELS8(y, v, y);
+ }
+ if (w < avctx->width - 1) {
+ WRITE_PIXELS8(u, y, v);
+
+ val = CLIP8(*y++) << 2;
+ if (w == avctx->width - 2) {
+ AV_WL32(dst, val);
+ dst += 4;
+ }
+ }
if (w < avctx->width - 3) {
- val |= (CLIP(*u++) << 10) | (CLIP(*y++) << 20);
- bytestream2_put_le32u(&p, val);
+ val |= (CLIP8(*u++) << 12) | (CLIP8(*y++) << 22);
+ AV_WL32(dst, val);
+ dst += 4;
- val = CLIP(*v++) | (CLIP(*y++) << 10);
- bytestream2_put_le32u(&p, val);
+ val = (CLIP8(*v++) << 2) | (CLIP8(*y++) << 12);
+ AV_WL32(dst, val);
+ dst += 4;
}
- }
- bytestream2_set_buffer(&p, 0, line_padding);
+ memset(dst, 0, line_padding);
+ dst += line_padding;
- y += pic->linesize[0] / 2 - avctx->width;
- u += pic->linesize[1] / 2 - avctx->width / 2;
- v += pic->linesize[2] / 2 - avctx->width / 2;
+ y += pic->linesize[0] - avctx->width;
+ u += pic->linesize[1] - avctx->width / 2;
+ v += pic->linesize[2] - avctx->width / 2;
+ }
}
pkt->flags |= AV_PKT_FLAG_KEY;
.long_name = NULL_IF_CONFIG_SMALL("Uncompressed 4:2:2 10-bit"),
.type = AVMEDIA_TYPE_VIDEO,
.id = AV_CODEC_ID_V210,
+ .priv_data_size = sizeof(V210EncContext),
.init = encode_init,
.encode2 = encode_frame,
.close = encode_close,
- .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV422P10, AV_PIX_FMT_NONE },
+ .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV422P, AV_PIX_FMT_NONE },
};
--- /dev/null
+/*
+ * 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 AVCOENC_V210ENC_H
+#define AVCOENC_V210ENC_H
+
+#include "libavutil/log.h"
+#include "libavutil/opt.h"
+#include "libavutil/pixfmt.h"
+
+typedef struct {
+ void (*pack_line_8)(const uint8_t *y, const uint8_t *u, const uint8_t *v, uint8_t *dst, ptrdiff_t width);
+ void (*pack_line_10)(const uint16_t *y, const uint16_t *u, const uint16_t *v, uint8_t *dst, ptrdiff_t width);
+} V210EncContext;
+
+void ff_v210enc_init_x86(V210EncContext *s);
+
+#endif /* AVCOENC_V210ENC_H */
pic_param->vop_fields.bits.alternate_vertical_scan_flag = s->alternate_scan;
pic_param->vop_fcode_forward = s->f_code;
pic_param->vop_fcode_backward = s->b_code;
- pic_param->vop_time_increment_resolution = avctx->time_base.den;
+ pic_param->vop_time_increment_resolution = avctx->framerate.num;
pic_param->num_macroblocks_in_gob = s->mb_width * ff_h263_get_gob_height(s);
pic_param->num_gobs_in_vop = (s->mb_width * s->mb_height) / pic_param->num_macroblocks_in_gob;
pic_param->TRB = s->pb_time;
if (get_bits1(gb)) { //framerate stuff
if (get_bits1(gb)) {
- v->s.avctx->time_base.num = 32;
- v->s.avctx->time_base.den = get_bits(gb, 16) + 1;
+ v->s.avctx->framerate.den = 32;
+ v->s.avctx->framerate.num = get_bits(gb, 16) + 1;
} else {
int nr, dr;
nr = get_bits(gb, 8);
dr = get_bits(gb, 4);
if (nr > 0 && nr < 8 && dr > 0 && dr < 3) {
- v->s.avctx->time_base.num = ff_vc1_fps_dr[dr - 1];
- v->s.avctx->time_base.den = ff_vc1_fps_nr[nr - 1] * 1000;
+ v->s.avctx->framerate.den = ff_vc1_fps_dr[dr - 1];
+ v->s.avctx->framerate.num = ff_vc1_fps_nr[nr - 1] * 1000;
}
}
if (v->broadcast) { // Pulldown may be present
- v->s.avctx->time_base.den *= 2;
v->s.avctx->ticks_per_frame = 2;
}
}
if (get_bits1(gb)) {
- v->s.avctx->color_primaries = get_bits(gb, 8);
- v->s.avctx->color_trc = get_bits(gb, 8);
- v->s.avctx->colorspace = get_bits(gb, 8);
- v->s.avctx->color_range = AVCOL_RANGE_MPEG;
+ v->color_prim = get_bits(gb, 8);
+ v->transfer_char = get_bits(gb, 8);
+ v->matrix_coef = get_bits(gb, 8);
}
}
int panscanflag; ///< NUMPANSCANWIN, TOPLEFT{X,Y}, BOTRIGHT{X,Y} present
int refdist_flag; ///< REFDIST syntax element present in II, IP, PI or PP field picture headers
int extended_dmv; ///< Additional extended dmv range at P/B frame-level
+ int color_prim; ///< 8bits, chroma coordinates of the color primaries
+ int transfer_char; ///< 8bits, Opto-electronic transfer characteristics
+ int matrix_coef; ///< 8bits, Color primaries->YCbCr transform matrix
int hrd_param_flag; ///< Presence of Hypothetical Reference
///< Decoder parameters
int psf; ///< Progressive Segmented Frame
int ff_vc1_decode_end(AVCodecContext *avctx);
void ff_vc1_decode_blocks(VC1Context *v);
+void ff_vc1_loop_filter_iblk(VC1Context *v, int pq);
+void ff_vc1_loop_filter_iblk_delayed(VC1Context *v, int pq);
+void ff_vc1_smooth_overlap_filter_iblk(VC1Context *v);
+void ff_vc1_apply_p_loop_filter(VC1Context *v);
+
+void ff_vc1_mc_1mv(VC1Context *v, int dir);
+void ff_vc1_mc_4mv_luma(VC1Context *v, int n, int dir, int avg);
+void ff_vc1_mc_4mv_chroma(VC1Context *v, int dir);
+void ff_vc1_mc_4mv_chroma4(VC1Context *v, int dir, int dir2, int avg);
+
+void ff_vc1_interp_mc(VC1Context *v);
+
#endif /* AVCODEC_VC1_H */
--- /dev/null
+/*
+ * VC-1 and WMV3 decoder
+ * Copyright (c) 2011 Mashiat Sarker Shakkhar
+ * Copyright (c) 2006-2007 Konstantin Shishkov
+ * Partly based on vc9.c (c) 2005 Anonymous, Alex Beregszaszi, Michael Niedermayer
+ *
+ * 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
+ * VC-1 and WMV3 block decoding routines
+ */
+
+#include "avcodec.h"
+#include "mpegutils.h"
+#include "mpegvideo.h"
+#include "msmpeg4data.h"
+#include "unary.h"
+#include "vc1.h"
+#include "vc1_pred.h"
+#include "vc1acdata.h"
+#include "vc1data.h"
+
+#define MB_INTRA_VLC_BITS 9
+#define DC_VLC_BITS 9
+
+// offset tables for interlaced picture MVDATA decoding
+static const int offset_table1[9] = { 0, 1, 2, 4, 8, 16, 32, 64, 128 };
+static const int offset_table2[9] = { 0, 1, 3, 7, 15, 31, 63, 127, 255 };
+
+/***********************************************************************/
+/**
+ * @name VC-1 Bitplane decoding
+ * @see 8.7, p56
+ * @{
+ */
+
+
+static void init_block_index(VC1Context *v)
+{
+ MpegEncContext *s = &v->s;
+ ff_init_block_index(s);
+ if (v->field_mode && !(v->second_field ^ v->tff)) {
+ s->dest[0] += s->current_picture_ptr->f->linesize[0];
+ s->dest[1] += s->current_picture_ptr->f->linesize[1];
+ s->dest[2] += s->current_picture_ptr->f->linesize[2];
+ }
+}
+
+/** @} */ //Bitplane group
+
+static void vc1_put_signed_blocks_clamped(VC1Context *v)
+{
+ MpegEncContext *s = &v->s;
+ int topleft_mb_pos, top_mb_pos;
+ int stride_y, fieldtx = 0;
+ int v_dist;
+
+ /* The put pixels loop is always one MB row behind the decoding loop,
+ * because we can only put pixels when overlap filtering is done, and
+ * for filtering of the bottom edge of a MB, we need the next MB row
+ * present as well.
+ * Within the row, the put pixels loop is also one MB col behind the
+ * decoding loop. The reason for this is again, because for filtering
+ * of the right MB edge, we need the next MB present. */
+ if (!s->first_slice_line) {
+ if (s->mb_x) {
+ topleft_mb_pos = (s->mb_y - 1) * s->mb_stride + s->mb_x - 1;
+ if (v->fcm == ILACE_FRAME)
+ fieldtx = v->fieldtx_plane[topleft_mb_pos];
+ stride_y = s->linesize << fieldtx;
+ v_dist = (16 - fieldtx) >> (fieldtx == 0);
+ s->idsp.put_signed_pixels_clamped(v->block[v->topleft_blk_idx][0],
+ s->dest[0] - 16 * s->linesize - 16,
+ stride_y);
+ s->idsp.put_signed_pixels_clamped(v->block[v->topleft_blk_idx][1],
+ s->dest[0] - 16 * s->linesize - 8,
+ stride_y);
+ s->idsp.put_signed_pixels_clamped(v->block[v->topleft_blk_idx][2],
+ s->dest[0] - v_dist * s->linesize - 16,
+ stride_y);
+ s->idsp.put_signed_pixels_clamped(v->block[v->topleft_blk_idx][3],
+ s->dest[0] - v_dist * s->linesize - 8,
+ stride_y);
+ s->idsp.put_signed_pixels_clamped(v->block[v->topleft_blk_idx][4],
+ s->dest[1] - 8 * s->uvlinesize - 8,
+ s->uvlinesize);
+ s->idsp.put_signed_pixels_clamped(v->block[v->topleft_blk_idx][5],
+ s->dest[2] - 8 * s->uvlinesize - 8,
+ s->uvlinesize);
+ }
+ if (s->mb_x == s->mb_width - 1) {
+ top_mb_pos = (s->mb_y - 1) * s->mb_stride + s->mb_x;
+ if (v->fcm == ILACE_FRAME)
+ fieldtx = v->fieldtx_plane[top_mb_pos];
+ stride_y = s->linesize << fieldtx;
+ v_dist = fieldtx ? 15 : 8;
+ s->idsp.put_signed_pixels_clamped(v->block[v->top_blk_idx][0],
+ s->dest[0] - 16 * s->linesize,
+ stride_y);
+ s->idsp.put_signed_pixels_clamped(v->block[v->top_blk_idx][1],
+ s->dest[0] - 16 * s->linesize + 8,
+ stride_y);
+ s->idsp.put_signed_pixels_clamped(v->block[v->top_blk_idx][2],
+ s->dest[0] - v_dist * s->linesize,
+ stride_y);
+ s->idsp.put_signed_pixels_clamped(v->block[v->top_blk_idx][3],
+ s->dest[0] - v_dist * s->linesize + 8,
+ stride_y);
+ s->idsp.put_signed_pixels_clamped(v->block[v->top_blk_idx][4],
+ s->dest[1] - 8 * s->uvlinesize,
+ s->uvlinesize);
+ s->idsp.put_signed_pixels_clamped(v->block[v->top_blk_idx][5],
+ s->dest[2] - 8 * s->uvlinesize,
+ s->uvlinesize);
+ }
+ }
+
+#define inc_blk_idx(idx) do { \
+ idx++; \
+ if (idx >= v->n_allocated_blks) \
+ idx = 0; \
+ } while (0)
+
+ inc_blk_idx(v->topleft_blk_idx);
+ inc_blk_idx(v->top_blk_idx);
+ inc_blk_idx(v->left_blk_idx);
+ inc_blk_idx(v->cur_blk_idx);
+}
+
+/***********************************************************************/
+/**
+ * @name VC-1 Block-level functions
+ * @see 7.1.4, p91 and 8.1.1.7, p(1)04
+ * @{
+ */
+
+/**
+ * @def GET_MQUANT
+ * @brief Get macroblock-level quantizer scale
+ */
+#define GET_MQUANT() \
+ if (v->dquantfrm) { \
+ int edges = 0; \
+ if (v->dqprofile == DQPROFILE_ALL_MBS) { \
+ if (v->dqbilevel) { \
+ mquant = (get_bits1(gb)) ? v->altpq : v->pq; \
+ } else { \
+ mqdiff = get_bits(gb, 3); \
+ if (mqdiff != 7) \
+ mquant = v->pq + mqdiff; \
+ else \
+ mquant = get_bits(gb, 5); \
+ } \
+ } \
+ if (v->dqprofile == DQPROFILE_SINGLE_EDGE) \
+ edges = 1 << v->dqsbedge; \
+ else if (v->dqprofile == DQPROFILE_DOUBLE_EDGES) \
+ edges = (3 << v->dqsbedge) % 15; \
+ else if (v->dqprofile == DQPROFILE_FOUR_EDGES) \
+ edges = 15; \
+ if ((edges&1) && !s->mb_x) \
+ mquant = v->altpq; \
+ if ((edges&2) && s->first_slice_line) \
+ mquant = v->altpq; \
+ if ((edges&4) && s->mb_x == (s->mb_width - 1)) \
+ mquant = v->altpq; \
+ if ((edges&8) && s->mb_y == (s->mb_height - 1)) \
+ mquant = v->altpq; \
+ if (!mquant || mquant > 31) { \
+ av_log(v->s.avctx, AV_LOG_ERROR, \
+ "Overriding invalid mquant %d\n", mquant); \
+ mquant = 1; \
+ } \
+ }
+
+/**
+ * @def GET_MVDATA(_dmv_x, _dmv_y)
+ * @brief Get MV differentials
+ * @see MVDATA decoding from 8.3.5.2, p(1)20
+ * @param _dmv_x Horizontal differential for decoded MV
+ * @param _dmv_y Vertical differential for decoded MV
+ */
+#define GET_MVDATA(_dmv_x, _dmv_y) \
+ index = 1 + get_vlc2(gb, ff_vc1_mv_diff_vlc[s->mv_table_index].table, \
+ VC1_MV_DIFF_VLC_BITS, 2); \
+ if (index > 36) { \
+ mb_has_coeffs = 1; \
+ index -= 37; \
+ } else \
+ mb_has_coeffs = 0; \
+ s->mb_intra = 0; \
+ if (!index) { \
+ _dmv_x = _dmv_y = 0; \
+ } else if (index == 35) { \
+ _dmv_x = get_bits(gb, v->k_x - 1 + s->quarter_sample); \
+ _dmv_y = get_bits(gb, v->k_y - 1 + s->quarter_sample); \
+ } else if (index == 36) { \
+ _dmv_x = 0; \
+ _dmv_y = 0; \
+ s->mb_intra = 1; \
+ } else { \
+ index1 = index % 6; \
+ if (!s->quarter_sample && index1 == 5) val = 1; \
+ else val = 0; \
+ if (size_table[index1] - val > 0) \
+ val = get_bits(gb, size_table[index1] - val); \
+ else val = 0; \
+ sign = 0 - (val&1); \
+ _dmv_x = (sign ^ ((val>>1) + offset_table[index1])) - sign; \
+ \
+ index1 = index / 6; \
+ if (!s->quarter_sample && index1 == 5) val = 1; \
+ else val = 0; \
+ if (size_table[index1] - val > 0) \
+ val = get_bits(gb, size_table[index1] - val); \
+ else val = 0; \
+ sign = 0 - (val & 1); \
+ _dmv_y = (sign ^ ((val >> 1) + offset_table[index1])) - sign; \
+ }
+
+static av_always_inline void get_mvdata_interlaced(VC1Context *v, int *dmv_x,
+ int *dmv_y, int *pred_flag)
+{
+ int index, index1;
+ int extend_x = 0, extend_y = 0;
+ GetBitContext *gb = &v->s.gb;
+ int bits, esc;
+ int val, sign;
+ const int* offs_tab;
+
+ if (v->numref) {
+ bits = VC1_2REF_MVDATA_VLC_BITS;
+ esc = 125;
+ } else {
+ bits = VC1_1REF_MVDATA_VLC_BITS;
+ esc = 71;
+ }
+ switch (v->dmvrange) {
+ case 1:
+ extend_x = 1;
+ break;
+ case 2:
+ extend_y = 1;
+ break;
+ case 3:
+ extend_x = extend_y = 1;
+ break;
+ }
+ index = get_vlc2(gb, v->imv_vlc->table, bits, 3);
+ if (index == esc) {
+ *dmv_x = get_bits(gb, v->k_x);
+ *dmv_y = get_bits(gb, v->k_y);
+ if (v->numref) {
+ if (pred_flag) {
+ *pred_flag = *dmv_y & 1;
+ *dmv_y = (*dmv_y + *pred_flag) >> 1;
+ } else {
+ *dmv_y = (*dmv_y + (*dmv_y & 1)) >> 1;
+ }
+ }
+ }
+ else {
+ av_assert0(index < esc);
+ if (extend_x)
+ offs_tab = offset_table2;
+ else
+ offs_tab = offset_table1;
+ index1 = (index + 1) % 9;
+ if (index1 != 0) {
+ val = get_bits(gb, index1 + extend_x);
+ sign = 0 -(val & 1);
+ *dmv_x = (sign ^ ((val >> 1) + offs_tab[index1])) - sign;
+ } else
+ *dmv_x = 0;
+ if (extend_y)
+ offs_tab = offset_table2;
+ else
+ offs_tab = offset_table1;
+ index1 = (index + 1) / 9;
+ if (index1 > v->numref) {
+ val = get_bits(gb, (index1 + (extend_y << v->numref)) >> v->numref);
+ sign = 0 - (val & 1);
+ *dmv_y = (sign ^ ((val >> 1) + offs_tab[index1 >> v->numref])) - sign;
+ } else
+ *dmv_y = 0;
+ if (v->numref && pred_flag)
+ *pred_flag = index1 & 1;
+ }
+}
+
+/** Reconstruct motion vector for B-frame and do motion compensation
+ */
+static inline void vc1_b_mc(VC1Context *v, int dmv_x[2], int dmv_y[2],
+ int direct, int mode)
+{
+ if (direct) {
+ ff_vc1_mc_1mv(v, 0);
+ ff_vc1_interp_mc(v);
+ return;
+ }
+ if (mode == BMV_TYPE_INTERPOLATED) {
+ ff_vc1_mc_1mv(v, 0);
+ ff_vc1_interp_mc(v);
+ return;
+ }
+
+ ff_vc1_mc_1mv(v, (mode == BMV_TYPE_BACKWARD));
+}
+
+/** Get predicted DC value for I-frames only
+ * prediction dir: left=0, top=1
+ * @param s MpegEncContext
+ * @param overlap flag indicating that overlap filtering is used
+ * @param pq integer part of picture quantizer
+ * @param[in] n block index in the current MB
+ * @param dc_val_ptr Pointer to DC predictor
+ * @param dir_ptr Prediction direction for use in AC prediction
+ */
+static inline int vc1_i_pred_dc(MpegEncContext *s, int overlap, int pq, int n,
+ int16_t **dc_val_ptr, int *dir_ptr)
+{
+ int a, b, c, wrap, pred, scale;
+ int16_t *dc_val;
+ static const uint16_t dcpred[32] = {
+ -1, 1024, 512, 341, 256, 205, 171, 146, 128,
+ 114, 102, 93, 85, 79, 73, 68, 64,
+ 60, 57, 54, 51, 49, 47, 45, 43,
+ 41, 39, 38, 37, 35, 34, 33
+ };
+
+ /* find prediction - wmv3_dc_scale always used here in fact */
+ if (n < 4) scale = s->y_dc_scale;
+ else scale = s->c_dc_scale;
+
+ wrap = s->block_wrap[n];
+ dc_val = s->dc_val[0] + s->block_index[n];
+
+ /* B A
+ * C X
+ */
+ c = dc_val[ - 1];
+ b = dc_val[ - 1 - wrap];
+ a = dc_val[ - wrap];
+
+ if (pq < 9 || !overlap) {
+ /* Set outer values */
+ if (s->first_slice_line && (n != 2 && n != 3))
+ b = a = dcpred[scale];
+ if (s->mb_x == 0 && (n != 1 && n != 3))
+ b = c = dcpred[scale];
+ } else {
+ /* Set outer values */
+ if (s->first_slice_line && (n != 2 && n != 3))
+ b = a = 0;
+ if (s->mb_x == 0 && (n != 1 && n != 3))
+ b = c = 0;
+ }
+
+ if (abs(a - b) <= abs(b - c)) {
+ pred = c;
+ *dir_ptr = 1; // left
+ } else {
+ pred = a;
+ *dir_ptr = 0; // top
+ }
+
+ /* update predictor */
+ *dc_val_ptr = &dc_val[0];
+ return pred;
+}
+
+
+/** Get predicted DC value
+ * prediction dir: left=0, top=1
+ * @param s MpegEncContext
+ * @param overlap flag indicating that overlap filtering is used
+ * @param pq integer part of picture quantizer
+ * @param[in] n block index in the current MB
+ * @param a_avail flag indicating top block availability
+ * @param c_avail flag indicating left block availability
+ * @param dc_val_ptr Pointer to DC predictor
+ * @param dir_ptr Prediction direction for use in AC prediction
+ */
+static inline int ff_vc1_pred_dc(MpegEncContext *s, int overlap, int pq, int n,
+ int a_avail, int c_avail,
+ int16_t **dc_val_ptr, int *dir_ptr)
+{
+ int a, b, c, wrap, pred;
+ int16_t *dc_val;
+ int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
+ int q1, q2 = 0;
+ int dqscale_index;
+
+ wrap = s->block_wrap[n];
+ dc_val = s->dc_val[0] + s->block_index[n];
+
+ /* B A
+ * C X
+ */
+ c = dc_val[ - 1];
+ b = dc_val[ - 1 - wrap];
+ a = dc_val[ - wrap];
+ /* scale predictors if needed */
+ q1 = s->current_picture.qscale_table[mb_pos];
+ dqscale_index = s->y_dc_scale_table[q1] - 1;
+ if (dqscale_index < 0)
+ return 0;
+ if (c_avail && (n != 1 && n != 3)) {
+ q2 = s->current_picture.qscale_table[mb_pos - 1];
+ if (q2 && q2 != q1)
+ c = (c * s->y_dc_scale_table[q2] * ff_vc1_dqscale[dqscale_index] + 0x20000) >> 18;
+ }
+ if (a_avail && (n != 2 && n != 3)) {
+ q2 = s->current_picture.qscale_table[mb_pos - s->mb_stride];
+ if (q2 && q2 != q1)
+ a = (a * s->y_dc_scale_table[q2] * ff_vc1_dqscale[dqscale_index] + 0x20000) >> 18;
+ }
+ if (a_avail && c_avail && (n != 3)) {
+ int off = mb_pos;
+ if (n != 1)
+ off--;
+ if (n != 2)
+ off -= s->mb_stride;
+ q2 = s->current_picture.qscale_table[off];
+ if (q2 && q2 != q1)
+ b = (b * s->y_dc_scale_table[q2] * ff_vc1_dqscale[dqscale_index] + 0x20000) >> 18;
+ }
+
+ if (a_avail && c_avail) {
+ if (abs(a - b) <= abs(b - c)) {
+ pred = c;
+ *dir_ptr = 1; // left
+ } else {
+ pred = a;
+ *dir_ptr = 0; // top
+ }
+ } else if (a_avail) {
+ pred = a;
+ *dir_ptr = 0; // top
+ } else if (c_avail) {
+ pred = c;
+ *dir_ptr = 1; // left
+ } else {
+ pred = 0;
+ *dir_ptr = 1; // left
+ }
+
+ /* update predictor */
+ *dc_val_ptr = &dc_val[0];
+ return pred;
+}
+
+/** @} */ // Block group
+
+/**
+ * @name VC1 Macroblock-level functions in Simple/Main Profiles
+ * @see 7.1.4, p91 and 8.1.1.7, p(1)04
+ * @{
+ */
+
+static inline int vc1_coded_block_pred(MpegEncContext * s, int n,
+ uint8_t **coded_block_ptr)
+{
+ int xy, wrap, pred, a, b, c;
+
+ xy = s->block_index[n];
+ wrap = s->b8_stride;
+
+ /* B C
+ * A X
+ */
+ a = s->coded_block[xy - 1 ];
+ b = s->coded_block[xy - 1 - wrap];
+ c = s->coded_block[xy - wrap];
+
+ if (b == c) {
+ pred = a;
+ } else {
+ pred = c;
+ }
+
+ /* store value */
+ *coded_block_ptr = &s->coded_block[xy];
+
+ return pred;
+}
+
+/**
+ * Decode one AC coefficient
+ * @param v The VC1 context
+ * @param last Last coefficient
+ * @param skip How much zero coefficients to skip
+ * @param value Decoded AC coefficient value
+ * @param codingset set of VLC to decode data
+ * @see 8.1.3.4
+ */
+static void vc1_decode_ac_coeff(VC1Context *v, int *last, int *skip,
+ int *value, int codingset)
+{
+ GetBitContext *gb = &v->s.gb;
+ int index, escape, run = 0, level = 0, lst = 0;
+
+ index = get_vlc2(gb, ff_vc1_ac_coeff_table[codingset].table, AC_VLC_BITS, 3);
+ if (index != ff_vc1_ac_sizes[codingset] - 1) {
+ run = vc1_index_decode_table[codingset][index][0];
+ level = vc1_index_decode_table[codingset][index][1];
+ lst = index >= vc1_last_decode_table[codingset] || get_bits_left(gb) < 0;
+ if (get_bits1(gb))
+ level = -level;
+ } else {
+ escape = decode210(gb);
+ if (escape != 2) {
+ index = get_vlc2(gb, ff_vc1_ac_coeff_table[codingset].table, AC_VLC_BITS, 3);
+ run = vc1_index_decode_table[codingset][index][0];
+ level = vc1_index_decode_table[codingset][index][1];
+ lst = index >= vc1_last_decode_table[codingset];
+ if (escape == 0) {
+ if (lst)
+ level += vc1_last_delta_level_table[codingset][run];
+ else
+ level += vc1_delta_level_table[codingset][run];
+ } else {
+ if (lst)
+ run += vc1_last_delta_run_table[codingset][level] + 1;
+ else
+ run += vc1_delta_run_table[codingset][level] + 1;
+ }
+ if (get_bits1(gb))
+ level = -level;
+ } else {
+ int sign;
+ lst = get_bits1(gb);
+ if (v->s.esc3_level_length == 0) {
+ if (v->pq < 8 || v->dquantfrm) { // table 59
+ v->s.esc3_level_length = get_bits(gb, 3);
+ if (!v->s.esc3_level_length)
+ v->s.esc3_level_length = get_bits(gb, 2) + 8;
+ } else { // table 60
+ v->s.esc3_level_length = get_unary(gb, 1, 6) + 2;
+ }
+ v->s.esc3_run_length = 3 + get_bits(gb, 2);
+ }
+ run = get_bits(gb, v->s.esc3_run_length);
+ sign = get_bits1(gb);
+ level = get_bits(gb, v->s.esc3_level_length);
+ if (sign)
+ level = -level;
+ }
+ }
+
+ *last = lst;
+ *skip = run;
+ *value = level;
+}
+
+/** Decode intra block in intra frames - should be faster than decode_intra_block
+ * @param v VC1Context
+ * @param block block to decode
+ * @param[in] n subblock index
+ * @param coded are AC coeffs present or not
+ * @param codingset set of VLC to decode data
+ */
+static int vc1_decode_i_block(VC1Context *v, int16_t block[64], int n,
+ int coded, int codingset)
+{
+ GetBitContext *gb = &v->s.gb;
+ MpegEncContext *s = &v->s;
+ int dc_pred_dir = 0; /* Direction of the DC prediction used */
+ int i;
+ int16_t *dc_val;
+ int16_t *ac_val, *ac_val2;
+ int dcdiff;
+
+ /* Get DC differential */
+ if (n < 4) {
+ dcdiff = get_vlc2(&s->gb, ff_msmp4_dc_luma_vlc[s->dc_table_index].table, DC_VLC_BITS, 3);
+ } else {
+ dcdiff = get_vlc2(&s->gb, ff_msmp4_dc_chroma_vlc[s->dc_table_index].table, DC_VLC_BITS, 3);
+ }
+ if (dcdiff < 0) {
+ av_log(s->avctx, AV_LOG_ERROR, "Illegal DC VLC\n");
+ return -1;
+ }
+ if (dcdiff) {
+ if (dcdiff == 119 /* ESC index value */) {
+ /* TODO: Optimize */
+ if (v->pq == 1) dcdiff = get_bits(gb, 10);
+ else if (v->pq == 2) dcdiff = get_bits(gb, 9);
+ else dcdiff = get_bits(gb, 8);
+ } else {
+ if (v->pq == 1)
+ dcdiff = (dcdiff << 2) + get_bits(gb, 2) - 3;
+ else if (v->pq == 2)
+ dcdiff = (dcdiff << 1) + get_bits1(gb) - 1;
+ }
+ if (get_bits1(gb))
+ dcdiff = -dcdiff;
+ }
+
+ /* Prediction */
+ dcdiff += vc1_i_pred_dc(&v->s, v->overlap, v->pq, n, &dc_val, &dc_pred_dir);
+ *dc_val = dcdiff;
+
+ /* Store the quantized DC coeff, used for prediction */
+ if (n < 4) {
+ block[0] = dcdiff * s->y_dc_scale;
+ } else {
+ block[0] = dcdiff * s->c_dc_scale;
+ }
+ /* Skip ? */
+ if (!coded) {
+ goto not_coded;
+ }
+
+ // AC Decoding
+ i = 1;
+
+ {
+ int last = 0, skip, value;
+ const uint8_t *zz_table;
+ int scale;
+ int k;
+
+ scale = v->pq * 2 + v->halfpq;
+
+ if (v->s.ac_pred) {
+ if (!dc_pred_dir)
+ zz_table = v->zz_8x8[2];
+ else
+ zz_table = v->zz_8x8[3];
+ } else
+ zz_table = v->zz_8x8[1];
+
+ ac_val = s->ac_val[0][0] + s->block_index[n] * 16;
+ ac_val2 = ac_val;
+ if (dc_pred_dir) // left
+ ac_val -= 16;
+ else // top
+ ac_val -= 16 * s->block_wrap[n];
+
+ while (!last) {
+ vc1_decode_ac_coeff(v, &last, &skip, &value, codingset);
+ i += skip;
+ if (i > 63)
+ break;
+ block[zz_table[i++]] = value;
+ }
+
+ /* apply AC prediction if needed */
+ if (s->ac_pred) {
+ if (dc_pred_dir) { // left
+ for (k = 1; k < 8; k++)
+ block[k << v->left_blk_sh] += ac_val[k];
+ } else { // top
+ for (k = 1; k < 8; k++)
+ block[k << v->top_blk_sh] += ac_val[k + 8];
+ }
+ }
+ /* save AC coeffs for further prediction */
+ for (k = 1; k < 8; k++) {
+ ac_val2[k] = block[k << v->left_blk_sh];
+ ac_val2[k + 8] = block[k << v->top_blk_sh];
+ }
+
+ /* scale AC coeffs */
+ for (k = 1; k < 64; k++)
+ if (block[k]) {
+ block[k] *= scale;
+ if (!v->pquantizer)
+ block[k] += (block[k] < 0) ? -v->pq : v->pq;
+ }
+
+ if (s->ac_pred) i = 63;
+ }
+
+not_coded:
+ if (!coded) {
+ int k, scale;
+ ac_val = s->ac_val[0][0] + s->block_index[n] * 16;
+ ac_val2 = ac_val;
+
+ i = 0;
+ scale = v->pq * 2 + v->halfpq;
+ memset(ac_val2, 0, 16 * 2);
+ if (dc_pred_dir) { // left
+ ac_val -= 16;
+ if (s->ac_pred)
+ memcpy(ac_val2, ac_val, 8 * 2);
+ } else { // top
+ ac_val -= 16 * s->block_wrap[n];
+ if (s->ac_pred)
+ memcpy(ac_val2 + 8, ac_val + 8, 8 * 2);
+ }
+
+ /* apply AC prediction if needed */
+ if (s->ac_pred) {
+ if (dc_pred_dir) { //left
+ for (k = 1; k < 8; k++) {
+ block[k << v->left_blk_sh] = ac_val[k] * scale;
+ if (!v->pquantizer && block[k << v->left_blk_sh])
+ block[k << v->left_blk_sh] += (block[k << v->left_blk_sh] < 0) ? -v->pq : v->pq;
+ }
+ } else { // top
+ for (k = 1; k < 8; k++) {
+ block[k << v->top_blk_sh] = ac_val[k + 8] * scale;
+ if (!v->pquantizer && block[k << v->top_blk_sh])
+ block[k << v->top_blk_sh] += (block[k << v->top_blk_sh] < 0) ? -v->pq : v->pq;
+ }
+ }
+ i = 63;
+ }
+ }
+ s->block_last_index[n] = i;
+
+ return 0;
+}
+
+/** Decode intra block in intra frames - should be faster than decode_intra_block
+ * @param v VC1Context
+ * @param block block to decode
+ * @param[in] n subblock number
+ * @param coded are AC coeffs present or not
+ * @param codingset set of VLC to decode data
+ * @param mquant quantizer value for this macroblock
+ */
+static int vc1_decode_i_block_adv(VC1Context *v, int16_t block[64], int n,
+ int coded, int codingset, int mquant)
+{
+ GetBitContext *gb = &v->s.gb;
+ MpegEncContext *s = &v->s;
+ int dc_pred_dir = 0; /* Direction of the DC prediction used */
+ int i;
+ int16_t *dc_val = NULL;
+ int16_t *ac_val, *ac_val2;
+ int dcdiff;
+ int a_avail = v->a_avail, c_avail = v->c_avail;
+ int use_pred = s->ac_pred;
+ int scale;
+ int q1, q2 = 0;
+ int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
+
+ /* Get DC differential */
+ if (n < 4) {
+ dcdiff = get_vlc2(&s->gb, ff_msmp4_dc_luma_vlc[s->dc_table_index].table, DC_VLC_BITS, 3);
+ } else {
+ dcdiff = get_vlc2(&s->gb, ff_msmp4_dc_chroma_vlc[s->dc_table_index].table, DC_VLC_BITS, 3);
+ }
+ if (dcdiff < 0) {
+ av_log(s->avctx, AV_LOG_ERROR, "Illegal DC VLC\n");
+ return -1;
+ }
+ if (dcdiff) {
+ if (dcdiff == 119 /* ESC index value */) {
+ /* TODO: Optimize */
+ if (mquant == 1) dcdiff = get_bits(gb, 10);
+ else if (mquant == 2) dcdiff = get_bits(gb, 9);
+ else dcdiff = get_bits(gb, 8);
+ } else {
+ if (mquant == 1)
+ dcdiff = (dcdiff << 2) + get_bits(gb, 2) - 3;
+ else if (mquant == 2)
+ dcdiff = (dcdiff << 1) + get_bits1(gb) - 1;
+ }
+ if (get_bits1(gb))
+ dcdiff = -dcdiff;
+ }
+
+ /* Prediction */
+ dcdiff += ff_vc1_pred_dc(&v->s, v->overlap, mquant, n, v->a_avail, v->c_avail, &dc_val, &dc_pred_dir);
+ *dc_val = dcdiff;
+
+ /* Store the quantized DC coeff, used for prediction */
+ if (n < 4) {
+ block[0] = dcdiff * s->y_dc_scale;
+ } else {
+ block[0] = dcdiff * s->c_dc_scale;
+ }
+
+ //AC Decoding
+ i = 1;
+
+ /* check if AC is needed at all */
+ if (!a_avail && !c_avail)
+ use_pred = 0;
+ ac_val = s->ac_val[0][0] + s->block_index[n] * 16;
+ ac_val2 = ac_val;
+
+ scale = mquant * 2 + ((mquant == v->pq) ? v->halfpq : 0);
+
+ if (dc_pred_dir) // left
+ ac_val -= 16;
+ else // top
+ ac_val -= 16 * s->block_wrap[n];
+
+ q1 = s->current_picture.qscale_table[mb_pos];
+ if ( dc_pred_dir && c_avail && mb_pos)
+ q2 = s->current_picture.qscale_table[mb_pos - 1];
+ if (!dc_pred_dir && a_avail && mb_pos >= s->mb_stride)
+ q2 = s->current_picture.qscale_table[mb_pos - s->mb_stride];
+ if ( dc_pred_dir && n == 1)
+ q2 = q1;
+ if (!dc_pred_dir && n == 2)
+ q2 = q1;
+ if (n == 3)
+ q2 = q1;
+
+ if (coded) {
+ int last = 0, skip, value;
+ const uint8_t *zz_table;
+ int k;
+
+ if (v->s.ac_pred) {
+ if (!use_pred && v->fcm == ILACE_FRAME) {
+ zz_table = v->zzi_8x8;
+ } else {
+ if (!dc_pred_dir) // top
+ zz_table = v->zz_8x8[2];
+ else // left
+ zz_table = v->zz_8x8[3];
+ }
+ } else {
+ if (v->fcm != ILACE_FRAME)
+ zz_table = v->zz_8x8[1];
+ else
+ zz_table = v->zzi_8x8;
+ }
+
+ while (!last) {
+ vc1_decode_ac_coeff(v, &last, &skip, &value, codingset);
+ i += skip;
+ if (i > 63)
+ break;
+ block[zz_table[i++]] = value;
+ }
+
+ /* apply AC prediction if needed */
+ if (use_pred) {
+ /* scale predictors if needed*/
+ if (q2 && q1 != q2) {
+ q1 = q1 * 2 + ((q1 == v->pq) ? v->halfpq : 0) - 1;
+ q2 = q2 * 2 + ((q2 == v->pq) ? v->halfpq : 0) - 1;
+
+ if (q1 < 1)
+ return AVERROR_INVALIDDATA;
+ if (dc_pred_dir) { // left
+ for (k = 1; k < 8; k++)
+ block[k << v->left_blk_sh] += (ac_val[k] * q2 * ff_vc1_dqscale[q1 - 1] + 0x20000) >> 18;
+ } else { // top
+ for (k = 1; k < 8; k++)
+ block[k << v->top_blk_sh] += (ac_val[k + 8] * q2 * ff_vc1_dqscale[q1 - 1] + 0x20000) >> 18;
+ }
+ } else {
+ if (dc_pred_dir) { //left
+ for (k = 1; k < 8; k++)
+ block[k << v->left_blk_sh] += ac_val[k];
+ } else { //top
+ for (k = 1; k < 8; k++)
+ block[k << v->top_blk_sh] += ac_val[k + 8];
+ }
+ }
+ }
+ /* save AC coeffs for further prediction */
+ for (k = 1; k < 8; k++) {
+ ac_val2[k ] = block[k << v->left_blk_sh];
+ ac_val2[k + 8] = block[k << v->top_blk_sh];
+ }
+
+ /* scale AC coeffs */
+ for (k = 1; k < 64; k++)
+ if (block[k]) {
+ block[k] *= scale;
+ if (!v->pquantizer)
+ block[k] += (block[k] < 0) ? -mquant : mquant;
+ }
+
+ if (use_pred) i = 63;
+ } else { // no AC coeffs
+ int k;
+
+ memset(ac_val2, 0, 16 * 2);
+ if (dc_pred_dir) { // left
+ if (use_pred) {
+ memcpy(ac_val2, ac_val, 8 * 2);
+ if (q2 && q1 != q2) {
+ q1 = q1 * 2 + ((q1 == v->pq) ? v->halfpq : 0) - 1;
+ q2 = q2 * 2 + ((q2 == v->pq) ? v->halfpq : 0) - 1;
+ if (q1 < 1)
+ return AVERROR_INVALIDDATA;
+ for (k = 1; k < 8; k++)
+ ac_val2[k] = (ac_val2[k] * q2 * ff_vc1_dqscale[q1 - 1] + 0x20000) >> 18;
+ }
+ }
+ } else { // top
+ if (use_pred) {
+ memcpy(ac_val2 + 8, ac_val + 8, 8 * 2);
+ if (q2 && q1 != q2) {
+ q1 = q1 * 2 + ((q1 == v->pq) ? v->halfpq : 0) - 1;
+ q2 = q2 * 2 + ((q2 == v->pq) ? v->halfpq : 0) - 1;
+ if (q1 < 1)
+ return AVERROR_INVALIDDATA;
+ for (k = 1; k < 8; k++)
+ ac_val2[k + 8] = (ac_val2[k + 8] * q2 * ff_vc1_dqscale[q1 - 1] + 0x20000) >> 18;
+ }
+ }
+ }
+
+ /* apply AC prediction if needed */
+ if (use_pred) {
+ if (dc_pred_dir) { // left
+ for (k = 1; k < 8; k++) {
+ block[k << v->left_blk_sh] = ac_val2[k] * scale;
+ if (!v->pquantizer && block[k << v->left_blk_sh])
+ block[k << v->left_blk_sh] += (block[k << v->left_blk_sh] < 0) ? -mquant : mquant;
+ }
+ } else { // top
+ for (k = 1; k < 8; k++) {
+ block[k << v->top_blk_sh] = ac_val2[k + 8] * scale;
+ if (!v->pquantizer && block[k << v->top_blk_sh])
+ block[k << v->top_blk_sh] += (block[k << v->top_blk_sh] < 0) ? -mquant : mquant;
+ }
+ }
+ i = 63;
+ }
+ }
+ s->block_last_index[n] = i;
+
+ return 0;
+}
+
+/** Decode intra block in inter frames - more generic version than vc1_decode_i_block
+ * @param v VC1Context
+ * @param block block to decode
+ * @param[in] n subblock index
+ * @param coded are AC coeffs present or not
+ * @param mquant block quantizer
+ * @param codingset set of VLC to decode data
+ */
+static int vc1_decode_intra_block(VC1Context *v, int16_t block[64], int n,
+ int coded, int mquant, int codingset)
+{
+ GetBitContext *gb = &v->s.gb;
+ MpegEncContext *s = &v->s;
+ int dc_pred_dir = 0; /* Direction of the DC prediction used */
+ int i;
+ int16_t *dc_val = NULL;
+ int16_t *ac_val, *ac_val2;
+ int dcdiff;
+ int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
+ int a_avail = v->a_avail, c_avail = v->c_avail;
+ int use_pred = s->ac_pred;
+ int scale;
+ int q1, q2 = 0;
+
+ s->bdsp.clear_block(block);
+
+ /* XXX: Guard against dumb values of mquant */
+ mquant = (mquant < 1) ? 0 : ((mquant > 31) ? 31 : mquant);
+
+ /* Set DC scale - y and c use the same */
+ s->y_dc_scale = s->y_dc_scale_table[mquant];
+ s->c_dc_scale = s->c_dc_scale_table[mquant];
+
+ /* Get DC differential */
+ if (n < 4) {
+ dcdiff = get_vlc2(&s->gb, ff_msmp4_dc_luma_vlc[s->dc_table_index].table, DC_VLC_BITS, 3);
+ } else {
+ dcdiff = get_vlc2(&s->gb, ff_msmp4_dc_chroma_vlc[s->dc_table_index].table, DC_VLC_BITS, 3);
+ }
+ if (dcdiff < 0) {
+ av_log(s->avctx, AV_LOG_ERROR, "Illegal DC VLC\n");
+ return -1;
+ }
+ if (dcdiff) {
+ if (dcdiff == 119 /* ESC index value */) {
+ /* TODO: Optimize */
+ if (mquant == 1) dcdiff = get_bits(gb, 10);
+ else if (mquant == 2) dcdiff = get_bits(gb, 9);
+ else dcdiff = get_bits(gb, 8);
+ } else {
+ if (mquant == 1)
+ dcdiff = (dcdiff << 2) + get_bits(gb, 2) - 3;
+ else if (mquant == 2)
+ dcdiff = (dcdiff << 1) + get_bits1(gb) - 1;
+ }
+ if (get_bits1(gb))
+ dcdiff = -dcdiff;
+ }
+
+ /* Prediction */
+ dcdiff += ff_vc1_pred_dc(&v->s, v->overlap, mquant, n, a_avail, c_avail, &dc_val, &dc_pred_dir);
+ *dc_val = dcdiff;
+
+ /* Store the quantized DC coeff, used for prediction */
+
+ if (n < 4) {
+ block[0] = dcdiff * s->y_dc_scale;
+ } else {
+ block[0] = dcdiff * s->c_dc_scale;
+ }
+
+ //AC Decoding
+ i = 1;
+
+ /* check if AC is needed at all and adjust direction if needed */
+ if (!a_avail) dc_pred_dir = 1;
+ if (!c_avail) dc_pred_dir = 0;
+ if (!a_avail && !c_avail) use_pred = 0;
+ ac_val = s->ac_val[0][0] + s->block_index[n] * 16;
+ ac_val2 = ac_val;
+
+ scale = mquant * 2 + v->halfpq;
+
+ if (dc_pred_dir) //left
+ ac_val -= 16;
+ else //top
+ ac_val -= 16 * s->block_wrap[n];
+
+ q1 = s->current_picture.qscale_table[mb_pos];
+ if (dc_pred_dir && c_avail && mb_pos)
+ q2 = s->current_picture.qscale_table[mb_pos - 1];
+ if (!dc_pred_dir && a_avail && mb_pos >= s->mb_stride)
+ q2 = s->current_picture.qscale_table[mb_pos - s->mb_stride];
+ if ( dc_pred_dir && n == 1)
+ q2 = q1;
+ if (!dc_pred_dir && n == 2)
+ q2 = q1;
+ if (n == 3) q2 = q1;
+
+ if (coded) {
+ int last = 0, skip, value;
+ int k;
+
+ while (!last) {
+ vc1_decode_ac_coeff(v, &last, &skip, &value, codingset);
+ i += skip;
+ if (i > 63)
+ break;
+ if (v->fcm == PROGRESSIVE)
+ block[v->zz_8x8[0][i++]] = value;
+ else {
+ if (use_pred && (v->fcm == ILACE_FRAME)) {
+ if (!dc_pred_dir) // top
+ block[v->zz_8x8[2][i++]] = value;
+ else // left
+ block[v->zz_8x8[3][i++]] = value;
+ } else {
+ block[v->zzi_8x8[i++]] = value;
+ }
+ }
+ }
+
+ /* apply AC prediction if needed */
+ if (use_pred) {
+ /* scale predictors if needed*/
+ if (q2 && q1 != q2) {
+ q1 = q1 * 2 + ((q1 == v->pq) ? v->halfpq : 0) - 1;
+ q2 = q2 * 2 + ((q2 == v->pq) ? v->halfpq : 0) - 1;
+
+ if (q1 < 1)
+ return AVERROR_INVALIDDATA;
+ if (dc_pred_dir) { // left
+ for (k = 1; k < 8; k++)
+ block[k << v->left_blk_sh] += (ac_val[k] * q2 * ff_vc1_dqscale[q1 - 1] + 0x20000) >> 18;
+ } else { //top
+ for (k = 1; k < 8; k++)
+ block[k << v->top_blk_sh] += (ac_val[k + 8] * q2 * ff_vc1_dqscale[q1 - 1] + 0x20000) >> 18;
+ }
+ } else {
+ if (dc_pred_dir) { // left
+ for (k = 1; k < 8; k++)
+ block[k << v->left_blk_sh] += ac_val[k];
+ } else { // top
+ for (k = 1; k < 8; k++)
+ block[k << v->top_blk_sh] += ac_val[k + 8];
+ }
+ }
+ }
+ /* save AC coeffs for further prediction */
+ for (k = 1; k < 8; k++) {
+ ac_val2[k ] = block[k << v->left_blk_sh];
+ ac_val2[k + 8] = block[k << v->top_blk_sh];
+ }
+
+ /* scale AC coeffs */
+ for (k = 1; k < 64; k++)
+ if (block[k]) {
+ block[k] *= scale;
+ if (!v->pquantizer)
+ block[k] += (block[k] < 0) ? -mquant : mquant;
+ }
+
+ if (use_pred) i = 63;
+ } else { // no AC coeffs
+ int k;
+
+ memset(ac_val2, 0, 16 * 2);
+ if (dc_pred_dir) { // left
+ if (use_pred) {
+ memcpy(ac_val2, ac_val, 8 * 2);
+ if (q2 && q1 != q2) {
+ q1 = q1 * 2 + ((q1 == v->pq) ? v->halfpq : 0) - 1;
+ q2 = q2 * 2 + ((q2 == v->pq) ? v->halfpq : 0) - 1;
+ if (q1 < 1)
+ return AVERROR_INVALIDDATA;
+ for (k = 1; k < 8; k++)
+ ac_val2[k] = (ac_val2[k] * q2 * ff_vc1_dqscale[q1 - 1] + 0x20000) >> 18;
+ }
+ }
+ } else { // top
+ if (use_pred) {
+ memcpy(ac_val2 + 8, ac_val + 8, 8 * 2);
+ if (q2 && q1 != q2) {
+ q1 = q1 * 2 + ((q1 == v->pq) ? v->halfpq : 0) - 1;
+ q2 = q2 * 2 + ((q2 == v->pq) ? v->halfpq : 0) - 1;
+ if (q1 < 1)
+ return AVERROR_INVALIDDATA;
+ for (k = 1; k < 8; k++)
+ ac_val2[k + 8] = (ac_val2[k + 8] * q2 * ff_vc1_dqscale[q1 - 1] + 0x20000) >> 18;
+ }
+ }
+ }
+
+ /* apply AC prediction if needed */
+ if (use_pred) {
+ if (dc_pred_dir) { // left
+ for (k = 1; k < 8; k++) {
+ block[k << v->left_blk_sh] = ac_val2[k] * scale;
+ if (!v->pquantizer && block[k << v->left_blk_sh])
+ block[k << v->left_blk_sh] += (block[k << v->left_blk_sh] < 0) ? -mquant : mquant;
+ }
+ } else { // top
+ for (k = 1; k < 8; k++) {
+ block[k << v->top_blk_sh] = ac_val2[k + 8] * scale;
+ if (!v->pquantizer && block[k << v->top_blk_sh])
+ block[k << v->top_blk_sh] += (block[k << v->top_blk_sh] < 0) ? -mquant : mquant;
+ }
+ }
+ i = 63;
+ }
+ }
+ s->block_last_index[n] = i;
+
+ return 0;
+}
+
+/** Decode P block
+ */
+static int vc1_decode_p_block(VC1Context *v, int16_t block[64], int n,
+ int mquant, int ttmb, int first_block,
+ uint8_t *dst, int linesize, int skip_block,
+ int *ttmb_out)
+{
+ MpegEncContext *s = &v->s;
+ GetBitContext *gb = &s->gb;
+ int i, j;
+ int subblkpat = 0;
+ int scale, off, idx, last, skip, value;
+ int ttblk = ttmb & 7;
+ int pat = 0;
+
+ s->bdsp.clear_block(block);
+
+ if (ttmb == -1) {
+ ttblk = ff_vc1_ttblk_to_tt[v->tt_index][get_vlc2(gb, ff_vc1_ttblk_vlc[v->tt_index].table, VC1_TTBLK_VLC_BITS, 1)];
+ }
+ if (ttblk == TT_4X4) {
+ subblkpat = ~(get_vlc2(gb, ff_vc1_subblkpat_vlc[v->tt_index].table, VC1_SUBBLKPAT_VLC_BITS, 1) + 1);
+ }
+ if ((ttblk != TT_8X8 && ttblk != TT_4X4)
+ && ((v->ttmbf || (ttmb != -1 && (ttmb & 8) && !first_block))
+ || (!v->res_rtm_flag && !first_block))) {
+ subblkpat = decode012(gb);
+ if (subblkpat)
+ subblkpat ^= 3; // swap decoded pattern bits
+ if (ttblk == TT_8X4_TOP || ttblk == TT_8X4_BOTTOM)
+ ttblk = TT_8X4;
+ if (ttblk == TT_4X8_RIGHT || ttblk == TT_4X8_LEFT)
+ ttblk = TT_4X8;
+ }
+ scale = 2 * mquant + ((v->pq == mquant) ? v->halfpq : 0);
+
+ // convert transforms like 8X4_TOP to generic TT and SUBBLKPAT
+ if (ttblk == TT_8X4_TOP || ttblk == TT_8X4_BOTTOM) {
+ subblkpat = 2 - (ttblk == TT_8X4_TOP);
+ ttblk = TT_8X4;
+ }
+ if (ttblk == TT_4X8_RIGHT || ttblk == TT_4X8_LEFT) {
+ subblkpat = 2 - (ttblk == TT_4X8_LEFT);
+ ttblk = TT_4X8;
+ }
+ switch (ttblk) {
+ case TT_8X8:
+ pat = 0xF;
+ i = 0;
+ last = 0;
+ while (!last) {
+ vc1_decode_ac_coeff(v, &last, &skip, &value, v->codingset2);
+ i += skip;
+ if (i > 63)
+ break;
+ if (!v->fcm)
+ idx = v->zz_8x8[0][i++];
+ else
+ idx = v->zzi_8x8[i++];
+ block[idx] = value * scale;
+ if (!v->pquantizer)
+ block[idx] += (block[idx] < 0) ? -mquant : mquant;
+ }
+ if (!skip_block) {
+ if (i == 1)
+ v->vc1dsp.vc1_inv_trans_8x8_dc(dst, linesize, block);
+ else {
+ v->vc1dsp.vc1_inv_trans_8x8(block);
+ s->idsp.add_pixels_clamped(block, dst, linesize);
+ }
+ }
+ break;
+ case TT_4X4:
+ pat = ~subblkpat & 0xF;
+ for (j = 0; j < 4; j++) {
+ last = subblkpat & (1 << (3 - j));
+ i = 0;
+ off = (j & 1) * 4 + (j & 2) * 16;
+ while (!last) {
+ vc1_decode_ac_coeff(v, &last, &skip, &value, v->codingset2);
+ i += skip;
+ if (i > 15)
+ break;
+ if (!v->fcm)
+ idx = ff_vc1_simple_progressive_4x4_zz[i++];
+ else
+ idx = ff_vc1_adv_interlaced_4x4_zz[i++];
+ block[idx + off] = value * scale;
+ if (!v->pquantizer)
+ block[idx + off] += (block[idx + off] < 0) ? -mquant : mquant;
+ }
+ if (!(subblkpat & (1 << (3 - j))) && !skip_block) {
+ if (i == 1)
+ v->vc1dsp.vc1_inv_trans_4x4_dc(dst + (j & 1) * 4 + (j & 2) * 2 * linesize, linesize, block + off);
+ else
+ v->vc1dsp.vc1_inv_trans_4x4(dst + (j & 1) * 4 + (j & 2) * 2 * linesize, linesize, block + off);
+ }
+ }
+ break;
+ case TT_8X4:
+ pat = ~((subblkpat & 2) * 6 + (subblkpat & 1) * 3) & 0xF;
+ for (j = 0; j < 2; j++) {
+ last = subblkpat & (1 << (1 - j));
+ i = 0;
+ off = j * 32;
+ while (!last) {
+ vc1_decode_ac_coeff(v, &last, &skip, &value, v->codingset2);
+ i += skip;
+ if (i > 31)
+ break;
+ if (!v->fcm)
+ idx = v->zz_8x4[i++] + off;
+ else
+ idx = ff_vc1_adv_interlaced_8x4_zz[i++] + off;
+ block[idx] = value * scale;
+ if (!v->pquantizer)
+ block[idx] += (block[idx] < 0) ? -mquant : mquant;
+ }
+ if (!(subblkpat & (1 << (1 - j))) && !skip_block) {
+ if (i == 1)
+ v->vc1dsp.vc1_inv_trans_8x4_dc(dst + j * 4 * linesize, linesize, block + off);
+ else
+ v->vc1dsp.vc1_inv_trans_8x4(dst + j * 4 * linesize, linesize, block + off);
+ }
+ }
+ break;
+ case TT_4X8:
+ pat = ~(subblkpat * 5) & 0xF;
+ for (j = 0; j < 2; j++) {
+ last = subblkpat & (1 << (1 - j));
+ i = 0;
+ off = j * 4;
+ while (!last) {
+ vc1_decode_ac_coeff(v, &last, &skip, &value, v->codingset2);
+ i += skip;
+ if (i > 31)
+ break;
+ if (!v->fcm)
+ idx = v->zz_4x8[i++] + off;
+ else
+ idx = ff_vc1_adv_interlaced_4x8_zz[i++] + off;
+ block[idx] = value * scale;
+ if (!v->pquantizer)
+ block[idx] += (block[idx] < 0) ? -mquant : mquant;
+ }
+ if (!(subblkpat & (1 << (1 - j))) && !skip_block) {
+ if (i == 1)
+ v->vc1dsp.vc1_inv_trans_4x8_dc(dst + j * 4, linesize, block + off);
+ else
+ v->vc1dsp.vc1_inv_trans_4x8(dst + j*4, linesize, block + off);
+ }
+ }
+ break;
+ }
+ if (ttmb_out)
+ *ttmb_out |= ttblk << (n * 4);
+ return pat;
+}
+
+/** @} */ // Macroblock group
+
+static const int size_table [6] = { 0, 2, 3, 4, 5, 8 };
+static const int offset_table[6] = { 0, 1, 3, 7, 15, 31 };
+
+/** Decode one P-frame MB
+ */
+static int vc1_decode_p_mb(VC1Context *v)
+{
+ MpegEncContext *s = &v->s;
+ GetBitContext *gb = &s->gb;
+ int i, j;
+ int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
+ int cbp; /* cbp decoding stuff */
+ int mqdiff, mquant; /* MB quantization */
+ int ttmb = v->ttfrm; /* MB Transform type */
+
+ int mb_has_coeffs = 1; /* last_flag */
+ int dmv_x, dmv_y; /* Differential MV components */
+ int index, index1; /* LUT indexes */
+ int val, sign; /* temp values */
+ int first_block = 1;
+ int dst_idx, off;
+ int skipped, fourmv;
+ int block_cbp = 0, pat, block_tt = 0, block_intra = 0;
+
+ mquant = v->pq; /* lossy initialization */
+
+ if (v->mv_type_is_raw)
+ fourmv = get_bits1(gb);
+ else
+ fourmv = v->mv_type_mb_plane[mb_pos];
+ if (v->skip_is_raw)
+ skipped = get_bits1(gb);
+ else
+ skipped = v->s.mbskip_table[mb_pos];
+
+ if (!fourmv) { /* 1MV mode */
+ if (!skipped) {
+ GET_MVDATA(dmv_x, dmv_y);
+
+ if (s->mb_intra) {
+ s->current_picture.motion_val[1][s->block_index[0]][0] = 0;
+ s->current_picture.motion_val[1][s->block_index[0]][1] = 0;
+ }
+ s->current_picture.mb_type[mb_pos] = s->mb_intra ? MB_TYPE_INTRA : MB_TYPE_16x16;
+ ff_vc1_pred_mv(v, 0, dmv_x, dmv_y, 1, v->range_x, v->range_y, v->mb_type[0], 0, 0);
+
+ /* FIXME Set DC val for inter block ? */
+ if (s->mb_intra && !mb_has_coeffs) {
+ GET_MQUANT();
+ s->ac_pred = get_bits1(gb);
+ cbp = 0;
+ } else if (mb_has_coeffs) {
+ if (s->mb_intra)
+ s->ac_pred = get_bits1(gb);
+ cbp = get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2);
+ GET_MQUANT();
+ } else {
+ mquant = v->pq;
+ cbp = 0;
+ }
+ s->current_picture.qscale_table[mb_pos] = mquant;
+
+ if (!v->ttmbf && !s->mb_intra && mb_has_coeffs)
+ ttmb = get_vlc2(gb, ff_vc1_ttmb_vlc[v->tt_index].table,
+ VC1_TTMB_VLC_BITS, 2);
+ if (!s->mb_intra) ff_vc1_mc_1mv(v, 0);
+ dst_idx = 0;
+ for (i = 0; i < 6; i++) {
+ s->dc_val[0][s->block_index[i]] = 0;
+ dst_idx += i >> 2;
+ val = ((cbp >> (5 - i)) & 1);
+ off = (i & 4) ? 0 : ((i & 1) * 8 + (i & 2) * 4 * s->linesize);
+ v->mb_type[0][s->block_index[i]] = s->mb_intra;
+ if (s->mb_intra) {
+ /* check if prediction blocks A and C are available */
+ v->a_avail = v->c_avail = 0;
+ if (i == 2 || i == 3 || !s->first_slice_line)
+ v->a_avail = v->mb_type[0][s->block_index[i] - s->block_wrap[i]];
+ if (i == 1 || i == 3 || s->mb_x)
+ v->c_avail = v->mb_type[0][s->block_index[i] - 1];
+
+ vc1_decode_intra_block(v, s->block[i], i, val, mquant,
+ (i & 4) ? v->codingset2 : v->codingset);
+ if ((i>3) && (s->flags & CODEC_FLAG_GRAY))
+ continue;
+ v->vc1dsp.vc1_inv_trans_8x8(s->block[i]);
+ if (v->rangeredfrm)
+ for (j = 0; j < 64; j++)
+ s->block[i][j] <<= 1;
+ s->idsp.put_signed_pixels_clamped(s->block[i],
+ s->dest[dst_idx] + off,
+ i & 4 ? s->uvlinesize
+ : s->linesize);
+ if (v->pq >= 9 && v->overlap) {
+ if (v->c_avail)
+ v->vc1dsp.vc1_h_overlap(s->dest[dst_idx] + off, i & 4 ? s->uvlinesize : s->linesize);
+ if (v->a_avail)
+ v->vc1dsp.vc1_v_overlap(s->dest[dst_idx] + off, i & 4 ? s->uvlinesize : s->linesize);
+ }
+ block_cbp |= 0xF << (i << 2);
+ block_intra |= 1 << i;
+ } else if (val) {
+ pat = vc1_decode_p_block(v, s->block[i], i, mquant, ttmb, first_block,
+ s->dest[dst_idx] + off, (i & 4) ? s->uvlinesize : s->linesize,
+ (i & 4) && (s->flags & CODEC_FLAG_GRAY), &block_tt);
+ block_cbp |= pat << (i << 2);
+ if (!v->ttmbf && ttmb < 8)
+ ttmb = -1;
+ first_block = 0;
+ }
+ }
+ } else { // skipped
+ s->mb_intra = 0;
+ for (i = 0; i < 6; i++) {
+ v->mb_type[0][s->block_index[i]] = 0;
+ s->dc_val[0][s->block_index[i]] = 0;
+ }
+ s->current_picture.mb_type[mb_pos] = MB_TYPE_SKIP;
+ s->current_picture.qscale_table[mb_pos] = 0;
+ ff_vc1_pred_mv(v, 0, 0, 0, 1, v->range_x, v->range_y, v->mb_type[0], 0, 0);
+ ff_vc1_mc_1mv(v, 0);
+ }
+ } else { // 4MV mode
+ if (!skipped /* unskipped MB */) {
+ int intra_count = 0, coded_inter = 0;
+ int is_intra[6], is_coded[6];
+ /* Get CBPCY */
+ cbp = get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2);
+ for (i = 0; i < 6; i++) {
+ val = ((cbp >> (5 - i)) & 1);
+ s->dc_val[0][s->block_index[i]] = 0;
+ s->mb_intra = 0;
+ if (i < 4) {
+ dmv_x = dmv_y = 0;
+ s->mb_intra = 0;
+ mb_has_coeffs = 0;
+ if (val) {
+ GET_MVDATA(dmv_x, dmv_y);
+ }
+ ff_vc1_pred_mv(v, i, dmv_x, dmv_y, 0, v->range_x, v->range_y, v->mb_type[0], 0, 0);
+ if (!s->mb_intra)
+ ff_vc1_mc_4mv_luma(v, i, 0, 0);
+ intra_count += s->mb_intra;
+ is_intra[i] = s->mb_intra;
+ is_coded[i] = mb_has_coeffs;
+ }
+ if (i & 4) {
+ is_intra[i] = (intra_count >= 3);
+ is_coded[i] = val;
+ }
+ if (i == 4)
+ ff_vc1_mc_4mv_chroma(v, 0);
+ v->mb_type[0][s->block_index[i]] = is_intra[i];
+ if (!coded_inter)
+ coded_inter = !is_intra[i] & is_coded[i];
+ }
+ // if there are no coded blocks then don't do anything more
+ dst_idx = 0;
+ if (!intra_count && !coded_inter)
+ goto end;
+ GET_MQUANT();
+ s->current_picture.qscale_table[mb_pos] = mquant;
+ /* test if block is intra and has pred */
+ {
+ int intrapred = 0;
+ for (i = 0; i < 6; i++)
+ if (is_intra[i]) {
+ if (((!s->first_slice_line || (i == 2 || i == 3)) && v->mb_type[0][s->block_index[i] - s->block_wrap[i]])
+ || ((s->mb_x || (i == 1 || i == 3)) && v->mb_type[0][s->block_index[i] - 1])) {
+ intrapred = 1;
+ break;
+ }
+ }
+ if (intrapred)
+ s->ac_pred = get_bits1(gb);
+ else
+ s->ac_pred = 0;
+ }
+ if (!v->ttmbf && coded_inter)
+ ttmb = get_vlc2(gb, ff_vc1_ttmb_vlc[v->tt_index].table, VC1_TTMB_VLC_BITS, 2);
+ for (i = 0; i < 6; i++) {
+ dst_idx += i >> 2;
+ off = (i & 4) ? 0 : ((i & 1) * 8 + (i & 2) * 4 * s->linesize);
+ s->mb_intra = is_intra[i];
+ if (is_intra[i]) {
+ /* check if prediction blocks A and C are available */
+ v->a_avail = v->c_avail = 0;
+ if (i == 2 || i == 3 || !s->first_slice_line)
+ v->a_avail = v->mb_type[0][s->block_index[i] - s->block_wrap[i]];
+ if (i == 1 || i == 3 || s->mb_x)
+ v->c_avail = v->mb_type[0][s->block_index[i] - 1];
+
+ vc1_decode_intra_block(v, s->block[i], i, is_coded[i], mquant,
+ (i & 4) ? v->codingset2 : v->codingset);
+ if ((i>3) && (s->flags & CODEC_FLAG_GRAY))
+ continue;
+ v->vc1dsp.vc1_inv_trans_8x8(s->block[i]);
+ if (v->rangeredfrm)
+ for (j = 0; j < 64; j++)
+ s->block[i][j] <<= 1;
+ s->idsp.put_signed_pixels_clamped(s->block[i],
+ s->dest[dst_idx] + off,
+ (i & 4) ? s->uvlinesize
+ : s->linesize);
+ if (v->pq >= 9 && v->overlap) {
+ if (v->c_avail)
+ v->vc1dsp.vc1_h_overlap(s->dest[dst_idx] + off, i & 4 ? s->uvlinesize : s->linesize);
+ if (v->a_avail)
+ v->vc1dsp.vc1_v_overlap(s->dest[dst_idx] + off, i & 4 ? s->uvlinesize : s->linesize);
+ }
+ block_cbp |= 0xF << (i << 2);
+ block_intra |= 1 << i;
+ } else if (is_coded[i]) {
+ pat = vc1_decode_p_block(v, s->block[i], i, mquant, ttmb,
+ first_block, s->dest[dst_idx] + off,
+ (i & 4) ? s->uvlinesize : s->linesize,
+ (i & 4) && (s->flags & CODEC_FLAG_GRAY),
+ &block_tt);
+ block_cbp |= pat << (i << 2);
+ if (!v->ttmbf && ttmb < 8)
+ ttmb = -1;
+ first_block = 0;
+ }
+ }
+ } else { // skipped MB
+ s->mb_intra = 0;
+ s->current_picture.qscale_table[mb_pos] = 0;
+ for (i = 0; i < 6; i++) {
+ v->mb_type[0][s->block_index[i]] = 0;
+ s->dc_val[0][s->block_index[i]] = 0;
+ }
+ for (i = 0; i < 4; i++) {
+ ff_vc1_pred_mv(v, i, 0, 0, 0, v->range_x, v->range_y, v->mb_type[0], 0, 0);
+ ff_vc1_mc_4mv_luma(v, i, 0, 0);
+ }
+ ff_vc1_mc_4mv_chroma(v, 0);
+ s->current_picture.qscale_table[mb_pos] = 0;
+ }
+ }
+end:
+ v->cbp[s->mb_x] = block_cbp;
+ v->ttblk[s->mb_x] = block_tt;
+ v->is_intra[s->mb_x] = block_intra;
+
+ return 0;
+}
+
+/* Decode one macroblock in an interlaced frame p picture */
+
+static int vc1_decode_p_mb_intfr(VC1Context *v)
+{
+ MpegEncContext *s = &v->s;
+ GetBitContext *gb = &s->gb;
+ int i;
+ int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
+ int cbp = 0; /* cbp decoding stuff */
+ int mqdiff, mquant; /* MB quantization */
+ int ttmb = v->ttfrm; /* MB Transform type */
+
+ int mb_has_coeffs = 1; /* last_flag */
+ int dmv_x, dmv_y; /* Differential MV components */
+ int val; /* temp value */
+ int first_block = 1;
+ int dst_idx, off;
+ int skipped, fourmv = 0, twomv = 0;
+ int block_cbp = 0, pat, block_tt = 0;
+ int idx_mbmode = 0, mvbp;
+ int stride_y, fieldtx;
+
+ mquant = v->pq; /* Lossy initialization */
+
+ if (v->skip_is_raw)
+ skipped = get_bits1(gb);
+ else
+ skipped = v->s.mbskip_table[mb_pos];
+ if (!skipped) {
+ if (v->fourmvswitch)
+ idx_mbmode = get_vlc2(gb, v->mbmode_vlc->table, VC1_INTFR_4MV_MBMODE_VLC_BITS, 2); // try getting this done
+ else
+ idx_mbmode = get_vlc2(gb, v->mbmode_vlc->table, VC1_INTFR_NON4MV_MBMODE_VLC_BITS, 2); // in a single line
+ switch (ff_vc1_mbmode_intfrp[v->fourmvswitch][idx_mbmode][0]) {
+ /* store the motion vector type in a flag (useful later) */
+ case MV_PMODE_INTFR_4MV:
+ fourmv = 1;
+ v->blk_mv_type[s->block_index[0]] = 0;
+ v->blk_mv_type[s->block_index[1]] = 0;
+ v->blk_mv_type[s->block_index[2]] = 0;
+ v->blk_mv_type[s->block_index[3]] = 0;
+ break;
+ case MV_PMODE_INTFR_4MV_FIELD:
+ fourmv = 1;
+ v->blk_mv_type[s->block_index[0]] = 1;
+ v->blk_mv_type[s->block_index[1]] = 1;
+ v->blk_mv_type[s->block_index[2]] = 1;
+ v->blk_mv_type[s->block_index[3]] = 1;
+ break;
+ case MV_PMODE_INTFR_2MV_FIELD:
+ twomv = 1;
+ v->blk_mv_type[s->block_index[0]] = 1;
+ v->blk_mv_type[s->block_index[1]] = 1;
+ v->blk_mv_type[s->block_index[2]] = 1;
+ v->blk_mv_type[s->block_index[3]] = 1;
+ break;
+ case MV_PMODE_INTFR_1MV:
+ v->blk_mv_type[s->block_index[0]] = 0;
+ v->blk_mv_type[s->block_index[1]] = 0;
+ v->blk_mv_type[s->block_index[2]] = 0;
+ v->blk_mv_type[s->block_index[3]] = 0;
+ break;
+ }
+ if (ff_vc1_mbmode_intfrp[v->fourmvswitch][idx_mbmode][0] == MV_PMODE_INTFR_INTRA) { // intra MB
+ for (i = 0; i < 4; i++) {
+ s->current_picture.motion_val[1][s->block_index[i]][0] = 0;
+ s->current_picture.motion_val[1][s->block_index[i]][1] = 0;
+ }
+ v->is_intra[s->mb_x] = 0x3f; // Set the bitfield to all 1.
+ s->mb_intra = 1;
+ s->current_picture.mb_type[mb_pos] = MB_TYPE_INTRA;
+ fieldtx = v->fieldtx_plane[mb_pos] = get_bits1(gb);
+ mb_has_coeffs = get_bits1(gb);
+ if (mb_has_coeffs)
+ cbp = 1 + get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2);
+ v->s.ac_pred = v->acpred_plane[mb_pos] = get_bits1(gb);
+ GET_MQUANT();
+ s->current_picture.qscale_table[mb_pos] = mquant;
+ /* Set DC scale - y and c use the same (not sure if necessary here) */
+ s->y_dc_scale = s->y_dc_scale_table[mquant];
+ s->c_dc_scale = s->c_dc_scale_table[mquant];
+ dst_idx = 0;
+ for (i = 0; i < 6; i++) {
+ v->a_avail = v->c_avail = 0;
+ v->mb_type[0][s->block_index[i]] = 1;
+ s->dc_val[0][s->block_index[i]] = 0;
+ dst_idx += i >> 2;
+ val = ((cbp >> (5 - i)) & 1);
+ if (i == 2 || i == 3 || !s->first_slice_line)
+ v->a_avail = v->mb_type[0][s->block_index[i] - s->block_wrap[i]];
+ if (i == 1 || i == 3 || s->mb_x)
+ v->c_avail = v->mb_type[0][s->block_index[i] - 1];
+
+ vc1_decode_intra_block(v, s->block[i], i, val, mquant,
+ (i & 4) ? v->codingset2 : v->codingset);
+ if ((i>3) && (s->flags & CODEC_FLAG_GRAY)) continue;
+ v->vc1dsp.vc1_inv_trans_8x8(s->block[i]);
+ if (i < 4) {
+ stride_y = s->linesize << fieldtx;
+ off = (fieldtx) ? ((i & 1) * 8) + ((i & 2) >> 1) * s->linesize : (i & 1) * 8 + 4 * (i & 2) * s->linesize;
+ } else {
+ stride_y = s->uvlinesize;
+ off = 0;
+ }
+ s->idsp.put_signed_pixels_clamped(s->block[i],
+ s->dest[dst_idx] + off,
+ stride_y);
+ //TODO: loop filter
+ }
+
+ } else { // inter MB
+ mb_has_coeffs = ff_vc1_mbmode_intfrp[v->fourmvswitch][idx_mbmode][3];
+ if (mb_has_coeffs)
+ cbp = 1 + get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2);
+ if (ff_vc1_mbmode_intfrp[v->fourmvswitch][idx_mbmode][0] == MV_PMODE_INTFR_2MV_FIELD) {
+ v->twomvbp = get_vlc2(gb, v->twomvbp_vlc->table, VC1_2MV_BLOCK_PATTERN_VLC_BITS, 1);
+ } else {
+ if ((ff_vc1_mbmode_intfrp[v->fourmvswitch][idx_mbmode][0] == MV_PMODE_INTFR_4MV)
+ || (ff_vc1_mbmode_intfrp[v->fourmvswitch][idx_mbmode][0] == MV_PMODE_INTFR_4MV_FIELD)) {
+ v->fourmvbp = get_vlc2(gb, v->fourmvbp_vlc->table, VC1_4MV_BLOCK_PATTERN_VLC_BITS, 1);
+ }
+ }
+ s->mb_intra = v->is_intra[s->mb_x] = 0;
+ for (i = 0; i < 6; i++)
+ v->mb_type[0][s->block_index[i]] = 0;
+ fieldtx = v->fieldtx_plane[mb_pos] = ff_vc1_mbmode_intfrp[v->fourmvswitch][idx_mbmode][1];
+ /* for all motion vector read MVDATA and motion compensate each block */
+ dst_idx = 0;
+ if (fourmv) {
+ mvbp = v->fourmvbp;
+ for (i = 0; i < 6; i++) {
+ if (i < 4) {
+ dmv_x = dmv_y = 0;
+ val = ((mvbp >> (3 - i)) & 1);
+ if (val) {
+ get_mvdata_interlaced(v, &dmv_x, &dmv_y, 0);
+ }
+ ff_vc1_pred_mv_intfr(v, i, dmv_x, dmv_y, 0, v->range_x, v->range_y, v->mb_type[0], 0);
+ ff_vc1_mc_4mv_luma(v, i, 0, 0);
+ } else if (i == 4) {
+ ff_vc1_mc_4mv_chroma4(v, 0, 0, 0);
+ }
+ }
+ } else if (twomv) {
+ mvbp = v->twomvbp;
+ dmv_x = dmv_y = 0;
+ if (mvbp & 2) {
+ get_mvdata_interlaced(v, &dmv_x, &dmv_y, 0);
+ }
+ ff_vc1_pred_mv_intfr(v, 0, dmv_x, dmv_y, 2, v->range_x, v->range_y, v->mb_type[0], 0);
+ ff_vc1_mc_4mv_luma(v, 0, 0, 0);
+ ff_vc1_mc_4mv_luma(v, 1, 0, 0);
+ dmv_x = dmv_y = 0;
+ if (mvbp & 1) {
+ get_mvdata_interlaced(v, &dmv_x, &dmv_y, 0);
+ }
+ ff_vc1_pred_mv_intfr(v, 2, dmv_x, dmv_y, 2, v->range_x, v->range_y, v->mb_type[0], 0);
+ ff_vc1_mc_4mv_luma(v, 2, 0, 0);
+ ff_vc1_mc_4mv_luma(v, 3, 0, 0);
+ ff_vc1_mc_4mv_chroma4(v, 0, 0, 0);
+ } else {
+ mvbp = ff_vc1_mbmode_intfrp[v->fourmvswitch][idx_mbmode][2];
+ dmv_x = dmv_y = 0;
+ if (mvbp) {
+ get_mvdata_interlaced(v, &dmv_x, &dmv_y, 0);
+ }
+ ff_vc1_pred_mv_intfr(v, 0, dmv_x, dmv_y, 1, v->range_x, v->range_y, v->mb_type[0], 0);
+ ff_vc1_mc_1mv(v, 0);
+ }
+ if (cbp)
+ GET_MQUANT(); // p. 227
+ s->current_picture.qscale_table[mb_pos] = mquant;
+ if (!v->ttmbf && cbp)
+ ttmb = get_vlc2(gb, ff_vc1_ttmb_vlc[v->tt_index].table, VC1_TTMB_VLC_BITS, 2);
+ for (i = 0; i < 6; i++) {
+ s->dc_val[0][s->block_index[i]] = 0;
+ dst_idx += i >> 2;
+ val = ((cbp >> (5 - i)) & 1);
+ if (!fieldtx)
+ off = (i & 4) ? 0 : ((i & 1) * 8 + (i & 2) * 4 * s->linesize);
+ else
+ off = (i & 4) ? 0 : ((i & 1) * 8 + ((i > 1) * s->linesize));
+ if (val) {
+ pat = vc1_decode_p_block(v, s->block[i], i, mquant, ttmb,
+ first_block, s->dest[dst_idx] + off,
+ (i & 4) ? s->uvlinesize : (s->linesize << fieldtx),
+ (i & 4) && (s->flags & CODEC_FLAG_GRAY), &block_tt);
+ block_cbp |= pat << (i << 2);
+ if (!v->ttmbf && ttmb < 8)
+ ttmb = -1;
+ first_block = 0;
+ }
+ }
+ }
+ } else { // skipped
+ s->mb_intra = v->is_intra[s->mb_x] = 0;
+ for (i = 0; i < 6; i++) {
+ v->mb_type[0][s->block_index[i]] = 0;
+ s->dc_val[0][s->block_index[i]] = 0;
+ }
+ s->current_picture.mb_type[mb_pos] = MB_TYPE_SKIP;
+ s->current_picture.qscale_table[mb_pos] = 0;
+ v->blk_mv_type[s->block_index[0]] = 0;
+ v->blk_mv_type[s->block_index[1]] = 0;
+ v->blk_mv_type[s->block_index[2]] = 0;
+ v->blk_mv_type[s->block_index[3]] = 0;
+ ff_vc1_pred_mv_intfr(v, 0, 0, 0, 1, v->range_x, v->range_y, v->mb_type[0], 0);
+ ff_vc1_mc_1mv(v, 0);
+ }
+ if (s->mb_x == s->mb_width - 1)
+ memmove(v->is_intra_base, v->is_intra, sizeof(v->is_intra_base[0])*s->mb_stride);
+ return 0;
+}
+
+static int vc1_decode_p_mb_intfi(VC1Context *v)
+{
+ MpegEncContext *s = &v->s;
+ GetBitContext *gb = &s->gb;
+ int i;
+ int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
+ int cbp = 0; /* cbp decoding stuff */
+ int mqdiff, mquant; /* MB quantization */
+ int ttmb = v->ttfrm; /* MB Transform type */
+
+ int mb_has_coeffs = 1; /* last_flag */
+ int dmv_x, dmv_y; /* Differential MV components */
+ int val; /* temp values */
+ int first_block = 1;
+ int dst_idx, off;
+ int pred_flag = 0;
+ int block_cbp = 0, pat, block_tt = 0;
+ int idx_mbmode = 0;
+
+ mquant = v->pq; /* Lossy initialization */
+
+ idx_mbmode = get_vlc2(gb, v->mbmode_vlc->table, VC1_IF_MBMODE_VLC_BITS, 2);
+ if (idx_mbmode <= 1) { // intra MB
+ v->is_intra[s->mb_x] = 0x3f; // Set the bitfield to all 1.
+ s->mb_intra = 1;
+ s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][0] = 0;
+ s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][1] = 0;
+ s->current_picture.mb_type[mb_pos + v->mb_off] = MB_TYPE_INTRA;
+ GET_MQUANT();
+ s->current_picture.qscale_table[mb_pos] = mquant;
+ /* Set DC scale - y and c use the same (not sure if necessary here) */
+ s->y_dc_scale = s->y_dc_scale_table[mquant];
+ s->c_dc_scale = s->c_dc_scale_table[mquant];
+ v->s.ac_pred = v->acpred_plane[mb_pos] = get_bits1(gb);
+ mb_has_coeffs = idx_mbmode & 1;
+ if (mb_has_coeffs)
+ cbp = 1 + get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_ICBPCY_VLC_BITS, 2);
+ dst_idx = 0;
+ for (i = 0; i < 6; i++) {
+ v->a_avail = v->c_avail = 0;
+ v->mb_type[0][s->block_index[i]] = 1;
+ s->dc_val[0][s->block_index[i]] = 0;
+ dst_idx += i >> 2;
+ val = ((cbp >> (5 - i)) & 1);
+ if (i == 2 || i == 3 || !s->first_slice_line)
+ v->a_avail = v->mb_type[0][s->block_index[i] - s->block_wrap[i]];
+ if (i == 1 || i == 3 || s->mb_x)
+ v->c_avail = v->mb_type[0][s->block_index[i] - 1];
+
+ vc1_decode_intra_block(v, s->block[i], i, val, mquant,
+ (i & 4) ? v->codingset2 : v->codingset);
+ if ((i>3) && (s->flags & CODEC_FLAG_GRAY))
+ continue;
+ v->vc1dsp.vc1_inv_trans_8x8(s->block[i]);
+ off = (i & 4) ? 0 : ((i & 1) * 8 + (i & 2) * 4 * s->linesize);
+ s->idsp.put_signed_pixels_clamped(s->block[i],
+ s->dest[dst_idx] + off,
+ (i & 4) ? s->uvlinesize
+ : s->linesize);
+ // TODO: loop filter
+ }
+ } else {
+ s->mb_intra = v->is_intra[s->mb_x] = 0;
+ s->current_picture.mb_type[mb_pos + v->mb_off] = MB_TYPE_16x16;
+ for (i = 0; i < 6; i++) v->mb_type[0][s->block_index[i]] = 0;
+ if (idx_mbmode <= 5) { // 1-MV
+ dmv_x = dmv_y = pred_flag = 0;
+ if (idx_mbmode & 1) {
+ get_mvdata_interlaced(v, &dmv_x, &dmv_y, &pred_flag);
+ }
+ ff_vc1_pred_mv(v, 0, dmv_x, dmv_y, 1, v->range_x, v->range_y, v->mb_type[0], pred_flag, 0);
+ ff_vc1_mc_1mv(v, 0);
+ mb_has_coeffs = !(idx_mbmode & 2);
+ } else { // 4-MV
+ v->fourmvbp = get_vlc2(gb, v->fourmvbp_vlc->table, VC1_4MV_BLOCK_PATTERN_VLC_BITS, 1);
+ for (i = 0; i < 6; i++) {
+ if (i < 4) {
+ dmv_x = dmv_y = pred_flag = 0;
+ val = ((v->fourmvbp >> (3 - i)) & 1);
+ if (val) {
+ get_mvdata_interlaced(v, &dmv_x, &dmv_y, &pred_flag);
+ }
+ ff_vc1_pred_mv(v, i, dmv_x, dmv_y, 0, v->range_x, v->range_y, v->mb_type[0], pred_flag, 0);
+ ff_vc1_mc_4mv_luma(v, i, 0, 0);
+ } else if (i == 4)
+ ff_vc1_mc_4mv_chroma(v, 0);
+ }
+ mb_has_coeffs = idx_mbmode & 1;
+ }
+ if (mb_has_coeffs)
+ cbp = 1 + get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2);
+ if (cbp) {
+ GET_MQUANT();
+ }
+ s->current_picture.qscale_table[mb_pos] = mquant;
+ if (!v->ttmbf && cbp) {
+ ttmb = get_vlc2(gb, ff_vc1_ttmb_vlc[v->tt_index].table, VC1_TTMB_VLC_BITS, 2);
+ }
+ dst_idx = 0;
+ for (i = 0; i < 6; i++) {
+ s->dc_val[0][s->block_index[i]] = 0;
+ dst_idx += i >> 2;
+ val = ((cbp >> (5 - i)) & 1);
+ off = (i & 4) ? 0 : (i & 1) * 8 + (i & 2) * 4 * s->linesize;
+ if (val) {
+ pat = vc1_decode_p_block(v, s->block[i], i, mquant, ttmb,
+ first_block, s->dest[dst_idx] + off,
+ (i & 4) ? s->uvlinesize : s->linesize,
+ (i & 4) && (s->flags & CODEC_FLAG_GRAY),
+ &block_tt);
+ block_cbp |= pat << (i << 2);
+ if (!v->ttmbf && ttmb < 8) ttmb = -1;
+ first_block = 0;
+ }
+ }
+ }
+ if (s->mb_x == s->mb_width - 1)
+ memmove(v->is_intra_base, v->is_intra, sizeof(v->is_intra_base[0]) * s->mb_stride);
+ return 0;
+}
+
+/** Decode one B-frame MB (in Main profile)
+ */
+static void vc1_decode_b_mb(VC1Context *v)
+{
+ MpegEncContext *s = &v->s;
+ GetBitContext *gb = &s->gb;
+ int i, j;
+ int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
+ int cbp = 0; /* cbp decoding stuff */
+ int mqdiff, mquant; /* MB quantization */
+ int ttmb = v->ttfrm; /* MB Transform type */
+ int mb_has_coeffs = 0; /* last_flag */
+ int index, index1; /* LUT indexes */
+ int val, sign; /* temp values */
+ int first_block = 1;
+ int dst_idx, off;
+ int skipped, direct;
+ int dmv_x[2], dmv_y[2];
+ int bmvtype = BMV_TYPE_BACKWARD;
+
+ mquant = v->pq; /* lossy initialization */
+ s->mb_intra = 0;
+
+ if (v->dmb_is_raw)
+ direct = get_bits1(gb);
+ else
+ direct = v->direct_mb_plane[mb_pos];
+ if (v->skip_is_raw)
+ skipped = get_bits1(gb);
+ else
+ skipped = v->s.mbskip_table[mb_pos];
+
+ dmv_x[0] = dmv_x[1] = dmv_y[0] = dmv_y[1] = 0;
+ for (i = 0; i < 6; i++) {
+ v->mb_type[0][s->block_index[i]] = 0;
+ s->dc_val[0][s->block_index[i]] = 0;
+ }
+ s->current_picture.qscale_table[mb_pos] = 0;
+
+ if (!direct) {
+ if (!skipped) {
+ GET_MVDATA(dmv_x[0], dmv_y[0]);
+ dmv_x[1] = dmv_x[0];
+ dmv_y[1] = dmv_y[0];
+ }
+ if (skipped || !s->mb_intra) {
+ bmvtype = decode012(gb);
+ switch (bmvtype) {
+ case 0:
+ bmvtype = (v->bfraction >= (B_FRACTION_DEN/2)) ? BMV_TYPE_BACKWARD : BMV_TYPE_FORWARD;
+ break;
+ case 1:
+ bmvtype = (v->bfraction >= (B_FRACTION_DEN/2)) ? BMV_TYPE_FORWARD : BMV_TYPE_BACKWARD;
+ break;
+ case 2:
+ bmvtype = BMV_TYPE_INTERPOLATED;
+ dmv_x[0] = dmv_y[0] = 0;
+ }
+ }
+ }
+ for (i = 0; i < 6; i++)
+ v->mb_type[0][s->block_index[i]] = s->mb_intra;
+
+ if (skipped) {
+ if (direct)
+ bmvtype = BMV_TYPE_INTERPOLATED;
+ ff_vc1_pred_b_mv(v, dmv_x, dmv_y, direct, bmvtype);
+ vc1_b_mc(v, dmv_x, dmv_y, direct, bmvtype);
+ return;
+ }
+ if (direct) {
+ cbp = get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2);
+ GET_MQUANT();
+ s->mb_intra = 0;
+ s->current_picture.qscale_table[mb_pos] = mquant;
+ if (!v->ttmbf)
+ ttmb = get_vlc2(gb, ff_vc1_ttmb_vlc[v->tt_index].table, VC1_TTMB_VLC_BITS, 2);
+ dmv_x[0] = dmv_y[0] = dmv_x[1] = dmv_y[1] = 0;
+ ff_vc1_pred_b_mv(v, dmv_x, dmv_y, direct, bmvtype);
+ vc1_b_mc(v, dmv_x, dmv_y, direct, bmvtype);
+ } else {
+ if (!mb_has_coeffs && !s->mb_intra) {
+ /* no coded blocks - effectively skipped */
+ ff_vc1_pred_b_mv(v, dmv_x, dmv_y, direct, bmvtype);
+ vc1_b_mc(v, dmv_x, dmv_y, direct, bmvtype);
+ return;
+ }
+ if (s->mb_intra && !mb_has_coeffs) {
+ GET_MQUANT();
+ s->current_picture.qscale_table[mb_pos] = mquant;
+ s->ac_pred = get_bits1(gb);
+ cbp = 0;
+ ff_vc1_pred_b_mv(v, dmv_x, dmv_y, direct, bmvtype);
+ } else {
+ if (bmvtype == BMV_TYPE_INTERPOLATED) {
+ GET_MVDATA(dmv_x[0], dmv_y[0]);
+ if (!mb_has_coeffs) {
+ /* interpolated skipped block */
+ ff_vc1_pred_b_mv(v, dmv_x, dmv_y, direct, bmvtype);
+ vc1_b_mc(v, dmv_x, dmv_y, direct, bmvtype);
+ return;
+ }
+ }
+ ff_vc1_pred_b_mv(v, dmv_x, dmv_y, direct, bmvtype);
+ if (!s->mb_intra) {
+ vc1_b_mc(v, dmv_x, dmv_y, direct, bmvtype);
+ }
+ if (s->mb_intra)
+ s->ac_pred = get_bits1(gb);
+ cbp = get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2);
+ GET_MQUANT();
+ s->current_picture.qscale_table[mb_pos] = mquant;
+ if (!v->ttmbf && !s->mb_intra && mb_has_coeffs)
+ ttmb = get_vlc2(gb, ff_vc1_ttmb_vlc[v->tt_index].table, VC1_TTMB_VLC_BITS, 2);
+ }
+ }
+ dst_idx = 0;
+ for (i = 0; i < 6; i++) {
+ s->dc_val[0][s->block_index[i]] = 0;
+ dst_idx += i >> 2;
+ val = ((cbp >> (5 - i)) & 1);
+ off = (i & 4) ? 0 : ((i & 1) * 8 + (i & 2) * 4 * s->linesize);
+ v->mb_type[0][s->block_index[i]] = s->mb_intra;
+ if (s->mb_intra) {
+ /* check if prediction blocks A and C are available */
+ v->a_avail = v->c_avail = 0;
+ if (i == 2 || i == 3 || !s->first_slice_line)
+ v->a_avail = v->mb_type[0][s->block_index[i] - s->block_wrap[i]];
+ if (i == 1 || i == 3 || s->mb_x)
+ v->c_avail = v->mb_type[0][s->block_index[i] - 1];
+
+ vc1_decode_intra_block(v, s->block[i], i, val, mquant,
+ (i & 4) ? v->codingset2 : v->codingset);
+ if ((i>3) && (s->flags & CODEC_FLAG_GRAY))
+ continue;
+ v->vc1dsp.vc1_inv_trans_8x8(s->block[i]);
+ if (v->rangeredfrm)
+ for (j = 0; j < 64; j++)
+ s->block[i][j] <<= 1;
+ s->idsp.put_signed_pixels_clamped(s->block[i],
+ s->dest[dst_idx] + off,
+ i & 4 ? s->uvlinesize
+ : s->linesize);
+ } else if (val) {
+ vc1_decode_p_block(v, s->block[i], i, mquant, ttmb,
+ first_block, s->dest[dst_idx] + off,
+ (i & 4) ? s->uvlinesize : s->linesize,
+ (i & 4) && (s->flags & CODEC_FLAG_GRAY), NULL);
+ if (!v->ttmbf && ttmb < 8)
+ ttmb = -1;
+ first_block = 0;
+ }
+ }
+}
+
+/** Decode one B-frame MB (in interlaced field B picture)
+ */
+static void vc1_decode_b_mb_intfi(VC1Context *v)
+{
+ MpegEncContext *s = &v->s;
+ GetBitContext *gb = &s->gb;
+ int i, j;
+ int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
+ int cbp = 0; /* cbp decoding stuff */
+ int mqdiff, mquant; /* MB quantization */
+ int ttmb = v->ttfrm; /* MB Transform type */
+ int mb_has_coeffs = 0; /* last_flag */
+ int val; /* temp value */
+ int first_block = 1;
+ int dst_idx, off;
+ int fwd;
+ int dmv_x[2], dmv_y[2], pred_flag[2];
+ int bmvtype = BMV_TYPE_BACKWARD;
+ int idx_mbmode;
+
+ mquant = v->pq; /* Lossy initialization */
+ s->mb_intra = 0;
+
+ idx_mbmode = get_vlc2(gb, v->mbmode_vlc->table, VC1_IF_MBMODE_VLC_BITS, 2);
+ if (idx_mbmode <= 1) { // intra MB
+ v->is_intra[s->mb_x] = 0x3f; // Set the bitfield to all 1.
+ s->mb_intra = 1;
+ s->current_picture.motion_val[1][s->block_index[0]][0] = 0;
+ s->current_picture.motion_val[1][s->block_index[0]][1] = 0;
+ s->current_picture.mb_type[mb_pos + v->mb_off] = MB_TYPE_INTRA;
+ GET_MQUANT();
+ s->current_picture.qscale_table[mb_pos] = mquant;
+ /* Set DC scale - y and c use the same (not sure if necessary here) */
+ s->y_dc_scale = s->y_dc_scale_table[mquant];
+ s->c_dc_scale = s->c_dc_scale_table[mquant];
+ v->s.ac_pred = v->acpred_plane[mb_pos] = get_bits1(gb);
+ mb_has_coeffs = idx_mbmode & 1;
+ if (mb_has_coeffs)
+ cbp = 1 + get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_ICBPCY_VLC_BITS, 2);
+ dst_idx = 0;
+ for (i = 0; i < 6; i++) {
+ v->a_avail = v->c_avail = 0;
+ v->mb_type[0][s->block_index[i]] = 1;
+ s->dc_val[0][s->block_index[i]] = 0;
+ dst_idx += i >> 2;
+ val = ((cbp >> (5 - i)) & 1);
+ if (i == 2 || i == 3 || !s->first_slice_line)
+ v->a_avail = v->mb_type[0][s->block_index[i] - s->block_wrap[i]];
+ if (i == 1 || i == 3 || s->mb_x)
+ v->c_avail = v->mb_type[0][s->block_index[i] - 1];
+
+ vc1_decode_intra_block(v, s->block[i], i, val, mquant,
+ (i & 4) ? v->codingset2 : v->codingset);
+ if ((i>3) && (s->flags & CODEC_FLAG_GRAY))
+ continue;
+ v->vc1dsp.vc1_inv_trans_8x8(s->block[i]);
+ if (v->rangeredfrm)
+ for (j = 0; j < 64; j++)
+ s->block[i][j] <<= 1;
+ off = (i & 4) ? 0 : ((i & 1) * 8 + (i & 2) * 4 * s->linesize);
+ s->idsp.put_signed_pixels_clamped(s->block[i],
+ s->dest[dst_idx] + off,
+ (i & 4) ? s->uvlinesize
+ : s->linesize);
+ // TODO: yet to perform loop filter
+ }
+ } else {
+ s->mb_intra = v->is_intra[s->mb_x] = 0;
+ s->current_picture.mb_type[mb_pos + v->mb_off] = MB_TYPE_16x16;
+ for (i = 0; i < 6; i++) v->mb_type[0][s->block_index[i]] = 0;
+ if (v->fmb_is_raw)
+ fwd = v->forward_mb_plane[mb_pos] = get_bits1(gb);
+ else
+ fwd = v->forward_mb_plane[mb_pos];
+ if (idx_mbmode <= 5) { // 1-MV
+ int interpmvp = 0;
+ dmv_x[0] = dmv_x[1] = dmv_y[0] = dmv_y[1] = 0;
+ pred_flag[0] = pred_flag[1] = 0;
+ if (fwd)
+ bmvtype = BMV_TYPE_FORWARD;
+ else {
+ bmvtype = decode012(gb);
+ switch (bmvtype) {
+ case 0:
+ bmvtype = BMV_TYPE_BACKWARD;
+ break;
+ case 1:
+ bmvtype = BMV_TYPE_DIRECT;
+ break;
+ case 2:
+ bmvtype = BMV_TYPE_INTERPOLATED;
+ interpmvp = get_bits1(gb);
+ }
+ }
+ v->bmvtype = bmvtype;
+ if (bmvtype != BMV_TYPE_DIRECT && idx_mbmode & 1) {
+ get_mvdata_interlaced(v, &dmv_x[bmvtype == BMV_TYPE_BACKWARD], &dmv_y[bmvtype == BMV_TYPE_BACKWARD], &pred_flag[bmvtype == BMV_TYPE_BACKWARD]);
+ }
+ if (interpmvp) {
+ get_mvdata_interlaced(v, &dmv_x[1], &dmv_y[1], &pred_flag[1]);
+ }
+ if (bmvtype == BMV_TYPE_DIRECT) {
+ dmv_x[0] = dmv_y[0] = pred_flag[0] = 0;
+ dmv_x[1] = dmv_y[1] = pred_flag[0] = 0;
+ if (!s->next_picture_ptr->field_picture) {
+ av_log(s->avctx, AV_LOG_ERROR, "Mixed field/frame direct mode not supported\n");
+ return;
+ }
+ }
+ ff_vc1_pred_b_mv_intfi(v, 0, dmv_x, dmv_y, 1, pred_flag);
+ vc1_b_mc(v, dmv_x, dmv_y, (bmvtype == BMV_TYPE_DIRECT), bmvtype);
+ mb_has_coeffs = !(idx_mbmode & 2);
+ } else { // 4-MV
+ if (fwd)
+ bmvtype = BMV_TYPE_FORWARD;
+ v->bmvtype = bmvtype;
+ v->fourmvbp = get_vlc2(gb, v->fourmvbp_vlc->table, VC1_4MV_BLOCK_PATTERN_VLC_BITS, 1);
+ for (i = 0; i < 6; i++) {
+ if (i < 4) {
+ dmv_x[0] = dmv_y[0] = pred_flag[0] = 0;
+ dmv_x[1] = dmv_y[1] = pred_flag[1] = 0;
+ val = ((v->fourmvbp >> (3 - i)) & 1);
+ if (val) {
+ get_mvdata_interlaced(v, &dmv_x[bmvtype == BMV_TYPE_BACKWARD],
+ &dmv_y[bmvtype == BMV_TYPE_BACKWARD],
+ &pred_flag[bmvtype == BMV_TYPE_BACKWARD]);
+ }
+ ff_vc1_pred_b_mv_intfi(v, i, dmv_x, dmv_y, 0, pred_flag);
+ ff_vc1_mc_4mv_luma(v, i, bmvtype == BMV_TYPE_BACKWARD, 0);
+ } else if (i == 4)
+ ff_vc1_mc_4mv_chroma(v, bmvtype == BMV_TYPE_BACKWARD);
+ }
+ mb_has_coeffs = idx_mbmode & 1;
+ }
+ if (mb_has_coeffs)
+ cbp = 1 + get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2);
+ if (cbp) {
+ GET_MQUANT();
+ }
+ s->current_picture.qscale_table[mb_pos] = mquant;
+ if (!v->ttmbf && cbp) {
+ ttmb = get_vlc2(gb, ff_vc1_ttmb_vlc[v->tt_index].table, VC1_TTMB_VLC_BITS, 2);
+ }
+ dst_idx = 0;
+ for (i = 0; i < 6; i++) {
+ s->dc_val[0][s->block_index[i]] = 0;
+ dst_idx += i >> 2;
+ val = ((cbp >> (5 - i)) & 1);
+ off = (i & 4) ? 0 : (i & 1) * 8 + (i & 2) * 4 * s->linesize;
+ if (val) {
+ vc1_decode_p_block(v, s->block[i], i, mquant, ttmb,
+ first_block, s->dest[dst_idx] + off,
+ (i & 4) ? s->uvlinesize : s->linesize,
+ (i & 4) && (s->flags & CODEC_FLAG_GRAY), NULL);
+ if (!v->ttmbf && ttmb < 8)
+ ttmb = -1;
+ first_block = 0;
+ }
+ }
+ }
+}
+
+/** Decode one B-frame MB (in interlaced frame B picture)
+ */
+static int vc1_decode_b_mb_intfr(VC1Context *v)
+{
+ MpegEncContext *s = &v->s;
+ GetBitContext *gb = &s->gb;
+ int i, j;
+ int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
+ int cbp = 0; /* cbp decoding stuff */
+ int mqdiff, mquant; /* MB quantization */
+ int ttmb = v->ttfrm; /* MB Transform type */
+ int mvsw = 0; /* motion vector switch */
+ int mb_has_coeffs = 1; /* last_flag */
+ int dmv_x, dmv_y; /* Differential MV components */
+ int val; /* temp value */
+ int first_block = 1;
+ int dst_idx, off;
+ int skipped, direct, twomv = 0;
+ int block_cbp = 0, pat, block_tt = 0;
+ int idx_mbmode = 0, mvbp;
+ int stride_y, fieldtx;
+ int bmvtype = BMV_TYPE_BACKWARD;
+ int dir, dir2;
+
+ mquant = v->pq; /* Lossy initialization */
+ s->mb_intra = 0;
+ if (v->skip_is_raw)
+ skipped = get_bits1(gb);
+ else
+ skipped = v->s.mbskip_table[mb_pos];
+
+ if (!skipped) {
+ idx_mbmode = get_vlc2(gb, v->mbmode_vlc->table, VC1_INTFR_NON4MV_MBMODE_VLC_BITS, 2);
+ if (ff_vc1_mbmode_intfrp[0][idx_mbmode][0] == MV_PMODE_INTFR_2MV_FIELD) {
+ twomv = 1;
+ v->blk_mv_type[s->block_index[0]] = 1;
+ v->blk_mv_type[s->block_index[1]] = 1;
+ v->blk_mv_type[s->block_index[2]] = 1;
+ v->blk_mv_type[s->block_index[3]] = 1;
+ } else {
+ v->blk_mv_type[s->block_index[0]] = 0;
+ v->blk_mv_type[s->block_index[1]] = 0;
+ v->blk_mv_type[s->block_index[2]] = 0;
+ v->blk_mv_type[s->block_index[3]] = 0;
+ }
+ }
+
+ if (v->dmb_is_raw)
+ direct = get_bits1(gb);
+ else
+ direct = v->direct_mb_plane[mb_pos];
+
+ if (direct) {
+ if (s->next_picture_ptr->field_picture)
+ av_log(s->avctx, AV_LOG_WARNING, "Mixed frame/field direct mode not supported\n");
+ s->mv[0][0][0] = s->current_picture.motion_val[0][s->block_index[0]][0] = scale_mv(s->next_picture.motion_val[1][s->block_index[0]][0], v->bfraction, 0, s->quarter_sample);
+ s->mv[0][0][1] = s->current_picture.motion_val[0][s->block_index[0]][1] = scale_mv(s->next_picture.motion_val[1][s->block_index[0]][1], v->bfraction, 0, s->quarter_sample);
+ s->mv[1][0][0] = s->current_picture.motion_val[1][s->block_index[0]][0] = scale_mv(s->next_picture.motion_val[1][s->block_index[0]][0], v->bfraction, 1, s->quarter_sample);
+ s->mv[1][0][1] = s->current_picture.motion_val[1][s->block_index[0]][1] = scale_mv(s->next_picture.motion_val[1][s->block_index[0]][1], v->bfraction, 1, s->quarter_sample);
+
+ if (twomv) {
+ s->mv[0][2][0] = s->current_picture.motion_val[0][s->block_index[2]][0] = scale_mv(s->next_picture.motion_val[1][s->block_index[2]][0], v->bfraction, 0, s->quarter_sample);
+ s->mv[0][2][1] = s->current_picture.motion_val[0][s->block_index[2]][1] = scale_mv(s->next_picture.motion_val[1][s->block_index[2]][1], v->bfraction, 0, s->quarter_sample);
+ s->mv[1][2][0] = s->current_picture.motion_val[1][s->block_index[2]][0] = scale_mv(s->next_picture.motion_val[1][s->block_index[2]][0], v->bfraction, 1, s->quarter_sample);
+ s->mv[1][2][1] = s->current_picture.motion_val[1][s->block_index[2]][1] = scale_mv(s->next_picture.motion_val[1][s->block_index[2]][1], v->bfraction, 1, s->quarter_sample);
+
+ for (i = 1; i < 4; i += 2) {
+ s->mv[0][i][0] = s->current_picture.motion_val[0][s->block_index[i]][0] = s->mv[0][i-1][0];
+ s->mv[0][i][1] = s->current_picture.motion_val[0][s->block_index[i]][1] = s->mv[0][i-1][1];
+ s->mv[1][i][0] = s->current_picture.motion_val[1][s->block_index[i]][0] = s->mv[1][i-1][0];
+ s->mv[1][i][1] = s->current_picture.motion_val[1][s->block_index[i]][1] = s->mv[1][i-1][1];
+ }
+ } else {
+ for (i = 1; i < 4; i++) {
+ s->mv[0][i][0] = s->current_picture.motion_val[0][s->block_index[i]][0] = s->mv[0][0][0];
+ s->mv[0][i][1] = s->current_picture.motion_val[0][s->block_index[i]][1] = s->mv[0][0][1];
+ s->mv[1][i][0] = s->current_picture.motion_val[1][s->block_index[i]][0] = s->mv[1][0][0];
+ s->mv[1][i][1] = s->current_picture.motion_val[1][s->block_index[i]][1] = s->mv[1][0][1];
+ }
+ }
+ }
+
+ if (ff_vc1_mbmode_intfrp[0][idx_mbmode][0] == MV_PMODE_INTFR_INTRA) { // intra MB
+ for (i = 0; i < 4; i++) {
+ s->mv[0][i][0] = s->current_picture.motion_val[0][s->block_index[i]][0] = 0;
+ s->mv[0][i][1] = s->current_picture.motion_val[0][s->block_index[i]][1] = 0;
+ s->mv[1][i][0] = s->current_picture.motion_val[1][s->block_index[i]][0] = 0;
+ s->mv[1][i][1] = s->current_picture.motion_val[1][s->block_index[i]][1] = 0;
+ }
+ v->is_intra[s->mb_x] = 0x3f; // Set the bitfield to all 1.
+ s->mb_intra = 1;
+ s->current_picture.mb_type[mb_pos] = MB_TYPE_INTRA;
+ fieldtx = v->fieldtx_plane[mb_pos] = get_bits1(gb);
+ mb_has_coeffs = get_bits1(gb);
+ if (mb_has_coeffs)
+ cbp = 1 + get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2);
+ v->s.ac_pred = v->acpred_plane[mb_pos] = get_bits1(gb);
+ GET_MQUANT();
+ s->current_picture.qscale_table[mb_pos] = mquant;
+ /* Set DC scale - y and c use the same (not sure if necessary here) */
+ s->y_dc_scale = s->y_dc_scale_table[mquant];
+ s->c_dc_scale = s->c_dc_scale_table[mquant];
+ dst_idx = 0;
+ for (i = 0; i < 6; i++) {
+ v->a_avail = v->c_avail = 0;
+ v->mb_type[0][s->block_index[i]] = 1;
+ s->dc_val[0][s->block_index[i]] = 0;
+ dst_idx += i >> 2;
+ val = ((cbp >> (5 - i)) & 1);
+ if (i == 2 || i == 3 || !s->first_slice_line)
+ v->a_avail = v->mb_type[0][s->block_index[i] - s->block_wrap[i]];
+ if (i == 1 || i == 3 || s->mb_x)
+ v->c_avail = v->mb_type[0][s->block_index[i] - 1];
+
+ vc1_decode_intra_block(v, s->block[i], i, val, mquant,
+ (i & 4) ? v->codingset2 : v->codingset);
+ if (i > 3 && (s->flags & CODEC_FLAG_GRAY))
+ continue;
+ v->vc1dsp.vc1_inv_trans_8x8(s->block[i]);
+ if (i < 4) {
+ stride_y = s->linesize << fieldtx;
+ off = (fieldtx) ? ((i & 1) * 8) + ((i & 2) >> 1) * s->linesize : (i & 1) * 8 + 4 * (i & 2) * s->linesize;
+ } else {
+ stride_y = s->uvlinesize;
+ off = 0;
+ }
+ s->idsp.put_signed_pixels_clamped(s->block[i],
+ s->dest[dst_idx] + off,
+ stride_y);
+ }
+ } else {
+ s->mb_intra = v->is_intra[s->mb_x] = 0;
+ if (!direct) {
+ if (skipped || !s->mb_intra) {
+ bmvtype = decode012(gb);
+ switch (bmvtype) {
+ case 0:
+ bmvtype = (v->bfraction >= (B_FRACTION_DEN/2)) ? BMV_TYPE_BACKWARD : BMV_TYPE_FORWARD;
+ break;
+ case 1:
+ bmvtype = (v->bfraction >= (B_FRACTION_DEN/2)) ? BMV_TYPE_FORWARD : BMV_TYPE_BACKWARD;
+ break;
+ case 2:
+ bmvtype = BMV_TYPE_INTERPOLATED;
+ }
+ }
+
+ if (twomv && bmvtype != BMV_TYPE_INTERPOLATED)
+ mvsw = get_bits1(gb);
+ }
+
+ if (!skipped) { // inter MB
+ mb_has_coeffs = ff_vc1_mbmode_intfrp[0][idx_mbmode][3];
+ if (mb_has_coeffs)
+ cbp = 1 + get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2);
+ if (!direct) {
+ 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) {
+ v->twomvbp = get_vlc2(gb, v->twomvbp_vlc->table, VC1_2MV_BLOCK_PATTERN_VLC_BITS, 1);
+ }
+ }
+
+ for (i = 0; i < 6; i++)
+ v->mb_type[0][s->block_index[i]] = 0;
+ fieldtx = v->fieldtx_plane[mb_pos] = ff_vc1_mbmode_intfrp[0][idx_mbmode][1];
+ /* for all motion vector read MVDATA and motion compensate each block */
+ dst_idx = 0;
+ if (direct) {
+ if (twomv) {
+ for (i = 0; i < 4; i++) {
+ ff_vc1_mc_4mv_luma(v, i, 0, 0);
+ ff_vc1_mc_4mv_luma(v, i, 1, 1);
+ }
+ ff_vc1_mc_4mv_chroma4(v, 0, 0, 0);
+ ff_vc1_mc_4mv_chroma4(v, 1, 1, 1);
+ } else {
+ ff_vc1_mc_1mv(v, 0);
+ ff_vc1_interp_mc(v);
+ }
+ } else if (twomv && bmvtype == BMV_TYPE_INTERPOLATED) {
+ mvbp = v->fourmvbp;
+ for (i = 0; i < 4; i++) {
+ dir = i==1 || i==3;
+ dmv_x = dmv_y = 0;
+ val = ((mvbp >> (3 - i)) & 1);
+ if (val)
+ get_mvdata_interlaced(v, &dmv_x, &dmv_y, 0);
+ j = i > 1 ? 2 : 0;
+ ff_vc1_pred_mv_intfr(v, j, dmv_x, dmv_y, 2, v->range_x, v->range_y, v->mb_type[0], dir);
+ ff_vc1_mc_4mv_luma(v, j, dir, dir);
+ ff_vc1_mc_4mv_luma(v, j+1, dir, dir);
+ }
+
+ ff_vc1_mc_4mv_chroma4(v, 0, 0, 0);
+ ff_vc1_mc_4mv_chroma4(v, 1, 1, 1);
+ } else if (bmvtype == BMV_TYPE_INTERPOLATED) {
+ mvbp = v->twomvbp;
+ dmv_x = dmv_y = 0;
+ if (mvbp & 2)
+ get_mvdata_interlaced(v, &dmv_x, &dmv_y, 0);
+
+ ff_vc1_pred_mv_intfr(v, 0, dmv_x, dmv_y, 1, v->range_x, v->range_y, v->mb_type[0], 0);
+ ff_vc1_mc_1mv(v, 0);
+
+ dmv_x = dmv_y = 0;
+ if (mvbp & 1)
+ get_mvdata_interlaced(v, &dmv_x, &dmv_y, 0);
+
+ ff_vc1_pred_mv_intfr(v, 0, dmv_x, dmv_y, 1, v->range_x, v->range_y, v->mb_type[0], 1);
+ ff_vc1_interp_mc(v);
+ } else if (twomv) {
+ dir = bmvtype == BMV_TYPE_BACKWARD;
+ dir2 = dir;
+ if (mvsw)
+ dir2 = !dir;
+ mvbp = v->twomvbp;
+ dmv_x = dmv_y = 0;
+ if (mvbp & 2)
+ get_mvdata_interlaced(v, &dmv_x, &dmv_y, 0);
+ ff_vc1_pred_mv_intfr(v, 0, dmv_x, dmv_y, 2, v->range_x, v->range_y, v->mb_type[0], dir);
+
+ dmv_x = dmv_y = 0;
+ if (mvbp & 1)
+ get_mvdata_interlaced(v, &dmv_x, &dmv_y, 0);
+ ff_vc1_pred_mv_intfr(v, 2, dmv_x, dmv_y, 2, v->range_x, v->range_y, v->mb_type[0], dir2);
+
+ if (mvsw) {
+ for (i = 0; i < 2; i++) {
+ s->mv[dir][i+2][0] = s->mv[dir][i][0] = s->current_picture.motion_val[dir][s->block_index[i+2]][0] = s->current_picture.motion_val[dir][s->block_index[i]][0];
+ s->mv[dir][i+2][1] = s->mv[dir][i][1] = s->current_picture.motion_val[dir][s->block_index[i+2]][1] = s->current_picture.motion_val[dir][s->block_index[i]][1];
+ s->mv[dir2][i+2][0] = s->mv[dir2][i][0] = s->current_picture.motion_val[dir2][s->block_index[i]][0] = s->current_picture.motion_val[dir2][s->block_index[i+2]][0];
+ s->mv[dir2][i+2][1] = s->mv[dir2][i][1] = s->current_picture.motion_val[dir2][s->block_index[i]][1] = s->current_picture.motion_val[dir2][s->block_index[i+2]][1];
+ }
+ } else {
+ ff_vc1_pred_mv_intfr(v, 0, 0, 0, 2, v->range_x, v->range_y, v->mb_type[0], !dir);
+ ff_vc1_pred_mv_intfr(v, 2, 0, 0, 2, v->range_x, v->range_y, v->mb_type[0], !dir);
+ }
+
+ ff_vc1_mc_4mv_luma(v, 0, dir, 0);
+ ff_vc1_mc_4mv_luma(v, 1, dir, 0);
+ ff_vc1_mc_4mv_luma(v, 2, dir2, 0);
+ ff_vc1_mc_4mv_luma(v, 3, dir2, 0);
+ ff_vc1_mc_4mv_chroma4(v, dir, dir2, 0);
+ } else {
+ dir = bmvtype == BMV_TYPE_BACKWARD;
+
+ mvbp = ff_vc1_mbmode_intfrp[0][idx_mbmode][2];
+ dmv_x = dmv_y = 0;
+ if (mvbp)
+ get_mvdata_interlaced(v, &dmv_x, &dmv_y, 0);
+
+ ff_vc1_pred_mv_intfr(v, 0, dmv_x, dmv_y, 1, v->range_x, v->range_y, v->mb_type[0], dir);
+ v->blk_mv_type[s->block_index[0]] = 1;
+ v->blk_mv_type[s->block_index[1]] = 1;
+ v->blk_mv_type[s->block_index[2]] = 1;
+ v->blk_mv_type[s->block_index[3]] = 1;
+ ff_vc1_pred_mv_intfr(v, 0, 0, 0, 2, v->range_x, v->range_y, 0, !dir);
+ for (i = 0; i < 2; i++) {
+ s->mv[!dir][i+2][0] = s->mv[!dir][i][0] = s->current_picture.motion_val[!dir][s->block_index[i+2]][0] = s->current_picture.motion_val[!dir][s->block_index[i]][0];
+ s->mv[!dir][i+2][1] = s->mv[!dir][i][1] = s->current_picture.motion_val[!dir][s->block_index[i+2]][1] = s->current_picture.motion_val[!dir][s->block_index[i]][1];
+ }
+ ff_vc1_mc_1mv(v, dir);
+ }
+
+ if (cbp)
+ GET_MQUANT(); // p. 227
+ s->current_picture.qscale_table[mb_pos] = mquant;
+ if (!v->ttmbf && cbp)
+ ttmb = get_vlc2(gb, ff_vc1_ttmb_vlc[v->tt_index].table, VC1_TTMB_VLC_BITS, 2);
+ for (i = 0; i < 6; i++) {
+ s->dc_val[0][s->block_index[i]] = 0;
+ dst_idx += i >> 2;
+ val = ((cbp >> (5 - i)) & 1);
+ if (!fieldtx)
+ off = (i & 4) ? 0 : ((i & 1) * 8 + (i & 2) * 4 * s->linesize);
+ else
+ off = (i & 4) ? 0 : ((i & 1) * 8 + ((i > 1) * s->linesize));
+ if (val) {
+ pat = vc1_decode_p_block(v, s->block[i], i, mquant, ttmb,
+ first_block, s->dest[dst_idx] + off,
+ (i & 4) ? s->uvlinesize : (s->linesize << fieldtx),
+ (i & 4) && (s->flags & CODEC_FLAG_GRAY), &block_tt);
+ block_cbp |= pat << (i << 2);
+ if (!v->ttmbf && ttmb < 8)
+ ttmb = -1;
+ first_block = 0;
+ }
+ }
+
+ } else { // skipped
+ dir = 0;
+ for (i = 0; i < 6; i++) {
+ v->mb_type[0][s->block_index[i]] = 0;
+ s->dc_val[0][s->block_index[i]] = 0;
+ }
+ s->current_picture.mb_type[mb_pos] = MB_TYPE_SKIP;
+ s->current_picture.qscale_table[mb_pos] = 0;
+ v->blk_mv_type[s->block_index[0]] = 0;
+ v->blk_mv_type[s->block_index[1]] = 0;
+ v->blk_mv_type[s->block_index[2]] = 0;
+ v->blk_mv_type[s->block_index[3]] = 0;
+
+ if (!direct) {
+ if (bmvtype == BMV_TYPE_INTERPOLATED) {
+ ff_vc1_pred_mv_intfr(v, 0, 0, 0, 1, v->range_x, v->range_y, v->mb_type[0], 0);
+ ff_vc1_pred_mv_intfr(v, 0, 0, 0, 1, v->range_x, v->range_y, v->mb_type[0], 1);
+ } else {
+ dir = bmvtype == BMV_TYPE_BACKWARD;
+ ff_vc1_pred_mv_intfr(v, 0, 0, 0, 1, v->range_x, v->range_y, v->mb_type[0], dir);
+ if (mvsw) {
+ int dir2 = dir;
+ if (mvsw)
+ dir2 = !dir;
+ for (i = 0; i < 2; i++) {
+ s->mv[dir][i+2][0] = s->mv[dir][i][0] = s->current_picture.motion_val[dir][s->block_index[i+2]][0] = s->current_picture.motion_val[dir][s->block_index[i]][0];
+ s->mv[dir][i+2][1] = s->mv[dir][i][1] = s->current_picture.motion_val[dir][s->block_index[i+2]][1] = s->current_picture.motion_val[dir][s->block_index[i]][1];
+ s->mv[dir2][i+2][0] = s->mv[dir2][i][0] = s->current_picture.motion_val[dir2][s->block_index[i]][0] = s->current_picture.motion_val[dir2][s->block_index[i+2]][0];
+ s->mv[dir2][i+2][1] = s->mv[dir2][i][1] = s->current_picture.motion_val[dir2][s->block_index[i]][1] = s->current_picture.motion_val[dir2][s->block_index[i+2]][1];
+ }
+ } else {
+ v->blk_mv_type[s->block_index[0]] = 1;
+ v->blk_mv_type[s->block_index[1]] = 1;
+ v->blk_mv_type[s->block_index[2]] = 1;
+ v->blk_mv_type[s->block_index[3]] = 1;
+ ff_vc1_pred_mv_intfr(v, 0, 0, 0, 2, v->range_x, v->range_y, 0, !dir);
+ for (i = 0; i < 2; i++) {
+ s->mv[!dir][i+2][0] = s->mv[!dir][i][0] = s->current_picture.motion_val[!dir][s->block_index[i+2]][0] = s->current_picture.motion_val[!dir][s->block_index[i]][0];
+ s->mv[!dir][i+2][1] = s->mv[!dir][i][1] = s->current_picture.motion_val[!dir][s->block_index[i+2]][1] = s->current_picture.motion_val[!dir][s->block_index[i]][1];
+ }
+ }
+ }
+ }
+
+ ff_vc1_mc_1mv(v, dir);
+ if (direct || bmvtype == BMV_TYPE_INTERPOLATED) {
+ ff_vc1_interp_mc(v);
+ }
+ }
+ }
+ if (s->mb_x == s->mb_width - 1)
+ memmove(v->is_intra_base, v->is_intra, sizeof(v->is_intra_base[0]) * s->mb_stride);
+ v->cbp[s->mb_x] = block_cbp;
+ v->ttblk[s->mb_x] = block_tt;
+ return 0;
+}
+
+/** Decode blocks of I-frame
+ */
+static void vc1_decode_i_blocks(VC1Context *v)
+{
+ int k, j;
+ MpegEncContext *s = &v->s;
+ int cbp, val;
+ uint8_t *coded_val;
+ int mb_pos;
+
+ /* select codingmode used for VLC tables selection */
+ switch (v->y_ac_table_index) {
+ case 0:
+ v->codingset = (v->pqindex <= 8) ? CS_HIGH_RATE_INTRA : CS_LOW_MOT_INTRA;
+ break;
+ case 1:
+ v->codingset = CS_HIGH_MOT_INTRA;
+ break;
+ case 2:
+ v->codingset = CS_MID_RATE_INTRA;
+ break;
+ }
+
+ switch (v->c_ac_table_index) {
+ case 0:
+ v->codingset2 = (v->pqindex <= 8) ? CS_HIGH_RATE_INTER : CS_LOW_MOT_INTER;
+ break;
+ case 1:
+ v->codingset2 = CS_HIGH_MOT_INTER;
+ break;
+ case 2:
+ v->codingset2 = CS_MID_RATE_INTER;
+ break;
+ }
+
+ /* Set DC scale - y and c use the same */
+ s->y_dc_scale = s->y_dc_scale_table[v->pq];
+ s->c_dc_scale = s->c_dc_scale_table[v->pq];
+
+ //do frame decode
+ s->mb_x = s->mb_y = 0;
+ s->mb_intra = 1;
+ s->first_slice_line = 1;
+ for (s->mb_y = 0; s->mb_y < s->end_mb_y; s->mb_y++) {
+ s->mb_x = 0;
+ init_block_index(v);
+ for (; s->mb_x < v->end_mb_x; s->mb_x++) {
+ uint8_t *dst[6];
+ ff_update_block_index(s);
+ dst[0] = s->dest[0];
+ dst[1] = dst[0] + 8;
+ dst[2] = s->dest[0] + s->linesize * 8;
+ dst[3] = dst[2] + 8;
+ dst[4] = s->dest[1];
+ dst[5] = s->dest[2];
+ s->bdsp.clear_blocks(s->block[0]);
+ mb_pos = s->mb_x + s->mb_y * s->mb_width;
+ s->current_picture.mb_type[mb_pos] = MB_TYPE_INTRA;
+ s->current_picture.qscale_table[mb_pos] = v->pq;
+ s->current_picture.motion_val[1][s->block_index[0]][0] = 0;
+ s->current_picture.motion_val[1][s->block_index[0]][1] = 0;
+
+ // do actual MB decoding and displaying
+ cbp = get_vlc2(&v->s.gb, ff_msmp4_mb_i_vlc.table, MB_INTRA_VLC_BITS, 2);
+ v->s.ac_pred = get_bits1(&v->s.gb);
+
+ for (k = 0; k < 6; k++) {
+ val = ((cbp >> (5 - k)) & 1);
+
+ if (k < 4) {
+ int pred = vc1_coded_block_pred(&v->s, k, &coded_val);
+ val = val ^ pred;
+ *coded_val = val;
+ }
+ cbp |= val << (5 - k);
+
+ vc1_decode_i_block(v, s->block[k], k, val, (k < 4) ? v->codingset : v->codingset2);
+
+ if (k > 3 && (s->flags & CODEC_FLAG_GRAY))
+ continue;
+ v->vc1dsp.vc1_inv_trans_8x8(s->block[k]);
+ if (v->pq >= 9 && v->overlap) {
+ if (v->rangeredfrm)
+ for (j = 0; j < 64; j++)
+ s->block[k][j] <<= 1;
+ s->idsp.put_signed_pixels_clamped(s->block[k], dst[k],
+ k & 4 ? s->uvlinesize
+ : s->linesize);
+ } else {
+ if (v->rangeredfrm)
+ for (j = 0; j < 64; j++)
+ s->block[k][j] = (s->block[k][j] - 64) << 1;
+ s->idsp.put_pixels_clamped(s->block[k], dst[k],
+ k & 4 ? s->uvlinesize
+ : s->linesize);
+ }
+ }
+
+ if (v->pq >= 9 && v->overlap) {
+ if (s->mb_x) {
+ v->vc1dsp.vc1_h_overlap(s->dest[0], s->linesize);
+ v->vc1dsp.vc1_h_overlap(s->dest[0] + 8 * s->linesize, s->linesize);
+ if (!(s->flags & CODEC_FLAG_GRAY)) {
+ v->vc1dsp.vc1_h_overlap(s->dest[1], s->uvlinesize);
+ v->vc1dsp.vc1_h_overlap(s->dest[2], s->uvlinesize);
+ }
+ }
+ v->vc1dsp.vc1_h_overlap(s->dest[0] + 8, s->linesize);
+ v->vc1dsp.vc1_h_overlap(s->dest[0] + 8 * s->linesize + 8, s->linesize);
+ if (!s->first_slice_line) {
+ v->vc1dsp.vc1_v_overlap(s->dest[0], s->linesize);
+ v->vc1dsp.vc1_v_overlap(s->dest[0] + 8, s->linesize);
+ if (!(s->flags & CODEC_FLAG_GRAY)) {
+ v->vc1dsp.vc1_v_overlap(s->dest[1], s->uvlinesize);
+ v->vc1dsp.vc1_v_overlap(s->dest[2], s->uvlinesize);
+ }
+ }
+ v->vc1dsp.vc1_v_overlap(s->dest[0] + 8 * s->linesize, s->linesize);
+ v->vc1dsp.vc1_v_overlap(s->dest[0] + 8 * s->linesize + 8, s->linesize);
+ }
+ if (v->s.loop_filter)
+ ff_vc1_loop_filter_iblk(v, v->pq);
+
+ if (get_bits_count(&s->gb) > v->bits) {
+ ff_er_add_slice(&s->er, 0, 0, s->mb_x, s->mb_y, ER_MB_ERROR);
+ av_log(s->avctx, AV_LOG_ERROR, "Bits overconsumption: %i > %i\n",
+ get_bits_count(&s->gb), v->bits);
+ return;
+ }
+ }
+ if (!v->s.loop_filter)
+ ff_mpeg_draw_horiz_band(s, s->mb_y * 16, 16);
+ else if (s->mb_y)
+ ff_mpeg_draw_horiz_band(s, (s->mb_y - 1) * 16, 16);
+
+ s->first_slice_line = 0;
+ }
+ if (v->s.loop_filter)
+ ff_mpeg_draw_horiz_band(s, (s->end_mb_y - 1) * 16, 16);
+
+ /* This is intentionally mb_height and not end_mb_y - unlike in advanced
+ * profile, these only differ are when decoding MSS2 rectangles. */
+ ff_er_add_slice(&s->er, 0, 0, s->mb_width - 1, s->mb_height - 1, ER_MB_END);
+}
+
+/** Decode blocks of I-frame for advanced profile
+ */
+static void vc1_decode_i_blocks_adv(VC1Context *v)
+{
+ int k;
+ MpegEncContext *s = &v->s;
+ int cbp, val;
+ uint8_t *coded_val;
+ int mb_pos;
+ int mquant = v->pq;
+ int mqdiff;
+ GetBitContext *gb = &s->gb;
+
+ /* select codingmode used for VLC tables selection */
+ switch (v->y_ac_table_index) {
+ case 0:
+ v->codingset = (v->pqindex <= 8) ? CS_HIGH_RATE_INTRA : CS_LOW_MOT_INTRA;
+ break;
+ case 1:
+ v->codingset = CS_HIGH_MOT_INTRA;
+ break;
+ case 2:
+ v->codingset = CS_MID_RATE_INTRA;
+ break;
+ }
+
+ switch (v->c_ac_table_index) {
+ case 0:
+ v->codingset2 = (v->pqindex <= 8) ? CS_HIGH_RATE_INTER : CS_LOW_MOT_INTER;
+ break;
+ case 1:
+ v->codingset2 = CS_HIGH_MOT_INTER;
+ break;
+ case 2:
+ v->codingset2 = CS_MID_RATE_INTER;
+ break;
+ }
+
+ // do frame decode
+ s->mb_x = s->mb_y = 0;
+ s->mb_intra = 1;
+ s->first_slice_line = 1;
+ s->mb_y = s->start_mb_y;
+ if (s->start_mb_y) {
+ s->mb_x = 0;
+ init_block_index(v);
+ memset(&s->coded_block[s->block_index[0] - s->b8_stride], 0,
+ (1 + s->b8_stride) * sizeof(*s->coded_block));
+ }
+ for (; s->mb_y < s->end_mb_y; s->mb_y++) {
+ s->mb_x = 0;
+ init_block_index(v);
+ for (;s->mb_x < s->mb_width; s->mb_x++) {
+ int16_t (*block)[64] = v->block[v->cur_blk_idx];
+ ff_update_block_index(s);
+ s->bdsp.clear_blocks(block[0]);
+ mb_pos = s->mb_x + s->mb_y * s->mb_stride;
+ s->current_picture.mb_type[mb_pos + v->mb_off] = MB_TYPE_INTRA;
+ s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][0] = 0;
+ s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][1] = 0;
+
+ // do actual MB decoding and displaying
+ if (v->fieldtx_is_raw)
+ v->fieldtx_plane[mb_pos] = get_bits1(&v->s.gb);
+ cbp = get_vlc2(&v->s.gb, ff_msmp4_mb_i_vlc.table, MB_INTRA_VLC_BITS, 2);
+ if ( v->acpred_is_raw)
+ v->s.ac_pred = get_bits1(&v->s.gb);
+ else
+ v->s.ac_pred = v->acpred_plane[mb_pos];
+
+ if (v->condover == CONDOVER_SELECT && v->overflg_is_raw)
+ v->over_flags_plane[mb_pos] = get_bits1(&v->s.gb);
+
+ GET_MQUANT();
+
+ s->current_picture.qscale_table[mb_pos] = mquant;
+ /* Set DC scale - y and c use the same */
+ s->y_dc_scale = s->y_dc_scale_table[mquant];
+ s->c_dc_scale = s->c_dc_scale_table[mquant];
+
+ for (k = 0; k < 6; k++) {
+ val = ((cbp >> (5 - k)) & 1);
+
+ if (k < 4) {
+ int pred = vc1_coded_block_pred(&v->s, k, &coded_val);
+ val = val ^ pred;
+ *coded_val = val;
+ }
+ cbp |= val << (5 - k);
+
+ v->a_avail = !s->first_slice_line || (k == 2 || k == 3);
+ v->c_avail = !!s->mb_x || (k == 1 || k == 3);
+
+ vc1_decode_i_block_adv(v, block[k], k, val,
+ (k < 4) ? v->codingset : v->codingset2, mquant);
+
+ if (k > 3 && (s->flags & CODEC_FLAG_GRAY))
+ continue;
+ v->vc1dsp.vc1_inv_trans_8x8(block[k]);
+ }
+
+ ff_vc1_smooth_overlap_filter_iblk(v);
+ vc1_put_signed_blocks_clamped(v);
+ if (v->s.loop_filter)
+ ff_vc1_loop_filter_iblk_delayed(v, v->pq);
+
+ if (get_bits_count(&s->gb) > v->bits) {
+ // TODO: may need modification to handle slice coding
+ ff_er_add_slice(&s->er, 0, s->start_mb_y, s->mb_x, s->mb_y, ER_MB_ERROR);
+ av_log(s->avctx, AV_LOG_ERROR, "Bits overconsumption: %i > %i\n",
+ get_bits_count(&s->gb), v->bits);
+ return;
+ }
+ }
+ if (!v->s.loop_filter)
+ ff_mpeg_draw_horiz_band(s, s->mb_y * 16, 16);
+ else if (s->mb_y)
+ ff_mpeg_draw_horiz_band(s, (s->mb_y-1) * 16, 16);
+ s->first_slice_line = 0;
+ }
+
+ /* raw bottom MB row */
+ s->mb_x = 0;
+ init_block_index(v);
+
+ for (;s->mb_x < s->mb_width; s->mb_x++) {
+ ff_update_block_index(s);
+ vc1_put_signed_blocks_clamped(v);
+ if (v->s.loop_filter)
+ ff_vc1_loop_filter_iblk_delayed(v, v->pq);
+ }
+ if (v->s.loop_filter)
+ ff_mpeg_draw_horiz_band(s, (s->end_mb_y-1)*16, 16);
+ ff_er_add_slice(&s->er, 0, s->start_mb_y << v->field_mode, s->mb_width - 1,
+ (s->end_mb_y << v->field_mode) - 1, ER_MB_END);
+}
+
+static void vc1_decode_p_blocks(VC1Context *v)
+{
+ MpegEncContext *s = &v->s;
+ int apply_loop_filter;
+
+ /* select codingmode used for VLC tables selection */
+ switch (v->c_ac_table_index) {
+ case 0:
+ v->codingset = (v->pqindex <= 8) ? CS_HIGH_RATE_INTRA : CS_LOW_MOT_INTRA;
+ break;
+ case 1:
+ v->codingset = CS_HIGH_MOT_INTRA;
+ break;
+ case 2:
+ v->codingset = CS_MID_RATE_INTRA;
+ break;
+ }
+
+ switch (v->c_ac_table_index) {
+ case 0:
+ v->codingset2 = (v->pqindex <= 8) ? CS_HIGH_RATE_INTER : CS_LOW_MOT_INTER;
+ break;
+ case 1:
+ v->codingset2 = CS_HIGH_MOT_INTER;
+ break;
+ case 2:
+ v->codingset2 = CS_MID_RATE_INTER;
+ break;
+ }
+
+ apply_loop_filter = s->loop_filter && !(s->avctx->skip_loop_filter >= AVDISCARD_NONKEY) &&
+ v->fcm == PROGRESSIVE;
+ s->first_slice_line = 1;
+ memset(v->cbp_base, 0, sizeof(v->cbp_base[0])*2*s->mb_stride);
+ for (s->mb_y = s->start_mb_y; s->mb_y < s->end_mb_y; s->mb_y++) {
+ s->mb_x = 0;
+ init_block_index(v);
+ for (; s->mb_x < s->mb_width; s->mb_x++) {
+ ff_update_block_index(s);
+
+ if (v->fcm == ILACE_FIELD)
+ vc1_decode_p_mb_intfi(v);
+ else if (v->fcm == ILACE_FRAME)
+ vc1_decode_p_mb_intfr(v);
+ else vc1_decode_p_mb(v);
+ if (s->mb_y != s->start_mb_y && apply_loop_filter)
+ ff_vc1_apply_p_loop_filter(v);
+ if (get_bits_count(&s->gb) > v->bits || get_bits_count(&s->gb) < 0) {
+ // TODO: may need modification to handle slice coding
+ ff_er_add_slice(&s->er, 0, s->start_mb_y, s->mb_x, s->mb_y, ER_MB_ERROR);
+ av_log(s->avctx, AV_LOG_ERROR, "Bits overconsumption: %i > %i at %ix%i\n",
+ get_bits_count(&s->gb), v->bits, s->mb_x, s->mb_y);
+ return;
+ }
+ }
+ memmove(v->cbp_base, v->cbp, sizeof(v->cbp_base[0]) * s->mb_stride);
+ memmove(v->ttblk_base, v->ttblk, sizeof(v->ttblk_base[0]) * s->mb_stride);
+ memmove(v->is_intra_base, v->is_intra, sizeof(v->is_intra_base[0]) * s->mb_stride);
+ memmove(v->luma_mv_base, v->luma_mv, sizeof(v->luma_mv_base[0]) * s->mb_stride);
+ if (s->mb_y != s->start_mb_y) ff_mpeg_draw_horiz_band(s, (s->mb_y - 1) * 16, 16);
+ s->first_slice_line = 0;
+ }
+ if (apply_loop_filter) {
+ s->mb_x = 0;
+ init_block_index(v);
+ for (; s->mb_x < s->mb_width; s->mb_x++) {
+ ff_update_block_index(s);
+ ff_vc1_apply_p_loop_filter(v);
+ }
+ }
+ if (s->end_mb_y >= s->start_mb_y)
+ ff_mpeg_draw_horiz_band(s, (s->end_mb_y - 1) * 16, 16);
+ ff_er_add_slice(&s->er, 0, s->start_mb_y << v->field_mode, s->mb_width - 1,
+ (s->end_mb_y << v->field_mode) - 1, ER_MB_END);
+}
+
+static void vc1_decode_b_blocks(VC1Context *v)
+{
+ MpegEncContext *s = &v->s;
+
+ /* select codingmode used for VLC tables selection */
+ switch (v->c_ac_table_index) {
+ case 0:
+ v->codingset = (v->pqindex <= 8) ? CS_HIGH_RATE_INTRA : CS_LOW_MOT_INTRA;
+ break;
+ case 1:
+ v->codingset = CS_HIGH_MOT_INTRA;
+ break;
+ case 2:
+ v->codingset = CS_MID_RATE_INTRA;
+ break;
+ }
+
+ switch (v->c_ac_table_index) {
+ case 0:
+ v->codingset2 = (v->pqindex <= 8) ? CS_HIGH_RATE_INTER : CS_LOW_MOT_INTER;
+ break;
+ case 1:
+ v->codingset2 = CS_HIGH_MOT_INTER;
+ break;
+ case 2:
+ v->codingset2 = CS_MID_RATE_INTER;
+ break;
+ }
+
+ s->first_slice_line = 1;
+ for (s->mb_y = s->start_mb_y; s->mb_y < s->end_mb_y; s->mb_y++) {
+ s->mb_x = 0;
+ init_block_index(v);
+ for (; s->mb_x < s->mb_width; s->mb_x++) {
+ ff_update_block_index(s);
+
+ if (v->fcm == ILACE_FIELD)
+ vc1_decode_b_mb_intfi(v);
+ else if (v->fcm == ILACE_FRAME)
+ vc1_decode_b_mb_intfr(v);
+ else
+ vc1_decode_b_mb(v);
+ if (get_bits_count(&s->gb) > v->bits || get_bits_count(&s->gb) < 0) {
+ // TODO: may need modification to handle slice coding
+ ff_er_add_slice(&s->er, 0, s->start_mb_y, s->mb_x, s->mb_y, ER_MB_ERROR);
+ av_log(s->avctx, AV_LOG_ERROR, "Bits overconsumption: %i > %i at %ix%i\n",
+ get_bits_count(&s->gb), v->bits, s->mb_x, s->mb_y);
+ return;
+ }
+ if (v->s.loop_filter)
+ ff_vc1_loop_filter_iblk(v, v->pq);
+ }
+ if (!v->s.loop_filter)
+ ff_mpeg_draw_horiz_band(s, s->mb_y * 16, 16);
+ else if (s->mb_y)
+ ff_mpeg_draw_horiz_band(s, (s->mb_y - 1) * 16, 16);
+ s->first_slice_line = 0;
+ }
+ if (v->s.loop_filter)
+ ff_mpeg_draw_horiz_band(s, (s->end_mb_y - 1) * 16, 16);
+ ff_er_add_slice(&s->er, 0, s->start_mb_y << v->field_mode, s->mb_width - 1,
+ (s->end_mb_y << v->field_mode) - 1, ER_MB_END);
+}
+
+static void vc1_decode_skip_blocks(VC1Context *v)
+{
+ MpegEncContext *s = &v->s;
+
+ if (!v->s.last_picture.f->data[0])
+ return;
+
+ ff_er_add_slice(&s->er, 0, s->start_mb_y, s->mb_width - 1, s->end_mb_y - 1, ER_MB_END);
+ s->first_slice_line = 1;
+ for (s->mb_y = s->start_mb_y; s->mb_y < s->end_mb_y; s->mb_y++) {
+ s->mb_x = 0;
+ init_block_index(v);
+ ff_update_block_index(s);
+ memcpy(s->dest[0], s->last_picture.f->data[0] + s->mb_y * 16 * s->linesize, s->linesize * 16);
+ memcpy(s->dest[1], s->last_picture.f->data[1] + s->mb_y * 8 * s->uvlinesize, s->uvlinesize * 8);
+ memcpy(s->dest[2], s->last_picture.f->data[2] + s->mb_y * 8 * s->uvlinesize, s->uvlinesize * 8);
+ ff_mpeg_draw_horiz_band(s, s->mb_y * 16, 16);
+ s->first_slice_line = 0;
+ }
+ s->pict_type = AV_PICTURE_TYPE_P;
+}
+
+void ff_vc1_decode_blocks(VC1Context *v)
+{
+
+ v->s.esc3_level_length = 0;
+ if (v->x8_type) {
+ ff_intrax8_decode_picture(&v->x8, 2*v->pq + v->halfpq, v->pq * !v->pquantizer);
+ } else {
+ v->cur_blk_idx = 0;
+ v->left_blk_idx = -1;
+ v->topleft_blk_idx = 1;
+ v->top_blk_idx = 2;
+ switch (v->s.pict_type) {
+ case AV_PICTURE_TYPE_I:
+ if (v->profile == PROFILE_ADVANCED)
+ vc1_decode_i_blocks_adv(v);
+ else
+ vc1_decode_i_blocks(v);
+ break;
+ case AV_PICTURE_TYPE_P:
+ if (v->p_frame_skipped)
+ vc1_decode_skip_blocks(v);
+ else
+ vc1_decode_p_blocks(v);
+ break;
+ case AV_PICTURE_TYPE_B:
+ if (v->bi_type) {
+ if (v->profile == PROFILE_ADVANCED)
+ vc1_decode_i_blocks_adv(v);
+ else
+ vc1_decode_i_blocks(v);
+ } else
+ vc1_decode_b_blocks(v);
+ break;
+ }
+ }
+}
--- /dev/null
+/*
+ * VC-1 and WMV3 decoder
+ * Copyright (c) 2011 Mashiat Sarker Shakkhar
+ * Copyright (c) 2006-2007 Konstantin Shishkov
+ * Partly based on vc9.c (c) 2005 Anonymous, Alex Beregszaszi, Michael Niedermayer
+ *
+ * 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
+ * VC-1 and WMV3 loopfilter
+ */
+
+#include "avcodec.h"
+#include "mpegvideo.h"
+#include "vc1.h"
+#include "vc1dsp.h"
+
+void ff_vc1_loop_filter_iblk(VC1Context *v, int pq)
+{
+ MpegEncContext *s = &v->s;
+ int j;
+ if (!s->first_slice_line) {
+ v->vc1dsp.vc1_v_loop_filter16(s->dest[0], s->linesize, pq);
+ if (s->mb_x)
+ v->vc1dsp.vc1_h_loop_filter16(s->dest[0] - 16 * s->linesize, s->linesize, pq);
+ v->vc1dsp.vc1_h_loop_filter16(s->dest[0] - 16 * s->linesize + 8, s->linesize, pq);
+ for (j = 0; j < 2; j++) {
+ v->vc1dsp.vc1_v_loop_filter8(s->dest[j + 1], s->uvlinesize, pq);
+ if (s->mb_x)
+ v->vc1dsp.vc1_h_loop_filter8(s->dest[j + 1] - 8 * s->uvlinesize, s->uvlinesize, pq);
+ }
+ }
+ v->vc1dsp.vc1_v_loop_filter16(s->dest[0] + 8 * s->linesize, s->linesize, pq);
+
+ if (s->mb_y == s->end_mb_y - 1) {
+ if (s->mb_x) {
+ v->vc1dsp.vc1_h_loop_filter16(s->dest[0], s->linesize, pq);
+ v->vc1dsp.vc1_h_loop_filter8(s->dest[1], s->uvlinesize, pq);
+ v->vc1dsp.vc1_h_loop_filter8(s->dest[2], s->uvlinesize, pq);
+ }
+ v->vc1dsp.vc1_h_loop_filter16(s->dest[0] + 8, s->linesize, pq);
+ }
+}
+
+void ff_vc1_loop_filter_iblk_delayed(VC1Context *v, int pq)
+{
+ MpegEncContext *s = &v->s;
+ int j;
+
+ /* The loopfilter runs 1 row and 1 column behind the overlap filter, which
+ * means it runs two rows/cols behind the decoding loop. */
+ if (!s->first_slice_line) {
+ if (s->mb_x) {
+ if (s->mb_y >= s->start_mb_y + 2) {
+ v->vc1dsp.vc1_v_loop_filter16(s->dest[0] - 16 * s->linesize - 16, s->linesize, pq);
+
+ if (s->mb_x >= 2)
+ v->vc1dsp.vc1_h_loop_filter16(s->dest[0] - 32 * s->linesize - 16, s->linesize, pq);
+ v->vc1dsp.vc1_h_loop_filter16(s->dest[0] - 32 * s->linesize - 8, s->linesize, pq);
+ for (j = 0; j < 2; j++) {
+ v->vc1dsp.vc1_v_loop_filter8(s->dest[j + 1] - 8 * s->uvlinesize - 8, s->uvlinesize, pq);
+ if (s->mb_x >= 2) {
+ v->vc1dsp.vc1_h_loop_filter8(s->dest[j + 1] - 16 * s->uvlinesize - 8, s->uvlinesize, pq);
+ }
+ }
+ }
+ v->vc1dsp.vc1_v_loop_filter16(s->dest[0] - 8 * s->linesize - 16, s->linesize, pq);
+ }
+
+ if (s->mb_x == s->mb_width - 1) {
+ if (s->mb_y >= s->start_mb_y + 2) {
+ v->vc1dsp.vc1_v_loop_filter16(s->dest[0] - 16 * s->linesize, s->linesize, pq);
+
+ if (s->mb_x)
+ v->vc1dsp.vc1_h_loop_filter16(s->dest[0] - 32 * s->linesize, s->linesize, pq);
+ v->vc1dsp.vc1_h_loop_filter16(s->dest[0] - 32 * s->linesize + 8, s->linesize, pq);
+ for (j = 0; j < 2; j++) {
+ v->vc1dsp.vc1_v_loop_filter8(s->dest[j + 1] - 8 * s->uvlinesize, s->uvlinesize, pq);
+ if (s->mb_x >= 2) {
+ v->vc1dsp.vc1_h_loop_filter8(s->dest[j + 1] - 16 * s->uvlinesize, s->uvlinesize, pq);
+ }
+ }
+ }
+ v->vc1dsp.vc1_v_loop_filter16(s->dest[0] - 8 * s->linesize, s->linesize, pq);
+ }
+
+ if (s->mb_y == s->end_mb_y) {
+ if (s->mb_x) {
+ if (s->mb_x >= 2)
+ v->vc1dsp.vc1_h_loop_filter16(s->dest[0] - 16 * s->linesize - 16, s->linesize, pq);
+ v->vc1dsp.vc1_h_loop_filter16(s->dest[0] - 16 * s->linesize - 8, s->linesize, pq);
+ if (s->mb_x >= 2) {
+ for (j = 0; j < 2; j++) {
+ v->vc1dsp.vc1_h_loop_filter8(s->dest[j + 1] - 8 * s->uvlinesize - 8, s->uvlinesize, pq);
+ }
+ }
+ }
+
+ if (s->mb_x == s->mb_width - 1) {
+ if (s->mb_x)
+ v->vc1dsp.vc1_h_loop_filter16(s->dest[0] - 16 * s->linesize, s->linesize, pq);
+ v->vc1dsp.vc1_h_loop_filter16(s->dest[0] - 16 * s->linesize + 8, s->linesize, pq);
+ if (s->mb_x) {
+ for (j = 0; j < 2; j++) {
+ v->vc1dsp.vc1_h_loop_filter8(s->dest[j + 1] - 8 * s->uvlinesize, s->uvlinesize, pq);
+ }
+ }
+ }
+ }
+ }
+}
+
+void ff_vc1_smooth_overlap_filter_iblk(VC1Context *v)
+{
+ MpegEncContext *s = &v->s;
+ int mb_pos;
+
+ if (v->condover == CONDOVER_NONE)
+ return;
+
+ mb_pos = s->mb_x + s->mb_y * s->mb_stride;
+
+ /* Within a MB, the horizontal overlap always runs before the vertical.
+ * To accomplish that, we run the H on left and internal borders of the
+ * currently decoded MB. Then, we wait for the next overlap iteration
+ * to do H overlap on the right edge of this MB, before moving over and
+ * running the V overlap. Therefore, the V overlap makes us trail by one
+ * MB col and the H overlap filter makes us trail by one MB row. This
+ * is reflected in the time at which we run the put_pixels loop. */
+ if (v->condover == CONDOVER_ALL || v->pq >= 9 || v->over_flags_plane[mb_pos]) {
+ if (s->mb_x && (v->condover == CONDOVER_ALL || v->pq >= 9 ||
+ v->over_flags_plane[mb_pos - 1])) {
+ v->vc1dsp.vc1_h_s_overlap(v->block[v->left_blk_idx][1],
+ v->block[v->cur_blk_idx][0]);
+ v->vc1dsp.vc1_h_s_overlap(v->block[v->left_blk_idx][3],
+ v->block[v->cur_blk_idx][2]);
+ if (!(s->flags & CODEC_FLAG_GRAY)) {
+ v->vc1dsp.vc1_h_s_overlap(v->block[v->left_blk_idx][4],
+ v->block[v->cur_blk_idx][4]);
+ v->vc1dsp.vc1_h_s_overlap(v->block[v->left_blk_idx][5],
+ v->block[v->cur_blk_idx][5]);
+ }
+ }
+ v->vc1dsp.vc1_h_s_overlap(v->block[v->cur_blk_idx][0],
+ v->block[v->cur_blk_idx][1]);
+ v->vc1dsp.vc1_h_s_overlap(v->block[v->cur_blk_idx][2],
+ v->block[v->cur_blk_idx][3]);
+
+ if (s->mb_x == s->mb_width - 1) {
+ if (!s->first_slice_line && (v->condover == CONDOVER_ALL || v->pq >= 9 ||
+ v->over_flags_plane[mb_pos - s->mb_stride])) {
+ v->vc1dsp.vc1_v_s_overlap(v->block[v->top_blk_idx][2],
+ v->block[v->cur_blk_idx][0]);
+ v->vc1dsp.vc1_v_s_overlap(v->block[v->top_blk_idx][3],
+ v->block[v->cur_blk_idx][1]);
+ if (!(s->flags & CODEC_FLAG_GRAY)) {
+ v->vc1dsp.vc1_v_s_overlap(v->block[v->top_blk_idx][4],
+ v->block[v->cur_blk_idx][4]);
+ v->vc1dsp.vc1_v_s_overlap(v->block[v->top_blk_idx][5],
+ v->block[v->cur_blk_idx][5]);
+ }
+ }
+ v->vc1dsp.vc1_v_s_overlap(v->block[v->cur_blk_idx][0],
+ v->block[v->cur_blk_idx][2]);
+ v->vc1dsp.vc1_v_s_overlap(v->block[v->cur_blk_idx][1],
+ v->block[v->cur_blk_idx][3]);
+ }
+ }
+ if (s->mb_x && (v->condover == CONDOVER_ALL || v->over_flags_plane[mb_pos - 1])) {
+ if (!s->first_slice_line && (v->condover == CONDOVER_ALL || v->pq >= 9 ||
+ v->over_flags_plane[mb_pos - s->mb_stride - 1])) {
+ v->vc1dsp.vc1_v_s_overlap(v->block[v->topleft_blk_idx][2],
+ v->block[v->left_blk_idx][0]);
+ v->vc1dsp.vc1_v_s_overlap(v->block[v->topleft_blk_idx][3],
+ v->block[v->left_blk_idx][1]);
+ if (!(s->flags & CODEC_FLAG_GRAY)) {
+ v->vc1dsp.vc1_v_s_overlap(v->block[v->topleft_blk_idx][4],
+ v->block[v->left_blk_idx][4]);
+ v->vc1dsp.vc1_v_s_overlap(v->block[v->topleft_blk_idx][5],
+ v->block[v->left_blk_idx][5]);
+ }
+ }
+ v->vc1dsp.vc1_v_s_overlap(v->block[v->left_blk_idx][0],
+ v->block[v->left_blk_idx][2]);
+ v->vc1dsp.vc1_v_s_overlap(v->block[v->left_blk_idx][1],
+ v->block[v->left_blk_idx][3]);
+ }
+}
+
+static av_always_inline void vc1_apply_p_v_loop_filter(VC1Context *v, int block_num)
+{
+ MpegEncContext *s = &v->s;
+ int mb_cbp = v->cbp[s->mb_x - s->mb_stride],
+ block_cbp = mb_cbp >> (block_num * 4), bottom_cbp,
+ mb_is_intra = v->is_intra[s->mb_x - s->mb_stride],
+ block_is_intra = mb_is_intra >> block_num, bottom_is_intra;
+ int idx, linesize = block_num > 3 ? s->uvlinesize : s->linesize, ttblk;
+ uint8_t *dst;
+
+ if (block_num > 3) {
+ dst = s->dest[block_num - 3];
+ } else {
+ dst = s->dest[0] + (block_num & 1) * 8 + ((block_num & 2) * 4 - 8) * linesize;
+ }
+ if (s->mb_y != s->end_mb_y || block_num < 2) {
+ int16_t (*mv)[2];
+ int mv_stride;
+
+ if (block_num > 3) {
+ bottom_cbp = v->cbp[s->mb_x] >> (block_num * 4);
+ bottom_is_intra = v->is_intra[s->mb_x] >> block_num;
+ mv = &v->luma_mv[s->mb_x - s->mb_stride];
+ mv_stride = s->mb_stride;
+ } else {
+ bottom_cbp = (block_num < 2) ? (mb_cbp >> ((block_num + 2) * 4))
+ : (v->cbp[s->mb_x] >> ((block_num - 2) * 4));
+ bottom_is_intra = (block_num < 2) ? (mb_is_intra >> (block_num + 2))
+ : (v->is_intra[s->mb_x] >> (block_num - 2));
+ mv_stride = s->b8_stride;
+ mv = &s->current_picture.motion_val[0][s->block_index[block_num] - 2 * mv_stride];
+ }
+
+ if (bottom_is_intra & 1 || block_is_intra & 1 ||
+ mv[0][0] != mv[mv_stride][0] || mv[0][1] != mv[mv_stride][1]) {
+ v->vc1dsp.vc1_v_loop_filter8(dst, linesize, v->pq);
+ } else {
+ idx = ((bottom_cbp >> 2) | block_cbp) & 3;
+ if (idx == 3) {
+ v->vc1dsp.vc1_v_loop_filter8(dst, linesize, v->pq);
+ } else if (idx) {
+ if (idx == 1)
+ v->vc1dsp.vc1_v_loop_filter4(dst + 4, linesize, v->pq);
+ else
+ v->vc1dsp.vc1_v_loop_filter4(dst, linesize, v->pq);
+ }
+ }
+ }
+
+ dst -= 4 * linesize;
+ ttblk = (v->ttblk[s->mb_x - s->mb_stride] >> (block_num * 4)) & 0xF;
+ if (ttblk == TT_4X4 || ttblk == TT_8X4) {
+ idx = (block_cbp | (block_cbp >> 2)) & 3;
+ if (idx == 3) {
+ v->vc1dsp.vc1_v_loop_filter8(dst, linesize, v->pq);
+ } else if (idx) {
+ if (idx == 1)
+ v->vc1dsp.vc1_v_loop_filter4(dst + 4, linesize, v->pq);
+ else
+ v->vc1dsp.vc1_v_loop_filter4(dst, linesize, v->pq);
+ }
+ }
+}
+
+static av_always_inline void vc1_apply_p_h_loop_filter(VC1Context *v, int block_num)
+{
+ MpegEncContext *s = &v->s;
+ int mb_cbp = v->cbp[s->mb_x - 1 - s->mb_stride],
+ block_cbp = mb_cbp >> (block_num * 4), right_cbp,
+ mb_is_intra = v->is_intra[s->mb_x - 1 - s->mb_stride],
+ block_is_intra = mb_is_intra >> block_num, right_is_intra;
+ int idx, linesize = block_num > 3 ? s->uvlinesize : s->linesize, ttblk;
+ uint8_t *dst;
+
+ if (block_num > 3) {
+ dst = s->dest[block_num - 3] - 8 * linesize;
+ } else {
+ dst = s->dest[0] + (block_num & 1) * 8 + ((block_num & 2) * 4 - 16) * linesize - 8;
+ }
+
+ if (s->mb_x != s->mb_width || !(block_num & 5)) {
+ int16_t (*mv)[2];
+
+ if (block_num > 3) {
+ right_cbp = v->cbp[s->mb_x - s->mb_stride] >> (block_num * 4);
+ right_is_intra = v->is_intra[s->mb_x - s->mb_stride] >> block_num;
+ mv = &v->luma_mv[s->mb_x - s->mb_stride - 1];
+ } else {
+ right_cbp = (block_num & 1) ? (v->cbp[s->mb_x - s->mb_stride] >> ((block_num - 1) * 4))
+ : (mb_cbp >> ((block_num + 1) * 4));
+ right_is_intra = (block_num & 1) ? (v->is_intra[s->mb_x - s->mb_stride] >> (block_num - 1))
+ : (mb_is_intra >> (block_num + 1));
+ mv = &s->current_picture.motion_val[0][s->block_index[block_num] - s->b8_stride * 2 - 2];
+ }
+ if (block_is_intra & 1 || right_is_intra & 1 || mv[0][0] != mv[1][0] || mv[0][1] != mv[1][1]) {
+ v->vc1dsp.vc1_h_loop_filter8(dst, linesize, v->pq);
+ } else {
+ idx = ((right_cbp >> 1) | block_cbp) & 5; // FIXME check
+ if (idx == 5) {
+ v->vc1dsp.vc1_h_loop_filter8(dst, linesize, v->pq);
+ } else if (idx) {
+ if (idx == 1)
+ v->vc1dsp.vc1_h_loop_filter4(dst + 4 * linesize, linesize, v->pq);
+ else
+ v->vc1dsp.vc1_h_loop_filter4(dst, linesize, v->pq);
+ }
+ }
+ }
+
+ dst -= 4;
+ ttblk = (v->ttblk[s->mb_x - s->mb_stride - 1] >> (block_num * 4)) & 0xf;
+ if (ttblk == TT_4X4 || ttblk == TT_4X8) {
+ idx = (block_cbp | (block_cbp >> 1)) & 5;
+ if (idx == 5) {
+ v->vc1dsp.vc1_h_loop_filter8(dst, linesize, v->pq);
+ } else if (idx) {
+ if (idx == 1)
+ v->vc1dsp.vc1_h_loop_filter4(dst + linesize * 4, linesize, v->pq);
+ else
+ v->vc1dsp.vc1_h_loop_filter4(dst, linesize, v->pq);
+ }
+ }
+}
+
+void ff_vc1_apply_p_loop_filter(VC1Context *v)
+{
+ MpegEncContext *s = &v->s;
+ int i;
+
+ for (i = 0; i < 6; i++) {
+ vc1_apply_p_v_loop_filter(v, i);
+ }
+
+ /* V always precedes H, therefore we run H one MB before V;
+ * at the end of a row, we catch up to complete the row */
+ if (s->mb_x) {
+ for (i = 0; i < 6; i++) {
+ vc1_apply_p_h_loop_filter(v, i);
+ }
+ if (s->mb_x == s->mb_width - 1) {
+ s->mb_x++;
+ ff_update_block_index(s);
+ for (i = 0; i < 6; i++) {
+ vc1_apply_p_h_loop_filter(v, i);
+ }
+ }
+ }
+}
--- /dev/null
+/*
+ * VC-1 and WMV3 decoder
+ * Copyright (c) 2011 Mashiat Sarker Shakkhar
+ * Copyright (c) 2006-2007 Konstantin Shishkov
+ * Partly based on vc9.c (c) 2005 Anonymous, Alex Beregszaszi, Michael Niedermayer
+ *
+ * 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
+ * VC-1 and WMV3 block decoding routines
+ */
+
+#include "avcodec.h"
+#include "h264chroma.h"
+#include "mathops.h"
+#include "mpegvideo.h"
+#include "vc1.h"
+
+/** Do motion compensation over 1 macroblock
+ * Mostly adapted hpel_motion and qpel_motion from mpegvideo.c
+ */
+void ff_vc1_mc_1mv(VC1Context *v, int dir)
+{
+ MpegEncContext *s = &v->s;
+ H264ChromaContext *h264chroma = &v->h264chroma;
+ uint8_t *srcY, *srcU, *srcV;
+ int dxy, mx, my, uvmx, uvmy, src_x, src_y, uvsrc_x, uvsrc_y;
+ int v_edge_pos = s->v_edge_pos >> v->field_mode;
+ int i;
+ uint8_t (*luty)[256], (*lutuv)[256];
+ int use_ic;
+
+ if ((!v->field_mode ||
+ (v->ref_field_type[dir] == 1 && v->cur_field_type == 1)) &&
+ !v->s.last_picture.f->data[0])
+ return;
+
+ mx = s->mv[dir][0][0];
+ my = s->mv[dir][0][1];
+
+ // store motion vectors for further use in B frames
+ if (s->pict_type == AV_PICTURE_TYPE_P) {
+ for (i = 0; i < 4; i++) {
+ s->current_picture.motion_val[1][s->block_index[i] + v->blocks_off][0] = mx;
+ s->current_picture.motion_val[1][s->block_index[i] + v->blocks_off][1] = my;
+ }
+ }
+
+ uvmx = (mx + ((mx & 3) == 3)) >> 1;
+ uvmy = (my + ((my & 3) == 3)) >> 1;
+ v->luma_mv[s->mb_x][0] = uvmx;
+ v->luma_mv[s->mb_x][1] = uvmy;
+
+ if (v->field_mode &&
+ v->cur_field_type != v->ref_field_type[dir]) {
+ my = my - 2 + 4 * v->cur_field_type;
+ uvmy = uvmy - 2 + 4 * v->cur_field_type;
+ }
+
+ // fastuvmc shall be ignored for interlaced frame picture
+ if (v->fastuvmc && (v->fcm != ILACE_FRAME)) {
+ uvmx = uvmx + ((uvmx < 0) ? (uvmx & 1) : -(uvmx & 1));
+ uvmy = uvmy + ((uvmy < 0) ? (uvmy & 1) : -(uvmy & 1));
+ }
+ if (!dir) {
+ if (v->field_mode && (v->cur_field_type != v->ref_field_type[dir]) && v->second_field) {
+ srcY = s->current_picture.f->data[0];
+ srcU = s->current_picture.f->data[1];
+ srcV = s->current_picture.f->data[2];
+ luty = v->curr_luty;
+ lutuv = v->curr_lutuv;
+ use_ic = *v->curr_use_ic;
+ } else {
+ srcY = s->last_picture.f->data[0];
+ srcU = s->last_picture.f->data[1];
+ srcV = s->last_picture.f->data[2];
+ luty = v->last_luty;
+ lutuv = v->last_lutuv;
+ use_ic = v->last_use_ic;
+ }
+ } else {
+ srcY = s->next_picture.f->data[0];
+ srcU = s->next_picture.f->data[1];
+ srcV = s->next_picture.f->data[2];
+ luty = v->next_luty;
+ lutuv = v->next_lutuv;
+ use_ic = v->next_use_ic;
+ }
+
+ if (!srcY || !srcU) {
+ av_log(v->s.avctx, AV_LOG_ERROR, "Referenced frame missing.\n");
+ return;
+ }
+
+ src_x = s->mb_x * 16 + (mx >> 2);
+ src_y = s->mb_y * 16 + (my >> 2);
+ uvsrc_x = s->mb_x * 8 + (uvmx >> 2);
+ uvsrc_y = s->mb_y * 8 + (uvmy >> 2);
+
+ if (v->profile != PROFILE_ADVANCED) {
+ src_x = av_clip( src_x, -16, s->mb_width * 16);
+ src_y = av_clip( src_y, -16, s->mb_height * 16);
+ uvsrc_x = av_clip(uvsrc_x, -8, s->mb_width * 8);
+ uvsrc_y = av_clip(uvsrc_y, -8, s->mb_height * 8);
+ } else {
+ src_x = av_clip( src_x, -17, s->avctx->coded_width);
+ src_y = av_clip( src_y, -18, s->avctx->coded_height + 1);
+ uvsrc_x = av_clip(uvsrc_x, -8, s->avctx->coded_width >> 1);
+ uvsrc_y = av_clip(uvsrc_y, -8, s->avctx->coded_height >> 1);
+ }
+
+ srcY += src_y * s->linesize + src_x;
+ srcU += uvsrc_y * s->uvlinesize + uvsrc_x;
+ srcV += uvsrc_y * s->uvlinesize + uvsrc_x;
+
+ if (v->field_mode && v->ref_field_type[dir]) {
+ srcY += s->current_picture_ptr->f->linesize[0];
+ srcU += s->current_picture_ptr->f->linesize[1];
+ srcV += s->current_picture_ptr->f->linesize[2];
+ }
+
+ /* for grayscale we should not try to read from unknown area */
+ if (s->flags & CODEC_FLAG_GRAY) {
+ srcU = s->edge_emu_buffer + 18 * s->linesize;
+ srcV = s->edge_emu_buffer + 18 * s->linesize;
+ }
+
+ if (v->rangeredfrm || use_ic
+ || s->h_edge_pos < 22 || v_edge_pos < 22
+ || (unsigned)(src_x - s->mspel) > s->h_edge_pos - (mx&3) - 16 - s->mspel * 3
+ || (unsigned)(src_y - 1) > v_edge_pos - (my&3) - 16 - 3) {
+ uint8_t *ubuf = s->edge_emu_buffer + 19 * s->linesize;
+ uint8_t *vbuf = ubuf + 9 * s->uvlinesize;
+
+ srcY -= s->mspel * (1 + 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(ubuf, 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(vbuf, srcV,
+ s->uvlinesize, s->uvlinesize,
+ 8 + 1, 8 + 1,
+ uvsrc_x, uvsrc_y,
+ s->h_edge_pos >> 1, v_edge_pos >> 1);
+ srcU = ubuf;
+ srcV = vbuf;
+ /* if we deal with range reduction we need to scale source blocks */
+ if (v->rangeredfrm) {
+ int i, j;
+ uint8_t *src, *src2;
+
+ src = srcY;
+ for (j = 0; j < 17 + s->mspel * 2; j++) {
+ for (i = 0; i < 17 + s->mspel * 2; i++)
+ src[i] = ((src[i] - 128) >> 1) + 128;
+ src += s->linesize;
+ }
+ src = srcU;
+ src2 = srcV;
+ for (j = 0; j < 9; j++) {
+ for (i = 0; i < 9; i++) {
+ src[i] = ((src[i] - 128) >> 1) + 128;
+ src2[i] = ((src2[i] - 128) >> 1) + 128;
+ }
+ src += s->uvlinesize;
+ src2 += s->uvlinesize;
+ }
+ }
+ /* if we deal with intensity compensation we need to scale source blocks */
+ if (use_ic) {
+ int i, j;
+ uint8_t *src, *src2;
+
+ src = srcY;
+ for (j = 0; j < 17 + s->mspel * 2; j++) {
+ int f = v->field_mode ? v->ref_field_type[dir] : ((j + src_y - s->mspel) & 1) ;
+ for (i = 0; i < 17 + s->mspel * 2; i++)
+ src[i] = luty[f][src[i]];
+ src += s->linesize;
+ }
+ src = srcU;
+ src2 = srcV;
+ for (j = 0; j < 9; j++) {
+ int f = v->field_mode ? v->ref_field_type[dir] : ((j + uvsrc_y) & 1);
+ for (i = 0; i < 9; i++) {
+ src[i] = lutuv[f][src[i]];
+ src2[i] = lutuv[f][src2[i]];
+ }
+ src += s->uvlinesize;
+ src2 += s->uvlinesize;
+ }
+ }
+ srcY += s->mspel * (1 + s->linesize);
+ }
+
+ if (s->mspel) {
+ dxy = ((my & 3) << 2) | (mx & 3);
+ v->vc1dsp.put_vc1_mspel_pixels_tab[0][dxy](s->dest[0] , srcY , s->linesize, v->rnd);
+ } else { // hpel mc - always used for luma
+ dxy = (my & 2) | ((mx & 2) >> 1);
+ if (!v->rnd)
+ s->hdsp.put_pixels_tab[0][dxy](s->dest[0], srcY, s->linesize, 16);
+ else
+ s->hdsp.put_no_rnd_pixels_tab[0][dxy](s->dest[0], srcY, s->linesize, 16);
+ }
+
+ if (s->flags & CODEC_FLAG_GRAY) return;
+ /* Chroma MC always uses qpel bilinear */
+ uvmx = (uvmx & 3) << 1;
+ uvmy = (uvmy & 3) << 1;
+ if (!v->rnd) {
+ h264chroma->put_h264_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy);
+ h264chroma->put_h264_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy);
+ } else {
+ v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy);
+ v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy);
+ }
+}
+
+static inline int median4(int a, int b, int c, int d)
+{
+ if (a < b) {
+ if (c < d) return (FFMIN(b, d) + FFMAX(a, c)) / 2;
+ else return (FFMIN(b, c) + FFMAX(a, d)) / 2;
+ } else {
+ if (c < d) return (FFMIN(a, d) + FFMAX(b, c)) / 2;
+ else return (FFMIN(a, c) + FFMAX(b, d)) / 2;
+ }
+}
+
+/** Do motion compensation for 4-MV macroblock - luminance block
+ */
+void ff_vc1_mc_4mv_luma(VC1Context *v, int n, int dir, int avg)
+{
+ MpegEncContext *s = &v->s;
+ uint8_t *srcY;
+ int dxy, mx, my, src_x, src_y;
+ int off;
+ int fieldmv = (v->fcm == ILACE_FRAME) ? v->blk_mv_type[s->block_index[n]] : 0;
+ int v_edge_pos = s->v_edge_pos >> v->field_mode;
+ uint8_t (*luty)[256];
+ int use_ic;
+
+ if ((!v->field_mode ||
+ (v->ref_field_type[dir] == 1 && v->cur_field_type == 1)) &&
+ !v->s.last_picture.f->data[0])
+ return;
+
+ mx = s->mv[dir][n][0];
+ my = s->mv[dir][n][1];
+
+ if (!dir) {
+ if (v->field_mode && (v->cur_field_type != v->ref_field_type[dir]) && v->second_field) {
+ srcY = s->current_picture.f->data[0];
+ luty = v->curr_luty;
+ use_ic = *v->curr_use_ic;
+ } else {
+ srcY = s->last_picture.f->data[0];
+ luty = v->last_luty;
+ use_ic = v->last_use_ic;
+ }
+ } else {
+ srcY = s->next_picture.f->data[0];
+ luty = v->next_luty;
+ use_ic = v->next_use_ic;
+ }
+
+ if (!srcY) {
+ av_log(v->s.avctx, AV_LOG_ERROR, "Referenced frame missing.\n");
+ return;
+ }
+
+ if (v->field_mode) {
+ if (v->cur_field_type != v->ref_field_type[dir])
+ my = my - 2 + 4 * v->cur_field_type;
+ }
+
+ if (s->pict_type == AV_PICTURE_TYPE_P && n == 3 && v->field_mode) {
+ int same_count = 0, opp_count = 0, k;
+ int chosen_mv[2][4][2], f;
+ int tx, ty;
+ for (k = 0; k < 4; k++) {
+ f = v->mv_f[0][s->block_index[k] + v->blocks_off];
+ chosen_mv[f][f ? opp_count : same_count][0] = s->mv[0][k][0];
+ chosen_mv[f][f ? opp_count : same_count][1] = s->mv[0][k][1];
+ opp_count += f;
+ same_count += 1 - f;
+ }
+ f = opp_count > same_count;
+ switch (f ? opp_count : same_count) {
+ case 4:
+ tx = median4(chosen_mv[f][0][0], chosen_mv[f][1][0],
+ chosen_mv[f][2][0], chosen_mv[f][3][0]);
+ ty = median4(chosen_mv[f][0][1], chosen_mv[f][1][1],
+ chosen_mv[f][2][1], chosen_mv[f][3][1]);
+ break;
+ case 3:
+ tx = mid_pred(chosen_mv[f][0][0], chosen_mv[f][1][0], chosen_mv[f][2][0]);
+ ty = mid_pred(chosen_mv[f][0][1], chosen_mv[f][1][1], chosen_mv[f][2][1]);
+ break;
+ case 2:
+ tx = (chosen_mv[f][0][0] + chosen_mv[f][1][0]) / 2;
+ ty = (chosen_mv[f][0][1] + chosen_mv[f][1][1]) / 2;
+ break;
+ default:
+ av_assert0(0);
+ }
+ s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][0] = tx;
+ s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][1] = ty;
+ for (k = 0; k < 4; k++)
+ v->mv_f[1][s->block_index[k] + v->blocks_off] = f;
+ }
+
+ if (v->fcm == ILACE_FRAME) { // not sure if needed for other types of picture
+ int qx, qy;
+ int width = s->avctx->coded_width;
+ int height = s->avctx->coded_height >> 1;
+ if (s->pict_type == AV_PICTURE_TYPE_P) {
+ s->current_picture.motion_val[1][s->block_index[n] + v->blocks_off][0] = mx;
+ s->current_picture.motion_val[1][s->block_index[n] + v->blocks_off][1] = my;
+ }
+ qx = (s->mb_x * 16) + (mx >> 2);
+ qy = (s->mb_y * 8) + (my >> 3);
+
+ if (qx < -17)
+ mx -= 4 * (qx + 17);
+ else if (qx > width)
+ mx -= 4 * (qx - width);
+ if (qy < -18)
+ my -= 8 * (qy + 18);
+ else if (qy > height + 1)
+ my -= 8 * (qy - height - 1);
+ }
+
+ if ((v->fcm == ILACE_FRAME) && fieldmv)
+ off = ((n > 1) ? s->linesize : 0) + (n & 1) * 8;
+ else
+ off = s->linesize * 4 * (n & 2) + (n & 1) * 8;
+
+ src_x = s->mb_x * 16 + (n & 1) * 8 + (mx >> 2);
+ if (!fieldmv)
+ src_y = s->mb_y * 16 + (n & 2) * 4 + (my >> 2);
+ else
+ src_y = s->mb_y * 16 + ((n > 1) ? 1 : 0) + (my >> 2);
+
+ if (v->profile != PROFILE_ADVANCED) {
+ src_x = av_clip(src_x, -16, s->mb_width * 16);
+ src_y = av_clip(src_y, -16, s->mb_height * 16);
+ } else {
+ src_x = av_clip(src_x, -17, s->avctx->coded_width);
+ if (v->fcm == ILACE_FRAME) {
+ if (src_y & 1)
+ src_y = av_clip(src_y, -17, s->avctx->coded_height + 1);
+ else
+ src_y = av_clip(src_y, -18, s->avctx->coded_height);
+ } else {
+ src_y = av_clip(src_y, -18, s->avctx->coded_height + 1);
+ }
+ }
+
+ srcY += src_y * s->linesize + src_x;
+ if (v->field_mode && v->ref_field_type[dir])
+ srcY += s->current_picture_ptr->f->linesize[0];
+
+ if (fieldmv && !(src_y & 1))
+ v_edge_pos--;
+ if (fieldmv && (src_y & 1) && src_y < 4)
+ src_y--;
+ if (v->rangeredfrm || use_ic
+ || s->h_edge_pos < 13 || v_edge_pos < 23
+ || (unsigned)(src_x - s->mspel) > s->h_edge_pos - (mx & 3) - 8 - s->mspel * 2
+ || (unsigned)(src_y - (s->mspel << fieldmv)) > v_edge_pos - (my & 3) - ((8 + s->mspel * 2) << fieldmv)) {
+ srcY -= s->mspel * (1 + (s->linesize << fieldmv));
+ /* check emulate edge stride and offset */
+ s->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);
+ srcY = s->edge_emu_buffer;
+ /* if we deal with range reduction we need to scale source blocks */
+ if (v->rangeredfrm) {
+ int i, j;
+ uint8_t *src;
+
+ src = srcY;
+ for (j = 0; j < 9 + s->mspel * 2; j++) {
+ for (i = 0; i < 9 + s->mspel * 2; i++)
+ src[i] = ((src[i] - 128) >> 1) + 128;
+ src += s->linesize << fieldmv;
+ }
+ }
+ /* if we deal with intensity compensation we need to scale source blocks */
+ if (use_ic) {
+ int i, j;
+ uint8_t *src;
+
+ src = srcY;
+ for (j = 0; j < 9 + s->mspel * 2; j++) {
+ int f = v->field_mode ? v->ref_field_type[dir] : (((j<<fieldmv)+src_y - (s->mspel << fieldmv)) & 1);
+ for (i = 0; i < 9 + s->mspel * 2; i++)
+ src[i] = luty[f][src[i]];
+ src += s->linesize << fieldmv;
+ }
+ }
+ srcY += s->mspel * (1 + (s->linesize << fieldmv));
+ }
+
+ if (s->mspel) {
+ dxy = ((my & 3) << 2) | (mx & 3);
+ if (avg)
+ v->vc1dsp.avg_vc1_mspel_pixels_tab[1][dxy](s->dest[0] + off, srcY, s->linesize << fieldmv, v->rnd);
+ else
+ v->vc1dsp.put_vc1_mspel_pixels_tab[1][dxy](s->dest[0] + off, srcY, s->linesize << fieldmv, v->rnd);
+ } else { // hpel mc - always used for luma
+ dxy = (my & 2) | ((mx & 2) >> 1);
+ if (!v->rnd)
+ s->hdsp.put_pixels_tab[1][dxy](s->dest[0] + off, srcY, s->linesize, 8);
+ else
+ s->hdsp.put_no_rnd_pixels_tab[1][dxy](s->dest[0] + off, srcY, s->linesize, 8);
+ }
+}
+
+static av_always_inline int get_chroma_mv(int *mvx, int *mvy, int *a, int flag, int *tx, int *ty)
+{
+ int idx, i;
+ static const int count[16] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4};
+
+ idx = ((a[3] != flag) << 3)
+ | ((a[2] != flag) << 2)
+ | ((a[1] != flag) << 1)
+ | (a[0] != flag);
+ if (!idx) {
+ *tx = median4(mvx[0], mvx[1], mvx[2], mvx[3]);
+ *ty = median4(mvy[0], mvy[1], mvy[2], mvy[3]);
+ return 4;
+ } else if (count[idx] == 1) {
+ switch (idx) {
+ case 0x1:
+ *tx = mid_pred(mvx[1], mvx[2], mvx[3]);
+ *ty = mid_pred(mvy[1], mvy[2], mvy[3]);
+ return 3;
+ case 0x2:
+ *tx = mid_pred(mvx[0], mvx[2], mvx[3]);
+ *ty = mid_pred(mvy[0], mvy[2], mvy[3]);
+ return 3;
+ case 0x4:
+ *tx = mid_pred(mvx[0], mvx[1], mvx[3]);
+ *ty = mid_pred(mvy[0], mvy[1], mvy[3]);
+ return 3;
+ case 0x8:
+ *tx = mid_pred(mvx[0], mvx[1], mvx[2]);
+ *ty = mid_pred(mvy[0], mvy[1], mvy[2]);
+ return 3;
+ }
+ } else if (count[idx] == 2) {
+ int t1 = 0, t2 = 0;
+ for (i = 0; i < 3; i++)
+ if (!a[i]) {
+ t1 = i;
+ break;
+ }
+ for (i = t1 + 1; i < 4; i++)
+ if (!a[i]) {
+ t2 = i;
+ break;
+ }
+ *tx = (mvx[t1] + mvx[t2]) / 2;
+ *ty = (mvy[t1] + mvy[t2]) / 2;
+ return 2;
+ } else {
+ return 0;
+ }
+ return -1;
+}
+
+/** Do motion compensation for 4-MV macroblock - both chroma blocks
+ */
+void ff_vc1_mc_4mv_chroma(VC1Context *v, int dir)
+{
+ MpegEncContext *s = &v->s;
+ H264ChromaContext *h264chroma = &v->h264chroma;
+ uint8_t *srcU, *srcV;
+ int uvmx, uvmy, uvsrc_x, uvsrc_y;
+ int k, tx = 0, ty = 0;
+ int mvx[4], mvy[4], intra[4], mv_f[4];
+ int valid_count;
+ int chroma_ref_type = v->cur_field_type;
+ int v_edge_pos = s->v_edge_pos >> v->field_mode;
+ uint8_t (*lutuv)[256];
+ int use_ic;
+
+ if (!v->field_mode && !v->s.last_picture.f->data[0])
+ return;
+ if (s->flags & CODEC_FLAG_GRAY)
+ return;
+
+ for (k = 0; k < 4; k++) {
+ mvx[k] = s->mv[dir][k][0];
+ mvy[k] = s->mv[dir][k][1];
+ intra[k] = v->mb_type[0][s->block_index[k]];
+ if (v->field_mode)
+ mv_f[k] = v->mv_f[dir][s->block_index[k] + v->blocks_off];
+ }
+
+ /* calculate chroma MV vector from four luma MVs */
+ if (!v->field_mode || (v->field_mode && !v->numref)) {
+ valid_count = get_chroma_mv(mvx, mvy, intra, 0, &tx, &ty);
+ chroma_ref_type = v->reffield;
+ if (!valid_count) {
+ s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][0] = 0;
+ s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][1] = 0;
+ v->luma_mv[s->mb_x][0] = v->luma_mv[s->mb_x][1] = 0;
+ return; //no need to do MC for intra blocks
+ }
+ } else {
+ int dominant = 0;
+ if (mv_f[0] + mv_f[1] + mv_f[2] + mv_f[3] > 2)
+ dominant = 1;
+ valid_count = get_chroma_mv(mvx, mvy, mv_f, dominant, &tx, &ty);
+ if (dominant)
+ chroma_ref_type = !v->cur_field_type;
+ }
+ if (v->field_mode && chroma_ref_type == 1 && v->cur_field_type == 1 && !v->s.last_picture.f->data[0])
+ return;
+ s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][0] = tx;
+ s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][1] = ty;
+ uvmx = (tx + ((tx & 3) == 3)) >> 1;
+ uvmy = (ty + ((ty & 3) == 3)) >> 1;
+
+ v->luma_mv[s->mb_x][0] = uvmx;
+ v->luma_mv[s->mb_x][1] = uvmy;
+
+ if (v->fastuvmc) {
+ uvmx = uvmx + ((uvmx < 0) ? (uvmx & 1) : -(uvmx & 1));
+ uvmy = uvmy + ((uvmy < 0) ? (uvmy & 1) : -(uvmy & 1));
+ }
+ // Field conversion bias
+ if (v->cur_field_type != chroma_ref_type)
+ uvmy += 2 - 4 * chroma_ref_type;
+
+ uvsrc_x = s->mb_x * 8 + (uvmx >> 2);
+ uvsrc_y = s->mb_y * 8 + (uvmy >> 2);
+
+ if (v->profile != PROFILE_ADVANCED) {
+ uvsrc_x = av_clip(uvsrc_x, -8, s->mb_width * 8);
+ uvsrc_y = av_clip(uvsrc_y, -8, s->mb_height * 8);
+ } else {
+ uvsrc_x = av_clip(uvsrc_x, -8, s->avctx->coded_width >> 1);
+ uvsrc_y = av_clip(uvsrc_y, -8, s->avctx->coded_height >> 1);
+ }
+
+ if (!dir) {
+ if (v->field_mode && (v->cur_field_type != chroma_ref_type) && v->second_field) {
+ srcU = s->current_picture.f->data[1];
+ srcV = s->current_picture.f->data[2];
+ lutuv = v->curr_lutuv;
+ use_ic = *v->curr_use_ic;
+ } else {
+ srcU = s->last_picture.f->data[1];
+ srcV = s->last_picture.f->data[2];
+ lutuv = v->last_lutuv;
+ use_ic = v->last_use_ic;
+ }
+ } else {
+ srcU = s->next_picture.f->data[1];
+ srcV = s->next_picture.f->data[2];
+ lutuv = v->next_lutuv;
+ use_ic = v->next_use_ic;
+ }
+
+ if (!srcU) {
+ av_log(v->s.avctx, AV_LOG_ERROR, "Referenced frame missing.\n");
+ return;
+ }
+
+ srcU += uvsrc_y * s->uvlinesize + uvsrc_x;
+ srcV += uvsrc_y * s->uvlinesize + uvsrc_x;
+
+ if (v->field_mode) {
+ if (chroma_ref_type) {
+ srcU += s->current_picture_ptr->f->linesize[1];
+ srcV += s->current_picture_ptr->f->linesize[2];
+ }
+ }
+
+ if (v->rangeredfrm || use_ic
+ || 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, 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, 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;
+
+ /* if we deal with range reduction we need to scale source blocks */
+ if (v->rangeredfrm) {
+ int i, j;
+ uint8_t *src, *src2;
+
+ src = srcU;
+ src2 = srcV;
+ for (j = 0; j < 9; j++) {
+ for (i = 0; i < 9; i++) {
+ src[i] = ((src[i] - 128) >> 1) + 128;
+ src2[i] = ((src2[i] - 128) >> 1) + 128;
+ }
+ src += s->uvlinesize;
+ src2 += s->uvlinesize;
+ }
+ }
+ /* if we deal with intensity compensation we need to scale source blocks */
+ if (use_ic) {
+ int i, j;
+ uint8_t *src, *src2;
+
+ src = srcU;
+ src2 = srcV;
+ for (j = 0; j < 9; j++) {
+ int f = v->field_mode ? chroma_ref_type : ((j + uvsrc_y) & 1);
+ for (i = 0; i < 9; i++) {
+ src[i] = lutuv[f][src[i]];
+ src2[i] = lutuv[f][src2[i]];
+ }
+ src += s->uvlinesize;
+ src2 += s->uvlinesize;
+ }
+ }
+ }
+
+ /* Chroma MC always uses qpel bilinear */
+ uvmx = (uvmx & 3) << 1;
+ uvmy = (uvmy & 3) << 1;
+ if (!v->rnd) {
+ h264chroma->put_h264_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy);
+ h264chroma->put_h264_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy);
+ } else {
+ v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy);
+ v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy);
+ }
+}
+
+/** Do motion compensation for 4-MV interlaced frame chroma macroblock (both U and V)
+ */
+void ff_vc1_mc_4mv_chroma4(VC1Context *v, int dir, int dir2, int avg)
+{
+ MpegEncContext *s = &v->s;
+ H264ChromaContext *h264chroma = &v->h264chroma;
+ uint8_t *srcU, *srcV;
+ int uvsrc_x, uvsrc_y;
+ int uvmx_field[4], uvmy_field[4];
+ int i, off, tx, ty;
+ int fieldmv = v->blk_mv_type[s->block_index[0]];
+ static const int s_rndtblfield[16] = { 0, 0, 1, 2, 4, 4, 5, 6, 2, 2, 3, 8, 6, 6, 7, 12 };
+ int v_dist = fieldmv ? 1 : 4; // vertical offset for lower sub-blocks
+ int v_edge_pos = s->v_edge_pos >> 1;
+ int use_ic;
+ uint8_t (*lutuv)[256];
+
+ if (s->flags & CODEC_FLAG_GRAY)
+ return;
+
+ for (i = 0; i < 4; i++) {
+ int d = i < 2 ? dir: dir2;
+ tx = s->mv[d][i][0];
+ uvmx_field[i] = (tx + ((tx & 3) == 3)) >> 1;
+ ty = s->mv[d][i][1];
+ if (fieldmv)
+ uvmy_field[i] = (ty >> 4) * 8 + s_rndtblfield[ty & 0xF];
+ else
+ uvmy_field[i] = (ty + ((ty & 3) == 3)) >> 1;
+ }
+
+ for (i = 0; i < 4; i++) {
+ off = (i & 1) * 4 + ((i & 2) ? v_dist * s->uvlinesize : 0);
+ uvsrc_x = s->mb_x * 8 + (i & 1) * 4 + (uvmx_field[i] >> 2);
+ uvsrc_y = s->mb_y * 8 + ((i & 2) ? v_dist : 0) + (uvmy_field[i] >> 2);
+ // FIXME: implement proper pull-back (see vc1cropmv.c, vc1CROPMV_ChromaPullBack())
+ uvsrc_x = av_clip(uvsrc_x, -8, s->avctx->coded_width >> 1);
+ uvsrc_y = av_clip(uvsrc_y, -8, s->avctx->coded_height >> 1);
+ if (i < 2 ? dir : dir2) {
+ srcU = s->next_picture.f->data[1];
+ srcV = s->next_picture.f->data[2];
+ lutuv = v->next_lutuv;
+ use_ic = v->next_use_ic;
+ } else {
+ srcU = s->last_picture.f->data[1];
+ srcV = s->last_picture.f->data[2];
+ lutuv = v->last_lutuv;
+ use_ic = v->last_use_ic;
+ }
+ if (!srcU)
+ return;
+ srcU += uvsrc_y * s->uvlinesize + uvsrc_x;
+ srcV += uvsrc_y * s->uvlinesize + uvsrc_x;
+ uvmx_field[i] = (uvmx_field[i] & 3) << 1;
+ uvmy_field[i] = (uvmy_field[i] & 3) << 1;
+
+ if (fieldmv && !(uvsrc_y & 1))
+ v_edge_pos = (s->v_edge_pos >> 1) - 1;
+
+ if (fieldmv && (uvsrc_y & 1) && uvsrc_y < 2)
+ uvsrc_y--;
+ if (use_ic
+ || 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, 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;
+
+ /* if we deal with intensity compensation we need to scale source blocks */
+ if (use_ic) {
+ int i, j;
+ uint8_t *src, *src2;
+
+ src = srcU;
+ src2 = srcV;
+ for (j = 0; j < 5; j++) {
+ int f = (uvsrc_y + (j << fieldmv)) & 1;
+ for (i = 0; i < 5; i++) {
+ src[i] = lutuv[f][src[i]];
+ src2[i] = lutuv[f][src2[i]];
+ }
+ src += s->uvlinesize << fieldmv;
+ src2 += s->uvlinesize << fieldmv;
+ }
+ }
+ }
+ if (avg) {
+ if (!v->rnd) {
+ h264chroma->avg_h264_chroma_pixels_tab[1](s->dest[1] + off, srcU, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
+ h264chroma->avg_h264_chroma_pixels_tab[1](s->dest[2] + off, srcV, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
+ } else {
+ v->vc1dsp.avg_no_rnd_vc1_chroma_pixels_tab[1](s->dest[1] + off, srcU, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
+ v->vc1dsp.avg_no_rnd_vc1_chroma_pixels_tab[1](s->dest[2] + off, srcV, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
+ }
+ } else {
+ if (!v->rnd) {
+ h264chroma->put_h264_chroma_pixels_tab[1](s->dest[1] + off, srcU, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
+ h264chroma->put_h264_chroma_pixels_tab[1](s->dest[2] + off, srcV, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
+ } else {
+ v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[1](s->dest[1] + off, srcU, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
+ v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[1](s->dest[2] + off, srcV, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
+ }
+ }
+ }
+}
+
+/** Motion compensation for direct or interpolated blocks in B-frames
+ */
+void ff_vc1_interp_mc(VC1Context *v)
+{
+ MpegEncContext *s = &v->s;
+ H264ChromaContext *h264chroma = &v->h264chroma;
+ uint8_t *srcY, *srcU, *srcV;
+ int dxy, mx, my, uvmx, uvmy, src_x, src_y, uvsrc_x, uvsrc_y;
+ int off, off_uv;
+ int v_edge_pos = s->v_edge_pos >> v->field_mode;
+ int use_ic = v->next_use_ic;
+
+ if (!v->field_mode && !v->s.next_picture.f->data[0])
+ return;
+
+ mx = s->mv[1][0][0];
+ my = s->mv[1][0][1];
+ uvmx = (mx + ((mx & 3) == 3)) >> 1;
+ uvmy = (my + ((my & 3) == 3)) >> 1;
+ if (v->field_mode && v->cur_field_type != v->ref_field_type[1]) {
+ my = my - 2 + 4 * v->cur_field_type;
+ uvmy = uvmy - 2 + 4 * v->cur_field_type;
+ }
+ if (v->fastuvmc) {
+ uvmx = uvmx + ((uvmx < 0) ? -(uvmx & 1) : (uvmx & 1));
+ uvmy = uvmy + ((uvmy < 0) ? -(uvmy & 1) : (uvmy & 1));
+ }
+ srcY = s->next_picture.f->data[0];
+ srcU = s->next_picture.f->data[1];
+ srcV = s->next_picture.f->data[2];
+
+ src_x = s->mb_x * 16 + (mx >> 2);
+ src_y = s->mb_y * 16 + (my >> 2);
+ uvsrc_x = s->mb_x * 8 + (uvmx >> 2);
+ uvsrc_y = s->mb_y * 8 + (uvmy >> 2);
+
+ if (v->profile != PROFILE_ADVANCED) {
+ src_x = av_clip( src_x, -16, s->mb_width * 16);
+ src_y = av_clip( src_y, -16, s->mb_height * 16);
+ uvsrc_x = av_clip(uvsrc_x, -8, s->mb_width * 8);
+ uvsrc_y = av_clip(uvsrc_y, -8, s->mb_height * 8);
+ } else {
+ src_x = av_clip( src_x, -17, s->avctx->coded_width);
+ src_y = av_clip( src_y, -18, s->avctx->coded_height + 1);
+ uvsrc_x = av_clip(uvsrc_x, -8, s->avctx->coded_width >> 1);
+ uvsrc_y = av_clip(uvsrc_y, -8, s->avctx->coded_height >> 1);
+ }
+
+ srcY += src_y * s->linesize + src_x;
+ srcU += uvsrc_y * s->uvlinesize + uvsrc_x;
+ srcV += uvsrc_y * s->uvlinesize + uvsrc_x;
+
+ if (v->field_mode && v->ref_field_type[1]) {
+ srcY += s->current_picture_ptr->f->linesize[0];
+ srcU += s->current_picture_ptr->f->linesize[1];
+ srcV += s->current_picture_ptr->f->linesize[2];
+ }
+
+ /* for grayscale we should not try to read from unknown area */
+ if (s->flags & CODEC_FLAG_GRAY) {
+ srcU = s->edge_emu_buffer + 18 * s->linesize;
+ srcV = s->edge_emu_buffer + 18 * s->linesize;
+ }
+
+ if (v->rangeredfrm || s->h_edge_pos < 22 || v_edge_pos < 22 || use_ic
+ || (unsigned)(src_x - 1) > s->h_edge_pos - (mx & 3) - 16 - 3
+ || (unsigned)(src_y - 1) > v_edge_pos - (my & 3) - 16 - 3) {
+ uint8_t *ubuf = s->edge_emu_buffer + 19 * s->linesize;
+ uint8_t *vbuf = ubuf + 9 * s->uvlinesize;
+
+ srcY -= s->mspel * (1 + 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(ubuf, 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(vbuf, srcV,
+ s->uvlinesize, s->uvlinesize,
+ 8 + 1, 8 + 1,
+ uvsrc_x, uvsrc_y,
+ s->h_edge_pos >> 1, v_edge_pos >> 1);
+ srcU = ubuf;
+ srcV = vbuf;
+ /* if we deal with range reduction we need to scale source blocks */
+ if (v->rangeredfrm) {
+ int i, j;
+ uint8_t *src, *src2;
+
+ src = srcY;
+ for (j = 0; j < 17 + s->mspel * 2; j++) {
+ for (i = 0; i < 17 + s->mspel * 2; i++)
+ src[i] = ((src[i] - 128) >> 1) + 128;
+ src += s->linesize;
+ }
+ src = srcU;
+ src2 = srcV;
+ for (j = 0; j < 9; j++) {
+ for (i = 0; i < 9; i++) {
+ src[i] = ((src[i] - 128) >> 1) + 128;
+ src2[i] = ((src2[i] - 128) >> 1) + 128;
+ }
+ src += s->uvlinesize;
+ src2 += s->uvlinesize;
+ }
+ }
+
+ if (use_ic) {
+ uint8_t (*luty )[256] = v->next_luty;
+ uint8_t (*lutuv)[256] = v->next_lutuv;
+ int i, j;
+ uint8_t *src, *src2;
+
+ src = srcY;
+ for (j = 0; j < 17 + s->mspel * 2; j++) {
+ int f = v->field_mode ? v->ref_field_type[1] : ((j+src_y - s->mspel) & 1);
+ for (i = 0; i < 17 + s->mspel * 2; i++)
+ src[i] = luty[f][src[i]];
+ src += s->linesize;
+ }
+ src = srcU;
+ src2 = srcV;
+ for (j = 0; j < 9; j++) {
+ int f = v->field_mode ? v->ref_field_type[1] : ((j+uvsrc_y) & 1);
+ for (i = 0; i < 9; i++) {
+ src[i] = lutuv[f][src[i]];
+ src2[i] = lutuv[f][src2[i]];
+ }
+ src += s->uvlinesize;
+ src2 += s->uvlinesize;
+ }
+ }
+ srcY += s->mspel * (1 + s->linesize);
+ }
+
+ off = 0;
+ off_uv = 0;
+
+ if (s->mspel) {
+ dxy = ((my & 3) << 2) | (mx & 3);
+ v->vc1dsp.avg_vc1_mspel_pixels_tab[0][dxy](s->dest[0] + off , srcY , s->linesize, v->rnd);
+ } else { // hpel mc
+ dxy = (my & 2) | ((mx & 2) >> 1);
+
+ if (!v->rnd)
+ s->hdsp.avg_pixels_tab[0][dxy](s->dest[0] + off, srcY, s->linesize, 16);
+ else
+ s->hdsp.avg_no_rnd_pixels_tab[dxy](s->dest[0] + off, srcY, s->linesize, 16);
+ }
+
+ if (s->flags & CODEC_FLAG_GRAY) return;
+ /* Chroma MC always uses qpel blilinear */
+ uvmx = (uvmx & 3) << 1;
+ uvmy = (uvmy & 3) << 1;
+ if (!v->rnd) {
+ h264chroma->avg_h264_chroma_pixels_tab[0](s->dest[1] + off_uv, srcU, s->uvlinesize, 8, uvmx, uvmy);
+ h264chroma->avg_h264_chroma_pixels_tab[0](s->dest[2] + off_uv, srcV, s->uvlinesize, 8, uvmx, uvmy);
+ } else {
+ v->vc1dsp.avg_no_rnd_vc1_chroma_pixels_tab[0](s->dest[1] + off_uv, srcU, s->uvlinesize, 8, uvmx, uvmy);
+ v->vc1dsp.avg_no_rnd_vc1_chroma_pixels_tab[0](s->dest[2] + off_uv, srcV, s->uvlinesize, 8, uvmx, uvmy);
+ }
+}
break;
}
+ if (avctx->framerate.num)
+ avctx->time_base = av_inv_q(av_mul_q(avctx->framerate, (AVRational){avctx->ticks_per_frame, 1}));
}
static int vc1_parse(AVCodecParserContext *s,
--- /dev/null
+/*
+ * VC-1 and WMV3 decoder
+ * Copyright (c) 2011 Mashiat Sarker Shakkhar
+ * Copyright (c) 2006-2007 Konstantin Shishkov
+ * Partly based on vc9.c (c) 2005 Anonymous, Alex Beregszaszi, Michael Niedermayer
+ *
+ * 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
+ * VC-1 and WMV3 block decoding routines
+ */
+
+#include "mathops.h"
+#include "mpegutils.h"
+#include "mpegvideo.h"
+#include "vc1.h"
+#include "vc1_pred.h"
+#include "vc1data.h"
+
+static av_always_inline int scaleforsame_x(VC1Context *v, int n /* MV */, int dir)
+{
+ int scaledvalue, refdist;
+ int scalesame1, scalesame2;
+ int scalezone1_x, zone1offset_x;
+ int table_index = dir ^ v->second_field;
+
+ if (v->s.pict_type != AV_PICTURE_TYPE_B)
+ refdist = v->refdist;
+ else
+ refdist = dir ? v->brfd : v->frfd;
+ if (refdist > 3)
+ refdist = 3;
+ scalesame1 = ff_vc1_field_mvpred_scales[table_index][1][refdist];
+ scalesame2 = ff_vc1_field_mvpred_scales[table_index][2][refdist];
+ scalezone1_x = ff_vc1_field_mvpred_scales[table_index][3][refdist];
+ zone1offset_x = ff_vc1_field_mvpred_scales[table_index][5][refdist];
+
+ if (FFABS(n) > 255)
+ scaledvalue = n;
+ else {
+ if (FFABS(n) < scalezone1_x)
+ scaledvalue = (n * scalesame1) >> 8;
+ else {
+ if (n < 0)
+ scaledvalue = ((n * scalesame2) >> 8) - zone1offset_x;
+ else
+ scaledvalue = ((n * scalesame2) >> 8) + zone1offset_x;
+ }
+ }
+ return av_clip(scaledvalue, -v->range_x, v->range_x - 1);
+}
+
+static av_always_inline int scaleforsame_y(VC1Context *v, int i, int n /* MV */, int dir)
+{
+ int scaledvalue, refdist;
+ int scalesame1, scalesame2;
+ int scalezone1_y, zone1offset_y;
+ int table_index = dir ^ v->second_field;
+
+ if (v->s.pict_type != AV_PICTURE_TYPE_B)
+ refdist = v->refdist;
+ else
+ refdist = dir ? v->brfd : v->frfd;
+ if (refdist > 3)
+ refdist = 3;
+ scalesame1 = ff_vc1_field_mvpred_scales[table_index][1][refdist];
+ scalesame2 = ff_vc1_field_mvpred_scales[table_index][2][refdist];
+ scalezone1_y = ff_vc1_field_mvpred_scales[table_index][4][refdist];
+ zone1offset_y = ff_vc1_field_mvpred_scales[table_index][6][refdist];
+
+ if (FFABS(n) > 63)
+ scaledvalue = n;
+ else {
+ if (FFABS(n) < scalezone1_y)
+ scaledvalue = (n * scalesame1) >> 8;
+ else {
+ if (n < 0)
+ scaledvalue = ((n * scalesame2) >> 8) - zone1offset_y;
+ else
+ scaledvalue = ((n * scalesame2) >> 8) + zone1offset_y;
+ }
+ }
+
+ if (v->cur_field_type && !v->ref_field_type[dir])
+ return av_clip(scaledvalue, -v->range_y / 2 + 1, v->range_y / 2);
+ else
+ return av_clip(scaledvalue, -v->range_y / 2, v->range_y / 2 - 1);
+}
+
+static av_always_inline int scaleforopp_x(VC1Context *v, int n /* MV */)
+{
+ int scalezone1_x, zone1offset_x;
+ int scaleopp1, scaleopp2, brfd;
+ int scaledvalue;
+
+ brfd = FFMIN(v->brfd, 3);
+ scalezone1_x = ff_vc1_b_field_mvpred_scales[3][brfd];
+ zone1offset_x = ff_vc1_b_field_mvpred_scales[5][brfd];
+ scaleopp1 = ff_vc1_b_field_mvpred_scales[1][brfd];
+ scaleopp2 = ff_vc1_b_field_mvpred_scales[2][brfd];
+
+ if (FFABS(n) > 255)
+ scaledvalue = n;
+ else {
+ if (FFABS(n) < scalezone1_x)
+ scaledvalue = (n * scaleopp1) >> 8;
+ else {
+ if (n < 0)
+ scaledvalue = ((n * scaleopp2) >> 8) - zone1offset_x;
+ else
+ scaledvalue = ((n * scaleopp2) >> 8) + zone1offset_x;
+ }
+ }
+ return av_clip(scaledvalue, -v->range_x, v->range_x - 1);
+}
+
+static av_always_inline int scaleforopp_y(VC1Context *v, int n /* MV */, int dir)
+{
+ int scalezone1_y, zone1offset_y;
+ int scaleopp1, scaleopp2, brfd;
+ int scaledvalue;
+
+ brfd = FFMIN(v->brfd, 3);
+ scalezone1_y = ff_vc1_b_field_mvpred_scales[4][brfd];
+ zone1offset_y = ff_vc1_b_field_mvpred_scales[6][brfd];
+ scaleopp1 = ff_vc1_b_field_mvpred_scales[1][brfd];
+ scaleopp2 = ff_vc1_b_field_mvpred_scales[2][brfd];
+
+ if (FFABS(n) > 63)
+ scaledvalue = n;
+ else {
+ if (FFABS(n) < scalezone1_y)
+ scaledvalue = (n * scaleopp1) >> 8;
+ else {
+ if (n < 0)
+ scaledvalue = ((n * scaleopp2) >> 8) - zone1offset_y;
+ else
+ scaledvalue = ((n * scaleopp2) >> 8) + zone1offset_y;
+ }
+ }
+ if (v->cur_field_type && !v->ref_field_type[dir]) {
+ return av_clip(scaledvalue, -v->range_y / 2 + 1, v->range_y / 2);
+ } else {
+ return av_clip(scaledvalue, -v->range_y / 2, v->range_y / 2 - 1);
+ }
+}
+
+static av_always_inline int scaleforsame(VC1Context *v, int i, int n /* MV */,
+ int dim, int dir)
+{
+ int brfd, scalesame;
+ int hpel = 1 - v->s.quarter_sample;
+
+ n >>= hpel;
+ if (v->s.pict_type != AV_PICTURE_TYPE_B || v->second_field || !dir) {
+ if (dim)
+ n = scaleforsame_y(v, i, n, dir) << hpel;
+ else
+ n = scaleforsame_x(v, n, dir) << hpel;
+ return n;
+ }
+ brfd = FFMIN(v->brfd, 3);
+ scalesame = ff_vc1_b_field_mvpred_scales[0][brfd];
+
+ n = (n * scalesame >> 8) << hpel;
+ return n;
+}
+
+static av_always_inline int scaleforopp(VC1Context *v, int n /* MV */,
+ int dim, int dir)
+{
+ int refdist, scaleopp;
+ int hpel = 1 - v->s.quarter_sample;
+
+ n >>= hpel;
+ if (v->s.pict_type == AV_PICTURE_TYPE_B && !v->second_field && dir == 1) {
+ if (dim)
+ n = scaleforopp_y(v, n, dir) << hpel;
+ else
+ n = scaleforopp_x(v, n) << hpel;
+ return n;
+ }
+ if (v->s.pict_type != AV_PICTURE_TYPE_B)
+ refdist = FFMIN(v->refdist, 3);
+ else
+ refdist = dir ? v->brfd : v->frfd;
+ scaleopp = ff_vc1_field_mvpred_scales[dir ^ v->second_field][0][refdist];
+
+ n = (n * scaleopp >> 8) << hpel;
+ return n;
+}
+
+/** Predict and set motion vector
+ */
+void ff_vc1_pred_mv(VC1Context *v, int n, int dmv_x, int dmv_y,
+ int mv1, int r_x, int r_y, uint8_t* is_intra,
+ int pred_flag, int dir)
+{
+ MpegEncContext *s = &v->s;
+ int xy, wrap, off = 0;
+ int16_t *A, *B, *C;
+ int px, py;
+ int sum;
+ int mixedmv_pic, num_samefield = 0, num_oppfield = 0;
+ int opposite, a_f, b_f, c_f;
+ int16_t field_predA[2];
+ int16_t field_predB[2];
+ int16_t field_predC[2];
+ int a_valid, b_valid, c_valid;
+ int hybridmv_thresh, y_bias = 0;
+
+ if (v->mv_mode == MV_PMODE_MIXED_MV ||
+ ((v->mv_mode == MV_PMODE_INTENSITY_COMP) && (v->mv_mode2 == MV_PMODE_MIXED_MV)))
+ mixedmv_pic = 1;
+ else
+ mixedmv_pic = 0;
+ /* scale MV difference to be quad-pel */
+ dmv_x <<= 1 - s->quarter_sample;
+ dmv_y <<= 1 - s->quarter_sample;
+
+ wrap = s->b8_stride;
+ xy = s->block_index[n];
+
+ if (s->mb_intra) {
+ s->mv[0][n][0] = s->current_picture.motion_val[0][xy + v->blocks_off][0] = 0;
+ s->mv[0][n][1] = s->current_picture.motion_val[0][xy + v->blocks_off][1] = 0;
+ s->current_picture.motion_val[1][xy + v->blocks_off][0] = 0;
+ s->current_picture.motion_val[1][xy + v->blocks_off][1] = 0;
+ if (mv1) { /* duplicate motion data for 1-MV block */
+ s->current_picture.motion_val[0][xy + 1 + v->blocks_off][0] = 0;
+ s->current_picture.motion_val[0][xy + 1 + v->blocks_off][1] = 0;
+ s->current_picture.motion_val[0][xy + wrap + v->blocks_off][0] = 0;
+ s->current_picture.motion_val[0][xy + wrap + v->blocks_off][1] = 0;
+ s->current_picture.motion_val[0][xy + wrap + 1 + v->blocks_off][0] = 0;
+ s->current_picture.motion_val[0][xy + wrap + 1 + v->blocks_off][1] = 0;
+ v->luma_mv[s->mb_x][0] = v->luma_mv[s->mb_x][1] = 0;
+ s->current_picture.motion_val[1][xy + 1 + v->blocks_off][0] = 0;
+ s->current_picture.motion_val[1][xy + 1 + v->blocks_off][1] = 0;
+ s->current_picture.motion_val[1][xy + wrap][0] = 0;
+ s->current_picture.motion_val[1][xy + wrap + v->blocks_off][1] = 0;
+ s->current_picture.motion_val[1][xy + wrap + 1 + v->blocks_off][0] = 0;
+ s->current_picture.motion_val[1][xy + wrap + 1 + v->blocks_off][1] = 0;
+ }
+ return;
+ }
+
+ C = s->current_picture.motion_val[dir][xy - 1 + v->blocks_off];
+ A = s->current_picture.motion_val[dir][xy - wrap + v->blocks_off];
+ if (mv1) {
+ if (v->field_mode && mixedmv_pic)
+ off = (s->mb_x == (s->mb_width - 1)) ? -2 : 2;
+ else
+ off = (s->mb_x == (s->mb_width - 1)) ? -1 : 2;
+ } else {
+ //in 4-MV mode different blocks have different B predictor position
+ switch (n) {
+ case 0:
+ off = (s->mb_x > 0) ? -1 : 1;
+ break;
+ case 1:
+ off = (s->mb_x == (s->mb_width - 1)) ? -1 : 1;
+ break;
+ case 2:
+ off = 1;
+ break;
+ case 3:
+ off = -1;
+ }
+ }
+ B = s->current_picture.motion_val[dir][xy - wrap + off + v->blocks_off];
+
+ a_valid = !s->first_slice_line || (n == 2 || n == 3);
+ b_valid = a_valid && (s->mb_width > 1);
+ c_valid = s->mb_x || (n == 1 || n == 3);
+ if (v->field_mode) {
+ a_valid = a_valid && !is_intra[xy - wrap];
+ b_valid = b_valid && !is_intra[xy - wrap + off];
+ c_valid = c_valid && !is_intra[xy - 1];
+ }
+
+ if (a_valid) {
+ a_f = v->mv_f[dir][xy - wrap + v->blocks_off];
+ num_oppfield += a_f;
+ num_samefield += 1 - a_f;
+ field_predA[0] = A[0];
+ field_predA[1] = A[1];
+ } else {
+ field_predA[0] = field_predA[1] = 0;
+ a_f = 0;
+ }
+ if (b_valid) {
+ b_f = v->mv_f[dir][xy - wrap + off + v->blocks_off];
+ num_oppfield += b_f;
+ num_samefield += 1 - b_f;
+ field_predB[0] = B[0];
+ field_predB[1] = B[1];
+ } else {
+ field_predB[0] = field_predB[1] = 0;
+ b_f = 0;
+ }
+ if (c_valid) {
+ c_f = v->mv_f[dir][xy - 1 + v->blocks_off];
+ num_oppfield += c_f;
+ num_samefield += 1 - c_f;
+ field_predC[0] = C[0];
+ field_predC[1] = C[1];
+ } else {
+ field_predC[0] = field_predC[1] = 0;
+ c_f = 0;
+ }
+
+ if (v->field_mode) {
+ if (!v->numref)
+ // REFFIELD determines if the last field or the second-last field is
+ // to be used as reference
+ opposite = 1 - v->reffield;
+ else {
+ if (num_samefield <= num_oppfield)
+ opposite = 1 - pred_flag;
+ else
+ opposite = pred_flag;
+ }
+ } else
+ opposite = 0;
+ if (opposite) {
+ if (a_valid && !a_f) {
+ field_predA[0] = scaleforopp(v, field_predA[0], 0, dir);
+ field_predA[1] = scaleforopp(v, field_predA[1], 1, dir);
+ }
+ if (b_valid && !b_f) {
+ field_predB[0] = scaleforopp(v, field_predB[0], 0, dir);
+ field_predB[1] = scaleforopp(v, field_predB[1], 1, dir);
+ }
+ if (c_valid && !c_f) {
+ field_predC[0] = scaleforopp(v, field_predC[0], 0, dir);
+ field_predC[1] = scaleforopp(v, field_predC[1], 1, dir);
+ }
+ v->mv_f[dir][xy + v->blocks_off] = 1;
+ v->ref_field_type[dir] = !v->cur_field_type;
+ } else {
+ if (a_valid && a_f) {
+ field_predA[0] = scaleforsame(v, n, field_predA[0], 0, dir);
+ field_predA[1] = scaleforsame(v, n, field_predA[1], 1, dir);
+ }
+ if (b_valid && b_f) {
+ field_predB[0] = scaleforsame(v, n, field_predB[0], 0, dir);
+ field_predB[1] = scaleforsame(v, n, field_predB[1], 1, dir);
+ }
+ if (c_valid && c_f) {
+ field_predC[0] = scaleforsame(v, n, field_predC[0], 0, dir);
+ field_predC[1] = scaleforsame(v, n, field_predC[1], 1, dir);
+ }
+ v->mv_f[dir][xy + v->blocks_off] = 0;
+ v->ref_field_type[dir] = v->cur_field_type;
+ }
+
+ if (a_valid) {
+ px = field_predA[0];
+ py = field_predA[1];
+ } else if (c_valid) {
+ px = field_predC[0];
+ py = field_predC[1];
+ } else if (b_valid) {
+ px = field_predB[0];
+ py = field_predB[1];
+ } else {
+ px = 0;
+ py = 0;
+ }
+
+ if (num_samefield + num_oppfield > 1) {
+ px = mid_pred(field_predA[0], field_predB[0], field_predC[0]);
+ py = mid_pred(field_predA[1], field_predB[1], field_predC[1]);
+ }
+
+ /* Pullback MV as specified in 8.3.5.3.4 */
+ if (!v->field_mode) {
+ int qx, qy, X, Y;
+ qx = (s->mb_x << 6) + ((n == 1 || n == 3) ? 32 : 0);
+ qy = (s->mb_y << 6) + ((n == 2 || n == 3) ? 32 : 0);
+ X = (s->mb_width << 6) - 4;
+ Y = (s->mb_height << 6) - 4;
+ if (mv1) {
+ if (qx + px < -60) px = -60 - qx;
+ if (qy + py < -60) py = -60 - qy;
+ } else {
+ if (qx + px < -28) px = -28 - qx;
+ if (qy + py < -28) py = -28 - qy;
+ }
+ if (qx + px > X) px = X - qx;
+ if (qy + py > Y) py = Y - qy;
+ }
+
+ if (!v->field_mode || s->pict_type != AV_PICTURE_TYPE_B) {
+ /* Calculate hybrid prediction as specified in 8.3.5.3.5 (also 10.3.5.4.3.5) */
+ hybridmv_thresh = 32;
+ if (a_valid && c_valid) {
+ if (is_intra[xy - wrap])
+ sum = FFABS(px) + FFABS(py);
+ else
+ sum = FFABS(px - field_predA[0]) + FFABS(py - field_predA[1]);
+ if (sum > hybridmv_thresh) {
+ if (get_bits1(&s->gb)) { // read HYBRIDPRED bit
+ px = field_predA[0];
+ py = field_predA[1];
+ } else {
+ px = field_predC[0];
+ py = field_predC[1];
+ }
+ } else {
+ if (is_intra[xy - 1])
+ sum = FFABS(px) + FFABS(py);
+ else
+ sum = FFABS(px - field_predC[0]) + FFABS(py - field_predC[1]);
+ if (sum > hybridmv_thresh) {
+ if (get_bits1(&s->gb)) {
+ px = field_predA[0];
+ py = field_predA[1];
+ } else {
+ px = field_predC[0];
+ py = field_predC[1];
+ }
+ }
+ }
+ }
+ }
+
+ if (v->field_mode && v->numref)
+ r_y >>= 1;
+ if (v->field_mode && v->cur_field_type && v->ref_field_type[dir] == 0)
+ y_bias = 1;
+ /* store MV using signed modulus of MV range defined in 4.11 */
+ s->mv[dir][n][0] = s->current_picture.motion_val[dir][xy + v->blocks_off][0] = ((px + dmv_x + r_x) & ((r_x << 1) - 1)) - r_x;
+ s->mv[dir][n][1] = s->current_picture.motion_val[dir][xy + v->blocks_off][1] = ((py + dmv_y + r_y - y_bias) & ((r_y << 1) - 1)) - r_y + y_bias;
+ if (mv1) { /* duplicate motion data for 1-MV block */
+ s->current_picture.motion_val[dir][xy + 1 + v->blocks_off][0] = s->current_picture.motion_val[dir][xy + v->blocks_off][0];
+ s->current_picture.motion_val[dir][xy + 1 + v->blocks_off][1] = s->current_picture.motion_val[dir][xy + v->blocks_off][1];
+ s->current_picture.motion_val[dir][xy + wrap + v->blocks_off][0] = s->current_picture.motion_val[dir][xy + v->blocks_off][0];
+ s->current_picture.motion_val[dir][xy + wrap + v->blocks_off][1] = s->current_picture.motion_val[dir][xy + v->blocks_off][1];
+ s->current_picture.motion_val[dir][xy + wrap + 1 + v->blocks_off][0] = s->current_picture.motion_val[dir][xy + v->blocks_off][0];
+ s->current_picture.motion_val[dir][xy + wrap + 1 + v->blocks_off][1] = s->current_picture.motion_val[dir][xy + v->blocks_off][1];
+ v->mv_f[dir][xy + 1 + v->blocks_off] = v->mv_f[dir][xy + v->blocks_off];
+ v->mv_f[dir][xy + wrap + v->blocks_off] = v->mv_f[dir][xy + wrap + 1 + v->blocks_off] = v->mv_f[dir][xy + v->blocks_off];
+ }
+}
+
+/** Predict and set motion vector for interlaced frame picture MBs
+ */
+void ff_vc1_pred_mv_intfr(VC1Context *v, int n, int dmv_x, int dmv_y,
+ int mvn, int r_x, int r_y, uint8_t* is_intra, int dir)
+{
+ MpegEncContext *s = &v->s;
+ int xy, wrap, off = 0;
+ int A[2], B[2], C[2];
+ int px = 0, py = 0;
+ int a_valid = 0, b_valid = 0, c_valid = 0;
+ int field_a, field_b, field_c; // 0: same, 1: opposit
+ int total_valid, num_samefield, num_oppfield;
+ int pos_c, pos_b, n_adj;
+
+ wrap = s->b8_stride;
+ xy = s->block_index[n];
+
+ if (s->mb_intra) {
+ s->mv[0][n][0] = s->current_picture.motion_val[0][xy][0] = 0;
+ s->mv[0][n][1] = s->current_picture.motion_val[0][xy][1] = 0;
+ s->current_picture.motion_val[1][xy][0] = 0;
+ s->current_picture.motion_val[1][xy][1] = 0;
+ if (mvn == 1) { /* duplicate motion data for 1-MV block */
+ s->current_picture.motion_val[0][xy + 1][0] = 0;
+ s->current_picture.motion_val[0][xy + 1][1] = 0;
+ s->current_picture.motion_val[0][xy + wrap][0] = 0;
+ s->current_picture.motion_val[0][xy + wrap][1] = 0;
+ s->current_picture.motion_val[0][xy + wrap + 1][0] = 0;
+ s->current_picture.motion_val[0][xy + wrap + 1][1] = 0;
+ v->luma_mv[s->mb_x][0] = v->luma_mv[s->mb_x][1] = 0;
+ s->current_picture.motion_val[1][xy + 1][0] = 0;
+ s->current_picture.motion_val[1][xy + 1][1] = 0;
+ s->current_picture.motion_val[1][xy + wrap][0] = 0;
+ s->current_picture.motion_val[1][xy + wrap][1] = 0;
+ s->current_picture.motion_val[1][xy + wrap + 1][0] = 0;
+ s->current_picture.motion_val[1][xy + wrap + 1][1] = 0;
+ }
+ return;
+ }
+
+ off = ((n == 0) || (n == 1)) ? 1 : -1;
+ /* predict A */
+ if (s->mb_x || (n == 1) || (n == 3)) {
+ if ((v->blk_mv_type[xy]) // current block (MB) has a field MV
+ || (!v->blk_mv_type[xy] && !v->blk_mv_type[xy - 1])) { // or both have frame MV
+ A[0] = s->current_picture.motion_val[dir][xy - 1][0];
+ A[1] = s->current_picture.motion_val[dir][xy - 1][1];
+ a_valid = 1;
+ } else { // current block has frame mv and cand. has field MV (so average)
+ A[0] = (s->current_picture.motion_val[dir][xy - 1][0]
+ + s->current_picture.motion_val[dir][xy - 1 + off * wrap][0] + 1) >> 1;
+ A[1] = (s->current_picture.motion_val[dir][xy - 1][1]
+ + s->current_picture.motion_val[dir][xy - 1 + off * wrap][1] + 1) >> 1;
+ a_valid = 1;
+ }
+ if (!(n & 1) && v->is_intra[s->mb_x - 1]) {
+ a_valid = 0;
+ A[0] = A[1] = 0;
+ }
+ } else
+ A[0] = A[1] = 0;
+ /* Predict B and C */
+ B[0] = B[1] = C[0] = C[1] = 0;
+ if (n == 0 || n == 1 || v->blk_mv_type[xy]) {
+ if (!s->first_slice_line) {
+ if (!v->is_intra[s->mb_x - s->mb_stride]) {
+ b_valid = 1;
+ n_adj = n | 2;
+ pos_b = s->block_index[n_adj] - 2 * wrap;
+ if (v->blk_mv_type[pos_b] && v->blk_mv_type[xy]) {
+ n_adj = (n & 2) | (n & 1);
+ }
+ B[0] = s->current_picture.motion_val[dir][s->block_index[n_adj] - 2 * wrap][0];
+ B[1] = s->current_picture.motion_val[dir][s->block_index[n_adj] - 2 * wrap][1];
+ if (v->blk_mv_type[pos_b] && !v->blk_mv_type[xy]) {
+ B[0] = (B[0] + s->current_picture.motion_val[dir][s->block_index[n_adj ^ 2] - 2 * wrap][0] + 1) >> 1;
+ B[1] = (B[1] + s->current_picture.motion_val[dir][s->block_index[n_adj ^ 2] - 2 * wrap][1] + 1) >> 1;
+ }
+ }
+ if (s->mb_width > 1) {
+ if (!v->is_intra[s->mb_x - s->mb_stride + 1]) {
+ c_valid = 1;
+ n_adj = 2;
+ pos_c = s->block_index[2] - 2 * wrap + 2;
+ if (v->blk_mv_type[pos_c] && v->blk_mv_type[xy]) {
+ n_adj = n & 2;
+ }
+ C[0] = s->current_picture.motion_val[dir][s->block_index[n_adj] - 2 * wrap + 2][0];
+ C[1] = s->current_picture.motion_val[dir][s->block_index[n_adj] - 2 * wrap + 2][1];
+ if (v->blk_mv_type[pos_c] && !v->blk_mv_type[xy]) {
+ C[0] = (1 + C[0] + (s->current_picture.motion_val[dir][s->block_index[n_adj ^ 2] - 2 * wrap + 2][0])) >> 1;
+ C[1] = (1 + C[1] + (s->current_picture.motion_val[dir][s->block_index[n_adj ^ 2] - 2 * wrap + 2][1])) >> 1;
+ }
+ if (s->mb_x == s->mb_width - 1) {
+ if (!v->is_intra[s->mb_x - s->mb_stride - 1]) {
+ c_valid = 1;
+ n_adj = 3;
+ pos_c = s->block_index[3] - 2 * wrap - 2;
+ if (v->blk_mv_type[pos_c] && v->blk_mv_type[xy]) {
+ n_adj = n | 1;
+ }
+ C[0] = s->current_picture.motion_val[dir][s->block_index[n_adj] - 2 * wrap - 2][0];
+ C[1] = s->current_picture.motion_val[dir][s->block_index[n_adj] - 2 * wrap - 2][1];
+ if (v->blk_mv_type[pos_c] && !v->blk_mv_type[xy]) {
+ C[0] = (1 + C[0] + s->current_picture.motion_val[dir][s->block_index[1] - 2 * wrap - 2][0]) >> 1;
+ C[1] = (1 + C[1] + s->current_picture.motion_val[dir][s->block_index[1] - 2 * wrap - 2][1]) >> 1;
+ }
+ } else
+ c_valid = 0;
+ }
+ }
+ }
+ }
+ } else {
+ pos_b = s->block_index[1];
+ b_valid = 1;
+ B[0] = s->current_picture.motion_val[dir][pos_b][0];
+ B[1] = s->current_picture.motion_val[dir][pos_b][1];
+ pos_c = s->block_index[0];
+ c_valid = 1;
+ C[0] = s->current_picture.motion_val[dir][pos_c][0];
+ C[1] = s->current_picture.motion_val[dir][pos_c][1];
+ }
+
+ total_valid = a_valid + b_valid + c_valid;
+ // check if predictor A is out of bounds
+ if (!s->mb_x && !(n == 1 || n == 3)) {
+ A[0] = A[1] = 0;
+ }
+ // check if predictor B is out of bounds
+ if ((s->first_slice_line && v->blk_mv_type[xy]) || (s->first_slice_line && !(n & 2))) {
+ B[0] = B[1] = C[0] = C[1] = 0;
+ }
+ if (!v->blk_mv_type[xy]) {
+ if (s->mb_width == 1) {
+ px = B[0];
+ py = B[1];
+ } else {
+ if (total_valid >= 2) {
+ px = mid_pred(A[0], B[0], C[0]);
+ py = mid_pred(A[1], B[1], C[1]);
+ } else if (total_valid) {
+ if (a_valid) { px = A[0]; py = A[1]; }
+ else if (b_valid) { px = B[0]; py = B[1]; }
+ else { px = C[0]; py = C[1]; }
+ }
+ }
+ } else {
+ if (a_valid)
+ field_a = (A[1] & 4) ? 1 : 0;
+ else
+ field_a = 0;
+ if (b_valid)
+ field_b = (B[1] & 4) ? 1 : 0;
+ else
+ field_b = 0;
+ if (c_valid)
+ field_c = (C[1] & 4) ? 1 : 0;
+ else
+ field_c = 0;
+
+ num_oppfield = field_a + field_b + field_c;
+ num_samefield = total_valid - num_oppfield;
+ if (total_valid == 3) {
+ if ((num_samefield == 3) || (num_oppfield == 3)) {
+ px = mid_pred(A[0], B[0], C[0]);
+ py = mid_pred(A[1], B[1], C[1]);
+ } else if (num_samefield >= num_oppfield) {
+ /* take one MV from same field set depending on priority
+ the check for B may not be necessary */
+ px = !field_a ? A[0] : B[0];
+ py = !field_a ? A[1] : B[1];
+ } else {
+ px = field_a ? A[0] : B[0];
+ py = field_a ? A[1] : B[1];
+ }
+ } else if (total_valid == 2) {
+ if (num_samefield >= num_oppfield) {
+ if (!field_a && a_valid) {
+ px = A[0];
+ py = A[1];
+ } else if (!field_b && b_valid) {
+ px = B[0];
+ py = B[1];
+ } else /*if (c_valid)*/ {
+ av_assert1(c_valid);
+ px = C[0];
+ py = C[1];
+ }
+ } else {
+ if (field_a && a_valid) {
+ px = A[0];
+ py = A[1];
+ } else /*if (field_b && b_valid)*/ {
+ av_assert1(field_b && b_valid);
+ px = B[0];
+ py = B[1];
+ }
+ }
+ } else if (total_valid == 1) {
+ px = (a_valid) ? A[0] : ((b_valid) ? B[0] : C[0]);
+ py = (a_valid) ? A[1] : ((b_valid) ? B[1] : C[1]);
+ }
+ }
+
+ /* store MV using signed modulus of MV range defined in 4.11 */
+ s->mv[dir][n][0] = s->current_picture.motion_val[dir][xy][0] = ((px + dmv_x + r_x) & ((r_x << 1) - 1)) - r_x;
+ s->mv[dir][n][1] = s->current_picture.motion_val[dir][xy][1] = ((py + dmv_y + r_y) & ((r_y << 1) - 1)) - r_y;
+ if (mvn == 1) { /* duplicate motion data for 1-MV block */
+ s->current_picture.motion_val[dir][xy + 1 ][0] = s->current_picture.motion_val[dir][xy][0];
+ s->current_picture.motion_val[dir][xy + 1 ][1] = s->current_picture.motion_val[dir][xy][1];
+ s->current_picture.motion_val[dir][xy + wrap ][0] = s->current_picture.motion_val[dir][xy][0];
+ s->current_picture.motion_val[dir][xy + wrap ][1] = s->current_picture.motion_val[dir][xy][1];
+ s->current_picture.motion_val[dir][xy + wrap + 1][0] = s->current_picture.motion_val[dir][xy][0];
+ s->current_picture.motion_val[dir][xy + wrap + 1][1] = s->current_picture.motion_val[dir][xy][1];
+ } else if (mvn == 2) { /* duplicate motion data for 2-Field MV block */
+ s->current_picture.motion_val[dir][xy + 1][0] = s->current_picture.motion_val[dir][xy][0];
+ s->current_picture.motion_val[dir][xy + 1][1] = s->current_picture.motion_val[dir][xy][1];
+ s->mv[dir][n + 1][0] = s->mv[dir][n][0];
+ s->mv[dir][n + 1][1] = s->mv[dir][n][1];
+ }
+}
+
+void ff_vc1_pred_b_mv(VC1Context *v, int dmv_x[2], int dmv_y[2],
+ int direct, int mvtype)
+{
+ MpegEncContext *s = &v->s;
+ int xy, wrap, off = 0;
+ int16_t *A, *B, *C;
+ int px, py;
+ int sum;
+ int r_x, r_y;
+ const uint8_t *is_intra = v->mb_type[0];
+
+ av_assert0(!v->field_mode);
+
+ r_x = v->range_x;
+ r_y = v->range_y;
+ /* scale MV difference to be quad-pel */
+ dmv_x[0] <<= 1 - s->quarter_sample;
+ dmv_y[0] <<= 1 - s->quarter_sample;
+ dmv_x[1] <<= 1 - s->quarter_sample;
+ dmv_y[1] <<= 1 - s->quarter_sample;
+
+ wrap = s->b8_stride;
+ xy = s->block_index[0];
+
+ if (s->mb_intra) {
+ s->current_picture.motion_val[0][xy][0] =
+ s->current_picture.motion_val[0][xy][1] =
+ s->current_picture.motion_val[1][xy][0] =
+ s->current_picture.motion_val[1][xy][1] = 0;
+ return;
+ }
+ if (direct && s->next_picture_ptr->field_picture)
+ av_log(s->avctx, AV_LOG_WARNING, "Mixed frame/field direct mode not supported\n");
+
+ s->mv[0][0][0] = scale_mv(s->next_picture.motion_val[1][xy][0], v->bfraction, 0, s->quarter_sample);
+ s->mv[0][0][1] = scale_mv(s->next_picture.motion_val[1][xy][1], v->bfraction, 0, s->quarter_sample);
+ s->mv[1][0][0] = scale_mv(s->next_picture.motion_val[1][xy][0], v->bfraction, 1, s->quarter_sample);
+ s->mv[1][0][1] = scale_mv(s->next_picture.motion_val[1][xy][1], v->bfraction, 1, s->quarter_sample);
+
+ /* Pullback predicted motion vectors as specified in 8.4.5.4 */
+ s->mv[0][0][0] = av_clip(s->mv[0][0][0], -60 - (s->mb_x << 6), (s->mb_width << 6) - 4 - (s->mb_x << 6));
+ s->mv[0][0][1] = av_clip(s->mv[0][0][1], -60 - (s->mb_y << 6), (s->mb_height << 6) - 4 - (s->mb_y << 6));
+ s->mv[1][0][0] = av_clip(s->mv[1][0][0], -60 - (s->mb_x << 6), (s->mb_width << 6) - 4 - (s->mb_x << 6));
+ s->mv[1][0][1] = av_clip(s->mv[1][0][1], -60 - (s->mb_y << 6), (s->mb_height << 6) - 4 - (s->mb_y << 6));
+ if (direct) {
+ s->current_picture.motion_val[0][xy][0] = s->mv[0][0][0];
+ s->current_picture.motion_val[0][xy][1] = s->mv[0][0][1];
+ s->current_picture.motion_val[1][xy][0] = s->mv[1][0][0];
+ s->current_picture.motion_val[1][xy][1] = s->mv[1][0][1];
+ return;
+ }
+
+ if ((mvtype == BMV_TYPE_FORWARD) || (mvtype == BMV_TYPE_INTERPOLATED)) {
+ C = s->current_picture.motion_val[0][xy - 2];
+ A = s->current_picture.motion_val[0][xy - wrap * 2];
+ off = (s->mb_x == (s->mb_width - 1)) ? -2 : 2;
+ B = s->current_picture.motion_val[0][xy - wrap * 2 + off];
+
+ if (!s->mb_x) C[0] = C[1] = 0;
+ if (!s->first_slice_line) { // predictor A is not out of bounds
+ if (s->mb_width == 1) {
+ px = A[0];
+ py = A[1];
+ } else {
+ px = mid_pred(A[0], B[0], C[0]);
+ py = mid_pred(A[1], B[1], C[1]);
+ }
+ } else if (s->mb_x) { // predictor C is not out of bounds
+ px = C[0];
+ py = C[1];
+ } else {
+ px = py = 0;
+ }
+ /* Pullback MV as specified in 8.3.5.3.4 */
+ {
+ int qx, qy, X, Y;
+ if (v->profile < PROFILE_ADVANCED) {
+ qx = (s->mb_x << 5);
+ qy = (s->mb_y << 5);
+ X = (s->mb_width << 5) - 4;
+ Y = (s->mb_height << 5) - 4;
+ if (qx + px < -28) px = -28 - qx;
+ if (qy + py < -28) py = -28 - qy;
+ if (qx + px > X) px = X - qx;
+ if (qy + py > Y) py = Y - qy;
+ } else {
+ qx = (s->mb_x << 6);
+ qy = (s->mb_y << 6);
+ X = (s->mb_width << 6) - 4;
+ Y = (s->mb_height << 6) - 4;
+ if (qx + px < -60) px = -60 - qx;
+ if (qy + py < -60) py = -60 - qy;
+ if (qx + px > X) px = X - qx;
+ if (qy + py > Y) py = Y - qy;
+ }
+ }
+ /* Calculate hybrid prediction as specified in 8.3.5.3.5 */
+ if (0 && !s->first_slice_line && s->mb_x) {
+ if (is_intra[xy - wrap])
+ sum = FFABS(px) + FFABS(py);
+ else
+ sum = FFABS(px - A[0]) + FFABS(py - A[1]);
+ if (sum > 32) {
+ if (get_bits1(&s->gb)) {
+ px = A[0];
+ py = A[1];
+ } else {
+ px = C[0];
+ py = C[1];
+ }
+ } else {
+ if (is_intra[xy - 2])
+ sum = FFABS(px) + FFABS(py);
+ else
+ sum = FFABS(px - C[0]) + FFABS(py - C[1]);
+ if (sum > 32) {
+ if (get_bits1(&s->gb)) {
+ px = A[0];
+ py = A[1];
+ } else {
+ px = C[0];
+ py = C[1];
+ }
+ }
+ }
+ }
+ /* store MV using signed modulus of MV range defined in 4.11 */
+ s->mv[0][0][0] = ((px + dmv_x[0] + r_x) & ((r_x << 1) - 1)) - r_x;
+ s->mv[0][0][1] = ((py + dmv_y[0] + r_y) & ((r_y << 1) - 1)) - r_y;
+ }
+ if ((mvtype == BMV_TYPE_BACKWARD) || (mvtype == BMV_TYPE_INTERPOLATED)) {
+ C = s->current_picture.motion_val[1][xy - 2];
+ A = s->current_picture.motion_val[1][xy - wrap * 2];
+ off = (s->mb_x == (s->mb_width - 1)) ? -2 : 2;
+ B = s->current_picture.motion_val[1][xy - wrap * 2 + off];
+
+ if (!s->mb_x)
+ C[0] = C[1] = 0;
+ if (!s->first_slice_line) { // predictor A is not out of bounds
+ if (s->mb_width == 1) {
+ px = A[0];
+ py = A[1];
+ } else {
+ px = mid_pred(A[0], B[0], C[0]);
+ py = mid_pred(A[1], B[1], C[1]);
+ }
+ } else if (s->mb_x) { // predictor C is not out of bounds
+ px = C[0];
+ py = C[1];
+ } else {
+ px = py = 0;
+ }
+ /* Pullback MV as specified in 8.3.5.3.4 */
+ {
+ int qx, qy, X, Y;
+ if (v->profile < PROFILE_ADVANCED) {
+ qx = (s->mb_x << 5);
+ qy = (s->mb_y << 5);
+ X = (s->mb_width << 5) - 4;
+ Y = (s->mb_height << 5) - 4;
+ if (qx + px < -28) px = -28 - qx;
+ if (qy + py < -28) py = -28 - qy;
+ if (qx + px > X) px = X - qx;
+ if (qy + py > Y) py = Y - qy;
+ } else {
+ qx = (s->mb_x << 6);
+ qy = (s->mb_y << 6);
+ X = (s->mb_width << 6) - 4;
+ Y = (s->mb_height << 6) - 4;
+ if (qx + px < -60) px = -60 - qx;
+ if (qy + py < -60) py = -60 - qy;
+ if (qx + px > X) px = X - qx;
+ if (qy + py > Y) py = Y - qy;
+ }
+ }
+ /* Calculate hybrid prediction as specified in 8.3.5.3.5 */
+ if (0 && !s->first_slice_line && s->mb_x) {
+ if (is_intra[xy - wrap])
+ sum = FFABS(px) + FFABS(py);
+ else
+ sum = FFABS(px - A[0]) + FFABS(py - A[1]);
+ if (sum > 32) {
+ if (get_bits1(&s->gb)) {
+ px = A[0];
+ py = A[1];
+ } else {
+ px = C[0];
+ py = C[1];
+ }
+ } else {
+ if (is_intra[xy - 2])
+ sum = FFABS(px) + FFABS(py);
+ else
+ sum = FFABS(px - C[0]) + FFABS(py - C[1]);
+ if (sum > 32) {
+ if (get_bits1(&s->gb)) {
+ px = A[0];
+ py = A[1];
+ } else {
+ px = C[0];
+ py = C[1];
+ }
+ }
+ }
+ }
+ /* store MV using signed modulus of MV range defined in 4.11 */
+
+ s->mv[1][0][0] = ((px + dmv_x[1] + r_x) & ((r_x << 1) - 1)) - r_x;
+ s->mv[1][0][1] = ((py + dmv_y[1] + r_y) & ((r_y << 1) - 1)) - r_y;
+ }
+ s->current_picture.motion_val[0][xy][0] = s->mv[0][0][0];
+ s->current_picture.motion_val[0][xy][1] = s->mv[0][0][1];
+ s->current_picture.motion_val[1][xy][0] = s->mv[1][0][0];
+ s->current_picture.motion_val[1][xy][1] = s->mv[1][0][1];
+}
+
+void ff_vc1_pred_b_mv_intfi(VC1Context *v, int n, int *dmv_x, int *dmv_y,
+ int mv1, int *pred_flag)
+{
+ int dir = (v->bmvtype == BMV_TYPE_BACKWARD) ? 1 : 0;
+ MpegEncContext *s = &v->s;
+ int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
+
+ if (v->bmvtype == BMV_TYPE_DIRECT) {
+ int total_opp, k, f;
+ if (s->next_picture.mb_type[mb_pos + v->mb_off] != MB_TYPE_INTRA) {
+ s->mv[0][0][0] = scale_mv(s->next_picture.motion_val[1][s->block_index[0] + v->blocks_off][0],
+ v->bfraction, 0, s->quarter_sample);
+ s->mv[0][0][1] = scale_mv(s->next_picture.motion_val[1][s->block_index[0] + v->blocks_off][1],
+ v->bfraction, 0, s->quarter_sample);
+ s->mv[1][0][0] = scale_mv(s->next_picture.motion_val[1][s->block_index[0] + v->blocks_off][0],
+ v->bfraction, 1, s->quarter_sample);
+ s->mv[1][0][1] = scale_mv(s->next_picture.motion_val[1][s->block_index[0] + v->blocks_off][1],
+ v->bfraction, 1, s->quarter_sample);
+
+ total_opp = v->mv_f_next[0][s->block_index[0] + v->blocks_off]
+ + v->mv_f_next[0][s->block_index[1] + v->blocks_off]
+ + v->mv_f_next[0][s->block_index[2] + v->blocks_off]
+ + v->mv_f_next[0][s->block_index[3] + v->blocks_off];
+ f = (total_opp > 2) ? 1 : 0;
+ } else {
+ s->mv[0][0][0] = s->mv[0][0][1] = 0;
+ s->mv[1][0][0] = s->mv[1][0][1] = 0;
+ f = 0;
+ }
+ v->ref_field_type[0] = v->ref_field_type[1] = v->cur_field_type ^ f;
+ for (k = 0; k < 4; k++) {
+ s->current_picture.motion_val[0][s->block_index[k] + v->blocks_off][0] = s->mv[0][0][0];
+ s->current_picture.motion_val[0][s->block_index[k] + v->blocks_off][1] = s->mv[0][0][1];
+ s->current_picture.motion_val[1][s->block_index[k] + v->blocks_off][0] = s->mv[1][0][0];
+ s->current_picture.motion_val[1][s->block_index[k] + v->blocks_off][1] = s->mv[1][0][1];
+ v->mv_f[0][s->block_index[k] + v->blocks_off] = f;
+ v->mv_f[1][s->block_index[k] + v->blocks_off] = f;
+ }
+ return;
+ }
+ if (v->bmvtype == BMV_TYPE_INTERPOLATED) {
+ ff_vc1_pred_mv(v, 0, dmv_x[0], dmv_y[0], 1, v->range_x, v->range_y, v->mb_type[0], pred_flag[0], 0);
+ ff_vc1_pred_mv(v, 0, dmv_x[1], dmv_y[1], 1, v->range_x, v->range_y, v->mb_type[0], pred_flag[1], 1);
+ return;
+ }
+ if (dir) { // backward
+ ff_vc1_pred_mv(v, n, dmv_x[1], dmv_y[1], mv1, v->range_x, v->range_y, v->mb_type[0], pred_flag[1], 1);
+ if (n == 3 || mv1) {
+ ff_vc1_pred_mv(v, 0, dmv_x[0], dmv_y[0], 1, v->range_x, v->range_y, v->mb_type[0], 0, 0);
+ }
+ } else { // forward
+ ff_vc1_pred_mv(v, n, dmv_x[0], dmv_y[0], mv1, v->range_x, v->range_y, v->mb_type[0], pred_flag[0], 0);
+ if (n == 3 || mv1) {
+ ff_vc1_pred_mv(v, 0, dmv_x[1], dmv_y[1], 1, v->range_x, v->range_y, v->mb_type[0], 0, 1);
+ }
+ }
+}
--- /dev/null
+/*
+ * VC-1 and WMV3 decoder
+ * Copyright (c) 2006-2007 Konstantin Shishkov
+ * Partly based on vc9.c (c) 2005 Anonymous, Alex Beregszaszi, 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
+ */
+
+#ifndef AVCODEC_VC1_PRED_H
+#define AVCODEC_VC1_PRED_H
+
+#include "vc1.h"
+#include "vc1data.h"
+
+void ff_vc1_pred_mv(VC1Context *v, int n, int dmv_x, int dmv_y,
+ int mv1, int r_x, int r_y, uint8_t* is_intra,
+ int pred_flag, int dir);
+void ff_vc1_pred_mv_intfr(VC1Context *v, int n, int dmv_x, int dmv_y,
+ int mvn, int r_x, int r_y, uint8_t* is_intra,
+ int dir);
+void ff_vc1_pred_b_mv(VC1Context *v, int dmv_x[2], int dmv_y[2],
+ int direct, int mvtype);
+void ff_vc1_pred_b_mv_intfi(VC1Context *v, int n, int *dmv_x, int *dmv_y,
+ int mv1, int *pred_flag);
+
+static av_always_inline int scale_mv(int value, int bfrac, int inv, int qs)
+{
+ int n = bfrac;
+
+#if B_FRACTION_DEN==256
+ if (inv)
+ n -= 256;
+ if (!qs)
+ return 2 * ((value * n + 255) >> 9);
+ return (value * n + 128) >> 8;
+#else
+ if (inv)
+ n -= B_FRACTION_DEN;
+ if (!qs)
+ return 2 * ((value * n + B_FRACTION_DEN - 1) / (2 * B_FRACTION_DEN));
+ return (value * n + B_FRACTION_DEN/2) / B_FRACTION_DEN;
+#endif
+}
+
+#endif /* AVCODEC_VC1_PRED_H */
#define VC1_IF_MBMODE_VLC_BITS 5
//@}
-
-/* Denominator used for ff_vc1_bfraction_lut */
#define B_FRACTION_DEN 256
/* pre-computed scales for all bfractions and base=256 */
* VC-1 and WMV3 decoder
*/
-#include "internal.h"
-#include "avcodec.h"
-#include "error_resilience.h"
-#include "mpeg_er.h"
-#include "mpegutils.h"
-#include "mpegvideo.h"
-#include "h263.h"
-#include "h264chroma.h"
-#include "qpeldsp.h"
-#include "vc1.h"
-#include "vc1data.h"
-#include "vc1acdata.h"
-#include "msmpeg4data.h"
-#include "unary.h"
-#include "mathops.h"
-#include "vdpau_internal.h"
-#include "libavutil/avassert.h"
-
-#undef NDEBUG
-#include <assert.h>
-
-#define MB_INTRA_VLC_BITS 9
-#define DC_VLC_BITS 9
-
-
-// offset tables for interlaced picture MVDATA decoding
-static const int offset_table1[9] = { 0, 1, 2, 4, 8, 16, 32, 64, 128 };
-static const int offset_table2[9] = { 0, 1, 3, 7, 15, 31, 63, 127, 255 };
-
-/***********************************************************************/
-/**
- * @name VC-1 Bitplane decoding
- * @see 8.7, p56
- * @{
- */
-
-
-static void init_block_index(VC1Context *v)
-{
- MpegEncContext *s = &v->s;
- ff_init_block_index(s);
- if (v->field_mode && !(v->second_field ^ v->tff)) {
- s->dest[0] += s->current_picture_ptr->f->linesize[0];
- s->dest[1] += s->current_picture_ptr->f->linesize[1];
- s->dest[2] += s->current_picture_ptr->f->linesize[2];
- }
-}
-
-/** @} */ //Bitplane group
-
-static void vc1_put_signed_blocks_clamped(VC1Context *v)
-{
- MpegEncContext *s = &v->s;
- int topleft_mb_pos, top_mb_pos;
- int stride_y, fieldtx = 0;
- int v_dist;
-
- /* The put pixels loop is always one MB row behind the decoding loop,
- * because we can only put pixels when overlap filtering is done, and
- * for filtering of the bottom edge of a MB, we need the next MB row
- * present as well.
- * Within the row, the put pixels loop is also one MB col behind the
- * decoding loop. The reason for this is again, because for filtering
- * of the right MB edge, we need the next MB present. */
- if (!s->first_slice_line) {
- if (s->mb_x) {
- topleft_mb_pos = (s->mb_y - 1) * s->mb_stride + s->mb_x - 1;
- if (v->fcm == ILACE_FRAME)
- fieldtx = v->fieldtx_plane[topleft_mb_pos];
- stride_y = s->linesize << fieldtx;
- v_dist = (16 - fieldtx) >> (fieldtx == 0);
- s->idsp.put_signed_pixels_clamped(v->block[v->topleft_blk_idx][0],
- s->dest[0] - 16 * s->linesize - 16,
- stride_y);
- s->idsp.put_signed_pixels_clamped(v->block[v->topleft_blk_idx][1],
- s->dest[0] - 16 * s->linesize - 8,
- stride_y);
- s->idsp.put_signed_pixels_clamped(v->block[v->topleft_blk_idx][2],
- s->dest[0] - v_dist * s->linesize - 16,
- stride_y);
- s->idsp.put_signed_pixels_clamped(v->block[v->topleft_blk_idx][3],
- s->dest[0] - v_dist * s->linesize - 8,
- stride_y);
- s->idsp.put_signed_pixels_clamped(v->block[v->topleft_blk_idx][4],
- s->dest[1] - 8 * s->uvlinesize - 8,
- s->uvlinesize);
- s->idsp.put_signed_pixels_clamped(v->block[v->topleft_blk_idx][5],
- s->dest[2] - 8 * s->uvlinesize - 8,
- s->uvlinesize);
- }
- if (s->mb_x == s->mb_width - 1) {
- top_mb_pos = (s->mb_y - 1) * s->mb_stride + s->mb_x;
- if (v->fcm == ILACE_FRAME)
- fieldtx = v->fieldtx_plane[top_mb_pos];
- stride_y = s->linesize << fieldtx;
- v_dist = fieldtx ? 15 : 8;
- s->idsp.put_signed_pixels_clamped(v->block[v->top_blk_idx][0],
- s->dest[0] - 16 * s->linesize,
- stride_y);
- s->idsp.put_signed_pixels_clamped(v->block[v->top_blk_idx][1],
- s->dest[0] - 16 * s->linesize + 8,
- stride_y);
- s->idsp.put_signed_pixels_clamped(v->block[v->top_blk_idx][2],
- s->dest[0] - v_dist * s->linesize,
- stride_y);
- s->idsp.put_signed_pixels_clamped(v->block[v->top_blk_idx][3],
- s->dest[0] - v_dist * s->linesize + 8,
- stride_y);
- s->idsp.put_signed_pixels_clamped(v->block[v->top_blk_idx][4],
- s->dest[1] - 8 * s->uvlinesize,
- s->uvlinesize);
- s->idsp.put_signed_pixels_clamped(v->block[v->top_blk_idx][5],
- s->dest[2] - 8 * s->uvlinesize,
- s->uvlinesize);
- }
- }
-
-#define inc_blk_idx(idx) do { \
- idx++; \
- if (idx >= v->n_allocated_blks) \
- idx = 0; \
- } while (0)
-
- inc_blk_idx(v->topleft_blk_idx);
- inc_blk_idx(v->top_blk_idx);
- inc_blk_idx(v->left_blk_idx);
- inc_blk_idx(v->cur_blk_idx);
-}
-
-static void vc1_loop_filter_iblk(VC1Context *v, int pq)
-{
- MpegEncContext *s = &v->s;
- int j;
- if (!s->first_slice_line) {
- v->vc1dsp.vc1_v_loop_filter16(s->dest[0], s->linesize, pq);
- if (s->mb_x)
- v->vc1dsp.vc1_h_loop_filter16(s->dest[0] - 16 * s->linesize, s->linesize, pq);
- v->vc1dsp.vc1_h_loop_filter16(s->dest[0] - 16 * s->linesize + 8, s->linesize, pq);
- for (j = 0; j < 2; j++) {
- v->vc1dsp.vc1_v_loop_filter8(s->dest[j + 1], s->uvlinesize, pq);
- if (s->mb_x)
- v->vc1dsp.vc1_h_loop_filter8(s->dest[j + 1] - 8 * s->uvlinesize, s->uvlinesize, pq);
- }
- }
- v->vc1dsp.vc1_v_loop_filter16(s->dest[0] + 8 * s->linesize, s->linesize, pq);
-
- if (s->mb_y == s->end_mb_y - 1) {
- if (s->mb_x) {
- v->vc1dsp.vc1_h_loop_filter16(s->dest[0], s->linesize, pq);
- v->vc1dsp.vc1_h_loop_filter8(s->dest[1], s->uvlinesize, pq);
- v->vc1dsp.vc1_h_loop_filter8(s->dest[2], s->uvlinesize, pq);
- }
- v->vc1dsp.vc1_h_loop_filter16(s->dest[0] + 8, s->linesize, pq);
- }
-}
-
-static void vc1_loop_filter_iblk_delayed(VC1Context *v, int pq)
-{
- MpegEncContext *s = &v->s;
- int j;
-
- /* The loopfilter runs 1 row and 1 column behind the overlap filter, which
- * means it runs two rows/cols behind the decoding loop. */
- if (!s->first_slice_line) {
- if (s->mb_x) {
- if (s->mb_y >= s->start_mb_y + 2) {
- v->vc1dsp.vc1_v_loop_filter16(s->dest[0] - 16 * s->linesize - 16, s->linesize, pq);
-
- if (s->mb_x >= 2)
- v->vc1dsp.vc1_h_loop_filter16(s->dest[0] - 32 * s->linesize - 16, s->linesize, pq);
- v->vc1dsp.vc1_h_loop_filter16(s->dest[0] - 32 * s->linesize - 8, s->linesize, pq);
- for (j = 0; j < 2; j++) {
- v->vc1dsp.vc1_v_loop_filter8(s->dest[j + 1] - 8 * s->uvlinesize - 8, s->uvlinesize, pq);
- if (s->mb_x >= 2) {
- v->vc1dsp.vc1_h_loop_filter8(s->dest[j + 1] - 16 * s->uvlinesize - 8, s->uvlinesize, pq);
- }
- }
- }
- v->vc1dsp.vc1_v_loop_filter16(s->dest[0] - 8 * s->linesize - 16, s->linesize, pq);
- }
-
- if (s->mb_x == s->mb_width - 1) {
- if (s->mb_y >= s->start_mb_y + 2) {
- v->vc1dsp.vc1_v_loop_filter16(s->dest[0] - 16 * s->linesize, s->linesize, pq);
-
- if (s->mb_x)
- v->vc1dsp.vc1_h_loop_filter16(s->dest[0] - 32 * s->linesize, s->linesize, pq);
- v->vc1dsp.vc1_h_loop_filter16(s->dest[0] - 32 * s->linesize + 8, s->linesize, pq);
- for (j = 0; j < 2; j++) {
- v->vc1dsp.vc1_v_loop_filter8(s->dest[j + 1] - 8 * s->uvlinesize, s->uvlinesize, pq);
- if (s->mb_x >= 2) {
- v->vc1dsp.vc1_h_loop_filter8(s->dest[j + 1] - 16 * s->uvlinesize, s->uvlinesize, pq);
- }
- }
- }
- v->vc1dsp.vc1_v_loop_filter16(s->dest[0] - 8 * s->linesize, s->linesize, pq);
- }
-
- if (s->mb_y == s->end_mb_y) {
- if (s->mb_x) {
- if (s->mb_x >= 2)
- v->vc1dsp.vc1_h_loop_filter16(s->dest[0] - 16 * s->linesize - 16, s->linesize, pq);
- v->vc1dsp.vc1_h_loop_filter16(s->dest[0] - 16 * s->linesize - 8, s->linesize, pq);
- if (s->mb_x >= 2) {
- for (j = 0; j < 2; j++) {
- v->vc1dsp.vc1_h_loop_filter8(s->dest[j + 1] - 8 * s->uvlinesize - 8, s->uvlinesize, pq);
- }
- }
- }
-
- if (s->mb_x == s->mb_width - 1) {
- if (s->mb_x)
- v->vc1dsp.vc1_h_loop_filter16(s->dest[0] - 16 * s->linesize, s->linesize, pq);
- v->vc1dsp.vc1_h_loop_filter16(s->dest[0] - 16 * s->linesize + 8, s->linesize, pq);
- if (s->mb_x) {
- for (j = 0; j < 2; j++) {
- v->vc1dsp.vc1_h_loop_filter8(s->dest[j + 1] - 8 * s->uvlinesize, s->uvlinesize, pq);
- }
- }
- }
- }
- }
-}
-
-static void vc1_smooth_overlap_filter_iblk(VC1Context *v)
-{
- MpegEncContext *s = &v->s;
- int mb_pos;
-
- if (v->condover == CONDOVER_NONE)
- return;
-
- mb_pos = s->mb_x + s->mb_y * s->mb_stride;
-
- /* Within a MB, the horizontal overlap always runs before the vertical.
- * To accomplish that, we run the H on left and internal borders of the
- * currently decoded MB. Then, we wait for the next overlap iteration
- * to do H overlap on the right edge of this MB, before moving over and
- * running the V overlap. Therefore, the V overlap makes us trail by one
- * MB col and the H overlap filter makes us trail by one MB row. This
- * is reflected in the time at which we run the put_pixels loop. */
- if (v->condover == CONDOVER_ALL || v->pq >= 9 || v->over_flags_plane[mb_pos]) {
- if (s->mb_x && (v->condover == CONDOVER_ALL || v->pq >= 9 ||
- v->over_flags_plane[mb_pos - 1])) {
- v->vc1dsp.vc1_h_s_overlap(v->block[v->left_blk_idx][1],
- v->block[v->cur_blk_idx][0]);
- v->vc1dsp.vc1_h_s_overlap(v->block[v->left_blk_idx][3],
- v->block[v->cur_blk_idx][2]);
- if (!(s->flags & CODEC_FLAG_GRAY)) {
- v->vc1dsp.vc1_h_s_overlap(v->block[v->left_blk_idx][4],
- v->block[v->cur_blk_idx][4]);
- v->vc1dsp.vc1_h_s_overlap(v->block[v->left_blk_idx][5],
- v->block[v->cur_blk_idx][5]);
- }
- }
- v->vc1dsp.vc1_h_s_overlap(v->block[v->cur_blk_idx][0],
- v->block[v->cur_blk_idx][1]);
- v->vc1dsp.vc1_h_s_overlap(v->block[v->cur_blk_idx][2],
- v->block[v->cur_blk_idx][3]);
-
- if (s->mb_x == s->mb_width - 1) {
- if (!s->first_slice_line && (v->condover == CONDOVER_ALL || v->pq >= 9 ||
- v->over_flags_plane[mb_pos - s->mb_stride])) {
- v->vc1dsp.vc1_v_s_overlap(v->block[v->top_blk_idx][2],
- v->block[v->cur_blk_idx][0]);
- v->vc1dsp.vc1_v_s_overlap(v->block[v->top_blk_idx][3],
- v->block[v->cur_blk_idx][1]);
- if (!(s->flags & CODEC_FLAG_GRAY)) {
- v->vc1dsp.vc1_v_s_overlap(v->block[v->top_blk_idx][4],
- v->block[v->cur_blk_idx][4]);
- v->vc1dsp.vc1_v_s_overlap(v->block[v->top_blk_idx][5],
- v->block[v->cur_blk_idx][5]);
- }
- }
- v->vc1dsp.vc1_v_s_overlap(v->block[v->cur_blk_idx][0],
- v->block[v->cur_blk_idx][2]);
- v->vc1dsp.vc1_v_s_overlap(v->block[v->cur_blk_idx][1],
- v->block[v->cur_blk_idx][3]);
- }
- }
- if (s->mb_x && (v->condover == CONDOVER_ALL || v->over_flags_plane[mb_pos - 1])) {
- if (!s->first_slice_line && (v->condover == CONDOVER_ALL || v->pq >= 9 ||
- v->over_flags_plane[mb_pos - s->mb_stride - 1])) {
- v->vc1dsp.vc1_v_s_overlap(v->block[v->topleft_blk_idx][2],
- v->block[v->left_blk_idx][0]);
- v->vc1dsp.vc1_v_s_overlap(v->block[v->topleft_blk_idx][3],
- v->block[v->left_blk_idx][1]);
- if (!(s->flags & CODEC_FLAG_GRAY)) {
- v->vc1dsp.vc1_v_s_overlap(v->block[v->topleft_blk_idx][4],
- v->block[v->left_blk_idx][4]);
- v->vc1dsp.vc1_v_s_overlap(v->block[v->topleft_blk_idx][5],
- v->block[v->left_blk_idx][5]);
- }
- }
- v->vc1dsp.vc1_v_s_overlap(v->block[v->left_blk_idx][0],
- v->block[v->left_blk_idx][2]);
- v->vc1dsp.vc1_v_s_overlap(v->block[v->left_blk_idx][1],
- v->block[v->left_blk_idx][3]);
- }
-}
-
-/** Do motion compensation over 1 macroblock
- * Mostly adapted hpel_motion and qpel_motion from mpegvideo.c
- */
-static void vc1_mc_1mv(VC1Context *v, int dir)
-{
- MpegEncContext *s = &v->s;
- H264ChromaContext *h264chroma = &v->h264chroma;
- uint8_t *srcY, *srcU, *srcV;
- int dxy, mx, my, uvmx, uvmy, src_x, src_y, uvsrc_x, uvsrc_y;
- int v_edge_pos = s->v_edge_pos >> v->field_mode;
- int i;
- uint8_t (*luty)[256], (*lutuv)[256];
- int use_ic;
-
- if ((!v->field_mode ||
- (v->ref_field_type[dir] == 1 && v->cur_field_type == 1)) &&
- !v->s.last_picture.f->data[0])
- return;
-
- mx = s->mv[dir][0][0];
- my = s->mv[dir][0][1];
-
- // store motion vectors for further use in B frames
- if (s->pict_type == AV_PICTURE_TYPE_P) {
- for (i = 0; i < 4; i++) {
- s->current_picture.motion_val[1][s->block_index[i] + v->blocks_off][0] = mx;
- s->current_picture.motion_val[1][s->block_index[i] + v->blocks_off][1] = my;
- }
- }
-
- uvmx = (mx + ((mx & 3) == 3)) >> 1;
- uvmy = (my + ((my & 3) == 3)) >> 1;
- v->luma_mv[s->mb_x][0] = uvmx;
- v->luma_mv[s->mb_x][1] = uvmy;
-
- if (v->field_mode &&
- v->cur_field_type != v->ref_field_type[dir]) {
- my = my - 2 + 4 * v->cur_field_type;
- uvmy = uvmy - 2 + 4 * v->cur_field_type;
- }
-
- // fastuvmc shall be ignored for interlaced frame picture
- if (v->fastuvmc && (v->fcm != ILACE_FRAME)) {
- uvmx = uvmx + ((uvmx < 0) ? (uvmx & 1) : -(uvmx & 1));
- uvmy = uvmy + ((uvmy < 0) ? (uvmy & 1) : -(uvmy & 1));
- }
- if (!dir) {
- if (v->field_mode && (v->cur_field_type != v->ref_field_type[dir]) && v->second_field) {
- srcY = s->current_picture.f->data[0];
- srcU = s->current_picture.f->data[1];
- srcV = s->current_picture.f->data[2];
- luty = v->curr_luty;
- lutuv = v->curr_lutuv;
- use_ic = *v->curr_use_ic;
- } else {
- srcY = s->last_picture.f->data[0];
- srcU = s->last_picture.f->data[1];
- srcV = s->last_picture.f->data[2];
- luty = v->last_luty;
- lutuv = v->last_lutuv;
- use_ic = v->last_use_ic;
- }
- } else {
- srcY = s->next_picture.f->data[0];
- srcU = s->next_picture.f->data[1];
- srcV = s->next_picture.f->data[2];
- luty = v->next_luty;
- lutuv = v->next_lutuv;
- use_ic = v->next_use_ic;
- }
-
- if (!srcY || !srcU) {
- av_log(v->s.avctx, AV_LOG_ERROR, "Referenced frame missing.\n");
- return;
- }
-
- src_x = s->mb_x * 16 + (mx >> 2);
- src_y = s->mb_y * 16 + (my >> 2);
- uvsrc_x = s->mb_x * 8 + (uvmx >> 2);
- uvsrc_y = s->mb_y * 8 + (uvmy >> 2);
-
- if (v->profile != PROFILE_ADVANCED) {
- src_x = av_clip( src_x, -16, s->mb_width * 16);
- src_y = av_clip( src_y, -16, s->mb_height * 16);
- uvsrc_x = av_clip(uvsrc_x, -8, s->mb_width * 8);
- uvsrc_y = av_clip(uvsrc_y, -8, s->mb_height * 8);
- } else {
- src_x = av_clip( src_x, -17, s->avctx->coded_width);
- src_y = av_clip( src_y, -18, s->avctx->coded_height + 1);
- uvsrc_x = av_clip(uvsrc_x, -8, s->avctx->coded_width >> 1);
- uvsrc_y = av_clip(uvsrc_y, -8, s->avctx->coded_height >> 1);
- }
-
- srcY += src_y * s->linesize + src_x;
- srcU += uvsrc_y * s->uvlinesize + uvsrc_x;
- srcV += uvsrc_y * s->uvlinesize + uvsrc_x;
-
- if (v->field_mode && v->ref_field_type[dir]) {
- srcY += s->current_picture_ptr->f->linesize[0];
- srcU += s->current_picture_ptr->f->linesize[1];
- srcV += s->current_picture_ptr->f->linesize[2];
- }
-
- /* for grayscale we should not try to read from unknown area */
- if (s->flags & CODEC_FLAG_GRAY) {
- srcU = s->edge_emu_buffer + 18 * s->linesize;
- srcV = s->edge_emu_buffer + 18 * s->linesize;
- }
-
- if (v->rangeredfrm || use_ic
- || s->h_edge_pos < 22 || v_edge_pos < 22
- || (unsigned)(src_x - s->mspel) > s->h_edge_pos - (mx&3) - 16 - s->mspel * 3
- || (unsigned)(src_y - 1) > v_edge_pos - (my&3) - 16 - 3) {
- uint8_t *ubuf = s->edge_emu_buffer + 19 * s->linesize;
- uint8_t *vbuf = ubuf + 9 * s->uvlinesize;
-
- srcY -= s->mspel * (1 + 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(ubuf, 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(vbuf, srcV,
- s->uvlinesize, s->uvlinesize,
- 8 + 1, 8 + 1,
- uvsrc_x, uvsrc_y,
- s->h_edge_pos >> 1, v_edge_pos >> 1);
- srcU = ubuf;
- srcV = vbuf;
- /* if we deal with range reduction we need to scale source blocks */
- if (v->rangeredfrm) {
- int i, j;
- uint8_t *src, *src2;
-
- src = srcY;
- for (j = 0; j < 17 + s->mspel * 2; j++) {
- for (i = 0; i < 17 + s->mspel * 2; i++)
- src[i] = ((src[i] - 128) >> 1) + 128;
- src += s->linesize;
- }
- src = srcU;
- src2 = srcV;
- for (j = 0; j < 9; j++) {
- for (i = 0; i < 9; i++) {
- src[i] = ((src[i] - 128) >> 1) + 128;
- src2[i] = ((src2[i] - 128) >> 1) + 128;
- }
- src += s->uvlinesize;
- src2 += s->uvlinesize;
- }
- }
- /* if we deal with intensity compensation we need to scale source blocks */
- if (use_ic) {
- int i, j;
- uint8_t *src, *src2;
-
- src = srcY;
- for (j = 0; j < 17 + s->mspel * 2; j++) {
- int f = v->field_mode ? v->ref_field_type[dir] : ((j + src_y - s->mspel) & 1) ;
- for (i = 0; i < 17 + s->mspel * 2; i++)
- src[i] = luty[f][src[i]];
- src += s->linesize;
- }
- src = srcU;
- src2 = srcV;
- for (j = 0; j < 9; j++) {
- int f = v->field_mode ? v->ref_field_type[dir] : ((j + uvsrc_y) & 1);
- for (i = 0; i < 9; i++) {
- src[i] = lutuv[f][src[i]];
- src2[i] = lutuv[f][src2[i]];
- }
- src += s->uvlinesize;
- src2 += s->uvlinesize;
- }
- }
- srcY += s->mspel * (1 + s->linesize);
- }
-
- if (s->mspel) {
- dxy = ((my & 3) << 2) | (mx & 3);
- v->vc1dsp.put_vc1_mspel_pixels_tab[0][dxy](s->dest[0] , srcY , s->linesize, v->rnd);
- } else { // hpel mc - always used for luma
- dxy = (my & 2) | ((mx & 2) >> 1);
- if (!v->rnd)
- s->hdsp.put_pixels_tab[0][dxy](s->dest[0], srcY, s->linesize, 16);
- else
- s->hdsp.put_no_rnd_pixels_tab[0][dxy](s->dest[0], srcY, s->linesize, 16);
- }
-
- if (s->flags & CODEC_FLAG_GRAY) return;
- /* Chroma MC always uses qpel bilinear */
- uvmx = (uvmx & 3) << 1;
- uvmy = (uvmy & 3) << 1;
- if (!v->rnd) {
- h264chroma->put_h264_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy);
- h264chroma->put_h264_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy);
- } else {
- v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy);
- v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy);
- }
-}
-
-static inline int median4(int a, int b, int c, int d)
-{
- if (a < b) {
- if (c < d) return (FFMIN(b, d) + FFMAX(a, c)) / 2;
- else return (FFMIN(b, c) + FFMAX(a, d)) / 2;
- } else {
- if (c < d) return (FFMIN(a, d) + FFMAX(b, c)) / 2;
- else return (FFMIN(a, c) + FFMAX(b, d)) / 2;
- }
-}
-
-/** Do motion compensation for 4-MV macroblock - luminance block
- */
-static void vc1_mc_4mv_luma(VC1Context *v, int n, int dir, int avg)
-{
- MpegEncContext *s = &v->s;
- uint8_t *srcY;
- int dxy, mx, my, src_x, src_y;
- int off;
- int fieldmv = (v->fcm == ILACE_FRAME) ? v->blk_mv_type[s->block_index[n]] : 0;
- int v_edge_pos = s->v_edge_pos >> v->field_mode;
- uint8_t (*luty)[256];
- int use_ic;
-
- if ((!v->field_mode ||
- (v->ref_field_type[dir] == 1 && v->cur_field_type == 1)) &&
- !v->s.last_picture.f->data[0])
- return;
-
- mx = s->mv[dir][n][0];
- my = s->mv[dir][n][1];
-
- if (!dir) {
- if (v->field_mode && (v->cur_field_type != v->ref_field_type[dir]) && v->second_field) {
- srcY = s->current_picture.f->data[0];
- luty = v->curr_luty;
- use_ic = *v->curr_use_ic;
- } else {
- srcY = s->last_picture.f->data[0];
- luty = v->last_luty;
- use_ic = v->last_use_ic;
- }
- } else {
- srcY = s->next_picture.f->data[0];
- luty = v->next_luty;
- use_ic = v->next_use_ic;
- }
-
- if (!srcY) {
- av_log(v->s.avctx, AV_LOG_ERROR, "Referenced frame missing.\n");
- return;
- }
-
- if (v->field_mode) {
- if (v->cur_field_type != v->ref_field_type[dir])
- my = my - 2 + 4 * v->cur_field_type;
- }
-
- if (s->pict_type == AV_PICTURE_TYPE_P && n == 3 && v->field_mode) {
- int same_count = 0, opp_count = 0, k;
- int chosen_mv[2][4][2], f;
- int tx, ty;
- for (k = 0; k < 4; k++) {
- f = v->mv_f[0][s->block_index[k] + v->blocks_off];
- chosen_mv[f][f ? opp_count : same_count][0] = s->mv[0][k][0];
- chosen_mv[f][f ? opp_count : same_count][1] = s->mv[0][k][1];
- opp_count += f;
- same_count += 1 - f;
- }
- f = opp_count > same_count;
- switch (f ? opp_count : same_count) {
- case 4:
- tx = median4(chosen_mv[f][0][0], chosen_mv[f][1][0],
- chosen_mv[f][2][0], chosen_mv[f][3][0]);
- ty = median4(chosen_mv[f][0][1], chosen_mv[f][1][1],
- chosen_mv[f][2][1], chosen_mv[f][3][1]);
- break;
- case 3:
- tx = mid_pred(chosen_mv[f][0][0], chosen_mv[f][1][0], chosen_mv[f][2][0]);
- ty = mid_pred(chosen_mv[f][0][1], chosen_mv[f][1][1], chosen_mv[f][2][1]);
- break;
- case 2:
- tx = (chosen_mv[f][0][0] + chosen_mv[f][1][0]) / 2;
- ty = (chosen_mv[f][0][1] + chosen_mv[f][1][1]) / 2;
- break;
- default:
- av_assert0(0);
- }
- s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][0] = tx;
- s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][1] = ty;
- for (k = 0; k < 4; k++)
- v->mv_f[1][s->block_index[k] + v->blocks_off] = f;
- }
-
- if (v->fcm == ILACE_FRAME) { // not sure if needed for other types of picture
- int qx, qy;
- int width = s->avctx->coded_width;
- int height = s->avctx->coded_height >> 1;
- if (s->pict_type == AV_PICTURE_TYPE_P) {
- s->current_picture.motion_val[1][s->block_index[n] + v->blocks_off][0] = mx;
- s->current_picture.motion_val[1][s->block_index[n] + v->blocks_off][1] = my;
- }
- qx = (s->mb_x * 16) + (mx >> 2);
- qy = (s->mb_y * 8) + (my >> 3);
-
- if (qx < -17)
- mx -= 4 * (qx + 17);
- else if (qx > width)
- mx -= 4 * (qx - width);
- if (qy < -18)
- my -= 8 * (qy + 18);
- else if (qy > height + 1)
- my -= 8 * (qy - height - 1);
- }
-
- if ((v->fcm == ILACE_FRAME) && fieldmv)
- off = ((n > 1) ? s->linesize : 0) + (n & 1) * 8;
- else
- off = s->linesize * 4 * (n & 2) + (n & 1) * 8;
-
- src_x = s->mb_x * 16 + (n & 1) * 8 + (mx >> 2);
- if (!fieldmv)
- src_y = s->mb_y * 16 + (n & 2) * 4 + (my >> 2);
- else
- src_y = s->mb_y * 16 + ((n > 1) ? 1 : 0) + (my >> 2);
-
- if (v->profile != PROFILE_ADVANCED) {
- src_x = av_clip(src_x, -16, s->mb_width * 16);
- src_y = av_clip(src_y, -16, s->mb_height * 16);
- } else {
- src_x = av_clip(src_x, -17, s->avctx->coded_width);
- if (v->fcm == ILACE_FRAME) {
- if (src_y & 1)
- src_y = av_clip(src_y, -17, s->avctx->coded_height + 1);
- else
- src_y = av_clip(src_y, -18, s->avctx->coded_height);
- } else {
- src_y = av_clip(src_y, -18, s->avctx->coded_height + 1);
- }
- }
-
- srcY += src_y * s->linesize + src_x;
- if (v->field_mode && v->ref_field_type[dir])
- srcY += s->current_picture_ptr->f->linesize[0];
-
- if (fieldmv && !(src_y & 1))
- v_edge_pos--;
- if (fieldmv && (src_y & 1) && src_y < 4)
- src_y--;
- if (v->rangeredfrm || use_ic
- || s->h_edge_pos < 13 || v_edge_pos < 23
- || (unsigned)(src_x - s->mspel) > s->h_edge_pos - (mx & 3) - 8 - s->mspel * 2
- || (unsigned)(src_y - (s->mspel << fieldmv)) > v_edge_pos - (my & 3) - ((8 + s->mspel * 2) << fieldmv)) {
- srcY -= s->mspel * (1 + (s->linesize << fieldmv));
- /* check emulate edge stride and offset */
- s->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);
- srcY = s->edge_emu_buffer;
- /* if we deal with range reduction we need to scale source blocks */
- if (v->rangeredfrm) {
- int i, j;
- uint8_t *src;
-
- src = srcY;
- for (j = 0; j < 9 + s->mspel * 2; j++) {
- for (i = 0; i < 9 + s->mspel * 2; i++)
- src[i] = ((src[i] - 128) >> 1) + 128;
- src += s->linesize << fieldmv;
- }
- }
- /* if we deal with intensity compensation we need to scale source blocks */
- if (use_ic) {
- int i, j;
- uint8_t *src;
-
- src = srcY;
- for (j = 0; j < 9 + s->mspel * 2; j++) {
- int f = v->field_mode ? v->ref_field_type[dir] : (((j<<fieldmv)+src_y - (s->mspel << fieldmv)) & 1);
- for (i = 0; i < 9 + s->mspel * 2; i++)
- src[i] = luty[f][src[i]];
- src += s->linesize << fieldmv;
- }
- }
- srcY += s->mspel * (1 + (s->linesize << fieldmv));
- }
-
- if (s->mspel) {
- dxy = ((my & 3) << 2) | (mx & 3);
- if (avg)
- v->vc1dsp.avg_vc1_mspel_pixels_tab[1][dxy](s->dest[0] + off, srcY, s->linesize << fieldmv, v->rnd);
- else
- v->vc1dsp.put_vc1_mspel_pixels_tab[1][dxy](s->dest[0] + off, srcY, s->linesize << fieldmv, v->rnd);
- } else { // hpel mc - always used for luma
- dxy = (my & 2) | ((mx & 2) >> 1);
- if (!v->rnd)
- s->hdsp.put_pixels_tab[1][dxy](s->dest[0] + off, srcY, s->linesize, 8);
- else
- s->hdsp.put_no_rnd_pixels_tab[1][dxy](s->dest[0] + off, srcY, s->linesize, 8);
- }
-}
-
-static av_always_inline int get_chroma_mv(int *mvx, int *mvy, int *a, int flag, int *tx, int *ty)
-{
- int idx, i;
- static const int count[16] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4};
-
- idx = ((a[3] != flag) << 3)
- | ((a[2] != flag) << 2)
- | ((a[1] != flag) << 1)
- | (a[0] != flag);
- if (!idx) {
- *tx = median4(mvx[0], mvx[1], mvx[2], mvx[3]);
- *ty = median4(mvy[0], mvy[1], mvy[2], mvy[3]);
- return 4;
- } else if (count[idx] == 1) {
- switch (idx) {
- case 0x1:
- *tx = mid_pred(mvx[1], mvx[2], mvx[3]);
- *ty = mid_pred(mvy[1], mvy[2], mvy[3]);
- return 3;
- case 0x2:
- *tx = mid_pred(mvx[0], mvx[2], mvx[3]);
- *ty = mid_pred(mvy[0], mvy[2], mvy[3]);
- return 3;
- case 0x4:
- *tx = mid_pred(mvx[0], mvx[1], mvx[3]);
- *ty = mid_pred(mvy[0], mvy[1], mvy[3]);
- return 3;
- case 0x8:
- *tx = mid_pred(mvx[0], mvx[1], mvx[2]);
- *ty = mid_pred(mvy[0], mvy[1], mvy[2]);
- return 3;
- }
- } else if (count[idx] == 2) {
- int t1 = 0, t2 = 0;
- for (i = 0; i < 3; i++)
- if (!a[i]) {
- t1 = i;
- break;
- }
- for (i = t1 + 1; i < 4; i++)
- if (!a[i]) {
- t2 = i;
- break;
- }
- *tx = (mvx[t1] + mvx[t2]) / 2;
- *ty = (mvy[t1] + mvy[t2]) / 2;
- return 2;
- } else {
- return 0;
- }
- return -1;
-}
-
-/** Do motion compensation for 4-MV macroblock - both chroma blocks
- */
-static void vc1_mc_4mv_chroma(VC1Context *v, int dir)
-{
- MpegEncContext *s = &v->s;
- H264ChromaContext *h264chroma = &v->h264chroma;
- uint8_t *srcU, *srcV;
- int uvmx, uvmy, uvsrc_x, uvsrc_y;
- int k, tx = 0, ty = 0;
- int mvx[4], mvy[4], intra[4], mv_f[4];
- int valid_count;
- int chroma_ref_type = v->cur_field_type;
- int v_edge_pos = s->v_edge_pos >> v->field_mode;
- uint8_t (*lutuv)[256];
- int use_ic;
-
- if (!v->field_mode && !v->s.last_picture.f->data[0])
- return;
- if (s->flags & CODEC_FLAG_GRAY)
- return;
-
- for (k = 0; k < 4; k++) {
- mvx[k] = s->mv[dir][k][0];
- mvy[k] = s->mv[dir][k][1];
- intra[k] = v->mb_type[0][s->block_index[k]];
- if (v->field_mode)
- mv_f[k] = v->mv_f[dir][s->block_index[k] + v->blocks_off];
- }
-
- /* calculate chroma MV vector from four luma MVs */
- if (!v->field_mode || (v->field_mode && !v->numref)) {
- valid_count = get_chroma_mv(mvx, mvy, intra, 0, &tx, &ty);
- chroma_ref_type = v->reffield;
- if (!valid_count) {
- s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][0] = 0;
- s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][1] = 0;
- v->luma_mv[s->mb_x][0] = v->luma_mv[s->mb_x][1] = 0;
- return; //no need to do MC for intra blocks
- }
- } else {
- int dominant = 0;
- if (mv_f[0] + mv_f[1] + mv_f[2] + mv_f[3] > 2)
- dominant = 1;
- valid_count = get_chroma_mv(mvx, mvy, mv_f, dominant, &tx, &ty);
- if (dominant)
- chroma_ref_type = !v->cur_field_type;
- }
- if (v->field_mode && chroma_ref_type == 1 && v->cur_field_type == 1 && !v->s.last_picture.f->data[0])
- return;
- s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][0] = tx;
- s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][1] = ty;
- uvmx = (tx + ((tx & 3) == 3)) >> 1;
- uvmy = (ty + ((ty & 3) == 3)) >> 1;
-
- v->luma_mv[s->mb_x][0] = uvmx;
- v->luma_mv[s->mb_x][1] = uvmy;
-
- if (v->fastuvmc) {
- uvmx = uvmx + ((uvmx < 0) ? (uvmx & 1) : -(uvmx & 1));
- uvmy = uvmy + ((uvmy < 0) ? (uvmy & 1) : -(uvmy & 1));
- }
- // Field conversion bias
- if (v->cur_field_type != chroma_ref_type)
- uvmy += 2 - 4 * chroma_ref_type;
-
- uvsrc_x = s->mb_x * 8 + (uvmx >> 2);
- uvsrc_y = s->mb_y * 8 + (uvmy >> 2);
-
- if (v->profile != PROFILE_ADVANCED) {
- uvsrc_x = av_clip(uvsrc_x, -8, s->mb_width * 8);
- uvsrc_y = av_clip(uvsrc_y, -8, s->mb_height * 8);
- } else {
- uvsrc_x = av_clip(uvsrc_x, -8, s->avctx->coded_width >> 1);
- uvsrc_y = av_clip(uvsrc_y, -8, s->avctx->coded_height >> 1);
- }
-
- if (!dir) {
- if (v->field_mode && (v->cur_field_type != chroma_ref_type) && v->second_field) {
- srcU = s->current_picture.f->data[1];
- srcV = s->current_picture.f->data[2];
- lutuv = v->curr_lutuv;
- use_ic = *v->curr_use_ic;
- } else {
- srcU = s->last_picture.f->data[1];
- srcV = s->last_picture.f->data[2];
- lutuv = v->last_lutuv;
- use_ic = v->last_use_ic;
- }
- } else {
- srcU = s->next_picture.f->data[1];
- srcV = s->next_picture.f->data[2];
- lutuv = v->next_lutuv;
- use_ic = v->next_use_ic;
- }
-
- if (!srcU) {
- av_log(v->s.avctx, AV_LOG_ERROR, "Referenced frame missing.\n");
- return;
- }
-
- srcU += uvsrc_y * s->uvlinesize + uvsrc_x;
- srcV += uvsrc_y * s->uvlinesize + uvsrc_x;
-
- if (v->field_mode) {
- if (chroma_ref_type) {
- srcU += s->current_picture_ptr->f->linesize[1];
- srcV += s->current_picture_ptr->f->linesize[2];
- }
- }
-
- if (v->rangeredfrm || use_ic
- || 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, 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, 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;
-
- /* if we deal with range reduction we need to scale source blocks */
- if (v->rangeredfrm) {
- int i, j;
- uint8_t *src, *src2;
-
- src = srcU;
- src2 = srcV;
- for (j = 0; j < 9; j++) {
- for (i = 0; i < 9; i++) {
- src[i] = ((src[i] - 128) >> 1) + 128;
- src2[i] = ((src2[i] - 128) >> 1) + 128;
- }
- src += s->uvlinesize;
- src2 += s->uvlinesize;
- }
- }
- /* if we deal with intensity compensation we need to scale source blocks */
- if (use_ic) {
- int i, j;
- uint8_t *src, *src2;
-
- src = srcU;
- src2 = srcV;
- for (j = 0; j < 9; j++) {
- int f = v->field_mode ? chroma_ref_type : ((j + uvsrc_y) & 1);
- for (i = 0; i < 9; i++) {
- src[i] = lutuv[f][src[i]];
- src2[i] = lutuv[f][src2[i]];
- }
- src += s->uvlinesize;
- src2 += s->uvlinesize;
- }
- }
- }
-
- /* Chroma MC always uses qpel bilinear */
- uvmx = (uvmx & 3) << 1;
- uvmy = (uvmy & 3) << 1;
- if (!v->rnd) {
- h264chroma->put_h264_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy);
- h264chroma->put_h264_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy);
- } else {
- v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy);
- v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy);
- }
-}
-
-/** Do motion compensation for 4-MV interlaced frame chroma macroblock (both U and V)
- */
-static void vc1_mc_4mv_chroma4(VC1Context *v, int dir, int dir2, int avg)
-{
- MpegEncContext *s = &v->s;
- H264ChromaContext *h264chroma = &v->h264chroma;
- uint8_t *srcU, *srcV;
- int uvsrc_x, uvsrc_y;
- int uvmx_field[4], uvmy_field[4];
- int i, off, tx, ty;
- int fieldmv = v->blk_mv_type[s->block_index[0]];
- static const int s_rndtblfield[16] = { 0, 0, 1, 2, 4, 4, 5, 6, 2, 2, 3, 8, 6, 6, 7, 12 };
- int v_dist = fieldmv ? 1 : 4; // vertical offset for lower sub-blocks
- int v_edge_pos = s->v_edge_pos >> 1;
- int use_ic;
- uint8_t (*lutuv)[256];
-
- if (s->flags & CODEC_FLAG_GRAY)
- return;
-
- for (i = 0; i < 4; i++) {
- int d = i < 2 ? dir: dir2;
- tx = s->mv[d][i][0];
- uvmx_field[i] = (tx + ((tx & 3) == 3)) >> 1;
- ty = s->mv[d][i][1];
- if (fieldmv)
- uvmy_field[i] = (ty >> 4) * 8 + s_rndtblfield[ty & 0xF];
- else
- uvmy_field[i] = (ty + ((ty & 3) == 3)) >> 1;
- }
-
- for (i = 0; i < 4; i++) {
- off = (i & 1) * 4 + ((i & 2) ? v_dist * s->uvlinesize : 0);
- uvsrc_x = s->mb_x * 8 + (i & 1) * 4 + (uvmx_field[i] >> 2);
- uvsrc_y = s->mb_y * 8 + ((i & 2) ? v_dist : 0) + (uvmy_field[i] >> 2);
- // FIXME: implement proper pull-back (see vc1cropmv.c, vc1CROPMV_ChromaPullBack())
- uvsrc_x = av_clip(uvsrc_x, -8, s->avctx->coded_width >> 1);
- uvsrc_y = av_clip(uvsrc_y, -8, s->avctx->coded_height >> 1);
- if (i < 2 ? dir : dir2) {
- srcU = s->next_picture.f->data[1];
- srcV = s->next_picture.f->data[2];
- lutuv = v->next_lutuv;
- use_ic = v->next_use_ic;
- } else {
- srcU = s->last_picture.f->data[1];
- srcV = s->last_picture.f->data[2];
- lutuv = v->last_lutuv;
- use_ic = v->last_use_ic;
- }
- if (!srcU)
- return;
- srcU += uvsrc_y * s->uvlinesize + uvsrc_x;
- srcV += uvsrc_y * s->uvlinesize + uvsrc_x;
- uvmx_field[i] = (uvmx_field[i] & 3) << 1;
- uvmy_field[i] = (uvmy_field[i] & 3) << 1;
-
- if (fieldmv && !(uvsrc_y & 1))
- v_edge_pos = (s->v_edge_pos >> 1) - 1;
-
- if (fieldmv && (uvsrc_y & 1) && uvsrc_y < 2)
- uvsrc_y--;
- if (use_ic
- || 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, 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;
-
- /* if we deal with intensity compensation we need to scale source blocks */
- if (use_ic) {
- int i, j;
- uint8_t *src, *src2;
-
- src = srcU;
- src2 = srcV;
- for (j = 0; j < 5; j++) {
- int f = (uvsrc_y + (j << fieldmv)) & 1;
- for (i = 0; i < 5; i++) {
- src[i] = lutuv[f][src[i]];
- src2[i] = lutuv[f][src2[i]];
- }
- src += s->uvlinesize << fieldmv;
- src2 += s->uvlinesize << fieldmv;
- }
- }
- }
- if (avg) {
- if (!v->rnd) {
- h264chroma->avg_h264_chroma_pixels_tab[1](s->dest[1] + off, srcU, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
- h264chroma->avg_h264_chroma_pixels_tab[1](s->dest[2] + off, srcV, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
- } else {
- v->vc1dsp.avg_no_rnd_vc1_chroma_pixels_tab[1](s->dest[1] + off, srcU, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
- v->vc1dsp.avg_no_rnd_vc1_chroma_pixels_tab[1](s->dest[2] + off, srcV, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
- }
- } else {
- if (!v->rnd) {
- h264chroma->put_h264_chroma_pixels_tab[1](s->dest[1] + off, srcU, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
- h264chroma->put_h264_chroma_pixels_tab[1](s->dest[2] + off, srcV, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
- } else {
- v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[1](s->dest[1] + off, srcU, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
- v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[1](s->dest[2] + off, srcV, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
- }
- }
- }
-}
-
-/***********************************************************************/
-/**
- * @name VC-1 Block-level functions
- * @see 7.1.4, p91 and 8.1.1.7, p(1)04
- * @{
- */
-
-/**
- * @def GET_MQUANT
- * @brief Get macroblock-level quantizer scale
- */
-#define GET_MQUANT() \
- if (v->dquantfrm) { \
- int edges = 0; \
- if (v->dqprofile == DQPROFILE_ALL_MBS) { \
- if (v->dqbilevel) { \
- mquant = (get_bits1(gb)) ? v->altpq : v->pq; \
- } else { \
- mqdiff = get_bits(gb, 3); \
- if (mqdiff != 7) \
- mquant = v->pq + mqdiff; \
- else \
- mquant = get_bits(gb, 5); \
- } \
- } \
- if (v->dqprofile == DQPROFILE_SINGLE_EDGE) \
- edges = 1 << v->dqsbedge; \
- else if (v->dqprofile == DQPROFILE_DOUBLE_EDGES) \
- edges = (3 << v->dqsbedge) % 15; \
- else if (v->dqprofile == DQPROFILE_FOUR_EDGES) \
- edges = 15; \
- if ((edges&1) && !s->mb_x) \
- mquant = v->altpq; \
- if ((edges&2) && s->first_slice_line) \
- mquant = v->altpq; \
- if ((edges&4) && s->mb_x == (s->mb_width - 1)) \
- mquant = v->altpq; \
- if ((edges&8) && s->mb_y == (s->mb_height - 1)) \
- mquant = v->altpq; \
- if (!mquant || mquant > 31) { \
- av_log(v->s.avctx, AV_LOG_ERROR, \
- "Overriding invalid mquant %d\n", mquant); \
- mquant = 1; \
- } \
- }
-
-/**
- * @def GET_MVDATA(_dmv_x, _dmv_y)
- * @brief Get MV differentials
- * @see MVDATA decoding from 8.3.5.2, p(1)20
- * @param _dmv_x Horizontal differential for decoded MV
- * @param _dmv_y Vertical differential for decoded MV
- */
-#define GET_MVDATA(_dmv_x, _dmv_y) \
- index = 1 + get_vlc2(gb, ff_vc1_mv_diff_vlc[s->mv_table_index].table, \
- VC1_MV_DIFF_VLC_BITS, 2); \
- if (index > 36) { \
- mb_has_coeffs = 1; \
- index -= 37; \
- } else \
- mb_has_coeffs = 0; \
- s->mb_intra = 0; \
- if (!index) { \
- _dmv_x = _dmv_y = 0; \
- } else if (index == 35) { \
- _dmv_x = get_bits(gb, v->k_x - 1 + s->quarter_sample); \
- _dmv_y = get_bits(gb, v->k_y - 1 + s->quarter_sample); \
- } else if (index == 36) { \
- _dmv_x = 0; \
- _dmv_y = 0; \
- s->mb_intra = 1; \
- } else { \
- index1 = index % 6; \
- if (!s->quarter_sample && index1 == 5) val = 1; \
- else val = 0; \
- if (size_table[index1] - val > 0) \
- val = get_bits(gb, size_table[index1] - val); \
- else val = 0; \
- sign = 0 - (val&1); \
- _dmv_x = (sign ^ ((val>>1) + offset_table[index1])) - sign; \
- \
- index1 = index / 6; \
- if (!s->quarter_sample && index1 == 5) val = 1; \
- else val = 0; \
- if (size_table[index1] - val > 0) \
- val = get_bits(gb, size_table[index1] - val); \
- else val = 0; \
- sign = 0 - (val & 1); \
- _dmv_y = (sign ^ ((val >> 1) + offset_table[index1])) - sign; \
- }
-
-static av_always_inline void get_mvdata_interlaced(VC1Context *v, int *dmv_x,
- int *dmv_y, int *pred_flag)
-{
- int index, index1;
- int extend_x = 0, extend_y = 0;
- GetBitContext *gb = &v->s.gb;
- int bits, esc;
- int val, sign;
- const int* offs_tab;
-
- if (v->numref) {
- bits = VC1_2REF_MVDATA_VLC_BITS;
- esc = 125;
- } else {
- bits = VC1_1REF_MVDATA_VLC_BITS;
- esc = 71;
- }
- switch (v->dmvrange) {
- case 1:
- extend_x = 1;
- break;
- case 2:
- extend_y = 1;
- break;
- case 3:
- extend_x = extend_y = 1;
- break;
- }
- index = get_vlc2(gb, v->imv_vlc->table, bits, 3);
- if (index == esc) {
- *dmv_x = get_bits(gb, v->k_x);
- *dmv_y = get_bits(gb, v->k_y);
- if (v->numref) {
- if (pred_flag) {
- *pred_flag = *dmv_y & 1;
- *dmv_y = (*dmv_y + *pred_flag) >> 1;
- } else {
- *dmv_y = (*dmv_y + (*dmv_y & 1)) >> 1;
- }
- }
- }
- else {
- av_assert0(index < esc);
- if (extend_x)
- offs_tab = offset_table2;
- else
- offs_tab = offset_table1;
- index1 = (index + 1) % 9;
- if (index1 != 0) {
- val = get_bits(gb, index1 + extend_x);
- sign = 0 -(val & 1);
- *dmv_x = (sign ^ ((val >> 1) + offs_tab[index1])) - sign;
- } else
- *dmv_x = 0;
- if (extend_y)
- offs_tab = offset_table2;
- else
- offs_tab = offset_table1;
- index1 = (index + 1) / 9;
- if (index1 > v->numref) {
- val = get_bits(gb, (index1 + (extend_y << v->numref)) >> v->numref);
- sign = 0 - (val & 1);
- *dmv_y = (sign ^ ((val >> 1) + offs_tab[index1 >> v->numref])) - sign;
- } else
- *dmv_y = 0;
- if (v->numref && pred_flag)
- *pred_flag = index1 & 1;
- }
-}
-
-static av_always_inline int scaleforsame_x(VC1Context *v, int n /* MV */, int dir)
-{
- int scaledvalue, refdist;
- int scalesame1, scalesame2;
- int scalezone1_x, zone1offset_x;
- int table_index = dir ^ v->second_field;
-
- if (v->s.pict_type != AV_PICTURE_TYPE_B)
- refdist = v->refdist;
- else
- refdist = dir ? v->brfd : v->frfd;
- if (refdist > 3)
- refdist = 3;
- scalesame1 = ff_vc1_field_mvpred_scales[table_index][1][refdist];
- scalesame2 = ff_vc1_field_mvpred_scales[table_index][2][refdist];
- scalezone1_x = ff_vc1_field_mvpred_scales[table_index][3][refdist];
- zone1offset_x = ff_vc1_field_mvpred_scales[table_index][5][refdist];
-
- if (FFABS(n) > 255)
- scaledvalue = n;
- else {
- if (FFABS(n) < scalezone1_x)
- scaledvalue = (n * scalesame1) >> 8;
- else {
- if (n < 0)
- scaledvalue = ((n * scalesame2) >> 8) - zone1offset_x;
- else
- scaledvalue = ((n * scalesame2) >> 8) + zone1offset_x;
- }
- }
- return av_clip(scaledvalue, -v->range_x, v->range_x - 1);
-}
-
-static av_always_inline int scaleforsame_y(VC1Context *v, int i, int n /* MV */, int dir)
-{
- int scaledvalue, refdist;
- int scalesame1, scalesame2;
- int scalezone1_y, zone1offset_y;
- int table_index = dir ^ v->second_field;
-
- if (v->s.pict_type != AV_PICTURE_TYPE_B)
- refdist = v->refdist;
- else
- refdist = dir ? v->brfd : v->frfd;
- if (refdist > 3)
- refdist = 3;
- scalesame1 = ff_vc1_field_mvpred_scales[table_index][1][refdist];
- scalesame2 = ff_vc1_field_mvpred_scales[table_index][2][refdist];
- scalezone1_y = ff_vc1_field_mvpred_scales[table_index][4][refdist];
- zone1offset_y = ff_vc1_field_mvpred_scales[table_index][6][refdist];
-
- if (FFABS(n) > 63)
- scaledvalue = n;
- else {
- if (FFABS(n) < scalezone1_y)
- scaledvalue = (n * scalesame1) >> 8;
- else {
- if (n < 0)
- scaledvalue = ((n * scalesame2) >> 8) - zone1offset_y;
- else
- scaledvalue = ((n * scalesame2) >> 8) + zone1offset_y;
- }
- }
-
- if (v->cur_field_type && !v->ref_field_type[dir])
- return av_clip(scaledvalue, -v->range_y / 2 + 1, v->range_y / 2);
- else
- return av_clip(scaledvalue, -v->range_y / 2, v->range_y / 2 - 1);
-}
-
-static av_always_inline int scaleforopp_x(VC1Context *v, int n /* MV */)
-{
- int scalezone1_x, zone1offset_x;
- int scaleopp1, scaleopp2, brfd;
- int scaledvalue;
-
- brfd = FFMIN(v->brfd, 3);
- scalezone1_x = ff_vc1_b_field_mvpred_scales[3][brfd];
- zone1offset_x = ff_vc1_b_field_mvpred_scales[5][brfd];
- scaleopp1 = ff_vc1_b_field_mvpred_scales[1][brfd];
- scaleopp2 = ff_vc1_b_field_mvpred_scales[2][brfd];
-
- if (FFABS(n) > 255)
- scaledvalue = n;
- else {
- if (FFABS(n) < scalezone1_x)
- scaledvalue = (n * scaleopp1) >> 8;
- else {
- if (n < 0)
- scaledvalue = ((n * scaleopp2) >> 8) - zone1offset_x;
- else
- scaledvalue = ((n * scaleopp2) >> 8) + zone1offset_x;
- }
- }
- return av_clip(scaledvalue, -v->range_x, v->range_x - 1);
-}
-
-static av_always_inline int scaleforopp_y(VC1Context *v, int n /* MV */, int dir)
-{
- int scalezone1_y, zone1offset_y;
- int scaleopp1, scaleopp2, brfd;
- int scaledvalue;
-
- brfd = FFMIN(v->brfd, 3);
- scalezone1_y = ff_vc1_b_field_mvpred_scales[4][brfd];
- zone1offset_y = ff_vc1_b_field_mvpred_scales[6][brfd];
- scaleopp1 = ff_vc1_b_field_mvpred_scales[1][brfd];
- scaleopp2 = ff_vc1_b_field_mvpred_scales[2][brfd];
-
- if (FFABS(n) > 63)
- scaledvalue = n;
- else {
- if (FFABS(n) < scalezone1_y)
- scaledvalue = (n * scaleopp1) >> 8;
- else {
- if (n < 0)
- scaledvalue = ((n * scaleopp2) >> 8) - zone1offset_y;
- else
- scaledvalue = ((n * scaleopp2) >> 8) + zone1offset_y;
- }
- }
- if (v->cur_field_type && !v->ref_field_type[dir]) {
- return av_clip(scaledvalue, -v->range_y / 2 + 1, v->range_y / 2);
- } else {
- return av_clip(scaledvalue, -v->range_y / 2, v->range_y / 2 - 1);
- }
-}
-
-static av_always_inline int scaleforsame(VC1Context *v, int i, int n /* MV */,
- int dim, int dir)
-{
- int brfd, scalesame;
- int hpel = 1 - v->s.quarter_sample;
-
- n >>= hpel;
- if (v->s.pict_type != AV_PICTURE_TYPE_B || v->second_field || !dir) {
- if (dim)
- n = scaleforsame_y(v, i, n, dir) << hpel;
- else
- n = scaleforsame_x(v, n, dir) << hpel;
- return n;
- }
- brfd = FFMIN(v->brfd, 3);
- scalesame = ff_vc1_b_field_mvpred_scales[0][brfd];
-
- n = (n * scalesame >> 8) << hpel;
- return n;
-}
-
-static av_always_inline int scaleforopp(VC1Context *v, int n /* MV */,
- int dim, int dir)
-{
- int refdist, scaleopp;
- int hpel = 1 - v->s.quarter_sample;
-
- n >>= hpel;
- if (v->s.pict_type == AV_PICTURE_TYPE_B && !v->second_field && dir == 1) {
- if (dim)
- n = scaleforopp_y(v, n, dir) << hpel;
- else
- n = scaleforopp_x(v, n) << hpel;
- return n;
- }
- if (v->s.pict_type != AV_PICTURE_TYPE_B)
- refdist = FFMIN(v->refdist, 3);
- else
- refdist = dir ? v->brfd : v->frfd;
- scaleopp = ff_vc1_field_mvpred_scales[dir ^ v->second_field][0][refdist];
-
- n = (n * scaleopp >> 8) << hpel;
- return n;
-}
-
-/** Predict and set motion vector
- */
-static inline void vc1_pred_mv(VC1Context *v, int n, int dmv_x, int dmv_y,
- int mv1, int r_x, int r_y, uint8_t* is_intra,
- int pred_flag, int dir)
-{
- MpegEncContext *s = &v->s;
- int xy, wrap, off = 0;
- int16_t *A, *B, *C;
- int px, py;
- int sum;
- int mixedmv_pic, num_samefield = 0, num_oppfield = 0;
- int opposite, a_f, b_f, c_f;
- int16_t field_predA[2];
- int16_t field_predB[2];
- int16_t field_predC[2];
- int a_valid, b_valid, c_valid;
- int hybridmv_thresh, y_bias = 0;
-
- if (v->mv_mode == MV_PMODE_MIXED_MV ||
- ((v->mv_mode == MV_PMODE_INTENSITY_COMP) && (v->mv_mode2 == MV_PMODE_MIXED_MV)))
- mixedmv_pic = 1;
- else
- mixedmv_pic = 0;
- /* scale MV difference to be quad-pel */
- dmv_x <<= 1 - s->quarter_sample;
- dmv_y <<= 1 - s->quarter_sample;
-
- wrap = s->b8_stride;
- xy = s->block_index[n];
-
- if (s->mb_intra) {
- s->mv[0][n][0] = s->current_picture.motion_val[0][xy + v->blocks_off][0] = 0;
- s->mv[0][n][1] = s->current_picture.motion_val[0][xy + v->blocks_off][1] = 0;
- s->current_picture.motion_val[1][xy + v->blocks_off][0] = 0;
- s->current_picture.motion_val[1][xy + v->blocks_off][1] = 0;
- if (mv1) { /* duplicate motion data for 1-MV block */
- s->current_picture.motion_val[0][xy + 1 + v->blocks_off][0] = 0;
- s->current_picture.motion_val[0][xy + 1 + v->blocks_off][1] = 0;
- s->current_picture.motion_val[0][xy + wrap + v->blocks_off][0] = 0;
- s->current_picture.motion_val[0][xy + wrap + v->blocks_off][1] = 0;
- s->current_picture.motion_val[0][xy + wrap + 1 + v->blocks_off][0] = 0;
- s->current_picture.motion_val[0][xy + wrap + 1 + v->blocks_off][1] = 0;
- v->luma_mv[s->mb_x][0] = v->luma_mv[s->mb_x][1] = 0;
- s->current_picture.motion_val[1][xy + 1 + v->blocks_off][0] = 0;
- s->current_picture.motion_val[1][xy + 1 + v->blocks_off][1] = 0;
- s->current_picture.motion_val[1][xy + wrap][0] = 0;
- s->current_picture.motion_val[1][xy + wrap + v->blocks_off][1] = 0;
- s->current_picture.motion_val[1][xy + wrap + 1 + v->blocks_off][0] = 0;
- s->current_picture.motion_val[1][xy + wrap + 1 + v->blocks_off][1] = 0;
- }
- return;
- }
-
- C = s->current_picture.motion_val[dir][xy - 1 + v->blocks_off];
- A = s->current_picture.motion_val[dir][xy - wrap + v->blocks_off];
- if (mv1) {
- if (v->field_mode && mixedmv_pic)
- off = (s->mb_x == (s->mb_width - 1)) ? -2 : 2;
- else
- off = (s->mb_x == (s->mb_width - 1)) ? -1 : 2;
- } else {
- //in 4-MV mode different blocks have different B predictor position
- switch (n) {
- case 0:
- off = (s->mb_x > 0) ? -1 : 1;
- break;
- case 1:
- off = (s->mb_x == (s->mb_width - 1)) ? -1 : 1;
- break;
- case 2:
- off = 1;
- break;
- case 3:
- off = -1;
- }
- }
- B = s->current_picture.motion_val[dir][xy - wrap + off + v->blocks_off];
-
- a_valid = !s->first_slice_line || (n == 2 || n == 3);
- b_valid = a_valid && (s->mb_width > 1);
- c_valid = s->mb_x || (n == 1 || n == 3);
- if (v->field_mode) {
- a_valid = a_valid && !is_intra[xy - wrap];
- b_valid = b_valid && !is_intra[xy - wrap + off];
- c_valid = c_valid && !is_intra[xy - 1];
- }
-
- if (a_valid) {
- a_f = v->mv_f[dir][xy - wrap + v->blocks_off];
- num_oppfield += a_f;
- num_samefield += 1 - a_f;
- field_predA[0] = A[0];
- field_predA[1] = A[1];
- } else {
- field_predA[0] = field_predA[1] = 0;
- a_f = 0;
- }
- if (b_valid) {
- b_f = v->mv_f[dir][xy - wrap + off + v->blocks_off];
- num_oppfield += b_f;
- num_samefield += 1 - b_f;
- field_predB[0] = B[0];
- field_predB[1] = B[1];
- } else {
- field_predB[0] = field_predB[1] = 0;
- b_f = 0;
- }
- if (c_valid) {
- c_f = v->mv_f[dir][xy - 1 + v->blocks_off];
- num_oppfield += c_f;
- num_samefield += 1 - c_f;
- field_predC[0] = C[0];
- field_predC[1] = C[1];
- } else {
- field_predC[0] = field_predC[1] = 0;
- c_f = 0;
- }
-
- if (v->field_mode) {
- if (!v->numref)
- // REFFIELD determines if the last field or the second-last field is
- // to be used as reference
- opposite = 1 - v->reffield;
- else {
- if (num_samefield <= num_oppfield)
- opposite = 1 - pred_flag;
- else
- opposite = pred_flag;
- }
- } else
- opposite = 0;
- if (opposite) {
- if (a_valid && !a_f) {
- field_predA[0] = scaleforopp(v, field_predA[0], 0, dir);
- field_predA[1] = scaleforopp(v, field_predA[1], 1, dir);
- }
- if (b_valid && !b_f) {
- field_predB[0] = scaleforopp(v, field_predB[0], 0, dir);
- field_predB[1] = scaleforopp(v, field_predB[1], 1, dir);
- }
- if (c_valid && !c_f) {
- field_predC[0] = scaleforopp(v, field_predC[0], 0, dir);
- field_predC[1] = scaleforopp(v, field_predC[1], 1, dir);
- }
- v->mv_f[dir][xy + v->blocks_off] = 1;
- v->ref_field_type[dir] = !v->cur_field_type;
- } else {
- if (a_valid && a_f) {
- field_predA[0] = scaleforsame(v, n, field_predA[0], 0, dir);
- field_predA[1] = scaleforsame(v, n, field_predA[1], 1, dir);
- }
- if (b_valid && b_f) {
- field_predB[0] = scaleforsame(v, n, field_predB[0], 0, dir);
- field_predB[1] = scaleforsame(v, n, field_predB[1], 1, dir);
- }
- if (c_valid && c_f) {
- field_predC[0] = scaleforsame(v, n, field_predC[0], 0, dir);
- field_predC[1] = scaleforsame(v, n, field_predC[1], 1, dir);
- }
- v->mv_f[dir][xy + v->blocks_off] = 0;
- v->ref_field_type[dir] = v->cur_field_type;
- }
-
- if (a_valid) {
- px = field_predA[0];
- py = field_predA[1];
- } else if (c_valid) {
- px = field_predC[0];
- py = field_predC[1];
- } else if (b_valid) {
- px = field_predB[0];
- py = field_predB[1];
- } else {
- px = 0;
- py = 0;
- }
-
- if (num_samefield + num_oppfield > 1) {
- px = mid_pred(field_predA[0], field_predB[0], field_predC[0]);
- py = mid_pred(field_predA[1], field_predB[1], field_predC[1]);
- }
-
- /* Pullback MV as specified in 8.3.5.3.4 */
- if (!v->field_mode) {
- int qx, qy, X, Y;
- qx = (s->mb_x << 6) + ((n == 1 || n == 3) ? 32 : 0);
- qy = (s->mb_y << 6) + ((n == 2 || n == 3) ? 32 : 0);
- X = (s->mb_width << 6) - 4;
- Y = (s->mb_height << 6) - 4;
- if (mv1) {
- if (qx + px < -60) px = -60 - qx;
- if (qy + py < -60) py = -60 - qy;
- } else {
- if (qx + px < -28) px = -28 - qx;
- if (qy + py < -28) py = -28 - qy;
- }
- if (qx + px > X) px = X - qx;
- if (qy + py > Y) py = Y - qy;
- }
-
- if (!v->field_mode || s->pict_type != AV_PICTURE_TYPE_B) {
- /* Calculate hybrid prediction as specified in 8.3.5.3.5 (also 10.3.5.4.3.5) */
- hybridmv_thresh = 32;
- if (a_valid && c_valid) {
- if (is_intra[xy - wrap])
- sum = FFABS(px) + FFABS(py);
- else
- sum = FFABS(px - field_predA[0]) + FFABS(py - field_predA[1]);
- if (sum > hybridmv_thresh) {
- if (get_bits1(&s->gb)) { // read HYBRIDPRED bit
- px = field_predA[0];
- py = field_predA[1];
- } else {
- px = field_predC[0];
- py = field_predC[1];
- }
- } else {
- if (is_intra[xy - 1])
- sum = FFABS(px) + FFABS(py);
- else
- sum = FFABS(px - field_predC[0]) + FFABS(py - field_predC[1]);
- if (sum > hybridmv_thresh) {
- if (get_bits1(&s->gb)) {
- px = field_predA[0];
- py = field_predA[1];
- } else {
- px = field_predC[0];
- py = field_predC[1];
- }
- }
- }
- }
- }
-
- if (v->field_mode && v->numref)
- r_y >>= 1;
- if (v->field_mode && v->cur_field_type && v->ref_field_type[dir] == 0)
- y_bias = 1;
- /* store MV using signed modulus of MV range defined in 4.11 */
- s->mv[dir][n][0] = s->current_picture.motion_val[dir][xy + v->blocks_off][0] = ((px + dmv_x + r_x) & ((r_x << 1) - 1)) - r_x;
- s->mv[dir][n][1] = s->current_picture.motion_val[dir][xy + v->blocks_off][1] = ((py + dmv_y + r_y - y_bias) & ((r_y << 1) - 1)) - r_y + y_bias;
- if (mv1) { /* duplicate motion data for 1-MV block */
- s->current_picture.motion_val[dir][xy + 1 + v->blocks_off][0] = s->current_picture.motion_val[dir][xy + v->blocks_off][0];
- s->current_picture.motion_val[dir][xy + 1 + v->blocks_off][1] = s->current_picture.motion_val[dir][xy + v->blocks_off][1];
- s->current_picture.motion_val[dir][xy + wrap + v->blocks_off][0] = s->current_picture.motion_val[dir][xy + v->blocks_off][0];
- s->current_picture.motion_val[dir][xy + wrap + v->blocks_off][1] = s->current_picture.motion_val[dir][xy + v->blocks_off][1];
- s->current_picture.motion_val[dir][xy + wrap + 1 + v->blocks_off][0] = s->current_picture.motion_val[dir][xy + v->blocks_off][0];
- s->current_picture.motion_val[dir][xy + wrap + 1 + v->blocks_off][1] = s->current_picture.motion_val[dir][xy + v->blocks_off][1];
- v->mv_f[dir][xy + 1 + v->blocks_off] = v->mv_f[dir][xy + v->blocks_off];
- v->mv_f[dir][xy + wrap + v->blocks_off] = v->mv_f[dir][xy + wrap + 1 + v->blocks_off] = v->mv_f[dir][xy + v->blocks_off];
- }
-}
-
-/** Predict and set motion vector for interlaced frame picture MBs
- */
-static inline void vc1_pred_mv_intfr(VC1Context *v, int n, int dmv_x, int dmv_y,
- int mvn, int r_x, int r_y, uint8_t* is_intra, int dir)
-{
- MpegEncContext *s = &v->s;
- int xy, wrap, off = 0;
- int A[2], B[2], C[2];
- int px = 0, py = 0;
- int a_valid = 0, b_valid = 0, c_valid = 0;
- int field_a, field_b, field_c; // 0: same, 1: opposit
- int total_valid, num_samefield, num_oppfield;
- int pos_c, pos_b, n_adj;
-
- wrap = s->b8_stride;
- xy = s->block_index[n];
-
- if (s->mb_intra) {
- s->mv[0][n][0] = s->current_picture.motion_val[0][xy][0] = 0;
- s->mv[0][n][1] = s->current_picture.motion_val[0][xy][1] = 0;
- s->current_picture.motion_val[1][xy][0] = 0;
- s->current_picture.motion_val[1][xy][1] = 0;
- if (mvn == 1) { /* duplicate motion data for 1-MV block */
- s->current_picture.motion_val[0][xy + 1][0] = 0;
- s->current_picture.motion_val[0][xy + 1][1] = 0;
- s->current_picture.motion_val[0][xy + wrap][0] = 0;
- s->current_picture.motion_val[0][xy + wrap][1] = 0;
- s->current_picture.motion_val[0][xy + wrap + 1][0] = 0;
- s->current_picture.motion_val[0][xy + wrap + 1][1] = 0;
- v->luma_mv[s->mb_x][0] = v->luma_mv[s->mb_x][1] = 0;
- s->current_picture.motion_val[1][xy + 1][0] = 0;
- s->current_picture.motion_val[1][xy + 1][1] = 0;
- s->current_picture.motion_val[1][xy + wrap][0] = 0;
- s->current_picture.motion_val[1][xy + wrap][1] = 0;
- s->current_picture.motion_val[1][xy + wrap + 1][0] = 0;
- s->current_picture.motion_val[1][xy + wrap + 1][1] = 0;
- }
- return;
- }
-
- off = ((n == 0) || (n == 1)) ? 1 : -1;
- /* predict A */
- if (s->mb_x || (n == 1) || (n == 3)) {
- if ((v->blk_mv_type[xy]) // current block (MB) has a field MV
- || (!v->blk_mv_type[xy] && !v->blk_mv_type[xy - 1])) { // or both have frame MV
- A[0] = s->current_picture.motion_val[dir][xy - 1][0];
- A[1] = s->current_picture.motion_val[dir][xy - 1][1];
- a_valid = 1;
- } else { // current block has frame mv and cand. has field MV (so average)
- A[0] = (s->current_picture.motion_val[dir][xy - 1][0]
- + s->current_picture.motion_val[dir][xy - 1 + off * wrap][0] + 1) >> 1;
- A[1] = (s->current_picture.motion_val[dir][xy - 1][1]
- + s->current_picture.motion_val[dir][xy - 1 + off * wrap][1] + 1) >> 1;
- a_valid = 1;
- }
- if (!(n & 1) && v->is_intra[s->mb_x - 1]) {
- a_valid = 0;
- A[0] = A[1] = 0;
- }
- } else
- A[0] = A[1] = 0;
- /* Predict B and C */
- B[0] = B[1] = C[0] = C[1] = 0;
- if (n == 0 || n == 1 || v->blk_mv_type[xy]) {
- if (!s->first_slice_line) {
- if (!v->is_intra[s->mb_x - s->mb_stride]) {
- b_valid = 1;
- n_adj = n | 2;
- pos_b = s->block_index[n_adj] - 2 * wrap;
- if (v->blk_mv_type[pos_b] && v->blk_mv_type[xy]) {
- n_adj = (n & 2) | (n & 1);
- }
- B[0] = s->current_picture.motion_val[dir][s->block_index[n_adj] - 2 * wrap][0];
- B[1] = s->current_picture.motion_val[dir][s->block_index[n_adj] - 2 * wrap][1];
- if (v->blk_mv_type[pos_b] && !v->blk_mv_type[xy]) {
- B[0] = (B[0] + s->current_picture.motion_val[dir][s->block_index[n_adj ^ 2] - 2 * wrap][0] + 1) >> 1;
- B[1] = (B[1] + s->current_picture.motion_val[dir][s->block_index[n_adj ^ 2] - 2 * wrap][1] + 1) >> 1;
- }
- }
- if (s->mb_width > 1) {
- if (!v->is_intra[s->mb_x - s->mb_stride + 1]) {
- c_valid = 1;
- n_adj = 2;
- pos_c = s->block_index[2] - 2 * wrap + 2;
- if (v->blk_mv_type[pos_c] && v->blk_mv_type[xy]) {
- n_adj = n & 2;
- }
- C[0] = s->current_picture.motion_val[dir][s->block_index[n_adj] - 2 * wrap + 2][0];
- C[1] = s->current_picture.motion_val[dir][s->block_index[n_adj] - 2 * wrap + 2][1];
- if (v->blk_mv_type[pos_c] && !v->blk_mv_type[xy]) {
- C[0] = (1 + C[0] + (s->current_picture.motion_val[dir][s->block_index[n_adj ^ 2] - 2 * wrap + 2][0])) >> 1;
- C[1] = (1 + C[1] + (s->current_picture.motion_val[dir][s->block_index[n_adj ^ 2] - 2 * wrap + 2][1])) >> 1;
- }
- if (s->mb_x == s->mb_width - 1) {
- if (!v->is_intra[s->mb_x - s->mb_stride - 1]) {
- c_valid = 1;
- n_adj = 3;
- pos_c = s->block_index[3] - 2 * wrap - 2;
- if (v->blk_mv_type[pos_c] && v->blk_mv_type[xy]) {
- n_adj = n | 1;
- }
- C[0] = s->current_picture.motion_val[dir][s->block_index[n_adj] - 2 * wrap - 2][0];
- C[1] = s->current_picture.motion_val[dir][s->block_index[n_adj] - 2 * wrap - 2][1];
- if (v->blk_mv_type[pos_c] && !v->blk_mv_type[xy]) {
- C[0] = (1 + C[0] + s->current_picture.motion_val[dir][s->block_index[1] - 2 * wrap - 2][0]) >> 1;
- C[1] = (1 + C[1] + s->current_picture.motion_val[dir][s->block_index[1] - 2 * wrap - 2][1]) >> 1;
- }
- } else
- c_valid = 0;
- }
- }
- }
- }
- } else {
- pos_b = s->block_index[1];
- b_valid = 1;
- B[0] = s->current_picture.motion_val[dir][pos_b][0];
- B[1] = s->current_picture.motion_val[dir][pos_b][1];
- pos_c = s->block_index[0];
- c_valid = 1;
- C[0] = s->current_picture.motion_val[dir][pos_c][0];
- C[1] = s->current_picture.motion_val[dir][pos_c][1];
- }
-
- total_valid = a_valid + b_valid + c_valid;
- // check if predictor A is out of bounds
- if (!s->mb_x && !(n == 1 || n == 3)) {
- A[0] = A[1] = 0;
- }
- // check if predictor B is out of bounds
- if ((s->first_slice_line && v->blk_mv_type[xy]) || (s->first_slice_line && !(n & 2))) {
- B[0] = B[1] = C[0] = C[1] = 0;
- }
- if (!v->blk_mv_type[xy]) {
- if (s->mb_width == 1) {
- px = B[0];
- py = B[1];
- } else {
- if (total_valid >= 2) {
- px = mid_pred(A[0], B[0], C[0]);
- py = mid_pred(A[1], B[1], C[1]);
- } else if (total_valid) {
- if (a_valid) { px = A[0]; py = A[1]; }
- else if (b_valid) { px = B[0]; py = B[1]; }
- else { px = C[0]; py = C[1]; }
- }
- }
- } else {
- if (a_valid)
- field_a = (A[1] & 4) ? 1 : 0;
- else
- field_a = 0;
- if (b_valid)
- field_b = (B[1] & 4) ? 1 : 0;
- else
- field_b = 0;
- if (c_valid)
- field_c = (C[1] & 4) ? 1 : 0;
- else
- field_c = 0;
-
- num_oppfield = field_a + field_b + field_c;
- num_samefield = total_valid - num_oppfield;
- if (total_valid == 3) {
- if ((num_samefield == 3) || (num_oppfield == 3)) {
- px = mid_pred(A[0], B[0], C[0]);
- py = mid_pred(A[1], B[1], C[1]);
- } else if (num_samefield >= num_oppfield) {
- /* take one MV from same field set depending on priority
- the check for B may not be necessary */
- px = !field_a ? A[0] : B[0];
- py = !field_a ? A[1] : B[1];
- } else {
- px = field_a ? A[0] : B[0];
- py = field_a ? A[1] : B[1];
- }
- } else if (total_valid == 2) {
- if (num_samefield >= num_oppfield) {
- if (!field_a && a_valid) {
- px = A[0];
- py = A[1];
- } else if (!field_b && b_valid) {
- px = B[0];
- py = B[1];
- } else /*if (c_valid)*/ {
- av_assert1(c_valid);
- px = C[0];
- py = C[1];
- } /*else px = py = 0;*/
- } else {
- if (field_a && a_valid) {
- px = A[0];
- py = A[1];
- } else /*if (field_b && b_valid)*/ {
- av_assert1(field_b && b_valid);
- px = B[0];
- py = B[1];
- } /*else if (c_valid) {
- px = C[0];
- py = C[1];
- }*/
- }
- } else if (total_valid == 1) {
- px = (a_valid) ? A[0] : ((b_valid) ? B[0] : C[0]);
- py = (a_valid) ? A[1] : ((b_valid) ? B[1] : C[1]);
- }
- }
-
- /* store MV using signed modulus of MV range defined in 4.11 */
- s->mv[dir][n][0] = s->current_picture.motion_val[dir][xy][0] = ((px + dmv_x + r_x) & ((r_x << 1) - 1)) - r_x;
- s->mv[dir][n][1] = s->current_picture.motion_val[dir][xy][1] = ((py + dmv_y + r_y) & ((r_y << 1) - 1)) - r_y;
- if (mvn == 1) { /* duplicate motion data for 1-MV block */
- s->current_picture.motion_val[dir][xy + 1 ][0] = s->current_picture.motion_val[dir][xy][0];
- s->current_picture.motion_val[dir][xy + 1 ][1] = s->current_picture.motion_val[dir][xy][1];
- s->current_picture.motion_val[dir][xy + wrap ][0] = s->current_picture.motion_val[dir][xy][0];
- s->current_picture.motion_val[dir][xy + wrap ][1] = s->current_picture.motion_val[dir][xy][1];
- s->current_picture.motion_val[dir][xy + wrap + 1][0] = s->current_picture.motion_val[dir][xy][0];
- s->current_picture.motion_val[dir][xy + wrap + 1][1] = s->current_picture.motion_val[dir][xy][1];
- } else if (mvn == 2) { /* duplicate motion data for 2-Field MV block */
- s->current_picture.motion_val[dir][xy + 1][0] = s->current_picture.motion_val[dir][xy][0];
- s->current_picture.motion_val[dir][xy + 1][1] = s->current_picture.motion_val[dir][xy][1];
- s->mv[dir][n + 1][0] = s->mv[dir][n][0];
- s->mv[dir][n + 1][1] = s->mv[dir][n][1];
- }
-}
-
-/** Motion compensation for direct or interpolated blocks in B-frames
- */
-static void vc1_interp_mc(VC1Context *v)
-{
- MpegEncContext *s = &v->s;
- H264ChromaContext *h264chroma = &v->h264chroma;
- uint8_t *srcY, *srcU, *srcV;
- int dxy, mx, my, uvmx, uvmy, src_x, src_y, uvsrc_x, uvsrc_y;
- int off, off_uv;
- int v_edge_pos = s->v_edge_pos >> v->field_mode;
- int use_ic = v->next_use_ic;
-
- if (!v->field_mode && !v->s.next_picture.f->data[0])
- return;
-
- mx = s->mv[1][0][0];
- my = s->mv[1][0][1];
- uvmx = (mx + ((mx & 3) == 3)) >> 1;
- uvmy = (my + ((my & 3) == 3)) >> 1;
- if (v->field_mode) {
- if (v->cur_field_type != v->ref_field_type[1]) {
- my = my - 2 + 4 * v->cur_field_type;
- uvmy = uvmy - 2 + 4 * v->cur_field_type;
- }
- }
- if (v->fastuvmc) {
- uvmx = uvmx + ((uvmx < 0) ? -(uvmx & 1) : (uvmx & 1));
- uvmy = uvmy + ((uvmy < 0) ? -(uvmy & 1) : (uvmy & 1));
- }
- srcY = s->next_picture.f->data[0];
- srcU = s->next_picture.f->data[1];
- srcV = s->next_picture.f->data[2];
-
- src_x = s->mb_x * 16 + (mx >> 2);
- src_y = s->mb_y * 16 + (my >> 2);
- uvsrc_x = s->mb_x * 8 + (uvmx >> 2);
- uvsrc_y = s->mb_y * 8 + (uvmy >> 2);
-
- if (v->profile != PROFILE_ADVANCED) {
- src_x = av_clip( src_x, -16, s->mb_width * 16);
- src_y = av_clip( src_y, -16, s->mb_height * 16);
- uvsrc_x = av_clip(uvsrc_x, -8, s->mb_width * 8);
- uvsrc_y = av_clip(uvsrc_y, -8, s->mb_height * 8);
- } else {
- src_x = av_clip( src_x, -17, s->avctx->coded_width);
- src_y = av_clip( src_y, -18, s->avctx->coded_height + 1);
- uvsrc_x = av_clip(uvsrc_x, -8, s->avctx->coded_width >> 1);
- uvsrc_y = av_clip(uvsrc_y, -8, s->avctx->coded_height >> 1);
- }
-
- srcY += src_y * s->linesize + src_x;
- srcU += uvsrc_y * s->uvlinesize + uvsrc_x;
- srcV += uvsrc_y * s->uvlinesize + uvsrc_x;
-
- if (v->field_mode && v->ref_field_type[1]) {
- srcY += s->current_picture_ptr->f->linesize[0];
- srcU += s->current_picture_ptr->f->linesize[1];
- srcV += s->current_picture_ptr->f->linesize[2];
- }
-
- /* for grayscale we should not try to read from unknown area */
- if (s->flags & CODEC_FLAG_GRAY) {
- srcU = s->edge_emu_buffer + 18 * s->linesize;
- srcV = s->edge_emu_buffer + 18 * s->linesize;
- }
-
- if (v->rangeredfrm || s->h_edge_pos < 22 || v_edge_pos < 22 || use_ic
- || (unsigned)(src_x - 1) > s->h_edge_pos - (mx & 3) - 16 - 3
- || (unsigned)(src_y - 1) > v_edge_pos - (my & 3) - 16 - 3) {
- uint8_t *ubuf = s->edge_emu_buffer + 19 * s->linesize;
- uint8_t *vbuf = ubuf + 9 * s->uvlinesize;
-
- srcY -= s->mspel * (1 + 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(ubuf, 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(vbuf, srcV,
- s->uvlinesize, s->uvlinesize,
- 8 + 1, 8 + 1,
- uvsrc_x, uvsrc_y,
- s->h_edge_pos >> 1, v_edge_pos >> 1);
- srcU = ubuf;
- srcV = vbuf;
- /* if we deal with range reduction we need to scale source blocks */
- if (v->rangeredfrm) {
- int i, j;
- uint8_t *src, *src2;
-
- src = srcY;
- for (j = 0; j < 17 + s->mspel * 2; j++) {
- for (i = 0; i < 17 + s->mspel * 2; i++)
- src[i] = ((src[i] - 128) >> 1) + 128;
- src += s->linesize;
- }
- src = srcU;
- src2 = srcV;
- for (j = 0; j < 9; j++) {
- for (i = 0; i < 9; i++) {
- src[i] = ((src[i] - 128) >> 1) + 128;
- src2[i] = ((src2[i] - 128) >> 1) + 128;
- }
- src += s->uvlinesize;
- src2 += s->uvlinesize;
- }
- }
-
- if (use_ic) {
- uint8_t (*luty )[256] = v->next_luty;
- uint8_t (*lutuv)[256] = v->next_lutuv;
- int i, j;
- uint8_t *src, *src2;
-
- src = srcY;
- for (j = 0; j < 17 + s->mspel * 2; j++) {
- int f = v->field_mode ? v->ref_field_type[1] : ((j+src_y - s->mspel) & 1);
- for (i = 0; i < 17 + s->mspel * 2; i++)
- src[i] = luty[f][src[i]];
- src += s->linesize;
- }
- src = srcU;
- src2 = srcV;
- for (j = 0; j < 9; j++) {
- int f = v->field_mode ? v->ref_field_type[1] : ((j+uvsrc_y) & 1);
- for (i = 0; i < 9; i++) {
- src[i] = lutuv[f][src[i]];
- src2[i] = lutuv[f][src2[i]];
- }
- src += s->uvlinesize;
- src2 += s->uvlinesize;
- }
- }
- srcY += s->mspel * (1 + s->linesize);
- }
-
- off = 0;
- off_uv = 0;
-
- if (s->mspel) {
- dxy = ((my & 3) << 2) | (mx & 3);
- v->vc1dsp.avg_vc1_mspel_pixels_tab[0][dxy](s->dest[0] + off , srcY , s->linesize, v->rnd);
- } else { // hpel mc
- dxy = (my & 2) | ((mx & 2) >> 1);
-
- if (!v->rnd)
- s->hdsp.avg_pixels_tab[0][dxy](s->dest[0] + off, srcY, s->linesize, 16);
- else
- s->hdsp.avg_no_rnd_pixels_tab[dxy](s->dest[0] + off, srcY, s->linesize, 16);
- }
-
- if (s->flags & CODEC_FLAG_GRAY) return;
- /* Chroma MC always uses qpel blilinear */
- uvmx = (uvmx & 3) << 1;
- uvmy = (uvmy & 3) << 1;
- if (!v->rnd) {
- h264chroma->avg_h264_chroma_pixels_tab[0](s->dest[1] + off_uv, srcU, s->uvlinesize, 8, uvmx, uvmy);
- h264chroma->avg_h264_chroma_pixels_tab[0](s->dest[2] + off_uv, srcV, s->uvlinesize, 8, uvmx, uvmy);
- } else {
- v->vc1dsp.avg_no_rnd_vc1_chroma_pixels_tab[0](s->dest[1] + off_uv, srcU, s->uvlinesize, 8, uvmx, uvmy);
- v->vc1dsp.avg_no_rnd_vc1_chroma_pixels_tab[0](s->dest[2] + off_uv, srcV, s->uvlinesize, 8, uvmx, uvmy);
- }
-}
-
-static av_always_inline int scale_mv(int value, int bfrac, int inv, int qs)
-{
- int n = bfrac;
-
-#if B_FRACTION_DEN==256
- if (inv)
- n -= 256;
- if (!qs)
- return 2 * ((value * n + 255) >> 9);
- return (value * n + 128) >> 8;
-#else
- if (inv)
- n -= B_FRACTION_DEN;
- if (!qs)
- return 2 * ((value * n + B_FRACTION_DEN - 1) / (2 * B_FRACTION_DEN));
- return (value * n + B_FRACTION_DEN/2) / B_FRACTION_DEN;
-#endif
-}
-
-/** Reconstruct motion vector for B-frame and do motion compensation
- */
-static inline void vc1_b_mc(VC1Context *v, int dmv_x[2], int dmv_y[2],
- int direct, int mode)
-{
- if (direct) {
- vc1_mc_1mv(v, 0);
- vc1_interp_mc(v);
- return;
- }
- if (mode == BMV_TYPE_INTERPOLATED) {
- vc1_mc_1mv(v, 0);
- vc1_interp_mc(v);
- return;
- }
-
- vc1_mc_1mv(v, (mode == BMV_TYPE_BACKWARD));
-}
-
-static inline void vc1_pred_b_mv(VC1Context *v, int dmv_x[2], int dmv_y[2],
- int direct, int mvtype)
-{
- MpegEncContext *s = &v->s;
- int xy, wrap, off = 0;
- int16_t *A, *B, *C;
- int px, py;
- int sum;
- int r_x, r_y;
- const uint8_t *is_intra = v->mb_type[0];
-
- av_assert0(!v->field_mode);
-
- r_x = v->range_x;
- r_y = v->range_y;
- /* scale MV difference to be quad-pel */
- dmv_x[0] <<= 1 - s->quarter_sample;
- dmv_y[0] <<= 1 - s->quarter_sample;
- dmv_x[1] <<= 1 - s->quarter_sample;
- dmv_y[1] <<= 1 - s->quarter_sample;
-
- wrap = s->b8_stride;
- xy = s->block_index[0];
-
- if (s->mb_intra) {
- s->current_picture.motion_val[0][xy][0] =
- s->current_picture.motion_val[0][xy][1] =
- s->current_picture.motion_val[1][xy][0] =
- s->current_picture.motion_val[1][xy][1] = 0;
- return;
- }
- if (direct && s->next_picture_ptr->field_picture)
- av_log(s->avctx, AV_LOG_WARNING, "Mixed frame/field direct mode not supported\n");
-
- s->mv[0][0][0] = scale_mv(s->next_picture.motion_val[1][xy][0], v->bfraction, 0, s->quarter_sample);
- s->mv[0][0][1] = scale_mv(s->next_picture.motion_val[1][xy][1], v->bfraction, 0, s->quarter_sample);
- s->mv[1][0][0] = scale_mv(s->next_picture.motion_val[1][xy][0], v->bfraction, 1, s->quarter_sample);
- s->mv[1][0][1] = scale_mv(s->next_picture.motion_val[1][xy][1], v->bfraction, 1, s->quarter_sample);
-
- /* Pullback predicted motion vectors as specified in 8.4.5.4 */
- s->mv[0][0][0] = av_clip(s->mv[0][0][0], -60 - (s->mb_x << 6), (s->mb_width << 6) - 4 - (s->mb_x << 6));
- s->mv[0][0][1] = av_clip(s->mv[0][0][1], -60 - (s->mb_y << 6), (s->mb_height << 6) - 4 - (s->mb_y << 6));
- s->mv[1][0][0] = av_clip(s->mv[1][0][0], -60 - (s->mb_x << 6), (s->mb_width << 6) - 4 - (s->mb_x << 6));
- s->mv[1][0][1] = av_clip(s->mv[1][0][1], -60 - (s->mb_y << 6), (s->mb_height << 6) - 4 - (s->mb_y << 6));
- if (direct) {
- s->current_picture.motion_val[0][xy][0] = s->mv[0][0][0];
- s->current_picture.motion_val[0][xy][1] = s->mv[0][0][1];
- s->current_picture.motion_val[1][xy][0] = s->mv[1][0][0];
- s->current_picture.motion_val[1][xy][1] = s->mv[1][0][1];
- return;
- }
-
- if ((mvtype == BMV_TYPE_FORWARD) || (mvtype == BMV_TYPE_INTERPOLATED)) {
- C = s->current_picture.motion_val[0][xy - 2];
- A = s->current_picture.motion_val[0][xy - wrap * 2];
- off = (s->mb_x == (s->mb_width - 1)) ? -2 : 2;
- B = s->current_picture.motion_val[0][xy - wrap * 2 + off];
-
- if (!s->mb_x) C[0] = C[1] = 0;
- if (!s->first_slice_line) { // predictor A is not out of bounds
- if (s->mb_width == 1) {
- px = A[0];
- py = A[1];
- } else {
- px = mid_pred(A[0], B[0], C[0]);
- py = mid_pred(A[1], B[1], C[1]);
- }
- } else if (s->mb_x) { // predictor C is not out of bounds
- px = C[0];
- py = C[1];
- } else {
- px = py = 0;
- }
- /* Pullback MV as specified in 8.3.5.3.4 */
- {
- int qx, qy, X, Y;
- if (v->profile < PROFILE_ADVANCED) {
- qx = (s->mb_x << 5);
- qy = (s->mb_y << 5);
- X = (s->mb_width << 5) - 4;
- Y = (s->mb_height << 5) - 4;
- if (qx + px < -28) px = -28 - qx;
- if (qy + py < -28) py = -28 - qy;
- if (qx + px > X) px = X - qx;
- if (qy + py > Y) py = Y - qy;
- } else {
- qx = (s->mb_x << 6);
- qy = (s->mb_y << 6);
- X = (s->mb_width << 6) - 4;
- Y = (s->mb_height << 6) - 4;
- if (qx + px < -60) px = -60 - qx;
- if (qy + py < -60) py = -60 - qy;
- if (qx + px > X) px = X - qx;
- if (qy + py > Y) py = Y - qy;
- }
- }
- /* Calculate hybrid prediction as specified in 8.3.5.3.5 */
- if (0 && !s->first_slice_line && s->mb_x) {
- if (is_intra[xy - wrap])
- sum = FFABS(px) + FFABS(py);
- else
- sum = FFABS(px - A[0]) + FFABS(py - A[1]);
- if (sum > 32) {
- if (get_bits1(&s->gb)) {
- px = A[0];
- py = A[1];
- } else {
- px = C[0];
- py = C[1];
- }
- } else {
- if (is_intra[xy - 2])
- sum = FFABS(px) + FFABS(py);
- else
- sum = FFABS(px - C[0]) + FFABS(py - C[1]);
- if (sum > 32) {
- if (get_bits1(&s->gb)) {
- px = A[0];
- py = A[1];
- } else {
- px = C[0];
- py = C[1];
- }
- }
- }
- }
- /* store MV using signed modulus of MV range defined in 4.11 */
- s->mv[0][0][0] = ((px + dmv_x[0] + r_x) & ((r_x << 1) - 1)) - r_x;
- s->mv[0][0][1] = ((py + dmv_y[0] + r_y) & ((r_y << 1) - 1)) - r_y;
- }
- if ((mvtype == BMV_TYPE_BACKWARD) || (mvtype == BMV_TYPE_INTERPOLATED)) {
- C = s->current_picture.motion_val[1][xy - 2];
- A = s->current_picture.motion_val[1][xy - wrap * 2];
- off = (s->mb_x == (s->mb_width - 1)) ? -2 : 2;
- B = s->current_picture.motion_val[1][xy - wrap * 2 + off];
-
- if (!s->mb_x)
- C[0] = C[1] = 0;
- if (!s->first_slice_line) { // predictor A is not out of bounds
- if (s->mb_width == 1) {
- px = A[0];
- py = A[1];
- } else {
- px = mid_pred(A[0], B[0], C[0]);
- py = mid_pred(A[1], B[1], C[1]);
- }
- } else if (s->mb_x) { // predictor C is not out of bounds
- px = C[0];
- py = C[1];
- } else {
- px = py = 0;
- }
- /* Pullback MV as specified in 8.3.5.3.4 */
- {
- int qx, qy, X, Y;
- if (v->profile < PROFILE_ADVANCED) {
- qx = (s->mb_x << 5);
- qy = (s->mb_y << 5);
- X = (s->mb_width << 5) - 4;
- Y = (s->mb_height << 5) - 4;
- if (qx + px < -28) px = -28 - qx;
- if (qy + py < -28) py = -28 - qy;
- if (qx + px > X) px = X - qx;
- if (qy + py > Y) py = Y - qy;
- } else {
- qx = (s->mb_x << 6);
- qy = (s->mb_y << 6);
- X = (s->mb_width << 6) - 4;
- Y = (s->mb_height << 6) - 4;
- if (qx + px < -60) px = -60 - qx;
- if (qy + py < -60) py = -60 - qy;
- if (qx + px > X) px = X - qx;
- if (qy + py > Y) py = Y - qy;
- }
- }
- /* Calculate hybrid prediction as specified in 8.3.5.3.5 */
- if (0 && !s->first_slice_line && s->mb_x) {
- if (is_intra[xy - wrap])
- sum = FFABS(px) + FFABS(py);
- else
- sum = FFABS(px - A[0]) + FFABS(py - A[1]);
- if (sum > 32) {
- if (get_bits1(&s->gb)) {
- px = A[0];
- py = A[1];
- } else {
- px = C[0];
- py = C[1];
- }
- } else {
- if (is_intra[xy - 2])
- sum = FFABS(px) + FFABS(py);
- else
- sum = FFABS(px - C[0]) + FFABS(py - C[1]);
- if (sum > 32) {
- if (get_bits1(&s->gb)) {
- px = A[0];
- py = A[1];
- } else {
- px = C[0];
- py = C[1];
- }
- }
- }
- }
- /* store MV using signed modulus of MV range defined in 4.11 */
-
- s->mv[1][0][0] = ((px + dmv_x[1] + r_x) & ((r_x << 1) - 1)) - r_x;
- s->mv[1][0][1] = ((py + dmv_y[1] + r_y) & ((r_y << 1) - 1)) - r_y;
- }
- s->current_picture.motion_val[0][xy][0] = s->mv[0][0][0];
- s->current_picture.motion_val[0][xy][1] = s->mv[0][0][1];
- s->current_picture.motion_val[1][xy][0] = s->mv[1][0][0];
- s->current_picture.motion_val[1][xy][1] = s->mv[1][0][1];
-}
-
-static inline void vc1_pred_b_mv_intfi(VC1Context *v, int n, int *dmv_x, int *dmv_y, int mv1, int *pred_flag)
-{
- int dir = (v->bmvtype == BMV_TYPE_BACKWARD) ? 1 : 0;
- MpegEncContext *s = &v->s;
- int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
-
- if (v->bmvtype == BMV_TYPE_DIRECT) {
- int total_opp, k, f;
- if (s->next_picture.mb_type[mb_pos + v->mb_off] != MB_TYPE_INTRA) {
- s->mv[0][0][0] = scale_mv(s->next_picture.motion_val[1][s->block_index[0] + v->blocks_off][0],
- v->bfraction, 0, s->quarter_sample);
- s->mv[0][0][1] = scale_mv(s->next_picture.motion_val[1][s->block_index[0] + v->blocks_off][1],
- v->bfraction, 0, s->quarter_sample);
- s->mv[1][0][0] = scale_mv(s->next_picture.motion_val[1][s->block_index[0] + v->blocks_off][0],
- v->bfraction, 1, s->quarter_sample);
- s->mv[1][0][1] = scale_mv(s->next_picture.motion_val[1][s->block_index[0] + v->blocks_off][1],
- v->bfraction, 1, s->quarter_sample);
-
- total_opp = v->mv_f_next[0][s->block_index[0] + v->blocks_off]
- + v->mv_f_next[0][s->block_index[1] + v->blocks_off]
- + v->mv_f_next[0][s->block_index[2] + v->blocks_off]
- + v->mv_f_next[0][s->block_index[3] + v->blocks_off];
- f = (total_opp > 2) ? 1 : 0;
- } else {
- s->mv[0][0][0] = s->mv[0][0][1] = 0;
- s->mv[1][0][0] = s->mv[1][0][1] = 0;
- f = 0;
- }
- v->ref_field_type[0] = v->ref_field_type[1] = v->cur_field_type ^ f;
- for (k = 0; k < 4; k++) {
- s->current_picture.motion_val[0][s->block_index[k] + v->blocks_off][0] = s->mv[0][0][0];
- s->current_picture.motion_val[0][s->block_index[k] + v->blocks_off][1] = s->mv[0][0][1];
- s->current_picture.motion_val[1][s->block_index[k] + v->blocks_off][0] = s->mv[1][0][0];
- s->current_picture.motion_val[1][s->block_index[k] + v->blocks_off][1] = s->mv[1][0][1];
- v->mv_f[0][s->block_index[k] + v->blocks_off] = f;
- v->mv_f[1][s->block_index[k] + v->blocks_off] = f;
- }
- return;
- }
- if (v->bmvtype == BMV_TYPE_INTERPOLATED) {
- vc1_pred_mv(v, 0, dmv_x[0], dmv_y[0], 1, v->range_x, v->range_y, v->mb_type[0], pred_flag[0], 0);
- vc1_pred_mv(v, 0, dmv_x[1], dmv_y[1], 1, v->range_x, v->range_y, v->mb_type[0], pred_flag[1], 1);
- return;
- }
- if (dir) { // backward
- vc1_pred_mv(v, n, dmv_x[1], dmv_y[1], mv1, v->range_x, v->range_y, v->mb_type[0], pred_flag[1], 1);
- if (n == 3 || mv1) {
- vc1_pred_mv(v, 0, dmv_x[0], dmv_y[0], 1, v->range_x, v->range_y, v->mb_type[0], 0, 0);
- }
- } else { // forward
- vc1_pred_mv(v, n, dmv_x[0], dmv_y[0], mv1, v->range_x, v->range_y, v->mb_type[0], pred_flag[0], 0);
- if (n == 3 || mv1) {
- vc1_pred_mv(v, 0, dmv_x[1], dmv_y[1], 1, v->range_x, v->range_y, v->mb_type[0], 0, 1);
- }
- }
-}
-
-/** Get predicted DC value for I-frames only
- * prediction dir: left=0, top=1
- * @param s MpegEncContext
- * @param overlap flag indicating that overlap filtering is used
- * @param pq integer part of picture quantizer
- * @param[in] n block index in the current MB
- * @param dc_val_ptr Pointer to DC predictor
- * @param dir_ptr Prediction direction for use in AC prediction
- */
-static inline int vc1_i_pred_dc(MpegEncContext *s, int overlap, int pq, int n,
- int16_t **dc_val_ptr, int *dir_ptr)
-{
- int a, b, c, wrap, pred, scale;
- int16_t *dc_val;
- static const uint16_t dcpred[32] = {
- -1, 1024, 512, 341, 256, 205, 171, 146, 128,
- 114, 102, 93, 85, 79, 73, 68, 64,
- 60, 57, 54, 51, 49, 47, 45, 43,
- 41, 39, 38, 37, 35, 34, 33
- };
-
- /* find prediction - wmv3_dc_scale always used here in fact */
- if (n < 4) scale = s->y_dc_scale;
- else scale = s->c_dc_scale;
-
- wrap = s->block_wrap[n];
- dc_val = s->dc_val[0] + s->block_index[n];
-
- /* B A
- * C X
- */
- c = dc_val[ - 1];
- b = dc_val[ - 1 - wrap];
- a = dc_val[ - wrap];
-
- if (pq < 9 || !overlap) {
- /* Set outer values */
- if (s->first_slice_line && (n != 2 && n != 3))
- b = a = dcpred[scale];
- if (s->mb_x == 0 && (n != 1 && n != 3))
- b = c = dcpred[scale];
- } else {
- /* Set outer values */
- if (s->first_slice_line && (n != 2 && n != 3))
- b = a = 0;
- if (s->mb_x == 0 && (n != 1 && n != 3))
- b = c = 0;
- }
-
- if (abs(a - b) <= abs(b - c)) {
- pred = c;
- *dir_ptr = 1; // left
- } else {
- pred = a;
- *dir_ptr = 0; // top
- }
-
- /* update predictor */
- *dc_val_ptr = &dc_val[0];
- return pred;
-}
-
-
-/** Get predicted DC value
- * prediction dir: left=0, top=1
- * @param s MpegEncContext
- * @param overlap flag indicating that overlap filtering is used
- * @param pq integer part of picture quantizer
- * @param[in] n block index in the current MB
- * @param a_avail flag indicating top block availability
- * @param c_avail flag indicating left block availability
- * @param dc_val_ptr Pointer to DC predictor
- * @param dir_ptr Prediction direction for use in AC prediction
- */
-static inline int vc1_pred_dc(MpegEncContext *s, int overlap, int pq, int n,
- int a_avail, int c_avail,
- int16_t **dc_val_ptr, int *dir_ptr)
-{
- int a, b, c, wrap, pred;
- int16_t *dc_val;
- int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
- int q1, q2 = 0;
- int dqscale_index;
-
- wrap = s->block_wrap[n];
- dc_val = s->dc_val[0] + s->block_index[n];
-
- /* B A
- * C X
- */
- c = dc_val[ - 1];
- b = dc_val[ - 1 - wrap];
- a = dc_val[ - wrap];
- /* scale predictors if needed */
- q1 = s->current_picture.qscale_table[mb_pos];
- dqscale_index = s->y_dc_scale_table[q1] - 1;
- if (dqscale_index < 0)
- return 0;
- if (c_avail && (n != 1 && n != 3)) {
- q2 = s->current_picture.qscale_table[mb_pos - 1];
- if (q2 && q2 != q1)
- c = (c * s->y_dc_scale_table[q2] * ff_vc1_dqscale[dqscale_index] + 0x20000) >> 18;
- }
- if (a_avail && (n != 2 && n != 3)) {
- q2 = s->current_picture.qscale_table[mb_pos - s->mb_stride];
- if (q2 && q2 != q1)
- a = (a * s->y_dc_scale_table[q2] * ff_vc1_dqscale[dqscale_index] + 0x20000) >> 18;
- }
- if (a_avail && c_avail && (n != 3)) {
- int off = mb_pos;
- if (n != 1)
- off--;
- if (n != 2)
- off -= s->mb_stride;
- q2 = s->current_picture.qscale_table[off];
- if (q2 && q2 != q1)
- b = (b * s->y_dc_scale_table[q2] * ff_vc1_dqscale[dqscale_index] + 0x20000) >> 18;
- }
-
- if (a_avail && c_avail) {
- if (abs(a - b) <= abs(b - c)) {
- pred = c;
- *dir_ptr = 1; // left
- } else {
- pred = a;
- *dir_ptr = 0; // top
- }
- } else if (a_avail) {
- pred = a;
- *dir_ptr = 0; // top
- } else if (c_avail) {
- pred = c;
- *dir_ptr = 1; // left
- } else {
- pred = 0;
- *dir_ptr = 1; // left
- }
-
- /* update predictor */
- *dc_val_ptr = &dc_val[0];
- return pred;
-}
-
-/** @} */ // Block group
-
-/**
- * @name VC1 Macroblock-level functions in Simple/Main Profiles
- * @see 7.1.4, p91 and 8.1.1.7, p(1)04
- * @{
- */
-
-static inline int vc1_coded_block_pred(MpegEncContext * s, int n,
- uint8_t **coded_block_ptr)
-{
- int xy, wrap, pred, a, b, c;
-
- xy = s->block_index[n];
- wrap = s->b8_stride;
-
- /* B C
- * A X
- */
- a = s->coded_block[xy - 1 ];
- b = s->coded_block[xy - 1 - wrap];
- c = s->coded_block[xy - wrap];
-
- if (b == c) {
- pred = a;
- } else {
- pred = c;
- }
-
- /* store value */
- *coded_block_ptr = &s->coded_block[xy];
-
- return pred;
-}
-
-/**
- * Decode one AC coefficient
- * @param v The VC1 context
- * @param last Last coefficient
- * @param skip How much zero coefficients to skip
- * @param value Decoded AC coefficient value
- * @param codingset set of VLC to decode data
- * @see 8.1.3.4
- */
-static void vc1_decode_ac_coeff(VC1Context *v, int *last, int *skip,
- int *value, int codingset)
-{
- GetBitContext *gb = &v->s.gb;
- int index, escape, run = 0, level = 0, lst = 0;
-
- index = get_vlc2(gb, ff_vc1_ac_coeff_table[codingset].table, AC_VLC_BITS, 3);
- if (index != ff_vc1_ac_sizes[codingset] - 1) {
- run = vc1_index_decode_table[codingset][index][0];
- level = vc1_index_decode_table[codingset][index][1];
- lst = index >= vc1_last_decode_table[codingset] || get_bits_left(gb) < 0;
- if (get_bits1(gb))
- level = -level;
- } else {
- escape = decode210(gb);
- if (escape != 2) {
- index = get_vlc2(gb, ff_vc1_ac_coeff_table[codingset].table, AC_VLC_BITS, 3);
- run = vc1_index_decode_table[codingset][index][0];
- level = vc1_index_decode_table[codingset][index][1];
- lst = index >= vc1_last_decode_table[codingset];
- if (escape == 0) {
- if (lst)
- level += vc1_last_delta_level_table[codingset][run];
- else
- level += vc1_delta_level_table[codingset][run];
- } else {
- if (lst)
- run += vc1_last_delta_run_table[codingset][level] + 1;
- else
- run += vc1_delta_run_table[codingset][level] + 1;
- }
- if (get_bits1(gb))
- level = -level;
- } else {
- int sign;
- lst = get_bits1(gb);
- if (v->s.esc3_level_length == 0) {
- if (v->pq < 8 || v->dquantfrm) { // table 59
- v->s.esc3_level_length = get_bits(gb, 3);
- if (!v->s.esc3_level_length)
- v->s.esc3_level_length = get_bits(gb, 2) + 8;
- } else { // table 60
- v->s.esc3_level_length = get_unary(gb, 1, 6) + 2;
- }
- v->s.esc3_run_length = 3 + get_bits(gb, 2);
- }
- run = get_bits(gb, v->s.esc3_run_length);
- sign = get_bits1(gb);
- level = get_bits(gb, v->s.esc3_level_length);
- if (sign)
- level = -level;
- }
- }
-
- *last = lst;
- *skip = run;
- *value = level;
-}
-
-/** Decode intra block in intra frames - should be faster than decode_intra_block
- * @param v VC1Context
- * @param block block to decode
- * @param[in] n subblock index
- * @param coded are AC coeffs present or not
- * @param codingset set of VLC to decode data
- */
-static int vc1_decode_i_block(VC1Context *v, int16_t block[64], int n,
- int coded, int codingset)
-{
- GetBitContext *gb = &v->s.gb;
- MpegEncContext *s = &v->s;
- int dc_pred_dir = 0; /* Direction of the DC prediction used */
- int i;
- int16_t *dc_val;
- int16_t *ac_val, *ac_val2;
- int dcdiff;
-
- /* Get DC differential */
- if (n < 4) {
- dcdiff = get_vlc2(&s->gb, ff_msmp4_dc_luma_vlc[s->dc_table_index].table, DC_VLC_BITS, 3);
- } else {
- dcdiff = get_vlc2(&s->gb, ff_msmp4_dc_chroma_vlc[s->dc_table_index].table, DC_VLC_BITS, 3);
- }
- if (dcdiff < 0) {
- av_log(s->avctx, AV_LOG_ERROR, "Illegal DC VLC\n");
- return -1;
- }
- if (dcdiff) {
- if (dcdiff == 119 /* ESC index value */) {
- /* TODO: Optimize */
- if (v->pq == 1) dcdiff = get_bits(gb, 10);
- else if (v->pq == 2) dcdiff = get_bits(gb, 9);
- else dcdiff = get_bits(gb, 8);
- } else {
- if (v->pq == 1)
- dcdiff = (dcdiff << 2) + get_bits(gb, 2) - 3;
- else if (v->pq == 2)
- dcdiff = (dcdiff << 1) + get_bits1(gb) - 1;
- }
- if (get_bits1(gb))
- dcdiff = -dcdiff;
- }
-
- /* Prediction */
- dcdiff += vc1_i_pred_dc(&v->s, v->overlap, v->pq, n, &dc_val, &dc_pred_dir);
- *dc_val = dcdiff;
-
- /* Store the quantized DC coeff, used for prediction */
- if (n < 4) {
- block[0] = dcdiff * s->y_dc_scale;
- } else {
- block[0] = dcdiff * s->c_dc_scale;
- }
- /* Skip ? */
- if (!coded) {
- goto not_coded;
- }
-
- // AC Decoding
- i = 1;
-
- {
- int last = 0, skip, value;
- const uint8_t *zz_table;
- int scale;
- int k;
-
- scale = v->pq * 2 + v->halfpq;
-
- if (v->s.ac_pred) {
- if (!dc_pred_dir)
- zz_table = v->zz_8x8[2];
- else
- zz_table = v->zz_8x8[3];
- } else
- zz_table = v->zz_8x8[1];
-
- ac_val = s->ac_val[0][0] + s->block_index[n] * 16;
- ac_val2 = ac_val;
- if (dc_pred_dir) // left
- ac_val -= 16;
- else // top
- ac_val -= 16 * s->block_wrap[n];
-
- while (!last) {
- vc1_decode_ac_coeff(v, &last, &skip, &value, codingset);
- i += skip;
- if (i > 63)
- break;
- block[zz_table[i++]] = value;
- }
-
- /* apply AC prediction if needed */
- if (s->ac_pred) {
- if (dc_pred_dir) { // left
- for (k = 1; k < 8; k++)
- block[k << v->left_blk_sh] += ac_val[k];
- } else { // top
- for (k = 1; k < 8; k++)
- block[k << v->top_blk_sh] += ac_val[k + 8];
- }
- }
- /* save AC coeffs for further prediction */
- for (k = 1; k < 8; k++) {
- ac_val2[k] = block[k << v->left_blk_sh];
- ac_val2[k + 8] = block[k << v->top_blk_sh];
- }
-
- /* scale AC coeffs */
- for (k = 1; k < 64; k++)
- if (block[k]) {
- block[k] *= scale;
- if (!v->pquantizer)
- block[k] += (block[k] < 0) ? -v->pq : v->pq;
- }
-
- if (s->ac_pred) i = 63;
- }
-
-not_coded:
- if (!coded) {
- int k, scale;
- ac_val = s->ac_val[0][0] + s->block_index[n] * 16;
- ac_val2 = ac_val;
-
- i = 0;
- scale = v->pq * 2 + v->halfpq;
- memset(ac_val2, 0, 16 * 2);
- if (dc_pred_dir) { // left
- ac_val -= 16;
- if (s->ac_pred)
- memcpy(ac_val2, ac_val, 8 * 2);
- } else { // top
- ac_val -= 16 * s->block_wrap[n];
- if (s->ac_pred)
- memcpy(ac_val2 + 8, ac_val + 8, 8 * 2);
- }
-
- /* apply AC prediction if needed */
- if (s->ac_pred) {
- if (dc_pred_dir) { //left
- for (k = 1; k < 8; k++) {
- block[k << v->left_blk_sh] = ac_val[k] * scale;
- if (!v->pquantizer && block[k << v->left_blk_sh])
- block[k << v->left_blk_sh] += (block[k << v->left_blk_sh] < 0) ? -v->pq : v->pq;
- }
- } else { // top
- for (k = 1; k < 8; k++) {
- block[k << v->top_blk_sh] = ac_val[k + 8] * scale;
- if (!v->pquantizer && block[k << v->top_blk_sh])
- block[k << v->top_blk_sh] += (block[k << v->top_blk_sh] < 0) ? -v->pq : v->pq;
- }
- }
- i = 63;
- }
- }
- s->block_last_index[n] = i;
-
- return 0;
-}
-
-/** Decode intra block in intra frames - should be faster than decode_intra_block
- * @param v VC1Context
- * @param block block to decode
- * @param[in] n subblock number
- * @param coded are AC coeffs present or not
- * @param codingset set of VLC to decode data
- * @param mquant quantizer value for this macroblock
- */
-static int vc1_decode_i_block_adv(VC1Context *v, int16_t block[64], int n,
- int coded, int codingset, int mquant)
-{
- GetBitContext *gb = &v->s.gb;
- MpegEncContext *s = &v->s;
- int dc_pred_dir = 0; /* Direction of the DC prediction used */
- int i;
- int16_t *dc_val = NULL;
- int16_t *ac_val, *ac_val2;
- int dcdiff;
- int a_avail = v->a_avail, c_avail = v->c_avail;
- int use_pred = s->ac_pred;
- int scale;
- int q1, q2 = 0;
- int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
-
- /* Get DC differential */
- if (n < 4) {
- dcdiff = get_vlc2(&s->gb, ff_msmp4_dc_luma_vlc[s->dc_table_index].table, DC_VLC_BITS, 3);
- } else {
- dcdiff = get_vlc2(&s->gb, ff_msmp4_dc_chroma_vlc[s->dc_table_index].table, DC_VLC_BITS, 3);
- }
- if (dcdiff < 0) {
- av_log(s->avctx, AV_LOG_ERROR, "Illegal DC VLC\n");
- return -1;
- }
- if (dcdiff) {
- if (dcdiff == 119 /* ESC index value */) {
- /* TODO: Optimize */
- if (mquant == 1) dcdiff = get_bits(gb, 10);
- else if (mquant == 2) dcdiff = get_bits(gb, 9);
- else dcdiff = get_bits(gb, 8);
- } else {
- if (mquant == 1)
- dcdiff = (dcdiff << 2) + get_bits(gb, 2) - 3;
- else if (mquant == 2)
- dcdiff = (dcdiff << 1) + get_bits1(gb) - 1;
- }
- if (get_bits1(gb))
- dcdiff = -dcdiff;
- }
-
- /* Prediction */
- dcdiff += vc1_pred_dc(&v->s, v->overlap, mquant, n, v->a_avail, v->c_avail, &dc_val, &dc_pred_dir);
- *dc_val = dcdiff;
-
- /* Store the quantized DC coeff, used for prediction */
- if (n < 4) {
- block[0] = dcdiff * s->y_dc_scale;
- } else {
- block[0] = dcdiff * s->c_dc_scale;
- }
-
- //AC Decoding
- i = 1;
-
- /* check if AC is needed at all */
- if (!a_avail && !c_avail)
- use_pred = 0;
- ac_val = s->ac_val[0][0] + s->block_index[n] * 16;
- ac_val2 = ac_val;
-
- scale = mquant * 2 + ((mquant == v->pq) ? v->halfpq : 0);
-
- if (dc_pred_dir) // left
- ac_val -= 16;
- else // top
- ac_val -= 16 * s->block_wrap[n];
-
- q1 = s->current_picture.qscale_table[mb_pos];
- if ( dc_pred_dir && c_avail && mb_pos)
- q2 = s->current_picture.qscale_table[mb_pos - 1];
- if (!dc_pred_dir && a_avail && mb_pos >= s->mb_stride)
- q2 = s->current_picture.qscale_table[mb_pos - s->mb_stride];
- if ( dc_pred_dir && n == 1)
- q2 = q1;
- if (!dc_pred_dir && n == 2)
- q2 = q1;
- if (n == 3)
- q2 = q1;
-
- if (coded) {
- int last = 0, skip, value;
- const uint8_t *zz_table;
- int k;
-
- if (v->s.ac_pred) {
- if (!use_pred && v->fcm == ILACE_FRAME) {
- zz_table = v->zzi_8x8;
- } else {
- if (!dc_pred_dir) // top
- zz_table = v->zz_8x8[2];
- else // left
- zz_table = v->zz_8x8[3];
- }
- } else {
- if (v->fcm != ILACE_FRAME)
- zz_table = v->zz_8x8[1];
- else
- zz_table = v->zzi_8x8;
- }
-
- while (!last) {
- vc1_decode_ac_coeff(v, &last, &skip, &value, codingset);
- i += skip;
- if (i > 63)
- break;
- block[zz_table[i++]] = value;
- }
-
- /* apply AC prediction if needed */
- if (use_pred) {
- /* scale predictors if needed*/
- if (q2 && q1 != q2) {
- q1 = q1 * 2 + ((q1 == v->pq) ? v->halfpq : 0) - 1;
- q2 = q2 * 2 + ((q2 == v->pq) ? v->halfpq : 0) - 1;
-
- if (q1 < 1)
- return AVERROR_INVALIDDATA;
- if (dc_pred_dir) { // left
- for (k = 1; k < 8; k++)
- block[k << v->left_blk_sh] += (ac_val[k] * q2 * ff_vc1_dqscale[q1 - 1] + 0x20000) >> 18;
- } else { // top
- for (k = 1; k < 8; k++)
- block[k << v->top_blk_sh] += (ac_val[k + 8] * q2 * ff_vc1_dqscale[q1 - 1] + 0x20000) >> 18;
- }
- } else {
- if (dc_pred_dir) { //left
- for (k = 1; k < 8; k++)
- block[k << v->left_blk_sh] += ac_val[k];
- } else { //top
- for (k = 1; k < 8; k++)
- block[k << v->top_blk_sh] += ac_val[k + 8];
- }
- }
- }
- /* save AC coeffs for further prediction */
- for (k = 1; k < 8; k++) {
- ac_val2[k ] = block[k << v->left_blk_sh];
- ac_val2[k + 8] = block[k << v->top_blk_sh];
- }
-
- /* scale AC coeffs */
- for (k = 1; k < 64; k++)
- if (block[k]) {
- block[k] *= scale;
- if (!v->pquantizer)
- block[k] += (block[k] < 0) ? -mquant : mquant;
- }
-
- if (use_pred) i = 63;
- } else { // no AC coeffs
- int k;
-
- memset(ac_val2, 0, 16 * 2);
- if (dc_pred_dir) { // left
- if (use_pred) {
- memcpy(ac_val2, ac_val, 8 * 2);
- if (q2 && q1 != q2) {
- q1 = q1 * 2 + ((q1 == v->pq) ? v->halfpq : 0) - 1;
- q2 = q2 * 2 + ((q2 == v->pq) ? v->halfpq : 0) - 1;
- if (q1 < 1)
- return AVERROR_INVALIDDATA;
- for (k = 1; k < 8; k++)
- ac_val2[k] = (ac_val2[k] * q2 * ff_vc1_dqscale[q1 - 1] + 0x20000) >> 18;
- }
- }
- } else { // top
- if (use_pred) {
- memcpy(ac_val2 + 8, ac_val + 8, 8 * 2);
- if (q2 && q1 != q2) {
- q1 = q1 * 2 + ((q1 == v->pq) ? v->halfpq : 0) - 1;
- q2 = q2 * 2 + ((q2 == v->pq) ? v->halfpq : 0) - 1;
- if (q1 < 1)
- return AVERROR_INVALIDDATA;
- for (k = 1; k < 8; k++)
- ac_val2[k + 8] = (ac_val2[k + 8] * q2 * ff_vc1_dqscale[q1 - 1] + 0x20000) >> 18;
- }
- }
- }
-
- /* apply AC prediction if needed */
- if (use_pred) {
- if (dc_pred_dir) { // left
- for (k = 1; k < 8; k++) {
- block[k << v->left_blk_sh] = ac_val2[k] * scale;
- if (!v->pquantizer && block[k << v->left_blk_sh])
- block[k << v->left_blk_sh] += (block[k << v->left_blk_sh] < 0) ? -mquant : mquant;
- }
- } else { // top
- for (k = 1; k < 8; k++) {
- block[k << v->top_blk_sh] = ac_val2[k + 8] * scale;
- if (!v->pquantizer && block[k << v->top_blk_sh])
- block[k << v->top_blk_sh] += (block[k << v->top_blk_sh] < 0) ? -mquant : mquant;
- }
- }
- i = 63;
- }
- }
- s->block_last_index[n] = i;
-
- return 0;
-}
-
-/** Decode intra block in inter frames - more generic version than vc1_decode_i_block
- * @param v VC1Context
- * @param block block to decode
- * @param[in] n subblock index
- * @param coded are AC coeffs present or not
- * @param mquant block quantizer
- * @param codingset set of VLC to decode data
- */
-static int vc1_decode_intra_block(VC1Context *v, int16_t block[64], int n,
- int coded, int mquant, int codingset)
-{
- GetBitContext *gb = &v->s.gb;
- MpegEncContext *s = &v->s;
- int dc_pred_dir = 0; /* Direction of the DC prediction used */
- int i;
- int16_t *dc_val = NULL;
- int16_t *ac_val, *ac_val2;
- int dcdiff;
- int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
- int a_avail = v->a_avail, c_avail = v->c_avail;
- int use_pred = s->ac_pred;
- int scale;
- int q1, q2 = 0;
-
- s->bdsp.clear_block(block);
-
- /* XXX: Guard against dumb values of mquant */
- mquant = (mquant < 1) ? 0 : ((mquant > 31) ? 31 : mquant);
-
- /* Set DC scale - y and c use the same */
- s->y_dc_scale = s->y_dc_scale_table[mquant];
- s->c_dc_scale = s->c_dc_scale_table[mquant];
-
- /* Get DC differential */
- if (n < 4) {
- dcdiff = get_vlc2(&s->gb, ff_msmp4_dc_luma_vlc[s->dc_table_index].table, DC_VLC_BITS, 3);
- } else {
- dcdiff = get_vlc2(&s->gb, ff_msmp4_dc_chroma_vlc[s->dc_table_index].table, DC_VLC_BITS, 3);
- }
- if (dcdiff < 0) {
- av_log(s->avctx, AV_LOG_ERROR, "Illegal DC VLC\n");
- return -1;
- }
- if (dcdiff) {
- if (dcdiff == 119 /* ESC index value */) {
- /* TODO: Optimize */
- if (mquant == 1) dcdiff = get_bits(gb, 10);
- else if (mquant == 2) dcdiff = get_bits(gb, 9);
- else dcdiff = get_bits(gb, 8);
- } else {
- if (mquant == 1)
- dcdiff = (dcdiff << 2) + get_bits(gb, 2) - 3;
- else if (mquant == 2)
- dcdiff = (dcdiff << 1) + get_bits1(gb) - 1;
- }
- if (get_bits1(gb))
- dcdiff = -dcdiff;
- }
-
- /* Prediction */
- dcdiff += vc1_pred_dc(&v->s, v->overlap, mquant, n, a_avail, c_avail, &dc_val, &dc_pred_dir);
- *dc_val = dcdiff;
-
- /* Store the quantized DC coeff, used for prediction */
-
- if (n < 4) {
- block[0] = dcdiff * s->y_dc_scale;
- } else {
- block[0] = dcdiff * s->c_dc_scale;
- }
-
- //AC Decoding
- i = 1;
-
- /* check if AC is needed at all and adjust direction if needed */
- if (!a_avail) dc_pred_dir = 1;
- if (!c_avail) dc_pred_dir = 0;
- if (!a_avail && !c_avail) use_pred = 0;
- ac_val = s->ac_val[0][0] + s->block_index[n] * 16;
- ac_val2 = ac_val;
-
- scale = mquant * 2 + v->halfpq;
-
- if (dc_pred_dir) //left
- ac_val -= 16;
- else //top
- ac_val -= 16 * s->block_wrap[n];
-
- q1 = s->current_picture.qscale_table[mb_pos];
- if (dc_pred_dir && c_avail && mb_pos)
- q2 = s->current_picture.qscale_table[mb_pos - 1];
- if (!dc_pred_dir && a_avail && mb_pos >= s->mb_stride)
- q2 = s->current_picture.qscale_table[mb_pos - s->mb_stride];
- if ( dc_pred_dir && n == 1)
- q2 = q1;
- if (!dc_pred_dir && n == 2)
- q2 = q1;
- if (n == 3) q2 = q1;
-
- if (coded) {
- int last = 0, skip, value;
- int k;
-
- while (!last) {
- vc1_decode_ac_coeff(v, &last, &skip, &value, codingset);
- i += skip;
- if (i > 63)
- break;
- if (v->fcm == PROGRESSIVE)
- block[v->zz_8x8[0][i++]] = value;
- else {
- if (use_pred && (v->fcm == ILACE_FRAME)) {
- if (!dc_pred_dir) // top
- block[v->zz_8x8[2][i++]] = value;
- else // left
- block[v->zz_8x8[3][i++]] = value;
- } else {
- block[v->zzi_8x8[i++]] = value;
- }
- }
- }
-
- /* apply AC prediction if needed */
- if (use_pred) {
- /* scale predictors if needed*/
- if (q2 && q1 != q2) {
- q1 = q1 * 2 + ((q1 == v->pq) ? v->halfpq : 0) - 1;
- q2 = q2 * 2 + ((q2 == v->pq) ? v->halfpq : 0) - 1;
-
- if (q1 < 1)
- return AVERROR_INVALIDDATA;
- if (dc_pred_dir) { // left
- for (k = 1; k < 8; k++)
- block[k << v->left_blk_sh] += (ac_val[k] * q2 * ff_vc1_dqscale[q1 - 1] + 0x20000) >> 18;
- } else { //top
- for (k = 1; k < 8; k++)
- block[k << v->top_blk_sh] += (ac_val[k + 8] * q2 * ff_vc1_dqscale[q1 - 1] + 0x20000) >> 18;
- }
- } else {
- if (dc_pred_dir) { // left
- for (k = 1; k < 8; k++)
- block[k << v->left_blk_sh] += ac_val[k];
- } else { // top
- for (k = 1; k < 8; k++)
- block[k << v->top_blk_sh] += ac_val[k + 8];
- }
- }
- }
- /* save AC coeffs for further prediction */
- for (k = 1; k < 8; k++) {
- ac_val2[k ] = block[k << v->left_blk_sh];
- ac_val2[k + 8] = block[k << v->top_blk_sh];
- }
-
- /* scale AC coeffs */
- for (k = 1; k < 64; k++)
- if (block[k]) {
- block[k] *= scale;
- if (!v->pquantizer)
- block[k] += (block[k] < 0) ? -mquant : mquant;
- }
-
- if (use_pred) i = 63;
- } else { // no AC coeffs
- int k;
-
- memset(ac_val2, 0, 16 * 2);
- if (dc_pred_dir) { // left
- if (use_pred) {
- memcpy(ac_val2, ac_val, 8 * 2);
- if (q2 && q1 != q2) {
- q1 = q1 * 2 + ((q1 == v->pq) ? v->halfpq : 0) - 1;
- q2 = q2 * 2 + ((q2 == v->pq) ? v->halfpq : 0) - 1;
- if (q1 < 1)
- return AVERROR_INVALIDDATA;
- for (k = 1; k < 8; k++)
- ac_val2[k] = (ac_val2[k] * q2 * ff_vc1_dqscale[q1 - 1] + 0x20000) >> 18;
- }
- }
- } else { // top
- if (use_pred) {
- memcpy(ac_val2 + 8, ac_val + 8, 8 * 2);
- if (q2 && q1 != q2) {
- q1 = q1 * 2 + ((q1 == v->pq) ? v->halfpq : 0) - 1;
- q2 = q2 * 2 + ((q2 == v->pq) ? v->halfpq : 0) - 1;
- if (q1 < 1)
- return AVERROR_INVALIDDATA;
- for (k = 1; k < 8; k++)
- ac_val2[k + 8] = (ac_val2[k + 8] * q2 * ff_vc1_dqscale[q1 - 1] + 0x20000) >> 18;
- }
- }
- }
-
- /* apply AC prediction if needed */
- if (use_pred) {
- if (dc_pred_dir) { // left
- for (k = 1; k < 8; k++) {
- block[k << v->left_blk_sh] = ac_val2[k] * scale;
- if (!v->pquantizer && block[k << v->left_blk_sh])
- block[k << v->left_blk_sh] += (block[k << v->left_blk_sh] < 0) ? -mquant : mquant;
- }
- } else { // top
- for (k = 1; k < 8; k++) {
- block[k << v->top_blk_sh] = ac_val2[k + 8] * scale;
- if (!v->pquantizer && block[k << v->top_blk_sh])
- block[k << v->top_blk_sh] += (block[k << v->top_blk_sh] < 0) ? -mquant : mquant;
- }
- }
- i = 63;
- }
- }
- s->block_last_index[n] = i;
-
- return 0;
-}
-
-/** Decode P block
- */
-static int vc1_decode_p_block(VC1Context *v, int16_t block[64], int n,
- int mquant, int ttmb, int first_block,
- uint8_t *dst, int linesize, int skip_block,
- int *ttmb_out)
-{
- MpegEncContext *s = &v->s;
- GetBitContext *gb = &s->gb;
- int i, j;
- int subblkpat = 0;
- int scale, off, idx, last, skip, value;
- int ttblk = ttmb & 7;
- int pat = 0;
-
- s->bdsp.clear_block(block);
-
- if (ttmb == -1) {
- ttblk = ff_vc1_ttblk_to_tt[v->tt_index][get_vlc2(gb, ff_vc1_ttblk_vlc[v->tt_index].table, VC1_TTBLK_VLC_BITS, 1)];
- }
- if (ttblk == TT_4X4) {
- subblkpat = ~(get_vlc2(gb, ff_vc1_subblkpat_vlc[v->tt_index].table, VC1_SUBBLKPAT_VLC_BITS, 1) + 1);
- }
- if ((ttblk != TT_8X8 && ttblk != TT_4X4)
- && ((v->ttmbf || (ttmb != -1 && (ttmb & 8) && !first_block))
- || (!v->res_rtm_flag && !first_block))) {
- subblkpat = decode012(gb);
- if (subblkpat)
- subblkpat ^= 3; // swap decoded pattern bits
- if (ttblk == TT_8X4_TOP || ttblk == TT_8X4_BOTTOM)
- ttblk = TT_8X4;
- if (ttblk == TT_4X8_RIGHT || ttblk == TT_4X8_LEFT)
- ttblk = TT_4X8;
- }
- scale = 2 * mquant + ((v->pq == mquant) ? v->halfpq : 0);
-
- // convert transforms like 8X4_TOP to generic TT and SUBBLKPAT
- if (ttblk == TT_8X4_TOP || ttblk == TT_8X4_BOTTOM) {
- subblkpat = 2 - (ttblk == TT_8X4_TOP);
- ttblk = TT_8X4;
- }
- if (ttblk == TT_4X8_RIGHT || ttblk == TT_4X8_LEFT) {
- subblkpat = 2 - (ttblk == TT_4X8_LEFT);
- ttblk = TT_4X8;
- }
- switch (ttblk) {
- case TT_8X8:
- pat = 0xF;
- i = 0;
- last = 0;
- while (!last) {
- vc1_decode_ac_coeff(v, &last, &skip, &value, v->codingset2);
- i += skip;
- if (i > 63)
- break;
- if (!v->fcm)
- idx = v->zz_8x8[0][i++];
- else
- idx = v->zzi_8x8[i++];
- block[idx] = value * scale;
- if (!v->pquantizer)
- block[idx] += (block[idx] < 0) ? -mquant : mquant;
- }
- if (!skip_block) {
- if (i == 1)
- v->vc1dsp.vc1_inv_trans_8x8_dc(dst, linesize, block);
- else {
- v->vc1dsp.vc1_inv_trans_8x8(block);
- s->idsp.add_pixels_clamped(block, dst, linesize);
- }
- }
- break;
- case TT_4X4:
- pat = ~subblkpat & 0xF;
- for (j = 0; j < 4; j++) {
- last = subblkpat & (1 << (3 - j));
- i = 0;
- off = (j & 1) * 4 + (j & 2) * 16;
- while (!last) {
- vc1_decode_ac_coeff(v, &last, &skip, &value, v->codingset2);
- i += skip;
- if (i > 15)
- break;
- if (!v->fcm)
- idx = ff_vc1_simple_progressive_4x4_zz[i++];
- else
- idx = ff_vc1_adv_interlaced_4x4_zz[i++];
- block[idx + off] = value * scale;
- if (!v->pquantizer)
- block[idx + off] += (block[idx + off] < 0) ? -mquant : mquant;
- }
- if (!(subblkpat & (1 << (3 - j))) && !skip_block) {
- if (i == 1)
- v->vc1dsp.vc1_inv_trans_4x4_dc(dst + (j & 1) * 4 + (j & 2) * 2 * linesize, linesize, block + off);
- else
- v->vc1dsp.vc1_inv_trans_4x4(dst + (j & 1) * 4 + (j & 2) * 2 * linesize, linesize, block + off);
- }
- }
- break;
- case TT_8X4:
- pat = ~((subblkpat & 2) * 6 + (subblkpat & 1) * 3) & 0xF;
- for (j = 0; j < 2; j++) {
- last = subblkpat & (1 << (1 - j));
- i = 0;
- off = j * 32;
- while (!last) {
- vc1_decode_ac_coeff(v, &last, &skip, &value, v->codingset2);
- i += skip;
- if (i > 31)
- break;
- if (!v->fcm)
- idx = v->zz_8x4[i++] + off;
- else
- idx = ff_vc1_adv_interlaced_8x4_zz[i++] + off;
- block[idx] = value * scale;
- if (!v->pquantizer)
- block[idx] += (block[idx] < 0) ? -mquant : mquant;
- }
- if (!(subblkpat & (1 << (1 - j))) && !skip_block) {
- if (i == 1)
- v->vc1dsp.vc1_inv_trans_8x4_dc(dst + j * 4 * linesize, linesize, block + off);
- else
- v->vc1dsp.vc1_inv_trans_8x4(dst + j * 4 * linesize, linesize, block + off);
- }
- }
- break;
- case TT_4X8:
- pat = ~(subblkpat * 5) & 0xF;
- for (j = 0; j < 2; j++) {
- last = subblkpat & (1 << (1 - j));
- i = 0;
- off = j * 4;
- while (!last) {
- vc1_decode_ac_coeff(v, &last, &skip, &value, v->codingset2);
- i += skip;
- if (i > 31)
- break;
- if (!v->fcm)
- idx = v->zz_4x8[i++] + off;
- else
- idx = ff_vc1_adv_interlaced_4x8_zz[i++] + off;
- block[idx] = value * scale;
- if (!v->pquantizer)
- block[idx] += (block[idx] < 0) ? -mquant : mquant;
- }
- if (!(subblkpat & (1 << (1 - j))) && !skip_block) {
- if (i == 1)
- v->vc1dsp.vc1_inv_trans_4x8_dc(dst + j * 4, linesize, block + off);
- else
- v->vc1dsp.vc1_inv_trans_4x8(dst + j*4, linesize, block + off);
- }
- }
- break;
- }
- if (ttmb_out)
- *ttmb_out |= ttblk << (n * 4);
- return pat;
-}
-
-/** @} */ // Macroblock group
-
-static const int size_table [6] = { 0, 2, 3, 4, 5, 8 };
-static const int offset_table[6] = { 0, 1, 3, 7, 15, 31 };
-
-static av_always_inline void vc1_apply_p_v_loop_filter(VC1Context *v, int block_num)
-{
- MpegEncContext *s = &v->s;
- int mb_cbp = v->cbp[s->mb_x - s->mb_stride],
- block_cbp = mb_cbp >> (block_num * 4), bottom_cbp,
- mb_is_intra = v->is_intra[s->mb_x - s->mb_stride],
- block_is_intra = mb_is_intra >> (block_num * 4), bottom_is_intra;
- int idx, linesize = block_num > 3 ? s->uvlinesize : s->linesize, ttblk;
- uint8_t *dst;
-
- if (block_num > 3) {
- dst = s->dest[block_num - 3];
- } else {
- dst = s->dest[0] + (block_num & 1) * 8 + ((block_num & 2) * 4 - 8) * linesize;
- }
- if (s->mb_y != s->end_mb_y || block_num < 2) {
- int16_t (*mv)[2];
- int mv_stride;
-
- if (block_num > 3) {
- bottom_cbp = v->cbp[s->mb_x] >> (block_num * 4);
- bottom_is_intra = v->is_intra[s->mb_x] >> (block_num * 4);
- mv = &v->luma_mv[s->mb_x - s->mb_stride];
- mv_stride = s->mb_stride;
- } else {
- bottom_cbp = (block_num < 2) ? (mb_cbp >> ((block_num + 2) * 4))
- : (v->cbp[s->mb_x] >> ((block_num - 2) * 4));
- bottom_is_intra = (block_num < 2) ? (mb_is_intra >> ((block_num + 2) * 4))
- : (v->is_intra[s->mb_x] >> ((block_num - 2) * 4));
- mv_stride = s->b8_stride;
- mv = &s->current_picture.motion_val[0][s->block_index[block_num] - 2 * mv_stride];
- }
-
- if (bottom_is_intra & 1 || block_is_intra & 1 ||
- mv[0][0] != mv[mv_stride][0] || mv[0][1] != mv[mv_stride][1]) {
- v->vc1dsp.vc1_v_loop_filter8(dst, linesize, v->pq);
- } else {
- idx = ((bottom_cbp >> 2) | block_cbp) & 3;
- if (idx == 3) {
- v->vc1dsp.vc1_v_loop_filter8(dst, linesize, v->pq);
- } else if (idx) {
- if (idx == 1)
- v->vc1dsp.vc1_v_loop_filter4(dst + 4, linesize, v->pq);
- else
- v->vc1dsp.vc1_v_loop_filter4(dst, linesize, v->pq);
- }
- }
- }
-
- dst -= 4 * linesize;
- ttblk = (v->ttblk[s->mb_x - s->mb_stride] >> (block_num * 4)) & 0xF;
- if (ttblk == TT_4X4 || ttblk == TT_8X4) {
- idx = (block_cbp | (block_cbp >> 2)) & 3;
- if (idx == 3) {
- v->vc1dsp.vc1_v_loop_filter8(dst, linesize, v->pq);
- } else if (idx) {
- if (idx == 1)
- v->vc1dsp.vc1_v_loop_filter4(dst + 4, linesize, v->pq);
- else
- v->vc1dsp.vc1_v_loop_filter4(dst, linesize, v->pq);
- }
- }
-}
-
-static av_always_inline void vc1_apply_p_h_loop_filter(VC1Context *v, int block_num)
-{
- MpegEncContext *s = &v->s;
- int mb_cbp = v->cbp[s->mb_x - 1 - s->mb_stride],
- block_cbp = mb_cbp >> (block_num * 4), right_cbp,
- mb_is_intra = v->is_intra[s->mb_x - 1 - s->mb_stride],
- block_is_intra = mb_is_intra >> (block_num * 4), right_is_intra;
- int idx, linesize = block_num > 3 ? s->uvlinesize : s->linesize, ttblk;
- uint8_t *dst;
-
- if (block_num > 3) {
- dst = s->dest[block_num - 3] - 8 * linesize;
- } else {
- dst = s->dest[0] + (block_num & 1) * 8 + ((block_num & 2) * 4 - 16) * linesize - 8;
- }
-
- if (s->mb_x != s->mb_width || !(block_num & 5)) {
- int16_t (*mv)[2];
-
- if (block_num > 3) {
- right_cbp = v->cbp[s->mb_x - s->mb_stride] >> (block_num * 4);
- right_is_intra = v->is_intra[s->mb_x - s->mb_stride] >> (block_num * 4);
- mv = &v->luma_mv[s->mb_x - s->mb_stride - 1];
- } else {
- right_cbp = (block_num & 1) ? (v->cbp[s->mb_x - s->mb_stride] >> ((block_num - 1) * 4))
- : (mb_cbp >> ((block_num + 1) * 4));
- right_is_intra = (block_num & 1) ? (v->is_intra[s->mb_x - s->mb_stride] >> ((block_num - 1) * 4))
- : (mb_is_intra >> ((block_num + 1) * 4));
- mv = &s->current_picture.motion_val[0][s->block_index[block_num] - s->b8_stride * 2 - 2];
- }
- if (block_is_intra & 1 || right_is_intra & 1 || mv[0][0] != mv[1][0] || mv[0][1] != mv[1][1]) {
- v->vc1dsp.vc1_h_loop_filter8(dst, linesize, v->pq);
- } else {
- idx = ((right_cbp >> 1) | block_cbp) & 5; // FIXME check
- if (idx == 5) {
- v->vc1dsp.vc1_h_loop_filter8(dst, linesize, v->pq);
- } else if (idx) {
- if (idx == 1)
- v->vc1dsp.vc1_h_loop_filter4(dst + 4 * linesize, linesize, v->pq);
- else
- v->vc1dsp.vc1_h_loop_filter4(dst, linesize, v->pq);
- }
- }
- }
-
- dst -= 4;
- ttblk = (v->ttblk[s->mb_x - s->mb_stride - 1] >> (block_num * 4)) & 0xf;
- if (ttblk == TT_4X4 || ttblk == TT_4X8) {
- idx = (block_cbp | (block_cbp >> 1)) & 5;
- if (idx == 5) {
- v->vc1dsp.vc1_h_loop_filter8(dst, linesize, v->pq);
- } else if (idx) {
- if (idx == 1)
- v->vc1dsp.vc1_h_loop_filter4(dst + linesize * 4, linesize, v->pq);
- else
- v->vc1dsp.vc1_h_loop_filter4(dst, linesize, v->pq);
- }
- }
-}
-
-static void vc1_apply_p_loop_filter(VC1Context *v)
-{
- MpegEncContext *s = &v->s;
- int i;
-
- for (i = 0; i < 6; i++) {
- vc1_apply_p_v_loop_filter(v, i);
- }
-
- /* V always precedes H, therefore we run H one MB before V;
- * at the end of a row, we catch up to complete the row */
- if (s->mb_x) {
- for (i = 0; i < 6; i++) {
- vc1_apply_p_h_loop_filter(v, i);
- }
- if (s->mb_x == s->mb_width - 1) {
- s->mb_x++;
- ff_update_block_index(s);
- for (i = 0; i < 6; i++) {
- vc1_apply_p_h_loop_filter(v, i);
- }
- }
- }
-}
-
-/** Decode one P-frame MB
- */
-static int vc1_decode_p_mb(VC1Context *v)
-{
- MpegEncContext *s = &v->s;
- GetBitContext *gb = &s->gb;
- int i, j;
- int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
- int cbp; /* cbp decoding stuff */
- int mqdiff, mquant; /* MB quantization */
- int ttmb = v->ttfrm; /* MB Transform type */
-
- int mb_has_coeffs = 1; /* last_flag */
- int dmv_x, dmv_y; /* Differential MV components */
- int index, index1; /* LUT indexes */
- int val, sign; /* temp values */
- int first_block = 1;
- int dst_idx, off;
- int skipped, fourmv;
- int block_cbp = 0, pat, block_tt = 0, block_intra = 0;
-
- mquant = v->pq; /* lossy initialization */
-
- if (v->mv_type_is_raw)
- fourmv = get_bits1(gb);
- else
- fourmv = v->mv_type_mb_plane[mb_pos];
- if (v->skip_is_raw)
- skipped = get_bits1(gb);
- else
- skipped = v->s.mbskip_table[mb_pos];
-
- if (!fourmv) { /* 1MV mode */
- if (!skipped) {
- GET_MVDATA(dmv_x, dmv_y);
-
- if (s->mb_intra) {
- s->current_picture.motion_val[1][s->block_index[0]][0] = 0;
- s->current_picture.motion_val[1][s->block_index[0]][1] = 0;
- }
- s->current_picture.mb_type[mb_pos] = s->mb_intra ? MB_TYPE_INTRA : MB_TYPE_16x16;
- vc1_pred_mv(v, 0, dmv_x, dmv_y, 1, v->range_x, v->range_y, v->mb_type[0], 0, 0);
-
- /* FIXME Set DC val for inter block ? */
- if (s->mb_intra && !mb_has_coeffs) {
- GET_MQUANT();
- s->ac_pred = get_bits1(gb);
- cbp = 0;
- } else if (mb_has_coeffs) {
- if (s->mb_intra)
- s->ac_pred = get_bits1(gb);
- cbp = get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2);
- GET_MQUANT();
- } else {
- mquant = v->pq;
- cbp = 0;
- }
- s->current_picture.qscale_table[mb_pos] = mquant;
-
- if (!v->ttmbf && !s->mb_intra && mb_has_coeffs)
- ttmb = get_vlc2(gb, ff_vc1_ttmb_vlc[v->tt_index].table,
- VC1_TTMB_VLC_BITS, 2);
- if (!s->mb_intra) vc1_mc_1mv(v, 0);
- dst_idx = 0;
- for (i = 0; i < 6; i++) {
- s->dc_val[0][s->block_index[i]] = 0;
- dst_idx += i >> 2;
- val = ((cbp >> (5 - i)) & 1);
- off = (i & 4) ? 0 : ((i & 1) * 8 + (i & 2) * 4 * s->linesize);
- v->mb_type[0][s->block_index[i]] = s->mb_intra;
- if (s->mb_intra) {
- /* check if prediction blocks A and C are available */
- v->a_avail = v->c_avail = 0;
- if (i == 2 || i == 3 || !s->first_slice_line)
- v->a_avail = v->mb_type[0][s->block_index[i] - s->block_wrap[i]];
- if (i == 1 || i == 3 || s->mb_x)
- v->c_avail = v->mb_type[0][s->block_index[i] - 1];
-
- vc1_decode_intra_block(v, s->block[i], i, val, mquant,
- (i & 4) ? v->codingset2 : v->codingset);
- if ((i>3) && (s->flags & CODEC_FLAG_GRAY))
- continue;
- v->vc1dsp.vc1_inv_trans_8x8(s->block[i]);
- if (v->rangeredfrm)
- for (j = 0; j < 64; j++)
- s->block[i][j] <<= 1;
- s->idsp.put_signed_pixels_clamped(s->block[i],
- s->dest[dst_idx] + off,
- i & 4 ? s->uvlinesize
- : s->linesize);
- if (v->pq >= 9 && v->overlap) {
- if (v->c_avail)
- v->vc1dsp.vc1_h_overlap(s->dest[dst_idx] + off, i & 4 ? s->uvlinesize : s->linesize);
- if (v->a_avail)
- v->vc1dsp.vc1_v_overlap(s->dest[dst_idx] + off, i & 4 ? s->uvlinesize : s->linesize);
- }
- block_cbp |= 0xF << (i << 2);
- block_intra |= 1 << i;
- } else if (val) {
- pat = vc1_decode_p_block(v, s->block[i], i, mquant, ttmb, first_block,
- s->dest[dst_idx] + off, (i & 4) ? s->uvlinesize : s->linesize,
- (i & 4) && (s->flags & CODEC_FLAG_GRAY), &block_tt);
- block_cbp |= pat << (i << 2);
- if (!v->ttmbf && ttmb < 8)
- ttmb = -1;
- first_block = 0;
- }
- }
- } else { // skipped
- s->mb_intra = 0;
- for (i = 0; i < 6; i++) {
- v->mb_type[0][s->block_index[i]] = 0;
- s->dc_val[0][s->block_index[i]] = 0;
- }
- s->current_picture.mb_type[mb_pos] = MB_TYPE_SKIP;
- s->current_picture.qscale_table[mb_pos] = 0;
- vc1_pred_mv(v, 0, 0, 0, 1, v->range_x, v->range_y, v->mb_type[0], 0, 0);
- vc1_mc_1mv(v, 0);
- }
- } else { // 4MV mode
- if (!skipped /* unskipped MB */) {
- int intra_count = 0, coded_inter = 0;
- int is_intra[6], is_coded[6];
- /* Get CBPCY */
- cbp = get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2);
- for (i = 0; i < 6; i++) {
- val = ((cbp >> (5 - i)) & 1);
- s->dc_val[0][s->block_index[i]] = 0;
- s->mb_intra = 0;
- if (i < 4) {
- dmv_x = dmv_y = 0;
- s->mb_intra = 0;
- mb_has_coeffs = 0;
- if (val) {
- GET_MVDATA(dmv_x, dmv_y);
- }
- vc1_pred_mv(v, i, dmv_x, dmv_y, 0, v->range_x, v->range_y, v->mb_type[0], 0, 0);
- if (!s->mb_intra)
- vc1_mc_4mv_luma(v, i, 0, 0);
- intra_count += s->mb_intra;
- is_intra[i] = s->mb_intra;
- is_coded[i] = mb_has_coeffs;
- }
- if (i & 4) {
- is_intra[i] = (intra_count >= 3);
- is_coded[i] = val;
- }
- if (i == 4)
- vc1_mc_4mv_chroma(v, 0);
- v->mb_type[0][s->block_index[i]] = is_intra[i];
- if (!coded_inter)
- coded_inter = !is_intra[i] & is_coded[i];
- }
- // if there are no coded blocks then don't do anything more
- dst_idx = 0;
- if (!intra_count && !coded_inter)
- goto end;
- GET_MQUANT();
- s->current_picture.qscale_table[mb_pos] = mquant;
- /* test if block is intra and has pred */
- {
- int intrapred = 0;
- for (i = 0; i < 6; i++)
- if (is_intra[i]) {
- if (((!s->first_slice_line || (i == 2 || i == 3)) && v->mb_type[0][s->block_index[i] - s->block_wrap[i]])
- || ((s->mb_x || (i == 1 || i == 3)) && v->mb_type[0][s->block_index[i] - 1])) {
- intrapred = 1;
- break;
- }
- }
- if (intrapred)
- s->ac_pred = get_bits1(gb);
- else
- s->ac_pred = 0;
- }
- if (!v->ttmbf && coded_inter)
- ttmb = get_vlc2(gb, ff_vc1_ttmb_vlc[v->tt_index].table, VC1_TTMB_VLC_BITS, 2);
- for (i = 0; i < 6; i++) {
- dst_idx += i >> 2;
- off = (i & 4) ? 0 : ((i & 1) * 8 + (i & 2) * 4 * s->linesize);
- s->mb_intra = is_intra[i];
- if (is_intra[i]) {
- /* check if prediction blocks A and C are available */
- v->a_avail = v->c_avail = 0;
- if (i == 2 || i == 3 || !s->first_slice_line)
- v->a_avail = v->mb_type[0][s->block_index[i] - s->block_wrap[i]];
- if (i == 1 || i == 3 || s->mb_x)
- v->c_avail = v->mb_type[0][s->block_index[i] - 1];
-
- vc1_decode_intra_block(v, s->block[i], i, is_coded[i], mquant,
- (i & 4) ? v->codingset2 : v->codingset);
- if ((i>3) && (s->flags & CODEC_FLAG_GRAY))
- continue;
- v->vc1dsp.vc1_inv_trans_8x8(s->block[i]);
- if (v->rangeredfrm)
- for (j = 0; j < 64; j++)
- s->block[i][j] <<= 1;
- s->idsp.put_signed_pixels_clamped(s->block[i],
- s->dest[dst_idx] + off,
- (i & 4) ? s->uvlinesize
- : s->linesize);
- if (v->pq >= 9 && v->overlap) {
- if (v->c_avail)
- v->vc1dsp.vc1_h_overlap(s->dest[dst_idx] + off, i & 4 ? s->uvlinesize : s->linesize);
- if (v->a_avail)
- v->vc1dsp.vc1_v_overlap(s->dest[dst_idx] + off, i & 4 ? s->uvlinesize : s->linesize);
- }
- block_cbp |= 0xF << (i << 2);
- block_intra |= 1 << i;
- } else if (is_coded[i]) {
- pat = vc1_decode_p_block(v, s->block[i], i, mquant, ttmb,
- first_block, s->dest[dst_idx] + off,
- (i & 4) ? s->uvlinesize : s->linesize,
- (i & 4) && (s->flags & CODEC_FLAG_GRAY),
- &block_tt);
- block_cbp |= pat << (i << 2);
- if (!v->ttmbf && ttmb < 8)
- ttmb = -1;
- first_block = 0;
- }
- }
- } else { // skipped MB
- s->mb_intra = 0;
- s->current_picture.qscale_table[mb_pos] = 0;
- for (i = 0; i < 6; i++) {
- v->mb_type[0][s->block_index[i]] = 0;
- s->dc_val[0][s->block_index[i]] = 0;
- }
- for (i = 0; i < 4; i++) {
- vc1_pred_mv(v, i, 0, 0, 0, v->range_x, v->range_y, v->mb_type[0], 0, 0);
- vc1_mc_4mv_luma(v, i, 0, 0);
- }
- vc1_mc_4mv_chroma(v, 0);
- s->current_picture.qscale_table[mb_pos] = 0;
- }
- }
-end:
- v->cbp[s->mb_x] = block_cbp;
- v->ttblk[s->mb_x] = block_tt;
- v->is_intra[s->mb_x] = block_intra;
-
- return 0;
-}
-
-/* Decode one macroblock in an interlaced frame p picture */
-
-static int vc1_decode_p_mb_intfr(VC1Context *v)
-{
- MpegEncContext *s = &v->s;
- GetBitContext *gb = &s->gb;
- int i;
- int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
- int cbp = 0; /* cbp decoding stuff */
- int mqdiff, mquant; /* MB quantization */
- int ttmb = v->ttfrm; /* MB Transform type */
-
- int mb_has_coeffs = 1; /* last_flag */
- int dmv_x, dmv_y; /* Differential MV components */
- int val; /* temp value */
- int first_block = 1;
- int dst_idx, off;
- int skipped, fourmv = 0, twomv = 0;
- int block_cbp = 0, pat, block_tt = 0;
- int idx_mbmode = 0, mvbp;
- int stride_y, fieldtx;
-
- mquant = v->pq; /* Lossy initialization */
-
- if (v->skip_is_raw)
- skipped = get_bits1(gb);
- else
- skipped = v->s.mbskip_table[mb_pos];
- if (!skipped) {
- if (v->fourmvswitch)
- idx_mbmode = get_vlc2(gb, v->mbmode_vlc->table, VC1_INTFR_4MV_MBMODE_VLC_BITS, 2); // try getting this done
- else
- idx_mbmode = get_vlc2(gb, v->mbmode_vlc->table, VC1_INTFR_NON4MV_MBMODE_VLC_BITS, 2); // in a single line
- switch (ff_vc1_mbmode_intfrp[v->fourmvswitch][idx_mbmode][0]) {
- /* store the motion vector type in a flag (useful later) */
- case MV_PMODE_INTFR_4MV:
- fourmv = 1;
- v->blk_mv_type[s->block_index[0]] = 0;
- v->blk_mv_type[s->block_index[1]] = 0;
- v->blk_mv_type[s->block_index[2]] = 0;
- v->blk_mv_type[s->block_index[3]] = 0;
- break;
- case MV_PMODE_INTFR_4MV_FIELD:
- fourmv = 1;
- v->blk_mv_type[s->block_index[0]] = 1;
- v->blk_mv_type[s->block_index[1]] = 1;
- v->blk_mv_type[s->block_index[2]] = 1;
- v->blk_mv_type[s->block_index[3]] = 1;
- break;
- case MV_PMODE_INTFR_2MV_FIELD:
- twomv = 1;
- v->blk_mv_type[s->block_index[0]] = 1;
- v->blk_mv_type[s->block_index[1]] = 1;
- v->blk_mv_type[s->block_index[2]] = 1;
- v->blk_mv_type[s->block_index[3]] = 1;
- break;
- case MV_PMODE_INTFR_1MV:
- v->blk_mv_type[s->block_index[0]] = 0;
- v->blk_mv_type[s->block_index[1]] = 0;
- v->blk_mv_type[s->block_index[2]] = 0;
- v->blk_mv_type[s->block_index[3]] = 0;
- break;
- }
- if (ff_vc1_mbmode_intfrp[v->fourmvswitch][idx_mbmode][0] == MV_PMODE_INTFR_INTRA) { // intra MB
- for (i = 0; i < 4; i++) {
- s->current_picture.motion_val[1][s->block_index[i]][0] = 0;
- s->current_picture.motion_val[1][s->block_index[i]][1] = 0;
- }
- s->current_picture.mb_type[mb_pos] = MB_TYPE_INTRA;
- s->mb_intra = v->is_intra[s->mb_x] = 1;
- for (i = 0; i < 6; i++)
- v->mb_type[0][s->block_index[i]] = 1;
- fieldtx = v->fieldtx_plane[mb_pos] = get_bits1(gb);
- mb_has_coeffs = get_bits1(gb);
- if (mb_has_coeffs)
- cbp = 1 + get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2);
- v->s.ac_pred = v->acpred_plane[mb_pos] = get_bits1(gb);
- GET_MQUANT();
- s->current_picture.qscale_table[mb_pos] = mquant;
- /* Set DC scale - y and c use the same (not sure if necessary here) */
- s->y_dc_scale = s->y_dc_scale_table[mquant];
- s->c_dc_scale = s->c_dc_scale_table[mquant];
- dst_idx = 0;
- for (i = 0; i < 6; i++) {
- s->dc_val[0][s->block_index[i]] = 0;
- dst_idx += i >> 2;
- val = ((cbp >> (5 - i)) & 1);
- v->mb_type[0][s->block_index[i]] = s->mb_intra;
- v->a_avail = v->c_avail = 0;
- if (i == 2 || i == 3 || !s->first_slice_line)
- v->a_avail = v->mb_type[0][s->block_index[i] - s->block_wrap[i]];
- if (i == 1 || i == 3 || s->mb_x)
- v->c_avail = v->mb_type[0][s->block_index[i] - 1];
-
- vc1_decode_intra_block(v, s->block[i], i, val, mquant,
- (i & 4) ? v->codingset2 : v->codingset);
- if ((i>3) && (s->flags & CODEC_FLAG_GRAY)) continue;
- v->vc1dsp.vc1_inv_trans_8x8(s->block[i]);
- if (i < 4) {
- stride_y = s->linesize << fieldtx;
- off = (fieldtx) ? ((i & 1) * 8) + ((i & 2) >> 1) * s->linesize : (i & 1) * 8 + 4 * (i & 2) * s->linesize;
- } else {
- stride_y = s->uvlinesize;
- off = 0;
- }
- s->idsp.put_signed_pixels_clamped(s->block[i],
- s->dest[dst_idx] + off,
- stride_y);
- //TODO: loop filter
- }
-
- } else { // inter MB
- mb_has_coeffs = ff_vc1_mbmode_intfrp[v->fourmvswitch][idx_mbmode][3];
- if (mb_has_coeffs)
- cbp = 1 + get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2);
- if (ff_vc1_mbmode_intfrp[v->fourmvswitch][idx_mbmode][0] == MV_PMODE_INTFR_2MV_FIELD) {
- v->twomvbp = get_vlc2(gb, v->twomvbp_vlc->table, VC1_2MV_BLOCK_PATTERN_VLC_BITS, 1);
- } else {
- if ((ff_vc1_mbmode_intfrp[v->fourmvswitch][idx_mbmode][0] == MV_PMODE_INTFR_4MV)
- || (ff_vc1_mbmode_intfrp[v->fourmvswitch][idx_mbmode][0] == MV_PMODE_INTFR_4MV_FIELD)) {
- v->fourmvbp = get_vlc2(gb, v->fourmvbp_vlc->table, VC1_4MV_BLOCK_PATTERN_VLC_BITS, 1);
- }
- }
- s->mb_intra = v->is_intra[s->mb_x] = 0;
- for (i = 0; i < 6; i++)
- v->mb_type[0][s->block_index[i]] = 0;
- fieldtx = v->fieldtx_plane[mb_pos] = ff_vc1_mbmode_intfrp[v->fourmvswitch][idx_mbmode][1];
- /* for all motion vector read MVDATA and motion compensate each block */
- dst_idx = 0;
- if (fourmv) {
- mvbp = v->fourmvbp;
- for (i = 0; i < 6; i++) {
- if (i < 4) {
- dmv_x = dmv_y = 0;
- val = ((mvbp >> (3 - i)) & 1);
- if (val) {
- get_mvdata_interlaced(v, &dmv_x, &dmv_y, 0);
- }
- vc1_pred_mv_intfr(v, i, dmv_x, dmv_y, 0, v->range_x, v->range_y, v->mb_type[0], 0);
- vc1_mc_4mv_luma(v, i, 0, 0);
- } else if (i == 4) {
- vc1_mc_4mv_chroma4(v, 0, 0, 0);
- }
- }
- } else if (twomv) {
- mvbp = v->twomvbp;
- dmv_x = dmv_y = 0;
- if (mvbp & 2) {
- get_mvdata_interlaced(v, &dmv_x, &dmv_y, 0);
- }
- vc1_pred_mv_intfr(v, 0, dmv_x, dmv_y, 2, v->range_x, v->range_y, v->mb_type[0], 0);
- vc1_mc_4mv_luma(v, 0, 0, 0);
- vc1_mc_4mv_luma(v, 1, 0, 0);
- dmv_x = dmv_y = 0;
- if (mvbp & 1) {
- get_mvdata_interlaced(v, &dmv_x, &dmv_y, 0);
- }
- vc1_pred_mv_intfr(v, 2, dmv_x, dmv_y, 2, v->range_x, v->range_y, v->mb_type[0], 0);
- vc1_mc_4mv_luma(v, 2, 0, 0);
- vc1_mc_4mv_luma(v, 3, 0, 0);
- vc1_mc_4mv_chroma4(v, 0, 0, 0);
- } else {
- mvbp = ff_vc1_mbmode_intfrp[v->fourmvswitch][idx_mbmode][2];
- dmv_x = dmv_y = 0;
- if (mvbp) {
- get_mvdata_interlaced(v, &dmv_x, &dmv_y, 0);
- }
- vc1_pred_mv_intfr(v, 0, dmv_x, dmv_y, 1, v->range_x, v->range_y, v->mb_type[0], 0);
- vc1_mc_1mv(v, 0);
- }
- if (cbp)
- GET_MQUANT(); // p. 227
- s->current_picture.qscale_table[mb_pos] = mquant;
- if (!v->ttmbf && cbp)
- ttmb = get_vlc2(gb, ff_vc1_ttmb_vlc[v->tt_index].table, VC1_TTMB_VLC_BITS, 2);
- for (i = 0; i < 6; i++) {
- s->dc_val[0][s->block_index[i]] = 0;
- dst_idx += i >> 2;
- val = ((cbp >> (5 - i)) & 1);
- if (!fieldtx)
- off = (i & 4) ? 0 : ((i & 1) * 8 + (i & 2) * 4 * s->linesize);
- else
- off = (i & 4) ? 0 : ((i & 1) * 8 + ((i > 1) * s->linesize));
- if (val) {
- pat = vc1_decode_p_block(v, s->block[i], i, mquant, ttmb,
- first_block, s->dest[dst_idx] + off,
- (i & 4) ? s->uvlinesize : (s->linesize << fieldtx),
- (i & 4) && (s->flags & CODEC_FLAG_GRAY), &block_tt);
- block_cbp |= pat << (i << 2);
- if (!v->ttmbf && ttmb < 8)
- ttmb = -1;
- first_block = 0;
- }
- }
- }
- } else { // skipped
- s->mb_intra = v->is_intra[s->mb_x] = 0;
- for (i = 0; i < 6; i++) {
- v->mb_type[0][s->block_index[i]] = 0;
- s->dc_val[0][s->block_index[i]] = 0;
- }
- s->current_picture.mb_type[mb_pos] = MB_TYPE_SKIP;
- s->current_picture.qscale_table[mb_pos] = 0;
- v->blk_mv_type[s->block_index[0]] = 0;
- v->blk_mv_type[s->block_index[1]] = 0;
- v->blk_mv_type[s->block_index[2]] = 0;
- v->blk_mv_type[s->block_index[3]] = 0;
- vc1_pred_mv_intfr(v, 0, 0, 0, 1, v->range_x, v->range_y, v->mb_type[0], 0);
- vc1_mc_1mv(v, 0);
- }
- if (s->mb_x == s->mb_width - 1)
- memmove(v->is_intra_base, v->is_intra, sizeof(v->is_intra_base[0])*s->mb_stride);
- return 0;
-}
-
-static int vc1_decode_p_mb_intfi(VC1Context *v)
-{
- MpegEncContext *s = &v->s;
- GetBitContext *gb = &s->gb;
- int i;
- int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
- int cbp = 0; /* cbp decoding stuff */
- int mqdiff, mquant; /* MB quantization */
- int ttmb = v->ttfrm; /* MB Transform type */
-
- int mb_has_coeffs = 1; /* last_flag */
- int dmv_x, dmv_y; /* Differential MV components */
- int val; /* temp values */
- int first_block = 1;
- int dst_idx, off;
- int pred_flag = 0;
- int block_cbp = 0, pat, block_tt = 0;
- int idx_mbmode = 0;
-
- mquant = v->pq; /* Lossy initialization */
-
- idx_mbmode = get_vlc2(gb, v->mbmode_vlc->table, VC1_IF_MBMODE_VLC_BITS, 2);
- if (idx_mbmode <= 1) { // intra MB
- s->mb_intra = v->is_intra[s->mb_x] = 1;
- s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][0] = 0;
- s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][1] = 0;
- s->current_picture.mb_type[mb_pos + v->mb_off] = MB_TYPE_INTRA;
- GET_MQUANT();
- s->current_picture.qscale_table[mb_pos] = mquant;
- /* Set DC scale - y and c use the same (not sure if necessary here) */
- s->y_dc_scale = s->y_dc_scale_table[mquant];
- s->c_dc_scale = s->c_dc_scale_table[mquant];
- v->s.ac_pred = v->acpred_plane[mb_pos] = get_bits1(gb);
- mb_has_coeffs = idx_mbmode & 1;
- if (mb_has_coeffs)
- cbp = 1 + get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_ICBPCY_VLC_BITS, 2);
- dst_idx = 0;
- for (i = 0; i < 6; i++) {
- s->dc_val[0][s->block_index[i]] = 0;
- v->mb_type[0][s->block_index[i]] = 1;
- dst_idx += i >> 2;
- val = ((cbp >> (5 - i)) & 1);
- v->a_avail = v->c_avail = 0;
- if (i == 2 || i == 3 || !s->first_slice_line)
- v->a_avail = v->mb_type[0][s->block_index[i] - s->block_wrap[i]];
- if (i == 1 || i == 3 || s->mb_x)
- v->c_avail = v->mb_type[0][s->block_index[i] - 1];
-
- vc1_decode_intra_block(v, s->block[i], i, val, mquant,
- (i & 4) ? v->codingset2 : v->codingset);
- if ((i>3) && (s->flags & CODEC_FLAG_GRAY))
- continue;
- v->vc1dsp.vc1_inv_trans_8x8(s->block[i]);
- off = (i & 4) ? 0 : ((i & 1) * 8 + (i & 2) * 4 * s->linesize);
- s->idsp.put_signed_pixels_clamped(s->block[i],
- s->dest[dst_idx] + off,
- (i & 4) ? s->uvlinesize
- : s->linesize);
- // TODO: loop filter
- }
- } else {
- s->mb_intra = v->is_intra[s->mb_x] = 0;
- s->current_picture.mb_type[mb_pos + v->mb_off] = MB_TYPE_16x16;
- for (i = 0; i < 6; i++) v->mb_type[0][s->block_index[i]] = 0;
- if (idx_mbmode <= 5) { // 1-MV
- dmv_x = dmv_y = pred_flag = 0;
- if (idx_mbmode & 1) {
- get_mvdata_interlaced(v, &dmv_x, &dmv_y, &pred_flag);
- }
- vc1_pred_mv(v, 0, dmv_x, dmv_y, 1, v->range_x, v->range_y, v->mb_type[0], pred_flag, 0);
- vc1_mc_1mv(v, 0);
- mb_has_coeffs = !(idx_mbmode & 2);
- } else { // 4-MV
- v->fourmvbp = get_vlc2(gb, v->fourmvbp_vlc->table, VC1_4MV_BLOCK_PATTERN_VLC_BITS, 1);
- for (i = 0; i < 6; i++) {
- if (i < 4) {
- dmv_x = dmv_y = pred_flag = 0;
- val = ((v->fourmvbp >> (3 - i)) & 1);
- if (val) {
- get_mvdata_interlaced(v, &dmv_x, &dmv_y, &pred_flag);
- }
- vc1_pred_mv(v, i, dmv_x, dmv_y, 0, v->range_x, v->range_y, v->mb_type[0], pred_flag, 0);
- vc1_mc_4mv_luma(v, i, 0, 0);
- } else if (i == 4)
- vc1_mc_4mv_chroma(v, 0);
- }
- mb_has_coeffs = idx_mbmode & 1;
- }
- if (mb_has_coeffs)
- cbp = 1 + get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2);
- if (cbp) {
- GET_MQUANT();
- }
- s->current_picture.qscale_table[mb_pos] = mquant;
- if (!v->ttmbf && cbp) {
- ttmb = get_vlc2(gb, ff_vc1_ttmb_vlc[v->tt_index].table, VC1_TTMB_VLC_BITS, 2);
- }
- dst_idx = 0;
- for (i = 0; i < 6; i++) {
- s->dc_val[0][s->block_index[i]] = 0;
- dst_idx += i >> 2;
- val = ((cbp >> (5 - i)) & 1);
- off = (i & 4) ? 0 : (i & 1) * 8 + (i & 2) * 4 * s->linesize;
- if (val) {
- pat = vc1_decode_p_block(v, s->block[i], i, mquant, ttmb,
- first_block, s->dest[dst_idx] + off,
- (i & 4) ? s->uvlinesize : s->linesize,
- (i & 4) && (s->flags & CODEC_FLAG_GRAY),
- &block_tt);
- block_cbp |= pat << (i << 2);
- if (!v->ttmbf && ttmb < 8) ttmb = -1;
- first_block = 0;
- }
- }
- }
- if (s->mb_x == s->mb_width - 1)
- memmove(v->is_intra_base, v->is_intra, sizeof(v->is_intra_base[0]) * s->mb_stride);
- return 0;
-}
-
-/** Decode one B-frame MB (in Main profile)
- */
-static void vc1_decode_b_mb(VC1Context *v)
-{
- MpegEncContext *s = &v->s;
- GetBitContext *gb = &s->gb;
- int i, j;
- int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
- int cbp = 0; /* cbp decoding stuff */
- int mqdiff, mquant; /* MB quantization */
- int ttmb = v->ttfrm; /* MB Transform type */
- int mb_has_coeffs = 0; /* last_flag */
- int index, index1; /* LUT indexes */
- int val, sign; /* temp values */
- int first_block = 1;
- int dst_idx, off;
- int skipped, direct;
- int dmv_x[2], dmv_y[2];
- int bmvtype = BMV_TYPE_BACKWARD;
-
- mquant = v->pq; /* lossy initialization */
- s->mb_intra = 0;
-
- if (v->dmb_is_raw)
- direct = get_bits1(gb);
- else
- direct = v->direct_mb_plane[mb_pos];
- if (v->skip_is_raw)
- skipped = get_bits1(gb);
- else
- skipped = v->s.mbskip_table[mb_pos];
-
- dmv_x[0] = dmv_x[1] = dmv_y[0] = dmv_y[1] = 0;
- for (i = 0; i < 6; i++) {
- v->mb_type[0][s->block_index[i]] = 0;
- s->dc_val[0][s->block_index[i]] = 0;
- }
- s->current_picture.qscale_table[mb_pos] = 0;
-
- if (!direct) {
- if (!skipped) {
- GET_MVDATA(dmv_x[0], dmv_y[0]);
- dmv_x[1] = dmv_x[0];
- dmv_y[1] = dmv_y[0];
- }
- if (skipped || !s->mb_intra) {
- bmvtype = decode012(gb);
- switch (bmvtype) {
- case 0:
- bmvtype = (v->bfraction >= (B_FRACTION_DEN/2)) ? BMV_TYPE_BACKWARD : BMV_TYPE_FORWARD;
- break;
- case 1:
- bmvtype = (v->bfraction >= (B_FRACTION_DEN/2)) ? BMV_TYPE_FORWARD : BMV_TYPE_BACKWARD;
- break;
- case 2:
- bmvtype = BMV_TYPE_INTERPOLATED;
- dmv_x[0] = dmv_y[0] = 0;
- }
- }
- }
- for (i = 0; i < 6; i++)
- v->mb_type[0][s->block_index[i]] = s->mb_intra;
-
- if (skipped) {
- if (direct)
- bmvtype = BMV_TYPE_INTERPOLATED;
- vc1_pred_b_mv(v, dmv_x, dmv_y, direct, bmvtype);
- vc1_b_mc(v, dmv_x, dmv_y, direct, bmvtype);
- return;
- }
- if (direct) {
- cbp = get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2);
- GET_MQUANT();
- s->mb_intra = 0;
- s->current_picture.qscale_table[mb_pos] = mquant;
- if (!v->ttmbf)
- ttmb = get_vlc2(gb, ff_vc1_ttmb_vlc[v->tt_index].table, VC1_TTMB_VLC_BITS, 2);
- dmv_x[0] = dmv_y[0] = dmv_x[1] = dmv_y[1] = 0;
- vc1_pred_b_mv(v, dmv_x, dmv_y, direct, bmvtype);
- vc1_b_mc(v, dmv_x, dmv_y, direct, bmvtype);
- } else {
- if (!mb_has_coeffs && !s->mb_intra) {
- /* no coded blocks - effectively skipped */
- vc1_pred_b_mv(v, dmv_x, dmv_y, direct, bmvtype);
- vc1_b_mc(v, dmv_x, dmv_y, direct, bmvtype);
- return;
- }
- if (s->mb_intra && !mb_has_coeffs) {
- GET_MQUANT();
- s->current_picture.qscale_table[mb_pos] = mquant;
- s->ac_pred = get_bits1(gb);
- cbp = 0;
- vc1_pred_b_mv(v, dmv_x, dmv_y, direct, bmvtype);
- } else {
- if (bmvtype == BMV_TYPE_INTERPOLATED) {
- GET_MVDATA(dmv_x[0], dmv_y[0]);
- if (!mb_has_coeffs) {
- /* interpolated skipped block */
- vc1_pred_b_mv(v, dmv_x, dmv_y, direct, bmvtype);
- vc1_b_mc(v, dmv_x, dmv_y, direct, bmvtype);
- return;
- }
- }
- vc1_pred_b_mv(v, dmv_x, dmv_y, direct, bmvtype);
- if (!s->mb_intra) {
- vc1_b_mc(v, dmv_x, dmv_y, direct, bmvtype);
- }
- if (s->mb_intra)
- s->ac_pred = get_bits1(gb);
- cbp = get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2);
- GET_MQUANT();
- s->current_picture.qscale_table[mb_pos] = mquant;
- if (!v->ttmbf && !s->mb_intra && mb_has_coeffs)
- ttmb = get_vlc2(gb, ff_vc1_ttmb_vlc[v->tt_index].table, VC1_TTMB_VLC_BITS, 2);
- }
- }
- dst_idx = 0;
- for (i = 0; i < 6; i++) {
- s->dc_val[0][s->block_index[i]] = 0;
- dst_idx += i >> 2;
- val = ((cbp >> (5 - i)) & 1);
- off = (i & 4) ? 0 : ((i & 1) * 8 + (i & 2) * 4 * s->linesize);
- v->mb_type[0][s->block_index[i]] = s->mb_intra;
- if (s->mb_intra) {
- /* check if prediction blocks A and C are available */
- v->a_avail = v->c_avail = 0;
- if (i == 2 || i == 3 || !s->first_slice_line)
- v->a_avail = v->mb_type[0][s->block_index[i] - s->block_wrap[i]];
- if (i == 1 || i == 3 || s->mb_x)
- v->c_avail = v->mb_type[0][s->block_index[i] - 1];
-
- vc1_decode_intra_block(v, s->block[i], i, val, mquant,
- (i & 4) ? v->codingset2 : v->codingset);
- if ((i>3) && (s->flags & CODEC_FLAG_GRAY))
- continue;
- v->vc1dsp.vc1_inv_trans_8x8(s->block[i]);
- if (v->rangeredfrm)
- for (j = 0; j < 64; j++)
- s->block[i][j] <<= 1;
- s->idsp.put_signed_pixels_clamped(s->block[i],
- s->dest[dst_idx] + off,
- i & 4 ? s->uvlinesize
- : s->linesize);
- } else if (val) {
- vc1_decode_p_block(v, s->block[i], i, mquant, ttmb,
- first_block, s->dest[dst_idx] + off,
- (i & 4) ? s->uvlinesize : s->linesize,
- (i & 4) && (s->flags & CODEC_FLAG_GRAY), NULL);
- if (!v->ttmbf && ttmb < 8)
- ttmb = -1;
- first_block = 0;
- }
- }
-}
-
-/** Decode one B-frame MB (in interlaced field B picture)
- */
-static void vc1_decode_b_mb_intfi(VC1Context *v)
-{
- MpegEncContext *s = &v->s;
- GetBitContext *gb = &s->gb;
- int i, j;
- int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
- int cbp = 0; /* cbp decoding stuff */
- int mqdiff, mquant; /* MB quantization */
- int ttmb = v->ttfrm; /* MB Transform type */
- int mb_has_coeffs = 0; /* last_flag */
- int val; /* temp value */
- int first_block = 1;
- int dst_idx, off;
- int fwd;
- int dmv_x[2], dmv_y[2], pred_flag[2];
- int bmvtype = BMV_TYPE_BACKWARD;
- int idx_mbmode;
-
- mquant = v->pq; /* Lossy initialization */
- s->mb_intra = 0;
-
- idx_mbmode = get_vlc2(gb, v->mbmode_vlc->table, VC1_IF_MBMODE_VLC_BITS, 2);
- if (idx_mbmode <= 1) { // intra MB
- s->mb_intra = v->is_intra[s->mb_x] = 1;
- s->current_picture.motion_val[1][s->block_index[0]][0] = 0;
- s->current_picture.motion_val[1][s->block_index[0]][1] = 0;
- s->current_picture.mb_type[mb_pos + v->mb_off] = MB_TYPE_INTRA;
- GET_MQUANT();
- s->current_picture.qscale_table[mb_pos] = mquant;
- /* Set DC scale - y and c use the same (not sure if necessary here) */
- s->y_dc_scale = s->y_dc_scale_table[mquant];
- s->c_dc_scale = s->c_dc_scale_table[mquant];
- v->s.ac_pred = v->acpred_plane[mb_pos] = get_bits1(gb);
- mb_has_coeffs = idx_mbmode & 1;
- if (mb_has_coeffs)
- cbp = 1 + get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_ICBPCY_VLC_BITS, 2);
- dst_idx = 0;
- for (i = 0; i < 6; i++) {
- s->dc_val[0][s->block_index[i]] = 0;
- dst_idx += i >> 2;
- val = ((cbp >> (5 - i)) & 1);
- v->mb_type[0][s->block_index[i]] = s->mb_intra;
- v->a_avail = v->c_avail = 0;
- if (i == 2 || i == 3 || !s->first_slice_line)
- v->a_avail = v->mb_type[0][s->block_index[i] - s->block_wrap[i]];
- if (i == 1 || i == 3 || s->mb_x)
- v->c_avail = v->mb_type[0][s->block_index[i] - 1];
-
- vc1_decode_intra_block(v, s->block[i], i, val, mquant,
- (i & 4) ? v->codingset2 : v->codingset);
- if ((i>3) && (s->flags & CODEC_FLAG_GRAY))
- continue;
- v->vc1dsp.vc1_inv_trans_8x8(s->block[i]);
- if (v->rangeredfrm)
- for (j = 0; j < 64; j++)
- s->block[i][j] <<= 1;
- off = (i & 4) ? 0 : ((i & 1) * 8 + (i & 2) * 4 * s->linesize);
- s->idsp.put_signed_pixels_clamped(s->block[i],
- s->dest[dst_idx] + off,
- (i & 4) ? s->uvlinesize
- : s->linesize);
- // TODO: yet to perform loop filter
- }
- } else {
- s->mb_intra = v->is_intra[s->mb_x] = 0;
- s->current_picture.mb_type[mb_pos + v->mb_off] = MB_TYPE_16x16;
- for (i = 0; i < 6; i++) v->mb_type[0][s->block_index[i]] = 0;
- if (v->fmb_is_raw)
- fwd = v->forward_mb_plane[mb_pos] = get_bits1(gb);
- else
- fwd = v->forward_mb_plane[mb_pos];
- if (idx_mbmode <= 5) { // 1-MV
- int interpmvp = 0;
- dmv_x[0] = dmv_x[1] = dmv_y[0] = dmv_y[1] = 0;
- pred_flag[0] = pred_flag[1] = 0;
- if (fwd)
- bmvtype = BMV_TYPE_FORWARD;
- else {
- bmvtype = decode012(gb);
- switch (bmvtype) {
- case 0:
- bmvtype = BMV_TYPE_BACKWARD;
- break;
- case 1:
- bmvtype = BMV_TYPE_DIRECT;
- break;
- case 2:
- bmvtype = BMV_TYPE_INTERPOLATED;
- interpmvp = get_bits1(gb);
- }
- }
- v->bmvtype = bmvtype;
- if (bmvtype != BMV_TYPE_DIRECT && idx_mbmode & 1) {
- get_mvdata_interlaced(v, &dmv_x[bmvtype == BMV_TYPE_BACKWARD], &dmv_y[bmvtype == BMV_TYPE_BACKWARD], &pred_flag[bmvtype == BMV_TYPE_BACKWARD]);
- }
- if (interpmvp) {
- get_mvdata_interlaced(v, &dmv_x[1], &dmv_y[1], &pred_flag[1]);
- }
- if (bmvtype == BMV_TYPE_DIRECT) {
- dmv_x[0] = dmv_y[0] = pred_flag[0] = 0;
- dmv_x[1] = dmv_y[1] = pred_flag[0] = 0;
- if (!s->next_picture_ptr->field_picture) {
- av_log(s->avctx, AV_LOG_ERROR, "Mixed field/frame direct mode not supported\n");
- return;
- }
- }
- vc1_pred_b_mv_intfi(v, 0, dmv_x, dmv_y, 1, pred_flag);
- vc1_b_mc(v, dmv_x, dmv_y, (bmvtype == BMV_TYPE_DIRECT), bmvtype);
- mb_has_coeffs = !(idx_mbmode & 2);
- } else { // 4-MV
- if (fwd)
- bmvtype = BMV_TYPE_FORWARD;
- v->bmvtype = bmvtype;
- v->fourmvbp = get_vlc2(gb, v->fourmvbp_vlc->table, VC1_4MV_BLOCK_PATTERN_VLC_BITS, 1);
- for (i = 0; i < 6; i++) {
- if (i < 4) {
- dmv_x[0] = dmv_y[0] = pred_flag[0] = 0;
- dmv_x[1] = dmv_y[1] = pred_flag[1] = 0;
- val = ((v->fourmvbp >> (3 - i)) & 1);
- if (val) {
- get_mvdata_interlaced(v, &dmv_x[bmvtype == BMV_TYPE_BACKWARD],
- &dmv_y[bmvtype == BMV_TYPE_BACKWARD],
- &pred_flag[bmvtype == BMV_TYPE_BACKWARD]);
- }
- vc1_pred_b_mv_intfi(v, i, dmv_x, dmv_y, 0, pred_flag);
- vc1_mc_4mv_luma(v, i, bmvtype == BMV_TYPE_BACKWARD, 0);
- } else if (i == 4)
- vc1_mc_4mv_chroma(v, bmvtype == BMV_TYPE_BACKWARD);
- }
- mb_has_coeffs = idx_mbmode & 1;
- }
- if (mb_has_coeffs)
- cbp = 1 + get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2);
- if (cbp) {
- GET_MQUANT();
- }
- s->current_picture.qscale_table[mb_pos] = mquant;
- if (!v->ttmbf && cbp) {
- ttmb = get_vlc2(gb, ff_vc1_ttmb_vlc[v->tt_index].table, VC1_TTMB_VLC_BITS, 2);
- }
- dst_idx = 0;
- for (i = 0; i < 6; i++) {
- s->dc_val[0][s->block_index[i]] = 0;
- dst_idx += i >> 2;
- val = ((cbp >> (5 - i)) & 1);
- off = (i & 4) ? 0 : (i & 1) * 8 + (i & 2) * 4 * s->linesize;
- if (val) {
- vc1_decode_p_block(v, s->block[i], i, mquant, ttmb,
- first_block, s->dest[dst_idx] + off,
- (i & 4) ? s->uvlinesize : s->linesize,
- (i & 4) && (s->flags & CODEC_FLAG_GRAY), NULL);
- if (!v->ttmbf && ttmb < 8)
- ttmb = -1;
- first_block = 0;
- }
- }
- }
-}
-
-/** Decode one B-frame MB (in interlaced frame B picture)
- */
-static int vc1_decode_b_mb_intfr(VC1Context *v)
-{
- MpegEncContext *s = &v->s;
- GetBitContext *gb = &s->gb;
- int i, j;
- int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
- int cbp = 0; /* cbp decoding stuff */
- int mqdiff, mquant; /* MB quantization */
- int ttmb = v->ttfrm; /* MB Transform type */
- int mvsw = 0; /* motion vector switch */
- int mb_has_coeffs = 1; /* last_flag */
- int dmv_x, dmv_y; /* Differential MV components */
- int val; /* temp value */
- int first_block = 1;
- int dst_idx, off;
- int skipped, direct, twomv = 0;
- int block_cbp = 0, pat, block_tt = 0;
- int idx_mbmode = 0, mvbp;
- int stride_y, fieldtx;
- int bmvtype = BMV_TYPE_BACKWARD;
- int dir, dir2;
-
- mquant = v->pq; /* Lossy initialization */
- s->mb_intra = 0;
- if (v->skip_is_raw)
- skipped = get_bits1(gb);
- else
- skipped = v->s.mbskip_table[mb_pos];
-
- if (!skipped) {
- idx_mbmode = get_vlc2(gb, v->mbmode_vlc->table, VC1_INTFR_NON4MV_MBMODE_VLC_BITS, 2);
- if (ff_vc1_mbmode_intfrp[0][idx_mbmode][0] == MV_PMODE_INTFR_2MV_FIELD) {
- twomv = 1;
- v->blk_mv_type[s->block_index[0]] = 1;
- v->blk_mv_type[s->block_index[1]] = 1;
- v->blk_mv_type[s->block_index[2]] = 1;
- v->blk_mv_type[s->block_index[3]] = 1;
- } else {
- v->blk_mv_type[s->block_index[0]] = 0;
- v->blk_mv_type[s->block_index[1]] = 0;
- v->blk_mv_type[s->block_index[2]] = 0;
- v->blk_mv_type[s->block_index[3]] = 0;
- }
- }
-
- if (v->dmb_is_raw)
- direct = get_bits1(gb);
- else
- direct = v->direct_mb_plane[mb_pos];
-
- if (direct) {
- if (s->next_picture_ptr->field_picture)
- av_log(s->avctx, AV_LOG_WARNING, "Mixed frame/field direct mode not supported\n");
- s->mv[0][0][0] = s->current_picture.motion_val[0][s->block_index[0]][0] = scale_mv(s->next_picture.motion_val[1][s->block_index[0]][0], v->bfraction, 0, s->quarter_sample);
- s->mv[0][0][1] = s->current_picture.motion_val[0][s->block_index[0]][1] = scale_mv(s->next_picture.motion_val[1][s->block_index[0]][1], v->bfraction, 0, s->quarter_sample);
- s->mv[1][0][0] = s->current_picture.motion_val[1][s->block_index[0]][0] = scale_mv(s->next_picture.motion_val[1][s->block_index[0]][0], v->bfraction, 1, s->quarter_sample);
- s->mv[1][0][1] = s->current_picture.motion_val[1][s->block_index[0]][1] = scale_mv(s->next_picture.motion_val[1][s->block_index[0]][1], v->bfraction, 1, s->quarter_sample);
-
- if (twomv) {
- s->mv[0][2][0] = s->current_picture.motion_val[0][s->block_index[2]][0] = scale_mv(s->next_picture.motion_val[1][s->block_index[2]][0], v->bfraction, 0, s->quarter_sample);
- s->mv[0][2][1] = s->current_picture.motion_val[0][s->block_index[2]][1] = scale_mv(s->next_picture.motion_val[1][s->block_index[2]][1], v->bfraction, 0, s->quarter_sample);
- s->mv[1][2][0] = s->current_picture.motion_val[1][s->block_index[2]][0] = scale_mv(s->next_picture.motion_val[1][s->block_index[2]][0], v->bfraction, 1, s->quarter_sample);
- s->mv[1][2][1] = s->current_picture.motion_val[1][s->block_index[2]][1] = scale_mv(s->next_picture.motion_val[1][s->block_index[2]][1], v->bfraction, 1, s->quarter_sample);
-
- for (i = 1; i < 4; i += 2) {
- s->mv[0][i][0] = s->current_picture.motion_val[0][s->block_index[i]][0] = s->mv[0][i-1][0];
- s->mv[0][i][1] = s->current_picture.motion_val[0][s->block_index[i]][1] = s->mv[0][i-1][1];
- s->mv[1][i][0] = s->current_picture.motion_val[1][s->block_index[i]][0] = s->mv[1][i-1][0];
- s->mv[1][i][1] = s->current_picture.motion_val[1][s->block_index[i]][1] = s->mv[1][i-1][1];
- }
- } else {
- for (i = 1; i < 4; i++) {
- s->mv[0][i][0] = s->current_picture.motion_val[0][s->block_index[i]][0] = s->mv[0][0][0];
- s->mv[0][i][1] = s->current_picture.motion_val[0][s->block_index[i]][1] = s->mv[0][0][1];
- s->mv[1][i][0] = s->current_picture.motion_val[1][s->block_index[i]][0] = s->mv[1][0][0];
- s->mv[1][i][1] = s->current_picture.motion_val[1][s->block_index[i]][1] = s->mv[1][0][1];
- }
- }
- }
-
- if (ff_vc1_mbmode_intfrp[0][idx_mbmode][0] == MV_PMODE_INTFR_INTRA) { // intra MB
- for (i = 0; i < 4; i++) {
- s->mv[0][i][0] = s->current_picture.motion_val[0][s->block_index[i]][0] = 0;
- s->mv[0][i][1] = s->current_picture.motion_val[0][s->block_index[i]][1] = 0;
- s->mv[1][i][0] = s->current_picture.motion_val[1][s->block_index[i]][0] = 0;
- s->mv[1][i][1] = s->current_picture.motion_val[1][s->block_index[i]][1] = 0;
- }
- s->current_picture.mb_type[mb_pos] = MB_TYPE_INTRA;
- s->mb_intra = v->is_intra[s->mb_x] = 1;
- for (i = 0; i < 6; i++)
- v->mb_type[0][s->block_index[i]] = 1;
- fieldtx = v->fieldtx_plane[mb_pos] = get_bits1(gb);
- mb_has_coeffs = get_bits1(gb);
- if (mb_has_coeffs)
- cbp = 1 + get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2);
- v->s.ac_pred = v->acpred_plane[mb_pos] = get_bits1(gb);
- GET_MQUANT();
- s->current_picture.qscale_table[mb_pos] = mquant;
- /* Set DC scale - y and c use the same (not sure if necessary here) */
- s->y_dc_scale = s->y_dc_scale_table[mquant];
- s->c_dc_scale = s->c_dc_scale_table[mquant];
- dst_idx = 0;
- for (i = 0; i < 6; i++) {
- s->dc_val[0][s->block_index[i]] = 0;
- dst_idx += i >> 2;
- val = ((cbp >> (5 - i)) & 1);
- v->mb_type[0][s->block_index[i]] = s->mb_intra;
- v->a_avail = v->c_avail = 0;
- if (i == 2 || i == 3 || !s->first_slice_line)
- v->a_avail = v->mb_type[0][s->block_index[i] - s->block_wrap[i]];
- if (i == 1 || i == 3 || s->mb_x)
- v->c_avail = v->mb_type[0][s->block_index[i] - 1];
-
- vc1_decode_intra_block(v, s->block[i], i, val, mquant,
- (i & 4) ? v->codingset2 : v->codingset);
- if (i > 3 && (s->flags & CODEC_FLAG_GRAY))
- continue;
- v->vc1dsp.vc1_inv_trans_8x8(s->block[i]);
- if (i < 4) {
- stride_y = s->linesize << fieldtx;
- off = (fieldtx) ? ((i & 1) * 8) + ((i & 2) >> 1) * s->linesize : (i & 1) * 8 + 4 * (i & 2) * s->linesize;
- } else {
- stride_y = s->uvlinesize;
- off = 0;
- }
- s->idsp.put_signed_pixels_clamped(s->block[i],
- s->dest[dst_idx] + off,
- stride_y);
- }
- } else {
- s->mb_intra = v->is_intra[s->mb_x] = 0;
- if (!direct) {
- if (skipped || !s->mb_intra) {
- bmvtype = decode012(gb);
- switch (bmvtype) {
- case 0:
- bmvtype = (v->bfraction >= (B_FRACTION_DEN/2)) ? BMV_TYPE_BACKWARD : BMV_TYPE_FORWARD;
- break;
- case 1:
- bmvtype = (v->bfraction >= (B_FRACTION_DEN/2)) ? BMV_TYPE_FORWARD : BMV_TYPE_BACKWARD;
- break;
- case 2:
- bmvtype = BMV_TYPE_INTERPOLATED;
- }
- }
-
- if (twomv && bmvtype != BMV_TYPE_INTERPOLATED)
- mvsw = get_bits1(gb);
- }
-
- if (!skipped) { // inter MB
- mb_has_coeffs = ff_vc1_mbmode_intfrp[0][idx_mbmode][3];
- if (mb_has_coeffs)
- cbp = 1 + get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2);
- if (!direct) {
- 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) {
- v->twomvbp = get_vlc2(gb, v->twomvbp_vlc->table, VC1_2MV_BLOCK_PATTERN_VLC_BITS, 1);
- }
- }
-
- for (i = 0; i < 6; i++)
- v->mb_type[0][s->block_index[i]] = 0;
- fieldtx = v->fieldtx_plane[mb_pos] = ff_vc1_mbmode_intfrp[0][idx_mbmode][1];
- /* for all motion vector read MVDATA and motion compensate each block */
- dst_idx = 0;
- if (direct) {
- if (twomv) {
- for (i = 0; i < 4; i++) {
- vc1_mc_4mv_luma(v, i, 0, 0);
- vc1_mc_4mv_luma(v, i, 1, 1);
- }
- vc1_mc_4mv_chroma4(v, 0, 0, 0);
- vc1_mc_4mv_chroma4(v, 1, 1, 1);
- } else {
- vc1_mc_1mv(v, 0);
- vc1_interp_mc(v);
- }
- } else if (twomv && bmvtype == BMV_TYPE_INTERPOLATED) {
- mvbp = v->fourmvbp;
- for (i = 0; i < 4; i++) {
- dir = i==1 || i==3;
- dmv_x = dmv_y = 0;
- val = ((mvbp >> (3 - i)) & 1);
- if (val)
- get_mvdata_interlaced(v, &dmv_x, &dmv_y, 0);
- j = i > 1 ? 2 : 0;
- vc1_pred_mv_intfr(v, j, dmv_x, dmv_y, 2, v->range_x, v->range_y, v->mb_type[0], dir);
- vc1_mc_4mv_luma(v, j, dir, dir);
- vc1_mc_4mv_luma(v, j+1, dir, dir);
- }
-
- vc1_mc_4mv_chroma4(v, 0, 0, 0);
- vc1_mc_4mv_chroma4(v, 1, 1, 1);
- } else if (bmvtype == BMV_TYPE_INTERPOLATED) {
- mvbp = v->twomvbp;
- dmv_x = dmv_y = 0;
- if (mvbp & 2)
- get_mvdata_interlaced(v, &dmv_x, &dmv_y, 0);
-
- vc1_pred_mv_intfr(v, 0, dmv_x, dmv_y, 1, v->range_x, v->range_y, v->mb_type[0], 0);
- vc1_mc_1mv(v, 0);
-
- dmv_x = dmv_y = 0;
- if (mvbp & 1)
- get_mvdata_interlaced(v, &dmv_x, &dmv_y, 0);
-
- vc1_pred_mv_intfr(v, 0, dmv_x, dmv_y, 1, v->range_x, v->range_y, v->mb_type[0], 1);
- vc1_interp_mc(v);
- } else if (twomv) {
- dir = bmvtype == BMV_TYPE_BACKWARD;
- dir2 = dir;
- if (mvsw)
- dir2 = !dir;
- mvbp = v->twomvbp;
- dmv_x = dmv_y = 0;
- if (mvbp & 2)
- get_mvdata_interlaced(v, &dmv_x, &dmv_y, 0);
- vc1_pred_mv_intfr(v, 0, dmv_x, dmv_y, 2, v->range_x, v->range_y, v->mb_type[0], dir);
-
- dmv_x = dmv_y = 0;
- if (mvbp & 1)
- get_mvdata_interlaced(v, &dmv_x, &dmv_y, 0);
- vc1_pred_mv_intfr(v, 2, dmv_x, dmv_y, 2, v->range_x, v->range_y, v->mb_type[0], dir2);
-
- if (mvsw) {
- for (i = 0; i < 2; i++) {
- s->mv[dir][i+2][0] = s->mv[dir][i][0] = s->current_picture.motion_val[dir][s->block_index[i+2]][0] = s->current_picture.motion_val[dir][s->block_index[i]][0];
- s->mv[dir][i+2][1] = s->mv[dir][i][1] = s->current_picture.motion_val[dir][s->block_index[i+2]][1] = s->current_picture.motion_val[dir][s->block_index[i]][1];
- s->mv[dir2][i+2][0] = s->mv[dir2][i][0] = s->current_picture.motion_val[dir2][s->block_index[i]][0] = s->current_picture.motion_val[dir2][s->block_index[i+2]][0];
- s->mv[dir2][i+2][1] = s->mv[dir2][i][1] = s->current_picture.motion_val[dir2][s->block_index[i]][1] = s->current_picture.motion_val[dir2][s->block_index[i+2]][1];
- }
- } else {
- vc1_pred_mv_intfr(v, 0, 0, 0, 2, v->range_x, v->range_y, v->mb_type[0], !dir);
- vc1_pred_mv_intfr(v, 2, 0, 0, 2, v->range_x, v->range_y, v->mb_type[0], !dir);
- }
-
- vc1_mc_4mv_luma(v, 0, dir, 0);
- vc1_mc_4mv_luma(v, 1, dir, 0);
- vc1_mc_4mv_luma(v, 2, dir2, 0);
- vc1_mc_4mv_luma(v, 3, dir2, 0);
- vc1_mc_4mv_chroma4(v, dir, dir2, 0);
- } else {
- dir = bmvtype == BMV_TYPE_BACKWARD;
-
- mvbp = ff_vc1_mbmode_intfrp[0][idx_mbmode][2];
- dmv_x = dmv_y = 0;
- if (mvbp)
- get_mvdata_interlaced(v, &dmv_x, &dmv_y, 0);
-
- vc1_pred_mv_intfr(v, 0, dmv_x, dmv_y, 1, v->range_x, v->range_y, v->mb_type[0], dir);
- v->blk_mv_type[s->block_index[0]] = 1;
- v->blk_mv_type[s->block_index[1]] = 1;
- v->blk_mv_type[s->block_index[2]] = 1;
- v->blk_mv_type[s->block_index[3]] = 1;
- vc1_pred_mv_intfr(v, 0, 0, 0, 2, v->range_x, v->range_y, 0, !dir);
- for (i = 0; i < 2; i++) {
- s->mv[!dir][i+2][0] = s->mv[!dir][i][0] = s->current_picture.motion_val[!dir][s->block_index[i+2]][0] = s->current_picture.motion_val[!dir][s->block_index[i]][0];
- s->mv[!dir][i+2][1] = s->mv[!dir][i][1] = s->current_picture.motion_val[!dir][s->block_index[i+2]][1] = s->current_picture.motion_val[!dir][s->block_index[i]][1];
- }
- vc1_mc_1mv(v, dir);
- }
-
- if (cbp)
- GET_MQUANT(); // p. 227
- s->current_picture.qscale_table[mb_pos] = mquant;
- if (!v->ttmbf && cbp)
- ttmb = get_vlc2(gb, ff_vc1_ttmb_vlc[v->tt_index].table, VC1_TTMB_VLC_BITS, 2);
- for (i = 0; i < 6; i++) {
- s->dc_val[0][s->block_index[i]] = 0;
- dst_idx += i >> 2;
- val = ((cbp >> (5 - i)) & 1);
- if (!fieldtx)
- off = (i & 4) ? 0 : ((i & 1) * 8 + (i & 2) * 4 * s->linesize);
- else
- off = (i & 4) ? 0 : ((i & 1) * 8 + ((i > 1) * s->linesize));
- if (val) {
- pat = vc1_decode_p_block(v, s->block[i], i, mquant, ttmb,
- first_block, s->dest[dst_idx] + off,
- (i & 4) ? s->uvlinesize : (s->linesize << fieldtx),
- (i & 4) && (s->flags & CODEC_FLAG_GRAY), &block_tt);
- block_cbp |= pat << (i << 2);
- if (!v->ttmbf && ttmb < 8)
- ttmb = -1;
- first_block = 0;
- }
- }
-
- } else { // skipped
- dir = 0;
- for (i = 0; i < 6; i++) {
- v->mb_type[0][s->block_index[i]] = 0;
- s->dc_val[0][s->block_index[i]] = 0;
- }
- s->current_picture.mb_type[mb_pos] = MB_TYPE_SKIP;
- s->current_picture.qscale_table[mb_pos] = 0;
- v->blk_mv_type[s->block_index[0]] = 0;
- v->blk_mv_type[s->block_index[1]] = 0;
- v->blk_mv_type[s->block_index[2]] = 0;
- v->blk_mv_type[s->block_index[3]] = 0;
-
- if (!direct) {
- if (bmvtype == BMV_TYPE_INTERPOLATED) {
- vc1_pred_mv_intfr(v, 0, 0, 0, 1, v->range_x, v->range_y, v->mb_type[0], 0);
- vc1_pred_mv_intfr(v, 0, 0, 0, 1, v->range_x, v->range_y, v->mb_type[0], 1);
- } else {
- dir = bmvtype == BMV_TYPE_BACKWARD;
- vc1_pred_mv_intfr(v, 0, 0, 0, 1, v->range_x, v->range_y, v->mb_type[0], dir);
- if (mvsw) {
- int dir2 = dir;
- if (mvsw)
- dir2 = !dir;
- for (i = 0; i < 2; i++) {
- s->mv[dir][i+2][0] = s->mv[dir][i][0] = s->current_picture.motion_val[dir][s->block_index[i+2]][0] = s->current_picture.motion_val[dir][s->block_index[i]][0];
- s->mv[dir][i+2][1] = s->mv[dir][i][1] = s->current_picture.motion_val[dir][s->block_index[i+2]][1] = s->current_picture.motion_val[dir][s->block_index[i]][1];
- s->mv[dir2][i+2][0] = s->mv[dir2][i][0] = s->current_picture.motion_val[dir2][s->block_index[i]][0] = s->current_picture.motion_val[dir2][s->block_index[i+2]][0];
- s->mv[dir2][i+2][1] = s->mv[dir2][i][1] = s->current_picture.motion_val[dir2][s->block_index[i]][1] = s->current_picture.motion_val[dir2][s->block_index[i+2]][1];
- }
- } else {
- v->blk_mv_type[s->block_index[0]] = 1;
- v->blk_mv_type[s->block_index[1]] = 1;
- v->blk_mv_type[s->block_index[2]] = 1;
- v->blk_mv_type[s->block_index[3]] = 1;
- vc1_pred_mv_intfr(v, 0, 0, 0, 2, v->range_x, v->range_y, 0, !dir);
- for (i = 0; i < 2; i++) {
- s->mv[!dir][i+2][0] = s->mv[!dir][i][0] = s->current_picture.motion_val[!dir][s->block_index[i+2]][0] = s->current_picture.motion_val[!dir][s->block_index[i]][0];
- s->mv[!dir][i+2][1] = s->mv[!dir][i][1] = s->current_picture.motion_val[!dir][s->block_index[i+2]][1] = s->current_picture.motion_val[!dir][s->block_index[i]][1];
- }
- }
- }
- }
-
- vc1_mc_1mv(v, dir);
- if (direct || bmvtype == BMV_TYPE_INTERPOLATED) {
- vc1_interp_mc(v);
- }
- }
- }
- if (s->mb_x == s->mb_width - 1)
- memmove(v->is_intra_base, v->is_intra, sizeof(v->is_intra_base[0]) * s->mb_stride);
- v->cbp[s->mb_x] = block_cbp;
- v->ttblk[s->mb_x] = block_tt;
- return 0;
-}
-
-/** Decode blocks of I-frame
- */
-static void vc1_decode_i_blocks(VC1Context *v)
-{
- int k, j;
- MpegEncContext *s = &v->s;
- int cbp, val;
- uint8_t *coded_val;
- int mb_pos;
-
- /* select codingmode used for VLC tables selection */
- switch (v->y_ac_table_index) {
- case 0:
- v->codingset = (v->pqindex <= 8) ? CS_HIGH_RATE_INTRA : CS_LOW_MOT_INTRA;
- break;
- case 1:
- v->codingset = CS_HIGH_MOT_INTRA;
- break;
- case 2:
- v->codingset = CS_MID_RATE_INTRA;
- break;
- }
-
- switch (v->c_ac_table_index) {
- case 0:
- v->codingset2 = (v->pqindex <= 8) ? CS_HIGH_RATE_INTER : CS_LOW_MOT_INTER;
- break;
- case 1:
- v->codingset2 = CS_HIGH_MOT_INTER;
- break;
- case 2:
- v->codingset2 = CS_MID_RATE_INTER;
- break;
- }
-
- /* Set DC scale - y and c use the same */
- s->y_dc_scale = s->y_dc_scale_table[v->pq];
- s->c_dc_scale = s->c_dc_scale_table[v->pq];
-
- //do frame decode
- s->mb_x = s->mb_y = 0;
- s->mb_intra = 1;
- s->first_slice_line = 1;
- for (s->mb_y = 0; s->mb_y < s->end_mb_y; s->mb_y++) {
- s->mb_x = 0;
- init_block_index(v);
- for (; s->mb_x < v->end_mb_x; s->mb_x++) {
- uint8_t *dst[6];
- ff_update_block_index(s);
- dst[0] = s->dest[0];
- dst[1] = dst[0] + 8;
- dst[2] = s->dest[0] + s->linesize * 8;
- dst[3] = dst[2] + 8;
- dst[4] = s->dest[1];
- dst[5] = s->dest[2];
- s->bdsp.clear_blocks(s->block[0]);
- mb_pos = s->mb_x + s->mb_y * s->mb_width;
- s->current_picture.mb_type[mb_pos] = MB_TYPE_INTRA;
- s->current_picture.qscale_table[mb_pos] = v->pq;
- s->current_picture.motion_val[1][s->block_index[0]][0] = 0;
- s->current_picture.motion_val[1][s->block_index[0]][1] = 0;
-
- // do actual MB decoding and displaying
- cbp = get_vlc2(&v->s.gb, ff_msmp4_mb_i_vlc.table, MB_INTRA_VLC_BITS, 2);
- v->s.ac_pred = get_bits1(&v->s.gb);
-
- for (k = 0; k < 6; k++) {
- val = ((cbp >> (5 - k)) & 1);
-
- if (k < 4) {
- int pred = vc1_coded_block_pred(&v->s, k, &coded_val);
- val = val ^ pred;
- *coded_val = val;
- }
- cbp |= val << (5 - k);
-
- vc1_decode_i_block(v, s->block[k], k, val, (k < 4) ? v->codingset : v->codingset2);
-
- if (k > 3 && (s->flags & CODEC_FLAG_GRAY))
- continue;
- v->vc1dsp.vc1_inv_trans_8x8(s->block[k]);
- if (v->pq >= 9 && v->overlap) {
- if (v->rangeredfrm)
- for (j = 0; j < 64; j++)
- s->block[k][j] <<= 1;
- s->idsp.put_signed_pixels_clamped(s->block[k], dst[k],
- k & 4 ? s->uvlinesize
- : s->linesize);
- } else {
- if (v->rangeredfrm)
- for (j = 0; j < 64; j++)
- s->block[k][j] = (s->block[k][j] - 64) << 1;
- s->idsp.put_pixels_clamped(s->block[k], dst[k],
- k & 4 ? s->uvlinesize
- : s->linesize);
- }
- }
-
- if (v->pq >= 9 && v->overlap) {
- if (s->mb_x) {
- v->vc1dsp.vc1_h_overlap(s->dest[0], s->linesize);
- v->vc1dsp.vc1_h_overlap(s->dest[0] + 8 * s->linesize, s->linesize);
- if (!(s->flags & CODEC_FLAG_GRAY)) {
- v->vc1dsp.vc1_h_overlap(s->dest[1], s->uvlinesize);
- v->vc1dsp.vc1_h_overlap(s->dest[2], s->uvlinesize);
- }
- }
- v->vc1dsp.vc1_h_overlap(s->dest[0] + 8, s->linesize);
- v->vc1dsp.vc1_h_overlap(s->dest[0] + 8 * s->linesize + 8, s->linesize);
- if (!s->first_slice_line) {
- v->vc1dsp.vc1_v_overlap(s->dest[0], s->linesize);
- v->vc1dsp.vc1_v_overlap(s->dest[0] + 8, s->linesize);
- if (!(s->flags & CODEC_FLAG_GRAY)) {
- v->vc1dsp.vc1_v_overlap(s->dest[1], s->uvlinesize);
- v->vc1dsp.vc1_v_overlap(s->dest[2], s->uvlinesize);
- }
- }
- v->vc1dsp.vc1_v_overlap(s->dest[0] + 8 * s->linesize, s->linesize);
- v->vc1dsp.vc1_v_overlap(s->dest[0] + 8 * s->linesize + 8, s->linesize);
- }
- if (v->s.loop_filter) vc1_loop_filter_iblk(v, v->pq);
-
- if (get_bits_count(&s->gb) > v->bits) {
- ff_er_add_slice(&s->er, 0, 0, s->mb_x, s->mb_y, ER_MB_ERROR);
- av_log(s->avctx, AV_LOG_ERROR, "Bits overconsumption: %i > %i\n",
- get_bits_count(&s->gb), v->bits);
- return;
- }
- }
- if (!v->s.loop_filter)
- ff_mpeg_draw_horiz_band(s, s->mb_y * 16, 16);
- else if (s->mb_y)
- ff_mpeg_draw_horiz_band(s, (s->mb_y - 1) * 16, 16);
-
- s->first_slice_line = 0;
- }
- if (v->s.loop_filter)
- ff_mpeg_draw_horiz_band(s, (s->end_mb_y - 1) * 16, 16);
-
- /* This is intentionally mb_height and not end_mb_y - unlike in advanced
- * profile, these only differ are when decoding MSS2 rectangles. */
- ff_er_add_slice(&s->er, 0, 0, s->mb_width - 1, s->mb_height - 1, ER_MB_END);
-}
-
-/** Decode blocks of I-frame for advanced profile
- */
-static void vc1_decode_i_blocks_adv(VC1Context *v)
-{
- int k;
- MpegEncContext *s = &v->s;
- int cbp, val;
- uint8_t *coded_val;
- int mb_pos;
- int mquant = v->pq;
- int mqdiff;
- GetBitContext *gb = &s->gb;
-
- /* select codingmode used for VLC tables selection */
- switch (v->y_ac_table_index) {
- case 0:
- v->codingset = (v->pqindex <= 8) ? CS_HIGH_RATE_INTRA : CS_LOW_MOT_INTRA;
- break;
- case 1:
- v->codingset = CS_HIGH_MOT_INTRA;
- break;
- case 2:
- v->codingset = CS_MID_RATE_INTRA;
- break;
- }
-
- switch (v->c_ac_table_index) {
- case 0:
- v->codingset2 = (v->pqindex <= 8) ? CS_HIGH_RATE_INTER : CS_LOW_MOT_INTER;
- break;
- case 1:
- v->codingset2 = CS_HIGH_MOT_INTER;
- break;
- case 2:
- v->codingset2 = CS_MID_RATE_INTER;
- break;
- }
-
- // do frame decode
- s->mb_x = s->mb_y = 0;
- s->mb_intra = 1;
- s->first_slice_line = 1;
- s->mb_y = s->start_mb_y;
- if (s->start_mb_y) {
- s->mb_x = 0;
- init_block_index(v);
- memset(&s->coded_block[s->block_index[0] - s->b8_stride], 0,
- (1 + s->b8_stride) * sizeof(*s->coded_block));
- }
- for (; s->mb_y < s->end_mb_y; s->mb_y++) {
- s->mb_x = 0;
- init_block_index(v);
- for (;s->mb_x < s->mb_width; s->mb_x++) {
- int16_t (*block)[64] = v->block[v->cur_blk_idx];
- ff_update_block_index(s);
- s->bdsp.clear_blocks(block[0]);
- mb_pos = s->mb_x + s->mb_y * s->mb_stride;
- s->current_picture.mb_type[mb_pos + v->mb_off] = MB_TYPE_INTRA;
- s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][0] = 0;
- s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][1] = 0;
-
- // do actual MB decoding and displaying
- if (v->fieldtx_is_raw)
- v->fieldtx_plane[mb_pos] = get_bits1(&v->s.gb);
- cbp = get_vlc2(&v->s.gb, ff_msmp4_mb_i_vlc.table, MB_INTRA_VLC_BITS, 2);
- if ( v->acpred_is_raw)
- v->s.ac_pred = get_bits1(&v->s.gb);
- else
- v->s.ac_pred = v->acpred_plane[mb_pos];
-
- if (v->condover == CONDOVER_SELECT && v->overflg_is_raw)
- v->over_flags_plane[mb_pos] = get_bits1(&v->s.gb);
-
- GET_MQUANT();
-
- s->current_picture.qscale_table[mb_pos] = mquant;
- /* Set DC scale - y and c use the same */
- s->y_dc_scale = s->y_dc_scale_table[mquant];
- s->c_dc_scale = s->c_dc_scale_table[mquant];
-
- for (k = 0; k < 6; k++) {
- val = ((cbp >> (5 - k)) & 1);
-
- if (k < 4) {
- int pred = vc1_coded_block_pred(&v->s, k, &coded_val);
- val = val ^ pred;
- *coded_val = val;
- }
- cbp |= val << (5 - k);
-
- v->a_avail = !s->first_slice_line || (k == 2 || k == 3);
- v->c_avail = !!s->mb_x || (k == 1 || k == 3);
-
- vc1_decode_i_block_adv(v, block[k], k, val,
- (k < 4) ? v->codingset : v->codingset2, mquant);
-
- if (k > 3 && (s->flags & CODEC_FLAG_GRAY))
- continue;
- v->vc1dsp.vc1_inv_trans_8x8(block[k]);
- }
-
- vc1_smooth_overlap_filter_iblk(v);
- vc1_put_signed_blocks_clamped(v);
- if (v->s.loop_filter) vc1_loop_filter_iblk_delayed(v, v->pq);
-
- if (get_bits_count(&s->gb) > v->bits) {
- // TODO: may need modification to handle slice coding
- ff_er_add_slice(&s->er, 0, s->start_mb_y, s->mb_x, s->mb_y, ER_MB_ERROR);
- av_log(s->avctx, AV_LOG_ERROR, "Bits overconsumption: %i > %i\n",
- get_bits_count(&s->gb), v->bits);
- return;
- }
- }
- if (!v->s.loop_filter)
- ff_mpeg_draw_horiz_band(s, s->mb_y * 16, 16);
- else if (s->mb_y)
- ff_mpeg_draw_horiz_band(s, (s->mb_y-1) * 16, 16);
- s->first_slice_line = 0;
- }
-
- /* raw bottom MB row */
- s->mb_x = 0;
- init_block_index(v);
-
- for (;s->mb_x < s->mb_width; s->mb_x++) {
- ff_update_block_index(s);
- vc1_put_signed_blocks_clamped(v);
- if (v->s.loop_filter)
- vc1_loop_filter_iblk_delayed(v, v->pq);
- }
- if (v->s.loop_filter)
- ff_mpeg_draw_horiz_band(s, (s->end_mb_y-1)*16, 16);
- ff_er_add_slice(&s->er, 0, s->start_mb_y << v->field_mode, s->mb_width - 1,
- (s->end_mb_y << v->field_mode) - 1, ER_MB_END);
-}
-
-static void vc1_decode_p_blocks(VC1Context *v)
-{
- MpegEncContext *s = &v->s;
- int apply_loop_filter;
-
- /* select codingmode used for VLC tables selection */
- switch (v->c_ac_table_index) {
- case 0:
- v->codingset = (v->pqindex <= 8) ? CS_HIGH_RATE_INTRA : CS_LOW_MOT_INTRA;
- break;
- case 1:
- v->codingset = CS_HIGH_MOT_INTRA;
- break;
- case 2:
- v->codingset = CS_MID_RATE_INTRA;
- break;
- }
-
- switch (v->c_ac_table_index) {
- case 0:
- v->codingset2 = (v->pqindex <= 8) ? CS_HIGH_RATE_INTER : CS_LOW_MOT_INTER;
- break;
- case 1:
- v->codingset2 = CS_HIGH_MOT_INTER;
- break;
- case 2:
- v->codingset2 = CS_MID_RATE_INTER;
- break;
- }
-
- apply_loop_filter = s->loop_filter && !(s->avctx->skip_loop_filter >= AVDISCARD_NONKEY) &&
- v->fcm == PROGRESSIVE;
- s->first_slice_line = 1;
- memset(v->cbp_base, 0, sizeof(v->cbp_base[0])*2*s->mb_stride);
- for (s->mb_y = s->start_mb_y; s->mb_y < s->end_mb_y; s->mb_y++) {
- s->mb_x = 0;
- init_block_index(v);
- for (; s->mb_x < s->mb_width; s->mb_x++) {
- ff_update_block_index(s);
-
- if (v->fcm == ILACE_FIELD)
- vc1_decode_p_mb_intfi(v);
- else if (v->fcm == ILACE_FRAME)
- vc1_decode_p_mb_intfr(v);
- else vc1_decode_p_mb(v);
- if (s->mb_y != s->start_mb_y && apply_loop_filter)
- vc1_apply_p_loop_filter(v);
- if (get_bits_count(&s->gb) > v->bits || get_bits_count(&s->gb) < 0) {
- // TODO: may need modification to handle slice coding
- ff_er_add_slice(&s->er, 0, s->start_mb_y, s->mb_x, s->mb_y, ER_MB_ERROR);
- av_log(s->avctx, AV_LOG_ERROR, "Bits overconsumption: %i > %i at %ix%i\n",
- get_bits_count(&s->gb), v->bits, s->mb_x, s->mb_y);
- return;
- }
- }
- memmove(v->cbp_base, v->cbp, sizeof(v->cbp_base[0]) * s->mb_stride);
- memmove(v->ttblk_base, v->ttblk, sizeof(v->ttblk_base[0]) * s->mb_stride);
- memmove(v->is_intra_base, v->is_intra, sizeof(v->is_intra_base[0]) * s->mb_stride);
- memmove(v->luma_mv_base, v->luma_mv, sizeof(v->luma_mv_base[0]) * s->mb_stride);
- if (s->mb_y != s->start_mb_y) ff_mpeg_draw_horiz_band(s, (s->mb_y - 1) * 16, 16);
- s->first_slice_line = 0;
- }
- if (apply_loop_filter) {
- s->mb_x = 0;
- init_block_index(v);
- for (; s->mb_x < s->mb_width; s->mb_x++) {
- ff_update_block_index(s);
- vc1_apply_p_loop_filter(v);
- }
- }
- if (s->end_mb_y >= s->start_mb_y)
- ff_mpeg_draw_horiz_band(s, (s->end_mb_y - 1) * 16, 16);
- ff_er_add_slice(&s->er, 0, s->start_mb_y << v->field_mode, s->mb_width - 1,
- (s->end_mb_y << v->field_mode) - 1, ER_MB_END);
-}
-
-static void vc1_decode_b_blocks(VC1Context *v)
-{
- MpegEncContext *s = &v->s;
-
- /* select codingmode used for VLC tables selection */
- switch (v->c_ac_table_index) {
- case 0:
- v->codingset = (v->pqindex <= 8) ? CS_HIGH_RATE_INTRA : CS_LOW_MOT_INTRA;
- break;
- case 1:
- v->codingset = CS_HIGH_MOT_INTRA;
- break;
- case 2:
- v->codingset = CS_MID_RATE_INTRA;
- break;
- }
-
- switch (v->c_ac_table_index) {
- case 0:
- v->codingset2 = (v->pqindex <= 8) ? CS_HIGH_RATE_INTER : CS_LOW_MOT_INTER;
- break;
- case 1:
- v->codingset2 = CS_HIGH_MOT_INTER;
- break;
- case 2:
- v->codingset2 = CS_MID_RATE_INTER;
- break;
- }
-
- s->first_slice_line = 1;
- for (s->mb_y = s->start_mb_y; s->mb_y < s->end_mb_y; s->mb_y++) {
- s->mb_x = 0;
- init_block_index(v);
- for (; s->mb_x < s->mb_width; s->mb_x++) {
- ff_update_block_index(s);
-
- if (v->fcm == ILACE_FIELD)
- vc1_decode_b_mb_intfi(v);
- else if (v->fcm == ILACE_FRAME)
- vc1_decode_b_mb_intfr(v);
- else
- vc1_decode_b_mb(v);
- if (get_bits_count(&s->gb) > v->bits || get_bits_count(&s->gb) < 0) {
- // TODO: may need modification to handle slice coding
- ff_er_add_slice(&s->er, 0, s->start_mb_y, s->mb_x, s->mb_y, ER_MB_ERROR);
- av_log(s->avctx, AV_LOG_ERROR, "Bits overconsumption: %i > %i at %ix%i\n",
- get_bits_count(&s->gb), v->bits, s->mb_x, s->mb_y);
- return;
- }
- if (v->s.loop_filter) vc1_loop_filter_iblk(v, v->pq);
- }
- if (!v->s.loop_filter)
- ff_mpeg_draw_horiz_band(s, s->mb_y * 16, 16);
- else if (s->mb_y)
- ff_mpeg_draw_horiz_band(s, (s->mb_y - 1) * 16, 16);
- s->first_slice_line = 0;
- }
- if (v->s.loop_filter)
- ff_mpeg_draw_horiz_band(s, (s->end_mb_y - 1) * 16, 16);
- ff_er_add_slice(&s->er, 0, s->start_mb_y << v->field_mode, s->mb_width - 1,
- (s->end_mb_y << v->field_mode) - 1, ER_MB_END);
-}
-
-static void vc1_decode_skip_blocks(VC1Context *v)
-{
- MpegEncContext *s = &v->s;
-
- if (!v->s.last_picture.f->data[0])
- return;
-
- ff_er_add_slice(&s->er, 0, s->start_mb_y, s->mb_width - 1, s->end_mb_y - 1, ER_MB_END);
- s->first_slice_line = 1;
- for (s->mb_y = s->start_mb_y; s->mb_y < s->end_mb_y; s->mb_y++) {
- s->mb_x = 0;
- init_block_index(v);
- ff_update_block_index(s);
- memcpy(s->dest[0], s->last_picture.f->data[0] + s->mb_y * 16 * s->linesize, s->linesize * 16);
- memcpy(s->dest[1], s->last_picture.f->data[1] + s->mb_y * 8 * s->uvlinesize, s->uvlinesize * 8);
- memcpy(s->dest[2], s->last_picture.f->data[2] + s->mb_y * 8 * s->uvlinesize, s->uvlinesize * 8);
- ff_mpeg_draw_horiz_band(s, s->mb_y * 16, 16);
- s->first_slice_line = 0;
- }
- s->pict_type = AV_PICTURE_TYPE_P;
-}
-
-void ff_vc1_decode_blocks(VC1Context *v)
-{
+#include "avcodec.h"
+#include "blockdsp.h"
+#include "get_bits.h"
+#include "internal.h"
+#include "mpeg_er.h"
+#include "mpegvideo.h"
+#include "msmpeg4data.h"
+#include "vc1.h"
+#include "vc1data.h"
+#include "vdpau_internal.h"
+#include "libavutil/avassert.h"
- v->s.esc3_level_length = 0;
- if (v->x8_type) {
- ff_intrax8_decode_picture(&v->x8, 2*v->pq + v->halfpq, v->pq * !v->pquantizer);
- } else {
- v->cur_blk_idx = 0;
- v->left_blk_idx = -1;
- v->topleft_blk_idx = 1;
- v->top_blk_idx = 2;
- switch (v->s.pict_type) {
- case AV_PICTURE_TYPE_I:
- if (v->profile == PROFILE_ADVANCED)
- vc1_decode_i_blocks_adv(v);
- else
- vc1_decode_i_blocks(v);
- break;
- case AV_PICTURE_TYPE_P:
- if (v->p_frame_skipped)
- vc1_decode_skip_blocks(v);
- else
- vc1_decode_p_blocks(v);
- break;
- case AV_PICTURE_TYPE_B:
- if (v->bi_type) {
- if (v->profile == PROFILE_ADVANCED)
- vc1_decode_i_blocks_adv(v);
- else
- vc1_decode_i_blocks(v);
- } else
- vc1_decode_b_blocks(v);
- break;
- }
- }
-}
#if CONFIG_WMV3IMAGE_DECODER || CONFIG_VC1IMAGE_DECODER
avctx->has_b_frames = !!avctx->max_b_frames;
+ if (v->color_prim == 1 || v->color_prim == 5 || v->color_prim == 6)
+ avctx->color_primaries = v->color_prim;
+ if (v->transfer_char == 1 || v->transfer_char == 7)
+ avctx->color_trc = v->transfer_char;
+ if (v->matrix_coef == 1 || v->matrix_coef == 6 || v->matrix_coef == 7)
+ avctx->colorspace = v->matrix_coef;
+
s->mb_width = (avctx->coded_width + 15) >> 4;
s->mb_height = (avctx->coded_height + 15) >> 4;
*/
#include <limits.h>
+#include "libavutil/avassert.h"
#include "avcodec.h"
+#include "internal.h"
#include "h264.h"
#include "vc1.h"
* @{
*/
+static int vdpau_error(VdpStatus status)
+{
+ switch (status) {
+ case VDP_STATUS_OK:
+ return 0;
+ case VDP_STATUS_NO_IMPLEMENTATION:
+ return AVERROR(ENOSYS);
+ case VDP_STATUS_DISPLAY_PREEMPTED:
+ return AVERROR(EIO);
+ case VDP_STATUS_INVALID_HANDLE:
+ return AVERROR(EBADF);
+ case VDP_STATUS_INVALID_POINTER:
+ return AVERROR(EFAULT);
+ case VDP_STATUS_RESOURCES:
+ return AVERROR(ENOBUFS);
+ case VDP_STATUS_HANDLE_DEVICE_MISMATCH:
+ return AVERROR(EXDEV);
+ case VDP_STATUS_ERROR:
+ return AVERROR(EIO);
+ default:
+ return AVERROR(EINVAL);
+ }
+}
+
AVVDPAUContext *av_alloc_vdpaucontext(void)
{
return av_vdpau_alloc_context();
MAKE_ACCESSORS(AVVDPAUContext, vdpau_hwaccel, AVVDPAU_Render2, render2)
+int ff_vdpau_common_init(AVCodecContext *avctx, VdpDecoderProfile profile,
+ int level)
+{
+ VDPAUHWContext *hwctx = avctx->hwaccel_context;
+ VDPAUContext *vdctx = avctx->internal->hwaccel_priv_data;
+ VdpVideoSurfaceQueryCapabilities *surface_query_caps;
+ VdpDecoderQueryCapabilities *decoder_query_caps;
+ VdpDecoderCreate *create;
+ void *func;
+ VdpStatus status;
+ VdpBool supported;
+ uint32_t max_level, max_mb, max_width, max_height;
+ /* See vdpau/vdpau.h for alignment constraints. */
+ uint32_t width = (avctx->coded_width + 1) & ~1;
+ uint32_t height = (avctx->coded_height + 3) & ~3;
+
+ vdctx->width = UINT32_MAX;
+ vdctx->height = UINT32_MAX;
+
+ if (!hwctx) {
+ vdctx->device = VDP_INVALID_HANDLE;
+ av_log(avctx, AV_LOG_WARNING, "hwaccel_context has not been setup by the user application, cannot initialize\n");
+ return 0;
+ }
+
+ if (hwctx->context.decoder != VDP_INVALID_HANDLE) {
+ vdctx->decoder = hwctx->context.decoder;
+ vdctx->render = hwctx->context.render;
+ vdctx->device = VDP_INVALID_HANDLE;
+ return 0; /* Decoder created by user */
+ }
+ hwctx->reset = 0;
+
+ vdctx->device = hwctx->device;
+ vdctx->get_proc_address = hwctx->get_proc_address;
+
+ if (hwctx->flags & AV_HWACCEL_FLAG_IGNORE_LEVEL)
+ level = 0;
+ else if (level < 0)
+ return AVERROR(ENOTSUP);
+
+ status = vdctx->get_proc_address(vdctx->device,
+ VDP_FUNC_ID_VIDEO_SURFACE_QUERY_CAPABILITIES,
+ &func);
+ if (status != VDP_STATUS_OK)
+ return vdpau_error(status);
+ else
+ surface_query_caps = func;
+
+ status = surface_query_caps(vdctx->device, VDP_CHROMA_TYPE_420, &supported,
+ &max_width, &max_height);
+ if (status != VDP_STATUS_OK)
+ return vdpau_error(status);
+ if (supported != VDP_TRUE ||
+ max_width < width || max_height < height)
+ return AVERROR(ENOTSUP);
+
+ status = vdctx->get_proc_address(vdctx->device,
+ VDP_FUNC_ID_DECODER_QUERY_CAPABILITIES,
+ &func);
+ if (status != VDP_STATUS_OK)
+ return vdpau_error(status);
+ else
+ decoder_query_caps = func;
+
+ status = decoder_query_caps(vdctx->device, profile, &supported, &max_level,
+ &max_mb, &max_width, &max_height);
+ if (status != VDP_STATUS_OK)
+ return vdpau_error(status);
+
+ if (supported != VDP_TRUE || max_level < level ||
+ max_width < width || max_height < height)
+ return AVERROR(ENOTSUP);
+
+ status = vdctx->get_proc_address(vdctx->device, VDP_FUNC_ID_DECODER_CREATE,
+ &func);
+ if (status != VDP_STATUS_OK)
+ return vdpau_error(status);
+ else
+ create = func;
+
+ status = vdctx->get_proc_address(vdctx->device, VDP_FUNC_ID_DECODER_RENDER,
+ &func);
+ if (status != VDP_STATUS_OK)
+ return vdpau_error(status);
+ else
+ vdctx->render = func;
+
+ status = create(vdctx->device, profile, width, height, avctx->refs,
+ &vdctx->decoder);
+ if (status == VDP_STATUS_OK) {
+ vdctx->width = avctx->coded_width;
+ vdctx->height = avctx->coded_height;
+ }
+
+ return vdpau_error(status);
+}
+
+int ff_vdpau_common_uninit(AVCodecContext *avctx)
+{
+ VDPAUContext *vdctx = avctx->internal->hwaccel_priv_data;
+ VdpDecoderDestroy *destroy;
+ void *func;
+ VdpStatus status;
+
+ if (vdctx->device == VDP_INVALID_HANDLE)
+ return 0; /* Decoder created and destroyed by user */
+ if (vdctx->width == UINT32_MAX && vdctx->height == UINT32_MAX)
+ return 0;
+
+ status = vdctx->get_proc_address(vdctx->device,
+ VDP_FUNC_ID_DECODER_DESTROY, &func);
+ if (status != VDP_STATUS_OK)
+ return vdpau_error(status);
+ else
+ destroy = func;
+
+ status = destroy(vdctx->decoder);
+ return vdpau_error(status);
+}
+
+static int ff_vdpau_common_reinit(AVCodecContext *avctx)
+{
+ VDPAUHWContext *hwctx = avctx->hwaccel_context;
+ VDPAUContext *vdctx = avctx->internal->hwaccel_priv_data;
+
+ if (vdctx->device == VDP_INVALID_HANDLE)
+ return 0; /* Decoder created by user */
+ if (avctx->coded_width == vdctx->width &&
+ avctx->coded_height == vdctx->height && !hwctx->reset)
+ return 0;
+
+ avctx->hwaccel->uninit(avctx);
+ return avctx->hwaccel->init(avctx);
+}
+
int ff_vdpau_common_start_frame(struct vdpau_picture_context *pic_ctx,
av_unused const uint8_t *buffer,
av_unused uint32_t size)
return 0;
}
-#if CONFIG_H263_VDPAU_HWACCEL || CONFIG_MPEG1_VDPAU_HWACCEL || \
- CONFIG_MPEG2_VDPAU_HWACCEL || CONFIG_MPEG4_VDPAU_HWACCEL || \
- CONFIG_VC1_VDPAU_HWACCEL || CONFIG_WMV3_VDPAU_HWACCEL
-int ff_vdpau_mpeg_end_frame(AVCodecContext *avctx)
+int ff_vdpau_common_end_frame(AVCodecContext *avctx, AVFrame *frame,
+ struct vdpau_picture_context *pic_ctx)
{
- int res = 0;
+ VDPAUContext *vdctx = avctx->internal->hwaccel_priv_data;
AVVDPAUContext *hwctx = avctx->hwaccel_context;
- MpegEncContext *s = avctx->priv_data;
- Picture *pic = s->current_picture_ptr;
- struct vdpau_picture_context *pic_ctx = pic->hwaccel_picture_private;
- VdpVideoSurface surf = ff_vdpau_get_surface_id(pic->f);
+ VdpVideoSurface surf = ff_vdpau_get_surface_id(frame);
+ VdpStatus status;
+ int val;
+
+ val = ff_vdpau_common_reinit(avctx);
+ if (val < 0)
+ return val;
#if FF_API_BUFS_VDPAU
FF_DISABLE_DEPRECATION_WARNINGS
FF_ENABLE_DEPRECATION_WARNINGS
#endif
- if (!hwctx->render) {
- res = hwctx->render2(avctx, pic->f, (void *)&pic_ctx->info,
- pic_ctx->bitstream_buffers_used, pic_ctx->bitstream_buffers);
+ if (!hwctx->render && hwctx->render2) {
+ status = hwctx->render2(avctx, frame, (void *)&pic_ctx->info,
+ pic_ctx->bitstream_buffers_used, pic_ctx->bitstream_buffers);
} else
- hwctx->render(hwctx->decoder, surf, (void *)&pic_ctx->info,
- pic_ctx->bitstream_buffers_used, pic_ctx->bitstream_buffers);
+ status = vdctx->render(vdctx->decoder, surf, (void *)&pic_ctx->info,
+ pic_ctx->bitstream_buffers_used,
+ pic_ctx->bitstream_buffers);
- ff_mpeg_draw_horiz_band(s, 0, s->avctx->height);
av_freep(&pic_ctx->bitstream_buffers);
#if FF_API_BUFS_VDPAU
FF_ENABLE_DEPRECATION_WARNINGS
#endif
- return res;
+ return vdpau_error(status);
+}
+
+#if CONFIG_H263_VDPAU_HWACCEL || CONFIG_MPEG1_VDPAU_HWACCEL || \
+ CONFIG_MPEG2_VDPAU_HWACCEL || CONFIG_MPEG4_VDPAU_HWACCEL || \
+ CONFIG_VC1_VDPAU_HWACCEL || CONFIG_WMV3_VDPAU_HWACCEL
+int ff_vdpau_mpeg_end_frame(AVCodecContext *avctx)
+{
+ MpegEncContext *s = avctx->priv_data;
+ Picture *pic = s->current_picture_ptr;
+ struct vdpau_picture_context *pic_ctx = pic->hwaccel_picture_private;
+ int val;
+
+ val = ff_vdpau_common_end_frame(avctx, pic->f, pic_ctx);
+ if (val < 0)
+ return val;
+
+ ff_mpeg_draw_horiz_band(s, 0, s->avctx->height);
+ return 0;
}
#endif
}
case AV_CODEC_ID_H264:
switch (avctx->profile & ~FF_PROFILE_H264_INTRA) {
- case FF_PROFILE_H264_CONSTRAINED_BASELINE:
case FF_PROFILE_H264_BASELINE: PROFILE(VDP_DECODER_PROFILE_H264_BASELINE);
+ case FF_PROFILE_H264_CONSTRAINED_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);
return av_mallocz(sizeof(AVVDPAUContext));
}
+int av_vdpau_bind_context(AVCodecContext *avctx, VdpDevice device,
+ VdpGetProcAddress *get_proc, unsigned flags)
+{
+ VDPAUHWContext *hwctx;
+
+ if (flags & ~AV_HWACCEL_FLAG_IGNORE_LEVEL)
+ return AVERROR(EINVAL);
+
+ if (av_reallocp(&avctx->hwaccel_context, sizeof(*hwctx)))
+ return AVERROR(ENOMEM);
+
+ hwctx = avctx->hwaccel_context;
+
+ memset(hwctx, 0, sizeof(*hwctx));
+ hwctx->context.decoder = VDP_INVALID_HANDLE;
+ hwctx->device = device;
+ hwctx->get_proc_address = get_proc;
+ hwctx->flags = flags;
+ hwctx->reset = 1;
+ return 0;
+}
+
/* @}*/
AVVDPAU_Render2 av_vdpau_hwaccel_get_render2(const AVVDPAUContext *);
void av_vdpau_hwaccel_set_render2(AVVDPAUContext *, AVVDPAU_Render2);
+/**
+ * Associate a VDPAU device with a codec context for hardware acceleration.
+ * This function is meant to be called from the get_format() codec callback,
+ * or earlier. It can also be called after avcodec_flush_buffers() to change
+ * the underlying VDPAU device mid-stream (e.g. to recover from non-transparent
+ * display preemption).
+ *
+ * @note get_format() must return AV_PIX_FMT_VDPAU if this function completes
+ * successfully.
+ *
+ * @param avctx decoding context whose get_format() callback is invoked
+ * @param device VDPAU device handle to use for hardware acceleration
+ * @param get_proc_address VDPAU device driver
+ * @param flags zero of more OR'd AV_HWACCEL_FLAG_* flags
+ *
+ * @return 0 on success, an AVERROR code on failure.
+ */
+int av_vdpau_bind_context(AVCodecContext *avctx, VdpDevice device,
+ VdpGetProcAddress *get_proc_address, unsigned flags);
+
/**
* Allocate an AVVDPAUContext.
*
#include <vdpau/vdpau.h>
#include "avcodec.h"
+#include "internal.h"
#include "h264.h"
#include "mpegutils.h"
#include "vdpau.h"
static int vdpau_h264_end_frame(AVCodecContext *avctx)
{
- int res = 0;
- AVVDPAUContext *hwctx = avctx->hwaccel_context;
H264Context *h = avctx->priv_data;
H264Picture *pic = h->cur_pic_ptr;
struct vdpau_picture_context *pic_ctx = pic->hwaccel_picture_private;
- VdpVideoSurface surf = ff_vdpau_get_surface_id(&pic->f);
-
-#if FF_API_BUFS_VDPAU
-FF_DISABLE_DEPRECATION_WARNINGS
- hwctx->info = pic_ctx->info;
- hwctx->bitstream_buffers = pic_ctx->bitstream_buffers;
- hwctx->bitstream_buffers_used = pic_ctx->bitstream_buffers_used;
- hwctx->bitstream_buffers_allocated = pic_ctx->bitstream_buffers_allocated;
-FF_ENABLE_DEPRECATION_WARNINGS
-#endif
-
- if (!hwctx->render) {
- res = hwctx->render2(avctx, &pic->f, (void *)&pic_ctx->info,
- pic_ctx->bitstream_buffers_used, pic_ctx->bitstream_buffers);
- } else
- hwctx->render(hwctx->decoder, surf, (void *)&pic_ctx->info,
- pic_ctx->bitstream_buffers_used, pic_ctx->bitstream_buffers);
+ int val;
+
+ val = ff_vdpau_common_end_frame(avctx, &pic->f, pic_ctx);
+ if (val < 0)
+ return val;
ff_h264_draw_horiz_band(h, 0, h->avctx->height);
- av_freep(&pic_ctx->bitstream_buffers);
+ return 0;
+}
+
+static int vdpau_h264_init(AVCodecContext *avctx)
+{
+ VdpDecoderProfile profile;
+ uint32_t level = avctx->level;
+
+ switch (avctx->profile & ~FF_PROFILE_H264_INTRA) {
+ case FF_PROFILE_H264_BASELINE:
+ profile = VDP_DECODER_PROFILE_H264_BASELINE;
+ break;
+ case FF_PROFILE_H264_CONSTRAINED_BASELINE:
+ case FF_PROFILE_H264_MAIN:
+ profile = VDP_DECODER_PROFILE_H264_MAIN;
+ break;
+ case FF_PROFILE_H264_HIGH:
+ profile = VDP_DECODER_PROFILE_H264_HIGH;
+ break;
+ default:
+ return AVERROR(ENOTSUP);
+ }
-#if FF_API_BUFS_VDPAU
-FF_DISABLE_DEPRECATION_WARNINGS
- hwctx->bitstream_buffers = NULL;
- hwctx->bitstream_buffers_used = 0;
- hwctx->bitstream_buffers_allocated = 0;
-FF_ENABLE_DEPRECATION_WARNINGS
-#endif
+ if ((avctx->profile & FF_PROFILE_H264_INTRA) && avctx->level == 11)
+ level = VDP_DECODER_LEVEL_H264_1b;
- return res;
+ return ff_vdpau_common_init(avctx, profile, level);
}
AVHWAccel ff_h264_vdpau_hwaccel = {
.end_frame = vdpau_h264_end_frame,
.decode_slice = vdpau_h264_decode_slice,
.frame_priv_data_size = sizeof(struct vdpau_picture_context),
+ .init = vdpau_h264_init,
+ .uninit = ff_vdpau_common_uninit,
+ .priv_data_size = sizeof(VDPAUContext),
};
#include "vdpau.h"
#endif
+typedef struct VDPAUHWContext {
+ AVVDPAUContext context;
+ VdpDevice device;
+ VdpGetProcAddress *get_proc_address;
+ char reset;
+ unsigned char flags;
+} VDPAUHWContext;
+
+typedef struct VDPAUContext {
+ /**
+ * VDPAU device handle
+ */
+ VdpDevice device;
+
+ /**
+ * VDPAU decoder handle
+ */
+ VdpDecoder decoder;
+
+ /**
+ * VDPAU device driver
+ */
+ VdpGetProcAddress *get_proc_address;
+
+ /**
+ * VDPAU decoder render callback
+ */
+ VdpDecoderRender *render;
+
+ uint32_t width;
+ uint32_t height;
+} VDPAUContext;
+
struct vdpau_picture_context {
/**
* VDPAU picture information.
*/
VdpBitstreamBuffer *bitstream_buffers;
};
-#endif
+
+int ff_vdpau_common_init(AVCodecContext *avctx, VdpDecoderProfile profile,
+ int level);
+#endif //CONFIG_VDPAU
+
+int ff_vdpau_common_uninit(AVCodecContext *avctx);
int ff_vdpau_common_start_frame(struct vdpau_picture_context *pic,
const uint8_t *buffer, uint32_t size);
+int ff_vdpau_common_end_frame(AVCodecContext *avctx, AVFrame *frame,
+ struct vdpau_picture_context *pic);
int ff_vdpau_mpeg_end_frame(AVCodecContext *avctx);
int ff_vdpau_add_buffer(struct vdpau_picture_context *pic, const uint8_t *buf,
uint32_t buf_size);
}
#if CONFIG_MPEG1_VDPAU_HWACCEL
+static int vdpau_mpeg1_init(AVCodecContext *avctx)
+{
+ return ff_vdpau_common_init(avctx, VDP_DECODER_PROFILE_MPEG1,
+ VDP_DECODER_LEVEL_MPEG1_NA);
+}
+
AVHWAccel ff_mpeg1_vdpau_hwaccel = {
.name = "mpeg1_vdpau",
.type = AVMEDIA_TYPE_VIDEO,
.end_frame = ff_vdpau_mpeg_end_frame,
.decode_slice = vdpau_mpeg_decode_slice,
.frame_priv_data_size = sizeof(struct vdpau_picture_context),
+ .init = vdpau_mpeg1_init,
+ .uninit = ff_vdpau_common_uninit,
+ .priv_data_size = sizeof(VDPAUContext),
};
#endif
#if CONFIG_MPEG2_VDPAU_HWACCEL
+static int vdpau_mpeg2_init(AVCodecContext *avctx)
+{
+ VdpDecoderProfile profile;
+
+ switch (avctx->profile) {
+ case FF_PROFILE_MPEG2_MAIN:
+ profile = VDP_DECODER_PROFILE_MPEG2_MAIN;
+ break;
+ case FF_PROFILE_MPEG2_SIMPLE:
+ profile = VDP_DECODER_PROFILE_MPEG2_SIMPLE;
+ break;
+ default:
+ return AVERROR(EINVAL);
+ }
+
+ return ff_vdpau_common_init(avctx, profile, VDP_DECODER_LEVEL_MPEG2_HL);
+}
+
AVHWAccel ff_mpeg2_vdpau_hwaccel = {
.name = "mpeg2_vdpau",
.type = AVMEDIA_TYPE_VIDEO,
.end_frame = ff_vdpau_mpeg_end_frame,
.decode_slice = vdpau_mpeg_decode_slice,
.frame_priv_data_size = sizeof(struct vdpau_picture_context),
+ .init = vdpau_mpeg2_init,
+ .uninit = ff_vdpau_common_uninit,
+ .priv_data_size = sizeof(VDPAUContext),
};
#endif
info->trb[0] = s->pb_time;
info->trd[1] = s->pp_field_time >> 1;
info->trb[1] = s->pb_field_time >> 1;
- info->vop_time_increment_resolution = s->avctx->time_base.den;
+ info->vop_time_increment_resolution = s->avctx->framerate.num;
info->vop_fcode_forward = s->f_code;
info->vop_fcode_backward = s->b_code;
info->resync_marker_disable = !ctx->resync_marker;
}
#if CONFIG_H263_VDPAU_HWACCEL
+static int vdpau_h263_init(AVCodecContext *avctx)
+{
+ return ff_vdpau_common_init(avctx, VDP_DECODER_PROFILE_MPEG4_PART2_ASP,
+ VDP_DECODER_LEVEL_MPEG4_PART2_ASP_L5);
+}
+
AVHWAccel ff_h263_vdpau_hwaccel = {
.name = "h263_vdpau",
.type = AVMEDIA_TYPE_VIDEO,
.end_frame = ff_vdpau_mpeg_end_frame,
.decode_slice = vdpau_mpeg4_decode_slice,
.frame_priv_data_size = sizeof(struct vdpau_picture_context),
+ .init = vdpau_h263_init,
+ .uninit = ff_vdpau_common_uninit,
+ .priv_data_size = sizeof(VDPAUContext),
};
#endif
#if CONFIG_MPEG4_VDPAU_HWACCEL
+static int vdpau_mpeg4_init(AVCodecContext *avctx)
+{
+ VdpDecoderProfile profile;
+
+ switch (avctx->profile) {
+ case FF_PROFILE_MPEG4_SIMPLE:
+ profile = VDP_DECODER_PROFILE_MPEG4_PART2_SP;
+ break;
+ // As any ASP decoder must be able to decode SP, this
+ // should be a safe fallback if profile is unknown/unspecified.
+ case FF_PROFILE_UNKNOWN:
+ case FF_PROFILE_MPEG4_ADVANCED_SIMPLE:
+ profile = VDP_DECODER_PROFILE_MPEG4_PART2_ASP;
+ break;
+ default:
+ return AVERROR(ENOTSUP);
+ }
+
+ return ff_vdpau_common_init(avctx, profile, avctx->level);
+}
+
AVHWAccel ff_mpeg4_vdpau_hwaccel = {
.name = "mpeg4_vdpau",
.type = AVMEDIA_TYPE_VIDEO,
.end_frame = ff_vdpau_mpeg_end_frame,
.decode_slice = vdpau_mpeg4_decode_slice,
.frame_priv_data_size = sizeof(struct vdpau_picture_context),
+ .init = vdpau_mpeg4_init,
+ .uninit = ff_vdpau_common_uninit,
+ .priv_data_size = sizeof(VDPAUContext),
};
#endif
return 0;
}
+static int vdpau_vc1_init(AVCodecContext *avctx)
+{
+ VdpDecoderProfile profile;
+
+ switch (avctx->profile) {
+ case FF_PROFILE_VC1_SIMPLE:
+ profile = VDP_DECODER_PROFILE_VC1_SIMPLE;
+ break;
+ case FF_PROFILE_VC1_MAIN:
+ profile = VDP_DECODER_PROFILE_VC1_MAIN;
+ break;
+ case FF_PROFILE_VC1_ADVANCED:
+ profile = VDP_DECODER_PROFILE_VC1_ADVANCED;
+ break;
+ default:
+ return AVERROR(ENOTSUP);
+ }
+
+ return ff_vdpau_common_init(avctx, profile, avctx->level);
+}
+
#if CONFIG_WMV3_VDPAU_HWACCEL
AVHWAccel ff_wmv3_vdpau_hwaccel = {
.name = "wm3_vdpau",
.end_frame = ff_vdpau_mpeg_end_frame,
.decode_slice = vdpau_vc1_decode_slice,
.frame_priv_data_size = sizeof(struct vdpau_picture_context),
+ .init = vdpau_vc1_init,
+ .uninit = ff_vdpau_common_uninit,
+ .priv_data_size = sizeof(VDPAUContext),
};
#endif
.end_frame = ff_vdpau_mpeg_end_frame,
.decode_slice = vdpau_vc1_decode_slice,
.frame_priv_data_size = sizeof(struct vdpau_picture_context),
+ .init = vdpau_vc1_init,
+ .uninit = ff_vdpau_common_uninit,
+ .priv_data_size = sizeof(VDPAUContext),
};
#include "libavutil/version.h"
#define LIBAVCODEC_VERSION_MAJOR 56
-#define LIBAVCODEC_VERSION_MINOR 1
+#define LIBAVCODEC_VERSION_MINOR 13
#define LIBAVCODEC_VERSION_MICRO 100
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
#ifndef FF_API_MAX_BFRAMES
#define FF_API_MAX_BFRAMES (LIBAVCODEC_VERSION_MAJOR < 57)
#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 < 57)
#endif
#ifndef FF_API_EMU_EDGE
#define FF_API_EMU_EDGE (LIBAVCODEC_VERSION_MAJOR < 57)
#endif
-#ifndef FF_API_DSPUTIL
-#define FF_API_DSPUTIL (LIBAVCODEC_VERSION_MAJOR < 56)
-#endif
#ifndef FF_API_ARCH_SH4
#define FF_API_ARCH_SH4 (LIBAVCODEC_VERSION_MAJOR < 57)
#endif
/* XXX: don't forget to drop the -vismv documentation */
#define FF_API_VISMV (LIBAVCODEC_VERSION_MAJOR < 57)
#endif
+#ifndef FF_API_DV_FRAME_PROFILE
+#define FF_API_DV_FRAME_PROFILE (LIBAVCODEC_VERSION_MAJOR < 57)
+#endif
+#ifndef FF_API_AUDIOENC_DELAY
+#define FF_API_AUDIOENC_DELAY (LIBAVCODEC_VERSION_MAJOR < 58)
+#endif
+#ifndef FF_API_AVCTX_TIMEBASE
+#define FF_API_AVCTX_TIMEBASE (LIBAVCODEC_VERSION_MAJOR < 59)
+#endif
+#ifndef FF_API_MPV_OPT
+#define FF_API_MPV_OPT (LIBAVCODEC_VERSION_MAJOR < 59)
+#endif
#endif /* AVCODEC_VERSION_H */
* Determines the duration for each packet.
*/
+#include "libavutil/log.h"
+
#include "get_bits.h"
#include "parser.h"
#include "xiph.h"
-#include "vorbis_parser.h"
+#include "vorbis_parser_internal.h"
+
+static const AVClass vorbis_parser_class = {
+ .class_name = "Vorbis parser",
+ .item_name = av_default_item_name,
+ .version = LIBAVUTIL_VERSION_INT,
+};
-static int parse_id_header(AVCodecContext *avctx, VorbisParseContext *s,
+static int parse_id_header(AVVorbisParseContext *s,
const uint8_t *buf, int buf_size)
{
/* Id header should be 30 bytes */
if (buf_size < 30) {
- av_log(avctx, AV_LOG_ERROR, "Id header is too short\n");
+ av_log(s, AV_LOG_ERROR, "Id header is too short\n");
return AVERROR_INVALIDDATA;
}
/* make sure this is the Id header */
if (buf[0] != 1) {
- av_log(avctx, AV_LOG_ERROR, "Wrong packet type in Id header\n");
+ av_log(s, AV_LOG_ERROR, "Wrong packet type in Id header\n");
return AVERROR_INVALIDDATA;
}
/* check for header signature */
if (memcmp(&buf[1], "vorbis", 6)) {
- av_log(avctx, AV_LOG_ERROR, "Invalid packet signature in Id header\n");
+ av_log(s, AV_LOG_ERROR, "Invalid packet signature in Id header\n");
return AVERROR_INVALIDDATA;
}
if (!(buf[29] & 0x1)) {
- av_log(avctx, AV_LOG_ERROR, "Invalid framing bit in Id header\n");
+ av_log(s, AV_LOG_ERROR, "Invalid framing bit in Id header\n");
return AVERROR_INVALIDDATA;
}
return 0;
}
-static int parse_setup_header(AVCodecContext *avctx, VorbisParseContext *s,
+static int parse_setup_header(AVVorbisParseContext *s,
const uint8_t *buf, int buf_size)
{
GetBitContext gb, gb0;
/* avoid overread */
if (buf_size < 7) {
- av_log(avctx, AV_LOG_ERROR, "Setup header is too short\n");
+ av_log(s, AV_LOG_ERROR, "Setup header is too short\n");
return AVERROR_INVALIDDATA;
}
/* make sure this is the Setup header */
if (buf[0] != 5) {
- av_log(avctx, AV_LOG_ERROR, "Wrong packet type in Setup header\n");
+ av_log(s, AV_LOG_ERROR, "Wrong packet type in Setup header\n");
return AVERROR_INVALIDDATA;
}
/* check for header signature */
if (memcmp(&buf[1], "vorbis", 6)) {
- av_log(avctx, AV_LOG_ERROR, "Invalid packet signature in Setup header\n");
+ av_log(s, AV_LOG_ERROR, "Invalid packet signature in Setup header\n");
return AVERROR_INVALIDDATA;
}
/* reverse bytes so we can easily read backwards with get_bits() */
if (!(rev_buf = av_malloc(buf_size))) {
- av_log(avctx, AV_LOG_ERROR, "Out of memory\n");
+ av_log(s, AV_LOG_ERROR, "Out of memory\n");
return AVERROR(ENOMEM);
}
for (i = 0; i < buf_size; i++)
}
}
if (!got_framing_bit) {
- av_log(avctx, AV_LOG_ERROR, "Invalid Setup header\n");
+ av_log(s, AV_LOG_ERROR, "Invalid Setup header\n");
ret = AVERROR_INVALIDDATA;
goto bad_header;
}
}
}
if (!got_mode_header) {
- av_log(avctx, AV_LOG_ERROR, "Invalid Setup header\n");
+ av_log(s, AV_LOG_ERROR, "Invalid Setup header\n");
ret = AVERROR_INVALIDDATA;
goto bad_header;
}
* we may need to approach this the long way and parse the whole Setup
* header, but I hope very much that it never comes to that. */
if (last_mode_count > 2) {
- avpriv_request_sample(avctx,
+ avpriv_request_sample(s,
"%d modes (either a false positive or a "
"sample from an unknown encoder)",
last_mode_count);
/* We're limiting the mode count to 63 so that we know that the previous
* block flag will be in the first packet byte. */
if (last_mode_count > 63) {
- av_log(avctx, AV_LOG_ERROR, "Unsupported mode count: %d\n",
+ av_log(s, AV_LOG_ERROR, "Unsupported mode count: %d\n",
last_mode_count);
ret = AVERROR_INVALIDDATA;
goto bad_header;
return ret;
}
-int avpriv_vorbis_parse_extradata(AVCodecContext *avctx, VorbisParseContext *s)
+static int vorbis_parse_init(AVVorbisParseContext *s,
+ const uint8_t *extradata, int extradata_size)
{
uint8_t *header_start[3];
int header_len[3];
int ret;
- s->avctx = avctx;
+ s->class = &vorbis_parser_class;
s->extradata_parsed = 1;
- if ((ret = avpriv_split_xiph_headers(avctx->extradata,
- avctx->extradata_size, 30,
+ if ((ret = avpriv_split_xiph_headers(extradata,
+ extradata_size, 30,
header_start, header_len)) < 0) {
- av_log(avctx, AV_LOG_ERROR, "Extradata corrupt.\n");
+ av_log(s, AV_LOG_ERROR, "Extradata corrupt.\n");
return ret;
}
- if ((ret = parse_id_header(avctx, s, header_start[0], header_len[0])) < 0)
+ if ((ret = parse_id_header(s, header_start[0], header_len[0])) < 0)
return ret;
- if ((ret = parse_setup_header(avctx, s, header_start[2], header_len[2])) < 0)
+ if ((ret = parse_setup_header(s, header_start[2], header_len[2])) < 0)
return ret;
s->valid_extradata = 1;
return 0;
}
-int avpriv_vorbis_parse_frame_flags(VorbisParseContext *s, const uint8_t *buf,
- int buf_size, int *flags)
+int av_vorbis_parse_frame_flags(AVVorbisParseContext *s, const uint8_t *buf,
+ int buf_size, int *flags)
{
int duration = 0;
return 0;
bad_packet:
- av_log(s->avctx, AV_LOG_ERROR, "Invalid packet\n");
+ av_log(s, AV_LOG_ERROR, "Invalid packet\n");
return AVERROR_INVALIDDATA;
}
if (s->mode_count == 1)
else
mode = (buf[0] & s->mode_mask) >> 1;
if (mode >= s->mode_count) {
- av_log(s->avctx, AV_LOG_ERROR, "Invalid mode in packet\n");
+ av_log(s, AV_LOG_ERROR, "Invalid mode in packet\n");
return AVERROR_INVALIDDATA;
}
if(s->mode_blocksize[mode]){
return duration;
}
-int avpriv_vorbis_parse_frame(VorbisParseContext *s, const uint8_t *buf,
- int buf_size)
+int av_vorbis_parse_frame(AVVorbisParseContext *s, const uint8_t *buf,
+ int buf_size)
{
- return avpriv_vorbis_parse_frame_flags(s, buf, buf_size, NULL);
+ return av_vorbis_parse_frame_flags(s, buf, buf_size, NULL);
}
-void avpriv_vorbis_parse_reset(VorbisParseContext *s)
+void av_vorbis_parse_reset(AVVorbisParseContext *s)
{
if (s->valid_extradata)
s->previous_blocksize = s->blocksize[0];
}
+void av_vorbis_parse_free(AVVorbisParseContext **s)
+{
+ av_freep(s);
+}
+
+AVVorbisParseContext *av_vorbis_parse_init(const uint8_t *extradata,
+ int extradata_size)
+{
+ AVVorbisParseContext *s = av_mallocz(sizeof(*s));
+ int ret;
+
+ if (!s)
+ return NULL;
+
+ ret = vorbis_parse_init(s, extradata, extradata_size);
+ if (ret < 0) {
+ av_vorbis_parse_free(&s);
+ return NULL;
+ }
+
+ return s;
+}
+
+#if LIBAVCODEC_VERSION_MAJOR < 57
+int avpriv_vorbis_parse_extradata(AVCodecContext *avctx, AVVorbisParseContext *s)
+{
+ return vorbis_parse_init(s, avctx->extradata, avctx->extradata_size);
+}
+void avpriv_vorbis_parse_reset(AVVorbisParseContext *s)
+{
+ av_vorbis_parse_reset(s);
+}
+int avpriv_vorbis_parse_frame(AVVorbisParseContext *s, const uint8_t *buf,
+ int buf_size)
+{
+ return av_vorbis_parse_frame(s, buf, buf_size);
+}
+int avpriv_vorbis_parse_frame_flags(AVVorbisParseContext *s, const uint8_t *buf,
+ int buf_size, int *flags)
+{
+ return av_vorbis_parse_frame_flags(s, buf, buf_size, flags);
+}
+#endif
+
#if CONFIG_VORBIS_PARSER
+
+typedef struct VorbisParseContext {
+ AVVorbisParseContext *vp;
+} VorbisParseContext;
+
static int vorbis_parse(AVCodecParserContext *s1, AVCodecContext *avctx,
const uint8_t **poutbuf, int *poutbuf_size,
const uint8_t *buf, int buf_size)
VorbisParseContext *s = s1->priv_data;
int duration;
- if (!s->extradata_parsed && avctx->extradata && avctx->extradata_size)
- if (avpriv_vorbis_parse_extradata(avctx, s))
- goto end;
+ if (!s->vp && avctx->extradata && avctx->extradata_size) {
+ s->vp = av_vorbis_parse_init(avctx->extradata, avctx->extradata_size);
+ }
+ if (!s->vp)
+ goto end;
- if ((duration = avpriv_vorbis_parse_frame(s, buf, buf_size)) >= 0)
+ if ((duration = av_vorbis_parse_frame(s->vp, buf, buf_size)) >= 0)
s1->duration = duration;
end:
return buf_size;
}
+static void vorbis_parser_close(AVCodecParserContext *ctx)
+{
+ VorbisParseContext *s = ctx->priv_data;
+ av_vorbis_parse_free(&s->vp);
+}
+
AVCodecParser ff_vorbis_parser = {
.codec_ids = { AV_CODEC_ID_VORBIS },
.priv_data_size = sizeof(VorbisParseContext),
.parser_parse = vorbis_parse,
+ .parser_close = vorbis_parser_close,
};
#endif /* CONFIG_VORBIS_PARSER */
/*
- * Copyright (c) 2012 Justin Ruggles
*
* This file is part of FFmpeg.
*
/**
* @file
- * Vorbis audio parser
+ * A public API for Vorbis parsing
*
* Determines the duration for each packet.
*/
-#ifndef AVCODEC_VORBIS_PARSER_H
-#define AVCODEC_VORBIS_PARSER_H
+#ifndef AVCODEC_VORBIS_PARSE_H
+#define AVCODEC_VORBIS_PARSE_H
-#include "avcodec.h"
+#include <stdint.h>
-typedef struct VorbisParseContext {
- AVCodecContext *avctx; ///< codec context
- int extradata_parsed; ///< we have attempted to parse extradata
- int valid_extradata; ///< extradata is valid, so we can calculate duration
- int blocksize[2]; ///< short and long window sizes
- int previous_blocksize; ///< previous window size
- int mode_blocksize[64]; ///< window size mapping for each mode
- int mode_count; ///< number of modes
- int mode_mask; ///< bitmask used to get the mode in each packet
- int prev_mask; ///< bitmask used to get the previous mode flag in each packet
-} VorbisParseContext;
+typedef struct AVVorbisParseContext AVVorbisParseContext;
/**
- * Initialize the Vorbis parser using headers in the extradata.
+ * Allocate and initialize the Vorbis parser using headers in the extradata.
*
* @param avctx codec context
* @param s Vorbis parser context
*/
-int avpriv_vorbis_parse_extradata(AVCodecContext *avctx, VorbisParseContext *s);
+AVVorbisParseContext *av_vorbis_parse_init(const uint8_t *extradata,
+ int extradata_size);
+
+/**
+ * Free the parser and everything associated with it.
+ */
+void av_vorbis_parse_free(AVVorbisParseContext **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,
+ * If @p flags is @c NULL,
* special frames are considered invalid.
*
* @param s Vorbis parser context
* @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);
+int av_vorbis_parse_frame_flags(AVVorbisParseContext *s, const uint8_t *buf,
+ int buf_size, int *flags);
/**
* 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.
- *
* @param s Vorbis parser context
* @param buf buffer containing a Vorbis frame
* @param buf_size size of the buffer
*/
-int avpriv_vorbis_parse_frame(VorbisParseContext *s, const uint8_t *buf,
- int buf_size);
+int av_vorbis_parse_frame(AVVorbisParseContext *s, const uint8_t *buf,
+ int buf_size);
-void avpriv_vorbis_parse_reset(VorbisParseContext *s);
+void av_vorbis_parse_reset(AVVorbisParseContext *s);
-#endif /* AVCODEC_VORBIS_PARSER_H */
+#endif /* AVCODEC_VORBIS_PARSE_H */
--- /dev/null
+/*
+ * Copyright (c) 2012 Justin Ruggles
+ *
+ * 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
+ * Vorbis audio parser
+ *
+ * Determines the duration for each packet.
+ */
+
+#ifndef AVCODEC_VORBIS_PARSER_H
+#define AVCODEC_VORBIS_PARSER_H
+
+#include "avcodec.h"
+#include "vorbis_parser.h"
+
+struct AVVorbisParseContext {
+ const AVClass *class;
+ int extradata_parsed; ///< we have attempted to parse extradata
+ int valid_extradata; ///< extradata is valid, so we can calculate duration
+ int blocksize[2]; ///< short and long window sizes
+ int previous_blocksize; ///< previous window size
+ int mode_blocksize[64]; ///< window size mapping for each mode
+ int mode_count; ///< number of modes
+ int mode_mask; ///< bitmask used to get the mode in each packet
+ int prev_mask; ///< bitmask used to get the previous mode flag in each packet
+};
+
+#if LIBAVCODEC_VERSION_MAJOR < 57
+/**
+ * Initialize the Vorbis parser using headers in the extradata.
+ *
+ * @param avctx codec context
+ * @param s Vorbis parser context
+ */
+int avpriv_vorbis_parse_extradata(AVCodecContext *avctx, AVVorbisParseContext *s);
+
+/**
+ * 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(AVVorbisParseContext *s, const uint8_t *buf,
+ int buf_size, int *flags);
+
+/**
+ * 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.
+ *
+ * @param s Vorbis parser context
+ * @param buf buffer containing a Vorbis frame
+ * @param buf_size size of the buffer
+ */
+int avpriv_vorbis_parse_frame(AVVorbisParseContext *s, const uint8_t *buf,
+ int buf_size);
+
+void avpriv_vorbis_parse_reset(AVVorbisParseContext *s);
+#endif
+
+#endif /* AVCODEC_VORBIS_PARSER_H */
AVCodecContext *avctx;
GetBitContext gb;
VorbisDSPContext dsp;
- AVFloatDSPContext fdsp;
+ AVFloatDSPContext *fdsp;
FmtConvertContext fmt_conv;
FFTContext mdct[2];
av_freep(&vc->channel_residues);
av_freep(&vc->saved);
+ av_freep(&vc->fdsp);
if (vc->residues)
for (i = 0; i < vc->residue_count; i++)
- av_free(vc->residues[i].classifs);
+ av_freep(&vc->residues[i].classifs);
av_freep(&vc->residues);
av_freep(&vc->modes);
if (vc->codebooks)
for (i = 0; i < vc->codebook_count; ++i) {
- av_free(vc->codebooks[i].codevectors);
+ av_freep(&vc->codebooks[i].codevectors);
ff_free_vlc(&vc->codebooks[i].vlc);
}
av_freep(&vc->codebooks);
if (vc->floors)
for (i = 0; i < vc->floor_count; ++i) {
if (vc->floors[i].floor_type == 0) {
- av_free(vc->floors[i].data.t0.map[0]);
- av_free(vc->floors[i].data.t0.map[1]);
- av_free(vc->floors[i].data.t0.book_list);
- av_free(vc->floors[i].data.t0.lsp);
+ av_freep(&vc->floors[i].data.t0.map[0]);
+ av_freep(&vc->floors[i].data.t0.map[1]);
+ av_freep(&vc->floors[i].data.t0.book_list);
+ av_freep(&vc->floors[i].data.t0.lsp);
} else {
- av_free(vc->floors[i].data.t1.list);
+ av_freep(&vc->floors[i].data.t1.list);
}
}
av_freep(&vc->floors);
if (vc->mappings)
for (i = 0; i < vc->mapping_count; ++i) {
- av_free(vc->mappings[i].magnitude);
- av_free(vc->mappings[i].angle);
- av_free(vc->mappings[i].mux);
+ av_freep(&vc->mappings[i].magnitude);
+ av_freep(&vc->mappings[i].angle);
+ av_freep(&vc->mappings[i].mux);
}
av_freep(&vc->mappings);
}
ff_mdct_init(&vc->mdct[0], bl0, 1, -1.0);
ff_mdct_init(&vc->mdct[1], bl1, 1, -1.0);
+ vc->fdsp = avpriv_float_dsp_alloc(vc->avctx->flags & CODEC_FLAG_BITEXACT);
+ if (!vc->fdsp)
+ return AVERROR(ENOMEM);
av_dlog(NULL, " vorbis version %d \n audio_channels %d \n audio_samplerate %d \n bitrate_max %d \n bitrate_nom %d \n bitrate_min %d \n blk_0 %d blk_1 %d \n ",
vc->version, vc->audio_channels, vc->audio_samplerate, vc->bitrate_maximum, vc->bitrate_nominal, vc->bitrate_minimum, vc->blocksize[0], vc->blocksize[1]);
vc->avctx = avctx;
ff_vorbisdsp_init(&vc->dsp);
- avpriv_float_dsp_init(&vc->fdsp, avctx->flags & CODEC_FLAG_BITEXACT);
ff_fmt_convert_init(&vc->fmt_conv, avctx);
avctx->sample_fmt = AV_SAMPLE_FMT_FLTP;
for (j = vc->audio_channels-1;j >= 0; j--) {
ch_res_ptr = vc->channel_residues + res_chan[j] * blocksize / 2;
- vc->fdsp.vector_fmul(floor_ptr[j], floor_ptr[j], ch_res_ptr, blocksize / 2);
+ vc->fdsp->vector_fmul(floor_ptr[j], floor_ptr[j], ch_res_ptr, blocksize / 2);
mdct->imdct_half(mdct, ch_res_ptr, floor_ptr[j]);
}
const float *win = vc->win[blockflag & previous_window];
if (blockflag == previous_window) {
- vc->fdsp.vector_fmul_window(ret, saved, buf, win, blocksize / 4);
+ vc->fdsp->vector_fmul_window(ret, saved, buf, win, blocksize / 4);
} else if (blockflag > previous_window) {
- vc->fdsp.vector_fmul_window(ret, saved, buf, win, bs0 / 4);
+ vc->fdsp->vector_fmul_window(ret, saved, buf, win, bs0 / 4);
memcpy(ret+bs0/2, buf+bs0/4, ((bs1-bs0)/4) * sizeof(float));
} else {
memcpy(ret, saved, ((bs1 - bs0) / 4) * sizeof(float));
- vc->fdsp.vector_fmul_window(ret + (bs1 - bs0) / 4, saved + (bs1 - bs0) / 4, buf, win, bs0 / 4);
+ vc->fdsp->vector_fmul_window(ret + (bs1 - bs0) / 4, saved + (bs1 - bs0) / 4, buf, win, bs0 / 4);
}
memcpy(saved, buf + blocksize / 4, blocksize / 4 * sizeof(float));
}
if (frame) {
if (frame->pts != AV_NOPTS_VALUE)
avpkt->pts = ff_samples_to_time_base(avctx, frame->pts);
- } else
+ } else {
avpkt->pts = venc->next_pts;
+ }
if (avpkt->pts != AV_NOPTS_VALUE)
venc->next_pts = avpkt->pts + avpkt->duration;
av_log(avctx, AV_LOG_ERROR, "Invalid framerate\n");
return AVERROR_INVALIDDATA;
}
- av_reduce(&avctx->time_base.num, &avctx->time_base.den,
+ av_reduce(&avctx->framerate.den, &avctx->framerate.num,
fps.den, fps.num, 1 << 30);
}
if (s->alpha_context) {
ff_vp56_free_context(s->alpha_context);
vp6_decode_free_context(s->alpha_context);
- av_free(s->alpha_context);
+ av_freep(&s->alpha_context);
}
return 0;
buf_size -= header_size;
if (s->keyframe) {
- if (vp8_rac_get(c))
+ s->colorspace = vp8_rac_get(c);
+ if (s->colorspace)
av_log(s->avctx, AV_LOG_WARNING, "Unspecified colorspace\n");
- vp8_rac_get(c); // whether we can skip clamping in dsp functions
+ s->fullrange = vp8_rac_get(c);
}
if ((s->segmentation.enabled = vp8_rac_get(c)))
mb->bmv[2 * y * 4 + 2 * x + 1].y +
mb->bmv[(2 * y + 1) * 4 + 2 * x ].y +
mb->bmv[(2 * y + 1) * 4 + 2 * x + 1].y;
- uvmv.x = (uvmv.x + 2 + (uvmv.x >> (INT_BIT - 1))) >> 2;
- uvmv.y = (uvmv.y + 2 + (uvmv.y >> (INT_BIT - 1))) >> 2;
+ uvmv.x = (uvmv.x + 2 + FF_SIGNBIT(uvmv.x)) >> 2;
+ uvmv.y = (uvmv.y + 2 + FF_SIGNBIT(uvmv.y)) >> 2;
if (s->profile == 3) {
uvmv.x &= ~7;
uvmv.y &= ~7;
curframe = s->framep[VP56_FRAME_CURRENT] = vp8_find_free_buffer(s);
+ if (!s->colorspace)
+ avctx->colorspace = AVCOL_SPC_BT470BG;
+ if (s->fullrange)
+ avctx->color_range = AVCOL_RANGE_JPEG;
+ else
+ avctx->color_range = AVCOL_RANGE_MPEG;
+
/* Given that arithmetic probabilities are updated every frame, it's quite
* likely that the values we have on a random interframe are complete
* junk if we didn't start decode on a keyframe. So just don't display
vp8_mc_func put_pixels_tab[3][3][3];
VP8Frame frames[5];
+ uint8_t colorspace; ///< 0 is the only value allowed (meaning bt601)
+ uint8_t fullrange; ///< whether we can skip clamping in dsp functions
+
int num_jobs;
/**
* This describes the macroblock memory layout.
uint8_t yac_qi;
int8_t ydc_qdelta, uvdc_qdelta, uvac_qdelta;
uint8_t lossless;
+#define MAX_SEGMENT 8
struct {
uint8_t enabled;
uint8_t temporal;
int8_t lf_val;
int16_t qmul[2][2];
uint8_t lflvl[4][2];
- } feat[8];
+ } feat[MAX_SEGMENT];
} segmentation;
struct {
unsigned log2_tile_cols, log2_tile_rows;
return res;
}
+ if (s->fullrange)
+ ctx->color_range = AVCOL_RANGE_JPEG;
+ else
+ ctx->color_range = AVCOL_RANGE_MPEG;
+
+ switch (s->colorspace) {
+ case 1: ctx->colorspace = AVCOL_SPC_BT470BG; break;
+ case 2: ctx->colorspace = AVCOL_SPC_BT709; break;
+ case 3: ctx->colorspace = AVCOL_SPC_SMPTE170M; break;
+ case 4: ctx->colorspace = AVCOL_SPC_SMPTE240M; break;
+ }
+
// main tile decode loop
memset(s->above_partition_ctx, 0, s->cols);
memset(s->above_skip_ctx, 0, s->cols);
}
s->prob_ctx[s->framectxid].p = s->prob.p;
ff_thread_finish_setup(ctx);
+ } else if (!s->refreshctx) {
+ ff_thread_finish_setup(ctx);
}
do {
av_free(line);
}
- for (y = 0; y < img->frame->height; y++) {
- for (x = 0; x < img->frame->width; x++) {
- p = GET_PIXEL(img->frame, x, y);
- i = p[2];
- if (i >= pal->frame->width) {
- AV_WB32(p, 0x00000000);
- } else {
- const uint8_t *pi = GET_PIXEL(pal->frame, i, 0);
- AV_COPY32(p, pi);
+ // switch to local palette if it's worth initializing it
+ if (img->frame->height * img->frame->width > 300) {
+ uint8_t palette[256 * 4];
+ const int size = pal->frame->width * 4;
+ av_assert0(size <= 1024U);
+ memcpy(palette, GET_PIXEL(pal->frame, 0, 0), size); // copy palette
+ // set extra entries to transparent black
+ memset(palette + size, 0, 256 * 4 - size);
+ for (y = 0; y < img->frame->height; y++) {
+ for (x = 0; x < img->frame->width; x++) {
+ p = GET_PIXEL(img->frame, x, y);
+ i = p[2];
+ AV_COPY32(p, &palette[i * 4]);
+ }
+ }
+ } else {
+ for (y = 0; y < img->frame->height; y++) {
+ for (x = 0; x < img->frame->width; x++) {
+ p = GET_PIXEL(img->frame, x, y);
+ i = p[2];
+ if (i >= pal->frame->width) {
+ AV_WB32(p, 0x00000000);
+ } else {
+ const uint8_t *pi = GET_PIXEL(pal->frame, i, 0);
+ AV_COPY32(p, pi);
+ }
}
}
}
av_bprint_chars(buf, *p, 1);
p++;
}
- av_bprintf(buf, "\r\n");
return 0;
}
static int webvtt_decode_frame(AVCodecContext *avctx,
void *data, int *got_sub_ptr, AVPacket *avpkt)
{
+ int ret = 0;
AVSubtitle *sub = data;
const char *ptr = avpkt->data;
AVBPrint buf;
int ts_start = av_rescale_q(avpkt->pts, avctx->time_base, (AVRational){1,100});
int ts_duration = avpkt->duration != -1 ?
av_rescale_q(avpkt->duration, avctx->time_base, (AVRational){1,100}) : -1;
- ff_ass_add_rect(sub, buf.str, ts_start, ts_duration, 0);
+ ret = ff_ass_add_rect_bprint(sub, &buf, ts_start, ts_duration);
}
- *got_sub_ptr = sub->num_rects > 0;
av_bprint_finalize(&buf, NULL);
+ if (ret < 0)
+ return ret;
+ *got_sub_ptr = sub->num_rects > 0;
return avpkt->size;
}
return -1;
ff_fmt_convert_init(&s->fmt_conv, avctx);
- avpriv_float_dsp_init(&s->fdsp, avctx->flags & CODEC_FLAG_BITEXACT);
if (avctx->codec->id == AV_CODEC_ID_WMAV1)
s->version = 1;
#endif /* TRACE */
}
+ s->fdsp = avpriv_float_dsp_alloc(avctx->flags & CODEC_FLAG_BITEXACT);
+ if (!s->fdsp)
+ return AVERROR(ENOMEM);
+
/* choose the VLC tables for the coefficients */
coef_vlc_table = 2;
if (avctx->sample_rate >= 32000) {
av_freep(&s->level_table[i]);
av_freep(&s->int_table[i]);
}
+ av_freep(&s->fdsp);
return 0;
}
float lsp_pow_m_table1[(1 << LSP_POW_BITS)];
float lsp_pow_m_table2[(1 << LSP_POW_BITS)];
FmtConvertContext fmt_conv;
- AVFloatDSPContext fdsp;
+ AVFloatDSPContext *fdsp;
#ifdef TRACE
int frame_count;
block_len = s->block_len;
bsize = s->frame_len_bits - s->block_len_bits;
- s->fdsp.vector_fmul_add(out, in, s->windows[bsize],
+ s->fdsp->vector_fmul_add(out, in, s->windows[bsize],
out, block_len);
} else {
block_len = 1 << s->prev_block_len_bits;
n = (s->block_len - block_len) / 2;
bsize = s->frame_len_bits - s->prev_block_len_bits;
- s->fdsp.vector_fmul_add(out + n, in + n, s->windows[bsize],
+ s->fdsp->vector_fmul_add(out + n, in + n, s->windows[bsize],
out + n, block_len);
memcpy(out + n + block_len, in + n + block_len, n * sizeof(float));
block_len = s->block_len;
bsize = s->frame_len_bits - s->block_len_bits;
- s->fdsp.vector_fmul_reverse(out, in, s->windows[bsize], block_len);
+ s->fdsp->vector_fmul_reverse(out, in, s->windows[bsize], block_len);
} else {
block_len = 1 << s->next_block_len_bits;
n = (s->block_len - block_len) / 2;
memcpy(out, in, n * sizeof(float));
- s->fdsp.vector_fmul_reverse(out + n, in + n, s->windows[bsize],
+ s->fdsp->vector_fmul_reverse(out + n, in + n, s->windows[bsize],
block_len);
memset(out + n + block_len, 0, n * sizeof(float));
s->channel_coded[0] = 1;
}
- s->fdsp.butterflies_float(s->coefs[0], s->coefs[1], s->block_len);
+ s->fdsp->butterflies_float(s->coefs[0], s->coefs[1], s->block_len);
}
next:
(avctx->sample_rate * 8);
block_align = FFMIN(block_align, MAX_CODED_SUPERFRAME_SIZE);
avctx->block_align = block_align;
-
- avctx->frame_size =
- avctx->delay = s->frame_len;
+ avctx->frame_size = avctx->initial_padding = s->frame_len;
return 0;
}
for (ch = 0; ch < avctx->channels; ch++) {
memcpy(s->output, s->frame_out[ch], window_len * sizeof(*s->output));
- s->fdsp.vector_fmul_scalar(s->frame_out[ch], audio[ch], n, len);
- s->fdsp.vector_fmul_reverse(&s->output[window_len], s->frame_out[ch],
+ s->fdsp->vector_fmul_scalar(s->frame_out[ch], audio[ch], n, len);
+ s->fdsp->vector_fmul_reverse(&s->output[window_len], s->frame_out[ch],
win, len);
- s->fdsp.vector_fmul(s->frame_out[ch], s->frame_out[ch], win, len);
+ s->fdsp->vector_fmul(s->frame_out[ch], s->frame_out[ch], win, len);
mdct->mdct_calc(mdct, s->coefs[ch], s->output);
}
}
av_assert0(put_bits_ptr(&s->pb) - s->pb.buf == avctx->block_align);
if (frame->pts != AV_NOPTS_VALUE)
- avpkt->pts = frame->pts - ff_samples_to_time_base(avctx, avctx->delay);
+ avpkt->pts = frame->pts - ff_samples_to_time_base(avctx, avctx->initial_padding);
avpkt->size = avctx->block_align;
*got_packet_ptr = 1;
avctx->sample_fmt = AV_SAMPLE_FMT_S16P;
else if (s->bits_per_sample == 24) {
avctx->sample_fmt = AV_SAMPLE_FMT_S32P;
- avpriv_report_missing_feature(avctx, "Bit-depth higher than 16");
- return AVERROR_PATCHWELCOME;
+ avctx->bits_per_raw_sample = 24;
} else {
av_log(avctx, AV_LOG_ERROR, "Unknown bit-depth: %"PRIu8"\n",
s->bits_per_sample);
if (s->bits_per_sample == 16) {
*s->samples_16[c]++ = (int16_t) s->channel_residues[c][j] << padding_zeroes;
} else {
- *s->samples_32[c]++ = s->channel_residues[c][j] << padding_zeroes;
+ *s->samples_32[c]++ = s->channel_residues[c][j] << (padding_zeroes + 8);
}
}
}
typedef struct WMAProDecodeCtx {
/* generic decoder variables */
AVCodecContext* avctx; ///< codec context for av_log
- AVFloatDSPContext fdsp;
+ AVFloatDSPContext *fdsp;
uint8_t frame_data[MAX_FRAMESIZE +
FF_INPUT_BUFFER_PADDING_SIZE];///< compressed frame data
PutBitContext pb; ///< context for filling the frame_data buffer
WMAProDecodeCtx *s = avctx->priv_data;
int i;
+ av_freep(&s->fdsp);
+
for (i = 0; i < WMAPRO_BLOCK_SIZES; i++)
ff_mdct_end(&s->mdct_ctx[i]);
}
s->avctx = avctx;
- avpriv_float_dsp_init(&s->fdsp, avctx->flags & CODEC_FLAG_BITEXACT);
+ s->fdsp = avpriv_float_dsp_alloc(avctx->flags & CODEC_FLAG_BITEXACT);
+ if (!s->fdsp)
+ return AVERROR(ENOMEM);
init_put_bits(&s->pb, s->frame_data, MAX_FRAMESIZE);
offset &= ~3;
if (offset > s->sfb_offsets[i][band - 1])
s->sfb_offsets[i][band++] = offset;
+
+ if (offset >= subframe_len)
+ break;
}
s->sfb_offsets[i][band - 1] = subframe_len;
s->num_sfb[i] = band - 1;
}
} else if (s->avctx->channels == 2) {
int len = FFMIN(sfb[1], s->subframe_len) - sfb[0];
- s->fdsp.vector_fmul_scalar(ch_data[0] + sfb[0],
+ s->fdsp->vector_fmul_scalar(ch_data[0] + sfb[0],
ch_data[0] + sfb[0],
181.0 / 128, len);
- s->fdsp.vector_fmul_scalar(ch_data[1] + sfb[0],
+ s->fdsp->vector_fmul_scalar(ch_data[1] + sfb[0],
ch_data[1] + sfb[0],
181.0 / 128, len);
}
winlen >>= 1;
- s->fdsp.vector_fmul_window(start, start, start + winlen,
+ s->fdsp->vector_fmul_window(start, start, start + winlen,
window, winlen);
s->channel[c].prev_block_len = s->subframe_len;
s->channel[c].scale_factor_step;
const float quant = pow(10.0, exp / 20.0);
int start = s->cur_sfb_offsets[b];
- s->fdsp.vector_fmul_scalar(s->tmp + start,
+ s->fdsp->vector_fmul_scalar(s->tmp + start,
s->channel[c].coeffs + start,
quant, end - start);
}
s->p_tex_bits += get_bits_diff(s);
}
+FF_MPV_GENERIC_CLASS(wmv2)
+
AVCodec ff_wmv2_encoder = {
.name = "wmv2",
.long_name = NULL_IF_CONFIG_SMALL("Windows Media Video 8"),
.close = ff_mpv_encode_end,
.pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P,
AV_PIX_FMT_NONE },
+ .priv_class = &wmv2_class,
};
# decoders/encoders
OBJS-$(CONFIG_AAC_DECODER) += x86/sbrdsp_init.o
+OBJS-$(CONFIG_APNG_DECODER) += x86/pngdsp_init.o
OBJS-$(CONFIG_CAVS_DECODER) += x86/cavsdsp.o
OBJS-$(CONFIG_DCA_DECODER) += x86/dcadsp_init.o
OBJS-$(CONFIG_DNXHD_ENCODER) += x86/dnxhdenc_init.o
OBJS-$(CONFIG_HEVC_DECODER) += x86/hevcdsp_init.o
-OBJS-$(CONFIG_MLP_DECODER) += x86/mlpdsp.o
+OBJS-$(CONFIG_MLP_DECODER) += x86/mlpdsp_init.o
OBJS-$(CONFIG_MPEG4_DECODER) += x86/xvididct_init.o
OBJS-$(CONFIG_PNG_DECODER) += x86/pngdsp_init.o
OBJS-$(CONFIG_PRORES_DECODER) += x86/proresdsp_init.o
OBJS-$(CONFIG_RV40_DECODER) += x86/rv34dsp_init.o \
x86/rv40dsp_init.o
OBJS-$(CONFIG_SVQ1_ENCODER) += x86/svq1enc_init.o
-OBJS-$(CONFIG_V210_DECODER) += x86/v210-init.o
+OBJS-$(CONFIG_TRUEHD_DECODER) += x86/mlpdsp_init.o
OBJS-$(CONFIG_TTA_DECODER) += x86/ttadsp_init.o
-OBJS-$(CONFIG_TRUEHD_DECODER) += x86/mlpdsp.o
+OBJS-$(CONFIG_V210_DECODER) += x86/v210-init.o
+OBJS-$(CONFIG_V210_ENCODER) += x86/v210enc_init.o
OBJS-$(CONFIG_VC1_DECODER) += x86/vc1dsp_init.o
OBJS-$(CONFIG_VORBIS_DECODER) += x86/vorbisdsp_init.o
OBJS-$(CONFIG_VP6_DECODER) += x86/vp6dsp_init.o
# subsystems
MMX-OBJS-$(CONFIG_DIRAC_DECODER) += x86/dirac_dwt.o
MMX-OBJS-$(CONFIG_FDCTDSP) += x86/fdct.o
-MMX-OBJS-$(CONFIG_IDCTDSP) += x86/idctdsp_mmx.o \
- x86/simple_idct.o
+MMX-OBJS-$(CONFIG_IDCTDSP) += x86/simple_idct.o
# decoders/encoders
MMX-OBJS-$(CONFIG_MPEG4_DECODER) += x86/xvididct_mmx.o \
# decoders/encoders
YASM-OBJS-$(CONFIG_AAC_DECODER) += x86/sbrdsp.o
+YASM-OBJS-$(CONFIG_APNG_DECODER) += x86/pngdsp.o
YASM-OBJS-$(CONFIG_DCA_DECODER) += x86/dcadsp.o
YASM-OBJS-$(CONFIG_HEVC_DECODER) += x86/hevc_mc.o \
x86/hevc_deblock.o \
x86/hevc_idct.o \
x86/hevc_res_add.o
+YASM-OBJS-$(CONFIG_MLP_DECODER) += x86/mlpdsp.o
YASM-OBJS-$(CONFIG_PNG_DECODER) += x86/pngdsp.o
YASM-OBJS-$(CONFIG_PRORES_DECODER) += x86/proresdsp.o
YASM-OBJS-$(CONFIG_PRORES_LGPL_DECODER) += x86/proresdsp.o
YASM-OBJS-$(CONFIG_RV40_DECODER) += x86/rv34dsp.o \
x86/rv40dsp.o
YASM-OBJS-$(CONFIG_SVQ1_ENCODER) += x86/svq1enc.o
+YASM-OBJS-$(CONFIG_TRUEHD_DECODER) += x86/mlpdsp.o
YASM-OBJS-$(CONFIG_TTA_DECODER) += x86/ttadsp.o
+YASM-OBJS-$(CONFIG_V210_ENCODER) += x86/v210enc.o
YASM-OBJS-$(CONFIG_V210_DECODER) += x86/v210.o
YASM-OBJS-$(CONFIG_VC1_DECODER) += x86/vc1dsp.o
YASM-OBJS-$(CONFIG_VORBIS_DECODER) += x86/vorbisdsp.o
static void cavs_idct8_add_mmx(uint8_t *dst, int16_t *block, int stride)
{
int i;
- DECLARE_ALIGNED(8, int16_t, b2)[64];
+ DECLARE_ALIGNED(16, int16_t, b2)[64];
for(i=0; i<2; i++){
DECLARE_ALIGNED(8, uint64_t, tmp);
);
}
- ff_add_pixels_clamped_mmx(b2, dst, stride);
+ ff_add_pixels_clamped(b2, dst, stride);
}
#endif /* HAVE_MMX_INLINE */
DECLARE_ALIGNED(8, const uint64_t, ff_pw_96) = 0x0060006000600060ULL;
DECLARE_ALIGNED(8, const uint64_t, ff_pw_128) = 0x0080008000800080ULL;
DECLARE_ALIGNED(8, const uint64_t, ff_pw_255) = 0x00ff00ff00ff00ffULL;
-DECLARE_ALIGNED(16, const xmm_reg, ff_pw_256) = { 0x0100010001000100ULL, 0x0100010001000100ULL };
+DECLARE_ALIGNED(32, const ymm_reg, ff_pw_256) = { 0x0100010001000100ULL, 0x0100010001000100ULL,
+ 0x0100010001000100ULL, 0x0100010001000100ULL };
DECLARE_ALIGNED(16, const xmm_reg, ff_pw_512) = { 0x0200020002000200ULL, 0x0200020002000200ULL };
DECLARE_ALIGNED(16, const xmm_reg, ff_pw_1019) = { 0x03FB03FB03FB03FBULL, 0x03FB03FB03FB03FBULL };
DECLARE_ALIGNED(16, const xmm_reg, ff_pw_1024) = { 0x0400040004000400ULL, 0x0400040004000400ULL };
;* FLAC DSP SIMD optimizations
;*
;* Copyright (C) 2014 Loren Merritt
+;* Copyright (C) 2014 James Almer
;*
;* This file is part of FFmpeg.
;*
LPC_32 xop
%endif
LPC_32 sse4
+
+;----------------------------------------------------------------------------------
+;void ff_flac_decorrelate_[lrm]s_16_sse2(uint8_t **out, int32_t **in, int channels,
+; int len, int shift);
+;----------------------------------------------------------------------------------
+%macro FLAC_DECORRELATE_16 3-4
+cglobal flac_decorrelate_%1_16, 2, 4, 4, out, in0, in1, len
+%if ARCH_X86_32 || WIN64
+ movd m3, r4m
+%if ARCH_X86_32
+ mov lend, lenm
+%endif
+%else ; UNIX64
+ movd m3, r4d
+%endif
+ shl lend, 2
+ mov in1q, [in0q + gprsize]
+ mov in0q, [in0q]
+ mov outq, [outq]
+ add in1q, lenq
+ add in0q, lenq
+ add outq, lenq
+ neg lenq
+
+align 16
+.loop:
+ mova m0, [in0q + lenq]
+ mova m1, [in1q + lenq]
+%ifidn %1, ms
+ psrad m2, m1, 1
+ psubd m0, m2
+%endif
+%ifnidn %1, indep2
+ p%4d m2, m0, m1
+%endif
+ packssdw m%2, m%2
+ packssdw m%3, m%3
+ punpcklwd m%2, m%3
+ psllw m%2, m3
+ mova [outq + lenq], m%2
+ add lenq, 16
+ jl .loop
+ REP_RET
+%endmacro
+
+INIT_XMM sse2
+FLAC_DECORRELATE_16 ls, 0, 2, sub
+FLAC_DECORRELATE_16 rs, 2, 1, add
+FLAC_DECORRELATE_16 ms, 2, 0, add
+
+;----------------------------------------------------------------------------------
+;void ff_flac_decorrelate_[lrm]s_32_sse2(uint8_t **out, int32_t **in, int channels,
+; int len, int shift);
+;----------------------------------------------------------------------------------
+%macro FLAC_DECORRELATE_32 5
+cglobal flac_decorrelate_%1_32, 2, 4, 4, out, in0, in1, len
+%if ARCH_X86_32 || WIN64
+ movd m3, r4m
+%if ARCH_X86_32
+ mov lend, lenm
+%endif
+%else ; UNIX64
+ movd m3, r4d
+%endif
+ mov in1q, [in0q + gprsize]
+ mov in0q, [in0q]
+ mov outq, [outq]
+ sub in1q, in0q
+
+align 16
+.loop:
+ mova m0, [in0q]
+ mova m1, [in0q + in1q]
+%ifidn %1, ms
+ psrad m2, m1, 1
+ psubd m0, m2
+%endif
+ p%5d m2, m0, m1
+ pslld m%2, m3
+ pslld m%3, m3
+
+ SBUTTERFLY dq, %2, %3, %4
+
+ mova [outq ], m%2
+ mova [outq + mmsize], m%3
+
+ add in0q, mmsize
+ add outq, mmsize*2
+ sub lend, mmsize/4
+ jg .loop
+ REP_RET
+%endmacro
+
+INIT_XMM sse2
+FLAC_DECORRELATE_32 ls, 0, 2, 1, sub
+FLAC_DECORRELATE_32 rs, 2, 1, 0, add
+FLAC_DECORRELATE_32 ms, 2, 0, 1, add
+
+;-----------------------------------------------------------------------------------------
+;void ff_flac_decorrelate_indep<ch>_<bps>_<opt>(uint8_t **out, int32_t **in, int channels,
+; int len, int shift);
+;-----------------------------------------------------------------------------------------
+%macro TRANSPOSE8x4D 9
+ SBUTTERFLY dq, %1, %2, %9
+ SBUTTERFLY dq, %3, %4, %9
+ SBUTTERFLY dq, %5, %6, %9
+ SBUTTERFLY dq, %7, %8, %9
+ SBUTTERFLY qdq, %1, %3, %9
+ SBUTTERFLY qdq, %2, %4, %9
+ SBUTTERFLY qdq, %5, %7, %9
+ SBUTTERFLY qdq, %6, %8, %9
+ SWAP %2, %5
+ SWAP %4, %7
+%endmacro
+
+;%1 = bps
+;%2 = channels
+;%3 = last xmm reg used
+;%4 = word/dword (shift instruction)
+%macro FLAC_DECORRELATE_INDEP 4
+%define REPCOUNT %2/(32/%1) ; 16bits = channels / 2; 32bits = channels
+cglobal flac_decorrelate_indep%2_%1, 2, %2+2, %3+1, out, in0, in1, len, in2, in3, in4, in5, in6, in7
+%if ARCH_X86_32
+ movd m%3, r4m
+%if %2 == 6
+ DEFINE_ARGS out, in0, in1, in2, in3, in4, in5
+ %define lend dword r3m
+%else
+ mov lend, lenm
+%endif
+%elif WIN64
+ movd m%3, r4m
+%else ; UNIX64
+ movd m%3, r4d
+%endif
+
+%assign %%i 1
+%rep %2-1
+ mov in %+ %%i %+ q, [in0q+%%i*gprsize]
+%assign %%i %%i+1
+%endrep
+
+ mov in0q, [in0q]
+ mov outq, [outq]
+
+%assign %%i 1
+%rep %2-1
+ sub in %+ %%i %+ q, in0q
+%assign %%i %%i+1
+%endrep
+
+align 16
+.loop:
+ mova m0, [in0q]
+
+%assign %%i 1
+%rep REPCOUNT-1
+ mova m %+ %%i, [in0q + in %+ %%i %+ q]
+%assign %%i %%i+1
+%endrep
+
+%if %1 == 32
+
+%if %2 == 8
+ TRANSPOSE8x4D 0, 1, 2, 3, 4, 5, 6, 7, 8
+%elif %2 == 6
+ SBUTTERFLY dq, 0, 1, 6
+ SBUTTERFLY dq, 2, 3, 6
+ SBUTTERFLY dq, 4, 5, 6
+
+ punpcklqdq m6, m0, m2
+ punpckhqdq m2, m4
+ shufps m4, m0, 0xe4
+ punpcklqdq m0, m1, m3
+ punpckhqdq m3, m5
+ shufps m5, m1, 0xe4
+ SWAP 0,6,1,4,5,3
+%elif %2 == 4
+ TRANSPOSE4x4D 0, 1, 2, 3, 4
+%else ; %2 == 2
+ SBUTTERFLY dq, 0, 1, 2
+%endif
+
+%else ; %1 == 16
+
+%if %2 == 8
+ packssdw m0, [in0q + in4q]
+ packssdw m1, [in0q + in5q]
+ packssdw m2, [in0q + in6q]
+ packssdw m3, [in0q + in7q]
+ TRANSPOSE2x4x4W 0, 1, 2, 3, 4
+%elif %2 == 6
+ packssdw m0, [in0q + in3q]
+ packssdw m1, [in0q + in4q]
+ packssdw m2, [in0q + in5q]
+ pshufd m3, m0, q1032
+ punpcklwd m0, m1
+ punpckhwd m1, m2
+ punpcklwd m2, m3
+
+ shufps m3, m0, m2, q2020
+ shufps m0, m1, q2031
+ shufps m2, m1, q3131
+ shufps m1, m2, m3, q3120
+ shufps m3, m0, q0220
+ shufps m0, m2, q3113
+ SWAP 2, 0, 3
+%else ; %2 == 4
+ packssdw m0, [in0q + in2q]
+ packssdw m1, [in0q + in3q]
+ SBUTTERFLY wd, 0, 1, 2
+ SBUTTERFLY dq, 0, 1, 2
+%endif
+
+%endif
+
+%assign %%i 0
+%rep REPCOUNT
+ psll%4 m %+ %%i, m%3
+%assign %%i %%i+1
+%endrep
+
+%assign %%i 0
+%rep REPCOUNT
+ mova [outq + %%i*mmsize], m %+ %%i
+%assign %%i %%i+1
+%endrep
+
+ add in0q, mmsize
+ add outq, mmsize*REPCOUNT
+ sub lend, mmsize/4
+ jg .loop
+ REP_RET
+%endmacro
+
+INIT_XMM sse2
+FLAC_DECORRELATE_16 indep2, 0, 1 ; Reuse stereo 16bits macro
+FLAC_DECORRELATE_INDEP 32, 2, 3, d
+FLAC_DECORRELATE_INDEP 16, 4, 3, w
+FLAC_DECORRELATE_INDEP 32, 4, 5, d
+FLAC_DECORRELATE_INDEP 16, 6, 4, w
+FLAC_DECORRELATE_INDEP 32, 6, 7, d
+%if ARCH_X86_64
+FLAC_DECORRELATE_INDEP 16, 8, 5, w
+FLAC_DECORRELATE_INDEP 32, 8, 9, d
+%endif
+
+INIT_XMM avx
+FLAC_DECORRELATE_INDEP 32, 4, 5, d
+FLAC_DECORRELATE_INDEP 32, 6, 7, d
+%if ARCH_X86_64
+FLAC_DECORRELATE_INDEP 16, 8, 5, w
+FLAC_DECORRELATE_INDEP 32, 8, 9, d
+%endif
void ff_flac_enc_lpc_16_sse4(int32_t *, const int32_t *, int, int, const int32_t *,int);
-av_cold void ff_flacdsp_init_x86(FLACDSPContext *c, enum AVSampleFormat fmt,
+#define DECORRELATE_FUNCS(fmt, opt) \
+void ff_flac_decorrelate_ls_##fmt##_##opt(uint8_t **out, int32_t **in, int channels, \
+ int len, int shift); \
+void ff_flac_decorrelate_rs_##fmt##_##opt(uint8_t **out, int32_t **in, int channels, \
+ int len, int shift); \
+void ff_flac_decorrelate_ms_##fmt##_##opt(uint8_t **out, int32_t **in, int channels, \
+ int len, int shift); \
+void ff_flac_decorrelate_indep2_##fmt##_##opt(uint8_t **out, int32_t **in, int channels, \
+ int len, int shift); \
+void ff_flac_decorrelate_indep4_##fmt##_##opt(uint8_t **out, int32_t **in, int channels, \
+ int len, int shift); \
+void ff_flac_decorrelate_indep6_##fmt##_##opt(uint8_t **out, int32_t **in, int channels, \
+ int len, int shift); \
+void ff_flac_decorrelate_indep8_##fmt##_##opt(uint8_t **out, int32_t **in, int channels, \
+ int len, int shift)
+
+DECORRELATE_FUNCS(16, sse2);
+DECORRELATE_FUNCS(16, avx);
+DECORRELATE_FUNCS(32, sse2);
+DECORRELATE_FUNCS(32, avx);
+
+av_cold void ff_flacdsp_init_x86(FLACDSPContext *c, enum AVSampleFormat fmt, int channels,
int bps)
{
#if HAVE_YASM
int cpu_flags = av_get_cpu_flags();
+#if CONFIG_FLAC_DECODER
+ if (EXTERNAL_SSE2(cpu_flags)) {
+ if (fmt == AV_SAMPLE_FMT_S16) {
+ if (channels == 2)
+ c->decorrelate[0] = ff_flac_decorrelate_indep2_16_sse2;
+ else if (channels == 4)
+ c->decorrelate[0] = ff_flac_decorrelate_indep4_16_sse2;
+ else if (channels == 6)
+ c->decorrelate[0] = ff_flac_decorrelate_indep6_16_sse2;
+ else if (ARCH_X86_64 && channels == 8)
+ c->decorrelate[0] = ff_flac_decorrelate_indep8_16_sse2;
+ c->decorrelate[1] = ff_flac_decorrelate_ls_16_sse2;
+ c->decorrelate[2] = ff_flac_decorrelate_rs_16_sse2;
+ c->decorrelate[3] = ff_flac_decorrelate_ms_16_sse2;
+ } else if (fmt == AV_SAMPLE_FMT_S32) {
+ if (channels == 2)
+ c->decorrelate[0] = ff_flac_decorrelate_indep2_32_sse2;
+ else if (channels == 4)
+ c->decorrelate[0] = ff_flac_decorrelate_indep4_32_sse2;
+ else if (channels == 6)
+ c->decorrelate[0] = ff_flac_decorrelate_indep6_32_sse2;
+ else if (ARCH_X86_64 && channels == 8)
+ c->decorrelate[0] = ff_flac_decorrelate_indep8_32_sse2;
+ c->decorrelate[1] = ff_flac_decorrelate_ls_32_sse2;
+ c->decorrelate[2] = ff_flac_decorrelate_rs_32_sse2;
+ c->decorrelate[3] = ff_flac_decorrelate_ms_32_sse2;
+ }
+ }
if (EXTERNAL_SSE4(cpu_flags)) {
- if (bps > 16 && CONFIG_FLAC_DECODER)
+ if (bps > 16)
c->lpc = ff_flac_lpc_32_sse4;
- if (bps == 16 && CONFIG_FLAC_ENCODER && CONFIG_GPL)
- c->lpc_encode = ff_flac_enc_lpc_16_sse4;
+ }
+ if (EXTERNAL_AVX(cpu_flags)) {
+ if (fmt == AV_SAMPLE_FMT_S16) {
+ if (ARCH_X86_64 && channels == 8)
+ c->decorrelate[0] = ff_flac_decorrelate_indep8_16_avx;
+ } else if (fmt == AV_SAMPLE_FMT_S32) {
+ if (channels == 4)
+ c->decorrelate[0] = ff_flac_decorrelate_indep4_32_avx;
+ else if (channels == 6)
+ c->decorrelate[0] = ff_flac_decorrelate_indep6_32_avx;
+ else if (ARCH_X86_64 && channels == 8)
+ c->decorrelate[0] = ff_flac_decorrelate_indep8_32_avx;
+ }
}
if (EXTERNAL_XOP(cpu_flags)) {
- if (bps > 16 && CONFIG_FLAC_DECODER)
+ if (bps > 16)
c->lpc = ff_flac_lpc_32_xop;
}
#endif
+
+#if CONFIG_FLAC_ENCODER
+ if (EXTERNAL_SSE4(cpu_flags)) {
+ if (CONFIG_GPL && bps == 16)
+ c->lpc_encode = ff_flac_enc_lpc_16_sse4;
+ }
+#endif
+#endif /* HAVE_YASM */
}
INIT_XMM sse2
INT32_TO_FLOAT_FMUL_SCALAR 3
+;------------------------------------------------------------------------------
+; void ff_int32_to_float_fmul_array8(FmtConvertContext *c, float *dst, const int32_t *src,
+; const float *mul, int len);
+;------------------------------------------------------------------------------
+%macro INT32_TO_FLOAT_FMUL_ARRAY8 0
+cglobal int32_to_float_fmul_array8, 5, 5, 5, c, dst, src, mul, len
+ shl lend, 2
+ add srcq, lenq
+ add dstq, lenq
+ neg lenq
+.loop:
+ movss m0, [mulq]
+ SPLATD m0
+%if cpuflag(sse2)
+ cvtdq2ps m1, [srcq+lenq ]
+ cvtdq2ps m2, [srcq+lenq+16]
+%else
+ cvtpi2ps m1, [srcq+lenq ]
+ cvtpi2ps m3, [srcq+lenq+ 8]
+ cvtpi2ps m2, [srcq+lenq+16]
+ cvtpi2ps m4, [srcq+lenq+24]
+ movlhps m1, m3
+ movlhps m2, m4
+%endif
+ mulps m1, m0
+ mulps m2, m0
+ mova [dstq+lenq ], m1
+ mova [dstq+lenq+16], m2
+ add mulq, 4
+ add lenq, 32
+ jl .loop
+ REP_RET
+%endmacro
+
+INIT_XMM sse
+INT32_TO_FLOAT_FMUL_ARRAY8
+INIT_XMM sse2
+INT32_TO_FLOAT_FMUL_ARRAY8
;------------------------------------------------------------------------------
; void ff_float_to_int16(int16_t *dst, const float *src, long len);
void ff_int32_to_float_fmul_scalar_sse (float *dst, const int32_t *src, float mul, int len);
void ff_int32_to_float_fmul_scalar_sse2(float *dst, const int32_t *src, float mul, int len);
+void ff_int32_to_float_fmul_array8_sse (FmtConvertContext *c, float *dst, const int32_t *src,
+ const float *mul, int len);
+void ff_int32_to_float_fmul_array8_sse2(FmtConvertContext *c, float *dst, const int32_t *src,
+ const float *mul, int len);
void ff_float_to_int16_3dnow(int16_t *dst, const float *src, long len);
void ff_float_to_int16_sse (int16_t *dst, const float *src, long len);
}
if (EXTERNAL_SSE(cpu_flags)) {
c->int32_to_float_fmul_scalar = ff_int32_to_float_fmul_scalar_sse;
+ c->int32_to_float_fmul_array8 = ff_int32_to_float_fmul_array8_sse;
c->float_to_int16 = ff_float_to_int16_sse;
c->float_to_int16_interleave = float_to_int16_interleave_sse;
c->float_interleave = float_interleave_sse;
}
if (EXTERNAL_SSE2(cpu_flags)) {
c->int32_to_float_fmul_scalar = ff_int32_to_float_fmul_scalar_sse2;
+ c->int32_to_float_fmul_array8 = ff_int32_to_float_fmul_array8_sse2;
c->float_to_int16 = ff_float_to_int16_sse2;
c->float_to_int16_interleave = float_to_int16_interleave_sse2;
}
#if HAVE_INLINE_ASM
+#if ARCH_X86_64
+#define REG64 "r"
+#else
+#define REG64 "m"
+#endif
+
//FIXME use some macros to avoid duplicating get_cabac (cannot be done yet
//as that would make optimization work hard)
#if HAVE_7REGS && !BROKEN_COMPILER
"3: \n\t"
"mov %10, %0 \n\t"
- "movzbl (%0, %6), %k6 \n\t"
+ "movzb (%0, %6), %6 \n\t"
"add %9, %6 \n\t"
BRANCHLESS_GET_CABAC("%4", "%q4", "(%6)", "%3", "%w3",
AV_STRINGIFY(H264_MLPS_STATE_OFFSET),
"%15")
- "mov %1, %k6 \n\t"
+ "mov %1, %6 \n\t"
"test $1, %4 \n\t"
" jz 4f \n\t"
#ifdef BROKEN_RELOCATIONS
- "movzbl %c14(%15, %q6), %k6\n\t"
+ "movzb %c14(%15, %q6), %6\n\t"
#else
- "movzbl "MANGLE(ff_h264_cabac_tables)"+%c14(%k6), %k6\n\t"
+ "movzb "MANGLE(ff_h264_cabac_tables)"+%c14(%6), %6\n\t"
#endif
"add %11, %6 \n\t"
"%15")
"mov %2, %0 \n\t"
- "mov %1, %k6 \n\t"
- "movl %k6, (%0) \n\t"
+ "mov %1, %6 \n\t"
+ "mov %k6, (%0) \n\t"
"test $1, %4 \n\t"
" jnz 5f \n\t"
"add"OPSIZE" $4, %2 \n\t"
"4: \n\t"
- "addl $1, %k6 \n\t"
- "mov %k6, %1 \n\t"
- "cmpl $63, %k6 \n\t"
+ "add $1, %6 \n\t"
+ "mov %6, %1 \n\t"
+ "cmp $63, %6 \n\t"
" jb 3b \n\t"
"mov %2, %0 \n\t"
- "movl %k6, (%0) \n\t"
+ "mov %k6, (%0) \n\t"
"5: \n\t"
"addl %8, %k0 \n\t"
"shr $2, %k0 \n\t"
- : "=&q"(coeff_count), "+m"(last), "+m"(index), "+&r"(c->low),
+ : "=&q"(coeff_count), "+"REG64(last), "+"REG64(index), "+&r"(c->low),
"=&r"(bit), "+&r"(c->range), "=&r"(state)
: "r"(c), "m"(minusindex), "m"(significant_coeff_ctx_base),
- "m"(sig_off), "m"(last_coeff_ctx_base),
+ REG64(sig_off), REG64(last_coeff_ctx_base),
"i"(offsetof(CABACContext, bytestream)),
"i"(offsetof(CABACContext, bytestream_end)),
"i"(H264_LAST_COEFF_FLAG_OFFSET_8x8_OFFSET) TABLES_ARG
movq mm4, mm3
PALIGNR mm2, mm0, 7, mm0
PALIGNR mm1, mm4, 1, mm4
- test r1, r1 ; top_left
+ test r1d, r1d ; top_left
jz .fix_lt_2
- test r2, r2 ; top_right
+ test r2d, r2d ; top_right
jz .fix_tr_1
jmp .body
.fix_lt_2:
psllq mm5, 56
psrlq mm5, 56
pxor mm2, mm5
- test r2, r2 ; top_right
+ test r2d, r2d ; top_right
jnz .body
.fix_tr_1:
movq mm5, mm3
movq mm2, mm3
PALIGNR mm4, mm0, 7, mm0
PALIGNR mm1, mm2, 1, mm2
- test r1, r1
+ test r1d, r1d
jnz .do_left
.fix_lt_1:
movq mm5, mm3
psllq mm5, 56
psrlq mm5, 56
pxor mm2, mm5
- test r2, r2
+ test r2d, r2d
jnz .body
.fix_tr_1:
movq mm5, mm3
movq mm4, mm3
PALIGNR mm2, mm0, 7, mm0
PALIGNR mm1, mm4, 1, mm4
- test r1, r1
+ test r1d, r1d
jz .fix_lt_2
- test r2, r2
+ test r2d, r2d
jz .fix_tr_1
.body:
lea r1, [r0+r3*2]
sub r0, r3
lea r2, [r0+r3*2]
movq mm0, [r0+r3*1-8]
- test r1, r1
+ test r1d, r1d
lea r1, [r0+r3]
cmovnz r1, r0
punpckhbw mm0, [r1+r3*0-8]
movq mm4, mm3
PALIGNR mm2, mm0, 7, mm0
PALIGNR mm1, mm4, 1, mm4
- test r1, r1 ; top_left
+ test r1d, r1d ; top_left
jz .fix_lt_2
- test r2, r2 ; top_right
+ test r2d, r2d ; top_right
jz .fix_tr_1
jmp .body
.fix_lt_2:
psllq mm5, 56
psrlq mm5, 56
pxor mm2, mm5
- test r2, r2 ; top_right
+ test r2d, r2d ; top_right
jnz .body
.fix_tr_1:
movq mm5, mm3
movq mm4, mm3
PALIGNR mm2, mm0, 7, mm0
PALIGNR mm1, mm4, 1, mm4
- test r1, r1
+ test r1d, r1d
jz .fix_lt_2
- test r2, r2
+ test r2d, r2d
jz .fix_tr_1
jmp .do_top
.fix_lt_2:
psllq mm5, 56
psrlq mm5, 56
pxor mm2, mm5
- test r2, r2
+ test r2d, r2d
jnz .do_top
.fix_tr_1:
movq mm5, mm3
.do_top:
PRED4x4_LOWPASS mm4, mm2, mm1, mm3, mm5
movq mm7, mm4
- test r2, r2
+ test r2d, r2d
jz .fix_tr_2
movq mm0, [r0+8]
movq mm5, mm0
movq mm4, mm3
PALIGNR mm2, mm0, 7, mm0
PALIGNR mm1, mm4, 1, mm4
- test r1, r1 ; top_left
+ test r1d, r1d ; top_left
jz .fix_lt_2
- test r2, r2 ; top_right
+ test r2d, r2d ; top_right
jz .fix_tr_1
jmp .do_top
.fix_lt_2:
psllq mm5, 56
psrlq mm5, 56
pxor mm2, mm5
- test r2, r2 ; top_right
+ test r2d, r2d ; top_right
jnz .do_top
.fix_tr_1:
movq mm5, mm3
.do_top:
PRED4x4_LOWPASS mm4, mm2, mm1, mm3, mm5
movq2dq xmm3, mm4
- test r2, r2 ; top_right
+ test r2d, r2d ; top_right
jz .fix_tr_2
movq mm0, [r0+8]
movq mm5, mm0
movq mm2, mm3
PALIGNR mm4, mm0, 7, mm0
PALIGNR mm1, mm2, 1, mm2
- test r1, r1 ; top_left
+ test r1d, r1d ; top_left
jz .fix_lt_1
.do_left:
movq mm0, mm4
movq mm4, mm3
PALIGNR mm2, mm0, 7, mm0
PALIGNR mm1, mm4, 1, mm4
- test r1, r1 ; top_left
+ test r1d, r1d ; top_left
jz .fix_lt_2
- test r2, r2 ; top_right
+ test r2d, r2d ; top_right
jz .fix_tr_1
.do_top:
PRED4x4_LOWPASS mm4, mm2, mm1, mm3, mm5
psllq mm5, 56
psrlq mm5, 56
pxor mm2, mm5
- test r2, r2 ; top_right
+ test r2d, r2d ; top_right
jnz .do_top
.fix_tr_1:
movq mm5, mm3
movq mm2, mm3
PALIGNR mm4, mm0, 7, mm0
PALIGNR mm1, mm2, 1, mm2
- test r1, r1
+ test r1d, r1d
jz .fix_lt_1
jmp .do_left
.fix_lt_1:
psllq mm5, 56
psrlq mm5, 56
pxor mm2, mm5
- test r2, r2
+ test r2d, r2d
jnz .do_top
.fix_tr_1:
movq mm5, mm3
movq mm4, mm3
PALIGNR mm2, mm0, 7, mm0
PALIGNR mm1, mm4, 1, mm4
- test r1, r1
+ test r1d, r1d
jz .fix_lt_2
- test r2, r2
+ test r2d, r2d
jz .fix_tr_1
.do_top:
PRED4x4_LOWPASS mm4, mm2, mm1, mm3, mm5
movq mm2, mm3
PALIGNR mm4, mm0, 7, mm0
PALIGNR mm1, mm2, 1, mm2
- test r1, r1
+ test r1d, r1d
jz .fix_lt_1
jmp .do_left
.fix_lt_1:
psllq mm5, 56
psrlq mm5, 56
pxor mm2, mm5
- test r2, r2
+ test r2d, r2d
jnz .do_top
.fix_tr_1:
movq mm5, mm3
movq mm4, mm3
PALIGNR mm2, mm0, 7, mm0
PALIGNR mm1, mm4, 1, mm4
- test r1, r1
+ test r1d, r1d
jz .fix_lt_2
- test r2, r2
+ test r2d, r2d
jz .fix_tr_1
.do_top:
PRED4x4_LOWPASS mm6, mm2, mm1, mm3, mm5
movq mm2, mm3
PALIGNR mm4, mm0, 7, mm0
PALIGNR mm1, mm2, 1, mm2
- test r1, r1
+ test r1d, r1d
jnz .do_left
.fix_lt_1:
movq mm5, mm3
psllq mm5, 56
psrlq mm5, 56
pxor mm2, mm5
- test r2, r2
+ test r2d, r2d
jnz .do_top
.fix_tr_1:
movq mm5, mm3
movq mm4, mm3
PALIGNR mm2, mm0, 7, mm0
PALIGNR mm1, mm4, 1, mm4
- test r1, r1
+ test r1d, r1d
jz .fix_lt_2
- test r2, r2
+ test r2d, r2d
jz .fix_tr_1
.do_top:
PRED4x4_LOWPASS mm6, mm2, mm1, mm3, mm5
movq mm4, mm3
PALIGNR mm2, mm0, 7, mm0
PALIGNR mm1, mm4, 1, mm4
- test r1, r1
+ test r1d, r1d
jz .fix_lt_2
- test r2, r2
+ test r2d, r2d
jz .fix_tr_1
jmp .do_top
.fix_lt_2:
psllq mm5, 56
psrlq mm5, 56
pxor mm2, mm5
- test r2, r2
+ test r2d, r2d
jnz .do_top
.fix_tr_1:
movq mm5, mm3
.do_top:
PRED4x4_LOWPASS mm4, mm2, mm1, mm3, mm5
movq2dq xmm4, mm4
- test r2, r2
+ test r2d, r2d
jz .fix_tr_2
movq mm0, [r0+8]
movq mm5, mm0
sub r0, r3
lea r2, [r0+r3*2]
movq mm0, [r0+r3*1-8]
- test r1, r1
+ test r1d, r1d
lea r1, [r0+r3]
cmovnz r1, r0
punpckhbw mm0, [r1+r3*0-8]
movq mm2, mm3
PALIGNR mm4, mm0, 7, mm0
PALIGNR mm1, mm2, 1, mm2
- test r1, r1
+ test r1d, r1d
jnz .do_left
.fix_lt_1:
movq mm5, mm3
psllq mm5, 56
psrlq mm5, 56
pxor mm2, mm5
- test r2, r2
+ test r2d, r2d
jnz .do_top
.fix_tr_1:
movq mm5, mm3
movq mm4, mm3
PALIGNR mm2, mm0, 7, mm0
PALIGNR mm1, mm4, 1, mm4
- test r1, r1
+ test r1d, r1d
jz .fix_lt_2
- test r2, r2
+ test r2d, r2d
jz .fix_tr_1
.do_top:
PRED4x4_LOWPASS mm4, mm2, mm1, mm3, mm5
movq mm2, mm3
PALIGNR mm4, mm0, 7, mm0
PALIGNR mm1, mm2, 1, mm2
- test r1, r1
+ test r1d, r1d
jnz .do_left
.fix_lt_1:
movq mm5, mm3
psllq mm5, 56
psrlq mm5, 56
pxor mm2, mm5
- test r2, r2
+ test r2d, r2d
jnz .do_top
.fix_tr_1:
movq mm5, mm3
movq mm4, mm3
PALIGNR mm2, mm0, 7, mm0
PALIGNR mm1, mm4, 1, mm4
- test r1, r1
+ test r1d, r1d
jz .fix_lt_2
- test r2, r2
+ test r2d, r2d
jz .fix_tr_1
.do_top:
PRED4x4_LOWPASS mm4, mm2, mm1, mm3, mm5
movq2dq xmm1, mm4
- test r2, r2
+ test r2d, r2d
jz .fix_tr_2
movq mm0, [r0+8]
movq mm5, mm0
paddd m0, m3
paddd m1, m3
%endif
- packusdw m0, m1
+ packssdw m0, m1
%if %2 == 8
packuswb m0, m0
%else
pminsw m0, [max_pixels_%2]
+ pmaxsw m0, [zero]
%endif
PEL_%2STORE%1 dstq, m0, m1
add dstq, dststrideq ; dst += dststride
psrad m0, m5
psrad m1, m5
%endif
- packusdw m0, m1
+ packssdw m0, m1
%if %2 == 8
packuswb m0, m0
%else
pminsw m0, [max_pixels_%2]
+ pmaxsw m0, [zero]
%endif
PEL_%2STORE%1 dstq, m0, m1
add dstq, dststrideq ; dst += dststride
static void DEF(avg, pixels16_x2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
{
MOVQ_BFE(mm6);
- JUMPALIGN();
- do {
__asm__ volatile(
- "movq %1, %%mm0 \n\t"
- "movq 1%1, %%mm1 \n\t"
- "movq %0, %%mm3 \n\t"
+ ".p2align 3 \n\t"
+ "1: \n\t"
+ "movq (%1), %%mm0 \n\t"
+ "movq 1(%1), %%mm1 \n\t"
+ "movq (%2), %%mm3 \n\t"
PAVGB(%%mm0, %%mm1, %%mm2, %%mm6)
PAVGB_MMX(%%mm3, %%mm2, %%mm0, %%mm6)
- "movq %%mm0, %0 \n\t"
- "movq 8%1, %%mm0 \n\t"
- "movq 9%1, %%mm1 \n\t"
- "movq 8%0, %%mm3 \n\t"
+ "movq %%mm0, (%2) \n\t"
+ "movq 8(%1), %%mm0 \n\t"
+ "movq 9(%1), %%mm1 \n\t"
+ "movq 8(%2), %%mm3 \n\t"
PAVGB(%%mm0, %%mm1, %%mm2, %%mm6)
PAVGB_MMX(%%mm3, %%mm2, %%mm0, %%mm6)
- "movq %%mm0, 8%0 \n\t"
- :"+m"(*block)
- :"m"(*pixels)
+ "movq %%mm0, 8(%2) \n\t"
+ "add %3, %1 \n\t"
+ "add %3, %2 \n\t"
+ "subl $1, %0 \n\t"
+ "jnz 1b \n\t"
+ :"+g"(h), "+S"(pixels), "+D"(block)
+ :"r"((x86_reg)line_size)
:"memory");
- pixels += line_size;
- block += line_size;
- } while (--h);
}
static void DEF(avg, pixels8_y2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
;--------------------------------------------------------------------------
;void ff_put_signed_pixels_clamped(const int16_t *block, uint8_t *pixels,
-; int line_size)
+; ptrdiff_t line_size)
;--------------------------------------------------------------------------
%macro PUT_SIGNED_PIXELS_CLAMPED_HALF 1
PUT_SIGNED_PIXELS_CLAMPED 0
INIT_XMM sse2
PUT_SIGNED_PIXELS_CLAMPED 3
+
+;--------------------------------------------------------------------------
+; void ff_put_pixels_clamped(const int16_t *block, uint8_t *pixels,
+; ptrdiff_t line_size);
+;--------------------------------------------------------------------------
+; %1 = block offset
+%macro PUT_PIXELS_CLAMPED_HALF 1
+ mova m0, [blockq+mmsize*0+%1]
+ mova m1, [blockq+mmsize*2+%1]
+%if mmsize == 8
+ mova m2, [blockq+mmsize*4+%1]
+ mova m3, [blockq+mmsize*6+%1]
+%endif
+ packuswb m0, [blockq+mmsize*1+%1]
+ packuswb m1, [blockq+mmsize*3+%1]
+%if mmsize == 8
+ packuswb m2, [blockq+mmsize*5+%1]
+ packuswb m3, [blockq+mmsize*7+%1]
+ movq [pixelsq], m0
+ movq [lsizeq+pixelsq], m1
+ movq [2*lsizeq+pixelsq], m2
+ movq [lsize3q+pixelsq], m3
+%else
+ movq [pixelsq], m0
+ movhps [lsizeq+pixelsq], m0
+ movq [2*lsizeq+pixelsq], m1
+ movhps [lsize3q+pixelsq], m1
+%endif
+%endmacro
+
+%macro PUT_PIXELS_CLAMPED 0
+cglobal put_pixels_clamped, 3, 4, 2, block, pixels, lsize, lsize3
+ lea lsize3q, [lsizeq*3]
+ PUT_PIXELS_CLAMPED_HALF 0
+ lea pixelsq, [pixelsq+lsizeq*4]
+ PUT_PIXELS_CLAMPED_HALF 64
+ RET
+%endmacro
+
+INIT_MMX mmx
+PUT_PIXELS_CLAMPED
+INIT_XMM sse2
+PUT_PIXELS_CLAMPED
+
+;--------------------------------------------------------------------------
+; void ff_add_pixels_clamped(const int16_t *block, uint8_t *pixels,
+; ptrdiff_t line_size);
+;--------------------------------------------------------------------------
+; %1 = block offset
+%macro ADD_PIXELS_CLAMPED 1
+ mova m0, [blockq+mmsize*0+%1]
+ mova m1, [blockq+mmsize*1+%1]
+%if mmsize == 8
+ mova m5, [blockq+mmsize*2+%1]
+ mova m6, [blockq+mmsize*3+%1]
+%endif
+ movq m2, [pixelsq]
+ movq m3, [pixelsq+lsizeq]
+%if mmsize == 8
+ mova m7, m2
+ punpcklbw m2, m4
+ punpckhbw m7, m4
+ paddsw m0, m2
+ paddsw m1, m7
+ mova m7, m3
+ punpcklbw m3, m4
+ punpckhbw m7, m4
+ paddsw m5, m3
+ paddsw m6, m7
+%else
+ punpcklbw m2, m4
+ punpcklbw m3, m4
+ paddsw m0, m2
+ paddsw m1, m3
+%endif
+ packuswb m0, m1
+%if mmsize == 8
+ packuswb m5, m6
+ movq [pixelsq], m0
+ movq [pixelsq+lsizeq], m5
+%else
+ movq [pixelsq], m0
+ movhps [pixelsq+lsizeq], m0
+%endif
+%endmacro
+
+%macro ADD_PIXELS_CLAMPED 0
+cglobal add_pixels_clamped, 3, 3, 5, block, pixels, lsize
+ pxor m4, m4
+ ADD_PIXELS_CLAMPED 0
+ lea pixelsq, [pixelsq+lsizeq*2]
+ ADD_PIXELS_CLAMPED 32
+ lea pixelsq, [pixelsq+lsizeq*2]
+ ADD_PIXELS_CLAMPED 64
+ lea pixelsq, [pixelsq+lsizeq*2]
+ ADD_PIXELS_CLAMPED 96
+ RET
+%endmacro
+
+INIT_MMX mmx
+ADD_PIXELS_CLAMPED
+INIT_XMM sse2
+ADD_PIXELS_CLAMPED
#define AVCODEC_X86_IDCTDSP_H
#include <stdint.h>
+#include <stddef.h>
void ff_add_pixels_clamped_mmx(const int16_t *block, uint8_t *pixels,
- int line_size);
+ ptrdiff_t line_size);
+void ff_add_pixels_clamped_sse2(const int16_t *block, uint8_t *pixels,
+ ptrdiff_t line_size);
void ff_put_pixels_clamped_mmx(const int16_t *block, uint8_t *pixels,
- int line_size);
+ ptrdiff_t line_size);
+void ff_put_pixels_clamped_sse2(const int16_t *block, uint8_t *pixels,
+ ptrdiff_t line_size);
void ff_put_signed_pixels_clamped_mmx(const int16_t *block, uint8_t *pixels,
- int line_size);
+ ptrdiff_t line_size);
void ff_put_signed_pixels_clamped_sse2(const int16_t *block, uint8_t *pixels,
- int line_size);
+ ptrdiff_t line_size);
#endif /* AVCODEC_X86_IDCTDSP_H */
int cpu_flags = av_get_cpu_flags();
if (INLINE_MMX(cpu_flags)) {
- c->put_pixels_clamped = ff_put_pixels_clamped_mmx;
- c->add_pixels_clamped = ff_add_pixels_clamped_mmx;
-
if (!high_bit_depth &&
avctx->lowres == 0 &&
(avctx->idct_algo == FF_IDCT_AUTO ||
}
if (EXTERNAL_MMX(cpu_flags)) {
c->put_signed_pixels_clamped = ff_put_signed_pixels_clamped_mmx;
+ c->put_pixels_clamped = ff_put_pixels_clamped_mmx;
+ c->add_pixels_clamped = ff_add_pixels_clamped_mmx;
}
if (EXTERNAL_SSE2(cpu_flags)) {
c->put_signed_pixels_clamped = ff_put_signed_pixels_clamped_sse2;
+ c->put_pixels_clamped = ff_put_pixels_clamped_sse2;
+ c->add_pixels_clamped = ff_add_pixels_clamped_sse2;
}
}
+++ /dev/null
-/*
- * SIMD-optimized IDCT-related routines
- * Copyright (c) 2000, 2001 Fabrice Bellard
- * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
- *
- * MMX optimization by Nick Kurshev <nickols_k@mail.ru>
- *
- * 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/cpu.h"
-#include "libavutil/x86/asm.h"
-#include "idctdsp.h"
-#include "inline_asm.h"
-
-#if HAVE_INLINE_ASM
-
-void ff_put_pixels_clamped_mmx(const int16_t *block, uint8_t *pixels,
- int line_size)
-{
- const int16_t *p;
- uint8_t *pix;
-
- /* read the pixels */
- p = block;
- pix = pixels;
- /* unrolled loop */
- __asm__ volatile (
- "movq (%3), %%mm0 \n\t"
- "movq 8(%3), %%mm1 \n\t"
- "movq 16(%3), %%mm2 \n\t"
- "movq 24(%3), %%mm3 \n\t"
- "movq 32(%3), %%mm4 \n\t"
- "movq 40(%3), %%mm5 \n\t"
- "movq 48(%3), %%mm6 \n\t"
- "movq 56(%3), %%mm7 \n\t"
- "packuswb %%mm1, %%mm0 \n\t"
- "packuswb %%mm3, %%mm2 \n\t"
- "packuswb %%mm5, %%mm4 \n\t"
- "packuswb %%mm7, %%mm6 \n\t"
- "movq %%mm0, (%0) \n\t"
- "movq %%mm2, (%0, %1) \n\t"
- "movq %%mm4, (%0, %1, 2) \n\t"
- "movq %%mm6, (%0, %2) \n\t"
- :: "r" (pix), "r" ((x86_reg) line_size), "r" ((x86_reg) line_size * 3),
- "r" (p)
- : "memory");
- pix += line_size * 4;
- p += 32;
-
- // if here would be an exact copy of the code above
- // compiler would generate some very strange code
- // thus using "r"
- __asm__ volatile (
- "movq (%3), %%mm0 \n\t"
- "movq 8(%3), %%mm1 \n\t"
- "movq 16(%3), %%mm2 \n\t"
- "movq 24(%3), %%mm3 \n\t"
- "movq 32(%3), %%mm4 \n\t"
- "movq 40(%3), %%mm5 \n\t"
- "movq 48(%3), %%mm6 \n\t"
- "movq 56(%3), %%mm7 \n\t"
- "packuswb %%mm1, %%mm0 \n\t"
- "packuswb %%mm3, %%mm2 \n\t"
- "packuswb %%mm5, %%mm4 \n\t"
- "packuswb %%mm7, %%mm6 \n\t"
- "movq %%mm0, (%0) \n\t"
- "movq %%mm2, (%0, %1) \n\t"
- "movq %%mm4, (%0, %1, 2) \n\t"
- "movq %%mm6, (%0, %2) \n\t"
- :: "r" (pix), "r" ((x86_reg) line_size), "r" ((x86_reg) line_size * 3),
- "r" (p)
- : "memory");
-}
-
-void ff_add_pixels_clamped_mmx(const int16_t *block, uint8_t *pixels,
- int line_size)
-{
- const int16_t *p;
- uint8_t *pix;
- int i;
-
- /* read the pixels */
- p = block;
- pix = pixels;
- MOVQ_ZERO(mm7);
- i = 4;
- do {
- __asm__ volatile (
- "movq (%2), %%mm0 \n\t"
- "movq 8(%2), %%mm1 \n\t"
- "movq 16(%2), %%mm2 \n\t"
- "movq 24(%2), %%mm3 \n\t"
- "movq %0, %%mm4 \n\t"
- "movq %1, %%mm6 \n\t"
- "movq %%mm4, %%mm5 \n\t"
- "punpcklbw %%mm7, %%mm4 \n\t"
- "punpckhbw %%mm7, %%mm5 \n\t"
- "paddsw %%mm4, %%mm0 \n\t"
- "paddsw %%mm5, %%mm1 \n\t"
- "movq %%mm6, %%mm5 \n\t"
- "punpcklbw %%mm7, %%mm6 \n\t"
- "punpckhbw %%mm7, %%mm5 \n\t"
- "paddsw %%mm6, %%mm2 \n\t"
- "paddsw %%mm5, %%mm3 \n\t"
- "packuswb %%mm1, %%mm0 \n\t"
- "packuswb %%mm3, %%mm2 \n\t"
- "movq %%mm0, %0 \n\t"
- "movq %%mm2, %1 \n\t"
- : "+m" (*pix), "+m" (*(pix + line_size))
- : "r" (p)
- : "memory");
- pix += line_size * 2;
- p += 16;
- } while (--i);
-}
-
-#endif /* HAVE_INLINE_ASM */
; int ff_scalarproduct_and_madd_int16(int16_t *v1, int16_t *v2, int16_t *v3,
; int order, int mul)
cglobal scalarproduct_and_madd_int16, 4,4,8, v1, v2, v3, order, mul
+%if mmsize == 16
+ test orderq, 8
+ jnz scalarproduct_and_madd_int16_fallback
+%else
+ scalarproduct_and_madd_int16_fallback
+%endif
shl orderq, 1
movd m7, mulm
%if mmsize == 16
; int order, int mul)
INIT_XMM ssse3
cglobal scalarproduct_and_madd_int16, 4,5,10, v1, v2, v3, order, mul
+ test orderq, 8
+ jnz scalarproduct_and_madd_int16_fallback
shl orderq, 1
movd m7, mulm
pshuflw m7, m7, 0
%include "libavutil/x86/x86util.asm"
+SECTION_RODATA
+
+cextern pb_1
+cextern pb_80
+
SECTION .text
%macro DIFF_PIXELS_1 4
%elif cpuflag(mmx)
ALIGN 16
; int ff_hadamard8_diff_ ## cpu(MpegEncContext *s, uint8_t *src1,
-; uint8_t *src2, int stride, int h)
+; uint8_t *src2, ptrdiff_t stride, int h)
; r0 = void *s = unused, int h = unused (always 8)
; note how r1, r2 and r3 are not clobbered in this function, so 16x16
; can simply call this 2x2x (and that's why we access rsp+gprsize
HADAMARD8_DIFF 9
; int ff_sse*_*(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
-; int line_size, int h)
+; ptrdiff_t line_size, int h)
%macro SUM_SQUARED_ERRORS 1
cglobal sse%1, 5,5,8, v, pix1, pix2, lsize, h
SUM_ABS_DCTELEM 6, 2
;------------------------------------------------------------------------------
-; int ff_hf_noise*_mmx(uint8_t *pix1, int lsize, int h)
+; int ff_hf_noise*_mmx(uint8_t *pix1, ptrdiff_t lsize, int h)
;------------------------------------------------------------------------------
; %1 = 8/16. %2-5=m#
%macro HF_NOISE_PART1 5
; %1 = 8/16
%macro HF_NOISE 1
cglobal hf_noise%1, 3,3,0, pix1, lsize, h
- movsxdifnidn lsizeq, lsized
sub hd, 2
pxor m7, m7
pxor m6, m6
INIT_MMX mmx
HF_NOISE 8
HF_NOISE 16
+
+;---------------------------------------------------------------------------------------
+;int ff_sad_<opt>(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, ptrdiff_t stride, int h);
+;---------------------------------------------------------------------------------------
+;%1 = 8/16
+%macro SAD 1
+cglobal sad%1, 5, 5, 3, v, pix1, pix2, stride, h
+ movu m2, [pix2q]
+ movu m1, [pix2q+strideq]
+ psadbw m2, [pix1q]
+ psadbw m1, [pix1q+strideq]
+ paddw m2, m1
+%if %1 != mmsize
+ movu m0, [pix2q+8]
+ movu m1, [pix2q+strideq+8]
+ psadbw m0, [pix1q+8]
+ psadbw m1, [pix1q+strideq+8]
+ paddw m2, m0
+ paddw m2, m1
+%endif
+ sub hd, 2
+
+align 16
+.loop:
+ lea pix1q, [pix1q+strideq*2]
+ lea pix2q, [pix2q+strideq*2]
+ movu m0, [pix2q]
+ movu m1, [pix2q+strideq]
+ psadbw m0, [pix1q]
+ psadbw m1, [pix1q+strideq]
+ paddw m2, m0
+ paddw m2, m1
+%if %1 != mmsize
+ movu m0, [pix2q+8]
+ movu m1, [pix2q+strideq+8]
+ psadbw m0, [pix1q+8]
+ psadbw m1, [pix1q+strideq+8]
+ paddw m2, m0
+ paddw m2, m1
+%endif
+ sub hd, 2
+ jg .loop
+%if mmsize == 16
+ movhlps m0, m2
+ paddw m2, m0
+%endif
+ movd eax, m2
+ RET
+%endmacro
+
+INIT_MMX mmxext
+SAD 8
+SAD 16
+INIT_XMM sse2
+SAD 16
+
+;------------------------------------------------------------------------------------------
+;int ff_sad_x2_<opt>(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, ptrdiff_t stride, int h);
+;------------------------------------------------------------------------------------------
+;%1 = 8/16
+%macro SAD_X2 1
+cglobal sad%1_x2, 5, 5, 5, v, pix1, pix2, stride, h
+ movu m0, [pix2q]
+ movu m2, [pix2q+strideq]
+%if mmsize == 16
+ movu m3, [pix2q+1]
+ movu m4, [pix2q+strideq+1]
+ pavgb m0, m3
+ pavgb m2, m4
+%else
+ pavgb m0, [pix2q+1]
+ pavgb m2, [pix2q+strideq+1]
+%endif
+ psadbw m0, [pix1q]
+ psadbw m2, [pix1q+strideq]
+ paddw m0, m2
+%if %1 != mmsize
+ movu m1, [pix2q+8]
+ movu m2, [pix2q+strideq+8]
+ pavgb m1, [pix2q+9]
+ pavgb m2, [pix2q+strideq+9]
+ psadbw m1, [pix1q+8]
+ psadbw m2, [pix1q+strideq+8]
+ paddw m0, m1
+ paddw m0, m2
+%endif
+ sub hd, 2
+
+align 16
+.loop:
+ lea pix1q, [pix1q+2*strideq]
+ lea pix2q, [pix2q+2*strideq]
+ movu m1, [pix2q]
+ movu m2, [pix2q+strideq]
+%if mmsize == 16
+ movu m3, [pix2q+1]
+ movu m4, [pix2q+strideq+1]
+ pavgb m1, m3
+ pavgb m2, m4
+%else
+ pavgb m1, [pix2q+1]
+ pavgb m2, [pix2q+strideq+1]
+%endif
+ psadbw m1, [pix1q]
+ psadbw m2, [pix1q+strideq]
+ paddw m0, m1
+ paddw m0, m2
+%if %1 != mmsize
+ movu m1, [pix2q+8]
+ movu m2, [pix2q+strideq+8]
+ pavgb m1, [pix2q+9]
+ pavgb m2, [pix2q+strideq+9]
+ psadbw m1, [pix1q+8]
+ psadbw m2, [pix1q+strideq+8]
+ paddw m0, m1
+ paddw m0, m2
+%endif
+ sub hd, 2
+ jg .loop
+%if mmsize == 16
+ movhlps m1, m0
+ paddw m0, m1
+%endif
+ movd eax, m0
+ RET
+%endmacro
+
+INIT_MMX mmxext
+SAD_X2 8
+SAD_X2 16
+INIT_XMM sse2
+SAD_X2 16
+
+;------------------------------------------------------------------------------------------
+;int ff_sad_y2_<opt>(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, ptrdiff_t stride, int h);
+;------------------------------------------------------------------------------------------
+;%1 = 8/16
+%macro SAD_Y2 1
+cglobal sad%1_y2, 5, 5, 4, v, pix1, pix2, stride, h
+ movu m1, [pix2q]
+ movu m0, [pix2q+strideq]
+ movu m3, [pix2q+2*strideq]
+ pavgb m1, m0
+ pavgb m0, m3
+ psadbw m1, [pix1q]
+ psadbw m0, [pix1q+strideq]
+ paddw m0, m1
+ mova m1, m3
+%if %1 != mmsize
+ movu m4, [pix2q+8]
+ movu m5, [pix2q+strideq+8]
+ movu m6, [pix2q+2*strideq+8]
+ pavgb m4, m5
+ pavgb m5, m6
+ psadbw m4, [pix1q+8]
+ psadbw m5, [pix1q+strideq+8]
+ paddw m0, m4
+ paddw m0, m5
+ mova m4, m6
+%endif
+ add pix2q, strideq
+ sub hd, 2
+
+align 16
+.loop:
+ lea pix1q, [pix1q+2*strideq]
+ lea pix2q, [pix2q+2*strideq]
+ movu m2, [pix2q]
+ movu m3, [pix2q+strideq]
+ pavgb m1, m2
+ pavgb m2, m3
+ psadbw m1, [pix1q]
+ psadbw m2, [pix1q+strideq]
+ paddw m0, m1
+ paddw m0, m2
+ mova m1, m3
+%if %1 != mmsize
+ movu m5, [pix2q+8]
+ movu m6, [pix2q+strideq+8]
+ pavgb m4, m5
+ pavgb m5, m6
+ psadbw m4, [pix1q+8]
+ psadbw m5, [pix1q+strideq+8]
+ paddw m0, m4
+ paddw m0, m5
+ mova m4, m6
+%endif
+ sub hd, 2
+ jg .loop
+%if mmsize == 16
+ movhlps m1, m0
+ paddw m0, m1
+%endif
+ movd eax, m0
+ RET
+%endmacro
+
+INIT_MMX mmxext
+SAD_Y2 8
+SAD_Y2 16
+INIT_XMM sse2
+SAD_Y2 16
+
+;-------------------------------------------------------------------------------------------
+;int ff_sad_approx_xy2_<opt>(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, ptrdiff_t stride, int h);
+;-------------------------------------------------------------------------------------------
+;%1 = 8/16
+%macro SAD_APPROX_XY2 1
+cglobal sad%1_approx_xy2, 5, 5, 7, v, pix1, pix2, stride, h
+ mova m4, [pb_1]
+ movu m1, [pix2q]
+ movu m0, [pix2q+strideq]
+ movu m3, [pix2q+2*strideq]
+%if mmsize == 16
+ movu m5, [pix2q+1]
+ movu m6, [pix2q+strideq+1]
+ movu m2, [pix2q+2*strideq+1]
+ pavgb m1, m5
+ pavgb m0, m6
+ pavgb m3, m2
+%else
+ pavgb m1, [pix2q+1]
+ pavgb m0, [pix2q+strideq+1]
+ pavgb m3, [pix2q+2*strideq+1]
+%endif
+ psubusb m0, m4
+ pavgb m1, m0
+ pavgb m0, m3
+ psadbw m1, [pix1q]
+ psadbw m0, [pix1q+strideq]
+ paddw m0, m1
+ mova m1, m3
+%if %1 != mmsize
+ movu m5, [pix2q+8]
+ movu m6, [pix2q+strideq+8]
+ movu m7, [pix2q+2*strideq+8]
+ pavgb m5, [pix2q+1+8]
+ pavgb m6, [pix2q+strideq+1+8]
+ pavgb m7, [pix2q+2*strideq+1+8]
+ psubusb m6, m4
+ pavgb m5, m6
+ pavgb m6, m7
+ psadbw m5, [pix1q+8]
+ psadbw m6, [pix1q+strideq+8]
+ paddw m0, m5
+ paddw m0, m6
+ mova m5, m7
+%endif
+ add pix2q, strideq
+ sub hd, 2
+
+align 16
+.loop:
+ lea pix1q, [pix1q+2*strideq]
+ lea pix2q, [pix2q+2*strideq]
+ movu m2, [pix2q]
+ movu m3, [pix2q+strideq]
+%if mmsize == 16
+ movu m5, [pix2q+1]
+ movu m6, [pix2q+strideq+1]
+ pavgb m2, m5
+ pavgb m3, m6
+%else
+ pavgb m2, [pix2q+1]
+ pavgb m3, [pix2q+strideq+1]
+%endif
+ psubusb m2, m4
+ pavgb m1, m2
+ pavgb m2, m3
+ psadbw m1, [pix1q]
+ psadbw m2, [pix1q+strideq]
+ paddw m0, m1
+ paddw m0, m2
+ mova m1, m3
+%if %1 != mmsize
+ movu m6, [pix2q+8]
+ movu m7, [pix2q+strideq+8]
+ pavgb m6, [pix2q+8+1]
+ pavgb m7, [pix2q+strideq+8+1]
+ psubusb m6, m4
+ pavgb m5, m6
+ pavgb m6, m7
+ psadbw m5, [pix1q+8]
+ psadbw m6, [pix1q+strideq+8]
+ paddw m0, m5
+ paddw m0, m6
+ mova m5, m7
+%endif
+ sub hd, 2
+ jg .loop
+%if mmsize == 16
+ movhlps m1, m0
+ paddw m0, m1
+%endif
+ movd eax, m0
+ RET
+%endmacro
+
+INIT_MMX mmxext
+SAD_APPROX_XY2 8
+SAD_APPROX_XY2 16
+INIT_XMM sse2
+SAD_APPROX_XY2 16
+
+;--------------------------------------------------------------------
+;int ff_vsad_intra(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
+; ptrdiff_t line_size, int h);
+;--------------------------------------------------------------------
+; %1 = 8/16
+%macro VSAD_INTRA 1
+cglobal vsad_intra%1, 5, 5, 3, v, pix1, pix2, lsize, h
+ mova m0, [pix1q]
+%if %1 == mmsize
+ mova m2, [pix1q+lsizeq]
+ psadbw m0, m2
+%else
+ mova m2, [pix1q+lsizeq]
+ mova m3, [pix1q+8]
+ mova m4, [pix1q+lsizeq+8]
+ psadbw m0, m2
+ psadbw m3, m4
+ paddw m0, m3
+%endif
+ sub hd, 2
+
+.loop
+ lea pix1q, [pix1q + 2*lsizeq]
+%if %1 == mmsize
+ mova m1, [pix1q]
+ psadbw m2, m1
+ paddw m0, m2
+ mova m2, [pix1q+lsizeq]
+ psadbw m1, m2
+ paddw m0, m1
+%else
+ mova m1, [pix1q]
+ mova m3, [pix1q+8]
+ psadbw m2, m1
+ psadbw m4, m3
+ paddw m0, m2
+ paddw m0, m4
+ mova m2, [pix1q+lsizeq]
+ mova m4, [pix1q+lsizeq+8]
+ psadbw m1, m2
+ psadbw m3, m4
+ paddw m0, m1
+ paddw m0, m3
+%endif
+ sub hd, 2
+ jg .loop
+
+%if mmsize == 16
+ pshufd m1, m0, 0xe
+ paddd m0, m1
+%endif
+ movd eax, m0
+ RET
+%endmacro
+
+INIT_MMX mmxext
+VSAD_INTRA 8
+VSAD_INTRA 16
+INIT_XMM sse2
+VSAD_INTRA 16
+
+;---------------------------------------------------------------------
+;int ff_vsad_approx(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
+; ptrdiff_t line_size, int h);
+;---------------------------------------------------------------------
+; %1 = 8/16
+%macro VSAD_APPROX 1
+cglobal vsad%1_approx, 5, 5, 5, v, pix1, pix2, lsize, h
+ mova m1, [pb_80]
+ mova m0, [pix1q]
+%if %1 == mmsize ; vsad8_mmxext, vsad16_sse2
+ mova m4, [pix1q+lsizeq]
+%if mmsize == 16
+ movu m3, [pix2q]
+ movu m2, [pix2q+lsizeq]
+ psubb m0, m3
+ psubb m4, m2
+%else
+ psubb m0, [pix2q]
+ psubb m4, [pix2q+lsizeq]
+%endif
+ pxor m0, m1
+ pxor m4, m1
+ psadbw m0, m4
+%else ; vsad16_mmxext
+ mova m3, [pix1q+8]
+ psubb m0, [pix2q]
+ psubb m3, [pix2q+8]
+ pxor m0, m1
+ pxor m3, m1
+ mova m4, [pix1q+lsizeq]
+ mova m5, [pix1q+lsizeq+8]
+ psubb m4, [pix2q+lsizeq]
+ psubb m5, [pix2q+lsizeq+8]
+ pxor m4, m1
+ pxor m5, m1
+ psadbw m0, m4
+ psadbw m3, m5
+ paddw m0, m3
+%endif
+ sub hd, 2
+
+.loop
+ lea pix1q, [pix1q + 2*lsizeq]
+ lea pix2q, [pix2q + 2*lsizeq]
+ mova m2, [pix1q]
+%if %1 == mmsize ; vsad8_mmxext, vsad16_sse2
+%if mmsize == 16
+ movu m3, [pix2q]
+ psubb m2, m3
+%else
+ psubb m2, [pix2q]
+%endif
+ pxor m2, m1
+ psadbw m4, m2
+ paddw m0, m4
+ mova m4, [pix1q+lsizeq]
+ movu m3, [pix2q+lsizeq]
+ psubb m4, m3
+ pxor m4, m1
+ psadbw m2, m4
+ paddw m0, m2
+%else ; vsad16_mmxext
+ mova m3, [pix1q+8]
+ psubb m2, [pix2q]
+ psubb m3, [pix2q+8]
+ pxor m2, m1
+ pxor m3, m1
+ psadbw m4, m2
+ psadbw m5, m3
+ paddw m0, m4
+ paddw m0, m5
+ mova m4, [pix1q+lsizeq]
+ mova m5, [pix1q+lsizeq+8]
+ psubb m4, [pix2q+lsizeq]
+ psubb m5, [pix2q+lsizeq+8]
+ pxor m4, m1
+ pxor m5, m1
+ psadbw m2, m4
+ psadbw m3, m5
+ paddw m0, m2
+ paddw m0, m3
+%endif
+ sub hd, 2
+ jg .loop
+
+%if mmsize == 16
+ pshufd m1, m0, 0xe
+ paddd m0, m1
+%endif
+ movd eax, m0
+ RET
+%endmacro
+
+INIT_MMX mmxext
+VSAD_APPROX 8
+VSAD_APPROX 16
+INIT_XMM sse2
+VSAD_APPROX 16
int ff_sum_abs_dctelem_sse2(int16_t *block);
int ff_sum_abs_dctelem_ssse3(int16_t *block);
int ff_sse8_mmx(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
- int line_size, int h);
+ ptrdiff_t stride, int h);
int ff_sse16_mmx(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
- int line_size, int h);
+ ptrdiff_t stride, int h);
int ff_sse16_sse2(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
- int line_size, int h);
-int ff_hf_noise8_mmx(uint8_t *pix1, int lsize, int h);
-int ff_hf_noise16_mmx(uint8_t *pix1, int lsize, int h);
-
-#define hadamard_func(cpu) \
- int ff_hadamard8_diff_ ## cpu(MpegEncContext *s, uint8_t *src1, \
- uint8_t *src2, int stride, int h); \
- int ff_hadamard8_diff16_ ## cpu(MpegEncContext *s, uint8_t *src1, \
- uint8_t *src2, int stride, int h);
+ ptrdiff_t stride, int h);
+int ff_hf_noise8_mmx(uint8_t *pix1, ptrdiff_t stride, int h);
+int ff_hf_noise16_mmx(uint8_t *pix1, ptrdiff_t stride, int h);
+int ff_sad8_mmxext(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
+ ptrdiff_t stride, int h);
+int ff_sad16_mmxext(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
+ ptrdiff_t stride, int h);
+int ff_sad16_sse2(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
+ ptrdiff_t stride, int h);
+int ff_sad8_x2_mmxext(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
+ ptrdiff_t stride, int h);
+int ff_sad16_x2_mmxext(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
+ ptrdiff_t stride, int h);
+int ff_sad16_x2_sse2(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
+ ptrdiff_t stride, int h);
+int ff_sad8_y2_mmxext(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
+ ptrdiff_t stride, int h);
+int ff_sad16_y2_mmxext(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
+ ptrdiff_t stride, int h);
+int ff_sad16_y2_sse2(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
+ ptrdiff_t stride, int h);
+int ff_sad8_approx_xy2_mmxext(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
+ ptrdiff_t stride, int h);
+int ff_sad16_approx_xy2_mmxext(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
+ ptrdiff_t stride, int h);
+int ff_sad16_approx_xy2_sse2(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
+ ptrdiff_t stride, int h);
+int ff_vsad_intra8_mmxext(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
+ ptrdiff_t stride, int h);
+int ff_vsad_intra16_mmxext(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
+ ptrdiff_t stride, int h);
+int ff_vsad_intra16_sse2(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
+ ptrdiff_t stride, int h);
+int ff_vsad8_approx_mmxext(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
+ ptrdiff_t stride, int h);
+int ff_vsad16_approx_mmxext(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
+ ptrdiff_t stride, int h);
+int ff_vsad16_approx_sse2(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
+ ptrdiff_t stride, int h);
+
+#define hadamard_func(cpu) \
+ int ff_hadamard8_diff_ ## cpu(MpegEncContext *s, uint8_t *src1, \
+ uint8_t *src2, ptrdiff_t stride, int h); \
+ int ff_hadamard8_diff16_ ## cpu(MpegEncContext *s, uint8_t *src1, \
+ uint8_t *src2, ptrdiff_t stride, int h);
hadamard_func(mmx)
hadamard_func(mmxext)
#if HAVE_YASM
static int nsse16_mmx(MpegEncContext *c, uint8_t *pix1, uint8_t *pix2,
- int line_size, int h)
+ ptrdiff_t stride, int h)
{
int score1, score2;
if (c)
- score1 = c->mecc.sse[0](c, pix1, pix2, line_size, h);
+ score1 = c->mecc.sse[0](c, pix1, pix2, stride, h);
else
- score1 = ff_sse16_mmx(c, pix1, pix2, line_size, h);
- score2 = ff_hf_noise16_mmx(pix1, line_size, h) + ff_hf_noise8_mmx(pix1+8, line_size, h)
- - ff_hf_noise16_mmx(pix2, line_size, h) - ff_hf_noise8_mmx(pix2+8, line_size, h);
+ score1 = ff_sse16_mmx(c, pix1, pix2, stride, h);
+ score2 = ff_hf_noise16_mmx(pix1, stride, h) + ff_hf_noise8_mmx(pix1+8, stride, h)
+ - ff_hf_noise16_mmx(pix2, stride, h) - ff_hf_noise8_mmx(pix2+8, stride, h);
if (c)
return score1 + FFABS(score2) * c->avctx->nsse_weight;
}
static int nsse8_mmx(MpegEncContext *c, uint8_t *pix1, uint8_t *pix2,
- int line_size, int h)
+ ptrdiff_t stride, int h)
{
- int score1 = ff_sse8_mmx(c, pix1, pix2, line_size, h);
- int score2 = ff_hf_noise8_mmx(pix1, line_size, h) -
- ff_hf_noise8_mmx(pix2, line_size, h);
+ int score1 = ff_sse8_mmx(c, pix1, pix2, stride, h);
+ int score2 = ff_hf_noise8_mmx(pix1, stride, h) -
+ ff_hf_noise8_mmx(pix2, stride, h);
if (c)
return score1 + FFABS(score2) * c->avctx->nsse_weight;
#if HAVE_INLINE_ASM
static int vsad_intra16_mmx(MpegEncContext *v, uint8_t *pix, uint8_t *dummy,
- int line_size, int h)
+ ptrdiff_t stride, int h)
{
int tmp;
av_assert2((((int) pix) & 7) == 0);
- av_assert2((line_size & 7) == 0);
+ av_assert2((stride & 7) == 0);
#define SUM(in0, in1, out0, out1) \
"movq (%0), %%mm2\n" \
"paddw %%mm6, %%mm0\n"
"movd %%mm0, %1\n"
: "+r" (pix), "=r" (tmp)
- : "r" ((x86_reg) line_size), "m" (h)
+ : "r" (stride), "m" (h)
: "%ecx");
return tmp & 0xFFFF;
}
#undef SUM
-static int vsad_intra16_mmxext(MpegEncContext *v, uint8_t *pix, uint8_t *dummy,
- int line_size, int h)
-{
- int tmp;
-
- av_assert2((((int) pix) & 7) == 0);
- av_assert2((line_size & 7) == 0);
-
-#define SUM(in0, in1, out0, out1) \
- "movq (%0), " #out0 "\n" \
- "movq 8(%0), " #out1 "\n" \
- "add %2, %0\n" \
- "psadbw " #out0 ", " #in0 "\n" \
- "psadbw " #out1 ", " #in1 "\n" \
- "paddw " #in1 ", " #in0 "\n" \
- "paddw " #in0 ", %%mm6\n"
-
- __asm__ volatile (
- "movl %3, %%ecx\n"
- "pxor %%mm6, %%mm6\n"
- "pxor %%mm7, %%mm7\n"
- "movq (%0), %%mm0\n"
- "movq 8(%0), %%mm1\n"
- "add %2, %0\n"
- "jmp 2f\n"
- "1:\n"
-
- SUM(%%mm4, %%mm5, %%mm0, %%mm1)
- "2:\n"
- SUM(%%mm0, %%mm1, %%mm4, %%mm5)
-
- "subl $2, %%ecx\n"
- "jnz 1b\n"
-
- "movd %%mm6, %1\n"
- : "+r" (pix), "=r" (tmp)
- : "r" ((x86_reg) line_size), "m" (h)
- : "%ecx");
-
- return tmp;
-}
-#undef SUM
-
static int vsad16_mmx(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
- int line_size, int h)
+ ptrdiff_t stride, int h)
{
int tmp;
av_assert2((((int) pix1) & 7) == 0);
av_assert2((((int) pix2) & 7) == 0);
- av_assert2((line_size & 7) == 0);
+ av_assert2((stride & 7) == 0);
#define SUM(in0, in1, out0, out1) \
"movq (%0), %%mm2\n" \
"paddw %%mm6, %%mm0\n"
"movd %%mm0, %2\n"
: "+r" (pix1), "+r" (pix2), "=r" (tmp)
- : "r" ((x86_reg) line_size), "m" (h)
+ : "r" (stride), "m" (h)
: "%ecx");
return tmp & 0x7FFF;
}
#undef SUM
-static int vsad16_mmxext(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
- int line_size, int h)
-{
- int tmp;
-
- av_assert2((((int) pix1) & 7) == 0);
- av_assert2((((int) pix2) & 7) == 0);
- av_assert2((line_size & 7) == 0);
-
-#define SUM(in0, in1, out0, out1) \
- "movq (%0), " #out0 "\n" \
- "movq (%1), %%mm2\n" \
- "movq 8(%0), " #out1 "\n" \
- "movq 8(%1), %%mm3\n" \
- "add %3, %0\n" \
- "add %3, %1\n" \
- "psubb %%mm2, " #out0 "\n" \
- "psubb %%mm3, " #out1 "\n" \
- "pxor %%mm7, " #out0 "\n" \
- "pxor %%mm7, " #out1 "\n" \
- "psadbw " #out0 ", " #in0 "\n" \
- "psadbw " #out1 ", " #in1 "\n" \
- "paddw " #in1 ", " #in0 "\n" \
- "paddw " #in0 ", %%mm6\n "
-
- __asm__ volatile (
- "movl %4, %%ecx\n"
- "pxor %%mm6, %%mm6\n"
- "pcmpeqw %%mm7, %%mm7\n"
- "psllw $15, %%mm7\n"
- "packsswb %%mm7, %%mm7\n"
- "movq (%0), %%mm0\n"
- "movq (%1), %%mm2\n"
- "movq 8(%0), %%mm1\n"
- "movq 8(%1), %%mm3\n"
- "add %3, %0\n"
- "add %3, %1\n"
- "psubb %%mm2, %%mm0\n"
- "psubb %%mm3, %%mm1\n"
- "pxor %%mm7, %%mm0\n"
- "pxor %%mm7, %%mm1\n"
- "jmp 2f\n"
- "1:\n"
-
- SUM(%%mm4, %%mm5, %%mm0, %%mm1)
- "2:\n"
- SUM(%%mm0, %%mm1, %%mm4, %%mm5)
-
- "subl $2, %%ecx\n"
- "jnz 1b\n"
-
- "movd %%mm6, %2\n"
- : "+r" (pix1), "+r" (pix2), "=r" (tmp)
- : "r" ((x86_reg) line_size), "m" (h)
- : "%ecx");
-
- return tmp;
-}
-#undef SUM
-
-
-
DECLARE_ASM_CONST(8, uint64_t, round_tab)[3] = {
0x0000000000000000ULL,
0x0001000100010001ULL,
0x0002000200020002ULL,
};
-DECLARE_ASM_CONST(8, uint64_t, bone) = 0x0101010101010101LL;
-
-static inline void sad8_1_mmx(uint8_t *blk1, uint8_t *blk2, int stride, int h)
+static inline void sad8_1_mmx(uint8_t *blk1, uint8_t *blk2,
+ ptrdiff_t stride, int h)
{
- x86_reg len = -(x86_reg)stride * h;
+ x86_reg len = -stride * h;
__asm__ volatile (
".p2align 4 \n\t"
"1: \n\t"
"add %3, %%"REG_a" \n\t"
" js 1b \n\t"
: "+a" (len)
- : "r" (blk1 - len), "r" (blk2 - len), "r" ((x86_reg) stride));
-}
-
-static inline void sad8_1_mmxext(uint8_t *blk1, uint8_t *blk2,
- int stride, int h)
-{
- __asm__ volatile (
- ".p2align 4 \n\t"
- "1: \n\t"
- "movq (%1), %%mm0 \n\t"
- "movq (%1, %3), %%mm1 \n\t"
- "psadbw (%2), %%mm0 \n\t"
- "psadbw (%2, %3), %%mm1 \n\t"
- "paddw %%mm0, %%mm6 \n\t"
- "paddw %%mm1, %%mm6 \n\t"
- "lea (%1,%3,2), %1 \n\t"
- "lea (%2,%3,2), %2 \n\t"
- "sub $2, %0 \n\t"
- " jg 1b \n\t"
- : "+r" (h), "+r" (blk1), "+r" (blk2)
- : "r" ((x86_reg) stride));
-}
-
-static int sad16_sse2(MpegEncContext *v, uint8_t *blk2, uint8_t *blk1,
- int stride, int h)
-{
- int ret;
- __asm__ volatile (
- "pxor %%xmm2, %%xmm2 \n\t"
- ".p2align 4 \n\t"
- "1: \n\t"
- "movdqu (%1), %%xmm0 \n\t"
- "movdqu (%1, %4), %%xmm1 \n\t"
- "psadbw (%2), %%xmm0 \n\t"
- "psadbw (%2, %4), %%xmm1 \n\t"
- "paddw %%xmm0, %%xmm2 \n\t"
- "paddw %%xmm1, %%xmm2 \n\t"
- "lea (%1,%4,2), %1 \n\t"
- "lea (%2,%4,2), %2 \n\t"
- "sub $2, %0 \n\t"
- " jg 1b \n\t"
- "movhlps %%xmm2, %%xmm0 \n\t"
- "paddw %%xmm0, %%xmm2 \n\t"
- "movd %%xmm2, %3 \n\t"
- : "+r" (h), "+r" (blk1), "+r" (blk2), "=r" (ret)
- : "r" ((x86_reg) stride));
- return ret;
-}
-
-static inline void sad8_x2a_mmxext(uint8_t *blk1, uint8_t *blk2,
- int stride, int h)
-{
- __asm__ volatile (
- ".p2align 4 \n\t"
- "1: \n\t"
- "movq (%1), %%mm0 \n\t"
- "movq (%1, %3), %%mm1 \n\t"
- "pavgb 1(%1), %%mm0 \n\t"
- "pavgb 1(%1, %3), %%mm1 \n\t"
- "psadbw (%2), %%mm0 \n\t"
- "psadbw (%2, %3), %%mm1 \n\t"
- "paddw %%mm0, %%mm6 \n\t"
- "paddw %%mm1, %%mm6 \n\t"
- "lea (%1,%3,2), %1 \n\t"
- "lea (%2,%3,2), %2 \n\t"
- "sub $2, %0 \n\t"
- " jg 1b \n\t"
- : "+r" (h), "+r" (blk1), "+r" (blk2)
- : "r" ((x86_reg) stride));
-}
-
-static inline void sad8_y2a_mmxext(uint8_t *blk1, uint8_t *blk2,
- int stride, int h)
-{
- __asm__ volatile (
- "movq (%1), %%mm0 \n\t"
- "add %3, %1 \n\t"
- ".p2align 4 \n\t"
- "1: \n\t"
- "movq (%1), %%mm1 \n\t"
- "movq (%1, %3), %%mm2 \n\t"
- "pavgb %%mm1, %%mm0 \n\t"
- "pavgb %%mm2, %%mm1 \n\t"
- "psadbw (%2), %%mm0 \n\t"
- "psadbw (%2, %3), %%mm1 \n\t"
- "paddw %%mm0, %%mm6 \n\t"
- "paddw %%mm1, %%mm6 \n\t"
- "movq %%mm2, %%mm0 \n\t"
- "lea (%1,%3,2), %1 \n\t"
- "lea (%2,%3,2), %2 \n\t"
- "sub $2, %0 \n\t"
- " jg 1b \n\t"
- : "+r" (h), "+r" (blk1), "+r" (blk2)
- : "r" ((x86_reg) stride));
-}
-
-static inline void sad8_4_mmxext(uint8_t *blk1, uint8_t *blk2,
- int stride, int h)
-{
- __asm__ volatile (
- "movq "MANGLE(bone)", %%mm5 \n\t"
- "movq (%1), %%mm0 \n\t"
- "pavgb 1(%1), %%mm0 \n\t"
- "add %3, %1 \n\t"
- ".p2align 4 \n\t"
- "1: \n\t"
- "movq (%1), %%mm1 \n\t"
- "movq (%1,%3), %%mm2 \n\t"
- "pavgb 1(%1), %%mm1 \n\t"
- "pavgb 1(%1,%3), %%mm2 \n\t"
- "psubusb %%mm5, %%mm1 \n\t"
- "pavgb %%mm1, %%mm0 \n\t"
- "pavgb %%mm2, %%mm1 \n\t"
- "psadbw (%2), %%mm0 \n\t"
- "psadbw (%2,%3), %%mm1 \n\t"
- "paddw %%mm0, %%mm6 \n\t"
- "paddw %%mm1, %%mm6 \n\t"
- "movq %%mm2, %%mm0 \n\t"
- "lea (%1,%3,2), %1 \n\t"
- "lea (%2,%3,2), %2 \n\t"
- "sub $2, %0 \n\t"
- " jg 1b \n\t"
- : "+r" (h), "+r" (blk1), "+r" (blk2)
- : "r" ((x86_reg) stride)
- NAMED_CONSTRAINTS_ADD(bone));
+ : "r" (blk1 - len), "r" (blk2 - len), "r" (stride));
}
static inline void sad8_2_mmx(uint8_t *blk1a, uint8_t *blk1b, uint8_t *blk2,
- int stride, int h)
+ ptrdiff_t stride, int h)
{
- x86_reg len = -(x86_reg)stride * h;
+ x86_reg len = -stride * h;
__asm__ volatile (
".p2align 4 \n\t"
"1: \n\t"
" js 1b \n\t"
: "+a" (len)
: "r" (blk1a - len), "r" (blk1b - len), "r" (blk2 - len),
- "r" ((x86_reg) stride));
+ "r" (stride));
}
-static inline void sad8_4_mmx(uint8_t *blk1, uint8_t *blk2, int stride, int h)
+static inline void sad8_4_mmx(uint8_t *blk1, uint8_t *blk2,
+ ptrdiff_t stride, int h)
{
- x86_reg len = -(x86_reg)stride * h;
+ x86_reg len = -stride * h;
__asm__ volatile (
"movq (%1, %%"REG_a"), %%mm0 \n\t"
"movq 1(%1, %%"REG_a"), %%mm2 \n\t"
" js 1b \n\t"
: "+a" (len)
: "r" (blk1 - len), "r" (blk1 - len + stride), "r" (blk2 - len),
- "r" ((x86_reg) stride), "m" (round_tab[2]));
+ "r" (stride), "m" (round_tab[2]));
}
static inline int sum_mmx(void)
return ret & 0xFFFF;
}
-static inline int sum_mmxext(void)
-{
- int ret;
- __asm__ volatile (
- "movd %%mm6, %0 \n\t"
- : "=r" (ret));
- return ret;
-}
-
-static inline void sad8_x2a_mmx(uint8_t *blk1, uint8_t *blk2, int stride, int h)
+static inline void sad8_x2a_mmx(uint8_t *blk1, uint8_t *blk2,
+ ptrdiff_t stride, int h)
{
sad8_2_mmx(blk1, blk1 + 1, blk2, stride, h);
}
-static inline void sad8_y2a_mmx(uint8_t *blk1, uint8_t *blk2, int stride, int h)
+static inline void sad8_y2a_mmx(uint8_t *blk1, uint8_t *blk2,
+ ptrdiff_t stride, int h)
{
sad8_2_mmx(blk1, blk1 + stride, blk2, stride, h);
}
#define PIX_SAD(suf) \
static int sad8_ ## suf(MpegEncContext *v, uint8_t *blk2, \
- uint8_t *blk1, int stride, int h) \
+ uint8_t *blk1, ptrdiff_t stride, int h) \
{ \
av_assert2(h == 8); \
__asm__ volatile ( \
} \
\
static int sad8_x2_ ## suf(MpegEncContext *v, uint8_t *blk2, \
- uint8_t *blk1, int stride, int h) \
+ uint8_t *blk1, ptrdiff_t stride, int h) \
{ \
av_assert2(h == 8); \
__asm__ volatile ( \
} \
\
static int sad8_y2_ ## suf(MpegEncContext *v, uint8_t *blk2, \
- uint8_t *blk1, int stride, int h) \
+ uint8_t *blk1, ptrdiff_t stride, int h) \
{ \
av_assert2(h == 8); \
__asm__ volatile ( \
} \
\
static int sad8_xy2_ ## suf(MpegEncContext *v, uint8_t *blk2, \
- uint8_t *blk1, int stride, int h) \
+ uint8_t *blk1, ptrdiff_t stride, int h) \
{ \
av_assert2(h == 8); \
__asm__ volatile ( \
} \
\
static int sad16_ ## suf(MpegEncContext *v, uint8_t *blk2, \
- uint8_t *blk1, int stride, int h) \
+ uint8_t *blk1, ptrdiff_t stride, int h) \
{ \
__asm__ volatile ( \
"pxor %%mm7, %%mm7 \n\t" \
} \
\
static int sad16_x2_ ## suf(MpegEncContext *v, uint8_t *blk2, \
- uint8_t *blk1, int stride, int h) \
+ uint8_t *blk1, ptrdiff_t stride, int h) \
{ \
__asm__ volatile ( \
"pxor %%mm7, %%mm7 \n\t" \
} \
\
static int sad16_y2_ ## suf(MpegEncContext *v, uint8_t *blk2, \
- uint8_t *blk1, int stride, int h) \
+ uint8_t *blk1, ptrdiff_t stride, int h) \
{ \
__asm__ volatile ( \
"pxor %%mm7, %%mm7 \n\t" \
} \
\
static int sad16_xy2_ ## suf(MpegEncContext *v, uint8_t *blk2, \
- uint8_t *blk1, int stride, int h) \
+ uint8_t *blk1, ptrdiff_t stride, int h) \
{ \
__asm__ volatile ( \
"pxor %%mm7, %%mm7 \n\t" \
} \
PIX_SAD(mmx)
-PIX_SAD(mmxext)
#endif /* HAVE_INLINE_ASM */
}
}
- if (INLINE_MMXEXT(cpu_flags)) {
- c->vsad[4] = vsad_intra16_mmxext;
-
- c->pix_abs[0][0] = sad16_mmxext;
- c->pix_abs[1][0] = sad8_mmxext;
-
- c->sad[0] = sad16_mmxext;
- c->sad[1] = sad8_mmxext;
-
- c->pix_abs[0][1] = sad16_x2_mmxext;
- c->pix_abs[0][2] = sad16_y2_mmxext;
- c->pix_abs[1][1] = sad8_x2_mmxext;
- c->pix_abs[1][2] = sad8_y2_mmxext;
-
- if (!(avctx->flags & CODEC_FLAG_BITEXACT)) {
- c->pix_abs[0][3] = sad16_xy2_mmxext;
- c->pix_abs[1][3] = sad8_xy2_mmxext;
-
- c->vsad[0] = vsad16_mmxext;
- }
- }
-
- if (INLINE_SSE2(cpu_flags) && !(cpu_flags & AV_CPU_FLAG_SSE2SLOW) && avctx->codec_id != AV_CODEC_ID_SNOW) {
- c->sad[0] = sad16_sse2;
- }
-
#endif /* HAVE_INLINE_ASM */
if (EXTERNAL_MMX(cpu_flags)) {
c->hadamard8_diff[0] = ff_hadamard8_diff16_mmxext;
c->hadamard8_diff[1] = ff_hadamard8_diff_mmxext;
c->sum_abs_dctelem = ff_sum_abs_dctelem_mmxext;
+
+ c->sad[0] = ff_sad16_mmxext;
+ c->sad[1] = ff_sad8_mmxext;
+
+ c->pix_abs[0][0] = ff_sad16_mmxext;
+ c->pix_abs[0][1] = ff_sad16_x2_mmxext;
+ c->pix_abs[0][2] = ff_sad16_y2_mmxext;
+ c->pix_abs[1][0] = ff_sad8_mmxext;
+ c->pix_abs[1][1] = ff_sad8_x2_mmxext;
+ c->pix_abs[1][2] = ff_sad8_y2_mmxext;
+
+ c->vsad[4] = ff_vsad_intra16_mmxext;
+ c->vsad[5] = ff_vsad_intra8_mmxext;
+
+ if (!(avctx->flags & CODEC_FLAG_BITEXACT)) {
+ c->pix_abs[0][3] = ff_sad16_approx_xy2_mmxext;
+ c->pix_abs[1][3] = ff_sad8_approx_xy2_mmxext;
+
+ c->vsad[0] = ff_vsad16_approx_mmxext;
+ c->vsad[1] = ff_vsad8_approx_mmxext;
+ }
}
if (EXTERNAL_SSE2(cpu_flags)) {
c->hadamard8_diff[0] = ff_hadamard8_diff16_sse2;
c->hadamard8_diff[1] = ff_hadamard8_diff_sse2;
#endif
+ if (!(cpu_flags & AV_CPU_FLAG_SSE2SLOW) && avctx->codec_id != AV_CODEC_ID_SNOW) {
+ c->sad[0] = ff_sad16_sse2;
+ c->pix_abs[0][0] = ff_sad16_sse2;
+ c->pix_abs[0][1] = ff_sad16_x2_sse2;
+ c->pix_abs[0][2] = ff_sad16_y2_sse2;
+
+ c->vsad[4] = ff_vsad_intra16_sse2;
+ if (!(avctx->flags & CODEC_FLAG_BITEXACT)) {
+ c->pix_abs[0][3] = ff_sad16_approx_xy2_sse2;
+ c->vsad[0] = ff_vsad16_approx_sse2;
+ }
+ }
}
if (EXTERNAL_SSSE3(cpu_flags)) {
--- /dev/null
+;******************************************************************************
+;* SIMD-optimized MLP DSP functions
+;* Copyright (c) 2014 James Almer <jamrial@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_TEXT
+
+%if ARCH_X86_64
+
+%macro SHLX 2
+%if cpuflag(bmi2)
+ shlx %1, %1, %2q
+%else
+ shl %1, %2b
+%endif
+%endmacro
+
+%macro REMATRIX 0
+ movdqa m0, [samplesq]
+ movdqa m1, [coeffsq ]
+ pshufd m2, m0, q2301
+ pshufd m3, m1, q2301
+ pmuldq m0, m1
+ pmuldq m3, m2
+ paddq m0, m3
+%if notcpuflag(avx2)
+ movdqa m1, [samplesq + 16]
+ movdqa m2, [coeffsq + 16]
+ pshufd m3, m1, q2301
+ pshufd m4, m2, q2301
+ pmuldq m1, m2
+ pmuldq m4, m3
+ paddq m0, m1
+ paddq m0, m4
+%else
+ vextracti128 xm1, m0, 1
+ paddq xm0, xm1
+%endif
+%endmacro
+
+%macro LOOP_END 0
+ pshufd xm1, xm0, q0032
+ paddq xm0, xm1
+ movq accumq, xm0
+ movzx blsbsd, byte [blsbs_ptrq] ; load *bypassed_lsbs
+ sar accumq, 14 ; accum >>= 14
+ and accumd, maskd ; accum &= mask
+ add accumd, blsbsd ; accum += *bypassed_lsbs
+ mov [samplesq + dest_chq], accumd ; samples[dest_ch] = accum
+ add blsbs_ptrq, 8 ; bypassed_lsbs += MAX_CHANNELS;
+ add samplesq, 32 ; samples += MAX_CHANNELS;
+ cmp blsbs_ptrq, cntq
+%endmacro
+
+%macro LOOP_SHIFT_END 0
+ pshufd xm1, xm0, q0032
+ paddq xm0, xm1
+ movq accumq, xm0
+ and indexd, auspd ; index &= access_unit_size_pow2;
+ movsx noiseq, byte [noise_bufferq + indexq] ; load noise_buffer[index]
+ add indexd, index2d ; index += index2
+ SHLX noiseq, mns ; noise_buffer[index] <<= matrix_noise_shift
+ add accumq, noiseq ; accum += noise_buffer[index]
+ movzx noised, byte [blsbs_ptrq] ; load *bypassed_lsbs (reuse tmp noise register)
+ sar accumq, 14 ; accum >>= 14
+ and accumd, maskd ; accum &= mask
+ add accumd, noised ; accum += *bypassed_lsbs
+ mov [samplesq + dest_chq], accumd ; samples[dest_ch] = accum
+ add blsbs_ptrq, 8 ; bypassed_lsbs += MAX_CHANNELS;
+ add samplesq, 32 ; samples += MAX_CHANNELS;
+ cmp blsbs_ptrq, cntq
+%endmacro
+
+;void ff_mlp_rematrix_channel(int32_t *samples, const int32_t *coeffs,
+; const uint8_t *bypassed_lsbs, const int8_t *noise_buffer,
+; int index, unsigned int dest_ch, uint16_t blockpos,
+; unsigned int maxchan, int matrix_noise_shift,
+; int access_unit_size_pow2, int32_t mask)
+%macro MLP_REMATRIX_CHANNEL 0
+cglobal mlp_rematrix_channel, 0, 13, 5, samples, coeffs, blsbs_ptr, blsbs, \
+ index, dest_ch, blockpos, maxchan, mns, \
+ accum, mask, cnt
+ mov mnsd, mnsm ; load matrix_noise_shift
+ movzx blockposq, word blockposm ; load and zero extend blockpos (16bit)
+ mov maxchand, maxchanm ; load maxchan
+ mov maskd, maskm ; load mask
+%if WIN64
+ mov dest_chd, dest_chm ; load dest_chd (not needed on UNIX64)
+%endif
+ shl dest_chd, 2
+ lea cntq, [blsbs_ptrq + blockposq*8]
+ test mnsd, mnsd ; is matrix_noise_shift != 0?
+ jne .shift ; jump if true
+ cmp maxchand, 4 ; is maxchan < 4?
+ jl .loop4 ; jump if true
+
+align 16
+.loop8:
+ ; Process 5 or more channels
+ REMATRIX
+ LOOP_END
+ jne .loop8
+ RET
+
+align 16
+.loop4:
+ ; Process up to 4 channels
+ movdqa xm0, [samplesq]
+ movdqa xm1, [coeffsq ]
+ pshufd xm2, xm0, q2301
+ pshufd xm3, xm1, q2301
+ pmuldq xm0, xm1
+ pmuldq xm3, xm2
+ paddq xm0, xm3
+ LOOP_END
+ jne .loop4
+ RET
+
+.shift:
+%if WIN64
+ mov indexd, indexm ; load index (not needed on UNIX64)
+%endif
+ mov r9d, r9m ; load access_unit_size_pow2
+%if cpuflag(bmi2)
+ ; bmi2 has shift functions that accept any gpr, not just cl, so keep things in place.
+ DEFINE_ARGS samples, coeffs, blsbs_ptr, noise_buffer, \
+ index, dest_ch, accum, index2, mns, \
+ ausp, mask, cnt, noise
+ add mnsd, 7 ; matrix_noise_shift += 7
+%else ; sse4
+ mov r6, rcx ; move rcx elsewhere so we can use cl for matrix_noise_shift
+%if WIN64
+ ; r0 = rcx
+ DEFINE_ARGS mns, coeffs, blsbs_ptr, noise_buffer, index, dest_ch, samples, \
+ index2, accum, ausp, mask, cnt, noise
+%else ; UNIX64
+ ; r3 = rcx
+ DEFINE_ARGS samples, coeffs, blsbs_ptr, mns, index, dest_ch, noise_buffer, \
+ index2, accum, ausp, mask, cnt, noise
+%endif
+ lea mnsd, [r8 + 7] ; rcx = matrix_noise_shift + 7
+%endif ; cpuflag
+ sub auspd, 1 ; access_unit_size_pow2 -= 1
+ cmp r7d, 4 ; is maxchan < 4?
+ lea index2q, [indexq*2 + 1] ; index2 = 2 * index + 1;
+ jl .loop4_shift ; jump if maxchan < 4
+
+align 16
+.loop8_shift:
+ ; Process 5 or more channels
+ REMATRIX
+ LOOP_SHIFT_END
+ jne .loop8_shift
+ RET
+
+align 16
+.loop4_shift:
+ ; Process up to 4 channels
+ movdqa xm0, [samplesq]
+ movdqa xm1, [coeffsq ]
+ pshufd xm2, xm0, q2301
+ pshufd xm3, xm1, q2301
+ pmuldq xm0, xm1
+ pmuldq xm3, xm2
+ paddq xm0, xm3
+ LOOP_SHIFT_END
+ jne .loop4_shift
+ RET
+%endmacro
+
+INIT_XMM sse4
+MLP_REMATRIX_CHANNEL
+%if HAVE_AVX2_EXTERNAL
+INIT_YMM avx2, bmi2
+MLP_REMATRIX_CHANNEL
+%endif
+
+%endif ; ARCH_X86_64
#include "libavcodec/mlpdsp.h"
#include "libavcodec/mlp.h"
+#define REMATRIX_CHANNEL_FUNC(opt) \
+void ff_mlp_rematrix_channel_##opt(int32_t *samples, \
+ const int32_t *coeffs, \
+ const uint8_t *bypassed_lsbs, \
+ const int8_t *noise_buffer, \
+ int index, \
+ unsigned int dest_ch, \
+ uint16_t blockpos, \
+ unsigned int maxchan, \
+ int matrix_noise_shift, \
+ int access_unit_size_pow2, \
+ int32_t mask);
+
+REMATRIX_CHANNEL_FUNC(sse4)
+REMATRIX_CHANNEL_FUNC(avx2_bmi2)
+
#if HAVE_7REGS && HAVE_INLINE_ASM && HAVE_INLINE_ASM_NONLOCAL_LABELS
extern char ff_mlp_firorder_8;
av_cold void ff_mlpdsp_init_x86(MLPDSPContext *c)
{
-#if HAVE_7REGS && HAVE_INLINE_ASM && HAVE_INLINE_ASM_NONLOCAL_LABELS
int cpu_flags = av_get_cpu_flags();
+#if HAVE_7REGS && HAVE_INLINE_ASM && HAVE_INLINE_ASM_NONLOCAL_LABELS
if (INLINE_MMX(cpu_flags))
c->mlp_filter_channel = mlp_filter_channel_x86;
#endif
+ if (ARCH_X86_64 && EXTERNAL_SSE4(cpu_flags))
+ c->mlp_rematrix_channel = ff_mlp_rematrix_channel_sse4;
+ if (ARCH_X86_64 && EXTERNAL_AVX2(cpu_flags) && cpu_flags & AV_CPU_FLAG_BMI2)
+ c->mlp_rematrix_channel = ff_mlp_rematrix_channel_avx2_bmi2;
}
SECTION .text
; int ff_pix_sum16_mmx(uint8_t *pix, int line_size)
-; %1 = number of xmm registers used
-; %2 = number of loops
-; %3 = number of GPRs used
-%macro PIX_SUM16 4
-cglobal pix_sum16, 2, %3, %1
+; %1 = number of loops
+; %2 = number of GPRs used
+%macro PIX_SUM16 3
+cglobal pix_sum16, 2, %2, 6
movsxdifnidn r1, r1d
- mov r2, %2
-%if cpuflag(xop)
+ mov r2, %1
+%if mmsize == 16
lea r3, [r1*3]
-%else
+%endif
+%if notcpuflag(xop)
pxor m5, m5
%endif
pxor m4, m4
mova m0, [r0]
%if mmsize == 8
mova m1, [r0+8]
-%else
+%if cpuflag(mmxext)
+ mova m2, [r0+r1]
+ mova m3, [r0+r1+8]
+%endif
+%else ; sse2
mova m1, [r0+r1]
+ mova m2, [r0+r1*2]
+ mova m3, [r0+r3]
%endif
+%if cpuflag(mmxext)
+ psadbw m0, m5
+ psadbw m1, m5
+ psadbw m2, m5
+ psadbw m3, m5
+%else ; mmx
punpckhbw m2, m0, m5
punpcklbw m0, m5
punpckhbw m3, m1, m5
punpcklbw m1, m5
+%endif ; cpuflag(mmxext)
%endif ; cpuflag(xop)
paddw m1, m0
paddw m3, m2
paddw m3, m1
paddw m4, m3
-%if mmsize == 8
- add r0, r1
+%if cpuflag(mmxext)
+ lea r0, [r0+r1*%3]
%else
- lea r0, [r0+r1*%4]
+ add r0, r1
%endif
dec r2
jne .loop
-%if cpuflag(xop)
+%if mmsize == 16
pshufd m0, m4, q0032
paddd m4, m0
-%else
+%elif notcpuflag(mmxext)
HADDW m4, m5
%endif
movd eax, m4
RET
%endmacro
+%if ARCH_X86_32
INIT_MMX mmx
-PIX_SUM16 0, 16, 3, 0
+PIX_SUM16 16, 3, 0
+INIT_MMX mmxext
+PIX_SUM16 8, 4, 2
+%endif
INIT_XMM sse2
-PIX_SUM16 6, 8, 3, 2
+PIX_SUM16 4, 4, 4
%if HAVE_XOP_EXTERNAL
INIT_XMM xop
-PIX_SUM16 5, 4, 4, 4
+PIX_SUM16 4, 4, 4
%endif
; int ff_pix_norm1_mmx(uint8_t *pix, int line_size)
#include "libavcodec/mpegvideoencdsp.h"
int ff_pix_sum16_mmx(uint8_t *pix, int line_size);
+int ff_pix_sum16_mmxext(uint8_t *pix, int line_size);
int ff_pix_sum16_sse2(uint8_t *pix, int line_size);
int ff_pix_sum16_xop(uint8_t *pix, int line_size);
int ff_pix_norm1_mmx(uint8_t *pix, int line_size);
{
int cpu_flags = av_get_cpu_flags();
+#if ARCH_X86_32
if (EXTERNAL_MMX(cpu_flags)) {
c->pix_sum = ff_pix_sum16_mmx;
c->pix_norm1 = ff_pix_norm1_mmx;
}
+ if (EXTERNAL_MMXEXT(cpu_flags)) {
+ c->pix_sum = ff_pix_sum16_mmxext;
+ }
+#endif
+
if (EXTERNAL_SSE2(cpu_flags)) {
c->pix_sum = ff_pix_sum16_sse2;
c->pix_norm1 = ff_pix_norm1_sse2;
and waq, ~(mmsize*2-1)
jmp .end_v
.loop_v:
- mova m0, [src1q+iq]
- mova m1, [src1q+iq+mmsize]
- paddb m0, [src2q+iq]
- paddb m1, [src2q+iq+mmsize]
- mova [dstq+iq ], m0
- mova [dstq+iq+mmsize], m1
+ movu m0, [src2q+iq]
+ movu m1, [src2q+iq+mmsize]
+ paddb m0, [src1q+iq]
+ paddb m1, [src1q+iq+mmsize]
+ movu [dstq+iq ], m0
+ movu [dstq+iq+mmsize], m1
add iq, mmsize*2
.end_v:
cmp iq, waq
.loop
sub sizeq, 8
movq m1, [pix1q + sizeq]
- movu m2, [pix2q + sizeq*2]
+ mova m2, [pix2q + sizeq*2]
%if mmsize == 8
movq m3, [pix2q + sizeq*2 + mmsize]
punpckhbw m4, m1
--- /dev/null
+;******************************************************************************
+;* V210 SIMD pack
+;* Copyright (c) 2014 Kieran Kunhya <kierank@obe.tv>
+;*
+;* 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
+
+v210_enc_min_10: times 8 dw 0x4
+v210_enc_max_10: times 8 dw 0x3fb
+
+v210_enc_luma_mult_10: dw 4,1,16,4,1,16,0,0
+v210_enc_luma_shuf_10: db -1,0,1,-1,2,3,4,5,-1,6,7,-1,8,9,10,11
+
+v210_enc_chroma_mult_10: dw 1,4,16,0,16,1,4,0
+v210_enc_chroma_shuf_10: db 0,1,8,9,-1,2,3,-1,10,11,4,5,-1,12,13,-1
+
+v210_enc_min_8: times 16 db 0x1
+v210_enc_max_8: times 16 db 0xfe
+
+v210_enc_luma_shuf_8: db 6,-1,7,-1,8,-1,9,-1,10,-1,11,-1,-1,-1,-1,-1
+v210_enc_luma_mult_8: dw 16,4,64,16,4,64,0,0
+
+v210_enc_chroma_shuf1_8: db 0,-1,1,-1,2,-1,3,-1,8,-1,9,-1,10,-1,11,-1
+v210_enc_chroma_shuf2_8: db 3,-1,4,-1,5,-1,7,-1,11,-1,12,-1,13,-1,15,-1
+
+v210_enc_chroma_mult_8: dw 4,16,64,0,64,4,16,0
+
+SECTION .text
+
+%macro v210_planar_pack_10 0
+
+; v210_planar_pack_10(const uint16_t *y, const uint16_t *u, const uint16_t *v, uint8_t *dst, ptrdiff_t width)
+cglobal v210_planar_pack_10, 5, 5, 4, y, u, v, dst, width
+ lea r0, [yq+2*widthq]
+ add uq, widthq
+ add vq, widthq
+ neg widthq
+
+ mova m2, [v210_enc_min_10]
+ mova m3, [v210_enc_max_10]
+
+.loop
+ movu m0, [yq+2*widthq]
+ CLIPW m0, m2, m3
+
+ movq m1, [uq+widthq]
+ movhps m1, [vq+widthq]
+ CLIPW m1, m2, m3
+
+ pmullw m0, [v210_enc_luma_mult_10]
+ pshufb m0, [v210_enc_luma_shuf_10]
+
+ pmullw m1, [v210_enc_chroma_mult_10]
+ pshufb m1, [v210_enc_chroma_shuf_10]
+
+ por m0, m1
+
+ movu [dstq], m0
+
+ add dstq, mmsize
+ add widthq, 6
+ jl .loop
+
+ RET
+%endmacro
+
+INIT_XMM ssse3
+v210_planar_pack_10
+
+%macro v210_planar_pack_8 0
+
+; v210_planar_pack_8(const uint8_t *y, const uint8_t *u, const uint8_t *v, uint8_t *dst, ptrdiff_t width)
+cglobal v210_planar_pack_8, 5, 5, 7, y, u, v, dst, width
+ add yq, widthq
+ shr widthq, 1
+ add uq, widthq
+ add vq, widthq
+ neg widthq
+
+ mova m4, [v210_enc_min_8]
+ mova m5, [v210_enc_max_8]
+ pxor m6, m6
+
+.loop
+ movu m1, [yq+2*widthq]
+ CLIPUB m1, m4, m5
+
+ punpcklbw m0, m1, m6
+ ; can't unpack high bytes in the same way because we process
+ ; only six bytes at a time
+ pshufb m1, [v210_enc_luma_shuf_8]
+
+ pmullw m0, [v210_enc_luma_mult_8]
+ pmullw m1, [v210_enc_luma_mult_8]
+ pshufb m0, [v210_enc_luma_shuf_10]
+ pshufb m1, [v210_enc_luma_shuf_10]
+
+ movq m3, [uq+widthq]
+ movhps m3, [vq+widthq]
+ CLIPUB m3, m4, m5
+
+ ; shuffle and multiply to get the same packing as in 10-bit
+ pshufb m2, m3, [v210_enc_chroma_shuf1_8]
+ pshufb m3, [v210_enc_chroma_shuf2_8]
+
+ pmullw m2, [v210_enc_chroma_mult_8]
+ pmullw m3, [v210_enc_chroma_mult_8]
+ pshufb m2, [v210_enc_chroma_shuf_10]
+ pshufb m3, [v210_enc_chroma_shuf_10]
+
+ por m0, m2
+ por m1, m3
+
+ movu [dstq], m0
+ movu [dstq+mmsize], m1
+
+ add dstq, 2*mmsize
+ add widthq, 6
+ jl .loop
+
+ RET
+%endmacro
+
+INIT_XMM ssse3
+v210_planar_pack_8
+INIT_XMM avx
+v210_planar_pack_8
--- /dev/null
+/*
+ * 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/cpu.h"
+#include "libavcodec/v210enc.h"
+
+void ff_v210_planar_pack_8_ssse3(const uint8_t *y, const uint8_t *u, const uint8_t *v, uint8_t *dst, ptrdiff_t width);
+void ff_v210_planar_pack_8_avx(const uint8_t *y, const uint8_t *u, const uint8_t *v, uint8_t *dst, ptrdiff_t width);
+void ff_v210_planar_pack_10_ssse3(const uint16_t *y, const uint16_t *u, const uint16_t *v, uint8_t *dst, ptrdiff_t width);
+
+av_cold void ff_v210enc_init_x86(V210EncContext *s)
+{
+ int cpu_flags = av_get_cpu_flags();
+
+ if( EXTERNAL_SSSE3(cpu_flags) ) {
+ s->pack_line_8 = ff_v210_planar_pack_8_ssse3;
+ s->pack_line_10 = ff_v210_planar_pack_10_ssse3;
+ }
+
+ if( EXTERNAL_AVX(cpu_flags) )
+ s->pack_line_8 = ff_v210_planar_pack_8_avx;
+}
neg n_wordsq
lea start_xq, [start_xq+n_wordsq*2]
.y_loop: ; do {
- ; FIXME also write a ssse3 version using pshufb
+%if cpuflag(avx2)
+ vpbroadcastb m0, [dstq+start_xq]
+ mov wq, n_wordsq ; initialize w
+%else
movzx wd, byte [dstq+start_xq] ; w = read(1)
imul wd, 0x01010101 ; w *= 0x01010101
movd m0, wd
%else ; mmx
punpckldq m0, m0 ; splat
%endif ; mmx/sse
+%endif ; avx2
.x_loop: ; do {
movu [dstq+wq*2], m0 ; write($reg, $mmsize)
add wq, mmsize/2 ; w -= $mmsize/2
INIT_XMM sse2
hvar_fn
+%if HAVE_AVX2_EXTERNAL
+INIT_XMM avx2
+hvar_fn
+%endif
+
; macro to read/write a horizontal number of pixels (%2) to/from registers
; on sse, - fills xmm0-15 for consecutive sets of 16 pixels
; - if (%2 & 8) fills 8 bytes into xmm$next
; obviously not the same on both sides.
%macro READ_V_PIXEL 2
+%if cpuflag(avx2)
+ vpbroadcastb m0, %2
+%else
movzx vald, byte %2
imul vald, 0x01010101
%if %1 >= 8
punpckldq m0, m0
%endif ; mmsize == 16
%endif ; %1 > 16
+%endif ; avx2
%endmacro ; READ_V_PIXEL
%macro WRITE_V_PIXEL 2
%endif ; %1 >=/< 8
%if %1-%%off == 2
+%if cpuflag(avx2)
+ movd [%2+%%off-2], m0
+%else
mov [%2+%%off], valw
+%endif ; avx2
%endif ; (%1-%%off)/2
%endmacro ; WRITE_V_PIXEL
%macro H_EXTEND 2
%assign %%n %1
%rep 1+(%2-%1)/2
+%if cpuflag(avx2)
+cglobal emu_edge_hfix %+ %%n, 4, 4, 1, dst, dst_stride, start_x, bh
+%else
cglobal emu_edge_hfix %+ %%n, 4, 5, 1, dst, dst_stride, start_x, bh, val
+%endif
.loop_y: ; do {
READ_V_PIXEL %%n, [dstq+start_xq] ; $variable_regs = read($n)
WRITE_V_PIXEL %%n, dstq ; write($variable_regs, $n)
INIT_XMM sse2
H_EXTEND 16, 22
+%if HAVE_AVX2_EXTERNAL
+INIT_XMM avx2
+H_EXTEND 8, 22
+%endif
+
%macro PREFETCH_FN 1
cglobal prefetch, 3, 3, 0, buf, stride, h
.loop:
ff_emu_edge_hfix20_sse2, ff_emu_edge_hfix22_sse2
};
extern emu_edge_hvar_func ff_emu_edge_hvar_sse2;
+#if HAVE_AVX2_EXTERNAL
+extern emu_edge_hfix_func ff_emu_edge_hfix8_avx2;
+extern emu_edge_hfix_func ff_emu_edge_hfix10_avx2;
+extern emu_edge_hfix_func ff_emu_edge_hfix12_avx2;
+extern emu_edge_hfix_func ff_emu_edge_hfix14_avx2;
+extern emu_edge_hfix_func ff_emu_edge_hfix16_avx2;
+extern emu_edge_hfix_func ff_emu_edge_hfix18_avx2;
+extern emu_edge_hfix_func ff_emu_edge_hfix20_avx2;
+extern emu_edge_hfix_func ff_emu_edge_hfix22_avx2;
+static emu_edge_hfix_func * const hfixtbl_avx2[11] = {
+ ff_emu_edge_hfix2_mmx, ff_emu_edge_hfix4_mmx, ff_emu_edge_hfix6_mmx,
+ ff_emu_edge_hfix8_avx2, ff_emu_edge_hfix10_avx2, ff_emu_edge_hfix12_avx2,
+ ff_emu_edge_hfix14_avx2, ff_emu_edge_hfix16_avx2, ff_emu_edge_hfix18_avx2,
+ ff_emu_edge_hfix20_avx2, ff_emu_edge_hfix22_avx2
+};
+extern emu_edge_hvar_func ff_emu_edge_hvar_avx2;
+#endif
static av_always_inline void emulated_edge_mc(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride,
x86_reg block_w, x86_reg block_h,
x86_reg src_x, x86_reg src_y,
x86_reg w, x86_reg h,
- emu_edge_vfix_func **vfix_tbl,
+ emu_edge_vfix_func * const *vfix_tbl,
emu_edge_vvar_func *v_extend_var,
- emu_edge_hfix_func **hfix_tbl,
+ emu_edge_hfix_func * const *hfix_tbl,
emu_edge_hvar_func *h_extend_var)
{
x86_reg start_y, start_x, end_y, end_x, src_y_add = 0, p;
src_x, src_y, w, h, vfixtbl_sse, &ff_emu_edge_vvar_sse,
hfixtbl_sse2, &ff_emu_edge_hvar_sse2);
}
+
+#if HAVE_AVX2_EXTERNAL
+static av_noinline void emulated_edge_mc_avx2(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_avx2, &ff_emu_edge_hvar_avx2);
+}
+#endif /* HAVE_AVX2_EXTERNAL */
#endif /* HAVE_YASM */
void ff_prefetch_mmxext(uint8_t *buf, ptrdiff_t stride, int h);
if (EXTERNAL_SSE2(cpu_flags) && bpc <= 8) {
ctx->emulated_edge_mc = emulated_edge_mc_sse2;
}
+#if HAVE_AVX2_EXTERNAL
+ if (EXTERNAL_AVX2(cpu_flags) && bpc <= 8) {
+ ctx->emulated_edge_mc = emulated_edge_mc_avx2;
+ }
+#endif
#endif /* HAVE_YASM */
}
fpel_func(avg, 16, sse2);
fpel_func(avg, 32, sse2);
fpel_func(avg, 64, sse2);
+fpel_func(put, 32, avx);
+fpel_func(put, 64, avx);
+fpel_func(avg, 32, avx2);
+fpel_func(avg, 64, avx2);
#undef fpel_func
#define mc_func(avg, sz, dir, opt) \
void ff_vp9_##avg##_8tap_1d_##dir##_##sz##_##opt(uint8_t *dst, ptrdiff_t dst_stride, \
const uint8_t *src, ptrdiff_t src_stride, \
- int h, const int8_t (*filter)[16])
-#define mc_funcs(sz) \
-mc_func(put, sz, h, ssse3); \
-mc_func(avg, sz, h, ssse3); \
-mc_func(put, sz, v, ssse3); \
-mc_func(avg, sz, v, ssse3)
-
-mc_funcs(4);
-mc_funcs(8);
+ int h, const int8_t (*filter)[32])
+#define mc_funcs(sz, opt) \
+mc_func(put, sz, h, opt); \
+mc_func(avg, sz, h, opt); \
+mc_func(put, sz, v, opt); \
+mc_func(avg, sz, v, opt)
+
+mc_funcs(4, ssse3);
+mc_funcs(8, ssse3);
#if ARCH_X86_64
-mc_funcs(16);
+mc_funcs(16, ssse3);
+mc_funcs(32, avx2);
#endif
#undef mc_funcs
static av_always_inline void \
ff_vp9_##avg##_8tap_1d_##dir##_##sz##_##opt(uint8_t *dst, ptrdiff_t dst_stride, \
const uint8_t *src, ptrdiff_t src_stride, \
- int h, const int8_t (*filter)[16]) \
+ int h, const int8_t (*filter)[32]) \
{ \
ff_vp9_##avg##_8tap_1d_##dir##_##hsz##_##opt(dst, dst_stride, src, \
src_stride, h, filter); \
src_stride, h, filter); \
}
-#define mc_rep_funcs(sz, hsz) \
-mc_rep_func(put, sz, hsz, h, ssse3); \
-mc_rep_func(avg, sz, hsz, h, ssse3); \
-mc_rep_func(put, sz, hsz, v, ssse3); \
-mc_rep_func(avg, sz, hsz, v, ssse3)
+#define mc_rep_funcs(sz, hsz, opt) \
+mc_rep_func(put, sz, hsz, h, opt); \
+mc_rep_func(avg, sz, hsz, h, opt); \
+mc_rep_func(put, sz, hsz, v, opt); \
+mc_rep_func(avg, sz, hsz, v, opt)
#if ARCH_X86_32
-mc_rep_funcs(16, 8);
+mc_rep_funcs(16, 8, ssse3);
+#endif
+mc_rep_funcs(32, 16, ssse3);
+mc_rep_funcs(64, 32, ssse3);
+#if ARCH_X86_64 && HAVE_AVX2_EXTERNAL
+mc_rep_funcs(64, 32, avx2);
#endif
-mc_rep_funcs(32, 16);
-mc_rep_funcs(64, 32);
#undef mc_rep_funcs
#undef mc_rep_func
-extern const int8_t ff_filters_ssse3[3][15][4][16];
+extern const int8_t ff_filters_ssse3[3][15][4][32];
-#define filter_8tap_2d_fn(op, sz, f, fname) \
-static void op##_8tap_##fname##_##sz##hv_ssse3(uint8_t *dst, ptrdiff_t dst_stride, \
+#define filter_8tap_2d_fn(op, sz, f, fname, align, opt) \
+static void op##_8tap_##fname##_##sz##hv_##opt(uint8_t *dst, ptrdiff_t dst_stride, \
const uint8_t *src, ptrdiff_t src_stride, \
int h, int mx, int my) \
{ \
- LOCAL_ALIGNED_16(uint8_t, temp, [71 * 64]); \
- ff_vp9_put_8tap_1d_h_##sz##_ssse3(temp, 64, src - 3 * src_stride, src_stride, \
+ LOCAL_ALIGNED_##align(uint8_t, temp, [71 * 64]); \
+ ff_vp9_put_8tap_1d_h_##sz##_##opt(temp, 64, src - 3 * src_stride, src_stride, \
h + 7, ff_filters_ssse3[f][mx - 1]); \
- ff_vp9_##op##_8tap_1d_v_##sz##_ssse3(dst, dst_stride, temp + 3 * 64, 64, \
+ ff_vp9_##op##_8tap_1d_v_##sz##_##opt(dst, dst_stride, temp + 3 * 64, 64, \
h, ff_filters_ssse3[f][my - 1]); \
}
-#define filters_8tap_2d_fn(op, sz) \
-filter_8tap_2d_fn(op, sz, FILTER_8TAP_REGULAR, regular) \
-filter_8tap_2d_fn(op, sz, FILTER_8TAP_SHARP, sharp) \
-filter_8tap_2d_fn(op, sz, FILTER_8TAP_SMOOTH, smooth)
-
-#define filters_8tap_2d_fn2(op) \
-filters_8tap_2d_fn(op, 64) \
-filters_8tap_2d_fn(op, 32) \
-filters_8tap_2d_fn(op, 16) \
-filters_8tap_2d_fn(op, 8) \
-filters_8tap_2d_fn(op, 4)
-
-filters_8tap_2d_fn2(put)
-filters_8tap_2d_fn2(avg)
+#define filters_8tap_2d_fn(op, sz, align, opt) \
+filter_8tap_2d_fn(op, sz, FILTER_8TAP_REGULAR, regular, align, opt) \
+filter_8tap_2d_fn(op, sz, FILTER_8TAP_SHARP, sharp, align, opt) \
+filter_8tap_2d_fn(op, sz, FILTER_8TAP_SMOOTH, smooth, align, opt)
+
+#define filters_8tap_2d_fn2(op, align, opt) \
+filters_8tap_2d_fn(op, 64, align, opt) \
+filters_8tap_2d_fn(op, 32, align, opt) \
+filters_8tap_2d_fn(op, 16, align, opt) \
+filters_8tap_2d_fn(op, 8, align, opt) \
+filters_8tap_2d_fn(op, 4, align, opt)
+
+filters_8tap_2d_fn2(put, 16, ssse3)
+filters_8tap_2d_fn2(avg, 16, ssse3)
+#if ARCH_X86_64 && HAVE_AVX2_EXTERNAL
+filters_8tap_2d_fn(put, 64, 32, avx2)
+filters_8tap_2d_fn(put, 32, 32, avx2)
+filters_8tap_2d_fn(avg, 64, 32, avx2)
+filters_8tap_2d_fn(avg, 32, 32, avx2)
+#endif
#undef filters_8tap_2d_fn2
#undef filters_8tap_2d_fn
#undef filter_8tap_2d_fn
-#define filter_8tap_1d_fn(op, sz, f, fname, dir, dvar) \
-static void op##_8tap_##fname##_##sz##dir##_ssse3(uint8_t *dst, ptrdiff_t dst_stride, \
+#define filter_8tap_1d_fn(op, sz, f, fname, dir, dvar, opt) \
+static void op##_8tap_##fname##_##sz##dir##_##opt(uint8_t *dst, ptrdiff_t dst_stride, \
const uint8_t *src, ptrdiff_t src_stride, \
int h, int mx, int my) \
{ \
- ff_vp9_##op##_8tap_1d_##dir##_##sz##_ssse3(dst, dst_stride, src, src_stride, \
+ ff_vp9_##op##_8tap_1d_##dir##_##sz##_##opt(dst, dst_stride, src, src_stride, \
h, ff_filters_ssse3[f][dvar - 1]); \
}
-#define filters_8tap_1d_fn(op, sz, dir, dvar) \
-filter_8tap_1d_fn(op, sz, FILTER_8TAP_REGULAR, regular, dir, dvar) \
-filter_8tap_1d_fn(op, sz, FILTER_8TAP_SHARP, sharp, dir, dvar) \
-filter_8tap_1d_fn(op, sz, FILTER_8TAP_SMOOTH, smooth, dir, dvar)
-
-#define filters_8tap_1d_fn2(op, sz) \
-filters_8tap_1d_fn(op, sz, h, mx) \
-filters_8tap_1d_fn(op, sz, v, my)
-
-#define filters_8tap_1d_fn3(op) \
-filters_8tap_1d_fn2(op, 64) \
-filters_8tap_1d_fn2(op, 32) \
-filters_8tap_1d_fn2(op, 16) \
-filters_8tap_1d_fn2(op, 8) \
-filters_8tap_1d_fn2(op, 4)
-
-filters_8tap_1d_fn3(put)
-filters_8tap_1d_fn3(avg)
+#define filters_8tap_1d_fn(op, sz, dir, dvar, opt) \
+filter_8tap_1d_fn(op, sz, FILTER_8TAP_REGULAR, regular, dir, dvar, opt) \
+filter_8tap_1d_fn(op, sz, FILTER_8TAP_SHARP, sharp, dir, dvar, opt) \
+filter_8tap_1d_fn(op, sz, FILTER_8TAP_SMOOTH, smooth, dir, dvar, opt)
+
+#define filters_8tap_1d_fn2(op, sz, opt) \
+filters_8tap_1d_fn(op, sz, h, mx, opt) \
+filters_8tap_1d_fn(op, sz, v, my, opt)
+
+#define filters_8tap_1d_fn3(op, opt) \
+filters_8tap_1d_fn2(op, 64, opt) \
+filters_8tap_1d_fn2(op, 32, opt) \
+filters_8tap_1d_fn2(op, 16, opt) \
+filters_8tap_1d_fn2(op, 8, opt) \
+filters_8tap_1d_fn2(op, 4, opt)
+
+filters_8tap_1d_fn3(put, ssse3)
+filters_8tap_1d_fn3(avg, ssse3)
+#if ARCH_X86_64 && HAVE_AVX2_EXTERNAL
+filters_8tap_1d_fn2(put, 64, avx2)
+filters_8tap_1d_fn2(put, 32, avx2)
+filters_8tap_1d_fn2(avg, 64, avx2)
+filters_8tap_1d_fn2(avg, 32, avx2)
+#endif
#undef filters_8tap_1d_fn
#undef filters_8tap_1d_fn2
dsp->mc[idx1][FILTER_8TAP_REGULAR][idx2][idxh][idxv] = type##_8tap_regular_##sz##dir##_##opt; \
dsp->mc[idx1][FILTER_8TAP_SHARP ][idx2][idxh][idxv] = type##_8tap_sharp_##sz##dir##_##opt
-#define init_subpel2(idx, idxh, idxv, dir, type, opt) \
+#define init_subpel2_32_64(idx, idxh, idxv, dir, type, opt) \
init_subpel1(0, idx, idxh, idxv, 64, dir, type, opt); \
- init_subpel1(1, idx, idxh, idxv, 32, dir, type, opt); \
+ init_subpel1(1, idx, idxh, idxv, 32, dir, type, opt)
+
+#define init_subpel2(idx, idxh, idxv, dir, type, opt) \
+ init_subpel2_32_64(idx, idxh, idxv, dir, type, opt); \
init_subpel1(2, idx, idxh, idxv, 16, dir, type, opt); \
init_subpel1(3, idx, idxh, idxv, 8, dir, type, opt); \
init_subpel1(4, idx, idxh, idxv, 4, dir, type, opt)
dsp->itxfm_add[TX_32X32][DCT_ADST] =
dsp->itxfm_add[TX_32X32][DCT_DCT] = ff_vp9_idct_idct_32x32_add_avx;
}
+ init_fpel(1, 0, 32, put, avx);
+ init_fpel(0, 0, 64, put, avx);
init_lpf(avx);
init_ipred(TX_8X8, 8, avx);
init_ipred(TX_16X16, 16, avx);
}
if (EXTERNAL_AVX2(cpu_flags)) {
+ init_fpel(1, 1, 32, avg, avx2);
+ init_fpel(0, 1, 64, avg, avx2);
+ if (ARCH_X86_64) {
+#if ARCH_X86_64 && HAVE_AVX2_EXTERNAL
+ init_subpel2_32_64(0, 1, 1, hv, put, avx2);
+ init_subpel2_32_64(0, 0, 1, v, put, avx2);
+ init_subpel2_32_64(0, 1, 0, h, put, avx2);
+ init_subpel2_32_64(1, 1, 1, hv, avg, avx2);
+ init_subpel2_32_64(1, 0, 1, v, avg, avx2);
+ init_subpel2_32_64(1, 1, 0, h, avg, avx2);
+#endif
+ }
dsp->intra_pred[TX_32X32][DC_PRED] = ff_vp9_ipred_dc_32x32_avx2;
dsp->intra_pred[TX_32X32][LEFT_DC_PRED] = ff_vp9_ipred_dc_left_32x32_avx2;
dsp->intra_pred[TX_32X32][TOP_DC_PRED] = ff_vp9_ipred_dc_top_32x32_avx2;
%include "libavutil/x86/x86util.asm"
-SECTION_RODATA
+SECTION_RODATA 32
cextern pw_256
%macro F8_TAPS 8
-times 8 db %1, %2
-times 8 db %3, %4
-times 8 db %5, %6
-times 8 db %7, %8
+times 16 db %1, %2
+times 16 db %3, %4
+times 16 db %5, %6
+times 16 db %7, %8
%endmacro
-; int8_t ff_filters_ssse3[3][15][4][16]
+; int8_t ff_filters_ssse3[3][15][4][32]
const filters_ssse3 ; smooth
F8_TAPS -3, -1, 32, 64, 38, 1, -3, 0
F8_TAPS -2, -2, 29, 63, 41, 2, -3, 0
mova m6, [pw_256]
mova m7, [filteryq+ 0]
%if ARCH_X86_64 && mmsize > 8
- mova m8, [filteryq+16]
- mova m9, [filteryq+32]
- mova m10, [filteryq+48]
+ mova m8, [filteryq+32]
+ mova m9, [filteryq+64]
+ mova m10, [filteryq+96]
%endif
.loop:
movh m0, [srcq-3]
pmaddubsw m4, m9
pmaddubsw m1, m10
%else
- pmaddubsw m2, [filteryq+16]
- pmaddubsw m4, [filteryq+32]
- pmaddubsw m1, [filteryq+48]
+ pmaddubsw m2, [filteryq+32]
+ pmaddubsw m4, [filteryq+64]
+ pmaddubsw m1, [filteryq+96]
%endif
paddw m0, m2
paddw m4, m1
cglobal vp9_%1_8tap_1d_h_ %+ %%px, 6, 6, 14, dst, dstride, src, sstride, h, filtery
mova m13, [pw_256]
mova m8, [filteryq+ 0]
- mova m9, [filteryq+16]
- mova m10, [filteryq+32]
- mova m11, [filteryq+48]
+ mova m9, [filteryq+32]
+ mova m10, [filteryq+64]
+ mova m11, [filteryq+96]
.loop:
movu m0, [srcq-3]
movu m1, [srcq-2]
filter_hx2_fn put
filter_hx2_fn avg
+%if HAVE_AVX2_EXTERNAL
+INIT_YMM avx2
+filter_hx2_fn put
+filter_hx2_fn avg
+%endif
+
%endif ; ARCH_X86_64
%macro filter_v_fn 1
sub srcq, sstride3q
mova m7, [filteryq+ 0]
%if ARCH_X86_64 && mmsize > 8
- mova m8, [filteryq+16]
- mova m9, [filteryq+32]
- mova m10, [filteryq+48]
+ mova m8, [filteryq+32]
+ mova m9, [filteryq+64]
+ mova m10, [filteryq+96]
%endif
.loop:
; FIXME maybe reuse loads from previous rows, or just
pmaddubsw m4, m9
pmaddubsw m1, m10
%else
- pmaddubsw m2, [filteryq+16]
- pmaddubsw m4, [filteryq+32]
- pmaddubsw m1, [filteryq+48]
+ pmaddubsw m2, [filteryq+32]
+ pmaddubsw m4, [filteryq+64]
+ pmaddubsw m1, [filteryq+96]
%endif
paddw m0, m2
paddw m4, m1
lea src4q, [srcq+sstrideq]
sub srcq, sstride3q
mova m8, [filteryq+ 0]
- mova m9, [filteryq+16]
- mova m10, [filteryq+32]
- mova m11, [filteryq+48]
+ mova m9, [filteryq+32]
+ mova m10, [filteryq+64]
+ mova m11, [filteryq+96]
.loop:
; FIXME maybe reuse loads from previous rows, or just
; more generally unroll this to prevent multiple loads of
filter_vx2_fn put
filter_vx2_fn avg
+%if HAVE_AVX2_EXTERNAL
+INIT_YMM avx2
+filter_vx2_fn put
+filter_vx2_fn avg
+%endif
+
%endif ; ARCH_X86_64
%macro fpel_fn 6
%define %%dstfn mova
%endif
-%if %2 <= 16
+%if %2 <= mmsize
cglobal vp9_%1%2, 5, 7, 4, dst, dstride, src, sstride, h, dstride3, sstride3
lea sstride3q, [sstrideq*3]
lea dstride3q, [dstrideq*3]
%define d16 16
%define s16 16
+%define d32 32
+%define s32 32
INIT_MMX mmx
fpel_fn put, 4, strideq, strideq*2, stride3q, 4
fpel_fn put, 8, strideq, strideq*2, stride3q, 4
fpel_fn avg, 16, strideq, strideq*2, stride3q, 4
fpel_fn avg, 32, mmsize, strideq, strideq+mmsize, 2
fpel_fn avg, 64, mmsize, mmsize*2, mmsize*3, 1
+INIT_YMM avx
+fpel_fn put, 32, strideq, strideq*2, stride3q, 4
+fpel_fn put, 64, mmsize, strideq, strideq+mmsize, 2
+%if HAVE_AVX2_EXTERNAL
+INIT_YMM avx2
+fpel_fn avg, 32, strideq, strideq*2, stride3q, 4
+fpel_fn avg, 64, mmsize, strideq, strideq+mmsize, 2
+%endif
%undef s16
%undef d16
+%undef s32
+%undef d32
#include "libavutil/mem.h"
#include "libavcodec/avcodec.h"
+#include "libavcodec/idctdsp.h"
#include "idctdsp.h"
#include "xvididct.h"
void ff_xvid_idct_mmx_put(uint8_t *dest, int line_size, int16_t *block)
{
ff_xvid_idct_mmx(block);
- ff_put_pixels_clamped_mmx(block, dest, line_size);
+ ff_put_pixels_clamped(block, dest, line_size);
}
void ff_xvid_idct_mmx_add(uint8_t *dest, int line_size, int16_t *block)
{
ff_xvid_idct_mmx(block);
- ff_add_pixels_clamped_mmx(block, dest, line_size);
+ ff_add_pixels_clamped(block, dest, line_size);
}
#endif /* HAVE_MMX_INLINE */
void ff_xvid_idct_mmxext_put(uint8_t *dest, int line_size, int16_t *block)
{
ff_xvid_idct_mmxext(block);
- ff_put_pixels_clamped_mmx(block, dest, line_size);
+ ff_put_pixels_clamped(block, dest, line_size);
}
void ff_xvid_idct_mmxext_add(uint8_t *dest, int line_size, int16_t *block)
{
ff_xvid_idct_mmxext(block);
- ff_add_pixels_clamped_mmx(block, dest, line_size);
+ ff_add_pixels_clamped(block, dest, line_size);
}
#endif /* HAVE_MMXEXT_INLINE */
#include "libavutil/mem.h"
#include "libavutil/x86/asm.h"
+#include "libavcodec/idctdsp.h"
+
#include "idctdsp.h"
#include "xvididct.h"
void ff_xvid_idct_sse2_put(uint8_t *dest, int line_size, short *block)
{
ff_xvid_idct_sse2(block);
- ff_put_pixels_clamped_mmx(block, dest, line_size);
+ ff_put_pixels_clamped(block, dest, line_size);
}
void ff_xvid_idct_sse2_add(uint8_t *dest, int line_size, short *block)
{
ff_xvid_idct_sse2(block);
- ff_add_pixels_clamped_mmx(block, dest, line_size);
+ ff_add_pixels_clamped(block, dest, line_size);
}
#endif /* HAVE_SSE2_INLINE */
/*
* Image is encoded as a big integer, using characters from '~' to
- * '!', for a total of 92 symbols. In order to express 48x48=2304
- * bits, we need a total of 354 digits, as given by:
- * ceil(lg_92(2^2304)) = 354
+ * '!', for a total of 94 symbols. In order to express
+ * 48x48*2=8*XFACE_MAX_WORDS=4608
+ * bits, we need a total of 704 digits, as given by:
+ * ceil(lg_94(2^4608)) = 704
*/
-#define XFACE_MAX_DIGITS 354
+#define XFACE_MAX_DIGITS 704
#define XFACE_BITSPERWORD 8
#define XFACE_WORDCARRY (1 << XFACE_BITSPERWORD)
* The probability of the data determines the range of possible encodings.
* Offset gives the first possible encoding of the range. */
typedef struct {
- int range;
- int offset;
+ uint8_t range;
+ uint8_t offset;
} ProbRange;
extern const ProbRange ff_xface_probranges_per_level[4][3];
#include "xface.h"
#include "avcodec.h"
#include "internal.h"
+#include "libavutil/avassert.h"
typedef struct XFaceContext {
AVClass *class;
}
typedef struct {
- const ProbRange *prob_ranges[XFACE_PIXELS*2];
+ ProbRange prob_ranges[XFACE_PIXELS*2];
int prob_ranges_idx;
} ProbRangesQueue;
{
if (pq->prob_ranges_idx >= XFACE_PIXELS * 2 - 1)
return -1;
- pq->prob_ranges[pq->prob_ranges_idx++] = p;
+ pq->prob_ranges[pq->prob_ranges_idx++] = *p;
return 0;
}
const AVFrame *frame, int *got_packet)
{
XFaceContext *xface = avctx->priv_data;
- ProbRangesQueue pq = {{ 0 }, 0};
+ ProbRangesQueue pq = {{{ 0 }}, 0};
uint8_t bitmap_copy[XFACE_PIXELS];
BigInt b = {0};
int i, j, k, ret = 0;
encode_block(xface->bitmap + XFACE_WIDTH * 32 + 32, 16, 16, 0, &pq);
while (pq.prob_ranges_idx > 0)
- push_integer(&b, pq.prob_ranges[--pq.prob_ranges_idx]);
+ push_integer(&b, &pq.prob_ranges[--pq.prob_ranges_idx]);
/* write the inverted big integer in b to intbuf */
i = 0;
+ av_assert0(b.nb_words < XFACE_MAX_WORDS);
while (b.nb_words) {
uint8_t r;
ff_big_div(&b, XFACE_PRINTS, &r);
+ av_assert0(i < sizeof(intbuf));
intbuf[i++] = r + XFACE_FIRST_PRINT;
}
#include "libavutil/intreadwrite.h"
#include "xiph.h"
-int avpriv_split_xiph_headers(uint8_t *extradata, int extradata_size,
+int avpriv_split_xiph_headers(const uint8_t *extradata, int extradata_size,
int first_header_size, uint8_t *header_start[3],
int header_len[3])
{
* @param[out] header_len The sizes of each of the three headers.
* @return On error a negative value is returned, on success zero.
*/
-int avpriv_split_xiph_headers(uint8_t *extradata, int extradata_size,
+int avpriv_split_xiph_headers(const uint8_t *extradata, int extradata_size,
int first_header_size, uint8_t *header_start[3],
int header_len[3]);
OBJS-$(CONFIG_AVFOUNDATION_INDEV) += avfoundation.o
OBJS-$(CONFIG_BKTR_INDEV) += bktr.o
OBJS-$(CONFIG_CACA_OUTDEV) += caca.o
-OBJS-$(CONFIG_DECKLINK_OUTDEV) += decklink_enc.o decklink_enc_c.o
+OBJS-$(CONFIG_DECKLINK_OUTDEV) += decklink_enc.o decklink_enc_c.o decklink_common.o
+OBJS-$(CONFIG_DECKLINK_INDEV) += decklink_dec.o decklink_dec_c.o decklink_common.o
OBJS-$(CONFIG_DSHOW_INDEV) += dshow.o dshow_enummediatypes.o \
dshow_enumpins.o dshow_filter.o \
dshow_pin.o dshow_common.o
OBJS-$(CONFIG_OSS_INDEV) += oss_audio.o oss_audio_dec.o
OBJS-$(CONFIG_OSS_OUTDEV) += oss_audio.o oss_audio_enc.o
OBJS-$(CONFIG_PULSE_INDEV) += pulse_audio_dec.o \
- pulse_audio_common.o
+ pulse_audio_common.o timefilter.o
OBJS-$(CONFIG_PULSE_OUTDEV) += pulse_audio_enc.o \
pulse_audio_common.o
OBJS-$(CONFIG_QTKIT_INDEV) += qtkit.o
OBJS-$(CONFIG_V4L_INDEV) += v4l.o
OBJS-$(CONFIG_VFWCAP_INDEV) += vfwcap.o
OBJS-$(CONFIG_X11GRAB_INDEV) += x11grab.o
+OBJS-$(CONFIG_X11GRAB_XCB_INDEV) += xcbgrab.o
OBJS-$(CONFIG_XV_OUTDEV) += xv.o
# external libraries
# Windows resource file
SLIBOBJS-$(HAVE_GNU_WINDRES) += avdeviceres.o
-SKIPHEADERS-$(CONFIG_DECKLINK) += decklink_enc.h
+SKIPHEADERS-$(CONFIG_DECKLINK) += decklink_enc.h decklink_dec.h \
+ decklink_common.h decklink_common_c.h
SKIPHEADERS-$(CONFIG_DSHOW_INDEV) += dshow_capture.h
SKIPHEADERS-$(CONFIG_FBDEV_INDEV) += fbdev_common.h
SKIPHEADERS-$(CONFIG_FBDEV_OUTDEV) += fbdev_common.h
REGISTER_INDEV (AVFOUNDATION, avfoundation);
REGISTER_INDEV (BKTR, bktr);
REGISTER_OUTDEV (CACA, caca);
- REGISTER_OUTDEV (DECKLINK, decklink);
+ REGISTER_INOUTDEV(DECKLINK, decklink);
REGISTER_INDEV (DSHOW, dshow);
REGISTER_INDEV (DV1394, dv1394);
REGISTER_INOUTDEV(FBDEV, fbdev);
// REGISTER_INDEV (V4L, v4l
REGISTER_INDEV (VFWCAP, vfwcap);
REGISTER_INDEV (X11GRAB, x11grab);
+ REGISTER_INDEV (X11GRAB_XCB, x11grab_xcb);
REGISTER_OUTDEV (XV, xv);
/* external libraries */
s->reorder_buf_size = size;
return 0;
}
+
+/* ported from alsa-utils/aplay.c */
+int ff_alsa_get_device_list(AVDeviceInfoList *device_list, snd_pcm_stream_t stream_type)
+{
+ int ret = 0;
+ void **hints, **n;
+ char *name = NULL, *descr = NULL, *io = NULL, *tmp;
+ AVDeviceInfo *new_device = NULL;
+ const char *filter = stream_type == SND_PCM_STREAM_PLAYBACK ? "Output" : "Input";
+
+ if (snd_device_name_hint(-1, "pcm", &hints) < 0)
+ return AVERROR_EXTERNAL;
+ n = hints;
+ while (*n && !ret) {
+ name = snd_device_name_get_hint(*n, "NAME");
+ descr = snd_device_name_get_hint(*n, "DESC");
+ io = snd_device_name_get_hint(*n, "IOID");
+ if (!io || !strcmp(io, filter)) {
+ new_device = av_mallocz(sizeof(AVDeviceInfo));
+ if (!new_device) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+ new_device->device_name = av_strdup(name);
+ if ((tmp = strrchr(descr, '\n')) && tmp[1])
+ new_device->device_description = av_strdup(&tmp[1]);
+ else
+ new_device->device_description = av_strdup(descr);
+ if (!new_device->device_description || !new_device->device_name) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+ if ((ret = av_dynarray_add_nofree(&device_list->devices,
+ &device_list->nb_devices, new_device)) < 0) {
+ goto fail;
+ }
+ new_device = NULL;
+ }
+ fail:
+ free(io);
+ free(name);
+ free(descr);
+ n++;
+ }
+ if (new_device) {
+ av_free(new_device->device_description);
+ av_free(new_device->device_name);
+ av_free(new_device);
+ }
+ snd_device_name_free_hint(hints);
+ return ret;
+}
return 0;
}
+static int audio_get_device_list(AVFormatContext *h, AVDeviceInfoList *device_list)
+{
+ return ff_alsa_get_device_list(device_list, SND_PCM_STREAM_CAPTURE);
+}
+
static const AVOption options[] = {
{ "sample_rate", "", offsetof(AlsaData, sample_rate), AV_OPT_TYPE_INT, {.i64 = 48000}, 1, INT_MAX, AV_OPT_FLAG_DECODING_PARAM },
{ "channels", "", offsetof(AlsaData, channels), AV_OPT_TYPE_INT, {.i64 = 2}, 1, INT_MAX, AV_OPT_FLAG_DECODING_PARAM },
.read_header = audio_read_header,
.read_packet = audio_read_packet,
.read_close = ff_alsa_close,
+ .get_device_list = audio_get_device_list,
.flags = AVFMT_NOFILE,
.priv_class = &alsa_demuxer_class,
};
*dts = s->timestamp - delay;
}
+static int audio_get_device_list(AVFormatContext *h, AVDeviceInfoList *device_list)
+{
+ return ff_alsa_get_device_list(device_list, SND_PCM_STREAM_PLAYBACK);
+}
+
static const AVClass alsa_muxer_class = {
.class_name = "ALSA muxer",
.item_name = av_default_item_name,
.write_packet = audio_write_packet,
.write_trailer = ff_alsa_close,
.write_uncoded_frame = audio_write_frame,
+ .get_device_list = audio_get_device_list,
.get_output_timestamp = audio_get_output_timestamp,
.flags = AVFMT_NOFILE,
.priv_class = &alsa_muxer_class,
int ff_alsa_extend_reorder_buf(AlsaData *s, int size);
+int ff_alsa_get_device_list(AVDeviceInfoList *device_list, snd_pcm_stream_t stream_type);
+
#endif /* AVDEVICE_ALSA_AUDIO_H */
for (i = 0; i < list->nb_devices; i++) {
dev = list->devices[i];
if (dev) {
- av_free(dev->device_name);
- av_free(dev->device_description);
+ av_freep(&dev->device_name);
+ av_freep(&dev->device_description);
av_free(dev);
}
}
- av_free(list->devices);
+ av_freep(&list->devices);
av_freep(device_list);
}
#include "libavutil/pixdesc.h"
#include "libavutil/opt.h"
+#include "libavutil/avstring.h"
#include "libavformat/internal.h"
#include "libavutil/internal.h"
#include "libavutil/time.h"
#include "avdevice.h"
-static const int avf_time_base = 100;
+static const int avf_time_base = 1000000;
static const AVRational avf_time_base_q = {
.num = 1,
{
AVClass* class;
- float frame_rate;
int frames_captured;
+ int audio_frames_captured;
int64_t first_pts;
+ int64_t first_audio_pts;
pthread_mutex_t frame_lock;
pthread_cond_t frame_wait_cond;
id avf_delegate;
+ id avf_audio_delegate;
int list_devices;
int video_device_index;
+ int video_stream_index;
+ int audio_device_index;
+ int audio_stream_index;
+
+ char *video_filename;
+ char *audio_filename;
+
+ int num_video_devices;
+
+ int audio_channels;
+ int audio_bits_per_sample;
+ int audio_float;
+ int audio_be;
+ int audio_signed_integer;
+ int audio_packed;
+ int audio_non_interleaved;
+
+ int32_t *audio_buffer;
+ int audio_buffer_size;
+
enum AVPixelFormat pixel_format;
AVCaptureSession *capture_session;
AVCaptureVideoDataOutput *video_output;
+ AVCaptureAudioDataOutput *audio_output;
CMSampleBufferRef current_frame;
+ CMSampleBufferRef current_audio_frame;
} AVFContext;
static void lock_frames(AVFContext* ctx)
@end
+/** AudioReciever class - delegate for AVCaptureSession
+ */
+@interface AVFAudioReceiver : NSObject
+{
+ AVFContext* _context;
+}
+
+- (id)initWithContext:(AVFContext*)context;
+
+- (void) captureOutput:(AVCaptureOutput *)captureOutput
+ didOutputSampleBuffer:(CMSampleBufferRef)audioFrame
+ fromConnection:(AVCaptureConnection *)connection;
+
+@end
+
+@implementation AVFAudioReceiver
+
+- (id)initWithContext:(AVFContext*)context
+{
+ if (self = [super init]) {
+ _context = context;
+ }
+ return self;
+}
+
+- (void) captureOutput:(AVCaptureOutput *)captureOutput
+ didOutputSampleBuffer:(CMSampleBufferRef)audioFrame
+ fromConnection:(AVCaptureConnection *)connection
+{
+ lock_frames(_context);
+
+ if (_context->current_audio_frame != nil) {
+ CFRelease(_context->current_audio_frame);
+ }
+
+ _context->current_audio_frame = (CMSampleBufferRef)CFRetain(audioFrame);
+
+ pthread_cond_signal(&_context->frame_wait_cond);
+
+ unlock_frames(_context);
+
+ ++_context->audio_frames_captured;
+}
+
+@end
+
static void destroy_context(AVFContext* ctx)
{
[ctx->capture_session stopRunning];
[ctx->capture_session release];
[ctx->video_output release];
+ [ctx->audio_output release];
[ctx->avf_delegate release];
+ [ctx->avf_audio_delegate release];
ctx->capture_session = NULL;
ctx->video_output = NULL;
+ ctx->audio_output = NULL;
ctx->avf_delegate = NULL;
+ ctx->avf_audio_delegate = NULL;
+
+ av_freep(&ctx->audio_buffer);
pthread_mutex_destroy(&ctx->frame_lock);
pthread_cond_destroy(&ctx->frame_wait_cond);
}
}
-static int avf_read_header(AVFormatContext *s)
+static void parse_device_name(AVFormatContext *s)
{
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- AVFContext *ctx = (AVFContext*)s->priv_data;
- ctx->first_pts = av_gettime();
-
- pthread_mutex_init(&ctx->frame_lock, NULL);
- pthread_cond_init(&ctx->frame_wait_cond, NULL);
-
- // List devices if requested
- if (ctx->list_devices) {
- av_log(ctx, AV_LOG_INFO, "AVFoundation video devices:\n");
- NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
- for (AVCaptureDevice *device in devices) {
- const char *name = [[device localizedName] UTF8String];
- int index = [devices indexOfObject:device];
- av_log(ctx, AV_LOG_INFO, "[%d] %s\n", index, name);
- }
- goto fail;
- }
-
- // Find capture device
- AVCaptureDevice *video_device = nil;
-
- // check for device index given in filename
- if (ctx->video_device_index == -1) {
- sscanf(s->filename, "%d", &ctx->video_device_index);
- }
-
- if (ctx->video_device_index >= 0) {
- NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
-
- if (ctx->video_device_index >= [devices count]) {
- av_log(ctx, AV_LOG_ERROR, "Invalid device index\n");
- goto fail;
- }
-
- video_device = [devices objectAtIndex:ctx->video_device_index];
- } else if (strncmp(s->filename, "", 1) &&
- strncmp(s->filename, "default", 7)) {
- NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
-
- for (AVCaptureDevice *device in devices) {
- if (!strncmp(s->filename, [[device localizedName] UTF8String], strlen(s->filename))) {
- video_device = device;
- break;
- }
- }
+ AVFContext *ctx = (AVFContext*)s->priv_data;
+ char *tmp = av_strdup(s->filename);
+ char *save;
- if (!video_device) {
- av_log(ctx, AV_LOG_ERROR, "Video device not found\n");
- goto fail;
- }
+ if (tmp[0] != ':') {
+ ctx->video_filename = av_strtok(tmp, ":", &save);
+ ctx->audio_filename = av_strtok(NULL, ":", &save);
} else {
- video_device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeMuxed];
+ ctx->audio_filename = av_strtok(tmp, ":", &save);
}
+}
- // Video capture device not found, looking for AVMediaTypeVideo
- if (!video_device) {
- video_device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
+static int add_video_device(AVFormatContext *s, AVCaptureDevice *video_device)
+{
+ AVFContext *ctx = (AVFContext*)s->priv_data;
+ NSError *error = nil;
+ AVCaptureInput* capture_input = nil;
- if (!video_device) {
- av_log(s, AV_LOG_ERROR, "No AV capture device found\n");
- goto fail;
- }
+ if (ctx->video_device_index < ctx->num_video_devices) {
+ capture_input = (AVCaptureInput*) [[[AVCaptureDeviceInput alloc] initWithDevice:video_device error:&error] autorelease];
+ } else {
+ capture_input = (AVCaptureInput*) video_device;
}
- NSString* dev_display_name = [video_device localizedName];
- av_log(s, AV_LOG_DEBUG, "'%s' opened\n", [dev_display_name UTF8String]);
-
- // Initialize capture session
- ctx->capture_session = [[AVCaptureSession alloc] init];
-
- NSError *error = nil;
- AVCaptureDeviceInput* capture_dev_input = [[[AVCaptureDeviceInput alloc] initWithDevice:video_device error:&error] autorelease];
-
- if (!capture_dev_input) {
+ if (!capture_input) {
av_log(s, AV_LOG_ERROR, "Failed to create AV capture input device: %s\n",
[[error localizedDescription] UTF8String]);
- goto fail;
- }
-
- if (!capture_dev_input) {
- av_log(s, AV_LOG_ERROR, "Failed to add AV capture input device to session: %s\n",
- [[error localizedDescription] UTF8String]);
- goto fail;
+ return 1;
}
- if ([ctx->capture_session canAddInput:capture_dev_input]) {
- [ctx->capture_session addInput:capture_dev_input];
+ if ([ctx->capture_session canAddInput:capture_input]) {
+ [ctx->capture_session addInput:capture_input];
} else {
av_log(s, AV_LOG_ERROR, "can't add video input to capture session\n");
- goto fail;
+ return 1;
}
// Attaching output
if (!ctx->video_output) {
av_log(s, AV_LOG_ERROR, "Failed to init AV video output\n");
- goto fail;
+ return 1;
}
// select pixel format
if (pxl_fmt_spec.ff_id == AV_PIX_FMT_NONE) {
av_log(s, AV_LOG_ERROR, "Selected pixel format (%s) is not supported by AVFoundation.\n",
av_get_pix_fmt_name(pxl_fmt_spec.ff_id));
- goto fail;
+ return 1;
}
// check if the pixel format is available for this device
// fail if there is no appropriate pixel format or print a warning about overriding the pixel format
if (pxl_fmt_spec.ff_id == AV_PIX_FMT_NONE) {
- goto fail;
+ return 1;
} else {
av_log(s, AV_LOG_WARNING, "Overriding selected pixel format to use %s instead.\n",
av_get_pix_fmt_name(pxl_fmt_spec.ff_id));
}
}
-
+ ctx->pixel_format = pxl_fmt_spec.ff_id;
NSNumber *pixel_format = [NSNumber numberWithUnsignedInt:pxl_fmt_spec.avf_id];
NSDictionary *capture_dict = [NSDictionary dictionaryWithObject:pixel_format
forKey:(id)kCVPixelBufferPixelFormatTypeKey];
[ctx->capture_session addOutput:ctx->video_output];
} else {
av_log(s, AV_LOG_ERROR, "can't add video output to capture session\n");
- goto fail;
+ return 1;
}
- [ctx->capture_session startRunning];
+ return 0;
+}
+
+static int add_audio_device(AVFormatContext *s, AVCaptureDevice *audio_device)
+{
+ AVFContext *ctx = (AVFContext*)s->priv_data;
+ NSError *error = nil;
+ AVCaptureDeviceInput* audio_dev_input = [[[AVCaptureDeviceInput alloc] initWithDevice:audio_device error:&error] autorelease];
+
+ if (!audio_dev_input) {
+ av_log(s, AV_LOG_ERROR, "Failed to create AV capture input device: %s\n",
+ [[error localizedDescription] UTF8String]);
+ return 1;
+ }
+
+ if ([ctx->capture_session canAddInput:audio_dev_input]) {
+ [ctx->capture_session addInput:audio_dev_input];
+ } else {
+ av_log(s, AV_LOG_ERROR, "can't add audio input to capture session\n");
+ return 1;
+ }
+
+ // Attaching output
+ ctx->audio_output = [[AVCaptureAudioDataOutput alloc] init];
+
+ if (!ctx->audio_output) {
+ av_log(s, AV_LOG_ERROR, "Failed to init AV audio output\n");
+ return 1;
+ }
+
+ ctx->avf_audio_delegate = [[AVFAudioReceiver alloc] initWithContext:ctx];
+
+ dispatch_queue_t queue = dispatch_queue_create("avf_audio_queue", NULL);
+ [ctx->audio_output setSampleBufferDelegate:ctx->avf_audio_delegate queue:queue];
+ dispatch_release(queue);
+
+ if ([ctx->capture_session canAddOutput:ctx->audio_output]) {
+ [ctx->capture_session addOutput:ctx->audio_output];
+ } else {
+ av_log(s, AV_LOG_ERROR, "adding audio output to capture session failed\n");
+ return 1;
+ }
+
+ return 0;
+}
+
+static int get_video_config(AVFormatContext *s)
+{
+ AVFContext *ctx = (AVFContext*)s->priv_data;
// Take stream info from the first frame.
while (ctx->frames_captured < 1) {
AVStream* stream = avformat_new_stream(s, NULL);
if (!stream) {
- goto fail;
+ return 1;
}
+ ctx->video_stream_index = stream->index;
+
avpriv_set_pts_info(stream, 64, 1, avf_time_base);
CVImageBufferRef image_buffer = CMSampleBufferGetImageBuffer(ctx->current_frame);
stream->codec->codec_type = AVMEDIA_TYPE_VIDEO;
stream->codec->width = (int)image_buffer_size.width;
stream->codec->height = (int)image_buffer_size.height;
- stream->codec->pix_fmt = pxl_fmt_spec.ff_id;
+ stream->codec->pix_fmt = ctx->pixel_format;
CFRelease(ctx->current_frame);
ctx->current_frame = nil;
unlock_frames(ctx);
+
+ return 0;
+}
+
+static int get_audio_config(AVFormatContext *s)
+{
+ AVFContext *ctx = (AVFContext*)s->priv_data;
+
+ // Take stream info from the first frame.
+ while (ctx->audio_frames_captured < 1) {
+ CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.1, YES);
+ }
+
+ lock_frames(ctx);
+
+ AVStream* stream = avformat_new_stream(s, NULL);
+
+ if (!stream) {
+ return 1;
+ }
+
+ ctx->audio_stream_index = stream->index;
+
+ avpriv_set_pts_info(stream, 64, 1, avf_time_base);
+
+ CMFormatDescriptionRef format_desc = CMSampleBufferGetFormatDescription(ctx->current_audio_frame);
+ const AudioStreamBasicDescription *basic_desc = CMAudioFormatDescriptionGetStreamBasicDescription(format_desc);
+
+ if (!basic_desc) {
+ av_log(s, AV_LOG_ERROR, "audio format not available\n");
+ return 1;
+ }
+
+ stream->codec->codec_type = AVMEDIA_TYPE_AUDIO;
+ stream->codec->sample_rate = basic_desc->mSampleRate;
+ stream->codec->channels = basic_desc->mChannelsPerFrame;
+ stream->codec->channel_layout = av_get_default_channel_layout(stream->codec->channels);
+
+ ctx->audio_channels = basic_desc->mChannelsPerFrame;
+ ctx->audio_bits_per_sample = basic_desc->mBitsPerChannel;
+ ctx->audio_float = basic_desc->mFormatFlags & kAudioFormatFlagIsFloat;
+ ctx->audio_be = basic_desc->mFormatFlags & kAudioFormatFlagIsBigEndian;
+ ctx->audio_signed_integer = basic_desc->mFormatFlags & kAudioFormatFlagIsSignedInteger;
+ ctx->audio_packed = basic_desc->mFormatFlags & kAudioFormatFlagIsPacked;
+ ctx->audio_non_interleaved = basic_desc->mFormatFlags & kAudioFormatFlagIsNonInterleaved;
+
+ if (basic_desc->mFormatID == kAudioFormatLinearPCM &&
+ ctx->audio_float &&
+ ctx->audio_packed) {
+ stream->codec->codec_id = ctx->audio_be ? AV_CODEC_ID_PCM_F32BE : AV_CODEC_ID_PCM_F32LE;
+ } else {
+ av_log(s, AV_LOG_ERROR, "audio format is not supported\n");
+ return 1;
+ }
+
+ if (ctx->audio_non_interleaved) {
+ CMBlockBufferRef block_buffer = CMSampleBufferGetDataBuffer(ctx->current_audio_frame);
+ ctx->audio_buffer_size = CMBlockBufferGetDataLength(block_buffer);
+ ctx->audio_buffer = av_malloc(ctx->audio_buffer_size);
+ if (!ctx->audio_buffer) {
+ av_log(s, AV_LOG_ERROR, "error allocating audio buffer\n");
+ return 1;
+ }
+ }
+
+ CFRelease(ctx->current_audio_frame);
+ ctx->current_audio_frame = nil;
+
+ unlock_frames(ctx);
+
+ return 0;
+}
+
+static int avf_read_header(AVFormatContext *s)
+{
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ AVFContext *ctx = (AVFContext*)s->priv_data;
+ ctx->first_pts = av_gettime();
+ ctx->first_audio_pts = av_gettime();
+ uint32_t num_screens = 0;
+
+ pthread_mutex_init(&ctx->frame_lock, NULL);
+ pthread_cond_init(&ctx->frame_wait_cond, NULL);
+
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070
+ CGGetActiveDisplayList(0, NULL, &num_screens);
+#endif
+
+ // List devices if requested
+ if (ctx->list_devices) {
+ av_log(ctx, AV_LOG_INFO, "AVFoundation video devices:\n");
+ NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
+ int index = 0;
+ for (AVCaptureDevice *device in devices) {
+ const char *name = [[device localizedName] UTF8String];
+ index = [devices indexOfObject:device];
+ av_log(ctx, AV_LOG_INFO, "[%d] %s\n", index, name);
+ index++;
+ }
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070
+ if (num_screens > 0) {
+ CGDirectDisplayID screens[num_screens];
+ CGGetActiveDisplayList(num_screens, screens, &num_screens);
+ for (int i = 0; i < num_screens; i++) {
+ av_log(ctx, AV_LOG_INFO, "[%d] Capture screen %d\n", index + i, i);
+ }
+ }
+#endif
+
+ av_log(ctx, AV_LOG_INFO, "AVFoundation audio devices:\n");
+ devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeAudio];
+ for (AVCaptureDevice *device in devices) {
+ const char *name = [[device localizedName] UTF8String];
+ int index = [devices indexOfObject:device];
+ av_log(ctx, AV_LOG_INFO, "[%d] %s\n", index, name);
+ }
+ goto fail;
+ }
+
+ // Find capture device
+ AVCaptureDevice *video_device = nil;
+ AVCaptureDevice *audio_device = nil;
+
+ NSArray *video_devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
+ ctx->num_video_devices = [video_devices count];
+
+ // parse input filename for video and audio device
+ parse_device_name(s);
+
+ // check for device index given in filename
+ if (ctx->video_device_index == -1 && ctx->video_filename) {
+ sscanf(ctx->video_filename, "%d", &ctx->video_device_index);
+ }
+ if (ctx->audio_device_index == -1 && ctx->audio_filename) {
+ sscanf(ctx->audio_filename, "%d", &ctx->audio_device_index);
+ }
+
+ if (ctx->video_device_index >= 0) {
+ if (ctx->video_device_index < ctx->num_video_devices) {
+ video_device = [video_devices objectAtIndex:ctx->video_device_index];
+ } else if (ctx->video_device_index < ctx->num_video_devices + num_screens) {
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070
+ CGDirectDisplayID screens[num_screens];
+ CGGetActiveDisplayList(num_screens, screens, &num_screens);
+ AVCaptureScreenInput* capture_screen_input = [[[AVCaptureScreenInput alloc] initWithDisplayID:screens[ctx->video_device_index - ctx->num_video_devices]] autorelease];
+ video_device = (AVCaptureDevice*) capture_screen_input;
+#endif
+ } else {
+ av_log(ctx, AV_LOG_ERROR, "Invalid device index\n");
+ goto fail;
+ }
+ } else if (ctx->video_filename &&
+ strncmp(ctx->video_filename, "none", 4)) {
+ if (!strncmp(ctx->video_filename, "default", 7)) {
+ video_device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
+ } else {
+ // looking for video inputs
+ for (AVCaptureDevice *device in video_devices) {
+ if (!strncmp(ctx->video_filename, [[device localizedName] UTF8String], strlen(ctx->video_filename))) {
+ video_device = device;
+ break;
+ }
+ }
+
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070
+ // looking for screen inputs
+ if (!video_device) {
+ int idx;
+ if(sscanf(ctx->video_filename, "Capture screen %d", &idx) && idx < num_screens) {
+ CGDirectDisplayID screens[num_screens];
+ CGGetActiveDisplayList(num_screens, screens, &num_screens);
+ AVCaptureScreenInput* capture_screen_input = [[[AVCaptureScreenInput alloc] initWithDisplayID:screens[idx]] autorelease];
+ video_device = (AVCaptureDevice*) capture_screen_input;
+ ctx->video_device_index = ctx->num_video_devices + idx;
+ }
+ }
+#endif
+ }
+
+ if (!video_device) {
+ av_log(ctx, AV_LOG_ERROR, "Video device not found\n");
+ goto fail;
+ }
+ }
+
+ // get audio device
+ if (ctx->audio_device_index >= 0) {
+ NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeAudio];
+
+ if (ctx->audio_device_index >= [devices count]) {
+ av_log(ctx, AV_LOG_ERROR, "Invalid audio device index\n");
+ goto fail;
+ }
+
+ audio_device = [devices objectAtIndex:ctx->audio_device_index];
+ } else if (ctx->audio_filename &&
+ strncmp(ctx->audio_filename, "none", 4)) {
+ if (!strncmp(ctx->audio_filename, "default", 7)) {
+ audio_device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeAudio];
+ } else {
+ NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeAudio];
+
+ for (AVCaptureDevice *device in devices) {
+ if (!strncmp(ctx->audio_filename, [[device localizedName] UTF8String], strlen(ctx->audio_filename))) {
+ audio_device = device;
+ break;
+ }
+ }
+ }
+
+ if (!audio_device) {
+ av_log(ctx, AV_LOG_ERROR, "Audio device not found\n");
+ goto fail;
+ }
+ }
+
+ // Video nor Audio capture device not found, looking for AVMediaTypeVideo/Audio
+ if (!video_device && !audio_device) {
+ av_log(s, AV_LOG_ERROR, "No AV capture device found\n");
+ goto fail;
+ }
+
+ if (video_device) {
+ if (ctx->video_device_index < ctx->num_video_devices) {
+ av_log(s, AV_LOG_DEBUG, "'%s' opened\n", [[video_device localizedName] UTF8String]);
+ } else {
+ av_log(s, AV_LOG_DEBUG, "'%s' opened\n", [[video_device description] UTF8String]);
+ }
+ }
+ if (audio_device) {
+ av_log(s, AV_LOG_DEBUG, "audio device '%s' opened\n", [[audio_device localizedName] UTF8String]);
+ }
+
+ // Initialize capture session
+ ctx->capture_session = [[AVCaptureSession alloc] init];
+
+ if (video_device && add_video_device(s, video_device)) {
+ goto fail;
+ }
+ if (audio_device && add_audio_device(s, audio_device)) {
+ }
+
+ [ctx->capture_session startRunning];
+
+ if (video_device && get_video_config(s)) {
+ goto fail;
+ }
+
+ // set audio stream
+ if (audio_device && get_audio_config(s)) {
+ goto fail;
+ }
+
[pool release];
return 0;
pkt->pts = pkt->dts = av_rescale_q(av_gettime() - ctx->first_pts,
AV_TIME_BASE_Q,
avf_time_base_q);
- pkt->stream_index = 0;
+ pkt->stream_index = ctx->video_stream_index;
pkt->flags |= AV_PKT_FLAG_KEY;
CVPixelBufferLockBaseAddress(image_buffer, 0);
CVPixelBufferUnlockBaseAddress(image_buffer, 0);
CFRelease(ctx->current_frame);
ctx->current_frame = nil;
+ } else if (ctx->current_audio_frame != nil) {
+ CMBlockBufferRef block_buffer = CMSampleBufferGetDataBuffer(ctx->current_audio_frame);
+ int block_buffer_size = CMBlockBufferGetDataLength(block_buffer);
+
+ if (!block_buffer || !block_buffer_size) {
+ return AVERROR(EIO);
+ }
+
+ if (ctx->audio_non_interleaved && block_buffer_size > ctx->audio_buffer_size) {
+ return AVERROR_BUFFER_TOO_SMALL;
+ }
+
+ if (av_new_packet(pkt, block_buffer_size) < 0) {
+ return AVERROR(EIO);
+ }
+
+ pkt->pts = pkt->dts = av_rescale_q(av_gettime() - ctx->first_audio_pts,
+ AV_TIME_BASE_Q,
+ avf_time_base_q);
+
+ pkt->stream_index = ctx->audio_stream_index;
+ pkt->flags |= AV_PKT_FLAG_KEY;
+
+ if (ctx->audio_non_interleaved) {
+ int sample, c, shift;
+
+ OSStatus ret = CMBlockBufferCopyDataBytes(block_buffer, 0, pkt->size, ctx->audio_buffer);
+ if (ret != kCMBlockBufferNoErr) {
+ return AVERROR(EIO);
+ }
+
+ int num_samples = pkt->size / (ctx->audio_channels * (ctx->audio_bits_per_sample >> 3));
+
+ // transform decoded frame into output format
+ #define INTERLEAVE_OUTPUT(bps) \
+ { \
+ int##bps##_t **src; \
+ int##bps##_t *dest; \
+ src = av_malloc(ctx->audio_channels * sizeof(int##bps##_t*)); \
+ if (!src) return AVERROR(EIO); \
+ for (c = 0; c < ctx->audio_channels; c++) { \
+ src[c] = ((int##bps##_t*)ctx->audio_buffer) + c * num_samples; \
+ } \
+ dest = (int##bps##_t*)pkt->data; \
+ shift = bps - ctx->audio_bits_per_sample; \
+ for (sample = 0; sample < num_samples; sample++) \
+ for (c = 0; c < ctx->audio_channels; c++) \
+ *dest++ = src[c][sample] << shift; \
+ av_freep(&src); \
+ }
+
+ if (ctx->audio_bits_per_sample <= 16) {
+ INTERLEAVE_OUTPUT(16)
+ } else {
+ INTERLEAVE_OUTPUT(32)
+ }
+ } else {
+ OSStatus ret = CMBlockBufferCopyDataBytes(block_buffer, 0, pkt->size, pkt->data);
+ if (ret != kCMBlockBufferNoErr) {
+ return AVERROR(EIO);
+ }
+ }
+
+ CFRelease(ctx->current_audio_frame);
+ ctx->current_audio_frame = nil;
} else {
pkt->data = NULL;
pthread_cond_wait(&ctx->frame_wait_cond, &ctx->frame_lock);
}
static const AVOption options[] = {
- { "frame_rate", "set frame rate", offsetof(AVFContext, frame_rate), AV_OPT_TYPE_FLOAT, { .dbl = 30.0 }, 0.1, 30.0, AV_OPT_TYPE_VIDEO_RATE, NULL },
{ "list_devices", "list available devices", offsetof(AVFContext, list_devices), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, AV_OPT_FLAG_DECODING_PARAM, "list_devices" },
{ "true", "", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, AV_OPT_FLAG_DECODING_PARAM, "list_devices" },
{ "false", "", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, AV_OPT_FLAG_DECODING_PARAM, "list_devices" },
{ "video_device_index", "select video device by index for devices with same name (starts at 0)", offsetof(AVFContext, video_device_index), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, AV_OPT_FLAG_DECODING_PARAM },
+ { "audio_device_index", "select audio device by index for devices with same name (starts at 0)", offsetof(AVFContext, audio_device_index), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, AV_OPT_FLAG_DECODING_PARAM },
{ "pixel_format", "set pixel format", offsetof(AVFContext, pixel_format), AV_OPT_TYPE_PIXEL_FMT, {.i64 = AV_PIX_FMT_YUV420P}, 0, INT_MAX, AV_OPT_FLAG_DECODING_PARAM},
{ NULL },
};
c->canvas = caca_create_canvas(c->window_width, c->window_height);
if (!c->canvas) {
- av_log(s, AV_LOG_ERROR, "Failed to create canvas\n");
ret = AVERROR(errno);
+ av_log(s, AV_LOG_ERROR, "Failed to create canvas\n");
goto fail;
}
bpp / 8 * encctx->width,
0x0000ff, 0x00ff00, 0xff0000, 0);
if (!c->dither) {
- av_log(s, AV_LOG_ERROR, "Failed to create dither\n");
ret = AVERROR(errno);
+ av_log(s, AV_LOG_ERROR, "Failed to create dither\n");
goto fail;
}
c->display = caca_create_display_with_driver(c->canvas, c->driver);
if (!c->display) {
+ ret = AVERROR(errno);
av_log(s, AV_LOG_ERROR, "Failed to create display\n");
list_drivers(c);
- ret = AVERROR(errno);
goto fail;
}
--- /dev/null
+/*
+ * Blackmagic DeckLink output
+ * Copyright (c) 2013-2014 Ramiro Polla, Luca Barbato, Deti Fliegl
+ *
+ * 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 <DeckLinkAPI.h>
+#ifdef _WIN32
+#include <DeckLinkAPI_i.c>
+#else
+#include <DeckLinkAPIDispatch.cpp>
+#endif
+
+#include <pthread.h>
+#include <semaphore.h>
+
+extern "C" {
+#include "libavformat/avformat.h"
+#include "libavformat/internal.h"
+#include "libavutil/imgutils.h"
+}
+
+#include "decklink_common.h"
+
+#ifdef _WIN32
+IDeckLinkIterator *CreateDeckLinkIteratorInstance(void)
+{
+ IDeckLinkIterator *iter;
+
+ if (CoInitialize(NULL) < 0) {
+ av_log(NULL, AV_LOG_ERROR, "COM initialization failed.\n");
+ return NULL;
+ }
+
+ if (CoCreateInstance(CLSID_CDeckLinkIterator, NULL, CLSCTX_ALL,
+ IID_IDeckLinkIterator, (void**) &iter) != S_OK) {
+ av_log(NULL, AV_LOG_ERROR, "DeckLink drivers not installed.\n");
+ return NULL;
+ }
+
+ return iter;
+}
+#endif
+
+#ifdef _WIN32
+static char *dup_wchar_to_utf8(wchar_t *w)
+{
+ char *s = NULL;
+ int l = WideCharToMultiByte(CP_UTF8, 0, w, -1, 0, 0, 0, 0);
+ s = (char *) av_malloc(l);
+ if (s)
+ WideCharToMultiByte(CP_UTF8, 0, w, -1, s, l, 0, 0);
+ return s;
+}
+#define DECKLINK_STR OLECHAR *
+#define DECKLINK_STRDUP dup_wchar_to_utf8
+#define DECKLINK_FREE(s) SysFreeString(s)
+#else
+#define DECKLINK_STR const char *
+#define DECKLINK_STRDUP av_strdup
+/* free() is needed for a string returned by the DeckLink SDL. */
+#define DECKLINK_FREE(s) free((void *) s)
+#endif
+
+HRESULT ff_decklink_get_display_name(IDeckLink *This, const char **displayName)
+{
+ DECKLINK_STR tmpDisplayName;
+ HRESULT hr = This->GetDisplayName(&tmpDisplayName);
+ if (hr != S_OK)
+ return hr;
+ *displayName = DECKLINK_STRDUP(tmpDisplayName);
+ DECKLINK_FREE(tmpDisplayName);
+ return hr;
+}
+
+int ff_decklink_set_format(AVFormatContext *avctx,
+ int width, int height,
+ int tb_num, int tb_den,
+ decklink_direction_t direction, int num)
+{
+ struct decklink_cctx *cctx = (struct decklink_cctx *) avctx->priv_data;
+ struct decklink_ctx *ctx = (struct decklink_ctx *)cctx->ctx;
+ BMDDisplayModeSupport support;
+ IDeckLinkDisplayModeIterator *itermode;
+ IDeckLinkDisplayMode *mode;
+ int i = 1;
+ HRESULT res;
+
+ if (direction == DIRECTION_IN) {
+ res = ctx->dli->GetDisplayModeIterator (&itermode);
+ } else {
+ res = ctx->dlo->GetDisplayModeIterator (&itermode);
+ }
+
+ if (res!= S_OK) {
+ av_log(avctx, AV_LOG_ERROR, "Could not get Display Mode Iterator\n");
+ return AVERROR(EIO);
+ }
+
+
+ if (tb_num == 1) {
+ tb_num *= 1000;
+ tb_den *= 1000;
+ }
+ ctx->bmd_mode = bmdModeUnknown;
+ while ((ctx->bmd_mode == bmdModeUnknown) && itermode->Next(&mode) == S_OK) {
+ BMDTimeValue bmd_tb_num, bmd_tb_den;
+ int bmd_width = mode->GetWidth();
+ int bmd_height = mode->GetHeight();
+
+ mode->GetFrameRate(&bmd_tb_num, &bmd_tb_den);
+
+ if ((bmd_width == width && bmd_height == height &&
+ bmd_tb_num == tb_num && bmd_tb_den == tb_den) || i == num) {
+ ctx->bmd_mode = mode->GetDisplayMode();
+ ctx->bmd_width = bmd_width;
+ ctx->bmd_height = bmd_height;
+ ctx->bmd_tb_den = bmd_tb_den;
+ ctx->bmd_tb_num = bmd_tb_num;
+ ctx->bmd_field_dominance = mode->GetFieldDominance();
+ av_log(avctx, AV_LOG_INFO, "Found Decklink mode %d x %d with rate %.2f%s\n",
+ bmd_width, bmd_height, (float)bmd_tb_den/(float)bmd_tb_num,
+ (ctx->bmd_field_dominance==bmdLowerFieldFirst || ctx->bmd_field_dominance==bmdUpperFieldFirst)?"(i)":"");
+ }
+
+ mode->Release();
+ i++;
+ }
+
+ itermode->Release();
+
+ if (ctx->bmd_mode == bmdModeUnknown)
+ return -1;
+ if (direction == DIRECTION_IN) {
+ if (ctx->dli->DoesSupportVideoMode(ctx->bmd_mode, bmdFormat8BitYUV,
+ bmdVideoOutputFlagDefault,
+ &support, NULL) != S_OK)
+ return -1;
+ } else {
+ if (ctx->dlo->DoesSupportVideoMode(ctx->bmd_mode, bmdFormat8BitYUV,
+ bmdVideoOutputFlagDefault,
+ &support, NULL) != S_OK)
+ return -1;
+ }
+ if (support == bmdDisplayModeSupported)
+ return 0;
+
+ return -1;
+}
+
+int ff_decklink_set_format(AVFormatContext *avctx, decklink_direction_t direction, int num) {
+ return ff_decklink_set_format(avctx, 0, 0, 0, 0, direction, num);
+}
+
+int ff_decklink_list_devices(AVFormatContext *avctx)
+{
+ IDeckLink *dl = NULL;
+ IDeckLinkIterator *iter = CreateDeckLinkIteratorInstance();
+ if (!iter) {
+ av_log(avctx, AV_LOG_ERROR, "Could not create DeckLink iterator\n");
+ return AVERROR(EIO);
+ }
+ av_log(avctx, AV_LOG_INFO, "Blackmagic DeckLink devices:\n");
+ while (iter->Next(&dl) == S_OK) {
+ const char *displayName;
+ ff_decklink_get_display_name(dl, &displayName);
+ av_log(avctx, AV_LOG_INFO, "\t'%s'\n", displayName);
+ av_free((void *) displayName);
+ dl->Release();
+ }
+ iter->Release();
+ return 0;
+}
+
+int ff_decklink_list_formats(AVFormatContext *avctx, decklink_direction_t direction)
+{
+ struct decklink_cctx *cctx = (struct decklink_cctx *) avctx->priv_data;
+ struct decklink_ctx *ctx = (struct decklink_ctx *)cctx->ctx;
+ IDeckLinkDisplayModeIterator *itermode;
+ IDeckLinkDisplayMode *mode;
+ int i=0;
+ HRESULT res;
+
+ if (direction == DIRECTION_IN) {
+ res = ctx->dli->GetDisplayModeIterator (&itermode);
+ } else {
+ res = ctx->dlo->GetDisplayModeIterator (&itermode);
+ }
+
+ if (res!= S_OK) {
+ av_log(avctx, AV_LOG_ERROR, "Could not get Display Mode Iterator\n");
+ return AVERROR(EIO);
+ }
+
+ av_log(avctx, AV_LOG_INFO, "Supported formats for '%s':\n",
+ avctx->filename);
+ while (itermode->Next(&mode) == S_OK) {
+ BMDTimeValue tb_num, tb_den;
+ mode->GetFrameRate(&tb_num, &tb_den);
+ av_log(avctx, AV_LOG_INFO, "\t%d\t%ldx%ld at %d/%d fps",
+ ++i,mode->GetWidth(), mode->GetHeight(),
+ (int) tb_den, (int) tb_num);
+ switch (mode->GetFieldDominance()) {
+ case bmdLowerFieldFirst:
+ av_log(avctx, AV_LOG_INFO, " (interlaced, lower field first)"); break;
+ case bmdUpperFieldFirst:
+ av_log(avctx, AV_LOG_INFO, " (interlaced, upper field first)"); break;
+ }
+ av_log(avctx, AV_LOG_INFO, "\n");
+ mode->Release();
+ }
+
+ itermode->Release();
+
+ return 0;
+}
--- /dev/null
+/*
+ * Blackmagic DeckLink common code
+ * Copyright (c) 2013-2014 Ramiro Polla, Luca Barbato, Deti Fliegl
+ *
+ * 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 "decklink_common_c.h"
+
+class decklink_output_callback;
+class decklink_input_callback;
+
+typedef struct AVPacketQueue {
+ AVPacketList *first_pkt, *last_pkt;
+ int nb_packets;
+ unsigned long long size;
+ int abort_request;
+ pthread_mutex_t mutex;
+ pthread_cond_t cond;
+ AVFormatContext *avctx;
+} AVPacketQueue;
+
+struct decklink_ctx {
+ /* DeckLink SDK interfaces */
+ IDeckLink *dl;
+ IDeckLinkOutput *dlo;
+ IDeckLinkInput *dli;
+ decklink_output_callback *output_callback;
+ decklink_input_callback *input_callback;
+
+ /* DeckLink mode information */
+ BMDTimeValue bmd_tb_den;
+ BMDTimeValue bmd_tb_num;
+ BMDDisplayMode bmd_mode;
+ int bmd_width;
+ int bmd_height;
+ int bmd_field_dominance;
+
+ /* Capture buffer queue */
+ AVPacketQueue queue;
+
+ /* Streams present */
+ int audio;
+ int video;
+
+ /* Status */
+ int playback_started;
+ int capture_started;
+ int64_t last_pts;
+ unsigned long frameCount;
+ unsigned int dropped;
+ AVStream *audio_st;
+ AVStream *video_st;
+
+ /* Options */
+ int list_devices;
+ int list_formats;
+ double preroll;
+
+ int frames_preroll;
+ int frames_buffer;
+
+ sem_t semaphore;
+
+ int channels;
+};
+
+typedef enum { DIRECTION_IN, DIRECTION_OUT} decklink_direction_t;
+
+#ifdef _WIN32
+typedef unsigned long buffercount_type;
+IDeckLinkIterator *CreateDeckLinkIteratorInstance(void);
+#else
+typedef uint32_t buffercount_type;
+#endif
+
+
+HRESULT ff_decklink_get_display_name(IDeckLink *This, const char **displayName);
+int ff_decklink_set_format(AVFormatContext *avctx, int width, int height, int tb_num, int tb_den, decklink_direction_t direction = DIRECTION_OUT, int num = 0);
+int ff_decklink_set_format(AVFormatContext *avctx, decklink_direction_t direction, int num);
+int ff_decklink_list_devices(AVFormatContext *avctx);
+int ff_decklink_list_formats(AVFormatContext *avctx, decklink_direction_t direction = DIRECTION_OUT);
+
--- /dev/null
+/*
+ * Blackmagic DeckLink common code
+ * Copyright (c) 2013-2014 Ramiro Polla
+ *
+ * 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
+ */
+
+struct decklink_cctx {
+ const AVClass *cclass;
+
+ void *ctx;
+
+ /* Options */
+ int list_devices;
+ int list_formats;
+ double preroll;
+};
+
--- /dev/null
+/*
+ * Blackmagic DeckLink output
+ * Copyright (c) 2013-2014 Luca Barbato, Deti Fliegl
+ *
+ * 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 <DeckLinkAPI.h>
+
+#include <pthread.h>
+#include <semaphore.h>
+
+extern "C" {
+#include "libavformat/avformat.h"
+#include "libavformat/internal.h"
+#include "libavutil/imgutils.h"
+}
+
+#include "decklink_common.h"
+#include "decklink_dec.h"
+
+static void avpacket_queue_init(AVFormatContext *avctx, AVPacketQueue *q)
+{
+ memset(q, 0, sizeof(AVPacketQueue));
+ pthread_mutex_init(&q->mutex, NULL);
+ pthread_cond_init(&q->cond, NULL);
+ q->avctx = avctx;
+}
+
+static void avpacket_queue_flush(AVPacketQueue *q)
+{
+ AVPacketList *pkt, *pkt1;
+
+ pthread_mutex_lock(&q->mutex);
+ for (pkt = q->first_pkt; pkt != NULL; pkt = pkt1) {
+ pkt1 = pkt->next;
+ av_free_packet(&pkt->pkt);
+ av_freep(&pkt);
+ }
+ q->last_pkt = NULL;
+ q->first_pkt = NULL;
+ q->nb_packets = 0;
+ q->size = 0;
+ pthread_mutex_unlock(&q->mutex);
+}
+
+static void avpacket_queue_end(AVPacketQueue *q)
+{
+ avpacket_queue_flush(q);
+ pthread_mutex_destroy(&q->mutex);
+ pthread_cond_destroy(&q->cond);
+}
+
+static unsigned long long avpacket_queue_size(AVPacketQueue *q)
+{
+ unsigned long long size;
+ pthread_mutex_lock(&q->mutex);
+ size = q->size;
+ pthread_mutex_unlock(&q->mutex);
+ return size;
+}
+
+static int avpacket_queue_put(AVPacketQueue *q, AVPacket *pkt)
+{
+ AVPacketList *pkt1;
+
+ // Drop Packet if queue size is > 1GB
+ if (avpacket_queue_size(q) > 1024 * 1024 * 1024 ) {
+ av_log(q->avctx, AV_LOG_WARNING, "Decklink input buffer overrun!\n");
+ return -1;
+ }
+ /* duplicate the packet */
+ if (av_dup_packet(pkt) < 0) {
+ return -1;
+ }
+
+ pkt1 = (AVPacketList *)av_malloc(sizeof(AVPacketList));
+ if (!pkt1) {
+ return -1;
+ }
+ pkt1->pkt = *pkt;
+ pkt1->next = NULL;
+
+ pthread_mutex_lock(&q->mutex);
+
+ if (!q->last_pkt) {
+ q->first_pkt = pkt1;
+ } else {
+ q->last_pkt->next = pkt1;
+ }
+
+ q->last_pkt = pkt1;
+ q->nb_packets++;
+ q->size += pkt1->pkt.size + sizeof(*pkt1);
+
+ pthread_cond_signal(&q->cond);
+
+ pthread_mutex_unlock(&q->mutex);
+ return 0;
+}
+
+static int avpacket_queue_get(AVPacketQueue *q, AVPacket *pkt, int block)
+{
+ AVPacketList *pkt1;
+ int ret;
+
+ pthread_mutex_lock(&q->mutex);
+
+ for (;; ) {
+ pkt1 = q->first_pkt;
+ if (pkt1) {
+ q->first_pkt = pkt1->next;
+ if (!q->first_pkt) {
+ q->last_pkt = NULL;
+ }
+ q->nb_packets--;
+ q->size -= pkt1->pkt.size + sizeof(*pkt1);
+ *pkt = pkt1->pkt;
+ av_free(pkt1);
+ ret = 1;
+ break;
+ } else if (!block) {
+ ret = 0;
+ break;
+ } else {
+ pthread_cond_wait(&q->cond, &q->mutex);
+ }
+ }
+ pthread_mutex_unlock(&q->mutex);
+ return ret;
+}
+
+class decklink_input_callback : public IDeckLinkInputCallback
+{
+public:
+ decklink_input_callback(AVFormatContext *_avctx);
+ ~decklink_input_callback();
+
+ virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, LPVOID *ppv) { return E_NOINTERFACE; }
+ virtual ULONG STDMETHODCALLTYPE AddRef(void);
+ virtual ULONG STDMETHODCALLTYPE Release(void);
+ virtual HRESULT STDMETHODCALLTYPE VideoInputFormatChanged(BMDVideoInputFormatChangedEvents, IDeckLinkDisplayMode*, BMDDetectedVideoInputFormatFlags);
+ virtual HRESULT STDMETHODCALLTYPE VideoInputFrameArrived(IDeckLinkVideoInputFrame*, IDeckLinkAudioInputPacket*);
+
+private:
+ ULONG m_refCount;
+ pthread_mutex_t m_mutex;
+ AVFormatContext *avctx;
+ decklink_ctx *ctx;
+ int no_video;
+ int64_t initial_video_pts;
+ int64_t initial_audio_pts;
+};
+
+decklink_input_callback::decklink_input_callback(AVFormatContext *_avctx) : m_refCount(0)
+{
+ avctx = _avctx;
+ decklink_cctx *cctx = (struct decklink_cctx *) avctx->priv_data;
+ ctx = (struct decklink_ctx *) cctx->ctx;
+ initial_audio_pts = initial_video_pts = AV_NOPTS_VALUE;
+ pthread_mutex_init(&m_mutex, NULL);
+}
+
+decklink_input_callback::~decklink_input_callback()
+{
+ pthread_mutex_destroy(&m_mutex);
+}
+
+ULONG decklink_input_callback::AddRef(void)
+{
+ pthread_mutex_lock(&m_mutex);
+ m_refCount++;
+ pthread_mutex_unlock(&m_mutex);
+
+ return (ULONG)m_refCount;
+}
+
+ULONG decklink_input_callback::Release(void)
+{
+ pthread_mutex_lock(&m_mutex);
+ m_refCount--;
+ pthread_mutex_unlock(&m_mutex);
+
+ if (m_refCount == 0) {
+ delete this;
+ return 0;
+ }
+
+ return (ULONG)m_refCount;
+}
+
+HRESULT decklink_input_callback::VideoInputFrameArrived(
+ IDeckLinkVideoInputFrame *videoFrame, IDeckLinkAudioInputPacket *audioFrame)
+{
+ void *frameBytes;
+ void *audioFrameBytes;
+ BMDTimeValue frameTime;
+ BMDTimeValue frameDuration;
+
+ ctx->frameCount++;
+
+ // Handle Video Frame
+ if (videoFrame) {
+ AVPacket pkt;
+ AVCodecContext *c;
+ av_init_packet(&pkt);
+ c = ctx->video_st->codec;
+ if (ctx->frameCount % 25 == 0) {
+ unsigned long long qsize = avpacket_queue_size(&ctx->queue);
+ av_log(avctx, AV_LOG_DEBUG,
+ "Frame received (#%lu) - Valid (%liB) - QSize %fMB\n",
+ ctx->frameCount,
+ videoFrame->GetRowBytes() * videoFrame->GetHeight(),
+ (double)qsize / 1024 / 1024);
+ }
+
+ videoFrame->GetBytes(&frameBytes);
+ videoFrame->GetStreamTime(&frameTime, &frameDuration,
+ ctx->video_st->time_base.den);
+
+ if (videoFrame->GetFlags() & bmdFrameHasNoInputSource) {
+ unsigned bars[8] = {
+ 0xEA80EA80, 0xD292D210, 0xA910A9A5, 0x90229035,
+ 0x6ADD6ACA, 0x51EF515A, 0x286D28EF, 0x10801080 };
+ int width = videoFrame->GetWidth();
+ int height = videoFrame->GetHeight();
+ unsigned *p = (unsigned *)frameBytes;
+
+ for (int y = 0; y < height; y++) {
+ for (int x = 0; x < width; x += 2)
+ *p++ = bars[(x * 8) / width];
+ }
+
+ if (!no_video) {
+ av_log(avctx, AV_LOG_WARNING, "Frame received (#%lu) - No input signal detected "
+ "- Frames dropped %u\n", ctx->frameCount, ++ctx->dropped);
+ }
+ no_video = 1;
+ } else {
+ if (no_video) {
+ av_log(avctx, AV_LOG_WARNING, "Frame received (#%lu) - Input returned "
+ "- Frames dropped %u\n", ctx->frameCount, ++ctx->dropped);
+ }
+ no_video = 0;
+ }
+
+ pkt.pts = frameTime / ctx->video_st->time_base.num;
+
+ if (initial_video_pts == AV_NOPTS_VALUE) {
+ initial_video_pts = pkt.pts;
+ }
+
+ pkt.pts -= initial_video_pts;
+ pkt.dts = pkt.pts;
+
+ pkt.duration = frameDuration;
+ //To be made sure it still applies
+ pkt.flags |= AV_PKT_FLAG_KEY;
+ pkt.stream_index = ctx->video_st->index;
+ pkt.data = (uint8_t *)frameBytes;
+ pkt.size = videoFrame->GetRowBytes() *
+ videoFrame->GetHeight();
+ //fprintf(stderr,"Video Frame size %d ts %d\n", pkt.size, pkt.pts);
+ c->frame_number++;
+ if (avpacket_queue_put(&ctx->queue, &pkt) < 0) {
+ ++ctx->dropped;
+ }
+ }
+
+ // Handle Audio Frame
+ if (audioFrame) {
+ AVCodecContext *c;
+ AVPacket pkt;
+ BMDTimeValue audio_pts;
+ av_init_packet(&pkt);
+
+ c = ctx->audio_st->codec;
+ //hack among hacks
+ pkt.size = audioFrame->GetSampleFrameCount() * ctx->audio_st->codec->channels * (16 / 8);
+ audioFrame->GetBytes(&audioFrameBytes);
+ audioFrame->GetPacketTime(&audio_pts, ctx->audio_st->time_base.den);
+ pkt.pts = audio_pts / ctx->audio_st->time_base.num;
+
+ if (initial_audio_pts == AV_NOPTS_VALUE) {
+ initial_audio_pts = pkt.pts;
+ }
+
+ pkt.pts -= initial_audio_pts;
+ pkt.dts = pkt.pts;
+
+ //fprintf(stderr,"Audio Frame size %d ts %d\n", pkt.size, pkt.pts);
+ pkt.flags |= AV_PKT_FLAG_KEY;
+ pkt.stream_index = ctx->audio_st->index;
+ pkt.data = (uint8_t *)audioFrameBytes;
+
+ c->frame_number++;
+ if (avpacket_queue_put(&ctx->queue, &pkt) < 0) {
+ ++ctx->dropped;
+ }
+ }
+
+ return S_OK;
+}
+
+HRESULT decklink_input_callback::VideoInputFormatChanged(
+ BMDVideoInputFormatChangedEvents events, IDeckLinkDisplayMode *mode,
+ BMDDetectedVideoInputFormatFlags)
+{
+ return S_OK;
+}
+
+static HRESULT decklink_start_input(AVFormatContext *avctx)
+{
+ struct decklink_cctx *cctx = (struct decklink_cctx *) avctx->priv_data;
+ struct decklink_ctx *ctx = (struct decklink_ctx *) cctx->ctx;
+
+ ctx->input_callback = new decklink_input_callback(avctx);
+ ctx->dli->SetCallback(ctx->input_callback);
+ return ctx->dli->StartStreams();
+}
+
+extern "C" {
+
+av_cold int ff_decklink_read_close(AVFormatContext *avctx)
+{
+ struct decklink_cctx *cctx = (struct decklink_cctx *) avctx->priv_data;
+ struct decklink_ctx *ctx = (struct decklink_ctx *) cctx->ctx;
+
+ if (ctx->capture_started) {
+ ctx->dli->StopStreams();
+ ctx->dli->DisableVideoInput();
+ ctx->dli->DisableAudioInput();
+ }
+
+ if (ctx->dli)
+ ctx->dli->Release();
+ if (ctx->dl)
+ ctx->dl->Release();
+
+ avpacket_queue_end(&ctx->queue);
+
+ av_freep(&cctx->ctx);
+
+ return 0;
+}
+
+av_cold int ff_decklink_read_header(AVFormatContext *avctx)
+{
+ struct decklink_cctx *cctx = (struct decklink_cctx *) avctx->priv_data;
+ struct decklink_ctx *ctx;
+ IDeckLinkDisplayModeIterator *itermode;
+ IDeckLinkIterator *iter;
+ IDeckLink *dl = NULL;
+ AVStream *st;
+ HRESULT result;
+ char fname[1024];
+ char *tmp;
+ int mode_num = 0;
+
+ ctx = (struct decklink_ctx *) av_mallocz(sizeof(struct decklink_ctx));
+ if (!ctx)
+ return AVERROR(ENOMEM);
+ ctx->list_devices = cctx->list_devices;
+ ctx->list_formats = cctx->list_formats;
+ ctx->preroll = cctx->preroll;
+ cctx->ctx = ctx;
+
+ iter = CreateDeckLinkIteratorInstance();
+ if (!iter) {
+ av_log(avctx, AV_LOG_ERROR, "Could not create DeckLink iterator\n");
+ return AVERROR(EIO);
+ }
+
+ /* List available devices. */
+ if (ctx->list_devices) {
+ ff_decklink_list_devices(avctx);
+ return AVERROR_EXIT;
+ }
+
+ strcpy (fname, avctx->filename);
+ tmp=strchr (fname, '@');
+ if (tmp != NULL) {
+ mode_num = atoi (tmp+1);
+ *tmp = 0;
+ }
+
+ /* Open device. */
+ while (iter->Next(&dl) == S_OK) {
+ const char *displayName;
+ ff_decklink_get_display_name(dl, &displayName);
+ if (!strcmp(fname, displayName)) {
+ av_free((void *) displayName);
+ ctx->dl = dl;
+ break;
+ }
+ av_free((void *) displayName);
+ dl->Release();
+ }
+ iter->Release();
+ if (!ctx->dl) {
+ av_log(avctx, AV_LOG_ERROR, "Could not open '%s'\n", fname);
+ return AVERROR(EIO);
+ }
+
+ /* Get input device. */
+ if (ctx->dl->QueryInterface(IID_IDeckLinkInput, (void **) &ctx->dli) != S_OK) {
+ av_log(avctx, AV_LOG_ERROR, "Could not open output device from '%s'\n",
+ avctx->filename);
+ ctx->dl->Release();
+ return AVERROR(EIO);
+ }
+
+ /* List supported formats. */
+ if (ctx->list_formats) {
+ ff_decklink_list_formats(avctx, DIRECTION_IN);
+ ctx->dli->Release();
+ ctx->dl->Release();
+ return AVERROR_EXIT;
+ }
+
+ if (ctx->dli->GetDisplayModeIterator(&itermode) != S_OK) {
+ av_log(avctx, AV_LOG_ERROR, "Could not get Display Mode Iterator\n");
+ ctx->dl->Release();
+ return AVERROR(EIO);
+ }
+
+ if (mode_num > 0) {
+ if (ff_decklink_set_format(avctx, DIRECTION_IN, mode_num) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "Could not set mode %d for %s\n", mode_num, fname);
+ goto error;
+ }
+ }
+
+ itermode->Release();
+
+ /* Setup streams. */
+ st = avformat_new_stream(avctx, NULL);
+ if (!st) {
+ av_log(avctx, AV_LOG_ERROR, "Cannot add stream\n");
+ goto error;
+ }
+ st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
+ st->codec->codec_id = AV_CODEC_ID_PCM_S16LE;
+ st->codec->sample_rate = bmdAudioSampleRate48kHz;
+ st->codec->channels = 2;
+ avpriv_set_pts_info(st, 64, 1, 1000000); /* 64 bits pts in us */
+ ctx->audio_st=st;
+
+ st = avformat_new_stream(avctx, NULL);
+ if (!st) {
+ av_log(avctx, AV_LOG_ERROR, "Cannot add stream\n");
+ goto error;
+ }
+ st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
+ st->codec->codec_id = AV_CODEC_ID_RAWVIDEO;
+ st->codec->width = ctx->bmd_width;
+ st->codec->height = ctx->bmd_height;
+
+ st->codec->pix_fmt = AV_PIX_FMT_UYVY422;
+ st->codec->time_base.den = ctx->bmd_tb_den;
+ st->codec->time_base.num = ctx->bmd_tb_num;
+ st->codec->bit_rate = avpicture_get_size(st->codec->pix_fmt, ctx->bmd_width, ctx->bmd_height) * 1/av_q2d(st->codec->time_base) * 8;
+ st->codec->codec_tag = MKTAG('U', 'Y', 'V', 'Y');
+
+ avpriv_set_pts_info(st, 64, 1, 1000000); /* 64 bits pts in us */
+
+ ctx->video_st=st;
+
+ result = ctx->dli->EnableAudioInput(bmdAudioSampleRate48kHz, bmdAudioSampleType16bitInteger, 2);
+
+ if (result != S_OK) {
+ av_log(avctx, AV_LOG_ERROR, "Cannot enable audio input\n");
+ goto error;
+ }
+
+ result = ctx->dli->EnableVideoInput(ctx->bmd_mode, bmdFormat8BitYUV, bmdVideoInputFlagDefault);
+
+ if (result != S_OK) {
+ av_log(avctx, AV_LOG_ERROR, "Cannot enable video input\n");
+ goto error;
+ }
+
+ avpacket_queue_init (avctx, &ctx->queue);
+
+ if (decklink_start_input (avctx) != S_OK) {
+ av_log(avctx, AV_LOG_ERROR, "Cannot start input stream\n");
+ goto error;
+ }
+
+ return 0;
+
+error:
+
+ ctx->dli->Release();
+ ctx->dl->Release();
+
+ return AVERROR(EIO);
+}
+
+int ff_decklink_read_packet(AVFormatContext *avctx, AVPacket *pkt)
+{
+ struct decklink_cctx *cctx = (struct decklink_cctx *) avctx->priv_data;
+ struct decklink_ctx *ctx = (struct decklink_ctx *) cctx->ctx;
+ AVFrame *frame = ctx->video_st->codec->coded_frame;
+
+ avpacket_queue_get(&ctx->queue, pkt, 1);
+ if (frame && (ctx->bmd_field_dominance == bmdUpperFieldFirst || ctx->bmd_field_dominance == bmdLowerFieldFirst)) {
+ frame->interlaced_frame = 1;
+ if (ctx->bmd_field_dominance == bmdUpperFieldFirst) {
+ frame->top_field_first = 1;
+ }
+ }
+
+ return 0;
+}
+
+} /* extern "C" */
--- /dev/null
+/*
+ * Blackmagic DeckLink output
+ * Copyright (c) 2013-2014 Ramiro Polla
+ *
+ * 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 __cplusplus
+extern "C" {
+#endif
+
+int ff_decklink_read_header(AVFormatContext *avctx);
+int ff_decklink_read_packet(AVFormatContext *avctx, AVPacket *pkt);
+int ff_decklink_read_close(AVFormatContext *avctx);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
--- /dev/null
+/*
+ * Blackmagic DeckLink output
+ * Copyright (c) 2014 Deti Fliegl
+ *
+ * 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 "libavformat/avformat.h"
+#include "libavutil/opt.h"
+
+#include "decklink_common_c.h"
+#include "decklink_dec.h"
+
+#define OFFSET(x) offsetof(struct decklink_cctx, x)
+#define DEC AV_OPT_FLAG_DECODING_PARAM
+
+static const AVOption options[] = {
+ { "list_devices", "list available devices" , OFFSET(list_devices), AV_OPT_TYPE_INT , { .i64 = 0 }, 0, 1, DEC },
+ { "list_formats", "list supported formats" , OFFSET(list_formats), AV_OPT_TYPE_INT , { .i64 = 0 }, 0, 1, DEC },
+ { NULL },
+};
+
+static const AVClass decklink_demuxer_class = {
+ .class_name = "Blackmagic DeckLink demuxer",
+ .item_name = av_default_item_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+ .category = AV_CLASS_CATEGORY_DEVICE_VIDEO_INPUT,
+};
+
+AVInputFormat ff_decklink_demuxer = {
+ .name = "decklink",
+ .long_name = NULL_IF_CONFIG_SMALL("Blackmagic DeckLink input"),
+ .flags = AVFMT_NOFILE | AVFMT_RAWPICTURE,
+ .priv_class = &decklink_demuxer_class,
+ .priv_data_size = sizeof(struct decklink_cctx),
+ .read_header = ff_decklink_read_header,
+ .read_packet = ff_decklink_read_packet,
+ .read_close = ff_decklink_read_close,
+};
*/
#include <DeckLinkAPI.h>
-#ifdef _WIN32
-#include <DeckLinkAPI_i.c>
-typedef unsigned long buffercount_type;
-#else
-#include <DeckLinkAPIDispatch.cpp>
-typedef uint32_t buffercount_type;
-#endif
#include <pthread.h>
#include <semaphore.h>
#include "libavutil/imgutils.h"
}
+#include "decklink_common.h"
#include "decklink_enc.h"
-class decklink_callback;
-
-struct decklink_ctx {
- /* DeckLink SDK interfaces */
- IDeckLink *dl;
- IDeckLinkOutput *dlo;
- decklink_callback *callback;
-
- /* DeckLink mode information */
- IDeckLinkDisplayModeIterator *itermode;
- BMDTimeValue bmd_tb_den;
- BMDTimeValue bmd_tb_num;
- BMDDisplayMode bmd_mode;
- int bmd_width;
- int bmd_height;
-
- /* Streams present */
- int audio;
- int video;
-
- /* Status */
- int playback_started;
- int64_t last_pts;
-
- /* Options */
- int list_devices;
- int list_formats;
- double preroll;
-
- int frames_preroll;
- int frames_buffer;
-
- sem_t semaphore;
-
- int channels;
-};
/* DeckLink callback class declaration */
class decklink_frame : public IDeckLinkVideoFrame
int _refs;
};
-class decklink_callback : public IDeckLinkVideoOutputCallback
+class decklink_output_callback : public IDeckLinkVideoOutputCallback
{
public:
virtual HRESULT STDMETHODCALLTYPE ScheduledFrameCompleted(IDeckLinkVideoFrame *_frame, BMDOutputFrameCompletionResult result)
virtual ULONG STDMETHODCALLTYPE Release(void) { return 1; }
};
-#ifdef _WIN32
-static IDeckLinkIterator *CreateDeckLinkIteratorInstance(void)
-{
- IDeckLinkIterator *iter;
-
- if (CoInitialize(NULL) != S_OK) {
- av_log(NULL, AV_LOG_ERROR, "COM initialization failed.\n");
- return NULL;
- }
-
- if (CoCreateInstance(CLSID_CDeckLinkIterator, NULL, CLSCTX_ALL,
- IID_IDeckLinkIterator, (void**) &iter) != S_OK) {
- av_log(NULL, AV_LOG_ERROR, "DeckLink drivers not installed.\n");
- return NULL;
- }
-
- return iter;
-}
-#endif
-
-/* free() is needed for a string returned by the DeckLink SDL. */
-#undef free
-
-#ifdef _WIN32
-static char *dup_wchar_to_utf8(wchar_t *w)
-{
- char *s = NULL;
- int l = WideCharToMultiByte(CP_UTF8, 0, w, -1, 0, 0, 0, 0);
- s = (char *) av_malloc(l);
- if (s)
- WideCharToMultiByte(CP_UTF8, 0, w, -1, s, l, 0, 0);
- return s;
-}
-#define DECKLINK_STR OLECHAR *
-#define DECKLINK_STRDUP dup_wchar_to_utf8
-#else
-#define DECKLINK_STR const char *
-#define DECKLINK_STRDUP av_strdup
-#endif
-
-static HRESULT IDeckLink_GetDisplayName(IDeckLink *This, const char **displayName)
-{
- DECKLINK_STR tmpDisplayName;
- HRESULT hr = This->GetDisplayName(&tmpDisplayName);
- if (hr != S_OK)
- return hr;
- *displayName = DECKLINK_STRDUP(tmpDisplayName);
- free((void *) tmpDisplayName);
- return hr;
-}
-
-static int decklink_set_format(struct decklink_ctx *ctx,
- int width, int height,
- int tb_num, int tb_den)
-{
- BMDDisplayModeSupport support;
- IDeckLinkDisplayMode *mode;
-
- if (tb_num == 1) {
- tb_num *= 1000;
- tb_den *= 1000;
- }
- ctx->bmd_mode = bmdModeUnknown;
- while ((ctx->bmd_mode == bmdModeUnknown) && ctx->itermode->Next(&mode) == S_OK) {
- BMDTimeValue bmd_tb_num, bmd_tb_den;
- int bmd_width = mode->GetWidth();
- int bmd_height = mode->GetHeight();
-
- mode->GetFrameRate(&bmd_tb_num, &bmd_tb_den);
-
- if (bmd_width == width && bmd_height == height &&
- bmd_tb_num == tb_num && bmd_tb_den == tb_den) {
- ctx->bmd_mode = mode->GetDisplayMode();
- ctx->bmd_width = bmd_width;
- ctx->bmd_height = bmd_height;
- ctx->bmd_tb_den = bmd_tb_den;
- ctx->bmd_tb_num = bmd_tb_num;
- }
-
- mode->Release();
- }
- if (ctx->bmd_mode == bmdModeUnknown)
- return -1;
- if (ctx->dlo->DoesSupportVideoMode(ctx->bmd_mode, bmdFormat8BitYUV,
- bmdVideoOutputFlagDefault,
- &support, NULL) != S_OK)
- return -1;
- if (support == bmdDisplayModeSupported)
- return 0;
-
- return -1;
-}
-
static int decklink_setup_video(AVFormatContext *avctx, AVStream *st)
{
struct decklink_cctx *cctx = (struct decklink_cctx *) avctx->priv_data;
" Only AV_PIX_FMT_UYVY422 is supported.\n");
return -1;
}
- if (decklink_set_format(ctx, c->width, c->height,
+ if (ff_decklink_set_format(avctx, c->width, c->height,
c->time_base.num, c->time_base.den)) {
av_log(avctx, AV_LOG_ERROR, "Unsupported video size or framerate!"
" Check available formats with -list_formats 1.\n");
}
/* Set callback. */
- ctx->callback = new decklink_callback();
- ctx->dlo->SetScheduledFrameCompletionCallback(ctx->callback);
+ ctx->output_callback = new decklink_output_callback();
+ ctx->dlo->SetScheduledFrameCompletionCallback(ctx->output_callback);
/* Start video semaphore. */
ctx->frames_preroll = c->time_base.den * ctx->preroll;
if (ctx->dl)
ctx->dl->Release();
- if (ctx->callback)
- delete ctx->callback;
+ if (ctx->output_callback)
+ delete ctx->output_callback;
sem_destroy(&ctx->semaphore);
{
struct decklink_cctx *cctx = (struct decklink_cctx *) avctx->priv_data;
struct decklink_ctx *ctx;
+ IDeckLinkDisplayModeIterator *itermode;
IDeckLinkIterator *iter;
IDeckLink *dl = NULL;
unsigned int n;
/* List available devices. */
if (ctx->list_devices) {
- av_log(avctx, AV_LOG_INFO, "Blackmagic DeckLink devices:\n");
- while (iter->Next(&dl) == S_OK) {
- const char *displayName;
- IDeckLink_GetDisplayName(dl, &displayName);
- av_log(avctx, AV_LOG_INFO, "\t'%s'\n", displayName);
- av_free((void *) displayName);
- dl->Release();
- }
- iter->Release();
+ ff_decklink_list_devices(avctx);
return AVERROR_EXIT;
}
/* Open device. */
while (iter->Next(&dl) == S_OK) {
const char *displayName;
- IDeckLink_GetDisplayName(dl, &displayName);
+ ff_decklink_get_display_name(dl, &displayName);
if (!strcmp(avctx->filename, displayName)) {
av_free((void *) displayName);
ctx->dl = dl;
return AVERROR(EIO);
}
- if (ctx->dlo->GetDisplayModeIterator(&ctx->itermode) != S_OK) {
- av_log(avctx, AV_LOG_ERROR, "Could not get Display Mode Iterator\n");
- ctx->dl->Release();
- return AVERROR(EIO);
- }
-
/* List supported formats. */
if (ctx->list_formats) {
- IDeckLinkDisplayMode *mode;
-
- av_log(avctx, AV_LOG_INFO, "Supported formats for '%s':\n",
- avctx->filename);
- while (ctx->itermode->Next(&mode) == S_OK) {
- BMDTimeValue tb_num, tb_den;
- mode->GetFrameRate(&tb_num, &tb_den);
- av_log(avctx, AV_LOG_INFO, "\t%ldx%ld at %d/%d fps",
- mode->GetWidth(), mode->GetHeight(),
- (int) tb_den, (int) tb_num);
- switch (mode->GetFieldDominance()) {
- case bmdLowerFieldFirst:
- av_log(avctx, AV_LOG_INFO, " (interlaced, lower field first)"); break;
- case bmdUpperFieldFirst:
- av_log(avctx, AV_LOG_INFO, " (interlaced, upper field first)"); break;
- }
- av_log(avctx, AV_LOG_INFO, "\n");
- mode->Release();
- }
-
- ctx->itermode->Release();
+ ff_decklink_list_formats(avctx);
ctx->dlo->Release();
ctx->dl->Release();
return AVERROR_EXIT;
}
+ if (ctx->dlo->GetDisplayModeIterator(&itermode) != S_OK) {
+ av_log(avctx, AV_LOG_ERROR, "Could not get Display Mode Iterator\n");
+ ctx->dl->Release();
+ return AVERROR(EIO);
+ }
+
/* Setup streams. */
for (n = 0; n < avctx->nb_streams; n++) {
AVStream *st = avctx->streams[n];
goto error;
}
}
- ctx->itermode->Release();
+ itermode->Release();
return 0;
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-struct decklink_cctx {
- const AVClass *cclass;
-
- void *ctx;
-
- /* Options */
- int list_devices;
- int list_formats;
- double preroll;
-};
-
#ifdef __cplusplus
extern "C" {
#endif
#include "libavformat/avformat.h"
#include "libavutil/opt.h"
+#include "decklink_common_c.h"
#include "decklink_enc.h"
#define OFFSET(x) offsetof(struct decklink_cctx, x)
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include "dshow_capture.h"
#include "libavutil/parseutils.h"
#include "libavutil/pixdesc.h"
#include "libavutil/opt.h"
#include "libavformat/internal.h"
#include "libavformat/riff.h"
#include "avdevice.h"
-#include "dshow_capture.h"
#include "libavcodec/raw.h"
struct dshow_ctx {
#include "avdevice.h"
#define COBJMACROS
+#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#define NO_DSHOW_STRSAFE
#include <dshow.h>
for (i = 0; i <= 31; i++) {
snprintf(device_file, sizeof(device_file), "/dev/fb%d", i);
- if ((fd = avpriv_open(device_file, O_RDWR)) < 0)
+ if ((fd = avpriv_open(device_file, O_RDWR)) < 0) {
+ int err = AVERROR(errno);
+ if (err != AVERROR(ENOENT))
+ av_log(NULL, AV_LOG_ERROR, "Could not open framebuffer device '%s': %s\n",
+ device_file, av_err2str(err));
continue;
+ }
if (ioctl(fd, FBIOGET_VSCREENINFO, &varinfo) == -1)
goto fail_device;
if (ioctl(fd, FBIOGET_FSCREENINFO, &fixinfo) == -1)
fail_device:
if (device) {
- av_free(device->device_name);
- av_free(device->device_description);
+ av_freep(&device->device_name);
+ av_freep(&device->device_description);
av_freep(&device);
}
if (fd >= 0)
AVStream *st = NULL;
enum AVPixelFormat pix_fmt;
int ret, flags = O_RDONLY;
+ const char* device;
if (!(st = avformat_new_stream(avctx, NULL)))
return AVERROR(ENOMEM);
if (avctx->flags & AVFMT_FLAG_NONBLOCK)
flags |= O_NONBLOCK;
- if ((fbdev->fd = avpriv_open(avctx->filename, flags)) == -1) {
+ if (avctx->filename[0])
+ device = avctx->filename;
+ else
+ device = ff_fbdev_default_device();
+
+ if ((fbdev->fd = avpriv_open(device, flags)) == -1) {
ret = AVERROR(errno);
av_log(avctx, AV_LOG_ERROR,
"Could not open framebuffer device '%s': %s\n",
- avctx->filename, av_err2str(ret));
+ device, av_err2str(ret));
return ret;
}
return ret;
/* refresh fbdev->varinfo, visible data position may change at each call */
- if (ioctl(fbdev->fd, FBIOGET_VSCREENINFO, &fbdev->varinfo) < 0)
+ if (ioctl(fbdev->fd, FBIOGET_VSCREENINFO, &fbdev->varinfo) < 0) {
av_log(avctx, AV_LOG_WARNING,
- "Error refreshing variable info: %s\n", av_err2str(ret));
+ "Error refreshing variable info: %s\n", av_err2str(AVERROR(errno)));
+ }
pkt->pts = curtime;
size = avpriv_mpegts_parse_packet(dv->mpeg_demux, pkt, packet->buf,
packet->len);
dv->queue_first = packet->next;
- av_free(packet->buf);
- av_free(packet);
+ av_freep(&packet->buf);
+ av_freep(&packet);
dv->packets--;
if (size > 0)
if (!dv->max_packets)
dv->max_packets = 100;
- if (dv->type == IEC61883_HDV) {
+ if (CONFIG_MPEGTS_DEMUXER && dv->type == IEC61883_HDV) {
/* Init HDV receive */
pthread_mutex_destroy(&dv->mutex);
#endif
- if (dv->type == IEC61883_HDV) {
+ if (CONFIG_MPEGTS_DEMUXER && dv->type == IEC61883_HDV) {
iec61883_mpeg2_recv_stop(dv->iec61883_mpeg2);
iec61883_mpeg2_close(dv->iec61883_mpeg2);
avpriv_mpegts_parse_close(dv->mpeg_demux);
while (dv->queue_first) {
DVPacket *packet = dv->queue_first;
dv->queue_first = packet->next;
- av_free(packet->buf);
- av_free(packet);
+ av_freep(&packet->buf);
+ av_freep(&packet);
}
iec61883_cmp_disconnect(dv->raw1394, dv->node, dv->output_port,
av_log(context, AV_LOG_ERROR,
"Input error: timed out when waiting for JACK process callback output\n");
} else {
+ char errbuf[128];
+ int ret = AVERROR(errno);
+ av_strerror(ret, errbuf, sizeof(errbuf));
av_log(context, AV_LOG_ERROR, "Error while waiting for audio packet: %s\n",
- strerror(errno));
+ errbuf);
}
if (!self->client)
av_log(context, AV_LOG_ERROR, "Input error: JACK server is gone\n");
#include "config.h"
#if HAVE_WINDOWS_H
+#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#endif
#if HAVE_OPENGL_GL3_H
else
audio_fd = avpriv_open(audio_device, O_RDONLY);
if (audio_fd < 0) {
- av_log(s1, AV_LOG_ERROR, "%s: %s\n", audio_device, strerror(errno));
+ av_log(s1, AV_LOG_ERROR, "%s: %s\n", audio_device, av_err2str(AVERROR(errno)));
return AVERROR(EIO);
}
/* non blocking mode */
if (!is_output) {
if (fcntl(audio_fd, F_SETFL, O_NONBLOCK) < 0) {
- av_log(s1, AV_LOG_WARNING, "%s: Could not enable non block mode (%s)\n", audio_device, strerror(errno));
+ av_log(s1, AV_LOG_WARNING, "%s: Could not enable non block mode (%s)\n", audio_device, av_err2str(AVERROR(errno)));
}
}
#define CHECK_IOCTL_ERROR(event) \
if (err < 0) { \
- av_log(s1, AV_LOG_ERROR, #event ": %s\n", strerror(errno)); \
+ av_log(s1, AV_LOG_ERROR, #event ": %s\n", av_err2str(AVERROR(errno)));\
goto fail; \
}
/* select format : favour native format
* We don't CHECK_IOCTL_ERROR here because even if failed OSS still may be
* usable. If OSS is not usable the SNDCTL_DSP_SETFMTS later is going to
- * fail anyway. `err =` kept to eliminate compiler warning. */
+ * fail anyway. */
err = ioctl(audio_fd, SNDCTL_DSP_GETFMTS, &tmp);
if (err < 0) {
- av_log(s1, AV_LOG_WARNING, "SNDCTL_DSP_GETFMTS: %s\n", strerror(errno));
+ av_log(s1, AV_LOG_WARNING, "SNDCTL_DSP_GETFMTS: %s\n", av_err2str(AVERROR(errno)));
}
#if HAVE_BIGENDIAN
return;
fail:
- av_free(new_device->device_description);
- av_free(new_device->device_name);
+ av_freep(&new_device->device_description);
+ av_freep(&new_device->device_name);
av_free(new_device);
}
#include "v4l2-common.h"
-const struct fmt_map avpriv_fmt_conversion_table[] = {
+const struct fmt_map ff_fmt_conversion_table[] = {
//ff_fmt codec_id v4l2_fmt
{ AV_PIX_FMT_YUV420P, AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_YUV420 },
{ AV_PIX_FMT_YUV420P, AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_YVU420 },
#ifdef V4L2_PIX_FMT_H264
{ AV_PIX_FMT_NONE, AV_CODEC_ID_H264, V4L2_PIX_FMT_H264 },
#endif
+#ifdef V4L2_PIX_FMT_MPEG4
+ { AV_PIX_FMT_NONE, AV_CODEC_ID_MPEG4, V4L2_PIX_FMT_MPEG4 },
+#endif
#ifdef V4L2_PIX_FMT_CPIA1
{ AV_PIX_FMT_NONE, AV_CODEC_ID_CPIA, V4L2_PIX_FMT_CPIA1 },
#endif
{ AV_PIX_FMT_NONE, AV_CODEC_ID_NONE, 0 },
};
-uint32_t avpriv_fmt_ff2v4l(enum AVPixelFormat pix_fmt, enum AVCodecID codec_id)
+uint32_t ff_fmt_ff2v4l(enum AVPixelFormat pix_fmt, enum AVCodecID codec_id)
{
int i;
- for (i = 0; avpriv_fmt_conversion_table[i].codec_id != AV_CODEC_ID_NONE; i++) {
+ for (i = 0; ff_fmt_conversion_table[i].codec_id != AV_CODEC_ID_NONE; i++) {
if ((codec_id == AV_CODEC_ID_NONE ||
- avpriv_fmt_conversion_table[i].codec_id == codec_id) &&
+ ff_fmt_conversion_table[i].codec_id == codec_id) &&
(pix_fmt == AV_PIX_FMT_NONE ||
- avpriv_fmt_conversion_table[i].ff_fmt == pix_fmt)) {
- return avpriv_fmt_conversion_table[i].v4l2_fmt;
+ ff_fmt_conversion_table[i].ff_fmt == pix_fmt)) {
+ return ff_fmt_conversion_table[i].v4l2_fmt;
}
}
return 0;
}
-enum AVPixelFormat avpriv_fmt_v4l2ff(uint32_t v4l2_fmt, enum AVCodecID codec_id)
+enum AVPixelFormat ff_fmt_v4l2ff(uint32_t v4l2_fmt, enum AVCodecID codec_id)
{
int i;
- for (i = 0; avpriv_fmt_conversion_table[i].codec_id != AV_CODEC_ID_NONE; i++) {
- if (avpriv_fmt_conversion_table[i].v4l2_fmt == v4l2_fmt &&
- avpriv_fmt_conversion_table[i].codec_id == codec_id) {
- return avpriv_fmt_conversion_table[i].ff_fmt;
+ for (i = 0; ff_fmt_conversion_table[i].codec_id != AV_CODEC_ID_NONE; i++) {
+ if (ff_fmt_conversion_table[i].v4l2_fmt == v4l2_fmt &&
+ ff_fmt_conversion_table[i].codec_id == codec_id) {
+ return ff_fmt_conversion_table[i].ff_fmt;
}
}
return AV_PIX_FMT_NONE;
}
-enum AVCodecID avpriv_fmt_v4l2codec(uint32_t v4l2_fmt)
+enum AVCodecID ff_fmt_v4l2codec(uint32_t v4l2_fmt)
{
int i;
- for (i = 0; avpriv_fmt_conversion_table[i].codec_id != AV_CODEC_ID_NONE; i++) {
- if (avpriv_fmt_conversion_table[i].v4l2_fmt == v4l2_fmt) {
- return avpriv_fmt_conversion_table[i].codec_id;
+ for (i = 0; ff_fmt_conversion_table[i].codec_id != AV_CODEC_ID_NONE; i++) {
+ if (ff_fmt_conversion_table[i].v4l2_fmt == v4l2_fmt) {
+ return ff_fmt_conversion_table[i].codec_id;
}
}
uint32_t v4l2_fmt;
};
-extern av_export const struct fmt_map avpriv_fmt_conversion_table[];
+extern const struct fmt_map ff_fmt_conversion_table[];
-uint32_t avpriv_fmt_ff2v4l(enum AVPixelFormat pix_fmt, enum AVCodecID codec_id);
-enum AVPixelFormat avpriv_fmt_v4l2ff(uint32_t v4l2_fmt, enum AVCodecID codec_id);
-enum AVCodecID avpriv_fmt_v4l2codec(uint32_t v4l2_fmt);
+uint32_t ff_fmt_ff2v4l(enum AVPixelFormat pix_fmt, enum AVCodecID codec_id);
+enum AVPixelFormat ff_fmt_v4l2ff(uint32_t v4l2_fmt, enum AVCodecID codec_id);
+enum AVCodecID ff_fmt_v4l2codec(uint32_t v4l2_fmt);
#endif /* AVDEVICE_V4L2_COMMON_H */
struct video_data {
AVClass *class;
int fd;
- int frame_format; /* V4L2_PIX_FMT_* */
+ int pixelformat; /* V4L2_PIX_FMT_* */
int width, height;
int frame_size;
int interlaced;
struct video_data *s = ctx->priv_data;
struct v4l2_capability cap;
int fd;
- int ret;
+ int err;
int flags = O_RDWR;
#define SET_WRAPPERS(prefix) do { \
fd = v4l2_open(ctx->filename, flags, 0);
if (fd < 0) {
- ret = AVERROR(errno);
+ err = AVERROR(errno);
av_log(ctx, AV_LOG_ERROR, "Cannot open video device %s: %s\n",
- ctx->filename, av_err2str(ret));
- return ret;
+ ctx->filename, av_err2str(err));
+ return err;
}
if (v4l2_ioctl(fd, VIDIOC_QUERYCAP, &cap) < 0) {
- ret = AVERROR(errno);
+ err = AVERROR(errno);
av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_QUERYCAP): %s\n",
- av_err2str(ret));
+ av_err2str(err));
goto fail;
}
if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {
av_log(ctx, AV_LOG_ERROR, "Not a video capture device.\n");
- ret = AVERROR(ENODEV);
+ err = AVERROR(ENODEV);
goto fail;
}
if (!(cap.capabilities & V4L2_CAP_STREAMING)) {
av_log(ctx, AV_LOG_ERROR,
"The device does not support the streaming I/O method.\n");
- ret = AVERROR(ENOSYS);
+ err = AVERROR(ENOSYS);
goto fail;
}
fail:
v4l2_close(fd);
- return ret;
+ return err;
}
static int device_init(AVFormatContext *ctx, int *width, int *height,
- uint32_t pix_fmt)
+ uint32_t pixelformat)
{
struct video_data *s = ctx->priv_data;
struct v4l2_format fmt = { .type = V4L2_BUF_TYPE_VIDEO_CAPTURE };
- struct v4l2_pix_format *pix = &fmt.fmt.pix;
int res = 0;
- pix->width = *width;
- pix->height = *height;
- pix->pixelformat = pix_fmt;
- pix->field = V4L2_FIELD_ANY;
+ fmt.fmt.pix.width = *width;
+ fmt.fmt.pix.height = *height;
+ fmt.fmt.pix.pixelformat = pixelformat;
+ fmt.fmt.pix.field = V4L2_FIELD_ANY;
+ /* Some drivers will fail and return EINVAL when the pixelformat
+ is not supported (even if type field is valid and supported) */
if (v4l2_ioctl(s->fd, VIDIOC_S_FMT, &fmt) < 0)
res = AVERROR(errno);
*height = fmt.fmt.pix.height;
}
- if (pix_fmt != fmt.fmt.pix.pixelformat) {
+ if (pixelformat != fmt.fmt.pix.pixelformat) {
av_log(ctx, AV_LOG_DEBUG,
"The V4L2 driver changed the pixel format "
"from 0x%08X to 0x%08X\n",
- pix_fmt, fmt.fmt.pix.pixelformat);
+ pixelformat, fmt.fmt.pix.pixelformat);
res = AVERROR(EINVAL);
}
struct v4l2_fmtdesc vfd = { .type = V4L2_BUF_TYPE_VIDEO_CAPTURE };
while(!v4l2_ioctl(s->fd, VIDIOC_ENUM_FMT, &vfd)) {
- enum AVCodecID codec_id = avpriv_fmt_v4l2codec(vfd.pixelformat);
- enum AVPixelFormat pix_fmt = avpriv_fmt_v4l2ff(vfd.pixelformat, codec_id);
+ enum AVCodecID codec_id = ff_fmt_v4l2codec(vfd.pixelformat);
+ enum AVPixelFormat pix_fmt = ff_fmt_v4l2ff(vfd.pixelformat, codec_id);
vfd.index++;
return AVERROR(EAGAIN);
}
res = AVERROR(errno);
- av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_DQBUF): %s\n", av_err2str(res));
+ av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_DQBUF): %s\n",
+ av_err2str(res));
return res;
}
if (v4l2_ioctl(s->fd, VIDIOC_QBUF, &buf) < 0) {
res = AVERROR(errno);
- av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_QBUF): %s\n", av_err2str(res));
+ av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_QBUF): %s\n",
+ av_err2str(res));
return res;
}
}
type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
if (v4l2_ioctl(s->fd, VIDIOC_STREAMON, &type) < 0) {
res = AVERROR(errno);
- av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_STREAMON): %s\n", av_err2str(res));
+ av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_STREAMON): %s\n",
+ av_err2str(res));
return res;
}
if (v4l2_ioctl(s->fd, VIDIOC_S_PARM, &streamparm) < 0) {
ret = AVERROR(errno);
- av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_S_PARM): %s\n", av_err2str(ret));
+ av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_S_PARM): %s\n",
+ av_err2str(ret));
return ret;
}
{
int ret, i;
- *desired_format = avpriv_fmt_ff2v4l(pix_fmt, ctx->video_codec_id);
+ *desired_format = ff_fmt_ff2v4l(pix_fmt, ctx->video_codec_id);
if (*desired_format) {
ret = device_init(ctx, width, height, *desired_format);
}
if (!*desired_format) {
- for (i = 0; avpriv_fmt_conversion_table[i].codec_id != AV_CODEC_ID_NONE; i++) {
+ for (i = 0; ff_fmt_conversion_table[i].codec_id != AV_CODEC_ID_NONE; i++) {
if (ctx->video_codec_id == AV_CODEC_ID_NONE ||
- avpriv_fmt_conversion_table[i].codec_id == ctx->video_codec_id) {
+ ff_fmt_conversion_table[i].codec_id == ctx->video_codec_id) {
av_log(ctx, AV_LOG_DEBUG, "Trying to set codec:%s pix_fmt:%s\n",
- avcodec_get_name(avpriv_fmt_conversion_table[i].codec_id),
- (char *)av_x_if_null(av_get_pix_fmt_name(avpriv_fmt_conversion_table[i].ff_fmt), "none"));
+ avcodec_get_name(ff_fmt_conversion_table[i].codec_id),
+ (char *)av_x_if_null(av_get_pix_fmt_name(ff_fmt_conversion_table[i].ff_fmt), "none"));
- *desired_format = avpriv_fmt_conversion_table[i].v4l2_fmt;
+ *desired_format = ff_fmt_conversion_table[i].v4l2_fmt;
ret = device_init(ctx, width, height, *desired_format);
if (ret >= 0)
break;
}
}
- *codec_id = avpriv_fmt_v4l2codec(*desired_format);
+ *codec_id = ff_fmt_v4l2codec(*desired_format);
av_assert0(*codec_id != AV_CODEC_ID_NONE);
return ret;
}
+static int v4l2_read_probe(AVProbeData *p)
+{
+ if (av_strstart(p->filename, "/dev/video", NULL))
+ return AVPROBE_SCORE_MAX - 1;
+ return 0;
+}
+
static int v4l2_read_header(AVFormatContext *ctx)
{
struct video_data *s = ctx->priv_data;
avpriv_set_pts_info(st, 64, 1, 1000000); /* 64 bits pts in us */
- if ((res = v4l2_set_parameters(ctx)) < 0)
- goto fail;
-
if (s->pixel_format) {
AVCodec *codec = avcodec_find_decoder_by_name(s->pixel_format);
"Querying the device for the current frame size\n");
if (v4l2_ioctl(s->fd, VIDIOC_G_FMT, &fmt) < 0) {
res = AVERROR(errno);
- av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_G_FMT): %s\n", av_err2str(res));
+ av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_G_FMT): %s\n",
+ av_err2str(res));
goto fail;
}
if ((res = av_image_check_size(s->width, s->height, 0, ctx)) < 0)
goto fail;
- s->frame_format = desired_format;
+ s->pixelformat = desired_format;
+
+ if ((res = v4l2_set_parameters(ctx)) < 0)
+ goto fail;
- st->codec->pix_fmt = avpriv_fmt_v4l2ff(desired_format, codec_id);
+ st->codec->pix_fmt = ff_fmt_v4l2ff(desired_format, codec_id);
s->frame_size =
avpicture_get_size(st->codec->pix_fmt, s->width, s->height);
.name = "video4linux2,v4l2",
.long_name = NULL_IF_CONFIG_SMALL("Video4Linux2 device grab"),
.priv_data_size = sizeof(struct video_data),
+ .read_probe = v4l2_read_probe,
.read_header = v4l2_read_header,
.read_packet = v4l2_read_packet,
.read_close = v4l2_read_close,
enc_ctx = s1->streams[0]->codec;
- v4l2_pixfmt = avpriv_fmt_ff2v4l(enc_ctx->pix_fmt, AV_CODEC_ID_RAWVIDEO);
+ v4l2_pixfmt = ff_fmt_ff2v4l(enc_ctx->pix_fmt, AV_CODEC_ID_RAWVIDEO);
if (!v4l2_pixfmt) { // XXX: try to force them one by one?
av_log(s1, AV_LOG_ERROR, "Unknown V4L2 pixel format equivalent for %s\n",
av_get_pix_fmt_name(enc_ctx->pix_fmt));
#include "libavutil/version.h"
#define LIBAVDEVICE_VERSION_MAJOR 56
-#define LIBAVDEVICE_VERSION_MINOR 0
+#define LIBAVDEVICE_VERSION_MINOR 3
#define LIBAVDEVICE_VERSION_MICRO 100
#define LIBAVDEVICE_VERSION_INT AV_VERSION_INT(LIBAVDEVICE_VERSION_MAJOR, \
return 0;
}
+static int setup_mouse(Display *dpy, int screen)
+{
+ int ev_ret, ev_err;
+
+ if (XFixesQueryExtension(dpy, &ev_ret, &ev_err)) {
+ Window root = RootWindow(dpy, screen);
+ XFixesSelectCursorInput(dpy, root, XFixesDisplayCursorNotifyMask);
+ return 0;
+ }
+
+ return AVERROR(ENOSYS);
+}
+
static int pixfmt_from_image(AVFormatContext *s, XImage *image, int *pix_fmt)
{
av_log(s, AV_LOG_DEBUG,
AllPlanes, ZPixmap);
}
+ if (x11grab->draw_mouse && setup_mouse(dpy, screen) < 0) {
+ av_log(s1, AV_LOG_WARNING,
+ "XFixes not available, cannot draw the mouse cursor\n");
+ x11grab->draw_mouse = 0;
+ }
+
x11grab->frame_size = x11grab->width * x11grab->height * image->bits_per_pixel / 8;
x11grab->dpy = dpy;
x11grab->time_base = av_inv_q(x11grab->framerate);
uint8_t *pix = image->data;
Window root;
XSetWindowAttributes attr;
- Bool pointer_on_screen;
- Window w;
- int _;
-
- root = DefaultRootWindow(dpy);
- pointer_on_screen = XQueryPointer(dpy, root, &w, &w, &_, &_, &_, &_, &_);
- if (!pointer_on_screen)
- return;
/* Code doesn't currently support 16-bit or PAL8 */
if (image->bits_per_pixel != 24 && image->bits_per_pixel != 32)
if (!s->c)
s->c = XCreateFontCursor(dpy, XC_left_ptr);
+ root = DefaultRootWindow(dpy);
attr.cursor = s->c;
XChangeWindowAttributes(dpy, root, CWCursor, &attr);
xcim = XFixesGetCursorImage(dpy);
if (!xcim) {
av_log(s1, AV_LOG_WARNING,
- "XFixes extension not available, impossible to draw cursor\n");
- s->draw_mouse = 0;
+ "XFixesGetCursorImage failed\n");
return;
}
int x_off = s->x_off;
int y_off = s->y_off;
int follow_mouse = s->follow_mouse;
- int screen;
- Window root;
+ int screen, pointer_x, pointer_y, _, same_screen = 1;
+ Window w, root;
int64_t curtime, delay;
struct timespec ts;
screen = DefaultScreen(dpy);
root = RootWindow(dpy, screen);
- if (follow_mouse) {
+
+ if (follow_mouse || s->draw_mouse)
+ same_screen = XQueryPointer(dpy, root, &w, &w,
+ &pointer_x, &pointer_y, &_, &_, &_);
+
+ if (follow_mouse && same_screen) {
int screen_w, screen_h;
- int pointer_x, pointer_y, _;
- Window w;
screen_w = DisplayWidth(dpy, screen);
screen_h = DisplayHeight(dpy, screen);
- XQueryPointer(dpy, root, &w, &w, &pointer_x, &pointer_y, &_, &_, &_);
if (follow_mouse == -1) {
// follow the mouse, put it at center of grabbing region
x_off += pointer_x - s->width / 2 - x_off;
s->y_off - REGION_WIN_BORDER);
}
- if (s->show_region) {
+ if (s->show_region && same_screen) {
if (s->region_win) {
XEvent evt = { .type = NoEventMask };
// Clean up the events, and do the initial draw or redraw.
av_log(s1, AV_LOG_INFO, "XGetZPixmap() failed\n");
}
- if (s->draw_mouse)
+ if (s->draw_mouse && same_screen)
paint_mouse_pointer(image, s1);
return s->frame_size;
--- /dev/null
+/*
+ * XCB input grabber
+ * Copyright (C) 2014 Luca Barbato <lu_zero@gentoo.org>
+ *
+ * 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 <stdlib.h>
+#include <xcb/xcb.h>
+
+#if CONFIG_LIBXCB_XFIXES
+#include <xcb/xfixes.h>
+#endif
+
+#if CONFIG_LIBXCB_SHM
+#include <sys/shm.h>
+#include <xcb/shm.h>
+#endif
+
+#if CONFIG_LIBXCB_SHAPE
+#include <xcb/shape.h>
+#endif
+
+#include "libavformat/avformat.h"
+#include "libavformat/internal.h"
+
+#include "libavutil/mathematics.h"
+#include "libavutil/opt.h"
+#include "libavutil/parseutils.h"
+#include "libavutil/time.h"
+
+typedef struct XCBGrabContext {
+ const AVClass *class;
+
+ xcb_connection_t *conn;
+ xcb_screen_t *screen;
+ xcb_window_t window;
+#if CONFIG_LIBXCB_SHM
+ xcb_shm_seg_t segment;
+#endif
+
+ int64_t time_frame;
+ AVRational time_base;
+
+ int x, y;
+ int width, height;
+ int frame_size;
+ int bpp;
+
+ int draw_mouse;
+ int follow_mouse;
+ int show_region;
+ int region_border;
+ int centered;
+
+ const char *video_size;
+ const char *framerate;
+
+ int has_shm;
+} XCBGrabContext;
+
+#define FOLLOW_CENTER -1
+
+#define OFFSET(x) offsetof(XCBGrabContext, x)
+#define D AV_OPT_FLAG_DECODING_PARAM
+static const AVOption options[] = {
+ { "x", "Initial x coordinate.", OFFSET(x), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, D },
+ { "y", "Initial y coordinate.", OFFSET(y), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, D },
+ { "video_size", "A string describing frame size, such as 640x480 or hd720.", OFFSET(video_size), AV_OPT_TYPE_STRING, {.str = "vga" }, 0, 0, D },
+ { "framerate", "", OFFSET(framerate), AV_OPT_TYPE_STRING, {.str = "ntsc" }, 0, 0, D },
+ { "draw_mouse", "Draw the mouse pointer.", OFFSET(draw_mouse), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 1, D },
+ { "follow_mouse", "Move the grabbing region when the mouse pointer reaches within specified amount of pixels to the edge of region.",
+ OFFSET(follow_mouse), AV_OPT_TYPE_INT, { .i64 = 0 }, FOLLOW_CENTER, INT_MAX, D, "follow_mouse" },
+ { "centered", "Keep the mouse pointer at the center of grabbing region when following.", 0, AV_OPT_TYPE_CONST, { .i64 = -1 }, INT_MIN, INT_MAX, D, "follow_mouse" },
+ { "show_region", "Show the grabbing region.", OFFSET(show_region), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, D },
+ { "region_border", "Set the region border thickness.", OFFSET(region_border), AV_OPT_TYPE_INT, { .i64 = 3 }, 1, 128, D },
+ { NULL },
+};
+
+static const AVClass xcbgrab_class = {
+ .class_name = "xcbgrab indev",
+ .item_name = av_default_item_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+ .category = AV_CLASS_CATEGORY_DEVICE_VIDEO_INPUT,
+};
+
+static int xcbgrab_reposition(AVFormatContext *s,
+ xcb_query_pointer_reply_t *p,
+ xcb_get_geometry_reply_t *geo)
+{
+ XCBGrabContext *c = s->priv_data;
+ int x = c->x, y = c->y, p_x = p->win_x, p_y = p->win_y;
+ int w = c->width, h = c->height, f = c->follow_mouse;
+
+ if (!p || !geo)
+ return AVERROR(EIO);
+
+ if (f == FOLLOW_CENTER) {
+ x = p_x - w / 2;
+ y = p_y - h / 2;
+ } else {
+ int left = x + f;
+ int right = x + w - f;
+ int top = y + f;
+ int bottom = y + h + f;
+ if (p_x > right) {
+ x += p_x - right;
+ } else if (p_x < left) {
+ x -= left - p_x;
+ }
+ if (p_y > bottom) {
+ y += p_y - bottom;
+ } else if (p_y < top) {
+ y -= top - p_y;
+ }
+ }
+
+ c->x = FFMIN(FFMAX(0, x), geo->width - w);
+ c->y = FFMIN(FFMAX(0, y), geo->height - h);
+
+ return 0;
+}
+
+static int xcbgrab_frame(AVFormatContext *s, AVPacket *pkt)
+{
+ XCBGrabContext *c = s->priv_data;
+ xcb_get_image_cookie_t iq;
+ xcb_get_image_reply_t *img;
+ xcb_drawable_t drawable = c->screen->root;
+ uint8_t *data;
+ int length, ret;
+
+ iq = xcb_get_image(c->conn, XCB_IMAGE_FORMAT_Z_PIXMAP, drawable,
+ c->x, c->y, c->width, c->height, ~0);
+
+ img = xcb_get_image_reply(c->conn, iq, NULL);
+ if (!img)
+ return AVERROR(EAGAIN);
+
+ data = xcb_get_image_data(img);
+ length = xcb_get_image_data_length(img);
+
+ ret = av_new_packet(pkt, length);
+
+ if (!ret)
+ memcpy(pkt->data, data, length);
+
+ free(img);
+
+ return ret;
+}
+
+static void wait_frame(AVFormatContext *s, AVPacket *pkt)
+{
+ XCBGrabContext *c = s->priv_data;
+ int64_t curtime, delay;
+ int64_t frame_time = av_rescale_q(1, c->time_base, AV_TIME_BASE_Q);
+
+ c->time_frame += frame_time;
+
+ for (;;) {
+ curtime = av_gettime();
+ delay = c->time_frame - curtime;
+ if (delay <= 0)
+ break;
+ av_usleep(delay);
+ }
+
+ pkt->pts = curtime;
+}
+
+#if CONFIG_LIBXCB_SHM
+static int check_shm(xcb_connection_t *conn)
+{
+ xcb_shm_query_version_cookie_t cookie = xcb_shm_query_version(conn);
+ xcb_shm_query_version_reply_t *reply;
+
+ reply = xcb_shm_query_version_reply(conn, cookie, NULL);
+ if (reply) {
+ free(reply);
+ return 1;
+ }
+
+ return 0;
+}
+
+static void dealloc_shm(void *unused, uint8_t *data)
+{
+ shmdt(data);
+}
+
+static int xcbgrab_frame_shm(AVFormatContext *s, AVPacket *pkt)
+{
+ XCBGrabContext *c = s->priv_data;
+ xcb_shm_get_image_cookie_t iq;
+ xcb_shm_get_image_reply_t *img;
+ xcb_drawable_t drawable = c->screen->root;
+ uint8_t *data;
+ int size = c->frame_size + FF_INPUT_BUFFER_PADDING_SIZE;
+ int id = shmget(IPC_PRIVATE, size, IPC_CREAT | 0777);
+ xcb_generic_error_t *e = NULL;
+
+ if (id == -1) {
+ char errbuf[1024];
+ int err = AVERROR(errno);
+ av_strerror(err, errbuf, sizeof(errbuf));
+ av_log(s, AV_LOG_ERROR, "Cannot get %d bytes of shared memory: %s.\n",
+ size, errbuf);
+ return err;
+ }
+
+ xcb_shm_attach(c->conn, c->segment, id, 0);
+
+ iq = xcb_shm_get_image(c->conn, drawable,
+ c->x, c->y, c->width, c->height, ~0,
+ XCB_IMAGE_FORMAT_Z_PIXMAP, c->segment, 0);
+
+ xcb_shm_detach(c->conn, c->segment);
+
+ img = xcb_shm_get_image_reply(c->conn, iq, &e);
+
+ xcb_flush(c->conn);
+
+ if (e) {
+ av_log(s, AV_LOG_ERROR,
+ "Cannot get the image data "
+ "event_error: response_type:%u error_code:%u "
+ "sequence:%u resource_id:%u minor_code:%u major_code:%u.\n",
+ e->response_type, e->error_code,
+ e->sequence, e->resource_id, e->minor_code, e->major_code);
+
+ shmctl(id, IPC_RMID, 0);
+ return AVERROR(EACCES);
+ }
+
+ free(img);
+
+ data = shmat(id, NULL, 0);
+ shmctl(id, IPC_RMID, 0);
+
+ if ((intptr_t)data == -1)
+ return AVERROR(errno);
+
+ pkt->buf = av_buffer_create(data, size, dealloc_shm, NULL, 0);
+ if (!pkt->buf) {
+ shmdt(data);
+ return AVERROR(ENOMEM);
+ }
+
+ pkt->data = pkt->buf->data;
+ pkt->size = c->frame_size;
+
+ return 0;
+}
+#endif /* CONFIG_LIBXCB_SHM */
+
+#if CONFIG_LIBXCB_XFIXES
+static int check_xfixes(xcb_connection_t *conn)
+{
+ xcb_xfixes_query_version_cookie_t cookie;
+ xcb_xfixes_query_version_reply_t *reply;
+
+ cookie = xcb_xfixes_query_version(conn, XCB_XFIXES_MAJOR_VERSION,
+ XCB_XFIXES_MINOR_VERSION);
+ reply = xcb_xfixes_query_version_reply(conn, cookie, NULL);
+
+ if (reply) {
+ free(reply);
+ return 1;
+ }
+ return 0;
+}
+
+#define BLEND(target, source, alpha) \
+ (target) + ((source) * (255 - (alpha)) + 255 / 2) / 255
+
+static void xcbgrab_draw_mouse(AVFormatContext *s, AVPacket *pkt,
+ xcb_query_pointer_reply_t *p,
+ xcb_get_geometry_reply_t *geo)
+{
+ XCBGrabContext *gr = s->priv_data;
+ uint32_t *cursor;
+ uint8_t *image = pkt->data;
+ int stride = gr->bpp / 8;
+ xcb_xfixes_get_cursor_image_cookie_t cc;
+ xcb_xfixes_get_cursor_image_reply_t *ci;
+ int cx, cy, x, y, w, h, c_off, i_off;
+
+ cc = xcb_xfixes_get_cursor_image(gr->conn);
+ ci = xcb_xfixes_get_cursor_image_reply(gr->conn, cc, NULL);
+ if (!ci)
+ return;
+
+ cursor = xcb_xfixes_get_cursor_image_cursor_image(ci);
+ if (!cursor)
+ return;
+
+ cx = ci->x - ci->xhot;
+ cy = ci->y - ci->yhot;
+
+ x = FFMAX(cx, gr->x);
+ y = FFMAX(cy, gr->y);
+
+ w = FFMIN(cx + ci->width, gr->x + gr->width) - x;
+ h = FFMIN(cy + ci->height, gr->y + gr->height) - y;
+
+ c_off = x - cx;
+ i_off = x - gr->x;
+
+ cursor += (y - cy) * ci->width;
+ image += (y - gr->y) * gr->width * stride;
+
+ for (y = 0; y < h; y++) {
+ cursor += c_off;
+ image += i_off * stride;
+ for (x = 0; x < w; x++, cursor++, image += stride) {
+ int r, g, b, a;
+
+ r = *cursor & 0xff;
+ g = (*cursor >> 8) & 0xff;
+ b = (*cursor >> 16) & 0xff;
+ a = (*cursor >> 24) & 0xff;
+
+ if (!a)
+ continue;
+
+ if (a == 255) {
+ image[0] = r;
+ image[1] = g;
+ image[2] = b;
+ } else {
+ image[0] = BLEND(r, image[0], a);
+ image[1] = BLEND(g, image[1], a);
+ image[2] = BLEND(b, image[2], a);
+ }
+
+ }
+ cursor += ci->width - w - c_off;
+ image += (gr->width - w - i_off) * stride;
+ }
+
+ free(ci);
+}
+#endif /* CONFIG_LIBXCB_XFIXES */
+
+static void xcbgrab_update_region(AVFormatContext *s)
+{
+ XCBGrabContext *c = s->priv_data;
+ const uint32_t args[] = { c->x - c->region_border,
+ c->y - c->region_border };
+
+ xcb_configure_window(c->conn,
+ c->window,
+ XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y,
+ args);
+}
+
+static int xcbgrab_read_packet(AVFormatContext *s, AVPacket *pkt)
+{
+ XCBGrabContext *c = s->priv_data;
+ xcb_query_pointer_cookie_t pc;
+ xcb_get_geometry_cookie_t gc;
+ xcb_query_pointer_reply_t *p = NULL;
+ xcb_get_geometry_reply_t *geo = NULL;
+ int ret = 0;
+
+ wait_frame(s, pkt);
+
+ if (c->follow_mouse || c->draw_mouse) {
+ pc = xcb_query_pointer(c->conn, c->screen->root);
+ gc = xcb_get_geometry(c->conn, c->screen->root);
+ p = xcb_query_pointer_reply(c->conn, pc, NULL);
+ geo = xcb_get_geometry_reply(c->conn, gc, NULL);
+ }
+
+ if (c->follow_mouse && p->same_screen)
+ xcbgrab_reposition(s, p, geo);
+
+ if (c->show_region)
+ xcbgrab_update_region(s);
+
+#if CONFIG_LIBXCB_SHM
+ if (c->has_shm && xcbgrab_frame_shm(s, pkt) < 0)
+ c->has_shm = 0;
+#endif
+ if (!c->has_shm)
+ ret = xcbgrab_frame(s, pkt);
+
+#if CONFIG_LIBXCB_XFIXES
+ if (c->draw_mouse && p->same_screen)
+ xcbgrab_draw_mouse(s, pkt, p, geo);
+#endif
+
+ free(p);
+ free(geo);
+
+ return ret;
+}
+
+static av_cold int xcbgrab_read_close(AVFormatContext *s)
+{
+ XCBGrabContext *ctx = s->priv_data;
+
+ xcb_disconnect(ctx->conn);
+
+ return 0;
+}
+
+static xcb_screen_t *get_screen(const xcb_setup_t *setup, int screen_num)
+{
+ xcb_screen_iterator_t it = xcb_setup_roots_iterator(setup);
+ xcb_screen_t *screen = NULL;
+
+ for (; it.rem > 0; xcb_screen_next (&it)) {
+ if (!screen_num) {
+ screen = it.data;
+ break;
+ }
+
+ screen_num--;
+ }
+
+ return screen;
+}
+
+static int pixfmt_from_pixmap_format(AVFormatContext *s, int depth,
+ int *pix_fmt)
+{
+ XCBGrabContext *c = s->priv_data;
+ const xcb_setup_t *setup = xcb_get_setup(c->conn);
+ const xcb_format_t *fmt = xcb_setup_pixmap_formats(setup);
+ int length = xcb_setup_pixmap_formats_length(setup);
+
+ *pix_fmt = 0;
+
+ while (length--) {
+ if (fmt->depth == depth) {
+ switch (depth) {
+ case 32:
+ if (fmt->bits_per_pixel == 32)
+ *pix_fmt = AV_PIX_FMT_ARGB;
+ break;
+ case 24:
+ if (fmt->bits_per_pixel == 32)
+ *pix_fmt = AV_PIX_FMT_RGB32;
+ else if (fmt->bits_per_pixel == 24)
+ *pix_fmt = AV_PIX_FMT_RGB24;
+ break;
+ case 16:
+ if (fmt->bits_per_pixel == 16)
+ *pix_fmt = AV_PIX_FMT_RGB565;
+ break;
+ case 15:
+ if (fmt->bits_per_pixel == 16)
+ *pix_fmt = AV_PIX_FMT_RGB555;
+ break;
+ case 8:
+ if (fmt->bits_per_pixel == 8)
+ *pix_fmt = AV_PIX_FMT_RGB8;
+ break;
+ }
+ }
+
+ if (*pix_fmt) {
+ c->bpp = fmt->bits_per_pixel;
+ c->frame_size = c->width * c->height * fmt->bits_per_pixel / 8;
+ return 0;
+ }
+
+ fmt++;
+ }
+ av_log(s, AV_LOG_ERROR, "Pixmap format not mappable.\n");
+
+ return AVERROR_PATCHWELCOME;
+}
+
+static int create_stream(AVFormatContext *s)
+{
+ XCBGrabContext *c = s->priv_data;
+ AVStream *st = avformat_new_stream(s, NULL);
+ xcb_get_geometry_cookie_t gc;
+ xcb_get_geometry_reply_t *geo;
+ int ret;
+
+ if (!st)
+ return AVERROR(ENOMEM);
+
+ ret = av_parse_video_size(&c->width, &c->height, c->video_size);
+ if (ret < 0)
+ return ret;
+
+ ret = av_parse_video_rate(&st->avg_frame_rate, c->framerate);
+ if (ret < 0)
+ return ret;
+
+ avpriv_set_pts_info(st, 64, 1, 1000000);
+
+ gc = xcb_get_geometry(c->conn, c->screen->root);
+ geo = xcb_get_geometry_reply(c->conn, gc, NULL);
+
+ c->width = FFMIN(geo->width, c->width);
+ c->height = FFMIN(geo->height, c->height);
+ c->time_base = (AVRational){ st->avg_frame_rate.den,
+ st->avg_frame_rate.num };
+ c->time_frame = av_gettime();
+
+ st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
+ st->codec->codec_id = AV_CODEC_ID_RAWVIDEO;
+ st->codec->width = c->width;
+ st->codec->height = c->height;
+ st->codec->time_base = c->time_base;
+
+ ret = pixfmt_from_pixmap_format(s, geo->depth, &st->codec->pix_fmt);
+
+ free(geo);
+
+ return ret;
+}
+
+static void draw_rectangle(AVFormatContext *s)
+{
+ XCBGrabContext *c = s->priv_data;
+ xcb_gcontext_t gc = xcb_generate_id(c->conn);
+ uint32_t mask = XCB_GC_FOREGROUND |
+ XCB_GC_BACKGROUND |
+ XCB_GC_LINE_WIDTH |
+ XCB_GC_LINE_STYLE |
+ XCB_GC_FILL_STYLE;
+ uint32_t values[] = { c->screen->black_pixel,
+ c->screen->white_pixel,
+ c->region_border,
+ XCB_LINE_STYLE_DOUBLE_DASH,
+ XCB_FILL_STYLE_SOLID };
+ xcb_rectangle_t r = { 1, 1,
+ c->width + c->region_border * 2 - 3,
+ c->height + c->region_border * 2 - 3 };
+
+ xcb_create_gc(c->conn, gc, c->window, mask, values);
+
+ xcb_poly_rectangle(c->conn, c->window, gc, 1, &r);
+}
+
+static void setup_window(AVFormatContext *s)
+{
+ XCBGrabContext *c = s->priv_data;
+ uint32_t mask = XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK;
+ uint32_t values[] = { 1,
+ XCB_EVENT_MASK_EXPOSURE |
+ XCB_EVENT_MASK_STRUCTURE_NOTIFY };
+ xcb_rectangle_t rect = { c->x, c->y, c->width, c->height };
+
+ c->window = xcb_generate_id(c->conn);
+
+ xcb_create_window(c->conn, XCB_COPY_FROM_PARENT,
+ c->window,
+ c->screen->root,
+ c->x - c->region_border,
+ c->y - c->region_border,
+ c->width + c->region_border * 2,
+ c->height + c->region_border * 2,
+ 0,
+ XCB_WINDOW_CLASS_INPUT_OUTPUT,
+ XCB_COPY_FROM_PARENT,
+ mask, values);
+
+#if CONFIG_LIBXCB_SHAPE
+ xcb_shape_rectangles(c->conn, XCB_SHAPE_SO_SUBTRACT,
+ XCB_SHAPE_SK_BOUNDING, XCB_CLIP_ORDERING_UNSORTED,
+ c->window,
+ c->region_border, c->region_border,
+ 1, &rect);
+#endif
+
+ xcb_map_window(c->conn, c->window);
+
+ draw_rectangle(s);
+}
+
+static av_cold int xcbgrab_read_header(AVFormatContext *s)
+{
+ XCBGrabContext *c = s->priv_data;
+ int screen_num, ret;
+ const xcb_setup_t *setup;
+ char *display_name = av_strdup(s->filename);
+
+ if (!display_name)
+ return AVERROR(ENOMEM);
+
+ if (!sscanf(s->filename, "%[^+]+%d,%d", display_name, &c->x, &c->y)) {
+ *display_name = 0;
+ sscanf(s->filename, "+%d,%d", &c->x, &c->y);
+ }
+
+ c->conn = xcb_connect(display_name, &screen_num);
+ av_freep(&display_name);
+ if ((ret = xcb_connection_has_error(c->conn))) {
+ av_log(s, AV_LOG_ERROR, "Cannot open display %s, error %d.\n",
+ (*s->filename) ? s->filename : "default", ret);
+ return AVERROR(EIO);
+ }
+ setup = xcb_get_setup(c->conn);
+
+ c->screen = get_screen(setup, screen_num);
+ if (!c->screen) {
+ av_log(s, AV_LOG_ERROR, "The screen %d does not exist.\n",
+ screen_num);
+ xcbgrab_read_close(s);
+ return AVERROR(EIO);
+ }
+
+#if CONFIG_LIBXCB_SHM
+ c->segment = xcb_generate_id(c->conn);
+#endif
+
+ ret = create_stream(s);
+
+ if (ret < 0) {
+ xcbgrab_read_close(s);
+ return ret;
+ }
+
+#if CONFIG_LIBXCB_SHM
+ c->has_shm = check_shm(c->conn);
+#endif
+
+#if CONFIG_LIBXCB_XFIXES
+ if (c->draw_mouse) {
+ if (!(c->draw_mouse = check_xfixes(c->conn))) {
+ av_log(s, AV_LOG_WARNING,
+ "XFixes not available, cannot draw the mouse.\n");
+ }
+ if (c->bpp < 24) {
+ avpriv_report_missing_feature(s, "%d bits per pixel screen",
+ c->bpp);
+ c->draw_mouse = 0;
+ }
+ }
+#endif
+
+ if (c->show_region)
+ setup_window(s);
+
+ return 0;
+}
+
+AVInputFormat ff_x11grab_xcb_demuxer = {
+ .name = "x11grab",
+ .long_name = NULL_IF_CONFIG_SMALL("X11 screen capture, using XCB"),
+ .priv_data_size = sizeof(XCBGrabContext),
+ .read_header = xcbgrab_read_header,
+ .read_packet = xcbgrab_read_packet,
+ .read_close = xcbgrab_read_close,
+ .flags = AVFMT_NOFILE,
+ .priv_class = &xcbgrab_class,
+};
OBJS-$(CONFIG_AVCODEC) += avcodec.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_VIDSTABTRANSFORM_FILTER) += vidstabutils.o vf_vidstabtransform.o
OBJS-$(CONFIG_VIGNETTE_FILTER) += vf_vignette.o
OBJS-$(CONFIG_W3FDIF_FILTER) += vf_w3fdif.o
+OBJS-$(CONFIG_XBR_FILTER) += vf_xbr.o
OBJS-$(CONFIG_YADIF_FILTER) += vf_yadif.o
OBJS-$(CONFIG_ZMQ_FILTER) += f_zmq.o
OBJS-$(CONFIG_ZOOMPAN_FILTER) += vf_zoompan.o
+++ /dev/null
-/*
- * Copyright (c) 2010 S.N. Hemanth Meenakshisundaram <smeenaks@ucsd.edu>
- * Copyright (c) 2011 Stefano Sabatini
- * Copyright (c) 2011 Mina Nagy Zaki
- *
- * 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
- * sample format and channel layout conversion audio filter
- */
-
-#include "libavutil/channel_layout.h"
-#include "libavutil/opt.h"
-#include "libswresample/swresample.h"
-#include "avfilter.h"
-#include "audio.h"
-#include "internal.h"
-
-typedef struct {
- const AVClass *class;
- enum AVSampleFormat out_sample_fmt;
- int64_t out_chlayout;
- struct SwrContext *swr;
- char *format_str;
- char *channel_layout_str;
-} AConvertContext;
-
-#define OFFSET(x) offsetof(AConvertContext, x)
-#define A AV_OPT_FLAG_AUDIO_PARAM
-#define F AV_OPT_FLAG_FILTERING_PARAM
-static const AVOption aconvert_options[] = {
- { "sample_fmt", "", OFFSET(format_str), AV_OPT_TYPE_STRING, .flags = A|F },
- { "channel_layout", "", OFFSET(channel_layout_str), AV_OPT_TYPE_STRING, .flags = A|F },
- { NULL }
-};
-
-AVFILTER_DEFINE_CLASS(aconvert);
-
-static av_cold int init(AVFilterContext *ctx)
-{
- AConvertContext *aconvert = ctx->priv;
- int ret = 0;
-
- av_log(ctx, AV_LOG_WARNING, "This filter is deprecated, use aformat instead\n");
-
- aconvert->out_sample_fmt = AV_SAMPLE_FMT_NONE;
- aconvert->out_chlayout = 0;
-
- if (aconvert->format_str && strcmp(aconvert->format_str, "auto") &&
- (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, NULL, aconvert->channel_layout_str, ctx);
- return ret;
-}
-
-static av_cold void uninit(AVFilterContext *ctx)
-{
- AConvertContext *aconvert = ctx->priv;
- swr_free(&aconvert->swr);
-}
-
-static int query_formats(AVFilterContext *ctx)
-{
- AVFilterFormats *formats = NULL;
- AConvertContext *aconvert = ctx->priv;
- AVFilterLink *inlink = ctx->inputs[0];
- AVFilterLink *outlink = ctx->outputs[0];
- AVFilterChannelLayouts *layouts;
-
- ff_formats_ref(ff_all_formats(AVMEDIA_TYPE_AUDIO),
- &inlink->out_formats);
- if (aconvert->out_sample_fmt != AV_SAMPLE_FMT_NONE) {
- formats = NULL;
- ff_add_format(&formats, aconvert->out_sample_fmt);
- ff_formats_ref(formats, &outlink->in_formats);
- } else
- ff_formats_ref(ff_all_formats(AVMEDIA_TYPE_AUDIO),
- &outlink->in_formats);
-
- ff_channel_layouts_ref(ff_all_channel_layouts(),
- &inlink->out_channel_layouts);
- if (aconvert->out_chlayout != 0) {
- layouts = NULL;
- ff_add_channel_layout(&layouts, aconvert->out_chlayout);
- ff_channel_layouts_ref(layouts, &outlink->in_channel_layouts);
- } else
- ff_channel_layouts_ref(ff_all_channel_layouts(),
- &outlink->in_channel_layouts);
-
- return 0;
-}
-
-static int config_output(AVFilterLink *outlink)
-{
- int ret;
- AVFilterContext *ctx = outlink->src;
- AVFilterLink *inlink = ctx->inputs[0];
- AConvertContext *aconvert = ctx->priv;
- char buf1[64], buf2[64];
-
- /* if not specified in args, use the format and layout of the output */
- if (aconvert->out_sample_fmt == AV_SAMPLE_FMT_NONE)
- aconvert->out_sample_fmt = outlink->format;
- if (aconvert->out_chlayout == 0)
- aconvert->out_chlayout = outlink->channel_layout;
-
- aconvert->swr = swr_alloc_set_opts(aconvert->swr,
- aconvert->out_chlayout, aconvert->out_sample_fmt, inlink->sample_rate,
- inlink->channel_layout, inlink->format, inlink->sample_rate,
- 0, ctx);
- if (!aconvert->swr)
- return AVERROR(ENOMEM);
- ret = swr_init(aconvert->swr);
- if (ret < 0)
- return ret;
-
- av_get_channel_layout_string(buf1, sizeof(buf1),
- -1, inlink ->channel_layout);
- av_get_channel_layout_string(buf2, sizeof(buf2),
- -1, outlink->channel_layout);
- av_log(ctx, AV_LOG_VERBOSE,
- "fmt:%s cl:%s -> fmt:%s cl:%s\n",
- av_get_sample_fmt_name(inlink ->format), buf1,
- av_get_sample_fmt_name(outlink->format), buf2);
-
- return 0;
-}
-
-static int filter_frame(AVFilterLink *inlink, AVFrame *insamplesref)
-{
- AConvertContext *aconvert = inlink->dst->priv;
- const int n = insamplesref->nb_samples;
- AVFilterLink *const outlink = inlink->dst->outputs[0];
- AVFrame *outsamplesref = ff_get_audio_buffer(outlink, n);
- int ret;
-
- if (!outsamplesref)
- return AVERROR(ENOMEM);
- swr_convert(aconvert->swr, outsamplesref->extended_data, n,
- (void *)insamplesref->extended_data, n);
-
- av_frame_copy_props(outsamplesref, insamplesref);
- av_frame_set_channels(outsamplesref, outlink->channels);
- outsamplesref->channel_layout = outlink->channel_layout;
-
- ret = ff_filter_frame(outlink, outsamplesref);
- av_frame_free(&insamplesref);
- return ret;
-}
-
-static const AVFilterPad aconvert_inputs[] = {
- {
- .name = "default",
- .type = AVMEDIA_TYPE_AUDIO,
- .filter_frame = filter_frame,
- },
- { NULL }
-};
-
-static const AVFilterPad aconvert_outputs[] = {
- {
- .name = "default",
- .type = AVMEDIA_TYPE_AUDIO,
- .config_props = config_output,
- },
- { NULL }
-};
-
-AVFilter ff_af_aconvert = {
- .name = "aconvert",
- .description = NULL_IF_CONFIG_SMALL("Convert the input audio to sample_fmt:channel_layout."),
- .priv_size = sizeof(AConvertContext),
- .priv_class = &aconvert_class,
- .init = init,
- .uninit = uninit,
- .query_formats = query_formats,
- .inputs = aconvert_inputs,
- .outputs = aconvert_outputs,
-};
int i;
for (i = 0; i < s->nb_delays; i++)
- av_free(s->chandelay[i].samples);
+ av_freep(&s->chandelay[i].samples);
av_freep(&s->chandelay);
}
AVFilterLink *outlink = inlink->dst->outputs[0];
int nb_samples = buf->nb_samples;
AVFrame *out_buf;
- int64_t cur_sample = av_rescale_q(buf->pts, (AVRational){1, outlink->sample_rate}, outlink->time_base);
+ int64_t cur_sample = av_rescale_q(buf->pts, inlink->time_base, (AVRational){1, inlink->sample_rate});
if ((!s->type && (s->start_sample + s->nb_samples < cur_sample)) ||
( s->type && (cur_sample + s->nb_samples < s->start_sample)))
typedef struct MixContext {
const AVClass *class; /**< class for AVOptions */
- AVFloatDSPContext fdsp;
+ AVFloatDSPContext *fdsp;
int nb_inputs; /**< number of inputs */
int active_inputs; /**< number of input currently active */
plane_size = FFALIGN(plane_size, 16);
for (p = 0; p < planes; p++) {
- s->fdsp.vector_fmac_scalar((float *)out_buf->extended_data[p],
+ s->fdsp->vector_fmac_scalar((float *)out_buf->extended_data[p],
(float *) in_buf->extended_data[p],
s->input_scale[i], plane_size);
}
ff_insert_inpad(ctx, i, &pad);
}
- avpriv_float_dsp_init(&s->fdsp, 0);
+ s->fdsp = avpriv_float_dsp_alloc(0);
+ if (!s->fdsp)
+ return AVERROR(ENOMEM);
return 0;
}
av_freep(&s->frame_list);
av_freep(&s->input_state);
av_freep(&s->input_scale);
+ av_freep(&s->fdsp);
for (i = 0; i < ctx->nb_inputs; i++)
av_freep(&ctx->input_pads[i].name);
static int query_formats(AVFilterContext *ctx)
{
AVFilterFormats *formats = NULL;
+ AVFilterChannelLayouts *layouts;
+
+ layouts = ff_all_channel_layouts();
+
+ if (!layouts)
+ return AVERROR(ENOMEM);
+
ff_add_format(&formats, AV_SAMPLE_FMT_FLT);
ff_add_format(&formats, AV_SAMPLE_FMT_FLTP);
ff_set_common_formats(ctx, formats);
- ff_set_common_channel_layouts(ctx, ff_all_channel_layouts());
+ ff_set_common_channel_layouts(ctx, layouts);
ff_set_common_samplerates(ctx, ff_all_samplerates());
return 0;
}
struct SwrContext *swr;
int64_t next_pts;
int req_fullfilled;
+ int more_data;
} AResampleContext;
static av_cold int init_dict(AVFilterContext *ctx, AVDictionary **opts)
} else {
out_samplerates = ff_all_samplerates();
}
+ if (!out_samplerates) {
+ av_log(ctx, AV_LOG_ERROR, "Cannot allocate output samplerates.\n");
+ return AVERROR(ENOMEM);
+ }
+
ff_formats_ref(out_samplerates, &outlink->in_samplerates);
if(out_format != AV_SAMPLE_FMT_NONE) {
delay = swr_get_delay(aresample->swr, outlink->sample_rate);
if (delay > 0)
- n_out += delay;
+ n_out += FFMIN(delay, FFMAX(4096, n_out));
outsamplesref = ff_get_audio_buffer(outlink, n_out);
return 0;
}
+ aresample->more_data = outsamplesref->nb_samples == n_out; // Indicate that there is probably more data in our buffers
+
outsamplesref->nb_samples = n_out;
ret = ff_filter_frame(outlink, outsamplesref);
return ret;
}
-static int request_frame(AVFilterLink *outlink)
+static int flush_frame(AVFilterLink *outlink, int final, AVFrame **outsamplesref_ret)
{
AVFilterContext *ctx = outlink->src;
AResampleContext *aresample = ctx->priv;
AVFilterLink *const inlink = outlink->src->inputs[0];
+ AVFrame *outsamplesref;
+ int n_out = 4096;
+ int64_t pts;
+
+ outsamplesref = ff_get_audio_buffer(outlink, n_out);
+ *outsamplesref_ret = outsamplesref;
+ 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, final ? NULL : (void*)outsamplesref->extended_data, 0);
+ if (n_out <= 0) {
+ av_frame_free(&outsamplesref);
+ return (n_out == 0) ? AVERROR_EOF : n_out;
+ }
+
+ outsamplesref->sample_rate = outlink->sample_rate;
+ outsamplesref->nb_samples = n_out;
+
+ outsamplesref->pts = pts;
+
+ return 0;
+}
+
+static int request_frame(AVFilterLink *outlink)
+{
+ AVFilterContext *ctx = outlink->src;
+ AResampleContext *aresample = ctx->priv;
int ret;
+ // First try to get data from the internal buffers
+ if (aresample->more_data) {
+ AVFrame *outsamplesref;
+
+ if (flush_frame(outlink, 0, &outsamplesref) >= 0) {
+ return ff_filter_frame(outlink, outsamplesref);
+ }
+ }
+ aresample->more_data = 0;
+
+ // Second request more data from the input
aresample->req_fullfilled = 0;
do{
ret = ff_request_frame(ctx->inputs[0]);
}while(!aresample->req_fullfilled && ret>=0);
+ // Third if we hit the end flush
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);
- return (n_out == 0) ? AVERROR_EOF : n_out;
- }
-
- outsamplesref->sample_rate = outlink->sample_rate;
- outsamplesref->nb_samples = n_out;
- outsamplesref->pts = pts;
+ if ((ret = flush_frame(outlink, 1, &outsamplesref)) < 0)
+ return ret;
return ff_filter_frame(outlink, outsamplesref);
}
static int channelmap_query_formats(AVFilterContext *ctx)
{
ChannelMapContext *s = ctx->priv;
+ AVFilterChannelLayouts *layouts;
ff_set_common_formats(ctx, ff_planar_sample_fmts());
ff_set_common_samplerates(ctx, ff_all_samplerates());
- ff_channel_layouts_ref(ff_all_channel_layouts(), &ctx->inputs[0]->out_channel_layouts);
+
+ layouts = ff_all_channel_layouts();
+ if (!layouts)
+ return AVERROR(ENOMEM);
+
+ ff_channel_layouts_ref(layouts, &ctx->inputs[0]->out_channel_layouts);
ff_channel_layouts_ref(s->channel_layouts, &ctx->outputs[0]->in_channel_layouts);
return 0;
ff_add_channel_layout(&layouts, s->channel_layout);
ff_channel_layouts_ref(layouts, &ctx->outputs[0]->in_channel_layouts);
- for (i = 0; i < ctx->nb_inputs; i++)
- ff_channel_layouts_ref(ff_all_channel_layouts(),
- &ctx->inputs[i]->out_channel_layouts);
+ for (i = 0; i < ctx->nb_inputs; i++) {
+ layouts = ff_all_channel_layouts();
+ if (!layouts)
+ return AVERROR(ENOMEM);
+ ff_channel_layouts_ref(layouts, &ctx->inputs[i]->out_channel_layouts);
+ }
ff_set_common_formats (ctx, ff_planar_sample_fmts());
ff_set_common_samplerates(ctx, ff_all_samplerates());
return AVERROR(ENOMEM);
if (s->options) {
+ int ret;
AVDictionaryEntry *e = NULL;
while ((e = av_dict_get(s->options, "", e, AV_DICT_IGNORE_SUFFIX)))
av_log(ctx, AV_LOG_VERBOSE, "lavr option: %s=%s\n", e->key, e->value);
- av_opt_set_dict(s->avr, &s->options);
+ ret = av_opt_set_dict(s->avr, &s->options);
+ if (ret < 0)
+ return ret;
}
av_opt_set_int(s->avr, "in_channel_layout", inlink ->channel_layout, 0);
static av_cold int init(AVFilterContext *ctx)
{
VolumeContext *vol = ctx->priv;
+
+ vol->fdsp = avpriv_float_dsp_alloc(0);
+ if (!vol->fdsp)
+ return AVERROR(ENOMEM);
+
return set_expr(&vol->volume_pexpr, vol->volume_expr, ctx);
}
VolumeContext *vol = ctx->priv;
av_expr_free(vol->volume_pexpr);
av_opt_free(vol);
+ av_freep(&vol->fdsp);
}
static int query_formats(AVFilterContext *ctx)
vol->scale_samples = scale_samples_s32;
break;
case AV_SAMPLE_FMT_FLT:
- avpriv_float_dsp_init(&vol->fdsp, 0);
vol->samples_align = 4;
break;
case AV_SAMPLE_FMT_DBL:
- avpriv_float_dsp_init(&vol->fdsp, 0);
vol->samples_align = 8;
break;
}
}
} else if (av_get_packed_sample_fmt(vol->sample_fmt) == AV_SAMPLE_FMT_FLT) {
for (p = 0; p < vol->planes; p++) {
- vol->fdsp.vector_fmul_scalar((float *)out_buf->extended_data[p],
+ vol->fdsp->vector_fmul_scalar((float *)out_buf->extended_data[p],
(const float *)buf->extended_data[p],
vol->volume, plane_samples);
}
} else {
for (p = 0; p < vol->planes; p++) {
- vol->fdsp.vector_dmul_scalar((double *)out_buf->extended_data[p],
+ vol->fdsp->vector_dmul_scalar((double *)out_buf->extended_data[p],
(const double *)buf->extended_data[p],
vol->volume, plane_samples);
}
typedef struct VolumeContext {
const AVClass *class;
- AVFloatDSPContext fdsp;
+ AVFloatDSPContext *fdsp;
enum PrecisionType precision;
enum EvalMode eval_mode;
const char *volume_expr;
return;
initialized = 1;
-#if FF_API_ACONVERT_FILTER
- REGISTER_FILTER(ACONVERT, aconvert, af);
-#endif
REGISTER_FILTER(ADELAY, adelay, af);
REGISTER_FILTER(AECHO, aecho, af);
REGISTER_FILTER(AEVAL, aeval, af);
REGISTER_FILTER(VIDSTABTRANSFORM, vidstabtransform, vf);
REGISTER_FILTER(VIGNETTE, vignette, vf);
REGISTER_FILTER(W3FDIF, w3fdif, vf);
+ REGISTER_FILTER(XBR, xbr, vf);
REGISTER_FILTER(YADIF, yadif, vf);
REGISTER_FILTER(ZMQ, zmq, vf);
REGISTER_FILTER(ZOOMPAN, zoompan, vf);
return 0;
}
#endif
-
-#if FF_API_FILL_FRAME
-int avfilter_fill_frame_from_audio_buffer_ref(AVFrame *frame,
- const AVFilterBufferRef *samplesref)
-{
- return avfilter_copy_buf_props(frame, samplesref);
-}
-
-int avfilter_fill_frame_from_video_buffer_ref(AVFrame *frame,
- const AVFilterBufferRef *picref)
-{
- return avfilter_copy_buf_props(frame, picref);
-}
-
-int avfilter_fill_frame_from_buffer_ref(AVFrame *frame,
- const AVFilterBufferRef *ref)
-{
- return avfilter_copy_buf_props(frame, ref);
-}
-#endif
int perms);
#endif
-#if FF_API_FILL_FRAME
-/**
- * Fill an AVFrame with the information stored in samplesref.
- *
- * @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
- * failure
- * @deprecated Use avfilter_copy_buf_props() instead.
- */
-attribute_deprecated
-int avfilter_fill_frame_from_audio_buffer_ref(AVFrame *frame,
- const AVFilterBufferRef *samplesref);
-
-/**
- * Fill an AVFrame with the information stored in picref.
- *
- * @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
- * failure
- * @deprecated Use avfilter_copy_buf_props() instead.
- */
-attribute_deprecated
-int avfilter_fill_frame_from_video_buffer_ref(AVFrame *frame,
- const AVFilterBufferRef *picref);
-
-/**
- * Fill an AVFrame with information stored in ref.
- *
- * @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
- * failure
- * @deprecated Use avfilter_copy_buf_props() instead.
- */
-attribute_deprecated
-int avfilter_fill_frame_from_buffer_ref(AVFrame *frame,
- const AVFilterBufferRef *ref);
-#endif
-
#endif /* AVFILTER_AVCODEC_H */
static const AVOption concat_options[] = {
{ "n", "specify the number of segments", OFFSET(nb_segments),
- AV_OPT_TYPE_INT, { .i64 = 2 }, 2, INT_MAX, V|A|F},
+ AV_OPT_TYPE_INT, { .i64 = 2 }, 1, INT_MAX, V|A|F},
{ "v", "specify the number of video streams",
OFFSET(nb_streams[AVMEDIA_TYPE_VIDEO]),
AV_OPT_TYPE_INT, { .i64 = 1 }, 0, INT_MAX, V|F },
}
for (i = 0; i < ctx->nb_outputs; i++)
av_freep(&ctx->output_pads[i].name);
- av_free(cat->in);
+ av_freep(&cat->in);
}
AVFilter ff_avf_concat = {
showwaves->req_fullfilled = 1;
showwaves->outpicref = NULL;
showwaves->buf_idx = 0;
- for (i = 0; i <= nb_channels; i++)
+ for (i = 0; i < nb_channels; i++)
showwaves->buf_idy[i] = 0;
return ret;
}
AVFilterLink *inlink;
if (!link) continue;
+ if (!link->src || !link->dst) {
+ av_log(filter, AV_LOG_ERROR,
+ "Not all input and output are properly linked (%d).\n", i);
+ return AVERROR(EINVAL);
+ }
inlink = link->src->nb_inputs ? link->src->inputs[0] : NULL;
link->current_pts = AV_NOPTS_VALUE;
return min;
}
-static const char *const var_names[] = { "t", "n", "pos", NULL };
-enum { VAR_T, VAR_N, VAR_POS, VAR_VARS_NB };
+static const char *const var_names[] = {
+ "t",
+ "n",
+ "pos",
+ "w",
+ "h",
+ NULL
+};
+
+enum {
+ VAR_T,
+ VAR_N,
+ VAR_POS,
+ VAR_W,
+ VAR_H,
+ VAR_VARS_NB
+};
static int set_enable_expr(AVFilterContext *ctx, const char *expr)
{
int64_t pos = av_frame_get_pkt_pos(out);
dstctx->var_values[VAR_N] = link->frame_count;
dstctx->var_values[VAR_T] = pts == AV_NOPTS_VALUE ? NAN : pts * av_q2d(link->time_base);
+ dstctx->var_values[VAR_W] = link->w;
+ dstctx->var_values[VAR_H] = link->h;
dstctx->var_values[VAR_POS] = pos == -1 ? NAN : pos;
dstctx->is_disabled = fabs(av_expr_eval(dstctx->enable, dstctx->var_values, NULL)) < 0.5;
if ((ret = avfilter_insert_filter(link, convert, 0, 0)) < 0)
return ret;
- filter_query_formats(convert);
+ if ((ret = filter_query_formats(convert)) < 0)
+ return ret;
+
inlink = convert->inputs[0];
outlink = convert->outputs[0];
av_assert0( inlink-> in_formats->refcount > 0);
#define ADD_FORMAT(f, fmt, type, list, nb) \
do { \
type *fmts; \
+ void *oldf = *f; \
\
if (!(*f) && !(*f = av_mallocz(sizeof(**f)))) \
return AVERROR(ENOMEM); \
\
fmts = av_realloc((*f)->list, \
sizeof(*(*f)->list) * ((*f)->nb + 1));\
- if (!fmts) \
+ if (!fmts) { \
+ if (!oldf) \
+ av_freep(f); \
return AVERROR(ENOMEM); \
+ } \
\
(*f)->list = fmts; \
(*f)->list[(*f)->nb++] = fmt; \
}
#define SET_COMMON_FORMATS(ctx, fmts, in_fmts, out_fmts, ref, list) \
-{ \
+if (fmts) { \
int count = 0, i; \
\
for (i = 0; i < ctx->nb_inputs; i++) { \
if (p->filter_ctx) {
ret = link_filter(p->filter_ctx, p->pad_idx, filt_ctx, pad, log_ctx);
- av_free(p->name);
- av_free(p);
+ av_freep(&p->name);
+ av_freep(&p);
if (ret < 0)
return ret;
} else {
av_free(name);
return ret;
}
- av_free(match->name);
- av_free(name);
- av_free(match);
- av_free(input);
+ av_freep(&match->name);
+ av_freep(&name);
+ av_freep(&match);
+ av_freep(&input);
} else {
/* Not in the list, so add the first input as a open_output */
input->name = name;
--- /dev/null
+/*
+ * 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.
+ */
+
+/**
+ * @file
+ * progressive to interlaced content filter, inspired by heavy debugging of
+ * tinterlace filter.
+ */
+
+#ifndef AVFILTER_INTERLACE_H
+#define AVFILTER_INTERLACE_H
+
+#include "libavutil/common.h"
+#include "libavutil/imgutils.h"
+#include "libavutil/opt.h"
+
+#include "avfilter.h"
+#include "formats.h"
+#include "internal.h"
+#include "video.h"
+
+enum ScanMode {
+ MODE_TFF = 0,
+ MODE_BFF = 1,
+};
+
+enum FieldType {
+ FIELD_UPPER = 0,
+ FIELD_LOWER = 1,
+};
+
+typedef struct InterlaceContext {
+ const AVClass *class;
+ enum ScanMode scan; // top or bottom field first scanning
+ int lowpass; // enable or disable low pass filterning
+ AVFrame *cur, *next; // the two frames from which the new one is obtained
+ void (*lowpass_line)(uint8_t *dstp, ptrdiff_t linesize, const uint8_t *srcp,
+ const uint8_t *srcp_above, const uint8_t *srcp_below);
+} InterlaceContext;
+
+void ff_interlace_init_x86(InterlaceContext *interlace);
+
+#endif /* AVFILTER_INTERLACE_H */
int contrast;
};
-#if HAVE_MMX && HAVE_6REGS
+#if HAVE_MMX_INLINE && HAVE_6REGS
static void process_MMX(unsigned char *dest, int dstride, unsigned char *src, int sstride,
int w, int h, int brightness, int contrast)
{
if (args) sscanf(args, "%d:%d", &vf->priv->brightness, &vf->priv->contrast);
process = process_C;
-#if HAVE_MMX && HAVE_6REGS
+#if HAVE_MMX_INLINE && HAVE_6REGS
if(ff_gCpuCaps.hasMMX) process = process_MMX;
#endif
par->lut_clean = 1;
}
-#if HAVE_MMX && HAVE_6REGS
+#if HAVE_MMX_INLINE && HAVE_6REGS
static
void affine_1d_MMX (eq2_param_t *par, unsigned char *dst, unsigned char *src,
unsigned w, unsigned h, unsigned dstride, unsigned sstride)
if ((par->c == 1.0) && (par->b == 0.0) && (par->g == 1.0)) {
par->adjust = NULL;
}
-#if HAVE_MMX && HAVE_6REGS
+#if HAVE_MMX_INLINE && HAVE_6REGS
else if (par->g == 1.0 && ff_gCpuCaps.hasMMX) {
par->adjust = &affine_1d_MMX;
}
};
-#if !HAVE_MMX
+#if !HAVE_MMX_INLINE
//This func reads from 1 slice, 1 and clears 0 & 1
static void store_slice_c(uint8_t *dst, int16_t *src, int dst_stride, int src_stride, int width, int height, int log2_scale)
#define row_idct_s row_idct_c
#define row_fdct_s row_fdct_c
-#else /* HAVE_MMX */
+#else /* HAVE_MMX_INLINE */
//This func reads from 1 slice, 1 and clears 0 & 1
static void store_slice_mmx(uint8_t *dst, int16_t *src, long dst_stride, long src_stride, long width, long height, long log2_scale)
#define column_fidct_s column_fidct_mmx
#define row_idct_s row_idct_mmx
#define row_fdct_s row_fdct_mmx
-#endif // HAVE_MMX
+#endif // HAVE_MMX_INLINE
static void filter(struct vf_priv_s *p, uint8_t *dst, uint8_t *src,
int dst_stride, int src_stride,
}
}
-#if HAVE_MMX
+#if HAVE_MMX_INLINE
if(ff_gCpuCaps.hasMMX) __asm__ volatile ("emms\n\t");
#endif
-#if HAVE_MMX2
+#if HAVE_MMXEXT_INLINE
if(ff_gCpuCaps.hasMMX2) __asm__ volatile ("sfence\n\t");
#endif
return ff_vf_next_put_image(vf,dmpi, pts);
#define THRESHOLD(r,x,t) if(((unsigned)((x)+t))>t*2) r=(x);else r=0;
#define DESCALE(x,n) (((x) + (1 << ((n)-1))) >> n)
-#if HAVE_MMX
+#if HAVE_MMX_INLINE
DECLARE_ASM_CONST(8, uint64_t, MM_FIX_0_382683433)=FIX64(0.382683433, 14);
DECLARE_ALIGNED(8, uint64_t, ff_MM_FIX_0_541196100)=FIX64(0.541196100, 14);
DECLARE_ASM_CONST(8, uint64_t, MM_DESCALE_RND)=C64(4);
DECLARE_ASM_CONST(8, uint64_t, MM_2)=C64(2);
-#else /* !HAVE_MMX */
+#else /* !HAVE_MMX_INLINE */
typedef int32_t int_simd16_t;
static const int16_t FIX_0_382683433=FIX(0.382683433, 14);
#endif
-#if !HAVE_MMX
+#if !HAVE_MMX_INLINE
static void column_fidct_c(int16_t* thr_adr, int16_t *data, int16_t *output, int cnt)
{
}
}
-#else /* HAVE_MMX */
+#else /* HAVE_MMX_INLINE */
static void column_fidct_mmx(int16_t* thr_adr, int16_t *data, int16_t *output, int cnt)
{
);
}
-#endif // HAVE_MMX
+#endif // HAVE_MMX_INLINE
-#if !HAVE_MMX
+#if !HAVE_MMX_INLINE
static void row_idct_c(int16_t* workspace,
int16_t* output_adr, int output_stride, int cnt)
}
}
-#else /* HAVE_MMX */
+#else /* HAVE_MMX_INLINE */
static void row_idct_mmx (int16_t* workspace,
int16_t* output_adr, int output_stride, int cnt)
);
}
-#endif // HAVE_MMX
+#endif // HAVE_MMX_INLINE
-#if !HAVE_MMX
+#if !HAVE_MMX_INLINE
static void row_fdct_c(int16_t *data, const uint8_t *pixels, int line_size, int cnt)
{
}
}
-#else /* HAVE_MMX */
+#else /* HAVE_MMX_INLINE */
static void row_fdct_mmx(int16_t *data, const uint8_t *pixels, int line_size, int cnt)
{
: "%"REG_d);
}
-#endif // HAVE_MMX
+#endif // HAVE_MMX_INLINE
}
}
-#if HAVE_MMX
+#if HAVE_MMX_INLINE
static void pack_nn_MMX(unsigned char *dst, unsigned char *y,
unsigned char *u, unsigned char *v, int w,
int av_unused us, int av_unused vs)
pack_nn = pack_nn_C;
pack_li_0 = pack_li_0_C;
pack_li_1 = pack_li_1_C;
-#if HAVE_MMX
+#if HAVE_MMX_INLINE
if(ff_gCpuCaps.hasMMX) {
pack_nn = pack_nn_MMX;
#if HAVE_EBX_AVAILABLE
}
}
-#if HAVE_MMX
+#if HAVE_MMX_INLINE
static void dctB_mmx(int16_t *dst, int16_t *src){
__asm__ volatile (
"movq (%0), %%mm0 \n\t"
memcpy_pic(dmpi->planes[2], mpi->planes[2], mpi->w>>mpi->chroma_x_shift, mpi->h>>mpi->chroma_y_shift, dmpi->stride[2], mpi->stride[2]);
}
-#if HAVE_MMX
+#if HAVE_MMX_INLINE
if(ff_gCpuCaps.hasMMX) __asm__ volatile ("emms\n\t");
#endif
-#if HAVE_MMX2
+#if HAVE_MMXEXT_INLINE
if(ff_gCpuCaps.hasMMX2) __asm__ volatile ("sfence\n\t");
#endif
case 2: requantize= mediumthresh_c; break;
}
-#if HAVE_MMX
+#if HAVE_MMX_INLINE
if(ff_gCpuCaps.hasMMX){
dctB= dctB_mmx;
}
}
}
-#if HAVE_MMX
+#if HAVE_MMX_INLINE
if(ff_gCpuCaps.hasMMX) __asm__ volatile ("emms\n\t");
#endif
-#if HAVE_MMX2
+#if HAVE_MMXEXT_INLINE
if(ff_gCpuCaps.hasMMX2) __asm__ volatile ("sfence\n\t");
#endif
if(vf->priv->qp < 0)
vf->priv->qp = 0;
-// #if HAVE_MMX
+// #if HAVE_MMX_INLINE
// if(ff_gCpuCaps.hasMMX){
// store_slice= store_slice_mmx;
// }
--- /dev/null
+/*
+ * Copyright (c) 2011 Stefano Sabatini
+ * Copyright (c) 2010 Baptiste Coudurier
+ * Copyright (c) 2003 Michael Zucchi <notzed@ximian.com>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with FFmpeg; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+/**
+ * @file
+ * temporal field interlace filter, ported from MPlayer/libmpcodecs
+ */
+#ifndef AVFILTER_TINTERLACE_H
+#define AVFILTER_TINTERLACE_H
+
+#include "libavutil/opt.h"
+#include "avfilter.h"
+
+enum TInterlaceMode {
+ MODE_MERGE = 0,
+ MODE_DROP_EVEN,
+ MODE_DROP_ODD,
+ MODE_PAD,
+ MODE_INTERLEAVE_TOP,
+ MODE_INTERLEAVE_BOTTOM,
+ MODE_INTERLACEX2,
+ MODE_NB,
+};
+
+typedef struct {
+ const AVClass *class;
+ enum TInterlaceMode mode; ///< interlace mode selected
+ AVRational preout_time_base;
+ int flags; ///< flags affecting interlacing algorithm
+ int frame; ///< number of the output frame
+ int vsub; ///< chroma vertical subsampling
+ AVFrame *cur;
+ AVFrame *next;
+ uint8_t *black_data[4]; ///< buffer used to fill padded lines
+ int black_linesize[4];
+ void (*lowpass_line)(uint8_t *dstp, ptrdiff_t width, const uint8_t *srcp,
+ const uint8_t *srcp_above, const uint8_t *srcp_below);
+} TInterlaceContext;
+
+void ff_tinterlace_init_x86(TInterlaceContext *interlace);
+
+#endif /* AVFILTER_TINTERLACE_H */
#include "libavutil/version.h"
#define LIBAVFILTER_VERSION_MAJOR 5
-#define LIBAVFILTER_VERSION_MINOR 1
-#define LIBAVFILTER_VERSION_MICRO 100
+#define LIBAVFILTER_VERSION_MINOR 2
+#define LIBAVFILTER_VERSION_MICRO 103
#define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \
LIBAVFILTER_VERSION_MINOR, \
#ifndef FF_API_FOO_COUNT
#define FF_API_FOO_COUNT (LIBAVFILTER_VERSION_MAJOR < 6)
#endif
-#ifndef FF_API_FILL_FRAME
-#define FF_API_FILL_FRAME (LIBAVFILTER_VERSION_MAJOR < 5)
-#endif
-#ifndef FF_API_BUFFERSRC_BUFFER
-#define FF_API_BUFFERSRC_BUFFER (LIBAVFILTER_VERSION_MAJOR < 5)
-#endif
#ifndef FF_API_AVFILTERBUFFER
#define FF_API_AVFILTERBUFFER (LIBAVFILTER_VERSION_MAJOR < 6)
#endif
#ifndef FF_API_OLD_FILTER_OPTS
#define FF_API_OLD_FILTER_OPTS (LIBAVFILTER_VERSION_MAJOR < 6)
#endif
-#ifndef FF_API_ACONVERT_FILTER
-#define FF_API_ACONVERT_FILTER (LIBAVFILTER_VERSION_MAJOR < 5)
-#endif
#ifndef FF_API_AVFILTER_OPEN
#define FF_API_AVFILTER_OPEN (LIBAVFILTER_VERSION_MAJOR < 6)
#endif
#ifndef FF_API_OLD_GRAPH_PARSE
#define FF_API_OLD_GRAPH_PARSE (LIBAVFILTER_VERSION_MAJOR < 5)
#endif
-#ifndef FF_API_DRAWTEXT_OLD_TIMELINE
-#define FF_API_DRAWTEXT_OLD_TIMELINE (LIBAVFILTER_VERSION_MAJOR < 5)
-#endif
#ifndef FF_API_NOCONST_GET_NAME
#define FF_API_NOCONST_GET_NAME (LIBAVFILTER_VERSION_MAJOR < 6)
#endif
#include "libavutil/random_seed.h"
#include "libavutil/parseutils.h"
#include "libavutil/timecode.h"
+#include "libavutil/time_internal.h"
#include "libavutil/tree.h"
#include "libavutil/lfg.h"
#include "avfilter.h"
AVExpr *x_pexpr, *y_pexpr; ///< parsed expressions for x and y
int64_t basetime; ///< base pts time in the real world for display
double var_values[VAR_VARS_NB];
-#if FF_API_DRAWTEXT_OLD_TIMELINE
- char *draw_expr; ///< expression for draw
- AVExpr *draw_pexpr; ///< parsed expression for draw
- int draw; ///< set to zero to prevent drawing
-#endif
AVLFG prng; ///< random
char *tc_opt_string; ///< specified timecode option string
AVRational tc_rate; ///< frame rate for timecode
{"borderw", "set border width", OFFSET(borderw), AV_OPT_TYPE_INT, {.i64=0}, INT_MIN, INT_MAX , FLAGS},
{"tabsize", "set tab size", OFFSET(tabsize), AV_OPT_TYPE_INT, {.i64=4}, 0, INT_MAX , FLAGS},
{"basetime", "set base time", OFFSET(basetime), AV_OPT_TYPE_INT64, {.i64=AV_NOPTS_VALUE}, INT64_MIN, INT64_MAX , FLAGS},
-#if FF_API_DRAWTEXT_OLD_TIMELINE
- {"draw", "if false do not draw (deprecated)", OFFSET(draw_expr), AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX, FLAGS},
-#endif
#if CONFIG_LIBFONTCONFIG
{ "font", "Font name", OFFSET(font), AV_OPT_TYPE_STRING, { .str = "Sans" }, .flags = FLAGS },
#endif
return err;
}
- if (!(tmp = av_realloc(s->text, textbuf_size + 1))) {
+ if (textbuf_size > SIZE_MAX - 1 || !(tmp = av_realloc(s->text, textbuf_size + 1))) {
av_file_unmap(textbuf, textbuf_size);
return AVERROR(ENOMEM);
}
DrawTextContext *s = ctx->priv;
Glyph *glyph;
-#if FF_API_DRAWTEXT_OLD_TIMELINE
- if (s->draw_expr)
- av_log(ctx, AV_LOG_WARNING, "'draw' option is deprecated and will be removed soon, "
- "you are encouraged to use the generic timeline support through the 'enable' option\n");
-#endif
-
if (!s->fontfile && !CONFIG_LIBFONTCONFIG) {
av_log(ctx, AV_LOG_ERROR, "No font filename provided\n");
return AVERROR(EINVAL);
av_expr_free(s->x_pexpr);
av_expr_free(s->y_pexpr);
-#if FF_API_DRAWTEXT_OLD_TIMELINE
- av_expr_free(s->draw_pexpr);
- s->x_pexpr = s->y_pexpr = s->draw_pexpr = NULL;
-#else
s->x_pexpr = s->y_pexpr = NULL;
-#endif
av_freep(&s->positions);
s->nb_positions = 0;
av_expr_free(s->x_pexpr);
av_expr_free(s->y_pexpr);
-#if FF_API_DRAWTEXT_OLD_TIMELINE
- av_expr_free(s->draw_pexpr);
- s->x_pexpr = s->y_pexpr = s->draw_pexpr = NULL;
-#else
s->x_pexpr = s->y_pexpr = NULL;
-#endif
if ((ret = av_expr_parse(&s->x_pexpr, s->x_expr, var_names,
NULL, NULL, fun2_names, fun2, 0, ctx)) < 0 ||
NULL, NULL, fun2_names, fun2, 0, ctx)) < 0)
return AVERROR(EINVAL);
-#if FF_API_DRAWTEXT_OLD_TIMELINE
- if (s->draw_expr &&
- (ret = av_expr_parse(&s->draw_pexpr, s->draw_expr, var_names,
- NULL, NULL, fun2_names, fun2, 0, ctx)) < 0)
- return ret;
-#endif
return 0;
}
return 0;
}
-#if !HAVE_LOCALTIME_R
-static void localtime_r(const time_t *t, struct tm *tm)
-{
- *tm = *localtime(t);
-}
-#endif
-
static int func_strftime(AVFilterContext *ctx, AVBPrint *bp,
char *fct, unsigned argc, char **argv, int tag)
{
if (tag == 'L')
localtime_r(&now, &tm);
else
- tm = *gmtime(&now);
+ tm = *gmtime_r(&now, &tm);
av_bprint_strftime(bp, fmt, &tm);
return 0;
}
s->x = s->var_values[VAR_X] = av_expr_eval(s->x_pexpr, s->var_values, &s->prng);
s->y = s->var_values[VAR_Y] = av_expr_eval(s->y_pexpr, s->var_values, &s->prng);
s->x = s->var_values[VAR_X] = av_expr_eval(s->x_pexpr, s->var_values, &s->prng);
-#if FF_API_DRAWTEXT_OLD_TIMELINE
- if (s->draw_pexpr){
- s->draw = av_expr_eval(s->draw_pexpr, s->var_values, &s->prng);
-
- if(!s->draw)
- return 0;
- }
- if (ctx->is_disabled)
- return 0;
-#endif
box_w = FFMIN(width - 1 , max_text_line_w);
box_h = FFMIN(height - 1, y + s->max_glyph_h);
.inputs = avfilter_vf_drawtext_inputs,
.outputs = avfilter_vf_drawtext_outputs,
.process_command = command,
-#if FF_API_DRAWTEXT_OLD_TIMELINE
- .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL,
-#else
.flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
-#endif
};
int i;
int ret;
- if (!s->pix_fmts)
+ if (!s->pix_fmts) {
+ av_log(ctx, AV_LOG_ERROR, "Empty output format string.\n");
return AVERROR(EINVAL);
+ }
/* count the formats */
cur = s->pix_fmts;
static const AVOption idet_options[] = {
{ "intl_thres", "set interlacing threshold", OFFSET(interlace_threshold), AV_OPT_TYPE_FLOAT, {.dbl = 1.04}, -1, FLT_MAX, FLAGS },
{ "prog_thres", "set progressive threshold", OFFSET(progressive_threshold), AV_OPT_TYPE_FLOAT, {.dbl = 1.5}, -1, FLT_MAX, FLAGS },
+ { "rep_thres", "set repeat threshold", OFFSET(repeat_threshold), AV_OPT_TYPE_FLOAT, {.dbl = 3.0}, -1, FLT_MAX, FLAGS },
+ { "half_life", "half life of cumulative statistics", OFFSET(half_life), AV_OPT_TYPE_FLOAT, {.dbl = 0.0}, -1, INT_MAX, FLAGS },
{ NULL }
};
static const char *type2str(Type type)
{
switch(type) {
- case TFF : return "Top Field First ";
- case BFF : return "Bottom Field First";
- case PROGRSSIVE : return "Progressive ";
- case UNDETERMINED: return "Undetermined ";
+ case TFF : return "tff";
+ case BFF : return "bff";
+ case PROGRESSIVE : return "progressive";
+ case UNDETERMINED : return "undetermined";
+ }
+ return NULL;
+}
+
+#define PRECISION 1048576
+
+static uint64_t uintpow(uint64_t b,unsigned int e)
+{
+ uint64_t r=1;
+ while(e--) r*=b;
+ return r;
+}
+
+static int av_dict_set_fxp(AVDictionary **pm, const char *key, uint64_t value, unsigned int digits,
+ int flags)
+{
+ char valuestr[44];
+ uint64_t print_precision = uintpow(10, digits);
+
+ value = av_rescale(value, print_precision, PRECISION);
+
+ snprintf(valuestr, sizeof(valuestr), "%"PRId64".%0*"PRId64,
+ value / print_precision, digits, value % print_precision);
+
+ return av_dict_set(pm, key, valuestr, flags);
+}
+
+static const char *rep2str(RepeatedField repeated_field)
+{
+ switch(repeated_field) {
+ case REPEAT_NONE : return "neither";
+ case REPEAT_TOP : return "top";
+ case REPEAT_BOTTOM : return "bottom";
}
return NULL;
}
int y, i;
int64_t alpha[2]={0};
int64_t delta=0;
+ int64_t gamma[2]={0};
Type type, best_type;
+ RepeatedField repeat;
int match = 0;
+ AVDictionary **metadata = avpriv_frame_get_metadatap(idet->cur);
for (i = 0; i < idet->csp->nb_components; i++) {
int w = idet->cur->width;
alpha[ y &1] += idet->filter_line(cur-refs, prev, cur+refs, w);
alpha[(y^1)&1] += idet->filter_line(cur-refs, next, cur+refs, w);
delta += idet->filter_line(cur-refs, cur, cur+refs, w);
+ gamma[(y^1)&1] += idet->filter_line(cur , prev, cur , w);
}
}
}else if(alpha[1] > idet->interlace_threshold * alpha[0]){
type = BFF;
}else if(alpha[1] > idet->progressive_threshold * delta){
- type = PROGRSSIVE;
+ type = PROGRESSIVE;
}else{
type = UNDETERMINED;
}
+ if ( gamma[0] > idet->repeat_threshold * gamma[1] ){
+ repeat = REPEAT_TOP;
+ } else if ( gamma[1] > idet->repeat_threshold * gamma[0] ){
+ repeat = REPEAT_BOTTOM;
+ } else {
+ repeat = REPEAT_NONE;
+ }
+
memmove(idet->history+1, idet->history, HIST_SIZE-1);
idet->history[0] = type;
best_type = UNDETERMINED;
}else if(idet->last_type == BFF){
idet->cur->top_field_first = 0;
idet->cur->interlaced_frame = 1;
- }else if(idet->last_type == PROGRSSIVE){
+ }else if(idet->last_type == PROGRESSIVE){
idet->cur->interlaced_frame = 0;
}
- idet->prestat [ type] ++;
- idet->poststat[idet->last_type] ++;
- av_log(ctx, AV_LOG_DEBUG, "Single frame:%s, Multi frame:%s\n", type2str(type), type2str(idet->last_type));
+ for(i=0; i<3; i++)
+ idet->repeats[i] = av_rescale(idet->repeats [i], idet->decay_coefficient, PRECISION);
+
+ for(i=0; i<4; i++){
+ idet->prestat [i] = av_rescale(idet->prestat [i], idet->decay_coefficient, PRECISION);
+ idet->poststat[i] = av_rescale(idet->poststat[i], idet->decay_coefficient, PRECISION);
+ }
+
+ idet->total_repeats [ repeat] ++;
+ idet->repeats [ repeat] += PRECISION;
+
+ idet->total_prestat [ type] ++;
+ idet->prestat [ type] += PRECISION;
+
+ idet->total_poststat[idet->last_type] ++;
+ idet->poststat [idet->last_type] += PRECISION;
+
+ av_log(ctx, AV_LOG_DEBUG, "Repeated Field:%12s, Single frame:%12s, Multi frame:%12s\n",
+ rep2str(repeat), type2str(type), type2str(idet->last_type));
+
+ av_dict_set (metadata, "lavfi.idet.repeated.current_frame", rep2str(repeat), 0);
+ av_dict_set_fxp(metadata, "lavfi.idet.repeated.neither", idet->repeats[REPEAT_NONE], 2, 0);
+ av_dict_set_fxp(metadata, "lavfi.idet.repeated.top", idet->repeats[REPEAT_TOP], 2, 0);
+ av_dict_set_fxp(metadata, "lavfi.idet.repeated.bottom", idet->repeats[REPEAT_BOTTOM], 2, 0);
+
+ av_dict_set (metadata, "lavfi.idet.single.current_frame", type2str(type), 0);
+ av_dict_set_fxp(metadata, "lavfi.idet.single.tff", idet->prestat[TFF], 2 , 0);
+ av_dict_set_fxp(metadata, "lavfi.idet.single.bff", idet->prestat[BFF], 2, 0);
+ av_dict_set_fxp(metadata, "lavfi.idet.single.progressive", idet->prestat[PROGRESSIVE], 2, 0);
+ av_dict_set_fxp(metadata, "lavfi.idet.single.undetermined", idet->prestat[UNDETERMINED], 2, 0);
+
+ av_dict_set (metadata, "lavfi.idet.multiple.current_frame", type2str(idet->last_type), 0);
+ av_dict_set_fxp(metadata, "lavfi.idet.multiple.tff", idet->poststat[TFF], 2, 0);
+ av_dict_set_fxp(metadata, "lavfi.idet.multiple.bff", idet->poststat[BFF], 2, 0);
+ av_dict_set_fxp(metadata, "lavfi.idet.multiple.progressive", idet->poststat[PROGRESSIVE], 2, 0);
+ av_dict_set_fxp(metadata, "lavfi.idet.multiple.undetermined", idet->poststat[UNDETERMINED], 2, 0);
}
static int filter_frame(AVFilterLink *link, AVFrame *picref)
idet->cur = idet->next;
idet->next = picref;
- if (!idet->cur)
- return 0;
+ if (!idet->cur &&
+ !(idet->cur = av_frame_clone(idet->next)))
+ return AVERROR(ENOMEM);
if (!idet->prev)
- idet->prev = av_frame_clone(idet->cur);
+ return 0;
if (!idet->csp)
idet->csp = av_pix_fmt_desc_get(link->format);
return ff_filter_frame(ctx->outputs[0], av_frame_clone(idet->cur));
}
+static int request_frame(AVFilterLink *link)
+{
+ AVFilterContext *ctx = link->src;
+ IDETContext *idet = ctx->priv;
+
+ do {
+ int ret;
+
+ if (idet->eof)
+ return AVERROR_EOF;
+
+ ret = ff_request_frame(link->src->inputs[0]);
+
+ if (ret == AVERROR_EOF && idet->cur) {
+ AVFrame *next = av_frame_clone(idet->next);
+
+ if (!next)
+ return AVERROR(ENOMEM);
+
+ filter_frame(link->src->inputs[0], next);
+ idet->eof = 1;
+ } else if (ret < 0) {
+ return ret;
+ }
+ } while (!idet->prev);
+
+ return 0;
+}
+
static av_cold void uninit(AVFilterContext *ctx)
{
IDETContext *idet = ctx->priv;
- av_log(ctx, AV_LOG_INFO, "Single frame detection: TFF:%d BFF:%d Progressive:%d Undetermined:%d\n",
- idet->prestat[TFF],
- idet->prestat[BFF],
- idet->prestat[PROGRSSIVE],
- idet->prestat[UNDETERMINED]
- );
- av_log(ctx, AV_LOG_INFO, "Multi frame detection: TFF:%d BFF:%d Progressive:%d Undetermined:%d\n",
- idet->poststat[TFF],
- idet->poststat[BFF],
- idet->poststat[PROGRSSIVE],
- idet->poststat[UNDETERMINED]
- );
+ av_log(ctx, AV_LOG_INFO, "Repeated Fields: Neither:%6"PRId64" Top:%6"PRId64" Bottom:%6"PRId64"\n",
+ idet->total_repeats[REPEAT_NONE],
+ idet->total_repeats[REPEAT_TOP],
+ idet->total_repeats[REPEAT_BOTTOM]
+ );
+ av_log(ctx, AV_LOG_INFO, "Single frame detection: TFF:%6"PRId64" BFF:%6"PRId64" Progressive:%6"PRId64" Undetermined:%6"PRId64"\n",
+ idet->total_prestat[TFF],
+ idet->total_prestat[BFF],
+ idet->total_prestat[PROGRESSIVE],
+ idet->total_prestat[UNDETERMINED]
+ );
+ av_log(ctx, AV_LOG_INFO, "Multi frame detection: TFF:%6"PRId64" BFF:%6"PRId64" Progressive:%6"PRId64" Undetermined:%6"PRId64"\n",
+ idet->total_poststat[TFF],
+ idet->total_poststat[BFF],
+ idet->total_poststat[PROGRESSIVE],
+ idet->total_poststat[UNDETERMINED]
+ );
av_frame_free(&idet->prev);
av_frame_free(&idet->cur );
{
IDETContext *idet = ctx->priv;
+ idet->eof = 0;
idet->last_type = UNDETERMINED;
memset(idet->history, UNDETERMINED, HIST_SIZE);
+ if( idet->half_life > 0 )
+ idet->decay_coefficient = (uint64_t) round( PRECISION * exp2(-1.0 / idet->half_life) );
+ else
+ idet->decay_coefficient = PRECISION;
+
idet->filter_line = ff_idet_filter_line_c;
if (ARCH_X86)
return 0;
}
-
static const AVFilterPad idet_inputs[] = {
{
.name = "default",
.name = "default",
.type = AVMEDIA_TYPE_VIDEO,
.config_props = config_output,
+ .request_frame = request_frame
},
{ NULL }
};
typedef enum {
TFF,
BFF,
- PROGRSSIVE,
+ PROGRESSIVE,
UNDETERMINED,
} Type;
+typedef enum {
+ REPEAT_NONE,
+ REPEAT_TOP,
+ REPEAT_BOTTOM,
+} RepeatedField;
+
typedef struct {
const AVClass *class;
float interlace_threshold;
float progressive_threshold;
+ float repeat_threshold;
+ float half_life;
+ uint64_t decay_coefficient;
Type last_type;
- int prestat[4];
- int poststat[4];
+
+ uint64_t repeats[3];
+ uint64_t prestat[4];
+ uint64_t poststat[4];
+ uint64_t total_repeats[3];
+ uint64_t total_prestat[4];
+ uint64_t total_poststat[4];
uint8_t history[HIST_SIZE];
ff_idet_filter_func filter_line;
const AVPixFmtDescriptor *csp;
+ int eof;
} IDETContext;
void ff_idet_init_x86(IDETContext *idet, int for_16b);
#include "formats.h"
#include "avfilter.h"
+#include "interlace.h"
#include "internal.h"
#include "video.h"
-enum ScanMode {
- MODE_TFF = 0,
- MODE_BFF = 1,
-};
-
-enum FieldType {
- FIELD_UPPER = 0,
- FIELD_LOWER = 1,
-};
-
-typedef struct InterlaceContext {
- const AVClass *class;
- enum ScanMode scan; // top or bottom field first scanning
- int lowpass; // enable or disable low pass filterning
- AVFrame *cur, *next; // the two frames from which the new one is obtained
-} InterlaceContext;
-
#define OFFSET(x) offsetof(InterlaceContext, x)
#define V AV_OPT_FLAG_VIDEO_PARAM
static const AVOption interlace_options[] = {
AVFILTER_DEFINE_CLASS(interlace);
+static void lowpass_line_c(uint8_t *dstp, ptrdiff_t linesize,
+ const uint8_t *srcp,
+ const uint8_t *srcp_above,
+ const uint8_t *srcp_below)
+{
+ int i;
+ for (i = 0; i < linesize; i++) {
+ // this calculation is an integer representation of
+ // '0.5 * current + 0.25 * above + 0.25 * below'
+ // '1 +' is for rounding.
+ dstp[i] = (1 + srcp[i] + srcp[i] + srcp_above[i] + srcp_below[i]) >> 2;
+ }
+}
+
static const enum AVPixelFormat formats_supported[] = {
AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV444P,
AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUVA420P,
outlink->frame_rate.den *= 2;
outlink->flags |= FF_LINK_FLAG_REQUEST_LOOP;
+
+ if (s->lowpass) {
+ s->lowpass_line = lowpass_line_c;
+ if (ARCH_X86)
+ ff_interlace_init_x86(s);
+ }
+
av_log(ctx, AV_LOG_VERBOSE, "%s interlacing %s lowpass filter\n",
s->scan == MODE_TFF ? "tff" : "bff", (s->lowpass) ? "with" : "without");
return 0;
}
-static void copy_picture_field(AVFrame *src_frame, AVFrame *dst_frame,
+static void copy_picture_field(InterlaceContext *s,
+ AVFrame *src_frame, AVFrame *dst_frame,
AVFilterLink *inlink, enum FieldType field_type,
int lowpass)
{
const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format);
int vsub = desc->log2_chroma_h;
- int plane, i, j;
+ int plane, j;
for (plane = 0; plane < desc->nb_components; plane++) {
int lines = (plane == 1 || plane == 2) ? FF_CEIL_RSHIFT(inlink->h, vsub) : inlink->h;
- int linesize = av_image_get_linesize(inlink->format, inlink->w, plane);
+ ptrdiff_t linesize = av_image_get_linesize(inlink->format, inlink->w, plane);
uint8_t *dstp = dst_frame->data[plane];
const uint8_t *srcp = src_frame->data[plane];
srcp_above = srcp; // there is no line above
if (j == 1)
srcp_below = srcp; // there is no line below
- for (i = 0; i < linesize; i++) {
- // this calculation is an integer representation of
- // '0.5 * current + 0.25 * above + 0.25 * below'
- // '1 +' is for rounding.
- dstp[i] = (1 + srcp[i] + srcp[i] + srcp_above[i] + srcp_below[i]) >> 2;
- }
+ s->lowpass_line(dstp, linesize, srcp, srcp_above, srcp_below);
dstp += dstp_linesize;
srcp += srcp_linesize;
}
out->pts /= 2; // adjust pts to new framerate
/* copy upper/lower field from cur */
- copy_picture_field(s->cur, out, inlink, tff ? FIELD_UPPER : FIELD_LOWER, s->lowpass);
+ copy_picture_field(s, s->cur, out, inlink, tff ? FIELD_UPPER : FIELD_LOWER, s->lowpass);
av_frame_free(&s->cur);
/* copy lower/upper field from next */
- copy_picture_field(s->next, out, inlink, tff ? FIELD_LOWER : FIELD_UPPER, s->lowpass);
+ copy_picture_field(s, s->next, out, inlink, tff ? FIELD_LOWER : FIELD_UPPER, s->lowpass);
av_frame_free(&s->next);
ret = ff_filter_frame(outlink, out);
return pow((val-minval)/(maxval-minval), gamma) * (maxval-minval)+minval;
}
+/**
+ * Compute Rec.709 gama correction of value val
+ */
+static double compute_gammaval709(void *opaque, double gamma)
+{
+ LutContext *s = opaque;
+ double val = s->var_values[VAR_CLIPVAL];
+ double minval = s->var_values[VAR_MINVAL];
+ double maxval = s->var_values[VAR_MAXVAL];
+ double level = (val - minval) / (maxval - minval);
+ level = level < 0.018 ? 4.5 * level
+ : 1.099 * pow(level, 1.0 / gamma) - 0.099;
+ return level * (maxval - minval) + minval;
+}
+
static double (* const funcs1[])(void *, double) = {
(void *)clip,
(void *)compute_gammaval,
+ (void *)compute_gammaval709,
NULL
};
static const char * const funcs1_names[] = {
"clip",
"gammaval",
+ "gammaval709",
NULL
};
#include "libavutil/lfg.h"
#include "libavutil/parseutils.h"
#include "libavutil/pixdesc.h"
-#include "libavutil/x86/asm.h"
#include "avfilter.h"
#include "formats.h"
#include "internal.h"
+#include "vf_noise.h"
#include "video.h"
-#define MAX_NOISE 5120
-#define MAX_SHIFT 1024
-#define MAX_RES (MAX_NOISE-MAX_SHIFT)
-
-#define NOISE_UNIFORM 1
-#define NOISE_TEMPORAL 2
-#define NOISE_AVERAGED 8
-#define NOISE_PATTERN 16
-
-typedef struct {
- int strength;
- unsigned flags;
- AVLFG lfg;
- int seed;
- int8_t *noise;
- int8_t *prev_shift[MAX_RES][3];
-} FilterParams;
-
-typedef struct {
- const AVClass *class;
- int nb_planes;
- int bytewidth[4];
- int height[4];
- FilterParams all;
- FilterParams param[4];
- int rand_shift[MAX_RES];
- int rand_shift_init;
- void (*line_noise)(uint8_t *dst, const uint8_t *src, const int8_t *noise, int len, int shift);
- void (*line_noise_avg)(uint8_t *dst, const uint8_t *src, int len, const int8_t * const *shift);
-} NoiseContext;
-
typedef struct ThreadData {
AVFrame *in, *out;
} ThreadData;
if (!noise)
return AVERROR(ENOMEM);
- av_lfg_init(&fp->lfg, fp->seed);
+ av_lfg_init(&fp->lfg, fp->seed + comp*31415U);
for (i = 0, j = 0; i < MAX_NOISE; i++, j++) {
if (flags & NOISE_UNIFORM) {
for (j = 0; j < 3; j++)
fp->prev_shift[i][j] = noise + (av_lfg_get(lfg) & (MAX_SHIFT - 1));
- if (!n->rand_shift_init) {
- for (i = 0; i < MAX_RES; i++)
- n->rand_shift[i] = av_lfg_get(lfg) & (MAX_SHIFT - 1);
- n->rand_shift_init = 1;
- }
-
fp->noise = noise;
return 0;
}
return 0;
}
-static inline void line_noise_c(uint8_t *dst, const uint8_t *src, const int8_t *noise,
- int len, int shift)
+void ff_line_noise_c(uint8_t *dst, const uint8_t *src, const int8_t *noise,
+ int len, int shift)
{
int i;
}
}
-#define ASMALIGN(ZEROBITS) ".p2align " #ZEROBITS "\n\t"
-
-static void line_noise_mmx(uint8_t *dst, const uint8_t *src,
- const int8_t *noise, int len, int shift)
-{
-#if HAVE_MMX_INLINE
- x86_reg mmx_len= len&(~7);
- noise+=shift;
-
- __asm__ volatile(
- "mov %3, %%"REG_a" \n\t"
- "pcmpeqb %%mm7, %%mm7 \n\t"
- "psllw $15, %%mm7 \n\t"
- "packsswb %%mm7, %%mm7 \n\t"
- ASMALIGN(4)
- "1: \n\t"
- "movq (%0, %%"REG_a"), %%mm0 \n\t"
- "movq (%1, %%"REG_a"), %%mm1 \n\t"
- "pxor %%mm7, %%mm0 \n\t"
- "paddsb %%mm1, %%mm0 \n\t"
- "pxor %%mm7, %%mm0 \n\t"
- "movq %%mm0, (%2, %%"REG_a") \n\t"
- "add $8, %%"REG_a" \n\t"
- " js 1b \n\t"
- :: "r" (src+mmx_len), "r" (noise+mmx_len), "r" (dst+mmx_len), "g" (-mmx_len)
- : "%"REG_a
- );
- if (mmx_len!=len)
- line_noise_c(dst+mmx_len, src+mmx_len, noise+mmx_len, len-mmx_len, 0);
-#endif
-}
-
-static void line_noise_mmxext(uint8_t *dst, const uint8_t *src,
- const int8_t *noise, int len, int shift)
-{
-#if HAVE_MMXEXT_INLINE
- x86_reg mmx_len= len&(~7);
- noise+=shift;
-
- __asm__ volatile(
- "mov %3, %%"REG_a" \n\t"
- "pcmpeqb %%mm7, %%mm7 \n\t"
- "psllw $15, %%mm7 \n\t"
- "packsswb %%mm7, %%mm7 \n\t"
- ASMALIGN(4)
- "1: \n\t"
- "movq (%0, %%"REG_a"), %%mm0 \n\t"
- "movq (%1, %%"REG_a"), %%mm1 \n\t"
- "pxor %%mm7, %%mm0 \n\t"
- "paddsb %%mm1, %%mm0 \n\t"
- "pxor %%mm7, %%mm0 \n\t"
- "movntq %%mm0, (%2, %%"REG_a") \n\t"
- "add $8, %%"REG_a" \n\t"
- " js 1b \n\t"
- :: "r" (src+mmx_len), "r" (noise+mmx_len), "r" (dst+mmx_len), "g" (-mmx_len)
- : "%"REG_a
- );
- if (mmx_len != len)
- line_noise_c(dst+mmx_len, src+mmx_len, noise+mmx_len, len-mmx_len, 0);
-#endif
-}
-
-static inline void line_noise_avg_c(uint8_t *dst, const uint8_t *src,
- int len, const int8_t * const *shift)
+void ff_line_noise_avg_c(uint8_t *dst, const uint8_t *src,
+ int len, const int8_t * const *shift)
{
int i;
const int8_t *src2 = (const int8_t*)src;
}
}
-static inline void line_noise_avg_mmx(uint8_t *dst, const uint8_t *src,
- int len, const int8_t * const *shift)
-{
-#if HAVE_MMX_INLINE && HAVE_6REGS
- x86_reg mmx_len= len&(~7);
-
- __asm__ volatile(
- "mov %5, %%"REG_a" \n\t"
- ASMALIGN(4)
- "1: \n\t"
- "movq (%1, %%"REG_a"), %%mm1 \n\t"
- "movq (%0, %%"REG_a"), %%mm0 \n\t"
- "paddb (%2, %%"REG_a"), %%mm1 \n\t"
- "paddb (%3, %%"REG_a"), %%mm1 \n\t"
- "movq %%mm0, %%mm2 \n\t"
- "movq %%mm1, %%mm3 \n\t"
- "punpcklbw %%mm0, %%mm0 \n\t"
- "punpckhbw %%mm2, %%mm2 \n\t"
- "punpcklbw %%mm1, %%mm1 \n\t"
- "punpckhbw %%mm3, %%mm3 \n\t"
- "pmulhw %%mm0, %%mm1 \n\t"
- "pmulhw %%mm2, %%mm3 \n\t"
- "paddw %%mm1, %%mm1 \n\t"
- "paddw %%mm3, %%mm3 \n\t"
- "paddw %%mm0, %%mm1 \n\t"
- "paddw %%mm2, %%mm3 \n\t"
- "psrlw $8, %%mm1 \n\t"
- "psrlw $8, %%mm3 \n\t"
- "packuswb %%mm3, %%mm1 \n\t"
- "movq %%mm1, (%4, %%"REG_a") \n\t"
- "add $8, %%"REG_a" \n\t"
- " js 1b \n\t"
- :: "r" (src+mmx_len), "r" (shift[0]+mmx_len), "r" (shift[1]+mmx_len), "r" (shift[2]+mmx_len),
- "r" (dst+mmx_len), "g" (-mmx_len)
- : "%"REG_a
- );
-
- if (mmx_len != len){
- const int8_t *shift2[3]={shift[0]+mmx_len, shift[1]+mmx_len, shift[2]+mmx_len};
- line_noise_avg_c(dst+mmx_len, src+mmx_len, len-mmx_len, shift2);
- }
-#endif
-}
-
static void noise(uint8_t *dst, const uint8_t *src,
int dst_linesize, int src_linesize,
int width, int start, int end, NoiseContext *n, int comp)
FilterParams *p = &n->param[comp];
int8_t *noise = p->noise;
const int flags = p->flags;
- AVLFG *lfg = &p->lfg;
- int shift, y;
+ int y;
if (!noise) {
if (dst != src)
for (y = start; y < end; y++) {
const int ix = y & (MAX_RES - 1);
- if (flags & NOISE_TEMPORAL)
- shift = av_lfg_get(lfg) & (MAX_SHIFT - 1);
- else
- shift = n->rand_shift[ix];
+ int x;
+ for (x=0; x < width; x+= MAX_RES) {
+ int w = FFMIN(width - x, MAX_RES);
+ int shift = p->rand_shift[ix];
- if (flags & NOISE_AVERAGED) {
- n->line_noise_avg(dst, src, width, (const int8_t**)p->prev_shift[ix]);
- p->prev_shift[ix][shift & 3] = noise + shift;
- } else {
- n->line_noise(dst, src, noise, width, shift);
+ if (flags & NOISE_AVERAGED) {
+ n->line_noise_avg(dst + x, src + x, w, (const int8_t**)p->prev_shift[ix]);
+ p->prev_shift[ix][shift & 3] = noise + shift;
+ } else {
+ n->line_noise(dst + x, src + x, noise, w, shift);
+ }
}
dst += dst_linesize;
src += src_linesize;
NoiseContext *n = ctx->priv;
ThreadData td;
AVFrame *out;
+ int comp, i;
if (av_frame_is_writable(inpicref)) {
out = inpicref;
av_frame_copy_props(out, inpicref);
}
+ for (comp = 0; comp < 4; comp++) {
+ FilterParams *fp = &n->param[comp];
+
+ if ((!fp->rand_shift_init || (fp->flags & NOISE_TEMPORAL)) && fp->strength) {
+
+ for (i = 0; i < MAX_RES; i++) {
+ fp->rand_shift[i] = av_lfg_get(&fp->lfg) & (MAX_SHIFT - 1);
+ }
+ fp->rand_shift_init = 1;
+ }
+ }
+
td.in = inpicref; td.out = out;
ctx->internal->execute(ctx, filter_slice, &td, NULL, FFMIN(n->height[0], ctx->graph->nb_threads));
emms_c();
{
NoiseContext *n = ctx->priv;
int ret, i;
- int cpu_flags = av_get_cpu_flags();
for (i = 0; i < 4; i++) {
if (n->all.seed >= 0)
return ret;
}
- n->line_noise = line_noise_c;
- n->line_noise_avg = line_noise_avg_c;
+ n->line_noise = ff_line_noise_c;
+ n->line_noise_avg = ff_line_noise_avg_c;
- if (HAVE_MMX_INLINE &&
- cpu_flags & AV_CPU_FLAG_MMX) {
- n->line_noise = line_noise_mmx;
-#if HAVE_6REGS
- n->line_noise_avg = line_noise_avg_mmx;
-#endif
- }
- if (HAVE_MMXEXT_INLINE &&
- cpu_flags & AV_CPU_FLAG_MMXEXT)
- n->line_noise = line_noise_mmxext;
+ if (ARCH_X86)
+ ff_noise_init_x86(n);
return 0;
}
--- /dev/null
+/*
+ * Copyright (c) 2002 Michael Niedermayer <michaelni@gmx.at>
+ * 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
+ */
+
+#ifndef AVFILTER_NOISE_H
+#define AVFILTER_NOISE_H
+
+#include "libavutil/lfg.h"
+#include "avfilter.h"
+
+#define MAX_NOISE 5120
+#define MAX_SHIFT 1024
+#define MAX_RES (MAX_NOISE-MAX_SHIFT)
+
+#define NOISE_UNIFORM 1
+#define NOISE_TEMPORAL 2
+#define NOISE_AVERAGED 8
+#define NOISE_PATTERN 16
+
+typedef struct {
+ int strength;
+ unsigned flags;
+ AVLFG lfg;
+ int seed;
+ int8_t *noise;
+ int8_t *prev_shift[MAX_RES][3];
+ int rand_shift[MAX_RES];
+ int rand_shift_init;
+} FilterParams;
+
+typedef struct {
+ const AVClass *class;
+ int nb_planes;
+ int bytewidth[4];
+ int height[4];
+ FilterParams all;
+ FilterParams param[4];
+ void (*line_noise)(uint8_t *dst, const uint8_t *src, const int8_t *noise, int len, int shift);
+ void (*line_noise_avg)(uint8_t *dst, const uint8_t *src, int len, const int8_t * const *shift);
+} NoiseContext;
+
+void ff_line_noise_c(uint8_t *dst, const uint8_t *src, const int8_t *noise, int len, int shift);
+void ff_line_noise_avg_c(uint8_t *dst, const uint8_t *src, int len, const int8_t * const *shift);
+
+void ff_noise_init_x86(NoiseContext *n);
+
+#endif /* AVFILTER_NOISE_H */
int height[4];
int hsub, vsub;
int nb_planes;
+ int sense;
int (*perspective)(AVFilterContext *ctx,
void *arg, int job, int nb_jobs);
#define OFFSET(x) offsetof(PerspectiveContext, x)
#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
+enum PERSPECTIVESense {
+ PERSPECTIVE_SENSE_SOURCE = 0, ///< coordinates give locations in source of corners of destination.
+ PERSPECTIVE_SENSE_DESTINATION = 1, ///< coordinates give locations in destination of corners of source.
+};
+
static const AVOption perspective_options[] = {
{ "x0", "set top left x coordinate", OFFSET(expr_str[0][0]), AV_OPT_TYPE_STRING, {.str="0"}, 0, 0, FLAGS },
{ "y0", "set top left y coordinate", OFFSET(expr_str[0][1]), AV_OPT_TYPE_STRING, {.str="0"}, 0, 0, FLAGS },
{ "interpolation", "set interpolation", OFFSET(interpolation), AV_OPT_TYPE_INT, {.i64=LINEAR}, 0, 1, FLAGS, "interpolation" },
{ "linear", "", 0, AV_OPT_TYPE_CONST, {.i64=LINEAR}, 0, 0, FLAGS, "interpolation" },
{ "cubic", "", 0, AV_OPT_TYPE_CONST, {.i64=CUBIC}, 0, 0, FLAGS, "interpolation" },
+ { "sense", "specify the sense of the coordinates", OFFSET(sense), AV_OPT_TYPE_INT, {.i64=PERSPECTIVE_SENSE_SOURCE}, 0, 1, FLAGS, "sense"},
+ { "source", "specify locations in source to send to corners in destination",
+ 0, AV_OPT_TYPE_CONST, {.i64=PERSPECTIVE_SENSE_SOURCE}, 0, 0, FLAGS, "sense"},
+ { "destination", "specify locations in destination to send corners of source",
+ 0, AV_OPT_TYPE_CONST, {.i64=PERSPECTIVE_SENSE_DESTINATION}, 0, 0, FLAGS, "sense"},
+
{ NULL }
};
static int config_input(AVFilterLink *inlink)
{
- double x0, x1, x2, x3, x4, x5, x6, x7, q;
+ double x0, x1, x2, x3, x4, x5, x6, x7, x8, q;
+ double t0, t1, t2, t3;
AVFilterContext *ctx = inlink->dst;
PerspectiveContext *s = ctx->priv;
double (*ref)[2] = s->ref;
if (!s->pv)
return AVERROR(ENOMEM);
- x6 = ((ref[0][0] - ref[1][0] - ref[2][0] + ref[3][0]) *
- (ref[2][1] - ref[3][1]) -
- ( ref[0][1] - ref[1][1] - ref[2][1] + ref[3][1]) *
- (ref[2][0] - ref[3][0])) * h;
- x7 = ((ref[0][1] - ref[1][1] - ref[2][1] + ref[3][1]) *
- (ref[1][0] - ref[3][0]) -
- ( ref[0][0] - ref[1][0] - ref[2][0] + ref[3][0]) *
- (ref[1][1] - ref[3][1])) * w;
- q = ( ref[1][0] - ref[3][0]) * (ref[2][1] - ref[3][1]) -
- ( ref[2][0] - ref[3][0]) * (ref[1][1] - ref[3][1]);
-
- x0 = q * (ref[1][0] - ref[0][0]) * h + x6 * ref[1][0];
- x1 = q * (ref[2][0] - ref[0][0]) * w + x7 * ref[2][0];
- x2 = q * ref[0][0] * w * h;
- x3 = q * (ref[1][1] - ref[0][1]) * h + x6 * ref[1][1];
- x4 = q * (ref[2][1] - ref[0][1]) * w + x7 * ref[2][1];
- x5 = q * ref[0][1] * w * h;
+ switch (s->sense) {
+ case PERSPECTIVE_SENSE_SOURCE:
+ x6 = ((ref[0][0] - ref[1][0] - ref[2][0] + ref[3][0]) *
+ (ref[2][1] - ref[3][1]) -
+ ( ref[0][1] - ref[1][1] - ref[2][1] + ref[3][1]) *
+ (ref[2][0] - ref[3][0])) * h;
+ x7 = ((ref[0][1] - ref[1][1] - ref[2][1] + ref[3][1]) *
+ (ref[1][0] - ref[3][0]) -
+ ( ref[0][0] - ref[1][0] - ref[2][0] + ref[3][0]) *
+ (ref[1][1] - ref[3][1])) * w;
+ q = ( ref[1][0] - ref[3][0]) * (ref[2][1] - ref[3][1]) -
+ ( ref[2][0] - ref[3][0]) * (ref[1][1] - ref[3][1]);
+
+ x0 = q * (ref[1][0] - ref[0][0]) * h + x6 * ref[1][0];
+ x1 = q * (ref[2][0] - ref[0][0]) * w + x7 * ref[2][0];
+ x2 = q * ref[0][0] * w * h;
+ x3 = q * (ref[1][1] - ref[0][1]) * h + x6 * ref[1][1];
+ x4 = q * (ref[2][1] - ref[0][1]) * w + x7 * ref[2][1];
+ x5 = q * ref[0][1] * w * h;
+ x8 = q * w * h;
+ break;
+ case PERSPECTIVE_SENSE_DESTINATION:
+ t0 = ref[0][0] * (ref[3][1] - ref[1][1]) +
+ ref[1][0] * (ref[0][1] - ref[3][1]) +
+ ref[3][0] * (ref[1][1] - ref[0][1]);
+ t1 = ref[1][0] * (ref[2][1] - ref[3][1]) +
+ ref[2][0] * (ref[3][1] - ref[1][1]) +
+ ref[3][0] * (ref[1][1] - ref[2][1]);
+ t2 = ref[0][0] * (ref[3][1] - ref[2][1]) +
+ ref[2][0] * (ref[0][1] - ref[3][1]) +
+ ref[3][0] * (ref[2][1] - ref[0][1]);
+ t3 = ref[0][0] * (ref[1][1] - ref[2][1]) +
+ ref[1][0] * (ref[2][1] - ref[0][1]) +
+ ref[2][0] * (ref[0][1] - ref[1][1]);
+
+ x0 = t0 * t1 * w * (ref[2][1] - ref[0][1]);
+ x1 = t0 * t1 * w * (ref[0][0] - ref[2][0]);
+ x2 = t0 * t1 * w * (ref[0][1] * ref[2][0] - ref[0][0] * ref[2][1]);
+ x3 = t1 * t2 * h * (ref[1][1] - ref[0][1]);
+ x4 = t1 * t2 * h * (ref[0][0] - ref[1][0]);
+ x5 = t1 * t2 * h * (ref[0][1] * ref[1][0] - ref[0][0] * ref[1][1]);
+ x6 = t1 * t2 * (ref[1][1] - ref[0][1]) +
+ t0 * t3 * (ref[2][1] - ref[3][1]);
+ x7 = t1 * t2 * (ref[0][0] - ref[1][0]) +
+ t0 * t3 * (ref[3][0] - ref[2][0]);
+ x8 = t1 * t2 * (ref[0][1] * ref[1][0] - ref[0][0] * ref[1][1]) +
+ t0 * t3 * (ref[2][0] * ref[3][1] - ref[2][1] * ref[3][0]);
+ break;
+ }
for (y = 0; y < h; y++){
for (x = 0; x < w; x++){
int u, v;
u = (int)floor(SUB_PIXELS * (x0 * x + x1 * y + x2) /
- (x6 * x + x7 * y + q * w * h) + 0.5);
+ (x6 * x + x7 * y + x8) + 0.5);
v = (int)floor(SUB_PIXELS * (x3 * x + x4 * y + x5) /
- (x6 * x + x7 * y + q * w * h) + 0.5);
+ (x6 * x + x7 * y + x8) + 0.5);
s->pv[x + y * w][0] = u;
s->pv[x + y * w][1] = v;
AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUVJ420P,
AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUVJ422P,
AV_PIX_FMT_YUV411P,
+ AV_PIX_FMT_GBRP,
AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUVJ444P,
+ AV_PIX_FMT_YUV440P, AV_PIX_FMT_YUVJ440P,
+ AV_PIX_FMT_GRAY8,
AV_PIX_FMT_NONE
};
ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
PPFilterContext *pp = inlink->dst->priv;
switch (inlink->format) {
+ case AV_PIX_FMT_GRAY8:
case AV_PIX_FMT_YUVJ420P:
case AV_PIX_FMT_YUV420P: flags |= PP_FORMAT_420; break;
case AV_PIX_FMT_YUVJ422P:
case AV_PIX_FMT_YUV422P: flags |= PP_FORMAT_422; break;
case AV_PIX_FMT_YUV411P: flags |= PP_FORMAT_411; break;
+ case AV_PIX_FMT_GBRP:
case AV_PIX_FMT_YUVJ444P:
case AV_PIX_FMT_YUV444P: flags |= PP_FORMAT_444; break;
+ case AV_PIX_FMT_YUVJ440P:
+ case AV_PIX_FMT_YUV440P: flags |= PP_FORMAT_440; break;
default: av_assert0(0);
}
int i, plane, vsub = desc->log2_chroma_h;
for (plane = 0; plane < 4 && frame->data[plane] && frame->linesize[plane]; plane++) {
- int64_t linesize = av_image_get_linesize(frame->format, frame->width, plane);
uint8_t *data = frame->data[plane];
int h = plane == 1 || plane == 2 ? FF_CEIL_RSHIFT(inlink->h, vsub) : inlink->h;
+ int linesize = av_image_get_linesize(frame->format, frame->width, plane);
if (linesize < 0)
return linesize;
enum FilterMode outfilter;
int filters;
AVFrame *frame_prev;
- char *vrep_line;
uint8_t rgba_color[4];
int yuv_color[3];
+ int nb_jobs;
+ int *jobs_rets;
+
+ AVFrame *frame_sat;
+ AVFrame *frame_hue;
} SignalstatsContext;
+typedef struct ThreadData {
+ const AVFrame *in;
+ AVFrame *out;
+} ThreadData;
+
+typedef struct ThreadDataHueSatMetrics {
+ const AVFrame *src;
+ AVFrame *dst_sat, *dst_hue;
+} ThreadDataHueSatMetrics;
+
#define OFFSET(x) offsetof(SignalstatsContext, x)
#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
static const AVOption signalstats_options[] = {
{"stat", "set statistics filters", OFFSET(filters), AV_OPT_TYPE_FLAGS, {.i64=0}, 0, INT_MAX, FLAGS, "filters"},
{"tout", "analyze pixels for temporal outliers", 0, AV_OPT_TYPE_CONST, {.i64=1<<FILTER_TOUT}, 0, 0, FLAGS, "filters"},
- {"vrep", "analyze video lines for vertical line repitition", 0, AV_OPT_TYPE_CONST, {.i64=1<<FILTER_VREP}, 0, 0, FLAGS, "filters"},
+ {"vrep", "analyze video lines for vertical line repetition", 0, AV_OPT_TYPE_CONST, {.i64=1<<FILTER_VREP}, 0, 0, FLAGS, "filters"},
{"brng", "analyze for pixels outside of broadcast range", 0, AV_OPT_TYPE_CONST, {.i64=1<<FILTER_BRNG}, 0, 0, FLAGS, "filters"},
{"out", "set video filter", OFFSET(outfilter), AV_OPT_TYPE_INT, {.i64=FILTER_NONE}, -1, FILT_NUMB-1, FLAGS, "out"},
{"tout", "highlight pixels that depict temporal outliers", 0, AV_OPT_TYPE_CONST, {.i64=FILTER_TOUT}, 0, 0, FLAGS, "out"},
- {"vrep", "highlight video lines that depict vertical line repitition", 0, AV_OPT_TYPE_CONST, {.i64=FILTER_VREP}, 0, 0, FLAGS, "out"},
+ {"vrep", "highlight video lines that depict vertical line repetition", 0, AV_OPT_TYPE_CONST, {.i64=FILTER_VREP}, 0, 0, FLAGS, "out"},
{"brng", "highlight pixels that are outside of broadcast range", 0, AV_OPT_TYPE_CONST, {.i64=FILTER_BRNG}, 0, 0, FLAGS, "out"},
{"c", "set highlight color", OFFSET(rgba_color), AV_OPT_TYPE_COLOR, {.str="yellow"}, .flags=FLAGS},
{"color", "set highlight color", OFFSET(rgba_color), AV_OPT_TYPE_COLOR, {.str="yellow"}, .flags=FLAGS},
{
SignalstatsContext *s = ctx->priv;
av_frame_free(&s->frame_prev);
- av_freep(&s->vrep_line);
+ av_frame_free(&s->frame_sat);
+ av_frame_free(&s->frame_hue);
+ av_freep(&s->jobs_rets);
}
static int query_formats(AVFilterContext *ctx)
// TODO: add more
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_YUV440P,
+ AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ411P,
+ AV_PIX_FMT_YUVJ440P,
AV_PIX_FMT_NONE
};
return 0;
}
+static AVFrame *alloc_frame(enum AVPixelFormat pixfmt, int w, int h)
+{
+ AVFrame *frame = av_frame_alloc();
+ if (!frame)
+ return NULL;
+
+ frame->format = pixfmt;
+ frame->width = w;
+ frame->height = h;
+
+ if (av_frame_get_buffer(frame, 32) < 0)
+ return NULL;
+
+ return frame;
+}
+
static int config_props(AVFilterLink *outlink)
{
AVFilterContext *ctx = outlink->src;
s->fs = inlink->w * inlink->h;
s->cfs = s->chromaw * s->chromah;
- if (s->filters & 1<<FILTER_VREP) {
- s->vrep_line = av_malloc(inlink->h * sizeof(*s->vrep_line));
- if (!s->vrep_line)
- return AVERROR(ENOMEM);
- }
+ s->nb_jobs = FFMAX(1, FFMIN(inlink->h, ctx->graph->nb_threads));
+ s->jobs_rets = av_malloc_array(s->nb_jobs, sizeof(*s->jobs_rets));
+ if (!s->jobs_rets)
+ return AVERROR(ENOMEM);
+
+ s->frame_sat = alloc_frame(AV_PIX_FMT_GRAY8, inlink->w, inlink->h);
+ s->frame_hue = alloc_frame(AV_PIX_FMT_GRAY16, inlink->w, inlink->h);
+ if (!s->frame_sat || !s->frame_hue)
+ return AVERROR(ENOMEM);
return 0;
}
-static void burn_frame(SignalstatsContext *s, AVFrame *f, int x, int y)
+static void burn_frame(const SignalstatsContext *s, AVFrame *f, int x, int y)
{
const int chromax = x >> s->hsub;
const int chromay = y >> s->vsub;
f->data[2][chromay * f->linesize[2] + chromax] = s->yuv_color[2];
}
-static int filter_brng(SignalstatsContext *s, const AVFrame *in, AVFrame *out, int y, int w, int h)
+static int filter_brng(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
{
- int x, score = 0;
- const int yc = y >> s->vsub;
- const uint8_t *pluma = &in->data[0][y * in->linesize[0]];
- const uint8_t *pchromau = &in->data[1][yc * in->linesize[1]];
- const uint8_t *pchromav = &in->data[2][yc * in->linesize[2]];
-
- for (x = 0; x < w; x++) {
- const int xc = x >> s->hsub;
- const int luma = pluma[x];
- const int chromau = pchromau[xc];
- const int chromav = pchromav[xc];
- const int filt = luma < 16 || luma > 235 ||
- chromau < 16 || chromau > 240 ||
- chromav < 16 || chromav > 240;
- score += filt;
- if (out && filt)
- burn_frame(s, out, x, y);
+ ThreadData *td = arg;
+ const SignalstatsContext *s = ctx->priv;
+ const AVFrame *in = td->in;
+ AVFrame *out = td->out;
+ const int w = in->width;
+ const int h = in->height;
+ const int slice_start = (h * jobnr ) / nb_jobs;
+ const int slice_end = (h * (jobnr+1)) / nb_jobs;
+ int x, y, score = 0;
+
+ for (y = slice_start; y < slice_end; y++) {
+ const int yc = y >> s->vsub;
+ const uint8_t *pluma = &in->data[0][y * in->linesize[0]];
+ const uint8_t *pchromau = &in->data[1][yc * in->linesize[1]];
+ const uint8_t *pchromav = &in->data[2][yc * in->linesize[2]];
+
+ for (x = 0; x < w; x++) {
+ const int xc = x >> s->hsub;
+ const int luma = pluma[x];
+ const int chromau = pchromau[xc];
+ const int chromav = pchromav[xc];
+ const int filt = luma < 16 || luma > 235 ||
+ chromau < 16 || chromau > 240 ||
+ chromav < 16 || chromav > 240;
+ score += filt;
+ if (out && filt)
+ burn_frame(s, out, x, y);
+ }
}
return score;
}
return ((abs(x - y) + abs (z - y)) / 2) - abs(z - x) > 4; // make 4 configurable?
}
-static int filter_tout(SignalstatsContext *s, const AVFrame *in, AVFrame *out, int y, int w, int h)
+static int filter_tout(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
{
+ ThreadData *td = arg;
+ const SignalstatsContext *s = ctx->priv;
+ const AVFrame *in = td->in;
+ AVFrame *out = td->out;
+ const int w = in->width;
+ const int h = in->height;
+ const int slice_start = (h * jobnr ) / nb_jobs;
+ const int slice_end = (h * (jobnr+1)) / nb_jobs;
const uint8_t *p = in->data[0];
int lw = in->linesize[0];
- int x, score = 0, filt;
+ int x, y, score = 0, filt;
- if (y - 1 < 0 || y + 1 >= h)
- return 0;
+ for (y = slice_start; y < slice_end; y++) {
- // detect two pixels above and below (to eliminate interlace artefacts)
- // should check that video format is infact interlaced.
+ if (y - 1 < 0 || y + 1 >= h)
+ continue;
+
+ // detect two pixels above and below (to eliminate interlace artefacts)
+ // should check that video format is infact interlaced.
#define FILTER(i, j) \
-filter_tout_outlier(p[(y-j) * lw + x + i], \
- p[ y * lw + x + i], \
- p[(y+j) * lw + x + i])
+ filter_tout_outlier(p[(y-j) * lw + x + i], \
+ p[ y * lw + x + i], \
+ p[(y+j) * lw + x + i])
#define FILTER3(j) (FILTER(-1, j) && FILTER(0, j) && FILTER(1, j))
- if (y - 2 >= 0 && y + 2 < h) {
- for (x = 1; x < w - 1; x++) {
- filt = FILTER3(2) && FILTER3(1);
- score += filt;
- if (filt && out)
- burn_frame(s, out, x, y);
- }
- } else {
- for (x = 1; x < w - 1; x++) {
- filt = FILTER3(1);
- score += filt;
- if (filt && out)
- burn_frame(s, out, x, y);
+ if (y - 2 >= 0 && y + 2 < h) {
+ for (x = 1; x < w - 1; x++) {
+ filt = FILTER3(2) && FILTER3(1);
+ score += filt;
+ if (filt && out)
+ burn_frame(s, out, x, y);
+ }
+ } else {
+ for (x = 1; x < w - 1; x++) {
+ filt = FILTER3(1);
+ score += filt;
+ if (filt && out)
+ burn_frame(s, out, x, y);
+ }
}
}
return score;
#define VREP_START 4
-static void filter_init_vrep(SignalstatsContext *s, const AVFrame *p, int w, int h)
+static int filter_vrep(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
{
- int i, y;
- int lw = p->linesize[0];
+ ThreadData *td = arg;
+ const SignalstatsContext *s = ctx->priv;
+ const AVFrame *in = td->in;
+ AVFrame *out = td->out;
+ const int w = in->width;
+ const int h = in->height;
+ const int slice_start = (h * jobnr ) / nb_jobs;
+ const int slice_end = (h * (jobnr+1)) / nb_jobs;
+ const uint8_t *p = in->data[0];
+ const int lw = in->linesize[0];
+ int x, y, score = 0;
- for (y = VREP_START; y < h; y++) {
- int totdiff = 0;
- int y2lw = (y - VREP_START) * lw;
- int ylw = y * lw;
+ for (y = slice_start; y < slice_end; y++) {
+ const int y2lw = (y - VREP_START) * lw;
+ const int ylw = y * lw;
+ int filt, totdiff = 0;
- for (i = 0; i < w; i++)
- totdiff += abs(p->data[0][y2lw + i] - p->data[0][ylw + i]);
+ if (y < VREP_START)
+ continue;
- /* this value should be definable */
- s->vrep_line[y] = totdiff < w;
- }
-}
+ for (x = 0; x < w; x++)
+ totdiff += abs(p[y2lw + x] - p[ylw + x]);
+ filt = totdiff < w;
-static int filter_vrep(SignalstatsContext *s, const AVFrame *in, AVFrame *out, int y, int w, int h)
-{
- int x, score = 0;
-
- if (y < VREP_START)
- return 0;
-
- for (x = 0; x < w; x++) {
- if (s->vrep_line[y]) {
- score++;
- if (out)
+ score += filt;
+ if (filt && out)
+ for (x = 0; x < w; x++)
burn_frame(s, out, x, y);
- }
}
- return score;
+ return score * w;
}
static const struct {
const char *name;
- void (*init)(SignalstatsContext *s, const AVFrame *p, int w, int h);
- int (*process)(SignalstatsContext *s, const AVFrame *in, AVFrame *out, int y, int w, int h);
+ int (*process)(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs);
} filters_def[] = {
- {"TOUT", NULL, filter_tout},
- {"VREP", filter_init_vrep, filter_vrep},
- {"BRNG", NULL, filter_brng},
+ {"TOUT", filter_tout},
+ {"VREP", filter_vrep},
+ {"BRNG", filter_brng},
{NULL}
};
#define DEPTH 256
+static int compute_sat_hue_metrics(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
+{
+ int i, j;
+ ThreadDataHueSatMetrics *td = arg;
+ const SignalstatsContext *s = ctx->priv;
+ const AVFrame *src = td->src;
+ AVFrame *dst_sat = td->dst_sat;
+ AVFrame *dst_hue = td->dst_hue;
+
+ const int slice_start = (s->chromah * jobnr ) / nb_jobs;
+ const int slice_end = (s->chromah * (jobnr+1)) / nb_jobs;
+
+ const int lsz_u = src->linesize[1];
+ const int lsz_v = src->linesize[2];
+ const uint8_t *p_u = src->data[1] + slice_start * lsz_u;
+ const uint8_t *p_v = src->data[2] + slice_start * lsz_v;
+
+ const int lsz_sat = dst_sat->linesize[0];
+ const int lsz_hue = dst_hue->linesize[0];
+ uint8_t *p_sat = dst_sat->data[0] + slice_start * lsz_sat;
+ uint8_t *p_hue = dst_hue->data[0] + slice_start * lsz_hue;
+
+ for (j = slice_start; j < slice_end; j++) {
+ for (i = 0; i < s->chromaw; i++) {
+ const int yuvu = p_u[i];
+ const int yuvv = p_v[i];
+ p_sat[i] = hypot(yuvu - 128, yuvv - 128); // int or round?
+ ((int16_t*)p_hue)[i] = floor((180 / M_PI) * atan2f(yuvu-128, yuvv-128) + 180);
+ }
+ p_u += lsz_u;
+ p_v += lsz_v;
+ p_sat += lsz_sat;
+ p_hue += lsz_hue;
+ }
+
+ return 0;
+}
+
static int filter_frame(AVFilterLink *link, AVFrame *in)
{
- SignalstatsContext *s = link->dst->priv;
- AVFilterLink *outlink = link->dst->outputs[0];
+ AVFilterContext *ctx = link->dst;
+ SignalstatsContext *s = ctx->priv;
+ AVFilterLink *outlink = ctx->outputs[0];
AVFrame *out = in;
int i, j;
int w = 0, cw = 0, // in
pw = 0, cpw = 0; // prev
- int yuv, yuvu, yuvv;
int fil;
char metabuf[128];
unsigned int histy[DEPTH] = {0},
int filtot[FILT_NUMB] = {0};
AVFrame *prev;
+ AVFrame *sat = s->frame_sat;
+ AVFrame *hue = s->frame_hue;
+ const uint8_t *p_sat = sat->data[0];
+ const uint8_t *p_hue = hue->data[0];
+ const int lsz_sat = sat->linesize[0];
+ const int lsz_hue = hue->linesize[0];
+ ThreadDataHueSatMetrics td_huesat = {
+ .src = in,
+ .dst_sat = sat,
+ .dst_hue = hue,
+ };
+
if (!s->frame_prev)
s->frame_prev = av_frame_clone(in);
prev = s->frame_prev;
- if (s->outfilter != FILTER_NONE)
+ if (s->outfilter != FILTER_NONE) {
out = av_frame_clone(in);
+ av_frame_make_writable(out);
+ }
- for (fil = 0; fil < FILT_NUMB; fil ++)
- if ((s->filters & 1<<fil) && filters_def[fil].init)
- filters_def[fil].init(s, in, link->w, link->h);
+ ctx->internal->execute(ctx, compute_sat_hue_metrics, &td_huesat,
+ NULL, FFMIN(s->chromah, ctx->graph->nb_threads));
// Calculate luma histogram and difference with previous frame or field.
for (j = 0; j < link->h; j++) {
for (i = 0; i < link->w; i++) {
- yuv = in->data[0][w + i];
+ const int yuv = in->data[0][w + i];
histy[yuv]++;
- dify += abs(in->data[0][w + i] - prev->data[0][pw + i]);
+ dify += abs(yuv - prev->data[0][pw + i]);
}
w += in->linesize[0];
pw += prev->linesize[0];
// Calculate chroma histogram and difference with previous frame or field.
for (j = 0; j < s->chromah; j++) {
for (i = 0; i < s->chromaw; i++) {
- int sat, hue;
-
- yuvu = in->data[1][cw+i];
- yuvv = in->data[2][cw+i];
+ const int yuvu = in->data[1][cw+i];
+ const int yuvv = in->data[2][cw+i];
histu[yuvu]++;
- difu += abs(in->data[1][cw+i] - prev->data[1][cpw+i]);
+ difu += abs(yuvu - prev->data[1][cpw+i]);
histv[yuvv]++;
- difv += abs(in->data[2][cw+i] - prev->data[2][cpw+i]);
+ difv += abs(yuvv - prev->data[2][cpw+i]);
- // int or round?
- sat = hypot(yuvu - 128, yuvv - 128);
- histsat[sat]++;
- hue = floor((180 / M_PI) * atan2f(yuvu-128, yuvv-128) + 180);
- histhue[hue]++;
+ histsat[p_sat[i]]++;
+ histhue[((int16_t*)p_hue)[i]]++;
}
cw += in->linesize[1];
cpw += prev->linesize[1];
+ p_sat += lsz_sat;
+ p_hue += lsz_hue;
}
- for (j = 0; j < link->h; j++) {
- for (fil = 0; fil < FILT_NUMB; fil ++) {
- if (s->filters & 1<<fil) {
- AVFrame *dbg = out != in && s->outfilter == fil ? out : NULL;
- filtot[fil] += filters_def[fil].process(s, in, dbg, j, link->w, link->h);
- }
+ for (fil = 0; fil < FILT_NUMB; fil ++) {
+ if (s->filters & 1<<fil) {
+ ThreadData td = {
+ .in = in,
+ .out = out != in && s->outfilter == fil ? out : NULL,
+ };
+ memset(s->jobs_rets, 0, s->nb_jobs * sizeof(*s->jobs_rets));
+ ctx->internal->execute(ctx, filters_def[fil].process,
+ &td, s->jobs_rets, s->nb_jobs);
+ for (i = 0; i < s->nb_jobs; i++)
+ filtot[fil] += s->jobs_rets[i];
}
}
.inputs = signalstats_inputs,
.outputs = signalstats_outputs,
.priv_class = &signalstats_class,
+ .flags = AVFILTER_FLAG_SLICE_THREADS,
};
uint8_t rgba_map[4];
int pix_step[4]; ///< steps per pixel for each plane of the main output
int original_w, original_h;
+ int shaping;
FFDrawContext draw;
} AssContext;
/* libass supports a log level ranging from 0 to 7 */
static const int ass_libavfilter_log_level_map[] = {
- AV_LOG_QUIET, /* 0 */
- AV_LOG_PANIC, /* 1 */
- AV_LOG_FATAL, /* 2 */
- AV_LOG_ERROR, /* 3 */
- AV_LOG_WARNING, /* 4 */
- AV_LOG_INFO, /* 5 */
- AV_LOG_VERBOSE, /* 6 */
- AV_LOG_DEBUG, /* 7 */
+ [0] = AV_LOG_FATAL, /* MSGL_FATAL */
+ [1] = AV_LOG_ERROR, /* MSGL_ERR */
+ [2] = AV_LOG_WARNING, /* MSGL_WARN */
+ [3] = AV_LOG_WARNING, /* <undefined> */
+ [4] = AV_LOG_INFO, /* MSGL_INFO */
+ [5] = AV_LOG_INFO, /* <undefined> */
+ [6] = AV_LOG_VERBOSE, /* MSGL_V */
+ [7] = AV_LOG_DEBUG, /* MSGL_DBG2 */
};
static void ass_log(int ass_level, const char *fmt, va_list args, void *ctx)
{
- int level = ass_libavfilter_log_level_map[ass_level];
+ const int ass_level_clip = av_clip(ass_level, 0,
+ FF_ARRAY_ELEMS(ass_libavfilter_log_level_map) - 1);
+ const int level = ass_libavfilter_log_level_map[ass_level_clip];
av_vlog(ctx, level, fmt, args);
av_log(ctx, level, "\n");
if (ass->original_w && ass->original_h)
ass_set_aspect_ratio(ass->renderer, (double)inlink->w / inlink->h,
(double)ass->original_w / ass->original_h);
+ if (ass->shaping != -1)
+ ass_set_shaper(ass->renderer, ass->shaping);
return 0;
}
static const AVOption ass_options[] = {
COMMON_OPTIONS
+ {"shaping", "set shaping engine", OFFSET(shaping), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1, FLAGS, "shaping_mode"},
+ {"auto", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = -1}, INT_MIN, INT_MAX, FLAGS, "shaping_mode"},
+ {"simple", "simple shaping", 0, AV_OPT_TYPE_CONST, {.i64 = ASS_SHAPING_SIMPLE}, INT_MIN, INT_MAX, FLAGS, "shaping_mode"},
+ {"complex", "complex shaping", 0, AV_OPT_TYPE_CONST, {.i64 = ASS_SHAPING_COMPLEX}, INT_MIN, INT_MAX, FLAGS, "shaping_mode"},
{NULL},
};
#include "libavutil/avassert.h"
#include "avfilter.h"
#include "internal.h"
-
-enum TInterlaceMode {
- MODE_MERGE = 0,
- MODE_DROP_EVEN,
- MODE_DROP_ODD,
- MODE_PAD,
- MODE_INTERLEAVE_TOP,
- MODE_INTERLEAVE_BOTTOM,
- MODE_INTERLACEX2,
- MODE_NB,
-};
-
-typedef struct {
- const AVClass *class;
- enum TInterlaceMode mode; ///< interlace mode selected
- int flags; ///< flags affecting interlacing algorithm
- int frame; ///< number of the output frame
- int vsub; ///< chroma vertical subsampling
- AVFrame *cur;
- AVFrame *next;
- uint8_t *black_data[4]; ///< buffer used to fill padded lines
- int black_linesize[4];
-} TInterlaceContext;
+#include "tinterlace.h"
#define OFFSET(x) offsetof(TInterlaceContext, x)
#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
#define TINTERLACE_FLAG_VLPF 01
+#define TINTERLACE_FLAG_EXACT_TB 2
static const AVOption tinterlace_options[] = {
{"mode", "select interlace mode", OFFSET(mode), AV_OPT_TYPE_INT, {.i64=MODE_MERGE}, 0, MODE_NB-1, FLAGS, "mode"},
{"flags", "set flags", OFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64 = 0}, 0, INT_MAX, 0, "flags" },
{"low_pass_filter", "enable vertical low-pass filter", 0, AV_OPT_TYPE_CONST, {.i64 = TINTERLACE_FLAG_VLPF}, INT_MIN, INT_MAX, FLAGS, "flags" },
{"vlpf", "enable vertical low-pass filter", 0, AV_OPT_TYPE_CONST, {.i64 = TINTERLACE_FLAG_VLPF}, INT_MIN, INT_MAX, FLAGS, "flags" },
+ {"exact_tb", "force a timebase which can represent timestamps exactly", 0, AV_OPT_TYPE_CONST, {.i64 = TINTERLACE_FLAG_EXACT_TB}, INT_MIN, INT_MAX, FLAGS, "flags" },
{NULL}
};
FULL_SCALE_YUVJ_FORMATS, AV_PIX_FMT_NONE
};
+static const AVRational standard_tbs[] = {
+ {1, 25},
+ {1, 30},
+ {1001, 30000},
+};
+
static int query_formats(AVFilterContext *ctx)
{
static const enum AVPixelFormat pix_fmts[] = {
return 0;
}
+static void lowpass_line_c(uint8_t *dstp, ptrdiff_t width, const uint8_t *srcp,
+ const uint8_t *srcp_above, const uint8_t *srcp_below)
+{
+ int i;
+ for (i = 0; i < width; i++) {
+ // this calculation is an integer representation of
+ // '0.5 * current + 0.25 * above + 0.25 * below'
+ // '1 +' is for rounding.
+ dstp[i] = (1 + srcp[i] + srcp[i] + srcp_above[i] + srcp_below[i]) >> 2;
+ }
+}
+
static av_cold void uninit(AVFilterContext *ctx)
{
TInterlaceContext *tinterlace = ctx->priv;
AVFilterLink *inlink = outlink->src->inputs[0];
const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(outlink->format);
TInterlaceContext *tinterlace = ctx->priv;
+ int i;
tinterlace->vsub = desc->log2_chroma_h;
outlink->flags |= FF_LINK_FLAG_REQUEST_LOOP;
tinterlace->mode);
tinterlace->flags &= ~TINTERLACE_FLAG_VLPF;
}
+ tinterlace->preout_time_base = inlink->time_base;
if (tinterlace->mode == MODE_INTERLACEX2) {
- outlink->time_base.num = inlink->time_base.num;
- outlink->time_base.den = inlink->time_base.den * 2;
+ tinterlace->preout_time_base.den *= 2;
outlink->frame_rate = av_mul_q(inlink->frame_rate, (AVRational){2,1});
+ outlink->time_base = av_mul_q(inlink->time_base , (AVRational){1,2});
+ } else if (tinterlace->mode != MODE_PAD) {
+ outlink->frame_rate = av_mul_q(inlink->frame_rate, (AVRational){1,2});
+ outlink->time_base = av_mul_q(inlink->time_base , (AVRational){2,1});
+ }
+
+ for (i = 0; i<FF_ARRAY_ELEMS(standard_tbs); i++){
+ if (!av_cmp_q(standard_tbs[i], outlink->time_base))
+ break;
+ }
+ if (i == FF_ARRAY_ELEMS(standard_tbs) ||
+ (tinterlace->flags & TINTERLACE_FLAG_EXACT_TB))
+ outlink->time_base = tinterlace->preout_time_base;
+
+ if (tinterlace->flags & TINTERLACE_FLAG_VLPF) {
+ tinterlace->lowpass_line = lowpass_line_c;
+ if (ARCH_X86)
+ ff_tinterlace_init_x86(tinterlace);
}
av_log(ctx, AV_LOG_VERBOSE, "mode:%d filter:%s h:%d -> h:%d\n",
* @param flags context flags
*/
static inline
-void copy_picture_field(uint8_t *dst[4], int dst_linesize[4],
+void copy_picture_field(TInterlaceContext *tinterlace,
+ uint8_t *dst[4], int dst_linesize[4],
const uint8_t *src[4], int src_linesize[4],
enum AVPixelFormat format, int w, int src_h,
int src_field, int interleave, int dst_field,
const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(format);
int plane, vsub = desc->log2_chroma_h;
int k = src_field == FIELD_UPPER_AND_LOWER ? 1 : 2;
- int h, i;
+ int h;
for (plane = 0; plane < desc->nb_components; plane++) {
int lines = plane == 1 || plane == 2 ? FF_CEIL_RSHIFT(src_h, vsub) : src_h;
+ int cols = plane == 1 || plane == 2 ? FF_CEIL_RSHIFT( w, desc->log2_chroma_w) : w;
int linesize = av_image_get_linesize(format, w, plane);
uint8_t *dstp = dst[plane];
const uint8_t *srcp = src[plane];
const uint8_t *srcp_below = srcp + src_linesize[plane];
if (h == lines) srcp_above = srcp; // there is no line above
if (h == 1) srcp_below = srcp; // there is no line below
- for (i = 0; i < linesize; i++) {
- // this calculation is an integer representation of
- // '0.5 * current + 0.25 * above + 0.25 * below'
- // '1 +' is for rounding. */
- dstp[i] = (1 + srcp[i] + srcp[i] + srcp_above[i] + srcp_below[i]) >> 2;
- }
+
+ tinterlace->lowpass_line(dstp, cols, srcp, srcp_above, srcp_below);
dstp += dstp_linesize;
srcp += srcp_linesize;
}
out->top_field_first = 1;
/* write odd frame lines into the upper field of the new frame */
- copy_picture_field(out->data, out->linesize,
+ copy_picture_field(tinterlace, out->data, out->linesize,
(const uint8_t **)cur->data, cur->linesize,
inlink->format, inlink->w, inlink->h,
FIELD_UPPER_AND_LOWER, 1, FIELD_UPPER, tinterlace->flags);
/* write even frame lines into the lower field of the new frame */
- copy_picture_field(out->data, out->linesize,
+ copy_picture_field(tinterlace, out->data, out->linesize,
(const uint8_t **)next->data, next->linesize,
inlink->format, inlink->w, inlink->h,
FIELD_UPPER_AND_LOWER, 1, FIELD_LOWER, tinterlace->flags);
field = (1 + tinterlace->frame) & 1 ? FIELD_UPPER : FIELD_LOWER;
/* copy upper and lower fields */
- copy_picture_field(out->data, out->linesize,
+ copy_picture_field(tinterlace, out->data, out->linesize,
(const uint8_t **)cur->data, cur->linesize,
inlink->format, inlink->w, inlink->h,
FIELD_UPPER_AND_LOWER, 1, field, tinterlace->flags);
/* pad with black the other field */
- copy_picture_field(out->data, out->linesize,
+ copy_picture_field(tinterlace, out->data, out->linesize,
(const uint8_t **)tinterlace->black_data, tinterlace->black_linesize,
inlink->format, inlink->w, inlink->h,
FIELD_UPPER_AND_LOWER, 1, !field, tinterlace->flags);
out->top_field_first = tff;
/* copy upper/lower field from cur */
- copy_picture_field(out->data, out->linesize,
+ copy_picture_field(tinterlace, out->data, out->linesize,
(const uint8_t **)cur->data, cur->linesize,
inlink->format, inlink->w, inlink->h,
tff ? FIELD_UPPER : FIELD_LOWER, 1, tff ? FIELD_UPPER : FIELD_LOWER,
tinterlace->flags);
/* copy lower/upper field from next */
- copy_picture_field(out->data, out->linesize,
+ copy_picture_field(tinterlace, out->data, out->linesize,
(const uint8_t **)next->data, next->linesize,
inlink->format, inlink->w, inlink->h,
tff ? FIELD_LOWER : FIELD_UPPER, 1, tff ? FIELD_LOWER : FIELD_UPPER,
if (cur->pts != AV_NOPTS_VALUE)
out->pts = cur->pts*2;
+ out->pts = av_rescale_q(out->pts, tinterlace->preout_time_base, outlink->time_base);
if ((ret = ff_filter_frame(outlink, out)) < 0)
return ret;
return AVERROR(ENOMEM);
av_frame_copy_props(out, next);
out->interlaced_frame = 1;
+ out->top_field_first = !tff;
if (next->pts != AV_NOPTS_VALUE && cur->pts != AV_NOPTS_VALUE)
out->pts = cur->pts + next->pts;
else
out->pts = AV_NOPTS_VALUE;
/* write current frame second field lines into the second field of the new frame */
- copy_picture_field(out->data, out->linesize,
+ copy_picture_field(tinterlace, out->data, out->linesize,
(const uint8_t **)cur->data, cur->linesize,
inlink->format, inlink->w, inlink->h,
tff ? FIELD_LOWER : FIELD_UPPER, 1, tff ? FIELD_LOWER : FIELD_UPPER,
tinterlace->flags);
/* write next frame first field lines into the first field of the new frame */
- copy_picture_field(out->data, out->linesize,
+ copy_picture_field(tinterlace, out->data, out->linesize,
(const uint8_t **)next->data, next->linesize,
inlink->format, inlink->w, inlink->h,
tff ? FIELD_UPPER : FIELD_LOWER, 1, tff ? FIELD_UPPER : FIELD_LOWER,
av_assert0(0);
}
+ out->pts = av_rescale_q(out->pts, tinterlace->preout_time_base, outlink->time_base);
ret = ff_filter_frame(outlink, out);
tinterlace->frame++;
return AVERROR(AVERROR_EXTERNAL);
} else {
if (vsWriteToFile(md, sd->f, &localmotions) != VS_OK) {
+ int ret = AVERROR(errno);
av_log(ctx, AV_LOG_ERROR, "cannot write to transform file");
- return AVERROR(errno);
+ return ret;
}
vs_vector_del(&localmotions);
}
f = fopen(tc->input, "r");
if (!f) {
+ int ret = AVERROR(errno);
av_log(ctx, AV_LOG_ERROR, "cannot open input file %s\n", tc->input);
- return AVERROR(errno);
+ return ret;
} else {
VSManyLocalMotions mlms;
if (vsReadLocalMotionsFile(f, &mlms) == VS_OK) {
--- /dev/null
+/*
+ * This file is part of FFmpeg.
+ *
+ * Copyright (c) 2011, 2012 Hyllian/Jararaca <sergiogdb@gmail.com>
+ * Copyright (c) 2014 Arwa Arif <arwaarif1994@gmail.com>
+ *
+ * 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
+ * XBR Filter is used for depixelization of image.
+ * This is based on Hyllian's xBR shader.
+ *
+ * @see http://www.libretro.com/forums/viewtopic.php?f=6&t=134
+ * @see https://github.com/yoyofr/iFBA/blob/master/fba_src/src/intf/video/scalers/xbr.cpp
+ */
+
+#include "libavutil/opt.h"
+#include "libavutil/avassert.h"
+#include "libavutil/pixdesc.h"
+#include "internal.h"
+
+#define RGB_MASK 0x00FFFFFF
+#define LB_MASK 0x00FEFEFE
+#define RED_BLUE_MASK 0x00FF00FF
+#define GREEN_MASK 0x0000FF00
+
+typedef int (*xbrfunc_t)(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs);
+
+typedef struct {
+ const AVClass *class;
+ int n;
+ xbrfunc_t func;
+ uint32_t rgbtoyuv[1<<24];
+} XBRContext;
+
+typedef struct ThreadData {
+ AVFrame *in, *out;
+ const uint32_t *rgbtoyuv;
+} ThreadData;
+
+#define OFFSET(x) offsetof(XBRContext, x)
+#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
+static const AVOption xbr_options[] = {
+ { "n", "set scale factor", OFFSET(n), AV_OPT_TYPE_INT, {.i64 = 3}, 2, 4, .flags = FLAGS },
+ { NULL }
+};
+
+AVFILTER_DEFINE_CLASS(xbr);
+
+static uint32_t pixel_diff(uint32_t x, uint32_t y, const uint32_t *r2y)
+{
+#define YMASK 0xff0000
+#define UMASK 0x00ff00
+#define VMASK 0x0000ff
+
+ uint32_t yuv1 = r2y[x & 0xffffff];
+ uint32_t yuv2 = r2y[y & 0xffffff];
+
+ return (abs((yuv1 & YMASK) - (yuv2 & YMASK)) >> 16) +
+ (abs((yuv1 & UMASK) - (yuv2 & UMASK)) >> 8) +
+ abs((yuv1 & VMASK) - (yuv2 & VMASK));
+}
+
+#define ALPHA_BLEND_128_W(dst, src) dst = ((src & LB_MASK) >> 1) + ((dst & LB_MASK) >> 1)
+
+#define ALPHA_BLEND_32_W(dst, src) \
+ dst = ((RED_BLUE_MASK & ((dst & RED_BLUE_MASK) + ((((src & RED_BLUE_MASK) - \
+ (dst & RED_BLUE_MASK))) >> 3))) | (GREEN_MASK & ((dst & GREEN_MASK) + \
+ ((((src & GREEN_MASK) - (dst & GREEN_MASK))) >> 3))))
+
+#define ALPHA_BLEND_64_W(dst, src) \
+ dst = ((RED_BLUE_MASK & ((dst & RED_BLUE_MASK) + ((((src & RED_BLUE_MASK) - \
+ (dst & RED_BLUE_MASK))) >> 2))) | (GREEN_MASK & ((dst & GREEN_MASK) + \
+ ((((src & GREEN_MASK) - (dst & GREEN_MASK))) >> 2))))
+
+#define ALPHA_BLEND_192_W(dst, src) \
+ dst = ((RED_BLUE_MASK & ((dst & RED_BLUE_MASK) + ((((src & RED_BLUE_MASK) - \
+ (dst & RED_BLUE_MASK)) * 3) >> 2))) | (GREEN_MASK & ((dst & GREEN_MASK) + \
+ ((((src & GREEN_MASK) - (dst & GREEN_MASK)) * 3) >> 2))))
+
+#define ALPHA_BLEND_224_W(dst, src) \
+ dst = ((RED_BLUE_MASK & ((dst & RED_BLUE_MASK) + ((((src & RED_BLUE_MASK) - \
+ (dst & RED_BLUE_MASK)) * 7) >> 3))) | (GREEN_MASK & ((dst & GREEN_MASK) + \
+ ((((src & GREEN_MASK) - (dst & GREEN_MASK)) * 7) >> 3))))
+
+#define df(A, B) pixel_diff(A, B, r2y)
+#define eq(A, B) (df(A, B) < 155)
+
+#define FILT2(PE, PI, PH, PF, PG, PC, PD, PB, PA, G5, C4, G0, D0, C1, B1, F4, I4, H5, I5, A0, A1, \
+ N0, N1, N2, N3) do { \
+ if (PE != PH && PE != PF) { \
+ const unsigned e = df(PE,PC) + df(PE,PG) + df(PI,H5) + df(PI,F4) + (df(PH,PF)<<2); \
+ const unsigned i = df(PH,PD) + df(PH,I5) + df(PF,I4) + df(PF,PB) + (df(PE,PI)<<2); \
+ if (e < i && (!eq(PF,PB) && !eq(PH,PD) || eq(PE,PI) \
+ && (!eq(PF,I4) && !eq(PH,I5)) \
+ || eq(PE,PG) || eq(PE,PC))) { \
+ const unsigned ke = df(PF,PG); \
+ const unsigned ki = df(PH,PC); \
+ const int left = ke<<1 <= ki && PE != PG && PD != PG; \
+ const int up = ke >= ki<<1 && PE != PC && PB != PC; \
+ const unsigned px = df(PE,PF) <= df(PE,PH) ? PF : PH; \
+ if (left && up) { \
+ ALPHA_BLEND_224_W(E[N3], px); \
+ ALPHA_BLEND_64_W( E[N2], px); \
+ E[N1] = E[N2]; \
+ } else if (left) { \
+ ALPHA_BLEND_192_W(E[N3], px); \
+ ALPHA_BLEND_64_W( E[N2], px); \
+ } else if (up) { \
+ ALPHA_BLEND_192_W(E[N3], px); \
+ ALPHA_BLEND_64_W( E[N1], px); \
+ } else { /* diagonal */ \
+ ALPHA_BLEND_128_W(E[N3], px); \
+ } \
+ } else if (e <= i) { \
+ ALPHA_BLEND_128_W( E[N3], ((df(PE,PF) <= df(PE,PH)) ? PF : PH)); \
+ } \
+ } \
+} while (0)
+
+#define FILT3(PE, PI, PH, PF, PG, PC, PD, PB, PA, G5, C4, G0, D0, C1, B1, F4, I4, H5, I5, A0, A1, \
+ N0, N1, N2, N3, N4, N5, N6, N7, N8) do { \
+ if (PE != PH && PE != PF) { \
+ const unsigned e = df(PE,PC) + df(PE,PG) + df(PI,H5) + df(PI,F4) + (df(PH,PF)<<2); \
+ const unsigned i = df(PH,PD) + df(PH,I5) + df(PF,I4) + df(PF,PB) + (df(PE,PI)<<2); \
+ if (e < i && (!eq(PF,PB) && !eq(PF,PC) || !eq(PH,PD) && !eq(PH,PG) || eq(PE,PI) \
+ && (!eq(PF,F4) && !eq(PF,I4) || !eq(PH,H5) && !eq(PH,I5)) \
+ || eq(PE,PG) || eq(PE,PC))) { \
+ const unsigned ke = df(PF,PG); \
+ const unsigned ki = df(PH,PC); \
+ const int left = ke<<1 <= ki && PE != PG && PD != PG; \
+ const int up = ke >= ki<<1 && PE != PC && PB != PC; \
+ const unsigned px = df(PE,PF) <= df(PE,PH) ? PF : PH; \
+ if (left && up) { \
+ ALPHA_BLEND_192_W(E[N7], px); \
+ ALPHA_BLEND_64_W( E[N6], px); \
+ E[N5] = E[N7]; \
+ E[N2] = E[N6]; \
+ E[N8] = px; \
+ } else if (left) { \
+ ALPHA_BLEND_192_W(E[N7], px); \
+ ALPHA_BLEND_64_W( E[N5], px); \
+ ALPHA_BLEND_64_W( E[N6], px); \
+ E[N8] = px; \
+ } else if (up) { \
+ ALPHA_BLEND_192_W(E[N5], px); \
+ ALPHA_BLEND_64_W( E[N7], px); \
+ ALPHA_BLEND_64_W( E[N2], px); \
+ E[N8] = px; \
+ } else { /* diagonal */ \
+ ALPHA_BLEND_224_W(E[N8], px); \
+ ALPHA_BLEND_32_W( E[N5], px); \
+ ALPHA_BLEND_32_W( E[N7], px); \
+ } \
+ } else if (e <= i) { \
+ ALPHA_BLEND_128_W(E[N8], ((df(PE,PF) <= df(PE,PH)) ? PF : PH)); \
+ } \
+ } \
+} while (0)
+
+#define FILT4(PE, PI, PH, PF, PG, PC, PD, PB, PA, G5, C4, G0, D0, C1, B1, F4, I4, H5, I5, A0, A1, \
+ N15, N14, N11, N3, N7, N10, N13, N12, N9, N6, N2, N1, N5, N8, N4, N0) do { \
+ if (PE != PH && PE != PF) { \
+ const unsigned e = df(PE,PC) + df(PE,PG) + df(PI,H5) + df(PI,F4) + (df(PH,PF)<<2); \
+ const unsigned i = df(PH,PD) + df(PH,I5) + df(PF,I4) + df(PF,PB) + (df(PE,PI)<<2); \
+ if (e < i && (!eq(PF,PB) && !eq(PH,PD) || eq(PE,PI) \
+ && (!eq(PF,I4) && !eq(PH,I5)) \
+ || eq(PE,PG) || eq(PE,PC))) { \
+ const unsigned ke = df(PF,PG); \
+ const unsigned ki = df(PH,PC); \
+ const int left = ke<<1 <= ki && PE != PG && PD != PG; \
+ const int up = ke >= ki<<1 && PE != PC && PB != PC; \
+ const unsigned px = df(PE,PF) <= df(PE,PH) ? PF : PH; \
+ if (left && up) { \
+ ALPHA_BLEND_192_W(E[N13], px); \
+ ALPHA_BLEND_64_W( E[N12], px); \
+ E[N15] = E[N14] = E[N11] = px; \
+ E[N10] = E[N3] = E[N12]; \
+ E[N7] = E[N13]; \
+ } else if (left) { \
+ ALPHA_BLEND_192_W(E[N11], px); \
+ ALPHA_BLEND_192_W(E[N13], px); \
+ ALPHA_BLEND_64_W( E[N10], px); \
+ ALPHA_BLEND_64_W( E[N12], px); \
+ E[N14] = px; \
+ E[N15] = px; \
+ } else if (up) { \
+ ALPHA_BLEND_192_W(E[N14], px); \
+ ALPHA_BLEND_192_W(E[N7 ], px); \
+ ALPHA_BLEND_64_W( E[N10], px); \
+ ALPHA_BLEND_64_W( E[N3 ], px); \
+ E[N11] = px; \
+ E[N15] = px; \
+ } else { /* diagonal */ \
+ ALPHA_BLEND_128_W(E[N11], px); \
+ ALPHA_BLEND_128_W(E[N14], px); \
+ E[N15] = px; \
+ } \
+ } else if (e <= i) { \
+ ALPHA_BLEND_128_W( E[N15], ((df(PE,PF) <= df(PE,PH)) ? PF : PH)); \
+ } \
+ } \
+} while (0)
+
+static av_always_inline void xbr_filter(const ThreadData *td, int jobnr, int nb_jobs, int n)
+{
+ int x, y;
+ const AVFrame *input = td->in;
+ AVFrame *output = td->out;
+ const uint32_t *r2y = td->rgbtoyuv;
+ const int slice_start = (input->height * jobnr ) / nb_jobs;
+ const int slice_end = (input->height * (jobnr+1)) / nb_jobs;
+ const int nl = output->linesize[0] >> 2;
+ const int nl1 = nl + nl;
+ const int nl2 = nl1 + nl;
+
+ for (y = slice_start; y < slice_end; y++) {
+
+ uint32_t *E = (uint32_t *)(output->data[0] + y * output->linesize[0] * n);
+ const uint32_t *sa2 = (uint32_t *)(input->data[0] + y * input->linesize[0] - 8); /* center */
+ const uint32_t *sa1 = sa2 - (input->linesize[0]>>2); /* up x1 */
+ const uint32_t *sa0 = sa1 - (input->linesize[0]>>2); /* up x2 */
+ const uint32_t *sa3 = sa2 + (input->linesize[0]>>2); /* down x1 */
+ const uint32_t *sa4 = sa3 + (input->linesize[0]>>2); /* down x2 */
+
+ if (y <= 1) {
+ sa0 = sa1;
+ if (y == 0) {
+ sa0 = sa1 = sa2;
+ }
+ }
+
+ if (y >= input->height - 2) {
+ sa4 = sa3;
+ if (y == input->height - 1) {
+ sa4 = sa3 = sa2;
+ }
+ }
+
+ for (x = 0; x < input->width; x++) {
+ const uint32_t B1 = sa0[2];
+ const uint32_t PB = sa1[2];
+ const uint32_t PE = sa2[2];
+ const uint32_t PH = sa3[2];
+ const uint32_t H5 = sa4[2];
+
+ const int pprev = 2 - (x > 0);
+ const uint32_t A1 = sa0[pprev];
+ const uint32_t PA = sa1[pprev];
+ const uint32_t PD = sa2[pprev];
+ const uint32_t PG = sa3[pprev];
+ const uint32_t G5 = sa4[pprev];
+
+ const int pprev2 = pprev - (x > 1);
+ const uint32_t A0 = sa1[pprev2];
+ const uint32_t D0 = sa2[pprev2];
+ const uint32_t G0 = sa3[pprev2];
+
+ const int pnext = 3 - (x == input->width - 1);
+ const uint32_t C1 = sa0[pnext];
+ const uint32_t PC = sa1[pnext];
+ const uint32_t PF = sa2[pnext];
+ const uint32_t PI = sa3[pnext];
+ const uint32_t I5 = sa4[pnext];
+
+ const int pnext2 = pnext + 1 - (x >= input->width - 2);
+ const uint32_t C4 = sa1[pnext2];
+ const uint32_t F4 = sa2[pnext2];
+ const uint32_t I4 = sa3[pnext2];
+
+ if (n == 2) {
+ E[0] = E[1] = // 0, 1
+ E[nl] = E[nl + 1] = PE; // 2, 3
+
+ FILT2(PE, PI, PH, PF, PG, PC, PD, PB, PA, G5, C4, G0, D0, C1, B1, F4, I4, H5, I5, A0, A1, 0, 1, nl, nl+1);
+ FILT2(PE, PC, PF, PB, PI, PA, PH, PD, PG, I4, A1, I5, H5, A0, D0, B1, C1, F4, C4, G5, G0, nl, 0, nl+1, 1);
+ FILT2(PE, PA, PB, PD, PC, PG, PF, PH, PI, C1, G0, C4, F4, G5, H5, D0, A0, B1, A1, I4, I5, nl+1, nl, 1, 0);
+ FILT2(PE, PG, PD, PH, PA, PI, PB, PF, PC, A0, I5, A1, B1, I4, F4, H5, G5, D0, G0, C1, C4, 1, nl+1, 0, nl);
+ } else if (n == 3) {
+ E[0] = E[1] = E[2] = // 0, 1, 2
+ E[nl] = E[nl+1] = E[nl+2] = // 3, 4, 5
+ E[nl1] = E[nl1+1] = E[nl1+2] = PE; // 6, 7, 8
+
+ FILT3(PE, PI, PH, PF, PG, PC, PD, PB, PA, G5, C4, G0, D0, C1, B1, F4, I4, H5, I5, A0, A1, 0, 1, 2, nl, nl+1, nl+2, nl1, nl1+1, nl1+2);
+ FILT3(PE, PC, PF, PB, PI, PA, PH, PD, PG, I4, A1, I5, H5, A0, D0, B1, C1, F4, C4, G5, G0, nl1, nl, 0, nl1+1, nl+1, 1, nl1+2, nl+2, 2);
+ FILT3(PE, PA, PB, PD, PC, PG, PF, PH, PI, C1, G0, C4, F4, G5, H5, D0, A0, B1, A1, I4, I5, nl1+2, nl1+1, nl1, nl+2, nl+1, nl, 2, 1, 0);
+ FILT3(PE, PG, PD, PH, PA, PI, PB, PF, PC, A0, I5, A1, B1, I4, F4, H5, G5, D0, G0, C1, C4, 2, nl+2, nl1+2, 1, nl+1, nl1+1, 0, nl, nl1);
+ } else if (n == 4) {
+ E[0] = E[1] = E[2] = E[3] = // 0, 1, 2, 3
+ E[nl] = E[nl+1] = E[nl+2] = E[nl+3] = // 4, 5, 6, 7
+ E[nl1] = E[nl1+1] = E[nl1+2] = E[nl1+3] = // 8, 9, 10, 11
+ E[nl2] = E[nl2+1] = E[nl2+2] = E[nl2+3] = PE; // 12, 13, 14, 15
+
+ FILT4(PE, PI, PH, PF, PG, PC, PD, PB, PA, G5, C4, G0, D0, C1, B1, F4, I4, H5, I5, A0, A1, nl2+3, nl2+2, nl1+3, 3, nl+3, nl1+2, nl2+1, nl2, nl1+1, nl+2, 2, 1, nl+1, nl1, nl, 0);
+ FILT4(PE, PC, PF, PB, PI, PA, PH, PD, PG, I4, A1, I5, H5, A0, D0, B1, C1, F4, C4, G5, G0, 3, nl+3, 2, 0, 1, nl+2, nl1+3, nl2+3, nl1+2, nl+1, nl, nl1, nl1+1, nl2+2, nl2+1, nl2);
+ FILT4(PE, PA, PB, PD, PC, PG, PF, PH, PI, C1, G0, C4, F4, G5, H5, D0, A0, B1, A1, I4, I5, 0, 1, nl, nl2, nl1, nl+1, 2, 3, nl+2, nl1+1, nl2+1, nl2+2, nl1+2, nl+3, nl1+3, nl2+3);
+ FILT4(PE, PG, PD, PH, PA, PI, PB, PF, PC, A0, I5, A1, B1, I4, F4, H5, G5, D0, G0, C1, C4, nl2, nl1, nl2+1, nl2+3, nl2+2, nl1+1, nl, 0, nl+1, nl1+2, nl1+3, nl+3, nl+2, 1, 2, 3);
+ }
+
+ sa0 += 1;
+ sa1 += 1;
+ sa2 += 1;
+ sa3 += 1;
+ sa4 += 1;
+
+ E += n;
+ }
+ }
+}
+
+#define XBR_FUNC(size) \
+static int xbr##size##x(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) \
+{ \
+ xbr_filter(arg, jobnr, nb_jobs, size); \
+ return 0; \
+}
+
+XBR_FUNC(2)
+XBR_FUNC(3)
+XBR_FUNC(4)
+
+
+static int config_output(AVFilterLink *outlink)
+{
+ AVFilterContext *ctx = outlink->src;
+ XBRContext *xbr = ctx->priv;
+ AVFilterLink *inlink = ctx->inputs[0];
+
+ outlink->w = inlink->w * xbr->n;
+ outlink->h = inlink->h * xbr->n;
+ return 0;
+}
+
+static int query_formats(AVFilterContext *ctx)
+{
+ static const enum AVPixelFormat pix_fmts[] = {
+ AV_PIX_FMT_0RGB32, AV_PIX_FMT_NONE,
+ };
+
+ ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
+ return 0;
+}
+
+static int filter_frame(AVFilterLink *inlink, AVFrame *in)
+{
+ AVFilterContext *ctx = inlink->dst;
+ AVFilterLink *outlink = ctx->outputs[0];
+ XBRContext *xbr = ctx->priv;
+ ThreadData td;
+
+ AVFrame *out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
+ if (!out) {
+ av_frame_free(&in);
+ return AVERROR(ENOMEM);
+ }
+
+ av_frame_copy_props(out, in);
+
+ td.in = in;
+ td.out = out;
+ td.rgbtoyuv = xbr->rgbtoyuv;
+ ctx->internal->execute(ctx, xbr->func, &td, NULL, FFMIN(inlink->h, ctx->graph->nb_threads));
+
+ out->width = outlink->w;
+ out->height = outlink->h;
+
+ av_frame_free(&in);
+ return ff_filter_frame(outlink, out);
+}
+
+static int init(AVFilterContext *ctx)
+{
+ XBRContext *xbr = ctx->priv;
+ static const xbrfunc_t xbrfuncs[] = {xbr2x, xbr3x, xbr4x};
+
+ uint32_t c;
+ int bg, rg, g;
+
+ for (bg = -255; bg < 256; bg++) {
+ for (rg = -255; rg < 256; rg++) {
+ const uint32_t u = (uint32_t)((-169*rg + 500*bg)/1000) + 128;
+ const uint32_t v = (uint32_t)(( 500*rg - 81*bg)/1000) + 128;
+ int startg = FFMAX3(-bg, -rg, 0);
+ int endg = FFMIN3(255-bg, 255-rg, 255);
+ uint32_t y = (uint32_t)(( 299*rg + 1000*startg + 114*bg)/1000);
+ c = bg + (rg<<16) + 0x010101 * startg;
+ for (g = startg; g <= endg; g++) {
+ xbr->rgbtoyuv[c] = ((y++) << 16) + (u << 8) + v;
+ c+= 0x010101;
+ }
+ }
+ }
+
+ xbr->func = xbrfuncs[xbr->n - 2];
+ return 0;
+}
+
+static const AVFilterPad xbr_inputs[] = {
+ {
+ .name = "default",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .filter_frame = filter_frame,
+ },
+ { NULL }
+};
+
+static const AVFilterPad xbr_outputs[] = {
+ {
+ .name = "default",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .config_props = config_output,
+ },
+ { NULL }
+};
+
+AVFilter ff_vf_xbr = {
+ .name = "xbr",
+ .description = NULL_IF_CONFIG_SMALL("Scale the input using xBR algorithm."),
+ .inputs = xbr_inputs,
+ .outputs = xbr_outputs,
+ .query_formats = query_formats,
+ .priv_size = sizeof(XBRContext),
+ .priv_class = &xbr_class,
+ .init = init,
+ .flags = AVFILTER_FLAG_SLICE_THREADS,
+};
return -1;
}
+ if (!yadif->prev)
+ return 0;
+
if ((yadif->deint && !yadif->cur->interlaced_frame) || ctx->is_disabled) {
yadif->out = av_frame_clone(yadif->cur);
if (!yadif->out)
return ff_filter_frame(ctx->outputs[0], yadif->out);
}
- if (!yadif->prev)
- return 0;
-
yadif->out = ff_get_video_buffer(ctx->outputs[0], link->w, link->h);
if (!yadif->out)
return AVERROR(ENOMEM);
OBJS-$(CONFIG_GRADFUN_FILTER) += x86/vf_gradfun_init.o
OBJS-$(CONFIG_HQDN3D_FILTER) += x86/vf_hqdn3d_init.o
OBJS-$(CONFIG_IDET_FILTER) += x86/vf_idet_init.o
+OBJS-$(CONFIG_INTERLACE_FILTER) += x86/vf_interlace_init.o
+OBJS-$(CONFIG_NOISE_FILTER) += x86/vf_noise.o
OBJS-$(CONFIG_PULLUP_FILTER) += x86/vf_pullup_init.o
OBJS-$(CONFIG_SPP_FILTER) += x86/vf_spp.o
+OBJS-$(CONFIG_TINTERLACE_FILTER) += x86/vf_tinterlace_init.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_IDET_FILTER) += x86/vf_idet.o
+YASM-OBJS-$(CONFIG_INTERLACE_FILTER) += x86/vf_interlace.o
YASM-OBJS-$(CONFIG_PULLUP_FILTER) += x86/vf_pullup.o
+YASM-OBJS-$(CONFIG_TINTERLACE_FILTER) += x86/vf_interlace.o
YASM-OBJS-$(CONFIG_VOLUME_FILTER) += x86/af_volume.o
YASM-OBJS-$(CONFIG_YADIF_FILTER) += x86/vf_yadif.o x86/yadif-16.o x86/yadif-10.o
--- /dev/null
+;*****************************************************************************
+;* x86-optimized functions for interlace filter
+;*
+;* Copyright (C) 2014 Kieran Kunhya <kierank@obe.tv>
+;* Copyright (c) 2014 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/x86/x86util.asm"
+
+SECTION_RODATA
+
+SECTION .text
+
+%macro LOWPASS_LINE 0
+cglobal lowpass_line, 5, 5, 7
+ add r0, r1
+ add r2, r1
+ add r3, r1
+ add r4, r1
+ neg r1
+
+ pcmpeqb m6, m6
+
+.loop
+ mova m0, [r3+r1]
+ mova m1, [r3+r1+mmsize]
+ pavgb m0, [r4+r1]
+ pavgb m1, [r4+r1+mmsize]
+ pxor m0, m6
+ pxor m1, m6
+ pxor m2, m6, [r2+r1]
+ pxor m3, m6, [r2+r1+mmsize]
+ pavgb m0, m2
+ pavgb m1, m3
+ pxor m0, m6
+ pxor m1, m6
+ mova [r0+r1], m0
+ mova [r0+r1+mmsize], m1
+
+ add r1, 2*mmsize
+ jl .loop
+REP_RET
+%endmacro
+
+INIT_XMM sse2
+LOWPASS_LINE
+
+INIT_XMM avx
+LOWPASS_LINE
--- /dev/null
+/*
+ * Copyright (C) 2014 Kieran Kunhya <kierank@obe.tv>
+ *
+ * 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/internal.h"
+#include "libavutil/mem.h"
+#include "libavutil/x86/asm.h"
+#include "libavutil/x86/cpu.h"
+
+#include "libavfilter/interlace.h"
+
+void ff_lowpass_line_sse2(uint8_t *dstp, ptrdiff_t linesize,
+ const uint8_t *srcp,
+ const uint8_t *srcp_above,
+ const uint8_t *srcp_below);
+void ff_lowpass_line_avx (uint8_t *dstp, ptrdiff_t linesize,
+ const uint8_t *srcp,
+ const uint8_t *srcp_above,
+ const uint8_t *srcp_below);
+
+av_cold void ff_interlace_init_x86(InterlaceContext *s)
+{
+ int cpu_flags = av_get_cpu_flags();
+
+ if (EXTERNAL_SSE2(cpu_flags))
+ s->lowpass_line = ff_lowpass_line_sse2;
+ if (EXTERNAL_AVX(cpu_flags))
+ s->lowpass_line = ff_lowpass_line_avx;
+}
--- /dev/null
+/*
+ * Copyright (c) 2002 Michael Niedermayer <michaelni@gmx.at>
+ * 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/attributes.h"
+#include "libavutil/x86/cpu.h"
+#include "libavutil/x86/asm.h"
+#include "libavfilter/vf_noise.h"
+
+#if HAVE_INLINE_ASM
+static void line_noise_mmx(uint8_t *dst, const uint8_t *src,
+ const int8_t *noise, int len, int shift)
+{
+ x86_reg mmx_len= len & (~7);
+ noise += shift;
+
+ __asm__ volatile(
+ "mov %3, %%"REG_a" \n\t"
+ "pcmpeqb %%mm7, %%mm7 \n\t"
+ "psllw $15, %%mm7 \n\t"
+ "packsswb %%mm7, %%mm7 \n\t"
+ ".p2align 4 \n\t"
+ "1: \n\t"
+ "movq (%0, %%"REG_a"), %%mm0 \n\t"
+ "movq (%1, %%"REG_a"), %%mm1 \n\t"
+ "pxor %%mm7, %%mm0 \n\t"
+ "paddsb %%mm1, %%mm0 \n\t"
+ "pxor %%mm7, %%mm0 \n\t"
+ "movq %%mm0, (%2, %%"REG_a") \n\t"
+ "add $8, %%"REG_a" \n\t"
+ " js 1b \n\t"
+ :: "r" (src+mmx_len), "r" (noise+mmx_len), "r" (dst+mmx_len), "g" (-mmx_len)
+ : "%"REG_a
+ );
+ if (mmx_len != len)
+ ff_line_noise_c(dst+mmx_len, src+mmx_len, noise+mmx_len, len-mmx_len, 0);
+}
+
+#if HAVE_6REGS
+static void line_noise_avg_mmx(uint8_t *dst, const uint8_t *src,
+ int len, const int8_t * const *shift)
+{
+ x86_reg mmx_len = len & (~7);
+
+ __asm__ volatile(
+ "mov %5, %%"REG_a" \n\t"
+ ".p2align 4 \n\t"
+ "1: \n\t"
+ "movq (%1, %%"REG_a"), %%mm1 \n\t"
+ "movq (%0, %%"REG_a"), %%mm0 \n\t"
+ "paddb (%2, %%"REG_a"), %%mm1 \n\t"
+ "paddb (%3, %%"REG_a"), %%mm1 \n\t"
+ "movq %%mm0, %%mm2 \n\t"
+ "movq %%mm1, %%mm3 \n\t"
+ "punpcklbw %%mm0, %%mm0 \n\t"
+ "punpckhbw %%mm2, %%mm2 \n\t"
+ "punpcklbw %%mm1, %%mm1 \n\t"
+ "punpckhbw %%mm3, %%mm3 \n\t"
+ "pmulhw %%mm0, %%mm1 \n\t"
+ "pmulhw %%mm2, %%mm3 \n\t"
+ "paddw %%mm1, %%mm1 \n\t"
+ "paddw %%mm3, %%mm3 \n\t"
+ "paddw %%mm0, %%mm1 \n\t"
+ "paddw %%mm2, %%mm3 \n\t"
+ "psrlw $8, %%mm1 \n\t"
+ "psrlw $8, %%mm3 \n\t"
+ "packuswb %%mm3, %%mm1 \n\t"
+ "movq %%mm1, (%4, %%"REG_a") \n\t"
+ "add $8, %%"REG_a" \n\t"
+ " js 1b \n\t"
+ :: "r" (src+mmx_len), "r" (shift[0]+mmx_len), "r" (shift[1]+mmx_len), "r" (shift[2]+mmx_len),
+ "r" (dst+mmx_len), "g" (-mmx_len)
+ : "%"REG_a
+ );
+
+ if (mmx_len != len){
+ const int8_t *shift2[3] = { shift[0]+mmx_len, shift[1]+mmx_len, shift[2]+mmx_len };
+ ff_line_noise_avg_c(dst+mmx_len, src+mmx_len, len-mmx_len, shift2);
+ }
+}
+#endif /* HAVE_6REGS */
+
+static void line_noise_mmxext(uint8_t *dst, const uint8_t *src,
+ const int8_t *noise, int len, int shift)
+{
+ x86_reg mmx_len = len & (~7);
+ noise += shift;
+
+ __asm__ volatile(
+ "mov %3, %%"REG_a" \n\t"
+ "pcmpeqb %%mm7, %%mm7 \n\t"
+ "psllw $15, %%mm7 \n\t"
+ "packsswb %%mm7, %%mm7 \n\t"
+ ".p2align 4 \n\t"
+ "1: \n\t"
+ "movq (%0, %%"REG_a"), %%mm0 \n\t"
+ "movq (%1, %%"REG_a"), %%mm1 \n\t"
+ "pxor %%mm7, %%mm0 \n\t"
+ "paddsb %%mm1, %%mm0 \n\t"
+ "pxor %%mm7, %%mm0 \n\t"
+ "movntq %%mm0, (%2, %%"REG_a") \n\t"
+ "add $8, %%"REG_a" \n\t"
+ " js 1b \n\t"
+ :: "r" (src+mmx_len), "r" (noise+mmx_len), "r" (dst+mmx_len), "g" (-mmx_len)
+ : "%"REG_a
+ );
+ if (mmx_len != len)
+ ff_line_noise_c(dst+mmx_len, src+mmx_len, noise+mmx_len, len-mmx_len, 0);
+}
+#endif /* HAVE_INLINE_ASM */
+
+av_cold void ff_noise_init_x86(NoiseContext *n)
+{
+#if HAVE_INLINE_ASM
+ int cpu_flags = av_get_cpu_flags();
+
+ if (INLINE_MMX(cpu_flags)) {
+ n->line_noise = line_noise_mmx;
+#if HAVE_6REGS
+ n->line_noise_avg = line_noise_avg_mmx;
+#endif
+ }
+ if (INLINE_MMXEXT(cpu_flags)) {
+ n->line_noise = line_noise_mmxext;
+ }
+#endif
+}
--- /dev/null
+/*
+ * Copyright (C) 2014 Kieran Kunhya <kierank@obe.tv>
+ *
+ * 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/internal.h"
+#include "libavutil/mem.h"
+#include "libavutil/x86/asm.h"
+#include "libavutil/x86/cpu.h"
+
+#include "libavfilter/tinterlace.h"
+
+void ff_lowpass_line_sse2(uint8_t *dstp, ptrdiff_t linesize,
+ const uint8_t *srcp,
+ const uint8_t *srcp_above,
+ const uint8_t *srcp_below);
+void ff_lowpass_line_avx (uint8_t *dstp, ptrdiff_t linesize,
+ const uint8_t *srcp,
+ const uint8_t *srcp_above,
+ const uint8_t *srcp_below);
+
+av_cold void ff_tinterlace_init_x86(TInterlaceContext *s)
+{
+ int cpu_flags = av_get_cpu_flags();
+
+ if (EXTERNAL_SSE2(cpu_flags))
+ s->lowpass_line = ff_lowpass_line_sse2;
+ if (EXTERNAL_AVX(cpu_flags))
+ s->lowpass_line = ff_lowpass_line_avx;
+}
OBJS-$(CONFIG_ANM_DEMUXER) += anm.o
OBJS-$(CONFIG_APC_DEMUXER) += apc.o
OBJS-$(CONFIG_APE_DEMUXER) += ape.o apetag.o img2.o
+OBJS-$(CONFIG_APNG_DEMUXER) += apngdec.o
OBJS-$(CONFIG_AQTITLE_DEMUXER) += aqtitledec.o subtitles.o
OBJS-$(CONFIG_ASF_DEMUXER) += asfdec.o asf.o asfcrypt.o \
avlanguage.o
OBJS-$(CONFIG_CRC_MUXER) += crcenc.o
OBJS-$(CONFIG_DATA_DEMUXER) += rawdec.o
OBJS-$(CONFIG_DATA_MUXER) += rawdec.o
+OBJS-$(CONFIG_DASH_MUXER) += dashenc.o isom.o
OBJS-$(CONFIG_DAUD_DEMUXER) += dauddec.o
OBJS-$(CONFIG_DAUD_MUXER) += daudenc.o
OBJS-$(CONFIG_DFA_DEMUXER) += dfa.o
OBJS-$(CONFIG_IMAGE_DPX_PIPE_DEMUXER) += img2dec.o img2.o
OBJS-$(CONFIG_IMAGE_EXR_PIPE_DEMUXER) += img2dec.o img2.o
OBJS-$(CONFIG_IMAGE_J2K_PIPE_DEMUXER) += img2dec.o img2.o
+OBJS-$(CONFIG_IMAGE_JPEG_PIPE_DEMUXER) += img2dec.o img2.o
OBJS-$(CONFIG_IMAGE_JPEGLS_PIPE_DEMUXER) += img2dec.o img2.o
OBJS-$(CONFIG_IMAGE_PICTOR_PIPE_DEMUXER) += img2dec.o img2.o
OBJS-$(CONFIG_IMAGE_PNG_PIPE_DEMUXER) += img2dec.o img2.o
rtpenc_h261.o \
rtpenc_h263.o \
rtpenc_h263_rfc2190.o \
+ rtpenc_hevc.o \
rtpenc_jpeg.o \
rtpenc_mpv.o \
rtpenc.o \
vorbiscomment.o
OBJS-$(CONFIG_SRT_DEMUXER) += srtdec.o subtitles.o
OBJS-$(CONFIG_SRT_MUXER) += srtenc.o
+OBJS-$(CONFIG_STL_DEMUXER) += stldec.o subtitles.o
OBJS-$(CONFIG_STR_DEMUXER) += psxstr.o
OBJS-$(CONFIG_SUBVIEWER1_DEMUXER) += subviewer1dec.o subtitles.o
OBJS-$(CONFIG_SUBVIEWER_DEMUXER) += subviewerdec.o subtitles.o
+OBJS-$(CONFIG_SUP_DEMUXER) += supdec.o
OBJS-$(CONFIG_SWF_DEMUXER) += swfdec.o swf.o
OBJS-$(CONFIG_SWF_MUXER) += swfenc.o swf.o
OBJS-$(CONFIG_TAK_DEMUXER) += takdec.o apetag.o img2.o rawdec.o
oggparsevorbis.o vorbiscomment.o \
flac_picture.o replaygain.o
OBJS-$(CONFIG_WEBM_DASH_MANIFEST_MUXER) += webmdashenc.o matroska.o
+OBJS-$(CONFIG_WEBP_MUXER) += webpenc.o
OBJS-$(CONFIG_WEBVTT_DEMUXER) += webvttdec.o subtitles.o
OBJS-$(CONFIG_WEBVTT_MUXER) += webvttenc.o
OBJS-$(CONFIG_WSAUD_DEMUXER) += westwood_aud.o
OBJS-$(HAVE_LIBC_MSVCRT) += file_open.o
+# libavdevice dependencies
+OBJS-$(CONFIG_IEC61883_INDEV) += dv.o
+
# Windows resource file
SLIBOBJS-$(HAVE_GNU_WINDRES) += avformatres.o
pktdumper \
probetest \
seek_print \
+ sidxindex \
#define ADTS_MAX_FRAME_BYTES ((1 << 13) - 1)
-static int adts_decode_extradata(AVFormatContext *s, ADTSContext *adts, uint8_t *buf, int size)
+static int adts_decode_extradata(AVFormatContext *s, ADTSContext *adts, const uint8_t *buf, int size)
{
GetBitContext gb;
PutBitContext pb;
REGISTER_DEMUXER (ANM, anm);
REGISTER_DEMUXER (APC, apc);
REGISTER_DEMUXER (APE, ape);
+ REGISTER_DEMUXER (APNG, apng);
REGISTER_DEMUXER (AQTITLE, aqtitle);
REGISTER_MUXDEMUX(ASF, asf);
REGISTER_MUXDEMUX(ASS, ass);
REGISTER_DEMUXER (CINE, cine);
REGISTER_DEMUXER (CONCAT, concat);
REGISTER_MUXER (CRC, crc);
+ REGISTER_MUXER (DASH, dash);
REGISTER_MUXDEMUX(DATA, data);
REGISTER_MUXDEMUX(DAUD, daud);
REGISTER_DEMUXER (DFA, dfa);
REGISTER_MUXDEMUX(SPDIF, spdif);
REGISTER_MUXDEMUX(SRT, srt);
REGISTER_DEMUXER (STR, str);
+ REGISTER_DEMUXER (STL, stl);
REGISTER_DEMUXER (SUBVIEWER1, subviewer1);
REGISTER_DEMUXER (SUBVIEWER, subviewer);
+ REGISTER_DEMUXER (SUP, sup);
REGISTER_MUXDEMUX(SWF, swf);
REGISTER_DEMUXER (TAK, tak);
REGISTER_MUXER (TEE, tee);
REGISTER_DEMUXER (WC3, wc3);
REGISTER_MUXER (WEBM, webm);
REGISTER_MUXDEMUX(WEBM_DASH_MANIFEST, webm_dash_manifest);
+ REGISTER_MUXER (WEBP, webp);
REGISTER_MUXDEMUX(WEBVTT, webvtt);
REGISTER_DEMUXER (WSAUD, wsaud);
REGISTER_DEMUXER (WSVQA, wsvqa);
REGISTER_DEMUXER (IMAGE_DPX_PIPE, image_dpx_pipe);
REGISTER_DEMUXER (IMAGE_EXR_PIPE, image_exr_pipe);
REGISTER_DEMUXER (IMAGE_J2K_PIPE, image_j2k_pipe);
+ REGISTER_DEMUXER (IMAGE_JPEG_PIPE, image_jpeg_pipe);
REGISTER_DEMUXER (IMAGE_JPEGLS_PIPE, image_jpegls_pipe);
REGISTER_DEMUXER (IMAGE_PICTOR_PIPE, image_pictor_pipe);
REGISTER_DEMUXER (IMAGE_PNG_PIPE, image_png_pipe);
REGISTER_PROTOCOL(TCP, tcp);
REGISTER_PROTOCOL(TLS, tls);
REGISTER_PROTOCOL(UDP, udp);
+ REGISTER_PROTOCOL(UDPLITE, udplite);
REGISTER_PROTOCOL(UNIX, unix);
/* external libraries */
--- /dev/null
+/*
+ * APNG demuxer
+ * Copyright (c) 2014 Benoit Fouet
+ *
+ * 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
+ * APNG demuxer.
+ * @see https://wiki.mozilla.org/APNG_Specification
+ * @see http://www.w3.org/TR/PNG
+ */
+
+#include "avformat.h"
+#include "avio_internal.h"
+#include "internal.h"
+#include "libavutil/imgutils.h"
+#include "libavutil/intreadwrite.h"
+#include "libavutil/opt.h"
+#include "libavcodec/apng.h"
+#include "libavcodec/png.h"
+#include "libavcodec/bytestream.h"
+
+#define DEFAULT_APNG_FPS 15
+
+typedef struct APNGDemuxContext {
+ const AVClass *class;
+
+ int max_fps;
+ int default_fps;
+
+ int64_t pkt_pts;
+ int pkt_duration;
+
+ int is_key_frame;
+
+ /*
+ * loop options
+ */
+ int ignore_loop;
+ uint32_t num_frames;
+ uint32_t num_play;
+ uint32_t cur_loop;
+} APNGDemuxContext;
+
+/*
+ * To be a valid APNG file, we mandate, in this order:
+ * PNGSIG
+ * IHDR
+ * ...
+ * acTL
+ * ...
+ * IDAT
+ */
+static int apng_probe(AVProbeData *p)
+{
+ GetByteContext gb;
+ int state = 0;
+ uint32_t len, tag;
+
+ bytestream2_init(&gb, p->buf, p->buf_size);
+
+ if (bytestream2_get_be64(&gb) != PNGSIG)
+ return 0;
+
+ for (;;) {
+ len = bytestream2_get_be32(&gb);
+ if (len > 0x7fffffff)
+ return 0;
+
+ tag = bytestream2_get_le32(&gb);
+ /* we don't check IDAT size, as this is the last tag
+ * we check, and it may be larger than the probe buffer */
+ if (tag != MKTAG('I', 'D', 'A', 'T') &&
+ len + 4 > bytestream2_get_bytes_left(&gb))
+ return 0;
+
+ switch (tag) {
+ case MKTAG('I', 'H', 'D', 'R'):
+ if (len != 13)
+ return 0;
+ if (av_image_check_size(bytestream2_get_be32(&gb), bytestream2_get_be32(&gb), 0, NULL))
+ return 0;
+ bytestream2_skip(&gb, 9);
+ state++;
+ break;
+ case MKTAG('a', 'c', 'T', 'L'):
+ if (state != 1 ||
+ len != 8 ||
+ bytestream2_get_be32(&gb) == 0) /* 0 is not a valid value for number of frames */
+ return 0;
+ bytestream2_skip(&gb, 8);
+ state++;
+ break;
+ case MKTAG('I', 'D', 'A', 'T'):
+ if (state != 2)
+ return 0;
+ goto end;
+ default:
+ /* skip other tags */
+ bytestream2_skip(&gb, len + 4);
+ break;
+ }
+ }
+
+end:
+ return AVPROBE_SCORE_MAX;
+}
+
+static int append_extradata(AVCodecContext *s, AVIOContext *pb, int len)
+{
+ int previous_size = s->extradata_size;
+ int new_size, ret;
+ uint8_t *new_extradata;
+
+ if (previous_size > INT_MAX - len)
+ return AVERROR_INVALIDDATA;
+
+ new_size = previous_size + len;
+ new_extradata = av_realloc(s->extradata, new_size + FF_INPUT_BUFFER_PADDING_SIZE);
+ if (!new_extradata)
+ return AVERROR(ENOMEM);
+ s->extradata = new_extradata;
+ s->extradata_size = new_size;
+
+ if ((ret = avio_read(pb, s->extradata + previous_size, len)) < 0)
+ return ret;
+
+ return previous_size;
+}
+
+static int apng_read_header(AVFormatContext *s)
+{
+ APNGDemuxContext *ctx = s->priv_data;
+ AVIOContext *pb = s->pb;
+ uint32_t len, tag;
+ AVStream *st;
+ int ret = AVERROR_INVALIDDATA, acTL_found = 0;
+
+ /* verify PNGSIG */
+ if (avio_rb64(pb) != PNGSIG)
+ return ret;
+
+ /* parse IHDR (must be first chunk) */
+ len = avio_rb32(pb);
+ tag = avio_rl32(pb);
+ if (len != 13 || tag != MKTAG('I', 'H', 'D', 'R'))
+ return ret;
+
+ st = avformat_new_stream(s, NULL);
+ if (!st)
+ return AVERROR(ENOMEM);
+
+ /* set the timebase to something large enough (1/100,000 of second)
+ * to hopefully cope with all sane frame durations */
+ avpriv_set_pts_info(st, 64, 1, 100000);
+ st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
+ st->codec->codec_id = AV_CODEC_ID_APNG;
+ st->codec->width = avio_rb32(pb);
+ st->codec->height = avio_rb32(pb);
+ if ((ret = av_image_check_size(st->codec->width, st->codec->height, 0, s)) < 0)
+ return ret;
+
+ /* extradata will contain every chunk up to the first fcTL (excluded) */
+ st->codec->extradata = av_malloc(len + 12 + FF_INPUT_BUFFER_PADDING_SIZE);
+ if (!st->codec->extradata)
+ return AVERROR(ENOMEM);
+ st->codec->extradata_size = len + 12;
+ AV_WB32(st->codec->extradata, len);
+ AV_WL32(st->codec->extradata+4, tag);
+ AV_WB32(st->codec->extradata+8, st->codec->width);
+ AV_WB32(st->codec->extradata+12, st->codec->height);
+ if ((ret = avio_read(pb, st->codec->extradata+16, 9)) < 0)
+ goto fail;
+
+ while (!avio_feof(pb)) {
+ if (acTL_found && ctx->num_play != 1) {
+ int64_t size = avio_size(pb);
+ int64_t offset = avio_tell(pb);
+ if (size < 0) {
+ ret = size;
+ goto fail;
+ } else if (offset < 0) {
+ ret = offset;
+ goto fail;
+ } else if ((ret = ffio_ensure_seekback(pb, size - offset)) < 0) {
+ av_log(s, AV_LOG_WARNING, "Could not ensure seekback, will not loop\n");
+ ctx->num_play = 1;
+ }
+ }
+ if ((ctx->num_play == 1 || !acTL_found) &&
+ ((ret = ffio_ensure_seekback(pb, 4 /* len */ + 4 /* tag */)) < 0))
+ goto fail;
+
+ len = avio_rb32(pb);
+ if (len > 0x7fffffff) {
+ ret = AVERROR_INVALIDDATA;
+ goto fail;
+ }
+
+ tag = avio_rl32(pb);
+ switch (tag) {
+ case MKTAG('a', 'c', 'T', 'L'):
+ if ((ret = avio_seek(pb, -8, SEEK_CUR)) < 0 ||
+ (ret = append_extradata(st->codec, pb, len + 12)) < 0)
+ goto fail;
+ acTL_found = 1;
+ ctx->num_frames = AV_RB32(st->codec->extradata + ret + 8);
+ ctx->num_play = AV_RB32(st->codec->extradata + ret + 12);
+ av_log(s, AV_LOG_DEBUG, "num_frames: %"PRIu32", num_play: %"PRIu32"\n",
+ ctx->num_frames, ctx->num_play);
+ break;
+ case MKTAG('f', 'c', 'T', 'L'):
+ if (!acTL_found) {
+ ret = AVERROR_INVALIDDATA;
+ goto fail;
+ }
+ if ((ret = avio_seek(pb, -8, SEEK_CUR)) < 0)
+ goto fail;
+ return 0;
+ default:
+ if ((ret = avio_seek(pb, -8, SEEK_CUR)) < 0 ||
+ (ret = append_extradata(st->codec, pb, len + 12)) < 0)
+ goto fail;
+ }
+ }
+
+fail:
+ if (st->codec->extradata_size) {
+ av_freep(&st->codec->extradata);
+ st->codec->extradata_size = 0;
+ }
+ return ret;
+}
+
+static int decode_fctl_chunk(AVFormatContext *s, APNGDemuxContext *ctx, AVPacket *pkt)
+{
+ uint32_t sequence_number, width, height, x_offset, y_offset;
+ uint16_t delay_num, delay_den;
+ uint8_t dispose_op, blend_op;
+
+ sequence_number = avio_rb32(s->pb);
+ width = avio_rb32(s->pb);
+ height = avio_rb32(s->pb);
+ x_offset = avio_rb32(s->pb);
+ y_offset = avio_rb32(s->pb);
+ delay_num = avio_rb16(s->pb);
+ delay_den = avio_rb16(s->pb);
+ dispose_op = avio_r8(s->pb);
+ blend_op = avio_r8(s->pb);
+ avio_skip(s->pb, 4); /* crc */
+
+ /* default is hundredths of seconds */
+ if (!delay_den)
+ delay_den = 100;
+ if (!delay_num || delay_den / delay_num > ctx->max_fps) {
+ delay_num = 1;
+ delay_den = ctx->default_fps;
+ }
+ ctx->pkt_duration = av_rescale_q(delay_num,
+ (AVRational){ 1, delay_den },
+ s->streams[0]->time_base);
+
+ av_log(s, AV_LOG_DEBUG, "%s: "
+ "sequence_number: %"PRId32", "
+ "width: %"PRIu32", "
+ "height: %"PRIu32", "
+ "x_offset: %"PRIu32", "
+ "y_offset: %"PRIu32", "
+ "delay_num: %"PRIu16", "
+ "delay_den: %"PRIu16", "
+ "dispose_op: %d, "
+ "blend_op: %d\n",
+ __FUNCTION__,
+ sequence_number,
+ width,
+ height,
+ x_offset,
+ y_offset,
+ delay_num,
+ delay_den,
+ dispose_op,
+ blend_op);
+
+ if (width != s->streams[0]->codec->width ||
+ height != s->streams[0]->codec->height ||
+ x_offset != 0 ||
+ y_offset != 0) {
+ if (sequence_number == 0 ||
+ x_offset >= s->streams[0]->codec->width ||
+ width > s->streams[0]->codec->width - x_offset ||
+ y_offset >= s->streams[0]->codec->height ||
+ height > s->streams[0]->codec->height - y_offset)
+ return AVERROR_INVALIDDATA;
+ ctx->is_key_frame = 0;
+ } else {
+ if (sequence_number == 0 && dispose_op == APNG_DISPOSE_OP_PREVIOUS)
+ dispose_op = APNG_DISPOSE_OP_BACKGROUND;
+ ctx->is_key_frame = dispose_op == APNG_DISPOSE_OP_BACKGROUND ||
+ blend_op == APNG_BLEND_OP_SOURCE;
+ }
+
+ return 0;
+}
+
+static int apng_read_packet(AVFormatContext *s, AVPacket *pkt)
+{
+ APNGDemuxContext *ctx = s->priv_data;
+ int ret;
+ int64_t size;
+ AVIOContext *pb = s->pb;
+ uint32_t len, tag;
+
+ /*
+ * fcTL chunk length, in bytes:
+ * 4 (length)
+ * 4 (tag)
+ * 26 (actual chunk)
+ * 4 (crc) bytes
+ * and needed next:
+ * 4 (length)
+ * 4 (tag (must be fdAT or IDAT))
+ */
+ /* if num_play is not 1, then the seekback is already guaranteed */
+ if (ctx->num_play == 1 && (ret = ffio_ensure_seekback(pb, 46)) < 0)
+ return ret;
+
+ len = avio_rb32(pb);
+ tag = avio_rl32(pb);
+ switch (tag) {
+ case MKTAG('f', 'c', 'T', 'L'):
+ if (len != 26)
+ return AVERROR_INVALIDDATA;
+
+ if ((ret = decode_fctl_chunk(s, ctx, pkt)) < 0)
+ return ret;
+
+ /* fcTL must precede fdAT or IDAT */
+ len = avio_rb32(pb);
+ tag = avio_rl32(pb);
+ if (len > 0x7fffffff ||
+ tag != MKTAG('f', 'd', 'A', 'T') &&
+ tag != MKTAG('I', 'D', 'A', 'T'))
+ return AVERROR_INVALIDDATA;
+
+ size = 38 /* fcTL */ + 8 /* len, tag */ + len + 4 /* crc */;
+ if (size > INT_MAX)
+ return AVERROR(EINVAL);
+
+ if ((ret = avio_seek(pb, -46, SEEK_CUR)) < 0 ||
+ (ret = av_append_packet(pb, pkt, size)) < 0)
+ return ret;
+
+ if (ctx->num_play == 1 && (ret = ffio_ensure_seekback(pb, 8)) < 0)
+ return ret;
+
+ len = avio_rb32(pb);
+ tag = avio_rl32(pb);
+ while (tag &&
+ tag != MKTAG('f', 'c', 'T', 'L') &&
+ tag != MKTAG('I', 'E', 'N', 'D')) {
+ if (len > 0x7fffffff)
+ return AVERROR_INVALIDDATA;
+ if ((ret = avio_seek(pb, -8, SEEK_CUR)) < 0 ||
+ (ret = av_append_packet(pb, pkt, len + 12)) < 0)
+ return ret;
+ if (ctx->num_play == 1 && (ret = ffio_ensure_seekback(pb, 8)) < 0)
+ return ret;
+ len = avio_rb32(pb);
+ tag = avio_rl32(pb);
+ }
+ if ((ret = avio_seek(pb, -8, SEEK_CUR)) < 0)
+ return ret;
+
+ if (ctx->is_key_frame)
+ pkt->flags |= AV_PKT_FLAG_KEY;
+ pkt->pts = ctx->pkt_pts;
+ pkt->duration = ctx->pkt_duration;
+ ctx->pkt_pts += ctx->pkt_duration;
+ return ret;
+ case MKTAG('I', 'E', 'N', 'D'):
+ ctx->cur_loop++;
+ if (ctx->ignore_loop || ctx->num_play >= 1 && ctx->cur_loop == ctx->num_play) {
+ avio_seek(pb, -8, SEEK_CUR);
+ return AVERROR_EOF;
+ }
+ if ((ret = avio_seek(pb, s->streams[0]->codec->extradata_size + 8, SEEK_SET)) < 0)
+ return ret;
+ return 0;
+ default:
+ {
+ char tag_buf[5];
+
+ av_get_codec_tag_string(tag_buf, sizeof(tag_buf), tag);
+ avpriv_request_sample(s, "In-stream tag=%s (0x%08X) len=%"PRIu32, tag_buf, tag, len);
+ avio_skip(pb, len + 4);
+ }
+ }
+
+ /* Handle the unsupported yet cases */
+ return AVERROR_PATCHWELCOME;
+}
+
+static const AVOption options[] = {
+ { "ignore_loop", "ignore loop setting" , offsetof(APNGDemuxContext, ignore_loop),
+ AV_OPT_TYPE_INT, { .i64 = 1 } , 0, 1 , AV_OPT_FLAG_DECODING_PARAM },
+ { "max_fps" , "maximum framerate (0 is no limit)" , offsetof(APNGDemuxContext, max_fps),
+ AV_OPT_TYPE_INT, { .i64 = DEFAULT_APNG_FPS }, 0, INT_MAX, AV_OPT_FLAG_DECODING_PARAM },
+ { "default_fps", "default framerate (0 is as fast as possible)", offsetof(APNGDemuxContext, default_fps),
+ AV_OPT_TYPE_INT, { .i64 = DEFAULT_APNG_FPS }, 0, INT_MAX, AV_OPT_FLAG_DECODING_PARAM },
+ { NULL },
+};
+
+static const AVClass demuxer_class = {
+ .class_name = "APNG demuxer",
+ .item_name = av_default_item_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+ .category = AV_CLASS_CATEGORY_DEMUXER,
+};
+
+AVInputFormat ff_apng_demuxer = {
+ .name = "apng",
+ .long_name = NULL_IF_CONFIG_SMALL("Animated Portable Network Graphics"),
+ .priv_data_size = sizeof(APNGDemuxContext),
+ .read_probe = apng_probe,
+ .read_header = apng_read_header,
+ .read_packet = apng_read_packet,
+ .flags = AVFMT_GENERIC_INDEX,
+ .priv_class = &demuxer_class,
+};
return 0;
}
-static int asf_write_index(AVFormatContext *s, ASFIndex *index,
+static int asf_write_index(AVFormatContext *s, const ASFIndex *index,
uint16_t max, uint32_t count)
{
AVIOContext *pb = s->pb;
/*
* SSA/ASS demuxer
* Copyright (c) 2008 Michael Niedermayer
+ * Copyright (c) 2014 Clément Bœsch
*
* This file is part of FFmpeg.
*
typedef struct ASSContext {
FFDemuxSubtitlesQueue q;
+ unsigned readorder;
} ASSContext;
static int ass_probe(AVProbeData *p)
return 0;
}
-static int read_ts(const uint8_t *p, int64_t *start, int *duration)
+static int read_dialogue(ASSContext *ass, AVBPrint *dst, const uint8_t *p,
+ int64_t *start, int *duration)
{
+ int pos = 0;
int64_t end;
int hh1, mm1, ss1, ms1;
int hh2, mm2, ss2, ms2;
- if (sscanf(p, "%*[^,],%d:%d:%d%*c%d,%d:%d:%d%*c%d",
+ if (sscanf(p, "Dialogue: %*[^,],%d:%d:%d%*c%d,%d:%d:%d%*c%d,%n",
&hh1, &mm1, &ss1, &ms1,
- &hh2, &mm2, &ss2, &ms2) == 8) {
+ &hh2, &mm2, &ss2, &ms2, &pos) >= 8 && pos > 0) {
+
+ /* This is not part of the sscanf itself in order to handle an actual
+ * number (which would be the Layer) or the form "Marked=N" (which is
+ * the old SSA field, now replaced by Layer, and will lead to Layer
+ * being 0 here). */
+ const int layer = atoi(p + 10);
+
end = (hh2*3600LL + mm2*60LL + ss2) * 100LL + ms2;
*start = (hh1*3600LL + mm1*60LL + ss1) * 100LL + ms1;
*duration = end - *start;
+
+ av_bprint_clear(dst);
+ av_bprintf(dst, "%u,%d,%s", ass->readorder++, layer, p + pos);
+
+ /* right strip the buffer */
+ while (dst->len > 0 &&
+ dst->str[dst->len - 1] == '\r' ||
+ dst->str[dst->len - 1] == '\n')
+ dst->str[--dst->len] = 0;
return 0;
}
return -1;
static int ass_read_header(AVFormatContext *s)
{
ASSContext *ass = s->priv_data;
- AVBPrint header, line;
- int header_remaining, res = 0;
+ AVBPrint header, line, rline;
+ int res = 0;
AVStream *st;
FFTextReader tr;
- ff_text_init_avio(&tr, s->pb);
+ ff_text_init_avio(s, &tr, s->pb);
st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
avpriv_set_pts_info(st, 64, 1, 100);
st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
- st->codec->codec_id = AV_CODEC_ID_SSA;
-
- header_remaining = INT_MAX;
+ st->codec->codec_id = AV_CODEC_ID_ASS;
av_bprint_init(&header, 0, AV_BPRINT_SIZE_UNLIMITED);
av_bprint_init(&line, 0, AV_BPRINT_SIZE_UNLIMITED);
+ av_bprint_init(&rline, 0, AV_BPRINT_SIZE_UNLIMITED);
for (;;) {
int64_t pos = get_line(&line, &tr);
+ int64_t ts_start = AV_NOPTS_VALUE;
+ int duration = -1;
+ AVPacket *sub;
if (!line.str[0]) // EOF
break;
- if (!memcmp(line.str, "[Events]", 8))
- header_remaining = 2;
- else if (line.str[0] == '[')
- header_remaining = INT_MAX;
-
- if (header_remaining) {
+ if (read_dialogue(ass, &rline, line.str, &ts_start, &duration) < 0) {
av_bprintf(&header, "%s", line.str);
- header_remaining--;
- } else {
- int64_t ts_start = AV_NOPTS_VALUE;
- int duration = -1;
- AVPacket *sub;
-
- if (read_ts(line.str, &ts_start, &duration) < 0)
- continue;
- sub = ff_subtitles_queue_insert(&ass->q, line.str, line.len, 0);
- if (!sub) {
- res = AVERROR(ENOMEM);
- goto end;
- }
- sub->pos = pos;
- sub->pts = ts_start;
- sub->duration = duration;
+ continue;
}
+ sub = ff_subtitles_queue_insert(&ass->q, rline.str, rline.len, 0);
+ if (!sub) {
+ res = AVERROR(ENOMEM);
+ goto end;
+ }
+ sub->pos = pos;
+ sub->pts = ts_start;
+ sub->duration = duration;
}
- av_bprint_finalize(&line, NULL);
-
res = avpriv_bprint_to_extradata(st->codec, &header);
if (res < 0)
goto end;
ff_subtitles_queue_finalize(&ass->q);
end:
+ av_bprint_finalize(&header, NULL);
+ av_bprint_finalize(&line, NULL);
+ av_bprint_finalize(&rline, NULL);
return res;
}
#include "avformat.h"
#include "internal.h"
+#include "libavutil/opt.h"
+
typedef struct DialogueLine {
int readorder;
char *line;
} DialogueLine;
typedef struct ASSContext{
- unsigned int extra_index;
+ const AVClass *class;
int write_ts; // 0: ssa (timing in payload), 1: ass (matroska like)
int expected_readorder;
DialogueLine *dialogue_cache;
DialogueLine *last_added_dialogue;
int cache_size;
+ int ssa_mode;
+ int ignore_readorder;
}ASSContext;
static int write_header(AVFormatContext *s)
{
ASSContext *ass = s->priv_data;
AVCodecContext *avctx= s->streams[0]->codec;
- uint8_t *last= NULL;
if (s->nb_streams != 1 || (avctx->codec_id != AV_CODEC_ID_SSA &&
avctx->codec_id != AV_CODEC_ID_ASS)) {
av_log(s, AV_LOG_ERROR, "Exactly one ASS/SSA stream is needed.\n");
- return -1;
+ return AVERROR(EINVAL);
}
ass->write_ts = avctx->codec_id == AV_CODEC_ID_ASS;
avpriv_set_pts_info(s->streams[0], 64, 1, 100);
-
- while(ass->extra_index < avctx->extradata_size){
- uint8_t *p = avctx->extradata + ass->extra_index;
- uint8_t *end= strchr(p, '\n');
- if(!end) end= avctx->extradata + avctx->extradata_size;
- else end++;
-
- avio_write(s->pb, p, end-p);
- ass->extra_index += end-p;
-
- if(last && !memcmp(last, "[Events]", 8))
- break;
- last=p;
+ if (avctx->extradata_size > 0) {
+ avio_write(s->pb, avctx->extradata, avctx->extradata_size);
+ if (avctx->extradata[avctx->extradata_size - 1] != '\n')
+ avio_write(s->pb, "\r\n", 2);
+ ass->ssa_mode = !strstr(avctx->extradata, "\n[V4+ Styles]");
+ if (!strstr(avctx->extradata, "\n[Events]"))
+ avio_printf(s->pb, "[Events]\r\nFormat: %s, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text\r\n",
+ ass->ssa_mode ? "Marked" : "Layer");
}
-
avio_flush(s->pb);
return 0;
if (*p == ',')
p++;
+ if (ass->ssa_mode && !strncmp(p, "Marked=", 7))
+ p += 7;
+
layer = strtol(p, &p, 10);
if (*p == ',')
p++;
if (hh1 > 9) hh1 = 9, mm1 = 59, ss1 = 59, ms1 = 99;
if (hh2 > 9) hh2 = 9, mm2 = 59, ss2 = 59, ms2 = 99;
- dialogue->line = av_asprintf("%ld,%d:%02d:%02d.%02d,%d:%02d:%02d.%02d,%s",
+ dialogue->line = av_asprintf("%s%ld,%d:%02d:%02d.%02d,%d:%02d:%02d.%02d,%s",
+ ass->ssa_mode ? "Marked=" : "",
layer, hh1, mm1, ss1, ms1, hh2, mm2, ss2, ms2, p);
if (!dialogue->line) {
av_free(dialogue);
return AVERROR(ENOMEM);
}
insert_dialogue(ass, dialogue);
- purge_dialogues(s, 0);
+ purge_dialogues(s, ass->ignore_readorder);
} else {
avio_write(s->pb, pkt->data, pkt->size);
}
static int write_trailer(AVFormatContext *s)
{
- ASSContext *ass = s->priv_data;
- AVCodecContext *avctx= s->streams[0]->codec;
-
purge_dialogues(s, 1);
- avio_write(s->pb, avctx->extradata + ass->extra_index,
- avctx->extradata_size - ass->extra_index);
-
return 0;
}
+#define OFFSET(x) offsetof(ASSContext, x)
+#define E AV_OPT_FLAG_ENCODING_PARAM
+static const AVOption options[] = {
+ { "ignore_readorder", "write events immediately, even if they're out-of-order", OFFSET(ignore_readorder), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, E },
+ { NULL },
+};
+
+static const AVClass ass_class = {
+ .class_name = "ass muxer",
+ .item_name = av_default_item_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
AVOutputFormat ff_ass_muxer = {
.name = "ass",
.long_name = NULL_IF_CONFIG_SMALL("SSA (SubStation Alpha) subtitle"),
.write_packet = write_packet,
.write_trailer = write_trailer,
.flags = AVFMT_GLOBALHEADER | AVFMT_NOTIMESTAMPS | AVFMT_TS_NONSTRICT,
+ .priv_class = &ass_class,
};
{
AVStream *st = s->streams[stream_index];
AudioInterleaveContext *aic = st->priv_data;
-
+ int ret;
int size = FFMIN(av_fifo_size(aic->fifo), *aic->samples * aic->sample_size);
if (!size || (!flush && size == av_fifo_size(aic->fifo)))
return 0;
- if (av_new_packet(pkt, size) < 0)
- return AVERROR(ENOMEM);
+ ret = av_new_packet(pkt, size);
+ if (ret < 0)
+ return ret;
av_fifo_generic_read(aic->fifo, pkt->data, size, NULL);
pkt->dts = pkt->pts = aic->dts;
*size = out_size;
return 0;
}
+
+const uint8_t *ff_avc_mp4_find_startcode(const uint8_t *start,
+ const uint8_t *end,
+ int nal_length_size)
+{
+ unsigned int res = 0;
+
+ if (end - start < nal_length_size)
+ return NULL;
+ while (nal_length_size--)
+ res = (res << 8) | *start++;
+
+ if (res > end - start)
+ return NULL;
+
+ return start + res;
+}
int ff_isom_write_avcc(AVIOContext *pb, const uint8_t *data, int len);
const uint8_t *ff_avc_find_startcode(const uint8_t *p, const uint8_t *end);
int ff_avc_write_annexb_extradata(const uint8_t *in, uint8_t **buf, int *size);
+const uint8_t *ff_avc_mp4_find_startcode(const uint8_t *start,
+ const uint8_t *end,
+ int nal_length_size);
#endif /* AVFORMAT_AVC_H */
const char *filename;
unsigned char *buf; /**< Buffer must have AVPROBE_PADDING_SIZE of extra allocated bytes filled with zero. */
int buf_size; /**< Size of buf except extra allocated bytes */
- uint8_t *mime_type; /**< mime_type, when known. */
+ const char *mime_type; /**< mime_type, when known. */
} AVProbeData;
#define AVPROBE_SCORE_RETRY (AVPROBE_SCORE_MAX/4)
/**
* Stream information used internally by av_find_stream_info()
*/
-#define MAX_STD_TIMEBASES (60*12+6)
+#define MAX_STD_TIMEBASES (30*12+7+6)
struct {
int64_t last_dts;
int64_t duration_gcd;
*/
int skip_samples;
+ /**
+ * If not 0, the first audio sample that should be discarded from the stream.
+ * This is broken by design (needs global sample count), but can't be
+ * avoided for broken by design formats such as mp3 with ad-hoc gapless
+ * audio support.
+ */
+ int64_t first_discard_sample;
+
+ /**
+ * The sample after last sample that is intended to be discarded after
+ * first_discard_sample. Works on frame boundaries only. Used to prevent
+ * early EOF if the gapless info is broken (considered concatenated mp3s).
+ */
+ int64_t last_discard_sample;
+
/**
* Number of internally decoded frames, used internally in libavformat, do not access
* its lifetime differs from info which is why it is not in that structure.
*/
int inject_global_side_data;
+ /**
+ * String containing paris of key and values describing recommended encoder configuration.
+ * Paris are separated by ','.
+ * Keys are separated from values by '='.
+ */
+ char *recommended_encoder_configuration;
+
+ /**
+ * display aspect ratio (0 if unknown)
+ * - encoding: unused
+ * - decoding: Set by libavformat to calculate sample_aspect_ratio internally
+ */
+ AVRational display_aspect_ratio;
} AVStream;
AVRational av_stream_get_r_frame_rate(const AVStream *s);
void av_stream_set_r_frame_rate(AVStream *s, AVRational r);
struct AVCodecParserContext *av_stream_get_parser(const AVStream *s);
+char* av_stream_get_recommended_encoder_configuration(const AVStream *s);
+void av_stream_set_recommended_encoder_configuration(AVStream *s, char *configuration);
/**
* Returns the pts of the last muxed packet + its duration
*/
int max_ts_probe;
+ /**
+ * Avoid negative timestamps during muxing.
+ * Any value of the AVFMT_AVOID_NEG_TS_* constants.
+ * Note, this only works when using av_interleaved_write_frame. (interleave_packet_per_dts is in use)
+ * - muxing: Set by user
+ * - demuxing: unused
+ */
+ int avoid_negative_ts;
+#define AVFMT_AVOID_NEG_TS_AUTO -1 ///< Enabled when required by target format
+#define AVFMT_AVOID_NEG_TS_MAKE_NON_NEGATIVE 1 ///< Shift timestamps so they are non negative
+#define AVFMT_AVOID_NEG_TS_MAKE_ZERO 2 ///< Shift timestamps so that they start at 0
+
/**
* Transport stream id.
*/
int use_wallclock_as_timestamps;
- /**
- * Avoid negative timestamps during muxing.
- * 0 -> allow negative timestamps
- * 1 -> avoid negative timestamps
- * -1 -> choose automatically (default)
- * Note, this only works when interleave_packet_per_dts is in use.
- * - encoding: Set by user via AVOptions (NO direct access)
- * - decoding: unused
- */
- int avoid_negative_ts;
-
/**
* avio flags, used to force AVIO_FLAG_DIRECT.
* - encoding: unused
*/
int format_probesize;
+ /**
+ * ',' separated list of allowed decoders.
+ * If NULL then all are allowed
+ * - encoding: unused
+ * - decoding: set by user through AVOptions (NO direct access)
+ */
+ char *codec_whitelist;
+
+ /**
+ * ',' separated list of allowed demuxers.
+ * If NULL then all are allowed
+ * - encoding: unused
+ * - decoding: set by user through AVOptions (NO direct access)
+ */
+ char *format_whitelist;
+
/*****************************************************************
* All fields below this line are not part of the public API. They
* may not be used outside of libavformat and can be changed and
* via AVOptions (NO direct access).
*/
int64_t probesize2;
+
+ /**
+ * dump format separator.
+ * can be ", " or "\n " or anything else
+ * Code outside libavformat should access this field using AVOptions
+ * (NO direct access).
+ * - muxing: Set by user.
+ * - demuxing: Set by user.
+ */
+ uint8_t *dump_separator;
} AVFormatContext;
int av_format_get_probe_score(const AVFormatContext *s);
*/
-#if FF_API_ALLOC_OUTPUT_CONTEXT
-/**
- * @deprecated deprecated in favor of avformat_alloc_output_context2()
- */
-attribute_deprecated
-AVFormatContext *avformat_alloc_output_context(const char *format,
- AVOutputFormat *oformat,
- const char *filename);
-#endif
-
/**
* Allocate an AVFormatContext for an output format.
* avformat_free_context() can be used to free the context and
attribute_deprecated
int av_demuxer_open(AVFormatContext *ic);
-#if FF_API_FORMAT_PARAMETERS
-/**
- * Read packets of a media file to get stream information. This
- * is useful for file formats with no headers such as MPEG. This
- * function also computes the real framerate in case of MPEG-2 repeat
- * frame mode.
- * The logical file position is not changed by this function;
- * examined packets may be buffered for later processing.
- *
- * @param ic media file handle
- * @return >=0 if OK, AVERROR_xxx on error
- * @todo Let the user decide somehow what information is needed so that
- * we do not waste time getting stuff the user does not need.
- *
- * @deprecated use avformat_find_stream_info.
- */
-attribute_deprecated
-int av_find_stream_info(AVFormatContext *ic);
-#endif
-
/**
* Read packets of a media file to get stream information. This
* is useful for file formats with no headers such as MPEG. This
AVCodec **decoder_ret,
int flags);
-#if FF_API_READ_PACKET
-/**
- * @deprecated use AVFMT_FLAG_NOFILLIN | AVFMT_FLAG_NOPARSE to read raw
- * unprocessed packets
- *
- * Read a transport packet from a media file.
- *
- * This function is obsolete and should never be used.
- * Use av_read_frame() instead.
- *
- * @param s media file handle
- * @param pkt is filled
- * @return 0 if OK, AVERROR_xxx on error
- */
-attribute_deprecated
-int av_read_packet(AVFormatContext *s, AVPacket *pkt);
-#endif
-
/**
* Return the next frame of a stream.
* This function returns what is stored in the file, and does not validate
*/
int av_read_pause(AVFormatContext *s);
-#if FF_API_CLOSE_INPUT_FILE
-/**
- * @deprecated use avformat_close_input()
- * Close a media file (but not its codecs).
- *
- * @param s media file handle
- */
-attribute_deprecated
-void av_close_input_file(AVFormatContext *s);
-#endif
-
/**
* Close an opened input AVFormatContext. Free it and all its contents
* and set *s to NULL.
* @}
*/
-#if FF_API_NEW_STREAM
-/**
- * Add a new stream to a media file.
- *
- * Can only be called in the read_header() function. If the flag
- * AVFMTCTX_NOHEADER is in the format context, then new streams
- * can be added in read_packet too.
- *
- * @param s media file handle
- * @param id file-format-dependent stream ID
- */
-attribute_deprecated
-AVStream *av_new_stream(AVFormatContext *s, int id);
-#endif
-
-#if FF_API_SET_PTS_INFO
-/**
- * @deprecated this function is not supposed to be called outside of lavf
- */
-attribute_deprecated
-void av_set_pts_info(AVStream *s, int pts_wrap_bits,
- unsigned int pts_num, unsigned int pts_den);
-#endif
-
#define AVSEEK_FLAG_BACKWARD 1 ///< seek backward
#define AVSEEK_FLAG_BYTE 2 ///< seeking based on position in bytes
#define AVSEEK_FLAG_ANY 4 ///< seek to any frame, even non-keyframes
pal_size = FFMIN(pal_size, st->codec->extradata_size);
pal_src = st->codec->extradata +
st->codec->extradata_size - pal_size;
+ /* Exclude the "BottomUp" field from the palette */
+ if (pal_src - st->codec->extradata >= 9 &&
+ !memcmp(st->codec->extradata + st->codec->extradata_size - 9, "BottomUp", 9))
+ pal_src -= 9;
for (i = 0; i < pal_size / 4; i++)
ast->pal[i] = 0xFFU<<24 | AV_RL32(pal_src+4*i);
ast->has_pal = 1;
return 0;
}
-static int read_gab2_sub(AVStream *st, AVPacket *pkt)
+static int read_gab2_sub(AVFormatContext *s, AVStream *st, AVPacket *pkt)
{
if (pkt->size >= 7 &&
pkt->size < INT_MAX - AVPROBE_PADDING_SIZE &&
goto error;
ast->sub_ctx->pb = pb;
+
+ if (ff_copy_whitelists(ast->sub_ctx, s) < 0)
+ goto error;
+
if (!avformat_open_input(&ast->sub_ctx, "", sub_demuxer, NULL)) {
ff_read_packet(ast->sub_ctx, &ast->sub_pkt);
*st->codec = *ast->sub_ctx->streams[0]->codec;
return 1;
error:
+ av_freep(&ast->sub_ctx);
av_freep(&pb);
}
return 0;
return sub_st;
}
-static int get_stream_idx(unsigned *d)
+static int get_stream_idx(const unsigned *d)
{
if (d[0] >= '0' && d[0] <= '9' &&
d[1] >= '0' && d[1] <= '9') {
goto start_sync;
}
- n = avi->dv_demux ? 0 : get_stream_idx(d);
+ n = get_stream_idx(d);
if (!((i - avi->last_pkt_pos) & 1) &&
get_stream_idx(d + 1) < s->nb_streams)
goto start_sync;
}
+ if (avi->dv_demux && n != 0)
+ continue;
+
// parse ##dc/##wb
if (n < s->nb_streams) {
AVStream *st;
if (size < 0)
av_free_packet(pkt);
} else if (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE &&
- !st->codec->codec_tag && read_gab2_sub(st, pkt)) {
+ !st->codec->codec_tag && read_gab2_sub(s, st, pkt)) {
ast->frame_offset++;
avi->stream_index = -1;
ast->remaining = 0;
int entry;
int max_size;
+ int64_t last_dts;
+
AVIIndex indexes;
} AVIStream;
-static inline AVIIentry *avi_get_ientry(AVIIndex *idx, int ent_id)
+static int avi_write_packet(AVFormatContext *s, AVPacket *pkt);
+
+static inline AVIIentry *avi_get_ientry(const AVIIndex *idx, int ent_id)
{
int cl = ent_id / AVI_INDEX_CLUSTER_SIZE;
int id = ent_id % AVI_INDEX_CLUSTER_SIZE;
return 0;
}
+static int write_skip_frames(AVFormatContext *s, int stream_index, int64_t dts)
+{
+ AVIStream *avist = s->streams[stream_index]->priv_data;
+ AVCodecContext *enc = s->streams[stream_index]->codec;
+
+ av_dlog(s, "dts:%s packet_count:%d stream_index:%d\n", av_ts2str(dts), avist->packet_count, stream_index);
+ while (enc->block_align == 0 && dts != AV_NOPTS_VALUE &&
+ dts > avist->packet_count && enc->codec_id != AV_CODEC_ID_XSUB && avist->packet_count) {
+ AVPacket empty_packet;
+
+ if (dts - avist->packet_count > 60000) {
+ av_log(s, AV_LOG_ERROR, "Too large number of skipped frames %"PRId64" > 60000\n", dts - avist->packet_count);
+ return AVERROR(EINVAL);
+ }
+
+ av_init_packet(&empty_packet);
+ empty_packet.size = 0;
+ empty_packet.data = NULL;
+ empty_packet.stream_index = stream_index;
+ avi_write_packet(s, &empty_packet);
+ av_dlog(s, "dup dts:%s packet_count:%d\n", av_ts2str(dts), avist->packet_count);
+ }
+
+ return 0;
+}
+
static int avi_write_packet(AVFormatContext *s, AVPacket *pkt)
{
unsigned char tag[5];
AVIOContext *pb = s->pb;
AVIStream *avist = s->streams[stream_index]->priv_data;
AVCodecContext *enc = s->streams[stream_index]->codec;
+ int ret;
- if (enc->codec_id == AV_CODEC_ID_H264 && enc->codec_tag == MKTAG('H','2','6','4')) {
- int ret = ff_check_h264_startcode(s, s->streams[stream_index], pkt);
+ if (enc->codec_id == AV_CODEC_ID_H264 && enc->codec_tag == MKTAG('H','2','6','4') && pkt->size) {
+ ret = ff_check_h264_startcode(s, s->streams[stream_index], pkt);
if (ret < 0)
return ret;
}
- av_dlog(s, "dts:%s packet_count:%d stream_index:%d\n", av_ts2str(pkt->dts), avist->packet_count, stream_index);
- while (enc->block_align == 0 && pkt->dts != AV_NOPTS_VALUE &&
- pkt->dts > avist->packet_count && enc->codec_id != AV_CODEC_ID_XSUB && avist->packet_count) {
- AVPacket empty_packet;
- if (pkt->dts - avist->packet_count > 60000) {
- av_log(s, AV_LOG_ERROR, "Too large number of skipped frames %"PRId64" > 60000\n", pkt->dts - avist->packet_count);
- return AVERROR(EINVAL);
- }
+ if ((ret = write_skip_frames(s, stream_index, pkt->dts)) < 0)
+ return ret;
+
+ if (pkt->dts != AV_NOPTS_VALUE)
+ avist->last_dts = pkt->dts + pkt->duration;
- av_init_packet(&empty_packet);
- empty_packet.size = 0;
- empty_packet.data = NULL;
- empty_packet.stream_index = stream_index;
- avi_write_packet(s, &empty_packet);
- av_dlog(s, "dup dts:%s packet_count:%d\n", av_ts2str(pkt->dts), avist->packet_count);
- }
avist->packet_count++;
// Make sure to put an OpenDML chunk when the file size exceeds the limits
int i, j, n, nb_frames;
int64_t file_size;
+ for (i = 0; i < s->nb_streams; i++) {
+ AVIStream *avist = s->streams[i]->priv_data;
+ write_skip_frames(s, i, avist->last_dts);
+ }
+
if (pb->seekable) {
if (avi->riff_id == 1) {
ff_end_tag(pb, avi->movi_list);
*
* @param buffer Memory block for input/output operations via AVIOContext.
* The buffer must be allocated with av_malloc() and friends.
+ * It may be freed and replaced with a new buffer by libavformat.
+ * AVIOContext.buffer holds the buffer currently in use,
+ * which must be later freed with av_free().
* @param buffer_size The buffer size is very important for performance.
* For protocols with fixed blocksize it should be set to this blocksize.
* For others a typical size is a cache page, e.g. 4kb.
int avio_printf(AVIOContext *s, const char *fmt, ...) av_printf_format(2, 3);
/**
- * Force flushing of buffered data to the output s.
+ * Force flushing of buffered data.
*
- * Force the buffered data to be immediately written to the output,
+ * For write streams, force the buffered data to be immediately written to the output,
* without to wait to fill the internal buffer.
+ *
+ * For read streams, discard all currently buffered data, and advance the
+ * reported file position to that of the underlying stream. This does not
+ * read new data, and does not perform any seeks.
*/
void avio_flush(AVIOContext *s);
static void flush_buffer(AVIOContext *s)
{
- if (s->buf_ptr > s->buffer) {
+ if (s->write_flag && s->buf_ptr > s->buffer) {
writeout(s, s->buffer, s->buf_ptr - s->buffer);
if (s->update_checksum) {
s->checksum = s->update_checksum(s->checksum, s->checksum_ptr,
}
}
s->buf_ptr = s->buffer;
+ if (!s->write_flag)
+ s->buf_end = s->buffer;
}
void avio_w8(AVIOContext *s, int b)
if (c && i < maxlen-1)
buf[i++] = c;
} while (c != '\n' && c != '\r' && c);
- if (c == '\r' && avio_r8(s) != '\n')
+ if (c == '\r' && avio_r8(s) != '\n' && !avio_feof(s))
avio_skip(s, -1);
buf[i] = 0;
*pbuffer = NULL;
return 0;
}
- d = s->opaque;
/* don't attempt to pad fixed-size packet buffers */
if (!s->max_packet_size) {
avio_flush(s);
+ d = s->opaque;
*pbuffer = d->buffer;
size = d->size;
av_free(d);
if ((ret = av_new_packet(pkt, vidbuf_nbytes)) < 0)
goto fail;
memcpy(pkt->data, vidbuf_start, vidbuf_nbytes);
- av_free(vidbuf_start);
pkt->pos = position;
pkt->stream_index = vid->video_index;
if (vid->palette) {
uint8_t *pdata = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE,
BVID_PALETTE_SIZE);
- if (pdata)
- memcpy(pdata, vid->palette, BVID_PALETTE_SIZE);
+ if (!pdata) {
+ ret = AVERROR(ENOMEM);
+ av_log(s, AV_LOG_ERROR, "Failed to allocate palette side data\n");
+ goto fail;
+ }
+ memcpy(pdata, vid->palette, BVID_PALETTE_SIZE);
+
av_freep(&vid->palette);
}
vid->nframes--; // used to check if all the frames were read
- return 0;
fail:
av_free(vidbuf_start);
return ret;
int64_t data_start; ///< data start position, in bytes
int64_t data_size; ///< raw data size, in bytes
-} CaffContext;
+} CafContext;
static int probe(AVProbeData *p)
{
static int read_desc_chunk(AVFormatContext *s)
{
AVIOContext *pb = s->pb;
- CaffContext *caf = s->priv_data;
+ CafContext *caf = s->priv_data;
AVStream *st;
int flags;
{
AVIOContext *pb = s->pb;
AVStream *st = s->streams[0];
- CaffContext *caf = s->priv_data;
+ CafContext *caf = s->priv_data;
int64_t pos = 0, ccount, num_packets;
int i;
static int read_header(AVFormatContext *s)
{
AVIOContext *pb = s->pb;
- CaffContext *caf = s->priv_data;
+ CafContext *caf = s->priv_data;
AVStream *st;
uint32_t tag = 0;
int found_data, ret;
{
AVIOContext *pb = s->pb;
AVStream *st = s->streams[0];
- CaffContext *caf = s->priv_data;
+ CafContext *caf = s->priv_data;
int res, pkt_size = 0, pkt_frames = 0;
int64_t left = CAF_MAX_PKT_SIZE;
int64_t timestamp, int flags)
{
AVStream *st = s->streams[0];
- CaffContext *caf = s->priv_data;
+ CafContext *caf = s->priv_data;
int64_t pos, packet_cnt, frame_cnt;
timestamp = FFMAX(timestamp, 0);
AVInputFormat ff_caf_demuxer = {
.name = "caf",
.long_name = NULL_IF_CONFIG_SMALL("Apple CAF (Core Audio Format)"),
- .priv_data_size = sizeof(CaffContext),
+ .priv_data_size = sizeof(CafContext),
.read_probe = probe,
.read_header = read_header,
.read_packet = read_packet,
/*
- * Phanton Cine demuxer
+ * Phantom Cine demuxer
* Copyright (c) 2010-2011 Peter Ross <pross@xvid.org>
*
* This file is part of FFmpeg.
#include "libavutil/intreadwrite.h"
#include "libavcodec/bmp.h"
+#include "libavutil/intfloat.h"
#include "avformat.h"
#include "internal.h"
return 0;
}
+static int set_metadata_float(AVDictionary **dict, const char *key, float value, int allow_zero)
+{
+ if (value != 0 || allow_zero) {
+ char tmp[64];
+ snprintf(tmp, sizeof(tmp), "%f", value);
+ return av_dict_set(dict, key, tmp, 0);
+ }
+ return 0;
+}
+
static int cine_read_header(AVFormatContext *avctx)
{
AVIOContext *pb = avctx->pb;
set_metadata_int(&st->metadata, "contrast", avio_rl32(pb), 1);
set_metadata_int(&st->metadata, "gamma", avio_rl32(pb), 1);
- avio_skip(pb, 72); // Reserved1 .. WBView
+ avio_skip(pb, 12 + 16); // Reserved1 .. AutoExpRect
+ set_metadata_float(&st->metadata, "wbgain[0].r", av_int2float(avio_rl32(pb)), 1);
+ set_metadata_float(&st->metadata, "wbgain[0].b", av_int2float(avio_rl32(pb)), 1);
+ avio_skip(pb, 36); // WBGain[1].. WBView
st->codec->bits_per_coded_sample = avio_rl32(pb);
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include "avformat.h"
#include "libavutil/avstring.h"
#include "libavutil/mem.h"
+
+#include "avformat.h"
#include "url.h"
#define AV_CAT_SEPARATOR "|"
char *node_uri = NULL;
int err = 0;
int64_t size;
- size_t len, i;
+ size_t len, i;
URLContext *uc;
struct concat_data *data = h->priv_data;
struct concat_nodes *nodes;
av_strstart(uri, "concat:", &uri);
- for (i = 0, len = 1; uri[i]; i++)
- if (uri[i] == *AV_CAT_SEPARATOR)
+ for (i = 0, len = 1; uri[i]; i++) {
+ if (uri[i] == *AV_CAT_SEPARATOR) {
/* integer overflow */
if (++len == UINT_MAX / sizeof(*nodes)) {
av_freep(&h->priv_data);
return AVERROR(ENAMETOOLONG);
}
+ }
+ }
- if (!(nodes = av_realloc(NULL, sizeof(*nodes) * len))) {
+ if (!(nodes = av_realloc(NULL, sizeof(*nodes) * len)))
return AVERROR(ENOMEM);
- } else
+ else
data->nodes = nodes;
/* handle input */
len = strcspn(uri, AV_CAT_SEPARATOR);
if ((err = av_reallocp(&node_uri, len + 1)) < 0)
break;
- av_strlcpy(node_uri, uri, len+1);
- uri += len + strspn(uri+len, AV_CAT_SEPARATOR);
+ av_strlcpy(node_uri, uri, len + 1);
+ uri += len + strspn(uri + len, AV_CAT_SEPARATOR);
/* creating URLContext */
if ((err = ffurl_open(&uc, node_uri, flags,
int result, total = 0;
struct concat_data *data = h->priv_data;
struct concat_nodes *nodes = data->nodes;
- size_t i = data->current;
+ size_t i = data->current;
while (size > 0) {
result = ffurl_read(nodes[i].uc, buf, size);
if (result < 0)
return total ? total : result;
- if (!result)
+ if (!result) {
if (i + 1 == data->length ||
ffurl_seek(nodes[++i].uc, 0, SEEK_SET) < 0)
break;
+ }
total += result;
buf += result;
size -= result;
switch (whence) {
case SEEK_END:
- for (i = data->length - 1;
- i && pos < -nodes[i].size;
- i--)
+ for (i = data->length - 1; i && pos < -nodes[i].size; i--)
pos += nodes[i].size;
break;
case SEEK_CUR:
#include "libavutil/intreadwrite.h"
#include "libavutil/opt.h"
#include "libavutil/parseutils.h"
+#include "libavutil/timestamp.h"
#include "avformat.h"
#include "internal.h"
#include "url.h"
return AVERROR(ENOMEM);
cat->avf->interrupt_callback = avf->interrupt_callback;
+
+ if ((ret = ff_copy_whitelists(cat->avf, avf)) < 0)
+ return ret;
+
if ((ret = avformat_open_input(&cat->avf, file->url, NULL, NULL)) < 0 ||
(ret = avformat_find_stream_info(cat->avf, NULL)) < 0) {
av_log(avf, AV_LOG_ERROR, "Impossible to open '%s'\n", file->url);
int ret;
int64_t delta;
ConcatStream *cs;
+ AVStream *st;
while (1) {
ret = av_read_frame(cat->avf, pkt);
if ((ret = filter_packet(avf, cs, pkt)))
return ret;
+ st = cat->avf->streams[pkt->stream_index];
+ av_log(avf, AV_LOG_DEBUG, "file:%d stream:%d pts:%s pts_time:%s dts:%s dts_time:%s",
+ (unsigned)(cat->cur_file - cat->files), pkt->stream_index,
+ av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, &st->time_base),
+ av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, &st->time_base));
+
delta = av_rescale_q(cat->cur_file->start_time - cat->avf->start_time,
AV_TIME_BASE_Q,
cat->avf->streams[pkt->stream_index]->time_base);
pkt->pts += delta;
if (pkt->dts != AV_NOPTS_VALUE)
pkt->dts += delta;
+ av_log(avf, AV_LOG_DEBUG, " -> pts:%s pts_time:%s dts:%s dts_time:%s\n",
+ av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, &st->time_base),
+ av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, &st->time_base));
return ret;
}
int keylen;
uint8_t *iv;
int ivlen;
- struct AVAES *aes;
+ uint8_t *decrypt_key;
+ int decrypt_keylen;
+ uint8_t *decrypt_iv;
+ int decrypt_ivlen;
+ uint8_t *encrypt_key;
+ int encrypt_keylen;
+ uint8_t *encrypt_iv;
+ int encrypt_ivlen;
+ struct AVAES *aes_decrypt;
+ struct AVAES *aes_encrypt;
+
+ uint8_t pad[BLOCKSIZE];
+ int pad_len;
+
} CryptoContext;
#define OFFSET(x) offsetof(CryptoContext, x)
#define D AV_OPT_FLAG_DECODING_PARAM
+#define E AV_OPT_FLAG_ENCODING_PARAM
static const AVOption options[] = {
- {"key", "AES decryption key", OFFSET(key), AV_OPT_TYPE_BINARY, .flags = D },
- {"iv", "AES decryption initialization vector", OFFSET(iv), AV_OPT_TYPE_BINARY, .flags = D },
+ {"key", "AES encryption/decryption key", OFFSET(key), AV_OPT_TYPE_BINARY, .flags = D|E },
+ {"iv", "AES encryption/decryption initialization vector", OFFSET(iv), AV_OPT_TYPE_BINARY, .flags = D|E },
+ {"decryption_key", "AES decryption key", OFFSET(decrypt_key), AV_OPT_TYPE_BINARY, .flags = D },
+ {"decryption_iv", "AES decryption initialization vector", OFFSET(decrypt_iv), AV_OPT_TYPE_BINARY, .flags = D },
+ {"encryption_key", "AES encryption key", OFFSET(encrypt_key), AV_OPT_TYPE_BINARY, .flags = E },
+ {"encryption_iv", "AES encryption initialization vector", OFFSET(encrypt_iv), AV_OPT_TYPE_BINARY, .flags = E },
{ NULL }
};
.version = LIBAVUTIL_VERSION_INT,
};
+static int set_aes_arg(CryptoContext *c, uint8_t **buf, int *buf_len,
+ uint8_t *default_buf, int default_buf_len,
+ const char *desc)
+{
+ if (!*buf_len) {
+ if (!default_buf_len) {
+ av_log(c, AV_LOG_ERROR, "%s not set\n", desc);
+ return AVERROR(EINVAL);
+ } else if (default_buf_len != BLOCKSIZE) {
+ av_log(c, AV_LOG_ERROR,
+ "invalid %s size (%d bytes, block size is %d)\n",
+ desc, default_buf_len, BLOCKSIZE);
+ return AVERROR(EINVAL);
+ }
+ *buf = av_memdup(default_buf, default_buf_len);
+ if (!*buf)
+ return AVERROR(ENOMEM);
+ *buf_len = default_buf_len;
+ } else if (*buf_len != BLOCKSIZE) {
+ av_log(c, AV_LOG_ERROR,
+ "invalid %s size (%d bytes, block size is %d)\n",
+ desc, *buf_len, BLOCKSIZE);
+ return AVERROR(EINVAL);
+ }
+ return 0;
+}
+
static int crypto_open2(URLContext *h, const char *uri, int flags, AVDictionary **options)
{
const char *nested_url;
goto err;
}
- if (c->keylen < BLOCKSIZE || c->ivlen < BLOCKSIZE) {
- av_log(h, AV_LOG_ERROR, "Key or IV not set\n");
- ret = AVERROR(EINVAL);
- goto err;
+ if (flags & AVIO_FLAG_READ) {
+ if ((ret = set_aes_arg(c, &c->decrypt_key, &c->decrypt_keylen,
+ c->key, c->keylen, "decryption key")) < 0)
+ goto err;
+ if ((ret = set_aes_arg(c, &c->decrypt_iv, &c->decrypt_ivlen,
+ c->key, c->keylen, "decryption IV")) < 0)
+ goto err;
}
+
if (flags & AVIO_FLAG_WRITE) {
- av_log(h, AV_LOG_ERROR, "Only decryption is supported currently\n");
- ret = AVERROR(ENOSYS);
- goto err;
+ if ((ret = set_aes_arg(c, &c->encrypt_key, &c->encrypt_keylen,
+ c->key, c->keylen, "encryption key")) < 0)
+ if (ret < 0)
+ goto err;
+ if ((ret = set_aes_arg(c, &c->encrypt_iv, &c->encrypt_ivlen,
+ c->key, c->keylen, "encryption IV")) < 0)
+ goto err;
}
- if ((ret = ffurl_open(&c->hd, nested_url, AVIO_FLAG_READ,
+
+ if ((ret = ffurl_open(&c->hd, nested_url, flags,
&h->interrupt_callback, options)) < 0) {
- av_log(h, AV_LOG_ERROR, "Unable to open input\n");
+ av_log(h, AV_LOG_ERROR, "Unable to open resource: %s\n", nested_url);
goto err;
}
- c->aes = av_aes_alloc();
- if (!c->aes) {
- ret = AVERROR(ENOMEM);
- goto err;
+
+ if (flags & AVIO_FLAG_READ) {
+ c->aes_decrypt = av_aes_alloc();
+ if (!c->aes_decrypt) {
+ ret = AVERROR(ENOMEM);
+ goto err;
+ }
+ ret = av_aes_init(c->aes_decrypt, c->decrypt_key, BLOCKSIZE*8, 1);
+ if (ret < 0)
+ goto err;
}
- av_aes_init(c->aes, c->key, 128, 1);
+ if (flags & AVIO_FLAG_WRITE) {
+ c->aes_encrypt = av_aes_alloc();
+ if (!c->aes_encrypt) {
+ ret = AVERROR(ENOMEM);
+ goto err;
+ }
+ ret = av_aes_init(c->aes_encrypt, c->encrypt_key, BLOCKSIZE*8, 0);
+ if (ret < 0)
+ goto err;
+ }
+
+ c->pad_len = 0;
h->is_streamed = 1;
return AVERROR_EOF;
if (!c->eof)
blocks--;
- av_aes_crypt(c->aes, c->outbuffer, c->inbuffer + c->indata_used, blocks,
- c->iv, 1);
+ av_aes_crypt(c->aes_decrypt, c->outbuffer, c->inbuffer + c->indata_used,
+ blocks, c->decrypt_iv, 1);
c->outdata = BLOCKSIZE * blocks;
c->outptr = c->outbuffer;
c->indata_used += BLOCKSIZE * blocks;
goto retry;
}
+static int crypto_write(URLContext *h, const unsigned char *buf, int size)
+{
+ CryptoContext *c = h->priv_data;
+ int total_size, blocks, pad_len, out_size;
+ uint8_t *out_buf;
+ int ret = 0;
+
+ total_size = size + c->pad_len;
+ pad_len = total_size % BLOCKSIZE;
+ out_size = total_size - pad_len;
+ blocks = out_size / BLOCKSIZE;
+
+ if (out_size) {
+ out_buf = av_malloc(out_size);
+ if (!out_buf)
+ return AVERROR(ENOMEM);
+
+ if (c->pad_len) {
+ memcpy(&c->pad[c->pad_len], buf, BLOCKSIZE - c->pad_len);
+ av_aes_crypt(c->aes_encrypt, out_buf, c->pad, 1, c->encrypt_iv, 0);
+ blocks--;
+ }
+
+ av_aes_crypt(c->aes_encrypt, &out_buf[c->pad_len ? BLOCKSIZE : 0],
+ &buf[c->pad_len ? BLOCKSIZE - c->pad_len: 0],
+ blocks, c->encrypt_iv, 0);
+
+ ret = ffurl_write(c->hd, out_buf, out_size);
+ av_free(out_buf);
+ if (ret < 0)
+ return ret;
+
+ memcpy(c->pad, &buf[size - pad_len], pad_len);
+ } else
+ memcpy(&c->pad[c->pad_len], buf, size);
+
+ c->pad_len = pad_len;
+
+ return size;
+}
+
static int crypto_close(URLContext *h)
{
CryptoContext *c = h->priv_data;
+ uint8_t out_buf[BLOCKSIZE];
+ int ret, pad;
+
+ if (c->aes_encrypt) {
+ pad = BLOCKSIZE - c->pad_len;
+ memset(&c->pad[c->pad_len], pad, pad);
+ av_aes_crypt(c->aes_encrypt, out_buf, c->pad, 1, c->encrypt_iv, 0);
+ if ((ret = ffurl_write(c->hd, out_buf, BLOCKSIZE)) < 0)
+ return ret;
+ }
+
if (c->hd)
ffurl_close(c->hd);
- av_freep(&c->aes);
+ av_freep(&c->aes_decrypt);
+ av_freep(&c->aes_encrypt);
return 0;
}
.name = "crypto",
.url_open2 = crypto_open2,
.url_read = crypto_read,
+ .url_write = crypto_write,
.url_close = crypto_close,
.priv_data_size = sizeof(CryptoContext),
.priv_data_class = &crypto_class,
* 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/time_internal.h"
#include "avformat.h"
#include "internal.h"
couple of places, though. */
struct tm *ff_brktimegm(time_t secs, struct tm *tm)
{
- int days, y, ny, m;
- int md[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
-
- days = secs / 86400;
- secs %= 86400;
- tm->tm_hour = secs / 3600;
- tm->tm_min = (secs % 3600) / 60;
- tm->tm_sec = secs % 60;
-
- /* oh well, may be someone some day will invent a formula for this stuff */
- y = 1970; /* start "guessing" */
- while (days > 365) {
- ny = (y + days/366);
- days -= (ny - y) * 365 + LEAPS_COUNT(ny - 1) - LEAPS_COUNT(y - 1);
- y = ny;
- }
- if (days==365 && !ISLEAP(y)) { days=0; y++; }
- md[1] = ISLEAP(y)?29:28;
- for (m=0; days >= md[m]; m++)
- days -= md[m];
+ tm = gmtime_r(&secs, tm);
- tm->tm_year = y; /* unlike gmtime_r we store complete year here */
- tm->tm_mon = m+1; /* unlike gmtime_r tm_mon is from 1 to 12 */
- tm->tm_mday = days+1;
+ tm->tm_year += 1900; /* unlike gmtime_r we store complete year here */
+ tm->tm_mon += 1; /* unlike gmtime_r tm_mon is from 1 to 12 */
return tm;
}
--- /dev/null
+/*
+ * MPEG-DASH ISO BMFF segmenter
+ * Copyright (c) 2014 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"
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include "libavutil/avstring.h"
+#include "libavutil/intreadwrite.h"
+#include "libavutil/mathematics.h"
+#include "libavutil/opt.h"
+#include "libavutil/time_internal.h"
+
+#include "avc.h"
+#include "avformat.h"
+#include "avio_internal.h"
+#include "internal.h"
+#include "isom.h"
+#include "os_support.h"
+#include "url.h"
+
+// See ISO/IEC 23009-1:2014 5.3.9.4.4
+typedef enum {
+ DASH_TMPL_ID_UNDEFINED = -1,
+ DASH_TMPL_ID_ESCAPE,
+ DASH_TMPL_ID_REP_ID,
+ DASH_TMPL_ID_NUMBER,
+ DASH_TMPL_ID_BANDWIDTH,
+ DASH_TMPL_ID_TIME,
+} DASHTmplId;
+
+typedef struct Segment {
+ char file[1024];
+ int64_t start_pos;
+ int range_length, index_length;
+ int64_t time;
+ int duration;
+ int n;
+} Segment;
+
+typedef struct OutputStream {
+ AVFormatContext *ctx;
+ int ctx_inited;
+ uint8_t iobuf[32768];
+ URLContext *out;
+ int packets_written;
+ char initfile[1024];
+ int64_t init_start_pos;
+ int init_range_length;
+ int nb_segments, segments_size, segment_index;
+ Segment **segments;
+ int64_t first_dts, start_dts, end_dts;
+ int bit_rate;
+ char bandwidth_str[64];
+
+ char codec_str[100];
+} OutputStream;
+
+typedef struct DASHContext {
+ const AVClass *class; /* Class for private options. */
+ int window_size;
+ int extra_window_size;
+ int min_seg_duration;
+ int remove_at_exit;
+ int use_template;
+ int use_timeline;
+ int single_file;
+ OutputStream *streams;
+ int has_video, has_audio;
+ int last_duration;
+ int total_duration;
+ char availability_start_time[100];
+ char dirname[1024];
+ const char *single_file_name;
+ const char *init_seg_name;
+ const char *media_seg_name;
+} DASHContext;
+
+static int dash_write(void *opaque, uint8_t *buf, int buf_size)
+{
+ OutputStream *os = opaque;
+ if (os->out)
+ ffurl_write(os->out, buf, buf_size);
+ return buf_size;
+}
+
+// RFC 6381
+static void set_codec_str(AVFormatContext *s, AVCodecContext *codec,
+ char *str, int size)
+{
+ const AVCodecTag *tags[2] = { NULL, NULL };
+ uint32_t tag;
+ if (codec->codec_type == AVMEDIA_TYPE_VIDEO)
+ tags[0] = ff_codec_movvideo_tags;
+ else if (codec->codec_type == AVMEDIA_TYPE_AUDIO)
+ tags[0] = ff_codec_movaudio_tags;
+ else
+ return;
+
+ tag = av_codec_get_tag(tags, codec->codec_id);
+ if (!tag)
+ return;
+ if (size < 5)
+ return;
+
+ AV_WL32(str, tag);
+ str[4] = '\0';
+ if (!strcmp(str, "mp4a") || !strcmp(str, "mp4v")) {
+ uint32_t oti;
+ tags[0] = ff_mp4_obj_type;
+ oti = av_codec_get_tag(tags, codec->codec_id);
+ if (oti)
+ av_strlcatf(str, size, ".%02x", oti);
+ else
+ return;
+
+ if (tag == MKTAG('m', 'p', '4', 'a')) {
+ if (codec->extradata_size >= 2) {
+ int aot = codec->extradata[0] >> 3;
+ if (aot == 31)
+ aot = ((AV_RB16(codec->extradata) >> 5) & 0x3f) + 32;
+ av_strlcatf(str, size, ".%d", aot);
+ }
+ } else if (tag == MKTAG('m', 'p', '4', 'v')) {
+ // Unimplemented, should output ProfileLevelIndication as a decimal number
+ av_log(s, AV_LOG_WARNING, "Incomplete RFC 6381 codec string for mp4v\n");
+ }
+ } else if (!strcmp(str, "avc1")) {
+ uint8_t *tmpbuf = NULL;
+ uint8_t *extradata = codec->extradata;
+ int extradata_size = codec->extradata_size;
+ if (!extradata_size)
+ return;
+ if (extradata[0] != 1) {
+ AVIOContext *pb;
+ if (avio_open_dyn_buf(&pb) < 0)
+ return;
+ if (ff_isom_write_avcc(pb, extradata, extradata_size) < 0) {
+ avio_close_dyn_buf(pb, &tmpbuf);
+ av_free(tmpbuf);
+ return;
+ }
+ extradata_size = avio_close_dyn_buf(pb, &extradata);
+ tmpbuf = extradata;
+ }
+
+ if (extradata_size >= 4)
+ av_strlcatf(str, size, ".%02x%02x%02x",
+ extradata[1], extradata[2], extradata[3]);
+ av_free(tmpbuf);
+ }
+}
+
+static void dash_free(AVFormatContext *s)
+{
+ DASHContext *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->ctx && os->ctx_inited)
+ av_write_trailer(os->ctx);
+ if (os->ctx && os->ctx->pb)
+ av_free(os->ctx->pb);
+ ffurl_close(os->out);
+ os->out = NULL;
+ if (os->ctx)
+ avformat_free_context(os->ctx);
+ for (j = 0; j < os->nb_segments; j++)
+ av_free(os->segments[j]);
+ av_free(os->segments);
+ }
+ av_freep(&c->streams);
+}
+
+static void output_segment_list(OutputStream *os, AVIOContext *out, DASHContext *c)
+{
+ int i, start_index = 0, start_number = 1;
+ if (c->window_size) {
+ start_index = FFMAX(os->nb_segments - c->window_size, 0);
+ start_number = FFMAX(os->segment_index - c->window_size, 1);
+ }
+
+ if (c->use_template) {
+ int timescale = c->use_timeline ? os->ctx->streams[0]->time_base.den : AV_TIME_BASE;
+ avio_printf(out, "\t\t\t\t<SegmentTemplate timescale=\"%d\" ", timescale);
+ if (!c->use_timeline)
+ avio_printf(out, "duration=\"%d\" ", c->last_duration);
+ avio_printf(out, "initialization=\"%s\" media=\"%s\" startNumber=\"%d\">\n", c->init_seg_name, c->media_seg_name, c->use_timeline ? start_number : 1);
+ if (c->use_timeline) {
+ avio_printf(out, "\t\t\t\t\t<SegmentTimeline>\n");
+ for (i = start_index; i < os->nb_segments; ) {
+ Segment *seg = os->segments[i];
+ int repeat = 0;
+ avio_printf(out, "\t\t\t\t\t\t<S ");
+ if (i == start_index)
+ avio_printf(out, "t=\"%"PRId64"\" ", seg->time);
+ avio_printf(out, "d=\"%d\" ", seg->duration);
+ while (i + repeat + 1 < os->nb_segments && os->segments[i + repeat + 1]->duration == seg->duration)
+ repeat++;
+ if (repeat > 0)
+ avio_printf(out, "r=\"%d\" ", repeat);
+ avio_printf(out, "/>\n");
+ i += 1 + repeat;
+ }
+ avio_printf(out, "\t\t\t\t\t</SegmentTimeline>\n");
+ }
+ avio_printf(out, "\t\t\t\t</SegmentTemplate>\n");
+ } else if (c->single_file) {
+ avio_printf(out, "\t\t\t\t<BaseURL>%s</BaseURL>\n", os->initfile);
+ avio_printf(out, "\t\t\t\t<SegmentList timescale=\"%d\" duration=\"%d\" startNumber=\"%d\">\n", AV_TIME_BASE, c->last_duration, start_number);
+ avio_printf(out, "\t\t\t\t\t<Initialization range=\"%"PRId64"-%"PRId64"\" />\n", os->init_start_pos, os->init_start_pos + os->init_range_length - 1);
+ for (i = start_index; i < os->nb_segments; i++) {
+ Segment *seg = os->segments[i];
+ avio_printf(out, "\t\t\t\t\t<SegmentURL mediaRange=\"%"PRId64"-%"PRId64"\" ", seg->start_pos, seg->start_pos + seg->range_length - 1);
+ if (seg->index_length)
+ avio_printf(out, "indexRange=\"%"PRId64"-%"PRId64"\" ", seg->start_pos, seg->start_pos + seg->index_length - 1);
+ avio_printf(out, "/>\n");
+ }
+ avio_printf(out, "\t\t\t\t</SegmentList>\n");
+ } else {
+ avio_printf(out, "\t\t\t\t<SegmentList timescale=\"%d\" duration=\"%d\" startNumber=\"%d\">\n", AV_TIME_BASE, c->last_duration, start_number);
+ avio_printf(out, "\t\t\t\t\t<Initialization sourceURL=\"%s\" />\n", os->initfile);
+ for (i = start_index; i < os->nb_segments; i++) {
+ Segment *seg = os->segments[i];
+ avio_printf(out, "\t\t\t\t\t<SegmentURL media=\"%s\" />\n", seg->file);
+ }
+ avio_printf(out, "\t\t\t\t</SegmentList>\n");
+ }
+}
+
+static DASHTmplId dash_read_tmpl_id(const char *identifier, char *format_tag,
+ size_t format_tag_size, const char **ptr) {
+ const char *next_ptr;
+ DASHTmplId id_type = DASH_TMPL_ID_UNDEFINED;
+
+ if (av_strstart(identifier, "$$", &next_ptr)) {
+ id_type = DASH_TMPL_ID_ESCAPE;
+ *ptr = next_ptr;
+ } else if (av_strstart(identifier, "$RepresentationID$", &next_ptr)) {
+ id_type = DASH_TMPL_ID_REP_ID;
+ // default to basic format, as $RepresentationID$ identifiers
+ // are not allowed to have custom format-tags.
+ av_strlcpy(format_tag, "%d", format_tag_size);
+ *ptr = next_ptr;
+ } else { // the following identifiers may have an explicit format_tag
+ if (av_strstart(identifier, "$Number", &next_ptr))
+ id_type = DASH_TMPL_ID_NUMBER;
+ else if (av_strstart(identifier, "$Bandwidth", &next_ptr))
+ id_type = DASH_TMPL_ID_BANDWIDTH;
+ else if (av_strstart(identifier, "$Time", &next_ptr))
+ id_type = DASH_TMPL_ID_TIME;
+ else
+ id_type = DASH_TMPL_ID_UNDEFINED;
+
+ // next parse the dash format-tag and generate a c-string format tag
+ // (next_ptr now points at the first '%' at the beginning of the format-tag)
+ if (id_type != DASH_TMPL_ID_UNDEFINED) {
+ const char *number_format = DASH_TMPL_ID_TIME ? "lld" : "d";
+ if (next_ptr[0] == '$') { // no dash format-tag
+ snprintf(format_tag, format_tag_size, "%%%s", number_format);
+ *ptr = &next_ptr[1];
+ } else {
+ const char *width_ptr;
+ // only tolerate single-digit width-field (i.e. up to 9-digit width)
+ if (av_strstart(next_ptr, "%0", &width_ptr) &&
+ av_isdigit(width_ptr[0]) &&
+ av_strstart(&width_ptr[1], "d$", &next_ptr)) {
+ // yes, we're using a format tag to build format_tag.
+ snprintf(format_tag, format_tag_size, "%s%c%s", "%0", width_ptr[0], number_format);
+ *ptr = next_ptr;
+ } else {
+ av_log(NULL, AV_LOG_WARNING, "Failed to parse format-tag beginning with %s. Expected either a "
+ "closing '$' character or a format-string like '%%0[width]d', "
+ "where width must be a single digit\n", next_ptr);
+ id_type = DASH_TMPL_ID_UNDEFINED;
+ }
+ }
+ }
+ }
+ return id_type;
+}
+
+static void dash_fill_tmpl_params(char *dst, size_t buffer_size,
+ const char *template, int rep_id,
+ int number, int bit_rate,
+ int64_t time) {
+ int dst_pos = 0;
+ const char *t_cur = template;
+ while (dst_pos < buffer_size - 1 && *t_cur) {
+ char format_tag[7]; // May be "%d", "%0Xd", or "%0Xlld" (for $Time$), where X is in [0-9]
+ int n = 0;
+ DASHTmplId id_type;
+ const char *t_next = strchr(t_cur, '$'); // copy over everything up to the first '$' character
+ if (t_next) {
+ int num_copy_bytes = FFMIN(t_next - t_cur, buffer_size - dst_pos - 1);
+ av_strlcpy(&dst[dst_pos], t_cur, num_copy_bytes + 1);
+ // advance
+ dst_pos += num_copy_bytes;
+ t_cur = t_next;
+ } else { // no more DASH identifiers to substitute - just copy the rest over and break
+ av_strlcpy(&dst[dst_pos], t_cur, buffer_size - dst_pos);
+ break;
+ }
+
+ if (dst_pos >= buffer_size - 1 || !*t_cur)
+ break;
+
+ // t_cur is now pointing to a '$' character
+ id_type = dash_read_tmpl_id(t_cur, format_tag, sizeof(format_tag), &t_next);
+ switch (id_type) {
+ case DASH_TMPL_ID_ESCAPE:
+ av_strlcpy(&dst[dst_pos], "$", 2);
+ n = 1;
+ break;
+ case DASH_TMPL_ID_REP_ID:
+ n = snprintf(&dst[dst_pos], buffer_size - dst_pos, format_tag, rep_id);
+ break;
+ case DASH_TMPL_ID_NUMBER:
+ n = snprintf(&dst[dst_pos], buffer_size - dst_pos, format_tag, number);
+ break;
+ case DASH_TMPL_ID_BANDWIDTH:
+ n = snprintf(&dst[dst_pos], buffer_size - dst_pos, format_tag, bit_rate);
+ break;
+ case DASH_TMPL_ID_TIME:
+ n = snprintf(&dst[dst_pos], buffer_size - dst_pos, format_tag, time);
+ break;
+ case DASH_TMPL_ID_UNDEFINED:
+ // copy over one byte and advance
+ av_strlcpy(&dst[dst_pos], t_cur, 2);
+ n = 1;
+ t_next = &t_cur[1];
+ break;
+ }
+ // t_next points just past the processed identifier
+ // n is the number of bytes that were attempted to be written to dst
+ // (may have failed to write all because buffer_size).
+
+ // advance
+ dst_pos += FFMIN(n, buffer_size - dst_pos - 1);
+ t_cur = t_next;
+ }
+}
+
+static char *xmlescape(const char *str) {
+ int outlen = strlen(str)*3/2 + 6;
+ char *out = av_realloc(NULL, outlen + 1);
+ int pos = 0;
+ if (!out)
+ return NULL;
+ for (; *str; str++) {
+ if (pos + 6 > outlen) {
+ char *tmp;
+ outlen = 2 * outlen + 6;
+ tmp = av_realloc(out, outlen + 1);
+ if (!tmp) {
+ av_free(out);
+ return NULL;
+ }
+ out = tmp;
+ }
+ if (*str == '&') {
+ memcpy(&out[pos], "&", 5);
+ pos += 5;
+ } else if (*str == '<') {
+ memcpy(&out[pos], "<", 4);
+ pos += 4;
+ } else if (*str == '>') {
+ memcpy(&out[pos], ">", 4);
+ pos += 4;
+ } else if (*str == '\'') {
+ memcpy(&out[pos], "'", 6);
+ pos += 6;
+ } else if (*str == '\"') {
+ memcpy(&out[pos], """, 6);
+ pos += 6;
+ } else {
+ out[pos++] = *str;
+ }
+ }
+ out[pos] = '\0';
+ return out;
+}
+
+static void write_time(AVIOContext *out, int64_t time)
+{
+ int seconds = time / AV_TIME_BASE;
+ int fractions = time % AV_TIME_BASE;
+ int minutes = seconds / 60;
+ int hours = minutes / 60;
+ seconds %= 60;
+ minutes %= 60;
+ avio_printf(out, "PT");
+ if (hours)
+ avio_printf(out, "%dH", hours);
+ if (hours || minutes)
+ avio_printf(out, "%dM", minutes);
+ avio_printf(out, "%d.%dS", seconds, fractions / (AV_TIME_BASE / 10));
+}
+
+static int write_manifest(AVFormatContext *s, int final)
+{
+ DASHContext *c = s->priv_data;
+ AVIOContext *out;
+ char temp_filename[1024];
+ int ret, i;
+ AVDictionaryEntry *title = av_dict_get(s->metadata, "title", NULL, 0);
+
+ snprintf(temp_filename, sizeof(temp_filename), "%s.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", temp_filename);
+ return ret;
+ }
+ avio_printf(out, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
+ avio_printf(out, "<MPD xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n"
+ "\txmlns=\"urn:mpeg:dash:schema:mpd:2011\"\n"
+ "\txmlns:xlink=\"http://www.w3.org/1999/xlink\"\n"
+ "\txsi:schemaLocation=\"urn:mpeg:DASH:schema:MPD:2011 http://standards.iso.org/ittf/PubliclyAvailableStandards/MPEG-DASH_schema_files/DASH-MPD.xsd\"\n"
+ "\tprofiles=\"urn:mpeg:dash:profile:isoff-live:2011\"\n"
+ "\ttype=\"%s\"\n", final ? "static" : "dynamic");
+ if (final) {
+ avio_printf(out, "\tmediaPresentationDuration=\"");
+ write_time(out, c->total_duration);
+ avio_printf(out, "\"\n");
+ } else {
+ int update_period = c->last_duration / AV_TIME_BASE;
+ if (c->use_template && !c->use_timeline)
+ update_period = 500;
+ avio_printf(out, "\tminimumUpdatePeriod=\"PT%dS\"\n", update_period);
+ avio_printf(out, "\tsuggestedPresentationDelay=\"PT%dS\"\n", c->last_duration / AV_TIME_BASE);
+ if (!c->availability_start_time[0] && s->nb_streams > 0 && c->streams[0].nb_segments > 0) {
+ time_t t = time(NULL);
+ struct tm *ptm, tmbuf;
+ ptm = gmtime_r(&t, &tmbuf);
+ if (ptm) {
+ if (!strftime(c->availability_start_time, sizeof(c->availability_start_time),
+ "%Y-%m-%dT%H:%M:%S", ptm))
+ c->availability_start_time[0] = '\0';
+ }
+ }
+ if (c->availability_start_time[0])
+ avio_printf(out, "\tavailabilityStartTime=\"%s\"\n", c->availability_start_time);
+ if (c->window_size && c->use_template) {
+ avio_printf(out, "\ttimeShiftBufferDepth=\"");
+ write_time(out, c->last_duration * c->window_size);
+ avio_printf(out, "\"\n");
+ }
+ }
+ avio_printf(out, "\tminBufferTime=\"");
+ write_time(out, c->last_duration);
+ avio_printf(out, "\">\n");
+ avio_printf(out, "\t<ProgramInformation>\n");
+ if (title) {
+ char *escaped = xmlescape(title->value);
+ avio_printf(out, "\t\t<Title>%s</Title>\n", escaped);
+ av_free(escaped);
+ }
+ avio_printf(out, "\t</ProgramInformation>\n");
+ if (c->window_size && s->nb_streams > 0 && c->streams[0].nb_segments > 0 && !c->use_template) {
+ OutputStream *os = &c->streams[0];
+ int start_index = FFMAX(os->nb_segments - c->window_size, 0);
+ int64_t start_time = av_rescale_q(os->segments[start_index]->time, s->streams[0]->time_base, AV_TIME_BASE_Q);
+ avio_printf(out, "\t<Period start=\"");
+ write_time(out, start_time);
+ avio_printf(out, "\">\n");
+ } else {
+ avio_printf(out, "\t<Period start=\"PT0.0S\">\n");
+ }
+
+ if (c->has_video) {
+ avio_printf(out, "\t\t<AdaptationSet id=\"video\" segmentAlignment=\"true\" bitstreamSwitching=\"true\">\n");
+ for (i = 0; i < s->nb_streams; i++) {
+ AVStream *st = s->streams[i];
+ OutputStream *os = &c->streams[i];
+ if (s->streams[i]->codec->codec_type != AVMEDIA_TYPE_VIDEO)
+ continue;
+ avio_printf(out, "\t\t\t<Representation id=\"%d\" mimeType=\"video/mp4\" codecs=\"%s\"%s width=\"%d\" height=\"%d\">\n", i, os->codec_str, os->bandwidth_str, st->codec->width, st->codec->height);
+ output_segment_list(&c->streams[i], out, c);
+ avio_printf(out, "\t\t\t</Representation>\n");
+ }
+ avio_printf(out, "\t\t</AdaptationSet>\n");
+ }
+ if (c->has_audio) {
+ avio_printf(out, "\t\t<AdaptationSet id=\"audio\" segmentAlignment=\"true\" bitstreamSwitching=\"true\">\n");
+ for (i = 0; i < s->nb_streams; i++) {
+ AVStream *st = s->streams[i];
+ OutputStream *os = &c->streams[i];
+ if (s->streams[i]->codec->codec_type != AVMEDIA_TYPE_AUDIO)
+ continue;
+ avio_printf(out, "\t\t\t<Representation id=\"%d\" mimeType=\"audio/mp4\" codecs=\"%s\"%s audioSamplingRate=\"%d\">\n", i, os->codec_str, os->bandwidth_str, st->codec->sample_rate);
+ avio_printf(out, "\t\t\t\t<AudioChannelConfiguration schemeIdUri=\"urn:mpeg:dash:23003:3:audio_channel_configuration:2011\" value=\"%d\" />\n", st->codec->channels);
+ output_segment_list(&c->streams[i], out, c);
+ avio_printf(out, "\t\t\t</Representation>\n");
+ }
+ avio_printf(out, "\t\t</AdaptationSet>\n");
+ }
+ avio_printf(out, "\t</Period>\n");
+ avio_printf(out, "</MPD>\n");
+ avio_flush(out);
+ avio_close(out);
+ return ff_rename(temp_filename, s->filename, s);
+}
+
+static int dash_write_header(AVFormatContext *s)
+{
+ DASHContext *c = s->priv_data;
+ int ret = 0, i;
+ AVOutputFormat *oformat;
+ char *ptr;
+ char basename[1024];
+
+ if (c->single_file_name)
+ c->single_file = 1;
+ if (c->single_file)
+ c->use_template = 0;
+
+ av_strlcpy(c->dirname, s->filename, sizeof(c->dirname));
+ ptr = strrchr(c->dirname, '/');
+ if (ptr) {
+ av_strlcpy(basename, &ptr[1], sizeof(basename));
+ ptr[1] = '\0';
+ } else {
+ c->dirname[0] = '\0';
+ av_strlcpy(basename, s->filename, sizeof(basename));
+ }
+
+ ptr = strrchr(basename, '.');
+ if (ptr)
+ *ptr = '\0';
+
+ oformat = av_guess_format("mp4", 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[i];
+ AVFormatContext *ctx;
+ AVStream *st;
+ AVDictionary *opts = NULL;
+ char filename[1024];
+
+ os->bit_rate = s->streams[i]->codec->bit_rate ?
+ s->streams[i]->codec->bit_rate :
+ s->streams[i]->codec->rc_max_rate;
+ if (os->bit_rate) {
+ snprintf(os->bandwidth_str, sizeof(os->bandwidth_str),
+ " bandwidth=\"%d\"", os->bit_rate);
+ } else {
+ int level = s->strict_std_compliance >= FF_COMPLIANCE_STRICT ?
+ AV_LOG_ERROR : AV_LOG_WARNING;
+ av_log(s, level, "No bit rate set for stream %d\n", i);
+ if (s->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
+ ret = AVERROR(EINVAL);
+ goto fail;
+ }
+ }
+
+ ctx = avformat_alloc_context();
+ if (!ctx) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+ os->ctx = ctx;
+ ctx->oformat = oformat;
+ ctx->interrupt_callback = s->interrupt_callback;
+
+ 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;
+ st->time_base = s->streams[i]->time_base;
+ ctx->avoid_negative_ts = s->avoid_negative_ts;
+
+ ctx->pb = avio_alloc_context(os->iobuf, sizeof(os->iobuf), AVIO_FLAG_WRITE, os, NULL, dash_write, NULL);
+ if (!ctx->pb) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+
+ if (c->single_file) {
+ if (c->single_file_name)
+ dash_fill_tmpl_params(os->initfile, sizeof(os->initfile), c->single_file_name, i, 0, os->bit_rate, 0);
+ else
+ snprintf(os->initfile, sizeof(os->initfile), "%s-stream%d.m4s", basename, i);
+ } else {
+ dash_fill_tmpl_params(os->initfile, sizeof(os->initfile), c->init_seg_name, i, 0, os->bit_rate, 0);
+ }
+ snprintf(filename, sizeof(filename), "%s%s", c->dirname, os->initfile);
+ ret = ffurl_open(&os->out, filename, AVIO_FLAG_WRITE, &s->interrupt_callback, NULL);
+ if (ret < 0)
+ goto fail;
+ os->init_start_pos = 0;
+
+ av_dict_set(&opts, "movflags", "frag_custom+dash", 0);
+ if ((ret = avformat_write_header(ctx, &opts)) < 0) {
+ goto fail;
+ }
+ os->ctx_inited = 1;
+ avio_flush(ctx->pb);
+ av_dict_free(&opts);
+
+ if (c->single_file) {
+ os->init_range_length = avio_tell(ctx->pb);
+ } else {
+ ffurl_close(os->out);
+ os->out = NULL;
+ }
+
+ s->streams[i]->time_base = st->time_base;
+ // If the muxer wants to shift timestamps, request to have them shifted
+ // already before being handed to this muxer, so we don't have mismatches
+ // between the MPD and the actual segments.
+ s->avoid_negative_ts = ctx->avoid_negative_ts;
+ if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO)
+ c->has_video = 1;
+ else if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO)
+ c->has_audio = 1;
+
+ set_codec_str(s, os->ctx->streams[0]->codec, os->codec_str, sizeof(os->codec_str));
+ os->first_dts = AV_NOPTS_VALUE;
+ os->segment_index = 1;
+ }
+
+ if (!c->has_video && c->min_seg_duration <= 0) {
+ av_log(s, AV_LOG_WARNING, "no video stream and no min seg duration set\n");
+ ret = AVERROR(EINVAL);
+ }
+ ret = write_manifest(s, 0);
+
+fail:
+ if (ret)
+ dash_free(s);
+ return ret;
+}
+
+static int add_segment(OutputStream *os, const char *file,
+ int64_t time, int duration,
+ int64_t start_pos, int64_t range_length,
+ int64_t index_length)
+{
+ int err;
+ Segment *seg;
+ if (os->nb_segments >= os->segments_size) {
+ os->segments_size = (os->segments_size + 1) * 2;
+ if ((err = av_reallocp(&os->segments, sizeof(*os->segments) *
+ os->segments_size)) < 0) {
+ os->segments_size = 0;
+ os->nb_segments = 0;
+ return err;
+ }
+ }
+ seg = av_mallocz(sizeof(*seg));
+ if (!seg)
+ return AVERROR(ENOMEM);
+ av_strlcpy(seg->file, file, sizeof(seg->file));
+ seg->time = time;
+ seg->duration = duration;
+ seg->start_pos = start_pos;
+ seg->range_length = range_length;
+ seg->index_length = index_length;
+ os->segments[os->nb_segments++] = seg;
+ os->segment_index++;
+ return 0;
+}
+
+static void write_styp(AVIOContext *pb)
+{
+ avio_wb32(pb, 24);
+ ffio_wfourcc(pb, "styp");
+ ffio_wfourcc(pb, "msdh");
+ avio_wb32(pb, 0); /* minor */
+ ffio_wfourcc(pb, "msdh");
+ ffio_wfourcc(pb, "msix");
+}
+
+static void find_index_range(AVFormatContext *s, const char *dirname,
+ const char *filename, int64_t pos,
+ int *index_length)
+{
+ char full_path[1024];
+ uint8_t buf[8];
+ URLContext *fd;
+ int ret;
+
+ snprintf(full_path, sizeof(full_path), "%s%s", dirname, filename);
+ ret = ffurl_open(&fd, full_path, AVIO_FLAG_READ, &s->interrupt_callback, NULL);
+ if (ret < 0)
+ return;
+ if (ffurl_seek(fd, pos, SEEK_SET) != pos) {
+ ffurl_close(fd);
+ return;
+ }
+ ret = ffurl_read(fd, buf, 8);
+ ffurl_close(fd);
+ if (ret < 8)
+ return;
+ if (AV_RL32(&buf[4]) != MKTAG('s', 'i', 'd', 'x'))
+ return;
+ *index_length = AV_RB32(&buf[0]);
+}
+
+static int dash_flush(AVFormatContext *s, int final, int stream)
+{
+ DASHContext *c = s->priv_data;
+ int i, ret = 0;
+ int cur_flush_segment_index = 0;
+ if (stream >= 0)
+ cur_flush_segment_index = c->streams[stream].segment_index;
+
+ for (i = 0; i < s->nb_streams; i++) {
+ OutputStream *os = &c->streams[i];
+ char filename[1024] = "", full_path[1024], temp_path[1024];
+ int64_t start_pos = avio_tell(os->ctx->pb);
+ int range_length, index_length = 0;
+
+ if (!os->packets_written)
+ continue;
+
+ // Flush the single stream that got a keyframe right now.
+ // Flush all audio streams as well, in sync with video keyframes,
+ // but not the other video streams.
+ if (stream >= 0 && i != stream) {
+ if (s->streams[i]->codec->codec_type != AVMEDIA_TYPE_AUDIO)
+ continue;
+ // Make sure we don't flush audio streams multiple times, when
+ // all video streams are flushed one at a time.
+ if (c->has_video && os->segment_index > cur_flush_segment_index)
+ continue;
+ }
+
+ if (!c->single_file) {
+ dash_fill_tmpl_params(filename, sizeof(filename), c->media_seg_name, i, os->segment_index, os->bit_rate, os->start_dts);
+ snprintf(full_path, sizeof(full_path), "%s%s", c->dirname, filename);
+ snprintf(temp_path, sizeof(temp_path), "%s.tmp", full_path);
+ ret = ffurl_open(&os->out, temp_path, AVIO_FLAG_WRITE, &s->interrupt_callback, NULL);
+ if (ret < 0)
+ break;
+ write_styp(os->ctx->pb);
+ }
+ av_write_frame(os->ctx, NULL);
+ avio_flush(os->ctx->pb);
+ os->packets_written = 0;
+
+ range_length = avio_tell(os->ctx->pb) - start_pos;
+ if (c->single_file) {
+ find_index_range(s, c->dirname, os->initfile, start_pos, &index_length);
+ } else {
+ ffurl_close(os->out);
+ os->out = NULL;
+ ret = ff_rename(temp_path, full_path, s);
+ if (ret < 0)
+ break;
+ }
+ add_segment(os, filename, os->start_dts, os->end_dts - os->start_dts, start_pos, range_length, index_length);
+ }
+
+ if (c->window_size || (final && c->remove_at_exit)) {
+ for (i = 0; i < s->nb_streams; i++) {
+ OutputStream *os = &c->streams[i];
+ int j;
+ int remove = os->nb_segments - c->window_size - c->extra_window_size;
+ if (final && c->remove_at_exit)
+ remove = os->nb_segments;
+ if (remove > 0) {
+ for (j = 0; j < remove; j++) {
+ char filename[1024];
+ snprintf(filename, sizeof(filename), "%s%s", c->dirname, os->segments[j]->file);
+ unlink(filename);
+ av_free(os->segments[j]);
+ }
+ os->nb_segments -= remove;
+ memmove(os->segments, os->segments + remove, os->nb_segments * sizeof(*os->segments));
+ }
+ }
+ }
+
+ if (ret >= 0)
+ ret = write_manifest(s, final);
+ return ret;
+}
+
+static int dash_write_packet(AVFormatContext *s, AVPacket *pkt)
+{
+ DASHContext *c = s->priv_data;
+ AVStream *st = s->streams[pkt->stream_index];
+ OutputStream *os = &c->streams[pkt->stream_index];
+ int64_t seg_end_duration = (os->segment_index) * (int64_t) c->min_seg_duration;
+ int ret;
+
+ // If forcing the stream to start at 0, the mp4 muxer will set the start
+ // timestamps to 0. Do the same here, to avoid mismatches in duration/timestamps.
+ if (os->first_dts == AV_NOPTS_VALUE &&
+ s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_MAKE_ZERO) {
+ pkt->pts -= pkt->dts;
+ pkt->dts = 0;
+ }
+
+ if (os->first_dts == AV_NOPTS_VALUE)
+ os->first_dts = pkt->dts;
+
+ if ((!c->has_video || st->codec->codec_type == AVMEDIA_TYPE_VIDEO) &&
+ pkt->flags & AV_PKT_FLAG_KEY && os->packets_written &&
+ av_compare_ts(pkt->dts - os->first_dts, st->time_base,
+ seg_end_duration, AV_TIME_BASE_Q) >= 0) {
+ int64_t prev_duration = c->last_duration;
+
+ c->last_duration = av_rescale_q(pkt->dts - os->start_dts,
+ st->time_base,
+ AV_TIME_BASE_Q);
+ c->total_duration = av_rescale_q(pkt->dts - os->first_dts,
+ st->time_base,
+ AV_TIME_BASE_Q);
+
+ if ((!c->use_timeline || !c->use_template) && prev_duration) {
+ if (c->last_duration < prev_duration*9/10 ||
+ c->last_duration > prev_duration*11/10) {
+ av_log(s, AV_LOG_WARNING,
+ "Segment durations differ too much, enable use_timeline "
+ "and use_template, or keep a stricter keyframe interval\n");
+ }
+ }
+
+ if ((ret = dash_flush(s, 0, pkt->stream_index)) < 0)
+ return ret;
+ }
+
+ if (!os->packets_written)
+ os->start_dts = pkt->dts;
+ os->end_dts = pkt->dts + pkt->duration;
+ os->packets_written++;
+ return ff_write_chained(os->ctx, 0, pkt, s, 0);
+}
+
+static int dash_write_trailer(AVFormatContext *s)
+{
+ DASHContext *c = s->priv_data;
+
+ if (s->nb_streams > 0) {
+ OutputStream *os = &c->streams[0];
+ // If no segments have been written so far, try to do a crude
+ // guess of the segment duration
+ if (!c->last_duration)
+ c->last_duration = av_rescale_q(os->end_dts - os->start_dts,
+ s->streams[0]->time_base,
+ AV_TIME_BASE_Q);
+ c->total_duration = av_rescale_q(os->end_dts - os->first_dts,
+ s->streams[0]->time_base,
+ AV_TIME_BASE_Q);
+ }
+ dash_flush(s, 1, -1);
+
+ if (c->remove_at_exit) {
+ char filename[1024];
+ int i;
+ for (i = 0; i < s->nb_streams; i++) {
+ OutputStream *os = &c->streams[i];
+ snprintf(filename, sizeof(filename), "%s%s", c->dirname, os->initfile);
+ unlink(filename);
+ }
+ unlink(s->filename);
+ }
+
+ dash_free(s);
+ return 0;
+}
+
+#define OFFSET(x) offsetof(DASHContext, x)
+#define E AV_OPT_FLAG_ENCODING_PARAM
+static const AVOption options[] = {
+ { "window_size", "number of segments kept in the manifest", OFFSET(window_size), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, E },
+ { "extra_window_size", "number of segments kept outside of the manifest before removing from disk", OFFSET(extra_window_size), AV_OPT_TYPE_INT, { .i64 = 5 }, 0, INT_MAX, E },
+ { "min_seg_duration", "minimum segment duration (in microseconds)", OFFSET(min_seg_duration), AV_OPT_TYPE_INT64, { .i64 = 5000000 }, 0, INT_MAX, E },
+ { "remove_at_exit", "remove all segments when finished", OFFSET(remove_at_exit), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, E },
+ { "use_template", "Use SegmentTemplate instead of SegmentList", OFFSET(use_template), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 1, E },
+ { "use_timeline", "Use SegmentTimeline in SegmentTemplate", OFFSET(use_timeline), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 1, E },
+ { "single_file", "Store all segments in one file, accessed using byte ranges", OFFSET(single_file), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, E },
+ { "single_file_name", "DASH-templated name to be used for baseURL. Implies storing all segments in one file, accessed using byte ranges", OFFSET(single_file_name), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, E },
+ { "init_seg_name", "DASH-templated name to used for the initialization segment", OFFSET(init_seg_name), AV_OPT_TYPE_STRING, {.str = "init-stream$RepresentationID$.m4s"}, 0, 0, E },
+ { "media_seg_name", "DASH-templated name to used for the media segments", OFFSET(media_seg_name), AV_OPT_TYPE_STRING, {.str = "chunk-stream$RepresentationID$-$Number%05d$.m4s"}, 0, 0, E },
+ { NULL },
+};
+
+static const AVClass dash_class = {
+ .class_name = "dash muxer",
+ .item_name = av_default_item_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
+AVOutputFormat ff_dash_muxer = {
+ .name = "dash",
+ .long_name = NULL_IF_CONFIG_SMALL("DASH Muxer"),
+ .priv_data_size = sizeof(DASHContext),
+ .audio_codec = AV_CODEC_ID_AAC,
+ .video_codec = AV_CODEC_ID_H264,
+ .flags = AVFMT_GLOBALHEADER | AVFMT_NOFILE | AVFMT_TS_NEGATIVE,
+ .write_header = dash_write_header,
+ .write_packet = dash_write_packet,
+ .write_trailer = dash_write_trailer,
+ .codec_tag = (const AVCodecTag* const []){ ff_mp4_obj_type, 0 },
+ .priv_class = &dash_class,
+};
{
const uint8_t *buf, *bufp;
uint32_t state = -1;
- int markers[4] = {0};
+ int markers[4*16] = {0};
int sum, max, i;
int64_t diff = 0;
uint8_t hdr[12 + FF_INPUT_BUFFER_PADDING_SIZE] = { 0 };
for(; buf < (p->buf+p->buf_size)-2; buf+=2) {
int marker, sample_blocks, sample_rate, sr_code, framesize;
+ int lfe;
GetBitContext gb;
bufp = buf;
if (sample_rate == 0)
continue;
+ get_bits(&gb, 5);
+ if (get_bits(&gb, 1))
+ continue;
+
+ skip_bits_long(&gb, 9);
+ lfe = get_bits(&gb, 2);
+ if (lfe > 2)
+ continue;
+
+ marker += 4* sr_code;
+
markers[marker] ++;
}
- sum = markers[0] + markers[1] + markers[2] + markers[3];
- max = 0;
- for (i=1; i<4; i++)
+
+ sum = max = 0;
+ for (i=0; i<FF_ARRAY_ELEMS(markers); i++) {
+ sum += markers[i];
if (markers[max] < markers[i])
max = i;
+ }
+
if (markers[max] > 3 && p->buf_size / markers[max] < 32*1024 &&
markers[max] * 4 > sum * 3 &&
diff / p->buf_size > 200)
#include "libavutil/intreadwrite.h"
#include "libavutil/log.h"
#include "libavutil/mathematics.h"
+#include "libavutil/opt.h"
#include "libavutil/avstring.h"
#include "libavutil/replaygain.h"
#include "libavutil/stereo3d.h"
{
uint64_t v = lrintf(d * 100);
if (v % 100)
- av_log(NULL, AV_LOG_INFO, ", %3.2f %s", d, postfix);
+ av_log(NULL, AV_LOG_INFO, "%3.2f %s", d, postfix);
else if (v % (100 * 1000))
- av_log(NULL, AV_LOG_INFO, ", %1.0f %s", d, postfix);
+ av_log(NULL, AV_LOG_INFO, "%1.0f %s", d, postfix);
else
- av_log(NULL, AV_LOG_INFO, ", %1.0fk %s", d / 1000, postfix);
+ av_log(NULL, AV_LOG_INFO, "%1.0fk %s", d / 1000, postfix);
}
static void dump_metadata(void *ctx, AVDictionary *m, const char *indent)
int flags = (is_output ? ic->oformat->flags : ic->iformat->flags);
AVStream *st = ic->streams[i];
AVDictionaryEntry *lang = av_dict_get(st->metadata, "language", NULL, 0);
+ char *separator = ic->dump_separator;
+ char **codec_separator = av_opt_ptr(st->codec->av_class, st->codec, "dump_separator");
+ int use_format_separator = !*codec_separator;
+ if (use_format_separator)
+ *codec_separator = av_strdup(separator);
avcodec_string(buf, sizeof(buf), st->codec, is_output);
+ if (use_format_separator)
+ av_freep(codec_separator);
av_log(NULL, AV_LOG_INFO, " Stream #%d:%d", index, i);
/* the pid is an important information, so we display it */
}
if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
- if (st->avg_frame_rate.den && st->avg_frame_rate.num)
- print_fps(av_q2d(st->avg_frame_rate), "fps");
-#if FF_API_R_FRAME_RATE
- if (st->r_frame_rate.den && st->r_frame_rate.num)
- print_fps(av_q2d(st->r_frame_rate), "tbr");
-#endif
- if (st->time_base.den && st->time_base.num)
- print_fps(1 / av_q2d(st->time_base), "tbn");
- if (st->codec->time_base.den && st->codec->time_base.num)
+ int fps = st->avg_frame_rate.den && st->avg_frame_rate.num;
+ int tbr = st->r_frame_rate.den && st->r_frame_rate.num;
+ int tbn = st->time_base.den && st->time_base.num;
+ int tbc = st->codec->time_base.den && st->codec->time_base.num;
+
+ if (fps || tbr || tbn || tbc)
+ av_log(NULL, AV_LOG_INFO, "%s", separator);
+
+ if (fps)
+ print_fps(av_q2d(st->avg_frame_rate), tbr || tbn || tbc ? "fps, " : "fps");
+ if (tbr)
+ print_fps(av_q2d(st->r_frame_rate), tbn || tbc ? "tbr, " : "tbr");
+ if (tbn)
+ print_fps(1 / av_q2d(st->time_base), tbc ? "tbn, " : "tbn");
+ if (tbc)
print_fps(1 / av_q2d(st->codec->time_base), "tbc");
}
for (i = 0; i < ic->nb_chapters; i++) {
AVChapter *ch = ic->chapters[i];
- av_log(NULL, AV_LOG_INFO, " Chapter #%d.%d: ", index, i);
+ av_log(NULL, AV_LOG_INFO, " Chapter #%d:%d: ", index, i);
av_log(NULL, AV_LOG_INFO,
"start %f, ", ch->start * av_q2d(ch->time_base));
av_log(NULL, AV_LOG_INFO,
return result;
}
-static const uint8_t *dv_extract_pack(uint8_t *frame, enum dv_pack_type t)
+static const uint8_t *dv_extract_pack(const uint8_t *frame, enum dv_pack_type t)
{
int offs;
int c;
* 3. Audio is always returned as 16bit linear samples: 12bit nonlinear samples
* are converted into 16bit linear ones.
*/
-static int dv_extract_audio(uint8_t *frame, uint8_t **ppcm,
+static int dv_extract_audio(const uint8_t *frame, uint8_t **ppcm,
const AVDVProfile *sys)
{
int size, chan, i, j, d, of, smpls, freq, quant, half_ch;
return size;
}
-static int dv_extract_audio_info(DVDemuxContext *c, uint8_t *frame)
+static int dv_extract_audio_info(DVDemuxContext *c, const uint8_t *frame)
{
const uint8_t *as_pack;
int freq, stype, smpls, quant, i, ach;
return (c->sys->audio_min_samples[freq] + smpls) * 4; /* 2ch, 2bytes */
}
-static int dv_extract_video_info(DVDemuxContext *c, uint8_t *frame)
+static int dv_extract_video_info(DVDemuxContext *c, const uint8_t *frame)
{
const uint8_t *vsc_pack;
AVCodecContext *avctx;
return size;
}
-static int dv_extract_timecode(DVDemuxContext* c, uint8_t* frame, char *tc)
+static int dv_extract_timecode(DVDemuxContext* c, const uint8_t* frame, char *tc)
{
const uint8_t *tc_pack;
#include "libavutil/intreadwrite.h"
#include "libavutil/intfloat.h"
+#include "libavutil/opt.h"
+#include "libavutil/avassert.h"
+#include "libavutil/avstring.h"
#include "avformat.h"
#include "internal.h"
#include "ffm.h"
return 0;
}
+static int ffm_append_recommended_configuration(AVStream *st, char **conf)
+{
+ int ret;
+ size_t newsize;
+ av_assert0(conf && st);
+ if (!*conf)
+ return 0;
+ if (!st->recommended_encoder_configuration) {
+ st->recommended_encoder_configuration = *conf;
+ *conf = 0;
+ return 0;
+ }
+ newsize = strlen(*conf) + strlen(st->recommended_encoder_configuration) + 2;
+ if ((ret = av_reallocp(&st->recommended_encoder_configuration, newsize)) < 0)
+ return ret;
+ av_strlcat(st->recommended_encoder_configuration, ",", newsize);
+ av_strlcat(st->recommended_encoder_configuration, *conf, newsize);
+ av_freep(conf);
+ return 0;
+}
+
static int ffm2_read_header(AVFormatContext *s)
{
FFMContext *ffm = s->priv_data;
AVIOContext *pb = s->pb;
AVCodecContext *codec;
int ret;
+ int f_main = 0, f_cprv, f_stvi, f_stau;
+ AVCodec *enc;
+ char *buffer;
ffm->packet_size = avio_rb32(pb);
if (ffm->packet_size != FFM_PACKET_SIZE) {
switch(id) {
case MKBETAG('M', 'A', 'I', 'N'):
+ if (f_main++) {
+ ret = AVERROR(EINVAL);
+ goto fail;
+ }
avio_rb32(pb); /* nb_streams */
avio_rb32(pb); /* total bitrate */
break;
case MKBETAG('C', 'O', 'M', 'M'):
+ f_cprv = f_stvi = f_stau = 0;
st = avformat_new_stream(s, NULL);
if (!st) {
ret = AVERROR(ENOMEM);
if (ff_get_extradata(codec, pb, avio_rb32(pb)) < 0)
return AVERROR(ENOMEM);
}
- avio_seek(pb, next, SEEK_SET);
- id = avio_rb32(pb);
- size = avio_rb32(pb);
- next = avio_tell(pb) + size;
- switch(id) {
- case MKBETAG('S', 'T', 'V', 'I'):
- codec->time_base.num = avio_rb32(pb);
- codec->time_base.den = avio_rb32(pb);
- codec->width = avio_rb16(pb);
- codec->height = avio_rb16(pb);
- codec->gop_size = avio_rb16(pb);
- codec->pix_fmt = avio_rb32(pb);
- codec->qmin = avio_r8(pb);
- codec->qmax = avio_r8(pb);
- codec->max_qdiff = avio_r8(pb);
- codec->qcompress = avio_rb16(pb) / 10000.0;
- codec->qblur = avio_rb16(pb) / 10000.0;
- codec->bit_rate_tolerance = avio_rb32(pb);
- avio_get_str(pb, INT_MAX, rc_eq_buf, sizeof(rc_eq_buf));
- codec->rc_eq = av_strdup(rc_eq_buf);
- codec->rc_max_rate = avio_rb32(pb);
- codec->rc_min_rate = avio_rb32(pb);
- codec->rc_buffer_size = avio_rb32(pb);
- codec->i_quant_factor = av_int2double(avio_rb64(pb));
- codec->b_quant_factor = av_int2double(avio_rb64(pb));
- codec->i_quant_offset = av_int2double(avio_rb64(pb));
- codec->b_quant_offset = av_int2double(avio_rb64(pb));
- codec->dct_algo = avio_rb32(pb);
- codec->strict_std_compliance = avio_rb32(pb);
- codec->max_b_frames = avio_rb32(pb);
- codec->mpeg_quant = avio_rb32(pb);
- codec->intra_dc_precision = avio_rb32(pb);
- codec->me_method = avio_rb32(pb);
- codec->mb_decision = avio_rb32(pb);
- codec->nsse_weight = avio_rb32(pb);
- codec->frame_skip_cmp = avio_rb32(pb);
- codec->rc_buffer_aggressivity = av_int2double(avio_rb64(pb));
- codec->codec_tag = avio_rb32(pb);
- codec->thread_count = avio_r8(pb);
- codec->coder_type = avio_rb32(pb);
- codec->me_cmp = avio_rb32(pb);
- codec->me_subpel_quality = avio_rb32(pb);
- codec->me_range = avio_rb32(pb);
- codec->keyint_min = avio_rb32(pb);
- codec->scenechange_threshold = avio_rb32(pb);
- codec->b_frame_strategy = avio_rb32(pb);
- codec->qcompress = av_int2double(avio_rb64(pb));
- codec->qblur = av_int2double(avio_rb64(pb));
- codec->max_qdiff = avio_rb32(pb);
- codec->refs = avio_rb32(pb);
- break;
- case MKBETAG('S', 'T', 'A', 'U'):
- codec->sample_rate = avio_rb32(pb);
- codec->channels = avio_rl16(pb);
- codec->frame_size = avio_rl16(pb);
- break;
+ break;
+ case MKBETAG('S', 'T', 'V', 'I'):
+ if (f_stvi++) {
+ ret = AVERROR(EINVAL);
+ goto fail;
+ }
+ codec->time_base.num = avio_rb32(pb);
+ codec->time_base.den = avio_rb32(pb);
+ codec->width = avio_rb16(pb);
+ codec->height = avio_rb16(pb);
+ codec->gop_size = avio_rb16(pb);
+ codec->pix_fmt = avio_rb32(pb);
+ codec->qmin = avio_r8(pb);
+ codec->qmax = avio_r8(pb);
+ codec->max_qdiff = avio_r8(pb);
+ codec->qcompress = avio_rb16(pb) / 10000.0;
+ codec->qblur = avio_rb16(pb) / 10000.0;
+ codec->bit_rate_tolerance = avio_rb32(pb);
+ avio_get_str(pb, INT_MAX, rc_eq_buf, sizeof(rc_eq_buf));
+ codec->rc_eq = av_strdup(rc_eq_buf);
+ codec->rc_max_rate = avio_rb32(pb);
+ codec->rc_min_rate = avio_rb32(pb);
+ codec->rc_buffer_size = avio_rb32(pb);
+ codec->i_quant_factor = av_int2double(avio_rb64(pb));
+ codec->b_quant_factor = av_int2double(avio_rb64(pb));
+ codec->i_quant_offset = av_int2double(avio_rb64(pb));
+ codec->b_quant_offset = av_int2double(avio_rb64(pb));
+ codec->dct_algo = avio_rb32(pb);
+ codec->strict_std_compliance = avio_rb32(pb);
+ codec->max_b_frames = avio_rb32(pb);
+ codec->mpeg_quant = avio_rb32(pb);
+ codec->intra_dc_precision = avio_rb32(pb);
+ codec->me_method = avio_rb32(pb);
+ codec->mb_decision = avio_rb32(pb);
+ codec->nsse_weight = avio_rb32(pb);
+ codec->frame_skip_cmp = avio_rb32(pb);
+ codec->rc_buffer_aggressivity = av_int2double(avio_rb64(pb));
+ codec->codec_tag = avio_rb32(pb);
+ codec->thread_count = avio_r8(pb);
+ codec->coder_type = avio_rb32(pb);
+ codec->me_cmp = avio_rb32(pb);
+ codec->me_subpel_quality = avio_rb32(pb);
+ codec->me_range = avio_rb32(pb);
+ codec->keyint_min = avio_rb32(pb);
+ codec->scenechange_threshold = avio_rb32(pb);
+ codec->b_frame_strategy = avio_rb32(pb);
+ codec->qcompress = av_int2double(avio_rb64(pb));
+ codec->qblur = av_int2double(avio_rb64(pb));
+ codec->max_qdiff = avio_rb32(pb);
+ codec->refs = avio_rb32(pb);
+ break;
+ case MKBETAG('S', 'T', 'A', 'U'):
+ if (f_stau++) {
+ ret = AVERROR(EINVAL);
+ goto fail;
+ }
+ codec->sample_rate = avio_rb32(pb);
+ codec->channels = avio_rl16(pb);
+ codec->frame_size = avio_rl16(pb);
+ break;
+ case MKBETAG('C', 'P', 'R', 'V'):
+ if (f_cprv++) {
+ ret = AVERROR(EINVAL);
+ goto fail;
+ }
+ enc = avcodec_find_encoder(codec->codec_id);
+ if (enc && enc->priv_data_size && enc->priv_class) {
+ buffer = av_malloc(size + 1);
+ if (!buffer) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+ avio_get_str(pb, size, buffer, size + 1);
+ if ((ret = ffm_append_recommended_configuration(st, &buffer)) < 0)
+ goto fail;
+ }
+ break;
+ case MKBETAG('S', '2', 'V', 'I'):
+ if (f_stvi++) {
+ ret = AVERROR(EINVAL);
+ goto fail;
+ }
+ buffer = av_malloc(size);
+ if (!buffer) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+ avio_get_str(pb, INT_MAX, buffer, size);
+ av_set_options_string(codec, buffer, "=", ",");
+ if ((ret = ffm_append_recommended_configuration(st, &buffer)) < 0)
+ goto fail;
+ break;
+ case MKBETAG('S', '2', 'A', 'U'):
+ if (f_stau++) {
+ ret = AVERROR(EINVAL);
+ goto fail;
+ }
+ buffer = av_malloc(size);
+ if (!buffer) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
}
+ avio_get_str(pb, INT_MAX, buffer, size);
+ av_set_options_string(codec, buffer, "=", ",");
+ ffm_append_recommended_configuration(st, &buffer);
break;
}
avio_seek(pb, next, SEEK_SET);
#include "libavutil/intfloat.h"
#include "libavutil/avassert.h"
#include "libavutil/parseutils.h"
+#include "libavutil/opt.h"
#include "avformat.h"
#include "internal.h"
#include "ffm.h"
av_free(dyn_buf);
}
+static int ffm_write_header_codec_private_ctx(AVIOContext *pb, AVCodecContext *ctx, int type)
+{
+ AVIOContext *tmp;
+ char *buf = NULL;
+ int ret;
+ const AVCodec *enc = ctx->codec ? ctx->codec : avcodec_find_encoder(ctx->codec_id);
+
+ if (!enc)
+ return AVERROR(EINVAL);
+ if (ctx->priv_data && enc->priv_class && enc->priv_data_size) {
+ if ((ret = av_opt_serialize(ctx->priv_data, AV_OPT_FLAG_ENCODING_PARAM | type,
+ AV_OPT_SERIALIZE_SKIP_DEFAULTS, &buf, '=', ',')) < 0)
+ return ret;
+ if (buf && strlen(buf)) {
+ if (avio_open_dyn_buf(&tmp) < 0) {
+ av_free(buf);
+ return AVERROR(ENOMEM);
+ }
+ avio_put_str(tmp, buf);
+ write_header_chunk(pb, tmp, MKBETAG('C', 'P', 'R', 'V'));
+ }
+ av_free(buf);
+ }
+ return 0;
+}
+
+static int ffm_write_header_codec_ctx(AVIOContext *pb, AVCodecContext *ctx, unsigned tag, int type)
+{
+ AVIOContext *tmp;
+ char *buf = NULL;
+ uint8_t *p = NULL;
+ int ret, need_coma = 0;
+
+#define SKIP_DEFAULTS AV_OPT_SERIALIZE_SKIP_DEFAULTS
+#define OPT_FLAGS_EXACT AV_OPT_SERIALIZE_OPT_FLAGS_EXACT
+#define ENC AV_OPT_FLAG_ENCODING_PARAM
+
+ if (avio_open_dyn_buf(&tmp) < 0)
+ return AVERROR(ENOMEM);
+ if ((ret = av_opt_serialize(ctx, ENC | type, SKIP_DEFAULTS, &buf, '=', ',')) < 0)
+ goto fail;
+ if (buf && strlen(buf)) {
+ avio_write(tmp, buf, strlen(buf));
+ av_free(buf);
+ need_coma = 1;
+ }
+ if ((ret = av_opt_serialize(ctx, 0, SKIP_DEFAULTS | OPT_FLAGS_EXACT, &buf, '=', ',')) < 0)
+ goto fail;
+ if (buf && strlen(buf)) {
+ if (need_coma)
+ avio_w8(tmp, ',');
+ avio_write(tmp, buf, strlen(buf));
+ av_free(buf);
+ }
+ avio_w8(tmp, 0);
+ write_header_chunk(pb, tmp, tag);
+ return 0;
+ fail:
+ av_free(buf);
+ avio_close_dyn_buf(tmp, &p);
+ av_free(p);
+ return ret;
+
+#undef SKIP_DEFAULTS
+#undef OPT_FLAGS_EXACT
+#undef ENC
+}
+
+static int ffm_write_recommended_config(AVIOContext *pb, AVCodecContext *ctx, unsigned tag,
+ const char *configuration)
+{
+ int ret;
+ const AVCodec *enc = ctx->codec ? ctx->codec : avcodec_find_encoder(ctx->codec_id);
+ AVIOContext *tmp;
+ AVDictionaryEntry *t = NULL;
+ AVDictionary *all = NULL, *comm = NULL, *prv = NULL;
+ char *buf = NULL;
+
+ if (!enc || !enc->priv_class || !enc->priv_data_size) {
+ /* codec is not known/has no private options, so save everything as common options */
+ if (avio_open_dyn_buf(&tmp) < 0)
+ return AVERROR(ENOMEM);
+ avio_put_str(tmp, configuration);
+ write_header_chunk(pb, tmp, tag);
+ return 0;
+ }
+
+ if ((ret = av_dict_parse_string(&all, configuration, "=", ",", 0)) < 0)
+ return ret;
+
+ while ((t = av_dict_get(all, "", t, AV_DICT_IGNORE_SUFFIX))) {
+ if (av_opt_find((void *)&enc->priv_class, t->key, NULL, 0, AV_OPT_SEARCH_FAKE_OBJ)) {
+ if ((ret = av_dict_set(&prv, t->key, t->value, 0)) < 0)
+ goto fail;
+ } else if ((ret = av_dict_set(&comm, t->key, t->value, 0)) < 0)
+ goto fail;
+ }
+
+ if (comm) {
+ if ((ret = av_dict_get_string(comm, &buf, '=', ',')) < 0 ||
+ (ret = avio_open_dyn_buf(&tmp)) < 0)
+ goto fail;
+ avio_put_str(tmp, buf);
+ av_freep(&buf);
+ write_header_chunk(pb, tmp, tag);
+ }
+ if (prv) {
+ if ((ret = av_dict_get_string(prv, &buf, '=', ',')) < 0 ||
+ (ret = avio_open_dyn_buf(&tmp)) < 0)
+ goto fail;
+ avio_put_str(tmp, buf);
+ write_header_chunk(pb, tmp, MKBETAG('C', 'P', 'R', 'V'));
+ }
+
+ fail:
+ av_free(buf);
+ av_dict_free(&all);
+ av_dict_free(&comm);
+ av_dict_free(&prv);
+ return ret;
+}
+
static int ffm_write_header(AVFormatContext *s)
{
FFMContext *ffm = s->priv_data;
AVStream *st;
AVIOContext *pb = s->pb;
AVCodecContext *codec;
- int bit_rate, i;
+ int bit_rate, i, ret;
if (t = av_dict_get(s->metadata, "creation_time", NULL, 0)) {
- int ret = av_parse_time(&ffm->start_time, t->value, 0);
+ ret = av_parse_time(&ffm->start_time, t->value, 0);
if (ret < 0)
return ret;
}
avio_write(pb, codec->extradata, codec->extradata_size);
}
write_header_chunk(s->pb, pb, MKBETAG('C', 'O', 'M', 'M'));
- if(avio_open_dyn_buf(&pb) < 0)
- return AVERROR(ENOMEM);
/* specific info */
switch(codec->codec_type) {
case AVMEDIA_TYPE_VIDEO:
- avio_wb32(pb, codec->time_base.num);
- avio_wb32(pb, codec->time_base.den);
- avio_wb16(pb, codec->width);
- avio_wb16(pb, codec->height);
- avio_wb16(pb, codec->gop_size);
- avio_wb32(pb, codec->pix_fmt);
- avio_w8(pb, codec->qmin);
- avio_w8(pb, codec->qmax);
- avio_w8(pb, codec->max_qdiff);
- avio_wb16(pb, (int) (codec->qcompress * 10000.0));
- avio_wb16(pb, (int) (codec->qblur * 10000.0));
- avio_wb32(pb, codec->bit_rate_tolerance);
- avio_put_str(pb, codec->rc_eq ? codec->rc_eq : "tex^qComp");
- avio_wb32(pb, codec->rc_max_rate);
- avio_wb32(pb, codec->rc_min_rate);
- avio_wb32(pb, codec->rc_buffer_size);
- avio_wb64(pb, av_double2int(codec->i_quant_factor));
- avio_wb64(pb, av_double2int(codec->b_quant_factor));
- avio_wb64(pb, av_double2int(codec->i_quant_offset));
- avio_wb64(pb, av_double2int(codec->b_quant_offset));
- avio_wb32(pb, codec->dct_algo);
- avio_wb32(pb, codec->strict_std_compliance);
- avio_wb32(pb, codec->max_b_frames);
- avio_wb32(pb, codec->mpeg_quant);
- avio_wb32(pb, codec->intra_dc_precision);
- avio_wb32(pb, codec->me_method);
- avio_wb32(pb, codec->mb_decision);
- avio_wb32(pb, codec->nsse_weight);
- avio_wb32(pb, codec->frame_skip_cmp);
- avio_wb64(pb, av_double2int(codec->rc_buffer_aggressivity));
- avio_wb32(pb, codec->codec_tag);
- avio_w8(pb, codec->thread_count);
- avio_wb32(pb, codec->coder_type);
- avio_wb32(pb, codec->me_cmp);
- avio_wb32(pb, codec->me_subpel_quality);
- avio_wb32(pb, codec->me_range);
- avio_wb32(pb, codec->keyint_min);
- avio_wb32(pb, codec->scenechange_threshold);
- avio_wb32(pb, codec->b_frame_strategy);
- avio_wb64(pb, av_double2int(codec->qcompress));
- avio_wb64(pb, av_double2int(codec->qblur));
- avio_wb32(pb, codec->max_qdiff);
- avio_wb32(pb, codec->refs);
- write_header_chunk(s->pb, pb, MKBETAG('S', 'T', 'V', 'I'));
+ if (st->recommended_encoder_configuration) {
+ av_log(NULL, AV_LOG_DEBUG, "writing recommended configuration: %s\n",
+ st->recommended_encoder_configuration);
+ if ((ret = ffm_write_recommended_config(s->pb, codec, MKBETAG('S', '2', 'V', 'I'),
+ st->recommended_encoder_configuration)) < 0)
+ return ret;
+ } else if ((ret = ffm_write_header_codec_ctx(s->pb, codec, MKBETAG('S', '2', 'V', 'I'), AV_OPT_FLAG_VIDEO_PARAM)) < 0 ||
+ (ret = ffm_write_header_codec_private_ctx(s->pb, codec, AV_OPT_FLAG_VIDEO_PARAM)) < 0)
+ return ret;
break;
case AVMEDIA_TYPE_AUDIO:
- avio_wb32(pb, codec->sample_rate);
- avio_wl16(pb, codec->channels);
- avio_wl16(pb, codec->frame_size);
- write_header_chunk(s->pb, pb, MKBETAG('S', 'T', 'A', 'U'));
+ if (st->recommended_encoder_configuration) {
+ av_log(NULL, AV_LOG_DEBUG, "writing recommended configuration: %s\n",
+ st->recommended_encoder_configuration);
+ if ((ret = ffm_write_recommended_config(s->pb, codec, MKBETAG('S', '2', 'A', 'U'),
+ st->recommended_encoder_configuration)) < 0)
+ return ret;
+ } else if ((ret = ffm_write_header_codec_ctx(s->pb, codec, MKBETAG('S', '2', 'A', 'U'), AV_OPT_FLAG_AUDIO_PARAM)) < 0 ||
+ (ret = ffm_write_header_codec_private_ctx(s->pb, codec, AV_OPT_FLAG_AUDIO_PARAM)) < 0)
+ return ret;
break;
default:
return -1;
return avpriv_new_chapter(s, s->nb_chapters, tb, start, end, NULL);
}
-static uint8_t *unescape(uint8_t *buf, int size)
+static uint8_t *unescape(const uint8_t *buf, int size)
{
uint8_t *ret = av_malloc(size + 1);
- uint8_t *p1 = ret, *p2 = buf;
+ uint8_t *p1 = ret;
+ const uint8_t *p2 = buf;
if (!ret)
return NULL;
return ret;
}
-static int read_tag(uint8_t *line, AVDictionary **m)
+static int read_tag(const uint8_t *line, AVDictionary **m)
{
- uint8_t *key, *value, *p = line;
+ uint8_t *key, *value;
+ const uint8_t *p = line;
/* find first not escaped '=' */
while (1) {
st->codec->width = avio_rb16(pb);
st->codec->height = avio_rb16(pb);
film->leading = avio_rb16(pb);
+
+ if (st->codec->width * 4LL * st->codec->height >= INT_MAX) {
+ av_log(s, AV_LOG_ERROR, "dimensions too large\n");
+ return AVERROR_PATCHWELCOME;
+ }
+
avpriv_set_pts_info(st, 64, 1, avio_rb16(pb));
avio_seek(pb, 0, SEEK_SET);
if (avio_feof(s->pb))
return AVERROR(EIO);
- pkt->dts = avio_tell(s->pb) / (st->codec->width * (st->codec->height + film->leading) * 4);
+ pkt->dts = avio_tell(s->pb) / (st->codec->width * (int64_t)(st->codec->height + film->leading) * 4);
pkt->size = av_get_packet(s->pb, pkt, st->codec->width * st->codec->height * 4);
- avio_skip(s->pb, st->codec->width * film->leading * 4);
+ avio_skip(s->pb, st->codec->width * (int64_t) film->leading * 4);
if (pkt->size < 0)
return pkt->size;
pkt->flags |= AV_PKT_FLAG_KEY;
uint8_t mimetype[64], *desc = NULL;
AVIOContext *pb = NULL;
AVStream *st;
- int type, width, height;
- int len, ret = 0;
+ int width, height, ret = 0;
+ int len;
+ unsigned int type;
pb = avio_alloc_context(buf, buf_size, 0, NULL, NULL, NULL, NULL);
if (!pb)
/* read the picture type */
type = avio_rb32(pb);
- if (type >= FF_ARRAY_ELEMS(ff_id3v2_picture_types) || type < 0) {
+ if (type >= FF_ARRAY_ELEMS(ff_id3v2_picture_types)) {
av_log(s, AV_LOG_ERROR, "Invalid picture type: %d.\n", type);
if (s->error_recognition & AV_EF_EXPLODE) {
RETURN_ERROR(AVERROR_INVALIDDATA);
/* picture mimetype */
len = avio_rb32(pb);
- if (len <= 0 ||
+ if (len <= 0 || len >= 64 ||
avio_read(pb, mimetype, FFMIN(len, sizeof(mimetype) - 1)) != len) {
av_log(s, AV_LOG_ERROR, "Could not read mimetype from an attached "
"picture.\n");
#include "oggdec.h"
#include "vorbiscomment.h"
#include "replaygain.h"
-#include "libavcodec/bytestream.h"
static int flac_read_header(AVFormatContext *s)
{
}
if (metadata_type == FLAC_METADATA_TYPE_STREAMINFO) {
- FLACStreaminfo si;
+ uint32_t samplerate;
+ uint64_t samples;
+
/* STREAMINFO can only occur once */
if (found_streaminfo) {
RETURN_ERROR(AVERROR_INVALIDDATA);
st->codec->extradata_size = metadata_size;
buffer = NULL;
- /* get codec params from STREAMINFO header */
- avpriv_flac_parse_streaminfo(st->codec, &si, st->codec->extradata);
+ /* get sample rate and sample count from STREAMINFO header;
+ * other parameters will be extracted by the parser */
+ samplerate = AV_RB24(st->codec->extradata + 10) >> 4;
+ samples = (AV_RB64(st->codec->extradata + 13) >> 24) & ((1ULL << 36) - 1);
/* set time base and duration */
- if (si.samplerate > 0) {
- avpriv_set_pts_info(st, 64, 1, si.samplerate);
- if (si.samples > 0)
- st->duration = si.samples;
+ if (samplerate > 0) {
+ avpriv_set_pts_info(st, 64, 1, samplerate);
+ if (samples > 0)
+ st->duration = samples;
}
} else if (metadata_type == FLAC_METADATA_TYPE_CUESHEET) {
uint8_t isrc[13];
padding = 8192;
/* The FLAC specification states that 24 bits are used to represent the
* size of a metadata block so we must clip this value to 2^24-1. */
- padding = av_clip_c(padding, 0, 16777215);
+ padding = av_clip(padding, 0, 16777215);
ret = ff_flac_write_header(s->pb, codec->extradata,
codec->extradata_size, 0);
if (i == s->nb_streams) {
st = create_stream(s, AVMEDIA_TYPE_DATA);
if (!st)
- return AVERROR_INVALIDDATA;
+ return AVERROR(ENOMEM);
st->codec->codec_id = AV_CODEC_ID_TEXT;
}
if (s->pb->seekable && (!s->duration || s->duration == AV_NOPTS_VALUE) && !flv->searched_for_end) {
int size;
const int64_t pos = avio_tell(s->pb);
+ // Read the last 4 bytes of the file, this should be the size of the
+ // previous FLV tag. Use the timestamp of its payload as duration.
int64_t fsize = avio_size(s->pb);
retry_duration:
avio_seek(s->pb, fsize - 4, SEEK_SET);
size = avio_rb32(s->pb);
+ // Seek to the start of the last FLV tag at position (fsize - 4 - size)
+ // but skip the byte indicating the type.
avio_seek(s->pb, fsize - 3 - size, SEEK_SET);
if (size == avio_rb24(s->pb) + 11) {
uint32_t ts = avio_rb24(s->pb);
} else {
AVCodecContext ctx = {0};
ctx.sample_rate = sample_rate;
+ ctx.bits_per_coded_sample = bits_per_coded_sample;
flv_set_audio_codec(s, st, &ctx, flags & FLV_AUDIO_CODECID_MASK);
sample_rate = ctx.sample_rate;
}
int64_t filesize_offset;
int64_t duration;
int64_t delay; ///< first dts delay (needed for AVC & Speex)
+
+ AVCodecContext *audio_enc;
+ AVCodecContext *video_enc;
+ double framerate;
+ AVCodecContext *data_enc;
} FLVContext;
typedef struct FLVStreamContext {
avio_w8(pb, !!b);
}
-static int flv_write_header(AVFormatContext *s)
+static void write_metadata(AVFormatContext *s, unsigned int ts)
{
AVIOContext *pb = s->pb;
FLVContext *flv = s->priv_data;
- AVCodecContext *audio_enc = NULL, *video_enc = NULL, *data_enc = NULL;
- int i, metadata_count = 0;
- double framerate = 0.0;
+ int metadata_count = 0;
int64_t metadata_size_pos, data_size, metadata_count_pos;
AVDictionaryEntry *tag = NULL;
- for (i = 0; i < s->nb_streams; i++) {
- AVCodecContext *enc = s->streams[i]->codec;
- FLVStreamContext *sc;
- switch (enc->codec_type) {
- case AVMEDIA_TYPE_VIDEO:
- if (s->streams[i]->avg_frame_rate.den &&
- s->streams[i]->avg_frame_rate.num) {
- framerate = av_q2d(s->streams[i]->avg_frame_rate);
- }
- if (video_enc) {
- av_log(s, AV_LOG_ERROR,
- "at most one video stream is supported in flv\n");
- return AVERROR(EINVAL);
- }
- video_enc = enc;
- if (enc->codec_tag == 0) {
- av_log(s, AV_LOG_ERROR, "Video codec '%s' for stream %d is not compatible with FLV\n",
- avcodec_get_name(enc->codec_id), i);
- return AVERROR(EINVAL);
- }
- if (enc->codec_id == AV_CODEC_ID_MPEG4 ||
- enc->codec_id == AV_CODEC_ID_H263) {
- int error = enc->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL;
- av_log(s, error ? AV_LOG_ERROR : AV_LOG_WARNING,
- "Codec %s is not supported in the official FLV specification,\n", avcodec_get_name(enc->codec_id));
-
- if (error) {
- av_log(s, AV_LOG_ERROR,
- "use vstrict=-1 / -strict -1 to use it anyway.\n");
- return AVERROR(EINVAL);
- }
- }
- break;
- case AVMEDIA_TYPE_AUDIO:
- if (audio_enc) {
- av_log(s, AV_LOG_ERROR,
- "at most one audio stream is supported in flv\n");
- return AVERROR(EINVAL);
- }
- audio_enc = enc;
- if (get_audio_flags(s, enc) < 0)
- return AVERROR_INVALIDDATA;
- if (enc->codec_id == AV_CODEC_ID_PCM_S16BE)
- av_log(s, AV_LOG_WARNING,
- "16-bit big-endian audio in flv is valid but most likely unplayable (hardware dependent); use s16le\n");
- break;
- case AVMEDIA_TYPE_DATA:
- if (enc->codec_id != AV_CODEC_ID_TEXT) {
- av_log(s, AV_LOG_ERROR, "Data codec '%s' for stream %d is not compatible with FLV\n",
- avcodec_get_name(enc->codec_id), i);
- return AVERROR_INVALIDDATA;
- }
- data_enc = enc;
- break;
- default:
- av_log(s, AV_LOG_ERROR, "Codec type '%s' for stream %d is not compatible with FLV\n",
- av_get_media_type_string(enc->codec_type), i);
- return AVERROR(EINVAL);
- }
- avpriv_set_pts_info(s->streams[i], 32, 1, 1000); /* 32 bit pts in ms */
-
- sc = av_mallocz(sizeof(FLVStreamContext));
- if (!sc)
- return AVERROR(ENOMEM);
- s->streams[i]->priv_data = sc;
- sc->last_ts = -1;
- }
-
- flv->delay = AV_NOPTS_VALUE;
-
- avio_write(pb, "FLV", 3);
- avio_w8(pb, 1);
- avio_w8(pb, FLV_HEADER_FLAG_HASAUDIO * !!audio_enc +
- FLV_HEADER_FLAG_HASVIDEO * !!video_enc);
- avio_wb32(pb, 9);
- avio_wb32(pb, 0);
-
- for (i = 0; i < s->nb_streams; i++)
- if (s->streams[i]->codec->codec_tag == 5) {
- avio_w8(pb, 8); // message type
- avio_wb24(pb, 0); // include flags
- avio_wb24(pb, 0); // time stamp
- avio_wb32(pb, 0); // reserved
- avio_wb32(pb, 11); // size
- flv->reserved = 5;
- }
-
/* write meta_tag */
avio_w8(pb, 18); // tag type META
metadata_size_pos = avio_tell(pb);
avio_wb24(pb, 0); // size of data part (sum of all parts below)
- avio_wb24(pb, 0); // timestamp
+ avio_wb24(pb, ts); // timestamp
avio_wb32(pb, 0); // reserved
/* now data of data_size size */
/* mixed array (hash) with size and string/type/data tuples */
avio_w8(pb, AMF_DATA_TYPE_MIXEDARRAY);
metadata_count_pos = avio_tell(pb);
- metadata_count = 4 * !!video_enc +
- 5 * !!audio_enc +
- 1 * !!data_enc +
+ metadata_count = 4 * !!flv->video_enc +
+ 5 * !!flv->audio_enc +
+ 1 * !!flv->data_enc +
2; // +2 for duration and file size
avio_wb32(pb, metadata_count);
put_amf_string(pb, "duration");
- flv->duration_offset= avio_tell(pb);
+ flv->duration_offset = avio_tell(pb);
// fill in the guessed duration, it'll be corrected later if incorrect
put_amf_double(pb, s->duration / AV_TIME_BASE);
- if (video_enc) {
+ if (flv->video_enc) {
put_amf_string(pb, "width");
- put_amf_double(pb, video_enc->width);
+ put_amf_double(pb, flv->video_enc->width);
put_amf_string(pb, "height");
- put_amf_double(pb, video_enc->height);
+ put_amf_double(pb, flv->video_enc->height);
put_amf_string(pb, "videodatarate");
- put_amf_double(pb, video_enc->bit_rate / 1024.0);
+ put_amf_double(pb, flv->video_enc->bit_rate / 1024.0);
- if (framerate != 0.0) {
+ if (flv->framerate != 0.0) {
put_amf_string(pb, "framerate");
- put_amf_double(pb, framerate);
+ put_amf_double(pb, flv->framerate);
metadata_count++;
}
put_amf_string(pb, "videocodecid");
- put_amf_double(pb, video_enc->codec_tag);
+ put_amf_double(pb, flv->video_enc->codec_tag);
}
- if (audio_enc) {
+ if (flv->audio_enc) {
put_amf_string(pb, "audiodatarate");
- put_amf_double(pb, audio_enc->bit_rate / 1024.0);
+ put_amf_double(pb, flv->audio_enc->bit_rate / 1024.0);
put_amf_string(pb, "audiosamplerate");
- put_amf_double(pb, audio_enc->sample_rate);
+ put_amf_double(pb, flv->audio_enc->sample_rate);
put_amf_string(pb, "audiosamplesize");
- put_amf_double(pb, audio_enc->codec_id == AV_CODEC_ID_PCM_U8 ? 8 : 16);
+ put_amf_double(pb, flv->audio_enc->codec_id == AV_CODEC_ID_PCM_U8 ? 8 : 16);
put_amf_string(pb, "stereo");
- put_amf_bool(pb, audio_enc->channels == 2);
+ put_amf_bool(pb, flv->audio_enc->channels == 2);
put_amf_string(pb, "audiocodecid");
- put_amf_double(pb, audio_enc->codec_tag);
+ put_amf_double(pb, flv->audio_enc->codec_tag);
}
- if (data_enc) {
+ if (flv->data_enc) {
put_amf_string(pb, "datastream");
put_amf_double(pb, 0.0);
}
avio_wb24(pb, data_size);
avio_skip(pb, data_size + 10 - 3);
avio_wb32(pb, data_size + 11);
+}
+
+static int flv_write_header(AVFormatContext *s)
+{
+ int i;
+ AVIOContext *pb = s->pb;
+ FLVContext *flv = s->priv_data;
+ int64_t data_size;
+
+ for (i = 0; i < s->nb_streams; i++) {
+ AVCodecContext *enc = s->streams[i]->codec;
+ FLVStreamContext *sc;
+ switch (enc->codec_type) {
+ case AVMEDIA_TYPE_VIDEO:
+ if (s->streams[i]->avg_frame_rate.den &&
+ s->streams[i]->avg_frame_rate.num) {
+ flv->framerate = av_q2d(s->streams[i]->avg_frame_rate);
+ }
+ if (flv->video_enc) {
+ av_log(s, AV_LOG_ERROR,
+ "at most one video stream is supported in flv\n");
+ return AVERROR(EINVAL);
+ }
+ flv->video_enc = enc;
+ if (enc->codec_tag == 0) {
+ av_log(s, AV_LOG_ERROR, "Video codec '%s' for stream %d is not compatible with FLV\n",
+ avcodec_get_name(enc->codec_id), i);
+ return AVERROR(EINVAL);
+ }
+ if (enc->codec_id == AV_CODEC_ID_MPEG4 ||
+ enc->codec_id == AV_CODEC_ID_H263) {
+ int error = s->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL;
+ av_log(s, error ? AV_LOG_ERROR : AV_LOG_WARNING,
+ "Codec %s is not supported in the official FLV specification,\n", avcodec_get_name(enc->codec_id));
+
+ if (error) {
+ av_log(s, AV_LOG_ERROR,
+ "use vstrict=-1 / -strict -1 to use it anyway.\n");
+ return AVERROR(EINVAL);
+ }
+ } else if (enc->codec_id == AV_CODEC_ID_VP6) {
+ av_log(s, AV_LOG_WARNING,
+ "Muxing VP6 in flv will produce flipped video on playback.\n");
+ }
+ break;
+ case AVMEDIA_TYPE_AUDIO:
+ if (flv->audio_enc) {
+ av_log(s, AV_LOG_ERROR,
+ "at most one audio stream is supported in flv\n");
+ return AVERROR(EINVAL);
+ }
+ flv->audio_enc = enc;
+ if (get_audio_flags(s, enc) < 0)
+ return AVERROR_INVALIDDATA;
+ if (enc->codec_id == AV_CODEC_ID_PCM_S16BE)
+ av_log(s, AV_LOG_WARNING,
+ "16-bit big-endian audio in flv is valid but most likely unplayable (hardware dependent); use s16le\n");
+ break;
+ case AVMEDIA_TYPE_DATA:
+ if (enc->codec_id != AV_CODEC_ID_TEXT && enc->codec_id != AV_CODEC_ID_NONE) {
+ av_log(s, AV_LOG_ERROR, "Data codec '%s' for stream %d is not compatible with FLV\n",
+ avcodec_get_name(enc->codec_id), i);
+ return AVERROR_INVALIDDATA;
+ }
+ flv->data_enc = enc;
+ break;
+ default:
+ av_log(s, AV_LOG_ERROR, "Codec type '%s' for stream %d is not compatible with FLV\n",
+ av_get_media_type_string(enc->codec_type), i);
+ return AVERROR(EINVAL);
+ }
+ avpriv_set_pts_info(s->streams[i], 32, 1, 1000); /* 32 bit pts in ms */
+
+ sc = av_mallocz(sizeof(FLVStreamContext));
+ if (!sc)
+ return AVERROR(ENOMEM);
+ s->streams[i]->priv_data = sc;
+ sc->last_ts = -1;
+ }
+
+ flv->delay = AV_NOPTS_VALUE;
+
+ avio_write(pb, "FLV", 3);
+ avio_w8(pb, 1);
+ avio_w8(pb, FLV_HEADER_FLAG_HASAUDIO * !!flv->audio_enc +
+ FLV_HEADER_FLAG_HASVIDEO * !!flv->video_enc);
+ avio_wb32(pb, 9);
+ avio_wb32(pb, 0);
+
+ for (i = 0; i < s->nb_streams; i++)
+ if (s->streams[i]->codec->codec_tag == 5) {
+ avio_w8(pb, 8); // message type
+ avio_wb24(pb, 0); // include flags
+ avio_wb24(pb, 0); // time stamp
+ avio_wb32(pb, 0); // reserved
+ avio_wb32(pb, 11); // size
+ flv->reserved = 5;
+ }
+
+ write_metadata(s, 0);
for (i = 0; i < s->nb_streams; i++) {
AVCodecContext *enc = s->streams[i]->codec;
else
flags_size = 1;
+ if (flv->delay == AV_NOPTS_VALUE)
+ flv->delay = -pkt->dts;
+
+ if (pkt->dts < -flv->delay) {
+ av_log(s, AV_LOG_WARNING,
+ "Packets are not in the proper order with respect to DTS\n");
+ return AVERROR(EINVAL);
+ }
+
+ ts = pkt->dts + flv->delay; // add delay to force positive dts
+
+ if (s->event_flags & AVSTREAM_EVENT_FLAG_METADATA_UPDATED) {
+ write_metadata(s, ts);
+ s->event_flags &= ~AVSTREAM_EVENT_FLAG_METADATA_UPDATED;
+ }
+
switch (enc->codec_type) {
case AVMEDIA_TYPE_VIDEO:
avio_w8(pb, FLV_TAG_TYPE_VIDEO);
av_log(s, AV_LOG_WARNING, "aac bitstream error\n");
}
- if (flv->delay == AV_NOPTS_VALUE)
- flv->delay = -pkt->dts;
-
- if (pkt->dts < -flv->delay) {
- av_log(s, AV_LOG_WARNING,
- "Packets are not in the proper order with respect to DTS\n");
- return AVERROR(EINVAL);
- }
-
- ts = pkt->dts + flv->delay; // add delay to force positive dts
-
/* check Speex packet duration */
if (enc->codec_id == AV_CODEC_ID_SPEEX && ts - sc->last_ts > 160)
av_log(s, AV_LOG_WARNING, "Warning: Speex stream has more than "
if (sc->last_ts < ts)
sc->last_ts = ts;
+ if (size + flags_size >= 1<<24) {
+ av_log(s, AV_LOG_ERROR, "Too large packet with size %u >= %u\n",
+ size + flags_size, 1<<24);
+ return AVERROR(EINVAL);
+ }
+
avio_wb24(pb, size + flags_size);
avio_wb24(pb, ts & 0xFFFFFF);
avio_w8(pb, (ts >> 24) & 0x7F); // timestamps are 32 bits _signed_
if (enc->codec_type == AVMEDIA_TYPE_DATA) {
int data_size;
int64_t metadata_size_pos = avio_tell(pb);
- avio_w8(pb, AMF_DATA_TYPE_STRING);
- put_amf_string(pb, "onTextData");
- avio_w8(pb, AMF_DATA_TYPE_MIXEDARRAY);
- avio_wb32(pb, 2);
- put_amf_string(pb, "type");
- avio_w8(pb, AMF_DATA_TYPE_STRING);
- put_amf_string(pb, "Text");
- put_amf_string(pb, "text");
- avio_w8(pb, AMF_DATA_TYPE_STRING);
- put_amf_string(pb, pkt->data);
- put_amf_string(pb, "");
- avio_w8(pb, AMF_END_OF_OBJECT);
+ if (enc->codec_id == AV_CODEC_ID_TEXT) {
+ // legacy FFmpeg magic?
+ avio_w8(pb, AMF_DATA_TYPE_STRING);
+ put_amf_string(pb, "onTextData");
+ avio_w8(pb, AMF_DATA_TYPE_MIXEDARRAY);
+ avio_wb32(pb, 2);
+ put_amf_string(pb, "type");
+ avio_w8(pb, AMF_DATA_TYPE_STRING);
+ put_amf_string(pb, "Text");
+ put_amf_string(pb, "text");
+ avio_w8(pb, AMF_DATA_TYPE_STRING);
+ put_amf_string(pb, pkt->data);
+ put_amf_string(pb, "");
+ avio_w8(pb, AMF_END_OF_OBJECT);
+ } else {
+ // just pass the metadata through
+ avio_write(pb, data ? data : pkt->data, size);
+ }
/* write total size of tag */
data_size = avio_tell(pb) - metadata_size_pos;
avio_seek(pb, metadata_size_pos - 10, SEEK_SET);
int av_match_ext(const char *filename, const char *extensions)
{
- const char *ext, *p;
- char ext1[32], *q;
+ const char *ext;
if (!filename)
return 0;
ext = strrchr(filename, '.');
- if (ext) {
- ext++;
- p = extensions;
- for (;;) {
- q = ext1;
- while (*p != '\0' && *p != ',' && q - ext1 < sizeof(ext1) - 1)
- *q++ = *p++;
- *q = '\0';
- if (!av_strcasecmp(ext1, ext))
- return 1;
- if (*p == '\0')
- break;
- p++;
- }
- }
+ if (ext)
+ return av_match_name(ext + 1, extensions);
return 0;
}
if (offset >= max_probe_size)
return AVERROR(EINVAL);
- if (pb->av_class)
- av_opt_get(pb, "mime_type", AV_OPT_SEARCH_CHILDREN, &pd.mime_type);
+ if (pb->av_class) {
+ uint8_t *mime_type_opt = NULL;
+ av_opt_get(pb, "mime_type", AV_OPT_SEARCH_CHILDREN, &mime_type_opt);
+ pd.mime_type = (const char *)mime_type_opt;
+ }
#if 0
if (!*fmt && pb->av_class && av_opt_get(pb, "mime_type", AV_OPT_SEARCH_CHILDREN, &mime_type) >= 0 && mime_type) {
if (!av_strcasecmp(mime_type, "audio/aacp")) {
if (ret >= 0)
ret = ret2;
- av_free(pd.mime_type);
+ av_freep(&pd.mime_type);
return ret < 0 ? ret : score;
}
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);
+ av_log(s, AV_LOG_ERROR, "Unable to open %s for writing\n", temp_filename);
return ret;
}
avio_printf(out, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
avio_printf(out, "</manifest>\n");
avio_flush(out);
avio_close(out);
- if (rename(temp_filename, filename) == -1) {
- av_log(s, AV_LOG_ERROR, "failed to rename file %s to %s\n", temp_filename, filename);
- return AVERROR(errno);
- }
- return 0;
+ return ff_rename(temp_filename, filename, s);
}
static void update_size(AVIOContext *out, int64_t pos)
update_size(out, afrt_pos);
update_size(out, 0);
avio_close(out);
- if (rename(temp_filename, filename) == -1) {
- av_log(s, AV_LOG_ERROR, "failed to rename file %s to %s\n", temp_filename, filename);
- return AVERROR(errno);
- }
- return 0;
+ return ff_rename(temp_filename, filename, s);
}
static int init_file(AVFormatContext *s, OutputStream *os, int64_t start_ts)
AVOutputFormat *oformat;
if (mkdir(s->filename, 0777) == -1 && errno != EEXIST) {
- av_log(s, AV_LOG_ERROR , "Failed to create directory %s\n", s->filename);
ret = AVERROR(errno);
+ av_log(s, AV_LOG_ERROR , "Failed to create directory %s\n", s->filename);
goto fail;
}
goto fail;
}
avcodec_copy_context(st->codec, s->streams[i]->codec);
+ st->codec->codec_tag = 0;
st->sample_aspect_ratio = s->streams[i]->sample_aspect_ratio;
+ st->time_base = s->streams[i]->time_base;
}
if (c->streams[c->nb_streams].ctx)
c->nb_streams++;
snprintf(target_filename, sizeof(target_filename),
"%s/stream%dSeg1-Frag%d", s->filename, index, os->fragment_index);
- if (rename(os->temp_filename, target_filename) == -1) {
- av_log(s, AV_LOG_ERROR, "failed to rename file %s to %s\n", os->temp_filename, target_filename);
- return AVERROR(errno);
- }
+ ret = ff_rename(os->temp_filename, target_filename, s);
+ if (ret < 0)
+ return ret;
add_fragment(os, target_filename, os->frag_start_ts, end_ts - os->frag_start_ts);
if (!final) {
{
int i;
for (i = 0; i < pls->n_segments; i++) {
- av_free(pls->segments[i]->key);
- av_free(pls->segments[i]->url);
- av_free(pls->segments[i]);
+ av_freep(&pls->segments[i]->key);
+ av_freep(&pls->segments[i]->url);
+ av_freep(&pls->segments[i]);
}
av_freep(&pls->segments);
pls->n_segments = 0;
av_dict_free(&pls->id3_initial);
ff_id3v2_free_extra_meta(&pls->id3_deferred_extra);
av_free_packet(&pls->pkt);
- av_free(pls->pb.buffer);
+ av_freep(&pls->pb.buffer);
if (pls->input)
ffurl_close(pls->input);
if (pls->ctx) {
{
int i;
for (i = 0; i < c->n_renditions; i++)
- av_free(c->renditions[i]);
+ av_freep(&c->renditions[i]);
av_freep(&c->renditions);
c->n_renditions = 0;
}
}
}
if (pls)
- pls->last_load_time = av_gettime();
+ pls->last_load_time = av_gettime_relative();
fail:
av_free(new_url);
reload:
if (!v->finished &&
- av_gettime() - v->last_load_time >= reload_interval) {
+ av_gettime_relative() - v->last_load_time >= reload_interval) {
if ((ret = parse_playlist(c, v->url, v, NULL)) < 0) {
av_log(v->parent, AV_LOG_WARNING, "Failed to reload playlist %d\n",
v->index);
if (v->cur_seq_no >= v->start_seq_no + v->n_segments) {
if (v->finished)
return AVERROR_EOF;
- while (av_gettime() - v->last_load_time < reload_interval) {
+ while (av_gettime_relative() - v->last_load_time < reload_interval) {
if (ff_check_interrupt(c->interrupt_callback))
return AVERROR_EXIT;
av_usleep(100*1000);
int seq_no;
if (!pls->finished && !c->first_packet &&
- av_gettime() - pls->last_load_time >= default_reload_interval(pls))
+ av_gettime_relative() - pls->last_load_time >= default_reload_interval(pls))
/* reload the playlist since it was suspended */
parse_playlist(c, pls->url, pls, NULL);
}
pls->ctx->pb = &pls->pb;
pls->stream_offset = stream_offset;
+
+ if ((ret = ff_copy_whitelists(pls->ctx, s)) < 0)
+ goto fail;
+
ret = avformat_open_input(&pls->ctx, pls->segments[0]->url, in_fmt, NULL);
if (ret < 0)
goto fail;
typedef struct HLSSegment {
char filename[1024];
double duration; /* in seconds */
+ int64_t pos;
+ int64_t size;
struct HLSSegment *next;
} HLSSegment;
+typedef enum HLSFlags {
+ // Generate a single media file and use byte ranges in the playlist.
+ HLS_SINGLE_FILE = (1 << 0),
+} HLSFlags;
+
typedef struct HLSContext {
const AVClass *class; // Class for private options.
unsigned number;
float time; // Set by a private option.
int max_nb_segments; // Set by a private option.
int wrap; // Set by a private option.
+ uint32_t flags; // enum HLSFlags
+ int allowcache;
int64_t recording_time;
int has_video;
int64_t start_pts;
int64_t end_pts;
double duration; // last segment duration computed so far, in seconds
+ int64_t start_pos; // last segment starting position
+ int64_t size; // last segment size
int nb_entries;
HLSSegment *segments;
char *basename;
char *baseurl;
+ char *format_options_str;
+ AVDictionary *format_options;
AVIOContext *pb;
} HLSContext;
{
HLSContext *hls = s->priv_data;
AVFormatContext *oc;
- int i;
+ int i, ret;
- hls->avf = oc = avformat_alloc_context();
- if (!oc)
- return AVERROR(ENOMEM);
+ ret = avformat_alloc_output_context2(&hls->avf, hls->oformat, NULL, NULL);
+ if (ret < 0)
+ return ret;
+ oc = hls->avf;
oc->oformat = hls->oformat;
oc->interrupt_callback = s->interrupt_callback;
+ oc->max_delay = s->max_delay;
av_dict_copy(&oc->metadata, s->metadata, 0);
for (i = 0; i < s->nb_streams; i++) {
return AVERROR(ENOMEM);
avcodec_copy_context(st->codec, s->streams[i]->codec);
st->sample_aspect_ratio = s->streams[i]->sample_aspect_ratio;
+ st->time_base = s->streams[i]->time_base;
}
+ hls->start_pos = 0;
return 0;
}
/* Create a new segment and append it to the segment list */
-static int hls_append_segment(HLSContext *hls, double duration)
+static int hls_append_segment(HLSContext *hls, double duration, int64_t pos,
+ int64_t size)
{
HLSSegment *en = av_malloc(sizeof(*en));
av_strlcpy(en->filename, av_basename(hls->avf->filename), sizeof(en->filename));
en->duration = duration;
+ en->pos = pos;
+ en->size = size;
en->next = NULL;
if (!hls->segments)
int target_duration = 0;
int ret = 0;
int64_t sequence = FFMAX(hls->start_sequence, hls->sequence - hls->nb_entries);
+ int version = hls->flags & HLS_SINGLE_FILE ? 4 : 3;
if ((ret = avio_open2(&hls->pb, s->filename, AVIO_FLAG_WRITE,
&s->interrupt_callback, NULL)) < 0)
}
avio_printf(hls->pb, "#EXTM3U\n");
- avio_printf(hls->pb, "#EXT-X-VERSION:3\n");
+ avio_printf(hls->pb, "#EXT-X-VERSION:%d\n", version);
+ if (hls->allowcache == 0 || hls->allowcache == 1) {
+ avio_printf(hls->pb, "#EXT-X-ALLOW-CACHE:%s\n", hls->allowcache == 0 ? "NO" : "YES");
+ }
avio_printf(hls->pb, "#EXT-X-TARGETDURATION:%d\n", target_duration);
avio_printf(hls->pb, "#EXT-X-MEDIA-SEQUENCE:%"PRId64"\n", sequence);
for (en = hls->segments; en; en = en->next) {
avio_printf(hls->pb, "#EXTINF:%f,\n", en->duration);
+ if (hls->flags & HLS_SINGLE_FILE)
+ avio_printf(hls->pb, "#EXT-X-BYTERANGE:%"PRIi64"@%"PRIi64"\n",
+ en->size, en->pos);
if (hls->baseurl)
avio_printf(hls->pb, "%s", hls->baseurl);
avio_printf(hls->pb, "%s\n", en->filename);
AVFormatContext *oc = c->avf;
int err = 0;
- if (av_get_frame_filename(oc->filename, sizeof(oc->filename),
- c->basename, c->wrap ? c->sequence % c->wrap : c->sequence) < 0) {
- av_log(oc, AV_LOG_ERROR, "Invalid segment filename template '%s'\n", c->basename);
- return AVERROR(EINVAL);
- }
+ if (c->flags & HLS_SINGLE_FILE)
+ av_strlcpy(oc->filename, c->basename,
+ sizeof(oc->filename));
+ else
+ if (av_get_frame_filename(oc->filename, sizeof(oc->filename),
+ c->basename, c->wrap ? c->sequence % c->wrap : c->sequence) < 0) {
+ av_log(oc, AV_LOG_ERROR, "Invalid segment filename template '%s'\n", c->basename);
+ return AVERROR(EINVAL);
+ }
c->number++;
if ((err = avio_open2(&oc->pb, oc->filename, AVIO_FLAG_WRITE,
int ret, i;
char *p;
const char *pattern = "%d.ts";
+ AVDictionary *options = NULL;
int basename_size = strlen(s->filename) + strlen(pattern) + 1;
hls->sequence = hls->start_sequence;
hls->recording_time = hls->time * AV_TIME_BASE;
hls->start_pts = AV_NOPTS_VALUE;
+ if (hls->flags & HLS_SINGLE_FILE)
+ pattern = ".ts";
+
+ if (hls->format_options_str) {
+ ret = av_dict_parse_string(&hls->format_options, hls->format_options_str, "=", ":", 0);
+ if (ret < 0) {
+ av_log(s, AV_LOG_ERROR, "Could not parse format options list '%s'\n", hls->format_options_str);
+ goto fail;
+ }
+ }
+
for (i = 0; i < s->nb_streams; i++)
hls->has_video +=
s->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO;
if ((ret = hls_start(s)) < 0)
goto fail;
- if ((ret = avformat_write_header(hls->avf, NULL)) < 0)
+ av_dict_copy(&options, hls->format_options, 0);
+ ret = avformat_write_header(hls->avf, &options);
+ if (av_dict_count(options)) {
+ av_log(s, AV_LOG_ERROR, "Some of provided format options in '%s' are not recognized\n", hls->format_options_str);
+ ret = AVERROR(EINVAL);
goto fail;
-
+ }
av_assert0(s->nb_streams == hls->avf->nb_streams);
for (i = 0; i < s->nb_streams; i++) {
AVStream *inner_st = hls->avf->streams[i];
- AVStream *outter_st = s->streams[i];
- avpriv_set_pts_info(outter_st, inner_st->pts_wrap_bits, inner_st->time_base.num, inner_st->time_base.den);
+ AVStream *outer_st = s->streams[i];
+ avpriv_set_pts_info(outer_st, inner_st->pts_wrap_bits, inner_st->time_base.num, inner_st->time_base.den);
}
-
fail:
+
+ av_dict_free(&options);
if (ret) {
av_free(hls->basename);
if (hls->avf)
if (can_split && av_compare_ts(pkt->pts - hls->start_pts, st->time_base,
end_pts, AV_TIME_BASE_Q) >= 0) {
- ret = hls_append_segment(hls, hls->duration);
+ int64_t new_start_pos;
+ av_write_frame(oc, NULL); /* Flush any buffered data */
+
+ new_start_pos = avio_tell(hls->avf->pb);
+ hls->size = new_start_pos - hls->start_pos;
+ ret = hls_append_segment(hls, hls->duration, hls->start_pos, hls->size);
+ hls->start_pos = new_start_pos;
if (ret)
return ret;
hls->end_pts = pkt->pts;
hls->duration = 0;
- av_write_frame(oc, NULL); /* Flush any buffered data */
- avio_close(oc->pb);
+ if (hls->flags & HLS_SINGLE_FILE) {
+ if (hls->avf->oformat->priv_class && hls->avf->priv_data)
+ av_opt_set(hls->avf->priv_data, "mpegts_flags", "resend_headers", 0);
+ hls->number++;
+ } else {
+ avio_close(oc->pb);
- ret = hls_start(s);
+ ret = hls_start(s);
+ }
if (ret)
return ret;
AVFormatContext *oc = hls->avf;
av_write_trailer(oc);
+ hls->size = avio_tell(hls->avf->pb) - hls->start_pos;
avio_closep(&oc->pb);
- avformat_free_context(oc);
av_free(hls->basename);
- hls_append_segment(hls, hls->duration);
+ hls_append_segment(hls, hls->duration, hls->start_pos, hls->size);
+ avformat_free_context(oc);
+ hls->avf = NULL;
hls_window(s, 1);
hls_free_segments(hls);
{"start_number", "set first number in the sequence", OFFSET(start_sequence),AV_OPT_TYPE_INT64, {.i64 = 0}, 0, INT64_MAX, E},
{"hls_time", "set segment length in seconds", OFFSET(time), AV_OPT_TYPE_FLOAT, {.dbl = 2}, 0, FLT_MAX, E},
{"hls_list_size", "set maximum number of playlist entries", OFFSET(max_nb_segments), AV_OPT_TYPE_INT, {.i64 = 5}, 0, INT_MAX, E},
+ {"hls_ts_options","set hls mpegts list of options for the container format used for hls", OFFSET(format_options_str), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E},
{"hls_wrap", "set number after which the index wraps", OFFSET(wrap), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, E},
+ {"hls_allow_cache", "explicitly set whether the client MAY (1) or MUST NOT (0) cache media segments", OFFSET(allowcache), AV_OPT_TYPE_INT, {.i64 = -1}, INT_MIN, INT_MAX, E},
{"hls_base_url", "url to prepend to each playlist entry", OFFSET(baseurl), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E},
+ {"hls_flags", "set flags affecting HLS playlist and media file generation", OFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64 = 0 }, 0, UINT_MAX, E, "flags"},
+ {"single_file", "generate a single media file indexed with byte ranges", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_SINGLE_FILE }, 0, UINT_MAX, E, "flags"},
+
{ NULL },
};
}
}
}
- s->last_load_time = av_gettime();
+ s->last_load_time = av_gettime_relative();
fail:
avio_close(in);
s->target_duration;
retry:
if (!s->finished) {
- int64_t now = av_gettime();
+ int64_t now = av_gettime_relative();
if (now - s->last_load_time >= reload_interval) {
if ((ret = parse_playlist(h, s->playlisturl)) < 0)
return ret;
if (s->cur_seq_no - s->start_seq_no >= s->n_segments) {
if (s->finished)
return AVERROR_EOF;
- while (av_gettime() - s->last_load_time < reload_interval) {
+ while (av_gettime_relative() - s->last_load_time < reload_interval) {
if (ff_check_interrupt(&h->interrupt_callback))
return AVERROR_EXIT;
av_usleep(100*1000);
HTTPContext *s = h->priv_data;
int location_changed, attempts = 0, redirects = 0;
redo:
+ av_dict_copy(options, s->chained_options, 0);
+
cur_auth_type = s->auth_state.auth_type;
cur_proxy_auth_type = s->auth_state.auth_type;
fail:
if (s->hd)
ffurl_closep(&s->hd);
- return AVERROR(EIO);
+ if (location_changed < 0)
+ return location_changed;
+ return ff_http_averror(s->http_code, AVERROR(EIO));
}
int ff_http_do_new_request(URLContext *h, const char *uri)
if (!s->location)
return AVERROR(ENOMEM);
- av_dict_copy(&options, s->chained_options, 0);
ret = http_open_cnx(h, &options);
av_dict_free(&options);
return ret;
}
+int ff_http_averror(int status_code, int default_averror)
+{
+ switch (status_code) {
+ case 400: return AVERROR_HTTP_BAD_REQUEST;
+ case 401: return AVERROR_HTTP_UNAUTHORIZED;
+ case 403: return AVERROR_HTTP_FORBIDDEN;
+ case 404: return AVERROR_HTTP_NOT_FOUND;
+ default: break;
+ }
+ if (status_code >= 400 && status_code <= 499)
+ return AVERROR_HTTP_OTHER_4XX;
+ else if (status_code >= 500)
+ return AVERROR_HTTP_SERVER_ERROR;
+ else
+ return default_averror;
+}
+
static int http_open(URLContext *h, const char *uri, int flags,
AVDictionary **options)
{
(http_code != 407 || s->proxy_auth_state.auth_type != HTTP_AUTH_NONE)) {
end += strspn(end, SPACE_CHARS);
av_log(h, AV_LOG_WARNING, "HTTP error %d %s\n", http_code, end);
- return AVERROR(EIO);
+ return ff_http_averror(http_code, AVERROR(EIO));
}
return 0;
}
s->hd = NULL;
/* if it fails, continue on old connection */
- av_dict_copy(&options, s->chained_options, 0);
if ((ret = http_open_cnx(h, &options)) < 0) {
av_dict_free(&options);
memcpy(s->buffer, old_buf, old_buf_size);
if (s->http_code < 400)
return 0;
- ret = AVERROR(EIO);
+ ret = ff_http_averror(s->http_code, AVERROR(EIO));
fail:
http_proxy_close(h);
*/
int ff_http_do_new_request(URLContext *h, const char *uri);
+int ff_http_averror(int status_code, int default_averror);
+
#endif /* AVFORMAT_HTTP_H */
av_dict_set(&opt_dict, "method", s->legacy_icecast ? "SOURCE" : "PUT", 0);
av_dict_set(&opt_dict, "auth_type", "basic", 0);
av_dict_set(&opt_dict, "headers", headers, 0);
+ av_dict_set(&opt_dict, "chunked_post", "0", 0);
+ av_dict_set(&opt_dict, "send_expect_100", s->legacy_icecast ? "0" : "1", 0);
if (NOT_EMPTY(s->content_type))
av_dict_set(&opt_dict, "content_type", s->content_type, 0);
+ else
+ av_dict_set(&opt_dict, "content_type", "audio/mpeg", 0);
if (NOT_EMPTY(s->user_agent))
av_dict_set(&opt_dict, "user_agent", s->user_agent, 0);
const AVMetadataConv ff_id3v2_4_metadata_conv[] = {
{ "TCMP", "compilation" },
- { "TDRL", "date" },
{ "TDRC", "date" },
+ { "TDRL", "date" },
{ "TDEN", "creation_time" },
{ "TSOA", "album-sort" },
{ "TSOP", "artist-sort" },
return v;
}
+static unsigned int size_to_syncsafe(unsigned int size)
+{
+ return (((size) & (0x7f << 0)) >> 0) +
+ (((size) & (0x7f << 8)) >> 1) +
+ (((size) & (0x7f << 16)) >> 2) +
+ (((size) & (0x7f << 24)) >> 3);
+}
+
+/* No real verification, only check that the tag consists of
+ * a combination of capital alpha-numerical characters */
+static int is_tag(const char *buf, unsigned int len)
+{
+ if (!len)
+ return 0;
+
+ while (len--)
+ if ((buf[len] < 'A' ||
+ buf[len] > 'Z') &&
+ (buf[len] < '0' ||
+ buf[len] > '9'))
+ return 0;
+
+ return 1;
+}
+
+/**
+ * Return 1 if the tag of length len at the given offset is valid, 0 if not, -1 on error
+ */
+static int check_tag(AVIOContext *s, int offset, unsigned int len)
+{
+ char tag[4];
+
+ if (len > 4 ||
+ avio_seek(s, offset, SEEK_SET) < 0 ||
+ avio_read(s, tag, len) < len)
+ return -1;
+ else if (!AV_RB32(tag) || is_tag(tag, len))
+ return 1;
+
+ return 0;
+}
+
/**
* Free GEOB type extra metadata.
*/
int tunsync = 0;
int tcomp = 0;
int tencr = 0;
- unsigned long dlen;
+ unsigned long av_unused dlen;
if (isv34) {
if (avio_read(pb, tag, 4) < 4)
tag[4] = 0;
if (version == 3) {
tlen = avio_rb32(pb);
- } else
- tlen = get_size(pb, 4);
+ } else {
+ /* some encoders incorrectly uses v3 sizes instead of syncsafe ones
+ * so check the next tag to see which one to use */
+ tlen = avio_rb32(pb);
+ if (tlen > 0x7f) {
+ if (tlen < len) {
+ int64_t cur = avio_tell(pb);
+
+ if (ffio_ensure_seekback(pb, 2 /* tflags */ + tlen + 4 /* next tag */))
+ break;
+
+ if (check_tag(pb, cur + 2 + size_to_syncsafe(tlen), 4) == 1)
+ tlen = size_to_syncsafe(tlen);
+ else if (check_tag(pb, cur + 2 + tlen, 4) != 1)
+ break;
+ avio_seek(pb, cur, SEEK_SET);
+ } else
+ tlen = size_to_syncsafe(tlen);
+ }
+ }
tflags = avio_rb16(pb);
tunsync = tflags & ID3v2_FLAG_UNSYNCH;
} else {
case MKTAG('C','M','P','R'):
if (size < 4)
return AVERROR_INVALIDDATA;
- st->codec->codec_id = ff_codec_get_id(dsd_codec_tags, avio_rl32(pb));
+ tag = avio_rl32(pb);
+ st->codec->codec_id = ff_codec_get_id(dsd_codec_tags, tag);
+ if (!st->codec->codec_id) {
+ av_log(s, AV_LOG_ERROR, "'%c%c%c%c' compression is not supported\n",
+ tag&0xFF, (tag>>8)&0xFF, (tag>>16)&0xFF, (tag>>24)&0xFF);
+ return AVERROR_PATCHWELCOME;
+ }
break;
case MKTAG('F','S',' ',' '):
{ AV_CODEC_ID_TIFF, "tif" },
{ AV_CODEC_ID_SGI, "sgi" },
{ AV_CODEC_ID_PTX, "ptx" },
- { AV_CODEC_ID_BRENDER_PIX,"pix" },
{ AV_CODEC_ID_PCX, "pcx" },
{ AV_CODEC_ID_SUNRAST, "sun" },
{ AV_CODEC_ID_SUNRAST, "ras" },
VideoDemuxData *s = s1->priv_data;
char filename_bytes[1024];
char *filename = filename_bytes;
- int i;
+ int i, res;
int size[3] = { 0 }, ret[3] = { 0 };
AVIOContext *f[3] = { NULL };
AVCodecContext *codec = s1->streams[0]->codec;
}
}
- if (av_new_packet(pkt, size[0] + size[1] + size[2]) < 0)
- return AVERROR(ENOMEM);
+ res = av_new_packet(pkt, size[0] + size[1] + size[2]);
+ if (res < 0)
+ return res;
pkt->stream_index = 0;
pkt->flags |= AV_PKT_FLAG_KEY;
if (s->ts_from_file) {
return 0;
if (!AV_RN32(b + 6)) {
- return AVPROBE_SCORE_EXTENSION - 1; // lower than extension as bmp pipe has bugs
+ return AVPROBE_SCORE_EXTENSION + 1;
} else {
return AVPROBE_SCORE_EXTENSION / 4;
}
return 0;
}
+static int jpeg_probe(AVProbeData *p)
+{
+ const uint8_t *b = p->buf;
+ int i, state = 0xD8;
+
+ if (AV_RB16(b) != 0xFFD8 ||
+ AV_RB32(b) == 0xFFD8FFF7)
+ return 0;
+
+ b += 2;
+ for (i = 0; i < p->buf_size - 2; i++) {
+ int c;
+ if (b[i] != 0xFF)
+ continue;
+ c = b[i + 1];
+ switch (c) {
+ case 0xD8:
+ return 0;
+ case 0xC0:
+ case 0xC1:
+ case 0xC2:
+ case 0xC3:
+ case 0xC5:
+ case 0xC6:
+ case 0xC7:
+ if (state != 0xD8)
+ return 0;
+ state = 0xC0;
+ break;
+ case 0xDA:
+ if (state != 0xC0)
+ return 0;
+ state = 0xDA;
+ break;
+ case 0xD9:
+ if (state != 0xDA)
+ return 0;
+ state = 0xD9;
+ break;
+ default:
+ if ( (c >= 0x02 && c <= 0xBF)
+ || c == 0xC8)
+ return 0;
+ }
+ }
+
+ if (state == 0xD9)
+ return AVPROBE_SCORE_EXTENSION + 1;
+ return AVPROBE_SCORE_EXTENSION / 8;
+}
+
static int jpegls_probe(AVProbeData *p)
{
const uint8_t *b = p->buf;
IMAGEAUTO_DEMUXER(dpx, AV_CODEC_ID_DPX)
IMAGEAUTO_DEMUXER(exr, AV_CODEC_ID_EXR)
IMAGEAUTO_DEMUXER(j2k, AV_CODEC_ID_JPEG2000)
+IMAGEAUTO_DEMUXER(jpeg, AV_CODEC_ID_MJPEG)
IMAGEAUTO_DEMUXER(jpegls, AV_CODEC_ID_JPEGLS)
IMAGEAUTO_DEMUXER(pictor, AV_CODEC_ID_PICTOR)
IMAGEAUTO_DEMUXER(png, AV_CODEC_ID_PNG)
#include "libavutil/log.h"
#include "libavutil/opt.h"
#include "libavutil/pixdesc.h"
+#include "libavutil/time_internal.h"
#include "avformat.h"
#include "avio_internal.h"
#include "internal.h"
av_strlcpy(filename, img->path, sizeof(filename));
} else if (img->use_strftime) {
time_t now0;
- struct tm *tm;
+ struct tm *tm, tmpbuf;
time(&now0);
- tm = localtime(&now0);
+ tm = localtime_r(&now0, &tmpbuf);
if (!strftime(filename, sizeof(filename), img->path, tm)) {
av_log(s, AV_LOG_ERROR, "Could not get frame filename with strftime\n");
return AVERROR(EINVAL);
.long_name = NULL_IF_CONFIG_SMALL("image2 sequence"),
.extensions = "bmp,dpx,jls,jpeg,jpg,ljpg,pam,pbm,pcx,pgm,pgmyuv,png,"
"ppm,sgi,tga,tif,tiff,jp2,j2c,j2k,xwd,sun,ras,rs,im1,im8,im24,"
- "sunras,webp,xbm,xface,pix,y",
+ "sunras,xbm,xface,pix,y",
.priv_data_size = sizeof(VideoMuxData),
.video_codec = AV_CODEC_ID_MJPEG,
.write_header = write_header,
#include <stdint.h>
#include "avformat.h"
+#include "os_support.h"
#define MAX_URL_SIZE 4096
/**
* Return the frame duration in seconds. Return 0 if not available.
*/
-void ff_compute_frame_duration(int *pnum, int *pden, AVStream *st,
+void ff_compute_frame_duration(AVFormatContext *s, int *pnum, int *pden, AVStream *st,
AVCodecParserContext *pc, AVPacket *pkt);
unsigned int ff_codec_get_tag(const AVCodecTag *tags, enum AVCodecID id);
*/
int ff_generate_avci_extradata(AVStream *st);
+/**
+ * Wrap errno on rename() error.
+ *
+ * @param oldpath source path
+ * @param newpath destination path
+ * @return 0 or AVERROR on failure
+ */
+static inline int ff_rename(const char *oldpath, const char *newpath, void *logctx)
+{
+ int ret = 0;
+ if (rename(oldpath, newpath) == -1) {
+ ret = AVERROR(errno);
+ if (logctx)
+ av_log(logctx, AV_LOG_ERROR, "failed to rename file %s to %s\n", oldpath, newpath);
+ }
+ return ret;
+}
+
/**
* Allocate extradata with additional FF_INPUT_BUFFER_PADDING_SIZE at end
* which is always set to 0.
};
+/**
+ * Copies the whilelists from one context to the other
+ */
+int ff_copy_whitelists(AVFormatContext *dst, AVFormatContext *src);
#endif /* AVFORMAT_INTERNAL_H */
{ AV_CODEC_ID_VC1 , 0xA3 },
{ AV_CODEC_ID_DIRAC , 0xA4 },
{ AV_CODEC_ID_AC3 , 0xA5 },
+ { AV_CODEC_ID_EAC3 , 0xA6 },
{ AV_CODEC_ID_DTS , 0xA9 }, /* mp4ra.org */
{ AV_CODEC_ID_VORBIS , 0xDD }, /* non standard, gpac uses it */
{ AV_CODEC_ID_DVD_SUBTITLE, 0xE0 }, /* non standard, see unsupported-embedded-subs-2.mp4 */
unsigned duration;
unsigned size;
unsigned flags;
+ int64_t time;
} MOVFragment;
typedef struct MOVTrackExt {
unsigned int index;
} MOVSbgp;
+typedef struct MOVFragmentIndexItem {
+ int64_t moof_offset;
+ int64_t time;
+} MOVFragmentIndexItem;
+
+typedef struct MOVFragmentIndex {
+ unsigned track_id;
+ unsigned item_count;
+ unsigned current_item;
+ MOVFragmentIndexItem *items;
+} MOVFragmentIndex;
+
typedef struct MOVStreamContext {
AVIOContext *pb;
int pb_is_copied;
} MOVStreamContext;
typedef struct MOVContext {
- AVClass *avclass;
+ const AVClass *class; ///< class for private options
AVFormatContext *fc;
int time_scale;
int64_t duration; ///< duration of the longest track
int use_absolute_path;
int ignore_editlist;
int64_t next_root_atom; ///< offset of the next root atom
+ int export_all;
int *bitrates; ///< bitrates read before streams creation
int bitrates_count;
int moov_retry;
+ int use_mfra_for;
+ int has_looked_for_mfra;
+ MOVFragmentIndex** fragment_index_data;
+ unsigned fragment_index_count;
} MOVContext;
int ff_mp4_read_descr_len(AVIOContext *pb);
(tag) == MKTAG('a', 'i', '1', '3') || \
(tag) == MKTAG('a', 'i', '1', '5') || \
(tag) == MKTAG('a', 'i', '1', '6') || \
+ (tag) == MKTAG('a', 'i', 'v', 'x') || \
(tag) == MKTAG('A', 'V', 'i', 'n'))
int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries);
void ff_mov_write_chan(AVIOContext *pb, int64_t channel_layout);
+#define FF_MOV_FLAG_MFRA_AUTO -1
+#define FF_MOV_FLAG_MFRA_DTS 1
+#define FF_MOV_FLAG_MFRA_PTS 2
+
#endif /* AVFORMAT_ISOM_H */
/* general/essential directives in the extradata */
ret = avpriv_bprint_to_extradata(st->codec, &header);
if (ret < 0)
- return ret;
+ goto fail;
/* SHIFT and TIMERES affect the whole script so packet timing can only be
* done in a second pass */
ff_subtitles_queue_finalize(&jacosub->q);
return 0;
+fail:
+ jacosub_read_close(s);
+ return ret;
}
static int jacosub_read_packet(AVFormatContext *s, AVPacket *pkt)
#include "libavformat/avformat.h"
#include "libavformat/internal.h"
+#include "libavutil/avassert.h"
#include "libavutil/opt.h"
typedef struct {
if (rc != QUVI_OK)
goto quvi_fail;
+ if ((ret = ff_copy_whitelists(qc->fmtctx, s)) < 0)
+ goto end;
+
ret = avformat_open_input(&qc->fmtctx, media_url, NULL, NULL);
if (ret < 0)
goto end;
}
if (ctx->swfurl) {
av_strlcat(filename, " swfUrl=", len);
- av_strlcat(filename, ctx->pageurl, len);
+ av_strlcat(filename, ctx->swfurl, len);
}
if (ctx->flashver) {
av_strlcat(filename, " flashVer=", len);
libsmbc->ctx = smbc_new_context();
if (!libsmbc->ctx) {
+ int ret = AVERROR(errno);
av_log(h, AV_LOG_ERROR, "Cannot create context: %s.\n", strerror(errno));
- return AVERROR(errno);
+ return ret;
}
if (!smbc_init_context(libsmbc->ctx)) {
+ int ret = AVERROR(errno);
av_log(h, AV_LOG_ERROR, "Cannot initialize context: %s.\n", strerror(errno));
- return AVERROR(errno);
+ return ret;
}
smbc_set_context(libsmbc->ctx);
smbc_setWorkgroup(libsmbc->ctx, libsmbc->workgroup);
if (smbc_init(NULL, 0) < 0) {
+ int ret = AVERROR(errno);
av_log(h, AV_LOG_ERROR, "Initialization failed: %s\n", strerror(errno));
- return AVERROR(errno);
+ return ret;
}
return 0;
}
int bytes_read;
if ((bytes_read = smbc_read(libsmbc->fd, buf, size)) < 0) {
+ int ret = AVERROR(errno);
av_log(h, AV_LOG_ERROR, "Read error: %s\n", strerror(errno));
- return AVERROR(errno);
+ return ret;
}
return bytes_read;
int bytes_written;
if ((bytes_written = smbc_write(libsmbc->fd, buf, size)) < 0) {
+ int ret = AVERROR(errno);
av_log(h, AV_LOG_ERROR, "Write error: %s\n", strerror(errno));
- return AVERROR(errno);
+ return ret;
}
return bytes_written;
*/
#include "libavutil/intreadwrite.h"
+
#include "avformat.h"
#include "internal.h"
#define LMLM4_MAX_PACKET_SIZE 1024 * 1024
-static int lmlm4_probe(AVProbeData * pd) {
+static int lmlm4_probe(AVProbeData *pd)
+{
const unsigned char *buf = pd->buf;
unsigned int frame_type, packet_size;
- frame_type = AV_RB16(buf+2);
- packet_size = AV_RB32(buf+4);
+ frame_type = AV_RB16(buf + 2);
+ packet_size = AV_RB32(buf + 4);
if (!AV_RB16(buf) && frame_type <= LMLM4_MPEG1L2 && packet_size &&
frame_type != LMLM4_INVALID && packet_size <= LMLM4_MAX_PACKET_SIZE) {
-
if (frame_type == LMLM4_MPEG1L2) {
- if ((AV_RB16(buf+8) & 0xfffe) != 0xfffc)
+ if ((AV_RB16(buf + 8) & 0xfffe) != 0xfffc)
return 0;
/* I could calculate the audio framesize and compare with
* packet_size-8, but that seems overkill */
return AVPROBE_SCORE_MAX / 3;
- } else if (AV_RB24(buf+8) == 0x000001) { /* PES Signal */
+ } else if (AV_RB24(buf + 8) == 0x000001) { /* PES Signal */
return AVPROBE_SCORE_MAX / 5;
}
}
return 0;
}
-static int lmlm4_read_header(AVFormatContext *s) {
+static int lmlm4_read_header(AVFormatContext *s)
+{
AVStream *st;
if (!(st = avformat_new_stream(s, NULL)))
return 0;
}
-static int lmlm4_read_packet(AVFormatContext *s, AVPacket *pkt) {
+static int lmlm4_read_packet(AVFormatContext *s, AVPacket *pkt)
+{
AVIOContext *pb = s->pb;
int ret;
unsigned int frame_type, packet_size, padding, frame_size;
avio_skip(pb, padding);
switch (frame_type) {
- case LMLM4_I_FRAME:
- pkt->flags = AV_PKT_FLAG_KEY;
- case LMLM4_P_FRAME:
- case LMLM4_B_FRAME:
- pkt->stream_index = 0;
- break;
- case LMLM4_MPEG1L2:
- pkt->stream_index = 1;
- break;
+ case LMLM4_I_FRAME:
+ pkt->flags = AV_PKT_FLAG_KEY;
+ case LMLM4_P_FRAME:
+ case LMLM4_B_FRAME:
+ pkt->stream_index = 0;
+ break;
+ case LMLM4_MPEG1L2:
+ pkt->stream_index = 1;
+ break;
}
return ret;
* @param[out] header where to copy the ident to
* @return 0 if an ident was found, < 0 on I/O error
*/
-static int sync(AVFormatContext *s, uint8_t *header)
+static int lxf_sync(AVFormatContext *s, uint8_t *header)
{
uint8_t buf[LXF_IDENT_LENGTH];
int ret;
const uint8_t *p = header + LXF_IDENT_LENGTH;
//find and read the ident
- if ((ret = sync(s, header)) < 0)
+ if ((ret = lxf_sync(s, header)) < 0)
return ret;
ret = avio_read(pb, header + LXF_IDENT_LENGTH, 8);
static int mpeg4video_probe(AVProbeData *probe_packet)
{
- uint32_t temp_buffer= -1;
- int VO=0, VOL=0, VOP = 0, VISO = 0, res=0;
+ uint32_t temp_buffer = -1;
+ int VO = 0, VOL = 0, VOP = 0, VISO = 0, res = 0;
int i;
- for(i=0; i<probe_packet->buf_size; i++){
- temp_buffer = (temp_buffer<<8) + probe_packet->buf[i];
+ for (i = 0; i < probe_packet->buf_size; i++) {
+ temp_buffer = (temp_buffer << 8) + probe_packet->buf[i];
if (temp_buffer & 0xfffffe00)
continue;
if (temp_buffer < 2)
continue;
- if (temp_buffer == VOP_START_CODE) VOP++;
- else if (temp_buffer == VISUAL_OBJECT_START_CODE) VISO++;
- else if (temp_buffer >= 0x100 && temp_buffer < 0x120) VO++;
- else if (temp_buffer >= 0x120 && temp_buffer < 0x130) VOL++;
- else if ( !(0x1AF < temp_buffer && temp_buffer < 0x1B7)
- && !(0x1B9 < temp_buffer && temp_buffer < 0x1C4)) res++;
+ if (temp_buffer == VOP_START_CODE)
+ VOP++;
+ else if (temp_buffer == VISUAL_OBJECT_START_CODE)
+ VISO++;
+ else if (temp_buffer >= 0x100 && temp_buffer < 0x120)
+ VO++;
+ else if (temp_buffer >= 0x120 && temp_buffer < 0x130)
+ VOL++;
+ else if (!(0x1AF < temp_buffer && temp_buffer < 0x1B7) &&
+ !(0x1B9 < temp_buffer && temp_buffer < 0x1C4))
+ res++;
}
- if (VOP >= VISO && VOP >= VOL && VO >= VOL && VOL > 0 && res==0)
+ if (VOP >= VISO && VOP >= VOL && VO >= VOL && VOL > 0 && res == 0)
return VOP+VO > 4 ? AVPROBE_SCORE_EXTENSION : AVPROBE_SCORE_EXTENSION/2;
return 0;
}
-FF_DEF_RAWVIDEO_DEMUXER(m4v, "raw MPEG-4 video", mpeg4video_probe, "m4v", AV_CODEC_ID_MPEG4)
+FF_DEF_RAWVIDEO_DEMUXER2(m4v, "raw MPEG-4 video", mpeg4video_probe, "m4v",
+ AV_CODEC_ID_MPEG4, AVFMT_GENERIC_INDEX | AVFMT_TS_DISCONT)
{"S_TEXT/UTF8" , AV_CODEC_ID_SUBRIP},
{"S_TEXT/UTF8" , AV_CODEC_ID_TEXT},
- {"S_TEXT/UTF8" , AV_CODEC_ID_SRT},
{"S_TEXT/ASCII" , AV_CODEC_ID_TEXT},
{"S_TEXT/ASS" , AV_CODEC_ID_ASS},
{"S_TEXT/SSA" , AV_CODEC_ID_ASS},
#include <inttypes.h>
#include <stdio.h>
-#if CONFIG_BZLIB
-#include <bzlib.h>
-#endif
-#if CONFIG_ZLIB
-#include <zlib.h>
-#endif
#include "libavutil/avstring.h"
#include "libavutil/base64.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/lzo.h"
#include "libavutil/mathematics.h"
+#include "libavutil/time_internal.h"
#include "libavcodec/bytestream.h"
#include "libavcodec/flac.h"
#include "riff.h"
#include "rmsipr.h"
+#if CONFIG_BZLIB
+#include <bzlib.h>
+#endif
+#if CONFIG_ZLIB
+#include <zlib.h>
+#endif
+
typedef enum {
EBML_NONE,
EBML_UINT,
char buffer[32];
/* Convert to seconds and adjust by number of seconds between 2001-01-01 and Epoch */
time_t creation_time = date_utc / 1000000000 + 978307200;
- struct tm *ptm = gmtime(&creation_time);
+ struct tm tmpbuf, *ptm = gmtime_r(&creation_time, &tmpbuf);
if (!ptm) return;
- strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", ptm);
- av_dict_set(metadata, "creation_time", buffer, 0);
+ if (strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", ptm))
+ av_dict_set(metadata, "creation_time", buffer, 0);
}
static int matroska_parse_flac(AVFormatContext *s,
}
while (track->audio.pkt_cnt) {
- AVPacket *pkt = NULL;
- if (!(pkt = av_mallocz(sizeof(AVPacket))) || av_new_packet(pkt, a) < 0) {
- av_free(pkt);
+ int ret;
+ AVPacket *pkt = av_mallocz(sizeof(AVPacket));
+ if (!pkt)
return AVERROR(ENOMEM);
+
+ ret = av_new_packet(pkt, a);
+ if (ret < 0) {
+ av_free(pkt);
+ return ret;
}
memcpy(pkt->data,
track->audio.buf + a * (h * w / a - track->audio.pkt_cnt--),
int64_t timestamp, int flags)
{
MatroskaDemuxContext *matroska = s->priv_data;
- MatroskaTrack *tracks = matroska->tracks.elem;
+ MatroskaTrack *tracks = NULL;
AVStream *st = s->streams[stream_index];
int i, index, index_sub, index_min;
goto err;
timestamp = FFMAX(timestamp, st->index_entries[0].timestamp);
- if ((index = av_index_search_timestamp(st, timestamp, flags)) < 0) {
+ if ((index = av_index_search_timestamp(st, timestamp, flags)) < 0 || index == st->nb_index_entries - 1) {
avio_seek(s->pb, st->index_entries[st->nb_index_entries - 1].pos,
SEEK_SET);
matroska->current_id = 0;
- while ((index = av_index_search_timestamp(st, timestamp, flags)) < 0) {
+ while ((index = av_index_search_timestamp(st, timestamp, flags)) < 0 || index == st->nb_index_entries - 1) {
matroska_clear_queue(matroska);
if (matroska_parse_cluster(matroska) < 0)
break;
goto err;
index_min = index;
+ tracks = matroska->tracks.elem;
for (i = 0; i < matroska->tracks.nb_elem; i++) {
tracks[i].audio.pkt_cnt = 0;
tracks[i].audio.sub_packet_cnt = 0;
}
if (desc_end.start_time_ns == -1) {
// The prebuffer is larger than the duration.
- return (matroska->duration * matroska->time_scale >= prebuffered_ns) ? -1 : 0;
- }
-
- // The prebuffer ends in the last Cue. Estimate how much data was
- // prebuffered.
- pre_bytes = desc_end.end_offset - desc_end.start_offset;
- pre_ns = desc_end.end_time_ns - desc_end.start_time_ns;
- pre_sec = pre_ns / nano_seconds_per_second;
- prebuffer_bytes +=
- pre_bytes * ((temp_prebuffer_ns / nano_seconds_per_second) / pre_sec);
-
- prebuffer = prebuffer_ns / nano_seconds_per_second;
-
- // Set this to 0.0 in case our prebuffer buffers the entire video.
- bits_per_second = 0.0;
- do {
- int64_t desc_bytes = desc_end.end_offset - desc_beg.start_offset;
- int64_t desc_ns = desc_end.end_time_ns - desc_beg.start_time_ns;
- double desc_sec = desc_ns / nano_seconds_per_second;
- double calc_bits_per_second = (desc_bytes * 8) / desc_sec;
-
- // Drop the bps by the percentage of bytes buffered.
- double percent = (desc_bytes - prebuffer_bytes) / desc_bytes;
- double mod_bits_per_second = calc_bits_per_second * percent;
-
- if (prebuffer < desc_sec) {
- double search_sec =
- (double)(matroska->duration * matroska->time_scale) / nano_seconds_per_second;
-
- // Add 1 so the bits per second should be a little bit greater than file
- // datarate.
- int64_t bps = (int64_t)(mod_bits_per_second) + 1;
- const double min_buffer = 0.0;
- double buffer = prebuffer;
- double sec_to_download = 0.0;
-
- int rv = buffer_size_after_time_downloaded(prebuffered_ns, search_sec, bps,
- min_buffer, &buffer, &sec_to_download,
- s, cues_start);
- if (rv < 0) {
- return -1;
- } else if (rv == 0) {
- bits_per_second = (double)(bps);
- break;
+ if (matroska->duration * matroska->time_scale >= prebuffered_ns)
+ return -1;
+ bits_per_second = 0.0;
+ } else {
+ // The prebuffer ends in the last Cue. Estimate how much data was
+ // prebuffered.
+ pre_bytes = desc_end.end_offset - desc_end.start_offset;
+ pre_ns = desc_end.end_time_ns - desc_end.start_time_ns;
+ pre_sec = pre_ns / nano_seconds_per_second;
+ prebuffer_bytes +=
+ pre_bytes * ((temp_prebuffer_ns / nano_seconds_per_second) / pre_sec);
+
+ prebuffer = prebuffer_ns / nano_seconds_per_second;
+
+ // Set this to 0.0 in case our prebuffer buffers the entire video.
+ bits_per_second = 0.0;
+ do {
+ int64_t desc_bytes = desc_end.end_offset - desc_beg.start_offset;
+ int64_t desc_ns = desc_end.end_time_ns - desc_beg.start_time_ns;
+ double desc_sec = desc_ns / nano_seconds_per_second;
+ double calc_bits_per_second = (desc_bytes * 8) / desc_sec;
+
+ // Drop the bps by the percentage of bytes buffered.
+ double percent = (desc_bytes - prebuffer_bytes) / desc_bytes;
+ double mod_bits_per_second = calc_bits_per_second * percent;
+
+ if (prebuffer < desc_sec) {
+ double search_sec =
+ (double)(matroska->duration * matroska->time_scale) / nano_seconds_per_second;
+
+ // Add 1 so the bits per second should be a little bit greater than file
+ // datarate.
+ int64_t bps = (int64_t)(mod_bits_per_second) + 1;
+ const double min_buffer = 0.0;
+ double buffer = prebuffer;
+ double sec_to_download = 0.0;
+
+ int rv = buffer_size_after_time_downloaded(prebuffered_ns, search_sec, bps,
+ min_buffer, &buffer, &sec_to_download,
+ s, cues_start);
+ if (rv < 0) {
+ return -1;
+ } else if (rv == 0) {
+ bits_per_second = (double)(bps);
+ break;
+ }
}
- }
- desc_end = get_cue_desc(s, desc_end.end_time_ns, cues_start);
- } while (desc_end.start_time_ns != -1);
+ desc_end = get_cue_desc(s, desc_end.end_time_ns, cues_start);
+ } while (desc_end.start_time_ns != -1);
+ }
if (bandwidth < bits_per_second) bandwidth = bits_per_second;
}
return (int64_t)bandwidth;
before_pos = avio_tell(matroska->ctx->pb);
cues_start = seekhead[i].pos + matroska->segment_start;
if (avio_seek(matroska->ctx->pb, cues_start, SEEK_SET) == cues_start) {
- uint64_t cues_length = 0, cues_id = 0;
- ebml_read_num(matroska, matroska->ctx->pb, 4, &cues_id);
- ebml_read_length(matroska, matroska->ctx->pb, &cues_length);
- cues_end = cues_start + cues_length + 11; // 11 is the offset of Cues ID.
+ // cues_end is computed as cues_start + cues_length + length of the
+ // Cues element ID + EBML length of the Cues element. cues_end is
+ // inclusive and the above sum is reduced by 1.
+ uint64_t cues_length = 0, cues_id = 0, bytes_read = 0;
+ bytes_read += ebml_read_num(matroska, matroska->ctx->pb, 4, &cues_id);
+ bytes_read += ebml_read_length(matroska, matroska->ctx->pb, &cues_length);
+ cues_end = cues_start + cues_length + bytes_read - 1;
}
avio_seek(matroska->ctx->pb, before_pos, SEEK_SET);
if (cues_start == -1 || cues_end == -1) return -1;
// basename of the file
buf = strrchr(s->filename, '/');
- if (!buf) return -1;
- av_dict_set(&s->streams[0]->metadata, FILENAME, ++buf, 0);
+ av_dict_set(&s->streams[0]->metadata, FILENAME, buf ? ++buf : s->filename, 0);
// duration
buf = av_asprintf("%g", matroska->duration);
static int mkv_write_stereo_mode(AVFormatContext *s, AVIOContext *pb,
- AVStream *st, int mode)
+ AVStream *st, int mode, int *h_width, int *h_height)
{
int i;
int ret = 0;
AVDictionaryEntry *tag;
MatroskaVideoStereoModeType format = MATROSKA_VIDEO_STEREOMODE_TYPE_NB;
+ *h_width = 1;
+ *h_height = 1;
// convert metadata into proper side data and add it to the stream
if ((tag = av_dict_get(st->metadata, "stereo_mode", NULL, 0)) ||
(tag = av_dict_get( s->metadata, "stereo_mode", NULL, 0))) {
}
}
+ // iterate to find the stereo3d side data
for (i = 0; i < st->nb_side_data; i++) {
AVPacketSideData sd = st->side_data[i];
if (sd.type == AV_PKT_DATA_STEREO3D) {
format = (stereo->flags & AV_STEREO3D_FLAG_INVERT)
? MATROSKA_VIDEO_STEREOMODE_TYPE_RIGHT_LEFT
: MATROSKA_VIDEO_STEREOMODE_TYPE_LEFT_RIGHT;
+ *h_width = 2;
break;
case AV_STEREO3D_TOPBOTTOM:
format = MATROSKA_VIDEO_STEREOMODE_TYPE_TOP_BOTTOM;
if (stereo->flags & AV_STEREO3D_FLAG_INVERT)
format--;
+ *h_height = 2;
break;
case AV_STEREO3D_CHECKERBOARD:
format = MATROSKA_VIDEO_STEREOMODE_TYPE_CHECKERBOARD_LR;
format = MATROSKA_VIDEO_STEREOMODE_TYPE_ROW_INTERLEAVED_LR;
if (stereo->flags & AV_STEREO3D_FLAG_INVERT)
format--;
+ *h_height = 2;
break;
case AV_STEREO3D_COLUMNS:
format = MATROSKA_VIDEO_STEREOMODE_TYPE_COL_INTERLEAVED_LR;
if (stereo->flags & AV_STEREO3D_FLAG_INVERT)
format--;
+ *h_width = 2;
break;
case AV_STEREO3D_FRAMESEQUENCE:
format = MATROSKA_VIDEO_STEREOMODE_TYPE_BOTH_EYES_BLOCK_LR;
format++;
break;
}
- ret = stereo->type;
-
break;
}
}
if (format == MATROSKA_VIDEO_STEREOMODE_TYPE_NB)
return ret;
+ // if webm, do not write unsupported modes
if ((mode == MODE_WEBM &&
format > MATROSKA_VIDEO_STEREOMODE_TYPE_TOP_BOTTOM &&
format != MATROSKA_VIDEO_STEREOMODE_TYPE_RIGHT_LEFT)
return AVERROR(EINVAL);
}
+ // write StereoMode if format is valid
put_ebml_uint(pb, MATROSKA_ID_VIDEOSTEREOMODE, format);
return ret;
}
}
- if (codec->codec_type == AVMEDIA_TYPE_AUDIO && codec->delay && codec->codec_id == AV_CODEC_ID_OPUS) {
-// mkv->tracks[i].ts_offset = av_rescale_q(codec->delay,
+ if (codec->codec_type == AVMEDIA_TYPE_AUDIO && codec->initial_padding && codec->codec_id == AV_CODEC_ID_OPUS) {
+// mkv->tracks[i].ts_offset = av_rescale_q(codec->initial_padding,
// (AVRational){ 1, codec->sample_rate },
// st->time_base);
put_ebml_uint(pb, MATROSKA_ID_CODECDELAY,
- av_rescale_q(codec->delay, (AVRational){ 1, codec->sample_rate },
+ av_rescale_q(codec->initial_padding,
+ (AVRational){ 1, codec->sample_rate },
(AVRational){ 1, 1000000000 }));
}
if (codec->codec_id == AV_CODEC_ID_OPUS) {
// check both side data and metadata for stereo information,
// write the result to the bitstream if any is found
- ret = mkv_write_stereo_mode(s, pb, st, mkv->mode);
+ ret = mkv_write_stereo_mode(s, pb, st, mkv->mode,
+ &display_width_div,
+ &display_height_div);
if (ret < 0)
return ret;
- switch (ret) {
- case AV_STEREO3D_SIDEBYSIDE:
- case AV_STEREO3D_COLUMNS:
- display_width_div = 2;
- break;
- case AV_STEREO3D_TOPBOTTOM:
- case AV_STEREO3D_LINES:
- display_height_div = 2;
- break;
- }
-
if (((tag = av_dict_get(st->metadata, "alpha_mode", NULL, 0)) && atoi(tag->value)) ||
((tag = av_dict_get( s->metadata, "alpha_mode", NULL, 0)) && atoi(tag->value)) ||
(codec->pix_fmt == AV_PIX_FMT_YUVA420P)) {
put_ebml_uint(pb, MATROSKA_ID_VIDEOALPHAMODE, 1);
}
+ // write DisplayWidth and DisplayHeight, they contain the size of
+ // a single source view and/or the display aspect ratio
if (st->sample_aspect_ratio.num) {
int64_t d_width = av_rescale(codec->width, st->sample_aspect_ratio.num, st->sample_aspect_ratio.den);
if (d_width > INT_MAX) {
uint32_t color_space = av_le2ne32(codec->codec_tag);
put_ebml_binary(pb, MATROSKA_ID_VIDEOCOLORSPACE, &color_space, sizeof(color_space));
}
+
end_ebml_master(pb, subinfo);
break;
}
}
-static int srt_get_duration(uint8_t **buf)
-{
- int i, duration = 0;
-
- for (i = 0; i < 2 && !duration; i++) {
- int s_hour, s_min, s_sec, s_hsec, e_hour, e_min, e_sec, e_hsec;
- if (sscanf(*buf, "%d:%2d:%2d%*1[,.]%3d --> %d:%2d:%2d%*1[,.]%3d",
- &s_hour, &s_min, &s_sec, &s_hsec,
- &e_hour, &e_min, &e_sec, &e_hsec) == 8) {
- s_min += 60 * s_hour;
- e_min += 60 * e_hour;
- s_sec += 60 * s_min;
-
- e_sec += 60 * e_min;
- s_hsec += 1000 * s_sec;
- e_hsec += 1000 * e_sec;
-
- duration = e_hsec - s_hsec;
- }
- *buf += ff_subtitles_next_line(*buf);
- }
- return duration;
-}
-
-static int mkv_write_srt_blocks(AVFormatContext *s, AVIOContext *pb,
- AVPacket *pkt)
-{
- ebml_master blockgroup;
- AVPacket pkt2 = *pkt;
- int64_t duration = srt_get_duration(&pkt2.data);
- pkt2.size -= pkt2.data - pkt->data;
-
- blockgroup = start_ebml_master(pb, MATROSKA_ID_BLOCKGROUP,
- mkv_blockgroup_size(pkt2.size));
- mkv_write_block(s, pb, MATROSKA_ID_BLOCK, &pkt2, 0);
- put_ebml_uint(pb, MATROSKA_ID_BLOCKDURATION, duration);
- end_ebml_master(pb, blockgroup);
-
- return duration;
-}
-
static int mkv_write_vtt_blocks(AVFormatContext *s, AVIOContext *pb, AVPacket *pkt)
{
MatroskaMuxContext *mkv = s->priv_data;
if (!s->pb->seekable) {
if (!mkv->dyn_bc) {
- if ((ret = avio_open_dyn_buf(&mkv->dyn_bc)) < 0) {
+ ret = avio_open_dyn_buf(&mkv->dyn_bc);
+ if (ret < 0) {
av_log(s, AV_LOG_ERROR, "Failed to open dynamic buffer\n");
return ret;
}
if (ret < 0) return ret;
}
} else {
- if (codec->codec_id == AV_CODEC_ID_SRT) {
- duration = mkv_write_srt_blocks(s, pb, pkt);
- } else if (codec->codec_id == AV_CODEC_ID_WEBVTT) {
+ if (codec->codec_id == AV_CODEC_ID_WEBVTT) {
duration = mkv_write_vtt_blocks(s, pb, pkt);
} else {
ebml_master blockgroup = start_ebml_master(pb, MATROSKA_ID_BLOCKGROUP,
// on seeing key frames.
start_new_cluster = keyframe;
} else if (mkv->is_dash && codec_type == AVMEDIA_TYPE_AUDIO &&
- cluster_time > mkv->cluster_time_limit) {
+ (mkv->cluster_pos == -1 ||
+ cluster_time > mkv->cluster_time_limit)) {
// For DASH audio, we create a Cluster based on cluster_time_limit
start_new_cluster = 1;
} else if (!mkv->is_dash &&
time.tm_yday = avio_rl16(pb);
time.tm_isdst = avio_rl16(pb);
avio_skip(pb, 2);
- strftime(str, sizeof(str), "%Y-%m-%d %H:%M:%S", &time);
- av_dict_set(&avctx->metadata, "time", str, 0);
+ if (strftime(str, sizeof(str), "%Y-%m-%d %H:%M:%S", &time))
+ av_dict_set(&avctx->metadata, "time", str, 0);
size -= 20;
} else if (type == MKTAG('E','X','P','O') && size >= 16) {
av_dict_set(&avctx->metadata, "isoMode", avio_rl32(pb) ? "auto" : "manual", 0);
mmf->stereo = s->streams[0]->codec->channels > 1;
if (mmf->stereo &&
- s->streams[0]->codec->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) {
+ s->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) {
av_log(s, AV_LOG_ERROR, "Yamaha SMAF stereo is experimental, "
"add '-strict %d' if you want to use it.\n",
FF_COMPLIANCE_EXPERIMENTAL);
#include <limits.h>
#include <stdint.h>
-//#define MOV_EXPORT_ALL_METADATA
-
#include "libavutil/attributes.h"
#include "libavutil/channel_layout.h"
#include "libavutil/display.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/intfloat.h"
#include "libavutil/mathematics.h"
+#include "libavutil/time_internal.h"
#include "libavutil/avstring.h"
#include "libavutil/dict.h"
#include "libavutil/opt.h"
} MOVParseTableEntry;
static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom);
+static int mov_read_mfra(MOVContext *c, AVIOContext *f);
static int mov_metadata_track_or_disc_number(MOVContext *c, AVIOContext *pb,
unsigned len, const char *key)
static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
-#ifdef MOV_EXPORT_ALL_METADATA
char tmp_key[5];
-#endif
- char str[1024], key2[16], language[4] = {0};
+ char key2[32], language[4] = {0};
+ char *str = NULL;
const char *key = NULL;
uint16_t langcode = 0;
- uint32_t data_type = 0, str_size;
+ uint32_t data_type = 0, str_size, str_size_alloc;
int (*parse)(MOVContext*, AVIOContext*, unsigned, const char*) = NULL;
switch (atom.type) {
} else
str_size = atom.size;
-#ifdef MOV_EXPORT_ALL_METADATA
- if (!key) {
+ if (c->export_all && !key) {
snprintf(tmp_key, 5, "%.4s", (char*)&atom.type);
key = tmp_key;
}
-#endif
if (!key)
return 0;
if (atom.size < 0)
return AVERROR_INVALIDDATA;
- str_size = FFMIN3(sizeof(str)-1, str_size, atom.size);
+ str_size_alloc = str_size << 1; // worst-case requirement for output string in case of utf8 coded input
+ str = av_malloc(str_size_alloc);
+ if (!str)
+ return AVERROR(ENOMEM);
if (parse)
parse(c, pb, str_size, key);
else {
if (data_type == 3 || (data_type == 0 && (langcode < 0x400 || langcode == 0x7fff))) { // MAC Encoded
- mov_read_mac_string(c, pb, str_size, str, sizeof(str));
+ mov_read_mac_string(c, pb, str_size, str, str_size_alloc);
} else {
int ret = avio_read(pb, str, str_size);
- if (ret != str_size)
+ if (ret != str_size) {
+ av_freep(&str);
return ret < 0 ? ret : AVERROR_INVALIDDATA;
+ }
str[str_size] = 0;
}
c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
}
av_dlog(c->fc, "lang \"%3s\" ", language);
av_dlog(c->fc, "tag \"%s\" value \"%s\" atom \"%.4s\" %d %"PRId64"\n",
- key, str, (char*)&atom.type, str_size, atom.size);
+ key, str, (char*)&atom.type, str_size_alloc, atom.size);
+ av_freep(&str);
return 0;
}
static int mov_read_wfex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
AVStream *st;
+ int ret;
if (c->fc->nb_streams < 1)
return 0;
st = c->fc->streams[c->fc->nb_streams-1];
- if (ff_get_wav_header(pb, st->codec, atom.size) < 0) {
+ if ((ret = ff_get_wav_header(pb, st->codec, atom.size)) < 0)
av_log(c->fc, AV_LOG_WARNING, "get_wav_header failed\n");
- }
- return 0;
+ return ret;
}
static int mov_read_pasp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
static int mov_read_moof(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
+ if (!c->has_looked_for_mfra && c->use_mfra_for > 0) {
+ c->has_looked_for_mfra = 1;
+ if (pb->seekable) {
+ int ret;
+ av_log(c->fc, AV_LOG_VERBOSE, "stream has moof boxes, will look "
+ "for a mfra\n");
+ if ((ret = mov_read_mfra(c, pb)) < 0) {
+ av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but failed to "
+ "read the mfra (may be a live ismv)\n");
+ }
+ } else {
+ av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but stream is not "
+ "seekable, can not look for mfra\n");
+ }
+ }
c->fragment.moof_offset = c->fragment.implicit_offset = avio_tell(pb) - 8;
av_dlog(c->fc, "moof offset %"PRIx64"\n", c->fragment.moof_offset);
return mov_read_default(c, pb, atom);
{
char buffer[32];
if (time) {
- struct tm *ptm;
+ struct tm *ptm, tmbuf;
time_t timet;
if(time >= 2082844800)
time -= 2082844800; /* seconds between 1904-01-01 and Epoch */
timet = time;
- ptm = gmtime(&timet);
+ ptm = gmtime_r(&timet, &tmbuf);
if (!ptm) return;
- strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", ptm);
- av_dict_set(metadata, "creation_time", buffer, 0);
+ if (strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", ptm))
+ av_dict_set(metadata, "creation_time", buffer, 0);
}
}
return 0;
}
+static int mov_read_colr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
+{
+ AVStream *st;
+ char color_parameter_type[5] = { 0 };
+ int color_primaries, color_trc, color_matrix;
+
+ if (c->fc->nb_streams < 1)
+ return 0;
+ st = c->fc->streams[c->fc->nb_streams - 1];
+
+ avio_read(pb, color_parameter_type, 4);
+ if (strncmp(color_parameter_type, "nclx", 4) &&
+ strncmp(color_parameter_type, "nclc", 4)) {
+ av_log(c->fc, AV_LOG_WARNING, "unsupported color_parameter_type %s\n",
+ color_parameter_type);
+ return 0;
+ }
+
+ color_primaries = avio_rb16(pb);
+ color_trc = avio_rb16(pb);
+ color_matrix = avio_rb16(pb);
+
+ av_dlog(c->fc, "%s: pri %d trc %d matrix %d",
+ color_parameter_type, color_primaries, color_trc, color_matrix);
+
+ if (c->isom) {
+ uint8_t color_range = avio_r8(pb) >> 7;
+ av_dlog(c->fc, " full %"PRIu8"", color_range);
+ if (color_range)
+ st->codec->color_range = AVCOL_RANGE_JPEG;
+ else
+ st->codec->color_range = AVCOL_RANGE_MPEG;
+ /* 14496-12 references JPEG XR specs (rather than the more complete
+ * 23001-8) so some adjusting is required */
+ if (color_primaries >= AVCOL_PRI_FILM)
+ color_primaries = AVCOL_PRI_UNSPECIFIED;
+ if ((color_trc >= AVCOL_TRC_LINEAR &&
+ color_trc <= AVCOL_TRC_LOG_SQRT) ||
+ color_trc >= AVCOL_TRC_BT2020_10)
+ color_trc = AVCOL_TRC_UNSPECIFIED;
+ if (color_matrix >= AVCOL_SPC_BT2020_NCL)
+ color_matrix = AVCOL_SPC_UNSPECIFIED;
+ st->codec->color_primaries = color_primaries;
+ st->codec->color_trc = color_trc;
+ st->codec->colorspace = color_matrix;
+ } else {
+ /* color primaries, Table 4-4 */
+ switch (color_primaries) {
+ case 1: st->codec->color_primaries = AVCOL_PRI_BT709; break;
+ case 5: st->codec->color_primaries = AVCOL_PRI_SMPTE170M; break;
+ case 6: st->codec->color_primaries = AVCOL_PRI_SMPTE240M; break;
+ }
+ /* color transfer, Table 4-5 */
+ switch (color_trc) {
+ case 1: st->codec->color_trc = AVCOL_TRC_BT709; break;
+ case 7: st->codec->color_trc = AVCOL_TRC_SMPTE240M; break;
+ }
+ /* color matrix, Table 4-6 */
+ switch (color_matrix) {
+ case 1: st->codec->colorspace = AVCOL_SPC_BT709; break;
+ case 6: st->codec->colorspace = AVCOL_SPC_BT470BG; break;
+ case 7: st->codec->colorspace = AVCOL_SPC_SMPTE240M; break;
+ }
+ }
+ av_dlog(c->fc, "\n");
+
+ return 0;
+}
+
static int mov_read_fiel(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
AVStream *st;
if (type == MKTAG('f','i','e','l') && size == atom.size)
return mov_read_default(c, pb, atom);
}
+ if (st->codec->extradata_size > 1 && st->codec->extradata) {
+ av_log(c, AV_LOG_WARNING, "ignoring multiple glbl\n");
+ return 0;
+ }
av_free(st->codec->extradata);
if (ff_get_extradata(st->codec, pb, atom.size) < 0)
return AVERROR(ENOMEM);
if (!entries)
return 0;
- if (entries >= UINT_MAX/sizeof(int64_t))
- return AVERROR_INVALIDDATA;
- sc->chunk_offsets = av_malloc(entries * sizeof(int64_t));
+ if (sc->chunk_offsets)
+ av_log(c->fc, AV_LOG_WARNING, "Duplicated STCO atom\n");
+ av_free(sc->chunk_offsets);
+ sc->chunk_count = 0;
+ sc->chunk_offsets = av_malloc_array(entries, sizeof(*sc->chunk_offsets));
if (!sc->chunk_offsets)
return AVERROR(ENOMEM);
sc->chunk_count = entries;
st->codec->codec_id =
st->codec->codec_id == AV_CODEC_ID_PCM_S16BE ?
AV_CODEC_ID_PCM_S24BE : AV_CODEC_ID_PCM_S24LE;
+ else if (st->codec->bits_per_coded_sample == 32)
+ st->codec->codec_id =
+ st->codec->codec_id == AV_CODEC_ID_PCM_S16BE ?
+ AV_CODEC_ID_PCM_S32BE : AV_CODEC_ID_PCM_S32LE;
break;
/* set values for old format before stsd version 1 appeared */
case AV_CODEC_ID_MACE3:
}
break;
case AV_CODEC_ID_AC3:
+ case AV_CODEC_ID_EAC3:
case AV_CODEC_ID_MPEG1VIDEO:
case AV_CODEC_ID_VC1:
st->need_parsing = AVSTREAM_PARSE_FULL;
if (!entries)
return 0;
- if (entries >= UINT_MAX / sizeof(*sc->stsc_data))
- return AVERROR_INVALIDDATA;
- sc->stsc_data = av_malloc(entries * sizeof(*sc->stsc_data));
+ if (sc->stsc_data)
+ av_log(c->fc, AV_LOG_WARNING, "Duplicated STSC atom\n");
+ av_free(sc->stsc_data);
+ sc->stsc_count = 0;
+ sc->stsc_data = av_malloc_array(entries, sizeof(*sc->stsc_data));
if (!sc->stsc_data)
return AVERROR(ENOMEM);
avio_rb32(pb); // version + flags
entries = avio_rb32(pb);
- if (entries >= UINT_MAX / sizeof(*sc->stps_data))
- return AVERROR_INVALIDDATA;
- sc->stps_data = av_malloc(entries * sizeof(*sc->stps_data));
+ if (sc->stps_data)
+ av_log(c->fc, AV_LOG_WARNING, "Duplicated STPS atom\n");
+ av_free(sc->stps_data);
+ sc->stps_count = 0;
+ sc->stps_data = av_malloc_array(entries, sizeof(*sc->stps_data));
if (!sc->stps_data)
return AVERROR(ENOMEM);
st->need_parsing = AVSTREAM_PARSE_HEADERS;
return 0;
}
- if (entries >= UINT_MAX / sizeof(int))
- return AVERROR_INVALIDDATA;
- sc->keyframes = av_malloc(entries * sizeof(int));
+ if (sc->keyframes)
+ av_log(c->fc, AV_LOG_WARNING, "Duplicated STSS atom\n");
+ av_free(sc->keyframes);
+ sc->keyframe_count = 0;
+ sc->keyframes = av_malloc_array(entries, sizeof(*sc->keyframes));
if (!sc->keyframes)
return AVERROR(ENOMEM);
if (!entries)
return 0;
- if (entries >= UINT_MAX / sizeof(int) || entries >= (UINT_MAX - 4) / field_size)
+ if (entries >= (UINT_MAX - 4) / field_size)
return AVERROR_INVALIDDATA;
- sc->sample_sizes = av_malloc(entries * sizeof(int));
+ if (sc->sample_sizes)
+ av_log(c->fc, AV_LOG_WARNING, "Duplicated STSZ atom\n");
+ av_free(sc->sample_sizes);
+ sc->sample_count = 0;
+ sc->sample_sizes = av_malloc_array(entries, sizeof(*sc->sample_sizes));
if (!sc->sample_sizes)
return AVERROR(ENOMEM);
av_dlog(c->fc, "track[%i].stts.entries = %i\n",
c->fc->nb_streams-1, entries);
- if (entries >= UINT_MAX / sizeof(*sc->stts_data))
- return -1;
-
+ if (sc->stts_data)
+ av_log(c->fc, AV_LOG_WARNING, "Duplicated STTS atom\n");
av_free(sc->stts_data);
- sc->stts_data = av_malloc(entries * sizeof(*sc->stts_data));
+ sc->stts_count = 0;
+ sc->stts_data = av_malloc_array(entries, sizeof(*sc->stts_data));
if (!sc->stts_data)
return AVERROR(ENOMEM);
entries = avio_rb32(pb);
if (!entries)
return 0;
- if (entries >= UINT_MAX / sizeof(*sc->rap_group))
- return AVERROR_INVALIDDATA;
- sc->rap_group = av_malloc(entries * sizeof(*sc->rap_group));
+ if (sc->rap_group)
+ av_log(c->fc, AV_LOG_WARNING, "Duplicated SBGP atom\n");
+ av_free(sc->rap_group);
+ sc->rap_group_count = 0;
+ sc->rap_group = av_malloc_array(entries, sizeof(*sc->rap_group));
if (!sc->rap_group)
return AVERROR(ENOMEM);
{
MOVFragment *frag = &c->fragment;
MOVTrackExt *trex = NULL;
+ MOVFragmentIndex* index = NULL;
int flags, track_id, i;
avio_r8(pb); /* version */
av_log(c->fc, AV_LOG_ERROR, "could not find corresponding trex\n");
return AVERROR_INVALIDDATA;
}
+ for (i = 0; i < c->fragment_index_count; i++) {
+ MOVFragmentIndex* candidate = c->fragment_index_data[i];
+ if (candidate->track_id == frag->track_id) {
+ av_log(c->fc, AV_LOG_DEBUG,
+ "found fragment index for track %u\n", frag->track_id);
+ index = candidate;
+ break;
+ }
+ }
frag->base_data_offset = flags & MOV_TFHD_BASE_DATA_OFFSET ?
avio_rb64(pb) : flags & MOV_TFHD_DEFAULT_BASE_IS_MOOF ?
avio_rb32(pb) : trex->size;
frag->flags = flags & MOV_TFHD_DEFAULT_FLAGS ?
avio_rb32(pb) : trex->flags;
+ frag->time = AV_NOPTS_VALUE;
+ if (index) {
+ int i, found = 0;
+ for (i = index->current_item; i < index->item_count; i++) {
+ if (frag->implicit_offset == index->items[i].moof_offset) {
+ av_log(c->fc, AV_LOG_DEBUG, "found fragment index entry "
+ "for track %u and moof_offset %"PRId64"\n",
+ frag->track_id, index->items[i].moof_offset);
+ frag->time = index->items[i].time;
+ index->current_item = i + 1;
+ found = 1;
+ }
+ }
+ if (!found) {
+ av_log(c->fc, AV_LOG_WARNING, "track %u has a fragment index "
+ "but it doesn't have an (in-order) entry for moof_offset "
+ "%"PRId64"\n", frag->track_id, frag->implicit_offset);
+ }
+ }
av_dlog(c->fc, "frag flags 0x%x\n", frag->flags);
return 0;
}
return 0;
}
+static int mov_read_tfdt(MOVContext *c, AVIOContext *pb, MOVAtom atom)
+{
+ MOVFragment *frag = &c->fragment;
+ AVStream *st = NULL;
+ MOVStreamContext *sc;
+ int version, i;
+
+ for (i = 0; i < c->fc->nb_streams; i++) {
+ if (c->fc->streams[i]->id == frag->track_id) {
+ st = c->fc->streams[i];
+ break;
+ }
+ }
+ if (!st) {
+ av_log(c->fc, AV_LOG_ERROR, "could not find corresponding track id %d\n", frag->track_id);
+ return AVERROR_INVALIDDATA;
+ }
+ sc = st->priv_data;
+ if (sc->pseudo_stream_id + 1 != frag->stsd_id)
+ return 0;
+ version = avio_r8(pb);
+ avio_rb24(pb); /* flags */
+ if (version) {
+ sc->track_end = avio_rb64(pb);
+ } else {
+ sc->track_end = avio_rb32(pb);
+ }
+ return 0;
+}
+
static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
MOVFragment *frag = &c->fragment;
sc->ctts_data[sc->ctts_count].duration = (flags & MOV_TRUN_SAMPLE_CTS) ?
avio_rb32(pb) : 0;
mov_update_dts_shift(sc, sc->ctts_data[sc->ctts_count].duration);
+ if (frag->time != AV_NOPTS_VALUE) {
+ if (c->use_mfra_for == FF_MOV_FLAG_MFRA_PTS) {
+ int64_t pts = frag->time;
+ av_log(c->fc, AV_LOG_DEBUG, "found frag time %"PRId64
+ " sc->dts_shift %d ctts.duration %d"
+ " sc->time_offset %"PRId64" flags & MOV_TRUN_SAMPLE_CTS %d\n", pts,
+ sc->dts_shift, sc->ctts_data[sc->ctts_count].duration,
+ sc->time_offset, flags & MOV_TRUN_SAMPLE_CTS);
+ dts = pts - sc->dts_shift;
+ if (flags & MOV_TRUN_SAMPLE_CTS) {
+ dts -= sc->ctts_data[sc->ctts_count].duration;
+ } else {
+ dts -= sc->time_offset;
+ }
+ av_log(c->fc, AV_LOG_DEBUG, "calculated into dts %"PRId64"\n", dts);
+ } else {
+ dts = frag->time;
+ av_log(c->fc, AV_LOG_DEBUG, "found frag time %"PRId64
+ ", using it for dts\n", dts);
+ }
+ frag->time = AV_NOPTS_VALUE;
+ }
sc->ctts_count++;
if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO)
keyframe = 1;
return 0;
}
+static int mov_read_free(MOVContext *c, AVIOContext *pb, MOVAtom atom)
+{
+ int ret;
+ uint8_t content[16];
+
+ if (atom.size < 8)
+ return 0;
+
+ ret = avio_read(pb, content, FFMIN(sizeof(content), atom.size));
+ if (ret < 0)
+ return ret;
+
+ if ( !c->found_moov
+ && !c->found_mdat
+ && !memcmp(content, "Anevia\x1A\x1A", 8)
+ && c->use_mfra_for == FF_MOV_FLAG_MFRA_AUTO) {
+ c->use_mfra_for = FF_MOV_FLAG_MFRA_PTS;
+ }
+
+ return 0;
+}
+
static const MOVParseTableEntry mov_default_parse_table[] = {
{ MKTAG('A','C','L','R'), mov_read_avid },
{ MKTAG('A','P','R','G'), mov_read_avid },
{ MKTAG('a','v','s','s'), mov_read_avss },
{ MKTAG('c','h','p','l'), mov_read_chpl },
{ MKTAG('c','o','6','4'), mov_read_stco },
+{ MKTAG('c','o','l','r'), mov_read_colr },
{ MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */
{ MKTAG('d','i','n','f'), mov_read_default },
{ MKTAG('d','r','e','f'), mov_read_dref },
{ MKTAG('s','t','t','s'), mov_read_stts },
{ MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */
{ MKTAG('t','k','h','d'), mov_read_tkhd }, /* track header */
+{ MKTAG('t','f','d','t'), mov_read_tfdt },
{ MKTAG('t','f','h','d'), mov_read_tfhd }, /* track fragment header */
{ MKTAG('t','r','a','k'), mov_read_trak },
{ MKTAG('t','r','a','f'), mov_read_default },
{ 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 },
+{ MKTAG('f','r','e','e'), mov_read_free },
{ MKTAG('-','-','-','-'), mov_read_custom },
{ 0, NULL }
};
av_freep(&mov->trex_data);
av_freep(&mov->bitrates);
+ for (i = 0; i < mov->fragment_index_count; i++) {
+ MOVFragmentIndex* index = mov->fragment_index_data[i];
+ av_freep(&index->items);
+ av_freep(&mov->fragment_index_data[i]);
+ }
+ av_freep(&mov->fragment_index_data);
+
return 0;
}
}
}
+static int read_tfra(MOVContext *mov, AVIOContext *f)
+{
+ MOVFragmentIndex* index = NULL;
+ int version, fieldlength, i, j, err;
+ int64_t pos = avio_tell(f);
+ uint32_t size = avio_rb32(f);
+ if (avio_rb32(f) != MKBETAG('t', 'f', 'r', 'a')) {
+ return -1;
+ }
+ av_log(mov->fc, AV_LOG_VERBOSE, "found tfra\n");
+ index = av_mallocz(sizeof(MOVFragmentIndex));
+ if (!index) {
+ return AVERROR(ENOMEM);
+ }
+ mov->fragment_index_count++;
+ if ((err = av_reallocp(&mov->fragment_index_data,
+ mov->fragment_index_count *
+ sizeof(MOVFragmentIndex*))) < 0) {
+ av_freep(&index);
+ return err;
+ }
+ mov->fragment_index_data[mov->fragment_index_count - 1] =
+ index;
+
+ version = avio_r8(f);
+ avio_rb24(f);
+ index->track_id = avio_rb32(f);
+ fieldlength = avio_rb32(f);
+ index->item_count = avio_rb32(f);
+ index->items = av_mallocz(
+ index->item_count * sizeof(MOVFragmentIndexItem));
+ if (!index->items) {
+ return AVERROR(ENOMEM);
+ }
+ for (i = 0; i < index->item_count; i++) {
+ int64_t time, offset;
+ if (version == 1) {
+ time = avio_rb64(f);
+ offset = avio_rb64(f);
+ } else {
+ time = avio_rb32(f);
+ offset = avio_rb32(f);
+ }
+ index->items[i].time = time;
+ index->items[i].moof_offset = offset;
+ for (j = 0; j < ((fieldlength >> 4) & 3) + 1; j++)
+ avio_r8(f);
+ for (j = 0; j < ((fieldlength >> 2) & 3) + 1; j++)
+ avio_r8(f);
+ for (j = 0; j < ((fieldlength >> 0) & 3) + 1; j++)
+ avio_r8(f);
+ }
+
+ avio_seek(f, pos + size, SEEK_SET);
+ return 0;
+}
+
+static int mov_read_mfra(MOVContext *c, AVIOContext *f)
+{
+ int64_t stream_size = avio_size(f);
+ int64_t original_pos = avio_tell(f);
+ int64_t seek_ret;
+ int32_t mfra_size;
+ int ret = -1;
+ if ((seek_ret = avio_seek(f, stream_size - 4, SEEK_SET)) < 0) {
+ ret = seek_ret;
+ goto fail;
+ }
+ mfra_size = avio_rb32(f);
+ if (mfra_size < 0 || mfra_size > stream_size) {
+ av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (unreasonable size)\n");
+ goto fail;
+ }
+ if ((seek_ret = avio_seek(f, -mfra_size, SEEK_CUR)) < 0) {
+ ret = seek_ret;
+ goto fail;
+ }
+ if (avio_rb32(f) != mfra_size) {
+ av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (size mismatch)\n");
+ goto fail;
+ }
+ if (avio_rb32(f) != MKBETAG('m', 'f', 'r', 'a')) {
+ av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (tag mismatch)\n");
+ goto fail;
+ }
+ ret = 0;
+ av_log(c->fc, AV_LOG_VERBOSE, "stream has mfra\n");
+ while (!read_tfra(c, f)) {
+ /* Empty */
+ }
+fail:
+ seek_ret = avio_seek(f, original_pos, SEEK_SET);
+ if (seek_ret < 0) {
+ av_log(c->fc, AV_LOG_ERROR,
+ "failed to seek back after looking for mfra\n");
+ ret = seek_ret;
+ }
+ return ret;
+}
+
static int mov_read_header(AVFormatContext *s)
{
MOVContext *mov = s->priv_data;
av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den,
sc->time_scale*(int64_t)sc->nb_frames_for_fps, sc->duration_for_fps, INT_MAX);
if (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE) {
- if (st->codec->width <= 0 && st->codec->height <= 0) {
+ if (st->codec->width <= 0 || st->codec->height <= 0) {
st->codec->width = sc->width;
st->codec->height = sc->height;
}
}
}
+ if (mov->use_mfra_for > 0) {
+ for (i = 0; i < s->nb_streams; i++) {
+ AVStream *st = s->streams[i];
+ MOVStreamContext *sc = st->priv_data;
+ if (sc->duration_for_fps > 0) {
+ st->codec->bit_rate = sc->data_size * 8 * sc->time_scale /
+ sc->duration_for_fps;
+ }
+ }
+ }
+
for (i = 0; i < mov->bitrates_count && i < s->nb_streams; i++) {
if (mov->bitrates[i]) {
s->streams[i]->codec->bit_rate = mov->bitrates[i];
return 0;
}
-static const AVOption options[] = {
+#define OFFSET(x) offsetof(MOVContext, x)
+#define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
+static const AVOption mov_options[] = {
{"use_absolute_path",
"allow using absolute path when opening alias, this is a possible security issue",
offsetof(MOVContext, use_absolute_path), FF_OPT_TYPE_INT, {.i64 = 0},
0, 1, AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_DECODING_PARAM},
{"ignore_editlist", "", offsetof(MOVContext, ignore_editlist), FF_OPT_TYPE_INT, {.i64 = 0},
0, 1, AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_DECODING_PARAM},
- {NULL}
+ {"use_mfra_for",
+ "use mfra for fragment timestamps",
+ offsetof(MOVContext, use_mfra_for), FF_OPT_TYPE_INT, {.i64 = FF_MOV_FLAG_MFRA_AUTO},
+ -1, FF_MOV_FLAG_MFRA_PTS, AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_DECODING_PARAM,
+ "use_mfra_for"},
+ {"auto", "auto", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_AUTO}, 0, 0,
+ AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_DECODING_PARAM, "use_mfra_for" },
+ {"dts", "dts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_DTS}, 0, 0,
+ AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_DECODING_PARAM, "use_mfra_for" },
+ {"pts", "pts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_PTS}, 0, 0,
+ AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_DECODING_PARAM, "use_mfra_for" },
+ { "export_all", "Export unrecognized metadata entries", OFFSET(export_all),
+ AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, .flags = FLAGS },
+ { NULL },
};
static const AVClass mov_class = {
.class_name = "mov,mp4,m4a,3gp,3g2,mj2",
.item_name = av_default_item_name,
- .option = options,
+ .option = mov_options,
.version = LIBAVUTIL_VERSION_INT,
};
AVInputFormat ff_mov_demuxer = {
.name = "mov,mp4,m4a,3gp,3g2,mj2",
.long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
+ .priv_class = &mov_class,
.priv_data_size = sizeof(MOVContext),
.extensions = "mov,mp4,m4a,3gp,3g2,mj2",
.read_probe = mov_probe,
.read_packet = mov_read_packet,
.read_close = mov_read_close,
.read_seek = mov_read_seek,
- .priv_class = &mov_class,
.flags = AVFMT_NO_BYTE_SEEK,
};
#include "avio.h"
#include "isom.h"
#include "avc.h"
+#include "libavcodec/ac3_parser.h"
#include "libavcodec/get_bits.h"
#include "libavcodec/put_bits.h"
#include "libavcodec/vc1_common.h"
{ "movflags", "MOV muxer flags", offsetof(MOVMuxContext, flags), AV_OPT_TYPE_FLAGS, {.i64 = 0}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
{ "rtphint", "Add RTP hint tracks", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_RTP_HINT}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
{ "moov_size", "maximum moov size so it can be placed at the begin", offsetof(MOVMuxContext, reserved_moov_size), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, 0 },
- { "empty_moov", "Make the initial moov atom empty (not supported by QuickTime)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_EMPTY_MOOV}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
+ { "empty_moov", "Make the initial moov atom empty", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_EMPTY_MOOV}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
{ "frag_keyframe", "Fragment at video keyframes", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_FRAG_KEYFRAME}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
{ "separate_moof", "Write separate moof/mdat atoms for each track", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_SEPARATE_MOOF}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
{ "frag_custom", "Flush fragments on caller requests", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_FRAG_CUSTOM}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
{ "faststart", "Run a second pass to put the index (moov atom) at the beginning of the file", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_FASTSTART}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
{ "omit_tfhd_offset", "Omit the base data offset in tfhd atoms", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_OMIT_TFHD_OFFSET}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
{ "disable_chpl", "Disable Nero chapter atom", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_DISABLE_CHPL}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
+ { "default_base_moof", "Set the default-base-is-moof flag in tfhd atoms", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_DEFAULT_BASE_MOOF}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
+ { "dash", "Write DASH compatible fragmented MP4", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_DASH}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
+ { "frag_discont", "Signal that the next fragment is discontinuous from earlier ones", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_FRAG_DISCONT}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
FF_RTP_FLAG_OPTS(MOVMuxContext, rtp_flags),
{ "skip_iods", "Skip writing iods atom.", offsetof(MOVMuxContext, iods_skip), AV_OPT_TYPE_INT, {.i64 = 1}, 0, 1, AV_OPT_FLAG_ENCODING_PARAM},
{ "iods_audio_profile", "iods audio profile atom.", offsetof(MOVMuxContext, iods_audio_profile), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 255, AV_OPT_FLAG_ENCODING_PARAM},
{ "min_frag_duration", "Minimum fragment duration", offsetof(MOVMuxContext, min_fragment_duration), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
{ "frag_size", "Maximum fragment size", offsetof(MOVMuxContext, max_fragment_size), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
{ "ism_lookahead", "Number of lookahead entries for ISM files", offsetof(MOVMuxContext, ism_lookahead), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
- { "use_editlist", "use edit list", offsetof(MOVMuxContext, use_editlist), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 1, AV_OPT_FLAG_ENCODING_PARAM},
{ "video_track_timescale", "set timescale of all video tracks", offsetof(MOVMuxContext, video_track_timescale), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
{ "brand", "Override major brand", offsetof(MOVMuxContext, major_brand), AV_OPT_TYPE_STRING, {.str = NULL}, .flags = AV_OPT_FLAG_ENCODING_PARAM },
+ { "use_editlist", "use edit list", offsetof(MOVMuxContext, use_editlist), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 1, AV_OPT_FLAG_ENCODING_PARAM},
+ { "fragment_index", "Fragment number of the next fragment", offsetof(MOVMuxContext, fragments), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
{ NULL },
};
return curpos - pos;
}
-static int supports_edts(MOVMuxContext *mov)
-{
- // EDTS with fragments is tricky as we don't know the duration when its written
- return (mov->use_editlist<0 && !(mov->flags & FF_MOV_FLAG_FRAGMENT)) || mov->use_editlist>0;
-}
-
static int co64_required(const MOVTrack *track)
{
if (track->entry > 0 && track->cluster[track->entry - 1].pos + track->data_offset > UINT32_MAX)
return 11;
}
+struct eac3_info {
+ AVPacket pkt;
+ uint8_t ec3_done;
+ uint8_t num_blocks;
+
+ /* Layout of the EC3SpecificBox */
+ /* maximum bitrate */
+ uint16_t data_rate;
+ /* number of independent substreams */
+ uint8_t num_ind_sub;
+ struct {
+ /* sample rate code (see ff_ac3_sample_rate_tab) 2 bits */
+ uint8_t fscod;
+ /* bit stream identification 5 bits */
+ uint8_t bsid;
+ /* one bit reserved */
+ /* audio service mixing (not supported yet) 1 bit */
+ /* bit stream mode 3 bits */
+ uint8_t bsmod;
+ /* audio coding mode 3 bits */
+ uint8_t acmod;
+ /* sub woofer on 1 bit */
+ uint8_t lfeon;
+ /* 3 bits reserved */
+ /* number of dependent substreams associated with this substream 4 bits */
+ uint8_t num_dep_sub;
+ /* channel locations of the dependent substream(s), if any, 9 bits */
+ uint16_t chan_loc;
+ /* if there is no dependent substream, then one bit reserved instead */
+ } substream[1]; /* TODO: support 8 independent substreams */
+};
+
+static int handle_eac3(MOVMuxContext *mov, AVPacket *pkt, MOVTrack *track)
+{
+ GetBitContext gbc;
+ AC3HeaderInfo tmp, *hdr = &tmp;
+ struct eac3_info *info;
+ int num_blocks;
+
+ if (!track->eac3_priv && !(track->eac3_priv = av_mallocz(sizeof(*info))))
+ return AVERROR(ENOMEM);
+ info = track->eac3_priv;
+
+ init_get_bits(&gbc, pkt->data, pkt->size * 8);
+ if (avpriv_ac3_parse_header2(&gbc, &hdr) < 0) {
+ /* drop the packets until we see a good one */
+ if (!track->entry) {
+ av_log(mov, AV_LOG_WARNING, "Dropping invalid packet from start of the stream\n");
+ return 0;
+ }
+ return AVERROR_INVALIDDATA;
+ }
+
+ info->data_rate = FFMAX(info->data_rate, hdr->bit_rate / 1000);
+ num_blocks = hdr->num_blocks;
+
+ if (!info->ec3_done) {
+ /* AC-3 substream must be the first one */
+ if (hdr->bitstream_id <= 10 && hdr->substreamid != 0)
+ return AVERROR(EINVAL);
+
+ /* this should always be the case, given that our AC-3 parser
+ * concatenates dependent frames to their independent parent */
+ if (hdr->frame_type == EAC3_FRAME_TYPE_INDEPENDENT) {
+ /* substream ids must be incremental */
+ if (hdr->substreamid > info->num_ind_sub + 1)
+ return AVERROR(EINVAL);
+
+ if (hdr->substreamid == info->num_ind_sub + 1) {
+ //info->num_ind_sub++;
+ avpriv_request_sample(track->enc, "Multiple independent substreams");
+ return AVERROR_PATCHWELCOME;
+ } else if (hdr->substreamid < info->num_ind_sub ||
+ hdr->substreamid == 0 && info->substream[0].bsid) {
+ info->ec3_done = 1;
+ goto concatenate;
+ }
+ }
+
+ /* fill the info needed for the "dec3" atom */
+ info->substream[hdr->substreamid].fscod = hdr->sr_code;
+ info->substream[hdr->substreamid].bsid = hdr->bitstream_id;
+ info->substream[hdr->substreamid].bsmod = hdr->bitstream_mode;
+ info->substream[hdr->substreamid].acmod = hdr->channel_mode;
+ info->substream[hdr->substreamid].lfeon = hdr->lfe_on;
+
+ /* Parse dependent substream(s), if any */
+ if (pkt->size != hdr->frame_size) {
+ int cumul_size = hdr->frame_size;
+ int parent = hdr->substreamid;
+
+ while (cumul_size != pkt->size) {
+ int i;
+ init_get_bits(&gbc, pkt->data + cumul_size, (pkt->size - cumul_size) * 8);
+ if (avpriv_ac3_parse_header2(&gbc, &hdr) < 0)
+ return AVERROR_INVALIDDATA;
+ if (hdr->frame_type != EAC3_FRAME_TYPE_DEPENDENT)
+ return AVERROR(EINVAL);
+ cumul_size += hdr->frame_size;
+ info->substream[parent].num_dep_sub++;
+
+ /* header is parsed up to lfeon, but custom channel map may be needed */
+ /* skip bsid */
+ skip_bits(&gbc, 5);
+ /* skip volume control params */
+ for (i = 0; i < (hdr->channel_mode ? 1 : 2); i++) {
+ skip_bits(&gbc, 5); // skip dialog normalization
+ if (get_bits1(&gbc)) {
+ skip_bits(&gbc, 8); // skip compression gain word
+ }
+ }
+ /* get the dependent stream channel map, if exists */
+ if (get_bits1(&gbc))
+ info->substream[parent].chan_loc |= (get_bits(&gbc, 16) >> 5) & 0x1f;
+ else
+ info->substream[parent].chan_loc |= hdr->channel_mode;
+ }
+ }
+ }
+
+concatenate:
+ if (!info->num_blocks && num_blocks == 6)
+ return pkt->size;
+ else if (info->num_blocks + num_blocks > 6)
+ return AVERROR_INVALIDDATA;
+
+ if (!info->num_blocks) {
+ int ret;
+ if ((ret = av_copy_packet(&info->pkt, pkt)) < 0)
+ return ret;
+ info->num_blocks = num_blocks;
+ return 0;
+ } else {
+ int ret;
+ if ((ret = av_grow_packet(&info->pkt, pkt->size)) < 0)
+ return ret;
+ memcpy(info->pkt.data + info->pkt.size - pkt->size, pkt->data, pkt->size);
+ info->num_blocks += num_blocks;
+ info->pkt.duration += pkt->duration;
+ if ((ret = av_copy_packet_side_data(&info->pkt, pkt)) < 0)
+ return ret;
+ if (info->num_blocks != 6)
+ return 0;
+ av_free_packet(pkt);
+ if ((ret = av_copy_packet(pkt, &info->pkt)) < 0)
+ return ret;
+ av_free_packet(&info->pkt);
+ info->num_blocks = 0;
+ }
+
+ return pkt->size;
+}
+
+static int mov_write_eac3_tag(AVIOContext *pb, MOVTrack *track)
+{
+ PutBitContext pbc;
+ uint8_t *buf;
+ struct eac3_info *info;
+ int size, i;
+
+ if (!track->eac3_priv)
+ return AVERROR(EINVAL);
+
+ info = track->eac3_priv;
+ size = 2 + 4 * (info->num_ind_sub + 1);
+ buf = av_malloc(size);
+ if (!buf) {
+ size = AVERROR(ENOMEM);
+ goto end;
+ }
+
+ init_put_bits(&pbc, buf, size);
+ put_bits(&pbc, 13, info->data_rate);
+ put_bits(&pbc, 3, info->num_ind_sub);
+ for (i = 0; i <= info->num_ind_sub; i++) {
+ put_bits(&pbc, 2, info->substream[i].fscod);
+ put_bits(&pbc, 5, info->substream[i].bsid);
+ put_bits(&pbc, 1, 0); /* reserved */
+ put_bits(&pbc, 1, 0); /* asvc */
+ put_bits(&pbc, 3, info->substream[i].bsmod);
+ put_bits(&pbc, 3, info->substream[i].acmod);
+ put_bits(&pbc, 1, info->substream[i].lfeon);
+ put_bits(&pbc, 5, 0); /* reserved */
+ put_bits(&pbc, 4, info->substream[i].num_dep_sub);
+ if (!info->substream[i].num_dep_sub) {
+ put_bits(&pbc, 1, 0); /* reserved */
+ size--;
+ } else {
+ put_bits(&pbc, 9, info->substream[i].chan_loc);
+ }
+ }
+ flush_put_bits(&pbc);
+
+ avio_wb32(pb, size + 8);
+ ffio_wfourcc(pb, "dec3");
+ avio_write(pb, buf, size);
+
+ av_free(buf);
+
+end:
+ av_free_packet(&info->pkt);
+ av_freep(&track->eac3_priv);
+
+ return size;
+}
+
/**
* This function writes extradata "as is".
* Extradata must be formatted like a valid atom (with size and tag).
mov_write_amr_tag(pb, track);
} else if (track->enc->codec_id == AV_CODEC_ID_AC3) {
mov_write_ac3_tag(pb, track);
+ } else if (track->enc->codec_id == AV_CODEC_ID_EAC3) {
+ mov_write_eac3_tag(pb, track);
} else if (track->enc->codec_id == AV_CODEC_ID_ALAC ||
track->enc->codec_id == AV_CODEC_ID_QDM2) {
mov_write_extradata_tag(pb, track);
if (track->enc->codec_id == AV_CODEC_ID_PCM_U8 ||
track->enc->codec_id == AV_CODEC_ID_PCM_S8)
avio_wb16(pb, 8); /* bits per sample */
+ else if (track->enc->codec_id == AV_CODEC_ID_ADPCM_G726)
+ avio_wb16(pb, track->enc->bits_per_coded_sample);
else
avio_wb16(pb, 16);
avio_wb16(pb, track->audio_vbr ? -2 : 0); /* compression ID */
if (track->mode == MODE_MOV &&
(track->enc->codec_id == AV_CODEC_ID_AAC ||
track->enc->codec_id == AV_CODEC_ID_AC3 ||
+ track->enc->codec_id == AV_CODEC_ID_EAC3 ||
track->enc->codec_id == AV_CODEC_ID_AMR_NB ||
track->enc->codec_id == AV_CODEC_ID_ALAC ||
track->enc->codec_id == AV_CODEC_ID_ADPCM_MS ||
mov_write_amr_tag(pb, track);
else if (track->enc->codec_id == AV_CODEC_ID_AC3)
mov_write_ac3_tag(pb, track);
+ else if (track->enc->codec_id == AV_CODEC_ID_EAC3)
+ mov_write_eac3_tag(pb, track);
else if (track->enc->codec_id == AV_CODEC_ID_ALAC)
mov_write_extradata_tag(pb, track);
else if (track->enc->codec_id == AV_CODEC_ID_WMAPRO)
if (track->enc->codec_id == AV_CODEC_ID_H264) tag = MKTAG('a','v','c','1');
else if (track->enc->codec_id == AV_CODEC_ID_HEVC) tag = MKTAG('h','e','v','1');
else if (track->enc->codec_id == AV_CODEC_ID_AC3) tag = MKTAG('a','c','-','3');
+ else if (track->enc->codec_id == AV_CODEC_ID_EAC3) tag = MKTAG('e','c','-','3');
else if (track->enc->codec_id == AV_CODEC_ID_DIRAC) tag = MKTAG('d','r','a','c');
else if (track->enc->codec_id == AV_CODEC_ID_MOV_TEXT) tag = MKTAG('t','x','3','g');
else if (track->enc->codec_id == AV_CODEC_ID_VC1) tag = MKTAG('v','c','-','1');
return tag;
}
+static int mov_get_h264_codec_tag(AVFormatContext *s, MOVTrack *track)
+{
+ int tag = track->enc->codec_tag;
+ int interlaced = track->enc->field_order > AV_FIELD_PROGRESSIVE;
+ AVStream *st = track->st;
+ int rate = av_q2d(find_fps(s, st));
+
+ if (!tag)
+ tag = MKTAG('a', 'v', 'c', 'i'); //fallback tag
+
+ if (track->enc->pix_fmt == AV_PIX_FMT_YUV420P10) {
+ if (track->enc->width == 960 && track->enc->height == 720) {
+ if (!interlaced) {
+ if (rate == 24) tag = MKTAG('a','i','5','p');
+ else if (rate == 25) tag = MKTAG('a','i','5','q');
+ else if (rate == 30) tag = MKTAG('a','i','5','p');
+ else if (rate == 50) tag = MKTAG('a','i','5','q');
+ else if (rate == 60) tag = MKTAG('a','i','5','p');
+ }
+ } else if (track->enc->width == 1440 && track->enc->height == 1080) {
+ if (!interlaced) {
+ if (rate == 24) tag = MKTAG('a','i','5','3');
+ else if (rate == 25) tag = MKTAG('a','i','5','2');
+ else if (rate == 30) tag = MKTAG('a','i','5','3');
+ } else {
+ if (rate == 50) tag = MKTAG('a','i','5','5');
+ else if (rate == 60) tag = MKTAG('a','i','5','6');
+ }
+ }
+ } else if (track->enc->pix_fmt == AV_PIX_FMT_YUV422P10) {
+ if (track->enc->width == 1280 && track->enc->height == 720) {
+ if (!interlaced) {
+ if (rate == 24) tag = MKTAG('a','i','1','p');
+ else if (rate == 25) tag = MKTAG('a','i','1','q');
+ else if (rate == 30) tag = MKTAG('a','i','1','p');
+ else if (rate == 50) tag = MKTAG('a','i','1','q');
+ else if (rate == 60) tag = MKTAG('a','i','1','p');
+ }
+ } else if (track->enc->width == 1920 && track->enc->height == 1080) {
+ if (!interlaced) {
+ if (rate == 24) tag = MKTAG('a','i','1','3');
+ else if (rate == 25) tag = MKTAG('a','i','1','2');
+ else if (rate == 30) tag = MKTAG('a','i','1','3');
+ } else {
+ if (rate == 25) tag = MKTAG('a','i','1','5');
+ else if (rate == 50) tag = MKTAG('a','i','1','5');
+ else if (rate == 60) tag = MKTAG('a','i','1','6');
+ }
+ } else if ( track->enc->width == 4096 && track->enc->height == 2160
+ || track->enc->width == 3840 && track->enc->height == 2160) {
+ tag = MKTAG('a','i','v','x');
+ }
+ }
+
+ return tag;
+}
+
static const struct {
enum AVPixelFormat pix_fmt;
uint32_t tag;
{
int tag = track->enc->codec_tag;
- if (!tag || (track->enc->strict_std_compliance >= FF_COMPLIANCE_NORMAL &&
+ if (!tag || (s->strict_std_compliance >= FF_COMPLIANCE_NORMAL &&
(track->enc->codec_id == AV_CODEC_ID_DVVIDEO ||
track->enc->codec_id == AV_CODEC_ID_RAWVIDEO ||
track->enc->codec_id == AV_CODEC_ID_H263 ||
+ track->enc->codec_id == AV_CODEC_ID_H264 ||
track->enc->codec_id == AV_CODEC_ID_MPEG2VIDEO ||
av_get_bits_per_sample(track->enc->codec_id)))) { // pcm audio
if (track->enc->codec_id == AV_CODEC_ID_DVVIDEO)
tag = mov_get_rawvideo_codec_tag(s, track);
else if (track->enc->codec_id == AV_CODEC_ID_MPEG2VIDEO)
tag = mov_get_mpeg2_xdcam_codec_tag(s, track);
+ else if (track->enc->codec_id == AV_CODEC_ID_H264)
+ tag = mov_get_h264_codec_tag(s, track);
else if (track->enc->codec_type == AVMEDIA_TYPE_VIDEO) {
tag = ff_codec_get_tag(ff_codec_movvideo_tags, track->enc->codec_id);
if (!tag) { // if no mac fcc found, try with Microsoft tags
mov_write_avid_tag(pb, track);
else if (track->enc->codec_id == AV_CODEC_ID_HEVC)
mov_write_hvcc_tag(pb, track);
- else if (track->enc->codec_id == AV_CODEC_ID_H264) {
+ else if (track->enc->codec_id == AV_CODEC_ID_H264 && !TAG_IS_AVCI(track->tag)) {
mov_write_avcc_tag(pb, track);
if (track->mode == MODE_IPOD)
mov_write_uuid_tag_ipod(pb);
return update_size(pb, pos);
}
-static int mov_write_mdhd_tag(AVIOContext *pb, MOVTrack *track)
+static int mov_write_mdhd_tag(AVIOContext *pb, MOVMuxContext *mov,
+ MOVTrack *track)
{
int version = track->track_duration < INT32_MAX ? 0 : 1;
avio_wb32(pb, track->time); /* modification time */
}
avio_wb32(pb, track->timescale); /* time scale (sample rate for audio) */
- if (!track->entry)
+ if (!track->entry && mov->mode == MODE_ISM)
(version == 1) ? avio_wb64(pb, UINT64_C(0xffffffffffffffff)) : avio_wb32(pb, 0xffffffff);
+ else if (!track->entry)
+ (version == 1) ? avio_wb64(pb, 0) : avio_wb32(pb, 0);
else
(version == 1) ? avio_wb64(pb, track->track_duration) : avio_wb32(pb, track->track_duration); /* duration */
avio_wb16(pb, track->language); /* language */
return 32;
}
-static int mov_write_mdia_tag(AVIOContext *pb, MOVTrack *track)
+static int mov_write_mdia_tag(AVIOContext *pb, MOVMuxContext *mov,
+ MOVTrack *track)
{
int64_t pos = avio_tell(pb);
avio_wb32(pb, 0); /* size */
ffio_wfourcc(pb, "mdia");
- mov_write_mdhd_tag(pb, track);
+ mov_write_mdhd_tag(pb, mov, track);
mov_write_hdlr_tag(pb, track);
mov_write_minf_tag(pb, track);
return update_size(pb, pos);
}
avio_wb32(pb, track->track_id); /* track-id */
avio_wb32(pb, 0); /* reserved */
- if (!track->entry)
+ if (!track->entry && mov->mode == MODE_ISM)
(version == 1) ? avio_wb64(pb, UINT64_C(0xffffffffffffffff)) : avio_wb32(pb, 0xffffffff);
+ else if (!track->entry)
+ (version == 1) ? avio_wb64(pb, 0) : avio_wb32(pb, 0);
else
(version == 1) ? avio_wb64(pb, duration) : avio_wb32(pb, duration);
}
// This box seems important for the psp playback ... without it the movie seems to hang
-static int mov_write_edts_tag(AVIOContext *pb, MOVTrack *track)
+static int mov_write_edts_tag(AVIOContext *pb, MOVMuxContext *mov,
+ MOVTrack *track)
{
int64_t duration = av_rescale_rnd(track->track_duration, MOV_TIMESCALE,
track->timescale, AV_ROUND_UP);
avio_wb32(pb, entry_count);
if (delay > 0) { /* add an empty edit to delay presentation */
+ /* In the positive delay case, the delay includes the cts
+ * offset, and the second edit list entry below trims out
+ * the same amount from the actual content. This makes sure
+ * that the offsetted last sample is included in the edit
+ * list duration as well. */
if (version == 1) {
avio_wb64(pb, delay);
avio_wb64(pb, -1);
}
avio_wb32(pb, 0x00010000);
} else {
+ /* Avoid accidentally ending up with start_ct = -1 which has got a
+ * special meaning. Normally start_ct should end up positive or zero
+ * here, but use FFMIN in case dts is a a small positive integer
+ * rounded to 0 when represented in MOV_TIMESCALE units. */
av_assert0(av_rescale_rnd(track->cluster[0].dts, MOV_TIMESCALE, track->timescale, AV_ROUND_DOWN) <= 0);
- start_ct = -FFMIN(track->cluster[0].dts, 0); //FFMIN needed due to rounding
+ start_ct = -FFMIN(track->cluster[0].dts, 0);
+ /* Note, this delay is calculated from the pts of the first sample,
+ * ensuring that we don't reduce the duration for cases with
+ * dts<0 pts=0. */
duration += delay;
}
+ /* For fragmented files, we don't know the full length yet. Setting
+ * duration to 0 allows us to only specify the offset, including
+ * the rest of the content (from all future fragments) without specifying
+ * an explicit duration. */
+ if (mov->flags & FF_MOV_FLAG_FRAGMENT)
+ duration = 0;
+
/* duration */
if (version == 1) {
avio_wb64(pb, duration);
avio_wb32(pb, 0); /* size */
ffio_wfourcc(pb, "trak");
mov_write_tkhd_tag(pb, mov, track, st);
- if (supports_edts(mov))
- mov_write_edts_tag(pb, track); // PSP Movies and several other cases require edts box
+
+ av_assert2(mov->use_editlist >= 0);
+
+
+ if (track->entry) {
+ if (mov->use_editlist)
+ mov_write_edts_tag(pb, mov, track); // PSP Movies and several other cases require edts box
+ else if ((track->entry && track->cluster[0].dts) || track->mode == MODE_PSP || is_clcp_track(track))
+ av_log(mov->fc, AV_LOG_WARNING,
+ "Not writing any edit list even though one would have been required\n");
+ }
+
if (track->tref_tag)
mov_write_tref_tag(pb, track);
- mov_write_mdia_tag(pb, track);
+ mov_write_mdia_tag(pb, mov, track);
if (track->mode == MODE_PSP)
mov_write_uuid_tag_psp(pb, track); // PSP Movies require this uuid box
if (track->tag == MKTAG('r','t','p',' '))
int audio_profile = mov->iods_audio_profile;
int video_profile = mov->iods_video_profile;
for (i = 0; i < mov->nb_streams; i++) {
- if (mov->tracks[i].entry > 0) {
+ if (mov->tracks[i].entry > 0 || mov->flags & FF_MOV_FLAG_EMPTY_MOOV) {
has_audio |= mov->tracks[i].enc->codec_type == AVMEDIA_TYPE_AUDIO;
has_video |= mov->tracks[i].enc->codec_type == AVMEDIA_TYPE_VIDEO;
}
}
if (mov->flags & FF_MOV_FLAG_OMIT_TFHD_OFFSET)
flags &= ~MOV_TFHD_BASE_DATA_OFFSET;
+ if (mov->flags & FF_MOV_FLAG_DEFAULT_BASE_MOOF) {
+ flags &= ~MOV_TFHD_BASE_DATA_OFFSET;
+ flags |= MOV_TFHD_DEFAULT_BASE_IS_MOOF;
+ }
/* Don't set a default sample size, the silverlight player refuses
* to play files with that set. Don't set a default sample duration,
avio_wb32(pb, track->entry); /* sample count */
if (mov->flags & FF_MOV_FLAG_OMIT_TFHD_OFFSET &&
- !(mov->flags & FF_MOV_FLAG_SEPARATE_MOOF) &&
- track->track_id != 1)
+ !(mov->flags & FF_MOV_FLAG_DEFAULT_BASE_MOOF) &&
+ !mov->first_trun)
avio_wb32(pb, 0); /* Later tracks follow immediately after the previous one */
else
avio_wb32(pb, moof_size + 8 + track->data_offset +
avio_wb32(pb, track->cluster[i].cts);
}
+ mov->first_trun = 0;
return update_size(pb, pos);
}
return 0;
}
+static int mov_add_tfra_entries(AVIOContext *pb, MOVMuxContext *mov, int tracks,
+ int size)
+{
+ int i;
+ for (i = 0; i < mov->nb_streams; i++) {
+ MOVTrack *track = &mov->tracks[i];
+ MOVFragmentInfo *info;
+ if ((tracks >= 0 && i != tracks) || !track->entry)
+ continue;
+ track->nb_frag_info++;
+ if (track->nb_frag_info >= track->frag_info_capacity) {
+ unsigned new_capacity = track->nb_frag_info + MOV_FRAG_INFO_ALLOC_INCREMENT;
+ if (av_reallocp_array(&track->frag_info,
+ new_capacity,
+ sizeof(*track->frag_info)))
+ return AVERROR(ENOMEM);
+ track->frag_info_capacity = new_capacity;
+ }
+ info = &track->frag_info[track->nb_frag_info - 1];
+ info->offset = avio_tell(pb);
+ info->size = size;
+ // Try to recreate the original pts for the first packet
+ // from the fields we have stored
+ info->time = track->start_dts + track->frag_start +
+ track->cluster[0].cts;
+ // If the pts is less than zero, we will have trimmed
+ // away parts of the media track using an edit list,
+ // and the corresponding start presentation time is zero.
+ if (info->time < 0)
+ info->time = 0;
+ info->duration = track->start_dts + track->track_duration -
+ track->cluster[0].dts;
+ info->tfrf_offset = 0;
+ mov_write_tfrf_tags(pb, mov, track);
+ }
+ return 0;
+}
+
+static int mov_write_tfdt_tag(AVIOContext *pb, MOVTrack *track)
+{
+ int64_t pos = avio_tell(pb);
+
+ avio_wb32(pb, 0); /* size */
+ ffio_wfourcc(pb, "tfdt");
+ avio_w8(pb, 1); /* version */
+ avio_wb24(pb, 0);
+ avio_wb64(pb, track->frag_start);
+ return update_size(pb, pos);
+}
+
static int mov_write_traf_tag(AVIOContext *pb, MOVMuxContext *mov,
MOVTrack *track, int64_t moof_offset,
int moof_size)
ffio_wfourcc(pb, "traf");
mov_write_tfhd_tag(pb, mov, track, moof_offset);
+ if (mov->mode != MODE_ISM)
+ mov_write_tfdt_tag(pb, track);
mov_write_trun_tag(pb, mov, track, moof_size);
if (mov->mode == MODE_ISM) {
mov_write_tfxd_tag(pb, track);
if (mov->ism_lookahead) {
int i, size = 16 + 4 + 1 + 16 * mov->ism_lookahead;
- track->tfrf_offset = avio_tell(pb);
+ if (track->nb_frag_info > 0) {
+ MOVFragmentInfo *info = &track->frag_info[track->nb_frag_info - 1];
+ if (!info->tfrf_offset)
+ info->tfrf_offset = avio_tell(pb);
+ }
avio_wb32(pb, 8 + size);
ffio_wfourcc(pb, "free");
for (i = 0; i < size; i++)
avio_wb32(pb, 0); /* size placeholder */
ffio_wfourcc(pb, "moof");
+ mov->first_trun = 1;
mov_write_mfhd_tag(pb, mov);
for (i = 0; i < mov->nb_streams; i++) {
return update_size(pb, pos);
}
-static int mov_write_moof_tag(AVIOContext *pb, MOVMuxContext *mov, int tracks)
+static int mov_write_sidx_tag(AVIOContext *pb,
+ MOVTrack *track, int ref_size, int total_sidx_size)
+{
+ int64_t pos = avio_tell(pb), offset_pos, end_pos;
+ int64_t presentation_time, duration, offset;
+ int starts_with_SAP, i, entries;
+
+ if (track->entry) {
+ entries = 1;
+ presentation_time = track->start_dts + track->frag_start +
+ track->cluster[0].cts;
+ duration = track->start_dts + track->track_duration -
+ track->cluster[0].dts;
+ starts_with_SAP = track->cluster[0].flags & MOV_SYNC_SAMPLE;
+ } else {
+ entries = track->nb_frag_info;
+ presentation_time = track->frag_info[0].time;
+ }
+
+ // pts<0 should be cut away using edts
+ if (presentation_time < 0)
+ presentation_time = 0;
+
+ avio_wb32(pb, 0); /* size */
+ ffio_wfourcc(pb, "sidx");
+ avio_w8(pb, 1); /* version */
+ avio_wb24(pb, 0);
+ avio_wb32(pb, track->track_id); /* reference_ID */
+ avio_wb32(pb, track->timescale); /* timescale */
+ avio_wb64(pb, presentation_time); /* earliest_presentation_time */
+ offset_pos = avio_tell(pb);
+ avio_wb64(pb, 0); /* first_offset (offset to referenced moof) */
+ avio_wb16(pb, 0); /* reserved */
+
+ avio_wb16(pb, entries); /* reference_count */
+ for (i = 0; i < entries; i++) {
+ if (!track->entry) {
+ if (i > 1 && track->frag_info[i].offset != track->frag_info[i - 1].offset + track->frag_info[i - 1].size) {
+ av_log(NULL, AV_LOG_ERROR, "Non-consecutive fragments, writing incorrect sidx\n");
+ }
+ duration = track->frag_info[i].duration;
+ ref_size = track->frag_info[i].size;
+ starts_with_SAP = 1;
+ }
+ avio_wb32(pb, (0 << 31) | (ref_size & 0x7fffffff)); /* reference_type (0 = media) | referenced_size */
+ avio_wb32(pb, duration); /* subsegment_duration */
+ avio_wb32(pb, (starts_with_SAP << 31) | (0 << 28) | 0); /* starts_with_SAP | SAP_type | SAP_delta_time */
+ }
+
+ end_pos = avio_tell(pb);
+ offset = pos + total_sidx_size - end_pos;
+ avio_seek(pb, offset_pos, SEEK_SET);
+ avio_wb64(pb, offset);
+ avio_seek(pb, end_pos, SEEK_SET);
+ return update_size(pb, pos);
+}
+
+static int mov_write_sidx_tags(AVIOContext *pb, MOVMuxContext *mov,
+ int tracks, int ref_size)
+{
+ int i, round, ret;
+ AVIOContext *avio_buf;
+ int total_size = 0;
+ for (round = 0; round < 2; round++) {
+ // First run one round to calculate the total size of all
+ // sidx atoms.
+ // This would be much simpler if we'd only write one sidx
+ // atom, for the first track in the moof.
+ if (round == 0) {
+ if ((ret = ffio_open_null_buf(&avio_buf)) < 0)
+ return ret;
+ } else {
+ avio_buf = pb;
+ }
+ for (i = 0; i < mov->nb_streams; i++) {
+ MOVTrack *track = &mov->tracks[i];
+ if (tracks >= 0 && i != tracks)
+ continue;
+ // When writing a sidx for the full file, entry is 0, but
+ // we want to include all tracks. ref_size is 0 in this case,
+ // since we read it from frag_info instead.
+ if (!track->entry && ref_size > 0)
+ continue;
+ total_size -= mov_write_sidx_tag(avio_buf, track, ref_size,
+ total_size);
+ }
+ if (round == 0)
+ total_size = ffio_close_null_buf(avio_buf);
+ }
+ return 0;
+}
+
+static int mov_write_moof_tag(AVIOContext *pb, MOVMuxContext *mov, int tracks,
+ int64_t mdat_size)
{
AVIOContext *avio_buf;
int ret, moof_size;
return ret;
mov_write_moof_tag_internal(avio_buf, mov, tracks, 0);
moof_size = ffio_close_null_buf(avio_buf);
+
+ if (mov->flags & FF_MOV_FLAG_DASH && !(mov->flags & FF_MOV_FLAG_FASTSTART))
+ mov_write_sidx_tags(pb, mov, tracks, moof_size + 8 + mdat_size);
+
+ if ((ret = mov_add_tfra_entries(pb, mov, tracks, moof_size + 8 + mdat_size)) < 0)
+ return ret;
+
return mov_write_moof_tag_internal(pb, mov, tracks, moof_size);
}
avio_wb32(pb, track->nb_frag_info);
for (i = 0; i < track->nb_frag_info; i++) {
avio_wb64(pb, track->frag_info[i].time);
- avio_wb64(pb, track->frag_info[i].offset);
+ avio_wb64(pb, track->frag_info[i].offset + track->data_offset);
avio_w8(pb, 1); /* traf number */
avio_w8(pb, 1); /* trun number */
avio_w8(pb, 1); /* sample number */
minor = has_h264 ? 0x20000 : 0x10000;
} else if (mov->mode == MODE_PSP)
ffio_wfourcc(pb, "MSNV");
+ else if (mov->mode == MODE_MP4 && mov->flags & FF_MOV_FLAG_DEFAULT_BASE_MOOF)
+ ffio_wfourcc(pb, "iso5"); // Required when using default-base-is-moof
else if (mov->mode == MODE_MP4)
ffio_wfourcc(pb, "isom");
else if (mov->mode == MODE_IPOD)
ffio_wfourcc(pb, "qt ");
else if (mov->mode == MODE_ISM) {
ffio_wfourcc(pb, "piff");
- ffio_wfourcc(pb, "iso2");
- } else {
+ } else if (!(mov->flags & FF_MOV_FLAG_DEFAULT_BASE_MOOF)) {
ffio_wfourcc(pb, "isom");
ffio_wfourcc(pb, "iso2");
if (has_h264)
ffio_wfourcc(pb, "avc1");
}
+ // We add tfdt atoms when fragmenting, signal this with the iso6 compatible
+ // brand. This is compatible with users that don't understand tfdt.
+ if (mov->flags & FF_MOV_FLAG_FRAGMENT && mov->mode != MODE_ISM)
+ ffio_wfourcc(pb, "iso6");
+
if (mov->mode == MODE_3GP)
ffio_wfourcc(pb, has_h264 ? "3gp6":"3gp4");
else if (mov->mode & MODE_3G2)
ffio_wfourcc(pb, "MSNV");
else if (mov->mode == MODE_MP4)
ffio_wfourcc(pb, "mp41");
+
+ if (mov->flags & FF_MOV_FLAG_DASH && mov->flags & FF_MOV_FLAG_FASTSTART)
+ ffio_wfourcc(pb, "dash");
+
return update_size(pb, pos);
}
}
if (write_moof) {
- MOVFragmentInfo *info;
avio_flush(s->pb);
- track->nb_frag_info++;
- if (track->nb_frag_info >= track->frag_info_capacity) {
- unsigned new_capacity = track->nb_frag_info + MOV_FRAG_INFO_ALLOC_INCREMENT;
- if (av_reallocp_array(&track->frag_info,
- new_capacity,
- sizeof(*track->frag_info)))
- return AVERROR(ENOMEM);
- track->frag_info_capacity = new_capacity;
- }
- info = &track->frag_info[track->nb_frag_info - 1];
- info->offset = avio_tell(s->pb);
- info->time = mov->tracks[i].frag_start;
- info->duration = duration;
- mov_write_tfrf_tags(s->pb, mov, track);
-
- mov_write_moof_tag(s->pb, mov, moof_tracks);
- info->tfrf_offset = track->tfrf_offset;
+
+ mov_write_moof_tag(s->pb, mov, moof_tracks, mdat_size);
mov->fragments++;
avio_wb32(s->pb, mdat_size + 8);
MOVTrack *trk = &mov->tracks[pkt->stream_index];
AVCodecContext *enc = trk->enc;
unsigned int samples_in_chunk = 0;
- int size = pkt->size;
+ int size = pkt->size, ret = 0;
uint8_t *reformatted_data = NULL;
if (trk->entry) {
samples_in_chunk = 1;
/* copy extradata if it exists */
- if (trk->vos_len == 0 && enc->extradata_size > 0) {
+ if (trk->vos_len == 0 && enc->extradata_size > 0 && !TAG_IS_AVCI(trk->tag)) {
trk->vos_len = enc->extradata_size;
trk->vos_data = av_malloc(trk->vos_len);
memcpy(trk->vos_data, enc->extradata, trk->vos_len);
}
av_log(s, AV_LOG_WARNING, "aac bitstream error\n");
}
- if (enc->codec_id == AV_CODEC_ID_H264 && trk->vos_len > 0 && *(uint8_t *)trk->vos_data != 1) {
+ if (enc->codec_id == AV_CODEC_ID_H264 && trk->vos_len > 0 && *(uint8_t *)trk->vos_data != 1 && !TAG_IS_AVCI(trk->tag)) {
/* from x264 or from bytestream h264 */
/* nal reformating needed */
if (trk->hint_track >= 0 && trk->hint_track < mov->nb_streams) {
} else {
size = ff_hevc_annexb2mp4(pb, pkt->data, pkt->size, 0, NULL);
}
+ } else if (enc->codec_id == AV_CODEC_ID_EAC3) {
+ size = handle_eac3(mov, pkt, trk);
+ if (size < 0)
+ return size;
+ else if (!size)
+ goto end;
+ avio_write(pb, pkt->data, size);
} else {
avio_write(pb, pkt->data, size);
}
/* copy frame to create needed atoms */
trk->vos_len = size;
trk->vos_data = av_malloc(size);
- if (!trk->vos_data)
- return AVERROR(ENOMEM);
+ if (!trk->vos_data) {
+ ret = AVERROR(ENOMEM);
+ goto err;
+ }
memcpy(trk->vos_data, pkt->data, size);
}
if (trk->entry >= trk->cluster_capacity) {
unsigned new_capacity = 2 * (trk->entry + MOV_INDEX_CLUSTER_SIZE);
if (av_reallocp_array(&trk->cluster, new_capacity,
- sizeof(*trk->cluster)))
- return AVERROR(ENOMEM);
+ sizeof(*trk->cluster))) {
+ ret = AVERROR(ENOMEM);
+ goto err;
+ }
trk->cluster_capacity = new_capacity;
}
trk->cluster[trk->entry].entries = samples_in_chunk;
trk->cluster[trk->entry].dts = pkt->dts;
if (!trk->entry && trk->start_dts != AV_NOPTS_VALUE) {
- /* First packet of a new fragment. We already wrote the duration
- * of the last packet of the previous fragment based on track_duration,
- * which might not exactly match our dts. Therefore adjust the dts
- * of this packet to be what the previous packets duration implies. */
- trk->cluster[trk->entry].dts = trk->start_dts + trk->track_duration;
+ if (!trk->frag_discont) {
+ /* First packet of a new fragment. We already wrote the duration
+ * of the last packet of the previous fragment based on track_duration,
+ * which might not exactly match our dts. Therefore adjust the dts
+ * of this packet to be what the previous packets duration implies. */
+ trk->cluster[trk->entry].dts = trk->start_dts + trk->track_duration;
+ } else {
+ /* New fragment, but discontinuous from previous fragments.
+ * Pretend the duration sum of the earlier fragments is
+ * pkt->dts - trk->start_dts. */
+ trk->frag_start = pkt->dts - trk->start_dts;
+ trk->frag_discont = 0;
+ }
}
- if (!trk->entry && trk->start_dts == AV_NOPTS_VALUE && !supports_edts(mov)) {
+
+ if (!trk->entry && trk->start_dts == AV_NOPTS_VALUE && !mov->use_editlist &&
+ s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_MAKE_ZERO) {
+ /* Not using edit lists and shifting the first track to start from zero.
+ * If the other streams start from a later timestamp, we won't be able
+ * to signal the difference in starting time without an edit list.
+ * Thus move the timestamp for this first sample to 0, increasing
+ * its duration instead. */
trk->cluster[trk->entry].dts = trk->start_dts = 0;
}
- if (trk->start_dts == AV_NOPTS_VALUE)
+ if (trk->start_dts == AV_NOPTS_VALUE) {
trk->start_dts = pkt->dts;
+ if (trk->frag_discont) {
+ /* Pretend the whole stream started at dts=0, with earlier framgents
+ * already written, with a duration summing up to pkt->dts. */
+ trk->frag_start = pkt->dts;
+ trk->start_dts = 0;
+ trk->frag_discont = 0;
+ } else if (pkt->dts && mov->flags & FF_MOV_FLAG_EMPTY_MOOV)
+ av_log(s, AV_LOG_WARNING,
+ "Track %d starts with a nonzero dts %"PRId64". This "
+ "currently isn't handled correctly in combination with "
+ "empty_moov.\n", pkt->stream_index, pkt->dts);
+ }
trk->track_duration = pkt->dts - trk->start_dts + pkt->duration;
trk->last_sample_is_subtitle_end = 0;
if (trk->hint_track >= 0 && trk->hint_track < mov->nb_streams)
ff_mov_add_hinted_packet(s, pkt, trk->hint_track, trk->entry,
reformatted_data, size);
+
+end:
+err:
+
av_free(reformatted_data);
- return 0;
+ return ret;
}
static int mov_write_single_packet(AVFormatContext *s, AVPacket *pkt)
if (!pkt->size)
return 0; /* Discard 0 sized packets */
+ if (mov->flags & FF_MOV_FLAG_FRAG_DISCONT) {
+ int i;
+ for (i = 0; i < s->nb_streams; i++)
+ mov->tracks[i].frag_discont = 1;
+ mov->flags &= ~FF_MOV_FLAG_FRAG_DISCONT;
+ }
+
if (trk->entry && pkt->stream_index < s->nb_streams)
frag_duration = av_rescale_q(pkt->dts - trk->cluster[0].dts,
s->streams[pkt->stream_index]->time_base,
if (mov->mode == MODE_ISM)
mov->flags |= FF_MOV_FLAG_EMPTY_MOOV | FF_MOV_FLAG_SEPARATE_MOOF |
FF_MOV_FLAG_FRAGMENT;
+ if (mov->flags & FF_MOV_FLAG_DASH)
+ mov->flags |= FF_MOV_FLAG_FRAGMENT | FF_MOV_FLAG_EMPTY_MOOV |
+ FF_MOV_FLAG_DEFAULT_BASE_MOOF;
- /* faststart: moov at the beginning of the file, if supported */
if (mov->flags & FF_MOV_FLAG_FASTSTART) {
- if ((mov->flags & FF_MOV_FLAG_FRAGMENT) ||
- (s->flags & AVFMT_FLAG_CUSTOM_IO)) {
- av_log(s, AV_LOG_WARNING, "The faststart flag is incompatible "
- "with fragmentation and custom IO, disabling faststart\n");
- mov->flags &= ~FF_MOV_FLAG_FASTSTART;
- } else
- mov->reserved_moov_size = -1;
+ mov->reserved_moov_size = -1;
+ }
+
+ if (mov->use_editlist < 0) {
+ mov->use_editlist = 1;
+ if (mov->flags & FF_MOV_FLAG_FRAGMENT) {
+ // If we can avoid needing an edit list by shifting the
+ // tracks, prefer that over (trying to) write edit lists
+ // in fragmented output.
+ if (s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_AUTO ||
+ s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_MAKE_ZERO)
+ mov->use_editlist = 0;
+ }
}
+ if (mov->flags & FF_MOV_FLAG_EMPTY_MOOV && mov->use_editlist)
+ av_log(s, AV_LOG_WARNING, "No meaningful edit list will be written when using empty_moov\n");
- if (!supports_edts(mov) && s->avoid_negative_ts < 0) {
- s->avoid_negative_ts = 2;
- }
+ if (!mov->use_editlist && s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_AUTO)
+ s->avoid_negative_ts = AVFMT_AVOID_NEG_TS_MAKE_ZERO;
/* Non-seekable output is ok if using fragmentation. If ism_lookahead
* is enabled, we don't support non-seekable output at all. */
if (st->codec->extradata_size) {
if (st->codec->codec_id == AV_CODEC_ID_DVD_SUBTITLE)
mov_create_dvd_sub_decoder_specific_info(track, st);
- else {
+ else if (!TAG_IS_AVCI(track->tag)){
track->vos_len = st->codec->extradata_size;
track->vos_data = av_malloc(track->vos_len);
memcpy(track->vos_data, st->codec->extradata, track->vos_len);
if (mov->flags & FF_MOV_FLAG_EMPTY_MOOV) {
mov_write_moov_tag(pb, mov, s);
mov->fragments++;
+ if (mov->flags & FF_MOV_FLAG_FASTSTART)
+ mov->reserved_moov_pos = avio_tell(pb);
}
return 0;
return ffio_close_null_buf(moov_buf);
}
+static int get_sidx_size(AVFormatContext *s)
+{
+ int ret;
+ AVIOContext *buf;
+ MOVMuxContext *mov = s->priv_data;
+
+ if ((ret = ffio_open_null_buf(&buf)) < 0)
+ return ret;
+ mov_write_sidx_tags(buf, mov, -1, 0);
+ return ffio_close_null_buf(buf);
+}
+
/*
* This function gets the moov size if moved to the top of the file: the chunk
* offset table can switch between stco (32-bit entries) to co64 (64-bit
return moov_size2;
}
+static int compute_sidx_size(AVFormatContext *s)
+{
+ int i, sidx_size;
+ MOVMuxContext *mov = s->priv_data;
+
+ sidx_size = get_sidx_size(s);
+ if (sidx_size < 0)
+ return sidx_size;
+
+ for (i = 0; i < mov->nb_streams; i++)
+ mov->tracks[i].data_offset += sidx_size;
+
+ return sidx_size;
+}
+
static int shift_data(AVFormatContext *s)
{
int ret = 0, moov_size;
int read_size[2];
AVIOContext *read_pb;
- moov_size = compute_moov_size(s);
+ if (mov->flags & FF_MOV_FLAG_FRAGMENT)
+ moov_size = compute_sidx_size(s);
+ else
+ moov_size = compute_moov_size(s);
if (moov_size < 0)
return moov_size;
av_log(s, AV_LOG_INFO, "Starting second pass: moving the moov atom to the beginning of the file\n");
res = shift_data(s);
if (res == 0) {
- avio_seek(s->pb, mov->reserved_moov_pos, SEEK_SET);
+ avio_seek(pb, mov->reserved_moov_pos, SEEK_SET);
mov_write_moov_tag(pb, mov, s);
}
} else if (mov->reserved_moov_size > 0) {
}
} else {
mov_flush_fragment(s);
- mov_write_mfra_tag(pb, mov);
+ for (i = 0; i < mov->nb_streams; i++)
+ mov->tracks[i].data_offset = 0;
+ if (mov->flags & FF_MOV_FLAG_FASTSTART) {
+ av_log(s, AV_LOG_INFO, "Starting second pass: inserting sidx atoms\n");
+ res = shift_data(s);
+ if (res == 0) {
+ int64_t end = avio_tell(pb);
+ avio_seek(pb, mov->reserved_moov_pos, SEEK_SET);
+ mov_write_sidx_tags(pb, mov, -1, 0);
+ avio_seek(pb, end, SEEK_SET);
+ mov_write_mfra_tag(pb, mov);
+ }
+ } else {
+ mov_write_mfra_tag(pb, mov);
+ }
}
for (i = 0; i < mov->nb_streams; i++) {
int64_t time;
int64_t duration;
int64_t tfrf_offset;
+ int size;
} MOVFragmentInfo;
typedef struct MOVTrack {
AVIOContext *mdat_buf;
int64_t data_offset;
int64_t frag_start;
- int64_t tfrf_offset;
+ int frag_discont;
int nb_frag_info;
MOVFragmentInfo *frag_info;
int packet_entry;
int slices;
} vc1_info;
+
+ void *eac3_priv;
} MOVTrack;
typedef struct MOVMuxContext {
int max_fragment_size;
int ism_lookahead;
AVIOContext *mdat_buf;
+ int first_trun;
- int use_editlist;
int video_track_timescale;
int reserved_moov_size; ///< 0 for disabled, -1 for automatic, size otherwise
int per_stream_grouping;
AVFormatContext *fc;
+
+ int use_editlist;
} MOVMuxContext;
-#define FF_MOV_FLAG_RTP_HINT 1
-#define FF_MOV_FLAG_FRAGMENT 2
-#define FF_MOV_FLAG_EMPTY_MOOV 4
-#define FF_MOV_FLAG_FRAG_KEYFRAME 8
-#define FF_MOV_FLAG_SEPARATE_MOOF 16
-#define FF_MOV_FLAG_FRAG_CUSTOM 32
-#define FF_MOV_FLAG_ISML 64
-#define FF_MOV_FLAG_FASTSTART 128
-#define FF_MOV_FLAG_OMIT_TFHD_OFFSET 256
-#define FF_MOV_FLAG_DISABLE_CHPL 512
+#define FF_MOV_FLAG_RTP_HINT (1 << 0)
+#define FF_MOV_FLAG_FRAGMENT (1 << 1)
+#define FF_MOV_FLAG_EMPTY_MOOV (1 << 2)
+#define FF_MOV_FLAG_FRAG_KEYFRAME (1 << 3)
+#define FF_MOV_FLAG_SEPARATE_MOOF (1 << 4)
+#define FF_MOV_FLAG_FRAG_CUSTOM (1 << 5)
+#define FF_MOV_FLAG_ISML (1 << 6)
+#define FF_MOV_FLAG_FASTSTART (1 << 7)
+#define FF_MOV_FLAG_OMIT_TFHD_OFFSET (1 << 8)
+#define FF_MOV_FLAG_DISABLE_CHPL (1 << 9)
+#define FF_MOV_FLAG_DEFAULT_BASE_MOOF (1 << 10)
+#define FF_MOV_FLAG_DASH (1 << 11)
+#define FF_MOV_FLAG_FRAG_DISCONT (1 << 12)
int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt);
#define XING_FLAG_FRAMES 0x01
#define XING_FLAG_SIZE 0x02
#define XING_FLAG_TOC 0x04
+#define XING_FLAC_QSCALE 0x08
#define XING_TOC_COUNT 100
(AVRational){spf, c->sample_rate},
st->time_base));
/* VBR quality */
- if(v & 8)
- avio_skip(s->pb, 4);
+ if (v & XING_FLAC_QSCALE)
+ avio_rb32(s->pb);
/* Encoder short version string */
memset(version, 0, sizeof(version));
/* Encoder delays */
v= avio_rb24(s->pb);
if(AV_RB32(version) == MKBETAG('L', 'A', 'M', 'E')
- || AV_RB32(version) == MKBETAG('L', 'a', 'v', 'f')) {
+ || AV_RB32(version) == MKBETAG('L', 'a', 'v', 'f')
+ || AV_RB32(version) == MKBETAG('L', 'a', 'v', 'c')
+ ) {
mp3->start_pad = v>>12;
mp3-> end_pad = v&4095;
st->skip_samples = mp3->start_pad + 528 + 1;
+ if (mp3->frames) {
+ st->first_discard_sample = -mp3->end_pad + 528 + 1 + mp3->frames * (int64_t)spf;
+ st->last_discard_sample = mp3->frames * (int64_t)spf;
+ }
if (!st->start_time)
st->start_time = av_rescale_q(st->skip_samples,
(AVRational){1, c->sample_rate},
int64_t pos = ie->pos + (dir > 0 ? i - 1024 : -i);
int64_t candidate = -1;
int score = 999;
+
+ if (pos < 0)
+ continue;
+
for(j=0; j<MIN_VALID; j++) {
ret = check(s, pos);
if(ret < 0)
#include "libavutil/opt.h"
#include "libavutil/dict.h"
#include "libavutil/avassert.h"
+#include "libavutil/crc.h"
+#include "libavutil/mathematics.h"
+#include "libavutil/replaygain.h"
static int id3v1_set_string(AVFormatContext *s, const char *key,
uint8_t *buf, int buf_size)
count += id3v1_set_string(s, "TIT2", buf + 3, 30 + 1); //title
count += id3v1_set_string(s, "TPE1", buf + 33, 30 + 1); //author|artist
count += id3v1_set_string(s, "TALB", buf + 63, 30 + 1); //album
- count += id3v1_set_string(s, "TDRL", buf + 93, 4 + 1); //date
+ count += id3v1_set_string(s, "TDRC", buf + 93, 4 + 1); //date
count += id3v1_set_string(s, "comment", buf + 97, 30 + 1);
if ((tag = av_dict_get(s->metadata, "TRCK", NULL, 0))) { //track
buf[125] = 0;
#define XING_NUM_BAGS 400
#define XING_TOC_SIZE 100
-// maximum size of the xing frame: offset/Xing/flags/frames/size/TOC
-#define XING_MAX_SIZE (32 + 4 + 4 + 4 + 4 + XING_TOC_SIZE)
+// size of the XING/LAME data, starting from the Xing tag
+#define XING_SIZE 156
typedef struct MP3Context {
const AVClass *class;
int write_xing;
/* xing header */
- int64_t xing_offset;
+ // a buffer containing the whole XING/LAME frame
+ uint8_t *xing_frame;
+ int xing_frame_size;
+
+ AVCRC audio_crc; // CRC of the audio data
+ uint32_t audio_size; // total size of the audio data
+
+ // offset of the XING/LAME frame in the file
+ int64_t xing_frame_offset;
+ // offset of the XING/INFO tag in the frame
+ int xing_offset;
+
int32_t frames;
int32_t size;
uint32_t want;
{
MP3Context *mp3 = s->priv_data;
AVCodecContext *codec = s->streams[mp3->audio_stream_idx]->codec;
- int32_t header;
+ AVDictionaryEntry *enc = av_dict_get(s->streams[mp3->audio_stream_idx]->metadata, "encoder", NULL, 0);
+ AVIOContext *dyn_ctx;
+ int32_t header;
MPADecodeHeader mpah;
int srate_idx, i, channels;
int bitrate_idx;
int best_bitrate_idx = -1;
int best_bitrate_error = INT_MAX;
- int xing_offset;
+ int ret;
int ver = 0;
int bytes_needed;
- const char *vendor = (s->flags & AVFMT_FLAG_BITEXACT) ? "Lavf" : LIBAVFORMAT_IDENT;
if (!s->pb->seekable || !mp3->write_xing)
return 0;
header |= mask;
avpriv_mpegaudio_decode_header(&mpah, header);
- xing_offset=xing_offtbl[mpah.lsf == 1][mpah.nb_channels == 1];
- bytes_needed = 4 // header
- + xing_offset
- + 4 // xing tag
- + 4 // frames/size/toc flags
- + 4 // frames
- + 4 // size
- + XING_TOC_SIZE // toc
- + 24
- ;
+ mp3->xing_offset = xing_offtbl[mpah.lsf == 1][mpah.nb_channels == 1] + 4;
+ bytes_needed = mp3->xing_offset + XING_SIZE;
if (bytes_needed <= mpah.frame_size)
break;
header &= ~mask;
}
- avio_wb32(s->pb, header);
+ ret = avio_open_dyn_buf(&dyn_ctx);
+ if (ret < 0)
+ return ret;
+
+ avio_wb32(dyn_ctx, header);
- ffio_fill(s->pb, 0, xing_offset);
- mp3->xing_offset = avio_tell(s->pb);
- ffio_wfourcc(s->pb, "Xing");
- avio_wb32(s->pb, 0x01 | 0x02 | 0x04); // frames / size / TOC
+ ffio_fill(dyn_ctx, 0, mp3->xing_offset - 4);
+ ffio_wfourcc(dyn_ctx, "Xing");
+ avio_wb32(dyn_ctx, 0x01 | 0x02 | 0x04 | 0x08); // frames / size / TOC / vbr scale
mp3->size = mpah.frame_size;
mp3->want=1;
mp3->seen=0;
mp3->pos=0;
- avio_wb32(s->pb, 0); // frames
- avio_wb32(s->pb, 0); // size
+ avio_wb32(dyn_ctx, 0); // frames
+ avio_wb32(dyn_ctx, 0); // size
+
+ // TOC
+ for (i = 0; i < XING_TOC_SIZE; i++)
+ avio_w8(dyn_ctx, (uint8_t)(255 * i / XING_TOC_SIZE));
+
+ // vbr quality
+ // we write it, because some (broken) tools always expect it to be present
+ avio_wb32(dyn_ctx, 0);
+
+ // encoder short version string
+ if (enc) {
+ uint8_t encoder_str[9] = { 0 };
+ if ( strlen(enc->value) > sizeof(encoder_str)
+ && !strcmp("Lavc libmp3lame", enc->value)) {
+ memcpy(encoder_str, "Lavf lame", 9);
+ } else
+ memcpy(encoder_str, enc->value, FFMIN(strlen(enc->value), sizeof(encoder_str)));
+
+ avio_write(dyn_ctx, encoder_str, sizeof(encoder_str));
+ } else
+ avio_write(dyn_ctx, "Lavf\0\0\0\0\0", 9);
+
+ avio_w8(dyn_ctx, 0); // tag revision 0 / unknown vbr method
+ avio_w8(dyn_ctx, 0); // unknown lowpass filter value
+ ffio_fill(dyn_ctx, 0, 8); // empty replaygain fields
+ avio_w8(dyn_ctx, 0); // unknown encoding flags
+ avio_w8(dyn_ctx, 0); // unknown abr/minimal bitrate
+
+ // encoder delay
+ if (codec->initial_padding - 528 - 1 >= 1 << 12) {
+ av_log(s, AV_LOG_WARNING, "Too many samples of initial padding.\n");
+ }
+ avio_wb24(dyn_ctx, FFMAX(codec->initial_padding - 528 - 1, 0)<<12);
+
+ avio_w8(dyn_ctx, 0); // misc
+ avio_w8(dyn_ctx, 0); // mp3gain
+ avio_wb16(dyn_ctx, 0); // preset
- // toc
- for (i = 0; i < XING_TOC_SIZE; ++i)
- avio_w8(s->pb, (uint8_t)(255 * i / XING_TOC_SIZE));
+ // audio length and CRCs (will be updated later)
+ avio_wb32(dyn_ctx, 0); // music length
+ avio_wb16(dyn_ctx, 0); // music crc
+ avio_wb16(dyn_ctx, 0); // tag crc
- for (i = 0; i < strlen(vendor); ++i)
- avio_w8(s->pb, vendor[i]);
- for (; i < 21; ++i)
- avio_w8(s->pb, 0);
- avio_wb24(s->pb, FFMAX(codec->delay - 528 - 1, 0)<<12);
+ ffio_fill(dyn_ctx, 0, mpah.frame_size - bytes_needed);
- ffio_fill(s->pb, 0, mpah.frame_size - bytes_needed);
+ mp3->xing_frame_size = avio_close_dyn_buf(dyn_ctx, &mp3->xing_frame);
+ mp3->xing_frame_offset = avio_tell(s->pb);
+ avio_write(s->pb, mp3->xing_frame, mp3->xing_frame_size);
+
+ mp3->audio_size = mp3->xing_frame_size;
return 0;
}
return 0;
#endif
- if (mp3->xing_offset)
+ if (mp3->xing_offset) {
mp3_xing_add_frame(mp3, pkt);
+ mp3->audio_size += pkt->size;
+ mp3->audio_crc = av_crc(av_crc_get_table(AV_CRC_16_ANSI_LE),
+ mp3->audio_crc, pkt->data, pkt->size);
+ }
}
return ff_raw_write_packet(s, pkt);
static void mp3_update_xing(AVFormatContext *s)
{
MP3Context *mp3 = s->priv_data;
- int i;
+ AVReplayGain *rg;
+ uint16_t tag_crc;
+ uint8_t *toc;
+ int i, rg_size;
/* replace "Xing" identification string with "Info" for CBR files. */
- if (!mp3->has_variable_bitrate) {
- avio_seek(s->pb, mp3->xing_offset, SEEK_SET);
- ffio_wfourcc(s->pb, "Info");
- }
+ if (!mp3->has_variable_bitrate)
+ AV_WL32(mp3->xing_frame + mp3->xing_offset, MKTAG('I', 'n', 'f', 'o'));
- avio_seek(s->pb, mp3->xing_offset + 8, SEEK_SET);
- avio_wb32(s->pb, mp3->frames);
- avio_wb32(s->pb, mp3->size);
-
- avio_w8(s->pb, 0); // first toc entry has to be zero.
+ AV_WB32(mp3->xing_frame + mp3->xing_offset + 8, mp3->frames);
+ AV_WB32(mp3->xing_frame + mp3->xing_offset + 12, mp3->size);
+ toc = mp3->xing_frame + mp3->xing_offset + 16;
+ toc[0] = 0; // first toc entry has to be zero.
for (i = 1; i < XING_TOC_SIZE; ++i) {
int j = i * mp3->pos / XING_TOC_SIZE;
int seek_point = 256LL * mp3->bag[j] / mp3->size;
- avio_w8(s->pb, FFMIN(seek_point, 255));
+ toc[i] = FFMIN(seek_point, 255);
}
+ /* write replaygain */
+ rg = (AVReplayGain*)av_stream_get_side_data(s->streams[0], AV_PKT_DATA_REPLAYGAIN,
+ &rg_size);
+ if (rg && rg_size >= sizeof(*rg)) {
+ uint16_t val;
+
+ AV_WB32(mp3->xing_frame + mp3->xing_offset + 131,
+ av_rescale(rg->track_peak, 1 << 23, 100000));
+
+ if (rg->track_gain != INT32_MIN) {
+ val = FFABS(rg->track_gain / 10000) & ((1 << 9) - 1);
+ val |= (rg->track_gain < 0) << 9;
+ val |= 1 << 13;
+ AV_WB16(mp3->xing_frame + mp3->xing_offset + 135, val);
+ }
+
+ if (rg->album_gain != INT32_MIN) {
+ val = FFABS(rg->album_gain / 10000) & ((1 << 9) - 1);
+ val |= (rg->album_gain < 0) << 9;
+ val |= 1 << 14;
+ AV_WB16(mp3->xing_frame + mp3->xing_offset + 137, val);
+ }
+ }
+
+ AV_WB32(mp3->xing_frame + mp3->xing_offset + XING_SIZE - 8, mp3->audio_size);
+ AV_WB16(mp3->xing_frame + mp3->xing_offset + XING_SIZE - 4, mp3->audio_crc);
+
+ tag_crc = av_crc(av_crc_get_table(AV_CRC_16_ANSI_LE), 0, mp3->xing_frame, 190);
+ AV_WB16(mp3->xing_frame + mp3->xing_offset + XING_SIZE - 2, tag_crc);
+
+ avio_seek(s->pb, mp3->xing_frame_offset, SEEK_SET);
+ avio_write(s->pb, mp3->xing_frame, mp3->xing_frame_size);
avio_seek(s->pb, 0, SEEK_END);
}
if (mp3->xing_offset)
mp3_update_xing(s);
+ av_freep(&mp3->xing_frame);
+
return 0;
}
int stream_id = -1;
char id[64] = {0};
char alt[MAX_LINE_SIZE] = {0};
+ AVInputFormat *iformat;
sub_name = av_strdup(s->filename);
fname_len = strlen(sub_name);
}
memcpy(ext, !strncmp(ext, "IDX", 3) ? "SUB" : "sub", 3);
av_log(s, AV_LOG_VERBOSE, "IDX/SUB: %s -> %s\n", s->filename, sub_name);
- ret = avformat_open_input(&vobsub->sub_ctx, sub_name, &ff_mpegps_demuxer, NULL);
+
+ if (!(iformat = av_find_input_format("mpeg"))) {
+ ret = AVERROR_DEMUXER_NOT_FOUND;
+ goto end;
+ }
+
+ vobsub->sub_ctx = avformat_alloc_context();
+ if (!vobsub->sub_ctx) {
+ ret = AVERROR(ENOMEM);
+ goto end;
+ }
+
+ if ((ret = ff_copy_whitelists(vobsub->sub_ctx, s)) < 0)
+ goto end;
+
+ ret = avformat_open_input(&vobsub->sub_ctx, sub_name, iformat, NULL);
if (ret < 0) {
av_log(s, AV_LOG_ERROR, "Unable to open %s as MPEG subtitles\n", sub_name);
goto end;
es_size -= stream->premux_packet->unwritten_size;
stream->premux_packet = stream->premux_packet->next;
}
- if (es_size)
+ if (es_size) {
+ av_assert0(stream->premux_packet);
stream->premux_packet->unwritten_size -= es_size;
+ }
if (remove_decoded_packets(ctx, s->last_scr) < 0)
return -1;
#include "libavutil/avassert.h"
#include "libavcodec/bytestream.h"
#include "libavcodec/get_bits.h"
+#include "libavcodec/opus.h"
#include "avformat.h"
#include "mpegts.h"
#include "internal.h"
int skip_changes;
int skip_clear;
+ int scan_all_pmts;
+
int resync_size;
/******************************************/
{.i64 = 1}, 0, 1, AV_OPT_FLAG_DECODING_PARAM },
{"ts_packetsize", "Output option carrying the raw packet size.", offsetof(MpegTSContext, raw_packet_size), AV_OPT_TYPE_INT,
{.i64 = 0}, 0, 0, AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_EXPORT | AV_OPT_FLAG_READONLY },
+ {"scan_all_pmts", "Scan and combine all PMTs", offsetof(MpegTSContext, scan_all_pmts), AV_OPT_TYPE_INT,
+ { .i64 = -1}, -1, 1, AV_OPT_FLAG_DECODING_PARAM },
{"skip_changes", "Skip changing / adding streams / programs.", offsetof(MpegTSContext, skip_changes), AV_OPT_TYPE_INT,
{.i64 = 0}, 0, 1, 0 },
{"skip_clear", "Skip clearing programs.", offsetof(MpegTSContext, skip_clear), AV_OPT_TYPE_INT,
unsigned int pid)
{
struct Program *p = get_program(ts, programid);
+ int i;
if (!p)
return;
if (p->nb_pids >= MAX_PIDS_PER_PROGRAM)
return;
+
+ for (i = 0; i < p->nb_pids; i++)
+ if (p->pids[i] == pid)
+ return;
+
p->pids[p->nb_pids++] = pid;
}
{ 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 },
+ { MKTAG('O', 'p', 'u', 's'), AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_OPUS },
{ 0 },
};
av_free(mp4_descr[i].dec_config_descr);
}
+static const uint8_t opus_coupled_stream_cnt[9] = {
+ 1, 0, 1, 1, 2, 2, 2, 3, 3
+};
+
+static const uint8_t opus_channel_map[8][8] = {
+ { 0 },
+ { 0,1 },
+ { 0,2,1 },
+ { 0,1,2,3 },
+ { 0,4,1,2,3 },
+ { 0,4,1,2,3,5 },
+ { 0,4,1,2,3,5,6 },
+ { 0,6,1,2,3,4,5,7 },
+};
+
int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type,
const uint8_t **pp, const uint8_t *desc_list_end,
Mp4Descr *mp4_descr, int mp4_descr_count, int pid,
MpegTSContext *ts)
{
const uint8_t *desc_end;
- int desc_len, desc_tag, desc_es_id;
+ int desc_len, desc_tag, desc_es_id, ext_desc_tag, channels, channel_config_code;
char language[252];
int i;
mpegts_find_stream_type(st, st->codec->codec_tag, METADATA_types);
}
break;
+ case 0x7f: /* DVB extension descriptor */
+ ext_desc_tag = get8(pp, desc_end);
+ if (ext_desc_tag < 0)
+ return AVERROR_INVALIDDATA;
+ if (st->codec->codec_id == AV_CODEC_ID_OPUS &&
+ ext_desc_tag == 0x80) { /* User defined (provisional Opus) */
+ if (!st->codec->extradata) {
+ st->codec->extradata = av_mallocz(sizeof(opus_default_extradata) +
+ FF_INPUT_BUFFER_PADDING_SIZE);
+ if (!st->codec->extradata)
+ return AVERROR(ENOMEM);
+
+ st->codec->extradata_size = sizeof(opus_default_extradata);
+ memcpy(st->codec->extradata, opus_default_extradata, sizeof(opus_default_extradata));
+
+ channel_config_code = get8(pp, desc_end);
+ if (channel_config_code < 0)
+ return AVERROR_INVALIDDATA;
+ if (channel_config_code <= 0x8) {
+ st->codec->extradata[9] = channels = channel_config_code ? channel_config_code : 2;
+ st->codec->extradata[18] = channels > 2;
+ st->codec->extradata[19] = channel_config_code;
+ if (channel_config_code == 0) { /* Dual Mono */
+ st->codec->extradata[18] = 255; /* Mapping */
+ st->codec->extradata[19] = 2; /* Stream Count */
+ }
+ st->codec->extradata[20] = opus_coupled_stream_cnt[channel_config_code];
+ memcpy(&st->codec->extradata[21], opus_channel_map[channels - 1], channels);
+ } else {
+ avpriv_request_sample(fc, "Opus in MPEG-TS - channel_config_code > 0x8");
+ }
+ st->need_parsing = AVSTREAM_PARSE_FULL;
+ }
+ }
+ break;
default:
break;
}
if (parse_section_header(h, &p, p_end) < 0)
return;
- av_dlog(ts->stream, "sid=0x%x sec_num=%d/%d\n",
- h->id, h->sec_num, h->last_sec_num);
+ av_dlog(ts->stream, "sid=0x%x sec_num=%d/%d version=%d\n",
+ h->id, h->sec_num, h->last_sec_num, h->version);
if (h->tid != PMT_TID)
return;
- if (ts->skip_changes)
+ if (!ts->scan_all_pmts && ts->skip_changes)
return;
- clear_program(ts, h->id);
+ if (!ts->skip_clear)
+ clear_program(ts, h->id);
+
pcr_pid = get16(&p, p_end);
if (pcr_pid < 0)
return;
} else {
MpegTSFilter *fil = ts->pids[pmt_pid];
program = av_new_program(ts->stream, sid);
- program->program_num = sid;
- program->pmt_pid = pmt_pid;
+ if (program) {
+ program->program_num = sid;
+ program->pmt_pid = pmt_pid;
+ }
if (fil)
if ( fil->type != MPEGTS_SECTION
|| fil->pid != pmt_pid
// stop find_stream_info from waiting for more streams
// when all programs have received a PMT
- if (ts->stream->ctx_flags & AVFMTCTX_NOHEADER) {
+ if (ts->stream->ctx_flags & AVFMTCTX_NOHEADER && ts->scan_all_pmts <= 0) {
int i;
for (i = 0; i < ts->nb_prg; i++) {
if (!ts->prg[i].pmt_found)
break;
}
if (i == ts->nb_prg && ts->nb_prg > 0) {
- if (ts->stream->nb_streams > 1 || pos > 100000) {
+ int types = 0;
+ for (i = 0; i < ts->stream->nb_streams; i++) {
+ AVStream *st = ts->stream->streams[i];
+ types |= 1<<st->codec->codec_type;
+ }
+ if ((types & (1<<AVMEDIA_TYPE_AUDIO) && types & (1<<AVMEDIA_TYPE_VIDEO)) || pos > 100000) {
av_log(ts->stream, AV_LOG_DEBUG, "All programs have pmt, headers found\n");
ts->stream->ctx_flags &= ~AVFMTCTX_NOHEADER;
}
uint32_t tp_extra_header = pcr % 0x3fffffff;
tp_extra_header = AV_RB32(&tp_extra_header);
avio_write(s->pb, (unsigned char *) &tp_extra_header,
- sizeof(tp_extra_header));
+ sizeof(tp_extra_header));
}
}
ret = avcodec_copy_context(ast->codec, st->codec);
if (ret != 0)
goto fail;
+ ast->time_base = st->time_base;
ret = avformat_write_header(ts_st->amux, NULL);
if (ret < 0)
goto fail;
"('-bsf:v h264_mp4toannexb' option with ffmpeg)\n");
return AVERROR_INVALIDDATA;
}
- av_log(s, AV_LOG_WARNING, "H.264 bitstream error, startcode missing\n");
+ av_log(s, AV_LOG_WARNING, "H.264 bitstream error, startcode missing, size %d", pkt->size);
+ if (pkt->size) av_log(s, AV_LOG_WARNING, " data %08X", AV_RB32(pkt->data));
+ av_log(s, AV_LOG_WARNING, "\n");
}
return 0;
}
av_log(s, AV_LOG_ERROR, "HEVC bitstream malformed, no startcode found\n");
return AVERROR_PATCHWELCOME;
}
- av_log(s, AV_LOG_WARNING, "HEVC bitstream error, startcode missing\n");
+ av_log(s, AV_LOG_WARNING, "HEVC bitstream error, startcode missing, size %d", pkt->size);
+ if (pkt->size) av_log(s, AV_LOG_WARNING, " data %08X", AV_RB32(pkt->data));
+ av_log(s, AV_LOG_WARNING, "\n");
}
return 0;
}
{ .i64 = 0x1000 }, 0x0010, 0x1f00, AV_OPT_FLAG_ENCODING_PARAM },
{ "mpegts_start_pid", "Set the first pid.",
offsetof(MpegTSWrite, start_pid), AV_OPT_TYPE_INT,
- { .i64 = 0x0100 }, 0x0100, 0x0f00, AV_OPT_FLAG_ENCODING_PARAM },
+ { .i64 = 0x0100 }, 0x0020, 0x0f00, AV_OPT_FLAG_ENCODING_PARAM },
{ "mpegts_m2ts_mode", "Enable m2ts mode.",
offsetof(MpegTSWrite, m2ts_mode), AV_OPT_TYPE_INT,
{ .i64 = -1 }, -1, 1, AV_OPT_FLAG_ENCODING_PARAM },
* 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 "avformat.h"
/* Multipart JPEG */
#define BOUNDARY_TAG "ffserver"
+typedef struct MPJPEGContext {
+ AVClass *class;
+ char *boundary_tag;
+} MPJPEGContext;
+
static int mpjpeg_write_header(AVFormatContext *s)
{
+ MPJPEGContext *mpj = s->priv_data;
uint8_t buf1[256];
- snprintf(buf1, sizeof(buf1), "--%s\r\n", BOUNDARY_TAG);
+ snprintf(buf1, sizeof(buf1), "--%s\r\n", mpj->boundary_tag);
avio_write(s->pb, buf1, strlen(buf1));
avio_flush(s->pb);
return 0;
static int mpjpeg_write_packet(AVFormatContext *s, AVPacket *pkt)
{
+ MPJPEGContext *mpj = s->priv_data;
uint8_t buf1[256];
snprintf(buf1, sizeof(buf1), "Content-type: image/jpeg\r\n");
avio_write(s->pb, buf1, strlen(buf1));
avio_write(s->pb, pkt->data, pkt->size);
- snprintf(buf1, sizeof(buf1), "\r\n--%s\r\n", BOUNDARY_TAG);
+ snprintf(buf1, sizeof(buf1), "\r\n--%s\r\n", mpj->boundary_tag);
avio_write(s->pb, buf1, strlen(buf1));
return 0;
}
return 0;
}
+static const AVOption options[] = {
+ { "boundary_tag", "Boundary tag", offsetof(MPJPEGContext, boundary_tag), AV_OPT_TYPE_STRING, {.str = BOUNDARY_TAG}, .flags = AV_OPT_FLAG_ENCODING_PARAM },
+ { NULL },
+};
+
+static const AVClass mpjpeg_muxer_class = {
+ .class_name = "mpjpeg_muxer",
+ .item_name = av_default_item_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
AVOutputFormat ff_mpjpeg_muxer = {
.name = "mpjpeg",
.long_name = NULL_IF_CONFIG_SMALL("MIME multipart JPEG"),
.mime_type = "multipart/x-mixed-replace;boundary=" BOUNDARY_TAG,
.extensions = "mjpg",
+ .priv_data_size = sizeof(MPJPEGContext),
.audio_codec = AV_CODEC_ID_NONE,
.video_codec = AV_CODEC_ID_MJPEG,
.write_header = mpjpeg_write_header,
.write_packet = mpjpeg_write_packet,
.write_trailer = mpjpeg_write_trailer,
.flags = AVFMT_NOTIMESTAMPS,
+ .priv_class = &mpjpeg_muxer_class,
};
mtv->audio_identifier = avio_rl24(pb);
mtv->audio_br = avio_rl16(pb);
mtv->img_colorfmt = avio_rl24(pb);
- mtv->img_bpp = avio_r8(pb)>>3;
+ mtv->img_bpp = avio_r8(pb);
mtv->img_width = avio_rl16(pb);
mtv->img_height = avio_rl16(pb);
mtv->img_segment_size = avio_rl16(pb);
/* Calculate width and height if missing from header */
- if(!mtv->img_width && mtv->img_height)
- mtv->img_width=mtv->img_segment_size / (mtv->img_bpp)
+ if (!mtv->img_width && mtv->img_height > 0 && mtv->img_bpp >= 8)
+ mtv->img_width=mtv->img_segment_size / (mtv->img_bpp>>3)
/ mtv->img_height;
- if(!mtv->img_height && mtv->img_width)
- mtv->img_height=mtv->img_segment_size / (mtv->img_bpp)
+ if (!mtv->img_height && mtv->img_width > 0 && mtv->img_bpp >= 8)
+ mtv->img_height=mtv->img_segment_size / (mtv->img_bpp>>3)
/ mtv->img_width;
if(!mtv->img_height || !mtv->img_width || !mtv->img_segment_size){
av_log(s, AV_LOG_ERROR, "width or height or segment_size is invalid and I cannot calculate them from other information\n");
- return AVERROR(EINVAL);
+ return AVERROR_INVALIDDATA;
}
avio_skip(pb, 4);
return ret;
}
-#if FF_API_ALLOC_OUTPUT_CONTEXT
-AVFormatContext *avformat_alloc_output_context(const char *format,
- AVOutputFormat *oformat, const char *filename)
-{
- AVFormatContext *avctx;
- int ret = avformat_alloc_output_context2(&avctx, oformat, format, filename);
- return ret < 0 ? NULL : avctx;
-}
-#endif
-
static int validate_codec_tag(AVFormatContext *s, AVStream *st)
{
const AVCodecTag *avctag;
}
if (id != AV_CODEC_ID_NONE)
return 0;
- if (tag >= 0 && (st->codec->strict_std_compliance >= FF_COMPLIANCE_NORMAL))
+ if (tag >= 0 && (s->strict_std_compliance >= FF_COMPLIANCE_NORMAL))
return 0;
return 1;
}
return ret;
if (s->avoid_negative_ts < 0) {
+ av_assert2(s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_AUTO);
if (s->oformat->flags & (AVFMT_TS_NEGATIVE | AVFMT_NOTIMESTAMPS)) {
s->avoid_negative_ts = 0;
} else
- s->avoid_negative_ts = 1;
+ s->avoid_negative_ts = AVFMT_AVOID_NEG_TS_MAKE_NON_NEGATIVE;
}
return 0;
/* duration field */
if (pkt->duration == 0) {
- ff_compute_frame_duration(&num, &den, st, NULL, pkt);
+ ff_compute_frame_duration(s, &num, &den, st, NULL, pkt);
if (den && num) {
pkt->duration = av_rescale(1, num * (int64_t)st->time_base.den * st->codec->ticks_per_frame, den * (int64_t)st->time_base.num);
}
return AVERROR(EINVAL);
}
if (pkt->dts != AV_NOPTS_VALUE && pkt->pts != AV_NOPTS_VALUE && pkt->pts < pkt->dts) {
- av_log(s, AV_LOG_ERROR, "pts (%s) < dts (%s) in stream %d\n",
- av_ts2str(pkt->pts), av_ts2str(pkt->dts), st->index);
+ av_log(s, AV_LOG_ERROR,
+ "pts (%s) < dts (%s) in stream %d\n",
+ av_ts2str(pkt->pts), av_ts2str(pkt->dts),
+ st->index);
return AVERROR(EINVAL);
}
AVStream *st = s->streams[pkt->stream_index];
int64_t offset = st->mux_ts_offset;
- if ((pkt->dts < 0 || s->avoid_negative_ts == 2) && pkt->dts != AV_NOPTS_VALUE && !s->offset) {
+ if (s->offset == AV_NOPTS_VALUE && pkt->dts != AV_NOPTS_VALUE &&
+ (pkt->dts < 0 || s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_MAKE_ZERO)) {
s->offset = -pkt->dts;
s->offset_timebase = st->time_base;
}
- if (s->offset && !offset) {
+ if (s->offset != AV_NOPTS_VALUE && !offset) {
offset = st->mux_ts_offset =
av_rescale_q_rnd(s->offset,
s->offset_timebase,
if (pkt->pts != AV_NOPTS_VALUE)
pkt->pts += offset;
- av_assert2(pkt->dts == AV_NOPTS_VALUE || pkt->dts >= 0);
+ av_assert2(pkt->dts == AV_NOPTS_VALUE || pkt->dts >= 0 || s->max_interleave_delta > 0);
+ if (pkt->dts != AV_NOPTS_VALUE && pkt->dts < 0) {
+ av_log(s, AV_LOG_WARNING,
+ "Packets poorly interleaved, failed to avoid negative "
+ "timestamp %s in stream %d.\n"
+ "Try -max_interleave_delta 0 as a possible workaround.\n",
+ av_ts2str(pkt->dts),
+ pkt->stream_index
+ );
+ }
}
did_split = av_packet_split_side_data(pkt);
for (;; ) {
AVPacket pkt;
ret = interleave_packet(s, &pkt, NULL, 1);
- if (ret < 0) //FIXME cleanup needed for ret<0 ?
+ if (ret < 0)
goto fail;
if (!ret)
break;
goto fail;
}
+fail:
if (s->oformat->write_trailer)
+ if (ret >= 0) {
ret = s->oformat->write_trailer(s);
+ } else {
+ s->oformat->write_trailer(s);
+ }
-fail:
if (s->pb)
avio_flush(s->pb);
if (ret == 0)
static char *var_read_string(AVIOContext *pb, int size)
{
int n;
- char *str = av_malloc(size + 1);
+ char *str;
+
+ if (size < 0 || size == INT_MAX)
+ return NULL;
+
+ str = av_malloc(size + 1);
if (!str)
return NULL;
n = avio_get_str(pb, size, str, size + 1);
return 0;
}
-static void read_table(AVFormatContext *avctx, AVStream *st,
+static int read_table(AVFormatContext *avctx, AVStream *st,
int (*parse)(AVFormatContext *avctx, AVStream *st,
const char *name, int size))
{
avio_read(pb, name, 16);
name[sizeof(name) - 1] = 0;
size = avio_rb32(pb);
+ if (size < 0) {
+ av_log(avctx, AV_LOG_ERROR, "entry size %d is invalid\n", size);
+ return AVERROR_INVALIDDATA;
+ }
if (parse(avctx, st, name, size) < 0) {
avpriv_request_sample(avctx, "Variable %s", name);
avio_skip(pb, size);
}
}
+ return 0;
}
static void read_index(AVIOContext *pb, AVStream *st)
AVIOContext *pb = avctx->pb;
AVStream *ast = NULL, *vst = NULL; //initialization to suppress warning
int version, i;
+ int ret;
avio_skip(pb, 4);
} else if (!version && avio_rb16(pb) == 3) {
avio_skip(pb, 4);
- read_table(avctx, NULL, parse_global_var);
+ if ((ret = read_table(avctx, NULL, parse_global_var)) < 0)
+ return ret;
if (mv->nb_audio_tracks > 1) {
avpriv_request_sample(avctx, "Multiple audio streams support");
if (!ast)
return AVERROR(ENOMEM);
ast->codec->codec_type = AVMEDIA_TYPE_AUDIO;
- read_table(avctx, ast, parse_audio_var);
+ if ((read_table(avctx, ast, parse_audio_var)) < 0)
+ return ret;
if (mv->acompression == 100 &&
mv->aformat == AUDIO_FORMAT_SIGNED &&
ast->codec->bits_per_coded_sample == 16) {
if (!vst)
return AVERROR(ENOMEM);
vst->codec->codec_type = AVMEDIA_TYPE_VIDEO;
- read_table(avctx, vst, parse_video_var);
+ if ((ret = read_table(avctx, vst, parse_video_var))<0)
+ return ret;
}
if (mv->nb_audio_tracks)
{AV_PIX_FMT_RGB565BE,{'R', 5, 'G', 6, 'B', 5 }},
{AV_PIX_FMT_RGBA, {'R', 8, 'G', 8, 'B', 8, 'A', 8 }},
{AV_PIX_FMT_PAL8, {'P', 8 }},
+ {AV_PIX_FMT_GRAY8, {'A', 8 }},
};
static const int num_pixel_layouts = FF_ARRAY_ELEMS(ff_mxf_pixel_layouts);
SourcePackage,
SourceClip,
TimecodeComponent,
+ PulldownComponent,
Sequence,
MultipleDescriptor,
Descriptor,
IndexTableSegment,
EssenceContainerData,
TypeBottom,// add metadata type before this
+ EssenceGroup,
};
enum MXFFrameLayout {
int64_t header_byte_count;
int64_t index_byte_count;
int pack_length;
+ int64_t pack_ofs; ///< absolute offset of pack in file, including run-in
} MXFPartition;
typedef struct {
AVTimecode tc;
} MXFTimecodeComponent;
+typedef struct {
+ UID uid;
+ enum MXFMetadataSetType type;
+ UID input_segment_ref;
+} MXFPulldownComponent;
+
+typedef struct {
+ UID uid;
+ enum MXFMetadataSetType type;
+ UID *structural_components_refs;
+ int structural_components_count;
+ int64_t duration;
+} MXFEssenceGroup;
+
typedef struct {
UID uid;
enum MXFMetadataSetType type;
int field_dominance;
int channels;
int bits_per_sample;
+ int64_t duration; /* ContainerDuration optional property */
unsigned int component_depth;
unsigned int horiz_subsampling;
unsigned int vert_subsampling;
int tracks_count;
MXFDescriptor *descriptor; /* only one */
UID descriptor_ref;
+ char *name;
} MXFPackage;
typedef struct {
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;
av_log(mxf->fc, AV_LOG_ERROR, "item_num %d is too large\n", item_num);
return AVERROR_INVALIDDATA;
}
+ if (mxf->local_tags)
+ av_log(mxf->fc, AV_LOG_VERBOSE, "Multiple primer packs\n");
+ av_free(mxf->local_tags);
+ mxf->local_tags_count = 0;
mxf->local_tags = av_calloc(item_num, item_len);
if (!mxf->local_tags)
return AVERROR(ENOMEM);
memset(partition, 0, sizeof(*partition));
mxf->partitions_count++;
partition->pack_length = avio_tell(pb) - klv_offset + size;
+ partition->pack_ofs = klv_offset;
switch(uid[13]) {
case 2:
partition->index_sid, partition->body_sid);
/* sanity check PreviousPartition if set */
+ //NOTE: this isn't actually enough, see mxf_seek_to_previous_partition()
if (partition->previous_partition &&
mxf->run_in + partition->previous_partition >= klv_offset) {
av_log(mxf->fc, AV_LOG_ERROR,
MXFContext *mxf = arg;
switch (tag) {
case 0x1901:
+ if (mxf->packages_refs)
+ av_log(mxf->fc, AV_LOG_VERBOSE, "Multiple packages_refs\n");
+ av_free(mxf->packages_refs);
mxf->packages_count = avio_rb32(pb);
mxf->packages_refs = av_calloc(mxf->packages_count, sizeof(UID));
if (!mxf->packages_refs)
return 0;
}
-static int mxf_read_material_package(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset)
-{
- MXFPackage *package = arg;
- switch(tag) {
- case 0x4403:
- package->tracks_count = avio_rb32(pb);
- package->tracks_refs = av_calloc(package->tracks_count, sizeof(UID));
- if (!package->tracks_refs)
- return AVERROR(ENOMEM);
- avio_skip(pb, 4); /* useless size of objects, always 16 according to specs */
- avio_read(pb, (uint8_t *)package->tracks_refs, package->tracks_count * sizeof(UID));
- break;
- }
- return 0;
-}
-
static int mxf_read_timecode_component(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset)
{
MXFTimecodeComponent *mxf_timecode = arg;
return 0;
}
+static int mxf_read_pulldown_component(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset)
+{
+ MXFPulldownComponent *mxf_pulldown = arg;
+ switch(tag) {
+ case 0x0d01:
+ avio_read(pb, mxf_pulldown->input_segment_ref, 16);
+ break;
+ }
+ return 0;
+}
+
static int mxf_read_track(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset)
{
MXFTrack *track = arg;
case 0x1001:
sequence->structural_components_count = avio_rb32(pb);
sequence->structural_components_refs = av_calloc(sequence->structural_components_count, sizeof(UID));
- if (!sequence->structural_components_refs)
+ if (!sequence->structural_components_refs) {
+ sequence->structural_components_count = 0;
return AVERROR(ENOMEM);
+ }
avio_skip(pb, 4); /* useless size of objects, always 16 according to specs */
avio_read(pb, (uint8_t *)sequence->structural_components_refs, sequence->structural_components_count * sizeof(UID));
break;
return 0;
}
-static int mxf_read_source_package(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset)
+static int mxf_read_essence_group(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset)
+{
+ MXFEssenceGroup *essence_group = arg;
+ switch (tag) {
+ case 0x0202:
+ essence_group->duration = avio_rb64(pb);
+ break;
+ case 0x0501:
+ essence_group->structural_components_count = avio_rb32(pb);
+ essence_group->structural_components_refs = av_calloc(essence_group->structural_components_count, sizeof(UID));
+ if (!essence_group->structural_components_refs) {
+ essence_group->structural_components_count = 0;
+ return AVERROR(ENOMEM);
+ }
+ avio_skip(pb, 4); /* useless size of objects, always 16 according to specs */
+ avio_read(pb, (uint8_t *)essence_group->structural_components_refs, essence_group->structural_components_count * sizeof(UID));
+ break;
+ }
+ return 0;
+}
+
+static int mxf_read_utf16_string(AVIOContext *pb, int size, char** str)
+{
+ int ret;
+ size_t buf_size;
+
+ if (size < 0)
+ return AVERROR(EINVAL);
+
+ buf_size = size + size / 2 + 1;
+ *str = av_malloc(buf_size);
+ if (!*str)
+ return AVERROR(ENOMEM);
+
+ if ((ret = avio_get_str16be(pb, size, *str, buf_size)) < 0) {
+ av_freep(str);
+ return ret;
+ }
+
+ return ret;
+}
+
+static int mxf_read_package(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset)
{
MXFPackage *package = arg;
switch(tag) {
case 0x4701:
avio_read(pb, package->descriptor_ref, 16);
break;
+ case 0x4402:
+ return mxf_read_utf16_string(pb, size, &package->name);
}
return 0;
}
static int mxf_read_generic_descriptor(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset)
{
MXFDescriptor *descriptor = arg;
- descriptor->pix_fmt = AV_PIX_FMT_NONE;
switch(tag) {
case 0x3F01:
descriptor->sub_descriptors_count = avio_rb32(pb);
avio_skip(pb, 4); /* useless size of objects, always 16 according to specs */
avio_read(pb, (uint8_t *)descriptor->sub_descriptors_refs, descriptor->sub_descriptors_count * sizeof(UID));
break;
+ case 0x3002: /* ContainerDuration */
+ descriptor->duration = avio_rb64(pb);
+ break;
case 0x3004:
avio_read(pb, descriptor->essence_container_ul, 16);
break;
{ { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x02,0x0d,0x01,0x03,0x01,0x02,0x04,0x60,0x01 }, 14, AV_CODEC_ID_MPEG2VIDEO }, /* MPEG-ES Frame wrapped */
{ { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x01,0x0d,0x01,0x03,0x01,0x02,0x02,0x41,0x01 }, 14, AV_CODEC_ID_DVVIDEO }, /* DV 625 25mbps */
{ { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x01,0x0d,0x01,0x03,0x01,0x02,0x05,0x00,0x00 }, 14, AV_CODEC_ID_RAWVIDEO }, /* Uncompressed Picture */
+ { { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0xff,0x4b,0x46,0x41,0x41,0x00,0x0d,0x4d,0x4f }, 14, AV_CODEC_ID_RAWVIDEO }, /* Legacy ?? Uncompressed Picture */
{ { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, 0, AV_CODEC_ID_NONE },
};
&descriptor->essence_codec_ul)->id != AV_CODEC_ID_NONE;
}
+static int mxf_uid_to_str(UID uid, char **str)
+{
+ int i;
+ char *p;
+ p = *str = av_mallocz(sizeof(UID) * 2 + 4 + 1);
+ if (!p)
+ return AVERROR(ENOMEM);
+ for (i = 0; i < sizeof(UID); i++) {
+ snprintf(p, 2 + 1, "%.2x", uid[i]);
+ p += 2;
+ if (i == 3 || i == 5 || i == 7 || i == 9) {
+ snprintf(p, 1 + 1, "-");
+ p++;
+ }
+ }
+ return 0;
+}
+
+static int mxf_add_uid_metadata(AVDictionary **pm, const char *key, UID uid)
+{
+ char *str;
+ int ret;
+ if ((ret = mxf_uid_to_str(uid, &str)) < 0)
+ return ret;
+ av_dict_set(pm, key, str, AV_DICT_DONT_STRDUP_VAL);
+ return 0;
+}
+
static int mxf_add_timecode_metadata(AVDictionary **pm, const char *key, AVTimecode *tc)
{
char buf[AV_TIMECODE_STR_SIZE];
return 0;
}
+static MXFTimecodeComponent* mxf_resolve_timecode_component(MXFContext *mxf, UID *strong_ref)
+{
+ MXFStructuralComponent *component = NULL;
+ MXFPulldownComponent *pulldown = NULL;
+
+ component = mxf_resolve_strong_ref(mxf, strong_ref, AnyType);
+ if (!component)
+ return NULL;
+
+ switch (component->type) {
+ case TimecodeComponent:
+ return (MXFTimecodeComponent*)component;
+ case PulldownComponent: /* timcode component may be located on a pulldown component */
+ pulldown = (MXFPulldownComponent*)component;
+ return mxf_resolve_strong_ref(mxf, &pulldown->input_segment_ref, TimecodeComponent);
+ default:
+ break;
+ }
+ return NULL;
+}
+
+static MXFPackage* mxf_resolve_source_package(MXFContext *mxf, UID package_uid)
+{
+ MXFPackage *package = NULL;
+ int i;
+
+ for (i = 0; i < mxf->packages_count; i++) {
+ package = mxf_resolve_strong_ref(mxf, &mxf->packages_refs[i], SourcePackage);
+ if (!package)
+ continue;
+
+ if (!memcmp(package->package_uid, package_uid, 16))
+ return package;
+ }
+ return NULL;
+}
+
+static MXFStructuralComponent* mxf_resolve_essence_group_choice(MXFContext *mxf, MXFEssenceGroup *essence_group)
+{
+ MXFStructuralComponent *component = NULL;
+ MXFPackage *package = NULL;
+ MXFDescriptor *descriptor = NULL;
+ int i;
+
+ if (!essence_group || !essence_group->structural_components_count)
+ return NULL;
+
+ /* essence groups contains multiple representations of the same media,
+ this return the first components with a valid Descriptor typically index 0 */
+ for (i =0; i < essence_group->structural_components_count; i++){
+ component = mxf_resolve_strong_ref(mxf, &essence_group->structural_components_refs[i], SourceClip);
+ if (!component)
+ continue;
+
+ if (!(package = mxf_resolve_source_package(mxf, component->source_package_uid)))
+ continue;
+
+ descriptor = mxf_resolve_strong_ref(mxf, &package->descriptor_ref, Descriptor);
+ if (descriptor){
+ /* HACK: force the duration of the component to match the duration of the descriptor */
+ if (descriptor->duration != AV_NOPTS_VALUE)
+ component->duration = descriptor->duration;
+ return component;
+ }
+ }
+ return NULL;
+}
+
+static MXFStructuralComponent* mxf_resolve_sourceclip(MXFContext *mxf, UID *strong_ref)
+{
+ MXFStructuralComponent *component = NULL;
+
+ component = mxf_resolve_strong_ref(mxf, strong_ref, AnyType);
+ if (!component)
+ return NULL;
+ switch (component->type) {
+ case SourceClip:
+ return component;
+ case EssenceGroup:
+ return mxf_resolve_essence_group_choice(mxf, (MXFEssenceGroup*) component);
+ default:
+ break;
+ }
+ return NULL;
+}
+
+static int mxf_parse_physical_source_package(MXFContext *mxf, MXFTrack *source_track, AVStream *st)
+{
+ MXFPackage *physical_package = NULL;
+ MXFTrack *physical_track = NULL;
+ MXFStructuralComponent *sourceclip = NULL;
+ MXFTimecodeComponent *mxf_tc = NULL;
+ int i, j, k;
+ AVTimecode tc;
+ int flags;
+ int64_t start_position;
+
+ for (i = 0; i < source_track->sequence->structural_components_count; i++) {
+ sourceclip = mxf_resolve_strong_ref(mxf, &source_track->sequence->structural_components_refs[i], SourceClip);
+ if (!sourceclip)
+ continue;
+
+ if (!(physical_package = mxf_resolve_source_package(mxf, sourceclip->source_package_uid)))
+ break;
+
+ mxf_add_uid_metadata(&st->metadata, "reel_uid", physical_package->package_uid);
+
+ /* the name of physical source package is name of the reel or tape */
+ if (physical_package->name && physical_package->name[0])
+ av_dict_set(&st->metadata, "reel_name", physical_package->name, 0);
+
+ /* the source timecode is calculated by adding the start_position of the sourceclip from the file source package track
+ * to the start_frame of the timecode component located on one of the tracks of the physical source package.
+ */
+ for (j = 0; j < physical_package->tracks_count; j++) {
+ if (!(physical_track = mxf_resolve_strong_ref(mxf, &physical_package->tracks_refs[j], Track))) {
+ av_log(mxf->fc, AV_LOG_ERROR, "could not resolve source track strong ref\n");
+ continue;
+ }
+
+ if (!(physical_track->sequence = mxf_resolve_strong_ref(mxf, &physical_track->sequence_ref, Sequence))) {
+ av_log(mxf->fc, AV_LOG_ERROR, "could not resolve source track sequence strong ref\n");
+ continue;
+ }
+
+ for (k = 0; k < physical_track->sequence->structural_components_count; k++) {
+ if (!(mxf_tc = mxf_resolve_timecode_component(mxf, &physical_track->sequence->structural_components_refs[k])))
+ continue;
+
+ flags = mxf_tc->drop_frame == 1 ? AV_TIMECODE_FLAG_DROPFRAME : 0;
+ /* scale sourceclip start_position to match physical track edit rate */
+ start_position = av_rescale_q(sourceclip->start_position,
+ physical_track->edit_rate,
+ source_track->edit_rate);
+
+ if (av_timecode_init(&tc, mxf_tc->rate, flags, start_position + mxf_tc->start_frame, mxf->fc) == 0) {
+ mxf_add_timecode_metadata(&st->metadata, "timecode", &tc);
+ return 0;
+ }
+ }
+ }
+ }
+
+ return 0;
+}
+
static int mxf_parse_structural_metadata(MXFContext *mxf)
{
MXFPackage *material_package = NULL;
- MXFPackage *temp_package = NULL;
int i, j, k, ret;
av_dlog(mxf->fc, "metadata sets count %d\n", mxf->metadata_sets_count);
return AVERROR_INVALIDDATA;
}
+ mxf_add_uid_metadata(&mxf->fc->metadata, "material_package_uid", material_package->package_uid);
+ if (material_package->name && material_package->name[0])
+ av_dict_set(&mxf->fc->metadata, "material_package_name", material_package->name, 0);
+
for (i = 0; i < material_package->tracks_count; i++) {
MXFPackage *source_package = NULL;
MXFTrack *material_track = NULL;
/* TODO: handle multiple source clips */
for (j = 0; j < material_track->sequence->structural_components_count; j++) {
- component = mxf_resolve_strong_ref(mxf, &material_track->sequence->structural_components_refs[j], SourceClip);
+ component = mxf_resolve_sourceclip(mxf, &material_track->sequence->structural_components_refs[j]);
if (!component)
continue;
- for (k = 0; k < mxf->packages_count; k++) {
- temp_package = mxf_resolve_strong_ref(mxf, &mxf->packages_refs[k], SourcePackage);
- if (!temp_package)
- continue;
- if (!memcmp(temp_package->package_uid, component->source_package_uid, 16)) {
- source_package = temp_package;
- break;
- }
- }
+ source_package = mxf_resolve_source_package(mxf, component->source_package_uid);
if (!source_package) {
av_dlog(mxf->fc, "material track %d: no corresponding source package found\n", material_track->track_id);
break;
}
av_log(mxf->fc, AV_LOG_VERBOSE, "\n");
+ mxf_add_uid_metadata(&st->metadata, "file_package_uid", source_package->package_uid);
+ if (source_package->name && source_package->name[0])
+ av_dict_set(&st->metadata, "file_package_name", source_package->name, 0);
+
+ mxf_parse_physical_source_package(mxf, source_track, st);
+
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);
avpriv_request_sample(mxf->fc,
"Field dominance %d support",
descriptor->field_dominance);
+ case 0: // we already have many samples with field_dominance == unknown
break;
}
/* Turn field height into frame height. */
if (source_track->sequence->origin) {
av_dict_set_int(&st->metadata, "source_track_origin", source_track->sequence->origin, 0);
}
+ if (descriptor->aspect_ratio.num && descriptor->aspect_ratio.den)
+ st->display_aspect_ratio = descriptor->aspect_ratio;
} else if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
container_ul = mxf_get_codec_ul(mxf_sound_essence_container_uls, essence_container_ul);
/* Only overwrite existing codec ID if it is unset or A-law, which is the default according to SMPTE RP 224. */
return ret;
}
-static int mxf_read_utf16_string(AVIOContext *pb, int size, char** str)
-{
- int ret;
- size_t buf_size;
-
- if (size < 0)
- return AVERROR(EINVAL);
-
- buf_size = size + size / 2 + 1;
- *str = av_malloc(buf_size);
- if (!*str)
- return AVERROR(ENOMEM);
-
- if ((ret = avio_get_str16be(pb, size, *str, buf_size)) < 0) {
- av_freep(str);
- return ret;
- }
-
- return ret;
-}
-
-static int mxf_uid_to_str(UID uid, char **str)
-{
- int i;
- char *p;
- p = *str = av_mallocz(sizeof(UID) * 2 + 4 + 1);
- if (!p)
- return AVERROR(ENOMEM);
- for (i = 0; i < sizeof(UID); i++) {
- snprintf(p, 2 + 1, "%.2x", uid[i]);
- p += 2;
- if (i == 3 || i == 5 || i == 7 || i == 9) {
- snprintf(p, 1 + 1, "-");
- p++;
- }
- }
- return 0;
-}
-
static int mxf_timestamp_to_str(uint64_t timestamp, char **str)
{
struct tm time = { 0 };
*str = av_mallocz(32);
if (!*str)
return AVERROR(ENOMEM);
- strftime(*str, 32, "%Y-%m-%d %H:%M:%S", &time);
+ if (!strftime(*str, 32, "%Y-%m-%d %H:%M:%S", &time))
+ str[0] = '\0';
return 0;
}
{ { 0x06,0x0e,0x2b,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x04,0x04,0x00 }, mxf_read_partition_pack },
{ { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x30,0x00 }, mxf_read_identification_metadata },
{ { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x18,0x00 }, mxf_read_content_storage, 0, AnyType },
- { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x37,0x00 }, mxf_read_source_package, sizeof(MXFPackage), SourcePackage },
- { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x36,0x00 }, mxf_read_material_package, sizeof(MXFPackage), MaterialPackage },
+ { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x37,0x00 }, mxf_read_package, sizeof(MXFPackage), SourcePackage },
+ { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x36,0x00 }, mxf_read_package, sizeof(MXFPackage), MaterialPackage },
{ { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x0f,0x00 }, mxf_read_sequence, sizeof(MXFSequence), Sequence },
+ { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0D,0x01,0x01,0x01,0x01,0x01,0x05,0x00 }, mxf_read_essence_group, sizeof(MXFEssenceGroup), EssenceGroup},
{ { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x11,0x00 }, mxf_read_source_clip, sizeof(MXFStructuralComponent), SourceClip },
{ { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x44,0x00 }, mxf_read_generic_descriptor, sizeof(MXFDescriptor), MultipleDescriptor },
{ { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x42,0x00 }, mxf_read_generic_descriptor, sizeof(MXFDescriptor), Descriptor }, /* Generic Sound */
{ { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x3A,0x00 }, mxf_read_track, sizeof(MXFTrack), Track }, /* Static Track */
{ { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x3B,0x00 }, mxf_read_track, sizeof(MXFTrack), Track }, /* Generic Track */
{ { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x14,0x00 }, mxf_read_timecode_component, sizeof(MXFTimecodeComponent), TimecodeComponent },
+ { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x0c,0x00 }, mxf_read_pulldown_component, sizeof(MXFPulldownComponent), PulldownComponent },
{ { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x04,0x01,0x02,0x02,0x00,0x00 }, mxf_read_cryptographic_context, sizeof(MXFCryptoContext), CryptoContext },
{ { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x10,0x01,0x00 }, mxf_read_index_table_segment, sizeof(MXFIndexTableSegment), IndexTableSegment },
{ { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, NULL, 0, AnyType },
};
+static int mxf_metadataset_init(MXFMetadataSet *ctx, enum MXFMetadataSetType type)
+{
+ switch (type){
+ case MultipleDescriptor:
+ case Descriptor:
+ ((MXFDescriptor*)ctx)->pix_fmt = AV_PIX_FMT_NONE;
+ ((MXFDescriptor*)ctx)->duration = AV_NOPTS_VALUE;
+ break;
+ default:
+ break;
+ }
+ return 0;
+}
+
static int mxf_read_local_tags(MXFContext *mxf, KLVPacket *klv, MXFMetadataReadFunc *read_child, int ctx_size, enum MXFMetadataSetType type)
{
AVIOContext *pb = mxf->fc->pb;
if (!ctx)
return AVERROR(ENOMEM);
+ mxf_metadataset_init(ctx, type);
while (avio_tell(pb) + 4 < klv_end && !avio_feof(pb)) {
int ret;
int tag = avio_rb16(pb);
}
/**
- * Seeks to the previous partition, if possible
+ * Matches any partition pack key, in other words:
+ * - HeaderPartition
+ * - BodyPartition
+ * - FooterPartition
+ * @return non-zero if the key is a partition pack key, zero otherwise
+ */
+static int mxf_is_partition_pack_key(UID key)
+{
+ //NOTE: this is a little lax since it doesn't constraint key[14]
+ return !memcmp(key, mxf_header_partition_pack_key, 13) &&
+ key[13] >= 2 && key[13] <= 4;
+}
+
+/**
+ * Parses a metadata KLV
+ * @return <0 on error, 0 otherwise
+ */
+static int mxf_parse_klv(MXFContext *mxf, KLVPacket klv, MXFMetadataReadFunc *read,
+ int ctx_size, enum MXFMetadataSetType type)
+{
+ AVFormatContext *s = mxf->fc;
+ int res;
+ if (klv.key[5] == 0x53) {
+ res = mxf_read_local_tags(mxf, &klv, read, ctx_size, type);
+ } else {
+ uint64_t next = avio_tell(s->pb) + klv.length;
+ res = read(mxf, s->pb, 0, klv.length, klv.key, klv.offset);
+
+ /* only seek forward, else this can loop for a long time */
+ if (avio_tell(s->pb) > next) {
+ av_log(s, AV_LOG_ERROR, "read past end of KLV @ %#"PRIx64"\n",
+ klv.offset);
+ return AVERROR_INVALIDDATA;
+ }
+
+ avio_seek(s->pb, next, SEEK_SET);
+ }
+ if (res < 0) {
+ av_log(s, AV_LOG_ERROR, "error reading header metadata\n");
+ return res;
+ }
+ return 0;
+}
+
+/**
+ * Seeks to the previous partition and parses it, if possible
* @return <= 0 if we should stop parsing, > 0 if we should keep going
*/
static int mxf_seek_to_previous_partition(MXFContext *mxf)
{
AVIOContext *pb = mxf->fc->pb;
+ KLVPacket klv;
+ int64_t current_partition_ofs;
+ int ret;
if (!mxf->current_partition ||
mxf->run_in + mxf->current_partition->previous_partition <= mxf->last_forward_tell)
return 0; /* we've parsed all partitions */
/* seek to previous partition */
+ current_partition_ofs = mxf->current_partition->pack_ofs; //includes run-in
avio_seek(pb, mxf->run_in + mxf->current_partition->previous_partition, SEEK_SET);
mxf->current_partition = NULL;
av_dlog(mxf->fc, "seeking to previous partition\n");
+ /* Make sure this is actually a PartitionPack, and if so parse it.
+ * See deadlock2.mxf
+ */
+ if ((ret = klv_read_packet(&klv, pb)) < 0) {
+ av_log(mxf->fc, AV_LOG_ERROR, "failed to read PartitionPack KLV\n");
+ return ret;
+ }
+
+ if (!mxf_is_partition_pack_key(klv.key)) {
+ av_log(mxf->fc, AV_LOG_ERROR, "PreviousPartition @ %" PRIx64 " isn't a PartitionPack\n", klv.offset);
+ return AVERROR_INVALIDDATA;
+ }
+
+ /* We can't just check ofs >= current_partition_ofs because PreviousPartition
+ * can point to just before the current partition, causing klv_read_packet()
+ * to sync back up to it. See deadlock3.mxf
+ */
+ if (klv.offset >= current_partition_ofs) {
+ av_log(mxf->fc, AV_LOG_ERROR, "PreviousPartition for PartitionPack @ %"
+ PRIx64 " indirectly points to itself\n", current_partition_ofs);
+ return AVERROR_INVALIDDATA;
+ }
+
+ if ((ret = mxf_parse_klv(mxf, klv, mxf_read_partition_pack, 0, 0)) < 0)
+ return ret;
+
return 1;
}
if (mxf->parsing_backward) {
return mxf_seek_to_previous_partition(mxf);
} else {
- uint64_t offset = mxf->footer_partition ? mxf->footer_partition
- : mxf->last_partition;
-
- if (!offset) {
- av_dlog(mxf->fc, "no last partition\n");
+ if (!mxf->footer_partition) {
+ av_dlog(mxf->fc, "no FooterPartition\n");
return 0;
}
- av_dlog(mxf->fc, "seeking to last partition\n");
+ av_dlog(mxf->fc, "seeking to FooterPartition\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 last partition\n");
+ av_log(mxf->fc, AV_LOG_INFO, "file is not seekable - not parsing FooterPartition\n");
return -1;
}
- /* seek to last partition and parse backward */
- if ((ret = avio_seek(pb, mxf->run_in + offset, SEEK_SET)) < 0) {
+ /* seek to FooterPartition 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 last partition @ 0x%" PRIx64
+ "failed to seek to FooterPartition @ 0x%" PRIx64
" (%"PRId64") - partial file?\n",
- mxf->run_in + offset, ret);
+ mxf->run_in + mxf->footer_partition, ret);
return ret;
}
continue; /* BodySID == 0 -> no essence */
if (x >= mxf->partitions_count - 1)
- break; /* last partition - can't compute length (and we don't need to) */
+ break; /* FooterPartition - can't compute length (and we don't need to) */
/* essence container spans to the next partition */
p->essence_length = mxf->partitions[x+1].this_partition - p->essence_offset;
{
MXFContext *mxf = s->priv_data;
uint32_t length;
- int64_t file_size;
+ int64_t file_size, max_rip_length, min_rip_length;
KLVPacket klv;
if (!s->pb->seekable)
return;
file_size = avio_size(s->pb);
+
+ /* S377m says to check the RIP length for "silly" values, without defining "silly".
+ * The limit below assumes a file with nothing but partition packs and a RIP.
+ * Before changing this, consider that a muxer may place each sample in its own partition.
+ *
+ * 105 is the size of the smallest possible PartitionPack
+ * 12 is the size of each RIP entry
+ * 28 is the size of the RIP header and footer, assuming an 8-byte BER
+ */
+ max_rip_length = ((file_size - mxf->run_in) / 105) * 12 + 28;
+ max_rip_length = FFMIN(max_rip_length, INT_MAX); //2 GiB and up is also silly
+
+ /* We're only interested in RIPs with at least two entries.. */
+ min_rip_length = 16+1+24+4;
+
+ /* See S377m section 11 */
avio_seek(s->pb, file_size - 4, SEEK_SET);
length = avio_rb32(s->pb);
- if (length <= 32 || length >= FFMIN(file_size, INT_MAX))
+
+ if (length < min_rip_length || length > max_rip_length)
goto end;
avio_seek(s->pb, file_size - length, SEEK_SET);
if (klv_read_packet(&klv, s->pb) < 0 ||
goto end;
avio_skip(s->pb, klv.length - 12);
- mxf->last_partition = avio_rb64(s->pb);
+ mxf->footer_partition = avio_rb64(s->pb);
+
+ /* sanity check */
+ if (mxf->run_in + mxf->footer_partition >= file_size) {
+ av_log(s, AV_LOG_WARNING, "bad FooterPartition in RIP - ignoring\n");
+ mxf->footer_partition = 0;
+ }
end:
avio_seek(s->pb, mxf->run_in, SEEK_SET);
MXFContext *mxf = s->priv_data;
KLVPacket klv;
int64_t essence_offset = 0;
- int64_t last_pos = -1;
- uint64_t last_pos_index = 1;
int ret;
mxf->last_forward_tell = INT64_MAX;
while (!avio_feof(s->pb)) {
const MXFMetadataReadTableEntry *metadata;
- if (avio_tell(s->pb) == last_pos) {
- av_log(mxf->fc, AV_LOG_ERROR, "MXF structure loop detected\n");
- return AVERROR_INVALIDDATA;
- }
- if ((1ULL<<61) % last_pos_index++ == 0)
- last_pos = avio_tell(s->pb);
+
if (klv_read_packet(&klv, s->pb) < 0) {
/* EOF - seek to previous partition or stop */
if(mxf_parse_handle_partition_or_eof(mxf) <= 0)
if (mxf_parse_handle_essence(mxf) <= 0)
break;
continue;
- } else if (!memcmp(klv.key, mxf_header_partition_pack_key, 13) &&
- klv.key[13] >= 2 && klv.key[13] <= 4 && mxf->current_partition) {
+ } else if (mxf_is_partition_pack_key(klv.key) && mxf->current_partition) {
/* next partition pack - keep going, seek to previous partition or stop */
if(mxf_parse_handle_partition_or_eof(mxf) <= 0)
break;
for (metadata = mxf_metadata_read_table; metadata->read; metadata++) {
if (IS_KLV_KEY(klv.key, metadata->key)) {
- int res;
- if (klv.key[5] == 0x53) {
- res = mxf_read_local_tags(mxf, &klv, metadata->read, metadata->ctx_size, metadata->type);
- } else {
- uint64_t next = avio_tell(s->pb) + klv.length;
- res = metadata->read(mxf, s->pb, 0, klv.length, klv.key, klv.offset);
-
- /* only seek forward, else this can loop for a long time */
- if (avio_tell(s->pb) > next) {
- av_log(s, AV_LOG_ERROR, "read past end of KLV @ %#"PRIx64"\n",
- klv.offset);
- return AVERROR_INVALIDDATA;
- }
-
- avio_seek(s->pb, next, SEEK_SET);
- }
- if (res < 0) {
- av_log(s, AV_LOG_ERROR, "error reading header metadata\n");
- return res;
- }
+ if ((ret = mxf_parse_klv(mxf, klv, metadata->read, metadata->ctx_size, metadata->type)) < 0)
+ goto fail;
break;
} else {
av_log(s, AV_LOG_VERBOSE, "Dark key " PRIxUID "\n",
pkt->stream_index = index;
pkt->pos = klv.offset;
- codec = s->streams[index]->codec;
+ codec = st->codec;
if (codec->codec_type == AVMEDIA_TYPE_VIDEO && next_ofs >= 0) {
/* mxf->current_edit_unit good - see if we have an
case Sequence:
av_freep(&((MXFSequence *)mxf->metadata_sets[i])->structural_components_refs);
break;
+ case EssenceGroup:
+ av_freep(&((MXFEssenceGroup *)mxf->metadata_sets[i])->structural_components_refs);
+ break;
case SourcePackage:
case MaterialPackage:
av_freep(&((MXFPackage *)mxf->metadata_sets[i])->tracks_refs);
+ av_freep(&((MXFPackage *)mxf->metadata_sets[i])->name);
break;
case IndexTableSegment:
seg = (MXFIndexTableSegment *)mxf->metadata_sets[i];
* SMPTE 377M MXF File Format Specifications
* SMPTE 379M MXF Generic Container
* SMPTE 381M Mapping MPEG Streams into the MXF Generic Container
+ * SMPTE 422M Mapping JPEG 2000 Codestreams into the MXF Generic Container
* SMPTE RP210: SMPTE Metadata Dictionary
* SMPTE RP224: Registry of SMPTE Universal Labels
*/
#include "libavutil/random_seed.h"
#include "libavutil/timecode.h"
#include "libavutil/avassert.h"
+#include "libavutil/time_internal.h"
#include "libavcodec/bytestream.h"
#include "libavcodec/dnxhddata.h"
+#include "libavcodec/h264.h"
+#include "libavcodec/internal.h"
#include "audiointerleave.h"
#include "avformat.h"
#include "avio_internal.h"
{ AV_CODEC_ID_PCM_S16LE, 1 },
{ AV_CODEC_ID_DVVIDEO, 15 },
{ AV_CODEC_ID_DNXHD, 24 },
+ { AV_CODEC_ID_JPEG2000, 34 },
+ { AV_CODEC_ID_H264, 35 },
{ AV_CODEC_ID_NONE }
};
{ 0x06,0x0e,0x2b,0x34,0x01,0x02,0x01,0x01,0x0d,0x01,0x03,0x01,0x15,0x01,0x05,0x00 },
{ 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x71,0x13,0x00,0x00 },
mxf_write_cdci_desc },
+ // JPEG2000
+ { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x07,0x0d,0x01,0x03,0x01,0x02,0x0c,0x01,0x00 },
+ { 0x06,0x0e,0x2b,0x34,0x01,0x02,0x01,0x01,0x0d,0x01,0x03,0x01,0x15,0x01,0x08,0x00 },
+ { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x07,0x04,0x01,0x02,0x02,0x03,0x01,0x01,0x00 },
+ mxf_write_cdci_desc },
+ // H.264
+ { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0a,0x0D,0x01,0x03,0x01,0x02,0x10,0x60,0x01 },
+ { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x15,0x01,0x05,0x00 },
+ { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0a,0x04,0x01,0x02,0x02,0x01,0x00,0x00,0x00 },
+ mxf_write_mpegvideo_desc },
{ { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },
MXFStreamContext *sc = st->priv_data;
int profile_and_level = (st->codec->profile<<4) | st->codec->level;
- mxf_write_cdci_common(s, st, mxf_mpegvideo_descriptor_key, 8+5);
+ if (st->codec->codec_id != AV_CODEC_ID_H264) {
+ mxf_write_cdci_common(s, st, mxf_mpegvideo_descriptor_key, 8+5);
- // bit rate
- mxf_write_local_tag(pb, 4, 0x8000);
- avio_wb32(pb, sc->video_bit_rate);
+ // bit rate
+ mxf_write_local_tag(pb, 4, 0x8000);
+ avio_wb32(pb, sc->video_bit_rate);
- // profile and level
- mxf_write_local_tag(pb, 1, 0x8007);
- if (!st->codec->profile)
- profile_and_level |= 0x80; // escape bit
- avio_w8(pb, profile_and_level);
+ // profile and level
+ mxf_write_local_tag(pb, 1, 0x8007);
+ if (!st->codec->profile)
+ profile_and_level |= 0x80; // escape bit
+ avio_w8(pb, profile_and_level);
+ } else {
+ mxf_write_cdci_common(s, st, mxf_mpegvideo_descriptor_key, 0);
+ }
}
static void mxf_write_generic_sound_common(AVFormatContext *s, AVStream *st, const UID key, unsigned size)
return 1;
}
+static const struct {
+ UID uid;
+ int frame_size;
+ int profile;
+ uint8_t interlaced;
+} mxf_h264_codec_uls[] = {
+ {{ 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0a,0x04,0x01,0x02,0x02,0x01,0x32,0x20,0x01 }, 0, 110, 0 }, // AVC High 10 Intra
+ {{ 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0a,0x04,0x01,0x02,0x02,0x01,0x32,0x21,0x01 }, 232960, 0, 1 }, // AVC Intra 50 1080i60
+ {{ 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0a,0x04,0x01,0x02,0x02,0x01,0x32,0x21,0x02 }, 281088, 0, 1 }, // AVC Intra 50 1080i50
+ {{ 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0a,0x04,0x01,0x02,0x02,0x01,0x32,0x21,0x03 }, 232960, 0, 0 }, // AVC Intra 50 1080p30
+ {{ 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0a,0x04,0x01,0x02,0x02,0x01,0x32,0x21,0x04 }, 281088, 0, 0 }, // AVC Intra 50 1080p25
+ {{ 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0a,0x04,0x01,0x02,0x02,0x01,0x32,0x21,0x08 }, 116736, 0, 0 }, // AVC Intra 50 720p60
+ {{ 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0a,0x04,0x01,0x02,0x02,0x01,0x32,0x21,0x09 }, 140800, 0, 0 }, // AVC Intra 50 720p50
+ {{ 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0a,0x04,0x01,0x02,0x02,0x01,0x32,0x30,0x01 }, 0, 122, 0 }, // AVC High 422 Intra
+ {{ 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0a,0x04,0x01,0x02,0x02,0x01,0x32,0x31,0x01 }, 472576, 0, 1 }, // AVC Intra 100 1080i60
+ {{ 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0a,0x04,0x01,0x02,0x02,0x01,0x32,0x31,0x02 }, 568832, 0, 1 }, // AVC Intra 100 1080i50
+ {{ 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0a,0x04,0x01,0x02,0x02,0x01,0x32,0x31,0x03 }, 472576, 0, 0 }, // AVC Intra 100 1080p30
+ {{ 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0a,0x04,0x01,0x02,0x02,0x01,0x32,0x31,0x04 }, 568832, 0, 0 }, // AVC Intra 100 1080p25
+ {{ 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0a,0x04,0x01,0x02,0x02,0x01,0x32,0x31,0x08 }, 236544, 0, 0 }, // AVC Intra 100 720p60
+ {{ 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0a,0x04,0x01,0x02,0x02,0x01,0x32,0x31,0x09 }, 284672, 0, 0 }, // AVC Intra 100 720p50
+};
+
+static int mxf_parse_h264_frame(AVFormatContext *s, AVStream *st,
+ AVPacket *pkt, MXFIndexEntry *e)
+{
+ MXFContext *mxf = s->priv_data;
+ MXFStreamContext *sc = st->priv_data;
+ static const int mxf_h264_num_codec_uls = sizeof(mxf_h264_codec_uls) / sizeof(mxf_h264_codec_uls[0]);
+ const uint8_t *buf = pkt->data;
+ const uint8_t *buf_end = pkt->data + pkt->size;
+ uint32_t state = -1;
+ int extra_size = 512; // support AVC Intra files without SPS/PPS header
+ int i, frame_size;
+ uint8_t uid_found;
+
+ if (pkt->size > extra_size)
+ buf_end -= pkt->size - extra_size; // no need to parse beyond SPS/PPS header
+
+ for (;;) {
+ buf = avpriv_find_start_code(buf, buf_end, &state);
+ if (buf >= buf_end)
+ break;
+ --buf;
+ switch (state & 0x1f) {
+ case NAL_SPS:
+ st->codec->profile = buf[1];
+ e->flags |= 0x40;
+ break;
+ case NAL_PPS:
+ if (e->flags & 0x40) { // sequence header present
+ e->flags |= 0x80; // random access
+ extra_size = 0;
+ buf = buf_end;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (mxf->header_written)
+ return 1;
+
+ sc->aspect_ratio = (AVRational){ 16, 9 }; // 16:9 is mandatory for broadcast HD
+ sc->component_depth = 10; // AVC Intra is always 10 Bit
+ sc->interlaced = st->codec->field_order != AV_FIELD_PROGRESSIVE ? 1 : 0;
+ if (sc->interlaced)
+ sc->field_dominance = 1; // top field first is mandatory for AVC Intra
+
+ uid_found = 0;
+ frame_size = pkt->size + extra_size;
+ for (i = 0; i < mxf_h264_num_codec_uls; i++) {
+ if (frame_size == mxf_h264_codec_uls[i].frame_size && sc->interlaced == mxf_h264_codec_uls[i].interlaced) {
+ sc->codec_ul = &mxf_h264_codec_uls[i].uid;
+ return 1;
+ } else if (st->codec->profile == mxf_h264_codec_uls[i].profile) {
+ sc->codec_ul = &mxf_h264_codec_uls[i].uid;
+ uid_found = 1;
+ }
+ }
+
+ if (!uid_found) {
+ av_log(s, AV_LOG_ERROR, "AVC Intra 50/100 supported only\n");
+ return 0;
+ }
+
+ return 1;
+}
+
static const UID mxf_mpeg2_codec_uls[] = {
{ 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x01,0x10,0x00 }, // MP-ML I-Frame
{ 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x01,0x11,0x00 }, // MP-ML Long GOP
static uint64_t mxf_parse_timestamp(time_t timestamp)
{
- struct tm *time = gmtime(×tamp);
+ struct tm tmbuf;
+ struct tm *time = gmtime_r(×tamp, &tmbuf);
if (!time)
return 0;
return (uint64_t)(time->tm_year+1900) << 48 |
av_log(s, AV_LOG_ERROR, "could not get dv profile\n");
return -1;
}
+ } else if (st->codec->codec_id == AV_CODEC_ID_H264) {
+ if (!mxf_parse_h264_frame(s, st, pkt, &ie)) {
+ av_log(s, AV_LOG_ERROR, "could not get h264 profile\n");
+ return -1;
+ }
}
if (!mxf->header_written) {
};
#endif /* !HAVE_STRUCT_SOCKADDR_STORAGE */
+typedef union sockaddr_union {
+ struct sockaddr_storage storage;
+ struct sockaddr_in in;
+#if HAVE_STRUCT_SOCKADDR_IN6
+ struct sockaddr_in6 in6;
+#endif
+} sockaddr_union;
+
#ifndef MSG_NOSIGNAL
#define MSG_NOSIGNAL 0
#endif
};
const AVCodecTag ff_nut_video_tags[] = {
+ { AV_CODEC_ID_XFACE, MKTAG('X', 'F', 'A', 'C') },
{ AV_CODEC_ID_VP9, MKTAG('V', 'P', '9', '0') },
{ AV_CODEC_ID_RAWVIDEO, MKTAG('R', 'G', 'B', 15 ) },
{ AV_CODEC_ID_RAWVIDEO, MKTAG('B', 'G', 'R', 15 ) },
int64_t value, end;
char name[256], str_value[1024], type_str[256];
const char *type;
- int *event_flags = NULL;
+ int *event_flags = NULL;
AVChapter *chapter = NULL;
AVStream *st = NULL;
AVDictionary **metadata = NULL;
{
AVFormatContext *s = nut->avf;
AVIOContext *bc = s->pb;
- int size, stream_id, discard;
+ int size, stream_id, discard, ret;
int64_t pts, last_IP_pts;
StreamContext *stc;
uint8_t header_idx;
- int ret;
size = decode_frame_header(nut, &pts, &stream_id, &header_idx, frame_code);
if (size < 0)
return 1;
}
- if (av_new_packet(pkt, size + nut->header_len[header_idx]) < 0)
- return AVERROR(ENOMEM);
+ ret = av_new_packet(pkt, size + nut->header_len[header_idx]);
+ if (ret < 0)
+ return ret;
memcpy(pkt->data, nut->header[header_idx], nut->header_len[header_idx]);
pkt->pos = avio_tell(bc); // FIXME
if (stc->last_flags & FLAG_SM_DATA) {
}
}
av_assert0(frame_code != -1);
+
fc = &nut->frame_code[frame_code];
flags = fc->flags;
needed_flags = get_needed_flags(nut, nus, fc, pkt);
OGGStreamContext *oggstream, int bitexact,
AVDictionary **m)
{
- enum FLACExtradataFormat format;
- uint8_t *streaminfo;
uint8_t *p;
- if (!avpriv_flac_is_extradata_valid(avctx, &format, &streaminfo))
- return -1;
+ if (avctx->extradata_size < FLAC_STREAMINFO_SIZE)
+ return AVERROR(EINVAL);
// first packet: STREAMINFO
oggstream->header_len[0] = 51;
bytestream_put_buffer(&p, "fLaC", 4);
bytestream_put_byte(&p, 0x00); // streaminfo
bytestream_put_be24(&p, 34);
- bytestream_put_buffer(&p, streaminfo, FLAC_STREAMINFO_SIZE);
+ bytestream_put_buffer(&p, avctx->extradata, FLAC_STREAMINFO_SIZE);
// second packet: VorbisComment
p = ogg_write_vorbiscomment(4, bitexact, &oggstream->header_len[1], m, 0);
uint8_t *p;
if (avctx->extradata_size < SPEEX_HEADER_SIZE)
- return -1;
+ return AVERROR_INVALIDDATA;
// first packet: Speex header
p = av_mallocz(SPEEX_HEADER_SIZE);
uint8_t *p;
if (avctx->extradata_size < OPUS_HEADER_SIZE)
- return -1;
+ return AVERROR_INVALIDDATA;
/* first packet: Opus header */
p = av_mallocz(avctx->extradata_size);
st->codec->codec_id != AV_CODEC_ID_FLAC &&
st->codec->codec_id != AV_CODEC_ID_OPUS) {
av_log(s, AV_LOG_ERROR, "Unsupported codec id in stream %d\n", i);
- return -1;
+ return AVERROR(EINVAL);
}
if (!st->codec->extradata || !st->codec->extradata_size) {
av_log(s, AV_LOG_ERROR, "No extradata present\n");
- return -1;
+ return AVERROR_INVALIDDATA;
}
oggstream = av_mallocz(sizeof(*oggstream));
if (!oggstream)
oggstream->header, oggstream->header_len) < 0) {
av_log(s, AV_LOG_ERROR, "Extradata corrupted\n");
av_freep(&st->priv_data);
- return -1;
+ return AVERROR_INVALIDDATA;
}
p = ogg_write_vorbiscomment(7, s->flags & AVFMT_FLAG_BITEXACT,
}
granule = (oggstream->last_kf_pts<<oggstream->kfgshift) | pframe_count;
} else if (st->codec->codec_id == AV_CODEC_ID_OPUS)
- granule = pkt->pts + pkt->duration + av_rescale_q(st->codec->delay, (AVRational){ 1, st->codec->sample_rate }, st->time_base);
+ granule = pkt->pts + pkt->duration +
+ av_rescale_q(st->codec->initial_padding,
+ (AVRational){ 1, st->codec->sample_rate },
+ st->time_base);
else
granule = pkt->pts + pkt->duration;
st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
st->codec->codec_id = AV_CODEC_ID_DIRAC;
// dirac in ogg always stores timestamps as though the video were interlaced
- avpriv_set_pts_info(st, 64, st->codec->time_base.num, 2*st->codec->time_base.den);
+ avpriv_set_pts_info(st, 64, st->codec->framerate.den, 2*st->codec->framerate.num);
return 1;
}
struct ogg_stream *os = ogg->streams + idx;
AVStream *st = s->streams[idx];
GetBitContext gb;
- FLACStreaminfo si;
int mdt;
if (os->buf[os->pstart] == 0xff)
if (mdt == OGG_FLAC_METADATA_TYPE_STREAMINFO) {
uint8_t *streaminfo_start = os->buf + os->pstart + 5 + 4 + 4 + 4;
+ uint32_t samplerate;
+
skip_bits_long(&gb, 4*8); /* "FLAC" */
if(get_bits(&gb, 8) != 1) /* unsupported major version */
return -1;
if (get_bits_long(&gb, 32) != FLAC_STREAMINFO_SIZE)
return -1;
- avpriv_flac_parse_streaminfo(st->codec, &si, streaminfo_start);
-
st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
st->codec->codec_id = AV_CODEC_ID_FLAC;
st->need_parsing = AVSTREAM_PARSE_HEADERS;
return AVERROR(ENOMEM);
memcpy(st->codec->extradata, streaminfo_start, st->codec->extradata_size);
- avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
+ samplerate = AV_RB24(st->codec->extradata + 10) >> 4;
+ if (!samplerate)
+ return AVERROR_INVALIDDATA;
+
+ avpriv_set_pts_info(st, 64, 1, samplerate);
} else if (mdt == FLAC_METADATA_TYPE_VORBIS_COMMENT) {
ff_vorbis_stream_comment(s, st, os->buf + os->pstart + 4, os->psize - 4);
}
struct oggvorbis_private {
unsigned int len[3];
unsigned char *packet[3];
- VorbisParseContext vp;
+ AVVorbisParseContext *vp;
int64_t final_pts;
int final_duration;
};
struct ogg_stream *os = ogg->streams + idx;
struct oggvorbis_private *priv = os->private;
int i;
- if (os->private)
+ if (os->private) {
+ av_vorbis_parse_free(&priv->vp);
for (i = 0; i < 3; i++)
av_freep(&priv->packet[i]);
+ }
}
static int vorbis_update_metadata(AVFormatContext *s, int idx)
return AVERROR(ENOMEM);
}
+ priv = os->private;
+
if (!(pkt_type & 1))
- return 0;
+ return priv->vp ? 0 : AVERROR_INVALIDDATA;
if (os->psize < 1 || pkt_type > 5)
return AVERROR_INVALIDDATA;
- priv = os->private;
-
if (priv->packet[pkt_type >> 1])
return AVERROR_INVALIDDATA;
if (pkt_type > 1 && !priv->packet[0] || pkt_type > 3 && !priv->packet[1])
return ret;
}
st->codec->extradata_size = ret;
- if ((ret = avpriv_vorbis_parse_extradata(st->codec, &priv->vp))) {
+
+ priv->vp = av_vorbis_parse_init(st->codec->extradata, st->codec->extradata_size);
+ if (!priv->vp) {
av_freep(&st->codec->extradata);
st->codec->extradata_size = 0;
- return ret;
+ return AVERROR_UNKNOWN;
}
}
uint8_t *last_pkt = os->buf + os->pstart;
uint8_t *next_pkt = last_pkt;
- avpriv_vorbis_parse_reset(&priv->vp);
+ av_vorbis_parse_reset(priv->vp);
duration = 0;
seg = os->segp;
- d = avpriv_vorbis_parse_frame_flags(&priv->vp, last_pkt, 1, &flags);
+ d = av_vorbis_parse_frame_flags(priv->vp, last_pkt, 1, &flags);
if (d < 0) {
os->pflags |= AV_PKT_FLAG_CORRUPT;
return 0;
last_pkt = next_pkt = next_pkt + os->psize;
for (; seg < os->nsegs; seg++) {
if (os->segments[seg] < 255) {
- int d = avpriv_vorbis_parse_frame_flags(&priv->vp, last_pkt, 1, &flags);
+ int d = av_vorbis_parse_frame_flags(priv->vp, last_pkt, 1, &flags);
if (d < 0) {
duration = os->granule;
break;
s->streams[idx]->duration -= s->streams[idx]->start_time;
}
priv->final_pts = AV_NOPTS_VALUE;
- avpriv_vorbis_parse_reset(&priv->vp);
+ av_vorbis_parse_reset(priv->vp);
}
/* parse packet duration */
if (os->psize > 0) {
- duration = avpriv_vorbis_parse_frame_flags(&priv->vp, os->buf + os->pstart, 1, &flags);
+ duration = av_vorbis_parse_frame_flags(priv->vp, os->buf + os->pstart, 1, &flags);
if (duration < 0) {
os->pflags |= AV_PKT_FLAG_CORRUPT;
return 0;
ic = av_malloc(sizeof(AVFormatContext));
if (!ic) return ic;
avformat_get_context_defaults(ic);
+ ic->offset = AV_NOPTS_VALUE;
ic->internal = av_mallocz(sizeof(*ic->internal));
if (!ic->internal) {
{"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},
-{"avoid_negative_ts", "shift timestamps so they start at 0", OFFSET(avoid_negative_ts), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 2, E, "avoid_negative_ts"},
-{"auto", "enabled when required by target format", 0, AV_OPT_TYPE_CONST, {.i64 = -1 }, INT_MIN, INT_MAX, E, "avoid_negative_ts"},
-{"disabled", "do not change timestamps", 0, AV_OPT_TYPE_CONST, {.i64 = 0 }, INT_MIN, INT_MAX, E, "avoid_negative_ts"},
-{"make_zero", "shift timestamps so they start at 0", 0, AV_OPT_TYPE_CONST, {.i64 = 2 }, INT_MIN, INT_MAX, E, "avoid_negative_ts"},
-{"make_non_negative", "shift timestamps so they are non negative", 0, AV_OPT_TYPE_CONST, {.i64 = 1 }, INT_MIN, INT_MAX, E, "avoid_negative_ts"},
{"skip_initial_bytes", "set number of bytes to skip before reading header and frames", OFFSET(skip_initial_bytes), AV_OPT_TYPE_INT64, {.i64 = 0}, 0, INT64_MAX-1, D},
{"correct_ts_overflow", "correct single timestamp overflows", OFFSET(correct_ts_overflow), AV_OPT_TYPE_INT, {.i64 = 1}, 0, 1, D},
{"flush_packets", "enable flushing of the I/O context after each packet", OFFSET(flush_packets), AV_OPT_TYPE_INT, {.i64 = 1}, 0, 1, E},
{"unofficial", "allow unofficial extensions", 0, AV_OPT_TYPE_CONST, {.i64 = FF_COMPLIANCE_UNOFFICIAL }, INT_MIN, INT_MAX, D|E, "strict"},
{"experimental", "allow non-standardized experimental variants", 0, AV_OPT_TYPE_CONST, {.i64 = FF_COMPLIANCE_EXPERIMENTAL }, INT_MIN, INT_MAX, D|E, "strict"},
{"max_ts_probe", "maximum number of packets to read while waiting for the first timestamp", OFFSET(max_ts_probe), AV_OPT_TYPE_INT, { .i64 = 50 }, 0, INT_MAX, D },
+{"avoid_negative_ts", "shift timestamps so they start at 0", OFFSET(avoid_negative_ts), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 2, E, "avoid_negative_ts"},
+{"auto", "enabled when required by target format", 0, AV_OPT_TYPE_CONST, {.i64 = AVFMT_AVOID_NEG_TS_AUTO }, INT_MIN, INT_MAX, E, "avoid_negative_ts"},
+{"disabled", "do not change timestamps", 0, AV_OPT_TYPE_CONST, {.i64 = 0 }, INT_MIN, INT_MAX, E, "avoid_negative_ts"},
+{"make_non_negative", "shift timestamps so they are non negative", 0, AV_OPT_TYPE_CONST, {.i64 = AVFMT_AVOID_NEG_TS_MAKE_NON_NEGATIVE }, INT_MIN, INT_MAX, E, "avoid_negative_ts"},
+{"make_zero", "shift timestamps so they start at 0", 0, AV_OPT_TYPE_CONST, {.i64 = AVFMT_AVOID_NEG_TS_MAKE_ZERO }, INT_MIN, INT_MAX, E, "avoid_negative_ts"},
+{"dump_separator", "set information dump field separator", OFFSET(dump_separator), AV_OPT_TYPE_STRING, {.str = ", "}, CHAR_MIN, CHAR_MAX, D|E},
+{"codec_whitelist", "List of decoders that are allowed to be used", OFFSET(codec_whitelist), AV_OPT_TYPE_STRING, { .str = NULL }, CHAR_MIN, CHAR_MAX, D },
+{"format_whitelist", "List of demuxers that are allowed to be used", OFFSET(format_whitelist), AV_OPT_TYPE_STRING, { .str = NULL }, CHAR_MIN, CHAR_MAX, D },
{NULL},
};
*/
/* needed by inet_aton() */
+#define _DEFAULT_SOURCE
#define _SVID_SOURCE
#include "config.h"
#include <sys/stat.h>
+#ifdef _WIN32
+#if HAVE_DIRECT_H
+#include <direct.h>
+#endif
+#if HAVE_IO_H
+#include <io.h>
+#endif
+#endif
+
#if defined(_WIN32) && !defined(__MINGW32CE__)
# include <fcntl.h>
# ifdef lseek
# define fstat(f,s) _fstati64((f), (s))
#endif /* defined(_WIN32) && !defined(__MINGW32CE__) */
-#ifdef _WIN32
-#if HAVE_DIRECT_H
-#include <direct.h>
-#elif HAVE_IO_H
-#include <io.h>
-#endif
-#define mkdir(a, b) _mkdir(a)
+
+#ifdef __ANDROID__
+# if HAVE_UNISTD_H
+# include <unistd.h>
+# endif
+# ifdef lseek
+# undef lseek
+# endif
+# define lseek(f,p,w) lseek64((f), (p), (w))
#endif
static inline int is_dos_path(const char *path)
#endif /* HAVE_POLL_H */
#endif /* CONFIG_NETWORK */
+#if defined(__MINGW32CE__)
+#define mkdir(a, b) _mkdir(a)
+#elif defined(_WIN32)
+#include <stdio.h>
+#include <windows.h>
+#include "libavutil/wchar_filename.h"
+
+#define DEF_FS_FUNCTION(name, wfunc, afunc) \
+static inline int win32_##name(const char *filename_utf8) \
+{ \
+ wchar_t *filename_w; \
+ int ret; \
+ \
+ if (utf8towchar(filename_utf8, &filename_w)) \
+ return -1; \
+ if (!filename_w) \
+ goto fallback; \
+ \
+ ret = wfunc(filename_w); \
+ av_free(filename_w); \
+ return ret; \
+ \
+fallback: \
+ /* filename may be be in CP_ACP */ \
+ return afunc(filename_utf8); \
+}
+
+DEF_FS_FUNCTION(unlink, _wunlink, _unlink)
+DEF_FS_FUNCTION(mkdir, _wmkdir, _mkdir)
+DEF_FS_FUNCTION(rmdir, _wrmdir , _rmdir)
+
+static inline int win32_rename(const char *src_utf8, const char *dest_utf8)
+{
+ wchar_t *src_w, *dest_w;
+ int ret;
+
+ if (utf8towchar(src_utf8, &src_w))
+ return -1;
+ if (utf8towchar(dest_utf8, &dest_w)) {
+ av_free(src_w);
+ return -1;
+ }
+ if (!src_w || !dest_w) {
+ av_free(src_w);
+ av_free(dest_w);
+ goto fallback;
+ }
+
+ ret = MoveFileExW(src_w, dest_w, MOVEFILE_REPLACE_EXISTING);
+ av_free(src_w);
+ av_free(dest_w);
+ // Lacking proper mapping from GetLastError() error codes to errno codes
+ if (ret)
+ errno = EPERM;
+ return ret;
+
+fallback:
+ /* filename may be be in CP_ACP */
+#if HAVE_MOVEFILEEXA
+ ret = MoveFileExA(src_utf8, dest_utf8, MOVEFILE_REPLACE_EXISTING);
+ if (ret)
+ errno = EPERM;
+#else
+ /* Windows Phone doesn't have MoveFileExA. However, it's unlikely
+ * that anybody would input filenames in CP_ACP there, so this
+ * fallback is kept mostly for completeness. Alternatively we could
+ * do MultiByteToWideChar(CP_ACP) and use MoveFileExW, but doing
+ * explicit conversions with CP_ACP is allegedly forbidden in windows
+ * store apps (or windows phone), and the notion of a native code page
+ * doesn't make much sense there. */
+ ret = rename(src_utf8, dest_utf8);
+#endif
+ return ret;
+}
+
+#define mkdir(a, b) win32_mkdir(a)
+#define rename win32_rename
+#define rmdir win32_rmdir
+#define unlink win32_unlink
+
+#endif
+
#endif /* AVFORMAT_OS_SUPPORT_H */
#include "libavutil/channel_layout.h"
#include "libavutil/intreadwrite.h"
#include "avformat.h"
+#include "riff.h"
typedef struct {
uint32_t data_size; ///< size of data chunk
} else if (!memcmp(buf, guid_smv, 16)) {
st->codec->codec_id = AV_CODEC_ID_SMV;
} else {
- av_log(s, AV_LOG_ERROR, "Unknown codec GUID.\n");
+ av_log(s, AV_LOG_ERROR, "Unknown codec GUID "FF_PRI_GUID".\n",
+ FF_ARG_GUID(buf));
return AVERROR_INVALIDDATA;
}
avio_skip(pb, 2 + 80); // codec-version + codec-name
st->codec->codec_id = s->iformat->raw_codec_id;
st->need_parsing = AVSTREAM_PARSE_FULL_RAW;
+ st->codec->framerate = s1->framerate;
st->codec->time_base = av_inv_q(s1->framerate);
avpriv_set_pts_info(st, 64, 1, 1200000);
.read_header = ff_raw_data_read_header,
.read_packet = ff_raw_read_partial_packet,
.raw_codec_id = AV_CODEC_ID_NONE,
+ .flags = AVFMT_NOTIMESTAMPS,
};
#endif
.long_name = NULL_IF_CONFIG_SMALL("raw LOAS/LATM"),
.read_header = ff_raw_audio_read_header,
.read_packet = ff_raw_read_partial_packet,
- .flags = AVFMT_GENERIC_INDEX,
+ .flags = AVFMT_GENERIC_INDEX | AVFMT_NOTIMESTAMPS,
.extensions = "latm",
.raw_codec_id = AV_CODEC_ID_AAC_LATM,
};
.long_name = NULL_IF_CONFIG_SMALL("raw MLP"),
.read_header = ff_raw_audio_read_header,
.read_packet = ff_raw_read_partial_packet,
- .flags = AVFMT_GENERIC_INDEX,
+ .flags = AVFMT_GENERIC_INDEX | AVFMT_NOTIMESTAMPS,
.extensions = "mlp",
.raw_codec_id = AV_CODEC_ID_MLP,
};
.long_name = NULL_IF_CONFIG_SMALL("raw TrueHD"),
.read_header = ff_raw_audio_read_header,
.read_packet = ff_raw_read_partial_packet,
- .flags = AVFMT_GENERIC_INDEX,
+ .flags = AVFMT_GENERIC_INDEX | AVFMT_NOTIMESTAMPS,
.extensions = "thd",
.raw_codec_id = AV_CODEC_ID_TRUEHD,
};
.long_name = NULL_IF_CONFIG_SMALL("raw Shorten"),
.read_header = ff_raw_audio_read_header,
.read_packet = ff_raw_read_partial_packet,
- .flags = AVFMT_NOBINSEARCH | AVFMT_NOGENSEARCH | AVFMT_NO_BYTE_SEEK,
+ .flags = AVFMT_NOBINSEARCH | AVFMT_NOGENSEARCH | AVFMT_NO_BYTE_SEEK|AVFMT_NOTIMESTAMPS,
.extensions = "shn",
.raw_codec_id = AV_CODEC_ID_SHORTEN,
};
rdt_new_context (void)
{
PayloadContext *rdt = av_mallocz(sizeof(PayloadContext));
- int ret;
if (!rdt)
return NULL;
- ret = avformat_open_input(&rdt->rmctx, "", &ff_rdt_demuxer, NULL);
- if (ret < 0) {
- av_free(rdt);
- return NULL;
- }
+
+ rdt->rmctx = avformat_alloc_context();
+ if (!rdt->rmctx)
+ av_freep(&rdt);
return rdt;
}
+static int
+rdt_init_context (AVFormatContext *s, int st_index, PayloadContext *rdt)
+{
+ int ret;
+
+ if ((ret = ff_copy_whitelists(rdt->rmctx, s)) < 0)
+ return ret;
+
+ return avformat_open_input(&rdt->rmctx, "", &ff_rdt_demuxer, NULL);
+}
+
static void
rdt_free_context (PayloadContext *rdt)
{
.codec_id = AV_CODEC_ID_NONE, \
.parse_sdp_a_line = rdt_parse_sdp_line, \
.alloc = rdt_new_context, \
+ .init = rdt_init_context, \
.free = rdt_free_context, \
.parse_packet = rdt_parse_packet \
}
char c = 0;
int res = 0, duration = read_ts("60"); // default duration is 60 seconds
FFTextReader tr;
- ff_text_init_avio(&tr, s->pb);
+ ff_text_init_avio(s, &tr, s->pb);
if (!st)
return AVERROR(ENOMEM);
/* Ut Video version 13.0.1 BT.709 codecs */
{ AV_CODEC_ID_UTVIDEO, MKTAG('U', 'L', 'H', '0') },
{ AV_CODEC_ID_UTVIDEO, MKTAG('U', 'L', 'H', '2') },
+ { AV_CODEC_ID_UTVIDEO, MKTAG('U', 'Q', 'Y', '2') },
{ AV_CODEC_ID_VBLE, MKTAG('V', 'B', 'L', 'E') },
{ AV_CODEC_ID_ESCAPE130, MKTAG('E', '1', '3', '0') },
{ AV_CODEC_ID_DXTORY, MKTAG('x', 't', 'o', 'r') },
{ AV_CODEC_ID_G2M, MKTAG('G', '2', 'M', '2') },
{ AV_CODEC_ID_G2M, MKTAG('G', '2', 'M', '3') },
{ AV_CODEC_ID_G2M, MKTAG('G', '2', 'M', '4') },
+ { AV_CODEC_ID_G2M, MKTAG('G', '2', 'M', '5') },
{ AV_CODEC_ID_FIC, MKTAG('F', 'I', 'C', 'V') },
+ { AV_CODEC_ID_PRORES, MKTAG('A', 'P', 'C', 'N') },
{ AV_CODEC_ID_NONE, 0 }
};
extern const AVCodecGuid ff_codec_wav_guids[];
#define FF_PRI_GUID \
- "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"
+ "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x " \
+ "{%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x}"
#define FF_ARG_GUID(g) \
g[0], g[1], g[2], g[3], g[4], g[5], g[6], g[7], \
+ g[8], g[9], g[10], g[11], g[12], g[13], g[14], g[15],\
+ g[3], g[2], g[1], g[0], g[5], g[4], g[7], g[6], \
g[8], g[9], g[10], g[11], g[12], g[13], g[14], g[15]
#define FF_MEDIASUBTYPE_BASE_GUID \
{
int id;
+ if (size < 14)
+ avpriv_request_sample(codec, "wav header size < 14");
+
id = avio_rl16(pb);
codec->codec_type = AVMEDIA_TYPE_AUDIO;
codec->channels = avio_rl16(pb);
* fall back on using AVCodecContext.frame_size, which is not as reliable
* for indicating packet duration. */
frame_size = av_get_audio_frame_duration(enc, enc->block_align);
- if (!frame_size)
- frame_size = enc->frame_size;
waveformatextensible = (enc->channels > 2 && enc->channel_layout) ||
enc->sample_rate > 48000 ||
enc->bits_per_coded_sample, bps);
}
- if (enc->codec_id == AV_CODEC_ID_MP2 ||
- enc->codec_id == AV_CODEC_ID_MP3) {
- /* This is wrong, but it seems many demuxers do not work if this
- * is set correctly. */
+ if (enc->codec_id == AV_CODEC_ID_MP2) {
blkalign = frame_size;
- // blkalign = 144 * enc->bit_rate/enc->sample_rate;
+ } else if (enc->codec_id == AV_CODEC_ID_MP3) {
+ blkalign = 576 * (enc->sample_rate <= (24000 + 32000)/2 ? 1 : 2);
} else if (enc->codec_id == AV_CODEC_ID_AC3) {
blkalign = 3840; /* maximum bytes per frame */
} else if (enc->codec_id == AV_CODEC_ID_AAC) {
int64_t codec_pos;
int ret;
+ if (codec_data_size < 0)
+ return AVERROR_INVALIDDATA;
+
avpriv_set_pts_info(st, 64, 1, 1000);
codec_pos = avio_tell(pb);
v = avio_rb32(pb);
/* multiple of 20 bytes for ra144 (ugly) */
#define RAW_PACKET_SIZE 1000
-static int sync(AVFormatContext *s, int64_t *timestamp, int *flags, int *stream_index, int64_t *pos){
+static int rm_sync(AVFormatContext *s, int64_t *timestamp, int *flags, int *stream_index, int64_t *pos){
RMDemuxContext *rm = s->priv_data;
AVIOContext *pb = s->pb;
AVStream *st;
ast->deint_id == DEINT_ID_VBRS)
av_get_packet(pb, pkt, ast->sub_packet_lengths[ast->sub_packet_cnt - rm->audio_pkt_cnt]);
else {
- if(av_new_packet(pkt, st->codec->block_align) < 0)
- return AVERROR(ENOMEM);
+ int ret = av_new_packet(pkt, st->codec->block_align);
+ if (ret < 0)
+ return ret;
memcpy(pkt->data, ast->pkt.data + st->codec->block_align * //FIXME avoid this
(ast->sub_packet_h * ast->audio_framesize / st->codec->block_align - rm->audio_pkt_cnt),
st->codec->block_align);
flags = (seq++ == 1) ? 2 : 0;
pos = avio_tell(s->pb);
} else {
- len=sync(s, ×tamp, &flags, &i, &pos);
+ len = rm_sync(s, ×tamp, &flags, &i, &pos);
if (len > 0)
st = s->streams[i];
}
- if(len<0 || avio_feof(s->pb))
+ if (len <= 0 || avio_feof(s->pb))
return AVERROR(EIO);
res = ff_rm_parse_packet (s, s->pb, st, st->priv_data, len, pkt,
int seq=1;
AVStream *st;
- len=sync(s, &dts, &flags, &stream_index2, &pos);
+ len = rm_sync(s, &dts, &flags, &stream_index2, &pos);
if(len<0)
return AV_NOPTS_VALUE;
int timestamp, int size)
{
if (size) {
- pkt->data = av_malloc(size);
+ pkt->data = av_realloc(NULL, size);
if (!pkt->data)
return AVERROR(ENOMEM);
}
uint32_t client_report_size; ///< number of bytes after which client should report to server
uint32_t bytes_read; ///< number of bytes read from server
uint32_t last_bytes_read; ///< number of bytes read last reported to server
+ uint32_t last_timestamp; ///< last timestamp received in a packet
int skip_bytes; ///< number of bytes to skip from the input FLV stream in the next write call
int has_audio; ///< presence of audio data
int has_video; ///< presence of video data
int listen; ///< listen mode flag
int listen_timeout; ///< listen timeout to wait for new connections
int nb_streamid; ///< The next stream id to return on createStream calls
+ double duration; ///< Duration of the stream in seconds as returned by the server (only valid if non-zero)
char username[50];
char password[50];
char auth_params[500];
if (ret < 0)
return ret;
- // Send result_ NetConnection.Connect.Success to connect
+ // Send _result NetConnection.Connect.Success to connect
if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL,
RTMP_PT_INVOKE, 0,
RTMP_PKTDATA_DEFAULT_SIZE)) < 0)
return rtmp_send_packet(rt, &pkt, 0);
}
+/**
+ * Generate 'getStreamLength' call and send it to the server. If the server
+ * knows the duration of the selected stream, it will reply with the duration
+ * in seconds.
+ */
+static int gen_get_stream_length(URLContext *s, RTMPContext *rt)
+{
+ RTMPPacket pkt;
+ uint8_t *p;
+ int ret;
+
+ if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SOURCE_CHANNEL, RTMP_PT_INVOKE,
+ 0, 31 + strlen(rt->playpath))) < 0)
+ return ret;
+
+ p = pkt.data;
+ ff_amf_write_string(&p, "getStreamLength");
+ ff_amf_write_number(&p, ++rt->nb_invokes);
+ ff_amf_write_null(&p);
+ ff_amf_write_string(&p, rt->playpath);
+
+ return rtmp_send_packet(rt, &pkt, 1);
+}
+
/**
* Generate client buffer time and send it to the server.
*/
return rtmp_send_packet(rt, &pkt, 1);
}
+/**
+ * Generate a pause packet that either pauses or unpauses the current stream.
+ */
+static int gen_pause(URLContext *s, RTMPContext *rt, int pause, uint32_t timestamp)
+{
+ RTMPPacket pkt;
+ uint8_t *p;
+ int ret;
+
+ av_log(s, AV_LOG_DEBUG, "Sending pause command for timestamp %d\n",
+ timestamp);
+
+ if ((ret = ff_rtmp_packet_create(&pkt, 3, RTMP_PT_INVOKE, 0, 29)) < 0)
+ return ret;
+
+ pkt.extra = rt->stream_id;
+
+ p = pkt.data;
+ ff_amf_write_string(&p, "pause");
+ ff_amf_write_number(&p, 0); //no tracking back responses
+ ff_amf_write_null(&p); //as usual, the first null param
+ ff_amf_write_bool(&p, pause); // pause or unpause
+ ff_amf_write_number(&p, timestamp); //where we pause the stream
+
+ return rtmp_send_packet(rt, &pkt, 1);
+}
+
/**
* Generate 'publish' call and send it to the server.
*/
/* Gracefully ignore Adobe-specific historical artifact errors. */
level = AV_LOG_WARNING;
ret = 0;
+ } else if (tracked_method && !strcmp(tracked_method, "getStreamLength")) {
+ level = rt->live ? AV_LOG_DEBUG : AV_LOG_WARNING;
+ ret = 0;
} else if (tracked_method && !strcmp(tracked_method, "connect")) {
ret = handle_connect_error(s, tmpstr);
if (!ret) {
return ret;
}
+/**
+ * Read the AMF_NUMBER response ("_result") to a function call
+ * (e.g. createStream()). This response should be made up of the AMF_STRING
+ * "result", a NULL object and then the response encoded as AMF_NUMBER. On a
+ * successful response, we will return set the value to number (otherwise number
+ * will not be changed).
+ *
+ * @return 0 if reading the value succeeds, negative value otherwiss
+ */
+static int read_number_result(RTMPPacket *pkt, double *number)
+{
+ // We only need to fit "_result" in this.
+ uint8_t strbuffer[8];
+ int stringlen;
+ double numbuffer;
+ GetByteContext gbc;
+
+ bytestream2_init(&gbc, pkt->data, pkt->size);
+
+ // Value 1/4: "_result" as AMF_STRING
+ if (ff_amf_read_string(&gbc, strbuffer, sizeof(strbuffer), &stringlen))
+ return AVERROR_INVALIDDATA;
+ if (strcmp(strbuffer, "_result"))
+ return AVERROR_INVALIDDATA;
+ // Value 2/4: The callee reference number
+ if (ff_amf_read_number(&gbc, &numbuffer))
+ return AVERROR_INVALIDDATA;
+ // Value 3/4: Null
+ if (ff_amf_read_null(&gbc))
+ return AVERROR_INVALIDDATA;
+ // Value 4/4: The resonse as AMF_NUMBER
+ if (ff_amf_read_number(&gbc, &numbuffer))
+ return AVERROR_INVALIDDATA;
+ else
+ *number = numbuffer;
+
+ return 0;
+}
+
static int handle_invoke_result(URLContext *s, RTMPPacket *pkt)
{
RTMPContext *rt = s->priv_data;
}
}
} else if (!strcmp(tracked_method, "createStream")) {
- //extract a number from the result
- if (pkt->data[10] || pkt->data[19] != 5 || pkt->data[20]) {
+ double stream_id;
+ if (read_number_result(pkt, &stream_id)) {
av_log(s, AV_LOG_WARNING, "Unexpected reply on connect()\n");
} else {
- rt->stream_id = av_int2double(AV_RB64(pkt->data + 21));
+ rt->stream_id = stream_id;
}
if (!rt->is_input) {
if ((ret = gen_publish(s, rt)) < 0)
goto fail;
} else {
+ if (rt->live != -1) {
+ if ((ret = gen_get_stream_length(s, rt)) < 0)
+ goto fail;
+ }
if ((ret = gen_play(s, rt)) < 0)
goto fail;
if ((ret = gen_buffer_time(s, rt)) < 0)
goto fail;
}
+ } else if (!strcmp(tracked_method, "getStreamLength")) {
+ if (read_number_result(pkt, &rt->duration)) {
+ av_log(s, AV_LOG_WARNING, "Unexpected reply on getStreamLength()\n");
+ }
}
fail:
return AVERROR(EIO);
}
}
+
+ // Track timestamp for later use
+ rt->last_timestamp = rpkt.timestamp;
+
rt->bytes_read += ret;
if (rt->bytes_read - rt->last_bytes_read > rt->client_report_size) {
av_log(s, AV_LOG_DEBUG, "Sending bytes read report\n");
return ret;
}
+/**
+ * Insert a fake onMetadata packet into the FLV stream to notify the FLV
+ * demuxer about the duration of the stream.
+ *
+ * This should only be done if there was no real onMetadata packet sent by the
+ * server at the start of the stream and if we were able to retrieve a valid
+ * duration via a getStreamLength call.
+ *
+ * @return 0 for successful operation, negative value in case of error
+ */
+static int inject_fake_duration_metadata(RTMPContext *rt)
+{
+ // We need to insert the metdata packet directly after the FLV
+ // header, i.e. we need to move all other already read data by the
+ // size of our fake metadata packet.
+
+ uint8_t* p;
+ // Keep old flv_data pointer
+ uint8_t* old_flv_data = rt->flv_data;
+ // Allocate a new flv_data pointer with enough space for the additional package
+ if (!(rt->flv_data = av_malloc(rt->flv_size + 55))) {
+ rt->flv_data = old_flv_data;
+ return AVERROR(ENOMEM);
+ }
+
+ // Copy FLV header
+ memcpy(rt->flv_data, old_flv_data, 13);
+ // Copy remaining packets
+ memcpy(rt->flv_data + 13 + 55, old_flv_data + 13, rt->flv_size - 13);
+ // Increase the size by the injected packet
+ rt->flv_size += 55;
+ // Delete the old FLV data
+ av_free(old_flv_data);
+
+ p = rt->flv_data + 13;
+ bytestream_put_byte(&p, FLV_TAG_TYPE_META);
+ bytestream_put_be24(&p, 40); // size of data part (sum of all parts below)
+ bytestream_put_be24(&p, 0); // timestamp
+ bytestream_put_be32(&p, 0); // reserved
+
+ // first event name as a string
+ bytestream_put_byte(&p, AMF_DATA_TYPE_STRING);
+ // "onMetaData" as AMF string
+ bytestream_put_be16(&p, 10);
+ bytestream_put_buffer(&p, "onMetaData", 10);
+
+ // mixed array (hash) with size and string/type/data tuples
+ bytestream_put_byte(&p, AMF_DATA_TYPE_MIXEDARRAY);
+ bytestream_put_be32(&p, 1); // metadata_count
+
+ // "duration" as AMF string
+ bytestream_put_be16(&p, 8);
+ bytestream_put_buffer(&p, "duration", 8);
+ bytestream_put_byte(&p, AMF_DATA_TYPE_NUMBER);
+ bytestream_put_be64(&p, av_double2int(rt->duration));
+
+ // Finalise object
+ bytestream_put_be16(&p, 0); // Empty string
+ bytestream_put_byte(&p, AMF_END_OF_OBJECT);
+ bytestream_put_be32(&p, 40); // size of data part (sum of all parts below)
+
+ return 0;
+}
+
/**
* Open RTMP connection and verify that the stream can be played.
*
{
RTMPContext *rt = s->priv_data;
char proto[8], hostname[256], path[1024], auth[100], *fname;
- char *old_app, *qmark, fname_buffer[1024];
+ char *old_app, *qmark, *n, fname_buffer[1024];
uint8_t buf[2048];
int port;
AVDictionary *opts = NULL;
hostname, sizeof(hostname), &port,
path, sizeof(path), s->filename);
- if (strchr(path, ' ')) {
+ n = strchr(path, ' ');
+ if (n) {
av_log(s, AV_LOG_WARNING,
"Detected librtmp style URL parameters, these aren't supported "
"by the libavformat internal RTMP handler currently enabled. "
"See the documentation for the correct way to pass parameters.\n");
+ *n = '\0'; // Trim not supported part
}
if (auth[0]) {
char *next = *path ? path + 1 : path;
char *p = strchr(next, '/');
if (!p) {
- fname = next;
- rt->app[0] = '\0';
+ if (old_app) {
+ // If name of application has been defined by the user, assume that
+ // playpath is provided in the URL
+ fname = next;
+ } else {
+ fname = NULL;
+ av_strlcpy(rt->app, next, APP_MAX_LENGTH);
+ }
} else {
// make sure we do not mismatch a playpath for an application instance
char *c = strchr(p + 1, ':');
}
if (!rt->playpath) {
- int len = strlen(fname);
-
rt->playpath = av_malloc(PLAYPATH_MAX_LENGTH);
if (!rt->playpath) {
ret = AVERROR(ENOMEM);
goto fail;
}
- if (!strchr(fname, ':') && len >= 4 &&
- (!strcmp(fname + len - 4, ".f4v") ||
- !strcmp(fname + len - 4, ".mp4"))) {
- memcpy(rt->playpath, "mp4:", 5);
+ if (fname) {
+ int len = strlen(fname);
+ if (!strchr(fname, ':') && len >= 4 &&
+ (!strcmp(fname + len - 4, ".f4v") ||
+ !strcmp(fname + len - 4, ".mp4"))) {
+ memcpy(rt->playpath, "mp4:", 5);
+ } else {
+ if (len >= 4 && !strcmp(fname + len - 4, ".flv"))
+ fname[len - 4] = '\0';
+ rt->playpath[0] = 0;
+ }
+ av_strlcat(rt->playpath, fname, PLAYPATH_MAX_LENGTH);
} else {
- if (len >= 4 && !strcmp(fname + len - 4, ".flv"))
- fname[len - 4] = '\0';
- rt->playpath[0] = 0;
+ rt->playpath[0] = '\0';
}
- av_strlcat(rt->playpath, fname, PLAYPATH_MAX_LENGTH);
}
if (!rt->tcurl) {
rt->received_metadata = 0;
rt->last_bytes_read = 0;
rt->server_bw = 2500000;
+ rt->duration = 0;
av_log(s, AV_LOG_DEBUG, "Proto = %s, path = %s, app = %s, fname = %s\n",
proto, path, rt->app, rt->playpath);
}
if (rt->is_input) {
- int err;
// generate FLV header for demuxer
rt->flv_size = 13;
- if ((err = av_reallocp(&rt->flv_data, rt->flv_size)) < 0)
- return err;
+ if ((ret = av_reallocp(&rt->flv_data, rt->flv_size)) < 0)
+ goto fail;
rt->flv_off = 0;
memcpy(rt->flv_data, "FLV\1\0\0\0\0\011\0\0\0\0", rt->flv_size);
// audio or video packet arrives.
while (!rt->has_audio && !rt->has_video && !rt->received_metadata) {
if ((ret = get_packet(s, 0)) < 0)
- return ret;
+ goto fail;
}
// Either after we have read the metadata or (if there is none) the
if (rt->has_video) {
rt->flv_data[4] |= FLV_HEADER_FLAG_HASVIDEO;
}
+
+ // If we received the first packet of an A/V stream and no metadata but
+ // the server returned a valid duration, create a fake metadata packet
+ // to inform the FLV decoder about the duration.
+ if (!rt->received_metadata && rt->duration > 0) {
+ if ((ret = inject_fake_duration_metadata(rt)) < 0)
+ goto fail;
+ }
} else {
rt->flv_size = 0;
rt->flv_data = NULL;
return timestamp;
}
+static int rtmp_pause(URLContext *s, int pause)
+{
+ RTMPContext *rt = s->priv_data;
+ int ret;
+ av_log(s, AV_LOG_DEBUG, "Pause at timestamp %d\n",
+ rt->last_timestamp);
+ if ((ret = gen_pause(s, rt, pause, rt->last_timestamp)) < 0) {
+ av_log(s, AV_LOG_ERROR, "Unable to send pause command at timestamp %d\n",
+ rt->last_timestamp);
+ return ret;
+ }
+ return 0;
+}
+
static int rtmp_write(URLContext *s, const uint8_t *buf, int size)
{
RTMPContext *rt = s->priv_data;
int size_temp = size;
- int pktsize, pkttype;
+ int pktsize, pkttype, copy;
uint32_t ts;
const uint8_t *buf_temp = buf;
uint8_t c;
if (rt->flv_header_bytes < RTMP_HEADER) {
const uint8_t *header = rt->flv_header;
- int copy = FFMIN(RTMP_HEADER - rt->flv_header_bytes, size_temp);
int channel = RTMP_AUDIO_CHANNEL;
+
+ copy = FFMIN(RTMP_HEADER - rt->flv_header_bytes, size_temp);
bytestream_get_buffer(&buf_temp, rt->flv_header + rt->flv_header_bytes, copy);
rt->flv_header_bytes += copy;
size_temp -= copy;
if (pkttype == RTMP_PT_VIDEO)
channel = RTMP_VIDEO_CHANNEL;
- //force 12bytes header
if (((pkttype == RTMP_PT_VIDEO || pkttype == RTMP_PT_AUDIO) && ts == 0) ||
pkttype == RTMP_PT_NOTIFY) {
- if (pkttype == RTMP_PT_NOTIFY)
- pktsize += 16;
if ((ret = ff_rtmp_check_alloc_array(&rt->prev_pkt[1],
&rt->nb_prev_pkt[1],
channel)) < 0)
return ret;
+ // Force sending a full 12 bytes header by clearing the
+ // channel id, to make it not match a potential earlier
+ // packet in the same channel.
rt->prev_pkt[1][channel].channel_id = 0;
}
rt->out_pkt.extra = rt->stream_id;
rt->flv_data = rt->out_pkt.data;
-
- if (pkttype == RTMP_PT_NOTIFY)
- ff_amf_write_string(&rt->flv_data, "@setDataFrame");
}
- if (rt->flv_size - rt->flv_off > size_temp) {
- bytestream_get_buffer(&buf_temp, rt->flv_data + rt->flv_off, size_temp);
- rt->flv_off += size_temp;
- size_temp = 0;
- } else {
- bytestream_get_buffer(&buf_temp, rt->flv_data + rt->flv_off, rt->flv_size - rt->flv_off);
- size_temp -= rt->flv_size - rt->flv_off;
- rt->flv_off += rt->flv_size - rt->flv_off;
- }
+ copy = FFMIN(rt->flv_size - rt->flv_off, size_temp);
+ bytestream_get_buffer(&buf_temp, rt->flv_data + rt->flv_off, copy);
+ rt->flv_off += copy;
+ size_temp -= copy;
if (rt->flv_off == rt->flv_size) {
rt->skip_bytes = 4;
+ if (rt->out_pkt.type == RTMP_PT_NOTIFY) {
+ // For onMetaData and |RtmpSampleAccess packets, we want
+ // @setDataFrame prepended to the packet before it gets sent.
+ // However, not all RTMP_PT_NOTIFY packets (e.g., onTextData
+ // and onCuePoint).
+ uint8_t commandbuffer[64];
+ int stringlen = 0;
+ GetByteContext gbc;
+
+ bytestream2_init(&gbc, rt->flv_data, rt->flv_size);
+ if (!ff_amf_read_string(&gbc, commandbuffer, sizeof(commandbuffer),
+ &stringlen)) {
+ if (!strcmp(commandbuffer, "onMetaData") ||
+ !strcmp(commandbuffer, "|RtmpSampleAccess")) {
+ uint8_t *ptr;
+ if ((ret = av_reallocp(&rt->out_pkt.data, rt->out_pkt.size + 16)) < 0) {
+ rt->flv_size = rt->flv_off = rt->flv_header_bytes = 0;
+ return ret;
+ }
+ memmove(rt->out_pkt.data + 16, rt->out_pkt.data, rt->out_pkt.size);
+ rt->out_pkt.size += 16;
+ ptr = rt->out_pkt.data;
+ ff_amf_write_string(&ptr, "@setDataFrame");
+ }
+ }
+ }
+
if ((ret = rtmp_send_packet(rt, &rt->out_pkt, 0)) < 0)
return ret;
rt->flv_size = 0;
.url_open = rtmp_open, \
.url_read = rtmp_read, \
.url_read_seek = rtmp_seek, \
+ .url_read_pause = rtmp_pause, \
.url_write = rtmp_write, \
.url_close = rtmp_close, \
.priv_data_size = sizeof(RTMPContext), \
ff_register_dynamic_payload_handler(&ff_h263_2000_dynamic_handler);
ff_register_dynamic_payload_handler(&ff_h263_rfc2190_dynamic_handler);
ff_register_dynamic_payload_handler(&ff_h264_dynamic_handler);
- ff_register_dynamic_payload_handler(&ff_h265_dynamic_handler);
ff_register_dynamic_payload_handler(&ff_hevc_dynamic_handler);
ff_register_dynamic_payload_handler(&ff_ilbc_dynamic_handler);
ff_register_dynamic_payload_handler(&ff_jpeg_dynamic_handler);
return AVERROR_INVALIDDATA;
}
- s->last_rtcp_reception_time = av_gettime();
+ s->last_rtcp_reception_time = av_gettime_relative();
s->last_rtcp_ntp_time = AV_RB64(buf + 8);
s->last_rtcp_timestamp = AV_RB32(buf + 16);
if (s->first_rtcp_ntp_time == AV_NOPTS_VALUE) {
avio_wb32(pb, 0); /* delay since last SR */
} else {
uint32_t middle_32_bits = s->last_rtcp_ntp_time >> 16; // this is valid, right? do we need to handle 64 bit values special?
- uint32_t delay_since_last = av_rescale(av_gettime() - s->last_rtcp_reception_time,
+ uint32_t delay_since_last = av_rescale(av_gettime_relative() - s->last_rtcp_reception_time,
65536, AV_TIME_BASE);
avio_wb32(pb, middle_32_bits); /* last SR timestamp */
/* Send new feedback if enough time has elapsed since the last
* feedback packet. */
- now = av_gettime();
+ now = av_gettime_relative();
if (s->last_feedback_time &&
(now - s->last_feedback_time) < MIN_FEEDBACK_INTERVAL)
return 0;
packet = av_mallocz(sizeof(*packet));
if (!packet)
return;
- packet->recvtime = av_gettime();
+ packet->recvtime = av_gettime_relative();
packet->seq = seq;
packet->len = len;
packet->buf = buf;
}
if (s->st) {
- int64_t received = av_gettime();
+ int64_t received = av_gettime_relative();
uint32_t arrival_ts = av_rescale_q(received, AV_TIME_BASE_Q,
s->st->time_base);
timestamp = AV_RB32(buf + 4);
* @author Ronald S. Bultje <rbultje@ronald.bitfreak.net>
*/
+#include "libavutil/avassert.h"
#include "libavutil/base64.h"
#include "libavutil/avstring.h"
#include "libavutil/intreadwrite.h"
AVDictionary *opts = NULL;
int len = strlen(p) * 6 / 8;
char *buf = av_mallocz(len);
+ AVInputFormat *iformat;
+
av_base64_decode(buf, p, len);
if (rtp_asf_fix_header(buf, len) < 0)
if (rt->asf_ctx) {
avformat_close_input(&rt->asf_ctx);
}
+ if (!(iformat = av_find_input_format("asf")))
+ return AVERROR_DEMUXER_NOT_FOUND;
if (!(rt->asf_ctx = avformat_alloc_context()))
return AVERROR(ENOMEM);
rt->asf_ctx->pb = &pb;
av_dict_set(&opts, "no_resync_search", "1", 0);
- ret = avformat_open_input(&rt->asf_ctx, "", &ff_asf_demuxer, &opts);
+
+ if ((ret = ff_copy_whitelists(rt->asf_ctx, s)) < 0) {
+ av_dict_free(&opts);
+ return ret;
+ }
+
+ ret = avformat_open_input(&rt->asf_ctx, "", iformat, &opts);
av_dict_free(&opts);
if (ret < 0)
return ret;
extern RTPDynamicProtocolHandler ff_h263_2000_dynamic_handler;
extern RTPDynamicProtocolHandler ff_h263_rfc2190_dynamic_handler;
extern RTPDynamicProtocolHandler ff_h264_dynamic_handler;
-extern RTPDynamicProtocolHandler ff_h265_dynamic_handler;
extern RTPDynamicProtocolHandler ff_hevc_dynamic_handler;
extern RTPDynamicProtocolHandler ff_ilbc_dynamic_handler;
extern RTPDynamicProtocolHandler ff_jpeg_dynamic_handler;
uint32_t timestamp;
};
-static PayloadContext *h261_new_context(void)
+static av_cold PayloadContext *h261_new_context(void)
{
return av_mallocz(sizeof(PayloadContext));
}
*dyn_buf = NULL;
}
-static void h261_free_context(PayloadContext *pl_ctx)
+static av_cold void h261_free_context(PayloadContext *pl_ctx)
{
/* return if context is invalid */
if (!pl_ctx)
int sbit, ebit, gobn, mbap, quant;
int res;
- //av_log(ctx, AV_LOG_DEBUG, "got h261 RTP packet with time: %u\n", timestamp);
-
/* drop data of previous packets in case of non-continuous (loss) packet stream */
if (data->buf && data->timestamp != *timestamp) {
h261_free_dyn_buffer(&data->buf);
}
- /* sanity check for size of input packet */
- if (len < 5 /* 4 bytes header and 1 byte payload at least */) {
- av_log(ctx, AV_LOG_ERROR, "Too short H.261 RTP packet\n");
+ /* sanity check for size of input packet: 1 byte payload at least */
+ if (len < RTP_H261_PAYLOAD_HEADER_SIZE + 1) {
+ av_log(ctx, AV_LOG_ERROR, "Too short RTP/H.261 packet, got %d bytes\n", len);
return AVERROR_INVALIDDATA;
}
*/
#include "libavutil/avstring.h"
+#include "libavutil/base64.h"
#include "avformat.h"
#include "rtpdec.h"
struct PayloadContext {
int using_donl_field;
int profile_id;
+ uint8_t *sps, *pps, *vps, *sei;
+ int sps_size, pps_size, vps_size, sei_size;
};
static const uint8_t start_sequence[] = { 0x00, 0x00, 0x00, 0x01 };
/* sprop-sps: [base64] */
/* sprop-pps: [base64] */
/* sprop-sei: [base64] */
+ if (!strcmp(attr, "sprop-vps") || !strcmp(attr, "sprop-sps") ||
+ !strcmp(attr, "sprop-pps") || !strcmp(attr, "sprop-sei")) {
+ uint8_t **data_ptr;
+ int *size_ptr;
+ if (!strcmp(attr, "sprop-vps")) {
+ data_ptr = &hevc_data->vps;
+ size_ptr = &hevc_data->vps_size;
+ } else if (!strcmp(attr, "sprop-sps")) {
+ data_ptr = &hevc_data->sps;
+ size_ptr = &hevc_data->sps_size;
+ } else if (!strcmp(attr, "sprop-pps")) {
+ data_ptr = &hevc_data->pps;
+ size_ptr = &hevc_data->pps_size;
+ } else if (!strcmp(attr, "sprop-sei")) {
+ data_ptr = &hevc_data->sei;
+ size_ptr = &hevc_data->sei_size;
+ }
+
+ while (*value) {
+ char base64packet[1024];
+ uint8_t decoded_packet[1024];
+ int decoded_packet_size;
+ char *dst = base64packet;
+
+ while (*value && *value != ',' &&
+ (dst - base64packet) < sizeof(base64packet) - 1) {
+ *dst++ = *value++;
+ }
+ *dst++ = '\0';
+
+ if (*value == ',')
+ value++;
+
+ decoded_packet_size = av_base64_decode(decoded_packet, base64packet,
+ sizeof(decoded_packet));
+ if (decoded_packet_size > 0) {
+ uint8_t *tmp = av_realloc(*data_ptr, decoded_packet_size +
+ sizeof(start_sequence) + *size_ptr);
+ if (!tmp) {
+ av_log(s, AV_LOG_ERROR,
+ "Unable to allocate memory for extradata!\n");
+ return AVERROR(ENOMEM);
+ }
+ *data_ptr = tmp;
+
+ memcpy(*data_ptr + *size_ptr, start_sequence,
+ sizeof(start_sequence));
+ memcpy(*data_ptr + *size_ptr + sizeof(start_sequence),
+ decoded_packet, decoded_packet_size);
+
+ *size_ptr += sizeof(start_sequence) + decoded_packet_size;
+ }
+ }
+ }
+
/* max-lsr, max-lps, max-cpb, max-dpb, max-br, max-tr, max-tc */
/* max-fps */
/* jump beyond the "-" and determine the height value */
codec->height = atoi(sdp_line_ptr + 1);
} else if (av_strstart(sdp_line_ptr, "fmtp:", &sdp_line_ptr)) {
- return ff_parse_fmtp(ctx, current_stream, hevc_data, sdp_line_ptr,
- hevc_sdp_parse_fmtp_config);
+ int ret = ff_parse_fmtp(ctx, current_stream, hevc_data, sdp_line_ptr,
+ hevc_sdp_parse_fmtp_config);
+ if (hevc_data->vps_size || hevc_data->sps_size ||
+ hevc_data->pps_size || hevc_data->sei_size) {
+ av_freep(&codec->extradata);
+ codec->extradata_size = hevc_data->vps_size + hevc_data->sps_size +
+ hevc_data->pps_size + hevc_data->sei_size;
+ codec->extradata = av_malloc(codec->extradata_size +
+ FF_INPUT_BUFFER_PADDING_SIZE);
+ if (!codec->extradata) {
+ ret = AVERROR(ENOMEM);
+ codec->extradata_size = 0;
+ } else {
+ int pos = 0;
+ memcpy(codec->extradata + pos, hevc_data->vps, hevc_data->vps_size);
+ pos += hevc_data->vps_size;
+ memcpy(codec->extradata + pos, hevc_data->sps, hevc_data->sps_size);
+ pos += hevc_data->sps_size;
+ memcpy(codec->extradata + pos, hevc_data->pps, hevc_data->pps_size);
+ pos += hevc_data->pps_size;
+ memcpy(codec->extradata + pos, hevc_data->sei, hevc_data->sei_size);
+ pos += hevc_data->sei_size;
+ memset(codec->extradata + pos, 0, FF_INPUT_BUFFER_PADDING_SIZE);
+ }
+
+ av_freep(&hevc_data->vps);
+ av_freep(&hevc_data->sps);
+ av_freep(&hevc_data->pps);
+ av_freep(&hevc_data->sei);
+ hevc_data->vps_size = 0;
+ hevc_data->sps_size = 0;
+ hevc_data->pps_size = 0;
+ hevc_data->sei_size = 0;
+ }
+ return ret;
}
return 0;
buf += RTP_HEVC_PAYLOAD_HEADER_SIZE;
len -= RTP_HEVC_PAYLOAD_HEADER_SIZE;
- if (len < 1)
- return AVERROR_INVALIDDATA;
/*
decode the FU header
av_dlog(ctx, " FU type %d with %d bytes\n", fu_type, len);
+ /* sanity check for size of input packet: 1 byte payload at least */
if (len > 0) {
new_nal_header[0] = (rtp_pl[0] & 0x81) | (fu_type << 1);
new_nal_header[1] = rtp_pl[1];
memcpy(pkt->data, buf, len);
}
} else {
- /* sanity check for size of input packet: 1 byte payload at least */
- av_log(ctx, AV_LOG_ERROR,
- "Too short RTP/HEVC packet, got %d bytes of NAL unit type %d\n",
- len, nal_type);
- res = AVERROR_INVALIDDATA;
+ if (len < 0) {
+ av_log(ctx, AV_LOG_ERROR,
+ "Too short RTP/HEVC packet, got %d bytes of NAL unit type %d\n",
+ len, nal_type);
+ res = AVERROR_INVALIDDATA;
+ } else {
+ res = AVERROR(EAGAIN);
+ }
}
break;
}
RTPDynamicProtocolHandler ff_hevc_dynamic_handler = {
- .enc_name = "HEVC",
- .codec_type = AVMEDIA_TYPE_VIDEO,
- .codec_id = AV_CODEC_ID_HEVC,
- .init = hevc_init,
- .parse_sdp_a_line = hevc_parse_sdp_line,
- .alloc = hevc_new_context,
- .free = hevc_free_context,
- .parse_packet = hevc_handle_packet
-};
-
-RTPDynamicProtocolHandler ff_h265_dynamic_handler = {
.enc_name = "H265",
.codec_type = AVMEDIA_TYPE_VIDEO,
.codec_id = AV_CODEC_ID_HEVC,
case AV_CODEC_ID_H263:
case AV_CODEC_ID_H263P:
case AV_CODEC_ID_H264:
+ case AV_CODEC_ID_HEVC:
case AV_CODEC_ID_MPEG1VIDEO:
case AV_CODEC_ID_MPEG2VIDEO:
case AV_CODEC_ID_MPEG4:
s->nal_length_size = (st->codec->extradata[4] & 0x03) + 1;
}
break;
+ case AV_CODEC_ID_HEVC:
+ /* Only check for the standardized hvcC version of extradata, keeping
+ * things simple and similar to the avcC/H264 case above, instead
+ * of trying to handle the pre-standardization versions (as in
+ * libavcodec/hevc.c). */
+ if (st->codec->extradata_size > 21 && st->codec->extradata[0] == 1) {
+ s->nal_length_size = (st->codec->extradata[21] & 0x03) + 1;
+ }
+ break;
case AV_CODEC_ID_VORBIS:
case AV_CODEC_ID_THEORA:
if (!s->max_frames_per_packet) s->max_frames_per_packet = 15;
case AV_CODEC_ID_H263P:
ff_rtp_send_h263(s1, pkt->data, size);
break;
+ case AV_CODEC_ID_HEVC:
+ ff_rtp_send_hevc(s1, pkt->data, size);
+ break;
case AV_CODEC_ID_VORBIS:
case AV_CODEC_ID_THEORA:
ff_rtp_send_xiph(s1, pkt->data, size);
void ff_rtp_send_h263(AVFormatContext *s1, const uint8_t *buf1, int size);
void ff_rtp_send_h263_rfc2190(AVFormatContext *s1, const uint8_t *buf1, int size,
const uint8_t *mb_info, int mb_info_size);
+void ff_rtp_send_hevc(AVFormatContext *s1, const uint8_t *buf1, int size);
void ff_rtp_send_aac(AVFormatContext *s1, const uint8_t *buff, int size);
void ff_rtp_send_latm(AVFormatContext *s1, const uint8_t *buff, int size);
void ff_rtp_send_amr(AVFormatContext *s1, const uint8_t *buff, int size);
rtpctx->start_time_realtime = s->start_time_realtime;
avcodec_copy_context(rtpctx->streams[0]->codec, st->codec);
+ rtpctx->streams[0]->time_base = st->time_base;
if (handle) {
ret = ffio_fdopen(&rtpctx->pb, handle);
}
if (mb_info_pos < mb_info_count) {
const uint8_t *ptr = &mb_info[12*mb_info_pos];
+ /* get position in bits in the input packet at which the next info block should be used */
uint32_t bit_pos = AV_RL32(ptr);
- uint32_t pos = (bit_pos + 7)/8;
- if (pos <= end - buf_base) {
+ /* get position in bytes */
+ uint32_t pos_next_mb_info = (bit_pos + 7)/8;
+ /* check if data from the next MB info block should be used */
+ if (pos_next_mb_info <= end - buf_base) {
state.quant = ptr[4];
state.gobn = ptr[5];
state.mba = AV_RL16(&ptr[6]);
state.vmv1 = (int8_t) ptr[9];
state.hmv2 = (int8_t) ptr[10];
state.vmv2 = (int8_t) ptr[11];
- ebits = 8 * pos - bit_pos;
- len = pos - (buf - buf_base);
+ ebits = 8 * pos_next_mb_info - bit_pos;
+ len = pos_next_mb_info - (buf - buf_base);
mb_info_pos++;
- } else {
- av_log(s1, AV_LOG_ERROR,
- "Unable to split H263 packet, use -mb_info %d "
- "or lower.\n", s->max_payload_size - 8);
}
} else {
av_log(s1, AV_LOG_ERROR, "Unable to split H263 packet, "
#include "avc.h"
#include "rtpenc.h"
-static const uint8_t *avc_mp4_find_startcode(const uint8_t *start, const uint8_t *end, int nal_length_size)
-{
- unsigned int res = 0;
-
- if (end - start < nal_length_size)
- return NULL;
- while (nal_length_size--)
- res = (res << 8) | *start++;
-
- if (res > end - start)
- return NULL;
-
- return start + res;
-}
-
static void nal_send(AVFormatContext *s1, const uint8_t *buf, int size, int last)
{
RTPMuxContext *s = s1->priv_data;
s->timestamp = s->cur_timestamp;
if (s->nal_length_size)
- r = avc_mp4_find_startcode(buf1, end, s->nal_length_size) ? buf1 : end;
+ r = ff_avc_mp4_find_startcode(buf1, end, s->nal_length_size) ? buf1 : end;
else
r = ff_avc_find_startcode(buf1, end);
while (r < end) {
const uint8_t *r1;
if (s->nal_length_size) {
- r1 = avc_mp4_find_startcode(r, end, s->nal_length_size);
+ r1 = ff_avc_mp4_find_startcode(r, end, s->nal_length_size);
if (!r1)
r1 = end;
r += s->nal_length_size;
--- /dev/null
+/*
+ * RTP packetizer for HEVC/H.265 payload format (draft version 6)
+ * Copyright (c) 2014 Thomas Volkert <thomas@homer-conferencing.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 "avc.h"
+#include "avformat.h"
+#include "rtpenc.h"
+
+#define RTP_HEVC_HEADERS_SIZE 3
+
+static void nal_send(AVFormatContext *ctx, const uint8_t *buf, int len, int last_packet_of_frame)
+{
+ RTPMuxContext *rtp_ctx = ctx->priv_data;
+ int rtp_payload_size = rtp_ctx->max_payload_size - RTP_HEVC_HEADERS_SIZE;
+ int nal_type = (buf[0] >> 1) & 0x3F;
+
+ /* send it as one single NAL unit? */
+ if (len <= rtp_ctx->max_payload_size) {
+ /* use the original NAL unit buffer and transmit it as RTP payload */
+ ff_rtp_send_data(ctx, buf, len, last_packet_of_frame);
+ } else {
+ /*
+ create the HEVC payload header and transmit the buffer as fragmentation units (FU)
+
+ 0 1
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ |F| Type | LayerId | TID |
+ +-------------+-----------------+
+
+ F = 0
+ Type = 49 (fragmentation unit (FU))
+ LayerId = 0
+ TID = 1
+ */
+ rtp_ctx->buf[0] = 49 << 1;
+ rtp_ctx->buf[1] = 1;
+
+ /*
+ create the FU header
+
+ 0 1 2 3 4 5 6 7
+ +-+-+-+-+-+-+-+-+
+ |S|E| FuType |
+ +---------------+
+
+ S = variable
+ E = variable
+ FuType = NAL unit type
+ */
+ rtp_ctx->buf[2] = nal_type;
+ /* set the S bit: mark as start fragment */
+ rtp_ctx->buf[2] |= 1 << 7;
+
+ /* pass the original NAL header */
+ buf += 2;
+ len -= 2;
+
+ while (len > rtp_payload_size) {
+ /* complete and send current RTP packet */
+ memcpy(&rtp_ctx->buf[RTP_HEVC_HEADERS_SIZE], buf, rtp_payload_size);
+ ff_rtp_send_data(ctx, rtp_ctx->buf, rtp_ctx->max_payload_size, 0);
+
+ buf += rtp_payload_size;
+ len -= rtp_payload_size;
+
+ /* reset the S bit */
+ rtp_ctx->buf[2] &= ~(1 << 7);
+ }
+
+ /* set the E bit: mark as last fragment */
+ rtp_ctx->buf[2] |= 1 << 6;
+
+ /* complete and send last RTP packet */
+ memcpy(&rtp_ctx->buf[RTP_HEVC_HEADERS_SIZE], buf, len);
+ ff_rtp_send_data(ctx, rtp_ctx->buf, len + 2, last_packet_of_frame);
+ }
+}
+
+void ff_rtp_send_hevc(AVFormatContext *ctx, const uint8_t *frame_buf, int frame_size)
+{
+ const uint8_t *next_NAL_unit;
+ const uint8_t *buf_ptr, *buf_end = frame_buf + frame_size;
+ RTPMuxContext *rtp_ctx = ctx->priv_data;
+
+ /* use the default 90 KHz time stamp */
+ rtp_ctx->timestamp = rtp_ctx->cur_timestamp;
+
+ if (rtp_ctx->nal_length_size)
+ buf_ptr = ff_avc_mp4_find_startcode(frame_buf, buf_end, rtp_ctx->nal_length_size) ? frame_buf : buf_end;
+ else
+ buf_ptr = ff_avc_find_startcode(frame_buf, buf_end);
+
+ /* find all NAL units and send them as separate packets */
+ while (buf_ptr < buf_end) {
+ if (rtp_ctx->nal_length_size) {
+ next_NAL_unit = ff_avc_mp4_find_startcode(buf_ptr, buf_end, rtp_ctx->nal_length_size);
+ if (!next_NAL_unit)
+ next_NAL_unit = buf_end;
+
+ buf_ptr += rtp_ctx->nal_length_size;
+ } else {
+ while (!*(buf_ptr++))
+ ;
+ next_NAL_unit = ff_avc_find_startcode(buf_ptr, buf_end);
+ }
+ /* send the next NAL unit */
+ nal_send(ctx, buf_ptr, next_NAL_unit - buf_ptr, next_NAL_unit == buf_end);
+
+ /* jump to the next NAL unit */
+ buf_ptr = next_NAL_unit;
+ }
+}
const char *hostname, int port,
int local_port, int ttl,
int max_packet_size, int connect,
+ int dscp,
const char *include_sources,
const char *exclude_sources)
{
url_add_option(buf, buf_size, "pkt_size=%d", max_packet_size);
if (connect)
url_add_option(buf, buf_size, "connect=1");
+ if (dscp >= 0)
+ url_add_option(buf, buf_size, "dscp=%d", dscp);
url_add_option(buf, buf_size, "fifo_size=0");
if (include_sources && include_sources[0])
url_add_option(buf, buf_size, "sources=%s", include_sources);
ai = rtp_resolve_host(p, 0, SOCK_DGRAM, AF_UNSPEC, 0);
if (ai) {
source_addr = av_mallocz(sizeof(struct sockaddr_storage));
- if (!source_addr)
+ if (!source_addr) {
+ freeaddrinfo(ai);
break;
+ }
memcpy(source_addr, ai->ai_addr, ai->ai_addrlen);
freeaddrinfo(ai);
* 'sources=ip[,ip]' : list allowed source IP addresses
* 'block=ip[,ip]' : list disallowed source IP addresses
* 'write_to_source=0/1' : send packets to the source address of the latest received packet
+ * 'dscp=n' : set DSCP value to n (QoS)
* deprecated option:
* 'localport=n' : set the local port to n
*
RTPContext *s = h->priv_data;
int rtp_port, rtcp_port,
ttl, connect,
- local_rtp_port, local_rtcp_port, max_packet_size;
+ local_rtp_port, local_rtcp_port, max_packet_size, dscp;
char hostname[256], include_sources[1024] = "", exclude_sources[1024] = "";
char buf[1024];
char path[1024];
local_rtcp_port = -1;
max_packet_size = -1;
connect = 0;
+ dscp = -1;
p = strchr(uri, '?');
if (p) {
if (av_find_info_tag(buf, sizeof(buf), "write_to_source", p)) {
s->write_to_source = strtol(buf, NULL, 10);
}
+ if (av_find_info_tag(buf, sizeof(buf), "dscp", p)) {
+ dscp = strtol(buf, NULL, 10);
+ }
if (av_find_info_tag(buf, sizeof(buf), "sources", p)) {
av_strlcpy(include_sources, buf, sizeof(include_sources));
rtp_parse_addr_list(h, buf, &s->ssm_include_addrs, &s->nb_ssm_include_addrs);
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);
+ connect, dscp, 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);
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);
+ connect, dscp, 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;
}
build_udp_url(buf, sizeof(buf),
hostname, rtcp_port, local_rtcp_port, ttl, max_packet_size,
- connect, include_sources, exclude_sources);
+ connect, dscp, include_sources, exclude_sources);
if (ffurl_open(&s->rtcp_hd, buf, flags, &h->interrupt_callback, NULL) < 0)
goto fail;
break;
if (!strcmp(ff_rtp_enc_name(rtsp_st->sdp_payload_type), "MP2T")) {
/* no corresponding stream */
if (rt->transport == RTSP_TRANSPORT_RAW) {
- if (!rt->ts && CONFIG_RTPDEC)
+ if (CONFIG_RTPDEC && !rt->ts)
rt->ts = avpriv_mpegts_parse_open(s);
} else {
RTPDynamicProtocolHandler *handler;
avio_close(rtpctx->pb);
}
avformat_free_context(rtpctx);
- } else if (rt->transport == RTSP_TRANSPORT_RDT && CONFIG_RTPDEC)
+ } else if (CONFIG_RTPDEC && rt->transport == RTSP_TRANSPORT_RDT)
ff_rdt_parse_close(rtsp_st->transport_priv);
- else if (rt->transport == RTSP_TRANSPORT_RTP && CONFIG_RTPDEC)
+ else if (CONFIG_RTPDEC && rt->transport == RTSP_TRANSPORT_RTP)
ff_rtp_parse_close(rtsp_st->transport_priv);
}
rtsp_st->transport_priv = NULL;
if (rt->asf_ctx) {
avformat_close_input(&rt->asf_ctx);
}
- if (rt->ts && CONFIG_RTPDEC)
+ if (CONFIG_RTPDEC && rt->ts)
avpriv_mpegts_parse_close(rt->ts);
av_free(rt->p);
av_free(rt->recvbuf);
if (!st)
s->ctx_flags |= AVFMTCTX_NOHEADER;
- if (s->oformat && CONFIG_RTSP_MUXER) {
+ if (CONFIG_RTSP_MUXER && s->oformat) {
int ret = ff_rtp_chain_mux_open((AVFormatContext **)&rtsp_st->transport_priv,
s, st, rtsp_st->rtp_handle,
RTSP_TCP_MAX_PACKET_SIZE,
st->time_base = ((AVFormatContext*)rtsp_st->transport_priv)->streams[0]->time_base;
} else if (rt->transport == RTSP_TRANSPORT_RAW) {
return 0; // Don't need to open any parser here
- } else if (rt->transport == RTSP_TRANSPORT_RDT && CONFIG_RTPDEC)
+ } else if (CONFIG_RTPDEC && rt->transport == RTSP_TRANSPORT_RDT)
rtsp_st->transport_priv = ff_rdt_parse_open(s, st->index,
rtsp_st->dynamic_protocol_context,
rtsp_st->dynamic_handler);
if (!rtsp_st->transport_priv) {
return AVERROR(ENOMEM);
- } else if (rt->transport == RTSP_TRANSPORT_RTP && CONFIG_RTPDEC) {
+ } else if (CONFIG_RTPDEC && rt->transport == RTSP_TRANSPORT_RTP) {
if (rtsp_st->dynamic_handler) {
ff_rtp_parse_set_dynamic_protocol(rtsp_st->transport_priv,
rtsp_st->dynamic_protocol_context,
if (content_length > 0) {
/* leave some room for a trailing '\0' (useful for simple parsing) */
content = av_malloc(content_length + 1);
+ if (!content)
+ return AVERROR(ENOMEM);
ffurl_read_complete(rt->rtsp_hd, content, content_length);
content[content_length] = '\0';
}
}
ffurl_write(rt->rtsp_hd_out, ptr, strlen(ptr));
- rt->last_cmd_time = av_gettime();
+ rt->last_cmd_time = av_gettime_relative();
/* Even if the request from the server had data, it is not the data
* that the caller wants or expects. The memory could also be leaked
* if the actual following reply has content data. */
}
ffurl_write(rt->rtsp_hd_out, send_content, send_content_length);
}
- rt->last_cmd_time = av_gettime();
+ rt->last_cmd_time = av_gettime_relative();
return 0;
}
transport);
if (rt->accept_dynamic_rate)
av_strlcat(cmd, "x-Dynamic-Rate: 0\r\n", sizeof(cmd));
- if (i == 0 && rt->server_type == RTSP_SERVER_REAL && CONFIG_RTPDEC) {
+ if (CONFIG_RTPDEC && i == 0 && rt->server_type == RTSP_SERVER_REAL) {
char real_res[41], real_csum[9];
ff_rdt_calc_response_and_checksum(real_res, real_csum,
real_challenge);
goto fail;
} else if (reply->status_code != RTSP_STATUS_OK ||
reply->nb_transports != 1) {
- err = AVERROR_INVALIDDATA;
+ err = ff_rtsp_averror(reply->status_code, AVERROR_INVALIDDATA);
goto fail;
}
* potential NAT router by sending dummy packets.
* RTP/RTCP dummy packets are used for RDT, too.
*/
- if (!(rt->server_type == RTSP_SERVER_WMS && i > 1) && s->iformat &&
- CONFIG_RTPDEC)
+ if (CONFIG_RTPDEC &&
+ !(rt->server_type == RTSP_SERVER_WMS && i > 1) && s->iformat)
ff_rtp_send_punch_packets(rtsp_st->rtp_handle);
break;
}
int ff_rtsp_connect(AVFormatContext *s)
{
RTSPState *rt = s->priv_data;
- char host[1024], path[1024], tcpname[1024], cmd[2048], auth[128];
+ char proto[128], host[1024], path[1024];
+ char tcpname[1024], cmd[2048], auth[128];
+ const char *lower_rtsp_proto = "tcp";
int port, err, tcp_fd;
RTSPMessageHeader reply1 = {0}, *reply = &reply1;
int lower_transport_mask = 0;
+ int default_port = RTSP_DEFAULT_PORT;
char real_challenge[64] = "";
struct sockaddr_storage peer;
socklen_t peer_len = sizeof(peer);
rt->lower_transport_mask &= (1 << RTSP_LOWER_TRANSPORT_NB) - 1;
redirect:
- lower_transport_mask = rt->lower_transport_mask;
/* extract hostname and port */
- av_url_split(NULL, 0, auth, sizeof(auth),
+ av_url_split(proto, sizeof(proto), auth, sizeof(auth),
host, sizeof(host), &port, path, sizeof(path), s->filename);
+
+ if (!strcmp(proto, "rtsps")) {
+ lower_rtsp_proto = "tls";
+ default_port = RTSPS_DEFAULT_PORT;
+ rt->lower_transport_mask = 1 << RTSP_LOWER_TRANSPORT_TCP;
+ }
+
if (*auth) {
av_strlcpy(rt->auth, auth, sizeof(rt->auth));
}
if (port < 0)
- port = RTSP_DEFAULT_PORT;
+ port = default_port;
+
+ lower_transport_mask = rt->lower_transport_mask;
if (!lower_transport_mask)
lower_transport_mask = (1 << RTSP_LOWER_TRANSPORT_NB) - 1;
/* Construct the URI used in request; this is similar to s->filename,
* but with authentication credentials removed and RTSP specific options
* stripped out. */
- ff_url_join(rt->control_uri, sizeof(rt->control_uri), "rtsp", NULL,
+ ff_url_join(rt->control_uri, sizeof(rt->control_uri), proto, NULL,
host, port, "%s", path);
if (rt->control_transport == RTSP_MODE_TUNNEL) {
goto fail;
}
} else {
+ int ret;
/* open the tcp connection */
- ff_url_join(tcpname, sizeof(tcpname), "tcp", NULL, host, port,
+ ff_url_join(tcpname, sizeof(tcpname), lower_rtsp_proto, NULL,
+ host, port,
"?timeout=%d", rt->stimeout);
- if (ffurl_open(&rt->rtsp_hd, tcpname, AVIO_FLAG_READ_WRITE,
- &s->interrupt_callback, NULL) < 0) {
- err = AVERROR(EIO);
+ if ((ret = ffurl_open(&rt->rtsp_hd, tcpname, AVIO_FLAG_READ_WRITE,
+ &s->interrupt_callback, NULL)) < 0) {
+ err = ret;
goto fail;
}
rt->rtsp_hd_out = rt->rtsp_hd;
sizeof(cmd));
ff_rtsp_send_cmd(s, "OPTIONS", rt->control_uri, cmd, reply, NULL);
if (reply->status_code != RTSP_STATUS_OK) {
- err = AVERROR_INVALIDDATA;
+ err = ff_rtsp_averror(reply->status_code, AVERROR_INVALIDDATA);
goto fail;
}
break;
}
- if (s->iformat && CONFIG_RTSP_DEMUXER)
+ if (CONFIG_RTSP_DEMUXER && s->iformat)
err = ff_rtsp_setup_input_streams(s, reply);
else if (CONFIG_RTSP_MUXER)
err = ff_rtsp_setup_output_streams(s, host);
+ else
+ av_assert0(0);
if (err)
goto fail;
ff_rtsp_close_connections(s);
if (reply->status_code >=300 && reply->status_code < 400 && s->iformat) {
av_strlcpy(s->filename, reply->location, sizeof(s->filename));
+ rt->session_id[0] = '\0';
av_log(s, AV_LOG_INFO, "Status %d: Redirecting to %s\n",
reply->status_code,
s->filename);
for (;;) {
if (ff_check_interrupt(&s->interrupt_callback))
return AVERROR_EXIT;
- if (wait_end && wait_end - av_gettime() < 0)
+ if (wait_end && wait_end - av_gettime_relative() < 0)
return AVERROR(EAGAIN);
max_p = 0;
if (rt->rtsp_hd) {
ret = ff_rdt_parse_packet(rt->cur_transport_priv, pkt, NULL, 0);
} else if (rt->transport == RTSP_TRANSPORT_RTP) {
ret = ff_rtp_parse_packet(rt->cur_transport_priv, pkt, NULL, 0);
- } else if (rt->ts && CONFIG_RTPDEC) {
+ } else if (CONFIG_RTPDEC && rt->ts) {
ret = avpriv_mpegts_parse_packet(rt->ts, pkt, rt->recvbuf + rt->recvbuf_pos, rt->recvbuf_len - rt->recvbuf_pos);
if (ret >= 0) {
rt->recvbuf_pos += ret;
break;
case RTSP_LOWER_TRANSPORT_CUSTOM:
if (first_queue_st && rt->transport == RTSP_TRANSPORT_RTP &&
- wait_end && wait_end < av_gettime())
+ wait_end && wait_end < av_gettime_relative())
len = AVERROR(EAGAIN);
else
len = ffio_read_partial(s->pb, rt->recvbuf, RECVBUF_SIZE);
return AVERROR_EOF;
}
}
- } else if (rt->ts && CONFIG_RTPDEC) {
+ } else if (CONFIG_RTPDEC && rt->ts) {
ret = avpriv_mpegts_parse_packet(rt->ts, pkt, rt->recvbuf, len);
if (ret >= 0) {
if (ret < len) {
};
#define RTSP_DEFAULT_PORT 554
+#define RTSPS_DEFAULT_PORT 322
#define RTSP_MAX_TRANSPORTS 8
#define RTSP_TCP_MAX_PACKET_SIZE 1472
#define RTSP_DEFAULT_NB_AUDIO_CHANNELS 1
#define AVFORMAT_RTSPCODES_H
#include "libavutil/common.h"
+#include "libavformat/http.h"
/** RTSP handling */
enum RTSPStatusCode {
RECORD,
UNKNOWN = -1,
};
+
+static inline int ff_rtsp_averror(enum RTSPStatusCode status_code, int default_averror)
+{
+ return ff_http_averror(status_code, default_averror);
+}
+
#endif /* AVFORMAT_RTSPCODES_H */
RTSPState *rt = s->priv_data;
const char *linept, *searchlinept;
linept = strchr(line, ' ');
+
if (!linept) {
av_log(s, AV_LOG_ERROR, "Error parsing method string\n");
return AVERROR_INVALIDDATA;
}
+
if (linept - line > methodsize - 1) {
av_log(s, AV_LOG_ERROR, "Method string too long\n");
return AVERROR(EIO);
}
ff_rtsp_send_cmd(s, "PLAY", rt->control_uri, cmd, reply, NULL);
if (reply->status_code != RTSP_STATUS_OK) {
- return -1;
+ return ff_rtsp_averror(reply->status_code, -1);
}
if (rt->transport == RTSP_TRANSPORT_RTP &&
reply->range_start != AV_NOPTS_VALUE) {
else if (!(rt->server_type == RTSP_SERVER_REAL && rt->need_subscription)) {
ff_rtsp_send_cmd(s, "PAUSE", rt->control_uri, NULL, reply, NULL);
if (reply->status_code != RTSP_STATUS_OK) {
- return -1;
+ return ff_rtsp_averror(reply->status_code, -1);
}
}
rt->state = RTSP_STATE_PAUSED;
sizeof(cmd));
}
ff_rtsp_send_cmd(s, "DESCRIBE", rt->control_uri, cmd, reply, &content);
- if (!content)
- return AVERROR_INVALIDDATA;
if (reply->status_code != RTSP_STATUS_OK) {
av_freep(&content);
- return AVERROR_INVALIDDATA;
+ return ff_rtsp_averror(reply->status_code, AVERROR_INVALIDDATA);
}
+ if (!content)
+ return AVERROR_INVALIDDATA;
av_log(s, AV_LOG_VERBOSE, "SDP:\n%s\n", content);
/* now we got the SDP description, we parse it */
static int rtsp_listen(AVFormatContext *s)
{
RTSPState *rt = s->priv_data;
- char host[128], path[512], auth[128];
+ char proto[128], host[128], path[512], auth[128];
char uri[500];
int port;
+ int default_port = RTSP_DEFAULT_PORT;
char tcpname[500];
+ const char *lower_proto = "tcp";
unsigned char rbuf[4096];
unsigned char method[10];
int rbuflen = 0;
enum RTSPMethod methodcode;
/* extract hostname and port */
- av_url_split(NULL, 0, auth, sizeof(auth), host, sizeof(host), &port,
- path, sizeof(path), s->filename);
+ av_url_split(proto, sizeof(proto), auth, sizeof(auth), host, sizeof(host),
+ &port, path, sizeof(path), s->filename);
/* ff_url_join. No authorization by now (NULL) */
- ff_url_join(rt->control_uri, sizeof(rt->control_uri), "rtsp", NULL, host,
+ ff_url_join(rt->control_uri, sizeof(rt->control_uri), proto, NULL, host,
port, "%s", path);
+ if (!strcmp(proto, "rtsps")) {
+ lower_proto = "tls";
+ default_port = RTSPS_DEFAULT_PORT;
+ }
+
if (port < 0)
- port = RTSP_DEFAULT_PORT;
+ port = default_port;
/* Create TCP connection */
- ff_url_join(tcpname, sizeof(tcpname), "tcp", NULL, host, port,
+ ff_url_join(tcpname, sizeof(tcpname), lower_proto, NULL, host, port,
"?listen&listen_timeout=%d", rt->initial_timeout * 1000);
if (ret = ffurl_open(&rt->rtsp_hd, tcpname, AVIO_FLAG_READ_WRITE,
static int rtsp_probe(AVProbeData *p)
{
- if (av_strstart(p->filename, "rtsp:", NULL))
+ if (
+#if CONFIG_TLS_PROTOCOL
+ av_strstart(p->filename, "rtsps:", NULL) ||
+#endif
+ av_strstart(p->filename, "rtsp:", NULL))
return AVPROBE_SCORE_MAX;
return 0;
}
if (rt->initial_pause) {
/* do not start immediately */
} else {
- if (rtsp_read_play(s) < 0) {
+ if ((ret = rtsp_read_play(s)) < 0) {
ff_rtsp_close_streams(s);
ff_rtsp_close_connections(s);
- return AVERROR_INVALIDDATA;
+ return ret;
}
}
}
ff_rtsp_send_cmd(s, "SET_PARAMETER", rt->control_uri,
cmd, reply, NULL);
if (reply->status_code != RTSP_STATUS_OK)
- return AVERROR_INVALIDDATA;
+ return ff_rtsp_averror(reply->status_code, AVERROR_INVALIDDATA);
rt->need_subscription = 1;
}
}
ff_rtsp_send_cmd(s, "SET_PARAMETER", rt->control_uri,
cmd, reply, NULL);
if (reply->status_code != RTSP_STATUS_OK)
- return AVERROR_INVALIDDATA;
+ return ff_rtsp_averror(reply->status_code, AVERROR_INVALIDDATA);
rt->need_subscription = 0;
if (rt->state == RTSP_STATE_STREAMING)
if (!(rt->rtsp_flags & RTSP_FLAG_LISTEN)) {
/* send dummy request to keep TCP connection alive */
- if ((av_gettime() - rt->last_cmd_time) / 1000000 >= rt->timeout / 2 ||
+ if ((av_gettime_relative() - rt->last_cmd_time) / 1000000 >= rt->timeout / 2 ||
rt->auth_state.stale) {
if (rt->server_type == RTSP_SERVER_WMS ||
(rt->server_type != RTSP_SERVER_REAL &&
int64_t timestamp, int flags)
{
RTSPState *rt = s->priv_data;
+ int ret;
rt->seek_timestamp = av_rescale_q(timestamp,
s->streams[stream_index]->time_base,
case RTSP_STATE_IDLE:
break;
case RTSP_STATE_STREAMING:
- if (rtsp_read_pause(s) != 0)
- return -1;
+ if ((ret = rtsp_read_pause(s)) != 0)
+ return ret;
rt->state = RTSP_STATE_SEEKING;
- if (rtsp_read_play(s) != 0)
- return -1;
+ if ((ret = rtsp_read_play(s)) != 0)
+ return ret;
break;
case RTSP_STATE_PAUSED:
rt->state = RTSP_STATE_IDLE;
reply, NULL, sdp, strlen(sdp));
av_free(sdp);
if (reply->status_code != RTSP_STATUS_OK)
- return AVERROR_INVALIDDATA;
+ return ff_rtsp_averror(reply->status_code, AVERROR_INVALIDDATA);
/* Set up the RTSPStreams for each AVStream */
for (i = 0; i < s->nb_streams; i++) {
"Range: npt=0.000-\r\n");
ff_rtsp_send_cmd(s, "RECORD", rt->control_uri, cmd, reply, NULL);
if (reply->status_code != RTSP_STATUS_OK)
- return -1;
+ return ff_rtsp_averror(reply->status_code, -1);
rt->state = RTSP_STATE_STREAMING;
return 0;
}
char c = 0;
int res = 0, got_first_sync_point = 0;
FFTextReader tr;
- ff_text_init_avio(&tr, s->pb);
+ ff_text_init_avio(s, &tr, s->pb);
if (!st)
return AVERROR(ENOMEM);
*/
#include "avformat.h"
+#include "libavutil/avassert.h"
#include "libavutil/avstring.h"
#include "libavutil/intreadwrite.h"
#include "network.h"
sap->sdp_ctx->max_delay = s->max_delay;
sap->sdp_ctx->pb = &sap->sdp_pb;
sap->sdp_ctx->interrupt_callback = s->interrupt_callback;
+
+ if ((ret = ff_copy_whitelists(sap->sdp_ctx, s)) < 0)
+ goto fail;
+
ret = avformat_open_input(&sap->sdp_ctx, "temp.sdp", infmt, NULL);
if (ret < 0)
goto fail;
#include "libavutil/intreadwrite.h"
#include "libavutil/log.h"
#include "libavutil/opt.h"
+#include "libavutil/time_internal.h"
#include "avformat.h"
#include "internal.h"
} else {
/* Mixed relative/absolute ts: expand */
time_t now0;
- struct tm *tm;
+ struct tm *tm, tmpbuf;
av_log(log, AV_LOG_WARNING,
"Scripts with mixed absolute and relative timestamps can give "
"unexpected results (pause, seeking, time zone change).\n");
#undef time
time(&now0);
- tm = localtime(&now0);
+ tm = localtime_r(&now0, &tmpbuf);
now = tm ? tm->tm_hour * 3600 + tm->tm_min * 60 + tm->tm_sec :
now0 % DAY;
av_log(log, AV_LOG_INFO, "Using %02d:%02d:%02d as NOW.\n",
info.sinfo_stream = AV_RB16(buf);
if (info.sinfo_stream > s->max_streams) {
av_log(h, AV_LOG_ERROR, "bad input data\n");
- return AVERROR(EINVAL);
+ return AVERROR_BUG;
}
ret = ff_sctp_send(s->fd, buf + 2, size - 2, &info, MSG_EOR);
} else
#include "avformat.h"
#include "internal.h"
#include "avc.h"
+#include "hevc.h"
#include "rtp.h"
#if CONFIG_NETWORK
#include "network.h"
const uint8_t *r;
static const char pset_string[] = "; sprop-parameter-sets=";
static const char profile_string[] = "; profile-level-id=";
- uint8_t *orig_extradata = NULL;
- int orig_extradata_size = 0;
+ uint8_t *extradata = c->extradata;
+ int extradata_size = c->extradata_size;
+ uint8_t *tmpbuf = NULL;
const uint8_t *sps = NULL, *sps_end;
if (c->extradata_size > MAX_EXTRADATA_SIZE) {
return NULL;
}
if (c->extradata[0] == 1) {
- uint8_t *dummy_p;
- int dummy_int;
- AVBitStreamFilterContext *bsfc= av_bitstream_filter_init("h264_mp4toannexb");
-
- if (!bsfc) {
- av_log(c, AV_LOG_ERROR, "Cannot open the h264_mp4toannexb BSF!\n");
-
+ if (ff_avc_write_annexb_extradata(c->extradata, &extradata,
+ &extradata_size))
return NULL;
- }
-
- orig_extradata_size = c->extradata_size;
- orig_extradata = av_mallocz(orig_extradata_size +
- FF_INPUT_BUFFER_PADDING_SIZE);
- if (!orig_extradata) {
- av_bitstream_filter_close(bsfc);
- return NULL;
- }
- memcpy(orig_extradata, c->extradata, orig_extradata_size);
- av_bitstream_filter_filter(bsfc, c, NULL, &dummy_p, &dummy_int, NULL, 0, 0);
- av_bitstream_filter_close(bsfc);
+ tmpbuf = extradata;
}
psets = av_mallocz(MAX_PSET_SIZE);
if (!psets) {
av_log(c, AV_LOG_ERROR, "Cannot allocate memory for the parameter sets.\n");
- av_free(orig_extradata);
+ av_free(tmpbuf);
return NULL;
}
memcpy(psets, pset_string, strlen(pset_string));
p = psets + strlen(pset_string);
- r = ff_avc_find_startcode(c->extradata, c->extradata + c->extradata_size);
- while (r < c->extradata + c->extradata_size) {
+ r = ff_avc_find_startcode(extradata, extradata + extradata_size);
+ while (r < extradata + extradata_size) {
const uint8_t *r1;
uint8_t nal_type;
while (!*(r++));
nal_type = *r & 0x1f;
- r1 = ff_avc_find_startcode(r, c->extradata + c->extradata_size);
+ r1 = ff_avc_find_startcode(r, extradata + extradata_size);
if (nal_type != 7 && nal_type != 8) { /* Only output SPS and PPS */
r = r1;
continue;
if (!av_base64_encode(p, MAX_PSET_SIZE - (p - psets), r, r1 - r)) {
av_log(c, AV_LOG_ERROR, "Cannot Base64-encode %"PTRDIFF_SPECIFIER" %"PTRDIFF_SPECIFIER"!\n", MAX_PSET_SIZE - (p - psets), r1 - r);
av_free(psets);
+ av_free(tmpbuf);
return NULL;
}
ff_data_to_hex(p, sps + 1, 3, 0);
p[6] = '\0';
}
- if (orig_extradata) {
- av_free(c->extradata);
- c->extradata = orig_extradata;
- c->extradata_size = orig_extradata_size;
+ av_free(tmpbuf);
+
+ return psets;
+}
+
+static char *extradata2psets_hevc(AVCodecContext *c)
+{
+ char *psets;
+ uint8_t *extradata = c->extradata;
+ int extradata_size = c->extradata_size;
+ uint8_t *tmpbuf = NULL;
+ int ps_pos[3] = { 0 };
+ static const char * const ps_names[3] = { "vps", "sps", "pps" };
+ int num_arrays, num_nalus;
+ int pos, i, j;
+
+ // Convert to hvcc format. Since we need to group multiple NALUs of
+ // the same type, and we might need to convert from one format to the
+ // other anyway, we get away with a little less work by using the hvcc
+ // format.
+ if (c->extradata[0] != 1) {
+ AVIOContext *pb;
+ if (avio_open_dyn_buf(&pb) < 0)
+ return NULL;
+ if (ff_isom_write_hvcc(pb, c->extradata, c->extradata_size, 0) < 0) {
+ avio_close_dyn_buf(pb, &tmpbuf);
+ goto err;
+ }
+ extradata_size = avio_close_dyn_buf(pb, &extradata);
+ tmpbuf = extradata;
+ }
+
+ if (extradata_size < 23)
+ goto err;
+
+ num_arrays = extradata[22];
+ pos = 23;
+ for (i = 0; i < num_arrays; i++) {
+ int num_nalus, nalu_type;
+ if (pos + 3 > extradata_size)
+ goto err;
+ nalu_type = extradata[pos] & 0x3f;
+ // Not including libavcodec/hevc.h to avoid confusion between
+ // NAL_* with the same name for both H264 and HEVC.
+ if (nalu_type == 32) // VPS
+ ps_pos[0] = pos;
+ else if (nalu_type == 33) // SPS
+ ps_pos[1] = pos;
+ else if (nalu_type == 34) // PPS
+ ps_pos[2] = pos;
+ num_nalus = AV_RB16(&extradata[pos + 1]);
+ pos += 3;
+ for (j = 0; j < num_nalus; j++) {
+ int len;
+ if (pos + 2 > extradata_size)
+ goto err;
+ len = AV_RB16(&extradata[pos]);
+ pos += 2;
+ if (pos + len > extradata_size)
+ goto err;
+ pos += len;
+ }
+ }
+ if (!ps_pos[0] || !ps_pos[1] || !ps_pos[2])
+ goto err;
+
+ psets = av_mallocz(MAX_PSET_SIZE);
+ if (!psets)
+ goto err;
+ psets[0] = '\0';
+
+ for (i = 0; i < 3; i++) {
+ pos = ps_pos[i];
+
+ if (i > 0)
+ av_strlcat(psets, "; ", MAX_PSET_SIZE);
+ av_strlcatf(psets, MAX_PSET_SIZE, "sprop-%s=", ps_names[i]);
+
+ // Skipping boundary checks in the input here; we've already traversed
+ // the whole hvcc structure above without issues
+ num_nalus = AV_RB16(&extradata[pos + 1]);
+ pos += 3;
+ for (j = 0; j < num_nalus; j++) {
+ int len = AV_RB16(&extradata[pos]);
+ int strpos;
+ pos += 2;
+ if (j > 0)
+ av_strlcat(psets, ",", MAX_PSET_SIZE);
+ strpos = strlen(psets);
+ if (!av_base64_encode(psets + strpos, MAX_PSET_SIZE - strpos,
+ &extradata[pos], len)) {
+ av_free(psets);
+ goto err;
+ }
+ pos += len;
+ }
}
+ av_free(tmpbuf);
return psets;
+
+err:
+ av_free(tmpbuf);
+ return NULL;
}
static char *extradata2config(AVCodecContext *c)
payload_type,
payload_type, c->width, c->height);
break;
+ case AV_CODEC_ID_HEVC:
+ if (c->extradata_size)
+ config = extradata2psets_hevc(c);
+ av_strlcatf(buff, size, "a=rtpmap:%d H265/90000\r\n", payload_type);
+ if (config)
+ av_strlcatf(buff, size, "a=fmtp:%d %s\r\n",
+ payload_type, config);
+ break;
case AV_CODEC_ID_MPEG4:
if (c->extradata_size) {
config = extradata2config(c);
}
break;
case AV_CODEC_ID_OPUS:
- av_strlcatf(buff, size, "a=rtpmap:%d opus/48000\r\n",
+ /* The opus RTP draft says that all opus streams MUST be declared
+ as stereo, to avoid negotiation failures. The actual number of
+ channels can change on a packet-by-packet basis. The number of
+ channels a receiver prefers to receive or a sender plans to send
+ can be declared via fmtp parameters (both default to mono), but
+ receivers MUST be able to receive and process stereo packets. */
+ av_strlcatf(buff, size, "a=rtpmap:%d opus/48000/2\r\n",
payload_type);
+ if (c->channels == 2) {
+ av_strlcatf(buff, size, "a=fmtp:%d sprop-stereo:1\r\n",
+ payload_type);
+ }
break;
default:
/* Nothing special to do here... */
#include "libavutil/parseutils.h"
#include "libavutil/mathematics.h"
#include "libavutil/time.h"
+#include "libavutil/time_internal.h"
#include "libavutil/timestamp.h"
typedef struct SegmentListEntry {
oc = seg->avf;
oc->interrupt_callback = s->interrupt_callback;
+ oc->max_delay = s->max_delay;
av_dict_copy(&oc->metadata, s->metadata, 0);
for (i = 0; i < s->nb_streams; i++) {
ocodec->codec_tag = 0;
}
st->sample_aspect_ratio = s->streams[i]->sample_aspect_ratio;
+ st->time_base = s->streams[i]->time_base;
av_dict_copy(&st->metadata, s->streams[i]->metadata, 0);
}
AVFormatContext *oc = NULL;
AVDictionary *options = NULL;
int ret;
+ int i;
seg->segment_count = 0;
if (!seg->write_header_trailer)
}
seg->segment_frame_count = 0;
+ av_assert0(s->nb_streams == oc->nb_streams);
+ for (i = 0; i < s->nb_streams; i++) {
+ AVStream *inner_st = oc->streams[i];
+ AVStream *outer_st = s->streams[i];
+ avpriv_set_pts_info(outer_st, inner_st->pts_wrap_bits, inner_st->time_base.num, inner_st->time_base.den);
+ }
+
if (oc->avoid_negative_ts > 0 && s->avoid_negative_ts < 0)
s->avoid_negative_ts = 1;
if (seg->use_clocktime) {
int64_t avgt = av_gettime();
time_t sec = avgt / 1000000;
-#if HAVE_LOCALTIME_R
localtime_r(&sec, &ti);
-#else
- ti = *localtime(&sec);
-#endif
usecs = (int64_t)(ti.tm_hour*3600 + ti.tm_min*60 + ti.tm_sec) * 1000000 + (avgt % 1000000);
wrapped_val = usecs % seg->time;
if (seg->last_cut != usecs && wrapped_val < seg->last_val) {
#include "libavutil/opt.h"
#include "libavutil/avstring.h"
+#include "libavutil/file.h"
#include "libavutil/mathematics.h"
#include "libavutil/intreadwrite.h"
avio_printf(out, "</SmoothStreamingMedia>\n");
avio_flush(out);
avio_close(out);
- rename(temp_filename, filename);
- return 0;
+ return ff_rename(temp_filename, filename, s);
}
static int ism_write_header(AVFormatContext *s)
AVOutputFormat *oformat;
if (mkdir(s->filename, 0777) == -1 && errno != EEXIST) {
- av_log(s, AV_LOG_ERROR, "mkdir failed\n");
ret = AVERROR(errno);
+ av_log(s, AV_LOG_ERROR, "mkdir failed\n");
goto fail;
}
}
avcodec_copy_context(st->codec, s->streams[i]->codec);
st->sample_aspect_ratio = s->streams[i]->sample_aspect_ratio;
+ st->time_base = s->streams[i]->time_base;
ctx->pb = avio_alloc_context(os->iobuf, sizeof(os->iobuf), AVIO_FLAG_WRITE, os, NULL, ism_write, ism_seek);
if (!ctx->pb) {
for (i = 0; i < s->nb_streams; i++) {
OutputStream *os = &c->streams[i];
char filename[1024], target_filename[1024], header_filename[1024];
- int64_t start_pos = os->tail_pos, size;
+ int64_t size;
int64_t start_ts, duration, moof_size;
if (!os->packets_written)
continue;
ffurl_close(os->out);
os->out = NULL;
- size = os->tail_pos - start_pos;
+ size = os->tail_pos - os->cur_start_pos;
if ((ret = parse_fragment(s, filename, &start_ts, &duration, &moof_size, size)) < 0)
break;
snprintf(header_filename, sizeof(header_filename), "%s/FragmentInfo(%s=%"PRIu64")", os->dirname, os->stream_type_tag, start_ts);
snprintf(target_filename, sizeof(target_filename), "%s/Fragments(%s=%"PRIu64")", os->dirname, os->stream_type_tag, start_ts);
copy_moof(s, filename, header_filename, moof_size);
- rename(filename, target_filename);
- add_fragment(os, target_filename, header_filename, start_ts, duration, start_pos, size);
+ ret = ff_rename(filename, target_filename, s);
+ if (ret < 0)
+ break;
+ add_fragment(os, target_filename, header_filename, start_ts, duration,
+ os->cur_start_pos, size);
}
if (c->window_size || (final && c->remove_at_exit)) {
SmoothStreamingContext *c = s->priv_data;
AVStream *st = s->streams[pkt->stream_index];
OutputStream *os = &c->streams[pkt->stream_index];
- int64_t end_dts = (c->nb_fragments + 1LL) * c->min_frag_duration;
+ int64_t end_dts = (c->nb_fragments + 1) * (int64_t) c->min_frag_duration;
int ret;
if (st->first_dts == AV_NOPTS_VALUE)
static enum AVCodecID sol_codec_id(int magic, int type)
{
- if (magic == 0x0B8D)
- {
- if (type & SOL_DPCM) return AV_CODEC_ID_SOL_DPCM;
- else return AV_CODEC_ID_PCM_U8;
- }
if (type & SOL_DPCM)
- {
- if (type & SOL_16BIT) return AV_CODEC_ID_SOL_DPCM;
- else if (magic == 0x0C8D) return AV_CODEC_ID_SOL_DPCM;
- else return AV_CODEC_ID_SOL_DPCM;
- }
- if (type & SOL_16BIT) return AV_CODEC_ID_PCM_S16LE;
+ return AV_CODEC_ID_SOL_DPCM;
+
+ if (magic == 0x0B8D)
+ return AV_CODEC_ID_PCM_U8;
+
+ if (type & SOL_16BIT)
+ return AV_CODEC_ID_PCM_S16LE;
+
return AV_CODEC_ID_PCM_U8;
}
static int srt_probe(AVProbeData *p)
{
- int i, v, num = 0;
+ int v;
+ char buf[64], *pbuf;
FFTextReader tr;
ff_text_init_buf(&tr, p->buf, p->buf_size);
while (ff_text_peek_r8(&tr) == '\r' || ff_text_peek_r8(&tr) == '\n')
ff_text_r8(&tr);
- for (i=0; i<2; i++) {
- char buf[128];
- if (ff_subtitles_read_line(&tr, buf, sizeof(buf)) < 0)
- break;
- if ((num == i || num + 1 == i)
- && buf[0] >= '0' && buf[1] <= '9' && strstr(buf, " --> ")
- && sscanf(buf, "%*d:%*2d:%*2d%*1[,.]%*3d --> %*d:%*2d:%*2d%*1[,.]%3d", &v) == 1)
- return AVPROBE_SCORE_MAX;
- num = atoi(buf);
- }
+
+ /* Check if the first non-empty line is a number. We do not check what the
+ * number is because in practice it can be anything. */
+ if (ff_subtitles_read_line(&tr, buf, sizeof(buf)) < 0 ||
+ strtol(buf, &pbuf, 10) < 0 || *pbuf)
+ return 0;
+
+ /* Check if the next line matches a SRT timestamp */
+ if (ff_subtitles_read_line(&tr, buf, sizeof(buf)) < 0)
+ return 0;
+ if (buf[0] >= '0' && buf[1] <= '9' && strstr(buf, " --> ")
+ && sscanf(buf, "%*d:%*2d:%*2d%*1[,.]%*3d --> %*d:%*2d:%*2d%*1[,.]%3d", &v) == 1)
+ return AVPROBE_SCORE_MAX;
+
return 0;
}
AVStream *st = avformat_new_stream(s, NULL);
int res = 0;
FFTextReader tr;
- ff_text_init_avio(&tr, s->pb);
+ ff_text_init_avio(s, &tr, s->pb);
if (!st)
return AVERROR(ENOMEM);
return AVERROR(EINVAL);
}
if (avf->streams[0]->codec->codec_id != AV_CODEC_ID_TEXT &&
- avf->streams[0]->codec->codec_id != AV_CODEC_ID_SUBRIP &&
- avf->streams[0]->codec->codec_id != AV_CODEC_ID_SRT) {
+ avf->streams[0]->codec->codec_id != AV_CODEC_ID_SUBRIP) {
av_log(avf, AV_LOG_ERROR,
"Unsupported subtitles codec: %s\n",
avcodec_get_name(avf->streams[0]->codec->codec_id));
static int srt_write_packet(AVFormatContext *avf, AVPacket *pkt)
{
SRTContext *srt = avf->priv_data;
- int write_ts = avf->streams[0]->codec->codec_id != AV_CODEC_ID_SRT;
- if (write_ts) {
+ // TODO: reindent
int64_t s = pkt->pts, e, d = pkt->duration;
int size, x1 = -1, y1 = -1, x2 = -1, y2 = -1;
const uint8_t *p;
avio_printf(avf->pb, " X1:%03d X2:%03d Y1:%03d Y2:%03d",
x1, x2, y1, y2);
avio_printf(avf->pb, "\n");
- }
+
avio_write(avf->pb, pkt->data, pkt->size);
- if (write_ts)
- avio_write(avf->pb, "\n\n", 2);
+ avio_write(avf->pb, "\n\n", 2);
srt->index++;
return 0;
}
--- /dev/null
+/*
+ * Copyright (c) 2014 Eejya Singh
+ *
+ * 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
+ * STL subtitles format demuxer
+ * @see https://documentation.apple.com/en/dvdstudiopro/usermanual/index.html#chapter=19%26section=13%26tasks=true
+ */
+
+#include "avformat.h"
+#include "internal.h"
+#include "subtitles.h"
+#include "libavutil/intreadwrite.h"
+#include "libavutil/avstring.h"
+
+typedef struct {
+ FFDemuxSubtitlesQueue q;
+} STLContext;
+
+static int stl_probe(AVProbeData *p)
+{
+ char c;
+ const unsigned char *ptr = p->buf;
+
+ if (AV_RB24(ptr) == 0xEFBBBF)
+ ptr += 3; /* skip UTF-8 BOM */
+
+ while (*ptr == '\r' || *ptr == '\n' || *ptr == '$' || !strncmp(ptr, "//" , 2))
+ ptr += ff_subtitles_next_line(ptr);
+
+ if (sscanf(ptr, "%*d:%*d:%*d:%*d , %*d:%*d:%*d:%*d , %c", &c) == 1)
+ return AVPROBE_SCORE_MAX;
+
+ return 0;
+}
+
+static int64_t get_pts(char **buf, int *duration)
+{
+ int hh1, mm1, ss1, ms1;
+ int hh2, mm2, ss2, ms2;
+ int len = 0;
+
+ if (sscanf(*buf, "%2d:%2d:%2d:%2d , %2d:%2d:%2d:%2d , %n",
+ &hh1, &mm1, &ss1, &ms1,
+ &hh2, &mm2, &ss2, &ms2, &len) >= 8 && len > 0) {
+ int64_t start = (hh1*3600LL + mm1*60LL + ss1) * 100LL + ms1;
+ int64_t end = (hh2*3600LL + mm2*60LL + ss2) * 100LL + ms2;
+ *duration = end - start;
+ *buf += len;
+ return start;
+ }
+ return AV_NOPTS_VALUE;
+}
+
+static int stl_read_header(AVFormatContext *s)
+{
+ STLContext *stl = s->priv_data;
+ AVStream *st = avformat_new_stream(s, NULL);
+
+ if (!st)
+ return AVERROR(ENOMEM);
+ avpriv_set_pts_info(st, 64, 1, 100);
+ st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
+ st->codec->codec_id = AV_CODEC_ID_STL;
+
+ while (!avio_feof(s->pb)) {
+ char line[4096];
+ char *p = line;
+ const int64_t pos = avio_tell(s->pb);
+ int len = ff_get_line(s->pb, line, sizeof(line));
+ int64_t pts_start;
+ int duration;
+
+ if (!len)
+ break;
+
+ line[strcspn(line, "\r\n")] = 0;
+ pts_start = get_pts(&p , &duration);
+
+ if (pts_start != AV_NOPTS_VALUE) {
+ AVPacket *sub;
+ sub = ff_subtitles_queue_insert(&stl->q, p, strlen(p), 0);
+ if (!sub)
+ return AVERROR(ENOMEM);
+ sub->pos = pos;
+ sub->pts = pts_start;
+ sub->duration = duration;
+ }
+ }
+ ff_subtitles_queue_finalize(&stl->q);
+ return 0;
+}
+static int stl_read_packet(AVFormatContext *s, AVPacket *pkt)
+{
+ STLContext *stl = s->priv_data;
+ return ff_subtitles_queue_read_packet(&stl->q, pkt);
+}
+
+static int stl_read_seek(AVFormatContext *s, int stream_index,
+ int64_t min_ts, int64_t ts, int64_t max_ts, int flags)
+{
+ STLContext *stl = s->priv_data;
+ return ff_subtitles_queue_seek(&stl->q, s, stream_index,
+ min_ts, ts, max_ts, flags);
+}
+
+static int stl_read_close(AVFormatContext *s)
+{
+ STLContext *stl = s->priv_data;
+ ff_subtitles_queue_clean(&stl->q);
+ return 0;
+}
+
+AVInputFormat ff_stl_demuxer = {
+ .name = "stl",
+ .long_name = NULL_IF_CONFIG_SMALL("Spruce subtitle format"),
+ .priv_data_size = sizeof(STLContext),
+ .read_probe = stl_probe,
+ .read_header = stl_read_header,
+ .read_packet = stl_read_packet,
+ .read_seek2 = stl_read_seek,
+ .read_close = stl_read_close,
+ .extensions = "stl",
+};
#include "libavutil/avassert.h"
#include "libavutil/avstring.h"
-void ff_text_init_avio(FFTextReader *r, AVIOContext *pb)
+void ff_text_init_avio(void *s, FFTextReader *r, AVIOContext *pb)
{
int i;
r->pb = pb;
r->buf_pos += 3;
}
}
+ if (s && (r->type == FF_UTF16LE || r->type == FF_UTF16BE))
+ av_log(s, AV_LOG_INFO,
+ "UTF16 is automatically converted to UTF8, do not specify a character encoding\n");
}
void ff_text_init_buf(FFTextReader *r, void *buf, size_t size)
{
memset(&r->buf_pb, 0, sizeof(r->buf_pb));
ffio_init_context(&r->buf_pb, buf, size, 0, NULL, NULL, NULL, NULL);
- ff_text_init_avio(r, &r->buf_pb);
+ ff_text_init_avio(NULL, r, &r->buf_pb);
}
int64_t ff_text_pos(FFTextReader *r)
* Initialize the FFTextReader from the given AVIOContext. This function will
* read some bytes from pb, and test for UTF-8 or UTF-16 BOMs. Further accesses
* to FFTextReader will read more data from pb.
+ * If s is not NULL, the user will be warned if a UTF-16 conversion takes place.
*
* The purpose of FFTextReader is to transparently convert read data to UTF-8
* if the stream had a UTF-16 BOM.
*
+ * @param s Pointer to provide av_log context
* @param r object which will be initialized
* @param pb stream to read from (referenced as long as FFTextReader is in use)
*/
-void ff_text_init_avio(FFTextReader *r, AVIOContext *pb);
+void ff_text_init_avio(void *s, FFTextReader *r, AVIOContext *pb);
/**
* Similar to ff_text_init_avio(), but sets it up to read from a bounded buffer.
--- /dev/null
+/*
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "avformat.h"
+#include "internal.h"
+#include "libavutil/intreadwrite.h"
+
+#define SUP_PGS_MAGIC 0x5047 /* "PG", big endian */
+
+static int sup_read_header(AVFormatContext *s)
+{
+ AVStream *st = avformat_new_stream(s, NULL);
+ if (!st)
+ return AVERROR(ENOMEM);
+ st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
+ st->codec->codec_id = AV_CODEC_ID_HDMV_PGS_SUBTITLE;
+ avpriv_set_pts_info(st, 32, 1, 90000);
+
+ return 0;
+}
+
+static int sup_read_packet(AVFormatContext *s, AVPacket *pkt)
+{
+ int64_t pts, dts, pos;
+ int ret;
+
+ pos = avio_tell(s->pb);
+
+ if (avio_rb16(s->pb) != SUP_PGS_MAGIC)
+ return avio_feof(s->pb) ? AVERROR_EOF : AVERROR_INVALIDDATA;
+
+ pts = avio_rb32(s->pb);
+ dts = avio_rb32(s->pb);
+
+ if ((ret = av_get_packet(s->pb, pkt, 3)) < 0)
+ return ret;
+
+ pkt->stream_index = 0;
+ pkt->flags |= AV_PKT_FLAG_KEY;
+ pkt->pos = pos;
+ pkt->pts = pts;
+ // Many files have DTS set to 0 for all packets, so assume 0 means unset.
+ pkt->dts = dts ? dts : AV_NOPTS_VALUE;
+
+ if (pkt->size >= 3) {
+ // The full packet size is stored as part of the packet.
+ size_t len = AV_RB16(pkt->data + 1);
+
+ if ((ret = av_append_packet(s->pb, pkt, len)) < 0)
+ return ret;
+ }
+
+ return 0;
+}
+
+static int sup_probe(AVProbeData *p)
+{
+ unsigned char *buf = p->buf;
+ size_t buf_size = p->buf_size;
+ int nb_packets;
+
+ for (nb_packets = 0; nb_packets < 10; nb_packets++) {
+ size_t full_packet_size;
+ if (buf_size < 10 + 3)
+ break;
+ if (AV_RB16(buf) != SUP_PGS_MAGIC)
+ return 0;
+ full_packet_size = AV_RB16(buf + 10 + 1) + 10 + 3;
+ if (buf_size < full_packet_size)
+ break;
+ buf += full_packet_size;
+ buf_size -= full_packet_size;
+ }
+ if (!nb_packets)
+ return 0;
+ if (nb_packets < 2)
+ return AVPROBE_SCORE_RETRY / 2;
+ if (nb_packets < 4)
+ return AVPROBE_SCORE_RETRY;
+ if (nb_packets < 10)
+ return AVPROBE_SCORE_EXTENSION;
+ return AVPROBE_SCORE_MAX;
+}
+
+AVInputFormat ff_sup_demuxer = {
+ .name = "sup",
+ .long_name = NULL_IF_CONFIG_SMALL("raw HDMV Presentation Graphic Stream subtitles"),
+ .extensions = "sup",
+ .mime_type = "application/x-pgs",
+ .read_probe = sup_probe,
+ .read_header = sup_read_header,
+ .read_packet = sup_read_packet,
+ .flags = AVFMT_GENERIC_INDEX,
+};
#include "libavutil/parseutils.h"
#include "libavutil/opt.h"
#include "libavutil/time.h"
+
#include "internal.h"
#include "network.h"
#include "os_support.h"
#define D AV_OPT_FLAG_DECODING_PARAM
#define E AV_OPT_FLAG_ENCODING_PARAM
static const AVOption options[] = {
-{"listen", "listen on port instead of connecting", OFFSET(listen), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, D|E },
-{"timeout", "set timeout of socket I/O operations", OFFSET(rw_timeout), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, D|E },
-{"listen_timeout", "set connection awaiting timeout", OFFSET(listen_timeout), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, D|E },
-{NULL}
+ { "listen", "Listen for incoming connections", OFFSET(listen), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, .flags = D|E },
+ { "timeout", "set timeout (in microseconds) of socket I/O operations", OFFSET(rw_timeout), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, .flags = D|E },
+ { "listen_timeout", "Connection awaiting timeout", OFFSET(listen_timeout), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, .flags = D|E },
+ { NULL }
};
-static const AVClass tcp_context_class = {
+static const AVClass tcp_class = {
.class_name = "tcp",
.item_name = av_default_item_name,
.option = options,
.url_get_file_handle = tcp_get_file_handle,
.url_shutdown = tcp_shutdown,
.priv_data_size = sizeof(TCPContext),
- .priv_data_class = &tcp_context_class,
.flags = URL_PROTOCOL_FLAG_NETWORK,
+ .priv_data_class = &tcp_class,
};
SeqDemuxContext *seq = s->priv_data;
for (i = 0; i < SEQ_NUM_FRAME_BUFFERS; i++)
- av_free(seq->frame_buffers[i].data);
+ av_freep(&seq->frame_buffers[i].data);
return 0;
}
TLSContext *c = h->priv_data;
int ret;
int port;
+ const char *p;
char buf[200], host[200], opts[50] = "";
int numerichost = 0;
struct addrinfo hints = { 0 }, *ai = NULL;
const char *proxy_path;
int use_proxy;
- const char *p = strchr(uri, '?');
ff_tls_init();
- if(p && av_find_info_tag(buf, sizeof(buf), "listen", p))
- c->listen = 1;
if (c->listen)
snprintf(opts, sizeof(opts), "?listen=1");
av_url_split(NULL, 0, NULL, 0, host, sizeof(host), &port, NULL, 0, uri);
- ff_url_join(buf, sizeof(buf), "tcp", NULL, host, port, "%s", opts);
+
+ p = strchr(uri, '?');
+
+ if (!p) {
+ p = opts;
+ } else {
+ if (av_find_info_tag(opts, sizeof(opts), "listen", p))
+ c->listen = 1;
+ }
+
+ ff_url_join(buf, sizeof(buf), "tcp", NULL, host, port, "%s", p);
hints.ai_flags = AI_NUMERICHOST;
if (!getaddrinfo(host, NULL, &hints, &ai)) {
#include "os_support.h"
#include "url.h"
+#if HAVE_UDPLITE_H
+#include "udplite.h"
+#else
+/* On many Linux systems, udplite.h is missing but the kernel supports UDP-Lite.
+ * So, we provide a fallback here.
+ */
+#define UDPLITE_SEND_CSCOV 10
+#define UDPLITE_RECV_CSCOV 11
+#endif
+
+#ifndef IPPROTO_UDPLITE
+#define IPPROTO_UDPLITE 136
+#endif
+
#if HAVE_PTHREAD_CANCEL
#include <pthread.h>
#endif
#define UDP_TX_BUF_SIZE 32768
#define UDP_MAX_PKT_SIZE 65536
+#define UDP_HEADER_SIZE 8
typedef struct {
const AVClass *class;
int udp_fd;
int ttl;
+ int udplite_coverage;
int buffer_size;
int is_multicast;
int is_broadcast;
{"buffer_size", "set packet buffer size in bytes", OFFSET(buffer_size), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, D|E },
{"localport", "set local port to bind to", OFFSET(local_port), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, D|E },
{"localaddr", "choose local IP address", OFFSET(local_addr), AV_OPT_TYPE_STRING, {.str = ""}, 0, 0, D|E },
+{"udplite_coverage", "choose UDPLite head size which should be validated by checksum", OFFSET(udplite_coverage), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, D|E },
{"pkt_size", "set size of UDP packets", OFFSET(packet_size), AV_OPT_TYPE_INT, {.i64 = 1472}, 0, INT_MAX, D|E },
{"reuse", "explicitly allow or disallow reusing UDP sockets", OFFSET(reuse_socket), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, D|E },
{"broadcast", "explicitly allow or disallow broadcast destination", OFFSET(is_broadcast), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, E },
.version = LIBAVUTIL_VERSION_INT,
};
+static const AVClass udplite_context_class = {
+ .class_name = "udplite",
+ .item_name = av_default_item_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
static void log_net_error(void *ctx, int level, const char* prefix)
{
char errbuf[100];
if (!res0)
goto fail;
for (res = res0; res; res=res->ai_next) {
- udp_fd = ff_socket(res->ai_family, SOCK_DGRAM, 0);
+ if (s->udplite_coverage)
+ udp_fd = ff_socket(res->ai_family, SOCK_DGRAM, IPPROTO_UDPLITE);
+ else
+ udp_fd = ff_socket(res->ai_family, SOCK_DGRAM, 0);
if (udp_fd != -1) break;
log_net_error(NULL, AV_LOG_ERROR, "socket");
}
static int udp_open(URLContext *h, const char *uri, int flags)
{
char hostname[1024], localaddr[1024] = "";
- int port, udp_fd = -1, tmp, bind_ret = -1;
+ int port, udp_fd = -1, tmp, bind_ret = -1, dscp = -1;
UDPContext *s = h->priv_data;
int is_output;
const char *p;
if (av_find_info_tag(buf, sizeof(buf), "ttl", p)) {
s->ttl = strtol(buf, NULL, 10);
}
+ if (av_find_info_tag(buf, sizeof(buf), "udplite_coverage", p)) {
+ s->udplite_coverage = strtol(buf, NULL, 10);
+ }
if (av_find_info_tag(buf, sizeof(buf), "localport", p)) {
s->local_port = strtol(buf, NULL, 10);
}
if (av_find_info_tag(buf, sizeof(buf), "connect", p)) {
s->is_connected = strtol(buf, NULL, 10);
}
+ if (av_find_info_tag(buf, sizeof(buf), "dscp", p)) {
+ dscp = strtol(buf, NULL, 10);
+ }
if (av_find_info_tag(buf, sizeof(buf), "fifo_size", p)) {
s->circular_buffer_size = strtol(buf, NULL, 10);
if (!HAVE_PTHREAD_CANCEL)
goto fail;
}
+ /* Set the checksum coverage for UDP-Lite (RFC 3828) for sending and receiving.
+ * The receiver coverage has to be less than or equal to the sender coverage.
+ * Otherwise, the receiver will drop all packets.
+ */
+ if (s->udplite_coverage) {
+ if (setsockopt (udp_fd, IPPROTO_UDPLITE, UDPLITE_SEND_CSCOV, &(s->udplite_coverage), sizeof(s->udplite_coverage)) != 0)
+ av_log(h, AV_LOG_WARNING, "socket option UDPLITE_SEND_CSCOV not available");
+
+ if (setsockopt (udp_fd, IPPROTO_UDPLITE, UDPLITE_RECV_CSCOV, &(s->udplite_coverage), sizeof(s->udplite_coverage)) != 0)
+ av_log(h, AV_LOG_WARNING, "socket option UDPLITE_RECV_CSCOV not available");
+ }
+
+ if (dscp >= 0) {
+ dscp <<= 2;
+ if (setsockopt (udp_fd, IPPROTO_IP, IP_TOS, &dscp, sizeof(dscp)) != 0)
+ goto fail;
+ }
+
/* If multicast, try binding the multicast address first, to avoid
* receiving UDP packets from other sources aimed at the same UDP
* port. This fails on windows. This makes sending to the same address
return AVERROR(EIO);
}
+static int udplite_open(URLContext *h, const char *uri, int flags)
+{
+ UDPContext *s = h->priv_data;
+
+ // set default checksum coverage
+ s->udplite_coverage = UDP_HEADER_SIZE;
+
+ return udp_open(h, uri, flags);
+}
+
static int udp_read(URLContext *h, uint8_t *buf, int size)
{
UDPContext *s = h->priv_data;
.priv_data_class = &udp_context_class,
.flags = URL_PROTOCOL_FLAG_NETWORK,
};
+
+URLProtocol ff_udplite_protocol = {
+ .name = "udplite",
+ .url_open = udplite_open,
+ .url_read = udp_read,
+ .url_write = udp_write,
+ .url_close = udp_close,
+ .url_get_file_handle = udp_get_file_handle,
+ .priv_data_size = sizeof(UDPContext),
+ .priv_data_class = &udplite_context_class,
+ .flags = URL_PROTOCOL_FLAG_NETWORK,
+};
#define URL_PROTOCOL_FLAG_NESTED_SCHEME 1 /*< The protocol name can be the first part of a nested protocol scheme */
#define URL_PROTOCOL_FLAG_NETWORK 2 /*< The protocol uses network */
-extern int (*url_interrupt_cb)(void);
-
extern const AVClass ffurl_context_class;
typedef struct URLContext {
}
MAKE_ACCESSORS(AVStream, stream, AVRational, r_frame_rate)
+MAKE_ACCESSORS(AVStream, stream, char *, recommended_encoder_configuration)
MAKE_ACCESSORS(AVFormatContext, format, AVCodec *, video_codec)
MAKE_ACCESSORS(AVFormatContext, format, AVCodec *, audio_codec)
MAKE_ACCESSORS(AVFormatContext, format, AVCodec *, subtitle_codec)
}
}
+int ff_copy_whitelists(AVFormatContext *dst, AVFormatContext *src)
+{
+ av_assert0(!dst->codec_whitelist && !dst->format_whitelist);
+ dst-> codec_whitelist = av_strdup(src->codec_whitelist);
+ dst->format_whitelist = av_strdup(src->format_whitelist);
+ if ( (src-> codec_whitelist && !dst-> codec_whitelist)
+ || (src->format_whitelist && !dst->format_whitelist)) {
+ av_log(dst, AV_LOG_ERROR, "Failed to duplicate whitelist\n");
+ return AVERROR(ENOMEM);
+ }
+ return 0;
+}
+
static const AVCodec *find_decoder(AVFormatContext *s, AVStream *st, enum AVCodecID codec_id)
{
if (st->codec->codec)
int av_demuxer_open(AVFormatContext *ic) {
int err;
+ if (ic->format_whitelist && av_match_list(ic->iformat->name, ic->format_whitelist, ',') <= 0) {
+ av_log(ic, AV_LOG_ERROR, "Format not on whitelist\n");
+ return AVERROR(EINVAL);
+ }
+
if (ic->iformat->read_header) {
err = ic->iformat->read_header(ic);
if (err < 0)
if ((ret = init_input(s, filename, &tmp)) < 0)
goto fail;
s->probe_score = ret;
+
+ if (s->format_whitelist && av_match_list(s->iformat->name, s->format_whitelist, ',') <= 0) {
+ av_log(s, AV_LOG_ERROR, "Format not on whitelist\n");
+ ret = AVERROR(EINVAL);
+ goto fail;
+ }
+
avio_skip(s->pb, s->skip_initial_bytes);
/* Check filename in case an image number is expected. */
}
}
-#if FF_API_READ_PACKET
-int av_read_packet(AVFormatContext *s, AVPacket *pkt)
-{
- return ff_read_packet(s, pkt);
-}
-#endif
-
/**********************************************************/
/**
* Return the frame duration in seconds. Return 0 if not available.
*/
-void ff_compute_frame_duration(int *pnum, int *pden, AVStream *st,
+void ff_compute_frame_duration(AVFormatContext *s, int *pnum, int *pden, AVStream *st,
AVCodecParserContext *pc, AVPacket *pkt)
{
+ AVRational codec_framerate = s->iformat ? st->codec->framerate :
+ av_mul_q(av_inv_q(st->codec->time_base), (AVRational){1, st->codec->ticks_per_frame});
int frame_size;
*pnum = 0;
} else if (st->time_base.num * 1000LL > st->time_base.den) {
*pnum = st->time_base.num;
*pden = st->time_base.den;
- } else if (st->codec->time_base.num * 1000LL > st->codec->time_base.den) {
- *pnum = st->codec->time_base.num;
- *pden = st->codec->time_base.den;
+ } else if (codec_framerate.den * 1000LL > codec_framerate.num) {
+ av_assert0(st->codec->ticks_per_frame);
+ av_reduce(pnum, pden,
+ codec_framerate.den,
+ codec_framerate.num * (int64_t)st->codec->ticks_per_frame,
+ INT_MAX);
+
if (pc && pc->repeat_pict) {
- if (*pnum > INT_MAX / (1 + pc->repeat_pict))
- *pden /= 1 + pc->repeat_pict;
- else
- *pnum *= 1 + pc->repeat_pict;
+ av_assert0(s->iformat); // this may be wrong for interlaced encoding but its not used for that case
+ av_reduce(pnum, pden,
+ (*pnum) * (1LL + pc->repeat_pict),
+ (*pden),
+ INT_MAX);
}
/* If this codec can be interlaced or progressive then we need
* a parser to compute duration of a packet. Thus if we have
duration = av_mul_q((AVRational) {pkt->duration, 1}, st->time_base);
if (pkt->duration == 0) {
- ff_compute_frame_duration(&num, &den, st, pc, pkt);
+ ff_compute_frame_duration(s, &num, &den, st, pc, pkt);
if (den && num) {
duration = (AVRational) {num, den};
pkt->duration = av_rescale_rnd(1,
presentation_delayed = 1;
av_dlog(NULL,
- "IN delayed:%d pts:%s, dts:%s cur_dts:%s st:%d pc:%p duration:%d\n",
+ "IN delayed:%d pts:%s, dts:%s cur_dts:%s st:%d pc:%p duration:%d delay:%d onein_oneout:%d\n",
presentation_delayed, av_ts2str(pkt->pts), av_ts2str(pkt->dts), av_ts2str(st->cur_dts),
- pkt->stream_index, pc, pkt->duration);
+ pkt->stream_index, pc, pkt->duration, delay, onein_oneout);
/* Interpolate PTS and DTS if they are not present. We skip H264
* currently because delay and has_b_frames are not reliably set. */
if ((delay == 0 || (delay == 1 && pc)) &&
return 0;
}
+static int64_t ts_to_samples(AVStream *st, int64_t ts)
+{
+ return av_rescale(ts, st->time_base.num * st->codec->sample_rate, st->time_base.den);
+}
+
static int read_frame_internal(AVFormatContext *s, AVPacket *pkt)
{
int ret = 0, i, got_packet = 0;
if (ret >= 0) {
AVStream *st = s->streams[pkt->stream_index];
- if (st->skip_samples) {
+ int discard_padding = 0;
+ if (st->first_discard_sample && pkt->pts != AV_NOPTS_VALUE) {
+ int64_t pts = pkt->pts - (is_relative(pkt->pts) ? RELATIVE_TS_BASE : 0);
+ int64_t sample = ts_to_samples(st, pts);
+ int duration = ts_to_samples(st, pkt->duration);
+ int64_t end_sample = sample + duration;
+ if (duration > 0 && end_sample >= st->first_discard_sample &&
+ sample < st->last_discard_sample)
+ discard_padding = FFMIN(end_sample - st->first_discard_sample, duration);
+ }
+ if (st->skip_samples || discard_padding) {
uint8_t *p = av_packet_new_side_data(pkt, AV_PKT_DATA_SKIP_SAMPLES, 10);
if (p) {
AV_WL32(p, st->skip_samples);
+ AV_WL32(p + 4, discard_padding);
av_log(s, AV_LOG_DEBUG, "demuxer injecting skip %d\n", st->skip_samples);
}
st->skip_samples = 0;
(st->start_time != AV_NOPTS_VALUE ||
st->first_dts != AV_NOPTS_VALUE)) {
if (pkt->duration == 0) {
- ff_compute_frame_duration(&num, &den, st, st->parser, pkt);
+ ff_compute_frame_duration(ic, &num, &den, st, st->parser, pkt);
if (den && num) {
pkt->duration = av_rescale_rnd(1,
num * (int64_t) st->time_base.den,
/* Force thread count to 1 since the H.264 decoder will not extract
* SPS and PPS to extradata during multi-threaded decoding. */
av_dict_set(options ? options : &thread_opt, "threads", "1", 0);
+ if (s->codec_whitelist)
+ av_dict_set(options ? options : &thread_opt, "codec_whitelist", s->codec_whitelist, 0);
ret = avcodec_open2(st->codec, codec, options ? options : &thread_opt);
if (!options)
av_dict_free(&thread_opt);
static int get_std_framerate(int i)
{
- if (i < 60 * 12)
+ if (i < 30*12)
return (i + 1) * 1001;
- else
- return ((const int[]) { 24, 30, 60, 12, 15, 48 })[i - 60 * 12] * 1000 * 12;
+ i -= 30*12;
+
+ if (i < 7)
+ return ((const int[]) { 40, 48, 50, 60, 80, 120, 240})[i] * 1001 * 12;
+
+ i -= 7;
+
+ return ((const int[]) { 24, 30, 60, 12, 15, 48 })[i] * 1000 * 12;
}
/* Is the time base unreliable?
return 0;
}
-#if FF_API_FORMAT_PARAMETERS
-int av_find_stream_info(AVFormatContext *ic)
-{
- return avformat_find_stream_info(ic, NULL);
-}
-#endif
-
int ff_alloc_extradata(AVCodecContext *avctx, int size)
{
int ret;
int orig_nb_streams = ic->nb_streams;
int flush_codecs;
int64_t max_analyze_duration = ic->max_analyze_duration2;
+ int64_t max_stream_analyze_duration;
int64_t probesize = ic->probesize2;
if (!max_analyze_duration)
av_opt_set(ic, "skip_clear", "1", AV_OPT_SEARCH_CHILDREN);
+ max_stream_analyze_duration = max_analyze_duration;
if (!max_analyze_duration) {
- if (!strcmp(ic->iformat->name, "flv") && !(ic->ctx_flags & AVFMTCTX_NOHEADER)) {
- max_analyze_duration = 10*AV_TIME_BASE;
- } else
- max_analyze_duration = 5*AV_TIME_BASE;
+ max_stream_analyze_duration =
+ max_analyze_duration = 5*AV_TIME_BASE;
+ if (!strcmp(ic->iformat->name, "flv"))
+ max_stream_analyze_duration = 30*AV_TIME_BASE;
}
if (ic->pb)
* SPS and PPS to extradata during multi-threaded decoding. */
av_dict_set(options ? &options[i] : &thread_opt, "threads", "1", 0);
+ if (ic->codec_whitelist)
+ av_dict_set(options ? &options[i] : &thread_opt, "codec_whitelist", ic->codec_whitelist, 0);
+
/* Ensure that subtitle_header is properly set. */
if (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE
&& codec && !st->codec->codec) {
count = 0;
read_size = 0;
for (;;) {
+ int analyzed_all_streams;
if (ff_check_interrupt(&ic->interrupt_callback)) {
ret = AVERROR_EXIT;
av_log(ic, AV_LOG_DEBUG, "interrupted\n");
st->codec->codec_type == AVMEDIA_TYPE_AUDIO))
break;
}
+ analyzed_all_streams = 0;
if (i == ic->nb_streams) {
+ analyzed_all_streams = 1;
/* NOTE: If the format has no header, then we need to read some
* packets to get most of the streams, so we cannot stop here. */
if (!(ic->ctx_flags & AVFMTCTX_NOHEADER)) {
&& st->info->fps_last_dts != AV_NOPTS_VALUE)
t = FFMAX(t, av_rescale_q(st->info->fps_last_dts - st->info->fps_first_dts, st->time_base, AV_TIME_BASE_Q));
- if (t >= max_analyze_duration) {
+ if (t >= (analyzed_all_streams ? max_analyze_duration : max_stream_analyze_duration)) {
av_log(ic, AV_LOG_VERBOSE, "max_analyze_duration %"PRId64" reached at %"PRId64" microseconds\n",
max_analyze_duration,
t);
+ if (ic->flags & AVFMT_FLAG_NOBUFFER)
+ av_packet_unref(pkt);
break;
}
if (pkt->duration) {
try_decode_frame(ic, st, pkt,
(options && i < orig_nb_streams) ? &options[i] : NULL);
+ if (ic->flags & AVFMT_FLAG_NOBUFFER)
+ av_packet_unref(pkt);
+
st->codec_info_nb_frames++;
count++;
}
}
}
}
- av_opt_set(ic, "skip_clear", "0", AV_OPT_SEARCH_CHILDREN);
// close codecs which were opened in try_decode_frame()
for (i = 0; i < ic->nb_streams; i++) {
st->r_frame_rate.den = st->time_base.num;
}
}
+ if (st->display_aspect_ratio.num && st->display_aspect_ratio.den) {
+ AVRational hw_ratio = { st->codec->height, st->codec->width };
+ st->sample_aspect_ratio = av_mul_q(st->display_aspect_ratio,
+ hw_ratio);
+ }
} else if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
if (!st->codec->bits_per_coded_sample)
st->codec->bits_per_coded_sample =
if (probesize)
estimate_timings(ic, old_offset);
+ av_opt_set(ic, "skip_clear", "0", AV_OPT_SEARCH_CHILDREN);
+
if (ret >= 0 && ic->nb_streams)
/* We could not have all the codec parameters before EOF. */
ret = -1;
if (st->info)
av_freep(&st->info->duration_error);
av_freep(&st->info);
+ av_freep(&st->recommended_encoder_configuration);
av_freep(&s->streams[ --s->nb_streams ]);
}
av_free(s);
}
-#if FF_API_CLOSE_INPUT_FILE
-void av_close_input_file(AVFormatContext *s)
-{
- avformat_close_input(&s);
-}
-#endif
-
void avformat_close_input(AVFormatContext **ps)
{
AVFormatContext *s;
avio_close(pb);
}
-#if FF_API_NEW_STREAM
-AVStream *av_new_stream(AVFormatContext *s, int id)
-{
- AVStream *st = avformat_new_stream(s, NULL);
- if (st)
- st->id = id;
- return st;
-}
-#endif
-
AVStream *avformat_new_stream(AVFormatContext *s, const AVCodec *c)
{
AVStream *st;
return len;
}
-#if FF_API_SET_PTS_INFO
-void av_set_pts_info(AVStream *s, int pts_wrap_bits,
- unsigned int pts_num, unsigned int pts_den)
-{
- avpriv_set_pts_info(s, pts_wrap_bits, pts_num, pts_den);
-}
-#endif
-
void avpriv_set_pts_info(AVStream *s, int pts_wrap_bits,
unsigned int pts_num, unsigned int pts_den)
{
AVRational av_guess_frame_rate(AVFormatContext *format, AVStream *st, AVFrame *frame)
{
AVRational fr = st->r_frame_rate;
- AVRational codec_fr = av_inv_q(st->codec->time_base);
+ AVRational codec_fr = st->codec->framerate;
AVRational avg_fr = st->avg_frame_rate;
if (avg_fr.num > 0 && avg_fr.den > 0 && fr.num > 0 && fr.den > 0 &&
if (st->codec->ticks_per_frame > 1) {
- codec_fr.den *= st->codec->ticks_per_frame;
if ( codec_fr.num > 0 && codec_fr.den > 0 && av_q2d(codec_fr) < av_q2d(fr)*0.7
&& fabs(1.0 - av_q2d(av_div_q(avg_fr, fr))) > 0.1)
fr = codec_fr;
0x00, 0x00, 0x00, 0x01, 0x68, 0xce, 0x33, 0x48,
0xd0
};
+ static const uint8_t avci50_1080p_extradata[] = {
+ // SPS
+ 0x00, 0x00, 0x00, 0x01, 0x67, 0x6e, 0x10, 0x28,
+ 0xa6, 0xd4, 0x20, 0x32, 0x33, 0x0c, 0x71, 0x18,
+ 0x88, 0x62, 0x10, 0x19, 0x19, 0x86, 0x38, 0x8c,
+ 0x44, 0x30, 0x21, 0x02, 0x56, 0x4e, 0x6f, 0x37,
+ 0xcd, 0xf9, 0xbf, 0x81, 0x6b, 0xf3, 0x7c, 0xde,
+ 0x6e, 0x6c, 0xd3, 0x3c, 0x05, 0xa0, 0x22, 0x7e,
+ 0x5f, 0xfc, 0x00, 0x0c, 0x00, 0x13, 0x8c, 0x04,
+ 0x04, 0x05, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00,
+ 0x00, 0x03, 0x00, 0x32, 0x84, 0x00, 0x00, 0x00,
+ // PPS
+ 0x00, 0x00, 0x00, 0x01, 0x68, 0xee, 0x31, 0x12,
+ 0x11
+ };
static const uint8_t avci50_1080i_extradata[] = {
// SPS
0x00, 0x00, 0x00, 0x01, 0x67, 0x6e, 0x10, 0x28,
0x00, 0x00, 0x00, 0x01, 0x68, 0xce, 0x31, 0x12,
0x11
};
+ static const uint8_t avci50_720p_extradata[] = {
+ // SPS
+ 0x00, 0x00, 0x00, 0x01, 0x67, 0x6e, 0x10, 0x20,
+ 0xa6, 0xd4, 0x20, 0x32, 0x33, 0x0c, 0x71, 0x18,
+ 0x88, 0x62, 0x10, 0x19, 0x19, 0x86, 0x38, 0x8c,
+ 0x44, 0x30, 0x21, 0x02, 0x56, 0x4e, 0x6f, 0x37,
+ 0xcd, 0xf9, 0xbf, 0x81, 0x6b, 0xf3, 0x7c, 0xde,
+ 0x6e, 0x6c, 0xd3, 0x3c, 0x0f, 0x01, 0x6e, 0xff,
+ 0xc0, 0x00, 0xc0, 0x01, 0x38, 0xc0, 0x40, 0x40,
+ 0x50, 0x00, 0x00, 0x03, 0x00, 0x10, 0x00, 0x00,
+ 0x06, 0x48, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
+ // PPS
+ 0x00, 0x00, 0x00, 0x01, 0x68, 0xee, 0x31, 0x12,
+ 0x11
+ };
const uint8_t *data = NULL;
int size = 0;
size = sizeof(avci100_1080i_extradata);
}
} else if (st->codec->width == 1440) {
- data = avci50_1080i_extradata;
- size = sizeof(avci50_1080i_extradata);
+ if (st->codec->field_order == AV_FIELD_PROGRESSIVE) {
+ data = avci50_1080p_extradata;
+ size = sizeof(avci50_1080p_extradata);
+ } else {
+ data = avci50_1080i_extradata;
+ size = sizeof(avci50_1080i_extradata);
+ }
} else if (st->codec->width == 1280) {
data = avci100_720p_extradata;
size = sizeof(avci100_720p_extradata);
+ } else if (st->codec->width == 960) {
+ data = avci50_720p_extradata;
+ size = sizeof(avci50_720p_extradata);
}
if (!size)
#include "libavutil/version.h"
#define LIBAVFORMAT_VERSION_MAJOR 56
-#define LIBAVFORMAT_VERSION_MINOR 4
-#define LIBAVFORMAT_VERSION_MICRO 101
+#define LIBAVFORMAT_VERSION_MINOR 15
+#define LIBAVFORMAT_VERSION_MICRO 102
#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
LIBAVFORMAT_VERSION_MINOR, \
#define FF_API_URL_FEOF (LIBAVFORMAT_VERSION_MAJOR < 57)
#endif
-#ifndef FF_API_ALLOC_OUTPUT_CONTEXT
-#define FF_API_ALLOC_OUTPUT_CONTEXT (LIBAVFORMAT_VERSION_MAJOR < 56)
-#endif
-#ifndef FF_API_FORMAT_PARAMETERS
-#define FF_API_FORMAT_PARAMETERS (LIBAVFORMAT_VERSION_MAJOR < 56)
-#endif
-#ifndef FF_API_NEW_STREAM
-#define FF_API_NEW_STREAM (LIBAVFORMAT_VERSION_MAJOR < 56)
-#endif
-#ifndef FF_API_SET_PTS_INFO
-#define FF_API_SET_PTS_INFO (LIBAVFORMAT_VERSION_MAJOR < 56)
-#endif
-#ifndef FF_API_CLOSE_INPUT_FILE
-#define FF_API_CLOSE_INPUT_FILE (LIBAVFORMAT_VERSION_MAJOR < 56)
-#endif
-#ifndef FF_API_READ_PACKET
-#define FF_API_READ_PACKET (LIBAVFORMAT_VERSION_MAJOR < 56)
-#endif
#ifndef FF_API_R_FRAME_RATE
#define FF_API_R_FRAME_RATE 1
#endif
#include "libavutil/mathematics.h"
#include "libavutil/opt.h"
#include "libavutil/time.h"
+#include "libavutil/time_internal.h"
#include "avformat.h"
#include "avio.h"
memset(timestamp, 0, sizeof(timestamp));
if (!(s->flags & AVFMT_FLAG_BITEXACT)) {
+ struct tm tmpbuf;
av_log(s, AV_LOG_INFO, "Writing local time and date to Peak Envelope Chunk\n");
now0 = av_gettime();
now_secs = now0 / 1000000;
- strftime(timestamp, sizeof(timestamp), "%Y:%m:%d:%H:%M:%S:", localtime(&now_secs));
+ strftime(timestamp, sizeof(timestamp), "%Y:%m:%d:%H:%M:%S:", localtime_r(&now_secs, &tmpbuf));
av_strlcatf(timestamp, sizeof(timestamp), "%03d", (int)((now0 / 1000) % 1000));
}
char *adaptation_sets;
AdaptationSet *as;
int nb_as;
+ int representation_id;
} WebMDashMuxContext;
static const char *get_codec_name(int codec_id)
static void write_footer(AVFormatContext *s)
{
- avio_printf(s->pb, "</MPD>");
+ avio_printf(s->pb, "</MPD>\n");
}
static int subsegment_alignment(AVFormatContext *s, AdaptationSet *as) {
return 1;
}
+/*
+ * Writes a Representation within an Adaptation Set. Returns 0 on success and
+ * < 0 on failure.
+ */
+static int write_representation(AVFormatContext *s, AVStream *stream, int id,
+ int output_width, int output_height,
+ int output_sample_rate) {
+ AVDictionaryEntry *irange = av_dict_get(stream->metadata, INITIALIZATION_RANGE, NULL, 0);
+ AVDictionaryEntry *cues_start = av_dict_get(stream->metadata, CUES_START, NULL, 0);
+ AVDictionaryEntry *cues_end = av_dict_get(stream->metadata, CUES_END, NULL, 0);
+ AVDictionaryEntry *filename = av_dict_get(stream->metadata, FILENAME, NULL, 0);
+ AVDictionaryEntry *bandwidth = av_dict_get(stream->metadata, BANDWIDTH, NULL, 0);
+ if (!irange || cues_start == NULL || cues_end == NULL || filename == NULL ||
+ !bandwidth) {
+ return -1;
+ }
+ avio_printf(s->pb, "<Representation id=\"%d\"", id);
+ avio_printf(s->pb, " bandwidth=\"%s\"", bandwidth->value);
+ if (stream->codec->codec_type == AVMEDIA_TYPE_VIDEO && output_width)
+ avio_printf(s->pb, " width=\"%d\"", stream->codec->width);
+ if (stream->codec->codec_type == AVMEDIA_TYPE_VIDEO && output_height)
+ avio_printf(s->pb, " height=\"%d\"", stream->codec->height);
+ if (stream->codec->codec_type = AVMEDIA_TYPE_AUDIO && output_sample_rate)
+ avio_printf(s->pb, " audioSamplingRate=\"%d\"", stream->codec->sample_rate);
+ avio_printf(s->pb, ">\n");
+ avio_printf(s->pb, "<BaseURL>%s</BaseURL>\n", filename->value);
+ avio_printf(s->pb, "<SegmentBase\n");
+ avio_printf(s->pb, " indexRange=\"%s-%s\">\n", cues_start->value, cues_end->value);
+ avio_printf(s->pb, "<Initialization\n");
+ avio_printf(s->pb, " range=\"0-%s\" />\n", irange->value);
+ avio_printf(s->pb, "</SegmentBase>\n");
+ avio_printf(s->pb, "</Representation>\n");
+ return 0;
+}
+
+/*
+ * Checks if width of all streams are the same. Returns 1 if true, 0 otherwise.
+ */
+static int check_matching_width(AVFormatContext *s, AdaptationSet *as) {
+ int first_width, i;
+ if (as->nb_streams < 2) return 1;
+ first_width = s->streams[as->streams[0]]->codec->width;
+ for (i = 1; i < as->nb_streams; i++)
+ if (first_width != s->streams[as->streams[i]]->codec->width)
+ return 0;
+ return 1;
+}
+
+/*
+ * Checks if height of all streams are the same. Returns 1 if true, 0 otherwise.
+ */
+static int check_matching_height(AVFormatContext *s, AdaptationSet *as) {
+ int first_height, i;
+ if (as->nb_streams < 2) return 1;
+ first_height = s->streams[as->streams[0]]->codec->height;
+ for (i = 1; i < as->nb_streams; i++)
+ if (first_height != s->streams[as->streams[i]]->codec->height)
+ return 0;
+ return 1;
+}
+
+/*
+ * Checks if sample rate of all streams are the same. Returns 1 if true, 0 otherwise.
+ */
+static int check_matching_sample_rate(AVFormatContext *s, AdaptationSet *as) {
+ int first_sample_rate, i;
+ if (as->nb_streams < 2) return 1;
+ first_sample_rate = s->streams[as->streams[0]]->codec->sample_rate;
+ for (i = 1; i < as->nb_streams; i++)
+ if (first_sample_rate != s->streams[as->streams[i]]->codec->sample_rate)
+ return 0;
+ return 1;
+}
+
/*
* Writes an Adaptation Set. Returns 0 on success and < 0 on failure.
*/
WebMDashMuxContext *w = s->priv_data;
AdaptationSet *as = &w->as[as_index];
AVCodecContext *codec = s->streams[as->streams[0]]->codec;
+ AVDictionaryEntry *lang;
int i;
static const char boolean[2][6] = { "false", "true" };
int subsegmentStartsWithSAP = 1;
- AVDictionaryEntry *lang;
+
+ // Width, Height and Sample Rate will go in the AdaptationSet tag if they
+ // are the same for all contained Representations. otherwise, they will go
+ // on their respective Representation tag.
+ int width_in_as = 1, height_in_as = 1, sample_rate_in_as = 1;
+ if (codec->codec_type == AVMEDIA_TYPE_VIDEO) {
+ width_in_as = check_matching_width(s, as);
+ height_in_as = check_matching_height(s, as);
+ } else {
+ sample_rate_in_as = check_matching_sample_rate(s, as);
+ }
+
avio_printf(s->pb, "<AdaptationSet id=\"%s\"", as->id);
avio_printf(s->pb, " mimeType=\"%s/webm\"",
codec->codec_type == AVMEDIA_TYPE_VIDEO ? "video" : "audio");
lang = av_dict_get(s->streams[as->streams[0]]->metadata, "language", NULL, 0);
if (lang) avio_printf(s->pb, " lang=\"%s\"", lang->value);
- if (codec->codec_type == AVMEDIA_TYPE_VIDEO) {
+ if (codec->codec_type == AVMEDIA_TYPE_VIDEO && width_in_as)
avio_printf(s->pb, " width=\"%d\"", codec->width);
+ if (codec->codec_type == AVMEDIA_TYPE_VIDEO && height_in_as)
avio_printf(s->pb, " height=\"%d\"", codec->height);
- } else {
+ if (codec->codec_type == AVMEDIA_TYPE_AUDIO && sample_rate_in_as)
avio_printf(s->pb, " audioSamplingRate=\"%d\"", codec->sample_rate);
- }
avio_printf(s->pb, " bitstreamSwitching=\"%s\"",
boolean[bitstream_switching(s, as)]);
avio_printf(s->pb, ">\n");
for (i = 0; i < as->nb_streams; i++) {
- AVStream *stream = s->streams[as->streams[i]];
- AVDictionaryEntry *irange = av_dict_get(stream->metadata, INITIALIZATION_RANGE, NULL, 0);
- AVDictionaryEntry *cues_start = av_dict_get(stream->metadata, CUES_START, NULL, 0);
- AVDictionaryEntry *cues_end = av_dict_get(stream->metadata, CUES_END, NULL, 0);
- AVDictionaryEntry *filename = av_dict_get(stream->metadata, FILENAME, NULL, 0);
- AVDictionaryEntry *bandwidth = av_dict_get(stream->metadata, BANDWIDTH, NULL, 0);
- if (!irange || cues_start == NULL || cues_end == NULL || filename == NULL ||
- !bandwidth) {
- return -1;
- }
- avio_printf(s->pb, "<Representation id=\"%d\"", i);
- avio_printf(s->pb, " bandwidth=\"%s\"", bandwidth->value);
- avio_printf(s->pb, ">\n");
- avio_printf(s->pb, "<BaseURL>%s</BaseURL>\n", filename->value);
- avio_printf(s->pb, "<SegmentBase\n");
- avio_printf(s->pb, " indexRange=\"%s-%s\">\n", cues_start->value, cues_end->value);
- avio_printf(s->pb, "<Initialization\n");
- avio_printf(s->pb, " range=\"0-%s\" />\n", irange->value);
- avio_printf(s->pb, "</SegmentBase>\n");
- avio_printf(s->pb, "</Representation>\n");
+ write_representation(s, s->streams[as->streams[i]], w->representation_id++,
+ !width_in_as, !height_in_as, !sample_rate_in_as);
}
avio_printf(s->pb, "</AdaptationSet>\n");
return 0;
--- /dev/null
+/*
+ * webp muxer
+ * Copyright (c) 2014 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 "libavutil/opt.h"
+#include "avformat.h"
+#include "internal.h"
+
+typedef struct WebpContext{
+ AVClass *class;
+ int frame_count;
+ AVPacket last_pkt;
+ int loop;
+} WebpContext;
+
+static int webp_write_header(AVFormatContext *s)
+{
+ AVStream *st;
+
+ if (s->nb_streams != 1) {
+ av_log(s, AV_LOG_ERROR, "Only exactly 1 stream is supported\n");
+ return AVERROR(EINVAL);
+ }
+ st = s->streams[0];
+ if (st->codec->codec_id != AV_CODEC_ID_WEBP) {
+ av_log(s, AV_LOG_ERROR, "Only WebP is supported\n");
+ return AVERROR(EINVAL);
+ }
+ avpriv_set_pts_info(st, 24, 1, 1000);
+
+ avio_write(s->pb, "RIFF\0\0\0\0WEBP", 12);
+
+ return 0;
+}
+
+static int flush(AVFormatContext *s, int trailer, int64_t pts)
+{
+ WebpContext *w = s->priv_data;
+ AVStream *st = s->streams[0];
+
+ if (w->last_pkt.size) {
+ int skip = 0;
+ unsigned flags = 0;
+ int vp8x = 0;
+
+ if (AV_RL32(w->last_pkt.data) == AV_RL32("RIFF"))
+ skip = 12;
+ if (AV_RL32(w->last_pkt.data + skip) == AV_RL32("VP8X")) {
+ flags |= w->last_pkt.data[skip + 4 + 4];
+ vp8x = 1;
+ skip += AV_RL32(w->last_pkt.data + skip + 4) + 8;
+ }
+
+ w->frame_count ++;
+
+ if (w->frame_count == 1) {
+ if (!trailer) {
+ vp8x = 1;
+ flags |= 2 + 16;
+ }
+
+ if (vp8x) {
+ avio_write(s->pb, "VP8X", 4);
+ avio_wl32(s->pb, 10);
+ avio_w8(s->pb, flags);
+ avio_wl24(s->pb, 0);
+ avio_wl24(s->pb, st->codec->width - 1);
+ avio_wl24(s->pb, st->codec->height - 1);
+ }
+ if (!trailer) {
+ avio_write(s->pb, "ANIM", 4);
+ avio_wl32(s->pb, 6);
+ avio_wl32(s->pb, 0xFFFFFFFF);
+ avio_wl16(s->pb, w->loop);
+ }
+ }
+
+ if (w->frame_count > trailer) {
+ avio_write(s->pb, "ANMF", 4);
+ avio_wl32(s->pb, 16 + w->last_pkt.size - skip);
+ avio_wl24(s->pb, 0);
+ avio_wl24(s->pb, 0);
+ avio_wl24(s->pb, st->codec->width - 1);
+ avio_wl24(s->pb, st->codec->height - 1);
+ if (w->last_pkt.pts != AV_NOPTS_VALUE && pts != AV_NOPTS_VALUE) {
+ avio_wl24(s->pb, pts - w->last_pkt.pts);
+ } else
+ avio_wl24(s->pb, w->last_pkt.duration);
+ avio_w8(s->pb, 0);
+ }
+ avio_write(s->pb, w->last_pkt.data + skip, w->last_pkt.size - skip);
+ av_free_packet(&w->last_pkt);
+ }
+
+ return 0;
+}
+
+static int webp_write_packet(AVFormatContext *s, AVPacket *pkt)
+{
+ WebpContext *w = s->priv_data;
+ int ret;
+
+ if ((ret = flush(s, 0, pkt->pts)) < 0)
+ return ret;
+
+ av_copy_packet(&w->last_pkt, pkt);
+
+ return 0;
+}
+
+static int webp_write_trailer(AVFormatContext *s)
+{
+ unsigned filesize;
+ int ret;
+
+ if ((ret = flush(s, 1, AV_NOPTS_VALUE)) < 0)
+ return ret;
+
+ filesize = avio_tell(s->pb);
+ avio_seek(s->pb, 4, SEEK_SET);
+ avio_wl32(s->pb, filesize - 8);
+
+ return 0;
+}
+
+#define OFFSET(x) offsetof(WebpContext, x)
+#define ENC AV_OPT_FLAG_ENCODING_PARAM
+static const AVOption options[] = {
+ { "loop", "Number of times to loop the output: 0 - infinite loop", OFFSET(loop),
+ AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 65535, ENC },
+ { NULL },
+};
+
+static const AVClass webp_muxer_class = {
+ .class_name = "WebP muxer",
+ .item_name = av_default_item_name,
+ .version = LIBAVUTIL_VERSION_INT,
+ .option = options,
+};
+AVOutputFormat ff_webp_muxer = {
+ .name = "webp",
+ .long_name = NULL_IF_CONFIG_SMALL("WebP"),
+ .extensions = "webp",
+ .priv_data_size = sizeof(WebpContext),
+ .video_codec = AV_CODEC_ID_WEBP,
+ .write_header = webp_write_header,
+ .write_packet = webp_write_packet,
+ .write_trailer = webp_write_trailer,
+ .priv_class = &webp_muxer_class,
+ .flags = AVFMT_VARIABLE_FPS,
+};
#include "libavutil/channel_layout.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/intfloat.h"
+#include "libavutil/time_internal.h"
#include "avformat.h"
#include "internal.h"
#include "wtv.h"
static int filetime_to_iso8601(char *buf, int buf_size, int64_t value)
{
time_t t = (value / 10000000LL) - 11644473600LL;
- struct tm *tm = gmtime(&t);
+ struct tm tmbuf;
+ struct tm *tm = gmtime_r(&t, &tmbuf);
if (!tm)
return -1;
- strftime(buf, buf_size, "%Y-%m-%d %H:%M:%S", gmtime(&t));
+ if (!strftime(buf, buf_size, "%Y-%m-%d %H:%M:%S", tm))
+ return -1;
return 0;
}
static int crazytime_to_iso8601(char *buf, int buf_size, int64_t value)
{
time_t t = (value / 10000000LL) - 719162LL*86400LL;
- struct tm *tm = gmtime(&t);
+ struct tm tmbuf;
+ struct tm *tm = gmtime_r(&t, &tmbuf);
if (!tm)
return -1;
- strftime(buf, buf_size, "%Y-%m-%d %H:%M:%S", gmtime(&t));
+ if (!strftime(buf, buf_size, "%Y-%m-%d %H:%M:%S", tm))
+ return -1;
return 0;
}
static int oledate_to_iso8601(char *buf, int buf_size, int64_t value)
{
time_t t = (av_int2double(value) - 25569.0) * 86400;
- struct tm *result= gmtime(&t);
- if (!result)
+ struct tm tmbuf;
+ struct tm *tm= gmtime_r(&t, &tmbuf);
+ if (!tm)
+ return -1;
+ if (!strftime(buf, buf_size, "%Y-%m-%d %H:%M:%S", tm))
return -1;
- strftime(buf, buf_size, "%Y-%m-%d %H:%M:%S", result);
return 0;
}
avio_skip(s->pb, 4);
root_sector = avio_rl32(s->pb);
- seek_by_sector(s->pb, root_sector, 0);
+ ret = seek_by_sector(s->pb, root_sector, 0);
+ if (ret < 0)
+ return ret;
root_size = avio_read(s->pb, root, root_size);
if (root_size < 0)
return AVERROR_INVALIDDATA;
static int xwma_read_header(AVFormatContext *s)
{
int64_t size;
- int ret;
+ int ret = 0;
uint32_t dpds_table_size = 0;
uint32_t *dpds_table = NULL;
unsigned int tag;
for (;;) {
if (pb->eof_reached) {
ret = AVERROR_EOF;
- goto end;
+ goto fail;
}
/* read next chunk tag */
tag = avio_rl32(pb);
if (dpds_table) {
av_log(s, AV_LOG_ERROR, "two dpds chunks present\n");
ret = AVERROR_INVALIDDATA;
- goto end;
+ goto fail;
}
/* Compute the number of entries in the dpds chunk. */
/* Determine overall data length */
if (size < 0) {
ret = AVERROR_INVALIDDATA;
- goto end;
+ goto fail;
}
if (!size) {
xwma->data_end = INT64_MAX;
"Invalid bits_per_coded_sample %d for %d channels\n",
st->codec->bits_per_coded_sample, st->codec->channels);
ret = AVERROR_INVALIDDATA;
- goto end;
+ goto fail;
}
st->duration = total_decoded_bytes / bytes_per_sample;
st->duration = (size<<3) * st->codec->sample_rate / st->codec->bit_rate;
}
-end:
+fail:
av_free(dpds_table);
return ret;
case AV_PIX_FMT_YUV420P16:
case AV_PIX_FMT_YUV422P16:
case AV_PIX_FMT_YUV444P16:
- if (s->streams[0]->codec->strict_std_compliance >= FF_COMPLIANCE_NORMAL) {
+ if (s->strict_std_compliance >= FF_COMPLIANCE_NORMAL) {
av_log(s, AV_LOG_ERROR, "'%s' is not a official yuv4mpegpipe pixel format. "
"Use '-strict -1' to encode to this pixel format.\n",
av_get_pix_fmt_name(s->streams[0]->codec->pix_fmt));
static av_always_inline int even(uint64_t layout)
{
- return (!layout || (layout & (layout - 1)));
+ return (!layout || !!(layout & (layout - 1)));
}
static int sane_layout(uint64_t layout)
static inline int available_samples(AVFrame *out)
{
+ int samples;
int bytes_per_sample = av_get_bytes_per_sample(out->format);
- int samples = out->linesize[0] / bytes_per_sample;
+ if (!bytes_per_sample)
+ return AVERROR(EINVAL);
+ samples = out->linesize[0] / bytes_per_sample;
if (av_sample_fmt_is_planar(out->format)) {
return samples;
} else {
bprint.h \
bswap.h \
buffer.h \
+ cast5.h \
channel_layout.h \
common.h \
cpu.h \
hmac.h \
imgutils.h \
intfloat.h \
- intfloat_readwrite.h \
intreadwrite.h \
lfg.h \
log.h \
blowfish.o \
bprint.o \
buffer.o \
+ cast5.o \
channel_layout.o \
cpu.o \
crc.o \
hash.o \
hmac.o \
imgutils.o \
- intfloat_readwrite.o \
intmath.o \
lfg.o \
lls.o \
base64 \
blowfish \
bprint \
+ cast5 \
cpu \
crc \
des \
+ dict \
error \
eval \
file \
ripemd \
sha \
sha512 \
+ softfloat \
tree \
utf8 \
xtea \
void ff_vector_fmul_reverse_vfp(float *dst, const float *src0,
const float *src1, int len);
-void ff_butterflies_float_vfp(float *restrict v1, float *restrict v2, int len);
+void ff_butterflies_float_vfp(float *av_restrict v1, float *av_restrict v2, int len);
av_cold void ff_float_dsp_init_vfp(AVFloatDSPContext *fdsp, int cpu_flags)
{
#define avpriv_atomic_int_get atomic_int_get_gcc
static inline int atomic_int_get_gcc(volatile int *ptr)
{
+#if HAVE_ATOMIC_COMPARE_EXCHANGE
+ return __atomic_load_n(ptr, __ATOMIC_SEQ_CST);
+#else
__sync_synchronize();
return *ptr;
+#endif
}
#define avpriv_atomic_int_set atomic_int_set_gcc
static inline void atomic_int_set_gcc(volatile int *ptr, int val)
{
+#if HAVE_ATOMIC_COMPARE_EXCHANGE
+ __atomic_store_n(ptr, val, __ATOMIC_SEQ_CST);
+#else
*ptr = val;
__sync_synchronize();
+#endif
}
#define avpriv_atomic_int_add_and_fetch atomic_int_add_and_fetch_gcc
static inline int atomic_int_add_and_fetch_gcc(volatile int *ptr, int inc)
{
+#if HAVE_ATOMIC_COMPARE_EXCHANGE
+ return __atomic_add_fetch(ptr, inc, __ATOMIC_SEQ_CST);
+#else
return __sync_add_and_fetch(ptr, inc);
+#endif
}
#define avpriv_atomic_ptr_cas atomic_ptr_cas_gcc
static inline void *atomic_ptr_cas_gcc(void * volatile *ptr,
void *oldval, void *newval)
{
+#if HAVE_SYNC_VAL_COMPARE_AND_SWAP
#ifdef __ARMCC_VERSION
// armcc will throw an error if ptr is not an integer type
volatile uintptr_t *tmp = (volatile uintptr_t*)ptr;
#else
return __sync_val_compare_and_swap(ptr, oldval, newval);
#endif
+#else
+ __atomic_compare_exchange_n(ptr, &oldval, newval, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
+ return oldval;
+#endif
}
#endif /* AVUTIL_ATOMIC_GCC_H */
#ifndef AVUTIL_ATOMIC_WIN32_H
#define AVUTIL_ATOMIC_WIN32_H
+#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#define avpriv_atomic_int_get atomic_int_get_win32
return ret;
}
+int av_match_list(const char *name, const char *list, char separator)
+{
+ const char *p, *q;
+
+ for (p = name; p && *p; ) {
+ for (q = list; q && *q; ) {
+ int k;
+ for (k = 0; p[k] == q[k] || (p[k]*q[k] == 0 && p[k]+q[k] == separator); k++)
+ if (k && (!p[k] || p[k] == separator))
+ return 1;
+ q = strchr(q, separator);
+ q += !!q;
+ }
+ p = strchr(p, separator);
+ p += !!p;
+ }
+
+ return 0;
+}
+
#ifdef TEST
int main(void)
/**
* Locale-independent conversion of ASCII isdigit.
*/
-int av_isdigit(int c);
+av_const int av_isdigit(int c);
/**
* Locale-independent conversion of ASCII isgraph.
*/
-int av_isgraph(int c);
+av_const int av_isgraph(int c);
/**
* Locale-independent conversion of ASCII isspace.
*/
-int av_isspace(int c);
+av_const int av_isspace(int c);
/**
* Locale-independent conversion of ASCII characters to uppercase.
*/
-static inline int av_toupper(int c)
+static inline av_const int av_toupper(int c)
{
if (c >= 'a' && c <= 'z')
c ^= 0x20;
/**
* Locale-independent conversion of ASCII characters to lowercase.
*/
-static inline int av_tolower(int c)
+static inline av_const int av_tolower(int c)
{
if (c >= 'A' && c <= 'Z')
c ^= 0x20;
/**
* Locale-independent conversion of ASCII isxdigit.
*/
-int av_isxdigit(int c);
+av_const int av_isxdigit(int c);
/**
* Locale-independent case-insensitive compare.
int av_utf8_decode(int32_t *codep, const uint8_t **bufp, const uint8_t *buf_end,
unsigned int flags);
+/**
+ * Check if a name is in a list.
+ * @returns 0 if not found, or the 1 based index where it has been found in the
+ * list.
+ */
+int av_match_list(const char *name, const char *list, char separator);
+
/**
* @}
*/
* Define a structure with extra padding to a fixed size
* This helps ensuring binary compatibility with future versions.
*/
-#define FF_PAD_STRUCTURE(size, ...) \
+
+#define FF_PAD_STRUCTURE(name, size, ...) \
+struct ff_pad_helper_##name { __VA_ARGS__ }; \
+typedef struct name { \
__VA_ARGS__ \
- char reserved_padding[size - sizeof(struct { __VA_ARGS__ })];
+ char reserved_padding[size - sizeof(struct ff_pad_helper_##name)]; \
+} name;
/**
* Buffer to print data progressively
* internal buffer is large enough to hold a reasonable paragraph of text,
* such as the current paragraph.
*/
-typedef struct AVBPrint {
- FF_PAD_STRUCTURE(1024,
+
+FF_PAD_STRUCTURE(AVBPrint, 1024,
char *str; /**< string so far */
unsigned len; /**< length so far */
unsigned size; /**< allocated memory */
unsigned size_max; /**< maximum allocated memory */
char reserved_internal_buffer[1];
- )
-} AVBPrint;
+)
/**
* Convenience macros for special values for av_bprint_init() size_max
* It may have been truncated due to a memory allocation failure
* or the size_max limit (compare size and size_max if necessary).
*/
-static inline int av_bprint_is_complete(AVBPrint *buf)
+static inline int av_bprint_is_complete(const AVBPrint *buf)
{
return buf->len < buf->size;
}
#include "buffer_internal.h"
#include "common.h"
#include "mem.h"
+#include "thread.h"
AVBufferRef *av_buffer_create(uint8_t *data, int size,
void (*free)(void *opaque, uint8_t *data),
if (!pool)
return NULL;
+ ff_mutex_init(&pool->mutex, NULL);
+
pool->size = size;
pool->alloc = alloc ? alloc : av_buffer_alloc;
buf->free(buf->opaque, buf->data);
av_freep(&buf);
}
+ ff_mutex_destroy(&pool->mutex);
av_freep(&pool);
}
if(CONFIG_MEMORY_POISONING)
memset(buf->data, FF_MEMORY_POISON, pool->size);
+#if USE_ATOMICS
add_to_pool(buf);
+#else
+ ff_mutex_lock(&pool->mutex);
+ buf->next = pool->pool;
+ pool->pool = buf;
+ ff_mutex_unlock(&pool->mutex);
+#endif
+
if (!avpriv_atomic_int_add_and_fetch(&pool->refcount, -1))
buffer_pool_free(pool);
}
ret->buffer->opaque = buf;
ret->buffer->free = pool_release_buffer;
+#if USE_ATOMICS
avpriv_atomic_int_add_and_fetch(&pool->refcount, 1);
avpriv_atomic_int_add_and_fetch(&pool->nb_allocated, 1);
+#endif
return ret;
}
AVBufferRef *ret;
BufferPoolEntry *buf;
+#if USE_ATOMICS
/* check whether the pool is empty */
buf = get_pool(pool);
if (!buf && pool->refcount <= pool->nb_allocated) {
add_to_pool(buf);
return NULL;
}
- avpriv_atomic_int_add_and_fetch(&pool->refcount, 1);
+#else
+ ff_mutex_lock(&pool->mutex);
+ buf = pool->pool;
+ if (buf) {
+ ret = av_buffer_create(buf->data, pool->size, pool_release_buffer,
+ buf, 0);
+ if (ret) {
+ pool->pool = buf->next;
+ buf->next = NULL;
+ }
+ } else {
+ ret = pool_alloc_buffer(pool);
+ }
+ ff_mutex_unlock(&pool->mutex);
+#endif
+
+ if (ret)
+ avpriv_atomic_int_add_and_fetch(&pool->refcount, 1);
return ret;
}
#include <stdint.h>
#include "buffer.h"
+#include "thread.h"
/**
* The buffer is always treated as read-only.
void (*free)(void *opaque, uint8_t *data);
AVBufferPool *pool;
- struct BufferPoolEntry * volatile next;
+ struct BufferPoolEntry *next;
} BufferPoolEntry;
struct AVBufferPool {
- BufferPoolEntry * volatile pool;
+ AVMutex mutex;
+ BufferPoolEntry *pool;
/*
* This is used to track when the pool is to be freed.
--- /dev/null
+/*
+ * An implementation of the CAST128 algorithm as mentioned in RFC2144
+ * Copyright (c) 2014 Supraja Meedinti
+ *
+ * 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 "cast5.h"
+#include "common.h"
+#include "intreadwrite.h"
+#include "attributes.h"
+
+#define IA(x) ((x)>>24)
+#define IB(x) (((x)>>16) & 0xff)
+#define IC(x) (((x)>>8) & 0xff)
+#define ID(x) ((x) & 0xff)
+
+#define LR(x,c) (((x)<<(c))|((x)>>(32-(c))))
+
+#define F3(l,r,i) \
+ do { \
+ I=LR(cs->Km[i]-r,cs->Kr[i]); \
+ f=((S1[IA(I)]+S2[IB(I)])^S3[IC(I)])-S4[ID(I)]; \
+ l=f^l; \
+ } while (0)
+
+#define F2(l,r,i) \
+ do { \
+ I=LR(cs->Km[i]^r,cs->Kr[i]); \
+ f=((S1[IA(I)]-S2[IB(I)])+S3[IC(I)])^S4[ID(I)]; \
+ l=f^l; \
+ } while (0)
+
+#define F1(l,r,i) \
+ do { \
+ I=LR(cs->Km[i]+r,cs->Kr[i]); \
+ f=((S1[IA(I)]^S2[IB(I)])-S3[IC(I)])+S4[ID(I)]; \
+ l=f^l; \
+ } while (0)
+
+#define COMPUTE_Z \
+ do { \
+ z[0]=x[0]^S5[IB(x[3])]^S6[ID(x[3])]^S7[IA(x[3])]^S8[IC(x[3])]^S7[IA(x[2])]; \
+ z[1]=x[2]^S5[IA(z[0])]^S6[IC(z[0])]^S7[IB(z[0])]^S8[ID(z[0])]^S8[IC(x[2])]; \
+ z[2]=x[3]^S5[ID(z[1])]^S6[IC(z[1])]^S7[IB(z[1])]^S8[IA(z[1])]^S5[IB(x[2])]; \
+ z[3]=x[1]^S5[IC(z[2])]^S6[IB(z[2])]^S7[ID(z[2])]^S8[IA(z[2])]^S6[ID(x[2])]; \
+ } while (0)
+
+#define COMPUTE_X \
+ do { \
+ x[0]=z[2]^S5[IB(z[1])]^S6[ID(z[1])]^S7[IA(z[1])]^S8[IC(z[1])]^S7[IA(z[0])]; \
+ x[1]=z[0]^S5[IA(x[0])]^S6[IC(x[0])]^S7[IB(x[0])]^S8[ID(x[0])]^S8[IC(z[0])]; \
+ x[2]=z[1]^S5[ID(x[1])]^S6[IC(x[1])]^S7[IB(x[1])]^S8[IA(x[1])]^S5[IB(z[0])]; \
+ x[3]=z[3]^S5[IC(x[2])]^S6[IB(x[2])]^S7[ID(x[2])]^S8[IA(x[2])]^S6[ID(z[0])]; \
+ } while (0)
+
+
+typedef struct AVCAST5 {
+ uint32_t Km[17];
+ uint32_t Kr[17];
+ int rounds;
+} AVCAST5;
+
+const int av_cast5_size= sizeof(AVCAST5);
+
+static const uint32_t S1[256]={
+ 0x30fb40d4, 0x9fa0ff0b, 0x6beccd2f, 0x3f258c7a, 0x1e213f2f, 0x9c004dd3, 0x6003e540, 0xcf9fc949,
+ 0xbfd4af27, 0x88bbbdb5, 0xe2034090, 0x98d09675, 0x6e63a0e0, 0x15c361d2, 0xc2e7661d, 0x22d4ff8e,
+ 0x28683b6f, 0xc07fd059, 0xff2379c8, 0x775f50e2, 0x43c340d3, 0xdf2f8656, 0x887ca41a, 0xa2d2bd2d,
+ 0xa1c9e0d6, 0x346c4819, 0x61b76d87, 0x22540f2f, 0x2abe32e1, 0xaa54166b, 0x22568e3a, 0xa2d341d0,
+ 0x66db40c8, 0xa784392f, 0x004dff2f, 0x2db9d2de, 0x97943fac, 0x4a97c1d8, 0x527644b7, 0xb5f437a7,
+ 0xb82cbaef, 0xd751d159, 0x6ff7f0ed, 0x5a097a1f, 0x827b68d0, 0x90ecf52e, 0x22b0c054, 0xbc8e5935,
+ 0x4b6d2f7f, 0x50bb64a2, 0xd2664910, 0xbee5812d, 0xb7332290, 0xe93b159f, 0xb48ee411, 0x4bff345d,
+ 0xfd45c240, 0xad31973f, 0xc4f6d02e, 0x55fc8165, 0xd5b1caad, 0xa1ac2dae, 0xa2d4b76d, 0xc19b0c50,
+ 0x882240f2, 0x0c6e4f38, 0xa4e4bfd7, 0x4f5ba272, 0x564c1d2f, 0xc59c5319, 0xb949e354, 0xb04669fe,
+ 0xb1b6ab8a, 0xc71358dd, 0x6385c545, 0x110f935d, 0x57538ad5, 0x6a390493, 0xe63d37e0, 0x2a54f6b3,
+ 0x3a787d5f, 0x6276a0b5, 0x19a6fcdf, 0x7a42206a, 0x29f9d4d5, 0xf61b1891, 0xbb72275e, 0xaa508167,
+ 0x38901091, 0xc6b505eb, 0x84c7cb8c, 0x2ad75a0f, 0x874a1427, 0xa2d1936b, 0x2ad286af, 0xaa56d291,
+ 0xd7894360, 0x425c750d, 0x93b39e26, 0x187184c9, 0x6c00b32d, 0x73e2bb14, 0xa0bebc3c, 0x54623779,
+ 0x64459eab, 0x3f328b82, 0x7718cf82, 0x59a2cea6, 0x04ee002e, 0x89fe78e6, 0x3fab0950, 0x325ff6c2,
+ 0x81383f05, 0x6963c5c8, 0x76cb5ad6, 0xd49974c9, 0xca180dcf, 0x380782d5, 0xc7fa5cf6, 0x8ac31511,
+ 0x35e79e13, 0x47da91d0, 0xf40f9086, 0xa7e2419e, 0x31366241, 0x051ef495, 0xaa573b04, 0x4a805d8d,
+ 0x548300d0, 0x00322a3c, 0xbf64cddf, 0xba57a68e, 0x75c6372b, 0x50afd341, 0xa7c13275, 0x915a0bf5,
+ 0x6b54bfab, 0x2b0b1426, 0xab4cc9d7, 0x449ccd82, 0xf7fbf265, 0xab85c5f3, 0x1b55db94, 0xaad4e324,
+ 0xcfa4bd3f, 0x2deaa3e2, 0x9e204d02, 0xc8bd25ac, 0xeadf55b3, 0xd5bd9e98, 0xe31231b2, 0x2ad5ad6c,
+ 0x954329de, 0xadbe4528, 0xd8710f69, 0xaa51c90f, 0xaa786bf6, 0x22513f1e, 0xaa51a79b, 0x2ad344cc,
+ 0x7b5a41f0, 0xd37cfbad, 0x1b069505, 0x41ece491, 0xb4c332e6, 0x032268d4, 0xc9600acc, 0xce387e6d,
+ 0xbf6bb16c, 0x6a70fb78, 0x0d03d9c9, 0xd4df39de, 0xe01063da, 0x4736f464, 0x5ad328d8, 0xb347cc96,
+ 0x75bb0fc3, 0x98511bfb, 0x4ffbcc35, 0xb58bcf6a, 0xe11f0abc, 0xbfc5fe4a, 0xa70aec10, 0xac39570a,
+ 0x3f04442f, 0x6188b153, 0xe0397a2e, 0x5727cb79, 0x9ceb418f, 0x1cacd68d, 0x2ad37c96, 0x0175cb9d,
+ 0xc69dff09, 0xc75b65f0, 0xd9db40d8, 0xec0e7779, 0x4744ead4, 0xb11c3274, 0xdd24cb9e, 0x7e1c54bd,
+ 0xf01144f9, 0xd2240eb1, 0x9675b3fd, 0xa3ac3755, 0xd47c27af, 0x51c85f4d, 0x56907596, 0xa5bb15e6,
+ 0x580304f0, 0xca042cf1, 0x011a37ea, 0x8dbfaadb, 0x35ba3e4a, 0x3526ffa0, 0xc37b4d09, 0xbc306ed9,
+ 0x98a52666, 0x5648f725, 0xff5e569d, 0x0ced63d0, 0x7c63b2cf, 0x700b45e1, 0xd5ea50f1, 0x85a92872,
+ 0xaf1fbda7, 0xd4234870, 0xa7870bf3, 0x2d3b4d79, 0x42e04198, 0x0cd0ede7, 0x26470db8, 0xf881814c,
+ 0x474d6ad7, 0x7c0c5e5c, 0xd1231959, 0x381b7298, 0xf5d2f4db, 0xab838653, 0x6e2f1e23, 0x83719c9e,
+ 0xbd91e046, 0x9a56456e, 0xdc39200c, 0x20c8c571, 0x962bda1c, 0xe1e696ff, 0xb141ab08, 0x7cca89b9,
+ 0x1a69e783, 0x02cc4843, 0xa2f7c579, 0x429ef47d, 0x427b169c, 0x5ac9f049, 0xdd8f0f00, 0x5c8165bf};
+
+static const uint32_t S2[256]={
+ 0x1f201094, 0xef0ba75b, 0x69e3cf7e, 0x393f4380, 0xfe61cf7a, 0xeec5207a, 0x55889c94, 0x72fc0651,
+ 0xada7ef79, 0x4e1d7235, 0xd55a63ce, 0xde0436ba, 0x99c430ef, 0x5f0c0794, 0x18dcdb7d, 0xa1d6eff3,
+ 0xa0b52f7b, 0x59e83605, 0xee15b094, 0xe9ffd909, 0xdc440086, 0xef944459, 0xba83ccb3, 0xe0c3cdfb,
+ 0xd1da4181, 0x3b092ab1, 0xf997f1c1, 0xa5e6cf7b, 0x01420ddb, 0xe4e7ef5b, 0x25a1ff41, 0xe180f806,
+ 0x1fc41080, 0x179bee7a, 0xd37ac6a9, 0xfe5830a4, 0x98de8b7f, 0x77e83f4e, 0x79929269, 0x24fa9f7b,
+ 0xe113c85b, 0xacc40083, 0xd7503525, 0xf7ea615f, 0x62143154, 0x0d554b63, 0x5d681121, 0xc866c359,
+ 0x3d63cf73, 0xcee234c0, 0xd4d87e87, 0x5c672b21, 0x071f6181, 0x39f7627f, 0x361e3084, 0xe4eb573b,
+ 0x602f64a4, 0xd63acd9c, 0x1bbc4635, 0x9e81032d, 0x2701f50c, 0x99847ab4, 0xa0e3df79, 0xba6cf38c,
+ 0x10843094, 0x2537a95e, 0xf46f6ffe, 0xa1ff3b1f, 0x208cfb6a, 0x8f458c74, 0xd9e0a227, 0x4ec73a34,
+ 0xfc884f69, 0x3e4de8df, 0xef0e0088, 0x3559648d, 0x8a45388c, 0x1d804366, 0x721d9bfd, 0xa58684bb,
+ 0xe8256333, 0x844e8212, 0x128d8098, 0xfed33fb4, 0xce280ae1, 0x27e19ba5, 0xd5a6c252, 0xe49754bd,
+ 0xc5d655dd, 0xeb667064, 0x77840b4d, 0xa1b6a801, 0x84db26a9, 0xe0b56714, 0x21f043b7, 0xe5d05860,
+ 0x54f03084, 0x066ff472, 0xa31aa153, 0xdadc4755, 0xb5625dbf, 0x68561be6, 0x83ca6b94, 0x2d6ed23b,
+ 0xeccf01db, 0xa6d3d0ba, 0xb6803d5c, 0xaf77a709, 0x33b4a34c, 0x397bc8d6, 0x5ee22b95, 0x5f0e5304,
+ 0x81ed6f61, 0x20e74364, 0xb45e1378, 0xde18639b, 0x881ca122, 0xb96726d1, 0x8049a7e8, 0x22b7da7b,
+ 0x5e552d25, 0x5272d237, 0x79d2951c, 0xc60d894c, 0x488cb402, 0x1ba4fe5b, 0xa4b09f6b, 0x1ca815cf,
+ 0xa20c3005, 0x8871df63, 0xb9de2fcb, 0x0cc6c9e9, 0x0beeff53, 0xe3214517, 0xb4542835, 0x9f63293c,
+ 0xee41e729, 0x6e1d2d7c, 0x50045286, 0x1e6685f3, 0xf33401c6, 0x30a22c95, 0x31a70850, 0x60930f13,
+ 0x73f98417, 0xa1269859, 0xec645c44, 0x52c877a9, 0xcdff33a6, 0xa02b1741, 0x7cbad9a2, 0x2180036f,
+ 0x50d99c08, 0xcb3f4861, 0xc26bd765, 0x64a3f6ab, 0x80342676, 0x25a75e7b, 0xe4e6d1fc, 0x20c710e6,
+ 0xcdf0b680, 0x17844d3b, 0x31eef84d, 0x7e0824e4, 0x2ccb49eb, 0x846a3bae, 0x8ff77888, 0xee5d60f6,
+ 0x7af75673, 0x2fdd5cdb, 0xa11631c1, 0x30f66f43, 0xb3faec54, 0x157fd7fa, 0xef8579cc, 0xd152de58,
+ 0xdb2ffd5e, 0x8f32ce19, 0x306af97a, 0x02f03ef8, 0x99319ad5, 0xc242fa0f, 0xa7e3ebb0, 0xc68e4906,
+ 0xb8da230c, 0x80823028, 0xdcdef3c8, 0xd35fb171, 0x088a1bc8, 0xbec0c560, 0x61a3c9e8, 0xbca8f54d,
+ 0xc72feffa, 0x22822e99, 0x82c570b4, 0xd8d94e89, 0x8b1c34bc, 0x301e16e6, 0x273be979, 0xb0ffeaa6,
+ 0x61d9b8c6, 0x00b24869, 0xb7ffce3f, 0x08dc283b, 0x43daf65a, 0xf7e19798, 0x7619b72f, 0x8f1c9ba4,
+ 0xdc8637a0, 0x16a7d3b1, 0x9fc393b7, 0xa7136eeb, 0xc6bcc63e, 0x1a513742, 0xef6828bc, 0x520365d6,
+ 0x2d6a77ab, 0x3527ed4b, 0x821fd216, 0x095c6e2e, 0xdb92f2fb, 0x5eea29cb, 0x145892f5, 0x91584f7f,
+ 0x5483697b, 0x2667a8cc, 0x85196048, 0x8c4bacea, 0x833860d4, 0x0d23e0f9, 0x6c387e8a, 0x0ae6d249,
+ 0xb284600c, 0xd835731d, 0xdcb1c647, 0xac4c56ea, 0x3ebd81b3, 0x230eabb0, 0x6438bc87, 0xf0b5b1fa,
+ 0x8f5ea2b3, 0xfc184642, 0x0a036b7a, 0x4fb089bd, 0x649da589, 0xa345415e, 0x5c038323, 0x3e5d3bb9,
+ 0x43d79572, 0x7e6dd07c, 0x06dfdf1e, 0x6c6cc4ef, 0x7160a539, 0x73bfbe70, 0x83877605, 0x4523ecf1};
+
+static const uint32_t S3[256]={
+ 0x8defc240, 0x25fa5d9f, 0xeb903dbf, 0xe810c907, 0x47607fff, 0x369fe44b, 0x8c1fc644, 0xaececa90,
+ 0xbeb1f9bf, 0xeefbcaea, 0xe8cf1950, 0x51df07ae, 0x920e8806, 0xf0ad0548, 0xe13c8d83, 0x927010d5,
+ 0x11107d9f, 0x07647db9, 0xb2e3e4d4, 0x3d4f285e, 0xb9afa820, 0xfade82e0, 0xa067268b, 0x8272792e,
+ 0x553fb2c0, 0x489ae22b, 0xd4ef9794, 0x125e3fbc, 0x21fffcee, 0x825b1bfd, 0x9255c5ed, 0x1257a240,
+ 0x4e1a8302, 0xbae07fff, 0x528246e7, 0x8e57140e, 0x3373f7bf, 0x8c9f8188, 0xa6fc4ee8, 0xc982b5a5,
+ 0xa8c01db7, 0x579fc264, 0x67094f31, 0xf2bd3f5f, 0x40fff7c1, 0x1fb78dfc, 0x8e6bd2c1, 0x437be59b,
+ 0x99b03dbf, 0xb5dbc64b, 0x638dc0e6, 0x55819d99, 0xa197c81c, 0x4a012d6e, 0xc5884a28, 0xccc36f71,
+ 0xb843c213, 0x6c0743f1, 0x8309893c, 0x0feddd5f, 0x2f7fe850, 0xd7c07f7e, 0x02507fbf, 0x5afb9a04,
+ 0xa747d2d0, 0x1651192e, 0xaf70bf3e, 0x58c31380, 0x5f98302e, 0x727cc3c4, 0x0a0fb402, 0x0f7fef82,
+ 0x8c96fdad, 0x5d2c2aae, 0x8ee99a49, 0x50da88b8, 0x8427f4a0, 0x1eac5790, 0x796fb449, 0x8252dc15,
+ 0xefbd7d9b, 0xa672597d, 0xada840d8, 0x45f54504, 0xfa5d7403, 0xe83ec305, 0x4f91751a, 0x925669c2,
+ 0x23efe941, 0xa903f12e, 0x60270df2, 0x0276e4b6, 0x94fd6574, 0x927985b2, 0x8276dbcb, 0x02778176,
+ 0xf8af918d, 0x4e48f79e, 0x8f616ddf, 0xe29d840e, 0x842f7d83, 0x340ce5c8, 0x96bbb682, 0x93b4b148,
+ 0xef303cab, 0x984faf28, 0x779faf9b, 0x92dc560d, 0x224d1e20, 0x8437aa88, 0x7d29dc96, 0x2756d3dc,
+ 0x8b907cee, 0xb51fd240, 0xe7c07ce3, 0xe566b4a1, 0xc3e9615e, 0x3cf8209d, 0x6094d1e3, 0xcd9ca341,
+ 0x5c76460e, 0x00ea983b, 0xd4d67881, 0xfd47572c, 0xf76cedd9, 0xbda8229c, 0x127dadaa, 0x438a074e,
+ 0x1f97c090, 0x081bdb8a, 0x93a07ebe, 0xb938ca15, 0x97b03cff, 0x3dc2c0f8, 0x8d1ab2ec, 0x64380e51,
+ 0x68cc7bfb, 0xd90f2788, 0x12490181, 0x5de5ffd4, 0xdd7ef86a, 0x76a2e214, 0xb9a40368, 0x925d958f,
+ 0x4b39fffa, 0xba39aee9, 0xa4ffd30b, 0xfaf7933b, 0x6d498623, 0x193cbcfa, 0x27627545, 0x825cf47a,
+ 0x61bd8ba0, 0xd11e42d1, 0xcead04f4, 0x127ea392, 0x10428db7, 0x8272a972, 0x9270c4a8, 0x127de50b,
+ 0x285ba1c8, 0x3c62f44f, 0x35c0eaa5, 0xe805d231, 0x428929fb, 0xb4fcdf82, 0x4fb66a53, 0x0e7dc15b,
+ 0x1f081fab, 0x108618ae, 0xfcfd086d, 0xf9ff2889, 0x694bcc11, 0x236a5cae, 0x12deca4d, 0x2c3f8cc5,
+ 0xd2d02dfe, 0xf8ef5896, 0xe4cf52da, 0x95155b67, 0x494a488c, 0xb9b6a80c, 0x5c8f82bc, 0x89d36b45,
+ 0x3a609437, 0xec00c9a9, 0x44715253, 0x0a874b49, 0xd773bc40, 0x7c34671c, 0x02717ef6, 0x4feb5536,
+ 0xa2d02fff, 0xd2bf60c4, 0xd43f03c0, 0x50b4ef6d, 0x07478cd1, 0x006e1888, 0xa2e53f55, 0xb9e6d4bc,
+ 0xa2048016, 0x97573833, 0xd7207d67, 0xde0f8f3d, 0x72f87b33, 0xabcc4f33, 0x7688c55d, 0x7b00a6b0,
+ 0x947b0001, 0x570075d2, 0xf9bb88f8, 0x8942019e, 0x4264a5ff, 0x856302e0, 0x72dbd92b, 0xee971b69,
+ 0x6ea22fde, 0x5f08ae2b, 0xaf7a616d, 0xe5c98767, 0xcf1febd2, 0x61efc8c2, 0xf1ac2571, 0xcc8239c2,
+ 0x67214cb8, 0xb1e583d1, 0xb7dc3e62, 0x7f10bdce, 0xf90a5c38, 0x0ff0443d, 0x606e6dc6, 0x60543a49,
+ 0x5727c148, 0x2be98a1d, 0x8ab41738, 0x20e1be24, 0xaf96da0f, 0x68458425, 0x99833be5, 0x600d457d,
+ 0x282f9350, 0x8334b362, 0xd91d1120, 0x2b6d8da0, 0x642b1e31, 0x9c305a00, 0x52bce688, 0x1b03588a,
+ 0xf7baefd5, 0x4142ed9c, 0xa4315c11, 0x83323ec5, 0xdfef4636, 0xa133c501, 0xe9d3531c, 0xee353783};
+
+static const uint32_t S4[256]={
+ 0x9db30420, 0x1fb6e9de, 0xa7be7bef, 0xd273a298, 0x4a4f7bdb, 0x64ad8c57, 0x85510443, 0xfa020ed1,
+ 0x7e287aff, 0xe60fb663, 0x095f35a1, 0x79ebf120, 0xfd059d43, 0x6497b7b1, 0xf3641f63, 0x241e4adf,
+ 0x28147f5f, 0x4fa2b8cd, 0xc9430040, 0x0cc32220, 0xfdd30b30, 0xc0a5374f, 0x1d2d00d9, 0x24147b15,
+ 0xee4d111a, 0x0fca5167, 0x71ff904c, 0x2d195ffe, 0x1a05645f, 0x0c13fefe, 0x081b08ca, 0x05170121,
+ 0x80530100, 0xe83e5efe, 0xac9af4f8, 0x7fe72701, 0xd2b8ee5f, 0x06df4261, 0xbb9e9b8a, 0x7293ea25,
+ 0xce84ffdf, 0xf5718801, 0x3dd64b04, 0xa26f263b, 0x7ed48400, 0x547eebe6, 0x446d4ca0, 0x6cf3d6f5,
+ 0x2649abdf, 0xaea0c7f5, 0x36338cc1, 0x503f7e93, 0xd3772061, 0x11b638e1, 0x72500e03, 0xf80eb2bb,
+ 0xabe0502e, 0xec8d77de, 0x57971e81, 0xe14f6746, 0xc9335400, 0x6920318f, 0x081dbb99, 0xffc304a5,
+ 0x4d351805, 0x7f3d5ce3, 0xa6c866c6, 0x5d5bcca9, 0xdaec6fea, 0x9f926f91, 0x9f46222f, 0x3991467d,
+ 0xa5bf6d8e, 0x1143c44f, 0x43958302, 0xd0214eeb, 0x022083b8, 0x3fb6180c, 0x18f8931e, 0x281658e6,
+ 0x26486e3e, 0x8bd78a70, 0x7477e4c1, 0xb506e07c, 0xf32d0a25, 0x79098b02, 0xe4eabb81, 0x28123b23,
+ 0x69dead38, 0x1574ca16, 0xdf871b62, 0x211c40b7, 0xa51a9ef9, 0x0014377b, 0x041e8ac8, 0x09114003,
+ 0xbd59e4d2, 0xe3d156d5, 0x4fe876d5, 0x2f91a340, 0x557be8de, 0x00eae4a7, 0x0ce5c2ec, 0x4db4bba6,
+ 0xe756bdff, 0xdd3369ac, 0xec17b035, 0x06572327, 0x99afc8b0, 0x56c8c391, 0x6b65811c, 0x5e146119,
+ 0x6e85cb75, 0xbe07c002, 0xc2325577, 0x893ff4ec, 0x5bbfc92d, 0xd0ec3b25, 0xb7801ab7, 0x8d6d3b24,
+ 0x20c763ef, 0xc366a5fc, 0x9c382880, 0x0ace3205, 0xaac9548a, 0xeca1d7c7, 0x041afa32, 0x1d16625a,
+ 0x6701902c, 0x9b757a54, 0x31d477f7, 0x9126b031, 0x36cc6fdb, 0xc70b8b46, 0xd9e66a48, 0x56e55a79,
+ 0x026a4ceb, 0x52437eff, 0x2f8f76b4, 0x0df980a5, 0x8674cde3, 0xedda04eb, 0x17a9be04, 0x2c18f4df,
+ 0xb7747f9d, 0xab2af7b4, 0xefc34d20, 0x2e096b7c, 0x1741a254, 0xe5b6a035, 0x213d42f6, 0x2c1c7c26,
+ 0x61c2f50f, 0x6552daf9, 0xd2c231f8, 0x25130f69, 0xd8167fa2, 0x0418f2c8, 0x001a96a6, 0x0d1526ab,
+ 0x63315c21, 0x5e0a72ec, 0x49bafefd, 0x187908d9, 0x8d0dbd86, 0x311170a7, 0x3e9b640c, 0xcc3e10d7,
+ 0xd5cad3b6, 0x0caec388, 0xf73001e1, 0x6c728aff, 0x71eae2a1, 0x1f9af36e, 0xcfcbd12f, 0xc1de8417,
+ 0xac07be6b, 0xcb44a1d8, 0x8b9b0f56, 0x013988c3, 0xb1c52fca, 0xb4be31cd, 0xd8782806, 0x12a3a4e2,
+ 0x6f7de532, 0x58fd7eb6, 0xd01ee900, 0x24adffc2, 0xf4990fc5, 0x9711aac5, 0x001d7b95, 0x82e5e7d2,
+ 0x109873f6, 0x00613096, 0xc32d9521, 0xada121ff, 0x29908415, 0x7fbb977f, 0xaf9eb3db, 0x29c9ed2a,
+ 0x5ce2a465, 0xa730f32c, 0xd0aa3fe8, 0x8a5cc091, 0xd49e2ce7, 0x0ce454a9, 0xd60acd86, 0x015f1919,
+ 0x77079103, 0xdea03af6, 0x78a8565e, 0xdee356df, 0x21f05cbe, 0x8b75e387, 0xb3c50651, 0xb8a5c3ef,
+ 0xd8eeb6d2, 0xe523be77, 0xc2154529, 0x2f69efdf, 0xafe67afb, 0xf470c4b2, 0xf3e0eb5b, 0xd6cc9876,
+ 0x39e4460c, 0x1fda8538, 0x1987832f, 0xca007367, 0xa99144f8, 0x296b299e, 0x492fc295, 0x9266beab,
+ 0xb5676e69, 0x9bd3ddda, 0xdf7e052f, 0xdb25701c, 0x1b5e51ee, 0xf65324e6, 0x6afce36c, 0x0316cc04,
+ 0x8644213e, 0xb7dc59d0, 0x7965291f, 0xccd6fd43, 0x41823979, 0x932bcdf6, 0xb657c34d, 0x4edfd282,
+ 0x7ae5290c, 0x3cb9536b, 0x851e20fe, 0x9833557e, 0x13ecf0b0, 0xd3ffb372, 0x3f85c5c1, 0x0aef7ed2};
+
+static const uint32_t S5[256]={
+ 0x7ec90c04, 0x2c6e74b9, 0x9b0e66df, 0xa6337911, 0xb86a7fff, 0x1dd358f5, 0x44dd9d44, 0x1731167f,
+ 0x08fbf1fa, 0xe7f511cc, 0xd2051b00, 0x735aba00, 0x2ab722d8, 0x386381cb, 0xacf6243a, 0x69befd7a,
+ 0xe6a2e77f, 0xf0c720cd, 0xc4494816, 0xccf5c180, 0x38851640, 0x15b0a848, 0xe68b18cb, 0x4caadeff,
+ 0x5f480a01, 0x0412b2aa, 0x259814fc, 0x41d0efe2, 0x4e40b48d, 0x248eb6fb, 0x8dba1cfe, 0x41a99b02,
+ 0x1a550a04, 0xba8f65cb, 0x7251f4e7, 0x95a51725, 0xc106ecd7, 0x97a5980a, 0xc539b9aa, 0x4d79fe6a,
+ 0xf2f3f763, 0x68af8040, 0xed0c9e56, 0x11b4958b, 0xe1eb5a88, 0x8709e6b0, 0xd7e07156, 0x4e29fea7,
+ 0x6366e52d, 0x02d1c000, 0xc4ac8e05, 0x9377f571, 0x0c05372a, 0x578535f2, 0x2261be02, 0xd642a0c9,
+ 0xdf13a280, 0x74b55bd2, 0x682199c0, 0xd421e5ec, 0x53fb3ce8, 0xc8adedb3, 0x28a87fc9, 0x3d959981,
+ 0x5c1ff900, 0xfe38d399, 0x0c4eff0b, 0x062407ea, 0xaa2f4fb1, 0x4fb96976, 0x90c79505, 0xb0a8a774,
+ 0xef55a1ff, 0xe59ca2c2, 0xa6b62d27, 0xe66a4263, 0xdf65001f, 0x0ec50966, 0xdfdd55bc, 0x29de0655,
+ 0x911e739a, 0x17af8975, 0x32c7911c, 0x89f89468, 0x0d01e980, 0x524755f4, 0x03b63cc9, 0x0cc844b2,
+ 0xbcf3f0aa, 0x87ac36e9, 0xe53a7426, 0x01b3d82b, 0x1a9e7449, 0x64ee2d7e, 0xcddbb1da, 0x01c94910,
+ 0xb868bf80, 0x0d26f3fd, 0x9342ede7, 0x04a5c284, 0x636737b6, 0x50f5b616, 0xf24766e3, 0x8eca36c1,
+ 0x136e05db, 0xfef18391, 0xfb887a37, 0xd6e7f7d4, 0xc7fb7dc9, 0x3063fcdf, 0xb6f589de, 0xec2941da,
+ 0x26e46695, 0xb7566419, 0xf654efc5, 0xd08d58b7, 0x48925401, 0xc1bacb7f, 0xe5ff550f, 0xb6083049,
+ 0x5bb5d0e8, 0x87d72e5a, 0xab6a6ee1, 0x223a66ce, 0xc62bf3cd, 0x9e0885f9, 0x68cb3e47, 0x086c010f,
+ 0xa21de820, 0xd18b69de, 0xf3f65777, 0xfa02c3f6, 0x407edac3, 0xcbb3d550, 0x1793084d, 0xb0d70eba,
+ 0x0ab378d5, 0xd951fb0c, 0xded7da56, 0x4124bbe4, 0x94ca0b56, 0x0f5755d1, 0xe0e1e56e, 0x6184b5be,
+ 0x580a249f, 0x94f74bc0, 0xe327888e, 0x9f7b5561, 0xc3dc0280, 0x05687715, 0x646c6bd7, 0x44904db3,
+ 0x66b4f0a3, 0xc0f1648a, 0x697ed5af, 0x49e92ff6, 0x309e374f, 0x2cb6356a, 0x85808573, 0x4991f840,
+ 0x76f0ae02, 0x083be84d, 0x28421c9a, 0x44489406, 0x736e4cb8, 0xc1092910, 0x8bc95fc6, 0x7d869cf4,
+ 0x134f616f, 0x2e77118d, 0xb31b2be1, 0xaa90b472, 0x3ca5d717, 0x7d161bba, 0x9cad9010, 0xaf462ba2,
+ 0x9fe459d2, 0x45d34559, 0xd9f2da13, 0xdbc65487, 0xf3e4f94e, 0x176d486f, 0x097c13ea, 0x631da5c7,
+ 0x445f7382, 0x175683f4, 0xcdc66a97, 0x70be0288, 0xb3cdcf72, 0x6e5dd2f3, 0x20936079, 0x459b80a5,
+ 0xbe60e2db, 0xa9c23101, 0xeba5315c, 0x224e42f2, 0x1c5c1572, 0xf6721b2c, 0x1ad2fff3, 0x8c25404e,
+ 0x324ed72f, 0x4067b7fd, 0x0523138e, 0x5ca3bc78, 0xdc0fd66e, 0x75922283, 0x784d6b17, 0x58ebb16e,
+ 0x44094f85, 0x3f481d87, 0xfcfeae7b, 0x77b5ff76, 0x8c2302bf, 0xaaf47556, 0x5f46b02a, 0x2b092801,
+ 0x3d38f5f7, 0x0ca81f36, 0x52af4a8a, 0x66d5e7c0, 0xdf3b0874, 0x95055110, 0x1b5ad7a8, 0xf61ed5ad,
+ 0x6cf6e479, 0x20758184, 0xd0cefa65, 0x88f7be58, 0x4a046826, 0x0ff6f8f3, 0xa09c7f70, 0x5346aba0,
+ 0x5ce96c28, 0xe176eda3, 0x6bac307f, 0x376829d2, 0x85360fa9, 0x17e3fe2a, 0x24b79767, 0xf5a96b20,
+ 0xd6cd2595, 0x68ff1ebf, 0x7555442c, 0xf19f06be, 0xf9e0659a, 0xeeb9491d, 0x34010718, 0xbb30cab8,
+ 0xe822fe15, 0x88570983, 0x750e6249, 0xda627e55, 0x5e76ffa8, 0xb1534546, 0x6d47de08, 0xefe9e7d4};
+
+static const uint32_t S6[256]={
+ 0xf6fa8f9d, 0x2cac6ce1, 0x4ca34867, 0xe2337f7c, 0x95db08e7, 0x016843b4, 0xeced5cbc, 0x325553ac,
+ 0xbf9f0960, 0xdfa1e2ed, 0x83f0579d, 0x63ed86b9, 0x1ab6a6b8, 0xde5ebe39, 0xf38ff732, 0x8989b138,
+ 0x33f14961, 0xc01937bd, 0xf506c6da, 0xe4625e7e, 0xa308ea99, 0x4e23e33c, 0x79cbd7cc, 0x48a14367,
+ 0xa3149619, 0xfec94bd5, 0xa114174a, 0xeaa01866, 0xa084db2d, 0x09a8486f, 0xa888614a, 0x2900af98,
+ 0x01665991, 0xe1992863, 0xc8f30c60, 0x2e78ef3c, 0xd0d51932, 0xcf0fec14, 0xf7ca07d2, 0xd0a82072,
+ 0xfd41197e, 0x9305a6b0, 0xe86be3da, 0x74bed3cd, 0x372da53c, 0x4c7f4448, 0xdab5d440, 0x6dba0ec3,
+ 0x083919a7, 0x9fbaeed9, 0x49dbcfb0, 0x4e670c53, 0x5c3d9c01, 0x64bdb941, 0x2c0e636a, 0xba7dd9cd,
+ 0xea6f7388, 0xe70bc762, 0x35f29adb, 0x5c4cdd8d, 0xf0d48d8c, 0xb88153e2, 0x08a19866, 0x1ae2eac8,
+ 0x284caf89, 0xaa928223, 0x9334be53, 0x3b3a21bf, 0x16434be3, 0x9aea3906, 0xefe8c36e, 0xf890cdd9,
+ 0x80226dae, 0xc340a4a3, 0xdf7e9c09, 0xa694a807, 0x5b7c5ecc, 0x221db3a6, 0x9a69a02f, 0x68818a54,
+ 0xceb2296f, 0x53c0843a, 0xfe893655, 0x25bfe68a, 0xb4628abc, 0xcf222ebf, 0x25ac6f48, 0xa9a99387,
+ 0x53bddb65, 0xe76ffbe7, 0xe967fd78, 0x0ba93563, 0x8e342bc1, 0xe8a11be9, 0x4980740d, 0xc8087dfc,
+ 0x8de4bf99, 0xa11101a0, 0x7fd37975, 0xda5a26c0, 0xe81f994f, 0x9528cd89, 0xfd339fed, 0xb87834bf,
+ 0x5f04456d, 0x22258698, 0xc9c4c83b, 0x2dc156be, 0x4f628daa, 0x57f55ec5, 0xe2220abe, 0xd2916ebf,
+ 0x4ec75b95, 0x24f2c3c0, 0x42d15d99, 0xcd0d7fa0, 0x7b6e27ff, 0xa8dc8af0, 0x7345c106, 0xf41e232f,
+ 0x35162386, 0xe6ea8926, 0x3333b094, 0x157ec6f2, 0x372b74af, 0x692573e4, 0xe9a9d848, 0xf3160289,
+ 0x3a62ef1d, 0xa787e238, 0xf3a5f676, 0x74364853, 0x20951063, 0x4576698d, 0xb6fad407, 0x592af950,
+ 0x36f73523, 0x4cfb6e87, 0x7da4cec0, 0x6c152daa, 0xcb0396a8, 0xc50dfe5d, 0xfcd707ab, 0x0921c42f,
+ 0x89dff0bb, 0x5fe2be78, 0x448f4f33, 0x754613c9, 0x2b05d08d, 0x48b9d585, 0xdc049441, 0xc8098f9b,
+ 0x7dede786, 0xc39a3373, 0x42410005, 0x6a091751, 0x0ef3c8a6, 0x890072d6, 0x28207682, 0xa9a9f7be,
+ 0xbf32679d, 0xd45b5b75, 0xb353fd00, 0xcbb0e358, 0x830f220a, 0x1f8fb214, 0xd372cf08, 0xcc3c4a13,
+ 0x8cf63166, 0x061c87be, 0x88c98f88, 0x6062e397, 0x47cf8e7a, 0xb6c85283, 0x3cc2acfb, 0x3fc06976,
+ 0x4e8f0252, 0x64d8314d, 0xda3870e3, 0x1e665459, 0xc10908f0, 0x513021a5, 0x6c5b68b7, 0x822f8aa0,
+ 0x3007cd3e, 0x74719eef, 0xdc872681, 0x073340d4, 0x7e432fd9, 0x0c5ec241, 0x8809286c, 0xf592d891,
+ 0x08a930f6, 0x957ef305, 0xb7fbffbd, 0xc266e96f, 0x6fe4ac98, 0xb173ecc0, 0xbc60b42a, 0x953498da,
+ 0xfba1ae12, 0x2d4bd736, 0x0f25faab, 0xa4f3fceb, 0xe2969123, 0x257f0c3d, 0x9348af49, 0x361400bc,
+ 0xe8816f4a, 0x3814f200, 0xa3f94043, 0x9c7a54c2, 0xbc704f57, 0xda41e7f9, 0xc25ad33a, 0x54f4a084,
+ 0xb17f5505, 0x59357cbe, 0xedbd15c8, 0x7f97c5ab, 0xba5ac7b5, 0xb6f6deaf, 0x3a479c3a, 0x5302da25,
+ 0x653d7e6a, 0x54268d49, 0x51a477ea, 0x5017d55b, 0xd7d25d88, 0x44136c76, 0x0404a8c8, 0xb8e5a121,
+ 0xb81a928a, 0x60ed5869, 0x97c55b96, 0xeaec991b, 0x29935913, 0x01fdb7f1, 0x088e8dfa, 0x9ab6f6f5,
+ 0x3b4cbf9f, 0x4a5de3ab, 0xe6051d35, 0xa0e1d855, 0xd36b4cf1, 0xf544edeb, 0xb0e93524, 0xbebb8fbd,
+ 0xa2d762cf, 0x49c92f54, 0x38b5f331, 0x7128a454, 0x48392905, 0xa65b1db8, 0x851c97bd, 0xd675cf2f};
+
+static const uint32_t S7[256]={
+ 0x85e04019, 0x332bf567, 0x662dbfff, 0xcfc65693, 0x2a8d7f6f, 0xab9bc912, 0xde6008a1, 0x2028da1f,
+ 0x0227bce7, 0x4d642916, 0x18fac300, 0x50f18b82, 0x2cb2cb11, 0xb232e75c, 0x4b3695f2, 0xb28707de,
+ 0xa05fbcf6, 0xcd4181e9, 0xe150210c, 0xe24ef1bd, 0xb168c381, 0xfde4e789, 0x5c79b0d8, 0x1e8bfd43,
+ 0x4d495001, 0x38be4341, 0x913cee1d, 0x92a79c3f, 0x089766be, 0xbaeeadf4, 0x1286becf, 0xb6eacb19,
+ 0x2660c200, 0x7565bde4, 0x64241f7a, 0x8248dca9, 0xc3b3ad66, 0x28136086, 0x0bd8dfa8, 0x356d1cf2,
+ 0x107789be, 0xb3b2e9ce, 0x0502aa8f, 0x0bc0351e, 0x166bf52a, 0xeb12ff82, 0xe3486911, 0xd34d7516,
+ 0x4e7b3aff, 0x5f43671b, 0x9cf6e037, 0x4981ac83, 0x334266ce, 0x8c9341b7, 0xd0d854c0, 0xcb3a6c88,
+ 0x47bc2829, 0x4725ba37, 0xa66ad22b, 0x7ad61f1e, 0x0c5cbafa, 0x4437f107, 0xb6e79962, 0x42d2d816,
+ 0x0a961288, 0xe1a5c06e, 0x13749e67, 0x72fc081a, 0xb1d139f7, 0xf9583745, 0xcf19df58, 0xbec3f756,
+ 0xc06eba30, 0x07211b24, 0x45c28829, 0xc95e317f, 0xbc8ec511, 0x38bc46e9, 0xc6e6fa14, 0xbae8584a,
+ 0xad4ebc46, 0x468f508b, 0x7829435f, 0xf124183b, 0x821dba9f, 0xaff60ff4, 0xea2c4e6d, 0x16e39264,
+ 0x92544a8b, 0x009b4fc3, 0xaba68ced, 0x9ac96f78, 0x06a5b79a, 0xb2856e6e, 0x1aec3ca9, 0xbe838688,
+ 0x0e0804e9, 0x55f1be56, 0xe7e5363b, 0xb3a1f25d, 0xf7debb85, 0x61fe033c, 0x16746233, 0x3c034c28,
+ 0xda6d0c74, 0x79aac56c, 0x3ce4e1ad, 0x51f0c802, 0x98f8f35a, 0x1626a49f, 0xeed82b29, 0x1d382fe3,
+ 0x0c4fb99a, 0xbb325778, 0x3ec6d97b, 0x6e77a6a9, 0xcb658b5c, 0xd45230c7, 0x2bd1408b, 0x60c03eb7,
+ 0xb9068d78, 0xa33754f4, 0xf430c87d, 0xc8a71302, 0xb96d8c32, 0xebd4e7be, 0xbe8b9d2d, 0x7979fb06,
+ 0xe7225308, 0x8b75cf77, 0x11ef8da4, 0xe083c858, 0x8d6b786f, 0x5a6317a6, 0xfa5cf7a0, 0x5dda0033,
+ 0xf28ebfb0, 0xf5b9c310, 0xa0eac280, 0x08b9767a, 0xa3d9d2b0, 0x79d34217, 0x021a718d, 0x9ac6336a,
+ 0x2711fd60, 0x438050e3, 0x069908a8, 0x3d7fedc4, 0x826d2bef, 0x4eeb8476, 0x488dcf25, 0x36c9d566,
+ 0x28e74e41, 0xc2610aca, 0x3d49a9cf, 0xbae3b9df, 0xb65f8de6, 0x92aeaf64, 0x3ac7d5e6, 0x9ea80509,
+ 0xf22b017d, 0xa4173f70, 0xdd1e16c3, 0x15e0d7f9, 0x50b1b887, 0x2b9f4fd5, 0x625aba82, 0x6a017962,
+ 0x2ec01b9c, 0x15488aa9, 0xd716e740, 0x40055a2c, 0x93d29a22, 0xe32dbf9a, 0x058745b9, 0x3453dc1e,
+ 0xd699296e, 0x496cff6f, 0x1c9f4986, 0xdfe2ed07, 0xb87242d1, 0x19de7eae, 0x053e561a, 0x15ad6f8c,
+ 0x66626c1c, 0x7154c24c, 0xea082b2a, 0x93eb2939, 0x17dcb0f0, 0x58d4f2ae, 0x9ea294fb, 0x52cf564c,
+ 0x9883fe66, 0x2ec40581, 0x763953c3, 0x01d6692e, 0xd3a0c108, 0xa1e7160e, 0xe4f2dfa6, 0x693ed285,
+ 0x74904698, 0x4c2b0edd, 0x4f757656, 0x5d393378, 0xa132234f, 0x3d321c5d, 0xc3f5e194, 0x4b269301,
+ 0xc79f022f, 0x3c997e7e, 0x5e4f9504, 0x3ffafbbd, 0x76f7ad0e, 0x296693f4, 0x3d1fce6f, 0xc61e45be,
+ 0xd3b5ab34, 0xf72bf9b7, 0x1b0434c0, 0x4e72b567, 0x5592a33d, 0xb5229301, 0xcfd2a87f, 0x60aeb767,
+ 0x1814386b, 0x30bcc33d, 0x38a0c07d, 0xfd1606f2, 0xc363519b, 0x589dd390, 0x5479f8e6, 0x1cb8d647,
+ 0x97fd61a9, 0xea7759f4, 0x2d57539d, 0x569a58cf, 0xe84e63ad, 0x462e1b78, 0x6580f87e, 0xf3817914,
+ 0x91da55f4, 0x40a230f3, 0xd1988f35, 0xb6e318d2, 0x3ffa50bc, 0x3d40f021, 0xc3c0bdae, 0x4958c24c,
+ 0x518f36b2, 0x84b1d370, 0x0fedce83, 0x878ddada, 0xf2a279c7, 0x94e01be8, 0x90716f4b, 0x954b8aa3};
+
+static const uint32_t S8[256]={
+ 0xe216300d, 0xbbddfffc, 0xa7ebdabd, 0x35648095, 0x7789f8b7, 0xe6c1121b, 0x0e241600, 0x052ce8b5,
+ 0x11a9cfb0, 0xe5952f11, 0xece7990a, 0x9386d174, 0x2a42931c, 0x76e38111, 0xb12def3a, 0x37ddddfc,
+ 0xde9adeb1, 0x0a0cc32c, 0xbe197029, 0x84a00940, 0xbb243a0f, 0xb4d137cf, 0xb44e79f0, 0x049eedfd,
+ 0x0b15a15d, 0x480d3168, 0x8bbbde5a, 0x669ded42, 0xc7ece831, 0x3f8f95e7, 0x72df191b, 0x7580330d,
+ 0x94074251, 0x5c7dcdfa, 0xabbe6d63, 0xaa402164, 0xb301d40a, 0x02e7d1ca, 0x53571dae, 0x7a3182a2,
+ 0x12a8ddec, 0xfdaa335d, 0x176f43e8, 0x71fb46d4, 0x38129022, 0xce949ad4, 0xb84769ad, 0x965bd862,
+ 0x82f3d055, 0x66fb9767, 0x15b80b4e, 0x1d5b47a0, 0x4cfde06f, 0xc28ec4b8, 0x57e8726e, 0x647a78fc,
+ 0x99865d44, 0x608bd593, 0x6c200e03, 0x39dc5ff6, 0x5d0b00a3, 0xae63aff2, 0x7e8bd632, 0x70108c0c,
+ 0xbbd35049, 0x2998df04, 0x980cf42a, 0x9b6df491, 0x9e7edd53, 0x06918548, 0x58cb7e07, 0x3b74ef2e,
+ 0x522fffb1, 0xd24708cc, 0x1c7e27cd, 0xa4eb215b, 0x3cf1d2e2, 0x19b47a38, 0x424f7618, 0x35856039,
+ 0x9d17dee7, 0x27eb35e6, 0xc9aff67b, 0x36baf5b8, 0x09c467cd, 0xc18910b1, 0xe11dbf7b, 0x06cd1af8,
+ 0x7170c608, 0x2d5e3354, 0xd4de495a, 0x64c6d006, 0xbcc0c62c, 0x3dd00db3, 0x708f8f34, 0x77d51b42,
+ 0x264f620f, 0x24b8d2bf, 0x15c1b79e, 0x46a52564, 0xf8d7e54e, 0x3e378160, 0x7895cda5, 0x859c15a5,
+ 0xe6459788, 0xc37bc75f, 0xdb07ba0c, 0x0676a3ab, 0x7f229b1e, 0x31842e7b, 0x24259fd7, 0xf8bef472,
+ 0x835ffcb8, 0x6df4c1f2, 0x96f5b195, 0xfd0af0fc, 0xb0fe134c, 0xe2506d3d, 0x4f9b12ea, 0xf215f225,
+ 0xa223736f, 0x9fb4c428, 0x25d04979, 0x34c713f8, 0xc4618187, 0xea7a6e98, 0x7cd16efc, 0x1436876c,
+ 0xf1544107, 0xbedeee14, 0x56e9af27, 0xa04aa441, 0x3cf7c899, 0x92ecbae6, 0xdd67016d, 0x151682eb,
+ 0xa842eedf, 0xfdba60b4, 0xf1907b75, 0x20e3030f, 0x24d8c29e, 0xe139673b, 0xefa63fb8, 0x71873054,
+ 0xb6f2cf3b, 0x9f326442, 0xcb15a4cc, 0xb01a4504, 0xf1e47d8d, 0x844a1be5, 0xbae7dfdc, 0x42cbda70,
+ 0xcd7dae0a, 0x57e85b7a, 0xd53f5af6, 0x20cf4d8c, 0xcea4d428, 0x79d130a4, 0x3486ebfb, 0x33d3cddc,
+ 0x77853b53, 0x37effcb5, 0xc5068778, 0xe580b3e6, 0x4e68b8f4, 0xc5c8b37e, 0x0d809ea2, 0x398feb7c,
+ 0x132a4f94, 0x43b7950e, 0x2fee7d1c, 0x223613bd, 0xdd06caa2, 0x37df932b, 0xc4248289, 0xacf3ebc3,
+ 0x5715f6b7, 0xef3478dd, 0xf267616f, 0xc148cbe4, 0x9052815e, 0x5e410fab, 0xb48a2465, 0x2eda7fa4,
+ 0xe87b40e4, 0xe98ea084, 0x5889e9e1, 0xefd390fc, 0xdd07d35b, 0xdb485694, 0x38d7e5b2, 0x57720101,
+ 0x730edebc, 0x5b643113, 0x94917e4f, 0x503c2fba, 0x646f1282, 0x7523d24a, 0xe0779695, 0xf9c17a8f,
+ 0x7a5b2121, 0xd187b896, 0x29263a4d, 0xba510cdf, 0x81f47c9f, 0xad1163ed, 0xea7b5965, 0x1a00726e,
+ 0x11403092, 0x00da6d77, 0x4a0cdd61, 0xad1f4603, 0x605bdfb0, 0x9eedc364, 0x22ebe6a8, 0xcee7d28a,
+ 0xa0e736a0, 0x5564a6b9, 0x10853209, 0xc7eb8f37, 0x2de705ca, 0x8951570f, 0xdf09822b, 0xbd691a6c,
+ 0xaa12e4f2, 0x87451c0f, 0xe0f6a27a, 0x3ada4819, 0x4cf1764f, 0x0d771c2b, 0x67cdb156, 0x350d8384,
+ 0x5938fa0f, 0x42399ef3, 0x36997b07, 0x0e84093d, 0x4aa93e61, 0x8360d87b, 0x1fa98b0c, 0x1149382c,
+ 0xe97625a5, 0x0614d1b7, 0x0e25244b, 0x0c768347, 0x589e8d82, 0x0d2059d1, 0xa466bb1e, 0xf8da0a82,
+ 0x04f19130, 0xba6e4ec0, 0x99265164, 0x1ee7230d, 0x50b2ad80, 0xeaee6801, 0x8db2a283, 0xea8bf59e};
+
+static void generate_round_keys(int rnds,uint32_t* K, uint32_t* x, uint32_t* z)
+{
+ COMPUTE_Z;
+
+ K[1]=S5[IA(z[2])]^S6[IB(z[2])]^S7[ID(z[1])]^S8[IC(z[1])]^S5[IC(z[0])];
+ K[2]=S5[IC(z[2])]^S6[ID(z[2])]^S7[IB(z[1])]^S8[IA(z[1])]^S6[IC(z[1])];
+ K[3]=S5[IA(z[3])]^S6[IB(z[3])]^S7[ID(z[0])]^S8[IC(z[0])]^S7[IB(z[2])];
+ K[4]=S5[IC(z[3])]^S6[ID(z[3])]^S7[IB(z[0])]^S8[IA(z[0])]^S8[IA(z[3])];
+
+ COMPUTE_X;
+
+ K[5]=S5[ID(x[0])]^S6[IC(x[0])]^S7[IA(x[3])]^S8[IB(x[3])]^S5[IA(x[2])];
+ K[6]=S5[IB(x[0])]^S6[IA(x[0])]^S7[IC(x[3])]^S8[ID(x[3])]^S6[IB(x[3])];
+ K[7]=S5[ID(x[1])]^S6[IC(x[1])]^S7[IA(x[2])]^S8[IB(x[2])]^S7[ID(x[0])];
+ K[8]=S5[IB(x[1])]^S6[IA(x[1])]^S7[IC(x[2])]^S8[ID(x[2])]^S8[ID(x[1])];
+
+ COMPUTE_Z;
+
+ K[9]=S5[ID(z[0])]^S6[IC(z[0])]^S7[IA(z[3])]^S8[IB(z[3])]^S5[IB(z[2])];
+ K[10]=S5[IB(z[0])]^S6[IA(z[0])]^S7[IC(z[3])]^S8[ID(z[3])]^S6[IA(z[3])];
+ K[11]=S5[ID(z[1])]^S6[IC(z[1])]^S7[IA(z[2])]^S8[IB(z[2])]^S7[IC(z[0])];
+ K[12]=S5[IB(z[1])]^S6[IA(z[1])]^S7[IC(z[2])]^S8[ID(z[2])]^S8[IC(z[1])];
+
+ COMPUTE_X;
+
+ if (rnds==16) {
+ K[13]=S5[IA(x[2])]^S6[IB(x[2])]^S7[ID(x[1])]^S8[IC(x[1])]^S5[ID(x[0])];
+ K[14]=S5[IC(x[2])]^S6[ID(x[2])]^S7[IB(x[1])]^S8[IA(x[1])]^S6[ID(x[1])];
+ K[15]=S5[IA(x[3])]^S6[IB(x[3])]^S7[ID(x[0])]^S8[IC(x[0])]^S7[IA(x[2])];
+ K[16]=S5[IC(x[3])]^S6[ID(x[3])]^S7[IB(x[0])]^S8[IA(x[0])]^S8[IB(x[3])];
+ }
+}
+
+static void encipher(AVCAST5* cs,uint8_t* dst,const uint8_t* src)
+{
+ uint32_t r,l,f,I;
+ l=AV_RB32(src);
+ r=AV_RB32(src+4);
+ F1(l,r,1);
+ F2(r,l,2);
+ F3(l,r,3);
+ F1(r,l,4);
+ F2(l,r,5);
+ F3(r,l,6);
+ F1(l,r,7);
+ F2(r,l,8);
+ F3(l,r,9);
+ F1(r,l,10);
+ F2(l,r,11);
+ F3(r,l,12);
+ if (cs->rounds==16) {
+ F1(l,r,13);
+ F2(r,l,14);
+ F3(l,r,15);
+ F1(r,l,16);
+ }
+ AV_WB32(dst,r);
+ AV_WB32(dst+4,l);
+}
+
+static void decipher(AVCAST5* cs,uint8_t* dst,const uint8_t* src)
+{
+ uint32_t f,I,r,l;
+ l=AV_RB32(src);
+ r=AV_RB32(src+4);
+ if (cs->rounds==16) {
+ F1(l,r,16);
+ F3(r,l,15);
+ F2(l,r,14);
+ F1(r,l,13);
+ }
+ F3(l,r,12);
+ F2(r,l,11);
+ F1(l,r,10);
+ F3(r,l,9);
+ F2(l,r,8);
+ F1(r,l,7);
+ F3(l,r,6);
+ F2(r,l,5);
+ F1(l,r,4);
+ F3(r,l,3);
+ F2(l,r,2);
+ F1(r,l,1);
+
+ AV_WB32(dst,r);
+ AV_WB32(dst+4,l);
+
+}
+
+struct AVCAST5 *av_cast5_alloc(void)
+{
+ return av_mallocz(sizeof(struct AVCAST5));
+}
+
+av_cold int av_cast5_init(AVCAST5* cs, const uint8_t *key, int key_bits)
+{
+ uint8_t newKey[16];
+ int i;
+ uint32_t p[4],q[4];
+ if (key_bits%8||key_bits<40||key_bits>128)
+ return -1;
+ memset(newKey,0,sizeof(newKey));
+ memcpy(newKey,key,key_bits>>3);
+
+ cs->rounds = key_bits<=80 ? 12:16;
+ for (i=0;i<4;i++)
+ q[i]=AV_RB32(newKey+(4*i));
+ generate_round_keys(cs->rounds,cs->Km,q,p);
+ generate_round_keys(cs->rounds,cs->Kr,q,p);
+ for (i=0;i<=cs->rounds;i++)
+ cs->Kr[i]=cs->Kr[i]&0x1f;
+ return 0;
+}
+
+void av_cast5_crypt(AVCAST5* cs, uint8_t* dst, const uint8_t* src, int count, int decrypt)
+{
+ while (count--) {
+ if (decrypt){
+ decipher(cs,dst,src);
+ } else {
+ encipher(cs,dst,src);
+ }
+ src=src+8;
+ dst=dst+8;
+ }
+}
+
+#ifdef TEST
+#include<stdio.h>
+#include<stdlib.h>
+#include"log.h"
+
+int main(int argc, char** argv)
+{
+
+ static const uint8_t Key[3][16]={{0x01,0x23,0x45,0x67,0x12,0x34,0x56,0x78,0x23,0x45,0x67,0x89,0x34,0x56,0x78,0x9a},
+ {0x01,0x23,0x45,0x67,0x12,0x34,0x56,0x78,0x23,0x45},
+ {0x01,0x23,0x45,0x67,0x12}};
+ static const uint8_t rpt[8]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef};
+ static const uint8_t rct[3][8]={{0x23,0x8b,0x4f,0xe5,0x84,0x7e,0x44,0xb2},
+ {0xeb,0x6a,0x71,0x1a,0x2c,0x02,0x27,0x1b},
+ {0x7a,0xc8,0x16,0xd1,0x6e,0x9b,0x30,0x2e}};
+ static const uint8_t rct2[2][16]={{0xee,0xa9,0xd0,0xa2,0x49,0xfd,0x3b,0xa6,0xb3,0x43,0x6f,0xb8,0x9d,0x6d,0xca,0x92},
+ {0xb2,0xc9,0x5e,0xb0,0x0c,0x31,0xad,0x71,0x80,0xac,0x05,0xb8,0xe8,0x3d,0x69,0x6e}};
+ static uint8_t rpt2[2][16];
+ int i,j,err=0;
+ static int key_bits[3]={128,80,40};
+ uint8_t temp[8];
+ AVCAST5 *cs;
+ cs=av_cast5_alloc();
+ if (!cs)
+ return 1;
+ for (j=0;j<3;j++){
+
+ av_cast5_init(cs,Key[j],key_bits[j]);
+ av_cast5_crypt(cs,temp,rpt,1,0);
+ for (i=0;i<8;i++){
+ if (rct[j][i]!=temp[i]){
+ av_log(NULL,AV_LOG_ERROR,"%d %02x %02x\n",i,rct[j][i],temp[i]);
+ err=1;
+ }
+ }
+
+ av_cast5_crypt(cs,temp,rct[j],1,1);
+ for (i=0;i<8;i++){
+ if (rpt[i]!=temp[i]){
+ av_log(NULL,AV_LOG_ERROR,"%d %02x %02x\n",i,rpt[i],temp[i]);
+ err=1;
+ }
+ }
+ }
+ memcpy(rpt2[0],Key[0],16);
+ memcpy(rpt2[1],Key[0],16);
+ for (i=0;i<1000000;i++){
+ av_cast5_init(cs,rpt2[1],128);
+ av_cast5_crypt(cs,rpt2[0],rpt2[0],2,0);
+ av_cast5_init(cs,rpt2[0],128);
+ av_cast5_crypt(cs,rpt2[1],rpt2[1],2,0);
+ }
+ for (j=0;j<2;j++){
+ for (i=0;i<16;i++){
+ if (rct2[j][i]!=rpt2[j][i]){
+ av_log(NULL,AV_LOG_ERROR,"%d %02x %02x\n",i,rct2[j][i],rpt2[j][i]);
+ err=1;
+ }
+ }
+ }
+ av_free(cs);
+ return err;
+}
+#endif
--- /dev/null
+/*
+ * An implementation of the CAST128 algorithm as mentioned in RFC2144
+ * Copyright (c) 2014 Supraja Meedinti
+ *
+ * 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 AVUTIL_CAST5_H
+#define AVUTIL_CAST5_H
+
+#include <stdint.h>
+
+
+/**
+ * @file
+ * @brief Public header for libavutil CAST5 algorithm
+ * @defgroup lavu_cast5 CAST5
+ * @ingroup lavu_crypto
+ * @{
+ */
+
+extern const int av_cast5_size;
+
+struct AVCAST5;
+
+/**
+ * Allocate an AVCAST5 context
+ * To free the struct: av_free(ptr)
+ */
+struct AVCAST5 *av_cast5_alloc(void);
+/**
+ * Initialize an AVCAST5 context.
+ *
+ * @param ctx an AVCAST5 context
+ * @param key a key of 5,6,...16 bytes used for encryption/decryption
+ * @param key_bits number of keybits: possible are 40,48,...,128
+ */
+int av_cast5_init(struct AVCAST5 *ctx, const uint8_t *key, int key_bits);
+
+/**
+ * Encrypt or decrypt a buffer using a previously initialized context
+ *
+ * @param ctx an AVCAST5 context
+ * @param dst destination array, can be equal to src
+ * @param src source array, can be equal to dst
+ * @param count number of 8 byte blocks
+ * @param decrypt 0 for encryption, 1 for decryption
+ */
+void av_cast5_crypt(struct AVCAST5 *ctx, uint8_t *dst, const uint8_t *src, int count,int decrypt);
+/**
+ * @}
+ */
+#endif /* AVUTIL_CAST5_H */
#include "dict.h"
#include "internal.h"
#include "mem.h"
+#include "bprint.h"
struct AVDictionary {
int count;
return m ? m->count : 0;
}
-AVDictionaryEntry *av_dict_get(FF_CONST_AVUTIL53 AVDictionary *m, const char *key,
+AVDictionaryEntry *av_dict_get(const AVDictionary *m, const char *key,
const AVDictionaryEntry *prev, int flags)
{
unsigned int i, j;
av_freep(pm);
}
-void av_dict_copy(AVDictionary **dst, FF_CONST_AVUTIL53 AVDictionary *src, int flags)
+void av_dict_copy(AVDictionary **dst, const AVDictionary *src, int flags)
{
AVDictionaryEntry *t = NULL;
while ((t = av_dict_get(src, "", t, AV_DICT_IGNORE_SUFFIX)))
av_dict_set(dst, t->key, t->value, flags);
}
+
+int av_dict_get_string(const AVDictionary *m, char **buffer,
+ const char key_val_sep, const char pairs_sep)
+{
+ AVDictionaryEntry *t = NULL;
+ AVBPrint bprint;
+ int cnt = 0;
+ char special_chars[] = {pairs_sep, key_val_sep, '\0'};
+
+ if (!buffer || pairs_sep == '\0' || key_val_sep == '\0' || pairs_sep == key_val_sep ||
+ pairs_sep == '\\' || key_val_sep == '\\')
+ return AVERROR(EINVAL);
+
+ if (!av_dict_count(m)) {
+ *buffer = av_strdup("");
+ return *buffer ? 0 : AVERROR(ENOMEM);
+ }
+
+ av_bprint_init(&bprint, 64, AV_BPRINT_SIZE_UNLIMITED);
+ while ((t = av_dict_get(m, "", t, AV_DICT_IGNORE_SUFFIX))) {
+ if (cnt++)
+ av_bprint_append_data(&bprint, &pairs_sep, 1);
+ av_bprint_escape(&bprint, t->key, special_chars, AV_ESCAPE_MODE_BACKSLASH, 0);
+ av_bprint_append_data(&bprint, &key_val_sep, 1);
+ av_bprint_escape(&bprint, t->value, special_chars, AV_ESCAPE_MODE_BACKSLASH, 0);
+ }
+ return av_bprint_finalize(&bprint, buffer);
+}
+
+#ifdef TEST
+static void print_dict(const AVDictionary *m)
+{
+ AVDictionaryEntry *t = NULL;
+ while ((t = av_dict_get(m, "", t, AV_DICT_IGNORE_SUFFIX)))
+ printf("%s %s ", t->key, t->value);
+ printf("\n");
+}
+
+static void test_separators(const AVDictionary *m, const char pair, const char val)
+{
+ AVDictionary *dict = NULL;
+ char pairs[] = {pair , '\0'};
+ char vals[] = {val, '\0'};
+
+ char *buffer = NULL;
+ av_dict_copy(&dict, m, 0);
+ print_dict(dict);
+ av_dict_get_string(dict, &buffer, val, pair);
+ printf("%s\n", buffer);
+ av_dict_free(&dict);
+ av_dict_parse_string(&dict, buffer, vals, pairs, 0);
+ av_freep(&buffer);
+ print_dict(dict);
+ av_dict_free(&dict);
+}
+
+int main(void)
+{
+ AVDictionary *dict = NULL;
+ char *buffer = NULL;
+
+ printf("Testing av_dict_get_string() and av_dict_parse_string()\n");
+ av_dict_get_string(dict, &buffer, '=', ',');
+ printf("%s\n", buffer);
+ av_freep(&buffer);
+ av_dict_set(&dict, "aaa", "aaa", 0);
+ av_dict_set(&dict, "b,b", "bbb", 0);
+ av_dict_set(&dict, "c=c", "ccc", 0);
+ av_dict_set(&dict, "ddd", "d,d", 0);
+ av_dict_set(&dict, "eee", "e=e", 0);
+ av_dict_set(&dict, "f,f", "f=f", 0);
+ av_dict_set(&dict, "g=g", "g,g", 0);
+ test_separators(dict, ',', '=');
+ av_dict_free(&dict);
+ av_dict_set(&dict, "aaa", "aaa", 0);
+ av_dict_set(&dict, "bbb", "bbb", 0);
+ av_dict_set(&dict, "ccc", "ccc", 0);
+ av_dict_set(&dict, "\\,=\'\"", "\\,=\'\"", 0);
+ test_separators(dict, '"', '=');
+ test_separators(dict, '\'', '=');
+ test_separators(dict, ',', '"');
+ test_separators(dict, ',', '\'');
+ test_separators(dict, '\'', '"');
+ test_separators(dict, '"', '\'');
+ av_dict_free(&dict);
+
+ return 0;
+}
+#endif
* @param flags a collection of AV_DICT_* flags controlling how the entry is retrieved
* @return found entry or NULL in case no matching entry was found in the dictionary
*/
-AVDictionaryEntry *av_dict_get(FF_CONST_AVUTIL53 AVDictionary *m, const char *key,
+AVDictionaryEntry *av_dict_get(const AVDictionary *m, const char *key,
const AVDictionaryEntry *prev, int flags);
/**
* @param flags flags to use when setting entries in *dst
* @note metadata is read using the AV_DICT_IGNORE_SUFFIX flag
*/
-void av_dict_copy(AVDictionary **dst, FF_CONST_AVUTIL53 AVDictionary *src, int flags);
+void av_dict_copy(AVDictionary **dst, const AVDictionary *src, int flags);
/**
* Free all the memory allocated for an AVDictionary struct
*/
void av_dict_free(AVDictionary **m);
+/**
+ * Get dictionary entries as a string.
+ *
+ * Create a string containing dictionary's entries.
+ * Such string may be passed back to av_dict_parse_string().
+ * @note String is escaped with backslashes ('\').
+ *
+ * @param[in] m dictionary
+ * @param[out] buffer Pointer to buffer that will be allocated with string containg entries.
+ * Buffer must be freed by the caller when is no longer needed.
+ * @param[in] key_val_sep character used to separate key from value
+ * @param[in] pairs_sep character used to separate two pairs from each other
+ * @return >= 0 on success, negative on error
+ * @warning Separators cannot be neither '\\' nor '\0'. They also cannot be the same.
+ */
+int av_dict_get_string(const AVDictionary *m, char **buffer,
+ const char key_val_sep, const char pairs_sep);
+
/**
* @}
*/
};
#define ERROR_TAG(tag) AVERROR_##tag, #tag
+#define AVERROR_INPUT_AND_OUTPUT_CHANGED (AVERROR_INPUT_CHANGED | AVERROR_OUTPUT_CHANGED)
static const struct error_entry error_entries[] = {
{ ERROR_TAG(BSF_NOT_FOUND), "Bitstream filter not found" },
{ ERROR_TAG(BUG), "Internal bug, should not have happened" },
{ ERROR_TAG(EXIT), "Immediate exit requested" },
{ ERROR_TAG(EXTERNAL), "Generic error in an external library" },
{ ERROR_TAG(FILTER_NOT_FOUND), "Filter not found" },
+ { ERROR_TAG(INPUT_CHANGED), "Input changed" },
{ ERROR_TAG(INVALIDDATA), "Invalid data found when processing input" },
{ ERROR_TAG(MUXER_NOT_FOUND), "Muxer not found" },
{ ERROR_TAG(OPTION_NOT_FOUND), "Option not found" },
+ { ERROR_TAG(OUTPUT_CHANGED), "Output changed" },
{ ERROR_TAG(PATCHWELCOME), "Not yet implemented in FFmpeg, patches welcome" },
{ ERROR_TAG(PROTOCOL_NOT_FOUND), "Protocol not found" },
{ ERROR_TAG(STREAM_NOT_FOUND), "Stream not found" },
{ ERROR_TAG(UNKNOWN), "Unknown error occurred" },
{ ERROR_TAG(EXPERIMENTAL), "Experimental feature" },
+ { ERROR_TAG(INPUT_AND_OUTPUT_CHANGED), "Input and output changed" },
+ { ERROR_TAG(HTTP_BAD_REQUEST), "Server returned 400 Bad Request" },
+ { ERROR_TAG(HTTP_UNAUTHORIZED), "Server returned 401 Unauthorized (authorization failed)" },
+ { ERROR_TAG(HTTP_FORBIDDEN), "Server returned 403 Forbidden (access denied)" },
+ { ERROR_TAG(HTTP_NOT_FOUND), "Server returned 404 Not Found" },
+ { ERROR_TAG(HTTP_OTHER_4XX), "Server returned 4XX Client Error, but not one of 40{0,1,3,4}" },
+ { ERROR_TAG(HTTP_SERVER_ERROR), "Server returned 5XX Server Error reply" },
};
int av_strerror(int errnum, char *errbuf, size_t errbuf_size)
#define AVERROR_EXPERIMENTAL (-0x2bb2afa8) ///< Requested feature is flagged experimental. Set strict_std_compliance if you really want to use it.
#define AVERROR_INPUT_CHANGED (-0x636e6701) ///< Input changed between calls. Reconfiguration is required. (can be OR-ed with AVERROR_OUTPUT_CHANGED)
#define AVERROR_OUTPUT_CHANGED (-0x636e6702) ///< Output changed between calls. Reconfiguration is required. (can be OR-ed with AVERROR_INPUT_CHANGED)
+/* HTTP & RTSP errors */
+#define AVERROR_HTTP_BAD_REQUEST FFERRTAG(0xF8,'4','0','0')
+#define AVERROR_HTTP_UNAUTHORIZED FFERRTAG(0xF8,'4','0','1')
+#define AVERROR_HTTP_FORBIDDEN FFERRTAG(0xF8,'4','0','3')
+#define AVERROR_HTTP_NOT_FOUND FFERRTAG(0xF8,'4','0','4')
+#define AVERROR_HTTP_OTHER_4XX FFERRTAG(0xF8,'4','X','X')
+#define AVERROR_HTTP_SERVER_ERROR FFERRTAG(0xF8,'5','X','X')
#define AV_ERROR_MAX_STRING_SIZE 64
f->wndx = f->rndx = 0;
}
-int av_fifo_size(FF_CONST_AVUTIL53 AVFifoBuffer *f)
+int av_fifo_size(const AVFifoBuffer *f)
{
return (uint32_t)(f->wndx - f->rndx);
}
-int av_fifo_space(FF_CONST_AVUTIL53 AVFifoBuffer *f)
+int av_fifo_space(const AVFifoBuffer *f)
{
return f->end - f->buffer - av_fifo_size(f);
}
* @param f AVFifoBuffer to read from
* @return size
*/
-int av_fifo_size(FF_CONST_AVUTIL53 AVFifoBuffer *f);
+int av_fifo_size(const AVFifoBuffer *f);
/**
* Return the amount of space in bytes in the AVFifoBuffer, that is the
* @param f AVFifoBuffer to write into
* @return size
*/
-int av_fifo_space(FF_CONST_AVUTIL53 AVFifoBuffer *f);
+int av_fifo_space(const AVFifoBuffer *f);
/**
* Feed data from an AVFifoBuffer to a user-supplied callback.
* Wrapper to work around the lack of mkstemp() on mingw.
* Also, tries to create file in /tmp first, if possible.
* *prefix can be a character constant; *filename will be allocated internally.
- * @return file descriptor of opened file (or -1 on error)
+ * @return file descriptor of opened file (or negative value corresponding to an
+ * AVERROR code on error)
* and opened file name in **filename.
* @note On very old libcs it is necessary to set a secure umask before
* calling this, av_tempfile() can't call umask itself as it is used in
#include <windows.h>
#include <share.h>
#include <errno.h>
+#include "wchar_filename.h"
static int win32_open(const char *filename_utf8, int oflag, int pmode)
{
int fd;
- int num_chars;
wchar_t *filename_w;
/* convert UTF-8 to wide chars */
- num_chars = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, filename_utf8, -1, NULL, 0);
- if (num_chars <= 0)
- goto fallback;
- filename_w = av_mallocz_array(num_chars, sizeof(wchar_t));
- if (!filename_w) {
- errno = ENOMEM;
+ if (utf8towchar(filename_utf8, &filename_w))
return -1;
- }
- MultiByteToWideChar(CP_UTF8, 0, filename_utf8, -1, filename_w, num_chars);
+ if (!filename_w)
+ goto fallback;
fd = _wsopen(filename_w, oflag, SH_DENYNO, pmode);
av_freep(&filename_w);
#include "config.h"
#include "attributes.h"
#include "float_dsp.h"
+#include "mem.h"
static void vector_fmul_c(float *dst, const float *src0, const float *src1,
int len)
ff_float_dsp_init_mips(fdsp);
}
+av_cold AVFloatDSPContext *avpriv_float_dsp_alloc(int bit_exact)
+{
+ AVFloatDSPContext *ret = av_mallocz(sizeof(AVFloatDSPContext));
+ if (ret)
+ avpriv_float_dsp_init(ret, bit_exact);
+ return ret;
+}
+
+
#ifdef TEST
#include <float.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
+#if HAVE_UNISTD_H
+#include <unistd.h> /* for getopt */
+#endif
+#if !HAVE_GETOPT
+#include "compat/getopt.c"
+#endif
#include "common.h"
#include "cpu.h"
#include "internal.h"
#include "lfg.h"
#include "log.h"
-#include "mem.h"
#include "random_seed.h"
#define LEN 240
int main(int argc, char **argv)
{
- int ret = 0;
+ int ret = 0, seeded = 0;
uint32_t seed;
AVFloatDSPContext fdsp, cdsp;
AVLFG lfg;
LOCAL_ALIGNED(32, double, dbl_src0, [LEN]);
LOCAL_ALIGNED(32, double, dbl_src1, [LEN]);
- if (argc > 2 && !strcmp(argv[1], "-s"))
- seed = strtoul(argv[2], NULL, 10);
- else
+ for (;;) {
+ int arg = getopt(argc, argv, "s:c:");
+ if (arg == -1)
+ break;
+ switch (arg) {
+ case 's':
+ seed = strtoul(optarg, NULL, 10);
+ seeded = 1;
+ break;
+ case 'c':
+ {
+ int cpuflags = av_get_cpu_flags();
+
+ if (av_parse_cpu_caps(&cpuflags, optarg) < 0)
+ return 1;
+
+ av_force_cpu_flags(cpuflags);
+ break;
+ }
+ }
+ }
+ if (!seeded)
seed = av_get_random_seed();
- av_log(NULL, AV_LOG_INFO, "float_dsp-test: random seed %u\n", seed);
+ av_log(NULL, AV_LOG_INFO, "float_dsp-test: %s %u\n", seeded ? "seed" : "random seed", seed);
av_lfg_init(&lfg, seed);
void ff_float_dsp_init_x86(AVFloatDSPContext *fdsp);
void ff_float_dsp_init_mips(AVFloatDSPContext *fdsp);
+/**
+ * Allocate a float DSP context.
+ *
+ * @param strict setting to non-zero avoids using functions which may not be IEEE-754 compliant
+ */
+AVFloatDSPContext *avpriv_float_dsp_alloc(int strict);
+
#endif /* AVUTIL_FLOAT_DSP_H */
* libavutil/motion_vector.h.
*/
AV_FRAME_DATA_MOTION_VECTORS,
+ /**
+ * Recommmends skipping the specified number of samples. This is exported
+ * only if the "skip_manual" AVOption is set in libavcodec.
+ * This has the same format as AV_PKT_DATA_SKIP_SAMPLES.
+ * @code
+ * u32le number of samples to skip from start of this packet
+ * u32le number of samples to skip from end of this packet
+ * u8 reason for start skip
+ * u8 reason for end skip (0=padding silence, 1=convergence)
+ * @endcode
+ */
+ AV_FRAME_DATA_SKIP_SAMPLES,
};
enum AVActiveFormatDescription {
for (i = 0; i < 4; i++)
dst_linesize[i] = FFALIGN(dst_linesize[i], align);
- if ((ret = av_image_fill_pointers(dst_data, pix_fmt, width, NULL, dst_linesize)) < 0)
- return ret;
-
return av_image_fill_pointers(dst_data, pix_fmt, height, (uint8_t *)src, dst_linesize);
}
# define FF_ENABLE_DEPRECATION_WARNINGS
#endif
-#ifndef INT_BIT
-# define INT_BIT (CHAR_BIT * sizeof(int))
-#endif
#define FF_MEMORY_POISON 0x2a
+++ /dev/null
-/*
- * portable IEEE float/double read/write functions
- *
- * Copyright (c) 2005 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
- */
-
-/**
- * @file
- * portable IEEE float/double read/write functions
- */
-
-#include <stdint.h>
-#include "common.h"
-#include "mathematics.h"
-#include "intfloat_readwrite.h"
-#include "version.h"
-
-#if FF_API_INTFLOAT
-double av_int2dbl(int64_t v){
- if((uint64_t)v+v > 0xFFEULL<<52)
- return NAN;
- return ldexp(((v&((1LL<<52)-1)) + (1LL<<52)) * (v>>63|1), (v>>52&0x7FF)-1075);
-}
-
-float av_int2flt(int32_t v){
- if((uint32_t)v+v > 0xFF000000U)
- return NAN;
- return ldexp(((v&0x7FFFFF) + (1<<23)) * (v>>31|1), (v>>23&0xFF)-150);
-}
-
-double av_ext2dbl(const AVExtFloat ext){
- uint64_t m = 0;
- int e, i;
-
- for (i = 0; i < 8; i++)
- m = (m<<8) + ext.mantissa[i];
- e = (((int)ext.exponent[0]&0x7f)<<8) | ext.exponent[1];
- if (e == 0x7fff && m)
- return NAN;
- e -= 16383 + 63; /* In IEEE 80 bits, the whole (i.e. 1.xxxx)
- * mantissa bit is written as opposed to the
- * single and double precision formats. */
- if (ext.exponent[0]&0x80)
- m= -m;
- return ldexp(m, e);
-}
-
-int64_t av_dbl2int(double d){
- int e;
- if ( !d) return 0;
- else if(d-d) return 0x7FF0000000000000LL + ((int64_t)(d<0)<<63) + (d!=d);
- d= frexp(d, &e);
- return (int64_t)(d<0)<<63 | (e+1022LL)<<52 | (int64_t)((fabs(d)-0.5)*(1LL<<53));
-}
-
-int32_t av_flt2int(float d){
- int e;
- if ( !d) return 0;
- else if(d-d) return 0x7F800000 + ((d<0)<<31) + (d!=d);
- d= frexp(d, &e);
- return (d<0)<<31 | (e+126)<<23 | (int64_t)((fabs(d)-0.5)*(1<<24));
-}
-
-AVExtFloat av_dbl2ext(double d){
- struct AVExtFloat ext= {{0}};
- int e, i; double f; uint64_t m;
-
- f = fabs(frexp(d, &e));
- if (f >= 0.5 && f < 1) {
- e += 16382;
- ext.exponent[0] = e>>8;
- ext.exponent[1] = e;
- m = (uint64_t)ldexp(f, 64);
- for (i=0; i < 8; i++)
- ext.mantissa[i] = m>>(56-(i<<3));
- } else if (f != 0.0) {
- ext.exponent[0] = 0x7f; ext.exponent[1] = 0xff;
- if (!isinf(f))
- ext.mantissa[0] = ~0;
- }
- if (d < 0)
- ext.exponent[0] |= 0x80;
- return ext;
-}
-#endif /* FF_API_INTFLOAT */
* @{
*/
-#if HAVE_FAST_CLZ && AV_GCC_VERSION_AT_LEAST(3,4)
-
+#if HAVE_FAST_CLZ
+#if AV_GCC_VERSION_AT_LEAST(3,4)
#ifndef ff_log2
# define ff_log2(x) (31 - __builtin_clz((x)|1))
# ifndef ff_log2_16bit
# define ff_log2_16bit av_log2
# endif
#endif /* ff_log2 */
-
+#elif defined( __INTEL_COMPILER )
+#ifndef ff_log2
+# define ff_log2(x) (_bit_scan_reverse(x|1))
+# ifndef ff_log2_16bit
+# define ff_log2_16bit av_log2
+# endif
+#endif /* ff_log2 */
+#endif
#endif /* AV_GCC_VERSION_AT_LEAST(3,4) */
extern const uint8_t ff_log2_tab[256];
#ifndef ff_log2
#define ff_log2 ff_log2_c
+#if !defined( _MSC_VER )
static av_always_inline av_const int ff_log2_c(unsigned int v)
{
int n = 0;
return n;
}
+#else
+static av_always_inline av_const int ff_log2_c(unsigned int v)
+{
+ unsigned long n;
+ _BitScanReverse(&n, v|1);
+ return n;
+}
+#define ff_log2_16bit av_log2
+#endif
#endif
#ifndef ff_log2_16bit
* @{
*/
-#if HAVE_FAST_CLZ && AV_GCC_VERSION_AT_LEAST(3,4)
+#if HAVE_FAST_CLZ
+#if AV_GCC_VERSION_AT_LEAST(3,4)
#ifndef ff_ctz
#define ff_ctz(v) __builtin_ctz(v)
#endif
+#elif defined( __INTEL_COMPILER )
+#ifndef ff_ctz
+#define ff_ctz(v) _bit_scan_forward(v)
+#endif
+#endif
#endif
#ifndef ff_ctz
#define ff_ctz ff_ctz_c
+#if !defined( _MSC_VER )
static av_always_inline av_const int ff_ctz_c(int v)
{
int c;
return c;
}
+#else
+static av_always_inline av_const int ff_ctz_c( int v )
+{
+ unsigned long c;
+ _BitScanForward(&c, v);
+ return c;
+}
+#endif
#endif
/**
#define exp2f(x) ((float)exp2(x))
#endif /* HAVE_EXP2F */
-#if !HAVE_FMINF
-#undef fminf
-static av_always_inline av_const float fminf(float x, float y)
-{
- //Note, the NaN special case is needed for C spec compliance, it should be
- //optimized away if the users compiler is configured to assume no NaN
- return x > y ? y : (x == x ? x : y);
-}
-#endif
-
#if !HAVE_ISINF
static av_always_inline av_const int isinf(float x)
{
#include "version.h"
#include "lls.h"
-static void update_lls(LLSModel *m, double *var)
+static void update_lls(LLSModel *m, const double *var)
{
int i, j;
}
}
-static double evaluate_lls(LLSModel *m, double *param, int order)
+static double evaluate_lls(LLSModel *m, const double *param, int order)
{
int i;
double out = 0;
* 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 LLSModel *m, const 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);
+ double (*evaluate_lls)(struct LLSModel *m, const double *var, int order);
} LLSModel;
void avpriv_init_lls(LLSModel *m, int indep_count);
av_log(NULL, AV_LOG_ERROR, "decompression incorrect\n");
else
av_log(NULL, AV_LOG_ERROR, "decompression OK\n");
+ fclose(in);
return 0;
}
#endif
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];
AVOpenCLDeviceList device_list;
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 }
};
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)
-{
- 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)
{
cl_int status;
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;
cl_device_type device_type;
*/
int av_opencl_init(AVOpenCLExternalEnv *ext_opencl_env);
-#if FF_API_OLD_OPENCL
-/**
- * Create kernel object in the specified kernel environment.
- *
- * @param env pointer to kernel environment which is filled with
- * 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
*
*/
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.
*
#include "pixdesc.h"
#include "mathematics.h"
#include "samplefmt.h"
+#include "bprint.h"
#include <float.h>
-#if FF_API_FIND_OPT
-//FIXME order them and do a bin search
-const AVOption *av_find_opt(void *v, const char *name, const char *unit, int mask, int flags)
-{
- const AVOption *o = NULL;
-
- while ((o = av_next_option(v, o))) {
- if (!strcmp(o->name, name) && (!unit || (o->unit && !strcmp(o->unit, unit))) && (o->flags & mask) == flags)
- return o;
- }
- return NULL;
-}
-#endif
-
#if FF_API_OLD_AVOPTIONS
-const AVOption *av_next_option(void *obj, const AVOption *last)
+const AVOption *av_next_option(FF_CONST_AVUTIL55 void *obj, const AVOption *last)
{
return av_opt_next(obj, last);
}
#endif
-const AVOption *av_opt_next(void *obj, const AVOption *last)
+const AVOption *av_opt_next(FF_CONST_AVUTIL55 void *obj, const AVOption *last)
{
- AVClass *class = *(AVClass**)obj;
+ const AVClass *class;
+ if (!obj)
+ return NULL;
+ class = *(const AVClass**)obj;
if (!last && class && class->option && class->option[0].name)
return class->option;
if (last && last[1].name)
return NULL;
}
-static int read_number(const AVOption *o, void *dst, double *num, int *den, int64_t *intnum)
+static int read_number(const AVOption *o, const void *dst, double *num, int *den, int64_t *intnum)
{
switch (o->type) {
case AV_OPT_TYPE_FLAGS: *intnum = *(unsigned int*)dst;return 0;
{
int *lendst = (int *)(dst + 1);
uint8_t *bin, *ptr;
- int len = strlen(val);
+ int len;
av_freep(dst);
*lendst = 0;
+ if (!val || !(len = strlen(val)))
+ return 0;
+
if (len & 1)
return AVERROR(EINVAL);
len /= 2;
return AVERROR(EINVAL);
if (!(*out_val = av_malloc(len*2 + 1)))
return AVERROR(ENOMEM);
+ if (!len) {
+ *out_val[0] = '\0';
+ return 0;
+ }
bin = *(uint8_t**)dst;
for (i = 0; i < len; i++)
snprintf(*out_val + i*2, 3, "%02X", bin[i]);
break;
case AV_OPT_TYPE_DURATION:
i64 = *(int64_t *)dst;
- ret = snprintf(buf, sizeof(buf), "%"PRIi64"d:%02d:%02d.%06d",
+ ret = snprintf(buf, sizeof(buf), "%"PRIi64":%02d:%02d.%06d",
i64 / 3600000000, (int)((i64 / 60000000) % 60),
(int)((i64 / 1000000) % 60), (int)(i64 % 1000000));
break;
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]);
+ ret = snprintf(buf, sizeof(buf), "0x%02x%02x%02x%02x",
+ (int)((uint8_t *)dst)[0], (int)((uint8_t *)dst)[1],
+ (int)((uint8_t *)dst)[2], (int)((uint8_t *)dst)[3]);
break;
case AV_OPT_TYPE_CHANNEL_LAYOUT:
i64 = *(int64_t *)dst;
write_number(s, opt, dst, 1, 1, opt->default_val.i64);
break;
case AV_OPT_TYPE_BINARY:
+ set_string_binary(s, opt, opt->default_val.str, dst);
+ break;
case AV_OPT_TYPE_DICT:
/* Cannot set defaults for these types */
break;
return 0;
}
-int av_opt_copy(void *dst, void *src)
+int av_opt_copy(void *dst, FF_CONST_AVUTIL55 void *src)
{
const AVOption *o = NULL;
const AVClass *c;
*(int*)(field_dst8 + 1) = len;
} else if (o->type == AV_OPT_TYPE_CONST) {
// do nothing
+ } else if (o->type == AV_OPT_TYPE_DICT) {
+ AVDictionary **sdict = (AVDictionary **) field_src;
+ AVDictionary **ddict = (AVDictionary **) field_dst;
+ if (*sdict != *ddict)
+ av_dict_free(ddict);
+ *ddict = NULL;
+ av_dict_copy(ddict, *sdict, 0);
+ if (av_dict_count(*sdict) != av_dict_count(*ddict))
+ ret = AVERROR(ENOMEM);
} else {
memcpy(field_dst, field_src, opt_size(o->type));
}
av_freep(rangesp);
}
+int av_opt_is_set_to_default(void *obj, const AVOption *o)
+{
+ int64_t i64;
+ double d, d2;
+ float f;
+ AVRational q;
+ int ret, w, h;
+ char *str;
+ void *dst;
+
+ if (!o || !obj)
+ return AVERROR(EINVAL);
+
+ dst = ((uint8_t*)obj) + o->offset;
+
+ switch (o->type) {
+ case AV_OPT_TYPE_CONST:
+ return 1;
+ case AV_OPT_TYPE_FLAGS:
+ case AV_OPT_TYPE_PIXEL_FMT:
+ case AV_OPT_TYPE_SAMPLE_FMT:
+ case AV_OPT_TYPE_INT:
+ case AV_OPT_TYPE_CHANNEL_LAYOUT:
+ case AV_OPT_TYPE_DURATION:
+ case AV_OPT_TYPE_INT64:
+ read_number(o, dst, NULL, NULL, &i64);
+ return o->default_val.i64 == i64;
+ case AV_OPT_TYPE_STRING:
+ str = *(char **)dst;
+ if (str == o->default_val.str) //2 NULLs
+ return 1;
+ if (!str || !o->default_val.str) //1 NULL
+ return 0;
+ return !strcmp(str, o->default_val.str);
+ case AV_OPT_TYPE_DOUBLE:
+ read_number(o, dst, &d, NULL, NULL);
+ return o->default_val.dbl == d;
+ case AV_OPT_TYPE_FLOAT:
+ read_number(o, dst, &d, NULL, NULL);
+ f = o->default_val.dbl;
+ d2 = f;
+ return d2 == d;
+ case AV_OPT_TYPE_RATIONAL:
+ q = av_d2q(o->default_val.dbl, INT_MAX);
+ return !av_cmp_q(*(AVRational*)dst, q);
+ case AV_OPT_TYPE_BINARY: {
+ struct {
+ uint8_t *data;
+ int size;
+ } tmp = {0};
+ int opt_size = *(int *)((void **)dst + 1);
+ void *opt_ptr = *(void **)dst;
+ if (!opt_ptr && (!o->default_val.str || !strlen(o->default_val.str)))
+ return 1;
+ if (opt_ptr && o->default_val.str && !strlen(o->default_val.str))
+ return 0;
+ if (opt_size != strlen(o->default_val.str) / 2)
+ return 0;
+ ret = set_string_binary(NULL, NULL, o->default_val.str, &tmp.data);
+ if (!ret)
+ ret = !memcmp(opt_ptr, tmp.data, tmp.size);
+ av_free(tmp.data);
+ return ret;
+ }
+ case AV_OPT_TYPE_DICT:
+ /* Binary and dict have not default support yet. Any pointer is not default. */
+ return !!(*(void **)dst);
+ case AV_OPT_TYPE_IMAGE_SIZE:
+ if (!o->default_val.str || !strcmp(o->default_val.str, "none"))
+ w = h = 0;
+ else if ((ret = av_parse_video_size(&w, &h, o->default_val.str)) < 0)
+ return ret;
+ return (w == *(int *)dst) && (h == *((int *)dst+1));
+ case AV_OPT_TYPE_VIDEO_RATE:
+ q = (AVRational){0, 0};
+ if (o->default_val.str)
+ av_parse_video_rate(&q, o->default_val.str);
+ return !av_cmp_q(*(AVRational*)dst, q);
+ case AV_OPT_TYPE_COLOR: {
+ uint8_t color[4] = {0, 0, 0, 0};
+ if (o->default_val.str)
+ av_parse_color(color, o->default_val.str, -1, NULL);
+ return !memcmp(color, dst, sizeof(color));
+ }
+ default:
+ av_log(obj, AV_LOG_WARNING, "Not supported option type: %d, option name: %s\n", o->type, o->name);
+ break;
+ }
+ return AVERROR_PATCHWELCOME;
+}
+
+int av_opt_is_set_to_default_by_name(void *obj, const char *name, int search_flags)
+{
+ const AVOption *o;
+ void *target;
+ if (!obj)
+ return AVERROR(EINVAL);
+ o = av_opt_find2(obj, name, NULL, 0, search_flags, &target);
+ if (!o)
+ return AVERROR_OPTION_NOT_FOUND;
+ return av_opt_is_set_to_default(target, o);
+}
+
+int av_opt_serialize(void *obj, int opt_flags, int flags, char **buffer,
+ const char key_val_sep, const char pairs_sep)
+{
+ const AVOption *o = NULL;
+ uint8_t *buf;
+ AVBPrint bprint;
+ int ret, cnt = 0;
+ const char special_chars[] = {pairs_sep, key_val_sep, '\0'};
+
+ if (pairs_sep == '\0' || key_val_sep == '\0' || pairs_sep == key_val_sep ||
+ pairs_sep == '\\' || key_val_sep == '\\') {
+ av_log(obj, AV_LOG_ERROR, "Invalid separator(s) found.");
+ return AVERROR(EINVAL);
+ }
+
+ if (!obj || !buffer)
+ return AVERROR(EINVAL);
+
+ *buffer = NULL;
+ av_bprint_init(&bprint, 64, AV_BPRINT_SIZE_UNLIMITED);
+
+ while (o = av_opt_next(obj, o)) {
+ if (o->type == AV_OPT_TYPE_CONST)
+ continue;
+ if ((flags & AV_OPT_SERIALIZE_OPT_FLAGS_EXACT) && o->flags != opt_flags)
+ continue;
+ else if (((o->flags & opt_flags) != opt_flags))
+ continue;
+ if (flags & AV_OPT_SERIALIZE_SKIP_DEFAULTS && av_opt_is_set_to_default(obj, o) > 0)
+ continue;
+ if ((ret = av_opt_get(obj, o->name, 0, &buf)) < 0) {
+ av_bprint_finalize(&bprint, NULL);
+ return ret;
+ }
+ if (buf) {
+ if (cnt++)
+ av_bprint_append_data(&bprint, &pairs_sep, 1);
+ av_bprint_escape(&bprint, o->name, special_chars, AV_ESCAPE_MODE_BACKSLASH, 0);
+ av_bprint_append_data(&bprint, &key_val_sep, 1);
+ av_bprint_escape(&bprint, buf, special_chars, AV_ESCAPE_MODE_BACKSLASH, 0);
+ av_freep(&buf);
+ }
+ }
+ av_bprint_finalize(&bprint, buffer);
+ return 0;
+}
+
#ifdef TEST
typedef struct TestContext
int64_t duration;
uint8_t color[4];
int64_t channel_layout;
+ void *binary;
+ int binary_size;
+ void *binary1;
+ int binary_size1;
+ void *binary2;
+ int binary_size2;
+ int64_t num64;
+ float flt;
+ double dbl;
+ char *escape;
} TestContext;
#define OFFSET(x) offsetof(TestContext, x)
static const AVOption test_options[]= {
{"num", "set num", OFFSET(num), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 100 },
-{"toggle", "set toggle", OFFSET(toggle), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1 },
-{"rational", "set rational", OFFSET(rational), AV_OPT_TYPE_RATIONAL, {.dbl = 0}, 0, 10 },
+{"toggle", "set toggle", OFFSET(toggle), AV_OPT_TYPE_INT, {.i64 = 1}, 0, 1 },
+{"rational", "set rational", OFFSET(rational), AV_OPT_TYPE_RATIONAL, {.dbl = 1}, 0, 10 },
{"string", "set string", OFFSET(string), AV_OPT_TYPE_STRING, {.str = "default"}, CHAR_MIN, CHAR_MAX },
-{"flags", "set flags", OFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64 = 0}, 0, INT_MAX, 0, "flags" },
+{"escape", "set escape str", OFFSET(escape), AV_OPT_TYPE_STRING, {.str = "\\=,"}, CHAR_MIN, CHAR_MAX },
+{"flags", "set flags", OFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64 = 1}, 0, INT_MAX, 0, "flags" },
{"cool", "set cool flag ", 0, AV_OPT_TYPE_CONST, {.i64 = TEST_FLAG_COOL}, INT_MIN, INT_MAX, 0, "flags" },
{"lame", "set lame flag ", 0, AV_OPT_TYPE_CONST, {.i64 = TEST_FLAG_LAME}, INT_MIN, INT_MAX, 0, "flags" },
{"mu", "set mu flag ", 0, AV_OPT_TYPE_CONST, {.i64 = TEST_FLAG_MU}, INT_MIN, INT_MAX, 0, "flags" },
-{"size", "set size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE,{0}, 0, 0 },
-{"pix_fmt", "set pixfmt", OFFSET(pix_fmt), AV_OPT_TYPE_PIXEL_FMT, {.i64 = AV_PIX_FMT_NONE}, -1, INT_MAX},
-{"sample_fmt", "set samplefmt", OFFSET(sample_fmt), AV_OPT_TYPE_SAMPLE_FMT, {.i64 = AV_SAMPLE_FMT_NONE}, -1, INT_MAX},
+{"size", "set size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE,{.str="200x300"}, 0, 0 },
+{"pix_fmt", "set pixfmt", OFFSET(pix_fmt), AV_OPT_TYPE_PIXEL_FMT, {.i64 = AV_PIX_FMT_0BGR}, -1, INT_MAX},
+{"sample_fmt", "set samplefmt", OFFSET(sample_fmt), AV_OPT_TYPE_SAMPLE_FMT, {.i64 = AV_SAMPLE_FMT_S16}, -1, INT_MAX},
{"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},
+{"duration", "set duration", OFFSET(duration), AV_OPT_TYPE_DURATION, {.i64 = 1000}, 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},
+{"bin", "set binary value", OFFSET(binary), AV_OPT_TYPE_BINARY, {.str="62696e00"}, 0, 0 },
+{"bin1", "set binary value", OFFSET(binary1), AV_OPT_TYPE_BINARY, {.str=NULL}, 0, 0 },
+{"bin2", "set binary value", OFFSET(binary2), AV_OPT_TYPE_BINARY, {.str=""}, 0, 0 },
+{"num64", "set num 64bit", OFFSET(num64), AV_OPT_TYPE_INT64, {.i64 = 1}, 0, 100 },
+{"flt", "set float", OFFSET(flt), AV_OPT_TYPE_FLOAT, {.dbl = 1.0/3}, 0, 100 },
+{"dbl", "set double", OFFSET(dbl), AV_OPT_TYPE_DOUBLE, {.dbl = 1.0/3}, 0, 100 },
{NULL},
};
{
int i;
+ printf("Testing default values\n");
+ {
+ TestContext test_ctx = { 0 };
+ test_ctx.class = &test_class;
+ av_opt_set_defaults(&test_ctx);
+
+ printf("num=%d\n", test_ctx.num);
+ printf("toggle=%d\n", test_ctx.toggle);
+ printf("string=%s\n", test_ctx.string);
+ printf("escape=%s\n", test_ctx.escape);
+ printf("flags=%d\n", test_ctx.flags);
+ printf("rational=%d/%d\n", test_ctx.rational.num, test_ctx.rational.den);
+ printf("video_rate=%d/%d\n", test_ctx.video_rate.num, test_ctx.video_rate.den);
+ printf("width=%d height=%d\n", test_ctx.w, test_ctx.h);
+ printf("pix_fmt=%s\n", av_get_pix_fmt_name(test_ctx.pix_fmt));
+ printf("sample_fmt=%s\n", av_get_sample_fmt_name(test_ctx.sample_fmt));
+ printf("duration=%"PRId64"\n", test_ctx.duration);
+ printf("color=%d %d %d %d\n", test_ctx.color[0], test_ctx.color[1], test_ctx.color[2], test_ctx.color[3]);
+ printf("channel_layout=%"PRId64"=%"PRId64"\n", test_ctx.channel_layout, (int64_t)AV_CH_LAYOUT_HEXAGONAL);
+ if (test_ctx.binary)
+ printf("binary=%x %x %x %x\n", ((uint8_t*)test_ctx.binary)[0], ((uint8_t*)test_ctx.binary)[1], ((uint8_t*)test_ctx.binary)[2], ((uint8_t*)test_ctx.binary)[3]);
+ printf("binary_size=%d\n", test_ctx.binary_size);
+ printf("num64=%"PRId64"\n", test_ctx.num64);
+ printf("flt=%.6f\n", test_ctx.flt);
+ printf("dbl=%.6f\n", test_ctx.dbl);
+ av_opt_free(&test_ctx);
+ }
+
+ printf("\nTesting av_opt_is_set_to_default()\n");
+ {
+ int ret;
+ TestContext test_ctx = { 0 };
+ const AVOption *o = NULL;
+ test_ctx.class = &test_class;
+
+ av_log_set_level(AV_LOG_QUIET);
+
+ while (o = av_opt_next(&test_ctx, o)) {
+ ret = av_opt_is_set_to_default_by_name(&test_ctx, o->name, 0);
+ printf("name:%10s default:%d error:%s\n", o->name, !!ret, ret < 0 ? av_err2str(ret) : "");
+ }
+ av_opt_set_defaults(&test_ctx);
+ while (o = av_opt_next(&test_ctx, o)) {
+ ret = av_opt_is_set_to_default_by_name(&test_ctx, o->name, 0);
+ printf("name:%10s default:%d error:%s\n", o->name, !!ret, ret < 0 ? av_err2str(ret) : "");
+ }
+ av_opt_free(&test_ctx);
+ }
+
+ printf("\nTest av_opt_serialize()\n");
+ {
+ TestContext test_ctx = { 0 };
+ char *buf;
+ test_ctx.class = &test_class;
+
+ av_log_set_level(AV_LOG_QUIET);
+
+ av_opt_set_defaults(&test_ctx);
+ if (av_opt_serialize(&test_ctx, 0, 0, &buf, '=', ',') >= 0) {
+ printf("%s\n", buf);
+ av_opt_free(&test_ctx);
+ memset(&test_ctx, 0, sizeof(test_ctx));
+ test_ctx.class = &test_class;
+ av_set_options_string(&test_ctx, buf, "=", ",");
+ av_free(buf);
+ if (av_opt_serialize(&test_ctx, 0, 0, &buf, '=', ',') >= 0) {
+ printf("%s\n", buf);
+ av_free(buf);
+ }
+ }
+ av_opt_free(&test_ctx);
+ }
+
printf("\nTesting av_set_options_string()\n");
{
TestContext test_ctx = { 0 };
"color=0x42FF07AA",
"cl=stereo+downmix",
"cl=foo",
+ "bin=boguss",
+ "bin=111",
+ "bin=ffff",
+ "num64=bogus",
+ "num64=44",
+ "num64=44.4",
+ "num64=-1",
+ "num64=101",
+ "flt=bogus",
+ "flt=2",
+ "flt=2.2",
+ "flt=-1",
+ "flt=101",
+ "dbl=bogus",
+ "dbl=2",
+ "dbl=2.2",
+ "dbl=-1",
+ "dbl=101",
};
test_ctx.class = &test_class;
av_opt_set_defaults(&test_ctx);
- av_log_set_level(AV_LOG_DEBUG);
+ av_log_set_level(AV_LOG_QUIET);
for (i=0; i < FF_ARRAY_ELEMS(options); i++) {
av_log(&test_ctx, AV_LOG_DEBUG, "Setting options string '%s'\n", options[i]);
if (av_set_options_string(&test_ctx, options[i], "=", ":") < 0)
- av_log(&test_ctx, AV_LOG_ERROR, "Error setting options string: '%s'\n", options[i]);
- printf("\n");
+ printf("Error '%s'\n", options[i]);
+ else
+ printf("OK '%s'\n", options[i]);
}
av_opt_free(&test_ctx);
}
test_ctx.class = &test_class;
av_opt_set_defaults(&test_ctx);
- av_log_set_level(AV_LOG_DEBUG);
+ av_log_set_level(AV_LOG_QUIET);
for (i=0; i < FF_ARRAY_ELEMS(options); i++) {
av_log(&test_ctx, AV_LOG_DEBUG, "Setting options string '%s'\n", options[i]);
if (av_opt_set_from_string(&test_ctx, options[i], shorthand, "=", ":") < 0)
- av_log(&test_ctx, AV_LOG_ERROR, "Error setting options string: '%s'\n", options[i]);
- printf("\n");
+ printf("Error '%s'\n", options[i]);
+ else
+ printf("OK '%s'\n", options[i]);
}
av_opt_free(&test_ctx);
}
#include "log.h"
#include "pixfmt.h"
#include "samplefmt.h"
+#include "version.h"
/**
* @defgroup avoptions AVOptions
} AVOptionRanges;
-#if FF_API_FIND_OPT
-/**
- * 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).
- *
- * @param[in] obj a pointer to a struct whose first element is a
- * pointer to an AVClass
- * @param[in] name the name of the option to look for
- * @param[in] unit the unit of the option to look for, or any if NULL
- * @return a pointer to the option found, or NULL if no option
- * has been found
- *
- * @deprecated use av_opt_find.
- */
-attribute_deprecated
-const AVOption *av_find_opt(void *obj, const char *name, const char *unit, int mask, int flags);
-#endif
-
#if FF_API_OLD_AVOPTIONS
/**
* Set the field of obj with the given name to value.
AVRational av_get_q(void *obj, const char *name, const AVOption **o_out);
int64_t av_get_int(void *obj, const char *name, const AVOption **o_out);
attribute_deprecated const char *av_get_string(void *obj, const char *name, const AVOption **o_out, char *buf, int buf_len);
-attribute_deprecated const AVOption *av_next_option(void *obj, const AVOption *last);
+attribute_deprecated const AVOption *av_next_option(FF_CONST_AVUTIL55 void *obj, const AVOption *last);
#endif
/**
* @return the number of successfully set key/value pairs, or a negative
* value corresponding to an AVERROR code in case of error:
* AVERROR(EINVAL) if opts cannot be parsed,
- * the error code issued by av_set_string3() if a key/value pair
+ * the error code issued by av_opt_set() if a key/value pair
* cannot be set
*/
int av_set_options_string(void *ctx, const char *opts,
* was found.
*
* @note Options found with AV_OPT_SEARCH_CHILDREN flag may not be settable
- * directly with av_set_string3(). Use special calls which take an options
+ * directly with av_opt_set(). Use special calls which take an options
* AVDictionary (e.g. avformat_open_input()) to set options found with this
* flag.
*/
* or NULL
* @return next AVOption or NULL
*/
-const AVOption *av_opt_next(void *obj, const AVOption *prev);
+const AVOption *av_opt_next(FF_CONST_AVUTIL55 void *obj, const AVOption *prev);
/**
* Iterate over AVOptions-enabled children of obj.
*/
int av_opt_query_ranges(AVOptionRanges **, void *obj, const char *key, int flags);
-int av_opt_copy(void *dest, void *src);
+/**
+ * Copy options from src object into dest object.
+ *
+ * Options that require memory allocation (e.g. string or binary) are malloc'ed in dest object.
+ * Original memory allocated for such options is freed unless both src and dest options points to the same memory.
+ *
+ * @param dest Object to copy from
+ * @param src Object to copy into
+ * @return 0 on success, negative on error
+ */
+int av_opt_copy(void *dest, FF_CONST_AVUTIL55 void *src);
/**
* Get a default list of allowed ranges for the given option.
*/
int av_opt_query_ranges_default(AVOptionRanges **, void *obj, const char *key, int flags);
+/**
+ * Check if given option is set to its default value.
+ *
+ * Options o must belong to the obj. This function must not be called to check child's options state.
+ * @see av_opt_is_set_to_default_by_name().
+ *
+ * @param obj AVClass object to check option on
+ * @param o option to be checked
+ * @return >0 when option is set to its default,
+ * 0 when option is not set its default,
+ * <0 on error
+ */
+int av_opt_is_set_to_default(void *obj, const AVOption *o);
+
+/**
+ * Check if given option is set to its default value.
+ *
+ * @param obj AVClass object to check option on
+ * @param name option name
+ * @param search_flags combination of AV_OPT_SEARCH_*
+ * @return >0 when option is set to its default,
+ * 0 when option is not set its default,
+ * <0 on error
+ */
+int av_opt_is_set_to_default_by_name(void *obj, const char *name, int search_flags);
+
+
+#define AV_OPT_SERIALIZE_SKIP_DEFAULTS 0x00000001 ///< Serialize options that are not set to default values only.
+#define AV_OPT_SERIALIZE_OPT_FLAGS_EXACT 0x00000002 ///< Serialize options that exactly match opt_flags only.
+
+/**
+ * Serialize object's options.
+ *
+ * Create a string containing object's serialized options.
+ * Such string may be passed back to av_opt_set_from_string() in order to restore option values.
+ * A key/value or pairs separator occurring in the serialized value or
+ * name string are escaped through the av_escape() function.
+ *
+ * @param[in] obj AVClass object to serialize
+ * @param[in] opt_flags serialize options with all the specified flags set (AV_OPT_FLAG)
+ * @param[in] flags combination of AV_OPT_SERIALIZE_* flags
+ * @param[out] buffer Pointer to buffer that will be allocated with string containg serialized options.
+ * Buffer must be freed by the caller when is no longer needed.
+ * @param[in] key_val_sep character used to separate key from value
+ * @param[in] pairs_sep character used to separate two pairs from each other
+ * @return >= 0 on success, negative on error
+ * @warning Separators cannot be neither '\\' nor '\0'. They also cannot be the same.
+ */
+int av_opt_serialize(void *obj, int opt_flags, int flags, char **buffer,
+ const char key_val_sep, const char pairs_sep);
/**
* @}
*/
#include "eval.h"
#include "log.h"
#include "random_seed.h"
+#include "time_internal.h"
#include "parseutils.h"
#ifdef TEST
const char *p, *q;
int64_t t;
time_t now;
- struct tm dt = { 0 };
+ struct tm dt = { 0 }, tmbuf;
int today = 0, negative = 0, microseconds = 0;
int i;
static const char * const date_fmt[] = {
int is_utc = *q == 'Z' || *q == 'z';
q += is_utc;
if (today) { /* fill in today's date */
- struct tm dt2 = is_utc ? *gmtime(&now) : *localtime(&now);
+ struct tm dt2 = is_utc ? *gmtime_r(&now, &tmbuf) : *localtime_r(&now, &tmbuf);
dt2.tm_hour = dt.tm_hour;
dt2.tm_min = dt.tm_min;
dt2.tm_sec = dt.tm_sec;
av_free(pca);
}
-void ff_pca_add(PCA *pca, double *v){
+void ff_pca_add(PCA *pca, const double *v){
int i, j;
const int n= pca->n;
struct PCA *ff_pca_init(int n);
void ff_pca_free(struct PCA *pca);
-void ff_pca_add(struct PCA *pca, double *v);
+void ff_pca_add(struct PCA *pca, const double *v);
int ff_pca(struct PCA *pca, double *eigenvector, double *eigenvalue);
#endif /* AVUTIL_PCA_H */
},
};
+static const char *color_range_names[AVCOL_RANGE_NB] = {
+ "unknown", "tv", "pc",
+};
+
+static const char *color_primaries_names[AVCOL_PRI_NB] = {
+ "reserved", "bt709", "unknown", "reserved", "bt470m",
+ "bt470bg", "smpte170m", "smpte240m", "film", "bt2020",
+};
+
+static const char *color_transfer_names[AVCOL_TRC_NB] = {
+ "reserved", "bt709", "unknown", "reserved", "bt470m",
+ "bt470bg", "smpte170m", "smpte240m", "linear", "log100",
+ "log316", "iec61966-2-4", "bt1361e", "iec61966-2-1",
+ "bt2020-10", "bt2020-20",
+};
+
+static const char *color_space_names[AVCOL_SPC_NB] = {
+ "gbr", "bt709", "unknown", "reserved", "fcc",
+ "bt470bg", "smpte170m", "smpte240m", "ycgco",
+ "bt2020nc", "bt2020c",
+};
+
+static const char *chroma_location_names[AVCHROMA_LOC_NB] = {
+ "unspecified", "left", "center", "topleft",
+ "top", "bottomleft", "bottom",
+};
+
FF_DISABLE_DEPRECATION_WARNINGS
static enum AVPixelFormat get_pix_fmt_internal(const char *name)
{
return dst_pix_fmt;
}
+const char *av_color_range_name(enum AVColorRange range)
+{
+ return (unsigned) range < AVCOL_RANGE_NB ?
+ color_range_names[range] : NULL;
+}
+
+const char *av_color_primaries_name(enum AVColorPrimaries primaries)
+{
+ return (unsigned) primaries < AVCOL_PRI_NB ?
+ color_primaries_names[primaries] : NULL;
+}
+
+const char *av_color_transfer_name(enum AVColorTransferCharacteristic transfer)
+{
+ return (unsigned) transfer < AVCOL_TRC_NB ?
+ color_transfer_names[transfer] : NULL;
+}
+
+const char *av_color_space_name(enum AVColorSpace space)
+{
+ return (unsigned) space < AVCOL_SPC_NB ?
+ color_space_names[space] : NULL;
+}
+
+const char *av_chroma_location_name(enum AVChromaLocation location)
+{
+ return (unsigned) location < AVCHROMA_LOC_NB ?
+ chroma_location_names[location] : NULL;
+}
+
#ifdef TEST
int main(void){
}
#endif
+
*/
enum AVPixelFormat av_find_best_pix_fmt_of_2(enum AVPixelFormat dst_pix_fmt1, enum AVPixelFormat dst_pix_fmt2,
enum AVPixelFormat src_pix_fmt, int has_alpha, int *loss_ptr);
+
+/**
+ * @return the name for provided color range or NULL if unknown.
+ */
+const char *av_color_range_name(enum AVColorRange range);
+
+/**
+ * @return the name for provided color primaries or NULL if unknown.
+ */
+const char *av_color_primaries_name(enum AVColorPrimaries primaries);
+
+/**
+ * @return the name for provided color transfer or NULL if unknown.
+ */
+const char *av_color_transfer_name(enum AVColorTransferCharacteristic transfer);
+
+/**
+ * @return the name for provided color space or NULL if unknown.
+ */
+const char *av_color_space_name(enum AVColorSpace space);
+
+/**
+ * @return the name for provided chroma location or NULL if unknown.
+ */
+const char *av_chroma_location_name(enum AVChromaLocation location);
+
#endif /* AVUTIL_PIXDESC_H */
* Chromaticity coordinates of the source primaries.
*/
enum AVColorPrimaries {
+ AVCOL_PRI_RESERVED0 = 0,
AVCOL_PRI_BT709 = 1, ///< also ITU-R BT1361 / IEC 61966-2-4 / SMPTE RP177 Annex B
AVCOL_PRI_UNSPECIFIED = 2,
AVCOL_PRI_RESERVED = 3,
- AVCOL_PRI_BT470M = 4,
+ AVCOL_PRI_BT470M = 4, ///< also FCC Title 47 Code of Federal Regulations 73.682 (a)(20)
+
AVCOL_PRI_BT470BG = 5, ///< also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM
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_FILM = 8, ///< colour filters using Illuminant C
AVCOL_PRI_BT2020 = 9, ///< ITU-R BT2020
AVCOL_PRI_NB, ///< Not part of ABI
};
* Color Transfer Characteristic.
*/
enum AVColorTransferCharacteristic {
+ AVCOL_TRC_RESERVED0 = 0,
AVCOL_TRC_BT709 = 1, ///< also ITU-R BT1361
AVCOL_TRC_UNSPECIFIED = 2,
AVCOL_TRC_RESERVED = 3,
* YUV colorspace type.
*/
enum AVColorSpace {
- AVCOL_SPC_RGB = 0,
+ AVCOL_SPC_RGB = 0, ///< order of coefficients is actually GBR, also IEC 61966-2-1 (sRGB)
AVCOL_SPC_BT709 = 1, ///< also ITU-R BT1361 / IEC 61966-2-4 xvYCC709 / SMPTE RP177 Annex B
AVCOL_SPC_UNSPECIFIED = 2,
AVCOL_SPC_RESERVED = 3,
- AVCOL_SPC_FCC = 4,
+ AVCOL_SPC_FCC = 4, ///< FCC Title 47 Code of Federal Regulations 73.682 (a)(20)
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,
#define WORD_s1 0x14,0x15,0x16,0x17
#define WORD_s2 0x18,0x19,0x1a,0x1b
#define WORD_s3 0x1c,0x1d,0x1e,0x1f
-
#define vcprm(a,b,c,d) (const vector unsigned char){WORD_ ## a, WORD_ ## b, WORD_ ## c, WORD_ ## d}
+#define SWP_W2S0 0x02,0x03,0x00,0x01
+#define SWP_W2S1 0x06,0x07,0x04,0x05
+#define SWP_W2S2 0x0a,0x0b,0x08,0x09
+#define SWP_W2S3 0x0e,0x0f,0x0c,0x0d
+#define SWP_W2Ss0 0x12,0x13,0x10,0x11
+#define SWP_W2Ss1 0x16,0x17,0x14,0x15
+#define SWP_W2Ss2 0x1a,0x1b,0x18,0x19
+#define SWP_W2Ss3 0x1e,0x1f,0x1c,0x1d
+#define vcswapi2s(a,b,c,d) (const vector unsigned char){SWP_W2S ## a, SWP_W2S ## b, SWP_W2S ## c, SWP_W2S ## d}
+
+#define vcswapc() \
+ (const vector unsigned char){0x0f,0x0e,0x0d,0x0c,0x0b,0x0a,0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0x00}
+
// Transpose 8x8 matrix of 16-bit elements (in-place)
#define TRANSPOSE8(a,b,c,d,e,f,g,h) \
} while (0)
+#if HAVE_BIGENDIAN
+#define VEC_LD(offset,b) \
+ vec_perm(vec_ld(offset, b), vec_ld((offset)+15, b), vec_lvsl(offset, b))
+#else
+#define VEC_LD(offset,b) \
+ vec_vsx_ld(offset, b)
+#endif
+
/** @brief loads unaligned vector @a *src with offset @a offset
and returns it */
-static inline vector unsigned char unaligned_load(int offset, uint8_t *src)
+#if HAVE_BIGENDIAN
+static inline vector unsigned char unaligned_load(int offset, const uint8_t *src)
{
register vector unsigned char first = vec_ld(offset, src);
register vector unsigned char second = vec_ld(offset+15, src);
register vector unsigned char mask = vec_lvsl(offset, src);
return vec_perm(first, second, mask);
}
-
-/**
- * loads vector known misalignment
- * @param perm_vec the align permute vector to combine the two loads from lvsl
- */
-static inline vec_u8 load_with_perm_vec(int offset, uint8_t *src, vec_u8 perm_vec)
+static inline vec_u8 load_with_perm_vec(int offset, const uint8_t *src, vec_u8 perm_vec)
{
vec_u8 a = vec_ld(offset, src);
vec_u8 b = vec_ld(offset+15, src);
return vec_perm(a, b, perm_vec);
}
+#else
+#define unaligned_load(a,b) VEC_LD(a,b)
+#define load_with_perm_vec(a,b,c) VEC_LD(a,b)
+#endif
+
-#define vec_unaligned_load(b) \
- vec_perm(vec_ld(0, b), vec_ld(15, b), vec_lvsl(0, b));
+/**
+ * loads vector known misalignment
+ * @param perm_vec the align permute vector to combine the two loads from lvsl
+ */
+
+#define vec_unaligned_load(b) VEC_LD(0, b)
+
+#if HAVE_BIGENDIAN
+#define VEC_MERGEH(a, b) vec_mergeh(a, b)
+#define VEC_MERGEL(a, b) vec_mergel(a, b)
+#else
+#define VEC_MERGEH(a, b) vec_mergeh(b, a)
+#define VEC_MERGEL(a, b) vec_mergel(b, a)
+#endif
+
+#if HAVE_BIGENDIAN
+#define VEC_ST(a,b,c) vec_st(a,b,c)
+#else
+#define VEC_ST(a,b,c) vec_vsx_st(a,b,c)
+#endif
+
+#if HAVE_BIGENDIAN
+#define VEC_SPLAT16(a,b) vec_splat((vec_s16)(a), b)
+#else
+#define VEC_SPLAT16(a,b) vec_splat((vec_s16)(vec_perm(a, a, vcswapi2s(0,1,2,3))), b)
+#endif
+
+#if HAVE_BIGENDIAN
+#define VEC_SLD16(a,b,c) vec_sld(a, b, c)
+#else
+#define VEC_SLD16(a,b,c) vec_sld(b, a, c)
+#endif
#endif /* HAVE_ALTIVEC */
0 : sample_fmt_info[sample_fmt].bits >> 3;
}
-#if FF_API_GET_BITS_PER_SAMPLE_FMT
-int av_get_bits_per_sample_fmt(enum AVSampleFormat sample_fmt)
-{
- return sample_fmt < 0 || sample_fmt >= AV_SAMPLE_FMT_NB ?
- 0 : sample_fmt_info[sample_fmt].bits;
-}
-#endif
-
int av_sample_fmt_is_planar(enum AVSampleFormat sample_fmt)
{
if (sample_fmt < 0 || sample_fmt >= AV_SAMPLE_FMT_NB)
if (linesize)
*linesize = line_size;
-#if FF_API_SAMPLES_UTILS_RETURN_ZERO
- return 0;
-#else
return buf_size;
-#endif
}
int av_samples_alloc(uint8_t **audio_data, int *linesize, int nb_channels,
av_samples_set_silence(audio_data, 0, nb_samples, nb_channels, sample_fmt);
-#if FF_API_SAMPLES_UTILS_RETURN_ZERO
- return 0;
-#else
return size;
-#endif
}
int av_samples_alloc_array_and_samples(uint8_t ***audio_data, int *linesize, int nb_channels,
*/
char *av_get_sample_fmt_string(char *buf, int buf_size, enum AVSampleFormat sample_fmt);
-#if FF_API_GET_BITS_PER_SAMPLE_FMT
-/**
- * @deprecated Use av_get_bytes_per_sample() instead.
- */
-attribute_deprecated
-int av_get_bits_per_sample_fmt(enum AVSampleFormat sample_fmt);
-#endif
-
/**
* Return number of bytes per sample.
*
#include <stdint.h>
#include "common.h"
+#include "avassert.h"
+
#define MIN_EXP -126
#define MAX_EXP 126
#define ONE_BITS 29
static inline av_const SoftFloat av_normalize1_sf(SoftFloat a){
#if 1
- if(a.mant + 0x40000000 < 0){
+ if((int32_t)(a.mant + 0x40000000U) < 0){
a.exp++;
a.mant>>=1;
}
+ av_assert2(a.mant < 0x40000000 && a.mant > -0x40000000);
return a;
#elif 1
int t= a.mant + 0x40000000 < 0;
*/
static inline av_const SoftFloat av_mul_sf(SoftFloat a, SoftFloat b){
a.exp += b.exp;
+ av_assert2((int32_t)((a.mant * (int64_t)b.mant) >> ONE_BITS) == (a.mant * (int64_t)b.mant) >> ONE_BITS);
a.mant = (a.mant * (int64_t)b.mant) >> ONE_BITS;
return av_normalize1_sf(a);
}
static inline av_const SoftFloat av_add_sf(SoftFloat a, SoftFloat b){
int t= a.exp - b.exp;
- if(t<0) return av_normalize1_sf((SoftFloat){b.exp, b.mant + (a.mant >> (-t))});
- else return av_normalize1_sf((SoftFloat){a.exp, a.mant + (b.mant >> t )});
+ if (t <-31) return b;
+ else if (t < 0) return av_normalize1_sf((SoftFloat){b.exp, b.mant + (a.mant >> (-t))});
+ else if (t < 32) return av_normalize1_sf((SoftFloat){a.exp, a.mant + (b.mant >> t )});
+ else return a;
}
static inline av_const SoftFloat av_sub_sf(SoftFloat a, SoftFloat b){
--- /dev/null
+/*
+ * 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
+ */
+
+// This header should only be used to simplify code where
+// threading is optional, not as a generic threading abstraction.
+
+#ifndef AVUTIL_THREAD_H
+#define AVUTIL_THREAD_H
+
+#include "config.h"
+
+#if HAVE_PTHREADS || HAVE_W32THREADS || HAVE_OS2THREADS
+
+#define USE_ATOMICS 0
+
+#if HAVE_PTHREADS
+#include <pthread.h>
+#elif HAVE_OS2THREADS
+#include "compat/os2threads.h"
+#else
+#include "compat/w32pthreads.h"
+#endif
+
+#define AVMutex pthread_mutex_t
+
+#define ff_mutex_init pthread_mutex_init
+#define ff_mutex_lock pthread_mutex_lock
+#define ff_mutex_unlock pthread_mutex_unlock
+#define ff_mutex_destroy pthread_mutex_destroy
+
+#else
+
+#define USE_ATOMICS 1
+
+#define AVMutex char
+
+#define ff_mutex_init(mutex, attr) (0)
+#define ff_mutex_lock(mutex) (0)
+#define ff_mutex_unlock(mutex) (0)
+#define ff_mutex_destroy(mutex) (0)
+
+#endif
+
+#endif /* AVUTIL_THREAD_H */
clock_gettime(CLOCK_MONOTONIC, &ts);
return (int64_t)ts.tv_sec * 1000000 + ts.tv_nsec / 1000;
#else
- return av_gettime();
+ return av_gettime() + 42 * 60 * 60 * INT64_C(1000000);
#endif
}
* Get the current time in microseconds since some unspecified starting point.
* On platforms that support it, the time comes from a monotonic clock
* This property makes this time source ideal for measuring relative time.
- * If a monotonic clock is not available on the targeted platform, the
- * implementation fallsback on using av_gettime().
+ * The returned values may not be monotonic on platforms where a monotonic
+ * clock is not available.
*/
int64_t av_gettime_relative(void);
/*
- * DSP utils
- *
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include "me_cmp.h"
-#include "dsputil.h"
+#ifndef AVUTIL_TIME_INTERNAL_H
+#define AVUTIL_TIME_INTERNAL_H
-#if FF_API_DSPUTIL
+#include <time.h>
+#include "config.h"
-void avpriv_dsputil_init(DSPContext* p, AVCodecContext *avctx)
+#if !HAVE_GMTIME_R && !defined(gmtime_r)
+static inline struct tm *gmtime_r(const time_t* clock, struct tm *result)
{
- MECmpContext mecc;
-
- ff_me_cmp_init(&mecc, avctx);
-#define COPY(name) memcpy(&p->name, &mecc.name, sizeof(p->name))
- COPY(sum_abs_dctelem);
- COPY(sad);
- COPY(sse);
- COPY(hadamard8_diff);
- COPY(dct_sad);
- COPY(quant_psnr);
- COPY(bit);
- COPY(rd);
- COPY(vsad);
- COPY(vsse);
- COPY(nsse);
- COPY(w53);
- COPY(w97);
- COPY(dct_max);
- COPY(dct264_sad);
- COPY(me_pre_cmp);
- COPY(me_cmp);
- COPY(me_sub_cmp);
- COPY(mb_cmp);
- COPY(ildct_cmp);
- COPY(frame_skip_cmp);
- COPY(pix_abs);
+ struct tm *ptr = gmtime(clock);
+ if (!ptr)
+ return NULL;
+ *result = *ptr;
+ return result;
}
+#endif
+#if !HAVE_LOCALTIME_R && !defined(localtime_r)
+static inline struct tm *localtime_r(const time_t* clock, struct tm *result)
+{
+ struct tm *ptr = localtime(clock);
+ if (!ptr)
+ return NULL;
+ *result = *ptr;
+ return result;
+}
#endif
+
+#endif /* AVUTIL_TIME_INTERNAL_H */
*/
#define LIBAVUTIL_VERSION_MAJOR 54
-#define LIBAVUTIL_VERSION_MINOR 7
+#define LIBAVUTIL_VERSION_MINOR 15
#define LIBAVUTIL_VERSION_MICRO 100
#define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \
* @{
*/
-#ifndef FF_API_GET_BITS_PER_SAMPLE_FMT
-#define FF_API_GET_BITS_PER_SAMPLE_FMT (LIBAVUTIL_VERSION_MAJOR < 54)
-#endif
-#ifndef FF_API_FIND_OPT
-#define FF_API_FIND_OPT (LIBAVUTIL_VERSION_MAJOR < 54)
-#endif
#ifndef FF_API_OLD_AVOPTIONS
#define FF_API_OLD_AVOPTIONS (LIBAVUTIL_VERSION_MAJOR < 55)
#endif
#ifndef FF_API_CPU_FLAG_MMX2
#define FF_API_CPU_FLAG_MMX2 (LIBAVUTIL_VERSION_MAJOR < 55)
#endif
-#ifndef FF_API_SAMPLES_UTILS_RETURN_ZERO
-#define FF_API_SAMPLES_UTILS_RETURN_ZERO (LIBAVUTIL_VERSION_MAJOR < 54)
-#endif
#ifndef FF_API_LLS_PRIVATE
#define FF_API_LLS_PRIVATE (LIBAVUTIL_VERSION_MAJOR < 55)
#endif
-#ifndef FF_API_LLS1
-#define FF_API_LLS1 (LIBAVUTIL_VERSION_MAJOR < 54)
-#endif
#ifndef FF_API_AVFRAME_LAVC
#define FF_API_AVFRAME_LAVC (LIBAVUTIL_VERSION_MAJOR < 55)
#endif
#ifndef FF_API_GET_CHANNEL_LAYOUT_COMPAT
#define FF_API_GET_CHANNEL_LAYOUT_COMPAT (LIBAVUTIL_VERSION_MAJOR < 55)
#endif
-#ifndef FF_API_OLD_OPENCL
-#define FF_API_OLD_OPENCL (LIBAVUTIL_VERSION_MAJOR < 54)
-#endif
#ifndef FF_API_XVMC
#define FF_API_XVMC (LIBAVUTIL_VERSION_MAJOR < 55)
#endif
-#ifndef FF_API_INTFLOAT
-#define FF_API_INTFLOAT (LIBAVUTIL_VERSION_MAJOR < 54)
-#endif
#ifndef FF_API_OPT_TYPE_METADATA
#define FF_API_OPT_TYPE_METADATA (LIBAVUTIL_VERSION_MAJOR < 55)
#endif
-
-#ifndef FF_CONST_AVUTIL53
-#if LIBAVUTIL_VERSION_MAJOR >= 53
-#define FF_CONST_AVUTIL53 const
+#ifndef FF_CONST_AVUTIL55
+#if LIBAVUTIL_VERSION_MAJOR >= 55
+#define FF_CONST_AVUTIL55 const
#else
-#define FF_CONST_AVUTIL53
+#define FF_CONST_AVUTIL55
#endif
#endif
--- /dev/null
+/*
+ * 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 AVUTIL_WCHAR_FILENAME_H
+#define AVUTIL_WCHAR_FILENAME_H
+
+#if defined(_WIN32) && !defined(__MINGW32CE__)
+#include <windows.h>
+#include "mem.h"
+
+static inline int utf8towchar(const char *filename_utf8, wchar_t **filename_w)
+{
+ int num_chars;
+ num_chars = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, filename_utf8, -1, NULL, 0);
+ if (num_chars <= 0) {
+ *filename_w = NULL;
+ return 0;
+ }
+ *filename_w = (wchar_t *)av_mallocz_array(num_chars, sizeof(wchar_t));
+ if (!*filename_w) {
+ errno = ENOMEM;
+ return -1;
+ }
+ MultiByteToWideChar(CP_UTF8, 0, filename_utf8, -1, *filename_w, num_chars);
+ return 0;
+}
+#endif
+
+#endif /* AVUTIL_WCHAR_FILENAME_H */
#include "libavutil/lls.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(LLSModel *m, const double *var);
+void ff_update_lls_avx(LLSModel *m, const double *var);
+double ff_evaluate_lls_sse2(LLSModel *m, const double *var, int order);
av_cold void ff_init_lls_x86(LLSModel *m)
{
%endif
%endmacro
+%macro CLIPUB 3 ;(dst, min, max)
+ pmaxub %1, %2
+ pminub %1, %3
+%endmacro
+
%macro CLIPW 3 ;(dst, min, max)
pmaxsw %1, %2
pminsw %1, %3
{"tn", "tmpnoise", 1, 7, 8, TEMP_NOISE_FILTER},
{"fq", "forcequant", 1, 0, 0, FORCE_QUANT},
{"be", "bitexact", 1, 0, 0, BITEXACT},
+ {"vi", "visualize", 1, 0, 0, VISUALIZE},
{NULL, NULL,0,0,0,0} //End Marker
};
#if ARCH_X86 && HAVE_INLINE_ASM
-static inline void prefetchnta(void *p)
+static inline void prefetchnta(const void *p)
{
__asm__ volatile( "prefetchnta (%0)\n\t"
: : "r" (p)
);
}
-static inline void prefetcht0(void *p)
+static inline void prefetcht0(const void *p)
{
__asm__ volatile( "prefetcht0 (%0)\n\t"
: : "r" (p)
);
}
-static inline void prefetcht1(void *p)
+static inline void prefetcht1(const void *p)
{
__asm__ volatile( "prefetcht1 (%0)\n\t"
: : "r" (p)
);
}
-static inline void prefetcht2(void *p)
+static inline void prefetcht2(const void *p)
{
__asm__ volatile( "prefetcht2 (%0)\n\t"
: : "r" (p)
const int dcThreshold= dcOffset*2 + 1;
for(y=0; y<BLOCK_SIZE; y++){
- if(((unsigned)(src[0] - src[1] + dcOffset)) < dcThreshold) numEq++;
- if(((unsigned)(src[1] - src[2] + dcOffset)) < dcThreshold) numEq++;
- if(((unsigned)(src[2] - src[3] + dcOffset)) < dcThreshold) numEq++;
- if(((unsigned)(src[3] - src[4] + dcOffset)) < dcThreshold) numEq++;
- if(((unsigned)(src[4] - src[5] + dcOffset)) < dcThreshold) numEq++;
- if(((unsigned)(src[5] - src[6] + dcOffset)) < dcThreshold) numEq++;
- if(((unsigned)(src[6] - src[7] + dcOffset)) < dcThreshold) numEq++;
+ numEq += ((unsigned)(src[0] - src[1] + dcOffset)) < dcThreshold;
+ numEq += ((unsigned)(src[1] - src[2] + dcOffset)) < dcThreshold;
+ numEq += ((unsigned)(src[2] - src[3] + dcOffset)) < dcThreshold;
+ numEq += ((unsigned)(src[3] - src[4] + dcOffset)) < dcThreshold;
+ numEq += ((unsigned)(src[4] - src[5] + dcOffset)) < dcThreshold;
+ numEq += ((unsigned)(src[5] - src[6] + dcOffset)) < dcThreshold;
+ numEq += ((unsigned)(src[6] - src[7] + dcOffset)) < dcThreshold;
src+= stride;
}
return numEq > c->ppMode.flatnessThreshold;
src+= stride*4; // src points to begin of the 8x8 Block
for(y=0; y<BLOCK_SIZE-1; y++){
- if(((unsigned)(src[0] - src[0+stride] + dcOffset)) < dcThreshold) numEq++;
- if(((unsigned)(src[1] - src[1+stride] + dcOffset)) < dcThreshold) numEq++;
- if(((unsigned)(src[2] - src[2+stride] + dcOffset)) < dcThreshold) numEq++;
- if(((unsigned)(src[3] - src[3+stride] + dcOffset)) < dcThreshold) numEq++;
- if(((unsigned)(src[4] - src[4+stride] + dcOffset)) < dcThreshold) numEq++;
- if(((unsigned)(src[5] - src[5+stride] + dcOffset)) < dcThreshold) numEq++;
- if(((unsigned)(src[6] - src[6+stride] + dcOffset)) < dcThreshold) numEq++;
- if(((unsigned)(src[7] - src[7+stride] + dcOffset)) < dcThreshold) numEq++;
+ numEq += ((unsigned)(src[0] - src[0+stride] + dcOffset)) < dcThreshold;
+ numEq += ((unsigned)(src[1] - src[1+stride] + dcOffset)) < dcThreshold;
+ numEq += ((unsigned)(src[2] - src[2+stride] + dcOffset)) < dcThreshold;
+ numEq += ((unsigned)(src[3] - src[3+stride] + dcOffset)) < dcThreshold;
+ numEq += ((unsigned)(src[4] - src[4+stride] + dcOffset)) < dcThreshold;
+ numEq += ((unsigned)(src[5] - src[5+stride] + dcOffset)) < dcThreshold;
+ numEq += ((unsigned)(src[6] - src[6+stride] + dcOffset)) < dcThreshold;
+ numEq += ((unsigned)(src[7] - src[7+stride] + dcOffset)) < dcThreshold;
src+= stride;
}
return numEq > c->ppMode.flatnessThreshold;
static inline int horizClassify_C(const uint8_t src[], int stride, const PPContext *c)
{
if( isHorizDC_C(src, stride, c) ){
- if( isHorizMinMaxOk_C(src, stride, c->QP) )
- return 1;
- else
- return 0;
+ return isHorizMinMaxOk_C(src, stride, c->QP);
}else{
return 2;
}
static inline int vertClassify_C(const uint8_t src[], int stride, const PPContext *c)
{
if( isVertDC_C(src, stride, c) ){
- if( isVertMinMaxOk_C(src, stride, c->QP) )
- return 1;
- else
- return 0;
+ return isVertMinMaxOk_C(src, stride, c->QP);
}else{
return 2;
}
* accurate deblock filter
*/
static av_always_inline void do_a_deblock_C(uint8_t *src, int step,
- int stride, const PPContext *c)
+ int stride, const PPContext *c, int mode)
{
int y;
const int QP= c->QP;
for(y=0; y<8; y++){
int numEq= 0;
- if(((unsigned)(src[-1*step] - src[0*step] + dcOffset)) < dcThreshold) numEq++;
- if(((unsigned)(src[ 0*step] - src[1*step] + dcOffset)) < dcThreshold) numEq++;
- if(((unsigned)(src[ 1*step] - src[2*step] + dcOffset)) < dcThreshold) numEq++;
- if(((unsigned)(src[ 2*step] - src[3*step] + dcOffset)) < dcThreshold) numEq++;
- if(((unsigned)(src[ 3*step] - src[4*step] + dcOffset)) < dcThreshold) numEq++;
- if(((unsigned)(src[ 4*step] - src[5*step] + dcOffset)) < dcThreshold) numEq++;
- if(((unsigned)(src[ 5*step] - src[6*step] + dcOffset)) < dcThreshold) numEq++;
- if(((unsigned)(src[ 6*step] - src[7*step] + dcOffset)) < dcThreshold) numEq++;
- if(((unsigned)(src[ 7*step] - src[8*step] + dcOffset)) < dcThreshold) numEq++;
+ numEq += ((unsigned)(src[-1*step] - src[0*step] + dcOffset)) < dcThreshold;
+ numEq += ((unsigned)(src[ 0*step] - src[1*step] + dcOffset)) < dcThreshold;
+ numEq += ((unsigned)(src[ 1*step] - src[2*step] + dcOffset)) < dcThreshold;
+ numEq += ((unsigned)(src[ 2*step] - src[3*step] + dcOffset)) < dcThreshold;
+ numEq += ((unsigned)(src[ 3*step] - src[4*step] + dcOffset)) < dcThreshold;
+ numEq += ((unsigned)(src[ 4*step] - src[5*step] + dcOffset)) < dcThreshold;
+ numEq += ((unsigned)(src[ 5*step] - src[6*step] + dcOffset)) < dcThreshold;
+ numEq += ((unsigned)(src[ 6*step] - src[7*step] + dcOffset)) < dcThreshold;
+ numEq += ((unsigned)(src[ 7*step] - src[8*step] + dcOffset)) < dcThreshold;
if(numEq > c->ppMode.flatnessThreshold){
int min, max, x;
sums[8] = sums[7] - src[3*step] + last;
sums[9] = sums[8] - src[4*step] + last;
+ if (mode & VISUALIZE) {
+ src[0*step] =
+ src[1*step] =
+ src[2*step] =
+ src[3*step] =
+ src[4*step] =
+ src[5*step] =
+ src[6*step] =
+ src[7*step] = 128;
+ }
src[0*step]= (sums[0] + sums[2] + 2*src[0*step])>>4;
src[1*step]= (sums[1] + sums[3] + 2*src[1*step])>>4;
src[2*step]= (sums[2] + sums[4] + 2*src[2*step])>>4;
d = FFMAX(d, q);
}
+ if ((mode & VISUALIZE) && d) {
+ d= (d < 0) ? 32 : -32;
+ src[3*step]= av_clip_uint8(src[3*step] - d);
+ src[4*step]= av_clip_uint8(src[4*step] + d);
+ d = 0;
+ }
+
src[3*step]-= d;
src[4*step]+= d;
}
av_log(NULL, AV_LOG_DEBUG, "pp: %s\n", name);
for(;;){
- char *filterName;
+ const char *filterName;
int q= 1000000; //PP_QUALITY_MAX;
int chrom=-1;
int luma=-1;
- char *option;
- char *options[OPTIONS_ARRAY_SIZE];
+ const char *option;
+ const char *options[OPTIONS_ARRAY_SIZE];
int i;
int filterNameOk=0;
int numOfUnknownOptions=0;
int enable=1; //does the user want us to enabled or disabled the filter
+ char *tokstate;
- filterToken= strtok(p, filterDelimiters);
+ filterToken= av_strtok(p, filterDelimiters, &tokstate);
if(!filterToken) break;
p+= strlen(filterToken) + 1; // p points to next filterToken
- filterName= strtok(filterToken, optionDelimiters);
+ filterName= av_strtok(filterToken, optionDelimiters, &tokstate);
if (!filterName) {
ppMode->error++;
break;
}
for(;;){ //for all options
- option= strtok(NULL, optionDelimiters);
+ option= av_strtok(NULL, optionDelimiters, &tokstate);
if(!option) break;
av_log(NULL, AV_LOG_DEBUG, "pp: option: %s\n", option);
av_free(mode);
}
-static void reallocAlign(void **p, int alignment, int size){
+static void reallocAlign(void **p, int size){
av_free(*p);
*p= av_mallocz(size);
}
c->stride= stride;
c->qpStride= qpStride;
- reallocAlign((void **)&c->tempDst, 8, stride*24+32);
- reallocAlign((void **)&c->tempSrc, 8, stride*24);
- reallocAlign((void **)&c->tempBlocks, 8, 2*16*8);
- reallocAlign((void **)&c->yHistogram, 8, 256*sizeof(uint64_t));
+ reallocAlign((void **)&c->tempDst, stride*24+32);
+ reallocAlign((void **)&c->tempSrc, stride*24);
+ reallocAlign((void **)&c->tempBlocks, 2*16*8);
+ reallocAlign((void **)&c->yHistogram, 256*sizeof(uint64_t));
for(i=0; i<256; i++)
c->yHistogram[i]= width*height/64*15/256;
for(i=0; i<3; i++){
//Note: The +17*1024 is just there so I do not have to worry about r/w over the end.
- reallocAlign((void **)&c->tempBlurred[i], 8, stride*mbHeight*16 + 17*1024);
- reallocAlign((void **)&c->tempBlurredPast[i], 8, 256*((height+7)&(~7))/2 + 17*1024);//FIXME size
+ reallocAlign((void **)&c->tempBlurred[i], stride*mbHeight*16 + 17*1024);
+ reallocAlign((void **)&c->tempBlurredPast[i], 256*((height+7)&(~7))/2 + 17*1024);//FIXME size
}
- reallocAlign((void **)&c->deintTemp, 8, 2*width+32);
- reallocAlign((void **)&c->nonBQPTable, 8, qpStride*mbHeight*sizeof(QP_STORE_T));
- reallocAlign((void **)&c->stdQPTable, 8, qpStride*mbHeight*sizeof(QP_STORE_T));
- reallocAlign((void **)&c->forcedQPTable, 8, mbWidth*sizeof(QP_STORE_T));
+ reallocAlign((void **)&c->deintTemp, 2*width+32);
+ reallocAlign((void **)&c->nonBQPTable, qpStride*mbHeight*sizeof(QP_STORE_T));
+ reallocAlign((void **)&c->stdQPTable, qpStride*mbHeight*sizeof(QP_STORE_T));
+ reallocAlign((void **)&c->forcedQPTable, mbWidth*sizeof(QP_STORE_T));
}
static const char * context_to_name(void * ptr) {
PPContext *c = (PPContext*)vc;
int i;
- for(i=0; i<3; i++) av_free(c->tempBlurred[i]);
- for(i=0; i<3; i++) av_free(c->tempBlurredPast[i]);
+ for(i=0; i<FF_ARRAY_ELEMS(c->tempBlurred); i++)
+ av_free(c->tempBlurred[i]);
+ for(i=0; i<FF_ARRAY_ELEMS(c->tempBlurredPast); i++)
+ av_free(c->tempBlurredPast[i]);
av_free(c->tempBlocks);
av_free(c->yHistogram);
{
int mbWidth = (width+15)>>4;
int mbHeight= (height+15)>>4;
- PPMode *mode = (PPMode*)vm;
- PPContext *c = (PPContext*)vc;
+ PPMode *mode = vm;
+ PPContext *c = vc;
int minStride= FFMAX(FFABS(srcStride[0]), FFABS(dstStride[0]));
int absQPStride = FFABS(QPStride);
postProcess(src[0], srcStride[0], dst[0], dstStride[0],
width, height, QP_store, QPStride, 0, mode, c);
+ if (!(src[1] && src[2] && dst[1] && dst[2]))
+ return;
+
width = (width )>>c->hChromaSubSample;
height = (height)>>c->vChromaSubSample;
#define PP_FORMAT_422 (0x00000001|PP_FORMAT)
#define PP_FORMAT_411 (0x00000002|PP_FORMAT)
#define PP_FORMAT_444 (0x00000000|PP_FORMAT)
+#define PP_FORMAT_440 (0x00000010|PP_FORMAT)
#define PP_PICT_TYPE_QP2 0x00000010 ///< MPEG2 style QScale
#define TEMP_NOISE_FILTER 0x100000
#define FORCE_QUANT 0x200000
#define BITEXACT 0x1000000
+#define VISUALIZE 0x2000000
//use if you want a faster postprocessing code
//cannot differentiate between chroma & luma filters (both on or both off)
//filters on
//#define COMPILE_TIME_MODE 0x77
-#define CLIP av_clip_uint8
-
/**
* Postprocessing filter.
*/
/**
* Check if the middle 8x8 Block in the given 8x16 block is flat
*/
-static inline int RENAME(vertClassify)(uint8_t src[], int stride, PPContext *c){
+static inline int RENAME(vertClassify)(const uint8_t src[], int stride, PPContext *c){
int numEq= 0, dcOk;
src+= stride*4; // src points to begin of the 8x8 Block
__asm__ volatile(
int x;
src+= stride*3;
for(x=0; x<8; x++){
- src[stride*3] = CLIP((-src[0] + 9*src[stride*2] + 9*src[stride*4] - src[stride*6])>>4);
- src[stride*5] = CLIP((-src[stride*2] + 9*src[stride*4] + 9*src[stride*6] - src[stride*8])>>4);
- src[stride*7] = CLIP((-src[stride*4] + 9*src[stride*6] + 9*src[stride*8] - src[stride*10])>>4);
- src[stride*9] = CLIP((-src[stride*6] + 9*src[stride*8] + 9*src[stride*10] - src[stride*12])>>4);
+ src[stride*3] = av_clip_uint8((-src[0] + 9*src[stride*2] + 9*src[stride*4] - src[stride*6])>>4);
+ src[stride*5] = av_clip_uint8((-src[stride*2] + 9*src[stride*4] + 9*src[stride*6] - src[stride*8])>>4);
+ src[stride*7] = av_clip_uint8((-src[stride*4] + 9*src[stride*6] + 9*src[stride*8] - src[stride*10])>>4);
+ src[stride*9] = av_clip_uint8((-src[stride*6] + 9*src[stride*8] + 9*src[stride*10] - src[stride*12])>>4);
src++;
}
#endif //TEMPLATE_PP_SSE2 || TEMPLATE_PP_MMXEXT || TEMPLATE_PP_3DNOW
int t1= tmp[x];
int t2= src[stride*1];
- src[stride*1]= CLIP((-t1 + 4*src[stride*0] + 2*t2 + 4*src[stride*2] - src[stride*3] + 4)>>3);
+ src[stride*1]= av_clip_uint8((-t1 + 4*src[stride*0] + 2*t2 + 4*src[stride*2] - src[stride*3] + 4)>>3);
t1= src[stride*4];
- src[stride*3]= CLIP((-t2 + 4*src[stride*2] + 2*t1 + 4*src[stride*4] - src[stride*5] + 4)>>3);
+ src[stride*3]= av_clip_uint8((-t2 + 4*src[stride*2] + 2*t1 + 4*src[stride*4] - src[stride*5] + 4)>>3);
t2= src[stride*6];
- src[stride*5]= CLIP((-t1 + 4*src[stride*4] + 2*t2 + 4*src[stride*6] - src[stride*7] + 4)>>3);
+ src[stride*5]= av_clip_uint8((-t1 + 4*src[stride*4] + 2*t2 + 4*src[stride*6] - src[stride*7] + 4)>>3);
t1= src[stride*8];
- src[stride*7]= CLIP((-t2 + 4*src[stride*6] + 2*t1 + 4*src[stride*8] - src[stride*9] + 4)>>3);
+ src[stride*7]= av_clip_uint8((-t2 + 4*src[stride*6] + 2*t1 + 4*src[stride*8] - src[stride*9] + 4)>>3);
tmp[x]= t1;
src++;
int t2= tmp2[x];
int t3= src[0];
- src[stride*0]= CLIP((-(t1 + src[stride*2]) + 2*(t2 + src[stride*1]) + 6*t3 + 4)>>3);
+ src[stride*0]= av_clip_uint8((-(t1 + src[stride*2]) + 2*(t2 + src[stride*1]) + 6*t3 + 4)>>3);
t1= src[stride*1];
- src[stride*1]= CLIP((-(t2 + src[stride*3]) + 2*(t3 + src[stride*2]) + 6*t1 + 4)>>3);
+ src[stride*1]= av_clip_uint8((-(t2 + src[stride*3]) + 2*(t3 + src[stride*2]) + 6*t1 + 4)>>3);
t2= src[stride*2];
- src[stride*2]= CLIP((-(t3 + src[stride*4]) + 2*(t1 + src[stride*3]) + 6*t2 + 4)>>3);
+ src[stride*2]= av_clip_uint8((-(t3 + src[stride*4]) + 2*(t1 + src[stride*3]) + 6*t2 + 4)>>3);
t3= src[stride*3];
- src[stride*3]= CLIP((-(t1 + src[stride*5]) + 2*(t2 + src[stride*4]) + 6*t3 + 4)>>3);
+ src[stride*3]= av_clip_uint8((-(t1 + src[stride*5]) + 2*(t2 + src[stride*4]) + 6*t3 + 4)>>3);
t1= src[stride*4];
- src[stride*4]= CLIP((-(t2 + src[stride*6]) + 2*(t3 + src[stride*5]) + 6*t1 + 4)>>3);
+ src[stride*4]= av_clip_uint8((-(t2 + src[stride*6]) + 2*(t3 + src[stride*5]) + 6*t1 + 4)>>3);
t2= src[stride*5];
- src[stride*5]= CLIP((-(t3 + src[stride*7]) + 2*(t1 + src[stride*6]) + 6*t2 + 4)>>3);
+ src[stride*5]= av_clip_uint8((-(t3 + src[stride*7]) + 2*(t1 + src[stride*6]) + 6*t2 + 4)>>3);
t3= src[stride*6];
- src[stride*6]= CLIP((-(t1 + src[stride*8]) + 2*(t2 + src[stride*7]) + 6*t3 + 4)>>3);
+ src[stride*6]= av_clip_uint8((-(t1 + src[stride*8]) + 2*(t2 + src[stride*7]) + 6*t3 + 4)>>3);
t1= src[stride*7];
- src[stride*7]= CLIP((-(t2 + src[stride*9]) + 2*(t3 + src[stride*8]) + 6*t1 + 4)>>3);
+ src[stride*7]= av_clip_uint8((-(t2 + src[stride*9]) + 2*(t3 + src[stride*8]) + 6*t1 + 4)>>3);
tmp[x]= t3;
tmp2[x]= t1;
/**
* Transpose and shift the given 8x8 Block into dst1 and dst2.
*/
-static inline void RENAME(transpose1)(uint8_t *dst1, uint8_t *dst2, uint8_t *src, int srcStride)
+static inline void RENAME(transpose1)(uint8_t *dst1, uint8_t *dst2, const uint8_t *src, int srcStride)
{
__asm__(
"lea (%0, %1), %%"REG_a" \n\t"
/**
* Transpose the given 8x8 block.
*/
-static inline void RENAME(transpose2)(uint8_t *dst, int dstStride, uint8_t *src)
+static inline void RENAME(transpose2)(uint8_t *dst, int dstStride, const uint8_t *src)
{
__asm__(
"lea (%0, %1), %%"REG_a" \n\t"
#if !TEMPLATE_PP_ALTIVEC
static inline void RENAME(tempNoiseReducer)(uint8_t *src, int stride,
- uint8_t *tempBlurred, uint32_t *tempBlurredPast, int *maxNoise)
+ uint8_t *tempBlurred, uint32_t *tempBlurredPast, const int *maxNoise)
{
// to save a register (FIXME do this outside of the loops)
tempBlurredPast[127]= maxNoise[0];
/**
* accurate deblock filter
*/
-static av_always_inline void RENAME(do_a_deblock)(uint8_t *src, int step, int stride, PPContext *c){
+static av_always_inline void RENAME(do_a_deblock)(uint8_t *src, int step, int stride, const PPContext *c, int mode){
int64_t dc_mask, eq_mask, both_masks;
int64_t sums[10*8*2];
src+= step*3; // src points to begin of the 8x8 Block
uint8_t * const tempDst= (dstStride > 0 ? c.tempDst : c.tempDst - 23*dstStride) + 32;
//const int mbWidth= isColor ? (width+7)>>3 : (width+15)>>4;
+ if (mode & VISUALIZE){
+ if(!(mode & (V_A_DEBLOCK | H_A_DEBLOCK)) || TEMPLATE_PP_MMX) {
+ av_log(c2, AV_LOG_WARNING, "Visualization is currently only supported with the accurate deblock filter without SIMD\n");
+ }
+ }
+
#if TEMPLATE_PP_MMX
for(i=0; i<57; i++){
int offset= ((i*c.ppMode.baseDcDiff)>>8) + 1;
else if(t==2)
RENAME(doVertDefFilter)(dstBlock, stride, &c);
}else if(mode & V_A_DEBLOCK){
- RENAME(do_a_deblock)(dstBlock, stride, 1, &c);
+ RENAME(do_a_deblock)(dstBlock, stride, 1, &c, mode);
}
}
else if(t==2)
RENAME(doVertDefFilter)(tempBlock1, 16, &c);
}else if(mode & H_A_DEBLOCK){
- RENAME(do_a_deblock)(tempBlock1, 16, 1, &c);
+ RENAME(do_a_deblock)(tempBlock1, 16, 1, &c, mode);
}
RENAME(transpose2)(dstBlock-4, dstStride, tempBlock1 + 4*16);
RENAME(doHorizDefFilter)(dstBlock-4, stride, &c);
#endif
}else if(mode & H_A_DEBLOCK){
- RENAME(do_a_deblock)(dstBlock-8, 1, stride, &c);
+ RENAME(do_a_deblock)(dstBlock-8, 1, stride, &c, mode);
}
#endif //TEMPLATE_PP_MMX
if(mode & DERING){
#include "libavutil/avutil.h"
#define LIBPOSTPROC_VERSION_MAJOR 53
-#define LIBPOSTPROC_VERSION_MINOR 0
+#define LIBPOSTPROC_VERSION_MINOR 3
#define LIBPOSTPROC_VERSION_MICRO 100
#define LIBPOSTPROC_VERSION_INT AV_VERSION_INT(LIBPOSTPROC_VERSION_MAJOR, \
//FIXME put things below under ifdefs so we do not waste space for cases no codec will need
CONV_FUNC(AV_SAMPLE_FMT_U8 , uint8_t, AV_SAMPLE_FMT_U8 , *(const uint8_t*)pi)
-CONV_FUNC(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_U8 , (*(const uint8_t*)pi - 0x80)<<8)
-CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_U8 , (*(const uint8_t*)pi - 0x80)<<24)
+CONV_FUNC(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_U8 , (*(const uint8_t*)pi - 0x80U)<<8)
+CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_U8 , (*(const uint8_t*)pi - 0x80U)<<24)
CONV_FUNC(AV_SAMPLE_FMT_FLT, float , AV_SAMPLE_FMT_U8 , (*(const uint8_t*)pi - 0x80)*(1.0f/ (1<<7)))
CONV_FUNC(AV_SAMPLE_FMT_DBL, double , AV_SAMPLE_FMT_U8 , (*(const uint8_t*)pi - 0x80)*(1.0 / (1<<7)))
CONV_FUNC(AV_SAMPLE_FMT_U8 , uint8_t, AV_SAMPLE_FMT_S16, (*(const int16_t*)pi>>8) + 0x80)
res = num - *out_sz;
*out_idx = c->filter_length + (c->index >> c->phase_shift);
- *out_sz = 1 + c->filter_length * 2 - *out_idx;
+ *out_sz = FFMAX(*out_sz + c->filter_length,
+ 1 + c->filter_length * 2) - *out_idx;
c->index &= c->phase_mask;
- av_assert1(res > 0);
- return res;
+ return FFMAX(res, 0);
}
struct Resampler const swri_resampler={
border = s->resampler->invert_initial_buffer(s->resample, &s->in_buffer,
&in, in_count, &s->in_buffer_index, &s->in_buffer_count);
- if (border == INT_MAX) return 0;
- else if (border < 0) return border;
- else if (border) { buf_set(&in, &in, border); in_count -= border; s->resample_in_constraint = 0; }
+ if (border == INT_MAX) {
+ return 0;
+ } else if (border < 0) {
+ return border;
+ } else if (border) {
+ buf_set(&in, &in, border);
+ in_count -= border;
+ s->resample_in_constraint = 0;
+ }
do{
int ret, size, consumed;
continue;
}
- if(s->drop_output || !out_arg)
- return 0;
+ av_assert0(s->drop_output);
+ return 0;
}
if(!in_arg){
}
int swr_drop_output(struct SwrContext *s, int count){
+ const uint8_t *tmp_arg[SWR_CH_MAX];
s->drop_output += count;
if(s->drop_output <= 0)
return 0;
av_log(s, AV_LOG_VERBOSE, "discarding %d audio samples\n", count);
- return swr_convert(s, NULL, s->drop_output, NULL, 0);
+ return swr_convert(s, NULL, s->drop_output, tmp_arg, 0);
}
int swr_inject_silence(struct SwrContext *s, int count){
mov%3 m4, [srcq+src4q]
mov%3 m5, [srcq+src5q]
%7 x,x,x,x,m7,x
-%if cpuflag(sse4)
+%if cpuflag(sse)
SBUTTERFLYPS 0, 1, 6
SBUTTERFLYPS 2, 3, 6
SBUTTERFLYPS 4, 5, 6
+%if cpuflag(avx)
blendps m6, m4, m0, 1100b
+%else
+ movaps m6, m4
+ shufps m4, m0, q3210
+ SWAP 4,6
+%endif
movlhps m0, m2
movhlps m4, m2
+%if cpuflag(avx)
blendps m2, m5, m1, 1100b
+%else
+ movaps m2, m5
+ shufps m5, m1, q3210
+ SWAP 2,5
+%endif
movlhps m1, m3
movhlps m5, m3
mulps %1, %5
mulps %2, %5
cvtps2dq %6, %1
- cmpnltps %1, %5
+ cmpps %1, %1, %5, 5
paddd %1, %6
cvtps2dq %6, %2
- cmpnltps %2, %5
+ cmpps %2, %2, %5, 5
paddd %2, %6
%endmacro
PACK_6CH float, float, u, 2, 2, NOP_N, NOP_N
PACK_6CH float, float, a, 2, 2, NOP_N, NOP_N
+INIT_XMM sse
+PACK_6CH float, float, u, 2, 2, NOP_N, NOP_N
+PACK_6CH float, float, a, 2, 2, NOP_N, NOP_N
+
INIT_XMM sse2
CONV int32, int16, u, 2, 1, INT16_TO_INT32_N, NOP_N
CONV int32, int16, a, 2, 1, INT16_TO_INT32_N, NOP_N
UNPACK_2CH int16, float, u, 1, 2, FLOAT_TO_INT16_N, FLOAT_TO_INT16_INIT
UNPACK_2CH int16, float, a, 1, 2, FLOAT_TO_INT16_N, FLOAT_TO_INT16_INIT
+PACK_6CH float, int32, u, 2, 2, INT32_TO_FLOAT_N, INT32_TO_FLOAT_INIT
+PACK_6CH float, int32, a, 2, 2, INT32_TO_FLOAT_N, INT32_TO_FLOAT_INIT
+PACK_6CH int32, float, u, 2, 2, FLOAT_TO_INT32_N, FLOAT_TO_INT32_INIT
+PACK_6CH int32, float, a, 2, 2, FLOAT_TO_INT32_N, FLOAT_TO_INT32_INIT
INIT_XMM ssse3
UNPACK_2CH int16, int16, u, 1, 1, NOP_N, NOP_N
UNPACK_2CH float, int16, u, 2, 1, INT16_TO_FLOAT_N, INT16_TO_FLOAT_INIT
UNPACK_2CH float, int16, a, 2, 1, INT16_TO_FLOAT_N, INT16_TO_FLOAT_INIT
-INIT_XMM sse4
-PACK_6CH float, float, u, 2, 2, NOP_N, NOP_N
-PACK_6CH float, float, a, 2, 2, NOP_N, NOP_N
-
-PACK_6CH float, int32, u, 2, 2, INT32_TO_FLOAT_N, INT32_TO_FLOAT_INIT
-PACK_6CH float, int32, a, 2, 2, INT32_TO_FLOAT_N, INT32_TO_FLOAT_INIT
-PACK_6CH int32, float, u, 2, 2, FLOAT_TO_INT32_N, FLOAT_TO_INT32_INIT
-PACK_6CH int32, float, a, 2, 2, FLOAT_TO_INT32_N, FLOAT_TO_INT32_INIT
-
%if HAVE_AVX_EXTERNAL
INIT_XMM avx
PACK_6CH float, float, u, 2, 2, NOP_N, NOP_N
CONV float, int32, u, 2, 2, INT32_TO_FLOAT_N, INT32_TO_FLOAT_INIT
CONV float, int32, a, 2, 2, INT32_TO_FLOAT_N, INT32_TO_FLOAT_INIT
%endif
+
+%if HAVE_AVX2_EXTERNAL
+INIT_YMM avx2
+CONV int32, float, u, 2, 2, FLOAT_TO_INT32_N, FLOAT_TO_INT32_INIT
+CONV int32, float, a, 2, 2, FLOAT_TO_INT32_N, FLOAT_TO_INT32_INIT
+%endif
#define PROTO(pre, in, out, cap) void ff ## pre ## in## _to_ ##out## _a_ ##cap(uint8_t **dst, const uint8_t **src, int len);
#define PROTO2(pre, out, cap) PROTO(pre, int16, out, cap) PROTO(pre, int32, out, cap) PROTO(pre, float, out, cap)
#define PROTO3(pre, cap) PROTO2(pre, int16, cap) PROTO2(pre, int32, cap) PROTO2(pre, float, cap)
-#define PROTO4(pre) PROTO3(pre, mmx) PROTO3(pre, sse) PROTO3(pre, sse2) PROTO3(pre, ssse3) PROTO3(pre, sse4) PROTO3(pre, avx)
+#define PROTO4(pre) PROTO3(pre, mmx) PROTO3(pre, sse) PROTO3(pre, sse2) PROTO3(pre, ssse3) PROTO3(pre, sse4) PROTO3(pre, avx) PROTO3(pre, avx2)
PROTO4(_)
PROTO4(_pack_2ch_)
PROTO4(_pack_6ch_)
ac->simd_f = ff_pack_6ch_float_to_float_a_mmx;
}
}
-
+ if(EXTERNAL_SSE(mm_flags)) {
+ if(channels == 6) {
+ if( out_fmt == AV_SAMPLE_FMT_FLT && in_fmt == AV_SAMPLE_FMT_FLTP || out_fmt == AV_SAMPLE_FMT_S32 && in_fmt == AV_SAMPLE_FMT_S32P)
+ ac->simd_f = ff_pack_6ch_float_to_float_a_sse;
+ }
+ }
if(EXTERNAL_SSE2(mm_flags)) {
if( out_fmt == AV_SAMPLE_FMT_FLT && in_fmt == AV_SAMPLE_FMT_S32 || out_fmt == AV_SAMPLE_FMT_FLTP && in_fmt == AV_SAMPLE_FMT_S32P)
ac->simd_f = ff_int32_to_float_a_sse2;
if( out_fmt == AV_SAMPLE_FMT_S16P && in_fmt == AV_SAMPLE_FMT_FLT)
ac->simd_f = ff_unpack_2ch_float_to_int16_a_sse2;
}
+ if(channels == 6) {
+ if( out_fmt == AV_SAMPLE_FMT_FLT && in_fmt == AV_SAMPLE_FMT_S32P)
+ ac->simd_f = ff_pack_6ch_int32_to_float_a_sse2;
+ if( out_fmt == AV_SAMPLE_FMT_S32 && in_fmt == AV_SAMPLE_FMT_FLTP)
+ ac->simd_f = ff_pack_6ch_float_to_int32_a_sse2;
+ }
}
if(EXTERNAL_SSSE3(mm_flags)) {
if(channels == 2) {
ac->simd_f = ff_unpack_2ch_int16_to_float_a_ssse3;
}
}
- if(EXTERNAL_SSE4(mm_flags)) {
- if(channels == 6) {
- if( out_fmt == AV_SAMPLE_FMT_FLT && in_fmt == AV_SAMPLE_FMT_FLTP || out_fmt == AV_SAMPLE_FMT_S32 && in_fmt == AV_SAMPLE_FMT_S32P)
- ac->simd_f = ff_pack_6ch_float_to_float_a_sse4;
- if( out_fmt == AV_SAMPLE_FMT_FLT && in_fmt == AV_SAMPLE_FMT_S32P)
- ac->simd_f = ff_pack_6ch_int32_to_float_a_sse4;
- if( out_fmt == AV_SAMPLE_FMT_S32 && in_fmt == AV_SAMPLE_FMT_FLTP)
- ac->simd_f = ff_pack_6ch_float_to_int32_a_sse4;
- }
- }
if(EXTERNAL_AVX(mm_flags)) {
if( out_fmt == AV_SAMPLE_FMT_FLT && in_fmt == AV_SAMPLE_FMT_S32 || out_fmt == AV_SAMPLE_FMT_FLTP && in_fmt == AV_SAMPLE_FMT_S32P)
ac->simd_f = ff_int32_to_float_a_avx;
ac->simd_f = ff_pack_6ch_float_to_int32_a_avx;
}
}
+ if(EXTERNAL_AVX2(mm_flags)) {
+ if( out_fmt == AV_SAMPLE_FMT_S32 && in_fmt == AV_SAMPLE_FMT_FLT || out_fmt == AV_SAMPLE_FMT_S32P && in_fmt == AV_SAMPLE_FMT_FLTP)
+ ac->simd_f = ff_float_to_int32_a_avx2;
+ }
}
#include "libavutil/attributes.h"
#include "libavutil/cpu.h"
#include "yuv2rgb_altivec.h"
+#include "libavutil/ppc/util_altivec.h"
#if HAVE_ALTIVEC
#define vzero vec_splat_s32(0)
-#define yuv2planeX_8(d1, d2, l1, src, x, perm, filter) do { \
- vector signed short l2 = vec_ld(((x) << 1) + 16, src); \
- vector signed short ls = vec_perm(l1, l2, perm); \
- vector signed int i1 = vec_mule(filter, ls); \
- vector signed int i2 = vec_mulo(filter, ls); \
- vector signed int vf1 = vec_mergeh(i1, i2); \
- vector signed int vf2 = vec_mergel(i1, i2); \
- d1 = vec_add(d1, vf1); \
- d2 = vec_add(d2, vf2); \
- l1 = l2; \
+#if HAVE_BIGENDIAN
+#define GET_LS(a,b,c,s) {\
+ vector signed short l2 = vec_ld(((b) << 1) + 16, s);\
+ ls = vec_perm(a, l2, c);\
+ a = l2;\
+ }
+#define GET_VF(a, b, c,d) {\
+ a = vec_mergeh(c, d);\
+ b = vec_mergel(c, d);\
+ }
+#else
+#define GET_LS(a,b,c,s) {\
+ ls = a;\
+ a = vec_vsx_ld(((b) << 1) + 16, s);\
+ }
+#define GET_VF(a, b, c, d) {\
+ a = vec_mergel(d, c);\
+ b = vec_mergeh(d, c);\
+ }
+#endif
+
+#define yuv2planeX_8(d1, d2, l1, src, x, perm, filter) do {\
+ vector signed short ls;\
+ GET_LS(l1, x, perm, src);\
+ vector signed int i1 = vec_mule(filter, ls);\
+ vector signed int i2 = vec_mulo(filter, ls);\
+ vector signed int vf1, vf2;\
+ GET_VF(vf1, vf2, i1, i2);\
+ d1 = vec_add(d1, vf1);\
+ d2 = vec_add(d2, vf2);\
} while (0)
+#if HAVE_BIGENDIAN
+#define LOAD_FILTER(vf,f) {\
+ vector unsigned char perm0 = vec_lvsl(joffset, f);\
+ vf = vec_ld(joffset, f);\
+ vf = vec_perm(vf, vf, perm0);\
+}
+#define LOAD_L1(ll1,s,p){\
+ p = vec_lvsl(xoffset, s);\
+ ll1 = vec_ld(xoffset, s);\
+}
+#else
+#define LOAD_FILTER(vf,f) {\
+ vf = vec_vsx_ld(joffset, f);\
+}
+#define LOAD_L1(ll1,s,p){\
+ ll1 = vec_vsx_ld(xoffset, s);\
+}
+#endif
+
static void yuv2planeX_16_altivec(const int16_t *filter, int filterSize,
const int16_t **src, uint8_t *dest,
const uint8_t *dither, int offset, int x)
vo4 = vec_ld(48, val);
for (j = 0; j < filterSize; j++) {
- vector signed short l1, vLumFilter = vec_ld(j << 1, filter);
- vector unsigned char perm, perm0 = vec_lvsl(j << 1, filter);
- vLumFilter = vec_perm(vLumFilter, vLumFilter, perm0);
- vLumFilter = vec_splat(vLumFilter, 0); // lumFilter[j] is loaded 8 times in vLumFilter
-
- perm = vec_lvsl(x << 1, src[j]);
- l1 = vec_ld(x << 1, src[j]);
-
+ unsigned int joffset=j<<1;
+ unsigned int xoffset=x<<1;
+ vector unsigned char perm;
+ vector signed short l1,vLumFilter;
+ LOAD_FILTER(vLumFilter,filter);
+ vLumFilter = vec_splat(vLumFilter, 0);
+ LOAD_L1(l1,src[j],perm);
yuv2planeX_8(vo1, vo2, l1, src[j], x, perm, vLumFilter);
yuv2planeX_8(vo3, vo4, l1, src[j], x + 8, perm, vLumFilter);
}
vs1 = vec_packsu(vo1, vo2);
vs2 = vec_packsu(vo3, vo4);
vf = vec_packsu(vs1, vs2);
- vec_st(vf, 0, dest);
+ VEC_ST(vf, 0, dest);
}
+
static inline void yuv2planeX_u(const int16_t *filter, int filterSize,
const int16_t **src, uint8_t *dest, int dstW,
const uint8_t *dither, int offset, int x)
yuv2planeX_u(filter, filterSize, src, dest, dstW, dither, offset, i);
}
+#if HAVE_BIGENDIAN
+// The 3 above is 2 (filterSize == 4) + 1 (sizeof(short) == 2).
+
+// The neat trick: We only care for half the elements,
+// high or low depending on (i<<3)%16 (it's 0 or 8 here),
+// and we're going to use vec_mule, so we choose
+// carefully how to "unpack" the elements into the even slots.
+#define GET_VF4(a, vf, f) {\
+ vf = vec_ld(a<< 3, f);\
+ if ((a << 3) % 16)\
+ vf = vec_mergel(vf, (vector signed short)vzero);\
+ else\
+ vf = vec_mergeh(vf, (vector signed short)vzero);\
+}
+#define FIRST_LOAD(sv, pos, s, per) {\
+ sv = vec_ld(pos, s);\
+ per = vec_lvsl(pos, s);\
+}
+#define UPDATE_PTR(s0, d0, s1, d1) {\
+ d0 = s0;\
+ d1 = s1;\
+}
+#define LOAD_SRCV(pos, a, s, per, v0, v1, vf) {\
+ v1 = vec_ld(pos + a + 16, s);\
+ vf = vec_perm(v0, v1, per);\
+}
+#define LOAD_SRCV8(pos, a, s, per, v0, v1, vf) {\
+ if ((((uintptr_t)s + pos) % 16) > 8) {\
+ v1 = vec_ld(pos + a + 16, s);\
+ }\
+ vf = vec_perm(v0, src_v1, per);\
+}
+#define GET_VFD(a, b, f, vf0, vf1, per, vf, off) {\
+ vf1 = vec_ld((a * 2 * filterSize) + (b * 2) + 16 + off, f);\
+ vf = vec_perm(vf0, vf1, per);\
+}
+#else /* else of #if HAVE_BIGENDIAN */
+#define GET_VF4(a, vf, f) {\
+ vf = (vector signed short)vec_vsx_ld(a << 3, f);\
+ vf = vec_mergeh(vf, (vector signed short)vzero);\
+}
+#define FIRST_LOAD(sv, pos, s, per) {}
+#define UPDATE_PTR(s0, d0, s1, d1) {}
+#define LOAD_SRCV(pos, a, s, per, v0, v1, vf) {\
+ vf = vec_vsx_ld(pos + a, s);\
+}
+#define LOAD_SRCV8(pos, a, s, per, v0, v1, vf) LOAD_SRCV(pos, a, s, per, v0, v1, vf)
+#define GET_VFD(a, b, f, vf0, vf1, per, vf, off) {\
+ vf = vec_vsx_ld((a * 2 * filterSize) + (b * 2) + off, f);\
+}
+#endif /* end of #if HAVE_BIGENDIAN */
+
static void hScale_altivec_real(SwsContext *c, int16_t *dst, int dstW,
const uint8_t *src, const int16_t *filter,
const int32_t *filterPos, int filterSize)
for (i = 0; i < dstW; i++) {
register int srcPos = filterPos[i];
- vector unsigned char src_v0 = vec_ld(srcPos, src);
- vector unsigned char src_v1, src_vF;
+ vector unsigned char src_vF = unaligned_load(srcPos, src);
vector signed short src_v, filter_v;
vector signed int val_vEven, val_s;
- if ((((uintptr_t)src + srcPos) % 16) > 12) {
- src_v1 = vec_ld(srcPos + 16, src);
- }
- src_vF = vec_perm(src_v0, src_v1, vec_lvsl(srcPos, src));
-
src_v = // vec_unpackh sign-extends...
- (vector signed short)(vec_mergeh((vector unsigned char)vzero, src_vF));
+ (vector signed short)(VEC_MERGEH((vector unsigned char)vzero, src_vF));
// now put our elements in the even slots
src_v = vec_mergeh(src_v, (vector signed short)vzero);
-
- filter_v = vec_ld(i << 3, filter);
- // The 3 above is 2 (filterSize == 4) + 1 (sizeof(short) == 2).
-
- // The neat trick: We only care for half the elements,
- // high or low depending on (i<<3)%16 (it's 0 or 8 here),
- // and we're going to use vec_mule, so we choose
- // carefully how to "unpack" the elements into the even slots.
- if ((i << 3) % 16)
- filter_v = vec_mergel(filter_v, (vector signed short)vzero);
- else
- filter_v = vec_mergeh(filter_v, (vector signed short)vzero);
-
+ GET_VF4(i, filter_v, filter);
val_vEven = vec_mule(src_v, filter_v);
val_s = vec_sums(val_vEven, vzero);
vec_st(val_s, 0, tempo);
dst[i] = FFMIN(tempo[3] >> 7, (1 << 15) - 1);
}
break;
-
case 8:
for (i = 0; i < dstW; i++) {
register int srcPos = filterPos[i];
-
- vector unsigned char src_v0 = vec_ld(srcPos, src);
- vector unsigned char src_v1, src_vF;
+ vector unsigned char src_vF, src_v0, src_v1;
+ vector unsigned char permS;
vector signed short src_v, filter_v;
vector signed int val_v, val_s;
- if ((((uintptr_t)src + srcPos) % 16) > 8) {
- src_v1 = vec_ld(srcPos + 16, src);
- }
- src_vF = vec_perm(src_v0, src_v1, vec_lvsl(srcPos, src));
-
+ FIRST_LOAD(src_v0, srcPos, src, permS);
+ LOAD_SRCV8(srcPos, 0, src, permS, src_v0, src_v1, src_vF);
src_v = // vec_unpackh sign-extends...
- (vector signed short)(vec_mergeh((vector unsigned char)vzero, src_vF));
+ (vector signed short)(VEC_MERGEH((vector unsigned char)vzero, src_vF));
filter_v = vec_ld(i << 4, filter);
- // the 4 above is 3 (filterSize == 8) + 1 (sizeof(short) == 2)
-
val_v = vec_msums(src_v, filter_v, (vector signed int)vzero);
val_s = vec_sums(val_v, vzero);
vec_st(val_s, 0, tempo);
for (i = 0; i < dstW; i++) {
register int srcPos = filterPos[i];
- vector unsigned char src_v0 = vec_ld(srcPos, src);
- vector unsigned char src_v1 = vec_ld(srcPos + 16, src);
- vector unsigned char src_vF = vec_perm(src_v0, src_v1, vec_lvsl(srcPos, src));
-
+ vector unsigned char src_vF = unaligned_load(srcPos, src);
vector signed short src_vA = // vec_unpackh sign-extends...
- (vector signed short)(vec_mergeh((vector unsigned char)vzero, src_vF));
+ (vector signed short)(VEC_MERGEH((vector unsigned char)vzero, src_vF));
vector signed short src_vB = // vec_unpackh sign-extends...
- (vector signed short)(vec_mergel((vector unsigned char)vzero, src_vF));
-
+ (vector signed short)(VEC_MERGEL((vector unsigned char)vzero, src_vF));
vector signed short filter_v0 = vec_ld(i << 5, filter);
vector signed short filter_v1 = vec_ld((i << 5) + 16, filter);
- // the 5 above are 4 (filterSize == 16) + 1 (sizeof(short) == 2)
vector signed int val_acc = vec_msums(src_vA, filter_v0, (vector signed int)vzero);
vector signed int val_v = vec_msums(src_vB, filter_v1, val_acc);
vector signed int val_s = vec_sums(val_v, vzero);
- vec_st(val_s, 0, tempo);
+ VEC_ST(val_s, 0, tempo);
dst[i] = FFMIN(tempo[3] >> 7, (1 << 15) - 1);
}
break;
default:
for (i = 0; i < dstW; i++) {
- register int j;
+ register int j, offset = i * 2 * filterSize;
register int srcPos = filterPos[i];
vector signed int val_s, val_v = (vector signed int)vzero;
- vector signed short filter_v0R = vec_ld(i * 2 * filterSize, filter);
- vector unsigned char permF = vec_lvsl((i * 2 * filterSize), filter);
-
- vector unsigned char src_v0 = vec_ld(srcPos, src);
- vector unsigned char permS = vec_lvsl(srcPos, src);
+ vector signed short filter_v0R;
+ vector unsigned char permF, src_v0, permS;
+ FIRST_LOAD(filter_v0R, offset, filter, permF);
+ FIRST_LOAD(src_v0, srcPos, src, permS);
for (j = 0; j < filterSize - 15; j += 16) {
- vector unsigned char src_v1 = vec_ld(srcPos + j + 16, src);
- vector unsigned char src_vF = vec_perm(src_v0, src_v1, permS);
-
+ vector unsigned char src_v1, src_vF;
+ vector signed short filter_v1R, filter_v2R, filter_v0, filter_v1;
+ LOAD_SRCV(srcPos, j, src, permS, src_v0, src_v1, src_vF);
vector signed short src_vA = // vec_unpackh sign-extends...
- (vector signed short)(vec_mergeh((vector unsigned char)vzero, src_vF));
+ (vector signed short)(VEC_MERGEH((vector unsigned char)vzero, src_vF));
vector signed short src_vB = // vec_unpackh sign-extends...
- (vector signed short)(vec_mergel((vector unsigned char)vzero, src_vF));
-
- vector signed short filter_v1R = vec_ld((i * 2 * filterSize) + (j * 2) + 16, filter);
- vector signed short filter_v2R = vec_ld((i * 2 * filterSize) + (j * 2) + 32, filter);
- vector signed short filter_v0 = vec_perm(filter_v0R, filter_v1R, permF);
- vector signed short filter_v1 = vec_perm(filter_v1R, filter_v2R, permF);
+ (vector signed short)(VEC_MERGEL((vector unsigned char)vzero, src_vF));
+ GET_VFD(i, j, filter, filter_v0R, filter_v1R, permF, filter_v0, 0);
+ GET_VFD(i, j, filter, filter_v1R, filter_v2R, permF, filter_v1, 16);
vector signed int val_acc = vec_msums(src_vA, filter_v0, val_v);
val_v = vec_msums(src_vB, filter_v1, val_acc);
-
- filter_v0R = filter_v2R;
- src_v0 = src_v1;
+ UPDATE_PTR(filter_v2R, filter_v0R, src_v1, src_v0);
}
if (j < filterSize - 7) {
// loading src_v0 is useless, it's already done above
- // vector unsigned char src_v0 = vec_ld(srcPos + j, src);
vector unsigned char src_v1, src_vF;
vector signed short src_v, filter_v1R, filter_v;
- if ((((uintptr_t)src + srcPos) % 16) > 8) {
- src_v1 = vec_ld(srcPos + j + 16, src);
- }
- src_vF = vec_perm(src_v0, src_v1, permS);
-
+ LOAD_SRCV8(srcPos, j, src, permS, src_v0, src_v1, src_vF);
src_v = // vec_unpackh sign-extends...
- (vector signed short)(vec_mergeh((vector unsigned char)vzero, src_vF));
- // loading filter_v0R is useless, it's already done above
- // vector signed short filter_v0R = vec_ld((i * 2 * filterSize) + j, filter);
- filter_v1R = vec_ld((i * 2 * filterSize) + (j * 2) + 16, filter);
- filter_v = vec_perm(filter_v0R, filter_v1R, permF);
-
+ (vector signed short)(VEC_MERGEH((vector unsigned char)vzero, src_vF));
+ GET_VFD(i, j, filter, filter_v0R, filter_v1R, permF, filter_v, 0);
val_v = vec_msums(src_v, filter_v, val_v);
}
-
val_s = vec_sums(val_v, vzero);
- vec_st(val_s, 0, tempo);
+ VEC_ST(val_s, 0, tempo);
dst[i] = FFMIN(tempo[3] >> 7, (1 << 15) - 1);
}
}
const uint8_t *yc = ysrc, *uc = usrc, *vc = vsrc;
for (i = 0; i < chromWidth; i += 2) {
uint64_t k = yc[0] + (uc[0] << 8) +
- (yc[1] << 16) + (unsigned)(vc[0] << 24);
+ (yc[1] << 16) + ((unsigned) vc[0] << 24);
uint64_t l = yc[2] + (uc[1] << 8) +
- (yc[3] << 16) + (unsigned)(vc[1] << 24);
+ (yc[3] << 16) + ((unsigned) vc[1] << 24);
*ldst++ = k + (l << 32);
yc += 4;
uc += 2;
const uint8_t *yc = ysrc, *uc = usrc, *vc = vsrc;
for (i = 0; i < chromWidth; i += 2) {
uint64_t k = uc[0] + (yc[0] << 8) +
- (vc[0] << 16) + (unsigned)(yc[1] << 24);
+ (vc[0] << 16) + ((unsigned) yc[1] << 24);
uint64_t l = uc[1] + (yc[2] << 8) +
- (vc[1] << 16) + (unsigned)(yc[3] << 24);
+ (vc[1] << 16) + ((unsigned) yc[3] << 24);
*ldst++ = k + (l << 32);
yc += 4;
uc += 2;
#include "libavutil/avutil.h"
#include "libavutil/bswap.h"
#include "libavutil/cpu.h"
+#include "libavutil/imgutils.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/mathematics.h"
#include "libavutil/pixdesc.h"
c->xyz2rgb_matrix[2][2] * z >> 12;
// limit values to 12-bit depth
- r = av_clip_c(r,0,4095);
- g = av_clip_c(g,0,4095);
- b = av_clip_c(b,0,4095);
+ r = av_clip(r, 0, 4095);
+ g = av_clip(g, 0, 4095);
+ b = av_clip(b, 0, 4095);
// convert from sRGBlinear to RGB and scale from 12bit to 16bit
if (desc->flags & AV_PIX_FMT_FLAG_BE) {
c->rgb2xyz_matrix[2][2] * b >> 12;
// limit values to 12-bit depth
- x = av_clip_c(x,0,4095);
- y = av_clip_c(y,0,4095);
- z = av_clip_c(z,0,4095);
+ x = av_clip(x, 0, 4095);
+ y = av_clip(y, 0, 4095);
+ z = av_clip(z, 0, 4095);
// convert from XYZlinear to X'Y'Z' and scale from 12bit to 16bit
if (desc->flags & AV_PIX_FMT_FLAG_BE) {
av_log(c, AV_LOG_ERROR, "One of the input parameters to sws_scale() is NULL, please check the calling code\n");
return 0;
}
+ if (c->cascaded_context[0] && srcSliceY == 0 && srcSliceH == c->cascaded_context[0]->srcH) {
+ ret = sws_scale(c->cascaded_context[0],
+ srcSlice, srcStride, srcSliceY, srcSliceH,
+ c->cascaded_tmp, c->cascaded_tmpStride);
+ if (ret < 0)
+ return ret;
+ ret = sws_scale(c->cascaded_context[1],
+ (const uint8_t * const * )c->cascaded_tmp, c->cascaded_tmpStride, 0, c->cascaded_context[0]->dstH,
+ dst, dstStride);
+ return ret;
+ }
+
memcpy(src2, srcSlice, sizeof(src2));
memcpy(dst2, dst, sizeof(dst2));
# define APCK_SIZE 16
#endif
+#define RETCODE_USE_CASCADE -12345
+
struct SwsContext;
typedef enum SwsDither {
int sliceDir; ///< Direction that slices are fed to the scaler (1 = top-to-bottom, -1 = bottom-to-top).
double param[2]; ///< Input parameters for scaling algorithms that need them.
+ /* The cascaded_* fields allow spliting a scaler task into multiple
+ * sequential steps, this is for example used to limit the maximum
+ * downscaling factor that needs to be supported in one scaler.
+ */
+ struct SwsContext *cascaded_context[2];
+ int cascaded_tmpStride[4];
+ uint8_t *cascaded_tmp[4];
+
uint32_t pal_yuv[256];
uint32_t pal_rgb[256];
SwsFunc ff_yuv2rgb_init_x86(SwsContext *c);
SwsFunc ff_yuv2rgb_init_ppc(SwsContext *c);
-#if FF_API_SWS_FORMAT_NAME
-/**
- * @deprecated Use av_get_pix_fmt_name() instead.
- */
-attribute_deprecated
-const char *sws_format_name(enum AVPixelFormat format);
-#endif
-
static av_always_inline int is16BPS(enum AVPixelFormat pix_fmt)
{
const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
#include "libavutil/avutil.h"
#include "libavutil/bswap.h"
#include "libavutil/cpu.h"
+#include "libavutil/imgutils.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/mathematics.h"
#include "libavutil/opt.h"
format_entries[pix_fmt].is_supported_endianness : 0;
}
-#if FF_API_SWS_FORMAT_NAME
-const char *sws_format_name(enum AVPixelFormat format)
-{
- const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(format);
- if (desc)
- return desc->name;
- else
- return "Unknown format";
-}
-#endif
-
static double getSplineCoeff(double a, double b, double c, double d,
double dist)
{
goto fail;
if (filterSize >= MAX_FILTER_SIZE * 16 /
((flags & SWS_ACCURATE_RND) ? APCK_SIZE : 16)) {
- av_log(NULL, AV_LOG_ERROR, "sws: filterSize %d is too large, try less extreme scaling or set --sws-max-filter-size and recompile\n",
- FF_CEIL_RSHIFT((filterSize+1) * ((flags & SWS_ACCURATE_RND) ? APCK_SIZE : 16), 4));
+ ret = RETCODE_USE_CASCADE;
goto fail;
}
*outFilterSize = filterSize;
fail:
if(ret < 0)
- av_log(NULL, AV_LOG_ERROR, "sws: initFilter failed\n");
+ av_log(NULL, ret == RETCODE_USE_CASCADE ? AV_LOG_DEBUG : AV_LOG_ERROR, "sws: initFilter failed\n");
av_free(filter);
av_free(filter2);
return ret;
enum AVPixelFormat dstFormat = c->dstFormat;
const AVPixFmtDescriptor *desc_src;
const AVPixFmtDescriptor *desc_dst;
+ int ret = 0;
cpu_flags = av_get_cpu_flags();
flags = c->flags;
}
}
+ if (isBayer(srcFormat)) {
+ if (!unscaled ||
+ (dstFormat != AV_PIX_FMT_RGB24 && dstFormat != AV_PIX_FMT_YUV420P)) {
+ enum AVPixelFormat tmpFormat = AV_PIX_FMT_RGB24;
+
+ ret = av_image_alloc(c->cascaded_tmp, c->cascaded_tmpStride,
+ srcW, srcH, tmpFormat, 64);
+ if (ret < 0)
+ return ret;
+
+ c->cascaded_context[0] = sws_getContext(srcW, srcH, srcFormat,
+ srcW, srcH, tmpFormat,
+ flags, srcFilter, NULL, c->param);
+ if (!c->cascaded_context[0])
+ return -1;
+
+ c->cascaded_context[1] = sws_getContext(srcW, srcH, tmpFormat,
+ dstW, dstH, dstFormat,
+ flags, NULL, dstFilter, c->param);
+ if (!c->cascaded_context[1])
+ return -1;
+ return 0;
+ }
+ }
+
#define USE_MMAP (HAVE_MMAP && HAVE_MPROTECT && defined MAP_ANONYMOUS)
/* precalculate horizontal scaler filter coefficients */
const int filterAlign = X86_MMX(cpu_flags) ? 4 :
PPC_ALTIVEC(cpu_flags) ? 8 : 1;
- if (initFilter(&c->hLumFilter, &c->hLumFilterPos,
+ if ((ret = initFilter(&c->hLumFilter, &c->hLumFilterPos,
&c->hLumFilterSize, c->lumXInc,
srcW, dstW, filterAlign, 1 << 14,
(flags & SWS_BICUBLIN) ? (flags | SWS_BICUBIC) : flags,
cpu_flags, srcFilter->lumH, dstFilter->lumH,
c->param,
get_local_pos(c, 0, 0, 0),
- get_local_pos(c, 0, 0, 0)) < 0)
+ get_local_pos(c, 0, 0, 0))) < 0)
goto fail;
- if (initFilter(&c->hChrFilter, &c->hChrFilterPos,
+ if ((ret = initFilter(&c->hChrFilter, &c->hChrFilterPos,
&c->hChrFilterSize, c->chrXInc,
c->chrSrcW, c->chrDstW, filterAlign, 1 << 14,
(flags & SWS_BICUBLIN) ? (flags | SWS_BILINEAR) : flags,
cpu_flags, srcFilter->chrH, dstFilter->chrH,
c->param,
get_local_pos(c, c->chrSrcHSubSample, c->src_h_chr_pos, 0),
- get_local_pos(c, c->chrDstHSubSample, c->dst_h_chr_pos, 0)) < 0)
+ get_local_pos(c, c->chrDstHSubSample, c->dst_h_chr_pos, 0))) < 0)
goto fail;
}
} // initialize horizontal stuff
const int filterAlign = X86_MMX(cpu_flags) ? 2 :
PPC_ALTIVEC(cpu_flags) ? 8 : 1;
- if (initFilter(&c->vLumFilter, &c->vLumFilterPos, &c->vLumFilterSize,
+ if ((ret = initFilter(&c->vLumFilter, &c->vLumFilterPos, &c->vLumFilterSize,
c->lumYInc, srcH, dstH, filterAlign, (1 << 12),
(flags & SWS_BICUBLIN) ? (flags | SWS_BICUBIC) : flags,
cpu_flags, srcFilter->lumV, dstFilter->lumV,
c->param,
get_local_pos(c, 0, 0, 1),
- get_local_pos(c, 0, 0, 1)) < 0)
+ get_local_pos(c, 0, 0, 1))) < 0)
goto fail;
- if (initFilter(&c->vChrFilter, &c->vChrFilterPos, &c->vChrFilterSize,
+ if ((ret = initFilter(&c->vChrFilter, &c->vChrFilterPos, &c->vChrFilterSize,
c->chrYInc, c->chrSrcH, c->chrDstH,
filterAlign, (1 << 12),
(flags & SWS_BICUBLIN) ? (flags | SWS_BILINEAR) : flags,
cpu_flags, srcFilter->chrV, dstFilter->chrV,
c->param,
get_local_pos(c, c->chrSrcVSubSample, c->src_v_chr_pos, 1),
- get_local_pos(c, c->chrDstVSubSample, c->dst_v_chr_pos, 1)) < 0)
+ get_local_pos(c, c->chrDstVSubSample, c->dst_v_chr_pos, 1))) < 0)
goto fail;
c->swscale = ff_getSwsFunc(c);
return 0;
fail: // FIXME replace things by appropriate error codes
+ if (ret == RETCODE_USE_CASCADE) {
+ int tmpW = sqrt(srcW * (int64_t)dstW);
+ int tmpH = sqrt(srcH * (int64_t)dstH);
+ enum AVPixelFormat tmpFormat = AV_PIX_FMT_YUV420P;
+
+ if (srcW*(int64_t)srcH <= 4LL*dstW*dstH)
+ return AVERROR(EINVAL);
+
+ ret = av_image_alloc(c->cascaded_tmp, c->cascaded_tmpStride,
+ tmpW, tmpH, tmpFormat, 64);
+ if (ret < 0)
+ return ret;
+
+ c->cascaded_context[0] = sws_getContext(srcW, srcH, srcFormat,
+ tmpW, tmpH, tmpFormat,
+ flags, srcFilter, NULL, c->param);
+ if (!c->cascaded_context[0])
+ return -1;
+
+ c->cascaded_context[1] = sws_getContext(tmpW, tmpH, tmpFormat,
+ dstW, dstH, dstFormat,
+ flags, NULL, dstFilter, c->param);
+ if (!c->cascaded_context[1])
+ return -1;
+ return 0;
+ }
return -1;
}
av_freep(&c->yuvTable);
av_freep(&c->formatConvBuffer);
+ sws_freeContext(c->cascaded_context[0]);
+ sws_freeContext(c->cascaded_context[1]);
+ memset(c->cascaded_context, 0, sizeof(c->cascaded_context));
+ av_freep(&c->cascaded_tmp[0]);
+
av_free(c);
}
#include "libavutil/version.h"
#define LIBSWSCALE_VERSION_MAJOR 3
-#define LIBSWSCALE_VERSION_MINOR 0
-#define LIBSWSCALE_VERSION_MICRO 100
+#define LIBSWSCALE_VERSION_MINOR 1
+#define LIBSWSCALE_VERSION_MICRO 101
#define LIBSWSCALE_VERSION_INT AV_VERSION_INT(LIBSWSCALE_VERSION_MAJOR, \
LIBSWSCALE_VERSION_MINOR, \
#ifndef FF_API_SWS_CPU_CAPS
#define FF_API_SWS_CPU_CAPS (LIBSWSCALE_VERSION_MAJOR < 4)
#endif
-#ifndef FF_API_SWS_FORMAT_NAME
-#define FF_API_SWS_FORMAT_NAME (LIBSWSCALE_VERSION_MAJOR < 3)
-#endif
#ifndef FF_API_ARCH_BFIN
#define FF_API_ARCH_BFIN (LIBSWSCALE_VERSION_MAJOR < 4)
#endif
#define BGR2V_IDX "16*4+16*34"
int y;
const x86_reg chromWidth= width>>1;
+
+ if (height > 2) {
+ ff_rgb24toyv12_c(src, ydst, udst, vdst, width, 2, lumStride, chromStride, srcStride, rgb2yuv);
+ src += 2*srcStride;
+ ydst += 2*lumStride;
+ udst += chromStride;
+ vdst += chromStride;
+ height -= 2;
+ }
+
for (y=0; y<height-2; y+=2) {
int i;
for (i=0; i<2; i++) {
for (h=0; h < height; h++) {
int w;
+ if (width >= 16)
#if COMPILE_TEMPLATE_SSE2
__asm__(
"xor %%"REG_a", %%"REG_a" \n\t"
yuv2yuvX_mmxext(filter, filterSize, src, dest, dstW, dither, offset);
return;
}
- if (offset) {
- __asm__ volatile("movq (%0), %%xmm3\n\t"
- "movdqa %%xmm3, %%xmm4\n\t"
- "psrlq $24, %%xmm3\n\t"
- "psllq $40, %%xmm4\n\t"
- "por %%xmm4, %%xmm3\n\t"
- :: "r"(dither)
- );
- } else {
- __asm__ volatile("movq (%0), %%xmm3\n\t"
- :: "r"(dither)
- );
- }
filterSize--;
- __asm__ volatile(
- "pxor %%xmm0, %%xmm0\n\t"
- "punpcklbw %%xmm0, %%xmm3\n\t"
- "movd %0, %%xmm1\n\t"
- "punpcklwd %%xmm1, %%xmm1\n\t"
- "punpckldq %%xmm1, %%xmm1\n\t"
- "punpcklqdq %%xmm1, %%xmm1\n\t"
- "psllw $3, %%xmm1\n\t"
- "paddw %%xmm1, %%xmm3\n\t"
- "psraw $4, %%xmm3\n\t"
- ::"m"(filterSize)
- );
- __asm__ volatile(
- "movdqa %%xmm3, %%xmm4\n\t"
- "movdqa %%xmm3, %%xmm7\n\t"
- "movl %3, %%ecx\n\t"
+#define MAIN_FUNCTION \
+ "pxor %%xmm0, %%xmm0 \n\t" \
+ "punpcklbw %%xmm0, %%xmm3 \n\t" \
+ "movd %4, %%xmm1 \n\t" \
+ "punpcklwd %%xmm1, %%xmm1 \n\t" \
+ "punpckldq %%xmm1, %%xmm1 \n\t" \
+ "punpcklqdq %%xmm1, %%xmm1 \n\t" \
+ "psllw $3, %%xmm1 \n\t" \
+ "paddw %%xmm1, %%xmm3 \n\t" \
+ "psraw $4, %%xmm3 \n\t" \
+ "movdqa %%xmm3, %%xmm4 \n\t" \
+ "movdqa %%xmm3, %%xmm7 \n\t" \
+ "movl %3, %%ecx \n\t" \
"mov %0, %%"REG_d" \n\t"\
"mov (%%"REG_d"), %%"REG_S" \n\t"\
".p2align 4 \n\t" /* FIXME Unroll? */\
" jnz 1b \n\t"\
"psraw $3, %%xmm3 \n\t"\
"psraw $3, %%xmm4 \n\t"\
- "packuswb %%xmm4, %%xmm3 \n\t"
- "movntdq %%xmm3, (%1, %%"REG_c")\n\t"
+ "packuswb %%xmm4, %%xmm3 \n\t"\
+ "movntdq %%xmm3, (%1, %%"REG_c")\n\t"\
"add $16, %%"REG_c" \n\t"\
"cmp %2, %%"REG_c" \n\t"\
- "movdqa %%xmm7, %%xmm3\n\t"
- "movdqa %%xmm7, %%xmm4\n\t"
+ "movdqa %%xmm7, %%xmm3 \n\t" \
+ "movdqa %%xmm7, %%xmm4 \n\t" \
"mov %0, %%"REG_d" \n\t"\
"mov (%%"REG_d"), %%"REG_S" \n\t"\
- "jb 1b \n\t"\
- :: "g" (filter),
- "r" (dest-offset), "g" ((x86_reg)(dstW+offset)), "m" (offset)
- : XMM_CLOBBERS("%xmm0" , "%xmm1" , "%xmm2" , "%xmm3" , "%xmm4" , "%xmm5" , "%xmm7" ,)
- "%"REG_d, "%"REG_S, "%"REG_c
- );
+ "jb 1b \n\t"
+
+ if (offset) {
+ __asm__ volatile(
+ "movq %5, %%xmm3 \n\t"
+ "movdqa %%xmm3, %%xmm4 \n\t"
+ "psrlq $24, %%xmm3 \n\t"
+ "psllq $40, %%xmm4 \n\t"
+ "por %%xmm4, %%xmm3 \n\t"
+ MAIN_FUNCTION
+ :: "g" (filter),
+ "r" (dest-offset), "g" ((x86_reg)(dstW+offset)), "m" (offset),
+ "m"(filterSize), "m"(((uint64_t *) dither)[0])
+ : XMM_CLOBBERS("%xmm0" , "%xmm1" , "%xmm2" , "%xmm3" , "%xmm4" , "%xmm5" , "%xmm7" ,)
+ "%"REG_d, "%"REG_S, "%"REG_c
+ );
+ } else {
+ __asm__ volatile(
+ "movq %5, %%xmm3 \n\t"
+ MAIN_FUNCTION
+ :: "g" (filter),
+ "r" (dest-offset), "g" ((x86_reg)(dstW+offset)), "m" (offset),
+ "m"(filterSize), "m"(((uint64_t *) dither)[0])
+ : XMM_CLOBBERS("%xmm0" , "%xmm1" , "%xmm2" , "%xmm3" , "%xmm4" , "%xmm5" , "%xmm7" ,)
+ "%"REG_d, "%"REG_S, "%"REG_c
+ );
+ }
}
#endif
case 16: do_16_case; break; \
case 10: if (!isBE(c->dstFormat)) vscalefn = ff_yuv2planeX_10_ ## opt; break; \
case 9: if (!isBE(c->dstFormat)) vscalefn = ff_yuv2planeX_9_ ## opt; break; \
- default: if (condition_8bit) /*vscalefn = ff_yuv2planeX_8_ ## opt;*/ break; \
+ case 8: if ((condition_8bit) && !c->use_mmx_vfilter) vscalefn = ff_yuv2planeX_8_ ## opt; break; \
}
#define ASSIGN_VSCALE_FUNC(vscalefn, opt1, opt2, opt2chk) \
switch(c->dstBpc){ \
$(M)$< $@
tests/data/vsynth2.yuv: tests/rotozoom$(HOSTEXESUF) | tests/data
+ $(M)$< $(SRC_PATH)/tests/reference.pnm $@
+
+tests/data/vsynth_lena.yuv: tests/rotozoom$(HOSTEXESUF) | tests/data
$(M)$< $(SAMPLES)/lena.pnm $@
tests/data/vsynth3.yuv: tests/videogen$(HOSTEXESUF) | tests/data
$(M)$< $@ $(FATEW) $(FATEH)
-tests/test.ffmeta: TAG = COPY
-tests/test.ffmeta:
- $(M)cp -f $(SRC_PATH)/tests/test.ffmeta $(TARGET_PATH)/tests/test.ffmeta
+tests/test_copy.ffmeta: TAG = COPY
+tests/test_copy.ffmeta: tests/data
+ $(M)cp -f $(SRC_PATH)/tests/test.ffmeta tests/test_copy.ffmeta
-tests/data/ffprobe-test.nut: ffmpeg$(EXESUF) | tests/data tests/test.ffmeta
+tests/data/ffprobe-test.nut: ffmpeg$(EXESUF) tests/test_copy.ffmeta
$(M)$(TARGET_EXEC) ./$< \
-f lavfi -i "aevalsrc=sin(400*PI*2*t):d=0.125[out0]; testsrc=d=0.125[out1]; testsrc=s=100x100:d=0.125[out2]" \
- -f ffmetadata -i $(TARGET_PATH)/tests/test.ffmeta \
+ -f ffmetadata -i $(TARGET_PATH)/tests/test_copy.ffmeta \
-flags +bitexact -map 0:0 -map 0:1 -map 0:2 -map_metadata 1 \
-map_metadata:s:0 1:s:0 -map_metadata:s:1 1:s:1 \
-vcodec rawvideo -acodec pcm_s16le \
- -y $@ 2>/dev/null
+ -y $(TARGET_PATH)/$@ 2>/dev/null
tests/data/%.sw tests/data/asynth% tests/data/vsynth%.yuv tests/vsynth%/00.pgm tests/data/%.nut: TAG = GEN
include $(SRC_PATH)/tests/fate/monkeysaudio.mak
include $(SRC_PATH)/tests/fate/mp3.mak
include $(SRC_PATH)/tests/fate/mpc.mak
+include $(SRC_PATH)/tests/fate/mpeg4.mak
include $(SRC_PATH)/tests/fate/opus.mak
include $(SRC_PATH)/tests/fate/pcm.mak
include $(SRC_PATH)/tests/fate/probe.mak
$(RM) -r tests/vsynth1 tests/data tools/lavfi-showfiltfmts$(EXESUF)
$(RM) $(CLEANSUFFIXES:%=tests/%)
$(RM) $(TESTTOOLS:%=tests/%$(HOSTEXESUF))
- $(RM) tests/pixfmts.mak
+ $(RM) tests/pixfmts.mak tests/test_copy.ffmeta
-include $(wildcard tests/*.d)
ffmpeg "$@" -vn -f s16le -
}
+fmtstdout(){
+ fmt=$1
+ shift 1
+ ffmpeg -flags +bitexact "$@" -f $fmt -
+}
+
enc_dec_pcm(){
out_fmt=$1
dec_fmt=$2
$showfiltfmts $filter | awk -F '[ \r]' '/^INPUT/{ fmt=substr($3, 5); print fmt }' | sort >$in_fmts
pix_fmts=$(comm -12 $scale_exclude_fmts $in_fmts)
+ outertest=$test
for pix_fmt in $pix_fmts; do
test=$pix_fmt
video_filter "${prefilter_chain}format=$pix_fmt,$filter=$filter_args" -pix_fmt $pix_fmt
done
rm $in_fmts $scale_in_fmts $scale_out_fmts $scale_exclude_fmts
+ test=$outertest
}
mkdir -p "$outdir"
if test -e "$ref" || test $cmp = "oneline" ; then
case $cmp in
diff) diff -u -b "$ref" "$outfile" >$cmpfile ;;
+ rawdiff)diff -u "$ref" "$outfile" >$cmpfile ;;
oneoff) oneoff "$ref" "$outfile" >$cmpfile ;;
stddev) stddev "$ref" "$outfile" >$cmpfile ;;
oneline)oneline "$ref" "$outfile" >$cmpfile ;;
fate-nellymoser-aref-encode: CMD = enc_dec_pcm flv wav s16le $(REF) -c:a nellymoser
fate-nellymoser-aref-encode: CMP = stddev
fate-nellymoser-aref-encode: REF = ./tests/data/asynth-16000-1.wav
-fate-nellymoser-aref-encode: CMP_SHIFT = -244
-fate-nellymoser-aref-encode: CMP_TARGET = 9612
+fate-nellymoser-aref-encode: CMP_SHIFT = -256
+fate-nellymoser-aref-encode: CMP_TARGET = 3863
fate-nellymoser-aref-encode: SIZE_TOLERANCE = 268
FATE_SAMPLES_AUDIO-$(call DEMDEC, AVI, ON2AVC) += fate-on2avc
fate-ffmpeg-lavfi: CMD = framecrc -lavfi color=d=1:r=5
FATE_SAMPLES_FFMPEG-$(CONFIG_RAWVIDEO_DEMUXER) += fate-force_key_frames
-fate-force_key_frames: tests/data/vsynth2.yuv
+fate-force_key_frames: tests/data/vsynth_lena.yuv
fate-force_key_frames: CMD = enc_dec \
- "rawvideo -s 352x288 -pix_fmt yuv420p" tests/data/vsynth2.yuv \
+ "rawvideo -s 352x288 -pix_fmt yuv420p" tests/data/vsynth_lena.yuv \
avi "-c mpeg4 -g 240 -qscale 10 -force_key_frames 0.5,0:00:01.5" \
framecrc "" "" "-skip_frame nokey"
FATE_SAMPLES_FFMPEG-$(call ALLYES, VOBSUB_DEMUXER DVDSUB_DECODER AVFILTER OVERLAY_FILTER DVDSUB_ENCODER) += fate-sub2video
-fate-sub2video: tests/data/vsynth2.yuv
+fate-sub2video: tests/data/vsynth_lena.yuv
fate-sub2video: CMD = framecrc \
- -f rawvideo -r 5 -s 352x288 -pix_fmt yuv420p -i $(TARGET_PATH)/tests/data/vsynth2.yuv \
+ -f rawvideo -r 5 -s 352x288 -pix_fmt yuv420p -i $(TARGET_PATH)/tests/data/vsynth_lena.yuv \
-ss 132 -i $(TARGET_SAMPLES)/sub/vobsub.idx \
-filter_complex "sws_flags=+accurate_rnd+bitexact\;[0:0]scale=720:480[v]\;[v][1:0]overlay[v2]" \
-map "[v2]" -c:v rawvideo -map 1:s -c:s dvdsub
fate-filter-hq4x: CMD = framecrc -i $(TARGET_SAMPLES)/filter/pixelart%d.png -vf hqx=4 -pix_fmt bgra
fate-filter-hqx: $(FATE_FILTER_HQX-yes)
+FATE_FILTER_XBR-$(call ALLYES, IMAGE2_DEMUXER PNG_DECODER XBR_FILTER) = fate-filter-2xbr fate-filter-3xbr fate-filter-4xbr
+FATE_FILTER-yes += $(FATE_FILTER_XBR-yes)
+fate-filter-2xbr: CMD = framecrc -i $(TARGET_SAMPLES)/filter/pixelart%d.png -vf xbr=2 -pix_fmt bgra
+fate-filter-3xbr: CMD = framecrc -i $(TARGET_SAMPLES)/filter/pixelart%d.png -vf xbr=3 -pix_fmt bgra
+fate-filter-4xbr: CMD = framecrc -i $(TARGET_SAMPLES)/filter/pixelart%d.png -vf xbr=4 -pix_fmt bgra
+fate-filter-xbr: $(FATE_FILTER_XBR-yes)
+
FATE_FILTER-$(call ALLYES, UTVIDEO_DECODER AVI_DEMUXER PERMS_FILTER CURVES_FILTER) += fate-filter-curves
fate-filter-curves: CMD = framecrc -i $(TARGET_SAMPLES)/utvideo/utvideo_rgb_median.avi -vf perms=random,curves=vintage
FATE_FILTER_VSYNTH-$(CONFIG_PP_FILTER) += fate-filter-pp
fate-filter-pp: CMD = video_filter "pp=be/hb/vb/tn/l5/al"
+FATE_FILTER_VSYNTH-$(CONFIG_PP_FILTER) += fate-filter-pp1
+fate-filter-pp1: CMD = video_filter "pp=fq|4/be/hb/vb/tn/l5/al"
+
FATE_FILTER_VSYNTH-$(CONFIG_PP_FILTER) += fate-filter-pp2
fate-filter-pp2: CMD = video_filter "pp=be/fq|16/h1/v1/lb"
fate-aes: CMD = run libavutil/aes-test
fate-aes: REF = /dev/null
+FATE_LIBAVUTIL += fate-cast5
+fate-cast5: libavutil/cast5-test$(EXESUF)
+fate-cast5: CMD = run libavutil/cast5-test
+fate-cast5: REF = /dev/null
+
FATE_LIBAVUTIL += fate-atomic
fate-atomic: libavutil/atomic-test$(EXESUF)
fate-atomic: CMD = run libavutil/atomic-test
FATE_LIBAVUTIL += fate-float-dsp
fate-float-dsp: libavutil/float_dsp-test$(EXESUF)
-fate-float-dsp: CMD = run libavutil/float_dsp-test
+fate-float-dsp: CMD = run libavutil/float_dsp-test $(CPUFLAGS:%=-c%)
fate-float-dsp: CMP = null
fate-float-dsp: REF = /dev/null
fate-xtea: libavutil/xtea-test$(EXESUF)
fate-xtea: CMD = run libavutil/xtea-test
+FATE_LIBAVUTIL += fate-opt
+fate-opt: libavutil/opt-test$(EXESUF)
+fate-opt: CMD = run libavutil/opt-test
+
FATE_LIBAVUTIL += $(FATE_LIBAVUTIL-yes)
FATE-$(CONFIG_AVUTIL) += $(FATE_LIBAVUTIL)
fate-libavutil: $(FATE_LIBAVUTIL)
fate-swr-resample_async-$(3)-$(1)-$(2): REF = tests/data/asynth-$(1)-1.wav
endef
-fate-swr-resample_async-fltp-44100-8000: CMP_TARGET = 4047.25
-fate-swr-resample_async-fltp-44100-8000: SIZE_TOLERANCE = 529200 - 20132
+fate-swr-resample_async-fltp-44100-8000: CMP_TARGET = 4031.60
+fate-swr-resample_async-fltp-44100-8000: SIZE_TOLERANCE = 529200 - 20310
-fate-swr-resample_async-fltp-8000-44100: CMP_TARGET = 11193.77
-fate-swr-resample_async-fltp-8000-44100: SIZE_TOLERANCE = 96000 - 20312
+fate-swr-resample_async-fltp-8000-44100: CMP_TARGET = 11185.34
+fate-swr-resample_async-fltp-8000-44100: SIZE_TOLERANCE = 96000 - 20344
-fate-swr-resample_async-s16p-44100-8000: CMP_TARGET = 4047.24
-fate-swr-resample_async-s16p-44100-8000: SIZE_TOLERANCE = 529200 - 20132
+fate-swr-resample_async-s16p-44100-8000: CMP_TARGET = 4031.59
+fate-swr-resample_async-s16p-44100-8000: SIZE_TOLERANCE = 529200 - 20310
-fate-swr-resample_async-s16p-8000-44100: CMP_TARGET = 11194.08
-fate-swr-resample_async-s16p-8000-44100: SIZE_TOLERANCE = 96000 - 20312
+fate-swr-resample_async-s16p-8000-44100: CMP_TARGET = 11185.65
+fate-swr-resample_async-s16p-8000-44100: SIZE_TOLERANCE = 96000 - 20344
$(call CROSS_TEST,$(SAMPLERATES),ARESAMPLE,s16p,s16le,s16)
$(call CROSS_TEST,$(SAMPLERATES),ARESAMPLE,s32p,s32le,s16)
FATE_VC1-$(CONFIG_VC1_DEMUXER) += fate-vc1_sa20021
fate-vc1_sa20021: CMD = framecrc -i $(TARGET_SAMPLES)/vc1/SA20021.vc1
+FATE_VC1-$(CONFIG_VC1_DEMUXER) += fate-vc1_ilaced_twomv
+fate-vc1_ilaced_twomv: CMD = framecrc -flags +bitexact -i $(TARGET_SAMPLES)/vc1/ilaced_twomv.vc1
+
FATE_VC1-$(CONFIG_MOV_DEMUXER) += fate-vc1-ism
fate-vc1-ism: CMD = framecrc -i $(TARGET_SAMPLES)/isom/vc1-wmapro.ism -an
--- /dev/null
+
+MPEG4_RESOLUTION_CHANGE = down-down down-up up-down up-up
+
+fate-mpeg4-resolution-change-%: CMD = framemd5 -flags +bitexact -idct simple -i $(TARGET_SAMPLES)/mpeg4/resize_$(@:fate-mpeg4-resolution-change-%=%).h263 -sws_flags +bitexact
+
+FATE_MPEG4-$(call DEMDEC, H263, H263) := $(addprefix fate-mpeg4-resolution-change-, $(MPEG4_RESOLUTION_CHANGE))
+
+FATE_SAMPLES_AVCONV += $(FATE_MPEG4-yes)
+fate-mpeg4: $(FATE_MPEG4-yes)
+FATE_REALAUDIO-$(call DEMDEC, RM, RA_144) += fate-ra3-144
+fate-ra3-144: CMD = framecrc -i $(TARGET_SAMPLES)/realaudio/ra3.ra
+
+#FATE_REALAUDIO-$(call DEMDEC, RM, RA_288) += fate-ra4-288
+fate-ra4-288: CMD = pcm -i $(TARGET_SAMPLES)/realaudio/ra4_288.ra
+fate-ra4-288: REF = $(SAMPLES)/realaudio/ra4_288.pcm
+fate-ra4-288: CMP = oneoff
+
FATE_REALMEDIA_AUDIO-$(call DEMDEC, RM, RA_144) += fate-ra-144
fate-ra-144: CMD = md5 -i $(TARGET_SAMPLES)/real/ra3_in_rm_file.rm -f s16le
FATE_REALMEDIA_AUDIO-$(call DEMDEC, RM, SIPR) += $(FATE_SIPR)
fate-sipr: $(FATE_SIPR)
+fate-realaudio: $(FATE_REALAUDIO-yes)
fate-realmedia-audio: $(FATE_REALMEDIA_AUDIO-yes)
fate-realmedia-video: $(FATE_REALMEDIA_VIDEO-yes)
fate-realmedia: fate-realmedia-audio fate-realmedia-video
+fate-real: fate-realaudio fate-realmedia
-FATE_SAMPLES_FFMPEG += $(FATE_REALMEDIA_AUDIO-yes) $(FATE_REALMEDIA_VIDEO-yes)
+FATE_SAMPLES_FFMPEG += $(FATE_REALAUDIO-yes) $(FATE_REALMEDIA_AUDIO-yes) $(FATE_REALMEDIA_VIDEO-yes)
FATE_SEEK += $(FATE_SEEK_ACODEC-yes:%=fate-seek-acodec-%)
-# files from fate-vsynth2
-
-FATE_SEEK_VSYNTH2-$(call ENCDEC, ASV1, AVI) += asv1
-FATE_SEEK_VSYNTH2-$(call ENCDEC, ASV2, AVI) += asv2
-FATE_SEEK_VSYNTH2-$(call ENCDEC, DNXHD, DNXHD) += dnxhd-720p
-FATE_SEEK_VSYNTH2-$(call ENCDEC, DNXHD, DNXHD) += dnxhd-720p-rd
-FATE_SEEK_VSYNTH2-$(call ENCDEC, DNXHD, MOV) += dnxhd-1080i
-FATE_SEEK_VSYNTH2-$(call ENCDEC, DVVIDEO, DV) += dv
-FATE_SEEK_VSYNTH2-$(call ENCDEC, DVVIDEO, DV) += dv-411
-FATE_SEEK_VSYNTH2-$(call ENCDEC, DVVIDEO, DV) += dv-50
-FATE_SEEK_VSYNTH2-$(call ENCDEC, FFV1, AVI) += ffv1
-FATE_SEEK_VSYNTH2-$(call ENCDEC, FLASHSV, FLV) += flashsv
-FATE_SEEK_VSYNTH2-$(call ENCDEC, FLV, FLV) += flv
-FATE_SEEK_VSYNTH2-$(call ENCDEC, H261, AVI) += h261
-FATE_SEEK_VSYNTH2-$(call ENCDEC, H263, AVI) += h263
-FATE_SEEK_VSYNTH2-$(call ENCDEC, H263, AVI) += h263p
-FATE_SEEK_VSYNTH2-$(call ENCDEC, HUFFYUV, AVI) += huffyuv
-FATE_SEEK_VSYNTH2-$(call ENCDEC, JPEGLS, AVI) += jpegls
-FATE_SEEK_VSYNTH2-$(call ENCDEC, LJPEG MJPEG, AVI) += ljpeg
-FATE_SEEK_VSYNTH2-$(call ENCDEC, MJPEG, AVI) += mjpeg
-
-FATE_SEEK_VSYNTH2-$(call ENCDEC, MPEG1VIDEO, MPEG1VIDEO MPEGVIDEO) += \
+# files from fate-vsynth_lena
+
+FATE_SEEK_VSYNTH_LENA-$(call ENCDEC, ASV1, AVI) += asv1
+FATE_SEEK_VSYNTH_LENA-$(call ENCDEC, ASV2, AVI) += asv2
+FATE_SEEK_VSYNTH_LENA-$(call ENCDEC, DNXHD, DNXHD) += dnxhd-720p
+FATE_SEEK_VSYNTH_LENA-$(call ENCDEC, DNXHD, DNXHD) += dnxhd-720p-rd
+FATE_SEEK_VSYNTH_LENA-$(call ENCDEC, DNXHD, MOV) += dnxhd-1080i
+FATE_SEEK_VSYNTH_LENA-$(call ENCDEC, DVVIDEO, DV) += dv
+FATE_SEEK_VSYNTH_LENA-$(call ENCDEC, DVVIDEO, DV) += dv-411
+FATE_SEEK_VSYNTH_LENA-$(call ENCDEC, DVVIDEO, DV) += dv-50
+FATE_SEEK_VSYNTH_LENA-$(call ENCDEC, FFV1, AVI) += ffv1
+FATE_SEEK_VSYNTH_LENA-$(call ENCDEC, FLASHSV, FLV) += flashsv
+FATE_SEEK_VSYNTH_LENA-$(call ENCDEC, FLV, FLV) += flv
+FATE_SEEK_VSYNTH_LENA-$(call ENCDEC, H261, AVI) += h261
+FATE_SEEK_VSYNTH_LENA-$(call ENCDEC, H263, AVI) += h263
+FATE_SEEK_VSYNTH_LENA-$(call ENCDEC, H263, AVI) += h263p
+FATE_SEEK_VSYNTH_LENA-$(call ENCDEC, HUFFYUV, AVI) += huffyuv
+FATE_SEEK_VSYNTH_LENA-$(call ENCDEC, JPEGLS, AVI) += jpegls
+FATE_SEEK_VSYNTH_LENA-$(call ENCDEC, LJPEG MJPEG, AVI) += ljpeg
+FATE_SEEK_VSYNTH_LENA-$(call ENCDEC, MJPEG, AVI) += mjpeg
+
+FATE_SEEK_VSYNTH_LENA-$(call ENCDEC, MPEG1VIDEO, MPEG1VIDEO MPEGVIDEO) += \
mpeg1 \
mpeg1b
-FATE_SEEK_VSYNTH2-$(call ENCDEC, MPEG2VIDEO, MPEG2VIDEO MPEGVIDEO) += \
+FATE_SEEK_VSYNTH_LENA-$(call ENCDEC, MPEG2VIDEO, MPEG2VIDEO MPEGVIDEO) += \
mpeg2-422 \
mpeg2-idct-int \
mpeg2-ilace \
mpeg2-thread \
mpeg2-thread-ivlc
-FATE_SEEK_VSYNTH2-$(call ENCDEC, MPEG4, MP4 MOV) += mpeg4
-FATE_SEEK_VSYNTH2-$(call ENCDEC, MPEG4, AVI) += $(FATE_MPEG4_AVI)
-FATE_SEEK_VSYNTH2-$(call ENCDEC, MSMPEG4V3, AVI) += msmpeg4
-FATE_SEEK_VSYNTH2-$(call ENCDEC, MSMPEG4V2, AVI) += msmpeg4v2
-FATE_SEEK_VSYNTH2-$(call ENCDEC, RAWVIDEO, AVI) += rgb
-FATE_SEEK_VSYNTH2-$(call ENCDEC, ROQ, ROQ) += roqvideo
-FATE_SEEK_VSYNTH2-$(call ENCDEC, RV10, RM) += rv10
-FATE_SEEK_VSYNTH2-$(call ENCDEC, RV20, RM) += rv20
-FATE_SEEK_VSYNTH2-$(call ENCDEC, SNOW, AVI) += snow
-FATE_SEEK_VSYNTH2-$(call ENCDEC, SNOW, AVI) += snow-ll
-FATE_SEEK_VSYNTH2-$(call ENCDEC, SVQ1, MOV) += svq1
-FATE_SEEK_VSYNTH2-$(call ENCDEC, WMV1, AVI) += wmv1
-FATE_SEEK_VSYNTH2-$(call ENCDEC, WMV2, AVI) += wmv2
-FATE_SEEK_VSYNTH2-$(call ENCDEC, RAWVIDEO, AVI) += yuv
-
-fate-seek-vsynth2-asv1: SRC = fate/vsynth2-asv1.avi
-fate-seek-vsynth2-asv2: SRC = fate/vsynth2-asv2.avi
-fate-seek-vsynth2-dnxhd-1080i: SRC = fate/vsynth2-dnxhd-1080i.mov
-fate-seek-vsynth2-dnxhd-720p: SRC = fate/vsynth2-dnxhd-720p.dnxhd
-fate-seek-vsynth2-dnxhd-720p-rd: SRC = fate/vsynth2-dnxhd-720p.dnxhd
-fate-seek-vsynth2-dv: SRC = fate/vsynth2-dv.dv
-fate-seek-vsynth2-dv-411: SRC = fate/vsynth2-dv-411.dv
-fate-seek-vsynth2-dv-50: SRC = fate/vsynth2-dv-50.dv
-fate-seek-vsynth2-ffv1: SRC = fate/vsynth2-ffv1.avi
-fate-seek-vsynth2-flashsv: SRC = fate/vsynth2-flashsv.flv
-fate-seek-vsynth2-flv: SRC = fate/vsynth2-flv.flv
-fate-seek-vsynth2-h261: SRC = fate/vsynth2-h261.avi
-fate-seek-vsynth2-h263: SRC = fate/vsynth2-h263.avi
-fate-seek-vsynth2-h263p: SRC = fate/vsynth2-h263p.avi
-fate-seek-vsynth2-huffyuv: SRC = fate/vsynth2-huffyuv.avi
-fate-seek-vsynth2-jpegls: SRC = fate/vsynth2-jpegls.avi
-fate-seek-vsynth2-ljpeg: SRC = fate/vsynth2-ljpeg.avi
-fate-seek-vsynth2-mjpeg: SRC = fate/vsynth2-mjpeg.avi
-fate-seek-vsynth2-mpeg1: SRC = fate/vsynth2-mpeg1.mpeg1video
-fate-seek-vsynth2-mpeg1b: SRC = fate/vsynth2-mpeg1b.mpeg1video
-fate-seek-vsynth2-mpeg2-422: SRC = fate/vsynth2-mpeg2-422.mpeg2video
-fate-seek-vsynth2-mpeg2-idct-int: SRC = fate/vsynth2-mpeg2-idct-int.mpeg2video
-fate-seek-vsynth2-mpeg2-ilace: SRC = fate/vsynth2-mpeg2-ilace.mpeg2video
-fate-seek-vsynth2-mpeg2-ivlc-qprd: SRC = fate/vsynth2-mpeg2-ivlc-qprd.mpeg2video
-fate-seek-vsynth2-mpeg2-thread: SRC = fate/vsynth2-mpeg2-thread.mpeg2video
-fate-seek-vsynth2-mpeg2-thread-ivlc: SRC = fate/vsynth2-mpeg2-thread-ivlc.mpeg2video
-fate-seek-vsynth2-mpeg4: SRC = fate/vsynth2-mpeg4.mp4
-fate-seek-vsynth2-mpeg4-adap: SRC = fate/vsynth2-mpeg4-adap.avi
-fate-seek-vsynth2-mpeg4-adv: SRC = fate/vsynth2-mpeg4-adv.avi
-fate-seek-vsynth2-mpeg4-error: SRC = fate/vsynth2-mpeg4-error.avi
-fate-seek-vsynth2-mpeg4-nr: SRC = fate/vsynth2-mpeg4-nr.avi
-fate-seek-vsynth2-mpeg4-nsse: SRC = fate/vsynth2-mpeg4-nsse.avi
-fate-seek-vsynth2-mpeg4-qpel: SRC = fate/vsynth2-mpeg4-qpel.avi
-fate-seek-vsynth2-mpeg4-qprd: SRC = fate/vsynth2-mpeg4-qprd.avi
-fate-seek-vsynth2-mpeg4-rc: SRC = fate/vsynth2-mpeg4-rc.avi
-fate-seek-vsynth2-mpeg4-thread: SRC = fate/vsynth2-mpeg4-thread.avi
-fate-seek-vsynth2-msmpeg4: SRC = fate/vsynth2-msmpeg4.avi
-fate-seek-vsynth2-msmpeg4v2: SRC = fate/vsynth2-msmpeg4v2.avi
-fate-seek-vsynth2-rgb: SRC = fate/vsynth2-rgb.avi
-fate-seek-vsynth2-roqvideo: SRC = fate/vsynth2-roqvideo.roq
-fate-seek-vsynth2-rv10: SRC = fate/vsynth2-rv10.rm
-fate-seek-vsynth2-rv20: SRC = fate/vsynth2-rv20.rm
-fate-seek-vsynth2-snow: SRC = fate/vsynth2-snow.avi
-fate-seek-vsynth2-snow-ll: SRC = fate/vsynth2-snow-ll.avi
-fate-seek-vsynth2-svq1: SRC = fate/vsynth2-svq1.mov
-fate-seek-vsynth2-wmv1: SRC = fate/vsynth2-wmv1.avi
-fate-seek-vsynth2-wmv2: SRC = fate/vsynth2-wmv2.avi
-fate-seek-vsynth2-yuv: SRC = fate/vsynth2-yuv.avi
-
-FATE_SAMPLES_SEEK += $(FATE_SEEK_VSYNTH2-yes:%=fate-seek-vsynth2-%)
+FATE_SEEK_VSYNTH_LENA-$(call ENCDEC, MPEG4, MP4 MOV) += mpeg4
+FATE_SEEK_VSYNTH_LENA-$(call ENCDEC, MPEG4, AVI) += $(FATE_MPEG4_AVI)
+FATE_SEEK_VSYNTH_LENA-$(call ENCDEC, MSMPEG4V3, AVI) += msmpeg4
+FATE_SEEK_VSYNTH_LENA-$(call ENCDEC, MSMPEG4V2, AVI) += msmpeg4v2
+FATE_SEEK_VSYNTH_LENA-$(call ENCDEC, RAWVIDEO, AVI) += rgb
+FATE_SEEK_VSYNTH_LENA-$(call ENCDEC, ROQ, ROQ) += roqvideo
+FATE_SEEK_VSYNTH_LENA-$(call ENCDEC, RV10, RM) += rv10
+FATE_SEEK_VSYNTH_LENA-$(call ENCDEC, RV20, RM) += rv20
+FATE_SEEK_VSYNTH_LENA-$(call ENCDEC, SNOW, AVI) += snow
+FATE_SEEK_VSYNTH_LENA-$(call ENCDEC, SNOW, AVI) += snow-ll
+FATE_SEEK_VSYNTH_LENA-$(call ENCDEC, SVQ1, MOV) += svq1
+FATE_SEEK_VSYNTH_LENA-$(call ENCDEC, WMV1, AVI) += wmv1
+FATE_SEEK_VSYNTH_LENA-$(call ENCDEC, WMV2, AVI) += wmv2
+FATE_SEEK_VSYNTH_LENA-$(call ENCDEC, RAWVIDEO, AVI) += yuv
+
+fate-seek-vsynth_lena-asv1: SRC = fate/vsynth_lena-asv1.avi
+fate-seek-vsynth_lena-asv2: SRC = fate/vsynth_lena-asv2.avi
+fate-seek-vsynth_lena-dnxhd-1080i: SRC = fate/vsynth_lena-dnxhd-1080i.mov
+fate-seek-vsynth_lena-dnxhd-720p: SRC = fate/vsynth_lena-dnxhd-720p.dnxhd
+fate-seek-vsynth_lena-dnxhd-720p-rd: SRC = fate/vsynth_lena-dnxhd-720p.dnxhd
+fate-seek-vsynth_lena-dv: SRC = fate/vsynth_lena-dv.dv
+fate-seek-vsynth_lena-dv-411: SRC = fate/vsynth_lena-dv-411.dv
+fate-seek-vsynth_lena-dv-50: SRC = fate/vsynth_lena-dv-50.dv
+fate-seek-vsynth_lena-ffv1: SRC = fate/vsynth_lena-ffv1.avi
+fate-seek-vsynth_lena-flashsv: SRC = fate/vsynth_lena-flashsv.flv
+fate-seek-vsynth_lena-flv: SRC = fate/vsynth_lena-flv.flv
+fate-seek-vsynth_lena-h261: SRC = fate/vsynth_lena-h261.avi
+fate-seek-vsynth_lena-h263: SRC = fate/vsynth_lena-h263.avi
+fate-seek-vsynth_lena-h263p: SRC = fate/vsynth_lena-h263p.avi
+fate-seek-vsynth_lena-huffyuv: SRC = fate/vsynth_lena-huffyuv.avi
+fate-seek-vsynth_lena-jpegls: SRC = fate/vsynth_lena-jpegls.avi
+fate-seek-vsynth_lena-ljpeg: SRC = fate/vsynth_lena-ljpeg.avi
+fate-seek-vsynth_lena-mjpeg: SRC = fate/vsynth_lena-mjpeg.avi
+fate-seek-vsynth_lena-mpeg1: SRC = fate/vsynth_lena-mpeg1.mpeg1video
+fate-seek-vsynth_lena-mpeg1b: SRC = fate/vsynth_lena-mpeg1b.mpeg1video
+fate-seek-vsynth_lena-mpeg2-422: SRC = fate/vsynth_lena-mpeg2-422.mpeg2video
+fate-seek-vsynth_lena-mpeg2-idct-int: SRC = fate/vsynth_lena-mpeg2-idct-int.mpeg2video
+fate-seek-vsynth_lena-mpeg2-ilace: SRC = fate/vsynth_lena-mpeg2-ilace.mpeg2video
+fate-seek-vsynth_lena-mpeg2-ivlc-qprd: SRC = fate/vsynth_lena-mpeg2-ivlc-qprd.mpeg2video
+fate-seek-vsynth_lena-mpeg2-thread: SRC = fate/vsynth_lena-mpeg2-thread.mpeg2video
+fate-seek-vsynth_lena-mpeg2-thread-ivlc: SRC = fate/vsynth_lena-mpeg2-thread-ivlc.mpeg2video
+fate-seek-vsynth_lena-mpeg4: SRC = fate/vsynth_lena-mpeg4.mp4
+fate-seek-vsynth_lena-mpeg4-adap: SRC = fate/vsynth_lena-mpeg4-adap.avi
+fate-seek-vsynth_lena-mpeg4-adv: SRC = fate/vsynth_lena-mpeg4-adv.avi
+fate-seek-vsynth_lena-mpeg4-error: SRC = fate/vsynth_lena-mpeg4-error.avi
+fate-seek-vsynth_lena-mpeg4-nr: SRC = fate/vsynth_lena-mpeg4-nr.avi
+fate-seek-vsynth_lena-mpeg4-nsse: SRC = fate/vsynth_lena-mpeg4-nsse.avi
+fate-seek-vsynth_lena-mpeg4-qpel: SRC = fate/vsynth_lena-mpeg4-qpel.avi
+fate-seek-vsynth_lena-mpeg4-qprd: SRC = fate/vsynth_lena-mpeg4-qprd.avi
+fate-seek-vsynth_lena-mpeg4-rc: SRC = fate/vsynth_lena-mpeg4-rc.avi
+fate-seek-vsynth_lena-mpeg4-thread: SRC = fate/vsynth_lena-mpeg4-thread.avi
+fate-seek-vsynth_lena-msmpeg4: SRC = fate/vsynth_lena-msmpeg4.avi
+fate-seek-vsynth_lena-msmpeg4v2: SRC = fate/vsynth_lena-msmpeg4v2.avi
+fate-seek-vsynth_lena-rgb: SRC = fate/vsynth_lena-rgb.avi
+fate-seek-vsynth_lena-roqvideo: SRC = fate/vsynth_lena-roqvideo.roq
+fate-seek-vsynth_lena-rv10: SRC = fate/vsynth_lena-rv10.rm
+fate-seek-vsynth_lena-rv20: SRC = fate/vsynth_lena-rv20.rm
+fate-seek-vsynth_lena-snow: SRC = fate/vsynth_lena-snow.avi
+fate-seek-vsynth_lena-snow-ll: SRC = fate/vsynth_lena-snow-ll.avi
+fate-seek-vsynth_lena-svq1: SRC = fate/vsynth_lena-svq1.mov
+fate-seek-vsynth_lena-wmv1: SRC = fate/vsynth_lena-wmv1.avi
+fate-seek-vsynth_lena-wmv2: SRC = fate/vsynth_lena-wmv2.avi
+fate-seek-vsynth_lena-yuv: SRC = fate/vsynth_lena-yuv.avi
+
+FATE_SAMPLES_SEEK += $(FATE_SEEK_VSYNTH_LENA-yes:%=fate-seek-vsynth_lena-%)
# files from fate-lavf
FATE_SUBTITLES_ASS-$(call ALLYES, AQTITLE_DEMUXER TEXT_DECODER ICONV) += fate-sub-aqtitle
-fate-sub-aqtitle: CMD = md5 -sub_charenc windows-1250 -i $(TARGET_SAMPLES)/sub/AQTitle_capability_tester.aqt -f ass
+fate-sub-aqtitle: CMD = fmtstdout ass -sub_charenc windows-1250 -i $(TARGET_SAMPLES)/sub/AQTitle_capability_tester.aqt
FATE_SUBTITLES_ASS-$(call DEMDEC, JACOSUB, JACOSUB) += fate-sub-jacosub
-fate-sub-jacosub: CMD = md5 -i $(TARGET_SAMPLES)/sub/JACOsub_capability_tester.jss -f ass
+fate-sub-jacosub: CMD = fmtstdout ass -i $(TARGET_SAMPLES)/sub/JACOsub_capability_tester.jss
FATE_SUBTITLES_ASS-$(call DEMDEC, MICRODVD, MICRODVD) += fate-sub-microdvd
-fate-sub-microdvd: CMD = md5 -i $(TARGET_SAMPLES)/sub/MicroDVD_capability_tester.sub -f ass
+fate-sub-microdvd: CMD = fmtstdout ass -i $(TARGET_SAMPLES)/sub/MicroDVD_capability_tester.sub
FATE_SUBTITLES-$(call ALLYES, MICRODVD_DEMUXER MICRODVD_MUXER) += fate-sub-microdvd-remux
-fate-sub-microdvd-remux: CMD = md5 -i $(TARGET_SAMPLES)/sub/MicroDVD_capability_tester.sub -c:s copy -f microdvd
+fate-sub-microdvd-remux: CMD = fmtstdout microdvd -i $(TARGET_SAMPLES)/sub/MicroDVD_capability_tester.sub -c:s copy
FATE_SUBTITLES_ASS-$(call DEMDEC, MOV, MOVTEXT) += fate-sub-movtext
-fate-sub-movtext: CMD = md5 -i $(TARGET_SAMPLES)/sub/MovText_capability_tester.mp4 -f ass
+fate-sub-movtext: CMD = fmtstdout ass -i $(TARGET_SAMPLES)/sub/MovText_capability_tester.mp4
FATE_SUBTITLES-$(call ENCDEC, MOVTEXT, MOV) += fate-sub-movtextenc
fate-sub-movtextenc: CMD = md5 -i $(TARGET_SAMPLES)/sub/MovText_capability_tester.mp4 -map 0 -scodec mov_text -f mp4 -flags +bitexact -movflags frag_keyframe+empty_moov
FATE_SUBTITLES_ASS-$(call DEMDEC, MPL2, MPL2) += fate-sub-mpl2
-fate-sub-mpl2: CMD = md5 -i $(TARGET_SAMPLES)/sub/MPL2_capability_tester.txt -f ass
+fate-sub-mpl2: CMD = fmtstdout ass -i $(TARGET_SAMPLES)/sub/MPL2_capability_tester.txt
FATE_SUBTITLES_ASS-$(call DEMDEC, MPSUB, TEXT) += fate-sub-mpsub
-fate-sub-mpsub: CMD = md5 -i $(TARGET_SAMPLES)/sub/MPSub_capability_tester.sub -f ass
+fate-sub-mpsub: CMD = fmtstdout ass -i $(TARGET_SAMPLES)/sub/MPSub_capability_tester.sub
FATE_SUBTITLES_ASS-$(call DEMDEC, MPSUB, TEXT) += fate-sub-mpsub-frames
-fate-sub-mpsub-frames: CMD = md5 -i $(TARGET_SAMPLES)/sub/MPSub_capability_tester_frames.sub -f ass
+fate-sub-mpsub-frames: CMD = fmtstdout ass -i $(TARGET_SAMPLES)/sub/MPSub_capability_tester_frames.sub
FATE_SUBTITLES_ASS-$(call DEMDEC, PJS, PJS) += fate-sub-pjs
-fate-sub-pjs: CMD = md5 -i $(TARGET_SAMPLES)/sub/PJS_capability_tester.pjs -f ass
+fate-sub-pjs: CMD = fmtstdout ass -i $(TARGET_SAMPLES)/sub/PJS_capability_tester.pjs
FATE_SUBTITLES_ASS-$(call DEMDEC, REALTEXT, REALTEXT) += fate-sub-realtext
-fate-sub-realtext: CMD = md5 -i $(TARGET_SAMPLES)/sub/RealText_capability_tester.rt -f ass
+fate-sub-realtext: CMD = fmtstdout ass -i $(TARGET_SAMPLES)/sub/RealText_capability_tester.rt
FATE_SUBTITLES_ASS-$(call DEMDEC, SAMI, SAMI) += fate-sub-sami
-fate-sub-sami: CMD = md5 -i $(TARGET_SAMPLES)/sub/SAMI_capability_tester.smi -f ass
+fate-sub-sami: CMD = fmtstdout ass -i $(TARGET_SAMPLES)/sub/SAMI_capability_tester.smi
FATE_SUBTITLES_ASS-$(call DEMDEC, SRT, SUBRIP) += fate-sub-srt
-fate-sub-srt: CMD = md5 -i $(TARGET_SAMPLES)/sub/SubRip_capability_tester.srt -f ass
+fate-sub-srt: CMD = fmtstdout ass -i $(TARGET_SAMPLES)/sub/SubRip_capability_tester.srt
-FATE_SUBTITLES-$(call ALLYES, MOV_DEMUXER MOVTEXT_DECODER SUBRIP_ENCODER) += fate-sub-subripenc
-fate-sub-subripenc: CMD = md5 -i $(TARGET_SAMPLES)/sub/MovText_capability_tester.mp4 -scodec subrip -f srt
+FATE_SUBTITLES_ASS-$(call DEMDEC, STL, STL) += fate-sub-stl
+fate-sub-stl: CMD = fmtstdout ass -i $(TARGET_SAMPLES)/sub/STL_capability_tester.stl
+
+FATE_SUBTITLES-$(call ALLYES, MOV_DEMUXER MOVTEXT_DECODER SUBRIP_ENCODER SRT_MUXER) += fate-sub-subripenc
+fate-sub-subripenc: CMD = fmtstdout srt -i $(TARGET_SAMPLES)/sub/MovText_capability_tester.mp4 -scodec subrip
FATE_SUBTITLES_ASS-$(call ALLYES, SUBVIEWER1_DEMUXER SUBVIEWER1_DECODER ICONV) += fate-sub-subviewer1
-fate-sub-subviewer1: CMD = md5 -sub_charenc windows-1250 -i $(TARGET_SAMPLES)/sub/SubViewer1_capability_tester.sub -f ass
+fate-sub-subviewer1: CMD = fmtstdout ass -sub_charenc windows-1250 -i $(TARGET_SAMPLES)/sub/SubViewer1_capability_tester.sub
FATE_SUBTITLES_ASS-$(call DEMDEC, SUBVIEWER, SUBVIEWER) += fate-sub-subviewer
-fate-sub-subviewer: CMD = md5 -i $(TARGET_SAMPLES)/sub/SubViewer_capability_tester.sub -f ass
+fate-sub-subviewer: CMD = fmtstdout ass -i $(TARGET_SAMPLES)/sub/SubViewer_capability_tester.sub
FATE_SUBTITLES_ASS-$(call DEMDEC, VPLAYER, VPLAYER) += fate-sub-vplayer
-fate-sub-vplayer: CMD = md5 -i $(TARGET_SAMPLES)/sub/VPlayer_capability_tester.txt -f ass
+fate-sub-vplayer: CMD = fmtstdout ass -i $(TARGET_SAMPLES)/sub/VPlayer_capability_tester.txt
FATE_SUBTITLES_ASS-$(call DEMDEC, WEBVTT, WEBVTT) += fate-sub-webvtt
-fate-sub-webvtt: CMD = md5 -i $(TARGET_SAMPLES)/sub/WebVTT_capability_tester.vtt -f ass
+fate-sub-webvtt: CMD = fmtstdout ass -i $(TARGET_SAMPLES)/sub/WebVTT_capability_tester.vtt
-FATE_SUBTITLES_ASS-$(call ENCMUX, WEBVTT, WEBVTT) += fate-sub-webvttenc
-fate-sub-webvttenc: CMD = md5 -i $(TARGET_SAMPLES)/sub/SubRip_capability_tester.srt -f webvtt
+FATE_SUBTITLES-$(call ALLYES, SRT_DEMUXER SUBRIP_DECODER WEBVTT_ENCODER WEBVTT_MUXER) += fate-sub-webvttenc
+fate-sub-webvttenc: CMD = fmtstdout webvtt -i $(TARGET_SAMPLES)/sub/SubRip_capability_tester.srt
FATE_SUBTITLES_ASS-$(call ALLYES, MICRODVD_DEMUXER MICRODVD_DECODER ICONV) += fate-sub-charenc
-fate-sub-charenc: CMD = md5 -sub_charenc cp1251 -i $(TARGET_SAMPLES)/sub/cp1251-subtitles.sub -f ass
+fate-sub-charenc: CMD = fmtstdout ass -sub_charenc cp1251 -i $(TARGET_SAMPLES)/sub/cp1251-subtitles.sub
FATE_SUBTITLES-$(call ENCMUX, ASS, ASS) += $(FATE_SUBTITLES_ASS-yes)
FATE_SUBTITLES += $(FATE_SUBTITLES-yes)
FATE_SAMPLES_FFMPEG += $(FATE_SUBTITLES)
+fate-subtitles: CMP = rawdiff
fate-subtitles: $(FATE_SUBTITLES)
fate-vsynth1-%: SRC = tests/data/vsynth1.yuv
fate-vsynth2-%: SRC = tests/data/vsynth2.yuv
+fate-vsynth_lena-%: SRC = tests/data/vsynth_lena.yuv
fate-vsynth3-%: SRC = tests/data/vsynth3.yuv
fate-vsynth%: CODEC = $(word 3, $(subst -, ,$(@)))
fate-vsynth%: FMT = avi
FATE_VCODEC-$(call ENCDEC, RAWVIDEO, AVI) += yuv
fate-vsynth%-yuv: CODEC = rawvideo
+FATE_VCODEC-$(call ENCDEC, XFACE, NUT) += xface
+fate-vsynth%-xface: ENCOPTS = -s 48x48 -sws_flags neighbor+bitexact
+fate-vsynth%-xface: DECOPTS = -sws_flags neighbor+bitexact
+fate-vsynth%-xface: FMT = nut
+
FATE_VCODEC-$(call ENCDEC, YUV4, AVI) += yuv4
FATE_VCODEC-$(call ENCDEC, Y41P, AVI) += y41p
FATE_VCODEC += $(FATE_VCODEC-yes)
FATE_VSYNTH1 = $(FATE_VCODEC:%=fate-vsynth1-%)
FATE_VSYNTH2 = $(FATE_VCODEC:%=fate-vsynth2-%)
+FATE_VSYNTH_LENA = $(FATE_VCODEC:%=fate-vsynth_lena-%)
# Redundant tests because they just resize the input
RESIZE_OFF = dnxhd-720p dnxhd-720p-rd dnxhd-720p-10bit dnxhd-1080i \
dv dv-411 dv-50 avui snow snow-hpel snow-ll
$(FATE_VSYNTH1): tests/data/vsynth1.yuv
$(FATE_VSYNTH2): tests/data/vsynth2.yuv
+$(FATE_VSYNTH_LENA): tests/data/vsynth_lena.yuv
$(FATE_VSYNTH3): tests/data/vsynth3.yuv
-FATE_AVCONV += $(FATE_VSYNTH1) $(FATE_VSYNTH3)
-FATE_SAMPLES_AVCONV += $(FATE_VSYNTH2)
+FATE_AVCONV += $(FATE_VSYNTH1) $(FATE_VSYNTH2) $(FATE_VSYNTH3)
+FATE_SAMPLES_AVCONV += $(FATE_VSYNTH_LENA)
fate-vsynth1: $(FATE_VSYNTH1)
fate-vsynth2: $(FATE_VSYNTH2)
+fate-vsynth_lena: $(FATE_VSYNTH_LENA)
fate-vsynth3: $(FATE_VSYNTH3)
-fate-vcodec: fate-vsynth1 fate-vsynth2 fate-vsynth3
+fate-vcodec: fate-vsynth1 fate-vsynth_lena fate-vsynth2 fate-vsynth3
FATE_VP8-$(call DEMDEC, WEBM_DASH_MANIFEST, VP8) += fate-webm-dash-manifest-unaligned-audio-streams
fate-webm-dash-manifest-unaligned-audio-streams: CMD = run ffmpeg -f webm_dash_manifest -i $(TARGET_SAMPLES)/vp8/dash_audio1.webm -f webm_dash_manifest -i $(TARGET_SAMPLES)/vp8/dash_audio3.webm -c copy -map 0 -map 1 -f webm_dash_manifest -adaptation_sets "id=0,streams=0,1" -
+FATE_VP8-$(call DEMDEC, WEBM_DASH_MANIFEST, VP8) += fate-webm-dash-manifest-representations
+fate-webm-dash-manifest-representations: CMD = run ffmpeg -f webm_dash_manifest -i $(TARGET_SAMPLES)/vp8/dash_video1.webm -f webm_dash_manifest -i $(TARGET_SAMPLES)/vp8/dash_video4.webm -c copy -map 0 -map 1 -f webm_dash_manifest -adaptation_sets "id=0,streams=0,1" -
+
FATE_SAMPLES_AVCONV += $(FATE_VP6-yes)
fate-vp6: $(FATE_VP6-yes)
$(eval $(call FATE_VP9_SUITE,segmentation-aq-akiyo,$(1),$(2)))
$(eval $(call FATE_VP9_SUITE,segmentation-sf-akiyo,$(1),$(2)))
$(eval $(call FATE_VP9_SUITE,tiling-pedestrian,$(1),$(2)))
+$(eval $(call FATE_VP9_SUITE,trac3849,$(1),$(2)))
endef
$(eval $(call FATE_VP9_FULL))
-0a30509d9296b857e134b762b76dbc31 *tests/data/fate/acodec-adpcm-adx.adx
+d7ec7d52a2f5c91464812d031b07cc1d *tests/data/fate/acodec-adpcm-adx.adx
297720 tests/data/fate/acodec-adpcm-adx.adx
-7260139001fcac62384dad50a1023e75 *tests/data/fate/acodec-adpcm-adx.out.wav
-stddev: 6989.46 PSNR: 19.44 MAXDIFF:65398 bytes: 1058400/ 1058432
+5b5a436ec9d528d6eb0bebaf667521b0 *tests/data/fate/acodec-adpcm-adx.out.wav
+stddev: 2549.93 PSNR: 28.20 MAXDIFF:57514 bytes: 1058400/ 1058432
-0a30509d9296b857e134b762b76dbc31 *tests/data/fate/acodec-adpcm-adx-trellis.adx
+d7ec7d52a2f5c91464812d031b07cc1d *tests/data/fate/acodec-adpcm-adx-trellis.adx
297720 tests/data/fate/acodec-adpcm-adx-trellis.adx
-7260139001fcac62384dad50a1023e75 *tests/data/fate/acodec-adpcm-adx-trellis.out.wav
-stddev: 6989.46 PSNR: 19.44 MAXDIFF:65398 bytes: 1058400/ 1058432
+5b5a436ec9d528d6eb0bebaf667521b0 *tests/data/fate/acodec-adpcm-adx-trellis.out.wav
+stddev: 2549.93 PSNR: 28.20 MAXDIFF:57514 bytes: 1058400/ 1058432
-#tb 0: 12/601
+#tb 0: 1/50
0, 0, 0, 1, 63180, 0xcda82c16
0, 1, 1, 1, 63180, 0xa6097bf9
0, 2, 2, 1, 63180, 0x4c2fb091
-#tb 0: 3/158
+#tb 0: 12/281
0, 0, 0, 1, 67584, 0xce0cade5
-#tb 0: 12/601
+#tb 0: 1/50
0, 0, 0, 1, 67584, 0x5eae629b
0, 1, 1, 1, 67584, 0x32591227
0, 2, 2, 1, 67584, 0x4e4424c7
packet|codec_type=video|stream_index=2|pts=6144|pts_time=0.120000|dts=6144|dts_time=0.120000|duration=2048|duration_time=0.040000|convergence_duration=N/A|convergence_duration_time=N/A|size=30000|pos=1024801|flags=K
frame|media_type=video|key_frame=1|pkt_pts=6144|pkt_pts_time=0.120000|pkt_dts=6144|pkt_dts_time=0.120000|best_effort_timestamp=6144|best_effort_timestamp_time=0.120000|pkt_duration=2048|pkt_duration_time=0.040000|pkt_pos=1024801|pkt_size=30000|width=100|height=100|pix_fmt=rgb24|sample_aspect_ratio=1:1|pict_type=I|coded_picture_number=0|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0
stream|index=0|codec_name=pcm_s16le|profile=unknown|codec_type=audio|codec_time_base=1/44100|codec_tag_string=PSD[16]|codec_tag=0x10445350|sample_fmt=s16|sample_rate=44100|channels=1|channel_layout=unknown|bits_per_sample=16|id=N/A|r_frame_rate=0/0|avg_frame_rate=0/0|time_base=1/44100|start_pts=0|start_time=0.000000|duration_ts=N/A|duration=N/A|bit_rate=705600|max_bit_rate=N/A|bits_per_raw_sample=N/A|nb_frames=N/A|nb_read_frames=6|nb_read_packets=6|disposition:default=0|disposition:dub=0|disposition:original=0|disposition:comment=0|disposition:lyrics=0|disposition:karaoke=0|disposition:forced=0|disposition:hearing_impaired=0|disposition:visual_impaired=0|disposition:clean_effects=0|disposition:attached_pic=0|tag:E=mc²|tag:encoder=Lavc pcm_s16le
-stream|index=1|codec_name=rawvideo|profile=unknown|codec_type=video|codec_time_base=1/51200|codec_tag_string=RGB[24]|codec_tag=0x18424752|width=320|height=240|has_b_frames=0|sample_aspect_ratio=1:1|display_aspect_ratio=4:3|pix_fmt=rgb24|level=-99|color_range=N/A|color_space=unknown|timecode=N/A|id=N/A|r_frame_rate=25/1|avg_frame_rate=25/1|time_base=1/51200|start_pts=0|start_time=0.000000|duration_ts=N/A|duration=N/A|bit_rate=N/A|max_bit_rate=N/A|bits_per_raw_sample=N/A|nb_frames=N/A|nb_read_frames=4|nb_read_packets=4|disposition:default=0|disposition:dub=0|disposition:original=0|disposition:comment=0|disposition:lyrics=0|disposition:karaoke=0|disposition:forced=0|disposition:hearing_impaired=0|disposition:visual_impaired=0|disposition:clean_effects=0|disposition:attached_pic=0|tag:title=foobar|tag:duration_ts=field-and-tags-conflict-attempt|tag:encoder=Lavc rawvideo
-stream|index=2|codec_name=rawvideo|profile=unknown|codec_type=video|codec_time_base=1/51200|codec_tag_string=RGB[24]|codec_tag=0x18424752|width=100|height=100|has_b_frames=0|sample_aspect_ratio=1:1|display_aspect_ratio=1:1|pix_fmt=rgb24|level=-99|color_range=N/A|color_space=unknown|timecode=N/A|id=N/A|r_frame_rate=25/1|avg_frame_rate=25/1|time_base=1/51200|start_pts=0|start_time=0.000000|duration_ts=N/A|duration=N/A|bit_rate=N/A|max_bit_rate=N/A|bits_per_raw_sample=N/A|nb_frames=N/A|nb_read_frames=4|nb_read_packets=4|disposition:default=0|disposition:dub=0|disposition:original=0|disposition:comment=0|disposition:lyrics=0|disposition:karaoke=0|disposition:forced=0|disposition:hearing_impaired=0|disposition:visual_impaired=0|disposition:clean_effects=0|disposition:attached_pic=0|tag:encoder=Lavc rawvideo
+stream|index=1|codec_name=rawvideo|profile=unknown|codec_type=video|codec_time_base=1/51200|codec_tag_string=RGB[24]|codec_tag=0x18424752|width=320|height=240|has_b_frames=0|sample_aspect_ratio=1:1|display_aspect_ratio=4:3|pix_fmt=rgb24|level=-99|color_range=N/A|color_space=unknown|color_transfer=unknown|color_primaries=unknown|chroma_location=unspecified|timecode=N/A|id=N/A|r_frame_rate=25/1|avg_frame_rate=25/1|time_base=1/51200|start_pts=0|start_time=0.000000|duration_ts=N/A|duration=N/A|bit_rate=N/A|max_bit_rate=N/A|bits_per_raw_sample=N/A|nb_frames=N/A|nb_read_frames=4|nb_read_packets=4|disposition:default=0|disposition:dub=0|disposition:original=0|disposition:comment=0|disposition:lyrics=0|disposition:karaoke=0|disposition:forced=0|disposition:hearing_impaired=0|disposition:visual_impaired=0|disposition:clean_effects=0|disposition:attached_pic=0|tag:title=foobar|tag:duration_ts=field-and-tags-conflict-attempt|tag:encoder=Lavc rawvideo
+stream|index=2|codec_name=rawvideo|profile=unknown|codec_type=video|codec_time_base=1/51200|codec_tag_string=RGB[24]|codec_tag=0x18424752|width=100|height=100|has_b_frames=0|sample_aspect_ratio=1:1|display_aspect_ratio=1:1|pix_fmt=rgb24|level=-99|color_range=N/A|color_space=unknown|color_transfer=unknown|color_primaries=unknown|chroma_location=unspecified|timecode=N/A|id=N/A|r_frame_rate=25/1|avg_frame_rate=25/1|time_base=1/51200|start_pts=0|start_time=0.000000|duration_ts=N/A|duration=N/A|bit_rate=N/A|max_bit_rate=N/A|bits_per_raw_sample=N/A|nb_frames=N/A|nb_read_frames=4|nb_read_packets=4|disposition:default=0|disposition:dub=0|disposition:original=0|disposition:comment=0|disposition:lyrics=0|disposition:karaoke=0|disposition:forced=0|disposition:hearing_impaired=0|disposition:visual_impaired=0|disposition:clean_effects=0|disposition:attached_pic=0|tag:encoder=Lavc rawvideo
format|filename=tests/data/ffprobe-test.nut|nb_streams=3|nb_programs=0|format_name=nut|start_time=0.000000|duration=0.120000|size=1054882|bit_rate=70325466|probe_score=100|tag:title=ffprobe test file|tag:comment='A comment with CSV, XML & JSON special chars': <tag value="x">|tag:comment2=I ♥ Üñîçød€
packet,video,2,6144,0.120000,6144,0.120000,2048,0.040000,N/A,N/A,30000,1024801,K
frame,video,1,6144,0.120000,6144,0.120000,6144,0.120000,2048,0.040000,1024801,30000,100,100,rgb24,1:1,I,0,0,0,0,0
stream,0,pcm_s16le,unknown,audio,1/44100,PSD[16],0x10445350,s16,44100,1,unknown,16,N/A,0/0,0/0,1/44100,0,0.000000,N/A,N/A,705600,N/A,N/A,N/A,6,6,0,0,0,0,0,0,0,0,0,0,0,mc²,Lavc pcm_s16le
-stream,1,rawvideo,unknown,video,1/51200,RGB[24],0x18424752,320,240,0,1:1,4:3,rgb24,-99,N/A,unknown,N/A,N/A,25/1,25/1,1/51200,0,0.000000,N/A,N/A,N/A,N/A,N/A,N/A,4,4,0,0,0,0,0,0,0,0,0,0,0,foobar,field-and-tags-conflict-attempt,Lavc rawvideo
-stream,2,rawvideo,unknown,video,1/51200,RGB[24],0x18424752,100,100,0,1:1,1:1,rgb24,-99,N/A,unknown,N/A,N/A,25/1,25/1,1/51200,0,0.000000,N/A,N/A,N/A,N/A,N/A,N/A,4,4,0,0,0,0,0,0,0,0,0,0,0,Lavc rawvideo
+stream,1,rawvideo,unknown,video,1/51200,RGB[24],0x18424752,320,240,0,1:1,4:3,rgb24,-99,N/A,unknown,unknown,unknown,unspecified,N/A,N/A,25/1,25/1,1/51200,0,0.000000,N/A,N/A,N/A,N/A,N/A,N/A,4,4,0,0,0,0,0,0,0,0,0,0,0,foobar,field-and-tags-conflict-attempt,Lavc rawvideo
+stream,2,rawvideo,unknown,video,1/51200,RGB[24],0x18424752,100,100,0,1:1,1:1,rgb24,-99,N/A,unknown,unknown,unknown,unspecified,N/A,N/A,25/1,25/1,1/51200,0,0.000000,N/A,N/A,N/A,N/A,N/A,N/A,4,4,0,0,0,0,0,0,0,0,0,0,0,Lavc rawvideo
format,tests/data/ffprobe-test.nut,3,0,nut,0.000000,0.120000,1054882,70325466,100,ffprobe test file,"'A comment with CSV, XML & JSON special chars': <tag value=""x"">",I ♥ Üñîçød€
level=-99
color_range=N/A
color_space=unknown
+color_transfer=unknown
+color_primaries=unknown
+chroma_location=unspecified
timecode=N/A
id=N/A
r_frame_rate=25/1
level=-99
color_range=N/A
color_space=unknown
+color_transfer=unknown
+color_primaries=unknown
+chroma_location=unspecified
timecode=N/A
id=N/A
r_frame_rate=25/1
streams.stream.1.level=-99
streams.stream.1.color_range="N/A"
streams.stream.1.color_space="unknown"
+streams.stream.1.color_transfer="unknown"
+streams.stream.1.color_primaries="unknown"
+streams.stream.1.chroma_location="unspecified"
streams.stream.1.timecode="N/A"
streams.stream.1.id="N/A"
streams.stream.1.r_frame_rate="25/1"
streams.stream.2.level=-99
streams.stream.2.color_range="N/A"
streams.stream.2.color_space="unknown"
+streams.stream.2.color_transfer="unknown"
+streams.stream.2.color_primaries="unknown"
+streams.stream.2.chroma_location="unspecified"
streams.stream.2.timecode="N/A"
streams.stream.2.id="N/A"
streams.stream.2.r_frame_rate="25/1"
level=-99
color_range=N/A
color_space=unknown
+color_transfer=unknown
+color_primaries=unknown
+chroma_location=unspecified
timecode=N/A
id=N/A
r_frame_rate=25/1
level=-99
color_range=N/A
color_space=unknown
+color_transfer=unknown
+color_primaries=unknown
+chroma_location=unspecified
timecode=N/A
id=N/A
r_frame_rate=25/1
--- /dev/null
+#tb 0: 1/25
+0, 0, 0, 1, 877072, 0x5142c6cd
+0, 1, 1, 1, 877072, 0xa01a3f47
--- /dev/null
+#tb 0: 1/25
+0, 0, 0, 1, 1973412, 0xd4cf257b
+0, 1, 1, 1, 1973412, 0x63fcd614
--- /dev/null
+#tb 0: 1/25
+0, 0, 0, 1, 3508288, 0xc7b1d170
+0, 1, 1, 1, 3508288, 0x3fd0c3fb
-idet 1790336872e844c867a53150b8ee8810
+idet 005e6ddc8a5daf11cf866a1ec76c2572
-0bgr e179e118e6dc0a5b6f9e80955fedc776
-0rgb 95fa448040fa3f86d23418b857123259
-abgr 1a24de822f91557546c8e9c8236f7814
-argb adc0120d95192942f5c39de1b602b883
-bgr0 33ee8c3df7c05bff51c742fe6beacad1
-bgra 6e8b840001a5f50c0b277fe3d7cafd26
-rgb0 8d63004296dc6db7868aa7163780f5b5
-rgba ebf7aaa65634dcee4289e80d4fb31e50
-yuv420p 8edaf2d52dc7fba910784076b2dbdcfc
-yuyv422 07198d8a9f7989bd75d1da94800c69d5
+0bgr bdff73f3a0b22f29d2fcae461db92efc
+0rgb 6d19d706cc405fc7e0d0e941d34ddc5f
+abgr 6eb205786c9eb1419334f7725fc799ee
+argb 180b920be1f3b03234e327725a00abed
+bgr0 661a99840c4cb6d9bb755ab6fec9548b
+bgra c5e9622e15ad7ad276f50d8ebb7e994f
+rgb0 58d8a93cf254c8a7affef326a2e88367
+rgba 403329386173553df13d94c7230ec734
+yuv420p c1d71b5c7f1f65d7e27070355fc7c74a
+yuyv422 ce701473de3deefd9a8a1184e505ffe5
-gray 330feb7cbe8ede999b93ac802012058a
-yuv410p c5dac1d3f5a7a51310795daf1ac57992
-yuv411p 2fe635d25d77d7d107ddd9ad2ae1a863
-yuv420p aea7ee5c4dc21d17c833c5390d9f22ba
-yuv422p 5820321e6a49c72677003163a8fd5ebb
-yuv440p 1011e599e6f2c8095d46ed28d74ae74d
-yuv444p 4602f8acdea686aee4c281d7305831c9
-yuva420p b7258aaa6de3492642008fff075ecb2c
-yuva422p b4691c4c3b1bfc9adb5b1d855aadec81
-yuva444p a83646df12b4674d732e17b93b538be2
-yuvj420p 40b23e9f290aa5fc536337bda1e55118
-yuvj422p 036400f7fdafc1964582811b11677330
-yuvj440p 572bd7e96fe7fc6df118bb213e168f80
-yuvj444p 867f5851eb22ad7d3032333219e8133b
+gray 5bfdd4a77ce5bef266f2e0ce9f4f971b
+yuv410p 2327b4c01e6a16acf18229f3faa4f29f
+yuv411p 486a0448fd543b54eefd599eee613ba4
+yuv420p 36c640c73bdbc62d047a923d2abbc559
+yuv422p 2434b401a62eb3799e441d8b1c2e18f2
+yuv440p 6951eb4455ea2979f65ece3b1132eb5c
+yuv444p d36e193a9bfc1b21ca16b563d3802d9c
+yuva420p 54139ae3544a9c2695ade817342bd1d6
+yuva422p 0ec7ea9e289365c357ba0a0926d684f3
+yuva444p bb9cfc136d4a5a2e8c25b5885ff51a38
+yuvj420p ead0073708f677df3ea594d326954415
+yuvj422p b76079bba6818dac80d71795403585d8
+yuvj440p e3d34f02bf946af9d7973701097b3391
+yuvj444p c1757fcbb3f04d78cf082afe6537a540
--- /dev/null
+pp1 cb9f884e27a5be11f72afc9b517efd10
#tb 0: 1/1
0, 0, 0, 1, 112320, 0xb8afe429
+0, 1, 1, 1, 112320, 0xae588a4b
0, 3, 3, 1, 112320, 0xccdd27b7
--- /dev/null
+#format: frame checksums
+#version: 1
+#hash: MD5
+#tb 0: 1/25
+#stream#, dts, pts, duration, size, hash
+0, 0, 0, 1, 460800, d65fcc79c7eb9ebd9d88dca3ebb15bf4
+0, 1, 1, 1, 460800, 6c86b8c7e8eae3d63b21342f233fb44e
+0, 2, 2, 1, 460800, 7fea65fd8ee4d3fcec722f721d05ef45
+0, 3, 3, 1, 460800, 2a1d943211f8c1995cc250586f105991
+0, 4, 4, 1, 460800, 0430fa1da6a968c0936fc60a425c3b9f
+0, 5, 5, 1, 460800, 1593684b29c0f394176c9fce83ebe4a3
+0, 6, 6, 1, 460800, ff8c25a20ced839a1ce33ef25d04f342
+0, 7, 7, 1, 460800, 08869a31b677080f3fb1b12e3178c1f8
+0, 8, 8, 1, 460800, 7e8d4c417698e434508663dfd851e95d
+0, 9, 9, 1, 460800, 97488eafaa5db813bc9fbb13a4204240
+0, 10, 10, 1, 460800, aac8d92f678f077b560f24a74427ef33
+0, 11, 11, 1, 460800, dbb953e70f356c528e232dd90b21af99
+0, 12, 12, 1, 460800, 2f7b6c9f006ca733c159aadb78958621
+0, 13, 13, 1, 460800, 938142d358a298df924da648ff9542e2
+0, 14, 14, 1, 460800, 93cae8797e91f0ecb94782fd614ba477
+0, 15, 15, 1, 460800, 4644a98dbd46865c6c4e1ebe168b5095
+0, 16, 16, 1, 460800, cc932f281bf90456c508f58fda085658
+0, 17, 17, 1, 460800, 9280ef543c11446d7005a098d19b74a3
+0, 18, 18, 1, 460800, f5c91502bd600e1cfcd9ff7a5e683ce4
+0, 19, 19, 1, 460800, 4eda3b1d48ca986eeb14c90af947b6af
+0, 20, 20, 1, 460800, 84e8398c333e76412bd310c207e131d3
+0, 21, 21, 1, 460800, 7abe283b322cc4c9aaeb56e4b2e03597
+0, 22, 22, 1, 460800, b4daa2055782c6f3769bf71cb1534124
+0, 23, 23, 1, 460800, 3deb3e2f41ef4549da3b0d89031eaa42
+0, 24, 24, 1, 460800, 73b9efcd2714b3cd65b1d8aee953cd38
+0, 25, 25, 1, 460800, 493ee5aab3a0ca22887b2b673d871efd
+0, 26, 26, 1, 460800, 5fe537734707bbc050290df8c0095d0f
+0, 27, 27, 1, 460800, ca337619639144e0aea0fe226e9dad63
+0, 28, 28, 1, 460800, 8fa2e0ff609d1593d34722058e56b19a
+0, 29, 29, 1, 460800, be0950c431591485ed4de678f8f17187
+0, 30, 30, 1, 460800, 0ef4b6a8d2e3d455d697deaf730cf402
+0, 31, 31, 1, 460800, f74302190c8e47120b9597073525b08e
+0, 32, 32, 1, 460800, 129fb2cc916aa16f8fee053ae89c31b3
+0, 33, 33, 1, 460800, 0186eacb73263bb0ae02c20f827dd650
+0, 34, 34, 1, 460800, f3c0245c28ded8d497665c87e66531de
+0, 35, 35, 1, 460800, e550cae2b446a5460a7201ef20ad74fd
+0, 36, 36, 1, 460800, 5fcf10d7b438dc4e29f7ec44f027170a
+0, 37, 37, 1, 460800, 65be5db585be02d64238a43eabc40abe
+0, 38, 38, 1, 460800, 93a9d9a64726138405db6d8865a6b71b
+0, 39, 39, 1, 460800, 5af0a0d96f311fc96733c6e3e6860347
+0, 40, 40, 1, 460800, 8b6de9fe7f44a87eac573dedf8c6bbcb
+0, 41, 41, 1, 460800, f8a7bb899b2643754f63317fa949c5d2
+0, 42, 42, 1, 460800, f9011d02dd844a80e477af7c497a1e56
+0, 43, 43, 1, 460800, ddae63ad8f604d5ed3d5a558fd84c6bb
+0, 44, 44, 1, 460800, e815946decb3bee3f52fe4476d0f38ea
+0, 45, 45, 1, 460800, c3b3e46f4f851ad16d4ce9782c3fdcca
+0, 46, 46, 1, 460800, 9adcaa5ca967282f588ae184a64f15d8
+0, 47, 47, 1, 460800, 29a243a8e57c2b923c514d68c18645bf
+0, 48, 48, 1, 460800, 7a1538cfa6fad69f93bf9977ce03b2df
+0, 49, 49, 1, 460800, 91e042b5a26fb0a578fe8abad6a881c8
+0, 50, 50, 1, 460800, 4892c52ebd173c1c1f651ab9043bc0ae
+0, 51, 51, 1, 460800, 411e8f1d0603f1bf9a6e0e2fbf139b40
+0, 52, 52, 1, 460800, a8982db63153a60d32d22e3ec52d055f
+0, 53, 53, 1, 460800, eccd934107810c2360850b125c60aa20
+0, 54, 54, 1, 460800, 4ff4a75ad54f3fca7fe302fd42d8b635
+0, 55, 55, 1, 460800, 096f9c7f9605bd03a7d1a2f3707ab0cd
+0, 56, 56, 1, 460800, 8b71840efcaa91b0e999b656458259e4
+0, 57, 57, 1, 460800, a316e47df5e3b815890bbe8ad28e58f7
+0, 58, 58, 1, 460800, c05734743b26b5938bbe491c5e1207bb
+0, 59, 59, 1, 460800, f513bfb6d22eb6dee298bd60289d49ef
+0, 60, 60, 1, 460800, 1242d643e8c4d4b758dd2e4ea934ddb1
+0, 61, 61, 1, 460800, d390abd9c75cce2847ea11929d765a97
+0, 62, 62, 1, 460800, 07c172820c57f4653db9d980f8003f05
+0, 63, 63, 1, 460800, f5121dc906185e1dad2b4d3ef036ffa2
+0, 64, 64, 1, 460800, ab9d1fcf6a5aad68d0f7f68f956a8905
+0, 65, 65, 1, 460800, a30b4e2d59c411cb8ed8b420d0e9980f
+0, 66, 66, 1, 460800, a239203d87b8f6dae0b04aedb5509303
+0, 67, 67, 1, 460800, 08fe1416f25273f66354a8f4365886a9
+0, 68, 68, 1, 460800, 62a4f52f688484a633219bf2431a05a1
+0, 69, 69, 1, 460800, 4f56bbbdce274dca30ea0a6af1ad9fb5
+0, 70, 70, 1, 460800, 7cb37bb372fac6a6ed10066724bd55dc
+0, 71, 71, 1, 460800, 74452850aa88ea0072e84657503d9044
+0, 72, 72, 1, 460800, e5a41bc0f20298b7ad04d5920cbd0ef9
+0, 73, 73, 1, 460800, 6bf692b510e12a1478ad701cd6b92f5f
+0, 74, 74, 1, 460800, 70a990aa4e4e1cd09eb145fc5830182d
+0, 75, 75, 1, 460800, d1766902072052fb820a485c382c5c38
+0, 76, 76, 1, 460800, 36959297268283e0134118a7552d5432
+0, 77, 77, 1, 460800, 907bec0f379ea9eb60a3122b8c253eeb
+0, 78, 78, 1, 460800, 43f1068a583a9645245a0d60dc647b00
+0, 79, 79, 1, 460800, ee55d4619e4b10d3e931eca18a4d4586
+0, 80, 80, 1, 460800, ba6a2efc84360d701944df2236292d74
+0, 81, 81, 1, 460800, b496e4674b5eb6a60e16ec4069ffa1c2
+0, 82, 82, 1, 460800, 5ae928c45606d4665d82da353dd81a81
+0, 83, 83, 1, 460800, 3c84403932cf66e616373f0d25c9f4a8
+0, 84, 84, 1, 460800, e0b63b21cdfd96c44adeb2617ecd9022
+0, 85, 85, 1, 460800, 57e0299f7435c8bd610cba860b128001
+0, 86, 86, 1, 460800, a543a8694155a488e7cc9066a70739e5
+0, 87, 87, 1, 460800, 953d38d3b44e1564b037f83171f7f594
+0, 88, 88, 1, 460800, 3725640ec5fdaec8acc4da7a224b8137
+0, 89, 89, 1, 460800, bd1086accdf2eb9f3e8cfb1e0f09ff60
+0, 90, 90, 1, 460800, b1fc08e447396a2db10e1be8c6cda6a4
+0, 91, 91, 1, 460800, 76849824f2b9aafc850dcb9994058afb
+0, 92, 92, 1, 460800, 90523973962279d4eb5ce1261f631ff0
+0, 93, 93, 1, 460800, d5c69da4109d4d41d9b7940dbed8a21a
+0, 94, 94, 1, 460800, 978d8cbfe9413418d295c485225d8ac8
+0, 95, 95, 1, 460800, a917cd3dc6dd127523e972424f1f1544
+0, 96, 96, 1, 460800, 1a4889b8c72066ea90c2a66ff80cd118
+0, 97, 97, 1, 460800, 30f1792bad369f51bd90e20b8d084779
+0, 98, 98, 1, 460800, 14d67997177544d76d9ec69abe992bf5
+0, 99, 99, 1, 460800, 39ba73b642d95ab9d7d00ca9ecb276af
+0, 100, 100, 1, 460800, 7614eed47fa4ab378fa95a6fa09048dd
+0, 101, 101, 1, 460800, efbce233c30851726551446f2cf007d4
+0, 102, 102, 1, 460800, 4cdf067f4e0dec1d5468d73bc2fb6971
+0, 103, 103, 1, 460800, b6d5a482c97622ca0ac526e46864586c
+0, 104, 104, 1, 460800, 860c1d3db436f96a29f83b25cad8a292
+0, 105, 105, 1, 460800, 3e1adea399679f5ea40539c49d63f475
+0, 106, 106, 1, 460800, 0422ac63df21baada7df73d9efb2b4a8
+0, 107, 107, 1, 460800, f372ebfd2acea1ac3d06a898bdf5ed28
+0, 108, 108, 1, 460800, 95c1bdc33fa3a9bf6fc1cf616eae4989
+0, 109, 109, 1, 460800, a8b67585ab13e9476a2075afb347e551
+0, 110, 110, 1, 460800, 6d7ff7585b172c18e9095bbf304701aa
+0, 111, 111, 1, 460800, ca17a315650ecafcbff854414e832daf
+0, 112, 112, 1, 460800, 0e58c300f666e2f608dde25cb4e7c6e4
+0, 113, 113, 1, 460800, 7e05f8ab2cf1fb99d11edb7dce8adb61
+0, 114, 114, 1, 460800, 5ec17032a3d98c18055eedc994d5b22c
+0, 115, 115, 1, 460800, 3be2f9e9bdf62279b1d1c55af298b8bf
+0, 116, 116, 1, 460800, d791c1335df7a9aac01aeb893e16ebeb
+0, 117, 117, 1, 460800, b1235bfe00b13ac9d4abeb42be518de6
+0, 118, 118, 1, 460800, 770b5fc1acd72c526f7b751569f9ebdd
+0, 119, 119, 1, 460800, 76988407c42beb84704e5cc8175ae3d1
+0, 120, 120, 1, 460800, 9b38739847b080d019403ad0d62505f1
+0, 121, 121, 1, 460800, 06d881fe05e16b528a056001f6162b18
+0, 122, 122, 1, 460800, 2f920d88d0ac956bb7c82c2ee1999b5d
+0, 123, 123, 1, 460800, 3bda811ee889672ef9bf3b329c0d8702
+0, 124, 124, 1, 460800, 793ca50f817442d000c228bae1d34f01
+0, 125, 125, 1, 460800, 6ac43125d47508fbee2a112962d68f7f
+0, 126, 126, 1, 460800, ee60676687c0a54c648f37dc5ac62934
+0, 127, 127, 1, 460800, 34c11e62e2f886fb3f86eabaf5bb8616
+0, 128, 128, 1, 460800, fbf06b77ea70076417e7dae3f05559ad
+0, 129, 129, 1, 460800, 0910773159fee4579b60665961f42dff
+0, 130, 130, 1, 460800, 16e2bdddb02ed137c45779915e83f8ce
+0, 131, 131, 1, 460800, 36c2a8b39e39e37dfd3acaf53166d32d
+0, 132, 132, 1, 460800, 86a93fca2ea3b276d8b5d7922b051635
+0, 133, 133, 1, 460800, 453eeba71c375f94cd2955a390e19aee
+0, 134, 134, 1, 460800, 9b0661b42795d819909b6a10759f2ea8
+0, 135, 135, 1, 460800, 982d156baa7facd8ff90dfc896705dba
+0, 136, 136, 1, 460800, 4346140eb7859cf937813b320c2afd75
+0, 137, 137, 1, 460800, cb19089d54d215ee5759fa95c995cb03
+0, 138, 138, 1, 460800, 4372a47d5c86bd7f36af8b1708d89db1
+0, 139, 139, 1, 460800, 63c1ccf9233c8ced848a536ca83fd2e2
+0, 140, 140, 1, 460800, e05f15fe8811919b514aff6d712e050b
+0, 141, 141, 1, 460800, 7a0787e04d549faeb60e6c53d036fc36
+0, 142, 142, 1, 460800, a48da643d5807dc1b2c9e3768c14fa09
+0, 143, 143, 1, 460800, 18e8af2af9a6d07d0319c216f32833bd
+0, 144, 144, 1, 460800, 54a4abc6dc41181dc6c4ed12ff68d9b6
+0, 145, 145, 1, 460800, 8c4bb205f07927c237134a2b43a1c75e
+0, 146, 146, 1, 460800, c8fbebc0b9d1b0eef22ed22b339c29ad
+0, 147, 147, 1, 460800, 0092360b69fd89eec83302f9c54e63c0
+0, 148, 148, 1, 460800, 454f705a542986ee3df10a31571bac36
+0, 149, 149, 1, 460800, 810de13c12e064d70ca6d1f1c175f0b6
--- /dev/null
+#format: frame checksums
+#version: 1
+#hash: MD5
+#tb 0: 1/25
+#stream#, dts, pts, duration, size, hash
+0, 0, 0, 1, 460800, d65fcc79c7eb9ebd9d88dca3ebb15bf4
+0, 1, 1, 1, 460800, 6c86b8c7e8eae3d63b21342f233fb44e
+0, 2, 2, 1, 460800, 7fea65fd8ee4d3fcec722f721d05ef45
+0, 3, 3, 1, 460800, 2a1d943211f8c1995cc250586f105991
+0, 4, 4, 1, 460800, 0430fa1da6a968c0936fc60a425c3b9f
+0, 5, 5, 1, 460800, 1593684b29c0f394176c9fce83ebe4a3
+0, 6, 6, 1, 460800, ff8c25a20ced839a1ce33ef25d04f342
+0, 7, 7, 1, 460800, 08869a31b677080f3fb1b12e3178c1f8
+0, 8, 8, 1, 460800, 7e8d4c417698e434508663dfd851e95d
+0, 9, 9, 1, 460800, 97488eafaa5db813bc9fbb13a4204240
+0, 10, 10, 1, 460800, aac8d92f678f077b560f24a74427ef33
+0, 11, 11, 1, 460800, dbb953e70f356c528e232dd90b21af99
+0, 12, 12, 1, 460800, 2f7b6c9f006ca733c159aadb78958621
+0, 13, 13, 1, 460800, 938142d358a298df924da648ff9542e2
+0, 14, 14, 1, 460800, 93cae8797e91f0ecb94782fd614ba477
+0, 15, 15, 1, 460800, 4644a98dbd46865c6c4e1ebe168b5095
+0, 16, 16, 1, 460800, cc932f281bf90456c508f58fda085658
+0, 17, 17, 1, 460800, 9280ef543c11446d7005a098d19b74a3
+0, 18, 18, 1, 460800, f5c91502bd600e1cfcd9ff7a5e683ce4
+0, 19, 19, 1, 460800, 4eda3b1d48ca986eeb14c90af947b6af
+0, 20, 20, 1, 460800, 84e8398c333e76412bd310c207e131d3
+0, 21, 21, 1, 460800, 7abe283b322cc4c9aaeb56e4b2e03597
+0, 22, 22, 1, 460800, b4daa2055782c6f3769bf71cb1534124
+0, 23, 23, 1, 460800, 3deb3e2f41ef4549da3b0d89031eaa42
+0, 24, 24, 1, 460800, 73b9efcd2714b3cd65b1d8aee953cd38
+0, 25, 25, 1, 460800, 493ee5aab3a0ca22887b2b673d871efd
+0, 26, 26, 1, 460800, 5fe537734707bbc050290df8c0095d0f
+0, 27, 27, 1, 460800, ca337619639144e0aea0fe226e9dad63
+0, 28, 28, 1, 460800, 8fa2e0ff609d1593d34722058e56b19a
+0, 29, 29, 1, 460800, be0950c431591485ed4de678f8f17187
+0, 30, 30, 1, 460800, 0ef4b6a8d2e3d455d697deaf730cf402
+0, 31, 31, 1, 460800, f74302190c8e47120b9597073525b08e
+0, 32, 32, 1, 460800, 129fb2cc916aa16f8fee053ae89c31b3
+0, 33, 33, 1, 460800, 0186eacb73263bb0ae02c20f827dd650
+0, 34, 34, 1, 460800, f3c0245c28ded8d497665c87e66531de
+0, 35, 35, 1, 460800, e550cae2b446a5460a7201ef20ad74fd
+0, 36, 36, 1, 460800, 5fcf10d7b438dc4e29f7ec44f027170a
+0, 37, 37, 1, 460800, 65be5db585be02d64238a43eabc40abe
+0, 38, 38, 1, 460800, 93a9d9a64726138405db6d8865a6b71b
+0, 39, 39, 1, 460800, 5af0a0d96f311fc96733c6e3e6860347
+0, 40, 40, 1, 460800, 8b6de9fe7f44a87eac573dedf8c6bbcb
+0, 41, 41, 1, 460800, f8a7bb899b2643754f63317fa949c5d2
+0, 42, 42, 1, 460800, f9011d02dd844a80e477af7c497a1e56
+0, 43, 43, 1, 460800, ddae63ad8f604d5ed3d5a558fd84c6bb
+0, 44, 44, 1, 460800, e815946decb3bee3f52fe4476d0f38ea
+0, 45, 45, 1, 460800, c3b3e46f4f851ad16d4ce9782c3fdcca
+0, 46, 46, 1, 460800, 9adcaa5ca967282f588ae184a64f15d8
+0, 47, 47, 1, 460800, 29a243a8e57c2b923c514d68c18645bf
+0, 48, 48, 1, 460800, 7a1538cfa6fad69f93bf9977ce03b2df
+0, 49, 49, 1, 460800, 91e042b5a26fb0a578fe8abad6a881c8
+0, 50, 50, 1, 460800, 7614eed47fa4ab378fa95a6fa09048dd
+0, 51, 51, 1, 460800, efbce233c30851726551446f2cf007d4
+0, 52, 52, 1, 460800, 4cdf067f4e0dec1d5468d73bc2fb6971
+0, 53, 53, 1, 460800, b6d5a482c97622ca0ac526e46864586c
+0, 54, 54, 1, 460800, 860c1d3db436f96a29f83b25cad8a292
+0, 55, 55, 1, 460800, 3e1adea399679f5ea40539c49d63f475
+0, 56, 56, 1, 460800, 0422ac63df21baada7df73d9efb2b4a8
+0, 57, 57, 1, 460800, f372ebfd2acea1ac3d06a898bdf5ed28
+0, 58, 58, 1, 460800, 95c1bdc33fa3a9bf6fc1cf616eae4989
+0, 59, 59, 1, 460800, a8b67585ab13e9476a2075afb347e551
+0, 60, 60, 1, 460800, 6d7ff7585b172c18e9095bbf304701aa
+0, 61, 61, 1, 460800, ca17a315650ecafcbff854414e832daf
+0, 62, 62, 1, 460800, 0e58c300f666e2f608dde25cb4e7c6e4
+0, 63, 63, 1, 460800, 7e05f8ab2cf1fb99d11edb7dce8adb61
+0, 64, 64, 1, 460800, 5ec17032a3d98c18055eedc994d5b22c
+0, 65, 65, 1, 460800, 3be2f9e9bdf62279b1d1c55af298b8bf
+0, 66, 66, 1, 460800, d791c1335df7a9aac01aeb893e16ebeb
+0, 67, 67, 1, 460800, b1235bfe00b13ac9d4abeb42be518de6
+0, 68, 68, 1, 460800, 770b5fc1acd72c526f7b751569f9ebdd
+0, 69, 69, 1, 460800, 76988407c42beb84704e5cc8175ae3d1
+0, 70, 70, 1, 460800, 9b38739847b080d019403ad0d62505f1
+0, 71, 71, 1, 460800, 06d881fe05e16b528a056001f6162b18
+0, 72, 72, 1, 460800, 2f920d88d0ac956bb7c82c2ee1999b5d
+0, 73, 73, 1, 460800, 3bda811ee889672ef9bf3b329c0d8702
+0, 74, 74, 1, 460800, 793ca50f817442d000c228bae1d34f01
+0, 75, 75, 1, 460800, 6ac43125d47508fbee2a112962d68f7f
+0, 76, 76, 1, 460800, ee60676687c0a54c648f37dc5ac62934
+0, 77, 77, 1, 460800, 34c11e62e2f886fb3f86eabaf5bb8616
+0, 78, 78, 1, 460800, fbf06b77ea70076417e7dae3f05559ad
+0, 79, 79, 1, 460800, 0910773159fee4579b60665961f42dff
+0, 80, 80, 1, 460800, 16e2bdddb02ed137c45779915e83f8ce
+0, 81, 81, 1, 460800, 36c2a8b39e39e37dfd3acaf53166d32d
+0, 82, 82, 1, 460800, 86a93fca2ea3b276d8b5d7922b051635
+0, 83, 83, 1, 460800, 453eeba71c375f94cd2955a390e19aee
+0, 84, 84, 1, 460800, 9b0661b42795d819909b6a10759f2ea8
+0, 85, 85, 1, 460800, 982d156baa7facd8ff90dfc896705dba
+0, 86, 86, 1, 460800, 4346140eb7859cf937813b320c2afd75
+0, 87, 87, 1, 460800, cb19089d54d215ee5759fa95c995cb03
+0, 88, 88, 1, 460800, 4372a47d5c86bd7f36af8b1708d89db1
+0, 89, 89, 1, 460800, 63c1ccf9233c8ced848a536ca83fd2e2
+0, 90, 90, 1, 460800, e05f15fe8811919b514aff6d712e050b
+0, 91, 91, 1, 460800, 7a0787e04d549faeb60e6c53d036fc36
+0, 92, 92, 1, 460800, a48da643d5807dc1b2c9e3768c14fa09
+0, 93, 93, 1, 460800, 18e8af2af9a6d07d0319c216f32833bd
+0, 94, 94, 1, 460800, 54a4abc6dc41181dc6c4ed12ff68d9b6
+0, 95, 95, 1, 460800, 8c4bb205f07927c237134a2b43a1c75e
+0, 96, 96, 1, 460800, c8fbebc0b9d1b0eef22ed22b339c29ad
+0, 97, 97, 1, 460800, 0092360b69fd89eec83302f9c54e63c0
+0, 98, 98, 1, 460800, 454f705a542986ee3df10a31571bac36
+0, 99, 99, 1, 460800, 810de13c12e064d70ca6d1f1c175f0b6
+0, 100, 100, 1, 460800, 4892c52ebd173c1c1f651ab9043bc0ae
+0, 101, 101, 1, 460800, 411e8f1d0603f1bf9a6e0e2fbf139b40
+0, 102, 102, 1, 460800, a8982db63153a60d32d22e3ec52d055f
+0, 103, 103, 1, 460800, eccd934107810c2360850b125c60aa20
+0, 104, 104, 1, 460800, 4ff4a75ad54f3fca7fe302fd42d8b635
+0, 105, 105, 1, 460800, 096f9c7f9605bd03a7d1a2f3707ab0cd
+0, 106, 106, 1, 460800, 8b71840efcaa91b0e999b656458259e4
+0, 107, 107, 1, 460800, a316e47df5e3b815890bbe8ad28e58f7
+0, 108, 108, 1, 460800, c05734743b26b5938bbe491c5e1207bb
+0, 109, 109, 1, 460800, f513bfb6d22eb6dee298bd60289d49ef
+0, 110, 110, 1, 460800, 1242d643e8c4d4b758dd2e4ea934ddb1
+0, 111, 111, 1, 460800, d390abd9c75cce2847ea11929d765a97
+0, 112, 112, 1, 460800, 07c172820c57f4653db9d980f8003f05
+0, 113, 113, 1, 460800, f5121dc906185e1dad2b4d3ef036ffa2
+0, 114, 114, 1, 460800, ab9d1fcf6a5aad68d0f7f68f956a8905
+0, 115, 115, 1, 460800, a30b4e2d59c411cb8ed8b420d0e9980f
+0, 116, 116, 1, 460800, a239203d87b8f6dae0b04aedb5509303
+0, 117, 117, 1, 460800, 08fe1416f25273f66354a8f4365886a9
+0, 118, 118, 1, 460800, 62a4f52f688484a633219bf2431a05a1
+0, 119, 119, 1, 460800, 4f56bbbdce274dca30ea0a6af1ad9fb5
+0, 120, 120, 1, 460800, 7cb37bb372fac6a6ed10066724bd55dc
+0, 121, 121, 1, 460800, 74452850aa88ea0072e84657503d9044
+0, 122, 122, 1, 460800, e5a41bc0f20298b7ad04d5920cbd0ef9
+0, 123, 123, 1, 460800, 6bf692b510e12a1478ad701cd6b92f5f
+0, 124, 124, 1, 460800, 70a990aa4e4e1cd09eb145fc5830182d
+0, 125, 125, 1, 460800, d1766902072052fb820a485c382c5c38
+0, 126, 126, 1, 460800, 36959297268283e0134118a7552d5432
+0, 127, 127, 1, 460800, 907bec0f379ea9eb60a3122b8c253eeb
+0, 128, 128, 1, 460800, 43f1068a583a9645245a0d60dc647b00
+0, 129, 129, 1, 460800, ee55d4619e4b10d3e931eca18a4d4586
+0, 130, 130, 1, 460800, ba6a2efc84360d701944df2236292d74
+0, 131, 131, 1, 460800, b496e4674b5eb6a60e16ec4069ffa1c2
+0, 132, 132, 1, 460800, 5ae928c45606d4665d82da353dd81a81
+0, 133, 133, 1, 460800, 3c84403932cf66e616373f0d25c9f4a8
+0, 134, 134, 1, 460800, e0b63b21cdfd96c44adeb2617ecd9022
+0, 135, 135, 1, 460800, 57e0299f7435c8bd610cba860b128001
+0, 136, 136, 1, 460800, a543a8694155a488e7cc9066a70739e5
+0, 137, 137, 1, 460800, 953d38d3b44e1564b037f83171f7f594
+0, 138, 138, 1, 460800, 3725640ec5fdaec8acc4da7a224b8137
+0, 139, 139, 1, 460800, bd1086accdf2eb9f3e8cfb1e0f09ff60
+0, 140, 140, 1, 460800, b1fc08e447396a2db10e1be8c6cda6a4
+0, 141, 141, 1, 460800, 76849824f2b9aafc850dcb9994058afb
+0, 142, 142, 1, 460800, 90523973962279d4eb5ce1261f631ff0
+0, 143, 143, 1, 460800, d5c69da4109d4d41d9b7940dbed8a21a
+0, 144, 144, 1, 460800, 978d8cbfe9413418d295c485225d8ac8
+0, 145, 145, 1, 460800, a917cd3dc6dd127523e972424f1f1544
+0, 146, 146, 1, 460800, 1a4889b8c72066ea90c2a66ff80cd118
+0, 147, 147, 1, 460800, 30f1792bad369f51bd90e20b8d084779
+0, 148, 148, 1, 460800, 14d67997177544d76d9ec69abe992bf5
+0, 149, 149, 1, 460800, 39ba73b642d95ab9d7d00ca9ecb276af
--- /dev/null
+#format: frame checksums
+#version: 1
+#hash: MD5
+#tb 0: 1/25
+#stream#, dts, pts, duration, size, hash
+0, 0, 0, 1, 180000, 9fc6302026cf2a2dd310646b83c5dfa1
+0, 1, 1, 1, 180000, b1b2646c8df579ddf8676bc2488411a5
+0, 2, 2, 1, 180000, 5aca8cdf4914a96577cffbbc18508043
+0, 3, 3, 1, 180000, d5bec8091a32a6669e76b8ab8f82db1f
+0, 4, 4, 1, 180000, d8e8543d19d0d71959321ffcebf820ad
+0, 5, 5, 1, 180000, 90520f273b47e423ae8f519e17b9994b
+0, 6, 6, 1, 180000, 3f6b9fc1fc30804b98a16264b944ff55
+0, 7, 7, 1, 180000, 3cd3b36f6ee370c27ef86c6cd9fc7c1d
+0, 8, 8, 1, 180000, 44f44f2ac0c9160d3e8ae184c7e4caa9
+0, 9, 9, 1, 180000, c7c96bf89dd79249755b9ae0af6a259e
+0, 10, 10, 1, 180000, 8ba3f9677fb07be37b0964cf847cb538
+0, 11, 11, 1, 180000, 59614cce923cf836395b7628dddaba06
+0, 12, 12, 1, 180000, 6497b597654c9c90e290feec2f8b11c8
+0, 13, 13, 1, 180000, df2774f8219a29629bbda3c368ca3046
+0, 14, 14, 1, 180000, 818bed7e0e12e11bf510939e0a895421
+0, 15, 15, 1, 180000, 591377e15da046fe83cadede3c13ec0d
+0, 16, 16, 1, 180000, 6dcc7dc9287054307cd67db723f4b806
+0, 17, 17, 1, 180000, 5158145404ee2eda2cad930127bc9480
+0, 18, 18, 1, 180000, 9423c3bc58b00299c762d547a98d22b1
+0, 19, 19, 1, 180000, 960dcbf47536653087afc917a99f97b4
+0, 20, 20, 1, 180000, 05f7ba88fd8a73416cfab0427db30c5f
+0, 21, 21, 1, 180000, 51809dcb798fc5cc45066faf56f6b533
+0, 22, 22, 1, 180000, b637cc799280b57a770d8c3417f5a9f3
+0, 23, 23, 1, 180000, 900632153e8a06208550d62c7f327e06
+0, 24, 24, 1, 180000, fcbce1d8ee2a284e7a8a2923d878ca1a
+0, 25, 25, 1, 180000, ac64fdfeef02c97bb7ee3bd8d42cda4a
+0, 26, 26, 1, 180000, 528b693654f55eac5793222591fc32ca
+0, 27, 27, 1, 180000, d2d23bf508c6ab797cfa9093824e7271
+0, 28, 28, 1, 180000, 249d71065ba6170ee82fffeb84489a57
+0, 29, 29, 1, 180000, ab8a7ac5bdaeb22a4cc5834ff4dbc838
+0, 30, 30, 1, 180000, bc9a0da67f7dd812e4dc29adab36c79c
+0, 31, 31, 1, 180000, 4fd1c8d536616622d2acf5313ffad839
+0, 32, 32, 1, 180000, 32241cbbf06fc238ac8f852db8004788
+0, 33, 33, 1, 180000, 99cdd2026fae42d0f5de666596073c23
+0, 34, 34, 1, 180000, 9fc705da6bdf42c7f41b858185851816
+0, 35, 35, 1, 180000, 8acbd773806f2933aaadb85b4a693390
+0, 36, 36, 1, 180000, 781045116f6e6576cd53453fada887d4
+0, 37, 37, 1, 180000, 81a53875f718c706de28881c340e79a1
+0, 38, 38, 1, 180000, d183354aa17b8d65d3583264ae81bd54
+0, 39, 39, 1, 180000, 42dc484e20e9779405b205d8aa879373
+0, 40, 40, 1, 180000, d2034292cfb3a3a61b815a6a434d8f01
+0, 41, 41, 1, 180000, 625bde305548017781ed1f5bc5cb8cc4
+0, 42, 42, 1, 180000, 260544b15d99fff9e5782e30a165e5bf
+0, 43, 43, 1, 180000, 7ba5b56979a3ec49e407f7fd51912dc4
+0, 44, 44, 1, 180000, 78e40b052b8773631a014692c667590d
+0, 45, 45, 1, 180000, a79266a1d52b21594467f1efde654e3d
+0, 46, 46, 1, 180000, 33f00d3f9dd037ab9cf4dcf8a68ab013
+0, 47, 47, 1, 180000, 91d7f5d53a0d5f37c2cf485e73db66bb
+0, 48, 48, 1, 180000, 74463929bc9e7e56bd8b2f9cc194e0e9
+0, 49, 49, 1, 180000, 14c4f3cead9eda56e96dbaedce61e4c8
+0, 50, 50, 1, 180000, ba12d7a55633679bb4a9767e1c4a4c76
+0, 51, 51, 1, 180000, ad39deaa1c6a3c3dbc9a5448b9449d55
+0, 52, 52, 1, 180000, 1a59266fd8b69ecd8c0ba6894a902d9f
+0, 53, 53, 1, 180000, f0229d7137bfac76273261df2eaacbaf
+0, 54, 54, 1, 180000, 0655f3778ec7c64aa44b2cb7e9f4bce9
+0, 55, 55, 1, 180000, e5d0cf9f7a9c751afe09cac6f415f9a3
+0, 56, 56, 1, 180000, a103674a6d42da7bb026ddc6c21907f5
+0, 57, 57, 1, 180000, 86fd09abac435c94aacdc4e24bae5fa4
+0, 58, 58, 1, 180000, cba4362f9905f12ea415114011f634e3
+0, 59, 59, 1, 180000, adc6dc728070c97414d5681606f9509a
+0, 60, 60, 1, 180000, ab105d61727de7f3234c1b4618684fff
+0, 61, 61, 1, 180000, e1bb39c9fda419ce27459b3679bab6f5
+0, 62, 62, 1, 180000, 6b1b2e9e4dbf0512f5c082b950f5d1ea
+0, 63, 63, 1, 180000, 58fde3d07e884461f9e535cc6af67d61
+0, 64, 64, 1, 180000, d696821896825012fdef20361ea43376
+0, 65, 65, 1, 180000, b3a15b5a8efb394dbec89ef722d02937
+0, 66, 66, 1, 180000, bbf7cc7fef6b4b37abf12dea62c190ec
+0, 67, 67, 1, 180000, 19ad669ab8639d4eebd3f7217270b8d3
+0, 68, 68, 1, 180000, 1c8d1f98393cb9d0d38d43a296c47d17
+0, 69, 69, 1, 180000, 6feac439b0e0172220c87abda22c726b
+0, 70, 70, 1, 180000, 9c8608262d6a6012f9dd49001e8a5c2d
+0, 71, 71, 1, 180000, e79b848e3d0e323d6425a76c35a6d6f1
+0, 72, 72, 1, 180000, f2553bbaaae2e1b6898202401a085cf0
+0, 73, 73, 1, 180000, 34903147296c1d9f5c6c322a05ad1bbe
+0, 74, 74, 1, 180000, 6ed277498b9cdee9591b98bf9c1d6ba2
+0, 75, 75, 1, 180000, 5d94ad871ad94c36a7b6e3cf72058c4e
+0, 76, 76, 1, 180000, e380d7309b5f5c135c47773709575061
+0, 77, 77, 1, 180000, 554aa8facbaacc17eab7d2c36e2516c8
+0, 78, 78, 1, 180000, e5d7a81ec4c3244f548ad8d9225672fe
+0, 79, 79, 1, 180000, 201b30fb23e71c5472b884153592846d
+0, 80, 80, 1, 180000, 329bcc411f576fa4fbc7cd863e2ae459
+0, 81, 81, 1, 180000, 0b7ace1a4821d560c61053e3980b9b21
+0, 82, 82, 1, 180000, ebb2567c17350e67415e1e2259b0da8b
+0, 83, 83, 1, 180000, c10b8774392c43585c69434f7d5bd94e
+0, 84, 84, 1, 180000, 9f5862196d2bebc4ad09c214593b223e
+0, 85, 85, 1, 180000, 300dc16fbb0f2486100ed167f1d90627
+0, 86, 86, 1, 180000, 0bec9c42aa215b0c5e73a5faf8f5c925
+0, 87, 87, 1, 180000, 779d67d3f58b5dd8094b414a830b94fc
+0, 88, 88, 1, 180000, a9414e841f60cd04e414a9cad3126f22
+0, 89, 89, 1, 180000, 6b4bf1026523dd19e77705a56c9395bf
+0, 90, 90, 1, 180000, 3e7f0e8db2738e287a5c1dff33bdc90b
+0, 91, 91, 1, 180000, 5d8bf7db24fa21a21beaba6fb6ac3c95
+0, 92, 92, 1, 180000, 90f594797c97a10457bc1617d8e069e0
+0, 93, 93, 1, 180000, 9caa885630cd088d51a3601afa090f45
+0, 94, 94, 1, 180000, c189ea0726442a93a30466930b498aba
+0, 95, 95, 1, 180000, 117422414360e8bb3b617e4118bb5699
+0, 96, 96, 1, 180000, 4ad2ffd81a6adeb21affce414fea992e
+0, 97, 97, 1, 180000, 4b1f12d5a755070858d5a8218cb42ee5
+0, 98, 98, 1, 180000, 77bee2dff4ebafdea925228a870aa270
+0, 99, 99, 1, 180000, f9e4ed9fb47611084dfe1998b3a17fe2
+0, 100, 100, 1, 180000, e532cc6487cc51a7ea99d7a909f0d9d7
+0, 101, 101, 1, 180000, 79abcb269e5400f7676c869db06201f5
+0, 102, 102, 1, 180000, 5ea8363a325b8c73d8f7689234b534cb
+0, 103, 103, 1, 180000, 8b92e05ce85cb879779256efb60ef56d
+0, 104, 104, 1, 180000, 7319585dceaaa1dc339cba253ca7f7e1
+0, 105, 105, 1, 180000, a589ddfebfc5106268996dc641b63ed5
+0, 106, 106, 1, 180000, f1ea16230a29ab7a0c76b62119aec1f6
+0, 107, 107, 1, 180000, bf783508ccdc7ded175c240803c8ba42
+0, 108, 108, 1, 180000, 8432ceb650366458ea568d5d38f34339
+0, 109, 109, 1, 180000, e83eec0ba33fb28c2652985e3d5a5aa7
+0, 110, 110, 1, 180000, 866481b59ea1f6654c617b598218ac72
+0, 111, 111, 1, 180000, d1d5d72d11b430986d62a4976d3f440b
+0, 112, 112, 1, 180000, d5bbb30019545ef298f5aedeb1e50420
+0, 113, 113, 1, 180000, 9b519b5c800734d940d5b6e1c519d2f3
+0, 114, 114, 1, 180000, 46854ea69f9de67f74d216fb46ca0d3f
+0, 115, 115, 1, 180000, 43c3e53ee16e172c635bc2215e1dbe7a
+0, 116, 116, 1, 180000, 76ffdd6b5630a716cea844e34f357726
+0, 117, 117, 1, 180000, 9a65251f4152bee7529d22017d75d30b
+0, 118, 118, 1, 180000, 350ff9995c2287a5d6af83adaaa94692
+0, 119, 119, 1, 180000, 18c87ab4e73b5c4013e722a82015144a
+0, 120, 120, 1, 180000, 45bfbaac738447afda91f1aa3b877114
+0, 121, 121, 1, 180000, 727d7b1d10b96f60593b0363a1da04a3
+0, 122, 122, 1, 180000, 77c7fff4a368cf923d442a70bef5d2b6
+0, 123, 123, 1, 180000, e021419b7c840409c8543d127c55ceef
+0, 124, 124, 1, 180000, 5af4ffe289b7466c7b2ba6696e24b891
+0, 125, 125, 1, 180000, 7869c8c388f762054726a4fded34ef76
+0, 126, 126, 1, 180000, 9de7b2074944cdb6c1b28490b89b4d1b
+0, 127, 127, 1, 180000, 1c65f0842787445c5a4291db5ec95306
+0, 128, 128, 1, 180000, 0836fc11e0537c64b89ca03c98e91a88
+0, 129, 129, 1, 180000, 6c0633861801dfff2464211987e199f4
+0, 130, 130, 1, 180000, 804f395636e19519f8b2c57572e2f5b9
+0, 131, 131, 1, 180000, 26119987a7cfce7146596b5119627cec
+0, 132, 132, 1, 180000, bb064421d53f2aa472e189ceb1d1fb8f
+0, 133, 133, 1, 180000, 8f4fe12cf1ada41bd75a8ab4e6c29daa
+0, 134, 134, 1, 180000, 320803434ed72884005218c336ec616c
+0, 135, 135, 1, 180000, 636d47f0af76b7caa244436b61d066ea
+0, 136, 136, 1, 180000, d72bcab89102d278bdc34cc9d6d70d8d
+0, 137, 137, 1, 180000, 8b97a2fd174e873c5d2f815c996307e1
+0, 138, 138, 1, 180000, 780a5d69dab54077770f038b83da3786
+0, 139, 139, 1, 180000, 49238301baf70b59bc7155c79b77812f
+0, 140, 140, 1, 180000, ba9c941092f9c000935f5d0077943155
+0, 141, 141, 1, 180000, 2c91278ed0bd73a83fafa5ab373025ae
+0, 142, 142, 1, 180000, e8c1ce1347e00d9a9267ec2ee2e55f88
+0, 143, 143, 1, 180000, a9d055533ee4c85f1a47dbc0e4900ee5
+0, 144, 144, 1, 180000, 37011528ef6d82c233ab81d6fa4b25c9
+0, 145, 145, 1, 180000, bec33254e1b75e5bcf9add1b016c6409
+0, 146, 146, 1, 180000, 686469d5f908c4b13f7da93accdbfe08
+0, 147, 147, 1, 180000, 175bc1a2a4b93c51f26cec24919a5e71
+0, 148, 148, 1, 180000, 7b42cf6186457f0796a5edf418c97ff1
+0, 149, 149, 1, 180000, f6dc114720002a975e5dd4c96d64eec8
--- /dev/null
+#format: frame checksums
+#version: 1
+#hash: MD5
+#tb 0: 1/25
+#stream#, dts, pts, duration, size, hash
+0, 0, 0, 1, 152064, 7f952fd8bd40c32197afc21e2fa66404
+0, 1, 1, 1, 152064, 5b2cc25b04d9a9d33bcf5fe480505d68
+0, 2, 2, 1, 152064, 56d6bb0022f68fbccae81ef054a88c9a
+0, 3, 3, 1, 152064, e9185c3ef0d3886f1a39b83f84da767e
+0, 4, 4, 1, 152064, cac301c833ad7a916acfae8fd5e524e9
+0, 5, 5, 1, 152064, cd050aba9e0681e15294480188f4076a
+0, 6, 6, 1, 152064, 6451e141b4d6360dd7bf098fa235afc7
+0, 7, 7, 1, 152064, ac242e1eb5389ce7a6ecfc34c8594383
+0, 8, 8, 1, 152064, d35ed5d3c1542a08881fc3aa729e5308
+0, 9, 9, 1, 152064, 4049e48c807e9d39b1ac03d5b9cc4647
+0, 10, 10, 1, 152064, 2c39818c50ab18982da8e29b1a95d574
+0, 11, 11, 1, 152064, adba30adcdaf3c52bb6c2595753f3bf1
+0, 12, 12, 1, 152064, 77ba6ff6f1e7380c84e4ef635dad5414
+0, 13, 13, 1, 152064, 8ee39ce5454533b610c680ef8944c369
+0, 14, 14, 1, 152064, 1785d1de2383fff0f6ba133ece182003
+0, 15, 15, 1, 152064, fe7d8c8a7ace0dabc550d6672e8e9c15
+0, 16, 16, 1, 152064, d751ad4771ab30290f01afc9c15d93ff
+0, 17, 17, 1, 152064, 3a0f3e1dd11527ce6660bc5a3c846f5e
+0, 18, 18, 1, 152064, 5db4cb8d1403a296d1346bc0aac7e6e6
+0, 19, 19, 1, 152064, fb8f602708055e1436b473bd00abf646
+0, 20, 20, 1, 152064, dcad983fe9d87b9597e893d05352d865
+0, 21, 21, 1, 152064, 2541aefc80d4598ab64ea8591dcf79de
+0, 22, 22, 1, 152064, a80f92f508833eecd69c7f8dd21da13f
+0, 23, 23, 1, 152064, 6e28ef4f6e1151861929e46afc0aad5f
+0, 24, 24, 1, 152064, a9104c687097adc9d68751e508940bcc
+0, 25, 25, 1, 152064, 65e90aa73b8228bda909775914453dc2
+0, 26, 26, 1, 152064, 3c068b06d02b5e4110732700b1aa146b
+0, 27, 27, 1, 152064, 48f3ec3807d333774c3d031c5a9cdc50
+0, 28, 28, 1, 152064, 0d74aaa8ee4a88b4983b3e505938c962
+0, 29, 29, 1, 152064, ff1ec9697579f47fc647f56d85591207
+0, 30, 30, 1, 152064, 8052dd9c27296a2d5b2101d97af62d8e
+0, 31, 31, 1, 152064, 7a253ee1c0e0aadd3e12bfb1278299fb
+0, 32, 32, 1, 152064, b24126f3573811d8d6dc6db674ca8c64
+0, 33, 33, 1, 152064, b3f54900ec9a60f9d63387a24500a13e
+0, 34, 34, 1, 152064, 5de1ae2d5b66906ef01190ea8dad606f
+0, 35, 35, 1, 152064, d5b5458eee09aac711a2c17b7cfdc40c
+0, 36, 36, 1, 152064, 94c08ac166465b9dbfed1cb67eeb3bc3
+0, 37, 37, 1, 152064, 1b1ccbe8316f625b56d94cff1d209434
+0, 38, 38, 1, 152064, 703a29b3efd7513370c8f7ca37730d1f
+0, 39, 39, 1, 152064, c15f1fa6c7d595919d11f4142f1a6878
+0, 40, 40, 1, 152064, 8c6ef06f585061acdd66380493ea5c00
+0, 41, 41, 1, 152064, 35771c1c43232ba6ea87bd9d6e638b03
+0, 42, 42, 1, 152064, 01612e4027837fdce2f0ce8cc4a46be7
+0, 43, 43, 1, 152064, 02f1d688df26b1421079a72fe0d62c70
+0, 44, 44, 1, 152064, 7a5c70e39a65101e9622ebeaf62cfac8
+0, 45, 45, 1, 152064, 27af67aecb0500ead2a9a55e6365afb0
+0, 46, 46, 1, 152064, d4105deee590978600eb964e54a6bfa2
+0, 47, 47, 1, 152064, 7aa99b69eb5b2cc85ea99e246d378260
+0, 48, 48, 1, 152064, dd008e25da59d3260d089a9e3f5ca07c
+0, 49, 49, 1, 152064, c76ea53f0ac9a0cc5626c0b24d818e33
+0, 50, 50, 1, 152064, 89735f9e0d3be100be93d399472815d5
+0, 51, 51, 1, 152064, e6ceaa7d2df6e7d1f0833cd0efc10762
+0, 52, 52, 1, 152064, 619768d16aed503750e36e6ad1e7da49
+0, 53, 53, 1, 152064, b0a262a526be1363c1cdae34cb963500
+0, 54, 54, 1, 152064, 367f1f0f8e7f16b60d579611705bdaf7
+0, 55, 55, 1, 152064, 32013ef82c20af9a5701ac822e758995
+0, 56, 56, 1, 152064, ed37bcd10044179ff15313ac638a6cb9
+0, 57, 57, 1, 152064, 7f396f585d454a828949a82994c07e55
+0, 58, 58, 1, 152064, 203cd9b81f324784f2d06ae5596cc141
+0, 59, 59, 1, 152064, c81977bf1603b3889285125e8fa869ab
+0, 60, 60, 1, 152064, a915aac53d793ff7af3c6c073a22ab4a
+0, 61, 61, 1, 152064, e100fbd898f4263eadf11f9c48b16154
+0, 62, 62, 1, 152064, 83a6ddeba2a921a8c30ce4186ae85171
+0, 63, 63, 1, 152064, ec3d156b338d5ed1c73467ba827780eb
+0, 64, 64, 1, 152064, aca73a9b00ca3e79a6915f0af8ea21c3
+0, 65, 65, 1, 152064, 8575798a21a4417f368525b193b1b91b
+0, 66, 66, 1, 152064, d149f32e2f7ac054d70525f2a6a95eb7
+0, 67, 67, 1, 152064, 86afd4fc9c7daaa3493e7b3690f6cfd3
+0, 68, 68, 1, 152064, 5d9e18798bb214ddf1db5b52596f564c
+0, 69, 69, 1, 152064, 7dc13fe68442967746a29a83b460aacd
+0, 70, 70, 1, 152064, cc53daafdf5123591c23ae81098c1910
+0, 71, 71, 1, 152064, 3e67307e26dcfc3a3670b605e2807e8d
+0, 72, 72, 1, 152064, 204a839741780015879f69e5d1a14ee9
+0, 73, 73, 1, 152064, c2190591032c3a78271565a2ef2b775e
+0, 74, 74, 1, 152064, 3e998a8508082402bd8fb3f233b54090
+0, 75, 75, 1, 152064, 1a8aa4f4b3762550becdc410ec15aa1e
+0, 76, 76, 1, 152064, 8942b68b03d47ad70fdfab7bdd6ba6e3
+0, 77, 77, 1, 152064, 1dc3a0d8f8f9e21838a3076d37f7440e
+0, 78, 78, 1, 152064, b741149b65ab4d546589ddd86eab0974
+0, 79, 79, 1, 152064, ae613ac4352122303830630aa1659bf3
+0, 80, 80, 1, 152064, 9d63f03904c4ba2d6ba9f5064fb876c0
+0, 81, 81, 1, 152064, 558613ee2d0067463955a3e0ad53300c
+0, 82, 82, 1, 152064, b7dc3958e008647203699ba33eee87fa
+0, 83, 83, 1, 152064, edaa3e3518609d3e74992333a82e7112
+0, 84, 84, 1, 152064, 52a6a70676e436a33ee895d84ad596bc
+0, 85, 85, 1, 152064, 0e2a16eb0f92f36a8850ef1bf0036666
+0, 86, 86, 1, 152064, ae7a1bbd95a3720abe058188332c23d5
+0, 87, 87, 1, 152064, b5a96ba8cdd239f71ea3b8ba9dff2d5b
+0, 88, 88, 1, 152064, 779ddc0e67b4ae2680b2cbcf7677c455
+0, 89, 89, 1, 152064, d21d0d06a337c3f15a0a14bfc690314f
+0, 90, 90, 1, 152064, ad8dbde040a9d7e908b378b6ff239197
+0, 91, 91, 1, 152064, 558f727ae629c902aacec1adde0b93bf
+0, 92, 92, 1, 152064, c1eb3c2cad922e3485a1dae690fa30bc
+0, 93, 93, 1, 152064, 0070fda686af92eaca687066ae74c31a
+0, 94, 94, 1, 152064, 363328969fd103a7860e109267211547
+0, 95, 95, 1, 152064, 2def2821815115bb3c0574c686c68231
+0, 96, 96, 1, 152064, 08c93e6efc9148b1903dc5bbb999594d
+0, 97, 97, 1, 152064, 7611bd388d2ca03b2bbe0b8659cc15f5
+0, 98, 98, 1, 152064, 8f41948219f2366883896f51b208a93a
+0, 99, 99, 1, 152064, efa7e5d74dbdff7cdca512c0abf7e0cd
+0, 100, 100, 1, 152064, 9764d3ab383ef0964149f1e22376a8c6
+0, 101, 101, 1, 152064, c6c28e349ca4dc37d5862419e35f0786
+0, 102, 102, 1, 152064, 7a4a7315a5c4b76f8ee4704a48ec9f4d
+0, 103, 103, 1, 152064, f3336a5107afcf7a797826c9bfa791d2
+0, 104, 104, 1, 152064, ef25146735a0250b737a359bd29c35fd
+0, 105, 105, 1, 152064, 8b0979747f36694dd0f9d16c545f777b
+0, 106, 106, 1, 152064, 23911162849aedca0136528e30784c2f
+0, 107, 107, 1, 152064, 8390350c4d3065e52ba42189019889a4
+0, 108, 108, 1, 152064, 228a4f65158409f984d334e80cabe978
+0, 109, 109, 1, 152064, 3eb67bba80c7bbea6cce099f666a2ede
+0, 110, 110, 1, 152064, 437966de7c15a11fdcea5c544204a0f4
+0, 111, 111, 1, 152064, bbfbb8008f1e7b002aab021082bf59c6
+0, 112, 112, 1, 152064, 388b81b3b7d6efa9e1fe2481308f23c7
+0, 113, 113, 1, 152064, efabd9424c4541c04eed3c8ba95d0596
+0, 114, 114, 1, 152064, 86ad8a0772ffaca7c23284625a7cbcee
+0, 115, 115, 1, 152064, 9d7988d07bcfd36442fbf2d8e5e101f4
+0, 116, 116, 1, 152064, 80770b3dbf125e02167e79324ad1cd91
+0, 117, 117, 1, 152064, b9479f64fe9fbd98ae9abab1a6312ae8
+0, 118, 118, 1, 152064, d6c209d64d1d7126a7ec034bea9ff90d
+0, 119, 119, 1, 152064, 14f93282da9b72f6b5ad48a7adbe123e
+0, 120, 120, 1, 152064, 12a54bf2592e25a18c706164b6ec101d
+0, 121, 121, 1, 152064, cb352e89039a04a8f16620107e8d9014
+0, 122, 122, 1, 152064, c8e116f3f3366f50bf70a51cc93be7e7
+0, 123, 123, 1, 152064, 8d7eb47f6b233a92151f2775d1978f0e
+0, 124, 124, 1, 152064, 5cfab1f17edf8a84f34a349d6794f032
+0, 125, 125, 1, 152064, 6ebec5f5e1fb1edc4063be265314ad8f
+0, 126, 126, 1, 152064, a49875c669e23e24ea17f2de189b21d3
+0, 127, 127, 1, 152064, 5c8d5b347ecccecb0bae9745ac6b45f0
+0, 128, 128, 1, 152064, b6dc1815dc30eaaab5df0554f0a5b56e
+0, 129, 129, 1, 152064, 509a0ac070524f8c719a3c4d79fb76e5
+0, 130, 130, 1, 152064, ad13dcf1552d26a87d17101036b45c52
+0, 131, 131, 1, 152064, 2620e7fb141063ca4fbad4439f32dae7
+0, 132, 132, 1, 152064, 18d34d054c41a1423d969344af80fac4
+0, 133, 133, 1, 152064, 8599dccbb02cc59563b5afea6c193acd
+0, 134, 134, 1, 152064, b53d42b366b8d7cbb4af52f8840630e4
+0, 135, 135, 1, 152064, 11747b80047ff5599dda6f9f0417478e
+0, 136, 136, 1, 152064, 10f68820f282a0e89b58a1657bcf6fa8
+0, 137, 137, 1, 152064, ca0f0c0ca11c703f16cf190d52971a2a
+0, 138, 138, 1, 152064, b6fb4d3ce986c503cac8ae21ad72313b
+0, 139, 139, 1, 152064, 194b3f779eaddadf563b447b7b579d3c
+0, 140, 140, 1, 152064, 6c248256e677d7d374b2ca2cc42f58e7
+0, 141, 141, 1, 152064, dd358dcc4e3f750b2bcc96db0c3293c7
+0, 142, 142, 1, 152064, eb0d082f192d46bc4188b892e2812eb6
+0, 143, 143, 1, 152064, f539f619df45340677c6a80db65f1795
+0, 144, 144, 1, 152064, 9d274ccc0a6e7bc52065f6d413b82d2f
+0, 145, 145, 1, 152064, 18b950f15cc925d25e3ce823dea4c265
+0, 146, 146, 1, 152064, 38573a7cdfc3fdd7110ed6682d57e2b6
+0, 147, 147, 1, 152064, e41c4605b77dc0286314b318865375b7
+0, 148, 148, 1, 152064, 5080b5b6bc48d21c6445b98f42ae72e8
+0, 149, 149, 1, 152064, afc35d2de20b972087e40dbb597c888a
--- /dev/null
+Testing default values
+num=0
+toggle=1
+string=default
+escape=\=,
+flags=1
+rational=1/1
+video_rate=25/1
+width=200 height=300
+pix_fmt=0bgr
+sample_fmt=s16
+duration=1000
+color=255 192 203 255
+channel_layout=311=311
+binary=62 69 6e 0
+binary_size=4
+num64=1
+flt=0.333333
+dbl=0.333333
+
+Testing av_opt_is_set_to_default()
+name: num default:1 error:
+name: toggle default:0 error:
+name: rational default:0 error:
+name: string default:0 error:
+name: escape default:0 error:
+name: flags default:0 error:
+name: cool default:1 error:Option not found
+name: lame default:1 error:Option not found
+name: mu default:1 error:Option not found
+name: size default:0 error:
+name: pix_fmt default:0 error:
+name:sample_fmt default:0 error:
+name:video_rate default:0 error:
+name: duration default:0 error:
+name: color default:0 error:
+name: cl default:0 error:
+name: bin default:0 error:
+name: bin1 default:1 error:
+name: bin2 default:1 error:
+name: num64 default:0 error:
+name: flt default:0 error:
+name: dbl default:0 error:
+name: num default:1 error:
+name: toggle default:1 error:
+name: rational default:1 error:
+name: string default:1 error:
+name: escape default:1 error:
+name: flags default:1 error:
+name: cool default:1 error:Option not found
+name: lame default:1 error:Option not found
+name: mu default:1 error:Option not found
+name: size default:1 error:
+name: pix_fmt default:1 error:
+name:sample_fmt default:1 error:
+name:video_rate default:1 error:
+name: duration default:1 error:
+name: color default:1 error:
+name: cl default:1 error:
+name: bin default:1 error:
+name: bin1 default:1 error:
+name: bin2 default:1 error:
+name: num64 default:1 error:
+name: flt default:1 error:
+name: dbl default:1 error:
+
+Test av_opt_serialize()
+num=0,toggle=1,rational=1/1,string=default,escape=\\\=\,,flags=0x00000001,size=200x300,pix_fmt=0bgr,sample_fmt=s16,video_rate=25/1,duration=0:00:00.001000,color=0xffc0cbff,cl=0x137,bin=62696E00,bin1=,bin2=,num64=1,flt=0.333333,dbl=0.333333
+num=0,toggle=1,rational=1/1,string=default,escape=\\\=\,,flags=0x00000001,size=200x300,pix_fmt=0bgr,sample_fmt=s16,video_rate=25/1,duration=0:00:00.001000,color=0xffc0cbff,cl=0x137,bin=62696E00,bin1=,bin2=,num64=1,flt=0.333333,dbl=0.333333
+
+Testing av_set_options_string()
+OK ''
+Error ':'
+Error '='
+Error 'foo=:'
+Error ':=foo'
+Error '=foo'
+Error 'foo='
+Error 'foo'
+Error 'foo=val'
+Error 'foo==val'
+Error 'toggle=:'
+OK 'string=:'
+Error 'toggle=1 : foo'
+Error 'toggle=100'
+Error 'toggle==1'
+OK 'flags=+mu-lame : num=42: toggle=0'
+OK 'num=42 : string=blahblah'
+Error 'rational=0 : rational=1/2 : rational=1/-1'
+Error 'rational=-1/0'
+OK 'size=1024x768'
+OK 'size=pal'
+Error 'size=bogus'
+OK 'pix_fmt=yuv420p'
+OK 'pix_fmt=2'
+Error 'pix_fmt=bogus'
+OK 'sample_fmt=s16'
+OK 'sample_fmt=2'
+Error 'sample_fmt=bogus'
+OK 'video_rate=pal'
+OK 'video_rate=25'
+OK 'video_rate=30000/1001'
+OK 'video_rate=30/1.001'
+Error 'video_rate=bogus'
+Error 'duration=bogus'
+OK 'duration=123.45'
+OK 'duration=1\:23\:45.67'
+OK 'color=blue'
+OK 'color=0x223300'
+OK 'color=0x42FF07AA'
+OK 'cl=stereo+downmix'
+Error 'cl=foo'
+Error 'bin=boguss'
+Error 'bin=111'
+OK 'bin=ffff'
+Error 'num64=bogus'
+OK 'num64=44'
+OK 'num64=44.4'
+Error 'num64=-1'
+Error 'num64=101'
+Error 'flt=bogus'
+OK 'flt=2'
+OK 'flt=2.2'
+Error 'flt=-1'
+Error 'flt=101'
+Error 'dbl=bogus'
+OK 'dbl=2'
+OK 'dbl=2.2'
+Error 'dbl=-1'
+Error 'dbl=101'
+
+Testing av_opt_set_from_string()
+OK ''
+OK '5'
+OK '5:hello'
+OK '5:hello:size=pal'
+Error '5:size=pal:hello'
+Error ':'
+Error '='
+OK ' 5 : hello : size = pal '
+Error 'a_very_long_option_name_that_will_need_to_be_ellipsized_around_here=42'
--- /dev/null
+#tb 0: 1/8000
+0, 0, 0, 160, 320, 0x00000000
+0, 160, 160, 160, 320, 0x4cfd5d74
+0, 320, 320, 160, 320, 0xbb60fa3d
+0, 480, 480, 160, 320, 0x4d75097c
+0, 640, 640, 160, 320, 0x59cbd3b4
+0, 800, 800, 160, 320, 0x0bcddb40
+0, 960, 960, 160, 320, 0x3d8ec98a
+0, 1120, 1120, 160, 320, 0x3612b700
+0, 1280, 1280, 160, 320, 0x23cfb9b6
+0, 1440, 1440, 160, 320, 0xd339c9a5
+0, 1600, 1600, 160, 320, 0xffb6b7c9
+0, 1760, 1760, 160, 320, 0x8730ac48
+0, 1920, 1920, 160, 320, 0x1568b279
+0, 2080, 2080, 160, 320, 0xf2229fda
+0, 2240, 2240, 160, 320, 0x91c0adbf
+0, 2400, 2400, 160, 320, 0xe261a238
+0, 2560, 2560, 160, 320, 0x5c0d97c6
+0, 2720, 2720, 160, 320, 0x32d492de
+0, 2880, 2880, 160, 320, 0x46a3af81
+0, 3040, 3040, 160, 320, 0xf8deaa2e
+0, 3200, 3200, 160, 320, 0x48649866
+0, 3360, 3360, 160, 320, 0x4cb2a03e
+0, 3520, 3520, 160, 320, 0x55e9a3d7
+0, 3680, 3680, 160, 320, 0xc60d9cf8
+0, 3840, 3840, 160, 320, 0x969098b8
+0, 4000, 4000, 160, 320, 0xe00b9f43
+0, 4160, 4160, 160, 320, 0x85c6af06
+0, 4320, 4320, 160, 320, 0x2037a849
+0, 4480, 4480, 160, 320, 0xd8e09379
+0, 4640, 4640, 160, 320, 0x5df69e34
+0, 4800, 4800, 160, 320, 0x95869c06
+0, 4960, 4960, 160, 320, 0x651c95a7
+0, 5120, 5120, 160, 320, 0xd433a2f4
+0, 5280, 5280, 160, 320, 0xc6c1a0e2
+0, 5440, 5440, 160, 320, 0x6cad9e61
+0, 5600, 5600, 160, 320, 0x57f5ab36
+0, 5760, 5760, 160, 320, 0x11fd9788
+0, 5920, 5920, 160, 320, 0x805db795
+0, 6080, 6080, 160, 320, 0xb306a36b
+0, 6240, 6240, 160, 320, 0xa34d9933
+0, 6400, 6400, 160, 320, 0xbc24a23c
+0, 6560, 6560, 160, 320, 0x6639a03c
+0, 6720, 6720, 160, 320, 0x4f20ab13
+0, 6880, 6880, 160, 320, 0xe30ca2bb
+0, 7040, 7040, 160, 320, 0x51e5ac4f
+0, 7200, 7200, 160, 320, 0x2a369ff4
+0, 7360, 7360, 160, 320, 0xfbffaa78
+0, 7520, 7520, 160, 320, 0xf117a04f
+0, 7680, 7680, 160, 320, 0x36479938
+0, 7840, 7840, 160, 320, 0xd1269299
-47834efc39225264e705dfb885f57df2
+[Script Info]\r
+; Script generated by FFmpeg/Lavc\r
+ScriptType: v4.00+\r
+PlayResX: 384\r
+PlayResY: 288\r
+\r
+[V4+ Styles]\r
+Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding\r
+Style: Default,Arial,16,&Hffffff,&Hffffff,&H0,&H0,0,0,0,0,100,100,0,0,1,1,0,2,10,10,10,0\r
+\r
+[Events]\r
+Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text\r
+Dialogue: 0,0:03:29.92,0:03:31.28,Default,,0,0,0,,Dougu?\r
+Dialogue: 0,0:03:33.36,0:03:35.76,Default,,0,0,0,,Zlato, jseš v pořádku?\r
+Dialogue: 0,0:03:37.72,0:03:39.12,Default,,0,0,0,,Měl jsi sny.\r
+Dialogue: 0,0:03:41.44,0:03:43.32,Default,,0,0,0,,Byly o Marsu?\r
+Dialogue: 0,0:03:48.92,0:03:50.52,Default,,0,0,0,,Je to lepší?\r
+Dialogue: 0,0:03:53.12,0:03:54.72,Default,,0,0,0,,Chudinko moje.\r
+Dialogue: 0,0:03:55.76,0:03:58.08,Default,,0,0,0,,Začíná to být\Nposedlost.\r
+Dialogue: 0,0:04:05.92,0:04:07.16,Default,,0,0,0,,Byla tam i ona?\r
+Dialogue: 0,0:04:09.12,0:04:10.48,Default,,0,0,0,,Kdo?\r
+Dialogue: 0,0:04:12.44,0:04:15.16,Default,,0,0,0,,Ta, o které jsi mi vyprávěl.\NTa bruneta.\r
+Dialogue: 0,0:04:16.32,0:04:17.52,Default,,0,0,0,,Lori.\r
+Dialogue: 0,0:04:20.32,0:04:23.16,Default,,0,0,0,,Nemůžu uvěřit\Nže žárlíš na sen.\r
+Dialogue: 0,0:04:23.84,0:04:26.60,Default,,0,0,0,,- Kdo je ona?\N- Nikdo.\r
+Dialogue: 0,0:04:26.60,0:04:28.80,Default,,0,0,0,,"Nikdo"? Jak se jmenuje?\r
+Dialogue: 0,0:04:28.80,0:04:30.24,Default,,0,0,0,,Nevím.\r
+Dialogue: 0,0:04:31.52,0:04:33.20,Default,,0,0,0,,- Pověz!\N- Nevím!\r
+Dialogue: 0,0:04:33.20,0:04:35.48,Default,,0,0,0,,Radši bys mi to měl říct!\r
+Dialogue: 0,0:04:35.48,0:04:39.16,Default,,0,0,0,,To není legrace Dougu.\NZdá se ti o ní každou noc.\r
+Dialogue: 0,0:04:39.16,0:04:41.84,Default,,0,0,0,,Ale vždy se ráno probudím.\r
+Dialogue: 0,0:04:41.84,0:04:43.28,Default,,0,0,0,,Nech mě být!\r
+Dialogue: 0,0:04:45.72,0:04:47.76,Default,,0,0,0,,No tak, zlato.\r
+Dialogue: 0,0:04:47.76,0:04:50.72,Default,,0,0,0,,Ty víš, že jsi dívkou\Nmých snů.\r
+Dialogue: 0,0:04:50.72,0:04:52.40,Default,,0,0,0,,Myslíš to vážně?\r
+Dialogue: 0,0:04:53.48,0:04:55.32,Default,,0,0,0,,To víš že ano.\r
+Dialogue: 0,0:05:04.40,0:05:07.20,Default,,0,0,0,,Dám ti něco\No čem budeš snít.\r
+Dialogue: 0,0:05:16.76,0:05:16.92,Default,,0,0,0,,Premiér se útoku ubránil\Na řekl, že zbraně založené na vesmírných...\r
+Dialogue: 0,0:05:16.92,0:05:20.36,Default,,0,0,0,,Premiér se útoku ubránil\Na řekl, že zbraně založené na vesmírných...\r
+Dialogue: 0,0:05:20.36,0:05:24.36,Default,,0,0,0,,jsou naše jediná obrana proti\Npočetní převaze z jižního bloku.\r
+Dialogue: 0,0:05:24.36,0:05:26.76,Default,,0,0,0,,A další násilí na Marsu...\r
+Dialogue: 0,0:05:26.76,1:44:16.00,Default,,0,0,0,,[...]\r
+Dialogue: 0,1:44:16.00,1:44:17.60,Default,,0,0,0,,Co se děje?\r
+Dialogue: 0,1:44:17.60,1:44:21.28,Default,,0,0,0,,Měl jsem jenom hroznou představu.\NCo když tohle je jenom sen?\r
+Dialogue: 0,1:44:22.76,1:44:25.68,Default,,0,0,0,,Tak mi dej ryhcle pusu\Nnež se probudíš.\r
-c088c2924fd7af0a53eeeeb54a3f4456
+[Script Info]\r
+; Script generated by FFmpeg/Lavc\r
+ScriptType: v4.00+\r
+PlayResX: 384\r
+PlayResY: 288\r
+\r
+[V4+ Styles]\r
+Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding\r
+Style: Default,Arial,16,&Hffffff,&Hffffff,&H0,&H0,0,0,0,0,100,100,0,0,1,1,0,2,10,10,10,0\r
+\r
+[Events]\r
+Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text\r
+Dialogue: 0,0:00:32.95,0:00:38.25,Default,,0,0,0,,КОЛУМБИА ПИКЧЪРС - АЗИЯ\NСОНИ ПИКЧЪРС и Е.Е. Co.\Nпредставят\r
+Dialogue: 0,0:00:52.76,0:00:58.60,Default,,0,0,0,,Т И Г Ъ Р И Д Р А К О Н\r
+Dialogue: 0,0:01:22.17,0:01:24.05,Default,,0,0,0,,Учителят Ли е тук.\r
+Dialogue: 0,0:01:45.48,0:01:47.32,Default,,0,0,0,,Шу Лиен!\r
+Dialogue: 0,0:01:54.53,0:01:57.24,Default,,0,0,0,,Ли Му Бай е тук.\r
+Dialogue: 0,0:02:05.83,0:02:09.00,Default,,0,0,0,,- Как вървят нещата?\N- Добре. Моля, влезте!\r
+Dialogue: 0,0:02:23.48,0:02:26.52,Default,,0,0,0,,Му Бай...\NМина много време.\r
+Dialogue: 0,0:02:26.73,0:02:28.11,Default,,0,0,0,,Така е.\r
+Dialogue: 0,0:02:28.57,0:02:31.41,Default,,0,0,0,,- Как върви бизнесът?\N- Добре.\r
+Dialogue: 0,0:02:31.61,0:02:33.90,Default,,0,0,0,,- А ти как си?\N- Добре.\r
+Dialogue: 0,0:02:40.16,0:02:42.79,Default,,0,0,0,,Монахът Дзенг каза,\Nче си в планината Удан.\r
+Dialogue: 0,0:02:43.04,0:02:46.54,Default,,0,0,0,,Каза, че практикуваш\Nдълбока медитация.\r
+Dialogue: 0,0:02:48.84,0:02:50.68,Default,,0,0,0,,Сигурно в планината\Nе много спокойно.\r
+Dialogue: 0,0:02:51.25,0:02:53.46,Default,,0,0,0,,Завиждам ти.\r
+Dialogue: 0,0:02:53.67,0:02:58.34,Default,,0,0,0,,Имам толкова много работа,\Nпочти не ми остава\Nвреме за почивка.\r
+Dialogue: 0,0:03:00.26,0:03:03.89,Default,,0,0,0,,Оставих обучението рано.\r
+Dialogue: 0,0:03:05.69,0:03:11.28,Default,,0,0,0,,Защо? Ти си боец на Удан.\NОбучението е всичко.\r
+Dialogue: 0,0:03:11.90,0:03:14.86,Default,,0,0,0,,По време на медитация…\r
+Dialogue: 0,0:03:15.07,0:03:18.49,Default,,0,0,0,,стигнах до място,\Nкъдето имаше дълбока тишина...\r
+Dialogue: 0,0:03:19.87,0:03:22.79,Default,,0,0,0,,бях обграден от светлина...\r
+Dialogue: 0,0:03:23.41,0:03:28.08,Default,,0,0,0,,времето и пространството изчезнаха.\r
+Dialogue: 0,0:03:28.71,0:03:34.09,Default,,0,0,0,,Достигнах до състояние, за което\Nучителят не ми беше казвал.\r
+Dialogue: 0,0:03:37.05,0:03:39.14,Default,,0,0,0,,Постигнал си просветление?\r
+Dialogue: 0,0:03:39.34,0:03:41.22,Default,,0,0,0,,Не.\r
+Dialogue: 0,0:03:41.72,0:03:45.81,Default,,0,0,0,,Не почувствах блаженството\Nна просветлението.\r
+Dialogue: 0,0:03:46.02,0:03:52.86,Default,,0,0,0,,Вместо това... ме обгърна\Nбезкрайна мъка.\r
+Dialogue: 0,0:03:53.40,0:03:56.57,Default,,0,0,0,,Не можах да издържа.\r
+Dialogue: 0,0:03:57.49,0:03:59.74,Default,,0,0,0,,Прекъснах медитацията си.\r
+Dialogue: 0,0:03:59.95,0:04:02.24,Default,,0,0,0,,Не можах да продължа.\r
+Dialogue: 0,0:04:03.20,0:04:07.79,Default,,0,0,0,,Нещо...\Nме дърпаше назад.\r
+Dialogue: 0,0:04:09.62,0:04:10.91,Default,,0,0,0,,Какво беше?\r
+Dialogue: 0,0:04:15.46,0:04:18.00,Default,,0,0,0,,Нещо, от което не\Nмога да се освободя.\r
+Dialogue: 0,0:04:23.39,0:04:24.68,Default,,0,0,0,,Скоро ли ще тръгваш?\r
+Dialogue: 0,0:04:26.77,0:04:30.27,Default,,0,0,0,,Подготвяме охрана\Nза една доставка...\r
+Dialogue: 0,0:04:30.48,0:04:31.94,Default,,0,0,0,,за Пекин.\r
+Dialogue: 0,0:04:32.56,0:04:34.10,Default,,0,0,0,,Мога ли да те помоля...\r
+Dialogue: 0,0:04:35.07,0:04:38.82,Default,,0,0,0,,да занесеш нещо на господин Те.\r
+Dialogue: 0,0:04:44.28,0:04:48.12,Default,,0,0,0,,Зеленият меч на Съдбата!?\NДаваш го на господин Те!?\r
+Dialogue: 0,0:04:48.37,0:04:52.67,Default,,0,0,0,,Да. Той винаги е бил\Nнашият най-голям покровител.\r
+Dialogue: 0,0:04:52.88,0:04:56.55,Default,,0,0,0,,Не разбирам.\NКак можеш да се разделиш с него?\r
+Dialogue: 0,0:04:56.76,0:04:59.93,Default,,0,0,0,,Той винаги е бил с теб.\r
+Dialogue: 0,0:05:01.18,0:05:05.52,Default,,0,0,0,,Твърде много хора са\Nзагинали от това острие.\r
+Dialogue: 0,0:05:09.68,0:05:14.52,Default,,0,0,0,,Чисто е единствено защото\Nкръвта се отмива лесно.\r
+Dialogue: 0,0:05:15.40,0:05:20.61,Default,,0,0,0,,Ти го използваш справедливо.\NДостоен си за него.\r
+Dialogue: 0,0:05:23.66,0:05:27.37,Default,,0,0,0,,Дойде време\Nда го оставя.\r
+Dialogue: 0,0:05:27.58,0:05:31.21,Default,,0,0,0,,Е, какво ще правиш\Nот сега нататък?\r
+Dialogue: 0,0:05:34.71,0:05:37.50,Default,,0,0,0,,Ела с мен в Пекин.\r
+Dialogue: 0,0:05:37.71,0:05:41.42,Default,,0,0,0,,Лично ще дадеш меча\Nна господин Те.\r
+Dialogue: 0,0:05:41.68,0:05:44.89,Default,,0,0,0,,Ще бъде както преди.\r
+Dialogue: 0,0:05:47.01,0:05:51.68,Default,,0,0,0,,Първо трябва да отида\Nна гроба на учителя си.\r
-3bf9f062bd9825c7d8c3b62451b6d360
+[Script Info]\r
+; Script generated by FFmpeg/Lavc\r
+ScriptType: v4.00+\r
+PlayResX: 384\r
+PlayResY: 288\r
+\r
+[V4+ Styles]\r
+Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding\r
+Style: Default,Arial,16,&Hffffff,&Hffffff,&H0,&H0,0,0,0,0,100,100,0,0,1,1,0,2,10,10,10,0\r
+\r
+[Events]\r
+Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text\r
+Dialogue: 0,0:00:00.12,0:00:04.36,Default,,0,0,0,,{\an5}JACOsub\N\NThis script demonstrates some of the capabilities of JACOsub.\r
+Dialogue: 0,0:00:04.12,0:00:14.86,Default,,0,0,0,,{\an8}Text may be positioned at the top,\r
+Dialogue: 0,0:00:05.12,0:00:17.46,Default,,0,0,0,,{\an5}middle,\r
+Dialogue: 0,0:00:06.12,0:00:20.06,Default,,0,0,0,,{\an2}or bottom of the screen.\r
+Dialogue: 0,0:00:08.12,0:00:27.36,Default,,0,0,0,,{\an5}{this is a comment} (And, you just saw, {another comment} timing ranges for different lines of text.\r
+Dialogue: 0,0:00:11.12,0:00:35.86,Default,,0,0,0,,{\an1}Within margin constraints\Nthat you set, text may be\Nleft justified,\r
+Dialogue: 0,0:00:13.62,0:00:42.11,Default,,0,0,0,,{\an2}{the JC is redundant - it's the default}center\Njustified,\r
+Dialogue: 0,0:00:14.87,0:00:45.86,Default,,0,0,0,,{\an3}and also\Nright justified.\r
+Dialogue: 0,0:00:22.42,0:01:12.76,Default,,0,0,0,,Text may appear in different styles\N(Normal, {\b1}Bold{\r}, {\i1}Italic{\r})\r
+Dialogue: 0,0:01:16.12,0:03:53.36,Default,,0,0,0,,{\an5}\N\NAt that time, you may press any key to return to the Editor.\r
+Dialogue: 0,0:01:16.12,0:03:53.36,Default,,0,0,0,,OK, this script will be finished when the screen goes blank.\r
-1741d6776462277430d5e320157f5bf9
+[Script Info]\r
+; Script generated by FFmpeg/Lavc\r
+ScriptType: v4.00+\r
+PlayResX: 384\r
+PlayResY: 288\r
+\r
+[V4+ Styles]\r
+Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding\r
+Style: Default,Comic Sans MS,30,&H123456,&H123456,&H0,&H0,0,0,0,0,100,100,0,0,1,1,0,2,10,10,10,0\r
+\r
+[Events]\r
+Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text\r
+Dialogue: 0,0:00:00.00,0:00:40.00,Default,,0,0,0,,25.000 FPS\r
+Dialogue: 0,0:00:40.00,0:00:52.00,Default,,0,0,0,,{\c&H345678&}foo{\c}\N{\c&HABCDEF&}bar{\c}\Nbla\r
+Dialogue: 0,0:00:52.00,0:00:56.00,Default,,0,0,0,,{\u1}{\s1}{\i1}{\b1}italic bold underline strike{\s0}{\u0}\Nitalic bold no-underline no-strike\r
+Dialogue: 0,0:00:56.00,0:01:00.00,Default,,0,0,0,,back to\r
+Dialogue: 0,0:01:00.00,0:01:04.00,Default,,0,0,0,,the future\r
+Dialogue: 0,0:01:20.00,0:01:24.92,Default,,0,0,0,,{\pos(10,20)}Some more crazy stuff\r
+Dialogue: 0,0:02:14.00,0:02:15.60,Default,,0,0,0,,this subtitle...\r
+Dialogue: 0,0:02:15.60,0:02:40.00,Default,,0,0,0,,...continues up to...\r
+Dialogue: 0,0:02:40.00,0:03:00.00,Default,,0,0,0,,this one.\r
+Dialogue: 0,0:03:04.00,0:03:12.00,Default,,0,0,0,,and now...\r
+Dialogue: 0,0:03:12.00,9:59:59.99,Default,,0,0,0,,...to the end of the presentation\r
-24c02caa25c6a82d803171697a10d8f5
+[Script Info]\r
+; Script generated by FFmpeg/Lavc\r
+ScriptType: v4.00+\r
+PlayResX: 384\r
+PlayResY: 288\r
+\r
+[V4+ Styles]\r
+Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding\r
+Style: Default,Arial,16,&Hffffff,&Hffffff,&H0,&H0,0,0,0,0,100,100,0,0,1,1,0,2,10,10,10,0\r
+\r
+[Events]\r
+Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text\r
+Dialogue: 0,0:00:00.97,0:00:02.54,Default,,0,0,0,,- Test 1.\N- Test 2.\r
+Dialogue: 0,0:00:03.05,0:00:04.74,Default,,0,0,0,,Test 3.\r
+Dialogue: 0,0:00:05.85,0:00:08.14,Default,,0,0,0,,- Test 4.\N- Test 5.\r
-3c685e807d4961924d0abcc18b3f8fa8
+bb762c178bd8c437a9101c748c1ccb4d
-28fb7dad61c3394f5edc8b186fdf7dd6
+[Script Info]\r
+; Script generated by FFmpeg/Lavc\r
+ScriptType: v4.00+\r
+PlayResX: 384\r
+PlayResY: 288\r
+\r
+[V4+ Styles]\r
+Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding\r
+Style: Default,Arial,16,&Hffffff,&Hffffff,&H0,&H0,0,0,0,0,100,100,0,0,1,1,0,2,10,10,10,0\r
+\r
+[Events]\r
+Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text\r
+Dialogue: 0,0:00:00.00,0:00:01.20,Default,,0,0,0,,Foo\Nbar\Nbla\r
+Dialogue: 0,0:00:04.10,0:00:05.30,Default,,0,0,0,,{\i1}italic{\r}\N{\b1}bold{\r}\N{\b1}{\i1}italicbold\r
+Dialogue: 0,0:00:05.30,0:00:07.20,Default,,0,0,0,,{\u1}underline{\r}\Nnormal\r
+Dialogue: 0,0:00:08.40,0:00:12.80,Default,,0,0,0,,hello\r
-2f10577c4e2631e9a50495fa2cc9a985
+[Script Info]\r
+; Script generated by FFmpeg/Lavc\r
+ScriptType: v4.00+\r
+PlayResX: 384\r
+PlayResY: 288\r
+\r
+[V4+ Styles]\r
+Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding\r
+Style: Default,Arial,16,&Hffffff,&Hffffff,&H0,&H0,0,0,0,0,100,100,0,0,1,1,0,2,10,10,10,0\r
+\r
+[Events]\r
+Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text\r
+Dialogue: 0,0:00:15.00,0:00:18.00,Default,,0,0,0,,A long, long time ago...\r
+Dialogue: 0,0:00:18.00,0:00:21.00,Default,,0,0,0,,in a galaxy far away...\r
+Dialogue: 0,0:00:21.00,0:00:24.00,Default,,0,0,0,,Naboo was under an attack.\r
+Dialogue: 0,0:00:25.00,0:00:27.50,Default,,0,0,0,,And I thought me and\NQui-Gon Jinn could\r
+Dialogue: 0,0:00:27.50,0:00:30.00,Default,,0,0,0,,talk the Federation into\r
+Dialogue: 0,0:00:30.00,0:00:34.00,Default,,0,0,0,,...maybe cutting them a\Nlittle slack.\r
+Dialogue: 0,0:00:36.00,0:00:39.00,Default,,0,0,0,,But their response, it\Ndidn't thrill us,\r
+Dialogue: 0,0:00:39.00,0:00:42.00,Default,,0,0,0,,They locked the doors,\Nand tried to kill us.\r
+Dialogue: 0,0:00:42.00,0:00:44.50,Default,,0,0,0,,We escaped from that gas,\r
+Dialogue: 0,0:00:44.50,0:00:48.00,Default,,0,0,0,,then met Jar-jar and\NBoss-Nass.\r
+Dialogue: 0,0:00:49.00,0:00:55.00,Default,,0,0,0,,We took a bongo from the\Nscene and we went to\NTheed to see the Queen.\r
+Dialogue: 0,0:00:55.00,0:01:00.00,Default,,0,0,0,,We all wound' up on\NTatooine.\r
+Dialogue: 0,0:01:00.00,0:01:06.00,Default,,0,0,0,,That's where, we've found\Nthis boy.\r
+Dialogue: 0,0:01:06.00,0:01:10.00,Default,,0,0,0,,Oh my, my this here\NAnakin guy,\r
+Dialogue: 0,0:01:10.00,0:01:15.00,Default,,0,0,0,,maybe Vader someday\Nlater now he's just\Na small fry.\r
+Dialogue: 0,0:01:15.00,0:01:19.00,Default,,0,0,0,,And he left his home and\Nkissed his mommy goodbye,\r
+Dialogue: 0,0:01:19.00,0:01:24.00,Default,,0,0,0,,singing "Soon I'm gonna be\Na Jedi!"\r
+Dialogue: 0,0:01:30.00,0:01:36.00,Default,,0,0,0,,Did you know this junkyard\Nslave isn't even old enough\Nto shave,\r
+Dialogue: 0,0:01:36.00,0:01:39.00,Default,,0,0,0,,but he can use the Force,\Nthey say.\r
+Dialogue: 0,0:01:40.00,0:01:46.00,Default,,0,0,0,,Ahh, do you see him hitting\Non the queen though he's\Njust nine and she's fourteen\r
+Dialogue: 0,0:01:46.00,0:01:52.00,Default,,0,0,0,,yeah, he's probably gonna\Nmarry her, someday!\r
-792dab5d9a471e0381e18b705fc408cc
+[Script Info]\r
+; Script generated by FFmpeg/Lavc\r
+ScriptType: v4.00+\r
+PlayResX: 384\r
+PlayResY: 288\r
+\r
+[V4+ Styles]\r
+Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding\r
+Style: Default,Arial,16,&Hffffff,&Hffffff,&H0,&H0,0,0,0,0,100,100,0,0,1,1,0,2,10,10,10,0\r
+\r
+[Events]\r
+Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text\r
+Dialogue: 0,0:00:01.00,0:00:02.48,Default,,0,0,0,,Start at 1sec,\Nlast 1.5 seconds\r
+Dialogue: 0,0:00:02.52,0:00:11.52,Default,,0,0,0,,One frame later,\Nduring 9 seconds\r
-a335eefaf09b3b148e65c757bf41af4d
+[Script Info]\r
+; Script generated by FFmpeg/Lavc\r
+ScriptType: v4.00+\r
+PlayResX: 384\r
+PlayResY: 288\r
+\r
+[V4+ Styles]\r
+Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding\r
+Style: Default,Arial,16,&Hffffff,&Hffffff,&H0,&H0,0,0,0,0,100,100,0,0,1,1,0,2,10,10,10,0\r
+\r
+[Events]\r
+Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text\r
+Dialogue: 0,0:04:04.70,0:04:11.30,Default,,0,0,0,,You should come to the Drama Club, too.\r
+Dialogue: 0,0:04:11.30,0:04:19.40,Default,,0,0,0,,Yeah. The Drama Club is worried\Nthat you haven't been coming.\r
+Dialogue: 0,0:04:20.30,0:04:27.50,Default,,0,0,0,,I see. Sorry, I'll drop by next time.\r
-a36977a149ce60eac443e4c9bb329ca2
+[Script Info]\r
+; Script generated by FFmpeg/Lavc\r
+ScriptType: v4.00+\r
+PlayResX: 384\r
+PlayResY: 288\r
+\r
+[V4+ Styles]\r
+Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding\r
+Style: Default,Arial,16,&Hffffff,&Hffffff,&H0,&H0,0,0,0,0,100,100,0,0,1,1,0,2,10,10,10,0\r
+\r
+[Events]\r
+Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text\r
+Dialogue: 0,0:00:00.00,0:00:00.00,Default,,0,0,0,,Mary had a little lamb, \N\r
+Dialogue: 0,0:00:03.00,0:00:18.00,Default,,0,0,0,,little lamb, \N\r
+Dialogue: 0,0:00:06.99,0:00:21.99,Default,,0,0,0,,little lamb, \N\r
+Dialogue: 0,0:00:09.00,0:00:23.00,Default,,0,0,0,,Mary had a little lamb \N\r
+Dialogue: 0,0:00:12.34,0:00:27.34,Default,,0,0,0,,whose fleece was white as snow. \r
-04098faede85ddacb40aa12c798cc0cc
+[Script Info]\r
+; Script generated by FFmpeg/Lavc\r
+ScriptType: v4.00+\r
+PlayResX: 384\r
+PlayResY: 288\r
+\r
+[V4+ Styles]\r
+Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding\r
+Style: Default,Arial,16,&Hffffff,&Hffffff,&H0,&H0,0,0,0,0,100,100,0,0,1,1,0,2,10,10,10,0\r
+\r
+[Events]\r
+Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text\r
+Dialogue: 0,0:00:00.00,0:00:00.01,Default,,0,0,0,,{\i1}Pres. John F. Kennedy {\i0}\N\r
+Dialogue: 0,0:00:00.01,0:00:08.80,Default,,0,0,0,,{\i1}Pres. John F. Kennedy {\i0}\NLet the word go forth, from this time and place to friend and foe alike that the torch \r
+Dialogue: 0,0:00:08.80,0:00:19.50,Default,,0,0,0,,{\i1}Pres. John F. Kennedy {\i0}\Nhas been passed to a new generation of Americans, born in this century, tempered by war, \r
+Dialogue: 0,0:00:19.50,0:00:28.00,Default,,0,0,0,,{\i1}Pres. John F. Kennedy {\i0}\Ndisciplined by a hard and bitter peace, proud of our ancient heritage, and unwilling to witness \r
+Dialogue: 0,0:00:28.00,0:00:38.00,Default,,0,0,0,,{\i1}Pres. John F. Kennedy {\i0}\Nor permit the slow undoing of those human rights to which this nation has always \r
+Dialogue: 0,0:00:38.00,0:00:46.00,Default,,0,0,0,,{\i1}Pres. John F. Kennedy {\i0}\Nbeen committed and to which we are committed today at home and around the world. \r
+Dialogue: 0,0:00:46.00,0:01:01.00,Default,,0,0,0,,{\i1}Pres. John F. Kennedy {\i0}\NLet every nation know, whether it wishes us well or ill, that we shall pay any price, bear any burden, \r
+Dialogue: 0,0:01:01.00,0:01:13.00,Default,,0,0,0,,{\i1}Pres. John F. Kennedy {\i0}\Nmeet any hardship, support any friend, oppose any foe, to ensure the survival and success of liberty. \r
+Dialogue: 0,0:01:13.00,9:59:59.99,Default,,0,0,0,,{\i1}End of: {\i0}\NPresident John F. Kennedy Speech \r
-be870f5037933b6890d56e614ec4aa75
+[Script Info]\r
+; Script generated by FFmpeg/Lavc\r
+ScriptType: v4.00+\r
+PlayResX: 384\r
+PlayResY: 288\r
+\r
+[V4+ Styles]\r
+Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding\r
+Style: Default,Arial,16,&Hffffff,&Hffffff,&H0,&H0,0,0,0,0,100,100,0,0,1,1,0,2,10,10,10,0\r
+\r
+[Events]\r
+Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text\r
+Dialogue: 0,0:00:00.00,0:00:00.00,Default,,0,0,0,,Don't show this text it may be used to insert hidden data\r
+Dialogue: 0,0:00:01.50,0:00:04.50,Default,,0,0,0,,SubRip subtitles capability tester 1.3o by ale5000\N{\b1}{\i1}Use VLC 1.1 or higher as reference for most things and MPC Home Cinema for others{\i0}{\b0}\N{\c&HFF0000&}This text should be blue{\c}\N{\c&HFF&}This text should be red{\c}\N{\c&H0&}This text should be black{\c}\N{\fnWebdings}If you see this with the normal font, the player don't (fully) support font face{\fn}\r
+Dialogue: 0,0:00:04.50,0:00:04.50,Default,,0,0,0,,Hidden\r
+Dialogue: 0,0:00:04.50,0:00:07.50,Default,,0,0,0,,{\fs8}This text should be small{\fs}\NThis text should be normal\N{\fs35}This text should be big{\fs}\r
+Dialogue: 0,0:00:07.50,0:00:11.50,Default,,0,0,0,,This should be an E with an accent: È\N日本語\N{\fs30}{\b1}{\i1}{\u1}This text should be bold, italics and underline{\u0}{\i0}{\b0}{\fs}\N{\fs9}{\c&HFF00&}This text should be small and green{\c}{\fs}\N{\fs9}{\c&HFF&}This text should be small and red{\c}{\fs}\N{\fs24}{\c&H2A2AA5&}This text should be big and brown{\c}{\fs}\r
+Dialogue: 0,0:00:11.50,0:00:14.50,Default,,0,0,0,,{\b1}This line should be bold{\b0}\N{\i1}This line should be italics{\i0}\N{\u1}This line should be underline{\u0}\N{\s1}This line should be strikethrough{\s0}\N{\u1}Both lines\Nshould be underline{\u0}\r
+Dialogue: 0,0:00:14.50,0:00:17.50,Default,,0,0,0,,>\NIt would be a good thing to\Nhide invalid html tags that are closed and show the text in them\N<invalid_tag_unclosed>but show un-closed invalid html tags\NShow not opened tags</invalid_tag_not_opened>\N<\r
+Dialogue: 0,0:00:17.50,0:00:20.50,Default,,0,0,0,,and also\Nhide invalid html tags with parameters that are closed and show the text in them\N<invalid_tag_uc par=5>but show un-closed invalid html tags\N{\u1}This text should be showed underlined without problems also: 2<3,5>1,4<6{\u0}\NThis shouldn't be underlined\r
+Dialogue: 0,0:00:20.50,0:00:21.50,Default,,0,0,0,,This text should be in the normal position...\r
+Dialogue: 0,0:00:21.50,0:00:22.50,Default,,0,0,0,,{\an1}{\move(0,50,0,100)}This text should NOT be in the normal position\r
+Dialogue: 0,0:00:22.50,0:00:24.50,Default,,0,0,0,,Implementation is the same of the ASS tag\N{\an8}This text should be at the\Ntop and horizontally centered\r
+Dialogue: 0,0:00:22.50,0:00:24.50,Default,,0,0,0,,{\an5}This text should be at the\Nmiddle and horizontally centered\r
+Dialogue: 0,0:00:22.50,0:00:24.50,Default,,0,0,0,,{\an2}This text should be at the\Nbottom and horizontally centered\r
+Dialogue: 0,0:00:24.50,0:00:26.50,Default,,0,0,0,,This text should be at the\Ntop and horizontally at the left{\an7}\r
+Dialogue: 0,0:00:24.50,0:00:26.50,Default,,0,0,0,,{\an4}This text should be at the\Nmiddle and horizontally at the left\N(The second position must be ignored)\r
+Dialogue: 0,0:00:24.50,0:00:26.50,Default,,0,0,0,,{\an1}This text should be at the\Nbottom and horizontally at the left\r
+Dialogue: 0,0:00:26.50,0:00:28.50,Default,,0,0,0,,{\an9}This text should be at the\Ntop and horizontally at the right\r
+Dialogue: 0,0:00:26.50,0:00:28.50,Default,,0,0,0,,{\an6}This text should be at the\Nmiddle and horizontally at the right\r
+Dialogue: 0,0:00:26.50,0:00:28.50,Default,,0,0,0,,{\an3}This text should be at the\Nbottom and horizontally at the right\r
+Dialogue: 0,0:00:28.50,0:00:31.50,Default,,0,0,0,,{\fs6}{\c&HFF00&}This could be the {\fs35}m{\c&H0&}o{\c&HFF00&}st{\fs6} difficult thing to implement{\c}{\fs}\r
+Dialogue: 0,0:00:31.50,0:00:50.50,Default,,0,0,0,,First text\r
+Dialogue: 0,0:00:33.50,0:00:35.50,Default,,0,0,0,,Second, it shouldn't overlap first\r
+Dialogue: 0,0:00:35.50,0:00:37.50,Default,,0,0,0,,Third, it should replace second\r
+Dialogue: 0,0:00:36.50,0:00:50.50,Default,,0,0,0,,Fourth, it shouldn't overlap first and third\r
+Dialogue: 0,0:00:40.50,0:00:45.50,Default,,0,0,0,,Fifth, it should replace third\r
+Dialogue: 0,0:00:45.50,0:00:50.50,Default,,0,0,0,,Sixth, it shouldn't be\Nshowed overlapped\r
+Dialogue: 0,0:00:50.50,0:00:52.50,Default,,0,0,0,,TEXT 1 (bottom)\r
+Dialogue: 0,0:00:50.50,0:00:52.50,Default,,0,0,0,,text 2\r
+Dialogue: 0,0:00:52.50,0:00:54.50,Default,,0,0,0,,Hide these tags:\Nalso hide these tags:\Nbut show this: {normal text}\r
+Dialogue: 0,0:00:54.50,0:01:00.50,Default,,0,0,0,,{\an8}\N\ N is a forced line break\N\ h is a hard space\NNormal spaces at the start and at the end of the line are trimmed while hard spaces are not trimmed.\NThe\hline\hwill\hnever\hbreak\hautomatically\hright\hbefore\hor\hafter\ha\hhard\hspace.\h:-D\r
+Dialogue: 0,0:00:54.50,0:00:56.50,Default,,0,0,0,,{\an1}\N\h\h\h\h\hA (05 hard spaces followed by a letter)\NA (Normal spaces followed by a letter)\NA (No hard spaces followed by a letter)\r
+Dialogue: 0,0:00:56.50,0:00:58.50,Default,,0,0,0,,\h\h\h\h\hA (05 hard spaces followed by a letter)\NA (Normal spaces followed by a letter)\NA (No hard spaces followed by a letter)\NShow this: \TEST and this: \-)\r
+Dialogue: 0,0:00:58.50,0:01:00.50,Default,,0,0,0,,{\an3}\NA letter followed by 05 hard spaces: A\h\h\h\h\h\NA letter followed by normal spaces: A\NA letter followed by no hard spaces: A\N05 hard spaces between letters: A\h\h\h\h\hA\N5 normal spaces between letters: A A\N\N^--Forced line break\r
+Dialogue: 0,0:01:00.50,0:01:02.50,Default,,0,0,0,,{\s1}Both line should be strikethrough,\Nyes.{\s0}\NCorrectly closed tags\Nshould be hidden.\r
+Dialogue: 0,0:01:02.50,0:01:04.50,Default,,0,0,0,,It shouldn't be strikethrough,\Nnot opened tag showed as text.</s>\NNot opened tag showed as text.</xxxxx>\r
+Dialogue: 0,0:01:04.50,0:01:06.50,Default,,0,0,0,,{\s1}Three lines should be strikethrough,\Nyes.\N<yyyy>Not closed tags showed as text\r
+Dialogue: 0,0:01:06.50,0:01:08.50,Default,,0,0,0,,{\s1}Both line should be strikethrough but\Nthe wrong closing tag should be showed</b>\r
--- /dev/null
+[Script Info]\r
+; Script generated by FFmpeg/Lavc\r
+ScriptType: v4.00+\r
+PlayResX: 384\r
+PlayResY: 288\r
+\r
+[V4+ Styles]\r
+Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding\r
+Style: Default,Arial,16,&Hffffff,&Hffffff,&H0,&H0,0,0,0,0,100,100,0,0,1,1,0,2,10,10,10,0\r
+\r
+[Events]\r
+Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text\r
+Dialogue: 0,0:00:31.02,0:00:33.00,Default,,0,0,0,,Hello, my name is Axel Kornmesser.\r
+Dialogue: 0,0:00:45.02,0:00:49.13,Default,,0,0,0,,It is always a pleasure to work with ESA astronomers.\r
+Dialogue: 0,0:00:49.13,0:00:52.03,Default,,0,0,0,,The "Eyes on The Skies" documentary\r
+Dialogue: 0,0:00:52.03,0:00:55.09,Default,,0,0,0,,was our second collaboration\r
+Dialogue: 0,0:00:55.09,0:00:58.07,Default,,0,0,0,,after a great \Nexperience in 2005,\r
+Dialogue: 0,0:00:58.07,0:00:59.20,Default,,0,0,0,,when \Nwe did the story about the\r
+Dialogue: 0,0:00:59.20,0:01:04.01,Default,,0,0,0,,Hubble Telescope "15 Years of Discovery".\r
+Dialogue: 0,0:01:04.16,0:01:07.04,Default,,0,0,0,,It was a lot of fun again.\r
+Dialogue: 0,0:01:15.04,0:01:18.16,Default,,0,0,0,,We usually \N don't get the final film \Nbefore we start composing\r
+Dialogue: 0,0:01:18.21,0:01:22.02,Default,,0,0,0,,We had a script and many details about the story,\r
+Dialogue: 0,0:01:22.10,0:01:26.08,Default,,0,0,0,,and so we worked\N in parallel \Nin the movie production\r
+Dialogue: 0,0:01:27.04,0:01:30.17,Default,,0,0,0,,The largest part of \N the soundtrack \Nwas done without seeing a movie\r
+Dialogue: 0,0:01:30.17,0:01:36.06,Default,,0,0,0,,It was no problem, but very inspiring \Nand a free working process.\r
+Dialogue: 0,0:02:08.13,0:02:10.23,Default,,0,0,0,,Galileo's theme is one of my favourites.\r
+Dialogue: 0,0:02:10.23,0:02:14.10,Default,,0,0,0,,We did a lot of different versions \Nabout the central theme.\r
+Dialogue: 0,0:02:14.10,0:02:18.02,Default,,0,0,0,,For the 17th century \N we used a nice harpsichord\r
+Dialogue: 0,0:02:19.05,0:02:22.09,Default,,0,0,0,,and so we landed directly into Galileo's time.\r
-b7cb0eeb34af0da364e29b238f0634ae
+1
+00:00:00,970 --> 00:00:02,540
+- Test 1.\r
+- Test 2.
+
+2
+00:00:03,050 --> 00:00:04,740
+Test 3.
+
+3
+00:00:05,850 --> 00:00:08,140
+- Test 4.\r
+- Test 5.
+
-848f774195e873ce71febf35b6c9c541
+[Script Info]\r
+; Script generated by FFmpeg/Lavc\r
+ScriptType: v4.00+\r
+PlayResX: 384\r
+PlayResY: 288\r
+\r
+[V4+ Styles]\r
+Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding\r
+Style: Default,Arial,16,&Hffffff,&Hffffff,&H0,&H0,0,0,0,0,100,100,0,0,1,1,0,2,10,10,10,0\r
+\r
+[Events]\r
+Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text\r
+Dialogue: 0,0:01:00.10,0:02:00.20,Default,,0,0,0,,Hello.\NWorld!\r
+Dialogue: 0,0:02:00.30,0:03:00.40,Default,,0,0,0,,\Nfoo\Nbar\Nbla\Nmixed with br\r
+Dialogue: 0,0:03:04.12,0:03:10.20,Default,,0,0,0,,Another event.\r
-040d7880a6621b1661f9d12c5375037f
+[Script Info]\r
+; Script generated by FFmpeg/Lavc\r
+ScriptType: v4.00+\r
+PlayResX: 384\r
+PlayResY: 288\r
+\r
+[V4+ Styles]\r
+Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding\r
+Style: Default,Arial,16,&Hffffff,&Hffffff,&H0,&H0,0,0,0,0,100,100,0,0,1,1,0,2,10,10,10,0\r
+\r
+[Events]\r
+Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text\r
+Dialogue: 0,0:03:45.00,0:03:48.00,Default,,0,0,0,,- ToIerábiIis?\N- Azt jeIenti: tűrhető.\r
+Dialogue: 0,0:03:48.00,0:03:51.00,Default,,0,0,0,,Tudom, mit jeIent. Megnézhetem?\r
+Dialogue: 0,0:03:52.00,0:03:54.00,Default,,0,0,0,,TiszteIt bírónő.\r
+Dialogue: 0,0:03:57.00,0:04:00.00,Default,,0,0,0,,KépzeIje magát\Na környékbeIi gyermekek heIyébe.\r
+Dialogue: 0,0:04:01.00,0:04:05.00,Default,,0,0,0,,Naphosszat monoton, döngöIő zaj\Nszaggatja a dobhártyájukat.\r
+Dialogue: 0,0:04:05.00,0:04:10.00,Default,,0,0,0,,Ahogy egyre föIébük tornyosuI,\Nrájuk veti sötét árnyékát.\r
+Dialogue: 0,0:04:10.00,0:04:15.00,Default,,0,0,0,,Ez a feIhőkarcoIó, az emberi\Nmohóság újabb emIékműve.\r
+Dialogue: 0,1:50:38.00,1:50:41.00,Default,,0,0,0,,készen áIIok.\r
+Dialogue: 0,1:51:00.00,1:51:03.00,Default,,0,0,0,,Joe ... Miguel keres.\r
+Dialogue: 0,2:00:18.00,9:59:59.99,Default,,0,0,0,,Magyar szöveg: Nikowvitz Oszkár\r
-0bb5d4f72b6dc1b37d2ee7b5579ed87e
+[Script Info]\r
+; Script generated by FFmpeg/Lavc\r
+ScriptType: v4.00+\r
+PlayResX: 384\r
+PlayResY: 288\r
+\r
+[V4+ Styles]\r
+Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding\r
+Style: Default,Arial,16,&Hffffff,&Hffffff,&H0,&H0,0,0,0,0,100,100,0,0,1,1,0,2,10,10,10,0\r
+\r
+[Events]\r
+Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text\r
+Dialogue: 0,0:00:00.12,0:00:23.51,Default,,0,0,0,,Hello\r
+Dialogue: 0,0:00:23.51,0:01:02.05,Default,,0,0,0,,World\r
+Dialogue: 0,0:01:02.05,9:59:59.99,Default,,0,0,0,,!\Nnewline\r
-ee266bd7141df4ea11a9447ab038bb6e
+[Script Info]\r
+; Script generated by FFmpeg/Lavc\r
+ScriptType: v4.00+\r
+PlayResX: 384\r
+PlayResY: 288\r
+\r
+[V4+ Styles]\r
+Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding\r
+Style: Default,Arial,16,&Hffffff,&Hffffff,&H0,&H0,0,0,0,0,100,100,0,0,1,1,0,2,10,10,10,0\r
+\r
+[Events]\r
+Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text\r
+Dialogue: 0,0:00:11.00,0:00:13.00,Default,,0,0,0,,We are in New York City\NRandom line added\r
+Dialogue: 0,0:00:13.00,0:00:16.00,Default,,0,0,0,,We're actually at the Lucern Hotel, just down the street\r
+Dialogue: 0,0:00:16.00,0:00:18.00,Default,,0,0,0,,from the American Museum of Natural History\r
+Dialogue: 0,0:00:18.00,0:00:20.00,Default,,0,0,0,,And with me is Neil deGrasse Tyson\r
+Dialogue: 0,0:00:20.00,0:00:22.00,Default,,0,0,0,,Astrophysicist, Director of the Hayden Planetarium\r
+Dialogue: 0,0:00:22.00,0:00:24.00,Default,,0,0,0,,at the AMNH.\r
+Dialogue: 0,0:00:24.00,0:00:26.00,Default,,0,0,0,,Thank you for walking down here.\r
+Dialogue: 0,0:00:27.00,0:00:30.00,Default,,0,0,0,,And I want to do a follow-up on the last conversation we did.\Nmultiple lines\Nagain\r
+Dialogue: 0,0:00:30.00,0:00:31.50,Default,,0,0,0,,When we e-mailed—\r
+Dialogue: 0,0:00:30.50,0:00:32.50,Default,,0,0,0,,Didn't we {\b1}talk {\i1}about\N{\i0} enough{\b0} in that conversation? \{I'm not an ASS comment\}\r
+Dialogue: 0,0:00:32.00,0:00:35.50,Default,,0,0,0,,No! No no no no; 'cos 'cos obviously 'cos\r
+Dialogue: 0,0:00:32.50,0:00:33.50,Default,,0,0,0,,{\i1}Laughs{\i0}\r
+Dialogue: 0,0:00:35.50,0:00:38.00,Default,,0,0,0,,You know I'm so excited my glasses are falling off here.\r
+Dialogue: 0,0:00:50.00,0:00:51.13,Default,,0,0,0,,This event and the following\None have CLRF\r
+Dialogue: 0,0:59:00.12,1:23:45.68,Default,,0,0,0,,Obiwan Kenobi\r
-8683216a86e147a98f29dafee33a0987
+WEBVTT
+
+00:00.000 --> 00:00.000
+Don't show this text it may be used to insert hidden data
+
+00:01.500 --> 00:04.500
+SubRip subtitles capability tester 1.3o by ale5000
+<b><i>Use VLC 1.1 or higher as reference for most things and MPC Home Cinema for others</i></b>
+This text should be blue
+This text should be red
+This text should be black
+If you see this with the normal font, the player don't (fully) support font face
+
+00:04.500 --> 00:04.500
+Hidden
+
+00:04.501 --> 00:07.501
+This text should be small
+This text should be normal
+This text should be big
+
+00:07.501 --> 00:11.501
+This should be an E with an accent: È
+日本語
+<b><i><u>This text should be bold, italics and underline</u></i></b>
+This text should be small and green
+This text should be small and red
+This text should be big and brown
+
+00:11.501 --> 00:14.501
+<b>This line should be bold</b>
+<i>This line should be italics</i>
+<u>This line should be underline</u>
+This line should be strikethrough
+<u>Both lines
+should be underline</u>
+
+00:14.501 --> 00:17.501
+>
+It would be a good thing to
+hide invalid html tags that are closed and show the text in them
+<invalid_tag_unclosed>but show un-closed invalid html tags
+Show not opened tags</invalid_tag_not_opened>
+<
+
+00:17.501 --> 00:20.501
+and also
+hide invalid html tags with parameters that are closed and show the text in them
+<invalid_tag_uc par=5>but show un-closed invalid html tags
+<u>This text should be showed underlined without problems also: 2<3,5>1,4<6</u>
+This shouldn't be underlined
+
+00:20.501 --> 00:21.501
+This text should be in the normal position...
+
+00:21.501 --> 00:22.501
+This text should NOT be in the normal position
+
+00:22.501 --> 00:24.501
+Implementation is the same of the ASS tag
+This text should be at the
+top and horizontally centered
+
+00:22.501 --> 00:24.501
+This text should be at the
+middle and horizontally centered
+
+00:22.501 --> 00:24.501
+This text should be at the
+bottom and horizontally centered
+
+00:24.501 --> 00:26.501
+This text should be at the
+top and horizontally at the left
+
+00:24.501 --> 00:26.501
+This text should be at the
+middle and horizontally at the left
+(The second position must be ignored)
+
+00:24.501 --> 00:26.501
+This text should be at the
+bottom and horizontally at the left
+
+00:26.501 --> 00:28.501
+This text should be at the
+top and horizontally at the right
+
+00:26.501 --> 00:28.501
+This text should be at the
+middle and horizontally at the right
+
+00:26.501 --> 00:28.501
+This text should be at the
+bottom and horizontally at the right
+
+00:28.501 --> 00:31.501
+This could be the most difficult thing to implement
+
+00:31.501 --> 00:50.501
+First text
+
+00:33.500 --> 00:35.500
+Second, it shouldn't overlap first
+
+00:35.501 --> 00:37.501
+Third, it should replace second
+
+00:36.501 --> 00:50.501
+Fourth, it shouldn't overlap first and third
+
+00:40.501 --> 00:45.501
+Fifth, it should replace third
+
+00:45.501 --> 00:50.501
+Sixth, it shouldn't be
+showed overlapped
+
+00:50.501 --> 00:52.501
+TEXT 1 (bottom)
+
+00:50.501 --> 00:52.501
+text 2
+
+00:52.501 --> 00:54.501
+Hide these tags:
+also hide these tags:
+but show this: {normal text}
+
+00:54.501 --> 01:00.501
+
+\ N is a forced line break
+\ h is a hard space
+Normal spaces at the start and at the end of the line are trimmed while hard spaces are not trimmed.
+The\hline\hwill\hnever\hbreak\hautomatically\hright\hbefore\hor\hafter\ha\hhard\hspace.\h:-D
+
+00:54.501 --> 00:56.501
+
+\h\h\h\h\hA (05 hard spaces followed by a letter)
+A (Normal spaces followed by a letter)
+A (No hard spaces followed by a letter)
+
+00:56.501 --> 00:58.501
+\h\h\h\h\hA (05 hard spaces followed by a letter)
+A (Normal spaces followed by a letter)
+A (No hard spaces followed by a letter)
+Show this: \TEST and this: \-)
+
+00:58.501 --> 01:00.501
+
+A letter followed by 05 hard spaces: A\h\h\h\h\h
+A letter followed by normal spaces: A
+A letter followed by no hard spaces: A
+05 hard spaces between letters: A\h\h\h\h\hA
+5 normal spaces between letters: A A
+
+^--Forced line break
+
+01:00.501 --> 01:02.501
+Both line should be strikethrough,
+yes.
+Correctly closed tags
+should be hidden.
+
+01:02.501 --> 01:04.501
+It shouldn't be strikethrough,
+not opened tag showed as text.</s>
+Not opened tag showed as text.</xxxxx>
+
+01:04.501 --> 01:06.501
+Three lines should be strikethrough,
+yes.
+<yyyy>Not closed tags showed as text
+
+01:06.501 --> 01:08.501
+Both line should be strikethrough but
+the wrong closing tag should be showed</b>
--- /dev/null
+#tb 0: 1001/30000
+0, 0, 0, 1, 3110400, 0x764f8856
+0, 2, 2, 1, 3110400, 0x3b615b79
+0, 3, 3, 1, 3110400, 0x4fbb6f84
+0, 4, 4, 1, 3110400, 0xc1ca8532
+0, 5, 5, 1, 3110400, 0xb6e7d363
+0, 6, 6, 1, 3110400, 0x1beb5c34
+0, 7, 7, 1, 3110400, 0xcb8cb061
+0, 8, 8, 1, 3110400, 0x13ddbd61
+0, 9, 9, 1, 3110400, 0xde8f052f
+0, 10, 10, 1, 3110400, 0x4d4072db
+0, 11, 11, 1, 3110400, 0x4e5d29e3
+0, 12, 12, 1, 3110400, 0x75300531
+0, 13, 13, 1, 3110400, 0x1114285a
-#tb 0: 16701/250000
+#tb 0: 1001/15000
0, 0, 0, 1, 38016, 0x50e93e0d
0, 1, 1, 1, 38016, 0x6ac8627d
0, 2, 2, 1, 38016, 0x6f38661e
--- /dev/null
+#format: frame checksums
+#version: 1
+#hash: MD5
+#tb 0: 1/30
+#stream#, dts, pts, duration, size, hash
+0, 0, 0, 1, 345600, c2ee30cb4529fcbd61938af1887e2b45
+0, 1, 1, 1, 345600, 946e9bfee03777a07c122df038087d92
+0, 2, 2, 1, 345600, 5dd1916a4bad6e94393f6a50a37c823d
+0, 3, 3, 1, 345600, 2f2760d8dcecc1854fd665892382c3af
+0, 4, 4, 1, 345600, 70418b01ae59e2885457b62b7f416bac
+0, 5, 5, 1, 345600, bda937bb934a6eba193daadccdaa418d
+0, 6, 6, 1, 345600, 8348bbb7c260dec6baa135c8f16348a9
+0, 7, 7, 1, 345600, d45bf60db5f25e774d32975eca01f9c7
+0, 8, 8, 1, 345600, 980e73d96767b2097adf26e0ea31d50e
+0, 9, 9, 1, 345600, 66fda810a9a35f1ce57d6f2351b73c13
<Representation id="1" bandwidth="302355">
<BaseURL>dash_video2.webm</BaseURL>
<SegmentBase
- indexRange="1115782-1115886">
+ indexRange="1115782-1115879">
<Initialization
range="0-249" />
</SegmentBase>
</Representation>
</AdaptationSet>
<AdaptationSet id="1" mimeType="audio/webm" codecs="vorbis" lang="eng" audioSamplingRate="44100" bitstreamSwitching="true" subsegmentAlignment="false" subsegmentStartsWithSAP="1">
-<Representation id="0" bandwidth="82867">
+<Representation id="2" bandwidth="82867">
<BaseURL>dash_audio1.webm</BaseURL>
<SegmentBase
indexRange="335488-335612">
range="0-4103" />
</SegmentBase>
</Representation>
-<Representation id="1" bandwidth="82814">
+<Representation id="3" bandwidth="82814">
<BaseURL>dash_audio2.webm</BaseURL>
<SegmentBase
- indexRange="335312-335432">
+ indexRange="335312-335425">
<Initialization
range="0-3927" />
</SegmentBase>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<MPD
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="urn:mpeg:DASH:schema:MPD:2011"
+ xsi:schemaLocation="urn:mpeg:DASH:schema:MPD:2011"
+ type="static"
+ mediaPresentationDuration="PT32.48S"
+ minBufferTime="PT1S"
+ profiles="urn:webm:dash:profile:webm-on-demand:2012">
+<Period id="0" start="PT0S" duration="PT32.48S" >
+<AdaptationSet id="0" mimeType="video/webm" codecs="vp8" lang="eng" bitstreamSwitching="true" subsegmentAlignment="false" subsegmentStartsWithSAP="1">
+<Representation id="0" bandwidth="302355" width="640" height="360">
+<BaseURL>dash_video1.webm</BaseURL>
+<SegmentBase
+ indexRange="1115974-1116097">
+<Initialization
+ range="0-441" />
+</SegmentBase>
+</Representation>
+<Representation id="1" bandwidth="243938" width="320" height="240">
+<BaseURL>dash_video4.webm</BaseURL>
+<SegmentBase
+ indexRange="871124-871645">
+<Initialization
+ range="0-437" />
+</SegmentBase>
+</Representation>
+</AdaptationSet>
+</Period>
+</MPD>
<Representation id="1" bandwidth="83502">
<BaseURL>dash_audio3.webm</BaseURL>
<SegmentBase
- indexRange="335312-335432">
+ indexRange="335312-335425">
<Initialization
range="0-3927" />
</SegmentBase>
<Representation id="1" bandwidth="321574">
<BaseURL>dash_video3.webm</BaseURL>
<SegmentBase
- indexRange="1116070-1116461">
+ indexRange="1116070-1116455">
<Initialization
range="0-249" />
</SegmentBase>
-8facd3cc6158b611cb312920a426cbd7 *./tests/data/lavf-fate/lavf.mp3
+f231c5316357fd747573cbcb02f889c5 *./tests/data/lavf-fate/lavf.mp3
96016 ./tests/data/lavf-fate/lavf.mp3
./tests/data/lavf-fate/lavf.mp3 CRC=0x6c9850fe
11be3e5caa2892236b3475c3f7807b76 *./tests/data/lavf/lavf.dv
3600000 ./tests/data/lavf/lavf.dv
-./tests/data/lavf/lavf.dv CRC=0x25bdd732
+./tests/data/lavf/lavf.dv CRC=0x0b2cd3ec
e9949bc767924e1e7d28856029fee024 *./tests/data/lavf/lavf.dv
3480000 ./tests/data/lavf/lavf.dv
-./tests/data/lavf/lavf.dv CRC=0xc4f27ca7
+./tests/data/lavf/lavf.dv CRC=0xfab17c4a
87d3b20f656235671383a7eaa2f66330 *./tests/data/lavf/lavf.dv
3600000 ./tests/data/lavf/lavf.dv
-./tests/data/lavf/lavf.dv CRC=0x0e868a82
+./tests/data/lavf/lavf.dv CRC=0xf3e6873c
-16cc0ee04b036c210b2fc85182d748e1 *./tests/data/lavf/lavf.ffm
+d5d4e5e3eec336ae6680dde035870564 *./tests/data/lavf/lavf.ffm
376832 ./tests/data/lavf/lavf.ffm
./tests/data/lavf/lavf.ffm CRC=0x000e23ae
-17b0b8eff852edd25fa38aed062689d7 *./tests/data/lavf/lavf.ismv
-312546 ./tests/data/lavf/lavf.ismv
-./tests/data/lavf/lavf.ismv CRC=0xb7d29d29
-543e5146df7bd4b7eb7edc94e0034ad9 *./tests/data/lavf/lavf.ismv
-321452 ./tests/data/lavf/lavf.ismv
-./tests/data/lavf/lavf.ismv CRC=0x33834815
-17b0b8eff852edd25fa38aed062689d7 *./tests/data/lavf/lavf.ismv
-312546 ./tests/data/lavf/lavf.ismv
-./tests/data/lavf/lavf.ismv CRC=0xb7d29d29
+a9ccbb4cd1436d222ef4425567b4e03d *./tests/data/lavf/lavf.ismv
+312542 ./tests/data/lavf/lavf.ismv
+./tests/data/lavf/lavf.ismv CRC=0x9d9a638a
+440d85f9fd5b9f63c2676638782b5c15 *./tests/data/lavf/lavf.ismv
+321448 ./tests/data/lavf/lavf.ismv
+./tests/data/lavf/lavf.ismv CRC=0xe8130120
+a9ccbb4cd1436d222ef4425567b4e03d *./tests/data/lavf/lavf.ismv
+312542 ./tests/data/lavf/lavf.ismv
+./tests/data/lavf/lavf.ismv CRC=0x9d9a638a
-103403355e6dec356c7342ee2d034691 *./tests/data/lavf/lavf.mxf
+dbc4ced82ef1c2fa4df3571b4f994a22 *./tests/data/lavf/lavf.mxf
525369 ./tests/data/lavf/lavf.mxf
./tests/data/lavf/lavf.mxf CRC=0xdbfff6f1
-f61e4c8481610f30b2f5e2279e254f6b *./tests/data/lavf/lavf.mxf
+fe4294023cd990938f042c7855405f63 *./tests/data/lavf/lavf.mxf
560697 ./tests/data/lavf/lavf.mxf
./tests/data/lavf/lavf.mxf CRC=0x11a6178e
-a586dad4ff94136be460afb02ff6101e *./tests/data/lavf/lavf.mxf
+ef0c741e17bf7963fc51adcb6bab8ec8 *./tests/data/lavf/lavf.mxf
525369 ./tests/data/lavf/lavf.mxf
./tests/data/lavf/lavf.mxf CRC=0xdbfff6f1
-838b732d832dcf40b0eb9944bc6d8f55 *./tests/data/lavf/lavf.mxf_d10
+87e0903ef7ea55b1a032b9d878588683 *./tests/data/lavf/lavf.mxf_d10
5330989 ./tests/data/lavf/lavf.mxf_d10
./tests/data/lavf/lavf.mxf_d10 CRC=0x6c74d488
4d572f758b55a1756adf9f54132f3b9e *tests/data/fate/vsynth1-dv.dv
7200000 tests/data/fate/vsynth1-dv.dv
-02ac7cdeab91d4d5621e7ce96dddc498 *tests/data/fate/vsynth1-dv.out.rawvideo
+1cda5a62c3a2f17cc7d5b4cddccf2524 *tests/data/fate/vsynth1-dv.out.rawvideo
stddev: 6.90 PSNR: 31.34 MAXDIFF: 76 bytes: 7603200/ 7603200
f179899efba432c6f01149c36c709092 *tests/data/fate/vsynth1-dv-411.dv
7200000 tests/data/fate/vsynth1-dv-411.dv
-53946d51762b7826773e681fb02f377b *tests/data/fate/vsynth1-dv-411.out.rawvideo
-stddev: 9.45 PSNR: 28.62 MAXDIFF: 84 bytes: 7603200/ 7603200
+48904744fabbbc3421a762f615ef6456 *tests/data/fate/vsynth1-dv-411.out.rawvideo
+stddev: 9.44 PSNR: 28.62 MAXDIFF: 84 bytes: 7603200/ 7603200
a193c5f92bf6e74c604e759d5f4f0f94 *tests/data/fate/vsynth1-dv-50.dv
14400000 tests/data/fate/vsynth1-dv-50.dv
-a2ff093e93ffed10f730fa21df02fc50 *tests/data/fate/vsynth1-dv-50.out.rawvideo
+41c4df5f2d876fcd5245643b9ded6711 *tests/data/fate/vsynth1-dv-50.out.rawvideo
stddev: 1.72 PSNR: 43.38 MAXDIFF: 29 bytes: 7603200/ 7603200
-895d30660eb4da017568141a8d1df4e8 *tests/data/fate/vsynth1-v210.avi
+b066679e08cd90c342da21c88bec2a20 *tests/data/fate/vsynth1-v210.avi
14752448 tests/data/fate/vsynth1-v210.avi
-50973792d3f1abe04a51ee0121f077f2 *tests/data/fate/vsynth1-v210.out.rawvideo
-stddev: 1.85 PSNR: 42.78 MAXDIFF: 29 bytes: 7603200/ 7603200
+2ba7f4ca302f3c4147860b9dfb12b6e4 *tests/data/fate/vsynth1-v210.out.rawvideo
+stddev: 1.84 PSNR: 42.81 MAXDIFF: 29 bytes: 7603200/ 7603200
--- /dev/null
+487c3e53249f7b9f16e04257295998de *tests/data/fate/vsynth1-xface.nut
+19746 tests/data/fate/vsynth1-xface.nut
+42d8261bb538b8789840ac085f7fc4d2 *tests/data/fate/vsynth1-xface.out.rawvideo
+stddev: 103.88 PSNR: 7.80 MAXDIFF: 254 bytes: 7603200/ 7603200
-e0d0da8cf786616eff2e88c45644c902 *tests/data/fate/vsynth2-amv.avi
-761976 tests/data/fate/vsynth2-amv.avi
-f256ad9feefb499c6569d06d868eb496 *tests/data/fate/vsynth2-amv.out.rawvideo
-stddev: 4.30 PSNR: 35.46 MAXDIFF: 65 bytes: 7603200/ 7603200
+4aecb14ef9fc1a0b54d1ae39808a488e *tests/data/fate/vsynth2-amv.avi
+912548 tests/data/fate/vsynth2-amv.avi
+5b7fe07a366b176e35d2564ecf95ebe9 *tests/data/fate/vsynth2-amv.out.rawvideo
+stddev: 4.91 PSNR: 34.31 MAXDIFF: 71 bytes: 7603200/ 7603200
-bffe7188b4b5c3ff76c75561d0bebd77 *tests/data/fate/vsynth2-asv1.avi
-689416 tests/data/fate/vsynth2-asv1.avi
-a7cdefad200f48ab308c746461a8792e *tests/data/fate/vsynth2-asv1.out.rawvideo
-stddev: 5.07 PSNR: 34.03 MAXDIFF: 70 bytes: 7603200/ 7603200
+c80b5ad97e55e5fa644698a53e8f0559 *tests/data/fate/vsynth2-asv1.avi
+836552 tests/data/fate/vsynth2-asv1.avi
+da15fb1affc65904161dc37eff4cdc7a *tests/data/fate/vsynth2-asv1.out.rawvideo
+stddev: 5.78 PSNR: 32.88 MAXDIFF: 75 bytes: 7603200/ 7603200
-f8c3b9899bbd9545757fac0c7ecf4e34 *tests/data/fate/vsynth2-asv2.avi
-675584 tests/data/fate/vsynth2-asv2.avi
-5990db66c7ac0bbe2f98ec2770c1bf3b *tests/data/fate/vsynth2-asv2.out.rawvideo
-stddev: 4.57 PSNR: 34.93 MAXDIFF: 47 bytes: 7603200/ 7603200
+56d3455969d54fc484b13df3cca465ec *tests/data/fate/vsynth2-asv2.avi
+822228 tests/data/fate/vsynth2-asv2.avi
+15329433bcccfb9ca874d949423cef47 *tests/data/fate/vsynth2-asv2.out.rawvideo
+stddev: 5.13 PSNR: 33.92 MAXDIFF: 50 bytes: 7603200/ 7603200
-df5efcfd2170df82e466be4deb7ce4a9 *tests/data/fate/vsynth2-avui.mov
+4d46be4cf21d2f0dc0a857bb2603b899 *tests/data/fate/vsynth2-avui.mov
42624917 tests/data/fate/vsynth2-avui.mov
-dde5895817ad9d219f79a52d0bdfb001 *tests/data/fate/vsynth2-avui.out.rawvideo
+36d7ca943916e1743cefa609eba0205c *tests/data/fate/vsynth2-avui.out.rawvideo
stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 7603200/ 7603200
-7bfd989038611212a80b5b050bb78ea7 *tests/data/fate/vsynth2-cljr.avi
+655e904953107fb0c015338bccb40873 *tests/data/fate/vsynth2-cljr.avi
5075648 tests/data/fate/vsynth2-cljr.avi
-965c4a134144b30b24d6d138b03ddb8c *tests/data/fate/vsynth2-cljr.out.rawvideo
-stddev: 3.29 PSNR: 37.76 MAXDIFF: 23 bytes: 7603200/ 7603200
+14e64b6e6c1d7fdefbb111920911f301 *tests/data/fate/vsynth2-cljr.out.rawvideo
+stddev: 3.34 PSNR: 37.65 MAXDIFF: 37 bytes: 7603200/ 7603200
-d680a5eed77c5b8dc6b5ef3bcf6e87e8 *tests/data/fate/vsynth2-dnxhd-1080i.mov
+d59d5d40ffb33ebb9e9e0d5025aefb88 *tests/data/fate/vsynth2-dnxhd-1080i.mov
3031911 tests/data/fate/vsynth2-dnxhd-1080i.mov
-744ba46da5d4c19a28562ea31061d170 *tests/data/fate/vsynth2-dnxhd-1080i.out.rawvideo
-stddev: 1.31 PSNR: 45.77 MAXDIFF: 23 bytes: 7603200/ 760320
+099001db73036eeb9545c463cf90f0ba *tests/data/fate/vsynth2-dnxhd-1080i.out.rawvideo
+stddev: 1.53 PSNR: 44.43 MAXDIFF: 31 bytes: 7603200/ 760320
-4ca9473a8d106bdfe36e9bf7c516b648 *tests/data/fate/vsynth2-dnxhd-720p.dnxhd
+3bb2d4fe12b49eae830918d68bde0675 *tests/data/fate/vsynth2-dnxhd-720p.dnxhd
2293760 tests/data/fate/vsynth2-dnxhd-720p.dnxhd
-d44c4b08cda8a8042ae345124fdfffcc *tests/data/fate/vsynth2-dnxhd-720p.out.rawvideo
-stddev: 1.32 PSNR: 45.68 MAXDIFF: 22 bytes: 7603200/ 760320
+903e5a7f2b84c0cd362a0f3a69549989 *tests/data/fate/vsynth2-dnxhd-720p.out.rawvideo
+stddev: 1.53 PSNR: 44.41 MAXDIFF: 31 bytes: 7603200/ 760320
-e96fc4a7d994b9369c50da32fd325822 *tests/data/fate/vsynth2-dnxhd-720p-10bit.dnxhd
+e49cb87f69acc809aee55d64990c84a9 *tests/data/fate/vsynth2-dnxhd-720p-10bit.dnxhd
2293760 tests/data/fate/vsynth2-dnxhd-720p-10bit.dnxhd
-0449440eb3e8416840a27deb1a8f80b0 *tests/data/fate/vsynth2-dnxhd-720p-10bit.out.rawvideo
-stddev: 1.35 PSNR: 45.47 MAXDIFF: 22 bytes: 7603200/ 760320
+3eb47758e42db9fc704e1254b7abbeb0 *tests/data/fate/vsynth2-dnxhd-720p-10bit.out.rawvideo
+stddev: 1.56 PSNR: 44.25 MAXDIFF: 31 bytes: 7603200/ 760320
-b305b03708e905717b42fc0b304367d4 *tests/data/fate/vsynth2-dnxhd-720p-rd.dnxhd
+b723c7412a4c93f500b917ad721f6d21 *tests/data/fate/vsynth2-dnxhd-720p-rd.dnxhd
2293760 tests/data/fate/vsynth2-dnxhd-720p-rd.dnxhd
-13de1c5ed025abb5120450e134aa623d *tests/data/fate/vsynth2-dnxhd-720p-rd.out.rawvideo
-stddev: 1.32 PSNR: 45.66 MAXDIFF: 22 bytes: 7603200/ 760320
+f7d437ea7024700cfd61c40197f44852 *tests/data/fate/vsynth2-dnxhd-720p-rd.out.rawvideo
+stddev: 1.53 PSNR: 44.40 MAXDIFF: 31 bytes: 7603200/ 760320
+++ /dev/null
-204e80f2e406ada90fca596ab2810b3e *./tests/data/vsynth2/dnxhd-1080i.mov
-3031911 ./tests/data/vsynth2/dnxhd-1080i.mov
-3c559af629ae0a8fb1a9a0e4b4da7733 *./tests/data/dnxhd_1080i.vsynth2.out.yuv
-stddev: 1.31 PSNR: 45.77 MAXDIFF: 23 bytes: 760320/ 7603200
-85b8d55b0b68bb3fc2e90babb580f9b7 *tests/data/fate/vsynth2-dv.dv
+9002a5769a7744a4b8d24b01787abc3b *tests/data/fate/vsynth2-dv.dv
7200000 tests/data/fate/vsynth2-dv.dv
-7ec62bd3350a6848364669e6e1e4b9cc *tests/data/fate/vsynth2-dv.out.rawvideo
-stddev: 1.71 PSNR: 43.47 MAXDIFF: 33 bytes: 7603200/ 7603200
+22a62dc9108c4a8b1a3c708e5d383748 *tests/data/fate/vsynth2-dv.out.rawvideo
+stddev: 1.99 PSNR: 42.12 MAXDIFF: 38 bytes: 7603200/ 7603200
-e428508f400327aeb96969c08fb9e1b5 *tests/data/fate/vsynth2-dv-411.dv
+701dac8c1d3fe69957eab7ba8d5ecb25 *tests/data/fate/vsynth2-dv-411.dv
7200000 tests/data/fate/vsynth2-dv-411.dv
-3cd4b85065d67bfb7fbab3bea4039711 *tests/data/fate/vsynth2-dv-411.out.rawvideo
-stddev: 2.89 PSNR: 38.91 MAXDIFF: 45 bytes: 7603200/ 7603200
+bf821931bb81f4e92dc38f86d8187300 *tests/data/fate/vsynth2-dv-411.out.rawvideo
+stddev: 3.48 PSNR: 37.28 MAXDIFF: 56 bytes: 7603200/ 7603200
-0032a07167199e6f49e07fa7ed4d5f62 *tests/data/fate/vsynth2-dv-50.dv
+9b9ebdf35911dad62203dfdf1f56754e *tests/data/fate/vsynth2-dv-50.dv
14400000 tests/data/fate/vsynth2-dv-50.dv
-af3f2dd5ab62c1a1d98b07d4aeb6852f *tests/data/fate/vsynth2-dv-50.out.rawvideo
-stddev: 0.82 PSNR: 49.82 MAXDIFF: 12 bytes: 7603200/ 7603200
+b4d324b2095bc919ad16891891d40b36 *tests/data/fate/vsynth2-dv-50.out.rawvideo
+stddev: 0.88 PSNR: 49.20 MAXDIFF: 17 bytes: 7603200/ 7603200
+++ /dev/null
-e428508f400327aeb96969c08fb9e1b5 *./tests/data/vsynth2/dv411.dv
-7200000 ./tests/data/vsynth2/dv411.dv
-7f9fa421028aabb11eaf4c6513a5a843 *./tests/data/dv_411.vsynth2.out.yuv
-stddev: 10.09 PSNR: 28.05 MAXDIFF: 60 bytes: 7603200/ 7603200
-9e091bee097632ef7106d3bade12b81b *tests/data/fate/vsynth2-ffv1.avi
-3547788 tests/data/fate/vsynth2-ffv1.avi
-dde5895817ad9d219f79a52d0bdfb001 *tests/data/fate/vsynth2-ffv1.out.rawvideo
+5ebaa3df3ab8063214a3c612c8e98e04 *tests/data/fate/vsynth2-ffv1.avi
+3718022 tests/data/fate/vsynth2-ffv1.avi
+36d7ca943916e1743cefa609eba0205c *tests/data/fate/vsynth2-ffv1.out.rawvideo
stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 7603200/ 7603200
-114950628c091cd830d9e66e74f6bca2 *tests/data/fate/vsynth2-ffv1.0.avi
-3525792 tests/data/fate/vsynth2-ffv1.0.avi
-dde5895817ad9d219f79a52d0bdfb001 *tests/data/fate/vsynth2-ffv1.0.out.rawvideo
+f7960e9a863ce303f71b8a9feaeec1d2 *tests/data/fate/vsynth2-ffv1.0.avi
+3692538 tests/data/fate/vsynth2-ffv1.0.avi
+36d7ca943916e1743cefa609eba0205c *tests/data/fate/vsynth2-ffv1.0.out.rawvideo
stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 7603200/ 7603200
-7cb61df06d2cb4659ceb8d73c4822aaf *tests/data/fate/vsynth2-ffvhuff.avi
-4845022 tests/data/fate/vsynth2-ffvhuff.avi
-dde5895817ad9d219f79a52d0bdfb001 *tests/data/fate/vsynth2-ffvhuff.out.rawvideo
+ca0fd7f4ab121383c89c1e708375ed73 *tests/data/fate/vsynth2-ffvhuff.avi
+4865618 tests/data/fate/vsynth2-ffvhuff.avi
+36d7ca943916e1743cefa609eba0205c *tests/data/fate/vsynth2-ffvhuff.out.rawvideo
stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 7603200/ 7603200
-e5873a19c7be1cdf25600eb033738b9e *tests/data/fate/vsynth2-ffvhuff420p12.avi
-10925576 tests/data/fate/vsynth2-ffvhuff420p12.avi
-08b3c6c70eba608bae926608ff253f2a *tests/data/fate/vsynth2-ffvhuff420p12.out.rawvideo
-stddev: 0.68 PSNR: 51.38 MAXDIFF: 1 bytes: 7603200/ 7603200
+954970affeb3bf759625945364b48681 *tests/data/fate/vsynth2-ffvhuff420p12.avi
+10562804 tests/data/fate/vsynth2-ffvhuff420p12.avi
+542327cb5ca7708085513ffc3d7c693c *tests/data/fate/vsynth2-ffvhuff420p12.out.rawvideo
+stddev: 0.72 PSNR: 50.87 MAXDIFF: 1 bytes: 7603200/ 7603200
-d7d321c3b1ed3378e03b2f618f248d86 *tests/data/fate/vsynth2-ffvhuff422p10left.avi
-10041832 tests/data/fate/vsynth2-ffvhuff422p10left.avi
-a627fb50c8276200fd71383977d87ca3 *tests/data/fate/vsynth2-ffvhuff422p10left.out.rawvideo
-stddev: 0.34 PSNR: 57.43 MAXDIFF: 6 bytes: 7603200/ 7603200
+e6aac4b4faafac27aa3ae76ef84519e5 *tests/data/fate/vsynth2-ffvhuff422p10left.avi
+9870624 tests/data/fate/vsynth2-ffvhuff422p10left.avi
+8bb1c449e1a2a94fd0d98841c04246bb *tests/data/fate/vsynth2-ffvhuff422p10left.out.rawvideo
+stddev: 0.39 PSNR: 56.17 MAXDIFF: 9 bytes: 7603200/ 7603200
-68e78dc89bb596f93a14e7f4a7a24365 *tests/data/fate/vsynth2-ffvhuff444.avi
-7530714 tests/data/fate/vsynth2-ffvhuff444.avi
-d43cb310c130c69214332d74f6ee5f9a *tests/data/fate/vsynth2-ffvhuff444.out.rawvideo
-stddev: 0.41 PSNR: 55.80 MAXDIFF: 7 bytes: 7603200/ 7603200
+38071294a9151e244640d32ce6bc440d *tests/data/fate/vsynth2-ffvhuff444.avi
+7635770 tests/data/fate/vsynth2-ffvhuff444.avi
+8394327c14ef0b6fbaae3b69fcc5572a *tests/data/fate/vsynth2-ffvhuff444.out.rawvideo
+stddev: 0.50 PSNR: 54.10 MAXDIFF: 13 bytes: 7603200/ 7603200
-db17747292df97d6c62b15b041c378da *tests/data/fate/vsynth2-ffvhuff444p16.avi
-26360716 tests/data/fate/vsynth2-ffvhuff444p16.avi
-05ccd9a38f9726030b3099c0c99d3a13 *tests/data/fate/vsynth2-ffvhuff444p16.out.rawvideo
-stddev: 0.45 PSNR: 55.06 MAXDIFF: 7 bytes: 7603200/ 7603200
+d66af9c3aa21371f8483a2d32af2ff59 *tests/data/fate/vsynth2-ffvhuff444p16.avi
+26612920 tests/data/fate/vsynth2-ffvhuff444p16.avi
+410af07de7ae21936aaeae03fc90cbc9 *tests/data/fate/vsynth2-ffvhuff444p16.out.rawvideo
+stddev: 0.53 PSNR: 53.63 MAXDIFF: 13 bytes: 7603200/ 7603200
-0667077971e0cb63b5f49c580006e90e *tests/data/fate/vsynth2-flashsv.flv
-12368953 tests/data/fate/vsynth2-flashsv.flv
-3a984506f1ebfc9fb73b6814cab201cc *tests/data/fate/vsynth2-flashsv.out.rawvideo
-stddev: 0.66 PSNR: 51.73 MAXDIFF: 14 bytes: 7603200/ 7603200
+f4b45770dd93b43b4077532e8ef90bfc *tests/data/fate/vsynth2-flashsv.flv
+11636546 tests/data/fate/vsynth2-flashsv.flv
+7f0fc12c02e68faddc153e69ddd6841c *tests/data/fate/vsynth2-flashsv.out.rawvideo
+stddev: 1.20 PSNR: 46.52 MAXDIFF: 20 bytes: 7603200/ 7603200
-01e0aa4da9ccc8e12fd03df63625eea4 *tests/data/fate/vsynth2-flashsv2.flv
-9291162 tests/data/fate/vsynth2-flashsv2.flv
-8f63e24049ba1789a7f8353c695a3d99 *tests/data/fate/vsynth2-flashsv2.out.rawvideo
-stddev: 2.39 PSNR: 40.55 MAXDIFF: 21 bytes: 7603200/ 7603200
+22bdec26851a2003c9f37dd1828284da *tests/data/fate/vsynth2-flashsv2.flv
+8660168 tests/data/fate/vsynth2-flashsv2.flv
+c1b3691276c2982ea55c34c130b2fdb1 *tests/data/fate/vsynth2-flashsv2.out.rawvideo
+stddev: 2.87 PSNR: 38.97 MAXDIFF: 28 bytes: 7603200/ 7603200
-dee04bdab18c2eed81373faec89fd5a7 *tests/data/fate/vsynth2-flv.flv
-131380 tests/data/fate/vsynth2-flv.flv
-184034553ceb801bb1d1521d2d998a67 *tests/data/fate/vsynth2-flv.out.rawvideo
-stddev: 5.33 PSNR: 33.59 MAXDIFF: 79 bytes: 7603200/ 7603200
+9c5da517eec395fd98318a4a86578f03 *tests/data/fate/vsynth2-flv.flv
+174673 tests/data/fate/vsynth2-flv.flv
+b49557d32c0a4a230a1201b270cfadc3 *tests/data/fate/vsynth2-flv.out.rawvideo
+stddev: 6.02 PSNR: 32.53 MAXDIFF: 83 bytes: 7603200/ 7603200
-6399cb1044e5433c844c21790fc17128 *tests/data/fate/vsynth2-h261.avi
-191060 tests/data/fate/vsynth2-h261.avi
-08f65e9aeeeaf189548c2bb417d5114f *tests/data/fate/vsynth2-h261.out.rawvideo
-stddev: 6.37 PSNR: 32.03 MAXDIFF: 77 bytes: 7603200/ 7603200
+99f46a0a9d77052818e503f17376c67b *tests/data/fate/vsynth2-h261.avi
+257934 tests/data/fate/vsynth2-h261.avi
+8962b6ea3153a828e5a4df68e1d5da44 *tests/data/fate/vsynth2-h261.out.rawvideo
+stddev: 7.21 PSNR: 30.97 MAXDIFF: 96 bytes: 7603200/ 7603200
-616cb40cf84704d177e207ee85a24531 *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
+21e3d72b623a17d695e9a7d491d932e4 *tests/data/fate/vsynth2-h261-trellis.avi
+249852 tests/data/fate/vsynth2-h261-trellis.avi
+15452237f6c333690d3e05f354f63196 *tests/data/fate/vsynth2-h261-trellis.out.rawvideo
+stddev: 7.10 PSNR: 31.10 MAXDIFF: 96 bytes: 7603200/ 7603200
-b5ea141b794ad88019507375ec092ad7 *tests/data/fate/vsynth2-h263.avi
-160102 tests/data/fate/vsynth2-h263.avi
-b7d733ebedbaa04f49bf7493a907e223 *tests/data/fate/vsynth2-h263.out.rawvideo
-stddev: 5.43 PSNR: 33.42 MAXDIFF: 77 bytes: 7603200/ 7603200
+0f4436f0e58e5e26ed191647b17325f6 *tests/data/fate/vsynth2-h263.avi
+216470 tests/data/fate/vsynth2-h263.avi
+d77291a0611eeec0667bbc3aba7190b8 *tests/data/fate/vsynth2-h263.out.rawvideo
+stddev: 6.12 PSNR: 32.39 MAXDIFF: 83 bytes: 7603200/ 7603200
-d242b7948697014abcaaff50551400ac *tests/data/fate/vsynth2-h263-obmc.avi
-154726 tests/data/fate/vsynth2-h263-obmc.avi
-588d992d9d8096da8bdc5027268da914 *tests/data/fate/vsynth2-h263-obmc.out.rawvideo
-stddev: 5.39 PSNR: 33.49 MAXDIFF: 82 bytes: 7603200/ 7603200
+7b2bd6306c6d5a5d092d45087ceb0ed8 *tests/data/fate/vsynth2-h263-obmc.avi
+208518 tests/data/fate/vsynth2-h263-obmc.avi
+4a939ef99fc759293f2e609bfcacd2a4 *tests/data/fate/vsynth2-h263-obmc.out.rawvideo
+stddev: 6.10 PSNR: 32.41 MAXDIFF: 90 bytes: 7603200/ 7603200
-000157a2e05709df95e40bd5e2185141 *tests/data/fate/vsynth2-h263p.avi
-867998 tests/data/fate/vsynth2-h263p.avi
-dca18571c05c13dd691d7b0b232e43fc *tests/data/fate/vsynth2-h263p.out.rawvideo
-stddev: 1.91 PSNR: 42.50 MAXDIFF: 19 bytes: 7603200/ 7603200
+4026635d74704989f48a6599c1a8a076 *tests/data/fate/vsynth2-h263p.avi
+1134962 tests/data/fate/vsynth2-h263p.avi
+66e8c0bd40918f970e62b6cdd7df79a5 *tests/data/fate/vsynth2-h263p.out.rawvideo
+stddev: 2.01 PSNR: 42.04 MAXDIFF: 21 bytes: 7603200/ 7603200
-c639e4044a66dc5dffb46d5d82516ef8 *tests/data/fate/vsynth2-huffyuv.avi
-6108510 tests/data/fate/vsynth2-huffyuv.avi
-dde5895817ad9d219f79a52d0bdfb001 *tests/data/fate/vsynth2-huffyuv.out.rawvideo
+e0fdf09f1265c24d2878088594f88ecf *tests/data/fate/vsynth2-huffyuv.avi
+6159094 tests/data/fate/vsynth2-huffyuv.avi
+36d7ca943916e1743cefa609eba0205c *tests/data/fate/vsynth2-huffyuv.out.rawvideo
stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 7603200/ 7603200
-d72d98a2847811499028f8997320a38b *tests/data/fate/vsynth2-huffyuvbgr24.avi
-8872410 tests/data/fate/vsynth2-huffyuvbgr24.avi
-0a8b7ddfec03622e37c869c5b552f9fc *tests/data/fate/vsynth2-huffyuvbgr24.out.rawvideo
-stddev: 1.24 PSNR: 46.26 MAXDIFF: 17 bytes: 7603200/ 7603200
+06eb7c8bd4cc8401431b1a6ce7652b34 *tests/data/fate/vsynth2-huffyuvbgr24.avi
+8809206 tests/data/fate/vsynth2-huffyuvbgr24.avi
+835a86f8dff88917c3e5f2776954c5b7 *tests/data/fate/vsynth2-huffyuvbgr24.out.rawvideo
+stddev: 1.57 PSNR: 44.18 MAXDIFF: 20 bytes: 7603200/ 7603200
-e8c2dbe6ad5d273af2bdb2dc3a2a524d *tests/data/fate/vsynth2-huffyuvbgra.avi
-10139598 tests/data/fate/vsynth2-huffyuvbgra.avi
-0a8b7ddfec03622e37c869c5b552f9fc *tests/data/fate/vsynth2-huffyuvbgra.out.rawvideo
-stddev: 1.24 PSNR: 46.26 MAXDIFF: 17 bytes: 7603200/ 7603200
+5f386d45bd3b2c250c5db43ab59b3439 *tests/data/fate/vsynth2-huffyuvbgra.avi
+10076386 tests/data/fate/vsynth2-huffyuvbgra.avi
+835a86f8dff88917c3e5f2776954c5b7 *tests/data/fate/vsynth2-huffyuvbgra.out.rawvideo
+stddev: 1.57 PSNR: 44.18 MAXDIFF: 20 bytes: 7603200/ 7603200
-6cf1985f29a7febbb79edf1d5268e203 *tests/data/fate/vsynth2-jpeg2000.avi
-1151144 tests/data/fate/vsynth2-jpeg2000.avi
-e7d79c9e11d0fe97f03e38be66c34e4f *tests/data/fate/vsynth2-jpeg2000.out.rawvideo
-stddev: 4.41 PSNR: 35.23 MAXDIFF: 63 bytes: 7603200/ 7603200
+bd10f835a585ca63bcd6f94a5a71b1d4 *tests/data/fate/vsynth2-jpeg2000.avi
+1513140 tests/data/fate/vsynth2-jpeg2000.avi
+1d33de510f21eaad6c3cecfcf29798ba *tests/data/fate/vsynth2-jpeg2000.out.rawvideo
+stddev: 4.99 PSNR: 34.17 MAXDIFF: 70 bytes: 7603200/ 7603200
-7cdaa014398f52869704dc537983db54 *tests/data/fate/vsynth2-jpeg2000-97.avi
-1118952 tests/data/fate/vsynth2-jpeg2000-97.avi
-8ac8b9ee81fa73c873668e9f6b78764d *tests/data/fate/vsynth2-jpeg2000-97.out.rawvideo
-stddev: 4.95 PSNR: 34.23 MAXDIFF: 60 bytes: 7603200/ 7603200
+91c0f0afa29952204ebfc2f93fb41c75 *tests/data/fate/vsynth2-jpeg2000-97.avi
+1467468 tests/data/fate/vsynth2-jpeg2000-97.avi
+e523db4385f586d73aa0ee2688a75d2e *tests/data/fate/vsynth2-jpeg2000-97.out.rawvideo
+stddev: 5.44 PSNR: 33.41 MAXDIFF: 57 bytes: 7603200/ 7603200
-9840b70886b4fc86512de729e41de979 *tests/data/fate/vsynth2-jpegls.avi
-8334618 tests/data/fate/vsynth2-jpegls.avi
-3a984506f1ebfc9fb73b6814cab201cc *tests/data/fate/vsynth2-jpegls.out.rawvideo
-stddev: 0.66 PSNR: 51.73 MAXDIFF: 14 bytes: 7603200/ 7603200
+c51763b68e2c1f37c7d588c0f1ea532f *tests/data/fate/vsynth2-jpegls.avi
+8311644 tests/data/fate/vsynth2-jpegls.avi
+7f0fc12c02e68faddc153e69ddd6841c *tests/data/fate/vsynth2-jpegls.out.rawvideo
+stddev: 1.20 PSNR: 46.52 MAXDIFF: 20 bytes: 7603200/ 7603200
-234a0e54d00829513bdc92fc580b2598 *tests/data/fate/vsynth2-ljpeg.avi
-4763454 tests/data/fate/vsynth2-ljpeg.avi
-dde5895817ad9d219f79a52d0bdfb001 *tests/data/fate/vsynth2-ljpeg.out.rawvideo
+bc40b0e3bf900ce18942886c9193869c *tests/data/fate/vsynth2-ljpeg.avi
+4712244 tests/data/fate/vsynth2-ljpeg.avi
+36d7ca943916e1743cefa609eba0205c *tests/data/fate/vsynth2-ljpeg.out.rawvideo
stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 7603200/ 7603200
-a3c1f9f7887b726bab17dbafa5debdca *tests/data/fate/vsynth2-mjpeg.avi
-673174 tests/data/fate/vsynth2-mjpeg.avi
-9d4bd90e9abfa18192383b4adc23c8d4 *tests/data/fate/vsynth2-mjpeg.out.rawvideo
-stddev: 4.32 PSNR: 35.40 MAXDIFF: 49 bytes: 7603200/ 7603200
+52873568b64fd315f01559d1216930b2 *tests/data/fate/vsynth2-mjpeg.avi
+830150 tests/data/fate/vsynth2-mjpeg.avi
+2b8c59c59e33d6ca7c85d31c5eeab7be *tests/data/fate/vsynth2-mjpeg.out.rawvideo
+stddev: 4.87 PSNR: 34.37 MAXDIFF: 55 bytes: 7603200/ 7603200
-ebf2e0f17a75119ff86b15e721d16a76 *tests/data/fate/vsynth2-mjpeg-422.avi
-746530 tests/data/fate/vsynth2-mjpeg-422.avi
-451ac80989c4e14445cf951fd7f83b6d *tests/data/fate/vsynth2-mjpeg-422.out.rawvideo
-stddev: 4.18 PSNR: 35.70 MAXDIFF: 49 bytes: 7603200/ 7603200
+98afd6e384f6c0dad8d5e713be157cf3 *tests/data/fate/vsynth2-mjpeg-422.avi
+920360 tests/data/fate/vsynth2-mjpeg-422.avi
+4a1b18eeb8b0f3dccc2c0e6a9f8c876d *tests/data/fate/vsynth2-mjpeg-422.out.rawvideo
+stddev: 4.69 PSNR: 34.69 MAXDIFF: 55 bytes: 7603200/ 7603200
-7674eb1aedaad0976c60329f556440d1 *tests/data/fate/vsynth2-mjpeg-444.avi
-851442 tests/data/fate/vsynth2-mjpeg-444.avi
-34edcb9c87ff7aac456a4fb07f43504b *tests/data/fate/vsynth2-mjpeg-444.out.rawvideo
-stddev: 4.05 PSNR: 35.96 MAXDIFF: 49 bytes: 7603200/ 7603200
+0f8f4b3b45bfd0157ac4500cf88a639b *tests/data/fate/vsynth2-mjpeg-444.avi
+1060066 tests/data/fate/vsynth2-mjpeg-444.avi
+6417f5a4be03ca7854f0a1be429a286e *tests/data/fate/vsynth2-mjpeg-444.out.rawvideo
+stddev: 4.57 PSNR: 34.93 MAXDIFF: 55 bytes: 7603200/ 7603200
-a77a8eb6e2ad32a5b20b41abda16f4c1 *tests/data/fate/vsynth2-mpeg1.mpeg1video
-192794 tests/data/fate/vsynth2-mpeg1.mpeg1video
-b3584042c60385e0fb988b8ec5b36409 *tests/data/fate/vsynth2-mpeg1.out.rawvideo
-stddev: 4.95 PSNR: 34.22 MAXDIFF: 57 bytes: 7603200/ 7603200
+2e5441dfaf41f9afc1934c9f475afa5d *tests/data/fate/vsynth2-mpeg1.mpeg1video
+262153 tests/data/fate/vsynth2-mpeg1.mpeg1video
+5fd6c2afc4f880cdf65637bfd8d94d9d *tests/data/fate/vsynth2-mpeg1.out.rawvideo
+stddev: 5.54 PSNR: 33.26 MAXDIFF: 77 bytes: 7603200/ 7603200
-333395b113b8045bac4e3fd90839ca6a *tests/data/fate/vsynth2-mpeg1b.mpeg1video
-225201 tests/data/fate/vsynth2-mpeg1b.mpeg1video
-f17fb3eef4ed3d03eeaaee45b217f7a5 *tests/data/fate/vsynth2-mpeg1b.out.rawvideo
-stddev: 4.10 PSNR: 35.86 MAXDIFF: 59 bytes: 7603200/ 7603200
+1496c950cd3d3b61b08b5888c5ae42a1 *tests/data/fate/vsynth2-mpeg1b.mpeg1video
+298132 tests/data/fate/vsynth2-mpeg1b.mpeg1video
+e300711fe39a914c66793b806360b754 *tests/data/fate/vsynth2-mpeg1b.out.rawvideo
+stddev: 4.60 PSNR: 34.87 MAXDIFF: 77 bytes: 7603200/ 7603200
-6071414a26d41ae9c4cc5477d8ca19eb *tests/data/fate/vsynth2-mpeg2.mpeg2video
-198673 tests/data/fate/vsynth2-mpeg2.mpeg2video
-9efe4846a75d9b7387d1e3bb1e5db29a *tests/data/fate/vsynth2-mpeg2.out.rawvideo
-stddev: 4.96 PSNR: 34.20 MAXDIFF: 59 bytes: 7603200/ 7603200
+38afa638d9ac0b9c7ccebb8073412920 *tests/data/fate/vsynth2-mpeg2.mpeg2video
+268153 tests/data/fate/vsynth2-mpeg2.mpeg2video
+bbddc9948fadfcc79487b391417ba8ed *tests/data/fate/vsynth2-mpeg2.out.rawvideo
+stddev: 5.55 PSNR: 33.23 MAXDIFF: 77 bytes: 7603200/ 7603200
-521ec92c0b8672011a43dd13db98c400 *tests/data/fate/vsynth2-mpeg2-422.mpeg2video
-356431 tests/data/fate/vsynth2-mpeg2-422.mpeg2video
-51ca353620f85db8b5b1c56f1a275add *tests/data/fate/vsynth2-mpeg2-422.out.rawvideo
-stddev: 3.15 PSNR: 38.14 MAXDIFF: 49 bytes: 7603200/ 7603200
+b2fa9b73c3547191ecc01b8163abd4e5 *tests/data/fate/vsynth2-mpeg2-422.mpeg2video
+379164 tests/data/fate/vsynth2-mpeg2-422.mpeg2video
+704f6a96f93c2409219bd48b74169041 *tests/data/fate/vsynth2-mpeg2-422.out.rawvideo
+stddev: 4.17 PSNR: 35.73 MAXDIFF: 70 bytes: 7603200/ 7603200
-505371e1b10f5af01b63b3f57606b26e *tests/data/fate/vsynth2-mpeg2-idct-int.mpeg2video
-198041 tests/data/fate/vsynth2-mpeg2-idct-int.mpeg2video
-92794e70e4a19a494f10efe353d9895d *tests/data/fate/vsynth2-mpeg2-idct-int.out.rawvideo
-stddev: 4.97 PSNR: 34.19 MAXDIFF: 58 bytes: 7603200/ 7603200
+67a99a21e2b88e22b64d8e3d1b5572e8 *tests/data/fate/vsynth2-mpeg2-idct-int.mpeg2video
+267370 tests/data/fate/vsynth2-mpeg2-idct-int.mpeg2video
+b750f48d58f157da94613fe92012e7a5 *tests/data/fate/vsynth2-mpeg2-idct-int.out.rawvideo
+stddev: 5.56 PSNR: 33.22 MAXDIFF: 77 bytes: 7603200/ 7603200
-dbc7dd0272f3711f50722f4753e3bfb0 *tests/data/fate/vsynth2-mpeg2-ilace.mpeg2video
-204576 tests/data/fate/vsynth2-mpeg2-ilace.mpeg2video
-d69be0d4ba1cb9c1fef9fb0d94a912ba *tests/data/fate/vsynth2-mpeg2-ilace.out.rawvideo
-stddev: 4.98 PSNR: 34.18 MAXDIFF: 65 bytes: 7603200/ 7603200
+b7d52a6496d439f61e8199bfa53e8af8 *tests/data/fate/vsynth2-mpeg2-ilace.mpeg2video
+274976 tests/data/fate/vsynth2-mpeg2-ilace.mpeg2video
+7c5b9f6986686e1c3accbc16efd02408 *tests/data/fate/vsynth2-mpeg2-ilace.out.rawvideo
+stddev: 5.57 PSNR: 33.20 MAXDIFF: 77 bytes: 7603200/ 7603200
-5731a196498d4e8097c0ebe57e383ef6 *tests/data/fate/vsynth2-mpeg2-ivlc-qprd.mpeg2video
-244694 tests/data/fate/vsynth2-mpeg2-ivlc-qprd.mpeg2video
-b26e21599dee48a174bdbc40b2817e55 *tests/data/fate/vsynth2-mpeg2-ivlc-qprd.out.rawvideo
-stddev: 4.15 PSNR: 35.76 MAXDIFF: 74 bytes: 7603200/ 7603200
+907a30295ed8323780eee08e606af0ab *tests/data/fate/vsynth2-mpeg2-ivlc-qprd.mpeg2video
+269722 tests/data/fate/vsynth2-mpeg2-ivlc-qprd.mpeg2video
+d2d9793bf8f3427b5cc17a1be78ddd64 *tests/data/fate/vsynth2-mpeg2-ivlc-qprd.out.rawvideo
+stddev: 5.54 PSNR: 33.25 MAXDIFF: 94 bytes: 7603200/ 7603200
-9e734d384b4234d075203dffffa5174c *tests/data/fate/vsynth2-mpeg2-thread.mpeg2video
-179656 tests/data/fate/vsynth2-mpeg2-thread.mpeg2video
-f8f084b7f51fbe4f82d57b8aeec17edf *tests/data/fate/vsynth2-mpeg2-thread.out.rawvideo
-stddev: 4.72 PSNR: 34.65 MAXDIFF: 72 bytes: 7603200/ 7603200
+a451384397f9b64a48fbb52e70be85ec *tests/data/fate/vsynth2-mpeg2-thread.mpeg2video
+230624 tests/data/fate/vsynth2-mpeg2-thread.mpeg2video
+6d666990137b894baf28aadc306f7c2b *tests/data/fate/vsynth2-mpeg2-thread.out.rawvideo
+stddev: 5.31 PSNR: 33.62 MAXDIFF: 73 bytes: 7603200/ 7603200
-39ae4e15e3da14218ebf250180badd92 *tests/data/fate/vsynth2-mpeg2-thread-ivlc.mpeg2video
-178807 tests/data/fate/vsynth2-mpeg2-thread-ivlc.mpeg2video
-f8f084b7f51fbe4f82d57b8aeec17edf *tests/data/fate/vsynth2-mpeg2-thread-ivlc.out.rawvideo
-stddev: 4.72 PSNR: 34.65 MAXDIFF: 72 bytes: 7603200/ 7603200
+ec4005f89785d14fbb3da14e9e3b18f5 *tests/data/fate/vsynth2-mpeg2-thread-ivlc.mpeg2video
+227850 tests/data/fate/vsynth2-mpeg2-thread-ivlc.mpeg2video
+6d666990137b894baf28aadc306f7c2b *tests/data/fate/vsynth2-mpeg2-thread-ivlc.out.rawvideo
+stddev: 5.31 PSNR: 33.62 MAXDIFF: 73 bytes: 7603200/ 7603200
-4a029747434d24d128b078a5e6aa1e88 *tests/data/fate/vsynth2-mpeg4.mp4
-119722 tests/data/fate/vsynth2-mpeg4.mp4
-9a1e085d9e488c5ead0c940c9612a37a *tests/data/fate/vsynth2-mpeg4.out.rawvideo
-stddev: 5.34 PSNR: 33.57 MAXDIFF: 83 bytes: 7603200/ 7603200
+adbd883d1701beabd04522d003dafab6 *tests/data/fate/vsynth2-mpeg4.mp4
+159310 tests/data/fate/vsynth2-mpeg4.mp4
+2645405bc5350acc85ad72f3352f5135 *tests/data/fate/vsynth2-mpeg4.out.rawvideo
+stddev: 6.02 PSNR: 32.53 MAXDIFF: 89 bytes: 7603200/ 7603200
-bbb12e077f858242c1387d23d2ccdae8 *tests/data/fate/vsynth2-mpeg4-adap.avi
-198496 tests/data/fate/vsynth2-mpeg4-adap.avi
-87b6dbe98d276137fceaae2fa672eced *tests/data/fate/vsynth2-mpeg4-adap.out.rawvideo
-stddev: 3.75 PSNR: 36.65 MAXDIFF: 71 bytes: 7603200/ 7603200
+36f4edf171cd1990211a44136fa1d038 *tests/data/fate/vsynth2-mpeg4-adap.avi
+213504 tests/data/fate/vsynth2-mpeg4-adap.avi
+0c709f2b81f4593eaa29490332c2cb39 *tests/data/fate/vsynth2-mpeg4-adap.out.rawvideo
+stddev: 4.87 PSNR: 34.36 MAXDIFF: 86 bytes: 7603200/ 7603200
-9fa1b5a68a6128a7160cfc8443a696e1 *tests/data/fate/vsynth2-mpeg4-adv.avi
-141534 tests/data/fate/vsynth2-mpeg4-adv.avi
-3f3a21e9db85a9c0f7022f557a5374c1 *tests/data/fate/vsynth2-mpeg4-adv.out.rawvideo
-stddev: 4.94 PSNR: 34.25 MAXDIFF: 69 bytes: 7603200/ 7603200
+42618863ff3400b699775ed7de5a6e5f *tests/data/fate/vsynth2-mpeg4-adv.avi
+187242 tests/data/fate/vsynth2-mpeg4-adv.avi
+505bdffb9b051dc2123d07a4ae183faf *tests/data/fate/vsynth2-mpeg4-adv.out.rawvideo
+stddev: 5.51 PSNR: 33.30 MAXDIFF: 80 bytes: 7603200/ 7603200
-82510449a3200b58dbcfbf0a643eb624 *tests/data/fate/vsynth2-mpeg4-error.avi
-180364 tests/data/fate/vsynth2-mpeg4-error.avi
-4537ba5320f1ae0971cc6e329c366776 *tests/data/fate/vsynth2-mpeg4-error.out.rawvideo
-stddev: 7.65 PSNR: 30.45 MAXDIFF: 158 bytes: 7603200/ 7603200
+aa15d3d241e2d23d1f17e30833b8ee99 *tests/data/fate/vsynth2-mpeg4-error.avi
+236056 tests/data/fate/vsynth2-mpeg4-error.avi
+f67a99fe41cd22a2a6713965eebb990e *tests/data/fate/vsynth2-mpeg4-error.out.rawvideo
+stddev: 15.66 PSNR: 24.23 MAXDIFF: 236 bytes: 7603200/ 7603200
-cf0cde80515f8bfbd89d33aa51f1c5e1 *tests/data/fate/vsynth2-mpeg4-nr.avi
-154994 tests/data/fate/vsynth2-mpeg4-nr.avi
-d89cd5d0b1707f48fa9c4747c66d2d56 *tests/data/fate/vsynth2-mpeg4-nr.out.rawvideo
-stddev: 4.73 PSNR: 34.63 MAXDIFF: 64 bytes: 7603200/ 7603200
+402c4381982f706fac32a693de9d9001 *tests/data/fate/vsynth2-mpeg4-nr.avi
+206034 tests/data/fate/vsynth2-mpeg4-nr.avi
+b1b0edaec04620b5f9149dce5171939c *tests/data/fate/vsynth2-mpeg4-nr.out.rawvideo
+stddev: 5.32 PSNR: 33.61 MAXDIFF: 78 bytes: 7603200/ 7603200
-b60bb3d8b942795272f0f0d89cd6351e *tests/data/fate/vsynth2-mpeg4-nsse.avi
-198434 tests/data/fate/vsynth2-mpeg4-nsse.avi
-59864a1050e641eaed8b0ee077bc780b *tests/data/fate/vsynth2-mpeg4-nsse.out.rawvideo
-stddev: 4.32 PSNR: 35.40 MAXDIFF: 60 bytes: 7603200/ 7603200
+dc007cd18a96cacbac7c8c182a397267 *tests/data/fate/vsynth2-mpeg4-nsse.avi
+266096 tests/data/fate/vsynth2-mpeg4-nsse.avi
+9123b1641394250a6edd389d02f249e8 *tests/data/fate/vsynth2-mpeg4-nsse.out.rawvideo
+stddev: 4.83 PSNR: 34.45 MAXDIFF: 59 bytes: 7603200/ 7603200
-ab94d9e56635e100d95e74fc8dc845e5 *tests/data/fate/vsynth2-mpeg4-qpel.avi
-163662 tests/data/fate/vsynth2-mpeg4-qpel.avi
-e2ce994dbb66da51c2e1ad26617d7c2f *tests/data/fate/vsynth2-mpeg4-qpel.out.rawvideo
-stddev: 3.97 PSNR: 36.14 MAXDIFF: 54 bytes: 7603200/ 7603200
+5213d1609a3ee3a92e9abfddc214bd1d *tests/data/fate/vsynth2-mpeg4-qpel.avi
+209866 tests/data/fate/vsynth2-mpeg4-qpel.avi
+5313cb1ef8c520de548389d541842c51 *tests/data/fate/vsynth2-mpeg4-qpel.out.rawvideo
+stddev: 4.42 PSNR: 35.22 MAXDIFF: 56 bytes: 7603200/ 7603200
-a576ecbf48c33916f2d17cf1bf37f3fe *tests/data/fate/vsynth2-mpeg4-qprd.avi
-231450 tests/data/fate/vsynth2-mpeg4-qprd.avi
-3071250e0864546c2455c9f9c9b8604e *tests/data/fate/vsynth2-mpeg4-qprd.out.rawvideo
-stddev: 3.71 PSNR: 36.72 MAXDIFF: 61 bytes: 7603200/ 7603200
+0a3dd46ad20ea8e5e07aab03f2175487 *tests/data/fate/vsynth2-mpeg4-qprd.avi
+248702 tests/data/fate/vsynth2-mpeg4-qprd.avi
+baa8d0d57a7fb5e393642cb20efed2c2 *tests/data/fate/vsynth2-mpeg4-qprd.out.rawvideo
+stddev: 4.85 PSNR: 34.40 MAXDIFF: 85 bytes: 7603200/ 7603200
-ea96539a0bebf70c3c09de0199a53a30 *tests/data/fate/vsynth2-mpeg4-rc.avi
-226310 tests/data/fate/vsynth2-mpeg4-rc.avi
-6e8b62e8c3bcbfdcc58afb69a0b1c4e3 *tests/data/fate/vsynth2-mpeg4-rc.out.rawvideo
-stddev: 4.23 PSNR: 35.60 MAXDIFF: 85 bytes: 7603200/ 7603200
+ba5823634562defe9a5d73e951e6849d *tests/data/fate/vsynth2-mpeg4-rc.avi
+254734 tests/data/fate/vsynth2-mpeg4-rc.avi
+53ef615a87c8ae49c379242385315f61 *tests/data/fate/vsynth2-mpeg4-rc.out.rawvideo
+stddev: 5.57 PSNR: 33.20 MAXDIFF: 116 bytes: 7603200/ 7603200
-8d7903d55221035c67866b8c1314c499 *tests/data/fate/vsynth2-mpeg4-thread.avi
-250092 tests/data/fate/vsynth2-mpeg4-thread.avi
-045fe9f226bbcc3d41644bffaed03b31 *tests/data/fate/vsynth2-mpeg4-thread.out.rawvideo
-stddev: 3.69 PSNR: 36.78 MAXDIFF: 65 bytes: 7603200/ 7603200
+48a493804d07360c413b189eed200306 *tests/data/fate/vsynth2-mpeg4-thread.avi
+268392 tests/data/fate/vsynth2-mpeg4-thread.avi
+f432bd8d897c7c8e286e385b77cedcfa *tests/data/fate/vsynth2-mpeg4-thread.out.rawvideo
+stddev: 4.89 PSNR: 34.34 MAXDIFF: 86 bytes: 7603200/ 7603200
-aaee9d1ff7dccfc045603c45f0160000 *tests/data/fate/vsynth2-mpng.avi
-12558330 tests/data/fate/vsynth2-mpng.avi
-98d0e2854731472c5bf13d8638502d0a *tests/data/fate/vsynth2-mpng.out.rawvideo
-stddev: 1.26 PSNR: 46.10 MAXDIFF: 13 bytes: 7603200/ 7603200
+77f4e52311a1b3a1abf10e0a68cad6eb *tests/data/fate/vsynth2-mpng.avi
+11816974 tests/data/fate/vsynth2-mpng.avi
+32fae3e665407bb4317b3f90fedb903c *tests/data/fate/vsynth2-mpng.out.rawvideo
+stddev: 1.54 PSNR: 44.37 MAXDIFF: 17 bytes: 7603200/ 7603200
-50b91fe78559c0f5f1e5873cdcc0e6a8 *tests/data/fate/vsynth2-msmpeg4.avi
-127660 tests/data/fate/vsynth2-msmpeg4.avi
-bb14902d5850d6b0ab70fdb017855775 *tests/data/fate/vsynth2-msmpeg4.out.rawvideo
-stddev: 5.33 PSNR: 33.58 MAXDIFF: 78 bytes: 7603200/ 7603200
+7c95be46992866b930e24fa96deb7fe4 *tests/data/fate/vsynth2-msmpeg4.avi
+170436 tests/data/fate/vsynth2-msmpeg4.avi
+81135454c184b78040c49a2aadca6394 *tests/data/fate/vsynth2-msmpeg4.out.rawvideo
+stddev: 6.02 PSNR: 32.53 MAXDIFF: 89 bytes: 7603200/ 7603200
-4770bd848f1937a861bf1a72295c6094 *tests/data/fate/vsynth2-msmpeg4v2.avi
-129918 tests/data/fate/vsynth2-msmpeg4v2.avi
-537c114e1d47c54a4bccd31f4073e9bd *tests/data/fate/vsynth2-msmpeg4v2.out.rawvideo
-stddev: 5.33 PSNR: 33.59 MAXDIFF: 79 bytes: 7603200/ 7603200
+a40774474aeee3534ae146fea8ee234a *tests/data/fate/vsynth2-msmpeg4v2.avi
+171906 tests/data/fate/vsynth2-msmpeg4v2.avi
+c4ca06487e0fdfdfccdccdb671acab42 *tests/data/fate/vsynth2-msmpeg4v2.out.rawvideo
+stddev: 6.02 PSNR: 32.53 MAXDIFF: 83 bytes: 7603200/ 7603200
-e554e31a4a635c924391228b7194d21b *tests/data/fate/vsynth2-msvideo1.avi
-914560 tests/data/fate/vsynth2-msvideo1.avi
-9a6ac7c0171286f009d159b59fdc1154 *tests/data/fate/vsynth2-msvideo1.out.rawvideo
-stddev: 7.97 PSNR: 30.10 MAXDIFF: 123 bytes: 7603200/ 7603200
+da9992daf1e15d7815fcd6c6b6be1b18 *tests/data/fate/vsynth2-msvideo1.avi
+1301736 tests/data/fate/vsynth2-msvideo1.avi
+9b6e5905b00c64ed936293f85abbd6cf *tests/data/fate/vsynth2-msvideo1.out.rawvideo
+stddev: 9.04 PSNR: 29.01 MAXDIFF: 169 bytes: 7603200/ 7603200
-637f34b5fd81f072f76a967595fa6af7 *tests/data/fate/vsynth2-prores.mov
-2844076 tests/data/fate/vsynth2-prores.mov
-03fd29e3963716a09d232b6f817ecb57 *tests/data/fate/vsynth2-prores.out.rawvideo
-stddev: 1.31 PSNR: 45.77 MAXDIFF: 11 bytes: 7603200/ 7603200
+aa57fd1221b7eefaf1f34f9d57d6a7cb *tests/data/fate/vsynth2-prores.mov
+3265056 tests/data/fate/vsynth2-prores.mov
+537b0ff66d7c8c3c12faa89d042e6a49 *tests/data/fate/vsynth2-prores.out.rawvideo
+stddev: 1.38 PSNR: 45.29 MAXDIFF: 12 bytes: 7603200/ 7603200
-b03741c69037cbdcd2809278c00c0350 *tests/data/fate/vsynth2-prores_ks.mov
-3884596 tests/data/fate/vsynth2-prores_ks.mov
-6cfe987de99cf8ac9d43bdc5cd150838 *tests/data/fate/vsynth2-prores_ks.out.rawvideo
-stddev: 0.92 PSNR: 48.78 MAXDIFF: 10 bytes: 7603200/ 7603200
+00c75fc738859e41c48cbe36ad60c2e2 *tests/data/fate/vsynth2-prores_ks.mov
+3868162 tests/data/fate/vsynth2-prores_ks.mov
+fe7ad707205c6100e9a3956d4e1c300e *tests/data/fate/vsynth2-prores_ks.out.rawvideo
+stddev: 1.17 PSNR: 46.72 MAXDIFF: 14 bytes: 7603200/ 7603200
-4863978263d966d704ffaaa6d23123bb *tests/data/fate/vsynth2-qtrle.mov
-14798345 tests/data/fate/vsynth2-qtrle.mov
-98d0e2854731472c5bf13d8638502d0a *tests/data/fate/vsynth2-qtrle.out.rawvideo
-stddev: 1.26 PSNR: 46.10 MAXDIFF: 13 bytes: 7603200/ 7603200
+b44d1cd0bb4c1e7c57d668bd9c1d319a *tests/data/fate/vsynth2-qtrle.mov
+14035926 tests/data/fate/vsynth2-qtrle.mov
+32fae3e665407bb4317b3f90fedb903c *tests/data/fate/vsynth2-qtrle.out.rawvideo
+stddev: 1.54 PSNR: 44.37 MAXDIFF: 17 bytes: 7603200/ 7603200
-2c4e69b59d8e8e19903c843575806d5f *tests/data/fate/vsynth2-qtrlegray.mov
-5111283 tests/data/fate/vsynth2-qtrlegray.mov
-d7bfbe259af9ae323bb94b09c33570a5 *tests/data/fate/vsynth2-qtrlegray.out.rawvideo
-stddev: 18.65 PSNR: 22.72 MAXDIFF: 72 bytes: 7603200/ 7603200
+4910471607743da624ef7339637a33e2 *tests/data/fate/vsynth2-qtrlegray.mov
+4988372 tests/data/fate/vsynth2-qtrlegray.mov
+510a92a21b552c51fcafab8188982f4d *tests/data/fate/vsynth2-qtrlegray.out.rawvideo
+stddev: 16.31 PSNR: 23.88 MAXDIFF: 89 bytes: 7603200/ 7603200
-16717c6cee907554cbeaefbbc116cd66 *tests/data/fate/vsynth2-r210.avi
+4ec1178f35bed604600da20b528b7372 *tests/data/fate/vsynth2-r210.avi
22125248 tests/data/fate/vsynth2-r210.avi
-6ea4fcd93fc83defc8770e85b64b60bb *tests/data/fate/vsynth2-r210.out.rawvideo
-stddev: 0.70 PSNR: 51.12 MAXDIFF: 12 bytes: 7603200/ 7603200
+2ade5f6167d7a4a1589e168ddbbc35d0 *tests/data/fate/vsynth2-r210.out.rawvideo
+stddev: 1.17 PSNR: 46.71 MAXDIFF: 15 bytes: 7603200/ 7603200
-188bce319523a1c7d24103aab1ed1bda *tests/data/fate/vsynth2-rgb.avi
+d32e51226ad1ef1ee0846841d077d4cd *tests/data/fate/vsynth2-rgb.avi
15213248 tests/data/fate/vsynth2-rgb.avi
-98d0e2854731472c5bf13d8638502d0a *tests/data/fate/vsynth2-rgb.out.rawvideo
-stddev: 1.26 PSNR: 46.10 MAXDIFF: 13 bytes: 7603200/ 7603200
+32fae3e665407bb4317b3f90fedb903c *tests/data/fate/vsynth2-rgb.out.rawvideo
+stddev: 1.54 PSNR: 44.37 MAXDIFF: 17 bytes: 7603200/ 7603200
-1a43cd71c91f2ef42d11a81419bff3bd *tests/data/fate/vsynth2-roqvideo.roq
-94810 tests/data/fate/vsynth2-roqvideo.roq
-97cda6096430c0ab7a43a0e120cd3e91 *tests/data/fate/vsynth2-roqvideo.out.rawvideo
-stddev: 3.81 PSNR: 36.50 MAXDIFF: 49 bytes: 7603200/ 760320
+f6caa394394e07b16c73fa2bb4807a88 *tests/data/fate/vsynth2-roqvideo.roq
+92517 tests/data/fate/vsynth2-roqvideo.roq
+a80f3f01b06b062ae416bee6a65917e9 *tests/data/fate/vsynth2-roqvideo.out.rawvideo
+stddev: 4.87 PSNR: 34.37 MAXDIFF: 73 bytes: 7603200/ 760320
-33a2aae3351b0b2121f823057c0e226f *tests/data/fate/vsynth2-rv10.rm
-154321 tests/data/fate/vsynth2-rv10.rm
-b7d733ebedbaa04f49bf7493a907e223 *tests/data/fate/vsynth2-rv10.out.rawvideo
-stddev: 5.43 PSNR: 33.42 MAXDIFF: 77 bytes: 7603200/ 7603200
+45a1e6800af36b7e2d42cadd2b6d1447 *tests/data/fate/vsynth2-rv10.rm
+210679 tests/data/fate/vsynth2-rv10.rm
+d77291a0611eeec0667bbc3aba7190b8 *tests/data/fate/vsynth2-rv10.out.rawvideo
+stddev: 6.12 PSNR: 32.39 MAXDIFF: 83 bytes: 7603200/ 7603200
-4d23a72fe7e29f98f38888804eacd111 *tests/data/fate/vsynth2-rv20.rm
-153304 tests/data/fate/vsynth2-rv20.rm
-6fa5dc1c2f00f858fc4895ad640891a2 *tests/data/fate/vsynth2-rv20.out.rawvideo
-stddev: 5.48 PSNR: 33.35 MAXDIFF: 81 bytes: 7603200/ 7603200
+17ea9a2979ce2a39a390643af5112fa6 *tests/data/fate/vsynth2-rv20.rm
+210658 tests/data/fate/vsynth2-rv20.rm
+3aa8e0c1d5dcf3f07960ac0a2d439b48 *tests/data/fate/vsynth2-rv20.out.rawvideo
+stddev: 6.19 PSNR: 32.28 MAXDIFF: 81 bytes: 7603200/ 7603200
-a7bc7eba6ac50f0b417cb9f829feb7a1 *tests/data/fate/vsynth2-snow.avi
-57688 tests/data/fate/vsynth2-snow.avi
-8890189af71a0dd3447c4e8424c9a76b *tests/data/fate/vsynth2-snow.out.rawvideo
-stddev: 10.47 PSNR: 27.72 MAXDIFF: 119 bytes: 7603200/ 7603200
+1ff8a762f2501b1b674cffa5d98631b3 *tests/data/fate/vsynth2-snow.avi
+72802 tests/data/fate/vsynth2-snow.avi
+fb1944b90011ff997e4762eebe3d5ad3 *tests/data/fate/vsynth2-snow.out.rawvideo
+stddev: 13.72 PSNR: 25.38 MAXDIFF: 162 bytes: 7603200/ 7603200
-fa6986c9ebaa087b037d099acefa0ade *tests/data/fate/vsynth2-snow-hpel.avi
-61760 tests/data/fate/vsynth2-snow-hpel.avi
-8680d40905f423999d65b996c4dcb984 *tests/data/fate/vsynth2-snow-hpel.out.rawvideo
-stddev: 10.45 PSNR: 27.74 MAXDIFF: 123 bytes: 7603200/ 7603200
+be952f3c331c49cad45b01311f586fae *tests/data/fate/vsynth2-snow-hpel.avi
+79724 tests/data/fate/vsynth2-snow-hpel.avi
+2cc64d8171175a1532fd7d3ed3011fbf *tests/data/fate/vsynth2-snow-hpel.out.rawvideo
+stddev: 13.70 PSNR: 25.39 MAXDIFF: 162 bytes: 7603200/ 7603200
-ed109f21012f92ad5ea19451844ae721 *tests/data/fate/vsynth2-snow-ll.avi
-2721746 tests/data/fate/vsynth2-snow-ll.avi
-dde5895817ad9d219f79a52d0bdfb001 *tests/data/fate/vsynth2-snow-ll.out.rawvideo
+615ef578a42f0d64fbf65b0c763df915 *tests/data/fate/vsynth2-snow-ll.avi
+2829414 tests/data/fate/vsynth2-snow-ll.avi
+36d7ca943916e1743cefa609eba0205c *tests/data/fate/vsynth2-snow-ll.out.rawvideo
stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 7603200/ 7603200
-6e9678439ab7460db1fcc8e41ca1a1e0 *tests/data/fate/vsynth2-svq1.mov
-766701 tests/data/fate/vsynth2-svq1.mov
-aa03471dac3f49455a33a2b19fda1098 *tests/data/fate/vsynth2-svq1.out.rawvideo
-stddev: 3.23 PSNR: 37.93 MAXDIFF: 61 bytes: 7603200/ 7603200
+c767386f0f6f36b554d278592bc6e9a4 *tests/data/fate/vsynth2-svq1.mov
+940289 tests/data/fate/vsynth2-svq1.mov
+a8cd3b833cd7f570ddbf1e6b3eb125b6 *tests/data/fate/vsynth2-svq1.out.rawvideo
+stddev: 3.71 PSNR: 36.72 MAXDIFF: 210 bytes: 7603200/ 7603200
-6fbbcfee1832fe4c62aacb70454cff62 *tests/data/fate/vsynth2-v210.avi
+06dc558ed5ea170f746bd40c94990adc *tests/data/fate/vsynth2-v210.avi
14752448 tests/data/fate/vsynth2-v210.avi
-a627fb50c8276200fd71383977d87ca3 *tests/data/fate/vsynth2-v210.out.rawvideo
-stddev: 0.34 PSNR: 57.43 MAXDIFF: 6 bytes: 7603200/ 7603200
+99e367a50da75c2c187230889bee8e2e *tests/data/fate/vsynth2-v210.out.rawvideo
+stddev: 0.40 PSNR: 56.06 MAXDIFF: 9 bytes: 7603200/ 7603200
-1ea64cd6ad32dae72963b8fdf89e96d1 *tests/data/fate/vsynth2-v308.avi
+62f4b2028533f889a932ed7b052abdcc *tests/data/fate/vsynth2-v308.avi
15213248 tests/data/fate/vsynth2-v308.avi
-d43cb310c130c69214332d74f6ee5f9a *tests/data/fate/vsynth2-v308.out.rawvideo
-stddev: 0.41 PSNR: 55.80 MAXDIFF: 7 bytes: 7603200/ 7603200
+8394327c14ef0b6fbaae3b69fcc5572a *tests/data/fate/vsynth2-v308.out.rawvideo
+stddev: 0.50 PSNR: 54.10 MAXDIFF: 13 bytes: 7603200/ 7603200
-b4cdf2351f908fc308d8693d0cee69e1 *tests/data/fate/vsynth2-v408.avi
+3efbdd666f299c23297db8e1cc137bc2 *tests/data/fate/vsynth2-v408.avi
20282048 tests/data/fate/vsynth2-v408.avi
-dde5895817ad9d219f79a52d0bdfb001 *tests/data/fate/vsynth2-v408.out.rawvideo
+36d7ca943916e1743cefa609eba0205c *tests/data/fate/vsynth2-v408.out.rawvideo
stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 7603200/ 7603200
-3099f5514693a609180ab5761dc8d4ca *tests/data/fate/vsynth2-wmv1.avi
-129510 tests/data/fate/vsynth2-wmv1.avi
-dec44e3c04db4fef49a7728f164d9159 *tests/data/fate/vsynth2-wmv1.out.rawvideo
-stddev: 5.33 PSNR: 33.60 MAXDIFF: 77 bytes: 7603200/ 7603200
+ab72afaaaf155eaeea89eef5adfcf8e5 *tests/data/fate/vsynth2-wmv1.avi
+172400 tests/data/fate/vsynth2-wmv1.avi
+da619b78881243205024fca4c525d8cc *tests/data/fate/vsynth2-wmv1.out.rawvideo
+stddev: 6.01 PSNR: 32.54 MAXDIFF: 88 bytes: 7603200/ 7603200
-c8d1d1371bd09add388c32f3259ef555 *tests/data/fate/vsynth2-wmv2.avi
-129852 tests/data/fate/vsynth2-wmv2.avi
-b4de16a0d302c52702f7a4362da989bc *tests/data/fate/vsynth2-wmv2.out.rawvideo
-stddev: 5.33 PSNR: 33.59 MAXDIFF: 77 bytes: 7603200/ 7603200
+a3f7bdaf87799839537951b40c765f9f *tests/data/fate/vsynth2-wmv2.avi
+173818 tests/data/fate/vsynth2-wmv2.avi
+cfcdca2c4b183c5502cd6ec69e573127 *tests/data/fate/vsynth2-wmv2.out.rawvideo
+stddev: 6.02 PSNR: 32.54 MAXDIFF: 88 bytes: 7603200/ 7603200
--- /dev/null
+dc0ff0ba9588dbec10580941529b77a2 *tests/data/fate/vsynth2-xface.nut
+16866 tests/data/fate/vsynth2-xface.nut
+71a54876bc79746cc8c36f3f02aea4ef *tests/data/fate/vsynth2-xface.out.rawvideo
+stddev: 86.58 PSNR: 9.38 MAXDIFF: 250 bytes: 7603200/ 7603200
-522ebf5fbf98aeec5ee6b39de1c1afc0 *tests/data/fate/vsynth2-y41p.avi
+9abb526eb8a5cacbabf2745099c850bf *tests/data/fate/vsynth2-y41p.avi
7610048 tests/data/fate/vsynth2-y41p.avi
-d27a84ccdac09055724d122e03fea82a *tests/data/fate/vsynth2-y41p.out.rawvideo
-stddev: 1.07 PSNR: 47.54 MAXDIFF: 21 bytes: 7603200/ 7603200
+7c760febffcf1c2e43e494f38b010af1 *tests/data/fate/vsynth2-y41p.out.rawvideo
+stddev: 1.32 PSNR: 45.72 MAXDIFF: 34 bytes: 7603200/ 7603200
-f48f08c67097b3c35b1105f24ef68a0c *tests/data/fate/vsynth2-yuv.avi
+b1abb1a3febd265c9dc57eaa421fe8ff *tests/data/fate/vsynth2-yuv.avi
7610048 tests/data/fate/vsynth2-yuv.avi
-dde5895817ad9d219f79a52d0bdfb001 *tests/data/fate/vsynth2-yuv.out.rawvideo
+36d7ca943916e1743cefa609eba0205c *tests/data/fate/vsynth2-yuv.out.rawvideo
stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 7603200/ 7603200
-1dcf2c21fe3ff1b57f9280a4fd550d14 *tests/data/fate/vsynth2-yuv4.avi
+4074b647de926ca3a91c987bc8f49d2a *tests/data/fate/vsynth2-yuv4.avi
7610048 tests/data/fate/vsynth2-yuv4.avi
-dde5895817ad9d219f79a52d0bdfb001 *tests/data/fate/vsynth2-yuv4.out.rawvideo
+36d7ca943916e1743cefa609eba0205c *tests/data/fate/vsynth2-yuv4.out.rawvideo
stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 7603200/ 7603200
-f2c6b3c88f07f0ed08dd25ca654854fb *tests/data/fate/vsynth2-zlib.avi
-12517176 tests/data/fate/vsynth2-zlib.avi
-98d0e2854731472c5bf13d8638502d0a *tests/data/fate/vsynth2-zlib.out.rawvideo
-stddev: 1.26 PSNR: 46.10 MAXDIFF: 13 bytes: 7603200/ 7603200
+f93b760f637c67e0945f564afc3a5f6c *tests/data/fate/vsynth2-zlib.avi
+11760516 tests/data/fate/vsynth2-zlib.avi
+32fae3e665407bb4317b3f90fedb903c *tests/data/fate/vsynth2-zlib.out.rawvideo
+stddev: 1.54 PSNR: 44.37 MAXDIFF: 17 bytes: 7603200/ 7603200
+++ /dev/null
-e9cc761eb3fedc36ce5f97744196ed8b *tests/data/fate/vsynth2-zmbv.avi
-1808720 tests/data/fate/vsynth2-zmbv.avi
-ee68a5292fd0745834246b4ec0d85e9b *tests/data/fate/vsynth2-zmbv.out.rawvideo
-stddev: 8.12 PSNR: 29.94 MAXDIFF: 32 bytes: 7603200/ 7603200
-d2f5e07f0c0e917d80d63f39d683919e *tests/data/fate/vsynth3-v210.avi
+6618ab86d047f4fb8fdd2d633888b20b *tests/data/fate/vsynth3-v210.avi
224448 tests/data/fate/vsynth3-v210.avi
-0cf7cf68724fa5146b1667e4fa08b0e1 *tests/data/fate/vsynth3-v210.out.rawvideo
-stddev: 2.12 PSNR: 41.58 MAXDIFF: 26 bytes: 86700/ 86700
+198ffb24c06927d8aaac5e59d81a0934 *tests/data/fate/vsynth3-v210.out.rawvideo
+stddev: 2.11 PSNR: 41.61 MAXDIFF: 27 bytes: 86700/ 86700
--- /dev/null
+f399a6b312d0a2d873b8a3bc761c5eba *tests/data/fate/vsynth3-xface.nut
+15696 tests/data/fate/vsynth3-xface.nut
+eafdc027c9c36f96e71e91a5682a0d2e *tests/data/fate/vsynth3-xface.out.rawvideo
+stddev: 97.22 PSNR: 8.37 MAXDIFF: 236 bytes: 86700/ 86700
--- /dev/null
+e0d0da8cf786616eff2e88c45644c902 *tests/data/fate/vsynth_lena-amv.avi
+761976 tests/data/fate/vsynth_lena-amv.avi
+f256ad9feefb499c6569d06d868eb496 *tests/data/fate/vsynth_lena-amv.out.rawvideo
+stddev: 4.30 PSNR: 35.46 MAXDIFF: 65 bytes: 7603200/ 7603200
--- /dev/null
+bffe7188b4b5c3ff76c75561d0bebd77 *tests/data/fate/vsynth_lena-asv1.avi
+689416 tests/data/fate/vsynth_lena-asv1.avi
+a7cdefad200f48ab308c746461a8792e *tests/data/fate/vsynth_lena-asv1.out.rawvideo
+stddev: 5.07 PSNR: 34.03 MAXDIFF: 70 bytes: 7603200/ 7603200
--- /dev/null
+f8c3b9899bbd9545757fac0c7ecf4e34 *tests/data/fate/vsynth_lena-asv2.avi
+675584 tests/data/fate/vsynth_lena-asv2.avi
+5990db66c7ac0bbe2f98ec2770c1bf3b *tests/data/fate/vsynth_lena-asv2.out.rawvideo
+stddev: 4.57 PSNR: 34.93 MAXDIFF: 47 bytes: 7603200/ 7603200
--- /dev/null
+df5efcfd2170df82e466be4deb7ce4a9 *tests/data/fate/vsynth_lena-avui.mov
+42624917 tests/data/fate/vsynth_lena-avui.mov
+dde5895817ad9d219f79a52d0bdfb001 *tests/data/fate/vsynth_lena-avui.out.rawvideo
+stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 7603200/ 7603200
--- /dev/null
+7bfd989038611212a80b5b050bb78ea7 *tests/data/fate/vsynth_lena-cljr.avi
+5075648 tests/data/fate/vsynth_lena-cljr.avi
+965c4a134144b30b24d6d138b03ddb8c *tests/data/fate/vsynth_lena-cljr.out.rawvideo
+stddev: 3.29 PSNR: 37.76 MAXDIFF: 23 bytes: 7603200/ 7603200
--- /dev/null
+d680a5eed77c5b8dc6b5ef3bcf6e87e8 *tests/data/fate/vsynth_lena-dnxhd-1080i.mov
+3031911 tests/data/fate/vsynth_lena-dnxhd-1080i.mov
+744ba46da5d4c19a28562ea31061d170 *tests/data/fate/vsynth_lena-dnxhd-1080i.out.rawvideo
+stddev: 1.31 PSNR: 45.77 MAXDIFF: 23 bytes: 7603200/ 760320
--- /dev/null
+4ca9473a8d106bdfe36e9bf7c516b648 *tests/data/fate/vsynth_lena-dnxhd-720p.dnxhd
+2293760 tests/data/fate/vsynth_lena-dnxhd-720p.dnxhd
+d44c4b08cda8a8042ae345124fdfffcc *tests/data/fate/vsynth_lena-dnxhd-720p.out.rawvideo
+stddev: 1.32 PSNR: 45.68 MAXDIFF: 22 bytes: 7603200/ 760320
--- /dev/null
+e96fc4a7d994b9369c50da32fd325822 *tests/data/fate/vsynth_lena-dnxhd-720p-10bit.dnxhd
+2293760 tests/data/fate/vsynth_lena-dnxhd-720p-10bit.dnxhd
+0449440eb3e8416840a27deb1a8f80b0 *tests/data/fate/vsynth_lena-dnxhd-720p-10bit.out.rawvideo
+stddev: 1.35 PSNR: 45.47 MAXDIFF: 22 bytes: 7603200/ 760320
--- /dev/null
+b305b03708e905717b42fc0b304367d4 *tests/data/fate/vsynth_lena-dnxhd-720p-rd.dnxhd
+2293760 tests/data/fate/vsynth_lena-dnxhd-720p-rd.dnxhd
+13de1c5ed025abb5120450e134aa623d *tests/data/fate/vsynth_lena-dnxhd-720p-rd.out.rawvideo
+stddev: 1.32 PSNR: 45.66 MAXDIFF: 22 bytes: 7603200/ 760320
--- /dev/null
+204e80f2e406ada90fca596ab2810b3e *./tests/data/vsynth_lena/dnxhd-1080i.mov
+3031911 ./tests/data/vsynth_lena/dnxhd-1080i.mov
+3c559af629ae0a8fb1a9a0e4b4da7733 *./tests/data/dnxhd_1080i.vsynth_lena.out.yuv
+stddev: 1.31 PSNR: 45.77 MAXDIFF: 23 bytes: 760320/ 7603200
--- /dev/null
+85b8d55b0b68bb3fc2e90babb580f9b7 *tests/data/fate/vsynth_lena-dv.dv
+7200000 tests/data/fate/vsynth_lena-dv.dv
+7dac420637360b031ccae7c5a69c5e0c *tests/data/fate/vsynth_lena-dv.out.rawvideo
+stddev: 1.70 PSNR: 43.47 MAXDIFF: 33 bytes: 7603200/ 7603200
--- /dev/null
+e428508f400327aeb96969c08fb9e1b5 *tests/data/fate/vsynth_lena-dv-411.dv
+7200000 tests/data/fate/vsynth_lena-dv-411.dv
+713ed907fde448c603d6e9aee5efedd1 *tests/data/fate/vsynth_lena-dv-411.out.rawvideo
+stddev: 2.89 PSNR: 38.91 MAXDIFF: 45 bytes: 7603200/ 7603200
--- /dev/null
+0032a07167199e6f49e07fa7ed4d5f62 *tests/data/fate/vsynth_lena-dv-50.dv
+14400000 tests/data/fate/vsynth_lena-dv-50.dv
+56c77e537291536b242857d1056de30c *tests/data/fate/vsynth_lena-dv-50.out.rawvideo
+stddev: 0.82 PSNR: 49.82 MAXDIFF: 12 bytes: 7603200/ 7603200
--- /dev/null
+e428508f400327aeb96969c08fb9e1b5 *./tests/data/vsynth_lena/dv411.dv
+7200000 ./tests/data/vsynth_lena/dv411.dv
+7f9fa421028aabb11eaf4c6513a5a843 *./tests/data/dv_411.vsynth_lena.out.yuv
+stddev: 10.09 PSNR: 28.05 MAXDIFF: 60 bytes: 7603200/ 7603200
--- /dev/null
+9e091bee097632ef7106d3bade12b81b *tests/data/fate/vsynth_lena-ffv1.avi
+3547788 tests/data/fate/vsynth_lena-ffv1.avi
+dde5895817ad9d219f79a52d0bdfb001 *tests/data/fate/vsynth_lena-ffv1.out.rawvideo
+stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 7603200/ 7603200
--- /dev/null
+114950628c091cd830d9e66e74f6bca2 *tests/data/fate/vsynth_lena-ffv1.0.avi
+3525792 tests/data/fate/vsynth_lena-ffv1.0.avi
+dde5895817ad9d219f79a52d0bdfb001 *tests/data/fate/vsynth_lena-ffv1.0.out.rawvideo
+stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 7603200/ 7603200
--- /dev/null
+7cb61df06d2cb4659ceb8d73c4822aaf *tests/data/fate/vsynth_lena-ffvhuff.avi
+4845022 tests/data/fate/vsynth_lena-ffvhuff.avi
+dde5895817ad9d219f79a52d0bdfb001 *tests/data/fate/vsynth_lena-ffvhuff.out.rawvideo
+stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 7603200/ 7603200
--- /dev/null
+e5873a19c7be1cdf25600eb033738b9e *tests/data/fate/vsynth_lena-ffvhuff420p12.avi
+10925576 tests/data/fate/vsynth_lena-ffvhuff420p12.avi
+08b3c6c70eba608bae926608ff253f2a *tests/data/fate/vsynth_lena-ffvhuff420p12.out.rawvideo
+stddev: 0.68 PSNR: 51.38 MAXDIFF: 1 bytes: 7603200/ 7603200
--- /dev/null
+d7d321c3b1ed3378e03b2f618f248d86 *tests/data/fate/vsynth_lena-ffvhuff422p10left.avi
+10041832 tests/data/fate/vsynth_lena-ffvhuff422p10left.avi
+a627fb50c8276200fd71383977d87ca3 *tests/data/fate/vsynth_lena-ffvhuff422p10left.out.rawvideo
+stddev: 0.34 PSNR: 57.43 MAXDIFF: 6 bytes: 7603200/ 7603200
--- /dev/null
+68e78dc89bb596f93a14e7f4a7a24365 *tests/data/fate/vsynth_lena-ffvhuff444.avi
+7530714 tests/data/fate/vsynth_lena-ffvhuff444.avi
+d43cb310c130c69214332d74f6ee5f9a *tests/data/fate/vsynth_lena-ffvhuff444.out.rawvideo
+stddev: 0.41 PSNR: 55.80 MAXDIFF: 7 bytes: 7603200/ 7603200
--- /dev/null
+db17747292df97d6c62b15b041c378da *tests/data/fate/vsynth_lena-ffvhuff444p16.avi
+26360716 tests/data/fate/vsynth_lena-ffvhuff444p16.avi
+05ccd9a38f9726030b3099c0c99d3a13 *tests/data/fate/vsynth_lena-ffvhuff444p16.out.rawvideo
+stddev: 0.45 PSNR: 55.06 MAXDIFF: 7 bytes: 7603200/ 7603200
--- /dev/null
+0667077971e0cb63b5f49c580006e90e *tests/data/fate/vsynth_lena-flashsv.flv
+12368953 tests/data/fate/vsynth_lena-flashsv.flv
+3a984506f1ebfc9fb73b6814cab201cc *tests/data/fate/vsynth_lena-flashsv.out.rawvideo
+stddev: 0.66 PSNR: 51.73 MAXDIFF: 14 bytes: 7603200/ 7603200
--- /dev/null
+01e0aa4da9ccc8e12fd03df63625eea4 *tests/data/fate/vsynth_lena-flashsv2.flv
+9291162 tests/data/fate/vsynth_lena-flashsv2.flv
+8f63e24049ba1789a7f8353c695a3d99 *tests/data/fate/vsynth_lena-flashsv2.out.rawvideo
+stddev: 2.39 PSNR: 40.55 MAXDIFF: 21 bytes: 7603200/ 7603200
--- /dev/null
+dee04bdab18c2eed81373faec89fd5a7 *tests/data/fate/vsynth_lena-flv.flv
+131380 tests/data/fate/vsynth_lena-flv.flv
+184034553ceb801bb1d1521d2d998a67 *tests/data/fate/vsynth_lena-flv.out.rawvideo
+stddev: 5.33 PSNR: 33.59 MAXDIFF: 79 bytes: 7603200/ 7603200
--- /dev/null
+6399cb1044e5433c844c21790fc17128 *tests/data/fate/vsynth_lena-h261.avi
+191060 tests/data/fate/vsynth_lena-h261.avi
+08f65e9aeeeaf189548c2bb417d5114f *tests/data/fate/vsynth_lena-h261.out.rawvideo
+stddev: 6.37 PSNR: 32.03 MAXDIFF: 77 bytes: 7603200/ 7603200
--- /dev/null
+616cb40cf84704d177e207ee85a24531 *tests/data/fate/vsynth_lena-h261-trellis.avi
+184582 tests/data/fate/vsynth_lena-h261-trellis.avi
+f9df8cd110a2f3d9706dd2f29a1d0a89 *tests/data/fate/vsynth_lena-h261-trellis.out.rawvideo
+stddev: 6.32 PSNR: 32.11 MAXDIFF: 89 bytes: 7603200/ 7603200
--- /dev/null
+b5ea141b794ad88019507375ec092ad7 *tests/data/fate/vsynth_lena-h263.avi
+160102 tests/data/fate/vsynth_lena-h263.avi
+b7d733ebedbaa04f49bf7493a907e223 *tests/data/fate/vsynth_lena-h263.out.rawvideo
+stddev: 5.43 PSNR: 33.42 MAXDIFF: 77 bytes: 7603200/ 7603200
--- /dev/null
+d242b7948697014abcaaff50551400ac *tests/data/fate/vsynth_lena-h263-obmc.avi
+154726 tests/data/fate/vsynth_lena-h263-obmc.avi
+588d992d9d8096da8bdc5027268da914 *tests/data/fate/vsynth_lena-h263-obmc.out.rawvideo
+stddev: 5.39 PSNR: 33.49 MAXDIFF: 82 bytes: 7603200/ 7603200
--- /dev/null
+000157a2e05709df95e40bd5e2185141 *tests/data/fate/vsynth_lena-h263p.avi
+867998 tests/data/fate/vsynth_lena-h263p.avi
+dca18571c05c13dd691d7b0b232e43fc *tests/data/fate/vsynth_lena-h263p.out.rawvideo
+stddev: 1.91 PSNR: 42.50 MAXDIFF: 19 bytes: 7603200/ 7603200
--- /dev/null
+c639e4044a66dc5dffb46d5d82516ef8 *tests/data/fate/vsynth_lena-huffyuv.avi
+6108510 tests/data/fate/vsynth_lena-huffyuv.avi
+dde5895817ad9d219f79a52d0bdfb001 *tests/data/fate/vsynth_lena-huffyuv.out.rawvideo
+stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 7603200/ 7603200
--- /dev/null
+d72d98a2847811499028f8997320a38b *tests/data/fate/vsynth_lena-huffyuvbgr24.avi
+8872410 tests/data/fate/vsynth_lena-huffyuvbgr24.avi
+0a8b7ddfec03622e37c869c5b552f9fc *tests/data/fate/vsynth_lena-huffyuvbgr24.out.rawvideo
+stddev: 1.24 PSNR: 46.26 MAXDIFF: 17 bytes: 7603200/ 7603200
--- /dev/null
+e8c2dbe6ad5d273af2bdb2dc3a2a524d *tests/data/fate/vsynth_lena-huffyuvbgra.avi
+10139598 tests/data/fate/vsynth_lena-huffyuvbgra.avi
+0a8b7ddfec03622e37c869c5b552f9fc *tests/data/fate/vsynth_lena-huffyuvbgra.out.rawvideo
+stddev: 1.24 PSNR: 46.26 MAXDIFF: 17 bytes: 7603200/ 7603200
--- /dev/null
+6cf1985f29a7febbb79edf1d5268e203 *tests/data/fate/vsynth_lena-jpeg2000.avi
+1151144 tests/data/fate/vsynth_lena-jpeg2000.avi
+e7d79c9e11d0fe97f03e38be66c34e4f *tests/data/fate/vsynth_lena-jpeg2000.out.rawvideo
+stddev: 4.41 PSNR: 35.23 MAXDIFF: 63 bytes: 7603200/ 7603200
--- /dev/null
+7cdaa014398f52869704dc537983db54 *tests/data/fate/vsynth_lena-jpeg2000-97.avi
+1118952 tests/data/fate/vsynth_lena-jpeg2000-97.avi
+8ac8b9ee81fa73c873668e9f6b78764d *tests/data/fate/vsynth_lena-jpeg2000-97.out.rawvideo
+stddev: 4.95 PSNR: 34.23 MAXDIFF: 60 bytes: 7603200/ 7603200
--- /dev/null
+9840b70886b4fc86512de729e41de979 *tests/data/fate/vsynth_lena-jpegls.avi
+8334618 tests/data/fate/vsynth_lena-jpegls.avi
+3a984506f1ebfc9fb73b6814cab201cc *tests/data/fate/vsynth_lena-jpegls.out.rawvideo
+stddev: 0.66 PSNR: 51.73 MAXDIFF: 14 bytes: 7603200/ 7603200
--- /dev/null
+234a0e54d00829513bdc92fc580b2598 *tests/data/fate/vsynth_lena-ljpeg.avi
+4763454 tests/data/fate/vsynth_lena-ljpeg.avi
+dde5895817ad9d219f79a52d0bdfb001 *tests/data/fate/vsynth_lena-ljpeg.out.rawvideo
+stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 7603200/ 7603200
--- /dev/null
+a3c1f9f7887b726bab17dbafa5debdca *tests/data/fate/vsynth_lena-mjpeg.avi
+673174 tests/data/fate/vsynth_lena-mjpeg.avi
+9d4bd90e9abfa18192383b4adc23c8d4 *tests/data/fate/vsynth_lena-mjpeg.out.rawvideo
+stddev: 4.32 PSNR: 35.40 MAXDIFF: 49 bytes: 7603200/ 7603200
--- /dev/null
+ebf2e0f17a75119ff86b15e721d16a76 *tests/data/fate/vsynth_lena-mjpeg-422.avi
+746530 tests/data/fate/vsynth_lena-mjpeg-422.avi
+451ac80989c4e14445cf951fd7f83b6d *tests/data/fate/vsynth_lena-mjpeg-422.out.rawvideo
+stddev: 4.18 PSNR: 35.70 MAXDIFF: 49 bytes: 7603200/ 7603200
--- /dev/null
+7674eb1aedaad0976c60329f556440d1 *tests/data/fate/vsynth_lena-mjpeg-444.avi
+851442 tests/data/fate/vsynth_lena-mjpeg-444.avi
+34edcb9c87ff7aac456a4fb07f43504b *tests/data/fate/vsynth_lena-mjpeg-444.out.rawvideo
+stddev: 4.05 PSNR: 35.96 MAXDIFF: 49 bytes: 7603200/ 7603200
--- /dev/null
+a77a8eb6e2ad32a5b20b41abda16f4c1 *tests/data/fate/vsynth_lena-mpeg1.mpeg1video
+192794 tests/data/fate/vsynth_lena-mpeg1.mpeg1video
+b3584042c60385e0fb988b8ec5b36409 *tests/data/fate/vsynth_lena-mpeg1.out.rawvideo
+stddev: 4.95 PSNR: 34.22 MAXDIFF: 57 bytes: 7603200/ 7603200
--- /dev/null
+333395b113b8045bac4e3fd90839ca6a *tests/data/fate/vsynth_lena-mpeg1b.mpeg1video
+225201 tests/data/fate/vsynth_lena-mpeg1b.mpeg1video
+f17fb3eef4ed3d03eeaaee45b217f7a5 *tests/data/fate/vsynth_lena-mpeg1b.out.rawvideo
+stddev: 4.10 PSNR: 35.86 MAXDIFF: 59 bytes: 7603200/ 7603200
--- /dev/null
+6071414a26d41ae9c4cc5477d8ca19eb *tests/data/fate/vsynth_lena-mpeg2.mpeg2video
+198673 tests/data/fate/vsynth_lena-mpeg2.mpeg2video
+9efe4846a75d9b7387d1e3bb1e5db29a *tests/data/fate/vsynth_lena-mpeg2.out.rawvideo
+stddev: 4.96 PSNR: 34.20 MAXDIFF: 59 bytes: 7603200/ 7603200
--- /dev/null
+521ec92c0b8672011a43dd13db98c400 *tests/data/fate/vsynth_lena-mpeg2-422.mpeg2video
+356431 tests/data/fate/vsynth_lena-mpeg2-422.mpeg2video
+51ca353620f85db8b5b1c56f1a275add *tests/data/fate/vsynth_lena-mpeg2-422.out.rawvideo
+stddev: 3.15 PSNR: 38.14 MAXDIFF: 49 bytes: 7603200/ 7603200
--- /dev/null
+505371e1b10f5af01b63b3f57606b26e *tests/data/fate/vsynth_lena-mpeg2-idct-int.mpeg2video
+198041 tests/data/fate/vsynth_lena-mpeg2-idct-int.mpeg2video
+92794e70e4a19a494f10efe353d9895d *tests/data/fate/vsynth_lena-mpeg2-idct-int.out.rawvideo
+stddev: 4.97 PSNR: 34.19 MAXDIFF: 58 bytes: 7603200/ 7603200
--- /dev/null
+dbc7dd0272f3711f50722f4753e3bfb0 *tests/data/fate/vsynth_lena-mpeg2-ilace.mpeg2video
+204576 tests/data/fate/vsynth_lena-mpeg2-ilace.mpeg2video
+d69be0d4ba1cb9c1fef9fb0d94a912ba *tests/data/fate/vsynth_lena-mpeg2-ilace.out.rawvideo
+stddev: 4.98 PSNR: 34.18 MAXDIFF: 65 bytes: 7603200/ 7603200
--- /dev/null
+5731a196498d4e8097c0ebe57e383ef6 *tests/data/fate/vsynth_lena-mpeg2-ivlc-qprd.mpeg2video
+244694 tests/data/fate/vsynth_lena-mpeg2-ivlc-qprd.mpeg2video
+b26e21599dee48a174bdbc40b2817e55 *tests/data/fate/vsynth_lena-mpeg2-ivlc-qprd.out.rawvideo
+stddev: 4.15 PSNR: 35.76 MAXDIFF: 74 bytes: 7603200/ 7603200
--- /dev/null
+9e734d384b4234d075203dffffa5174c *tests/data/fate/vsynth_lena-mpeg2-thread.mpeg2video
+179656 tests/data/fate/vsynth_lena-mpeg2-thread.mpeg2video
+f8f084b7f51fbe4f82d57b8aeec17edf *tests/data/fate/vsynth_lena-mpeg2-thread.out.rawvideo
+stddev: 4.72 PSNR: 34.65 MAXDIFF: 72 bytes: 7603200/ 7603200
--- /dev/null
+39ae4e15e3da14218ebf250180badd92 *tests/data/fate/vsynth_lena-mpeg2-thread-ivlc.mpeg2video
+178807 tests/data/fate/vsynth_lena-mpeg2-thread-ivlc.mpeg2video
+f8f084b7f51fbe4f82d57b8aeec17edf *tests/data/fate/vsynth_lena-mpeg2-thread-ivlc.out.rawvideo
+stddev: 4.72 PSNR: 34.65 MAXDIFF: 72 bytes: 7603200/ 7603200
--- /dev/null
+4a029747434d24d128b078a5e6aa1e88 *tests/data/fate/vsynth_lena-mpeg4.mp4
+119722 tests/data/fate/vsynth_lena-mpeg4.mp4
+9a1e085d9e488c5ead0c940c9612a37a *tests/data/fate/vsynth_lena-mpeg4.out.rawvideo
+stddev: 5.34 PSNR: 33.57 MAXDIFF: 83 bytes: 7603200/ 7603200
--- /dev/null
+bbb12e077f858242c1387d23d2ccdae8 *tests/data/fate/vsynth_lena-mpeg4-adap.avi
+198496 tests/data/fate/vsynth_lena-mpeg4-adap.avi
+87b6dbe98d276137fceaae2fa672eced *tests/data/fate/vsynth_lena-mpeg4-adap.out.rawvideo
+stddev: 3.75 PSNR: 36.65 MAXDIFF: 71 bytes: 7603200/ 7603200
--- /dev/null
+9fa1b5a68a6128a7160cfc8443a696e1 *tests/data/fate/vsynth_lena-mpeg4-adv.avi
+141534 tests/data/fate/vsynth_lena-mpeg4-adv.avi
+3f3a21e9db85a9c0f7022f557a5374c1 *tests/data/fate/vsynth_lena-mpeg4-adv.out.rawvideo
+stddev: 4.94 PSNR: 34.25 MAXDIFF: 69 bytes: 7603200/ 7603200
--- /dev/null
+82510449a3200b58dbcfbf0a643eb624 *tests/data/fate/vsynth_lena-mpeg4-error.avi
+180364 tests/data/fate/vsynth_lena-mpeg4-error.avi
+4537ba5320f1ae0971cc6e329c366776 *tests/data/fate/vsynth_lena-mpeg4-error.out.rawvideo
+stddev: 7.65 PSNR: 30.45 MAXDIFF: 158 bytes: 7603200/ 7603200
--- /dev/null
+cf0cde80515f8bfbd89d33aa51f1c5e1 *tests/data/fate/vsynth_lena-mpeg4-nr.avi
+154994 tests/data/fate/vsynth_lena-mpeg4-nr.avi
+d89cd5d0b1707f48fa9c4747c66d2d56 *tests/data/fate/vsynth_lena-mpeg4-nr.out.rawvideo
+stddev: 4.73 PSNR: 34.63 MAXDIFF: 64 bytes: 7603200/ 7603200
--- /dev/null
+b60bb3d8b942795272f0f0d89cd6351e *tests/data/fate/vsynth_lena-mpeg4-nsse.avi
+198434 tests/data/fate/vsynth_lena-mpeg4-nsse.avi
+59864a1050e641eaed8b0ee077bc780b *tests/data/fate/vsynth_lena-mpeg4-nsse.out.rawvideo
+stddev: 4.32 PSNR: 35.40 MAXDIFF: 60 bytes: 7603200/ 7603200
--- /dev/null
+ab94d9e56635e100d95e74fc8dc845e5 *tests/data/fate/vsynth_lena-mpeg4-qpel.avi
+163662 tests/data/fate/vsynth_lena-mpeg4-qpel.avi
+e2ce994dbb66da51c2e1ad26617d7c2f *tests/data/fate/vsynth_lena-mpeg4-qpel.out.rawvideo
+stddev: 3.97 PSNR: 36.14 MAXDIFF: 54 bytes: 7603200/ 7603200
--- /dev/null
+a576ecbf48c33916f2d17cf1bf37f3fe *tests/data/fate/vsynth_lena-mpeg4-qprd.avi
+231450 tests/data/fate/vsynth_lena-mpeg4-qprd.avi
+3071250e0864546c2455c9f9c9b8604e *tests/data/fate/vsynth_lena-mpeg4-qprd.out.rawvideo
+stddev: 3.71 PSNR: 36.72 MAXDIFF: 61 bytes: 7603200/ 7603200
--- /dev/null
+ea96539a0bebf70c3c09de0199a53a30 *tests/data/fate/vsynth_lena-mpeg4-rc.avi
+226310 tests/data/fate/vsynth_lena-mpeg4-rc.avi
+6e8b62e8c3bcbfdcc58afb69a0b1c4e3 *tests/data/fate/vsynth_lena-mpeg4-rc.out.rawvideo
+stddev: 4.23 PSNR: 35.60 MAXDIFF: 85 bytes: 7603200/ 7603200
--- /dev/null
+8d7903d55221035c67866b8c1314c499 *tests/data/fate/vsynth_lena-mpeg4-thread.avi
+250092 tests/data/fate/vsynth_lena-mpeg4-thread.avi
+045fe9f226bbcc3d41644bffaed03b31 *tests/data/fate/vsynth_lena-mpeg4-thread.out.rawvideo
+stddev: 3.69 PSNR: 36.78 MAXDIFF: 65 bytes: 7603200/ 7603200
--- /dev/null
+aaee9d1ff7dccfc045603c45f0160000 *tests/data/fate/vsynth_lena-mpng.avi
+12558330 tests/data/fate/vsynth_lena-mpng.avi
+98d0e2854731472c5bf13d8638502d0a *tests/data/fate/vsynth_lena-mpng.out.rawvideo
+stddev: 1.26 PSNR: 46.10 MAXDIFF: 13 bytes: 7603200/ 7603200
--- /dev/null
+50b91fe78559c0f5f1e5873cdcc0e6a8 *tests/data/fate/vsynth_lena-msmpeg4.avi
+127660 tests/data/fate/vsynth_lena-msmpeg4.avi
+bb14902d5850d6b0ab70fdb017855775 *tests/data/fate/vsynth_lena-msmpeg4.out.rawvideo
+stddev: 5.33 PSNR: 33.58 MAXDIFF: 78 bytes: 7603200/ 7603200
--- /dev/null
+4770bd848f1937a861bf1a72295c6094 *tests/data/fate/vsynth_lena-msmpeg4v2.avi
+129918 tests/data/fate/vsynth_lena-msmpeg4v2.avi
+537c114e1d47c54a4bccd31f4073e9bd *tests/data/fate/vsynth_lena-msmpeg4v2.out.rawvideo
+stddev: 5.33 PSNR: 33.59 MAXDIFF: 79 bytes: 7603200/ 7603200
--- /dev/null
+e554e31a4a635c924391228b7194d21b *tests/data/fate/vsynth_lena-msvideo1.avi
+914560 tests/data/fate/vsynth_lena-msvideo1.avi
+9a6ac7c0171286f009d159b59fdc1154 *tests/data/fate/vsynth_lena-msvideo1.out.rawvideo
+stddev: 7.97 PSNR: 30.10 MAXDIFF: 123 bytes: 7603200/ 7603200
--- /dev/null
+637f34b5fd81f072f76a967595fa6af7 *tests/data/fate/vsynth_lena-prores.mov
+2844076 tests/data/fate/vsynth_lena-prores.mov
+03fd29e3963716a09d232b6f817ecb57 *tests/data/fate/vsynth_lena-prores.out.rawvideo
+stddev: 1.31 PSNR: 45.77 MAXDIFF: 11 bytes: 7603200/ 7603200
--- /dev/null
+b03741c69037cbdcd2809278c00c0350 *tests/data/fate/vsynth_lena-prores_ks.mov
+3884596 tests/data/fate/vsynth_lena-prores_ks.mov
+6cfe987de99cf8ac9d43bdc5cd150838 *tests/data/fate/vsynth_lena-prores_ks.out.rawvideo
+stddev: 0.92 PSNR: 48.78 MAXDIFF: 10 bytes: 7603200/ 7603200
--- /dev/null
+4863978263d966d704ffaaa6d23123bb *tests/data/fate/vsynth_lena-qtrle.mov
+14798345 tests/data/fate/vsynth_lena-qtrle.mov
+98d0e2854731472c5bf13d8638502d0a *tests/data/fate/vsynth_lena-qtrle.out.rawvideo
+stddev: 1.26 PSNR: 46.10 MAXDIFF: 13 bytes: 7603200/ 7603200
--- /dev/null
+2c4e69b59d8e8e19903c843575806d5f *tests/data/fate/vsynth_lena-qtrlegray.mov
+5111283 tests/data/fate/vsynth_lena-qtrlegray.mov
+d7bfbe259af9ae323bb94b09c33570a5 *tests/data/fate/vsynth_lena-qtrlegray.out.rawvideo
+stddev: 18.65 PSNR: 22.72 MAXDIFF: 72 bytes: 7603200/ 7603200
--- /dev/null
+16717c6cee907554cbeaefbbc116cd66 *tests/data/fate/vsynth_lena-r210.avi
+22125248 tests/data/fate/vsynth_lena-r210.avi
+6ea4fcd93fc83defc8770e85b64b60bb *tests/data/fate/vsynth_lena-r210.out.rawvideo
+stddev: 0.70 PSNR: 51.12 MAXDIFF: 12 bytes: 7603200/ 7603200
--- /dev/null
+188bce319523a1c7d24103aab1ed1bda *tests/data/fate/vsynth_lena-rgb.avi
+15213248 tests/data/fate/vsynth_lena-rgb.avi
+98d0e2854731472c5bf13d8638502d0a *tests/data/fate/vsynth_lena-rgb.out.rawvideo
+stddev: 1.26 PSNR: 46.10 MAXDIFF: 13 bytes: 7603200/ 7603200
--- /dev/null
+1a43cd71c91f2ef42d11a81419bff3bd *tests/data/fate/vsynth_lena-roqvideo.roq
+94810 tests/data/fate/vsynth_lena-roqvideo.roq
+97cda6096430c0ab7a43a0e120cd3e91 *tests/data/fate/vsynth_lena-roqvideo.out.rawvideo
+stddev: 3.81 PSNR: 36.50 MAXDIFF: 49 bytes: 7603200/ 760320
--- /dev/null
+33a2aae3351b0b2121f823057c0e226f *tests/data/fate/vsynth_lena-rv10.rm
+154321 tests/data/fate/vsynth_lena-rv10.rm
+b7d733ebedbaa04f49bf7493a907e223 *tests/data/fate/vsynth_lena-rv10.out.rawvideo
+stddev: 5.43 PSNR: 33.42 MAXDIFF: 77 bytes: 7603200/ 7603200
--- /dev/null
+4d23a72fe7e29f98f38888804eacd111 *tests/data/fate/vsynth_lena-rv20.rm
+153304 tests/data/fate/vsynth_lena-rv20.rm
+6fa5dc1c2f00f858fc4895ad640891a2 *tests/data/fate/vsynth_lena-rv20.out.rawvideo
+stddev: 5.48 PSNR: 33.35 MAXDIFF: 81 bytes: 7603200/ 7603200
--- /dev/null
+a7bc7eba6ac50f0b417cb9f829feb7a1 *tests/data/fate/vsynth_lena-snow.avi
+57688 tests/data/fate/vsynth_lena-snow.avi
+8890189af71a0dd3447c4e8424c9a76b *tests/data/fate/vsynth_lena-snow.out.rawvideo
+stddev: 10.47 PSNR: 27.72 MAXDIFF: 119 bytes: 7603200/ 7603200
--- /dev/null
+fa6986c9ebaa087b037d099acefa0ade *tests/data/fate/vsynth_lena-snow-hpel.avi
+61760 tests/data/fate/vsynth_lena-snow-hpel.avi
+8680d40905f423999d65b996c4dcb984 *tests/data/fate/vsynth_lena-snow-hpel.out.rawvideo
+stddev: 10.45 PSNR: 27.74 MAXDIFF: 123 bytes: 7603200/ 7603200
--- /dev/null
+ed109f21012f92ad5ea19451844ae721 *tests/data/fate/vsynth_lena-snow-ll.avi
+2721746 tests/data/fate/vsynth_lena-snow-ll.avi
+dde5895817ad9d219f79a52d0bdfb001 *tests/data/fate/vsynth_lena-snow-ll.out.rawvideo
+stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 7603200/ 7603200
--- /dev/null
+6e9678439ab7460db1fcc8e41ca1a1e0 *tests/data/fate/vsynth_lena-svq1.mov
+766701 tests/data/fate/vsynth_lena-svq1.mov
+aa03471dac3f49455a33a2b19fda1098 *tests/data/fate/vsynth_lena-svq1.out.rawvideo
+stddev: 3.23 PSNR: 37.93 MAXDIFF: 61 bytes: 7603200/ 7603200
--- /dev/null
+fa1c4b1b8d0e9454b4bc2269c7fe634b *tests/data/fate/vsynth_lena-v210.avi
+14752448 tests/data/fate/vsynth_lena-v210.avi
+7ba6e411e43c6b57c95c49d6848f41e6 *tests/data/fate/vsynth_lena-v210.out.rawvideo
+stddev: 0.34 PSNR: 57.41 MAXDIFF: 6 bytes: 7603200/ 7603200
--- /dev/null
+1ea64cd6ad32dae72963b8fdf89e96d1 *tests/data/fate/vsynth_lena-v308.avi
+15213248 tests/data/fate/vsynth_lena-v308.avi
+d43cb310c130c69214332d74f6ee5f9a *tests/data/fate/vsynth_lena-v308.out.rawvideo
+stddev: 0.41 PSNR: 55.80 MAXDIFF: 7 bytes: 7603200/ 7603200
--- /dev/null
+b4cdf2351f908fc308d8693d0cee69e1 *tests/data/fate/vsynth_lena-v408.avi
+20282048 tests/data/fate/vsynth_lena-v408.avi
+dde5895817ad9d219f79a52d0bdfb001 *tests/data/fate/vsynth_lena-v408.out.rawvideo
+stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 7603200/ 7603200
--- /dev/null
+3099f5514693a609180ab5761dc8d4ca *tests/data/fate/vsynth_lena-wmv1.avi
+129510 tests/data/fate/vsynth_lena-wmv1.avi
+dec44e3c04db4fef49a7728f164d9159 *tests/data/fate/vsynth_lena-wmv1.out.rawvideo
+stddev: 5.33 PSNR: 33.60 MAXDIFF: 77 bytes: 7603200/ 7603200
--- /dev/null
+c8d1d1371bd09add388c32f3259ef555 *tests/data/fate/vsynth_lena-wmv2.avi
+129852 tests/data/fate/vsynth_lena-wmv2.avi
+b4de16a0d302c52702f7a4362da989bc *tests/data/fate/vsynth_lena-wmv2.out.rawvideo
+stddev: 5.33 PSNR: 33.59 MAXDIFF: 77 bytes: 7603200/ 7603200
--- /dev/null
+6a1a7b467eeab2795510e7dd1ca528ff *tests/data/fate/vsynth_lena-xface.nut
+17504 tests/data/fate/vsynth_lena-xface.nut
+6d87881d630439d02c7a97f468d67a1c *tests/data/fate/vsynth_lena-xface.out.rawvideo
+stddev: 99.01 PSNR: 8.22 MAXDIFF: 238 bytes: 7603200/ 7603200
--- /dev/null
+522ebf5fbf98aeec5ee6b39de1c1afc0 *tests/data/fate/vsynth_lena-y41p.avi
+7610048 tests/data/fate/vsynth_lena-y41p.avi
+d27a84ccdac09055724d122e03fea82a *tests/data/fate/vsynth_lena-y41p.out.rawvideo
+stddev: 1.07 PSNR: 47.54 MAXDIFF: 21 bytes: 7603200/ 7603200
--- /dev/null
+f48f08c67097b3c35b1105f24ef68a0c *tests/data/fate/vsynth_lena-yuv.avi
+7610048 tests/data/fate/vsynth_lena-yuv.avi
+dde5895817ad9d219f79a52d0bdfb001 *tests/data/fate/vsynth_lena-yuv.out.rawvideo
+stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 7603200/ 7603200
--- /dev/null
+1dcf2c21fe3ff1b57f9280a4fd550d14 *tests/data/fate/vsynth_lena-yuv4.avi
+7610048 tests/data/fate/vsynth_lena-yuv4.avi
+dde5895817ad9d219f79a52d0bdfb001 *tests/data/fate/vsynth_lena-yuv4.out.rawvideo
+stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 7603200/ 7603200
--- /dev/null
+f2c6b3c88f07f0ed08dd25ca654854fb *tests/data/fate/vsynth_lena-zlib.avi
+12517176 tests/data/fate/vsynth_lena-zlib.avi
+98d0e2854731472c5bf13d8638502d0a *tests/data/fate/vsynth_lena-zlib.out.rawvideo
+stddev: 1.26 PSNR: 46.10 MAXDIFF: 13 bytes: 7603200/ 7603200
--- /dev/null
+e9cc761eb3fedc36ce5f97744196ed8b *tests/data/fate/vsynth_lena-zmbv.avi
+1808720 tests/data/fate/vsynth_lena-zmbv.avi
+ee68a5292fd0745834246b4ec0d85e9b *tests/data/fate/vsynth_lena-zmbv.out.rawvideo
+stddev: 8.12 PSNR: 29.94 MAXDIFF: 32 bytes: 7603200/ 7603200
+++ /dev/null
-fdc1926e0a599de94513f0a3472b598f *./tests/data/vsynth2/cljr.avi
-5075660 ./tests/data/vsynth2/cljr.avi
-7df03229ee6361ea11a0d83d4926cb10 *./tests/data/cljr.vsynth2.out.yuv
-stddev: 10.30 PSNR: 27.87 MAXDIFF: 65 bytes: 7603200/ 7603200
+++ /dev/null
-ed66182be0d515e8b6cb970ad63162da *./tests/data/vsynth2/huffyuv.avi
-6455232 ./tests/data/vsynth2/huffyuv.avi
-dde5895817ad9d219f79a52d0bdfb001 *./tests/data/huffyuv.vsynth2.out.yuv
-stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 7603200/ 7603200
+++ /dev/null
-3d5ee6d2023bc15bba898819e4977e46 *./tests/data/vsynth2/yuv.avi
-7610060 ./tests/data/vsynth2/yuv.avi
-dde5895817ad9d219f79a52d0bdfb001 *./tests/data/yuv.vsynth2.out.yuv
-stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 7603200/ 7603200
--- /dev/null
+fdc1926e0a599de94513f0a3472b598f *./tests/data/vsynth_lena/cljr.avi
+5075660 ./tests/data/vsynth_lena/cljr.avi
+7df03229ee6361ea11a0d83d4926cb10 *./tests/data/cljr.vsynth_lena.out.yuv
+stddev: 10.30 PSNR: 27.87 MAXDIFF: 65 bytes: 7603200/ 7603200
--- /dev/null
+ed66182be0d515e8b6cb970ad63162da *./tests/data/vsynth_lena/huffyuv.avi
+6455232 ./tests/data/vsynth_lena/huffyuv.avi
+dde5895817ad9d219f79a52d0bdfb001 *./tests/data/huffyuv.vsynth_lena.out.yuv
+stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 7603200/ 7603200
--- /dev/null
+3d5ee6d2023bc15bba898819e4977e46 *./tests/data/vsynth_lena/yuv.avi
+7610060 ./tests/data/vsynth_lena/yuv.avi
+dde5895817ad9d219f79a52d0bdfb001 *./tests/data/yuv.vsynth_lena.out.yuv
+stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 7603200/ 7603200
--- /dev/null
+P6
+# CREATOR: GIMP PNM Filter Version 1.1
+256 256
+255
+Ò¸ ܼ¦áÁ¡á½\9fæ¾\9fåº\9eè¼\9fé½\9fä·\9béº\9dç¸\98è·\98å´\92æ·\92ç¸\97êÁ\9bæâ³é½\87Þ¯\82éµ\90í¾\99îÀ\9dîÀ\9fîÀ\9cî£î£îÁ¡îÄ¥íÇ«íȬìÉíÈìË®ìËìËíˬíÌ®íÍìΰìÏ°íгíαîÍíͲíѵíͲíͯîË«îʪîȨî˪îË®îÉ©îÇ¥íǦíƤìÄ¢ìÄ¢ìÅ£íÅ£ìÄ¡ìà êÁ\9fêÂ\9fè¾\9béÀ\9bç¾\9bæ¾\99èÀ\9cç¿\9bä¼\97å½\99â¼\98á»\97ä¿\9bçà èÄ£éŤæÁ á¾\9aß¼\99â¿\9dçÄ¢çÇ¥çÇ¥åŤæǧãÆ¥åÇ¥äȦæɧéÍ«êÏèË©äÈ£ãÇ¢åȤæÊ£åÉ âÅ¡âÅ¡ãÆ¢ãÆ£äÆ£àÂ\9fááàÅ ãɤåÊ¥áÉ¢áË¥ÞÈ\9fÞÈ\9eáÊ¡æϧåΨáË¥ÝÆ ßÈ¢ÜÆ\9dãÌ£åϨçÑ«èÒåΩçÑ«èÓ¬ìÙ²íåÂîéËíæÊîßÁìعéÓµã̦պ\91¸\98k\8eh8\81P"\89J\1f\88H\1e\8aK\1f\85E\18\84D\19z?\12w;\ e|B\e}E!\7fY3~iC\86tV\87y\\7foMtcH[M8A9,"\1f\1a\ f\ e\v\b\b\a \a\a\a\b\b\b\a\a\a\a\a\a\a\a\a\ 6\ 6\ 6\a\a\a\a\a\a\ 6\ 6\ 6\ 6\ 6\ 6\ 6\ 6\ 6\a\a\a\a\a\a\ 6\ 6\ 6\a\a\a\a\a\a\a\a\a\b\b\b\a\a\a\b\b\b \b\b\b
+
+
+
+
+
+ \b\b\b \a\a\a\a\a\a\ 6\ 6\ 6\ 5\ 5\ 5\ 6\ 6\ 6\ 5\ 5\ 5\ 6\ 6\ 6\ 6\ 6\ 6\ 6\ 6\ 6\ 6\ 6\ 6\ 6\ 6\ 6\ 6\ 6\ 6\ 6\ 6\ 6\ 5\ 5\ 5\ 6\ 6\ 6\a\a\a\a\a\a\ 6\ 6\ 6\ 6\ 6\ 6\ 6\ 6\ 6\b\b\b\b\b\b\a\a\a\ 6\ 6\ 6\a\a\a\a\a\a\b\b\b\a\a\a\a\a\a\ 6\ 6\ 6\a\a\a\a\a\a
+
+
+\f\f\f\r\ e
+\10\ e\v\10\ e\v\10\ e\v\12\11\r\ f\r
+\12\10\v\14\13\f\13\11
+\11\10 \11\10 \11\ f\b\11\10 \11\ f\b\11\10 \12\10 \12\10 \13\12\v\12\10
+\13\12\v\14\12\f\15\14\r\14\13\f\13\12\v\12\10
+\12\11
+\13\12\v\14\12\v\13\11\v\13\11
+\13\12
+\15\13\v\15\14\vÁ¤\91»\99\85À\97yϧ\8cä½¢á·\99ç¼\9eæ¾\9cå¹\9båº\99è¹\98æ¶\94è¹\97é»\99å·\90ç¼\95ãé·ìÍ\9aá³\86ë·\90í¼\99í¼\9aî¾\9dî¾\9eî¿ î½\9eîÁ£îÁ¢îÁ£îÀ£î¤îèîèîÆ©íƪíÇ©íȪíÍ®ìίíÍ®íÍ®íÏ°íϯíÏ°íгìÒ²îήî̬íÏ°îήíÍîάîͬîË©îɧíɧîɦîɧîɧìǦìäëâìŦëäéÁ ê¢é¾\9cèÀ\9céÁ\9eè¾\9cçÀ\9cä¼\98ä¼\9aã»\98ä¼\99é¿ èÀ\9fæÁ\9eå¿\9dâ¾\9cá½\9bâÀ\9cäÀ\9fçÅ£åÅ¢çǤæÆ¢äƦãƦåÈ¥ç̪æΪéάé̪åÈ¥äǤæÉ¥æÉ¥äÈ¡ãÇ ãÇ¢áà âÅ âÄ¡âÅ¡àÄ áÅ¡âÈ£ãÈ£ãɤáÉ£ßÈ£ßÈ\9fáÉ¢ã̦ãÍ¥âË¥ÛÄ\9aÛÄ\9cßÇ àÉ æͦèÒ¬æЪæϪã̦èÒ¬ëײîá¾îäÅîãÇîÞ¿ëÕ²éÒ±âË£×»\8c¾\9do\99nA\8cT*\8bJ\e\8cL\1e\8dO#\8bH\1f\86D\e~D\19|?\15wA\19zN,|\5}fDwlNt_A_Q6?9\1e%$\19\13\ f\r \b\b\b\b\b\b\a\a\a\ 5\ 5\ 5\b\b\b\b\b\b \ 6\ 6\ 6\a\a\a \a\a\a\a\a\a\ 6\ 6\ 6\a\a\a\a\a\a \b\b\b\b\b\b
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ \a\a\a\b\b\b\ 6\ 6\ 6\ 5\ 5\ 5\ 6\ 6\ 6\a\a\a\ 5\ 5\ 5\ 6\ 6\ 6\ 5\ 5\ 5\ 6\ 6\ 6\ 6\ 6\ 6\ 6\ 6\ 6\ 6\ 6\ 6\a\a\a\ 5\ 5\ 5\b\b\b\b\b\b\ 6\ 6\ 6\a\a\a\b\b\b\a\a\a\a\a\a \a\a\a\a\a\a\b\b\b\a\a\a\b\b\b\ 6\ 6\ 6\ 5\ 5\ 5\ 6\ 6\ 6
+
+
+\v\v\v\f\f\f\10\10\f\ f\ f\v\ f\r
+\12\10\r\ f\r
+\12\11\f\11\10 \13\12\v\13\11
+\13\11
+\11\ f \12\10
+\13\11
+\13\11
+\13\11
+\14\12\v\13\11
+\12\10
+\12\10
+\13\11
+\12\11
+\14\13\f\15\13\r\16\14\ e\14\13\f\12\11
+\14\12\f\16\14\r\12\11
+\15\13\f\18\16\ f\14\12
+\15\13\v\D.dK1}^F¢\81fÇ\9f~Ϥ\88ß³\9cá¶\97ß³\91âµ\96æ¸\95å¹\99ç»\99ê½\97é»\98è»\96ãë¾êÏ\9bä¹\8dë¹\93î¿\9cí¼\99îº\9cí½\9bí¹\9bî½\9fí¹\9dî¼\9eí¼\9eî½\9eí½\9cîÁ¤îÁ£îÀ¢îÀ¢íÁ£îĦìÇ«îÉîÉíÉí̱î̬íͬíϯíήîίíдîϲíѳîѳîвîÌ®îÌîΰîÍ®îËîˬî̪íÈ¥ìÇ¥ìÆ¢ìŦëÆ£êÅ¡êÄ éÂ\9eêÂ\9fêÂ\9eèÁ\9cèÀ\9cæ¼\9dã½\9cä»\97â»\97ä¾\9då¿\9dåÀ\9fä¿\9bã¿\9dá¼\9bá¾\9cãÀ\9då æÆ¢äÂ\9fåÄ¡äâæÆ¥åǦçË©æʧè˨éÍ«åÉ£åɤę̀çÊ¥åÉ æÊ£àÂ\9eâÆ\9fâÅ\9dáÅ\9dâÄ\9dáÄ\9fßÃ\9bãÆ¢ãÆ£âÈ\9fÝÅ\9aÞÆ\9eßÇ âÇ¡å̤âÌ£âÇ\9fÛÃ\9aÙÂ\98ÞÄ\9bâÈ\9fåË£äΧäͧäΦäΧæЪéÓ®íÛ¹îß¾íÞ¼ìÚ·éÓ°æѬâ̤ؾ\92Â\9eq¥uG\96]2\95S \96Q$\92Q#\8eL$\89H&}C\1f~D\e{E"|Q0vX4o];bU4J?$3(\17\17\15\ f \b \b\b\b\b\b\b\b\b\b\b\b\b\a\a\a\b\b\b\b\b\b\a\a\a\b\b\b\b\b\b\a\a\a\b\b\b\a\a\a\b\b\b\a\a\a
+
+
+
+
+
+ \b\b\b
+
+
+\f\f\f\v\v\v
+
+
+\v\v\v\f\f\f\v\v\v\v\v\v\ e\ e\ e\r\r\r\v\v\v
+
+
+\a\a\a\b\b\b\ 5\ 5\ 5\ 5\ 5\ 5\ 6\ 6\ 6\ 6\ 6\ 6\ 6\ 6\ 6\a\a\a\ 6\ 6\ 6\ 5\ 5\ 5\ 6\ 6\ 6\a\a\a\ 6\ 6\ 6\a\a\a\ 6\ 6\ 6\b\b\b\a\a\a\b\b\b\b\b\b\a\a\a\b\b\b\b\b\b\b\b\b\a\a\a\b\b\b\b\b\b\b\b\b\ 6\ 6\ 6\ 6\ 6\ 6\ 6\ 6\ 6\a\a\a\b\b\b \f\f\f\v\v \10\10\r\11\ f\v\10\ f\v\11\ f\f\12\11\f\14\12\f\14\11\f\11\ f\b\14\13\v\11\10 \13\11
+\13\12\f\12\11
+\11\ f \14\12\v\13\11 \13\11\v\12\11
+\14\12\v\14\13\f\12\10
+\14\12\f\17\16\ f\14\13\f\15\13\f\16\14\r\15\13\r\16\14\ e\13\12
+\15\13\f\14\13\v\15\13\v\16\14\fbJ5iK8gO9\7fgK\94v]°\88oÀ\97uÔ§\89Õ©\89Û®\90ݱ\8eå¹\94åº\95ç¼\98èº\99êº\95åá¶èТä¹\92ê¹\91îÁ\99î½\9bî¾\9eìº\98íº\9bí»\9fí¹\9aíº\9bî¼\9dì¸\9aî»\9dí¼\9bî»\9cî¼ î¿¢î¾¢î¿¡îÁ£îÂ¥îæîĨîãîȦîʨîɧî˨í̬íÏ®íϯîÍíаîѳîίîίîÏ°îгî̯îαîΰíËìÈ©íÊ«íˬìȧìÈ©ëÄ¢ëà ëÄ¥éŤçÂ\9eéÀ\9cä¾\9eâ¼\98ã¾\9båº\9bâ¼\9bâ¼\9cä¾\9eá¼\9aàº\99á»\9aà¼\99â¿\9cäÀ\9eåÁ\9cäÁ äÅ¡ãÄ\9fäÄ åÇ£äǤæ˨èË©åȤåÉ¥åȦäÇ¥æʤæË£äÈ¢äǤâÅ\9fãÇ âÆ\9dâÄ\9cáÆ\9dàÂ\9dåÉ£äÉ¡âÈ¡âÈ ÞÃ\9aÞÄ\9bâÇ\9fãÉ¢äÊ àÇ\99ÛÃ\99Õ¿\93ÝÄ\98àÇ\9báË¡âË¢âÌ£áË£ßÉ\9fâË¢äͤéÓ°ëÖ±ëÕ±êÔ¯èÑåÏ©áÊ¥Ù¿\96Ç¡q«{L d6¢]+\99V+\91Q)\8cI"\8aH%~D\19|C\1e\80O2\7fR6vR3N?%80\18\1c\1a\ f\r\f\a
+ \a\b\b\b\b\b\b\b\b\b\b\b\b\a\a\a\b\b\b\a\a\a\b\b\b\b\b\b\a\a\a\b\b\b
+
+
+\a\a\a \b\b\b
+
+
+
+
+
+\f\f\f\f\f\f\r\r\r\v\v\v\v\v\v\f\f\f\v\v\v\r\r\r\r\r\r\r\r\r\f\f\f\r\r\r\v\v\v \b\b\b\ 6\ 6\ 6\b\b\b\ 6\ 6\ 6\ 6\ 6\ 6\ 5\ 5\ 5\ 5\ 5\ 5\ 6\ 6\ 6\ 6\ 6\ 6\ 6\ 6\ 6\ 6\ 6\ 6\ 5\ 5\ 5\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\b\b\b\b\b\b\b\b\b\a\a\a\a\a\a\b\b\b\b\b\b\ 6\ 6\ 6\ 6\ 6\ 6\a\a\a\a\a\a\a\a\a\a\a\a \b\b\b
+
+
+\v\v\v\ e\ e\v\ f\ f\f\12\10\r\11\ f\f\10\ e\b\11\10 \13\11
+\11\10 \12\10 \13\11
+\14\12\v\12\10 \14\13\v\13\11
+\12\10\b\11\ f\a\13\12
+\11\ f\a\13\11
+\14\12\v\15\13\f\13\11
+\14\13\f\14\12
+\15\13\f\13\12
+\16\14\r\16\15\ e\15\14\v\16\15\r\14\13
+\16\14\f\14\12
+\15\14\fiQ:gN5qX<u_Ev\B\92iV³\87q¿\95|Ê\9b\82Ö«\8bÕª\85ß°\8aå¸\96è¼\94æº\96á³\8béÄ\9dç·\8eÚ¯\88áµ\8aì¾\9bîÀ¢í¿\9fî½\9dì½\9dë¹\98î»\9cíº\9cí»\9cì¸\99í¹\9bì¶\97í¹\9bîº\9fíº\9fíº\9eî½£î½ î¾\9eî¿ î¾ îÁ¢íÁ¢îŤîáîǦî˧îʬîË«îË«îͬîάîϯîϱîͯîÍ®îѳîѳîΰîͯí̬îÍ®îÌí̬ìÉ©ìǨìɧëÊ©ëǤêÆ¢èà æÀ\9fæÁ\9eã¼\99ä¾\9bâ½\9bâ¼\98ä¿\9aá»\96àº\96Ý·\93á»\96à»\96ã¾\9dåÂ\9fåà åáäÁ\9eåÄ\9cäà äÅ£åÆ¥æɦãÆ£ãÆ¢âÅ¡æÊ¥æÈ¥æˤäÈ\9eåÉ¢ãÇ¡âÆ\9eãÇ\9eßÂ\99âÅ\9eâÇ\9fãÇ\9fçʦäÉ¢áÆ\9eàÆ\9dÞÃ\9càÇ\9bãÉ\9fâÉ\9eßÆ\98ÛÀ\97ÙÁ\95ÛÁ\95àÅ\9dßÈ\9eàÉ àÊ ÞÇ\9fßÉ¡ÝÆ áˤą̂æΪåЫåΧæϪåΪäͨٿ\93ʪ|¸\89d®pF§c3\9cX.\8fQ*\8eK'\89C'\83J \88V4\84X>vW<^F,7,\12\13\12\ 6\ e\v\a
+ \a\ 6\a\a \a\b\b\b \b\b\b
+
+
+
+
+
+\b\b\b
+
+
+\b\b\b
+
+
+\f\f\f
+
+
+
+
+
+\f\f\f\v\v\v\f\f\f\r\r\r\ e\ e\ e\r\r\r\r\r\r\r\r\r\ e\ e\ e\r\r\r\f\f\f\r\r\r\r\r\r\r\r\r\v\v\v\f\f\f\v\v\v\a\a\a \a\a\a\ 5\ 5\ 5\ 6\ 6\ 6\ 6\ 6\ 6\ 6\ 6\ 6\ 5\ 5\ 5\ 5\ 5\ 5\ 6\ 6\ 6\ 6\ 6\ 6\ 6\ 6\ 6\ 6\ 6\ 6\a\a\a\ 6\ 6\ 6\ 5\ 5\ 5\a\a\a\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\a\a\a\a\a\a \a\a\a\b\b\b\b\b\b\b\b\b\ 6\ 6\ 6\a\a\a \v\v\v\ e\ e\v\ f\ e
+\13\11\ e\12\10\r\13\11\v\13\12\v\16\14\r\14\13\f\14\13\r\13\11\v\13\12\v\13\11
+\14\12
+\14\12
+\14\13
+\15\13\f\13\12 \14\12 \14\13
+\13\11 \15\13\v\12\11
+\19\13\r\19\13\f\17\14\f\18\14\r\15\13\r\1a\14\ e\17\12 \18\14\f\18\15\r\19\14\f\1a\14\f\19\14\fkX@yaC\90zX§\9b\85yhC\8drO¯\93xÁ\9d\83Ü´\9cݶ\96Óª\87ܲ\8cä½\99å½\92ã¹\94á¸\95Þ\8bÖ£\82ת\86Û®\85íÂ í¿¢í½\9fíÀ\9fí¿¢í¼ î½\9fíº\9cíº\9cì¸\9bí¶\9aí¶\99í¸\9bí¸\9aí·\9aì¸\96í»\9dí¸\9aí»\9cí½\9fî¼\9dî½\9fîÀ¡îÁ¢î¿\9eîãíÂ\9eîƦîɨîË©î̪îÍ®îίîÏ°îÍ®îÏ°îϱîѳîΰíÌîÏîίíÍ°îÍîÍ®íˬíË«íÌ«ìË«ìɨêÅ¥èÄ£êƦåÁ æ¡æÀ ä¼\9câ½\9bã½\9cß¹\97ß¹\97ݺ\94Þ¸\93á½\9aà½\9bäÂ\9fåÂ\9få äÄ æÇ£äÄ åÅ¢äǤäÇ£âÅ¡äÇ£áÆ\9cåÈ£âÆ\9fãÇ¢åÈ¥åɤåÈ¢åÈ¢åȤáÅ\9fâÆ\9eåÉ¡åÊ¡åÊ¢âÇ ÞÃ\98ÞÄ\98àÆ\99áÈ\9bâÉ\9cÝÃ\96ØÁ\95Õ¾\91ØÀ\94ÞÃ\9aàÅ\9dàÈ àÊ àÇ ÜÅ\9cÜÅ\9cÞÈ¢ßÉ£áË¥áË£âÌ¥ãΨã̦â˦ÜÃ\98Ñ°\80Á\94h´tH§a0\9aV)\89M"\82E\18\85H$\88U1\8ehA\8bmIw_CTH'*!\b\14\12\ 4\ e\f\ 5\v
+ \ 6 \ 5 \b\b\b\b\b\b\b \v\v\v\v\v\v
+
+
+\v\v\v
+
+
+\r\r\r\v\v\v\f\f\f
+
+
+\r\r\r\v\v\v\r\r\r\r\r\r\10\10\10\ e\ e\ e\ e\ e\ f\10\10\10\r\r\r\ e\ e\ e\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\ e\ e\ e\f\f\f\f\f\f \b\b\b\b\b\b\a\a\a\ 6\ 6\ 6\a\a\a\ 6\ 6\ 6\ 6\ 6\ 6\ 6\ 6\ 6\a\a\a\ 6\ 6\ 6\ 5\ 5\ 5\ 6\ 6\ 6\ 6\ 6\ 6\ 5\ 5\ 5\a\a\a\a\a\a\ 6\ 6\ 6 \a\a\a\b\b\b \a\a\a\b\b\b \b\b\b \ 6\ 6\ 6\a\a\a\a\a\a\b\b\b\b\b\b
+
+
+\f\f\b\10\ f\v\12\10\r\11\ f\f\12\11\ e\11\ f \15\13\f\11\10 \14\13\f\15\13\f\15\14\r\14\13\f\13\12\v\11\ f \14\12\v\16\14\r\12\11\b\13\12 \12\11
+\16\13\f\16\12
+\18\13\v\19\14\f\19\14\f\1a\14\f\17\12
+\19\14\f\18\13
+\19\14\v\17\12\v\e\15\r\19\14\v\e\16\v\1a\15\v\e\16\vĪ\8fâÄ«êÔ¾éíæâàÓåÏ®çίîÒ½îÓ»ïÓºëÉ«æÀ\9cè¡íͬåÁ\9dà½\9dØ\8bÐ {Ѧ\81Ö¬\8dæ»\9bíÀ¡í¿¥ì¼ ë»\9eì¾£ì½¢í¾ í¼ íº\9dí»\9fì¹\9fì¸\9bí¹\9cì¸\9cìµ\9cí·\9cë¶\9aíº\9bíº\9bíº\9cíº\9bì»\98í¼\9bíÀ\9eí¿\9dîÄ¡íÄ îǧîƦîȨîʪîɪíÊ«îË«íʬîίîΰîαíͯîϱîήîϱîвíαîΰîϯìÌíÌìË«ëɨëÉ©ëȨéŤè¢åÀ\9féãå¾\9eä¿\9aâ¼\9cߺ\92ݹ\92Þ¶\92à»\96â¿\99â¿\9aäÁ\9cäÂ\9eãÁ âÁ\9fåÄ¡äÄ¡åÅ¥åÈ¥áÄ âÄ¡âÄ¡âÅ¡äÈ äÇ£åȤçË¥åÉ¢äǤâÄ àÅ\9câÆ\9eâÅ\9eåÉ£ç̨áÉ¢àÄ\9dÞÄ\98áÆ\9eàÅ\9bàÇ\9aßÆ\99ÙÀ\95Õ¿\93Ö½\94ÛÁ\97àÅ\9fÞÅ\9cÜÅ\9bÛÅ\9dÚÄ\9aÛÄ\9cÙÂ\9bÛÄ\9dÞÈ¡ÞÇ¡ÞÈ\9fßÈ¡ÞÈ\9fâˤáÇ\9eѲ\80¾\91_±tF\9f\-\94R)\83H\1a\81H \84Q(\8ciC\9b\81_\98\7fZ\7fmMUL/&!\r\14\ f\ 6\ e\r\a\r\f
+
+\a\v\v\b \ 6
+
+
+\v\v\v\r\r\r\r\r\r\f\f\f\v\v\v\f\f\f\v\v\v\f\f\f\r\r\r\ e\ e\ e\ f\ f\ f\ e\ e\ e\ e\ e\ f\r\r\r\r\r\r\ e\ e\f\ e\ e\r\ f\ f\r\ e\ e\r\r\r\f\ f\ f\ e\r\r\f\ e\ e\v\f\f
+\r\r\r\f\f\r\r\r\r\f\f\f\v\v\v\v\v\v\b\b\b\a\a\a\ 6\ 6\ 6\a\a\a\ 6\ 6\ 6\ 6\ 6\ 6\ 6\ 6\ 6\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\ 6\ 6\ 6\a\a\a\a\a\a\a\a\a\b\b\b\b\b\b\b\b\b\a\a\a\b\b\b
+
+
+\b\b\b \b\b\b\a\a\a\b\b\b \b\b\b
+
+
+\r \f\11\10\f\11\ f\f\13\11\ e\13\11\ e\14\12\v\16\14\ e\15\14\r\14\12\f\16\10\v\15\11 \14\10\b\17\13\v\18\14\f\14\11 \14\10\b\18\13\v\18\14\f\18\13\v\19\13\v\18\13\v\1a\15\r\18\13\v\e\14\r\19\13\f\18\13
+\17\12
+\15\13\v\13\10\ 5\1a\15\b#\1e\12 \1a\ e)&\124/\eA=0íʲêÒ·êÙÄçÛÌéèÜèÓ¹éΰäĨèÈ«êÈ©ã¿¡Õª\8aäÁ£êȦæãè¤à¹\99È\9exÇ\9dyÒ¦\8cç¸\9eé»\9dê»\9dë»\9eì¼\9fë¼\9e콡ë»\9eëº\9dí¼\9fì»\9fì»\9fíº\9eì¶\9bí¹\9bëµ\97ì¶\9dìµ\9dìµ\95ì¶\94ëµ\96ì¸\9aì¹\99ìº\96í½\9bì¼\9cí½\9eíÁ¡îÄ¥îȪîƨíǧîÉ©íǨîȪîɪíǨíÈ©îÊîËíÌ®ìʬíÍ®í˯îΰíÍ®íίíͯìÌ«ìË©ëÊ©ëɧéȦëɧêȦèÄ£çÅ çÄ\9fåÁ\9cä¿\9cà»\96ß¹\95Ü·\93á»\96á¾\99à½\97ß¼\96á¾\99à¿\9bäÄ¡ãÄ äÆ¢ãƤãÅ£ãƤâÄ¢áÄ¡áÄ¡ãÇ¢ãÆ¢äÇ£âÅ ãÇ\9fãÆ¢áÅ\9dßÃ\9bäÇ æÈ\9fçË¥æɧâÈ áÆ\9fÞÃ\9bßÄ\9cßÅ\9càÇ\9aÜÂ\95Ù¾\91ؽ\96ÚÀ\93ÞÃ\9aÜÄ\9dàÄ\9dÞÄ\9cÞÃ\9eÜÁ\9bÙ¾\97ÜÂ\9cÙÂ\9aÛÅ\9eÛÄ\9aÜÆ\9cÜÄ\9bâÈ àË¡ßÆ\9aϱ\80«\88Z\91b:\8fU2\87N)\84K$\81M)\86a@\90}T\9d\8ec\9d\8fg\85z[VO/'#\11\13\11\b\10\ e\a\r\r
+\f\f \v\v\a\v\v\b
+
+\b\v\v\v\v\v\v\r\r\r\f\f\f\r\r\ e\f\f\f\r\r\r\ e\ e\v\10\10\f\ f\ f\v\ f\ f\f\ e\ e\v\ f\ f\r\ e\ e\v\ f\ f\f\ e\ e\v\ e\ e\v\ f\ f\f\10\10\f\ e\ e\v\ f\ f\f\ e\ e\v\10\10\f\r\r
+\r\r \ f\ f\v\f\f \r\r\f\f\f\f\r\r\r\v\v\v \b\b\b\a\a\a\b\b\b\a\a\a\ 5\ 5\ 5\ 6\ 6\ 6\a\a\a\a\a\a\a\a\a\b\b\b\a\a\a\b\b\b\a\a\a\a\a\a\a\a\a\a\a\a\b\b\b\a\a\a\a\a\a\b\b\b\b\b\b \v\v\v \b\b\b\b\b\b\b\b\b\b\b\b
+
+
+
+ \r\f
+\ e\r \10\ e\v\10\ f\v\13\12\ e\13\12\f\13\12\v\16\15\ f\15\13\f\15\14\v\18\14\r\19\14\f\1c\17\ f\19\14\f\e\15\v\19\13\b\18\13\ 5\17\13\ 5\15\10\ 5\17\11\ 4\1a\14 \1a\14 \18\15\v!\1d\10#!\190.'@>/OL;]\PolY\85\81o\8f\8cx\9f\9c\85¬¨\97³®\9cŲӮ\9bÕµ\96àÆ©Ýŧæêí×Á\9fÙ¿\9aؾ\9bÙ·\97Þº\9dΦ\89Ч\87Φ\86Ò¯\8c̪\88Õ±\86Û·\8fÇ zÁ\98nÈ\98uä³\98éº¦é» êº\9fé¹¢êº é¸\9cê¹\9céº\9bëº\9fé¸\9cé¶\99ì¸\99ì·\99ê´\98ê¶\99ëµ\9aê´\98ë´\96ê´\96ëµ\97ë´\94é²\93êµ\94é·\94ëº\99ëº\9díÀ\9fíáíÇ¥íƤíƤëáìŤëãìÅ¥ìŦìƧìŧíǨíŦëƦèâìǧìȧìʪíÌìʪìɨèŤìÊ©éŦìË©êǦêÇ¥èƤéŤçÆ£çÅ¢åáå¡à½\9aá¿\9càº\98â¾\9dß¼\99ß¼\98Þ»\98ß¼\98ß¾\9aáÁ\9dááâÂ\9fâÅ¡ãÅ¡äÇ¥ãÅ£áÄ âÅ¢âÄ¡ãÆ¢áÄ àÃ\9eâÅ¡ßÄ\9dÞÃ\9cßÃ\99åÉ¢åÈ¢å˧ãÉ£ßÇ\9fÞÅ\97ßÆ\99ßÅ\9aÝÃ\97ÚÂ\95ÙÁ\97Õ½\93ÚÀ\95ÛÀ\98ÝÃ\9aÛÄ\9aÛÃ\9aÙÀ\99ؽ\94×À\97×À\99×Á\97ÚÂ\9cØÂ\97ÚÃ\9dÚÄ\9aÞÃ\9cÝÆ\9cÚ¿\96ŧw\9e}N\83Z)zH\1c~L'\80N&\86\;\87sP\98\8dg¨\98m¢\98q\8c\83e^U4-+\15\13\13\b\10\ e\ 6\11\ e\v\ e\ e
+\r\r
+\ e\ e
+\ e\ e\v\ e\ e\ e\ f\ f\r\ f\ f\r\ f\ f\v\ f\ f\f\ f\ f\f\10\10\f\ f\ f\v\ f\ f\f\ e\ e\v\ f\ f\f\ f\ f\f\ f\ f\v\ e\ e\v\ f\ f\f\ e\ e
+\11\10\f\10\10\r\10\ f\v\ f\ e\v\ f\ e\v\ f\ f\v\10\ f\v\ f\ e\v\ e\r
+\ f\ e\v\ f\ f\f\f\f
+\v\f\f\r\r\r\v\v\v\f\f\f \b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\a\a\a\b\b\b\b\b\b\b\b\b\a\a\a\ 6\ 6\ 6\b\b\b\b\b\b\b\b\b
+
+
+ \b\b\b
+
+
+
+
+
+\v
+
+
+\b
+ \b\b\v\v\b\ e\r\v\ f\r \12\11\r\13\11\f\14\12\r\13\11
+\15\13\f\14\13 \16\13\r\17\12\b\18\12\ 5\1d\16\a \1c\ e$\1e\10&%\ e*)\1463\e<9!PL:]XEmkTxse\89\85s\94\8fy¨¢\8d´®\9dÀ¼¬ÎʱÖÑ¿ßÖÅáÛÒèåÛéæ×ìëÜëëáìíæÝÀ¥áǦÜħä׺åêìáɪßÅ£ÝÅ¥Ú¾\9bÖ¸\95Õ¶\94Ó±\93Ó®\8fظ\93Ȩ~Ç©\80Ĥ{¾\9aq¼\92nÅ\94sÓ£\86Õ£\8fݪ\95Ý\9bà¯\9cá¬\98Სâ±\98à²\9cä´\9cà¯\92à°\94â³\98ã²\99ã±\93æ³\94å¬\8eå¯\90ç®\8fè¯\90é±\94è\8dç¯\91ç¯\92ê³\95ê´\97é¶\95ë»\98íÀ íƤîÃ¥êÁ¢êÁ¡ëÁ¤éÀ¢éÀ¡éÀ¡êÁ£ìÅ©ëÅ£éÁ¡æ¿¡å¼\9aé¿¡çÀ¡èÀ\9eè¿\9eçÁ£ç¢æÁ çÁ£éÄ¥éĤæÁ çãèĤêŤéŤçÄ\9fæÄ¡æÄ¡â¾\99â¿\9aâÀ\9aß¼\97á½\98ß¼\97ݺ\94ܹ\94Þ½\99ݽ\99à¿\9bâÀ\9eàááÄ¢âÅ£âĤâÃ\9fãÅ¡àÄ\9eáÄ¡âÅ\9eâÅ àÂ\9fÞÀ\9cßÁ\9dÞÃ\9câÆ¡äÈ¡äÉ£åʦâÈ¢ÞÂ\9aßÅ\9cßÄ\9cÜÃ\99ØÁ\99Ö¿\98Ö¿\98×¾\95ÚÀ\9aÚÄ\9aÛÂ\99ÚÂ\9aÚÂ\9cÚÀ\9aÕ¿\98Õ½\96Õ¾\97ÙÂ\9bØÁ\9bØ¿\99ÚÁ\9cÛÁ\9bÝÂ\95Õº\8f¸\98k\8ei>|R&uE\17yK(\7fY9\8fjO\97\80[£\94k°¡{®\9dv\92\8ajg]::1\15\16\16\a\12\11
+\12\10\v\11\ f\f\11\ f\f\ f\ e\v\12\11\ e\12\11\ e\11\10\r\11\12\ e\11\11\ e\11\11\ e\ f\ f\v\r\r
+\ f\ f\v\10\ f\v\12\10\ e\13\11\ e\10\ e\v\ f\ e
+\10\ f\v\ e\f
+\ f\ f\v\12\10\r\13\12\ e\11\10\f\10\ e\v\10\ f\v\11\ f\f\10\ e\v\10\ f\v\ f\r
+\11\ f\f\ e\r
+\ f\ e\v\ e\v\f\ e\r\ e\f\f\f\f\f\f \b\b\b \b\b\b\a\a\a\a\a\a
+
+
+\a\a\a
+
+
+
+\b\b\b\b\b\b \b\b\b\a\a\b
+
+
+ \v\v
+\v\v\v\v\v
+ \a
+ \a\v\b\a\v \ 5\r\v\ 6\v \ 4\14\ f\b\14\12\r!\1d\r""\13/+\e?:*ED8QK2XVBkhTxrY\89\81e\8f\8ar¡\9a\83¦¢\8a§¥\91·²\9f½¹¢ÅÁ¬ÏÊ»ÙÔÀÞ×ÈæÝÐéäÑëèÝíìäììäêíêèìíçéìåèíäæëãåêãäèâäèããèë²\9aãŦâȨä̬èÔ¹æÊàÇ©ßÆ©ÛÁ¡Ø¿\9dÙ»\95Ôµ\8eÑ\8aѯ\8bͬ\82Ç©\81¿ zÀ\9asÀ\92oÇ\91tÉ\91q³\7fg¹\84u½\8a~¾\8c}¾\8b\80Ã\91\7fÀ\90|Ä\96\86¾\92|È\99|È\97|É\99~Ì\9c\84É\98xÍ\9a\7fÓ\9b\7fÒ\9b{Ü¥\85ߨ\86à§\86ãª\8câ¨\8aãª\8aä¬\91ä®\94æ¯\93è´\98ì½ ì£íäè¼\9aç¼\9bè¾\9cè¼\9bçº\99è¿\9fè¿£íÆ«êÂ\9få»\9bݲ\9bá´\99à³\97Û®\92Ü°\93Ú¯\91ݱ\99ܯ\94Û¯\92ܲ\96ܱ\94ݲ\94ßµ\95à»\97á¼\9bä¿\9eå¿\99âÀ\97â¿\97â¿\9aß¼\97ã¿\9aá¾\99à½\97ß¼\97ß»\97Ûº\94Ü»\96Û¼\97ܼ\97Ü»\97ß¼\9aÞ¾\9bÝÁ\9eÞÀ\9eÞÀ\9eßÁ\9dܾ\9bÝÀ\9dÞÂ\9dàÃ\9fÝÂ\9cÜÁ\9bÛ¿\9aÛÀ\9aÚÀ\9aÞÄ\9eâÆ äÉ£áÇ áÆ\9eÝÄ\9cÝÃ\99ÚÂ\96׿\95Ö¾\95Õ»\93ѹ\90Ó¼\92Ó¼\95ØÀ\99Ù¿\96Ú¿\9a׿\95Õ¿\97Ô¼\92Öº\93Û¿\9aÚÀ\9a×À\99Ô½\96Ù¿\9aÚÂ\9bÖ¾\91β\88\8fb\8fj>vP%yR(\81b?\86mJ\98\80_\9f\8dj¬¡|´¤\84²£\82\9d\94rtiFE:\18\1d\19\a\13\11 \13\11 \15\12 \13\11\b\14\13\v\12\ f
+\13\11\r\14\12\10\15\12\ f\12\11\r\12\10\v\14\12\ e\11\10\f\12\11\r\11\10\f\11\10\f\11\ f\f\10\ e\v\10\ f\v\11\ f\f\11\10\f\11\ f\f\13\11\ e\11\ e\f\12\10\r\10\ f\v\11\ f\f\10\ e\v\13\12\ e\ f\ e
+\10\ e\v\ f\ f\v\ e\r
+\ e\r
+\ f\ e
+\ e\f \ f\ e\v\ e\ e\ e
+
+
+
+
+\b\b\b
+
+
+
+\f
+\v \v\a\b \b\a
+
+\b
+
+\b \ 5
+\ 4\b\b\ 5\v\v\b\v\v \r\ e\a\10\10 \14\16\ e\1c\1c\15 \1f\16*'\1c75$;9)KG0RM8\YElfNys]\83~l\9b\98\84§\99±\94¹´¡É¿®ÏÉ·ÓνÞÙÇäßÎæàÒêæØêèÞìëÞííäêêåìíééëêéëìæéìæéíãæíãäêâäêããéããçããçããåããåãããããäããäããäããäî¥\95æ¾¢ßÄ¢áǧèίæαáÊàɬÜħֽ\9bѲ\8cÊ©\81É¥zȦzÏ«\82Ȫ\7f¿ rÃ\9exÌ\90jå£uÐ\8fkc@&cE2oN5uS?}YH}]H~^I\83`L\8deS\95gO\9bnS¡lN¦oX¥mP¬sW±vZ½\82iÍ\94\7fÔ\9c~Ö\9b}Ö\9c\7fÛ\9e~Ú¡|Û \82Ü¡\81Þ¤~ä©\8bè´\98éº\98ê¼\9eã²\93åµ\94ã²\91ä´\95æ¶\98åµ\96é¿\9fêÀ\9dæº\95ß°\8dݬ\8fÛ¨\8aÖ¥\88Ó¤\8aÒ\9f\86Ì\99{Î\9a\81Î\98\7fÏ\9a\80Ï\9d\81Ð\9f\81Ï\9d\80Ñ \82Ó¢\81Ö¨\89Ù¬\8eÚ¯\8eÚ°\89Ú²\8cÛ±\90Ú³\93Ü´\94Û¶\95ܸ\98Ú·\93ݸ\98Ü·\97Ú·\96×µ\93×µ\92׶\90Ø´\91×´\8eÖµ\91غ\97ع\97Ú¸\97Ø·\93Ö¸\96Ôµ\91Ôµ\92Ѳ\8eÕ·\95Ò³\91Ó´\95Ѳ\91Ùº\9bÚÀ\99ÝÅ¢Ù¾\98Ö¼\97Ó¼\99Ô¹\90и\90η\94Ȳ\8aé\82¿¨\80®\80Æ®\86̱\8aѸ\92Õº\9aÒ»\98Òº\94Ò¹\95Õº\94Ó¼\95×¾\97Ô½\96Õ½\98ؽ\97ؼ\95Õº\90Ê®\8a¨\8dn\8boC|b8\86fB\8dqO\96\7fU\9d\8ch¨\9c{°¥\85µ¦\85¶ª\87\9e\92s\80vZUL-.'\v(!
+"\1d\ 6&
+'#\ e" \f !\14\1a\19\ f\14\13 \15\13\v\15\12
+\12\11\r\14\13\ f\13\11\ e\10\ f\v\13\12\ e\10\ e\v\10\ f\v\10\ e\v\12\11\r\12\11\ e\11\ f\f\12\10\r\12\11\r\13\11\ e\11\10\f\11\10\f\12\10\r\12\10\r\11\ f\f\12\10\ e\11\10\f\11\11\r\ f\ e\v\ e\ e\v\10\ f\f\r\r
+\ e\ e
+\r\r\f\ e\ e\r
+
+\b
+
+\ 6
+ \ 6
+
+
+
+ \v\f\a\r\v\ 4\ e\ e \11\ f\ 4\19\15
+\1c\e\10 \1e\ f)&\15/+\19:7"DC0LG5XTC\[IjiXyrb\80{m\8c\86u\90\8cw\9b\97\86¥¡\8f®©\94º´¢½¹¦ÈıÒȱÚÒ¾àÛÊçâÐèåÖìíäíîéëíëêëêèìíåêíåèíäçíãåìãåìãäìãäêããéããèããèããçããæããåããæããçããåããæããæããçããåããçããæããèããçããçããçí¶\9eá½\9fÝÁ¢ßäèÍ°çÍ®âǦâÉ«ÞÈ£Û¿\99Ôµ\91ΰ\86Ï\7fÔ°~׬}Í©|Ç¢r×sç×\86äÙ\82Â\8aJ8 \1d\11\ 4\1a\11\ 3\1e\16\v*\1d\11.!\15/ \132#\18?-\1aT8$mE3yA,y>&\7fA3\83E0\96T>¬lXÁ\82kÎ\8fvÌ\8dqË\8frÎ\92tÏ\92tÔ\97|Ò\94wÒ\96u×\9b{à¦\87ݨ\8bÙ§\88Ø£\83Û¥\88Ù§\89ܪ\8bÚ§\86à«\91á®\8eâ³\8dݬ\87ئ\82פ\82Ï\9byÊ\96tÆ\91qÃ\8fpÂ\8eo¿\88jÂ\8bkÄ\8dmÃ\8clÅ\8fmÃ\8djÆ\91oÆ\91oÉ\93nÊ\96qÌ\99zÉ\98pË\9d~Ë\9d~Ë\9f}Í¡}ˤ\84Ȩ\88Ч\88Í¥\82Ñ©\89Ψ\85Ï«\85ʨ\80ͪ\84Ϩ\8bϨ\88É£\84È¡\83Ê¥\81Æ¥\84¡\83¢~¾\9e{À¡~½\9fxº\9b{¸\98uµ\94uº\9a}À \82Ç©\89ʬ\8cͲ\91Å«\8cÀ¦\7fº¢{¹¥\86º£\82³£}¯\9e~¦\93r¤\91m©\98w¯\9cvº£}Áª\8aÅ®\8dɳ\8dȲ\8eʳ\8d϶\93е\95ж\90Ó¼\98е\90и\90Ѹ\8eƯ\89ª\91p\96~P\90xM\91zO\9b\87] \8eg¬\9cu°£{³§\81¸¨\83½±\8f±¥\85¤\95w\87zXujIqfHwjI}rZ}r_xpTkcFdZ?RL1C@#61\15*'\12\e\1a\a\19\16\r\ f\r\ 6\12\10\v\13\10
+\12\11\v\11\10\f\12\10
+\10\ f \11\10
+\13\11\f\12\11\v\13\11\f\ e\r\b\11\10\v\11\ f
+\12\11\v\13\11\v\13\11\f\10\ f
+\12\10 \12\10\v\ e\r \11\ e\b\10\ f\ 6\10\11\b\12\12\f\1a\18 "#\17*)!,,!31"?;%IB,NM3]YBjbHulS\81}g\8e\85k\94\8e{\9e\99\82ª¦\90¯ª\93·°\9eÁ¹¤È¾¨ÍdzÔȳÛйàÛÇãÜËçãÒêæ×ìêÞìêâííâëëæêìéêííèììåçîäçíãäìããëãâéããéããèããçããèããèããçããçããçããèããèããèããèããèããèããçããèããèããèããèããèããèããéããéããèããéããéããéããéâáßäàŤÞáàÅ£Ù¾\9aÑ´\8dàÄ¡äͨâÅ\9f׸\93а\84Ю\85Ò¬}Ü\7fÚ¡tãÁ\99äëÞãçÊçÔqË\86E:\e\v\16\r\ 6\10
+\ 3\10
+\ 5\10\v\ 5\11
+\ 5\r\b\ 2\12\v\ 6\e\15\b9)\19X:(i8"n3\19p1\1fy3!\87A.¢bN¾~dË\8bxÍ\8exÎ\8etÊ\8ctË\8esÌ\8dtÍ\8esÌ\8epÎ\92sÐ\90uÓ\97{Ñ\96xÐ\93uÓ\99\80Ñ\99}Ó\99}Õ\9c\80Õ\9d\82Ø\9f\85Ö\9f\82Ö\9e\82Ð\98{Ï\96xÆ\8erÃ\8cp½\86d»\83c¹\81c¼\82dÀ\86eÂ\88jÁ\88kÁ\88h½\88e½\86c¿\88g¿\8afÁ\8ciÀ\8bj¿\8aj½\89l¾\8eo¾\8dn»\8cmÀ\91u¾\91u¾\92qÀ\94t¿\94sº\93p¿\96tº\95uÁ\9a}»\93v·\92p±\8fm®\8dj¨\87b¢\85a§\87f\9f\80b\9b\7fc\9c~`\97|X\97|Z\9a~]\97\7fZ\95~[\99\80\¡\89o¬\94z¨\93s¥\93q§\96r¡\93o \92q¡\93r¡\95t\98\8dl\92\85c\91\82`\8f\82^\97\8cg\9e\92k¦\98v®£\83·¥\82¶¤\82¹§\82¾«\8a¾ª\88¾§\83Á¬\8dÆ\90ǯ\8bÇ®\87é\82³\9bw¡\8ej\9d\8ak\9f\90q¤\94q«\9ax°¤|º¨\83¿\8fÅ·\93;\98ÖŨѼ¡Ñ»\9fÌ·\99Í·\9aÕ¿\9fÚ¤ÜħÚƬÓÁ¨Ë·\9e»¬\8e¬\9d\80\99\8bo\81w[i`JTN8A8\1f.)\12\1e\17\ 5\13\ f\ 4\12\10\b\12\11 \11\10 \12\11
+\13\ f \13\10
+\11\ f\ 6\10\ f\b\11\ f
+\16\13\v\18\15 \1f\e\10\1e\e\r(%\182.\1a10 92 MG2TRA][NkjYusX\7f|c\8c\88x\93\8dy\9d\95}¤\9d\84°¤\8e¿·¢Å»¥ÉÁ«ÚкÜÔÃäÛÉãÝÍçäÑêåÔêçÝííäíëßìíãìíåêîëéíëçëìåëîåêîäèïãçîãçîâæîãåíãåíãåíãäíããìããìããëããëããêããéããéããèããèããéããèããéããéããéããéããéããéããêããêãäëãäêãäêãäìãåìãäìãäëãäìããëããëããêããëããêããêàÄ¢àâÞà Þà ÜÀ\9dÜÁ\9dáÅ¡êÐíÕ³ãÊ¥Ô¸\93ͯ\83ί\7fשxåªråÍ\91ãæèããêãèÐè§iÉnJB#\13\12\v\ 4\11
+\ 5\r\a\ 3\10 \ 4\12 \ 5\10\b\ 4\ e\b\ 4\1c\15\aA4 _G;nN?k<(r4$v4%\83=,¢`N¿\7fdÉ\89rÉ\8crÈ\8bpÊ\8brÉ\8aqÈ\8apÈ\8aoÅ\88lÇ\8anË\8fsÈ\8bnÉ\89lÉ\8aoÌ\8crÌ\8dpÎ\8fuÌ\8frÏ\92tÒ\93zÐ\93zÐ\93yÑ\95zË\8dtÆ\88oº\81h¸\80e¹\81dº\82e¼\82g¿\85iÀ\85j¾\85e¿\88fº\83a¹\81]º\86`»\85`¹\85_¹\84a¹\83`¶\84b·\86f´\83c¸\86i¸\88o´\85iµ\86j\80b\83d©\84b¬\85e }^\9f\7ff\9ax]\97xZ\93u[\8dtX\87lR\87nT\80hG\80gI{eHzcC~hLzgIzeFzeF~mL~jJ\82rQ\89}_\8c\80`\93\85e\91\88j\90\88f\93\89e\94\8ah\93\87f\8c\7f]\89}X\83xR\86zU\8a|X\8f\81_\96\8ag\9f\92o£\97r©\9cw«\9dw¦\98u¦\9au¯\9e|\9a|¯\9dz´\9e{º¥\84¸£}¯\9az§\98y¦\96wª\98w¬\9cy´¤\83Ê»\98Ñ¿\9aØȨßϯãѲêؽíÚ¼ïÝÂîÝÂïÞÄîÜ¿îÞÂîàÅïáÇïãÊïäÍîåÍíàÇêÚÀÞÊÓÀ¤¼\8d\9f\8fn\82tTf_FA< (&\r\1d\19\r\1d\16\ 6\1d\16\b\1c\14\ 5\19\14 \1f\19\ e%\1d\f6.\19JC1bY>mcHxnT\86\80i\88\84u\93\8f}¦\9d\84¯©\91¶±\9dÀ¹¨ÌîÏÇ°×кÝÕÇåÛÉéãÍéäÓîéÜëéàíìâììäëíçèììèíìçëìåêïäëîãéîãèîãçîãèîãçîãèîãçîãçîãçîãçîãæîãçîãäíãæîãåîãçîãåíãåíãæíãåíãåíãåíãäìãäìããëããëããëãäìãäìãäìããëãäìãåìãåìãåìãåìãæíãçíãæíãçíãæìãåíãæìãäìãäëãäëããëãäëããêããëããêÜÀ\9cßÁ ßÄ¢ÞÄ¡çˬéѳêÒ¯ëѯéЬãÈ\9fÜÀ\90á¾\86æµwç¿\84âÝ\9aãé¯ããçããâãëãç\8auÜk_R*!\15\f\ 6\10\b\ 3\ e\a\ 6\ e\b\ 6\12\b\a\12\b\a\ e\a\ 3\e\15\ eI:2qULx]GvN<r<,r3$\82<0\93Q<·w\Å\85nÆ\8boÆ\88oÅ\87nÆ\87lÄ\87kÃ\85iÅ\87nÆ\88mÅ\88lÅ\87lÅ\88lÅ\87mÅ\88lÇ\89mÈ\8boÉ\8dpÈ\8amÌ\8etÌ\8euË\8dwÈ\8cqÄ\8an¿\85j¹\81eº\80f·\7ff»\81g¿\83j½\81g¼\82f¼\84f¶\7f^¶\7f`³}\µ\7f_±}Y¸\83^²\82]®}X±\81^®\81^®\80[«|Y±\80g¬\7fc«~f¡wa\9fv[\9bwV\90pR\8boL\87mO\7ffIxaF{bHp\Ap[?kX<nY=mZ=kY<n]@raCp`CsaFveEqcBwfM|lO|pQ\82wY\85z[\88|[\8c\81`\8f\84e\8f\83_\8f\83_\8e\82`\86zU\84yX\81wX\88{Z\8d\80\\93\84b\9f\90n\9f\95s¢\99v \96t£\9aw¢\98v¢\99w¢\95t¤\94t¥\97t«\9by¬\9bv\9bz¦\96t§\97t«\9ax¸¦\84ÒÁ\99ãͨíÚ¶íÞ½îßÃîßÄîàÂîÛ¾îÝÁíÝÀîÝÀìÙºíÙºì×·íÛ»íÞ¿îäÍíéÒíëÓìíÕíìÔíèÐíãÉèÚÁ×ǽ°\93¢\98v\7fsTjcPSJ2L?)F:\1cA8!G=)VK.nbF\9b\90y¸¬\8fǼ¤ÒɵÖ͹Þ×ÇäÞÎçàÐìç×íèÙíìàììáëîçêíèèíêçìíçìíåëîåëîäêîäéîãéîãéîäéîãéîäéîãéîãèîãèîãèîãèîãèîãèîäèîãèîãèîãéîãçîãèîãçîãçîãçîãèîãèîãçíäçîãçîãèîãçîãèîãçîãæíãèîãçíãæíãæíãåíãæíãåíãåíãæíãæíãåíãçíãåíãæíãåìãåìãäìãäìããëãäëããêãäêããéããèããéããéããêÝÀ Ý¿\9eàâåɧëÒ³éÏèʧäÄ\9fá·\91ê\8cé}äÓ\8dâ´sãÁ\7fã×\98ãçÌããâããããèáçiRØdYX/\1c\19\r\ 5\ f\a\ 4\r\b\ 3\11 \ 5\11
+\ 6\12\v\ 6\11 \ 5\1e\18\12J<5\7fb]\95sa\83aPvE5v7)}9/\92U=²sWÂ\82lÈ\8asÅ\85mÅ\88qÄ\86oÂ\85mÂ\83m¿\84lÁ\85oÂ\81m¾\83h¼\7fe½\80i¾\84hÀ\86jÃ\86kÃ\87mÂ\86jÈ\8csÄ\89nÅ\89sÂ\89nÀ\89l¹\81f¸\7fd¸\7fdµ~d·\80e¸\80d·~bµ|aµ|b¬z\®|_z^ªyZ«zY¬zY«{W©zX¨yY¨yY£uV uX\9fsU\98sV\95pU\8ekO\89lO\7fgKwcHq_AiW7dT8fV:dT9fX<dU9fY<fX;iZ=fY=h[=i\>i[?j\?pbDr`BsfJ{nP~rS\80vV\85zW\8a~]\8d\80\\90\84c\8f\82`\8e\82]\8c\7f^\87{Y\83zX\83yW\86yX\8b\7f]\91\85`\98\8cj\9f\93o¡\97v \93o¢\97s\9d\92n\9f\92n\9f\92n\9f\92n¢\93p¦\96t£\98y¨\98{¦\98x¦\9a}¬\9b{Á®\89åÑ®îß¾íäÆîåÇîßÁîßÁíÛ½íܽíÙºíÛ»ìÙ¹ëÖµê×·éÔ²êÕ´êÖ¸ìÚ¿îáÃíçÊìêÑìëÔììÕíìÔíêÕîéÓîäËèÙ¿Ýͳ¿µ\99«¡\81\9b\8ep\8e\83e\8ay\\82oO\8e~_\9e\82ÔÆ°èÞÉîêÜíîâëïèëîèèìëèììçììåìîåëîåëîäëîäëîåëíæìíåëîæëíæëíçììæëìçìëçëìçìëæëíçììèììçìëèìíçììæìíæìíèììæìíæëíæëíæìíåêíåêíåëíãèîäéîãèîäéîäçîãæîãçîäèîäèîäéîãèíãèíãèîãèîãèíãèíãæíãæíãæìãåìãåìãäìãäëãäëãäìãäëããëããêãäêããêããéããéããçããçããçããèããçããçããèÞÀ£ã æÇ¥ççå¼\9cÚ¤\8aÛ\96\80ÇtRÊZ:áZIä£wãÓ\85ãªkã\9adãÖ¥ãããããæããããçÖå}BÜbEh3#\15\v\ 4\10 \ 4\ f\b\ 6\ f\b\ 4\10 \ 5\10 \ 5\ e\a\ 4\17\ f\vMA5zfY\92xf\89hUxJ9l3 p4%\89K>¨jW¿\7fjÃ\83lÀ\82lÂ\84m¾\80m»\80e¸~f»\7fiº\80h¹}e¹\80f·}e´|`¶z_»\7fg½\82k½\81jÀ\85nº\7fh¿\86n»\82i½\84l¸\80g´|c¯z_ªuY«v]¬x`ªvZ¬x^ªw_¥t_¥sY\9emR pV£tZ¡qV¢vZ¤vY sW\9erV\9bqS\98pV\8fjP\8bjF\85hDydFt`Al_@eX7dV8`S4_Q6dU:_P6`R6aS7bT8dW;eW;eV:fX;i]=n_Co`FmaBseHveExiJ{mO~qS\7fsT\89zZ\8b\7f^\8b\7fZ\91\84c\93\87e\8e\82_\8d\7fZ\8a}\\83xX\80wR\84xU\8a\7f`\93\86c\9a\8cj\9d\91l \95u¢\98w \94t\9f\93p\9f\92n \8fm \90o¤\93r¢\95v¤\97w¦\95w¢\97w¦\9a~¯\9ezϼ\96êؾîåÈíçÈîäÆîâÃîßÀîÞ¿íܽíܾíܽîÞ¿íÚ»ìÚ»ìÙºë×·ëÙ¹ìÚºîÞ¿îãÇîåÈíèÎíêÒììÓíêÏìëÑìëÓíëÒïèÑíãÈçؼáѳÚ̱ÍÁ¦Â³\93ö\98Ë¿¡âÖ½îìÚêîéçíìåëîåëìæìíåëîæëîæìíçìëçìëçíêéíééíèéíæëîäëîâëîâìîßíîàííÜíîãìíáîíÛííÝíìÚîíÛíìÜííÛîíÚíìÚíîáìîáíîÞíîáíîàíîâëîåêîåêíéçìíçìíåêîäéîãæíãäëãäëãäéãäèãæìãçîãèîãçíãæíãçîãæìãåìãäìãäëãäêããêããêããêããêããéããéããéããéããéããéããéããéããéããéããêããéããéããéæ¬\98Ë\9e\89Ã\8fr¿\81j´iJ¸RAÂNEÊG1ë\DßF3å\96gãÅvã\83Lã\9ciãÕ¬ãçàãäåããæããêâ´\84ç]C}4*\1a
+\ 4\11 \ 6\ f\b\ 6\ e\a\ 3\ f\b\ 5\10 \ 4\ f\b\ 4\16\10 PB3ziY\96{n\8foavK7g2 i0 \7fE5\9dbJ¹{d½\81jº\7ff¸|a¶|cµ{c³xaµzc³x_·|d®u\°u]°v[±v\²w]¶{`´z`´|c²z^±y`®w]®y]«u\©t\¤rW¡nT£rZ¢pW\9bjQ\97iO\94jN\93kO\90eI\90eH\92jO\8fgM\91hI\8ehG\8fhM\91jM\8diJ\88fJ\81dHz_Er\?n^?cU6cV6`Q6_R6`S8bS9aR:aS:bT:bT;aS9dU=fX<hY>hY>jZ@p]Cp^Cp^DpbGseIwiJxhG|pQ\7frQ\81rN\86uR\8c\7fZ\91\7f^\92\87g\95\85a\94\85a\8d\81_\89|[\84sN\84tQ\85wV\8b}[\94\88h\98\8cj\9c\90l\9f\93o \96t\9c\90o\9a\8en\9c\8cj\9e\8dk£\92r£\93s \8fo¡\91o \8fl¦\95v± \84IJ\93ÜȦìÜÀîåÉíçÈîäÆîâÃîàÁîßÂîßÂîàÄîâÅîâÅîäÇîäÆîæÇîæÇíåÇîäÈîãÈîãÉîäÇîçËîèÍíèÌîçËíéÎìêÒìëÔììÔìëÓíëÒîéÑîäÌëáÊåÜÅßÓ»ßÕºäÚÂîéÐíîÞëîáèìêèìêèíëêíçêíåìîãìîâìîáíîÝíîÛîí×îì×îìÔîëÖíêÒîéÐíåÍíæÎìãÍíåÎìåÍìäÌìäÍìåÍìåÍìåÌëäÍìåÍîèÐíèÐíçÏîêÕîë×îëÖîéÔîëÖííÜíîáìîãëíåèìíãèíããìããçãããããããããããêãäíãçíãæíãæîãåíãåíãäìãäëããêãäëããêããêããêããêããêããéããêããêããêããéããéããêããèããèããéããéããèâ\89zÅziÉrh·]W\99C+ÁK@»B5ÎM:ÞT=àK<ãº\86å\85NèW9âqRã\8diãÇ\8eãã¨ããëããæãº\96æVB\815.\17 \ 6\12\b\a\11\a\a\11\a\a\12\b\b\11\a\a\11\b\a\16\11
+I<-vfW\98\7fq\8epe{Q=b2\1ca,\1dyA0\94\F¤nY°zc±yc°y_±xa«u_«r]t`¬u`ªq^©p]«q]ªq]¦mY¦o\¨oY¬v]¥pZ¨qZ¥oZ£qa¢q[¡r[\9akX\98jU\97iV\91cL\8fcF\8bbH\87cG\84bG\88cG\86bF\82`D\82`E\82bF\81`?\80a@y[;tZ8yb?t^?q_Bo\?fU8cR3cQ6bR7`Q5`Q5bR;eT<eU=cS<dU=fX?jX@jW@jZ@mY@kZ?mZ@p]Cs`Fn_DsbGxjNziLzjM}rS\82tS\83sQ\87xU\8a}Z\8e\82\\8f\82b\8e\82a\8d\80^\8c\7f^\89}\\84wU\86vS\88wS\8e}^\93\83^\9a\8ce\9c\90i\9f\91l\9c\8ei\9b\90l\9d\8dj\9a\8cg\9b\8cf\99\89e\9c\8bh\9d\8cg\9d\8bj\9e\8eh¨\97rʸ\95áдëÝÀîæÉíèÎíéÍîåÆîäÅîàÂîáÂîâÄîãÄîåÇíæÉîçÉíéÍíèÎìêÏíçÍìêÐìêÐìëÑíêÏíèÍîèÍîæÊîæÊîæÊîèËíêÐììÕëìÕíìÕíëÓíëÓîèÏîèÎîæÌìâÈìãËíäÊîèÐîìØíîÝìîàìîàííÞîíÚîì×ííÚîíÙîíÚîíØîìÖîëÕîìÕîêÓîêÒîçÏíçÏíèÏíçÏíçÐíäÎìåÍíäÌíäÎìäÌìãËìäËëâËíåÍìæÌíæÏìäÌíäÎíåÎîçÐíåÏîèÒîéÓîéÓîëØîíÛêíçæéîâãéãããããããããããèããìãåìãæíãçîãçîãçîãåíãåíãåíãåìããëãäìãäëããëããëãäëãäëãäêããêããêããêãäêããëããêããëãäëããëÎ{jÂvi¿e`¾d`¥J=°A4¯:*½@/ÏF8ãUCãÆ\84çxVíR7êH.ä^Bã¨\82ãÊ\8dããÝããêãÓ¡éuM¢=5\e
+\ 6\12\b \12\b\b\11\b\b\11\a\a\11\a\a\11
+ \17\10\vJ=-vfW\95~k\96xl~YCg@"^0\1cq;-\80N?\99gY¥t_¦s^£q\£q^£q]£o[¡oZ nY¤q]¢o[\9foZ\9bkU\9emY\9dn\¢p_\99hV\9cnY\9dm[\97gS\95jS\91eR\8eeO\8edM\8bbL\88aK\87bI\82]C\81]C}[@|[@xZ=yY=vX9pU6rW:nU2qV8qZ;p\@m\>n\?mZ?dS7dU9iX;gT:iV<eT:eS8gT=kV@kXBiV@kX@lYBgT>nZCo[Bq_Eq\Cn\AsaDubHufGweI{mP|kM~pS\7frU\82tT\86vV\87xT\88yV\8f\81]\90\81^\8f\80]\90\81^\8f\80\\8a}X\88yU\88zQ\8c}S\90\7fZ\93\85\\98\8ab\9a\8bc\99\89`\98\88^\9b\8ac\9a\89d\97\86`\9a\89c\97\86\\98\86`\97\85]\99\86_\99\87^·¡yÞɤíãÉíêÒíéÌíéÍîçÉíçÉîâÃîâÃîâÃîâÄîáÅîäÇîåÉîçÇíéÊìçÎìêÎíëÍìëÐììÓëìÓëíÔêíÖëìÓëìÖìëÐíèÌîèÏîçÎîèÏíéÒìëÔììÕììÔíì×îëÔîéÒîæÏîçÏîåËíãÊíäÍîéÓííÜííÝíîàíìßîì×ííÞìîâêîæêîãéíåêíäëîäëîãìîßìîßëíßíîÞíîßíîÜííÚííÛîì×îì×îìÖîìÔîêÔîêÒíèÐîèÐíåÎíçÐíæÏíçÑîæÎíçÑíèÕîéÔîèÕîéÔîëÚîëÛïíàììäèèåååæäåéãåìãæìãæíãèîãèîãèîãèíãçíãæîãåîãåíãäíãäìãäíãäìããìãåëãåìãäìãäëãäëãäìãåìãäìãäêããéãäëãäê\93SJ\8fMC\8bE9\86>2\91A3\979'\9c4(£9%¹>+ÊC/ç}_áV@×= ìI/æR9ã\87\ãܤããÝããâãëÙã©pÀF8%\v\ 1\12 \b\11\a\a\13\b \12\b\a\12\b\a\10
+\b\15\ e F7/o_M\9f\83s£\7fp\93o_sR9cD4h9.wH:\8d^O\9cnY\9alW\9aoW\9boY\9anZ\9bl\\9al\\96jV\97hU\9akZ\98kY\93kW\90hQ\93jV\8ddO\90iU\8dgS\8dhR\8aeN\86bI\87bJ\88dL\83_G\83_F\7f\CyW>z[CxYAwXApR:oT8pT9mR6nS8kQ6mS7nT:oW=mX>m\BlY=o\Bm\@kZ<lY;n[BlY>jW<hU;p]CoZAp[CoZAoZ@mY>s_Er`Es`Fq]BvbGv`B{hJzgJ|gE\81jF\82lM\84nK\83qP\88tR\89wR\8byW\8ayV\8d|Y\8f\7f\\8f~Z\94\83_\93\82^\8f\7fZ\90\80Y\91~Y\8f}Z\97\81X\96\7fU\93\80W\95\83Z\99\87^\9b\87^\9a\87^\96\84[\95\82X\97\83Y\96\81X\99\84Z\99\83Z\99\84Y\97\7fT\99\83Y¼§\7fäЬîæÉíéÎíèÊíèÊíéÊíèÊíéÊíæÉîåÇíæÈîäÉîäÊîæËíåËîæËíèÍíçÌíçËíçÎìéÏììÒëíÕéîØèîÜéîÜéíØêî×ìëÓíéÏíèÐíçÑíæÏíéÏîëÓììØíìÙíìÕîëÔîêÒîèÑîéÏîéÏííÚëíåèîèéîèéíèçíëçìëæììåììäëíäëîäêíãêîãéîäêíãèîãéîåëíäêíäëíæëìæììçíéèíéèíèéíçêíèëîæëîèìíãìîâííßííÛîíÙîíÛîìÚîíÝííÝíîáíîÞíîãîíâìîäìîåìîäëïêêîêçííåêîãçíãçîãèîãéîãèíãèîãèîãçíãèîãæíãæíãæíãæíãæìãæíãæíãæìãåìãæíãåìãåìãæíãæìãåëãåíãçí[-\16k3\1ei.\el,\19o1 \801\1f\8e1\1c\923 \8e-\14\8f)\rÉ:'À*\13·.\14â=\1cåV5ãµ\83ãç¸ããéãããããæãÀ\84ËP>.\ e\ 4\12
+\ 6\12\b \11 \ 5\13\v\ 6\11 \ 4\12
+\a\13\v\ 6E80zgY \84y©\8bx\9a\7fh\88nYsSCqP7zT?\8bdS\96o[\97p\\97p^\98o]\93kV\92jX\94l]\8fhT\90iW\91hW\90jV\8bgR\8ciR\8chR\87eK\86dJ\85cK\84dL\84bL\86cM\7f]F~_F|_H|_Iz]Hz]Hx_GpT@qWBoU=pS=mS;nT9tY?rW=oT:sZ@t\Aw]Ev]Cy_FxaGwbFw`DxaBwcGv`GzeKv^G|bK~eM}eN}gN~fL\7feL\81hO~fM\81iO\82iP\86nT\8crY\87qU\88sS\90wW\8brR\8ctU\8fyW\8eyT\91zV\91|W\8f|X\8d{Z\93\7fX\90\80V\93\81Y\92\7fX\95\82]\93\80Y\97\84_\96\80W\96\83\\97\83Z\9d\85_\98\85\\99\88]\9b\88`\99\87\\9c\87]\9d\8a_\98\84\\98\84[\99\83Y\98\82X\99\83\\99\84Y\97\82X\9c\85[°\98nÜÅ\9díàÂíèÏíæÌíçÎíéÍíèÎíçÎíæÌíçÍíèÎíèÎíæÌíèÌîåÈíçËîçÉíæÇîæÇíåÈîæÇîçÉìéËêíÖëíÙéîÙçîÝæîÝêîØëí×ìêÒîèÎîçÍîåÌîæÍíêÐìëÔìíÖììÙíêÕîí×íìÖëîÝçíæäíëäììãëíäììæììäììãêîäëíäêíäëíãêîäéîäéíãèîãçîãèîãèîãéîãêîãêîãêîäêîäêíäëíãêíåêíåêíäêîäêîäêîäëîæëìçíëèíêèìêèìêèíëèìêçìëæëëæëìåëîåêíäêîãèîäéîäêîãéîãèîãèíãèîãéîãèîãèîãèíäèîãèîãéîãéîãèîãèîãèîäéîãèîãéîäéîãèîäéîãçíãèíãèîãçíãèîäèîZ,\17h2#h+\eo.\1co0!v-\19|/\19|*\15\87*\12\993\1a¯5\e²/\18Â3\1eéE*â{Sãè²ããèããäãããããéãË£ß^[?\ f
+\13\ 6\ 5\12\b\a\14\f\ 6\11 \ 5\12
+\ 5\12 \ 4\14\v\a@6)q`Q\9c\82v\92}¤\8ap\9a\7fl\8coW\82_G\86gP\98zg\99\7fh\98~h\97ud\96ua\95rb\94p^\90kX\92o\\89kV\8egR\8fjV\8fjV\8ahQ\8ahR\88eO\86dK\86eI\83bJ\84aK\85aK\81eL{_D\80bJ}`LxaJz`Ix^Fz`Jy]Fy]FuZA{^E{^E\7faIy]D\82fL\82eL~cJ\84jR\86iQ\87kP\88lT\87mO\88lP\85jK\8anT\8anT\8boV\8fsY\90sY\8eqY\92u`\8fr]\8fsZ\91w`\91u]\94xb\91w]\98z`\99|c\96y^\98|_\97{^\97{^\94yZ\99~^\99\80^\97~]\98~\\97\80^\97\7f\\97\81[\9a\84[\95\81[\99\87_\99\87b\98\86b\9c\85a\9b\8af\9d\88_\99\85]\9c\87`\9c\88_\9e\8a`\9e\8a` \8cb\9d\89^\9d\89^\9c\8b`\9a\88^\9a\89^\9a\86[\9a\86\\9b\86\\9a\88a\9b\83Y\9d\86\\9e\8b_ʵ\8cèÓ±îãÆíçÌîæËíèËîèÌíéÏíêÏìêÐìëÓíêÐíêÏíèÎîæÊíçËîæÈîæÈîæÇîæÈîãÄîäÄîåÇíåÉìëÏêíÕéîÛçîÛçîÝèîÞèîÝëíØíëÒîæËîæÍîåÌíçÒíèÔíêÒìíÖìí×ìíÛêîßæíéåíéåíéäìëäëìãëíäêìãéîãéîãéîãêîäêíãéîãéîãèîãèîãéîãéîãêíãéîäêíäëíäêíãêîäëíåììåììäêîãéîãèîãçîãçîãæîãçîãçîãçîãçîãèîãæîãçîãçîãæîãèîãèîãæíãçíäèîãçîãèîäéîãèîäéîäêîãéîäêîåêîæëîäëîæëîäêîæëîçìíæìîæìîåêîäêîäêîåëîãéîäéîãéîãéîãéîåëîäêî_/!d- g,\el-\1dj-\1dm(\12p(\13t&\11\83'\14\98.\18§1\1a´0\1dÖ7*äoeãÜÃãæÕããäããããããããããåØçxsX\15\12\19\v\a\14\r\a\14\v\ 6\14\v\ 6\17\b\ 6\12
+\ 5\14\v\a80"iYE\97\7fk¬\94~§\8fs§\8du\99~e\96zf\99zk£\86uª\91~¤\8cu¢\84p\9czf\99uh\95p`\97t_\92p\\93r`\91m_\90kW\93q_\8do_\8foZ\8bhQ\8ahR\8biO\8ckO\8diU\8ciT\8emW\90jW\90kT\92pZ\8bmV\8dpV\88nW\8boY\90oY\8bjR\8enX\91mX\92qZ\90qY\95qW\97rZ\9avb\99v_\97uV\9dva\9by`\9bzd\9az^\9a|[\9c{e\9d}d\9b{a\9a{]\9c~b\9e\7fc\9f\80e\9c~g\9c}_\9e\80e\98\7fa\9c\81d\9a\80b\9b\7f_\9b\7f^\9a\7f_\9d\82i\9a~a\9b\7f\\9c\7fb\9c\80e\9b~]\9c~\\9c\81`\9e\86a\9e\85e\9d\85b\9d\87c\9e\87d\9e\87c \8bh\9e\88d\9f\8bf\9b\88e\9e\8af\9e\8be¢\8cc£\8ef\9d\8bb¡\8ba¢\8dc£\8cc¥\8ee©\95nª\93qª\95q¦\94k£\91k¢\90i \8ba¡\8ab \88a\9e\88_£\8ed¸£|ÞÅ îÜ¿îçÌíæÊîèËíçËíéÎìêÐíëÑëíÖêí×ëìÓìëÑíèÎíèÊíçÊîäÆíâÃîâÅíâÃîÞÁîݾîàÀîãÃìèËëíÔêî×èîÚçîàéîàèîáéîáììÖíêÑîåÌîäÉîãËîäÊîæÌìéÒëìØëîÞéîâéîáçíææíèåíéãëíãëíãêîãéîãéîãéîãéîãéîãéîãêîãéîãèîãéîãéîäêíåëíåëìäëíäëíäëíäëíåììåììäéîãéîãçîãèîãçîãèîãçîãçîãçîãèîãçîãçîãçîãçîãèîãçîãéîäêîäéîãéîäêîåêîåëîæëíæìíåëîæìîçìíèíìçìíçìíèíìèíëéíìéíëçìíçíìèíìæìíæìíåëîäêîäêîåêîåëîåëîåëî[.!]- i-\1dk+\1an*\1an'\17t*\1aw(\18\80&\12\97+\16 +\12´0\1däD=â{hã³\88ãæÍããããããããããããããæéÀ§t\1a\1a"\r\a\1a
+\a\1a\v\ 6\16\v\ 5\17\f\ 6\1a\r\ 4\16\ f\ 68)\1ao^I\9d\84r±\95\84±\97\7f°\93{±\94z\91~º\9d\8aÂ¥\91ç\95»¢\93³\9b\84²\93}µ\94\7f³\93\84²\91\7f¶\94\81±\8ez«\89v¬\8bt§\86v¡\81o\9f}i¡{g\9bzd\9aub\9f{f {i\9cv`¡xe va¢}g {i¤\7fj\9ezd\9f|f\9f|d¡zd¢xa¡\7fg¡{d©\80i¥\82g¥~d¦\80i¦\80h¨\80h¥}c¦\7ff§\80i§\82j¦\83k ~`§\80e¦\82l¤\82h£\80e§\84j¤\85i¢\83d¦\85f¥\86j \81c¡\87d\9f\84b¢\87d¢\88f¡\87f¡\88j \83e\9f\84g\9b\81[\9b~b\9c~]¥\87b£\89h£\89c¥\8dj«\92uª\93m¤\8ei¥\8el¤\90g§\91p¨\91k¦\90l§\8eg¦\8fe¦\90h§\90j¨\91g¨\93h©\95k\95m³\9cw¶ w¾¬\87Ã\8bƲ\8c¾©\82ºª\80¸¥yº\9fy¹ zµ\9cw³\9bp®\98k¹£zØÃ\9dëÙ¾îæÊíéÍíêÎíéÎíêÏììÒêíÔéî×êîÛéîÙéî×ëíÓìëÎîéËîåÈîâÃîãÅíܼîݽîÜ»îÚ¹íÛ¹îݽíåÈìëÐêíÖêîÜéîáèîâèîáçîßêîßìíÖîêÎîãÈîâÄîáÅîåÌîèÐíëÒììÖëìÚëíÝéîàçîãåíèäìëäììäêíãêîãêîäéîäêíäêîãêîäêîäêíäêîäêíãêîäëíåëíåëìäìíæíëåëíäëíäêíäêîãéîãèîãçîãçîãèîãçîãèîãèîãéîãèîãéîãéîãéîäéîãêîäêîäêîäêîåëîæìîæìîçìíçìíèíìèíìèíëèíëêîêêîèêîêéîëêîêéíêéîëèíìèíìçììçìíçìîåëîåëîçìîçìîæìîèííçìîZ+\1d`, i,\1cl-\1el,\en%\15t(\15|(\16\87)\15\97.\1a¥-\e¹1 ê@/âfDã°tãçÍãããããããããããããääè±\90B:I0"L4&S8$N8"SC5WE:\K:r_M\94\84m¯\9a\88Ǫ\97ɬ\98Æ«\95Ī\93Ƭ\96͵\9cÕ¼¢ÚÁ©Ò·¢Ö¹¡Ñµ\9bγ\9cÙ»§Ô¶\9fÓ´\9cض£Ð«\97˨\94À\9c\89¾\96\84·\90{·\8fyµ\95|·\94yº\93x·\92|¯\89q´\8e}³\89w°\87t²\8bx¯\85o\86n\85o¬\84lª\84l¨\84k¨\85l«\86p«\89r¬\88o«\87q«\84lª\86n§\82i«\87p¨\85nª\85l«\8bq¨\8an¦\88k§\8bn¦\8bk¦\8bk§\8cm¨\8en©\8ekª\8cj¯\93t®\94y²\96v°\94r³\97z³\97}·\9d\85³\9d\7f´\9ayµ\9b|°\9c\80¬\98r§\8em«\91u¯\96|°\9a}¶\9c\82º\9f\84¼¤\8aº¤\81À©\84¹£\7f¸¦}¹¢~¸¢\82´¡z¹¢}´\9du¼¤\7f¸£w½¨\84»¤\81«\87Â\8aDz\8eÑÁ\9aÔÅ\9fÝÍ©ÛÉ¢ÜˤÖÇ\9fÒÀ\99Ó¾\98κ\94ϼ\94Ê´\8cл\91͹\8fÛÇ\9eíÞÀîæÈììÏììÒëìÓëìÓêíÔêîÖèîÚèîÛçîÝæîßåîßéîÚëíÕíìÐîãÆîáÆíÝ»îÝ»îÛ¹íضîÚºì×¼íÚ¾îßÂíèÐëí×ëîÜéîßèîáèîáçîâèîáêîÞìì×îæÊîáÆîàÇîâÈîäÈîäÈîçÍíèÎíêÐëíÖëîÜèîâæîèåíêæíêåìíäëîãêîäêíãéîäêîãêíãêîãêíäëíäêíåëìåìëæììåììäëíäêíäêîãèîãéîãçîãçîãçîãèîãèîãèîãéîãèîãéîäéîãéîäêîãéîäêîåëîæëíæìíçìíçíìèììèíëèíêéîëéíëéíêêîéêîéêîêëîèêîéêîéêíêéíëéíëèíìèíìçììçíìæìîçìíçìíéíìèíìèííèíìY-\1d],\1cg1!h)\18k)\16r'\16w+\e})\19\8e)\19\9a-\19£*\15¼4$ãA7âk]ãµ\81ãçÞããèããããããããããããä½¾Ê{k£~j©\88o¨\86q«\8au¬\8d|¬\95\84¯\97\88½¢\8d˲\9a׺¥áðÞįàŸáÉ´äʺä˶ëÒ½ëÒ¿ëÑ»ëÒ¿êÒ¾èѼéϼíÕ½ëйäŴݸ¡Ò¬\97Ê\9e\93Ä\97\86Á\94\83Á\94\84ɧ\90Í°\90Ì®\92̬\93Ê\91Ë«\96Æ¢\8bƦ\8eÀ\9f\87Á\9b\80¾\9c\86¾\9c\89¹\98\82»\99\7f¶\94z¸\92x³\92yµ\97z´\91u³\93~´\96|µ\95x´\96w´\93t´\94x¼\9az¸\9a\81·\9b\80µ\9a}¹ \82¶\9c|¼£\88º¤\83¿§\85©\8aê\89©\8cŬ\8eɱ\8fÌ·\97Ó¼¥Î´\98Ï» к\9aϹ\9a˶\92Å°\8bÅ®\91Å®\8e˯\93ʵ\97Ë´\9aй\9fÓ¼\99ÖÀ\9fÖáÔÁ\9dÕÄ ÒÀ\9aÑÁ\9bÒÁ\9fп\99Ѿ\97ѽ\98м\99Ò½\99×Ä¡ØÅ¡ÚÈ¡ÞʨâϪåÕµæ×¹ëÛ¾êÛ½èØ·èÙ¹æ×µæ׶åÕ²ãÔ²äÓ²áЯßÎäÔ³ëÝÄíëÏêí×êîÙéîÛêíÚéîÝéîÞçîàæîáåîãåîãäíäãîçäîäçíßììÕíèËîâ¿îݺíÙµî×·ì׶ì׸ëÔµí×¹íÜ¿îãÈìêÓëíÚêîÞéîáéîâèîãèîâéîáëíÚîéÐîçÏîãÊîãÇîáÆîáÊîãËîãÊîåÌíçÐíéÑêë×êíÚéíàæíèäíëäììäëìäëìãêîäêíäëíäéíãêîäêíäêîäëíäëíäìíåììãêîãéîãèîãèîãèîãçîãèîãèîãèîãèîãèîãéîãéîãéîäêîãêîäêîäêîåëîçìíæìíæìíçíìèíëêîêêîéêíêêîèëîêëîèëîèëîèëîèëîèêîéêîéêîëéîëéíëéíëçíìçììèíìçíìéîëêîêéíëéîêéíëY-\1dg:'d-\1ag'\18o)\19p#\12x*\18}&\13\87'\14\96*\16¤+\15»4$Þ=3åVVã\92mãçÎãç×ããåãããããããããäºæ \95ཪ߿¬ß¿°âıãǶäɹäȸç̼êÒ¿íÕÃíÔÃïØÇîØÈí×ÆîÛÍîÝÎîÛÌîÚÊîÜÉîÜÌîÛÊîÛÊîÛÉîÖÅêÑÀིѪ\96Æ\9c\83º\90z¶\8avµ\87uÀ\97\7fÌ\90ÜèßȲÝÆ®ÝÄ°Þ°ÜÀ«ÚÁ©Ø¾¦Ô¸\9eѶ£Ò·£Ì¯\98˯\8fÊ°\93˲\95̲\94Ŭ\8dɯ\90ͱ\9cж¡Ì°\93É®\93Ç®\8fʱ\93̳\97ε\97Ï·\9aѹ¢Ò¼¤Ó¼¢Õ¿§Ô½¢ÔÀ£Ø©ÝÇÝɬÞËßͱÝÌ°âиåÓ·äÔ¾ãÓ½áиÝÌ°ÜʪÚɯÜɳÞ˱ãÏ´äеçÔ¼åÖ½èÙÀäÖ¼èÙ¾äÕ»äÔµäÓ³äÖ¶ãÓ³áÒ°åÖ³äÕ°åѲãÒ¯âÒ°âÒ±àЮæÕ·èØ»éÙ¼ìÞÃëÝÃëÝ¿êÚ¼ëÜ¿éÙ¼éÚºéÚ»èÙ»éÚ¿è×½èÙ½îâÊíêÔêîÞèîáèîâèîâéîáèîâçîãæîååíæäíçäìèäìéäìêäìèåîåèîÚìèÌîâÃîݽìØ»ì׸ëÕ¶ëÕ·ìÖ¸ìغîÛ¾îÞÃíæËíëÑëîÝéîâêîàèîãèîâèîâéîßëíÛìêÒíéÎíåÌîãÍîáÉîàÈîâÈîäËîãÈíåÌíèÏìëÓêîÜéîâæíéæíéäìëäëìäêìãéíäéíãéîãêîãéîãéîäêíãêîäëíãêîãêîãéîãèîãèîãèîãéîãèîãéîãèîãèîãèîãèîäéîãèîãéîåêîäêîåêîåëíæìíçìíçííèíìêîêêîéêîêêîéëîçêîéëîèëîçìîæêîéëîèêîééîêêîééîëéíëéíëèíìéíëéíëêíêéîêêîéëîèìîæW+\1fk8(d.\eh)\1ad#\ fq&\11|+\17\87'\15\8b#\11\95%\12¢*\1a¸.\1dÎ3(ëG@ä`Uã\81xãÝÆãâçãããããããääå®\9dî´µîØÉîÛÌîØËîÙÍîÛÍîÚÌîÛÍîÚÌîÚËîÚÈîÚÉîÜÌîÛÊîÚÊîÛËîÜÊîÞÌîÚÉîÙÈîÛÉíØÇîÙÈíÙÅëÓÄÛ¼ª¹\90\82\9fxd\9bt]\93iQ\95mW\9cp[³\8fzǬ\8fàˬèÒ¼èÓ½éÒÀéÔ¾æлæкã͵ãͶâ̵áË´â̳áÇ®âË´àÉ°àʳà˲ßɳÜÇ°á˸ßÉ´ßɳá˵ãͶá̵ãζäÏ·æÑ»åкæÒ¼åÔ¾æÖÀæÕÀè×ÁéØÂèØÃèØÂêØÃëÛÅéÙÂëÛÃëÛÆêÚÃéØÃè×ÀçÖ¿æÕ¾êÙÂè×ÀêÙÃêÛÄìÛÆëÛÅëÝÇêÜÅèÚÂêÚÃéØ¿ìÜÁèÙ½ëÝÀêܾéÙ»èظãÔ´ÝάÖƤϿ\9bÑÀ\9cØÆ\9fÛ˧âЪæÕ´éÛÁéÚ½éÙ¾éÙÀêÛ½êÙÀèؼéÙ¾éØ¿éÙ¾èÚ¿íàÅîéÓêîÞæîáæîåçîãèîâçîäæîååîæåíçäíéäíêãëëãìëãìëãìëäìéäîäëì×îèÊîáÄîÝ¿îÝÂîÛ¿îÝÃîÝÅîÝÅíÜÄîßÇîãÎíéÔìì×ëîÜèîãèîâèîãèîâèîâéîßéîÚêîØìêÒîèËîåÈîãÈîâÇîáÅîáÄîâÊîãÉîæÊîêÓëíÜéîÝèîäæîçäìëãëíãêíãêíãêîãéîãèîãèîãèîãéîãéîãéîãèîãèîäéîãéîãèîãèîãéîäéîäèîãèîãéîãéîäêîäêîäêîåëîæìíåëîåëíæìîçìíèííèíìéíéêîéêîêëîèëîèìîçëîèìîæêîéëîèêîêéíêêîéêîêêîééíêêîêéîêêîéëîçëîçëîèìîæíîã^0!g3"j2 f&\15e\1f\ fs(\19{*\17\8c#\15\90"\13\94"\13¡&\15´(\13Î3#Ù5!êD2èI;ã\93ZãçÉããããããããã屳ﱯîØÆîÙÈîÙÊîÙÉîÚÊîÙÈîÙÈîØÈîÛÊîÚÊîÚÈîÙÈîÙÇîØÇîÚÈîÚÈîØÆîÙÈîÙÇíØÆîØÇíÓÁìÓÀÞÀ«»\95}\96kR\95hV\92cR\95kW\93hR\97kW\9bzc¾£\8aÙÅ«éÓ¼êÕÁë×ÂëÖÁêÓÀêÓÁéѾéѾèÒ¾éÒ¿çлèÒ½çÓ¾êÕÁéÕÁêÕÁéÕÀêÖÁéÕÁêÖÂéÖÁéÕÁêÖÂêÖÂêÙÃéÖÂêØÄè×Âé×ÁéØÄêÙÄêÙÃéØÂêÚÄêÚÃêÚÅéÙÄëÛÆëÛÅìÝÇëÜÆëÜÇêÚÄéÙÃé×ÃêÚÄêÚÄëÛÆëÜÇíÞÉìÜÅìÞÈíßÈëÜÅêÛÄìÜÅéÜÂêܾêÛ½ëÝÄéÚ¾çØ»áѰо\9b½©\8d©\96w\9d\8co¢\8fl¦\94mµ£~ɸ\8dÖÄ\9fÜͱæÙ¼êÙ¿êÚ¾êܾéÚ¼êÛ½éØÀéؽêÙ¿è×½ìÞÄîçÐêîßçîäæîæèîãçîâçîãæîååíæäîèäíéäìêãìëãìêãìëãììãìëäìêäîèçíàêíÙìéÐìêÐìéÍíéÐìêÔìêÓîçÏîâÉîäËîâÈîèÏìëÕëîÞëîÝêíÞçîäçîäçîàéîáêîÞìíÛíêÐîçÊîèÊíæÏîåÌîâÆîäËîãÉîãÉîåËíéÑíéÏëíØêíÚèîãçîçæîêäìëåëìäéíãéîãéîãçîãèîãçîãèîãèîãèîãéîãèîãèîãéîãèîãèîãéîãéîäéîäêîãéîäêîåëîåêîåëîåëíåëîæìîæëíçìíçííéíééíëéíëêîèêîéêîèëîçëîéëîçëîçìîçêîéêîêêîééíëéîêêîéêîèëîéëîèëîéìîæìîäìîãc4$i9'r:%m1\1du2 z,\1a\82(\16\88"\12\8d!\12\9b!\18¡&\18·/\13È/\18Û8(ä8\1eé?(ãk>ãÕ¯ããäããããçêå\9d\8cë©\95îÔÃîÙÉîÖÆî×ÈîÚÉîÙÈíÕÅîØÈîØÉî×ÇîÖÅî×Æî×Æî×Æî×ÆîØÇîØÆîÖÅîÙÇîÖÄíÕÃíÖÄêϻҲ\96£zc\90cL\90cM\92fO\93fO\8edI\92kT\97za»¡\89ÔÀ¨éÓºëÕ¿ë×ÁêÕ½ëÕ¿êÔ¾éÒ½èÒ¾æÒ»çÓ½èÔ¾éÕ¾êÖÁìÙÄìÙÅìØÄë×Âê×ÃíÙÅêÖÂéÕÂë×ÃëÖÂë×ÃìØÄìÚÆëÙÄëÙÄìÚÅêÚÄëÚÅêÙÃêÜÇêÛÅëÚÆëÛÆêÚÅëÛÆìÜÆìÝÇìÝÇëÜÆëÛÄêÚÅëÜÆêÚÅìÝÈìÞÈìÝÈìßÉìßÉíÞÉìÝÇìÝÆëÝÆëÜÄëÜÂéÜÁëÛÃêÙÀëÛÀãӳ͹\93\99r\96\80_\86qGygBvdAr_8\7fmF\94\81U\9asѾ\9fÙË«æÙºéÚ¼êÚ¼éÙ¾êÚ¿êÚ¿éÚÀêÚÁêÙÀìÞÅîæÐêîßçîãæîåçîãçîãçîâçîãæîæåíèåíèäìêäíéãìêäíêãììãëëãìêäìéåíçåíååîãåîáåîáåîãäîäæîáèîßëíÛíëÖíêÕîçÏîçÎíë×ììÚêîÞêîàèîãèîäçîäéîáèîáéîÞêíÚêíØëìÖëíÖìëÓëìÖììÖîêÎîçÏîæÊîæÌîæËíêÑíìÖëîÛéîâçîçåîéäíêåììäëëäêíãéîãèîãèîãèîãéîãéîãêîãèîãèîãèîãéîãèîäéîãèîãéîäéîäêîãéîãêîåëíåëîåìíåëîåëîæìíçìíçìíéíêéîëéíëêîéëîéìîæëîèëîçëîèêîééîéêîéêîêéíêêîééíêêîèëîèêîèìîçìîæìîäìîäc;,wE0}E%\81?%\87<%\87/\18\86(\15\8b"\12\99&\12£#\ f(\17µ/\18Ã2\e×7"Û4\1cç<,âqMãÂ\7fããêããããíÙç\7f^ß\9f|îÕÁîÔÆîÖÆîÕÈîÔÄîÕÅî×ÅîÖÅíÕÄîØÆî×Çî×ÆîØÆî×ÆîØÆî×ÆîØÇî×Æî×Åî×ÅîÖÅíÔÃè͹Ģ\8a\9amW\8fcK\8fdJ\8dbM\8feR\8ddQ\8fkW\9e\87k½«\8fÞɬêÕ½ëÖ¿ì×ÁêÔ½ìØÃéÒ¾çÒ¼çÒ¼çÒ¼éÔ¾èÔÀìØÄê×Áê×ÂìÙÅëÖÂìÙÅìØÄìÙÅëØÄê×ÃìÙÅìØÄëØÄìÚÆëØÄëÛÆé×ÂëÛÆëÛÆéÙÄêÙÄìÜÇëÜÆëÜÆëÜÆëÜÆìÜÆìÜÆìÞÈìÞÈìÞÈìÞÉëÛÅéÚÄëÝÆìÝÇìÝÈíàÊíÞÉìÞÈìßÊìÝÈëÞÅëßÇëÞÃëÛÃéÛÁêÜ¿ëÝÂèÙ»ÙÆ£¹¦~\8d{W\84pO\85oL~kIua<mY/gT+jT/}jG¦\90mǸ\96Ø˨èÙ¿êÛ¼êÛ½éÚ¼ëܾëÝÀëÜÂíÞÅìÝÄîæÐëîÞèîãèîäçîãèîâèîâèîâæíåçîäæîæåíçåíèæíèåíèåíéãìêãìéãìëäíèäíæäíçäíçåîçåîæåíçæîåçîäéîáéîáëíÜíìÚíê×îêÔíëØííÛìíÚëíÜëíÜëîÝéîàéîßçîàéîÞéîàêîÞéîßèîâèîßèîßìí×ëíÛíìÔîéÎîåÉîäÌîåËîéÑíëÓíìØëîÝéîâéîãèíçåìíåëîäëíäëíãêîãéîãéîãèîãèîãèîãçîãèîãéîãèîãèîãéîãéîäéîäéîäêîãéîäëîäëîäëîåëîåëîåëîæìíçìíèíìèíìéîëêîéêîêêîéëîæëîçëîèêîéêîééíêêîééíêëîèëîèêîèëîçìîæëîçìîåíîãoF-\89ZE\92[A\7f>-\8b?0\890\1e\8d'\13\97&\13\9f(\17¬,\19»1\1fº+\1aÂ+\11Ñ4\1cÕ5\19êC.ã[Cã¼\86ãäåããããÚ¹éiMà\99yîÔÀîÕÆîÖÅîÕËîÕÄíÓÆîÖÈí×ÊîÖÊî×ÉîØÊîØÊîÖÄîÙÊîÙÇîØÇîØÇî×Åî×ÅîÕÄîØÇíÔÂãÄ°º\91~\90dQ\8dcL\89_D\84]F\8beR\8fhS\8ft[«\92tλ\9cæѵì׿ìØÄíÚÅìØÄì×ÃêÖÀéÕÁêÕ¿çÓ½èÕÀëØÄì×ÄìÙÄìÙÄëØÃìÙÅìÙÃìÙÅìÙÄëØÄëØÄíÚÆíÚÆíÛÇìÚÆëÜÇëÛÆêÙÄëÛÆêÚÅêÚÅìÜÇëÛÆìÝÇìÝÈìÝÇëÜÆëÜÅëÝÆíßÊíáËìÞÇíàÊëÜÇìÜÇëÛÆìÞÈîáÌíáËîàËíáÌìàËìÞÉëÞÈêÝÂêÝÅéÛÀêÜÀèÛÀëÞÃèؾØǦ\9dv\88uP\81nM\82kL\7flLyd>mX2fS.dQ.dQ1xhG¥\93nϾ\9aâÒ³ëÜ¿ëÞÂëÜÁëÜÁëÝÀíßÅìàÇìàÆîäÍìíÙêîàèîãèîáèîâèîâéîâèîäèîäæîåçîäåíèåíèåíçãíêäíêãìêãìëåíèåíçåíæçîãèîáèîâéîàêîáëîßêîßìîÝìíÜìíÜíìÙîë×îèÓîèÓîèÓîèÓîêÔìíÙììÚêîÞëíÝììÙîçÎîåÉìèËêîÙêîßéîàéîàèîâéîßìíØíëÐîèÊîçÇîåÆîåÇîèÌîèÐîëÑíí×ëîàêîäçîççíêæììäëíäëíãéîãèîãçîãçîãèîãçîãèîãçîãèîãçîãèîãèîãèîãèîäéîãêîäèîãéîäêîåêíåëîäêîæëîåìíçíìèììèíëéîêêîéêíëêîêêîêëîèêîêêîéêîëëîèêîéêîéëîèëîçëîæëîçìîçíîä\8deB\93eJ\99gM\87E8\94F5\8a/\16\92*\17\97(\18¤+\1c¯(\e®,\17¶*\19Å/\19Ê4\1cÔ6\1dêB*äZ;ã¹\87ãèÞããêãÛºçgOÚ\96{ïÔ¾î×ÅîÖÇîÓÉîÕÈîÔÇíÕÇíÕÇîØÌîØÉîÙÊîÙËî×ÈîÙÉî×ÆîÚÉîÙÇîÚÈî×ÅîÖÅîÖÅîÕÀܶ¥\82n\90fN\8aaH\84_E\88cK\86dN\8akQ¢\8ew¬\95àͶëØÅíÚÈíÚÇíÙÆíØÅìÙÄíÙÅêÖÂéÕÁéÔÀëÙÇê×ÃëØÄíÛÆìÚÆíÜÈìÙÅìÚÆíÛÆìÚÆíÚÇíÛÇíÛÇìÚÆíÛÇíÞÉëÜÇëÛÆëÛÇêÚÄìÝÇëÛÆêÛÅìÞÈìÝÈìÝÇìÜÇëÜÆìÝÈìÝÈíÞÉíÞÊíàËìÞÉìÝÈìÞÉìÝÈíßÉîáÌîãÍîâÍíáÌíáÌíáÌìÞÈêÝÄìßÆéÜÂëÞÆêÝÃéÛÂèؾÚʪ¶§\88\91\80]}gHyfCub:ta<jX3fR1iV3dS1hV9\80oS®\9b|×Ǧå×»êÛÀìÞÁëÝÃìàÅíßÈíáÉíãËîåÎíëÖëîßéîáéîáéîáêîßéîáêîàéîâèîãçîææîèåîèåíèäíêäíéäíèäíèæîåçîãéîáêîßêíßëîÜìîÝíìÙíìÚííÚíë×íë×íê×îêÖíê×îêÕîéÔîêÖîêÖíìÛìíÜéîßêîßëîÝíì×íêÏîçÊîâÇíèÌìíÛéîàèîâéîàèîâèîàêîÚìîÔîêÏîæÇîåÆîâÅîåÉîäÈîèÍîêÓììÖëîÛêîáéîäçíæçíèæìêåëìãêíäêíãéîãéîãçîãèîãéîãçîãèîãèîãéîãçîãçíãçîãçîãèîãèîãéîãéîäêîäêîåëîæëîçìíæìíçìíéîëéíêêîêêîéêîééíëêîéêîéëîèêîéêîêêîéëîçëîçìîèìîæìîç\92mP\97nL\9erP\90L0\9aF-\946\e\99.\1a¡)\18¢(\13«)\15²2\1f´2\1f·-\e¿0\1eÒ7\1cä:"åU;ã©zãëÔããèãÞÏçe\Ý\93|îÕ¼îÛÅîÙÇîØÆî×Æî×ÉîÖÈîØÊîÙÊîÙÊîØÊîÚËîÙÈîØÇîÛÉîØÆîÛÊîÙÇîÙÇî×Äî×ÇëѼӮ\98\9bu`\8ccK\89bI\80]?\85fL\88pY\93|g±\9b\7fØÇê×ÀíÜËîÛÉîÝÊîÛÉíÛÈìÙÅêÖÂêÖÂéÕÁë×Ãê×ÃëÙÅíÛÇíÛÇíÜÈîÜÈíÛÈìÛÇíÛÇìÛÇìÛÇíÛÇíÝÉíÜÈîÝÉíÝÈíÞÈìÝÈíßÉìÝÈëÛÇëÝÈìÛÉìÝÇìÜÉíßÊìÞÉìÞÈíßÊíÞÉìÞÉíßÌìÞÊìÜÇíÞÈìÝÇëÛÆîâÍíáÌîãÎíáÌîãÍíáÌíàËìàÍëÝÅêÝÅêÜÄêÝÅêÝÅéÜÃêÜÄãѹ˻\9f¯\99\81\93\80`yg@q`;s`9n[8iW4jW7hU5kX8n];\8b{Yº¬\84ÜÌ®èغêÛÁêÜÃëÞÃíÞÇíâÌîãÌîäÍîêÖëíÛëîßêîàêîßéîâêîßéîàèîâèîãçîæåîèåíçåíèäíêåíèæîæçîåêîàêîàêîÞìíÛìíÛíë×ííÛíëØíìÙîë×îêÕîêÖîéÔíéÕîêÕîêÖîêÖìíÝéîâåíëäìëäëëãëìäìêäíêåíçæíéèîåëîÜìîÜêíÝëîÞèîßéîÞéîÝëîØëîÖîìÒîëÊîçÈîãÄîâÂíݼíܲìÝ°îãÂíèÌîëÕíì×ìíØëîßêîãèíäçíèåìêåëëäéîãéîãèîãèîãçîãèîãçîãéîãèîãçîãçîãæíãçîãæîãæíãèîãèîãèîäêîåëîäêîåëîæìíçìíèíëéíëéîêéíëéîêéîëéîêéíëëîèêîéëîéìîèëîçëîèëîæêîé©\8ap«\82f¢u\\9d`E\92C%\9cC'\9e5"¦0\e¦0\19«-\1a´4!².\eº2\1d½0\1eÊ5\1açB%éD)ãsOãÃ\8bãååãæÒéjLÙ\93pîßÄêæÒêãÍíàËîÞÍîÜËîÙÊîÚËîÚËîØÊîÙÊîØÊîÜÍîÙËîÚÉîÜËîÙÈîÛÊîØÇîÙÈîÖÅèË»À\9f\89\90nS\8bfM\8aaG\84bC\8coX\8dw`£\90yȲ\9cäÒ¿êÙÄíÚÆíÜÊîÝÉíÜÈíÜÉíÚÆëÖÂëÖÃéÖÁéÕÁëØÄìÙÅîÜÈíÝÉíÜÈíÜÈîÞÊíÜÈíÝÉîÝÈîÜÈíÝÉíÝÉîÝÉíÜÇîàËìÝÈìÝÇíàÊìÝÊìÝÈìÝÉíßÍìÞËíÞËíàËîáËíßÊìÞÈíßÊíàËîàËíàËíßÊíÞÉíÞÈìÞÉìÞÉîâÌîãÍîáÌíáÍëßÊíàÊìÞÉìßÉëÝÇëÝÅëÞÅëÞÆìàÈìßÆéÙÂßʹл\9e´¢\86¡\89j\8evV\81nHwd=s^;o]6o\;iU-hZ-k\;\99\88`Ë´\86äÍ\9bê×¹ëÛÁëÝÄìÝÇìÞÈíàÊíãËîæÑììÙëíàëîàëîÝêîàêîàêîßèîáèîãæîèåîèæíççîæçîåéîäêîáëîßëîßìíÜíìÚíë×ííÚíìØíëØîë×îë×íëÖíì×îëØíìØîêÕîë×îêÖîìØìíÜèîèåëíãëíäëìäëîãìëäìêåíéåíéæíæèíäèîâëîÝíìÖîéÑìåÃìå·ëâ¶ìä®íã¯ìØ\9eîÚ\9díÓ\95ìÐ\91ìÐ\93ä½l߸`íÐ\96íØ«îݹîâÄíçÌíéÎíëÔëíÛëîàéîèèíéæíëäëîäêíãéîãêîãêîãéîãéîãèîãèîãèîãçîãèîãæîãæîãçîãçîãèîãèîãèîãéîäéîåëîæìíçìíçííèììçìíèíìèíëéîëêîéêîêêîêëîéëîêêîêëîêëîéêíìÙÀ¥Ä¡\8a¶\8do¡hJ\94L3\9fN:¦>*¤5 ¨4\1e®2\1e®2\1e´2\1d¸4"¼2\1dÅ3\eä>(íA'â^AãÇ\97ãç³ã߶êdEØ\92néèÒäîáæíßçëÜéèÛëå×ìäÒìßÔîÞÏîÝÎîÚÌíÚËîÚÉîÚËîÜÊîÜÊîÛÉîÚÈîØÇîØÇíÔÆáÀ³\8bv\8dkR\8alQ\87fM\89kP\8etV\9d\86s·£\8dÜɱèÖÁíÙÃîÛÉíÜÈîÝÈîÜÈíÚÇíÛÅìØÅêÖÁê×Ãë×ÂìÙÅìÛÇíÜÈíÝÉîÞÊîÞÉîÞÊîßËîßÊíÜÈíÜÈîÞÊíÝÉîÞÊîÝÉíÝÈîàÌíàËîßÊíßÉíßÊìÝÈíÞÉíßÉíàËíàËíàËîâÌîàËîâÍíâÍîâÍîâÍìßÊìÞÉìÞÉëÝÈíàËîâÍîäÏîãÎíáÌìàËìÞÉëÞÈéÛÄêÛÄêÝÅëÞÆìßÇìßÇëÞÆëÝÅèÚÂáÒ¹ÕŨ̴\99·¤\84«\96|\99\82_\8cxX\82nG\7fjGxf<n`2nZ7\81mCÃ\9abç¯lêÃ\88çаëÛÁìÝÄëÝÆíáËíâÌíäÐíêÕìíÝêîÞêîáéîâéîâèîãçîåèîäèîæèîåêîáêîàëîßìîÝìíÝííÛíìÙííÚíìÚíëØíìÙíìÙíëØîë×íëØîìØîë×íëØíìØíëÚîëÙíìÛííÝëîàèîççíêæîæåíêæîêéîäéîâêîâìíÜíì×îëÕíéÑîéÑîåÈîà¸ëÑ\9déÂyëÂqìÇwíÆtë½aé·WäLà¥>ߥDÚ\9d7Ö\9d5Ý«Nã´\ç¿séÄ\84éÐ\9bëÒ\9eìÖ¦îÜ´îåÊíê×ììÙêíâêîäéîéèíëçíìæííåìíäëíäëîäêîãêîãéîãéîãèîãæîãçîãçîãçîãçîãçîãçîãéîäéîäëîäêîåëîåëîæìíæìíçìíèíìèíìéíëéíëêîêêîéëîèëîèéîìèìíìÞÉæγʩ\8e£xV\98d@\9cU6\9f>%\9e8%\9d1\17¬5\1e±5"´4"°0\1a¹4"¿8 Ò=,æD/éJ/ã\98oã\9cjã\8bià\GÏ\95pèéÔãíìãîéãîèãîèãîçæíâçìàééÚêèÚìäÖíäÕíáÐíßÐîÛÊíàÎîÛÊîÚÊîÛÎîØÈíÑÁÓ³\9f\9cy\\93rV\8fpV\8bnV\90s[\96z`ª\96\81н§éÕÂëØÈíÛÈîÝËîÝËîßÊîßÌîÜÉíÚÇìÙÅëØÅéØÃèÖÄé×ÆêÚÇîÝÉîÞÉîÞÊîßÌîáÍîßËíÝÉîÞËîÞÍíÝËîÝÌîÞÍíßÎîáÎíßÉíßÊíàËíßÊîáËíÞÉíàËíàÌíÞÍîâÌíâÌîáÍíáÌíáÌîãÍîãÎîâÍîáÍìÞËëÜÇìßÊîáÌíâÏîäÒíâÍíãÏíâÍìßÊëÞÇêÝÄéÛÄéÛÂéÜÃëÝÅëÞÆíàÈìàÈìÝÇéÛÃäÕ»âÒ¹ÖĦϺ¢Â©\8c²\9d\83§\93u\95\83^\8dzN\89wC\82qD\98|NÑ\92Mé\9c>å Gã²fêÍ\94ëܽèÜÅìßÈìßÊíáÍîæÑíìÛëîàèîâçîèæîæçîåèîãéîáêîßìíÜìîÝìíÜííÛìíÜíìÚíìÚíìÙíìÚîëØííÚíëØíìÙîìÙííÚîëÙíìÙíìØîìÚíìÙíìÛíìÙííÚíìÙííÜëîàëîÝêîáìîÜííÛîìØíèÑíãÊëáÄêÜÁêܽéÛ¹éÚ¸èسéÐ\9dêÉ\86êÅ~éÂwìÆuíÈuè»\åNß\9f;Þ\992Þ\9f7Ý\9a5Ø\984Ò\8f%Ñ\91(Ô\9b4Ø¢DÚ¨PÛ©QÝ®[Ü\æºpêÈ\86ìÐ\9eîÛ±íçÇîëÔííÛìíßëîåëîâêîèèíèèîêçììæìíäëîäêíãêîãèîãèîãçîãçîãçîãèîãèîãèîãéîãêîäêîåëîæëíçìíæìíçìíèííèíìéííéíìéíìêîëéííçìîçìîëêÛîãÍÜæº\92wªwU\87B%\99;*\9b='\9f7\1f¦6\1d¬4\1e¬3\eª0\18¶5\1e´1\14¸6\eÀ;!äA/ãlVãoMäqVÞ]GÌ\8eoêçÔãîëãíëãíëãîëãííãîëãîçãîçãîææìßæíßçëÛèéÚëåÖìåÔìäÓíãÑíàÎíÞÍêл¼\9b\86\99va\9bw^\94sX\91tY\93vZ¢\8an»§\8dÝͱêØÅíÞÍîÝÎîãÒîæÕíæÓíæÖîäÓîàÏíÝÌëÚÉêÙÈêÙÇìÙÈíÚÉìÛÇîÞËîÞÊîáÌîßÌîßÍîßÎîßÍîÞÌîÝÊîßÌîßÌîßËîáÍíßÊíàËîâÍíàËíàÍîáËíâÌíáÌîâÍîäÐîáÌîãÍîáÌîäÏîäÏîäÏîåÏîãÎíâÌëÝÇìßÉíàËîäÎîçÑîçÒîæÓîçÓíäÏíâÌíáÊëÝÈëÝÆêÝÆêÜÅëÞÇëÞÇìßÇëÞÅìßÇëÞÇìÜÆèØÁäÕ½ÝɯÙǯ̺ Ȳ\97¾§\81®\9cm¥\8a[Ä\90Xä\95Kå\948à\8c+Õ\86'ä®ZëÓ§çÜÆìßÌíßÊíàÌíãÏíê×êîãæîææíæçîäèîäêîàëîÝìíÝííÜìíÛìíÛìíÝììÛìíÛííÚíìÚíìÚííÜííÚíìÙííÚííÚíìÙíë×íìÙíìÙííÚíìÙíìØîë×íëØíìÙîë×íë×îëÖîëÕîèÐíãÇçÜÁãÓ»àÎÛÊ¥×ǤÜ˧äÒ¨æÕ©æÑ£äÅ\8dä¼tçÁ{çÁxèÀqíÉ|êÄkçQß\9f@ä«KáªGÜ\9c6Ù\94-Õ\8c\1dÊ\87\16Ð\8f#Ó\95-Ñ\95/×\9a6Ö\9a2Õ\9b5Ó\98)Ð\92'Ù\9d8Þ©YáµqéÉ\87íÙ§îâ¾íçÔîèÒíìÛíîàìíäëîäêîèéîêèíëçìíæìíäëîãêîãêîäéîãèîãèîãçîãèîäéîãêîåëíåëîæëîæëîåëîçìîçííçìîçìîèíîçííçìîæìíäêîêìÞìêÔâ˲ȥ\8f©\80a\80I*\876$\9eB0\927!\9b8\1d¥5!¤5\1a\9e3\17©1\1a¯6 ©5\19´9\1cÕ='íVFêZFèeSÝ^HÌ\92oêçÎãíìãíëãíìãíëãíìãîëãíëãîêãîêãîéãîèãîäãîçãîääîâåíâçëÜèêÛìäÔäƵ©\87u\9e{e\9e{e\97y^\91uZ\98~g\97\86ÖªìáÌíåÓîç×ìëÙéíâèíáçîãéíâìëÛíèÔîäÐîáÏìÞËìÜÊìÛÈíÜÈîßËíÞÊîàÍîàÎîáÐîßÎîßÎîáÏîßÎíÞÍîáÎíßËîáÎîáÌíáÌîâÌíàËîáÌíáËîàÊîáÌîäÏîâÒîâÑîãÓîâÐîæÕîäÒîçÓîæÑîèÓîçÓîåÐíâÌíáÉîäÒîæÑíë×ììÝíìÛììÛíìÛîêÕîæÑíâÍíâÌíâËìÞÈíáÉîâÌëàÈîãÌíâÌíáÌíáËìßÉíàÊìàÉêÚÂêÝÉåÖÁâÍ°ÖâÍzà\9eTæ\94FÚ\88/Ï|\17Æs
+Ë\83$߯aèÏ\9açØ·ìÞÆîåÓîæÒîéÕêîäçîåèîäêîàéîàêîßëîßëîßìíÝìíÛìíÜìíÜëîÞìîÝìíÜìîÝííÛíìÚííÛíìÚíìÙîëØîëØíë×íëØîë×îë×îë×îë×îéÖîèÓîèÐîèÎîçÑîæÐìáÆèÛ»ÔŧÀ´\99º¨\91¶¢\80Á¨\86¯\91Ò½\95àÌ ãÔ¨çÑ\9eåÂ\85ã¹oç¿oâºjâ¸këÈ~íÊuã°Mä¯PèºXå¶Tá¤@Û\90%Ö\8e\1fÎ\89\1fË\84\eË\88\1eÌ\8d#Ñ\91)Ò\93'Ô\95-Ó\93*Ê\89\eÐ\91)×\9b;Õ\9a7Ò\97<Û¤Uâ®iéÅ\8cìÏ\9eíÛ»íàÌîëÙîëÜííáìîÛìîáëîçêîëéíêèíëçíìåêíåëîäêîäêîäéîãéîãéîäëîåëîãéîåëîåêîåêîåëîäëîäêîåëîäëîåëîåëîæìííáÌêëÚèÙÂÑ®\91º\94x\82Z:t< \90?)\8a8 \946\1e\9b7%\985\1c\9d6! 1\1f\9d3\1a 5\e¬3\1cÁ7 ÚI2ëP@îXIãcKÆ\8dhêãÈãíëãíìãîëãíìãíìãîëãíìãíëãíìãíëãíìãíëãîêãîéãíéãîèãîåãîåëåÓ×·¦\9c{j¡~f\9f{b\9b}b\94z]\9d\86lð\99ëÞÉìëÚêîãèîèåíèãîëãîíãíëäîææîåêíÚììÖîèÓîåÏîâÍíàÌíßÊîßÌîáÍîâÍîáÎîãÏîáÐîãÑîâÏîáÏîáÏîäÎîâÍîãÎîâÌíáÌíáÌîäÏîåÑîåÏîåÑîæÒîèÓîêÕíêÚîéÙìëÛìêÚîëÙíëÛëìÛëîßëîáíìÜîéÓîçÏíé×ìíÚèîæçíêéîäëîâëîåìîàíëØîèÖîèÔîçÑîéÔîæÒîèÔîçÔîèÓîêÒîèÒîçÑîæÑîåÎîæÐîçÑíêÕîêØìêÖíáÈäÁ\86â\9eAà\8f.Î{\1f½h\v·a\ 3µd\ 2É\83\1dÛ³]ÝÉ\98çÔ±íßÉíåÕîèØìîâéîæëíÝíéÖíèÖêîÞêîßëîÞëîßëîßìîÞëîÞëîßëîßìîÞìíÝìîÝííÛìíÛììÚíëØíìÙíìÙîëØîëÖîêÖîêÕîéÓîèÑîèÐíåÎîãÊíâÊëÞÇèؽßÏ°Ç´\8e\9e\90rzlOqa:{jE\94}]£\8cc¼¤~н\8eÔÃ\93ÝÁ\8aä½\7fæ¿wã½nߺjÙ±^éÈzëÈxã·Yé½^â¸Yß´Mä²Mߢ;Ý\9f3Û\9a/Ö\91%Ñ\8f"Ê\8b\1cÍ\8e!Ð\90%Ï\8f'Ô\970Ñ\970Ù\9e=Ú\979Ð\88$Æ~\1e½u+Ä}+¿}$Æ\8a6Ì\93GرtïÛªìâÄîèÖîêÓííÛííßìîåëîçêîçéíêéîçæíìéîêçíêçìëæëëæìíåëîæëíäëîäêîãèîãèîãèîãéîäêîäëîåìîçííèíìéîêíåÔëëÛíÝÈáǫȧ\90º\96z~O3\80G-\84H-\887\1e\8d4\1e\8b5\1d\8e3\e\943\e\975\1c¡2 ¶6$Å7 Ì:\1eçL=ïXSÚ_GÅ\8cdéÝÇãîíãíìãíìãííãíìãíìãííãííãíìãííãííãíîãíìãíêãíëãîêãîêãïèìßÊ´\99\85\96ye\9dz_\9aw\\97zb\95\80e§\98\80ÛпìêÙæîçäîêãìíãìíãëîãìîãíìãíìåîåèîßêíÞììÚíìØîëÖîè×îæÕîçÖîæÕîæÕîæÖîè×îè×îåÓîçÔîåÓîçÕîçÓîèÔîèÔîèÓîêÕîèÓíéÕîë×íë×íëØìíÛëíÞêíâêíãêîãéîäéîåéîåèîåèîæèîåêîåëîàííÞîëÙììÝéîäåîéçîéçîèêîæëîãìíÞíìÜíëÚîêÙíëÚîë×ííÙíìÙíìÙííÙíìÙíìÙîëÙíìØíìÙììÙììÚìíÝëîÞëîÜíäÓæ¹\83ß\8d,Û\88$Ãn\ e¹^\ 4U\ 3µb\ 4É{\10Þ\9f<à²`Ú½\82âÉ\9fçÚ¾íâÊíêØíìÜîçÕìÚÇíßÇíìØêîßêîáëîàêîáêîßëíÝêîàëîßêîàëîßìíÝìíÜìíÚíìÚíëØîë×îêÖîèÓîèÒîçÐîæÑîçÐîèÐíãËìßÆè×ÂãÔºÚʳϾ¢¸¤\80\9a\8ajtfGcS1`N)]M&bU,qb5\80n=\94\81L«\95ZͪkåÀ~æÁtã½râ»nݳ_ß»i߸fÒ¥JÜ°QÜ´Vá¹ZåÁ_ãºUä·Oä®DÚ\9e4×\93&Ô\94(Ò\92'Ø\98-Ö\971Ó\972Ý«Låºc×\9eBºn\v¸g\ 6·m\1c¹p\17·q\15µq\15°m\r¯q\1dÇ\91IäÂ\8eêÐ¥îÝ·îåÌíìÕíìÜìíãìîàìîâëîâìîâìîáìîáìîâìîãêíçéîééíëæììäëîäëîäêîãêîæìíèîéêîäëîáìîäíìÞîé×êìÙìêÙíåÒìÚÈÓ¶\99Ò²\95\9bt]yN-\7fI)}>\1e\82:\1a\877\19\8a6\18\8f2\15\947\1c 5\1e©2\1eµ-\17Í9'ìVEíVMÛaKÂ\86céÔÀãîîãíìãîìãíìãíìãíìãìíãíìãííãíìãíëãíìãíëãíëãîëãíëãîëäîäåÒÀ\99\83n\8erY\8doY\8dmR\94zd\99\88oµ¦\95èÝÍêîßåîèãíìãìíãìíãëîãëîãííãíëäîçåîèèîåêîâëíáêîáëíàììÝëíàêîâìíàëîàëíàëíàêîâëíãëíâëìáììàììßëíáêîáëîàëíáêîãéîáéîâèîâèîäæîæçîèåîêåîéåîéæîéçîèæîéæîèèîçèîçëîãìíáîëÚìíàèîæäíëæíëçîèêîæêîæìîâíìÛîëØíìÜííÝííÝííÜìíÞííÝíìÝìîÛìíÝìíÜííÛìíÜëîÞìîÝìîÞêîßëîÝìÔµÖ\97OÓ\82\1eÈw\r½i\ 6°V\ 3ºf\ 4Æz\12Ø\8e%Ü\91)Ü\913Ù¡ZÐ¥j˳\81ØÃ\9dêÚÂîâÇíßÇäÓ¸âαîàÊëîÞéîáéîáëîàìîÝìíÝëîßìîÝêîáêîàìîÝííÝíìÚîì×îèÓîéÒîæÑîãÍíáÅìàÅìßÃëßÁëÝÂãÔ¹Ú̪ÓĤÀ°\8d¶ \86¢\8fl\8f\7fZ\88xW{iD\84rPxfDp]3j_3eV&iW\1eo\&\8bs6Õ®jéÃ\7fãÁrߺgàºgã¾iÛµdÒªYØT߶Wã¾eèÆmçÅkäÁ\ä»UÞ±GݨBÕ\9f3Ò\95'Ð\8c"Ô\8e$Ò\8f&Ò\95.ã½aêËvÚQ¹u\14¹p\b¼y\19À|\e¼u\1c²l\r¯o\f°q\16±r\1e´w&È\93FÜ®gèÊ\90íÚ®îÛ½îäÌíéÓíìÚíîÜíîßíîÞíîÞííÞíîßíîàìîâëîçèíçéîèéîæéíâìíÞíêÛíéÖîæÒîåÐíâÍîãÍîäÎçíÜìæÕîâÏíâÏ஡\86¬\8bv\9brU\81P1|E$\81:!\89;#\865\1c\8d3\1c\8e0\18\9a2\1f\9f2\1a¦*\17Â8'ëSEîXQÔZF¾\7faè϶âîìãíìãíìãíìãíìãìíãíëãíëãííãíìãíìãîëãíëãîëãíëãíêãîêéèÔÓ¸¥\8fwc\8eoV\8cmV\92t]\95{c \8esʺ\9eíæÏçîäãíëãìíãëíãêîãëîãìîãííãíêãíéåîçéîãéîåéîáêîáéîãéîäéîäçîèæîèæîéæîèçîèæîèçîçæîèæîêæîêæîéæîèæîéåîèçîçæîææîçæîçåîçæîçåíèåíêåîéäíëäîëåíêåîéæîèçîèçîéçîçêîäìíÞìíÞìîßçîëäíëåíêçîééîåéîåëíáìíÝíìÛìíÝîìÙìëÜííÞííÛíìÚìíÛìíÝëîÞìíÜìîÝìíÜëîÝëíßëîßéîßíê×à¶\8fËy6Ëz\ eÉw\fÀn\ 5Åt
+Í|\15×\8f*Þ\927Ö\85#Õz"Íz)Ä\808¯{7£\83Fº§päÓ³íÜÍìÜÅãиëÛÅíëÖéîßëîàëîÞìîÝìíÜìíÜëîßëîÞêîáëîÞíæÐíæÍîæÏìßÇíâÉêÞÄãÔ¶çÚ¹Þϲ×ȤÜΫ×ɦ˺\9f»«\8d\9bz \8bg\9a\81b\96\81\\92\80\\90\81]\8f|S\91\7fZ\91\80Y\92\7fV\89{R\8buJ\96|H¥\81B·\92MäºoçÂvÞ¸nÞ¶gÜ·cߺfߺhز]ݶ^á·Zá¾däÂjß»bÛ¶SÞ´QÛ±NÜGÖ£;Ò\9d9Ð\973È\8a"Ò\8d'Ñ\92,äÁeãÃjÖ¨GÀ\83"Æ\85$Ê\902Æ\87&ºu\19´k\ e¨f\ 4¤f\a¤g\ 5©m
+°t\18¹}\1fÉ\93:Ú¨SÚ«Zá¶yçÅ\8díÖ¥íâÅîéÕîìÙîíÜîíÛíîßìîÞìîßìîáìíÞîíÛîéÔîæÏíåÍîáÌíàËíßÉîãÌîáËîãÌîâÌéêØìçÔîÞËîÞÌëϹѰ\8d¹\9c\80\9buX\88[:~L.y7"~3\19\835\e\831\1c\82/\13\883\e\973\1a§-\16¶/\19áK=îUQÚ\KµwUãʱãïëãíëãíìãíìãíìãíìãíìãíìãíìãíìãíëãíëãíìãíëãîëãîëãîáêÒ¹µ\92|£|i¥yd¦zf¢{g\9c}h¨\91xßгìíÛæíèãììãìíãëîãëîãëîãìîãììãíìäîèãíèäîçèîæéîáéîâéîäèîäçîåæîéåîêäíëåîêäíëåîêäíêäîëäíëåíëäíëäîëäíëåîêåíêåîèåíêåîéäîêåîêåîéåíéäíëåîêãíìåîëæîéäíêåíëåíëèîçéîäëîâìíàëîÞçîèäìëäíëæîêæîéèîèéîãëîáìîßìíßëîáìîßìíÝíìÚííÛíìÛìîÜìíÜìíÛìíÛííÛìíÝìîÝëíÞëîàíâÈÎ\94]Åq$Í\84\17Ð\80\11Éz\ eÊy\12Èv\ fÎ~\19Êy\16Ër\11Ìv\1dÀj\18¼e\eºn+¯v7\94q.®\99`áʳîßÎíÞÊìÝÊîêÖëíÛìíÜíìÚîì×îíØíìØìíÚëîÝëîÝíí×áÕ¸äÙ»ìßÃÞЯå׳áѯÓÄ¢ßÍ«Ç·\8e¼«\87³\92¹¨\86¨\95q\9c\87^\9c\87_\9f\87e\9c\89d\9b\86^\9c\87^\9d\8cl£\92r¨\9a{\9e{\9ey¼ª\89¸§zÁ¡gܪdêÀsëÅuçÂrÞ¸jÜ·fÞ¹fݸgß¼há½jܶ]Þ¹\á¿iß½cׯSܵYá¼`ß¹]ÞµTשFÕ¨DÒ¡>Ä\8f/Ô AÙ¨Gà¸^ײTСCÆ\937Å\94>Ï GÎ\9cBÃ\87#µo\10¨c\ 4¥g\a¡c\ 3¢h\ 3ªo\ f©n\v±{\13¿\87%Í\93:Ì\93CÌ\977Ô£Há¹oëÕ§îéÑíìÞìîâëîâíîßìíâîëØîèÔíåÑíàÌîáÌíßÊíàÍîâÏîâÍîåÐîèÒîèÓîéÒêêÖëçÖîßÍîÙÁíÔµáÁ ̨\8d\92kI\8f`?\80U4r= }<#|7\19}5\19\81.\11}+\11\97/\1a¡%\10²4\1cÚF<íNHÚWL¶rTãĨãîèãíìãíëãííãíìãìíãíìãìíãíìãíëãíìãîëãíêãîëãîêãîéîàÌѨ\98¹\88r¶\80l·\82nº\82n®\80i\9a~d°\9b\82éÛÄéîáåíæãìêãëîãëîãëîãëîãìîãëîãìíãíëãìêãíéåîçèîåéîãèîåéîäèîåæîéæîéæîéäíëåíêäíìäíëäíëäíëäíìäíëäíëäíëäíëåîêäíêäíéäíêäíëäíêäìêäíìãìíãìíãëíãìíãíìãìíãìíäììäíìçîçéîæëîáëíáçîéãìîäëìäëíåíìäíìæíêéîåéîäêîâéîåëîáëîßìîÜëíÝíìÙííÙííÙìîÛìíÛëíÝìîÜìîÜëîÞëîÞíÛ½Ñ\97NÐ\8b,Ó\90'Ë\7f\11År\aÂp\ 6Àj\a¾k\f¼h Ãi\fÂi\11±^\10µ^\ e»e\eÄu+½x.\9au1´\9eeæÕµîåÑíé×íëÕíìØíìÖîçÒîèÒîçÍîéÒíìÖíîÛìíØîéÓÍÀ¡ÙÇ©æÓ±ÑÁ\98×Á\9bÒ¼\95¸©\80͹\96³\9f{£\93l¤\94m\9b\8ce\9c\8ag\9b\89a¡\8ad \8cj¤\92m¦\94n¬\9bu¸¨\8aÁ°\92̼¤Ë¿¤ÖÇ©ÖÇ¥ÙË à¼~è¼nëÄuëÆxâ»hÞ¹iÞ¸fز^Û¸dâÁnß½hݹ`ß¾gß¿iÙ³VÖ¬Qܶ\ß¿dÛµ[Ñ¥AÑ¥@ϧEÒ¥HÓ¥FàµYã¸bâ¾iÔ®YѦOÎ\9c?É\97AÏ¡IÖ§NÄ\89&²r\ e¤_\ 2\9f_\ 3\9e`\ 3¢d\ 3¥j\ 6«r\11t\10¶\7f\17Á\89.À\898¿\88(Â\89\1eÉ\955Ô£RäÅ\8cíìÖëîäíîßîë×îç×îâÌìàÉìßÇìÞÇíàÉîáËíãÌîåÏîæÐîèÓîåÏîæÑìáÌéêÙéèØìäÓîÖ½íÓ¹éʬ߽ ¢|]\97lO\8ec<yH.}E"|@\e}9\1d{3\16\80-\ e\94.\12¢*\15¬0\1eË=/èNFà_U¾rZâ¿\9bãîåãìíãìîãííãìíãííãííãííãíìãìíãíìãíìãíìãíìãîëèêÚäïÁ\8dy¹\82o¼\82n»\82lº\82pª\7ff\9a}^Ʊ\96ìåÔèîêäíéãìëãìîãëîãêîãëîãéîãêîãëîãëíãìíãììãíéåíçæîèçîåçîææîååîéäíëäîêäíëåíêäíëäíëãììãíìãìíãíìãììäíìäíìãìíãíìãìëãìëãëìãëìãìíãìîãìíãêîãêîãéîãêîãëîãëîãëîãìíäììèîçéîäèîçåìíãêîãêîãêíäëíãìíåíëçíéèîäèîåéîäèîäêîáêîàìîÝììÚíì×ííÙìîÚííÚìîÛìîÜëíÜëîÝëîÚíܸÑ\99?Ñ\92+Ô\982Í\8d(Êw\12Âo ¾i\ 5¸d\ 6¹e\b¼b\a¸a\b³]\r¬Y\a^\f³f\12Ào\1fºp-v+Õ²qëßÄìíÜêíÞììÚîæÏìÞÂìÝÄêÚÁíàÄíãÍîçÐíäÃâÖ¶¬\9fzʶ\96Í´\8eª\97q³ }\9d\8ff\98\88_ \8ba\92\7fP\9b\8a_\9f\8ca \8eh£\91k£\8fk°\9bx®\9dxº§\83ų\8fʽ\9eÔɦÞÏ®ßÔ»èÛÂçÚÁåÙÁãÕ²äÁ\87æ½pëÄwèÄwݺeà¾lá¼jÞ¸dܸcÛ¸dصVÝ·YÞ²WÖ¥HÍ\972Ï\967À\84 É\975Í\9eFϤFÖ¯MѨJÕ¬LÜ´VÖ«LÖ¬UÞ»lÙµeÖWÏ\9fBÇ\96:Ï¢KÑ£MÁ\86"³o\f«d\ 4 b\ 3 b\ 3¡f\ 3 e\ 3£g\ 5«q\v¬w\rº\83"¹\83\1f»\83\1e»\85\1e¿\8c&Æ\90+Ë\97=áÀ\86ïåÂíæÌîãÉëÞÆíßÈëÜÃíßÆîâÊíâÍîäÌîäÌîäÍíàÇëÜÅãÑ»ÙʬÚÅ£çëÝæìÞëæÕîØÂîÖÁìеæĽ\93y xU\95mJ\89ZB\86R3\7fD\1e\83@$~8\e\84/\11\983\1c¥2\1c©0\1eÅ>-ßM@æe[Í{gâ»\9eäîâãëíãëîãëíãëîãëîãìîãëîãìîãìîãìîãìíãìíãííãîèëÚÅÇ\9c\85¸\80i¸\81n¶\7fj¹\81l¹\81u©{e¥\89pÖƱìëÜæíìãíêãëíãëîãëîãêîãéîãéîãêîãéîãêîãéîãêîãëíäíêäíéäíéåîçæîçåîçäíêäíêãíëãììãììãëîãìíãìíãëîãëîãëîãëîäìíãëîãëîãëíãëîãëîãêîãëîãêîãêîãéîãéîãéîãéîãêîãêîãéîãêîãìíåíééîæèîèãëîãéîãéîãéîãëîäììäìêåíéæîæçíæçîçèîçêîãëîßêîÝííÙíìØîìÖííÙííØííØìíÛìîÜëíÛëîÝíߺףT×\9d>Û¥DØ¢CÔ\969Ï\89(Ào\ 6¼h
+Ái\r½h\f»h\10®`\ 6±` ©\\a¯`\f³c\13¼j Êy,Ë\8d>äÅ\8eîåÉéîáììÞíâÉãÓ´ØÉ¢ÔÆ¥ØÄ ÛɪÛ˪տ\9a®\9dw\8c|N¡\8bb\97\85]\8azQ\97\83W\92\7fS\91\7fV\86uG\8f~O \8ee¥\94h°\9fw´¢{»ª\84Ŷ\92о\97ÔÆ¢ÝÍ°ãÖ½åÛÁæÝÂèÝÄçÝÄèÞÄçÜÄàÒ°âÀ\86æ¼oä½là¹gÜ·^àÀlà½hÞ¼dâ¼dä¼`ܵZÜ°VܧEÔ\998É\88&Ä|\16¹p\a³v\ f³z\18Ð\9eAÖ«JÕUß¾fâÂkܶ^Õ±_Û¸gÙ¶eË£KÈ\99?É\9aBѤOÐ KÅ\8c/¶u\12¨f\ 3¢e\ 3 d\ 3¡g\ 4¢h\ 3¢j\ 5¢m\ 4¨s\a´\7f\14»\86\1a¸\83\e¹\85\1e¹\86\1fÄ\90,Â\8f,É\96AÙ³xéÔ§ëÝÁëÞÉíàÉíâÉîäÍîäÍîäÎîáËëÝÇåѸÚÆ\9fϸ\93Ç\86ê\80Ç«\81çìÜäíàçìÚíâÎîÚÇìθí϶հ\8e\9bqN\9euX\8da?\88\9\83N1\84F+\87?"\8b:\1d\979!\9f4\1d¢3\1c¸@/×XKäibÔ\80nß»¢äîÞãëíãêîãêîãêîãêîãêîãëîãêîãêîãêîãëîãìíãíìèèÙܶ¡¼\85r¹~i¸\81n·\80n·\81m¹\80sª|f°\98\7fçÜÊèíçäìíãëìãêíãéîãéîãéîãçîãèîãçîãçîãèîãèîãêîãêîãëíãëìãìêäìêäíêäíéäìëãìëãëìãêîãëîãêîãêîãêîãëîãêîãêîãëîãêîãëîãëîãêîãëîãêîãëîãêîãêîãêîãéîãéîãéîãéîãêîãéîãéîãéîäìíåíêçîèæíêãëíãèîãèîãéîãêîãëìäëìåíéäíêæîèæíèæíçèîåêîàëíÞìíÜíìÙíìØîì×íìÕíìØííØìíÚìîÜìîÜìâÅÙ¬lÔ\9cDÙ£BÛ§EÛ¨EÓ\961Å|\13Ê}\18Ær\10¸g\b´d\r^\ 5¯_\a´b\10´d\ f¹i\1aÀm#Êw"Í\81"×\9bBèÈ\88îäÇíåÎâӳѿ\9b¼«\86±\9e\7f©\97u©\99s¶¡z¬\95k\8auL\8dwL\91zM\8ezN\92|N\98\82S\95\82P\92\83U\83sA\92\84Nµ§yʺ\8fɺ\94ÖÇ ÝͧâÕ´å׺éÜÀëÞÄêÝÄéßÆèÞÅéßÆéßÆéßÇêàÉãÕ®Þ·oÞ²]â»eÜ´[߸_à¾gß½eß¹^á·Vã°Mß°LáKÞ§BÝ£>Ù\99:Ë\84!¼p\v¶s\ e±r\ e°r\12¸\85%Ç\9dCß¿iäÅuëËxæÄwÕ²bØ·hÄ\99DÂ\90:Ë\9dGÏ£NТMË\93:ºx\1d±o
+£f\ 3¡f\ 3¢g\ 4 f\ 3\9fh\ 4¨t\vx\ e¯{\10·\84\1c³\80\17¸\81\1aº\87!º\86\1f¿\8b&Å\905Å\91AݸzîÛÄîàÌîäÎîäÎîãÌíáÌêÙ½ßÌ°ÖÀ¢Ï²\8dÇ«\83¿¢wĤ}ƨ\7fж\8aäìàäíáäíÞêæÔîÚÉìλîҽ߽§µ\8bu¤}`£xT\9dmC\8eY7\85I)\88I'\8cD \94C\1f\97<\1e\9b7\1dµD0×_ZètfØ\87qÞ¹¡åíäãêîãêîãéîãéîãéîãêîãéîãêîãêîãéîãêîãêîäìãìͽÀ\8d~¿\84s»\82o·\80j¹\82m¸\83o´\80nª\80eÀ¬\94íæÑäíëãêîãéîãéîãçîãçîãèîãçîãèîãèîãèîãçîãèîãèîãéîãêíãêíãëìãìëäíéäìêãììãíìãëíãëíãêîãêîãéîãéîãêîãéîãêîãêîãêîãëîãëîãêîãêîãêîãéîãêîãéîãéîãéîãêîãêîãéîãéîãéîãéîãêîäììäíìçîéçîéãêîãèîãçîãéîãéîãéîãêíäìëäìëäíêãìëåìëæìçèîãëîÞìîÛíìÙíì×îëÓîëÓíì×íì×ìíÚìíÙìíÚíêÒÞ»\83Ê\93AÈ\8c,Ë\952Ì\986Ç\88$Ç\88$Í\8b&Ê\82"¼m\r¹f\10¸e\10²d
+±^\ f´f\ f¹l\12Âr\17Ìz!Ìz\eÔ\89&Ù\9fJèÅ\89æ̡м\91¶\9eu\9e\8cd\90xN\86tF\9d\87X£\88Y\94|G\89tD\8ewC\8dxF\94~N\9e\81M¡\86T´\94^¹\9fe¤\91[¹¨xÕÄ\95ßѤâÕ±çܼéÞ¾ìàÂëàÆìßÄëÞÅìàÉéÞÅëàÈìàÊëàÈèÜÆèÝÇÝÉ\9bÓ¦UÙYàºcà»aà»bà»aá¼]ç¿`ã¸Tå°Nߦ@ߥ;â§>Ý¢;Û 9Ò\931¿s\ e·m\b³o\f²q\ e¬o\ f¸\86(áÁkêÍ}éÊyåÃp׳]Õ³eÉ¡N¿\90?Ç\9cMФSÏ¢OÊ\906¼\7f\e«m\ 6\9f_\ 4\9b^\ 3¢f\ 3¡j\ 5¤l\ 5§p «v\f°|\14·\83\e·\83\e³\7f\18º\86 ¹\84\1e¸\85\1e¿\8a$Â\8d2È\9aRìÖ«îäÔîåÐìàÃæÖµÝÊ¡Ô¼\97̵\8fÅ¥\80Ŧ|Á£yÂ¥zж\91áÉ¥éÙ¶æìÛäíàãíÞæçÕíÞÊîÔ½îÒ»åÅ©Â\9d\80¦~b¨~Z¦zV\8e`=\8aT.\88O*\8dP%\93O#¦^:¹aC¹U4Ûq^ë\88zÏ\8dtÜ·\9fåìâãéîãêîãéîãéîãêîãêîãêîãêîãéîãêîãêîãíìêãØÎ\9f\8f¾\87v¿\83q»\82pµ\80j»\83n¶\80kª{d§\89gØɯêíâãëëãëíãéîãéîãèîãçîãçîãçîãèîãèîãèîãèîãèîãéîãêîãéîãëíãêíãëìãìëãìëãíëäìêäìëãëìãëíãêíãêîãêîãêîãëîãéîãëîãëîãëîãëîãêîãéîãêîãéîãêîãéîãêîãéîãéîãéîãêîãêîãêîãéîãêîãéîäììæíéçíêäìîãçîãèîãéîãéîãêîãêíãêîãììäëìäìëãçíãèééîØëîØííÓîìÒíëÏîêÊîìÌëíÓìî×ëíÔìíÏëíÒíîÓêÚ°Ú³iË¡T¿\8c3¶\84"¼\85"¿\85 Æ\8b)Í\8a+Ç}\1dÀr\14ºk\ fµd\bµf\ e½o\11Åv\17Çy\eË}#Î\80\1eÍ\80\17Ì\7f\14Ñ\8e0Ô§dË¥l£\81I\85p?\7fh5\92}K¡\8b]\9a\82L\8cvA\8as<\8ewB\8ar>§\8bW³\94_¿\9d`Û²pîÍ\88ãÇ\85àÆ\8aåÌ\93ëÖ¦é׬ëÚ®íܵëÛ²èÙµçÚ»å×´äÕ³ãÔ±ßѲÙɪÖÈ©ÑÄ¥ÉÀ\9b½©hÇ\95EܬTä»aâ¸]â¸[ç½\â¸Wé»WèµNé°Há©?â¥=ߤ=Ü£7Þ¦>Ö\985È{\13¹l\ 6©f\ 4¯k\vk\b§l
+¹\88-Û´`åÂtá¿pÚµ`Ö³^È¢T»\90D¸\8eAÉ\9eRϤRÆ\8c.¹|\19·p\18£d\ 6\9ca\ 3 f\ 4¡h\ 4¥k\ 5¨r ªv\r³\80\18·\84\18¸\85\1a³\7f\17·\83\1c´\81\19¯{\13µ\84"½\88-Ã\8e=ݾ\86îãÊíàÄäÔ²ÛʨÔÀ\98Í·\90ʳ\8aÈ®\87Ǭ\86Ç«\85Ô¹\98åÓµîãÄîæÈåìÝäíáãîßéçÖìßËîÔ¸í͵ìÌ°Ô¯\8c²\88f zR¡wU\95iG\8f^=\88Y4\96b=\96X.¾xUÃw[È~]Ü\8fqå\98\8aÐ\96\80׳\97æíáãéîãêîãéîãêîãéîãêîãéîãéîãêîãêîãêîåëáä½±Ã\8dv»\81lº\83j¸\80kµ\80i»\82nµ~g¥~g«\91páÔ¸çîäãêíãêíãèîãèîãçîãèîãçîãæîãçîãçîãçîãèîãçîãçîãéîãêîãêíãêíãëìãìëäëëäìêãìëãìëãìëãëìãêíãêîãêíãéîãëîãêîãëîãëîãëîãëîãêîãêîãêíãëîãëîãéîãêîãêîãéîãêîãêîãêîãêîãêîãéîãêîäëíæîêåíìãëíãçîãçîãèîãèîãéîãëíäíçèíâëí×ìéÌèèÚææßêÞ²éÜ®èØ«åÖ¡çØ¢çÙ\9fëܧëÝ©ëæ¹ìã±ìÞ©îä²íèºíè¸îߨêÕ\9dâÆ\83Ì©X·\907°\81\1eÂ\89,É\8d2Ï\8c.Ç\7f Âv\19¿s\17½q\19Äx\eÆx\eÑ\85&Ì\80\1aÆ{\11Àr\aÃp\ 6Æy\15Ò\8f=Û\9aT®{9\86i)\93\80G \90a¥\94d\8fvD\89q;\8fyD\8dw?¤\8cS¼¢hÍ®pضlìË\81ìÎ\86îÑ\85íÓ\8cìÍ\88êÌ\8aêÏ\90ìÑ\95ìÑ\9bçÍ\97ϼ\8b»«\80·¦x¾ªz©vµ\9fmª\94e¡\90Z\7fo1ib\1fzi\1c½\8b6Û¤DÞ\9f;ß\9f;Ú\9b5Û\983Ý\9a5Þ\9e:æ©BäªBç¬@ߢ6á§Cݤ6Þ¤=Þ¡<Ó\8f&Àw
+¸t\ f·q\13¹u\19ªo\11£l\vªv\17Î\9cKÝ´lÛ¶eÓ«]É UÄ\9bN¼\92GÇ\9eSÍ¡PÉ\955¹y\18³m\ e¥f\ 5\9da\ 3\9fd\ 3¥j\ 4¨m\b¨q\v¨t\v³\7f\18µ\81\19±\80\18·\86#¸\85\1e³\80\e¬}\18±\81%³\83,¸\861Ò®qîèÎíéÓìåÈëÞÅêÚÀåÒ³åаãÎÛÆ¡Ô¾\98ßÉ©íàÂîæËîçÏæéÛãìàåêÛéåÔìÞÊîÕ¾î×Áíиà½\9cÀ\98q\96qN\95iL\92fD\93fD\92g?\9bmK\92^8¸xZÍ\88mÕ\9d{æª\8dî\99Ï\9a\83Öµ\94æëÝãêîãêîãêîãéîãéîãêîãéîãëîãéîãëîãííêÜÉÊ\97\84À\84s½\83l½\81m¹\80j»\82k·~i²~g¢z_º¤\82éáÈåíæãëíãêîãéîãçîãçîãçîãèîãæîãçîãæîãçîãçîãèîãèîãéíãéîãêîãëíãëíãìëãíêäìëäíéäìêãìêãêíãëìãêîãêîãìíãëíãëîãëîãëîãëíãëîãëîãëíãëîãêíãêíãêîãêîãêîãêîãêíãêíãêîãëíãêîãéîãèîãêîäìíåíëãëîãçîãçîãéíåìééíàëèÍëß´å×\9cÝÍ\8fÚÃ\84ÖÁ~ÖÀ\85Ø¿}Ò»qÖ¾uÖÀuÙÂxÚÄ|ÛÅ{âÌ\89âË\84ãÏ\88åÎ\8aåÏ\88èÑ\8cëÖ\94ìÚ\9bîÝ¥îá¦íÜ\94áÅuʪSɤL¾\928Ç\902Ç\89*É\84)Ç\80%Ç}"È{!Ì\84&Ó\8a+Ì\82\eÅy\16½q ¹l\aºm
+¾p\11Çu\19´i\17¡u2£\8cQ¦\91]\9a\85N\8dv?\8dt>\93v;º\98Vá¿zëÎ\89îÔ\8dîÑ\84ëÏ\80ëÌ\83ìÎ\86íÒ\8aëÏ\87êÌ\85ìÎ\8aîÖ\98î×\9bèË\8fÞÀ\84βzδzÛ¿~äÄ\88àÁ\81áÃ\7fãÇ\7fʦ]¨\862\82 Ð\92+Ü\95,Þ\90*Ú\92)×\90$Ö\8c Û\8d$Ö\8b$Ý\9e;âªBâ©9Ü 3Ø\991Ý 3Þ¥9Ü\9d9Ù\95/Ë\80\14Ç}\16¾x\11»~\1a¸|\1co
+¬p\15t\1fÊ\9cKÖ®dÔ¬cѧ]¾\93B¿\96JÇ\9dQÍ¥VË\9dMµy\1eªm \9c^\ 3\9b]\ 3\9ff\ 4 i\ 6©p\vv\rx\ e´\80\19´\80\19¯\80\1a®\80 µ\85!³\83\1f°\7f ©{ ªz%¬|)ЧkìîÛéîäéîâìíÚîìÖîæÑîâÍîãËíàÃêÛ½ëÛ¿íäÊîèÑìáÊéæÔéæÔêâÏêâÒìàÍîÚÃíÛÆíÑ»æǩͨ\8e\86j tU\93kI\90jG\8di@\99rO\9apK·\82`Ú¦\82ß²\8cæ½\99å·\90Å\99{ɧ\8bèíâãêîãêíãéîãéîãéîãêîãêîãéîãëîãììæéßܵ£¾\88s¾\84q»\83l¼\81l¼\83j¸\81h´\80i©|e£\80fκ\9eììÝãììãêíãéîãéîãèîãèîãéîãèîãèîãæîãçîãèîãçîãèîãçîãèîãéîãêíãëíãëíãììãìëäíëãìêäìéãìëãìëãëìãëìãêíãêíãëíãëîãìíãìíãëîãëîãìíãìíäìíãëíäëíãëíäììãìíãëíãëíäììãìíäììãëîãêîãçîãçîãêîãìíãêîãêíæíâëéÌåÚ¯ÚÈ\91ѺxË`©YÆ«[Æ©XÍ®_̱]Ò¸d×»hؼh×¼lÚÀmÜÂißÅlãÊyáÈ}âÌ}äÌ\7fãË~æÐ\84æÍ\81çÐ\85èÓ\8eì×\91ìØ\90ëÕ\8dîà\9bìÙ\95ÞÀwÆ¡N´\87*¸~$Å\80#È\82)Ì\83(É\81#Ë\81$Ê\7f\1eºf\a°_\ 3²f\ 5´h\b²f\v§R\ 2¤Q\ 4³t,´\8eT\95\82J\8du;\8at6\91u<Ä\9e_êÈ\80îÔ\89îÕ\8bíÓ\8aíÏ\7fêÍ~îÓ\8dîÖ\90îÜ\95îÚ\96îÖ\90íÓ\8díÒ\92íÔ\99íÒ\98ëÒ\93îÖ\98îÓ\95íÒ\8fíÖ\8fìÒ\89ìÑ\87íÓ\88îÓ\86ß²Và\9d1Ý\93&Þ\95+ß\94.Ý\97-ß\9a-Ú\93(×\8b\1cÖ\8e"ß\9d<ã§?å¬<ߤ8Ü\9c1Þ¡4à¤8ߤ9Ú\9b2Î\88 ¿w\rÂx\17Î\946¿\85&¼\7f\1dµz!®t\1ey\1cÌ\9eKÚ³iÏ¥Vª\7f(°\878ͧ[Ó«^УUµ~'§l\f\94W\ 3\92T\ 3\95^\ 3\9bd\ 4¢k\ 6¨t
+z\11²\81\1d¶\87%·\86#µ\84 ±\81"°\81%°\82&¨{%§v'®~1Ó¯uîìÛëîâêîàëîßëîÜîë×îæÑîåËîèÏîçÐîéÐîëÑîãÉâÒ¸êâÐëàÍíÞÊíÝÉíÜÄîÛÄîØÂîѸêɯ۸\9aÈ¥\80¹\95p\96vO\85d=\8anH\91nI¡|Q¼\8fkÑ£\83Ù¬\8aØ°\8cÓ£\84½\91oÈ¥\83ééÛãëíãêîãéîãéîãêîãéîãêîãëîãëîãíééÕÅÇ\97\87¾\84t¾\83m½\83o»\83nº\84k¸\81h´\82k zc¤\85l×ƬëíÝäíçãëëãëíãêîãêîãéîãéîãèîãèîãçîãçîãèîãèîãéîãèîãéîãêîãêîãêíãìëãíêãìëãìëäíêäìêãíêãìëãììãëìãììãìëãëíãììãìíãìîãííãííäìíãììãíìäììãììäíìäíìäììäíìãìíåììåíêåíêäìíãéîãèîãèîãéîåìëéíàìæÄàÐ\99л|½¥]º\9cM½\9cJ¼\9bEÁ£LȨRÈ«RÊRαOѶOÔ¸WÕºWÕ»WÚ½RܽSÛÁ_àÂeìØ\8cåÐ\80ßÉoãËpâÉuäÍyæÐ\83çÐ\81éÒ\87êÓ\8aéÒ\84ëÕ\8aìÚ\95ïá\9dçÏ\87ɦT\841®y\1eº\82+Ây\1aÇ}\1dË\80 Åx\19°b\ 3°b\ 3°g\aµi\r¤W\ 4\98H\ 3\98I\ 3\9eP ¨v0\91s0xZ\15\96p+Ã\90Hå¾vîÐ\8bíÍ|ëÏ\7fíÑ\89ìÌ\7fî×\8eîØ\92îÚ\94îÙ\92îÙ\94ìÐ\8béÌ\80ìÑ\8eîÖ\99îÙ\9eîÚ\9eîÙ\9eíÖ\9aíÔ\96íÒ\8fëÎ\88éË\80íÓ\82ìÊoá±Kæ§DÞ\980ã\9f7ß\9a(Û\90&Ö\8c ×\8f"Ü\96)Ü\96&Ý\99/à\9f5äª=âª>â¨?á¦8à£9â£8à£6Ø\980¾~\13¹{\14¿\87*µ~"µ~\1a«v\18¬v\1d¦m\12©w\1dÆ\9aGÈ\9eE¯\82/¾\92B̦[ѨZÍ\9eN±z%£e \99\\ 4\92W\ 3\92Z\ 2\99a\ 4¥m ¨t\r¦u\r o\ e²\81)¸\8c-µ\86'ª{\13©x\15®\82$©})§v&¯\7f3Ú¶\81íäÌîëÙíìÚíîàìîÝéîâííÝîéÕîèÐíìÕìîÚìíÚîèÒëÞÆíÜÉìÜÉíÜÉíÜÈîÚÂíØÁîÔ¾ìͶì͵àÀ\9dÒ°\8f¾\9b}£\87f\96|Z\8cqO\90qL\98vJª\87b»\91pÊ\98vÊ\95zÂ\8bp½\8bnÂ\9f\80éæÓãêîãêîãêîãêîãêîãêîãêîãêîãìîäíß䶡¾\87q¾\84r¿\87n½\86nº\83i»\82i»\83i±}e\95w[¬\92wáÒ²ìì×èîàãîæäîèãíêãíéãëíãëíãêîãéîãèîãèîãèîãèîãéîãêîãéîãëíãëíãëíãêíãììäìêãìëãìëãìëãììäìëãìëãëëãììãìëãììãííãíìäìíäìíãííäíëäíìäíëåíëåíêäíìæíêäíêåíêåíêäíëäíêåíèäëìãêîãèíãéîæîäìçÆáÑ\9eªb½\9eM±\928²\91=µ\93;¸\954»\997À¢=Ä¥7Æ¥8ǧ;Ȫ8ǧ(ͨ0É£+Ê¥&È¥'̦)˨/Ö¹Hêì\9dã×\83ͳAΰ;Ù¼LÙ¾XßÆmáÆjçÎvèÏxèÎ~èÏ\82èÏ\84êÑ\85íÝ\96ìÙ\8eË«b¡u!£n\17¼z Ç\80$Ãw\16¾p\12a\ 4«^\ 3§^\a¡X\ 6\96G\ 3\94E\ 3\92C\ 3\92D\ 3\9bS\r¬v,\8bW\ f®w)ߤVêÅsëÊyæÃoìË{ìÓ\88î×\8cîÛ\94îÛ\92îÙ\94î×\90îÔ\8céÊ\7fèÎ\84î×\98îØ\9cîØ\99îÖ\97îØ\9aîÚ\9eîÕ\98íÒ\90ìÏ\88îÕ\8díØ\8eîÎxëÁ\ì½Wè©?â\9c2à\95#Ý\93*×\8e$Ú\92%Ý\97,Ø\91&×\90$Ø\91$Þ\9d/ß /ä«Bà§<Þ¤7Ú\9e5Ù¡;Ñ\973Á\8f)Í\9b;Ë\9fHÊ\9dEÀ\946¿\929¼\8d1°} «x\1d¬{ ³\82,²\823Ä\9aPϦ]Ñ©]¿\8b9¢f\10ªj\10\9b]\ 6\9a^\a\9bf\f\98`\ 6\9dh\ 6¤s\ f¢p\ e\9fn\v¥v\19¯\84(³\85*¤w\e¦v\15¨x\1e¦v#©y)µ\83@Ú¾\8bëÞÄìàÆîæÑîëÙìîÜëîâêîâììÜìíÛêîàçíçèîäìîÞíîÜîØÅîÛÃîØÁîØÂîÙÃîØÁîÒ¸íζíͳßÁ ×¼\99ȧ\8c¾\9c~©\8eq\93wO\8cmI\93vU¢~a¢\7f_³\85cº\87j»\89k³\86hº\94wéâÌãììãêîãêîãëîãêíãêîãëîãììãïèêÙÎÍ\98\88Á\86tº\82i¼\84k½\85l¼\84k½\85kº\84e¦}_\98~[¬\92ëÝ¿íëÕéíÜæîÞäîßåîßäîáäîáäîääíäãìêãììãêíãêíãéîãéîãéîãêîãêîãëíãëíãêíãéíãêíãêíãëìãêíãëìãêíãëìäëíãëíãììãëîãëîãëíãëîãëîãëíãìíãíìãíìåììäíëåíëæíèåíéåíéæíèäìêäíêäìêãììãêîãéíçîãì߼ι}µ\96J®\87)°\8b%²\8c%³\8e+¸\93-º\95(¿\99$¿\99!»\95\12¾\96\12¼\94\10¼\94 º\91\a»\91\ 6º\8e\b½\93\a¼\92
+¾\93
+¼\92
+½\96\ eâÈ_Ï´B½\95\15À\9a\1d½\9a\1aÉ£(ɤ+ÓµE×´EãÅTèÑyèÎ|èÍ~åÊzéÎ\82íÜ\9béÖ\9b«\8a<\95h\19§r!º~4Ã|+Àt\18±d ¨Z\ 4¢R\a\90F\ 3\8fD\ 3\8fA\ 3\8dA\ 3\8a>\ 3\8c?\ 3\93N
+¤b\eÂ\86=ß³_æÃnçÆqêÉvîÒ\86îÙ\8eîÝ\93íß\96íÞ\92îÜ\96î×\8fêÏ\86èÌ\82íÔ\8eîÙ\98î×\97êÏ\8dêÍ\8cíÓ\8fìÑ\8aìÑ\8bî×\90î×\91îÛ\92î×\8eìËvìÆdîÁZëAè¥8å 0à\99-Ý\95,Þ\95-Ö\8f$Õ\8b#Ï\84\19Ì\83\1aÐ\87\1eÓ\89\1cÔ\8c(Þ 3Û£7É\960Ç\964Ò§IÁ\98;Í =É£DÇ F§\7f&«\85.º\90:»\908·\8b2¬\81&¬x"´\84-Ç\9fQͤ\Ç\9aE³|'¦i\15¤h\14\94Z\ 5\91V\ 3\95a\b\98d \99i
+\9aj\ e\9bk\ f\9ai
+¡l\10\7f!¬~%¢s"\99g\16\98e\r\9ej\18¥r&Æ\9a^áÍ£êÚÁêÚÃìßÊîäÎîêÖíîÛéîáçîãçîææíçèîåêîâìîâëîâîØÂîØÁîÙÁîØÂîÙÃîÖ¿îÕ¼íѺë͵åÆ©Ú¼\99Í®\92¢\82«\90p\9ay`\8frQ\8doK\94sR\9c{Z¦|`ª\80e¨\7fa£{^²\8ckêâÊãëîãêîãéîãêîãëíãììãíìãíìåèÙ滤È\8e\80¿\84q¹\80l½\81i¿\87n½\85l½\87m´\81f\9e}\¨\95pÜÌìëÕèîßåîáäîßäîàåîÞåîÝäîÞæíÞäîßæíßäíãäîäãíëãëîãéîãêíãéîãêîãêíãéîãéîãêíãêîãëíãêíãéîãêíãêíãëíãêíãêíãêíãêîãêîãêîãêîãêîãêîãëîãëîãìíäììãëíåíëåíëåíèåíéæîéåíèäíéåîèçïååîåçîäëݴ̳|±\92Dª\87,«\86\1e¬\88\1c\88\15³\8b\16µ\8e\18·\8f\11´\8c\b´\8a\ 6±\88\ 3³\8b\ 4®\81\ 3·\89\ 3³\89\ 3·\8b\ 3·\89\ 3»\8c\ 3¾\8b\ 3½\91\ 6¿\93\ 6´\8d\ 3\8e §\8a
+¦\80\ 6¬\89\b¯\8e
+²\8a\ 5»\8e\ 4À\93
+Ä\9d\13Ϭ&êÔpèÏnâÆiãÈrãÈuêÓ\91ïâ²Ò´uxT\ evM\ 6{M ®s-Äz+¨d\12\9bO\ 4\8c=\ 3\89>\ 3\8aA\ 3\8aB\ 3\88=\ 3\84;\ 3}8\ 3u/\ 2\88D\ 5Ë\90AåºcèÇwìÏ\80îÔ\8aîÖ\8cîÙ\90î×\8cî×\8dîÚ\90îÞ\98îÙ\93íÕ\8eîÚ\93îÝ\9dîÚ\95èÌ\84вhÝÀzåÈ\83èË\83ëÐ\8aîÙ\96îÚ\96îÜ\95î×\8eíÎríÈdí»Që¬?ç§9å¢/Ú\90 Ø\89\eÔ\86\19Ô\85\1aÌ~\13Ô\88\1dÏ\84\19Î\83\17Ñ\89\1fÒ\89!Ú\9b.׫CÕ³Mܽ]ݾd·\923¯\82$¯\89-²\8c0³\8e5¸\93<«\864¢}$·\916À\98@¶\8a1¨z'½\8e=Ì\9dS·\84-¤n\14¢e\17\91V
+\8cP\ 3\89M\ 3\8cU\ 5\94a\f\94e\ e\9ak\15\90d\r\93a\b\9ag
+ª{'©y"\93a\ f\8dZ\v\96d\12\94`\13¦z;ϸ\88ãÔ°äÖ»æØÃëÜÊìáÊîæÓìíÚéîáæíéæíæçîæéîãëîáëîäëîâî×ÀîØÁîØÄîÖ¿îÖÁîÙÂîÕÀíÔ¾ìϸæȪãĪϰ\9bÆ¥\8a¼ \86\9f\83i\8ftT\96tW\98uZ\99wV\9dyZ¤~d£{_¡|e°\8fuêàÈãêîãéîãëîãëìãìèãîäãíÙäèÕéԽآ\8aÆ\8d}Â\87sÀ\88rÂ\88rÃ\8asÀ\88p¼\87g¯\83b¦\86aε\8fìà¿êîÔçîÙäîÞãîßãîÞãîáãîâãîæãîääîÛäíÚêéÔèëÕåíããëìãêîãéîãêîãéîãëîãêíãêíãéîãéíãéîãéîãêíãèîãêîãëìãêíãêîãêîãêíãêîãéîãêíãêîãêîãêîãêîãëíãìíãììãìíåíéåíéåíéåíéæîçêîÝîåÆáÏ«èÚ¹îæÊϺ}³\92G§\874©\85\1e«\86\14ª\86\r¬\85\ 6§\80\ 3ª\82\ 4¨\7f\ 3¦}\ 3®\84\ 3°\82\ 3²\84\ 3¶\88\ 3»\8c\ 3»\90\ 3¾\96\ 4À\93\ 4À\8f\ 3À\91\ 4½\93\ 5¼\90\ 5°\8a\ 3\99\81\ 4\8ax\ 3\85r\ 3\87n\ 3\94{\ 3\9f\81\ 4©\85\ 4»\8f\ 4Ã\94\ 4Ä\98 àÆPÍ©+Ñ1Ö¸KàÈkæÎ\83îÛ¢ÛÃ\89gG\rR.\ 3_5\ 3}L\b\8cU\v\96O\b\86=\ 4\826\ 3\848\ 3\85>\ 3\83=\ 3\7f8\ 3x2\ 3i.\ 3e)\ 3k'\ 2Ã\826ê»iíÑ\87î×\8dîÚ\93îØ\8eíÏ\84íÐ\81íÒ\89îÕ\89î×\8eîÛ\94îÜ\95îÞ\98îÝ\98îÝ\98íÖ\8fáÆ|êÐ\8aëÐ\88íÓ\8cîÖ\8fîÚ\92îÝ\96îÝ\94îÕ\88îÒ|îÄ\ìºNíµHë¯Bå¡3Ü\94%Ñ\86\18Ñ\7f\ eÑ\81\17Ñ\82\16Î\80\14Ì\80\14Ó\83\19Ð\87\eÏ\8c\1eÙ¥<Û¶Rà½]Þ¼ZΪQ°\8c3\9dz$¢|'¬\87.¿\9dJаa¸\99E¢\84/ª\863¸\94@¶\8e5¬~+¡m\17Ä\94D¸\87.§o\e\94^\10\8cT\b\88M\ 4\86N\ 3\88O\ 4\87P\ 5\8b[\f\92d\13\88]\ 6\8cZ\ 3\8dW\ 5£r%\9fo!\8cY
+\8bW\ 4\92_\ f\99d\1d¯\85Hϼ\90ØÉ¥àѯãÓ½åÖÀéÙÃíäÐìîÞêîâêîåëîæëîâêîáêîàëîâëîâîÓ¼îÔ¾îÖÂî×Áî׿î×ÁîÔ¾íÒ»ëϲèˬäƫݽ¢Ó²\9bË®\95¬\90x\94vY\9cvY\97qU\95sT\9dxY¢{]¦}a¡zb\8etçÜÈãëìãëìãíêãíßãìÚãæÎäâÌçÚÅé»\9eË\93zÌ\94{Æ\8ewÄ\8cwÂ\8bpÆ\8ex¿\88m±\82e¬\87bÄ©\84ãÉ¢îß½ìäÅêçÉèéÐçèÒçéÑæêÒäíßãíéãìíãíæäîàêéÔîáËêêÚäíæãéîãêîãêîãéîãêíãëíãêíãèîãéîãêíãéîãèîãéîãéíãêíãëîãêíãéîãêíãêíãêîãéíãêíãéîãéîãêíãêíãêîãìíãíìäíèæîäæîâçîáëèÑÝÇ\9c\89[\99vBâΧæÚ±¶\9aT«\8a-ª\86"¥}\r©\80\ 4©\82\ 3¥~\ 3¤|\ 3¦~\ 3¨\7f\ 3°\84\ 3±\89\ 3¹\8d\ 3¿\92\ 5Ä\99\aÄ\99\ 3Á\95\ 3¾\95\ 5·\92\ 5±\8a\ 4®\8c\ 3¯\8d\ 5«\8a\ 4¤\85\ 3£\86\ 3\91|\ 3\8ds\ 3\8ct\ 3\99|\ 3\9b~\ 3¥\85\ 3±\8a\ 3Â\96\ 4Ä\96\ 5Ç\9b\bÈ\9b\bÇ\9a\vÊ¢\1fÔ²CáÅuïÚ\9bÓ¸\80`B
+A \ 3P(\ 3X4\ 3{M\b\89K\ 5\83:\ 3\7f7\ 3\838\ 3}8\ 3}9\ 3s1\ 3g)\ 3]%\ 3X\1e\ 3W\e\ 3\98Y\19ݯbîÒ\87îÖ\8fîØ\8eîÓ\86êË}åÅuíÐ\7fíÑ\80íÕ\8dí×\8eíÞ\98îÞ\98îÜ\95îÜ\95îÙ\94îÙ\91íÕ\8cíÔ\8díÓ\8cí×\8eîÚ\92îÚ\93îØ\8dîØ\89îÔ\81îÊgí½Vì½Xí¼QÜ\93 Ú\89\11Õ\87\14Ó\89\1fÑ\82\18Ð\82\17Ð\83\19Í\82\17Í\80\13Ö\8b\1fÛ¥>çÄhÚº[Ò®QÃ\9d;µ\959§\885\8fp\1d¢~1«\897\874¨\866¼\9aF¾\9dH\9aw$\9bw&³\8f7¶\927¢t\1c¢q\1d¸\80*¢j\17\8fT\v\86R\b\80K\ 4}I\ 3\83L\ 4\82N\ 6\85U\b\8c[\ e\84Z\f\86V\a\8c[\ f\99j\1c\91e\16\88U\a\8aT\b\91\\17\9cm,Â\9bjζ\8cÇ·\98ѤÖçÛË´àÏ·éÜÄîéÒîëÛííÛîëÜìíÞìíÜëîÞëîÞêîßíÏ·îÓºîؾî׿î׿îÖ¿îÓ»íѶê̲é̯æËäÈÝÀ¨Öº\9fÆ¥\8e \82i\9e|`\9ax]\96qX\99u\¥\81g§\7ff§\7fe©\89mèÑ´âïããîâäèÖããÊæÚÃç×ÀèÖÃìÃ¯× \83Î\94{É\8ezÇ\8esÆ\8etÇ\90sÉ\91y¸\84h\9f}Z¶\98tß¡íѱîÕ¸îØ»íÙ¿îÙ¾íÝÀíÚ½íÝÂèéÒãîããìîãëìäîãèìÔíàÈîâÏçíÞãëìãêîãéîãéîãéîãêîãéîãéîãéîãèîãèîãéîãéîãêíãêíãêíãêìãêíãêíãêíãêíãêîãéîãêîãéíãêíãêíãëìåîÞéèÎëãÃìÜíاêÑ¢å¿\8e\9dq9wH\17¦yCîåÀÞÉ\96¯\91@©\86'¦\7f\r\9fv\ 3¡w\ 3£z\ 3 x\ 3¦{\ 3©\82\ 3±\87\ 3º\8f\ 3¾\95\ 3Á\98\ 3É\9f\aÉ\98\ 5Æ\99\ 3³\8e\ 3¤\82\ 3 \81\ 3 \82\ 3\9d\82\ 3§\88\ 3¬\8c\ 3¯\8c\ 4µ\92\a¹\97\ fµ\8d\ 3¹\89\ 3Á\8f\ 3Ã\9d À\96\ 5Á\94\ 4Æ\98\ 4Ç\9b\bÌ\9e Ë\9e
+Ê\9f\bÇ\9c Ì¥$äÆnëÔ\95º\9eeS0\0@\1f\ 3F!\ 3R,\ 3jE\ 4|K\ 3\82>\ 3|8\ 3\7f9\ 3z6\ 3q3\ 3d*\ 3Y$\ 3S \ 3P\e\ 3K\1a\ 3{G\11Û§]ìËzìÎ\81îÕ\8cîÖ\8bíÓ\89çÉ}âÄoåÇvíÔ\89îÚ\93îÙ\91îØ\8fîØ\91í×\8eìÒ\89ìÑ\87íÕ\87ìÒ\8bèÌ~ìÓ\85îÙ\92çÆxï×\89î×\84îÖ\7fîÏqê¿ZíÆbæ¬D×\82\10Ó{
+Ó\86\16Ö\8c!Ñ\87\16Ì\80\14Ì\7f\14Î\83\16Ãx Ì\86\1aÖ¤@Þ½aϳWãG«\892¯\8d7¡\82,\9f}+´\91E±\8b6»\98C²\8e@Á\9bJÍ]§\84,\86b\ e§\850µ\914¡w\1d\8f\\r¥o\16\90T\ 4\86L\ 5\83M\ 5|G\ 3yE\ 3}E\ 3\83N\b\88W\ e\88W\r~L\ 6\81M\a\83Q \97d\18\8d[\ f\89T\b\91[\11\9ad&«\85L×Ã\9fÓåʺ ñ\97ï\93ij\9a˺\9e×ĦèÙ¿èÜÆëÞÆìãÍíâÌîçÑîêÕíèÒîëÔìÑ·íÓ¸îÕ¼îÕ½î׿îÔ¼îÓ»íÔ½ìÏ·êͯåÉ©âƦڽ¡Ô·\9bÓµ\9c³\95|§\86g \80_\9e}\¡{bª\83k«\87j¨\82dª\88iäÁ¤äæÎãâÒäÝËæØÅè×ÀéÒ¿êͻ赡Ñ\9a\86Ê\93|Ê\92~Ê\92{É\91zÈ\91y¿\89p\9cuU\96~\À¨\87ã˪ìаîбîÓ¶îÓµîÕ¶îÓ¶îÖ¹îÓ¶îÛ½êçÎãîçãììãíèçîÚíâÇîÞËçîÜãêíãèîãèîãéîãéîãêîãêîãéîãéîãéîãèîãèîãèîãêíãëìãëíãëìãëìãëìãëìãêíãêíãêíãêíãéîãéîãêíçîäì×®ä®pã«fáª\Þ¤ZÝ\9eWÐ\8aK\90Z\euK\12³\8fWíëÍÞÊ\99¯\8e7¥\80\1d\97s\ 3\9ar\ 3\9cs\ 3\9ds\ 3£{\ 3\7f\ 3´\84\ 3·\8f\ 3Ã\97\ 4Ã\9a\ 4Ã\97\ 4Â\96\ 4Á\92\ 3Ц\f¸\8f\ 3³\88\ 3²\8a\ 3³\8b\ 3²\89\ 3¼\90\ 3¸\8e\ 3À\94\ 3Ë¡\ eÌ¥\16Å\99\ 6È\98\ 4Ê\9b\ 4Ì¡\ 5Ò¥ Ñ¢ Ó¤\aÑ¡\ 6Õ¤\aק\ 6Ô¢\ 4É\9d\aÒ1ìÔ\8bàÈ\8c\8aj-S-\ 2C \ 3>\e\ 3E$\ 3Q+\ 3f:\ 4r:\ 3r4\ 3s7\ 3g.\ 3^+\ 3O\1d\ 3J\1e\ 3I\e\ 3D\17\ 3D\17\ 3i;\v×\9bQè¼gëÉríÐ\80îÔ\85î×\8bíÙ\92ìÒ\88äÅxíÕ\8cíØ\91îÚ\94îÕ\8dîÙ\93îØ\90î×\8fîÕ\8dî×\8eìÔ\87æÌ{îÙ\8dîÙ\8bà©NêÂkìÍsîÎtîÐníÉgíÅ[Ó\90 Ô{\fØ\88\19Ù\91+Ö\87\1fÌ|\vÒ\85\16Ð\81\17Ë\83\16Ì\8c#Õ\9a2Ô¬LÎQ³\913©\87-¯\8d9¨\83(´\92;¾\9cMظjÅ Hί_¾\9cRÄ¢WÁ U¡},\94q\17©\89:Â\9cI·\8c:\9fo\1a\91b\v\80I\ 3zD\ 3wC\ 3vB\ 3xE\ 4zG\ 4xF\ 5\84T\ e\80M\b~K\a|I\ 5\87R
+\8bX\ e\89W\12\8cY\ f\95a\e¢q5Ô¸\89èÝÂèÜÉãÖÃÜ͸˻ Á¯\9a·¥\8aÀ\8c̼\9bØÉ«àеäÓ¾çÙÀçÙÁèÛÁèÛÂãÕ¾êϳíÒµìÒµíÔµîÖ¼íÒ·íÓ´ìÒ°æ̨äǦáƤÜÁ\9fÚ½ Ò´\92׸\9a¾\9f\87ª\8cm®\8ck®\8ai°\89o±\8ct±\89m°\8ai\8boÞ¸\9eçÝÃåÞÈåÝÇçØÄçØÀéÓ½í«ݤ\8fÏ\98\85Ê\90{È\8dyÉ\91}È\91{À\8bt\9duW\88lE\98\81aʳ\94áÉ©êͯîήîÒ´îÓµîÔ·îÔ·îÒ´îÒ´îÔ·íÛ¿æëÕãíæãìèåîÝíâÉîÞÇæîÝãêìãéîãèîãéîãêíãéîãêîãéîãéîãèîãêîãéîãéîãêíãêíãëëãìëãììäëëãëìãëìãêìãêíãëíãêíãéîãëíìåÌÛ¡kà\97Zá\9bPá\9dHá\9aJÞ\96JÍ\84: _\e\83O
+¯\8aGìíÌêÛ°¶\97A¦\82\1c\92n\ 2\97m\ 3£u\ 3§|\ 3¬\80\ 3¶\8a\ 3À\92\ 3¾\90\ 3Ã\96\ 3Ã\96\ 3Á\94\ 3¾\92\ 3Á\94\ 3Ò¨\ fΣ
+Æ\93\ 3Â\93\ 3Å\96\ 3Å\95\ 3É\98\ 3Ê\99\ 3È\97\ 3Æ\97\ 2Ê\9d\aÆ\97\ 3Á\98\ 3Æ\9b\ 6Ç\96\ 3Ì\9b\ 3Ô¤\ 6Ö¤\ 5צ\ 5Ù¨\ 4Ü«\ 3Ü®\vݸ9èÏzéÔ\97¼\9bW\85^\1dvK\fk@\ 4_8\ 4J)\ 1U1\ 1T/\ 2e4\ 3f4\ 3`-\ 3R\1f\ 3I\1c\ 3J\1d\ 3E\18\ 3D\18\ 3=\12\ 3A\14\ 3K\1d\ 1\9d_\1dÌ\84;Þ¢Sä³dê¾níË\7fïÕ\8dîÕ\8díÒ\89îÖ\8cëÎ\85ëÌ\80íÖ\8dîØ\90î×\8fîÚ\95îÛ\93îÚ\8fîØ\87íØ\8cîÜ\94ëÐ|Ú\8a,Ö\85&çªIç®MîÂ\íËgîÈeâ£6Û\8d\1cà\95"Û\94)Ô\86!Ö\8b Ô\8c Ï\8b\1eÑ\992΢AÕ®SÍ«O»\9bB¤\7f {\1c¤\82&ª\8a.¸\97C¾ S¹\9bL¸\94CÚ»nŤX¸\96J\8c=\99v#®\8c6\8a:\875¶\8f>³\898\98l\14|H\ 3u?\ 3o;\ 3r?\ 3uA\ 3uB\ 4yF\ 5|N
+{J
+yG\ 6}J\b\8aW\10\8aX\11\8aW\16\90]\1d\91f(¨{ìáÉîëÚìäÌëáËêßËèÛÅâÓÀÓìů\92½©\89Æ·\95Ï¿\9dÓŨÔŧÜͱÜ̱ÜÍ°ÚËèΰèͯéÏ®êίêΰåʧäÇ¡âÅ Þ ۿ¢Ú½\9aÔ¸\93Ôµ\94Ò³\92Ò²\96â\89³\90y¼\95|Ä\9b\7fÂ\9e~»\97z¿\97}¸\90v³\8duݵ\98èÛÁæÞÈåáÈåßÇæÝÆêÔºêµ\9eÒ\97\81Í\92zÎ\90|È\8exÆ\8brÁ\87o§zb\87jB\89oI©\91vÑ»\98âʧéËîаîѳîÓµîÔ·îÒ´îÒµîÑ´îÒ´îÖ¿ëæÎãíçãíéæíÞíáÉëçÑäíçãéîãèîãéîãéîãêîãêíãêîãéîãèîãêîãéîãéîãêîãëíãëìãìëãìëäíéäìêäìëãìëãëëãììãëíãêíãëíäíçéΧÜ\90Mà\95Là\96Cà\98=Þ\98=Ú\92;Ä|-¥^\11\97V\f¶\87>êêÄêìÍÝÅ\81©\86\1f\8dg\ 1 u\ 3£u\ 3±\84\ 3µ\86\ 3»\8e\ 3¿\91\ 3¾\92\ 3¾\94\ 3Æ\98\ 3È\99\ 3Æ\9a\ 3É\9a\ 4Ë\9b\ 4Í\9c\ 3Ë\9b\ 3É\9b\ 3Ë\9b\ 3Ë\9b\ 4É\99\ 3Î\9c\ 4Ì\9b\ 4Ê\9b\ 4È\9a\ 4´\8f\ 3¤\84\ 3¬\84\ 3²\84\ 3Ä\91\ 3Ë\96\ 3Ð\9b\ 3Í\9c\ 4Ô¤\ 5ßµ\19éÌ[íÛ\8céÎ\7fÚ´gÊ\97JÇ\8dDÐ\9aPרZÆ\90K·\8fF¦\7f:\8cb\1cvI\bk>\ 4[*\ 2L\1e\ 3L\1a\ 3G\18\ 3A\14\ 3>\16\ 3C\14\ 3B\17\ 3H\1d\ 3r3\ 4\97J\r¯b\eÀq'Ãu+Ò\87CÛ¡Sç¸ièÀrìÊzíÑ\87íÕ\88î×\8fîÙ\93îÕ\88î×\89íÑ~íÔ~íØ\88îÚ\90îÛ\8fëÄqÚ\83#Êk
+¾g
+Ás\13ä±PìÈfíÅcå®Bç¨5æ¦2Ý\99+Õ\87\16Õ\89\17à\98*Ô¡9ѬL¿\9b:Ä¡FÄ£N©\86(¡\7f$¤\81$¬\897 P·\9aG®\8d>¯\8d=±\90C®\8d<©\879¦\856\9d{- z+´\91B±\8f>£{(¦|*·\8e7\9bq\e\87R\aq9\ 3m7\ 3p8\ 3n:\ 3m:\ 3rC\ 5wH\ 6qB\ 4vD\a\81J
+\86R\10\8aS\1a\88R\16\8cb+§\91bØǨïç×îêÜîëÙîéÓíåÑìâÍíàÎêàÌÞӼ˾ Ì¿\9fѤξ¢È¶\98È·\94Å´\90͸\97Æ´\8fâËãÊäÊ«äÌãÉ©ÜÁ\9eàÁ\9dغ\93ؼ\97Ù»\9bÖ·\95Ö·\97Ù»\9bÕ¸\97Ôµ\95˨\87À\96\80Å\9d\8cÌ©\8fÊ¥\89Ä\9f~Ä\9e\80Á\9b\83·\91w×\8dëÒ¶æÝÇäáÈãåÍäãÊëͳߩ\8eÏ\95|É\90tÊ\90{Ç\8du¿\89l±|`\93pP\87jB\94{[½¢\80ØÁ\9eą̈êÏíÒ°îÔµîÓ´îÕ¸îÒµîÔ·îÓ¶îÒµîÖ¹íÞÄäîåãîçéì×íçÍèíÙãêíãéîãèîãéîãêíãêíãêíãéîãéîãéîãéîãéîãêîãëíãììãìëäíéäíéåíéæíçãíêãìêäíéäíêãìëãìëãëìäîâèÃ\91Ø\8cBÞ\95=Ý\96:Ý\95<Ù\928Ó\8a.¾r\1c»o\1d´m\1eË\8cHéä¿äî×êëÉÙÀ\85®\903\9dy\ 2«\7f\ 2¹\8a\ 3º\8e\ 3À\92\ 3Ä\97\ 4¿\95\ 3Å\98\ 3Ì\9d\ 3Î\9d\ 3Í\9e\ 4É\9c\ 4Ä\98\ 6¯\8d\ 4\99}\ 3¹\92\ 3Ï¡ Ó \ 5Ð\9e\ 4Ï\9f\ 4Ï\9d\ 3Ñ\9f\ 5Ä\94\ 4¶\8e\ 4´\8c\ 4½\8f\ 4Â\8f\ 4¾\8b\ 3¿\8a\ 2Æ\96\ 4Ï¢\eß¾UëÓoìÝ\95îÐ\8aáºgçÁqéÃqå¿sëÇ\80çÄ|êÁvðÓ\8bðÖ\8eêÈ\82Ù³fÃ\95I¬~4\82S\11h4\ 5J\1f\ 3<\19\ 3A\16\ 3C\1c\ 3M#\ 4_4\ 6o8\ 6x3\ 2\87;\ 3\8d@\ 5\94D\r\91>\ 6¥R\rÂp$Õ\8c=Þ\9dNä®aì¸kè·jê»mæZê®]é½hîÍwîÖ\88ïØ\8cîÒ\84æ¶YÜ\86$Ír\10Áe
+µ^\ 2Ø\960âµIêÄ]ä±Dê³Aå¬>ãªBà¥7äEê¸NêÇcÛ¾`¸\957Å£EÀ\9c?¿\9b>¨\8b5¥\86- \80.À Q´\97H«\8a;¸\98L¨\8b=¦\87:§\88;¬\8d?\9c{,\97u(¦\848°\8c?¢|'£y(®\863£x \88R\vj5\ 4i4\ 3k4\ 3e2\ 3l;\ 4p@\ 4qA\ 5k;\ 3qA\ 5{G\r\81K\17\84R$ yL¬\96mÏ»\95Û˲ßÔ¾éÝÉîæÓîëÖîìØíèÔîçÓìâËëÞÉå×ÂáÓ¹ãÔ¼ÕÈ®¾\88ª\97{©\97v§\95n°\98rÛäÜÄ¥àɨàÈ©ÝÄ£Ù¼\99Ö¸\92Õ·\92Õ¶\94Óµ\90Ô¶\92Ö·\93غ\96Ú¾\99غ\97Ö´\8fÊ¥\81Ϊ\88Ô±\94Ѳ\8fÏ\8bÏ®\90ɧ\86Á\9c|Õª\87ëƦéÑ»åÝÈãäÑæàÉë¾\9dÓ\9b{Ì\93zÈ\8evÇ\8du¼\84hµ\80g\95nI\8alK\98\7fY°¡\7f×Å¥èÑ°êÓ°íѲîÕ·îÖ¸í׺îÔ·î׺îÒµîÓµîÔ¶î×»íâÆèíÛåîâéìØéíÚãíèãêîãéîãéîãêíãêîãêíãëîãéîãêîãéîãéîãêîãêîãëìãììäìêåíèåíèåîçæíæçîæåíçåíæäíèäíèãìêãëëæîàæ¾\8aÖ\8dDØ\8e:Ù\929Ô\8c3×\907Õ\8d3Î\85+Ë\81)É~*Ö\90Fëà²åíÑçíÓéíÑçÚ¬ØÄx¢,½\97\ e½\94\ 6Ä\9a\ 2È\94\ 2Î\9f\ 4Ì\9f\ 3Ò£\ 4Ò¦\ 6Î \ 3Ä\98\ 5³\8f\ 4\90{\ 4\80o\ 3©\85\ 3Æ\97\ 3Ð\9d\ 3Ñ \ 3Ñ\9f\ 4Ò¡\ 4Ð\9f\ 4ר\fÌ\9b\ 2Î\9c\aÈ\9b\aÄ\96\ 6¾\93\r¾\9f,Ô½fçÔ\86ïá¡ìÓ\8céÊ\82êÇ{ëË}î×\90îÙ\91îÝ\97îÙ\95îÞ\9aîÛ\95íâ\9dîÝ\99íÝ\99î×\8cîÔ\8aïÖ\8aä´bÇ\87@\7fJ\fK \ 2D\e\ 3F"\ 3V2\ 5oA p?\ 4t;\ 3\8fK\17~:\ 3l.\ 3l+\ 3z2\ 4£H\b¹Z\16Ãn*Çv.¿g\1cË{/Ò\8b?Ì~1Äm\1dÔ\8c?â®Xæ»`ܱRåº_å®KÔ\81\18Ër\v»]\ 2¾e\ 3Í\87\1a߯Iæ»Tâ°Dç´Eé¹Lê¹Lè¶Hê·Kè¸Pß¹SÓ°Pº\979½\9b?¾\9a@È¡G°\906©\8a3§\870»\9bJ\8d9·\97H¼\9dT¬\8c9¼\9dQ¬\8d<¥\86:\98y#\9d|,§\867°\8e@\9cy)\9bt$\9fu,¦y+\88V\15a/\ 2Y+\ 3c2\ 3_0\ 3h8\ 4n<\ 6c4\ 3g7\ 5q>
+wD\10nA\ e¡\80U«\82ÖÃ\9aÖÇ\9b×ȧÝδÛ̳ÞзäÙÃíæÓîëÚíîÞííßííÝîçØîâÎìäÐçÜÇ̼\9e¤\90s\97\84d\93\7fb\99\85`Ö¿¢×¿£àƧàÄ£Þǥؾ\99Ù¾\9aÖº\95Õº\95Ö»\96Ù¾\99Ú¿\9bÝÂ\9fàÂ\9fáÄ âÅ¡Û½\99ÜÀ\9aàÄ¡ÞÀ\9cÞÁ¡Ü¿¡Ö´\92Ç¡{Ö«\8cëÆ®ê͵ç×¾åÞÉìͷݨ\8dÐ\99}Ì\91wÉ\8evÂ\85l|Y\9asP\90qK\92yUµ yÝÍ«ìÛÀîÝ¿îÛ»îÛ»îÚ¼íÛ½íÙ½î׺îÔ¸îÓ¶îÔ·îÖµíÙ¾íáËéíÕçíÞæîÜãìêãêîãëîãêîãëíãêíãêíãëíãêîãêîãéîãéîãëîãêîãëîãìíäíìäíéæíççîæèîäêîâèîãèíäèîäæíæäíèäíéãìêéíÛåº\8bÑ\82@Ó\885Ó\890Ô\892Ô\8c1Õ\8a1Ó\87/Î\82)Ë\80.Õ\91BìÙ¥èêÌéêÐéíÐæîÚäìæèå¿èÚ\91Õ½fή4Ϊ\18Ë¥\15Ñ¥\ eÒ¦\a΢\ 6É\9a\ 3Å\96\ 3¨\87\ 3\80q\ 2\9d\85\b¶\8f\ 4Ã\97\aÏ\9f\bÓ¤\aÒ¢\aÑ¡
+Õ¥\12Ó¨\eÏ©"Ï9Ø»SÙÅiåÕ\8aíâ£îâ¢ìÖ\8dëÐ\89ìÓ\8aîÜ\95î×\92îÜ\97íÞ\98îÝ\97îß\9eîà\9fíß\9cíß\9dîà\9díÞ\9bîÜ\96îÜ\96íß\99îÚ\90íÎ\81ê¾nØ\9fU\89P\14?\1e\ 3D\1f\ 3I'\ 3[5\ 6m>\bj3\ 3v?\10w@ Z"\ 3W \ 3_(\ 3y5\ 5\892\ 3\99G\r¡P\ f\91C\ 4\94B\ 4¤Q\ f¢L\ e\9bA\a¨P\bÁj\1aÎ\7f#Æ\7f\1dÏ\8e0Ú\9b:×\89\1fÏy\ eÉp\fÍv\16Ì\83\1eاAâ¸Pç¼VëÁWê¿Ræ²GÖ\9d/á§=à®EسUÌ«OÉ«T¸\97<̧QɧTѳ^æW»\9aM³\92A¶\98H»\9cO¦\896®\8b7Ä¥T»\9cN\9f\7f0\9b{,¢\823©\89;¦\866¢\7f1£|*\99q!¤\801\86Z\15Z*\ 2V&\ 3W)\ 3Z)\ 3b0\ 3c5\ 4a0\ 5^0\ 3^2\ 5K&\ 3H+\ 3\91zKË·\8cÕÄ\94×Å\9dØÉ©ÙʬÙˬÜÍ´ßѸàÒºêÜÉíçÖíîâêîâëíáíëÛîíÚîçÓÙÊ®»©\8d«\9av\95\82d\8dzZÛǧÕÁ¦áȦáÇ£áȦàÈ£áÇ¢àÅ\9fÞÃ\9fÝÃ\9fâÇ¢äʦç̨éϬè˨èÍ©ìÔ²êѬç˨êαëͲèÈ®áÀ§Ä\9f\7fØ«\8cé͸çѽå×ÄäÙÆëÁ¦à«\8fÑ\99zÍ\91vË\8au¹\7fi\9fuR\93rH\94yR\96yØãîàÄîãÇíâÆëäËìàÃìßÃíÙ½îØ»îØ»îÓµîÔµîÓµîÕ´îÚ¿íèÔéíÚæîáãíçãêîãêíãëîãëíãëíãëíãëíãêîãêîãéîãëíãêîãëíãíìãíëäíêäíéæîæèîäèîäèîåéîãêîáéîâèîãæîäåíæåíçäíééëÕÙ©pÍ\7f;Ñ\85/Ó\87*Ó\87,Õ\8b/Ó\8b+Ô\89/Î\84%Í\80+Õ\8c:íÕ\9eëéÊëèÇíèÇìéÈêìÌèíÏäïÚììÆêã«èÙ\94åÓ\8cãÅkàÄHÚ¾HÖ·6ί;¤\92'¨\93(Á¥5¼¢+Ï°5Ö¶0ßÂOæËbêÏuë×\84ëÝ\92ëä¥íæ±îæ²îá¬ëÕ\95äÁpãÂdëÊuî×\90îÜ\93îà\9dîá íâ îà\9díâ¢íâ¢íá¡íà\9eîà\9dîÞ\9bîÞ\97íÞ\9bíÞ\99îÙ\91îÙ\93îÚ\94îÓ\86ëºi½\839T*\ 3?\1c\ 3?\1d\ 3I&\ 3\3\ 4i2\ 3g2\ 3f.\ 3Y \ 3U\1c\ 3U\1c\ 3V \ 3`"\ 3i(\ 3u0\ 5w-\ 3v,\ 3v,\ 3u,\ 3x,\ 3\834\ 4\9dF\ 5§Q\ 4«Z\ 4¹v\14ä¥Dß\95.Ø\87\1aÔ~\16Ñ\80\18Ó\8f*Ø\9e=â±Mè¼Wê¿Zà²LÛ¤:Ø\9d2Õ 8Õ¢=Ò«JήUÍQ¾\9bD¾\9b@Í®\ϳaƧU´\95D°\91<¿\9fRÌ®Y²\94E¼\9cKÅ¥S®\8f<¨\88:°\90I¥\844©\8a=\8dA§\836§\83-¶\8f<¶\8fA\91c\14],\ 3L!\ 3O!\ 3U%\ 3Y-\ 3W+\ 3M!\ 3E \ 3<\1a\ 33\e\ 39 \ 3Y?\ e±\9dvη\90ÔÄ\9eÖÆ¥ØÈ©ÛÌ°ÝϵßзàкâÒ¾æÙÅëãÍìîÞêîãêîáèíåìíßèÛ½ÑÀ\9e·¥\80¯\9c{¢\8ckèÖ¼æÓ¸çÒ²çѯæЯçÒ°èÑ®èЮçÎêаéϯíÕµìÓ¶íÔ¹îÓ¸íÕ¹îÞÀî×ÁîÑ´îѼîͳëÄÛ´\95À\9czج\8bèÓÂåÖÄäÞÆæÛÄêÔ¸îÈ©ä¥\8aÙ\91tÉ\83h°x^\9byT¢\88b± ~ÕÂ¥ëÚ¿îäÊíäÈëçËéçÐéæÌêãÉìÝÂíÚÀî×»îÕ¹îÒµîÔ¸îÚÁìèÓçîáãíèãëìãêîãêíãêíãëíãëíãëíãìíãëíãêíãêîãëíãëíãëíãíëãëíãìëãíêæîæçîäéîãêîâéîáéîâêîàéîáèîãçîãæîääíåäíçêêÑØ£lÉz4Ñ\862Ò\87(Ô\88.Ô\8c-Ó\8b,Ô\8b-Ò\88+Ð\85*Õ\8e6íÊ\91ìåÄìåÁìæÂíä½íã¼íä»îåºíçÀìêÀëìÆëìÅéíÁëê¹êìÀä×\92èÖ\95èä¹ìè»êá¬íå²íæ²ìè²íëµìê·ìê¾ëç¹ëà®éÙ\9dåÒ\90ÞÅ|Û¹fß²Vã±WëÈsîÛ\91îÝ\97îÝ\95íâ íâ¡íà\9eíã£ìå§ìä¥íã£ìã¡íà\9díà\9díÞ\97îß\99íÝ\96îØ\8fîÛ\91íÝ\96îÑ\82ë¾iÐ\85)v<\ 4>\e\ 3=\e\ 3B\1f\ 3M$\ 3\+\ 3^)\ 3a&\ 3W\e\ 3X \ 3T\1a\ 3U\1d\ 3W\1d\ 3V\1d\ 3]"\ 3l)\ 3i%\ 3f"\ 3k%\ 3k'\ 3n'\ 3u-\ 3\8a;\ 3\8eE\ 1Ï\989Þ\9b9Ü\8a'Ù\84\1fËn\ 5Âh\ 4Äm\vÆs\ eÄv\rÓ\91+æµUé¿]צ<Î\99.Ê\972Ò¤CʤHÀ\9b@º\97Aµ\93<\8d8¾ RË\αc¾\9dQÀ RÍ°cÂ¥Q½\9fO¼\9cMÀ¡P¯\90@\90B©\88=°\8d@\8e9¨\865©\867¨\842¹\91B±\88>\90_\19K\1f\ 3<\18\ 3C \ 3>\e\ 3B!\ 3D!\ 36\18\ 3.\16\ 31\18\ 33\1c\ 39\1f\ 3D)\ 2|e8Àª\81ÓÂ\9fÔà ØÇ©×Ç©Û̳ÝÍ·ßϸáÒ½äÔÁâÖ¿ëàÍëîééíçéîåíìÝçÜÀϾ\9d¹¤\7f·\9f\7f¯\9brîÞÅìÙÀîÛÄìؾíÛ¿íؽíÙ¿íÙ¿îÛÀîÛÁîÛ¾îÛ¿îؽîÕ½îÓ»îдíØÇîÔ¿îÉëĬ껡ç®\8fͤ\7f»\9e{Þ·\98æ×ÀãâÌãêÓãìÓãêÔæÚÂí·\98æ\95{É\8aj³\87c±\98q¿¯\8eßÓ°ìßÁîäÊíäËíåÉëæÊêèÌëåËêäÉìáÅíÜÀíÚ¾íÚÄíÜÂëåÊæîÙäîæãííãìíãëíãêîãêîãêîãëíãììãììãëíãëíãëíãëíãëìãììãììãììäìêåíéæîæçîåéîâéîâêîàëîàëîßéîàêîßéîàèîâçîäåîåäíæìëÔË\94[Éy7Ô\889Ó\8a+Ñ\88*Ô\8a)Ò\89+Ó\89-Î\84%Ñ\85)Ò\880ìÅ\8aíã¿ìæÁìäÀîàºîà·îß·îß´î߶îܯîß±íܧíÜ¥íÞªîã¸ßUà\8e
+êè¬íä¾ìà´ìݯìÚ¥ìÖ¢éÐ\96çÑ\98âÈ\88ßÄ~Ù¾zÒ³cÖªR×\9f8ä¯FíÌuîÑ\85îÛ\93íâ\9fîà\9aîÞ\99íã íâ íã¢îà\9eíá ìæ§ìä¤ìä¢ìâ íâ¡îà\9bíá\9cîÝ\95íÞ\96íß\98îÛ\91îÕ\84â®U¹k\11W'\ 3<\1c\ 39\19\ 3:\1c\ 3A\e\ 3L!\ 3['\ 3j1\ 4d+\ 3S\1c\ 3O\1a\ 3M\18\ 3P\1a\ 3T\e\ 3Z\1e\ 3_!\ 3c!\ 3g&\ 3g%\ 3h%\ 3h!\ 3h!\ 3v/\ 3\8bB\ 2ë³\Ò\83\1aÕ}\17Îr\vÍt\ fÂj\ 5¾f\ 3¸c\ 3·e\ 4Ái\bÅ|\18å·Uß°MÎ\9e7É\988ѨJÇ¢K¸\97>¾\9dN¹\99Gµ\94FعrÙ»nÓ´b¸\98H¼\9bMɪ[Á¢[´\99J¹\9bKº\9bL¯\90C´\95Hª\8a>¹\99K´\93B¶\94J¾\9bM£\800¥~0\9et%\84X\128\1f\ 2)\16\ 3'\16\ 3-\18\ 3-\17\ 3,\17\ 3-\17\ 31\1a\ 33\1d\ 32\1f\ 3;"\ 3=&\ 3X:\ e\9f\86YÊ·\90ÒÂ\9cÕƧÖǨÚ˱Ú̱ÜÍ´ßϺáѼáÖ¿åÖ¿íëÝêîéìîäëãÍßеIJ\8e»¨\83¸£\7f´\9fwîßÆîßÅîÝÃîÞÅîÝÅîÝÂîÞÃîÞÅîßÇîÜÃîÜ¿îÙ½îÕ¹îϳîÊîƧîÊ°íÀªç¹£ãçÛâäÝê¤\8dÆ£\82½¥\82äÆ£ãçÑãìÙãíÖãëÑãèÐçØÁìÁ¥é®\91Ò¨\84ˬ\8cÞÀ\9eéÚ¸îèÉìêÎíèÎíãÇíâÆíâÇëæÊëãÈêäÉìàÄìÝÅëßÃéèÑçìÙãîáãìèãêíãêíãêìãêíãêíãéîãëíãììãëíãëíãëíãììãëíãìëãììãìëãìíäìêäíëæîéèîæèîäêîàëîßëíÞëîÞëîÞìîÞëîÞêîßéîàçîãåîååîåíéÎÇ\8aQÉ{6Ò\863Ô\8b+Ô\8b-Ò\89)Ó\88(Ð\87$Ï\86$Ð\83%Ï\85.ê¸qíß²ìãÃíá½îà¼îßµîܳîݳîÛ®îÚ®íØ©ìÕ\9bêÒ\98ìÑ\96ìÒ\98ã¤Aë\83\ 1èª:æÏ\97äË\93ãÉ\8fàÆ\87àÄ\87ßÁ\85Ùºx׶kÒ²dÏ`Ì\9fLÒ\9a9à\97'ã\92\ fêÂJîÖ\85îá\99îß\9bîá\9fíâ\9fíà\9eîÝ\9aîß\9eíá\9fíâ¡íâ£îà\9bíâ\9eíá\9fíà\9díâ\9eîß\9aîÝ\96íÝ\96íÞ\96îÛ\93ìÉuÕ\96H\9cQ\r?\1c\ 36\19\ 36\17\ 34\17\ 3=\19\ 3D\1a\ 3b/\ 5vA
+h3\ 4X&\ 3N\19\ 3M\17\ 3M\17\ 3W\1e\ 3Z!\ 3]!\ 3c"\ 3f%\ 3f#\ 3f#\ 3h%\ 3i%\ 3j(\ 3y0\0ç«\Ø\89\1fÖx\ fËm\bÄh\ 2»]\ 3µ_\ 3³c\ 3³_\ 3ºf\ 3ºn\f½|\1a¬p\f¶\87\1cÁ\969ϪOÅ\9fFãLª\8c;©\8b;¿\9dUÔ¶nµ\94B¼\9cEˬ]Ê©]½\9eH¬\8f@¸\9cOÀ¢Q»\9dMç]§`ɪe»\9dM»\99L±\8f?µ\94Eª\89=¬\88=©\819xP\ f/\1d\ 3"\13\ 3\1f\11\ 3%\14\ 3-\17\ 3,\18\ 31\18\ 37\1c\ 3: \ 3?'\ 3I'\ 3U*\ 3tD \88`\1d¸¤kι\8bÒÀ\9dÖŤÔŤØÊÝζÞηÞÒ¹ßÒ»ãÙ¾ìæÒëîãîëØéÞÆØǯ¬\87»§\83¶£\82´\9cvîÞÇîÞÄîßÇîÞÆîÜÆîÚÃîÚÂíÝÅíÚÄîÕ¼îÑ·î˯îÉ°íÀ¥î½ î¾¢íÂ«ì± æijãêëãäã黧ǯ\8dʲ\8fêÕ¶ãîÝãîÙãèÐäâÅæÜÃé×»ê×¼îѳíÍ°íÔºíÜ¿ëäÇêêÎëèÌëåÉíâÅíâÆíáÅëáÆëâÈëâÉëäÎééÖãîáãíèãììãëíãìíãëíãëíãììãëíãêíãéíãëíãëíãëìãììãíêãíêãììãìëãíêãíêãíëäíéæîçéîåêîãëîàëîÞëîÝíìÛìíÛíìÛìíÛëîÝëíÝêîßçîáçîàåîãìâÅÈ\8bQÊz0Ò\88/Ñ\87*Ô\8a-Ô\8b-Ó\88+Ò\85$Ï\83\1fÓ\84%Õ\89.è°bîܯíá¾íà¹îÞ¸îÜ´îÜ·îÙ¯îÙ«îשí×¥ëÓ\9dèÏ\98êÑ\97èÏ\92â¡=ì\81\ 2Ýw\ 1êÂdàÉ\8báÆ\8bÞÂ\86ÞÃ\87Û¼}ÚºwÔ±hÐdÍ SÏ\98>Ù\9a2Ý\96!è\8d\ 1ä\8d\0êÈUîß\9bíá¡íâ\9fîá\9aìÖ\8fîÜ\9cíâ¥íâ¢íâ¢íà¢îÜ\9aîß\9cîß\9cíá\9fíà\9aìÓ\8cîÙ\90îÙ\90îÚ\8eîÔ\88é³[Åt#\839\ 4@\1d\ 34\16\ 38\19\ 3:\19\ 3L$\ 3[.\ 3yB\b\7fD
+i5\ 5X%\ 3P\e\ 3N\18\ 3K\15\ 3O\17\ 3T\1a\ 3Z\1f\ 3a#\ 3h&\ 3f#\ 3g%\ 3i'\ 3e#\ 3g)\ 3{7\ 2Þ\9cEÞ\95&Íw\aÄi\ 3Àd\ 3·\\ 3³]\ 3°\\ 3Z\ 3¬Z\ 3®\\ 3µe\a¯p\ 6«y\13Ì¥IÌP½\9a?×¹g´\98C£\84-µ\94FÃ¥Y´\94F·\9aL¹\98E¼\9dM³\95A¼\9eO¹\9aO¼\9fR·\9bRɬd´\94K¸\9aM³\92J¯\8fC\9c{+¥\836«\8a;«\88:¯\86>wL\ f.\1c\ 3*\e\ 3(\16\ 3(\16\ 3+\19\ 3/\1d\ 33\1d\ 3H*\ 3Q+\ 3c;\ 4l9\ 3\81E\ 4\87N\ 5\87P\ 6¤\81IÅ®\80;\94Ï»\98ÓÂ\9eÓŨ×ȯÜͶÚζßѺãÖÀíé×ëîåííÛìäÍ×Ëʶ\99Ƴ\96ñ\93º©\88íÝÇíÝÇíÜÇíÚÆíÔ»î͵í͹îÈ´íÄ®íÀ¬ì±\98ì¯\96í¹¦îÄ°î̱ìÒ¶èÛÃéßËäæÔãîäæßÎæϵʱ\90̵\98ëÖ¶âëØãáÍæиê̱êÒ¶èÚ¿çÜÁêÝÁêÝÃéßÄêâÆéâÆèæÌëâÆíàÂíßÁíÞÁíàÃëâÈëãÅéêÒåîãäíèãëìãëìãììãëíãëîãëíãëíãëíãëìãëíãëíãëîãëíãììãíëãîèãíéãíêãíêãíêãíëåîéæíççîãêîáêîàìîÝííÛííÛííÚíìÚíë×ííÙìíÙëîÝêîÝéîáçîàæîäíßÀÆ\85AÎ\7f*Ñ\86.Ñ\85)Ñ\84'Ð\84!Ñ\84%Ï\82!Ï\84\1fÓ\85"Ñ\85(ã¤SíÒ îÞ¶îܲîݵîܲîÙ¬îÚî׫íרíاëÑ¢èÏ\9açÎ\91èÍ\94à\9f=è}\ 2ês\ 3Ü\82!æÊ\8aßÃ\84ßÂ\80ݽ~Õ¶sسlÑ«^ʤVÈ\9aHÎ\97Dæ·\Þ\9c#æ\85\ 2í\86\ 3ê\92\ 4êÝ\86îà\9bíâ íÜ\99îÙ\96íÙ\95îß\9bîà\9fîá¡îà\9fíâ\9fíß íà\9eîÞ\98îØ\91íÖ\8eîÙ\91îÛ\8fîÛ\91íÐ\84à\9bDªV\at/\ 3L#\ 3R)\ 3^-\ 3p9\ 3}E \90S\11\9eZ\e\8bK\10e.\ 3W&\ 3Q\1a\ 3L\19\ 3M\17\ 3O\18\ 3R\1a\ 3W\1c\ 3^ \ 3b#\ 3d#\ 3e%\ 3h'\ 3d \ 3b$\ 3\88E Ù\955×\8b#Ì{\rÈo\aÂf\ 3¾b\ 3¶_\ 3°[\ 3®[\ 3[\ 3¯\\ 3µg\ 6º\88 ¾\9a6¿\9c@±\912˧NÝÀmÝÃs½\9bH¶\95H¿¡RĨR̯Z©\87/¯\91CÍ®bÈ«\¸\9bJ¶\9aM¼\9fT²\95Iµ\95J\8fA©\8bA¤\867\99x*¯\8dD¢}/©\853ª|1mF
+)\17\ 3-\e\ 3/\19\ 34\e\ 39!\ 3B#\ 3S-\ 3o;\ 3}B\ 3\84I\ 3\8eP\ 3\8dQ\ 5\8cR\ 6\90T \98b#¶\95bij\86˸\8fÉ·\8eο\9bÒÂ¥ÖƪØÈÛͯãÖ¿íëÛêîäëîäíîàèÞÅàÕ¹ÞÔ½ÜÍ´×É«îγìÒ¸ìÒ¹îÆ°í¾¢í»¡ìµ\9bé\97ç©\99å¥\95ä¢\8bâ¨\90ëØÂæêâäíçåîÜãîàãèíãçîçíÞìáÇÌ·\9c¼\9f\83ϵ\9eçÄ¥é̳컥ë»\9eëŦéÒ·èØ¿éÙ¾éÚ¿êÜÂêÚÀëÚ¿ìÝÀëÞÃëÞÅíÞÃíÝÄíÞÅêæËèéÓåíßãíéãêîãêîãëîãêîãììãëíãëíãìíãëîãëîãìíãëîãìíãìíãíìãíëãíëãîéãíëãíéãíéãíéåîçåíççîäêîáëîáìíÝìîÜíëØìîÜíìÙíìØîëØìíÚìíÚëíÛêîÜèîàåîáæïáíÛ¼Í\85LÍ}0Í\7f-Ì\80%Ï\83'Ï\85#Î\85\1cÓ\87&Ò\84"Ñ\82\1eÐ\84(Ü\96AíÊ\87îÚªîÞ±îܳîÙ¯íجíתìÔ§ìÔ¤ìÔ¢êÓ¤éÏ\9aéÎ\95çÉ\96å¦Ièw\ 1êq\ 3ßh\ 2á\951àÃ\7fܾyظuÕµqÓ«eЪ`΢WÆ\98IÓ¡QìËzâ=ä\82\ 2ê\81\ 3ê\86\ 3å\90\féÎhîà\99íà£ìã¥îà\9eí×\93íâ¢íá¡íã£íâ£íã¤íá£îÝ\98îÝ\97íá\9cíá\9bíß\99îÚ\8eîÍ{Ô\93<\8eF\ 2|:\ 3\81E\ 4\88H\ 3\91P\ 5\97R\b¢Y\12\9dV\11\9fY\10\8bP\ fd/\ 3V$\ 3T\1f\ 3P\1a\ 3T\e\ 3U\1a\ 3V\1e\ 3W\e\ 3_"\ 3a#\ 3b \ 3d#\ 3e%\ 3e#\ 3` \ 3¡Y\ eÔ|\1fÌk\rÒ~\19Ál\ 6Èn\bºb\ 3¾k\ 3½m\ 4´^\ 3¶\\ 3ºe\ 4Ãs\10Æ\985ÓµZ°\93;°\8e:ÕµhØ»lÄ¥]·\96H°\90EÁ¤Tдdαaµ\95B¦\8b>¼\9eM´\96G³\94EÁ Q¾¢Q©\8dA¸\98L©\8b<±\91@«\8c=®\8fB²\90F©\849¬\869 t+Z8\ 5=%\ 3B&\ 3M)\ 3[/\ 3m7\ 3s;\ 5\81D\a\85F\ 3\8aK\ 4\8eN\ 3\8cP\ 5\8eR\ 4\8dQ\ 4\90T\b\91W\v\93f!³\9diÅ´\8bÉ·\95ͽ\9b̸\96м\99н ×ɯéÞÄíîÜëîáëîãîìÛéÞÆçÛÄçÛÆç×Äåٿ꾨îË´íçâ©\8eèµ\98èµ\98ß«\90ߧ\95ݦ\95Õ£\8bÜ\92æééëÞãâîããíåèèéíäæéíêìçéßÅѸ\96º\96w»\9b|ʪ\8eå´\9cî\9aíª\98îº\9fì̯êÔ¸ëÔ¹ìÒ¸ìÒ¶ìÓ¹íÑ·íÒ¸í×¼íØ¿ìßÇíàÅíáÊéêÓåíØãîæãëíãëîãêîãêîãêîãëîãììãìíãëíãëíãìíãëíãëíãìíãëíãììãíëãìëãíéãíêãíêäíéåíèäîèåíççîäéîâêîßìíÛìíÜìíÛíìÙîìÙíë×îë×íìØííÚëíÜëîÜèîßçîàæîßæîâì×½Èx=Ìz1Ë}/Î\7f'Ñ\88*Ö\8a-Ò\86$Ô\88'Õ\89(Ó\87*Ò\86)×\8b0ç«YîÏ\96îØ©îÚªíשíרîרîÖ¨ìÑ\9dìÐ\9eêÏ\99êÎ\97çÉ\91çË\96ã«Nçt\ 1ëo\ 3æh\ 3æm\0ß\95/߶kÔµoÔ²hÒ«aË£YÊ\9dSÆ\94@Ó HîÎwçÄaä|\0ê|\ 3í\7f\ 3ì}\ 3æ\8a\0åÒiíäªëèìç«ìå©ìå§íä¨ìä¤íä¥ìå¨ìå§ìä¥íÞ\9cîÝ\97îÞ\98íß\99îÚ\91è¶`Ãt\1e\8bD\ 3\8fM\ 6\9cX \9eY \9cW\b\9eV V\r¢]\14\9eY\ e\8dM\ah1\ 3W%\ 3V"\ 3W\1e\ 3[#\ 3W\1e\ 3V\1e\ 3]"\ 3c$\ 3g%\ 3d"\ 3e$\ 3d$\ 3a"\ 3\\1f\ 3\96N\rÁg\a½]\ 3Æj\bÁg\aÀh\ 3Äo\ 5Är\ 4½g\ 3¸c\ 3¸a\ 3Àd\ 6É{\17Ê\9d7ЯT¤\84)·\97Bΰ_À¡N°\8fC¤\842¿\9eTÁ£ZÑ´jÏ®aª\8b;¡\847¨\898§\89:\8f;¢\840Æ©Z\92D³\96G´\96FÀ¢T¯\8e@¶\96I¯\8fA¬\8a;´\92F\9bt+K*\ 1Y3\ 3uC\v\83I\r\87I\r\83E\ 5~A\ 3\87E\ 3\88G\ 3\8cM\ 3\8cL\ 3\8cL\ 3\8cP\ 4\8eR\ 5\8fS\ 5\8eS\ 5\8eR\a¥z;¬zÇ·\8dǶ\8eʶ\92ɹ\96ÔĬçÜÊíçÒííáìîâíîßíæÒäÛÅãÙÂæÚÃãÙ¿â×¾êɱîÞÅéáÈëçÎìåÉæ̮ۿ ×»\9aѳ\97Òµ\96Ô»\9fáͶíîÜæçìãäíçêäìæËîáÅÞϯη\97Æ¡\86À\96w½\9b|è\8aÔ¢\8bî\9e\94í¨\98íÁªìʲì϶íδîδîͳîζîÏ´îѸî×¹ìÞÁëäËéëÓåïÝäîæãìíãëîãêíãêîãêîãëîãëíãëíãëíãìíãììãëíãêîãìíãëíãìíãìíãìëãìëãíêãíêãíéãíéäíêçîæçíåçîåèîãëîÞìíÞìíÝíìÚíëÙíëØîëØíìØíìÙíëØìíÛëíÜêîßéîÜæîáåîáæîáíÔ·Äq/Î}3Õ\8a6Ô\89,Ô\8c,Ø\8d,Ù\8e.×\8c*Ø\8e(Ô\89&Ö\8b)Ö\86(á\95<è·líÏ\9bíפìÔ¥íÓ¤ìÔ¤ìÒ¡ìÐ\9fëÎ\9céÍ\97çÊ\95æÈ\8däÈ\91ݦLìw\ 2ël\ 3êi\ 3ên\ 3ãr\0á\8b\19ݶOÒ¬^Ч[Ë¢WÆ\9bKÉ\8f3Þ§EïÏtíÕ\81Þ|\0ìy\ 3í{\ 3íz\ 3êp\ 3ê\8e çá\87íã¢ìå¦íã¥ìæ¨ìç«íå¨íã¥íä¤ìä¥ìã¥îÝ\9cîÚ\93îÝ\95íÝ\95íÐ\83×\99?£R\ 3\86@\ 3\8fN\ 4 U\b\9dU\ 3\96T\ 1\95Y \9aY\ e§a\13¢Z\f\92M w>\ 4O#\ 3S%\ 2U$\ 3Z&\ 3\&\ 3["\ 3^$\ 3f(\ 3k+\ 3k*\ 3h(\ 3d%\ 3] \ 3`#\ 3\80=\a¹c\a·\\ 3·[\ 2¿g\ 5Àg\ 5Ãp\ 5»f\ 4¾h\ 4·c\ 4¸c\ 3Ãn\ eÍ\85$Σ@Á¢H£\85-ãM®\8d>\9bx#¤\868«\8eCŦ]¶\95G¿£]µ\96C\8e:¨\878µ\94C·\99KÃ¥T¢\876¤\º\9dP\8fD³\95H»\9aM¤\844´\93D \802\9f}/²\8eB\91k!A#\ 2U/\ 5qC\10\85Q\14\8eO\10\87C\ 4\84A\ 3\84D\ 3\8bJ\ 3\8cK\ 3\8fP\ 3\8eO\ 3\91R\ 3\90Q\ 3\8bO\ 3\8eR\ 3\92T\ 6\97\\14µ\93X½\81ƹ\91̽\96ÕǪæØÅîçÑîíÜííßííÞííÞêÞÌâØÁá×½ã×ÀâÖ¿àÕ¾ëÝÂëíáãæìãäîëíáãÛÀÖƬѾ\9fξ¢Ê¼\9fÕÄ¥åÕ¾éáÈîíØêíÜëÝÆèÈ«àÀ\9eÛ¾\9aÓ³\93Î¥\8bÂ\93|¯\91|©\94|¾\96\82Õ\8f\7fà¤\8bë½ ë¼£íÇ°îɵîÌ·íξíѾíØÄìàÍéèÓæìØåîßäîããíêãìëãëíãëíãêíãêîãêîãêîãëîãìíãìíãêîãìíãëîãìíãëíãììãìíãììãììãììãíêãíêãíêäíéçîæçîåçîäéîâëîßíîÜííÛííÛííÛíìÙííÛííÛííÚîìØìíÛìíÚëîÜéîßèîáæîâæîßçîßéαÆx:Ñ\832Ö\8c2Ù\8f.Ù\91.Ü\92+Û\92+Þ\92-Ü\91,ß\911Ù\8e.Õ\88,Ù\890×\8c:ݧeèÇ\8dêÏ\91ëÎ\98ëÎ\9cëÍ\9aëÏ\9céÌ\96èË\95èË\95èË\94âÇ\90åµ]és\0ëi\ 3êg\ 3ím\ 3ís\ 3éj\ 3ã~\ 4Ü©4˦SÉ VÅ\98DÌ\917á¥FìÍvíß\91Ü\8e\19ëu\ 3ëu\ 3ìw\ 3ën\ 3ì}\ 2ë\96\båÏyéç©ìå«ìã¦ìæ¨ìã¦íâ¤íá ëç§ìâ¥îÙ\98îÚ\93îß\98îÜ\97íÓ\86Ì\916\95N\ 3|9\0\8bW\ f¾\8d=à¸kìË\80êÉyز`Å\93?\9da\15\88G\ 3\80B\ 3m8\ 2\86Y\13\80O\ fP"\ 2G\1e\ 3S \ 3]$\ 3i)\ 3o.\ 3q/\ 3p.\ 3o(\ 3h&\ 3c%\ 3n-\ 3±d\v±\\ 4µ^\ 3·e\ 5±]\ 3Âv\r¼j\ 3»j\b·d\ 3Áf\ 6Âr\ fÌ\85 Ï¡D¿¥Jª\8b5Ç¥P²\91B\9f}-¦\86<\90G¨\89=·\9cRÇ«bµ\97G¶\98I \82/¯\90?°\91G³\95G©\8d<º\9aQ½\9fU°\95Kº\9aNº\9cL°\92=±\91?\9ax%©\868©\88;vU\13?!\ 3B"\ 3L(\ 3i@\ 4\85M\b\8eL\ 4\8fN\ 4\8eN\ 3\8cN\ 3\8dM\ 3\8aK\ 3\8dN\ 3\91R\ 3\89L\ 3\88L\ 3\8aO\ 3\8fR\ 4\92V\ 6\95e »¤qĺ\8bÙͦêܾíçÒîêÕîìÙííÜîíÜíéØã×¾ÞÓ¹ßÔ¼áÖ¿àÔ½áÕ¿æܾêëæâäïçéêêåËÛϯÒÀ¡Ò¼\9eк\9dÑ»\9fáÇ©ì׺íØ¿íÝÀèάåÃ¤ä¾ æÀ\9dà¼\99Õ³\95Ä\9a|¤~e\82v]\8d\81e«\8cp¸\8ck¼\96tÅ\9e}Õ©\87ݯ\92á·\9aëèîѹíàÆèêØåîãäîåãíçãîæãíéãíéãìëãììãìíãëíãëíãëíãëîãìîãëíãëíãëíãëíãëíãìîãìíãìíãìíãìíãìëãíëãíêãíëåîççîæçîäçîäèîâéîáëîÞíìÛííÝíìÜíìÚìíÜíìÛíìÚííÛíìÛìíÜëîÝêîÞêîÝèíÞåîâæîàæïáèʪÇy8Õ\84/Ù\8e3Û\901Ü\930Ü\92,Û\92*Ú\91)Ù\8f(Ù\8b%Ø\89(Ø\89/Ø\87+Îz%¼p'Ì\94Qá¶nåÃ\81êË\91éÌ\94éÌ\91éÍ\92çÊ\90çÊ\91åÉ\8fãÅ\8bëÂrãx\0ëk\ 3ìh\ 3ëg\ 3ìl\ 3îq\ 3ël\ 3ßs\ 2Ù\9b'É EÃ\99HÁ\891Ð\8f%îÉpîÜ\8aà\9a.ëm\ 3ëp\ 3ìz\ 3ës\ 3îy\ 3ës\ 3ã\8d\ 3ç¤1íËoìÙ\94íä¡ìå¥ìå§íã¡ìå¥íã¤îÞ\9eîÞ\98íà\9aîØ\8cèÂk½\7f#\86K\ 2̧YïÐ\86êÌ~èÒ\8dìÜ\96êËxèÇvçÅpåÀiÉ K\81I\ 5\8bQ\a¹\876¼\821pA\ 5Q.\ 2oG\v`5\ 4a.\ 2_,\ 3_'\ 3g-\ 3o.\ 3g'\ 3h'\ 3c%\ 3ª^ ²Z\ 3®[\ 4°a\ 4®_\ 3µh\bµi\ 5Ät\11¿s
+¹h\ 4Çs\ eÌ\82\1e׬MÇ«S¢\83*¢J¾\9fJ\99{"£\832§\89;ª\8bA¾¢\É^¿\9fMäV³\94F´\97J°\91G°\92K®\8fE¹\99N±\92E¯\8eDª\8c<¾ Q®\8f:©\88:\95t)\9f}3¦\7f3jH\ 6B&\ 3H(\ 3H"\ 3P)\ 3j9\ 3\82E\ 3\90O\ 4\91S\ 4\8fP\ 3\92Q\ 3\8fP\ 3\8fP\ 3\90Q\ 3\90Q\ 3\8dP\ 3\8eS\ 3\90U\ 3\8eR\ 3\89R\ 4¤\86GØϧêÞÃîèÓîèÔîê×îëØîìÚîíÛëáÎÜ̲ÝÓ¹ÝÔ»ÝÓ½ÝÒºÝÔ¼éÑ°îåÉíî×îáËåѺßťܾ\9eÛ½ Ý»\9eß½\9eäħëÆ©ìħ黣èº\9eä¹\9aì¾£éº\9cæɦÞа\99\84_\82kGh]B\83tX¥\8ah£\8afª\93x\93m¹\9atÁ¥\82Í·\9cèʲîÞÆíêÕèîãåîçãíèãîéãíçãíëãíëãììãììãììãêíãëíãêîãëîãëíãëîãëíãëîãìîãìíãëíãìíãëìãëìãììãíëãìëãíêæíçæîçèîãéîâèîâéîáëîÞëîÞíìÛíìÜíìÛíìÜîëØîìÙííÚíìÚìîÝëîÝêîÞéîàèîàéíÝçîáåîâçïàåÄ\9eÆy5Ð\83/Ô\89/Ó\87+Ò\86(Ô\8d$×\8d%Ø\8b)Ö\86\1eÓ\83\1aÑ\81\1eÓ\81#Ñ\7f\eÐ}"´f\18¦a\19Â\80;Ó\9cTÚ§gä¸}ß½}ãÅ\81æÇ\89äÇ\8cäÇ\8bãÆ\83æÃ\7fá\8e\17ím\ 3ìj\ 3ìe\ 3ìj\ 3în\ 3ín\ 3ìn\ 3âo\ 3Ô\91"À\96=¿\8b0Ø\9a/îÏvîÛ\8bÝ«Båi\ 3êg\ 3ìn\ 3ìq\ 3ër\ 3ìr\ 3íz\ 2ìw\ 2í¥\12ä¯Cã¼ièÔ\8aæÕ\8aåÕ\8eíâ\9fìá\9cíã\9dîá\99îÜ\92ìÊpà£FÃ\831ìÎ\83éË\7fêÊ|ìÎ\80îÐ\80éÛ\93ìÍ}éÊwèÈqçÅjà½bâ½_¯\80&º\7f*¬k\19\89O\ 4\8cU\ 6©n*¥m)¤q+~Q\ fD\1f\ 3F"\ 3R"\ 3X#\ 3c(\ 3k+\ 3¢S
+¸` ¨U\ 3¦V\ 3¨X\ 3©X\ 3ªZ\ 3±c\ 6¹m\f²c\b»j
+½w\16Ý´UÅ©QĤT¼\9dJÈ©S§\879¦\87>¦\858ª\8b@Â¥^¾\9fUÀ\9eOÅ¥YÁ¡S·\9aL§\898§\8b9·\96G«\8dH«\8bA³\93J \7f6°\93D¼\9bL¤\847\91n\1d©\85=\9br'[1\ 1Q,\ 3O,\ 3N(\ 3O+\ 3S,\ 3yH\ 3\92U\ 6\93T\ 3\90R\ 3\8eO\ 3\90Q\ 3\90Q\ 3\8fP\ 3\92S\ 3\92S\ 3\90V\ 3\92W\ 5\93W\a\93W\v\95d\1fÚÆ\97íâËëáÍîèÔîèÓîê×îìÙîíÙêâÍÙÌ´ÛÒ¼ÚиÜÒ¼ÜÒºÛÓ¹ã¹\9fã¿¥éÆ®èÅêÇ°éÁªä¾¥à¹¢à¸¡à¶¡ä¸\9eè¸ ä²\99ä¯\9bÙ¦\8bÛ®\92í¬\94è \7fèÞ¾îòâ\9c\91q\82w[tkQ¦\8fwª\91w¥\8fv¨\95y´ \81Ê·\99ÔÈ«ãÙÅëßÌîéÖîì×íìÝëîáéîãæîåäîåãîéãíëãììãëíãëíãêíãêîãêîãêîãêîãëîãêîãëîãëîãëîãëîãìîãìîãìíãìíãíëäíéäíèçîåçîåéîâéîâêîåëîßëîàììÝîëÛíìÜííÝííÜíëÛííÝíìÜìíÜìîÝêíßêîàèîãæîâçîâäîäåîÞåïáâ¾\98Ât5Ï\801Ð\85/Ñ\84*Ñ\85&Ð\84\1fÐ\85 Ð\84!Ó\83\1eÐ\81\eÏ\7f\18Ï~\19Ìy\17Ìx\1c¼h\14¦X
+¢^\14¹q.Ã\81=Å\86DÓ¡_Ï\9fWÛ¬iÚ³pß·{á·vàº~ç°Mêv\0ím\ 3íi\ 3îi\ 3ìh\ 3ík\ 3îl\ 3ìl\ 3ãm\ 3Ñ\85\ eÀ\87\eã¡8îÉqîÔ\86â·Jåj\ 1ëh\ 3ël\ 3ìl\ 3ío\ 3ëo\ 3ìp\ 3ìo\ 3ê\80\ 2ì¹Hã¼gåÀuá½näÁpäÂqçÅsã¿gçÃmêÅoà§GÓ\926îÌ\80ëÌ\81êË~ëÑ\83íÐ\81íÑ~ìÎ~êËvéÇqéÊrèÇnäÃhãÄbܯL«p\12\98R\ 4\8fM\ 4\9f_\ 6¯l\19»w'¾\7f2±r"\86M\ 6o<\ 6Y'\ 3I\1e\ 3K \ 3P#\ 3z@\ 5©X\a¦U\ 3¤S\ 3¤R\ 3£R\ 3£R\ 3§U\ 3¬]\ 3±]\ 5ºe\bÐ\88#Þ¯PÁ¡IÁ£P·\9eL»\9dL¥\856¯\8fE¼\9eZ´\97P¯\91B¯\91B¶\98I´\97H£V¦\888¤\84/¨\8a9¯\92B¤\88A°\95Kª\8b=\92q%\9f}0¥\846\96u)\99u%§\800\89]\11W/\ 3M,\ 3N,\ 3Q,\ 3P-\ 3m?\ 3\8fW\ 5\9a]\ 5\94U\ 3\93R\ 3\90Q\ 3\91S\ 3\90R\ 3\93U\ 3\92T\ 3\8fQ\ 3\91V\ 4\95Z\ 5\91T\ 6\95U \95Z\11¥\81CãË£Ö îâÌíèÔîêÙîëØîéÕíçÓÜÓ½Øλ×θÚÑ»ÚкÛѼ×\92ยà¸\9dà¸\9eã¹£â·\9fß²\9cÛ²\9bÖ®\95Ò¦\8fÍ \85È\9c{Ã\96\80¸\8ev¤\82_Ï\8fuäDzãæßãèæééÞ¥\88n\95\81i©\94}Ê«\91·\9d\86½©\94Ǹ¡ÝÍ´éÛÇíæÍîë×îëÖîì×îëÖíìÛîíÜííÞêîáçîäãíçãíéãìíãëìãëîãëîãêîãêîãêîãêîãêîãëîãëîãëîãìîãëîãëíãìíãììãííåîêåíéçîèèîæéîâêîâêîâëîßëîâííÝííÝíìÜíìÜíìÝìíÝìíÞííÞìíßìíßëîáêîßéîáèîãæîããîæäîååîáèîàܵ\87Ãv4Ò\843Ò\872Ò\87)Ñ\87&Ó\86(Î\83!Î\81 Ì}\14Ð\81\eÏ\7f\19Ì|\16Ìw\13Ês\14Äp\12Ân\13¬]
+\9cX\v«g\1cºx3¹y3·w-º~4À\826Ä\86>Ç\8dBÃ\8e@Ì\92Bá\7f
+ín\ 3íh\ 3ìe\ 3íe\ 3íe\ 3íj\ 3în\ 3íp\ 3ãg\ 3Ùv\ 4Ö\88\16ìºTìÍsïÏrÝf\0èd\ 3çf\ 3ëm\ 3ël\ 3ëk\ 3êj\ 3ìt\ 3í|\ 2ì¨+â»kà»kã¾oåÁmçÄoçÆuåÁjå»[à©Fä¦BìÅjêÍzìÌ\80ìÌ\7fìÎ~êÊyëÌ|ëÌzëËxéÈmêÇnéÄeèÅfãÀXØ?Õ¤7ªg\ 5°c\r°d\v´m\16µm\e²k\17¦^
+¥_\ f£X\10¡R\ 6\8fE\ 4\81A\ 3q;\ 3y>\ 4¥V\ 4¢R\ 3¢R\ 3\9fP\ 3¡O\ 3\9eJ\ 3¨S\ 3®]\a³]\ 5º^\ 3Ð}\eߧKÀ\9eE»\9cF·\99G¾£X©\8a@ª\8b@Á£[½\9dS£[¶\99IƧVĤU¾\9eK³\96F±\92A·\9cP¢\818¢\833\90D¥\833\95s!\95t"\9dz)\9f{)´\87:\9fm\ek?\ 5J(\ 3J+\ 3K*\ 3K)\ 3l;\ 3\8aO\ 4\9b\\ 4 `\ 5\9aZ\ 3\96V\ 3\94T\ 3\96V\ 3\94U\ 3\97W\ 3\94X\ 3\92U\ 3\93V\ 3\97X\ 4\95W\ 3\94U\ 3\95X\ 5\97a\11Å\9dfÔ¼\9dëßÇîèÔîê×îëÚîëÕîéÔÞÓ»ÖͲ×ζ×Í·×͵×ʹâ\87Ó±\9aɬ\94Ω\90Ê¢\8eǧ\97Ã\9e\85·\97~³\96}«\8fp¤\89q¢~a«z`\8ciI\86`DÖynãÕºãâðãê×ä©\9b©|fº\95\80×\9b̬\95Ê· ÖÊ´çÛÉíåÐîêÙîìØîíÛííÙîíÜííÝîíÜííÝííÜîíÜëîâèîåæîèäíëãìíãìíãêîãêîãêîãéîãéîãêîãëîãìîãìîãííãííãìíãììãíëãîìåíçèîåéîæêîâéîåêîáëîáìîàëíàíìÜîëÚîêÙíìÜííÝíìÜìíÞìîßëîáëîáëîãéîáèîâèîääîæåîäåîäåîãéïÝÚ¯\83Ât3Ð\822Ð\84*Ð\86(Ò\89)Ó\87(Ð\85 Ï\83"Ï\84\1eÓ\84\1eÓ\84\1fÒ\83\1eÒ\81\1cÑ\7f\1aÍ|\1cËv\15Ép\15²^\ 6\9aS\ 2\9e[\f¥e\15±o'²q'·w&¶x(·v(³t\18±s\1cÁw\11êt\ 3íl\ 3íh\ 3îe\ 3íb\ 3íd\ 3íh\ 3íj\ 3ín\ 3âd\ 3Ýu\ 3å¢"ç»Nì×}Úu\aèc\ 3èd\ 3èf\ 3ëo\ 3èg\ 3ég\ 3íy\ 3íx\ 3ë\88\ 6ê¹QäÁoå¾gçÀhçÁgçÂjå¼^Þ¬GØ\950ç®LíÏ|êËzëÍ{ìÏ\7fëÌzêÊvëËxìÌyêÉuéÈméÈpèÁbæÁ\ã¸Lß±>ب8¿\88#³l\ f·k\f¶m\12¶m\14±g\ f°e\12®d\14²e\eª\ _ ªa\v§`\a§]\aª[\ 6£U\ 3\9cL\ 3\9dO\ 3\9cM\ 3\9fP\ 3£T\ 3ª[\ 6³a\ 5»b Åf\ eÏ\946³\904¶\98Eɯ`ÚÁpÓ¹p«\8dC»\9aO®\8f>¼\9eX¼\9fP̱dÒ¶mʨ[¸\99J¾ S°\92J¢\82;§\8bD¬\90F¢\823\99z.\9d\818¨\8b=¡{&\9cr#\88Z\bV.\ 3I*\ 3J(\ 3P*\ 3k<\ 3\8cL\ 4\98W\ 4\99Y\ 3\99Y\ 3\9b\\ 3\99Y\ 3\98X\ 3\96V\ 3\98X\ 3\99Z\ 3\98[\ 3\9a]\ 3\96Y\ 3\97Z\ 3\98[\ 4\99Z\ 5¡f
+¨k\13¤u+ϸ\91äÜÆìâÐîéÕîéÖîéÕîèÔßÕ¿ÕÉ°×̵Õ̵ÚѺ×η¢\8dt¢\87u¦\94w©\98|¹ª\8fàà×ÙÓì\9d\80®\9f\85µ§\89§\92s¢vW¦gM\87\;\8dV=ÒjSä´\88ããÐãçÂ罦ڮ\8a庡îƳÝįå×ÅìäÐîèÔîêÓîêÖîì×íìØîìÙíîÜîíÝîíÝííÝîìÚííÞíîÞìîàëîãéîææíëäëíãìíãéîãêîãêîãëîãííæîêçîêèîéçíéåíìåíëåîëåíêæîçèîçêîäêîäëîáëîáìîàëîàìíàìíßíìÜíìÛíëÛíìÜííßìíßìíÞëîáêîáëîâêîàèîâæîææîåäîæäíæåîääîåéíÚרwÂq.Ë}*Ï\83/Ó\89.×\8c/×\8b,Ö\8c'Õ\8a)Ô\87&Ó\84\1eÔ\85\1fÑ\81\1cÓ\84\1cÕ\85\1eÒ\81\1fÎ|\1dÍy\1cËu\1d½k\14] ¦X\a\9bS\ 6\9bW\r\9bY\b¡e\11¥g\18¨m\10¤k\11¦n\10×z\ 5îo\ 3ìf\ 3ík\ 3ìe\ 3îg\ 3íf\ 3íe\ 3íl\ 3ïr\ 3äj\ 3Ùr\ 3ç¤)êÅUÞ\9f%â^\ 3éb\ 3ëg\ 3êl\ 3éi\ 3êc\ 3íq\ 3ìt\ 3ìx\ 3ã\8e é½\ã½bæ½dç½eâ»Zá´LÞ¨A×\9a5îÊrêÊuêÈréØ\93ëÍ\7fìÍzìÍzìÌzêËvéÊrçÄgèÄgåÀ[èÂ[ÞµFÛ°=צ1Ô\9f7³m\b¼n\ f»p\13¹n\15¶k\ fe\r¬f\10¯e\11¯g\ eb\b¯c\vc\a®a «]\ 6 Q\ 3\9cK\ 3\9eL\ 3\9fO\ 3\9cL\ 3¥V\ 3¨Z\ 4´e\ 6³^\ 4µ[\ 2Ñ\8e4¶\947¯\8e7ΰ\×¼ißÄw¸\9dU¾ ZÁ¢V¼\9dX±\96M¸\9eVÀ¥_¢\835¶\96D»\9dK¯\91Gª\88@¬\8eEÁ¢Z\8c@¡\814¨\8b@«\8b:ª\81-\98l\e~Q\bT-\ 3S+\ 3d4\ 4zE\ 3\94V\ 4\99Y\ 3\9a[\ 3\9a[\ 3\9b\\ 3\9b[\ 3\9b[\ 3\99Z\ 3\9aZ\ 3\9d_\ 4\9a[\ 3\9b^\ 3\99]\ 3\99\\ 3\9a]\ 3\9a^\ 5¦h\13ªp\16«r\1cªr"¾\95Q×Æ\9eçÝÁíçÑîë×îêÖîéÕéáÌåÚÇäÚÇçÝÌåÛÉåÛÊ\9e\93v\96\89l\9c\91t\9e\92sż£ëêìéê枧ÓÄ«Ý̶̳\9a©}a\93\=\7fX:\88T6ÁmTé\92zãѼãïäãäÌæçÔæáÍäãÕîâÍîêÕîéÖîêÕîêÕîëÖîìØîìÙîìØííÛîíÞííÜîíÛîíÛîíÜîíÞîíÜíîßíîßëîäèîéåíìäíîäëíäííæîêêîæëîãìíãìîâëíâëîâêîäêíäêîåèîæêîãêîâìíàìîßìíßìîÞìîßííÜíìÙîë×íëÚíìÙìíßíìÝìíÞìîáêîãêîãéîäéîåçîèæíæäíçãíèãîçäîååîäéíÝÓ\9fjÃm'Ê|0Ó\883Ó\8b/Ó\8c+Ô\8a$Ô\8b$Ô\88'Ð\83\1aÏ\81\1aÏ\81\1dÕ\86"Õ\87#Ò\82\1cÐ\80\eÒ\7f\1fÏ\80\1eÏ{\1cÑ\7f#Éw\17¿m\ e¸f\ e®a\ e\9dR\ 3\94M\ 3\8eO\ 4\85N\ 2\82L\ 3\89O\ 2\99T\ 3ës\ 3îj\ 3íg\ 3íe\ 3ìd\ 3îe\ 3îf\ 3íd\ 3îi\ 3ì{\ 3éj\ 3Ùm\ 4æ¥\1eì½5Ûc\0ãV\ 3é[\ 3êl\ 3íq\ 3êk\ 3éi\ 3ìo\ 3ìq\ 2æ\99\vç .ç¾dã·[à´Yß²VÛ¬Eؤ=âµQëÊoêÉsëËvíËzìÍyìÌwíÑ}íÏ\7fêÊråÄeäÁZä¼Sà¸Lã»O߶Há¾MÚ»UÔ 3¼|\18¼o\14¾p\12¹o\12¹j\ f»n\14¸k\ e³f\f±e\v±e\f°d\v¬a\ab\ 5_\ 5 Q\ 3\9eL\ 3\9dO\ 3\98H\ 3\98K\ 3¤T\ 3¨Z\ 6¬\\ 5\\ 5³b\ 6Á\81$½\95>²\93>Æ¥VÌ°dдkº\9eS¹\9dPÍ°l¼\9e[\81g\1e\8ex,\90?¶\96GɨZËaº\9eUª\8d@¶\94G¸\97K²\92Fµ\90A®\885§\844¦~'\81X\ab8\ 3Y1\ 3sA\ 3\93Y\ 6\9b^\ 6 \\ 3\9f_\ 4\9e]\ 4\9d]\ 3\9e]\ 3\9e`\ 3\9c]\ 3\96X\ 3\9d_\ 3\98[\ 3\97[\ 3\98\\ 3\97[\ 3\9b^\ 3\9a]\ 3£h\b¯q\16´v\1dµw"²t"«r%Îs×̬çßÆíçÐíçÓîéÕîéÙîè×îç×îè×íæÕîçÖ¹¬\8fÁ²\95Ƚ ¼²\9aÛÕÅååæææèßÛÌÜ˱à˲ػ¡´\87m\97eF\8cgD£\80^ß·\96åÝÃãéëãçîãåìããçãæêãìèçîáëîÝìíÚíìÚîíÙîíÙîìÙîíÙííÜîíÝííÝííÜîíÜîíÝîíÝííÞííÞîíßííàíîâìîæëîåêîçëîçëîäìîãììáìíâìíàìîáìíÞìîàíìÜìîßííÝìíßìîßííßííÞíîÜííÛíîÛííÛîíÚîíÙîëÖíìØíìÛííÝìíÞëîáëîãêîåèîæçîççîçæîçåíèãíèäîçãíèäîçäîåëì×Ë\9ac¾l)Ë|0Ð\85.Ð\84+Ò\88*Ï\85&Ï\86#Î\82 Î\81\1eÌ\7f\18Î\80\eÕ\87"Ö\88$×\8b'Û\8d(Ý\8d-Õ\86&Ó\82!Ò\82!Ñ\82!Î\80\1eÈz\19Áq\12Äp\12Àp\14¹h\f¯c\a§\\ 6£[\ 3 X\ 5Òn\ 4íi\ 3ík\ 3íg\ 3ìc\ 3îd\ 3îb\ 3îc\ 3îd\ 3ís\ 3ì}\ 4éh\ 3ãs\ 3á\92\ 5á\83\ 5æV\ 3çW\ 3èb\ 3êj\ 3êi\ 3çf\ 3ìo\ 3ëm\ 3ê\88\ 4é\94\ 3ã\9b.à®MÞHÛªFÝ©CØ¢;éÂbéÆlêÉtëÎzëËtëÊsëËuìâ\96îÒ\7fçÅiæÄgäÀZâ¸Hß´DÛ±AÝ°Aש8Û¶EÒ¡5¿\82\1f¸l
+¶l ¶k\ e¹l\10»n\12¼o\11·l\ f´i\r´h\ f±e\b¬a\ 5¬`\a¬a\ 4§\\ 5\97H\ 3\9cN\ 3\9aM\ 3\9eO\ 3¢T\ 3\9fQ\ 3¤T\ 4§W\ 4±a\f»{\1c¾\98B¦\864»\99LÄ£V½\9cM°\92F²\95J¼\9cQ½¡[¹\9fV¦\8a9¤\855¶\95K«\88:º\99Kº\9dS²\92Hº\98P§\8bA£\815®\853\9ey-\9fy(\89b\fd9\ 3rA\ 4\90V\ 5 b\ 4\9e\\ 3 ]\ 3 ]\ 3 _\ 3£b\ 3 _\ 3\9e_\ 3\9f_\ 3\9a^\ 3\9b]\ 3\9b]\ 3\9d_\ 3\9c^\ 3\9c^\ 3\9e`\ 3\99]\ 3¥m\v¯s\12²u\18²v\18²v\1f¶x!³t"¶\84;ÒÄ\90Ô˱çßÌìæÕíèÒîè×íèÖîêÚîéØîêÙîéس\98ÔÄÔǫ̽ ØйéééããâææàÚ˶ÛÆÔ¹\9bÏ\92̧\89Ö¸\97éÖ»ééÕãìêãåîããêããããããããâããåãåìäéìæìçéîéëîåííÞííÚííÝíîÞííÝíîßííÝííßíîÞíîßííàííáìíãíîâííâìíâìîåìíäííâìîãíîâìîãëíäíîáììßíìÛíëÛîëÛîê×íèÔîëÙîëÙîíÜîì×îíÚííÚîîÛîíÚîíÚîíØîë×íëØììÞìíßëíàêîãéîåéîåèîççîçæîææíçæîæäíèäîçäîæäîæäîåêêÓÍ\92bÆw5Î{-Ì\7f(Ì\80(Ð\85,Í\83$Ñ\86&Ô\89(Ñ\87 Ð\84\1dÔ\88\1fÖ\8b&Ú\8b(Ø\8a&Ü\8e+Ú\8c)Ú\8c+Ù\8b*×\88&Ø\88&Ø\8d1Ö\87&Ñ\82!Ì{\19Éz\19Æt\10Ão\ 6Äq\ 5Ær\aÁp\aÆp\ 4ãm\ 3ëh\ 3îj\ 3îi\ 3íf\ 3ìc\ 3íb\ 3íe\ 3îi\ 3ê\80\ 4ê{\ 5êg\ 3év\ 3é\80\ 4âZ\ 3æS\ 3å\\ 3èe\ 3êi\ 3êh\ 3êj\ 3ís\ 3ìq\ 2ç¡\fã\83\ 2ä\9e+Ù¦9ئ@×\9f9Ö\9e2ëÃeêÅkçÂgêÆpëÉpíÌxêËrêÑ\7fåÄeæÃ]ä¿[å¿Xß·HÜ°Aܯ=Ù©4á²?Ô¤1Î\9b-Å\8a$´i\b¦a\ 5µk\rµj\vµj\v¹l\ f¸k\10µj\v¶k ¶j\v¶j\fµg
+µg ®a\ 6\95E\ 3\8fE\ 3\8fH\ 3\98M\ 3\98P\ 3©^\10¥W\ 6¢O\ 3]\ 6¿|"\890£\840½\9eJ¿\9fHÀ\9fH°\8f@²\94D¾\9eSŦXÌ®^½\9dN¯\8fAª\89:\97t\1f¦\867·\98P®\8fA¶\95J \816zU\ 4\93o\15\7f\\byL\ 3zE\ 2|G\ 3\8fP\ 4£a\ 3¥c\ 3¡a\ 3\9d]\ 3¢`\ 3\9f_\ 3\9d\\ 3\9e]\ 4\9d^\ 3\9fa\ 3\9fa\ 3\9d_\ 3\9c^\ 3\9b^\ 3\9b]\ 3\99[\ 3\9e_\ 3¦j\b¯t\15³v\13´w\e²w\18³x\1e±w\1d®r\1c¬p\1eà ZÎÅ ÙѼëãËìçÐîèÖîèÔîêÚîéÙîè×îéظ¦\8c¼ª\97ö¢È¼ Ǻ¤ßÜÕããåäàÖÞ̳ç̼ëÔÁìÚ¿êâÇçêØäîããîèãìëãçìãåëããçããæããããããããâããëäåíäêíåëíéîéìîßìîáííßííßìîàíîßííàíîáìîâííãíîàìîâìîäìîåíîäëîåëîæííãìîçìîäëîèìîçíîãîëÜîëÜîéÖîê×îèÕîèÕîçÓîèÕîêÕîìÚîëÖîíÛîìÚîíÚîìØîìÚíëØííÝìíÝëíàëîáêîãéîåèîææîèæîèçîéçîæäîçäíèåîååîääîååîäëéÊÉ\89WÆw3Î\7f4Ó\873Ô\8a2Ð\85+Ó\8a+Ô\8a-Ð\84%Ô\87(Ò\87$Ö\8b&Ú\90.Ü\8e,×\88&Ú\8c'Ù\8b'Ù\8b'Û\8d)Ø\8a&Ù\8b(Ø\89&Õ\87"Ñ\82!Ò\83#Ï~\1eÍ|\1cÈv\10Èw\ eÃu\bÇx\ 6Áv\ 4Øz\ 3ìi\ 3íh\ 3ìg\ 3ìe\ 3ìe\ 3ìb\ 3îe\ 3îh\ 3ío\ 3êo\ 3êt\bê{\ 5êg\ 3æl\aâM\ 3çR\ 3ç`\ 3ée\ 3çc\ 3èh\ 3êm\ 3ëq\ 3ë}\ 6ê\88\ 4à\80\ 4Ù¡*Ô 7Ô\9b.Ô\9c.ìÄfêÄdêÄiêÅmìÇoéÇmêÇhæÃcèÄdå¾Xæ¿Yá¹P߶MÙ¬=Ø©7Ó¥2Ô§9Î\98&Ë\95(Æ\8c&´o\11µq\r·l\10»n\ f¸l
+¹q\ e½q\15Às\15¾r\ f½p\11½o\10¼n\10¹l\ e·i\f Q\ 4\89@\ 3\8cD\ 3\91H\ 3\8fH\ 3\99P\ 3\9cQ\ 4 P\ 3«]\ 5À{ °\88/«\8b9µ\92?»\9bJÈ«[°\91D\9a|+¿\9fXÕ¸r³\95F§\874©\89:¯\8e@£\80/\9ax(¥\833²\96I\8f=_G\ 3wS\ 5\99p\1ewN\ 3\88R\ 3\96T\ 3¡`\ 4£c\ 4¦e\ 4¤d\ 3¢b\ 3¦e\ 3¨f\ 4£c\ 3£d\ 3¥d\ 4£b\ 3\9f`\ 3¡d\ 3\9fa\ 4¢d\ 3\9a]\ 3\9a^\ 3\9a`\ 3¬o\ 5®r\v²u\ e²s\10³w\15²y\19³y\1f·{"²v\1fp\e¬y,Ñ»\8bÔʱàÖ¿íåÑíæÔîçÖîè×îèÖîêØîéÖ´¤\88£\92y¬¡\8fÀµ\99½¯\9a¿¯\9eÍ¿ªàϾëØ¿íâÒçéÛãîßãîæãíèãíåãîÞãîããîêãíìãììãéíãäìããêããæããçããêãäíãæîåëêèíçêíáëîáëîåëîäìîäìîåíîãìîäìîãìîãìîäëîçëîæëîæìîåëîæëîæëîçìîåìîäííâîìÞîêÛîêÛîê×îèÔîçÓîçÔíåÑíäÍíåÎîçÑîéÓîìÙîíØîìÙîë×íìÚîëÙìíÝííÜëîáêîâéîæéîåæîéçîçæîèæîéæîæãîçäîæåîæåîäæîãåîãíæÆÄ\85MÉ{9Ï\863Ó\880Ó\890Ó\88/Ó\89-Í\83%Ð\84$Ï\82"Ò\85%Ó\87&Ñ\84#Ó\85%Õ\86$Ô\85!Ø\89$Ø\8a&Ø\89&Ù\8b'×\89&Ô\84 Ò\82\1fÕ\87%Ô\84\1fÖ\87$Ò\83\1fÔ\83 Ñ\7f\18Ë|\10Ë{\fÉ}\ 6Ì}\ 5äu\ 3ë`\ 3íe\ 3íf\ 3íe\ 3ìa\ 3îe\ 3ìb\ 3ëc\ 3êf\ 3ç}\fãy
+ìo\ 3è\81\báP\ 2åO\ 3ãY\ 3ée\ 3éf\ 3çc\ 3ël\ 3éo\ 3él\ 3è\8f\bä}\ 3Ù\88\fÖ\96\1fÏ\96*Ð\92#è¼YèÀ]èÁaéÄeçÂdéÄcçÂ`åÁ[çÁ`æ½Wã¹QÝ´FÙ¨<Ø©;Ó¡2Õ£6Í¥:Ì 6Æ\91'Ä\8b#»r\15Áp\rÂp\14¿p\14»n\ e½q\11¿p\11Àt\10¿q\11¿s\10»o\ f¼m\ e¿q\14¼m\10²a\a\8eA\ 3\88A\ 3\86<\ 3\8eD\ 3\92J\ 3\94L\ 4\9aO\ 3¤W\ 5½y\1f±\86.±\90=«\889¿\9fK³\93F®\8eCª\8cA½\9fT½\9eS¥\87: \7f/£\833¦\862°\8f@\8fCª\8d@µ\97H\93r%9!\ 2fC\ 4wR\ 4xJ\ 3\9b^\ 4¥a\ 4¦d\ 4¤d\ 3¦f\ 4©g\ 6§g\ 4§f\ 5¥e\ 5§g\ 4 a\ 3¦e\ 4\9fa\ 3\9fa\ 3\9f`\ 3 a\ 3¡d\ 4¥g\ 5\99Z\ 3£i\ 5®r\v¯t\12²w\16¸|\1e´z\18³x\17¸| ¶z\1f³x\1d±u\1c«o\1d¹\8fOÔÇ©ÛнìãÑíåÔîçÖîèÖîçÕíè×íèÖʹ¢µ¤\8b¥\9a\89·©\95Ⱥ¨ÐÆ°ÝÓÄéÞÇîèÙîëØëîßæîâãíêãìéãîâãîæãîããîèãîèãîêãíêãêîãçîãäíããéããêããëãäíãåîäìëéîåéíèêîæêîçëîäêîçëîåëîåëîåëîæêîèêîéêîéëîçêîèêîçêîéêîèìîåíîáîìÞîëÚîè×îéÖîèÓîæÓîæÔíäÓíäÎíãÍíäÎìãÌíçÎîêÒîíÕîìÕîìÕîë×îìØííÛëíàëîâêîäéîæèîæçîçæîêåîêæîéæîåæîäæîäæîäæîãæîáçîàî⿽}CÅw5Ð\834Ñ\850Ð\87.Ñ\87-Ò\87+Ë\81 Ê\7f\eÌ\81!Í\82\1eÎ\82 Ð\84%Ñ\86"Ó\85&Ó\84$Ð\81 Ô\85#Ö\86"Ù\8e)Ö\87$Õ\86$Õ\86"Õ\87"Ö\8a$Ó\88$Õ\86#Ô\85 Õ\86 Ô\87\1aÑ\83\10Í}\fÌ\7f\bÓ{\ 3éi\ 3íg\ 3êb\ 3íe\ 3íd\ 3ìb\ 3í^\ 3ë^\ 3èV\ 3èW\ 3ë]\ 2ê}\aä\86\ eã]\ 3ÜI\ 3ÞP\ 3èc\ 3ëk\ 3æa\ 3èd\ 3éh\ 3éi\ 1é\9d\14áq\ 2Þg\ 3Ùo\ 2Î\7f È\86\14éµPå¶Né¿Yç¾ZéÀ[ä¼UåºXä»UäºUâ¸Qâ¶Nà´LÝ´Má¿`äÆoéÍræËsèÊqÞ¾b߸XÉ\8f5Ão\18Ãd\vÈn\11¿l\ e¿q\10¼p\ eÀs\11Àr\f½n\vºl\ e»n\ fºm\ f¼o\ f¹j\10¬]\v\8cA\ 2\859\ 3\83:\ 3\89@\ 3\92J\ 3\90G\ 3\97P\ 4f\ e°\7f+»\95I¨\875¬\8c5¬\8c;²\93Aµ\94BÆ£T¾\9cQ²\93GÀ\9bL¦\856³\8c9¶\8e<ɧ^\8b<\99w bE\b9 \ 3f;\ 3\7fH\ 3¡_\ 4§d\ 3©f\ 4ªg\ 6ªf\ 4¨d\ 4ªh\ 3®l\a¨i\ 4¢c\ 3£d\ 3¢b\ 3¤f\ 3¤e\ 3 a\ 3£d\ 3\9f_\ 3§f\ 4£g\ 5¦h\ 5ªm\ 6°r\fµw\14¾\82 ³v\14²w\14¶y\18·{\1f¶{"»~%³w"¶z(¬q&Ê®yÕ˯ëâÒíæÕíæÕíè×íèÖîé×íèÖÕīϹ\9eǵ\9fŸ§ÔÈ°âØÆìäÔîèÙîëÜîìÜíìÞìîãçíæãíéãîåãîããîããîããîæãîçãîêãíçãëíãéíãæîããíããìããìãäîãçîäêìæíééîçéîééíèêîçëîåéîæêîæèîèèíêéîêéîéëîèêîééîéëîåìîãííâîëÛîéÖîêÖîèÕîéÖîæÓîçÔíåÒíæÐíäÍìâÌìâËìãÌíãÊíæÏîëÕîìÔîìÖîìØîì×ìîÝíîàëîâêîäéîãéîãçîææîçæîçæîææîæåîååîåæîâçîãèîßèîßìß¿¹}AÅv6Ì\7f1Ë~.Ì\812Ë\81'Ë\80"Ì\81%Ì\80$É~\1dÊ\7f Í\83%Ð\85'Í\81"Î\81 Ï\82!Ð\83"Ð\81\1eÓ\83\1fÔ\86&Õ\88&Ñ\85 Ô\87(Ø\8b+Õ\88,Ó\87(Ò\86%Ñ\85#Ð\85 Î\81\16Ï\81\15Î\80\13Ï\7f\14Õ\80\bÞs\ 3ìf\ 3ê`\ 3ía\ 3ëb\ 3ìa\ 3ì_\ 3ë`\ 3çW\ 3æR\ 3åP\ 3éY\ 3èb\ 2ã`\ 3ÜO\ 3ÝM\ 3äV\ 3éc\ 3æe\ 3ã_\ 3çg\ 3ëp\ 3ê\83 àh\ 2Þd\ 3Ûf\ 3Ýn\ 3Ìy\ 5á¤8ä@å²JåµJæµLæ¶Nä´MãµOå·Oä²KÞ±Jâ»YçÈpäÆoêÑ\7fëÔ\84éÎyéÏzêÎzæÊtçÌuèËsê½gÖ\8d3Äu\15»o\rºn\f¸l\b·k\aºo\fºm\f½p\10¹l\v¸k\f»l\10¸j\ e©Z\ 5\83:\ 3x1\ 3{4\ 3\82<\ 3\86?\ 3\8eH\ 3¥Y ·\82/¬\8b=¥\827Å¥R¶\96A±\94H¸\9aKÈ\9fT½\9aN»\9fP¿\9aK¶\95G´\90<µ\89/§\7f#\94k\19uV\ 5X4\ 3{J\ 3\9c_\ 4©g\a§f\ 3«k\ 6¬k\b¬i\ 6«h\ 5ªg\ 4j\ 5¯l\a©f\ 4©f\ 3§f\ 3¦d\ 3§e\ 3¤e\ 3£g\ 3 d\ 3¡b\ 3§f\ 4±s\f¯q
+°u\ e±r\f±u\ e²u\ e°s\r°t\ e±u\12³w\18°v\1a³v\1a´y!²u#²u#´\83<ÖÃ\95éâËìãÏìåÓîçÖîèÖîéÓíèÔ×Ƨá϶âÓ¸ãØÄéàÊìãÐîèÕîêØîëÛîëÚîìÜíìÜéîáåîååîãäîáäîáãîâãîäãîäãîçãîåãíìãêîãéîãçîããíãäîãåîãçîãçîãéîãëíåíëæíéäíëèîéçîêçíëèíëçíìèîëéîêéîééîéëîéìîäííáîëÝíè×îèÕîæÒîèÔîæÒîèÔíåÒíäÎìâÌíãÍëâÍìãËìâËíãÍíäÌïçÌîåÊíèÒìëÙëåÑéãÍæÙÅæÞÊèãÓæåØæéàæïàçòåæòçåòèæðåäîäçîãæîáçîáæîÞçîÜëÞ¹³v4Äw5Èz,Í\801Ë\7f/Ê\80&Ì\80%É}#É|$Ë\80 Î\81$Ñ\85(Ð\84'Ñ\84)Ï\82"Î\82$Ñ\83%Õ\85%Ó\84$Ô\85$Ó\86#Ô\88$Õ\8a*Ö\8a)Ó\88#Ó\88'Ñ\85#Ï\83\1cÏ\84\eÐ\85\1eÏ\81\18Ð\81\17Ñ\83\12Ð\80\ 5Ò|\ 3èg\ 3êb\ 3ê_\ 3ê]\ 3îf\ 3ía\ 3ë_\ 3æY\ 3âQ\ 3åR\ 3áO\ 3áR\ 3æY\ 3âX\ 4ØG\ 3ÞO\ 3çb\ 3èg\ 3å^\ 3æd\ 3ër\ 3åd\ 2Þ`\ 3àc\ 3Ú^\ 3Þe\ 3Ùk\ 1á\91$Ü¡-ã©>ä¬Bä¬?ã®Aà®Fâ¯FàBÜ©Dæ¿_êÍwäÇrçÊuéÌxéÌxéÌwèÍxéÌwèËwæÊuèÌwçÌvæËsåÃiÐ\9d9¹u\r¸n\v»o\r»q
+¼q\fºl\f¸k\v¹k ·h
+·h
+\9aO\ 4x5\ 3n+\ 3q.\ 3w4\ 3\85=\ 3\89D\ 4\95M\ 4®l\eµ\8b:¼\98H̪Z¿\9eMÄ£VÉ©X½\98H·\96HáR»\9bI´\95F\870\8ac
+xK\ 2jB\ 3h?\ 3\87Q\ 4¢d\ 4£c\ 3®j\b®k\ 6h\ 6k\ 3¬m\ 6®j\ 6«h\ 4ªi\ 4¨j\ 4¬i\ 5¥e\ 3¥e\ 3ªg\ 5±n\ 5³s\b¯r\b¬o\ 5«m\ 6µw\ f´t\ eµu\r·z\13q
+²v\11µz\14¶x\14±t\ f±u\13²w\16³x\1a³x\1a´y#®v!¯w$«q!Ã\9c\çÞÂìäÒíåÓíæÑîéÔîéÕíèÒÞиçÜÉîëÖííâííàîëÜîêÛîêÜîéÛîêÙîëÙííÝëîßèîãæîãèîàçîßçîàæîáãîããîèãîèãíìãìíãêîãèîãçîãæîãèîãçîãæîãçîãæîãéîãèîãêîãêîãìíäìîåìíçíìæíìèíëéîëëîæíîâîìÛîìÚîèÔîçÓîçÒíåÒíåÐîçÓîæÒîæÓíåÎíäÎìáËëâÊìáÈëáËìÝÈæ´¥Ý\86yÞpfÕmbÒi^ÆVHËaP¼PA¿PB»Q@¼PB¾_RºdJÁn]Âxd¿\85mÊ\9d\88Ó·¢ééÚæóáæîàæîßæîÞëضµt8Ãw5É{1Î\823Ì\80*Í\81/Í\80.Ì\81)Ë~'Î\82*Ï\81%Ð\84,Ñ\84)Ï\82%Ï\82$Ï\81$Ð\82$Ó\82!Ö\86(Ó\87'Ô\88-Ð\85!Ñ\86\1eÕ\8a*Ô\8a#Ò\86#Ñ\84$Í\81\1aÐ\85\1eÑ\87 Ð\83\18Ï\81\11Ê}\aÈy\ 4Í{\ 4Ûu\ 3éb\ 3ìa\ 3ìd\ 3ë`\ 3ía\ 3ìa\ 3ê^\ 3äR\ 3âK\ 3ãN\ 3âN\ 3ãQ\ 3ÛI\ 3ÙJ\ 3ÜN\ 3ßY\ 3åc\ 3åa\ 3åb\ 3æi\ 3äg\ 3Þ]\ 3äd\ 3ÚY\ 3Û_\ 3Ý`\ 3Úp\ 6Ù\92!Þ\9e,ß\9d*ß\9e,à¥3Û¡5Ú¡3Þ£<ã»[äÅgåÈpãÈrèËtæÉtèÍzéÍ|èÍzêÍ{çÊuçÍwèËvëËuéÍwèÌváÄdܸVÕ¥D¶u\rÂv\ f¿q\rÀq\11½p\ e½n\ e»m\f»m\ e\91E\ 2p0\ 3d+\ 3^&\ 3c)\ 3s6\ 3y:\ 3\85@\ 3¡W\f®w!Á\9bDÅ¡P¹\99EáQÀ\9cFµ\92:°\92@µ\96Hª\87/¯\8d2\8cd\vb?\ 4c=\ 3\80N\ 3\9f_\ 6«g\ 6©f\ 4©h\ 4¯j\ 6i\ 4¬g\ 3¯k\ 3¬i\ 4©f\ 4ªg\ 3©f\ 4«i\ 4«h\ 3¦c\ 3§g\ 3¬i\ 4ºw\fºx\v½{\ fºx\fºw
+ºx\v·v
+·u\v¸y\12²t\r´w\10µy\14³w\14¶z\15µx\14²w\16µ{\e²v\15µz\1c´x#¯u «s\1d¦x1åÖ¸ìçÓìäÏíåÑíèÓíçÒíçÒçÝÂîéØíîáéîéèíéëîåííâîêÜîêØîêÖîêÖííÚìîÛëîßéîáéîàêíÝêîÝéîßæîàäîäãîéãíêãììãìíãêîãéîãêîãëíãêíãéîãçîãæîãçîãèîãéîãëíãêîãêîãìîåíëåíìæíëèîçìîâííÝîë×îèÔíçÑîèÒíæÑîçÐíäÍíäÎîæÑîåÐìâÌëâÌìãÌëáÊëáÊíàËà\8f\88ßa\á`XÞ\VÚ\PÏUIÊ]IÆUF¾P9¸N8ºM9´E2®A-°H0²I5ºRA±K2ªE.±M;®J8¾wXÔ·\97êîÓæõÝçÖ°r7Åz;Ê\7f6Ð\821Ñ\840Ï\83.Ô\865Ð\84/Ñ\84/Ï\81-Ò\85/Ò\83.Ó\85.Ó\84,Ð\82)Ò\86,Ð\83(Ò\83,Ð\82/Ð\84#Ô\88'Ð\84$Ó\86,Ò\86%Ó\88"Ò\87'Ï\82 Î\82\1dÍ\81\1aÎ\84\1cÐ\82\17Ï\81\12Î\80\rÏ\81\fÐ\83\rÓ~\ 5ßd\ 3ëa\ 3êb\ 3ìb\ 3ía\ 3í_\ 3éZ\ 3ãN\ 3åN\ 3âL\ 3àL\ 3âP\ 3ßM\ 3×C\ 3ÓE\ 3ÞR\ 3ÞT\ 3çc\ 3äb\ 3äd\ 3äc\ 2äd\ 3âd\ 3ßd\ 3ÖY\ 3×V\ 3×X\ 3Ú| ×\93\1eÛ\94(Ú\97#Ø\95&Ü\97,Ø\94(â±HãÃdåÆläÉsæÉwçËtçËyèÍ}éÎ}éÎ\7féÎ\7fêÐ~çÌzêÏzèÌxéÍyçÊtãÆmßÀaÞ½]â¸SÍ\90$»r\ 6Ã}\18»p\11¼n\f½p\11¶k\v¢X \8bD\ 6l+\ 3Y)\ 3L\e\ 3A\19\ 3b/\ 3\819\ 3\8eE\ 3 [\aª{&Á SÆ¢M½\99Bº\8e9ª{%\9fu\17 }"\98k\f\93i\ eh@\ 2uE\ 3\98\\ 6³n\f®h\a°l\b¯k\a²n\a³m ®j\ 4®j\ 4k\ 4ªk\ 4«i\ 4¨e\ 3¨d\ 3¨e\ 4¨f\ 3¨d\ 3ªe\ 3©i\ 4·s
+¾~\13¼~\11¼~\14½}\11»|\ e½\7f\16¸z\ f¹{\11¶w\rµx\10·z\14·y\13·y\15´x\13µx\15³v\16¸z\17µy\16·x ²t\19¬o\1dªo'¼\9cdêàÃìäÑìæÒìæÒíæÑíèÔíäÈìíÝêîåéîéèíìçíìéîêííáîìÜîë×îìÛíìÜííÝìîÞêîàêîàëîÞëíÝéîßéîßèîàæîããîçãîçãíëãíìãíìãëîãìíãìíãìíãëíãêîãéîãêîãêîãéîãêîãëîãìîæîêèîçëîäìíßííÝîëÛîëÙîæÔîåÒíãÏíäÐíåÏíåÏíäÎíæÐíåÎíãÍìäÎìãÌìãËìãËæ©\9aá`bâZWã^Và_TÔXFÉS=ÀP=»K:»N8¶K8³I6²I0¬B(¬D(«B*D,¨>*«?+±D1´J1°M/±M.®L-Å\81YÙ«\86¶tAÌ\87QÐ\8dIÑ\89?Ñ\8b?Ñ\8a>Í\866Î\899Î\89=Í\87;Í\88>Í\88:Ð\87?Õ\8bAÓ\90JÕ\9cYâhá\9dU×\88@Ò\840Ò\83*Ó\86*Ó\861Ø\8c2Ó\87(Ò\85%Ï\83 Ï\83\1eÍ\80\1eÏ\81\1cÎ~\12Ð\81\15Ð\81\14Ò\84\14Ò\83\14Ñ\84\ fØ{\ 4ä^\ 3ëe\ 3ê]\ 3ì\\ 3ì]\ 3ë_\ 3çS\ 3àI\ 3àJ\ 3ÞK\ 3àN\ 3àK\ 3ØD\ 3Ð@\ 3ÔF\ 3ÙM\ 3ÛR\ 3àW\ 3â^\ 2ço\ 5àd\ 5áb\ 3ß`\ 3ÙZ\ 3ÓN\ 3ÕT\ 3Ö_\ 3Ôr\ 3Õ\84\fÓ\88\12Ð\87\17Ð\85\17Ø\9a/ä¾YæÅhãÄkæÖ£æÉuéÌ}çÌzèÌ{çÌzéÏ}èÌ{èÍ{çËuèÍ|êÎ{êÍxéÐ{èÏxãÅ]ݾYÙ·NÙ°@ã¾VíÅdÕ\9b7Ãy\17Äy\1a½r\ e¶i\10¹j\17\9cO\ 4t0\ 3K\1a\ 32\15\ 34\16\ 3])\ 3\83@\ 3\9bP\ 3 f\11Â\99G·\8d7£y#\98d\ 5t?\ 2|F\ 3Z4\ 2i=\ 3yE\ 3\8fW\ 6ªj\ f´j\ f¹n\16³m ·m\r¶r\f·s
+¶o\f°n\ 6³m\ 4®k\ 6«g\ 3«h\ 3§e\ 3©h\ 4¨j\ 4ªi\ 4ªh\ 4©f\ 3ªk\ 5¹y\f¿~\14¾\80\16¾\80\12¿\82\16¿\80\13½\7f\15½\7f\17¶w\r¸y\10¸z\13¹{\15¹z\14´u\ f³s\10°s\ e³v\10¶x\15¸y\e´w\1dµw\1d°p\1e©i$\98j)ØÉ íåÔíçÓìæÑíçÒîèÓíêÑëîäêîèéîéèíëèîëçíìéîëëîäìíãíìàííÞîíÝìîßëîáëîßëîÞìíÜìîÜëíÝêîßéîáåîããîèãîëãîêãìíãìîãìîãëíãìíãëíãêîãëìäìíãëíãèîãêîäìíäîèçîæêîâìíÞíìÜíëÚîêÚîèÖîäÑîäÏíâÌíáÏíãÌìãÍíåÏíåÏíäÏíäÎîåÐîÜÅîàËêƹáYUãTPèc]ß]TáaPÖ_LÇO;ÃO>¾L:·G/¶J3¯E0B+©>#ªB(²F/³I5®D5ªA(¬?,±F7®O4°G(µC%¸G$½Y:Ý pà°zßuÞ®sâ¸}ãº\7fã¼\81èÂ\89éÅ\91êÊ\96íÏ¢îѤïÕªîÔ¤ðÔ¢çµ~ã\96_â\90XÞ\89PÛ\8dLÖ\85=Ô\86,Ò\85+Ó\87+Ñ\84%Î\80!Ï\82#Ð\83#Ó\86&Ò\85$Ó\84\1fÓ\83\eÏ\81\14Ï\83\12Ò\87\1aÓ\87\10Ô\86\ fÙw\bä]\ 3ë_\ 3é[\ 3ê]\ 3ê_\ 3é[\ 3âK\ 3àI\ 3ßM\ 3ÝL\ 3ßO\ 3ØG\ 3Í<\ 3ÔE\ 3ÒC\ 3ÖG\ 3ÚN\ 3ßX\ 3åx\ 6áa\ 2Ý[\ 3âe\ 3Ú[\ 3ÑQ\ 3ÒR\ 3ÐO\ 3Û^\ 3Ñc\ 3Ïu\ 4Î}\fÍ\7f\15æ»YæÅiäÄhçÆqèÉsèÏ\7fèè³èÌ\81æÊ}çÌ}èÍ\7fæËzçËyçÊtçÉxéËyçËuíÖ\81ëß\8aäÈiàÄaÞ¼TÛ±DݵLÒ 8Ë\80\18É\7f\1eÈ{\1dÃv\17ºm\f¶i\ f´h\ f¬^ \87K\ 3Z'\ 3<\16\ 30\12\ 3C\19\ 3s=\ 4\96Y\r¹\81%¥z"\8bc\rpA\ 2Y+\ 3P%\ 3j;\ 4\8cQ\ 4ªf\ 4¯j ´p\r²g\rµd\ 4Á|\ f³l\ 6²o
+´q\v·o\b²k\ 5®j\ 5®i\ 5j\ 5«g\ 4j\ 5ªj\ 5«m\ 6«k\b©j\ 5©l\ 5ªk\ 6µx\r¾}\11¿\81\18¿\81\14¿\82\17Á\7f\16¿}\14¼\7f\19º{\14»}\15ºx\15¶y\13µw\13²u\ f¯r\fq\f¬p\r´x\17°t\16¯t\17©n\13¨l\1f§l \9c\\1a¤\82LëãÆîçÔîéÑíæÏíéÔíîÞëîèéîééîêçíëçíìçííæìíçíìçîëêîèìíâíîßííÞëîàìíßìíÜííÜìîÝëîÝêîßèîàèîâåîåãíêãíëãìíãìíãëîãëîãëíãëíãëíãììãìíãêíãëíãíçäîäéíÜéíáììÝíëÙîê×íé×îèÕîåÐîäÏíâÍíáËëâÊìãÍíãÎíåÐîæÕíåÏíåÌä·¤â\83vë\90\86éooì^]ë`Xß[Ná^OÞ`OÌW?ÄQ7ÂP9·O0µK/²H,³L0«H(´K)¶L.±G#±I0±J.¬E*«B)µP9±O6³J+®C&¬?\1aÈ{MÞ®wÙ«tÜtß±{߶\80áº\83ã¼\85äÀ\8eçÅ\9aêÊ îЫíÔ±îÔ°îÓ¬è¸\8aÞ\8d]â\8d[ß\8bTå\92^à\8dWÛ\8aKÒ\806Ñ\82.Ñ\84*Ï\83(Ò\87+Ñ\84)Ö\8a,Ô\88'Ù\8d1Ù\8c+×\8c%Ò\85\1aÔ\89\1eØ\8c Ö\8a\eÚ\8d\1eÙ\8b\16Ùj\ 5çW\ 3é\\ 3é^\ 3ê`\ 3é^\ 3åL\ 3àH\ 3ÚI\ 3ÚH\ 3ÝQ\ 3ÝQ\ 3ÒF\ 3Ë?\ 3Í>\ 3ÔC\ 3ÔF\ 3ÙL\ 3ãd\ 3åd\ 3âc\ 3àb\ 3ß`\ 3ÐP\ 3ÏP\ 3ÏO\ 3ÕU\ 3ÖU\ 3ÉX\ 3Äk\ 2Ú\973å¿^ãÀdéÉnéÉsêÌzëá¤éÙ\9aéÒ\8cæË}æËyåÉxçÉxæÊtåÈqåÈråÇqçÊtéÒ\81éÏtçÊoãÂ^á¾YÞ¹OÙ¯JÎ\971Í\81\18Ê\80\1cÉ~\1dÆ|\1cÃw\14¼o\ e¶g\10°a\ e¨`\a\9cU\ 3y=\ 3X$\ 3;\13\ 3/\15\ 3Q(\ 2\8bR\b}J\ 4W/\ 3\2\ 3l>\ 3\8cU\ 4£d\ 4¯i\ 6¯d\ 6ª[\ 4¤U\ 4®[\ 2Î\7f\15ã©:Á\84\17±n\ 4¯m\ 3²j\ 4´k\ 5«k\ 3j\ 3«h\ 3¬i\ 4®k\ 6¯k\ 6ªk\ 6ªl\ 6«l\ 6§e\ 5¨j\a³v\ e¾|\12½\7f\16¼}\19·w\ e¹{\15º{\15¶y\13²v\11³u\10¯r\ e¬o\ eªn\v¬o\ e¥i\b¢g\a¡e\a d\b¢f ¤g\ f¡b
+\9c`\10\98]\r\93W\10\89Y\19½¬\7fíæÐìæÎîéÑíêÒìîãëîâéîêèíêèîëæììæìíæíìçíìçíìæíìéîèìîåìíàìíÛìîßííÛìíÛìíÜëîÞêîßéîßèîáçîãäíèãíêãíëãìîãìîãìîãëîãìíãìíãìíãìíãììãîëãíáäëàçëÚêëÙëëÙíêÖîèÓîçÒîæÑíäÏíàËíàÊíàÌíßÊìãÌíâÌîåÐîåÒîæÐèÀ¨ç\84tîopîeeìd`æSRçUKÐSCÖXEÑO8ÇT/Ä|CÎ\8aR¿|?¸i9´N(¶K)D&¬?\e¹M(¡1\14¦7\1d¬9\1f£0\16¥-\1a¢3\1e§7%\9f1\1a\9f1\1a¯P,àyÞ²zÞ°zÜ®wݳ\80áº\88߸\84á¼\8cà»\8fäÁ\98êÇ\9fìÍ©íÓ±íÏíÉ\9fÞ\93fä\8fbå\91bä\90_ã\91_â\90[â\8f[Þ\8aQÔ\7f;Î\81/Í\82*Ñ\84+Ó\860Õ\8a.Ö\8c/Ø\8b.Ù\8e.×\8c,×\8e-Ö\8c&Õ\88 Ø\8e#Ø\91!Ù\91"Ø\82\15ÞV\ 3çW\ 3ç]\ 3é_\ 3é]\ 3êZ\ 3ÝJ\ 3ÛK\ 3ÚK\ 3ÚL\ 3ÙP\ 3ÔM\ 3Ê?\ 3Í@\ 3Ë>\ 3Ï>\ 3ÒB\ 3ÖI\ 3ßV\ 3çj\ 3Ý\\ 3àe\ 4ØZ\ 3ÉH\ 3ÎM\ 3ÑM\ 3ÖT\ 3ÐU\ 3·_\aå³NçÂaåÃjéÉrëÍ|éË~êÏ\81ëÛ êÒ\91èÌ|äÈvæËxæÇväÇrãÆsâÆsäÇqåÈrëÓ|æÆjâ¿dß¿Zß¼WÚ³MÕEÐ\9c3Ð\8a#Î\84\1fÎ\84#Ì\80\1e¿r\10»l\10¶i\ e´f
+ª`\ 4©^\ 4¦_\ 5\93P\ 3j7\ 3A#\ 39\e\ 3E \ 3J&\ 3i7\ 3\95V\ 3 b\ 4«g\ 5¬d\ 4¤Z\ 2¨W\ 4ªV\ 3°`\ 4Ì\84\18Ü¡4å»Mã¶L®p\ 5±m\ 5²r\vk\ 2¯k\ 5¬j\ 5¦g\ 3ªl\ 4«j\ 5¨g\ 5¦g\ 4ªk\ 5¢d\ 2ªj\ 5¦h\ 4¨k\ 6¯q °r
+r\f«n\a¨i\ 6©i\ 4¬k\aªj\a©i\ 6¨f\ 4¦h\a§i\ 6 b\ 4£g b\ 5\9ea\ 6\9db\a\9fc\b\9d` \98Z\b\9b`\r\95X\a\91V\ exH\b\80b/ìâ¿íéÏîêÔîêÓìîáéîééîêéîêèíìçíìæííæííçííæííæìëåììèíêëîäíîßííßíîÜìîÝìîÞëîßêîßéîáéîáæîãåîåäîèãíéãîìãííãìîãìîãìîãíîãìîãîìãîëãíåãìããêÝåëÝèëÛëè×íèÔîçÓîçÒîäÏîãÍíàËìÞÉíßÊìßÊìßÊîãÍíäÏíåÏîåÐå\87yêreëfdë\TÙM@ÇI>ÎUC·B*¿J3ÉU8Ü bÏ\9cV¾y9¹t5Å\8dJÀw<¡E\13\9b1\13\8d+\f\92%\ e\89\10\ 2\8a\12\ 5\98\1e\f\95\1a\v\90\19 \84\15\ 3\83\16\ 4~\12\ 3}\14\0×\96iÚ®uÜ®vÚ«wÞ²\80ß·\87âº\89â»\8aàº\8eâ½\8fåÀ\97æÂ\99êÇ£ìΫëǤä¸\91Û\89eá\89dâ\8dbâ\8e]ã\91_ã\92cá\8fZà\88SÝ\88NÒ\80@Ï\821Ñ\86.Ô\893Õ\8c.Ö\8e0Ù\8e1Ö\8a*Ù\900Ø\910×\8d(Ö\8c%Ø\8e$Ö\8d\1dÚ\92$Û\91!Öe\ 3ßV\ 3âX\ 3äZ\ 3å[\ 3ç[\ 3ÞM\ 3ÙJ\ 3ØF\ 3ØG\ 3ÕM\ 3ÕQ\ 3ËB\ 3Ä7\ 3É;\ 3Ê7\ 3Í=\ 3Ï?\ 3ÚG\ 3áV\ 3äj\ 4án\bØX\ 3ÏN\ 3ÍJ\ 3ÈE\ 3ÒR\ 3ÕU\ 3Ö{ å¹VãÀ`åÄpçÊtçÈwèËzçË\7féË|éÍ\83çÉ}åÇväÅtãÅvâÆoäÆtãÅsáÅnçÆqéÈsáÂeÞ¾[Ý»UÙ±LÕ®IÓªEÒ\9f8Ó\8d'Ð\88$Ï\85#Í\83 Ãu\13¼n\ e¶h ²g\ 5µe\ 6²f\b«d\a¤_\ 5¤a
+\93R\ 4v@\ 3vC\ 3\90R\ 4£`\ 5¨f\ 4²h\ 4¸m\ 4ºl\ 6È{\ e±`\ 3©V\ 3©Y\ 2Å~\15â²Cä½RçÅ\Ò¨@q\ 6°q\b²q\ 4®l\ 5ªl\ 5«m\ 6¨j\ 5©j\ 5ªj\a©i\a§g\ 4¥h\ 4¤g\ 3¨j\ 5¨k\ 6¨k\ 6©k\ 6¤g\ 3£f\ 4©l\ 5¥k\b©k\a¥e\ 4¥e\ 4¡c\ 5\9ea\ 5\9fc\a\9b^\ 5\9a`\ 6\99]\ 6\95[\ 5\99_\b\9bb\f\95\\ 6\92Y\v\93Y\ e\95Z\ e\93Y\12\86O\ e\89`*èرîéÑîëÔîëÖëîæêîçêîééîêçíëèîëçííçíìçíìæíìæìëåìíäëíçíêêîèìíáííáìîßëîàëîßëíÞëîßêîàèîâæîãåîããîèãîêãîëãíìãíîãíîãíîãîîãîíãîìãîéãíäãêÝãêÜèéÙëëØìé×íæÓîçÑîäÏîâÍìßÊìßÊëÞÆìàÈíàËíãÍîãÏïáÈê³\97ìxhëneça^ßTFÂH2¹H5³T3²M,°H*Ñ\90WÙª_³h'²Q\1f»\0\99C\1a c!´u8q\ f\0¤U\1f}!\ 3\82\13\ 4\82\11\ 5\8b\1e\b\94(\10\8a\1a\ 6\84\19\ 5\7f\16\ 3{\13\ 4\93>!â´\84Ø®wÚ®yÛ±}Þµ\82á¸\8bä½\8fà¹\87á»\8få¾\93çÃ\9fèÅ£ëÉ£éÆ£êǤߨ\87Ü\89aâ\89eÝ\86aá\8b_ã\8feç\97læ\98eÞ\8dYß\90\Ü\8aUÏ}8Ð\82+Ô\8a2×\8c4Ö\8c1Ó\8b,Ó\8b,Ø\90,Õ\8d*Ø\8f*Ú\92*Û\93*Ø\90&Ú\91#Ø\92"Ø\89\16Ô]\ 3ÙR\ 3ÔN\ 3ä[\ 3æ^\ 3ßS\ 3ÛN\ 3ÖF\ 3ÔE\ 3ÓD\ 3ÕI\ 3É>\ 3Â6\ 3Å9\ 3Ç9\ 3Æ;\ 3È<\ 3Î?\ 3ØI\ 3ß`\ 5âe\ 2ÚW\ 3ÔQ\ 3ÎH\ 3ÍI\ 3ÍJ\ 3ÖZ\ 2á\990äºVçÅiæÆpèÇséÈtèÉvéÉwåÇsåÈtäÆtæÈtãÅtáÂqàÃoãÃnâÂkâÁkâÃläÃiß½]áÄaÛ´PׯJÕ¯JѨDÎ\9d4Ï\8a"Ñ\8a$Ð\87"Ë\81!Áv\14ºq\v·l\vµj\a¹j\ 6¹p\ f³m\f±j\r¯k\r±k\f¯i\v®j ²n\ f¸w\11¾{\16Éx\vÓ\8e\1eÔ\95%Å\87\16À\83\16¿{\12Ã\82\1cݬ;ã¼LèÆ[ìÎkíØuÅ\9a2¬k\ 6®m\ 4ªl\ 4¬m\aªi\b¦f\ 4¤d\ 3¦f\ 5¨g\ 5¤c\ 4¢b\ 3¢a\ 4¥g\a¢g\ 6¡e\ 5¡a\ 2Â\87%±m £_\ 1\97`\a\96]\ 3\96\\ 3\9b^\ 6\98Z\ 4\91X\ 3\8fT\ 4\98\\ 6\93Y\ 4\93Y\ 4\8eT\ 3\91W\ 3\91U\ 5\93[\b\91W \92X\ e\91W\f\91Y\14\8cU\13\91t;ïéÄîçÌîêÓîêÓéîåèîæêîçéîçèíëèíêèíëèíêæíìçìëæììæììåììäëíçíëêîçìîãíîÜìíÞëîßëíßëîÞëîÞéîàçîáåîâåîããîããîèãíëãîíãîîãîîãîíãîíãíìãîíãíéãìããëÝæëÙêêÕëéÖîéÕîäÐîäÏíàËíáÊíàÊìÝÅíÞÂíݾîÛ¿çµ æ\88rî\80jëycèlXØXLÄL;±G(A Ð\8cUТdÕ§dЧ_Ö«^Ñ£W·s1\8b.\ 4r\15\ 1\80>\a\93V\15\89@\eÓ¡bÀ\92Mp\1f\ 4\8c\19 ¨A\17\987\13\92 \a\8c\1d\a\8c\1a\ 5\8e\1e\ 5Ô\8bdÜ®zÙªwÚ®{ܲ\7fàµ\86âº\8câ½\92æÁ\93äÂ\99åÂ\98ë˦ì̪ì˪îήéÆ£Õ\90uÝ\84dÜ\82^ß\86cã\8edè\97pè\97sã\94iØ\85SÞ\84Rå\8ebÜ\8eVÈw0Ò\843Ô\8b:Ô\8a2Ó\8a+Ø\8f1Ý\957Ø\900×\8e-Þ\985Ü\97.Ü\94)Ø\93 Ü\94$Ú\96"Ùv\vÔR\ 3ÚO\ 3ßT\ 3è^\ 3ç[\ 3ÝQ\ 3×G\ 3ÕF\ 3ÓG\ 3ÐI\ 3ÇB\ 3¼1\ 3¾5\ 3Â;\ 3Ã8\ 3Ä8\ 3Ç;\ 3Ë?\ 3ÓI\ 3ÚV\ 3ÚW\ 3ÚW\ 3ÐL\ 3ËF\ 3ÌE\ 3ËW\ 2é°JéÂaæÃièÆqæÅpéÈtéÉvèÈtçÆsåÅpåÅrà¾hÞÂkà¾jß¾hÞ½gß½eà¿gß¿fÞ½^Ú´PÚ´QØ°LØ°KÒ©DЦBÏ\980Ò\8a#Ï\88\1fÌ\84\1eÍ\82\1d¾x\10Áy\11¾t\11½t\fÀv\ f¿u\11Âx\18»t\12·s\10ºt\11»v\10Àz\10Å\81\17Ç\80\14Ð\88\1aÚ\9a*äµMá¸Ná·FÖ¨6ܪ5߬<à·Kå¾RêÈ^ëÌlêÑtåËj«y\14¥g\ 4£e\ 4¡a\ 4£c\ 3¢b\ 3¥c\ 4¢d\ 4\9da\0\9ea\ 2¡f\a·\80"¿\900Ç\9f:Ã\951\9ed\ 5 e Þ£?Ï\87\1fk\r\94[\ 3\95\\ 5\99_\b\96\\ 5\91[\ 4\91X\ 3\94[\ 6\95\\ 4\8fW\ 5\89Q\ 3\8dU\ 5\8dW\ 6\8cW \8fY
+\8bS\a\8aS\ 5\8bS\ e\84N\f\92t:éÛ¶êÖ³ìãÆíéÒéîåçîéêîçéíèéîèèíêèíêçíëæìëæìëæíëåìíæìíæììåììçíìéîéëîãíîàííÛëîÞëíÞëîàêîßêîßçîâæîâæîããîäãîæãíåãíæãíåãìâãìåãíäãíêãîçãìäãìßãêÚæêÙëèÕíéÔîæÑîåÎîàÉîÙÈîѼí̬íÇ£íÀ\9dä\9bzßuaÊQ6ÀH/ÀG,¸>)ÅM8ÂL.·F#²C\1fÞ\99dÎ\9dWÊ ZÎ¥\Ш]ѦYÎ PÌ\9aL\95U\18x4\ 3¿\82A\86L\15¨yCêÊwÃ\88EÓ^0ÂM\19ºX*¢E\1a\93&
+\9c%\f\9b1\ fè³|â·}Úsàµ~Û±|åÂ\94åÄ\9bäÁ\97ãÂ\94æÆ éÉ¥ëÌ©íϬîÒ³êÞÁîΫéº\9dÚ\89oÕ|Yß\86fÜ\86dä\92kç\96sÏsOÊb<Ñg5á\84Zà\92cÕ\83UÒ\83D×\91H×\96LÖ\95F×\93CÛ\95;Ü\969Û\937Ü\944ß\980Þ\96'ã\9a3à\99+ß\97*Þ\97 Ìa\ 3ÙO\ 3ÛR\ 3âZ\ 3å\\ 3ÝR\ 3ÙG\ 3ÕF\ 3ÓG\ 3ÎG\ 3Æ@\ 3¾9\ 3¯+\ 3À=\ 3¿7\ 3Á7\ 3À2\ 3È:\ 3Ë>\ 3ÔI\ 3ØU\ 3ÖQ\ 3ÓO\ 3ÐJ\ 3ËF\ 3Öv\1aå¶MèÂ]èÅiæÅnèÆqéÈsèÇvåÅuäÅwãÂnß½iÞ¼fݾfá¿iß¾gà¾dà¾bÙº[ÚµRÙ²MÖ°HÖKÓ©EÓ©EÕ¬GФCÆ\86\1eÉ\7f\16É\81\19Æ}\19Ãz\14¿w\ eÁx\11Â|\1aÀx\12¾v\ f¾v\10¾w\14¶r\r·p\ f¸u\10ºu\ eËx\10Ñ\85\19×\91#Ô\93!è»Mß´Mà¶JݳCã¼OÝ´Cã»Oã½TèÁVéÄXæÃ^çÏrêÏoÓ¯K\9ea\0£d\ 6¨m ¤i\r´~\19Ã\8e)Ê\9d9ÞµSãÀbðÓxíÎqìÍqíÎrëÊiîÍp§{\1eÖ®Oß©@Ú\970¤j\12\8dU\ 3\91Y\ 3\8fW\ 4\8dU\ 3\8dT\ 3\8dU\ 3\8fV\ 4\8bV\ 4\88T\ 3\88R\ 3\8bU\ 5\89S\ 4\89R\ 6\89R\a\8aS\ e\85M \83M
+\94o7µ\91fÆ\99tåѳîêÖèîãéîæéîçéîèèíéèîéèíéçíêçíêèíêåììæììæíìæííæììæììæììèíìêîäëîßìíÛìíÝìíÝëîÞêíßéîßèíàèíßåîßäìßäíÞäëÜãëÛãêØãëßãìàãìâãìâãíåãíßãíÝåéØéèÔíèÓîåÐîàÇíͱîÆîˬéÃ\9bî¸\93Ñ{`ºC.¸;"¾9\1e¾< Å?$º: º9 º7\1a³5\12·;\18ÒlHÔyOÁe8¥d&\8eK!¦o2Ë\9fSÇ\9cNÌ\9fG¸\865Ç\90?¤H\10}8\10Â\96?Ù©V»W\18ÈW\1e¼Z$¯U"®M\1f½f;É\8bYâµzÜtÚ«rã·\82å¹\86çÅ\97æÅ\98æÂ\97èÅ\9béÉ êÊ¢éȦíÍì˨îÍ©ìÍ©èÄ ç§\8bâ\92vã\8boã\90lç\96rì¢~ÉkJÅ[;ÎrIä\91nâ\96qÜ\89dá\93iæ¤vç¯{ìÀ\87ë¿|ç¯cÜ\99BÝ\957Þ\969ß\974Þ\97/â\9c3ß\9a/Ý\97,Ü\97$â\93\16ÍS\0ØK\ 3ÞP\ 3áV\ 3ßV\ 3ÜP\ 3ÖH\ 3ÓF\ 3ÑF\ 3ÉD\ 3½8\ 3³/\ 3¯.\ 3¿>\ 3½8\ 3À3\ 3À3\ 3Ã7\ 3Å<\ 3ÍM\ 3ØY\ 3ÜX\ 3ÐK\ 3ËG\ 1å\971æµHçÁ`èÃiçÄiçÄlæÃkäÃlåÃoãÁlÞ»fÝ»eà½gá¿jß¼bÛº^ܹ\Û¶YسVØ°L×HÓ¬FѧIÐ¥CÒ¥@ѪEË\9d>½}!Áu\13¾w\ f¾v\12½t\10¼s\ f¶n\b´n\b·q ´k\a³k\a¯i\a¯h\ 4¬e\ 6a\ 3Át\10Þ\95-Ø\9c6Þ©?ß²Kà¶Gà·KáºQãºLâ»JÞ¶Lå¾Uâ¼UèÃ\æÁWëËeçÍoêÏpçËlÏ\9e7Ý =Þ§<é¸Lå»Oç¿WèÅ_ëËlìÐuìÏtëÌsëÊpêÊsëÉmçÅaìÒxͧOéÈjß³R«s\18\8cS\ 3\8dV\ 5\8dU\ 6\8bU\ 4\8cV\ 4\90X\b\90W\ 6\8cV\ 6\88S\ 4\8fW\a\8bU\b\83N\ 4\84O\ 6\89U\ f\88S\ e\8aV\12\8aU\15\8da'ª\8aXÖÁ\9cëáÉíèÒéîåéîåèîèèíééîèèíéèîéèíéçíêæìëæììåììæíìåììåìíåìíæììäëíåììéîæëîáìíÞëîàêîÞëíàëîßëíÞêìÜêìÚéêÛéêÙéèØçêÙåëÚäêÛãêÜãëÜãìÞãìÝãíÞãìÜãëÛèèÔìçÓîåÑíÑ´í¿\97ìÁ\9bêÂ\9bé·\94½[Cµ7 º;%·4!³0\182\17²6\1e¶8\1dµ2\19³3\15³4\16°1\14¯/\14¬0\13\9a6\ 6v3\ 3i\1c\ 2d \ 2p=\ 3µ\87EÎ SÏ¥OͤNÞ®^ܯ]»\884È\99F\94T\f°c\1f\7f&\a\9b>\14ºi=è¶|åÁ\88à»~á´zݲwâº\81ã¼\86åÃ\91âÀ\8däÁ\90éÆ\9aêÅ\99êØ´éÆ¢ëÉ©íË«íÐîǧäª\8aÝ\8blÛ\82gÝ\80dã\88jâ\8dlâ\8dkÞ\8bbá\8dhÝ\8afÞ\8cfá\8ekÜ\8b_Ö\84]Ø\82YÒzRËuEÛ\8eRÞ\98Tß\9bVÞ\9bDÞ\988à\997ä\9f6â\9e5ä\9f5á\9c2Þ\98&ä¡+×\85\18ÓN\ 3ßL\ 3ÞQ\ 3ÞV\ 3ÚO\ 3ÙJ\ 3ÔG\ 3ÑE\ 3ÉA\ 3¿;\ 3µ6\ 3©*\ 3°3\ 3¾=\ 3ÆF\ 4ÅD\ 3ÔT\ 3Û\\ 3Ýf\ 3än\ 3ßi\ 3ÖZ\ 3ÈH\ 1æ£1å³Iå»YåÂgåÂjäÁläÃmäÃgá¿dá¿iܺdØ·^ÚµZÛ¸_Û·YØ´U×´XÙ´YÛ³R׬IÐ¥AЦBÍ¡?Í¡<Ò¤@ЪLÃ\99?³w\e¹r\10ºu\f°o
+·q\ f²m\b²m\a¬k\ 5¬h\ 4ªc\ 3ªe\ 5©g\ 5«g\ 6°f\ 6Ð\82\1aÝ\97.ç²JèÂ]á¸QÞµQâºNéÂXå½Qá·JÞ²Bá¹Hâ¸Mä»SÞ·Ná½SéÊièËmçÌnéÏrãÃdÞ°Gá¯EãµLá¹NèÀZéÄ`ëËnìÎqëÍkêÊoëËléÈnêÆfæÂZéÇhêÉjèÅkèÇp©y \8eX\a\8cT\ 3\89T\ 3\89V\ 4\89U\ 5\90W\ 6\8eU\ 6\8cU\ 6\8eX \90Y\f\89S\a\89S\a\8bU\ e\8aU\ f\8aU\10\89T\14\85R\12\8fd+«\93dȼ\9eìäËíçÐéîåéîæèîçéîèèîééíéèíëéîéçíìçíêæììçíìæííæííåìíçíìåìíåìíäëíæííçîêêîäêîãìíßëíÞëìÜëìÙìé×íçÖìéÖìèÔëéÖéé×èêØçêÙåìÚäìÛäìÚãíÞãîßãíÞäìØåê×èéÕíܽì·\99ê¥\83æ \83Ö\88m³@'¸7\1e¹8\1eµ9\19½S0Ó\7f`Ö\90mã\9d{Ð{\¦,\14ª*\12©)\ e¯2\15±5\1a\947\fu;\ 3m5\ 2\8cY\19`3\ 4pF\ 3b2\0¨y*½\8f:À\99AÃ\9aAÈ\97E\9ei\15\9ff\11\9fi\1ez@\vf\1f\ 6h#\ 2\9fY!ÞªsäÂ\8aæÅ\8dà´xã¹{æÀ\84å¿\87߸~à¹~â»\83á¼\89êÈ\9aéË¡êɤëÊ©éÌ«ìƧØ\8dtÜ\81jÚzbÞycâ\83hæ\8bnâ\8bkÜ\83eÜ\83aÜ\86cÞ\8afÝ\88hÛ\87gÜ\8bcÔ\83_Ñ}XÐ|RÎoHÉi@Ø\87TÑ}DÝ\94Là Qä£Gã\9e6ã¢9å£>â\9e6á\9d)×\8a\ eä\8b\16Ò\\ 1ØO\ 3ÙN\ 3ÜR\ 3ÝS\ 3ÙL\ 3ÓH\ 3ÏD\ 3ÍI\ 3ÍL\ 3ÊQ\ 3Ò\\ 3Öd\ 3Úh\ 3Üj\ 3ãp\ 3Þh\ 3Ý`\ 3Þ`\ 3Ü^\ 3Ýb\ 3áe\ 3ßo\ 5è©0è¹Ná¹Vâ½Zà»_ß½aß»`Þ¹^Û´YÙ´[ص\Ø´ZÕ¯PׯVÓ®UײV×±TÖ±TÒªHÒ¦DÎ\9f:Ð ;È\9b5Ë\9d8Ï£DÆ\9d;Á\96;«n\v±n
+l\a«n\v«j\ f©i\a¦h\ 6£c\ 3£d\ 4¨g\ 5§c\ 5£d\ 4§e\ 5Ð\85"Þ\9d7à°MçÀ^éÂ]èÁZèÃ]êÅ`çÀYá¸Ká¶Gá¶Gܱ?Ü=Þ¯>â¼QçÅaçÈfèËnêÍsëÍrèËpܶQÛ®GÛ¯Já¹QæÃ_éÄcêÉqëÊpæÅcêÈléÉlêÈkâÀ]àºWåÁcéÅjéÇkÅ\9fC\90[ \90W\ 6\8eV\ 5\8aU\ 5\8aV\ 3\88S\ 4\87R\ 3\89Q\ 3\88Q\ 5\89R\ 6\89Q\ 5\8bR\ 6\8aS
+\89Q\10\89Q\r\87P
+\83N\ f\87P\15\91f5±\97r¼«\89êäÆíèÑèîæçîéçîééíèéíééîèèíéèíéçíëèíéçíëåìíçìëæììæìëåëíåëìäëíäëíåëìåììåíêçîçêíãìíÞììÙìëØíé×ìêØíêÖìçÖìê×ëêÚéìÚèìÜèíÝäîßäîâãîâãîããîâäêÔç±\9cà\8f}æ\96\85ë\9e\83ä\8doÃ\Bµ7#¼2\1c¸-\e»>#ÅjBâ\9enìÌ\9eè½\8dãµ\8aÓ\8fl¿X7©2\14¦-\10¬4\1c\8a- j2\ 3j5\ 3k5\ 3Y,\ 4\8ad\ f\7fY\ en:\0¥x\e¡x\1a¬\81)\82)¸\8b5Á\93<·\8a1±\81-h1\ 2\99e\1c\8dY\1d¨p8¸y>Ú¨jß²qß°váº}ç¾\86â»\83ݺ|Ý´zÞ¹\85Ý·\84éÈ\9aìÍ©ìˬíÑ°ïÕ³ä²\90Û\8esØ\7fbÚy`Þ{cá\82eç\90oâ\8alÜ\83dÝ\86gß\87fÞ\89iÜ\88kå\97yÜ\8blÚ\88hØ\87eÏ}TÇe<ÀZ-És>Çs>Év:â£`Ú\91;ß\961Þ\971Û\95.Ù\90(×\8f\eÛ\86\váo\ 2ãh\ 3Þ_\ 3Ü]\ 3ÚX\ 3ß`\ 4ÞZ\ 3âf\ 3âh\ 3ái\ 3Ød\ 3Øc\ 3Úe\ 3Úg\ 3Ùe\ 3Ûf\ 3Ýd\ 3ßb\ 3Û[\ 3ÙQ\ 3ÛR\ 3×S\ 3ÞZ\ 3Þ]\ 3Øh\ 3å\96#ß 0á®FÝ°OÙ°SØ®PÙ°WÙ°VײYسZرVÖ¯TØ°XÔ¬RÔªOÕªNÒ§E΢@Ë ?Ë\9d:Ê\9c7Æ\982Ï£CΪSÁ\9c@¹\8f5¢i\f£d\ 6¤e\a¢c\a¦g ¢c\ 6¢c\ 6\9f`\ 4¢c\ 5 b\ 6\9b^\ 3¡a\ 5Ï\86\1eæLéÃcíËtìÉnìÊhëÉgá¼TèÄ_ä¼Tâ¼Tâ¹KÜ<ݱBß´Cà´BæÁUéÅ`çÆ`éÍmçÊiìÍoáÈjܶVÖ©EܱTß·QæÀ\èÇbéÈjêÊnêÉoéÈnçÄkâ½bÞ¶RܵRâº]Ú³PäÁbݹc\98f\14\8eW\b\90Y\ 4\8cS\ 5\8aV\ 5\8aT\ 4\8aU\ 5\8bS\ 6\88Q\b\8bU\v\8fU \89S\a\86P \7fI\b\82M\f\85U\16\8eY%\88_+¨\8d_¾\90ßÖ¹ìæÎíçÒçíæèîèæîéèíééíçèíéèîéèíëçíëéîéèíêçíìæííæíìçíìåìíæííåììæììæíëæìëåíìçîéçîèéîåêîâêîßéîâéîàéîàéîßéíßéìÝêìÛèîÝçîàåîãäîãäîããðäæϼÙ{qÔe\Úc_Ü`_ßtdÄ[E»A1¶5 ²4\1f·;\1eÀ`?Ù\9chã\7fäº\8fåµ\8aå¹\91ÊyVÁc:Ä`:¹P0\87)
+r1\ 4f4\ 4e4\ 3[*\ 3[1\ 4uK\ 6Á\9aDÆ£I»\97<½\9eC\9bu\1f x#°\88/¶\8a7É£JÅ\9fHª\7f.\93h\1c\83S {C\ 6i)\0Å\8bQÚ¢hØ¡iÚ¡lÏ\91ZÓ\9dpÞ¯{â¼\88Ü·\81á¿\8aèË¡ìͦíϯíаä£ç¿\9aæ¹\9bà§\83Ñ\84hÏy[Ý\7faß\83jØ\80cÜ\80aÜ\82cÚ\83dÞ\88gÜ\8ajá\90sÚ\8bhØ\8adÏ\81YÌvRÍnM»V5»a9ÈyIÃn1Ù\94WÍ\829Õ\82%Ó\85(Ó\85"Ñ\83\1eÏ}\ fÒ\7f\ f×w\ 5Üg\0ãb\ 3áb\ 3áb\ 3à_\ 3Þ[\ 3ÛW\ 3ãb\ 3âf\ 3Ûc\ 3Þc\ 3Ýa\ 3Ú_\ 3Ýd\ 3Úa\ 3Ø]\ 3Ú_\ 3ØZ\ 3ÖO\ 3ÓF\ 3ÓJ\ 3ÔI\ 3ØM\ 3ÜX\ 3Ýa\ 2Úi\ 3á\8f Ö\9f3ئCÖªLÖªOجOÕ©RÖ¬PÓ¨LÔ©RÏ£IÒ§JϤIÏ¢HФLÆ\998É\9b6Æ\940Æ\94/Ë\9d8ϨOϬUÀ\97?¼\8b:¡e\r¤d\v¢c\ 6¥e
+¡b\a¡b\ 5£d\a¢c\ 6 a\ 5 b\ 3¢b\ 4Ë\83\1eá¦:íÈcëÇdêËkëÈkéÈhèÇlëÈgèÃcæ½Yß´LÜ®=Ô¢1Í\9b%Ñ¡,Ý°?߸HæÁ[äÁZåÃ\åÅbÛ¹[äÄ`Ý»\Ï¢>ܱLá½XêÇkìÍoêÏrëÎvèÎvÞº^Ô§?ק@Ñ¡8Ñ ;Í¢;ݱMâ¼_ìÒ~åÍ\7f\8bU\ 6\89Q\0\87P\ 1\83R\ 3\82V\ 4\86S \8cZ\ e\8dd\1e\95p0\9cv9¨\83M²\95bº\9ciȬ\7fÖÅ\9cÞÒ´âؾçßÆíçÔîëÖíè×îê×èîäéîæéîåéíééîèéîèèíêéîéèîìèíëèîëçíìèíëçíìæííæììæìíæíëèíêæíêæîêæíêæíéèîçèîæéîåèîçèîççîèæîéäíêåîìæîææîãåîäçîâæîâæîâæïâáîÒkbÜcaÙ^WÔONÌC;Â@-µ>%µ4"¯4\1d³E*´L$½c9Ö\8b_Ù\98oÙ\9fuá´\8aܯ\82Ì{ZÉuPÈiFÆcBÂfA\9bK k.\ 3[,\ 2T.\ 3V/\ 3a9\ 3yU\f\86g\ f\97v\1e\9d}"¥\8a0«\89,\9cm\15¦y\1d©|\19µ\8f1³\891¼\8d9¯|5\9fl$Î\9abÐ\92_Ò\8c_Ð\84SÒ\7fNÊzIÆvHÁlJÍ\84]å²~߸\83äÂ\97çÅ\9eêʧêʬèãçÄ\9fìÆ¡çÃ\9bè»\93æ¦\8cÝ\92qÛ\87iÛ\80cØx\×~\Ú\84`Þ\8cfá\92rß\8erÛ\88kÛ\8bkæ vÔ\82^ÈhC¿[7M+Ë{HÄp6ÊyDÕ\8bKÈv"Èy\eË|\1fÉy\1cÌz\18Ê{\16Î\8d/áºbÛb\ 1ßa\ 3ÞZ\ 3ÜW\ 3ÚT\ 3ÝT\ 3ÜT\ 3Û]\ 3Þ`\ 3Ý^\ 3Þ_\ 3Ü_\ 3Ú`\ 3Ü^\ 3Ú\\ 3ÙZ\ 3Ü\\ 3ÕS\ 3ÐD\ 3ÏD\ 3ÐD\ 3ÑE\ 3ÏG\ 3ÝY\ 3ÛZ\ 3Øc\ 2Ú\80\16×\99*Ñ\970Ñ ;Î DТDÏ¢?Í¢AÑ£NÒ£FѤGÌ\9e@Ë\9e>É\9a>Å\955Â\92.Ä\8f-Ä\933Ë ĮPÐY¾\97>¹\870¤e\ e¤c\v¢c ¥f\v£d
+¥f\v¢b\ 6¡a\ 5¢b\ 6¦d\ 5É~\1fæªDç¸Wä¸Uá»WéÈfçÅfêÈfèÆjæÃeéÆdß·RÛ¯>Ú:Õ¦4Ö¤1Ô¦0ئ6ß´FÛ³Gà»Qá¾SëÌoá½]ܸQêÑuÑQÞ´VåÁ`éÊtèÊmèÈkåÆjßÀbÌ£CÍ\9c4Ë\9c2Î\9f7ÕªIׯLÚ°KÙJàºYɤN³\92G¼\9cUÅ©nɳ}ÕÅ\8dáË\9báÏ çÛ¬êáºìäÃíçËïëÐïíÖðïØîëÔîìÖîìÖîêÖîëÙîë×îéÓîëÖèîåéîåèîçêîæéîèèíééîééíèéíèéîéèîêèíêèîëèíééíèèíêèíêèíééíéèîèèîçèîçèîæéîäéîåèîæèîææîéæîèåíèäíêãíëäìëåíéåíèçîåæîäæîâçÜËÏrkÙa`ÕVLÎMAÄ?5ÇL6º@)¼>&µ1\1e®3\e»W1¶W.¼V7ÁdBÇ\82VÙ¤råº\8bÎ\91aÏ}TÍvVÊjOÃeCÄf@Âa@¼hG\89C\1e])\ 2S0\ 2[=\ 4mI\ f¬\8b;\96r\18\9du\17}[\b\8bk\ f\97n\13\94i\v\9dn\10±\84,º\8b:¦u)Ì\9faÒ¬nÕ§mÔ\98hÔ\91aÒ\89UÑ\7fMÎyKÆm?ÄlG¿hCÁnHÙ\93kè¸\8eã¼\90äÀ\9cæÂ\9eéÄ¢èÄ\9dèÀ\99æÀ\9cݲ\88Ã}YÔ\82]à\8dlÝ\88gÚ\83gã\94uÛ\8aiÚ\87cÞ\8aoÛ\87jÙ\86gÙ\87hÕ\84bÙ\89cÉmI»Y7ªJ(¹d4¾j2»e1Ås5½m%¿q%Âu)Àt%½r\16¾p\1c×Æ\8bá½{ºY\ 4Óa\ 3Û[\ 3ÙV\ 3ÛT\ 3ÚM\ 3ØK\ 3×I\ 3ÙT\ 3Ü`\ 3ß_\ 3ØZ\ 3Ù`\ 3×Z\ 3Ú^\ 3ÖV\ 3ÖV\ 3ÐR\ 3ÏN\ 3ÎD\ 3ÏB\ 3ËA\ 3ÏA\ 3ÒD\ 3ÙQ\ 3ÖV\ 3ÑR\ 2Îe Ò\87\1fÎ\937É\979Ç\977Ç\97;Ê\9b?É\97>Ê\9bAÅ\96<È\98=Â\915Ä\93:Å\947¿\902½\8c1À\92:É¥TÌTѳ_»\98A¸\8a7¤e\v¤e\ e¨i\13¥f\v¥f\f¥f\v¥f\b¥g\v¥f\bÁs\14á\9a4éºUÓ¤?æ¿^çÄkåÀ_å¾ZêÄbéÇhêÊnçÆgÒ¨DÕ¥;Ø«<׬:Ú«=Ó¢.ק6Úª:Ø«AÞ¶OäÅ^ëÍnéËlêÌqíØ\80äÈkÒ©Fß¹Vß¿_Ü·TݵSÒ«BÕGܵQã¾iéÉmß·OÔ©E×JÖ¬Hà·QÙµUïéµðëÄíìÂëÞ¦ïì¸ìâ«îìÇîêÐîéÑîêÓîêÓîéÓîêÓîëÓîêÓîêÔîëÔíéÔíèÓíçÒíçÒìæÑìåÐéîâèîåéîçêîæèíééîèéíèéíèéîçéîèéíèèíèéîèéíéèîèéíèéîçéîçéîåéîçéîäéîåêîäéîåéîæéîåçîèçíéçîèçíçæîæåíçåîçåíéåíèæîçæîåèðáÛ \90ßldÕWMÖRHØ`YÌYJÅH2½>(¶6\1f²1\1d²2\1c·D'¶Y.¹b?Ö\94mä²\84ã¹\8eæ¸\8fÉxOÏyUÏ\7f]ÈsTÊoQÃd:ÆdBÃgEÅfJ²Z7\80E\1aR*\0«\85CÖ¯]µ\8f5«\7f!}Z |V\ 6oI\ 2\84T\a\88U\ 3Á\97Mؽ\82çÊ\94ëÌ\98åÄ\91Ò¢mÔ\97f×\90_×\8e[Ô\88UÑ\81RÇvFÆrIÀlFº]7´R0ÉuQä¯\83ܲ\84à¹\8dçÁ\99çÂ\9eëŤå¹\98äº\95Ñ\94oÎvZ×w_Õy]Õ{_Ôz]Õ\7fbØ\83fØ\82iÙ\83gÕ\81eÙ\88jÒ\83fÕ\85jÊuV¶V9«D(¯Q.Àd8¾d-¿f0¶d#´e\1d°e\16³d\16²e\14¯f\1eéõÙåÝ©»\8cP¤kQÇ\841Èo\19¾X ¹C\0¸;\0º>\0¾=\0ÂF\0ÑN\0ÖV\0ÔT\0ÔN\ 1ÛV\ 2ÖT\ 3×T\ 3Ú[\ 4ÓR\ 3ÑK\ 3ÐD\ 3ÌB\ 3ÍD\ 3ÎA\ 3ÓI\ 3×S\ 3ÍP\ 3ËJ\ 3ÂW\ 4Å~\18Ç\8b7Å\8d8Å\908Å\91;Ä\906Æ\918Ã\8f6¿\8b3Ã\8a2¾\88*º\83)¶\81+¸\889áÉ\7fŧYÖ¸iÕ¼oδj»\95J b\ e¡c\f¦h\11¥f\ eªk\14¨h\10¦i\11¥g\aj\rß¡?ì½]Ú®NéÇfçÅkèÇqÕNæÃbàºYåÁbèÄbäÀ`à¹Và¸SÛ±CÕª9Ø©8Ú«9Ú¬@Î\9b(¹~\vר?èÊgåÆbçÍrëÒ|êÒ|ìÔyʧEرHѦ=Ë\9a4Ô§EÓ¨DÕ®GÞ¼]æÅiã¾_É\98/Ñ¡:Ô«FÞ¸[Û³Mç×\94îíÑæà³Ú½jæÃfäÄrâº_äÍ\85ïëÌîéÔíéÔîéÕîêÕîéÖíéÒíèÒîéÓíèÑíçÒìåÐìäÏìåÐìäÏìäÏéîâéîãéîåéîäëîåéîçêîçéîèéîçéîééîçêîçéîçêîçêîåêîæëîâêîæëîãêîäëîãêîäéîäêîäêîäéîåèîçèîæèîççîçæîçæîåæîæåíæçîææíåæîäëèØËn_×]YÔ^PØe[Ç[FÁM5Ã>%¼8#´4"°/\e¬0\18°>&»fBã©\81ä²\8cç¹\8eêÁ\9cÌ\8bmËsWÍuZÛ\95xÙ\89rÕ\81cÑyVÉpGÅiFÈiIÍtOÌxLÁz@»\84;{)º\92<Ê\9fH´\8b.Å\9eDÇ\9eK²\83-®~,Ù±râÅ\95ìÝ°èË\9aݼ\89á¸\86Ñ\97lÔ\8e]Ö\8c\×\8e^Ô\85[Ò\85WÎ\83VÆwV´X9µS4·T8ÃjQã\85Þ´\87å¿\98çÁ\99à¶\8eÞ²\89Ü®\85Ü®\88Õ\9ayÄrRÐtXÓy]Ôy]Ñz]Ô}aÒ{bÔ}bÓ|cÔ\80gÕ\85oÕ\87qÕ\87h±R7©?*¬N.¯]4¾d7½`3½c2·c*®c\1eb\13d\16Ä\89HéîÆéëÊéíÏçðâèïàêõáêùàëöÛêìÊâàÀÞÙµÜѧÛÉ\9cÖ¿\83Õ¶tÓªcÏ\97XÐ\92OÑ\8bBÒ{,Ëi\16ÃW\aÁP\ 4Á@\0ÁA\0ÂC\0ÅA\ 2ÌM\ 3ÎU\ 3ÇK\ 3À>\ 3¶H\ 2ºi\14º~&»\7f&¸\82-·\81,¼\860´}$³z#´z ±x\1c«q\18\94S\aâÓ\95èÚ\9cÌgؾtßÉ\8béØ¡º\94P¥g\1c¥e\12§i\13§g\10¤d\r¢h\10¥j\11Ì\947Õ\8f*ê½_êÈqçÄeèÃaèÇmèÇqæÂfåÂdݹWæÁeçÂdìÊjâºTÙ¯GØ®=ݱ@Î\9b&Ö§5Ü®>È\94#Ä\8a\17¼\82\16ßµIãÃ_åÇgäÈgìÒwìÔ~Ö³W¼\8b Å\90)Æ\941Ò£@Ö«MØ°NÖ°LÔ¬NÕJÅ\980Õ¬BãÁXܹTÜÆxäݪ×Å\88×µiâ»_éÃiéÇoæ¾^ä¹YæÉ|îéÎîéÒíçÒîéÔíçÑíçÒíçÒëäÏíæÒìæÑëäÏêãÎéáÌëãÎëâÍèîâèîäéîåéîåëîäêîåêîæêîæêîçéîçêîçêîæëîåêîæëîäëîäëîäìîâëîäìîâêîäêîäéîäéîæèîåèîæèîçèîèèîæéîäéîãèîæèîåéîãçîåèîãéîäܹ§ÖgYÚleÉdM¹R5ÂH0½D.»;!¶5!¯/\1a.\18®4\1f¬<"ÊyUݦ{ä°\89ä°\84è¹\94Ë\88dÉjMÊkQÕ\7fdÕ\80fÐ~^Ø\86^ÎvLÍqSËrMÍvPÍqKÑ{Jºd*¤S\10«a\1eµ\822È¢I³\893¦{%\93f\11«x/Ç\91XæÉ\9aëá¼ëÌ\9aéÉ\9aêÇ\9bÔ\9bnÒ\89^Ó\89[Ò\88ZÕ\8a`Ñ\86YÐ\83XÊyV¹c<¯D%»R:ºYC°bEçµ\86Û°\86ק\84Ü\84ݯ\89Ý´\8dà³\92áº\95ä¾\97ÅwWÔy^Òx[ÍtYÎuZÑz[Ív\Ô|cÕ\80fÖ\84jÐ}bÌw_¾bB\9f9\1e @"§V0ºh=»\5¶Y2¯Z%µl.ªb\1dªa\1cÂ\82AêÐ\9aæÐ\9båÎ\9dáÊ\94ãÌ\97áÌ\98åÒ¢äÏ£èÖªêØ©êÝ®ìß²ëâ¹ëå¾ìå¼ëå¿éëÒéíÔçïØæñÔæõàçôÚèïÐãáÂßÒ¨âΡյ\8dÍ¢gÈ\8aHÅv-ºc °N\13£O\ 5ªa\12¬h\1a¥h\12¬r!°s#®q\1a±t ªq"¡e\ f\89@\bi&\fòôÃÖÂ\80ÞÄ\82ÛÁ\81æÓ\9dîݬ®\8bL¦q/«q,°|6¹\88C¾\93JÁ WÞ±YÏ\92,æ®JìÆeêÉnâº^æ½\çÄdçÆjéÈqéÉnçÆpåÁbçÇjêÅdä¿Xß·Pß´HÚ¯?Ù¬<Ú¬5Ù©1ܬ9¿\8b\15Ë\94"Ù«8Þ´JÒ¦9â¼Rà¾YëÎtÛ¼]Ê 6È\9a1Ô¨BתEÛµSÚ²N×HØ°QÞ·TΣ<àºTâÁbéÝ\90ëæ°ÙÀwÈ\9d?Ñ«SæÄjâ¾dçÆkèÅiëÈnëÅiíâµíèÑìæÐíæÑíçÓíèÓíçÒíæÑìäÏìçÒëäÏìåÏìäÏéâÍêâÍéîáêîàêîãëîáìîâëîäêîäêîæëîçëîçêîçêîèëîçëîæìîâìîâëîãìîáìîâëîãìîãëîäìîäêîåèîèéîåèîçéîæèîçêîäéîåèîæéîäèîæèîãèîãèóíÓ\96\83Úsd»Q?·?(¼>'¼<(¹:&³6".\1e®-\1a¯.\1d§+\17°K/Ú\9cwá«~à¯\85Þ«~â«\86ÄxZËnSÎu\Õ\84eÒ~`Ö\84cÔ\82\Ö\7f]ÃfKÊuRÌvPÊkAËj@Ìo@®T\1fN \99Q\14¤r*\97o\1e\91f\13\8aV\bÀ\96XÁ\89KñÕ¢ìØ©ëÊ\9dæÄ\93ìÌ\9fÔ\9aiÑ\88\Ó\88^Ò\88[Õ\8a_Ï\80SÂmCÃlKÁmF¢6\14¾V>ÃmL«^AªQ4á£~Ø¥}Õ¢xÚ©\83ݲ\8eÞ¶\95â¼\9aàº\97×£\83Çs]Ït[ÇjOÈnZËpSÎw]ÉhRËnZËqdÈjQÈoTÄmS\922\15\983\1c\98B(ºiD³Q/S2«S$«Z(¯d%¬b!³o.æÄ\8fØÀ\88×½\85×¼\84Ö»\86×¼\87Õ¹\86Ù¾\8dؾ\8cÕ»\88ÜÂ\90ÚÀ\90ÛÁ\95ßÇ\99ÜÄ\98ßÉ\9dâË¡âÊ\9aéÔ¤éÓ èÖ¦ìÞ±êß³êá±ìá¶ëä»ìåÀêêÂëîÈêòÎêôÖåðÚäéáãèØäæÏãݳÔÌ\98Ó¾\89Ê®w¿\9c]¯\8dO\91^)\8eV:ÓÄ\9aîç²ÏµmâÈ\83ÛÁ\83çÕ¢åשáÔ¤æ×ë߶ëåÀíêÏíîÑîëÃÈ\99Eà£@ìÃdçÁaêÇfèÇgá¼`éÇlèÅièÆnéÈnçÆlèÄláÀfèÄaçÁ]â»XÞ´GܳBÞ¶FÜ°=Ù7Î\9d'Ú¦/Ó¥3Ò¦5Ô©;Â\93&Ç\9a*çÆaëÌtàÂhÐHÓ«FׯHÔ¦EÔ«HÕ¬HÓ©FÛ±MÓ¨EÝ»^äÆeÇ\9d8Ä\97<Â\9aCÅ\9a>Ò¨MáÀfçÅlåÃmèÆlçÆgèÅcêÅaäÄrïéÎíéÔîéÔíèÔîèÓîéÕîéÔìæÒíèÓíæÑíèÓìåÐìäÏëäÏëîàêîàëîâëîâìîáìîãëîãìîâëîäëîãìîäìîâìîáíîàìîãìîâíîáìîâìîãëîãìîãëîäëîãëîäéîåéîçêîæéîæéîæéîåéîäêîâéîâéîãéîâéîáëëÜÕ\8a\80Ðo[±A'¸;+´:#¸;*³4%±.\e²1 ¬(\e±0"¡5%é°\90Ù£|اyìˤêÄ\9bã®\8aÅxZÄeJÈmQÛ\87kÐx[Óy\Òx^ÏvUÊmIÏsOÌmDËj@ÍmDÀa4¼c:®V(§P\18\9eK\r\9aM\r\9fU\15\9cP\ f\9aG\fݪtìÐ\9fëÑ£ëÌ çÇ\97çÀ\95Ð\8efÒ\86^Ò\85\Ò\85YÖ\8b]Ë\80Xµd>ÅuMÆnH ;\e¬I-·\D½fMÄ^MÂYGÜ\91oÕ\9dsÚ«\86ݱ\8fß´\95ß·\95ݺ\97Þº\99Ô¢\83ÃwYÀhPÃkUÄkPÁeQÀfN¼`JÃkV½bFÁfGÂgN\999$\91,\13\968!®U;¬L1K% E\1c¨R)¯c%¯g(«e(ÝÂ\8bؽ\85Ó¸\83Ô¹\87Ô¸\85Ô¸\86д\82Ó¶\85Öº\88Õ¹\88Ö»\89×½\8eÚÁ\94ÛÁ\91ÜÃ\94×¾\8dÙÀ\8f×¼\8bÚÁ\8b׿\86ÜÄ\90ÜÂ\92ÜÄ\8fÜÇ\90ÞÉ\96áË\9bâÍ\99ãÎ\9cãÐ åÒ¥ëØ«ìÜ®ëã¹ìá¾ëæÅéá¾ëäÁêçÍéëÍêîÏíòÏï÷ÔîõÎíëÀåØ¡Ê°oÝÇ\89ÛÂ\87æÕ¤åÖ¨êð×éîßèîáéîáéîÝêðÜ̯mÚ\9d<êÀbêÇiìËoëÍvíÍxëÊsêÉpëÊnéÈpéÇqæÃlçÈlçÆmçÂ_êÆ`ä¾\ß·NáºQØ®AÕ¨7Ò¡/º\84 Ô¡0Ò§9Ù²Eà¼VÁ\95&³\86\eÓ´TáÇlåÈmܸaÆ\9c?Ð¥CЦHÔ¬MΤF×JÏ©GáÐ|Ó´^¾\91+Æ\971È\9b4Ó¬KÕOض^ݺ[ܶTéÈoéÈuçÄjåÄgåÃfâ¼eçܳîêØîéÕíêÖíêÕîèÓîêÕíèÓíçÒíçÑîèÔìæÑíçÑëåÏêíßëîâëîáëîàìîáìîâìîáëîâëîâìîáíîßíîàíîàìîàìîáìîâìîâëîãìîâëîãëîäëîãëîäêîæëîäêîåêîæëîãëîãêîãéîãèîãêîâêîâéîãéïß⹡Ú\8apÀZJ®:#°6'±8#·;-´5+°,\1e¯)\1c². ¦)\1eË\80iå»\93ß©\85Õ\9dy߯\8a߶\88å¼\95é³\89Ï\84ZÈqTËqVÏvZÐuXÓyZÎqMÍqKÏuOÍpGÉh=Êk@ÎmEÆd7Äm5»W+¶O\1a·T"³O"I\17©G\1eç½\8cîÛíÓ¢åÂ\95߸\8aÛ|Ì\83WÕ\84VÐ\80TØ\99pß®\89à¥\80Ú¡xÍ\8bbÃjM£5\e¦?"±P4Ã[=É`FÍ\EÄT?Ú\91jÚ©\80ܬ\8aÛ²\8eà¶\93ܵ\92ܺ\96Ú³\90Ì\90s·dS·`Iº^F¿bLÁiUµZJ´WF¾_I·]D¹ZD¦D2\8d&\ f\930\19\98=\19¡E&¢A\1e\9d<\17§R,¯c)®c)ªb+Ùµ\82×¹\81Ôµ\83е\83Õµ\84Ѷ\84Ó¸\86Òµ\83ѵ\82Ò¶\84Ò·\83Ö¿\90×¾\91Ø¿\8cÖ¼\8bÕ»\89Õ»\8aÖ¼\8cÖ¾\87Ö¾\86×¾\88Õ½\86×¾\88Õ¼\83Ó»\85Ô¿\8b×Â\8cÖÁ\8bÝÇ\92ÝÈ\95ßÇ\96âÌ\99áÊ\9aãÊ\99àÊ\9bãÎ\9bâÍ\9bäÎ\9dçÒ¢éÕ¥éÕ¦ëÜ®ëÚ¨ê֣˯qÓ½yÜÈ\8dßÈ\92ãÓ¢çÙ«èïÛéîâéíáéîáéîÜÖÏ£Á\8a/ì¼\íÐyîÒ}îÐ{íÐ{íÐ}íÏ{èÇlܸ^éÇqèÆmæÄlÝ»WäÂ^â¼WëÉfå¿VÚ°?à·HݶCÛ±?Ú¬;½\83
+Î\9d*à·Kâ½TåÁXÞ·Gͧ;äÃ]àÅcèÐvéÌrÆ\9f=º\8b"Í¥@ϦDÓ¨IÕ²Nîæ¡éÞ\99Å\9b6Æ\98/Ì 8ݶLâÁaäÃiصXæÅhèÉièÆkèÈoäÁeåÂgçÄiæÁfãÅzîëÓîêÖîéÕîêÖîéÕîêÖîéÔíèÔíéÕîéÖíèÔìæÔìåÓëîÞìíÝìíßííßíîßìîàíîàííÞìîáíîàííßíîâìîáìîáëîâìîáëîâëîãëîãëîãëîäìîãëîäëîäëîäëîäëîäëîãëîãëîåëîáëîáêîâëîáìïßâγڢ\82Ó\88i²N68#¬2"®4 °4$¬2 ¬/\1f0\1d²4"¥>,ïÁ\9aâ²\82ݨ\83ݨ\85ìÃ\9fæ½\91Õ¡tÚ¤vܦvÐ\8ekÇjPÑxZÐvVÍpNÍpRËpSÍtTÐxNÆh>Èb;ÀX3¾Y(¿`+¼Z+¶L\1f¸Q'´O\1d³K\1e¨J\1eðË\9díàµèÈ\9câº\91Þ¯\88Ø\9bpË\88ZÑ\88UÓ\8fiã¼\92Ù©\83Ñ\8beÕ\96iØ¢uÐ\8bj\9c;\1f¯F&ÎmGÇcAÁT:¼D+²=$«<&â\9e\7fÛ¯\8cÚ°\8eÛ±\8cÙ²\91Ú¶\93Õ©\88Ñ¡\80¿\7ff«T;°R:°N:µQ=µXE®P>®P<°U?³UC§I4w\e\ 3\87*\f\947\19\97C'\915\1c\87,\f};\16\9d]-¬f/©g/Õ|Ö¶\84в\7fβ\7fÒ³\83Ñ°\80Òµ\83д\83г\83ί~д\80ѵ\84ϳ\83е\81Ò¶\85Òµ\82Ô¹\86Ò¹\84Óº\84Ôº\88Ó»\84Ô»\84Ѹ\82з}×¾\89к\86Ó½\88Ô¿\89ØÂ\8eÚÀ\8cÚÁ\8fÙÀ\8fÜÂ\91ÚÂ\8cÝÄ\91ÞÄ\93ÛÅ\94ÛÅ\8fÞÉ\94ÞÉ\93äÎ\9bäÏ\9bäÐ\9bÖÁ\8a¿\98WÛÂ\88ÚÄ\8dßÉ\93ãÒ¡éßµéïÜêîáêíàéíãíòá¹\8c9Ø\9c9ìÊjìËvíÏyìÎyíÏzíÐ}ëÊwèÆnçÅnéÈsçÅjäÁeäÃiß»^çÃcçÂcáºRÔ¥2Ý°<á¸IݳCݲ?Ï\9f)Ú4ã¹Dà¶Eå¾Râ»PåÀVåÁ\çÈléËoæÊmßÁbÃ\982Å\9e5È <Â\961Ò®OÛÂoÅ\954Í¡<دIâºSä½WåÁ\çÅgæÄgåÅmèÈmêÍvèÇpæÅjåÁhãÁ^æÁ\Þ³OïêÊîê×îêØíéÔîêÖíéÖíéÔìèÕíè×íèÕìçÓëåÒëãÏëîáííÞííÝííÞîíÞíîßíîßíîãìíâííãìîãìîäëîåìîáëîäìîâìîâëîäëîãêîåëîãëîãìîáêîäìîäëîãëîãìîâêîäëîâëîáìîàëîáìîÞíîÚæдÙ\9e\80Ö\90s·bD¨6'°4%°7&¬0"«-\1e®.!0#ª.\1få§\89è½\92ߪ\7fÜ\9fvÛ£zß®\87ëÃ\9bæ¼\91Ú¥{Ñ\8bfÞ\9euÔ\87bÏuXÐsPÐqPÔwZØ~bÚ\83f×\7f\Åg<Â_8Âa8½U#¸S#·P*¿S.¸L#´K!¶F\1f»W3ðݶçÑ«ãÁ\95Û±\83È\90dÆ\88\Ð\95oÉ\8d_à±\8aäÂ\98Ó\9asÑ\85aÐ\88]Þ\9ctß\9dzÄoKÐjDÒiKÊfLÍeEÏdAÊU?µ>0¥>/Ü\9d\82Ù«\8bݲ\8eÕ«\8b׬\8bÙ¬\8bÉ\99uÅ\8eq¬cP©O8£K0°U@§L7¯U@§M5T>ªN:§L4q\19\ 3\7f"\11\841\1f\8c9$\7f/\12X\19\ 1H\e\ 1\8bZ1\9ef6¥m:˧u׸\86Ó´\83ϱ\80ά|Ю\7fί~ѵ\83б\80Ï°\80ϲ\82α\81Í~ή\80ϲ\84Ï´~δ\80Ò¹\87Ó¹\87Ò·\85ϵ\82е\83е\83Ó¹\87м\87Ñ»\88Ô½\89Õ½\8b×½\8bÕ»\8aÖ¼\8b×½\8c×¾\8cÚÀ\8f×½\8cÚÂ\8fÜÃ\91ÚÃ\90ØÄ\91ÞÇ\8fßÈ\91ÝÇ\90ÙÃ\8eɯu¯\90NßÍ\99ØÁ\89àÉ\93äÒ¢ìéËèîßëîáêîáíòåĵ\80Á\8c.ä¬HéÆgêÈnà»`ëÉqìÌzìÍyéÉuæÆrëÉsæÄlÝ·]æÁiæÅoâ¿aä¼XèÂcã½YÀ\8e\1fݳFãºLâºJÞµCÚ;à´CÝ°7à²Cã¼QáºPà»RèÃ\æÂ`èÈdêÌjêÎo¾\973»\92)±\85\1c\7f\15¯\80\17Â\91(Ñ 6جEá¹Oâ»Vá¹SäÀZçÃ`èÉméÉnäÃiéËséËuåÆpÞ¹bå¿bß¹Wä¼]êß°îéÙíêÕîêÖíèÖíé×íèÔìçÕíæÓîéÔìçÒìçÒìæÑìíÞìíÝíîßîìÜíîÞííßíîàííâëîæíîãìîãëîåìîäëîäìîãëîãëîåëîãëîåëîãìîâìîâìîãìîâìîáìîáëîâìîâëîãìîàìîàëîáíîàíîÜéàËÓ²\90Û¤\85Ù\93zÚ\86o¯<,¯7'¬7\1f«-#®,%-\1f+\1eÃcNìÁ ç±\8dá\98xØ\7f`Ô|[â¥\7fì¼\91â³\86ߥ\80Þ\9dyÔ\95jÕ\90eÎzZØ\7f_Ö\7f[ÓyW×}`ÑwYá\93tÎtPËlFÖ|[¿Y2¨B\17 8\11¬7\e»O.±K#Â]2½a>ì˦ãÁ\97Ù«}Í\99i¿zRÚ¢\80Ò\9fyÕ¦\81æʫد\83ÁsGË{S¶`6®Q3¹X>ÊnLÌnDÆa7ÊcCÖ\80\ÔzTËgKÅ^DÃbKÁeMØ\98{Ó¤\80Ù«\8dÓ¤\85Ö§\85Ê\9bz¿\8dm¿\84p L;¥L-©Q7 F8£H5¥I9¨N8 D1§K3r\18\ 5c\1a a\12\aq\19\ f\8cB%µxT\9b_@\8cQ,\89U'\8bZ0½\9agÔ³\84Ñ°\81Ì«{Ï®~Î\7fÏ®\7f̯\7fÌ®~ͯ\80ί\82ΰ\84Ì®\7fͯ\7fˬ\7fγ\82Ô»\85ˬxË®}ȬzË°~Ï´\82Ѷ\84Ï´\81Ó¸\87ж\84ϵ\84Ó¹\87Ѷ\84Ö»\8aÒ·\86Ó¹\87Ö¼\8a×½\8bØ¿\8bÙ¿\8dØÀ\8f׿\8eØ¿\8eØ¿\8aÜÆ\91×Á\8dÕ½\86À¥k¬\88JÜÇ\90Ô¿\89ÙÃ\8bàÏ ëæÈíëÔîïßìîßÖͧ±\86.Ò\955åºYéÈiêËsìÍvëËxëÍ|ìÌ{ãÂnäÂkèÆpéÇrêÈsèÆpåÃièÆnåÀaèÄaèÃa¾\8d\1fÙ¯Jâ¸NÞµDá¹Hܯ=Þ²AØ©4Ú®9ݵBâ»Lâ½MÛ²FÞ¸QãÁZæÈiêÏrÚ¼_¨{\17±\83\1a¸\89\17Ê\9b*Ó¤7ש;Ú©DÝ°Iß³LݳKÞ¸Qá»UéÅkëËpìÌréÌwâÁdß¾]æÃmäÁfçÄ`å½^ëܪíèÖíèÔíéÕíèÕìçÒíèÓíèÖìèÓîéÕíèÓëäÐìçÒìíÞìíÜííÞíîßíîàìîáìîäëîçìîäëîæëîçìîåìîäìîãìîâìîáìîâìîãëîãëîãìîáíîàíîàìîâìîãëîäëîãëîãìîßìîáëîâìîßëîÞêäÎ\84iEݨ\88ã³\90Þ\9b\80Ñn\¾O6©9"·M2¥/#©(\1eª+\e©)\1aï¹\96ç½\92ß\97uÎlIÐbKÏdWÎkNÕ\80Zã\99tÞ\95rÒ\8bdÑ\8c_Í\84ZÎ\7fXÌuSÌuS×}`Ø\81dÙ\80dÖ\82dÖ\83`ÌrGÑyPÅh;½_6¬D!«<%©:!¶M+Ã_8Àc7ì¿\92ׯ\7fÎ\99lÆ\86`É\85bÚ©\81Ö©\85áĢ߻\94Ë\87_¯O(¹`DºeB±R4¸P5ÏpGÜ\87[Å`3ºS1¼Z@ÉjLËmLÍlI×\7fkËq\·\BÎ\8duÓ¤\85Ñ¡\81Ï\9c|È\95x½\89n²yc·rY\9bC.¡J7\927(\9870\9770«]GÆzcÈr`¯`Jx2\eT\b\ 2c\r
+q\18
+y \14\81(\16\884%\96R3£j<½\92cÑ°\81Í«|ɨyʧx̪{Í«}ˬ\81ʪ|ɧxÉ©zŦ{Ç©}Ê«\80Ȭ\7fĨuº\94^¢rÊ®}Ê®~˯\7fγ\82̱\81Ͳ\7fͲ\82ж\87Ò¸\88д\85ϳ\83г\84Ò¸\87Ñ·\83Ò¸\86Ö»\8aÕ¼\8aÙÀ\8fÕ¾\8cÕ½\8c×¾\8bÓº~Ôº~ж}δ|¼¡h®\8bIܾ\81Í°qÍ»\85Ϲ\8d´ q¼«\81Ï¿\9cáÔ¨ª\88>¿\8b,ß\9e<â±RçÆjìÍ|éÉvëÌyæÃwìÐ\80á¿mãÀléÈsèÈsêÊväÂnçÄnãÀhܳNâ¼YéÄbà¸Tå¾Vã¼TÞ·HݵCÝ°<Ú°<׬7Õ§0Ù¬:á¸Kݲ@Ë\99,Ì¡9äÁ^ãÆdèËpçÍoÃ\993¼\8e!É\99'Ò¢3Ð\9e,Ò¡0Ó\9e-Û¬9Û«<Þ¯AÛ¯>áºPåÃdéÈméÊpèÇoݺYãÁbãÀbâ¿bäÃ`æ¿açÔ\9fíèÕíçÔìçÒíèÖìæÔíèÔíè×ëåÒìèÖëåÔíéÔìæÓíîàìîáìîãíîãííâìîäìîäëîåëîæëîåìîäìîäííáìîäìîáíîáìîâëîåíîâíîáíîàíîàíîàìîáìîáëîãêîäëîäëîàëîàëîáìîáíãÉ\99nJÇ\96wÍ\87oå¯\93ËydÍfWÎcO¬B*¦;!§1\1f¤$\19¨)"Èm^ë¸\8eß\95yËaJÄT:Î`EÎdLÌeGÏkNÆcCÕwUÑzQÌ\80VÎ\81^Ð\7f^ÌvVÑ\7fZÔ\82`Ò\7f]Û\92rÍ\80XËyVÐ\7f\Í|[Ô\80`ÀiDá\9ctã }ÅwQ£;\1c©:\1d¦;\17Ú\9euÑ¡rË\93gÅ~XÖ\9d~åÄ\9fêË£àǤګ\8a\910\19ªC-µX?·d@²V5ÐmKÜ\81Rá\88[½P&¿M+¹N+ÒqT¼T3Ú~\Ów[ÂcE£4$¦B8¿\7fgË\9c|É\97zÅ\91s´~c¦oY«vW\96K;\8d1-\8c,!\922(¹eOÂo]²WD\90\1f\12\91%\1aºcO\808&a
+\ 5r\16\ ey\17\13}\18\r}\14\fw\15\v\8eG/ª|UÌ¥\82ʦ~Ç¥xɧxÈ¥y̦wÌ£zÃ\96o»\88\Â\94kÅ vÂ\9br v¿¤x½£rÀ£o§wÇ«xƪy̱\81Ê®|˯yβ\81Ë°\7fϲ\81Ͳ\80ϵ\82ϲ\80ϲ\83е\85е\83Ó¸\87Ò¶\86Ô¾\8cÖº\88Ù¿\8aÖ½\8cÖ»\87е{Ç«mѸ}̱x»\9eb¯\8bF½\9f]Æ©k¶\9fi²\98h³\9em°\9dm±\9ej\92n)±\820Å\8f-Ü¡>ä¼_éÊséÉuêÉrëËwëÍ~éËyâÃrêÊyéËvéÉsß»bÕ®Zá¾gëÊnÞ·QçÂ`èÄbéÆdèÂ^ã¼Sç¾Oà·EÞµ>ß´@Öª5Ë\9c\1f²\81\12±\85\13Ê\9f/Ë\9a*Õ¬IæÆgáÃ`äÄdÞ¼^É¢?¿\8f\1fÍ\9e/Ð 3Ï\9f0Í\9a%Ñ\9d#Õ¤0Ñ¡)Ô +Ú©6Þ³IáÀ]Þº]åÃfãÁdçÇmçÆjâÀbäÃhæÃcåÀ\áÈ\87îéÖíçÒíéÔíèÓíéÔíèÔîê×íèÕîê×îêÖíèÖíè×ìîâëîæìîåëîçìîäìîåìîæìîæìîåíîäíîáíîàîîßîíàíîßíîáëîãëîåëîâìîáìîàííßìîáíîàìîãìîàìîãëîâëîàìîßìîáìåб\89dÆ\90jÚ\94{¼gP×\91xÈo^ÏjZÃQD¸M=¦<&¨2"¢$"\8d\e\ fï²\98â¢\83È`KÇVCÄTAÊ[DÍ_FÌgMÑlTÉ`GÎfO»R?ËlSÓ\81bÑ\85aâ\98xà\9evé®\8bå¢\81é\86åª\85âª\87åµ\95Ý\9f{Í\86_ä¥zØ rÚ\9arß\9dw³X9\9f=\1eÁkDÚ¡|Î\9dpÈ\90j¿nPå\88çʨåɤӮ\85Â\81c\96.\e\92\1c\f®M4»dB¸_:Ô{TÇc8¹K ºI ºR0Ù\7fXÃW;¬;)¸M4¢4\e¤<)\9c-'\9f1&©UDÂ\83rË¡\81Á\90t´\83d£oP\9dfO\91J8\872)\97@9¶_O 5-\86\19\1a\89\18\18\8c\18\17\8a\18\15\85\14\13Ár`]\r\ 4j\13\fs\14\11v\14\10y\14\11u\ e\v\864(¥sPˤ\7fÃ\9fwÀ\99rº\88^£eA\9bK%\938\16\958\18\949\19\94<\e\96<\1a\9cD%¦]@«rTÁ\98rĤw¿¢p¼\9foħxĦvÅ«yÆ|Ƭ{Ȭy˯~Ë°\7fË°~ϱ\81α\80г\83е\82Ѷ\84Ó¶\86Õ¹\89Ô¹\84Ô·\83Ô¸\85Ô¹\84Õº\85Ó·\82Ñ´\80Ë®x·\97X¯\87F¶\97T¤i¡\89P«\92Y¬\97b«\98e¢\8aN¡q!´\86&Ñ\952å¬KèÄhéÉqæÆiçÈtêËzíÐ\84ìÏ\82èÈwëÊuíÎ{Ú²TÊ\9b:Ó©MëÊrëÌtéÈjæÃaèÅdéÅdèÅaâ»LÜ´=ß´>Ù¬5Т-Õ§4¨w
+\8bW\ 3\9al\bׯCݵOãÀ^ãÃ_äÄcÛ»WÐEÊ\9d3¾\90$Í\9c0Î\9e.Î\9f+Ï\9e+Ó¢,Ö¨4Õ¤-Ô£,Ö¥6ÚBà¸Sß¼YèÅièÆkíÑwèÉmåÃgåÅiæÀ^åÀ[àÇ~îìÔîêØîêÖîë×îêÖîë×íéÔîêÕíê×îêÕîêØîêØëîãëîæëîæëîçìîåìîäìîåìîæìîåíîâíîÞîíÝííÝîîÞìîâìîâìîâëîåìîâìîâìîàìîáìîáíîáíîàìîàëîãìîßìîßíîßêàË\99lN\9c`DÕ\98}Æxe¹]DÏ\7f`ÎrVÑfVÄRFµG:¬?/£.\1f\8f\15\ e±]Hç¨\8dÊhUÆTIÅO>ÇQEÈYFÌ\EËeOÍaNÇXEÅXC»L9½F2Øx^Ø\88jÐ\7f]â\9duÒ~YÊ`AÔw[×\86fÙ\8emÙ\9dwÚ\9dzÚ zà§\80ߥ|Ü¢wÞ¥}Ý {â¦\80Ù yß©\86Ó\9du·mR\99)\1e¦B1²^N¯YI¾x^Y;£?#\93(\12\91'\15¸T:ÆqLÂc:µK$¹I#¬E\1a²L(×{T»M*·P:´B0¤:\1e¬J5\9a4)\99/!¯TGªf[ªgXÄ\90r²\86m¥sX\8eQ8\8aB/¢XG\812"w\13\ f\80\11\13{\11\12\80\14\16\84\15\16\86\17\16\84\13\12¬XK\829)c\10\fn\18\16v\18\17w\12\12s\11\11\85*(\9d]IÃ\9bw¸\8fl\9e\>\9a:"\930\14\93+\11¡5\1c\97,\13\93&\f\8f"\v\94'\ f\96(\13\95*\17\972\1d\8e9\1d\9cc?²\8b_¹\9ev¼¡w¹ oÀ¥vÅ©{©}Å©~É\80Ë\81Ë°\83Ë®\7fˬ~ϲ\82ΰ\81г\82Ѳ\83Ôµ\81Õ·\82Ñ´\83Ô·\86Ѷ\81Óµ\80Ôµ\83ϳ~Ë®v²\90N°\89F¼\99Z±\93V\99\80Iª\94\©\95Xª\94X \87E\99l\1dÊ\97>È\84%å°LèÇlëÐ|íÒ~î×\8cíÓ\88íÕ\8déÌ~çÅséÇqæÄpÁ\923Â\925çÃléÊsëËqëÊoéÉlçÇfëÍmêÇaÔ©7ݳBܳBÕ¨1ש4Ï\9f-\8cX\0\89Y\0³\81\eÙ±IÚ·Oà½YâÀZáÂ]Ô³QϬL³\84\1d¼\8e$Ã\96+Ð 2Ï\9e-Ñ£0ب:Ú«<ب8ب9Ø©:Ú¯?߶OåÂ\èÇgçÅgêÉnìÍtëÌsåÄjâ¼Vç¿[âÅ\88îìÙîëØîìÙîë×îëØîìÙîêÛîéÙîëÙîëÚîêÚîêØìîãëîåíîäìîäìîåìîäìîæëîçíîäíîâîîßîíÜîíÝíîÞíîàìîáìîãëîäëîäìîâíîáìîáëîâíîáìîâìîâëîâíîáìîáèäСyX£iE©mNâ§\97Ão^¾aEÑu_ÉhUÎgYÇWDÂRGµH2\9d*\18¦4%å¡\82ËkPÌXJÇQEÆN?ÄK:ÆQ=ÉZCÑbMË]GÌXAÇT>¼H0¼?-ÁK7ÊcFÏnRÇcGÄ]AÉ[CÈ\HËcL¿aDÊyT×\96rÖ\9bqà©\80à¨\7fÞ©\81Þª\82Ú yÛ\9fzÒ\97rÎ\90qÑ\8el\92!\18\9c\1e\19 )\1c\96\1e\1a\8f\16\ f\87\r\aªJ7¼cJ¦B&®G2\9f8\1eÔ\81T¶V)¶N'¶P)¯M%¸X,ÈnC¬L#¿ZAª?+§=$¥@-\993!\97(\1a\9eD5©aZw \e¸xb°\84i«{a\87O1\99Q@})\1cr\ f\vt\10\11r\f\rt\f\rv\ e\ e\80\14\12\84\17\ e\83\18\11ªVI\92L?b\r\bf\14\rq\16\11q\11\ fr\14\12\83(&\9eVHµqX\922\1e\960\1d\8c%\13\8a#\11\9f7#®Q5\97,\15\92!\v\91"\ f\93(\13\8e"
+\91&\12\8e$\ f\8f'\ f\8c+\11\8f7\19¢iD±\92l¯\93e¸\9aj´\98fº¡x»¢{À¦}Ū{Ũzƪ{ͬ}ˬ{ϯ|Î}Ô³\82Я{Ñ°|Ôµ\82Ó²\81ϯ{Ò±~Ю{Ï®yÇ©q\8bL¨\85>¡\81>\9a{:\83f-\92zJ¤\8cS¥\8fH®\93MÁ\97@Ð\9d8²k
+à¤AïÑwìÒ\7fîÖ\8bíÕ\8aíÐ\84éÌ\7fëÏ\80Ù¶cÛ¶]Ø°Z½\8f3ܶ[éÊqìÍtíÍuçÆhëÈjéÈièÅaçÂ[Ú®=ä»Hà¶FÛ«7Ò¡+Ú®;¼\90\1eÉ\9c-Õ¦7áºPâ½Vá¿ZáÀYݾUÏGÆ£CÄ >Å :Â\97.Ç\99,Ó£4Ô¥5Þ±CÙª;Ú;Ù©8Û¬;Ú«;á¶HàºQæÃ`æÅhèÈlëÌwèÇræÅlá»XãºYعzïîÚîìÙîìØîìÚîìÙîìÙîëÚîíÜîìÙîìÚîìÚîëÜìîâíîâíîåíîãíîãíîãìîäìîäìîäîíàîìÞîìÚîíÛíîàíîàëîäëîãìîâìîâìîáìîàìîâìîâìîâìîâëîãíîáíîÞéâÍ\8ff=\81O&\83R)\93_<Ú¦\8dÏzdÌmVÙ~mÉeTÊdUÉ[NÉ[MÂVB\95\1c\12ÂcNÖ\84rÍYJÆP@ÃK7ÂH5ÄL8ÄP>ÉZAÉZBÉ[DÇW@ÀJ7ÀB.¶6 »>0¼H-ÆU:ÌZCÉZDÃR:ÄO=ÅR<ÌmPÄvPÍ\88eÖ\99yܤ|ݨ|à¬\84ß«\84Þ¦~Ú¦}µsS\86,\1dÆmV£* ¯;3809/¢,\1d\93\1d\16\89\1c\11\96+\1e´J<ÃdPÄwTÒxN°O"®H\1f½`7¼Y6ºX4ÊpK©H$ªA&¡9\1d\9a0\1e\90-\1f\93* \89!\e\8e7%\99S>m\16\18j\1e\18¼\8av\7fc\8eXB\85<,m\16\ro\ f\fi\f\bh\a\ 4m\f\vs\ f\ry\11\11{\16\11}\17\13\91:6¥]Y]\r\b`\ e\vm\15\11o\13\11m\12\ f|#!\84*'\83\e\14\8a\1f\14\8a\1c\11\8f#\1a¬L4ªQ?\95(\10\8b\1f\ e\90#\ e\90&\f\92(\13\8e!\f\8f#\v\8a\1f\a\8a!\b\8c \90(\ f\8c2\17\8dK(²\8e`\96i¯\95f´\99k´\9ctº\9ev¾\9fq¿¢mÂ¥vȨt̪wÎ{Ï®~ѯ\80ÐzЮ{ÏzͬxάyÏ®yЯ{̬xãkª\87Hª\818\97t)\7fa\14G.\ 1;'\0A,\ 1D-\ 1\9c},Ê¡<Õ¢1¶l
+ߨGíÌqíÑ\81íÕ\88îÔ\89ëÎ\81íÒ\86íÒ\86ëÍ\81ìÐ\80åÅoزXà¿fêÌrëËsìÊsæÃgéÆfçÅcçÅ]ëÇ_ã¼Mä¾Qâ¹NÜ°<ר1àµFÖ©3Õ¥4ר8ß³DÝ´Há½SãÁXÙºRʧ>É¥CÕ¶WßÂe»\91)È\9b2Î\9f0Õ¥9Ú¬<Ý°?Þ²@Ù¨5Ý®>Ü®=Û®=ܵKâ½XçÃbéÇièÉmäÄjß¼`à¼\àºSÕ¹pðîÚîíÚîìÚîíÛîìÙîíÛîíÜîíÚîíÚîìÙîìÚîìØíîáìîäìîäíîäíîâîîâìîäíîäìîäíîàîëÜîíÝíîàìîáìîâìîâìîâëîâìîâíîáìîáëîâìîâìîáëîãìîãëîãêæÐhP4f@\18pD yQ/¯\83^Ô\95qÒz[ÐqXÖ~iÇbRÃ^PÉ\MÉZK¹H5\99\1f\17ÖxhÎhWÂL@ÃK>½I6¾H5ÄQDÉ[HÎ]FË\IË^IÊWEÁJ9¿F.·6&³='ÉU=ÌX>ÇS:ÊS@ÃN7ÃN8¿L4Ê]HÒ\84kØ\9fzá³\8eÞ®\8bà\88ã¯\8då²\8cä°\8cæ´\90Ø ~\86(\18®>1µ?/·90°90ª62«8/¡."\99(\1f\93 \15\89\16\v\87\e\bÝ\94r¿b7¶T)·T*¾_4¾b4ÓvP¸[1ªF!\932\18\950\1e\8f,$\82\1e\1a\7f\e\1a~\17\1a\80$\1f\89<1`\ e\ eV\v\ 6v;2´\87r\9flN\86P/X\ f\ 5g\ f
+e\v\ 6l\ f\ff
+ m\r
+s\11\ fv\13\12\7f\1a\19\8f81\8d?7j\e\17\\11\ fg\16\15m\12\10p\11\ ft\15\13s\11\ f\81\e\18\84\e\19\8a\1e\15\8c\1e\11\90%\15\8b \r\8e"\ e\9a/!\9d3\1c\92%\v\91$\11\8f!\12\8f!\ f\8f"\f\8a\1e \87\1f \87
+\8d(\ e\8c.\13\91I)¯\93hª\92e¯\95h±\96o³\96l»\9eq½ m¿\9eoÄ¥qÈ©yˬ|Я~Ï®~Ï|άzÍ©zͪv˪vË«sΫvƨtÀ\9ec¦\84A«\837\94s+eI
+8'\ 39+\ 4Z@\v\8ah\1a˦H׫BÞ¯@¿}\15å²SëÊqíÑ\80îÔ\84íÓ\89ìÐ\82íÓ\87ëÐ\86éÍ\82éÎ~ΩUׯVåÅrëÌxëÍwéÈiêÉfçÃfçÂbåÀXäÀVáºJà¹Kã»Oà¸GÞµEÚ²BÆ\93(Î\97%ק8Ù®>Þ³KÞ·HáÀUÙ¸TÕµWÙ¼_ßÃbçÌqÅ\9e4Å\96/Í\9f6΢4Ó§<Ö¨:ب;Û®=ܯ>Û±AÚ°AÛ³Dá¹Sä¿]åÀ_ëÇfߺXÞ¶UÝ·RߺP׺sððàîìÚîìÛííÝîíÛîíÝíîßîíÛîíÜîíÚîíÛîìÙìîàíîáìîäíîãíîãìîäíîäìîåìîãííàîíàíîãëîæëîæìîâëîãëîãìîãëîãìîáìîâìîâëîâëîâëîãëîåìèÖ^C U3\ fR3\vQ2\rM2 ¨\82WÙ\9exÊuTÒqVÃ_IÃbRÊeZÈWO¾Q<²@*°?7¿TI¿M:ºC1¹D3¿L7ÀK8Í\MÑhPÔgNÈWBÊ[EÌUCÁI:¸>)¹:)ÊU@ÍVFÈP<ÅO8ÅM7ÂL5ÀJ4ÀI8¾K8Ðs_Õ\9atݬ\89ã¹\9aá°\8fá\87à\85áª\83ߨ\84Ô\9bw\8e/\17ºSB¸G:¸=0¯6,«72©9/¦5,¤6,¤4*\94'\1a\8e\1d\10ªH5¿`9¼\3²S-Ãd:Ái9´R*¶Q4¢H(\8f3 \87%\1d\81\1d\1ey\18\19o\ f\14n\10\er\1e\1dv+!R\f\vL\f\b<\ 4\ 1uF>¯\80g\9abDW\12\ 5_\12\ah\15\ 4d\11\ 3c\ e\ 4j\11\bl\ f\vm\f
+x\14\16\860*\9bM:o\19\10T\ e
+X\11\14n\16\15r\12\11p\ e\10v\11\10w\12\ e\81\17\13\84\18\ e\8a\1e\ f\9a2"\8d#\ e\8d"\10\8e"\r\8c$\10¸\7fn\8d)\10\9a2 \90!\ f\8b\1e \89\1e\ 5\85\1f\ 5\86!\ 6\86&\b\82%\b\85+\r\93X4¬\91c«\92g¬\92f£\86Vµ\97n¸\9cl¹\9aoÀ\9fl̤wȤwÏ«{ΧvÏ©uÊ£oÆ¢sƤsÇ¥sɨpɦnÃ¥pº\98^¡|8\9fz-\8ah ?-\ 30)\ 4\84`\11\80$Ê ?ܳNÛ¯FÙ«:Ð\91/ã¨BìÊlíÐ~îÒ\83íÓ\89íÖ\8aíÓ\8bìÒ\85åÈ{ëÍ~Ò¬WÔªOçÇrèÈrëÍxåÄfÚ°KÒ¤Fà¹Tâ¸Jâ»Ná¼KâºKÚ°Cá¹KݳBÔ¦4³\81\10º\87\rש5Ò¤4Û±?Þ¶HáÀYغUÜÁaÛÃeàÄdëÐvÔ±P´\86\1fÈ\9d5Ѧ;Õ©Dש;Ú«<ج<Ö§8Ú¬=Ùª?ݲIá¹RåÀ_èÅeäÀ]â½W߸NÞµLá¸NÙÁ\83îîÜîíÛîíÝîíÛîíÝîìÞîíÜîíÜîíÝîíÛîìÚîìÙìíáìîàëîåìîåìîäìîçìîåìîäíîäíîâìîåìîãìîæìîåìîâìîáëîâëîäìîäëîãìîãìîáìîãìîáìîáìè×\8bhLxO$uJ\1ck<\11j<\11_1\ 6¹\8emÚ§~É~\ÀfI§>.®=+²C6ºI9ÀM7¨(\1a³;4·I9¹J8·@/¹D2¿KAÉSDÏ\NÔcPÚfUÈUDÌXGËXGÁF<ºB/ÈO=ÉSAÍTGËTAÆM9ÃK6ÃK8¾H2ÁK4ÃN7ÀR<ÐuZà£\81ß°\8cßµ\8bã·\8bâ´\8bß«\84â¯\86í¿\95é«{ä\9fx¬S=°B3ª1#§3-¦6,¥6-¥6,¤8-¥7* 4%§;)»W0¼Z9Äi?¿c;®T+®L/\9f?!\94:#\8a+\1ct\13\au\12\11r\12\13h\r\ra \ri\17\11]\16\12E \f8\ 5\ 34\ 5\ 3-\ 1\0h:0\9diI\94T1\86U(\94`0\91b3\8aT#u8\10a\ f\ 4h\f\ 6r\11\ f\865,\9aZNi\17\10f\19\15P\v d\11\13g\ f\rj\r\13l\r\rs\ e\fx\11\r\81\18\f\82\1a\f\87\1d\r\8b!
+\8f(\12\8f(\11\933\1céîî´|`\907#\956!\8f-\18\83\19\ 3\82\19\ 4\7f\17\ 4\84\1e\ 5\85)\v\80%\ 4\80+\v\9coJ¢\8dd¢\8a`§\8ab©\90f·\91d¹\89f¸zO³i<«X+«Z2§T+¦T*±]1Ç\8acÇ\9dqÀ\9dl»\9dhÁ\9dj»\99g±\90U z6\9ev)uV\ e1\1f\ 3~]\14\99n\13·\85!ß¹TÝ´L׫DÔ§=È\8d!ß¡;ç¿Zà·\ã¾jéÉyìÏ\80íÔ\8cíÕ\8aíÒ\87ìÑ\84ìÏ\80ß½cçÆpèÇqêËuÊ\9fB·\83\15Í¡8â¼Wã¼Sá¹OݶFÛ²Bá¸Oä½QÞ¯AÚ;Â\91\1eѤ4Ï£5Ϥ3Ú°?߶IæÄZåÈeåÉiÝ¿^àÄbëÑtìÒ{º\91*Æ\991Ï¡6Õª@ج?Ô¦6×AØ=×<ݳGà¸RݶQá»UèÆcåÄgà¹TÞ¶PݱJÚ@ÕºlëéËîîÚîíÜîíÝîíÛîìÚîíÛîíÜîîÝîíÝîìÚîíÙìîáíîáëîãìîäëîæìîæìîåìîåìîåìîæìîåìîåëîæìîåìîäíîáìîáìîâíîáìîáìîáíîßíîãìîåíë×\95wV\87X5rG\15zJ\17{F\17{D\19\8dU/Ù¤\82µuRÂ\7fXÑ\8ej±R>¨<0¬;1ÁWE¯7-\9e\1c\17£/\1eª@0±D5½K=ÁMAÍYTËULÑYTÏRNÔUUÓ]RÊPDÊTKÉRDÈPBÉUBÉT?ÉSAÈS=ÆP<ÁH3ÂJ6ÅL:ÁI6ÃN9ÄTAÈUEÏnSß\9ey߶\8bä½\92èÁ\9eè¬\8aÚ\88hÛ}WÙuMè¤zïÆ\9cÞ§\7fË\83_ªE4 4(£5,¦8.«A1¨=-¥<-¾]B´N*¯M)½b9Àc=«Q*¥I'\944\17\87,\1d\82%\15j\14\vf\f\ f_\10\ fZ\r\vX
+\f\\12\14B\ 4\ 55\ 5\ 64\ 3\ 50\ 3\ 3,\ 4\ 4(\0\0\83W+\9ds9\97r/\8ef \91i&\83]\16\87[\18~M\13a\1e\ 4d\12\ 3|2(\94THg\15\10c\19\12Y\13\rc\12\ fg\10\ fg\ f\rj\ f\ fo\ f\fr\12\ fu\14\rz\19
+\81\1c\ e\85\1f\v\80\1d\ 5\8b#\ 6\8e'\10¤`Fß̼Æ\9e\8dÊ\98\83Ò¢\8c\85 \v\7f\18\ 3~\17\ 3\80\19\ 4\82!\a\7f%\ 6{$\vz7\18\9f\86_\9f\87_¤\8cc\9bhH\96A\1e\9b7\1a¢9\1c£3\13¦;\17§:\19¥8\18¥6\12¨6\18£9\1a¦L-±pJÂ\9bl½\97f·\95dª\87L£{6\99p%b@\ 5xX\12\95h\12®\84/Ë\9a<à·Xá¹RÛ¯GÓ§<Ì\9b1È\87\1cã°JØ®SÞ¸^ݹdæÃyçÉ\80íÑ\84îÕ\8aìÐ\80íÓ\84á¾kß»fëÍ{ëËu½\8f8º\8a,â»^èÆgçÁ[å½TÙ¯>á¸Ká·NÞ´EܱBÓ¤1Ѥ6Ù®EÖ«;Ø=Û²Dß·HéÉ[çÈ_æÆaâÂ`âÂcéÊjîÖ|Ì©GÇ\9c4Ò¢5Ô¨=Ú°CÛ«A׫AÚ¯?ت;ݲFá¹Qå¾XáºQä¾Yâ»Vß·SÝ´RÞBÚ¨:Ä\98;ΰsððÙîíÝíîÞîíÜîíÜîîÝîìÛííÜîìÙîíÛîìÚíîàìîàíîáìîäìîäíîâëîåìîåíîãìîæìîãìîäíîãíîãííàìîßííÞíîáííâíîßíîßìîäìíãîîÞ»\98v°zNuK¢e7¡^)\9c^-\98^'®m?µxI ]6°kBÀ{Y¸hO¦;-§4,´I9\9c(\19\96 \14\98)\1a 4#°A5ÅSGÊQLÐROÒUPÍPSÎLKÐJMÉECÇFAÉQLÉREÌUEÌXDËVAÎWDÉQ=ÈQ=ÆN9ÉS:ÇN;ÄO=ÇS>ÈQAÆQ@Ï]JÏgOÛ\8fnÜ\93sÕr[Ì^AØlLÛmKÝmNß\7f`ã¥{ë½\8eçÂ\90æ´\8aÊ\81e£7*¨=/¦=-§@-§=/°J/®I'±M(¸W*®Q,ªT,\98=\19\8d-\16|\1e\ fu\17\fa\f\ 6[\f\fQ\v\vL\b
+K\b
+J
+:\ 6\a7\ 5\ 62\ 4\ 42\ 4\ 3+\ 1\ 2l@\1d\94m0\85b\17zT\ 5\93m\1cwQ\0{T\ 5}U\ 5}T\ 4\8c[\16s5\ fv3\1f ]Ke\12\b^\14\rg"\1dT\10 [\ f\r\
+\ 6b\v
+d\r
+i\ f\vm\10\ 5s\14\ 6v\17\ 5}\17\ 4}\1d\ 3\80\1f\ 3\89-\ e\98G!Ò¡xг\8dئ\88½\88f _F}\1c\ 3|\15\ 4\7f\18\ 3\7f\e\ 5\82+ z%
+r%\ 6\88X7\9e\87[\87W,\88/\14\99.\12£.\13¢2\14¨4\12©0\11¨.\16ª5\19¢/\r¢.\r¢-\f¥7\17¢=\1f\9dK(³\80M³\8fY§\85D\9cp*\93k!bB\ 4\95d\11\9fh ½\91:Ò¬QسVå¿[Ú±AÕ©<Ò¤8Å\80\18Þ¤=ݳUá½gÞ½fâÆtíÑ\85ìÐ\83íÔ\86ìÐ\80ìÏ\80ìÎ|ìÎzíÏ{éÉtÕ±VÙµXçÁfçÅdä¾Sã»RáºLâ¼Nà¸Oà¸L΢4Å\94\1fÄ\94 ×>Û²=Û±?à·FÛ°=à¹HæÄSæÆ`æÇgäÅdêÌlìÔvìÐs¾\95+Ï¡7Õ«FÙ°D×@Ó£6Ù®<Ô¨6à³E߶Iæ½RáºNã¼UݳHÛ±DÙ¯Dܧ9Õ¦;Ä\98?ƧeïîÛîíÜîíÜîîÝîîÜîíÛîíÚîìÛîíÚîìÚîíÛìîàìîâìîâíîßìîâííáìíáìîäíîãìîäìîäííâíîâííàíîàîîÞíîßìîàííÞíîàíîßìíàïïß \7f\\95d7¨h?¦h9¶wBµv@¸sE®m8Æ\81O\95Z&\8fN%\8eI\1f©d?µpNªP=«?1®?5 (\1e\9c%\1a\93"\14¸H4ÈTHÈQGÐVPÆJGÈNHÈNNÃHDÈIGËDFÅ<:ÉNLÏXNÑZNÏZJËWJËVIÎXDÊT@ËXCÉSAËVAÈT?ÈT?ÉU?ÌXCÌYBÐ^JÐbJÑaHÕhMÚnNÙvTÕnK×eGÓ_CÔlCà\9bnå´\88Ù¤xØ¡u£<&°=2¨9.ª@.ªA2¶V<®F'ªE&³U.®M(£F$\903\11\8c.\14z\e\ 5n\13\fZ \vS \rL
+I\ 6
+C\a
+?\ 6\b;\ 5\b7\ 5\b4\ 3\ 55\ 4\ 4W-\10\85Z\ e{S\bzW\ 6¬\8f@\7f]\a}V\ 5\7fX\a|W\ 5{R\ 3\85\\f\87X\15§sI\8eP6a\ f\ 5Z\12 ]\16\10[\17\16S\r
+R \ \r^\v\fd\ f\fl\11\bn\ f\ 4s\15\ax\19\ 5v'\ 6\80;\v\8aK\15\8eO\18\90]\17\90Z\e\9cn3¢zAu0\b\81* u\17\ 3z\18\ 3y\1a\ 3z#\ 6z&\ 4s \ 3g(
+\92nH{,\ f\8e+\v\97)\10¤,\14ª5\1a¬5\16¥*\13¥+\13¥-\15¢*\ e£,\v¨1\10¥7\13£3\14ª;\1e\9f6\11\9bH\19¤m8\98s+\89^\14|P ¨m\1dÆ\80\1fÍ\9e<Ï¥DجHÊ\9a+Î\9f.Ò¥;Ò¢:Á\80\17Ø\940ä»^çÄoêÌzìÑ\80îÔ\87îÕ\89ëÏ\80ìÏ\7féÍzêÊuìÍxìÌwéÊséËpéÉoæÄdá¾[ä½Væ¾Xâ»NåÀNæÁXçÁZÜ´HÁ\8f\1aÃ\8f\19ܱFà·Hà·FܲAÕ«9Ø;àºFã¿RçÈgåÈeæÇeçÈfãÄ`Ω@΢7Ò¨@Ù°FÜ´IÛ±D߶Hà¶KØDܲCã¾Sä½QÝ´JܱFجCÙ¨?Ý 2Ñ\9f2Æ¡DʱqíìÕîìÛîíÛîìÛîîÜîíÛîëØîìÙîëØîìÙîìÙìîàíîßìîàííÞíîàíîßîíÜíîßîíßííàíîßííàííÞîíßííÝíîßíîÞíîàíîßííÞîíÛòðÞ\91x[xK(zN(~K\1f\88Q\1d\92W#\9aZ%\98`(\9ea(\9f^.\9f\*©j7©g7®h@Ü\9as¿mX±Q>²E5©;-\9c+\1e³G;ÈXMÈQKÆOKÅMHÇPMÇNOÄNJÀFAÀ=:Á64Â<@ÏVUÐXMÑYNÏYLÕ^TÒ^OÒ]LÍXHÐZJÎVEÉQ>ËXCËVBÑ_JÑ^HÑ]GÑ`IÖdNÓfF×kLÖgGËc=Ë_9ÉU3ÉO/ÊP2ÓtTÎ\88`Æ\82RÉ\82\£4%«7(«=-=)¸Q9¼_8´N'´X:±Z9¦G\1d\9b=\17\924\14\89*\14v\1a
+a\r\ 3O
+ M\b
+K \rC\ 5\b?\ 5 ;\ 4\a9\ 4\a7\ 4\ 66\ 4\a@\10\ 5|O\b\8f_ ~U\ 2yT\ 2\8ck\12\7f[\ 5vS\ 3yW\ 4{X\ 4|W\ 5\96u#}Y\ e~Z"i*\ e_\12\aW\12
+S\ f
+V\13\ eS\r
+J\a\ 6R \ 6V \ 5[\v\b`\r\bd\r\ 6j\13\ 6v;\r\8eb"\86\\17\84^\18¥\86<vQ\ 6zY\ ewU
+\80\\16\84]\1azE\ft+\ 6t\1c\ 3t\1c\ 3t\1d\ 4m\18\ 3u&\ 4]\1a\ 2Q"\fv(\r\8f%\v£,\19 $\r\9d#\f³='±;#¦/\15¦.\14\9f%\r\99%\a£'\v¦*\v¢)\b£(
+£(\b\9f)\ 6\9b+\ 5\9aN\19\87Q\12yK\a¤s\1fÅ\8c.Ê\991Í\9c2Ì\980Ì\9a)Í\9c+Ò\9e0Ð 3½\7f\11Ê\82"ß®OçÂiìÏ|íÓ\85íÕ\8aíÔ\87ìÒ\85ìÑzäÇqêÎxíÏ{éÉuìÍvçÇfêÉlçÃ^Í 4È\9a-âºOâ¼Rå¾RäÀXáºMä¼OØ®@Þ´Hà¹Oâ»KÜ®8Ì\9c(Ï\9e)ت5Û³?Þ¸Gâ½Pã¾RæÅ\äÀSæÄ]Ú¸OÌ¡3Ð¥7Þ²EܲEݯBܱB߶FݳCß·Jß¹Mà·KܲEܱCÛ®HÖ¡:Ù\96&Ó¡8Ê©PÆpìêÖîíÜîíÛîíÛîíÛîìÛîíÚîëØîë×îìØîëÙíîÝíîÞííÞííÞîíÝííÜííÝîíÝîìÛííÜîìÛîíÛííÞîíÜíîÝîìÛííÞíîßîíÝîíÝñïÞ¹¡\7f«{S\9fk>\93d/\84T&zG\ fyC
+zF
+xE\r\80G\10\8aN\17\88K\1c\8bG!¦]4½qLÒ\80b¸WBÊjVÄ[H«J5´M?ÖtfÉWSÆMIÅMJÉQPÅLMÃJKÂGHÁDK½<@»;>ÆLMÌUNÏQKÏXNÔ]RÐYOÔ^MÍWDÎXIÐ\HÊT?ÍZFÍ[EÍVAÒ^LÐ_HÒbKÓeNÔfKÔjMÏaCË_?ÅU2ÃK)ÀI(¿E)¶@\1f»R-Í|U×\97l³Z>¤1\19³D,¶C,³D-³K4´O.¯J$¹[=¨J0§B%\989\17\8a.\11\80"\10r\13\fZ\v\ 5L\v J\ 6\bB\ 5 A\ 6\b@\a\a>\ 4\ 6;\ 4\ 6:\ 4\ 5:\ 5\ 6e3\1c\81U\ e\82Y\ 5}[\ 6yW\ 2\8ai\16wU\ 3vT\ 3xV\ 3yX\ 4tR\ 3\87h\18\91p#yU\14i1\ eW\ f\ 4R\r\aR\ f S\12\vI\f\a>\a\ 6K\b\aN\b\ 6P
+\bZ\r\a\\f\ 5o5\ f\80[\17}X\ f\8dl#tS\awV\auS\btR\aqO\aqP rQ\ 6vV\f\88_\1ewA k'\ 5h\1a\ 2n\1c\ 3j\e\ 4V\12\ 3= \ 3]\14\ 3\82\16 £)\1c¡&\10¢(\16§3\1c§5\19¨2\18¥-\13\97 \ 5\8b\1e\ 3\99 \a¡&\v£(\ e\9e$\b\9e% \9a!\ 6\98!\ 4\96'\a\811\ 5\7fK
+¸\8c8Æ\97>Ê\9b7Ë\9a5Ê\93,É\97'Ë\9d-É\97)Ä\92(Ë\97*¾x\ eÞ\9b8éÀaéÅoéÉuíÏ}ëÏ}åÇväÃoëÏ~ìÐ}êÊuëÊwèÊræÅeçÆeܵQÌ\9a*Õ¨<à¸Là·Iå¾RçÄ_æÀYâ½RäÀWæÂ\Þ·PÕª9Ò¥.Â\90\1fÌ\9c,Ù¬<Ø°<ݵBÝ·Dà½Já½Kã½JãÀSÞºMÊ\9f3Ì\9f2У7Ù®CÝ°FܳDÞ´CÞ´Eç¼Oå¾RâºNâºPá´KÑ¡3Ò\9d0Î\88\16Ó¤BͯbÆuñïØîîÝîìÜîíÚîëØîíÛîëÖîíÚîìØîë×îêÖííÝíîÞíîÞííÞîíÜîíÝííÞííÜííÜîíÜîìÛîìÛîíÜííÝíîÞíîÝííÝîìÝííÝñðÞº¡\80£rC§rD¦n8¥l6¤l3q9¤k/£n2\9c`,\95\&\97Y-©cFÂq\ÆlTËvaÍvdÕ{i¬B>®?:Á`UÑveÔiaÊVVÇOLÂMH¼FD¿GK¿KH½EHÀBKÆRXÄPQÉRSÌTSÎOTÐXSÎWOÑZQÎVGÎXIÏYLÎYJÑ^IÍYFÍYFÎ[G×fQÓgMÑbOÔeRË_DÍ`FË]GÂU9¾J*¹@#²=\1cµ?%·P-Ó\85aÇ{\¶_?\9e.\1f¬=0Å[AÊ\EÈZGÃU>³J+¶P0¨F,§B%¢>'\997\1e\90/\1e\85#\19t\18\r\\11\ 6L\ e\ 5M
+B\ 6\ 6>\ 5\ 6A\ 6\b@\ 5\ 6<\ 5\ 6?\v\bI\15\bxD\f\7fT\ 6~W\ 4¢\830\8ai\14vU\ 3uT\ 3wV\ 3xV\ 4tR\ 3yV\ 4wS\ 2\91o\1dqO\bi:\aW\18\ 4S\11 U\14\11P\f
+]($;\r\fA\b\ 6@\b\ 6G
+ K
+ T\14\a\7fX%}]\15wO\ 6xV\v´\99SmM\ 2jO\ 4jL\ 4lN\aiJ\ 6lN\ 6lN\ 5sU\rzZ\13\81a"mB\12m+\ 5^\10\ 3U\10\ 3>\r\ 3W\14\ 3}\15 \91\e\15\98'\12£*\19 +\e¢1\1a£.\16 +\15\9a&\f\96"\ 4¡'\10¦+\16 &\v\9c%\a\9d$ \9c" \97"\b\93(
+\8b,\b\9c]&Ê\9cMÉ\99>Ì\9a7Í\9e9Ê\983Å\94+Ç\99/È\96)Á\8e\1fÀ\8c\1aµt\vÈx\eä¬LìÊsìÍyíÏ~îÒ\83êÌ{æÇqëËyéÊuéÊvìÌxèÇmçÄdå¿Yá¹SÛ±KáºTå¾Wä½QáºNá¸RåÁ[èÆ^äÀYß»Q×BÕ¥7Ó¨9¿\8e\1eС3Ú¬;Ú¯=á·Gß·Gá¼Oã¼PàºMß¾Rà¾SѪ?¿\93,Ò¤:Ò¦;Ù¯AÚ³Bà·HãºKæ¾QèÂUáµFá·HܯBÙ¦7Ó\93$Æ\7f\13ʤQǪ^±\91O\87xTòñãîìÞîìÛîìÙîìÙîíÚîìØîë×îìÙíêÖííÜííÝííÞíîàíîßîíÝîíÝíîÞííÜîíÛîëÚîëÚîìÛíîÞîíÛîíÝííÞíîÞñòâ¤\90oqI\1a}K\1d\83Q#\8f_/\8aW#\98`+\9a`.¡i5Ë\92gä³\8aä·\87Ò\8cjÆoRÇjNÄmWÞ\9a\81ÉxdÉ]P¦('¬37½XO¾^KÑa[ÇTSÂIHºDG»@D¿IL½GI¿NNÃOQÅVXÀLIËTQÉQOÇPMÏWOÎXPÊUMÊVHËUEÉTDÆRBÉWGÌXHÉVEÎ]KÑ^JÒcOÎ^KÐ^IÉV>ÄP8¿J1¼@'¼=%¨0\15£5\e¬<(A)«N:¤A5\92\e\10\9f\1f\14·C8Ã[CË^GÒ^NË[DÂQ8µI- <" :\1c\9c= §Q3\9bC0\8e-(\89*(\86/(\896*w!\1eN\ 5\aA\ 4\aA\ 4\ 5U\15\11S\15\ e[\1e\12a,\r~N\a\80W\ 4vR\ 2«\8e=pN\0uT\ 3sR\ 3pN\ 3nL\ 3sR\ 3sP\ 4zW\ 4tQ\ 3nI\ 4h@\ 4X)\ 4Q\11 Q\12\10N\ f\rV\1a\18U+\1d9\r\a:\a\b<\a\ 5B\v\a]-\13\81\\1fjJ\ 6lJ\ 3xX\f|b\19sS\ 5iN\ 4fI\ 3fH\ 3dE\ 3dH\ 3fG\ 3nP\ayV\f}[\16x\\16xU\15U&\ 4Q\18\ 42\v\ 3K\13\ 3v\14\ 5\89\18\r\8f"\12¦1%¢*\19 .\17¡,\17\9c*\11§.\1f¥+\13§+\14©.\18£(\f¡%\ e #\f $\ e\98!\b\91#\a\89&\ 3\82/\ 5Î\98XÊ\9bEÉ\98;Ì\9d=Ï\9b7Æ\94&Ä\93&Ê\9b.É\99.¶\84\e¥q\vµj\vÖ\85&ç´Rä¼_ëÌwëÏ{ëÎyéÎxëÐ|ëÏ}èÌväÄbäÂ^èÃ^æ¿XáºPâ»RãºQà¹Nà¹Oâ¼R߸OâºSåÁZã¿Xà¼RÞ·N×®HÒ¦;Ì\9b*Õ¥5ש8ܲAá¹Jä¿Rã¼OÙ²A߸LÛ¶EåÃZæÄ^È\9c6Î\9c+ש:׬<ݳEá¹KÞ´Eã·Hà²Bâ³Dâ³HÛ©:Ö\9f0Ñ\8d Î\91-Ì«`Ê®i\9a\7f>\8d|]ñðàîìÞîíÜîìÙîíÚîë×îìÙîëØîëØîê×íìÜíîßííßííÞìîàíîßííßíîÞîíÞîìßîìÜîíÛííÝîíÜííÝîíÝííßññå¦\8doc7\ 5k8
+n>\10m=\ erA\ ewD\12~F\16\7fF\1cÔ¨zÛ±\8cã¾\96æÁ\96Í\8bkºW=ÀR7·T9ÊmVÊr`¶LA©++\9a\1f ªI@ÕvfÉUMÆNIÁDB¼AC¹<;¾EF´9=¾ILÃQPÃRQÆSOÄPKÅOKÃQNÇVLÀNE§;/µD:ÆNGÃOAÅTAÍ]LÉWCÊYHË[KÌ]IËZEËZEÉU@ÁK7½E/µ="3\1fª.\1c°B&\9f7\1e\9e@%}\10\ 4\8b\13\r\88\11\r\8e\18\12\9f"\19µ?5½RCÆWFÎ^NÍ^FÇTAÅR;®F/³X@\99;+\8c#\1d\7f\15\12\80\14\15{\12\15}\15\17t\r\12q\r\ fT\ 3\aK\b Q\f\ eb\1d\1ds1(m,\el4\ f{N }W\ 5xT\ 5pO\0uT\ 3sR\ 3sR\ 3oN\ 3pP\ 3oO\ 3rR\ 4wW\ 6wW\ 6rN\ 6fD\ 5T,\ 4J\11\aP\15\12K\10\vO\14\10`*#V-$+ \a7 8\b\ 3[4\14\80]\1c\85k'rT\asU\av[\12hM\ 3eJ\ 3dH\ 3_C\ 3bG\ 3bF\ 3`E\ 3cD\ 3sT
+z\\12oP\btY\12uX\11G%\ 44\r\ 3H\12\ 3k\ f\ 4|\14\b\8a\1c\r\8b\1c\ f\95#\16\99(\1a¡.\1aª:#°7"·G/¦-\12¥)\11£%\ e¥'\r«/\15 $ \94\1f\ 6\8e\e\ 4\87&\ 3\82 \ 3\95I\17È\99HÈ\99?Å\954Å\90*¿\8b\1dÊ\9f7Ì :Ç\970\9en
+\8d\\ 3\93X\ 2½k\f×\8d*æµPìÊkéÊoëÌvêÉråÅdéÇkçÃcâ¼Sá»Ræ¿Vß¹MÞµKܲFÞµIá¹LÞ´KÚDدFݵKã¾Vã¾ZߺSá¼UݵKÚ¯AÆ\96&Ñ£4Ö§7Ú°?âºOåÁXÜ´EÓ¨2Ш1ݸKåÃ\êËdݹSÄ\93%Ð\9e1Ú¬<ß³Aä¹Iá¶Eà³AÝ=ب9Ù¤6×\9f4Ð\95)Ãx\rÏ¢HĬcêdnV\1e¯¢\84ïïÞîìÞîìÝîíÛîìÜîíÚîìØîë×îìÙîë×íìÝííÝîíÜíîÞííÝííÞííßíîÞîìÜîíÜîíÛîìÜîíÛîìÛíîÝííàïðæÙÁ¥Ô rÐ\8f`É\88]²zL\9ec4\8cN\e\88Q w=\10\98V-·{Qß±\8dâ½\9aݧ\83¯N5ÅcQÈkTÈiQ«@+¥6,²@:¯81¢7-\90&\1dºPGÅVKÁMD¾C?¸><µ:9±81«0-16½KM½LKÄMMÀJD½KA³I@£9+\9e4%\9d/%\9b) ¾F4ÂI@ÀK9ÈT=ÃT>ÆWHË[KÊZFÈXCÅR<¾F0»A1®/\19¦%\r\9c\1f\r\9e#\18±J-\976 q\15\bx\12\b\86\13\f}\v |\f\r\95\e\15±9/¼K:ÅRFÉWHÏ]JÇTC´H1\99+\1c\88\19\15\81\15\10\84\14\15\82\16\18\82\17\18|\14\15y\10\13s\10\ fn\r\ fa \f`\10\10^\16\12_\15\ f~-&y8"m7 yM\ayR\ 4qM\0¨amL\0sS\ 3qQ\ 3qQ\ 3oO\ 3qQ\ 3qQ\ 3wW\ 5vW\ 6oO\ 4jG\ 5T/\ 4H\15\aH\10\rM\13\10O\15\12P\1c\18oB;,\ 6\ 1(\ 6\ 5-\ 6\ 3J,\10rX \7fb#rR\vpS nS\bdH\ 4dH\ 3jN\ 5aF\ 3dI\ 3aE\ 3bF\ 3bF\ 3]B\ 3dI\ 3nP\ 4oQ\bvX\10vX\10J+\ 3;\f\ 3e\ e\ 3s\15\a\82\19 \87\e\f\8a\17
+\90 \10\9b+\13¨<#¶G,¼M0·L0§;\1fµE"§,\f¦*\ f\9e"\b\9a!\b\8f\1a\ 3\8d&\ 4\88#\ 3u"\0º\8bEÅ\9aA½\8f/Å\93.Á\90*Ç\9d9¼\931\9fw\15\83V\ 2\8e`\ 3\86]\ 5¨q\10Às\rÜ\964ç»XèÂ^ìÎqèÉmà¾VÖ¨DÙ§AÛ¬AÙ¬EݱIá¹LàºO߶KßµGÚ¯DÔ¦AÍ\9d8Ä\94(Ä\97.Ó§AݵQæÀ_á¹Uá¸KÚ°CÎ 5Í\9e.Ñ¡0Ú¯=à¸KÜ´GÓ¨8È\9c)Ò§6á½PäÄ]éÎjæÊeÇ\9d7Ï\9e/Ù§7ب:ܬAÚ¥3Ù¢1Þ¦8Û 4Ú\93*Ð\89"¿w\14É\91>Ī_Á§_»¡ZQ7\ 5Á¶\98îíÚîëÚîéÚîìÜîëØîíÚîìÙîêÖîêÖîëØíìÜíìÜííÞíîßíîßííÞîìÜîíÝííßííáîìÛîìÜííÜîíÛîíÜïïà϶\9bÁ\8d_Å\8fXÓ\96fÓ\93cÑ\96`×\98bÚ\9adÑ\94^Ä\81T½nKÀiEÄlHÇ}dÀiRÁTFÇjS·QEªA1À[M©D0ª<4¸SHµTAÈfS¿^JÂhS»XF´F>¯;3«80§7*¥/+¤&)©18¼QN¸SD´F8ºPC¡B0§D0¢B3\8f\1f\14\94%\16\9f.\1cµ60½E<ÁI<ÅTDÊ[OÌ[LÉUCÁQ8ºD5·<2³2)©+\19¢"\r\9b\1e\11\96#\18¡:$¤>+«H9\82!\10\82\11\ e\81\13\10v
+v\r\v¡2.¹B;ÄI<ÉVA¿XB¢/#\8a\19\ e\8d\1a\19\88\13\14\87\14\14\86\17\17\83\15\18\81\15\18\7f\15\17x\12\18r\10\12n\ e\10g\v\10c\ f\11o$$n"\el\19\12x8$qA\fvP\ 6qN\ 3pO\ 4xW\asT\ 4nR\ 3pQ\ 3qP\ 3kO\ 3jK\ 3mO\ 3pR\ 3uY \8bo\1ffI\ 3[9\ 6D\17\ 3@\v\bL\10\ eT\1a\17Q\1e\1eK\e\1aO&$'\ 4\ 2"\ 6\ 39 \f\C\13kL\rkM
+fI\apU\fgL\ 4gN\ 6dK\ 3aF\ 3aE\ 3[>\ 3^B\ 3^B\ 3_D\ 3`E\ 3iM\ 3mQ\ 6tV\ etS\rpQ\ eK#\ 3R\10\ 3b\14\ 3t\16\ 6{\13 \86\15\r\89\1a\f\90#\10\93%\17¤3 A%Ý£\89㿨à±\90ÁL-¦'\ f\9c\1e\b\99\1c\ 6\95\1e\a\8b\1d\ 3\8a!\ 3x\18\ 3\8eV\1a§{%¦y"µ\88*¶\8a#¹\910´\8c$\9cq\12yO\ 1\8dc\13»\95<©\81"t\ eË\7f á¡EëºRëÂXêÇiëÇhË\9c8½\82\17É\90*Í\985Ò¡:Ú±Jß·RÞ´OݲEÎ 7½\8e$²\81\12´\81\12²\82\1a¶\86!¿\8c$Ö¬NÚ®OÕ©CΡ8Ϥ5С3Ö¦9ج?Ø>Ù®<Ô¨7Ê -Ч:åÄ^æÆ`êÎkèÉbݽYÎ 6Õ 2Õ\9e/Ó\9a.Ð\8e Ô\88 Ñ\85\19Ì\84\eË~\1c»q\12Ã\892ƦZ¿¨_©e§\93TK7\bÕͲîìØîìÝîëÛîìÜîìØîëØîìÚîìØîëØîë×îíÜííÝíîßííÞííÝííÞîíÛíìÜîìÛîíÜíîÞîíÜîíÜîíÜïðàÉ´\9dyH\1em8\12p=\ e}F\1e\8aS%\97_-\9ff3¶}LÈ\86W¯Z:´T3´U;±K2ÁbE±>+®1$£2!¸ID±F:¬I=©>/°;7·M:µJ:®D6¹S>¿dSÁ]O§9/¢5,¨8-C1¢1&°I:µSGµQD»VF±A2©9,¯RA¢E5\95.!\94%\1c\94$\19\92 \13\9a!\17·>0½J=ÃM:ÅS?ÂRBÁM=»B1µ:/®2*\9f!\17\97 \17\93!\12\993!\9c9,\9e4!\9e0!\9d-%y\10\r\81\15\13|\15\16{\13\15j
+\ 6\88 \13·81ÀM=½]K\8e&\17\8c\15\11\8c\13\12\8c\18\17\8a\14\16\85\12\13\88\14\17\86\15\18\87\16\e\84\16\1a}\13\16w\ e\14r\12\15f\r\10]\ f\ ec\12\ fi\16\13h\16\ fj\1e
+s@\rwS\brP\ 3rQ\ 4vS\ 3vU\ 3nO\ 3rQ\ 3kM\ 3iL\ 3gG\ 3hH\ 3jM\ 4jN\ 2çOwX
+aC D\1d\ 4?\v\aG\14\10G\11\rY(%K\1c\17R'!E\e\14#\ 6\ 3#\r\ 4Q8\aY<\ 4\@\ 5_E\ 3jO\akQ\bgP\ 6eI\ 4bF\ 4`E\ 3]A\ 3\A\ 3_D\ 3^C\ 3aF\ 3eI\ 3nP\ 6tW\vpS\ fmM
+dB\ 6N\e\ 3\\ f\ 3m\10\ 4w\11\a{\13\v{\16\v\85\1a\v\8a\e\ f\93\1e\10\9a(\13\9d,\13§=%¸L3ÀF+¢#\v\9e\1e
+\9a\e\a\93\1d\ 5\8e \ 4\88\1e\ 3}\1d\ 3t8\v\9dx*°\8b9¶\94@\97n\11\8ee\a£\80\1c\82]\11±\87-É\9bDÊ\9fGÁ\97>©y\1eº|\1eÒ\8a,Ý\94'ì¹Næ¼Zâ¼eÚLÆ\93-³z\13¼\88"Æ\93,È\94-Ë\9b/ש@Ó¢2Ç\94(\9eo\ 5\9ep\a§x\ e r\ e«{\e¬|\1c·\89*Á\8f/Ç\9b4΢<Ó¦=Ì\9f0ש7Ò¢/Õ¨9ت5Þ´BܶCÚµEÞ»TçÃ[ëËeæÇcäÁ_Ò 5É\89\1eÉ\81\16¼w\ e·m\ 6²f\a±o\a¬e\ 3²n\12½\863À\9cLǯgïl¼¦h\F\15TE\1aÝÕ»îìØîìÙîìØîìÙîëØîê×îëÙîëÖîêÖîëÖîìÛîìÚîìÛííÝííÞííÝíîÞîìÛîíÝîíßîíÝííÝíîßïïÞν¨wI*\81O*i=\17`2\fh9\ el9\fk:\ fm9\f}<\10 I1¬L5\9d:(¯P@Îu\ÆfP¶K=¬:4²H<³L@¯E4´PF¤0'µE<¸O@@8®I:°L<«F<\9e8.\95) ¶PB½aK±\F¬P=¬K8ª@:²Q>±T@£>0¢:,\98,$\90'\1f\92)!\91(\1f\9a.$\91'\1e\93\1c\1a§0$¸C:¼E>ÄVI½NC¹E>³8,©-\1d\98\1c\12\92\16\ f\93-\1e¡B.\95*\18\91!\13\98&\1c\9f3'\91&\1d\8e%&\8e'!\911.\987-\7f\18\12v\11
+£?8£P>v#\18\82\14\13\8b\15\16\90\16\15\89\14\14\8a\17\18\87\14\17\87\14\16\87\18\1a\86\15\1a\81\13\17~\11\17y\ f\13q\11\15h\r\10a\ e\12k\19\17k\e\13s$\19i!\ 4nB\btQ\ 6rN\ 3oN\ 3uR\ 4oN\ 3oO\ 3nN\ 3hI\ 3eH\ 3dH\ 3eH\ 3gL\ 3hN\ 3¢\881\92u&K3\ 3> \ 47\v\ 56
+\ 5=\r\bT#\1eQ"\1aK\1f\12?\1e\14@\19\10/\ f\ 4C,\ 3R8\ 3X>\ 3]B\ 3cI\ 3kN\ 4mR\bcJ\ 4`F\ 3]B\ 3\A\ 3^B\ 3]A\ 3aE\ 3_D\ 3cF\ 3kL\ 5mR\ 6iM\blN
+dD\ 6_9\ 4Q\19\ 3`\10\ 4g\10\ 5p\10\ 3n\11\ 5x\14\ 5\80\18
+\87\1a\f\8b\1f\r\93#\v\9b)\ e\9e,\13\9d!\v\98# \97 \a\99 \b\94\1c\ 4\91\1d\ 6\8c\1f\ 4x\19\ 1b#\ 4\9ew,µ\90E\8dj\17Z:\ 5T:\11$\10\0\8eu-É¡JÉ LϨQسb®\81&¢p\10¿\7f$×\85\1cà\98.æ¬JפFÏ¢B׫KÕ¨DÉ\9fCÆ\985Æ\93*É\97-Ó¥=Ñ£:دE\95c\b~N\ 2\9bl\b\98l\ 6£t\12´\87(·\88'º\8b,»\8c$½\8b#À\8d&Ñ¡6Ø©9Ì\9c*Ì\9f,Ó¤/Ø«7߶Jß·KÞ¹Já½PèÇ`èÊhÛºX¢b\0³f\ 4\9eQ\ 3\9dT\ 2¤]\ 3£c\ 3ªp
+©r\v´\7f º\917¿¡NÀ©\¾©c¨\94R6$\0k[2äÝÇîêÚîìÙîëÙîëÜîìØîë×íëØîë×îë×íéÕîìÙîìÜííÜííÜîìÚííÝîíÜîìÛîíÝííÝîíÞííÝïðàЯ}P0\80M'\81K)\8bU*\8aT(\82N\1drA\14vD\1f\8aD$\9eE' 3%\9b3%£@5¸\K®H4´E5¾`M©@0¦6*¡, £2\1f«@7¯A7®?4¤8+©:5¦;,§;-©A6«O:¶S>°F<¥H8«O>¡<,\9b+\1d\9d0)²_G±WA\9f9,\99-\1e\95(\1d\97-#\981&\95*$£F:\96?)\85\19\13\9e&&¬54¶C@¸F>·@7¶>8ª)(\9d\1a\18\8a\18\11\8f+\1d\9e<(\92$\13\91#\e\8a!\14\9e9*\9d<0\86!\13\8b$\1c\9790©MA¥E4\9c6-\8d*#u\13\10o\r\r~\11\14\89\13\19\8e\18\1e\8d\17\1d\8f\19\1f\8a\15\19\89\15\1c\8c\e!\88\18\1c\89\19\1d\80\15\18~\12\18z\13\14v\11\12q\10\ ek\ f\rx\1f\e\814"g\1e\10\ \ 3nA\ 6rM\ 5pM\ 5rP\ 4qP\ 3rQ\ 3lN\ 3mO\ 3hK\ 3eI\ 3bG\ 3cI\ 3fL\ 3gL\ 2´\9bGmR\rJ4\ 57\1e\ 30
+\ 43
+\ 49\ f\ 6C\12\vX+\eP \ f?\1c\b1\f\ 20\v\ 3<#\ 4O:\ 3S;\ 3Y@\ 4bF\ 3hM\ 4jQ\baI\ 3]E\ 3^C\ 3Z@\ 3]B\ 3^C\ 3`E\ 4_E\ 3eJ\ 3eI\ 3gL\ 3mQ\ 6oR kM\a`;\ 3X0\ 4K\r\ 3T\10\ 3_\ f\ 3i\11\ 4o\13\ 6x\15\bw\12\ 4}\17\ 5\8c!
+\92\1f\ 6\92#\f\9b)\10\9c'\10\96#
+\95#
+\91"\ 6\8c!\ 5¡R*º\88T\91e2¯\8fQ¼\9bZÅ¥]µ\97K¾ Q®\97KÌ«UϦT¶\8e?»\91B\94j \88V\ 5\87c\11\95i\15¾\84%Õ\8f(Ô\86#Ý\979á°OÛ±Ráº^éÒ\7fáÀfæ¿_å¾[á¹ZéÆfá¿]Ç\9e=zQ\ 6²\883\94k\v\82!¶\88%´\86*®\81&µ\84#¸\86\1e¸\87 È\9a1Ñ£3Ö¤4Ô¤0Ô¦4Ñ¡0Ú?߶Lâ¼Râ¿VçÇcçÈeèËh¨o\r¦_\ 3\9f[\ 3¡d\ 6¦l\aªq\ e¬\81\1f«\85%¬\8b/¬\8f7·\9eR¼¨b´\9f]U;\bE0\ 3\87vMèâÍîëÜîêÚîìØîìÚîëØîêÖîêÖîë×îê×îê×îìØîëÙíìÜííÝííÜîìÜîíÛííÝííÞîìàííÞîïßÛË·¦rO¡k@\90X-\85S+\82K \82F\e\86E\13\9dR(£Q4¨Q9¤D' =%\9d9/\9e9+¥4+¬9/°A5¬D/?,¦4%£2\1f®O4¸ZJ°F9«:0²G:©>3£7&¦;#«K5¦A0 1)³NB¥</\9e3# 4#\95%\1d\96,\1d\9f=, >-\9e;.\94, \92*\1c\91'\1c\92(#\982/½p^\9bI.\84\1c\ e\90\1d\17¨4.¬;/±B8µD9§6/\9e)"¯F9¶[I\933$\94' \8c\1f\17\83\1c\17\98;-\87&\17\81\1e\e\81\19\14\88!\19\85"\1f§SA´aT\8b%(\83\14\17\84\13\18\83\12\16\89\15\15\8c\15\1a\8b\16\e\8d\14\e\8c\14\1a\8e\1a\1f\8f\e \8b\19\1e\8d\e\1f\8e\1e"\85\19\1e\88\1a!~\15\18y\13\17q\11\10l\12\10n\17\14u%\17\86B.f)
+j@\ 5lC\ 3pL\ 3mL\ 3nN\ 3qP\ 5tT\ 3jJ\ 3fI\ 3cF\ 3bD\ 3`F\ 3iM\ 4nR\ 6\82d\16`G B/\ 33\19\ 30\b\ 33
+\ 4:\r\ 6@\12 @\14
+@\12\ 6rM$`>\1f. \ 26\1d\ 3G0\ 3R8\ 3X?\ 3[B\ 3\C\ 3ZB\ 3^D\ 3\D\ 3]B\ 3]A\ 3\@\ 3]C\ 3_D\ 3bF\ 3`E\ 3aF\ 3bG\ 3hL\ 5pY\rpY\12aD\ 4^9\ 6N%\ 5@\ e\ 3L\11\ 3U\ f\ 3a\12\ 4j\12\ 3r\13\ 4y\17\ 3\81\1c\ 5\86\19\ 4\89!\ 6\85#\ 2\900\ e¦X.Á{PÓ\9bjá»\81éÐ\97ìÕ\97ïÞ¡ïߤïà\9cíÔ\8aîØ\8aïÛ\8cîÙ\8dïØ\8aîÔ}ìÐ\82æÑ\8aÖ»o\8a=sW
+tQ \92l\1cÒªOèÀgÖ\9fBÔ\9c=ÙªLß·Zܺ]çÄjçÁeéÃgêÇlÚ±RײWßÁjܽjåÈv˪X³\8d7®\84(\84*³\86-¬~!¬\84&»\8f'É\9c1Ôª<ب9Úª:Û±@Ü´FÙ±EÚ±Hß·Oã½UäÃaåÆièÌsάN\9dg\ 3\9dc\ 3¦r\f©}\1a¬\83$¨\83&«\87,»\9eK¹\9dO¶\9eX±\9d[\94{AV5\bR5\ 4\9b\8abŵ\99ìçÎïìØîêÚîêÙîëÛíêÙîëÚîêØîë×îë×îìÛííÜííÝîíÝííÝíìÛííÜîìÚîíÜííÝîíÜÛÍ´¿\88aÎ\93fÇ\8a`Ã\87^Å\8cbÅ\8c^§c>\97O*¯X4¬K1¥I6\9f>-\9a8&²QH³QD¬>4²I5©:.©3#£1#\9e/!º\J¾nZ³YL§E4¨?.²M?ªF6¤9*¥A,¯]H±RD¤@1 <)\9b6!\96,&\94/#\9c6)\9c7%\9c6(¤B3\972$\95+ \91)\1d\8e$\16\8f'#²ZN¨Q=\8e6\1a\969'\90*\e 2*³A7¯?=¨51 2(²O>\96/\e\86\1a\10\82\19\ f\89\1c\17\9b82\95;1\92:*}\e\14}\18\ f|\12\12\8a!"\8b(\1d¶eW\83\1c\e\81\10\15\84\13\18\85\13\17\83\11\13\88\15\18\8c\16\1d\8b\15\1a\8d\19\1f\8e\1a!\8b\18\1d\8d\e\1f\8e\1a \8b\1e#\8b\1f$\8d\1d%\91"-\8c\1f"|\13\11o\12\ fm\12\10g\14\ff\15 \8dG*r7 h?\ 4oF\ 4mG\ 3kH\ 4pM\ 4}a\ f\93{+pN\ 2fH\ 3dG\ 3aE\ 3`D\ 3hL\ 3{`\11{_\16T?\ 5>,\ 30\1a\ 3(\b\ 3(\a\ 3.\v\ 61\f\a/\v\ 6:\12\ 6mN*fK':\19\a/\12\ 39#\ 3F/\ 3N5\ 3Q:\ 3T=\ 3T<\ 3V<\ 3ZB\ 3^B\ 3[?\ 3Z?\ 3^B\ 3^B\ 3aF\ 3bG\ 3bF\ 3cH\ 4fK\ 4iN\ 5sW\10fK\aaA\ 5T1\ 4<\11\ 3=\f\ 3E\10\ 3Q\r\ 3[\10\ 3f\13\ 4j\12\0\80-\11®g>È\94eã¹\84ñÍ\95ïÔ\99íÛ\9fíÝ¢ïߥîâ¨ðç®ñéªñã¤æÉ\7fÅ\95DÄ\96L´\84;»\8cDÖª_åÆxìà\97ìéªìë¬ïé©àÌ\87¢~+qJ\ 1tM\a¸\97Gîà\93ïã\96íÕ\83åÍxçÈuæÅræÀhå¾céÈpà¿gÚ·eãÂoáÀmâÆväÈ{ßÀq×µdÕ³_Õ¶dÛºfÝ»dÛºbÎ¥<Ò¤=ת;ß·Lá¸KݵLÞ·OÞ¸NàºPäÀYæÃ]èÊnçÌvàÅh·\8b*¤s\ e§|\16¤|\17¨\86'¢\82(³\92@¸\9eM¶\9eS¹¡[fM\15C#\0P5\ 3T:\b\8c{L\9ez¶¤\86ÓÈ¥èàÊðèÔîéÔîêÕîêØîêÕîìØîêÖíìÚîìÛíìÜíìÚîíÜîíÜíîÞíìÜîíÙîíÜÞÖÃ\7f];\97c8§kE±wSÂ\88\È\8b^ªlC¦]D¢R3³^C²VF¤G6§K?¦D6¤G3«KBÀ`SµX>¤90¥2(\9e*$\9c0(ºXG¥E8 8.\9b4$ªF4¨<0«C5©C5P>¸hY²[L¤@2¨D7\970!\8d$ \9a8.\9dA2\9b5)\9c4-\96/)\93*\1f\97/'\9a3,\960)\982-¡A7\90."\934 \946&\941 \93!#¤78B>§>3\93*\1f\93!\1a\85\17\15\85\1d\19\81\1a\16\80\16\ f\934,\9184~ \1d}\19\18t\10\rt\11\r\80\17\1a\9b=7\82 %\84\16\1e\86\15\1a\80\11\13\83\11\16\82\11\16\88\14\1a\8d\19\1f\90\1c"\8f\1c#\8f\1c$\8f\1d#\90\1f$\8d\1d#\8c\1d#\8e$(\93%*\90)-\9311\87)!~!\1fz\1f\1em\14\10m\19\11\97L6r7\alF\ 4lG\ 3kF\ 3nK\ 4pN\ 3\94y,\87q*jO\ 3fM\ 3gI\ 3aF\ 3`J\ 3bK\ 3qY\v~c K5\ 3=-\ 31\1e\ 4!\a\ 3!\a\ 3"\a\ 3#\v\ 37\18\ 5X6\11nJ\17pM\1dQ/\b@$\ 32"\ 24&\ 3<+\ 3G5\ 3G3\ 3H5\ 3N9\ 3U?\ 4ZA\ 3W>\ 3ZA\ 3]A\ 3\D\ 3`E\ 3bF\ 3`E\ 3^D\ 3aF\ 3iN\ 6nR
+pS\ fbC\ 5W7\ 5C\1a\ 4/
+\ 35\ e\ 3E\ f\ 3G\r\0{@&Æ\9ctïÎ\9eïÛ¥ïߤðâ«ïá«ìݦæÌ\8eâÃ\84ήq¹\92W¨|B\9ab*\8aW\17\99Z\12§b\1a\96U\17§v5Ï«mëÕ\91ïæ¦îæ¨íê¬ëë¬ìëíë®ïä\9eÓºm\9ew\1fwF\ 2\96h\eܾqïæ\9dîæ\9díç\9fîã\98îØ\8bæËzæÉyçË\81Ô®_Ò¨Vá¿háÂsãÅzß¿qâÃváÃuáÃtäÆtãÂnßÀlÙ´SÓ¨CÞµLà¹Pß·Lä¾Xà½Xã¾WäÀXãÁ[âÁZèÈkéÑyÙ½gϳV\98n\ e\95s\10\9av\ e©\88,²\96G²\97K»£X³\9eY£\8dJL2\ 1F.\ 4I2\ 4_K\18\89uF¯ \7f©\9e~§\9bt° {¾¯\91ßÔ»îéÒíéÕîêÖîéÕîê×îêÖíëÚîìÚííÝîìÜîëÚîìÚîíÛîíÜÖÏ»pN.\82_=\8ab>~R/k=\1e\82F#¡X9¯eL\9fO;SA\9e@0\9bA/¥Q<·^M¢D7¹iYÄwfÁdT¼^P£;1¤/$ª90¹TDªA1¢<1 1'\9a1&\9d;.£>2 ;1\9a6/\9d;+¥G5¥H9¦@6£?6\90*!\8f%#\8e-#\9c@/ ?1ªNB¤D:\971&\9e80¦A<\990,\97,$\91*"\8e& \89(\17\90+*\88%$}\18\13\9a6.²MF\9b."\96,\1e\8c!\13\86\e\16\81\1a\17\83\1a\18\80\18\ f\85 \1f|\1a\e~\18\1cx\13\15u\r\13~\13\15\87'$\82$\1d|\14\16\80\14\17\80\14\17\7f\12\15\7f\12\15\83\12\17\88\15\1a\8c\19\1f\8f\1c"\94!)\91!$\8a\1f#\8c\1a!\8b\1f$\8a\1e"\8c$'\8c#'\89\1f%\902+\80& \83#\1f\82( w"\17u%\16\8fC(o1\ 6mE\ 4lG\ 3lH\ 3lJ\ 3oN\ 2y\\18\83r5gM\ 2fL\ 3dG\ 3_H\ 3bH\ 4eO\ 4zb\1a`L\ eK6\ 38(\ 3*\17\ 3 \a\ 3!\ 5\ 32\12\ 3\;\12\84c&\8cl$\8fj#\8bh#\91o$xX\vqR\v^E\ 5K5\ 3=(\ 3C-\ 3K6\ 3J5\ 3P;\ 3S=\ 3V>\ 3W?\ 3W>\ 3ZB\ 3Y@\ 3^C\ 3Z@\ 3hO\acG\ 3hM\ 6iN\ 6oS\rgJ\bT8\ 4J(\ 3"\v\ 3'\12\ 3xO0Ϫ\83ñÖ¥ïÛ«ïÔ¡áÄ\91Ó©r¸\80O¨n2¸\82EÃ\8bMÂ\8cK¿¤~°\98g\87[&²\84M̯vÙ³væÒ\98ïߤîä¥îê«îç¦îæ§îèªîé«íé©íêªîé«îëîë§ïä\99Ý¿g°\7f2¦v*½\95FÛ»qåÌ\7fîá\97îã\98íä\9aíÝ\97îÕ\89É¢JÍ\9fSϪ^ãÅwâÃwäÆ{äÆzèÊ\7fáÃtãÅpäÆqäÂmÞ¼cÛ²QدFÚ²FݵKà¸Qà¼Tá½VáÀ[áÀ[æÆhæÉoéÐvåÌxÛÁm\9bt\15\97s\1d¡\81+ª\8d1³\94E²\93G«\90F´\9cXu^'6!\ 38'\ 3E0\ 6eS\1f\86sE°\9cwª\97o¨\98o«\9ay¬\9cz¯\9d|àÕ¾îèÙíéÕîêÖîêÖîé×îëÛííÝííÜíìÜîìÚîêÖîìØÛÔÂl@"qI#tP.rE%tE"\8bK.«`K´mO¥[I\9bD.\9a:'\936#\9cG2¶cP\9eB0¿sX¬\DÁ[K¶S>±G8§5, +\1d +\1c¦:-²N@¦F8\9e4%\9a5%\9e9*¡:/\95-'\9c5,´SB½aK©J5\9e8/\95.+\8f+"\8c%\1e\82!\17\98=) G5\967/\8c(\1e\984&\9f:/\91,#\92,#\93, \9a8-\95)%\85!\14\8b*\1c\86$!\9b>;®IB¨?: :7\8d&#\82\1c\10\8a)#\88*)\7f\1d\19\82\1e\13\82!\1c\83'#~#\et\10\ fw\12\ ez\13\16\874&t\18\13y\12\17~\13\15~\13\17{\ f\12\84\16\18\84\12\17\89\1a\1c\8c\e\1f\94"+\98'/\8e\1d#\8a\1c \89\e\1f\87\1f!\88 "\8b!'\8a"*\8a('\8e/-\83""\7f\1d\19|\1d\16z\1d\14\850\1f\8a?"l1\ 5lD\ 4mH\ 4lH\ 4mJ\ 4lM\0ØÒ»ãàÏeI\0dG\ 3aF\ 3_H\ 3dN\ 4dN\ 4\83l%T@\ 3F2\ 37&\ 3)\1a\ 3\1f
+\ 3>%
+iH\a}Z\ e\80_
+\81a \88d\15¨\8c?¯\96E\90s\1d\83c\f}\\a\82c
+kP\ 3W:\ 3J5\ 3E0\ 3J8\ 3K6\ 3O:\ 3T=\ 3T;\ 3U=\ 3X>\ 3]E\ 3`G\ 3aF\ 3cH\ 3fI\ 4gK\ 4cH\ 4dL\bX9\ 3K)\ 2H-\r\99uNÇ\98pÀ\91c¥k=\91S%\87O\1e\8cR(\9dd9Ä\8f_Ó¬rãÅ\89æÍ\91éÒ\97éå½ëÞ¢ïä¬ðé¯íì·íì³îé¬îâ¡éÒ\8bßÂ\84âÄ\82êÖ\90îÞ\9aîÜ\9aîÞ\9cèÖ\91æÐ\8bæÊ\84Ú±dà¼uìÒ\88ðâ\9bðä\9dîß\98çÕ\8cÞÂpϪSÒ«^ÞÄxìØ\8còã\9aðÛ\8céÊ~ß¿xßÂvàÁuæÇ}äÆ{åÇ{çÈ{äÈxàÂkà½bß¼aâ»[Ü´M߶MÞ³MݵHÚ°H߸Pà»SäÁ]èËoêÎvêÏ}êÐ\82ãÌzÉ®V\9f~(»\9eO§V¸\9bNµ\95L\9d\85@³\9aV@.\a&\1c\ 31 \ 36&\ 3hQ$\89qE\9asH {K\95j©\99v¨\98xª\99z¬\9c\80ÛѸîéÕîéÖîéÕîéØíëÛíìÛíìÚîêØíìÙíë×áÙÅ\85cD\82U2\89W0\93^7\96R4¬eN¦WC³lQÄ\83`\9cM9\98@)\99;)\99A,\9cG5\98<)\9eI3¶cK´UC¾[J²UC¥9*¨;0¬H:¤?.¥?0¤D4¦C2§C4\9d;)\9e8$\97-\1a\993&\9d3(\9a5$\93.\1f\96+!\94/'\961.\962)\91'\1f\931'\956%\8d)\e\86&\18\910\1f¡B0¥E=\994.\961, A4±[P\90*#\987)\924$¦NF±WN\9f?2¡?6\88%'\80\19\e\89!\1f\8a/%\85.%\81) \85%!|\1c\19\85**|#\1aw\14\15u\11\12\82!!s\1c\17s\12\14y\13\18{\13\15|\11\17\80\17\1c\82\16\19\84\19\1c\89\1a \90 &\91"(\90\1f*\8a #\8c\1e#\89\1e#\88\1c!\89!#\8a")\8a')\916+\8b-)\84##\7f \1d}\1f\19x\e\17}$\18\8c>+h5 f@\ 4hD\ 4pK\ 4oO\ 4kN\ 2¿µ\8fÞÚÑjN\f_B\ 3`G\ 3\C\ 3cK\ 4eM\ 3s[\13N8\ 27*\ 30%\ 3%\14\ 3<) _G\fuW ~[\ 5\88f\14~]\a\88g\15\8fr"\99{)¹\9dK£\89<\89e\a\84d\ 6|]\ 3xX\ 3iK\ 3M3\ 3A/\ 3G3\ 3N9\ 3O:\ 3R<\ 2ZD\ 5[A\ 4bK\ 6hK\ 5bG\ 3cH\ 3hJ\ 5cG\ 3`B\ 3J3\ 5H&\ 2[4\bp?\13yC\15\94f?©|VÃ\9fvÝÀ\8fíئïá³ïêºëì»ëí½ëí½ìí»ìî»íì·ðí·íé´ðê´îà¡äË\84Ç\98MÁ\8aD¯p*°u.¹\816Î\9bRÒ¢YÖ\9eT¿\818\9a[\13\9fb\1aÊ\94HÌ\95FÉ\8f>Ã\8e8Ë\9bKˤUЪXÔ®[×½kàÁnãÁvײf½\8e;\82W\15b@\ eX<\10x^#׺qäÇzäÆyåÈ\7fæÊ|áÁsàÃrãÅrà¾fß»_Ú²QÛ´LÛ±KÚ°JÓ¤6׬?߸Qß¿ZåÄ`çÈjêÎvêÐ\81ìÓ\89ßÄtÝÂpĤSÖ½rѺu±\97N«\90O¤\8eQ\89u73!\ 3/!\ 37#\ 30"\ 1jY)p[0iN\1e\90i8\9f\84T©\98q¦\94w£\96y©\9b\7f³§\8béáÅíçÒíèÔîé×îé×íêØíêÖîë×îì×åáÊ\8ceF\81H#\83H&§iI¸p]aH³hT¸kZ_I§X?¢N<ª[?\9cA*¡M6¢H8\9dD1©RD¼pcÐ\7fj¯H<°PB¡4)«B<¨JAªF=ªP>¦H9¨E8£@3\9f81\9e:*\982)\9f>-\95+\e\971\1d\93.!\9c:8\9a72\942-\942(\94,(\8e'"\89'!\8d*&\8d+"\8e,"\8c+"\9772\964+\961*\9a81\8f.&\8f4$UD²]N¼kZ\9e=3\97:/\86&&|\1a\19\82\1f\1f\924-\96<,\88,#\80!\1e|\1a\1az\19\1ax\17\16v\15\14v\14\13z\16\19}\1f$o\16\16t\13\1az\11\14{\12\13|\10\16\81\16\19\84\17\1a\84\18\e\86\1a\1e\8b\1c!\8d!"\86 \89 #\87 "\86\1d!\84\1d \87 !\87""\9577\8b,&}\1e\17\83%"\82!\1f\80"\1e\80!\1ds\19\ f\8aA)e4\ 5fA\biF\ 4iF\ 4iL\ 4oQ\ 4×Í\9d§\94YiK\ 4_D\ 3[B\ 3YA\ 3aI\ 5bH\ 4]G\ 4J5\ 37)\ 3,#\ 3$\16\ 3O<\viP zX\ 5\83a\r \801ÖÊ£\84b
+\82e\ e\87e\v\94v ØÁs\93r\14\88j\f\82b\ 4\84b\ 5\81^\ 3qP\ 3S8\ 3@/\ 3@/\ 3G3\ 3J4\ 3O<\ 3X?\ 3]D\ 3dN bF\ 5eJ\ 3bG\ 3^D\ 2L.\ 1dF\e\95q?Á\9eiãÃ\92ìÚ©ðæ´ïê¸íë»ëìºêì¿êíÀìî¹íí·ííÀíç´èÖ\9bÔ²vǦj\9cn2¤j1¥i,¥c"o,£e\1fÐ\97OÂ\88?¨o(\99W\11\93O\r ^\19¤^\18\99U\ e\91L\v\90N\v¤g&¯w2»{2Ô¥Qà»iåÃpéÓ\83èÒ\84áÃuÖ¯g»\8eB·\88>ª|-\84Q\12Y2\a,\1c\0 \16\ 1hO\16çÏ\8béÐ\86âÄ|ãÆwãÄvàÃrÞ¿gâÂjÛ¹[Õ¯JÙ®HײGÚ´MÒ¨=Ð¥8ØCá¿YäÂ]æÇkêÎyêÐ\80ëÑ\87àÅuÚÀlÊ«[Õ¼pÕ¼u¦\8cE«\91R\9b\88NWC\160 \ 37%\ 38$\ 3?,\ 5lZ*P=\14YA\esX(\8byJ\99\88_\9f\8fi¤\95v§\97w§\9a|˾\9dïéÓíçÕîèÖîëØîéÕîêÕíëÙèáÈ£rM«jF²jH§]BªbL³jS¯dY®bR«YL¶n\¨[JÂ{h·mS¼n\£PA¦TE±_JºaQÂwa±XH©<0¤7+¥80 .$\9e2(»XR´]K¡>+¢?.\993# <-¥C6¤B7¬RA©Q8\90.\e¤J?£UB\900%\920*\932&\92-$\89'"\8c'%\8c,!\92.#\92-%\8f+!\954*\8d(\e\951)\92.%\932'¨Q;\94<%\84(\1f~\1e\18\89%\1d\81 \16y\16\15|\18\18}\1c\1e\83&\e\84(\1f|\1f\1c}\1d\1e\80" } \1ev\19\18u\15\12|\1d\18\8c/+\87)-m\12\ ex\15\18|\15\17z\12\15~\16\17~\15\17\81\18\19\84\18\1c\83\18\19\84\e\e\80\17\15|\17\13\83\e\1d\82\1d\1c\7f\19\19\7f\1c\1a\81\1e\1d\9d:;\9255}\1e\1c~ \1e~ \1e\81\1f\1e~$\1a\82)!x!\13x.\15_)\ 3hB\ahF\ 5jH\ 4mL\ 6oS\ 5~^\12~a\19fJ\ 3`F\ 3]E\ 3Y@\ 3X@\ 4_I\ 5U?\ 4B.\ 34"\ 3&\1a\ 3&\19\ 3\D
+oQ\ 5\81a
+~^
+\87f\ fлu\9c\81(\85d \84b\ 5\86e\b\94u\e\93s\16\8bk\a\8ag\ 4\88c\ 3\85b\ 5\84a\ 4oO\ 3N7\ 3>.\ 3>.\ 3E1\ 3L7\ 3P;\ 3W@\ 3V@\ 3ZB\ 4ZA\ 3Y@\ 4\88j+Ó¹zèÑ\94ðãðè²îç°îê»ïä«ïæ°ìèµíå´ëÞ§æÎ\98Ï°u»\8ePªq?\96`(\91U\18\8aU\1c¥\81K\9dr<±\7fLÀ\91UÁ\8fOÄ\9ej²\8bE©q(¯w4©x1µ\84=»\8dHÅ\98RÓ®pܺ{ãÇ\86âÄ\81ݼ{Òkº\87?·\805±{)¼\7f.Ö RÛ¯`á¾oçË~ïÞ\95îß\99íß\99íÚ\95çÑ\8fнx¨\92N\97~;âË\8aîß\9aîÜ\96çÌ\81âÄxáÂpá¿iâÂlÛº_Ø®NФ>ѪBܱQÒ¨FÒ¨BÚ²Lß»XáÀ]äÆmèËvêÎ\81ìÒ\88èÏ\84àÉ\80Ì°hÒ½w͵q\9f\85F©\90Q|i0;#\0=%\ 3@*\ 36\1f\ 3E+\ 5eQ!XF\1caM#\82pA\89zL\91\82V\98\89`\9a\8ac\9c\89`¢\93p´§\88îçÐìåÐîêÕîêÙîéÕîëÖàÖÁ\98cG\9cS1¢ZA\9bNC¦YO·sc\9cN8\9fQB¡YE¯cQµnV½uecT¸u\Ê\88u´iXÄud¸_M¸VF§C4 82 9.©B3\9e0)\9f2'°L<¦J9¨J<\9e<,¥C1¡@/¢>/\963&¦D8\953 \8d&\13\943)gP\95?0\953(\982$\953*\8d)&\87$#\86 \e\8d,$\90, \8c(\e\8c)\17\8b*\1e\92.\1e\93.%\8f,#\965-\933)\8c-\1f~\1d\1a{\1c\18\81\1f\1a\85! {\1a\13|\e\19v\18\15x\e\16y\19\16{\1c\19u\19\13u\14\15r\13\11t\16\13q\12\ e|\1d\19\8f.1\83" v\19\15|\17\18\7f\1a\1cy\14\14~\16\17\81\17\17\82\19\1a\81\18\17\82\19\19\84\1a\e\7f\17\16~\1a\18\80\1c\19~\19\18\80\1d\e|\1a\17\7f\1e\1d\9387\85.*y\1e\1f}\1e\1e~ \1e\83$\1f\83&!\81$ y!\14\810!a,\vaA\vgC\ 5gF\amO\ 6qU\voS
+fK\ 4bH\ 3\B\ 3YA\ 3V>\ 3S<\ 3U>\ 4F4\ 3>,\ 40\1f\ 3\1e\11\ 3,\1f\ 6fM\ erW\b}^\a\81a
+\81_\ 6\84b\ 5\8bj\11\8em\f\84e\ 5\84c\ 4\87e\ 6\8el\b\89f\ 4\8dl\ 5\87d\ 3\84b\ 4\85b\ 5~[\ 3wW\ 4F4\ 3:.\ 3?-\ 3D2\ 3B/\ 3K:\ 3L6\ 3Q;\ 3`F\ fº\9fféÓ\95îÛ\9bÜÃ\85¸\96_¬\89Sª\86M\9eqA\92Y/\92Y6\91X1\8bR)\82M\18\86Q\1e\9dj2³\89QÒsãÊ\92êÛ¤íâîèµîê´îì·îë´îé°íç°íçðê¨íä©îåªîæ¬ïç«îé¬íí²ìé®íë±íë°íê®îé¬íâ\9dðá\9fëÔ\8dÚ·fÔ§WÍ\9aMÁ\90?·\807¼\894Ô®_èÐ\8eïß\9aîä\9fïå¤ðä¢ðà\9bîá\9fîá\9dîã\9fîá\9dìÖ\8dáÅqáÀjãÁjܺaÞ¶U·\89 «\81\16¿\933ΤFÒLÕ¬KݹWà¾]åÈtæË{éÌ\81ëÓ\8aéÑ\89ÝÇ\80γj̳mǬg¬\8fJ\9f\87ER=\vB-\ 3K1\ 5J.\ 3M0\ 5YC\12aO!fU&iY*wi7\92\7fW\92\80V\92\82X\93\84Y\9b\8ba\9b\8dj©\9e\81ìãËìåÏîêÕîëÙîìÖëçÏ\90cF\8aL0\8eE.ªdN®hY²jU¡QD¤Q@\9aG=\9dQE¡XN³se®j\³mb¥_L´lc§QFªOD²TM¶\N¹]L¡;1¦F9£E5¥=6§>3¨B4 C5\979'\9d?-¡>0\9b=,·cO¡O8\983!\990#\8f'\12\967+¡E4\9b;-¢F2\9aA0\97F7\8f4&\82#\e\81%\14\97E3\913)\92.$\89)\1c\8b-%\8d.!\965-\8d,&\901+\85"\1fy\16\ f{\e\16\7f\1d\1c\80\1f\e\7f!\1d\7f \1dt\16\18q\15\17q\17\15r\16\13t\16\15r\12\11s\14\13t\15\13u\15\13t\14\12u\11\11\86\1f\1f\95:/\7f\1e\1a\82\1a\1c\82\19\e\82\e\1d\86\e\1e\83\1c\1e\85\1d\1e\84\1a\1c\82\1a\1a\83"\1f~\e\19~\19\18\81\e\18\81!\1e}\1a\e~\1c\1c\82#"\85+)y!\e~$%|\1e\1c\81%!\82$\1c\87&%\82#\1c\7f'\1dz/\1a^*\bd?
+c>\ 4gD\ 6iL\ 3jL\ 6jK\ 4aE\ 3aC\ 3Y?\ 3T=\ 3T=\ 4S=\ 3K8\ 3=0\ 66&\ 3'\16\ 3\13\ e\ 34'\ 6eI rQ\ 5xV\ 3\81`\ 4\81_\ 4}]\ 3\84b\ 5\87d\ 6\88g\ 5\85b\ 3\86b\ 3\86b\ 3\83a\ 4\86e\ 3\85c\ 3\88e\ 5\88d\ 4\88e\ 6\86e\ 6mV\ 5?/\ 38(\ 3;,\ 3;*\ 3?/\ 3@,\ 1eK\14Ò¹\7fêÖ\97îޤ¥eP(\ 2;\13\08\17\08\14\0D\17\0^-\ e\85V0ª\7fRÍ©xÞÈ\8eïá©ìéµíì»ëïÁèïÃêí¿éîÂèîÀêí½éî¼êíºëìµëê®ìé«ìì°ëì²êí¹êíºëì¶ìì´êí¶ëíµìì³ìì²ëí´ëì³ìì±íè¨îã¡îæ\9fïã\9bîè¦ïæ¢éØ\92äÉ}ܹmØ´nʦZÔ¯[æÍ\86ìÚ\8fïä\9aíä\9cîâ\9dîã\9fíä¡îã íÚ\94åÉ\7fßÂqÛ¹_Õ¯NÑI¸\8c*¨{\19¸\8c&×®Pܹ\ݾ[ÞÀbäÇtâÈ{êÐ\85ëÒ\89êÓ\8cÝÅzÀ¦ZƬj¹\9dV¢\8aEaJ\124 \ 3:&\ 3<#\ 3;$\ 4A)\ 6]L aO"hV)o_1q\*\8axK\92\80Y\8e~T\8f\7fW\97\88]\9d\8dg\9f\93pçßÉìåÐîèÔîêØíèÏ\97oT\88F'\94@)\9cB0°\F¯bH\9bO4£UL¥TK\95G=\8d=3\8e>;\9eSP\9aOD»ti\9bJA«`W¨RL¤@;²^LÙ\99\8c¥J<§F?¦LI¥NG ?8¢?7¥C7\9e@-\9b:0\9a;.\987(¯ZI½uZ´mM\9d9#\9d8#\96=(¦W@\93=+Ç\87o·y[±pW\98V@x%\15\84'\1f\88:'\87H*\96O7\93I7\84.$\928-\8d1(\913(\966,\7f\1c\19\81\1e\1c\80\1e\1a|\1a\17|\1a\17\7f\1c\e}\1c v\17\1al\11\16k\10\12l\13\12r\18\16t\1a\1co\17\16q\16\14s\17\15u\15\13s\18\14y\18\19\9dA@\95B9\86(\1f\89%%\85\1c\1d\85\1f!\86 \1d\86 \8a$$\88# \86# \8a('\87$\1f\87&!\87%#\82\1f\1d|\e\1a}\1e\e\8d/*\86. v\1c\14x\1f\18\7f\1f\1d\80"\1d\7f#\16\8e3)\84, \872+t-\13e.\b`6\ba9\ 6eA\ 5hJ\ 5iK\ 5dF\ 3aC\ 3_B\ 4Z?\ 3V=\ 4]C\ 3X?\ 4B-\ 38*\ 6.!\ 3"\13\ 3\r\b\ 39,\afG\ 4tU\ 4|Z\ 3\87e\ 6\81^\ 3\83`\ 3\83`\ 3\84b\ 3\88e\ 4\88f\ 3\86d\ 4\88g\ 3\87f\ 3\85b\ 3\85d\ 3\84a\ 3\8eh\ 6\8ag\ 6\88d\a\89h
+kM\ 25$\ 37"\ 34#\ 33#\0wa+ÞÉ\8fîáªîâ¨îá¸\95Z_5\fjD\10hH\1d\88i7À¦pæÒ¡íâ´íëºìî½êî¿êîÁéîÃèíÃèîÃèîÂæîÄèîÃêî»êí¼ëí¹ëí¶ëí¶ìì´ìì´éîµëí³ìí´êî¸êí¶êí¶ëî·ëí¶ëíµìì°ëì±ìí³ìì±ìì¯ìë¯íëªíé¨íé§íêªíê©îç¥íè¦îç£íã äÌ\84ѱdΤYÔ_ãÇxíÞ\94îä îå¢íâ\9dîâ\9bïÞ\94èÍ|Õ±[ѪQÜ»eàÀiØ·aϪRÖ³ZÝ»bÞ¾f×·aáÁnåÉ~éÎ\84êÐ\87ëÓ\8dàÈ\83Ö½q¹\9cT«\95Kxc"1\1e\ 1A.\ 2E-\ 45 \ 2.\1c\ 36&\ 3\L\1f^P"hX*n[+q^+|j9\8e|P\8f\81V\94\84Y\95\86[\98\89a¤\97uìäÌêâÍîéÔíèÓÕ£\86°_F¡J3\98<,´ZUZG¬U@°bS SF\89;6u%#g\17\13c\10\ff\11\11d\ f\11h\15\12f\11\11d\16\16l\1a\19\81')ª_Q´aSºidµaX£H@·bZ¹bS¹\Y´ZR¦L5\97:+©NC¤K=°[KÄv^´\B¢D+\97?,\889'x0\e³{h½\8en½\8bk³\80f\90UF|1$\92>4¨fR§pR°x[Å\8bpÃ\89n\876 \82"\e\8d*(\91+'\83\1c\1e\85'%\81# \7f"\1f\84'$x\1a\1au\18\1ao\14\15k\ f\14i\12\16l\16\10s\1c\15|+"q\1c\et\17\16q\16\13t\16\15u\1a\18y\1e\1d£[M¢L=\8b-$\8b*(\85""\83"!\8f1(\8d%'\942-\934+\90,)\90,#\8e+!\8a+\1f\87*\1f\83"!\81# }\1f\e\80"\1f\85-$}#\1d{"\1c\7f&\1f\84)!\88/#\851%\832"\841"\85<#p1\ f_7\ 5a<\ 5cC\ 6kM gL\ 5gH\ 5`A\ 3X<\ 3[B\ 3T9\ 3W?\ 4R8\ 4:)\ 3-\1f\ 3 \16\ 4\12\r\ 4 \a\ 3<,\veI\ 6nQ\ 4yY\ 3\80_\ 5\80_\ 4\85b\ 4\88f\ 6\88e\ 5\88f\ 6\8ah\a\8cl\ 5\8ek
+\86c\ 3\84c\ 3\83_\ 3\85b\ 3\8ad\ 3\8bi\b\88g\a\8dm\18\98|"H0\ 2'\e\ 36#\ 2\9a\83NëÜ¥ïé³ìç´ìèµëê¸îä¯áË\96ÜÄ\8dèÓ\9dîå´íí¾êîÁéîÀêî¿éîÀèîÄèîÃèîÄçîÄèîÃçîÃëí½ìì»ëí¼æìÊæîÆéî¿ìí¸ìì·ìíµëî¶êî·ëí¶ìíµëí¶êí¶ììµêí¹ìí´ììîì«îéìë¯ìì±ìë¯îê©íç¢íè¢íé¦íê©ìè¦íé¨îè©íç§îå¤îä¢îÝ\99åÏ\8aÙ¼wÊ¥\Ù¹qìÛ\99ïá\9fîà\9dîà\97îâ\98ì×\8câÇxàÃràÃsßÁrâÂqáÂráÁläÇpãÅuà¿jáÅræÉ}æÌ\82ëÒ\8fæÍ\88Ô¹l\8eB\93{2K6\ 1@,\ 2nR\1a\7fc+sR\1d\6\bJ1\ 6q`.]M\16k[-nZ)ra0yh7\8a|O\8e\7fR\94\85X\93\82W\9b\8bj§\98yçÝÃêáËëåϼ\88o\9eI=¨MD¨LB\9780\9e=7\9cA5¡J:\88:)\839,k\1f\14h\1f\19^\19\12Y\17\ e`\15\17c\16\1a[\11\ fY\12\ f_\13\14]\12\11i\e\1di\1a\17\851.Ï\92\8bÂxm®aO¼ja±d_Í \95·rZ\9eJ: F2®]J«[D¬X@¼dE²[D\843\1c\94N9\8cK1£eGÀ\93z¼\92vº\8bn²\7fl\89RBw*#\86+'\9dL:¹|cÃ\8erÏ\9awÔ\99u¬eC¡J6\98@;\89-+~\1f\1e|\1e\1f~ \ex\1e\ez \1ep\15\16t\e\1al\14\13i\ f\10t\19\1do\e\16z(%y*$s\1f\18p\18\14p\18\14r\17\14v\1a\17\81/)Á\84n^N\957,\9121\8a)'\84&#\8b))\920+\9590\940,\91.'\9b?.\9fF<\9bEB\894-\873,~&!z \17\7f%!w \12\80'\1f\80)#\873-\81+#\92A1\95I;\90K;\849,t!\11u+\11e.\ 6`6\ 4a<\ 4cD\ 4iK\afI\a_A\ 3Z<\ 3U=\ 3O5\ 3P3\ 3@*\ 3-\1f\ 3&\17\ 3\16\11\ 4\10 \ 4 \a\ 3/%\ 6^A\ 5oK\ 4vT\ 3{X\ 3\7f\\ 3\80^\ 3\86d\ 5\87f\ 6\8ah\a\8bk
+\94s\11ȱl\99{!\86b\ 3\85a\ 3\85b\ 3\84c\ 3\8ag\ 6\89f\a\92s\1a\85e\vcG\ 30!\ 2ìrðß¡íç®ìéµêê·êì¹êìºéí¼êí¼êì»éí¾éî¾éîÀéíÀèîÀéîÁêî¼éí¿èîÃèðÃèðÃìîºíê³íá¥èÔ\94ãÌ\8fçÕ\9açØ\9aèÒ\94æË\91æÉ\8eçÌ\8aåÊ\86æÎ\8cæÒ\90èÕ\93ëÙ\94éÛ\9aæÖ\92èÕ\96âÄ\81Ø£ZÄ\91HÊ\99QãÃ~ìÝ\98êÖ\8fáÆwÛ·gä¸kéÃyíÔ\8bïä îã¡îå ïâ\99ïß\98îÞ\96ïà\9bïá\9cïã¢ìÚ\95ßÁxÒ±aÕ·jؽxÚ¿tÝÂyêÕ\8fíÚ\95ãÊ|ãÅsåÆuäÄqÞÀiåÉyçË|èÍ|åÊxåÈzçÌ\82çÍ\81éÎ\87çÏ\88ÛÀv¯\91@pR\13>(\ 3B/\ 1\80^\1c\8ef#\8c_ |N\ foL\12xa+_Q\1fiW'nZ'uc6rc5\85vK\8b{P\90\80V\90\7fW\9b\8dh²¤\87ëâËéá˺\85s\9b@6\9d<;\951.\9660§KC¡E<\9dF=\897&u&\1at+$g\e\17k\1d\1cU\11\ fN\11\10\\17\ea\1c\1cd\1e"\\16\19^\14\16W\11\ ee\1c\1dc\1a\1ab\19\1ek"% TM¶kb¼qeÇ\81zà· Ë\97z±fT¯QA®_N¤O9¿sZ[F\92@,«mU«k^\96Y<\8fM0\9fhL¥vY\9bcK}@(t3\es&\16\89=2\8cD5¡_TÀ\84l¼\81_Î\97q¿\83g\97I6w$\1fk\18\11w\1d\17}\1f\ex\e\17q\19\15n\15\11p\15\15|()w)#i\15\13h\13\12r\1f\1dv&%l\1c\ei\17\12j\18\14n\1a\16t!\1dq\1d\17\8d?0·wh¼rd\97<.\8f50\8f--\8a+&\8c)&\944/\93<3\91:2\9eH=µk^ºrf»ud·zc®qZ¯k]\8fK=x) u\1c\10\82$\e\83( \83-'|'\e\90H5\92J>\8dF={+#k\10\ fg\1c\fb!\ 5[,\ 3]:\ 6[<\ 3gK\roR\10]@\ 2Y=\ 4N5\ 3J0\ 4=&\ 3/\1d\ 3%\18\ 4\1f\16\ 6\11\v\ 3\r\a\ 6 \b\ 4#\e\ 5V<\ 4kE\ 3rP\ 3tR\ 3zY\ 3\81`\ 4\86a\ 4\89g\b\89h
+\8bj
+\8bh\ 5Ûִɹl \84,\83\\ 1\82a\ 3\84b\ 3\84b\ 3\8bi \8ai\ e\8cl\10wW\ 4\9f\88Dê×\9bíæ¯ëë¶ëë´éí»éì¹êì¹èí»æîÁèí½èí¿èí¿êí½êï¿éï½êî¹ëê°ìâ¨êݦâÅ\84Ú³qجhâ»{Ù²pÒ¤bÌ aÚ°wÙ²rÍ¡`Æ\8aW¹v?Á\8aCׯoÞ»zÛ»tßÁ{ßÁ|áÄ}áÃ~ß¾xÞ»yØ®kÕ®mدfßÄzèÎ\80â¿qΣTÁ\8eC±l!©Z\12¸y$Î\98MÚ²bݹiÎ\9eIÏ\92A½{-»\811Î NÝ·kâÄwæÍ\84Þ¾mÜÀpÇ£W¤y-¬\94NxV\17~` ¦\8cFÆ©[ÝÀráÁnÝ¿iåÇvçÊ}æÊwÒ±XâÅoåÈ~äÊ\80éÎ\88èÏ\8aãË\83È®a\8fr+`C\ 6xV\11\94i"\90a\1e\91e$\8a`!yV\19yZ#fU$kY)o^.ra3tc3{i?\8a|R\8e\7fT\93\83\\96\87eÊÀ£èßÈéáÌ\97:1\9a<1\9e;2\94/0¡F4¢K9¯cT\99O<s"\11n\1c\13k\19\15i\17\13u,)i\1e\1eZ\13\15\\16\1ab!#o1-\\19\1a[\ f\ e[\14\16X\11\14V\ e\10W\11\14X\10\14c\1c\1a\89;;¢[O¦XFÂ\80hµtd¥PD©RHÀw`¦M5µiT¤]C©kL²z_\9aUF}4\1ch \12d\e\16X\17\ e[\16\va\1d\11k)\eu.\1f\9ecL\8eP8\95L>\9bQJµuaÌ\9e|¶z`y*\1er\e\16j\17\11r\19\15x\1e\1av\1c\17n\19\14h\14\ fn\1a\14z(&t#\1eq\1f\1av' s$\1em!\19h\1c\17l\1a\18o\1e\18q \1cw&$t'\1d\9dYK«gY£WJ\96B8\8a3(\8c.,~%\1e\80,!\8d90\87<.\8fF3\93E>\97M?\8cA7\8dD/\91J5°jT±t\±o\¢^K\803+\82&\1c\83&\1fw \e\8a8-\81:'u,!r#\19d\15\ fr'\1e|:)q4\1dZ/\aR4\ 4Z;\ 5eG\ e^?\ 6Y9\ 5R9\ 6C*\ 59"\ 4-\1c\ 4$\17\ 5\19\13\ 6\15\ f\b\ e\b\ 3\f\ 6\ 3\f\ 6\ 3\12\r\ 4B4 fD\apL\ 3tQ\ 3zT\ 3~[\ 3\84b\ 4\87d\ 6\8ag \89g\b\8bg\ 6¦\83"º¤Q×Í\86\8ag\ 1\83`\ 3\80_\ 3\89g\ 6\8ah\f\83e
+\85d\b\80a\råÎ\8eîã¨ëê¸êì¼êì»éí¾éí½èí½èí¾èî¿êî½èï¿ëêµìâ¦éÔ\96æÄ\83Þ³qà±pÛ©fÖ¤`רdâºwéÎ\8dìÛ ïÞ¥ìÍ\9aèÍ\96èÍ\90äÉ\8aÜ°vÇ\93T¬f)È\93PãÂ\87ìÒ\93ìØ\98ïá£ïä©îæ©îå¦ïæªîé¬îëïç¦íè«ïè«íè¥íæ£íà\9aíÜ\99æÌ\82Ü´mÒ¥\Ä\8d@¾\885º\800¹\7f+¾\859Ç\96RË£XÍ¥YË VÔ¨^âÀwÞ¼pîá\9dëé²êã°íîÆ\96|8^@
+;$\0N6\ 6¨\90IàÄváÃsäÅuæÉxÔ°[ͧRعbåÈ}åË\80æË\84êÐ\8bëÓ\8dãÌ\82зjjH
+\8a_\19¡o(\90\\e\8b]\1e\94f(\8fo0eT\1di[,l[*p]/s`3uc6wf<\8ayT\90\80W\92\81V\9a\8cjäÝÅéáÊêâ̽ka\99<5¥C6¡E>\9dB5\9bB2\9eR=t%\11q\1f\17j\17\12g\19\16k\e\19m\1e\1ci\1e\1f]\14\14]\15\16d\1f!g$"a\e [\16\16^\1a\17[\16\14P\r\rP\r\ fR\ e\ fU\11\11t-+\9bRJ°aYªbWÊ\88{¢R?É\84oß®\95¤P7¾w`ªmPÄ\8bl»\89iu.\1fn&\1fX\15\fe\1e\e^ \17[\1a\13Z\16\ e_\1c\14r3+ªqf\93Q:\8b?/|,(\97NAµrU\9eU;\856"g\14\10n\1c\15q\1e\18x\1f\1cu\1f\eq\1a\16l\16\13o\1a\18l\1a\17m\1c\en \1as$\1f}1,z2/\83C7z3.p!\17v" x##{.'\97TG\8e@2\8b>-\7f0&p"\1dm!\1ah\1a\10{.&y0%y6*{7#\8dH7\90O7\827(~0'u-\e\84;)«iR®gRw5)g"\1d|+$x$\1dz*#}1)\815+\7f0(}1$j\1e\14|6(\8bJ3\83Q2oC!L+\ 5W9 W6\ 4U4\ 5K.\ 4@&\ 41\1f\ 4,\19\a&\16\a#\12\ 4\1c\12 \12
+\ 4\ f\b\ 4\ e\b\ 3\f\a\ 3\ e\b\ 3:+\ e\>\ahD\ 3oJ\ 3yO\ 3yT\ 3\81^\ 4\84a\ 4\85c\ 5\87d\ 5\89c\ 4\8ac\ 6\8be\ 4\87c\ 1\86d\ 4\85b\ 5\84a\ 3\81^\ 4\88h\ 6\84d\auW\ 1Ѷhïà ëé±êìºêì¼èí¾èí¾çîÀéí¼êí¹êë¯êÙ\9bá¹|Ð\9cVË\8eJÖ£`Í\99U¼~<·w5½|CÄ\90PÍ aÕªhتlÒ£`Ä\93U¾\89TÁ\8fXË¢iØ´|Ùµ\80ѬpÉ `È\9cZΤbÌ _Ë\9d`Ë\9dXÊ\9dWТ[Ô§bÊ\9eZË YÍ¡XÙeäÁ|ëÏ\8aæÈ\81èÂwêÓ\8eïá\9fîç£îéªîâ¢îß\98íÝ\95ëØ\91ìÛ\96îß\9cîâ îâ íá¡îà\9eíß\9fîå¦îå¥îçªçêÃåëÎèèÂèØ\95ÓÁ{¨\8dE|e! \86>ÝÁsܾjÞ¿oâÆtÝ¿mÝÀrÝÀqåÉ}çÌ\82çÌ\82èÏ\84ìÒ\89äÉ|ؽp\8aj\1f\99n\1e\94c\14\87Z\16}M
+\89\"\98y?\J\12cY+k[)p_1p^1t`5xh>\80qF\90\80V\95\80W¥\93oæÞÈèàÊêâ̤`R\9bH>\9a>4¢JC¢HB¤HAªUJx"\14\80-%o\18\14n!\1c\826/m\1e\1cq%'e\e\1d`\18\1ai\1f"\7f8;p*,b "_\1a\1cn-+W\1e\17N\ f\ eQ\r\rT\13\12\\e\19p,+\95IA¥WP¶nfcK«cK¿v^¶m]Ê\98yÄ\8dqÄ\8ep\8bF4k$\1fb"\1dm,)\7f>8m.-b\1e\e^\e\17W\13\10c \e}<4\83@+t&\1aj\1c\14\9dQC\8fD+\93F/¨jOl\e\ fs \1ew" x \1as\1e\17u\1f\1ao\19\14},#\807,}-0y)(p#\1es" s)"\86D:\7f;7x'\1f\80+(\8c?:\89>1\805)}-\1ah\19\f`\ e
+_\15\12d\1e\1ca\18\15q)!l%\1an.!z7%\98_K\95ZJ\84>)\83:'\8eH3z3 \815(\8bE1l'\1cg!\15l"\12\7f4)w-\1ee\1e\11g\1c\1ad\19\14\\17\10[\14\ ff\e\19o-$s0!c,\17P!
+T-\aS,\ 5F'\ 47 \ 3,\1a\ 3)\16\ 6%\14\ 5\1e\10\ 6\19\ e\ 6\14\v\a\11\b\ 3\10\b\ 4\ f\b\ 4\ f\b\ 3\r\a\ 3\1f\17
+L6
+a=\ 3mI\ 3tJ\ 3uP\ 3}Y\a\81[\ 5\80]\ 5\81^\ 5\85^\ 4\8ae
+\90j\v\8ah\b\84a\ 5\83a\ 4\85b\ 4\83b\ 4\80^\ 3yW\ 1¸\9bLïà¢ìé²êì·éí¹éí¼èí¼éí¾éî½ìåçÆ\8bÓ\97TÄ\83?Ã\81;Ø¢]Úf¿\84?\94Q\ e\94Y ³\7fGÒsäÍ\92åÏ\99ëÔ\9dèÒ\99ìÙ¤íà¨îã¯íç´êìÀçïÇéïÅìí¼íì¸îë³íæ«íãíà©îÝ£íÙ\9aëÔ\96äÇ\8a׺yÎiϧ`Ë\9bS΢YÉ\92H«f!\9eS\11¾v4Ñ\97QÛ¯eåÂxë×\92ïå¢îã\9fîæ£îå¥îè«îèªíéªîç©îç©îä¥îèªíé«îçªîèªîç¨æéÁæîÃíâ îÛ\98ßÊ\83äÌ\83áÉ{çÏ\81ßÀpà¿kâÅwåÊ\81éË\83æÉ\81éÌ\82çË\81èÎ\83êÐ\86âÉ}ÜÁsª\88=\9bm"¦x*\9bm"\99i'¦{=\90q4ZI\14l\,r_/m[.p_/ra4tf7yj8\91\80V\97\87bº¬\91æÝÇéàÈêâË\96RG\8f<3\929/¤XB\9dJ>\9fD?§UN\98H8\874(\92;0 NE\93GK\89@7\8cK<g h\1d$s*0w64|@1l/)Y\16\18k*-\\e!O\r\11T\11\17L\ e\vH\f P\10\ fu.%\9dQJ¾yjÏ\8et\90E3¦UFÌ\8f\80Í \87¸\87k©pTy7#j'$a\1e\1ae"\1ec\1f\1dX\17\15a\1d\18]\19\18e$\1ac\1e\16^\18\11q+!\84<2\84@.\9bPE XF§aF»\83f\7f:*o#\1ep\1d u\1d\19o\1a\19x% u\1c\1d\91C=\85;2\7f/-w'!v)$y(%v,"\87?5\89B;\817-}1&\816,m \15r!$b\16\13]\13\10`\17\16X\11\11S\f\ e`\1d\17_\1c\13_\16\fe"\16\8eQ>¶\89p\92UB\88>+\86;)}6(n#\18{.\e\89<.\8490r'\et%\e{/$s+!j#\17_\1a\12e!\18Z\14
+S\11 `\1c\18_\1d\17R\12\bK\ f\ 4F\12\ 4C\1a\ 5?\1e\ 6.\15\ 3'\10\ 4&\11\ 4%\12\ 3\1c\ f\ 5\19\v\ 4\12 \ 5\ e\a\ 6\10\b\ 5\r\ 6\ 4\r\ 6\ 4\ f\b\ 5\ e\a\ 4\ e \ 48&\v]8\ 3a;\ 3oD\ 3tK\ 3zQ\ 3~W\ 5\80[\ 5\82_\ 4\83_\ 5\82^\ 5\89e
+\87a\b~[\ 3\80]\ 4~\\ 3}\\ 3~_\ 2\98x"éÕ\90îç¬êì¶êí¹ëí¾éí»êì¹íê·æÌ\8f¿\85?·d&Ãx2Î\90GÉ\92K¾\80: ^\17¯u-×qæÒ\9eíé²ëì¼êîÀêí¿êíÂëîÁêîÂèîÄéíÂèîÅæîÇæîÉèîÇèîÁêî¾êíºëí¹êí¹ëíµëì´ìí¶ìë³ëìµìì·îã¦íÜ\99íÜ\95íÜ\95èÑ\89Í¢[Ë\9c`رná½wÙ³lÍ¢SÎ\9cQÍ\9fTäÃyî×\8bîÜ\96îá\9fîç¦íè¬îç«îæªîæ§îçªîæ¨íè©îä¦îã¥îâ¤íé°êéµîà\9cîß\99îÜ\98êÕ\8eêÕ\8fæÍ\85Ö³_Û·gæÊ\7fçË\80ãÆ{çÊ\7fåÉ~åÊ~ëÑ\88ãË\80ؽmÃ¥W\83Z\ e\98k!\97d\18\99i"\9au1\8cu9aS\1em\-mZ*pa3r`3uc8q_2yd8\8d|R\95\86eÊÁ§èâÉéàÊéàË\841*\8b4+\8a5&\9aF3\98=0\99=0¡GA\9fM?¨_H¦ZC\9fSB¬la¯zh¦r_r5-j &x14t/*\82E8t4-W\14\16Z\18\1a\\e X\18\eW\16\19N\r\fH
+\bJ\f ]\16\14\9190\94=1\9aK@\93F0\98=/\92E1¨p_\99bUv:*i+\1fc#\1fa\1c\1ad\1a\17^\1a\17f#\1d`\1c\18^\1a\19X\17\11Z\15\ e`\19\13s1%\87K=\9d`Q£bR¶zhªlZ\9eaJs2!\\11\vm\1c\19t\e\18p\e\15v#\e\8451\8794\8540\83/*\80-&}+*z*&\7f2)\827-\87>7\818,\7f3%s!\16m"\1f\\13\13[\13\14U\10
+Q\ e U\ e\v^\17\18b \17Z\e\13g$\el("{7/\92ZG\8bL<\8aG6z0\1et/%g\1d\14u(\1c\89<1|.'w&\1ew&\1eq"\18h \14a\1f\17g!\1cb\1e\17^\19\12^\1a\15b\1f\17^\1f\15P\13\fH\r\ 5<\f\ 54\ e\ 5-\ e\ 5)\r\ 4"\ e\ 4 \ e\b\19\f\a\15 \ 4\11\a\ 4\11\b\ 6\10\b\ 6\10 \b\ f \a\r\a\ 5\ f\b\a\f\ 6\ 4\10
+\ 5%\17\ 4I/\ 3_:\ 3f<\ 3lD\ 3sL\ 4zP\ 3}Y\ 6~Z\ 5|X\ 5|X\ 4{T\ 3\81[\ 4{Y\ 3\7f\\ 5\81^\ 3\81_\ 4\85c\vÛÂxîá\9bêì¶ëïºîå®êÔ\9aàÀ\84Ù«o´|A\89B\10\857\ 2\93C\v\92E
+¤`#\92R\r´w8Ø°qìÞ¥íè°ëí¹éî¿êîÀçîÍéîÁèîÄéîÄéíÃéîÄéîÂéîÂéîÃääâæìÔéî¾éí½êíºêî»êíºëíºêí»ëíºëí¸êí¸ëí·ìì²ìê¯îç¬îæ¦íè¬îå¨îç©îè¬íéíç«íß\99àÂ|Á\91FÍ\9bOש\Ç\96FÁ\8f?ݳjåÄ\7fí×\94îà îè©îèªîæ§îä¦îã¥îä¦îå¦íä©îä¥îá íÞ\99íÝ\9cìÛ\93íÙ\96éÕ\8dÛÀqÒ§Sà»hâÄtãÆ{äÈ|äÇ|äÇ|çË~ÞÂoÔ¹cؼn~[\14|P\rmA\ 2tG\ 5|Y\11\84p3hX'kZ,m[,p_1o^0ta5sc9zg?\85uO\99\8doàØ¿êàÌëâÍêáÌ\88*'\916(\8f;-\97C2¦K?¾o^XO\9bF;§^E J8²gWº\8ar·\81o§uc\81B@r++u*&r(%f "i)!a\1c Z\17\1aU\15\18W\15\18Y\1a\1cP\ f\12R\11\rM\f U\10 o\1f\15\860,\94C=\9cNA¢H@u&\1d|5-u-+h#!h%$f!!p+*g\1f\1f]\18\16o,*n),g!#a\1e\eX\16\ f_\17\15\93TK£ne\97\O\99^R aY\96VP\84F2`\1a\fY\ f\rm\e\1ao\e\15n\1c\16w%\1a\866/\90HA\8a71\92@5\90@5\8431{.+\834.\812,}0-m \1cd\18\15d\19\15U\ f\rP\v\vQ\r
+S\ e\vS\ f\rX\14\12a\1d\1ah$\1fi)!m,'i%\1el$ q0$h%\18i"\17}7)g\1c\14c\19\16o%\1c\802)x)!|,%x)"y+#q%\1fa\19\12o%#t.(k&$c\19\18b\19\11e!\1aq0(f+\1aM\19\11;\f\ 5/\v\ 4"\a\ 4\17 \ 5\12\ 5\ 4\ e\ 4\ 5\10\a\ 3\12\ 6\a\ e\ 5\ 5\ e \a\10\b\a\ f\b\a\ f \a\ e\a\ 6\10 \b\12
+
+\16\ e\b?)\ 4P1\ 3Z7\ 3d@\ 5kE\ 5nG\ 3wP\ 3xT\azT\ 5{V\ 4yT\ 3yU\ 4xV\ 3|Y\ 4|Z\ 5{Y\ 3¶\95Kïà£íèªíç°Ñ³x\9eh2\8fK\14\8fC\16¯m5µ|G¤g.³~C\99e&À\9dkÖ³uàÇ\84íÞ¢ìî¿êí¿êíÀêî¿éîÁèìÓãâææíßæîËéíÃéíÃèîÄéîÂêìÁéîÁäé×æíËéî½éî¼êî¼êíºéî¼ëí¹ëí¹éî¼ëíºëí¹ëí¸êíºìì·íë²íë´íê³ììµìëµëì·íë²ìë±ìê±îç«ìÛ\9aíÙ\96çÓ\8bÔ¯j¯v-¢c\14\9eZ\ f¤d\1aÃ\8bAرjåÉ\81îÞ îã¥îä¨îã¨îã¥îå¦îä¦îà¢îà íÜ\9bîÝ\9aíÛ\97ëÖ\8càÇz¦~0¿\92Eݳ_äÅxäÆwãÇxåÈ{æË{ßÄuÞÃväÉ}¯\93CpJ\ 5d9\ 3mH\ enW\17\7fj/k]-k\.n].oa1rb3ud;wfAxgD\88uP²§\8açàÉéàÈêâÍëãÎ\8d4'\9a?1©UG\9eH8 A8ªLC B8 N;¦`I\8970£bT®xd\92WL}@5c!\1f|;6u((s++b\1c"r0-p+*a O\11\18Q\13\19d40N\11\10V\15\10M\ e\ 6H\f\ 3[\15\fp$\1e\95F;®bL\9dK?h\1d\16n$\1cp(#m*&k+'c" m-)l(#q.+n,(l)*k()_$\1fc%!g&#\83CB\8aMG\92RL\91OE\9a\O\8bM>x6(\\19\18R\ f\ fZ\11\13k \1fo \15w&\e\856.\99PH\93J9\99H<¥[H\94M:\815.\814,\7f3!r\1a\15`\10\13^\13\13V\ f\rO\r\vO\ e\vS\17\ eX\16\14a\1f\1f]\1e\ee$$f&!\#\14a$\1fs5&h%\1ai!\1dj$\1e_\1a\10b\1c\12d\1d\13b\19\12a\17\ fi\1f\14w)&|+*z%$~,)x(&{*,z+&q($t+*s//k&#e\e\19`\17\13e!\1f`#\eX\e\16E\ e\v9\v
+.\b\ 6$\a\b\1f
+\a\15\ 6\ 6\17\a\b\10\ 5\ 6\12\b\b\17\b\a\12
+ \10 \b\15\r\v!\14\v$\18\v%\17\aJ-\bG)\ 4N/\ 3U5\ 3d=\ 3lD\akD\ 3tM\avQ\bwR\ 5xU\awS\ 6vS\ 3vP\ 4uQ\ 3\8ek éÒ\94îçëÞ \9dx<`5 b+\ 3\80=\v¸\82PåÈ\93ìØ¥é×\9aíݦêØ¡éåºìì¾ëí¿éîÃéíÂèîÅèîÅêîÁéîÃäåãããääåææíÞèîÁéíÂêìÁèîÄèîÈçîÊèîÂéî¿éí»êî¼êí½ëì¹êîºëíºëì¸ìí¸ëí¹ëí¹êíºêíºìì·ìë¶ìë¶ìì¶ìì·ëì·ìì¸ìëµëì³íë±íë°íê¯îê¬íèªîç§èÕ\93×¼w¶\90Fz9¯w2¯|3¸}5Ä\8dBجcéÐ\90îæªîæªîã¥îã§îâ¤îá\9fîß\9dîÝ\9bíÛ\99ìØ\93ëÕ\88¢\813T,\0\97n!ɤQÛ¼iàÀráÃtßÂtçË|ãÉ}æÍ\83ßÇ{\93p#{L\ 4\8cf&\87m/tc&iX'n]1o]0td9rb6p`9yfA{jK\92\86hèßÂæÝÄéáÈëâÍëäÏ\9aKB\9bC;\90<0\9dH;¡G@\9f?;«OC¨YG\83."i\e\15l' t3+\\18\13Q\14\rU!\1d\82HDn',f!#h%'h#']\e\1dW\17\18Y\1d!T\1d\1c<\ e\rN\17\17N\16\13E\10\fE\r\ 5W\12\fg\1c\16\9aN;\9eH?\91;7f\17\12o!\1cd\1d\17p.)p.*d"\1fl,'m2(n2'o3)s36v76\7fEF£rnj74n//\8ePF\91UG\92L>\89G:\80B8q1(L
+\aL\v\vP\f\rk')y*${(#\8c95\9fZM\93I9\9bO?¬cV\93I=\856/}/#s&\14~2-d\13\15_\14\16W\10\ eS\ f\r]\1f\16\88MD`\1f\1dg(\1f]\1c\19c \1em-)x<3t7,|;5l("j' e\e\16b\1c\14c\1d\13h \1ai \1c_\14\11S\10
+Y\13\15x(,\891.\900/\84-)\85+)\86*'m# z1-l))p+&e\1d\19\\16\11V\11\12W\13\14T\11\13Q\12\13K\12\13D\ e\118\b
+5\10\ e>$\1a$
+\ 6'\10\ f&\ e\v*\10\r \v
+\1c\v\f \ f\fE,\1eqYFuS;a7\15J"\ 5B(\ 3K+\ 3Y6\ 3c>\ 4f@\ 4hE\ 4kF\ 4mK\ 5kH\ 4oK\ 5oL\ 3pL\ 4lG\ 4гmîߥîè·\93TH\1f\0\7fS\1d\8ed-ß¿\88íá¨ëí¾êí¿ëí»êî¿ëí¿êîÀéîÀéîÂèîÄçîÆèîÅçîÇåíÏèîÃéíÆçîÉçêÐåéÔêíÁêíÁêíÁèîÅçîÆæîËéîÂêî¿êí½ëíºëìºëì¸ëíµëí·ìë²íë±ëìµìí¶ëí·ëí¹ëì¸ëì·ëì·ëî¹ëí¹ëí·ëí¸ìì¶ìì¶ìë´ìë±íê°íê°íéîé«îèªîå©ìÜ\9bèÒ\93èÓ\95æÏ\8eÞ»sÑbÅ\93GÊ\97SáÃ|ïë±ìÝ îã§îä¥îã£îà\9dîà íÝ\9cíÚ\97éÕ\8dеhjJ X7\ 2pK\a¨\835Ó¬]Þ½mãÇ|àÅwÝÂuâÇ\81ãÌ\85Ë«`\93j\1f\93m*\8bo7iW lZ+hY,u^3m^4wd9ve>{i?\93\88iá׿èàÈéàÈêâÊëãËêãͦaS\99A7¡J;¯YSÄoj«YJ\97?'\8f5%{#\18r\1d\10d\1d\11[\18\10S\13\ fS\17\rW\19\16}C>j+,X\1a\15\"\1fX\1a\1aS\13\15S\15\15Z Y" N\19\16L\11\10S\17\15K\ f\f`\1f\1eT\11\ ec\18\15\844!¡E5´aSw \el\1d\15k!\1ao.(x7/j)"v91s9-d*\1ft8,k.*x;2\96a\¤xjm52v77\83C@~?8{5*\80=1p+%f%!O\ e K
+
+K\b
+\\19\19\88?4\88?4\90?;\9fQJ\8a5+£YH¡_N\94H>\879*z.\e\81:%q)"f\1a\19a\1a\15\\18\13`\1f\17m.%l,%b% Y\1c\19T\13\10h.!~E;\81@6~:2v/-m##d\1e\18b\1a\15e\1e\18b\1a\10k#\1ck!!d\18\16N\ f\ fM\12\13^\15\10\894/\908:\96?;\8e;3w%#[\ f\ f[\16\vZ\16\ fo(#k#\1ek'%h&"^\e\1aW\14\11R\15\10P\13\13C\r\ f=
+\f=\ e
+E\19\117\ e
+-\r\ e/\r\v6\14\111\ f\f/\ e
+_C2\86^M\85QHs:*h,\18V#\rE\1e\ 3I%\ 3P-\ 3V1\ 3Y7\ 3[:\ 4_>\ 3_;\ 3aA\ 4cC\ 3hI\ 6`C\ 4\9d~CéÕ\97íæ«ñè®\98o2c-\ 5´\8bQêÚ ëì»êîÀêí¿éî¾èîÁèîÃèîÁçîÄçîÅèîÅçîÅæîÇæîÈåîÈåíËçîÃèîÁèîÄéî¿êí¼êí½êíÁêí¿ëí¾ãåâèíÈéî¿ëí·ìí´ëì²ëë±ëë±ìêìêíèªíé¬íé«ìê®ëë³ëì´ìì³íë°ëìµìì¶ëí¹ìì·ìëµìí¶ììµëí¸ìì³íê°íë°íê°íé®îè«íêíé¬îçªîæ©îæªîä§îá¢ìÙ\97ß¾zÒ«bÉ\96LÕ¤]åÇ\82ëØ\97ïá¢íà¡îß\9díß\9fíÚ\99ì×\95âÉ\80¥\857Y8\ 2Q1\ 3aA\ 5\80\\11\853Ö°cßÄuؾvÖ½tØÁyÒµk\9cw+\92s.\88o4jV$iW&l^/p]3tc9vd9\7ftP¦\9bwÝÔºäÛÄêàÊêâËéáÊêáÌêãÍ OE¬QD¦C?½TR³\P\9fMA\81\e\ e{!\ es \fq\19\11^\16\ eR\16\fR\17\10S\16\11R\14\10p/*m1*Y\1c\16O\13\13L\10\10O\12\12M\10\10T\13\15Z\1d\1dW\e\1aX\17\15V\15\14W\14\14]\1a\1aR\ f\vh\1f\1a\9aS@¤F7¶`V\97J9r$\16a\18\rh$\18r5*\8aNFu51q3'o2)e)!i,#l-(m5,\88ME\89SEl4&\89OFy=6\7f<8|<6r4)[\1e\10M\ f\fL
+
+N
+
+Z\16\12\84B5 bZ\8c<2\97<<\96C<°iVªj[£[I\8d=/\8bC4\85I6]\18\13`\17\16^\19\12\\19\15d(\1eg#!d#!Z\1c\1ab'!j.%~A;\7fA6y1.l!\1dr,$q)&f\1f\19c\1e\16`\1e\18b\1e\13n&\eq'"P\v\rF\ f\fG\r\rO\r\rr(&\8a9>\9bCC\91==z*&]\10\14S\v\fN
+ X\16\15c\19\eq')p,&t3+j$\1c]\1e\14M\11\ eG\ f\ f?\r\f@\10\r@\10\ f8
+6 \f4
+;\10\11;\10\10@\17\12P,\1dc2\1fl0%j/!h.\1fb-\1aG\1c\ 4=\1f\ 3D"\ 4I&\ 3K,\ 3P2\ 3T6\ 3V7\ 3X8\ 4Y8\ 3Y8\ 4[A Ó¹~îß©íç±îç²Ú½\85×¹}ïå¯ëìºëí½éîÀéîÁèîÃèîÅèîÄæîÇèîÅçîÆçîÆçîÆæîÈçîÆçîÇçîÆçîÄçîÄéîÁèîÁéî¿êí½ìë±íè¬ìê¶âåáìë²ìê¯ìê¯ìé¬íé¬íé«ìêªíç¥íè§íç¤íç¡íæ¡íæ¤íç¦íéíë°îê¯íë°îè¬îêíë±íì³íì²íë´íë·îê¶ïê²íë¯íé¬íê¬îè¬íé¯îé°îç¬îç«îçíå«îæ¨îæªîä¦íà ÜÀvÏ©`¹\8fJÉ¡^ßÀyíÚ\94îÞ\9bíÜ\9cíÛ\99ì×\93çÐ\89ÔºnnQ\11;%\ 3F-\ 3H-\ 4W9\ 2\85?ÞºoÜÃzÞÇ{ÞÆ\7fÊ°h\98y4\92s.\89q4lY%iX'n_1sa6te<\84uJÞÕºàÕ¼ßÕ¼ãÚÂèàÈêãÍéáÈêáÍéàË´IEËNPÛSTÏNP F4\927)\83&"\86:/\8eI9\80=1j+#N\15\10I\ f\fL\ f\10M\10\10x<<Z\19\1cS\14\12N\11\13P\13\14K\11\ fJ\10\ eN\12\12X\1e\eY\1c\eX\17\18Z\e\15U\13\vH\r\aF\f\ak(\1cªdO¥RF¨]I\96V?r.&j!\14h+\13\9baS\8aMC{<4\81E8c% b"\1c}C3s7)\8cZL\91YQk.&v:*\96aT\8eVK~@7\91UN\86QML\11\fH\r
+K\v L\f\v\\1a\14\8bRDvn\98UJ\9397\9273\98@4\9fOB\9e[F\813+\87B=Z\17\12^\e\18X\14\13Z\1a\16\\1c\17c$!j)'q0,k,'b#!k.+y<2o-%a\18\1ad\e\19k#\ei!\1eo(#s-!k+#]\19\13j"\1c`\1f\19D\f\r? \bH\f\fG\v\vc\1e!\8a8?\98><\8a27\83/-d\15\10S
+\rL\v\vC\a\aL\v\f^\17\17q,&t,(k%\1fa#\1aS\14\ fF\f
+?\ e\fC\12\12<\f\v8\v
+7 \v5\b\b=\13\128\ e\ e3\f\vL \16\+\1ai3$k7%g3 d/\1cX%\r6\16\ 32\16\ 3?\1f\ 3?#\ 3E*\ 3E)\ 3G+\ 3J.\ 3K.\ 3L.\ 3\8ck8ðÞ©íä¯íæ´ìê¸ìé¶ìì¼êí¿ëí¼ëí¼éíÁèíÄèîÂçîÆçîÅçîÇçîÆèîÅçîÇæîÈæîÉçîÇæîÈçîÆèíÅçîÇèîÅéîÃëë´íç®îá çåÑéé¿íâ\9eíã\9bíà\9bíß\97íÞ\95îß\99îÛ\94íÙ\94ìÔ\8cîÜ\95ëÖ\8déÍ\83å½tÜ®hÙ§`ׯiÛ¶qÝ·yܵsÔ¨eÜ°kçÄ\85í×\99êÖ\96ìÜ£åË\8eݸ~ܵræÇ\81äÅ}èÆ\7fçÆ\80î×\94îÜ\9bíÞ\9bîâ¤îâ¨îäîæ©îæ«îã§îã¦íà¡íÝ\98äÐ\8e˪f¤z-Á\9bQãÌ\83îÛ\9aëÛ\9bìÙ\96èÒ\89ÛÀu¥\87<<%\ 1A(\ 37%\ 36(\ 3cC\10Æ¢]Ú¾rÝÅ|âÉ\88̲o\8cr,~f#\80j0jW"kY'oa2sc6wg@\96\8beà×½á×¼ßÖ¼äÛÃëâËéàÈêãËêáÌêáÌÎ[]åOZîV`ØDG\993)\9eM9¶|c±~f¬za¦v_\93cMb%\1d_#!S\17\19Y\18\ej21W\19\19W\1a\17K\10\rN\e\16M\18\15L\12\10K\14\11M\17\14Y!\16o3'u1%f\19\10L\r\ 3S\16 r5#°fS F>\9bJAu-\1fj \1a\81:0\94_H\8dMA\8aF=\8bICs6&k/*y81{?2\87N=\82H=i'%l+(\89N?¶\7fp\7f=4\80?;q40`"\19H \ 6F \ 6F\v
+K\f\rf \8cC; ZR\90A:\8e40\904.\914.\97E:\858&\808-d\19\14a\1f\1d^\1a\18`\1a\e\\e\18]\1c\19]\1a\1a^\1c\1ef'%m,*h'$s3*~E7^!\14\\11\13]\13\12]\13\11`\15\16z1-p'\1ck'\1ak#\1aZ\13\12B\f
+=
+
+>
+
+>
+\vH\ e\rb\1e\1f\7f0.\90=5\8974\861/r"\19W\ f\vN\ e\vI\a\fC\a\a=\ 5\aM\11\11_\1a\19a$\19U\1d\15W\1d\19T\1d\13H\18\fQ\1e\15Q\1e\18T"\1e\*!W(\18=\10\a8
+\v<\ f\11n@6c3 ]*\17e2\1ec/\eb.\1a`+\18W&\12B\17\b-\11\ 37\1a\ 4<\1f\ 4>"\ 3>"\ 3A&\ 3C'\ 3C%\0ÈvïÞ¨íå³ìéµëê¶ëë¹êìºëë¸êë´êí¼éîÀèîÄçîÆçîÆæîÆçîÅçîÆçîÅçîÄæîÉæîÇçîÇçîÅéîÅéîÃéîÆëðÂìâ¦æÏ\8eÞºwϨdÓ»\90Ì®uÒ YÙ«`Ù¤ZÚª`ت[Ô¢TÌ\9bOÆ\90KÍ\97TÓ£ZØ«`Ï¢W¾\91Kº\85F¿\83=Æ\8dFË\98PÔ¤_Î [Í\9fYÇ\95UÃ\8fNº\89N¾\8bOÁ\8aH»\85Ds0·\83BÌ\9f\Ì\9eZÉ\90KÅ\88D½\82>Â\85@Ã\8aEÇ\8cGË\9bVÓ°såÌ\89ïÞ¤ïå§îå¦îá£îà îà\9fêÚ\99àÊ\81Ä¡U»\91DÒ³iéÖ\91ìØ\8féÔ\8dÝÆz¹\9dTS6\ 5<%\ 32#\ 3-\e\ 34\e\ 1\7f_(ÏhÛ¾uØÁ\80ÖÀ~\95~<jX"ye2bQ\1egV#m_1pb2vg:®¤|ßÕ»ßÕ»áÚÁåÜÃéàÈêâÌêáÌëãÍéáËÃZOÛa\æSPÏC<\9b/ Á\80hÀ\8coÁ\8ep»\87jµ\84k\80lu8/h'\1fk0(e"'U\16\19T\17\13M\15\ fM\15\11tI>U,\1dH\15\ fN\1a\17[)"wHAm5!u(\1an\e\13Q\11\ba!\11\82C3¨UO\8a.(\8543v,'o+$o)$g\1f\1cp*#\8aH;~3+\80C6\80I<\95[L\83M>h1#g,%t75\7fC4\92VJ\82@7\9a\Q\80D>f+)N\ f\rF
+
+D
+\bH\v\vN\r\ fj""\851*\850*\87/(\8a3+\95>4\934.\8d3/\811!\87A6d\e\13T\12\v[\1a\18]\1c\1a[\1a\17[\18\18Y\15\16[\19\1a_\1c\1eX\15\16c&!k-#n0(]\1e\14a\17\18U\ f\r\\12\ em##j \1ea\16\ ek\1e\13r-"K\ e
+?\f
+>\f\f< \a;\v C\r\vf#"}.+\8c55\840)\8200\8775g\18\19R\r\rO\ f\11?\a\ 59\ 6\b6\ 6\ 4>\v H\12\rV \12V\1c\15Y\1a\13c&\1d\80F7\82O?{J;q@.])\15L\17
+D\11\ eJ\18\12e1)Y%\18M\e\ e`-\1cc-\1de.\1ch/\1fh/\1fg/\1fQ(\167\15\ 5+\12\ 2+\16\ 3-\17\ 30\16\ 32\19\ 3L2\16èÏ¢íß®íå³ìéµëëºêì¼êì¾ìêµìé±éî¾éîÀçîÄæîÅçîÄçîÅèîÄæîÅæîÇæîÇæîÇæîÇçîÆçîÅêîÀëç®éÓ\96á»vÑ\9eVÑ X°~<À\97^©{?¸\89LÕ«eåÄ\7fåÇ\82çÌ\89äË\89ßÅ{Þ½tܽwÞ½|äÃ}ëÑ\8díÙ\96ëÛ\9fëØ\98êÙ\9aëÛ\9bìÝ\9dìá¤íâ¤ìߣìߤåÎ\92ÜÁ\89صzѪiܼ~ÜÀ\80ãÎ\8eëØ\9aèÕ\98æÎ\8dáÁ\81Ö´sÂ\96V²z;\9aV\16\8bJ\a\91T\18\9bc\e´\81BΪlçÏ\8aíÞ\9aîá£îâ£îá¢íÝ\9cìÜ\99ßÈ\82»\9bT RäÍ\84éÔ\8cáÌ\83Ë´kxW\ f[9\ 3T2\ 3S3\ 3J.\ 3I*\ 3\91o-Ë®jʲu· b\98\81C\84p6sa,l\-iW&n`1pa4sc:÷\93ÞÔ»à×¾àÖ½æÝÅëãËéáÉêáÉêâÊéáÉÔtfØrhÉ\PÇPI¡<.´aKÂ\8alÀ\89o¸\81c³\80d£nZh'\1f`\1f\1ae)"_$"M\10\11Q\16\12Q\18\ fN\14\12M\16\ eK\16\fH\11\ fK\16\12a/)\84WH\86T@m-\1dS\15\vU\e\14{9-\8d>5\9465\8d62\8681k\1d\14u0(\7f?3l$!q.+y4.~7,u3,y;1\92bKk8'e'!v:4\8cQO\95UO\8aHH\8eMJ\8bNG\80D<]\1f\1fS\14\14K\ e\rI\v
+L\ e\ fR\11\12w..\881.\8a/-\8b,(\9180\8c70\8a3+\8d72{+ s*\1e{5+d!\14_!\13Y\1c\15Z\15\10Y\19\16V\16\13Y\18\19W\16\14Y\19\17a#\ed&"n1)d\1d\1eb\15\18a\16\12d\1a\12f\e\14c\17\ eh\1e\13r+\1c[\e\11@\v\a=
+\a;
+\a?
+\a=
+\aF\ e\fb\1f$|0-\8865\8972\7f-,\8683w&&o \1e\\14\17A\a\ 6:\ 6\ 66\b\a7\a\ 57\a\ 6?\v\bH\12\ fF\ f\ eU\18\15g%\1fu7,p5*[ \eU\1d\15F\f\ 5C\11\vC\r
+B\ e\b=
+\aE\13\f[)\1dj/%i-\1fo3$o3$q6's;'m8'Q"\117\12\ 3+\12\ 3%\ e\ 3\1f\r\ 2t^;ëÕ¦îà«íæ±ìéµéì»êì¼êìºëë¸éíºèîÂçîÄäîÊåîÇåîÈçîÅåîÉæîÈåîÉæîÈçîÇéî¿ëë·ëߣåÁ\7fתcÓ£^ܳvâÆ\89çÏ\91çÒ\97ê×\9cåÎ\8bãÌ\83ìÔ\8dëÖ\93ìÖ\91îà íá éÔ\8eåÆ~êÕ\92íÜ\98îâ¢îç«íê±íê³íé²íê³ìë¶íë·íë·ìì¸ìë¸îéµíé´îç±îã«îã«îå©îæ¬îä©íé°îç¬îæ«îä§îâ¥ëÜ¡æÒ\93ÙÀ\81É«kǧm²\90K\96e&\95]$®\80>Ò¯hæÒ\92ëÛ\9eíá¤íß íÞ îߤêØ\98˲i¾\9cSÝÁvâÌ\84ÚÄy\90t/^8\ 3Y5\ 3T2\ 3T6\ 3Q2\ 3W6\ 4tW\1cqQ\15fL\10P7\ 3\89q9r]'lZ+m[*m]/ra5|pLÑƦßÖ¼ß×¼áؾæÝÅéáÉêáÉéàÈêâÊêáÊÂ\MÊr`ÙuoÏVM³C5¢H3\9fO8¤_F\98^D{A-[\1d\13V\15\10Y\17\13V\18\17U\19\17S\17\17R\17\14M\14\13I\10\rJ\10
+H\ f\bF\ e\fR \eyL=\96lU\89YHF\v\ 2E\ f\ap7*\97RG\9aD<\9d;8\9122z,!}5"\8dPA\84?5~4'x2%\81;3x3&c \14\87LD\8cW@f, e)"¨pc\83NCr.-|<=\80E?\82D@l*)M
+\bR\11\11T\13\rU\13\ fR\ f\ ed\1d\16\8a63\8e><\8b81\8f00\8a/'\96;3\8b.+\8a2*\872&~1!t+\18z4(e#\16c\1f\1cg%\1ec%!^\e\15[\1c\1aU\14\11U\16\13]\1e\14j*,q3-\86GB\88B;u'"l \14g\1d\13n!\13q+\1ed#\1cF\ e\f@\v\a@\v\a?\v A\f ?\f ?\f\bd#%|/2}/0\834/\8572\8420\8632\8715~.4_\16\17F \ 5>
+\ 5:\a\a8\a\ 5< \a<\b\ 69\ 6\ 4<\b\ 6D\ e\vI\10\rE\r
+B\f
+D
+\bI\ f\rI\ e\vC\r
+G\ f L\12 `#\1c_(\1fl."i)\1cn,!o,\1fs1"s1 u/$m/\1f`&\13Y$\10D\1a 3\11\0¬\90fìרîÞªíæ²ëéµëë»ëë¹èí¿éí½èî½èîÂæîÆåîÉäîÌæîÉäîËåîÉæîÇæîÇèîÁëì¼ìÔ\95Ý«gÖ\99WÌ\96Sâ¼yêÖ\9bîçµîêµîäªìÙ\9cäÅ\84Ü«fÎ\8fIÌ\85BÁ~:Ç\80;Î\93KÕ£Y½\80:´k#Ä\85=Å\90HÎ¥`à¿zíÙ\9cîèíë¯ìë³ìë´ìë¶ìëµíëµìë¶ìëµíë³íë³íêµíê¶íê¶íè³íêµîéµîé²îê³ìì¶íí¸íê³íê²îå¯íá¨ëã©êÜ\9fãË\8aÖº{βtÓ®j׶qÞÄ\83ÞÅ\80éÑ\8eéÖ\96ëÝ\9déØ\94âÏ\86Ë«[¹\8eBÔ¶jÜÈ}²\9e`?&\ 35\1f\ 36"\ 3="\ 3B(\ 3I-\ 3E,\ 3M1\ 3P2\ 3V: \94v?s[$iZ(kZ&n`0tb6{nFÙѲàÕ»âؾà×½êáÉèßÇêáÊéàÈêâÊéâÉ°IB¶^TÁcW±KC¨M; L7\84*\1et&\19^\1e\vJ\ e\ 4P\13\10R\13\ fP\ f\fU\19\18a%"Z\1e\1dS\15\12=\v
+C\ f
+T\15
+H\f\ 4C\ f tD0\93eN\92_KY%\17L\12
+c&\19\87A/\878)¥TI\9a>4\901+v*\1a\87?0\91UH\7f8-\88A0\8aM=n-#h+%y=/\88KAx:.n-*\82D:s2!t5(|B5\82L=\89P@\80A1a\14\16I\b L\f\vQ\11\ eN\r ^\14\19z-"\854-\8f@7¢TA\8d1*\8e1+\8c)$\9b>=\8e3-\8c2$\89D*p%\14k%!j&'\88KEp-(n11b \1dQ\17\16P\ f\10Q\10\10m6,\89KHy54~64|*'n\1d\14m\1a\12h\18\ fh\e\13T\12\aH\r\aA\r\bC
+\bD\r
+A\r C\ e\v?\r
+E\ f\ eq/*w)"y)"s'\1dt0#\844/\8738\8d36\8866\81//p"#R\10\rF \v@
+\a<
+\ 6;\b\ 5:\b\ 58\ 6\ 49\a\ 4< \ 6;\a\ 4? \a>
+\aB \aK\12\10U\19\15Y\e\ f_\1c\ fh!\15h"\ec\1d\11g\1f\15j \18l&\15t(\1dx1'}6*s*\et+"n$\eh%\17f/\1aÕ¸\90ì×¥îà«íå³ìéµëë¹éí½èí¿éí¼èîÀèîÂçîÄäîËäíÍåîÌåîÉåîÉæîÇèí·ìÙ\96ã¼xÐ\95MÊ\8aCסZçË\8bïæ«íâ«éÏ\93á±oÎ\96RÁ{4¿p0Æ\80>Í\93TÏ\95UÏ\95RÏ\9f[×¥bÃ\8eF°y7¯v0±{1«v/©m'ªp+¾\82DÔ ]à¾xîÜ\9dîå¨îé¬íë°íê¯ìê±íëµíê³ìê³íê³ìì·íê¶íë¸íêµîéµíé¶íé´ìì¹ëí½ììºíé´íê¶îç²îé´îä¯îä©îá¦ìà¤íߣíÛ\9fæÍ\90ØÀ~ÐbЬaήaѨ\Ì¥YȤQ¿\8eC¨{1ؼsλwaG\v?#\ 33\1c\ 30\19\ 3-\1d\ 3+\e\ 3*\1a\ 3/\1d\ 33\1f\ 3V?\12\91u>q_(jY'jX$n^/wf9\8azVÝÓ¸àÖ½âØÀá׿éáÉêâÊêâÊéàÉéáÉêâÊ£C:¢C8\9bN8\8fC:\8f=1\899)|+\1an#\14j'\1dS\17
+X\16\12b'\1eW\1d\ eP\13\rT\13\ eW\1a\16V\19\13S\1a\12^%\1ah*\ed*\1fc2&\8bVE\82F-\!\ fK\13
+k-&\85;.\823+\8d:0\9aC?\9b?8\97B1o \14q)!|;-l-\1el+\er5)n."u;+t5)o.'v43x85\83E<{>1\86H?\8eSK¢ma\8ePAl"\16W\r\vK\v\bI
+\aM\10\b_\19\17u%#\888-\9eNJfU©^K\98@7\9a@7\978,\99=8\92<3\9cP=\95P?|.%\82<5\91QOq0(k($a\1c\1dP\r\rQ\ f\10P\f\ fO\ f\ e^\1f\1ad!\18b\19\10k\18\1dn\18\16l\13\14f\13\rU\f\ 5M
+\ 6C \ 4A \ 2F\f H\ f\fG\r\fH\11\ fN\15\13S\18\17Z \1dw31}5.w*%v*%\86K<v,$|*(\8700\87,*\89,.\83(+}%%f\10\16W\f\11D \b@\v\b>\b\b>\a\ 5?\b\ 6E\f G\f B \bC\b\ 6J
+M\v\v_\1a\12f$\16i$\16c\1e\13_\14\v`\15\vf\1c\12g\1c\13j!\11r%\19w0"\82:-\8a@0\93S@\85L7\8dR3\8cZ;ÝÀ\96ëÕ¥îá¬íçµëé¶ëëºéí½éí½éîÀæíÁèîÂçîÅäíÉãíÍäîËäîËæîÅìæ©æÀxæ³mã¶nÝ´læÁxàµnاiÖ¨pÓ¥e¹}=ºw6¨a'±m/Ö¥iëÏ\91ìߪîá¨íå¯ìæîè°ìÞ¡ëØ\9dëÛ éÙ\9cêØ\9báÊ\86Ò³tÄ\95W¹\81@¾{=¹x:Ì\9f^Þ½|ëÓ\8fîà\9fîåªîé¯íê³íë·íê¶íë·íë·íë¸íë²íé°îê°íë±ìì¹ëì¾ìë¸îê³íé¶îé¯îæªîç¬îå«îæ®îçîåªîá§íÞ¡ëÚ\9cäÏ\8aÓ·mÆ SÚ`Ы_Ó´g¢p"\89V\f¬\86CÕÀx\87g&f:\ 5_6\ 4K'\ 49\e\ 21\1d\ 3+\1d\ 3(\19\ 3+\1c\ 3P?\18\7ff4l[(iW'lZ*o`/ub7\9c\8bfáÖ»áÖ¾äÚÂãÚÀçÞÆéáËêßÉëãÍéáÉêâÊ\9eP7\98<1\9eM<¤`N\836#\857,\849'e!\12O\11\aX\13\vW\14\ra"\17V\17\ eW\14\11V\12\ eY\15\14R\12\r^ \18X\17\10l+\1fa$\16[\19\ eX\1a\ fI\f\ 4O\11 i)\1ez1#\824%\8c91\93<1§TQ\9dFF\98>9t)\1f]$\en1$g$\18m-\1fv7)s5$p1%s1(h&#i('h%%i''{;<\8eOC²yg\96^Im+ [\14\ fX\14\13P\ e\ f]\19\10d\1a\ fv&'\96AA\91=7\93D<¡XF·pZ\9bB;§VJ\9dH5\9fA:\9cE@\9fJE\8c:0\800'\8dL@q*!`\17\18Z\15\13U\ e\10U\12\12Z\16\15S\10\ eW\13\12l*\1fs0#g\19\11h\18\15p\1a\14\7f)\e\849(t&\16k\1d\13Z\15\vZ\e\12Z\1a\14V\15\12[\19\19]\1a\e`\1c\ea\1e\1dn'(h\1f h\1d\1fu*&|-%u*"\814+~*%\8a11\89-/\8a,-\88*)\87)'\83)-y\1e)k\18\eW\f\rS\v\rS\v\rR
+\fY\ e\10Y\10\r]\13\10n\1f\1ar%\er*!k#\18q$\er#\es%\18k!\12c\18\ fa\16\fg\1c\13g\1c\11i\1a\10l\1f\13o"\12{,$\8b@,\87J3\99gF«\81_æÇ\9eìÖ¥îà¨íæ±ìè³êëºèí¾éî¾èîÃêí½èîÂåîÈåîÊåíËäîÊçïÆëÜ\9eØ£XÈ~4Ï\91IÚ¥]É\93IÊ\8dH»q2ÜÆ°æéÝçÆ\88Ú®xççÆçפèÑ\96íå±ëíÀëíÀëíÀëíÁêîÂëí¿ëí¿ìì½ìí¿ìì¼ìî¾íìºìç´íá¨çÒ\97Õ¯r¯u:¶\80AÄ\91KÆ\93SË\9ebÓ±såÊ\8dìÙ\9aïå¨îç°îë¹íë¶ìë·íë¸íë¸íê·íì¹ìí½ìì¾íê¶íê·íêµîç±îç±îæ¯îå®îå«îè®îè®îä©íá¥íà£ìߢìÛ\9dêÙ\96ìÜ\99äáÌäéÜÒ¶i\9ak \91]\1fÄ¥`\9a\83Bj?\ 4{G\v\80I\13\7fF\15^3\aG(\ 36\1e\ 38%\ 4ZG\eta0q_5m]2l[0td8wgA¯ \82ßÕ¸â×½äØÂåÜÄêáÉéàÈèàÈèßÇëãËêâÊ¡X?\8e7+\95E8¥aQ\8dB3\7f5$\828,g(\eQ\14\ 5b\1e\11s)#p#$_\17\15V\13\10[\18\17]\1a\18R\16\16f'%o/-d\e\17V\15\ 6^\18\ ek#\1ak(\1dx,\1a}2'\856/\8a9*\93=0\95;3§PL§SP\9983|3)Y'\19f)\1cj&\16o(\1du5%\84D5w60x93m5&k3'e*!g&\1fn((y/(w4(d!\1aX\10\v`\18\12f\1c\1cf\1e\e\84>2\88:/y\e\1f\955:\94;<\95>7\9eL@°`P G3¯fS\95F+\917/\9697\913-\8b+(\80$\1c\838.o'\15`\17\ f^\18\14S\ f\10R\ f\11[\14\14Z\15\14Q\r
+Z\10\10[\10\11]\10\11f\1a\16\84:/\8a=0\8c>/\83/$~.#y+\19k"\14m(\1fj\1f\17e\1c\17b\1a\18l!!l#\1fq)#k!\em\1f\1eq$\1fv(\1dv&\1d\8d>6\82/'\8f30\946:\9355\8e./\8d//\9053\87)-\85('\80\1f\1ep\17\19j\18\18m\e\1ex"#{"\1f|'&}(#\86/$\8a8/\840)\82)'|%\1f{%\e^\1a\fV\e\10g!\ fd\16\fh\e\ fh\18\ fk\1a\13i\1d\ fp \15\7f5#|3\1d\93Q<ªsQâÆ\94ìÕ¥îÞ§îä®ìê·êì»éì¼êíÀêî½èî½éî¿çîÄæîÅèïÀëë±èÉ\88Ó\9bT²Z\14¯P\rªO\ e¦R\12¦_\18·z6à¸}éá±ãåçìë»ìèµéêÊëëÂëîÅêîÄêîÂêíÂéîÂêîÃëíÁêíÂëîÁëí¿êíÁêí¿ëíÀëí¿ëí¿ìì¼ìê¸ìã¬æÔ\96èÔ\96ëÕ\99ãÇ\89Ó®rÃ\98W¼\89L»\8cMÍ£eäÅ\8cíÞ©îæíê·íê¸íë¹íë¸íë·ìì¹íê·íë¸îê¶îè³îæ°îç±îå°îä®îæîåîç®îæ«îåªíá¦îá¤îã©íå§íë¯æëÉãæÕìâ£Õ»q®\88= z3\9c\83?V4\ 3pB\fxC\10}D\14\85N\ei5\ 5R1\ 5D.\ 3gU&r`.n`1o_5o`2sa4q^5Á´\9aàÕ»â׿âØÀæÝÃéàÉëãÊéáÊëâÊêâÊéáÉ£_G\849"\88;%\84;+\805"x, z/&k&\eb\19\10k"\1cw-.t)'j!\ea\e\10r.-l,$o,)\82<9\8eK>\8cJ7|>&\7f<(\86</\7f5)\821\1a\94=6\99I=\95A-\917-\9cA8²`WµhY\9eE:\88;.e#\16n'\1ak%\14h!\13u/\1c\94PD\9a_T\8aL9\8eQ: cJ|=-k%\1cW\12\rY\11\11P\ e\ fM
+\v~?8£i`\86E@\7f5'\97E7\8a.(\83 C:£C9\9cB:\9e@7\944/\9eA0©\K¨^I\95B.\98?9\9280\891&\84.\1e{)\1ez'!o\1c\18_\10\f`\15\15c\16\17e\12\17`\10\10`\11\10m\1c\1cy(-\94GJ¥]U\9bTA\94A:\8f60\9cK@\9dR@\90A1}.$~/)x+ q#\eh\1a\19f\1a\1ak! k!\1fl#\1eq%"t%#y(#v'\1d\862,\94D8\8e9/\8e02\8e+,\8c)-\8c++\8a)(\8d+*\8f00\8f//\81#%\83(%\83'%\87+(\87*'\84(%\84)%\84,%\8f81\8a/-\8b.,\84'!\7f*!m%\1a=\10\ 5a+\1ag"\ ff\1a k\1f\13k\1d\ fn!\11o \ fp#\13v,\14w,\12\92S1åÆ\9aíÕ¢íÛ¤íåìé´ëëºêìºéíºêîºêî»éí¼éî½ëêìÓ\93Ö ^Ð\98Vºq.\9dM ©\\1cÀ\80=Ó\9f\âÄ\86ïâ«ìç³ëíÃêîÃéîÆéîÆèîÈéîÇéîÆèîÉéîÆêîÆéîÄêíÃêîÂéîÃêîÃëíÀëíÀéîÄëîÁìí¿ìí¾ëíÀëí¾ëí½íê·íì¸íê·íê²íå«ëÛ¡ßÈ\8dбtÀ\96X²\85FÁ\92T׸\7fëØ¡ðæ²îé¯îé´ìí»ììºíêµíé´íé´îé³îè³îå®îäîå¯îäîå¯îæ°íë±íä¦îâ¤íá¢îä©îç©îé¬íè¯åìÂíâ¢ãÐ\89ÓÀuª\88>\92u1L1\ 3\2\ 3c7\ 5j< o:\vl;
+Z2\ 4M4
+ta5uc3tb4r_4sb5ue7wd9ΨâؼáÖ½ãÚÃæÝÄèàÇêáÊëãÎéàÉêãËêâË\91M6\85E2d \11u%\19|/"q!\18t#\ej\1f\16d\19\rh!\16{20n(\1en!\18o#\e|21s**v.)\85>8\9dWE£eP\9c\G\92I8\8c<+\864$\96J6£MG¢S@\95A2\91<6\92<0\9dD< F;\8b4+\8b:1~2(l \10n!\13s'\17t&\1cz) \8d<,\8fD0\875&v( `\14\12Q\v\bM\f\aM
+\fI\ 6\bn0+º\83qµ\80l\97[K¦aQ\9875\99>5\9b@7 C6\976/\9994\9c8/¬YLµdUaN³_Q¤Q? L<\97?2\95A3\96F7\97F;\98E@\8c2.\8a11\8974~,"|("~%\1e\8941\90AA\9cIO¦TP\9bB@\8b%$\8b#\1e\8e..£KC¨YG\9dI=\892(\7f*(\8601\89:/\8597i\1e\1cf\1c\eg\1e\1cj \1cn\1e\1dr"\1fo\1c\16y"\19~'\1e\90:1\99F5\8f8+\8d/+\8e-,\88'%\8d--\8f/.\8b+)\88*'\8a-*\8d0-\8c/+\87*'\8a-)\86,+\86,)\85*)\86-*\8b4,\883%\927,\892"\80*\1dV\19\fO\1a\ 5b\1f\ 4j\1d\ 5q!\10t&\15q#\vt!\rs%\12w.\13m*\v\91T+â¿\88êÓ\98îÛ¢îã¬íè®ëëµêì¹èí½êí½ëë¶ìå§ìÙ\95à®eÅ{9\9fF
+¢S\12¿\82>Û³wéÎ\93ìÞ£ìè±êîÁéîÄèîÅèîÈçîÉèîÉèîÉêîÆéîÈéîÇéîÇéîÅêîÄéîÃéîÂéîÅéîÃéîÄêíÂëîÁêîÂêîÂëíÁìí¿ëîÀëì¼ëí¼ììºíì¹ììºíê·íë¸íê·îé²îä©ê×\9cßÆ\89Å\9c]¶\85FË\9aZ×käÅ\85íߤíé±îé´íêµîç²îæ°îå¯îæ¯îå¯îä®îã«îæªîä«îä¬îè¯îè«íä¦íà¡íà¤îã¤íè¬æçÓâä×íé¨ëÜ\97ÝË\82ÔÀ{\9a~?T:
+Q.\ 3`3\ 5e8\ 5h5 `7\fb>\ eV7\ft_1qa/uc7p^2tc5wf;zi=ÝеáÖ¾äØÀáØÁãÚÁâØÀåÜÄêáÊêâÍêâÍêâÌ\88?#y4%q/%n!\16x( m\1e\16b\19\16]\15\13U\18\vJ\12\ 6\80>1m&\e|2%w0%}5+|8.{/.\8c<:©jV©oV¥gO¨cJ\8fA/\8f@+¢YE²ia\9bL>\92<(\96@6\9aK?\929/\98@6\93<1\94>5\8f;3\8e:)~)\1fw$\14x#\1a{"\18\84*\1a~*\ei\15\10T\ e\ fI\v L
+ L\v\bL\b\bL
+
+\7fI<{@0[\12
+f!\15¡WA\9b6/\98<6§[J¨UC\9cA2\965*\980%²[I«UH¤K=\9b>1§HE¦ND\9cK;\97?6\97?:\96=9\92:6\9042\9378\8f72\8b5.\8e2/\94:3\9c@;\92;:\8e03\8f).\8d*%\89("\8e)'\90/,\9d>6\9eB:\99A8\9bD7\89+,\9053\8c;0\87:1z0)t**m""m!!h\1c\17n\1d\17n\1d\16u# }&\1f\9351ªZJ¡UE\8e4#\8d3-\8b/)\903+\8c,+\8a-'\89-%\89,%\8b-)\88-"\8b.(\8e0.\8e45\86-)\870&\96<2\95=2\97C2\94;.\919+\907&{5\1ex@\1e\7fB$n&\fn&\ eu)\10x.\13{1\12o*\ai*\vc*\ 3\8bV,Þ½\82éÏ\96îÜ¢îâ¬ìè²ìê´ëì¸êí»ëì»íÓ\91æ»qÑ\97R¤T\15\97@\ 2\9eQ\ fÔ£dëÕ\98íë»êíÃéîÂèîÅèîÈæîÉèîÈçîÉçîÊèîÈèîÈèîÈèîÉêîÆèîÇéîÆéîÆéîÇêîÃêîÂéîÃéîÄêîÂëíÀëíÁêíÁëí¿ëíÀëíÀëì½ìì»ìì»ììºììºìë¹ìí»ììºìë¹íë¶îè°íå¯ëà¦àË\8eѱwÉ\9b[Æ\96TÍ£`ãÊ\8aîà¦îä¨îåîäîä®îäîäîä®îå¯îå«îåªîä©îåªîè®îçîã¦îâ¦îå§åíÇãäØåêÍíà\9eéÙ\9bâÏ\8fÜÊ\84ƯkcL\13B&\ 2d;\ fd;\bg=\vgA\12nB\15hF\1a\80j5q`/td5tb5tc5td7\89xLÝѱàÕ¼ãÙÁá×¾áØÀãÙÁæÝÅåÜÄëãÎëãÌêâÍ|2\1cj!\17i$\18j \14l\1e\1a[\18\14B\ f\v3\r\ 5/\ f\ 4R(\13\84L>k(\1cu.\1ft,$\83=6\8eJ;\8460\96A:«bLoW§cS TB\9dR@¥`IeS\9aH>\91=3\95A8«ZM\91B3\94<3\97C<\95>4©WK\9eK:\9e@7\9cC>\909)\860'|$\1d\85/"r\e
+`\11\ eO\f K\ e\vW\10\10\\12\ fY\15\11Y\19\13z;0z4,v("x-#\9fQ;\955)\956.±dMÆ\82e·fN\9c<-\9b5"\93+%\8d*%\91/+\95/*\9821\924/\95<1¢NB¢RL\9aB6\9256\9198\95:8\8f++\8d,$\993:\9dB=\98C7¦UK£OF¦ZP¤\U~5,z* o&\eb"\1ab!\1f]#\18l&\1c\82:.\850(\831(~/&x)"v(!v+'o"\1do%\1ce\19\12m\1c\16q$\1c~*\1f\883+ªaK°qX¥_E QB\97<4\8d/#\8c-)\901'\8f1)\8e0'\8a,#\8e0&\902(\8e0&\89(#\935.\99@0\9dC2\9fE6¡L:\9dS=\869$\846 \808!i+\ f}I(\81K$\81L%|E$\89T.\8dW+\89V*\88^3\98k7¤x@Õ³xäÊ\94îÙ¡îáªíæ²ìé³ëë¸ëì¸êÕ\92Ú¡ZÂz9¢I\ e\92:\ 4§c!Ö©nîߪêðÄéîÄèîÅèîÆçîÉçîÊèîÊçîÉæîÌçîÊçîÊéîÈèîÉèîÉçîÉèîÈèîÈéîÇéîÇêíÄéîÄéîÄéîÄêíÁêíÂëíÀêîÂëíÀëí¿ëí¿ìì¾ìí»ììºììºìíºíì¹íë¸ìì¹ìì¹íë·îéµíè´îé³îä¬îã¨çÖ\99àÉ\8cÖ¹yÓ±mÞ½væË\86êÖ\97ìÜ¡îá«îå«îä®îäîå«îæ¬îã©îä©îåªîèîé¯îã¥îã¨ìé«ââíããâäéÍëÜ\9aéÙ\9aâÏ\8eÝÊ\8bÕÂ\80\86o2=!\ 2S0\ 3W1\ 4W0\ 5T/\ 5^:\vkQ\1d\8dtCqa4td5r_5ve7rb6\9f\8ddâÖ´àÖ¼âÚÀâÙÁãÚÂäÛÃåÜÄåÜÃçßÈêáÌëãÎi\1f\10e\19\11X\18\fP\18\fD\15\v,\ e\ 3&\r\ 3*\11\ 39\17\ 6\.\1c\88G;w2*t,#w0\1e\806+\8fJ8\8eG6\9bLD\9fG:\93H7\94G:\96D>\9eJ@¬`N¥[J\98I6\98E6\9eJ?\9cG5\90?,\98F;\94A7\96?3¦SD®_J\9fE9\990,\8d)\1e\83%\1d\86+%\8b1+\83)\1e\825#u'\1fm\1d\1a}-&\854/\94JA\9e^P\8cG@\89<6\94D8\97E6\95A-\95<2\979, H9²^M³\G´[I¥G.\9c=+\8d.\1d\8d,\1e\901$\901(\87*"\98=9^S·ia\96<,\96<4ª[Tºn_\9fI@¨PI¹je[W\8e;3\82?:f$\1cY\17\11L\12\11=\v\a7\b\ 36\b\ 44\ 6\ 34\ 6\ 34\ 5\ 46\a\ 3Q\19\15r&#v"\1et$#v$#l\18\15q#\1cq#\et&\1fh\1f\15g\1d\12k\1e\14y%\e\831 ¬`C¸}\µyY«fH\9bF5\904(\924)\8f1%\8f4(\8f2'\87+\1e\89-!\89-!\84'\1a\9571¤E7\9eI3¡J8\9aK7\90D4e(\16[\15
+[\10\ac\19\10`$\ ed:\19yL!\8b]0\8a[/\92e3\91f3\9brD\96rA\92l4\8fl1ΫoàÄ\87íÙ\9eíà¨íä¬íæ¯íè°ïâ¢Þ¢W³f\1f\99I\ e\8d4\0b\1dã·sîå©ëí½èîÅçîÇçîÇçîÈçîÇèîÊæîËèîÉèîÉçîÉèîÊçîÊèîÈçîÊçîËéîÇèîÇéîÈéîÆéîÇêîÂéîÃêîÄêîÂëîÀëíÀëíÀëí¿ìì½ìí¾ëì¾ììºììºíì¹ìë¹íë¸íë¸ìë¹íë·íë·íê¶íë³íé²îé³îçîç¬îæªîà£èÔ\92ãÆ\82Ó¬d¸\8cHÁ¡báÊ\89îá©îä±îá¬îâ«îä®îâ«îä«îä©îå©îçîä§íã¥íê¬ãäåãäÖãçÐëá£çÖ\94àÎ\8aÝÊ\8dáÐ\93\98\82FC-\ 2N5\ 5Z=\ 6W8\ 6X9\bQ7\ 5kV)\82n=we2r`4r`3n]/vc8¬\9dyãÖ»âÙ¾ÞÕ»ãÚÂäÚÂãÙÀåÜÄåÜÅåÜÅéáËêâËw0\1cc \149\r\ 2*\ f\ 3+\ f\ 24\16\ 4=\18\aC \r<\14\ 3E\1e\rY#\12v@2\81F<\98YC\8eN:\82<2\90L=\9dUK\90<+\97@-\90?0\96@8\95>1\9cG;©^M©^M¢PB I<\9aE1«`Q¥XJ\99F=\97F7\9fM?\9cIA¤NA\9d<.\8b*"\89)\e\8b1"\88*#\8d0$\96E1\94E6~'\1e\85)#\8a*(\9233\9dOD\9e^L\9dV@\96G;\91=.\96;,\9cD:\9a<4\99B7 M;§R<¯[FU@¨N6¥M5\9a>/\9a<)\9c<(\99@,¶kWÁugªUD¢P;®_L¸m[¦[K\90D6\88B9r-)U\14\13?\ 6\ 46\ 6\ 53\a\ 52\ 6\ 52\a\ 42\ 6\ 36\v\ 56\v\a2\b\ 4:\ e\b>\ e\a@\ e H\12
+V\19\12k#(b\19\17a# {31o\1e\1ak\18\17o\1d\19f\1c\10_\17\vk \11y'\1a\7f,\1e¢P@¶wY¸~]¹|\°rV§\J\8f7'\917(\906*\8a1"\87/"\87-&\87+!\89&\1d D?\9fD3\9aD1{+\17d \14L\r\ 4J\11\ 5U\10\ 5V\10\aV\12\ 4\%\fU(
+\84X(\8ba1\94g6\94f2\96m7\8ff3\8fg2\82^'pR\1e½\9adÞÀ\80ëÒ\94îݦíã¬îã«îè¬åÂz½s*\94?\ 3\861\ 2®e\1dà¹qíåªêî¾éîÁéîÅçîÇçîÈçîÇçîËçîËçîÊæîÌèîÉçîËçîÊæîÌçîËæîÍçîËéîÈèîÈèîÇèîÈéîÇéîÇêîÄëíÁêîÁëîÀìí¿ëí¾ëí¿ìí½ìì½ìí¾íë¸ìí»íë¸íë¸íì¹íê·ììºíë¸íê¶îé´íé³îé³íé°îè¯îç®îæ¬îä«îä©íÞ¡âÇ\86°\82>\80H\fº\8cFæÏ\8bíà£îãªîâ¨îâ¤íâ§íá©íá¥îä§îã§îã¥îä¦îå§ìë¯åì¿êí³íÚ\9aåÒ\91ÜÉ\86áÐ\91ÝÌ\8e«\95`N9\bgX\1dwd%^H\11L2\ 3W<\rqZ/vd7r`2ra4tb6tc5vc9¿´\92áÖ¼áÖ¼áØ¿äÛÂãÚÂåÜÄæÜÆäÛÆåÛÆêâÌêáÍS\1f\ 6D\13\ 38\ e\ 28\10\ 5R'\12V-\vS(\rS.\14O,\13K'\v^8 \9evX©ya nV\9cjN\86?5´oh\99RB\88:)\99B4\9aI9\94@7\93@/\9eL:¦ZCcN«bP¨]O¨`H\9bN>\9cH>£RA¡WC¡T>\95?5§VGTF\988-\938'\948)\925,\904-\918*\8f5*\8c3*\86,*\85%%\8b(&\93>1\96F>¡MB\9aA4\94?-\95B2\9dG:¬\M¦\H\9eL9\9eK9¢Q9 M5§Q9£P8\9a@4«PA¨D;\9f=5¥XF\9bMB\8c4$\9cWA\8cD7y* l\1e\14]\15\ eI\f E B\v ;\b\ 58\a\ 58\a\ 57\a\ 68 \ 58\b\ 55\a\ 68
+\ 65 \ 57\v\ 6D\ f\rD\10
+I\10\fN\10\vZ\16\12X\19\121\ 6\ 3R\1c\13q.!x**q#\1do"\17g\18\11i\1d\ eq \13p \15\8fA0±qS·\80]¹~]±wV³sX\9aR:\899(\8d5)\8a4'\8b3*\8a1%\8c-!\956+\97A5\87?$s+\1fX\13\vG\12\ 5I\ f\ 4I\11\ 3W\16\bU\14\ 5`!\ eZ(\ fL\1f\ 3\8d^1\92f3\94h4\92e3\99n8\96l7\91k3\8aa)\89d.¨\83KÙµuäÈ\87íØ\9eîߦíã«ê×\97Ê\90I\8f=\ 3~+\ 3\9bT\14ݳlìã£ìí½éîÃèîÃéîÅèîÆçîÈæîÉçîÉçîËæîÌçîÊçîÊçîÌæîÍåîÏåîÎæîÎæîÎèîËèîÉéîÇêîÆéîÆêîÄëíÂêîÁêîÁëí¾ëíÀìí¾ìì¼íì»ìì½ììºíì»ììºíë¸ìì¹íê¶íë¸íê·îêµîë²íë´îè¯íé±íè¯îæîè®íç¯îæîå«îãªíÝ¡ÙÄ\7f e½\9aWÙ¿yçÒ\8fëÛ\9dîà£íß¡îá¥îá¥íâ¤îã¥îä§îã¤íà¢îä¥îå¦ìë°îé¨ìÚ\99âÎ\8fÜÊ\88àÎ\8fÞÍ\8e¬\96^</\ 3H9\ 5\?\bX0\ 4Z2\ 6eE\1cua2r`0ud6tc5t`8s\0xe:ù\99âÙÀßÖ½ãÚÂåÜÇãÚÂãÚÃæÝÈèßÊæÝÈèàËêâÌ_3\12^0\12e9\18R#\bg4\18f9\16f8\16i=\1ce9\1cuN5£\83j¸\91o¬{\±\7fe¥hR\97I?\9fVK\835 \8b=*§WC£NF\9aI;\96H<\94C4¤ZA«]F U?©^KcL©^J\9fM=\9dK:\9cF:\98E2¤V@µpW¨cD\9cH/\9aC.\989)\99<-\8f. \96;-\94:+\98?3\92:0\9090\8a/\1f\8e3&\98C>\94;:\8d.#\95<,£R;\9cH8\9a@6\8c5\1c\909#£P=®\@¨M4®UC§P=\98=.\946/\8a'$~"\1ct\1f\17Y\17
+^\1a\14c\19\10]\11\b`\14\f_\16\ e[\15\ fN\f Q\12\ eO\11\ fC\ f\v; \ 5;\b\ 58 \ 5<\r\a;\v\ 69 \ 58\b\ 48
+\ 5;
+\ 6@\f C\10\fF\10\vG\ f\vU\12\13c\e\143
+\ 3" \ 3:\e\ f{4)z. t&\1at'\1cu)\1am \10n!\10}-\18\8b@&\9bR6\9bN3\9dO5«eJ§cG\90?)\8d4&\8b2&\8a3)\8a0&\918+\97>3q.\13@\1a\ 48\11\ 2:\13\ 39\11\ 3;\11\ 3=\13\ 3F\16\ 4O\19\ 6S\1c\bH\1c\ 3T+\ 5\7fP\1e\8a\#\90_)\94k8\95j/\94h/\97k1\98l,\97k0¥{<Ê©dßÁ|êÑ\93îÚ îݢߺv\9dN\ ex&\ 3\825\ 2»\89EëÜ\9eëì¼êîÁéíÀèîÀèîÂèîÆèîÇçîÉæîÉæîËèîÊçîÊæîÌæîÎåîÎäîÐãíÓåîÎäíÑåîÏèîÊèîÈèîÈêîÅêíÁêîÁìí¾ìì¾ëí¿ìì½ìì»íë¸íë¼íëºíë¹íë·íê·íë¸îêµîé´íê¶îé³íêµíé³íé°îç®îæîæíç®îæîç®îå©îå¬îã¨îä¨íÞ¡åÑ\93ãÏ\8fÞÇ\84Ò¹tÔ¸sçÒ\93ìÝ\9fîá¤îä§îä¦îä¦íä§îá£íà¡îâ¤îâ£îå¦íß\9eéØ\97ßÎ\8dÜÊ\89ÝÌ\8fßÎ\90\9a\86L1!\ 1A(\ 4X2\aX0\ 6[/\ 6bC\13ta3p_2ta6ud8q`2q_2s`5\97\8cjÜÓ´áؽà׿ãÚÅåÜÆãÚÄãÚÄçÞÉêáÌëâÍêâÍS)\vX1\14Y.\10c6\14f8\19e:\15h9\15wI(\80S2\87^>¶\92wzQ7\8aZ=\96`?¥eQ\92?:\8d;3\97G<¥[J¨YB£Q>¢P?\96E6\90@2\8d7#\958'\95>2\9bF6\97F3\93?3\91=&\95>(\98B.¢I5¤S=³nU¿~g²mQ\8c@%\947.\94?(\9bH2\8e4(\9bA6\938,\917' PC\896)\8e7-\98D:\9bI;\8e1-\916&\8d9%\8b6#\94:5\95?,\94A.\95H3\88<*~-\18\831\1d\8c<&\97D/\979/\8a+\1c\7f$\17\831)@\10\ 41\v\ 3H\14
+]\1c\10a\1c\ fY\16\vY\13\vU\12\fW\13\ fL\f\aC\r ;\b\ 5>\v\ 6?\v\b?\f\b=\v\a;\v\ 6>\ e\b@\r\aB\ e\a?\f @\f @\f\bH\ e
+g%\1f{/,@\f $
+\ 3%\r\ 3?\17\r`(\1a\84;1\879,\827)x(\19x'\13z(\17|*\e~,\e~)\14\7f,\1a\8d<(\93C-\92;,\91:.\919,\8f:*\95@4\98G2\805'A\14\ 31\11\ 35\14\ 36\15\ 36\14\ 31\11\ 35\13\ 3:\15\ 3L#\aV)\ae=\11mF\11pG\10wL\18|Q\19\88_*\96l3\95j/\94j2\96i.\9do1\9bo/¸\93RÓ±mìÏ\91îÖ\9bïÙ\9b·\8aFn'\ 1q(\ 3\9e_\1câÅ\84íé¸êí¿êîÂéîÃéîÃèíÃèîÅèîÇçîÈæîÊæîÊæîÌçîËæîÌåîÏäíÑäíÒäìØãìÙäìÕãíÖãíÔäíÑçîÌéîÇêîÄêîÃëí¿ìí¾íì¼íê¹íç°îè°îê¸îë¹îé·îé¶îè±îè²îè±îç³îé³îç²îæ±îç°îçîè¯îæîè¯îä«îæîå¬îæ«îä¨îå©îå«îãªîà¥îà¥éÙ\99×¾{³\8aAÂ\9aYáÊ\86îÝ\9eîã¥îã¥îä¦íà¢íà ìÝ\9díß\9fíß íÝ\9eéØ\94äÓ\90ßË\8bßÍ\8cÝÌ\8eÜÊ\8e\91{H-\18\ 1/\18\ 3>(\ 4C&\ 3H,\ 6aG\1a{i8we6sa3sb3r`4sa0p_2vi>ȼ\9cáؾâØÀâÙÃãÙÃãÚÃæÝÆæÜÅëâÍêâÍêâÍi;\19[2\17U.\ fN)\ 6R)\10M*\ e]6\18oE#sE$\85Z:¡\83^c>\17sB\e\84E"\94I2\90G8\8eG:\96H;\8fD-\8b1$\894'\914%\926)\98E3\928$\97<)¨ZJ¬^T\9cQ?¨`N\9eN7 L8\97E0\9eK3ªR>¡L6¤W@\9fZCx.\1al\1e\12\841 §S=\9bJ8\93F1\9dVG\92J?dR¢YE\98D;\92:2 K?¤ZG²jQ¯gOªbI\94H=q"\12^\12\ 5\\11\ 2X\11\ 3V\ f\ 3U\ e\ 2`\1c\vl%\ ey,\12\830\1a}%\15u$\112\ e\ 4\17\b\ 3 \b\ 30\v\ 4>\14\aI\19\ fP\18\11R\1a\10X\18\ fS\13\10H\ e\f@
+\aB\r B\v\bA\v\ 5?\r\a?\v\bR\17\ eY\1e\ eO\18\aF\10\aI\13
+[ \14k*\ex2"p+\16>\ f\a%
+\ 3)\11\ 4)\ e\ 45\ f\ 6u4&\94J<\8fC8\862)\81/\1e\80/"{+\1ev'\17u&\f{)\12})\11\883"\870\1c\92@*\8c@+\92@,\8fD3{< T\e ;\12\ 46\11\ 3;\14\ 3=\14\ 39\12\ 2?\1e\ 4I#\vS1\v^5\vj?\ fqG\18qH\14qJ\14sJ\16sF\14nC qJ\ f}V\1d\87^"\8aa$\88`"\8cb\1f\9cs3Ä¡[âÄ\83ìÒ\94çÏ\92\8a\#U\19\ 3x0\ 4Æ\9dZíß©ìë»ëí¾éíÂèîÅèîÃèîÄèîÅèîÆèîÆæîÊèîÉçîÊçîÊæîÍãíÑäíÒãëØãìØãìØãì×äêÜãëÚãìÖåîÏéïÅêëºíæ³ëÞ¤íÞ¤êÔ\96âÄ\82ßÁ\87ݽ}ß¿}àÄ\86âÄ\81çÊ\8bæÉ\8céÎ\90èÑ\95êÕ\9béÖ\9cëÙ\9dîà¡îߢíã¦îâ¦îâ§îä®îå¯îä©îç¬îä¨îã¨îãªîâ¨îâ§îá¨îã©íà¤éØ\9cÊ®n¨x5Ê XêÓ\90íÜ\9eíß¡ìÝ\9fìÜ\9eëÛ\9aìÞ\9eëÜ\9bêÙ\94çÖ\95çÕ\94âÑ\90ÜË\8aÝÌ\8bÛÊ\8aÓÃ\8d|f6'\14\ 1'\1a\ 30\1c\ 35!\ 38$\ 3`L ud3ud5s`4tb4xe9sc6vd9tb4\9d\8dhÝÔ¹âÙÀäÛÆäÛÄãÚÄæÞÈéâÍêáÍëãÍëãÎj?#`8\1f]3\10_3\ f[5\fY0\10a;\1a]5\ fP,\ 6yU.`@\17L)\ 5kB\1avD"t=\1er< \94^D\849.\8c:&\8c/\1c\8e4&\9bC8\95A7\95?0\96A4\92>2\92>3\93A-¡RB¢UD¨YB®[H«S?¡D7\9a3'\993(\9fC9\862+Y\e\113\ f\ 3Q\1a\v\94C.\859\1d\95\<Æ\96|¿\90{·za¯lNªaL¨XJ±bP\90L7\88@,\826(x,"a\17\r\\11\vX\16\bX\14\bU\12\ 5P\r\ 3T\12\ 3Y\17\a\\19
+^\e\vf!\ fr(\16v\1d\18:
+\ 3\16\a\ 3\18 \ 3\e \ 3\1f\b\ 3" \ 2)\v\ 30\10\ 5I\18
+Z\1a\14e"\e^\1e\11R\12\bV\17\12N\ e\ 6N\12\brA.}E3v9%n7'm2%j'\17k&\18s)\13\80@(e-\15
+\ 3\1a\f\ 3*\16\a< \r?\1f\ 6\81E+h/\18e-\ey6 \819!\85:\1e\815\e\87;+\817\1e\7f0\15\89;#\8d>&\8b7 \99U;\91V9|? _+\fM\1d\ 3F\1a\ 5?\18\ 2?\19\ 2L$\bX-\va3\f^1\v\1\a`9\rb9\bd: pH\18qH\14oJ\15wQ\1cyP\epG\rnH\ euN\10}T\18}U\1ayR\13|V\14{V\17\9e|>Ô³xåÈ\8eÞ¿\7fpE\rM\17\ 2\8aR åÉ\91íè·ìë¹ëí»ëí»éîÂêìÁèîÄèîÄçîÅèîÅéîÅèîÇèîÅçîÈæîÍæîÍäìÔåíÓãíÖäì×ãëÚãëÚæëÈìç¸ìØ¢æÆ\88ßµuÝ©lÒ\97\¿\88H¿\83F²p3¯t0°u5µx5³x5¸{9Ã\86DÁ\87G¼\82EÀ\87JÄ\8cJÆ\92PÏ\97TÊ\97SΧaѱjáÄ\83æÍ\88éÕ\97íÞ£íÜ¢îã¤íâ£îá¥íß¡îâ¥îâ¦îß¡îá¤íÞ¡íÝ¡åÒ\95ͯkË©aâÇ\80êÖ\96íÜ\9eìÛ\9dëÚ\9aìÛ\9dêØ\98é×\97èÖ\94ãÒ\90âÑ\91ßÎ\8eÚÉ\87ÜË\8aÛÉ\8eÌ·\83mS )\16\ 2+\1a\ 32\1d\ 31\1e\ 38%\ 3eR'pa/o_4r`3ue7xh<wf;uc8ue7\90\81YÝÔ½á׿ãÚÅãÚÅãÚÅèàÊéáÌéáÌêáÌëãÍX6\16X6\16X1\ eV. e<\16pD\1cuJ)qE\1dmD\1f`>\15U4\rS1\vS2\vU2\12S/\ eV.\14e:\e|B-\8a='\8f8"\96H1\98G0§]G\98H1\9eL5\96G5~-$\93@+\9aM6¡P<\9dK6£R>£R>\9b>5 ?8¦K?\98@1|#\192 \ 2$\r\ 3>\15\ 4S\1e\ 49\10\ 2@\17\ 4yL.¤wT¥rV\8bO2\8eK4z1!l$\12g\1f\ri \ fd\1a\ fY\14 W\15\vT\10\ 6X\13\b[\17\v[\16\f[\16\f[\e\bX\17\ 4Y\16\ 6[\e\vW\16\b\\1a
+t)\18A\v\ 4\1e \ 3 \ 6\ 3\1f\b\ 3'
+\ 3%\f\ 3,\ f\ 3'\ e\ 35\ f\ 4I\13\vZ\1a\ eg'\12z4%t,#k#\1cs,\18\9bdD\9b^G\95M8\9dTF\8a>&|0#\835*\91?/w:%>\14\a \ e\ 3\1f\ e\ 32\e\ 68\1d\ 5C$\vc0\1aI!
+4\12\ 39\13\ 3O\1d\aS&\v^-\ en1\16r4\19s3\18\86B%y9\1ej0\13r9!`1\16U' Z. d5\14^1\ e`6\10f9\12j;\15k=\17o@\17o=\17rB\17q?\13sC\17zH\eyL yL\19zL\17\83Y\1d}S\14xO\13{Q\10{R\11{Q\12}U\15}V\15|V\14sJ
+{W\18½\99_àÂ\82ÏhZ4\ 5U&\0·\8cRíØ\9cîè´ìê·ëí»ìì¹êíÁéîÂêíÂèîÅèîÄèîÅèîÅéîÅéîÈèîÉæîÌåîÎäíÏãíÓæîÍèíÉéæ´ìÕ\9eäµ|É\8cQÆ\88PÒ\96[סgÙ§pÙ§nÔ¨rͤfΤgÒlάkϯtÔ®nÖ±qØ´tÔ¯nЧdÏ¢dÈ\9bXÇ\9abÅ\91Y¶y8¥m+±u6²q0x1¿\8aFÍ¥dÜ¿yáÊ\86êÕ\93íÜ¡íß îß îÞ¢îߢîâ£íߢíÞ ìÛ\9déÕ\96ãÑ\91èÐ\8aéÔ\94èÔ\95ëØ\97ë×\96éÖ\99êÖ\98æÔ\93æÔ\93äÒ\90áÐ\91ÜÊ\8bÙÈ\86ÙÇ\89ÖÅ\86µ\9feP;\v/\1d\ 38\1d\ 3; \ 3: \ 3=&\ 5p]3m_.m\1sb4uc5td8tc8vc:ua7\8d\81WÙдâÙÂãÙÄäÛÆæÞÉæÝÈéáËéáËêâÎéâÍV6\12U6\13T2\ eL*\ 4P1\aK,\aQ0 _;\13^8\14X6\rW5\11V3\ fV4\ fX6\13Y7\13W3\17b7\14`2\14\%\11W \rd-\12t8\1dz9$\86:"\8d9 \820"\844"\876%\833)|, },\1dw \17r"\19~0\1e\93@&¥V>\8eB)Z\18\v.\f\ 3)\14\ 3J\1e\bY"\a[$ 9\10\ 3:\12\ 2F\17\ 6F\16\ 6C\11\ 3B\12\ 4L\18\aP\16
+W\19\a[\19 X\15\bT\14\ 5R\11\ 4d \rf\1f\10_\16\va\1c\11j\1f\15o*\10j+\f^\17\b^\16\ 5\\16\aX\15\ 6p*\19M\1c\f(\f\ 3D\1c\fQ\1c\b\+\14P$
+<\15\ 3<\15\ 3L\1c\ 6R\1d\fN\15\ 6Q\19\ 4c%\ e{6)\80=/\84B*£[B\9aR5\95B-\94D.\92E(\8c?-\87?.m)\15N\19\ 4P&\vI"\aD$\ 5? \ 49\1d\ 5?"\aA&\bE$\b-\15\ 3*\16\ 3/\17\ 32\16\ 3:\1c\ 4F#\ 4@\1c\ 2E \ 3M$\ 3L$\ 5N'
+V,\ eS)\vZ1\11b7\11o?!n@\euH#wJ&wG\1fr@\1arA\17yJ!~N$\80P"\84S(\81O"\7fQ \7fO!\87X"\95e%\95h(\92f&\94g*\85X\15\88\\1d\87]\1a\86[\18\83[\17\7fX\14vO \9cu2ͩg˪fg9
+vD\16×¹\80ïà¦îå°íé´íë·ëë¼ëí»êí¼êí¿êí¿éîÂéíÂèîÂéîÄéîÄèîÈçîÊçîËèïËëé¹îÙ\98å¹xØ\97XÇ~CÑ\92\åÑ£ëáºëäºëêÅíè½ìéºíæ¶ìâ¯íâ«íá¬íà«íâªîâ¬îá¦ìߧíà¦íÞ¤ìÛ¡éÙ\9cèØ\9dãÏ\96ÝÄ\84Õ´vË£cÆ\9c[¸\8fL°\80A§r2v.¸\80;Â\8fNЪkâÂ}êÑ\8eìÚ\9cìÜ\9díÛ\9dìÞ\9eìÜ\9fìÛ\9dîÝ êØ\99ê×\96éÕ\97âÐ\8eáÉ\86éÓ\91êÖ\99äÒ\8eæÔ\94äÓ\91àÎ\8cßÍ\8b×Æ\84ÕÂ\80ÔÂ\82Ò¿\84\8ezC0%\ 2*\18\ 3>"\ 3B$\ 4@&\ 5N6\14vc=m^.l]0yg:wf8wh<ve9we;xf?}oMÉ¿¥ßÖÀãÚÄäÚÅåÞÈåÝÈçßÊëãÎèàËéáÌS6\ fV8\12V4\ fN+\aD&\ 3H,\ 6U6\ eV6\rX8\ eY7\10Z6\ fcA\19h@\1dg?\1ab=\19e; j?\1dpA\1fh=\19T0\10K*\rE\e\ 5E\13\ 3l1\15w5\18r*\19t/\1ae\1f\ fj \14w*\1d\803$q"\18h\e\13e\17\rg\1d\f\8c=0v+\15>\10\ 3/\10\ 38\15\ 2\-\vb,\10Y%\ eL\1c\ 4L\1d\ 3N\1c\ 4@\12\ 36\ f\ 34\ e\ 37\ e\ 3<\ e\ 3@\10\ 3?\r\ 4F\14\ 5S\17\a[\1c\vf \rk#\ ej\1f\12m\1d\vz/\16\85<\1e\88G'v,\15u#\10p \11q"\ f\800&R\1d\ f/\f\ 4R" ^#\ 4a&\ba)\b]'\b^(\ eY%\ 6W" T \ 6Y \ 4[!\aW\1f\ 4e(\12n/\12\80:\1a{9\1c\80;\1e\8dI&\89I \82C\1f{>\1a{?\1a\80H!\83K!~E\eh7\ ea3\vU/\fR.\fH&\b?\1f\a0\1c\ 4@' 8\1d\ 4<#\ 4B(\bI, I- H- K/\vK+ K+ M/\vQ1\vY5\15_7\ fmD\1fpD tH#xI&yL$wH\1fzH\e}Q'\80U(\80U%\84V$~P\1d\82T \85X"\8ea%\96e&\99i)\98j-\9eq5\9bo6\9eq2\97j+\95j,\94h)\8fc$\83\\17\85Z\18µ\8fKâa\91f-\85IäÎ\8fîÝ¥îä±îçµíê¶ìê»ëì»ììºêí¾ëíÃëíÀìë·êí½êíÁêîÀêîÃëìÀìç±îÐ\92ä®jÏ\90HÕ\94Oá±uìä·äéßããíãâîããíãèáèíÔêîÉëîÃíì¼îê¹íê¸îé¶îç²îæ°îç°îäîæ¬îæ«îâ§îãªîã©îäïá©ìݦìÜ\9fçÖ\9bãÏ\94àÈ\89Ô¶rÅ \\85<©s-¦n%³z5Ç\8fIÓ¬dÞÅ\83éÕ\97ëÚ\9bìÛ\9dìÛ\9fìÛ\9fêÙ\9bêÙ\9aé×\97ãÏ\8eжkâÅ\7fãÐ\88åÓ\91äÓ\94áÎ\8cáÎ\8cÕÃ\80ÔÄ\81п|ν}¼§o`L\1c&\1a\ 2*\17\ 3E*\ 5I)\bF(\ 6X@\1as`9iZ.m\/p_1td6xi>vh9{j?}kG¢\95xÙиà׿áÙÃâÚÄåÝÇãÜÆäÝÇçßÊêâÍêäÏU9\ eZ<\12U7\ fS5\ fN1
+V6\11O1\vO4\rS4\fX5\f[8\11W6\rU3
+U2 \9\13[2\17W2\11T/\10Y2\10]5\15c9\17e:\1aa5\13f5\12g3\12d'\13yA&p;\1di&\11m'\12b\e\vZ\17 \\14 t$\1dt(\1e\87D7N\1e\r5\11\ 34\11\ 2_3\15uB wD&v@"n6\10s6\10h-\ 5^$\bM\1d\ 5E\15\ 2G\e\ 3K\1a\ 5L\19\ 4M\e\ 4N\1d T\1f\ 6a&\10o+\12y/\1az-\ez*\16\86;&\9aR3 _@\8a;\1f\85&\13\81"\18\84*\16z%\19M\12\ 5R\17\ 5|?\1dv9\14t5\12o0\fk1\vf- h/\vi/\fi2\ f\)\a[%\ 6^+\bi4\14`(\ag.\vf.\fk4\10zF\1a\80P ~P#\8dX+\92X,\8dR$\8dR$\8aM#\85K \82G\ev@\15sA\16nB\ee<\14[9\12W3
+W3\rL-
+G,\aG+\ 6H-\bI0
+E*\ 5G-\aH.\aI.\bM2\bT4\ eT5\vT8\rX6\ eZ7\ ekC\1cmG\1ezO)tL$wO#{Q\1f{P }R"\83U\1e\87Z&\8a`#\92i-\96i*\90d#\97k.\9cl1\9dp8\9bj)\9eq2\9er3\9dr2\98n-\97l.\8fb%\90f(º\98^Á\9ebϲsæÏ\92îÚ îà©íãíç²íé¹ìë¼ìë¼ëì¾ëëÀêÔ\98ãºwíÒ\91ëå¬êîºìê·ìÛ\9aå¶iÕ\8eCÙ\92Jä¸uîÛ ëîÅããìããîããäããéããëåëÙéíÎëë¿ìæ³îç°íãªíäªïæ«îä¨îåîå¬îåîçîäªîæîå«îã©îä©îä«îä©íâ§îâ§íߤíߥêÙ\9båÔ\95ßÊ\8aѸuɪf¿\98U±}7¨n'®\80?Ê\9f_ؾwâÎ\8cëØ\9fêØ\9bé×\97é×\98èÕ\95åÒ\92вlÇ\9eVÜÄ\81áÐ\92ßÎ\91ÜË\8aÖÅ\83ÒÁ\7fνyͺ}Á¬r\95\7fAV@\v2#\ 34\1e\ 3K.\ 5V2\fN0\v_G\19p_1k]-o_1sa5tb4wg;zj;\87wO¯¤\84ÙÏ´ßÖ½à׿áØÂáÚÄâÚÅãÛÅâÚÆæßËçàËéáÍkJ\17aC\fY<
+V:\vU4\bY;\11Q2 T6\fZ5
+lB\17cC\1fU:\13R0\vS1\vW5\10T1\12U5\14U7\15S0\rT1\11b7\1ac5\12d9\14g7\13_,\bZ'\b^.\12^,\ ej1\18g+\16g(\13b#\fk"\12\8a>2\8eF9Z#\176\10\ 29\13\ 4A\18\ 6p<\1e|F$\83K(\8aL(\86K \7fA\18~>\14x9\11r:\16n6\10h2\rf/\f_( Z\1f\ 3_$\vV \a]!\bd$\rh*\10h+\rk-\ fp/\13q0\11q0\14f%\rd%\ ea#\vf$\ 6e"\ 6a&\bx9\13\89B\1c\8eF!\8cE\1d\89B\19\87C\17\8bI\1c\89E\18\87G\18\84D\15q4\fb+\ 6[*\ 5_+\af2\bb1\bf6\fe6\rb4 W,\ 3^3\ 6d6
+l<\ f}G\17\7fK\1c\82L\1f\86P&\82M\1f\84K {I\19}L |G\1cvB\16oA\11oD\19pG#lE d;\11a5\bX6\aZ4\r[5\vQ6\bO3\aU7\ eY7\fU8\fO5\bS:\ eP2 [;\17Z8\11a=\15c=\17iC\13nF\16{S \81Y'\86^#\8aa)\8ef-\94k1\98j,\97k*\97l1\9aj.\96i*\9bn, s3\98l*\9bp.\9ft2\9an-\92e \83Y\18\9bu;½ _Õ»\80çË\8eì×\9eíݧîâ¬îæ±íç·ìêºíëºìë¸íê·çË\8eÎ\9aTÙ§]ëÌ\83îÙ\91éÌ}ܪWÎ\884â¯dëÎ\8bìç®ëíÂéîÍãëÛäçàãçáæêÔéß°åØ©Ú¸}Ø®pÈ\9e_Ë\9c]É ^ʦhÑ·uÝÃ}èÌ\8eèÖ\98ìÞ¡îá¥îå¬îå©îã¬îå¬îãªîä«îå¬îã¨îâ§íà¥îá¦íà¦íߣëÜ\9féØ\9fæÔ\97ßÎ\8d϶w¿\9aS¦s6\9ce%¦u1º\94LÑ´qÞÊ\8aåÓ\93æÕ\95èÔ\95éØ\96ÙÅ\7f°\88<À¡_×Å\8cÕÅ\85Ô¿|Ò¿~ϼ{ɵyÀ¬l¬\97ZsV\1e\8am5@'\ 59"\ 3O/\ 6W7\13Z@\14iR#jZ*iZ+l[.q`/we5vh4\93\81XÒÆ£ÞÓµÝÔºàÖ½ßÖ½à׿ãÚÃáÙÃáÙÄáÚÅäÜÉæßÉéáÎ\89\!\80Y\1e\83`&\88a'\85Z\1evJ\13pJ\19^<\ fZ8 oG!gF\e[>\14Z8\11a@\19U5\13N.\11N5\13Q6\12[9\17\<\19h?\1ej?\1ak@\13l@\15_5\vX,\a[.\ fV)
+a/\ra.\10e/\15m4\17s4\1a|='\'\ f7\r\ 27\r\ 3;\ f\ 3I \aj:\eh9\18yF%\7fG%~C\1a~D\18}E\1e\82F\1a{<\12}:\11\80?\16\80A\16}>\16\80A\18q2\ ff-\va&\ 6_%\b_&\aV \ 2U$\ 3J\18\ 2L\e\ 2T$\ 4Q\1e\ 3M\1f\ 4Q!\ 5`(\b]$\ 5]'\ 6g0 p6\ f}B\18\87K\1c\8aK\e\8eN\1d\8eM\e\90M\1c\8eM\1e\92Q\1f\92R \87G\15~D\12zC\15w@\10o<\rm;\ fc3\ab5\a\1\ 5X.\ 3Y,\ 6]2\v\0\bY2\aU1\a]5\b`9\bmA\11uF\18{K$\85T,\89V(\80N\1f~N#\8aX.\84S*~M!\80Q!}O\1d~Q%vJ\1amF\14nI\17oK\1df>\14b@\15T4\bV8\ f_?\16Y8\ eR3
+X8\r`>\11^>\11fC\14pJ\1csL\enH\14tM\17\89b1\82^*\8dd+\8ed)\8ed,\8da(\8aa)\93e+\96p3\93m,\8fg$\96k*\96k+\90h'\8bf#\8dd'§\83CΫlàÀ\82éÒ\98ìØ î߬îã±îå´íè¸íé·ìë·íê¶îâ«éÕ\99éÏ\87çÉzà³dÛ\9cHË\80)Ö\94?çÌ{îá¡íä«êߣêÖ\9cèÌ\8båÀ\81Û«kÈ\89LÃ\9apæÕ\90Q\1a|5\bq.\ 5x4\ 6s8 {>\f\85P\15\97e'±v:»\89IÈ\9d]Ú³pæÊ\88éÕ\96êÛ\9cîâ¬îãíá©îâªîá©îã«íà¤íà¤íߣíÞ£íߣìÝ¡êÛ\9fêÙ\9eéØ\9bÚÈ\8aÒ´v»\97\¢o.\8cY\16\90c#°\8dIØÂ\82âÑ\8eçÕ\95éÖ\98ãÐ\8e¼ V¦\89HÁ®rκ|ѺvȳqdzpÀªt°\9aa\80j.vZ&\8bs;:$\ 1V5\ 5\6\ 6_>\11kN\eva-m['hY'm]+sa0ve6ylA\9d\91mÛÒ°ÞÖ¹à×½ßÖ¼áØ¿àÙÁàÙÁáØÂãÚÅäÜÇæÞËäÜÇçàË\95e$\87Z\1a\92`#\8e_!\90h(\90c%\8eb(\93e0\88^(\7fZ&~V#xR"hB\ f[9\vU5\10_B\1fkI gC\19[9\f`=\13b:\13h@\16oE\1atI\1drG\1ap@\17m?\15j?\19i8\ fh6\12e1\16c1\15Z(\fO\1e\b;\15\ 26\13\ 3B\1c\ 3G\1f\ 3T.\bj@\19i>\el@\evD"sD\17`5\ fc6\13zE\19\8bO#\8aG!\86D\1e\85C\1a\86F\1d~@\14|@\15|A\13\83H \84C\e|>\16w9\15f-\ 5^+\ 5N!\ 2S$\ 4U%\ 6R%\ 6X) X*\bP"\ 4O\1f\ 3W+\aX-\a].\ 6e3\ap9\v\82E\14\89O\1a\87O\18\8dQ\e\8fR\e\94U!\96T\1f\95T#\88L\1a\87N\18\86N\16~H\15|H\14vC\10g7\ 6b3\ 6`.\ 5[6 Q/\ 4N,\ 4I+\ 3T/\ 6Z3\ 6`8
+j=\14k9\15c;\11b;
+qA\15uH\18\89X'\83S\1f\86V'\88U'\8a[(\8cY'}P\19\84W$\85Z*\83Z'\7fS#xN\1doI\16mF\16uM\1fc?\v`@\10cB\13bA\ f_?\12kI\1clI\1alG\16fD\11dB\fnI\13oH\14qK\16xQ\1c\7fY#yR\1a{U\1a\8aa*\93l0\8fg*\90f&\93k*\8fh'\8eg&\90e%\85^\1a\8ab"´\8ePÒ±vàÈ\88éÑ\93ì× îݧîã¯îå¯íç®íé³íê´íé²îç°íÝ\9bߺfÊ\8a;Áx$¹k\rÄ|"اSÚ¯f×£]Ê\96LÄ\85>¹o1³f&¨Y\1e\9bS\18µ\7fPàÃ\90|< u4
+f.\ 4Z+\ 5X%\ 1_%\ 1c#\0`#\ 1i(\0w3\ 6\89C\12\96W\18r4»\8cGȤ\Ý¿\7fäÐ\8dìÚ\9bëÜ\9eìÞ¤íݦíÞ§íߥíߣìÜ ìÝ¡ìÜ¡ëÜ¡ìÛ êØ\9fèÖ\9fãÓ\92ÚÈ\87еt§\8aDmA lA\b¦\84DÕÄ\89áÓ\9bäÒ\96ÝÉ\88͸s§\8aH\9c\82=¶ aɳ{Ä°o¹¥h¬\92X\92zES7\vy`0\G\1aD+\ 3fA\11mE\1ciE\1cqQ#q[,iU#m[*n\(rb/uf8zkG°¤\82ßÔ¹ÞÕºÞÕ¼ÞÔ»âÙÁãÙÃáÙÁßÕ¿âÙÃâÙÃçÞÉåÜÇæÝȺ\91L±\8cG¢{;\90e+\8be%\8ac&\8da&\93f+\96i,\93l.\9eq<\9duC\95k6\88`){V$uP\1d}S&qJ\1d^@\10dA\15qH\1elB\1arK\1dnG\19g=\ fj<\13oD\12oE\12wJ\19}K\18sC\13i?\17g:\10f9\13_6\ eW1\a[1
+U-\bQ+\ 6Z1 g=\12l@\15i9\14c9\ ec:\10f7\10yF\exC\16\85J#\80H\1dzE\eyE\19zB\14~D\17\8bL\1f\8aO!\8eN\1d\8eO\1e\8eN \88H\15\8bK\1a\81D\10yA\11s;\ fe1\ 6^*\ 6Q"\ 3K\1d\ 4D\e\ 3;!\ 3@&\ 3H(\ 4K,\ 3O-\ 3Y2\ 4]3\ 5d9
+t>\vu>\v~I\12\86N\13\8bP\1e\88O\1a\8aT\1c\83M\12\80J\15~H\ f\7fJ\15|H\17\81K\19{E\11k=\ 5_9\ 6W0\ 4V/\ 3Z2\ 4]6\ 5f=\rn>\ ff:\f[1\ 5V+\ 3W/\ 3`7\va;\ f]4\alB\12|K\18|L\17\89X#\8b[-\8e_,\8c[*\8aX(\85U!\7fQ\1f\85Y#\85Y(\81U#wL\17vM\17vK\16nI\11gB\rdA\rb@\11_=\vgE\12uS\ejH\13kG\12nI\14sO\19sL\16lB sL\r\7fW\19\84[\1d\83Z\1c\87]\1c\95j)\91j)\8eg&\8ce#\8ef&\8fh'\92k1¸\95\ϱpáÄ\84æÎ\90íØ¡îÛ îáªîä§íçîæîåªîß âÂrÇ\886¼i\18ªV \\v¬[
+®`\ f¯a\17«[\f«\\11¯e\1dºx<Æ\91RÕ©kÖ²vÒ®x̦u˦pÄ h³\96\®\8aUª\86T\9fyA\9fo:\90c%\87V\1d\84N\12\7f@\f\82B\ 6~3\ 2\809\ 2\91O\f¨e\1eº\88?Ыg×¼uäÐ\91èÖ\96éÙ\9bêÛ\9fìÛ£ëÜ ëÛ êÛ\9eéÙ\9cêÚ\9eéØ\9aèØ\9bæÔ\97àÎ\8eßÏ\8e̵q\91u<W5\ 4gF\11¿¦hÛÌ\93ÙÈ\8dÒ¿\81˶t\95O\8el*£\84C»¤g±\9ca¦\8fX\83o9L7\aC/\ 4I5\bB(\ 2hA\16sE\eiC\17lF\1eiO"nX'gT"iX(r\(p]-uf8{lB¾²\8eÛÓ´à×»ßÖ¼áؾâÙÀâÙÁáØ¿ãÛÃâÙÄâÙÃãÚÅåÛÆãÚÅÅ\98OÈ\9eXÆ cÃ\9a^Â\9aV»\95W´\91S¥\80B\97m+\94l(\9fv=\9fxA¢vA¤w=\9am1\99l4\99l3\96l4\84_-\81Y(\81T%\7fS$~V&}V&vO\1dmI\17lK\18mE\rlB\r{O\1cyJ\19f?\11xL\19~Q\1epB\19mC\19i>\10mC\15f@\ ff>\ fd9\va7\fY1\ 5\6\f]4
+a6\vc7\v_4\fZ2 Z3
+X-\ 2]-\ 3r?\r~D\17\80G\e\86P\1a\93S!\97W&\96U!\96R\19\9cW \9cU\1c\97V\1d\97W!\93U \94W\1e\90Y*\83J\1cv@\10d8\ eX,\ 6W/\bQ*\ 2E$\ 3D\1f\ 3G\1f\ 3L'\ 3I\1d\ 3G!\ 3M%\ 3Q%\ 3Y1\ 4b4\ 5b5\ 6f8\ 5sA
+~I\ f\7fO\19\8cX"\8dV \87R\e\83O\13\86S\1c\81N\esD sF\10i=\ 5h>
+j:\vh; ]2\ 5Z.\ 4[0\ 5[0\ 5]6
+^5\ba8 d;\vd;\bi<\vm@\14wJ\17\82T\1e\82S\e\84V\1e\85U\1c\87X \86U!\85T \86U!\84S \81R!\86W#xJ\13tJ\11qH\ fkC\vqJ\11tO\13yR\19|U\1avR\19yS\eqI\vgC oN\10wR\14xS\13xS\r~X\16\81[\1d\82Z\19\88a\1f\8bb$\8de'\8bd"|X\1e|[\1cµ\93PÓ´vÝÂ\83åÍ\8fìÕ\96îÛ\9eîá£îãªîä«íÞ\9cãÀuÈ\8d<¯a\ f¥K\ 4\9bB\ 3 H\ 2\97N\ 1¦b\11·t%Å\8d=Ф_سsãÌ\8eêØ ìÞ§íá¬íáîà®ëݨìÝ©çÔ¢èÔ\9eâÌ\96ÜÉ\90ÞÇ\90Ô½\82ηyȬi¡]º\98V¥y0 f(\8eM\v\8fJ\a\91H\ 5¡\\18¶u-Ä\93KѨ`Û¼wâÊ\86áÎ\90ãÒ\94é×\9béØ\9céØ\9eçÖ\9aæÕ\99çÕ\9båÔ\98àÏ\8fßÏ\8eÚÆ\87¹¤k~d$~d&µ\9e\н\7fʵ{ʶxDZr¸¥e\8cl-\8dj/¢\8dO\9f\8bR\82j5L<\ f+\1d\ 32%\ 3C.\ 6d=\vyJ\1ayI\19zM\1d\81`5u^0mZ,hW&hW'lY)p_1vd7zm?ËÁ\9aàÕ·ÜÔ´ßÖ½âØÀâÚÁâÙÁãÙÁäÛÇâÙÁáØÂãÙÅãÙÈâÙÃÁ\97KÆ\9dW̤^Ï«lÑ°lÒ²kØ»sÚ»xѬfÆ\9fY½\98Q´\92Nª\86C\9er.\97e#\8d^#\98g(¤q/¤r6¢p3\9fl.\9ah'\91b \8aY\1a\84X\19|R\19eB\fiC f>
+nF\11rH\16j=\14nC\12}R\1fwL\1apG\14oH\14rI\16tK\19mF\1amF\16i@\11a: X3 W4
+Y3 W2\aU0\ 6L+\ 4B%\ 3M.\ 4\4
+h;\ fe4
+l=\11vF\11v@\vr=\10{B\14w@\a\89M\14\92R \92V%\97\)\9dd- h2\9ff5¤g8\9f`+\97W\1d\91S\1e\91T\1f\8dT\1d\7fI\13r9\ap=\ 6p>
+k=\ 5^3\ 3c8\ 6b5\ 4b8\ 6i;
+c3\ 5Z-\ 5_3\ 3k: q?\ fyG\13\85O\18\89R\1c\85O\13\8dV\1e\8bU\e\83O\15\7fK\13yG\13vB\10vE\14yH\17xF\18sC\12j; `4\ 6i=\11i>\rh9\be9\aa6\ 4b6\ 5a:\amC\ elA\rmE\10lC\rmC\fvI\17zN\1czQ\1c\80T\1e\8a\&\89_'\8d^+\89Y%\89Z"\88\\1d\82W\19\80X\1e{P\16\82U\18\88^#\83\$\87^&\80X\1dvN\10wQ\14~Z%yU\1avR\15\80[!\7fZ\1f\82^!\87a&\84^$\84^'\7fY\17wO\10[7\ 4pP\18²\94\Ì®lÞÅ\84æÍ\8fêÕ\99íݧîߥíÜ\9dâÂwÍ\97S¯i#\96H\ 2\97A\ 2¡T
+¹y2É\99SÖ´râÅ}èÑ\8cëÚ\9cìá¬îä¬îè¶îèµíè¸îæ´îæ´îæ·îåµîä´îå³îâ°íߪîß©ìܦíÞ¦êÚ¢æÕ\99âÐ\92ÜÇ\88ÓºxÇ©c¾\9bUµ\83F¥n*\99U\10\9eW\13ªf%³|5½\8fKÄ [Ò²tÞÃ\85åÓ\9bæÓ\9båÕ\9dåÔ\9aäÒ\98âÑ\98âÏ\92ßË\8cÛÈ\88ÕÁ\8cÀ¨n¶¢iƳx¿¨b¦\8cLµ\9ccéo³\9db\88i8zZ$\94x>|h4E9\f \1c\ 3)!\ 30!\ 3G1\vgB\13i>\vlA\ f|O\1d\84d3u_-oX)mX)iV&n\+p^0vd7\7frHÕË©ÞÔ¹ß×»á×¾à×¾âÙÁá׿ãÚÁäÚÂâÙÄá×ÂäÚÅá×ÃáØÃÈ¡UÑ«e×µm׺vÕ¹t×¹pÒ²jÕµoÕ¶kÓ´mÖµnÐgͪdÑ®kÈ \¹\8fQ¨{8«x/£q+¤p) n+¤q,¨v1¦q,\9fk'\97e#\8d_\1e\87Y\1c~S\14\81V ~O\19oE\ fjB\10k@\13sI\16hA nE\15vJ\19rK\19rH\1dlF\12mF\16nE\13e@\15`A\19[8\ eQ2\bU4\ fM0\aJ.\ 4K+\ 3K,\ 3L.\ 4P/\ 4V4\aU1\ 5P,\ 3T1\ 6g<\12l@\ euF\16vI\1c{O!\80K\e~J\e\80O\1f\89T%\92Y&\95W#\96Z$\94W \96U ¡[)¡\,\96W!\8fT\1a\8eT\17\8aR\15\82O\18~G\10{@
+|F\13yE\10u?\vwA\10zE\15wB\ fq<\bn:\ 6s>\ 5{G\ fzE\ e|G\11\80K\13|G\13zG\13uC\11uC\13uD\13wD\14tC\12sD\14sC\12tB\10yH\16}K\1czI\16xH\13vC\11q@\13j@
+qD\10mE\14lD\ fg?\ ff<\rh?\ eoG\13rI\17uM\19vN\18\7fV \80V#\82X$\88_+\8ec,\93h1\8fd%\8c`"\91f/\92i-\94l6\97o6\91h/\93i/\91h0\94l3\8df/\8bd*\8ac&\88b \8ac#\87a!\80Z\e|X\1ezW\19{T\19nG\ fW8\ 2sS\1d¹\98[дrÜÁ~èÐ\92ëÔ\9eìÚ¡ëÒ\90É\97M¯o,\9dU\e\8a>\ 2\98Q\rÅ\96MÚÂ}çÕ\96íÝ¥îà¨îæ±îæ³îå²îæ´îçµîé·îçµíç¹îæ·îæ¶îä´îåµîä²îä´îä³îà¬îáîà¬íݨíÞ§íݦêÚ è×\9dè×\9bàÍ\92ÚÆ\88ζuµ\98R\9dh\1d\90F ~?\ 6\80G\r\8cR\18\9ek1¼\99^ÚÉ\91ßÐ\95äÑ\96ãÑ\94àÏ\8fßÎ\91ÜË\8aØÆ\85×Ä\85ÕÂ\89κ\7f˶|È´z®\95P}\\19\81`)ª\8fV«\93V\85g.dE\fnZ(E3
+! \ 3\1c\19\ 3!\1c\ 35"\ 3=%\ 3A)\ 3O2 N1\ 6\;\bkJ\18mV#gT&jX+gY(n\-r`3vg:\94\89dØϲÝÕ»àÖ¼ßÖ¼à×¾ÞÕ¼áØÀâÙÁâÙÁáØÀáØÃâÙÄâÙÄâÙÄΩ`ÐcÓ´o׸uݾzÙ»xÕ¶nÏ®jÎgÕ´nÔµqήgÏgÑhÑgЪ`Í¥YЧ\Ϧ_Ã\99O³\88A¦{1ªz6§s0©s0\9fn$ n)\9fk-\97f%\94c"\97e&\8fb"\88^\1e\81T\1d\81U\1esM\12cB\vb;\bkC\ fzS uO\15qJ\12tL\17{T'oN#iF\19gF\17eD\1ab?\rd?\11b?\14Q2\aK3\ 6F.\ 4I/\ 5G-\ 4B'\ 3K0\ 5P1\ 6T3\ 6X4\vQ.\ 5R0\ab7\rf;\vd;
+^4 e: l?\ e}J\1a\84H\14\8bK\19\91W"\91R\e\8eP\e\95V#\91U\18\92Z"\91X \94\ \94[#\90X#\85O\14\81I\10\81I\13\7fF\16yA\ryA\11t=\aq:\ 4u<\ 6vA yD\fyE\rr? m<\vq?\ fsA\11r@\10p?\ esC\13yH\18}L\e\81P\1e~M\18\83Q\1e\85Q\1c\83O\19\88Q#\8e^0\8aV"\81Q\1ayL\12pC h;
+c7\bi>\ eoG\12pH\13rJ\17qI\15xM\19tK\1avI\17}O\1d}T\e\81W\1f\90g(\99r4\9evA\9ct;\9ar7\9fw;\9cs8\97o1\9du9 v5\9dw8\97p3\95n.\96o/\92k*\8eg%\88a \7fX\1dxQ\14zU\17pK\12fF
+[<\ 3\80a'·\98VÔ·oÜÂ\7fãË\8açÐ\91Ûºs¼y6\98O\f\8aB\ 4\8aB\ 3·\85BáÄ\80ìݤíà§íà¦îá©îä®îæ¯îäîå®îå´îæ±îæ°îæ´îå³îáªîå²íã°îã±îâ«îä°îâîá«îáªíݦíà©íݦìÝ¥êÚ\9fêÛ é×\9eçÕ\9cãÒ\97ÞÈ\8a¼\98R\83N\ f`(\ 3K \ 3X#\ 3^-\ 2\95n<̵~ÞÌ\8fÜÊ\8dÝÌ\8eÛÊ\89×Å\86ÙÈ\88ÕÃ\85ÓÂ\82Ѿ\82л\82κ~įs¬\95XqM\19c<\ f\92wA\9b\84KxV\1eL7\b<.\ 5- \ 3' \ 3&\1f\ 30$\ 3>'\ 3;$\ 3:"\ 3;"\ 3;"\ 3G0\aV?\12mS#iW)iW*jX)kY+q_2zj<\9f\91jÛÒµÞÕ¼ÜÓ¸áؾâÙÁäÚÂáØÀâÙÁãÚÂà׿à×ÀâÙÂãÚÁãÚÂÈ£^̨cЮhѯlÕ²sÖµs×·qΪe̦_ЬdÓ±k̦_̤ZϨ_ЩaÔ®eЪ^Ω]Ï©_Õ®eزiÑ©]Ì RϤ[Ã\98R·\8bA°\85<ªx3\9fo)\9fn&¢q1\9fl+\9cm+\97d%\90c$\86^!\87_ \85\\e\84[\1c|V\18xP\12xO\14yP\14|R\1d\86_-~X\1csM\15e?\ frL\1cxN!mF\1ahG\1a`B\10_?\11Z9\vW7 \<\rb?\10_;\v\7 [8\aa<\fc@\11gB\14a;\vb<\r_;\rb?\ fV3 Z4 Y1\ 5a7\ad;\fi=\vk<
+zD\13\86O\1d\91Z%\8f['\95a+\92Z&\98`,\99^*\99X#\8dS\18\87Q\1a\85N\16|I\10xG n=\ 3n8\arA\ evC\ exD\ro?\fk:\fo=\ esA\11o@\10m<\fo>\ ep@\12tE\17zG\17yG\16xG\16zG\15\86S\1f\88V!\89Z%\88X!\88S\e\85T\e\87U\1d\83P\1ayG\14yJ\18xJ\18vI\12nB\10pE\12sF\14n?\ fj@\buJ\18yN\16|T\18\80Y\e\8ce$\91i-\91g(\96l.\97n2\9ar6\94i)\98n2¡w7¥z<\9ct4\9au4\9ao.\9bq1\9ev7\95m-\93h,\8ec$\8ed)\84[\1a\84[ \80\ kJ\ e\87d&¸\99TÈ®nÙ¿\80×½~Â\94N¢[\13\89D\ 6\82>\ 2\9bZ\1eΦgêÓ\93íܤíÞ¥îâ¨íà¦îã¬îâªîã¬îã¬îä®îå´îã¯îä°îä°îã°îá®îã°îà«íߨíߪîߨìݦíߦíà¥íÞ¢ëÛ ìÛ\9fëÚ\9dêÙ\9eéØ\9céØ\9cåÒ\94ãÑ\96Ѷw\90i'V$\ 26\12\ 3/\15\ 3@\1c\ 1\89e.Æ°uÙÆ\8bÚÇ\8cÙÆ\8cÔÃ\84×Ä\88ÓÀ\80ν{λ|Ì´wÉ®oĪi½§m«\93Y\83`+lJ\15\86p1\85r9K7\ 5/!\ 3;,\ 43&\ 3:%\ 4S9 ^D\16W8
+N4\bF,\aC(\ 4A(\ 5H.
+U>\17hS%iV(iW*jX+p]0r`3td9©\9fuÜÔ´ßÕ¼ÞÕ»ßÖ¼âØ¿ãÙ¿á׿áØÀãÚÁáØÀáØ¿áØÀá׿ãÚÂÊ¡bÉ\9fZÈ [Ñ°iÎiϬhÇ£[Ȧ^Ë¥\ʤ_Ì©eÅ\9bVÌ£X̦^Ë©]Ñ«`Ñ«\Î¥ZÏ©]Õ®gÖ°iÖ®cϧ]Ö°kÕ¯fÕ¬aÕ]Ó_É¡]Ã\9aYº\93S²\80A¢m.\9di#\93f \8fd#\8fc"\99j'\9dp,\93h&\91e$\8a_\1f\84Y\e\83Y \86]"\8b`'\86[#\88\%\80Y#wP vL\1etO\1atP\1c}T$uL\19gA\fbC\ ehD\18iB\rjF\ eiE\ fiC\ fnH\14qL\17hB\ fkD\13mH\17c@\12Q0\ 6I,\ 4L,\ 5V2\ 5`9 a:\vZ4 V,\ 5_4\b\6 d>\ exN\1f\8bW'\91[)\97\.\9d])\93]$\8eV\1a\90Y\1f\90[!\8aW\1f\8aV\1d\84P\1a\83K\19\81J\1awA\12p?\10k=\ eo>\12p@\10m<\fi8\bf; d9\vn@\11wE\15r?\11o?\11n>\ esE\10tE\vxH\11}L\14}K\12~K\13\7fJ\12\83O\18\81K\13\85N\17\8aU\e\88S\17\82O\12~K\ f|K\ ftC tH
+vK\10zN\17}S\1a}S\15\86]#\89`&\89a#\87\\1e\84\"\85`#\8bb%\8fc*\91h'\99o0\9bq3\9et5\9cq1\9cr7\9ao6\99n0\9cp6\99o5\9ap4\94i*\92g-\97o9\88`*~U\1d\89e*³\91VƧgËkz:\83A\ 4v4\ 4\82A\a¤n1Ô¸{éÕ\9dëÙ\9fìÜ\9fíݤíݤíߪíÞ¤íÞ¤îà¨íߨîà©íß©îàªíàªîá¬íߪîÞ¨íÞ©íÞ©íß©ìݦíݧìܤìÜ¥íܦêØ¡éÖ\9dê×\9cêÖ\9bèÖ\9dèÖ\9aåÒ\96àÍ\90ØÂ\84¦\88KU+\ 32\r\ 3%\11\ 39\1a\0\88j7ƲzÔ¿\84ÖÁ\7fÓ¿\82Ô¿\83Ò½~͸zɲvÈ°pìn¿¥j¸\9e_µ\9cb¤\89O\95y?|]&yc*J=\ e)\1d\ 4+\1e\ 38%\ 3=)\ 3X;\10lC\16wR%uS)lK\1acD\15Z?\10Z?\12[A\17dK&iT'kW+kX-lY0n]4rb7te=º°\8fÞÕ¹ÞÕºàÖ½á×¾ÞÕ¼àÖ½áØÀãÚÂãÚÁáØ¿âÙÁßÖ½äÚÂãÚ°\87G¶\8dI³\8fJ¼\9aSº\98R¾\99OÃ\9eXÃ\9fTÆ\9fV½\95M¿\97O½\95K¾\97LÊ¢[Ï©bɤXϧ^ÔfÏ©`Õ®fÒ®eÑ®fº\95Oº\8d?Ì\9dOÈ\9fVË¢S׫]á»uߺrÛ¹pÔ¬dΣ^È\9cSÀ\98M»\93O§}=\9dk"\9ek \9cl!\97h"\97j'\9bo(\98j)\9es8\8fe*\94f+\9cm1\93l.\7fU#zP\1d\80X {U\1e}V\1e\87]!~S\1efC\10g@\ ekF\12oJ\14nL\16lF\11nJ\14oI\17lF\15jD\14jH\16Z;\fS7\bP4\aL1\ 5V3\bW5\ 4Y4 S1\ 6X4\ 6S1\ 3Q,\ 6M-\ 4N-\ 5W3
+]9\ eoB\1d|K\1a\87T\1d\8bS\1d\90X!\93["\8eY \8cU\1c\8eY%\90[!\92Z!\8bR\1e\82N\1a\81M\1a\81J\1azI\etG\17nA\15h:\12d:\11a5\ eh8\ ef9\ ee9
+`4 g:\ ei<\rf:\vj?\fj>\rj=
+n>\bn?\vxI\12\84N\1d\89R\1e\8cU!\8aR\1f\8eV\1f\8eX\1f\88T\19\89U\1a\86S\18\8bY\1e\83R\19\80S\12\81S\18\82S\1a\84X\1e\82Y\1c\7fY\1d~Y\1d\81X \85]'\87_$\90h1\90g2\91j0\95m4\92i3\91h.\93k/\96n6\97o5\98p9\95l0\94j1\9dr6\9es9\8da(|T!\84]+¨\86Hº\98X\9al)l4\ 3b%\ 3{=\b¢m,Ù¿\83åÒ\99éÕ\9dèÔ\99ëÙ¢éÙ¥ëÙ¡ìÚ¥íÝ©íܧíÞ¨íݦíݨíÞ§ìÞ©íݧìÜ£íݦìÜ¥ëÛ¤ëÚ£ìܤëÛ¤ìÛ£êÙ£êØ éØ é×\9fäÓ\96åÓ\99äÒ\99æÒ\97âÎ\91ÜÈ\8cÙÄ\88±\96^`?\ e0\12\ 3#\10\ 3;!\ 2\94yHDZxϸ\80η}ͺ\7fË·\82DZwůtÀ©jº£d²\9c_¬\98_ª\92\\9d\84K\9c~B\8fu8nR\eD0\ 4\e\14\ 3\18\12\ 3!\18\ 3-!\ 3B+\ 3_=\10rK\1e|R'{T0sN oK!eE\17kL\1ekS'kS-hQ&fT)jV,j[.m]1qa5wg?Æ»\98ÝÔ¶à×¼àÖ½ßÖ¼ßÖ½ßÖ½à×ÀâÙÁâÙÁáØÀâØÁãÚÂâÙÁáØë\84D²\89O«\84D§\7f>¥\7f>©\80>·\8cK¸\94KÂ\97MÅ\9cUÀ\9bR¿\9bS»\97R¾\99VÁ\9dXÄ£Zá\ÑjѬcÔ¯bѬaѬ`Ъ`Æ\9fSÈ\9dNÅ\9aOË£UÏ¥WÕ¨\Õ«]Ч\Ò§^ÓªaÑ©_Òª`ÑaÔ¬eÉ¡YÀ\92I±\848§z2¤{3\9dt,\94i \91b%\8fd&\99o6\9dr5\95m4\95j1\8ed*\94g+\89a%}V\e}V\1a\81W\1dxU\1epJ\15zR\1e\81V+yS%vO\ewO\1cqL\19fD\11iH\16hH\16[:\vW;\b_<\raA\11aA\ f_=\ eT8
+T5\ 6U9
+X7\vV3\aU3\aQ0\bM-\ 5K,\ 4K*\ 3V4
+`8
+i=\rsF\10|J\15|K\14~H\10{K\16\83S\19\84Q\1c\87R\1f\87R\1e\88S"\85S#\7fP \82R!~N\1fxJ#vJ!nC\1cl=\14c4\f]2\ 6[3\a]1\ab8\ f_9\v_6 ^6 b:\fb8 a6\bb7\aoB\11sB\10uG\15}K\17\84M\1a\85O\18\88T\1d\86U\1d\8aW\1e\8eY\1f\8aY!\8dY\1f\8cZ#\88V\1d\83P\14~P\16\80R\18xK\11xI\14wI\15\80T\1c\83X\1a\86]&\87^!\87`%\8ab&\8ff*\8ff,\8dd*\8dd(\93k4\93j0\94i-\96o1 x8\98l0\91h1|T\1d{Q\14\92l0\82W\19V)\ 2H\1e\ 3a0\ 5\9dq2ʱ{ÙÄ\8aáÌ\97æÎ\95äÐ\9bèÓ\9fèÔ\9eêסêÖ£ëÙ¦ìÙ¥ìÚ¦ëÙ¦ìÛ¤ëÙ¢ìÚ¢ëÚ¢ëÚ¢êØ ëÚ¢é×\9cè×\9déÖ\9eé×\9dçÕ\9dçÖ\9dåÓ\97äÒ\96âÎ\92áÏ\92áÍ\91ßË\90ÝÉ\8cÚÆ\88Ò¾\81¿¦k~^&> \ 24\1c\ 3[E\12¤\8eYÇ°vîxƯzÆ°x¿©m¿ªoº£l²\97^¥\90X¤\89O\9e\83N\99\7fN\94yE\86n/eP\147)\ 4\13\10\ 3\10\ e\ 3\16\12\ 3\1f\18\ 3*\1f\ 3=%\ 3L.\ 3^>\ egC\12kM!kN"lK\1ejL!kP\1enU+iT+dS'bR$gV)gV+o^2qa6~nJÐƪßÕºß×½ßÖ¿á׿ßÖ½ßÖ¾âÙÁãÚÂäÛÂâÙÂáØÂâÙÄãÚÄãÚÅ\98p7¡t:®\82F¥\7fD\9dt8\9ao.\92i&\9as0\9cs,¬\84>À\9e`à a¿\99T¾\97T½\97V¹\93P¸\90Lµ\8fO¼\97SÄ\9dUˤ^ѪaÓ¯cЩ`Î¥XϧZϦYϦYÕª[É\9fQÆ\9cQÊ\9eTÌ¢Yͤ[È\9fUÊ¢WÍ¢UΤUÒ¨[Ñ¥[Î¥XЧ^̤YË¥Z½\96S°\86Iª\7f>¤y8 u7\9cr1\9cp,\9bm-\93f&\89\\e\88^\1e\8b`%\84Z\1c\83[!\86Z!\81U\1c{S\1f~V {S\1ewO\18gD\12lK\1aiJ\17[< _C\10pL\17uN\17vR\1c\80['vX#nM\16dD\r_>\bb;\f\6\a\:\ fX6 T3\aO-\ 4J,\ 3Q-\ 5J-\ 3Q0\ 3c8 c:\ 5d6\ 4h<\ ej:\foA\10oB\11uG\16tF\16zM\1dxN\1c~R \81O!\81P"\84R%\7fO!\80Q%~L\1euE\16l@\11j=\ fe:\fa8\v]3\b_5 Z1\ 6Y2\ 4^4\aY0\ 4[3\ 6W/\ 4T-\ 3Y1\ 4`5\ 6b5\bf7
+m@\v}M\1a\80K\1a\84R"\8cZ'\8f\"\8e[\1d\88T\18\83Q\15~L\14yJ\15vG\10qB\vvF\11}R\19\7fV\1f\80X |T\19\80Y!\85\&\84[$\82Y \86\#\8dd.\8ee(\93i-\93k-\93l,\93m.\94l0\8cd&vN\10fC\f^=\ e=\1d\ 37\17\ 3O&\ 2\8aj2¿¢pͲ}Ï·}ÙÁ\88ÝÅ\88ÝÈ\8aâÊ\8eæÏ\95çÒ\9cæÒ\9dèÕ\9fçÔ\9déÖ\9féÕ\9dê× ê×\9féÕ\9eëØ èÕ\9bèÔ\99çÓ\98åÑ\95æÒ\97ãÏ\93âÑ\94âÎ\91ãÍ\8fàÍ\90âÏ\96ßÊ\8eÛÈ\8cÝÉ\8eØÄ\87ÕÁ\81к|ìt§\8dT\82i,r] \92{D±\9a]¼¥p¿¨r½£lº\9d`´\9d^©\96Y©\94^¢\87R\96\7fD\91z@\8fq9\87n7t](M:\b0\1f\ 3\16\11\ 3\14\11\ 3!\1e\ 3)#\ 3.!\ 34$\ 38&\ 3E0\ 5I3\ 4S9\fQ=\11T=\11S<\11W>\13\C\16fO#eQ%hT)cP%fW*fV*p]5rb:\86wRÔ˯ÞÕ·ßÖ¼àÖ¾ß×¾âÙÀà׿ãÚÂäÛÃâØÀâØÁáØÂãÚÄãÚÄáØÂ\8ef0\99s<\99r;¤\82N¢\7fJ\99s:\9bx9\93g+\9er2¤}5¨\87D²\8dK´\8fM¶\90P³\8fI»\94L·\93L®\8cD³\8cG¼\95RÃ\9cTÄ\9bRÅ\9eUË¥ZÆ\9dOΦXͤZѨ[ЩYЧ[Ш\ΧXÌ£VÇ\9eSÉ SÊ¢UͤSÎ¥UѦUÉ¡OШUÓ§UÒ§TÏ©[ͧ]Ñ«dͨcÍ©aÆ¡Y¶\94Kª\85C£|6\9al.\95c'\8dc!\96k0\97j*\9cl(¡r0\9fm+\96f&\93b!\92e#\81X\19}T sN\16fH\13W;
+`D\roK\ ftN\17sP\16yO\15tU\19qN\18lH\14iC\14e>\11eC\15fA\13a>\ egC\15_?\11Z8\rQ.\ 5G-\ 4F,\ 3H1\ 4P1\ 5R1\ 4S1\ 6W4\bU0\ 6[6 ^6\vZ3\bZ1\ad<\ fi?\12l@\11tG\19xJ\1a{N$}O$\7fQ$xI\16xG\15xH\15wI\18vF\14tC\14qB\ fk<\rb6\bY-\ 5P+\ 3M*\ 3I(\ 3E"\ 3E%\ 3K)\ 4K'\ 3N*\ 5Q,\ 4W1
+\4\vf;\10tH\e\80R\1f\82S\1d\80P\1d\82N\e\82Q\1a\81P\e\82R\1f~P\1d\81T!\80R \82S"\81U$}T!\7fU \7fV\1f\83Z%}S\1a\81W\1c\86Z$\86\$\8bb.\8bb+\8ef-\8ad+\8dh2\86`+|X\edC\ eW7\v8\17\ 3(\ e\ 38\1a\ 2eO\1e¡\87Q·\96\£nÅ©ḻrÓ´vØÁ\83ÛÃ\84àÊ\94áÌ\93ãÊ\8eåÐ\95åÐ\98åÒ\99åÑ\96åÒ\96åÑ\97åÑ\96äÑ\95åÑ\96ãÐ\94äÐ\94âÎ\92âÎ\91ÝÉ\8dáÍ\90ÝÇ\87ÝÉ\8dÜÇ\8bØÄ\83ÛÄ\86ÔÀ\81Ò½\82Ï»\80θ}Å®u»\9fh«\95]§\90V«\92[²\9a^µ\9ce°\99`´\99^¨\8fR \8aK\9f\82J\90xC\8dq?\84l/zb%rU\1dZ?\bC-\ 3'\14\ 3#\r\ 38!\ 3[; lH\vjD\amB [9\ 4[8\aU4\ 2R5\ 5P7\ 5Q:\bB'\ 3A'\ 3@(\ 3G-\ 3V>\ f`M!aO#gX-jZ.hX.jZ1qc=\8e\81dÕͲÝÕ·ßÕ½ÞÖ½à׿âØÀáØ¿à׿âÙÁà×ÁãÚÄà×Àà×Áß×ÁàØÃW6 eG\16wV'\8ai<\92n5\96p5¦\7fG¥\7fN¤~Iª\87J¨\84L\9e{C¦\81K¥\82B©\84D¬\87D§\80:¦\81>±\8dG¹\95OÁ\9cYÂ\9fYÉ£[Ç\9fYÃ\98QÅ\9cSÉ\9fS̤XΦXÑ©YΧUÓ«XÓ«ZЧ]Î¥XΣPÌ LÊ¡PÆ\9bIÅ\97EÄ\9cIÉ¢QÆ\9dLÆ\9dOÄ\9dPÀ\98MÁ\98RÉ¡\ͬdÊ©gÆ¢YÁ\9cV·\92J¹\8fN®\84B\9cs-\9dp*\9cl)\99f%\9cg&¥o&ªv/®y0\9dn&\96g)\92c!\82Y\1c^A\vaD\vjE\vuQ\e|X!{Y$uV pR\1ajH\14dA\ feB\12eC\15a?\10c@\10cA\12gE\14pH\1ckD\11`>\ eY;
+U9\vQ2\aJ.\ 4Q0\ 5Q0\ 6L,\ 3P0\ 5R1\aQ-\ 5R0\ 6U4
+Z3
+Y3
+Y3 ^5\fc;\14i>\19j>\14mB\10qE\15vF\17uG\18}L\1azG\16zL\18wI\18wG\15nA\ ff>\ e`7\f\7\ eM+\ 6H&\ 3G'\ 3E$\ 3@$\ 3A%\ 3@&\ 3F+\ 5A(\ 3J/\aU8\ fP/\ 6Q/\ 5d>\10iA\16oF\19{P&yO\e|R!\81R!\85V!\80V\1f\83Y#~X \80W!|S!{R!{O\19\80T\1c{R\1azP\1c\7fR \82V\1c\85]%\7fZ%~W$|V#yU!oJ\1aM/\b*\13\ 3$\15\ 3>+\au\+\96v<¢\84K°\90Y¶\9ai¿¡kÇ«pϳsÒ·{Õ¾|ÚÃ\87ÛÃ\8dáÈ\8aâÊ\90àÌ\8fáÎ\91âÎ\99áÎ\92àÍ\91âÍ\92áÎ\91ßË\8fÞÊ\8eÞÊ\8dÜÈ\8aÙÆ\89ØÆ\8b×Â\84×Ã\86ÓÀ\82Ѿ\80Ѽ|ͶxɲzÄwªv»£l³\9df°\9ag«\93[®\92W«\90X¤\8bN£\85N\96}H\95{E\8cuB\82f4y_,cP\19Q9\v<'\ 3/ \ 3'\13\ 36\1e\ 4V;\11zT\1e\89\\1c\8d_\1e\8bX\17\8f\\1e\89X\13\88[\13\89]\1czQ\ fmG\fd@\ 6Z:\aL2\ 5K4\ 5J2\ 6ZE\17eU)bR%hW+hX+j[2n_5vf=\9c\8dmÛÑ·ÜÓ¹ÞÕ»áØÀâØÀáØÀáØ¿âØÀà×ÀáØÂãÚÄà׿á×ÀáÚÄäÜÆK1\aE*\ 3B&\ 1J2\a\<\rtN#\7fT\1e\8db,\9bwI\9cx@\95tB\8bi6\87c.\80\'\8ek8\9av@\9du3\95l.\9at0\88Iµ\90P³\8bK¹\93P·\91Qº\93UÃ\9cYÉ¡X̤U̦XΦXÌ£TÏ¥XÌ¢TÈ\9eTÎ¥[ШYÒ¥UѦVÈ\9ePÇ\9cKÆ\9eKÊ¡SϨ`Ã\9aLÃ\9bLÈ¢UÆ\9fPΧ[Ϊ^Ã\9bSÈ\9fTÇ\9fUÁ\97R¿\99UÃ\9bSÃ\9aRÌ¥^È\9eZ¶\8bJª\80?¦x2§u3®|:¥q*¢k, m-£r3\93d%\8b`#\8dc)\8a`%\88`$\87`'\8ab&\8cd'\8aY\1f\83[\1d\80\\1duN\17fF\14hF\13jH\17iG\13pM\19qN\19pM\elF\14gE\12`>\v^;
+];
+_?\ f^< X7\bQ3\aN.\ 4Q.\ 5S0\ 6T1\bX3
+X0\aW0\ 6V0 X. `7\r`6\vg=\10lA\13f;\ftG\16pD\11rF\15pB\13uG\15vG\13vH\15pA\ fl@\12h=\f`8\v[7\fV0\ 6T-\b@$\ 3>#\ 39$\ 34"\ 37"\ 34$\ 35#\ 35!\ 37"\ 2;'\ 4B-\ 5N3 O4\aZ<\10kD\16vJ\18sI\14\7fS"\7fU"~V#|U!}T'zM\17xN\16tM\14tK\17tK\16uN\17\7fW vO\17qK\17tO\epL\17sN\1aeE\15G,\ 5(\16\ 3%\16\ 3@%\ 3X:\vpN \80b2\96v?¤\82F°\8eW¹\9ceÀ¡bÃ¥iÆq͵\80Ó¹zÕ»{ÙÁ\82ÛÅ\86ÞÉ\94×Ä\86ÛÇ\8aÞÊ\8aÛÇ\8bÙÅ\85ÛÆ\85ÙÅ\87×Â\82Ò¾\81Ò¿\86м|͸w˶xdzuÅ®kÇ«pÁ¦m»¢j¸\9fjµ\9bc°\94Y¨\8fX§\8bY\9e\84M\99\80E\97zD\90r<\8am6za&rY$`J\18I6\a0!\ 4(\14\ 3'\15\ 3.#\ 3D0\ahL"\86g3\95j3\90`)\8fa\1f\91`#\96c&\9ch#\9el'\9ck*\99f&\91a"\90b"\8fc%\84[\1e\84]"~d.m[+dS%fT'hU*gY,jY1p`;qc@£\97wÙжÞÖ¼ÝÓ»ÞÕ¼áØÂà׿à׿á׿áØÀáØÂáÙÃáÚÃâÚÅãÛÆäÝÇ_@\e_=\14U3\vO3\rN0\aU6\ eU5\r[<\11sQ%vU \81_.\82\)\82^,\84_,\85b0\92n:\9bu<\93l0\93h(£|<©\82E\9ex@\9dv8\9ex9 y=¤}>®\84EÄ\9cYÄ\9dVͧ]ͧ^Ê\9fTÉ\9cRÃ\9bRÁ\99MÈ\9eQÊ¡SÊ£TϨYЧTÍ¥RШWÓ¬`Ï©\Ë¢UЩ[Ъ^×µkÑ«bÉ\9fTЩ`ЩaШaÂ\9aSÁ\98SÃ\99PÌ VÓ§\Ð¥]ϧ^Ë\9fUÄ\9bP¸\8fH»\8eF¶\82>¯|7¬w2«r-£o)¥q. n(ª{6«|8¤v1\9bo-\9ai(\96e!\93f%\83\\1dvO\eyW\1f\80W\1f\81W\e~X"|R\exP\18sJ\13vL\17qF\12pC\vpG\12jD\ flC\15sN\1cwR pJ\1dgA\ fhC\16b:\r[8\fU1\bQ0\ 6Q.\aO.\ 6S0\bT0 \6\f\5\f]5\f[2\b`5
+a6\va7
+e<\ epC\13qC\14l?\11lB\15k@\13h;\fh=\12d9\ eb7\ f_7\ fZ1 M*\ 6F,\ 5D)\ 4>'\ 45\1a\ 3- \ 3/"\ 30"\ 31$\ 30"\ 32&\ 3;(\ 3B,\ 5G-\ 6K.\ 5Y5\v`:\rgD\18kG\18rK\enE\12pJ\12rJ\13sK\18sK\15qJ\11yS\1fsM\eqH\1alC\15oF\13qJ\18mK\1eiA\11R1\ 5F.\bD)\ 4C'\ 4I+\ 4I/\ 4]?\vwT\1e\88i5\92u:¥\82A«\8dQ´\94W¾¢iÆ©tÇsɱtе~Ѷ\7fÒº}Ò¹~Ô¾~ѽ\80Ô¾\80Ô¼}Ò»\84Ë·|̶{ȱwɯtÆtçj¾¤i½¢cº\9d`®\92T¯\92Y®\8eQ¨\89N¡\84D\9c\81D\97{F\91w?\8bp:\8ag0~^\1dlO\14[B\13A+\ 3,\e\ 2\1f\11\ 3"\13\ 3-\e\ 2E1 R8\fmO\18yW\1e\8bg-\97r6\91g4\82W\ e\8b\\1c\93b \98e \98f!\97e\1c\97g\1f\99f"\9ek-\9bh*\9el-\9ep4\9f{E{h:eS'dR$dV'jV+k\0tc;thH¶®\90ÞÕ»ßÕ¼ßÖ½à×¾à×¾à׿âØÀâÚÃáØÃáØÃÞÖÀãÛÅåÝÈåÞÈçßÉrM0mJ&pI$eA\ec<\16U8\fL0\ 4K1
+H/\aZ>\19bI"gJ\1fqX,pQ$uQ\1c\7fV'\83\%\85`#\95n6£|?§}B¡u7\9bt5\9cr3§}<«\82C¤~=¢|=¥}9\88Aº\91GÃ\97R½\92G½\93I¿\96MÄ\9bPÁ\98MÅ\9eSÈ¡WÉ SÈ¢WÍ©\Ñ©^Ó¬bÔ®eÓ«bÕ¯hÙ¸oÕ±iÑ©cΦ`Ï¥\Ñ©`ЪbÉ¢^É¡\Φ[Ò¦YΡUÓ¦_ׯdÖ¯eÔ¬cÒ¥^Ñ¢[Ï¢YÊ\9bRË¡XÄ\96M¾\88B±z4®y4{2§t+¦v/\9dn*\9fm+\98i(\8ea!\89`#\85\\1e\87Z\18\8eb\1d\92d$\8e`\1f\88Z\1a\80S\1avQ\15\81V$\82W\1d\82Z&\82Z(\88`.\8dc4\88`*\87Z'\84[$\84^+\85W$xN\1fpN\1deD\13`=\ eQ3\bQ/\ 5Q/\ 6W3\v_8\vX3\ 5X3\aY2\ 5Y2\ 6Y3\ 6W0\ 5Y1\ 6\4\b\6
+^7\ ea:\ fa8\10e;\12c9\11a6\11b8\12g;\17e:\13c:\12^7\11U2
+Q/\aJ)\ 4F'\ 4B$\ 59%\ 55%\ 47"\ 49'\ 4<(\ 69$\ 4;(\ 5A)\ 5C+\ 6G+\ 6N0 Q1\bQ0\a\8\f`=\ eb=\11eA\ efA\frM"rJ\1fjB\14lC\14mF\14rG\19wN vN"pH\19uJ\1ciB\15a@\ fV5\bK0\ 4B(\ 4H.\ 2L0\ 3\?\ftU\1d\87c,\99zB \82H¨\8aI³\94]·\9a`¿\9ed¿¢j¾¥gĨn§jƪnÄ©oÆ«r¨oĨk¿¢d»\9ec·\9fk³\98_µ\96_²\95`§\8dQ¨\8aU\9f\84K\9b|E\98y?\94v6\8eo3\8an-\84g)z\\1fsU\1agH\14M8\ 4;&\ 3(\15\ 3\1f\10\ 3#\17\ 3(\1a\ 34\1d\ 3H0\ 6\=\11jG\eyQ \7fV\1d\82]%\98w:\99t=\89`$\8a_\1c\8b_\1e\8b^\1c\8c_\1c\8d^\17\91_\1d\93`\1c\95d$\94c$\99h+\9al1\99r?t^.^R#dS#cS%dV'l[3pb:sfEÊÀ\9eÜÔ¶à×½ßÖ¼à×¾ßÖ½áØÀâØÂá×ÁäÛÆäÜÇäÝÈäÜÇæÞÈæÞÊçßÊ{^7\81`9uL+oI!mF\1dmI\1ehF\edG\1fS5\bN2\rI0\ eE-\bE.\bV>\15X>\10[=\16oT%rP\1ezW%\87f/\91l;\96m4\95i,\99n4¤{B¤\81G¦\81E²\8dSª\86D©\80=\9eu0¤}8µ\8bH¼\96Q¹\95R¸\8fJ´\8eJ¾\95N½\92M¼\91K½\93MÆ\9eSÈ¢YȦ^Ïb̪_Ô´jܼrÕ´kɤ\Ê¥[É¢VÊ£[Ì£\È¡VÃ\99OÊ¡WÒªbϧ[Ò¥\Þ·nà»rÕ®fϦaÒ¦XÏ YÌ\9eUΡXУYÔ SÐ YÉ\9aS¿\93H¸\8bAª}1¨y0\9fj$\9ci\1c\99i\1d\9bi!\9ai)\95h)\95h-\96h*\97k*\95j)\86W\eyP\16{R\1e{R\1a\83\+\88_/\8cc0\93f1\93i2\90a%\87^#\86\$\8da,\8d`,\91g3\8da,\80U\1euK\1ad<
+f=
+b>\ f`:\ e_9
+[7 [5\a[4\ 5X0\ 4V/\ 3Y2\ 6W1\ 4T/\ 5S,\ 5T0\bT2\bS/\aV/ W0 X2\v_7\11e9\15c9\15b7\13b7\10a8\ fb5\ ee9\10g<\15a7\ fQ2\vQ/\rP3\ eO0\rI+
+E*\ 6H, K- K-\aM0 K.\bK/\bL-\ 5M/\ 6F*\ 3M/\bV4\vZ7\11_>\15\:\13a=\13fA\18mE!sG\1f|R+yP+vL"wO'rL"mG lG\ed@\11]<\ fM.\ 5H+\ 3K+\ 3U0\ 6]: oN\16\83f)\93r6\9d{= }?©\89Mª\8eQ°\96\¶\96a´\94Y·\9d`¯\93X¬\91V¯\93\¦\8dQ¥\89V¤\89P¢\85Q\9c\80H\98zG\94w@\94x:\89m3\87h6\81a*|^&vX!jO\15^C S5\ 4@'\ 35\18\ 2*\14\ 3,\15\ 33#\ 3=(\ 3K0\ 6I.\ 3K.\ 3W<\bcA
+c=\vjC\13rK\18rK\18\84](\8ef/\85^\1f\85]\1d\83[\1a\83T\12\88[\1a\8a\\17\87T\15{J\b\81N\f\81R\10\8aW\1d\90^&\8ei0kS\1dbS$bT$eU(fW)jZ-l`:znKÑɤÝÔ¸ÞÕ¼ÝÔ¼ßÖ¾áØÀà×ÂãÛÅãÚÆäÜÆäÝÇæÞÉæÞÈæßÊæÞÉäÜÇu_<\8aoNuX5nP+qP/}X2wO(kI hG\1e_>\19T8\16Q4\11T5\11P5\11N4\rJ2\fO5\ fX?\14bH\1fX=\11W<\11^A\12hI\19uT*\83]3\8dl:\94n?£~K©\83K¯\89P«\84D¦\81>·\8cL¹\92Wº\95U·\8eN´\8bL´\8bI¼\94P¾\96K¿\94H½\94HÁ\99L½\97HÀ\96GÅ\9eQÉ£Yϧ^Ó®cȨaʧaÑ«cɤ^Ȥ\Æ\9eUÊ£ZÇ WÇ\9eVÃ\97NÇ\9bPÏ¥ZÕ«^Õ«`Ð¥\ΦYÒ¨]Ê¡XÁ\98LÈ\9aPÈ\95HÌ\9eMÏ¢RÖ¯`ݸi×°aΤZЦ[Ì£Z¿\93I³\836©z4\9fp+\96i*\95g'\9ag%\9dn'\9ak#\8f_\e\8a]!\8b^'\87Z\1f\80V\1dyQ\17\83X\e\87_&\87\#\81X\1d\80W\1f\81X#\85\'\8ca/\89^)\89['\81U vK\19vJ\13lB\10b;\ f^7\bZ5\ 6X5 W5\ 6_<\10Y3\ 6`9\v]7\rY5\vU2\bS0\aO/\ 5K+\ 3L+\ 4I&\ 3M*\ 5L,\ 6T/\ eT0\rT/ a6\13a:\14c:\13c;\13iA\ehA\17e<\15d;\15b<\12b9\13a=\18a>\17]9\11\:\11Z9\11Q2\fR3\ fU3 T6\10O2\fH,\ 6H.\ 6I,\ 3L1\aT4\ eP0
+P0 S2\v^;\14b?\15hC\1crH!oI\1cqK$oI\1cqH\1arI\18qI\17pF\15nE\16a9\b]3\bP*\ 4P+\ 3J*\ 3P0\ 4[:\vfD\11sR \80a&\8bk1\8frA\95t@\9byA\94t<\98xC\96yC\8fs?\95tC\8eo>\86k5\82f1\82d-z\(u\)iP\1ajM\1d^?\13S5\bL0\ 4E)\ 3=&\ 3;$\ 2:\1d\ 3E+\ 5K/\ 4]=\bc?
+`= bC\ fjF\13b:\ 4a8\ 4a=\bfB\fa<
+`<\ac= a;\ 6dA\amI\ eqN\ fwK\rrH\ 6tK\f\7fR\10\82U\ f\82R\12yK\b|M
+\7fN\f\85U\18\8ea'\8ak4nW"bQ#_Q cU&hW,i\2l_8\85xUÒɤÛÒ¶ÜÓ¹à×¾âÙÁãÛÅåÝÈãÜÅäÜÇåÝÈæÞÉåÞÈæßÊåÜÈäÝÇåÝȤ\97~\94\87q~qWvfHucI\85kF\83b;\86f?|^6xR0oM2dE\1ec?\e^?\1aT6\18O3\11Q1\12Q6\10O7\10I0\fI1\vI3 J1\fN5\r^A\1ffF kJ\1d|W%\8fh0\9bqA\9br9\9fx8£}@¡~A°\8eN®\89J³\8bK¶\8dOÀ\96WÁ\99T¿\97MÃ\99PÈ\9eT¼\93G¼\92F½\94H¿\97MÂ\99QÀ\97MÅ\9aUÇ\9fZͤ_ʨbà \¾\99S¹\93J¾\9aTÄ\9cVÂ\99U¾\98RÀ\95HÄ\97NÅ\97NÅ\98IÈ\9dTЧZÓ«bÒª_Ò«gÌ WÂ\94GÄ\94DÑ¥^ÕbÓªZׯcÞ¹hã½tã½rßµdѨVÅ\9dQÄ\97R·\8cE®\817¨w2¤v5\9cl)\9cm'\9dr3\99m*\96j(\8cb"\89[\1d\88Z!\86Y \84X\1a\83[&\7fT!rF\10o@\foE\ fzO\1avI\12rH\16uL\18xN\esK\19rJ\ fsI\17mE\16oD\14j>\vd:\fb;\10b;\ f_9\f^9\10Y6\fW4\bS1\vO-\ 6J, H)\aG*\aK-\vN,\aL*\aM+\aW3\f\6\ f\5\ fb:\12a<\12`6\10c;\15b=\17c=\16gA\ekI'oK)kD\1ekI$gD\1eeF\1ed@\18a=\17\:\15S1\fP1\fN.\ 6U8\10R4\rO1\vP2\vE*\ 4I-\ 6M1\bS3\vT4\ eY7\10]:\13`=\12iF\13lD\12jE\11oG\17pH\1cqH\19oF\17lF\16e>\12]7\rP/\ 5K,\ 3L*\ 3L-\ 5K.\ 2V:\bZ;\10_@\11Z?\faE\12fH\15iM\1dbF\17`G\e[B\11X<\ eT:\fP5\aF-\ 4A)\ 2?%\ 34\1f\ 27\1f\ 32\19\ 35\e\ 39\1e\ 3F.\ 4Y<
+fG\rrR\19xQ\15\7fU\18\89_!\86Z\1a\80V\16\80S\17uI
+vL\ eiD\fnD\rlE\fc=\ 6`;\ 5^6\ 3`8\ 3a;\ 3`:\ 4_7\ 3f<\ 3nB\ 6tF\ 5xI\axK
+vI\a}O\v{M\rzM\ e\86Z\1c\83f1gO\18aQ#^N\1dfU#fX)iZ1h[5\93\87gØͱÞÕ¹ÞÔ½à×¾äÛÅãÙÄäÜÆåÝÈåÝÈäÝÈäÜÇåÝÈæÞÉåÞÈäÜÇäÝÇ×Í´ÓË°ÍëƼ£©\9f\83\9e\90p\88wR\83pQ\81jM\8bpT\89nQ\84eFuT4qQ5kH(b@\1fb>\e\>\17V:\ fL5\rF0
+H4\ eD,\aG3\ fK7\15D.\rD1
+Q7\ ecF\1drV(~Y-\88e1\91l9\93l=\92k6\9fz@°\88J³\8cK¼\93PÁ\99UÅ\9cSˤ\È¡WÅ\9bPÂ\99QÂ\9aWÁ\95R¹\8fL²\89Eº\8fQÁ\99T¼\94NÂ\9aSÀ\9dVÂ\9fZ¾\9aO¾\9aS¿\97Qº\92M¿\96O¼\93H¹\8fEÁ\96OÆ\9fQΡVФ[Ψ]Φ^Ò¨fѨbШ^Ôª`Óª_ЧZ΢UÏ¢SÙ±cܵiÙ°aâ¹gå¿iâ»kà»hÓ«V׬YÚ´oÖ°kÄ\9aR·\8a?¦z4 r6\9cm%\96l'\99n*\96j+\92e'\8c`\1e\89[\19\88[\1e\7fQ\17qG\fnE uL\13vJ\15vI\17\80X%\84[$\8cc-\88_(\88a)\89`*\88_'\7fU\1etK\16nD\17a9\vf?\ fd=\ eb>\11W6\rQ2 T4 O1\aJ+\ 4M/ V4\rV3\fR.
+O-\aS0\vW3\rW3\vV2\fT0\ eU0\fU2\rN+\fY5\14`;\ehE\1fqJ%mG\1fqI%qI(uO+tN)nG\1ejE nD#kD%b?\15a=\17\>\19T7\ fM/\bI,
+M0\ eK/\fK/ N/
+L/\fP2\rW6\ eZ6\r\;\11Z8\ ea>\16dB\16kG\17nG\1aoH!pG\1dpD\1epF\1ee;\11^8\ eU/\ 4T1\ 5R0\aH)\ 4J)\ 3H)\ 3D)\ 3>#\ 2A'\ 4>#\ 2<$\ 29\1f\ 36\1f\ 35\1f\ 37#\ 33\1f\ 3=$\ 3<\1e\ 3C&\ 4L-\ 3O+\ 3P/\ 4]>\flI\13|R\18\7fW\1a\8a]$\89Z#\84Y\19\88Z\1a\8b\\1d\8bZ\18\87X\15\8bZ\18\85V\12\80Q\ e\81N\v\81O
+xN
+mI\avG\ag:\ 2g<\ 3j?\ 4h>\ 4i>\ 3qD\ 4tG\ 5yL\vuH\ 6vJ\ayL
+lC\blB\ryS\1dt]*cP\e^M\1ddR!_Q&hX,jZ0m^5\9a\91r×γÜÒ·ßÖ¾áØÀãÚÃäÝÆåÝÈäÜÇäÝÆçßÌåÝÈåÞÈåÝÈåÝÈäÝÇèàËÙϸØϸ×θÖÍ·ÖγÕ̵Ö͵ƾ©´\96©\9b~\96\85k\8aq^|gK}iGx\5wY;wZ6jH\1fiE Y=\1aU:\1dR;\1aH1\ fG3\12C1\10F1\12F1\10B-\fB0\fA+\ 6S9\14_C\1ax[2pM\1d{O\1d\8a\*\96i+\9cp3¢x6³\8bL³\8cI»\92P¾\95QÀ\96LÃ\99VÀ\96UÀ\99XÂ\97V¸\8eK»\95Sµ\91P·\94M¯\8bD¸\94M¹\95Lº\96MÃ\9cTÀ\9cV½\98PÀ\97PÁ\98Q½\95N¾\95OÅ\9dVÆ\9dUÈ XШ_Ô©]ѧbÏ¥`Ì£XΦZÒ©]Ó©\Ñ¥WÏ¢MÓ©UÝ»lܸnÛ°_׫Wß´_å¾jä»gà¶gÛ·jãÁyæÂvá½sÜ·pѨfÂ\97P¿\95V³\89H¯\85H\9eu.\9cn)\9cg*\9ah&\95f%\90_%\8a^!\87W!\84W\13\82W\18\80X\1a{S\16xO\15oK\17pI\16uK\erI\16zR\1etL\19tJ\1ayR%}V$\82]'xS\1feA\13^9\vY6\fV6\aY4\aP0\aX8\rW2
+V2 S0\ 6Y6\r^:\12Z6\ fV2
+S.\fT0\ fN*\aL(\vN+\ fT3\18_:\19[8\14]8\16a<\elI(jB!lI$pG#nG#nI$oI!nH\1fhC\1aa@\15^<\12\8\11X6\ eT3\vS2
+J.\aQ2 N/\ 6O0\ 6Q1\aS2 Q0\aV6\vZ6\r]7\r`<\13b>\12d<\16g=\18h>\13d:\10h=\10jA\11h<\re<\ ej@\14e?\10`;\rY4 Z6
+T/\aS1\aQ.\ 6L,\ 5H(\ 4I,\ 5P0\ 5P/\ 5V3\ 6R1\ 6W3\ 6a9
+f?\fc:\ 6e;\voE\14vJ\11~N\14|M\15\81P\1a\87X\1e\83V\18\88Y\e\86X\17\89Y\18\8a[\19\89X\19\88Z\17\88Z\17\8bW\ f\8d[\12\8b\\16\86Y\12\87Y\12\82R\f|L\byJ\btK\vwL }O\v\80S\f\7fR\ e}K\a{K\ 5vF\ 6l>
+a8\ 6nG\12iS aO\1fcR&_P aR$`P#hX+l^5©¡\83ÙÒµÝÔºÞÕ½ãÚÃãÛÄäÝÅäÜÈäÜÇäÜÇåÝÈåÞËäÜÆäÜÇäÜÇåÝÈãÛÆÖͳ×δ×ͲÖͲØε×δÙε×θ×йÙÏ»Õ̵ÍĬĸ\9e®¡\88\9f\8ft\87t]{gLv^9u^;v]<mT8gP-V=\16R<\1dP9\1dP4\eI3\12E-
+B,\vC-\vF)\bD, L3\ eY>\14\:\15b?\18jG\19yU&~W!\89`"\8fg(\9fo5¡v7¤{:¬\82E²\87I½\93[Ã\97^¾\93N¶\8bKµ\8eL²\8cH°\8dG¶\90Lº\96Oµ\91F±\84:µ\8dC·\8fD¾\95KÁ\98Q¾\93MÃ\99VÃ\9bT¿\96OÀ\99VÉ\9eU΢UÌ£UÍ£WÑ¥WÎ¥XÐ¥T΢QÍ¡OÊ\9dHÊ\9cIΣSÔª]Ù±_Ö¬ZÛ±^à¹iÚ°aÕ°`ܶeà¹lâ¾låÄséË\81éÆzæÃyß¼qÖ°jÕ°kÔ°gÓªaÎ¥]»\8fG¦t/£p0\9eo2\97j(\95g!\8e`"\89_ \85_"\7fS\16sN\ fmG\13e=\ 3h?\fd?
+b>\rkH\14sN\1ayQ\1ewP\1cyT!sM mG\16iC\17a;\ e^7\vY7\ eY8\v[:\10W4\fT2 T1\bT2
+Y5\ eU1 V2
+Y5\fX3\ fS/\rJ+\ fK,\12R0\18P/\12Q2\14U4\14R0\12T1\11S2\11Y8\16bA\1fa@\1ajG"iF\1ehE\1ecB\1abA\18a=\15dA\19^:\13^<\15\:\12\:\ fT1 P/\aK*\ 5J,\ 5K)\ 3T2 Y2\b\5 [4
+Z1\v\5\ e]5\ eZ3
+_6\ fY0\b^6\ f`6\fd7\rb8\r`6 d;\ ff;\10e;\11e=\10f<\11d9\ ee;\10b8\f`8\fa9\fa8\va8\fa8\ f`8\ ea8 h=\ fc8\ 6c:\ak@\ frG\ fzK\15xJ\10\80O\14\80Q\15\81R\12\81Q\12\85U\16\85W\15\8bY\17\90_\1f\89\\13\8b]\16\8cZ\15\8aY\11\89V\11\87V\10\89Y\14\8d\\14\90^\19\8e]\16\8a[\10\8e^\17\94d\1e\9am(\98g\1f\90d\1e\89[\16{P\riB\v`9\ 6gF\ eiP\1e_M\e]L\1eeR&_P!cS%m]1rb=·®\92ÛÒ¹ÝÕ¾ÞÕ¾ßÕ¿áÙÂäÝÇäÜÈãÛÆæßÉæÞÉäÝÉåÞÈâÚÅçßÊåÝÉäÜÇØζÙкÙϸÙй×ͼ×͵ÙлÙйÙкØκÙйÙϺÙкÚмÕ˶ÏŮĹ¥µ«\90\9e\94v\89x`}qUua>nV5iW8bR6XB&]B%^D\1fT<\17M2\fK0\fI1\rF1\fF2\rH3\fD. G.\ 6P5\fT9\f`B\11hH\10\80X"\88^)\92j.\9am7\9dm5«}F¹\8cS·\8dJ´\8aJ»\90Q·\8dM¸\8eK»\93LÁ\9dV¿\9aP°\8a<¬\86<®\84@±\8aA²\89B¯\87@·\8eI¼\98Q¸\94M¶\92L»\95PÃ\9aRÇ\9eWÇ\9eWÉ TÊ SÈ\9fRË¢WË¡QÌ QΣWÏ¢QÔ©\׫]ÖªYÕªZÖ¯cÕ«ZЪXÑ¥Q×®]Õ¯\Ü·câÁrçÄxæÃyá¾oݸoÜ·oâ¾tæÃyåÅ}åÃ\7fã¾xÕ¬gÈ\9dY²\86<¨y6\9ck0\94l+\9ap,\99o,\9as0\95l-\87^%|T\1aqG\ eg>\r`?\ ehE\11b< kB\13oJ\19uQ"}V&\83^+xR\1dlF\14lH\17pN pN\1ab@\ fT5\vJ/\ 5O0\bT0\b[8\10\9\13W5\10W4\14S4\16L0\11N.\12N/\10Q3\14I.\ eL1\10H-\rD( A*
+B(
+H,\vO3\17P4\16V5\15]<\1eaA!`C\1fdB\eiE\1f`?\16[:\16bA\16fA\18dB\19S2 K*\ 4L,\aL*\ 5R*\ 6U1\bU1 T0
+T,\ 6Q.
+S, U-
+U, S.
+R+\bR,\ 5O+\ 5V0\aQ,\ 5S1 X2\bY7\r`9\13_:\ ea<\10`5\rc5\vd7\rf8\ fa3
+e7\ ee8\fc7\vd8 a5\ 6_3\ 4]3\ 4a6\ 6j@\ao@
+o@\bxE
+vB\a{G\r\81L\ e\81N\r\82O\f\88T\r\8f]\19\8bZ\15\8d`\1f\8d`\1a\8aY\10\89V\11\85R\r\89V\11\8cY\13\8d[\18\90^\18\93b\15\99f\1e\9dl"¤t)£t)\9en(\98h \90a\1a\86W\16}S\13pM\14dO\eaQ#`O"aO"dT(eV,h[-ugB¿µ\98ÞÕ»ÝÔ¾ÞÕ¼àØÂâÚÅãÜÆâÛÅäÛÇåÞÈåÝÉæÞÈåÞÈäÜÇåÝÈãÛÆäÜÈàÖÀÜÒ¾ÞÔÂÜÑÀÜÒÃÚѼØλØμÙÏ»Úн×̺ØιØ϶ÛϼØλÙйØηØϺÓ˱Õ˳ÌìÀ¶\9e©\9c\85\9c\8dq\84z_sbEiO6iO*cK*fI-Y=\e\< V5\1aP1\13M1\fI.\rI0\ eA- D/\ 5K4\bP4\aO3\ 4hE\12}_,\86b1\8a^,\8ea(¡{E\88K²\8cO°\88N¯\85H³\8bJ½\96U¾\99Y¼\97Rµ\92K²\8eI±\8bM´\91M±\88F¥{8§\7f8\85>°\89D¯\89C¬\85D´\8dGº\91O¿\97RÆ\9dVÇ\9eUÂ\99NÀ\99LÅ\9dQÉ\9fOÈ QÊ£TÉ NШWÖ¬_Ò©YÖ®^׬X×®]ѪXÕ°_׳aÖ²]ÚµhÙµeÙµhܸnܸoß¼rãÁwâ¿wá¿wâ¿wæÃzåÁyݹvÔ®pÄ\9eZ´\8a?\84Aª\84?¨}<¦}:\9du,\8ff$\87Z#\7fR\1e\81W#\82[#}V\1fnG\ fjE\11kD\ fmG\17vN\1c}P\1fyO\18oJ\18lI\15sO\1cxS\1cvQ\efE\17R8\fO3\aY9\rb>\15`=\16V4\10T3\rT4\14K/\ fJ,\11M.\12L/\ fL0\11J.\ fI.\rH,\rF+\v@& A(\a<#\ 4<&\v@(\vD+\vJ/\fU8\18V7\18Y9\19\:\1a\9\16d@\1egD!_>\13c@\18mF\1c`;\16Y6\ fX0\vR,\ 6S.\aW3\ eS. P,\bO*\ 6S. V1\fY1\vV0 N+\bI)\ 5I)\ 5E(\ 5I+\ 6F%\ 4H,\ 5N/
+Q0\vO-\aT.
+X1\v]2\v_5\ e]4\ba6\fd7
+d7\ff:\fe9\b`5\ 5f;
+e9\af;\aj=\ 6j<\ 4h9\ 4j;\ 6n@\ 5rA\ 5sD\bsC\azI\ e\87T\14\88U\11\8b\\18\8dZ\13\8bY\11\89V\10\88T\ e\8bX\12\88U\v\8bY\11\8d]\16\91\\10\9ag\1c\9dl\1e m$ m' q*\9fp&\99i\1f\98f'\92g&\81]%gS%]N!\N"^R$aQ$fX/i[.}pNËÁ¦ÜÔ»ÞÖÂà׿àØÃßØÂãÜÆäÜÇãÜÆãÚÅãÜÆåÞÈâÛÅæÝÈäÜÇäÜÇãÛÆáØÂßÕÂàÖÄá×ÁÞÖÄÞÔÀÝÓÁÜÓÁÚÑ»ÚкÜÓ¿ÙÏ·ÚѸØη×ͶØδÚѹÛѺÚÒ¹ÙйÙÏ»ÛÒ¼ÚѺØζÑɳŻ¤·¨\8f\9f\8fs\8c}g{lRp[AkO6mM8jG-c?!Z7\16_D#T2\ eN2\12M5\10G,\bC-\aS4\r[:\14a@\17iH\etJ!\82]1\90d7\97n9\9cuB\9exE\98r?\9br6®\81>µ\8cF¹\8fK¸\8eQ»\91T»\98X¶\94R¦~>¢{6¨\83=¬\86A²\8aE¨\83?¨\818®\85>©\81:²\8aF»\95P¾\95K»\92H½\95I¾\96K¾\96JÁ\98N¿\94I½\92DÃ\9aKÏ¢UФVÓ©XÔ«XÖ²aÙ¶hݾpàÀuß½sزiÕ±eÔ¯g×±kÙ´mܺpß¾vàÀwß¾wâÀuäÁ{à»tÞ¸yÙ³oЩ_É¡ZÌ¥_Ä\9bR¿\95S³\8bDª\7f9¨z@\9ar7\99p3\9br2\8fe$\82U\1axO\18sO\12rM\17tK\15qH\13f?
+]=\vhE\11nE\10xQ\18{U#\80W$sQ\1erQ\1coI\18mH kD iA\egC\ef? V7\1aL0\14K0\12M.\ fH,\fF*
+I.\ eH/\rH-\rB+ B(\bA)\b:%\ 5<'\a;%\ 5?'\ 6?%\ 5E,\vE+\vF+
+N1\11N0\10W7\19X7\14jC\1atJ!wN%mD\1ae=\13b:\13Z4\ eV0\rU,\bU-
+X/
+[2\ e\5\11_4\ f\1\fX1\vU. S/\bQ-\ 6J)\ 5E%\ 4G%\ 4E(\ 5E)\ 4G(\ 4H(\ 4D$\ 3H)\ 4K+\ 6L*\ 4S-\ 5X1\a[1\ 6]4\bc;
+^3\ 4d: d8\ae8\ 4g8\ 2h9\ 5k;\ 3j9\ 4j9\ 3l;\ 4n;\ 4o<\ 3n=\ 4p=\ 3{I\b\80M\f\86R\ e\88Q \8bX\12\8aX\r\90\\12\8d\\11\90`\13\96f\19\99g\e\9ek"\9dl \9dj\1f\9bh\1d\9ci"\9bh!\9ag#\96f%\93b"\81^#bS![M [O%[P&^O#cS(hV.\88|ZÓ̶ÛÓ¼ßÖÁÝÕ¿ÞÕ¼ß×ÂáÚÃâÚÅâÚÄäÜÉäÜÅäÛÅãÜÆáÚÄäÜÇåÝÈäÜÆãÚÄá×Åá×ÅáÙÃá×ÄâØÇÞÔÂàÕÄàÕÃâ×Åà×ÃÞÔ¿ÛÒ»ÙϹÙϹÙкÚкÚѽÙÏ»ÚÑ»ÞÔÀÛѼÚÑ»ÙϺÝÓ¾ÚѺÚѹ×ζÕÌ·Îú¯\97§\99\81\95\83n~kTv`KrX<sW5mN1cF']A\1fO5\ fO5\15R8\1aN/\ fL/\fH.\vL0\ f^>\1da=\1aoK"yT$\82Y(\82["\8eb$\96k,\99l'\9dq-¢x=±\89R¹\8fO¼\94T¸\93T¸\91Q¸\93T¸\91Pµ\8eLª\83C¬\88Dµ\90M¶\8dK´\91N¸\92M¯\86>¬\86=«\88?±\8cDµ\93I¸\93H¹\92K¹\92G¾\97O¾\94JÀ\98N̦ZÕ¯^Ö²aÓ²fΪ_ͧbÕ³lÕ´kÖ¶k×´kÕ±kÑdÕ°gÚµkÙ¶l×°hزeÛ·kÛµiزlÚ¶nÙ±kЩ`Ô®cØ´hÖ°mΧdÇ\9eVÄ\99YÄ\9d]À\98S¹\90I¿\93R¬\80@\92a\1c\86Y\1e\88]&\86Y\17\83V\evS\14tQ\16sK\12pI\ ewO\12\80X!\89`$\8ba%\8a[\1e\84S\1axJ\enE\1dqJ\1frI\1aqJ%Y7\15K.\rQ3\12Y8\11`@\17U6\fL/\ eD.\fI/\rH0\ eI1\ eI/\rG/\f?&\ 5>)\a;%\ 6:%\ 4?%\ 5?&\ 6D+
+B)\bB&\aD* C) P1\fa>\17a<\13e>\16d=\14e?\14f?\19_<\15_5\ f[5\11Y3\12Y/\fX0\r^3\11b6\13e8\13b6\10c7\11`6\r]2\rW,\ 6T+\ 4K)\ 3I+\ 5H)\aH*\ 6I'\ 3G(\aC'\ 6H&\ 4J%\ 3J&\ 3M*\ 3O+\ 4P*\ 2R,\ 4U/\ 4[3\ab7\b_4\ 5f6\ 3f6\ 4i9\ 4k:\ 4j:\ 3k;\ 3l;\ 4l<\ 3i7\ 3uB\ 4{F\ 4\81N\f\86S\r\87S\f\8e]\14\91]\14\91`\17\94c\1e\98g"\9ci ¡l#¢o%¦r(\9fk\1e\9af\1e\99f!\97f!\96e%\95d$\80Z ^M\1eWM\1eZM&ZN$cV1bV,lZ2\9a\8cqÓË®ÞÕºÝÔ¼ß×Áà×ÃÞÖÁÝ×¾áÙÄåÝÈãÜÆáÙÂãÜÅäÜÆâÚÄãÛÆâÚÅäÝÈãÚÅäÙÈãÙÈàÕÄãØÇãÙÇãØÇá×ÅàÖÄâØÆâÙÆáØÃáØÃâÙÄßÖÀÜÓ½ÝÔ¾ÜÓ½ÜÓ½ÚѺÙϹÚйÛÒºÚÑ»ØϹÚѺÚÑ»ØθØιÜпÜÒÀÚÑ»×͸ÒÇ´Á¸¡¯¤\8d\99\8an\87s\\80hM{`GgN,qU6aF\1fP4\fL2\ eJ4\14J3\15H*\ eQ4\12P8\12N7\r\<\10gC\ fwS\1e|U\1f\84U \8a`*\92i)\9bs:\9du5§z@²\84K¸\8eO½\93Vº\90Q³\89J·\8dN³\8fO·\93R¸\94Qµ\91P¯\8dG«\84:£\7f5\9bv+\9dv%¨\87>°\8bA²\8eE´\8dE¶\8fF¸\8fFº\91Kº\92FÅ\9dQÏ©YÖ³`Ñ«`É£^ͧaÆ\9fXÏdײk׶n×µiÓ°eЫ`Õ°dÔªaѨ_Î¥WË\9fVÆ\9aRÄ\9bQÏ¥bЧbЧ^Õ±fݹmâÀsÚ¶kÕbϦ_̤bÊ\9f^É\9cWÄ\96N½\92G³\85?¦t2¦w.¦u:\9cl.\88_%\82T\12\81T\19\83Y\17\87`\19\8aa\1f\89`"\85\\19\83X\1cyN\18pI\ fsJ\17lF\fiF\14Y9\ eT5\rU3\ fa=\13gB\14nG\1anJ!cC\1aW:\ fN4\rQ6\11P5\vN5\ eL0 C,\a?'\a>'\a='\aA+
+D-\fF-\fB*\b?(\b;!\ 3?&\ 3<!\ 3=$\ 3C(\ 4F+\ 4M1\fW6\12Z5\10\7\10b:\16\7\15X0\fU, Z/\r[1\ e\1\ f`5\10a6\10d:\12e;\13b7\10d8\11g8\10f:\16^4\ f^3\r]1
+[.
+T-\ 6M)\ 3M(\ 3O)\ 3L'\ 3N)\ 3K&\ 3J&\ 3P(\ 3V.\ 4`4\ 5a4\ 4].\ 3a2\ 3b4\ 3i8\ 3h7\ 3m=\ 4p@\aqA\ 4n>\ 4qA\ 6wE\ 6~L\ e\82P\r\85R\r\89V\12\8bW\12\90\\17\90\\18\95d!\97a\1d\9ci!£n)¢p( l%\9ch#\9ci*\97g%\96d&\94e&vT\e^N\1fZN#[N(\O)`S.cV5j^<¥\9b\82ÖδÜÓ¹ßÕ¼ÚÒ¸ÜÔ¾ÝÕ¿ÝÕ¿ß×ÂáÙÄâÚÄâÚÅàÙÃãÚÃâÚÃâÛÇàÙÃâÚÄäÚÅåÚÉãÙÈâÙÅâØÆäÙÈáØÅá×ÅàÖÅá×Åá×ÄâØÄáØÃá×Âà×ÁÝÔ¾à×ÂâÙÃà×ÁÜÓ¾ßÖÀÛÒ»ÛÑ»ÚкØйÚѹÙ϶ÜÒ½ÚÑ»ÛпÝÒÂÛѼÜÒ¾Ö͹ÚÑ»ØϹØηÕ˵ù£¶§\92§\98\81\92\81b\83nKrZ7sZ=jT5`D'_B&\B$P6\19L4\12M0 P1\ 4L3\aQ;\ eb?\14kH\19pG\15zR&\84](\93f,\97l8£{B«\83I¶\88M¶\8fQ´\8fN½\99Z½\9a[¸\94V¸\90P³\8eM®\86A¦}3\9ds'\9dq%\9bs& v+\9fw/¦\80:\89A²\8bD¶\91N½\93H¼\92F½\96IÂ\9cMÌ©\ЯdÖ´lÕ´lÕ³jÒ®dÑc×µmÖµpÔ±jÓ¬gÓ«gÒªcͦ^É\9fY¿\95O¾\95OÅ\9bUË¢YШ^Ô©_Ö¬^Û²hØ´iܶh߶nÝ·rÔ©iÇ\9bUÄ\95QÇ\97QÂ\92LÂ\8fGÈ\9bQÇ\9cTÁ\92G´\87>ª|6\9fp,\98j"\93c\1a\8b[\r\85Y\13\89]\1a\80X\16\85Z!yQ\17uN\17nH\12gD\ f_>\ eR4\aP3\ 6W;\rdB\ foL\18vQ\1dwT$jI\17eE\1c`>\12eC\19bB\17hE\1dX7\ eP1 Q3
+K/\bJ/ G.\bG.\aE+ B*\b:"\ 35\1e\ 38#\ 4;#\ 4<#\ 5<#\ 4?&\ 5>"\ 4C&\ 6G(\aN-\vR1\11V1\11W1\11U/\10W0\10V0\fY3\12X0
+X0 V1 \7\13`:\17j;\14sA"o?\eh:\14m<\17sA\1fh9\13]0 \/\ 6]0 Y/\ 5Y-\ 6Y,\ 5[0\a[0\ 4\1\ 4`1\ 3a2\ 3].\ 3_0\ 3b3\ 3i7\ 5i7\ 4j8\ 4p@\btD
+l;\ 3n>\ 4sC\axH\v|J \86P\ e\88T\ f\8bY\16\8bX\15\8cZ\15\8bX\14\92_\1e\92`\e\96e\1d\9ag"\96d \94b\1e\91^\1e\93`"\93d'\8ee-uY#YL\1fVK\1fZN#]Q(_S+_R/i]9°¥\8dÚÑ»ÜÒºÜÒºÜÓ¾ÛÓ½ÛÓ¾ÝÕ¾ÝÕ¿ß×ÂáÙÄáÙÃâÚÅáÚÄàØÂß×ÂáÙÄâÚÅäÙÇãÙÇâ×ÆáÖÅãÙÈäÙÈãØÇãÙÈãØÆâØÆäÙÉá×ÅáÖÄßÖÁßÖÀáØÀà×ÁâÙÄáØÂãÚÄà×ÁâÙÄßÖÀáÖÅÞÔÀÝÔ¾ÜÓ½ÚÑ»ÜÒ¼ØκÚѺÛÒ¼ÚмÙϼÙϺÝÓ½ÜÒ½ÝÔ¾ÛÓ½ßÖÀÚѺÖͳÌÁ¦À´\99³£\89\9b\86k\90za\82oOvd=w[7iM'gO#\D\16I5\ eK4\11R7\fY?\16]A\18aB\1fpN${U"\83a-\83\*\8cc3\91h3\99l:§~E¯\88G²\8eOº\92Q·\91Qµ\91L³\90J²\8eJ¬\89C«\88G©\84?¥}9\9dt1\99p0¥}:«\83Cº\93M½\96LÇ¥Y¾\97Hº\93HÂ\9bQÂ\9dPÊ¥\ЬbÓ¬eѬeÏ©^زjÓ±iЬbË£^Å£\ɤ[Ì¥aÃ\9bSÁ\99TÁ\98TÁ\98OÆ\9dTÈ\9fVË¢XÒ¥]Í¥]Í¡Uѧ]Ó§aÕhׯkÑ©bÈ\9fUÇ\9cRÂ\96QÄ\97OÏ£Yש^Ô§ZÒ£UÏ RÍ\9eTÂ\92G¼\86?¸\84;«x7§v4£u0¡q.\90g&\8dc$\83W\15wN\17qK\14aA\faB aB
+gD\ enG\13qK\17uO\1arM\1ctL\eqK\19rK\18sL\1fsL\1ftM vP$pJ\1dlG\1a`<\15P3\10Q6\ eL1\bC)\ 4@'\ 5C* :"\ 39"\ 37#\ 36 \ 38#\ 4<&\ 58"\ 3>%\ 5B(\bC'\bM+\ eL,\rM-\fL+ M-\bQ. Q-\vN.\vH*\aF)\ 4M/\rX3\ fa7\12c:\19b8\11j<\18sD!rC\1cj<\17l<\13p@\15sA\17j<\ff7\bh7\aj:\bd3\ 4d5\ 3`0\ 3]/\ 3d2\ 3g4\ 4j8\ 5g5\ 3i7\ 3p>\bp@\ 6l<\ 4g6\ 3l<\ 4qA\ 4wF\ 6\7fN\ e\85T\12\88W\16\88W\15\8bZ\18\8dZ\15\90^\1a\8e]\17\91a\19\95c\1c\90]\e\87U\13\87S\19\82P\1d\84["\80^'hQ#[M!ZN$]P*[O(cU/dX2rgDÁ¶¢ÚкÛÒ¹ÝÔ¼ÛÓ½ÚÒ¼ÛÓ½ÛÓ½ÝÕÀß×ÁàØÂâÚÅáÙÃáÚÄß×ÂàØÃáÙÄâÚÄäÛÉãØÇãØÈäÚÉâØÆåÚÉãØÆãÙÇãØÇäÚÅâÙÅâØÅãÙÅãÚÅáØÃá×ÁâÙÃäÛÆá×ÂäÛÅâÙÄâÙÃáØÃáØÂáØÂà×Âà×ÂßÖÀà×ÁÝÕ¾ÝÔ¾ÛѽÚмÛÒ¼ÛÒ¼ÙкÜÒ¼ÞÕ¿ÝÔ¾ÜÒ½ÛÓ»ÝÓ¼ÝÔ¼ÛѹÜÓ»ÚкÐƪĺ\9b¸«\91¤\94{\96\86m\81qMt`>fR7cJ-]G W?\16K8\16P=\eM8\13U:\15fM(tV-pO%qN wM\e\86]&\8dg.\96p8¨{=¦y>¥x9«\83@°\88C¯\87D®\86G\87G®\89I¥\7f=¦~=¥{5¤\7f;¦\82;¬\89Bµ\93I¹\94I½\9aUÁ\9dVÀ\9bSÀ\9cT¾\9aR¾\9bSÇ£`Ê¥\É¢VÈ£WÊ¥YÅ\9cPÁ\99O¾\98RÅ\9fWÊ\9fWÉ YÇ\9f[Å\9bWÅ\9bUÀ\95OÅ\98OÅ\99OÄ\96MÂ\99NÂ\99NÅ\9aOШ_ÔªaѧYË£VÎ¥[Ë UÈ¡SÍ¢UÔ¨`Ó¦\Ó¦]Ù¬aØ©Yب[Ö¥VÎ\9fKÒ\9dRÓ¡ZÎ\9bNÊ\95JÅ\95L¿\8b=º\87?©z9\92g!\86]\1c\86V\ e\85Z\15\84Y\16\80S\12wP\15yM\14|R\19~U\1d{Q\eyO\1ctI\17uJ\17vL\1cuN\1dvN\1eoI\elE\18jH\egE\1ciL!hM$gL$_B\1cY=\11[@\15F.\ 6:&\ 36"\ 3;(\ 68$\ 38#\ 39#\ 4<%\ 5C&\bD(\ 6B(\ 6@%\ 5@&\ 4H+\bJ, G)\aF)\ 6F(\ 6I)\aK* Q- T.\rY2\ eX0\r]4\11b5\13c7\13n;\13uB\17yE\16vF\14q?\ fq=\ro9\vi8\ 6l= i9\ 6i6\ 4k9\ 6l: i9\ 4k8\ 3g4\ 3h8\ 4h7\ 4k9\ 6k9\ 5n=\ 5pB\btE
+uG\10}O\14}R\15\7fS\13\85Y\15\8b\\16\86V\10\86Z\12\8a]\1a\8e`\1f\93c#\8c\\1a\82R\15zM\1atM\17qS#gO!\J\1c\Q']J&ZO&ZM(aT/ulIÊÀ§ÙÑ»ÛѺÛÒºÙѼÜÔ¾ÚÒ¼ÜÔ¾ÝÔ¾ÜÓ¼ÞÖÁáÙÃàØÃàÙÃáÙÃáÙÃàØÃÞ×ÁäÙÈãØÇäÙÈãÙÈåÚÉäÚÈäÚÉâØÇãÚÅâØÃãÚÂâÙÃà×ÁãÚÄãÙÄãÚÅãÚÅãÙÄãÚÅäÛÅâÙÃà×Âá×ÂäÛÆäÛÅâÙÄà×ÁäÛÅáØÃáØÂá×ÅàÖÅá×ÅàÕÄÞÓÂÝÔ¾ÙϹÝÓ¾ÛÒ¼ÚлÝÔ¾ÜÓ»ÜÓ»ÜÒºÞÔ½ÜÓºÚѸÛÒ¹ÝÔ»ÜÒºÓʳËÀ¥¾´\9b¬\9e\85\9f\8ft\81oNsc>gZ9gT&hR([D\17X>\1a]<\13E5
+V9\10W:\ eb?\13qH\19yS$\87^'\8b]!\94e-\99n.¡v5¥y7§|8®\7f=®\84A\86A¨\80@ {4¦\82:¤\7f:¥\83<¦\82;¬\88B²\8fF½\9aX¿\9bS»\97K¾\99T½\9bX¾\9c\¼\98P¾\9aQ¾\9bU¾\99P¼\95Mº\92Iº\91I»\93IÀ\94IÇ\99PÆ\9dZÆ\99TÅ\99RÀ\98NÀ\96KÁ\95JÁ\90K¾\91CÁ\94AÇ\98JË RÎ\9fRÊ\9dOΣTÒ¦XÐ¥TÑ¥WÔ¨ZÔ¨[Ó¥]Ô¦^Õ§]Õ¦[Ö¨ZÚaÚ_ß±bÜ®eÚ«^بVبYÖ§XÔ£VÇ\98GÁ\92E¾\8eA»\8c?²\84<©y1\9bl&\8d`!\8aY\e\89\\e\87X }T\14~S\1euL\16xM\19|Q\1eyR\1dpI\15aA\ fmC\15nM\1ewY.{a7\82g;\80b2uS*tR'qQ#\B\12I4 D2\vH1 E-\ 4A*\ 4;'\ 5@(\ 5@'\ 6>%\ 5<%\ 5;%\ 58"\ 39 \ 3=%\ 5?%\ 5?%\ 5B(\ 5C'\ 4E)\ 6H*\ 4P- R0\vR. Q,\bU.\vX4\fa4 q9\14t>\16t=\11vA\15u=\11v<\10u>\ euC\10s?\rr8\ 6wA\fuA vB s>\ 6s>\bm=\ 5i9\ 4f5\ 3m;\ap@\bq? i<\ 6g= oG\rqH\11oF\ ewO\15vN\12tL\10tN\11yQ\12\80[\1c\88^\1f\84X\16vL
+tI\ ftO\1ciP#bN"[I\1aXJ"^Q-_R-]R'e[2\88\7fbÌæÙ϶ÚиÚзÙÒ¹ÝÕ¿ÜÓ¾ÛÓ½ÚÒ¼ÛÒ¼ÞÖÁáÙÃâÚÄâÚÅà×ÀâÚÆàØÂàØÃæÛÉãØÇãØÇäÙÈäÙÈçÝËåÚÈâ×ÇâØÄá×ÅäÚÈâØÄãÚÅãÚÅâÙÃãÙÄãÚÄâØÄäÜÆåÜÆãÙÄäÛÆãÚÄãÚÅãÚÄãÚÅâÙÃáÙÃâØÃâÙÃâÙÃßÕÁâ×Æá×ÅâØÄá×ÂâÙÃßÖÁßÕÀÞÕ¾ÛÒ»ÝÓ»ÞÕ½ÛÒºÞÔ½ÞÔ½ÜÒ»ÞÕ½ÝÔ¼ÛиÞÓ»ÜÔ¸ÚÒ¹ÜÒºÖ̲ÑÇ°¿¶\9c³¬\91\9e\92s\8f~]\84qDxa>oU.ZI%ZA\1dY@\1dY;\15]=\16dA\19kG\14qN\14yU\1f\84](\89_)\9ar8\9ap0¡y7¡t3¢x5¥|=¦\80>¥\81>¢}:£~7 {4§\81>®\8cI³\91M®\8dI¯\8bG±\8dK´\91P±\8fN«\87D·\92Q¶\94O·\93O³\8fM²\8dF´\8cF°\87A¦}9\85@µ\8bK\82?µ\8bI»\92L¿\94I¾\93G¿\91H¾\91FÁ\93GÃ\98EÊ\9cMÉ\9cPÊ\9eTϤWÐ¥ZΣVÌ\9dLÍ\9fRÎ XÎ\9fVÒ¤\Ó¥\Ì\9eUÌ\9dPÏ¡RÙ¬`ܱ^àµgÞ´fݱ^Ú`שYÓ£QÔ¥RÏ\9fKÊ\9bJÈ\9bJÉ\99JÈ\9aP¾\91D½\8dF¸\8aH¤x3 o,\8eb#\81S\12|Q\11\81W\e\80V\17}W\1asM\10a<\ 5e@ fF\12hL\19wX"\82^.\85a.\82]-\7fZ(~\'jK\18aG\18X>\ f]C\15Y?\ fO5\aP:\ fO8\ fF-\ 6@*\ 4C,
+A*\b?) @*\b=#\ 3=&\ 58 \ 3<$\ 3=$\ 5@'\aB'\ 6G+\aI,\ 5L+\ 4H(\aG'\aJ)\aP-\vV.\ fU.\ra5\12b5\ri8\rn9\ el5\ 6o< t?\ fr;\bwB\f{G\10yB\bzD
+}H\10vE zH\ exG\ ewE\ ftD\fj<\ 6e;\ 5e=\vmF\10iA
+kB\ flF\12jD\10iA\rhA\rh@\rqF\11tN\19nH\12_;\ 6`?\ e^E\19`N$ZK#YO#WJ"ZM(^Q+\P(cW/\94\8bnÔÍ´ØϹÚѹØϵÙйÚÒ½ÛÒ½ÛÒ¼ÛÓ¾ÝÕÀß×Áß×Áà×ÂàÙÃß×ÃßØÅÝÕÁàÙÆäÚÈãÙÈäÙÈäÙÈãÙÇâØÆâØÇãØÇåÛÊäÙÉäÚÉãÙÈàÖÁáØÂãÙÄãÚÅáØÂâØÁåÛÇâØÈäÛÆâÙÄåÛÆãÚÆáØÂáØÃåÜÇãÚÇâÚÆäÚÆáØÄáÖÅáÖÅâÙÃãÚÅáØÂâÙÃà×ÂáØÂãÚÅâÙÄßÖÀßÖÀà×ÁßÕÀßÖÀÜÓ½ÞÕ¿à×ÁÛÒºÝÓ½ÝÓ½ÛÒ½ÜÓ½ßÖÀÝÔ¿ÜÔ½ÛÒ»×δÖγǻ\9f¶©\8d§\96}\93\84b\87rW}b@mY6gM)aD\12^@\ egM\16gM!\=\ fhF\10qO\19\82[$\83^&\8ef0\95j2\94h1\9dv9¥\7f?¦\7f=£z9\9ex6¤~>¨\84A²\8fK«\88F§\83A¨\83B¨\84@£~6 ~;\9fy7§\83?\88A°\8dL¯\8cK¬\87E¨\84>£~:¤~<¡x6¦}<ª\81A±\8eLº\92NÀ\95L¾\91H¿\91C¾\8fA¸\8b<À\90>Ä\98JÆ\9cSÊ YË¢XΣVÉ\9cJÊ\9fLÆ\99IË\9cJÎ\9fTÎ MË\9cLÉ\9aIÈ\98GÌ\9dNÎ MÒ¥QÔ¦SФQΡMУPÒ¥SѤPÒ¡NË\98HÅ\93@Ä\94AÂ\94EÇ\9aLÇ\9aNÅ\98P¿\93J¹\89A¯\81B«\7f<\9fr0\95j*\8a^\1a\8a]\1d~V\13tM\ 5vM\brH\rnL\12oG\10uM\11rK\10vO\19{V#xS\1erL\15jI\18qM\1aoI\15iE\17bE\16\@\11[<\ eX:\ eV8\rQ7\vP5\vP7\ eU9\13P5\vC+\ 5@(\ 6=#\ 4?#\ 3@&\ 5A(\ 6?%\ 4D*\aB(\ 5A'\ 4?%\ 4?#\ 5C&\ 4D%\ 4E(\ 6F&\ 4S/\aX.\aZ/\ 6[/\ 4^1\ 4g7\ 5l:\bvA\13wA\11yA\rzD\ f}H\13\83J\17\82J\14\7fG\10\81J\13\82R\e{M\17|M\19wM\exL\18rH\10rJ\11rL\11qK\17jE\10hA\fa9 g: f?\r`< Q2\ 4O2\ 3T<\ fYH\eVG YM"^Q,_R/ZN)]Q+dW2£\99xÐÉ«ÔÌ´ØÏ·ØϵÛÓ½ÙѼÙÑ»ÛÔºÛÓ¾ÞÖÀß×ÂàØÃß×ÁÝÖÀß×ÂàÙÂÞÖÀß×ÂâØÇãÙÇãÙÇäÙÈãØÇäÙÈäÙÈâ×ÆáÖÅäÚÅâÙÄäÛÆãÛÅâÙÄâØÃâÙÃâÙÂáÙÂãÚÄâØÅãÙÅäÚÅäÛÆåÛÇåÜÆäÛÇãÙÄåÛÇâÚÆåÜÆãÚÅâÙÃãÙÇäÛÅäÛÆäÛÆâÙÄâÙÄåÛÆäÛÆãÚÄâÙÄãÚÅåÜÇäÚÅãÚÅáØÃâÙÃßÖÁÝÔ¾ßÖÁÝÓ»ÝÔ¾ÞÕ¿ÜÒ½ßÖÀÞÕ¿ßÖ¾ßÖÀÜÓ¼ÜÓºá×ÂÛÒ¹×δÍĪ¿³\94³§\8a£\94u\8c}U|i=yb0sa=^F!ZC\13cE\1adA\15eD\13kE\18rI\15\82X(\8fi8\99r7\9fv8¡w3 w7£}=¨\82A«\86D«\88G¦\81=¤}=¤\80<¤~7\9ev4\9dt5\97q-\9ey4¢};ª\84E£~<¦\82<¨\82B¥\7fC¤\7f=©\80@©\80@¤\80Aµ\90N¼\93P¼\92L¾\95I½\95I´\87<·\896®\842³\89@´\87A¿\93JÅ\99RÅ\97KÉ\9cJÊ\9eOÇ\97HÊ\9bMТSÏ¡LÊ\9bNÇ\95FÅ\93CÆ\97MÅ\95GÇ\98IÉ\99JÇ\9bLÈ\9cNÂ\95EÅ\96GÊ\99GÇ\97FÇ\98DÆ\95CÂ\93I¾\90B»\8eA»\8eB¹\8b?Á\92IÃ\96Q¼\92H»\90K±\88C²\85@~8©z/¡t,\98k#\90b\e\84W\16\81R\18\81R\15zR\15\83Y\1d\87\"\84^%\85Y\1f\81V!\85V\1d\85U\18zL\11mG\r^=\b^>\bfC\12lH\18pN!cJ\1daE\14eK\13^C\12R6\vL4\rN5
+O4\ fP4\10L3\fE+\ 6>&\ 4>%\ 3>%\ 4>%\ 49\1f\ 3<"\ 3;\1f\ 3:\1f\ 3< \ 3C$\ 3K%\ 3N&\ 4N)\ 3Q)\ 3X-\ 6V*\ 5[0 `3\ve5\bd6\vg9\rpA\13{I\17xC\ e\83O\1f\85R!\86V#\81S!\86Y&\86X \86X \88^$\85^\1f\8cf/\85a+|T"nK\1anM\elI\1ac;\fT6\bK1\ 6P7\vUD\14XH\1dWK [N)]P-^P+`T,g]7³ª\87ÒɪØϸÙиÙѸÙѹÙѼØкØѹÚÓ»ÝÕÀÞÖÁßØÂÞÖÁÞÖÀÞ×ÀàØÃáØÃß×Áâ×ÆàÖÄâ×ÆáÖÅâ×ÇãÙÈãÙÈâØÆà×ÃâØÃáØÂáØÂáØÃâØÅäÙÇãÙÅãÚÄâØÇâØÇãÙÅäÛÆâÙÂâØÃäÛÅæÝÇåÜÆäÛÅäÛÆåÛÈãÛÆãÚÄâØÃãÚÆâÙÃáØÃãÚÄâÙÄãÚÅãÚÅäÛÅäÛÆåÜÆäÛÆæÝÇäÛÆæÝÇæÝÇåÜÆäÜÅãÚÅãÙÄßÖÁà×ÁÞÕÀßÕÀßÖÁàÕ¾ßÔ½ÞÔ¿ÛÒ¹ÝÔ»ßÖ½à×½ÜÓºßÖ¾àÖ¾ßÖ½ÚѸÒÊȾ\9f·ª\83\9c\8fp\89yYyjGqY1mP&cM ]C\19^=\vd?\10nM%\81[+\87\'\93h/\97p9\9bs5 y8 ~>¨\83H©~?§~@¬\81=¨\7f:£~8\9ey6\9au/\96p-\9au3\9bv8\9f{=¤~;§\81A¦\82A¦\82A¦\80A¦\7f=£\7f>\88G¯\8bKµ\8eF·\91F½\96Jº\91D»\91A´\8d=\837«\7f5¯\805«\7f8±\83=µ\8b>º\8fD¾\8fDÆ\96JÍ\9eUÍ\9bKÆ\96EÂ\92E¾\8dC·\86:»\8b:À\91BÇ\9bLÉ\99JÆ\97GÄ\94GÀ\90C¹\89:¾\8b7À\91;É\9bHÃ\94B»\8c8¹\8c>¯\7f3³\838´\82:°\81=°\847½\90BÃ\94LÇ\9aTÇ\99S¿\91G¹\8cB³\86=¸\88:´\823°~5¦v4\9et1\9do,\9dl'\9fp-\9cn(\9en,\9bl)\98f(\91b \88\ |T\1cxQ\17uL\12vQ\1crM\1fkL\18hI\12mL\15iI\15fG\14jJ\17kJ\12a@\ fW;\ fW;\vX<\ fF.\a?'\ 3>&\ 4A(\ 6B(\ 4;#\ 3<"\ 37\1f\ 38\1c\ 3<"\ 3@#\ 3A$\ 3D$\ 3F%\ 3F'\ 3K)\ 3J)\ 2L)\ 4N,\ 3Q/\ 5P.\ 5X7\v_5\b`5\fh=\11uG\17wI\16\7fO"\80T$\83S!\8cY"\8da(\92h/\93k2\90j0\8cc+\8ab.\81[&\7fX#pK\17jE\13`A\13X@\15WF\eTH\1cXL#ZM&\O)\O,bU/xmN½¸\9dÕÌ°ØиÖηØγÙÒ¹×зÚÒ¼ØкÚÒ¼ÞÖÀß×ÁÝÕÀáÙÃÞÖÀß×Àß×ÂÝÕÀÜÔÁâØÆá×ÆâØÆáØÅá×Ãá×Åá×ÅãÚÅá×ÂãÙÆá×Äâ×ÄâÙÃâØÄãÙÄäÛÆáØÂáØÂãÚÅáØÄáØÂâÚÄâÙÃâÙÃãÚÄáØÃâÙÄãÚÅãÚÄâØÆáØÂãÚÅäÚÇäÛÆåÛÇãÚÄãÚÅäÛÅâÙÃåÜÆãÚÄåÜÇæÝÇåÜÇæÝÈçÞÉåÜÇèÞÊæÝÈåÜÆäÜÆåÜÆäÛÆäÛÅâÙÄáÙÃà×ÁßÖÁà×ÂßÕ¿ÞÕ¼àÖ¿ßÖ¾ÝÕ¾àÖ¿âÙÀÞÕ¼àÖ¾àÖ½ÞÕ¼ÝÔºÛÑ·ÔÈ®ËÀ¨½²\95¤\9ar\92\86`\81tLmY1eO*bP$`H\1ciJ\1clJ\eoL\1c\80V'\87`.\95m3\96n/\9an0£w<©\7fB«\81@¨\7f;\84A¨\81=\9fy7\9dx8\97s2\9av7\9dw8¡z= {>\9f{> x=\9cx9£\7f@¤\81B§\84D«\84D©\84<¤\83;ª\826º\8fE¼\94H²\88?«\815ª\804©}6£w0¨z2«}4©{3·\88>¹\8aBÁ\93IÄ\97L¼\8dE·\89Dµ\86;\7f/³\863¶\882½\8e?Á\92DÄ\94GÇ\97KÁ\93B¼\8b6º\896¿\91?Å\96CÅ\95DÃ\93CÁ\90A¼\89?²\836©y/«}-´\869Ã\94IÈ\9bPÍ [Ê\9bSÅ\97IÈ\98NÏ\9f[É\99GÊ\9aFÈ\99IÊ\9aQÅ\95HÁ\92A½\8bB°\814©x/§v.¥r(¦r+ o,\9el'\99j%\8e`\18\82V\15xR\19sM\18nM\18lJ\17iE\10lH\14zS"xT\1fuO\1akH\13sN\1avP\1fbC\13O7\vR7\fZ<\12R5 P4 P8\rC/
+:(\ 3@(\ 5B(\ 3E+\ 4H*\ 4H*\ 3G*\ 3G)\ 3M,\ 5L-\ 5I*\ 3G*\ 3I(\ 3J*\ 3K(\ 3O+\ 4O*\ 3X2\ 3b9\ 5h=\vh?\ eqE\16{L\1a\83X#\84W!\88_(\8fc0\90b.\8aa-\8b`+\82X!~M\18|N\19qI\18`H\19TC\16UJ\1eWJ"ZO$ZM(^R-`R,\82xXÿ§Õ̳ÖεÖκÚкÙлÙÑ»×ϺÚÒ¼ÛÓ½ÝÕÀÝÕ¿ÝÕÂÞÖÁÝÕÂß×ÄÝÕÀß×ÃÝÕ¿áÖÄßÔÃÞÔÂà×ÄáØÂà×ÄáÖÅá×Ãá×ÂßÖÁáÙÃãÚÅà×ÂãÚÅäÛÅåÜÆáØÃâÙÃáØÃâÙÃáØÁáØÃâÙÄãÙÄãÙÄäÛÆäÛÆãÚÅãÚÄâØÄãÙÇäÚÇåÚÈäÚÈãÙÈæÜÈãØÆãÙÈçÝÉäÛÆãÚÄåÜÆåÜÇæÝÇèßÊæÝÈçÞÈæÝÈäÛÄãÚÅåÛÆãÛÆäÛÅåÜÇäÜÆçÜÊãÚÇãÚÅäÛÅáØÃà×ÂàÖÁà×Áà×Áà×ÂÞÕ¿ÞÕ¼á×¾ßÖ¾ßÕ¿ÞÕ½ÝÔ¼ÞÔ¼ßÖ½ÜÓ¹ÛÓµÕϵÌĬº±\96®¢\88\9b\8bk\87xTp_5jV.gP(eE\1cdD\13xR\1e|R\18\7fR!\8b]*\8d`&\96h,\9en4\9eq5¦|?¤}@£{;§\7fD¤\7fG\9fw;\9fw;\97n3\9at8\9ar6\9as:\9bu< |B£{B\9dx:\9bw5\9au.\97r)¥~8\85;ª\828ª\806ª\817¦~5¬\838«\80:¨|9¤x3¨}8ª\80:¬\826·\88Aµ\88=¯\86@¯\818©y,°\806¯\816µ\86;·\88=¿\92D»\8dC½\8d=¾\8e=À\90?¿\91=Å\94@Æ\95CÇ\97IÃ\93AÅ\97IÂ\95C¼\8eC«\824±\816»\8c@Æ\99KË\9eTÍ\9eUÍ\9eRÍ\9eSÆ\95JÎ\9dNÑ¡Oש_ש`Ù¬^Û`Ù®ZЦWË\9eNº\875º\83/¶\836·\85=°\7f6¬|1ªx2\9em!\97j&\8cc!\8de,\82^&~X!{S\19|R\17|S\1a|U\1c\80W%\83X \83U\1dzU\18qK\15qK"hF\16hF\12oN\1cdB\12`C\18R;\ eR8\rS7\vS8\ eN4\fH*\ 3I+\ 5H-\aG*\ 4H+\ 3H+\ 4E'\ 3E&\ 3I'\ 3A$\ 3E'\ 3G%\ 3O.\ 3Y5\ 5\6\a[8\f[7\ 4b;\vhB\14nF\18qK\19wO\1ewP\1eyO!\80S |P\1d{L\17{R vT!fM\1fUF\1eWJ$VI"YK&YL'\P*_R-\92\87lɨ×͵Ö϶ØÑ»Ùз×к×ϹÙÑ»ØлÛÓ½ÜÔ¾ÜÔ¾ÞÖÁß×Âß×ÂÜÔÀÞÖÄÝÕÁÛÓ½ÜÓ¾ßÔÃßÕÃàÖÄàÖÃÝÒÀßÕÃá×ÅàÖÄÝÓ¿â×Åà×ÂÞÔ¿á×ÃáØÃãÚÅäÛÅâØÃãÚÅâØÄà×ÃáØÃßÖÁâÙÃà×ÃâØÃäÚÄãÚÅâØÃâÙÄãÚÅá×ÄãÚÅæÛÊäÙÈæÛÊåÛÉäÚÈæÜÊåÜÉäÛÆæÝÇæÝÇçÞÊæÜÈæÝÆæÝÈæÝÈæÝÈãÛÅåÛÆåÛÉæÝÈçÞÈåÜÇåÜÇäÚÆäÛÅçÞÉæÝÇâÙÄåÜÇåÜÇäÛÅâØÃâÙÃàÖ¿ßÖ¿àØÀâØÂà׿ßÖ¾á×ÀáØ¿áÙÀßÖ¿ßÖ¾ÞÕ¾ÝÓ»ÜÒ½ÔʱÐūú\9e¶ª\8f\99\8cm\88yQxc6jY-jN d?\ eiE\13tM\19yO\1c\86Y$\87]'\91d.\98k4\9co3¥zC¨}C©\80E§\80C¤|A y>\9dv:\9du9\9ew8\9fz:\9ew7\9cv7\9au4\96q+\94n+\9eu/£z2£{.¥|4¨\829¦\82:¯\86=²\87C¨\82A¥v-¦|6¡w0\9eo#£t,¤w.ª\7f8¬\825«\803±\86>²\87A¶\8bA¹\8a=»\8b@¼\8c@À\93DÄ\94DÃ\93CÆ\97FÉ\99HÈ\97CÄ\96HÆ\98JÊ\9ePÇ\9cNÄ\99M¼\8fD¹\89>¸\8a9·\89<Â\94EÄ\94IË\9bKÒ¤UÖ©[Ò¥S׫XØ«WТPÒ¤Uت^Ü°_Ú¯`Ö¬YÏ\9eJÉ\97AÅ\93>Ç\96EÉ\98GÌ\9bLÊ\99MÅ\93H»\89;³\814¨z2£u3\9br,\97m.\93f#\8b[\1a\85W\19\88Z!\8a\&\89[\e\84X\1a\81S\1a\80V#qI\15pJ\15mH\17mJ\17jE\15lL\ewW#rR\1egG\16Z8\vY8\v\@\15R8\ fV9\13P2\aL4 E*\ 3B%\ 3D(\ 4K+\ 3N.\ 5H)\ 3N.\ 4O0\ 4P1\aM-\ 4R0\ 4T3\ 6U3 X5\fY7\vb>\f[: a=\10b=\ egC\14lI\16oQ#mT&fM"YH\1eXK#XG\1e\J'[N*_S5dY4\9a\8enÔÊ°Õ̲ÕͳÔ̶ØÏ·ØѹÛÓ½ÛÓ½ÜÔÁÜÔ¿ÞÖÀÞÖÂÝÕÁÝÕ¿ß×ÂÝÕÀß×ÄÞÖÂÝÕ¿ÝÓÂÝÒÀÝÓÂÞÓÁÞÔÁÝÓÀßÔÃÝÒÁÝÓÀÝÔÀÜÒ¿ßÖÀÞÔ¾ßÖÁß×ÀßÕÂßÕÃßÕÂãÙÇãØÇâ×Æá×Âà×ÀàÖÁàÖÂáØÃáØÂãÚÄãÙÄãÚÅáØÄâÙÃãÚÄãÙÈäÚÉåÚÉåÛÈæÝÈåÛÇåÛÈæÝÈåÛÆçÞÉæÝÈèßÊåÝÅåÜÆçÝÉçÞÉæÝÈæÝÈäÜÆçÝÌçÞÉæÝÇåÜÆåÜÆåÜÇåÜÇæÞÈæÝÇæÜÊåÛÈæÛÊæÜÈæÝÈãÚÅæÝÇäÛÇäÛÆáØÃâÙÃàÖÁá×ÃàÖÁÝÔ¿à×ÁßÖÁÞÕ¿ßÕÀÛÓ¾ÝÔ¼ßÕÀÞÔ¿ÔʲÐƨƼ\9e³®\8d§\9ex\8b\80]wh=cO$cJ\1agG\14iE\11pH\15|Q \82X\1f\8bb,\93g/\9bo;¦zH\9f{E¢z@\9cs9\9ct:\9bt:\9ev:\9ew:\9fw<\9cv7\97p.\97q.\93n(\98s+ y/£}8§\83>¦\82>©\83A°\89H©\84B¡|:\9ew4\9at.\9bq.\97n+\98n)\9fu0¥{-«\815°\85:¸\8aD¿\90HÀ\92GÃ\93GÂ\93CÂ\93DÈ\9bMÈ\9aIÌ\9eNË\9dMÊ\9dIÇ\9aLÆ\9bLÅ\99IÆ\99GÇ\9aH¾\94H¿\91D½\8eD»\8e>¼\8b?½\8dA¿\8d<Ë\9aKÓ¤TتVßµ_ß·^Û°_Ï¢NѤPÓ¤RÔ¥RÔ¤PÑ¡NÍ\9eKÌ\9dGË\99FÎ\9eKÓ¥QÐ NÓ¤QÓ£OÔ§UУUÊ\9bL¼\8dA¶\8bJ°\81;£q.\95f!\97i'\97h)\93c \8d^\e\88X\17\83Z\1cyP\1euM\14qK\17nN\16qM\16\7f['\8ei0\86d/xU"aD\ fgL\1anT&wY2nP&bE\15S8
+L.\ 6F.\ 4L4\bX:\ eO0\ 5K-\ 3F(\ 2F+\ 3F(\ 3G,\ 3J.\ 5K-\ 3O/\ 5N-\ 4R1\bP/\ 5S2\ 5U3\ 5Y8\fZ8\r`?\12dJ\1f`N"aN#XG\1eRB\1cSE\1dXL)YN+^S3gZ:ª¢\88ÎÅ©×δÕÌ´ÖιÚÒ¼ÛÓ½ÜÔ¾ÛÓ¾ÜÔÁÞÖÁÞÖÁÜÔ¾ÞÖÂÝÕÁß×ÄÞÖÃÞ×ÄÞÕÀß×ÂÛѼÜÒ¿ÜÒ¿ÝÒ¿ÞÓÁÝÒÀÜÑÀÜÑÀÜѾÛÒ½ÜÒ¿ßÔÃßÖÀßÔÂàÕÄàÖÄàÔÄàÖÅá×ÆãØÇá×ÅãØÇâØÇá×ÅàÕÃáÖÄâØÆÞÔÀáØÂâÙÅãÙÄãÚÄãÚÄäÚÈçÝÊæÛÊåÛÇæÜÇçÞÉäÛÆæÝÇæÜÈåÜÇæÝÉèßÉåÜÇæÝÈçÞÉèßÉçÞÉèßÉæÜÇèßËéáËåÜÇæÝÈçÞÊåÜÆèßÊæÜÊæÜËèÝÌçÝÌçÜËéßÎèÞÌæÜÉæÝÈæÝÈåÜÇæÝÈãÚÅåÜÆãÚÄâÙÂá×ÂàÖÁáØÃà×ÁàÖÂßÖÀÞÔ¿ÝÔ¾ÞÔ¾ÝÓ½ÜÓ¼ÝÓ¾ÛÔ¹×ÎÐɬŻ ¬¢}\8e\84]nd<p_:qT3vQ0kM!oO!zR%\81V/\85]/\8ce1\96m9\96m8\96n9\9ap8\9du;\9du:\9dw9\9ds3\9as2\99s2\96o/\98q0\94n*\98s1\96q0\9fy7 z7¦\81?¬\88G¨\87E¦\84D\9e}8¡\7f<\9fx7\9dw2£}7§{5®\84;¯\86;®\816±\827¶\8cA¿\90@Ã\95AÇ\99IË\9fMÉ\9fPÉ\9aIÉ\9dPÈ\9cMË\9fQ΢TÌ\9fOÊ\9eJÉ\9eQÅ\9cQÀ\94IÀ\93D½\90B·\889·\866»\8a7»\8a6È\97EË\9cHÞ°]â¹dâºiܳbÔ©UÒ¤OÖ©TÒ¤PÑ¢RÍ\9aDÉ\94<Æ\95CÂ\91AÆ\97GÊ\9aJاWÚXÚ[Ú°aÙ^׬^Ô¨\СSÉ\9aN¿\91Fµ\85<³\82:§x/¤t*\99h \97n,\98k4\91`\1d\82W\14\7fX\1d}Y%\84^*\95q8\92n8\8ce,\89f3\8am<\8do?\90oA\82]-lS!jK\16iL\efH\19jP\1flM\1ftQ#dC\13`@\1a[3\rN1\bJ,\ 5H+\ 3I,\ 4K0\ 5Q1\ 6S2\ 6W7
+P/\ 5R1\ 5T3\ 5V6 T8
+Z?\13`J\1f^K\1fXI!XK%VI$UH%XM+]R3pdA°¬\92Õ̵Õ̲Ó̵ÛÓ¿ÛÓ¿ÚÒÀÝÕÁÞÖÁáÙÃÝÕÀÜÔ¿ÜÔ¿ÜÔ¾ÝÕÁÞÖÄÞÖÁÜÔÀÞ×ÄÞÖÃÚÑ»ÝÔ¾ÜÓ¾ÛÒ¼ÛÒ¼ÞÔÀÝÒÁÝÒÂÛÑ»ÜÒ¿ÞÔÂàÖÅßÕÂá×Åá×ÅßÔÃáÖÅãØÈâÙÄãÙÇäÙÈâ×ÆãØÇãÙÈåÚÉäÚÈãÙÇãØÇåÚÉâ×ÆãÙÇåÚÉáØÄæÜÉäÛÆæÜËäÛÇæÛÉçÜÊæÛÉæÜËåÛÉçÞÈçÞÉåÜÇæÝÇäÛÇåÜÇçÝÉçÝÉæÝÈéàÊçÞÈçßÊèßÉæÝÈèßËæÛÊèÞËæÜÊçÜÊæßÎçÝËæÜÊæÛÊçÞÊçÞÉèßÊèßÊçßÉçÞÈæÝÇãÚÄæÝÅæÝÈäÚÅäÛÅâÙÃâÙÃà×ÂÞÕ½á×ÂßÖÀÞÕ¾ÝÔ½ÞÔ¿ÞÕ¿ÜÓ»ÜÒ¹Ø϶ÖͲÒÊ©Æ»¡ÈÁ¦ÈÁ£Â¹\9dµ¨\8b \97w\8c~Z\80hHrW6iQ,sS+\81Y/\89_0\8ed6\92f4\96j6\96l4\96l1\99q4\9cv6\9ex7\9ew7\9cw7\9as2\98q4\99q5\9ar6\9ar5 z;£|@£~=¡{< z9\9fy9\9bu3\9ex7£~=¬\84B´\8aI\83;¨\7f9¬\828¬\825µ\87;¹\8aAÄ\96LÍ¡SÊ¡UÊ\9aJÈ\9aJÇ\99PÅ\97NÊ\9eNÉ\9dMÍ¢UÊ¡UÇ\9fSÁ\97KÁ\95EÂ\92Iº\8c=µ\887·\8a8¼\8e?¸\896¿\90>É\98FÓ¤S׬Wݳ`Û®_ÙYÖ©VÖ©VÚ©XÑ£OÎ\9aDÈ\96AÁ\91;Å\94@Ä\94AÍ\9cHÑ£PÔ§SÚ[Ù¯^Ø]Û±cÙ®^×\Ô©]Í£YÈ\9bRÅ\97NÁ\92H¿\90F¶\90G±\88Bª\7f9\9fo)\9ap1\93g.\9ao6\9ex@¡|C\9ew<¢|H¡\7fI\99vA\89k:y['pQ\1ctP\1avU\19\83f2\86j2\8fi4\88b0~Y*sM'hB\e^>\13[<\ fV9\aS2\ 4Q2\ 6S1\b\8\ eY8
+U5\bN0\ 4O4\aS6\ 6U:
+X=\10aI\1e`L VH"UH!WI&XL*ZO1_T6znQ¿¶\99Õ˱Ô˳ÕÍ·Ô̶ÝÕÁÜÔÁÛÓÀÞÖÁÞÖÀÜÔÂÜÔ¾ÞÖÂÜÔ¿ÜÕÂß×ÄÞÖÃß×Äß×ÃÞÖÃÝÒÂßÔÂÛÒ½ÞÓÂßÔÂÞÔÂàÕÄßÕÀÝÓ¾ÝÓÀßÔÂÝÓ¿áØÂá×Äá×Åá×ÆäÚÈãÙÈâØÅãØÇäÚÉäÚÈäÚÈæÛÊåÚÉæÛËæÛÊäÚÇãÚÆãØÈæÛÉåÚÉæÜËçÝËçÜËçÝÌèÝÍçÝËæÛÉåÚÉåÜÊæÝÉçÞÈçÞÊéßÍæÛÉæÛÉæÝÇéáÍçÞÉçÞÉçÝÊçÝËçÝËæÝÊèßÌéßÌçÞÌçÞÍæÞÌçàÍèàÏçßÍèßÍèÞÌçÝÊèßÊçÞÉåÜÇèßÊçÞÈçÞÉçÞÉæÞÉæÞÉåÜÇæÝÈåÜÇäÛÆåÜÅæÝÇãÚÅäØÂâØÂáØÀâÙÄâÙÁÞÕ½ÜÓ»ÛѺÙзÓɯÔ˲ÚÒ½äÚÃãÛÃÞÖ¿ØйÑƬÈÁ¨¶¯\90 \97s\8f\84[\88vRya;w]4sS'\83W)\8d_/\90b-\8ec+\96j2\9eu=\9fx> y;¡x9\9fv:\9eu8\9dw7\9cu6\9dv9\9cu8\98r1\99r6\99s5\9dw7\9ev9\9cv8¦\84B«\86G¨\82<¤\81;¤\81:«\86<²\89>²\88:¶\8b@Â\94JÈ\9bRÊ\9dMÉ\9dKÁ\91@½\90B·\8b<¾\90BÇ\9aLÎ¥TͤVÆ\9cRÃ\99NÀ\93F½\91C¹\8c=»\8d?¼\8c:º\8d@»\8d?À\91CÃ\93EÆ\95EÌ\9ePÐ NÒ¥RÓ©TÙ¯^Û¯\Û°[Û±cÙ«ZÖªWÔ¥QÏ MË\9bFÌ\9cGÐ\9fHÓ¤QÒ¢PÔ¤RÖ©VÔ`×°^Ù®_Ö¯dÕdÓª`ÓªaѨaˤ[ΧaÊ£\Æ\9dSÅ\99QÂ\96S¿\90H³\87Fª\84Bª\80D«|<ª\7f=¥~@\98s5\8ck5|^%}[\1d\8ai6\91t:\99zF\9f\80C\98x7\90k2\83^(uO kE\ejE\17bA\ f_A\ e];
+Y8\bgB\ fnG\12c?
+W8\fJ/\ 6I0\ 5L1\ 5U=\11W?\16[G\1dZH\1eRC\1dUH"UH"XK)[N._T5\8b\82dƼ¡ÓÊ°ÕÌ´ÒʲØкØйÛÓ¿ÛÓ¿ÜÕ½ÜÔ¾ÜÔ¾ÞÖÀÝÕÀÚÒ¼ÛÓ½ÝÕÀÞØ¿ÜÔÁÝÕÂÝÕÃàÕÄÞÓÃà×ÂßÖÃàÖÄàÕÄàÖÃàÕÃâ×ÆáØÆàÕÄÝÔ½áØÃãØÇàÖÄá×ÅãÙÇåÚÉäÚÈåÚÉäÙÈâØÆåÚÉçÞÌèÞÌçÝÌçÞËæÞÈèßÌçÝËçßÌèÝÌçÝÌéßÍçÝÌçÝËæÜËçÞÌæÛÊèÞÍçÜÊåÝËçÜÊæÝËçßÌæÞËåÝÉéßÊêàÏéàËèÞÊèßËéßÍéßÍéÞÍèÞÌèÞÍéàÎèßÍéàÎèÞÍêáÏéáÏèÞÍèÝÌèÞÍéßÌéàËèßÊçÞÈçÞÉèßÊéàÌçÞÊéàËæÝÈæÝÉèßËèÞËçÝÈåÜÇéàËæÝÈåÜÇåÜÇãÚÄâÙÄàÖ¿ßÕ¿ÜÒ»ØεÔʯÕ˱ßÖ¿çÝÈæÜÇãÙÃàÙÅßÖ¾ÞÔ¿ÜÔºØϵÑÈ«Å»¡»´\97©\9f\81\92\87b\7fjC{d@}_6\83_,\88_,\94l;\9br9\9cs7\9ft5\9bs7\9du9¡x=¡z;¤}=£z?¢z>\9du6\9fw8\9fv6\9dt9\9fy9 z:¢{>¥|=¦}9¦|8ª\81;±\88A´\8bB¸\8dC»\91F¾\90F¿\91H¾\90E¹\8b>º\8c=²\840»\8aAÀ\95Kϧ[Ò¨\Ê¡TÂ\98PÂ\96KÃ\96FÀ\90D¿\91CÃ\93C¾\8e@Á\91B¾\8e>Â\91BÀ\90@Á\92>Æ\97AÈ\9bKÑ¢QÕ©VתSתVÙ[Ù¯Yܱ\Û°^Ú°\תT׫YÔ¦TѤQÕ¨XÔ¨VÓ¨XÖª]Ö¬_Ö«^Ö¬bÑ©_Òª_ÖdÕ«dÒªbШ`Í¥^̤ZÍ£[ЧcÍ¥]ϧb̤_Ç\99W»\89F¶\84@¬{3\9ft,\96j+\8fg$\8ed\1f\98r5¢~F£\7fD£\81B\95r.\8cf*}W\1cwQ\1erJ\18oH\15kE\rjD\rdC\ foH\12\7fT\1dxS\18rM\1c\<\vP5\ 6O3\bU;\ fU=\10V>\13bK\1d]I\1fQE\1cPB\1cVF!VJ&YL,\P3\9a\8eqÎĨÒÊ®ÕδÕͶ×ϹÛÓ¾ÛÓÁÛÓ¾ÝÕÃÜÔÁÞÖÂÝÕÂÛÓ½ÝÕÂÚÓ¾ÛÓ¿ÛÓ¼ÝÕÁÜÔÂÞÖÁáØÃáÖÄá×ÅáØÄáÖÅãØÇá×ÄâØÄãØÇãØÇäÚÉá×ÆäÙÇãÙÈäÙÈãÙÈãØÇäÙÈåÛÉæÜÊåÛÉæÛÊèÞÌèÞÍçÝÌæÜËéÞÍçÞÌèÞÍéàÎéßÎèáÍèÞÌèÞÍéàÎèßÌèÞÍçàÍçßÍéàÌåÝÇæÞËæÞÌæàÌçÞÍéáÎèßÍêâÎéßÍéßÏéßÍéáÌêáÌëãÏêáÏéàÎëâÑéßÍéßÎéàÏéßÎéßÎéàÏéßÎéáÌéßÎéàÏèßÌêâÍéàÊêáÍéàÍêàÏéßÍéßÍéßÌéßÍçÞÌéàÌçÞÊæÞÈæÝÈæÜÇçÞÈæÞÈåÜÈåÜÇãÚÄßÖ¿à×ÁÝÔ¾×ζÕ̵ãÙÅèßÊæÝÇáØÀãÙÃÞÕ½ÞÓÀÞÕÂßÕ¿ÜÒ¹ß×½ÝÔ»ÙÑ·Óʮ̧À¶\98´¨\89¬\99u\9f\87e\99\7fV\96xG\95t=\8fo8\97p:\92f.\98k3\9eq8£u:¤x>©~C¥z<¨}?¡v7¤y= x<\9cv7\9bu0\9dr3¤z8¦}6¥~9©\81;¶\8bA·\89>º\8cC¼\8eD·\8bA¶\87;·\879®\7f3²\855¶\88;Á\95IÊ¡VÔ¨ZË£UÉ¢UÆ\9cPÂ\96IÁ\94EÂ\93JÆ\99KÇ\9aLÆ\96JÃ\96HÁ\91BÂ\93CÂ\93BÃ\93B¾\8f@¾\8f?Ì\9bLÒ¥NÖ§WѦUÔ§VÑ¥]Ó§VØ«[Ø\ÙXجWØ«WÚZÖ«W×ZØ^Ø]Ö^ÖaÒª]ѧ\Ì\9fTФVϦ^ͤ[Ê¡WÊ¡WÊ Wϧ^ÕdÕbÕ®eÓ«`Ò¦_Ê\9cTÁ\92Hº\88?¶\85?¬{2§{:£y3£x6 {7 |<\94k'\8ce'\83Y\18\84^#|T\11wO\13pJ\ ejG\ fqM\17}W$\82Y%|T\1cwS\1egH\17\<\10U5 X=\10[A\14]D\19bK aK L=\10OC\1dSE VL*_S6bW9¤\9a\82ÏƱÓ̱ÖÍ·ÓË´ÜÔÀÚÒ½ÜÔÀÜÔÁÛÓÀÛÓÀÝÕÁÝÕÀß×ÁÞÖÀÛÓ½ÜÔ¿ÝÕ¿ÜÔ¿ÝÕÂàØÆàÖÆâØÇáÖÅáÖÅâØÇâ×ÆãØÆãØÇãØÇâ×ÆäÙÈåÛÉäÚÈåÚÉãÙÇåÚÉäÚÉåÚÉäÚÈåÛÊäÜÊåÚÉåÞËäÝÊèàÍæßÌèàÎåÞËèàÎèàÏèßÍèßÍèáÏæßÌèàÎêàÏéßÎéáÏçàÍçàÍéáÏéâÏéáÏèàÌèàÍèàÍèàÊçßËêàÏêàÌèáËêâÎéàÌêâÐëäÑêáÎëâÐèáÏéáÏèàÎçàÍéâÐéáÏèàÍèßÍêàÎéàÎêàÏêâÍèßÊéáÊêâÌéàËêàÍêáÍéáÌêáËëâÌèßËèßÊéàÌèßÊçßÊèßÊçÞÉèÞËåÜÆáÙÃâÙÃâÙÃßÖ¿ÚмÚмåÜËêàÏéàÍæÜÊäÚÈâÙÃàÖÄâÙÆÞÔ¾ÜÓ¹ß×½ÜÔ»ÝÔ»ßÕ½âÙÁà׿ß×¾ÚзÕ˱ͨø\99¹«\86§\94h \89_\91wI\93r>\8em9\96n:\9eu@¥|H\9fw;¥|C¢{C§}C§~C¥{?¡w8¤z:¦|=§{9§|<¦z9®\83@°\84<±\838¶\87?·\88@µ\86=·\87<´\87<´\88<¸\8b;º\8a>¾\95JÈ\9bPÆ\9cOÉ¡VÇ\9eSÄ\9bQÂ\97K¿\92EÂ\95GÇ\97KÇ\99MÇ\99OÄ\95JÃ\97J¿\92C½\90Aº\8d>»\8d@»\8dA½\8f=Á\93HÂ\95HÀ\91GÄ\96KÂ\95EÇ\98HÍ\9eRÖ©[Ú¯[Û¯_ÙXÛ¯ZÚ¯[Þ´cܳcÙ²bÚ³hÕbΤZË¢WÉ QШ\Î¥]Ë¢ZÉ UÈ\9eTÊ\9fUÍ¥[Ó¬dÖ®eÓ«bѧ\Ó©`Î¥\Ì\9fSÅ\9bQÄ\98N»\92I³\89<´\86=\7f7¯\83:¦{3\9ap'\98n#\96k-\94k,\89_\1f~U\17zS\19zS\18\80X\1d\80W\e~V\1ewP\enK\16b?\ ffE\13fE\17dE\eZF\17gO ZG\1aL=\13PE$SF%VK(YL-laC§¢\8bÒμÔ˲ÕÍ·ÖθÙѼÙÑ¿ÛÓÀÛÓÀÝÕÂÛÓÀÝÕÂÜÔÁÛÓ¿ÞÖÃÜÔÀÞ×ÅÝÕÃÜÔ¿ÞÖÁßØÂáØÆßÖÄÜÒÁÜÑÀßÖÃáÙÇáÙÇàÖÄâØÇäÚÉâÙÇæÜËäÛÉäÚÉåÜÊäÜÊãÛÉåÜÊãÛÉçàÍåÞËçÞËåÝÊæßÌèáÍèàÎæÞËçàÌçàÎèáÎçàÍéáÎéâÏêâÐèâÏèßÍèàÍéâÏèáÎéâÏçßÍèàÎèáÎéâÏéâÐçàÍéáÎéáÏéâÏèàÍçßËêâÐêãÐéáÏêãÑëäÒëãÑêäÑéâÏéâÒêäÑéáÏêãÐêãÑéßÍëáÏéàÎëâÑëãÎêáËëãÏêàÐêáÐêàÐéáÏëâÍêáÏéßÎéàÏéßÎéßÎéßÎéàÌéßËéàÏçÝÉæÝÇæÜÇäÛÆáØÃÝÓ¾ÝÔ¹ÜÒ¿èàÌìäÑëäÎêâÌèÞÉåÜÆãØÆàØÁáØÀÜÓ»àÖ½ÞÕ¾ÞÕ½ßÖ¿âÙÂãÙÂáØÀâÙÁà׿à׿âÙÄßÖ¼ÚÒ¶Òɮǽ\9c¾±\8d®\9fz£\90l\96\7fY\9c|N\9azF |D§\81J§~H¨\80F©\7fEª\7fE¨~A¯\82Fª\80B¤x7¦y9¦y;¨|8ª~8¯\83:³\84<³\86?¯\85:´\8a?²\88=µ\8a=º\8fD¼\91G½\90FÁ\97LÁ\97LÁ\96LÃ\97P¼\90L¿\91G½\8fCÂ\92HÂ\95KÄ\96LÂ\94JÀ\91GÂ\94IÄ\95KÀ\92F½\8eD½\8f@¼\8fA¾\8eC·\89;´\869·\88=³\852±\82-¹\8b?¾\92@Ê\9eNÊ\9eKФQÛ±]Ù±_Ù°`×®_ׯbرeÚ³iÔ«bÑ©aѪ_Ñ«`Ѩ_ͤZË¢VÈ\9fSË\9eRÊ¡WѪ`ÔdÒª`ϧZѨ^Ó`Î¥ZѨ_Ш]Ñ©ZÊ¡SË¡VÄ\9aOÄ\9aSÂ\95N¹\90D¶\8cA«{5°\80B¤w3 u1\99n)\91e \85^\1a\88_$\82Z\1e~X\1fsI\12lJ\17jI\18iH\15`B\13dJ\1ciT%YI\1eRC\1cPC"SF%VK*^R4ocF³ª\94Ó̸Ó˶ÕͶØоÜÔÁÚÒ¿ÙѾÜÔÀÛÓÁÜÔÂÝÕÃÛÓÀÛÓÀÜÔÂÜÔÂÜÔÁß×ÅàØÅÝÕÂßÖÄà×ÃÛÒ¾¿µ\9dʽß×ÅàØÆâÚÇâÛÅáÚÇâÛÉáÜÉâÛÈäÜÊæßÌåÞÊæÞÌæÞËäÜÉäÛÈæÞËäÝÊäÝÊçßÌçàÍæÞËèáÎãÜÊåÝËæÞÌèàÍéáÏëãÑçáÍéâÏéâÏêâÐèáÎéáÏèáÎèàÎêãÑéáÏçàÍëåÓêãÐêãÑçàÍèàÎèàÏëäÓêâÐëäÑëäÒêâÐêãÐëäÒêãÐêãÑëåÒêãÒêãÑëåÒëåÖêâÐéàÎêáÐêáÏëâÐëâÍêãÎêáÏëâÍêàÏëáÐëáÐêàÏéßÎêáÐêáÐéßÍëâÐéàÎéáÏêâÐéàÏèÝÌèàÎçÞÉäÛÆäÚÉßÖÀÝÔ¾ßÕÁêâÎìåÐëâÐëâÎéáÌèßÌèßÊäÛÅãÙÄãÚÅãÚÄãÚÅáØÃÞÕÀß×Âà׿à×ÁáØÂá׿áØÀçÝÇäÛÄáØÀáØÀáØÁÞÕºØγÑʮɾ¡À²\91³¦\83ª\96n£\8fd¤\86X¥\81T£\84R§\7fG«\7fH¬\82H¨|?§y<¥x;¨y:¤s2£u/ª~9ª~5©|:§{9«\7f<¯\84?\839²\89E¸\8eK¶\8cGµ\8bE·\8dCº\91Hº\90E´\89?´\8aAº\8dD¸\8eC¼\8eC»\8cB½\8dCº\8bA¿\90FÀ\92HÀ\92E½\8fAÂ\94G¾\91E¿\95J¹\8fC¶\899²\846²\847«~-®\822²\874º\8d;Á\94?Å\96DΡOѬ]ΧVÍ¥XÒª[Щ]Ó¬bѪaÔ®g׳hÓdÓªfÌ¥[ͤZÈ\9fUÈ\9eTϧ\ÓªaШ\Ì£UÎ¥\ϧ[Òª]Óª^Ш[Ñ©^Òª`ÓªaÔ«bÕ®fÔ¬bÑ©_Ñ©_Ê¡VÃ\99P¿\96J½\93I¼\8eI¸\8eB±\87A§}>\9fw6\96p&\8dj'\87[\1c\82[ tT\17rR\19sR%tT&pV&WF\19I;\15QD\1eRE#[N.\N.zoS¾µ\9aÓ˱ÕÍ·ÕÍ·ÙѼÜÔÂÜÔ½ÚÒ¾ÜÕÂÝÕÂÚÒ¾ÛÓ¾ÝÕÂÝÕÂÜÔÁÚÒ¿ÞÖÄÝÕÀÜÕ¿ÞÖÂàØÅßÖÁÏǵ\9e\94~¾²\9eÞÖÃâÙÆàÙÆáÙÄãÛÉâÚÇäÛÉåÜËãÜÉåÝÊåÝËçßÍæßÌäÜÊäÜÊæÞËæÞËæßÌæßÌãÛÈåÝËèáÏæßÍçßÍçàÎçßÌèáÎéáÏèáÐéãÒéáÐëäÒëäÑêäÑèâÏêâÐêäÑêãÑêãÑëäÑêâÐèáÎèàÍêâÐéâÐêãÑêãÒéâÌêãÏëãÑêãÐêäÑìäÒìæÔêãÑëåÑëäÒêâÐëåÔëãÒëâÑëâÑëãÒìãÑìäÏëâÏêßÎêàÏëàÐìäÓêãÑêâÐêâÐëäÑêãÑêãÐèáÎéáÎéâÐéâÐçßËæÞÌçßÌèàËæÝÈäÛÈà×ÁÞÕÁà×ÃêáËëäÑìäÓëâÐëáÎéàÍèßËæÝÈåÜÇåÛÆæÝÈåÜÆâÙÄâØÃáØÁà׿âØÀáØÃá×Âá×ÁäÛÃâÙÃáØÃáØÂáØÃãÚÄãÚÄà×Áà×Âá×ÂÝÕ»ØеÒɮʺ\99¯\8c«\9cv¬\8d[©\87U¨\82W¢xA¢w<¨~D¥x?¡s7¢r4¦x@¨z;¬|;§{=§|;©|<§{:¨}=ª~A«\80@©\7f?µ\8aHµ\89F¹\8fK¶\8bG°\85>°\86<²\87@²\87>±\86;°\849²\828¯\849µ\8c@¸\8cB»\90DÁ\94HÂ\96IÂ\98NÃ\99N¿\91B»\8d@¹\8aA¹\8a=µ\888½\8fC¼\8fA¾\8fC¾\8f@Å\95GÌ\9fVÊ TÇ\9cOÌ£YͦXͦYÈ Uɦ[Ñ©]Ó«dЩfΨaÑ©^Ê¡RÉ\9fSͤZͤWÎ¥XË¡UË¢T̤VÌ£VѨ[Ѫ^Ñ©ZÑ©[Ѩ[Õ¬`ÕbÒ«aÖ®a×±bر_Õ®^Ì¥SϤSÉ\9dMÈ\9fTÆ\9eXÄ\9bQÁ\9aS¹\90K\89K¤~7\9br0\94p6\90k9\8bj:\80g1pZ(WG\1cMC\1cPC\1eWK'SG&\M.\85}gÄ»¢ÕÌ´×ϹÖθØлÚÒ¾ÜÔÁÜÔÁÝÔÁÝÕÃÛÓÁÚÒ¿ÝÕÃÞÖÃÞÖÂÜÔ¿ÞÖÃÝÕÀÛÔ»ÞÖÂÞÖÁÞÖ¼¬\94\9a\8aqø\9fà×ÅâÚÇàØÄáØÂãÛÈãÜÉãÛÈäÜÊäÝÊåÞËãÛÉçàÌäÝËåÜËäÜÊæÞÌæÝËäÝÉæÞËçßÌäÝÊæÞËçßÍçàÍæÞÍçàÎèàÎéáÐêâÒèàÑëãÔéáÐéâÐéàÐèáÏèáÎçßÍêãÑéáÏëäÑìæÓêâÐèâÏéâÒêäÔëäÑêãÑêãÏëåÓêãÑêâÏëãÑêãÐëåÓêãÐëäÒéâÐëåÓêäÑìäÒìåÓëäÒêãÑëäÓëãÒëâÑìâÑëãÒêäÑëäÑêãÑëãÑëäÓëäÑéãÐëåÓêâÐéâÏêãÐéâÐèáÎëãÑèßÌéßËæÝÈãÚÄãÙÄßÖÀâÙÃëãÎîèÖìåÑìäÒëâÏêàÍêàÏèßËçÞÈæÜÉåÛÇãÚÅäÛÆäÛÅåÜÆãÚÄåÜÆäÚÅãÙÄãÚÅãÚÅãÚÄãÚÄâØÂáÖÀà×ÀâÙÂÞÔ¾áÖÀâØÁæÚÄæÜÅãÙ¿äÙÀâؼÜѸÕÉ©ÎÁ\9eÆ·\96¼ª\80³\97k¥\8a\\9d~M\99s<\9br=£sB¨x@«|=ª}>«~=©{>¬\80A©}>¨}>¦{;¨|=©~=°\7f>«~<¥y7¥y6ª~<¬\81B«\81?®\83:¯\837\848³\89?°\86;³\89>°\87;¶\8c@¼\91H»\91G¿\93GÃ\96L¾\92Gº\8eC»\8fC¼\90DÁ\92HÂ\98HÃ\98MÃ\99NÂ\99OÃ\9bOÅ\9aMÀ\97IÅ\9cRÉ QÇ\9dVÅ\9aUÂ\98PÊ¡Wʤ\ͤ`Ì¢^É\9fYÈ\9eUÉ¡YË¢WͤVË¢XÉ RÈ\9fSÇ\9dRÉ RÎ¥Wϧ]Ѩ\Î¥VΩZΧYΩ[Ϩ]Ô«bÔ«[Ø®b×±_Ö¯]Õ«]Ó¨ZÓ§\Ò¨\̤WϨdΨcÆ `Ä\9aZ´\90I±\8bQ¯\89T¦\85N\97{Jq[+SF\1dNE\1ePC\1dSH#UJ+]P4\88~fÄ» ×ζ×ϹØкÚÒ¾ÞÖÃÞÖÃÛÕÅÜÔÄÝÕÂÜÔÃÞÖÂÜÔÂÜÔÁÞÖÂÞÖÄß×ÂÞÖÀÝÕÀàØÂÜÔ¾×Ì´«\99\80\9c\8evÎçàØÃáÙÅáÙÇáÙÆãÛÈãÛÈãÛÉâÛÈæÞËäÝÊäÜÉäÝÊæÞËæÝËçßÌåÝËåÞËæÝËæßÌæÞÌèàÎçßÍçßÌæßÎçàÐåßÏçßÏçßÏçàÐçàÑêãÓèáÑéâÓçàÐêãÔçàÎêâÐéáÏëäÑêâÐéâÏêãÐêâÐèáÏìæÓìåÓëåÒêãÑëåÓêäÑìåÓêãÑëåÓëãÑêäÒëäÑëåÒêäÒìæÔìæÔêãÐìåÓìæÔëäÒìäÒìåÓëåÒêãÐëäÒìåÓìåÓëäÑéãÐëåÓêãÑëãÑêãÎêâÐèáÎéãÐêâÐéàÏéßÎêáÏéàÊæÝÈâÙÃãÙÄá×ÄìåÐíçÔìäÔìãÒêáÐëâÎéÞÎèßÊæÝÉçÞÊçÞÉæÝÈæÝÇåÜÇäÛÆæÝÇãÚÅãÙÄãÚÅäÚÅäÛÆãÛÅáØÀâØÀà׿ßÖ½ßÖ½ßÖ¾áÖ¼ãÙÂãÚÂåÜÄãÚÁçÞÅåÜÅãÛÂæÝÆäÛÃåÜÄÜÓ¼ÕͳËģķ\94¸¬\83\9at«\8ac¥\7fQ¥zH¦yE©{@«}Aª|A¬\7fC«~B£w:¦x<£v7¡t6£w7\9dp0\9er1¢v4¦w4¨}9\81:\837\837±\87<³\89@²\87=®\848«\826¯\869¶\8aE¶\8cA¸\8d@»\90G»\90G·\8d@»\91F¾\95IÁ\97NÂ\98MÁ\96KÄ\9aPÆ\9eQÂ\98LÀ\95I¿\95JÁ\91HÀ\96KÃ\98RÃ\9aPÇ\9eWÈ¡ZÌ¢^Ê¡WÆ\9cSÄ\9dRÇ\9eSÇ\9eQÅ\9cQÇ\9dNÄ\9bKÄ\9bLÃ\9aLÃ\99PÈ\9dPË¡WÇ TÌ£XË¢VÊ¡UË¢WË¢WΧ\ЩZÒª_Ô¬_×®aÖ®bØcÕ¬bÕ¬`Ô¯g×®kЯmÑ®qͪmɤeÅ£`Â\9fa¹\97[\9e\82Ks[+XD\17TG"TH TG#YJ'eU9\9a\8aqÌìÔͳ×ϹÚѼÚÒ¿ÜÔÀÞÖÃÞÖÂÜÔÂÜÔÁÝÕÂÝÖÃÛÓÁÝÕÂÞÖÄÜÔÂÜÔÁÞÖÀàØÂÝÕ¿ÛӾʾ¥\9b\8dy¤\96}ÓËÞÖÂÞÖÄàÙÆàØÅáÙÇâÚÈâÚÈåÝËåÝÊåÝÊæÞËåÝÎæÞËåÞËäÜÊäÝÊæÞËæÞËæÞËçàÍçàÏåÞÌçßÍçàÍçàÐäÞÎçßÏæßÏéáÑèàÐèáÑêáÒéâÒêâÒêâÓéáÑêãÑëäÒêâÐéáÏêãÒéâÒêãÐéâÓëåÔêäÓêãÑëäÕìæØìåÕêäÓìåÕêãÑëäÑìåÓêâÐìåÓìåÓìåÓìåÓìåÓìåÓìæÔéâÐêäÑìçÕìåÓëåÒêãÒëäÔìæÖëäÔëåÒëåÑëäÒëäÒéâÏêãÐëäÑëäÑéâÐêáÏêáÐéàÏèÞÌçÝÍåÚÈáØÂåÜÈíåÒíçÖíåÔìãÒëãÑêáÏêàÏèÞÎèàÊéßËèÞÍçÞÌæÝÈæÝÇåÜÇãÚÄãÚÄãÙÃåÜÆäÛÅåÛÆãÚÄâÙÃáØÃâÙÂà×Àá×ÂãÚÄßÖ½âØÀàÖ¾ãÚÃâÙÃãÙÃáØÁãÙÃãÚÂäÛÄåÜÇåÜÃâØÁßÕ½ßÖÁÙÓ¼ØϯÏšȺ\96¿\89¼¢}²\95i«\83T |R¤}M¦{C¦zA¥yD¢t<¢v;\9ep5\9dp2\9dn1 s2£w5©~:©\7f=¬\80:ª}7²\89@²\8a?±\88?ª\805¬\817§|1¬\828ª}7¯\848\82=³\88@´\8a=³\8a?·\8dD»\92D½\93I¾\94J¾\93G¾\94F¿\95JÀ\95J¾\92G½\92G¾\94H¾\94KÀ\97OÄ\9bWÊ£_É¡^É WÅ\9bRÄ\9cSÈ\9fTÇ\9dSÈ\9eSÅ\9cNÅ\9cQÀ\9bMÁ\96HÁ\93G¿\92DÁ\96LÅ\9bOÇ\9eSÇ\9eSÈ\9cOÆ\9bLÆ\9cOÊ£UͤSͤQУOѨWЩTÒªZÓ«^ϨYÕ®eÙµpÖµrÓ±pÍ«h˧dɧeÄ¢d¸\99_\9c\80EoX'YJ\1fRG\1eOC\eWI%^M,kZ:£\96|ÎÅ°ÕÍ·Õ͹ØмÚÒ»ÝÕÂÜÔÁÜÔÀÜÔÁÜÔÁÜÔÁÜÔÂÞÖÃÛÓÁÝÔÂàØÅß×ÃÞÖÁÞÖÁÞÖÀÞÖÁ½³\9f\90\83h¯ \84ÒÉ°ÞÖÀàØÃÞÖÄáÙÇâÚÇãÛÉäÝËãÜÊãÜÉäÜÉäÜËæÞÊåÝËåÝÌâÚÈäÝÉæÞÌæÞÌåÞÍåÞÍæÞÎçßÏåÝÌçßÎèàÐæßÏéáÑçàÐçßÏçàÐéáÑèàÐéâÓéãÐêâÏéâÏéâÐéáÎëâÏêäÐêãÑêâÐéâÏëåÕëäÕëåÔêãÕêãÓëåÕíçØìæÖìæÖíèÖíçÔêãÐëäÑìæÓìæÓëåÓëåÒëåÒìåÓìçÔëåÓêãÑëåÓëåÒìåÓìåÓìæÓìäÕìåÖëåÕëäÕìåÖêäÔëäÔëäÑëäÒìæÓëæÓêâÏéáÏçàËçÞÉæÜËæÝÇãÚÅæÞÈìåÔîè×íåÔëâÑëáÐëáÐèÞÌèÞÏêáÍéàËéßÍåÜÉæÝÈçÝÉæÜËäÙÇæÜÈäÛÅäÛÅæÜÇãÚÅåÜÆãÚÅáØÃãÚÅâÙÄãÛÅâÙÄâÙÄâØÃá×Âá×ÂäÚÅãÚÄá×ÀáØÃãÚÃãÙÄáØÃâÙÂâÙÁáÙÂßÖ¾áØÃà׿à×½áÙ»ßÖ»ÚеÔÉÑ£Ÿ\99´¦\82µ\9bw¨\8cc\9f\85Z\9f{O\98p>\9bs=¡s<¦x;¤u:¨|=¬\81?§|:ª~<¨{:©z7\83@®\84A©}6ª\7f:¨|5¤y3§|8¥y1§{3¨|5¬\819®\85=¯\85>¸\8fE¶\8dB¹\8fC¶\8b?¹\8eC¸\8dAº\8cAÁ\92H¾\93I¿\94M¼\92M»\93N½\95QÄ\9bWÃ\9cTÃ\9bRÁ\98O¿\96MÂ\9aPÂ\9bQÅ\9aQÅ\9bPÄ\99NÂ\9bN¾\95H¼\93Jº\90EÀ\95KÃ\97MÁ\98HÆ\9aOÃ\96IÅ\98IÅ\98NÇ\9bOÊ\9cNÈ\9fPÈ\9eOË¢W̤VÎ¥XͤVÓbÕ¯j×±nÖ¶rÕ´pͧaÈ£_Ê£cÄ a¶\97]\97x=kW$VJ\1eTJ"SG!UH"`T6l_H±¦\8f×εØк×ϹÙѺÛÓÀÛÔÁÜÔÁÛÓÀÛÓÀÝÕÃÝÕÂÜÔÁÞÖÃÜÔÁÙѾÝÕÁÞÖÄß×ÃÝÕ¿ÝÕÂÜÔÁ«\9e\8a\8f\81m²¢\88ÛÓ¼ÝÕÃÞÖÀß×ÄàØÃß×ÃáÙÆãÛÉåÝÌãÛÊäÜÌåÝÍãÜÌäÜÊäÜÌåÝÌãÛÉæÝËåÞËçßÎæÞÏäÜÊæÞÎçÞÎçßÏæÞÏåÝÍèàÐçàÐæÞÎèàÐèáÑèáÒêâÒëãÓêãÒèáÏçßÍêãÐéâÏéáÏéâÐëäÒêãÐëãÓìåÔëäÔëäÓëåÕêãÔìæÖëåÔìæÓëåÒìæÓêäÐëåÒìåÓëåÓëåÓëäÒìæÓëäÑêäÑëãÐëäÑêâÐêäÑêäÒêãÒéãÒéãÓëåÕëåÕëåÕëäÔëäÔëãÔëäÔëãÒëäÑëãÓêãÏèàÊæÞÈèàÌèßÊæÝÇäÛÆèÞËíåÕíæÔëãÒìäÒêâÐéßÎèÞÌèÞÌèßËèßËçÝËèÞÍåÛÇæÝÈèßÉåÜÇåÜÇçÞÉãÚÅäÛÆæÝÇæÝÇçÞÉåÜÆäÛÆäÛÆåÜÇãÚÅäÛÅäÛÆäÛÆâÙÃâÙÄãÙÄäÛÅãÚÅåÛÆãÚÅåÛÆãÛÆâÙÃáØÃãÚÅãÚÅà×ÀãÚÃáؾäÛÄäÛÃäÛÁâؾá×¾ÜÔ·ØÏ°Ñƨŷ\94»¬\84¹¥|ª\92f§\88X\9c\7fM¦\84P±\86L³\87M¯\82D\81D¨x=¥y5£w9¡u6\9dp. s1¢v2§~;¦z6©}:§{8ª~;ª~;ª~;¯\82;¯\87?µ\8cE¸\8dC¹\8fF¬\827¯\83>±\828·\89>¶\8aC¿\96OÂ\9aV¹\90L¼\93N¿\96PÄ\9eWÃ\9eUÀ\97P¿\97Q»\95IÀ\99Q¿\97KÂ\9aO»\93F¾\99NÄ\9dUÃ\9aRÁ\98N¾\94JÂ\99OÂ\98K¿\92DÂ\99KÄ\9aNÁ\99LÃ\98K¾\93DÁ\93IÃ\95IÅ\9aMÆ\9aPÅ\9aQÆ\9cNÈ\9fSЩeЫfÎkΪfÌ¥`Ê£`É¥eÅ¡c²\94Y\90zFkS#ZN#\P)XK%[O&_S.ynQ¸®\92×εÖÏ·×иÙѼÛÓ¿ÜÔÂÜÔÁÝÕÃÝÕÃÜÔÁÜÔÂÝÕÃÛÓ¿ÝÕÂÜÔÀÚÒ¼ÝÕ¿ÝÕÀÜÔ¿ÝÕÀÛÓ¾\9b\8fy\8e\80j·©\8fÜÕÀÝÕÁàØÅß×ÅàÙÆáÙÆáÙÆáÙÈãÜÉâÚÇåÞÌäÝÌäÜÊäÜÉåÝËåÝÊçàÍåÞËæÝËæÞÌåÝËèáÐçàÍåÝÊèáÍçßÏçßÏåÝÍçßÏãÛËæßÏêâÒèáÑéâÒéáÑéâÒèáÑèàÎèáÎéâÏëãÐêãÐéâÐëäÔêâÓìåÕêãÓëäÕêâÓëåÕìæÕìæÖêãÓìåÕìåÖìåÔéâÏêäÒëåÓëäÒëåÒìäÒëæÖìåÖëåÕëäÑëåÓëäÖêãÔêäÔëäÕëäÔëãÓêäÔëäÔëäÔêãÓëåÒëåÓëåÒëäÒëäÒêâÏêâÍéàÍçáÐçÝÊæÝÇçÝÈéàÌìäÓíæ×ìäÑêâÐëâÑëáÏéßÎéßÎêßÎèÞÍéßÎèÞÍèÞÍéÞÍéÞÌæÜÌèÞÌèßÌèÝËæÝÉæÜÇçÝÉéàËçÞÉçÞÉçÞÈçÝÊæÜÈèßÉæÝÈèÞÍæÝÊåÜÇåÛÇåÛÇæÜÉæÜÉäÛÅæÜËçÝÊåÜÄåÜÆæÜÈæÝÈäÛÅãÚÅäÛÃâÙÂãÚÂâØÀåÛÄãÙÁäÛÃâØÀâØ¿áÙÀÝÔº×αÕˮʽ\9bÁ¶\90·¨\82³\9cq°\8ed´\8a^§\84K¬\81G¤{A£w9\9bm/\9bm2\99k-\9al/\9am/£v8¢x6©}=¨}:ª\7f;©}:¯\82<°\88A·\8cJ¶\8cFµ\8cF°\88A¨\7f:§{8¬\7f6¯\85A¶\8cH´\90K¹\90M¶\8dI¹\90K»\94R¾\9aSÅ\9cV¿\9aT¿\9aV½\99RÀ\9cRÁ\9dT»\96O¿\9aRÀ\9cTÂ\9dUÅ\9fWÈ¢ZÁ\99MÂ\9aOÄ\9dUÆ¡XÉ¡YÈ¢XÄ\9bLÅ\9bPÁ\93H¾\90Aº\8f@½\93I³\8cD¹\92Iº\90GÄ\9aYÈ¢`ˤfÈ¥`Ç\9eZÈ\9eXŤcÇ¥h³\95Z\89tAfT#\M\1f_Q$_R%^R%hX/\82xYú\9cÕ̳ØйÖжÚÒ¾ÜÔ¿ÛÓÀÜÔÂÝÕÆÜÔÂÝÕÂÛÓÀÞÖÄÝÕÂÝÕÁÝÕ¾ÝÕ¿ÜÔ¿ÜÔ¾ÞÖÀÝÖÀÞÖÀ\91\87q\90\84uø§ÚÒ¾ÝÕÂàØÅÞ×Äß×ÄàØÅàØÆâÚÇâÚÇãÛÈãÜÉæÞËåÝÊäÜÉåÝÍåÝËåÝÊåÞÌåÝÌäÜÍçàÏçßÎæÞÏåÝÎçßÏéáÑçàÐçàÐåÞÍåÝÍèàÐèáÑèáÑçàÐëâÑéâÐéáÏêãÑçàÌéáÏéâÏèáÏèáÎéâÑêãÔêäÔêäÔëãÔìåÕéâÒìæ×ëåÔëäÔëåÕìåÔëåÓêãÐëäÒêãÑìåÒêãÑëåÓëåÓëãÑêãÑêãÑêäÓêâÒëäÔêãÔêãÔéâÒéáÐêäÔêäÔêãÒêãÔìæÕêäÓëåÒëäÑëäÒëãÑéàÎéàÏèàÍéßÎçÞÉæÝÇéàÎìäÓíåÔìäÓìäÓìâÔìäÔëâÒêàÏéßÍëáÐéàÐêàÐêàÏèÞÍèßÍéßÎéßÍçÝÍéáÐèÞÌçÝÌéßÍéßÏèßÍèÞÍéßÍéßÍëáÏèÞÍèÞÍéßÎéàÏêàÏéßÎéßÎéàÌæÜÉêàÍèÞÍçÝËèÞÍèßÌèÞÍçÞÉçÞÈæÝÇæÝÇãÚÃãÚÃåÜÆåÜÅäÛÃäÛÆåÜÄâÙÁâÙÁåÛÃáØ¿äÛÅâØÁßÖ½ÚÒ¸Óɮ˽\9eñ\8eº«}²\9fyª\8c]£\80I\97uA\9dzD\9cs8\97o6\9dq6\9cn/¢w9¡w8¤x9£y9£y:ª\81A°\88C°\87E²\8aD´\8bI\86Aª\81<¨\80;¬\82A¯\87D¶\8dN²\8bK³\89H¬\81C±\86I°\8aL¶\91Sº\95P¼\97S½\9aW¿\9bSÂ\9eVÄ¡]Á\9d\Â\9eZ¿\9cV¿\9aTÀ\9cVÈ£\Ä¡X˨_ʧaʧ`̪cË©c˨_É¢YÂ\9aO½\91F¼\92G¸\8fE¶\8dB²\88<°\86;³\8a@¸\95NÂ\99SÇ\9f\Ä\9aXÀ\9bZÇ£jÆ¥i¬\91S\8bt:gV!dT'eR(cU(eZ-jY1\91\86kÇ¿¤ØжÖ϶ÖÏ´ÙѼÛÓ¿ÛÓ¿ÜÔÀÝÕÂÝÕÂÛÓÁÛÓÀÜÔÁÝÕÃÞÖÃÝÕ¿ÜÔ¾ÜÔ¾ÝÕÀÜÔ¾ÜÕ¿ÝÕ¿\8d\80o\92\86rÍ®ÝÕ¿ÞÖÄß×ÄßØÅáÙÆß×ÅâÛÈãÚÉãÜÉäÜÊåÝÎãÛËäÜÉäÜËãÜËäÜÊäÜÍäÝÍäÝÊæÞÌäÜÊèàÎæßÏæÞÍæßÍçßÎèßÐçßÏçÞÏæßÏæßÏèàÐçßÐéâÒçàÐéâÑêãÑèáÎèàÏéâÏêãÑèáÎæßÌçßÏéâÑëäÔëãÓëåÕêâÓëäÔêäÔëåÕêãÓìåÕêãÒêãÒêãÒëäÓëåÕêãÓêãÒëäÓêãÑêãÓêãÑëåÒëäÑëäÑêãÓêãÒéâÏêâÒéâÒëäÔëåÕëåÕëåÕéâÓëåÒêãÑéâÐëäÒëãÑëâÏëâÏëâÏéßÌèàËèßÉèßÌìãÒíåÔíäÓìãÓìãÒìãÓìãÒëâÒìãÓëâÓêáÑêãÓêâÎêâÑéâÐëãÑèáÎêâÐéâÐéàÏéáÎéßÏêàÏêáÏéáÏêâÐéßÎêàÎèßÍèßÎêáÐëâÑëáÐéßÍêàÏêàÏéßÎêàÎéÞÍêàÏçÝÌêàÏèÞÍéßÌéàÍèßÍçÞÉçÞÉéàÊæÞÈåÜÆäÚÄáØÃâÙÃâÙÁãÚÁâÙÁãÚÂâÙÁåÜÅãÚÄãÚÁãÚÄãÚÄÞÕ¾ÚÑ·ÑÉÐæĸ\98»®\89¯¥z©\90a\9f\87Z\9b{L\9fwE§~I¦|D¡x=\9ft6\9fu9¡w9¤y:¨~>«\7f>©|>\83C©\80<©\80;ª\82>µ\8cJ³\8fK®\8bI®\87D¬\83C§\81A¤~=®\87D·\90M¸\91Mº\93L´\8dE¼\99Q¿\9bUÂ\9f\¿\9cU½\9aS¿\9bU¾\9bSÃ\9f[à XÆ¢Z̨b˨dʦ`ʧ_Ì©bÉ¢[Å\9dRÃ\9cQ¿\97O¿\99R¾\97P¹\90H³\89@\88@´\8eGµ\8dE¹\92N¼\93O¿\9cZÄ¢j£k«\91X\7fj3jV\1dhS"gU,hW,fY/o\;¢\98~ÎÄ«ØзÖ϶ØкÚÒ¼ÝÕÀÝÕ¾ÜÔ¾ÜÔ¿ÜÔÀÜÔÀÜÔÀÜÔÀÜÔÂÜÕÀÞÖÁÛÓ¾ÛÓ¾ÞÖÁÜÔ¾ÝÕ¿ÜÔÀ\8b|k\99\8awÒȶÜÔÀÝÕÁÞÖÄßØÅß×ÄáÙÆáÙÆâÛÉãÜÉãÛÉäÜÌãÛÊãÛÊåÞÎåÞÎäÜÌäÝÊäÝÊäÜÉåÝÊçßÍæÞËåÞËçßÌæÞÍçàÐçàÐèáÑæßÏæÞÎçßÏçßÏèáÑéáÓçàÐéâÑèáÎéâÏéáÍçàÎêâÐêâÐçÞÌçàËéâÏêãÒéâÓëäÔêãÓêãÓêãÓêãÔêãÓëäÔëäÔêäÔëåÕêãÓêãÔìæÖêäÕëåÕëåÕëåÕêâÑìæÔëäÒéãÐëäÔêâÒéâÑéâÒçàÍéâÑëäÔëäÔêãÔëäÔêãÐêãÐëâÒëâÐëâÐíåÑéàÊêâÍéáÌéàËçßÊêâÌìäÓìåÔìãÒìãÒíäÓíåÓëâÑëâÑëãÐìäÐìäÓìãÒëäÑëãÔëãÑêâÐéâÎëãÑêãÑêãÑéáÐèáÎêáÏëãÑêãÑèáÎêãÑéáÍæáÐéãÐéâÐëâÑêãÐéâÑêãÑêâÐéáÏêâÒêâÐçàÐéàÏêáÐéßÎéàÏêáÐêáÏêâÎéàËëãÍêáÎêâÌêáÌåÜÇäÛÅåÜÇåÜÆäÚÅäÛÄäÛÃåÛÆãÚÅåÜÅçÞÆèßÉèßÊçÝÈçÞÉâÙÅÞÔ¼ÞÓ¸ÓȪÏÃ\9fÆ»\99¾´\8f·¦\7f±\9aqª\8dZ¥\83M zC\9dzJ¤|H¦{@¥z?¤y=¦y?¢w<¥z<¨}@¦{?«\81C°\88I°\8cQ¯\8aM®\83E©\83C¨\81F®\87I\89Eµ\8bL±\88C°\85?®\88B³\8dD¹\92L»\98QÁ\9bX¿\9bZÀ\9cX¿\9bW¼\9aUÀ\9eV `Ã\9f^Ä \Å¡YÃ\9fYÇ£]Å\9cSÆ\9dUÁ\98OÁ\9dWÅ\9fX¾\95L½\95Kº\91Kµ\8fJ\88C´\8eH¾\95PÁ\9f]Á\9fdÁ£jª\92Y\80l1hS\19jV"q[0iV,m]0|jE´©\8dÔÌ°Ùϸ×зÚÒ»ØкÞÖÂÛÓ¿ÜÔ¿ÛÓÁÝÕÂÜÔÃÜÔ¾ÜÔ¿ÛÓ¿ÝÔÁÝÕ¿ÚÒ¼ÝÕ¿ÜÔ¿ß×ÃÜÔÁÜÔÁ\89|i\9e\92}ÔɲÛÔÁß×ÅàØÅß×ÅÞ×ÂàÙÆãÛÈáÙÇâÚÇãÜÉãÛÊáÙÉãÛÊäÜÍåÝÍãÜÌäÝÊåÝÊåÞËãÛÊåÞÍåÝÊåÞËçßÌçàÍéáÐæßÎæÝÎåÞÎèàÐçßÏçßÏèáÑéáÒéâÑèáÑèâÓêáÏçàËéâÎèáÎéâÏèàÍéâÎéáÑéâÒéâÒèáÒêâÓëäÔëäÕëäÔêäÔéâÒéâÒèàÐêãÓêãÑêãÐëäÓìæÖëäÔëäÔëãÔêâÑëåÓìåÒêãÐëãÓêãÑêãÑéâÓéâÑéâÏêãÑêãÒêãÓêâÐéáÎêâÐëáÐêàÏêâÎéßÍêáÌéàËéáËéáËéàÊèàËíç×ìåÔíåÔíåÓìåÔìäÒëâÑêáÐêáÑëäÒëåÒëãÑêãÑëäÑëäÓëäÓêãÐéâÏéâÏêãÐèàÎèáÎêãÐêãÑêãÎéâÐéâÏéâÐéâÏèàÎêâÐêäÒêãÑêäÔèáÐéâÒéâÒéáÏêãÓèáÐéáÑéáÑêâÐëåÒëãÒêâÑëâÑêáÏëãÐëáÐëàÏêßÎèßËçÞÉçÞÉæÝÇäÛÆäÛÅãÚÅåÜÆäÛÅæÝÇçÞÉçÞÉçÝÈèßÍèßÊèàÊçÞÉçÜÈäÚÅäÛÃâÙÁÜÓ»ÚгÏũȺ\92ñ\84¾¦}¨\98pª\8fc£\84Q£\81N§\80M¤}L¨~I£zA©\7fD¦}E§~G©\80E¦~G¬\85N²\8aM¬\86H®\85L´\8aW±\8bK³\8aI®\88C©\83=ª\808¥y3¯\84B®\88F´\8cI¸\95U¹\95Rµ\90K¶\8aG´\8bG¹\92U»\95UÀ\9bZ½\98VÂ\9eYÂ\9fYÆ Z½\9aU¹\94O¿\96O½\99PÄ\9cRÃ\9aQ¼\94J¶\91L³\8cG¶\90M¼\98X¿ aÄ e»\9ef\9c\87M{c'lY"iY%l\.q_6p`5\8b}\Ä»¢ÕÏ´ØθÙÒºÙÒºØкÛÓ¾ÜÔ¾ÝÕÀÝÕÂÜÔÁÜÔÁÚÒ¾ÚÒ¼ÚÒÀÞÖÃÜÔÂÜÔ¿ÝÕÁÝÕÁÜÔÀÝÕÀÜÔ¿\8a}kª \8dÖ̶ÜÔ¿ÝÕÁÞ×Äß×ÅàØÄáØÆâÚÇãÛÈãÜËâÛÊãÜËãÚËãÛÌäÜÊåÞÎãÛËäÝËäÜÉåÝÊåÝËáÚÇçßÌäÜÉåÞËçßÌçßÍäÝÍåÝÍçßÏæßÏçßÏéáÑçáÑèßÏèàÍéáÏçàÍéâÏçßÍèáÎèáÎéâÏèáÎéâÒéáÑèáÑêäÔêãÔéâÓëåÔéáÐìåÕëåÕëäÔéáÏëãÑêãÐêãÑëåÒëåÒìæÓêãÑêãÑéâÐêãÒëäÕêâÐêãÑêãÐéáÏèáÎèàÎêâÐèßÍéâÏéâÐéáÐêáÐéàÎêáÐêáÏçÝÌèßËéàËèßÊçÞÉæÝÇåÜÆçÞÉëãÏíæÕíçÖìäÓìæÔëãÒëäÕëãÓêáÒèßÏéãÒëäÕéáÑéâÒëåÕëåÔëäÔêãÐëäÒéâÐèáÎêãÐéâÏéâÐêâÐçàÎéâÏêâÑèáÐçàÍèàÎêãÒìåÔëäÔéâÑìåÔëäÓêãÒéâÑèáÐéâÑêâÒéâÑéâÐëäÒëåÕêãÑëãÑêâÑëâÒìãÒêáÐéáËêáÐçÞÍæÝÉæÝÊçÝÊèÞÌæÛÊãØÅæÜÊåÜÇåÜÆæÝÇçÞÈèßÉéàËèßÉéàÊçÞÉåÜÇåÜÃçÞÈäÛÃãÚÂåÜÄãÚÂßÖ»ØϵÑƪÊÁ¤À±\91¼©\89²\9cuª\91i¤\8db\9e\84X§\86L¬\89W©\84M¥}D¤~H¦\7fH®\88N©\82G©\81F¬\86K³\8dM¶\90Q´\8fO¯\8aG\84@§{:£y9¢z8ª\83>°\8cJ³\8dN¯\8dK¯\89G\88H´\91Pº\96V¼\97W¼\96W»\96VÂ\9f^Á\9d]º\95Q±\8eL°\8aB¶\93OÀ\9bRÂ\9cXº\96P³\8dL¶\90P·\95TÀ\9eeÀ¡d¿ f·\9cg\99\85Osa+jZ(m\/l[-m\1xi=¢\95vÏÅ©×ζÚк×Ï·ÚÓ»ÜÔ¿ÝÕ¿ÙѽÞÖÃÝÕÂÜÔ¿ÛÓÀÛÓÀÛÓÀÜÔÀÜÔÀÛÓ½ÝÕÀß×ÁÝÕÀÜÔ¿ÛÓ¿ÝÕÁ\87|k´©\97ÙѽÜÔÁÝÕÄáÙÆâÚÈàØÆâÛÈàØÅãÛÉâÚÇãÛËäÜÌãÜÌáÙÉãÜËåÜÌäÝÎäÛÌåÝÍäÜÊæÝËäÝÊåÝËäÜÊæßÌæßÌæÞÌãÝÏåÞÎæÞÏèáÏçßÏèàÐçàÐéáÎçßÍçàÍéâÏèàÍèàÎèáÎëãÑèáÎçàÎéâÐèâÐêãÓêâÑèáÍêâÒêâÑêãÑêãÐëäÒêäÑéáÏéãÐèâÏëäÑéâÏéâÏéáÏêâÎéáÏëãÐéáÐêáÏëãÑêâÐêâÏéáÎçßÍèàÎèßÌèàÎèàÎéâÐèáÎéßÎçÞÍçÝËéßÎèÝËèÞÌåÝÇæÝÇâÚÄäÛÆåÜÇäÛÅèàÉìæÔíæÕìäÒëåÓëäÒëåÓêãÔéâÐëäÑêäÑëãÑéâÏëåÒëäÒëåÒëäÑëåÒëäÕêãÓêâÒéáÒéáÑéâÐçàÍèàÏèàÑéâÐéâÒêãÑéáÒêãÓëãÔëäÖêãÔéãÓëäÔéáÒêâÓêâÒéãÓêãÓêâÒéâÓêãÓëäÒëäÑêãÐêäÑëäÔêâÑëâÑêáÏèÞÌéÞÍçÝÌèÞÌçÝËèÞÌéÞÍæÜËçÝËæÛËæÜËæÜËæÜËéáÌèÞËèàËéàËçÞÉæÝÈæÝÆäÛÆäÛÅäÛÂåÜÃäÛÃäÛÅäÜÆãÚÃâÙÃßÖ½ÙϹÎŪǽ ½±\97º«\8a¯\9ev®\9bp¥\8d_¨\8b`¢\82S¨\81N«\88N¬\85N«\84O®\89N±\8dPµ\90V¶\93X·\92T¶\8fP¯\87I¥|?¥}>¨\7f>ª\83G¯\88P±\8bR²\8eP±\8dP¶\92W½\9a[º\97V·\95Tº\93U¹\95T»\98V¹\95Q¬\89H®\8aG´\91P¼\97Yº\95V·\8eL°\8bI°\8aI´\91P¹\99[¼\9da³\97]¯\95\\97\7fJo`.hY*m\1p_3sc:\86xP»±\8e×αÛѸÚѸ×ϸÚÓ»ÛÓ¾ÜÔ¿ÝÕÀÝÕÁÝÕÂÚÒÁÝÔ¿ÚÒ¾ÜÕÀÛÓÁÝÕÁÛÓÁÜÔÀÜÔÁß×ÄÜÔÀÞÖÂÝÕÂ\8a|eÁ¸\9dØÓ¾ÜÔÁÝÕÃÝÕÃÞÖÃáÙÉáØÆáÙÆâÚÇáÙÆàØÈâÚÊáÚÊãÛËãÜËãÜËäÝÍæÞÍäÝËåÝÊæÞËåÝÊåÝÊåÞËåÜÊæßÌåÝÊåÞÌåÞÎãÛËèáÑçßÐçßÏäÜËçàÎèàÎçàÍèàÎçßÍèáÎèáÎçßÍéáÏçßÌèáÎêâÐéâÏçàÎèáÎèáÏéáÐèáÎéâÏéâÒìãÒèáÏéáÏèàÍêâÐéâÐèàÎéâÎéáÎçÞÌëáÐêáÐéàÎéàÎêáÐèßÎèÞÍèÝÌèßÎçÝËåÚÉèÞÍæÜÊçÜËæÜËæÛÊåÛÉåÚÉåÛÊãÚÆäÛÆãÙÅàÖÂà×ÂßÔÁâØÄéßÍíæÖíæÖíäÓëäÑêãÐêäÑêâÐéâÏéâÏêãÐêãÐêâÐëäÑëãÑêãÐëãÑêâÏêâÐéáÏêâÏéáÏéáÎçßÍéáÐèáÍèáÐêãÔçáÒéâÑëãÔéáÒêâÒêãÖëäÕêãÔêãÓêãÓéâÓëäÔêãÔéáÒéáÒéâÒëãÔéâÓëäÔëåÓëãÑëâÑìäÕìãÓêáÐéàÏçÝÌêàÏèßÎèÞÍèßÍçÝËæÛÊæÜËäÛÉèÞÌçÝËéàÍéÞÍéàÊéàËéáËæÝÈæÝÇæÝÈäÛÆåÜÄãÚÃäÛÆåÜÇåÜÇåÜÇäÛÅäÛÆæÝÅåÜÇåÛÆäÛÅáØÃÚÑ·ÓʯËÁ¤É¼\9d½¬\87¸¡z¹¡y¬\98n¬\94i±\92h®\8c[\8aU²\8eV·\93Zº\97_¹\95`´\90X¬\87P«\86N«\85Q\87R§\81J\86Q³\8fTµ\90W¹\94\º\96X»\97Y¸\96V¶\93S¸\95T²\90N´\91O°\8dK±\8cK®\8bK±\8dM±\8dL²\8dL¦\83B©\88G¬\8cQ±\94]´\99c\92_§\90W\8eyAp`0k]-k\0m^2vg>¢\93oÍæÙϵÛÒ¹ÜÒºÙÓºÙÒ»ÜÔ¼ÝÕ½ÛÓ¾ÛÓ½ÜÔ¾ÝÕ¿ÜÔ¾ÙѽÚÒ¾ÜÔ¿ÛÓ¿ÚÒ¿ÛÓÀÝÕÂÞÖÃÞÖÄÜÔÃÝÕÄ\93\85qɾ¦ÚÔÀÛÒ½ÝÕÂß×Åß×Äß×ÄàØÅàØÅâÛÇáÙÆáÚÇß×ÅãÛËâÛËâÚÇãÛËäÜÌçßÎåÝÊãÚÈæÞËâÛÈãÜÈäÛÉåÝÊäÜÊæÞÌâÚÈãÜÊåÝËæßÍèàÎäÝÊãÜÉæÞËèàÍæÞËåÝËèàÎçßÌçàÍèßÍçßÍèàÑèàÌçàÐéáÎçßÍçàÍçßÌçßËçßÍçßÍéáÎæßÌèáÎçßÍèàÎéáÎçßÍçßÍçßÍæÝËçÝËæÜÊèßËæÜÈèßÌçÞÉçÝÉèÞËæÛÉæÜÊãØÇãÚÅæÛÊåÚÉçÜÍæÛËåÚÉäÙÈåÚÉåÚÉåÜÆäÛÅáØÃâÙÃà×ÁßÔÃßÔÂçßËìäÔëäÓëãÒëäÒêâÐéáÏéáÎéáÏêãÐèáÏèáÏéâÐêãÑêâÑéáÏèáÏéáÏèàÎèáÎéáÏèáÐçßÍèáÑêãÓêâÓëãÓêãÔèâÓëäÔêãÓèáÑéãÓëäÔêãÓêãÓêäÔëãÔëäÔéâÒëåÕêäÔêâÓêãÒçàÏçáÑêãÓëåÔëåÔéâÑëäÔëäÒéáÏêâÐçßÌçÞÌéáÏèàÎçÞÌçÜÌåÚÉçÝËæÜÊèÞÌêàÍèàËèßÏèßÍéàÊéàËèßÉéàËäÛÆæÝÈåÜÇäÛÆäÛÆãØÇãØÇåÚÈãÙÇäÚÉâÙÅäÛÅäÛÄæÝÈåÛÅåÜÅäÚÃâÙÀàÖ¿ÛÒ·ÚѸÑƪÍæɿ ƹ\94ñ\8d·¢v·¢w®\97l²\98n±\94e®\91a³\91_°\8dZ²\8d\¯\8cY¯\8bV\8aT®\8aT±\8dV´\8fW·\93Y¶\91V²\8eR²\8eR±\8eO¯\8cN\8aJ®\8cO±\8eN¬\8bN«\88I¤\80=¦\82>¡\81?¡\84E¦\89N¨\8cV¨\8d[ \89T\9c\87R\88q8o^+l^.qb4ue<\85yQ¹°\90Ô̱ÛÒ¹Ù϶ÙÑ·ÚÓ¹ÙѼÚÒ»ÛÓ½ÛÓ½ÜÔ¾ÜÔ½ÚÒ¿ÜÔ¿ÛÓ½ÚÒ½ÜÔÀÜÔÁÜÔÂÛÓ¿ÜÔÁÜÔÁÜÔÂÞÖÄÜÒÃ\9b\90zÒÈ´ÜÓÂÜÕÁÞÖÃÝÕÃÞÖÄàØÅß×Äß×ÅàØÆãÛÉàØÅáÙÆáÙÆàØÆãÚÇß×ÅâÚÈäÜÉâÚÈäÜÉäÝËâÚÈäÜÊãÛÈãÛÈåÞÊáÙÇãÛÈãÛÉâÛÈäÜÊæßÌäÜÊæÞËâÛÈåÝÊæÞÌèáÎçßÍäÜÊæÞËçàÍåÝËæÞËåÞÌåÝËäÝÊåÞËæÞËåÝÉåÜÉçÝËæÝÌçßÌèÞÍçÜËæÛÊæÜËçÝËåÛÊæÝÇäÛÅãÚÄãÙÄãÚÅâÙÃäÛÆäÚÇåÝÇäÛÆåÜÆæÝÉåÚÉåÛÊãÙÈãØÆæÛÊãÙÇåÚÉåÛÉåÛÉçÞÌåÜÇäÛÆåÜÇäÛÅáØÃÝÔ¿ÝÒÁá×ÄåÝËìæÕìæÓìâÑèáÎéâÏéâÐèàÎèàÍèàÎèàÎèßÍçàÎçßÌêãÐçàÎèàÎèàÎéâÏèàÎæßÌêâÐèàÎèàÏéâÒêãÓêäÓêâÒëäÔëäÕéâÒèàÐéâÑêãÔêâÔèãÕêãÓêäÔêäÔêãÓêãÔêãÓêãÓèàÐêãÔéàÑëåÕêäÔëäÕëåÕéâÒêâÒêâÐéâÐçàÑçàÎéáÑèàÏæßÍåÜÊêßÎèàÎåÜÊéÞÍéßÎéßÎêáÐêàÎêàÏêàÎèßÌèßÌçÞÉèßËçÝÉæÝÈãÙÈäÙÈäÙÈãÙÇãÙÇäÙÈåÚÉãØÇãÙÅåÜÆâÙÄäÛÆâÙÄãÚÆçÞÈåÜÇäÛÂçÞÆæÝÅäÛÃÝÓ¹ÛÒºÔɪÌÃ\9aɽ\9aÀ°\86¹¨|´¤\7f±\9cu«\95k¨\8e`¬\90bª\8dZ¯\8dX²\8fZ°\8dY\8cT±\8eU¬\87N«\88M¬\89Q¯\8cRª\87I¨\84H¬\8aQ¯\8dP¯\90S©\88E£\7f>¢{<\9fz;£\7fC£\86L¥\89T \87Y¡\89Z\9c\86V\80h1m])l]-qd;xh>£\98rÈ ×βÚÑ·ÙзØÒ¸ÙÓºÜÔ¾ÜÔ¾ÛÓ½ÝÕ¿ÞÖÄÛÓ¾ÞÖÀÞÖÃÜÔÀÜÔÂÚÒ¿ÜÔÁÛÓÀÜÔÁÛÓÁÜÔÀÞÖÃÚÒ¿ÛÓ¿¡\86ÖεÜÔÁÝÕÂÜÔÁß×ÄàØÇÞ×ÄßÖÄß×ÅáÙÇàÙÆáÙÇß×Äß×ÇàØÆáÙÇâÚÈâÛÊãÛÈãÛÈâÚÇâÚÉâÛÈâÛÇãÛÉáÙÇãÛÉâÚÇáØÅãÜÉâÚÇãÛÉãÛÈâÛÈáÚÇæÜÊãÚÈæÝËåÜÊåÝËåÝÊäÜÉåÝËäÝÊãÜÉåÝÊäÜÉäÜÊåÝÊåÞÉãÛÇàÖÅåÚÈäÙÈæÜÊåÚÈäÚÉãÚÈåÛÉäÚÉäÙÈâØÇâØÆãØÇâØÆãØÈãØÇãØÇâØÄåÜÇâÙÄâÙÃáØÃãÚÆäÚÇåÛÈâØÆäÚÉäÚÉæÛÊåÚÉäÚÈåÛÉäÚÉæÜÊäÛÆâÙÄßÕÃßÔÁÜÒÁÝÓÁçÝÍíåÖëåÓìäÒêãÓéâÑçàÏçàÏçßÍèàÎçàÍçßÌæÞÌåÞËæàÍçàÍçàÍæÞÌæÞËçàÍèàÎèàÍèáÎçàÎéáÏèáÐêâÐêäÔêãÓìåÕêãÓèáÑêãÓéáÓêâÔêâÒèáÒëäÕéáÑëäÔêâÓëäÔêãÔéâÒéâÒéáÒéáÒëäÔëåÕêãÓëäÔêãÓêãÓèáÒèáÐèàÑèàÐèßÎåÞÌæßÌåÞËèßÌèßÍçÞÌçÝÌêàÏêàÏêàÎèßÍêàÏêàÏèÝÌéßÍæÜËèÞÍåÚÉçÜËæÛÊãÙÇäÚÉåÛÉãÙÈâØÆãÙÈâØÆâØÅâÙÄáØÂâÙÃãÚÄäÛÃãÚÃãÚÃåÜÆåÜÄæÝÅæÝÅåÜÄãÚÂáØ¿ßÕ½ÙжÓÉ°Í¥;\9d¶\94¹¬\8d²¡|«\98n©\91d¯\94j¯\94f©\8f_ª\8d\¨\88T§\88R«\8aX®\8dS©\88L§\83K\8cQ³\92T°\90W¬\8eQ©\88K§\86M ~D£\84J¡\85M¢\89R£\8d^\9d\87Y\94\7fQ\7fi9o_-pe7reC\95\89hĺ\9cØѶÙѹØÓ¸ÚÔ¹ÛÓ»ÚÒ¼ÝÕ¿ÝÕ¿ÜÔ¾ÜÔ¾ÛÓÁÝÕÁÛÓÀÞÖÁÚÒÀÛÓÀÚÒÀÝÕÂÛÓÁÜÔÂÛÔÀÚÓÂÜÔÄÛÓÁØн¾¯\93Ù϶ÞÖÃÝÖÂÞÖÄÝÕÃÜÔÁÞÖÄß×ÅàØÅàØÅàØÆâÙÆáÙÆàÙÆâÛÈâÚÈãÛËâÚÉâÛÊáÙÉáÙÉâÚÊâÚÈàØÆáÙÉâÚÇáÙÆß×ÄáÙÇâÚÇàÙÆáÙÇâØÇãÙÈäÚÈæÛÊåÚÉåÚÉãÚÆâÚÇâÛÈãÛÊãÛÊâÚÈâÚÈÞÖÅâÛÊâÚÈâÛÈáÙÆáÙÆà×ÅãØÇáÖÅãÙÆáØÅäÙÈãÙÊáÖÆá×Æá×ÆäÙÈâ×ÆâØÇâÙÄäÚÅãÚÆàÖÃâÙÅá×ÃáØÃãÚÄäÛÅãÚÄäÛÅäÛÅåÛÊæÜËçÜËçÜËæÜËéÞÍæÛÉæÛËåÛÊæÛÉâÙÅá×ÃßÕÁÝÒÁßÕÄæÝÌìäÕëåÔêäÑêãÒçßÏçàÍçàÎèàÍåÝËæßÌæßÌæßÌäÝÊåÞËçàÍçßÌåÝËæßÍæßÌêâÐéâÏèàÎèáÏèàÑèáÑêâÓéâÒëäÕéâÒéáÒéáÐëäÔêãÓêãÓëäÔëãÔêãÔéâÒéâÒéáÑéâÒéâÑêãÔéâÒêãÓêãÓêãÔìæÖëãÔëåÕêâÓêãÓéãÓéáÒèáÑçàÐèàÐçßÏåÞÎçßÎèàÏåÝËæÝÌêÞÍéßÎêáÏêáÐêàÏéßÎéßÎèßÍéÞÍçÝÌçÝÌçÝËæÛÊæÜÊäÙÈåÜÊãØÇãÙÈåÛÉäÚÈåÛÇäÙÈäÙÈâÙÃãÙÄâØÃãÚÅãÚÅáØÃâØÃâÙÄâÙÄãÚÂäÛÃæÝÇãÚÄâÙÁà×ÁáÙÄà×¾ÞÕ¹ÜÒº×δÎŦɺ\9f½±\94¾±\94·¦\81¯\9ew\97o§\8ff¦\8b]¢\87Y¨\8cZ©\8aVª\8aU¨\89O©\8bP¯\90Y©\8bT¨\88O¦\87P¢\83I\9d\80K\9b~K¢\85S¢\89Y\9e\86[\93~Nwf7o_4rf>\86z]¶ª\8fÓɯØÒ¹ÙÒ¹ÛÔºÛÓ»ÜÔ½ÛÔ¼ÜÔ¿ÜÔ¾ÝÕ¿ÝÕ¿ß×ÁÜÔÃÜÔ¿ÚÒ¼ÛÓ¾ÛÓÀÙѾÝÕÂÛÓ¿ÝÖÅÛÕÄÛÔÄÛÓÀÙÑ¿ÝÕÄÊÁ§ÚÒºÛÓÀÝÕÂÞÖÃÝÕÂÞÖÄß×ÄÝÕÃÞ×Äß×ÄàØÅß×ÅàØÅáØÆß×ÅàÙÆàØÇàÙÇãÛÉáÙÇâÛÉáÚÇáÙÆáÙÆáÙÇàØÅß×ÄÞÖÃÞÖÂáØÅâ×ÅáÖÄáÖÅàÕÃá×ÄáÖÅáØÂâÙÅâØÅâØÆß×ÅàØÆàØÅâÚÇàØÆàØÅàØÆàØÆàØÅàÙÅâÚÈáØÆàÖÄâØÆãØÇáÖÅáÖÄáÖÅàÖÃßÔÃâØÅâ×ÅäÚÈãØÇãÙÅãÙÅãÚÄãÚÆâØÅâØÄãÙÄãÚÄâÙÂäÛÆåÜÈæÝÉæÜÈäÚÉåÛÉæÜÊæÜÊçÝËçÝËæÛÊæÜÊäÚÉäÛÅãÚÆà×ÃÝÔÂÝÕÄæßÍëåÕëäÔëåÒéáÒéáÑçßÏçßÍãÛÊæßÌåÝÊæßÍåÝËåÞËäÝÊåÝËæÞËæÞËæßÏæàÎèàÎèáÐèáÐéáÑçßÏèàÐéáÑèàÐèàÐéâÒéâÒêâÓêãÓëäÔëäÔëãÕêäÕêäÔêãÓêãÔéáÒéâÑéâÒèáÑæÞÎéâÒèàÑêâÒëåÔëäÔêãÓêãÔéâÒéâÒéáÑèàÑèáÑèáÑçàÐçßÏæßÏéáÑçàÎèáÏèàÏêàÏéàÎêàÎëâÑéàÎêàÏéßÍçÝÌçÞÌåÞËæÝËäÜÊäÜÉåÝÊäÜÊâÛÈâÚÈäÙÈäÚÉæÜËåÛÉãÚÄãÙÄãÚÅâÙÃáØÃáØÂáØÃáØÂâÙÃãÚÅâÙÃâÙÁà×Àà×ÂàÖÁâØÃà×ÁáØÂá×Âà×ÁßÖ¿ÝÕ¼ÛÒ¹ÛÒ¹ØεÒäͼ\96ĵ\98ò\96¹¨\88±¢\80µ£}¬\98q¦\91e¡\88Y\9f\84W \87X\9e\83N¡\85P\9d\81L\9a}I\9a|J\99~N\9e\85U\96\7fL\94~M\87qIwe9rf=\88zV¬¦\8aÍÄÙѸÙÒ¹ÙѼÚÒ»ÛÓ¾ÚÒ¼ÞÖÀÜÔÀÞÖÁÝÕÃÝÕ¿ÛÓ¾ÞÖÀÛÓ½ÜÔ¿ÛÓÀÚÒ¾ÙѼÚÒ¿ÛÒ¾ØÒÃÙÒÃÜÕÅÜÔÃÝÕÅÜÔÂ
\ No newline at end of file
switch (len) {
case 1:
case 2: {
- int64_t a = buf[0][j];
- int64_t b = buf[1][j];
+ int64_t a, b;
int dist;
if (len == 2) {
a = get_s16l(buf[0] + j);
} while (0)
static void rgb24_to_yuv420p(unsigned char *lum, unsigned char *cb,
- unsigned char *cr, unsigned char *src,
+ unsigned char *cr, const unsigned char *src,
int width, int height)
{
int wrap, wrap3, x, y;
int r, g, b, r1, g1, b1;
- unsigned char *p;
+ const unsigned char *p;
wrap = width;
wrap3 = width * 3;
#define DEFAULT_NB_PICT 50
static void pgmyuv_save(const char *filename, int w, int h,
- unsigned char *rgb_tab)
+ const unsigned char *rgb_tab)
{
FILE *f;
int i, h2, w2;
#include "libavutil/sha512.h"
#include "libavutil/ripemd.h"
#include "libavutil/aes.h"
+#include "libavutil/cast5.h"
#define IMPL_USE_lavu IMPL_USE
av_aes_crypt(aes, output, input, size >> 4, NULL, 0);
}
+static void run_lavu_cast128(uint8_t *output,
+ const uint8_t *input, unsigned size)
+{
+ static struct AVCAST5 *cast;
+ if (!cast && !(cast = av_cast5_alloc()))
+ fatal_error("out of memory");
+ av_cast5_init(cast, hardcoded_key, 128);
+ av_cast5_crypt(cast, output, input, size >> 3, 0);
+}
+
/***************************************************************************
* crypto: OpenSSL's libcrypto
***************************************************************************/
#include <openssl/sha.h>
#include <openssl/ripemd.h>
#include <openssl/aes.h>
+#include <openssl/cast.h>
#define DEFINE_CRYPTO_WRAPPER(suffix, function) \
static void run_crypto_ ## suffix(uint8_t *output, \
AES_encrypt(input + i, output + i, &aes);
}
+static void run_crypto_cast128(uint8_t *output,
+ const uint8_t *input, unsigned size)
+{
+ CAST_KEY cast;
+ unsigned i;
+
+ CAST_set_key(&cast, 16, hardcoded_key);
+ for (i = 0; i < size; i += 8)
+ CAST_ecb_encrypt(input + i, output + i, &cast, 1);
+}
+
#define IMPL_USE_crypto(...) IMPL_USE(__VA_ARGS__)
#else
#define IMPL_USE_crypto(...) /* ignore */
gcry_cipher_encrypt(aes, output, size, input, size);
}
+static void run_gcrypt_cast128(uint8_t *output,
+ const uint8_t *input, unsigned size)
+{
+ static gcry_cipher_hd_t cast;
+ if (!cast)
+ gcry_cipher_open(&cast, GCRY_CIPHER_CAST5, GCRY_CIPHER_MODE_ECB, 0);
+ gcry_cipher_setkey(cast, hardcoded_key, 16);
+ gcry_cipher_encrypt(cast, output, size, input, size);
+}
+
#define IMPL_USE_gcrypt(...) IMPL_USE(__VA_ARGS__)
#else
#define IMPL_USE_gcrypt(...) /* ignore */
aes_ecb_encrypt(input + i, output + i, &aes);
}
+static void run_tomcrypt_cast128(uint8_t *output,
+ const uint8_t *input, unsigned size)
+{
+ symmetric_key cast;
+ unsigned i;
+
+ cast5_setup(hardcoded_key, 16, 0, &cast);
+ for (i = 0; i < size; i += 8)
+ cast5_ecb_encrypt(input + i, output + i, &cast);
+}
+
#define IMPL_USE_tomcrypt(...) IMPL_USE(__VA_ARGS__)
#else
#define IMPL_USE_tomcrypt(...) /* ignore */
"7c25b9e118c200a189fcd5a01ef106a4e200061f3e97dbf50ba065745fd46bef")
IMPL_ALL("RIPEMD-160", ripemd160, "62a5321e4fc8784903bb43ab7752c75f8b25af00")
IMPL_ALL("AES-128", aes128, "crc:ff6bc888")
+ IMPL_ALL("CAST-128", cast128, "crc:456aa584")
};
int main(int argc, char **argv)
for (;;) {
int size = read(fd, buffer, SIZE);
if (size < 0) {
+ int err = errno;
close(fd);
finish();
- printf("+READ-FAILED: %s", strerror(errno));
+ printf("+READ-FAILED: %s", strerror(err));
ret = 2;
goto end;
} else if(!size)
#include "cmdutils.h"
#include "libavformat/avformat.h"
+#include "libavformat/isom.h"
#include "libavformat/os_support.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/mathematics.h"
return ret;
}
+static int64_t read_trun_duration(AVIOContext *in, int default_duration,
+ int64_t end)
+{
+ int64_t ret = 0;
+ int64_t pos;
+ int flags, i;
+ int entries;
+ avio_r8(in); /* version */
+ flags = avio_rb24(in);
+ if (default_duration <= 0 && !(flags & MOV_TRUN_SAMPLE_DURATION)) {
+ fprintf(stderr, "No sample duration in trun flags\n");
+ return -1;
+ }
+ entries = avio_rb32(in);
+
+ if (flags & MOV_TRUN_DATA_OFFSET) avio_rb32(in);
+ if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) avio_rb32(in);
+
+ pos = avio_tell(in);
+ for (i = 0; i < entries && pos < end; i++) {
+ int sample_duration = default_duration;
+ if (flags & MOV_TRUN_SAMPLE_DURATION) sample_duration = avio_rb32(in);
+ if (flags & MOV_TRUN_SAMPLE_SIZE) avio_rb32(in);
+ if (flags & MOV_TRUN_SAMPLE_FLAGS) avio_rb32(in);
+ if (flags & MOV_TRUN_SAMPLE_CTS) avio_rb32(in);
+ if (sample_duration < 0) {
+ fprintf(stderr, "Negative sample duration %d\n", sample_duration);
+ return -1;
+ }
+ ret += sample_duration;
+ pos = avio_tell(in);
+ }
+
+ return ret;
+}
+
+static int64_t read_moof_duration(AVIOContext *in, int64_t offset)
+{
+ int64_t ret = -1;
+ int32_t moof_size, size, tag;
+ int64_t pos = 0;
+ int default_duration = 0;
+
+ avio_seek(in, offset, SEEK_SET);
+ moof_size = avio_rb32(in);
+ tag = avio_rb32(in);
+ if (expect_tag(tag, MKBETAG('m', 'o', 'o', 'f')) != 0)
+ goto fail;
+ while (pos < offset + moof_size) {
+ pos = avio_tell(in);
+ size = avio_rb32(in);
+ tag = avio_rb32(in);
+ if (tag == MKBETAG('t', 'r', 'a', 'f')) {
+ int64_t traf_pos = pos;
+ int64_t traf_size = size;
+ while (pos < traf_pos + traf_size) {
+ pos = avio_tell(in);
+ size = avio_rb32(in);
+ tag = avio_rb32(in);
+ if (tag == MKBETAG('t', 'f', 'h', 'd')) {
+ int flags = 0;
+ avio_r8(in); /* version */
+ flags = avio_rb24(in);
+ avio_rb32(in); /* track_id */
+ if (flags & MOV_TFHD_BASE_DATA_OFFSET)
+ avio_rb64(in);
+ if (flags & MOV_TFHD_STSD_ID)
+ avio_rb32(in);
+ if (flags & MOV_TFHD_DEFAULT_DURATION)
+ default_duration = avio_rb32(in);
+ }
+ if (tag == MKBETAG('t', 'r', 'u', 'n')) {
+ return read_trun_duration(in, default_duration,
+ pos + size);
+ }
+ avio_seek(in, pos + size, SEEK_SET);
+ }
+ fprintf(stderr, "Couldn't find trun\n");
+ goto fail;
+ }
+ avio_seek(in, pos + size, SEEK_SET);
+ }
+ fprintf(stderr, "Couldn't find traf\n");
+
+fail:
+ return ret;
+}
+
static int read_tfra(struct Tracks *tracks, int start_index, AVIOContext *f)
{
int ret = AVERROR_EOF, track_id;
ret = AVERROR(ENOMEM);
goto fail;
}
+ // The duration here is always the difference between consecutive
+ // start times.
for (i = 0; i < track->chunks; i++) {
if (version == 1) {
track->offsets[i].time = avio_rb64(f);
track->offsets[i - 1].duration = track->offsets[i].time -
track->offsets[i - 1].time;
}
- if (track->chunks > 0)
- track->offsets[track->chunks - 1].duration = track->duration -
+ if (track->chunks > 0) {
+ track->offsets[track->chunks - 1].duration = track->offsets[0].time +
+ track->duration -
track->offsets[track->chunks - 1].time;
+ }
+ // Now try and read the actual durations from the trun sample data.
+ for (i = 0; i < track->chunks; i++) {
+ int64_t duration = read_moof_duration(f, track->offsets[i].offset);
+ if (duration > 0 && abs(duration - track->offsets[i].duration) > 3) {
+ // 3 allows for integer duration to drift a few units,
+ // e.g., for 1/3 durations
+ track->offsets[i].duration = duration;
+ }
+ }
+ if (track->chunks > 0) {
+ if (track->offsets[track->chunks - 1].duration <= 0) {
+ fprintf(stderr, "Calculated last chunk duration for track %d "
+ "was non-positive (%"PRId64"), probably due to missing "
+ "fragments ", track->track_id,
+ track->offsets[track->chunks - 1].duration);
+ if (track->chunks > 1) {
+ track->offsets[track->chunks - 1].duration =
+ track->offsets[track->chunks - 2].duration;
+ } else {
+ track->offsets[track->chunks - 1].duration = 1;
+ }
+ fprintf(stderr, "corrected to %"PRId64"\n",
+ track->offsets[track->chunks - 1].duration);
+ track->duration = track->offsets[track->chunks - 1].time +
+ track->offsets[track->chunks - 1].duration -
+ track->offsets[0].time;
+ fprintf(stderr, "Track duration corrected to %"PRId64"\n",
+ track->duration);
+ }
+ }
ret = 0;
fail:
const char *type)
{
int i, j;
+ int64_t pos = 0;
struct Track *track = tracks->tracks[main];
int should_print_time_mismatch = 1;
}
}
}
- fprintf(out, "\t\t<c n=\"%d\" d=\"%"PRId64"\" />\n",
+ fprintf(out, "\t\t<c n=\"%d\" d=\"%"PRId64"\" ",
i, track->offsets[i].duration);
+ if (pos != track->offsets[i].time) {
+ fprintf(out, "t=\"%"PRId64"\" ", track->offsets[i].time);
+ pos = track->offsets[i].time;
+ }
+ pos += track->offsets[i].duration;
+ fprintf(out, "/>\n");
}
}
--- /dev/null
+/*
+ * Copyright (c) 2014 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 <stdio.h>
+#include <string.h>
+
+#include "libavformat/avformat.h"
+#include "libavutil/avstring.h"
+#include "libavutil/intreadwrite.h"
+#include "libavutil/mathematics.h"
+
+static int usage(const char *argv0, int ret)
+{
+ fprintf(stderr, "%s -out foo.mpd file1\n", argv0);
+ return ret;
+}
+
+struct Track {
+ const char *name;
+ int64_t duration;
+ int bitrate;
+ int track_id;
+ int is_audio, is_video;
+ int width, height;
+ int sample_rate, channels;
+ int timescale;
+ char codec_str[30];
+ int64_t sidx_start, sidx_length;
+ int64_t earliest_presentation;
+ uint32_t earliest_presentation_timescale;
+};
+
+struct Tracks {
+ int nb_tracks;
+ int64_t duration;
+ struct Track **tracks;
+ int multiple_tracks_per_file;
+};
+
+static void set_codec_str(AVCodecContext *codec, char *str, int size)
+{
+ switch (codec->codec_id) {
+ case AV_CODEC_ID_H264:
+ snprintf(str, size, "avc1");
+ if (codec->extradata_size >= 4 && codec->extradata[0] == 1) {
+ av_strlcatf(str, size, ".%02x%02x%02x",
+ codec->extradata[1], codec->extradata[2], codec->extradata[3]);
+ }
+ break;
+ case AV_CODEC_ID_AAC:
+ snprintf(str, size, "mp4a.40"); // 0x40 is the mp4 object type for AAC
+ if (codec->extradata_size >= 2) {
+ int aot = codec->extradata[0] >> 3;
+ if (aot == 31)
+ aot = ((AV_RB16(codec->extradata) >> 5) & 0x3f) + 32;
+ av_strlcatf(str, size, ".%d", aot);
+ }
+ break;
+ }
+}
+
+static int find_sidx(struct Tracks *tracks, int start_index,
+ const char *file)
+{
+ int err = 0;
+ AVIOContext *f = NULL;
+ int i;
+
+ if ((err = avio_open2(&f, file, AVIO_FLAG_READ, NULL, NULL)) < 0)
+ goto fail;
+
+ while (!f->eof_reached) {
+ int64_t pos = avio_tell(f);
+ int32_t size, tag;
+
+ size = avio_rb32(f);
+ tag = avio_rb32(f);
+ if (size < 8)
+ break;
+ if (tag == MKBETAG('s', 'i', 'd', 'x')) {
+ int version, track_id;
+ uint32_t timescale;
+ int64_t earliest_presentation;
+ version = avio_r8(f);
+ avio_rb24(f); /* flags */
+ track_id = avio_rb32(f);
+ timescale = avio_rb32(f);
+ earliest_presentation = version ? avio_rb64(f) : avio_rb32(f);
+ for (i = start_index; i < tracks->nb_tracks; i++) {
+ struct Track *track = tracks->tracks[i];
+ if (!track->sidx_start) {
+ track->sidx_start = pos;
+ track->sidx_length = size;
+ } else if (pos == track->sidx_start + track->sidx_length) {
+ track->sidx_length = pos + size - track->sidx_start;
+ }
+ if (track->track_id == track_id) {
+ track->earliest_presentation = earliest_presentation;
+ track->earliest_presentation_timescale = timescale;
+ }
+ }
+ }
+ if (avio_seek(f, pos + size, SEEK_SET) != pos + size)
+ break;
+ }
+
+fail:
+ if (f)
+ avio_close(f);
+ return err;
+}
+
+static int handle_file(struct Tracks *tracks, const char *file)
+{
+ AVFormatContext *ctx = NULL;
+ int err = 0, i, orig_tracks = tracks->nb_tracks;
+ char errbuf[50], *ptr;
+ struct Track *track;
+
+ err = avformat_open_input(&ctx, file, NULL, NULL);
+ if (err < 0) {
+ av_strerror(err, errbuf, sizeof(errbuf));
+ fprintf(stderr, "Unable to open %s: %s\n", file, errbuf);
+ return 1;
+ }
+
+ err = avformat_find_stream_info(ctx, NULL);
+ if (err < 0) {
+ av_strerror(err, errbuf, sizeof(errbuf));
+ fprintf(stderr, "Unable to identify %s: %s\n", file, errbuf);
+ goto fail;
+ }
+
+ if (ctx->nb_streams < 1) {
+ fprintf(stderr, "No streams found in %s\n", file);
+ goto fail;
+ }
+ if (ctx->nb_streams > 1)
+ tracks->multiple_tracks_per_file = 1;
+
+ for (i = 0; i < ctx->nb_streams; i++) {
+ struct Track **temp;
+ AVStream *st = ctx->streams[i];
+
+ if (st->codec->bit_rate == 0) {
+ fprintf(stderr, "Skipping track %d in %s as it has zero bitrate\n",
+ st->id, file);
+ continue;
+ }
+
+ track = av_mallocz(sizeof(*track));
+ if (!track) {
+ err = AVERROR(ENOMEM);
+ goto fail;
+ }
+ temp = av_realloc(tracks->tracks,
+ sizeof(*tracks->tracks) * (tracks->nb_tracks + 1));
+ if (!temp) {
+ av_free(track);
+ err = AVERROR(ENOMEM);
+ goto fail;
+ }
+ tracks->tracks = temp;
+ tracks->tracks[tracks->nb_tracks] = track;
+
+ track->name = file;
+ if ((ptr = strrchr(file, '/')))
+ track->name = ptr + 1;
+
+ track->bitrate = st->codec->bit_rate;
+ track->track_id = st->id;
+ track->timescale = st->time_base.den;
+ track->duration = st->duration;
+ track->is_audio = st->codec->codec_type == AVMEDIA_TYPE_AUDIO;
+ track->is_video = st->codec->codec_type == AVMEDIA_TYPE_VIDEO;
+
+ if (!track->is_audio && !track->is_video) {
+ fprintf(stderr,
+ "Track %d in %s is neither video nor audio, skipping\n",
+ track->track_id, file);
+ av_freep(&tracks->tracks[tracks->nb_tracks]);
+ continue;
+ }
+
+ tracks->duration = FFMAX(tracks->duration,
+ av_rescale_rnd(track->duration, AV_TIME_BASE,
+ track->timescale, AV_ROUND_UP));
+
+ if (track->is_audio) {
+ track->channels = st->codec->channels;
+ track->sample_rate = st->codec->sample_rate;
+ }
+ if (track->is_video) {
+ track->width = st->codec->width;
+ track->height = st->codec->height;
+ }
+ set_codec_str(st->codec, track->codec_str, sizeof(track->codec_str));
+
+ tracks->nb_tracks++;
+ }
+
+ avformat_close_input(&ctx);
+
+ err = find_sidx(tracks, orig_tracks, file);
+
+fail:
+ if (ctx)
+ avformat_close_input(&ctx);
+ return err;
+}
+
+static void write_time(FILE *out, int64_t time, int decimals, enum AVRounding round)
+{
+ int seconds = time / AV_TIME_BASE;
+ int fractions = time % AV_TIME_BASE;
+ int minutes = seconds / 60;
+ int hours = minutes / 60;
+ fractions = av_rescale_rnd(fractions, pow(10, decimals), AV_TIME_BASE, round);
+ seconds %= 60;
+ minutes %= 60;
+ fprintf(out, "PT");
+ if (hours)
+ fprintf(out, "%dH", hours);
+ if (hours || minutes)
+ fprintf(out, "%dM", minutes);
+ fprintf(out, "%d.%0*dS", seconds, decimals, fractions);
+}
+
+static int output_mpd(struct Tracks *tracks, const char *filename)
+{
+ FILE *out;
+ int i, j, ret = 0;
+ struct Track **adaptation_sets_buf[2] = { NULL };
+ struct Track ***adaptation_sets;
+ int nb_tracks_buf[2] = { 0 };
+ int *nb_tracks;
+ int set, nb_sets;
+ int64_t latest_start = 0;
+
+ if (!tracks->multiple_tracks_per_file) {
+ adaptation_sets = adaptation_sets_buf;
+ nb_tracks = nb_tracks_buf;
+ nb_sets = 2;
+ for (i = 0; i < 2; i++) {
+ adaptation_sets[i] = av_malloc(sizeof(*adaptation_sets[i]) * tracks->nb_tracks);
+ if (!adaptation_sets[i]) {
+ ret = AVERROR(ENOMEM);
+ goto err;
+ }
+ }
+ for (i = 0; i < tracks->nb_tracks; i++) {
+ int set_index = -1;
+ if (tracks->tracks[i]->is_video)
+ set_index = 0;
+ else if (tracks->tracks[i]->is_audio)
+ set_index = 1;
+ else
+ continue;
+ adaptation_sets[set_index][nb_tracks[set_index]++] = tracks->tracks[i];
+ }
+ } else {
+ adaptation_sets = &tracks->tracks;
+ nb_tracks = &tracks->nb_tracks;
+ nb_sets = 1;
+ }
+
+ out = fopen(filename, "w");
+ if (!out) {
+ ret = AVERROR(errno);
+ perror(filename);
+ return ret;
+ }
+ fprintf(out, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
+ fprintf(out, "<MPD xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n"
+ "\txmlns=\"urn:mpeg:dash:schema:mpd:2011\"\n"
+ "\txmlns:xlink=\"http://www.w3.org/1999/xlink\"\n"
+ "\txsi:schemaLocation=\"urn:mpeg:DASH:schema:MPD:2011 http://standards.iso.org/ittf/PubliclyAvailableStandards/MPEG-DASH_schema_files/DASH-MPD.xsd\"\n"
+ "\tprofiles=\"urn:mpeg:dash:profile:isoff-on-demand:2011\"\n"
+ "\ttype=\"static\"\n");
+ fprintf(out, "\tmediaPresentationDuration=\"");
+ write_time(out, tracks->duration, 1, AV_ROUND_DOWN);
+ fprintf(out, "\"\n");
+ fprintf(out, "\tminBufferTime=\"PT5S\">\n");
+
+ for (i = 0; i < tracks->nb_tracks; i++) {
+ int64_t start = av_rescale_rnd(tracks->tracks[i]->earliest_presentation,
+ AV_TIME_BASE,
+ tracks->tracks[i]->earliest_presentation_timescale,
+ AV_ROUND_UP);
+ latest_start = FFMAX(start, latest_start);
+ }
+ fprintf(out, "\t<Period start=\"");
+ write_time(out, latest_start, 3, AV_ROUND_UP);
+ fprintf(out, "\">\n");
+
+
+ for (set = 0; set < nb_sets; set++) {
+ if (nb_tracks[set] == 0)
+ continue;
+ fprintf(out, "\t\t<AdaptationSet segmentAlignment=\"true\">\n");
+ if (nb_sets == 1) {
+ for (i = 0; i < nb_tracks[set]; i++) {
+ struct Track *track = adaptation_sets[set][i];
+ if (strcmp(track->name, adaptation_sets[set][0]->name))
+ break;
+ fprintf(out, "\t\t\t<ContentComponent id=\"%d\" contentType=\"%s\" />\n", track->track_id, track->is_audio ? "audio" : "video");
+ }
+ }
+
+ for (i = 0; i < nb_tracks[set]; ) {
+ struct Track *first_track = adaptation_sets[set][i];
+ int width = 0, height = 0, sample_rate = 0, channels = 0, bitrate = 0;
+ fprintf(out, "\t\t\t<Representation id=\"%d\" codecs=\"", i);
+ for (j = i; j < nb_tracks[set]; j++) {
+ struct Track *track = adaptation_sets[set][j];
+ if (strcmp(track->name, first_track->name))
+ break;
+ if (track->is_audio) {
+ sample_rate = track->sample_rate;
+ channels = track->channels;
+ }
+ if (track->is_video) {
+ width = track->width;
+ height = track->height;
+ }
+ bitrate += track->bitrate;
+ if (j > i)
+ fprintf(out, ",");
+ fprintf(out, "%s", track->codec_str);
+ }
+ fprintf(out, "\" mimeType=\"%s/mp4\" bandwidth=\"%d\"",
+ width ? "video" : "audio", bitrate);
+ if (width > 0 && height > 0)
+ fprintf(out, " width=\"%d\" height=\"%d\"", width, height);
+ if (sample_rate > 0)
+ fprintf(out, " audioSamplingRate=\"%d\"", sample_rate);
+ fprintf(out, ">\n");
+ if (channels > 0)
+ fprintf(out, "\t\t\t\t<AudioChannelConfiguration schemeIdUri=\"urn:mpeg:dash:23003:3:audio_channel_configuration:2011\" value=\"%d\" />\n", channels);
+ fprintf(out, "\t\t\t\t<BaseURL>%s</BaseURL>\n", first_track->name);
+ fprintf(out, "\t\t\t\t<SegmentBase indexRange=\"%"PRId64"-%"PRId64"\" />\n", first_track->sidx_start, first_track->sidx_start + first_track->sidx_length - 1);
+ fprintf(out, "\t\t\t</Representation>\n");
+ i = j;
+ }
+ fprintf(out, "\t\t</AdaptationSet>\n");
+ }
+ fprintf(out, "\t</Period>\n");
+ fprintf(out, "</MPD>\n");
+
+ fclose(out);
+err:
+ for (i = 0; i < 2; i++)
+ av_free(adaptation_sets_buf[i]);
+ return ret;
+}
+
+static void clean_tracks(struct Tracks *tracks)
+{
+ int i;
+ for (i = 0; i < tracks->nb_tracks; i++) {
+ av_freep(&tracks->tracks[i]);
+ }
+ av_freep(&tracks->tracks);
+ tracks->nb_tracks = 0;
+}
+
+int main(int argc, char **argv)
+{
+ const char *out = NULL;
+ struct Tracks tracks = { 0 };
+ int i;
+
+ av_register_all();
+
+ for (i = 1; i < argc; i++) {
+ if (!strcmp(argv[i], "-out")) {
+ out = argv[i + 1];
+ i++;
+ } else if (argv[i][0] == '-') {
+ return usage(argv[0], 1);
+ } else {
+ if (handle_file(&tracks, argv[i]))
+ return 1;
+ }
+ }
+ if (!tracks.nb_tracks || !out)
+ return usage(argv[0], 1);
+
+ output_mpd(&tracks, out);
+
+ clean_tracks(&tracks);
+
+ return 0;
+}
if test -f "$BUILD"/ffmpeg_options ; then
USER_OPTS=$(cat "$BUILD"/ffmpeg_options)
fi
-OPTIONS=" --prefix=/opt/ffmpeg --enable-avresample --disable-debug --enable-nonfree --enable-gpl --enable-version3 --enable-x11grab --enable-libpulse --enable-libopencore-amrnb --enable-libopencore-amrwb --disable-decoder=amrnb --disable-decoder=amrwb $USER_OPTS"
+OPTIONS=" --prefix=/opt/ffmpeg --enable-avresample --disable-debug --enable-nonfree --enable-gpl --enable-version3 --enable-libpulse --enable-libopencore-amrnb --enable-libopencore-amrwb --disable-decoder=amrnb --disable-decoder=amrwb $USER_OPTS"
# optional flags for encoding
-OPTIONS="$OPTIONS --enable-libx264 --enable-libx265 --enable-libfdk-aac --enable-libvorbis --enable-libmp3lame --enable-libopus --enable-libvpx --enable-libspeex --enable-libass --enable-avisynth --enable-libsoxr --enable-libxvid "
+OPTIONS="$OPTIONS --enable-libx264 --enable-libx265 --enable-libfdk-aac --enable-libvorbis --enable-libmp3lame --enable-libopus --enable-libvpx --enable-libspeex --enable-libass --enable-avisynth --enable-libsoxr --enable-libxvid --enable-libvo-aacenc "
echo Using ffmpeg options: $OPTIONS