From: Doug McMahon Date: Sat, 6 Dec 2014 13:32:16 +0000 (-0500) Subject: Imported Debian version 2.5.0~trusty1.1 X-Git-Tag: debian/2.5.0_trusty1.1^0 X-Git-Url: https://git.piment-noir.org/?a=commitdiff_plain;h=f6fa7814ccfe3e76514b36cf04f5cd3cb657c8cf;p=deb_ffmpeg.git Imported Debian version 2.5.0~trusty1.1 --- diff --git a/debian/changelog b/debian/changelog index b06e8e1..b0cadb8 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,8 +1,21 @@ -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 Fri, 07 Nov 2014 14:38:48 -0500 + -- Doug McMahon 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 Thu, 04 Dec 2014 08:49:38 -0500 + +ffmpeg (7:2.5.0~trusty) trusty; urgency=medium + + * New upstream release 2.5 + + -- Doug McMahon Thu, 04 Dec 2014 08:02:31 -0500 ffmpeg (7:2.4.2~trusty1.1) trusty; urgency=medium diff --git a/debian/control b/debian/control index bfadd66..04a9adc 100644 --- a/debian/control +++ b/debian/control @@ -22,6 +22,7 @@ Build-Depends: libtheora-dev, libva-dev [!hurd-any], libvdpau-dev, + libvo-aacenc-dev, libvorbis-dev, libvpx-dev (>= 0.9.6), libx11-dev, @@ -29,6 +30,8 @@ Build-Depends: libx265-dev, libxext-dev, libxfixes-dev, + libxcb-shm0-dev, + libxcb-xfixes0-dev, libxvidcore-dev, libxvmc-dev, texi2html, diff --git a/debian/ffmpeg.links b/debian/ffmpeg.links index ad206b1..fee1084 100644 --- a/debian/ffmpeg.links +++ b/debian/ffmpeg.links @@ -1,4 +1,5 @@ /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# diff --git a/ffmpeg/Changelog b/ffmpeg/Changelog index 1002a0f..0130ca8 100644 --- a/ffmpeg/Changelog +++ b/ffmpeg/Changelog @@ -1,78 +1,23 @@ Entries are sorted chronologically from oldest to youngest within each release, releases are sorted from youngest to oldest. -version : - -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: diff --git a/ffmpeg/LICENSE.md b/ffmpeg/LICENSE.md index e0a431b..cf9955f 100644 --- a/ffmpeg/LICENSE.md +++ b/ffmpeg/LICENSE.md @@ -64,6 +64,7 @@ There are a handful of files under other licensing terms, namely: 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 diff --git a/ffmpeg/MAINTAINERS b/ffmpeg/MAINTAINERS index 062ff39..15b976f 100644 --- a/ffmpeg/MAINTAINERS +++ b/ffmpeg/MAINTAINERS @@ -309,6 +309,7 @@ libavdevice 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) @@ -385,6 +386,7 @@ Muxers/Demuxers: 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 @@ -462,7 +464,7 @@ Muxers/Demuxers: 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 @@ -496,6 +498,7 @@ Protocols: libssh.c Lukasz Marek mms*.c Ronald S. Bultje udp.c Luca Abeni + icecast.c Marvin Scholz libswresample diff --git a/ffmpeg/Makefile b/ffmpeg/Makefile index 57f6a91..1e1dbb3 100644 --- a/ffmpeg/Makefile +++ b/ffmpeg/Makefile @@ -32,6 +32,7 @@ OBJS-ffmpeg += ffmpeg_opt.o ffmpeg_filter.o 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 diff --git a/ffmpeg/README.md b/ffmpeg/README.md index 182d726..04089e4 100644 --- a/ffmpeg/README.md +++ b/ffmpeg/README.md @@ -32,7 +32,7 @@ and in the [wiki](http://trac.ffmpeg.org). ### Examples -Conding examples are available in the **doc/example** directory. +Coding examples are available in the **doc/examples** directory. ## License diff --git a/ffmpeg/RELEASE b/ffmpeg/RELEASE index 35cee72..95e3ba8 100644 --- a/ffmpeg/RELEASE +++ b/ffmpeg/RELEASE @@ -1 +1 @@ -2.4.3 +2.5 diff --git a/ffmpeg/RELEASE_NOTES b/ffmpeg/RELEASE_NOTES index 9d0d7e4..a1ddd35 100644 --- a/ffmpeg/RELEASE_NOTES +++ b/ffmpeg/RELEASE_NOTES @@ -1,17 +1,11 @@ ┌────────────────────────────────────────┐ - │ 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). @@ -20,24 +14,21 @@ │ 🔨 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. @@ -45,39 +36,64 @@ │ ★ 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 diff --git a/ffmpeg/VERSION b/ffmpeg/VERSION index 35cee72..95e3ba8 100644 --- a/ffmpeg/VERSION +++ b/ffmpeg/VERSION @@ -1 +1 @@ -2.4.3 +2.5 diff --git a/ffmpeg/cmdutils.c b/ffmpeg/cmdutils.c index 1143ea1..b68dae9 100644 --- a/ffmpeg/cmdutils.c +++ b/ffmpeg/cmdutils.c @@ -444,7 +444,7 @@ int locate_option(int argc, char **argv, const OptionDef *options, (po->name && !strcmp(optname, po->name))) return i; - if (po->flags & HAS_ARG) + if (!po->name || po->flags & HAS_ARG) i++; } return 0; @@ -959,9 +959,10 @@ static int init_report(const char *env) 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, @@ -1543,7 +1544,8 @@ int show_protocols(void *optctx, const char *opt, const char *arg) 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; @@ -1556,7 +1558,6 @@ int show_filters(void *optctx, const char *opt, const char *arg) " 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++) { @@ -1581,6 +1582,8 @@ int show_filters(void *optctx, const char *opt, const char *arg) filter->process_command ? 'C' : '.', filter->name, descr, filter->description); } +#else + printf("No filters available: libavfilter disabled\n"); #endif return 0; } @@ -1861,17 +1864,19 @@ int cmdutils_read_file(const char *filename, char **bufptr, size_t *size) 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) { @@ -1883,9 +1888,9 @@ int cmdutils_read_file(const char *filename, char **bufptr, size_t *size) 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 { @@ -1992,7 +1997,7 @@ AVDictionary *filter_codec_opts(AVDictionary *opts, enum AVCodecID codec_id, 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) || @@ -2050,3 +2055,184 @@ void *grow_array(void *array, int elem_size, int *size, int new_size) } 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 diff --git a/ffmpeg/cmdutils.h b/ffmpeg/cmdutils.h index 76d11a5..f6ad44c 100644 --- a/ffmpeg/cmdutils.h +++ b/ffmpeg/cmdutils.h @@ -443,6 +443,20 @@ int show_formats(void *optctx, const char *opt, const char *arg); */ 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. diff --git a/ffmpeg/cmdutils_common_opts.h b/ffmpeg/cmdutils_common_opts.h index 49b5180..758dac1 100644 --- a/ffmpeg/cmdutils_common_opts.h +++ b/ffmpeg/cmdutils_common_opts.h @@ -27,3 +27,9 @@ { "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 diff --git a/ffmpeg/compat/w32pthreads.h b/ffmpeg/compat/w32pthreads.h index 2a7f323..87e816f 100644 --- a/ffmpeg/compat/w32pthreads.h +++ b/ffmpeg/compat/w32pthreads.h @@ -55,35 +55,17 @@ typedef struct pthread_t { * 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 @@ -136,6 +118,36 @@ static inline int pthread_mutex_unlock(pthread_mutex_t *m) 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 { @@ -147,6 +159,13 @@ 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; @@ -159,7 +178,7 @@ static av_unused int pthread_cond_init(pthread_cond_t *cond, const void *unused_ 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; @@ -174,7 +193,7 @@ static av_unused int pthread_cond_init(pthread_cond_t *cond, const void *unused_ 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; @@ -185,12 +204,12 @@ static av_unused void pthread_cond_destroy(pthread_cond_t *cond) 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) { @@ -221,7 +240,7 @@ static av_unused void pthread_cond_broadcast(pthread_cond_t *cond) 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); @@ -253,7 +272,7 @@ static av_unused int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mu 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); @@ -275,6 +294,7 @@ static av_unused void pthread_cond_signal(pthread_cond_t *cond) pthread_mutex_unlock(&win32_cond->mtx_broadcast); } +#endif static av_unused void w32thread_init(void) { diff --git a/ffmpeg/configure b/ffmpeg/configure index 618dfab..c046e34 100755 --- a/ffmpeg/configure +++ b/ffmpeg/configure @@ -251,17 +251,22 @@ External library support: --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] @@ -1198,13 +1203,17 @@ require_cpp(){ 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" @@ -1380,6 +1389,10 @@ EXTERNAL_LIBRARY_LIST=" libx264 libx265 libxavs + libxcb + libxcb_shm + libxcb_shape + libxcb_xfixes libxvid libzmq libzvbi @@ -1388,6 +1401,7 @@ EXTERNAL_LIBRARY_LIST=" opencl opengl openssl + sdl x11grab xlib zlib @@ -1594,6 +1608,7 @@ ARCH_FEATURES=" BUILTIN_LIST=" atomic_cas_ptr + atomic_compare_exchange machine_rw_barrier MemoryBarrier mm_empty @@ -1650,6 +1665,7 @@ HEADERS_LIST=" sys_un_h sys_videoio_h termios_h + udplite_h unistd_h windows_h winsock2_h @@ -1668,7 +1684,6 @@ MATH_FUNCS=" exp2 exp2f expf - fminf isinf isnan ldexpf @@ -1712,6 +1727,7 @@ SYSTEM_FUNCS=" gettimeofday glob glXGetProcAddress + gmtime_r inet_aton isatty jack_port_get_latency_range @@ -1720,6 +1736,7 @@ SYSTEM_FUNCS=" lzo1x_999_compress mach_absolute_time MapViewOfFile + MoveFileExA memalign mkstemp mmap @@ -1765,6 +1782,7 @@ TOOLCHAIN_FEATURES=" " TYPES_LIST=" + CONDITION_VARIABLE_Ptr socklen_t struct_addrinfo struct_group_source_req @@ -2018,7 +2036,7 @@ simd_align_16_if_any="altivec neon sse" 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" @@ -2057,6 +2075,7 @@ amrwb_decoder_select="lsp" 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" @@ -2386,6 +2405,7 @@ avi_muxer_select="riffenc" 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" @@ -2410,7 +2430,7 @@ matroska_muxer_select="riffenc" 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" @@ -2449,12 +2469,14 @@ xwma_demuxer_select="riffdec" # 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" @@ -2489,6 +2511,7 @@ vfwcap_indev_extralibs="-lavicap32" 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" @@ -2528,11 +2551,11 @@ tcp_protocol_select="network" 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" @@ -2551,19 +2574,16 @@ drawtext_filter_deps="libfreetype" 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" @@ -3036,8 +3056,9 @@ case "$toolchain" in 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" @@ -3049,9 +3070,13 @@ set_default arch cc cxx doxygen pkg_config ranlib strip sysinclude \ 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 && \ @@ -3428,55 +3453,56 @@ probe_cc(){ # 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) @@ -3934,6 +3960,9 @@ case "$arch" in ;; 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 @@ -4033,6 +4062,7 @@ case $target_os in 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" @@ -4065,6 +4095,7 @@ case $target_os in # 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" @@ -4230,6 +4261,15 @@ probe_libc(){ eval ${pfx}libc_type=solaris add_${pfx}cppflags -D__EXTENSIONS__ -D_XOPEN_SOURCE=600 fi + check_${pfx}cc < +void *v = localtime_r; +EOF +test "$?" != 0 && check_${pfx}cc -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600 < +void *v = localtime_r; +EOF + } probe_libc @@ -4374,7 +4414,7 @@ EOF 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 @@ -4500,7 +4540,7 @@ elif enabled parisc; then 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 @@ -4616,6 +4656,10 @@ elif check_func dlopen -ldl; then 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 @@ -4657,6 +4701,7 @@ if ! disabled network; then 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" @@ -4667,13 +4712,14 @@ check_func ${malloc_prefix}memalign && enable memalign 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 @@ -4681,7 +4727,7 @@ check_func mkstemp 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 @@ -4700,10 +4746,12 @@ check_func_headers windows.h GetProcessAffinityMask 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 @@ -4717,6 +4765,7 @@ check_header io.h 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 @@ -4782,7 +4831,6 @@ disabled crystalhd || check_lib libcrystalhd/libcrystalhd_if.h DtsCrystalHDVersi 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} @@ -4825,7 +4873,8 @@ enabled libnut && require libnut libnut.h nut_demuxer_init -lnut 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 @@ -4834,9 +4883,8 @@ enabled libquvi && require_pkg_config libquvi quvi/quvi.h quvi_init 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 @@ -4861,10 +4909,10 @@ enabled libvpx && { 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 && @@ -4910,21 +4958,26 @@ if enabled libdc1394; then 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 @@ -4943,6 +4996,7 @@ check_header linux/videodev2.h 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 @@ -4988,10 +5042,37 @@ fi 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" @@ -5302,7 +5383,6 @@ done 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" @@ -5712,7 +5792,7 @@ Cflags: -I\${includedir} 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" diff --git a/ffmpeg/doc/APIchanges b/ffmpeg/doc/APIchanges index 8a28029..abb83b8 100644 --- a/ffmpeg/doc/APIchanges +++ b/ffmpeg/doc/APIchanges @@ -15,6 +15,58 @@ libavutil: 2014-08-09 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< --------- @@ -214,10 +266,10 @@ API changes, most recent first: 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 @@ -862,6 +914,9 @@ lavd 54.4.100 / 54.0.0, lavfi 3.5.0 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. diff --git a/ffmpeg/doc/Doxyfile b/ffmpeg/doc/Doxyfile index e158951..a5b9640 100644 --- a/ffmpeg/doc/Doxyfile +++ b/ffmpeg/doc/Doxyfile @@ -31,7 +31,7 @@ PROJECT_NAME = FFmpeg # 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 diff --git a/ffmpeg/doc/bitstream_filters.texi b/ffmpeg/doc/bitstream_filters.texi index 58ebddd..6431ce8 100644 --- a/ffmpeg/doc/bitstream_filters.texi +++ b/ffmpeg/doc/bitstream_filters.texi @@ -13,7 +13,16 @@ bitstream filter using the option @code{--disable-bsf=BSF}. 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 @@ -135,9 +144,16 @@ ffmpeg -i frame_%d.jpg -c:v copy rotated.avi 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 diff --git a/ffmpeg/doc/codecs.texi b/ffmpeg/doc/codecs.texi index 5a1abb8..f1f5c00 100644 --- a/ffmpeg/doc/codecs.texi +++ b/ffmpeg/doc/codecs.texi @@ -71,7 +71,9 @@ Force low delay. @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 @@ -1114,6 +1116,19 @@ Interlaced video, bottom coded first, top displayed first 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 diff --git a/ffmpeg/doc/decoders.texi b/ffmpeg/doc/decoders.texi index 6910dc1..01fca9f 100644 --- a/ffmpeg/doc/decoders.texi +++ b/ffmpeg/doc/decoders.texi @@ -190,6 +190,15 @@ The format for this option is a string containing 16 24-bits hexadecimal 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 diff --git a/ffmpeg/doc/demuxers.texi b/ffmpeg/doc/demuxers.texi index e582322..11dfe1b 100644 --- a/ffmpeg/doc/demuxers.texi +++ b/ffmpeg/doc/demuxers.texi @@ -29,6 +29,26 @@ the caller can decide which variant streams to actually receive. The total bitrate of the variant that the stream belongs to is available in a metadata key named "variant_bitrate". +@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. diff --git a/ffmpeg/doc/encoders.texi b/ffmpeg/doc/encoders.texi index 44b49ce..c0e9890 100644 --- a/ffmpeg/doc/encoders.texi +++ b/ffmpeg/doc/encoders.texi @@ -1745,6 +1745,10 @@ Enable calculation and printing SSIM stats after the encoding. 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". @@ -1882,6 +1886,34 @@ no-fast-pskip=1:subq=6:8x8dct=0:trellis=0 OUTPUT 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. diff --git a/ffmpeg/doc/examples/decoding_encoding.c b/ffmpeg/doc/examples/decoding_encoding.c index 556fe98..80da664 100644 --- a/ffmpeg/doc/examples/decoding_encoding.c +++ b/ffmpeg/doc/examples/decoding_encoding.c @@ -288,6 +288,7 @@ static void audio_decode_example(const char *outfilename, const char *filename) avpkt.size = fread(inbuf, 1, AUDIO_INBUF_SIZE, f); while (avpkt.size > 0) { + int i, ch; int got_frame = 0; if (!decoded_frame) { @@ -304,15 +305,15 @@ static void audio_decode_example(const char *outfilename, const char *filename) } 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; inb_samples; i++) + for (ch=0; chchannels; ch++) + fwrite(decoded_frame->data[ch] + data_size*i, 1, data_size, outfile); } avpkt.size -= len; avpkt.data += len; @@ -650,7 +651,7 @@ int main(int argc, char **argv) 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"); diff --git a/ffmpeg/doc/examples/transcode_aac.c b/ffmpeg/doc/examples/transcode_aac.c index cee447f..e98c217 100644 --- a/ffmpeg/doc/examples/transcode_aac.c +++ b/ffmpeg/doc/examples/transcode_aac.c @@ -306,7 +306,7 @@ static int decode_audio_frame(AVFrame *frame, /** 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 { diff --git a/ffmpeg/doc/examples/transcoding.c b/ffmpeg/doc/examples/transcoding.c index a8f4210..759c628 100644 --- a/ffmpeg/doc/examples/transcoding.c +++ b/ffmpeg/doc/examples/transcoding.c @@ -385,17 +385,9 @@ static int encode_write_frame(AVFrame *filt_frame, unsigned int stream_index, in /* 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 */ @@ -509,14 +501,9 @@ int main(int argc, char **argv) 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, @@ -538,14 +525,9 @@ int main(int argc, char **argv) } } 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) diff --git a/ffmpeg/doc/ffmpeg.texi b/ffmpeg/doc/ffmpeg.texi index 4fc7682..d774aba 100644 --- a/ffmpeg/doc/ffmpeg.texi +++ b/ffmpeg/doc/ffmpeg.texi @@ -360,7 +360,7 @@ ffmpeg -i myfile.avi -target vcd -bf 2 /tmp/vcd.mpg @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. @@ -467,7 +467,7 @@ attachments. @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). @@ -692,7 +692,7 @@ If this option is not specified, the default adapter is used. @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 @@ -1016,6 +1016,12 @@ processing (e.g. in case the format option @option{avoid_negative_ts} 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: diff --git a/ffmpeg/doc/ffplay.texi b/ffmpeg/doc/ffplay.texi index 203085c..3c85417 100644 --- a/ffmpeg/doc/ffplay.texi +++ b/ffmpeg/doc/ffplay.texi @@ -37,10 +37,14 @@ Force displayed height. 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} @@ -109,15 +113,10 @@ duration, the codec parameters, the current position in the stream and 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 @@ -126,7 +125,8 @@ players use audio as master clock, but in some cases (streaming or high quality broadcast) it is necessary to change that. This option is mainly used for debugging purposes. @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 @@ -164,8 +164,20 @@ Force a specific video decoder. 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 diff --git a/ffmpeg/doc/ffprobe.texi b/ffmpeg/doc/ffprobe.texi index 0a39ed4..5c90470 100644 --- a/ffmpeg/doc/ffprobe.texi +++ b/ffmpeg/doc/ffprobe.texi @@ -321,6 +321,12 @@ Show information related to program and library versions. This is the 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. diff --git a/ffmpeg/doc/ffprobe.xsd b/ffmpeg/doc/ffprobe.xsd index 5dfbb47..c2cab37 100644 --- a/ffmpeg/doc/ffprobe.xsd +++ b/ffmpeg/doc/ffprobe.xsd @@ -10,8 +10,10 @@ + + @@ -35,6 +37,16 @@ + + + + + + + + + + @@ -166,6 +178,9 @@ + + + @@ -277,4 +292,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ffmpeg/doc/ffserver.texi b/ffmpeg/doc/ffserver.texi index 77273d2..83b6520 100644 --- a/ffmpeg/doc/ffserver.texi +++ b/ffmpeg/doc/ffserver.texi @@ -408,6 +408,12 @@ ignored, and the log is written to standard output. 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 @@ -571,6 +577,11 @@ deprecated in favor of @option{Metadata}. @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. @@ -589,8 +600,9 @@ Set sampling frequency for audio. When using low bitrates, you should lower this frequency to 22050 or 11025. The supported frequencies depend on the selected audio codec. -@item AVOptionAudio @var{option} @var{value} (@emph{encoding,audio}) -Set generic option for audio stream. +@item 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. @@ -667,8 +679,9 @@ Set video @option{qdiff} encoding option. @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. diff --git a/ffmpeg/doc/fftools-common-opts.texi b/ffmpeg/doc/fftools-common-opts.texi index 7b6afba..0e8f849 100644 --- a/ffmpeg/doc/fftools-common-opts.texi +++ b/ffmpeg/doc/fftools-common-opts.texi @@ -103,7 +103,10 @@ Print detailed information about the filter name @var{filter_name}. Use the 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. @@ -138,6 +141,22 @@ Show channel names and standard channel layouts. @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 diff --git a/ffmpeg/doc/filters.texi b/ffmpeg/doc/filters.texi index bb486ea..8c16c7a 100644 --- a/ffmpeg/doc/filters.texi +++ b/ffmpeg/doc/filters.texi @@ -282,6 +282,10 @@ sequential number of the input frame, starting from 0 @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 @@ -309,41 +313,6 @@ build. 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. @@ -1741,11 +1710,11 @@ The default is 0.707q and gives a Butterworth response. 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 @@ -1776,13 +1745,13 @@ avoiding clipping noise. 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 @@ -1805,25 +1774,25 @@ remapping. 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 @@ -2552,6 +2521,26 @@ Same as the @ref{subtitles} filter, except that it doesn't require libavcodec 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 @@ -4185,7 +4174,7 @@ drawtext='fontfile=Linux Libertine O-40\:style=Semibold:text=FFmpeg' @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 @@ -4458,6 +4447,10 @@ and VIVTC/VFM (VapourSynth project). The later is a light clone of TFM from 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 @@ -5124,6 +5117,22 @@ Modify RGB components depending on pixel position: @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 @@ -5565,8 +5574,62 @@ value. 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: @@ -5575,6 +5638,13 @@ 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 @@ -6221,7 +6291,7 @@ values are assumed. 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. @@ -6713,6 +6783,9 @@ A description of the accepted parameters follows. @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: @@ -6732,6 +6805,24 @@ It accepts the following values: @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 @@ -8646,6 +8737,7 @@ ffmpeg -i INPUT -vf trim=duration=1 @end itemize +@anchor{unsharp} @section unsharp Sharpen or blur the input video. @@ -8807,7 +8899,7 @@ Read a file with transform information for each frame and 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}. @@ -8817,7 +8909,7 @@ To enable compilation of this filter you need to configure FFmpeg with @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 @@ -8825,9 +8917,9 @@ camera movements. Default value is 10. 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. @@ -8864,7 +8956,7 @@ fill the border black 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 @@ -8930,7 +9022,7 @@ Use @command{ffmpeg} for a typical stabilization with default values: 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: @@ -9104,6 +9196,20 @@ Only deinterlace frames marked as interlaced. 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 diff --git a/ffmpeg/doc/formats.texi b/ffmpeg/doc/formats.texi index 027510e..4138709 100644 --- a/ffmpeg/doc/formats.texi +++ b/ffmpeg/doc/formats.texi @@ -55,6 +55,10 @@ Do not merge side data. 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}) @@ -168,6 +172,18 @@ The offset is added by the muxer to the output timestamps. 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 diff --git a/ffmpeg/doc/general.texi b/ffmpeg/doc/general.texi index 8d7555d..dd19fcc 100644 --- a/ffmpeg/doc/general.texi +++ b/ffmpeg/doc/general.texi @@ -454,6 +454,7 @@ library: @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. @@ -1030,6 +1031,7 @@ performance on systems without hardware floating point support). @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 diff --git a/ffmpeg/doc/indevs.texi b/ffmpeg/doc/indevs.texi index ce409b9..ad823ab 100644 --- a/ffmpeg/doc/indevs.texi +++ b/ffmpeg/doc/indevs.texi @@ -58,34 +58,94 @@ AVFoundation input device. 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 +} +and/or +@option{ + -audio_device_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 +If set to true, a list of all available input devices is given showing all +device names and indices. + +@item -video_device_index +Specify the video device by its index. Overrides anything given in the input filename. + +@item -audio_device_index +Specify the audio device by its index. Overrides anything given in the input filename. + +@item -pixel_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. @@ -922,4 +982,58 @@ Use the MIT-SHM extension for shared memory. Default value is @code{1}. 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 diff --git a/ffmpeg/doc/muxers.texi b/ffmpeg/doc/muxers.texi index 57e81f4..c6ba604 100644 --- a/ffmpeg/doc/muxers.texi +++ b/ffmpeg/doc/muxers.texi @@ -194,15 +194,19 @@ can not be smaller than one centi second. 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 @@ -220,6 +224,11 @@ Set the segment length in seconds. Default value is 2. 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 @@ -233,6 +242,9 @@ to @var{wrap}. 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. @@ -241,6 +253,17 @@ Note that the playlist sequence number must be unique for each segment 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} @@ -536,7 +559,6 @@ a short portion of the file. With this option set, there is no initial 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, @@ -557,6 +579,16 @@ and a QuickTime chapter track are written to the file. With this option 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 @@ -569,29 +601,38 @@ ffmpeg -re @var{} -movflags isml+frag_keyframe @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: diff --git a/ffmpeg/doc/print_options.c b/ffmpeg/doc/print_options.c index ec8d839..9fd66ca 100644 --- a/ffmpeg/doc/print_options.c +++ b/ffmpeg/doc/print_options.c @@ -26,6 +26,10 @@ #include #include +// 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" diff --git a/ffmpeg/doc/protocols.texi b/ffmpeg/doc/protocols.texi index dc2fdb1..d165bda 100644 --- a/ffmpeg/doc/protocols.texi +++ b/ffmpeg/doc/protocols.texi @@ -750,7 +750,7 @@ port will be used for the local RTP and RTCP ports. @item If @option{localrtcpport} (the local RTCP port) is not set it will be -set to the the local RTP port value plus 1. +set to the local RTP port value plus 1. @end enumerate @section rtsp diff --git a/ffmpeg/doc/t2h.pm b/ffmpeg/doc/t2h.pm index 75dc0d3..a927071 100644 --- a/ffmpeg/doc/t2h.pm +++ b/ffmpeg/doc/t2h.pm @@ -14,9 +14,9 @@ # 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 diff --git a/ffmpeg/doc/writing_filters.txt b/ffmpeg/doc/writing_filters.txt index c7923e8..eb16d42 100644 --- a/ffmpeg/doc/writing_filters.txt +++ b/ffmpeg/doc/writing_filters.txt @@ -16,16 +16,15 @@ outputs the modified frame. The most simple way of doing this is to take a 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 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. diff --git a/ffmpeg/ffmpeg.c b/ffmpeg/ffmpeg.c index ee8039c..eef774b 100644 --- a/ffmpeg/ffmpeg.c +++ b/ffmpeg/ffmpeg.c @@ -475,6 +475,7 @@ static void ffmpeg_cleanup(int ret) } ost->bitstream_filters = NULL; av_frame_free(&ost->filtered_frame); + av_frame_free(&ost->last_frame); av_parser_close(ost->parser); @@ -622,7 +623,11 @@ static void write_frame(AVFormatContext *s, AVPacket *pkt, OutputStream *ost) 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); @@ -659,6 +664,17 @@ static void write_frame(AVFormatContext *s, AVPacket *pkt, OutputStream *ost) } 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 && @@ -681,15 +697,6 @@ static void write_frame(AVFormatContext *s, AVPacket *pkt, OutputStream *ost) 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; @@ -872,14 +879,14 @@ static void do_subtitle_out(AVFormatContext *s, 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; @@ -890,10 +897,20 @@ static void do_video_out(AVFormatContext *s, 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; @@ -913,19 +930,34 @@ static void do_video_out(AVFormatContext *s, } } + 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) @@ -942,28 +974,36 @@ static void do_video_out(AVFormatContext *s, } 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 @@ -978,10 +1018,8 @@ static void do_video_out(AVFormatContext *s, /* 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; @@ -1007,8 +1045,7 @@ static void do_video_out(AVFormatContext *s, 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; @@ -1102,6 +1139,11 @@ static void do_video_out(AVFormatContext *s, 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) @@ -1270,7 +1312,6 @@ static void print_final_stats(int64_t total_size) 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, @@ -1461,6 +1502,8 @@ static void print_report(int is_last_report, int64_t timer_start, int64_t cur_ti 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; @@ -1496,10 +1539,11 @@ static void print_report(int is_last_report, int64_t timer_start, int64_t cur_ti 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); } @@ -1906,6 +1950,20 @@ static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output) 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++) @@ -2122,11 +2180,11 @@ static int process_input_packet(InputStream *ist, const AVPacket *pkt) 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; @@ -2181,11 +2239,11 @@ static int process_input_packet(InputStream *ist, const AVPacket *pkt) 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; } @@ -2621,6 +2679,26 @@ static int transcode_init(void) 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) { @@ -2635,7 +2713,10 @@ static int transcode_init(void) 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) @@ -2882,10 +2963,11 @@ static int transcode_init(void) 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; } } @@ -3085,9 +3167,9 @@ static OutputStream *choose_output(void) 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; @@ -3465,13 +3547,14 @@ static int process_input(int file_index) 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", @@ -3482,14 +3565,15 @@ static int process_input(int file_index) } } - 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, @@ -3501,7 +3585,7 @@ static int process_input(int file_index) } } 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; } @@ -3509,7 +3593,7 @@ static int process_input(int file_index) 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; } @@ -3752,6 +3836,7 @@ static int transcode(void) av_dict_free(&ost->encoder_opts); av_dict_free(&ost->swr_opts); av_dict_free(&ost->resample_opts); + av_dict_free(&ost->bsf_args); } } } @@ -3773,7 +3858,7 @@ static int64_t getutime(void) GetProcessTimes(proc, &c, &e, &k, &u); return ((int64_t) u.dwHighDateTime << 32 | u.dwLowDateTime) / 10; #else - return av_gettime(); + return av_gettime_relative(); #endif } diff --git a/ffmpeg/ffmpeg.h b/ffmpeg/ffmpeg.h index 56eb66a..117a35c 100644 --- a/ffmpeg/ffmpeg.h +++ b/ffmpeg/ffmpeg.h @@ -388,6 +388,8 @@ typedef struct OutputStream { AVCodec *enc; int64_t max_frames; AVFrame *filtered_frame; + AVFrame *last_frame; + int last_droped; /* video only */ AVRational frame_rate; @@ -420,6 +422,7 @@ typedef struct OutputStream { 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) */ @@ -481,6 +484,7 @@ extern int do_deinterlace; 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; @@ -490,6 +494,7 @@ extern int stdin_interaction; 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; diff --git a/ffmpeg/ffmpeg_filter.c b/ffmpeg/ffmpeg_filter.c index d52b1f7..264840b 100644 --- a/ffmpeg/ffmpeg_filter.c +++ b/ffmpeg/ffmpeg_filter.c @@ -383,9 +383,8 @@ static int configure_output_video_filter(FilterGraph *fg, OutputFilter *ofilter, 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; @@ -620,6 +619,7 @@ static int sub2video_prepare(InputStream *ist) ist->sub2video.frame = av_frame_alloc(); if (!ist->sub2video.frame) return AVERROR(ENOMEM); + ist->sub2video.last_pts = INT64_MIN; return 0; } @@ -637,6 +637,7 @@ static int configure_input_video_filter(FilterGraph *fg, InputFilter *ifilter, 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"); @@ -711,8 +712,14 @@ static int configure_input_video_filter(FilterGraph *fg, InputFilter *ifilter, 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; @@ -731,6 +738,7 @@ static int configure_input_audio_filter(FilterGraph *fg, InputFilter *ifilter, 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"); @@ -813,8 +821,14 @@ static int configure_input_audio_filter(FilterGraph *fg, InputFilter *ifilter, 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; diff --git a/ffmpeg/ffmpeg_opt.c b/ffmpeg/ffmpeg_opt.c index 05ab652..1f281f6 100644 --- a/ffmpeg/ffmpeg_opt.c +++ b/ffmpeg/ffmpeg_opt.c @@ -91,6 +91,7 @@ int do_benchmark_all = 0; 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; @@ -508,7 +509,8 @@ static int opt_recording_timestamp(void *optctx, const char *opt, const char *ar 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 " @@ -702,7 +704,7 @@ static void add_input_streams(OptionsContext *o, AVFormatContext *ic) 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); } @@ -792,6 +794,7 @@ static int open_input_file(OptionsContext *o, const char *filename) 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))) { @@ -862,12 +865,18 @@ static int open_input_file(OptionsContext *o, const char *filename) 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); @@ -921,7 +930,7 @@ static int open_input_file(OptionsContext *o, const char *filename) 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; @@ -1129,8 +1138,11 @@ static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, e 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); @@ -1139,6 +1151,7 @@ static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, e 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; @@ -1276,6 +1289,8 @@ static OutputStream *new_video_stream(OptionsContext *o, AVFormatContext *oc, in 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) { @@ -1620,27 +1635,36 @@ static int read_ffserver_streams(OptionsContext *o, AVFormatContext *s, const ch 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); @@ -1728,8 +1752,8 @@ static int open_output_file(OptionsContext *o, const char *filename) 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; } @@ -2807,7 +2831,7 @@ const OptionDef options[] = { "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 }, @@ -2836,6 +2860,8 @@ const OptionDef options[] = { "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 | @@ -2856,7 +2882,7 @@ const OptionDef options[] = { { "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" }, @@ -2898,7 +2924,7 @@ const OptionDef options[] = { /* 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" }, @@ -2980,10 +3006,13 @@ const OptionDef options[] = { { "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 | diff --git a/ffmpeg/ffmpeg_vdpau.c b/ffmpeg/ffmpeg_vdpau.c index fe09306..14a3773 100644 --- a/ffmpeg/ffmpeg_vdpau.c +++ b/ffmpeg/ffmpeg_vdpau.c @@ -42,9 +42,11 @@ typedef struct VDPAUContext { 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; @@ -57,6 +59,8 @@ typedef struct VDPAUContext { VdpYCbCrFormat vdpau_format; } VDPAUContext; +int vdpau_api_ver = 2; + static void vdpau_uninit(AVCodecContext *s) { InputStream *ist = s->opaque; @@ -239,9 +243,11 @@ do { 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); @@ -270,12 +276,16 @@ do { 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, " @@ -291,7 +301,7 @@ fail: 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; @@ -333,3 +343,22 @@ int vdpau_init(AVCodecContext *s) 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; +} diff --git a/ffmpeg/ffplay.c b/ffmpeg/ffplay.c index 833b5b1..1914a66 100644 --- a/ffmpeg/ffplay.c +++ b/ffmpeg/ffplay.c @@ -121,25 +121,8 @@ typedef struct PacketQueue { #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; @@ -160,15 +143,61 @@ typedef struct Clock { 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; @@ -183,13 +212,19 @@ typedef struct VideoState { 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; @@ -210,11 +245,6 @@ typedef struct VideoState { 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; @@ -223,8 +253,6 @@ typedef struct VideoState { 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 @@ -242,10 +270,6 @@ typedef struct VideoState { 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; @@ -253,12 +277,7 @@ typedef struct VideoState { 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 @@ -306,7 +325,6 @@ static int show_status = 1; static int av_sync_type = AV_SYNC_AUDIO_MASTER; static int64_t start_time = AV_NOPTS_VALUE; static int64_t duration = AV_NOPTS_VALUE; -static int workaround_bugs = 1; static int fast = 0; static int genpts = 0; static int lowres = 0; @@ -371,6 +389,8 @@ int64_t get_valid_channel_layout(int64_t channel_layout, int channels) return 0; } +static void free_picture(Frame *vp); + static int packet_queue_put_private(PacketQueue *q, AVPacket *pkt) { MyAVPacketList *pkt1; @@ -517,6 +537,246 @@ static int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block, int *seria 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) { @@ -795,7 +1055,7 @@ static void blend_subrect(AVPicture *dst, const AVSubtitleRect *rect, int imgw, } } -static void free_picture(VideoPicture *vp) +static void free_picture(Frame *vp) { if (vp->bmp) { SDL_FreeYUVOverlay(vp->bmp); @@ -803,11 +1063,6 @@ static void free_picture(VideoPicture *vp) } } -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) @@ -841,17 +1096,17 @@ static void calculate_display_rect(SDL_Rect *rect, 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); @@ -1033,7 +1288,6 @@ static void video_audio_display(VideoState *s) 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); @@ -1042,14 +1296,9 @@ static void stream_close(VideoState *is) 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); @@ -1088,7 +1337,7 @@ static void set_default_window_size(int width, int height, AVRational sar) 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; @@ -1308,7 +1557,7 @@ static double compute_target_delay(double delay, VideoState *is) 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) @@ -1320,38 +1569,10 @@ static double vp_duration(VideoState *is, VideoPicture *vp, VideoPicture *nextvp } } -/* 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 */ @@ -1360,7 +1581,7 @@ static void video_refresh(void *opaque, double *remaining_time) 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); @@ -1377,21 +1598,20 @@ static void video_refresh(void *opaque, double *remaining_time) 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; } @@ -1419,29 +1639,29 @@ 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; @@ -1449,16 +1669,7 @@ retry: || (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; } @@ -1470,7 +1681,7 @@ display: 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); @@ -1522,10 +1733,10 @@ display: 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); @@ -1545,10 +1756,10 @@ static void alloc_picture(VideoState *is) 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) { @@ -1571,27 +1782,16 @@ 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 */ @@ -1612,17 +1812,17 @@ static int queue_picture(VideoState *is, AVFrame *src_frame, double pts, double 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; @@ -1670,45 +1870,21 @@ static int queue_picture(VideoState *is, AVFrame *src_frame, double pts, double 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; @@ -1719,18 +1895,17 @@ static int get_video_frame(VideoState *is, AVFrame *frame, AVPacket *pkt, int *s 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 @@ -1943,15 +2118,100 @@ end: } #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); @@ -1966,12 +2226,7 @@ static int video_thread(void *arg) #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) @@ -1981,14 +2236,14 @@ static int video_thread(void *arg) 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) { @@ -2003,7 +2258,7 @@ static int video_thread(void *arg) 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; } @@ -2018,7 +2273,7 @@ static int video_thread(void *arg) 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; } @@ -2030,7 +2285,7 @@ static int video_thread(void *arg) #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 } @@ -2043,7 +2298,6 @@ static int video_thread(void *arg) #if CONFIG_AVFILTER avfilter_graph_free(&graph); #endif - av_free_packet(&pkt); av_frame_free(&frame); return 0; } @@ -2051,50 +2305,26 @@ static int video_thread(void *arg) 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++) { @@ -2109,15 +2339,10 @@ static int subtitle_thread(void *arg) } /* 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; } @@ -2193,229 +2418,107 @@ static int synchronize_audio(VideoState *is, int nb_samples) */ 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 */ @@ -2540,7 +2643,7 @@ static int stream_component_open(VideoState *is, int stream_index) 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) @@ -2565,7 +2668,6 @@ static int stream_component_open(VideoState *is, int stream_index) } 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)); @@ -2585,11 +2687,13 @@ static int stream_component_open(VideoState *is, int stream_index) 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; @@ -2604,7 +2708,7 @@ static int stream_component_open(VideoState *is, int stream_index) 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; @@ -2618,7 +2722,7 @@ static int stream_component_open(VideoState *is, int stream_index) /* 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; @@ -2631,14 +2735,16 @@ static int stream_component_open(VideoState *is, int stream_index) 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: @@ -2646,20 +2752,26 @@ static int stream_component_open(VideoState *is, int stream_index) 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) @@ -2674,16 +2786,16 @@ 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); @@ -2691,21 +2803,17 @@ static void stream_component_close(VideoState *is, int stream_index) 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: @@ -2713,12 +2821,11 @@ static void stream_component_close(VideoState *is, int stream_index) /* 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: @@ -2782,6 +2889,7 @@ static int read_thread(void *arg) 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; @@ -2791,12 +2899,19 @@ static int read_thread(void *arg) 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; @@ -2813,15 +2928,17 @@ static int read_thread(void *arg) 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 @@ -2991,8 +3108,8 @@ static int read_thread(void *arg) 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) { @@ -3000,27 +3117,25 @@ static int read_thread(void *arg) 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; @@ -3054,8 +3169,9 @@ static int read_thread(void *arg) 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) { @@ -3082,11 +3198,12 @@ static VideoState *stream_open(const char *filename, AVInputFormat *iformat) 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); @@ -3098,11 +3215,11 @@ static VideoState *stream_open(const char *filename, AVInputFormat *iformat) 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; @@ -3193,7 +3310,7 @@ static void toggle_full_screen(VideoState *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); @@ -3344,11 +3461,12 @@ static void event_loop(VideoState *cur_stream) 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; @@ -3418,7 +3536,7 @@ static void event_loop(VideoState *cur_stream) 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); @@ -3566,7 +3684,6 @@ static const OptionDef options[] = { { "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", ""}, diff --git a/ffmpeg/ffprobe.c b/ffmpeg/ffprobe.c index 9bb0f0f..24ecafd 100644 --- a/ffmpeg/ffprobe.c +++ b/ffmpeg/ffprobe.c @@ -66,6 +66,9 @@ static int do_show_stream_disposition = 0; 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; @@ -132,6 +135,11 @@ typedef enum { 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, @@ -165,6 +173,11 @@ static struct section sections[] = { [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 } }, @@ -175,7 +188,8 @@ static struct section sections[] = { [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" }, @@ -2098,12 +2112,28 @@ static int show_stream(WriterContext *w, AVFormatContext *fmt_ctx, int stream_id 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); @@ -2356,12 +2386,19 @@ static int open_input_file(AVFormatContext **fmt_ctx_ptr, const char *filename) 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; @@ -2557,6 +2594,58 @@ static void ffprobe_show_library_versions(WriterContext *w) 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); @@ -2890,6 +2979,7 @@ DEFINE_OPT_SHOW_SECTION(format, FORMAT); 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); @@ -2928,6 +3018,7 @@ static const OptionDef real_options[] = { { "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" }, @@ -2984,6 +3075,9 @@ int main(int argc, char **argv) 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); @@ -3048,10 +3142,12 @@ int main(int argc, char **argv) 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); diff --git a/ffmpeg/ffserver.c b/ffmpeg/ffserver.c index 24e4005..ab3e6e9 100644 --- a/ffmpeg/ffserver.c +++ b/ffmpeg/ffserver.c @@ -49,7 +49,6 @@ #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" @@ -70,6 +69,7 @@ #include #include "cmdutils.h" +#include "ffserver_config.h" const char program_name[] = "ffserver"; const int program_birth_year = 2000; @@ -107,8 +107,6 @@ static const char * const http_state[] = { "RTSP_SEND_PACKET", }; -#define MAX_STREAMS 20 - #define IOBUFFER_INIT_SIZE 8192 /* timeouts are in ms */ @@ -156,12 +154,12 @@ typedef struct HTTPContext { 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; @@ -182,95 +180,29 @@ typedef struct HTTPContext { /* 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); @@ -293,12 +225,12 @@ static void rtsp_cmd_play(HTTPContext *c, const char *url, RTSPMessageHeader *h) 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, @@ -306,18 +238,12 @@ static int rtp_new_av_stream(HTTPContext *c, 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 @@ -367,41 +293,6 @@ static void ffm_set_write_index(AVFormatContext *s, int64_t pos, 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; @@ -487,7 +378,7 @@ static int compute_datarate(DataRateData *drd, int64_t count) } -static void start_children(FFStream *feed) +static void start_children(FFServerStream *feed) { if (no_launch) return; @@ -527,7 +418,7 @@ static void start_children(FFStream *feed) 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)) @@ -585,14 +476,14 @@ static int socket_open_listen(struct sockaddr_in *my_addr) /* 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); @@ -646,21 +537,21 @@ static int http_server(void) 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); @@ -676,7 +567,7 @@ static int http_server(void) http_log("FFserver started.\n"); - start_children(first_feed); + start_children(config.first_feed); start_multicast(); @@ -759,7 +650,7 @@ static int http_server(void) if (need_to_start_children) { need_to_start_children = 0; - start_children(first_feed); + start_children(config.first_feed); } /* now handle the events */ @@ -813,7 +704,7 @@ static void http_send_too_busy_reply(int fd) "

The server is too busy to serve your request at this time.

\r\n" "

The number of current connections is %u, and this exceeds the limit of %u.

\r\n" "\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"); @@ -837,7 +728,7 @@ static void new_connection(int server_fd, int is_rtsp) 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; } @@ -865,7 +756,7 @@ static void new_connection(int server_fd, int is_rtsp) fail: if (c) { - av_free(c->buffer); + av_freep(&c->buffer); av_free(c); } closesocket(fd); @@ -918,8 +809,8 @@ static void close_connection(HTTPContext *c) 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) @@ -940,7 +831,7 @@ static void close_connection(HTTPContext *c) } for(i=0; inb_streams; i++) - av_free(ctx->streams[i]); + av_freep(&ctx->streams[i]); av_freep(&ctx->streams); av_freep(&ctx->priv_data); @@ -955,7 +846,7 @@ static void close_connection(HTTPContext *c) av_freep(&c->pb_buffer); av_freep(&c->packet_buffer); - av_free(c->buffer); + av_freep(&c->buffer); av_free(c); nb_connections--; } @@ -1183,7 +1074,7 @@ static int extract_rates(char *rates, int ratelen, const char *request) 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; @@ -1223,7 +1114,7 @@ static int find_stream_in_feed(FFStream *feed, AVCodecContext *codec, int bit_ra 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 */ @@ -1276,111 +1167,12 @@ static void get_word(char *buf, int buf_size, const char **pp) *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 or \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; @@ -1390,7 +1182,7 @@ static IPAddressACL* parse_dynamic_acl(FFStream *stream, HTTPContext *c) return NULL; } - acl = av_mallocz(sizeof(IPAddressACL)); + acl = av_mallocz(sizeof(FFServerIPAddressACL)); /* Build ACL */ for(;;) { @@ -1402,19 +1194,19 @@ static IPAddressACL* parse_dynamic_acl(FFStream *stream, HTTPContext *c) 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) { @@ -1424,10 +1216,10 @@ static void free_acl_list(IPAddressACL *in_acl) } } -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; @@ -1441,11 +1233,10 @@ static int validate_acl_list(IPAddressACL *in_acl, HTTPContext *c) 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); @@ -1468,14 +1259,14 @@ static void compute_real_filename(char *filename, int max_size) 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) @@ -1508,7 +1299,7 @@ static int http_parse_request(HTTPContext *c) char protocol[32]; char msg[1024]; const char *mime_type; - FFStream *stream; + FFServerStream *stream; int i; char ratebuf[32]; const char *useragent = 0; @@ -1533,7 +1324,7 @@ static int http_parse_request(HTTPContext *c) 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 */ @@ -1565,7 +1356,7 @@ static int http_parse_request(HTTPContext *c) 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")) { @@ -1583,7 +1374,7 @@ static int http_parse_request(HTTPContext *c) 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; @@ -1638,7 +1429,7 @@ static int http_parse_request(HTTPContext *c) 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, @@ -1649,7 +1440,7 @@ static int http_parse_request(HTTPContext *c) "

The server is too busy to serve your request at this time.

\r\n" "

The bandwidth being served (including your stream) is %"PRIu64"kbit/sec, " "and this exceeds the limit of %"PRIu64"kbit/sec.

\r\n" - "\r\n", current_bandwidth, max_bandwidth); + "\r\n", current_bandwidth, config.max_bandwidth); q += strlen(q); /* prepare output buffer */ c->buffer_ptr = c->buffer; @@ -1734,7 +1525,7 @@ static int http_parse_request(HTTPContext *c) /* 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; @@ -1935,7 +1726,7 @@ static void fmt_bytecount(AVIOContext *pb, int64_t count) static void compute_status(HTTPContext *c) { HTTPContext *c1; - FFStream *stream; + FFServerStream *stream; char *p; time_t ti; int i, len; @@ -1962,7 +1753,7 @@ static void compute_status(HTTPContext *c) avio_printf(pb, "

Available Streams

\n"); avio_printf(pb, "\n"); avio_printf(pb, "
PathServed
Conns

bytes
FormatBit rate
kbits/s
Video
kbits/s

Codec
Audio
kbits/s

Codec
Feed\n"); - stream = first_stream; + stream = config.first_stream; while (stream) { char sfilename[1024]; char *eosf; @@ -2051,7 +1842,7 @@ static void compute_status(HTTPContext *c) } avio_printf(pb, "
\n"); - stream = first_stream; + stream = config.first_stream; while (stream) { if (stream->feed == stream) { avio_printf(pb, "

Feed %s

", stream->filename); @@ -2121,10 +1912,10 @@ static void compute_status(HTTPContext *c) avio_printf(pb, "

Connection Status

\n"); avio_printf(pb, "Number of connections: %d / %d
\n", - nb_connections, nb_max_connections); + nb_connections, config.nb_max_connections); avio_printf(pb, "Bandwidth in use: %"PRIu64"k / %"PRIu64"k
\n", - current_bandwidth, max_bandwidth); + current_bandwidth, config.max_bandwidth); avio_printf(pb, "\n"); avio_printf(pb, "
#FileIPProtoStateTarget bits/secActual bits/secBytes transferred\n"); @@ -2291,7 +2082,7 @@ static int http_prepare_data(HTTPContext *c) for(i=0;istream->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]; @@ -2463,6 +2254,7 @@ static int http_prepare_data(HTTPContext *c) 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; @@ -2513,7 +2305,7 @@ static int http_send_data(HTTPContext *c) ret = http_prepare_data(c); if (ret < 0) return -1; - else if (ret != 0) + else if (ret) /* state change requested */ break; } else { @@ -2744,7 +2536,7 @@ static int http_receive_data(HTTPContext *c) } 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) { @@ -2800,14 +2592,14 @@ static int http_receive_data(HTTPContext *c) 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; @@ -2820,7 +2612,7 @@ static int http_receive_data(HTTPContext *c) } avformat_close_input(&s); - av_free(pb); + av_freep(&pb); } c->buffer_ptr = c->buffer; } @@ -2896,7 +2688,7 @@ static int rtsp_parse_request(HTTPContext *c) } /* 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; } @@ -2957,7 +2749,7 @@ static int rtsp_parse_request(HTTPContext *c) 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; @@ -2999,7 +2791,7 @@ static int prepare_sdp_description(FFStream *stream, uint8_t **pbuffer, 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); @@ -3018,7 +2810,7 @@ static void rtsp_cmd_options(HTTPContext *c, const char *url) static void rtsp_cmd_describe(HTTPContext *c, const char *url) { - FFStream *stream; + FFServerStream *stream; char path1[1024]; const char *path; uint8_t *content; @@ -3032,7 +2824,7 @@ static void rtsp_cmd_describe(HTTPContext *c, const char *url) 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)) { @@ -3093,7 +2885,7 @@ static RTSPTransportField *find_transport(RTSPMessageHeader *h, enum RTSPLowerTr 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]; @@ -3110,7 +2902,7 @@ static void rtsp_cmd_setup(HTTPContext *c, const char *url, 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 */ @@ -3330,7 +3122,7 @@ static void rtsp_cmd_interrupt(HTTPContext *c, const char *url, RTSPMessageHeade /* 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; @@ -3338,7 +3130,7 @@ static HTTPContext *rtp_new_connection(struct sockaddr_in *from_addr, /* 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 */ @@ -3386,7 +3178,7 @@ static HTTPContext *rtp_new_connection(struct sockaddr_in *from_addr, fail: if (c) { - av_free(c->buffer); + av_freep(&c->buffer); av_free(c); } return NULL; @@ -3494,7 +3286,7 @@ static int rtp_new_av_stream(HTTPContext *c, /********************************************************************/ /* 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; @@ -3505,13 +3297,8 @@ static AVStream *add_av_stream1(FFStream *stream, AVCodecContext *codec, int cop 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. @@ -3527,7 +3314,7 @@ static AVStream *add_av_stream1(FFStream *stream, AVCodecContext *codec, int cop } /* 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; @@ -3535,8 +3322,7 @@ static int add_av_stream(FFStream *feed, AVStream *st) av = st->codec; for(i=0;inb_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) { @@ -3564,13 +3350,16 @@ static int add_av_stream(FFStream *feed, AVStream *st) 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; @@ -3633,11 +3422,11 @@ static void extract_mpeg4_header(AVFormatContext *infile) /* 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 && @@ -3685,11 +3474,11 @@ static void build_file_streams(void) /* 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) { @@ -3704,7 +3493,7 @@ static void build_feed_streams(void) } /* 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) { @@ -3834,9 +3623,9 @@ static void compute_bandwidth(void) { 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;inb_streams;i++) { AVStream *st = stream->streams[i]; @@ -3853,834 +3642,15 @@ static void compute_bandwidth(void) } } -/* 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, "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, "")) { - if (!feed) { - ERROR("No corresponding for \n"); - } - feed = NULL; - } else if (!av_strcasecmp(cmd, "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 -: %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, "")) { - if (!stream) { - ERROR("No corresponding for \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, "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, "")) { - if (!redirect) { - ERROR("No corresponding for \n"); - } else { - if (!redirect->feed_filename[0]) { - ERROR("No URL found for \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; @@ -4689,7 +3659,7 @@ static void handle_child_exit(int sig) if (uptime < 30) /* Turn off any more restarts */ - feed->child_argv = 0; + ffserver_free_child_args(&feed->child_argv); } } } @@ -4699,8 +3669,8 @@ static void handle_child_exit(int sig) 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) @@ -4715,7 +3685,7 @@ static const OptionDef options[] = { #include "cmdutils_common_opts.h" { "n", OPT_BOOL, {(void *)&no_launch }, "enable no-launch mode" }, { "d", 0, {(void*)opt_debug}, "enable debug mode" }, - { "f", HAS_ARG | OPT_STRING, {(void*)&config_filename }, "use configfile instead of /etc/ffserver.conf", "configfile" }, + { "f", HAS_ARG | OPT_STRING, {(void*)&config.filename }, "use configfile instead of /etc/ffserver.conf", "configfile" }, { NULL }, }; @@ -4724,7 +3694,7 @@ int main(int argc, char **argv) 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(); @@ -4744,19 +3714,19 @@ int main(int argc, char **argv) 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); } diff --git a/ffmpeg/ffserver_config.c b/ffmpeg/ffserver_config.c new file mode 100644 index 0000000..8ea86aa --- /dev/null +++ b/ffmpeg/ffserver_config.c @@ -0,0 +1,1260 @@ +/* + * 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 +#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 or \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, "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, "")) { + *pfeed = NULL; + } else { + ERROR("Invalid entry '%s' inside \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, "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 " + "-: %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, "")) { + 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 \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, "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, "")) { + if (!redirect->feed_filename[0]) + ERROR("No URL found for \n"); + *predirect = NULL; + } else { + ERROR("Invalid entry '%s' inside \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, "next; + /* add in feed list */ + *last_feed = feed; + last_feed = &feed->next_feed; + } + } + } else if (stream || !av_strcasecmp(cmd, "next; + } + } + } else if (redirect || !av_strcasecmp(cmd, "next; + } + } + } else { + ffserver_parse_config_global(config, cmd, &p); + } + } + if (stream || feed || redirect) + ERROR("Not closed tag %s\n", stream ? "" : (feed ? "" : "")); + + 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); +} diff --git a/ffmpeg/ffserver_config.h b/ffmpeg/ffserver_config.h new file mode 100644 index 0000000..bdeb3c9 --- /dev/null +++ b/ffmpeg/ffserver_config.h @@ -0,0 +1,133 @@ +/* + * 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 */ diff --git a/ffmpeg/libavcodec/4xm.c b/ffmpeg/libavcodec/4xm.c index 3d3bc56..3a25622 100644 --- a/ffmpeg/libavcodec/4xm.c +++ b/ffmpeg/libavcodec/4xm.c @@ -339,21 +339,25 @@ static inline void mcdc(uint16_t *dst, const uint16_t *src, int log2w, } } -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--; diff --git a/ffmpeg/libavcodec/Makefile b/ffmpeg/libavcodec/Makefile index 43d73a7..fa0f53d 100644 --- a/ffmpeg/libavcodec/Makefile +++ b/ffmpeg/libavcodec/Makefile @@ -11,6 +11,7 @@ HEADERS = avcodec.h \ vda.h \ vdpau.h \ version.h \ + vorbis_parser.h \ xvmc.h \ OBJS = allcodecs.o \ @@ -31,6 +32,8 @@ OBJS = allcodecs.o \ resample.o \ resample2.o \ utils.o \ + vorbis_parser.o \ + xiph.o \ # subsystems OBJS-$(CONFIG_AANDCTTABLES) += aandcttab.o @@ -70,7 +73,7 @@ OBJS-$(CONFIG_LLVIDDSP) += lossless_videodsp.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 @@ -133,6 +136,7 @@ OBJS-$(CONFIG_AMV_ENCODER) += mjpegenc.o mjpeg.o mjpegenc_common.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 @@ -276,7 +280,7 @@ OBJS-$(CONFIG_INTERPLAY_VIDEO_DECODER) += interplayvideo.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 @@ -429,6 +433,7 @@ OBJS-$(CONFIG_SONIC_LS_ENCODER) += sonic.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 @@ -444,7 +449,6 @@ OBJS-$(CONFIG_TAK_DECODER) += takdec.o tak.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 @@ -473,7 +477,9 @@ OBJS-$(CONFIG_V410_ENCODER) += v410enc.o OBJS-$(CONFIG_V210X_DECODER) += v210x.o OBJS-$(CONFIG_VB_DECODER) += vb.o OBJS-$(CONFIG_VBLE_DECODER) += vble.o -OBJS-$(CONFIG_VC1_DECODER) += vc1dec.o vc1.o vc1data.o vc1dsp.o \ +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 @@ -481,7 +487,7 @@ OBJS-$(CONFIG_VMDAUDIO_DECODER) += vmdaudio.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 @@ -673,20 +679,18 @@ OBJS-$(CONFIG_VC1_VDPAU_HWACCEL) += vdpau_vc1.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 @@ -695,21 +699,19 @@ OBJS-$(CONFIG_MPEGTS_MUXER) += mpeg4audio.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 @@ -753,7 +755,7 @@ OBJS-$(CONFIG_LIBVO_AACENC_ENCODER) += libvo-aacenc.o mpeg4audio.o 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 @@ -809,7 +811,6 @@ OBJS-$(CONFIG_TAK_PARSER) += tak_parser.o tak.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 diff --git a/ffmpeg/libavcodec/aac.h b/ffmpeg/libavcodec/aac.h index 1bcd95c..a151737 100644 --- a/ffmpeg/libavcodec/aac.h +++ b/ffmpeg/libavcodec/aac.h @@ -245,6 +245,7 @@ typedef struct SingleChannelElement { * 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) @@ -274,6 +275,7 @@ struct AACContext { ChannelElement *che[4][MAX_ELEM_ID]; ChannelElement *tag_che_map[4][MAX_ELEM_ID]; int tags_mapped; + int warned_remapping_once; /** @} */ /** @@ -293,7 +295,7 @@ struct AACContext { FFTContext mdct_ld; FFTContext mdct_ltp; FmtConvertContext fmt_conv; - AVFloatDSPContext fdsp; + AVFloatDSPContext *fdsp; int random_state; /** @} */ diff --git a/ffmpeg/libavcodec/aacdec.c b/ffmpeg/libavcodec/aacdec.c index 10c509b..d00b3d0 100644 --- a/ffmpeg/libavcodec/aacdec.c +++ b/ffmpeg/libavcodec/aacdec.c @@ -621,6 +621,12 @@ static ChannelElement *get_che(AACContext *ac, int type, int elem_id) * 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]; } @@ -630,6 +636,22 @@ static ChannelElement *get_che(AACContext *ac, int type, int elem_id) 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) { @@ -681,6 +703,7 @@ static void decode_channel_map(uint8_t layout_map[][3], syn_ele = TYPE_LFE; break; default: + // AAC_CHANNEL_OFF has no channel map av_assert0(0); } layout_map[0][0] = syn_ele; @@ -1114,7 +1137,10 @@ static av_cold int aac_decode_init(AVCodecContext *avctx) 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; @@ -1490,13 +1516,12 @@ static void decode_mid_side_stereo(ChannelElement *cpe, GetBitContext *gb, 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])); } } @@ -1618,9 +1643,9 @@ static int decode_spectrum_and_dequant(AACContext *ac, float coef[1024], 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]; @@ -1766,7 +1791,7 @@ static int decode_spectrum_and_dequant(AACContext *ac, float coef[1024], } } 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); } } @@ -1979,7 +2004,7 @@ static void apply_mid_side_stereo(AACContext *ac, ChannelElement *cpe) 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]); } @@ -2018,7 +2043,7 @@ static void apply_intensity_stereo(AACContext *ac, 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]); @@ -2268,7 +2293,12 @@ static int decode_extension_payload(AACContext *ac, GetBitContext *gb, int cnt, { 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: @@ -2381,15 +2411,15 @@ static void windowing_and_mdct_ltp(AACContext *ac, float *out, 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); @@ -2442,17 +2472,17 @@ static void update_ltp(AACContext *ac, SingleChannelElement *sce) 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]; } @@ -2493,19 +2523,19 @@ static void imdct_and_windowing(AACContext *ac, SingleChannelElement *sce) */ 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)); } } @@ -2513,9 +2543,9 @@ static void imdct_and_windowing(AACContext *ac, SingleChannelElement *sce) // 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)); @@ -2540,10 +2570,10 @@ static void imdct_and_windowing_ld(AACContext *ac, SingleChannelElement *sce) 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 @@ -2716,7 +2746,7 @@ static void spectral_to_sample(AACContext *ac) 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) { @@ -2748,6 +2778,9 @@ static void spectral_to_sample(AACContext *ac) } 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); } } } @@ -2852,6 +2885,7 @@ static int aac_decode_er_frame(AVCodecContext *avctx, void *data, elem_type, elem_id); return AVERROR_INVALIDDATA; } + che->present = 1; if (aot != AOT_ER_AAC_ELD) skip_bits(gb, 4); switch (elem_type) { @@ -2915,6 +2949,9 @@ static int aac_decode_frame_int(AVCodecContext *avctx, void *data, 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", @@ -2923,6 +2960,7 @@ static int aac_decode_frame_int(AVCodecContext *avctx, void *data, goto fail; } samples = 1024; + che->present = 1; } switch (elem_type) { @@ -3131,6 +3169,7 @@ static av_cold int aac_decode_close(AVCodecContext *avctx) ff_mdct_end(&ac->mdct_small); ff_mdct_end(&ac->mdct_ld); ff_mdct_end(&ac->mdct_ltp); + av_freep(&ac->fdsp); return 0; } @@ -3440,6 +3479,18 @@ static const AVClass aac_decoder_class = { .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)"), @@ -3456,6 +3507,7 @@ AVCodec ff_aac_decoder = { .channel_layouts = aac_channel_layout, .flush = flush, .priv_class = &aac_decoder_class, + .profiles = profiles, }; /* @@ -3478,4 +3530,5 @@ AVCodec ff_aac_latm_decoder = { .capabilities = CODEC_CAP_CHANNEL_CONF | CODEC_CAP_DR1, .channel_layouts = aac_channel_layout, .flush = flush, + .profiles = profiles, }; diff --git a/ffmpeg/libavcodec/aacenc.c b/ffmpeg/libavcodec/aacenc.c index 0378f0d..d9c7215 100644 --- a/ffmpeg/libavcodec/aacenc.c +++ b/ffmpeg/libavcodec/aacenc.c @@ -252,7 +252,7 @@ static void apply_window_and_mdct(AACEncContext *s, SingleChannelElement *sce, 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); @@ -567,6 +567,10 @@ static int aac_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, 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; } @@ -678,6 +682,7 @@ static av_cold int aac_encode_end(AVCodecContext *avctx) 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; } @@ -686,7 +691,9 @@ static av_cold int dsp_init(AVCodecContext *avctx, AACEncContext *s) { 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); @@ -776,7 +783,7 @@ static av_cold int aac_encode_init(AVCodecContext *avctx) 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; diff --git a/ffmpeg/libavcodec/aacenc.h b/ffmpeg/libavcodec/aacenc.h index ecd6811..0decb1d 100644 --- a/ffmpeg/libavcodec/aacenc.h +++ b/ffmpeg/libavcodec/aacenc.h @@ -67,7 +67,7 @@ typedef struct AACEncContext { 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 diff --git a/ffmpeg/libavcodec/aacsbr.c b/ffmpeg/libavcodec/aacsbr.c index f550ead..94a5685 100644 --- a/ffmpeg/libavcodec/aacsbr.c +++ b/ffmpeg/libavcodec/aacsbr.c @@ -326,7 +326,7 @@ static int check_n_master(AVCodecContext *avctx, int n_master, int bs_xover_band 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; @@ -556,7 +556,8 @@ static int sbr_hf_calc_npatches(AACContext *ac, SpectralBandReplication *sbr) 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; @@ -1611,8 +1612,14 @@ static void sbr_hf_assemble(float Y1[38][64][2], 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++) { @@ -1693,7 +1700,7 @@ void ff_sbr_apply(AACContext *ac, SpectralBandReplication *sbr, int id_aac, } 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, @@ -1739,13 +1746,13 @@ void ff_sbr_apply(AACContext *ac, SpectralBandReplication *sbr, int id_aac, 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, diff --git a/ffmpeg/libavcodec/aarch64/fft_neon.S b/ffmpeg/libavcodec/aarch64/fft_neon.S index 54c13a4..30f24dd 100644 --- a/ffmpeg/libavcodec/aarch64/fft_neon.S +++ b/ffmpeg/libavcodec/aarch64/fft_neon.S @@ -376,7 +376,8 @@ function ff_fft_calc_neon, export=1 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] @@ -416,21 +417,21 @@ function ff_fft_permute_neon, export=1 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 diff --git a/ffmpeg/libavcodec/aarch64/opus_imdct_neon.S b/ffmpeg/libavcodec/aarch64/opus_imdct_neon.S index 6234309..c242261 100644 --- a/ffmpeg/libavcodec/aarch64/opus_imdct_neon.S +++ b/ffmpeg/libavcodec/aarch64/opus_imdct_neon.S @@ -438,8 +438,8 @@ function fft_b15_calc_neon 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] @@ -452,13 +452,13 @@ function fft_b15_calc_neon 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 diff --git a/ffmpeg/libavcodec/ac3dec.c b/ffmpeg/libavcodec/ac3dec.c index 969e37f..d3e8713 100644 --- a/ffmpeg/libavcodec/ac3dec.c +++ b/ffmpeg/libavcodec/ac3dec.c @@ -195,7 +195,7 @@ static av_cold int ac3_decode_init(AVCodecContext *avctx) #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); @@ -688,7 +688,7 @@ static inline void do_imdct(AC3DecodeContext *s, int channels) 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++) @@ -700,7 +700,7 @@ static inline void do_imdct(AC3DecodeContext *s, int channels) 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)); @@ -1635,9 +1635,7 @@ static av_cold int ac3_decode_end(AVCodecContext *avctx) 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; } diff --git a/ffmpeg/libavcodec/ac3dec.h b/ffmpeg/libavcodec/ac3dec.h index a213bc0..be29f00 100644 --- a/ffmpeg/libavcodec/ac3dec.h +++ b/ffmpeg/libavcodec/ac3dec.h @@ -218,7 +218,7 @@ typedef struct AC3DecodeContext { #if USE_FIXED AVFixedDSPContext *fdsp; #else - AVFloatDSPContext fdsp; + AVFloatDSPContext *fdsp; #endif AC3DSPContext ac3dsp; FmtConvertContext fmt_conv; ///< optimized conversion functions diff --git a/ffmpeg/libavcodec/ac3enc.c b/ffmpeg/libavcodec/ac3enc.c index ce5cde8..dc52908 100644 --- a/ffmpeg/libavcodec/ac3enc.c +++ b/ffmpeg/libavcodec/ac3enc.c @@ -2035,6 +2035,7 @@ av_cold int ff_ac3_encode_close(AVCodecContext *avctx) 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); @@ -2434,7 +2435,7 @@ av_cold int ff_ac3_encode_init(AVCodecContext *avctx) 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) diff --git a/ffmpeg/libavcodec/ac3enc.h b/ffmpeg/libavcodec/ac3enc.h index 9c9a7ce..a2442d0 100644 --- a/ffmpeg/libavcodec/ac3enc.h +++ b/ffmpeg/libavcodec/ac3enc.h @@ -80,12 +80,14 @@ typedef int64_t CoefSumType; #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 @@ -163,7 +165,7 @@ typedef struct AC3EncodeContext { 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 diff --git a/ffmpeg/libavcodec/ac3enc_float.c b/ffmpeg/libavcodec/ac3enc_float.c index fa6e509..766b14e 100644 --- a/ffmpeg/libavcodec/ac3enc_float.c +++ b/ffmpeg/libavcodec/ac3enc_float.c @@ -139,7 +139,9 @@ static CoefType calc_cpl_coord(CoefSumType energy_ch, CoefSumType energy_cpl) 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); } diff --git a/ffmpeg/libavcodec/ac3enc_opts_template.c b/ffmpeg/libavcodec/ac3enc_opts_template.c index a252be9..83113b8 100644 --- a/ffmpeg/libavcodec/ac3enc_opts_template.c +++ b/ffmpeg/libavcodec/ac3enc_opts_template.c @@ -46,18 +46,20 @@ static const AVOption ac3_options[] = { {"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"}, diff --git a/ffmpeg/libavcodec/ac3enc_template.c b/ffmpeg/libavcodec/ac3enc_template.c index f1f81da..c3ad76f 100644 --- a/ffmpeg/libavcodec/ac3enc_template.c +++ b/ffmpeg/libavcodec/ac3enc_template.c @@ -108,7 +108,7 @@ static void apply_mdct(AC3EncodeContext *s) 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, @@ -443,7 +443,7 @@ int AC3_NAME(encode_frame)(AVCodecContext *avctx, AVPacket *avpkt, 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; diff --git a/ffmpeg/libavcodec/adxenc.c b/ffmpeg/libavcodec/adxenc.c index 05e3245..4387ffb 100644 --- a/ffmpeg/libavcodec/adxenc.c +++ b/ffmpeg/libavcodec/adxenc.c @@ -43,14 +43,12 @@ static void adx_encode(ADXContext *c, uint8_t *adx, const int16_t *wav, 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) @@ -58,10 +56,10 @@ static void adx_encode(ADXContext *c, uint8_t *adx, const int16_t *wav, 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; } @@ -77,8 +75,23 @@ static void adx_encode(ADXContext *c, uint8_t *adx, const int16_t *wav, 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); } diff --git a/ffmpeg/libavcodec/alacenc.c b/ffmpeg/libavcodec/alacenc.c index b9ad899..ce63da6 100644 --- a/ffmpeg/libavcodec/alacenc.c +++ b/ffmpeg/libavcodec/alacenc.c @@ -429,10 +429,9 @@ static void write_element(AlacEncodeContext *s, // 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]); } } } @@ -444,7 +443,7 @@ static void write_element(AlacEncodeContext *s, // 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]; } diff --git a/ffmpeg/libavcodec/allcodecs.c b/ffmpeg/libavcodec/allcodecs.c index 7650543..0d39d33 100644 --- a/ffmpeg/libavcodec/allcodecs.c +++ b/ffmpeg/libavcodec/allcodecs.c @@ -105,6 +105,7 @@ void avcodec_register_all(void) 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); @@ -490,6 +491,7 @@ void avcodec_register_all(void) 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); diff --git a/ffmpeg/libavcodec/alpha/idctdsp_alpha.c b/ffmpeg/libavcodec/alpha/idctdsp_alpha.c index 1050697..1923ebb 100644 --- a/ffmpeg/libavcodec/alpha/idctdsp_alpha.c +++ b/ffmpeg/libavcodec/alpha/idctdsp_alpha.c @@ -24,14 +24,14 @@ #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, diff --git a/ffmpeg/libavcodec/alpha/idctdsp_alpha.h b/ffmpeg/libavcodec/alpha/idctdsp_alpha.h index e52cd80..bf98495 100644 --- a/ffmpeg/libavcodec/alpha/idctdsp_alpha.h +++ b/ffmpeg/libavcodec/alpha/idctdsp_alpha.h @@ -23,9 +23,9 @@ #include 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); diff --git a/ffmpeg/libavcodec/alpha/idctdsp_alpha_asm.S b/ffmpeg/libavcodec/alpha/idctdsp_alpha_asm.S index e3a8364..f545df9 100644 --- a/ffmpeg/libavcodec/alpha/idctdsp_alpha_asm.S +++ b/ffmpeg/libavcodec/alpha/idctdsp_alpha_asm.S @@ -33,7 +33,7 @@ /************************************************************************ * 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 @@ -83,7 +83,7 @@ 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 diff --git a/ffmpeg/libavcodec/anm.c b/ffmpeg/libavcodec/anm.c index 79a87dd..3727534 100644 --- a/ffmpeg/libavcodec/anm.c +++ b/ffmpeg/libavcodec/anm.c @@ -47,8 +47,10 @@ static av_cold int decode_init(AVCodecContext *avctx) 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++) diff --git a/ffmpeg/libavcodec/ansi.c b/ffmpeg/libavcodec/ansi.c index 45c307f..92981cc 100644 --- a/ffmpeg/libavcodec/ansi.c +++ b/ffmpeg/libavcodec/ansi.c @@ -90,9 +90,11 @@ static av_cold int decode_init(AVCodecContext *avctx) 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; } diff --git a/ffmpeg/libavcodec/apng.h b/ffmpeg/libavcodec/apng.h new file mode 100644 index 0000000..41249e0 --- /dev/null +++ b/ffmpeg/libavcodec/apng.h @@ -0,0 +1,41 @@ +/* + * 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 */ diff --git a/ffmpeg/libavcodec/arm/flacdsp_init_arm.c b/ffmpeg/libavcodec/arm/flacdsp_init_arm.c index 9ddb268..df1b19c 100644 --- a/ffmpeg/libavcodec/arm/flacdsp_init_arm.c +++ b/ffmpeg/libavcodec/arm/flacdsp_init_arm.c @@ -24,7 +24,7 @@ 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) diff --git a/ffmpeg/libavcodec/arm/idctdsp_arm.S b/ffmpeg/libavcodec/arm/idctdsp_arm.S index e8333c4..057eff9 100644 --- a/ffmpeg/libavcodec/arm/idctdsp_arm.S +++ b/ffmpeg/libavcodec/arm/idctdsp_arm.S @@ -22,7 +22,7 @@ #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 diff --git a/ffmpeg/libavcodec/arm/idctdsp_init_arm.c b/ffmpeg/libavcodec/arm/idctdsp_init_arm.c index 2d846dc..da5da06 100644 --- a/ffmpeg/libavcodec/arm/idctdsp_init_arm.c +++ b/ffmpeg/libavcodec/arm/idctdsp_init_arm.c @@ -30,7 +30,7 @@ #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 */ diff --git a/ffmpeg/libavcodec/arm/idctdsp_init_armv6.c b/ffmpeg/libavcodec/arm/idctdsp_init_armv6.c index 648f1fd..a3470a8 100644 --- a/ffmpeg/libavcodec/arm/idctdsp_init_armv6.c +++ b/ffmpeg/libavcodec/arm/idctdsp_init_armv6.c @@ -27,7 +27,7 @@ #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) diff --git a/ffmpeg/libavcodec/arm/idctdsp_init_neon.c b/ffmpeg/libavcodec/arm/idctdsp_init_neon.c index 80c391c..b70c5b0 100644 --- a/ffmpeg/libavcodec/arm/idctdsp_init_neon.c +++ b/ffmpeg/libavcodec/arm/idctdsp_init_neon.c @@ -27,9 +27,9 @@ #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) diff --git a/ffmpeg/libavcodec/arm/me_cmp_init_arm.c b/ffmpeg/libavcodec/arm/me_cmp_init_arm.c index eb48b38..03870a2 100644 --- a/ffmpeg/libavcodec/arm/me_cmp_init_arm.c +++ b/ffmpeg/libavcodec/arm/me_cmp_init_arm.c @@ -26,17 +26,17 @@ #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) { diff --git a/ffmpeg/libavcodec/ass.c b/ffmpeg/libavcodec/ass.c index a5b5ae5..3a37cee 100644 --- a/ffmpeg/libavcodec/ass.c +++ b/ffmpeg/libavcodec/ass.c @@ -34,16 +34,39 @@ int ff_ass_subtitle_header(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); @@ -104,7 +127,7 @@ int ff_ass_bprint_dialog(AVBPrint *buf, const char *dialog, 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"); @@ -151,6 +174,15 @@ err: 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) { @@ -187,5 +219,4 @@ void ff_ass_bprint_text_event(AVBPrint *buf, const char *p, int size, av_bprint_chars(buf, *p, 1); } } - av_bprintf(buf, "\r\n"); } diff --git a/ffmpeg/libavcodec/ass.h b/ffmpeg/libavcodec/ass.h index 2df38e6..77218bf 100644 --- a/ffmpeg/libavcodec/ass.h +++ b/ffmpeg/libavcodec/ass.h @@ -91,6 +91,13 @@ int ff_ass_subtitle_header_default(AVCodecContext *avctx); 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. * diff --git a/ffmpeg/libavcodec/ass_split.c b/ffmpeg/libavcodec/ass_split.c index 413e9c8..cc4f961 100644 --- a/ffmpeg/libavcodec/ass_split.c +++ b/ffmpeg/libavcodec/ass_split.c @@ -44,7 +44,7 @@ typedef struct { int size; int offset; int offset_count; - ASSFields fields[10]; + ASSFields fields[24]; } ASSSection; static const ASSSection ass_sections[] = { @@ -64,15 +64,29 @@ 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}, } }, @@ -82,14 +96,24 @@ 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) }, - {"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}, } }, @@ -99,11 +123,16 @@ static const ASSSection ass_sections[] = { .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}, } }, @@ -200,6 +229,20 @@ static inline const char *skip_space(const char *buf) 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]; @@ -217,7 +260,7 @@ static const char *ass_split_section(ASSSplitContext *ctx, const char *buf) } 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); @@ -240,6 +283,15 @@ static const char *ass_split_section(ASSSplitContext *ctx, const char *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; @@ -269,6 +321,7 @@ static const char *ass_split_section(ASSSplitContext *ctx, const char *buf) } } } +next_line: buf += strcspn(buf, "\n"); buf += !!*buf; } diff --git a/ffmpeg/libavcodec/ass_split.h b/ffmpeg/libavcodec/ass_split.h index 06c1ce3..c912252 100644 --- a/ffmpeg/libavcodec/ass_split.h +++ b/ffmpeg/libavcodec/ass_split.h @@ -41,13 +41,28 @@ typedef struct { 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; /** @@ -58,6 +73,11 @@ typedef struct { 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()) */ diff --git a/ffmpeg/libavcodec/asvenc.c b/ffmpeg/libavcodec/asvenc.c index 3ad2c31..2b2080e 100644 --- a/ffmpeg/libavcodec/asvenc.c +++ b/ffmpeg/libavcodec/asvenc.c @@ -52,7 +52,7 @@ static inline void asv1_put_level(PutBitContext *pb, int level) } } -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; @@ -60,6 +60,10 @@ static inline void asv2_put_level(PutBitContext *pb, int level) 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); } } @@ -152,13 +156,13 @@ static inline void asv2_encode_block(ASV1Context *a, int16_t block[64]) 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]); } } } diff --git a/ffmpeg/libavcodec/atrac1.c b/ffmpeg/libavcodec/atrac1.c index d059d75..aeb068c 100644 --- a/ffmpeg/libavcodec/atrac1.c +++ b/ffmpeg/libavcodec/atrac1.c @@ -80,7 +80,7 @@ typedef struct { 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 */ @@ -140,7 +140,7 @@ static int at1_imdct_block(AT1SUCtx* su, AT1Ctx *q) 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]; @@ -324,6 +324,8 @@ static av_cold int atrac1_decode_end(AVCodecContext * avctx) ff_mdct_end(&q->mdct_ctx[1]); ff_mdct_end(&q->mdct_ctx[2]); + av_freep(&q->fdsp); + return 0; } @@ -359,7 +361,7 @@ static av_cold int atrac1_decode_init(AVCodecContext *avctx) 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; diff --git a/ffmpeg/libavcodec/atrac3.c b/ffmpeg/libavcodec/atrac3.c index d1dfa6b..9dc0811 100644 --- a/ffmpeg/libavcodec/atrac3.c +++ b/ffmpeg/libavcodec/atrac3.c @@ -109,7 +109,7 @@ typedef struct ATRAC3Context { AtracGCContext gainc_ctx; FFTContext mdct_ctx; FmtConvertContext fmt_conv; - AVFloatDSPContext fdsp; + AVFloatDSPContext *fdsp; } ATRAC3Context; static DECLARE_ALIGNED(32, float, mdct_window)[MDCT_SIZE]; @@ -142,7 +142,7 @@ static void imlt(ATRAC3Context *q, float *input, float *output, int odd_band) 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); } /* @@ -190,8 +190,9 @@ static av_cold int atrac3_decode_close(AVCodecContext *avctx) { 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); @@ -915,11 +916,11 @@ static av_cold int atrac3_decode_init(AVCodecContext *avctx) } 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); } diff --git a/ffmpeg/libavcodec/atrac3plus.c b/ffmpeg/libavcodec/atrac3plus.c index f7a42cc..575a493 100644 --- a/ffmpeg/libavcodec/atrac3plus.c +++ b/ffmpeg/libavcodec/atrac3plus.c @@ -1575,7 +1575,7 @@ static void decode_tones_amplitude(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, { 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; diff --git a/ffmpeg/libavcodec/atrac3plusdec.c b/ffmpeg/libavcodec/atrac3plusdec.c index 3a6b3cf..78121e8 100644 --- a/ffmpeg/libavcodec/atrac3plusdec.c +++ b/ffmpeg/libavcodec/atrac3plusdec.c @@ -47,7 +47,7 @@ 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 @@ -67,7 +67,10 @@ typedef struct ATRAC3PContext { 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; } @@ -150,8 +153,6 @@ static av_cold int atrac3p_decode_init(AVCodecContext *avctx) 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); @@ -167,8 +168,9 @@ static av_cold int atrac3p_decode_init(AVCodecContext *avctx) 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); } @@ -265,7 +267,7 @@ static void reconstruct_frame(ATRAC3PContext *ctx, Atrac3pChanUnitCtx *ch_unit, 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) + @@ -299,7 +301,7 @@ static void reconstruct_frame(ATRAC3PContext *ctx, Atrac3pChanUnitCtx *ch_unit, 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]); } } diff --git a/ffmpeg/libavcodec/audio_frame_queue.c b/ffmpeg/libavcodec/audio_frame_queue.c index 1220345..4f6bccc 100644 --- a/ffmpeg/libavcodec/audio_frame_queue.c +++ b/ffmpeg/libavcodec/audio_frame_queue.c @@ -28,8 +28,8 @@ 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; } diff --git a/ffmpeg/libavcodec/avcodec.h b/ffmpeg/libavcodec/avcodec.h index fb1c9ca..dabae1b 100644 --- a/ffmpeg/libavcodec/avcodec.h +++ b/ffmpeg/libavcodec/avcodec.h @@ -42,11 +42,6 @@ #include "version.h" -#if FF_API_FAST_MALLOC -// to provide fast_*alloc -#include "libavutil/mem.h" -#endif - /** * @defgroup libavc Encoding/Decoding Library * @{ @@ -324,6 +319,7 @@ enum AVCodecID { 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 @@ -514,6 +510,7 @@ enum AVCodecID { 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'), @@ -552,7 +549,7 @@ enum AVCodecID { /** * 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; @@ -768,6 +765,7 @@ typedef struct RcOverride{ #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) @@ -1350,8 +1348,11 @@ typedef struct AVCodecContext { * 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; @@ -1377,16 +1378,7 @@ typedef struct AVCodecContext { * 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 @@ -1480,6 +1472,10 @@ typedef struct AVCodecContext { * @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. @@ -1800,21 +1796,19 @@ typedef struct AVCodecContext { */ 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 @@ -1837,13 +1831,13 @@ typedef struct AVCodecContext { */ 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 @@ -2277,16 +2271,18 @@ typedef struct AVCodecContext { */ 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 @@ -2303,12 +2299,13 @@ typedef struct AVCodecContext { 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 @@ -2324,14 +2321,16 @@ typedef struct AVCodecContext { */ 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, of what can be used without an underflow. @@ -2375,19 +2374,19 @@ typedef struct AVCodecContext { */ 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 @@ -2980,6 +2979,31 @@ typedef struct AVCodecContext { */ 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: @@ -3079,6 +3103,24 @@ typedef struct AVCodecContext { * - 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); @@ -3210,7 +3252,8 @@ int av_codec_get_max_lowres(const AVCodec *codec); struct MpegEncContext; /** - * AVHWAccel. + * @defgroup lavc_hwaccel AVHWAccel + * @{ */ typedef struct AVHWAccel { /** @@ -3346,6 +3389,17 @@ 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 * @@ -5116,16 +5170,26 @@ enum AVLockOp { /** * 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)); diff --git a/ffmpeg/libavcodec/avpacket.c b/ffmpeg/libavcodec/avpacket.c index a87e8e3..3c26046 100644 --- a/ffmpeg/libavcodec/avpacket.c +++ b/ffmpeg/libavcodec/avpacket.c @@ -34,8 +34,7 @@ void av_destruct_packet(AVPacket *pkt) { - av_free(pkt->data); - pkt->data = NULL; + av_freep(&pkt->data); pkt->size = 0; } @@ -273,7 +272,7 @@ void av_packet_free_side_data(AVPacket *pkt) { 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; } diff --git a/ffmpeg/libavcodec/avpicture.c b/ffmpeg/libavcodec/avpicture.c index a6f89ef..0484dc3 100644 --- a/ffmpeg/libavcodec/avpicture.c +++ b/ffmpeg/libavcodec/avpicture.c @@ -66,7 +66,7 @@ int avpicture_alloc(AVPicture *picture, void avpicture_free(AVPicture *picture) { - av_free(picture->data[0]); + av_freep(&picture->data[0]); } void av_picture_copy(AVPicture *dst, const AVPicture *src, diff --git a/ffmpeg/libavcodec/avs.c b/ffmpeg/libavcodec/avs.c index c4eaf20..976d325 100644 --- a/ffmpeg/libavcodec/avs.c +++ b/ffmpeg/libavcodec/avs.c @@ -165,9 +165,8 @@ static av_cold int avs_decode_init(AVCodecContext * avctx) 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) diff --git a/ffmpeg/libavcodec/avuienc.c b/ffmpeg/libavcodec/avuienc.c index 700b8cb..db640bb 100644 --- a/ffmpeg/libavcodec/avuienc.c +++ b/ffmpeg/libavcodec/avuienc.c @@ -25,16 +25,10 @@ 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; @@ -45,6 +39,11 @@ static av_cold int avui_encode_init(AVCodecContext *avctx) 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; } diff --git a/ffmpeg/libavcodec/bfi.c b/ffmpeg/libavcodec/bfi.c index c7ac378..77bca49 100644 --- a/ffmpeg/libavcodec/bfi.c +++ b/ffmpeg/libavcodec/bfi.c @@ -171,7 +171,7 @@ static int bfi_decode_frame(AVCodecContext *avctx, void *data, static av_cold int bfi_decode_close(AVCodecContext *avctx) { BFIContext *bfi = avctx->priv_data; - av_free(bfi->dst); + av_freep(&bfi->dst); return 0; } diff --git a/ffmpeg/libavcodec/bitstream_filter.c b/ffmpeg/libavcodec/bitstream_filter.c index 751b90d..3275326 100644 --- a/ffmpeg/libavcodec/bitstream_filter.c +++ b/ffmpeg/libavcodec/bitstream_filter.c @@ -43,9 +43,9 @@ void av_register_bitstream_filter(AVBitStreamFilter *bsf) 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)); @@ -54,7 +54,6 @@ AVBitStreamFilterContext *av_bitstream_filter_init(const char *name) bsf->priv_data_size ? av_mallocz(bsf->priv_data_size) : NULL; return bsfc; } - bsf = bsf->next; } return NULL; } diff --git a/ffmpeg/libavcodec/cavs.c b/ffmpeg/libavcodec/cavs.c index a41a8aa..c0880e0 100644 --- a/ffmpeg/libavcodec/cavs.c +++ b/ffmpeg/libavcodec/cavs.c @@ -30,6 +30,7 @@ #include "golomb.h" #include "h264chroma.h" #include "idctdsp.h" +#include "internal.h" #include "mathops.h" #include "qpeldsp.h" #include "cavs.h" @@ -539,8 +540,8 @@ static inline void scale_mv(AVSContext *h, int *d_x, int *d_y, { 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, @@ -822,16 +823,16 @@ av_cold int ff_cavs_end(AVCodecContext *avctx) 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; } diff --git a/ffmpeg/libavcodec/cavsdec.c b/ffmpeg/libavcodec/cavsdec.c index 34b65e6..b5304ea 100644 --- a/ffmpeg/libavcodec/cavsdec.c +++ b/ffmpeg/libavcodec/cavsdec.c @@ -467,7 +467,7 @@ static inline void mv_pred_direct(AVSContext *h, cavs_vector *pmv_fw, { 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]; @@ -476,7 +476,7 @@ static inline void mv_pred_direct(AVSContext *h, cavs_vector *pmv_fw, /* 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); } @@ -1147,8 +1147,7 @@ static int decode_seq_header(AVSContext *h) 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) diff --git a/ffmpeg/libavcodec/cngdec.c b/ffmpeg/libavcodec/cngdec.c index 855baaa..c49e903 100644 --- a/ffmpeg/libavcodec/cngdec.c +++ b/ffmpeg/libavcodec/cngdec.c @@ -41,11 +41,11 @@ typedef struct CNGContext { 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; } diff --git a/ffmpeg/libavcodec/codec_desc.c b/ffmpeg/libavcodec/codec_desc.c index 9e9728b..0af66f4 100644 --- a/ffmpeg/libavcodec/codec_desc.c +++ b/ffmpeg/libavcodec/codec_desc.c @@ -1440,6 +1440,14 @@ static const AVCodecDescriptor codec_descriptors[] = { .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" */ { @@ -2634,6 +2642,13 @@ static const AVCodecDescriptor codec_descriptors[] = { .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, diff --git a/ffmpeg/libavcodec/cook.c b/ffmpeg/libavcodec/cook.c index 0cc01d0..cfbce2a 100644 --- a/ffmpeg/libavcodec/cook.c +++ b/ffmpeg/libavcodec/cook.c @@ -1058,7 +1058,7 @@ static av_cold int cook_decode_init(AVCodecContext *avctx) 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; } diff --git a/ffmpeg/libavcodec/crystalhd.c b/ffmpeg/libavcodec/crystalhd.c index 45b2d46..001afa4 100644 --- a/ffmpeg/libavcodec/crystalhd.c +++ b/ffmpeg/libavcodec/crystalhd.c @@ -362,7 +362,7 @@ static av_cold int uninit(AVCodecContext *avctx) av_bitstream_filter_close(priv->bsfc); } - av_free(priv->sps_pps_buf); + av_freep(&priv->sps_pps_buf); av_frame_free (&priv->pic); diff --git a/ffmpeg/libavcodec/dca.c b/ffmpeg/libavcodec/dca.c index f952976..22be88f 100644 --- a/ffmpeg/libavcodec/dca.c +++ b/ffmpeg/libavcodec/dca.c @@ -30,8 +30,7 @@ #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 }; diff --git a/ffmpeg/libavcodec/dca_parser.c b/ffmpeg/libavcodec/dca_parser.c index 329b6e7..9fa6d0d 100644 --- a/ffmpeg/libavcodec/dca_parser.c +++ b/ffmpeg/libavcodec/dca_parser.c @@ -22,9 +22,9 @@ * 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; @@ -35,15 +35,15 @@ typedef struct DCAParseContext { } 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; @@ -51,7 +51,7 @@ static int dca_find_frame_end(DCAParseContext * pc1, const uint8_t * buf, ParseContext *pc = &pc1->pc; start_found = pc->frame_start_found; - state = pc->state; + state = pc->state; i = 0; if (!start_found) { @@ -59,7 +59,7 @@ static int dca_find_frame_end(DCAParseContext * pc1, const uint8_t * buf, 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; @@ -74,21 +74,21 @@ static int dca_find_frame_end(DCAParseContext * pc1, const uint8_t * buf, 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; @@ -122,7 +122,7 @@ static int dca_parse_params(const uint8_t *buf, int buf_size, int *duration, 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; @@ -130,10 +130,9 @@ static int dca_parse_params(const uint8_t *buf, int buf_size, int *duration, 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; @@ -145,7 +144,7 @@ static int dca_parse(AVCodecParserContext * s, 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; } @@ -153,12 +152,12 @@ static int dca_parse(AVCodecParserContext * s, /* 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; } diff --git a/ffmpeg/libavcodec/dcadata.h b/ffmpeg/libavcodec/dcadata.h index 72aebde..582f14d 100644 --- a/ffmpeg/libavcodec/dcadata.h +++ b/ffmpeg/libavcodec/dcadata.h @@ -24,4172 +24,4168 @@ #define AVCODEC_DCADATA_H #include + #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] = { @@ -4201,3114 +4197,3108 @@ 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), @@ -7439,8 +7429,7 @@ DECLARE_ALIGNED(16, static const float, lfe_fir_64)[] = 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), @@ -7521,26 +7510,26 @@ DECLARE_ALIGNED(16, static const float, lfe_fir_128)[] = * 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, @@ -7568,95 +7557,110 @@ static const float dca_default_coeffs[10][6][2] = { }; /* 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 */ diff --git a/ffmpeg/libavcodec/dcadec.c b/ffmpeg/libavcodec/dcadec.c index 82d96d2..a36f69b 100644 --- a/ffmpeg/libavcodec/dcadec.c +++ b/ffmpeg/libavcodec/dcadec.c @@ -34,17 +34,18 @@ #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" @@ -236,79 +237,79 @@ static const int8_t dca_lfe_index[] = { }; 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 */ @@ -471,7 +472,7 @@ typedef struct { int profile; int debug_flag; ///< used for suppressing repeated error messages output - AVFloatDSPContext fdsp; + AVFloatDSPContext *fdsp; FFTContext imdct; SynthFilterContext synth; DCADSPContext dcadsp; @@ -499,27 +500,27 @@ static av_cold void dca_init_vlcs(void) 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, @@ -642,7 +643,6 @@ static int dca_parse_audio_coding_header(DCAContext *s, int base_channel, 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) @@ -816,18 +816,17 @@ static int dca_parse_frame_header(DCAContext *s) #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); @@ -915,10 +914,10 @@ static int dca_subframe_header(DCAContext *s, int base_channel, int block_index) 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 */ @@ -996,7 +995,7 @@ static int dca_subframe_header(DCAContext *s, int base_channel, int block_index) 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; @@ -1076,7 +1075,7 @@ static int dca_subframe_header(DCAContext *s, int base_channel, int block_index) 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"); @@ -1130,10 +1129,10 @@ static void lfe_interpolation_fir(DCAContext *s, int decimation_select, /* 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 */ @@ -1219,7 +1218,7 @@ static void dca_downmix(float **samples, int srcfmt, int lfe_present, } 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]; @@ -1227,7 +1226,6 @@ static void dca_downmix(float **samples, int srcfmt, int lfe_present, } } - #ifndef decode_blockcodes /* Very compact version of the block code decoder that does not use table * look-up but is slightly slower */ @@ -1239,7 +1237,7 @@ static int decode_blockcode(int code, int levels, int32_t *values) for (i = 0; i < 4; i++) { int div = FASTDIV(code, levels); values[i] = code - offset - div * levels; - code = div; + code = div; } return code; @@ -1307,7 +1305,7 @@ static int dca_subsubframe(DCAContext *s, int base_channel, int block_index) /* 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) { @@ -1319,8 +1317,8 @@ static int dca_subsubframe(DCAContext *s, int base_channel, int block_index) 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"); @@ -1335,9 +1333,8 @@ static int dca_subsubframe(DCAContext *s, int base_channel, int block_index) /* 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); } - } } @@ -1419,12 +1416,10 @@ static int dca_filter_channels(DCAContext *s, int block_index) /* 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!!! */ @@ -1445,7 +1440,6 @@ static int dca_filter_channels(DCAContext *s, int block_index) return 0; } - static int dca_subframe_footer(DCAContext *s, int base_channel) { int in, out, aux_data_count, aux_data_end, reserved; @@ -1532,8 +1526,8 @@ static int dca_subframe_footer(DCAContext *s, int base_channel) // 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, @@ -1643,7 +1637,7 @@ static int dca_exss_parse_asset_header(DCAContext *s) 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) @@ -1707,7 +1701,6 @@ static int dca_exss_parse_asset_header(DCAContext *s) skip_bits_long(&s->gb, num_dec_ch * 5); // remap codes } } - } else { skip_bits(&s->gb, 3); // representation type } @@ -1750,10 +1743,18 @@ static int dca_exss_parse_asset_header(DCAContext *s) } 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 */ @@ -2129,7 +2130,7 @@ static int dca_decode_frame(AVCodecContext *avctx, void *data, { 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; @@ -2160,10 +2161,10 @@ static int dca_decode_frame(AVCodecContext *avctx, void *data, } 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; @@ -2232,7 +2233,6 @@ static int dca_decode_frame(AVCodecContext *avctx, void *data, /* 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); @@ -2263,8 +2263,9 @@ static int dca_decode_frame(AVCodecContext *avctx, void *data, /* 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; } @@ -2369,7 +2370,7 @@ FF_ENABLE_DEPRECATION_WARNINGS 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; @@ -2389,8 +2390,8 @@ FF_ENABLE_DEPRECATION_WARNINGS 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) { @@ -2478,7 +2479,7 @@ FF_ENABLE_DEPRECATION_WARNINGS 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) { @@ -2493,7 +2494,7 @@ FF_ENABLE_DEPRECATION_WARNINGS 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); @@ -2518,8 +2519,8 @@ FF_ENABLE_DEPRECATION_WARNINGS 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 */ @@ -2539,7 +2540,7 @@ FF_ENABLE_DEPRECATION_WARNINGS 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); } } @@ -2589,8 +2590,6 @@ FF_ENABLE_DEPRECATION_WARNINGS return buf_size; } - - /** * DCA initialization * @@ -2604,7 +2603,10 @@ static av_cold int dca_decode_init(AVCodecContext *avctx) 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); @@ -2631,6 +2633,7 @@ static av_cold int dca_decode_end(AVCodecContext *avctx) DCAContext *s = avctx->priv_data; ff_mdct_end(&s->imdct); av_freep(&s->extra_channels_buffer); + av_freep(&s->fdsp); return 0; } @@ -2644,7 +2647,7 @@ static const AVProfile profiles[] = { }; 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 }, }; diff --git a/ffmpeg/libavcodec/dcadsp.c b/ffmpeg/libavcodec/dcadsp.c index 7d50442..b32d962 100644 --- a/ffmpeg/libavcodec/dcadsp.c +++ b/ffmpeg/libavcodec/dcadsp.c @@ -20,8 +20,10 @@ */ #include "config.h" + #include "libavutil/attributes.h" #include "libavutil/intreadwrite.h" + #include "dcadsp.h" static void decode_hf_c(float dst[DCA_SUBBANDS][8], @@ -42,9 +44,8 @@ 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; @@ -55,7 +56,7 @@ dca_lfe_fir(float *out, const float *in, const float *coefs, 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; @@ -86,7 +87,8 @@ static void dca_qmf_32_subbands(float samples_in[32][8], int sb_act, } 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; } } @@ -103,10 +105,13 @@ static void dca_lfe_fir1_c(float *out, const float *in, const float *coefs) 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); } diff --git a/ffmpeg/libavcodec/dcahuff.h b/ffmpeg/libavcodec/dcahuff.h index cbc8429..9388b63 100644 --- a/ffmpeg/libavcodec/dcahuff.h +++ b/ffmpeg/libavcodec/dcahuff.h @@ -29,632 +29,595 @@ #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, @@ -665,8 +628,8 @@ static const uint16_t bitalloc_65_codes_a[65] = 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, @@ -677,8 +640,8 @@ static const uint16_t bitalloc_65_codes_b[65] = 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, @@ -689,8 +652,8 @@ static const uint16_t bitalloc_65_codes_c[65] = 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, @@ -701,8 +664,8 @@ static const uint16_t bitalloc_65_codes_d[65] = 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, @@ -713,8 +676,8 @@ static const uint16_t bitalloc_65_codes_e[65] = 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, @@ -725,8 +688,8 @@ static const uint16_t bitalloc_65_codes_f[65] = 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, @@ -737,56 +700,56 @@ static const uint16_t bitalloc_65_codes_g[65] = 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, @@ -794,8 +757,7 @@ static const uint8_t bitalloc_65_bits_g[65] = 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, @@ -814,8 +776,8 @@ static const uint16_t bitalloc_129_codes_a[129] = 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, @@ -834,8 +796,8 @@ static const uint16_t bitalloc_129_codes_b[129] = 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, @@ -854,8 +816,8 @@ static const uint16_t bitalloc_129_codes_c[129] = 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, @@ -874,8 +836,8 @@ static const uint16_t bitalloc_129_codes_d[129] = 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, @@ -894,8 +856,8 @@ static const uint16_t bitalloc_129_codes_e[129] = 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, @@ -914,8 +876,8 @@ static const uint16_t bitalloc_129_codes_f[129] = 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, @@ -934,8 +896,8 @@ static const uint16_t bitalloc_129_codes_g[129] = 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, @@ -946,8 +908,8 @@ static const uint8_t bitalloc_129_bits_a[129] = 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, @@ -958,8 +920,8 @@ static const uint8_t bitalloc_129_bits_b[129] = 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, @@ -970,8 +932,8 @@ static const uint8_t bitalloc_129_bits_c[129] = 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, @@ -982,8 +944,8 @@ static const uint8_t bitalloc_129_bits_d[129] = 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, @@ -994,8 +956,8 @@ static const uint8_t bitalloc_129_bits_e[129] = 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, @@ -1006,8 +968,8 @@ static const uint8_t bitalloc_129_bits_f[129] = 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, @@ -1019,10 +981,13 @@ static const uint8_t bitalloc_129_bits_g[129] = 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 }, @@ -1037,40 +1002,40 @@ static const uint8_t bitalloc_maxbits[10][7] = { { 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 */ diff --git a/ffmpeg/libavcodec/dct-test.c b/ffmpeg/libavcodec/dct-test.c index 1739c37..30eca3e 100644 --- a/ffmpeg/libavcodec/dct-test.c +++ b/ffmpeg/libavcodec/dct-test.c @@ -98,8 +98,8 @@ static const struct algo idct_tab[] = { #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 diff --git a/ffmpeg/libavcodec/dct.c b/ffmpeg/libavcodec/dct.c index 26b4851..9cabc4f 100644 --- a/ffmpeg/libavcodec/dct.c +++ b/ffmpeg/libavcodec/dct.c @@ -193,7 +193,7 @@ av_cold int ff_dct_init(DCTContext *s, int nbits, enum DCTTransformType inverse) 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; } @@ -218,5 +218,5 @@ av_cold int ff_dct_init(DCTContext *s, int nbits, enum DCTTransformType inverse) av_cold void ff_dct_end(DCTContext *s) { ff_rdft_end(&s->rdft); - av_free(s->csc2); + av_freep(&s->csc2); } diff --git a/ffmpeg/libavcodec/dirac.c b/ffmpeg/libavcodec/dirac.c index c1f6937..07db919 100644 --- a/ffmpeg/libavcodec/dirac.c +++ b/ffmpeg/libavcodec/dirac.c @@ -174,8 +174,7 @@ static int parse_source_parameters(AVCodecContext *avctx, GetBitContext *gb, /* [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) */ diff --git a/ffmpeg/libavcodec/dirac_arith.h b/ffmpeg/libavcodec/dirac_arith.h index a1fa96b..003430a 100644 --- a/ffmpeg/libavcodec/dirac_arith.h +++ b/ffmpeg/libavcodec/dirac_arith.h @@ -135,7 +135,7 @@ static inline int dirac_get_arith_bit(DiracArith *c, int ctx) 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; diff --git a/ffmpeg/libavcodec/dirac_parser.c b/ffmpeg/libavcodec/dirac_parser.c index 4119e3b..45ded5a 100644 --- a/ffmpeg/libavcodec/dirac_parser.c +++ b/ffmpeg/libavcodec/dirac_parser.c @@ -139,6 +139,8 @@ static int dirac_combine_frame(AVCodecParserContext *s, AVCodecContext *avctx, 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); @@ -149,6 +151,8 @@ static int dirac_combine_frame(AVCodecParserContext *s, AVCodecContext *avctx, 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; @@ -247,7 +251,7 @@ static void dirac_parse_close(AVCodecParserContext *s) DiracParseContext *pc = s->priv_data; if (pc->buffer_size > 0) - av_free(pc->buffer); + av_freep(&pc->buffer); } AVCodecParser ff_dirac_parser = { diff --git a/ffmpeg/libavcodec/dnxhdenc.c b/ffmpeg/libavcodec/dnxhdenc.c index d438fbb..d7105a1 100644 --- a/ffmpeg/libavcodec/dnxhdenc.c +++ b/ffmpeg/libavcodec/dnxhdenc.c @@ -117,7 +117,7 @@ static int dnxhd_10bit_dct_quantize(MpegEncContext *ctx, int16_t *block, 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; @@ -314,6 +314,7 @@ static av_cold int dnxhd_encode_init(AVCodecContext *avctx) index = ff_dnxhd_get_cid_table(ctx->cid); av_assert0(index >= 0); + ctx->cid_table = &ff_dnxhd_cid_table[index]; ctx->m.avctx = avctx; diff --git a/ffmpeg/libavcodec/dpx.c b/ffmpeg/libavcodec/dpx.c index 5d8c4f3..3b78486 100644 --- a/ffmpeg/libavcodec/dpx.c +++ b/ffmpeg/libavcodec/dpx.c @@ -163,7 +163,7 @@ static int decode_frame(AVCodecContext *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; } } diff --git a/ffmpeg/libavcodec/dsputil.h b/ffmpeg/libavcodec/dsputil.h deleted file mode 100644 index 2f4be85..0000000 --- a/ffmpeg/libavcodec/dsputil.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * DSP utils - * Copyright (c) 2000, 2001, 2002 Fabrice Bellard - * Copyright (c) 2002-2004 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 - * 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 */ diff --git a/ffmpeg/libavcodec/dv.c b/ffmpeg/libavcodec/dv.c index 4b23f2a..2bc7fc5 100644 --- a/ffmpeg/libavcodec/dv.c +++ b/ffmpeg/libavcodec/dv.c @@ -50,7 +50,7 @@ #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) @@ -185,8 +185,6 @@ static const uint8_t dv_quant_areas[4] = { 6, 21, 43, 64 }; 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++) { @@ -204,38 +202,6 @@ int ff_dv_init_dynamic_tables(DVVideoContext *ctx, const AVDVProfile *d) } } - 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; } @@ -277,7 +243,7 @@ av_cold int ff_dvvideo_init(AVCodecContext *avctx) * 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]; diff --git a/ffmpeg/libavcodec/dv.h b/ffmpeg/libavcodec/dv.h index 8a54cfe..5d28263 100644 --- a/ffmpeg/libavcodec/dv.h +++ b/ffmpeg/libavcodec/dv.h @@ -90,11 +90,12 @@ enum dv_pack_type { */ #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) diff --git a/ffmpeg/libavcodec/dv_profile.c b/ffmpeg/libavcodec/dv_profile.c index 084f304..b301cbf 100644 --- a/ffmpeg/libavcodec/dv_profile.c +++ b/ffmpeg/libavcodec/dv_profile.c @@ -257,7 +257,7 @@ void ff_dv_print_profiles(void *logctx, int loglevel) #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 @@ -297,10 +297,18 @@ const AVDVProfile* avpriv_dv_frame_profile2(AVCodecContext* codec, const AVDVPro 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, diff --git a/ffmpeg/libavcodec/dv_profile.h b/ffmpeg/libavcodec/dv_profile.h index a2aec4d..d4437c9 100644 --- a/ffmpeg/libavcodec/dv_profile.h +++ b/ffmpeg/libavcodec/dv_profile.h @@ -58,8 +58,14 @@ typedef struct AVDVProfile { 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. diff --git a/ffmpeg/libavcodec/dv_profile_internal.h b/ffmpeg/libavcodec/dv_profile_internal.h index 9772041..67d3a2b 100644 --- a/ffmpeg/libavcodec/dv_profile_internal.h +++ b/ffmpeg/libavcodec/dv_profile_internal.h @@ -19,9 +19,17 @@ #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 */ diff --git a/ffmpeg/libavcodec/dvbsubdec.c b/ffmpeg/libavcodec/dvbsubdec.c index 097597e..261e161 100644 --- a/ffmpeg/libavcodec/dvbsubdec.c +++ b/ffmpeg/libavcodec/dvbsubdec.c @@ -306,64 +306,58 @@ static void delete_region_display_list(DVBSubContext *ctx, DVBSubRegion *region) 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); } } @@ -468,7 +462,7 @@ static av_cold int dvbsub_close_decoder(AVCodecContext *avctx) display = ctx->display_list; ctx->display_list = display->next; - av_free(display); + av_freep(&display); } return 0; @@ -734,22 +728,16 @@ static int dvbsub_read_8bit_string(uint8_t *destbuf, int dbuf_len, 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++; } @@ -763,7 +751,7 @@ static int dvbsub_read_8bit_string(uint8_t *destbuf, int dbuf_len, 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; @@ -774,6 +762,7 @@ static void save_subtitle_set(AVCodecContext *avctx, AVSubtitle *sub, int *got_o uint32_t *clut_table; int i; int offset_x=0, offset_y=0; + int ret = 0; if (display_def) { @@ -784,7 +773,7 @@ static void save_subtitle_set(AVCodecContext *avctx, AVSubtitle *sub, int *got_o /* 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); @@ -802,6 +791,11 @@ static void save_subtitle_set(AVCodecContext *avctx, AVSubtitle *sub, int *got_o 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; inum_rects; i++) sub->rects[i] = av_mallocz(sizeof(*sub->rects[i])); @@ -844,14 +838,39 @@ static void save_subtitle_set(AVCodecContext *avctx, AVSubtitle *sub, int *got_o } 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; inum_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, @@ -1318,7 +1337,7 @@ static void dvbsub_parse_page_segment(AVCodecContext *avctx, tmp_display_list = display->next; - av_free(display); + av_freep(&display); } } @@ -1412,7 +1431,7 @@ static void save_display_set(DVBSubContext *ctx) png_save2(filename, pbuf, width, height); - av_free(pbuf); + av_freep(&pbuf); } fileno_index++; diff --git a/ffmpeg/libavcodec/dvdata.c b/ffmpeg/libavcodec/dvdata.c index 85cba53..231569a 100644 --- a/ffmpeg/libavcodec/dvdata.c +++ b/ffmpeg/libavcodec/dvdata.c @@ -69,71 +69,6 @@ const uint8_t ff_dv_quant_shifts[22][4] = { 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 diff --git a/ffmpeg/libavcodec/dvdata.h b/ffmpeg/libavcodec/dvdata.h index 0932d3a..e0ed043 100644 --- a/ffmpeg/libavcodec/dvdata.h +++ b/ffmpeg/libavcodec/dvdata.h @@ -26,13 +26,6 @@ extern const uint8_t ff_dv_zigzag248_direct[64]; 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]; diff --git a/ffmpeg/libavcodec/dvdec.c b/ffmpeg/libavcodec/dvdec.c index 7de7e5b..99fe1f4 100644 --- a/ffmpeg/libavcodec/dvdec.c +++ b/ffmpeg/libavcodec/dvdec.c @@ -42,6 +42,7 @@ #include "avcodec.h" #include "dv.h" +#include "dv_profile_internal.h" #include "dvdata.h" #include "get_bits.h" #include "idctdsp.h" @@ -61,6 +62,117 @@ typedef struct BlockInfo { 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; @@ -362,7 +474,7 @@ static int dvvideo_decode_frame(AVCodecContext *avctx, void *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 */ @@ -374,6 +486,7 @@ static int dvvideo_decode_frame(AVCodecContext *avctx, void *data, av_log(avctx, AV_LOG_ERROR, "Error initializing the work tables.\n"); return ret; } + dv_init_weight_tables(s, sys); s->sys = sys; } @@ -381,7 +494,7 @@ static int dvvideo_decode_frame(AVCodecContext *avctx, void *data, s->frame->key_frame = 1; s->frame->pict_type = AV_PICTURE_TYPE_I; avctx->pix_fmt = s->sys->pix_fmt; - avctx->time_base = s->sys->time_base; + avctx->framerate = av_inv_q(s->sys->time_base); ret = ff_set_dimensions(avctx, s->sys->width, s->sys->height); if (ret < 0) @@ -392,7 +505,7 @@ static int dvvideo_decode_frame(AVCodecContext *avctx, void *data, 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]); } diff --git a/ffmpeg/libavcodec/dvdsubdec.c b/ffmpeg/libavcodec/dvdsubdec.c index 7355c03..39604f3 100644 --- a/ffmpeg/libavcodec/dvdsubdec.c +++ b/ffmpeg/libavcodec/dvdsubdec.c @@ -28,17 +28,20 @@ #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 @@ -548,6 +551,9 @@ static int dvdsub_decode(AVCodecContext *avctx, 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]; @@ -579,10 +585,71 @@ static void parse_palette(DVDSubContext *ctx, char *p) } } +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; @@ -603,11 +670,9 @@ static int dvdsub_parse_extradata(AVCodecContext *avctx) } 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; } } @@ -615,8 +680,9 @@ static int dvdsub_parse_extradata(AVCodecContext *avctx) data += strspn(data, "\n\r"); } +fail: av_free(dataorig); - return 1; + return ret; } static av_cold int dvdsub_init(AVCodecContext *avctx) @@ -627,6 +693,8 @@ 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) { @@ -649,9 +717,11 @@ static av_cold int dvdsub_close(AVCodecContext *avctx) } #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 = { diff --git a/ffmpeg/libavcodec/dvenc.c b/ffmpeg/libavcodec/dvenc.c index a3868c4..5d810e3 100644 --- a/ffmpeg/libavcodec/dvenc.c +++ b/ffmpeg/libavcodec/dvenc.c @@ -758,7 +758,7 @@ AVCodec ff_dvvideo_encoder = { .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 diff --git a/ffmpeg/libavcodec/dxtory.c b/ffmpeg/libavcodec/dxtory.c index 1a59ae7..4d8b7b2 100644 --- a/ffmpeg/libavcodec/dxtory.c +++ b/ffmpeg/libavcodec/dxtory.c @@ -82,10 +82,10 @@ static int dxtory_decode_v1_410(AVCodecContext *avctx, AVFrame *pic, 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; @@ -410,7 +410,7 @@ static int dxtory_decode_v2_410(AVCodecContext *avctx, AVFrame *pic, { 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; @@ -424,13 +424,12 @@ static int dxtory_decode_v2_410(AVCodecContext *avctx, AVFrame *pic, 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); @@ -445,9 +444,9 @@ static int dxtory_decode_v2_410(AVCodecContext *avctx, AVFrame *pic, 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, @@ -475,7 +474,6 @@ static int dxtory_decode_v2_410(AVCodecContext *avctx, AVFrame *pic, V += pic->linesize[2] * (slice_height >> 2); off += slice_size; cur_y = next_y; - next_y += ref_slice_height; } return 0; @@ -514,7 +512,7 @@ static int dxtory_decode_v2_420(AVCodecContext *avctx, AVFrame *pic, { 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; @@ -528,13 +526,12 @@ static int dxtory_decode_v2_420(AVCodecContext *avctx, AVFrame *pic, 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); @@ -549,9 +546,9 @@ static int dxtory_decode_v2_420(AVCodecContext *avctx, AVFrame *pic, 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, @@ -579,7 +576,6 @@ static int dxtory_decode_v2_420(AVCodecContext *avctx, AVFrame *pic, V += pic->linesize[2] * (slice_height >> 1); off += slice_size; cur_y = next_y; - next_y += ref_slice_height; } return 0; diff --git a/ffmpeg/libavcodec/eacmv.c b/ffmpeg/libavcodec/eacmv.c index 4a1af8c..d1b7c68 100644 --- a/ffmpeg/libavcodec/eacmv.c +++ b/ffmpeg/libavcodec/eacmv.c @@ -154,7 +154,7 @@ static int cmv_process_header(CmvContext *s, const uint8_t *buf, const uint8_t * 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]); diff --git a/ffmpeg/libavcodec/eamad.c b/ffmpeg/libavcodec/eamad.c index 711363c..813a2d1 100644 --- a/ffmpeg/libavcodec/eamad.c +++ b/ffmpeg/libavcodec/eamad.c @@ -257,7 +257,7 @@ static int decode_frame(AVCodecContext *avctx, 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); @@ -329,7 +329,7 @@ static av_cold int decode_end(AVCodecContext *avctx) { MadContext *t = avctx->priv_data; av_frame_free(&t->last_frame); - av_free(t->bitstream_buf); + av_freep(&t->bitstream_buf); return 0; } diff --git a/ffmpeg/libavcodec/eatgq.c b/ffmpeg/libavcodec/eatgq.c index 34cb642..771dc2f 100644 --- a/ffmpeg/libavcodec/eatgq.c +++ b/ffmpeg/libavcodec/eatgq.c @@ -53,7 +53,7 @@ static av_cold int tgq_decode_init(AVCodecContext *avctx) 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; } diff --git a/ffmpeg/libavcodec/eatgv.c b/ffmpeg/libavcodec/eatgv.c index f204a13..b4d3d1d 100644 --- a/ffmpeg/libavcodec/eatgv.c +++ b/ffmpeg/libavcodec/eatgv.c @@ -55,7 +55,7 @@ static av_cold int tgv_decode_init(AVCodecContext *avctx) { 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(); @@ -349,8 +349,8 @@ static av_cold int tgv_decode_end(AVCodecContext *avctx) 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; } diff --git a/ffmpeg/libavcodec/eatqi.c b/ffmpeg/libavcodec/eatqi.c index 864291a..34fc30d 100644 --- a/ffmpeg/libavcodec/eatqi.c +++ b/ffmpeg/libavcodec/eatqi.c @@ -56,7 +56,7 @@ static av_cold int tqi_decode_init(AVCodecContext *avctx) 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; @@ -149,7 +149,7 @@ static int tqi_decode_frame(AVCodecContext *avctx, 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; } diff --git a/ffmpeg/libavcodec/error_resilience.c b/ffmpeg/libavcodec/error_resilience.c index 2ba4a68..c72c562 100644 --- a/ffmpeg/libavcodec/error_resilience.c +++ b/ffmpeg/libavcodec/error_resilience.c @@ -448,7 +448,7 @@ static void guess_mv(ERContext *s) 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; @@ -858,7 +858,7 @@ void ff_er_add_slice(ERContext *s, int startx, int starty, 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 }; @@ -875,6 +875,7 @@ void ff_er_frame_end(ERContext *s) (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) diff --git a/ffmpeg/libavcodec/escape124.c b/ffmpeg/libavcodec/escape124.c index bed1efb..2816741 100644 --- a/ffmpeg/libavcodec/escape124.c +++ b/ffmpeg/libavcodec/escape124.c @@ -76,7 +76,7 @@ static av_cold int escape124_decode_close(AVCodecContext *avctx) 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); @@ -143,10 +143,11 @@ static MacroBlock decode_macroblock(Escape124Context* s, GetBitContext* gb, // 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; @@ -263,7 +264,7 @@ static int escape124_decode_frame(AVCodecContext *avctx, 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; diff --git a/ffmpeg/libavcodec/exr.c b/ffmpeg/libavcodec/exr.c index 62e8521..b56fe2e 100644 --- a/ffmpeg/libavcodec/exr.c +++ b/ffmpeg/libavcodec/exr.c @@ -382,8 +382,9 @@ static int huf_unpack_enc_table(GetByteContext *gb, int32_t im, int32_t iM, uint64_t *hcode) { GetBitContext gbit; - - init_get_bits8(&gbit, gb->buffer, bytestream2_get_bytes_left(gb)); + 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); diff --git a/ffmpeg/libavcodec/ffv1dec.c b/ffmpeg/libavcodec/ffv1dec.c index c408f16..5fbe51c 100644 --- a/ffmpeg/libavcodec/ffv1dec.c +++ b/ffmpeg/libavcodec/ffv1dec.c @@ -1051,12 +1051,17 @@ static int update_thread_context(AVCodecContext *dst, const AVCodecContext *src) 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; inum_h_slices * fdst->num_v_slices; i++) { FFV1Context *fssrc = fsrc->slice_context[i]; FFV1Context *fsdst = fdst->slice_context[i]; diff --git a/ffmpeg/libavcodec/ffv1enc.c b/ffmpeg/libavcodec/ffv1enc.c index e2d3707..cf2a13d 100644 --- a/ffmpeg/libavcodec/ffv1enc.c +++ b/ffmpeg/libavcodec/ffv1enc.c @@ -166,7 +166,7 @@ static void find_best_state(uint8_t best_state[256][256], 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); diff --git a/ffmpeg/libavcodec/fic.c b/ffmpeg/libavcodec/fic.c index 5615e69..adc8a25 100644 --- a/ffmpeg/libavcodec/fic.c +++ b/ffmpeg/libavcodec/fic.c @@ -308,7 +308,10 @@ static int fic_decode_frame(AVCodecContext *avctx, void *data, 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; @@ -317,14 +320,14 @@ static int fic_decode_frame(AVCodecContext *avctx, void *data, /* 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; diff --git a/ffmpeg/libavcodec/flac.c b/ffmpeg/libavcodec/flac.c index 1053491..5ff004e 100644 --- a/ffmpeg/libavcodec/flac.c +++ b/ffmpeg/libavcodec/flac.c @@ -166,7 +166,7 @@ int ff_flac_get_max_frame_size(int blocksize, int ch, int bps) 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) { @@ -201,7 +201,7 @@ void ff_flac_set_channel_layout(AVCodecContext *avctx) 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; @@ -235,3 +235,18 @@ void avpriv_flac_parse_streaminfo(AVCodecContext *avctx, struct FLACStreaminfo * 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 diff --git a/ffmpeg/libavcodec/flac.h b/ffmpeg/libavcodec/flac.h index d85195f..f1307c7 100644 --- a/ffmpeg/libavcodec/flac.h +++ b/ffmpeg/libavcodec/flac.h @@ -96,8 +96,16 @@ typedef struct FLACFrameInfo { * @param[out] s where parsed information is stored * @param[in] buffer pointer to start of 34-byte streaminfo data */ +void ff_flac_parse_streaminfo(AVCodecContext *avctx, struct FLACStreaminfo *s, + const uint8_t *buffer); + +#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. @@ -106,9 +114,9 @@ void avpriv_flac_parse_streaminfo(AVCodecContext *avctx, struct FLACStreaminfo * * @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. diff --git a/ffmpeg/libavcodec/flac_parser.c b/ffmpeg/libavcodec/flac_parser.c index a031dbf..0e45ab0 100644 --- a/ffmpeg/libavcodec/flac_parser.c +++ b/ffmpeg/libavcodec/flac_parser.c @@ -724,7 +724,7 @@ static void flac_parse_close(AVCodecParserContext *c) curr = temp; } av_fifo_freep(&fpc->fifo_buf); - av_free(fpc->wrap_buf); + av_freep(&fpc->wrap_buf); } AVCodecParser ff_flac_parser = { diff --git a/ffmpeg/libavcodec/flacdec.c b/ffmpeg/libavcodec/flacdec.c index c9dbc14..34a0a70 100644 --- a/ffmpeg/libavcodec/flacdec.c +++ b/ffmpeg/libavcodec/flacdec.c @@ -34,7 +34,6 @@ #include #include "libavutil/avassert.h" -#include "libavutil/channel_layout.h" #include "libavutil/crc.h" #include "avcodec.h" #include "internal.h" @@ -103,16 +102,16 @@ static av_cold int flac_decode_init(AVCodecContext *avctx) 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; @@ -169,12 +168,12 @@ static int parse_streaminfo(FLACContext *s, const uint8_t *buf, int buf_size) 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; @@ -367,7 +366,7 @@ static inline int decode_subframe(FLACContext *s, int channel) 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, @@ -473,10 +472,10 @@ static int decode_frame(FLACContext *s) 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); diff --git a/ffmpeg/libavcodec/flacdsp.c b/ffmpeg/libavcodec/flacdsp.c index b15bc74..a83eb83 100644 --- a/ffmpeg/libavcodec/flacdsp.c +++ b/ffmpeg/libavcodec/flacdsp.c @@ -85,7 +85,7 @@ static void flac_lpc_32_c(int32_t *decoded, const int coeffs[32], } -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) { @@ -127,7 +127,7 @@ av_cold void ff_flacdsp_init(FLACDSPContext *c, enum AVSampleFormat fmt, } 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); } diff --git a/ffmpeg/libavcodec/flacdsp.h b/ffmpeg/libavcodec/flacdsp.h index 14f3466..417381c 100644 --- a/ffmpeg/libavcodec/flacdsp.h +++ b/ffmpeg/libavcodec/flacdsp.h @@ -31,8 +31,8 @@ typedef struct FLACDSPContext { 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 */ diff --git a/ffmpeg/libavcodec/flacenc.c b/ffmpeg/libavcodec/flacenc.c index 3b72888..e66ef3d 100644 --- a/ffmpeg/libavcodec/flacenc.c +++ b/ffmpeg/libavcodec/flacenc.c @@ -428,7 +428,7 @@ static av_cold int flac_encode_init(AVCodecContext *avctx) 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); diff --git a/ffmpeg/libavcodec/flashsv2enc.c b/ffmpeg/libavcodec/flashsv2enc.c index 9735a13..1c016f2 100644 --- a/ffmpeg/libavcodec/flashsv2enc.c +++ b/ffmpeg/libavcodec/flashsv2enc.c @@ -192,7 +192,7 @@ static av_cold int flashsv2_encode_init(AVCodecContext * avctx) 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)) { diff --git a/ffmpeg/libavcodec/flashsvenc.c b/ffmpeg/libavcodec/flashsvenc.c index 7ad15f1..a6d7caa 100644 --- a/ffmpeg/libavcodec/flashsvenc.c +++ b/ffmpeg/libavcodec/flashsvenc.c @@ -94,9 +94,9 @@ static av_cold int flashsv_encode_end(AVCodecContext *avctx) 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); diff --git a/ffmpeg/libavcodec/g2meet.c b/ffmpeg/libavcodec/g2meet.c index d0cb88c..0cd502b 100644 --- a/ffmpeg/libavcodec/g2meet.c +++ b/ffmpeg/libavcodec/g2meet.c @@ -683,12 +683,12 @@ static int g2m_decode_frame(AVCodecContext *avctx, void *data, 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); } diff --git a/ffmpeg/libavcodec/g722enc.c b/ffmpeg/libavcodec/g722enc.c index c4d6c7b..dac7c87 100644 --- a/ffmpeg/libavcodec/g722enc.c +++ b/ffmpeg/libavcodec/g722enc.c @@ -107,7 +107,7 @@ static av_cold int g722_encode_init(AVCodecContext * avctx) a common packet size for VoIP applications */ avctx->frame_size = 320; } - avctx->delay = 22; + avctx->initial_padding = 22; if (avctx->trellis) { /* validate trellis */ @@ -374,7 +374,7 @@ static int g722_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, } 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; } diff --git a/ffmpeg/libavcodec/h261dec.c b/ffmpeg/libavcodec/h261dec.c index ead81fc..9064f1a 100644 --- a/ffmpeg/libavcodec/h261dec.c +++ b/ffmpeg/libavcodec/h261dec.c @@ -492,7 +492,7 @@ static int h261_decode_picture_header(H261Context *h) 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 */ diff --git a/ffmpeg/libavcodec/h263.h b/ffmpeg/libavcodec/h263.h index 54ce2a5..29798ba 100644 --- a/ffmpeg/libavcodec/h263.h +++ b/ffmpeg/libavcodec/h263.h @@ -29,6 +29,7 @@ #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 diff --git a/ffmpeg/libavcodec/h263dec.c b/ffmpeg/libavcodec/h263dec.c index e5870fa..4ef7825 100644 --- a/ffmpeg/libavcodec/h263dec.c +++ b/ffmpeg/libavcodec/h263dec.c @@ -43,6 +43,14 @@ #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; @@ -57,10 +65,6 @@ av_cold int ff_h263_decode_init(AVCodecContext *avctx) 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 */ @@ -120,6 +124,7 @@ av_cold int ff_h263_decode_init(AVCodecContext *avctx) 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; @@ -345,7 +350,8 @@ static int decode_slice(MpegEncContext *s) } 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; @@ -504,9 +510,11 @@ retry: 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); @@ -540,6 +548,12 @@ retry: 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 || diff --git a/ffmpeg/libavcodec/h264.c b/ffmpeg/libavcodec/h264.c index 12713de..222bf58 100644 --- a/ffmpeg/libavcodec/h264.c +++ b/ffmpeg/libavcodec/h264.c @@ -877,7 +877,7 @@ static void decode_postinit(H264Context *h, int setup_finished) 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); } } diff --git a/ffmpeg/libavcodec/h264_cabac.c b/ffmpeg/libavcodec/h264_cabac.c index c2e183d..6455ee7 100644 --- a/ffmpeg/libavcodec/h264_cabac.c +++ b/ffmpeg/libavcodec/h264_cabac.c @@ -27,6 +27,7 @@ #define CABAC(h) 1 #define UNCHECKED_BITSTREAM_READER 1 +#define INT_BIT (CHAR_BIT * sizeof(int)) #include "libavutil/attributes.h" #include "libavutil/avassert.h" diff --git a/ffmpeg/libavcodec/h264_mb.c b/ffmpeg/libavcodec/h264_mb.c index 7feae57..dd406c7 100644 --- a/ffmpeg/libavcodec/h264_mb.c +++ b/ffmpeg/libavcodec/h264_mb.c @@ -49,7 +49,7 @@ static inline int get_lowest_part_list_y(H264Context *h, H264Picture *pic, int n 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) { @@ -96,7 +96,7 @@ static void await_references(H264Context *h) { 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; diff --git a/ffmpeg/libavcodec/h264_mp4toannexb_bsf.c b/ffmpeg/libavcodec/h264_mp4toannexb_bsf.c index 739ff95..ae96ee9 100644 --- a/ffmpeg/libavcodec/h264_mp4toannexb_bsf.c +++ b/ffmpeg/libavcodec/h264_mp4toannexb_bsf.c @@ -26,9 +26,12 @@ #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; @@ -60,7 +63,7 @@ static int alloc_and_copy(uint8_t **poutbuf, int *poutbuf_size, 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; @@ -70,11 +73,14 @@ static int h264_extradata_to_annexb(AVCodecContext *avctx, const int padding) 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; } @@ -103,13 +109,15 @@ static int h264_extradata_to_annexb(AVCodecContext *avctx, const int padding) 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, @@ -151,12 +159,13 @@ static int h264_mp4toannexb_filter(AVBitStreamFilterContext *bsfc, /* 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; } @@ -176,8 +185,25 @@ static int h264_mp4toannexb_filter(AVBitStreamFilterContext *bsfc, 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. @@ -186,22 +212,35 @@ static int h264_mp4toannexb_filter(AVBitStreamFilterContext *bsfc, 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); diff --git a/ffmpeg/libavcodec/h264_parser.c b/ffmpeg/libavcodec/h264_parser.c index 14d709c..6e87efa 100644 --- a/ffmpeg/libavcodec/h264_parser.c +++ b/ffmpeg/libavcodec/h264_parser.c @@ -492,6 +492,8 @@ static int h264_parse(AVCodecParserContext *s, 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; @@ -517,17 +519,22 @@ static int h264_split(AVCodecContext *avctx, 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--; @@ -545,7 +552,7 @@ static void close(AVCodecParserContext *s) H264Context *h = s->priv_data; ParseContext *pc = &h->parse_context; - av_free(pc->buffer); + av_freep(&pc->buffer); ff_h264_free_context(h); } diff --git a/ffmpeg/libavcodec/h264_ps.c b/ffmpeg/libavcodec/h264_ps.c index 2013670..4070490 100644 --- a/ffmpeg/libavcodec/h264_ps.c +++ b/ffmpeg/libavcodec/h264_ps.c @@ -31,32 +31,12 @@ #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) \ @@ -164,8 +144,8 @@ static inline int decode_vui_parameters(H264Context *h, SPS *sps) 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; diff --git a/ffmpeg/libavcodec/h264_sei.c b/ffmpeg/libavcodec/h264_sei.c index aa889b8..8e1697a 100644 --- a/ffmpeg/libavcodec/h264_sei.c +++ b/ffmpeg/libavcodec/h264_sei.c @@ -281,7 +281,7 @@ static int decode_display_orientation(H264Context *h) 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; diff --git a/ffmpeg/libavcodec/h264_slice.c b/ffmpeg/libavcodec/h264_slice.c index c46cc24..53f61ca 100644 --- a/ffmpeg/libavcodec/h264_slice.c +++ b/ffmpeg/libavcodec/h264_slice.c @@ -1181,8 +1181,8 @@ static int h264_slice_header_init(H264Context *h, int reinit) 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) diff --git a/ffmpeg/libavcodec/h264data.h b/ffmpeg/libavcodec/h264data.h index 38f3258..95ea385 100644 --- a/ffmpeg/libavcodec/h264data.h +++ b/ffmpeg/libavcodec/h264data.h @@ -167,4 +167,23 @@ static const PMbInfo b_sub_mb_type_info[13] = { { 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 */ diff --git a/ffmpeg/libavcodec/hevc.c b/ffmpeg/libavcodec/hevc.c index 309b385..d4dc52c 100644 --- a/ffmpeg/libavcodec/hevc.c +++ b/ffmpeg/libavcodec/hevc.c @@ -351,7 +351,7 @@ static int set_sps(HEVCContext *s, const HEVCSPS *sps) } 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; @@ -865,8 +865,7 @@ static int hls_cross_component_pred(HEVCContext *s, int idx) { 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]; @@ -972,8 +971,8 @@ static int hls_transform_unit(HEVCContext *s, int x0, int y0, 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 + @@ -1001,8 +1000,8 @@ static int hls_transform_unit(HEVCContext *s, int x0, int y0, 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 + @@ -1183,7 +1182,7 @@ do { } 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; @@ -1327,7 +1326,6 @@ static void luma_mc_uni(HEVCContext *s, uint8_t *dst, ptrdiff_t dststride, 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; @@ -1381,13 +1379,13 @@ static void luma_mc_uni(HEVCContext *s, uint8_t *dst, ptrdiff_t dststride, 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]], @@ -1482,7 +1480,6 @@ static void chroma_mc_uni(HEVCContext *s, uint8_t *dst0, 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]; @@ -1552,15 +1549,15 @@ static void chroma_mc_bi(HEVCContext *s, uint8_t *dst0, ptrdiff_t dststride, AVF 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], @@ -1573,12 +1570,57 @@ static void chroma_mc_bi(HEVCContext *s, uint8_t *dst0, ptrdiff_t dststride, AVF 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) @@ -1602,95 +1644,33 @@ static void hls_prediction_unit(HEVCContext *s, int x0, int y0, 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]]; @@ -1964,11 +1944,9 @@ static int hls_coding_unit(HEVCContext *s, int x0, int y0, int log2_cb_size) 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++) @@ -2004,6 +1982,8 @@ static int hls_coding_unit(HEVCContext *s, int x0, int y0, int log2_cb_size) 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 || @@ -2017,9 +1997,9 @@ static int hls_coding_unit(HEVCContext *s, int x0, int y0, int log2_cb_size) 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) @@ -2069,12 +2049,14 @@ static int hls_coding_unit(HEVCContext *s, int x0, int y0, int log2_cb_size) } } - 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 : @@ -2105,7 +2087,7 @@ static int hls_coding_unit(HEVCContext *s, int x0, int y0, int log2_cb_size) 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; } @@ -2119,7 +2101,7 @@ static int hls_coding_quadtree(HEVCContext *s, int x0, int y0, 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) { @@ -2532,7 +2514,7 @@ static int set_side_data(HEVCContext *s) 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; diff --git a/ffmpeg/libavcodec/hevc.h b/ffmpeg/libavcodec/hevc.h index 0369d8f..8fdefbb 100644 --- a/ffmpeg/libavcodec/hevc.h +++ b/ffmpeg/libavcodec/hevc.h @@ -631,10 +631,6 @@ typedef struct SliceHeader { int slice_ctb_addr_rs; } SliceHeader; -typedef struct CodingTree { - int depth; ///< ctDepth -} CodingTree; - typedef struct CodingUnit { int x; int y; @@ -642,10 +638,6 @@ typedef struct CodingUnit { 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 @@ -683,7 +675,6 @@ typedef struct PredictionUnit { } 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; @@ -746,7 +737,6 @@ typedef struct HEVCNAL { } 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]; @@ -772,8 +762,9 @@ typedef struct HEVCLocalContext { /* +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; diff --git a/ffmpeg/libavcodec/hevc_cabac.c b/ffmpeg/libavcodec/hevc_cabac.c index 2b3d8c0..3862df7 100644 --- a/ffmpeg/libavcodec/hevc_cabac.c +++ b/ffmpeg/libavcodec/hevc_cabac.c @@ -835,7 +835,7 @@ int ff_hevc_inter_pred_idc_decode(HEVCContext *s, int nPbW, int nPbH) { if (nPbW + nPbH == 12) return GET_CABAC(elem_offset[INTER_PRED_IDC] + 4); - if (GET_CABAC(elem_offset[INTER_PRED_IDC] + s->HEVClc->ct.depth)) + if (GET_CABAC(elem_offset[INTER_PRED_IDC] + s->HEVClc->ct_depth)) return PRED_BI; return GET_CABAC(elem_offset[INTER_PRED_IDC] + 4); @@ -1079,7 +1079,7 @@ void ff_hevc_hls_residual_coding(HEVCContext *s, int x0, int y0, 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; @@ -1552,7 +1552,7 @@ void ff_hevc_hls_residual_coding(HEVCContext *s, int x0, int y0, } } 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); diff --git a/ffmpeg/libavcodec/hevc_mvs.c b/ffmpeg/libavcodec/hevc_mvs.c index 826d084..318e7a2 100644 --- a/ffmpeg/libavcodec/hevc_mvs.c +++ b/ffmpeg/libavcodec/hevc_mvs.c @@ -408,7 +408,7 @@ static void derive_spatial_merge_candidates(HEVCContext *s, int x0, int y0, // 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) ? diff --git a/ffmpeg/libavcodec/hevc_ps.c b/ffmpeg/libavcodec/hevc_ps.c index 4e1c561..6b5e13f 100644 --- a/ffmpeg/libavcodec/hevc_ps.c +++ b/ffmpeg/libavcodec/hevc_ps.c @@ -951,6 +951,11 @@ int ff_hevc_decode_nal_sps(HEVCContext *s) 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); @@ -1025,10 +1030,8 @@ int ff_hevc_decode_nal_sps(HEVCContext *s) } 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; } @@ -1375,7 +1378,8 @@ int ff_hevc_decode_nal_pps(HEVCContext *s) 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; } } diff --git a/ffmpeg/libavcodec/hevcdsp_template.c b/ffmpeg/libavcodec/hevcdsp_template.c index 8a843f5..360a509 100644 --- a/ffmpeg/libavcodec/hevcdsp_template.c +++ b/ffmpeg/libavcodec/hevcdsp_template.c @@ -42,16 +42,16 @@ static void FUNC(put_pcm)(uint8_t *_dst, ptrdiff_t stride, int width, int height } } -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++; } @@ -59,55 +59,28 @@ static void FUNC(transform_add4x4)(uint8_t *_dst, int16_t *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); } diff --git a/ffmpeg/libavcodec/hnm4video.c b/ffmpeg/libavcodec/hnm4video.c index d8c51d0..31995bc 100644 --- a/ffmpeg/libavcodec/hnm4video.c +++ b/ffmpeg/libavcodec/hnm4video.c @@ -22,6 +22,7 @@ #include +#include "libavutil/imgutils.h" #include "libavutil/internal.h" #include "libavutil/intreadwrite.h" #include "libavutil/mem.h" @@ -453,6 +454,7 @@ static int hnm_decode_frame(AVCodecContext *avctx, void *data, 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, @@ -460,6 +462,10 @@ static av_cold int hnm_decode_init(AVCodecContext *avctx) 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; diff --git a/ffmpeg/libavcodec/huffyuvdec.c b/ffmpeg/libavcodec/huffyuvdec.c index 3b2b0f7..98c6128 100644 --- a/ffmpeg/libavcodec/huffyuvdec.c +++ b/ffmpeg/libavcodec/huffyuvdec.c @@ -272,6 +272,20 @@ static int read_old_huffman_tables(HYuvContext *s) 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; @@ -327,7 +341,7 @@ static av_cold int decode_init(AVCodecContext *avctx) 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: @@ -355,7 +369,7 @@ static av_cold int decode_init(AVCodecContext *avctx) s->context = 0; if ((ret = read_old_huffman_tables(s)) < 0) - return ret; + goto error; } if (s->version <= 2) { @@ -383,7 +397,8 @@ static av_cold int decode_init(AVCodecContext *avctx) 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, @@ -520,7 +535,8 @@ static av_cold int decode_init(AVCodecContext *avctx) avctx->pix_fmt = AV_PIX_FMT_YUVA420P16; break; default: - return AVERROR_INVALIDDATA; + ret = AVERROR_INVALIDDATA; + goto error; } } @@ -528,21 +544,26 @@ static av_cold int decode_init(AVCodecContext *avctx) 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) @@ -1181,11 +1202,10 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, 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); } } } @@ -1209,20 +1229,6 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, 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"), diff --git a/ffmpeg/libavcodec/huffyuvdsp.h b/ffmpeg/libavcodec/huffyuvdsp.h index 78b2bca..db37728 100644 --- a/ffmpeg/libavcodec/huffyuvdsp.h +++ b/ffmpeg/libavcodec/huffyuvdsp.h @@ -20,6 +20,7 @@ #define AVCODEC_HUFFYUVDSP_H #include +#include "config.h" #if HAVE_BIGENDIAN #define B 3 diff --git a/ffmpeg/libavcodec/idctdsp.c b/ffmpeg/libavcodec/idctdsp.c index 75695ef..b497221 100644 --- a/ffmpeg/libavcodec/idctdsp.c +++ b/ffmpeg/libavcodec/idctdsp.c @@ -80,11 +80,11 @@ av_cold void ff_init_scantable_permutation(uint8_t *idct_permutation, } } -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; @@ -138,7 +138,7 @@ static void put_pixels_clamped2_c(const int16_t *block, uint8_t *av_restrict pix 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; @@ -158,7 +158,7 @@ static void put_signed_pixels_clamped_c(const int16_t *block, } static void add_pixels_clamped_c(const int16_t *block, uint8_t *av_restrict pixels, - int line_size) + ptrdiff_t line_size) { int i; diff --git a/ffmpeg/libavcodec/idctdsp.h b/ffmpeg/libavcodec/idctdsp.h index 8d60656..538b716 100644 --- a/ffmpeg/libavcodec/idctdsp.h +++ b/ffmpeg/libavcodec/idctdsp.h @@ -52,13 +52,13 @@ typedef struct IDCTDSPContext { /* 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 */); @@ -95,8 +95,8 @@ typedef struct IDCTDSPContext { 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); diff --git a/ffmpeg/libavcodec/iirfilter.c b/ffmpeg/libavcodec/iirfilter.c index a2d9d11..cb5871c 100644 --- a/ffmpeg/libavcodec/iirfilter.c +++ b/ffmpeg/libavcodec/iirfilter.c @@ -196,7 +196,7 @@ av_cold struct FFIIRFilterCoeffs* ff_iir_filter_init_coeffs(void *avc, return c; init_fail: - ff_iir_filter_free_coeffs(c); + ff_iir_filter_free_coeffsp(&c); return NULL; } @@ -299,18 +299,19 @@ void ff_iir_filter_flt(const struct FFIIRFilterCoeffs *c, } } -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) { @@ -347,8 +348,8 @@ int main(void) 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 */ diff --git a/ffmpeg/libavcodec/iirfilter.h b/ffmpeg/libavcodec/iirfilter.h index 4ea6642..6f7bba6 100644 --- a/ffmpeg/libavcodec/iirfilter.h +++ b/ffmpeg/libavcodec/iirfilter.h @@ -104,14 +104,14 @@ struct FFIIRFilterState* ff_iir_filter_init_state(int order); * * @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. diff --git a/ffmpeg/libavcodec/imc.c b/ffmpeg/libavcodec/imc.c index dcedbd6..6c9ffd7 100644 --- a/ffmpeg/libavcodec/imc.c +++ b/ffmpeg/libavcodec/imc.c @@ -96,7 +96,7 @@ typedef struct { GetBitContext gb; BswapDSPContext bdsp; - AVFloatDSPContext fdsp; + AVFloatDSPContext *fdsp; FFTContext fft; DECLARE_ALIGNED(32, FFTComplex, samples)[COEFFS / 2]; float *out_samples; @@ -256,7 +256,13 @@ static av_cold int imc_decode_init(AVCodecContext *avctx) 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; @@ -1044,7 +1050,7 @@ static int imc_decode_frame(AVCodecContext *avctx, void *data, } 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); } @@ -1053,12 +1059,12 @@ static int imc_decode_frame(AVCodecContext *avctx, void *data, 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; } diff --git a/ffmpeg/libavcodec/indeo2.c b/ffmpeg/libavcodec/indeo2.c index cccac44..39735c2 100644 --- a/ffmpeg/libavcodec/indeo2.c +++ b/ffmpeg/libavcodec/indeo2.c @@ -54,15 +54,13 @@ static int ir2_decode_plane(Ir2Context *ctx, int width, int height, uint8_t *dst 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) @@ -79,7 +77,7 @@ static int ir2_decode_plane(Ir2Context *ctx, int width, int height, uint8_t *dst 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) @@ -89,7 +87,7 @@ static int ir2_decode_plane(Ir2Context *ctx, int width, int height, uint8_t *dst 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++; diff --git a/ffmpeg/libavcodec/internal.h b/ffmpeg/libavcodec/internal.h index dcb2113..f4e12e8 100644 --- a/ffmpeg/libavcodec/internal.h +++ b/ffmpeg/libavcodec/internal.h @@ -35,6 +35,8 @@ #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 diff --git a/ffmpeg/libavcodec/ituh263dec.c b/ffmpeg/libavcodec/ituh263dec.c index 70a8ffe..4a07ac2 100644 --- a/ffmpeg/libavcodec/ituh263dec.c +++ b/ffmpeg/libavcodec/ituh263dec.c @@ -82,7 +82,7 @@ void ff_h263_show_pict_info(MpegEncContext *s){ 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 ); } } @@ -948,7 +948,7 @@ int ff_h263_decode_picture_header(MpegEncContext *s) 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; @@ -1047,18 +1047,18 @@ int ff_h263_decode_picture_header(MpegEncContext *s) 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 }; } } diff --git a/ffmpeg/libavcodec/jacosubdec.c b/ffmpeg/libavcodec/jacosubdec.c index b64fac8..2f94956 100644 --- a/ffmpeg/libavcodec/jacosubdec.c +++ b/ffmpeg/libavcodec/jacosubdec.c @@ -29,6 +29,7 @@ #include "jacosub.h" #include "libavutil/avstring.h" #include "libavutil/bprint.h" +#include "libavutil/time_internal.h" #undef time @@ -44,11 +45,7 @@ static int insert_datetime(AVBPrint *dst, const char *in, const char *arg) 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; @@ -162,12 +159,12 @@ static void jacosub_to_ass(AVCodecContext *avctx, AVBPrint *dst, const char *src 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; @@ -176,7 +173,6 @@ static int jacosub_decode_frame(AVCodecContext *avctx, if (*ptr) { AVBPrint buffer; - char *dec_sub; // skip timers ptr = jss_skip_whitespace(ptr); @@ -185,9 +181,10 @@ static int jacosub_decode_frame(AVCodecContext *avctx, 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: diff --git a/ffmpeg/libavcodec/jpeg2000.c b/ffmpeg/libavcodec/jpeg2000.c index ede1a79..644e25d 100644 --- a/ffmpeg/libavcodec/jpeg2000.c +++ b/ffmpeg/libavcodec/jpeg2000.c @@ -369,16 +369,18 @@ int ff_jpeg2000_init_component(Jpeg2000Component *comp, 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 */ @@ -425,12 +427,15 @@ int ff_jpeg2000_init_component(Jpeg2000Component *comp, 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; diff --git a/ffmpeg/libavcodec/jpeg2000dec.c b/ffmpeg/libavcodec/jpeg2000dec.c index d6204bb..17ee541 100644 --- a/ffmpeg/libavcodec/jpeg2000dec.c +++ b/ffmpeg/libavcodec/jpeg2000dec.c @@ -37,6 +37,7 @@ #include "internal.h" #include "thread.h" #include "jpeg2000.h" +#include "jpeg2000dsp.h" #define JP2_SIG_TYPE 0x6A502020 #define JP2_SIG_VALUE 0x0D0A870A @@ -93,6 +94,7 @@ typedef struct Jpeg2000DecoderContext { int curtileno; Jpeg2000Tile *tile; + Jpeg2000DSPContext dsp; /*options parameters*/ int reduction_factor; @@ -1141,26 +1143,10 @@ static void dequantization_int(int x, int y, Jpeg2000Cblk *cblk, } } -/* 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) { @@ -1170,47 +1156,14 @@ static void mct_decode(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile) 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, @@ -1621,6 +1574,15 @@ static int jp2_find_codestream(Jpeg2000DecoderContext *s) 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) { @@ -1731,6 +1693,7 @@ AVCodec ff_jpeg2000_decoder = { .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, diff --git a/ffmpeg/libavcodec/jpeg2000dsp.c b/ffmpeg/libavcodec/jpeg2000dsp.c new file mode 100644 index 0000000..a7c7f53 --- /dev/null +++ b/ffmpeg/libavcodec/jpeg2000dsp.c @@ -0,0 +1,98 @@ +/* + * JPEG 2000 DSP functions + * Copyright (c) 2007 Kamil Nowosad + * Copyright (c) 2013 Nicolas Bertrand + * + * 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; +} diff --git a/ffmpeg/libavutil/intfloat_readwrite.h b/ffmpeg/libavcodec/jpeg2000dsp.h similarity index 50% rename from ffmpeg/libavutil/intfloat_readwrite.h rename to ffmpeg/libavcodec/jpeg2000dsp.h index 1d79e3e..de1ddb9 100644 --- a/ffmpeg/libavutil/intfloat_readwrite.h +++ b/ffmpeg/libavcodec/jpeg2000dsp.h @@ -1,5 +1,7 @@ /* - * copyright (c) 2005 Michael Niedermayer + * JPEG 2000 DSP functions + * Copyright (c) 2007 Kamil Nowosad + * Copyright (c) 2013 Nicolas Bertrand * * This file is part of FFmpeg. * @@ -18,27 +20,16 @@ * 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 +#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 */ diff --git a/ffmpeg/libavcodec/jpeg2000dwt.h b/ffmpeg/libavcodec/jpeg2000dwt.h index b5be812..b6d296d 100644 --- a/ffmpeg/libavcodec/jpeg2000dwt.h +++ b/ffmpeg/libavcodec/jpeg2000dwt.h @@ -34,7 +34,8 @@ enum DWTType { FF_DWT97, FF_DWT53, - FF_DWT97_INT + FF_DWT97_INT, + FF_DWT_NB }; typedef struct DWTContext { diff --git a/ffmpeg/libavcodec/lagarith.c b/ffmpeg/libavcodec/lagarith.c index a08d7fd..2c6d70c 100644 --- a/ffmpeg/libavcodec/lagarith.c +++ b/ffmpeg/libavcodec/lagarith.c @@ -128,7 +128,7 @@ static int lag_decode_prob(GetBitContext *gb, uint32_t *value) } val = get_bits_long(gb, bits); - val |= 1 << bits; + val |= 1U << bits; *value = val - 1; @@ -675,10 +675,10 @@ static int lag_decode_frame(AVCodecContext *avctx, 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; @@ -702,11 +702,11 @@ static int lag_decode_frame(AVCodecContext *avctx, 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: diff --git a/ffmpeg/libavcodec/lcldec.c b/ffmpeg/libavcodec/lcldec.c index ca62b42..1d94041 100644 --- a/ffmpeg/libavcodec/lcldec.c +++ b/ffmpeg/libavcodec/lcldec.c @@ -180,6 +180,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac 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; @@ -191,7 +192,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac 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) { @@ -411,10 +412,11 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac } 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: diff --git a/ffmpeg/libavcodec/libfaac.c b/ffmpeg/libavcodec/libfaac.c index 477669a..69c186b 100644 --- a/ffmpeg/libavcodec/libfaac.c +++ b/ffmpeg/libavcodec/libfaac.c @@ -167,7 +167,7 @@ static av_cold int Faac_encode_init(AVCodecContext *avctx) } } - avctx->delay = FAAC_DELAY_SAMPLES; + avctx->initial_padding = FAAC_DELAY_SAMPLES; ff_af_queue_init(avctx, &s->afq); return 0; diff --git a/ffmpeg/libavcodec/libfdk-aacdec.c b/ffmpeg/libavcodec/libfdk-aacdec.c index 624d579..90cd956 100644 --- a/ffmpeg/libavcodec/libfdk-aacdec.c +++ b/ffmpeg/libavcodec/libfdk-aacdec.c @@ -25,6 +25,12 @@ #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, @@ -36,9 +42,20 @@ typedef struct FDKAACDecContext { 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[] = { @@ -46,6 +63,14 @@ 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 } }; @@ -57,7 +82,7 @@ static int get_stream_info(AVCodecContext *avctx) { 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; @@ -75,7 +100,7 @@ static int get_stream_info(AVCodecContext *avctx) 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; } @@ -170,6 +195,8 @@ static av_cold int fdk_aac_decode_close(AVCodecContext *avctx) if (s->handle) aacDecoder_Close(s->handle); + av_freep(&s->decoder_buffer); + av_freep(&s->anc_buffer); return 0; } @@ -178,6 +205,7 @@ static av_cold int fdk_aac_decode_init(AVCodecContext *avctx) { 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) { @@ -199,9 +227,77 @@ static av_cold int fdk_aac_decode_init(AVCodecContext *avctx) 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, @@ -225,14 +321,24 @@ 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); @@ -258,16 +364,20 @@ 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) 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; } diff --git a/ffmpeg/libavcodec/libfdk-aacenc.c b/ffmpeg/libavcodec/libfdk-aacenc.c index b9c9a13..3eadb36 100644 --- a/ffmpeg/libavcodec/libfdk-aacenc.c +++ b/ffmpeg/libavcodec/libfdk-aacenc.c @@ -286,7 +286,7 @@ static av_cold int aac_encode_init(AVCodecContext *avctx) } 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) { diff --git a/ffmpeg/libavcodec/libmp3lame.c b/ffmpeg/libavcodec/libmp3lame.c index 1ac79a2..e33919b 100644 --- a/ffmpeg/libavcodec/libmp3lame.c +++ b/ffmpeg/libavcodec/libmp3lame.c @@ -52,7 +52,7 @@ typedef struct LAMEContext { int abr; float *samples_flt[2]; AudioFrameQueue afq; - AVFloatDSPContext fdsp; + AVFloatDSPContext *fdsp; } LAMEContext; @@ -79,6 +79,7 @@ static av_cold int mp3lame_encode_close(AVCodecContext *avctx) 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); @@ -106,9 +107,7 @@ static av_cold int mp3lame_encode_init(AVCodecContext *avctx) 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 */ @@ -138,7 +137,7 @@ static av_cold int mp3lame_encode_init(AVCodecContext *avctx) } /* 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); @@ -160,7 +159,12 @@ static av_cold int mp3lame_encode_init(AVCodecContext *avctx) 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: @@ -199,7 +203,7 @@ static int mp3lame_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, 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)); diff --git a/ffmpeg/libavcodec/libopencore-amr.c b/ffmpeg/libavcodec/libopencore-amr.c index 827bded..b2ad839 100644 --- a/ffmpeg/libavcodec/libopencore-amr.c +++ b/ffmpeg/libavcodec/libopencore-amr.c @@ -199,7 +199,7 @@ static av_cold int amr_nb_encode_init(AVCodecContext *avctx) } 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); @@ -246,7 +246,7 @@ static int amr_nb_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, 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) { diff --git a/ffmpeg/libavcodec/libopusenc.c b/ffmpeg/libavcodec/libopusenc.c index 75e82da..6bb4862 100644 --- a/ffmpeg/libavcodec/libopusenc.c +++ b/ffmpeg/libavcodec/libopusenc.c @@ -87,7 +87,7 @@ static void libopus_write_header(AVCodecContext *avctx, int stream_count, 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. */ @@ -170,10 +170,11 @@ static av_cold int libopus_encode_init(AVCodecContext *avctx) /* 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 + @@ -284,7 +285,7 @@ static av_cold int libopus_encode_init(AVCodecContext *avctx) 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", @@ -316,7 +317,9 @@ static int libopus_encode(AVCodecContext *avctx, AVPacket *avpkt, 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); diff --git a/ffmpeg/libavcodec/libschroedingerdec.c b/ffmpeg/libavcodec/libschroedingerdec.c index f20633a..dca3379 100644 --- a/ffmpeg/libavcodec/libschroedingerdec.c +++ b/ffmpeg/libavcodec/libschroedingerdec.c @@ -195,8 +195,8 @@ static void libschroedinger_handle_first_access_unit(AVCodecContext *avctx) 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, diff --git a/ffmpeg/libavcodec/libspeexdec.c b/ffmpeg/libavcodec/libspeexdec.c index 5e149a5..a5f52d1 100644 --- a/ffmpeg/libavcodec/libspeexdec.c +++ b/ffmpeg/libavcodec/libspeexdec.c @@ -33,6 +33,7 @@ typedef struct { SpeexStereoState stereo; void *dec_state; int frame_size; + int pktsize; } LibSpeexContext; @@ -50,14 +51,20 @@ static av_cold int libspeex_decode_init(AVCodecContext *avctx) 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; @@ -143,9 +150,11 @@ static int libspeex_decode_frame(AVCodecContext *avctx, void *data, *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 */ diff --git a/ffmpeg/libavcodec/libspeexenc.c b/ffmpeg/libavcodec/libspeexenc.c index aba4618..21238aa 100644 --- a/ffmpeg/libavcodec/libspeexenc.c +++ b/ffmpeg/libavcodec/libspeexenc.c @@ -236,7 +236,7 @@ static av_cold int encode_init(AVCodecContext *avctx) 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 */ diff --git a/ffmpeg/libavcodec/libtwolame.c b/ffmpeg/libavcodec/libtwolame.c index e26454b..dc18857 100644 --- a/ffmpeg/libavcodec/libtwolame.c +++ b/ffmpeg/libavcodec/libtwolame.c @@ -60,7 +60,7 @@ static av_cold int twolame_encode_init(AVCodecContext *avctx) 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) @@ -152,10 +152,10 @@ static int twolame_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, 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; } diff --git a/ffmpeg/libavcodec/libutvideodec.cpp b/ffmpeg/libavcodec/libutvideodec.cpp index 60dbd15..e4b87a8 100644 --- a/ffmpeg/libavcodec/libutvideodec.cpp +++ b/ffmpeg/libavcodec/libutvideodec.cpp @@ -39,8 +39,8 @@ static av_cold int utvideo_decode_init(AVCodecContext *avctx) 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; } @@ -80,6 +80,12 @@ static av_cold int utvideo_decode_init(AVCodecContext *avctx) 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); @@ -88,6 +94,10 @@ static av_cold int utvideo_decode_init(AVCodecContext *avctx) /* 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) { @@ -155,6 +165,56 @@ static int utvideo_decode_frame(AVCodecContext *avctx, void *data, 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 */ diff --git a/ffmpeg/libavcodec/libvo-aacenc.c b/ffmpeg/libavcodec/libvo-aacenc.c index 04f9902..7b38d51 100644 --- a/ffmpeg/libavcodec/libvo-aacenc.c +++ b/ffmpeg/libavcodec/libvo-aacenc.c @@ -61,7 +61,7 @@ static av_cold int aac_encode_init(AVCodecContext *avctx) 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); diff --git a/ffmpeg/libavcodec/libvo-amrwbenc.c b/ffmpeg/libavcodec/libvo-amrwbenc.c index f14d61f..fe19e71 100644 --- a/ffmpeg/libavcodec/libvo-amrwbenc.c +++ b/ffmpeg/libavcodec/libvo-amrwbenc.c @@ -93,7 +93,7 @@ static av_cold int amr_wb_encode_init(AVCodecContext *avctx) s->last_bitrate = avctx->bit_rate; avctx->frame_size = 320; - avctx->delay = 80; + avctx->initial_padding = 80; s->state = E_IF_init(); @@ -129,7 +129,7 @@ static int amr_wb_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, } 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; diff --git a/ffmpeg/libavcodec/libvorbisdec.c b/ffmpeg/libavcodec/libvorbisdec.c index b703b65..db00572 100644 --- a/ffmpeg/libavcodec/libvorbisdec.c +++ b/ffmpeg/libavcodec/libvorbisdec.c @@ -35,17 +35,17 @@ typedef struct OggVorbisDecContext { 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); @@ -65,7 +65,8 @@ static int oggvorbis_decode_init(AVCodecContext *avccontext) { 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++; @@ -83,7 +84,8 @@ static int oggvorbis_decode_init(AVCodecContext *avccontext) { } 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++){ @@ -92,7 +94,8 @@ static int oggvorbis_decode_init(AVCodecContext *avccontext) { 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; } } @@ -105,6 +108,11 @@ static int oggvorbis_decode_init(AVCodecContext *avccontext) { vorbis_block_init(&context->vd, &context->vb); return 0 ; + + error: + vorbis_info_clear(&context->vi); + vorbis_comment_clear(&context->vc) ; + return ret; } diff --git a/ffmpeg/libavcodec/libvorbisenc.c b/ffmpeg/libavcodec/libvorbisenc.c index ed6baa9..231d1be 100644 --- a/ffmpeg/libavcodec/libvorbisenc.c +++ b/ffmpeg/libavcodec/libvorbisenc.c @@ -49,7 +49,7 @@ typedef struct LibvorbisEncContext { 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; @@ -187,6 +187,8 @@ static av_cold int libvorbis_encode_close(AVCodecContext *avctx) ff_af_queue_close(&s->afq); av_freep(&avctx->extradata); + av_vorbis_parse_free(&s->vp); + return 0; } @@ -246,7 +248,8 @@ static av_cold int libvorbis_encode_init(AVCodecContext *avctx) 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; } @@ -341,12 +344,12 @@ static int libvorbis_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, 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) @@ -369,7 +372,7 @@ AVCodec ff_libvorbis_encoder = { .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, diff --git a/ffmpeg/libavcodec/libvpxdec.c b/ffmpeg/libavcodec/libvpxdec.c index 94e1e4d..7faef3a 100644 --- a/ffmpeg/libavcodec/libvpxdec.c +++ b/ffmpeg/libavcodec/libvpxdec.c @@ -56,10 +56,62 @@ static av_cold int vpx_init(AVCodecContext *avctx, 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) { @@ -82,10 +134,15 @@ static int vp8_decode(AVCodecContext *avctx, } 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) { diff --git a/ffmpeg/libavcodec/libvpxenc.c b/ffmpeg/libavcodec/libvpxenc.c index 163d12a..c69acc0 100644 --- a/ffmpeg/libavcodec/libvpxenc.c +++ b/ffmpeg/libavcodec/libvpxenc.c @@ -89,6 +89,7 @@ typedef struct VP8EncoderContext { int lag_in_frames; int error_resilient; int crf; + int static_thresh; int max_intra_rate; // VP9-only @@ -443,7 +444,16 @@ static av_cold int vpx_init(AVCodecContext *avctx, 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) @@ -634,7 +644,7 @@ static int queue_frames(AVCodecContext *avctx, AVPacket *pkt_out, 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); @@ -753,8 +763,8 @@ static int vp8_encode(AVCodecContext *avctx, AVPacket *pkt, } 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; @@ -793,6 +803,7 @@ static int vp8_encode(AVCodecContext *avctx, AVPacket *pkt, "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}, \ diff --git a/ffmpeg/libavcodec/libwebpenc.c b/ffmpeg/libavcodec/libwebpenc.c index 4cb8dc3..95d56ac 100644 --- a/ffmpeg/libavcodec/libwebpenc.c +++ b/ffmpeg/libavcodec/libwebpenc.c @@ -41,6 +41,9 @@ typedef struct LibWebPContext { 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) @@ -62,10 +65,9 @@ static av_cold int libwebp_encode_init(AVCodecContext *avctx) 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", @@ -144,8 +146,8 @@ static int libwebp_encode_frame(AVCodecContext *avctx, AVPacket *pkt, 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; @@ -158,22 +160,80 @@ static int libwebp_encode_frame(AVCodecContext *avctx, AVPacket *pkt, 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; } @@ -243,6 +303,15 @@ end: 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[] = { @@ -255,9 +324,13 @@ 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, @@ -279,6 +352,7 @@ AVCodec ff_libwebp_encoder = { .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, diff --git a/ffmpeg/libavcodec/libx264.c b/ffmpeg/libavcodec/libx264.c index 8830f59..4da0ee0 100644 --- a/ffmpeg/libavcodec/libx264.c +++ b/ffmpeg/libavcodec/libx264.c @@ -80,6 +80,7 @@ typedef struct X264Context { int slice_max_size; char *stats; int nal_hrd; + int avcintra_class; char *x264_params; } X264Context; @@ -100,7 +101,7 @@ static void X264_log(void *p, int level, const char *fmt, va_list args) 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; @@ -183,6 +184,8 @@ static int X264_frame(AVCodecContext *ctx, AVPacket *pkt, const AVFrame *frame, 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); @@ -226,6 +229,7 @@ static int X264_frame(AVCodecContext *ctx, AVPacket *pkt, const AVFrame *frame, 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) { @@ -301,7 +305,7 @@ static av_cold int X264_close(AVCodecContext *avctx) 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); @@ -528,6 +532,13 @@ static av_cold int X264_init(AVCodecContext *avctx) 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) @@ -805,6 +816,7 @@ static const AVOption options[] = { { "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 }, }; diff --git a/ffmpeg/libavcodec/libx265.c b/ffmpeg/libavcodec/libx265.c index 55019d4..923c750 100644 --- a/ffmpeg/libavcodec/libx265.c +++ b/ffmpeg/libavcodec/libx265.c @@ -111,6 +111,7 @@ static av_cold int libx265_encode_init(AVCodecContext *avctx) 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, diff --git a/ffmpeg/libavcodec/libxavs.c b/ffmpeg/libavcodec/libxavs.c index 92dcece..ed86b61 100644 --- a/ffmpeg/libavcodec/libxavs.c +++ b/ffmpeg/libavcodec/libxavs.c @@ -201,7 +201,7 @@ static av_cold int XAVS_close(AVCodecContext *avctx) 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) diff --git a/ffmpeg/libavcodec/libxvid.c b/ffmpeg/libavcodec/libxvid.c index aee9dac..046d2f7 100644 --- a/ffmpeg/libavcodec/libxvid.c +++ b/ffmpeg/libavcodec/libxvid.c @@ -359,7 +359,7 @@ static void xvid_correct_framerate(AVCodecContext *avctx) 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; @@ -488,6 +488,7 @@ static av_cold int xvid_encode_init(AVCodecContext *avctx) 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] = @@ -501,8 +502,9 @@ static av_cold int xvid_encode_init(AVCodecContext *avctx) 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; @@ -510,14 +512,19 @@ static av_cold int xvid_encode_init(AVCodecContext *avctx) 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; @@ -659,13 +666,15 @@ static av_cold int xvid_encode_init(AVCodecContext *avctx) 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, @@ -812,6 +821,7 @@ static av_cold int xvid_encode_close(AVCodecContext *avctx) av_freep(&x->twopassfile); av_freep(&x->intra_matrix); av_freep(&x->inter_matrix); + av_frame_free(&avctx->coded_frame); return 0; } diff --git a/ffmpeg/libavcodec/libxvid_rc.c b/ffmpeg/libavcodec/libxvid_rc.c index 4ee4d82..f92bef1 100644 --- a/ffmpeg/libavcodec/libxvid_rc.c +++ b/ffmpeg/libavcodec/libxvid_rc.c @@ -68,10 +68,11 @@ av_cold int ff_xvid_rate_control_init(MpegEncContext *s) (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; } } diff --git a/ffmpeg/libavcodec/libzvbi-teletextdec.c b/ffmpeg/libavcodec/libzvbi-teletextdec.c index e65e3fb..15c1a5d 100644 --- a/ffmpeg/libavcodec/libzvbi-teletextdec.c +++ b/ffmpeg/libavcodec/libzvbi-teletextdec.c @@ -101,6 +101,7 @@ static int create_ass_text(TeletextContext *ctx, const char *text, char **ass) /* 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); diff --git a/ffmpeg/libavcodec/lossless_audiodsp.h b/ffmpeg/libavcodec/lossless_audiodsp.h index 4c27502..c3ee2be 100644 --- a/ffmpeg/libavcodec/lossless_audiodsp.h +++ b/ffmpeg/libavcodec/lossless_audiodsp.h @@ -29,7 +29,7 @@ typedef struct LLAudDSPContext { /** * 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, diff --git a/ffmpeg/libavcodec/lpc.c b/ffmpeg/libavcodec/lpc.c index 1d52edf..deb02e7 100644 --- a/ffmpeg/libavcodec/lpc.c +++ b/ffmpeg/libavcodec/lpc.c @@ -175,7 +175,7 @@ int ff_lpc_calc_coefs(LPCContext *s, 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; @@ -208,7 +208,7 @@ int ff_lpc_calc_coefs(LPCContext *s, } 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)); diff --git a/ffmpeg/libavcodec/lpc.h b/ffmpeg/libavcodec/lpc.h index c323230..96acb37 100644 --- a/ffmpeg/libavcodec/lpc.h +++ b/ffmpeg/libavcodec/lpc.h @@ -24,6 +24,7 @@ #include #include "libavutil/avassert.h" +#include "libavutil/lls.h" #define ORDER_METHOD_EST 0 #define ORDER_METHOD_2LEVEL 1 @@ -79,6 +80,9 @@ typedef struct LPCContext { */ 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; @@ -153,7 +157,7 @@ static inline int compute_lpc_coefs(const LPC_TYPE *autoc, int max_order, int normalize) { int i, j; - LPC_TYPE err; + LPC_TYPE err = 0; LPC_TYPE *lpc_last = lpc; av_assert2(normalize || !fail); diff --git a/ffmpeg/libavcodec/me_cmp.c b/ffmpeg/libavcodec/me_cmp.c index 1355a23..cfd14ab 100644 --- a/ffmpeg/libavcodec/me_cmp.c +++ b/ffmpeg/libavcodec/me_cmp.c @@ -32,7 +32,7 @@ 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; @@ -42,14 +42,14 @@ static int sse4_c(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, 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; @@ -63,14 +63,14 @@ static int sse8_c(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, 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; @@ -93,8 +93,8 @@ static int sse16_c(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, s += sq[pix1[14] - pix2[14]]; s += sq[pix1[15] - pix2[15]]; - pix1 += line_size; - pix2 += line_size; + pix1 += stride; + pix2 += stride; } return s; } @@ -112,7 +112,7 @@ static int sum_abs_dctelem_c(int16_t *block) #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; @@ -133,14 +133,14 @@ static inline int pix_abs16_c(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, 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; @@ -161,17 +161,17 @@ static int pix_abs16_x2_c(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, 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])); @@ -190,18 +190,18 @@ static int pix_abs16_y2_c(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, 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])); @@ -220,15 +220,15 @@ static int pix_abs16_xy2_c(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, 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; @@ -241,14 +241,14 @@ static inline int pix_abs8_c(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, 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; @@ -261,17 +261,17 @@ static int pix_abs8_x2_c(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, 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])); @@ -282,18 +282,18 @@ static int pix_abs8_y2_c(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, 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])); @@ -304,14 +304,15 @@ static int pix_abs8_xy2_c(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, 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; @@ -335,7 +336,8 @@ static int nsse16_c(MpegEncContext *c, uint8_t *s1, uint8_t *s2, int stride, int 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; @@ -360,7 +362,7 @@ static int nsse8_c(MpegEncContext *c, uint8_t *s1, uint8_t *s2, int stride, int } static int zero_cmp(MpegEncContext *s, uint8_t *a, uint8_t *b, - int stride, int h) + ptrdiff_t stride, int h) { return 0; } @@ -443,7 +445,7 @@ void ff_set_cmp(MECmpContext *c, me_cmp_func *cmp, int type) #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; @@ -495,7 +497,7 @@ static int hadamard8_diff8x8_c(MpegEncContext *s, uint8_t *dst, } 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; @@ -547,7 +549,7 @@ static int hadamard8_intra8x8_c(MpegEncContext *s, uint8_t *src, } 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]); @@ -588,7 +590,7 @@ static int dct_sad8x8_c(MpegEncContext *s, uint8_t *src1, } 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; @@ -613,7 +615,7 @@ static int dct264_sad8x8_c(MpegEncContext *s, uint8_t *src1, #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; @@ -630,7 +632,7 @@ static int dct_max8x8_c(MpegEncContext *s, uint8_t *src1, } 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; @@ -655,7 +657,7 @@ static int quant_psnr8x8_c(MpegEncContext *s, uint8_t *src1, } 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]); @@ -732,7 +734,7 @@ static int rd8x8_c(MpegEncContext *s, uint8_t *src1, uint8_t *src2, } 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]); @@ -795,7 +797,7 @@ static int bit8x8_c(MpegEncContext *s, uint8_t *src1, uint8_t *src2, #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; \ \ @@ -817,7 +819,7 @@ VSAD_INTRA(16) #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; \ \ @@ -837,7 +839,7 @@ VSAD(16) #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; \ \ @@ -858,7 +860,7 @@ VSSE_INTRA(16) #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; \ \ @@ -876,7 +878,7 @@ VSSE(16) #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; \ \ diff --git a/ffmpeg/libavcodec/me_cmp.h b/ffmpeg/libavcodec/me_cmp.h index 0e3b922..98ee53c 100644 --- a/ffmpeg/libavcodec/me_cmp.h +++ b/ffmpeg/libavcodec/me_cmp.h @@ -47,7 +47,8 @@ struct MpegEncContext; * 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 */); diff --git a/ffmpeg/libavcodec/microdvddec.c b/ffmpeg/libavcodec/microdvddec.c index f3c640f..96034a0 100644 --- a/ffmpeg/libavcodec/microdvddec.c +++ b/ffmpeg/libavcodec/microdvddec.c @@ -66,8 +66,24 @@ static void microdvd_set_tag(struct microdvd_tag *tags, struct microdvd_tag tag) // 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); @@ -101,7 +117,7 @@ static char *microdvd_load_tags(struct microdvd_tag *tags, char *s) case 'C': tag.persistent = MICRODVD_PERSISTENT_ON; case 'c': - if (*s == '$') + while (*s == '$' || *s == '#') s++; tag.data1 = strtol(s, &s, 16) & 0x00ffffff; if (*s != '}') @@ -178,7 +194,7 @@ static char *microdvd_load_tags(struct microdvd_tag *tags, char *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) @@ -260,8 +276,6 @@ static int microdvd_decode_frame(AVCodecContext *avctx, { 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}}; @@ -269,15 +283,6 @@ static int microdvd_decode_frame(AVCodecContext *avctx, 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 @@ -301,18 +306,17 @@ static int microdvd_decode_frame(AVCodecContext *avctx, } } 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; diff --git a/ffmpeg/libavcodec/mips/aacdec_mips.c b/ffmpeg/libavcodec/mips/aacdec_mips.c index e403366..5db10f9 100644 --- a/ffmpeg/libavcodec/mips/aacdec_mips.c +++ b/ffmpeg/libavcodec/mips/aacdec_mips.c @@ -90,7 +90,7 @@ static void imdct_and_windowing_mips(AACContext *ac, SingleChannelElement *sce) */ 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; @@ -199,7 +199,7 @@ static void imdct_and_windowing_mips(AACContext *ac, SingleChannelElement *sce) } } } 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; @@ -248,9 +248,9 @@ static void imdct_and_windowing_mips(AACContext *ac, SingleChannelElement *sce) // 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; @@ -561,7 +561,7 @@ static void update_ltp_mips(AACContext *ac, SingleChannelElement *sce) : "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 ( @@ -646,7 +646,7 @@ static void update_ltp_mips(AACContext *ac, SingleChannelElement *sce) : [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 ( @@ -683,7 +683,7 @@ static void update_ltp_mips(AACContext *ac, SingleChannelElement *sce) } } 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]; diff --git a/ffmpeg/libavcodec/mjpegdec.c b/ffmpeg/libavcodec/mjpegdec.c index 8966672..a29a533 100644 --- a/ffmpeg/libavcodec/mjpegdec.c +++ b/ffmpeg/libavcodec/mjpegdec.c @@ -244,7 +244,8 @@ int ff_mjpeg_decode_dht(MJpegDecodeContext *s) 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]; @@ -256,6 +257,11 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s) 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) @@ -378,7 +384,7 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s) 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]; @@ -435,16 +441,15 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s) 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; @@ -461,7 +466,6 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s) 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: @@ -470,7 +474,6 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s) 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: @@ -488,18 +491,34 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s) 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: @@ -510,12 +529,18 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s) 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: @@ -526,7 +551,7 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s) 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; } @@ -1293,6 +1318,8 @@ static int mjpeg_decode_scan_progressive_ac(MJpegDecodeContext *s, int ss, } 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]; } @@ -1594,6 +1621,8 @@ static int mjpeg_decode_app(MJpegDecodeContext *s) } 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"); @@ -1603,17 +1632,27 @@ static int mjpeg_decode_app(MJpegDecodeContext *s) 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) { @@ -2089,18 +2128,26 @@ the_end: 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<>= hshift; + if (p==1 || p==2) { + w = FF_CEIL_RSHIFT(w, hshift); + h = FF_CEIL_RSHIFT(h, vshift); + } + if (s->upscale_v & (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--) { @@ -2119,21 +2166,32 @@ the_end: 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<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++) diff --git a/ffmpeg/libavcodec/mjpegdec.h b/ffmpeg/libavcodec/mjpegdec.h index 53a412c..deacabe 100644 --- a/ffmpeg/libavcodec/mjpegdec.h +++ b/ffmpeg/libavcodec/mjpegdec.h @@ -63,7 +63,6 @@ typedef struct MJpegDecodeContext { int progressive; int rgb; int upscale_h; - int chroma_height; int upscale_v; int rct; /* standard rct */ int pegasus_rct; /* pegasus reversible colorspace transform */ diff --git a/ffmpeg/libavcodec/mjpegenc.c b/ffmpeg/libavcodec/mjpegenc.c index 72c56d2..14701e2 100644 --- a/ffmpeg/libavcodec/mjpegenc.c +++ b/ffmpeg/libavcodec/mjpegenc.c @@ -78,7 +78,7 @@ av_cold int ff_mjpeg_encode_init(MpegEncContext *s) 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) @@ -215,6 +215,8 @@ static int amv_encode_picture(AVCodecContext *avctx, AVPacket *pkt, } #if CONFIG_MJPEG_ENCODER +FF_MPV_GENERIC_CLASS(mjpeg) + AVCodec ff_mjpeg_encoder = { .name = "mjpeg", .long_name = NULL_IF_CONFIG_SMALL("MJPEG (Motion JPEG)"), @@ -228,9 +230,12 @@ AVCodec ff_mjpeg_encoder = { .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"), @@ -243,5 +248,6 @@ AVCodec ff_amv_encoder = { .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_NONE }, + .priv_class = &amv_class, }; #endif diff --git a/ffmpeg/libavcodec/mlp.h b/ffmpeg/libavcodec/mlp.h index bb9ca26..05d8dba 100644 --- a/ffmpeg/libavcodec/mlp.h +++ b/ffmpeg/libavcodec/mlp.h @@ -45,7 +45,7 @@ /** 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 diff --git a/ffmpeg/libavcodec/mlp_parser.c b/ffmpeg/libavcodec/mlp_parser.c index 4bb82ee..deaa844 100644 --- a/ffmpeg/libavcodec/mlp_parser.c +++ b/ffmpeg/libavcodec/mlp_parser.c @@ -119,6 +119,23 @@ uint64_t ff_truehd_layout(int chanmap) 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. @@ -127,18 +144,19 @@ uint64_t ff_truehd_layout(int chanmap) 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; } @@ -147,6 +165,7 @@ int ff_mlp_read_major_sync(void *log, MLPHeaderInfo *mh, GetBitContext *gb) 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)]; @@ -199,7 +218,7 @@ int ff_mlp_read_major_sync(void *log, MLPHeaderInfo *mh, GetBitContext *gb) 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; } diff --git a/ffmpeg/libavcodec/mlp_parser.h b/ffmpeg/libavcodec/mlp_parser.h index 5d1d2e7..0c0109e 100644 --- a/ffmpeg/libavcodec/mlp_parser.h +++ b/ffmpeg/libavcodec/mlp_parser.h @@ -32,6 +32,7 @@ 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) diff --git a/ffmpeg/libavcodec/mlpdec.c b/ffmpeg/libavcodec/mlpdec.c index ed6a7fb..490d107 100644 --- a/ffmpeg/libavcodec/mlpdec.c +++ b/ffmpeg/libavcodec/mlpdec.c @@ -105,7 +105,7 @@ typedef struct SubStream { /// 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]; //@} @@ -132,6 +132,9 @@ typedef struct MLPDecodeContext { /// 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; @@ -156,7 +159,7 @@ typedef struct MLPDecodeContext { 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; @@ -349,11 +352,15 @@ static int read_major_sync(MLPDecodeContext *m, GetBitContext *gb) 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; @@ -576,7 +583,7 @@ FF_ENABLE_DEPRECATION_WARNINGS 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); @@ -1031,15 +1038,27 @@ static void fill_noise_buffer(MLPDecodeContext *m, unsigned int substr) 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) { @@ -1049,6 +1068,8 @@ static void rematrix_channels(MLPDecodeContext *m, unsigned int substr) 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], @@ -1063,27 +1084,6 @@ static void rematrix_channels(MLPDecodeContext *m, unsigned int substr) 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; @@ -1142,7 +1142,7 @@ static int read_access_unit(AVCodecContext *avctx, void* data, 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) { @@ -1291,8 +1291,6 @@ next_substr: 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; diff --git a/ffmpeg/libavcodec/mmvideo.c b/ffmpeg/libavcodec/mmvideo.c index 9ff6393..9a7c10c 100644 --- a/ffmpeg/libavcodec/mmvideo.c +++ b/ffmpeg/libavcodec/mmvideo.c @@ -49,7 +49,7 @@ typedef struct MmContext { AVCodecContext *avctx; AVFrame *frame; - int palette[AVPALETTE_COUNT]; + unsigned int palette[AVPALETTE_COUNT]; GetByteContext gb; } MmContext; diff --git a/ffmpeg/libavcodec/motion_est.c b/ffmpeg/libavcodec/motion_est.c index 81ee2bd..901fafd 100644 --- a/ffmpeg/libavcodec/motion_est.c +++ b/ffmpeg/libavcodec/motion_est.c @@ -193,7 +193,13 @@ static av_always_inline int cmp_inline(MpegEncContext *s, const int x, const int 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; @@ -290,7 +296,7 @@ static int cmp_qpel(MpegEncContext *s, const int x, const int y, const int subx, #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; } @@ -971,27 +977,7 @@ void ff_estimate_p_frame_motion(MpegEncContext * s, 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); diff --git a/ffmpeg/libavcodec/movtextdec.c b/ffmpeg/libavcodec/movtextdec.c index 05ff53a..1c7ffea 100644 --- a/ffmpeg/libavcodec/movtextdec.c +++ b/ffmpeg/libavcodec/movtextdec.c @@ -42,7 +42,6 @@ static int text_to_ass(AVBPrint *buf, const char *text, const char *text_end) text++; } - av_bprintf(buf, "\r\n"); return 0; } @@ -60,7 +59,7 @@ static int mov_text_decode_frame(AVCodecContext *avctx, 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; @@ -96,13 +95,11 @@ static int mov_text_decode_frame(AVCodecContext *avctx, // 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; } diff --git a/ffmpeg/libavcodec/mpeg12dec.c b/ffmpeg/libavcodec/mpeg12dec.c index 95cc1a8..78888c7 100644 --- a/ffmpeg/libavcodec/mpeg12dec.c +++ b/ffmpeg/libavcodec/mpeg12dec.c @@ -733,6 +733,7 @@ static int mpeg_decode_mb(MpegEncContext *s, int16_t block[12][64]) { 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); @@ -753,7 +754,7 @@ static int mpeg_decode_mb(MpegEncContext *s, int16_t block[12][64]) 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; @@ -773,7 +774,7 @@ static int mpeg_decode_mb(MpegEncContext *s, int16_t block[12][64]) 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 { @@ -785,7 +786,7 @@ static int mpeg_decode_mb(MpegEncContext *s, int16_t block[12][64]) 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; @@ -794,7 +795,7 @@ static int mpeg_decode_mb(MpegEncContext *s, int16_t block[12][64]) 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; @@ -846,13 +847,13 @@ static int mpeg_decode_mb(MpegEncContext *s, int16_t block[12][64]) 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) { @@ -982,7 +983,7 @@ static int mpeg_decode_mb(MpegEncContext *s, int16_t block[12][64]) 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++) { @@ -1036,7 +1037,7 @@ static int mpeg_decode_mb(MpegEncContext *s, int16_t block[12][64]) 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; } } @@ -1053,7 +1054,7 @@ static int mpeg_decode_mb(MpegEncContext *s, int16_t block[12][64]) 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 @@ -1074,8 +1075,8 @@ static int mpeg_decode_mb(MpegEncContext *s, int16_t block[12][64]) 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; } @@ -1094,8 +1095,8 @@ static int mpeg_decode_mb(MpegEncContext *s, int16_t block[12][64]) } 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; } @@ -1120,6 +1121,10 @@ static av_cold int mpeg_decode_init(AVCodecContext *avctx) 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; @@ -1308,16 +1313,15 @@ static int mpeg_decode_postinit(AVCodecContext *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; @@ -1394,7 +1398,7 @@ static int mpeg1_decode_picture(AVCodecContext *avctx, const uint8_t *buf, 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; @@ -1403,7 +1407,7 @@ static int mpeg1_decode_picture(AVCodecContext *avctx, const uint8_t *buf, 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; @@ -1412,7 +1416,7 @@ static int mpeg1_decode_picture(AVCodecContext *avctx, const uint8_t *buf, 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; @@ -1534,7 +1538,7 @@ static int load_matrix(MpegEncContext *s, uint16_t matrix0[64], 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); @@ -1624,13 +1628,14 @@ static int mpeg_field_start(MpegEncContext *s, const uint8_t *buf, int buf_size) { 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); @@ -1709,8 +1714,8 @@ static int mpeg_field_start(MpegEncContext *s, const uint8_t *buf, int buf_size) } 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; @@ -1731,6 +1736,7 @@ static int mpeg_decode_slice(MpegEncContext *s, int mb_y, 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; @@ -1748,7 +1754,7 @@ static int mpeg_decode_slice(MpegEncContext *s, int mb_y, if (s->qscale == 0) { av_log(s->avctx, AV_LOG_ERROR, "qscale == 0\n"); - return -1; + return AVERROR_INVALIDDATA; } /* extra slice info */ @@ -1765,7 +1771,7 @@ static int mpeg_decode_slice(MpegEncContext *s, int mb_y, 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) @@ -1780,7 +1786,7 @@ static int mpeg_decode_slice(MpegEncContext *s, int mb_y, 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) { @@ -1827,8 +1833,8 @@ static int mpeg_decode_slice(MpegEncContext *s, int mb_y, 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) { @@ -1933,7 +1939,7 @@ static int mpeg_decode_slice(MpegEncContext *s, int mb_y, 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) { @@ -1956,7 +1962,7 @@ static int mpeg_decode_slice(MpegEncContext *s, int mb_y, 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 */ @@ -2115,14 +2121,18 @@ static int mpeg1_decode_sequence(AVCodecContext *avctx, 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; @@ -2153,7 +2163,7 @@ static int mpeg1_decode_sequence(AVCodecContext *avctx, 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. */ @@ -2171,8 +2181,8 @@ static int mpeg1_decode_sequence(AVCodecContext *avctx, 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; } @@ -2182,6 +2192,7 @@ static int vcr2_init_sequence(AVCodecContext *avctx) 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; @@ -2198,8 +2209,8 @@ static int vcr2_init_sequence(AVCodecContext *avctx) 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++) { @@ -2605,7 +2616,7 @@ static int decode_chunks(AVCodecContext *avctx, AVFrame *picture, 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) { @@ -2656,8 +2667,8 @@ static int decode_chunks(AVCodecContext *avctx, AVFrame *picture, 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, diff --git a/ffmpeg/libavcodec/mpeg12enc.c b/ffmpeg/libavcodec/mpeg12enc.c index 827812e..9795b7f 100644 --- a/ffmpeg/libavcodec/mpeg12enc.c +++ b/ffmpeg/libavcodec/mpeg12enc.c @@ -606,7 +606,8 @@ static void mpeg1_encode_motion(MpegEncContext *s, int val, int f_or_b_code) 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) { diff --git a/ffmpeg/libavcodec/mpeg4video_parser.c b/ffmpeg/libavcodec/mpeg4video_parser.c index b7718f6..aa5e87a 100644 --- a/ffmpeg/libavcodec/mpeg4video_parser.c +++ b/ffmpeg/libavcodec/mpeg4video_parser.c @@ -88,7 +88,7 @@ static int mpeg4_decode_header(AVCodecParserContext *s1, AVCodecContext *avctx, 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"); } diff --git a/ffmpeg/libavcodec/mpeg4videodec.c b/ffmpeg/libavcodec/mpeg4videodec.c index bc9264f..1daecfa 100644 --- a/ffmpeg/libavcodec/mpeg4videodec.c +++ b/ffmpeg/libavcodec/mpeg4videodec.c @@ -1760,23 +1760,24 @@ static int decode_vol_header(Mpeg4DecContext *ctx, GetBitContext *gb) 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; @@ -1828,7 +1829,7 @@ static int decode_vol_header(Mpeg4DecContext *ctx, GetBitContext *gb) "%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); @@ -2036,7 +2037,7 @@ no_cplx_est: 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, @@ -2264,8 +2265,9 @@ static int decode_vop_header(Mpeg4DecContext *ctx, GetBitContext *gb) 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<time_increment_bits) { - s->avctx->time_base.den = 1<time_increment_bits; + if (s->avctx->framerate.num && 4*s->avctx->framerate.num < 1<time_increment_bits) { + s->avctx->framerate.num = 1<time_increment_bits; + s->avctx->time_base = av_inv_q(av_mul_q(s->avctx->framerate, (AVRational){s->avctx->ticks_per_frame, 1})); } } @@ -2277,19 +2279,19 @@ static int decode_vop_header(Mpeg4DecContext *ctx, GetBitContext *gb) 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 || @@ -2315,8 +2317,8 @@ static int decode_vop_header(Mpeg4DecContext *ctx, GetBitContext *gb) } } - 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) @@ -2372,7 +2374,7 @@ static int decode_vop_header(Mpeg4DecContext *ctx, GetBitContext *gb) 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) { @@ -2411,7 +2413,7 @@ static int decode_vop_header(Mpeg4DecContext *ctx, GetBitContext *gb) 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) { @@ -2420,7 +2422,7 @@ static int decode_vop_header(Mpeg4DecContext *ctx, GetBitContext *gb) 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; @@ -2431,7 +2433,7 @@ static int decode_vop_header(Mpeg4DecContext *ctx, GetBitContext *gb) 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; @@ -2500,6 +2502,7 @@ int ff_mpeg4_decode_picture_header(Mpeg4DecContext *ctx, GetBitContext *gb) { MpegEncContext *s = &ctx->m; unsigned startcode, v; + int ret; /* search next start code */ align_get_bits(gb); @@ -2588,8 +2591,8 @@ int ff_mpeg4_decode_picture_header(Mpeg4DecContext *ctx, GetBitContext *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) { diff --git a/ffmpeg/libavcodec/mpegaudio_parser.c b/ffmpeg/libavcodec/mpegaudio_parser.c index 3d9e946..79dbf63 100644 --- a/ffmpeg/libavcodec/mpegaudio_parser.c +++ b/ffmpeg/libavcodec/mpegaudio_parser.c @@ -73,20 +73,21 @@ static int mpegaudio_parse(AVCodecParserContext *s1, 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; diff --git a/ffmpeg/libavcodec/mpegaudiodec_float.c b/ffmpeg/libavcodec/mpegaudiodec_float.c index 35f07fa..f432c83 100644 --- a/ffmpeg/libavcodec/mpegaudiodec_float.c +++ b/ffmpeg/libavcodec/mpegaudiodec_float.c @@ -46,6 +46,7 @@ AVCodec ff_mp1float_decoder = { .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, @@ -63,6 +64,7 @@ AVCodec ff_mp2float_decoder = { .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, @@ -78,6 +80,7 @@ AVCodec ff_mp3float_decoder = { .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, @@ -94,6 +97,7 @@ AVCodec ff_mp3adufloat_decoder = { .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, diff --git a/ffmpeg/libavcodec/mpegaudiodec_template.c b/ffmpeg/libavcodec/mpegaudiodec_template.c index c4c03d9..bbd07c5 100644 --- a/ffmpeg/libavcodec/mpegaudiodec_template.c +++ b/ffmpeg/libavcodec/mpegaudiodec_template.c @@ -85,7 +85,7 @@ typedef struct MPADecodeContext { int err_recognition; AVCodecContext* avctx; MPADSPContext mpadsp; - AVFloatDSPContext fdsp; + AVFloatDSPContext *fdsp; AVFrame *frame; } MPADecodeContext; @@ -406,6 +406,16 @@ static av_cold void decode_init_static(void) } } +#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; @@ -418,7 +428,10 @@ static av_cold int decode_init(AVCodecContext * avctx) 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 && @@ -1138,7 +1151,7 @@ found2: /* 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; @@ -1819,7 +1832,7 @@ static av_cold int decode_close_mp3on4(AVCodecContext * avctx) int i; for (i = 0; i < s->frames; i++) - av_free(s->mp3decctx[i]); + av_freep(&s->mp3decctx[i]); return 0; } diff --git a/ffmpeg/libavcodec/mpegaudioenc_template.c b/ffmpeg/libavcodec/mpegaudioenc_template.c index e9571d8..1bf9471 100644 --- a/ffmpeg/libavcodec/mpegaudioenc_template.c +++ b/ffmpeg/libavcodec/mpegaudioenc_template.c @@ -89,7 +89,7 @@ static av_cold int MPA_encode_init(AVCodecContext *avctx) 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; @@ -771,7 +771,7 @@ static int MPA_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, 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; diff --git a/ffmpeg/libavcodec/mpegvideo.c b/ffmpeg/libavcodec/mpegvideo.c index f043bbd..f84557b 100644 --- a/ffmpeg/libavcodec/mpegvideo.c +++ b/ffmpeg/libavcodec/mpegvideo.c @@ -956,6 +956,7 @@ int ff_mpeg_update_thread_context(AVCodecContext *dst, // 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; @@ -966,10 +967,10 @@ int ff_mpeg_update_thread_context(AVCodecContext *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; } } } diff --git a/ffmpeg/libavcodec/mpegvideo.h b/ffmpeg/libavcodec/mpegvideo.h index 87fe87f..cadf6f2 100644 --- a/ffmpeg/libavcodec/mpegvideo.h +++ b/ffmpeg/libavcodec/mpegvideo.h @@ -28,6 +28,8 @@ #ifndef AVCODEC_MPEGVIDEO_H #define AVCODEC_MPEGVIDEO_H +#include + #include "avcodec.h" #include "blockdsp.h" #include "error_resilience.h" @@ -650,6 +652,20 @@ typedef struct MpegEncContext { 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; @@ -678,7 +694,9 @@ typedef struct MpegEncContext { #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" },\ @@ -694,7 +712,21 @@ typedef struct MpegEncContext { 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[]; @@ -842,7 +874,7 @@ extern const uint8_t * const ff_mpeg2_dc_scale_table[4]; 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); diff --git a/ffmpeg/libavcodec/mpegvideo_enc.c b/ffmpeg/libavcodec/mpegvideo_enc.c index 40f8277..27153cf 100644 --- a/ffmpeg/libavcodec/mpegvideo_enc.c +++ b/ffmpeg/libavcodec/mpegvideo_enc.c @@ -96,41 +96,40 @@ void ff_convert_matrix(MpegEncContext *s, int (*qmat)[64], 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) @@ -374,12 +373,19 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx) /* 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; @@ -640,13 +646,6 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx) 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"); @@ -950,6 +949,32 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx) 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(); @@ -1090,13 +1115,10 @@ static int load_input_picture(MpegEncContext *s, const AVFrame *pic_arg) } 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; @@ -1108,27 +1130,20 @@ static int load_input_picture(MpegEncContext *s, const AVFrame *pic_arg) 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; } @@ -1701,7 +1716,11 @@ int ff_mpv_encode_picture(AVCodecContext *avctx, AVPacket *pkt, /* 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, @@ -1726,7 +1745,13 @@ int ff_mpv_encode_picture(AVCodecContext *avctx, AVPacket *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; @@ -1746,10 +1771,10 @@ vbv_retry: 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) { @@ -1776,6 +1801,7 @@ vbv_retry: 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; } @@ -2769,6 +2795,29 @@ static int encode_thread(AVCodecContext *c, void *arg){ 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; diff --git a/ffmpeg/libavcodec/mpegvideo_parser.c b/ffmpeg/libavcodec/mpegvideo_parser.c index 44bf26d..0159421 100644 --- a/ffmpeg/libavcodec/mpegvideo_parser.c +++ b/ffmpeg/libavcodec/mpegvideo_parser.c @@ -70,10 +70,10 @@ static void mpegvideo_extract_headers(AVCodecParserContext *s, did_set_size=1; } frame_rate_index = buf[3] & 0xf; - pc->frame_rate.den = avctx->time_base.den = ff_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: @@ -95,9 +95,10 @@ static void mpegvideo_extract_headers(AVCodecParserContext *s, 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 */ @@ -150,6 +151,10 @@ static void mpegvideo_extract_headers(AVCodecParserContext *s, ((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, @@ -178,7 +183,7 @@ 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; diff --git a/ffmpeg/libavcodec/mpl2dec.c b/ffmpeg/libavcodec/mpl2dec.c index a777c7c..ca95dc8 100644 --- a/ffmpeg/libavcodec/mpl2dec.c +++ b/ffmpeg/libavcodec/mpl2dec.c @@ -59,13 +59,13 @@ static int mpl2_event_to_ass(AVBPrint *buf, const char *p) } } - 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; @@ -74,15 +74,12 @@ static int mpl2_decode_frame(AVCodecContext *avctx, void *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; } diff --git a/ffmpeg/libavcodec/mss1.c b/ffmpeg/libavcodec/mss1.c index 6bb524b..2eb67df 100644 --- a/ffmpeg/libavcodec/mss1.c +++ b/ffmpeg/libavcodec/mss1.c @@ -197,6 +197,8 @@ static av_cold int mss1_decode_init(AVCodecContext *avctx) 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; diff --git a/ffmpeg/libavcodec/nellymoserdec.c b/ffmpeg/libavcodec/nellymoserdec.c index ef16fd6..2d8a594 100644 --- a/ffmpeg/libavcodec/nellymoserdec.c +++ b/ffmpeg/libavcodec/nellymoserdec.c @@ -51,7 +51,7 @@ typedef struct NellyMoserDecodeContext { 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; @@ -106,7 +106,7 @@ static void nelly_decode_block(NellyMoserDecodeContext *s, (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); @@ -122,7 +122,9 @@ static av_cold int decode_init(AVCodecContext * avctx) { 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; @@ -190,6 +192,7 @@ static av_cold int decode_end(AVCodecContext * avctx) { NellyMoserDecodeContext *s = avctx->priv_data; ff_mdct_end(&s->imdct_ctx); + av_freep(&s->fdsp); return 0; } diff --git a/ffmpeg/libavcodec/nellymoserenc.c b/ffmpeg/libavcodec/nellymoserenc.c index 98e33f0..48caba2 100644 --- a/ffmpeg/libavcodec/nellymoserenc.c +++ b/ffmpeg/libavcodec/nellymoserenc.c @@ -56,7 +56,7 @@ 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]; @@ -66,7 +66,7 @@ typedef struct NellyMoserEncodeContext { 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, @@ -122,12 +122,12 @@ static void apply_mdct(NellyMoserEncodeContext *s) 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); } @@ -138,10 +138,11 @@ static av_cold int encode_end(AVCodecContext *avctx) 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; } @@ -165,17 +166,21 @@ static av_cold int encode_init(AVCodecContext *avctx) } 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 )); diff --git a/ffmpeg/libavcodec/on2avc.c b/ffmpeg/libavcodec/on2avc.c index e5e7cc3..01977e5 100644 --- a/ffmpeg/libavcodec/on2avc.c +++ b/ffmpeg/libavcodec/on2avc.c @@ -47,7 +47,7 @@ enum WindowTypes { 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); @@ -714,7 +714,7 @@ static int on2avc_reconstruct_stereo(On2AVCContext *c, AVFrame *dst, int offset) } 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)); @@ -750,20 +750,20 @@ static int on2avc_reconstruct_channel(On2AVCContext *c, int channel, 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)); } } @@ -772,9 +772,9 @@ static int on2avc_reconstruct_channel(On2AVCContext *c, int channel, 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: @@ -952,13 +952,14 @@ static av_cold int on2avc_decode_init(AVCodecContext *avctx) 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; @@ -966,9 +967,7 @@ static av_cold int on2avc_decode_init(AVCodecContext *avctx) 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++) { @@ -977,13 +976,16 @@ static av_cold int on2avc_decode_init(AVCodecContext *avctx) 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) @@ -998,6 +1000,8 @@ 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; diff --git a/ffmpeg/libavcodec/options.c b/ffmpeg/libavcodec/options.c index ec9830f..7f9fb07 100644 --- a/ffmpeg/libavcodec/options.c +++ b/ffmpeg/libavcodec/options.c @@ -27,6 +27,7 @@ #include "avcodec.h" #include "internal.h" #include "libavutil/avassert.h" +#include "libavutil/internal.h" #include "libavutil/mem.h" #include "libavutil/opt.h" #include /* FLT_MIN, FLT_MAX */ @@ -94,8 +95,10 @@ int avcodec_get_context_defaults3(AVCodecContext *s, const AVCodec *codec) 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; @@ -106,6 +109,8 @@ int avcodec_get_context_defaults3(AVCodecContext *s, const AVCodec *codec) 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; @@ -113,7 +118,6 @@ int avcodec_get_context_defaults3(AVCodecContext *s, const AVCodec *codec) 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){ @@ -166,6 +170,9 @@ void avcodec_free_context(AVCodecContext **pavctx) 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); } @@ -185,6 +192,7 @@ int avcodec_copy_context(AVCodecContext *dest, const AVCodecContext *src) av_opt_free(dest); memcpy(dest, src, sizeof(*dest)); + av_opt_copy(dest, src); dest->priv_data = orig_priv_data; @@ -199,17 +207,11 @@ int avcodec_copy_context(AVCodecContext *dest, const AVCodecContext *src) 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) { \ @@ -236,7 +238,11 @@ fail: 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); } diff --git a/ffmpeg/libavcodec/options_table.h b/ffmpeg/libavcodec/options_table.h index ad3d52e..1d5b078 100644 --- a/ffmpeg/libavcodec/options_table.h +++ b/ffmpeg/libavcodec/options_table.h @@ -89,6 +89,7 @@ static const AVOption avcodec_options[] = { {"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" }, @@ -105,8 +106,8 @@ static const AVOption avcodec_options[] = { {"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}, @@ -173,23 +174,27 @@ static const AVOption avcodec_options[] = { {"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"}, @@ -319,8 +324,10 @@ static const AVOption avcodec_options[] = { {"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"}, @@ -329,8 +336,10 @@ static const AVOption avcodec_options[] = { #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}, @@ -359,7 +368,9 @@ static const AVOption avcodec_options[] = { {"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}, @@ -387,7 +398,7 @@ static const AVOption avcodec_options[] = { {"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 @@ -406,26 +417,26 @@ static const AVOption avcodec_options[] = { {"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"}, @@ -436,7 +447,14 @@ static const AVOption avcodec_options[] = { {"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"}, @@ -468,6 +486,10 @@ static const AVOption avcodec_options[] = { {"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}, }; diff --git a/ffmpeg/libavcodec/opus.c b/ffmpeg/libavcodec/opus.c index e76c510..6b3d3c3 100644 --- a/ffmpeg/libavcodec/opus.c +++ b/ffmpeg/libavcodec/opus.c @@ -290,10 +290,6 @@ av_cold int ff_opus_parse_extradata(AVCodecContext *avctx, 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; @@ -308,9 +304,8 @@ av_cold int ff_opus_parse_extradata(AVCodecContext *avctx, "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; @@ -330,7 +325,7 @@ av_cold int ff_opus_parse_extradata(AVCodecContext *avctx, 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; diff --git a/ffmpeg/libavcodec/opus.h b/ffmpeg/libavcodec/opus.h index 543d90c..1faa7d3 100644 --- a/ffmpeg/libavcodec/opus.h +++ b/ffmpeg/libavcodec/opus.h @@ -61,6 +61,15 @@ #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, @@ -167,7 +176,7 @@ typedef struct OpusContext { int nb_streams; int nb_stereo_streams; - AVFloatDSPContext fdsp; + AVFloatDSPContext *fdsp; int16_t gain_i; float gain; diff --git a/ffmpeg/libavcodec/opus_celt.c b/ffmpeg/libavcodec/opus_celt.c index e8a8de7..4f3212b 100644 --- a/ffmpeg/libavcodec/opus_celt.c +++ b/ffmpeg/libavcodec/opus_celt.c @@ -62,7 +62,7 @@ struct CeltContext { // 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 @@ -2072,7 +2072,7 @@ int ff_celt_decode_frame(CeltContext *s, OpusRangeCoder *rc, /* 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)); @@ -2098,7 +2098,7 @@ int ff_celt_decode_frame(CeltContext *s, OpusRangeCoder *rc, 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); } @@ -2181,6 +2181,7 @@ void ff_celt_free(CeltContext **ps) for (i = 0; i < FF_ARRAY_ELEMS(s->imdct); i++) ff_celt_imdct_uninit(&s->imdct[i]); + av_freep(&s->dsp); av_freep(ps); } @@ -2208,7 +2209,11 @@ int ff_celt_init(AVCodecContext *avctx, CeltContext **ps, int output_channels) 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); diff --git a/ffmpeg/libavcodec/opus_parser.c b/ffmpeg/libavcodec/opus_parser.c index 7eb72f9..b128a40 100644 --- a/ffmpeg/libavcodec/opus_parser.c +++ b/ffmpeg/libavcodec/opus_parser.c @@ -27,49 +27,162 @@ #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 }; diff --git a/ffmpeg/libavcodec/opusdec.c b/ffmpeg/libavcodec/opusdec.c index b28edfb..759eaa5 100644 --- a/ffmpeg/libavcodec/opusdec.c +++ b/ffmpeg/libavcodec/opusdec.c @@ -499,6 +499,12 @@ static int opus_decode_packet(AVCodecContext *avctx, void *data, 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); } @@ -529,7 +535,7 @@ static int opus_decode_packet(AVCodecContext *avctx, void *data, } 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)); } @@ -583,6 +589,7 @@ static av_cold int opus_decode_close(AVCodecContext *avctx) c->nb_streams = 0; av_freep(&c->channel_maps); + av_freep(&c->fdsp); return 0; } @@ -595,7 +602,9 @@ static av_cold int opus_decode_init(AVCodecContext *avctx) 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); @@ -624,7 +633,7 @@ static av_cold int opus_decode_init(AVCodecContext *avctx) s->redundancy_output[j] = s->redundancy_buf[j]; } - s->fdsp = &c->fdsp; + s->fdsp = c->fdsp; s->swr =swr_alloc(); if (!s->swr) diff --git a/ffmpeg/libavcodec/parser.c b/ffmpeg/libavcodec/parser.c index 55c2f52..d1e1574 100644 --- a/ffmpeg/libavcodec/parser.c +++ b/ffmpeg/libavcodec/parser.c @@ -212,7 +212,7 @@ void av_parser_close(AVCodecParserContext *s) 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); } } diff --git a/ffmpeg/libavcodec/pcm-dvd.c b/ffmpeg/libavcodec/pcm-dvd.c index 9b4c40e..e4184a5 100644 --- a/ffmpeg/libavcodec/pcm-dvd.c +++ b/ffmpeg/libavcodec/pcm-dvd.c @@ -158,21 +158,21 @@ static void *pcm_dvd_decode_samples(AVCodecContext *avctx, const uint8_t *src, 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 { diff --git a/ffmpeg/libavcodec/pngdec.c b/ffmpeg/libavcodec/pngdec.c index 835d962..7e7b285 100644 --- a/ffmpeg/libavcodec/pngdec.c +++ b/ffmpeg/libavcodec/pngdec.c @@ -26,6 +26,7 @@ #include "avcodec.h" #include "bytestream.h" #include "internal.h" +#include "apng.h" #include "png.h" #include "pngdsp.h" #include "thread.h" @@ -37,11 +38,15 @@ typedef struct PNGDecContext { 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; @@ -51,6 +56,7 @@ typedef struct PNGDecContext { int bits_per_pixel; int bpp; + int frame_id; uint8_t *image_buf; int image_linesize; uint32_t palette[256]; @@ -267,8 +273,10 @@ static void png_filter_row(PNGDSPContext *dsp, uint8_t *dst, int filter_type, /* 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; @@ -298,14 +306,14 @@ static void png_handle_row(PNGDecContext *s) 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) { @@ -317,7 +325,7 @@ static void png_handle_row(PNGDecContext *s) } } 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) { @@ -332,7 +340,7 @@ static void png_handle_row(PNGDecContext *s) } 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 */ @@ -345,11 +353,11 @@ static void png_handle_row(PNGDecContext *s) 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) { @@ -360,7 +368,7 @@ static void png_handle_row(PNGDecContext *s) 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; @@ -519,266 +527,209 @@ static int decode_text_chunk(PNGDecContext *s, uint32_t length, int compressed, 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++) { @@ -798,13 +749,12 @@ exit_loop: } 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; @@ -827,18 +777,17 @@ exit_loop: } 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--) { @@ -849,32 +798,339 @@ exit_loop: 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; @@ -886,24 +1142,89 @@ the_end: 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; } @@ -913,10 +1234,15 @@ static av_cold int png_dec_init(AVCodecContext *avctx) 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; @@ -930,6 +1256,8 @@ static av_cold int png_dec_end(AVCodecContext *avctx) { 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); @@ -944,6 +1272,23 @@ static av_cold int png_dec_end(AVCodecContext *avctx) 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"), @@ -952,8 +1297,9 @@ AVCodec ff_png_decoder = { .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 diff --git a/ffmpeg/libavcodec/pngdsp.h b/ffmpeg/libavcodec/pngdsp.h index 1475b0c..fbc1a50 100644 --- a/ffmpeg/libavcodec/pngdsp.h +++ b/ffmpeg/libavcodec/pngdsp.h @@ -25,9 +25,9 @@ #include 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, diff --git a/ffmpeg/libavcodec/ppc/h264chroma_template.c b/ffmpeg/libavcodec/ppc/h264chroma_template.c index 7436e11..cb1e095 100644 --- a/ffmpeg/libavcodec/ppc/h264chroma_template.c +++ b/ffmpeg/libavcodec/ppc/h264chroma_template.c @@ -19,12 +19,14 @@ */ #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);\ @@ -49,8 +51,8 @@ #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);\ @@ -70,6 +72,43 @@ #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) { @@ -80,23 +119,27 @@ static void PREFIX_h264_chroma_mc8_altivec(uint8_t * dst, uint8_t * src, (( 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, @@ -110,89 +153,28 @@ static void PREFIX_h264_chroma_mc8_altivec(uint8_t * dst, uint8_t * src, 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; } } } @@ -209,23 +191,27 @@ static void PREFIX_no_rnd_vc1_chroma_mc8_altivec(uint8_t * dst, uint8_t * src, i (( 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, @@ -239,47 +225,14 @@ static void PREFIX_no_rnd_vc1_chroma_mc8_altivec(uint8_t * dst, uint8_t * src, i 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 diff --git a/ffmpeg/libavcodec/ppc/h264dsp.c b/ffmpeg/libavcodec/ppc/h264dsp.c index 7fc7e0b..da118a4 100644 --- a/ffmpeg/libavcodec/ppc/h264dsp.c +++ b/ffmpeg/libavcodec/ppc/h264dsp.c @@ -62,10 +62,17 @@ 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); \ @@ -165,26 +172,43 @@ static void h264_idct_add_altivec(uint8_t *dst, int16_t *block, int stride) 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) { @@ -192,8 +216,8 @@ 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); @@ -236,20 +260,25 @@ static av_always_inline void h264_idct_dc_add_internal(uint8_t *dst, int16_t *bl { 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); @@ -633,6 +662,9 @@ void weight_h264_W_altivec(uint8_t *block, int stride, int height, 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); @@ -641,8 +673,8 @@ void weight_h264_W_altivec(uint8_t *block, int stride, int height, 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); @@ -679,6 +711,9 @@ void biweight_h264_W_altivec(uint8_t *dst, uint8_t *src, int stride, int height, 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); @@ -690,10 +725,10 @@ void biweight_h264_W_altivec(uint8_t *dst, uint8_t *src, int stride, int height, 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) diff --git a/ffmpeg/libavcodec/ppc/h264qpel.c b/ffmpeg/libavcodec/ppc/h264qpel.c index 4a01f17..575f504 100644 --- a/ffmpeg/libavcodec/ppc/h264qpel.c +++ b/ffmpeg/libavcodec/ppc/h264qpel.c @@ -191,86 +191,79 @@ static void OPNAME ## h264_qpel ## SIZE ## _mc32_ ## CODETYPE(uint8_t *dst, cons 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; } } diff --git a/ffmpeg/libavcodec/ppc/h264qpel_template.c b/ffmpeg/libavcodec/ppc/h264qpel_template.c index 360e9e3..9a34548 100644 --- a/ffmpeg/libavcodec/ppc/h264qpel_template.c +++ b/ffmpeg/libavcodec/ppc/h264qpel_template.c @@ -18,7 +18,14 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "config.h" +#if HAVE_UNISTD_H +#include +#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)); @@ -26,6 +33,76 @@ #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, @@ -35,12 +112,7 @@ 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)); @@ -59,79 +131,32 @@ static void PREFIX_h264_qpel16_h_lowpass_altivec(uint8_t *dst, 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); @@ -178,7 +203,10 @@ static void PREFIX_h264_qpel16_v_lowpass_altivec(uint8_t *dst, 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); @@ -186,52 +214,41 @@ static void PREFIX_h264_qpel16_v_lowpass_altivec(uint8_t *dst, 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); @@ -288,12 +305,7 @@ static void PREFIX_h264_qpel16_hv_lowpass_altivec(uint8_t *dst, int16_t *tmp, { 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); @@ -325,81 +337,35 @@ static void PREFIX_h264_qpel16_hv_lowpass_altivec(uint8_t *dst, int16_t *tmp, 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); @@ -448,8 +414,8 @@ static void PREFIX_h264_qpel16_hv_lowpass_altivec(uint8_t *dst, int16_t *tmp, 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; @@ -474,10 +440,14 @@ static void PREFIX_h264_qpel16_hv_lowpass_altivec(uint8_t *dst, int16_t *tmp, 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); diff --git a/ffmpeg/libavcodec/ppc/hpeldsp_altivec.c b/ffmpeg/libavcodec/ppc/hpeldsp_altivec.c index 7c3b5a1..87a1f05 100644 --- a/ffmpeg/libavcodec/ppc/hpeldsp_altivec.c +++ b/ffmpeg/libavcodec/ppc/hpeldsp_altivec.c @@ -38,12 +38,11 @@ /* 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; @@ -55,22 +54,14 @@ void ff_put_pixels16_altivec(uint8_t *block, const uint8_t *pixels, ptrdiff_t li // -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; } @@ -80,15 +71,12 @@ void ff_put_pixels16_altivec(uint8_t *block, const uint8_t *pixels, ptrdiff_t li #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; @@ -108,9 +96,7 @@ static void avg_pixels8_altivec(uint8_t * block, const uint8_t * pixels, ptrdiff 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)); @@ -132,21 +118,16 @@ static void put_pixels8_xy2_altivec(uint8_t *block, const uint8_t *pixels, ptrdi { 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); @@ -155,17 +136,10 @@ static void put_pixels8_xy2_altivec(uint8_t *block, const uint8_t *pixels, ptrdi 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); @@ -191,22 +165,16 @@ static void put_no_rnd_pixels8_xy2_altivec(uint8_t *block, const uint8_t *pixels { 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); @@ -215,17 +183,10 @@ static void put_no_rnd_pixels8_xy2_altivec(uint8_t *block, const uint8_t *pixels 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); @@ -251,24 +212,18 @@ static void put_pixels16_xy2_altivec(uint8_t * block, const uint8_t * pixels, pt { 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); @@ -279,20 +234,13 @@ static void put_pixels16_xy2_altivec(uint8_t * block, const uint8_t * pixels, pt 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, @@ -319,25 +267,19 @@ static void put_no_rnd_pixels16_xy2_altivec(uint8_t * block, const uint8_t * pix { 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); @@ -346,22 +288,13 @@ static void put_no_rnd_pixels16_xy2_altivec(uint8_t * block, const uint8_t * pix 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, @@ -376,7 +309,7 @@ static void put_no_rnd_pixels16_xy2_altivec(uint8_t * block, const uint8_t * pix blockv = vec_packsu(temp3, temp4); - vec_st(blockv, 0, block); + VEC_ST(blockv, 0, block); block += line_size; pixels += line_size; @@ -388,7 +321,7 @@ static void avg_pixels8_xy2_altivec(uint8_t *block, const uint8_t *pixels, ptrdi { 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) @@ -396,16 +329,10 @@ static void avg_pixels8_xy2_altivec(uint8_t *block, const uint8_t *pixels, ptrdi 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); @@ -414,17 +341,11 @@ static void avg_pixels8_xy2_altivec(uint8_t *block, const uint8_t *pixels, ptrdi 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); diff --git a/ffmpeg/libavcodec/ppc/lossless_audiodsp_altivec.c b/ffmpeg/libavcodec/ppc/lossless_audiodsp_altivec.c index 1ebb0f4..bdec252 100644 --- a/ffmpeg/libavcodec/ppc/lossless_audiodsp_altivec.c +++ b/ffmpeg/libavcodec/ppc/lossless_audiodsp_altivec.c @@ -29,6 +29,20 @@ #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, @@ -38,26 +52,23 @@ static int32_t scalarproduct_and_madd_int16_altivec(int16_t *v1, 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; diff --git a/ffmpeg/libavcodec/ppc/me_cmp.c b/ffmpeg/libavcodec/ppc/me_cmp.c index 18f2c6e..38a7ba1 100644 --- a/ffmpeg/libavcodec/ppc/me_cmp.c +++ b/ffmpeg/libavcodec/ppc/me_cmp.c @@ -35,26 +35,43 @@ #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); @@ -66,8 +83,8 @@ static int sad16_x2_altivec(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, /* 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); @@ -78,37 +95,33 @@ static int sad16_x2_altivec(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, } 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); @@ -119,9 +132,9 @@ static int sad16_y2_altivec(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, /* 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. */ @@ -132,43 +145,41 @@ static int sad16_y2_altivec(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, } 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; @@ -178,11 +189,7 @@ static int sad16_xy2_altivec(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, * 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 @@ -191,10 +198,10 @@ static int sad16_xy2_altivec(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, * 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); @@ -212,8 +219,8 @@ static int sad16_xy2_altivec(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, /* 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; @@ -227,21 +234,19 @@ static int sad16_xy2_altivec(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, } 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); @@ -251,8 +256,8 @@ static int sad16_altivec(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, /* 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. */ @@ -264,16 +269,15 @@ static int sad16_altivec(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, } 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; @@ -281,14 +285,10 @@ static int sad8_altivec(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, /* 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); @@ -298,8 +298,8 @@ static int sad8_altivec(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, /* 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. */ @@ -313,16 +313,15 @@ static int sad8_altivec(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, /* 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; @@ -330,14 +329,8 @@ static int sse8_altivec(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, /* 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. */ @@ -350,8 +343,8 @@ static int sse8_altivec(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, /* 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. */ @@ -365,21 +358,19 @@ static int sse8_altivec(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, /* 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. */ @@ -392,22 +383,22 @@ static int sse16_altivec(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, /* 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, @@ -432,24 +423,19 @@ static int hadamard8_diff8x8_altivec(MpegEncContext *s, uint8_t *dst, { 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 */ \ @@ -461,6 +447,7 @@ static int hadamard8_diff8x8_altivec(MpegEncContext *s, uint8_t *dst, 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); @@ -510,6 +497,7 @@ static int hadamard8_diff8x8_altivec(MpegEncContext *s, uint8_t *dst, 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; @@ -534,9 +522,9 @@ static int hadamard8_diff8x8_altivec(MpegEncContext *s, uint8_t *dst, * 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"), @@ -584,31 +572,23 @@ static int hadamard8_diff16x8_altivec(MpegEncContext *s, uint8_t *dst, #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 */ \ @@ -639,6 +619,7 @@ static int hadamard8_diff16x8_altivec(MpegEncContext *s, uint8_t *dst, res1 = vec_mladd(but2, vprod3, op3); \ res2 = vec_mladd(but2S, vprod3, op3S); \ } + ONEITERBUTTERFLY(0, temp0, temp0S); ONEITERBUTTERFLY(1, temp1, temp1S); ONEITERBUTTERFLY(2, temp2, temp2S); @@ -725,13 +706,14 @@ static int hadamard8_diff16x8_altivec(MpegEncContext *s, uint8_t *dst, 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); diff --git a/ffmpeg/libavcodec/ppc/mpegvideoencdsp.c b/ffmpeg/libavcodec/ppc/mpegvideoencdsp.c index 00ae2a6..e91ba5d 100644 --- a/ffmpeg/libavcodec/ppc/mpegvideoencdsp.c +++ b/ffmpeg/libavcodec/ppc/mpegvideoencdsp.c @@ -31,6 +31,34 @@ #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; @@ -58,7 +86,37 @@ static int pix_norm1_altivec(uint8_t *pix, int line_size) 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; @@ -88,6 +146,8 @@ static int pix_sum_altivec(uint8_t *pix, int line_size) return s; } +#endif /* HAVE_VSX */ + #endif /* HAVE_ALTIVEC */ av_cold void ff_mpegvideoencdsp_init_ppc(MpegvideoEncDSPContext *c, diff --git a/ffmpeg/libavcodec/ppc/pixblockdsp.c b/ffmpeg/libavcodec/ppc/pixblockdsp.c index 4580c3d..9bbdf96 100644 --- a/ffmpeg/libavcodec/ppc/pixblockdsp.c +++ b/ffmpeg/libavcodec/ppc/pixblockdsp.c @@ -35,6 +35,34 @@ #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) { @@ -62,6 +90,71 @@ static void get_pixels_altivec(int16_t *restrict block, const uint8_t *pixels, } } +#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) { @@ -134,6 +227,8 @@ static void diff_pixels_altivec(int16_t *restrict block, const uint8_t *s1, } } +#endif /* HAVE_VSX */ + #endif /* HAVE_ALTIVEC */ av_cold void ff_pixblockdsp_init_ppc(PixblockDSPContext *c, diff --git a/ffmpeg/libavcodec/proresenc_kostya.c b/ffmpeg/libavcodec/proresenc_kostya.c index 9f7c03e..5f432a9 100644 --- a/ffmpeg/libavcodec/proresenc_kostya.c +++ b/ffmpeg/libavcodec/proresenc_kostya.c @@ -1101,7 +1101,7 @@ static av_cold int encode_close(AVCodecContext *avctx) 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); @@ -1148,11 +1148,13 @@ static av_cold int encode_init(AVCodecContext *avctx) 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) { diff --git a/ffmpeg/libavcodec/psymodel.c b/ffmpeg/libavcodec/psymodel.c index 22d2497..059cbef 100644 --- a/ffmpeg/libavcodec/psymodel.c +++ b/ffmpeg/libavcodec/psymodel.c @@ -138,10 +138,10 @@ void ff_psy_preprocess(struct FFPsyPreprocessContext *ctx, float **audio, int ch 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); } diff --git a/ffmpeg/libavcodec/pthread_frame.c b/ffmpeg/libavcodec/pthread_frame.c index 1db46fc..5a4ab84 100644 --- a/ffmpeg/libavcodec/pthread_frame.c +++ b/ffmpeg/libavcodec/pthread_frame.c @@ -198,6 +198,7 @@ static int update_context_from_thread(AVCodecContext *dst, AVCodecContext *src, 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; @@ -285,13 +286,10 @@ FF_ENABLE_DEPRECATION_WARNINGS 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)); @@ -653,8 +651,8 @@ int ff_frame_thread_init(AVCodecContext *avctx) p->frame = av_frame_alloc(); if (!p->frame) { - err = AVERROR(ENOMEM); av_freep(©); + err = AVERROR(ENOMEM); goto error; } diff --git a/ffmpeg/libavcodec/pthread_slice.c b/ffmpeg/libavcodec/pthread_slice.c index fea989f..b948e16 100644 --- a/ffmpeg/libavcodec/pthread_slice.c +++ b/ffmpeg/libavcodec/pthread_slice.c @@ -120,7 +120,7 @@ void ff_slice_thread_free(AVCodecContext *avctx) 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); } diff --git a/ffmpeg/libavcodec/put_bits.h b/ffmpeg/libavcodec/put_bits.h index 8081fb9..8858caa 100644 --- a/ffmpeg/libavcodec/put_bits.h +++ b/ffmpeg/libavcodec/put_bits.h @@ -62,6 +62,24 @@ static inline void init_put_bits(PutBitContext *s, uint8_t *buffer, 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. */ diff --git a/ffmpeg/libavcodec/ra144enc.c b/ffmpeg/libavcodec/ra144enc.c index 499c41a..3ad3f4e 100644 --- a/ffmpeg/libavcodec/ra144enc.c +++ b/ffmpeg/libavcodec/ra144enc.c @@ -55,7 +55,7 @@ static av_cold int ra144_encode_init(AVCodecContext * avctx) 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]; diff --git a/ffmpeg/libavcodec/ra288.c b/ffmpeg/libavcodec/ra288.c index 968672c..dbb2643 100644 --- a/ffmpeg/libavcodec/ra288.c +++ b/ffmpeg/libavcodec/ra288.c @@ -38,7 +38,7 @@ #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) @@ -59,6 +59,15 @@ typedef struct { 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; @@ -72,7 +81,9 @@ static av_cold int ra288_decode_init(AVCodecContext *avctx) 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; } @@ -146,7 +157,7 @@ static void do_hybrid_window(RA288Context *ractx, 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); @@ -173,7 +184,7 @@ static void backward_filter(RA288Context *ractx, 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)); } @@ -235,5 +246,6 @@ AVCodec ff_ra_288_decoder = { .priv_data_size = sizeof(RA288Context), .init = ra288_decode_init, .decode = ra288_decode_frame, + .close = ra288_decode_close, .capabilities = CODEC_CAP_DR1, }; diff --git a/ffmpeg/libavcodec/ratecontrol.c b/ffmpeg/libavcodec/ratecontrol.c index 72b3f44..d05e2ee 100644 --- a/ffmpeg/libavcodec/ratecontrol.c +++ b/ffmpeg/libavcodec/ratecontrol.c @@ -138,11 +138,11 @@ av_cold int ff_rate_control_init(MpegEncContext *s) } 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; } @@ -250,9 +250,9 @@ av_cold int ff_rate_control_init(MpegEncContext *s) 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) @@ -399,7 +399,7 @@ static double get_qscale(MpegEncContext *s, RateControlEntry *rce, 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; } @@ -477,8 +477,8 @@ static double get_diff_limited_q(MpegEncContext *s, RateControlEntry *rce, doubl */ 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); @@ -517,10 +517,10 @@ static double modify_qscale(MpegEncContext *s, RateControlEntry *rce, 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) { @@ -533,7 +533,7 @@ static double modify_qscale(MpegEncContext *s, RateControlEntry *rce, 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) * @@ -553,7 +553,7 @@ static double modify_qscale(MpegEncContext *s, RateControlEntry *rce, 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 * @@ -569,8 +569,8 @@ static double modify_qscale(MpegEncContext *s, RateControlEntry *rce, } 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) @@ -619,7 +619,7 @@ static void adaptive_quantization(MpegEncContext *s, double q) 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; diff --git a/ffmpeg/libavcodec/rawdec.c b/ffmpeg/libavcodec/rawdec.c index 28792a1..647dfa9 100644 --- a/ffmpeg/libavcodec/rawdec.c +++ b/ffmpeg/libavcodec/rawdec.c @@ -172,6 +172,9 @@ static int raw_decode(AVCodecContext *avctx, void *data, int *got_frame, 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; diff --git a/ffmpeg/libavcodec/realtextdec.c b/ffmpeg/libavcodec/realtextdec.c index 4578897..870953b 100644 --- a/ffmpeg/libavcodec/realtextdec.c +++ b/ffmpeg/libavcodec/realtextdec.c @@ -52,13 +52,13 @@ static int rt_event_to_ass(AVBPrint *buf, const char *p) } 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; @@ -67,9 +67,11 @@ static int realtext_decode_frame(AVCodecContext *avctx, // 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; } diff --git a/ffmpeg/libavcodec/rl2.c b/ffmpeg/libavcodec/rl2.c index 6e63ed1..eaf31b6 100644 --- a/ffmpeg/libavcodec/rl2.c +++ b/ffmpeg/libavcodec/rl2.c @@ -207,7 +207,7 @@ static av_cold int rl2_decode_end(AVCodecContext *avctx) { Rl2Context *s = avctx->priv_data; - av_free(s->back_frame); + av_freep(&s->back_frame); return 0; } diff --git a/ffmpeg/libavcodec/roqaudioenc.c b/ffmpeg/libavcodec/roqaudioenc.c index b0b76d0..2c59074 100644 --- a/ffmpeg/libavcodec/roqaudioenc.c +++ b/ffmpeg/libavcodec/roqaudioenc.c @@ -148,9 +148,8 @@ static int roq_dpcm_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, return 0; } } - if (context->input_frames < 8) { + if (context->input_frames < 8) in = context->frame_buffer; - } if (stereo) { context->lastSample[0] &= 0xFF00; diff --git a/ffmpeg/libavcodec/roqvideoenc.c b/ffmpeg/libavcodec/roqvideoenc.c index 1c5970f..694792e 100644 --- a/ffmpeg/libavcodec/roqvideoenc.c +++ b/ffmpeg/libavcodec/roqvideoenc.c @@ -936,8 +936,8 @@ static int roq_encode_video(RoqContext *enc) 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++; @@ -951,11 +951,11 @@ static av_cold int roq_encode_end(AVCodecContext *avctx) 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; } diff --git a/ffmpeg/libavcodec/rv30.c b/ffmpeg/libavcodec/rv30.c index fd8fd4f..1483107 100644 --- a/ffmpeg/libavcodec/rv30.c +++ b/ffmpeg/libavcodec/rv30.c @@ -259,13 +259,13 @@ static av_cold int rv30_decode_init(AVCodecContext *avctx) 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){ diff --git a/ffmpeg/libavcodec/samidec.c b/ffmpeg/libavcodec/samidec.c index 39ac608..7705f93 100644 --- a/ffmpeg/libavcodec/samidec.c +++ b/ffmpeg/libavcodec/samidec.c @@ -104,7 +104,7 @@ static int sami_paragraph_to_ass(AVCodecContext *avctx, const char *src) 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); @@ -122,7 +122,9 @@ static int sami_decode_frame(AVCodecContext *avctx, 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; diff --git a/ffmpeg/libavcodec/shorten.c b/ffmpeg/libavcodec/shorten.c index 5c4bf81..4c9cc06 100644 --- a/ffmpeg/libavcodec/shorten.c +++ b/ffmpeg/libavcodec/shorten.c @@ -510,7 +510,7 @@ static int shorten_decode_frame(AVCodecContext *avctx, void *data, 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; diff --git a/ffmpeg/libavcodec/smacker.c b/ffmpeg/libavcodec/smacker.c index 518bdad..b5538c7 100644 --- a/ffmpeg/libavcodec/smacker.c +++ b/ffmpeg/libavcodec/smacker.c @@ -589,6 +589,7 @@ static av_cold int decode_init(AVCodecContext *avctx) /* 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); } diff --git a/ffmpeg/libavcodec/smvjpegdec.c b/ffmpeg/libavcodec/smvjpegdec.c index 69327cd..375c9d9 100644 --- a/ffmpeg/libavcodec/smvjpegdec.c +++ b/ffmpeg/libavcodec/smvjpegdec.c @@ -75,6 +75,20 @@ static inline void smv_img_pnt(uint8_t *dst_data[4], uint8_t *src_data[4], 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; @@ -89,8 +103,10 @@ static av_cold int smvjpeg_decode_init(AVCodecContext *avctx) 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]; @@ -120,6 +136,8 @@ static av_cold int smvjpeg_decode_init(AVCodecContext *avctx) } av_dict_free(&thread_opt); + if (ret < 0) + smvjpeg_decode_end(avctx); return ret; } @@ -176,20 +194,6 @@ static int smvjpeg_decode_frame(AVCodecContext *avctx, void *data, int *data_siz 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, diff --git a/ffmpeg/libavcodec/snow.c b/ffmpeg/libavcodec/snow.c index 5660eba..83db3c7 100644 --- a/ffmpeg/libavcodec/snow.c +++ b/ffmpeg/libavcodec/snow.c @@ -324,7 +324,7 @@ static void mc_block(Plane *p, uint8_t *dst, const uint8_t *src, int stride, int } } -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]; @@ -637,8 +637,10 @@ void ff_snow_release_buffer(AVCodecContext *avctx) 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; + } } } diff --git a/ffmpeg/libavcodec/snow.h b/ffmpeg/libavcodec/snow.h index b6a8bf4..6f1fca3 100644 --- a/ffmpeg/libavcodec/snow.h +++ b/ffmpeg/libavcodec/snow.h @@ -29,6 +29,8 @@ #include "rangecoder.h" #include "mathops.h" + +#define FF_MPV_OFFSET(x) (offsetof(MpegEncContext, x) + offsetof(SnowContext, m)) #include "mpegvideo.h" #include "h264qpel.h" @@ -231,7 +233,7 @@ void ff_snow_reset_contexts(SnowContext *s); int ff_snow_alloc_blocks(SnowContext *s); int ff_snow_frame_start(SnowContext *s); void ff_snow_pred_block(SnowContext *s, uint8_t *dst, uint8_t *tmp, 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 */ diff --git a/ffmpeg/libavcodec/snow_dwt.c b/ffmpeg/libavcodec/snow_dwt.c index 63ff7a0..5b890e0 100644 --- a/ffmpeg/libavcodec/snow_dwt.c +++ b/ffmpeg/libavcodec/snow_dwt.c @@ -745,7 +745,7 @@ void ff_spatial_idwt(IDWTELEM *buffer, IDWTELEM *temp, int width, int height, 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; @@ -814,32 +814,32 @@ static inline int w_c(struct MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, in 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); } diff --git a/ffmpeg/libavcodec/snow_dwt.h b/ffmpeg/libavcodec/snow_dwt.h index e929189..e2d7528 100644 --- a/ffmpeg/libavcodec/snow_dwt.h +++ b/ffmpeg/libavcodec/snow_dwt.h @@ -21,6 +21,7 @@ #ifndef AVCODEC_SNOW_DWT_H #define AVCODEC_SNOW_DWT_H +#include #include typedef int DWTELEM; @@ -105,8 +106,8 @@ void ff_snow_inner_add_yblock(const uint8_t *obmc, const int obmc_stride, 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); diff --git a/ffmpeg/libavcodec/snowenc.c b/ffmpeg/libavcodec/snowenc.c index eaeafa9..cbc89c9 100644 --- a/ffmpeg/libavcodec/snowenc.c +++ b/ffmpeg/libavcodec/snowenc.c @@ -1862,7 +1862,7 @@ static av_cold int encode_end(AVCodecContext *avctx) 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; } @@ -1870,6 +1870,7 @@ static av_cold int encode_end(AVCodecContext *avctx) #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 }, diff --git a/ffmpeg/libavcodec/srtdec.c b/ffmpeg/libavcodec/srtdec.c index b16645a..6d0c9bb 100644 --- a/ffmpeg/libavcodec/srtdec.c +++ b/ffmpeg/libavcodec/srtdec.c @@ -47,8 +47,14 @@ typedef struct { 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; @@ -61,14 +67,12 @@ static const char *srt_to_ass(AVCodecContext *avctx, char *out, char *out_end, 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; @@ -77,15 +81,13 @@ static const char *srt_to_ass(AVCodecContext *avctx, char *out, char *out_end, end = 1; break; } - while (out[-1] == ' ') - out--; - snprintf(out, out_end-out, "\\N"); - if(out= 0 && len > 0)) { in += len - 1; } else - *out++ = *in; + av_bprint_chars(dst, *in, 1); break; case '<': tag_close = in[1] == '/'; @@ -115,9 +117,7 @@ static const char *srt_to_ass(AVCodecContext *avctx, char *out, char *out_end, 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", buffer); @@ -169,7 +164,7 @@ static const char *srt_to_ass(AVCodecContext *avctx, char *out, char *out_end, 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)); @@ -177,53 +172,26 @@ static const char *srt_to_ass(AVCodecContext *avctx, char *out, char *out_end, } } 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) { @@ -236,12 +204,9 @@ static int srt_decode_frame(AVCodecContext *avctx, 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, @@ -249,11 +214,12 @@ static int srt_decode_frame(AVCodecContext *avctx, 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; @@ -263,9 +229,9 @@ static int srt_decode_frame(AVCodecContext *avctx, /* 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, }; diff --git a/ffmpeg/libavcodec/srtenc.c b/ffmpeg/libavcodec/srtenc.c index 89c26dc..3287970 100644 --- a/ffmpeg/libavcodec/srtenc.c +++ b/ffmpeg/libavcodec/srtenc.c @@ -33,8 +33,6 @@ typedef struct { AVCodecContext *avctx; ASSSplitContext *ass_ctx; AVBPrint buffer; - unsigned timestamp_end; - int count; char stack[SRT_STACK_SIZE]; int stack_ptr; int alignment_applied; @@ -201,35 +199,13 @@ static void srt_cancel_overrides_cb(void *priv, const char *style) 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 = { @@ -263,19 +239,6 @@ static int srt_encode_frame(AVCodecContext *avctx, 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); @@ -308,9 +271,9 @@ static int srt_encode_close(AVCodecContext *avctx) /* 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, diff --git a/ffmpeg/libavcodec/subviewerdec.c b/ffmpeg/libavcodec/subviewerdec.c index 63be418..a008828 100644 --- a/ffmpeg/libavcodec/subviewerdec.c +++ b/ffmpeg/libavcodec/subviewerdec.c @@ -43,33 +43,26 @@ static int subviewer_event_to_ass(AVBPrint *buf, const char *p) } } - 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; } diff --git a/ffmpeg/libavcodec/sunrastenc.c b/ffmpeg/libavcodec/sunrastenc.c index a55e3d4..cff8c85 100644 --- a/ffmpeg/libavcodec/sunrastenc.c +++ b/ffmpeg/libavcodec/sunrastenc.c @@ -158,6 +158,7 @@ static av_cold int sunrast_encode_init(AVCodecContext *avctx) 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; diff --git a/ffmpeg/libavcodec/svq1enc.c b/ffmpeg/libavcodec/svq1enc.c index 850630f..2a0d780 100644 --- a/ffmpeg/libavcodec/svq1enc.c +++ b/ffmpeg/libavcodec/svq1enc.c @@ -96,7 +96,7 @@ static int encode_block(SVQ1EncContext *s, uint8_t *src, uint8_t *ref, 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]; diff --git a/ffmpeg/libavcodec/svq1enc.h b/ffmpeg/libavcodec/svq1enc.h index 740d2ff..8e74885 100644 --- a/ffmpeg/libavcodec/svq1enc.h +++ b/ffmpeg/libavcodec/svq1enc.h @@ -59,6 +59,8 @@ typedef struct SVQ1EncContext { 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]; diff --git a/ffmpeg/libavcodec/textdec.c b/ffmpeg/libavcodec/textdec.c index d904023..c9f02a2 100644 --- a/ffmpeg/libavcodec/textdec.c +++ b/ffmpeg/libavcodec/textdec.c @@ -44,6 +44,7 @@ static const AVOption options[] = { 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; @@ -55,14 +56,12 @@ static int text_decode_frame(AVCodecContext *avctx, void *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; } @@ -89,7 +88,7 @@ AVCodec ff_text_decoder = { }; #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) { @@ -114,6 +113,22 @@ AVCodec ff_vplayer_decoder = { }; #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); diff --git a/ffmpeg/libavcodec/tiff.c b/ffmpeg/libavcodec/tiff.c index 4cb6668..ee16d78 100644 --- a/ffmpeg/libavcodec/tiff.c +++ b/ffmpeg/libavcodec/tiff.c @@ -29,6 +29,7 @@ #include #endif #if CONFIG_LZMA +#define LZMA_API_STATIC #include #endif @@ -510,7 +511,9 @@ static int tiff_unpack_strip(TiffContext *s, AVFrame *p, uint8_t *dst, int strid } 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); } diff --git a/ffmpeg/libavcodec/tiffenc.c b/ffmpeg/libavcodec/tiffenc.c index 138d214..72219da 100644 --- a/ffmpeg/libavcodec/tiffenc.c +++ b/ffmpeg/libavcodec/tiffenc.c @@ -235,7 +235,7 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, 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; @@ -327,6 +327,10 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, 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); @@ -416,7 +420,7 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, } } if (s->compr == TIFF_LZW) - av_free(s->lzws); + av_freep(&s->lzws); } s->num_entries = 0; diff --git a/ffmpeg/libavcodec/truemotion2.c b/ffmpeg/libavcodec/truemotion2.c index 18d7c1e..d2aa3c6 100644 --- a/ffmpeg/libavcodec/truemotion2.c +++ b/ffmpeg/libavcodec/truemotion2.c @@ -996,14 +996,14 @@ static av_cold int decode_end(AVCodecContext *avctx) 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; diff --git a/ffmpeg/libavcodec/tta.c b/ffmpeg/libavcodec/tta.c index 5fdbac8..01584d9 100644 --- a/ffmpeg/libavcodec/tta.c +++ b/ffmpeg/libavcodec/tta.c @@ -394,7 +394,7 @@ static av_cold int tta_decode_close(AVCodecContext *avctx) { 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); diff --git a/ffmpeg/libavcodec/twinvq.c b/ffmpeg/libavcodec/twinvq.c index f117220..4c289b0 100644 --- a/ffmpeg/libavcodec/twinvq.c +++ b/ffmpeg/libavcodec/twinvq.c @@ -358,7 +358,7 @@ static void imdct_and_window(TwinVQContext *tctx, enum TwinVQFrameType ftype, 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); @@ -405,7 +405,7 @@ static void imdct_output(TwinVQContext *tctx, enum TwinVQFrameType ftype, 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); } } @@ -446,7 +446,7 @@ static void read_and_decode_spectrum(TwinVQContext *tctx, float *out, 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); } @@ -461,7 +461,7 @@ static void read_and_decode_spectrum(TwinVQContext *tctx, float *out, 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; } } @@ -755,13 +755,14 @@ av_cold int ff_twinvq_decode_close(AVCodecContext *avctx) 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; } @@ -788,7 +789,11 @@ av_cold int ff_twinvq_decode_init(AVCodecContext *avctx) 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); diff --git a/ffmpeg/libavcodec/twinvq.h b/ffmpeg/libavcodec/twinvq.h index c4e9688..ae0f595 100644 --- a/ffmpeg/libavcodec/twinvq.h +++ b/ffmpeg/libavcodec/twinvq.h @@ -136,7 +136,7 @@ typedef struct TwinVQModeTab { typedef struct TwinVQContext { AVCodecContext *avctx; - AVFloatDSPContext fdsp; + AVFloatDSPContext *fdsp; FFTContext mdct_ctx[3]; const TwinVQModeTab *mtab; diff --git a/ffmpeg/libavcodec/utils.c b/ffmpeg/libavcodec/utils.c index 4931444..66fe62c 100644 --- a/ffmpeg/libavcodec/utils.c +++ b/ffmpeg/libavcodec/utils.c @@ -122,7 +122,7 @@ static void *avformat_mutex; 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); @@ -279,7 +279,7 @@ void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height, 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; @@ -735,44 +735,34 @@ FF_ENABLE_DEPRECATION_WARNINGS 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; @@ -1160,50 +1150,87 @@ static AVHWAccel *find_hwaccel(enum AVCodecID codec_id, 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; } @@ -1243,7 +1270,7 @@ int av_codec_get_max_lowres(const AVCodec *codec) 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; @@ -1352,6 +1379,12 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *code 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))) { @@ -1497,6 +1530,12 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *code 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++) @@ -1570,6 +1609,11 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *code 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); @@ -1614,9 +1658,9 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *code #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); @@ -1630,6 +1674,11 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *code } } } + +#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(); @@ -1641,6 +1690,8 @@ end: 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); @@ -1882,6 +1933,10 @@ end: av_frame_free(&padded_frame); av_free(extended_frame); +#if FF_API_AUDIOENC_DELAY + avctx->delay = avctx->initial_padding; +#endif + return ret; } @@ -2336,6 +2391,11 @@ fail: * 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; } @@ -2419,6 +2479,8 @@ int attribute_align_arg avcodec_decode_audio4(AVCodecContext *avctx, 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); @@ -2459,8 +2521,11 @@ int attribute_align_arg avcodec_decode_audio4(AVCodecContext *avctx, 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; @@ -2489,7 +2554,8 @@ int attribute_align_arg avcodec_decode_audio4(AVCodecContext *avctx, } } - 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 { @@ -2507,6 +2573,17 @@ int attribute_align_arg avcodec_decode_audio4(AVCodecContext *avctx, 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) { @@ -2568,10 +2645,10 @@ static int recode_subtitle(AVCodecContext *avctx, 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; @@ -2624,7 +2701,7 @@ int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub, } *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; @@ -2893,7 +2970,9 @@ void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode) 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; @@ -2918,6 +2997,7 @@ void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode) 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); @@ -2927,32 +3007,60 @@ void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode) 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, @@ -2976,11 +3084,12 @@ void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode) } 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), @@ -3205,6 +3314,7 @@ int av_get_audio_frame_duration(AVCodecContext *avctx, int frame_bytes) 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; @@ -3428,20 +3538,32 @@ AVHWAccel *av_hwaccel_next(const AVHWAccel *hwaccel) 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; } @@ -3474,6 +3596,7 @@ int ff_unlock_avcodec(void) if ((*lockmgr_cb)(&codec_mutex, AV_LOCK_RELEASE)) return -1; } + return 0; } @@ -3610,6 +3733,11 @@ int avpriv_bprint_to_extradata(AVCodecContext *avctx, struct AVBPrint *buf) 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 diff --git a/ffmpeg/libavcodec/utvideodec.c b/ffmpeg/libavcodec/utvideodec.c index afd56ea..b565c10 100644 --- a/ffmpeg/libavcodec/utvideodec.c +++ b/ffmpeg/libavcodec/utvideodec.c @@ -56,13 +56,14 @@ static int build_huff(const uint8_t *src, VLC *vlc, int *fsym) *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); @@ -224,7 +225,7 @@ static void restore_median(uint8_t *src, int step, int stride, 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]; @@ -284,7 +285,7 @@ static void restore_median_il(uint8_t *src, int step, int 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]; diff --git a/ffmpeg/libavcodec/v210enc.c b/ffmpeg/libavcodec/v210enc.c index 1e53bdb..0d40f99 100644 --- a/ffmpeg/libavcodec/v210enc.c +++ b/ffmpeg/libavcodec/v210enc.c @@ -24,82 +24,190 @@ #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; @@ -119,8 +227,9 @@ AVCodec ff_v210_encoder = { .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 }, }; diff --git a/ffmpeg/libavcodec/v210enc.h b/ffmpeg/libavcodec/v210enc.h new file mode 100644 index 0000000..ea6ae41 --- /dev/null +++ b/ffmpeg/libavcodec/v210enc.h @@ -0,0 +1,33 @@ +/* + * 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 */ diff --git a/ffmpeg/libavcodec/vaapi_mpeg4.c b/ffmpeg/libavcodec/vaapi_mpeg4.c index 19adb2b..23556af 100644 --- a/ffmpeg/libavcodec/vaapi_mpeg4.c +++ b/ffmpeg/libavcodec/vaapi_mpeg4.c @@ -88,7 +88,7 @@ static int vaapi_mpeg4_start_frame(AVCodecContext *avctx, av_unused const uint8_ 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; diff --git a/ffmpeg/libavcodec/vc1.c b/ffmpeg/libavcodec/vc1.c index d23efec..b3955f2 100644 --- a/ffmpeg/libavcodec/vc1.c +++ b/ffmpeg/libavcodec/vc1.c @@ -478,28 +478,26 @@ static int decode_sequence_header_adv(VC1Context *v, GetBitContext *gb) if (get_bits1(gb)) { //framerate stuff if (get_bits1(gb)) { - v->s.avctx->time_base.num = 32; - v->s.avctx->time_base.den = get_bits(gb, 16) + 1; + 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); } } diff --git a/ffmpeg/libavcodec/vc1.h b/ffmpeg/libavcodec/vc1.h index 9a684ba..eefb613 100644 --- a/ffmpeg/libavcodec/vc1.h +++ b/ffmpeg/libavcodec/vc1.h @@ -203,6 +203,9 @@ typedef struct VC1Context{ 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 @@ -413,4 +416,16 @@ void ff_vc1_init_transposed_scantables(VC1Context *v); 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 */ diff --git a/ffmpeg/libavcodec/vc1_block.c b/ffmpeg/libavcodec/vc1_block.c new file mode 100644 index 0000000..aa62ec2 --- /dev/null +++ b/ffmpeg/libavcodec/vc1_block.c @@ -0,0 +1,3048 @@ +/* + * 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; + } + } +} diff --git a/ffmpeg/libavcodec/vc1_loopfilter.c b/ffmpeg/libavcodec/vc1_loopfilter.c new file mode 100644 index 0000000..95c4519 --- /dev/null +++ b/ffmpeg/libavcodec/vc1_loopfilter.c @@ -0,0 +1,353 @@ +/* + * 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); + } + } + } +} diff --git a/ffmpeg/libavcodec/vc1_mc.c b/ffmpeg/libavcodec/vc1_mc.c new file mode 100644 index 0000000..09e8fac --- /dev/null +++ b/ffmpeg/libavcodec/vc1_mc.c @@ -0,0 +1,952 @@ +/* + * 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<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); + } +} diff --git a/ffmpeg/libavcodec/vc1_parser.c b/ffmpeg/libavcodec/vc1_parser.c index 33e672f..3a2308e 100644 --- a/ffmpeg/libavcodec/vc1_parser.c +++ b/ffmpeg/libavcodec/vc1_parser.c @@ -112,6 +112,8 @@ static void vc1_extract_header(AVCodecParserContext *s, AVCodecContext *avctx, 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, diff --git a/ffmpeg/libavcodec/vc1_pred.c b/ffmpeg/libavcodec/vc1_pred.c new file mode 100644 index 0000000..d0908ef --- /dev/null +++ b/ffmpeg/libavcodec/vc1_pred.c @@ -0,0 +1,958 @@ +/* + * 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); + } + } +} diff --git a/ffmpeg/libavcodec/vc1_pred.h b/ffmpeg/libavcodec/vc1_pred.h new file mode 100644 index 0000000..4d47f86 --- /dev/null +++ b/ffmpeg/libavcodec/vc1_pred.h @@ -0,0 +1,59 @@ +/* + * 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 */ diff --git a/ffmpeg/libavcodec/vc1data.h b/ffmpeg/libavcodec/vc1data.h index eecb045..763cd48 100644 --- a/ffmpeg/libavcodec/vc1data.h +++ b/ffmpeg/libavcodec/vc1data.h @@ -94,8 +94,6 @@ extern VLC ff_vc1_ac_coeff_table[8]; #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 */ diff --git a/ffmpeg/libavcodec/vc1dec.c b/ffmpeg/libavcodec/vc1dec.c index a25c3d9..da6724c 100644 --- a/ffmpeg/libavcodec/vc1dec.c +++ b/ffmpeg/libavcodec/vc1dec.c @@ -26,5222 +26,18 @@ * 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 - -#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<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 @@ -5731,6 +527,13 @@ static av_cold int vc1_decode_init(AVCodecContext *avctx) 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; diff --git a/ffmpeg/libavcodec/vdpau.c b/ffmpeg/libavcodec/vdpau.c index 0dc5355..f7116f4 100644 --- a/ffmpeg/libavcodec/vdpau.c +++ b/ffmpeg/libavcodec/vdpau.c @@ -22,7 +22,9 @@ */ #include +#include "libavutil/avassert.h" #include "avcodec.h" +#include "internal.h" #include "h264.h" #include "vc1.h" @@ -38,6 +40,30 @@ * @{ */ +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(); @@ -45,6 +71,142 @@ AVVDPAUContext *av_alloc_vdpaucontext(void) 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) @@ -55,17 +217,18 @@ int ff_vdpau_common_start_frame(struct vdpau_picture_context *pic_ctx, 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 @@ -76,14 +239,14 @@ 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 @@ -94,7 +257,25 @@ FF_DISABLE_DEPRECATION_WARNINGS 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 @@ -479,8 +660,8 @@ do { \ } 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); @@ -502,4 +683,26 @@ AVVDPAUContext *av_vdpau_alloc_context(void) 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; +} + /* @}*/ diff --git a/ffmpeg/libavcodec/vdpau.h b/ffmpeg/libavcodec/vdpau.h index e25cc42..1006779 100644 --- a/ffmpeg/libavcodec/vdpau.h +++ b/ffmpeg/libavcodec/vdpau.h @@ -149,6 +149,26 @@ AVVDPAUContext *av_alloc_vdpaucontext(void); 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. * diff --git a/ffmpeg/libavcodec/vdpau_h264.c b/ffmpeg/libavcodec/vdpau_h264.c index 05a41d0..c8307bc 100644 --- a/ffmpeg/libavcodec/vdpau_h264.c +++ b/ffmpeg/libavcodec/vdpau_h264.c @@ -24,6 +24,7 @@ #include #include "avcodec.h" +#include "internal.h" #include "h264.h" #include "mpegutils.h" #include "vdpau.h" @@ -189,41 +190,43 @@ static int vdpau_h264_decode_slice(AVCodecContext *avctx, 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 = { @@ -235,4 +238,7 @@ 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), }; diff --git a/ffmpeg/libavcodec/vdpau_internal.h b/ffmpeg/libavcodec/vdpau_internal.h index 0f3652b..e1ea430 100644 --- a/ffmpeg/libavcodec/vdpau_internal.h +++ b/ffmpeg/libavcodec/vdpau_internal.h @@ -55,6 +55,39 @@ union AVVDPAUPictureInfo { #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. @@ -76,10 +109,17 @@ struct vdpau_picture_context { */ 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); diff --git a/ffmpeg/libavcodec/vdpau_mpeg12.c b/ffmpeg/libavcodec/vdpau_mpeg12.c index 84a971c..c47e50e 100644 --- a/ffmpeg/libavcodec/vdpau_mpeg12.c +++ b/ffmpeg/libavcodec/vdpau_mpeg12.c @@ -95,6 +95,12 @@ static int vdpau_mpeg_decode_slice(AVCodecContext *avctx, } #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, @@ -104,10 +110,31 @@ AVHWAccel ff_mpeg1_vdpau_hwaccel = { .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, @@ -117,5 +144,8 @@ AVHWAccel ff_mpeg2_vdpau_hwaccel = { .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 diff --git a/ffmpeg/libavcodec/vdpau_mpeg4.c b/ffmpeg/libavcodec/vdpau_mpeg4.c index 64669a6..9141bec 100644 --- a/ffmpeg/libavcodec/vdpau_mpeg4.c +++ b/ffmpeg/libavcodec/vdpau_mpeg4.c @@ -61,7 +61,7 @@ static int vdpau_mpeg4_start_frame(AVCodecContext *avctx, 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; @@ -89,6 +89,12 @@ static int vdpau_mpeg4_decode_slice(av_unused AVCodecContext *avctx, } #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, @@ -98,10 +104,34 @@ AVHWAccel ff_h263_vdpau_hwaccel = { .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, @@ -111,5 +141,8 @@ AVHWAccel ff_mpeg4_vdpau_hwaccel = { .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 diff --git a/ffmpeg/libavcodec/vdpau_vc1.c b/ffmpeg/libavcodec/vdpau_vc1.c index 13c41df..ffd6505 100644 --- a/ffmpeg/libavcodec/vdpau_vc1.c +++ b/ffmpeg/libavcodec/vdpau_vc1.c @@ -113,6 +113,27 @@ static int vdpau_vc1_decode_slice(AVCodecContext *avctx, 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", @@ -123,6 +144,9 @@ AVHWAccel ff_wmv3_vdpau_hwaccel = { .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 @@ -135,4 +159,7 @@ AVHWAccel ff_vc1_vdpau_hwaccel = { .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), }; diff --git a/ffmpeg/libavcodec/version.h b/ffmpeg/libavcodec/version.h index 8664884..23443ed 100644 --- a/ffmpeg/libavcodec/version.h +++ b/ffmpeg/libavcodec/version.h @@ -29,7 +29,7 @@ #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, \ @@ -132,18 +132,12 @@ #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 @@ -178,5 +172,17 @@ /* 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 */ diff --git a/ffmpeg/libavcodec/vorbis_parser.c b/ffmpeg/libavcodec/vorbis_parser.c index 1e2cab3..b99f115 100644 --- a/ffmpeg/libavcodec/vorbis_parser.c +++ b/ffmpeg/libavcodec/vorbis_parser.c @@ -25,34 +25,42 @@ * 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; } @@ -62,7 +70,7 @@ static int parse_id_header(AVCodecContext *avctx, VorbisParseContext *s, 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; @@ -72,25 +80,25 @@ static int parse_setup_header(AVCodecContext *avctx, VorbisParseContext *s, /* 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++) @@ -105,7 +113,7 @@ static int parse_setup_header(AVCodecContext *avctx, VorbisParseContext *s, } } 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; } @@ -132,7 +140,7 @@ static int parse_setup_header(AVCodecContext *avctx, VorbisParseContext *s, } } 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; } @@ -141,7 +149,7 @@ static int parse_setup_header(AVCodecContext *avctx, VorbisParseContext *s, * 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); @@ -149,7 +157,7 @@ static int parse_setup_header(AVCodecContext *avctx, VorbisParseContext *s, /* 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; @@ -173,26 +181,27 @@ 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; @@ -201,8 +210,8 @@ int avpriv_vorbis_parse_extradata(AVCodecContext *avctx, VorbisParseContext *s) 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; @@ -227,7 +236,7 @@ int avpriv_vorbis_parse_frame_flags(VorbisParseContext *s, const uint8_t *buf, 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) @@ -235,7 +244,7 @@ bad_packet: 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]){ @@ -250,19 +259,68 @@ bad_packet: 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) @@ -270,11 +328,13 @@ static int vorbis_parse(AVCodecParserContext *s1, AVCodecContext *avctx, 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: @@ -285,9 +345,16 @@ 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 */ diff --git a/ffmpeg/libavcodec/vorbis_parser.h b/ffmpeg/libavcodec/vorbis_parser.h index 590101b..0f73537 100644 --- a/ffmpeg/libavcodec/vorbis_parser.h +++ b/ffmpeg/libavcodec/vorbis_parser.h @@ -1,5 +1,4 @@ /* - * Copyright (c) 2012 Justin Ruggles * * This file is part of FFmpeg. * @@ -20,35 +19,31 @@ /** * @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 -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 @@ -56,8 +51,7 @@ int avpriv_vorbis_parse_extradata(AVCodecContext *avctx, VorbisParseContext *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, + * If @p flags is @c NULL, * special frames are considered invalid. * * @param s Vorbis parser context @@ -65,22 +59,19 @@ int avpriv_vorbis_parse_extradata(AVCodecContext *avctx, VorbisParseContext *s); * @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 */ diff --git a/ffmpeg/libavcodec/vorbis_parser_internal.h b/ffmpeg/libavcodec/vorbis_parser_internal.h new file mode 100644 index 0000000..49481ee --- /dev/null +++ b/ffmpeg/libavcodec/vorbis_parser_internal.h @@ -0,0 +1,86 @@ +/* + * 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 */ diff --git a/ffmpeg/libavcodec/vorbisdec.c b/ffmpeg/libavcodec/vorbisdec.c index 354ab0e..fb16099 100644 --- a/ffmpeg/libavcodec/vorbisdec.c +++ b/ffmpeg/libavcodec/vorbisdec.c @@ -127,7 +127,7 @@ typedef struct vorbis_context_s { AVCodecContext *avctx; GetBitContext gb; VorbisDSPContext dsp; - AVFloatDSPContext fdsp; + AVFloatDSPContext *fdsp; FmtConvertContext fmt_conv; FFTContext mdct[2]; @@ -193,10 +193,11 @@ static void vorbis_free(vorbis_context *vc) 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); @@ -205,7 +206,7 @@ static void vorbis_free(vorbis_context *vc) 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); @@ -213,21 +214,21 @@ static void vorbis_free(vorbis_context *vc) 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); } @@ -992,6 +993,9 @@ static int vorbis_parse_id_hdr(vorbis_context *vc) 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]); @@ -1020,7 +1024,6 @@ static av_cold int vorbis_decode_init(AVCodecContext *avctx) 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; @@ -1688,7 +1691,7 @@ static int vorbis_parse_audio_packet(vorbis_context *vc, float **floor_ptr) 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]); } @@ -1705,13 +1708,13 @@ static int vorbis_parse_audio_packet(vorbis_context *vc, float **floor_ptr) 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)); } diff --git a/ffmpeg/libavcodec/vorbisenc.c b/ffmpeg/libavcodec/vorbisenc.c index 0f78d95..c06093e 100644 --- a/ffmpeg/libavcodec/vorbisenc.c +++ b/ffmpeg/libavcodec/vorbisenc.c @@ -1094,8 +1094,9 @@ static int vorbis_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, 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; diff --git a/ffmpeg/libavcodec/vp3.c b/ffmpeg/libavcodec/vp3.c index 4a72d0d..8aca83a 100644 --- a/ffmpeg/libavcodec/vp3.c +++ b/ffmpeg/libavcodec/vp3.c @@ -2269,7 +2269,7 @@ static int theora_decode_header(AVCodecContext *avctx, GetBitContext *gb) 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); } diff --git a/ffmpeg/libavcodec/vp6.c b/ffmpeg/libavcodec/vp6.c index a18b8ff..e97ef76 100644 --- a/ffmpeg/libavcodec/vp6.c +++ b/ffmpeg/libavcodec/vp6.c @@ -651,7 +651,7 @@ static av_cold int vp6_decode_free(AVCodecContext *avctx) 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; diff --git a/ffmpeg/libavcodec/vp8.c b/ffmpeg/libavcodec/vp8.c index d72fb57..6ad26f3 100644 --- a/ffmpeg/libavcodec/vp8.c +++ b/ffmpeg/libavcodec/vp8.c @@ -688,9 +688,10 @@ static int vp8_decode_frame_header(VP8Context *s, const uint8_t *buf, int buf_si 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))) @@ -1915,8 +1916,8 @@ void inter_predict(VP8Context *s, VP8ThreadData *td, uint8_t *dst[3], 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; @@ -2547,6 +2548,13 @@ int vp78_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, 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 diff --git a/ffmpeg/libavcodec/vp8.h b/ffmpeg/libavcodec/vp8.h index 83729c8..b650892 100644 --- a/ffmpeg/libavcodec/vp8.h +++ b/ffmpeg/libavcodec/vp8.h @@ -266,6 +266,9 @@ typedef struct VP8Context { 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. diff --git a/ffmpeg/libavcodec/vp9.c b/ffmpeg/libavcodec/vp9.c index 31725e6..07df9ef 100644 --- a/ffmpeg/libavcodec/vp9.c +++ b/ffmpeg/libavcodec/vp9.c @@ -145,6 +145,7 @@ typedef struct VP9Context { 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; @@ -160,7 +161,7 @@ typedef struct VP9Context { 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; @@ -3780,6 +3781,18 @@ static int vp9_decode_frame(AVCodecContext *ctx, void *frame, 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); @@ -3814,6 +3827,8 @@ static int vp9_decode_frame(AVCodecContext *ctx, void *frame, } s->prob_ctx[s->framectxid].p = s->prob.p; ff_thread_finish_setup(ctx); + } else if (!s->refreshctx) { + ff_thread_finish_setup(ctx); } do { diff --git a/ffmpeg/libavcodec/webp.c b/ffmpeg/libavcodec/webp.c index 274708d..4b1c8e7 100644 --- a/ffmpeg/libavcodec/webp.c +++ b/ffmpeg/libavcodec/webp.c @@ -1061,15 +1061,32 @@ static int apply_color_indexing_transform(WebPContext *s) 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); + } } } } diff --git a/ffmpeg/libavcodec/webvttdec.c b/ffmpeg/libavcodec/webvttdec.c index 6b86bed..1284a17 100644 --- a/ffmpeg/libavcodec/webvttdec.c +++ b/ffmpeg/libavcodec/webvttdec.c @@ -67,13 +67,13 @@ static int webvtt_event_to_ass(AVBPrint *buf, const char *p) 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; @@ -83,10 +83,12 @@ static int webvtt_decode_frame(AVCodecContext *avctx, 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; } diff --git a/ffmpeg/libavcodec/wma.c b/ffmpeg/libavcodec/wma.c index ecc7e41..51fda3f 100644 --- a/ffmpeg/libavcodec/wma.c +++ b/ffmpeg/libavcodec/wma.c @@ -86,7 +86,6 @@ av_cold int ff_wma_init(AVCodecContext *avctx, int flags2) 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; @@ -333,6 +332,10 @@ av_cold int ff_wma_init(AVCodecContext *avctx, int flags2) #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) { @@ -383,6 +386,7 @@ int ff_wma_end(AVCodecContext *avctx) av_freep(&s->level_table[i]); av_freep(&s->int_table[i]); } + av_freep(&s->fdsp); return 0; } diff --git a/ffmpeg/libavcodec/wma.h b/ffmpeg/libavcodec/wma.h index 6e5198a..a232b8a 100644 --- a/ffmpeg/libavcodec/wma.h +++ b/ffmpeg/libavcodec/wma.h @@ -132,7 +132,7 @@ typedef struct WMACodecContext { 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; diff --git a/ffmpeg/libavcodec/wmadec.c b/ffmpeg/libavcodec/wmadec.c index 6c3f28f..d32ca6f 100644 --- a/ffmpeg/libavcodec/wmadec.c +++ b/ffmpeg/libavcodec/wmadec.c @@ -390,14 +390,14 @@ static void wma_window(WMACodecContext *s, float *out) 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)); @@ -411,7 +411,7 @@ static void wma_window(WMACodecContext *s, float *out) 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; @@ -419,7 +419,7 @@ static void wma_window(WMACodecContext *s, float *out) 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)); @@ -738,7 +738,7 @@ static int wma_decode_block(WMACodecContext *s) 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: diff --git a/ffmpeg/libavcodec/wmaenc.c b/ffmpeg/libavcodec/wmaenc.c index dfa4ad9..08d45e9 100644 --- a/ffmpeg/libavcodec/wmaenc.c +++ b/ffmpeg/libavcodec/wmaenc.c @@ -88,9 +88,7 @@ static av_cold int encode_init(AVCodecContext *avctx) (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; } @@ -109,10 +107,10 @@ static void apply_window_and_mdct(AVCodecContext *avctx, const AVFrame *frame) 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); } } @@ -403,7 +401,7 @@ static int encode_superframe(AVCodecContext *avctx, AVPacket *avpkt, 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; diff --git a/ffmpeg/libavcodec/wmalosslessdec.c b/ffmpeg/libavcodec/wmalosslessdec.c index 8e2ac5f..e6e3476 100644 --- a/ffmpeg/libavcodec/wmalosslessdec.c +++ b/ffmpeg/libavcodec/wmalosslessdec.c @@ -200,8 +200,7 @@ static av_cold int decode_init(AVCodecContext *avctx) 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); @@ -997,7 +996,7 @@ static int decode_subframe(WmallDecodeCtx *s) 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); } } } diff --git a/ffmpeg/libavcodec/wmaprodec.c b/ffmpeg/libavcodec/wmaprodec.c index f45e1fc..cc7ad0d 100644 --- a/ffmpeg/libavcodec/wmaprodec.c +++ b/ffmpeg/libavcodec/wmaprodec.c @@ -171,7 +171,7 @@ typedef struct { 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 @@ -260,6 +260,8 @@ static av_cold int decode_end(AVCodecContext *avctx) 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]); @@ -286,7 +288,9 @@ static av_cold int decode_init(AVCodecContext *avctx) } 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); @@ -422,6 +426,9 @@ static av_cold int decode_init(AVCodecContext *avctx) 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; @@ -1034,10 +1041,10 @@ static void inverse_channel_transform(WMAProDecodeCtx *s) } } 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); } @@ -1068,7 +1075,7 @@ static void wmapro_window(WMAProDecodeCtx *s) 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; @@ -1288,7 +1295,7 @@ static int decode_subframe(WMAProDecodeCtx *s) 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); } diff --git a/ffmpeg/libavcodec/wmv2enc.c b/ffmpeg/libavcodec/wmv2enc.c index a05a224..62e99c0 100644 --- a/ffmpeg/libavcodec/wmv2enc.c +++ b/ffmpeg/libavcodec/wmv2enc.c @@ -222,6 +222,8 @@ void ff_wmv2_encode_mb(MpegEncContext *s, int16_t block[6][64], 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"), @@ -233,4 +235,5 @@ AVCodec ff_wmv2_encoder = { .close = ff_mpv_encode_end, .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE }, + .priv_class = &wmv2_class, }; diff --git a/ffmpeg/libavcodec/x86/Makefile b/ffmpeg/libavcodec/x86/Makefile index 7bf0e82..7c8e7aa 100644 --- a/ffmpeg/libavcodec/x86/Makefile +++ b/ffmpeg/libavcodec/x86/Makefile @@ -37,11 +37,12 @@ OBJS-$(CONFIG_XMM_CLOBBER_TEST) += x86/w64xmmtest.o # 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 @@ -50,9 +51,10 @@ OBJS-$(CONFIG_RV30_DECODER) += x86/rv34dsp_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 @@ -66,8 +68,7 @@ OBJS-$(CONFIG_WEBP_DECODER) += x86/vp8dsp_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 \ @@ -128,11 +129,13 @@ YASM-OBJS-$(CONFIG_VP3DSP) += x86/vp3dsp.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 @@ -140,7 +143,9 @@ YASM-OBJS-$(CONFIG_RV30_DECODER) += x86/rv34dsp.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 diff --git a/ffmpeg/libavcodec/x86/cavsdsp.c b/ffmpeg/libavcodec/x86/cavsdsp.c index d155fb2..190f6ee 100644 --- a/ffmpeg/libavcodec/x86/cavsdsp.c +++ b/ffmpeg/libavcodec/x86/cavsdsp.c @@ -139,7 +139,7 @@ static inline void cavs_idct8_1d(int16_t *block, uint64_t bias) 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); @@ -198,7 +198,7 @@ static void cavs_idct8_add_mmx(uint8_t *dst, int16_t *block, int stride) ); } - ff_add_pixels_clamped_mmx(b2, dst, stride); + ff_add_pixels_clamped(b2, dst, stride); } #endif /* HAVE_MMX_INLINE */ diff --git a/ffmpeg/libavcodec/x86/constants.c b/ffmpeg/libavcodec/x86/constants.c index 5d2c237..aa3df00 100644 --- a/ffmpeg/libavcodec/x86/constants.c +++ b/ffmpeg/libavcodec/x86/constants.c @@ -41,7 +41,8 @@ DECLARE_ALIGNED(16, const xmm_reg, ff_pw_64) = { 0x0040004000400040ULL, 0x004 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 }; diff --git a/ffmpeg/libavcodec/x86/flacdsp.asm b/ffmpeg/libavcodec/x86/flacdsp.asm index 37ee87b..d60a6e4 100644 --- a/ffmpeg/libavcodec/x86/flacdsp.asm +++ b/ffmpeg/libavcodec/x86/flacdsp.asm @@ -2,6 +2,7 @@ ;* FLAC DSP SIMD optimizations ;* ;* Copyright (C) 2014 Loren Merritt +;* Copyright (C) 2014 James Almer ;* ;* This file is part of FFmpeg. ;* @@ -72,3 +73,257 @@ ALIGN 16 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__(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 diff --git a/ffmpeg/libavcodec/x86/flacdsp_init.c b/ffmpeg/libavcodec/x86/flacdsp_init.c index ad88e5b..d04af45 100644 --- a/ffmpeg/libavcodec/x86/flacdsp_init.c +++ b/ffmpeg/libavcodec/x86/flacdsp_init.c @@ -29,21 +29,89 @@ void ff_flac_lpc_32_xop(int32_t *samples, const int coeffs[32], int order, 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 */ } diff --git a/ffmpeg/libavcodec/x86/fmtconvert.asm b/ffmpeg/libavcodec/x86/fmtconvert.asm index 0d3f821..19595f7 100644 --- a/ffmpeg/libavcodec/x86/fmtconvert.asm +++ b/ffmpeg/libavcodec/x86/fmtconvert.asm @@ -77,6 +77,44 @@ INT32_TO_FLOAT_FMUL_SCALAR 5 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); diff --git a/ffmpeg/libavcodec/x86/fmtconvert_init.c b/ffmpeg/libavcodec/x86/fmtconvert_init.c index d300dfd..cbb96e2 100644 --- a/ffmpeg/libavcodec/x86/fmtconvert_init.c +++ b/ffmpeg/libavcodec/x86/fmtconvert_init.c @@ -32,6 +32,10 @@ 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); @@ -134,12 +138,14 @@ av_cold void ff_fmt_convert_init_x86(FmtConvertContext *c, AVCodecContext *avctx } 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; } diff --git a/ffmpeg/libavcodec/x86/h264_i386.h b/ffmpeg/libavcodec/x86/h264_i386.h index ef65cf8..49ad0e0 100644 --- a/ffmpeg/libavcodec/x86/h264_i386.h +++ b/ffmpeg/libavcodec/x86/h264_i386.h @@ -36,6 +36,12 @@ #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 @@ -140,7 +146,7 @@ static int decode_significance_8x8_x86(CABACContext *c, "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", @@ -151,14 +157,14 @@ static int decode_significance_8x8_x86(CABACContext *c, 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" @@ -171,8 +177,8 @@ static int decode_significance_8x8_x86(CABACContext *c, "%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" @@ -180,19 +186,19 @@ static int decode_significance_8x8_x86(CABACContext *c, "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 diff --git a/ffmpeg/libavcodec/x86/h264_intrapred.asm b/ffmpeg/libavcodec/x86/h264_intrapred.asm index 88ba597..c88d91b 100644 --- a/ffmpeg/libavcodec/x86/h264_intrapred.asm +++ b/ffmpeg/libavcodec/x86/h264_intrapred.asm @@ -1027,9 +1027,9 @@ cglobal pred8x8l_top_dc_8, 4,4 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: @@ -1038,7 +1038,7 @@ cglobal pred8x8l_top_dc_8, 4,4 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 @@ -1099,7 +1099,7 @@ cglobal pred8x8l_dc_8, 4,5 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 @@ -1114,7 +1114,7 @@ cglobal pred8x8l_dc_8, 4,5 psllq mm5, 56 psrlq mm5, 56 pxor mm2, mm5 - test r2, r2 + test r2d, r2d jnz .body .fix_tr_1: movq mm5, mm3 @@ -1138,9 +1138,9 @@ cglobal pred8x8l_dc_8, 4,5 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] @@ -1182,7 +1182,7 @@ cglobal pred8x8l_horizontal_8, 4,4 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] @@ -1259,9 +1259,9 @@ cglobal pred8x8l_vertical_8, 4,4 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: @@ -1270,7 +1270,7 @@ cglobal pred8x8l_vertical_8, 4,4 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 @@ -1310,9 +1310,9 @@ cglobal pred8x8l_down_left_8, 4,5 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: @@ -1321,7 +1321,7 @@ cglobal pred8x8l_down_left_8, 4,5 psllq mm5, 56 psrlq mm5, 56 pxor mm2, mm5 - test r2, r2 + test r2d, r2d jnz .do_top .fix_tr_1: movq mm5, mm3 @@ -1337,7 +1337,7 @@ cglobal pred8x8l_down_left_8, 4,5 .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 @@ -1418,9 +1418,9 @@ cglobal pred8x8l_down_left_8, 4,4 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: @@ -1429,7 +1429,7 @@ cglobal pred8x8l_down_left_8, 4,4 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 @@ -1445,7 +1445,7 @@ cglobal pred8x8l_down_left_8, 4,4 .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 @@ -1527,7 +1527,7 @@ cglobal pred8x8l_down_right_8, 4,5 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 @@ -1545,9 +1545,9 @@ cglobal pred8x8l_down_right_8, 4,5 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 @@ -1566,7 +1566,7 @@ cglobal pred8x8l_down_right_8, 4,5 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 @@ -1659,7 +1659,7 @@ cglobal pred8x8l_down_right_8, 4,5 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: @@ -1675,7 +1675,7 @@ cglobal pred8x8l_down_right_8, 4,5 psllq mm5, 56 psrlq mm5, 56 pxor mm2, mm5 - test r2, r2 + test r2d, r2d jnz .do_top .fix_tr_1: movq mm5, mm3 @@ -1701,9 +1701,9 @@ cglobal pred8x8l_down_right_8, 4,5 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 @@ -1779,7 +1779,7 @@ cglobal pred8x8l_vertical_right_8, 4,5 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: @@ -1795,7 +1795,7 @@ cglobal pred8x8l_vertical_right_8, 4,5 psllq mm5, 56 psrlq mm5, 56 pxor mm2, mm5 - test r2, r2 + test r2d, r2d jnz .do_top .fix_tr_1: movq mm5, mm3 @@ -1815,9 +1815,9 @@ cglobal pred8x8l_vertical_right_8, 4,5 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 @@ -1889,7 +1889,7 @@ cglobal pred8x8l_vertical_right_8, 4,5,7 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 @@ -1904,7 +1904,7 @@ cglobal pred8x8l_vertical_right_8, 4,5,7 psllq mm5, 56 psrlq mm5, 56 pxor mm2, mm5 - test r2, r2 + test r2d, r2d jnz .do_top .fix_tr_1: movq mm5, mm3 @@ -1924,9 +1924,9 @@ cglobal pred8x8l_vertical_right_8, 4,5,7 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 @@ -1991,9 +1991,9 @@ cglobal pred8x8l_vertical_left_8, 4,4 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: @@ -2002,7 +2002,7 @@ cglobal pred8x8l_vertical_left_8, 4,4 psllq mm5, 56 psrlq mm5, 56 pxor mm2, mm5 - test r2, r2 + test r2d, r2d jnz .do_top .fix_tr_1: movq mm5, mm3 @@ -2018,7 +2018,7 @@ cglobal pred8x8l_vertical_left_8, 4,4 .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 @@ -2076,7 +2076,7 @@ cglobal pred8x8l_horizontal_up_8, 4,4 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] @@ -2185,7 +2185,7 @@ cglobal pred8x8l_horizontal_down_8, 4,5 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 @@ -2200,7 +2200,7 @@ cglobal pred8x8l_horizontal_down_8, 4,5 psllq mm5, 56 psrlq mm5, 56 pxor mm2, mm5 - test r2, r2 + test r2d, r2d jnz .do_top .fix_tr_1: movq mm5, mm3 @@ -2225,9 +2225,9 @@ cglobal pred8x8l_horizontal_down_8, 4,5 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 @@ -2300,7 +2300,7 @@ cglobal pred8x8l_horizontal_down_8, 4,5 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 @@ -2315,7 +2315,7 @@ cglobal pred8x8l_horizontal_down_8, 4,5 psllq mm5, 56 psrlq mm5, 56 pxor mm2, mm5 - test r2, r2 + test r2d, r2d jnz .do_top .fix_tr_1: movq mm5, mm3 @@ -2346,14 +2346,14 @@ cglobal pred8x8l_horizontal_down_8, 4,5 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 diff --git a/ffmpeg/libavcodec/x86/hevc_mc.asm b/ffmpeg/libavcodec/x86/hevc_mc.asm index e126200..eaa070c 100644 --- a/ffmpeg/libavcodec/x86/hevc_mc.asm +++ b/ffmpeg/libavcodec/x86/hevc_mc.asm @@ -1203,11 +1203,12 @@ cglobal hevc_put_hevc_uni_w%1_%2, 6, 6, 7, dst, dststride, src, srcstride, heigh 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 @@ -1274,11 +1275,12 @@ cglobal hevc_put_hevc_bi_w%1_%2, 5, 7, 10, dst, dststride, src, srcstride, src2, 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 diff --git a/ffmpeg/libavcodec/x86/hpeldsp_rnd_template.c b/ffmpeg/libavcodec/x86/hpeldsp_rnd_template.c index c8a68fd..8cbc412 100644 --- a/ffmpeg/libavcodec/x86/hpeldsp_rnd_template.c +++ b/ffmpeg/libavcodec/x86/hpeldsp_rnd_template.c @@ -138,27 +138,28 @@ static void DEF(put, pixels8_y2)(uint8_t *block, const uint8_t *pixels, ptrdiff_ 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) diff --git a/ffmpeg/libavcodec/x86/idctdsp.asm b/ffmpeg/libavcodec/x86/idctdsp.asm index 44a1a6e..0aa7345 100644 --- a/ffmpeg/libavcodec/x86/idctdsp.asm +++ b/ffmpeg/libavcodec/x86/idctdsp.asm @@ -31,7 +31,7 @@ SECTION_TEXT ;-------------------------------------------------------------------------- ;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 @@ -78,3 +78,106 @@ INIT_MMX mmx 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 diff --git a/ffmpeg/libavcodec/x86/idctdsp.h b/ffmpeg/libavcodec/x86/idctdsp.h index 9b7177a..daa4e79 100644 --- a/ffmpeg/libavcodec/x86/idctdsp.h +++ b/ffmpeg/libavcodec/x86/idctdsp.h @@ -20,14 +20,19 @@ #define AVCODEC_X86_IDCTDSP_H #include +#include 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 */ diff --git a/ffmpeg/libavcodec/x86/idctdsp_init.c b/ffmpeg/libavcodec/x86/idctdsp_init.c index 3f438f4..2c26a98 100644 --- a/ffmpeg/libavcodec/x86/idctdsp_init.c +++ b/ffmpeg/libavcodec/x86/idctdsp_init.c @@ -64,9 +64,6 @@ av_cold void ff_idctdsp_init_x86(IDCTDSPContext *c, AVCodecContext *avctx, 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 || @@ -80,8 +77,12 @@ av_cold void ff_idctdsp_init_x86(IDCTDSPContext *c, AVCodecContext *avctx, } 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; } } diff --git a/ffmpeg/libavcodec/x86/idctdsp_mmx.c b/ffmpeg/libavcodec/x86/idctdsp_mmx.c deleted file mode 100644 index a72b941..0000000 --- a/ffmpeg/libavcodec/x86/idctdsp_mmx.c +++ /dev/null @@ -1,133 +0,0 @@ -/* - * SIMD-optimized IDCT-related routines - * Copyright (c) 2000, 2001 Fabrice Bellard - * Copyright (c) 2002-2004 Michael Niedermayer - * - * MMX optimization by Nick Kurshev - * - * 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 */ diff --git a/ffmpeg/libavcodec/x86/lossless_audiodsp.asm b/ffmpeg/libavcodec/x86/lossless_audiodsp.asm index 64b769f..39395fe 100644 --- a/ffmpeg/libavcodec/x86/lossless_audiodsp.asm +++ b/ffmpeg/libavcodec/x86/lossless_audiodsp.asm @@ -26,6 +26,12 @@ SECTION_TEXT ; 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 @@ -117,6 +123,8 @@ align 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 diff --git a/ffmpeg/libavcodec/x86/me_cmp.asm b/ffmpeg/libavcodec/x86/me_cmp.asm index b0741f3..0160dc3 100644 --- a/ffmpeg/libavcodec/x86/me_cmp.asm +++ b/ffmpeg/libavcodec/x86/me_cmp.asm @@ -23,6 +23,11 @@ %include "libavutil/x86/x86util.asm" +SECTION_RODATA + +cextern pb_1 +cextern pb_80 + SECTION .text %macro DIFF_PIXELS_1 4 @@ -210,7 +215,7 @@ hadamard8_16_wrapper %1, 3 %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 @@ -275,7 +280,7 @@ INIT_XMM ssse3 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 @@ -390,7 +395,7 @@ INIT_XMM ssse3 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 @@ -432,7 +437,6 @@ SUM_ABS_DCTELEM 6, 2 ; %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 @@ -465,3 +469,466 @@ cglobal hf_noise%1, 3,3,0, pix1, lsize, h INIT_MMX mmx HF_NOISE 8 HF_NOISE 16 + +;--------------------------------------------------------------------------------------- +;int ff_sad_(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_(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_(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_(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 diff --git a/ffmpeg/libavcodec/x86/me_cmp_init.c b/ffmpeg/libavcodec/x86/me_cmp_init.c index 21db221..255df50 100644 --- a/ffmpeg/libavcodec/x86/me_cmp_init.c +++ b/ffmpeg/libavcodec/x86/me_cmp_init.c @@ -34,19 +34,55 @@ int ff_sum_abs_dctelem_mmxext(int16_t *block); 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) @@ -55,16 +91,16 @@ hadamard_func(ssse3) #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; @@ -73,11 +109,11 @@ static int nsse16_mmx(MpegEncContext *c, uint8_t *pix1, uint8_t *pix2, } 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; @@ -90,12 +126,12 @@ static int nsse8_mmx(MpegEncContext *c, uint8_t *pix1, uint8_t *pix2, #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" \ @@ -146,64 +182,21 @@ static int vsad_intra16_mmx(MpegEncContext *v, uint8_t *pix, uint8_t *dummy, "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" \ @@ -270,86 +263,23 @@ static int vsad16_mmx(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, "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" @@ -379,137 +309,13 @@ static inline void sad8_1_mmx(uint8_t *blk1, uint8_t *blk2, int stride, int h) "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" @@ -542,12 +348,13 @@ static inline void sad8_2_mmx(uint8_t *blk1a, uint8_t *blk1b, uint8_t *blk2, " 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" @@ -595,7 +402,7 @@ static inline void sad8_4_mmx(uint8_t *blk1, uint8_t *blk2, int stride, int h) " 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) @@ -613,28 +420,21 @@ 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 ( \ @@ -648,7 +448,7 @@ static int sad8_ ## suf(MpegEncContext *v, uint8_t *blk2, \ } \ \ 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 ( \ @@ -663,7 +463,7 @@ static int sad8_x2_ ## suf(MpegEncContext *v, uint8_t *blk2, \ } \ \ 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 ( \ @@ -678,7 +478,7 @@ static int sad8_y2_ ## suf(MpegEncContext *v, uint8_t *blk2, \ } \ \ 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 ( \ @@ -692,7 +492,7 @@ static int sad8_xy2_ ## suf(MpegEncContext *v, uint8_t *blk2, \ } \ \ 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" \ @@ -706,7 +506,7 @@ static int sad16_ ## suf(MpegEncContext *v, uint8_t *blk2, \ } \ \ 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" \ @@ -721,7 +521,7 @@ static int sad16_x2_ ## suf(MpegEncContext *v, uint8_t *blk2, \ } \ \ 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" \ @@ -736,7 +536,7 @@ static int sad16_y2_ ## suf(MpegEncContext *v, uint8_t *blk2, \ } \ \ 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" \ @@ -750,7 +550,6 @@ static int sad16_xy2_ ## suf(MpegEncContext *v, uint8_t *blk2, \ } \ PIX_SAD(mmx) -PIX_SAD(mmxext) #endif /* HAVE_INLINE_ASM */ @@ -779,32 +578,6 @@ av_cold void ff_me_cmp_init_x86(MECmpContext *c, AVCodecContext *avctx) } } - 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)) { @@ -823,6 +596,27 @@ av_cold void ff_me_cmp_init_x86(MECmpContext *c, AVCodecContext *avctx) 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)) { @@ -833,6 +627,18 @@ av_cold void ff_me_cmp_init_x86(MECmpContext *c, AVCodecContext *avctx) 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)) { diff --git a/ffmpeg/libavcodec/x86/mlpdsp.asm b/ffmpeg/libavcodec/x86/mlpdsp.asm new file mode 100644 index 0000000..ce656af --- /dev/null +++ b/ffmpeg/libavcodec/x86/mlpdsp.asm @@ -0,0 +1,196 @@ +;****************************************************************************** +;* SIMD-optimized MLP DSP functions +;* Copyright (c) 2014 James Almer +;* +;* 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 diff --git a/ffmpeg/libavcodec/x86/mlpdsp.c b/ffmpeg/libavcodec/x86/mlpdsp_init.c similarity index 86% rename from ffmpeg/libavcodec/x86/mlpdsp.c rename to ffmpeg/libavcodec/x86/mlpdsp_init.c index f090fd7..dc0bc58 100644 --- a/ffmpeg/libavcodec/x86/mlpdsp.c +++ b/ffmpeg/libavcodec/x86/mlpdsp_init.c @@ -26,6 +26,22 @@ #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; @@ -178,9 +194,13 @@ static void mlp_filter_channel_x86(int32_t *state, const int32_t *coeff, 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; } diff --git a/ffmpeg/libavcodec/x86/mpegvideoencdsp.asm b/ffmpeg/libavcodec/x86/mpegvideoencdsp.asm index 4fe6cfe..aec73f8 100644 --- a/ffmpeg/libavcodec/x86/mpegvideoencdsp.asm +++ b/ffmpeg/libavcodec/x86/mpegvideoencdsp.asm @@ -29,16 +29,16 @@ cextern pw_1 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 @@ -52,42 +52,59 @@ cglobal pix_sum16, 2, %3, %1 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) diff --git a/ffmpeg/libavcodec/x86/mpegvideoencdsp_init.c b/ffmpeg/libavcodec/x86/mpegvideoencdsp_init.c index d91b902..2a4db61 100644 --- a/ffmpeg/libavcodec/x86/mpegvideoencdsp_init.c +++ b/ffmpeg/libavcodec/x86/mpegvideoencdsp_init.c @@ -24,6 +24,7 @@ #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); @@ -218,11 +219,17 @@ av_cold void ff_mpegvideoencdsp_init_x86(MpegvideoEncDSPContext *c, { 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; diff --git a/ffmpeg/libavcodec/x86/pngdsp.asm b/ffmpeg/libavcodec/x86/pngdsp.asm index 8e23ccf..678a032 100644 --- a/ffmpeg/libavcodec/x86/pngdsp.asm +++ b/ffmpeg/libavcodec/x86/pngdsp.asm @@ -42,12 +42,12 @@ cglobal add_bytes_l2, 4, 6, %1, dst, src1, src2, wa, w, i 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 diff --git a/ffmpeg/libavcodec/x86/svq1enc.asm b/ffmpeg/libavcodec/x86/svq1enc.asm index 5fb3361..24ee70f 100644 --- a/ffmpeg/libavcodec/x86/svq1enc.asm +++ b/ffmpeg/libavcodec/x86/svq1enc.asm @@ -29,7 +29,7 @@ cglobal ssd_int8_vs_int16, 3, 3, 3, pix1, pix2, size .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 diff --git a/ffmpeg/libavcodec/x86/v210enc.asm b/ffmpeg/libavcodec/x86/v210enc.asm new file mode 100644 index 0000000..3245de3 --- /dev/null +++ b/ffmpeg/libavcodec/x86/v210enc.asm @@ -0,0 +1,145 @@ +;****************************************************************************** +;* V210 SIMD pack +;* Copyright (c) 2014 Kieran Kunhya +;* +;* 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 diff --git a/ffmpeg/libavcodec/x86/v210enc_init.c b/ffmpeg/libavcodec/x86/v210enc_init.c new file mode 100644 index 0000000..3ac498a --- /dev/null +++ b/ffmpeg/libavcodec/x86/v210enc_init.c @@ -0,0 +1,37 @@ +/* + * 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; +} diff --git a/ffmpeg/libavcodec/x86/videodsp.asm b/ffmpeg/libavcodec/x86/videodsp.asm index 1ac0257..25d4364 100644 --- a/ffmpeg/libavcodec/x86/videodsp.asm +++ b/ffmpeg/libavcodec/x86/videodsp.asm @@ -97,7 +97,10 @@ cglobal emu_edge_hvar, 5, 6, 1, dst, dst_stride, start_x, n_words, h, w 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 @@ -107,6 +110,7 @@ cglobal emu_edge_hvar, 5, 6, 1, dst, dst_stride, start_x, n_words, h, w %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 @@ -127,6 +131,11 @@ hvar_fn 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 @@ -344,6 +353,9 @@ VERTICAL_EXTEND 16, 22 ; 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 @@ -354,6 +366,7 @@ VERTICAL_EXTEND 16, 22 punpckldq m0, m0 %endif ; mmsize == 16 %endif ; %1 > 16 +%endif ; avx2 %endmacro ; READ_V_PIXEL %macro WRITE_V_PIXEL 2 @@ -398,14 +411,22 @@ VERTICAL_EXTEND 16, 22 %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) @@ -426,6 +447,11 @@ H_EXTEND 16, 22 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: diff --git a/ffmpeg/libavcodec/x86/videodsp_init.c b/ffmpeg/libavcodec/x86/videodsp_init.c index 7668d0b..885cdf1 100644 --- a/ffmpeg/libavcodec/x86/videodsp_init.c +++ b/ffmpeg/libavcodec/x86/videodsp_init.c @@ -128,6 +128,23 @@ static emu_edge_hfix_func * const hfixtbl_sse2[11] = { 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, @@ -135,9 +152,9 @@ static av_always_inline void emulated_edge_mc(uint8_t *dst, const uint8_t *src, 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; @@ -238,6 +255,20 @@ static av_noinline void emulated_edge_mc_sse2(uint8_t *buf, const uint8_t *src, 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); @@ -267,5 +298,10 @@ av_cold void ff_videodsp_init_x86(VideoDSPContext *ctx, int bpc) 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 */ } diff --git a/ffmpeg/libavcodec/x86/vp9dsp_init.c b/ffmpeg/libavcodec/x86/vp9dsp_init.c index b04e678..2790024 100644 --- a/ffmpeg/libavcodec/x86/vp9dsp_init.c +++ b/ffmpeg/libavcodec/x86/vp9dsp_init.c @@ -43,22 +43,27 @@ fpel_func(avg, 8, mmxext); 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 @@ -68,7 +73,7 @@ mc_funcs(16); 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); \ @@ -76,81 +81,96 @@ ff_vp9_##avg##_8tap_1d_##dir##_##sz##_##opt(uint8_t *dst, ptrdiff_t dst_stride, 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 @@ -270,9 +290,12 @@ av_cold void ff_vp9dsp_init_x86(VP9DSPContext *dsp) 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) @@ -389,6 +412,8 @@ av_cold void ff_vp9dsp_init_x86(VP9DSPContext *dsp) 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); @@ -396,6 +421,18 @@ av_cold void ff_vp9dsp_init_x86(VP9DSPContext *dsp) } 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; diff --git a/ffmpeg/libavcodec/x86/vp9mc.asm b/ffmpeg/libavcodec/x86/vp9mc.asm index aa10001..59e636d 100644 --- a/ffmpeg/libavcodec/x86/vp9mc.asm +++ b/ffmpeg/libavcodec/x86/vp9mc.asm @@ -22,17 +22,17 @@ %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 @@ -90,9 +90,9 @@ cglobal vp9_%1_8tap_1d_h_ %+ %%px, 6, 6, 11, dst, dstride, src, sstride, h, filt 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] @@ -114,9 +114,9 @@ cglobal vp9_%1_8tap_1d_h_ %+ %%px, 6, 6, 11, dst, dstride, src, sstride, h, filt 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 @@ -150,9 +150,9 @@ filter_h_fn avg 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] @@ -198,6 +198,12 @@ INIT_XMM ssse3 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 @@ -215,9 +221,9 @@ cglobal vp9_%1_8tap_1d_v_ %+ %%px, 4, 7, 11, dst, dstride, src, sstride, filtery 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 @@ -243,9 +249,9 @@ cglobal vp9_%1_8tap_1d_v_ %+ %%px, 4, 7, 11, dst, dstride, src, sstride, filtery 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 @@ -283,9 +289,9 @@ cglobal vp9_%1_8tap_1d_v_ %+ %%px, 6, 8, 14, dst, dstride, src, sstride, h, filt 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 @@ -335,6 +341,12 @@ INIT_XMM ssse3 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 @@ -346,7 +358,7 @@ filter_vx2_fn avg %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] @@ -377,6 +389,8 @@ cglobal vp9_%1%2, 5, 5, 4, dst, dstride, src, sstride, h %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 @@ -391,5 +405,15 @@ INIT_XMM sse2 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 diff --git a/ffmpeg/libavcodec/x86/xvididct_mmx.c b/ffmpeg/libavcodec/x86/xvididct_mmx.c index f4bb39f..57aa8c0 100644 --- a/ffmpeg/libavcodec/x86/xvididct_mmx.c +++ b/ffmpeg/libavcodec/x86/xvididct_mmx.c @@ -46,6 +46,7 @@ #include "libavutil/mem.h" #include "libavcodec/avcodec.h" +#include "libavcodec/idctdsp.h" #include "idctdsp.h" #include "xvididct.h" @@ -497,13 +498,13 @@ void ff_xvid_idct_mmx(short *block) 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 */ @@ -536,13 +537,13 @@ void ff_xvid_idct_mmxext(short *block) 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 */ diff --git a/ffmpeg/libavcodec/x86/xvididct_sse2.c b/ffmpeg/libavcodec/x86/xvididct_sse2.c index 50a2f99..51a5d9d 100644 --- a/ffmpeg/libavcodec/x86/xvididct_sse2.c +++ b/ffmpeg/libavcodec/x86/xvididct_sse2.c @@ -41,6 +41,8 @@ #include "libavutil/mem.h" #include "libavutil/x86/asm.h" +#include "libavcodec/idctdsp.h" + #include "idctdsp.h" #include "xvididct.h" @@ -392,13 +394,13 @@ av_extern_inline void ff_xvid_idct_sse2(short *block) 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 */ diff --git a/ffmpeg/libavcodec/xface.h b/ffmpeg/libavcodec/xface.h index cd59ba0..63df5d3 100644 --- a/ffmpeg/libavcodec/xface.h +++ b/ffmpeg/libavcodec/xface.h @@ -40,11 +40,12 @@ /* * 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) @@ -84,8 +85,8 @@ enum XFaceColor { XFACE_COLOR_BLACK = 0, XFACE_COLOR_GREY, XFACE_COLOR_WHITE }; * 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]; diff --git a/ffmpeg/libavcodec/xfaceenc.c b/ffmpeg/libavcodec/xfaceenc.c index e213c9d..7edef1e 100644 --- a/ffmpeg/libavcodec/xfaceenc.c +++ b/ffmpeg/libavcodec/xfaceenc.c @@ -27,6 +27,7 @@ #include "xface.h" #include "avcodec.h" #include "internal.h" +#include "libavutil/avassert.h" typedef struct XFaceContext { AVClass *class; @@ -73,7 +74,7 @@ static int all_white(char *bitmap, int w, int h) } typedef struct { - const ProbRange *prob_ranges[XFACE_PIXELS*2]; + ProbRange prob_ranges[XFACE_PIXELS*2]; int prob_ranges_idx; } ProbRangesQueue; @@ -81,7 +82,7 @@ static inline int pq_push(ProbRangesQueue *pq, const ProbRange *p) { 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; } @@ -146,7 +147,7 @@ static int xface_encode_frame(AVCodecContext *avctx, AVPacket *pkt, 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; @@ -192,13 +193,15 @@ static int xface_encode_frame(AVCodecContext *avctx, AVPacket *pkt, 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; } diff --git a/ffmpeg/libavcodec/xiph.c b/ffmpeg/libavcodec/xiph.c index e63cec8..49b978d 100644 --- a/ffmpeg/libavcodec/xiph.c +++ b/ffmpeg/libavcodec/xiph.c @@ -21,7 +21,7 @@ #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]) { diff --git a/ffmpeg/libavcodec/xiph.h b/ffmpeg/libavcodec/xiph.h index 5c4dcc4..b8ddbbe 100644 --- a/ffmpeg/libavcodec/xiph.h +++ b/ffmpeg/libavcodec/xiph.h @@ -36,7 +36,7 @@ * @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]); diff --git a/ffmpeg/libavdevice/Makefile b/ffmpeg/libavdevice/Makefile index db301e7..6b8ab2e 100644 --- a/ffmpeg/libavdevice/Makefile +++ b/ffmpeg/libavdevice/Makefile @@ -16,7 +16,8 @@ OBJS-$(CONFIG_ALSA_OUTDEV) += alsa-audio-common.o \ 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 @@ -34,7 +35,7 @@ OBJS-$(CONFIG_OPENGL_OUTDEV) += opengl_enc.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 @@ -46,6 +47,7 @@ OBJS-$(CONFIG_V4L2_OUTDEV) += v4l2enc.o v4l2-common.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 @@ -57,7 +59,8 @@ OBJS-$(HAVE_LIBC_MSVCRT) += file_open.o # 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 diff --git a/ffmpeg/libavdevice/alldevices.c b/ffmpeg/libavdevice/alldevices.c index ca34959..26aecf2 100644 --- a/ffmpeg/libavdevice/alldevices.c +++ b/ffmpeg/libavdevice/alldevices.c @@ -50,7 +50,7 @@ void avdevice_register_all(void) 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); @@ -69,6 +69,7 @@ void avdevice_register_all(void) // REGISTER_INDEV (V4L, v4l REGISTER_INDEV (VFWCAP, vfwcap); REGISTER_INDEV (X11GRAB, x11grab); + REGISTER_INDEV (X11GRAB_XCB, x11grab_xcb); REGISTER_OUTDEV (XV, xv); /* external libraries */ diff --git a/ffmpeg/libavdevice/alsa-audio-common.c b/ffmpeg/libavdevice/alsa-audio-common.c index 4e63397..749897f 100644 --- a/ffmpeg/libavdevice/alsa-audio-common.c +++ b/ffmpeg/libavdevice/alsa-audio-common.c @@ -343,3 +343,55 @@ int ff_alsa_extend_reorder_buf(AlsaData *s, int min_size) 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; +} diff --git a/ffmpeg/libavdevice/alsa-audio-dec.c b/ffmpeg/libavdevice/alsa-audio-dec.c index 2cdf356..7f8f8cd 100644 --- a/ffmpeg/libavdevice/alsa-audio-dec.c +++ b/ffmpeg/libavdevice/alsa-audio-dec.c @@ -132,6 +132,11 @@ static int audio_read_packet(AVFormatContext *s1, AVPacket *pkt) 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 }, @@ -153,6 +158,7 @@ AVInputFormat ff_alsa_demuxer = { .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, }; diff --git a/ffmpeg/libavdevice/alsa-audio-enc.c b/ffmpeg/libavdevice/alsa-audio-enc.c index e42cc8f..43d097d 100644 --- a/ffmpeg/libavdevice/alsa-audio-enc.c +++ b/ffmpeg/libavdevice/alsa-audio-enc.c @@ -142,6 +142,11 @@ audio_get_output_timestamp(AVFormatContext *s1, int stream, *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, @@ -159,6 +164,7 @@ AVOutputFormat ff_alsa_muxer = { .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, diff --git a/ffmpeg/libavdevice/alsa-audio.h b/ffmpeg/libavdevice/alsa-audio.h index 583c911..cf0e942 100644 --- a/ffmpeg/libavdevice/alsa-audio.h +++ b/ffmpeg/libavdevice/alsa-audio.h @@ -99,4 +99,6 @@ int ff_alsa_xrun_recover(AVFormatContext *s1, int err); 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 */ diff --git a/ffmpeg/libavdevice/avdevice.c b/ffmpeg/libavdevice/avdevice.c index 6a75bd7..755f251 100644 --- a/ffmpeg/libavdevice/avdevice.c +++ b/ffmpeg/libavdevice/avdevice.c @@ -219,11 +219,11 @@ void avdevice_free_list_devices(AVDeviceInfoList **device_list) 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); } diff --git a/ffmpeg/libavdevice/avfoundation.m b/ffmpeg/libavdevice/avfoundation.m index 4ac50a0..1a7eb5b 100644 --- a/ffmpeg/libavdevice/avfoundation.m +++ b/ffmpeg/libavdevice/avfoundation.m @@ -30,12 +30,13 @@ #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, @@ -80,20 +81,44 @@ typedef struct { 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) @@ -152,17 +177,69 @@ static void unlock_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); @@ -172,99 +249,43 @@ static void destroy_context(AVFContext* ctx) } } -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 @@ -272,7 +293,7 @@ static int avf_read_header(AVFormatContext *s) if (!ctx->video_output) { av_log(s, AV_LOG_ERROR, "Failed to init AV video output\n"); - goto fail; + return 1; } // select pixel format @@ -290,7 +311,7 @@ static int avf_read_header(AVFormatContext *s) 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 @@ -323,14 +344,14 @@ static int avf_read_header(AVFormatContext *s) // 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]; @@ -348,10 +369,58 @@ static int avf_read_header(AVFormatContext *s) [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) { @@ -363,9 +432,11 @@ static int avf_read_header(AVFormatContext *s) 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); @@ -375,12 +446,265 @@ static int avf_read_header(AVFormatContext *s) 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; @@ -407,7 +731,7 @@ static int avf_read_packet(AVFormatContext *s, AVPacket *pkt) 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); @@ -418,6 +742,71 @@ static int avf_read_packet(AVFormatContext *s, AVPacket *pkt) 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); @@ -437,11 +826,11 @@ static int avf_close(AVFormatContext *s) } 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 }, }; diff --git a/ffmpeg/libavdevice/caca.c b/ffmpeg/libavdevice/caca.c index a118064..ff54940 100644 --- a/ffmpeg/libavdevice/caca.c +++ b/ffmpeg/libavdevice/caca.c @@ -135,8 +135,8 @@ static int caca_write_header(AVFormatContext *s) 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; } @@ -145,8 +145,8 @@ static int caca_write_header(AVFormatContext *s) 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; } @@ -164,9 +164,9 @@ static int caca_write_header(AVFormatContext *s) 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; } diff --git a/ffmpeg/libavdevice/decklink_common.cpp b/ffmpeg/libavdevice/decklink_common.cpp new file mode 100644 index 0000000..07e1651 --- /dev/null +++ b/ffmpeg/libavdevice/decklink_common.cpp @@ -0,0 +1,231 @@ +/* + * 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 +#ifdef _WIN32 +#include +#else +#include +#endif + +#include +#include + +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; +} diff --git a/ffmpeg/libavdevice/decklink_common.h b/ffmpeg/libavdevice/decklink_common.h new file mode 100644 index 0000000..96912a7 --- /dev/null +++ b/ffmpeg/libavdevice/decklink_common.h @@ -0,0 +1,97 @@ +/* + * 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); + diff --git a/ffmpeg/libavdevice/decklink_common_c.h b/ffmpeg/libavdevice/decklink_common_c.h new file mode 100644 index 0000000..861a51a --- /dev/null +++ b/ffmpeg/libavdevice/decklink_common_c.h @@ -0,0 +1,32 @@ +/* + * 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; +}; + diff --git a/ffmpeg/libavdevice/decklink_dec.cpp b/ffmpeg/libavdevice/decklink_dec.cpp new file mode 100644 index 0000000..77a0fe5 --- /dev/null +++ b/ffmpeg/libavdevice/decklink_dec.cpp @@ -0,0 +1,531 @@ +/* + * 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 + +#include +#include + +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" */ diff --git a/ffmpeg/libavdevice/decklink_dec.h b/ffmpeg/libavdevice/decklink_dec.h new file mode 100644 index 0000000..6bd9226 --- /dev/null +++ b/ffmpeg/libavdevice/decklink_dec.h @@ -0,0 +1,32 @@ +/* + * 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 diff --git a/ffmpeg/libavdevice/decklink_dec_c.c b/ffmpeg/libavdevice/decklink_dec_c.c new file mode 100644 index 0000000..2aea277 --- /dev/null +++ b/ffmpeg/libavdevice/decklink_dec_c.c @@ -0,0 +1,54 @@ +/* + * 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, +}; diff --git a/ffmpeg/libavdevice/decklink_enc.cpp b/ffmpeg/libavdevice/decklink_enc.cpp index 3d7cbe2..6c5450f 100644 --- a/ffmpeg/libavdevice/decklink_enc.cpp +++ b/ffmpeg/libavdevice/decklink_enc.cpp @@ -20,13 +20,6 @@ */ #include -#ifdef _WIN32 -#include -typedef unsigned long buffercount_type; -#else -#include -typedef uint32_t buffercount_type; -#endif #include #include @@ -37,44 +30,9 @@ extern "C" { #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 @@ -109,7 +67,7 @@ private: int _refs; }; -class decklink_callback : public IDeckLinkVideoOutputCallback +class decklink_output_callback : public IDeckLinkVideoOutputCallback { public: virtual HRESULT STDMETHODCALLTYPE ScheduledFrameCompleted(IDeckLinkVideoFrame *_frame, BMDOutputFrameCompletionResult result) @@ -130,99 +88,6 @@ public: 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; @@ -239,7 +104,7 @@ static int decklink_setup_video(AVFormatContext *avctx, AVStream *st) " 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"); @@ -252,8 +117,8 @@ static int decklink_setup_video(AVFormatContext *avctx, AVStream *st) } /* 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; @@ -333,8 +198,8 @@ av_cold int ff_decklink_write_trailer(AVFormatContext *avctx) if (ctx->dl) ctx->dl->Release(); - if (ctx->callback) - delete ctx->callback; + if (ctx->output_callback) + delete ctx->output_callback; sem_destroy(&ctx->semaphore); @@ -450,6 +315,7 @@ av_cold int ff_decklink_write_header(AVFormatContext *avctx) { struct decklink_cctx *cctx = (struct decklink_cctx *) avctx->priv_data; struct decklink_ctx *ctx; + IDeckLinkDisplayModeIterator *itermode; IDeckLinkIterator *iter; IDeckLink *dl = NULL; unsigned int n; @@ -470,22 +336,14 @@ av_cold int ff_decklink_write_header(AVFormatContext *avctx) /* 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; @@ -508,40 +366,20 @@ av_cold int ff_decklink_write_header(AVFormatContext *avctx) 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]; @@ -557,7 +395,7 @@ av_cold int ff_decklink_write_header(AVFormatContext *avctx) goto error; } } - ctx->itermode->Release(); + itermode->Release(); return 0; diff --git a/ffmpeg/libavdevice/decklink_enc.h b/ffmpeg/libavdevice/decklink_enc.h index 0b9ad8f..6086947 100644 --- a/ffmpeg/libavdevice/decklink_enc.h +++ b/ffmpeg/libavdevice/decklink_enc.h @@ -19,17 +19,6 @@ * 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 diff --git a/ffmpeg/libavdevice/decklink_enc_c.c b/ffmpeg/libavdevice/decklink_enc_c.c index 7c18043..c3c9018 100644 --- a/ffmpeg/libavdevice/decklink_enc_c.c +++ b/ffmpeg/libavdevice/decklink_enc_c.c @@ -22,6 +22,7 @@ #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) diff --git a/ffmpeg/libavdevice/dshow.c b/ffmpeg/libavdevice/dshow.c index a543249..59d0818 100644 --- a/ffmpeg/libavdevice/dshow.c +++ b/ffmpeg/libavdevice/dshow.c @@ -19,13 +19,13 @@ * 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 { diff --git a/ffmpeg/libavdevice/dshow_capture.h b/ffmpeg/libavdevice/dshow_capture.h index e4b4dce..0252070 100644 --- a/ffmpeg/libavdevice/dshow_capture.h +++ b/ffmpeg/libavdevice/dshow_capture.h @@ -27,6 +27,7 @@ #include "avdevice.h" #define COBJMACROS +#define WIN32_LEAN_AND_MEAN #include #define NO_DSHOW_STRSAFE #include diff --git a/ffmpeg/libavdevice/fbdev_common.c b/ffmpeg/libavdevice/fbdev_common.c index 634780d..98f96de 100644 --- a/ffmpeg/libavdevice/fbdev_common.c +++ b/ffmpeg/libavdevice/fbdev_common.c @@ -84,8 +84,13 @@ int ff_fbdev_get_device_list(AVDeviceInfoList *device_list) 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) @@ -116,8 +121,8 @@ int ff_fbdev_get_device_list(AVDeviceInfoList *device_list) 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) diff --git a/ffmpeg/libavdevice/fbdev_dec.c b/ffmpeg/libavdevice/fbdev_dec.c index 1593b10..f56408c 100644 --- a/ffmpeg/libavdevice/fbdev_dec.c +++ b/ffmpeg/libavdevice/fbdev_dec.c @@ -68,6 +68,7 @@ static av_cold int fbdev_read_header(AVFormatContext *avctx) 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); @@ -77,11 +78,16 @@ static av_cold int fbdev_read_header(AVFormatContext *avctx) 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; } @@ -175,9 +181,10 @@ static int fbdev_read_packet(AVFormatContext *avctx, AVPacket *pkt) 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; diff --git a/ffmpeg/libavdevice/iec61883.c b/ffmpeg/libavdevice/iec61883.c index 6d5ec4a..b29aad1 100644 --- a/ffmpeg/libavdevice/iec61883.c +++ b/ffmpeg/libavdevice/iec61883.c @@ -219,8 +219,8 @@ static int iec61883_parse_queue_hdv(struct iec61883_data *dv, AVPacket *pkt) 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) @@ -350,7 +350,7 @@ static int iec61883_read_header(AVFormatContext *context) if (!dv->max_packets) dv->max_packets = 100; - if (dv->type == IEC61883_HDV) { + if (CONFIG_MPEGTS_DEMUXER && dv->type == IEC61883_HDV) { /* Init HDV receive */ @@ -444,7 +444,7 @@ static int iec61883_close(AVFormatContext *context) 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); @@ -455,8 +455,8 @@ static int iec61883_close(AVFormatContext *context) 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, diff --git a/ffmpeg/libavdevice/jack_audio.c b/ffmpeg/libavdevice/jack_audio.c index 2fda8ad..0c52a8e 100644 --- a/ffmpeg/libavdevice/jack_audio.c +++ b/ffmpeg/libavdevice/jack_audio.c @@ -287,8 +287,11 @@ static int audio_read_packet(AVFormatContext *context, AVPacket *pkt) 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"); diff --git a/ffmpeg/libavdevice/opengl_enc.c b/ffmpeg/libavdevice/opengl_enc.c index 5f5b800..434ae97 100644 --- a/ffmpeg/libavdevice/opengl_enc.c +++ b/ffmpeg/libavdevice/opengl_enc.c @@ -31,6 +31,7 @@ #include "config.h" #if HAVE_WINDOWS_H +#define WIN32_LEAN_AND_MEAN #include #endif #if HAVE_OPENGL_GL3_H diff --git a/ffmpeg/libavdevice/oss_audio.c b/ffmpeg/libavdevice/oss_audio.c index 951acbc..1f8b5e7 100644 --- a/ffmpeg/libavdevice/oss_audio.c +++ b/ffmpeg/libavdevice/oss_audio.c @@ -55,7 +55,7 @@ int ff_oss_audio_open(AVFormatContext *s1, int is_output, 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); } @@ -66,7 +66,7 @@ int ff_oss_audio_open(AVFormatContext *s1, int is_output, /* 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))); } } @@ -74,17 +74,17 @@ int ff_oss_audio_open(AVFormatContext *s1, int is_output, #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 diff --git a/ffmpeg/libavdevice/pulse_audio_common.c b/ffmpeg/libavdevice/pulse_audio_common.c index 5a2568b..4046641 100644 --- a/ffmpeg/libavdevice/pulse_audio_common.c +++ b/ffmpeg/libavdevice/pulse_audio_common.c @@ -163,8 +163,8 @@ static void pulse_add_detected_device(PulseAudioDeviceList *info, 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); } diff --git a/ffmpeg/libavdevice/v4l2-common.c b/ffmpeg/libavdevice/v4l2-common.c index c4c75d7..196c09b 100644 --- a/ffmpeg/libavdevice/v4l2-common.c +++ b/ffmpeg/libavdevice/v4l2-common.c @@ -18,7 +18,7 @@ #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 }, @@ -46,6 +46,9 @@ const struct fmt_map avpriv_fmt_conversion_table[] = { #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 @@ -58,43 +61,43 @@ const struct fmt_map avpriv_fmt_conversion_table[] = { { 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; } } diff --git a/ffmpeg/libavdevice/v4l2-common.h b/ffmpeg/libavdevice/v4l2-common.h index 8aef234..40c7164 100644 --- a/ffmpeg/libavdevice/v4l2-common.h +++ b/ffmpeg/libavdevice/v4l2-common.h @@ -53,10 +53,10 @@ struct fmt_map { 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 */ diff --git a/ffmpeg/libavdevice/v4l2.c b/ffmpeg/libavdevice/v4l2.c index cf7a92c..8695645 100644 --- a/ffmpeg/libavdevice/v4l2.c +++ b/ffmpeg/libavdevice/v4l2.c @@ -67,7 +67,7 @@ static const int desired_video_buffers = 256; 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; @@ -108,7 +108,7 @@ static int device_open(AVFormatContext *ctx) 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 { \ @@ -146,16 +146,16 @@ static int device_open(AVFormatContext *ctx) 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; } @@ -164,14 +164,14 @@ static int device_open(AVFormatContext *ctx) 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; } @@ -179,22 +179,23 @@ static int device_open(AVFormatContext *ctx) 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); @@ -206,11 +207,11 @@ static int device_init(AVFormatContext *ctx, int *width, int *height, *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); } @@ -270,8 +271,8 @@ static void list_formats(AVFormatContext *ctx, int type) 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++; @@ -505,7 +506,8 @@ static int mmap_read_frame(AVFormatContext *ctx, AVPacket *pkt) 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; } @@ -601,7 +603,8 @@ static int mmap_start(AVFormatContext *ctx) 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; } } @@ -610,7 +613,8 @@ static int mmap_start(AVFormatContext *ctx) 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; } @@ -727,7 +731,8 @@ static int v4l2_set_parameters(AVFormatContext *ctx) 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; } @@ -763,7 +768,7 @@ static int device_try_init(AVFormatContext *ctx, { 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); @@ -775,14 +780,14 @@ static int device_try_init(AVFormatContext *ctx, } 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; @@ -801,11 +806,18 @@ static int device_try_init(AVFormatContext *ctx, } } - *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; @@ -873,9 +885,6 @@ static int v4l2_read_header(AVFormatContext *ctx) 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); @@ -900,7 +909,8 @@ static int v4l2_read_header(AVFormatContext *ctx) "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; } @@ -924,9 +934,12 @@ static int v4l2_read_header(AVFormatContext *ctx) 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); @@ -1033,6 +1046,7 @@ AVInputFormat ff_v4l2_demuxer = { .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, diff --git a/ffmpeg/libavdevice/v4l2enc.c b/ffmpeg/libavdevice/v4l2enc.c index c9f8d92..ac4068c 100644 --- a/ffmpeg/libavdevice/v4l2enc.c +++ b/ffmpeg/libavdevice/v4l2enc.c @@ -56,7 +56,7 @@ static av_cold int write_header(AVFormatContext *s1) 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)); diff --git a/ffmpeg/libavdevice/version.h b/ffmpeg/libavdevice/version.h index 4529c64..3e427f0 100644 --- a/ffmpeg/libavdevice/version.h +++ b/ffmpeg/libavdevice/version.h @@ -28,7 +28,7 @@ #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, \ diff --git a/ffmpeg/libavdevice/x11grab.c b/ffmpeg/libavdevice/x11grab.c index 1481e7d..3a833eb 100644 --- a/ffmpeg/libavdevice/x11grab.c +++ b/ffmpeg/libavdevice/x11grab.c @@ -172,6 +172,19 @@ static int setup_shm(AVFormatContext *s, Display *dpy, XImage **image) 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, @@ -326,6 +339,12 @@ static int x11grab_read_header(AVFormatContext *s1) 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); @@ -391,14 +410,6 @@ static void paint_mouse_pointer(XImage *image, AVFormatContext *s1) 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) @@ -406,14 +417,14 @@ static void paint_mouse_pointer(XImage *image, AVFormatContext *s1) 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; } @@ -509,8 +520,8 @@ static int x11grab_read_packet(AVFormatContext *s1, AVPacket *pkt) 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; @@ -548,14 +559,16 @@ static int x11grab_read_packet(AVFormatContext *s1, AVPacket *pkt) 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; @@ -582,7 +595,7 @@ static int x11grab_read_packet(AVFormatContext *s1, AVPacket *pkt) 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. @@ -604,7 +617,7 @@ static int x11grab_read_packet(AVFormatContext *s1, AVPacket *pkt) 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; diff --git a/ffmpeg/libavdevice/xcbgrab.c b/ffmpeg/libavdevice/xcbgrab.c new file mode 100644 index 0000000..df8de20 --- /dev/null +++ b/ffmpeg/libavdevice/xcbgrab.c @@ -0,0 +1,672 @@ +/* + * XCB input grabber + * Copyright (C) 2014 Luca Barbato + * + * 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 +#include + +#if CONFIG_LIBXCB_XFIXES +#include +#endif + +#if CONFIG_LIBXCB_SHM +#include +#include +#endif + +#if CONFIG_LIBXCB_SHAPE +#include +#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, +}; diff --git a/ffmpeg/libavfilter/Makefile b/ffmpeg/libavfilter/Makefile index 3241b76..2c56e38 100644 --- a/ffmpeg/libavfilter/Makefile +++ b/ffmpeg/libavfilter/Makefile @@ -29,7 +29,6 @@ OBJS = allfilters.o \ 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 @@ -199,6 +198,7 @@ OBJS-$(CONFIG_VIDSTABDETECT_FILTER) += vidstabutils.o vf_vidstabdetect. 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 diff --git a/ffmpeg/libavfilter/af_aconvert.c b/ffmpeg/libavfilter/af_aconvert.c deleted file mode 100644 index 19095cb..0000000 --- a/ffmpeg/libavfilter/af_aconvert.c +++ /dev/null @@ -1,196 +0,0 @@ -/* - * Copyright (c) 2010 S.N. Hemanth Meenakshisundaram - * 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, -}; diff --git a/ffmpeg/libavfilter/af_adelay.c b/ffmpeg/libavfilter/af_adelay.c index cfc6b1f..ef60f43 100644 --- a/ffmpeg/libavfilter/af_adelay.c +++ b/ffmpeg/libavfilter/af_adelay.c @@ -246,7 +246,7 @@ static av_cold void uninit(AVFilterContext *ctx) 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); } diff --git a/ffmpeg/libavfilter/af_afade.c b/ffmpeg/libavfilter/af_afade.c index fbf9802..806f6f6 100644 --- a/ffmpeg/libavfilter/af_afade.c +++ b/ffmpeg/libavfilter/af_afade.c @@ -230,7 +230,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *buf) 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))) diff --git a/ffmpeg/libavfilter/af_amix.c b/ffmpeg/libavfilter/af_amix.c index d8a6651..e40969f 100644 --- a/ffmpeg/libavfilter/af_amix.c +++ b/ffmpeg/libavfilter/af_amix.c @@ -155,7 +155,7 @@ static int frame_list_add_frame(FrameList *frame_list, int nb_samples, int64_t p 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 */ @@ -298,7 +298,7 @@ static int output_frame(AVFilterLink *outlink, int nb_samples) 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); } @@ -501,7 +501,9 @@ static av_cold int init(AVFilterContext *ctx) 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; } @@ -520,6 +522,7 @@ static av_cold void uninit(AVFilterContext *ctx) 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); @@ -528,10 +531,17 @@ static av_cold void uninit(AVFilterContext *ctx) 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; } diff --git a/ffmpeg/libavfilter/af_aresample.c b/ffmpeg/libavfilter/af_aresample.c index 5f34321..57ac397 100644 --- a/ffmpeg/libavfilter/af_aresample.c +++ b/ffmpeg/libavfilter/af_aresample.c @@ -41,6 +41,7 @@ typedef struct { struct SwrContext *swr; int64_t next_pts; int req_fullfilled; + int more_data; } AResampleContext; static av_cold int init_dict(AVFilterContext *ctx, AVDictionary **opts) @@ -103,6 +104,11 @@ static int query_formats(AVFilterContext *ctx) } 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) { @@ -181,7 +187,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *insamplesref) 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); @@ -210,6 +216,8 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *insamplesref) 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); @@ -218,40 +226,65 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *insamplesref) 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); } diff --git a/ffmpeg/libavfilter/af_channelmap.c b/ffmpeg/libavfilter/af_channelmap.c index 0bf2fe9..c3454c5 100644 --- a/ffmpeg/libavfilter/af_channelmap.c +++ b/ffmpeg/libavfilter/af_channelmap.c @@ -287,10 +287,16 @@ static av_cold int channelmap_init(AVFilterContext *ctx) 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; diff --git a/ffmpeg/libavfilter/af_join.c b/ffmpeg/libavfilter/af_join.c index 560c5c8..a1717c6 100644 --- a/ffmpeg/libavfilter/af_join.c +++ b/ffmpeg/libavfilter/af_join.c @@ -248,9 +248,12 @@ static int join_query_formats(AVFilterContext *ctx) 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()); diff --git a/ffmpeg/libavfilter/af_resample.c b/ffmpeg/libavfilter/af_resample.c index f4b396a..d65d4bc 100644 --- a/ffmpeg/libavfilter/af_resample.c +++ b/ffmpeg/libavfilter/af_resample.c @@ -135,11 +135,14 @@ static int config_output(AVFilterLink *outlink) 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); diff --git a/ffmpeg/libavfilter/af_volume.c b/ffmpeg/libavfilter/af_volume.c index 9900d22..4809ae7 100644 --- a/ffmpeg/libavfilter/af_volume.c +++ b/ffmpeg/libavfilter/af_volume.c @@ -111,6 +111,11 @@ static int set_expr(AVExpr **pexpr, const char *expr, void *log_ctx) 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); } @@ -119,6 +124,7 @@ static av_cold void uninit(AVFilterContext *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) @@ -233,11 +239,9 @@ static av_cold void volume_init(VolumeContext *vol) 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; } @@ -428,13 +432,13 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *buf) } } 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); } diff --git a/ffmpeg/libavfilter/af_volume.h b/ffmpeg/libavfilter/af_volume.h index e78e042..53a328e 100644 --- a/ffmpeg/libavfilter/af_volume.h +++ b/ffmpeg/libavfilter/af_volume.h @@ -67,7 +67,7 @@ enum ReplayGainType { typedef struct VolumeContext { const AVClass *class; - AVFloatDSPContext fdsp; + AVFloatDSPContext *fdsp; enum PrecisionType precision; enum EvalMode eval_mode; const char *volume_expr; diff --git a/ffmpeg/libavfilter/allfilters.c b/ffmpeg/libavfilter/allfilters.c index 670f2d1..2352d44 100644 --- a/ffmpeg/libavfilter/allfilters.c +++ b/ffmpeg/libavfilter/allfilters.c @@ -45,9 +45,6 @@ void avfilter_register_all(void) 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); @@ -216,6 +213,7 @@ void avfilter_register_all(void) 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); diff --git a/ffmpeg/libavfilter/avcodec.c b/ffmpeg/libavfilter/avcodec.c index ba11a25..e0d9015 100644 --- a/ffmpeg/libavfilter/avcodec.c +++ b/ffmpeg/libavfilter/avcodec.c @@ -135,23 +135,3 @@ int avfilter_copy_buf_props(AVFrame *dst, const AVFilterBufferRef *src) 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 diff --git a/ffmpeg/libavfilter/avcodec.h b/ffmpeg/libavfilter/avcodec.h index 8bbdad2..d3d0e20 100644 --- a/ffmpeg/libavfilter/avcodec.h +++ b/ffmpeg/libavfilter/avcodec.h @@ -66,45 +66,4 @@ AVFilterBufferRef *avfilter_get_buffer_ref_from_frame(enum AVMediaType type, 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 */ diff --git a/ffmpeg/libavfilter/avf_concat.c b/ffmpeg/libavfilter/avf_concat.c index 18f373c..088d782 100644 --- a/ffmpeg/libavfilter/avf_concat.c +++ b/ffmpeg/libavfilter/avf_concat.c @@ -59,7 +59,7 @@ typedef struct { 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 }, @@ -409,7 +409,7 @@ static av_cold void uninit(AVFilterContext *ctx) } 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 = { diff --git a/ffmpeg/libavfilter/avf_showwaves.c b/ffmpeg/libavfilter/avf_showwaves.c index 4cd225a..fa34a52 100644 --- a/ffmpeg/libavfilter/avf_showwaves.c +++ b/ffmpeg/libavfilter/avf_showwaves.c @@ -157,7 +157,7 @@ inline static int push_frame(AVFilterLink *outlink) 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; } diff --git a/ffmpeg/libavfilter/avfilter.c b/ffmpeg/libavfilter/avfilter.c index 7b11467..963f5e6 100644 --- a/ffmpeg/libavfilter/avfilter.c +++ b/ffmpeg/libavfilter/avfilter.c @@ -227,6 +227,11 @@ int avfilter_config_links(AVFilterContext *filter) 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; @@ -381,8 +386,23 @@ int ff_poll_frame(AVFilterLink *link) 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) { @@ -1071,6 +1091,8 @@ static int ff_filter_frame_framed(AVFilterLink *link, AVFrame *frame) 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; diff --git a/ffmpeg/libavfilter/avfiltergraph.c b/ffmpeg/libavfilter/avfiltergraph.c index 9178939..a859ecb 100644 --- a/ffmpeg/libavfilter/avfiltergraph.c +++ b/ffmpeg/libavfilter/avfiltergraph.c @@ -559,7 +559,9 @@ static int query_formats(AVFilterGraph *graph, AVClass *log_ctx) 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); diff --git a/ffmpeg/libavfilter/formats.c b/ffmpeg/libavfilter/formats.c index 8160429..eb3b87a 100644 --- a/ffmpeg/libavfilter/formats.c +++ b/ffmpeg/libavfilter/formats.c @@ -314,14 +314,18 @@ AVFilterChannelLayouts *avfilter_make_format64_list(const int64_t *fmts) #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; \ @@ -490,7 +494,7 @@ void ff_formats_changeref(AVFilterFormats **oldref, AVFilterFormats **newref) } #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++) { \ diff --git a/ffmpeg/libavfilter/graphparser.c b/ffmpeg/libavfilter/graphparser.c index 7e25282..5180bd5 100644 --- a/ffmpeg/libavfilter/graphparser.c +++ b/ffmpeg/libavfilter/graphparser.c @@ -241,8 +241,8 @@ static int link_filter_inouts(AVFilterContext *filt_ctx, 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 { @@ -344,10 +344,10 @@ static int parse_outputs(const char **buf, AVFilterInOut **curr_inputs, 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; diff --git a/ffmpeg/libavfilter/interlace.h b/ffmpeg/libavfilter/interlace.h new file mode 100644 index 0000000..44f1e06 --- /dev/null +++ b/ffmpeg/libavfilter/interlace.h @@ -0,0 +1,58 @@ +/* + * 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 */ diff --git a/ffmpeg/libavfilter/libmpcodecs/vf_eq.c b/ffmpeg/libavfilter/libmpcodecs/vf_eq.c index f8efa84..7be1674 100644 --- a/ffmpeg/libavfilter/libmpcodecs/vf_eq.c +++ b/ffmpeg/libavfilter/libmpcodecs/vf_eq.c @@ -37,7 +37,7 @@ struct vf_priv_s { 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) { @@ -224,7 +224,7 @@ static int vf_open(vf_instance_t *vf, char *args) 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 diff --git a/ffmpeg/libavfilter/libmpcodecs/vf_eq2.c b/ffmpeg/libavfilter/libmpcodecs/vf_eq2.c index 0356813..d0a2b92 100644 --- a/ffmpeg/libavfilter/libmpcodecs/vf_eq2.c +++ b/ffmpeg/libavfilter/libmpcodecs/vf_eq2.c @@ -120,7 +120,7 @@ void create_lut (eq2_param_t *par) 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) @@ -289,7 +289,7 @@ void check_values (eq2_param_t *par) 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; } diff --git a/ffmpeg/libavfilter/libmpcodecs/vf_fspp.c b/ffmpeg/libavfilter/libmpcodecs/vf_fspp.c index c4a36ef..d457859 100644 --- a/ffmpeg/libavfilter/libmpcodecs/vf_fspp.c +++ b/ffmpeg/libavfilter/libmpcodecs/vf_fspp.c @@ -101,7 +101,7 @@ struct vf_priv_s { //align 16 ! }; -#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) @@ -177,7 +177,7 @@ static void row_fdct_c(int16_t *data, const uint8_t *pixels, int line_size, int #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) @@ -404,7 +404,7 @@ static void row_fdct_mmx(int16_t *data, const uint8_t *pixels, int line_size, #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, @@ -563,10 +563,10 @@ static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts) } } -#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); @@ -707,7 +707,7 @@ const vf_info_t ff_vf_info_fspp = { #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); @@ -728,7 +728,7 @@ DECLARE_ASM_CONST(8, uint64_t, MM_FIX_0_198912367)=FIX64(0.198912367, 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); @@ -743,7 +743,7 @@ static const int16_t FIX_1_082392200=FIX(1.082392200, 13); #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) { @@ -868,7 +868,7 @@ static void column_fidct_c(int16_t* thr_adr, int16_t *data, int16_t *output, int } } -#else /* HAVE_MMX */ +#else /* HAVE_MMX_INLINE */ static void column_fidct_mmx(int16_t* thr_adr, int16_t *data, int16_t *output, int cnt) { @@ -1605,9 +1605,9 @@ static void column_fidct_mmx(int16_t* thr_adr, int16_t *data, int16_t *output, ); } -#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) @@ -1672,7 +1672,7 @@ static void row_idct_c(int16_t* workspace, } } -#else /* HAVE_MMX */ +#else /* HAVE_MMX_INLINE */ static void row_idct_mmx (int16_t* workspace, int16_t* output_adr, int output_stride, int cnt) @@ -1876,9 +1876,9 @@ static void row_idct_mmx (int16_t* workspace, ); } -#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) { @@ -1941,7 +1941,7 @@ static void row_fdct_c(int16_t *data, const uint8_t *pixels, int line_size, int } } -#else /* HAVE_MMX */ +#else /* HAVE_MMX_INLINE */ static void row_fdct_mmx(int16_t *data, const uint8_t *pixels, int line_size, int cnt) { @@ -2121,4 +2121,4 @@ static void row_fdct_mmx(int16_t *data, const uint8_t *pixels, int line_size, : "%"REG_d); } -#endif // HAVE_MMX +#endif // HAVE_MMX_INLINE diff --git a/ffmpeg/libavfilter/libmpcodecs/vf_ilpack.c b/ffmpeg/libavfilter/libmpcodecs/vf_ilpack.c index fbf5817..d92b0ae 100644 --- a/ffmpeg/libavfilter/libmpcodecs/vf_ilpack.c +++ b/ffmpeg/libavfilter/libmpcodecs/vf_ilpack.c @@ -78,7 +78,7 @@ static void pack_li_1_C(unsigned char *dst, unsigned char *y, } } -#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) @@ -420,7 +420,7 @@ static int vf_open(vf_instance_t *vf, char *args) 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 diff --git a/ffmpeg/libavfilter/libmpcodecs/vf_pp7.c b/ffmpeg/libavfilter/libmpcodecs/vf_pp7.c index 89ed4fe..0283e5d 100644 --- a/ffmpeg/libavfilter/libmpcodecs/vf_pp7.c +++ b/ffmpeg/libavfilter/libmpcodecs/vf_pp7.c @@ -155,7 +155,7 @@ static void dctB_c(int16_t *dst, int16_t *src){ } } -#if HAVE_MMX +#if HAVE_MMX_INLINE static void dctB_mmx(int16_t *dst, int16_t *src){ __asm__ volatile ( "movq (%0), %%mm0 \n\t" @@ -397,10 +397,10 @@ static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){ 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 @@ -464,7 +464,7 @@ static int vf_open(vf_instance_t *vf, char *args){ case 2: requantize= mediumthresh_c; break; } -#if HAVE_MMX +#if HAVE_MMX_INLINE if(ff_gCpuCaps.hasMMX){ dctB= dctB_mmx; } diff --git a/ffmpeg/libavfilter/libmpcodecs/vf_uspp.c b/ffmpeg/libavfilter/libmpcodecs/vf_uspp.c index c9d9c1f..fb4329d 100644 --- a/ffmpeg/libavfilter/libmpcodecs/vf_uspp.c +++ b/ffmpeg/libavfilter/libmpcodecs/vf_uspp.c @@ -297,10 +297,10 @@ static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){ } } -#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 @@ -375,7 +375,7 @@ static int vf_open(vf_instance_t *vf, char *args){ 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; // } diff --git a/ffmpeg/libavfilter/tinterlace.h b/ffmpeg/libavfilter/tinterlace.h new file mode 100644 index 0000000..fa0a83a --- /dev/null +++ b/ffmpeg/libavfilter/tinterlace.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2011 Stefano Sabatini + * Copyright (c) 2010 Baptiste Coudurier + * Copyright (c) 2003 Michael Zucchi + * + * 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 */ diff --git a/ffmpeg/libavfilter/version.h b/ffmpeg/libavfilter/version.h index 6ebb1ce..6f61aee 100644 --- a/ffmpeg/libavfilter/version.h +++ b/ffmpeg/libavfilter/version.h @@ -30,8 +30,8 @@ #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, \ @@ -55,21 +55,12 @@ #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 @@ -82,9 +73,6 @@ #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 diff --git a/ffmpeg/libavfilter/vf_drawtext.c b/ffmpeg/libavfilter/vf_drawtext.c index 5b725d6..d20f805 100644 --- a/ffmpeg/libavfilter/vf_drawtext.c +++ b/ffmpeg/libavfilter/vf_drawtext.c @@ -52,6 +52,7 @@ #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" @@ -177,11 +178,6 @@ typedef struct DrawTextContext { 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 @@ -216,9 +212,6 @@ static const AVOption drawtext_options[]= { {"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 @@ -485,7 +478,7 @@ static int load_textfile(AVFilterContext *ctx) 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); } @@ -596,12 +589,6 @@ static av_cold int init(AVFilterContext *ctx) 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); @@ -713,12 +700,7 @@ static av_cold void uninit(AVFilterContext *ctx) 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; @@ -761,12 +743,7 @@ static int config_input(AVFilterLink *inlink) 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 || @@ -774,12 +751,6 @@ static int config_input(AVFilterLink *inlink) 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; } @@ -873,13 +844,6 @@ static int func_metadata(AVFilterContext *ctx, AVBPrint *bp, 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) { @@ -891,7 +855,7 @@ static int func_strftime(AVFilterContext *ctx, AVBPrint *bp, if (tag == 'L') localtime_r(&now, &tm); else - tm = *gmtime(&now); + tm = *gmtime_r(&now, &tm); av_bprint_strftime(bp, fmt, &tm); return 0; } @@ -1273,16 +1237,6 @@ static int draw_text(AVFilterContext *ctx, AVFrame *frame, 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); @@ -1375,9 +1329,5 @@ AVFilter ff_vf_drawtext = { .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 }; diff --git a/ffmpeg/libavfilter/vf_format.c b/ffmpeg/libavfilter/vf_format.c index 13b41e4..96cb7fd 100644 --- a/ffmpeg/libavfilter/vf_format.c +++ b/ffmpeg/libavfilter/vf_format.c @@ -60,8 +60,10 @@ static av_cold int init(AVFilterContext *ctx) 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; diff --git a/ffmpeg/libavfilter/vf_idet.c b/ffmpeg/libavfilter/vf_idet.c index 22ff494..9a25042 100644 --- a/ffmpeg/libavfilter/vf_idet.c +++ b/ffmpeg/libavfilter/vf_idet.c @@ -32,6 +32,8 @@ 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 } }; @@ -40,10 +42,43 @@ AVFILTER_DEFINE_CLASS(idet); 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; } @@ -80,8 +115,11 @@ static void filter(AVFilterContext *ctx) 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; @@ -100,6 +138,7 @@ static void filter(AVFilterContext *ctx) 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); } } @@ -108,11 +147,19 @@ static void filter(AVFilterContext *ctx) }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; @@ -141,13 +188,46 @@ static void filter(AVFilterContext *ctx) }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) @@ -161,11 +241,12 @@ 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); @@ -180,22 +261,56 @@ static int filter_frame(AVFilterLink *link, AVFrame *picref) 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 ); @@ -242,9 +357,15 @@ static av_cold int init(AVFilterContext *ctx) { 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) @@ -253,7 +374,6 @@ static av_cold int init(AVFilterContext *ctx) return 0; } - static const AVFilterPad idet_inputs[] = { { .name = "default", @@ -268,6 +388,7 @@ static const AVFilterPad idet_outputs[] = { .name = "default", .type = AVMEDIA_TYPE_VIDEO, .config_props = config_output, + .request_frame = request_frame }, { NULL } }; diff --git a/ffmpeg/libavfilter/vf_idet.h b/ffmpeg/libavfilter/vf_idet.h index c5799fb..af759b4 100644 --- a/ffmpeg/libavfilter/vf_idet.h +++ b/ffmpeg/libavfilter/vf_idet.h @@ -29,18 +29,32 @@ typedef int (*ff_idet_filter_func)(const uint8_t *a, const uint8_t *b, const uin 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]; @@ -50,6 +64,7 @@ typedef struct { ff_idet_filter_func filter_line; const AVPixFmtDescriptor *csp; + int eof; } IDETContext; void ff_idet_init_x86(IDETContext *idet, int for_16b); diff --git a/ffmpeg/libavfilter/vf_interlace.c b/ffmpeg/libavfilter/vf_interlace.c index e07963f..2828e36 100644 --- a/ffmpeg/libavfilter/vf_interlace.c +++ b/ffmpeg/libavfilter/vf_interlace.c @@ -33,26 +33,10 @@ #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[] = { @@ -69,6 +53,20 @@ 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, @@ -115,23 +113,31 @@ static int config_out_props(AVFilterLink *outlink) 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]; @@ -152,12 +158,7 @@ static void copy_picture_field(AVFrame *src_frame, AVFrame *dst_frame, 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; } @@ -207,11 +208,11 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *buf) 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); diff --git a/ffmpeg/libavfilter/vf_lut.c b/ffmpeg/libavfilter/vf_lut.c index fff5a2b..0b7a2ca 100644 --- a/ffmpeg/libavfilter/vf_lut.c +++ b/ffmpeg/libavfilter/vf_lut.c @@ -161,15 +161,32 @@ static double compute_gammaval(void *opaque, double gamma) 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 }; diff --git a/ffmpeg/libavfilter/vf_noise.c b/ffmpeg/libavfilter/vf_noise.c index 1028a3c..4acad8a 100644 --- a/ffmpeg/libavfilter/vf_noise.c +++ b/ffmpeg/libavfilter/vf_noise.c @@ -29,43 +29,12 @@ #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; @@ -110,7 +79,7 @@ static av_cold int init_noise(NoiseContext *n, int comp) 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) { @@ -157,12 +126,6 @@ static av_cold int init_noise(NoiseContext *n, int comp) 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; } @@ -199,8 +162,8 @@ static int config_input(AVFilterLink *inlink) 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; @@ -212,70 +175,8 @@ static inline void line_noise_c(uint8_t *dst, const uint8_t *src, const int8_t * } } -#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; @@ -286,50 +187,6 @@ static inline void line_noise_avg_c(uint8_t *dst, const uint8_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) @@ -337,8 +194,7 @@ static void noise(uint8_t *dst, const uint8_t *src, 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) @@ -348,16 +204,17 @@ static void noise(uint8_t *dst, const uint8_t *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; @@ -389,6 +246,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *inpicref) NoiseContext *n = ctx->priv; ThreadData td; AVFrame *out; + int comp, i; if (av_frame_is_writable(inpicref)) { out = inpicref; @@ -401,6 +259,18 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *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(); @@ -414,7 +284,6 @@ static av_cold int init(AVFilterContext *ctx) { 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) @@ -432,19 +301,11 @@ static av_cold int init(AVFilterContext *ctx) 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; } diff --git a/ffmpeg/libavfilter/vf_noise.h b/ffmpeg/libavfilter/vf_noise.h new file mode 100644 index 0000000..2207ed9 --- /dev/null +++ b/ffmpeg/libavfilter/vf_noise.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2002 Michael Niedermayer + * 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 */ diff --git a/ffmpeg/libavfilter/vf_perspective.c b/ffmpeg/libavfilter/vf_perspective.c index a796bd4..bf06d02 100644 --- a/ffmpeg/libavfilter/vf_perspective.c +++ b/ffmpeg/libavfilter/vf_perspective.c @@ -46,6 +46,7 @@ typedef struct PerspectiveContext { int height[4]; int hsub, vsub; int nb_planes; + int sense; int (*perspective)(AVFilterContext *ctx, void *arg, int job, int nb_jobs); @@ -54,6 +55,11 @@ typedef struct PerspectiveContext { #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 }, @@ -66,6 +72,12 @@ static const AVOption perspective_options[] = { { "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 } }; @@ -105,7 +117,8 @@ enum { VAR_W, VAR_H, VAR_VARS_NB }; 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; @@ -141,32 +154,64 @@ static int config_input(AVFilterLink *inlink) 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; diff --git a/ffmpeg/libavfilter/vf_pp.c b/ffmpeg/libavfilter/vf_pp.c index c72fdc6..e33ac48 100644 --- a/ffmpeg/libavfilter/vf_pp.c +++ b/ffmpeg/libavfilter/vf_pp.c @@ -79,7 +79,10 @@ static int pp_query_formats(AVFilterContext *ctx) 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)); @@ -92,13 +95,17 @@ static int pp_config_props(AVFilterLink *inlink) 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); } diff --git a/ffmpeg/libavfilter/vf_showinfo.c b/ffmpeg/libavfilter/vf_showinfo.c index 8201c2d..aa3bc83 100644 --- a/ffmpeg/libavfilter/vf_showinfo.c +++ b/ffmpeg/libavfilter/vf_showinfo.c @@ -86,9 +86,9 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame) 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; diff --git a/ffmpeg/libavfilter/vf_signalstats.c b/ffmpeg/libavfilter/vf_signalstats.c index 53f7401..4b2792f 100644 --- a/ffmpeg/libavfilter/vf_signalstats.c +++ b/ffmpeg/libavfilter/vf_signalstats.c @@ -43,22 +43,36 @@ typedef struct { 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<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) @@ -96,6 +112,9 @@ 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 }; @@ -103,6 +122,22 @@ static int query_formats(AVFilterContext *ctx) 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; @@ -121,16 +156,20 @@ static int config_props(AVFilterLink *outlink) s->fs = inlink->w * inlink->h; s->cfs = s->chromaw * s->chromah; - if (s->filters & 1<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; @@ -139,25 +178,36 @@ static void burn_frame(SignalstatsContext *s, AVFrame *f, int x, int y) 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; } @@ -167,38 +217,49 @@ static int filter_tout_outlier(uint8_t x, uint8_t y, uint8_t z) 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; @@ -206,63 +267,99 @@ filter_tout_outlier(p[(y-j) * lw + x + i], \ #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}, @@ -286,24 +383,37 @@ static int filter_frame(AVFilterLink *link, AVFrame *in) 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<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]; @@ -312,31 +422,33 @@ static int filter_frame(AVFilterLink *link, AVFrame *in) // 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<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<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]; } } @@ -475,4 +587,5 @@ AVFilter ff_vf_signalstats = { .inputs = signalstats_inputs, .outputs = signalstats_outputs, .priv_class = &signalstats_class, + .flags = AVFILTER_FLAG_SLICE_THREADS, }; diff --git a/ffmpeg/libavfilter/vf_subtitles.c b/ffmpeg/libavfilter/vf_subtitles.c index 4fa1174..be4c6a5 100644 --- a/ffmpeg/libavfilter/vf_subtitles.c +++ b/ffmpeg/libavfilter/vf_subtitles.c @@ -55,6 +55,7 @@ typedef struct { 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; @@ -68,19 +69,21 @@ typedef struct { /* 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, /* */ + [4] = AV_LOG_INFO, /* MSGL_INFO */ + [5] = AV_LOG_INFO, /* */ + [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"); @@ -139,6 +142,8 @@ static int config_input(AVFilterLink *inlink) 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; } @@ -205,6 +210,10 @@ static const AVFilterPad ass_outputs[] = { 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}, }; diff --git a/ffmpeg/libavfilter/vf_tinterlace.c b/ffmpeg/libavfilter/vf_tinterlace.c index 6bc55b5..c644895 100644 --- a/ffmpeg/libavfilter/vf_tinterlace.c +++ b/ffmpeg/libavfilter/vf_tinterlace.c @@ -30,33 +30,12 @@ #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"}, @@ -71,6 +50,7 @@ static const AVOption tinterlace_options[] = { {"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} }; @@ -84,6 +64,12 @@ static const enum AVPixelFormat full_scale_yuvj_pix_fmts[] = { 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[] = { @@ -99,6 +85,18 @@ static int query_formats(AVFilterContext *ctx) 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; @@ -114,6 +112,7 @@ static int config_out_props(AVFilterLink *outlink) 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; @@ -145,10 +144,28 @@ static int config_out_props(AVFilterLink *outlink) 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; itime_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", @@ -172,7 +189,8 @@ static int config_out_props(AVFilterLink *outlink) * @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, @@ -181,10 +199,11 @@ void copy_picture_field(uint8_t *dst[4], int dst_linesize[4], 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]; @@ -208,12 +227,8 @@ void copy_picture_field(uint8_t *dst[4], int dst_linesize[4], 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; } @@ -254,12 +269,12 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *picref) 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); @@ -284,12 +299,12 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *picref) 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); @@ -308,13 +323,13 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *picref) 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, @@ -330,6 +345,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *picref) 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; @@ -340,19 +356,20 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *picref) 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, @@ -362,6 +379,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *picref) 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++; diff --git a/ffmpeg/libavfilter/vf_vidstabdetect.c b/ffmpeg/libavfilter/vf_vidstabdetect.c index bf067af..1df6f74 100644 --- a/ffmpeg/libavfilter/vf_vidstabdetect.c +++ b/ffmpeg/libavfilter/vf_vidstabdetect.c @@ -176,8 +176,9 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) 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); } diff --git a/ffmpeg/libavfilter/vf_vidstabtransform.c b/ffmpeg/libavfilter/vf_vidstabtransform.c index 1bd43ff..9db6a46 100644 --- a/ffmpeg/libavfilter/vf_vidstabtransform.c +++ b/ffmpeg/libavfilter/vf_vidstabtransform.c @@ -208,8 +208,9 @@ static int config_input(AVFilterLink *inlink) 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) { diff --git a/ffmpeg/libavfilter/vf_xbr.c b/ffmpeg/libavfilter/vf_xbr.c new file mode 100644 index 0000000..47e4b76 --- /dev/null +++ b/ffmpeg/libavfilter/vf_xbr.c @@ -0,0 +1,440 @@ +/* + * This file is part of FFmpeg. + * + * Copyright (c) 2011, 2012 Hyllian/Jararaca + * Copyright (c) 2014 Arwa Arif + * + * 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, +}; diff --git a/ffmpeg/libavfilter/vf_yadif.c b/ffmpeg/libavfilter/vf_yadif.c index 70670c3..da6ee70 100644 --- a/ffmpeg/libavfilter/vf_yadif.c +++ b/ffmpeg/libavfilter/vf_yadif.c @@ -342,6 +342,9 @@ static int filter_frame(AVFilterLink *link, AVFrame *frame) 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) @@ -353,9 +356,6 @@ static int filter_frame(AVFilterLink *link, AVFrame *frame) 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); diff --git a/ffmpeg/libavfilter/x86/Makefile b/ffmpeg/libavfilter/x86/Makefile index ddb3774..44765d2 100644 --- a/ffmpeg/libavfilter/x86/Makefile +++ b/ffmpeg/libavfilter/x86/Makefile @@ -1,14 +1,19 @@ 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 diff --git a/ffmpeg/libavfilter/x86/vf_interlace.asm b/ffmpeg/libavfilter/x86/vf_interlace.asm new file mode 100644 index 0000000..ce3dd81 --- /dev/null +++ b/ffmpeg/libavfilter/x86/vf_interlace.asm @@ -0,0 +1,65 @@ +;***************************************************************************** +;* x86-optimized functions for interlace filter +;* +;* Copyright (C) 2014 Kieran Kunhya +;* 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 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 diff --git a/ffmpeg/libavfilter/x86/vf_interlace_init.c b/ffmpeg/libavfilter/x86/vf_interlace_init.c new file mode 100644 index 0000000..68ee47d --- /dev/null +++ b/ffmpeg/libavfilter/x86/vf_interlace_init.c @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2014 Kieran Kunhya + * + * 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; +} diff --git a/ffmpeg/libavfilter/x86/vf_noise.c b/ffmpeg/libavfilter/x86/vf_noise.c new file mode 100644 index 0000000..0a86cb0 --- /dev/null +++ b/ffmpeg/libavfilter/x86/vf_noise.c @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2002 Michael Niedermayer + * 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 +} diff --git a/ffmpeg/libavfilter/x86/vf_tinterlace_init.c b/ffmpeg/libavfilter/x86/vf_tinterlace_init.c new file mode 100644 index 0000000..ddb0cce --- /dev/null +++ b/ffmpeg/libavfilter/x86/vf_tinterlace_init.c @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2014 Kieran Kunhya + * + * 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; +} diff --git a/ffmpeg/libavformat/Makefile b/ffmpeg/libavformat/Makefile index 3d124fb..f0900c4 100644 --- a/ffmpeg/libavformat/Makefile +++ b/ffmpeg/libavformat/Makefile @@ -76,6 +76,7 @@ OBJS-$(CONFIG_AMR_MUXER) += amr.o 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 @@ -114,6 +115,7 @@ OBJS-$(CONFIG_CONCAT_DEMUXER) += concatdec.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 @@ -194,6 +196,7 @@ OBJS-$(CONFIG_IMAGE_BMP_PIPE_DEMUXER) += img2dec.o img2.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 @@ -367,6 +370,7 @@ OBJS-$(CONFIG_RTP_MUXER) += rtp.o \ rtpenc_h261.o \ rtpenc_h263.o \ rtpenc_h263_rfc2190.o \ + rtpenc_hevc.o \ rtpenc_jpeg.o \ rtpenc_mpv.o \ rtpenc.o \ @@ -402,9 +406,11 @@ OBJS-$(CONFIG_SPEEX_MUXER) += oggenc.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 @@ -446,6 +452,7 @@ OBJS-$(CONFIG_WEBM_DASH_MANIFEST_DEMUXER)+= matroskadec.o matroska.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 @@ -512,6 +519,9 @@ OBJS-$(CONFIG_UNIX_PROTOCOL) += unix.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 @@ -529,3 +539,4 @@ TOOLS = aviocat \ pktdumper \ probetest \ seek_print \ + sidxindex \ diff --git a/ffmpeg/libavformat/adtsenc.c b/ffmpeg/libavformat/adtsenc.c index d624b79..89c8869 100644 --- a/ffmpeg/libavformat/adtsenc.c +++ b/ffmpeg/libavformat/adtsenc.c @@ -45,7 +45,7 @@ typedef struct { #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; diff --git a/ffmpeg/libavformat/allformats.c b/ffmpeg/libavformat/allformats.c index 8f70c4b..81aab56 100644 --- a/ffmpeg/libavformat/allformats.c +++ b/ffmpeg/libavformat/allformats.c @@ -74,6 +74,7 @@ void av_register_all(void) 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); @@ -101,6 +102,7 @@ void av_register_all(void) 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); @@ -278,8 +280,10 @@ void av_register_all(void) 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); @@ -308,6 +312,7 @@ void av_register_all(void) 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); @@ -325,6 +330,7 @@ void av_register_all(void) 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); @@ -367,6 +373,7 @@ void av_register_all(void) REGISTER_PROTOCOL(TCP, tcp); REGISTER_PROTOCOL(TLS, tls); REGISTER_PROTOCOL(UDP, udp); + REGISTER_PROTOCOL(UDPLITE, udplite); REGISTER_PROTOCOL(UNIX, unix); /* external libraries */ diff --git a/ffmpeg/libavformat/apngdec.c b/ffmpeg/libavformat/apngdec.c new file mode 100644 index 0000000..d97b015 --- /dev/null +++ b/ffmpeg/libavformat/apngdec.c @@ -0,0 +1,446 @@ +/* + * 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, +}; diff --git a/ffmpeg/libavformat/asfenc.c b/ffmpeg/libavformat/asfenc.c index cccbf85..fbf6158 100644 --- a/ffmpeg/libavformat/asfenc.c +++ b/ffmpeg/libavformat/asfenc.c @@ -950,7 +950,7 @@ static int asf_write_packet(AVFormatContext *s, AVPacket *pkt) 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; diff --git a/ffmpeg/libavformat/assdec.c b/ffmpeg/libavformat/assdec.c index a5f792a..c62e76f 100644 --- a/ffmpeg/libavformat/assdec.c +++ b/ffmpeg/libavformat/assdec.c @@ -1,6 +1,7 @@ /* * SSA/ASS demuxer * Copyright (c) 2008 Michael Niedermayer + * Copyright (c) 2014 Clément Bœsch * * This file is part of FFmpeg. * @@ -29,6 +30,7 @@ typedef struct ASSContext { FFDemuxSubtitlesQueue q; + unsigned readorder; } ASSContext; static int ass_probe(AVProbeData *p) @@ -52,18 +54,36 @@ static int ass_read_close(AVFormatContext *s) 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; @@ -88,58 +108,46 @@ static int64_t get_line(AVBPrint *buf, FFTextReader *tr) 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; @@ -147,6 +155,9 @@ static int ass_read_header(AVFormatContext *s) ff_subtitles_queue_finalize(&ass->q); end: + av_bprint_finalize(&header, NULL); + av_bprint_finalize(&line, NULL); + av_bprint_finalize(&rline, NULL); return res; } diff --git a/ffmpeg/libavformat/assenc.c b/ffmpeg/libavformat/assenc.c index 2afeef7..bde1096 100644 --- a/ffmpeg/libavformat/assenc.c +++ b/ffmpeg/libavformat/assenc.c @@ -23,6 +23,8 @@ #include "avformat.h" #include "internal.h" +#include "libavutil/opt.h" + typedef struct DialogueLine { int readorder; char *line; @@ -30,42 +32,37 @@ typedef struct DialogueLine { } 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; @@ -164,6 +161,9 @@ static int write_packet(AVFormatContext *s, AVPacket *pkt) if (*p == ',') p++; + if (ass->ssa_mode && !strncmp(p, "Marked=", 7)) + p += 7; + layer = strtol(p, &p, 10); if (*p == ',') p++; @@ -174,14 +174,15 @@ static int write_packet(AVFormatContext *s, AVPacket *pkt) 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); } @@ -191,16 +192,24 @@ static int write_packet(AVFormatContext *s, AVPacket *pkt) 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"), @@ -212,4 +221,5 @@ AVOutputFormat ff_ass_muxer = { .write_packet = write_packet, .write_trailer = write_trailer, .flags = AVFMT_GLOBALHEADER | AVFMT_NOTIMESTAMPS | AVFMT_TS_NONSTRICT, + .priv_class = &ass_class, }; diff --git a/ffmpeg/libavformat/audiointerleave.c b/ffmpeg/libavformat/audiointerleave.c index 80bf768..b64010f 100644 --- a/ffmpeg/libavformat/audiointerleave.c +++ b/ffmpeg/libavformat/audiointerleave.c @@ -80,13 +80,14 @@ static int interleave_new_audio_packet(AVFormatContext *s, AVPacket *pkt, { 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; diff --git a/ffmpeg/libavformat/avc.c b/ffmpeg/libavformat/avc.c index f5c513b..c927b47 100644 --- a/ffmpeg/libavformat/avc.c +++ b/ffmpeg/libavformat/avc.c @@ -191,3 +191,20 @@ int ff_avc_write_annexb_extradata(const uint8_t *in, uint8_t **buf, int *size) *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; +} diff --git a/ffmpeg/libavformat/avc.h b/ffmpeg/libavformat/avc.h index 972e19b..c5e80ff 100644 --- a/ffmpeg/libavformat/avc.h +++ b/ffmpeg/libavformat/avc.h @@ -30,5 +30,8 @@ int ff_avc_parse_nal_units_buf(const uint8_t *buf_in, uint8_t **buf, int *size); 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 */ diff --git a/ffmpeg/libavformat/avformat.h b/ffmpeg/libavformat/avformat.h index b915148..2e54ed1 100644 --- a/ffmpeg/libavformat/avformat.h +++ b/ffmpeg/libavformat/avformat.h @@ -398,7 +398,7 @@ typedef struct AVProbeData { 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) @@ -916,7 +916,7 @@ typedef struct AVStream { /** * 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; @@ -1030,6 +1030,21 @@ typedef struct AVStream { */ 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. @@ -1082,11 +1097,26 @@ typedef struct AVStream { */ 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 @@ -1460,6 +1490,18 @@ typedef struct AVFormatContext { */ 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. @@ -1499,17 +1541,6 @@ typedef struct AVFormatContext { */ 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 @@ -1569,6 +1600,22 @@ typedef struct AVFormatContext { */ 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 @@ -1698,6 +1745,16 @@ typedef struct AVFormatContext { * 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); @@ -1859,16 +1916,6 @@ AVProgram *av_new_program(AVFormatContext *s, int id); */ -#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 @@ -1981,26 +2028,6 @@ int avformat_open_input(AVFormatContext **ps, const char *filename, AVInputForma 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 @@ -2067,24 +2094,6 @@ int av_find_best_stream(AVFormatContext *ic, 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 @@ -2170,17 +2179,6 @@ int av_read_play(AVFormatContext *s); */ 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. @@ -2190,30 +2188,6 @@ void avformat_close_input(AVFormatContext **s); * @} */ -#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 diff --git a/ffmpeg/libavformat/avidec.c b/ffmpeg/libavformat/avidec.c index 5b260e2..78a6dea 100644 --- a/ffmpeg/libavformat/avidec.c +++ b/ffmpeg/libavformat/avidec.c @@ -756,6 +756,10 @@ static int avi_read_header(AVFormatContext *s) 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; @@ -992,7 +996,7 @@ fail: 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 && @@ -1035,6 +1039,10 @@ static int read_gab2_sub(AVStream *st, AVPacket *pkt) 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; @@ -1047,6 +1055,7 @@ static int read_gab2_sub(AVStream *st, AVPacket *pkt) return 1; error: + av_freep(&ast->sub_ctx); av_freep(&pb); } return 0; @@ -1086,7 +1095,7 @@ static AVStream *get_subtitle_pkt(AVFormatContext *s, AVStream *next_st, 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') { @@ -1141,7 +1150,7 @@ start_sync: 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) @@ -1153,6 +1162,9 @@ start_sync: goto start_sync; } + if (avi->dv_demux && n != 0) + continue; + // parse ##dc/##wb if (n < s->nb_streams) { AVStream *st; @@ -1386,7 +1398,7 @@ FF_ENABLE_DEPRECATION_WARNINGS 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; diff --git a/ffmpeg/libavformat/avienc.c b/ffmpeg/libavformat/avienc.c index c45bac2..944c154 100644 --- a/ffmpeg/libavformat/avienc.c +++ b/ffmpeg/libavformat/avienc.c @@ -67,10 +67,14 @@ typedef struct { 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; @@ -565,6 +569,32 @@ static int avi_write_idx1(AVFormatContext *s) 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]; @@ -575,29 +605,20 @@ static int avi_write_packet(AVFormatContext *s, AVPacket *pkt) 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 @@ -661,6 +682,11 @@ static int avi_write_trailer(AVFormatContext *s) 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); diff --git a/ffmpeg/libavformat/avio.h b/ffmpeg/libavformat/avio.h index 2210c01..b9b4017 100644 --- a/ffmpeg/libavformat/avio.h +++ b/ffmpeg/libavformat/avio.h @@ -186,6 +186,9 @@ int avio_check(const char *url, int flags); * * @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. @@ -289,10 +292,14 @@ int url_feof(AVIOContext *s); 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); diff --git a/ffmpeg/libavformat/aviobuf.c b/ffmpeg/libavformat/aviobuf.c index 9795ba4..f374314 100644 --- a/ffmpeg/libavformat/aviobuf.c +++ b/ffmpeg/libavformat/aviobuf.c @@ -139,7 +139,7 @@ static void writeout(AVIOContext *s, const uint8_t *data, int len) 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, @@ -148,6 +148,8 @@ static void flush_buffer(AVIOContext *s) } } s->buf_ptr = s->buffer; + if (!s->write_flag) + s->buf_end = s->buffer; } void avio_w8(AVIOContext *s, int b) @@ -674,7 +676,7 @@ int ff_get_line(AVIOContext *s, char *buf, int maxlen) 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; @@ -1095,7 +1097,6 @@ int avio_close_dyn_buf(AVIOContext *s, uint8_t **pbuffer) *pbuffer = NULL; return 0; } - d = s->opaque; /* don't attempt to pad fixed-size packet buffers */ if (!s->max_packet_size) { @@ -1105,6 +1106,7 @@ int avio_close_dyn_buf(AVIOContext *s, uint8_t **pbuffer) avio_flush(s); + d = s->opaque; *pbuffer = d->buffer; size = d->size; av_free(d); diff --git a/ffmpeg/libavformat/bethsoftvid.c b/ffmpeg/libavformat/bethsoftvid.c index c98ff14..40a4252 100644 --- a/ffmpeg/libavformat/bethsoftvid.c +++ b/ffmpeg/libavformat/bethsoftvid.c @@ -180,7 +180,6 @@ static int read_frame(BVID_DemuxContext *vid, AVIOContext *pb, AVPacket *pkt, 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; @@ -192,13 +191,17 @@ static int read_frame(BVID_DemuxContext *vid, AVIOContext *pb, AVPacket *pkt, 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; diff --git a/ffmpeg/libavformat/cafdec.c b/ffmpeg/libavformat/cafdec.c index 80c5bb5..7d518d7 100644 --- a/ffmpeg/libavformat/cafdec.c +++ b/ffmpeg/libavformat/cafdec.c @@ -46,7 +46,7 @@ typedef struct { 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) { @@ -59,7 +59,7 @@ 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; @@ -167,7 +167,7 @@ static int read_pakt_chunk(AVFormatContext *s, int64_t size) { 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; @@ -216,7 +216,7 @@ static void read_info_chunk(AVFormatContext *s, int64_t size) 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; @@ -334,7 +334,7 @@ static int read_packet(AVFormatContext *s, AVPacket *pkt) { 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; @@ -390,7 +390,7 @@ static int read_seek(AVFormatContext *s, int stream_index, 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); @@ -422,7 +422,7 @@ static int read_seek(AVFormatContext *s, int stream_index, 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, diff --git a/ffmpeg/libavformat/cinedec.c b/ffmpeg/libavformat/cinedec.c index 9eed006..632f46c 100644 --- a/ffmpeg/libavformat/cinedec.c +++ b/ffmpeg/libavformat/cinedec.c @@ -1,5 +1,5 @@ /* - * Phanton Cine demuxer + * Phantom Cine demuxer * Copyright (c) 2010-2011 Peter Ross * * This file is part of FFmpeg. @@ -27,6 +27,7 @@ #include "libavutil/intreadwrite.h" #include "libavcodec/bmp.h" +#include "libavutil/intfloat.h" #include "avformat.h" #include "internal.h" @@ -78,6 +79,16 @@ static int set_metadata_int(AVDictionary **dict, const char *key, int value, int 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; @@ -177,7 +188,10 @@ static int cine_read_header(AVFormatContext *avctx) 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); diff --git a/ffmpeg/libavformat/concat.c b/ffmpeg/libavformat/concat.c index 3bbc83d..81fe970 100644 --- a/ffmpeg/libavformat/concat.c +++ b/ffmpeg/libavformat/concat.c @@ -21,9 +21,10 @@ * 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 "|" @@ -59,24 +60,26 @@ static av_cold int concat_open(URLContext *h, const char *uri, int flags) 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 */ @@ -87,8 +90,8 @@ static av_cold int concat_open(URLContext *h, const char *uri, int flags) 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, @@ -124,16 +127,17 @@ static int concat_read(URLContext *h, unsigned char *buf, int size) 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; @@ -151,9 +155,7 @@ static int64_t concat_seek(URLContext *h, int64_t pos, int whence) 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: diff --git a/ffmpeg/libavformat/concatdec.c b/ffmpeg/libavformat/concatdec.c index 9e98579..a2584d7 100644 --- a/ffmpeg/libavformat/concatdec.c +++ b/ffmpeg/libavformat/concatdec.c @@ -23,6 +23,7 @@ #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" @@ -288,6 +289,10 @@ static int open_file(AVFormatContext *avf, unsigned fileno) 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); @@ -475,6 +480,7 @@ static int concat_read_packet(AVFormatContext *avf, AVPacket *pkt) int ret; int64_t delta; ConcatStream *cs; + AVStream *st; while (1) { ret = av_read_frame(cat->avf, pkt); @@ -500,6 +506,12 @@ static int concat_read_packet(AVFormatContext *avf, AVPacket *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); @@ -507,6 +519,9 @@ static int concat_read_packet(AVFormatContext *avf, AVPacket *pkt) 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; } diff --git a/ffmpeg/libavformat/crypto.c b/ffmpeg/libavformat/crypto.c index a9b6e47..c1754b0 100644 --- a/ffmpeg/libavformat/crypto.c +++ b/ffmpeg/libavformat/crypto.c @@ -41,14 +41,32 @@ typedef struct { 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 } }; @@ -59,6 +77,33 @@ static const AVClass crypto_class = { .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; @@ -72,28 +117,54 @@ static int crypto_open2(URLContext *h, const char *uri, int flags, AVDictionary 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; @@ -131,8 +202,8 @@ retry: 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; @@ -150,12 +221,65 @@ retry: 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; } @@ -163,6 +287,7 @@ URLProtocol ff_crypto_protocol = { .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, diff --git a/ffmpeg/libavformat/cutils.c b/ffmpeg/libavformat/cutils.c index 0458a2d..d86ba05 100644 --- a/ffmpeg/libavformat/cutils.c +++ b/ffmpeg/libavformat/cutils.c @@ -18,6 +18,8 @@ * 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" @@ -28,30 +30,10 @@ 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; } diff --git a/ffmpeg/libavformat/dashenc.c b/ffmpeg/libavformat/dashenc.c new file mode 100644 index 0000000..149e7d9 --- /dev/null +++ b/ffmpeg/libavformat/dashenc.c @@ -0,0 +1,933 @@ +/* + * 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 +#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\tuse_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\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\ttime); + 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\n"); + } + avio_printf(out, "\t\t\t\t\n"); + } else if (c->single_file) { + avio_printf(out, "\t\t\t\t%s\n", os->initfile); + avio_printf(out, "\t\t\t\t\n", AV_TIME_BASE, c->last_duration, start_number); + avio_printf(out, "\t\t\t\t\t\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\tstart_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\n"); + } else { + avio_printf(out, "\t\t\t\t\n", AV_TIME_BASE, c->last_duration, start_number); + avio_printf(out, "\t\t\t\t\t\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\n", seg->file); + } + avio_printf(out, "\t\t\t\t\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, "\n"); + avio_printf(out, "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\n"); + if (title) { + char *escaped = xmlescape(title->value); + avio_printf(out, "\t\t%s\n", escaped); + av_free(escaped); + } + avio_printf(out, "\t\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\n"); + } else { + avio_printf(out, "\t\n"); + } + + if (c->has_video) { + avio_printf(out, "\t\t\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\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\n"); + } + avio_printf(out, "\t\t\n"); + } + if (c->has_audio) { + avio_printf(out, "\t\t\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\n", i, os->codec_str, os->bandwidth_str, st->codec->sample_rate); + avio_printf(out, "\t\t\t\t\n", st->codec->channels); + output_segment_list(&c->streams[i], out, c); + avio_printf(out, "\t\t\t\n"); + } + avio_printf(out, "\t\t\n"); + } + avio_printf(out, "\t\n"); + avio_printf(out, "\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, +}; diff --git a/ffmpeg/libavformat/dtsdec.c b/ffmpeg/libavformat/dtsdec.c index f6a939a..d054f43 100644 --- a/ffmpeg/libavformat/dtsdec.c +++ b/ffmpeg/libavformat/dtsdec.c @@ -34,7 +34,7 @@ static int dts_probe(AVProbeData *p) { 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 }; @@ -43,6 +43,7 @@ static int dts_probe(AVProbeData *p) 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; @@ -89,13 +90,27 @@ static int dts_probe(AVProbeData *p) 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 3 && p->buf_size / markers[max] < 32*1024 && markers[max] * 4 > sum * 3 && diff / p->buf_size > 200) diff --git a/ffmpeg/libavformat/dump.c b/ffmpeg/libavformat/dump.c index 3a7adbe..56b37ff 100644 --- a/ffmpeg/libavformat/dump.c +++ b/ffmpeg/libavformat/dump.c @@ -27,6 +27,7 @@ #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" @@ -118,11 +119,11 @@ static void print_fps(double d, const char *postfix) { 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) @@ -345,8 +346,15 @@ static void dump_stream_format(AVFormatContext *ic, int i, 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 */ @@ -372,15 +380,21 @@ static void dump_stream_format(AVFormatContext *ic, int i, } 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"); } @@ -460,7 +474,7 @@ void av_dump_format(AVFormatContext *ic, int index, 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, diff --git a/ffmpeg/libavformat/dv.c b/ffmpeg/libavformat/dv.c index 1030d51..095966c 100644 --- a/ffmpeg/libavformat/dv.c +++ b/ffmpeg/libavformat/dv.c @@ -72,7 +72,7 @@ static inline uint16_t dv_audio_12to16(uint16_t sample) 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; @@ -116,7 +116,7 @@ static const int dv_audio_frequency[3] = { * 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; @@ -219,7 +219,7 @@ static int dv_extract_audio(uint8_t *frame, uint8_t **ppcm, 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; @@ -279,7 +279,7 @@ static int dv_extract_audio_info(DVDemuxContext *c, uint8_t *frame) 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; @@ -307,7 +307,7 @@ static int dv_extract_video_info(DVDemuxContext *c, uint8_t *frame) 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; diff --git a/ffmpeg/libavformat/ffmdec.c b/ffmpeg/libavformat/ffmdec.c index 448762b..987f419 100644 --- a/ffmpeg/libavformat/ffmdec.c +++ b/ffmpeg/libavformat/ffmdec.c @@ -23,6 +23,9 @@ #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" @@ -230,6 +233,27 @@ static int ffm_close(AVFormatContext *s) 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; @@ -237,6 +261,9 @@ static int ffm2_read_header(AVFormatContext *s) 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) { @@ -267,10 +294,15 @@ static int ffm2_read_header(AVFormatContext *s) 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); @@ -291,63 +323,111 @@ static int ffm2_read_header(AVFormatContext *s) 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); diff --git a/ffmpeg/libavformat/ffmenc.c b/ffmpeg/libavformat/ffmenc.c index eb809eb..e6d1a31 100644 --- a/ffmpeg/libavformat/ffmenc.c +++ b/ffmpeg/libavformat/ffmenc.c @@ -23,6 +23,7 @@ #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" @@ -93,6 +94,128 @@ static void write_header_chunk(AVIOContext *pb, AVIOContext *dpb, unsigned id) 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; @@ -100,10 +223,10 @@ static int ffm_write_header(AVFormatContext *s) 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; } @@ -148,61 +271,29 @@ static int ffm_write_header(AVFormatContext *s) 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; diff --git a/ffmpeg/libavformat/ffmetadec.c b/ffmpeg/libavformat/ffmetadec.c index e4e9dda..e226406 100644 --- a/ffmpeg/libavformat/ffmetadec.c +++ b/ffmpeg/libavformat/ffmetadec.c @@ -78,10 +78,11 @@ static AVChapter *read_chapter(AVFormatContext *s) 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; @@ -95,9 +96,10 @@ static uint8_t *unescape(uint8_t *buf, int size) 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) { diff --git a/ffmpeg/libavformat/filmstripdec.c b/ffmpeg/libavformat/filmstripdec.c index abc5f66..b76d4b7 100644 --- a/ffmpeg/libavformat/filmstripdec.c +++ b/ffmpeg/libavformat/filmstripdec.c @@ -67,6 +67,12 @@ static int read_header(AVFormatContext *s) 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); @@ -82,9 +88,9 @@ static int read_packet(AVFormatContext *s, 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; diff --git a/ffmpeg/libavformat/flac_picture.c b/ffmpeg/libavformat/flac_picture.c index 5f2026d..669fd2e 100644 --- a/ffmpeg/libavformat/flac_picture.c +++ b/ffmpeg/libavformat/flac_picture.c @@ -33,8 +33,9 @@ int ff_flac_parse_picture(AVFormatContext *s, uint8_t *buf, int buf_size) 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) @@ -42,7 +43,7 @@ int ff_flac_parse_picture(AVFormatContext *s, uint8_t *buf, int buf_size) /* 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); @@ -52,7 +53,7 @@ int ff_flac_parse_picture(AVFormatContext *s, uint8_t *buf, int buf_size) /* 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"); diff --git a/ffmpeg/libavformat/flacdec.c b/ffmpeg/libavformat/flacdec.c index c291393..1a8dc19 100644 --- a/ffmpeg/libavformat/flacdec.c +++ b/ffmpeg/libavformat/flacdec.c @@ -27,7 +27,6 @@ #include "oggdec.h" #include "vorbiscomment.h" #include "replaygain.h" -#include "libavcodec/bytestream.h" static int flac_read_header(AVFormatContext *s) { @@ -75,7 +74,9 @@ 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); @@ -88,14 +89,16 @@ static int flac_read_header(AVFormatContext *s) 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]; diff --git a/ffmpeg/libavformat/flacenc.c b/ffmpeg/libavformat/flacenc.c index b3695a2..0eea942 100644 --- a/ffmpeg/libavformat/flacenc.c +++ b/ffmpeg/libavformat/flacenc.c @@ -95,7 +95,7 @@ static int flac_write_header(struct AVFormatContext *s) 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); diff --git a/ffmpeg/libavformat/flvdec.c b/ffmpeg/libavformat/flvdec.c index 12d25b2..17d1313 100644 --- a/ffmpeg/libavformat/flvdec.c +++ b/ffmpeg/libavformat/flvdec.c @@ -746,7 +746,7 @@ static int flv_data_packet(AVFormatContext *s, AVPacket *pkt, 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; } @@ -885,10 +885,14 @@ skip: 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); @@ -930,6 +934,7 @@ retry_duration: } 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; } diff --git a/ffmpeg/libavformat/flvenc.c b/ffmpeg/libavformat/flvenc.c index febc5e5..5468c4d 100644 --- a/ffmpeg/libavformat/flvenc.c +++ b/ffmpeg/libavformat/flvenc.c @@ -63,6 +63,11 @@ typedef struct FLVContext { 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 { @@ -191,108 +196,19 @@ static void put_amf_bool(AVIOContext *pb, int b) 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 */ @@ -304,57 +220,57 @@ static int flv_write_header(AVFormatContext *s) /* 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); } @@ -399,6 +315,106 @@ static int flv_write_header(AVFormatContext *s) 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; @@ -484,6 +500,22 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt) 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); @@ -528,17 +560,6 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt) 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 " @@ -548,6 +569,12 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt) 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_ @@ -556,18 +583,24 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt) 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); diff --git a/ffmpeg/libavformat/format.c b/ffmpeg/libavformat/format.c index 1026c8f..97f5657 100644 --- a/ffmpeg/libavformat/format.c +++ b/ffmpeg/libavformat/format.c @@ -80,28 +80,14 @@ void av_register_output_format(AVOutputFormat *format) 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; } @@ -269,8 +255,11 @@ int av_probe_input_buffer2(AVIOContext *pb, AVInputFormat **fmt, 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")) { @@ -334,7 +323,7 @@ fail: if (ret >= 0) ret = ret2; - av_free(pd.mime_type); + av_freep(&pd.mime_type); return ret < 0 ? ret : score; } diff --git a/ffmpeg/libavformat/hdsenc.c b/ffmpeg/libavformat/hdsenc.c index 1f77785..33d7c3a 100644 --- a/ffmpeg/libavformat/hdsenc.c +++ b/ffmpeg/libavformat/hdsenc.c @@ -174,7 +174,7 @@ static int write_manifest(AVFormatContext *s, int final) 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, "\n"); @@ -204,11 +204,7 @@ static int write_manifest(AVFormatContext *s, int final) avio_printf(out, "\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) @@ -289,11 +285,7 @@ static int write_abst(AVFormatContext *s, OutputStream *os, int final) 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) @@ -330,8 +322,8 @@ static int hds_write_header(AVFormatContext *s) 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; } @@ -404,7 +396,9 @@ static int hds_write_header(AVFormatContext *s) 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++; @@ -487,10 +481,9 @@ static int hds_flush(AVFormatContext *s, OutputStream *os, int final, 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) { diff --git a/ffmpeg/libavformat/hls.c b/ffmpeg/libavformat/hls.c index 0c86461..f17b826 100644 --- a/ffmpeg/libavformat/hls.c +++ b/ffmpeg/libavformat/hls.c @@ -193,9 +193,9 @@ static void free_segment_list(struct playlist *pls) { 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; @@ -212,7 +212,7 @@ static void free_playlist_list(HLSContext *c) 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) { @@ -243,7 +243,7 @@ static void free_rendition_list(HLSContext *c) { 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; } @@ -666,7 +666,7 @@ static int parse_playlist(HLSContext *c, const char *url, } } if (pls) - pls->last_load_time = av_gettime(); + pls->last_load_time = av_gettime_relative(); fail: av_free(new_url); @@ -1035,7 +1035,7 @@ restart: 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); @@ -1055,7 +1055,7 @@ reload: if (v->cur_seq_no >= v->start_seq_no + v->n_segments) { if (v->finished) return AVERROR_EOF; - while (av_gettime() - v->last_load_time < 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); @@ -1198,7 +1198,7 @@ static int select_cur_seq_no(HLSContext *c, struct playlist *pls) 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); @@ -1344,6 +1344,10 @@ static int hls_read_header(AVFormatContext *s) } 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; diff --git a/ffmpeg/libavformat/hlsenc.c b/ffmpeg/libavformat/hlsenc.c index cc142fa..e13f438 100644 --- a/ffmpeg/libavformat/hlsenc.c +++ b/ffmpeg/libavformat/hlsenc.c @@ -35,10 +35,17 @@ 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; @@ -51,12 +58,16 @@ typedef struct HLSContext { 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; @@ -64,6 +75,8 @@ typedef struct HLSContext { char *basename; char *baseurl; + char *format_options_str; + AVDictionary *format_options; AVIOContext *pb; } HLSContext; @@ -72,14 +85,16 @@ static int hls_mux_init(AVFormatContext *s) { 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++) { @@ -88,13 +103,16 @@ static int hls_mux_init(AVFormatContext *s) 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)); @@ -104,6 +122,8 @@ static int hls_append_segment(HLSContext *hls, double duration) 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) @@ -143,6 +163,7 @@ static int hls_window(AVFormatContext *s, int last) 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) @@ -154,7 +175,10 @@ static int hls_window(AVFormatContext *s, int last) } 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); @@ -163,6 +187,9 @@ static int hls_window(AVFormatContext *s, int last) 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); @@ -182,11 +209,15 @@ static int hls_start(AVFormatContext *s) 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, @@ -205,12 +236,24 @@ static int hls_write_header(AVFormatContext *s) 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; @@ -249,17 +292,22 @@ static int hls_write_header(AVFormatContext *s) 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) @@ -296,17 +344,28 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt) 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; @@ -328,10 +387,12 @@ static int hls_write_trailer(struct AVFormatContext *s) 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); @@ -345,8 +406,13 @@ static const AVOption options[] = { {"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 }, }; diff --git a/ffmpeg/libavformat/hlsproto.c b/ffmpeg/libavformat/hlsproto.c index e607c10..a569e92 100644 --- a/ffmpeg/libavformat/hlsproto.c +++ b/ffmpeg/libavformat/hlsproto.c @@ -169,7 +169,7 @@ static int parse_playlist(URLContext *h, const char *url) } } } - s->last_load_time = av_gettime(); + s->last_load_time = av_gettime_relative(); fail: avio_close(in); @@ -273,7 +273,7 @@ start: 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; @@ -292,7 +292,7 @@ retry: if (s->cur_seq_no - s->start_seq_no >= s->n_segments) { if (s->finished) return AVERROR_EOF; - while (av_gettime() - s->last_load_time < 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); diff --git a/ffmpeg/libavformat/http.c b/ffmpeg/libavformat/http.c index 018d25c..d9de05c 100644 --- a/ffmpeg/libavformat/http.c +++ b/ffmpeg/libavformat/http.c @@ -207,6 +207,8 @@ static int http_open_cnx(URLContext *h, AVDictionary **options) 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; @@ -250,7 +252,9 @@ redo: 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) @@ -266,12 +270,28 @@ 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) { @@ -354,7 +374,7 @@ static int check_http_code(URLContext *h, int http_code, const char *end) (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; } @@ -1117,7 +1137,6 @@ static int64_t http_seek(URLContext *h, int64_t off, int whence) 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); @@ -1267,7 +1286,7 @@ redo: if (s->http_code < 400) return 0; - ret = AVERROR(EIO); + ret = ff_http_averror(s->http_code, AVERROR(EIO)); fail: http_proxy_close(h); diff --git a/ffmpeg/libavformat/http.h b/ffmpeg/libavformat/http.h index be8ae7f..7d02713 100644 --- a/ffmpeg/libavformat/http.h +++ b/ffmpeg/libavformat/http.h @@ -47,4 +47,6 @@ void ff_http_init_auth_state(URLContext *dest, const URLContext *src); */ 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 */ diff --git a/ffmpeg/libavformat/icecast.c b/ffmpeg/libavformat/icecast.c index 56a2976..a7c7001 100644 --- a/ffmpeg/libavformat/icecast.c +++ b/ffmpeg/libavformat/icecast.c @@ -114,8 +114,12 @@ static int icecast_open(URLContext *h, const char *uri, int flags) 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); diff --git a/ffmpeg/libavformat/id3v2.c b/ffmpeg/libavformat/id3v2.c index 5469e0a..cbf4375 100644 --- a/ffmpeg/libavformat/id3v2.c +++ b/ffmpeg/libavformat/id3v2.c @@ -60,8 +60,8 @@ const AVMetadataConv ff_id3v2_34_metadata_conv[] = { const AVMetadataConv ff_id3v2_4_metadata_conv[] = { { "TCMP", "compilation" }, - { "TDRL", "date" }, { "TDRC", "date" }, + { "TDRL", "date" }, { "TDEN", "creation_time" }, { "TSOA", "album-sort" }, { "TSOP", "artist-sort" }, @@ -170,6 +170,48 @@ static unsigned int get_size(AVIOContext *s, int len) 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. */ @@ -726,7 +768,7 @@ static void id3v2_parse(AVIOContext *pb, AVDictionary **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) @@ -734,8 +776,26 @@ static void id3v2_parse(AVIOContext *pb, AVDictionary **metadata, 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 { diff --git a/ffmpeg/libavformat/iff.c b/ffmpeg/libavformat/iff.c index 8e20303..e7c240c 100644 --- a/ffmpeg/libavformat/iff.c +++ b/ffmpeg/libavformat/iff.c @@ -285,7 +285,13 @@ static int parse_dsd_prop(AVFormatContext *s, AVStream *st, uint64_t eof) 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',' ',' '): diff --git a/ffmpeg/libavformat/img2.c b/ffmpeg/libavformat/img2.c index 8002054..d6f1244 100644 --- a/ffmpeg/libavformat/img2.c +++ b/ffmpeg/libavformat/img2.c @@ -57,7 +57,6 @@ static const IdStrMap img_tags[] = { { 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" }, diff --git a/ffmpeg/libavformat/img2dec.c b/ffmpeg/libavformat/img2dec.c index 2969b51..a20868c 100644 --- a/ffmpeg/libavformat/img2dec.c +++ b/ffmpeg/libavformat/img2dec.c @@ -360,7 +360,7 @@ int ff_img_read_packet(AVFormatContext *s1, AVPacket *pkt) 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; @@ -436,8 +436,9 @@ int ff_img_read_packet(AVFormatContext *s1, AVPacket *pkt) } } - 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) { @@ -595,7 +596,7 @@ static int bmp_probe(AVProbeData *p) 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; } @@ -630,6 +631,57 @@ static int j2k_probe(AVProbeData *p) 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; @@ -721,6 +773,7 @@ IMAGEAUTO_DEMUXER(bmp, AV_CODEC_ID_BMP) 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) diff --git a/ffmpeg/libavformat/img2enc.c b/ffmpeg/libavformat/img2enc.c index 37dfbec..2b8b2d0 100644 --- a/ffmpeg/libavformat/img2enc.c +++ b/ffmpeg/libavformat/img2enc.c @@ -26,6 +26,7 @@ #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" @@ -83,9 +84,9 @@ static int write_packet(AVFormatContext *s, AVPacket *pkt) 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); @@ -194,7 +195,7 @@ AVOutputFormat ff_image2_muxer = { .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, diff --git a/ffmpeg/libavformat/internal.h b/ffmpeg/libavformat/internal.h index 3011706..ce03dac 100644 --- a/ffmpeg/libavformat/internal.h +++ b/ffmpeg/libavformat/internal.h @@ -23,6 +23,7 @@ #include #include "avformat.h" +#include "os_support.h" #define MAX_URL_SIZE 4096 @@ -334,7 +335,7 @@ void ff_free_stream(AVFormatContext *s, AVStream *st); /** * 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); @@ -371,6 +372,24 @@ AVRational ff_choose_timebase(AVFormatContext *s, AVStream *st, int min_precisio */ 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. @@ -412,5 +431,9 @@ enum AVWriteUncodedFrameFlags { }; +/** + * Copies the whilelists from one context to the other + */ +int ff_copy_whitelists(AVFormatContext *dst, AVFormatContext *src); #endif /* AVFORMAT_INTERNAL_H */ diff --git a/ffmpeg/libavformat/isom.c b/ffmpeg/libavformat/isom.c index d768c32..1509021 100644 --- a/ffmpeg/libavformat/isom.c +++ b/ffmpeg/libavformat/isom.c @@ -57,6 +57,7 @@ const AVCodecTag ff_mp4_obj_type[] = { { 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 */ diff --git a/ffmpeg/libavformat/isom.h b/ffmpeg/libavformat/isom.h index 979e967..e3160d0 100644 --- a/ffmpeg/libavformat/isom.h +++ b/ffmpeg/libavformat/isom.h @@ -78,6 +78,7 @@ typedef struct MOVFragment { unsigned duration; unsigned size; unsigned flags; + int64_t time; } MOVFragment; typedef struct MOVTrackExt { @@ -93,6 +94,18 @@ typedef struct MOVSbgp { 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; @@ -151,7 +164,7 @@ typedef struct MOVStreamContext { } 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 @@ -168,9 +181,14 @@ typedef struct MOVContext { 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); @@ -228,6 +246,7 @@ void ff_mp4_parse_es_descr(AVIOContext *pb, int *es_id); (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')) @@ -237,4 +256,8 @@ enum AVCodecID ff_mov_get_lpcm_codec_id(int bps, int flags); 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 */ diff --git a/ffmpeg/libavformat/jacosubdec.c b/ffmpeg/libavformat/jacosubdec.c index 9a28870..1ca0055 100644 --- a/ffmpeg/libavformat/jacosubdec.c +++ b/ffmpeg/libavformat/jacosubdec.c @@ -232,7 +232,7 @@ static int jacosub_read_header(AVFormatContext *s) /* 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 */ @@ -243,6 +243,9 @@ static int jacosub_read_header(AVFormatContext *s) ff_subtitles_queue_finalize(&jacosub->q); return 0; +fail: + jacosub_read_close(s); + return ret; } static int jacosub_read_packet(AVFormatContext *s, AVPacket *pkt) diff --git a/ffmpeg/libavformat/libquvi.c b/ffmpeg/libavformat/libquvi.c index ca71f9f..0a593cc 100644 --- a/ffmpeg/libavformat/libquvi.c +++ b/ffmpeg/libavformat/libquvi.c @@ -22,6 +22,7 @@ #include "libavformat/avformat.h" #include "libavformat/internal.h" +#include "libavutil/avassert.h" #include "libavutil/opt.h" typedef struct { @@ -75,6 +76,9 @@ static int libquvi_read_header(AVFormatContext *s) 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; diff --git a/ffmpeg/libavformat/librtmp.c b/ffmpeg/libavformat/librtmp.c index c57699c..67939b9 100644 --- a/ffmpeg/libavformat/librtmp.c +++ b/ffmpeg/libavformat/librtmp.c @@ -169,7 +169,7 @@ static int rtmp_open(URLContext *s, const char *uri, int flags) } 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); diff --git a/ffmpeg/libavformat/libsmbclient.c b/ffmpeg/libavformat/libsmbclient.c index 892d2db..8290d75 100644 --- a/ffmpeg/libavformat/libsmbclient.c +++ b/ffmpeg/libavformat/libsmbclient.c @@ -50,12 +50,14 @@ static av_cold int libsmbc_connect(URLContext *h) 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); @@ -68,8 +70,9 @@ static av_cold int libsmbc_connect(URLContext *h) 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; } @@ -157,8 +160,9 @@ static int libsmbc_read(URLContext *h, unsigned char *buf, int size) 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; @@ -170,8 +174,9 @@ static int libsmbc_write(URLContext *h, const unsigned char *buf, int size) 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; diff --git a/ffmpeg/libavformat/lmlm4.c b/ffmpeg/libavformat/lmlm4.c index c8ea421..899f449 100644 --- a/ffmpeg/libavformat/lmlm4.c +++ b/ffmpeg/libavformat/lmlm4.c @@ -23,6 +23,7 @@ */ #include "libavutil/intreadwrite.h" + #include "avformat.h" #include "internal.h" @@ -34,23 +35,23 @@ #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; } } @@ -58,7 +59,8 @@ static int lmlm4_probe(AVProbeData * pd) { 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))) @@ -78,7 +80,8 @@ static int lmlm4_read_header(AVFormatContext *s) { 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; @@ -104,15 +107,15 @@ static int lmlm4_read_packet(AVFormatContext *s, AVPacket *pkt) { 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; diff --git a/ffmpeg/libavformat/lxfdec.c b/ffmpeg/libavformat/lxfdec.c index 11d6da5..fb37da7 100644 --- a/ffmpeg/libavformat/lxfdec.c +++ b/ffmpeg/libavformat/lxfdec.c @@ -83,7 +83,7 @@ static int check_checksum(const uint8_t *header, int size) * @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; @@ -120,7 +120,7 @@ static int get_packet_header(AVFormatContext *s) 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); diff --git a/ffmpeg/libavformat/m4vdec.c b/ffmpeg/libavformat/m4vdec.c index 80bd75e..d8ee530 100644 --- a/ffmpeg/libavformat/m4vdec.c +++ b/ffmpeg/libavformat/m4vdec.c @@ -27,28 +27,34 @@ 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; ibuf_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) diff --git a/ffmpeg/libavformat/matroska.c b/ffmpeg/libavformat/matroska.c index 272d235..bc5007a 100644 --- a/ffmpeg/libavformat/matroska.c +++ b/ffmpeg/libavformat/matroska.c @@ -66,7 +66,6 @@ const CodecTags ff_mkv_codec_tags[]={ {"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}, diff --git a/ffmpeg/libavformat/matroskadec.c b/ffmpeg/libavformat/matroskadec.c index e3cd1e4..c81b5a0 100644 --- a/ffmpeg/libavformat/matroskadec.c +++ b/ffmpeg/libavformat/matroskadec.c @@ -32,12 +32,6 @@ #include #include -#if CONFIG_BZLIB -#include -#endif -#if CONFIG_ZLIB -#include -#endif #include "libavutil/avstring.h" #include "libavutil/base64.h" @@ -46,6 +40,7 @@ #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" @@ -61,6 +56,13 @@ #include "riff.h" #include "rmsipr.h" +#if CONFIG_BZLIB +#include +#endif +#if CONFIG_ZLIB +#include +#endif + typedef enum { EBML_NONE, EBML_UINT, @@ -1507,10 +1509,10 @@ static void matroska_metadata_creation_time(AVDictionary **metadata, int64_t dat 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, @@ -2328,10 +2330,15 @@ static int matroska_parse_rm_audio(MatroskaDemuxContext *matroska, } 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--), @@ -2907,7 +2914,7 @@ static int matroska_read_seek(AVFormatContext *s, int stream_index, 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; @@ -2921,11 +2928,11 @@ static int matroska_read_seek(AVFormatContext *s, int stream_index, 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; @@ -2937,6 +2944,7 @@ static int matroska_read_seek(AVFormatContext *s, int stream_index, 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; @@ -3189,55 +3197,57 @@ static int64_t webm_dash_manifest_compute_bandwidth(AVFormatContext *s, int64_t } 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; @@ -3262,10 +3272,13 @@ static int webm_dash_manifest_cues(AVFormatContext *s) 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; @@ -3321,8 +3334,7 @@ static int webm_dash_manifest_read_header(AVFormatContext *s) // 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); diff --git a/ffmpeg/libavformat/matroskaenc.c b/ffmpeg/libavformat/matroskaenc.c index 3fa4bab..e8e8da0 100644 --- a/ffmpeg/libavformat/matroskaenc.c +++ b/ffmpeg/libavformat/matroskaenc.c @@ -696,13 +696,15 @@ static int mkv_write_codecprivate(AVFormatContext *s, AVIOContext *pb, 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))) { @@ -722,6 +724,7 @@ static int mkv_write_stereo_mode(AVFormatContext *s, AVIOContext *pb, } } + // 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) { @@ -735,11 +738,13 @@ static int mkv_write_stereo_mode(AVFormatContext *s, AVIOContext *pb, 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; @@ -750,11 +755,13 @@ static int mkv_write_stereo_mode(AVFormatContext *s, AVIOContext *pb, 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; @@ -762,8 +769,6 @@ static int mkv_write_stereo_mode(AVFormatContext *s, AVIOContext *pb, format++; break; } - ret = stereo->type; - break; } } @@ -771,6 +776,7 @@ static int mkv_write_stereo_mode(AVFormatContext *s, AVIOContext *pb, 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) @@ -781,6 +787,7 @@ static int mkv_write_stereo_mode(AVFormatContext *s, AVIOContext *pb, return AVERROR(EINVAL); } + // write StereoMode if format is valid put_ebml_uint(pb, MATROSKA_ID_VIDEOSTEREOMODE, format); return ret; @@ -870,13 +877,14 @@ static int mkv_write_track(AVFormatContext *s, MatroskaMuxContext *mkv, } } - 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) { @@ -926,27 +934,20 @@ static int mkv_write_track(AVFormatContext *s, MatroskaMuxContext *mkv, // 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) { @@ -964,6 +965,7 @@ static int mkv_write_track(AVFormatContext *s, MatroskaMuxContext *mkv, 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; @@ -1589,47 +1591,6 @@ static void mkv_write_block(AVFormatContext *s, AVIOContext *pb, } } -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; @@ -1733,7 +1694,8 @@ static int mkv_write_packet_internal(AVFormatContext *s, AVPacket *pkt, int add_ 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; } @@ -1757,9 +1719,7 @@ static int mkv_write_packet_internal(AVFormatContext *s, AVPacket *pkt, int add_ 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, @@ -1813,7 +1773,8 @@ static int mkv_write_packet(AVFormatContext *s, AVPacket *pkt) // 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 && diff --git a/ffmpeg/libavformat/mlvdec.c b/ffmpeg/libavformat/mlvdec.c index 1855ea4..17bdb17 100644 --- a/ffmpeg/libavformat/mlvdec.c +++ b/ffmpeg/libavformat/mlvdec.c @@ -204,8 +204,8 @@ static int scan_file(AVFormatContext *avctx, AVStream *vst, AVStream *ast, int f 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); diff --git a/ffmpeg/libavformat/mmf.c b/ffmpeg/libavformat/mmf.c index f557eeb..e963112 100644 --- a/ffmpeg/libavformat/mmf.c +++ b/ffmpeg/libavformat/mmf.c @@ -82,7 +82,7 @@ static int mmf_write_header(AVFormatContext *s) 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); diff --git a/ffmpeg/libavformat/mov.c b/ffmpeg/libavformat/mov.c index ae48c02..8d66c0a 100644 --- a/ffmpeg/libavformat/mov.c +++ b/ffmpeg/libavformat/mov.c @@ -27,14 +27,13 @@ #include #include -//#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" @@ -68,6 +67,7 @@ typedef struct MOVParseTableEntry { } 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) @@ -258,13 +258,12 @@ static int mov_metadata_loci(MOVContext *c, AVIOContext *pb, unsigned len) 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) { @@ -346,29 +345,32 @@ static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom) } 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; @@ -380,8 +382,9 @@ static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom) } 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; } @@ -681,16 +684,16 @@ static int mov_read_chan(MOVContext *c, AVIOContext *pb, MOVAtom atom) 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) @@ -776,6 +779,21 @@ static int mov_read_moov(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); @@ -785,15 +803,15 @@ static void mov_metadata_creation_time(AVDictionary **metadata, int64_t time) { 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); } } @@ -915,6 +933,75 @@ static int mov_read_enda(MOVContext *c, AVIOContext *pb, MOVAtom atom) 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; @@ -1099,6 +1186,10 @@ static int mov_read_glbl(MOVContext *c, AVIOContext *pb, MOVAtom atom) 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); @@ -1174,10 +1265,12 @@ static int mov_read_stco(MOVContext *c, AVIOContext *pb, MOVAtom atom) 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; @@ -1422,6 +1515,10 @@ static void mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb, 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: @@ -1623,6 +1720,7 @@ static int mov_finalize_stsd_codec(MOVContext *c, AVIOContext *pb, } 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; @@ -1766,9 +1864,11 @@ static int mov_read_stsc(MOVContext *c, AVIOContext *pb, MOVAtom atom) 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); @@ -1800,9 +1900,11 @@ static int mov_read_stps(MOVContext *c, AVIOContext *pb, MOVAtom atom) 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); @@ -1844,9 +1946,11 @@ static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom) 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); @@ -1905,9 +2009,13 @@ static int mov_read_stsz(MOVContext *c, AVIOContext *pb, MOVAtom atom) 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); @@ -1961,11 +2069,11 @@ static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom) 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); @@ -2104,9 +2212,11 @@ static int mov_read_sbgp(MOVContext *c, AVIOContext *pb, MOVAtom atom) 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); @@ -2730,6 +2840,7 @@ static int mov_read_tfhd(MOVContext *c, AVIOContext *pb, MOVAtom atom) { MOVFragment *frag = &c->fragment; MOVTrackExt *trex = NULL; + MOVFragmentIndex* index = NULL; int flags, track_id, i; avio_r8(pb); /* version */ @@ -2748,6 +2859,15 @@ static int mov_read_tfhd(MOVContext *c, AVIOContext *pb, MOVAtom atom) 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 ? @@ -2760,6 +2880,25 @@ static int mov_read_tfhd(MOVContext *c, AVIOContext *pb, MOVAtom atom) 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; } @@ -2796,6 +2935,36 @@ static int mov_read_trex(MOVContext *c, AVIOContext *pb, MOVAtom atom) 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; @@ -2868,6 +3037,28 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom) 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; @@ -3096,6 +3287,28 @@ static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom) 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 }, @@ -3104,6 +3317,7 @@ static const MOVParseTableEntry mov_default_parse_table[] = { { 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 }, @@ -3140,6 +3354,7 @@ static const MOVParseTableEntry mov_default_parse_table[] = { { 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 }, @@ -3162,6 +3377,7 @@ static const MOVParseTableEntry mov_default_parse_table[] = { { 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 } }; @@ -3505,6 +3721,13 @@ static int mov_read_close(AVFormatContext *s) 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; } @@ -3542,6 +3765,106 @@ static void export_orphan_timecode(AVFormatContext *s) } } +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; @@ -3614,7 +3937,7 @@ static int mov_read_header(AVFormatContext *s) 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; } @@ -3634,6 +3957,17 @@ static int mov_read_header(AVFormatContext *s) } } + 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]; @@ -3858,26 +4192,42 @@ static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_ti 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, @@ -3885,6 +4235,5 @@ AVInputFormat ff_mov_demuxer = { .read_packet = mov_read_packet, .read_close = mov_read_close, .read_seek = mov_read_seek, - .priv_class = &mov_class, .flags = AVFMT_NO_BYTE_SEEK, }; diff --git a/ffmpeg/libavformat/movenc.c b/ffmpeg/libavformat/movenc.c index 021fe78..10e883c 100644 --- a/ffmpeg/libavformat/movenc.c +++ b/ffmpeg/libavformat/movenc.c @@ -31,6 +31,7 @@ #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" @@ -54,7 +55,7 @@ static const AVOption options[] = { { "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" }, @@ -62,6 +63,9 @@ static const AVOption options[] = { { "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}, @@ -70,9 +74,10 @@ static const AVOption options[] = { { "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 }, }; @@ -108,12 +113,6 @@ static int64_t update_size(AVIOContext *pb, int64_t pos) 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) @@ -292,6 +291,212 @@ static int mov_write_ac3_tag(AVIOContext *pb, MOVTrack *track) 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). @@ -486,6 +691,8 @@ static int mov_write_wave_tag(AVIOContext *pb, MOVTrack *track) 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); @@ -727,6 +934,8 @@ static int mov_write_audio_tag(AVIOContext *pb, MOVTrack *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 */ @@ -756,6 +965,7 @@ static int mov_write_audio_tag(AVIOContext *pb, MOVTrack *track) 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 || @@ -770,6 +980,8 @@ static int mov_write_audio_tag(AVIOContext *pb, MOVTrack *track) 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) @@ -877,6 +1089,7 @@ static int mp4_get_codec_tag(AVFormatContext *s, MOVTrack *track) 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'); @@ -1017,6 +1230,63 @@ static int mov_get_mpeg2_xdcam_codec_tag(AVFormatContext *s, MOVTrack *track) 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; @@ -1068,10 +1338,11 @@ static int mov_get_codec_tag(AVFormatContext *s, MOVTrack *track) { 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) @@ -1080,6 +1351,8 @@ static int mov_get_codec_tag(AVFormatContext *s, MOVTrack *track) 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 @@ -1294,7 +1567,7 @@ static int mov_write_video_tag(AVIOContext *pb, MOVTrack *track) 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); @@ -1760,7 +2033,8 @@ static int mov_write_minf_tag(AVIOContext *pb, MOVTrack *track) 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; @@ -1779,8 +2053,10 @@ static int mov_write_mdhd_tag(AVIOContext *pb, MOVTrack *track) 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 */ @@ -1796,12 +2072,13 @@ static int mov_write_mdhd_tag(AVIOContext *pb, MOVTrack *track) 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); @@ -1862,8 +2139,10 @@ static int mov_write_tkhd_tag(AVIOContext *pb, MOVMuxContext *mov, } 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); @@ -1944,7 +2223,8 @@ static int mov_write_tapt_tag(AVIOContext *pb, MOVTrack *track) } // 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); @@ -1969,6 +2249,11 @@ static int mov_write_edts_tag(AVIOContext *pb, MOVTrack *track) 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); @@ -1978,11 +2263,25 @@ static int mov_write_edts_tag(AVIOContext *pb, MOVTrack *track) } 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); @@ -2093,11 +2392,21 @@ static int mov_write_trak_tag(AVIOContext *pb, MOVMuxContext *mov, 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',' ')) @@ -2124,7 +2433,7 @@ static int mov_write_iods_tag(AVIOContext *pb, MOVMuxContext *mov) 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; } @@ -2826,6 +3135,10 @@ static int mov_write_tfhd_tag(AVIOContext *pb, MOVMuxContext *mov, } 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, @@ -2897,8 +3210,8 @@ static int mov_write_trun_tag(AVIOContext *pb, MOVMuxContext *mov, 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 + @@ -2917,6 +3230,7 @@ static int mov_write_trun_tag(AVIOContext *pb, MOVMuxContext *mov, avio_wb32(pb, track->cluster[i].cts); } + mov->first_trun = 0; return update_size(pb, pos); } @@ -2989,6 +3303,56 @@ static int mov_write_tfrf_tags(AVIOContext *pb, MOVMuxContext *mov, 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) @@ -2998,6 +3362,8 @@ static int mov_write_traf_tag(AVIOContext *pb, MOVMuxContext *mov, 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); @@ -3005,7 +3371,11 @@ static int mov_write_traf_tag(AVIOContext *pb, MOVMuxContext *mov, 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++) @@ -3024,6 +3394,7 @@ static int mov_write_moof_tag_internal(AVIOContext *pb, MOVMuxContext *mov, 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++) { @@ -3038,7 +3409,100 @@ static int mov_write_moof_tag_internal(AVIOContext *pb, MOVMuxContext *mov, 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; @@ -3047,6 +3511,13 @@ static int mov_write_moof_tag(AVIOContext *pb, MOVMuxContext *mov, int tracks) 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); } @@ -3065,7 +3536,7 @@ static int mov_write_tfra_tag(AVIOContext *pb, MOVTrack *track) 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 */ @@ -3141,6 +3612,8 @@ static int mov_write_ftyp_tag(AVIOContext *pb, AVFormatContext *s) 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) @@ -3158,14 +3631,18 @@ static int mov_write_ftyp_tag(AVIOContext *pb, AVFormatContext *s) 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) @@ -3174,6 +3651,10 @@ static int mov_write_ftyp_tag(AVIOContext *pb, AVFormatContext *s) 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); } @@ -3400,25 +3881,9 @@ static int mov_flush_fragment(AVFormatContext *s) } 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); @@ -3450,7 +3915,7 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt) 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) { @@ -3508,7 +3973,7 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt) 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); @@ -3524,7 +3989,7 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt) } 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) { @@ -3543,6 +4008,13 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt) } 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); } @@ -3552,16 +4024,20 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt) /* 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; } @@ -3572,17 +4048,44 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt) 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; @@ -3615,8 +4118,12 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt) 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) @@ -3630,6 +4137,13 @@ 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, @@ -4034,21 +4548,30 @@ static int mov_write_header(AVFormatContext *s) 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. */ @@ -4227,7 +4750,7 @@ static int mov_write_header(AVFormatContext *s) 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); @@ -4329,6 +4852,8 @@ static int mov_write_header(AVFormatContext *s) 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; @@ -4349,6 +4874,18 @@ static int get_moov_size(AVFormatContext *s) 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 @@ -4380,6 +4917,21 @@ static int compute_moov_size(AVFormatContext *s) 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; @@ -4390,7 +4942,10 @@ static int shift_data(AVFormatContext *s) 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; @@ -4497,7 +5052,7 @@ static int mov_write_trailer(AVFormatContext *s) 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) { @@ -4517,7 +5072,21 @@ static int mov_write_trailer(AVFormatContext *s) } } 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++) { diff --git a/ffmpeg/libavformat/movenc.h b/ffmpeg/libavformat/movenc.h index 9ce4a86..4cf6e3b 100644 --- a/ffmpeg/libavformat/movenc.h +++ b/ffmpeg/libavformat/movenc.h @@ -74,6 +74,7 @@ typedef struct MOVFragmentInfo { int64_t time; int64_t duration; int64_t tfrf_offset; + int size; } MOVFragmentInfo; typedef struct MOVTrack { @@ -128,7 +129,7 @@ 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; @@ -142,6 +143,8 @@ typedef struct MOVTrack { int packet_entry; int slices; } vc1_info; + + void *eac3_priv; } MOVTrack; typedef struct MOVMuxContext { @@ -169,8 +172,8 @@ 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 @@ -180,18 +183,23 @@ typedef struct MOVMuxContext { 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); diff --git a/ffmpeg/libavformat/mp3dec.c b/ffmpeg/libavformat/mp3dec.c index 4872afc..c4c1bb7 100644 --- a/ffmpeg/libavformat/mp3dec.c +++ b/ffmpeg/libavformat/mp3dec.c @@ -37,6 +37,7 @@ #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 @@ -168,8 +169,8 @@ static void mp3_parse_info_tag(AVFormatContext *s, AVStream *st, (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)); @@ -214,11 +215,17 @@ static void mp3_parse_info_tag(AVFormatContext *s, AVStream *st, /* 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}, @@ -450,6 +457,10 @@ static int mp3_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int64_t pos = ie->pos + (dir > 0 ? i - 1024 : -i); int64_t candidate = -1; int score = 999; + + if (pos < 0) + continue; + for(j=0; jmetadata, "TRCK", NULL, 0))) { //track buf[125] = 0; @@ -77,8 +80,8 @@ static int id3v1_create_tag(AVFormatContext *s, uint8_t *buf) #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; @@ -88,7 +91,18 @@ typedef struct MP3Context { 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; @@ -116,16 +130,17 @@ static int mp3_write_xing(AVFormatContext *s) { 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; @@ -178,16 +193,8 @@ static int mp3_write_xing(AVFormatContext *s) 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; @@ -195,32 +202,73 @@ static int mp3_write_xing(AVFormatContext *s) 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; } @@ -294,8 +342,12 @@ static int mp3_write_audio_packet(AVFormatContext *s, AVPacket *pkt) 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); @@ -324,26 +376,58 @@ static int mp3_queue_flush(AVFormatContext *s) 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); } @@ -366,6 +450,8 @@ static int mp3_write_trailer(struct AVFormatContext *s) if (mp3->xing_offset) mp3_update_xing(s); + av_freep(&mp3->xing_frame); + return 0; } diff --git a/ffmpeg/libavformat/mpeg.c b/ffmpeg/libavformat/mpeg.c index b153727..827a3c2 100644 --- a/ffmpeg/libavformat/mpeg.c +++ b/ffmpeg/libavformat/mpeg.c @@ -683,6 +683,7 @@ static int vobsub_read_header(AVFormatContext *s) 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); @@ -695,7 +696,22 @@ static int vobsub_read_header(AVFormatContext *s) } 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; diff --git a/ffmpeg/libavformat/mpegenc.c b/ffmpeg/libavformat/mpegenc.c index d3af9e1..b151506 100644 --- a/ffmpeg/libavformat/mpegenc.c +++ b/ffmpeg/libavformat/mpegenc.c @@ -1080,8 +1080,10 @@ retry: 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; diff --git a/ffmpeg/libavformat/mpegts.c b/ffmpeg/libavformat/mpegts.c index 8808269..97da0a3 100644 --- a/ffmpeg/libavformat/mpegts.c +++ b/ffmpeg/libavformat/mpegts.c @@ -29,6 +29,7 @@ #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" @@ -140,6 +141,8 @@ struct MpegTSContext { int skip_changes; int skip_clear; + int scan_all_pmts; + int resync_size; /******************************************/ @@ -164,6 +167,8 @@ static const AVOption options[] = { {.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, @@ -298,11 +303,17 @@ static void add_pid_to_pmt(MpegTSContext *ts, unsigned int programid, 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; } @@ -701,6 +712,7 @@ static const StreamType REGD_types[] = { { 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 }, }; @@ -1499,13 +1511,28 @@ static void m4sl_cb(MpegTSFilter *filter, const uint8_t *section, 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; @@ -1710,6 +1737,41 @@ int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type 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; } @@ -1740,15 +1802,17 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len 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; @@ -1925,8 +1989,10 @@ static void pat_cb(MpegTSFilter *filter, const uint8_t *section, int section_len } 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 @@ -2134,14 +2200,19 @@ static int handle_packet(MpegTSContext *ts, const uint8_t *packet) // 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<codec->codec_type; + } + if ((types & (1< 100000) { av_log(ts->stream, AV_LOG_DEBUG, "All programs have pmt, headers found\n"); ts->stream->ctx_flags &= ~AVFMTCTX_NOHEADER; } diff --git a/ffmpeg/libavformat/mpegtsenc.c b/ffmpeg/libavformat/mpegtsenc.c index 0184d87..a32c6d6 100644 --- a/ffmpeg/libavformat/mpegtsenc.c +++ b/ffmpeg/libavformat/mpegtsenc.c @@ -577,7 +577,7 @@ static void mpegts_prefix_m2ts_header(AVFormatContext *s) 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)); } } @@ -721,6 +721,7 @@ static int mpegts_write_header(AVFormatContext *s) 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; @@ -1197,7 +1198,9 @@ int ff_check_h264_startcode(AVFormatContext *s, const AVStream *st, const AVPack "('-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; } @@ -1209,7 +1212,9 @@ static int check_hevc_startcode(AVFormatContext *s, const AVStream *st, const AV 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; } @@ -1433,7 +1438,7 @@ static const AVOption options[] = { { .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 }, diff --git a/ffmpeg/libavformat/mpjpeg.c b/ffmpeg/libavformat/mpjpeg.c index a6e2a89..7b975e2 100644 --- a/ffmpeg/libavformat/mpjpeg.c +++ b/ffmpeg/libavformat/mpjpeg.c @@ -18,17 +18,24 @@ * 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; @@ -36,6 +43,7 @@ static int mpjpeg_write_header(AVFormatContext *s) 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"); @@ -45,7 +53,7 @@ static int mpjpeg_write_packet(AVFormatContext *s, AVPacket *pkt) 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; } @@ -55,15 +63,29 @@ static int mpjpeg_write_trailer(AVFormatContext *s) 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, }; diff --git a/ffmpeg/libavformat/mtv.c b/ffmpeg/libavformat/mtv.c index 1d5f266..addad24 100644 --- a/ffmpeg/libavformat/mtv.c +++ b/ffmpeg/libavformat/mtv.c @@ -112,7 +112,7 @@ static int mtv_read_header(AVFormatContext *s) 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); @@ -128,17 +128,17 @@ static int mtv_read_header(AVFormatContext *s) /* 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); diff --git a/ffmpeg/libavformat/mux.c b/ffmpeg/libavformat/mux.c index 55add43..023832c 100644 --- a/ffmpeg/libavformat/mux.c +++ b/ffmpeg/libavformat/mux.c @@ -171,16 +171,6 @@ error: 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; @@ -209,7 +199,7 @@ static int validate_codec_tag(AVFormatContext *s, AVStream *st) } 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; } @@ -429,10 +419,11 @@ int avformat_write_header(AVFormatContext *s, AVDictionary **options) 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; @@ -465,7 +456,7 @@ static int compute_pkt_fields2(AVFormatContext *s, AVStream *st, AVPacket *pkt) /* 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); } @@ -506,8 +497,10 @@ static int compute_pkt_fields2(AVFormatContext *s, AVStream *st, AVPacket *pkt) 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); } @@ -564,12 +557,13 @@ static int write_packet(AVFormatContext *s, AVPacket *pkt) 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, @@ -582,7 +576,16 @@ static int write_packet(AVFormatContext *s, AVPacket *pkt) 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); @@ -923,7 +926,7 @@ int av_write_trailer(AVFormatContext *s) 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; @@ -940,10 +943,14 @@ int av_write_trailer(AVFormatContext *s) 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) diff --git a/ffmpeg/libavformat/mvdec.c b/ffmpeg/libavformat/mvdec.c index 6e7c3ff..c8a5ebf 100644 --- a/ffmpeg/libavformat/mvdec.c +++ b/ffmpeg/libavformat/mvdec.c @@ -57,7 +57,12 @@ static int mv_probe(AVProbeData *p) 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); @@ -218,7 +223,7 @@ static int parse_video_var(AVFormatContext *avctx, AVStream *st, 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)) { @@ -233,11 +238,16 @@ static void read_table(AVFormatContext *avctx, AVStream *st, 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) @@ -263,6 +273,7 @@ static int mv_read_header(AVFormatContext *avctx) AVIOContext *pb = avctx->pb; AVStream *ast = NULL, *vst = NULL; //initialization to suppress warning int version, i; + int ret; avio_skip(pb, 4); @@ -335,7 +346,8 @@ static int mv_read_header(AVFormatContext *avctx) } 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"); @@ -345,7 +357,8 @@ static int mv_read_header(AVFormatContext *avctx) 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) { @@ -371,7 +384,8 @@ static int mv_read_header(AVFormatContext *avctx) 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) diff --git a/ffmpeg/libavformat/mxf.c b/ffmpeg/libavformat/mxf.c index 4dc54d7..14d143e 100644 --- a/ffmpeg/libavformat/mxf.c +++ b/ffmpeg/libavformat/mxf.c @@ -94,6 +94,7 @@ static const struct { {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); diff --git a/ffmpeg/libavformat/mxf.h b/ffmpeg/libavformat/mxf.h index 036c15e..d9e17c6 100644 --- a/ffmpeg/libavformat/mxf.h +++ b/ffmpeg/libavformat/mxf.h @@ -33,6 +33,7 @@ enum MXFMetadataSetType { SourcePackage, SourceClip, TimecodeComponent, + PulldownComponent, Sequence, MultipleDescriptor, Descriptor, @@ -45,6 +46,7 @@ enum MXFMetadataSetType { IndexTableSegment, EssenceContainerData, TypeBottom,// add metadata type before this + EssenceGroup, }; enum MXFFrameLayout { diff --git a/ffmpeg/libavformat/mxfdec.c b/ffmpeg/libavformat/mxfdec.c index 1dcdae0..0c88a8a 100644 --- a/ffmpeg/libavformat/mxfdec.c +++ b/ffmpeg/libavformat/mxfdec.c @@ -89,6 +89,7 @@ typedef struct { 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 { @@ -126,6 +127,20 @@ 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; @@ -154,6 +169,7 @@ typedef struct { 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; @@ -188,6 +204,7 @@ typedef struct { int tracks_count; MXFDescriptor *descriptor; /* only one */ UID descriptor_ref; + char *name; } MXFPackage; typedef struct { @@ -219,7 +236,6 @@ 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; @@ -425,6 +441,10 @@ static int mxf_read_primer_pack(void *arg, AVIOContext *pb, int tag, int size, U 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); @@ -461,6 +481,7 @@ static int mxf_read_partition_pack(void *arg, AVIOContext *pb, int tag, int size 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: @@ -536,6 +557,7 @@ static int mxf_read_partition_pack(void *arg, AVIOContext *pb, int tag, int size 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, @@ -619,6 +641,9 @@ static int mxf_read_content_storage(void *arg, AVIOContext *pb, int tag, int siz 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) @@ -652,22 +677,6 @@ static int mxf_read_source_clip(void *arg, AVIOContext *pb, int tag, int size, U 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; @@ -685,6 +694,17 @@ static int mxf_read_timecode_component(void *arg, AVIOContext *pb, int tag, int 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; @@ -722,8 +742,10 @@ static int mxf_read_sequence(void *arg, AVIOContext *pb, int tag, int size, UID 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; @@ -731,7 +753,49 @@ static int mxf_read_sequence(void *arg, AVIOContext *pb, int tag, int size, UID 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) { @@ -751,6 +815,8 @@ static int mxf_read_source_package(void *arg, AVIOContext *pb, int tag, int size case 0x4701: avio_read(pb, package->descriptor_ref, 16); break; + case 0x4402: + return mxf_read_utf16_string(pb, size, &package->name); } return 0; } @@ -838,7 +904,6 @@ static void mxf_read_pixel_layout(AVIOContext *pb, MXFDescriptor *descriptor) 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); @@ -848,6 +913,9 @@ static int mxf_read_generic_descriptor(void *arg, AVIOContext *pb, int tag, int 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; @@ -960,6 +1028,7 @@ static const MXFCodecUL mxf_picture_essence_container_uls[] = { { { 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 }, }; @@ -1366,6 +1435,34 @@ static int mxf_is_intra_only(MXFDescriptor *descriptor) &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]; @@ -1374,10 +1471,155 @@ static int mxf_add_timecode_metadata(AVDictionary **pm, const char *key, AVTimec 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); @@ -1391,6 +1633,10 @@ static int mxf_parse_structural_metadata(MXFContext *mxf) 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; @@ -1440,19 +1686,11 @@ static int mxf_parse_structural_metadata(MXFContext *mxf) /* 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; @@ -1571,6 +1809,12 @@ static int mxf_parse_structural_metadata(MXFContext *mxf) } 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); @@ -1606,6 +1850,7 @@ static int mxf_parse_structural_metadata(MXFContext *mxf) 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. */ @@ -1638,6 +1883,8 @@ static int mxf_parse_structural_metadata(MXFContext *mxf) 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. */ @@ -1706,45 +1953,6 @@ fail_and_free: 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 }; @@ -1767,7 +1975,8 @@ static int mxf_timestamp_to_str(uint64_t timestamp, char **str) *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; } @@ -1843,9 +2052,10 @@ static const MXFMetadataReadTableEntry mxf_metadata_read_table[] = { { { 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 */ @@ -1860,11 +2070,26 @@ static const MXFMetadataReadTableEntry mxf_metadata_read_table[] = { { { 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; @@ -1873,6 +2098,7 @@ static int mxf_read_local_tags(MXFContext *mxf, KLVPacket *klv, MXFMetadataReadF 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); @@ -1919,23 +2145,98 @@ static int mxf_read_local_tags(MXFContext *mxf, KLVPacket *klv, MXFMetadataReadF } /** - * 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; } @@ -1951,30 +2252,27 @@ static int mxf_parse_handle_essence(MXFContext *mxf) 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; } @@ -2012,7 +2310,7 @@ static void mxf_compute_essence_containers(MXFContext *mxf) 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; @@ -2075,16 +2373,33 @@ static void mxf_read_random_index_pack(AVFormatContext *s) { 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 || @@ -2093,7 +2408,13 @@ static void mxf_read_random_index_pack(AVFormatContext *s) 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); @@ -2104,8 +2425,6 @@ static int mxf_read_header(AVFormatContext *s) 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; @@ -2123,12 +2442,7 @@ static int mxf_read_header(AVFormatContext *s) 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) @@ -2180,8 +2494,7 @@ static int mxf_read_header(AVFormatContext *s) 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; @@ -2192,26 +2505,8 @@ static int mxf_read_header(AVFormatContext *s) 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", @@ -2426,7 +2721,7 @@ static int mxf_read_packet_old(AVFormatContext *s, AVPacket *pkt) 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 @@ -2541,9 +2836,13 @@ static int mxf_read_close(AVFormatContext *s) 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]; diff --git a/ffmpeg/libavformat/mxfenc.c b/ffmpeg/libavformat/mxfenc.c index 6a6b7c2..a850239 100644 --- a/ffmpeg/libavformat/mxfenc.c +++ b/ffmpeg/libavformat/mxfenc.c @@ -26,6 +26,7 @@ * 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 */ @@ -38,8 +39,11 @@ #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" @@ -95,6 +99,8 @@ static const struct { { 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 } }; @@ -266,6 +272,16 @@ static const MXFContainerEssenceEntry mxf_essence_container_uls[] = { { 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 }, @@ -981,17 +997,21 @@ static void mxf_write_mpegvideo_desc(AVFormatContext *s, AVStream *st) 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) @@ -1564,6 +1584,95 @@ static int mxf_parse_dv_frame(AVFormatContext *s, AVStream *st, AVPacket *pkt) 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 @@ -1657,7 +1766,8 @@ static int mxf_parse_mpeg2_frame(AVFormatContext *s, AVStream *st, 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 | @@ -1969,6 +2079,11 @@ static int mxf_write_packet(AVFormatContext *s, AVPacket *pkt) 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) { diff --git a/ffmpeg/libavformat/network.h b/ffmpeg/libavformat/network.h index d89a62d..0d1081a 100644 --- a/ffmpeg/libavformat/network.h +++ b/ffmpeg/libavformat/network.h @@ -111,6 +111,14 @@ struct sockaddr_storage { }; #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 diff --git a/ffmpeg/libavformat/nut.c b/ffmpeg/libavformat/nut.c index 9224a96..86a0301 100644 --- a/ffmpeg/libavformat/nut.c +++ b/ffmpeg/libavformat/nut.c @@ -40,6 +40,7 @@ const AVCodecTag ff_nut_data_tags[] = { }; 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 ) }, diff --git a/ffmpeg/libavformat/nutdec.c b/ffmpeg/libavformat/nutdec.c index 1b00cdb..ef29bdf 100644 --- a/ffmpeg/libavformat/nutdec.c +++ b/ffmpeg/libavformat/nutdec.c @@ -484,7 +484,7 @@ static int decode_info_header(NUTContext *nut) 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; @@ -994,11 +994,10 @@ static int decode_frame(NUTContext *nut, AVPacket *pkt, int frame_code) { 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) @@ -1020,8 +1019,9 @@ static int decode_frame(NUTContext *nut, AVPacket *pkt, int frame_code) 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) { diff --git a/ffmpeg/libavformat/nutenc.c b/ffmpeg/libavformat/nutenc.c index 5db380f..3424e26 100644 --- a/ffmpeg/libavformat/nutenc.c +++ b/ffmpeg/libavformat/nutenc.c @@ -1119,6 +1119,7 @@ static int nut_write_packet(AVFormatContext *s, AVPacket *pkt) } } av_assert0(frame_code != -1); + fc = &nut->frame_code[frame_code]; flags = fc->flags; needed_flags = get_needed_flags(nut, nus, fc, pkt); diff --git a/ffmpeg/libavformat/oggenc.c b/ffmpeg/libavformat/oggenc.c index 4a54126..f3413c5 100644 --- a/ffmpeg/libavformat/oggenc.c +++ b/ffmpeg/libavformat/oggenc.c @@ -307,12 +307,10 @@ static int ogg_build_flac_headers(AVCodecContext *avctx, 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; @@ -328,7 +326,7 @@ static int ogg_build_flac_headers(AVCodecContext *avctx, 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); @@ -350,7 +348,7 @@ static int ogg_build_speex_headers(AVCodecContext *avctx, 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); @@ -379,7 +377,7 @@ static int ogg_build_opus_headers(AVCodecContext *avctx, 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); @@ -448,12 +446,12 @@ static int ogg_write_header(AVFormatContext *s) 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) @@ -513,7 +511,7 @@ static int ogg_write_header(AVFormatContext *s) 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, @@ -582,7 +580,10 @@ static int ogg_write_packet_internal(AVFormatContext *s, AVPacket *pkt) } granule = (oggstream->last_kf_pts<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; diff --git a/ffmpeg/libavformat/oggparsedirac.c b/ffmpeg/libavformat/oggparsedirac.c index 73bc495..10fb07e 100644 --- a/ffmpeg/libavformat/oggparsedirac.c +++ b/ffmpeg/libavformat/oggparsedirac.c @@ -43,7 +43,7 @@ static int dirac_header(AVFormatContext *s, int idx) 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; } diff --git a/ffmpeg/libavformat/oggparseflac.c b/ffmpeg/libavformat/oggparseflac.c index 9f0f808..c7fb446 100644 --- a/ffmpeg/libavformat/oggparseflac.c +++ b/ffmpeg/libavformat/oggparseflac.c @@ -34,7 +34,6 @@ flac_header (AVFormatContext * s, int idx) struct ogg_stream *os = ogg->streams + idx; AVStream *st = s->streams[idx]; GetBitContext gb; - FLACStreaminfo si; int mdt; if (os->buf[os->pstart] == 0xff) @@ -46,6 +45,8 @@ flac_header (AVFormatContext * s, int idx) 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; @@ -56,8 +57,6 @@ flac_header (AVFormatContext * s, int idx) 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; @@ -66,7 +65,11 @@ flac_header (AVFormatContext * s, int idx) 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); } diff --git a/ffmpeg/libavformat/oggparsevorbis.c b/ffmpeg/libavformat/oggparsevorbis.c index 5e34be5..dd44337 100644 --- a/ffmpeg/libavformat/oggparsevorbis.c +++ b/ffmpeg/libavformat/oggparsevorbis.c @@ -213,7 +213,7 @@ int ff_vorbis_comment(AVFormatContext *as, AVDictionary **m, struct oggvorbis_private { unsigned int len[3]; unsigned char *packet[3]; - VorbisParseContext vp; + AVVorbisParseContext *vp; int64_t final_pts; int final_duration; }; @@ -253,9 +253,11 @@ static void vorbis_cleanup(AVFormatContext *s, int idx) 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) @@ -302,14 +304,14 @@ static int vorbis_header(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]) @@ -385,10 +387,12 @@ static int vorbis_header(AVFormatContext *s, int idx) 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; } } @@ -411,10 +415,10 @@ static int vorbis_packet(AVFormatContext *s, int idx) 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; @@ -426,7 +430,7 @@ static int vorbis_packet(AVFormatContext *s, int idx) 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; @@ -451,12 +455,12 @@ static int vorbis_packet(AVFormatContext *s, int idx) 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; diff --git a/ffmpeg/libavformat/options.c b/ffmpeg/libavformat/options.c index e0d6df6..5044043 100644 --- a/ffmpeg/libavformat/options.c +++ b/ffmpeg/libavformat/options.c @@ -110,6 +110,7 @@ AVFormatContext *avformat_alloc_context(void) 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) { diff --git a/ffmpeg/libavformat/options_table.h b/ffmpeg/libavformat/options_table.h index 71024be..40f1e0a 100644 --- a/ffmpeg/libavformat/options_table.h +++ b/ffmpeg/libavformat/options_table.h @@ -78,11 +78,6 @@ static const AVOption avformat_options[] = { {"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}, @@ -96,6 +91,14 @@ static const AVOption avformat_options[] = { {"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}, }; diff --git a/ffmpeg/libavformat/os_support.c b/ffmpeg/libavformat/os_support.c index e8f063a..f9d6eea 100644 --- a/ffmpeg/libavformat/os_support.c +++ b/ffmpeg/libavformat/os_support.c @@ -21,6 +21,7 @@ */ /* needed by inet_aton() */ +#define _DEFAULT_SOURCE #define _SVID_SOURCE #include "config.h" diff --git a/ffmpeg/libavformat/os_support.h b/ffmpeg/libavformat/os_support.h index 1522740..ffae4b7 100644 --- a/ffmpeg/libavformat/os_support.h +++ b/ffmpeg/libavformat/os_support.h @@ -31,6 +31,15 @@ #include +#ifdef _WIN32 +#if HAVE_DIRECT_H +#include +#endif +#if HAVE_IO_H +#include +#endif +#endif + #if defined(_WIN32) && !defined(__MINGW32CE__) # include # ifdef lseek @@ -47,13 +56,15 @@ # define fstat(f,s) _fstati64((f), (s)) #endif /* defined(_WIN32) && !defined(__MINGW32CE__) */ -#ifdef _WIN32 -#if HAVE_DIRECT_H -#include -#elif HAVE_IO_H -#include -#endif -#define mkdir(a, b) _mkdir(a) + +#ifdef __ANDROID__ +# if HAVE_UNISTD_H +# include +# 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) @@ -128,4 +139,86 @@ int ff_poll(struct pollfd *fds, nfds_t numfds, int timeout); #endif /* HAVE_POLL_H */ #endif /* CONFIG_NETWORK */ +#if defined(__MINGW32CE__) +#define mkdir(a, b) _mkdir(a) +#elif defined(_WIN32) +#include +#include +#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 */ diff --git a/ffmpeg/libavformat/qcp.c b/ffmpeg/libavformat/qcp.c index 4d42197..ccfa047 100644 --- a/ffmpeg/libavformat/qcp.c +++ b/ffmpeg/libavformat/qcp.c @@ -30,6 +30,7 @@ #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 @@ -106,7 +107,8 @@ static int qcp_read_header(AVFormatContext *s) } 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 diff --git a/ffmpeg/libavformat/rawdec.c b/ffmpeg/libavformat/rawdec.c index ca9b282..bbb76b6 100644 --- a/ffmpeg/libavformat/rawdec.c +++ b/ffmpeg/libavformat/rawdec.c @@ -84,6 +84,7 @@ int ff_raw_video_read_header(AVFormatContext *s) 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); @@ -118,6 +119,7 @@ AVInputFormat ff_data_demuxer = { .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 @@ -128,7 +130,7 @@ AVInputFormat ff_latm_demuxer = { .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, }; @@ -210,7 +212,7 @@ AVInputFormat ff_mlp_demuxer = { .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, }; @@ -222,7 +224,7 @@ AVInputFormat ff_truehd_demuxer = { .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, }; @@ -234,7 +236,7 @@ AVInputFormat ff_shorten_demuxer = { .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, }; diff --git a/ffmpeg/libavformat/rdt.c b/ffmpeg/libavformat/rdt.c index e8dc8f5..158a821 100644 --- a/ffmpeg/libavformat/rdt.c +++ b/ffmpeg/libavformat/rdt.c @@ -523,18 +523,27 @@ static PayloadContext * 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) { @@ -559,6 +568,7 @@ static RTPDynamicProtocolHandler rdt_ ## n ## _handler = { \ .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 \ } diff --git a/ffmpeg/libavformat/realtextdec.c b/ffmpeg/libavformat/realtextdec.c index 19af108..fff85d6 100644 --- a/ffmpeg/libavformat/realtextdec.c +++ b/ffmpeg/libavformat/realtextdec.c @@ -65,7 +65,7 @@ static int realtext_read_header(AVFormatContext *s) 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); diff --git a/ffmpeg/libavformat/riff.c b/ffmpeg/libavformat/riff.c index 053038b..8d7b1c2 100644 --- a/ffmpeg/libavformat/riff.c +++ b/ffmpeg/libavformat/riff.c @@ -341,6 +341,7 @@ const AVCodecTag ff_codec_bmp_tags[] = { /* 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') }, @@ -359,7 +360,9 @@ const AVCodecTag ff_codec_bmp_tags[] = { { 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 } }; diff --git a/ffmpeg/libavformat/riff.h b/ffmpeg/libavformat/riff.h index 88a77b0..e925634 100644 --- a/ffmpeg/libavformat/riff.h +++ b/ffmpeg/libavformat/riff.h @@ -91,10 +91,13 @@ typedef struct AVCodecGuid { 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 \ diff --git a/ffmpeg/libavformat/riffdec.c b/ffmpeg/libavformat/riffdec.c index 09fee9d..88e2229 100644 --- a/ffmpeg/libavformat/riffdec.c +++ b/ffmpeg/libavformat/riffdec.c @@ -84,6 +84,9 @@ int ff_get_wav_header(AVIOContext *pb, AVCodecContext *codec, int size) { 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); diff --git a/ffmpeg/libavformat/riffenc.c b/ffmpeg/libavformat/riffenc.c index 2eb2ae1..5e85800 100644 --- a/ffmpeg/libavformat/riffenc.c +++ b/ffmpeg/libavformat/riffenc.c @@ -68,8 +68,6 @@ int ff_put_wav_header(AVIOContext *pb, AVCodecContext *enc, int flags) * 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 || @@ -104,12 +102,10 @@ int ff_put_wav_header(AVIOContext *pb, AVCodecContext *enc, int flags) 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) { diff --git a/ffmpeg/libavformat/rmdec.c b/ffmpeg/libavformat/rmdec.c index 5d9c9b5..19bd7a7 100644 --- a/ffmpeg/libavformat/rmdec.c +++ b/ffmpeg/libavformat/rmdec.c @@ -312,6 +312,9 @@ ff_rm_read_mdpr_codecdata (AVFormatContext *s, AVIOContext *pb, 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); @@ -610,7 +613,7 @@ static int get_num(AVIOContext *pb, int *len) /* 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; @@ -918,8 +921,9 @@ ff_rm_retrieve_cache (AVFormatContext *s, AVIOContext *pb, 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); @@ -963,12 +967,12 @@ static int rm_read_packet(AVFormatContext *s, AVPacket *pkt) 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, @@ -1034,7 +1038,7 @@ static int64_t rm_read_dts(AVFormatContext *s, int stream_index, 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; diff --git a/ffmpeg/libavformat/rtmppkt.c b/ffmpeg/libavformat/rtmppkt.c index 92172dc..4f79487 100644 --- a/ffmpeg/libavformat/rtmppkt.c +++ b/ffmpeg/libavformat/rtmppkt.c @@ -396,7 +396,7 @@ int ff_rtmp_packet_create(RTMPPacket *pkt, int channel_id, RTMPPacketType type, int timestamp, int size) { if (size) { - pkt->data = av_malloc(size); + pkt->data = av_realloc(NULL, size); if (!pkt->data) return AVERROR(ENOMEM); } diff --git a/ffmpeg/libavformat/rtmpproto.c b/ffmpeg/libavformat/rtmpproto.c index 3cde966..ebc1628 100644 --- a/ffmpeg/libavformat/rtmpproto.c +++ b/ffmpeg/libavformat/rtmpproto.c @@ -96,6 +96,7 @@ typedef struct RTMPContext { uint32_t client_report_size; ///< number of bytes after which client should report to server uint32_t bytes_read; ///< number of bytes read from server uint32_t last_bytes_read; ///< number of bytes read last reported to server + 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 @@ -123,6 +124,7 @@ typedef struct RTMPContext { 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]; @@ -503,7 +505,7 @@ static int read_connect(URLContext *s, RTMPContext *rt) 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) @@ -676,6 +678,30 @@ static int gen_delete_stream(URLContext *s, RTMPContext *rt) 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. */ @@ -748,6 +774,33 @@ static int gen_seek(URLContext *s, RTMPContext *rt, int64_t timestamp) 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. */ @@ -1769,6 +1822,9 @@ static int handle_invoke_error(URLContext *s, RTMPPacket *pkt) /* 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) { @@ -1956,6 +2012,45 @@ static int send_invoke_response(URLContext *s, RTMPPacket *pkt) 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; @@ -1997,22 +2092,30 @@ static int handle_invoke_result(URLContext *s, RTMPPacket *pkt) } } } 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: @@ -2327,6 +2430,10 @@ static int get_packet(URLContext *s, int for_header) 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"); @@ -2413,6 +2520,70 @@ static int rtmp_close(URLContext *h) 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. * @@ -2426,7 +2597,7 @@ static int rtmp_open(URLContext *s, const char *uri, int flags) { 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; @@ -2441,11 +2612,13 @@ static int rtmp_open(URLContext *s, const char *uri, int flags) 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]) { @@ -2544,8 +2717,14 @@ reconnect: 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, ':'); @@ -2571,24 +2750,27 @@ reconnect: } 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) { @@ -2624,6 +2806,7 @@ reconnect: 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); @@ -2655,11 +2838,10 @@ reconnect: } 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); @@ -2670,7 +2852,7 @@ reconnect: // 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 @@ -2682,6 +2864,14 @@ reconnect: 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; @@ -2746,11 +2936,25 @@ static int64_t rtmp_seek(URLContext *s, int stream_index, int64_t timestamp, 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; @@ -2767,8 +2971,9 @@ static int rtmp_write(URLContext *s, const uint8_t *buf, int size) 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; @@ -2785,15 +2990,15 @@ static int rtmp_write(URLContext *s, const uint8_t *buf, int size) 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; } @@ -2804,24 +3009,43 @@ static int rtmp_write(URLContext *s, const uint8_t *buf, int size) 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; @@ -2908,6 +3132,7 @@ URLProtocol ff_##flavor##_protocol = { \ .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), \ diff --git a/ffmpeg/libavformat/rtpdec.c b/ffmpeg/libavformat/rtpdec.c index a78af87..33205aa 100644 --- a/ffmpeg/libavformat/rtpdec.c +++ b/ffmpeg/libavformat/rtpdec.c @@ -77,7 +77,6 @@ void ff_register_rtp_dynamic_payload_handlers(void) 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); @@ -144,7 +143,7 @@ static int rtcp_parse_packet(RTPDemuxContext *s, const unsigned char *buf, 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) { @@ -324,7 +323,7 @@ int ff_rtp_check_and_send_back_rr(RTPDemuxContext *s, URLContext *fd, 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 */ @@ -449,7 +448,7 @@ int ff_rtp_send_rtcp_feedback(RTPDemuxContext *s, URLContext *fd, /* 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; @@ -692,7 +691,7 @@ static void enqueue_packet(RTPDemuxContext *s, uint8_t *buf, int len) 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; @@ -770,7 +769,7 @@ static int rtp_parse_one_packet(RTPDemuxContext *s, AVPacket *pkt, } 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); diff --git a/ffmpeg/libavformat/rtpdec_asf.c b/ffmpeg/libavformat/rtpdec_asf.c index 8e19654..44c0a24 100644 --- a/ffmpeg/libavformat/rtpdec_asf.c +++ b/ffmpeg/libavformat/rtpdec_asf.c @@ -25,6 +25,7 @@ * @author Ronald S. Bultje */ +#include "libavutil/avassert.h" #include "libavutil/base64.h" #include "libavutil/avstring.h" #include "libavutil/intreadwrite.h" @@ -102,6 +103,8 @@ int ff_wms_parse_sdp_a_line(AVFormatContext *s, const char *p) 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) @@ -111,11 +114,19 @@ int ff_wms_parse_sdp_a_line(AVFormatContext *s, const char *p) 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; diff --git a/ffmpeg/libavformat/rtpdec_formats.h b/ffmpeg/libavformat/rtpdec_formats.h index d915fab..803410e 100644 --- a/ffmpeg/libavformat/rtpdec_formats.h +++ b/ffmpeg/libavformat/rtpdec_formats.h @@ -50,7 +50,6 @@ extern RTPDynamicProtocolHandler ff_h263_1998_dynamic_handler; 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; diff --git a/ffmpeg/libavformat/rtpdec_h261.c b/ffmpeg/libavformat/rtpdec_h261.c index b902d2a..43244bb 100644 --- a/ffmpeg/libavformat/rtpdec_h261.c +++ b/ffmpeg/libavformat/rtpdec_h261.c @@ -32,7 +32,7 @@ struct PayloadContext { uint32_t timestamp; }; -static PayloadContext *h261_new_context(void) +static av_cold PayloadContext *h261_new_context(void) { return av_mallocz(sizeof(PayloadContext)); } @@ -45,7 +45,7 @@ static void h261_free_dyn_buffer(AVIOContext **dyn_buf) *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) @@ -80,16 +80,14 @@ int ff_h261_handle_packet(AVFormatContext *ctx, PayloadContext *data, 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; } diff --git a/ffmpeg/libavformat/rtpdec_hevc.c b/ffmpeg/libavformat/rtpdec_hevc.c index 60a97e4..ac4c765 100644 --- a/ffmpeg/libavformat/rtpdec_hevc.c +++ b/ffmpeg/libavformat/rtpdec_hevc.c @@ -21,6 +21,7 @@ */ #include "libavutil/avstring.h" +#include "libavutil/base64.h" #include "avformat.h" #include "rtpdec.h" @@ -34,6 +35,8 @@ 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 }; @@ -85,6 +88,61 @@ static av_cold int hevc_sdp_parse_fmtp_config(AVFormatContext *s, /* 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 */ @@ -162,8 +220,41 @@ static av_cold int hevc_parse_sdp_line(AVFormatContext *ctx, int st_index, /* 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; @@ -270,8 +361,6 @@ static int hevc_handle_packet(AVFormatContext *ctx, PayloadContext *rtp_hevc_ctx buf += RTP_HEVC_PAYLOAD_HEADER_SIZE; len -= RTP_HEVC_PAYLOAD_HEADER_SIZE; - if (len < 1) - return AVERROR_INVALIDDATA; /* decode the FU header @@ -300,6 +389,7 @@ static int hevc_handle_packet(AVFormatContext *ctx, PayloadContext *rtp_hevc_ctx 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]; @@ -328,11 +418,14 @@ static int hevc_handle_packet(AVFormatContext *ctx, PayloadContext *rtp_hevc_ctx 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; @@ -350,17 +443,6 @@ static int hevc_handle_packet(AVFormatContext *ctx, PayloadContext *rtp_hevc_ctx } 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, diff --git a/ffmpeg/libavformat/rtpenc.c b/ffmpeg/libavformat/rtpenc.c index 9c587d2..c608dfb 100644 --- a/ffmpeg/libavformat/rtpenc.c +++ b/ffmpeg/libavformat/rtpenc.c @@ -53,6 +53,7 @@ static int is_supported(enum AVCodecID id) 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: @@ -200,6 +201,15 @@ static int rtp_write_header(AVFormatContext *s1) 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; @@ -577,6 +587,9 @@ static int rtp_write_packet(AVFormatContext *s1, AVPacket *pkt) 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); diff --git a/ffmpeg/libavformat/rtpenc.h b/ffmpeg/libavformat/rtpenc.h index 48b6b02..4eb98d8 100644 --- a/ffmpeg/libavformat/rtpenc.h +++ b/ffmpeg/libavformat/rtpenc.h @@ -85,6 +85,7 @@ void ff_rtp_send_h261(AVFormatContext *s1, const uint8_t *buf1, int 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); diff --git a/ffmpeg/libavformat/rtpenc_chain.c b/ffmpeg/libavformat/rtpenc_chain.c index dea1f70..b2aa124 100644 --- a/ffmpeg/libavformat/rtpenc_chain.c +++ b/ffmpeg/libavformat/rtpenc_chain.c @@ -75,6 +75,7 @@ int ff_rtp_chain_mux_open(AVFormatContext **out, AVFormatContext *s, 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); diff --git a/ffmpeg/libavformat/rtpenc_h263_rfc2190.c b/ffmpeg/libavformat/rtpenc_h263_rfc2190.c index 0493008..34b3906 100644 --- a/ffmpeg/libavformat/rtpenc_h263_rfc2190.c +++ b/ffmpeg/libavformat/rtpenc_h263_rfc2190.c @@ -150,9 +150,12 @@ void ff_rtp_send_h263_rfc2190(AVFormatContext *s1, const uint8_t *buf, int size, } 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]); @@ -160,13 +163,9 @@ void ff_rtp_send_h263_rfc2190(AVFormatContext *s1, const uint8_t *buf, int size, 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, " diff --git a/ffmpeg/libavformat/rtpenc_h264.c b/ffmpeg/libavformat/rtpenc_h264.c index b6c16e1..d2b2ed8 100644 --- a/ffmpeg/libavformat/rtpenc_h264.c +++ b/ffmpeg/libavformat/rtpenc_h264.c @@ -29,21 +29,6 @@ #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; @@ -88,14 +73,14 @@ void ff_rtp_send_h264(AVFormatContext *s1, const uint8_t *buf1, int size) 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; diff --git a/ffmpeg/libavformat/rtpenc_hevc.c b/ffmpeg/libavformat/rtpenc_hevc.c new file mode 100644 index 0000000..ce661fa --- /dev/null +++ b/ffmpeg/libavformat/rtpenc_hevc.c @@ -0,0 +1,130 @@ +/* + * RTP packetizer for HEVC/H.265 payload format (draft version 6) + * Copyright (c) 2014 Thomas Volkert + * + * 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; + } +} diff --git a/ffmpeg/libavformat/rtpproto.c b/ffmpeg/libavformat/rtpproto.c index a8cbd97..0ea9568 100644 --- a/ffmpeg/libavformat/rtpproto.c +++ b/ffmpeg/libavformat/rtpproto.c @@ -192,6 +192,7 @@ static void build_udp_url(char *buf, int buf_size, 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) { @@ -204,6 +205,8 @@ static void build_udp_url(char *buf, int buf_size, 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); @@ -232,8 +235,10 @@ static void rtp_parse_addr_list(URLContext *h, char *buf, 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); @@ -262,6 +267,7 @@ static void rtp_parse_addr_list(URLContext *h, char *buf, * '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 * @@ -276,7 +282,7 @@ static int rtp_open(URLContext *h, const char *uri, int flags) 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]; @@ -292,6 +298,7 @@ static int rtp_open(URLContext *h, const char *uri, int flags) local_rtcp_port = -1; max_packet_size = -1; connect = 0; + dscp = -1; p = strchr(uri, '?'); if (p) { @@ -319,6 +326,9 @@ static int rtp_open(URLContext *h, const char *uri, int flags) 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); @@ -332,7 +342,7 @@ static int rtp_open(URLContext *h, const char *uri, int flags) 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); @@ -344,7 +354,7 @@ static int rtp_open(URLContext *h, const char *uri, int flags) 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; @@ -353,7 +363,7 @@ static int rtp_open(URLContext *h, const char *uri, int flags) } build_udp_url(buf, sizeof(buf), hostname, rtcp_port, local_rtcp_port, ttl, max_packet_size, - connect, 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; diff --git a/ffmpeg/libavformat/rtsp.c b/ffmpeg/libavformat/rtsp.c index ce4763e..ae62252 100644 --- a/ffmpeg/libavformat/rtsp.c +++ b/ffmpeg/libavformat/rtsp.c @@ -438,7 +438,7 @@ static void sdp_parse_line(AVFormatContext *s, SDPParseState *s1, 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; @@ -687,9 +687,9 @@ void ff_rtsp_undo_setup(AVFormatContext *s, int send_packets) 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; @@ -727,7 +727,7 @@ void ff_rtsp_close_streams(AVFormatContext *s) 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); @@ -751,7 +751,7 @@ int ff_rtsp_open_transport_ctx(AVFormatContext *s, RTSPStream *rtsp_st) 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, @@ -763,7 +763,7 @@ int ff_rtsp_open_transport_ctx(AVFormatContext *s, RTSPStream *rtsp_st) 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); @@ -774,7 +774,7 @@ int ff_rtsp_open_transport_ctx(AVFormatContext *s, RTSPStream *rtsp_st) 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, @@ -1150,6 +1150,8 @@ start: 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'; } @@ -1181,7 +1183,7 @@ start: } 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. */ @@ -1278,7 +1280,7 @@ static int rtsp_send_cmd_with_content_async(AVFormatContext *s, } 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; } @@ -1461,7 +1463,7 @@ int ff_rtsp_make_setup_request(AVFormatContext *s, const char *host, int port, 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); @@ -1476,7 +1478,7 @@ int ff_rtsp_make_setup_request(AVFormatContext *s, const char *host, int port, 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; } @@ -1526,8 +1528,8 @@ int ff_rtsp_make_setup_request(AVFormatContext *s, const char *host, int port, * 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; } @@ -1588,10 +1590,13 @@ void ff_rtsp_close_connections(AVFormatContext *s) 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); @@ -1618,15 +1623,23 @@ int ff_rtsp_connect(AVFormatContext *s) 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; @@ -1646,7 +1659,7 @@ redirect: /* 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) { @@ -1724,12 +1737,14 @@ redirect: 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; @@ -1764,7 +1779,7 @@ redirect: 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; } @@ -1779,10 +1794,12 @@ redirect: 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; @@ -1816,6 +1833,7 @@ redirect: 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); @@ -1840,7 +1858,7 @@ static int udp_read_packet(AVFormatContext *s, RTSPStream **prtsp_st, 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) { @@ -1976,7 +1994,7 @@ int ff_rtsp_fetch_packet(AVFormatContext *s, AVPacket *pkt) 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; @@ -2039,7 +2057,7 @@ redo: 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); @@ -2115,7 +2133,7 @@ redo: 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) { diff --git a/ffmpeg/libavformat/rtsp.h b/ffmpeg/libavformat/rtsp.h index d159793..a9f2f1e 100644 --- a/ffmpeg/libavformat/rtsp.h +++ b/ffmpeg/libavformat/rtsp.h @@ -70,6 +70,7 @@ enum RTSPControlTransport { }; #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 diff --git a/ffmpeg/libavformat/rtspcodes.h b/ffmpeg/libavformat/rtspcodes.h index d4ae0a8..0ae490a 100644 --- a/ffmpeg/libavformat/rtspcodes.h +++ b/ffmpeg/libavformat/rtspcodes.h @@ -25,6 +25,7 @@ #define AVFORMAT_RTSPCODES_H #include "libavutil/common.h" +#include "libavformat/http.h" /** RTSP handling */ enum RTSPStatusCode { @@ -139,4 +140,10 @@ enum RTSPMethod { 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 */ diff --git a/ffmpeg/libavformat/rtspdec.c b/ffmpeg/libavformat/rtspdec.c index b4b4f12..fa7383c 100644 --- a/ffmpeg/libavformat/rtspdec.c +++ b/ffmpeg/libavformat/rtspdec.c @@ -360,10 +360,12 @@ static inline int parse_command_line(AVFormatContext *s, const char *line, 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); @@ -530,7 +532,7 @@ static int rtsp_read_play(AVFormatContext *s) } 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) { @@ -562,7 +564,7 @@ static int rtsp_read_pause(AVFormatContext *s) 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; @@ -589,12 +591,12 @@ int ff_rtsp_setup_input_streams(AVFormatContext *s, RTSPMessageHeader *reply) 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 */ @@ -609,10 +611,12 @@ int ff_rtsp_setup_input_streams(AVFormatContext *s, RTSPMessageHeader *reply) 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; @@ -620,18 +624,23 @@ static int rtsp_listen(AVFormatContext *s) 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, @@ -673,7 +682,11 @@ static int rtsp_listen(AVFormatContext *s) 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; } @@ -704,10 +717,10 @@ static int rtsp_read_header(AVFormatContext *s) 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; } } } @@ -801,7 +814,7 @@ retry: 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; } } @@ -836,7 +849,7 @@ retry: 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) @@ -874,7 +887,7 @@ retry: 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 && @@ -897,6 +910,7 @@ static int rtsp_read_seek(AVFormatContext *s, int stream_index, 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, @@ -906,11 +920,11 @@ static int rtsp_read_seek(AVFormatContext *s, int stream_index, 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; diff --git a/ffmpeg/libavformat/rtspenc.c b/ffmpeg/libavformat/rtspenc.c index 12fb410..e7707bb 100644 --- a/ffmpeg/libavformat/rtspenc.c +++ b/ffmpeg/libavformat/rtspenc.c @@ -84,7 +84,7 @@ int ff_rtsp_setup_output_streams(AVFormatContext *s, const char *addr) 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++) { @@ -116,7 +116,7 @@ static int rtsp_write_record(AVFormatContext *s) "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; } diff --git a/ffmpeg/libavformat/samidec.c b/ffmpeg/libavformat/samidec.c index 4dbf2cf..948e1ed 100644 --- a/ffmpeg/libavformat/samidec.c +++ b/ffmpeg/libavformat/samidec.c @@ -54,7 +54,7 @@ static int sami_read_header(AVFormatContext *s) 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); diff --git a/ffmpeg/libavformat/sapdec.c b/ffmpeg/libavformat/sapdec.c index fe7bd82..2dd8524 100644 --- a/ffmpeg/libavformat/sapdec.c +++ b/ffmpeg/libavformat/sapdec.c @@ -20,6 +20,7 @@ */ #include "avformat.h" +#include "libavutil/avassert.h" #include "libavutil/avstring.h" #include "libavutil/intreadwrite.h" #include "network.h" @@ -158,6 +159,10 @@ static int sap_read_header(AVFormatContext *s) sap->sdp_ctx->max_delay = s->max_delay; sap->sdp_ctx->pb = &sap->sdp_pb; sap->sdp_ctx->interrupt_callback = s->interrupt_callback; + + 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; diff --git a/ffmpeg/libavformat/sbgdec.c b/ffmpeg/libavformat/sbgdec.c index 36cd8a3..32822fb 100644 --- a/ffmpeg/libavformat/sbgdec.c +++ b/ffmpeg/libavformat/sbgdec.c @@ -25,6 +25,7 @@ #include "libavutil/intreadwrite.h" #include "libavutil/log.h" #include "libavutil/opt.h" +#include "libavutil/time_internal.h" #include "avformat.h" #include "internal.h" @@ -905,14 +906,14 @@ static void expand_timestamps(void *log, struct sbg_script *s) } 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", diff --git a/ffmpeg/libavformat/sctp.c b/ffmpeg/libavformat/sctp.c index 35b9ad1..d733895 100644 --- a/ffmpeg/libavformat/sctp.c +++ b/ffmpeg/libavformat/sctp.c @@ -298,7 +298,7 @@ static int sctp_write(URLContext *h, const uint8_t *buf, int size) 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 diff --git a/ffmpeg/libavformat/sdp.c b/ffmpeg/libavformat/sdp.c index bc27eae..5bf9de6 100644 --- a/ffmpeg/libavformat/sdp.c +++ b/ffmpeg/libavformat/sdp.c @@ -29,6 +29,7 @@ #include "avformat.h" #include "internal.h" #include "avc.h" +#include "hevc.h" #include "rtp.h" #if CONFIG_NETWORK #include "network.h" @@ -156,8 +157,9 @@ static char *extradata2psets(AVCodecContext *c) 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) { @@ -166,44 +168,28 @@ static char *extradata2psets(AVCodecContext *c) 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; @@ -219,6 +205,7 @@ static char *extradata2psets(AVCodecContext *c) 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; } @@ -231,13 +218,110 @@ static char *extradata2psets(AVCodecContext *c) 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) @@ -441,6 +525,14 @@ static char *sdp_write_media_attributes(char *buff, int size, 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); @@ -604,8 +696,18 @@ static char *sdp_write_media_attributes(char *buff, int size, AVCodecContext *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... */ diff --git a/ffmpeg/libavformat/segment.c b/ffmpeg/libavformat/segment.c index f35bbef..2cad6e3 100644 --- a/ffmpeg/libavformat/segment.c +++ b/ffmpeg/libavformat/segment.c @@ -39,6 +39,7 @@ #include "libavutil/parseutils.h" #include "libavutil/mathematics.h" #include "libavutil/time.h" +#include "libavutil/time_internal.h" #include "libavutil/timestamp.h" typedef struct SegmentListEntry { @@ -143,6 +144,7 @@ static int segment_mux_init(AVFormatContext *s) 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++) { @@ -162,6 +164,7 @@ static int segment_mux_init(AVFormatContext *s) 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); } @@ -567,6 +570,7 @@ static int seg_write_header(AVFormatContext *s) AVFormatContext *oc = NULL; AVDictionary *options = NULL; int ret; + int i; seg->segment_count = 0; if (!seg->write_header_trailer) @@ -672,6 +676,13 @@ static int seg_write_header(AVFormatContext *s) } 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; @@ -714,11 +725,7 @@ static int seg_write_packet(AVFormatContext *s, AVPacket *pkt) 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) { diff --git a/ffmpeg/libavformat/smoothstreamingenc.c b/ffmpeg/libavformat/smoothstreamingenc.c index d2b7c9e..d6cdf90 100644 --- a/ffmpeg/libavformat/smoothstreamingenc.c +++ b/ffmpeg/libavformat/smoothstreamingenc.c @@ -34,6 +34,7 @@ #include "libavutil/opt.h" #include "libavutil/avstring.h" +#include "libavutil/file.h" #include "libavutil/mathematics.h" #include "libavutil/intreadwrite.h" @@ -282,8 +283,7 @@ static int write_manifest(AVFormatContext *s, int final) avio_printf(out, "\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) @@ -293,8 +293,8 @@ 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; } @@ -343,6 +343,7 @@ static int ism_write_header(AVFormatContext *s) } 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) { @@ -515,7 +516,7 @@ static int ism_flush(AVFormatContext *s, int final) 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; @@ -533,14 +534,17 @@ static int ism_flush(AVFormatContext *s, int final) 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)) { @@ -574,7 +578,7 @@ static int ism_write_packet(AVFormatContext *s, AVPacket *pkt) 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) diff --git a/ffmpeg/libavformat/sol.c b/ffmpeg/libavformat/sol.c index 27d3551..c943453 100644 --- a/ffmpeg/libavformat/sol.c +++ b/ffmpeg/libavformat/sol.c @@ -50,18 +50,15 @@ static int sol_probe(AVProbeData *p) 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; } diff --git a/ffmpeg/libavformat/srtdec.c b/ffmpeg/libavformat/srtdec.c index f5f3933..b35e50f 100644 --- a/ffmpeg/libavformat/srtdec.c +++ b/ffmpeg/libavformat/srtdec.c @@ -31,23 +31,28 @@ typedef struct { 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; } @@ -82,7 +87,7 @@ static int srt_read_header(AVFormatContext *s) 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); diff --git a/ffmpeg/libavformat/srtenc.c b/ffmpeg/libavformat/srtenc.c index b43504b..9bb83d6 100644 --- a/ffmpeg/libavformat/srtenc.c +++ b/ffmpeg/libavformat/srtenc.c @@ -45,8 +45,7 @@ static int srt_write_header(AVFormatContext *avf) 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)); @@ -60,9 +59,8 @@ static int srt_write_header(AVFormatContext *avf) 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; @@ -94,10 +92,9 @@ static int srt_write_packet(AVFormatContext *avf, AVPacket *pkt) 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; } diff --git a/ffmpeg/libavformat/stldec.c b/ffmpeg/libavformat/stldec.c new file mode 100644 index 0000000..b84c7e9 --- /dev/null +++ b/ffmpeg/libavformat/stldec.c @@ -0,0 +1,141 @@ +/* + * 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", +}; diff --git a/ffmpeg/libavformat/subtitles.c b/ffmpeg/libavformat/subtitles.c index 95faca6..67624fc 100644 --- a/ffmpeg/libavformat/subtitles.c +++ b/ffmpeg/libavformat/subtitles.c @@ -24,7 +24,7 @@ #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; @@ -45,13 +45,16 @@ void ff_text_init_avio(FFTextReader *r, AVIOContext *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) diff --git a/ffmpeg/libavformat/subtitles.h b/ffmpeg/libavformat/subtitles.h index 903c24d..eb719ea 100644 --- a/ffmpeg/libavformat/subtitles.h +++ b/ffmpeg/libavformat/subtitles.h @@ -49,14 +49,16 @@ typedef struct { * 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. diff --git a/ffmpeg/libavformat/supdec.c b/ffmpeg/libavformat/supdec.c new file mode 100644 index 0000000..48083b2 --- /dev/null +++ b/ffmpeg/libavformat/supdec.c @@ -0,0 +1,109 @@ +/* + * 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, +}; diff --git a/ffmpeg/libavformat/tcp.c b/ffmpeg/libavformat/tcp.c index 3c3f4f5..0aabc9d 100644 --- a/ffmpeg/libavformat/tcp.c +++ b/ffmpeg/libavformat/tcp.c @@ -22,6 +22,7 @@ #include "libavutil/parseutils.h" #include "libavutil/opt.h" #include "libavutil/time.h" + #include "internal.h" #include "network.h" #include "os_support.h" @@ -43,13 +44,13 @@ typedef struct TCPContext { #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, @@ -228,6 +229,6 @@ URLProtocol ff_tcp_protocol = { .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, }; diff --git a/ffmpeg/libavformat/tiertexseq.c b/ffmpeg/libavformat/tiertexseq.c index 917a331..659ba06 100644 --- a/ffmpeg/libavformat/tiertexseq.c +++ b/ffmpeg/libavformat/tiertexseq.c @@ -301,7 +301,7 @@ static int seq_read_close(AVFormatContext *s) 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; } diff --git a/ffmpeg/libavformat/tls.c b/ffmpeg/libavformat/tls.c index 61fb2bf..d6a6be3 100644 --- a/ffmpeg/libavformat/tls.c +++ b/ffmpeg/libavformat/tls.c @@ -168,22 +168,30 @@ static int tls_open(URLContext *h, const char *uri, int flags) 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)) { diff --git a/ffmpeg/libavformat/udp.c b/ffmpeg/libavformat/udp.c index 376a544..91c7910 100644 --- a/ffmpeg/libavformat/udp.c +++ b/ffmpeg/libavformat/udp.c @@ -40,6 +40,20 @@ #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 #endif @@ -55,11 +69,13 @@ #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; @@ -95,6 +111,7 @@ static const AVOption options[] = { {"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 }, @@ -114,6 +131,13 @@ static const AVClass udp_context_class = { .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]; @@ -335,7 +359,10 @@ static int udp_socket_create(UDPContext *s, struct sockaddr_storage *addr, 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"); } @@ -529,7 +556,7 @@ static int parse_source_list(char *buf, char **sources, int *num_sources, 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; @@ -570,6 +597,9 @@ static int udp_open(URLContext *h, const char *uri, int flags) 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); } @@ -582,6 +612,9 @@ static int udp_open(URLContext *h, const char *uri, int flags) if (av_find_info_tag(buf, sizeof(buf), "connect", p)) { s->is_connected = strtol(buf, NULL, 10); } + if (av_find_info_tag(buf, sizeof(buf), "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) @@ -653,6 +686,24 @@ static int udp_open(URLContext *h, const char *uri, int flags) 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 @@ -780,6 +831,16 @@ static int udp_open(URLContext *h, const char *uri, int flags) 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; @@ -893,3 +954,15 @@ URLProtocol ff_udp_protocol = { .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, +}; diff --git a/ffmpeg/libavformat/url.h b/ffmpeg/libavformat/url.h index c4d1642..d0035f3 100644 --- a/ffmpeg/libavformat/url.h +++ b/ffmpeg/libavformat/url.h @@ -34,8 +34,6 @@ #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 { diff --git a/ffmpeg/libavformat/utils.c b/ffmpeg/libavformat/utils.c index e899e4d..798c612 100644 --- a/ffmpeg/libavformat/utils.c +++ b/ffmpeg/libavformat/utils.c @@ -103,6 +103,7 @@ static int64_t wrap_timestamp(AVStream *st, int64_t timestamp) } 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) @@ -130,6 +131,19 @@ void av_format_inject_global_side_data(AVFormatContext *s) } } +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) @@ -291,6 +305,11 @@ static int set_codec_from_probe_data(AVFormatContext *s, AVStream *st, 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) @@ -402,6 +421,13 @@ int avformat_open_input(AVFormatContext **ps, const char *filename, 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. */ @@ -691,13 +717,6 @@ int ff_read_packet(AVFormatContext *s, AVPacket *pkt) } } -#if FF_API_READ_PACKET -int av_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - return ff_read_packet(s, pkt); -} -#endif - /**********************************************************/ @@ -715,9 +734,11 @@ static int determinable_frame_size(AVCodecContext *avctx) /** * 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; @@ -730,14 +751,19 @@ void ff_compute_frame_duration(int *pnum, int *pden, AVStream *st, } 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 @@ -1022,7 +1048,7 @@ static void compute_pkt_fields(AVFormatContext *s, AVStream *st, 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, @@ -1053,9 +1079,9 @@ static void compute_pkt_fields(AVFormatContext *s, AVStream *st, 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)) && @@ -1255,6 +1281,11 @@ static int read_from_packet_buffer(AVPacketList **pkt_buffer, 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; @@ -1352,10 +1383,21 @@ static int read_frame_internal(AVFormatContext *s, AVPacket *pkt) 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; @@ -2365,7 +2407,7 @@ static void estimate_timings_from_pts(AVFormatContext *ic, int64_t old_offset) (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, @@ -2560,6 +2602,8 @@ static int try_decode_frame(AVFormatContext *s, AVStream *st, AVPacket *avpkt, /* 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); @@ -2743,10 +2787,16 @@ static void compute_chapters_end(AVFormatContext *s) 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? @@ -2769,13 +2819,6 @@ static int tb_unreliable(AVCodecContext *c) 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; @@ -2946,6 +2989,7 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options) 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) @@ -2956,11 +3000,12 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options) 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) @@ -3000,6 +3045,9 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options) * 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) { @@ -3030,6 +3078,7 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options) 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"); @@ -3069,7 +3118,9 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options) 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)) { @@ -3177,10 +3228,12 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options) && 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) { @@ -3214,6 +3267,9 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options) 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++; } @@ -3242,7 +3298,6 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options) } } } - 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++) { @@ -3303,6 +3358,11 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options) 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 = @@ -3331,6 +3391,8 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options) 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; @@ -3492,6 +3554,7 @@ void ff_free_stream(AVFormatContext *s, AVStream *st) { 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 ]); } @@ -3530,13 +3593,6 @@ void avformat_free_context(AVFormatContext *s) av_free(s); } -#if FF_API_CLOSE_INPUT_FILE -void av_close_input_file(AVFormatContext *s) -{ - avformat_close_input(&s); -} -#endif - void avformat_close_input(AVFormatContext **ps) { AVFormatContext *s; @@ -3565,16 +3621,6 @@ void avformat_close_input(AVFormatContext **ps) 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; @@ -3902,14 +3948,6 @@ int ff_hex_to_data(uint8_t *data, const char *p) return len; } -#if FF_API_SET_PTS_INFO -void av_set_pts_info(AVStream *s, int pts_wrap_bits, - unsigned int pts_num, unsigned int pts_den) -{ - avpriv_set_pts_info(s, pts_wrap_bits, pts_num, pts_den); -} -#endif - void avpriv_set_pts_info(AVStream *s, int pts_wrap_bits, unsigned int pts_num, unsigned int pts_den) { @@ -4115,7 +4153,7 @@ AVRational av_guess_sample_aspect_ratio(AVFormatContext *format, AVStream *strea 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 && @@ -4125,7 +4163,6 @@ AVRational av_guess_frame_rate(AVFormatContext *format, AVStream *st, AVFrame *f 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; @@ -4254,6 +4291,21 @@ int ff_generate_avci_extradata(AVStream *st) 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, @@ -4287,6 +4339,21 @@ int ff_generate_avci_extradata(AVStream *st) 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; @@ -4300,11 +4367,19 @@ int ff_generate_avci_extradata(AVStream *st) 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) diff --git a/ffmpeg/libavformat/version.h b/ffmpeg/libavformat/version.h index f5808eb..7288414 100644 --- a/ffmpeg/libavformat/version.h +++ b/ffmpeg/libavformat/version.h @@ -30,8 +30,8 @@ #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, \ @@ -61,24 +61,6 @@ #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 diff --git a/ffmpeg/libavformat/wavenc.c b/ffmpeg/libavformat/wavenc.c index c73c900..bce4876 100644 --- a/ffmpeg/libavformat/wavenc.c +++ b/ffmpeg/libavformat/wavenc.c @@ -38,6 +38,7 @@ #include "libavutil/mathematics.h" #include "libavutil/opt.h" #include "libavutil/time.h" +#include "libavutil/time_internal.h" #include "avformat.h" #include "avio.h" @@ -267,10 +268,11 @@ static void peak_write_chunk(AVFormatContext *s) 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)); } diff --git a/ffmpeg/libavformat/webmdashenc.c b/ffmpeg/libavformat/webmdashenc.c index 77f6170..4536b7d 100644 --- a/ffmpeg/libavformat/webmdashenc.c +++ b/ffmpeg/libavformat/webmdashenc.c @@ -46,6 +46,7 @@ typedef struct WebMDashMuxContext { char *adaptation_sets; AdaptationSet *as; int nb_as; + int representation_id; } WebMDashMuxContext; static const char *get_codec_name(int codec_id) @@ -95,7 +96,7 @@ static void write_header(AVFormatContext *s) static void write_footer(AVFormatContext *s) { - avio_printf(s->pb, ""); + avio_printf(s->pb, "\n"); } static int subsegment_alignment(AVFormatContext *s, AdaptationSet *as) { @@ -132,6 +133,80 @@ static int bitstream_switching(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, "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, "%s\n", filename->value); + avio_printf(s->pb, "pb, " indexRange=\"%s-%s\">\n", cues_start->value, cues_end->value); + avio_printf(s->pb, "pb, " range=\"0-%s\" />\n", irange->value); + avio_printf(s->pb, "\n"); + avio_printf(s->pb, "\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. */ @@ -140,10 +215,22 @@ static int write_adaptation_set(AVFormatContext *s, int as_index) 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, "id); avio_printf(s->pb, " mimeType=\"%s/webm\"", codec->codec_type == AVMEDIA_TYPE_VIDEO ? "video" : "audio"); @@ -152,12 +239,12 @@ static int write_adaptation_set(AVFormatContext *s, int as_index) 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)]); @@ -173,26 +260,8 @@ static int write_adaptation_set(AVFormatContext *s, int as_index) 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, "pb, " bandwidth=\"%s\"", bandwidth->value); - avio_printf(s->pb, ">\n"); - avio_printf(s->pb, "%s\n", filename->value); - avio_printf(s->pb, "pb, " indexRange=\"%s-%s\">\n", cues_start->value, cues_end->value); - avio_printf(s->pb, "pb, " range=\"0-%s\" />\n", irange->value); - avio_printf(s->pb, "\n"); - avio_printf(s->pb, "\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, "\n"); return 0; diff --git a/ffmpeg/libavformat/webpenc.c b/ffmpeg/libavformat/webpenc.c new file mode 100644 index 0000000..ee110de --- /dev/null +++ b/ffmpeg/libavformat/webpenc.c @@ -0,0 +1,169 @@ +/* + * 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, +}; diff --git a/ffmpeg/libavformat/wtvdec.c b/ffmpeg/libavformat/wtvdec.c index 9cedae1..4009964 100644 --- a/ffmpeg/libavformat/wtvdec.c +++ b/ffmpeg/libavformat/wtvdec.c @@ -30,6 +30,7 @@ #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" @@ -386,10 +387,12 @@ static int read_probe(AVProbeData *p) 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; } @@ -400,10 +403,12 @@ static int filetime_to_iso8601(char *buf, int buf_size, int64_t value) 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; } @@ -414,10 +419,12 @@ static int crazytime_to_iso8601(char *buf, int buf_size, int64_t value) 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; } @@ -974,7 +981,9 @@ static int read_header(AVFormatContext *s) 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; diff --git a/ffmpeg/libavformat/xwma.c b/ffmpeg/libavformat/xwma.c index 127c097..5d29d0b 100644 --- a/ffmpeg/libavformat/xwma.c +++ b/ffmpeg/libavformat/xwma.c @@ -44,7 +44,7 @@ static int xwma_probe(AVProbeData *p) 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; @@ -132,7 +132,7 @@ static int xwma_read_header(AVFormatContext *s) for (;;) { if (pb->eof_reached) { ret = AVERROR_EOF; - goto end; + goto fail; } /* read next chunk tag */ tag = avio_rl32(pb); @@ -155,7 +155,7 @@ static int xwma_read_header(AVFormatContext *s) 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. */ @@ -189,7 +189,7 @@ static int xwma_read_header(AVFormatContext *s) /* Determine overall data length */ if (size < 0) { ret = AVERROR_INVALIDDATA; - goto end; + goto fail; } if (!size) { xwma->data_end = INT64_MAX; @@ -210,7 +210,7 @@ static int xwma_read_header(AVFormatContext *s) "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; @@ -245,7 +245,7 @@ static int xwma_read_header(AVFormatContext *s) st->duration = (size<<3) * st->codec->sample_rate / st->codec->bit_rate; } -end: +fail: av_free(dpds_table); return ret; diff --git a/ffmpeg/libavformat/yuv4mpegenc.c b/ffmpeg/libavformat/yuv4mpegenc.c index a7f2d8a..cc954fc 100644 --- a/ffmpeg/libavformat/yuv4mpegenc.c +++ b/ffmpeg/libavformat/yuv4mpegenc.c @@ -268,7 +268,7 @@ static int yuv4_write_header(AVFormatContext *s) 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)); diff --git a/ffmpeg/libavresample/audio_mix_matrix.c b/ffmpeg/libavresample/audio_mix_matrix.c index bcbe181..5d92351 100644 --- a/ffmpeg/libavresample/audio_mix_matrix.c +++ b/ffmpeg/libavresample/audio_mix_matrix.c @@ -60,7 +60,7 @@ 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) diff --git a/ffmpeg/libavresample/utils.c b/ffmpeg/libavresample/utils.c index 69c255b..e285445 100644 --- a/ffmpeg/libavresample/utils.c +++ b/ffmpeg/libavresample/utils.c @@ -585,9 +585,12 @@ static inline int convert_frame(AVAudioResampleContext *avr, 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 { diff --git a/ffmpeg/libavutil/Makefile b/ffmpeg/libavutil/Makefile index 48ae0ef..c1aa8aa 100644 --- a/ffmpeg/libavutil/Makefile +++ b/ffmpeg/libavutil/Makefile @@ -15,6 +15,7 @@ HEADERS = adler32.h \ bprint.h \ bswap.h \ buffer.h \ + cast5.h \ channel_layout.h \ common.h \ cpu.h \ @@ -30,7 +31,6 @@ HEADERS = adler32.h \ hmac.h \ imgutils.h \ intfloat.h \ - intfloat_readwrite.h \ intreadwrite.h \ lfg.h \ log.h \ @@ -83,6 +83,7 @@ OBJS = adler32.o \ blowfish.o \ bprint.o \ buffer.o \ + cast5.o \ channel_layout.o \ cpu.o \ crc.o \ @@ -100,7 +101,6 @@ OBJS = adler32.o \ hash.o \ hmac.o \ imgutils.o \ - intfloat_readwrite.o \ intmath.o \ lfg.o \ lls.o \ @@ -153,9 +153,11 @@ TESTPROGS = adler32 \ base64 \ blowfish \ bprint \ + cast5 \ cpu \ crc \ des \ + dict \ error \ eval \ file \ @@ -177,6 +179,7 @@ TESTPROGS = adler32 \ ripemd \ sha \ sha512 \ + softfloat \ tree \ utf8 \ xtea \ diff --git a/ffmpeg/libavutil/arm/float_dsp_init_vfp.c b/ffmpeg/libavutil/arm/float_dsp_init_vfp.c index 45508b8..e15abf3 100644 --- a/ffmpeg/libavutil/arm/float_dsp_init_vfp.c +++ b/ffmpeg/libavutil/arm/float_dsp_init_vfp.c @@ -32,7 +32,7 @@ void ff_vector_fmul_window_vfp(float *dst, const float *src0, 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) { diff --git a/ffmpeg/libavutil/atomic_gcc.h b/ffmpeg/libavutil/atomic_gcc.h index 2bb43c3..5f9fc49 100644 --- a/ffmpeg/libavutil/atomic_gcc.h +++ b/ffmpeg/libavutil/atomic_gcc.h @@ -28,27 +28,40 @@ #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; @@ -56,6 +69,10 @@ static inline void *atomic_ptr_cas_gcc(void * volatile *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 */ diff --git a/ffmpeg/libavutil/atomic_win32.h b/ffmpeg/libavutil/atomic_win32.h index 20b99df..f729933 100644 --- a/ffmpeg/libavutil/atomic_win32.h +++ b/ffmpeg/libavutil/atomic_win32.h @@ -21,6 +21,7 @@ #ifndef AVUTIL_ATOMIC_WIN32_H #define AVUTIL_ATOMIC_WIN32_H +#define WIN32_LEAN_AND_MEAN #include #define avpriv_atomic_int_get atomic_int_get_win32 diff --git a/ffmpeg/libavutil/avstring.c b/ffmpeg/libavutil/avstring.c index fd010e4..25c65b4 100644 --- a/ffmpeg/libavutil/avstring.c +++ b/ffmpeg/libavutil/avstring.c @@ -402,6 +402,26 @@ end: 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) diff --git a/ffmpeg/libavutil/avstring.h b/ffmpeg/libavutil/avstring.h index 616c066..ffb7aa6 100644 --- a/ffmpeg/libavutil/avstring.h +++ b/ffmpeg/libavutil/avstring.h @@ -203,22 +203,22 @@ char *av_strtok(char *s, const char *delim, char **saveptr); /** * 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; @@ -228,7 +228,7 @@ static inline int av_toupper(int c) /** * 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; @@ -238,7 +238,7 @@ static inline int av_tolower(int c) /** * Locale-independent conversion of ASCII isxdigit. */ -int av_isxdigit(int c); +av_const int av_isxdigit(int c); /** * Locale-independent case-insensitive compare. @@ -357,6 +357,13 @@ int av_escape(char **dst, const char *src, const char *special_chars, 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); + /** * @} */ diff --git a/ffmpeg/libavutil/bprint.h b/ffmpeg/libavutil/bprint.h index 839ec1e..c09b1ac 100644 --- a/ffmpeg/libavutil/bprint.h +++ b/ffmpeg/libavutil/bprint.h @@ -30,9 +30,13 @@ * 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 @@ -74,15 +78,14 @@ * 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 @@ -179,7 +182,7 @@ void av_bprint_clear(AVBPrint *buf); * 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; } diff --git a/ffmpeg/libavutil/buffer.c b/ffmpeg/libavutil/buffer.c index e9bf54b..b114afc 100644 --- a/ffmpeg/libavutil/buffer.c +++ b/ffmpeg/libavutil/buffer.c @@ -23,6 +23,7 @@ #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), @@ -209,6 +210,8 @@ AVBufferPool *av_buffer_pool_init(int size, AVBufferRef* (*alloc)(int size)) if (!pool) return NULL; + ff_mutex_init(&pool->mutex, NULL); + pool->size = size; pool->alloc = alloc ? alloc : av_buffer_alloc; @@ -230,6 +233,7 @@ static void buffer_pool_free(AVBufferPool *pool) buf->free(buf->opaque, buf->data); av_freep(&buf); } + ff_mutex_destroy(&pool->mutex); av_freep(&pool); } @@ -290,7 +294,15 @@ static void pool_release_buffer(void *opaque, uint8_t *data) 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); } @@ -320,8 +332,10 @@ static AVBufferRef *pool_alloc_buffer(AVBufferPool *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; } @@ -331,6 +345,7 @@ AVBufferRef *av_buffer_pool_get(AVBufferPool *pool) AVBufferRef *ret; BufferPoolEntry *buf; +#if USE_ATOMICS /* check whether the pool is empty */ buf = get_pool(pool); if (!buf && pool->refcount <= pool->nb_allocated) { @@ -352,7 +367,24 @@ AVBufferRef *av_buffer_pool_get(AVBufferPool *pool) 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; } diff --git a/ffmpeg/libavutil/buffer_internal.h b/ffmpeg/libavutil/buffer_internal.h index c291908..e653048 100644 --- a/ffmpeg/libavutil/buffer_internal.h +++ b/ffmpeg/libavutil/buffer_internal.h @@ -22,6 +22,7 @@ #include #include "buffer.h" +#include "thread.h" /** * The buffer is always treated as read-only. @@ -68,11 +69,12 @@ typedef struct BufferPoolEntry { 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. diff --git a/ffmpeg/libavutil/cast5.c b/ffmpeg/libavutil/cast5.c new file mode 100644 index 0000000..c0d6d1e --- /dev/null +++ b/ffmpeg/libavutil/cast5.c @@ -0,0 +1,541 @@ +/* + * 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 +#include +#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 diff --git a/ffmpeg/libavutil/cast5.h b/ffmpeg/libavutil/cast5.h new file mode 100644 index 0000000..a4df6d8 --- /dev/null +++ b/ffmpeg/libavutil/cast5.h @@ -0,0 +1,67 @@ +/* + * 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 + + +/** + * @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 */ diff --git a/ffmpeg/libavutil/dict.c b/ffmpeg/libavutil/dict.c index 475e906..2983ea5 100644 --- a/ffmpeg/libavutil/dict.c +++ b/ffmpeg/libavutil/dict.c @@ -24,6 +24,7 @@ #include "dict.h" #include "internal.h" #include "mem.h" +#include "bprint.h" struct AVDictionary { int count; @@ -35,7 +36,7 @@ int av_dict_count(const AVDictionary *m) 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; @@ -200,10 +201,99 @@ void av_dict_free(AVDictionary **pm) 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 diff --git a/ffmpeg/libavutil/dict.h b/ffmpeg/libavutil/dict.h index 9b3381b..f2df687 100644 --- a/ffmpeg/libavutil/dict.h +++ b/ffmpeg/libavutil/dict.h @@ -101,7 +101,7 @@ typedef struct AVDictionary AVDictionary; * @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); /** @@ -163,7 +163,7 @@ int av_dict_parse_string(AVDictionary **pm, const char *str, * @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 @@ -171,6 +171,24 @@ void av_dict_copy(AVDictionary **dst, FF_CONST_AVUTIL53 AVDictionary *src, int f */ 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); + /** * @} */ diff --git a/ffmpeg/libavutil/error.c b/ffmpeg/libavutil/error.c index dd1fb30..d2868ac 100644 --- a/ffmpeg/libavutil/error.c +++ b/ffmpeg/libavutil/error.c @@ -29,6 +29,7 @@ struct error_entry { }; #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" }, @@ -41,14 +42,23 @@ static const struct error_entry error_entries[] = { { 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) diff --git a/ffmpeg/libavutil/error.h b/ffmpeg/libavutil/error.h index 621279a..71df4da 100644 --- a/ffmpeg/libavutil/error.h +++ b/ffmpeg/libavutil/error.h @@ -72,6 +72,13 @@ #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 diff --git a/ffmpeg/libavutil/fifo.c b/ffmpeg/libavutil/fifo.c index 77391ee..4ff3194 100644 --- a/ffmpeg/libavutil/fifo.c +++ b/ffmpeg/libavutil/fifo.c @@ -74,12 +74,12 @@ void av_fifo_reset(AVFifoBuffer *f) 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); } diff --git a/ffmpeg/libavutil/fifo.h b/ffmpeg/libavutil/fifo.h index dda7dd2..f3bdcbc 100644 --- a/ffmpeg/libavutil/fifo.h +++ b/ffmpeg/libavutil/fifo.h @@ -73,7 +73,7 @@ void av_fifo_reset(AVFifoBuffer *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 @@ -81,7 +81,7 @@ int av_fifo_size(FF_CONST_AVUTIL53 AVFifoBuffer *f); * @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. diff --git a/ffmpeg/libavutil/file.h b/ffmpeg/libavutil/file.h index a7364fe..1cae295 100644 --- a/ffmpeg/libavutil/file.h +++ b/ffmpeg/libavutil/file.h @@ -55,7 +55,8 @@ void av_file_unmap(uint8_t *bufptr, size_t size); * 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 diff --git a/ffmpeg/libavutil/file_open.c b/ffmpeg/libavutil/file_open.c index f3164eb..3f9a67c 100644 --- a/ffmpeg/libavutil/file_open.c +++ b/ffmpeg/libavutil/file_open.c @@ -37,23 +37,18 @@ #include #include #include +#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); diff --git a/ffmpeg/libavutil/float_dsp.c b/ffmpeg/libavutil/float_dsp.c index 8ac7480..467d7a7 100644 --- a/ffmpeg/libavutil/float_dsp.c +++ b/ffmpeg/libavutil/float_dsp.c @@ -22,6 +22,7 @@ #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) @@ -139,6 +140,15 @@ av_cold void avpriv_float_dsp_init(AVFloatDSPContext *fdsp, int bit_exact) 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 @@ -146,13 +156,18 @@ av_cold void avpriv_float_dsp_init(AVFloatDSPContext *fdsp, int bit_exact) #include #include #include +#if HAVE_UNISTD_H +#include /* 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 @@ -369,7 +384,7 @@ static int test_scalarproduct_float(AVFloatDSPContext *fdsp, AVFloatDSPContext * int main(int argc, char **argv) { - int ret = 0; + int ret = 0, seeded = 0; uint32_t seed; AVFloatDSPContext fdsp, cdsp; AVLFG lfg; @@ -380,12 +395,31 @@ int main(int argc, char **argv) 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); diff --git a/ffmpeg/libavutil/float_dsp.h b/ffmpeg/libavutil/float_dsp.h index 7fc851b..543f701 100644 --- a/ffmpeg/libavutil/float_dsp.h +++ b/ffmpeg/libavutil/float_dsp.h @@ -185,4 +185,11 @@ void ff_float_dsp_init_ppc(AVFloatDSPContext *fdsp, int strict); 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 */ diff --git a/ffmpeg/libavutil/frame.h b/ffmpeg/libavutil/frame.h index ee24628..d335bee 100644 --- a/ffmpeg/libavutil/frame.h +++ b/ffmpeg/libavutil/frame.h @@ -94,6 +94,18 @@ enum AVFrameSideDataType { * 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 { diff --git a/ffmpeg/libavutil/imgutils.c b/ffmpeg/libavutil/imgutils.c index 00b2031..7f3032b 100644 --- a/ffmpeg/libavutil/imgutils.c +++ b/ffmpeg/libavutil/imgutils.c @@ -331,9 +331,6 @@ int av_image_fill_arrays(uint8_t *dst_data[4], int dst_linesize[4], 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); } diff --git a/ffmpeg/libavutil/internal.h b/ffmpeg/libavutil/internal.h index 612b5f2..77af6f9 100644 --- a/ffmpeg/libavutil/internal.h +++ b/ffmpeg/libavutil/internal.h @@ -80,9 +80,6 @@ # define FF_ENABLE_DEPRECATION_WARNINGS #endif -#ifndef INT_BIT -# define INT_BIT (CHAR_BIT * sizeof(int)) -#endif #define FF_MEMORY_POISON 0x2a diff --git a/ffmpeg/libavutil/intfloat_readwrite.c b/ffmpeg/libavutil/intfloat_readwrite.c deleted file mode 100644 index af5da62..0000000 --- a/ffmpeg/libavutil/intfloat_readwrite.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - * portable IEEE float/double read/write functions - * - * Copyright (c) 2005 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 - * portable IEEE float/double read/write functions - */ - -#include -#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 */ diff --git a/ffmpeg/libavutil/intmath.h b/ffmpeg/libavutil/intmath.h index 8f7a69e..308c776 100644 --- a/ffmpeg/libavutil/intmath.h +++ b/ffmpeg/libavutil/intmath.h @@ -35,21 +35,29 @@ * @{ */ -#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; @@ -65,6 +73,15 @@ static av_always_inline av_const int ff_log2_c(unsigned int v) 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 @@ -94,14 +111,21 @@ static av_always_inline av_const int ff_log2_16bit_c(unsigned int v) * @{ */ -#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; @@ -130,6 +154,14 @@ static av_always_inline av_const int ff_ctz_c(int v) 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 /** diff --git a/ffmpeg/libavutil/libm.h b/ffmpeg/libavutil/libm.h index 28d5df8..6c17b28 100644 --- a/ffmpeg/libavutil/libm.h +++ b/ffmpeg/libavutil/libm.h @@ -82,16 +82,6 @@ static av_always_inline float cbrtf(float x) #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) { diff --git a/ffmpeg/libavutil/lls.c b/ffmpeg/libavutil/lls.c index 06fe423..f77043b 100644 --- a/ffmpeg/libavutil/lls.c +++ b/ffmpeg/libavutil/lls.c @@ -32,7 +32,7 @@ #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; @@ -100,7 +100,7 @@ void avpriv_solve_lls(LLSModel *m, double threshold, unsigned short min_order) } } -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; diff --git a/ffmpeg/libavutil/lls.h b/ffmpeg/libavutil/lls.h index 46f9606..5635b5b 100644 --- a/ffmpeg/libavutil/lls.h +++ b/ffmpeg/libavutil/lls.h @@ -47,14 +47,14 @@ typedef struct LLSModel { * 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); diff --git a/ffmpeg/libavutil/lzo.c b/ffmpeg/libavutil/lzo.c index 7b027ee..bca10ec 100644 --- a/ffmpeg/libavutil/lzo.c +++ b/ffmpeg/libavutil/lzo.c @@ -254,6 +254,7 @@ STOP_TIMER("lzod") av_log(NULL, AV_LOG_ERROR, "decompression incorrect\n"); else av_log(NULL, AV_LOG_ERROR, "decompression OK\n"); + fclose(in); return 0; } #endif diff --git a/ffmpeg/libavutil/opencl.c b/ffmpeg/libavutil/opencl.c index 0b4f83b..36cb6fe 100644 --- a/ffmpeg/libavutil/opencl.c +++ b/ffmpeg/libavutil/opencl.c @@ -70,12 +70,6 @@ typedef struct { 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; @@ -86,9 +80,6 @@ typedef struct { 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 } }; @@ -475,19 +466,6 @@ cl_command_queue av_opencl_get_command_queue(void) return opencl_ctx.command_queue; } -#if FF_API_OLD_OPENCL -int av_opencl_create_kernel(AVOpenCLKernelEnv *env, const char *kernel_name) -{ - av_log(&opencl_ctx, AV_LOG_ERROR, "Could not create OpenCL kernel %s, please update libavfilter.\n", kernel_name); - return AVERROR(EINVAL); -} - -void av_opencl_release_kernel(AVOpenCLKernelEnv *env) -{ - 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; diff --git a/ffmpeg/libavutil/opencl.h b/ffmpeg/libavutil/opencl.h index 9e6dc55..4655cba 100644 --- a/ffmpeg/libavutil/opencl.h +++ b/ffmpeg/libavutil/opencl.h @@ -69,14 +69,6 @@ typedef struct { 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; @@ -187,19 +179,6 @@ int av_opencl_register_kernel_code(const char *kernel_code); */ 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 * @@ -292,17 +271,6 @@ int av_opencl_buffer_read_image(uint8_t **dst_data, int *plane_size, int plane_n */ 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. * diff --git a/ffmpeg/libavutil/opt.c b/ffmpeg/libavutil/opt.c index ee72a96..d873bd2 100644 --- a/ffmpeg/libavutil/opt.c +++ b/ffmpeg/libavutil/opt.c @@ -37,33 +37,23 @@ #include "pixdesc.h" #include "mathematics.h" #include "samplefmt.h" +#include "bprint.h" #include -#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) @@ -71,7 +61,7 @@ const AVOption *av_opt_next(void *obj, const AVOption *last) 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; @@ -140,11 +130,14 @@ static int set_string_binary(void *obj, const AVOption *o, const char *val, uint { 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; @@ -725,6 +718,10 @@ int av_opt_get(void *obj, const char *name, int search_flags, uint8_t **out_val) 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]); @@ -740,12 +737,14 @@ int av_opt_get(void *obj, const char *name, int search_flags, uint8_t **out_val) 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; @@ -1236,6 +1235,8 @@ void av_opt_set_defaults2(void *s, int mask, int flags) 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; @@ -1572,7 +1573,7 @@ static int opt_size(enum AVOptionType type) 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; @@ -1609,6 +1610,15 @@ int av_opt_copy(void *dst, void *src) *(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)); } @@ -1726,6 +1736,156 @@ void av_opt_freep_ranges(AVOptionRanges **rangesp) 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 @@ -1743,6 +1903,16 @@ 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) @@ -1753,20 +1923,27 @@ typedef struct TestContext 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}, }; @@ -1785,6 +1962,79 @@ int main(void) { 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 }; @@ -1830,18 +2080,37 @@ int main(void) "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); } @@ -1865,13 +2134,14 @@ int main(void) 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); } diff --git a/ffmpeg/libavutil/opt.h b/ffmpeg/libavutil/opt.h index 4905ee3..5fc8a9b 100644 --- a/ffmpeg/libavutil/opt.h +++ b/ffmpeg/libavutil/opt.h @@ -33,6 +33,7 @@ #include "log.h" #include "pixfmt.h" #include "samplefmt.h" +#include "version.h" /** * @defgroup avoptions AVOptions @@ -378,25 +379,6 @@ typedef struct AVOptionRanges { } 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. @@ -435,7 +417,7 @@ double av_get_double(void *obj, const char *name, const AVOption **o_out); AVRational av_get_q(void *obj, const char *name, const AVOption **o_out); int64_t av_get_int(void *obj, const char *name, const AVOption **o_out); 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 /** @@ -475,7 +457,7 @@ void av_opt_set_defaults2(void *s, int mask, int flags); * @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, @@ -652,7 +634,7 @@ int av_opt_eval_q (void *obj, const AVOption *o, const char *val, AVRational * 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. */ @@ -692,7 +674,7 @@ const AVOption *av_opt_find2(void *obj, const char *name, const char *unit, * 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. @@ -834,7 +816,17 @@ void av_opt_freep_ranges(AVOptionRanges **ranges); */ 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. @@ -852,6 +844,56 @@ int av_opt_copy(void *dest, void *src); */ 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); /** * @} */ diff --git a/ffmpeg/libavutil/parseutils.c b/ffmpeg/libavutil/parseutils.c index ba4b4e1..4708699 100644 --- a/ffmpeg/libavutil/parseutils.c +++ b/ffmpeg/libavutil/parseutils.c @@ -29,6 +29,7 @@ #include "eval.h" #include "log.h" #include "random_seed.h" +#include "time_internal.h" #include "parseutils.h" #ifdef TEST @@ -552,7 +553,7 @@ int av_parse_time(int64_t *timeval, const char *timestr, int duration) 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[] = { @@ -647,7 +648,7 @@ int av_parse_time(int64_t *timeval, const char *timestr, int duration) 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; diff --git a/ffmpeg/libavutil/pca.c b/ffmpeg/libavutil/pca.c index 26d5bbb..f7ae350 100644 --- a/ffmpeg/libavutil/pca.c +++ b/ffmpeg/libavutil/pca.c @@ -57,7 +57,7 @@ void ff_pca_free(PCA *pca){ 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; diff --git a/ffmpeg/libavutil/pca.h b/ffmpeg/libavutil/pca.h index 00ddd60..992bb2e 100644 --- a/ffmpeg/libavutil/pca.h +++ b/ffmpeg/libavutil/pca.h @@ -29,7 +29,7 @@ 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 */ diff --git a/ffmpeg/libavutil/pixdesc.c b/ffmpeg/libavutil/pixdesc.c index 154392a..648d014 100644 --- a/ffmpeg/libavutil/pixdesc.c +++ b/ffmpeg/libavutil/pixdesc.c @@ -1902,6 +1902,33 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = { }, }; +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) { @@ -2305,6 +2332,36 @@ enum AVPixelFormat av_find_best_pix_fmt_of_2(enum AVPixelFormat dst_pix_fmt1, en 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){ @@ -2332,3 +2389,4 @@ int main(void){ } #endif + diff --git a/ffmpeg/libavutil/pixdesc.h b/ffmpeg/libavutil/pixdesc.h index 41e81db..a4376b2 100644 --- a/ffmpeg/libavutil/pixdesc.h +++ b/ffmpeg/libavutil/pixdesc.h @@ -356,4 +356,30 @@ int av_get_pix_fmt_loss(enum AVPixelFormat dst_pix_fmt, */ 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 */ diff --git a/ffmpeg/libavutil/pixfmt.h b/ffmpeg/libavutil/pixfmt.h index a76a852..756a1a7 100644 --- a/ffmpeg/libavutil/pixfmt.h +++ b/ffmpeg/libavutil/pixfmt.h @@ -433,14 +433,16 @@ enum AVPixelFormat { * 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 }; @@ -449,6 +451,7 @@ enum AVColorPrimaries { * 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, @@ -471,11 +474,11 @@ enum AVColorTransferCharacteristic { * 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, diff --git a/ffmpeg/libavutil/ppc/util_altivec.h b/ffmpeg/libavutil/ppc/util_altivec.h index 2c0ad5f..51a4e8c 100644 --- a/ffmpeg/libavutil/ppc/util_altivec.h +++ b/ffmpeg/libavutil/ppc/util_altivec.h @@ -46,9 +46,21 @@ #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) \ @@ -85,29 +97,68 @@ do { \ } 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 */ diff --git a/ffmpeg/libavutil/samplefmt.c b/ffmpeg/libavutil/samplefmt.c index a198698..c605b5e 100644 --- a/ffmpeg/libavutil/samplefmt.c +++ b/ffmpeg/libavutil/samplefmt.c @@ -107,14 +107,6 @@ int av_get_bytes_per_sample(enum AVSampleFormat sample_fmt) 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) @@ -173,11 +165,7 @@ int av_samples_fill_arrays(uint8_t **audio_data, int *linesize, 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, @@ -202,11 +190,7 @@ 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, diff --git a/ffmpeg/libavutil/samplefmt.h b/ffmpeg/libavutil/samplefmt.h index 2c346a3..6a8a031 100644 --- a/ffmpeg/libavutil/samplefmt.h +++ b/ffmpeg/libavutil/samplefmt.h @@ -129,14 +129,6 @@ enum AVSampleFormat av_get_planar_sample_fmt(enum AVSampleFormat sample_fmt); */ 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. * diff --git a/ffmpeg/libavutil/softfloat.h b/ffmpeg/libavutil/softfloat.h index 97e09ea..8647e6a 100644 --- a/ffmpeg/libavutil/softfloat.h +++ b/ffmpeg/libavutil/softfloat.h @@ -24,6 +24,8 @@ #include #include "common.h" +#include "avassert.h" + #define MIN_EXP -126 #define MAX_EXP 126 #define ONE_BITS 29 @@ -57,10 +59,11 @@ static av_const SoftFloat av_normalize_sf(SoftFloat a){ 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; @@ -78,6 +81,7 @@ static inline av_const SoftFloat av_normalize1_sf(SoftFloat a){ */ 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); } @@ -100,8 +104,10 @@ static inline av_const int av_cmp_sf(SoftFloat a, SoftFloat b){ 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){ diff --git a/ffmpeg/libavutil/thread.h b/ffmpeg/libavutil/thread.h new file mode 100644 index 0000000..297b5b9 --- /dev/null +++ b/ffmpeg/libavutil/thread.h @@ -0,0 +1,59 @@ +/* + * 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 +#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 */ diff --git a/ffmpeg/libavutil/time.c b/ffmpeg/libavutil/time.c index ce4552e..dbaee02 100644 --- a/ffmpeg/libavutil/time.c +++ b/ffmpeg/libavutil/time.c @@ -60,7 +60,7 @@ int64_t av_gettime_relative(void) 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 } diff --git a/ffmpeg/libavutil/time.h b/ffmpeg/libavutil/time.h index 910d28e..dc169b0 100644 --- a/ffmpeg/libavutil/time.h +++ b/ffmpeg/libavutil/time.h @@ -32,8 +32,8 @@ int64_t av_gettime(void); * 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); diff --git a/ffmpeg/libavcodec/dsputil_compat.c b/ffmpeg/libavutil/time_internal.h similarity index 53% rename from ffmpeg/libavcodec/dsputil_compat.c rename to ffmpeg/libavutil/time_internal.h index 7ac1099..612a75a 100644 --- a/ffmpeg/libavcodec/dsputil_compat.c +++ b/ffmpeg/libavutil/time_internal.h @@ -1,6 +1,4 @@ /* - * DSP utils - * * This file is part of FFmpeg. * * FFmpeg is free software; you can redistribute it and/or @@ -18,39 +16,32 @@ * 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 +#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 */ diff --git a/ffmpeg/libavutil/version.h b/ffmpeg/libavutil/version.h index 8311cdd..c19e943 100644 --- a/ffmpeg/libavutil/version.h +++ b/ffmpeg/libavutil/version.h @@ -56,7 +56,7 @@ */ #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, \ @@ -80,12 +80,6 @@ * @{ */ -#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 @@ -107,15 +101,9 @@ #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 @@ -125,25 +113,18 @@ #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 diff --git a/ffmpeg/libavutil/wchar_filename.h b/ffmpeg/libavutil/wchar_filename.h new file mode 100644 index 0000000..c553c46 --- /dev/null +++ b/ffmpeg/libavutil/wchar_filename.h @@ -0,0 +1,44 @@ +/* + * 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 +#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 */ diff --git a/ffmpeg/libavutil/x86/lls_init.c b/ffmpeg/libavutil/x86/lls_init.c index 181ca38..f531904 100644 --- a/ffmpeg/libavutil/x86/lls_init.c +++ b/ffmpeg/libavutil/x86/lls_init.c @@ -23,9 +23,9 @@ #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) { diff --git a/ffmpeg/libavutil/x86/x86util.asm b/ffmpeg/libavutil/x86/x86util.asm index 0d0ef07..2d02f75 100644 --- a/ffmpeg/libavutil/x86/x86util.asm +++ b/ffmpeg/libavutil/x86/x86util.asm @@ -641,6 +641,11 @@ %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 diff --git a/ffmpeg/libpostproc/postprocess.c b/ffmpeg/libpostproc/postprocess.c index 670908c..f8fb356 100644 --- a/ffmpeg/libpostproc/postprocess.c +++ b/ffmpeg/libpostproc/postprocess.c @@ -151,6 +151,7 @@ static const struct PPFilter filters[]= {"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 }; @@ -166,28 +167,28 @@ static const char * const replaceTable[]= #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) @@ -209,13 +210,13 @@ static inline int isHorizDC_C(const uint8_t src[], int stride, const PPContext * const int dcThreshold= dcOffset*2 + 1; for(y=0; y c->ppMode.flatnessThreshold; @@ -233,14 +234,14 @@ static inline int isVertDC_C(const uint8_t src[], int stride, const PPContext *c src+= stride*4; // src points to begin of the 8x8 Block for(y=0; y c->ppMode.flatnessThreshold; @@ -278,10 +279,7 @@ static inline int isVertMinMaxOk_C(const uint8_t src[], int stride, int QP) 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; } @@ -290,10 +288,7 @@ static inline int horizClassify_C(const uint8_t src[], int stride, const PPConte 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; } @@ -436,7 +431,7 @@ static inline void horizX1Filter(uint8_t *src, int stride, int QP) * 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; @@ -447,15 +442,15 @@ static av_always_inline void do_a_deblock_C(uint8_t *src, int step, 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; @@ -491,6 +486,16 @@ static av_always_inline void do_a_deblock_C(uint8_t *src, int step, 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; @@ -522,6 +527,13 @@ static av_always_inline void do_a_deblock_C(uint8_t *src, int step, 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; } @@ -704,21 +716,22 @@ pp_mode *pp_get_mode_by_name_and_quality(const char *name, int quality) 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; @@ -731,7 +744,7 @@ pp_mode *pp_get_mode_by_name_and_quality(const char *name, int quality) } 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); @@ -858,7 +871,7 @@ void pp_free_mode(pp_mode *mode){ 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); } @@ -871,23 +884,23 @@ static void reallocBuffers(PPContext *c, int width, int height, int stride, int 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) { @@ -931,8 +944,10 @@ void pp_free_context(void *vc){ 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; itempBlurred); i++) + av_free(c->tempBlurred[i]); + for(i=0; itempBlurredPast); i++) + av_free(c->tempBlurredPast[i]); av_free(c->tempBlocks); av_free(c->yHistogram); @@ -956,8 +971,8 @@ void pp_postprocess(const uint8_t * src[3], const int srcStride[3], { 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); @@ -1027,6 +1042,9 @@ void pp_postprocess(const uint8_t * src[3], const int srcStride[3], 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; diff --git a/ffmpeg/libpostproc/postprocess.h b/ffmpeg/libpostproc/postprocess.h index 928e01f..e00ed96 100644 --- a/ffmpeg/libpostproc/postprocess.h +++ b/ffmpeg/libpostproc/postprocess.h @@ -96,6 +96,7 @@ void pp_free_context(pp_context *ppContext); #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 diff --git a/ffmpeg/libpostproc/postprocess_internal.h b/ffmpeg/libpostproc/postprocess_internal.h index b1b8f0c..1ebd974 100644 --- a/ffmpeg/libpostproc/postprocess_internal.h +++ b/ffmpeg/libpostproc/postprocess_internal.h @@ -69,6 +69,7 @@ #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) @@ -76,8 +77,6 @@ //filters on //#define COMPILE_TIME_MODE 0x77 -#define CLIP av_clip_uint8 - /** * Postprocessing filter. */ diff --git a/ffmpeg/libpostproc/postprocess_template.c b/ffmpeg/libpostproc/postprocess_template.c index 10b91c3..6722f96 100644 --- a/ffmpeg/libpostproc/postprocess_template.c +++ b/ffmpeg/libpostproc/postprocess_template.c @@ -108,7 +108,7 @@ /** * 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( @@ -1571,10 +1571,10 @@ DEINT_CUBIC((%%REGd, %1), (%0, %1, 8) , (%%REGd, %1, 4), (%%REGc) , (%%REGc, 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 @@ -1645,13 +1645,13 @@ DEINT_FF((%%REGd, %1), (%%REGd, %1, 2), (%0, %1, 8) , (%%REGd, %1, 4)) 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++; @@ -1736,21 +1736,21 @@ DEINT_L5(%%mm1, %%mm0, (%%REGd, %1, 2), (%0, %1, 8) , (%%REGd, %1, 4)) 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; @@ -1989,7 +1989,7 @@ MEDIAN((%%REGd, %1), (%%REGd, %1, 2), (%0, %1, 8)) /** * 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" @@ -2074,7 +2074,7 @@ static inline void RENAME(transpose1)(uint8_t *dst1, uint8_t *dst2, uint8_t *src /** * 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" @@ -2155,7 +2155,7 @@ static inline void RENAME(transpose2)(uint8_t *dst, int dstStride, uint8_t *src) #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]; @@ -2544,7 +2544,7 @@ Switch between /** * 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 @@ -3272,6 +3272,12 @@ static void RENAME(postProcess)(const uint8_t src[], int srcStride, uint8_t dst[ 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; @@ -3566,7 +3572,7 @@ static void RENAME(postProcess)(const uint8_t src[], int srcStride, uint8_t dst[ 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); } } @@ -3587,7 +3593,7 @@ static void RENAME(postProcess)(const uint8_t src[], int srcStride, uint8_t dst[ 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); @@ -3619,7 +3625,7 @@ static void RENAME(postProcess)(const uint8_t src[], int srcStride, uint8_t dst[ 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){ diff --git a/ffmpeg/libpostproc/version.h b/ffmpeg/libpostproc/version.h index dab1965..59c2466 100644 --- a/ffmpeg/libpostproc/version.h +++ b/ffmpeg/libpostproc/version.h @@ -29,7 +29,7 @@ #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, \ diff --git a/ffmpeg/libswresample/audioconvert.c b/ffmpeg/libswresample/audioconvert.c index efdc9b5..58b0bf3 100644 --- a/ffmpeg/libswresample/audioconvert.c +++ b/ffmpeg/libswresample/audioconvert.c @@ -52,8 +52,8 @@ static void CONV_FUNC_NAME(ofmt, ifmt)(uint8_t *po, const uint8_t *pi, int is, i //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) diff --git a/ffmpeg/libswresample/resample.c b/ffmpeg/libswresample/resample.c index 2a8aa7e..d0f6e20 100644 --- a/ffmpeg/libswresample/resample.c +++ b/ffmpeg/libswresample/resample.c @@ -399,11 +399,11 @@ static int invert_initial_buffer(ResampleContext *c, AudioData *dst, const Audio 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={ diff --git a/ffmpeg/libswresample/swresample.c b/ffmpeg/libswresample/swresample.c index c325513..b0bd697 100644 --- a/ffmpeg/libswresample/swresample.c +++ b/ffmpeg/libswresample/swresample.c @@ -435,9 +435,15 @@ static int resample(SwrContext *s, AudioData *out_param, int out_count, 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; @@ -668,8 +674,8 @@ int swr_convert(struct SwrContext *s, uint8_t *out_arg[SWR_CH_MAX], int out_coun continue; } - if(s->drop_output || !out_arg) - return 0; + av_assert0(s->drop_output); + return 0; } if(!in_arg){ @@ -746,13 +752,14 @@ int swr_convert(struct SwrContext *s, uint8_t *out_arg[SWR_CH_MAX], int out_coun } 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){ diff --git a/ffmpeg/libswresample/x86/audio_convert.asm b/ffmpeg/libswresample/x86/audio_convert.asm index b6e9e5d..57d3a89 100644 --- a/ffmpeg/libswresample/x86/audio_convert.asm +++ b/ffmpeg/libswresample/x86/audio_convert.asm @@ -245,15 +245,27 @@ pack_6ch_%2_to_%1_u_int %+ SUFFIX 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 @@ -330,10 +342,10 @@ pack_6ch_%2_to_%1_u_int %+ SUFFIX 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 @@ -380,6 +392,10 @@ CONV int16, int32, a, 1, 2, INT32_TO_INT16_N, NOP_N 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 @@ -431,6 +447,10 @@ UNPACK_2CH float, int16, a, 2, 1, INT16_TO_FLOAT_N, INT16_TO_FLOAT_INIT 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 @@ -440,15 +460,6 @@ UNPACK_2CH int32, int16, a, 2, 1, INT16_TO_INT32_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 @@ -463,3 +474,9 @@ INIT_YMM avx 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 diff --git a/ffmpeg/libswresample/x86/audio_convert_init.c b/ffmpeg/libswresample/x86/audio_convert_init.c index a26cdf6..90bed51 100644 --- a/ffmpeg/libswresample/x86/audio_convert_init.c +++ b/ffmpeg/libswresample/x86/audio_convert_init.c @@ -25,7 +25,7 @@ #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_) @@ -58,7 +58,12 @@ MULTI_CAPS_FUNC(SSE2, sse2) 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; @@ -105,6 +110,12 @@ MULTI_CAPS_FUNC(SSE2, 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) { @@ -116,16 +127,6 @@ MULTI_CAPS_FUNC(SSE2, sse2) 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; @@ -138,4 +139,8 @@ MULTI_CAPS_FUNC(SSE2, sse2) 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; + } } diff --git a/ffmpeg/libswscale/ppc/swscale_altivec.c b/ffmpeg/libswscale/ppc/swscale_altivec.c index 86f40ab..a1548a7 100644 --- a/ffmpeg/libswscale/ppc/swscale_altivec.c +++ b/ffmpeg/libswscale/ppc/swscale_altivec.c @@ -29,22 +29,62 @@ #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) @@ -66,14 +106,13 @@ static void yuv2planeX_16_altivec(const int16_t *filter, int filterSize, 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); } @@ -85,9 +124,10 @@ static void yuv2planeX_16_altivec(const int16_t *filter, int filterSize, 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) @@ -118,6 +158,58 @@ static void yuv2planeX_altivec(const int16_t *filter, int filterSize, 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) @@ -140,57 +232,32 @@ static void hScale_altivec_real(SwsContext *c, int16_t *dst, int dstW, 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); @@ -202,85 +269,64 @@ static void hScale_altivec_real(SwsContext *c, int16_t *dst, int dstW, 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); } } diff --git a/ffmpeg/libswscale/rgb2rgb_template.c b/ffmpeg/libswscale/rgb2rgb_template.c index 121f4ef..f9a98a8 100644 --- a/ffmpeg/libswscale/rgb2rgb_template.c +++ b/ffmpeg/libswscale/rgb2rgb_template.c @@ -355,9 +355,9 @@ static inline void yuvPlanartoyuy2_c(const uint8_t *ysrc, const uint8_t *usrc, 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; @@ -419,9 +419,9 @@ static inline void yuvPlanartouyvy_c(const uint8_t *ysrc, const uint8_t *usrc, 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; diff --git a/ffmpeg/libswscale/swscale.c b/ffmpeg/libswscale/swscale.c index 59ead12..16a31ce 100644 --- a/ffmpeg/libswscale/swscale.c +++ b/ffmpeg/libswscale/swscale.c @@ -27,6 +27,7 @@ #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" @@ -804,9 +805,9 @@ static void xyz12Torgb48(struct SwsContext *c, uint16_t *dst, 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) { @@ -860,9 +861,9 @@ static void rgb48Toxyz12(struct SwsContext *c, uint16_t *dst, 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) { @@ -899,6 +900,18 @@ int attribute_align_arg sws_scale(struct SwsContext *c, 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)); diff --git a/ffmpeg/libswscale/swscale_internal.h b/ffmpeg/libswscale/swscale_internal.h index 335e1f8..63b4eca 100644 --- a/ffmpeg/libswscale/swscale_internal.h +++ b/ffmpeg/libswscale/swscale_internal.h @@ -61,6 +61,8 @@ # define APCK_SIZE 16 #endif +#define RETCODE_USE_CASCADE -12345 + struct SwsContext; typedef enum SwsDither { @@ -301,6 +303,14 @@ typedef struct SwsContext { 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]; @@ -611,14 +621,6 @@ av_cold void ff_sws_init_range_convert(SwsContext *c); 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); diff --git a/ffmpeg/libswscale/utils.c b/ffmpeg/libswscale/utils.c index 5615700..ab494ed 100644 --- a/ffmpeg/libswscale/utils.c +++ b/ffmpeg/libswscale/utils.c @@ -42,6 +42,7 @@ #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" @@ -240,17 +241,6 @@ int sws_isSupportedEndiannessConversion(enum AVPixelFormat pix_fmt) 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) { @@ -582,8 +572,7 @@ static av_cold int initFilter(int16_t **outFilter, int32_t **filterPos, 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; @@ -675,7 +664,7 @@ static av_cold int initFilter(int16_t **outFilter, int32_t **filterPos, 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; @@ -970,6 +959,7 @@ av_cold int sws_init_context(SwsContext *c, SwsFilter *srcFilter, 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; @@ -1227,6 +1217,31 @@ av_cold int sws_init_context(SwsContext *c, SwsFilter *srcFilter, } } + 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 */ @@ -1295,23 +1310,23 @@ av_cold int sws_init_context(SwsContext *c, SwsFilter *srcFilter, 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 @@ -1321,22 +1336,22 @@ av_cold int sws_init_context(SwsContext *c, SwsFilter *srcFilter, 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; @@ -1490,6 +1505,32 @@ av_cold int sws_init_context(SwsContext *c, SwsFilter *srcFilter, 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; } @@ -1901,6 +1942,11 @@ void sws_freeContext(SwsContext *c) 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); } diff --git a/ffmpeg/libswscale/version.h b/ffmpeg/libswscale/version.h index b764883..228c577 100644 --- a/ffmpeg/libswscale/version.h +++ b/ffmpeg/libswscale/version.h @@ -27,8 +27,8 @@ #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, \ @@ -49,9 +49,6 @@ #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 diff --git a/ffmpeg/libswscale/x86/rgb2rgb_template.c b/ffmpeg/libswscale/x86/rgb2rgb_template.c index 3899d0a..e71c7eb 100644 --- a/ffmpeg/libswscale/x86/rgb2rgb_template.c +++ b/ffmpeg/libswscale/x86/rgb2rgb_template.c @@ -1634,6 +1634,16 @@ static inline void RENAME(rgb24toyv12)(const uint8_t *src, uint8_t *ydst, uint8_ #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= 16) #if COMPILE_TEMPLATE_SSE2 __asm__( "xor %%"REG_a", %%"REG_a" \n\t" diff --git a/ffmpeg/libswscale/x86/swscale.c b/ffmpeg/libswscale/x86/swscale.c index c4c0e28..fe5c4ea 100644 --- a/ffmpeg/libswscale/x86/swscale.c +++ b/ffmpeg/libswscale/x86/swscale.c @@ -205,36 +205,20 @@ static void yuv2yuvX_sse3(const int16_t *filter, int filterSize, 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? */\ @@ -252,20 +236,41 @@ static void yuv2yuvX_sse3(const int16_t *filter, int filterSize, " 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 @@ -425,7 +430,7 @@ switch(c->dstBpc){ \ case 16: do_16_case; break; \ case 10: if (!isBE(c->dstFormat)) vscalefn = ff_yuv2planeX_10_ ## opt; break; \ case 9: if (!isBE(c->dstFormat)) vscalefn = ff_yuv2planeX_9_ ## opt; break; \ - default: 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){ \ diff --git a/ffmpeg/tests/Makefile b/ffmpeg/tests/Makefile index 184e220..84caed6 100644 --- a/ffmpeg/tests/Makefile +++ b/ffmpeg/tests/Makefile @@ -31,23 +31,26 @@ tests/data/vsynth1.yuv: tests/videogen$(HOSTEXESUF) | tests/data $(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 @@ -131,6 +134,7 @@ include $(SRC_PATH)/tests/fate/microsoft.mak 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 @@ -216,7 +220,7 @@ testclean: $(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) diff --git a/ffmpeg/tests/fate-run.sh b/ffmpeg/tests/fate-run.sh index b994aba..f78e4fc 100755 --- a/ffmpeg/tests/fate-run.sh +++ b/ffmpeg/tests/fate-run.sh @@ -114,6 +114,12 @@ pcm(){ ffmpeg "$@" -vn -f s16le - } +fmtstdout(){ + fmt=$1 + shift 1 + ffmpeg -flags +bitexact "$@" -f $fmt - +} + enc_dec_pcm(){ out_fmt=$1 dec_fmt=$2 @@ -197,12 +203,14 @@ pixfmts(){ $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" @@ -223,6 +231,7 @@ fi 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 ;; diff --git a/ffmpeg/tests/fate/audio.mak b/ffmpeg/tests/fate/audio.mak index aa58dfc..b7e5362 100644 --- a/ffmpeg/tests/fate/audio.mak +++ b/ffmpeg/tests/fate/audio.mak @@ -44,8 +44,8 @@ fate-nellymoser-aref-encode: $(AREF) ./tests/data/asynth-16000-1.wav 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 diff --git a/ffmpeg/tests/fate/ffmpeg.mak b/ffmpeg/tests/fate/ffmpeg.mak index a6cb159..6af1081 100644 --- a/ffmpeg/tests/fate/ffmpeg.mak +++ b/ffmpeg/tests/fate/ffmpeg.mak @@ -22,16 +22,16 @@ FATE_FFMPEG-$(CONFIG_COLOR_FILTER) += fate-ffmpeg-lavfi 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 diff --git a/ffmpeg/tests/fate/filter-video.mak b/ffmpeg/tests/fate/filter-video.mak index 9239b37..601a0d8 100644 --- a/ffmpeg/tests/fate/filter-video.mak +++ b/ffmpeg/tests/fate/filter-video.mak @@ -156,6 +156,13 @@ fate-filter-hq3x: CMD = framecrc -i $(TARGET_SAMPLES)/filter/pixelart%d.png -vf 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 @@ -229,6 +236,9 @@ fate-filter-pad: CMD = video_filter "pad=iw*1.5:ih*1.5:iw*0.3:ih*0.2" 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" diff --git a/ffmpeg/tests/fate/libavutil.mak b/ffmpeg/tests/fate/libavutil.mak index 579bdfb..eadebdb 100644 --- a/ffmpeg/tests/fate/libavutil.mak +++ b/ffmpeg/tests/fate/libavutil.mak @@ -8,6 +8,11 @@ fate-aes: libavutil/aes-test$(EXESUF) 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 @@ -53,7 +58,7 @@ fate-fifo: CMD = run libavutil/fifo-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 @@ -102,6 +107,10 @@ FATE_LIBAVUTIL += fate-xtea 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) diff --git a/ffmpeg/tests/fate/libswresample.mak b/ffmpeg/tests/fate/libswresample.mak index 3b479a9..24b7d66 100644 --- a/ffmpeg/tests/fate/libswresample.mak +++ b/ffmpeg/tests/fate/libswresample.mak @@ -365,17 +365,17 @@ fate-swr-resample_async-$(3)-$(1)-$(2): FUZZ = 0.1 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) diff --git a/ffmpeg/tests/fate/microsoft.mak b/ffmpeg/tests/fate/microsoft.mak index 27e46db..4e8ae51 100644 --- a/ffmpeg/tests/fate/microsoft.mak +++ b/ffmpeg/tests/fate/microsoft.mak @@ -57,6 +57,9 @@ fate-vc1_sa10143: CMD = framecrc -i $(TARGET_SAMPLES)/vc1/SA10143.vc1 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 diff --git a/ffmpeg/tests/fate/mpeg4.mak b/ffmpeg/tests/fate/mpeg4.mak new file mode 100644 index 0000000..eefdec9 --- /dev/null +++ b/ffmpeg/tests/fate/mpeg4.mak @@ -0,0 +1,9 @@ + +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) diff --git a/ffmpeg/tests/fate/real.mak b/ffmpeg/tests/fate/real.mak index e57f883..c123e44 100644 --- a/ffmpeg/tests/fate/real.mak +++ b/ffmpeg/tests/fate/real.mak @@ -1,3 +1,11 @@ +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 @@ -40,8 +48,10 @@ $(FATE_SIPR): CMP = oneoff 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) diff --git a/ffmpeg/tests/fate/seek.mak b/ffmpeg/tests/fate/seek.mak index e511387..105f3c7 100644 --- a/ffmpeg/tests/fate/seek.mak +++ b/ffmpeg/tests/fate/seek.mak @@ -58,32 +58,32 @@ fate-seek-acodec-pcm-u8: SRC = fate/acodec-pcm-u8.wav 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 \ @@ -91,71 +91,71 @@ FATE_SEEK_VSYNTH2-$(call ENCDEC, MPEG2VIDEO, MPEG2VIDEO MPEGVIDEO) += \ 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 diff --git a/ffmpeg/tests/fate/subtitles.mak b/ffmpeg/tests/fate/subtitles.mak index 0c71882..53cd4cb 100644 --- a/ffmpeg/tests/fate/subtitles.mak +++ b/ffmpeg/tests/fate/subtitles.mak @@ -1,65 +1,69 @@ 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) diff --git a/ffmpeg/tests/fate/vcodec.mak b/ffmpeg/tests/fate/vcodec.mak index c715071..807699e 100644 --- a/ffmpeg/tests/fate/vcodec.mak +++ b/ffmpeg/tests/fate/vcodec.mak @@ -1,5 +1,6 @@ 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 @@ -294,6 +295,11 @@ fate-vsynth%-wmv2: ENCOPTS = -qscale 10 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 @@ -303,6 +309,7 @@ FATE_VCODEC-$(call ENCDEC, ZLIB, AVI) += zlib 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 @@ -316,12 +323,14 @@ FATE_VSYNTH3 = $(FATE_VCODEC3:%=fate-vsynth3-%) $(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 diff --git a/ffmpeg/tests/fate/vpx.mak b/ffmpeg/tests/fate/vpx.mak index 0f84ef5..03f571b 100644 --- a/ffmpeg/tests/fate/vpx.mak +++ b/ffmpeg/tests/fate/vpx.mak @@ -37,6 +37,9 @@ fate-webm-dash-manifest-unaligned-video-streams: CMD = run ffmpeg -f webm_dash_m 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) @@ -95,6 +98,7 @@ $(eval $(call FATE_VP9_SUITE,parallelmode-akiyo,$(1),$(2))) $(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)) diff --git a/ffmpeg/tests/ref/acodec/adpcm-adx b/ffmpeg/tests/ref/acodec/adpcm-adx index b96d99a..34dd9b6 100644 --- a/ffmpeg/tests/ref/acodec/adpcm-adx +++ b/ffmpeg/tests/ref/acodec/adpcm-adx @@ -1,4 +1,4 @@ -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 diff --git a/ffmpeg/tests/ref/acodec/adpcm-adx-trellis b/ffmpeg/tests/ref/acodec/adpcm-adx-trellis index fff0291..d620d4a 100644 --- a/ffmpeg/tests/ref/acodec/adpcm-adx-trellis +++ b/ffmpeg/tests/ref/acodec/adpcm-adx-trellis @@ -1,4 +1,4 @@ -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 diff --git a/ffmpeg/tests/ref/fate/cdxl-bitline-ham6 b/ffmpeg/tests/ref/fate/cdxl-bitline-ham6 index 8060f06..9ba7404 100644 --- a/ffmpeg/tests/ref/fate/cdxl-bitline-ham6 +++ b/ffmpeg/tests/ref/fate/cdxl-bitline-ham6 @@ -1,4 +1,4 @@ -#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 diff --git a/ffmpeg/tests/ref/fate/cdxl-ham8 b/ffmpeg/tests/ref/fate/cdxl-ham8 index 269f1f3..1eebea3 100644 --- a/ffmpeg/tests/ref/fate/cdxl-ham8 +++ b/ffmpeg/tests/ref/fate/cdxl-ham8 @@ -1,2 +1,2 @@ -#tb 0: 3/158 +#tb 0: 12/281 0, 0, 0, 1, 67584, 0xce0cade5 diff --git a/ffmpeg/tests/ref/fate/cdxl-pal8 b/ffmpeg/tests/ref/fate/cdxl-pal8 index 82d4d63..b2fb045 100644 --- a/ffmpeg/tests/ref/fate/cdxl-pal8 +++ b/ffmpeg/tests/ref/fate/cdxl-pal8 @@ -1,4 +1,4 @@ -#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 diff --git a/ffmpeg/tests/ref/fate/ffprobe_compact b/ffmpeg/tests/ref/fate/ffprobe_compact index 3db868d..b7526f4 100644 --- a/ffmpeg/tests/ref/fate/ffprobe_compact +++ b/ffmpeg/tests/ref/fate/ffprobe_compact @@ -27,6 +27,6 @@ frame|media_type=video|key_frame=1|pkt_pts=6144|pkt_pts_time=0.120000|pkt_dts=61 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:comment2=I ♥ Üñîçød€ diff --git a/ffmpeg/tests/ref/fate/ffprobe_csv b/ffmpeg/tests/ref/fate/ffprobe_csv index 935f22e..78060da 100644 --- a/ffmpeg/tests/ref/fate/ffprobe_csv +++ b/ffmpeg/tests/ref/fate/ffprobe_csv @@ -27,6 +27,6 @@ frame,video,1,6144,0.120000,6144,0.120000,6144,0.120000,2048,0.040000,794377,230 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': ",I ♥ Üñîçød€ diff --git a/ffmpeg/tests/ref/fate/ffprobe_default b/ffmpeg/tests/ref/fate/ffprobe_default index e29e4ab..dcf4e25 100644 --- a/ffmpeg/tests/ref/fate/ffprobe_default +++ b/ffmpeg/tests/ref/fate/ffprobe_default @@ -566,6 +566,9 @@ 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 @@ -613,6 +616,9 @@ 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 diff --git a/ffmpeg/tests/ref/fate/ffprobe_flat b/ffmpeg/tests/ref/fate/ffprobe_flat index 289c535..c1e6b1a 100644 --- a/ffmpeg/tests/ref/fate/ffprobe_flat +++ b/ffmpeg/tests/ref/fate/ffprobe_flat @@ -507,6 +507,9 @@ streams.stream.1.pix_fmt="rgb24" 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" @@ -552,6 +555,9 @@ streams.stream.2.pix_fmt="rgb24" 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" diff --git a/ffmpeg/tests/ref/fate/ffprobe_ini b/ffmpeg/tests/ref/fate/ffprobe_ini index fbf680e..b2ae271 100644 --- a/ffmpeg/tests/ref/fate/ffprobe_ini +++ b/ffmpeg/tests/ref/fate/ffprobe_ini @@ -572,6 +572,9 @@ 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 @@ -623,6 +626,9 @@ 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 diff --git a/ffmpeg/tests/ref/fate/filter-2xbr b/ffmpeg/tests/ref/fate/filter-2xbr new file mode 100644 index 0000000..91e1d4c --- /dev/null +++ b/ffmpeg/tests/ref/fate/filter-2xbr @@ -0,0 +1,3 @@ +#tb 0: 1/25 +0, 0, 0, 1, 877072, 0x5142c6cd +0, 1, 1, 1, 877072, 0xa01a3f47 diff --git a/ffmpeg/tests/ref/fate/filter-3xbr b/ffmpeg/tests/ref/fate/filter-3xbr new file mode 100644 index 0000000..013f6a3 --- /dev/null +++ b/ffmpeg/tests/ref/fate/filter-3xbr @@ -0,0 +1,3 @@ +#tb 0: 1/25 +0, 0, 0, 1, 1973412, 0xd4cf257b +0, 1, 1, 1, 1973412, 0x63fcd614 diff --git a/ffmpeg/tests/ref/fate/filter-4xbr b/ffmpeg/tests/ref/fate/filter-4xbr new file mode 100644 index 0000000..92b70d9 --- /dev/null +++ b/ffmpeg/tests/ref/fate/filter-4xbr @@ -0,0 +1,3 @@ +#tb 0: 1/25 +0, 0, 0, 1, 3508288, 0xc7b1d170 +0, 1, 1, 1, 3508288, 0x3fd0c3fb diff --git a/ffmpeg/tests/ref/fate/filter-idet b/ffmpeg/tests/ref/fate/filter-idet index f1396c5..2f9f11c 100644 --- a/ffmpeg/tests/ref/fate/filter-idet +++ b/ffmpeg/tests/ref/fate/filter-idet @@ -1 +1 @@ -idet 1790336872e844c867a53150b8ee8810 +idet 005e6ddc8a5daf11cf866a1ec76c2572 diff --git a/ffmpeg/tests/ref/fate/filter-pixfmts-kerndeint b/ffmpeg/tests/ref/fate/filter-pixfmts-kerndeint index 6fefda3..376d8f4 100644 --- a/ffmpeg/tests/ref/fate/filter-pixfmts-kerndeint +++ b/ffmpeg/tests/ref/fate/filter-pixfmts-kerndeint @@ -1,10 +1,10 @@ -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 diff --git a/ffmpeg/tests/ref/fate/filter-pixfmts-tinterlace_merge b/ffmpeg/tests/ref/fate/filter-pixfmts-tinterlace_merge index 526b77f..4f1f75e 100644 --- a/ffmpeg/tests/ref/fate/filter-pixfmts-tinterlace_merge +++ b/ffmpeg/tests/ref/fate/filter-pixfmts-tinterlace_merge @@ -1,14 +1,14 @@ -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 diff --git a/ffmpeg/tests/ref/fate/filter-pp1 b/ffmpeg/tests/ref/fate/filter-pp1 new file mode 100644 index 0000000..b129ea3 --- /dev/null +++ b/ffmpeg/tests/ref/fate/filter-pp1 @@ -0,0 +1 @@ +pp1 cb9f884e27a5be11f72afc9b517efd10 diff --git a/ffmpeg/tests/ref/fate/gif-disposal-restore b/ffmpeg/tests/ref/fate/gif-disposal-restore index c5ebfcb..0ff1715 100644 --- a/ffmpeg/tests/ref/fate/gif-disposal-restore +++ b/ffmpeg/tests/ref/fate/gif-disposal-restore @@ -1,3 +1,4 @@ #tb 0: 1/1 0, 0, 0, 1, 112320, 0xb8afe429 +0, 1, 1, 1, 112320, 0xae588a4b 0, 3, 3, 1, 112320, 0xccdd27b7 diff --git a/ffmpeg/tests/ref/fate/mpeg4-resolution-change-down-down b/ffmpeg/tests/ref/fate/mpeg4-resolution-change-down-down new file mode 100644 index 0000000..02fcda5 --- /dev/null +++ b/ffmpeg/tests/ref/fate/mpeg4-resolution-change-down-down @@ -0,0 +1,155 @@ +#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 diff --git a/ffmpeg/tests/ref/fate/mpeg4-resolution-change-down-up b/ffmpeg/tests/ref/fate/mpeg4-resolution-change-down-up new file mode 100644 index 0000000..37e56d8 --- /dev/null +++ b/ffmpeg/tests/ref/fate/mpeg4-resolution-change-down-up @@ -0,0 +1,155 @@ +#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 diff --git a/ffmpeg/tests/ref/fate/mpeg4-resolution-change-up-down b/ffmpeg/tests/ref/fate/mpeg4-resolution-change-up-down new file mode 100644 index 0000000..36110c3 --- /dev/null +++ b/ffmpeg/tests/ref/fate/mpeg4-resolution-change-up-down @@ -0,0 +1,155 @@ +#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 diff --git a/ffmpeg/tests/ref/fate/mpeg4-resolution-change-up-up b/ffmpeg/tests/ref/fate/mpeg4-resolution-change-up-up new file mode 100644 index 0000000..8d1bbcd --- /dev/null +++ b/ffmpeg/tests/ref/fate/mpeg4-resolution-change-up-up @@ -0,0 +1,155 @@ +#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 diff --git a/ffmpeg/tests/ref/fate/opt b/ffmpeg/tests/ref/fate/opt new file mode 100644 index 0000000..084a222 --- /dev/null +++ b/ffmpeg/tests/ref/fate/opt @@ -0,0 +1,141 @@ +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' diff --git a/ffmpeg/tests/ref/fate/ra3-144 b/ffmpeg/tests/ref/fate/ra3-144 new file mode 100644 index 0000000..40bcaed --- /dev/null +++ b/ffmpeg/tests/ref/fate/ra3-144 @@ -0,0 +1,51 @@ +#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 diff --git a/ffmpeg/tests/ref/fate/sub-aqtitle b/ffmpeg/tests/ref/fate/sub-aqtitle index d87194b..87253c9 100644 --- a/ffmpeg/tests/ref/fate/sub-aqtitle +++ b/ffmpeg/tests/ref/fate/sub-aqtitle @@ -1 +1,45 @@ -47834efc39225264e705dfb885f57df2 +[Script Info] +; Script generated by FFmpeg/Lavc +ScriptType: v4.00+ +PlayResX: 384 +PlayResY: 288 + +[V4+ Styles] +Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding +Style: Default,Arial,16,&Hffffff,&Hffffff,&H0,&H0,0,0,0,0,100,100,0,0,1,1,0,2,10,10,10,0 + +[Events] +Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text +Dialogue: 0,0:03:29.92,0:03:31.28,Default,,0,0,0,,Dougu? +Dialogue: 0,0:03:33.36,0:03:35.76,Default,,0,0,0,,Zlato, jseÅ¡ v pořádku? +Dialogue: 0,0:03:37.72,0:03:39.12,Default,,0,0,0,,Měl jsi sny. +Dialogue: 0,0:03:41.44,0:03:43.32,Default,,0,0,0,,Byly o Marsu? +Dialogue: 0,0:03:48.92,0:03:50.52,Default,,0,0,0,,Je to lepší? +Dialogue: 0,0:03:53.12,0:03:54.72,Default,,0,0,0,,Chudinko moje. +Dialogue: 0,0:03:55.76,0:03:58.08,Default,,0,0,0,,Začíná to být\Nposedlost. +Dialogue: 0,0:04:05.92,0:04:07.16,Default,,0,0,0,,Byla tam i ona? +Dialogue: 0,0:04:09.12,0:04:10.48,Default,,0,0,0,,Kdo? +Dialogue: 0,0:04:12.44,0:04:15.16,Default,,0,0,0,,Ta, o které jsi mi vyprávěl.\NTa bruneta. +Dialogue: 0,0:04:16.32,0:04:17.52,Default,,0,0,0,,Lori. +Dialogue: 0,0:04:20.32,0:04:23.16,Default,,0,0,0,,Nemůžu uvěřit\Nže žárlíš na sen. +Dialogue: 0,0:04:23.84,0:04:26.60,Default,,0,0,0,,- Kdo je ona?\N- Nikdo. +Dialogue: 0,0:04:26.60,0:04:28.80,Default,,0,0,0,,"Nikdo"? Jak se jmenuje? +Dialogue: 0,0:04:28.80,0:04:30.24,Default,,0,0,0,,Nevím. +Dialogue: 0,0:04:31.52,0:04:33.20,Default,,0,0,0,,- Pověz!\N- Nevím! +Dialogue: 0,0:04:33.20,0:04:35.48,Default,,0,0,0,,RadÅ¡i bys mi to měl říct! +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. +Dialogue: 0,0:04:39.16,0:04:41.84,Default,,0,0,0,,Ale vždy se ráno probudím. +Dialogue: 0,0:04:41.84,0:04:43.28,Default,,0,0,0,,Nech mě být! +Dialogue: 0,0:04:45.72,0:04:47.76,Default,,0,0,0,,No tak, zlato. +Dialogue: 0,0:04:47.76,0:04:50.72,Default,,0,0,0,,Ty víš, že jsi dívkou\Nmých snů. +Dialogue: 0,0:04:50.72,0:04:52.40,Default,,0,0,0,,Myslíš to vážně? +Dialogue: 0,0:04:53.48,0:04:55.32,Default,,0,0,0,,To víš že ano. +Dialogue: 0,0:05:04.40,0:05:07.20,Default,,0,0,0,,Dám ti něco\No čem budeÅ¡ snít. +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... +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... +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. +Dialogue: 0,0:05:24.36,0:05:26.76,Default,,0,0,0,,A další násilí na Marsu... +Dialogue: 0,0:05:26.76,1:44:16.00,Default,,0,0,0,,[...] +Dialogue: 0,1:44:16.00,1:44:17.60,Default,,0,0,0,,Co se děje? +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? +Dialogue: 0,1:44:22.76,1:44:25.68,Default,,0,0,0,,Tak mi dej ryhcle pusu\Nnež se probudíš. diff --git a/ffmpeg/tests/ref/fate/sub-charenc b/ffmpeg/tests/ref/fate/sub-charenc index 5081731..ed5cdbe 100644 --- a/ffmpeg/tests/ref/fate/sub-charenc +++ b/ffmpeg/tests/ref/fate/sub-charenc @@ -1 +1,62 @@ -c088c2924fd7af0a53eeeeb54a3f4456 +[Script Info] +; Script generated by FFmpeg/Lavc +ScriptType: v4.00+ +PlayResX: 384 +PlayResY: 288 + +[V4+ Styles] +Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding +Style: Default,Arial,16,&Hffffff,&Hffffff,&H0,&H0,0,0,0,0,100,100,0,0,1,1,0,2,10,10,10,0 + +[Events] +Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text +Dialogue: 0,0:00:32.95,0:00:38.25,Default,,0,0,0,,КОЛУМБИА ПИКЧЪРС - АЗИЯ\NСОНИ ПИКЧЪРС и Е.Е. Co.\Nпредставят +Dialogue: 0,0:00:52.76,0:00:58.60,Default,,0,0,0,,Т И Г Ъ Р И Д Р А К О Н +Dialogue: 0,0:01:22.17,0:01:24.05,Default,,0,0,0,,Учителят Ли е тук. +Dialogue: 0,0:01:45.48,0:01:47.32,Default,,0,0,0,,Шу Лиен! +Dialogue: 0,0:01:54.53,0:01:57.24,Default,,0,0,0,,Ли Му Бай е тук. +Dialogue: 0,0:02:05.83,0:02:09.00,Default,,0,0,0,,- Как вървят нещата?\N- Добре. Моля, влезте! +Dialogue: 0,0:02:23.48,0:02:26.52,Default,,0,0,0,,Му Бай...\NМина много време. +Dialogue: 0,0:02:26.73,0:02:28.11,Default,,0,0,0,,Така е. +Dialogue: 0,0:02:28.57,0:02:31.41,Default,,0,0,0,,- Как върви бизнесът?\N- Добре. +Dialogue: 0,0:02:31.61,0:02:33.90,Default,,0,0,0,,- А ти как си?\N- Добре. +Dialogue: 0,0:02:40.16,0:02:42.79,Default,,0,0,0,,Монахът Дзенг каза,\Nче си в планината Удан. +Dialogue: 0,0:02:43.04,0:02:46.54,Default,,0,0,0,,Каза, че практикуваш\Nдълбока медитация. +Dialogue: 0,0:02:48.84,0:02:50.68,Default,,0,0,0,,Сигурно в планината\Nе много спокойно. +Dialogue: 0,0:02:51.25,0:02:53.46,Default,,0,0,0,,Завиждам ти. +Dialogue: 0,0:02:53.67,0:02:58.34,Default,,0,0,0,,Имам толкова много работа,\Nпочти не ми остава\Nвреме за почивка. +Dialogue: 0,0:03:00.26,0:03:03.89,Default,,0,0,0,,Оставих обучението рано. +Dialogue: 0,0:03:05.69,0:03:11.28,Default,,0,0,0,,Защо? Ти си боец на Удан.\NОбучението е всичко. +Dialogue: 0,0:03:11.90,0:03:14.86,Default,,0,0,0,,По време на медитация… +Dialogue: 0,0:03:15.07,0:03:18.49,Default,,0,0,0,,стигнах до място,\Nкъдето имаше дълбока тишина... +Dialogue: 0,0:03:19.87,0:03:22.79,Default,,0,0,0,,бях обграден от светлина... +Dialogue: 0,0:03:23.41,0:03:28.08,Default,,0,0,0,,времето и пространството изчезнаха. +Dialogue: 0,0:03:28.71,0:03:34.09,Default,,0,0,0,,Достигнах до състояние, за което\Nучителят не ми беше казвал. +Dialogue: 0,0:03:37.05,0:03:39.14,Default,,0,0,0,,Постигнал си просветление? +Dialogue: 0,0:03:39.34,0:03:41.22,Default,,0,0,0,,Не. +Dialogue: 0,0:03:41.72,0:03:45.81,Default,,0,0,0,,Не почувствах блаженството\Nна просветлението. +Dialogue: 0,0:03:46.02,0:03:52.86,Default,,0,0,0,,Вместо това... ме обгърна\Nбезкрайна мъка. +Dialogue: 0,0:03:53.40,0:03:56.57,Default,,0,0,0,,Не можах да издържа. +Dialogue: 0,0:03:57.49,0:03:59.74,Default,,0,0,0,,Прекъснах медитацията си. +Dialogue: 0,0:03:59.95,0:04:02.24,Default,,0,0,0,,Не можах да продължа. +Dialogue: 0,0:04:03.20,0:04:07.79,Default,,0,0,0,,Нещо...\Nме дърпаше назад. +Dialogue: 0,0:04:09.62,0:04:10.91,Default,,0,0,0,,Какво беше? +Dialogue: 0,0:04:15.46,0:04:18.00,Default,,0,0,0,,Нещо, от което не\Nмога да се освободя. +Dialogue: 0,0:04:23.39,0:04:24.68,Default,,0,0,0,,Скоро ли ще тръгваш? +Dialogue: 0,0:04:26.77,0:04:30.27,Default,,0,0,0,,Подготвяме охрана\Nза една доставка... +Dialogue: 0,0:04:30.48,0:04:31.94,Default,,0,0,0,,за Пекин. +Dialogue: 0,0:04:32.56,0:04:34.10,Default,,0,0,0,,Мога ли да те помоля... +Dialogue: 0,0:04:35.07,0:04:38.82,Default,,0,0,0,,да занесеш нещо на господин Те. +Dialogue: 0,0:04:44.28,0:04:48.12,Default,,0,0,0,,Зеленият меч на Съдбата!?\NДаваш го на господин Те!? +Dialogue: 0,0:04:48.37,0:04:52.67,Default,,0,0,0,,Да. Той винаги е бил\Nнашият най-голям покровител. +Dialogue: 0,0:04:52.88,0:04:56.55,Default,,0,0,0,,Не разбирам.\NКак можеш да се разделиш с него? +Dialogue: 0,0:04:56.76,0:04:59.93,Default,,0,0,0,,Той винаги е бил с теб. +Dialogue: 0,0:05:01.18,0:05:05.52,Default,,0,0,0,,Твърде много хора са\Nзагинали от това острие. +Dialogue: 0,0:05:09.68,0:05:14.52,Default,,0,0,0,,Чисто е единствено защото\Nкръвта се отмива лесно. +Dialogue: 0,0:05:15.40,0:05:20.61,Default,,0,0,0,,Ти го използваш справедливо.\NДостоен си за него. +Dialogue: 0,0:05:23.66,0:05:27.37,Default,,0,0,0,,Дойде време\Nда го оставя. +Dialogue: 0,0:05:27.58,0:05:31.21,Default,,0,0,0,,Е, какво ще правиш\Nот сега нататък? +Dialogue: 0,0:05:34.71,0:05:37.50,Default,,0,0,0,,Ела с мен в Пекин. +Dialogue: 0,0:05:37.71,0:05:41.42,Default,,0,0,0,,Лично ще дадеш меча\Nна господин Те. +Dialogue: 0,0:05:41.68,0:05:44.89,Default,,0,0,0,,Ще бъде както преди. +Dialogue: 0,0:05:47.01,0:05:51.68,Default,,0,0,0,,Първо трябва да отида\Nна гроба на учителя си. diff --git a/ffmpeg/tests/ref/fate/sub-jacosub b/ffmpeg/tests/ref/fate/sub-jacosub index b9b0cf7..a30fe4a 100644 --- a/ffmpeg/tests/ref/fate/sub-jacosub +++ b/ffmpeg/tests/ref/fate/sub-jacosub @@ -1 +1,23 @@ -3bf9f062bd9825c7d8c3b62451b6d360 +[Script Info] +; Script generated by FFmpeg/Lavc +ScriptType: v4.00+ +PlayResX: 384 +PlayResY: 288 + +[V4+ Styles] +Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding +Style: Default,Arial,16,&Hffffff,&Hffffff,&H0,&H0,0,0,0,0,100,100,0,0,1,1,0,2,10,10,10,0 + +[Events] +Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text +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. +Dialogue: 0,0:00:04.12,0:00:14.86,Default,,0,0,0,,{\an8}Text may be positioned at the top, +Dialogue: 0,0:00:05.12,0:00:17.46,Default,,0,0,0,,{\an5}middle, +Dialogue: 0,0:00:06.12,0:00:20.06,Default,,0,0,0,,{\an2}or bottom of the screen. +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. +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, +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, +Dialogue: 0,0:00:14.87,0:00:45.86,Default,,0,0,0,,{\an3}and also\Nright justified. +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}) +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. +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. diff --git a/ffmpeg/tests/ref/fate/sub-microdvd b/ffmpeg/tests/ref/fate/sub-microdvd index f72308e..f0eb331 100644 --- a/ffmpeg/tests/ref/fate/sub-microdvd +++ b/ffmpeg/tests/ref/fate/sub-microdvd @@ -1 +1,23 @@ -1741d6776462277430d5e320157f5bf9 +[Script Info] +; Script generated by FFmpeg/Lavc +ScriptType: v4.00+ +PlayResX: 384 +PlayResY: 288 + +[V4+ Styles] +Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding +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 + +[Events] +Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text +Dialogue: 0,0:00:00.00,0:00:40.00,Default,,0,0,0,,25.000 FPS +Dialogue: 0,0:00:40.00,0:00:52.00,Default,,0,0,0,,{\c&H345678&}foo{\c}\N{\c&HABCDEF&}bar{\c}\Nbla +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 +Dialogue: 0,0:00:56.00,0:01:00.00,Default,,0,0,0,,back to +Dialogue: 0,0:01:00.00,0:01:04.00,Default,,0,0,0,,the future +Dialogue: 0,0:01:20.00,0:01:24.92,Default,,0,0,0,,{\pos(10,20)}Some more crazy stuff +Dialogue: 0,0:02:14.00,0:02:15.60,Default,,0,0,0,,this subtitle... +Dialogue: 0,0:02:15.60,0:02:40.00,Default,,0,0,0,,...continues up to... +Dialogue: 0,0:02:40.00,0:03:00.00,Default,,0,0,0,,this one. +Dialogue: 0,0:03:04.00,0:03:12.00,Default,,0,0,0,,and now... +Dialogue: 0,0:03:12.00,9:59:59.99,Default,,0,0,0,,...to the end of the presentation diff --git a/ffmpeg/tests/ref/fate/sub-microdvd-remux b/ffmpeg/tests/ref/fate/sub-microdvd-remux index 24b5d3d..7cbab62 100644 Binary files a/ffmpeg/tests/ref/fate/sub-microdvd-remux and b/ffmpeg/tests/ref/fate/sub-microdvd-remux differ diff --git a/ffmpeg/tests/ref/fate/sub-movtext b/ffmpeg/tests/ref/fate/sub-movtext index 3274395..6a90e96 100644 --- a/ffmpeg/tests/ref/fate/sub-movtext +++ b/ffmpeg/tests/ref/fate/sub-movtext @@ -1 +1,15 @@ -24c02caa25c6a82d803171697a10d8f5 +[Script Info] +; Script generated by FFmpeg/Lavc +ScriptType: v4.00+ +PlayResX: 384 +PlayResY: 288 + +[V4+ Styles] +Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding +Style: Default,Arial,16,&Hffffff,&Hffffff,&H0,&H0,0,0,0,0,100,100,0,0,1,1,0,2,10,10,10,0 + +[Events] +Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text +Dialogue: 0,0:00:00.97,0:00:02.54,Default,,0,0,0,,- Test 1.\N- Test 2. +Dialogue: 0,0:00:03.05,0:00:04.74,Default,,0,0,0,,Test 3. +Dialogue: 0,0:00:05.85,0:00:08.14,Default,,0,0,0,,- Test 4.\N- Test 5. diff --git a/ffmpeg/tests/ref/fate/sub-movtextenc b/ffmpeg/tests/ref/fate/sub-movtextenc index 5d99766..e74b8f2 100644 --- a/ffmpeg/tests/ref/fate/sub-movtextenc +++ b/ffmpeg/tests/ref/fate/sub-movtextenc @@ -1 +1 @@ -3c685e807d4961924d0abcc18b3f8fa8 +bb762c178bd8c437a9101c748c1ccb4d diff --git a/ffmpeg/tests/ref/fate/sub-mpl2 b/ffmpeg/tests/ref/fate/sub-mpl2 index 39b38bc..72fc0fc 100644 --- a/ffmpeg/tests/ref/fate/sub-mpl2 +++ b/ffmpeg/tests/ref/fate/sub-mpl2 @@ -1 +1,16 @@ -28fb7dad61c3394f5edc8b186fdf7dd6 +[Script Info] +; Script generated by FFmpeg/Lavc +ScriptType: v4.00+ +PlayResX: 384 +PlayResY: 288 + +[V4+ Styles] +Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding +Style: Default,Arial,16,&Hffffff,&Hffffff,&H0,&H0,0,0,0,0,100,100,0,0,1,1,0,2,10,10,10,0 + +[Events] +Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text +Dialogue: 0,0:00:00.00,0:00:01.20,Default,,0,0,0,,Foo\Nbar\Nbla +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 +Dialogue: 0,0:00:05.30,0:00:07.20,Default,,0,0,0,,{\u1}underline{\r}\Nnormal +Dialogue: 0,0:00:08.40,0:00:12.80,Default,,0,0,0,,hello diff --git a/ffmpeg/tests/ref/fate/sub-mpsub b/ffmpeg/tests/ref/fate/sub-mpsub index d49ba2a..890ceb0 100644 --- a/ffmpeg/tests/ref/fate/sub-mpsub +++ b/ffmpeg/tests/ref/fate/sub-mpsub @@ -1 +1,33 @@ -2f10577c4e2631e9a50495fa2cc9a985 +[Script Info] +; Script generated by FFmpeg/Lavc +ScriptType: v4.00+ +PlayResX: 384 +PlayResY: 288 + +[V4+ Styles] +Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding +Style: Default,Arial,16,&Hffffff,&Hffffff,&H0,&H0,0,0,0,0,100,100,0,0,1,1,0,2,10,10,10,0 + +[Events] +Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text +Dialogue: 0,0:00:15.00,0:00:18.00,Default,,0,0,0,,A long, long time ago... +Dialogue: 0,0:00:18.00,0:00:21.00,Default,,0,0,0,,in a galaxy far away... +Dialogue: 0,0:00:21.00,0:00:24.00,Default,,0,0,0,,Naboo was under an attack. +Dialogue: 0,0:00:25.00,0:00:27.50,Default,,0,0,0,,And I thought me and\NQui-Gon Jinn could +Dialogue: 0,0:00:27.50,0:00:30.00,Default,,0,0,0,,talk the Federation into +Dialogue: 0,0:00:30.00,0:00:34.00,Default,,0,0,0,,...maybe cutting them a\Nlittle slack. +Dialogue: 0,0:00:36.00,0:00:39.00,Default,,0,0,0,,But their response, it\Ndidn't thrill us, +Dialogue: 0,0:00:39.00,0:00:42.00,Default,,0,0,0,,They locked the doors,\Nand tried to kill us. +Dialogue: 0,0:00:42.00,0:00:44.50,Default,,0,0,0,,We escaped from that gas, +Dialogue: 0,0:00:44.50,0:00:48.00,Default,,0,0,0,,then met Jar-jar and\NBoss-Nass. +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. +Dialogue: 0,0:00:55.00,0:01:00.00,Default,,0,0,0,,We all wound' up on\NTatooine. +Dialogue: 0,0:01:00.00,0:01:06.00,Default,,0,0,0,,That's where, we've found\Nthis boy. +Dialogue: 0,0:01:06.00,0:01:10.00,Default,,0,0,0,,Oh my, my this here\NAnakin guy, +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. +Dialogue: 0,0:01:15.00,0:01:19.00,Default,,0,0,0,,And he left his home and\Nkissed his mommy goodbye, +Dialogue: 0,0:01:19.00,0:01:24.00,Default,,0,0,0,,singing "Soon I'm gonna be\Na Jedi!" +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, +Dialogue: 0,0:01:36.00,0:01:39.00,Default,,0,0,0,,but he can use the Force,\Nthey say. +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 +Dialogue: 0,0:01:46.00,0:01:52.00,Default,,0,0,0,,yeah, he's probably gonna\Nmarry her, someday! diff --git a/ffmpeg/tests/ref/fate/sub-mpsub-frames b/ffmpeg/tests/ref/fate/sub-mpsub-frames index f78edd0..64528ec 100644 --- a/ffmpeg/tests/ref/fate/sub-mpsub-frames +++ b/ffmpeg/tests/ref/fate/sub-mpsub-frames @@ -1 +1,14 @@ -792dab5d9a471e0381e18b705fc408cc +[Script Info] +; Script generated by FFmpeg/Lavc +ScriptType: v4.00+ +PlayResX: 384 +PlayResY: 288 + +[V4+ Styles] +Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding +Style: Default,Arial,16,&Hffffff,&Hffffff,&H0,&H0,0,0,0,0,100,100,0,0,1,1,0,2,10,10,10,0 + +[Events] +Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text +Dialogue: 0,0:00:01.00,0:00:02.48,Default,,0,0,0,,Start at 1sec,\Nlast 1.5 seconds +Dialogue: 0,0:00:02.52,0:00:11.52,Default,,0,0,0,,One frame later,\Nduring 9 seconds diff --git a/ffmpeg/tests/ref/fate/sub-pjs b/ffmpeg/tests/ref/fate/sub-pjs index 3535039..799c62b 100644 --- a/ffmpeg/tests/ref/fate/sub-pjs +++ b/ffmpeg/tests/ref/fate/sub-pjs @@ -1 +1,15 @@ -a335eefaf09b3b148e65c757bf41af4d +[Script Info] +; Script generated by FFmpeg/Lavc +ScriptType: v4.00+ +PlayResX: 384 +PlayResY: 288 + +[V4+ Styles] +Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding +Style: Default,Arial,16,&Hffffff,&Hffffff,&H0,&H0,0,0,0,0,100,100,0,0,1,1,0,2,10,10,10,0 + +[Events] +Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text +Dialogue: 0,0:04:04.70,0:04:11.30,Default,,0,0,0,,You should come to the Drama Club, too. +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. +Dialogue: 0,0:04:20.30,0:04:27.50,Default,,0,0,0,,I see. Sorry, I'll drop by next time. diff --git a/ffmpeg/tests/ref/fate/sub-realtext b/ffmpeg/tests/ref/fate/sub-realtext index 4dc5753..cd9aa5a 100644 --- a/ffmpeg/tests/ref/fate/sub-realtext +++ b/ffmpeg/tests/ref/fate/sub-realtext @@ -1 +1,17 @@ -a36977a149ce60eac443e4c9bb329ca2 +[Script Info] +; Script generated by FFmpeg/Lavc +ScriptType: v4.00+ +PlayResX: 384 +PlayResY: 288 + +[V4+ Styles] +Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding +Style: Default,Arial,16,&Hffffff,&Hffffff,&H0,&H0,0,0,0,0,100,100,0,0,1,1,0,2,10,10,10,0 + +[Events] +Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text +Dialogue: 0,0:00:00.00,0:00:00.00,Default,,0,0,0,,Mary had a little lamb, \N +Dialogue: 0,0:00:03.00,0:00:18.00,Default,,0,0,0,,little lamb, \N +Dialogue: 0,0:00:06.99,0:00:21.99,Default,,0,0,0,,little lamb, \N +Dialogue: 0,0:00:09.00,0:00:23.00,Default,,0,0,0,,Mary had a little lamb \N +Dialogue: 0,0:00:12.34,0:00:27.34,Default,,0,0,0,,whose fleece was white as snow. diff --git a/ffmpeg/tests/ref/fate/sub-sami b/ffmpeg/tests/ref/fate/sub-sami index 0f5dc6d..caa85a2 100644 --- a/ffmpeg/tests/ref/fate/sub-sami +++ b/ffmpeg/tests/ref/fate/sub-sami @@ -1 +1,21 @@ -04098faede85ddacb40aa12c798cc0cc +[Script Info] +; Script generated by FFmpeg/Lavc +ScriptType: v4.00+ +PlayResX: 384 +PlayResY: 288 + +[V4+ Styles] +Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding +Style: Default,Arial,16,&Hffffff,&Hffffff,&H0,&H0,0,0,0,0,100,100,0,0,1,1,0,2,10,10,10,0 + +[Events] +Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text +Dialogue: 0,0:00:00.00,0:00:00.01,Default,,0,0,0,,{\i1}Pres. John F. Kennedy {\i0}\N +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 +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, +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 +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 +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. +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, +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. +Dialogue: 0,0:01:13.00,9:59:59.99,Default,,0,0,0,,{\i1}End of: {\i0}\NPresident John F. Kennedy Speech diff --git a/ffmpeg/tests/ref/fate/sub-srt b/ffmpeg/tests/ref/fate/sub-srt index c5044e3..4439857 100644 --- a/ffmpeg/tests/ref/fate/sub-srt +++ b/ffmpeg/tests/ref/fate/sub-srt @@ -1 +1,49 @@ -be870f5037933b6890d56e614ec4aa75 +[Script Info] +; Script generated by FFmpeg/Lavc +ScriptType: v4.00+ +PlayResX: 384 +PlayResY: 288 + +[V4+ Styles] +Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding +Style: Default,Arial,16,&Hffffff,&Hffffff,&H0,&H0,0,0,0,0,100,100,0,0,1,1,0,2,10,10,10,0 + +[Events] +Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text +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 +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} +Dialogue: 0,0:00:04.50,0:00:04.50,Default,,0,0,0,,Hidden +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} +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} +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} +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\Nbut show un-closed invalid html tags\NShow not opened tags\N< +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\Nbut 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 +Dialogue: 0,0:00:20.50,0:00:21.50,Default,,0,0,0,,This text should be in the normal position... +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 +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 +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 +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 +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} +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) +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 +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 +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 +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 +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} +Dialogue: 0,0:00:31.50,0:00:50.50,Default,,0,0,0,,First text +Dialogue: 0,0:00:33.50,0:00:35.50,Default,,0,0,0,,Second, it shouldn't overlap first +Dialogue: 0,0:00:35.50,0:00:37.50,Default,,0,0,0,,Third, it should replace second +Dialogue: 0,0:00:36.50,0:00:50.50,Default,,0,0,0,,Fourth, it shouldn't overlap first and third +Dialogue: 0,0:00:40.50,0:00:45.50,Default,,0,0,0,,Fifth, it should replace third +Dialogue: 0,0:00:45.50,0:00:50.50,Default,,0,0,0,,Sixth, it shouldn't be\Nshowed overlapped +Dialogue: 0,0:00:50.50,0:00:52.50,Default,,0,0,0,,TEXT 1 (bottom) +Dialogue: 0,0:00:50.50,0:00:52.50,Default,,0,0,0,,text 2 +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} +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 +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) +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: \-) +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 +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. +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.\NNot opened tag showed as text. +Dialogue: 0,0:01:04.50,0:01:06.50,Default,,0,0,0,,{\s1}Three lines should be strikethrough,\Nyes.\NNot closed tags showed as text +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 diff --git a/ffmpeg/tests/ref/fate/sub-stl b/ffmpeg/tests/ref/fate/sub-stl new file mode 100644 index 0000000..cde33cd --- /dev/null +++ b/ffmpeg/tests/ref/fate/sub-stl @@ -0,0 +1,29 @@ +[Script Info] +; Script generated by FFmpeg/Lavc +ScriptType: v4.00+ +PlayResX: 384 +PlayResY: 288 + +[V4+ Styles] +Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding +Style: Default,Arial,16,&Hffffff,&Hffffff,&H0,&H0,0,0,0,0,100,100,0,0,1,1,0,2,10,10,10,0 + +[Events] +Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text +Dialogue: 0,0:00:31.02,0:00:33.00,Default,,0,0,0,,Hello, my name is Axel Kornmesser. +Dialogue: 0,0:00:45.02,0:00:49.13,Default,,0,0,0,,It is always a pleasure to work with ESA astronomers. +Dialogue: 0,0:00:49.13,0:00:52.03,Default,,0,0,0,,The "Eyes on The Skies" documentary +Dialogue: 0,0:00:52.03,0:00:55.09,Default,,0,0,0,,was our second collaboration +Dialogue: 0,0:00:55.09,0:00:58.07,Default,,0,0,0,,after a great \Nexperience in 2005, +Dialogue: 0,0:00:58.07,0:00:59.20,Default,,0,0,0,,when \Nwe did the story about the +Dialogue: 0,0:00:59.20,0:01:04.01,Default,,0,0,0,,Hubble Telescope "15 Years of Discovery". +Dialogue: 0,0:01:04.16,0:01:07.04,Default,,0,0,0,,It was a lot of fun again. +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 +Dialogue: 0,0:01:18.21,0:01:22.02,Default,,0,0,0,,We had a script and many details about the story, +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 +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 +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. +Dialogue: 0,0:02:08.13,0:02:10.23,Default,,0,0,0,,Galileo's theme is one of my favourites. +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. +Dialogue: 0,0:02:14.10,0:02:18.02,Default,,0,0,0,,For the 17th century \N we used a nice harpsichord +Dialogue: 0,0:02:19.05,0:02:22.09,Default,,0,0,0,,and so we landed directly into Galileo's time. diff --git a/ffmpeg/tests/ref/fate/sub-subripenc b/ffmpeg/tests/ref/fate/sub-subripenc index 9666e9b..1f1e031 100644 --- a/ffmpeg/tests/ref/fate/sub-subripenc +++ b/ffmpeg/tests/ref/fate/sub-subripenc @@ -1 +1,14 @@ -b7cb0eeb34af0da364e29b238f0634ae +1 +00:00:00,970 --> 00:00:02,540 +- Test 1. +- Test 2. + +2 +00:00:03,050 --> 00:00:04,740 +Test 3. + +3 +00:00:05,850 --> 00:00:08,140 +- Test 4. +- Test 5. + diff --git a/ffmpeg/tests/ref/fate/sub-subviewer b/ffmpeg/tests/ref/fate/sub-subviewer index a083868..19944f6 100644 --- a/ffmpeg/tests/ref/fate/sub-subviewer +++ b/ffmpeg/tests/ref/fate/sub-subviewer @@ -1 +1,15 @@ -848f774195e873ce71febf35b6c9c541 +[Script Info] +; Script generated by FFmpeg/Lavc +ScriptType: v4.00+ +PlayResX: 384 +PlayResY: 288 + +[V4+ Styles] +Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding +Style: Default,Arial,16,&Hffffff,&Hffffff,&H0,&H0,0,0,0,0,100,100,0,0,1,1,0,2,10,10,10,0 + +[Events] +Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text +Dialogue: 0,0:01:00.10,0:02:00.20,Default,,0,0,0,,Hello.\NWorld! +Dialogue: 0,0:02:00.30,0:03:00.40,Default,,0,0,0,,\Nfoo\Nbar\Nbla\Nmixed with br +Dialogue: 0,0:03:04.12,0:03:10.20,Default,,0,0,0,,Another event. diff --git a/ffmpeg/tests/ref/fate/sub-subviewer1 b/ffmpeg/tests/ref/fate/sub-subviewer1 index 7d2ca53..a75406b 100644 --- a/ffmpeg/tests/ref/fate/sub-subviewer1 +++ b/ffmpeg/tests/ref/fate/sub-subviewer1 @@ -1 +1,22 @@ -040d7880a6621b1661f9d12c5375037f +[Script Info] +; Script generated by FFmpeg/Lavc +ScriptType: v4.00+ +PlayResX: 384 +PlayResY: 288 + +[V4+ Styles] +Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding +Style: Default,Arial,16,&Hffffff,&Hffffff,&H0,&H0,0,0,0,0,100,100,0,0,1,1,0,2,10,10,10,0 + +[Events] +Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text +Dialogue: 0,0:03:45.00,0:03:48.00,Default,,0,0,0,,- ToIerábiIis?\N- Azt jeIenti: tűrhető. +Dialogue: 0,0:03:48.00,0:03:51.00,Default,,0,0,0,,Tudom, mit jeIent. Megnézhetem? +Dialogue: 0,0:03:52.00,0:03:54.00,Default,,0,0,0,,TiszteIt bírónő. +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. +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. +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. +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. +Dialogue: 0,1:50:38.00,1:50:41.00,Default,,0,0,0,,készen áIIok. +Dialogue: 0,1:51:00.00,1:51:03.00,Default,,0,0,0,,Joe ... Miguel keres. +Dialogue: 0,2:00:18.00,9:59:59.99,Default,,0,0,0,,Magyar szöveg: Nikowvitz Oszkár diff --git a/ffmpeg/tests/ref/fate/sub-vplayer b/ffmpeg/tests/ref/fate/sub-vplayer index 70ba787..6e804f6 100644 --- a/ffmpeg/tests/ref/fate/sub-vplayer +++ b/ffmpeg/tests/ref/fate/sub-vplayer @@ -1 +1,15 @@ -0bb5d4f72b6dc1b37d2ee7b5579ed87e +[Script Info] +; Script generated by FFmpeg/Lavc +ScriptType: v4.00+ +PlayResX: 384 +PlayResY: 288 + +[V4+ Styles] +Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding +Style: Default,Arial,16,&Hffffff,&Hffffff,&H0,&H0,0,0,0,0,100,100,0,0,1,1,0,2,10,10,10,0 + +[Events] +Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text +Dialogue: 0,0:00:00.12,0:00:23.51,Default,,0,0,0,,Hello +Dialogue: 0,0:00:23.51,0:01:02.05,Default,,0,0,0,,World +Dialogue: 0,0:01:02.05,9:59:59.99,Default,,0,0,0,,!\Nnewline diff --git a/ffmpeg/tests/ref/fate/sub-webvtt b/ffmpeg/tests/ref/fate/sub-webvtt index 528e55c..8c63a90 100644 --- a/ffmpeg/tests/ref/fate/sub-webvtt +++ b/ffmpeg/tests/ref/fate/sub-webvtt @@ -1 +1,27 @@ -ee266bd7141df4ea11a9447ab038bb6e +[Script Info] +; Script generated by FFmpeg/Lavc +ScriptType: v4.00+ +PlayResX: 384 +PlayResY: 288 + +[V4+ Styles] +Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding +Style: Default,Arial,16,&Hffffff,&Hffffff,&H0,&H0,0,0,0,0,100,100,0,0,1,1,0,2,10,10,10,0 + +[Events] +Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text +Dialogue: 0,0:00:11.00,0:00:13.00,Default,,0,0,0,,We are in New York City\NRandom line added +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 +Dialogue: 0,0:00:16.00,0:00:18.00,Default,,0,0,0,,from the American Museum of Natural History +Dialogue: 0,0:00:18.00,0:00:20.00,Default,,0,0,0,,And with me is Neil deGrasse Tyson +Dialogue: 0,0:00:20.00,0:00:22.00,Default,,0,0,0,,Astrophysicist, Director of the Hayden Planetarium +Dialogue: 0,0:00:22.00,0:00:24.00,Default,,0,0,0,,at the AMNH. +Dialogue: 0,0:00:24.00,0:00:26.00,Default,,0,0,0,,Thank you for walking down here. +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 +Dialogue: 0,0:00:30.00,0:00:31.50,Default,,0,0,0,,When we e-mailed— +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\} +Dialogue: 0,0:00:32.00,0:00:35.50,Default,,0,0,0,,No! No no no no; 'cos 'cos obviously 'cos +Dialogue: 0,0:00:32.50,0:00:33.50,Default,,0,0,0,,{\i1}Laughs{\i0} +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. +Dialogue: 0,0:00:50.00,0:00:51.13,Default,,0,0,0,,This event and the following\None have CLRF +Dialogue: 0,0:59:00.12,1:23:45.68,Default,,0,0,0,,Obiwan Kenobi diff --git a/ffmpeg/tests/ref/fate/sub-webvttenc b/ffmpeg/tests/ref/fate/sub-webvttenc index 3fe6669..dbeadb0 100644 --- a/ffmpeg/tests/ref/fate/sub-webvttenc +++ b/ffmpeg/tests/ref/fate/sub-webvttenc @@ -1 +1,177 @@ -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 +Use VLC 1.1 or higher as reference for most things and MPC Home Cinema for others +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: È +日本語 +This text should be bold, italics and underline +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 +This line should be bold +This line should be italics +This line should be underline +This line should be strikethrough +Both lines +should be underline + +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 +but show un-closed invalid html tags +Show not opened tags +< + +00:17.501 --> 00:20.501 +and also +hide invalid html tags with parameters that are closed and show the text in them +but show un-closed invalid html tags +This text should be showed underlined without problems also: 2<3,5>1,4<6 +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. +Not opened tag showed as text. + +01:04.501 --> 01:06.501 +Three lines should be strikethrough, +yes. +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 diff --git a/ffmpeg/tests/ref/fate/vc1_ilaced_twomv b/ffmpeg/tests/ref/fate/vc1_ilaced_twomv new file mode 100644 index 0000000..1b4d55f --- /dev/null +++ b/ffmpeg/tests/ref/fate/vc1_ilaced_twomv @@ -0,0 +1,14 @@ +#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 diff --git a/ffmpeg/tests/ref/fate/vcr2 b/ffmpeg/tests/ref/fate/vcr2 index 521e55f..f7e1540 100644 --- a/ffmpeg/tests/ref/fate/vcr2 +++ b/ffmpeg/tests/ref/fate/vcr2 @@ -1,4 +1,4 @@ -#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 diff --git a/ffmpeg/tests/ref/fate/vp9-trac3849 b/ffmpeg/tests/ref/fate/vp9-trac3849 new file mode 100644 index 0000000..4d129b3 --- /dev/null +++ b/ffmpeg/tests/ref/fate/vp9-trac3849 @@ -0,0 +1,15 @@ +#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 diff --git a/ffmpeg/tests/ref/fate/webm-dash-manifest b/ffmpeg/tests/ref/fate/webm-dash-manifest index 1c1a679..f5fc912 100644 --- a/ffmpeg/tests/ref/fate/webm-dash-manifest +++ b/ffmpeg/tests/ref/fate/webm-dash-manifest @@ -20,14 +20,14 @@ dash_video2.webm + indexRange="1115782-1115879"> - + dash_audio1.webm @@ -35,10 +35,10 @@ range="0-4103" /> - + dash_audio2.webm + indexRange="335312-335425"> diff --git a/ffmpeg/tests/ref/fate/webm-dash-manifest-representations b/ffmpeg/tests/ref/fate/webm-dash-manifest-representations new file mode 100644 index 0000000..8556ece --- /dev/null +++ b/ffmpeg/tests/ref/fate/webm-dash-manifest-representations @@ -0,0 +1,30 @@ + + + + + +dash_video1.webm + + + + + +dash_video4.webm + + + + + + + diff --git a/ffmpeg/tests/ref/fate/webm-dash-manifest-unaligned-audio-streams b/ffmpeg/tests/ref/fate/webm-dash-manifest-unaligned-audio-streams index 5e1743e..6e9de21 100644 --- a/ffmpeg/tests/ref/fate/webm-dash-manifest-unaligned-audio-streams +++ b/ffmpeg/tests/ref/fate/webm-dash-manifest-unaligned-audio-streams @@ -20,7 +20,7 @@ dash_audio3.webm + indexRange="335312-335425"> diff --git a/ffmpeg/tests/ref/fate/webm-dash-manifest-unaligned-video-streams b/ffmpeg/tests/ref/fate/webm-dash-manifest-unaligned-video-streams index 3576b60..ce20563 100644 --- a/ffmpeg/tests/ref/fate/webm-dash-manifest-unaligned-video-streams +++ b/ffmpeg/tests/ref/fate/webm-dash-manifest-unaligned-video-streams @@ -20,7 +20,7 @@ dash_video3.webm + indexRange="1116070-1116455"> diff --git a/ffmpeg/tests/ref/lavf-fate/mp3 b/ffmpeg/tests/ref/lavf-fate/mp3 index ec66652..b559538 100644 --- a/ffmpeg/tests/ref/lavf-fate/mp3 +++ b/ffmpeg/tests/ref/lavf-fate/mp3 @@ -1,3 +1,3 @@ -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 diff --git a/ffmpeg/tests/ref/lavf/dv_fmt b/ffmpeg/tests/ref/lavf/dv_fmt index 3c8e5b1..b152c84 100644 --- a/ffmpeg/tests/ref/lavf/dv_fmt +++ b/ffmpeg/tests/ref/lavf/dv_fmt @@ -1,9 +1,9 @@ 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 diff --git a/ffmpeg/tests/ref/lavf/ffm b/ffmpeg/tests/ref/lavf/ffm index c11350a..5de2f39 100644 --- a/ffmpeg/tests/ref/lavf/ffm +++ b/ffmpeg/tests/ref/lavf/ffm @@ -1,3 +1,3 @@ -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 diff --git a/ffmpeg/tests/ref/lavf/ismv b/ffmpeg/tests/ref/lavf/ismv index 2c8d92c..f29b5ff 100644 --- a/ffmpeg/tests/ref/lavf/ismv +++ b/ffmpeg/tests/ref/lavf/ismv @@ -1,9 +1,9 @@ -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 diff --git a/ffmpeg/tests/ref/lavf/mxf b/ffmpeg/tests/ref/lavf/mxf index 27991ff..236661c 100644 --- a/ffmpeg/tests/ref/lavf/mxf +++ b/ffmpeg/tests/ref/lavf/mxf @@ -1,9 +1,9 @@ -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 diff --git a/ffmpeg/tests/ref/lavf/mxf_d10 b/ffmpeg/tests/ref/lavf/mxf_d10 index 98c2f6f..ff7d876 100644 --- a/ffmpeg/tests/ref/lavf/mxf_d10 +++ b/ffmpeg/tests/ref/lavf/mxf_d10 @@ -1,3 +1,3 @@ -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 diff --git a/ffmpeg/tests/ref/seek/vsynth2-asv1 b/ffmpeg/tests/ref/seek/vsynth_lena-asv1 similarity index 100% rename from ffmpeg/tests/ref/seek/vsynth2-asv1 rename to ffmpeg/tests/ref/seek/vsynth_lena-asv1 diff --git a/ffmpeg/tests/ref/seek/vsynth2-asv2 b/ffmpeg/tests/ref/seek/vsynth_lena-asv2 similarity index 100% rename from ffmpeg/tests/ref/seek/vsynth2-asv2 rename to ffmpeg/tests/ref/seek/vsynth_lena-asv2 diff --git a/ffmpeg/tests/ref/seek/vsynth2-dnxhd-1080i b/ffmpeg/tests/ref/seek/vsynth_lena-dnxhd-1080i similarity index 100% rename from ffmpeg/tests/ref/seek/vsynth2-dnxhd-1080i rename to ffmpeg/tests/ref/seek/vsynth_lena-dnxhd-1080i diff --git a/ffmpeg/tests/ref/seek/vsynth2-dnxhd-720p b/ffmpeg/tests/ref/seek/vsynth_lena-dnxhd-720p similarity index 100% rename from ffmpeg/tests/ref/seek/vsynth2-dnxhd-720p rename to ffmpeg/tests/ref/seek/vsynth_lena-dnxhd-720p diff --git a/ffmpeg/tests/ref/seek/vsynth2-dnxhd-720p-rd b/ffmpeg/tests/ref/seek/vsynth_lena-dnxhd-720p-rd similarity index 100% rename from ffmpeg/tests/ref/seek/vsynth2-dnxhd-720p-rd rename to ffmpeg/tests/ref/seek/vsynth_lena-dnxhd-720p-rd diff --git a/ffmpeg/tests/ref/seek/vsynth2-dv b/ffmpeg/tests/ref/seek/vsynth_lena-dv similarity index 100% rename from ffmpeg/tests/ref/seek/vsynth2-dv rename to ffmpeg/tests/ref/seek/vsynth_lena-dv diff --git a/ffmpeg/tests/ref/seek/vsynth2-dv-411 b/ffmpeg/tests/ref/seek/vsynth_lena-dv-411 similarity index 100% rename from ffmpeg/tests/ref/seek/vsynth2-dv-411 rename to ffmpeg/tests/ref/seek/vsynth_lena-dv-411 diff --git a/ffmpeg/tests/ref/seek/vsynth2-dv-50 b/ffmpeg/tests/ref/seek/vsynth_lena-dv-50 similarity index 100% rename from ffmpeg/tests/ref/seek/vsynth2-dv-50 rename to ffmpeg/tests/ref/seek/vsynth_lena-dv-50 diff --git a/ffmpeg/tests/ref/seek/vsynth2-ffv1 b/ffmpeg/tests/ref/seek/vsynth_lena-ffv1 similarity index 100% rename from ffmpeg/tests/ref/seek/vsynth2-ffv1 rename to ffmpeg/tests/ref/seek/vsynth_lena-ffv1 diff --git a/ffmpeg/tests/ref/seek/vsynth2-flashsv b/ffmpeg/tests/ref/seek/vsynth_lena-flashsv similarity index 100% rename from ffmpeg/tests/ref/seek/vsynth2-flashsv rename to ffmpeg/tests/ref/seek/vsynth_lena-flashsv diff --git a/ffmpeg/tests/ref/seek/vsynth2-flv b/ffmpeg/tests/ref/seek/vsynth_lena-flv similarity index 100% rename from ffmpeg/tests/ref/seek/vsynth2-flv rename to ffmpeg/tests/ref/seek/vsynth_lena-flv diff --git a/ffmpeg/tests/ref/seek/vsynth2-h261 b/ffmpeg/tests/ref/seek/vsynth_lena-h261 similarity index 100% rename from ffmpeg/tests/ref/seek/vsynth2-h261 rename to ffmpeg/tests/ref/seek/vsynth_lena-h261 diff --git a/ffmpeg/tests/ref/seek/vsynth2-h263 b/ffmpeg/tests/ref/seek/vsynth_lena-h263 similarity index 100% rename from ffmpeg/tests/ref/seek/vsynth2-h263 rename to ffmpeg/tests/ref/seek/vsynth_lena-h263 diff --git a/ffmpeg/tests/ref/seek/vsynth2-h263p b/ffmpeg/tests/ref/seek/vsynth_lena-h263p similarity index 100% rename from ffmpeg/tests/ref/seek/vsynth2-h263p rename to ffmpeg/tests/ref/seek/vsynth_lena-h263p diff --git a/ffmpeg/tests/ref/seek/vsynth2-huffyuv b/ffmpeg/tests/ref/seek/vsynth_lena-huffyuv similarity index 100% rename from ffmpeg/tests/ref/seek/vsynth2-huffyuv rename to ffmpeg/tests/ref/seek/vsynth_lena-huffyuv diff --git a/ffmpeg/tests/ref/seek/vsynth2-jpegls b/ffmpeg/tests/ref/seek/vsynth_lena-jpegls similarity index 100% rename from ffmpeg/tests/ref/seek/vsynth2-jpegls rename to ffmpeg/tests/ref/seek/vsynth_lena-jpegls diff --git a/ffmpeg/tests/ref/seek/vsynth2-ljpeg b/ffmpeg/tests/ref/seek/vsynth_lena-ljpeg similarity index 100% rename from ffmpeg/tests/ref/seek/vsynth2-ljpeg rename to ffmpeg/tests/ref/seek/vsynth_lena-ljpeg diff --git a/ffmpeg/tests/ref/seek/vsynth2-mjpeg b/ffmpeg/tests/ref/seek/vsynth_lena-mjpeg similarity index 100% rename from ffmpeg/tests/ref/seek/vsynth2-mjpeg rename to ffmpeg/tests/ref/seek/vsynth_lena-mjpeg diff --git a/ffmpeg/tests/ref/seek/vsynth2-mpeg1 b/ffmpeg/tests/ref/seek/vsynth_lena-mpeg1 similarity index 100% rename from ffmpeg/tests/ref/seek/vsynth2-mpeg1 rename to ffmpeg/tests/ref/seek/vsynth_lena-mpeg1 diff --git a/ffmpeg/tests/ref/seek/vsynth2-mpeg1b b/ffmpeg/tests/ref/seek/vsynth_lena-mpeg1b similarity index 100% rename from ffmpeg/tests/ref/seek/vsynth2-mpeg1b rename to ffmpeg/tests/ref/seek/vsynth_lena-mpeg1b diff --git a/ffmpeg/tests/ref/seek/vsynth2-mpeg2-422 b/ffmpeg/tests/ref/seek/vsynth_lena-mpeg2-422 similarity index 100% rename from ffmpeg/tests/ref/seek/vsynth2-mpeg2-422 rename to ffmpeg/tests/ref/seek/vsynth_lena-mpeg2-422 diff --git a/ffmpeg/tests/ref/seek/vsynth2-mpeg2-idct-int b/ffmpeg/tests/ref/seek/vsynth_lena-mpeg2-idct-int similarity index 100% rename from ffmpeg/tests/ref/seek/vsynth2-mpeg2-idct-int rename to ffmpeg/tests/ref/seek/vsynth_lena-mpeg2-idct-int diff --git a/ffmpeg/tests/ref/seek/vsynth2-mpeg2-ilace b/ffmpeg/tests/ref/seek/vsynth_lena-mpeg2-ilace similarity index 100% rename from ffmpeg/tests/ref/seek/vsynth2-mpeg2-ilace rename to ffmpeg/tests/ref/seek/vsynth_lena-mpeg2-ilace diff --git a/ffmpeg/tests/ref/seek/vsynth2-mpeg2-ivlc-qprd b/ffmpeg/tests/ref/seek/vsynth_lena-mpeg2-ivlc-qprd similarity index 100% rename from ffmpeg/tests/ref/seek/vsynth2-mpeg2-ivlc-qprd rename to ffmpeg/tests/ref/seek/vsynth_lena-mpeg2-ivlc-qprd diff --git a/ffmpeg/tests/ref/seek/vsynth2-mpeg2-thread b/ffmpeg/tests/ref/seek/vsynth_lena-mpeg2-thread similarity index 100% rename from ffmpeg/tests/ref/seek/vsynth2-mpeg2-thread rename to ffmpeg/tests/ref/seek/vsynth_lena-mpeg2-thread diff --git a/ffmpeg/tests/ref/seek/vsynth2-mpeg2-thread-ivlc b/ffmpeg/tests/ref/seek/vsynth_lena-mpeg2-thread-ivlc similarity index 100% rename from ffmpeg/tests/ref/seek/vsynth2-mpeg2-thread-ivlc rename to ffmpeg/tests/ref/seek/vsynth_lena-mpeg2-thread-ivlc diff --git a/ffmpeg/tests/ref/seek/vsynth2-mpeg4 b/ffmpeg/tests/ref/seek/vsynth_lena-mpeg4 similarity index 100% rename from ffmpeg/tests/ref/seek/vsynth2-mpeg4 rename to ffmpeg/tests/ref/seek/vsynth_lena-mpeg4 diff --git a/ffmpeg/tests/ref/seek/vsynth2-mpeg4-adap b/ffmpeg/tests/ref/seek/vsynth_lena-mpeg4-adap similarity index 100% rename from ffmpeg/tests/ref/seek/vsynth2-mpeg4-adap rename to ffmpeg/tests/ref/seek/vsynth_lena-mpeg4-adap diff --git a/ffmpeg/tests/ref/seek/vsynth2-mpeg4-adv b/ffmpeg/tests/ref/seek/vsynth_lena-mpeg4-adv similarity index 100% rename from ffmpeg/tests/ref/seek/vsynth2-mpeg4-adv rename to ffmpeg/tests/ref/seek/vsynth_lena-mpeg4-adv diff --git a/ffmpeg/tests/ref/seek/vsynth2-mpeg4-error b/ffmpeg/tests/ref/seek/vsynth_lena-mpeg4-error similarity index 100% rename from ffmpeg/tests/ref/seek/vsynth2-mpeg4-error rename to ffmpeg/tests/ref/seek/vsynth_lena-mpeg4-error diff --git a/ffmpeg/tests/ref/seek/vsynth2-mpeg4-nr b/ffmpeg/tests/ref/seek/vsynth_lena-mpeg4-nr similarity index 100% rename from ffmpeg/tests/ref/seek/vsynth2-mpeg4-nr rename to ffmpeg/tests/ref/seek/vsynth_lena-mpeg4-nr diff --git a/ffmpeg/tests/ref/seek/vsynth2-mpeg4-nsse b/ffmpeg/tests/ref/seek/vsynth_lena-mpeg4-nsse similarity index 100% rename from ffmpeg/tests/ref/seek/vsynth2-mpeg4-nsse rename to ffmpeg/tests/ref/seek/vsynth_lena-mpeg4-nsse diff --git a/ffmpeg/tests/ref/seek/vsynth2-mpeg4-qpel b/ffmpeg/tests/ref/seek/vsynth_lena-mpeg4-qpel similarity index 100% rename from ffmpeg/tests/ref/seek/vsynth2-mpeg4-qpel rename to ffmpeg/tests/ref/seek/vsynth_lena-mpeg4-qpel diff --git a/ffmpeg/tests/ref/seek/vsynth2-mpeg4-qprd b/ffmpeg/tests/ref/seek/vsynth_lena-mpeg4-qprd similarity index 100% rename from ffmpeg/tests/ref/seek/vsynth2-mpeg4-qprd rename to ffmpeg/tests/ref/seek/vsynth_lena-mpeg4-qprd diff --git a/ffmpeg/tests/ref/seek/vsynth2-mpeg4-rc b/ffmpeg/tests/ref/seek/vsynth_lena-mpeg4-rc similarity index 100% rename from ffmpeg/tests/ref/seek/vsynth2-mpeg4-rc rename to ffmpeg/tests/ref/seek/vsynth_lena-mpeg4-rc diff --git a/ffmpeg/tests/ref/seek/vsynth2-mpeg4-thread b/ffmpeg/tests/ref/seek/vsynth_lena-mpeg4-thread similarity index 100% rename from ffmpeg/tests/ref/seek/vsynth2-mpeg4-thread rename to ffmpeg/tests/ref/seek/vsynth_lena-mpeg4-thread diff --git a/ffmpeg/tests/ref/seek/vsynth2-msmpeg4 b/ffmpeg/tests/ref/seek/vsynth_lena-msmpeg4 similarity index 100% rename from ffmpeg/tests/ref/seek/vsynth2-msmpeg4 rename to ffmpeg/tests/ref/seek/vsynth_lena-msmpeg4 diff --git a/ffmpeg/tests/ref/seek/vsynth2-msmpeg4v2 b/ffmpeg/tests/ref/seek/vsynth_lena-msmpeg4v2 similarity index 100% rename from ffmpeg/tests/ref/seek/vsynth2-msmpeg4v2 rename to ffmpeg/tests/ref/seek/vsynth_lena-msmpeg4v2 diff --git a/ffmpeg/tests/ref/seek/vsynth2-rgb b/ffmpeg/tests/ref/seek/vsynth_lena-rgb similarity index 100% rename from ffmpeg/tests/ref/seek/vsynth2-rgb rename to ffmpeg/tests/ref/seek/vsynth_lena-rgb diff --git a/ffmpeg/tests/ref/seek/vsynth2-roqvideo b/ffmpeg/tests/ref/seek/vsynth_lena-roqvideo similarity index 100% rename from ffmpeg/tests/ref/seek/vsynth2-roqvideo rename to ffmpeg/tests/ref/seek/vsynth_lena-roqvideo diff --git a/ffmpeg/tests/ref/seek/vsynth2-rv10 b/ffmpeg/tests/ref/seek/vsynth_lena-rv10 similarity index 100% rename from ffmpeg/tests/ref/seek/vsynth2-rv10 rename to ffmpeg/tests/ref/seek/vsynth_lena-rv10 diff --git a/ffmpeg/tests/ref/seek/vsynth2-rv20 b/ffmpeg/tests/ref/seek/vsynth_lena-rv20 similarity index 100% rename from ffmpeg/tests/ref/seek/vsynth2-rv20 rename to ffmpeg/tests/ref/seek/vsynth_lena-rv20 diff --git a/ffmpeg/tests/ref/seek/vsynth2-snow b/ffmpeg/tests/ref/seek/vsynth_lena-snow similarity index 100% rename from ffmpeg/tests/ref/seek/vsynth2-snow rename to ffmpeg/tests/ref/seek/vsynth_lena-snow diff --git a/ffmpeg/tests/ref/seek/vsynth2-snow-ll b/ffmpeg/tests/ref/seek/vsynth_lena-snow-ll similarity index 100% rename from ffmpeg/tests/ref/seek/vsynth2-snow-ll rename to ffmpeg/tests/ref/seek/vsynth_lena-snow-ll diff --git a/ffmpeg/tests/ref/seek/vsynth2-svq1 b/ffmpeg/tests/ref/seek/vsynth_lena-svq1 similarity index 100% rename from ffmpeg/tests/ref/seek/vsynth2-svq1 rename to ffmpeg/tests/ref/seek/vsynth_lena-svq1 diff --git a/ffmpeg/tests/ref/seek/vsynth2-wmv1 b/ffmpeg/tests/ref/seek/vsynth_lena-wmv1 similarity index 100% rename from ffmpeg/tests/ref/seek/vsynth2-wmv1 rename to ffmpeg/tests/ref/seek/vsynth_lena-wmv1 diff --git a/ffmpeg/tests/ref/seek/vsynth2-wmv2 b/ffmpeg/tests/ref/seek/vsynth_lena-wmv2 similarity index 100% rename from ffmpeg/tests/ref/seek/vsynth2-wmv2 rename to ffmpeg/tests/ref/seek/vsynth_lena-wmv2 diff --git a/ffmpeg/tests/ref/seek/vsynth2-yuv b/ffmpeg/tests/ref/seek/vsynth_lena-yuv similarity index 100% rename from ffmpeg/tests/ref/seek/vsynth2-yuv rename to ffmpeg/tests/ref/seek/vsynth_lena-yuv diff --git a/ffmpeg/tests/ref/vsynth/vsynth1-dv b/ffmpeg/tests/ref/vsynth/vsynth1-dv index d051e8d..6237b07 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth1-dv +++ b/ffmpeg/tests/ref/vsynth/vsynth1-dv @@ -1,4 +1,4 @@ 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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth1-dv-411 b/ffmpeg/tests/ref/vsynth/vsynth1-dv-411 index bc4b802..48e01a1 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth1-dv-411 +++ b/ffmpeg/tests/ref/vsynth/vsynth1-dv-411 @@ -1,4 +1,4 @@ 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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth1-dv-50 b/ffmpeg/tests/ref/vsynth/vsynth1-dv-50 index e747075..d5da88d 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth1-dv-50 +++ b/ffmpeg/tests/ref/vsynth/vsynth1-dv-50 @@ -1,4 +1,4 @@ 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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth1-v210 b/ffmpeg/tests/ref/vsynth/vsynth1-v210 index dbafe42..0d12afa 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth1-v210 +++ b/ffmpeg/tests/ref/vsynth/vsynth1-v210 @@ -1,4 +1,4 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth1-xface b/ffmpeg/tests/ref/vsynth/vsynth1-xface new file mode 100644 index 0000000..3b916c6 --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth1-xface @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth2-amv b/ffmpeg/tests/ref/vsynth/vsynth2-amv index daa5894..a9b4a0f 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth2-amv +++ b/ffmpeg/tests/ref/vsynth/vsynth2-amv @@ -1,4 +1,4 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth2-asv1 b/ffmpeg/tests/ref/vsynth/vsynth2-asv1 index 7811888..2f20a07 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth2-asv1 +++ b/ffmpeg/tests/ref/vsynth/vsynth2-asv1 @@ -1,4 +1,4 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth2-asv2 b/ffmpeg/tests/ref/vsynth/vsynth2-asv2 index 617a77f..fc07630 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth2-asv2 +++ b/ffmpeg/tests/ref/vsynth/vsynth2-asv2 @@ -1,4 +1,4 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth2-avui b/ffmpeg/tests/ref/vsynth/vsynth2-avui index 7976a36..1500386 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth2-avui +++ b/ffmpeg/tests/ref/vsynth/vsynth2-avui @@ -1,4 +1,4 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth2-cljr b/ffmpeg/tests/ref/vsynth/vsynth2-cljr index 0b61365..7c44804 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth2-cljr +++ b/ffmpeg/tests/ref/vsynth/vsynth2-cljr @@ -1,4 +1,4 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth2-dnxhd-1080i b/ffmpeg/tests/ref/vsynth/vsynth2-dnxhd-1080i index d3cf503..527e6a7 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth2-dnxhd-1080i +++ b/ffmpeg/tests/ref/vsynth/vsynth2-dnxhd-1080i @@ -1,4 +1,4 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth2-dnxhd-720p b/ffmpeg/tests/ref/vsynth/vsynth2-dnxhd-720p index 0a8441b..f40da38 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth2-dnxhd-720p +++ b/ffmpeg/tests/ref/vsynth/vsynth2-dnxhd-720p @@ -1,4 +1,4 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth2-dnxhd-720p-10bit b/ffmpeg/tests/ref/vsynth/vsynth2-dnxhd-720p-10bit index 7a32d8c..c57bf7d 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth2-dnxhd-720p-10bit +++ b/ffmpeg/tests/ref/vsynth/vsynth2-dnxhd-720p-10bit @@ -1,4 +1,4 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth2-dnxhd-720p-rd b/ffmpeg/tests/ref/vsynth/vsynth2-dnxhd-720p-rd index 5387ce5..3d97557 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth2-dnxhd-720p-rd +++ b/ffmpeg/tests/ref/vsynth/vsynth2-dnxhd-720p-rd @@ -1,4 +1,4 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth2-dnxhd_1080i b/ffmpeg/tests/ref/vsynth/vsynth2-dnxhd_1080i deleted file mode 100644 index 81ecc5e..0000000 --- a/ffmpeg/tests/ref/vsynth/vsynth2-dnxhd_1080i +++ /dev/null @@ -1,4 +0,0 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth2-dv b/ffmpeg/tests/ref/vsynth/vsynth2-dv index 0d1465c..bb0602a 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth2-dv +++ b/ffmpeg/tests/ref/vsynth/vsynth2-dv @@ -1,4 +1,4 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth2-dv-411 b/ffmpeg/tests/ref/vsynth/vsynth2-dv-411 index d0e6d29..bdda636 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth2-dv-411 +++ b/ffmpeg/tests/ref/vsynth/vsynth2-dv-411 @@ -1,4 +1,4 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth2-dv-50 b/ffmpeg/tests/ref/vsynth/vsynth2-dv-50 index c5ac608..c21c525 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth2-dv-50 +++ b/ffmpeg/tests/ref/vsynth/vsynth2-dv-50 @@ -1,4 +1,4 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth2-dv_411 b/ffmpeg/tests/ref/vsynth/vsynth2-dv_411 deleted file mode 100644 index 708ac88..0000000 --- a/ffmpeg/tests/ref/vsynth/vsynth2-dv_411 +++ /dev/null @@ -1,4 +0,0 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth2-ffv1 b/ffmpeg/tests/ref/vsynth/vsynth2-ffv1 index d0035e4..eef1115 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth2-ffv1 +++ b/ffmpeg/tests/ref/vsynth/vsynth2-ffv1 @@ -1,4 +1,4 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth2-ffv1.0 b/ffmpeg/tests/ref/vsynth/vsynth2-ffv1.0 index f3877d1..a4f1a81 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth2-ffv1.0 +++ b/ffmpeg/tests/ref/vsynth/vsynth2-ffv1.0 @@ -1,4 +1,4 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth2-ffvhuff b/ffmpeg/tests/ref/vsynth/vsynth2-ffvhuff index 921d5bf..4fe9f86 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth2-ffvhuff +++ b/ffmpeg/tests/ref/vsynth/vsynth2-ffvhuff @@ -1,4 +1,4 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth2-ffvhuff420p12 b/ffmpeg/tests/ref/vsynth/vsynth2-ffvhuff420p12 index 1f1279f..bde1843 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth2-ffvhuff420p12 +++ b/ffmpeg/tests/ref/vsynth/vsynth2-ffvhuff420p12 @@ -1,4 +1,4 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth2-ffvhuff422p10left b/ffmpeg/tests/ref/vsynth/vsynth2-ffvhuff422p10left index bb16978..fb6fb18 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth2-ffvhuff422p10left +++ b/ffmpeg/tests/ref/vsynth/vsynth2-ffvhuff422p10left @@ -1,4 +1,4 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth2-ffvhuff444 b/ffmpeg/tests/ref/vsynth/vsynth2-ffvhuff444 index c4ea9cd..719373d 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth2-ffvhuff444 +++ b/ffmpeg/tests/ref/vsynth/vsynth2-ffvhuff444 @@ -1,4 +1,4 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth2-ffvhuff444p16 b/ffmpeg/tests/ref/vsynth/vsynth2-ffvhuff444p16 index 1f03a03..6308761 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth2-ffvhuff444p16 +++ b/ffmpeg/tests/ref/vsynth/vsynth2-ffvhuff444p16 @@ -1,4 +1,4 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth2-flashsv b/ffmpeg/tests/ref/vsynth/vsynth2-flashsv index e44fa8f..9bda896 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth2-flashsv +++ b/ffmpeg/tests/ref/vsynth/vsynth2-flashsv @@ -1,4 +1,4 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth2-flashsv2 b/ffmpeg/tests/ref/vsynth/vsynth2-flashsv2 index d207a8b..f680954 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth2-flashsv2 +++ b/ffmpeg/tests/ref/vsynth/vsynth2-flashsv2 @@ -1,4 +1,4 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth2-flv b/ffmpeg/tests/ref/vsynth/vsynth2-flv index ab31755..9b2651c 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth2-flv +++ b/ffmpeg/tests/ref/vsynth/vsynth2-flv @@ -1,4 +1,4 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth2-h261 b/ffmpeg/tests/ref/vsynth/vsynth2-h261 index 67a8f0b..afa57b6 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth2-h261 +++ b/ffmpeg/tests/ref/vsynth/vsynth2-h261 @@ -1,4 +1,4 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth2-h261-trellis b/ffmpeg/tests/ref/vsynth/vsynth2-h261-trellis index 8a7cf78..372d7d8 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth2-h261-trellis +++ b/ffmpeg/tests/ref/vsynth/vsynth2-h261-trellis @@ -1,4 +1,4 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth2-h263 b/ffmpeg/tests/ref/vsynth/vsynth2-h263 index 8feabfe..6ab7dc7 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth2-h263 +++ b/ffmpeg/tests/ref/vsynth/vsynth2-h263 @@ -1,4 +1,4 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth2-h263-obmc b/ffmpeg/tests/ref/vsynth/vsynth2-h263-obmc index aa9a60a..997e941 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth2-h263-obmc +++ b/ffmpeg/tests/ref/vsynth/vsynth2-h263-obmc @@ -1,4 +1,4 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth2-h263p b/ffmpeg/tests/ref/vsynth/vsynth2-h263p index 182e096..98b1e41 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth2-h263p +++ b/ffmpeg/tests/ref/vsynth/vsynth2-h263p @@ -1,4 +1,4 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth2-huffyuv b/ffmpeg/tests/ref/vsynth/vsynth2-huffyuv index a2d2ae3..137ac46 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth2-huffyuv +++ b/ffmpeg/tests/ref/vsynth/vsynth2-huffyuv @@ -1,4 +1,4 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth2-huffyuvbgr24 b/ffmpeg/tests/ref/vsynth/vsynth2-huffyuvbgr24 index 939eb2f..eedb564 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth2-huffyuvbgr24 +++ b/ffmpeg/tests/ref/vsynth/vsynth2-huffyuvbgr24 @@ -1,4 +1,4 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth2-huffyuvbgra b/ffmpeg/tests/ref/vsynth/vsynth2-huffyuvbgra index b37b49f..1062473 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth2-huffyuvbgra +++ b/ffmpeg/tests/ref/vsynth/vsynth2-huffyuvbgra @@ -1,4 +1,4 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth2-jpeg2000 b/ffmpeg/tests/ref/vsynth/vsynth2-jpeg2000 index 84e90d4..d1ebf4b 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth2-jpeg2000 +++ b/ffmpeg/tests/ref/vsynth/vsynth2-jpeg2000 @@ -1,4 +1,4 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth2-jpeg2000-97 b/ffmpeg/tests/ref/vsynth/vsynth2-jpeg2000-97 index c053a5d..cfc61eb 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth2-jpeg2000-97 +++ b/ffmpeg/tests/ref/vsynth/vsynth2-jpeg2000-97 @@ -1,4 +1,4 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth2-jpegls b/ffmpeg/tests/ref/vsynth/vsynth2-jpegls index e256dea..47cb5a5 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth2-jpegls +++ b/ffmpeg/tests/ref/vsynth/vsynth2-jpegls @@ -1,4 +1,4 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth2-ljpeg b/ffmpeg/tests/ref/vsynth/vsynth2-ljpeg index b59923e..bd7fbd8 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth2-ljpeg +++ b/ffmpeg/tests/ref/vsynth/vsynth2-ljpeg @@ -1,4 +1,4 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth2-mjpeg b/ffmpeg/tests/ref/vsynth/vsynth2-mjpeg index eaabc73..5e51523 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth2-mjpeg +++ b/ffmpeg/tests/ref/vsynth/vsynth2-mjpeg @@ -1,4 +1,4 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth2-mjpeg-422 b/ffmpeg/tests/ref/vsynth/vsynth2-mjpeg-422 index 61d2997..bc25008 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth2-mjpeg-422 +++ b/ffmpeg/tests/ref/vsynth/vsynth2-mjpeg-422 @@ -1,4 +1,4 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth2-mjpeg-444 b/ffmpeg/tests/ref/vsynth/vsynth2-mjpeg-444 index ae01a35..bfc0e10 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth2-mjpeg-444 +++ b/ffmpeg/tests/ref/vsynth/vsynth2-mjpeg-444 @@ -1,4 +1,4 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth2-mpeg1 b/ffmpeg/tests/ref/vsynth/vsynth2-mpeg1 index 9e3e999..83c18c1 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth2-mpeg1 +++ b/ffmpeg/tests/ref/vsynth/vsynth2-mpeg1 @@ -1,4 +1,4 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth2-mpeg1b b/ffmpeg/tests/ref/vsynth/vsynth2-mpeg1b index c2fb217..5c3f9bc 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth2-mpeg1b +++ b/ffmpeg/tests/ref/vsynth/vsynth2-mpeg1b @@ -1,4 +1,4 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth2-mpeg2 b/ffmpeg/tests/ref/vsynth/vsynth2-mpeg2 index bceb954..869948a 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth2-mpeg2 +++ b/ffmpeg/tests/ref/vsynth/vsynth2-mpeg2 @@ -1,4 +1,4 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth2-mpeg2-422 b/ffmpeg/tests/ref/vsynth/vsynth2-mpeg2-422 index b4a896c..ec7244f 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth2-mpeg2-422 +++ b/ffmpeg/tests/ref/vsynth/vsynth2-mpeg2-422 @@ -1,4 +1,4 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth2-mpeg2-idct-int b/ffmpeg/tests/ref/vsynth/vsynth2-mpeg2-idct-int index 69d5c86..3cbfde9 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth2-mpeg2-idct-int +++ b/ffmpeg/tests/ref/vsynth/vsynth2-mpeg2-idct-int @@ -1,4 +1,4 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth2-mpeg2-ilace b/ffmpeg/tests/ref/vsynth/vsynth2-mpeg2-ilace index 5c37c34..ba9c0f0 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth2-mpeg2-ilace +++ b/ffmpeg/tests/ref/vsynth/vsynth2-mpeg2-ilace @@ -1,4 +1,4 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth2-mpeg2-ivlc-qprd b/ffmpeg/tests/ref/vsynth/vsynth2-mpeg2-ivlc-qprd index dea3f94..16de39e 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth2-mpeg2-ivlc-qprd +++ b/ffmpeg/tests/ref/vsynth/vsynth2-mpeg2-ivlc-qprd @@ -1,4 +1,4 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth2-mpeg2-thread b/ffmpeg/tests/ref/vsynth/vsynth2-mpeg2-thread index 335d1c6..ee9092f 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth2-mpeg2-thread +++ b/ffmpeg/tests/ref/vsynth/vsynth2-mpeg2-thread @@ -1,4 +1,4 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth2-mpeg2-thread-ivlc b/ffmpeg/tests/ref/vsynth/vsynth2-mpeg2-thread-ivlc index 67a380a..4ef6211 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth2-mpeg2-thread-ivlc +++ b/ffmpeg/tests/ref/vsynth/vsynth2-mpeg2-thread-ivlc @@ -1,4 +1,4 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth2-mpeg4 b/ffmpeg/tests/ref/vsynth/vsynth2-mpeg4 index ac5ee39..85899ff 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth2-mpeg4 +++ b/ffmpeg/tests/ref/vsynth/vsynth2-mpeg4 @@ -1,4 +1,4 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth2-mpeg4-adap b/ffmpeg/tests/ref/vsynth/vsynth2-mpeg4-adap index 7a40c4b..67f9904 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth2-mpeg4-adap +++ b/ffmpeg/tests/ref/vsynth/vsynth2-mpeg4-adap @@ -1,4 +1,4 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth2-mpeg4-adv b/ffmpeg/tests/ref/vsynth/vsynth2-mpeg4-adv index c1385ca..664d329 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth2-mpeg4-adv +++ b/ffmpeg/tests/ref/vsynth/vsynth2-mpeg4-adv @@ -1,4 +1,4 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth2-mpeg4-error b/ffmpeg/tests/ref/vsynth/vsynth2-mpeg4-error index a8d93bc..ce7119c 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth2-mpeg4-error +++ b/ffmpeg/tests/ref/vsynth/vsynth2-mpeg4-error @@ -1,4 +1,4 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth2-mpeg4-nr b/ffmpeg/tests/ref/vsynth/vsynth2-mpeg4-nr index 05dcc54..7d88e83 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth2-mpeg4-nr +++ b/ffmpeg/tests/ref/vsynth/vsynth2-mpeg4-nr @@ -1,4 +1,4 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth2-mpeg4-nsse b/ffmpeg/tests/ref/vsynth/vsynth2-mpeg4-nsse index 0833519..c61b603 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth2-mpeg4-nsse +++ b/ffmpeg/tests/ref/vsynth/vsynth2-mpeg4-nsse @@ -1,4 +1,4 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth2-mpeg4-qpel b/ffmpeg/tests/ref/vsynth/vsynth2-mpeg4-qpel index 2822580..4d708b1 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth2-mpeg4-qpel +++ b/ffmpeg/tests/ref/vsynth/vsynth2-mpeg4-qpel @@ -1,4 +1,4 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth2-mpeg4-qprd b/ffmpeg/tests/ref/vsynth/vsynth2-mpeg4-qprd index 287fff2..0acc301 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth2-mpeg4-qprd +++ b/ffmpeg/tests/ref/vsynth/vsynth2-mpeg4-qprd @@ -1,4 +1,4 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth2-mpeg4-rc b/ffmpeg/tests/ref/vsynth/vsynth2-mpeg4-rc index ccf4400..0417bad 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth2-mpeg4-rc +++ b/ffmpeg/tests/ref/vsynth/vsynth2-mpeg4-rc @@ -1,4 +1,4 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth2-mpeg4-thread b/ffmpeg/tests/ref/vsynth/vsynth2-mpeg4-thread index f8475df..0120689 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth2-mpeg4-thread +++ b/ffmpeg/tests/ref/vsynth/vsynth2-mpeg4-thread @@ -1,4 +1,4 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth2-mpng b/ffmpeg/tests/ref/vsynth/vsynth2-mpng index 31fbdcc..cd40fb7 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth2-mpng +++ b/ffmpeg/tests/ref/vsynth/vsynth2-mpng @@ -1,4 +1,4 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth2-msmpeg4 b/ffmpeg/tests/ref/vsynth/vsynth2-msmpeg4 index 439bb4e..e192b53 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth2-msmpeg4 +++ b/ffmpeg/tests/ref/vsynth/vsynth2-msmpeg4 @@ -1,4 +1,4 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth2-msmpeg4v2 b/ffmpeg/tests/ref/vsynth/vsynth2-msmpeg4v2 index 985089a..bd02100 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth2-msmpeg4v2 +++ b/ffmpeg/tests/ref/vsynth/vsynth2-msmpeg4v2 @@ -1,4 +1,4 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth2-msvideo1 b/ffmpeg/tests/ref/vsynth/vsynth2-msvideo1 index 421ad87..4ec274b 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth2-msvideo1 +++ b/ffmpeg/tests/ref/vsynth/vsynth2-msvideo1 @@ -1,4 +1,4 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth2-prores b/ffmpeg/tests/ref/vsynth/vsynth2-prores index a46fa48..a1b4bb7 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth2-prores +++ b/ffmpeg/tests/ref/vsynth/vsynth2-prores @@ -1,4 +1,4 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth2-prores_ks b/ffmpeg/tests/ref/vsynth/vsynth2-prores_ks index ff815e5..b42e7b3 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth2-prores_ks +++ b/ffmpeg/tests/ref/vsynth/vsynth2-prores_ks @@ -1,4 +1,4 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth2-qtrle b/ffmpeg/tests/ref/vsynth/vsynth2-qtrle index c9bf1e3..4adf913 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth2-qtrle +++ b/ffmpeg/tests/ref/vsynth/vsynth2-qtrle @@ -1,4 +1,4 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth2-qtrlegray b/ffmpeg/tests/ref/vsynth/vsynth2-qtrlegray index 8b83a5a..824e64b 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth2-qtrlegray +++ b/ffmpeg/tests/ref/vsynth/vsynth2-qtrlegray @@ -1,4 +1,4 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth2-r210 b/ffmpeg/tests/ref/vsynth/vsynth2-r210 index e42d797..30dc5f0 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth2-r210 +++ b/ffmpeg/tests/ref/vsynth/vsynth2-r210 @@ -1,4 +1,4 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth2-rgb b/ffmpeg/tests/ref/vsynth/vsynth2-rgb index f86c37c..5176643 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth2-rgb +++ b/ffmpeg/tests/ref/vsynth/vsynth2-rgb @@ -1,4 +1,4 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth2-roqvideo b/ffmpeg/tests/ref/vsynth/vsynth2-roqvideo index c8b02e7..32a90fd 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth2-roqvideo +++ b/ffmpeg/tests/ref/vsynth/vsynth2-roqvideo @@ -1,4 +1,4 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth2-rv10 b/ffmpeg/tests/ref/vsynth/vsynth2-rv10 index 3fc93d9..ca5ae17 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth2-rv10 +++ b/ffmpeg/tests/ref/vsynth/vsynth2-rv10 @@ -1,4 +1,4 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth2-rv20 b/ffmpeg/tests/ref/vsynth/vsynth2-rv20 index 1251e49..921236e 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth2-rv20 +++ b/ffmpeg/tests/ref/vsynth/vsynth2-rv20 @@ -1,4 +1,4 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth2-snow b/ffmpeg/tests/ref/vsynth/vsynth2-snow index 74b6068..255e0b7 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth2-snow +++ b/ffmpeg/tests/ref/vsynth/vsynth2-snow @@ -1,4 +1,4 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth2-snow-hpel b/ffmpeg/tests/ref/vsynth/vsynth2-snow-hpel index f43263e..6742c51 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth2-snow-hpel +++ b/ffmpeg/tests/ref/vsynth/vsynth2-snow-hpel @@ -1,4 +1,4 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth2-snow-ll b/ffmpeg/tests/ref/vsynth/vsynth2-snow-ll index db2ffa9..09affc1 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth2-snow-ll +++ b/ffmpeg/tests/ref/vsynth/vsynth2-snow-ll @@ -1,4 +1,4 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth2-svq1 b/ffmpeg/tests/ref/vsynth/vsynth2-svq1 index afad59c..9c7db7f 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth2-svq1 +++ b/ffmpeg/tests/ref/vsynth/vsynth2-svq1 @@ -1,4 +1,4 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth2-v210 b/ffmpeg/tests/ref/vsynth/vsynth2-v210 index 1320c38..68cafc7 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth2-v210 +++ b/ffmpeg/tests/ref/vsynth/vsynth2-v210 @@ -1,4 +1,4 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth2-v308 b/ffmpeg/tests/ref/vsynth/vsynth2-v308 index f32dc5d..703289f 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth2-v308 +++ b/ffmpeg/tests/ref/vsynth/vsynth2-v308 @@ -1,4 +1,4 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth2-v408 b/ffmpeg/tests/ref/vsynth/vsynth2-v408 index 333a4e3..771d579 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth2-v408 +++ b/ffmpeg/tests/ref/vsynth/vsynth2-v408 @@ -1,4 +1,4 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth2-wmv1 b/ffmpeg/tests/ref/vsynth/vsynth2-wmv1 index 6e325ba..0db298a 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth2-wmv1 +++ b/ffmpeg/tests/ref/vsynth/vsynth2-wmv1 @@ -1,4 +1,4 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth2-wmv2 b/ffmpeg/tests/ref/vsynth/vsynth2-wmv2 index 72fe406..ff457e3 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth2-wmv2 +++ b/ffmpeg/tests/ref/vsynth/vsynth2-wmv2 @@ -1,4 +1,4 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth2-xface b/ffmpeg/tests/ref/vsynth/vsynth2-xface new file mode 100644 index 0000000..4544269 --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth2-xface @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth2-y41p b/ffmpeg/tests/ref/vsynth/vsynth2-y41p index 9c782f8..8afabb1 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth2-y41p +++ b/ffmpeg/tests/ref/vsynth/vsynth2-y41p @@ -1,4 +1,4 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth2-yuv b/ffmpeg/tests/ref/vsynth/vsynth2-yuv index 066cfec..0825e35 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth2-yuv +++ b/ffmpeg/tests/ref/vsynth/vsynth2-yuv @@ -1,4 +1,4 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth2-yuv4 b/ffmpeg/tests/ref/vsynth/vsynth2-yuv4 index b76cee4..51bd8b3 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth2-yuv4 +++ b/ffmpeg/tests/ref/vsynth/vsynth2-yuv4 @@ -1,4 +1,4 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth2-zlib b/ffmpeg/tests/ref/vsynth/vsynth2-zlib index d956a04..4a29285 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth2-zlib +++ b/ffmpeg/tests/ref/vsynth/vsynth2-zlib @@ -1,4 +1,4 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth2-zmbv b/ffmpeg/tests/ref/vsynth/vsynth2-zmbv deleted file mode 100644 index 93e0b6a..0000000 --- a/ffmpeg/tests/ref/vsynth/vsynth2-zmbv +++ /dev/null @@ -1,4 +0,0 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth3-v210 b/ffmpeg/tests/ref/vsynth/vsynth3-v210 index d3275f0..0eaf041 100644 --- a/ffmpeg/tests/ref/vsynth/vsynth3-v210 +++ b/ffmpeg/tests/ref/vsynth/vsynth3-v210 @@ -1,4 +1,4 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth3-xface b/ffmpeg/tests/ref/vsynth/vsynth3-xface new file mode 100644 index 0000000..f98a5c5 --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth3-xface @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth_lena-amv b/ffmpeg/tests/ref/vsynth/vsynth_lena-amv new file mode 100644 index 0000000..d2d1288 --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth_lena-amv @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth_lena-asv1 b/ffmpeg/tests/ref/vsynth/vsynth_lena-asv1 new file mode 100644 index 0000000..7859d98 --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth_lena-asv1 @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth_lena-asv2 b/ffmpeg/tests/ref/vsynth/vsynth_lena-asv2 new file mode 100644 index 0000000..f9d6ac6 --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth_lena-asv2 @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth_lena-avui b/ffmpeg/tests/ref/vsynth/vsynth_lena-avui new file mode 100644 index 0000000..02154a6 --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth_lena-avui @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth_lena-cljr b/ffmpeg/tests/ref/vsynth/vsynth_lena-cljr new file mode 100644 index 0000000..e841001 --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth_lena-cljr @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth_lena-dnxhd-1080i b/ffmpeg/tests/ref/vsynth/vsynth_lena-dnxhd-1080i new file mode 100644 index 0000000..5211b36 --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth_lena-dnxhd-1080i @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth_lena-dnxhd-720p b/ffmpeg/tests/ref/vsynth/vsynth_lena-dnxhd-720p new file mode 100644 index 0000000..686be54 --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth_lena-dnxhd-720p @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth_lena-dnxhd-720p-10bit b/ffmpeg/tests/ref/vsynth/vsynth_lena-dnxhd-720p-10bit new file mode 100644 index 0000000..794e9c1 --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth_lena-dnxhd-720p-10bit @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth_lena-dnxhd-720p-rd b/ffmpeg/tests/ref/vsynth/vsynth_lena-dnxhd-720p-rd new file mode 100644 index 0000000..453f68f --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth_lena-dnxhd-720p-rd @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth_lena-dnxhd_1080i b/ffmpeg/tests/ref/vsynth/vsynth_lena-dnxhd_1080i new file mode 100644 index 0000000..125c7a8 --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth_lena-dnxhd_1080i @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth_lena-dv b/ffmpeg/tests/ref/vsynth/vsynth_lena-dv new file mode 100644 index 0000000..ad0549f --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth_lena-dv @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth_lena-dv-411 b/ffmpeg/tests/ref/vsynth/vsynth_lena-dv-411 new file mode 100644 index 0000000..736a35d --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth_lena-dv-411 @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth_lena-dv-50 b/ffmpeg/tests/ref/vsynth/vsynth_lena-dv-50 new file mode 100644 index 0000000..adee628 --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth_lena-dv-50 @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth_lena-dv_411 b/ffmpeg/tests/ref/vsynth/vsynth_lena-dv_411 new file mode 100644 index 0000000..1ca2bc0 --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth_lena-dv_411 @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth_lena-ffv1 b/ffmpeg/tests/ref/vsynth/vsynth_lena-ffv1 new file mode 100644 index 0000000..154f455 --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth_lena-ffv1 @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth_lena-ffv1.0 b/ffmpeg/tests/ref/vsynth/vsynth_lena-ffv1.0 new file mode 100644 index 0000000..059170a --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth_lena-ffv1.0 @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth_lena-ffvhuff b/ffmpeg/tests/ref/vsynth/vsynth_lena-ffvhuff new file mode 100644 index 0000000..8a64606 --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth_lena-ffvhuff @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth_lena-ffvhuff420p12 b/ffmpeg/tests/ref/vsynth/vsynth_lena-ffvhuff420p12 new file mode 100644 index 0000000..6b666f8 --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth_lena-ffvhuff420p12 @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth_lena-ffvhuff422p10left b/ffmpeg/tests/ref/vsynth/vsynth_lena-ffvhuff422p10left new file mode 100644 index 0000000..519ea75 --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth_lena-ffvhuff422p10left @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth_lena-ffvhuff444 b/ffmpeg/tests/ref/vsynth/vsynth_lena-ffvhuff444 new file mode 100644 index 0000000..efd281c --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth_lena-ffvhuff444 @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth_lena-ffvhuff444p16 b/ffmpeg/tests/ref/vsynth/vsynth_lena-ffvhuff444p16 new file mode 100644 index 0000000..cb28f09 --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth_lena-ffvhuff444p16 @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth_lena-flashsv b/ffmpeg/tests/ref/vsynth/vsynth_lena-flashsv new file mode 100644 index 0000000..52046cd --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth_lena-flashsv @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth_lena-flashsv2 b/ffmpeg/tests/ref/vsynth/vsynth_lena-flashsv2 new file mode 100644 index 0000000..6186a1a --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth_lena-flashsv2 @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth_lena-flv b/ffmpeg/tests/ref/vsynth/vsynth_lena-flv new file mode 100644 index 0000000..e9f5e6b --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth_lena-flv @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth_lena-h261 b/ffmpeg/tests/ref/vsynth/vsynth_lena-h261 new file mode 100644 index 0000000..70b1da5 --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth_lena-h261 @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth_lena-h261-trellis b/ffmpeg/tests/ref/vsynth/vsynth_lena-h261-trellis new file mode 100644 index 0000000..1baab97 --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth_lena-h261-trellis @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth_lena-h263 b/ffmpeg/tests/ref/vsynth/vsynth_lena-h263 new file mode 100644 index 0000000..9865c48 --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth_lena-h263 @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth_lena-h263-obmc b/ffmpeg/tests/ref/vsynth/vsynth_lena-h263-obmc new file mode 100644 index 0000000..9bd1108 --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth_lena-h263-obmc @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth_lena-h263p b/ffmpeg/tests/ref/vsynth/vsynth_lena-h263p new file mode 100644 index 0000000..b0ca89e --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth_lena-h263p @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth_lena-huffyuv b/ffmpeg/tests/ref/vsynth/vsynth_lena-huffyuv new file mode 100644 index 0000000..fa9061a --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth_lena-huffyuv @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth_lena-huffyuvbgr24 b/ffmpeg/tests/ref/vsynth/vsynth_lena-huffyuvbgr24 new file mode 100644 index 0000000..4c23a95 --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth_lena-huffyuvbgr24 @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth_lena-huffyuvbgra b/ffmpeg/tests/ref/vsynth/vsynth_lena-huffyuvbgra new file mode 100644 index 0000000..ea7edb8 --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth_lena-huffyuvbgra @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth_lena-jpeg2000 b/ffmpeg/tests/ref/vsynth/vsynth_lena-jpeg2000 new file mode 100644 index 0000000..3efa6c5 --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth_lena-jpeg2000 @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth_lena-jpeg2000-97 b/ffmpeg/tests/ref/vsynth/vsynth_lena-jpeg2000-97 new file mode 100644 index 0000000..1577dd6 --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth_lena-jpeg2000-97 @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth_lena-jpegls b/ffmpeg/tests/ref/vsynth/vsynth_lena-jpegls new file mode 100644 index 0000000..99f47d6 --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth_lena-jpegls @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth_lena-ljpeg b/ffmpeg/tests/ref/vsynth/vsynth_lena-ljpeg new file mode 100644 index 0000000..6a25fda --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth_lena-ljpeg @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth_lena-mjpeg b/ffmpeg/tests/ref/vsynth/vsynth_lena-mjpeg new file mode 100644 index 0000000..84cbbcd --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth_lena-mjpeg @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth_lena-mjpeg-422 b/ffmpeg/tests/ref/vsynth/vsynth_lena-mjpeg-422 new file mode 100644 index 0000000..39978a8 --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth_lena-mjpeg-422 @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth_lena-mjpeg-444 b/ffmpeg/tests/ref/vsynth/vsynth_lena-mjpeg-444 new file mode 100644 index 0000000..6ba105d --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth_lena-mjpeg-444 @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth_lena-mpeg1 b/ffmpeg/tests/ref/vsynth/vsynth_lena-mpeg1 new file mode 100644 index 0000000..58539e5 --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth_lena-mpeg1 @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth_lena-mpeg1b b/ffmpeg/tests/ref/vsynth/vsynth_lena-mpeg1b new file mode 100644 index 0000000..23fe024 --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth_lena-mpeg1b @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth_lena-mpeg2 b/ffmpeg/tests/ref/vsynth/vsynth_lena-mpeg2 new file mode 100644 index 0000000..699a47b --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth_lena-mpeg2 @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth_lena-mpeg2-422 b/ffmpeg/tests/ref/vsynth/vsynth_lena-mpeg2-422 new file mode 100644 index 0000000..5f11d4e --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth_lena-mpeg2-422 @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth_lena-mpeg2-idct-int b/ffmpeg/tests/ref/vsynth/vsynth_lena-mpeg2-idct-int new file mode 100644 index 0000000..35269dc --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth_lena-mpeg2-idct-int @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth_lena-mpeg2-ilace b/ffmpeg/tests/ref/vsynth/vsynth_lena-mpeg2-ilace new file mode 100644 index 0000000..400be57 --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth_lena-mpeg2-ilace @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth_lena-mpeg2-ivlc-qprd b/ffmpeg/tests/ref/vsynth/vsynth_lena-mpeg2-ivlc-qprd new file mode 100644 index 0000000..2112cd2 --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth_lena-mpeg2-ivlc-qprd @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth_lena-mpeg2-thread b/ffmpeg/tests/ref/vsynth/vsynth_lena-mpeg2-thread new file mode 100644 index 0000000..01b60a3 --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth_lena-mpeg2-thread @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth_lena-mpeg2-thread-ivlc b/ffmpeg/tests/ref/vsynth/vsynth_lena-mpeg2-thread-ivlc new file mode 100644 index 0000000..2d0d42f --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth_lena-mpeg2-thread-ivlc @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth_lena-mpeg4 b/ffmpeg/tests/ref/vsynth/vsynth_lena-mpeg4 new file mode 100644 index 0000000..8d8ccce --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth_lena-mpeg4 @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth_lena-mpeg4-adap b/ffmpeg/tests/ref/vsynth/vsynth_lena-mpeg4-adap new file mode 100644 index 0000000..7787693 --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth_lena-mpeg4-adap @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth_lena-mpeg4-adv b/ffmpeg/tests/ref/vsynth/vsynth_lena-mpeg4-adv new file mode 100644 index 0000000..2304417 --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth_lena-mpeg4-adv @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth_lena-mpeg4-error b/ffmpeg/tests/ref/vsynth/vsynth_lena-mpeg4-error new file mode 100644 index 0000000..f04f3c3 --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth_lena-mpeg4-error @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth_lena-mpeg4-nr b/ffmpeg/tests/ref/vsynth/vsynth_lena-mpeg4-nr new file mode 100644 index 0000000..35c17ca --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth_lena-mpeg4-nr @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth_lena-mpeg4-nsse b/ffmpeg/tests/ref/vsynth/vsynth_lena-mpeg4-nsse new file mode 100644 index 0000000..0bc51c9 --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth_lena-mpeg4-nsse @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth_lena-mpeg4-qpel b/ffmpeg/tests/ref/vsynth/vsynth_lena-mpeg4-qpel new file mode 100644 index 0000000..d5c19dc --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth_lena-mpeg4-qpel @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth_lena-mpeg4-qprd b/ffmpeg/tests/ref/vsynth/vsynth_lena-mpeg4-qprd new file mode 100644 index 0000000..a0f20fe --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth_lena-mpeg4-qprd @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth_lena-mpeg4-rc b/ffmpeg/tests/ref/vsynth/vsynth_lena-mpeg4-rc new file mode 100644 index 0000000..85af229 --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth_lena-mpeg4-rc @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth_lena-mpeg4-thread b/ffmpeg/tests/ref/vsynth/vsynth_lena-mpeg4-thread new file mode 100644 index 0000000..6e84c1a --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth_lena-mpeg4-thread @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth_lena-mpng b/ffmpeg/tests/ref/vsynth/vsynth_lena-mpng new file mode 100644 index 0000000..45cd860 --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth_lena-mpng @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth_lena-msmpeg4 b/ffmpeg/tests/ref/vsynth/vsynth_lena-msmpeg4 new file mode 100644 index 0000000..c9eadbb --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth_lena-msmpeg4 @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth_lena-msmpeg4v2 b/ffmpeg/tests/ref/vsynth/vsynth_lena-msmpeg4v2 new file mode 100644 index 0000000..a8c4740 --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth_lena-msmpeg4v2 @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth_lena-msvideo1 b/ffmpeg/tests/ref/vsynth/vsynth_lena-msvideo1 new file mode 100644 index 0000000..b49d187 --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth_lena-msvideo1 @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth_lena-prores b/ffmpeg/tests/ref/vsynth/vsynth_lena-prores new file mode 100644 index 0000000..5b8c3fe --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth_lena-prores @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth_lena-prores_ks b/ffmpeg/tests/ref/vsynth/vsynth_lena-prores_ks new file mode 100644 index 0000000..0cdfa9b --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth_lena-prores_ks @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth_lena-qtrle b/ffmpeg/tests/ref/vsynth/vsynth_lena-qtrle new file mode 100644 index 0000000..9ce6abe --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth_lena-qtrle @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth_lena-qtrlegray b/ffmpeg/tests/ref/vsynth/vsynth_lena-qtrlegray new file mode 100644 index 0000000..951e7a7 --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth_lena-qtrlegray @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth_lena-r210 b/ffmpeg/tests/ref/vsynth/vsynth_lena-r210 new file mode 100644 index 0000000..c6bac90 --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth_lena-r210 @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth_lena-rgb b/ffmpeg/tests/ref/vsynth/vsynth_lena-rgb new file mode 100644 index 0000000..15df006 --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth_lena-rgb @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth_lena-roqvideo b/ffmpeg/tests/ref/vsynth/vsynth_lena-roqvideo new file mode 100644 index 0000000..10f2014 --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth_lena-roqvideo @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth_lena-rv10 b/ffmpeg/tests/ref/vsynth/vsynth_lena-rv10 new file mode 100644 index 0000000..651587b --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth_lena-rv10 @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth_lena-rv20 b/ffmpeg/tests/ref/vsynth/vsynth_lena-rv20 new file mode 100644 index 0000000..b8b6adf --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth_lena-rv20 @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth_lena-snow b/ffmpeg/tests/ref/vsynth/vsynth_lena-snow new file mode 100644 index 0000000..26c023f --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth_lena-snow @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth_lena-snow-hpel b/ffmpeg/tests/ref/vsynth/vsynth_lena-snow-hpel new file mode 100644 index 0000000..bdf2746 --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth_lena-snow-hpel @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth_lena-snow-ll b/ffmpeg/tests/ref/vsynth/vsynth_lena-snow-ll new file mode 100644 index 0000000..e68ba3f --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth_lena-snow-ll @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth_lena-svq1 b/ffmpeg/tests/ref/vsynth/vsynth_lena-svq1 new file mode 100644 index 0000000..1558c50 --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth_lena-svq1 @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth_lena-v210 b/ffmpeg/tests/ref/vsynth/vsynth_lena-v210 new file mode 100644 index 0000000..fe0a5a7 --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth_lena-v210 @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth_lena-v308 b/ffmpeg/tests/ref/vsynth/vsynth_lena-v308 new file mode 100644 index 0000000..d7bacf6 --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth_lena-v308 @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth_lena-v408 b/ffmpeg/tests/ref/vsynth/vsynth_lena-v408 new file mode 100644 index 0000000..2451c01 --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth_lena-v408 @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth_lena-wmv1 b/ffmpeg/tests/ref/vsynth/vsynth_lena-wmv1 new file mode 100644 index 0000000..f6e3ca9 --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth_lena-wmv1 @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth_lena-wmv2 b/ffmpeg/tests/ref/vsynth/vsynth_lena-wmv2 new file mode 100644 index 0000000..c75f762 --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth_lena-wmv2 @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth_lena-xface b/ffmpeg/tests/ref/vsynth/vsynth_lena-xface new file mode 100644 index 0000000..61031f9 --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth_lena-xface @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth_lena-y41p b/ffmpeg/tests/ref/vsynth/vsynth_lena-y41p new file mode 100644 index 0000000..91681c3 --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth_lena-y41p @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth_lena-yuv b/ffmpeg/tests/ref/vsynth/vsynth_lena-yuv new file mode 100644 index 0000000..3ee30de --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth_lena-yuv @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth_lena-yuv4 b/ffmpeg/tests/ref/vsynth/vsynth_lena-yuv4 new file mode 100644 index 0000000..4d173cc --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth_lena-yuv4 @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth_lena-zlib b/ffmpeg/tests/ref/vsynth/vsynth_lena-zlib new file mode 100644 index 0000000..913d155 --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth_lena-zlib @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth/vsynth_lena-zmbv b/ffmpeg/tests/ref/vsynth/vsynth_lena-zmbv new file mode 100644 index 0000000..e6c994f --- /dev/null +++ b/ffmpeg/tests/ref/vsynth/vsynth_lena-zmbv @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth2/cljr b/ffmpeg/tests/ref/vsynth2/cljr deleted file mode 100644 index f4cf7d1..0000000 --- a/ffmpeg/tests/ref/vsynth2/cljr +++ /dev/null @@ -1,4 +0,0 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth2/huffyuv b/ffmpeg/tests/ref/vsynth2/huffyuv deleted file mode 100644 index e59b53c..0000000 --- a/ffmpeg/tests/ref/vsynth2/huffyuv +++ /dev/null @@ -1,4 +0,0 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth2/yuv b/ffmpeg/tests/ref/vsynth2/yuv deleted file mode 100644 index 699ebc9..0000000 --- a/ffmpeg/tests/ref/vsynth2/yuv +++ /dev/null @@ -1,4 +0,0 @@ -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 diff --git a/ffmpeg/tests/ref/vsynth_lena/cljr b/ffmpeg/tests/ref/vsynth_lena/cljr new file mode 100644 index 0000000..e3bbc05 --- /dev/null +++ b/ffmpeg/tests/ref/vsynth_lena/cljr @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth_lena/huffyuv b/ffmpeg/tests/ref/vsynth_lena/huffyuv new file mode 100644 index 0000000..c0e374d --- /dev/null +++ b/ffmpeg/tests/ref/vsynth_lena/huffyuv @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/ref/vsynth_lena/yuv b/ffmpeg/tests/ref/vsynth_lena/yuv new file mode 100644 index 0000000..eff44c3 --- /dev/null +++ b/ffmpeg/tests/ref/vsynth_lena/yuv @@ -0,0 +1,4 @@ +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 diff --git a/ffmpeg/tests/reference.pnm b/ffmpeg/tests/reference.pnm new file mode 100644 index 0000000..e81bd7c --- /dev/null +++ b/ffmpeg/tests/reference.pnm @@ -0,0 +1,696 @@ +P6 +# CREATOR: GIMP PNM Filter Version 1.1 +256 256 +255 +Ò¸ Ü¼¦áÁ¡á½Ÿæ¾Ÿåºžè¼Ÿé½Ÿä·›éºç¸˜è·˜å´’淒縗êÁ›æâ³é½‡Þ¯‚éµí¾™îÀîÀŸîÀœî£î£îÁ¡îÄ¥íÇ«íȬìÉ­íÈ­ìË®ìË­ìË­íˬíÌ®íÍ­ìΰìÏ°íгíαîÍ­íͲíѵíͲíͯîË«îʪîȨî˪îË®îÉ©îÇ¥íǦíƤìÄ¢ìÄ¢ìÅ£íÅ£ìÄ¡ìàêÁŸêŸ辛éÀ›ç¾›æ¾™èÀœç¿›ä¼—彙⼘ỗ俛çàèÄ£éŤæÁ á¾šß¼™â¿çÄ¢çÇ¥çÇ¥åŤæǧãÆ¥åÇ¥äȦæɧéÍ«êÏ­èË©äÈ£ãÇ¢åȤæÊ£åÉ âÅ¡âÅ¡ãÆ¢ãÆ£äÆ£àŸááàÅ ãɤåÊ¥áÉ¢áË¥ÞȟÞȞáÊ¡æϧåΨáË¥ÝÆ ßÈ¢ÜƝãÌ£åϨçÑ«èÒ­åΩçÑ«èÓ¬ìÙ²íåÂîéËíæÊîßÁìعéÓµã̦պ‘¸˜kŽh8P"‰JˆHŠK…E„Dz?w;|B}E!Y3~iC†tV‡y\oMtcH[M8A9,"    + + + + + +   + + +  +     +   +        +      + +    + +  Á¤‘»™…À—yϧŒä½¢á·™ç¼žæ¾œå¹›åº™è¹˜æ¶”蹗黙巐缕ãé·ìÍšá³†ë·í¼™í¼šî¾î¾žî¿ î½žîÁ£îÁ¢îÁ£îÀ£î¤îèîèîÆ©íƪíÇ©íȪíÍ®ìίíÍ®íÍ®íÏ°íϯíÏ°íгìÒ²îήî̬íÏ°îήíÍ­îάîͬîË©îɧíɧîɦîɧîɧìǦìäëâìŦëäéÁ ê¢龜èÀœéÁžè¾œçÀœä¼˜ä¼šã»˜ä¼™é¿ èÀŸæÁžå¿â¾œá½›âÀœäÀŸçÅ£åÅ¢çǤæÆ¢äƦãƦåÈ¥ç̪æΪéάé̪åÈ¥äǤæÉ¥æÉ¥äÈ¡ãÇ ãÇ¢áàâÅ âÄ¡âÅ¡àÄ áÅ¡âÈ£ãÈ£ãɤáÉ£ßÈ£ßȟáÉ¢ã̦ãÍ¥âË¥ÛĚÛĜßÇ àÉ æͦèÒ¬æЪæϪã̦èÒ¬ëײîá¾îäÅîãÇîÞ¿ëÕ²éÒ±âË£×»Œ¾o™nAŒT*‹JŒLO#‹H†D~D|?wAzN,|\5}fDwlNt_A_Q6?9%$     + + + + + + + + + + + + + + + + + +   + + +    +  +    + +  + + + +  + + + + +    +   +  + \D.dK1}^F¢fǟ~Ϥˆß³œá¶—ß³‘ⵖ渕幙给꽗默軖ãë¾êÏ›ä¹ë¹“î¿œí¼™îºœí½›í¹›î½Ÿí¹î¼ží¼žî½ží½œîÁ¤îÁ£îÀ¢îÀ¢íÁ£îĦìÇ«îÉ­îÉ­íÉ­í̱î̬íͬíϯíήîίíдîϲíѳîѳîвîÌ®îÌ­îΰîÍ®îË­îˬî̪íÈ¥ìÇ¥ìÆ¢ìŦëÆ£êÅ¡êÄ éžêŸêžèÁœèÀœæ¼ã½œä»—⻗依忝åÀŸä¿›ã¿á¼›á¾œãÀå æÆ¢äŸåÄ¡äâæÆ¥åǦçË©æʧè˨éÍ«åÉ£åɤę̀çÊ¥åÉ æÊ£àžâƟâŝáŝâĝáğßÛãÆ¢ãÆ£âȟÝŚÞƞßÇ âÇ¡å̤âÌ£âǟÛÚÙ˜ÞěâȟåË£äΧäͧäΦäΧæЪéÓ®íÛ¹îß¾íÞ¼ìÚ·éÓ°æѬâ̤ؾ’žq¥uG–]2•S –Q$’Q#ŽL$‰H&}C~D{E"|Q0vX4o];bU4J?$3(   + + + + + +  + + + + + +  + + +           +  +     +   +      +    bJ5iK8gO9gK”v]°ˆoÀ—uÔ§‰Õ©‰Û®Ý±Žå¹”底缘躙꺕åá¶èТ乒깑îÁ™î½›î¾žìº˜íº›í»Ÿí¹šíº›î¼ì¸šî»í¼›î»œî¼ î¿¢î¾¢î¿¡îÁ£îÂ¥îæîĨîãîȦîʨîɧî˨í̬íÏ®íϯîÍ­íаîѳîίîίîÏ°îгî̯îαîΰíË­ìÈ©íÊ«íˬìȧìÈ©ëÄ¢ëàëÄ¥éŤçžéÀœä¾žâ¼˜ã¾›åº›â¼›â¼œä¾žá¼šàº™á»šà¼™â¿œäÀžåÁœäÁ äÅ¡ãğäÄ åÇ£äǤæ˨èË©åȤåÉ¥åȦäÇ¥æʤæË£äÈ¢äǤâşãÇ âƝâĜáƝàåÉ£äÉ¡âÈ¡âÈ ÞÚÞěâǟãÉ¢äÊ àǙÛÙտ“ÝĘàǛáË¡âË¢âÌ£áË£ßɟâË¢äͤéÓ°ëÖ±ëÕ±êÔ¯èÑ­åÏ©áÊ¥Ù¿–Ç¡q«{L d6¢]+™V+‘Q)ŒI"ŠH%~D|C€O2R6vR3N?%80  +  + + +  + + + + + +   + + +       +   +    + + +   +  +  +    +  + iQ:gN5qXvW<^F,7,  +    + + + + + + + + + + + + + + + + + +        +         + + + +    +   +           kX@yaCzX§›…yhCrO¯“xÁƒÜ´œÝ¶–Óª‡Ü²Œä½™å½’㹔ḕޭ‹Ö£‚ת†Û®…íÂ í¿¢í½ŸíÀŸí¿¢í¼ î½Ÿíºœíºœì¸›í¶ší¶™í¸›í¸ší·šì¸–í»í¸ší»œí½Ÿî¼î½ŸîÀ¡îÁ¢î¿žîãížîƦîɨîË©î̪îÍ®îίîÏ°îÍ®îÏ°îϱîѳîΰíÌ­îÏ­îίíÍ°îÍ­îÍ®íˬíË«íÌ«ìË«ìɨêÅ¥èÄ£êƦåÁ æ¡æÀ ä¼œâ½›ã½œß¹—ß¹—ݺ”Þ¸“὚ཛäŸåŸå äÄ æÇ£äÄ åÅ¢äǤäÇ£âÅ¡äÇ£áƜåÈ£âƟãÇ¢åÈ¥åɤåÈ¢åÈ¢åȤáşâƞåÉ¡åÊ¡åÊ¢âÇ ÞØÞĘàƙáțâɜÝÖØÁ•Õ¾‘ØÀ”ÞÚàŝàÈ àÊ àÇ ÜŜÜŜÞÈ¢ßÉ£áË¥áË£âÌ¥ãΨã̦â˦ÜØѰ€Á”h´tH§a0šV)‰M"‚E…H$ˆU1ŽhA‹mIw_CTH'*!  +    + + + + + + + + +         + + +                 +  +     +  +       ĪâÄ«êÔ¾éíæâàÓåÏ®çίîÒ½îÓ»ïÓºëÉ«æÀœè¡íͬåÁà½Ø­‹Ð {ѦÖ¬æ»›íÀ¡í¿¥ì¼ ë»žì¾£ì½¢í¾ í¼ íºí»Ÿì¹Ÿì¸›í¹œì¸œìµœí·œë¶šíº›íº›íºœíº›ì»˜í¼›íÀží¿îÄ¡íÄ îǧîƦîȨîʪîɪíÊ«îË«íʬîίîΰîαíͯîϱîήîϱîвíαîΰîϯìÌ­íÌ­ìË«ëɨëÉ©ëȨéŤè¢åÀŸéã從俚⼜ߺ’ݹ’Þ¶’໖⿙⿚äÁœäžãÁ âÁŸåÄ¡äÄ¡åÅ¥åÈ¥áÄ âÄ¡âÄ¡âÅ¡äÈ äÇ£åȤçË¥åÉ¢äǤâÄ àŜâƞâŞåÉ£ç̨áÉ¢àĝÞĘáƞàśàǚßƙÙÀ•Õ¿“Ö½”ÛÁ—àşÞŜÜśÛŝÚĚÛĜÙ›ÛĝÞÈ¡ÞÇ¡ÞȟßÈ¡ÞȟâˤáǞѲ€¾‘_±tFŸ\-”R)ƒHH „Q(ŒiC›_˜ZmMUL/&!   + +   + + +        +  + + +   + + +                     + + # )&4/A=0íʲêÒ·êÙÄçÛÌéèÜèÓ¹éΰäĨèÈ«êÈ©ã¿¡ÕªŠäÁ£êȦæãè¤๙ȞxǝyÒ¦Œç¸žé»ê»ë»žì¼Ÿë¼žì½¡ë»žëºí¼Ÿì»Ÿì»Ÿíºžì¶›í¹›ëµ—ì¶ìµìµ•ì¶”ëµ–ì¸šì¹™ìº–í½›ì¼œí½žíÁ¡îÄ¥îȪîƨíǧîÉ©íǨîȪîɪíǨíÈ©îÊ­îË­íÌ®ìʬíÍ®í˯îΰíÍ®íίíͯìÌ«ìË©ëÊ©ëɧéȦëɧêȦèÄ£çÅ çğåÁœä¿œà»–ß¹•Ü·“Ỗᾙབྷ߼–ᾙ࿛äÄ¡ãÄ äÆ¢ãƤãÅ£ãƤâÄ¢áÄ¡áÄ¡ãÇ¢ãÆ¢äÇ£âÅ ãǟãÆ¢áŝßÛäÇ æȟçË¥æɧâÈ áƟÞÛßĜßŜàǚÜ•پ‘ؽ–ÚÀ“ÞÚÜĝàĝÞĜÞÞÜÁ›Ù¾—ÜœÙšÛŞÛĚÜƜÜěâÈ àË¡ßƚϱ€«ˆZ‘b:U2‡N)„K$M)†a@}TŽcg…z[VO/'# +   + +                  +    + + + + +              !#!0.'@>/OL;]\PolY…oŒxŸœ…¬¨—³®œÅ²Ӯ›Õµ–àÆ©Ýŧæêí×ÁŸÙ¿šØ¾›Ù·—ÞºÎ¦‰Ð§‡Î¦†Ò¯ŒÌªˆÕ±†Û·Ç zÁ˜nȘu䳘麦黠꺟鹢꺠鸜깜麛뺟鸜鶙츙췙괘궙뵚괘봖괖뵗봔鲓굔鷔뺙뺝íÀŸíáíÇ¥íƤíƤëáìŤëãìÅ¥ìŦìƧìŧíǨíŦëƦèâìǧìȧìʪíÌ­ìʪìɨèŤìÊ©éŦìË©êǦêÇ¥èƤéŤçÆ£çÅ¢åáå¡ཚ῜ຘ⾝߼™ß¼˜Þ»˜ß¼˜ß¾šáÁááâŸâÅ¡ãÅ¡äÇ¥ãÅ£áÄ âÅ¢âÄ¡ãÆ¢áÄ àÞâÅ¡ßĝÞÜßÙåÉ¢åÈ¢å˧ãÉ£ßǟÞŗßƙߌÝ×Ú•ÙÁ—Õ½“ÚÀ•ÛÀ˜ÝÚÛĚÛÚÙÀ™Ø½”×À—×À™×Á—ڜؗÚÝÚĚÞÜÝƜڿ–ŧwž}NƒZ)zH~L'€N&†\;‡sP˜g¨˜m¢˜qŒƒe^U4-+  + + +                +         +  +  + + +  + + + + + + + + + +        +    $&%*)63<9!PL:]XEmkTxse‰…s”y¨¢´®À¼¬ÎʱÖÑ¿ßÖÅáÛÒèåÛéæ×ìëÜëëáìíæÝÀ¥áǦÜħä׺åêìáɪßÅ£ÝÅ¥Ú¾›Ö¸•Õ¶”Ó±“Ó®Ø¸“Ȩ~Ç©€Ä¤{¾šq¼’nŔsÓ£†Õ£Ýª•Ý­›à¯œá¬˜á²¡â±˜à²œä´œà¯’ఔⳘ㲙㱓泔嬎寐箏诐鱔譍篑篒곕괗鶕뻘íÀ íƤîÃ¥êÁ¢êÁ¡ëÁ¤éÀ¢éÀ¡éÀ¡êÁ£ìÅ©ëÅ£éÁ¡æ¿¡å¼šé¿¡çÀ¡èÀžè¿žçÁ£ç¢æÁ çÁ£éÄ¥éĤæÁ çãèĤêŤéŤçğæÄ¡æġ⾙⿚âÀšß¼—὘߼—ݺ”ܹ”Þ½™Ý½™à¿›âÀžàááÄ¢âÅ£âĤâßãÅ¡àĞáÄ¡âŞâÅ àŸÞÀœßÁÞÜâÆ¡äÈ¡äÉ£åʦâÈ¢ÞšßŜßĜÜÙØÁ™Ö¿˜Ö¿˜×¾•ÚÀšÚĚÛ™ÚšÚœÚÀšÕ¿˜Õ½–Õ¾—Ù›ØÁ›Ø¿™ÚÁœÛÁ›Ý•պ¸˜kŽi>|R&uEyK(Y9jO—€[£”k°¡{®v’Šjg]::1 +      +    +  +         +  +      + + + + + + +  + + + + +  +      ! ""/+?:*ED8QK2XVBkhTxrY‰eŠr¡šƒ¦¢Š§¥‘·²Ÿ½¹¢ÅÁ¬ÏÊ»ÙÔÀÞ×ÈæÝÐéäÑëèÝíìäììäêíêèìíçéìåèíäæëãåêãäèâäèããè벚ãŦâȨä̬èÔ¹æÊ­àÇ©ßÆ©ÛÁ¡Ø¿Ù»•ÔµŽÑ­ŠÑ¯‹Í¬‚Ç©¿ zÀšsÀ’oǑtɑq³g¹„u½Š~¾Œ}¾‹€Ã‘À|Ė†¾’|ș|ȗ|ə~̜„ɘx͚ӛқ{Ü¥…ߨ†à§†ãªŒâ¨ŠãªŠä¬‘䮔毓贘콠ì£íä輚缛辜輛纙迟迣íÆ«êŸ廛ݲ›á´™à³—Û®’Ü°“Ú¯‘ݱ™Ü¯”Û¯’ܲ–ܱ”ݲ”ßµ•à»—Ἓ俞忙âÀ—â¿—â¿šß¼—㿚ᾙབྷ߼—ß»—Ûº”Ü»–Û¼—ܼ—Ü»—ß¼šÞ¾›ÝÁžÞÀžÞÀžßÁÜ¾›ÝÀÞàßÝœÜÁ›Û¿šÛÀšÚÀšÞĞâÆ äÉ£áÇ áƞÝĜÝÙÚ–׿•Ö¾•Õ»“ѹÓ¼’Ó¼•ØÀ™Ù¿–Ú¿š×¿•Õ¿—Ô¼’Öº“Û¿šÚÀš×À™Ô½–Ù¿šÚ›־‘βˆ­bj>vP%yR(b?†mJ˜€_Ÿj¬¡|´¤„²£‚”rtiFE:     +                   +   + + +   + + + + + + + + + +   + + + +  +    *'75$;9)KG0RM8\YElfNys]ƒ~l›˜„­§™±­”¹´¡É¿®ÏÉ·ÓνÞÙÇäßÎæàÒêæØêèÞìëÞííäêêåìíééëêéëìæéìæéíãæíãäêâäêããéããçããçããåããåãããããäããäããäããä澢ßÄ¢áǧèίæαáÊ­àɬÜħֽ›Ñ²ŒÊ©É¥zȦzÏ«‚Ȫ¿ rÞx̐jå£uЏkc@&cE2oN5uS?}YH}]H~^Iƒ`LeS•gO›nS¡lN¦oX¥mP¬sW±vZ½‚i͔Ԝ~֛}֜۞~Ú¡|Û ‚Ü¡Þ¤~䩋贘麘꼞㲓嵔㲑䴕涘嵖鿟êÀæº•ß°Ý¬Û¨ŠÖ¥ˆÓ¤ŠÒŸ†Ì™{ΚÎ˜Ϛ€ÏÐŸÏ€Ñ ‚Ó¢Ö¨‰Ù¬ŽÚ¯ŽÚ°‰Ú²ŒÛ±Ú³“Ü´”Û¶•Ü¸˜Ú·“ݸ˜Ü·—Ú·–×µ“×µ’׶Ø´‘×´ŽÖµ‘غ—ع—Ú¸—Ø·“Ö¸–Ôµ‘Ôµ’ѲŽÕ·•Ò³‘Ó´•Ñ²‘Ùº›ÚÀ™ÝÅ¢Ù¾˜Ö¼—Ó¼™Ô¹Ð¸Î·”ȲŠÃ©‚¿¨€Â®€Æ®†Ì±ŠÑ¸’ÕºšÒ»˜Òº”Ò¹•Õº”Ó¼•×¾—Ô½–Õ½˜Ø½—ؼ•ÕºÊ®Š¨n‹oC|b8†fBqO–UŒh¨œ{°¥…µ¦…¶ª‡ž’s€vZUL-.' (! +"& +'#" !   +                   + +  + + + + +  + + + +    + )&/+:7"DC0LG5XTC\[IjiXyrb€{mŒ†uŒw›—†¥¡®©”º´¢½¹¦ÈıÒȱÚÒ¾àÛÊçâÐèåÖìíäíîéëíëêëêèìíåêíåèíäçíãåìãåìãäìãäêããéããèããèããçããæããåããæããçããåããæããæããçããåããçããæããèããçããçããçí¶žá½ŸÝÁ¢ßäèÍ°çÍ®âǦâÉ«ÞÈ£Û¿™Ôµ‘ΰ†Ï­Ô°~׬}Í©|Ç¢r×­sç׆äقŠJ8  *.!/ 2#?-T8$mE3yA,y>&A3ƒE0–T>¬lXÁ‚kΏv̍qˏrΒtϒtԗ|ҔwҖuכ{ইݨ‹Ù§ˆØ£ƒÛ¥ˆÙ§‰Üª‹Ú§†à«‘ᮎⳍݬ‡Ø¦‚פ‚Ï›yʖtƑqÏpŽo¿ˆj‹kčmÌlŏmÍjƑoƑoɓnʖq̙zɘp˝~˝~˟}Í¡}ˤ„ȨˆÐ§ˆÍ¥‚Ñ©‰Î¨…Ï«…ʨ€Íª„Ϩ‹Ï¨ˆÉ£„È¡ƒÊ¥Æ¥„¡ƒÂ¢~¾ž{À¡~½Ÿxº›{¸˜uµ”uºš}À ‚Ç©‰Ê¬ŒÍ²‘Å«ŒÀ¦º¢{¹¥†º£‚³£}¯ž~¦“r¤‘m©˜w¯œvº£}ÁªŠÅ®É³È²ŽÊ³Ï¶“е•Ð¶Ó¼˜ÐµÐ¸Ñ¸ŽÆ¯‰ª‘p–~PxM‘zO›‡] Žg¬œu°£{³§¸¨ƒ½±±¥…¤•w‡zXujIqfHwjI}rZ}r_xpTkcFdZ?RL1C@#61*'    +   +  +      +    +     "#*)!,,!31"?;%IB,NM3]YBjbHulS}gŽ…k”Ž{ž™‚ª¦¯ª“·°žÁ¹¤È¾¨ÍdzÔȳÛйàÛÇãÜËçãÒêæ×ìêÞìêâííâëëæêìéêííèììåçîäçíãäìããëãâéããéããèããçããèããèããçããçããçããèããèããèããèããèããèããçããèããèããèããèããèããèããéããéããèããéããéããéããéâáßäàŤÞáàÅ£Ù¾šÑ´àÄ¡äͨâş׸“а„Ю…Ò¬}Ü­Ú¡tãÁ™äëÞãçÊçÔqˆE:   + +  +  9)X:(i8"n3p1y3!‡A.¢bN¾~dˋx͎xΎtʌtˎs̍t͎s̎pΒsАuӗ{іxГuә€Ñ™}ә}՜€Õ‚ØŸ…ÖŸ‚Öž‚И{ϖxƎrÌp½†d»ƒc¹c¼‚dÀ†eˆjÁˆkÁˆh½ˆe½†c¿ˆg¿ŠfÁŒiÀ‹j¿Šj½‰l¾Žo¾n»ŒmÀ‘u¾‘u¾’qÀ”t¿”sº“p¿–tº•uÁš}»“v·’p±m®j¨‡b¢…a§‡fŸ€b›cœ~`—|X—|Zš~]—Z•~[™€\¡‰o¬”z¨“s¥“q§–r¡“o ’q¡“r¡•t˜l’…c‘‚`‚^—Œgž’k¦˜v®£ƒ·¥‚¶¤‚¹§‚¾«Š¾ªˆ¾§ƒÁ¬Æ­Ç¯‹Ç®‡Ã©‚³›w¡ŽjŠkŸq¤”q«šx°¤|º¨ƒ¿­Å·“;˜ÖŨѼ¡Ñ»ŸÌ·™Í·šÕ¿ŸÚ¤ÜħÚƬÓÁ¨Ë·ž»¬Ž¬€™‹ow[i`JTN8A8.)   +  + +   (%2.10 92 MG2TRA][NkjYusX|cŒˆx“y•}¤„°¤Ž¿·¢Å»¥ÉÁ«ÚкÜÔÃäÛÉãÝÍçäÑêåÔêçÝííäíëßìíãìíåêîëéíëçëìåëîåêîäèïãçîãçîâæîãåíãåíãåíãäíããìããìããëããëããêããéããéããèããèããéããèããéããéããéããéããéããéããêããêãäëãäêãäêãäìãåìãäìãäëãäìããëããëããêããëããêããêàÄ¢àâÞàÞàÜÀÜÁáÅ¡êЭíÕ³ãÊ¥Ô¸“ͯƒÎ¯שxåªrå͑ãæèããêãèÐè§iÉnJB#  +   A4 _G;nN?k<(r4$v4%ƒ=,¢`N¿dɉrɌrȋpʋrɊqȊpȊoňlNJnˏsȋnɉlɊǒr̍pΏȕrϒtғzГzГyѕzˍtƈoºh¸€e¹dº‚e¼‚g¿…iÀ…j¾…e¿ˆfºƒa¹]º†`»…`¹…_¹„a¹ƒ`¶„b·†f´ƒc¸†i¸ˆo´…iµ†j­€b­ƒd©„b¬…e }^Ÿfšx]—xZ“u[tX‡lR‡nT€hG€gI{eHzcC~hLzgIzeFzeF~mL~jJ‚rQ‰}_Œ€`“…e‘ˆjˆf“‰e”Šh“‡fŒ]‰}XƒxR†zUŠ|X_–ŠgŸ’o£—r©œw«w¦˜u¦šu¯ž|­š|¯z´ž{º¥„¸£}¯šz§˜y¦–wª˜w¬œy´¤ƒÊ»˜Ñ¿šØȨßϯãѲêؽíÚ¼ïÝÂîÝÂïÞÄîÜ¿îÞÂîàÅïáÇïãÊïäÍîåÍíàÇêÚÀÞÊ­ÓÀ¤¼­Ÿn‚tTf_FA< (&   % 6.JC1bY>mcHxnT†€iˆ„u“}¦„¯©‘¶±À¹¨ÌîÏÇ°×кÝÕÇåÛÉéãÍéäÓîéÜëéàíìâììäëíçèììèíìçëìåêïäëîãéîãèîãçîãèîãçîãèîãçîãçîãçîãçîãæîãçîãäíãæîãåîãçîãåíãåíãæíãåíãåíãåíãäìãäìããëããëããëãäìãäìãäìããëãäìãåìãåìãåìãåìãæíãçíãæíãçíãæìãåíãæìãäìãäëãäëããëãäëããêããëããêÜÀœßÁ ßÄ¢ÞÄ¡çˬéѳêÒ¯ëѯéЬãȟÜÀá¾†æµw翄âݚãé¯ããçããâãëãçŠuÜk_R*! I:2qULx]GvNi[?j\?pbDr`BsfJ{nP~rS€vV…zWŠ~]€\„c‚`Ž‚]Œ^‡{YƒzXƒyW†yX‹]‘…`˜ŒjŸ“o¡—v “o¢—s’nŸ’nŸ’nŸ’n¢“p¦–t£˜y¨˜{¦˜x¦š}¬›{Á®‰åÑ®îß¾íäÆîåÇîßÁîßÁíÛ½íܽíÙºíÛ»ìÙ¹ëÖµê×·éÔ²êÕ´êÖ¸ìÚ¿îáÃíçÊìêÑìëÔììÕíìÔíêÕîéÓîäËèÙ¿Ýͳ¿µ™«¡›ŽpŽƒeŠy\‚oOŽ~_­ž‚ÔÆ°èÞÉîêÜíîâëïèëîèèìëèììçììåìîåëîåëîäëîäëîåëíæìíåëîæëíæëíçììæëìçìëçëìçìëæëíçììèììçìëèìíçììæìíæìíèììæìíæëíæëíæìíåêíåêíåëíãèîäéîãèîäéîäçîãæîãçîäèîäèîäéîãèíãèíãèîãèîãèíãèíãæíãæíãæìãåìãåìãäìãäëãäëãäìãäëããëããêãäêããêããéããéããçããçããçããèããçããçããèÞÀ£ã æÇ¥çç弜ڤŠÛ–€ÇtRÊZ:áZIä£wãӅãªkãšdãÖ¥ãããããæããããçÖå}BÜbEh3#     MA5zfY’xf‰hUxJ9l3 p4%‰K>¨jW¿jÃlÀ‚l„m¾€m»€e¸~f»iº€h¹}e¹€f·}e´|`¶z_»g½‚k½jÀ…nºh¿†n»‚i½„l¸€g´|c¯z_ªuY«v]¬x`ªvZ¬x^ªw_¥t_¥sYžmR pV£tZ¡qV¢vZ¤vY sWžrV›qS˜pVjP‹jF…hDydFt`Al_@eX7dV8`S4_Q6dU:_P6`R6aS7bT8dW;eW;eV:fX;i]=n_Co`FmaBseHveExiJ{mO~qSsT‰zZ‹^‹Z‘„c“‡eŽ‚_ZŠ}\ƒxX€wR„xUŠ`“†cšŒj‘l •u¢˜w ”tŸ“pŸ’n m o¤“r¢•v¤—w¦•w¢—w¦š~¯žzϼ–êؾîåÈíçÈîäÆîâÃîßÀîÞ¿íܽíܾíܽîÞ¿íÚ»ìÚ»ìÙºë×·ëÙ¹ìÚºîÞ¿îãÇîåÈíèÎíêÒììÓíêÏìëÑìëÓíëÒïèÑíãÈçؼáѳÚ̱ÍÁ¦Â³“ö˜Ë¿¡âÖ½îìÚêîéçíìåëîåëìæìíåëîæëîæìíçìëçìëçíêéíééíèéíæëîäëîâëîâìîßíîàííÜíîãìíáîíÛííÝíìÚîíÛíìÜííÛîíÚíìÚíîáìîáíîÞíîáíîàíîâëîåêîåêíéçìíçìíåêîäéîãæíãäëãäëãäéãäèãæìãçîãèîãçíãæíãçîãæìãåìãäìãäëãäêããêããêããêããêããéããéããéããéããéããéããéããéããéããéããêããéããéããé欘˞‰Ãr¿j´iJ¸RAÂNEÊG1ë\DßF3å–gãÅvãƒLãœiãÕ¬ãçàãäåããæããêⴄç]C}4* +   PB3ziY–{noavK7g2 i0 E5bJ¹{d½jºf¸|a¶|cµ{c³xaµzc³x_·|d®u\°u]°v[±v\²w]¶{`´z`´|c²z^±y`®w]®y]«u\©t\¤rW¡nT£rZ¢pW›jQ—iO”jN“kOeIeH’jOgM‘hIŽhGhM‘jMiJˆfJdHz_Er\?n^?cU6cV6`Q6_R6`S8bS9aR:aS:bT:bT;aS9dU=fXhY>jZ@p]Cp^Cp^DpbGseIwiJxhG|pQrQrN†uRŒZ‘^’‡g•…a”…a_‰|[„sN„tQ…wV‹}[”ˆh˜ŒjœlŸ“o –tœošŽnœŒjžk£’r£“s o¡‘o l¦•v± „IJ“ÜȦìÜÀîåÉíçÈîäÆîâÃîàÁîßÂîßÂîàÄîâÅîâÅîäÇîäÆîæÇîæÇíåÇîäÈîãÈîãÉîäÇîçËîèÍíèÌîçËíéÎìêÒìëÔììÔìëÓíëÒîéÑîäÌëáÊåÜÅßÓ»ßÕºäÚÂîéÐíîÞëîáèìêèìêèíëêíçêíåìîãìîâìîáíîÝíîÛîí×îì×îìÔîëÖíêÒîéÐíåÍíæÎìãÍíåÎìåÍìäÌìäÍìåÍìåÍìåÌëäÍìåÍîèÐíèÐíçÏîêÕîë×îëÖîéÔîëÖííÜíîáìîãëíåèìíãèíããìããçãããããããããããêãäíãçíãæíãæîãåíãåíãäìãäëããêãäëããêããêããêããêããêããéããêããêããêããéããéããêããèããèããéããéããèâ‰zÅziÉrh·]W™C+ÁK@»B5ÎM:ÞT=àK<㺆å…NèW9âqRãiãǎãã¨ããëããæ㺖æVB5.  +I<-vfW˜qŽpe{Q=b2a,yA0”\F¤nY°zc±yc°y_±xa«u_«r]­t`¬u`ªq^©p]«q]ªq]¦mY¦o\¨oY¬v]¥pZ¨qZ¥oZ£qa¢q[¡r[škX˜jU—iV‘cLcF‹bH‡cG„bGˆcG†bF‚`D‚`E‚bF`?€a@y[;tZ8yb?t^?q_Bo\?fU8cR3cQ6bR7`Q5`Q5bR;eTn\?mZ?dS7dU9iX;gT:iVnZCo[Bq_Eq\Cn\AsaDubHufGweI{mP|kM~pSrU‚tT†vV‡xTˆyV]^€]^€\Š}XˆyUˆzQŒ}SZ“…\˜Šbš‹c™‰`˜ˆ^›Šcš‰d—†`š‰c—†\˜†`—…]™†_™‡^·¡yÞɤíãÉíêÒíéÌíéÍîçÉíçÉîâÃîâÃîâÃîâÄîáÅîäÇîåÉîçÇíéÊìçÎìêÎíëÍìëÐììÓëìÓëíÔêíÖëìÓëìÖìëÐíèÌîèÏîçÎîèÏíéÒìëÔììÕììÔíì×îëÔîéÒîæÏîçÏîåËíãÊíäÍîéÓííÜííÝíîàíìßîì×ííÞìîâêîæêîãéíåêíäëîäëîãìîßìîßëíßíîÞíîßíîÜííÚííÛîì×îì×îìÖîìÔîêÔîêÒíèÐîèÐíåÎíçÐíæÏíçÑîæÎíçÑíèÕîéÔîèÕîéÔîëÚîëÛïíàììäèèåååæäåéãåìãæìãæíãèîãèîãèîãèíãçíãæîãåîãåíãäíãäìãäíãäìããìãåëãåìãäìãäëãäëãäìãåìãäìãäêããéãäëãäê“SJMC‹E9†>2‘A3—9'œ4(£9%¹>+ÊC/ç}_áV@×= ìI/æR9ã‡\ãܤããÝããâãëÙã©pÀF8%    + F7/o_MŸƒs£p“o_sR9cD4h9.wH:^OœnYšlWšoW›oYšnZ›l\šl\–jV—hUškZ˜kY“kWhQ“jVdOiUgShRŠeN†bI‡bJˆdLƒ_Gƒ_F\CyW>z[CxYAwXApR:oT8pT9mR6nS8kQ6mS7nT:oW=mX>m\BlY=o\Bm\@kZjWs_Er`Es`Fq]BvbGv`B{hJzgJ|gEjF‚lM„nKƒqPˆtR‰wR‹yWŠyV|Y\~Z”ƒ_“‚^Z€Y‘~Y}Z—X–U“€W•ƒZ™‡^›‡^š‡^–„[•‚X—ƒY–X™„Z™ƒZ™„Y—T™ƒY¼§äЬîæÉíéÎíèÊíèÊíéÊíèÊíéÊíæÉîåÇíæÈîäÉîäÊîæËíåËîæËíèÍíçÌíçËíçÎìéÏììÒëíÕéîØèîÜéîÜéíØêî×ìëÓíéÏíèÐíçÑíæÏíéÏîëÓììØíìÙíìÕîëÔîêÒîèÑîéÏîéÏííÚëíåèîèéîèéíèçíëçìëæììåììäëíäëîäêíãêîãéîäêíãèîãéîåëíäêíäëíæëìæììçíéèíéèíèéíçêíèëîæëîèìíãìîâííßííÛîíÙîíÛîìÚîíÝííÝíîáíîÞíîãîíâìîäìîåìîäëïêêîêçííåêîãçíãçîãèîãéîãèíãèîãèîãçíãèîãæíãæíãæíãæíãæìãæíãæíãæìãåìãæíãåìãåìãæíãæìãåëãåíãçí[-k3i.l,o1 €1Ž1’3 Ž-) É:'À*·.â=åV5㵃ãç¸ããéãããããæãÀ„ËP>. +     + E80zgY „y©‹xšhˆnYsSCqP7zT?‹dS–o[—p\—p^˜o]“kV’jX”l]hTiW‘hWjV‹gRŒiRŒhR‡eK†dJ…cK„dL„bL†cM]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~fLeLhO~fMiO‚iP†nTŒrY‡qUˆsSwW‹rRŒtUyWŽyT‘zV‘|W|X{Z“X€V“Y’X•‚]“€Y—„_–€W–ƒ\—ƒZ…_˜…\™ˆ]›ˆ`™‡\œ‡]Š_˜„\˜„[™ƒY˜‚X™ƒ\™„Y—‚Xœ…[°˜nÜŝíàÂíèÏíæÌíçÎíéÍíèÎíçÎíæÌíçÍíèÎíèÎíæÌíèÌîåÈíçËîçÉíæÇîæÇíåÈîæÇîçÉìéËêíÖëíÙéîÙçîÝæîÝêîØëí×ìêÒîèÎîçÍîåÌîæÍíêÐìëÔìíÖììÙíêÕîí×íìÖëîÝçíæäíëäììãëíäììæììäììãêîäëíäêíäëíãêîäéîäéíãèîãçîãèîãèîãéîãêîãêîãêîäêîäêíäëíãêíåêíåêíäêîäêîäêîäëîæëìçíëèíêèìêèìêèíëèìêçìëæëëæëìåëîåêíäêîãèîäéîäêîãéîãèîãèíãèîãéîãèîãèîãèíäèîãèîãéîãéîãèîãèîãèîäéîãèîãéîäéîãèîäéîãçíãèíãèîãçíãèîäèîZ,h2#h+o.o0!v-|/|*‡*™3¯5²/Â3éE*â{Sãè²ããèããäãããããéãË£ß^[? +   +  @6)q`Qœ‚v­’}¤ŠpšlŒoW‚_G†gP˜zg™h˜~h—ud–ua•rb”p^kX’o\‰kVŽgRjVjVŠhQŠhRˆeO†dK†eIƒbJ„aK…aKeL{_D€bJ}`LxaJz`Ix^Fz`Jy]Fy]FuZA{^E{^EaIy]D‚fL‚eL~cJ„jR†iQ‡kPˆlT‡mOˆlP…jKŠnTŠnT‹oVsYsYŽqY’u`r]sZ‘w`‘u]”xb‘w]˜z`™|c–y^˜|_—{^—{^”yZ™~^™€^—~]˜~\—€^—\—[š„[•[™‡_™‡b˜†bœ…a›Šfˆ_™…]œ‡`œˆ_žŠ`žŠ` Œb‰^‰^œ‹`šˆ^š‰^š†[š†\›†\šˆa›ƒY†\ž‹_ʵŒèÓ±îãÆíçÌîæËíèËîèÌíéÏíêÏìêÐìëÓíêÐíêÏíèÎîæÊíçËîæÈîæÈîæÇîæÈîãÄîäÄîåÇíåÉìëÏêíÕéîÛçîÛçîÝèîÞèîÝëíØíëÒîæËîæÍîåÌíçÒíèÔíêÒìíÖìí×ìíÛêîßæíéåíéåíéäìëäëìãëíäêìãéîãéîãéîãêîäêíãéîãéîãèîãèîãéîãéîãêíãéîäêíäëíäêíãêîäëíåììåììäêîãéîãèîãçîãçîãæîãçîãçîãçîãçîãèîãæîãçîãçîãæîãèîãèîãæíãçíäèîãçîãèîäéîãèîäéîäêîãéîäêîåêîæëîäëîæëîäêîæëîçìíæìîæìîåêîäêîäêîåëîãéîäéîãéîãéîãéîåëîäêî_/!d- g,l-j-m(p(t&ƒ'˜.§1´0Ö7*äoeãÜÃãæÕããäããããããããããåØçxsX     + 80"iYE—k¬”~§s§u™~e–zf™zk£†uª‘~¤Œu¢„pœzf™uh•p`—t_’p\“r`‘m_kW“q_o_oZ‹hQŠhR‹iOŒkOiUŒiTŽmWjWkT’pZ‹mVpVˆnW‹oYoY‹jRŽnX‘mX’qZqY•qW—rZšvb™v_—uVva›y`›zdšz^š|[œ{e}d›{aš{]œ~bžcŸ€eœ~gœ}_ž€e˜aœdš€b›_›^š_‚iš~a›\œbœ€e›~]œ~\œ`ž†až…e…b‡cž‡dž‡c ‹hžˆdŸ‹f›ˆežŠfž‹e¢Œc£Žf‹b¡‹a¢c£Œc¥Že©•nª“qª•q¦”k£‘k¢i ‹a¡Šb ˆažˆ_£Žd¸£|ÞÅ îÜ¿îçÌíæÊîèËíçËíéÎìêÐíëÑëíÖêí×ëìÓìëÑíèÎíèÊíçÊîäÆíâÃîâÅíâÃîÞÁîݾîàÀîãÃìèËëíÔêî×èîÚçîàéîàèîáéîáììÖíêÑîåÌîäÉîãËîäÊîæÌìéÒëìØëîÞéîâéîáçíææíèåíéãëíãëíãêîãéîãéîãéîãéîãéîãéîãêîãéîãèîãéîãéîäêíåëíåëìäëíäëíäëíäëíåììåììäéîãéîãçîãèîãçîãèîãçîãçîãçîãèîãçîãçîãçîãçîãèîãçîãéîäêîäéîãéîäêîåêîåëîæëíæìíåëîæìîçìíèíìçìíçìíèíìèíëéíìéíëçìíçíìèíìæìíæìíåëîäêîäêîåêîåëîåëîåëî[.!]- i-k+n*n't*w(€&—+ +´0äD=â{h㳈ãæÍããããããããããããããæéÀ§t"  +    8)o^I„r±•„±—°“{±”z­‘~ºŠÂ¥‘ç•»¢“³›„²“}µ”³“„²‘¶”±Žz«‰v¬‹t§†v¡oŸ}i¡{g›zdšubŸ{f {iœv`¡xe va¢}g {i¤jžzdŸ|fŸ|d¡zd¢xa¡g¡{d©€i¥‚g¥~d¦€i¦€h¨€h¥}c¦f§€i§‚j¦ƒk ~`§€e¦‚l¤‚h£€e§„j¤…i¢ƒd¦…f¥†j c¡‡dŸ„b¢‡d¢ˆf¡‡f¡ˆj ƒeŸ„g›[›~bœ~]¥‡b£‰h£‰c¥j«’uª“m¤Ži¥Žl¤g§‘p¨‘k¦l§Žg¦e¦h§j¨‘g¨“h©•k­•m³œw¶ w¾¬‡Ã­‹Æ²Œ¾©‚ºª€¸¥yºŸy¹ zµœw³›p®˜k¹£zØÝëÙ¾îæÊíéÍíêÎíéÎíêÏììÒêíÔéî×êîÛéîÙéî×ëíÓìëÎîéËîåÈîâÃîãÅíܼîݽîÜ»îÚ¹íÛ¹îݽíåÈìëÐêíÖêîÜéîáèîâèîáçîßêîßìíÖîêÎîãÈîâÄîáÅîåÌîèÐíëÒììÖëìÚëíÝéîàçîãåíèäìëäììäêíãêîãêîäéîäêíäêîãêîäêîäêíäêîäêíãêîäëíåëíåëìäìíæíëåëíäëíäêíäêîãéîãèîãçîãçîãèîãçîãèîãèîãéîãèîãéîãéîãéîäéîãêîäêîäêîäêîåëîæìîæìîçìíçìíèíìèíìèíëèíëêîêêîèêîêéîëêîêéíêéîëèíìèíìçììçìíçìîåëîåëîçìîçìîæìîèííçìîZ+`, i,l-l,n%t(|(‡)—.¥-¹1 ê@/âfDã°tãçÍãããããããããããããääè±­B:I0"L4&S8$N8"SC5WE:\K:r_M”„m¯šˆÇª—ɬ˜Æ«•Äª“Ƭ–͵œÕ¼¢ÚÁ©Ò·¢Ö¹¡Ñµ›Î³œÙ»§Ô¶ŸÓ´œØ¶£Ð«—˨”Àœ‰¾–„·{·yµ•|·”yº“x·’|¯‰q´Ž}³‰w°‡t²‹x¯…o­†n­…o¬„lª„l¨„k¨…l«†p«‰r¬ˆo«‡q«„lª†n§‚i«‡p¨…nª…l«‹q¨Šn¦ˆk§‹n¦‹k¦‹k§Œm¨Žn©ŽkªŒj¯“t®”y²–v°”r³—z³—}·…³´šyµ›|°œ€¬˜r§Žm«‘u¯–|°š}¶œ‚ºŸ„¼¤Šº¤À©„¹£¸¦}¹¢~¸¢‚´¡z¹¢}´u¼¤¸£w½¨„»¤Â«‡Â­ŠÇ²ŽÑÁšÔşÝÍ©ÛÉ¢ÜˤÖǟÒÀ™Ó¾˜Îº”ϼ”Ê´ŒÐ»‘͹ÛǞíÞÀîæÈììÏììÒëìÓëìÓêíÔêîÖèîÚèîÛçîÝæîßåîßéîÚëíÕíìÐîãÆîáÆíÝ»îÝ»îÛ¹íضîÚºì×¼íÚ¾îßÂíèÐëí×ëîÜéîßèîáèîáçîâèîáêîÞìì×îæÊîáÆîàÇîâÈîäÈîäÈîçÍíèÎíêÐëíÖëîÜèîâæîèåíêæíêåìíäëîãêîäêíãéîäêîãêíãêîãêíäëíäêíåëìåìëæììåììäëíäêíäêîãèîãéîãçîãçîãçîãèîãèîãèîãéîãèîãéîäéîãéîäêîãéîäêîåëîæëíæìíçìíçíìèììèíëèíêéîëéíëéíêêîéêîéêîêëîèêîéêîéêíêéíëéíëèíìèíìçììçíìæìîçìíçìíéíìèíìèííèíìY-],g1!h)k)r'w+})Ž)š-£*¼4$ãA7âk]㵁ãçÞããèããããããããããããä½¾Ê{k£~j©ˆo¨†q«Šu¬|¬•„¯—ˆ½¢Ë²š×º¥áðÞįàŸáÉ´äʺä˶ëÒ½ëÒ¿ëÑ»ëÒ¿êÒ¾èѼéϼíÕ½ëйäŴݸ¡Ò¬—Êž“Ä—†Á”ƒÁ”„ɧÍ°Ì®’̬“Ê­‘Ë«–Æ¢‹Æ¦ŽÀŸ‡Á›€¾œ†¾œ‰¹˜‚»™¶”z¸’x³’yµ—z´‘u³“~´–|µ•x´–w´“t´”x¼šz¸š·›€µš}¹ ‚¶œ|¼£ˆº¤ƒ¿§…©ŠÃª‰Â©ŒÅ¬ŽÉ±Ì·—Ó¼¥Î´˜Ï» ÐºšÏ¹šË¶’Å°‹Å®‘Å®ŽË¯“ʵ—Ë´šÐ¹ŸÓ¼™ÖÀŸÖáÔÁÕÄ ÒÀšÑÁ›ÒÁŸÐ¿™Ñ¾—ѽ˜Ð¼™Ò½™×Ä¡ØÅ¡ÚÈ¡ÞʨâϪåÕµæ×¹ëÛ¾êÛ½èØ·èÙ¹æ×µæ׶åÕ²ãÔ²äÓ²áЯßέäÔ³ëÝÄíëÏêí×êîÙéîÛêíÚéîÝéîÞçîàæîáåîãåîãäíäãîçäîäçíßììÕíèËîâ¿îݺíÙµî×·ì׶ì׸ëÔµí×¹íÜ¿îãÈìêÓëíÚêîÞéîáéîâèîãèîâéîáëíÚîéÐîçÏîãÊîãÇîáÆîáÊîãËîãÊîåÌíçÐíéÑêë×êíÚéíàæíèäíëäììäëìäëìãêîäêíäëíäéíãêîäêíäêîäëíäëíäìíåììãêîãéîãèîãèîãèîãçîãèîãèîãèîãèîãèîãéîãéîãéîäêîãêîäêîäêîåëîçìíæìíæìíçíìèíëêîêêîéêíêêîèëîêëîèëîèëîèëîèëîèêîéêîéêîëéîëéíëéíëçíìçììèíìçíìéîëêîêéíëéîêéíëY-g:'d-g'o)p#x*}&‡'–*¤+»4$Þ=3åVVã’mãçÎãç×ããåãããããããããäº栕ཪ߿¬ß¿°âıãǶäɹäȸç̼êÒ¿íÕÃíÔÃïØÇîØÈí×ÆîÛÍîÝÎîÛÌîÚÊîÜÉîÜÌîÛÊîÛÊîÛÉîÖÅêÑÀིѪ–Æœƒºz¶Švµ‡uÀ—Ì­ÜèßȲÝÆ®ÝÄ°Þ°ÜÀ«ÚÁ©Ø¾¦Ô¸žÑ¶£Ò·£Ì¯˜Ë¯Ê°“˲•Ì²”ŬÉ¯Í±œÐ¶¡Ì°“É®“Ç®Ê±“̳—ε—Ï·šÑ¹¢Ò¼¤Ó¼¢Õ¿§Ô½¢ÔÀ£Ø©ÝÇ­ÝɬÞË­ßͱÝÌ°âиåÓ·äÔ¾ãÓ½áиÝÌ°ÜʪÚɯÜɳÞ˱ãÏ´äеçÔ¼åÖ½èÙÀäÖ¼èÙ¾äÕ»äÔµäÓ³äÖ¶ãÓ³áÒ°åÖ³äÕ°åѲãÒ¯âÒ°âÒ±àЮæÕ·èØ»éÙ¼ìÞÃëÝÃëÝ¿êÚ¼ëÜ¿éÙ¼éÚºéÚ»èÙ»éÚ¿è×½èÙ½îâÊíêÔêîÞèîáèîâèîâéîáèîâçîãæîååíæäíçäìèäìéäìêäìèåîåèîÚìèÌîâÃîݽìØ»ì׸ëÕ¶ëÕ·ìÖ¸ìغîÛ¾îÞÃíæËíëÑëîÝéîâêîàèîãèîâèîâéîßëíÛìêÒíéÎíåÌîãÍîáÉîàÈîâÈîäËîãÈíåÌíèÏìëÓêîÜéîâæíéæíéäìëäëìäêìãéíäéíãéîãêîãéîãéîäêíãêîäëíãêîãêîãéîãèîãèîãèîãéîãèîãéîãèîãèîãèîãèîäéîãèîãéîåêîäêîåêîåëíæìíçìíçííèíìêîêêîéêîêêîéëîçêîéëîèëîçìîæêîéëîèêîééîêêîééîëéíëéíëèíìéíëéíëêíêéîêêîéëîèìîæW+k8(d.h)d#q&|+‡'‹#•%¢*¸.Î3(ëG@ä`UãxãÝÆãâçãããããããää宝îØÉîÛÌîØËîÙÍîÛÍîÚÌîÛÍîÚÌîÚËîÚÈîÚÉîÜÌîÛÊîÚÊîÛËîÜÊîÞÌîÚÉîÙÈîÛÉíØÇîÙÈíÙÅëÓÄÛ¼ª¹‚Ÿxd›t]“iQ•mWœp[³zǬàˬèÒ¼èÓ½éÒÀéÔ¾æлæкã͵ãͶâ̵áË´â̳áÇ®âË´àÉ°àʳà˲ßɳÜÇ°á˸ßÉ´ßɳá˵ãͶá̵ãζäÏ·æÑ»åкæÒ¼åÔ¾æÖÀæÕÀè×ÁéØÂèØÃèØÂêØÃëÛÅéÙÂëÛÃëÛÆêÚÃéØÃè×ÀçÖ¿æÕ¾êÙÂè×ÀêÙÃêÛÄìÛÆëÛÅëÝÇêÜÅèÚÂêÚÃéØ¿ìÜÁèÙ½ëÝÀêܾéÙ»èظãÔ´ÝάÖƤϿ›ÑÀœØƟÛ˧âЪæÕ´éÛÁéÚ½éÙ¾éÙÀêÛ½êÙÀèؼéÙ¾éØ¿éÙ¾èÚ¿íàÅîéÓêîÞæîáæîåçîãèîâçîäæîååîæåíçäíéäíêãëëãìëãìëãìëäìéäîäëì×îèÊîáÄîÝ¿îÝÂîÛ¿îÝÃîÝÅîÝÅíÜÄîßÇîãÎíéÔìì×ëîÜèîãèîâèîãèîâèîâéîßéîÚêîØìêÒîèËîåÈîãÈîâÇîáÅîáÄîâÊîãÉîæÊîêÓëíÜéîÝèîäæîçäìëãëíãêíãêíãêîãéîãèîãèîãèîãéîãéîãéîãèîãèîäéîãéîãèîãèîãéîäéîäèîãèîãéîãéîäêîäêîäêîåëîæìíåëîåëíæìîçìíèííèíìéíéêîéêîêëîèëîèìîçëîèìîæêîéëîèêîêéíêêîéêîêêîééíêêîêéîêêîéëîçëîçëîèìîæíîã^0!g3"j2 f&es({*Œ#"”"¡&´(Î3#Ù5!êD2èI;ã“ZãçÉããããããããã屳ﱯîØÆîÙÈîÙÊîÙÉîÚÊîÙÈîÙÈîØÈîÛÊîÚÊîÚÈîÙÈîÙÇîØÇîÚÈîÚÈîØÆîÙÈîÙÇíØÆîØÇíÓÁìÓÀÞÀ«»•}–kR•hV’cR•kW“hR—kW›zc¾£ŠÙÅ«éÓ¼êÕÁë×ÂëÖÁêÓÀêÓÁéѾéѾèÒ¾éÒ¿çлèÒ½çÓ¾êÕÁéÕÁêÕÁéÕÀêÖÁéÕÁêÖÂéÖÁéÕÁêÖÂêÖÂêÙÃéÖÂêØÄè×Âé×ÁéØÄêÙÄêÙÃéØÂêÚÄêÚÃêÚÅéÙÄëÛÆëÛÅìÝÇëÜÆëÜÇêÚÄéÙÃé×ÃêÚÄêÚÄëÛÆëÜÇíÞÉìÜÅìÞÈíßÈëÜÅêÛÄìÜÅéÜÂêܾêÛ½ëÝÄéÚ¾çØ»áѰо›½©©–wŒo¢l¦”mµ£~ɸÖğÜͱæÙ¼êÙ¿êÚ¾êܾéÚ¼êÛ½éØÀéؽêÙ¿è×½ìÞÄîçÐêîßçîäæîæèîãçîâçîãæîååíæäîèäíéäìêãìëãìêãìëãììãìëäìêäîèçíàêíÙìéÐìêÐìéÍíéÐìêÔìêÓîçÏîâÉîäËîâÈîèÏìëÕëîÞëîÝêíÞçîäçîäçîàéîáêîÞìíÛíêÐîçÊîèÊíæÏîåÌîâÆîäËîãÉîãÉîåËíéÑíéÏëíØêíÚèîãçîçæîêäìëåëìäéíãéîãéîãçîãèîãçîãèîãèîãèîãéîãèîãèîãéîãèîãèîãéîãéîäéîäêîãéîäêîåëîåêîåëîåëíåëîæìîæëíçìíçííéíééíëéíëêîèêîéêîèëîçëîéëîçëîçìîçêîéêîêêîééíëéîêêîéêîèëîéëîèëîéìîæìîäìîãc4$i9'r:%m1u2 z,‚(ˆ"!›!¡&·/È/Û8(ä8é?(ãk>ãÕ¯ããäããããçê坌멕îÔÃîÙÉîÖÆî×ÈîÚÉîÙÈíÕÅîØÈîØÉî×ÇîÖÅî×Æî×Æî×Æî×ÆîØÇîØÆîÖÅîÙÇîÖÄíÕÃíÖÄêϻҲ–£zccLcM’fO“fOŽdI’kT—za»¡‰ÔÀ¨éÓºëÕ¿ë×ÁêÕ½ëÕ¿êÔ¾éÒ½èÒ¾æÒ»çÓ½èÔ¾éÕ¾êÖÁìÙÄìÙÅìØÄë×Âê×ÃíÙÅêÖÂéÕÂë×ÃëÖÂë×ÃìØÄìÚÆëÙÄëÙÄìÚÅêÚÄëÚÅêÙÃêÜÇêÛÅëÚÆëÛÆêÚÅëÛÆìÜÆìÝÇìÝÇëÜÆëÛÄêÚÅëÜÆêÚÅìÝÈìÞÈìÝÈìßÉìßÉíÞÉìÝÇìÝÆëÝÆëÜÄëÜÂéÜÁëÛÃêÙÀëÛÀãӳ͹“­™r–€_†qGygBvdAr_8mF”U­šsѾŸÙË«æÙºéÚ¼êÚ¼éÙ¾êÚ¿êÚ¿éÚÀêÚÁêÙÀìÞÅîæÐêîßçîãæîåçîãçîãçîâçîãæîæåíèåíèäìêäíéãìêäíêãììãëëãìêäìéåíçåíååîãåîáåîáåîãäîäæîáèîßëíÛíëÖíêÕîçÏîçÎíë×ììÚêîÞêîàèîãèîäçîäéîáèîáéîÞêíÚêíØëìÖëíÖìëÓëìÖììÖîêÎîçÏîæÊîæÌîæËíêÑíìÖëîÛéîâçîçåîéäíêåììäëëäêíãéîãèîãèîãèîãéîãéîãêîãèîãèîãèîãéîãèîäéîãèîãéîäéîäêîãéîãêîåëíåëîåìíåëîåëîæìíçìíçìíéíêéîëéíëêîéëîéìîæëîèëîçëîèêîééîéêîéêîêéíêêîééíêêîèëîèêîèìîçìîæìîäìîäc;,wE0}E%?%‡<%‡/†(‹"™&£#­(µ/Ã2×7"Û4ç<,âqMãÂããêããããíÙç^ߟ|îÕÁîÔÆîÖÆîÕÈîÔÄîÕÅî×ÅîÖÅíÕÄîØÆî×Çî×ÆîØÆî×ÆîØÆî×ÆîØÇî×Æî×Åî×ÅîÖÅíÔÃè͹ĢŠšmWcKdJbMeRdQkWž‡k½«ÞɬêÕ½ëÖ¿ì×ÁêÔ½ìØÃéÒ¾çÒ¼çÒ¼çÒ¼éÔ¾èÔÀìØÄê×Áê×ÂìÙÅëÖÂìÙÅìØÄìÙÅëØÄê×ÃìÙÅìØÄëØÄìÚÆëØÄëÛÆé×ÂëÛÆëÛÆéÙÄêÙÄìÜÇëÜÆëÜÆëÜÆëÜÆìÜÆìÜÆìÞÈìÞÈìÞÈìÞÉëÛÅéÚÄëÝÆìÝÇìÝÈíàÊíÞÉìÞÈìßÊìÝÈëÞÅëßÇëÞÃëÛÃéÛÁêÜ¿ëÝÂèÙ»ÙÆ£¹¦~{W„pO…oL~kIua-‹?0‰0'—&Ÿ(¬,»1º+Â+Ñ4Õ5êC.ã[C㼆ãäåããããÚ¹éiMà™yîÔÀîÕÆîÖÅîÕËîÕÄíÓÆîÖÈí×ÊîÖÊî×ÉîØÊîØÊîÖÄîÙÊîÙÇîØÇîØÇî×Åî×ÅîÕÄîØÇíÔÂãÄ°º‘~dQcL‰_D„]F‹eRhSt[«’tλœæѵì׿ìØÄíÚÅìØÄì×ÃêÖÀéÕÁêÕ¿çÓ½èÕÀëØÄì×ÄìÙÄìÙÄëØÃìÙÅìÙÃìÙÅìÙÄëØÄëØÄíÚÆíÚÆíÛÇìÚÆëÜÇëÛÆêÙÄëÛÆêÚÅêÚÅìÜÇëÛÆìÝÇìÝÈìÝÇëÜÆëÜÅëÝÆíßÊíáËìÞÇíàÊëÜÇìÜÇëÛÆìÞÈîáÌíáËîàËíáÌìàËìÞÉëÞÈêÝÂêÝÅéÛÀêÜÀèÛÀëÞÃèؾØǦ­vˆuPnM‚kLlLyd>mX2fS.dQ.dQ1xhG¥“nϾšâÒ³ëÜ¿ëÞÂëÜÁëÜÁëÝÀíßÅìàÇìàÆîäÍìíÙêîàèîãèîáèîâèîâéîâèîäèîäæîåçîäåíèåíèåíçãíêäíêãìêãìëåíèåíçåíæçîãèîáèîâéîàêîáëîßêîßìîÝìíÜìíÜíìÙîë×îèÓîèÓîèÓîèÓîêÔìíÙììÚêîÞëíÝììÙîçÎîåÉìèËêîÙêîßéîàéîàèîâéîßìíØíëÐîèÊîçÇîåÆîåÇîèÌîèÐîëÑíí×ëîàêîäçîççíêæììäëíäëíãéîãèîãçîãçîãèîãçîãèîãçîãèîãçîãèîãèîãèîãèîäéîãêîäèîãéîäêîåêíåëîäêîæëîåìíçíìèììèíëéîêêîéêíëêîêêîêëîèêîêêîéêîëëîèêîéêîéëîèëîçëîæëîçìîçíîäeB“eJ™gM‡E8”F5Š/’*—(¤+¯(®,¶*Å/Ê4Ô6êB*äZ;㹇ãèÞããêãÛºçgOږ{ïÔ¾î×ÅîÖÇîÓÉîÕÈîÔÇíÕÇíÕÇîØÌîØÉîÙÊîÙËî×ÈîÙÉî×ÆîÚÉîÙÇîÚÈî×ÅîÖÅîÖÅîÕÀܶ¥­‚nfNŠaH„_EˆcK†dNŠkQ¢Žw¬•àͶëØÅíÚÈíÚÇíÙÆíØÅìÙÄíÙÅêÖÂéÕÁéÔÀëÙÇê×ÃëØÄíÛÆìÚÆíÜÈìÙÅìÚÆíÛÆìÚÆíÚÇíÛÇíÛÇìÚÆíÛÇíÞÉëÜÇëÛÆëÛÇêÚÄìÝÇëÛÆêÛÅìÞÈìÝÈìÝÇìÜÇëÜÆìÝÈìÝÈíÞÉíÞÊíàËìÞÉìÝÈìÞÉìÝÈíßÉîáÌîãÍîâÍíáÌíáÌíáÌìÞÈêÝÄìßÆéÜÂëÞÆêÝÃéÛÂèؾÚʪ¶§ˆ‘€]}gHyfCub:ta*¤5 ¨4®2®2´2¸4"¼2Å3ä>(íA'â^AãǗãç³ã߶êdEؒnéèÒäîáæíßçëÜéèÛëå×ìäÒìßÔîÞÏîÝÎîÚÌíÚËîÚÉîÚËîÜÊîÜÊîÛÉîÚÈîØÇîØÇíÔÆáÀ³­‹vkRŠlQ‡fM‰kPŽtV†s·£ÜɱèÖÁíÙÃîÛÉíÜÈîÝÈîÜÈíÚÇíÛÅìØÅêÖÁê×Ãë×ÂìÙÅìÛÇíÜÈíÝÉîÞÊîÞÉîÞÊîßËîßÊíÜÈíÜÈîÞÊíÝÉîÞÊîÝÉíÝÈîàÌíàËîßÊíßÉíßÊìÝÈíÞÉíßÉíàËíàËíàËîâÌîàËîâÍíâÍîâÍîâÍìßÊìÞÉìÞÉëÝÈíàËîâÍîäÏîãÎíáÌìàËìÞÉëÞÈéÛÄêÛÄêÝÅëÞÆìßÇìßÇëÞÆëÝÅèÚÂáÒ¹ÕŨ̴™·¤„«–|™‚_ŒxX‚nGjGxfߥDڝ7֝5Ý«Nã´\ç¿séĄéЛëҞìÖ¦îÜ´îåÊíê×ììÙêíâêîäéîéèíëçíìæííåìíäëíäëîäêîãêîãéîãéîãèîãæîãçîãçîãçîãçîãçîãçîãéîäéîäëîäêîåëîåëîæìíæìíçìíèíìèíìéíëéíëêîêêîéëîèëîèéîìèìíìÞÉæγʩŽ£xV˜d@œU6Ÿ>%ž8%1¬5±5"´4"°0¹4"¿8 Ò=,æD/éJ/ã˜oãœjã‹ià\GϕpèéÔãíìãîéãîèãîèãîçæíâçìàééÚêèÚìäÖíäÕíáÐíßÐîÛÊíàÎîÛÊîÚÊîÛÎîØÈíÑÁÓ³Ÿœy\“rVpV‹nVs[–z`ª–Ð½§éÕÂëØÈíÛÈîÝËîÝËîßÊîßÌîÜÉíÚÇìÙÅëØÅéØÃèÖÄé×ÆêÚÇîÝÉîÞÉîÞÊîßÌîáÍîßËíÝÉîÞËîÞÍíÝËîÝÌîÞÍíßÎîáÎíßÉíßÊíàËíßÊîáËíÞÉíàËíàÌíÞÍîâÌíâÌîáÍíáÌíáÌîãÍîãÎîâÍîáÍìÞËëÜÇìßÊîáÌíâÏîäÒíâÍíãÏíâÍìßÊëÞÇêÝÄéÛÄéÛÂéÜÃëÝÅëÞÆíàÈìàÈìÝÇéÛÃäÕ»âÒ¹ÖĦϺ¢Â©Œ²ƒ§“u•ƒ^zN‰wC‚qD˜|NђMéœ>å Gã²fê͔ëܽèÜÅìßÈìßÊíáÍîæÑíìÛëîàèîâçîèæîæçîåèîãéîáêîßìíÜìîÝìíÜííÛìíÜíìÚíìÚíìÙíìÚîëØííÚíëØíìÙîìÙííÚîëÙíìÙíìØîìÚíìÙíìÛíìÙííÚíìÙííÜëîàëîÝêîáìîÜííÛîìØíèÑíãÊëáÄêÜÁêܽéÛ¹éÚ¸èسéНêɆêÅ~éÂwìÆuíÈuè»\å­Nߟ;ޙ2ޟ7ݚ5ؘ4ҏ%ё(ԛ4Ø¢DÚ¨PÛ©QÝ®[Ü­\æºpêȆìОîÛ±íçÇîëÔííÛìíßëîåëîâêîèèíèèîêçììæìíäëîäêíãêîãèîãèîãçîãçîãçîãèîãèîãèîãéîãêîäêîåëîæëíçìíæìíçìíèííèíìéííéíìéíìêîëéííçìîçìîëêÛîãÍÜ溒wªwU‡B%™;*›='Ÿ7¦6¬4¬3ª0¶5´1¸6À;!äA/ãlVãoMäqVÞ]G̎oêçÔãîëãíëãíëãîëãííãîëãîçãîçãîææìßæíßçëÛèéÚëåÖìåÔìäÓíãÑíàÎíÞÍêл¼›†™va›w^”sX‘tY“vZ¢Šn»§ÝͱêØÅíÞÍîÝÎîãÒîæÕíæÓíæÖîäÓîàÏíÝÌëÚÉêÙÈêÙÇìÙÈíÚÉìÛÇîÞËîÞÊîáÌîßÌîßÍîßÎîßÍîÞÌîÝÊîßÌîßÌîßËîáÍíßÊíàËîâÍíàËíàÍîáËíâÌíáÌîâÍîäÐîáÌîãÍîáÌîäÏîäÏîäÏîåÏîãÎíâÌëÝÇìßÉíàËîäÎîçÑîçÒîæÓîçÓíäÏíâÌíáÊëÝÈëÝÆêÝÆêÜÅëÞÇëÞÇìßÇëÞÅìßÇëÞÇìÜÆèØÁäÕ½ÝɯÙǯ̺ È²—¾§®œm¥Š[ĐXä•Kå”8àŒ+Ն'ä®ZëÓ§çÜÆìßÌíßÊíàÌíãÏíê×êîãæîææíæçîäèîäêîàëîÝìíÝííÜìíÛìíÛìíÝììÛìíÛííÚíìÚíìÚííÜííÚíìÙííÚííÚíìÙíë×íìÙíìÙííÚíìÙíìØîë×íëØíìÙîë×íë×îëÖîëÕîèÐíãÇçÜÁãÓ»àέÛÊ¥×ǤÜ˧äÒ¨æÕ©æÑ£äōä¼tçÁ{çÁxèÀqíÉ|êÄkç­Qߟ@ä«KáªGܜ6ٔ-ՌʇЏ#ӕ-ѕ/ך6֚2՛5Ә)В'ٝ8Þ©YáµqéɇíÙ§îâ¾íçÔîèÒíìÛíîàìíäëîäêîèéîêèíëçìíæìíäëîãêîãêîäéîãèîãèîãçîãèîäéîãêîåëíåëîæëîæëîåëîçìîçííçìîçìîèíîçííçìîæìíäêîêìÞìêÔâ˲ȥ©€a€I*‡6$žB0’7!›8¥5!¤5ž3©1¯6 ©5´9Õ='íVFêZFèeSÝ^H̒oêçÎãíìãíëãíìãíëãíìãîëãíëãîêãîêãîéãîèãîäãîçãîääîâåíâçëÜèêÛìäÔäƵ©‡už{ež{e—y^‘uZ˜~g­—†ÖªìáÌíåÓîç×ìëÙéíâèíáçîãéíâìëÛíèÔîäÐîáÏìÞËìÜÊìÛÈíÜÈîßËíÞÊîàÍîàÎîáÐîßÎîßÎîáÏîßÎíÞÍîáÎíßËîáÎîáÌíáÌîâÌíàËîáÌíáËîàÊîáÌîäÏîâÒîâÑîãÓîâÐîæÕîäÒîçÓîæÑîèÓîçÓîåÐíâÌíáÉîäÒîæÑíë×ììÝíìÛììÛíìÛîêÕîæÑíâÍíâÌíâËìÞÈíáÉîâÌëàÈîãÌíâÌíáÌíáËìßÉíàÊìàÉêÚÂêÝÉåÖÁâÍ°ÖâͭzàžTæ”Fڈ/Ï|Æs +˃$߯aèϚçØ·ìÞÆîåÓîæÒîéÕêîäçîåèîäêîàéîàêîßëîßëîßìíÝìíÛìíÜìíÜëîÞìîÝìíÜìîÝííÛíìÚííÛíìÚíìÙîëØîëØíë×íëØîë×îë×îë×îë×îéÖîèÓîèÐîèÎîçÑîæÐìáÆèÛ»ÔŧÀ´™º¨‘¶¢€Á¨†Â¯‘Ò½•àÌ ãÔ¨çўå…ã¹oç¿oâºjâ¸këÈ~íÊuã°Mä¯PèºXå¶Tá¤@ې%֎Ή˄ˈ̍#ё)ғ'ԕ-ӓ*ʉБ)כ;՚7җ<Û¤Uâ®iéŌìϞíÛ»íàÌîëÙîëÜííáìîÛìîáëîçêîëéíêèíëçíìåêíåëîäêîäêîäéîãéîãéîäëîåëîãéîåëîåêîåêîåëîäëîäêîåëîäëîåëîåëîæìííáÌêëÚèÙÂÑ®‘º”x‚Z:t< ?)Š8 ”6›7%˜56! 13 5¬3Á7 ÚI2ëP@îXIãcKƍhêãÈãíëãíìãîëãíìãíìãîëãíìãíëãíìãíëãíìãíëãîêãîéãíéãîèãîåãîåëåÓ×·¦œ{j¡~fŸ{b›}b”z]†lð™ëÞÉìëÚêîãèîèåíèãîëãîíãíëäîææîåêíÚììÖîèÓîåÏîâÍíàÌíßÊîßÌîáÍîâÍîáÎîãÏîáÐîãÑîâÏîáÏîáÏîäÎîâÍîãÎîâÌíáÌíáÌîäÏîåÑîåÏîåÑîæÒîèÓîêÕíêÚîéÙìëÛìêÚîëÙíëÛëìÛëîßëîáíìÜîéÓîçÏíé×ìíÚèîæçíêéîäëîâëîåìîàíëØîèÖîèÔîçÑîéÔîæÒîèÔîçÔîèÓîêÒîèÒîçÑîæÑîåÎîæÐîçÑíêÕîêØìêÖíáÈäÁ†âžAà.Î{½h ·aµdɃÛ³]ÝɘçÔ±íßÉíåÕîèØìîâéîæëíÝíéÖíèÖêîÞêîßëîÞëîßëîßìîÞëîÞëîßëîßìîÞìíÝìîÝííÛìíÛììÚíëØíìÙíìÙîëØîëÖîêÖîêÕîéÓîèÑîèÐíåÎîãÊíâÊëÞÇèؽßÏ°Ç´ŽžrzlOqa:{jE”}]£Œc¼¤~нŽÔÓÝÁŠä½æ¿wã½nߺjÙ±^éÈzëÈxã·Yé½^â¸Yß´Mä²Mߢ;ݟ3ۚ/֑%я"ʋ͎!А%Ϗ'ԗ0ї0ٞ=ڗ9Ј$Æ~½u+Ä}+¿}$Ɗ6̓GرtïÛªìâÄîèÖîêÓííÛííßìîåëîçêîçéíêéîçæíìéîêçíêçìëæëëæìíåëîæëíäëîäêîãèîãèîãèîãéîäêîäëîåìîçííèíìéîêíåÔëëÛíÝÈáǫȧº–z~O3€G-„H-ˆ74‹5Ž3”3—5¡2 ¶6$Å7 Ì:çL=ïXSÚ_GŌdéÝÇãîíãíìãíìãííãíìãíìãííãííãíìãííãííãíîãíìãíêãíëãîêãîêãïèìßÊ´™…–yez_šw\—zb•€e§˜€ÛпìêÙæîçäîêãìíãìíãëîãìîãíìãíìåîåèîßêíÞììÚíìØîëÖîè×îæÕîçÖîæÕîæÕîæÖîè×îè×îåÓîçÔîåÓîçÕîçÓîèÔîèÔîèÓîêÕîèÓíéÕîë×íë×íëØìíÛëíÞêíâêíãêîãéîäéîåéîåèîåèîæèîåêîåëîàííÞîëÙììÝéîäåîéçîéçîèêîæëîãìíÞíìÜíëÚîêÙíëÚîë×ííÙíìÙíìÙííÙíìÙíìÙîëÙíìØíìÙììÙììÚìíÝëîÞëîÜíäÓ湃ߍ,ۈ$Ãn¹^­UµbÉ{ޟ<à²`Ú½‚âɟçÚ¾íâÊíêØíìÜîçÕìÚÇíßÇíìØêîßêîáëîàêîáêîßëíÝêîàëîßêîàëîßìíÝìíÜìíÚíìÚíëØîë×îêÖîèÓîèÒîçÐîæÑîçÐîèÐíãËìßÆè×ÂãÔºÚʳϾ¢¸¤€šŠjtfGcS1`N)]M&bU,qb5€n=”L«•ZͪkåÀ~æÁtã½râ»nݳ_ß»i߸fÒ¥JÜ°QÜ´Vá¹ZåÁ_ãºUä·Oä®Dڞ4ד&Ԕ(Ғ'ؘ-֗1ӗ2Ý«LåºcמBºn ¸g·m¹p·qµq°m ¯qǑIäŽêÐ¥îÝ·îåÌíìÕíìÜìíãìîàìîâëîâìîâìîáìîáìîâìîãêíçéîééíëæììäëîäëîäêîãêîæìíèîéêîäëîáìîäíìÞîé×êìÙìêÙíåÒìÚÈÓ¶™Ò²•›t]yN-I)}>‚:‡7Š62”7 5©2µ-Í9'ìVEíVMÛaK†céÔÀãîîãíìãîìãíìãíìãíìãìíãíìãííãíìãíëãíìãíëãíëãîëãíëãîëäîäåÒÀ™ƒnŽrYoYmR”zd™ˆoµ¦•èÝÍêîßåîèãíìãìíãìíãëîãëîãííãíëäîçåîèèîåêîâëíáêîáëíàììÝëíàêîâìíàëîàëíàëíàêîâëíãëíâëìáììàììßëíáêîáëîàëíáêîãéîáéîâèîâèîäæîæçîèåîêåîéåîéæîéçîèæîéæîèèîçèîçëîãìíáîëÚìíàèîæäíëæíëçîèêîæêîæìîâíìÛîëØíìÜííÝííÝííÜìíÞííÝíìÝìîÛìíÝìíÜííÛìíÜëîÞìîÝìîÞêîßëîÝìԵ֗OӂÈw ½i°VºfÆz؎%ܑ)ܑ3Ù¡ZÐ¥j˳ØÝêÚÂîâÇíßÇäÓ¸âαîàÊëîÞéîáéîáëîàìîÝìíÝëîßìîÝêîáêîàìîÝííÝíìÚîì×îèÓîéÒîæÑîãÍíáÅìàÅìßÃëßÁëÝÂãÔ¹Ú̪ÓĤÀ°¶ †¢lZˆxW{iD„rPxfDp]3j_3eV&iWo\&‹s6Õ®jéÃãÁrߺgàºgã¾iÛµdÒªYØ­T߶Wã¾eèÆmçÅkäÁ\ä»UÞ±GݨB՟3ҕ'Ќ"Ԏ$ҏ&ҕ.ã½aêËvÚ­Q¹u¹p¼yÀ|¼u²l ¯o °q±r´w&ȓFÜ®gèʐíÚ®îÛ½îäÌíéÓíìÚíîÜíîßíîÞíîÞííÞíîßíîàìîâëîçèíçéîèéîæéíâìíÞíêÛíéÖîæÒîåÐíâÍîãÍîäÎçíÜìæÕîâÏíâÏ஡†¬‹v›rUP1|E$:!‰;#†53Ž0š2Ÿ2¦*Â8'ëSEîXQÔZF¾aè϶âîìãíìãíìãíìãíìãìíãíëãíëãííãíìãíìãîëãíëãîëãíëãíêãîêéèÔÓ¸¥wcŽoVŒmV’t]•{c ŽsʺžíæÏçîäãíëãìíãëíãêîãëîãìîãííãíêãíéåîçéîãéîåéîáêîáéîãéîäéîäçîèæîèæîéæîèçîèæîèçîçæîèæîêæîêæîéæîèæîéåîèçîçæîææîçæîçåîçæîçåíèåíêåîéäíëäîëåíêåîéæîèçîèçîéçîçêîäìíÞìíÞìîßçîëäíëåíêçîééîåéîåëíáìíÝíìÛìíÝîìÙìëÜííÞííÛíìÚìíÛìíÝëîÞìíÜìîÝìíÜëîÝëíßëîßéîßíê×ඏËy6ËzÉw ÀnÅt +Í|׏*ޒ7օ#Õz"Íz)Ā8¯{7£ƒFº§päÓ³íÜÍìÜÅãиëÛÅíëÖéîßëîàëîÞìîÝìíÜìíÜëîßëîÞêîáëîÞíæÐíæÍîæÏìßÇíâÉêÞÄãÔ¶çÚ¹Þϲ×ȤÜΫ×ɦ˺Ÿ»«­›z ‹gšb–\’€\]|S‘Z‘€Y’V‰{R‹uJ–|H¥B·’MäºoçÂvÞ¸nÞ¶gÜ·cߺfߺhز]ݶ^á·Zá¾däÂjß»bÛ¶SÞ´QÛ±NÜ­GÖ£;ҝ9З3Ȋ"ҍ'ђ,äÁeãÃjÖ¨GÀƒ"ƅ$ʐ2Ƈ&ºu´k¨f¤f¤g©m +°t¹}ɓ:Ú¨SÚ«Zá¶yçōíÖ¥íâÅîéÕîìÙîíÜîíÛíîßìîÞìîßìîáìíÞîíÛîéÔîæÏíåÍîáÌíàËíßÉîãÌîáËîãÌîâÌéêØìçÔîÞËîÞÌëϹѰ¹œ€›uXˆ[:~L.y7"~3ƒ5ƒ1‚/ˆ3—3§-¶/áK=îUQÚ\KµwUãʱãïëãíëãíìãíìãíìãíìãíìãíìãíìãíìãíëãíëãíìãíëãîëãîëãîáêÒ¹µ’|£|i¥yd¦zf¢{gœ}h¨‘xßгìíÛæíèãììãìíãëîãëîãëîãìîãììãíìäîèãíèäîçèîæéîáéîâéîäèîäçîåæîéåîêäíëåîêäíëåîêäíêäîëäíëåíëäíëäîëäíëåîêåíêåîèåíêåîéäîêåîêåîéåíéäíëåîêãíìåîëæîéäíêåíëåíëèîçéîäëîâìíàëîÞçîèäìëäíëæîêæîéèîèéîãëîáìîßìíßëîáìîßìíÝíìÚííÛíìÛìîÜìíÜìíÛìíÛííÛìíÝìîÝëíÞëîàíâÈΔ]Åq$̈́ЀÉzÊyÈvÎ~ÊyËrÌvÀj¼eºn+¯v7”q.®™`áʳîßÎíÞÊìÝÊîêÖëíÛìíÜíìÚîì×îíØíìØìíÚëîÝëîÝíí×áÕ¸äÙ»ìßÃÞЯå׳áѯÓÄ¢ßÍ«Ç·Ž¼«‡Â³’¹¨†¨•qœ‡^œ‡_Ÿ‡eœ‰d›†^œ‡^Œl£’r¨š{­ž{­žy¼ª‰¸§zÁ¡gܪdêÀsëÅuçÂrÞ¸jÜ·fÞ¹fݸgß¼há½jܶ]Þ¹\á¿iß½cׯSܵYá¼`ß¹]ÞµTשFÕ¨DÒ¡>ď/Ô AÙ¨Gà¸^ײTСCƓ7Ŕ>Ï GΜBÇ#µo¨c¥g¡c¢hªo©n ±{¿‡%͓:̓C̗7Ô£Há¹oëÕ§îéÑíìÞìîâëîâíîßìíâîëØîèÔíåÑíàÌîáÌíßÊíàÍîâÏîâÍîåÐîèÒîèÓîéÒêêÖëçÖîßÍîÙÁíÔµáÁ Ì¨’kI`?€U4r= }<#|7}5.}+—/¡%²4ÚF<íNHÚWL¶rTãĨãîèãíìãíëãííãíìãìíãíìãìíãíìãíëãíìãîëãíêãîëãîêãîéîàÌѨ˜¹ˆr¶€l·‚nº‚n®€iš~d°›‚éÛÄéîáåíæãìêãëîãëîãëîãëîãìîãëîãìíãíëãìêãíéåîçèîåéîãèîåéîäèîåæîéæîéæîéäíëåíêäíìäíëäíëäíëäíìäíëäíëäíëäíëåîêäíêäíéäíêäíëäíêäìêäíìãìíãìíãëíãìíãíìãìíãìíäììäíìçîçéîæëîáëíáçîéãìîäëìäëíåíìäíìæíêéîåéîäêîâéîåëîáëîßìîÜëíÝíìÙííÙííÙìîÛìíÛëíÝìîÜìîÜëîÞëîÞí۽їNЋ,Ӑ'ËÅrÂpÀj¾k ¼h Ãi Âi±^µ^»eÄu+½x.šu1´žeæÕµîåÑíé×íëÕíìØíìÖîçÒîèÒîçÍîéÒíìÖíîÛìíØîéÓÍÀ¡ÙÇ©æÓ±ÑÁ˜×Á›Ò¼•¸©€Í¹–³Ÿ{£“l¤”m›ŒeœŠg›‰a¡Šd Œj¤’m¦”n¬›u¸¨ŠÁ°’̼¤Ë¿¤ÖÇ©ÖÇ¥ÙË à¼~è¼nëÄuëÆxâ»hÞ¹iÞ¸fز^Û¸dâÁnß½hݹ`ß¾gß¿iÙ³VÖ¬Qܶ\ß¿dÛµ[Ñ¥AÑ¥@ϧEÒ¥HÓ¥FàµYã¸bâ¾iÔ®YѦOΜ?ɗAÏ¡IÖ§Nĉ&²r¤_Ÿ_ž`¢d¥j«r­t¶Á‰.À‰8¿ˆ(‰ɕ5Ô£RäŌíìÖëîäíîßîë×îç×îâÌìàÉìßÇìÞÇíàÉîáËíãÌîåÏîæÐîèÓîåÏîæÑìáÌéêÙéèØìäÓîÖ½íÓ¹éʬ߽ ¢|]—lOŽc-ßM@æe[Í{g⻞äîâãëíãëîãëíãëîãëîãìîãëîãìîãìîãìîãìíãìíãííãîèëÚÅǜ…¸€i¸n¶j¹l¹u©{e¥‰pÖƱìëÜæíìãíêãëíãëîãëîãêîãéîãéîãêîãéîãêîãéîãêîãëíäíêäíéäíéåîçæîçåîçäíêäíêãíëãììãììãëîãìíãìíãëîãëîãëîãëîäìíãëîãëîãëíãëîãëîãêîãëîãêîãêîãéîãéîãéîãéîãêîãêîãéîãêîãìíåíééîæèîèãëîãéîãéîãéîãëîäììäìêåíéæîæçíæçîçèîçêîãëîßêîÝííÙíìØîìÖííÙííØííØìíÛìîÜëíÛëîÝíߺףTם>Û¥DØ¢CԖ9ω(Ào¼h +Ái ½h »h®`±` ©\¯` ³c¼j Êy,ˍ>äŎîåÉéîáììÞíâÉãÓ´ØÉ¢ÔÆ¥ØÄ ÛɪÛ˪տš®wŒ|N¡‹b—…]ŠzQ—ƒW’S‘V†uG~O Že¥”h°Ÿw´¢{»ª„Ŷ’о—ÔÆ¢ÝÍ°ãÖ½åÛÁæÝÂèÝÄçÝÄèÞÄçÜÄàÒ°âÀ†æ¼oä½là¹gÜ·^àÀlà½hÞ¼dâ¼dä¼`ܵZÜ°VܧEԙ8Ɉ&Ä|¹p³v³zОAÖ«JÕ­Uß¾fâÂkܶ^Õ±_Û¸gÙ¶eË£Kș?ɚBѤOРKŌ/¶u¨f¢e d¡g¢h¢j¢m¨s´»†¸ƒ¹…¹†Đ,,ɖAÙ³xéÔ§ëÝÁëÞÉíàÉíâÉîäÍîäÍîäÎîáËëÝÇåѸÚƟϸ“Ç­†Ãª€Ç«çìÜäíàçìÚíâÎîÚÇìθí϶հŽ›qNžuXa?ˆ\9ƒN1„F+‡?"‹:—9!Ÿ4¢3¸@/×XKäibԀnß»¢äîÞãëíãêîãêîãêîãêîãêîãëîãêîãêîãêîãëîãìíãíìèèÙܶ¡¼…r¹~i¸n·€n·m¹€sª|f°˜çÜÊèíçäìíãëìãêíãéîãéîãéîãçîãèîãçîãçîãèîãèîãêîãêîãëíãëìãìêäìêäíêäíéäìëãìëãëìãêîãëîãêîãêîãêîãëîãêîãêîãëîãêîãëîãëîãêîãëîãêîãëîãêîãêîãêîãéîãéîãéîãéîãêîãéîãéîãéîäìíåíêçîèæíêãëíãèîãèîãéîãêîãëìäëìåíéäíêæîèæíèæíçèîåêîàëíÞìíÜíìÙíìØîì×íìÕíìØííØìíÚìîÜìîÜìâÅÙ¬lԜDÙ£BÛ§EÛ¨EӖ1Å|Ê}Ær¸g´d ­^¯_´b´d¹iÀm#Êw"́"כBèȈîäÇíåÎâӳѿ›¼«†±ž©—u©™s¶¡z¬•kŠuLwL‘zMŽzN’|N˜‚S•‚P’ƒUƒsA’„Nµ§yʺÉº”ÖÇ ÝͧâÕ´å׺éÜÀëÞÄêÝÄéßÆèÞÅéßÆéßÆéßÇêàÉãÕ®Þ·oÞ²]â»eÜ´[߸_à¾gß½eß¹^á·Vã°Mß°Lá­KÞ§BÝ£>ٙ:˄!¼p ¶s±r°r¸…%ǝCß¿iäÅuëËxæÄwÕ²bØ·hęD:˝GÏ£NТM˓:ºx±o +£f¡f¢g fŸh¨t ­x¯{·„³€¸º‡!º†¿‹&Ő5őAݸzîÛÄîàÌîäÎîäÎîãÌíáÌêÙ½ßÌ°ÖÀ¢Ï²Ç«ƒ¿¢wĤ}ƨжŠäìàäíáäíÞêæÔîÚÉìλîҽ߽§µ‹u¤}`£xTmCŽY7…I)ˆI'ŒD ”C—<›7µD0×_Zètf؇qÞ¹¡åíäãêîãêîãéîãéîãéîãêîãéîãêîãêîãéîãêîãêîäìãìͽÀ~¿„s»‚o·€j¹‚m¸ƒo´€nª€eÀ¬”íæÑäíëãêîãéîãéîãçîãçîãèîãçîãèîãèîãèîãçîãèîãèîãéîãêíãêíãëìãìëäíéäìêãììãíìãëíãëíãêîãêîãéîãéîãêîãéîãêîãêîãêîãëîãëîãêîãêîãêîãéîãêîãéîãéîãéîãêîãêîãéîãéîãéîãéîãêîäììäíìçîéçîéãêîãèîãçîãéîãéîãéîãêíäìëäìëäíêãìëåìëæìçèîãëîÞìîÛíìÙíì×îëÓîëÓíì×íì×ìíÚìíÙìíÚíêÒÞ»ƒÊ“AȌ,˕2̘6Lj$Lj$͋&ʂ"¼m ¹f¸e²d +±^´f¹lÂrÌz!Ìzԉ&ٟJèʼnæ̡쑶žužŒdxN†tF‡X£ˆY”|G‰tDŽwCxF”~NžM¡†T´”^¹Ÿe¤‘[¹¨xÕĕßѤâÕ±çܼéÞ¾ìàÂëàÆìßÄëÞÅìàÉéÞÅëàÈìàÊëàÈèÜÆèÝÇÝɛӦUÙ­Yàºcà»aà»bà»aá¼]ç¿`ã¸Tå°Nߦ@ߥ;â§>Ý¢;Û 9ғ1¿s·m³o ²q¬o¸†(áÁkêÍ}éÊyåÃp׳]Õ³eÉ¡N¿?ǜMФSÏ¢Oʐ6¼«mŸ_›^¢f¡j¤l§p «v °|·ƒ·ƒ³º† ¹„¸…¿Š$2ȚRìÖ«îäÔîåÐìàÃæÖµÝÊ¡Ô¼—̵Å¥€Å¦|Á£yÂ¥zж‘áÉ¥éÙ¶æìÛäíàãíÞæçÕíÞÊîÔ½îÒ»åũ€¦~b¨~Z¦zVŽ`=ŠT.ˆO*P%“O#¦^:¹aC¹U4Ûq^ëˆzύtÜ·ŸåìâãéîãêîãéîãéîãêîãêîãêîãêîãéîãêîãêîãíìêãØϏ¾‡v¿ƒq»‚pµ€j»ƒn¶€kª{d§‰gØɯêíâãëëãëíãéîãéîãèîãçîãçîãçîãèîãèîãèîãèîãèîãéîãêîãéîãëíãêíãëìãìëãìëãíëäìêäìëãëìãëíãêíãêîãêîãêîãëîãéîãëîãëîãëîãëîãêîãéîãêîãéîãêîãéîãêîãéîãéîãéîãêîãêîãêîãéîãêîãéîäììæíéçíêäìîãçîãèîãéîãéîãêîãêíãêîãììäëìäìëãçíãèééîØëîØííÓîìÒíëÏîêÊîìÌëíÓìî×ëíÔìíÏëíÒíîÓêÚ°Ú³iË¡T¿Œ3¶„"¼…"¿… Ƌ)͊+Ç}Àrºkµdµf½oÅvÇyË}#΀̀Ìю0Ô§dË¥l£I…p?h5’}K¡‹]š‚LŒvAŠs<ŽwBŠr>§‹W³”_¿`Û²pî͈ãDžàƊå̓ëÖ¦é׬ëÚ®íܵëÛ²èÙµçÚ»å×´äÕ³ãÔ±ßѲÙɪÖÈ©ÑÄ¥ÉÀ›½©hǕEܬTä»aâ¸]â¸[ç½\â¸Wé»WèµNé°Há©?â¥=ߤ=Ü£7Þ¦>֘5È{¹l©f¯k ­k§l +¹ˆ-Û´`åÂtá¿pÚµ`Ö³^È¢T»D¸ŽAɞRϤRƌ.¹|·p£dœa f¡h¥k¨r ªv ³€·„¸…³·ƒ´¯{µ„"½ˆ-Î=ݾ†îãÊíàÄäÔ²ÛʨÔÀ˜Í·Ê³ŠÈ®‡Ç¬†Ç«…Ô¹˜åÓµîãÄîæÈåìÝäíáãîßéçÖìßËîÔ¸í͵ìÌ°Ô¯Œ²ˆf zR¡wU•iG^=ˆY4–b=–X.¾xUÃw[È~]܏q嘊Ж€×³—æíáãéîãêîãéîãêîãéîãêîãéîãéîãêîãêîãêîåëá佱Ív»lºƒj¸€kµ€i»‚nµ~g¥~g«‘páÔ¸çîäãêíãêíãèîãèîãçîãèîãçîãæîãçîãçîãçîãèîãçîãçîãéîãêîãêíãêíãëìãìëäëëäìêãìëãìëãìëãëìãêíãêîãêíãéîãëîãêîãëîãëîãëîãëîãêîãêîãêíãëîãëîãéîãêîãêîãéîãêîãêîãêîãêîãêîãéîãêîäëíæîêåíìãëíãçîãçîãèîãèîãéîãëíäíçèíâëí×ìéÌèèÚææßêÞ²éÜ®èØ«åÖ¡çØ¢çٟëܧëÝ©ëæ¹ìã±ìÞ©îä²íèºíè¸îߨê՝âƃ̩X·7°‰,ɍ2ό.Ç Âv¿s½qÄxÆxх&̀Æ{ÀrÃpÆyҏ=ۚT®{9†i)“€G a¥”dvD‰q;yDw?¤ŒS¼¢hÍ®pضlìˁìΆîхíӌì͈ê̊êϐìѕìћç͗ϼ‹»«€·¦x¾ªz©vµŸmª”e¡Zo1ibzi½‹6Û¤Dޟ;ߟ;ڛ5ۘ3ݚ5ޞ:æ©BäªBç¬@ߢ6á§Cݤ6Þ¤=Þ¡<ӏ&Àw +¸t·q¹uªo£l ªvΜKÝ´lÛ¶eÓ«]É UěN¼’GǞSÍ¡Pɕ5¹y³m¥faŸd¥j¨m¨q ¨t ³µ±€·†#¸…³€¬}±%³ƒ,¸†1Ò®qîèÎíéÓìåÈëÞÅêÚÀåÒ³åаãέÛÆ¡Ô¾˜ßÉ©íàÂîæËîçÏæéÛãìàåêÛéåÔìÞÊîÕ¾î×ÁíиཛྷÀ˜q–qN•iL’fD“fD’g?›mK’^8¸xZ͈m՝{檍ϚƒÖµ”æëÝãêîãêîãêîãéîãéîãêîãéîãëîãéîãëîãííêÜÉʗ„À„s½ƒl½m¹€j»‚k·~i²~g¢z_º¤‚éáÈåíæãëíãêîãéîãçîãçîãçîãèîãæîãçîãæîãçîãçîãèîãèîãéíãéîãêîãëíãëíãìëãíêäìëäíéäìêãìêãêíãëìãêîãêîãìíãëíãëîãëîãëîãëíãëîãëîãëíãëîãêíãêíãêîãêîãêîãêîãêíãêíãêîãëíãêîãéîãèîãêîäìíåíëãëîãçîãçîãéíåìééíàëèÍëß´åלÝ͏ÚÄÖÁ~ÖÀ…Ø¿}Ò»qÖ¾uÖÀuÙÂxÚÄ|ÛÅ{ẩâ˄ãψåΊåψèьë֔ìڛîÝ¥îá¦íܔáÅuʪSɤL¾’8ǐ2lj*Ʉ)ǀ%Ç}"È{!̄&ӊ+̂Åy½q ¹lºm +¾pÇu´i¡u2£ŒQ¦‘]š…Nv?t>“v;º˜Vá¿zëΉîԍîфëπë̃ìΆíҊëχê̅ìΊî֘îכèˏÞÀ„βzδzÛ¿~äĈàÁáÃãÇʦ]¨†2­‚ В+ܕ,ސ*ڒ)א$֌ ۍ$֋$ݞ;âªBâ©9Ü 3ؙ1Ý 3Þ¥9ܝ9ٕ/ˀÇ}¾x»~¸|­o +¬p­tʜKÖ®dÔ¬cѧ]¾“B¿–JǝQÍ¥V˝Mµyªm œ^›]Ÿf i©p ­v ­x´€´€¯€®€ µ…!³ƒ° ©{ ªz%¬|)ЧkìîÛéîäéîâìíÚîìÖîæÑîâÍîãËíàÃêÛ½ëÛ¿íäÊîèÑìáÊéæÔéæÔêâÏêâÒìàÍîÚÃíÛÆíÑ»æǩͨŽ­†j tU“kIjGi@™rOšpK·‚`Ú¦‚ß²Œæ½™å·Å™{ɧ‹èíâãêîãêíãéîãéîãéîãêîãêîãéîãëîãììæéßܵ£¾ˆs¾„q»ƒl¼l¼ƒj¸h´€i©|e£€fκžììÝãììãêíãéîãéîãèîãèîãéîãèîãèîãæîãçîãèîãçîãèîãçîãèîãéîãêíãëíãëíãììãìëäíëãìêäìéãìëãìëãëìãëìãêíãêíãëíãëîãìíãìíãëîãëîãìíãìíäìíãëíäëíãëíäììãìíãëíãëíäììãìíäììãëîãêîãçîãçîãêîãìíãêîãêíæíâëéÌåÚ¯ÚȑѺxË­`©YÆ«[Æ©XÍ®_̱]Ò¸d×»hؼh×¼lÚÀmÜÂißÅlãÊyáÈ}âÌ}äÌãË~æЄǽçЅèӎìבìؐëՍîà›ìٕÞÀwÆ¡N´‡*¸~$ŀ#Ȃ)̃(Ɂ#ˁ$ʺf°_²f´h²f §R¤Q³t,´ŽT•‚Ju;Št6‘u<Ğ_êȀîԉîՋíӊíÏêÍ~îӍî֐îܕîږî֐íӍíҒíԙíҘëғî֘îӕíҏí֏ì҉ìчíӈîӆ߲Và1ݓ&ޕ+ߔ.ݗ-ߚ-ړ(׋֎"ߝ<ã§?å¬<ߤ8ܜ1Þ¡4à¤8ߤ9ڛ2Έ ¿w ÂxΔ6¿…&¼µz!®t­y̞KÚ³iÏ¥Vª(°‡8ͧ[Ó«^УUµ~'§l ”W’T•^›d¢k¨t +­z²¶‡%·†#µ„ ±"°%°‚&¨{%§v'®~1Ó¯uîìÛëîâêîàëîßëîÜîë×îæÑîåËîèÏîçÐîéÐîëÑîãÉâÒ¸êâÐëàÍíÞÊíÝÉíÜÄîÛÄîØÂîѸêɯ۸šÈ¥€¹•p–vO…d=ŠnH‘nI¡|Q¼kÑ£ƒÙ¬ŠØ°ŒÓ£„½‘oÈ¥ƒééÛãëíãêîãéîãéîãêîãéîãêîãëîãëîãíééÕÅǗ‡¾„t¾ƒm½ƒo»ƒnº„k¸h´‚k zc¤…l×ƬëíÝäíçãëëãëíãêîãêîãéîãéîãèîãèîãçîãçîãèîãèîãéîãèîãéîãêîãêîãêíãìëãíêãìëãìëäíêäìêãíêãìëãììãëìãììãìëãëíãììãìíãìîãííãííäìíãììãíìäììãììäíìäíìäììäíìãìíåììåíêåíêäìíãéîãèîãèîãéîåìëéíàìæÄàЙл|½¥]ºœM½œJ¼›EÁ£LȨRÈ«RÊ­RαOѶOÔ¸WÕºWÕ»WÚ½RܽSÛÁ_àÂeì،åЀßÉoãËpâÉuäÍyæЃçЁé҇êӊé҄ëՊìڕïáçχɦT­„1®yº‚+ÂyÇ}ˀ Åx°b°b°gµi ¤W˜H˜IžP ¨v0‘s0xZ–p+ÐHå¾vîЋíÍ|ëÏíщìÌî׎îؒîڔîْîٔìЋé̀ìюî֙îٞîڞîٞí֚íԖíҏëΈéˀíӂìÊoá±Kæ§Dޘ0ãŸ7ߚ(ې&֌ ׏"ܖ)ܖ&ݙ/àŸ5äª=âª>â¨?á¦8à£9â£8à£6ؘ0¾~¹{¿‡*µ~"µ~«v¬v¦m©wƚGȞE¯‚/¾’B̦[ѨZ͞N±z%£e ™\’W’Z™a¥m ¨t ¦u  o²)¸Œ-µ†'ª{©x®‚$©})§v&¯3Ú¶íäÌîëÙíìÚíîàìîÝéîâííÝîéÕîèÐíìÕìîÚìíÚîèÒëÞÆíÜÉìÜÉíÜÉíÜÈîÚÂíØÁîÔ¾ìͶì͵àÀÒ°¾›}£‡f–|ZŒqOqL˜vJª‡b»‘pʘvʕz‹p½‹nŸ€éæÓãêîãêîãêîãêîãêîãêîãêîãêîãìîäíß䶡¾‡q¾„r¿‡n½†nºƒi»‚i»ƒi±}e•w[¬’wáÒ²ìì×èîàãîæäîèãíêãíéãëíãëíãêîãéîãèîãèîãèîãèîãéîãêîãéîãëíãëíãëíãêíãììäìêãìëãìëãìëãììäìëãìëãëëãììãìëãììãííãíìäìíäìíãííäíëäíìäíëåíëåíêäíìæíêäíêåíêåíêäíëäíêåíèäëìãêîãèíãéîæîäìçÆáўªb½žM±’8²‘=µ“;¸•4»™7À¢=Ä¥7Æ¥8ǧ;Ȫ8ǧ(ͨ0É£+Ê¥&È¥'̦)˨/Ö¹Hêìã׃ͳAΰ;Ù¼LÙ¾XßÆmáÆjçÎvèÏxèÎ~èςèτêхíݖìَ˫b¡u!£n¼z ǀ$Ãw¾p­a«^§^¡X–G”E’C’D›S ¬v,‹W®w)ߤVêÅsëÊyæÃoìË{ìӈî׌î۔îےîٔîאîԌéÊè΄îטî؜îؙî֗îؚîڞî՘íҐìψîՍí؎îÎxëÁ\ì½Wè©?âœ2à•#ݓ*׎$ڒ%ݗ,ؑ&א$ؑ$ޝ/ß /ä«Bà§<Þ¤7ڞ5Ù¡;ї3Á)͛;˟HʝEÀ”6¿’9¼1°} «x¬{ ³‚,²‚3ĚPϦ]Ñ©]¿‹9¢fªj›]š^›f ˜`h¤s¢pŸn ¥v¯„(³…*¤w¦v¨x¦v#©y)µƒ@Ú¾‹ëÞÄìàÆîæÑîëÙìîÜëîâêîâììÜìíÛêîàçíçèîäìîÞíîÜîØÅîÛÃîØÁîØÂîÙÃîØÁîÒ¸íζíͳßÁ ×¼™È§Œ¾œ~©Žq“wOŒmI“vU¢~a¢_³…cº‡j»‰k³†hº”wéâÌãììãêîãêîãëîãêíãêîãëîãììãïèêÙÎ͘ˆÁ†tº‚i¼„k½…l¼„k½…kº„e¦}_˜~[¬’ëÝ¿íëÕéíÜæîÞäîßåîßäîáäîáäîääíäãìêãììãêíãêíãéîãéîãéîãêîãêîãëíãëíãêíãéíãêíãêíãëìãêíãëìãêíãëìäëíãëíãììãëîãëîãëíãëîãëîãëíãìíãíìãíìåììäíëåíëæíèåíéåíéæíèäìêäíêäìêãììãêîãéíçîãì߼ι}µ–J®‡)°‹%²Œ%³Ž+¸“-º•(¿™$¿™!»•¾–¼”¼” º‘»‘ºŽ½“¼’ +¾“ +¼’ +½–âÈ_Ï´B½•Àš½šÉ£(ɤ+ÓµE×´EãÅTèÑyèÎ|èÍ~åÊzé΂íܛé֛«Š<•h§r!º~4Ã|+Àt±d ¨Z¢RFDAAŠ>Œ?“N +¤b†=ß³_æÃnçÆqêÉvî҆îَîݓíߖíޒîܖî׏êφè̂íԎî٘îחêύê͌íӏìъìыîאîבîےî׎ìËvìÆdîÁZë­Aè¥8å 0à™-ݕ,ޕ-֏$Ջ#τ̃ЇӉԌ(Þ 3Û£7ɖ0ǖ4Ò§IÁ˜;Í =É£DÇ F§&«….º:»8·‹2¬&¬x"´„-ǟQͤ\ǚE³|'¦i¤h”Z‘V•a˜d ™i +šj›kši +¡l­!¬~%¢s"™g˜e žj¥r&ƚ^áÍ£êÚÁêÚÃìßÊîäÎîêÖíîÛéîáçîãçîææíçèîåêîâìîâëîâîØÂîØÁîÙÁîØÂîÙÃîÖ¿îÕ¼íѺë͵åÆ©Ú¼™Í®’¢‚«pšy`rQoK”sRœ{Z¦|`ª€e¨a£{^²ŒkêâÊãëîãêîãéîãêîãëíãììãíìãíìåèÙ滤Ȏ€¿„q¹€l½i¿‡n½…l½‡m´fž}\¨•pÜÌ­ìëÕèîßåîáäîßäîàåîÞåîÝäîÞæíÞäîßæíßäíãäîäãíëãëîãéîãêíãéîãêîãêíãéîãéîãêíãêîãëíãêíãéîãêíãêíãëíãêíãêíãêíãêîãêîãêîãêîãêîãêîãëîãëîãìíäììãëíåíëåíëåíèåíéæîéåíèäíéåîèçïååîåçîäëݴ̳|±’Dª‡,«†¬ˆ­ˆ³‹µŽ·´Œ´Š±ˆ³‹®·‰³‰·‹·‰»Œ¾‹½‘¿“´­Ž §Š +¦€¬‰¯Ž +²Š»ŽÀ“ +ĝϬ&êÔpèÏnâÆiãÈrãÈuêӑïâ²Ò´uxTvM{M ®s-Äz+¨d›OŒ=‰>ŠAŠBˆ=„;}8u/ˆDːAåºcèÇwìπîԊî֌îِî׌î׍îڐîޘîٓíՎîړîݝîڕè̄вhÝÀzåȃè˃ëЊîٖîږîܕî׎íÎríÈdí»Që¬?ç§9å¢/ڐ ؉ԆԅÌ~Ԉτ΃щ҉!ڛ.׫CÕ³Mܽ]ݾd·’3¯‚$¯‰-²Œ0³Ž5¸“<«†4¢}$·‘6À˜@¶Š1¨z'½Ž=̝S·„-¤n¢e‘V +ŒP‰MŒU”a ”eškd “ašg +ª{'©y"“aZ –d”`¦z;ϸˆãÔ°äÖ»æØÃëÜÊìáÊîæÓìíÚéîáæíéæíæçîæéîãëîáëîäëîâî×ÀîØÁîØÄîÖ¿îÖÁîÙÂîÕÀíÔ¾ìϸæȪãĪϰ›Æ¥Š¼ †ŸƒitT–tW˜uZ™wVyZ¤~d£{_¡|e°uêàÈãêîãéîãëîãëìãìèãîäãíÙäèÕéԽآŠÆ}‡sÀˆrˆrÊsÀˆp¼‡g¯ƒb¦†aεìà¿êîÔçîÙäîÞãîßãîÞãîáãîâãîæãîääîÛäíÚêéÔèëÕåíããëìãêîãéîãêîãéîãëîãêíãêíãéîãéíãéîãéîãêíãèîãêîãëìãêíãêîãêîãêíãêîãéîãêíãêîãêîãêîãêîãëíãìíãììãìíåíéåíéåíéåíéæîçêîÝîåÆáÏ«èÚ¹îæÊϺ}³’G§‡4©…«†ª† ¬…§€ª‚¨¦}®„°‚²„¶ˆ»Œ»¾–À“ÀÀ‘½“¼°Š™Šx…r‡n”{Ÿ©…»ÔĘ àÆPÍ©+Ñ­1Ö¸KàÈkæ΃îÛ¢ÛÉgG R._5}LŒU –O†=‚6„8…>ƒ=8x2i.e)k'Â6ê»iíчî׍îړî؎íτíЁí҉îՉî׎î۔îܕîޘîݘîݘí֏áÆ|êЊëЈíӌî֏îڒîݖîݔîՈîÒ|îÄ\ìºNíµHë¯Bå¡3ܔ%цÑст΀̀ӃЇόÙ¥<Û¶Rà½]Þ¼ZΪQ°Œ3z$¢|'¬‡.¿Jаa¸™E¢„/ª†3¸”@¶Ž5¬~+¡mĔD¸‡.§o”^ŒTˆM†NˆO‡P‹[ ’dˆ]ŒZW£r%Ÿo!ŒY +‹W’_™d¯…HϼØÉ¥àѯãÓ½åÖÀéÙÃíäÐìîÞêîâêîåëîæëîâêîáêîàëîâëîâîÓ¼îÔ¾îÖÂî×Áî׿î×ÁîÔ¾íÒ»ëϲèˬäƫݽ¢Ó²›Ë®•¬x”vYœvY—qU•sTxY¢{]¦}a¡zb­ŽtçÜÈãëìãëìãíêãíßãìÚãæÎäâÌçÚÅ點˓z̔{ƎwČw‹pƎx¿ˆm±‚e¬‡bÄ©„ãÉ¢îß½ìäÅêçÉèéÐçèÒçéÑæêÒäíßãíéãìíãíæäîàêéÔîáËêêÚäíæãéîãêîãêîãéîãêíãëíãêíãèîãéîãêíãéîãèîãéîãéíãêíãëîãêíãéîãêíãêíãêîãéíãêíãéîãéîãêíãêíãêîãìíãíìäíèæîäæîâçîáëèÑÝǜ­‰[™vBâΧæÚ±¶šT«Š-ª†"¥} ©€©‚¥~¤|¦~¨°„±‰¹¿’ęęÁ•¾•·’±Š®Œ¯«Š¤…£†‘|sŒt™|›~¥…±Š–ĖǛțǚ Ê¢Ô²CáÅuïڛӸ€`B +A P(X4{M‰Kƒ:7ƒ8}8}9s1g)]%XW˜Yݯbî҇î֏î؎îӆêË}åÅuíÐíрíՍí׎íޘîޘîܕîܕîٔîّíՌíԍíӌí׎îڒîړî؍î؉îԁîÊgí½Vì½Xí¼Qܓ ډՇӉтЂЃ͂̀֋Û¥>çÄhÚº[Ò®QÝ;µ•9§ˆ5p¢~1«‰7­‡4¨†6¼šF¾Hšw$›w&³7¶’7¢t¢q¸€*¢jT †R€K}IƒL‚N…UŒ[„Z †VŒ[™j‘eˆUŠT‘\œm,›jζŒÇ·˜Ñ¤ÖçÛË´àÏ·éÜÄîéÒîëÛííÛîëÜìíÞìíÜëîÞëîÞêîßíÏ·îÓºîؾî׿î׿îÖ¿îÓ»íѶê̲é̯æË­äÈ­ÝÀ¨ÖºŸÆ¥Ž ‚iž|`šx]–qX™u\¥g§f§e©‰mèÑ´âïããîâäèÖããÊæÚÃç×ÀèÖÃìïנƒÎ”{ɎzǎsƎtǐsɑy¸„hŸ}Z¶˜tß¡íѱîÕ¸îØ»íÙ¿îÙ¾íÝÀíÚ½íÝÂèéÒãîããìîãëìäîãèìÔíàÈîâÏçíÞãëìãêîãéîãéîãéîãêîãéîãéîãéîãèîãèîãéîãéîãêíãêíãêíãêìãêíãêíãêíãêíãêîãéîãêîãéíãêíãêíãëìåîÞéèÎëãÃìÜ­íاêѢ忎q9wH¦yCîåÀÞɖ¯‘@©†'¦ Ÿv¡w£z x¦{©‚±‡º¾•Á˜ɟɘƙ³Ž¤‚  ‚‚§ˆ¬Œ¯Œµ’¹—µ¹‰ÁÝ À–Á”ƘǛ̞ ˞ +ʟǜ Ì¥$äÆnëԕºžeS0@F!R,jE|K‚>|89z6q3d*Y$S PK{GÛ§]ìËzì΁îՌî֋íӉçÉ}âÄoåÇvíԉîړîّî؏îؑí׎ì҉ìчíՇìҋèÌ~ìӅîْçÆxï׉îׄîÖîÏqê¿ZíÆbæ¬DׂÓ{ +ӆ֌!ч̀Ì΃Ãx ̆Ö¤@Þ½aϳWãG«‰2¯7¡‚,Ÿ}+´‘E±‹6»˜C²Ž@Á›JÍ­]§„,†b§…0µ‘4¡w\ ¥oT†LƒM|GyE}EƒNˆWˆW ~LMƒQ —d[‰T‘[šd&«…L×ßÓåʺ Ã±—ï“ijšËºž×ĦèÙ¿èÜÆëÞÆìãÍíâÌîçÑîêÕíèÒîëÔìÑ·íÓ¸îÕ¼îÕ½î׿îÔ¼îÓ»íÔ½ìÏ·êͯåÉ©âƦڽ¡Ô·›Óµœ³•|§†g €_ž}\¡{bªƒk«‡j¨‚dªˆiäÁ¤äæÎãâÒäÝËæØÅè×ÀéÒ¿êͻ赡њ†Ê“|ʒ~ʒ{ɑzȑy¿‰pœuU–~\À¨‡ã˪ìаîбîÓ¶îÓµîÕ¶îÓ¶îÖ¹îÓ¶îÛ½êçÎãîçãììãíèçîÚíâÇîÞËçîÜãêíãèîãèîãéîãéîãêîãêîãéîãéîãéîãèîãèîãèîãêíãëìãëíãëìãëìãëìãëìãêíãêíãêíãêíãéîãéîãêíçîäì×®ä®pã«fáª\Þ¤ZݞWЊKZuK³WíëÍÞʙ¯Ž7¥€—sšrœss£{­´„·×Ú×–Á’Ц ¸³ˆ²Š³‹²‰¼¸ŽÀ”Ë¡Ì¥řȘʛÌ¡Ò¥ Ñ¢ ӤѡդקÔ¢ɝÒ­1ìԋàȌŠj-S-C >E$Q+f:r:r4s7g.^+OJIDDi; כQè¼gëÉríЀîԅî׋íْì҈äÅxíՌíؑîڔîՍîٓîؐî׏îՍî׎ìԇæÌ{îٍîًà©NêÂkìÍsîÎtîÐníÉgíÅ[Ӑ Ô{ ؈ّ+ևÌ| ҅Ё˃̌#՚2Ô¬LέQ³‘3©‡-¯9¨ƒ(´’;¾œMظjÅ Hί_¾œRÄ¢WÁ U¡},”q©‰:œI·Œ:Ÿo‘b €IzDwCvBxEzGxF„T€M~K|I‡R +‹X‰WŒY•a¢q5Ô¸‰èÝÂèÜÉãÖÃÜ͸˻ Á¯š·¥ŠÀ­ŒÌ¼›ØÉ«àеäÓ¾çÙÀçÙÁèÛÁèÛÂãÕ¾êϳíÒµìÒµíÔµîÖ¼íÒ·íÓ´ìÒ°æ̨äǦáƤÜÁŸÚ½ Ò´’׸š¾Ÿ‡ªŒm®Œk®Ši°‰o±Œt±‰m°Ši­‹oÞ¸žçÝÃåÞÈåÝÇçØÄçØÀéÓ½í«ݤÏ˜…ʐ{ȍyɑ}ȑ{À‹tuWˆlE˜aʳ”áÉ©êͯîήîÒ´îÓµîÔ·îÔ·îÒ´îÒ´îÔ·íÛ¿æëÕãíæãìèåîÝíâÉîÞÇæîÝãêìãéîãèîãéîãêíãéîãêîãéîãéîãèîãêîãéîãéîãêíãêíãëëãìëãììäëëãëìãëìãêìãêíãëíãêíãéîãëíìåÌÛ¡kà—Zá›PáHášJޖJ̈́: _ƒO +¯ŠGìíÌêÛ°¶—A¦‚’n—m£u§|¬€¶ŠÀ’¾ÖÖÁ”¾’Á”Ò¨Σ +Ɠ“ŖŕɘʙȗƗʝƗÁ˜ƛư̈̄Ô¤Ö¤צ٨ܫܮ ݸ9èÏzéԗ¼›W…^vK k@_8J)U1T/e4f4`-RIJED=AK_̄;Þ¢Sä³dê¾níËïՍîՍí҉î֌ë΅ë̀í֍îؐî׏îڕîۓîڏî؇í،îܔëÐ|ڊ,օ&çªIç®MîÂ\íËgîÈeâ£6ۍà•"۔)Ԇ!֋ Ԍ ϋљ2΢AÕ®SÍ«O»›B¤  {¤‚&ªŠ.¸—C¾ S¹›L¸”CÚ»nŤX¸–J­Œ=™v#®Œ6­Š:­‡5¶>³‰8˜l|Hu?o;r?uAuByF|N +{J +yG}JŠWŠXŠW]‘f(¨{ìáÉîëÚìäÌëáËêßËèÛÅâÓÀÓìů’½©‰Æ·•Ï¿ÓŨÔŧÜͱÜ̱ÜÍ°ÚË­èΰèͯéÏ®êίêΰåʧäÇ¡âÅ Þ ۿ¢Ú½šÔ¸“Ôµ”Ò³’Ò²–≳y¼•|ěž~»—z¿—}¸v³uݵ˜èÛÁæÞÈåáÈåßÇæÝÆêԺ굞җÍ’zΐ|ȎxƋrÁ‡o§zb‡jB‰oI©‘vÑ»˜âʧéË­îаîѳîÓµîÔ·îÒ´îÒµîÑ´îÒ´îÖ¿ëæÎãíçãíéæíÞíáÉëçÑäíçãéîãèîãéîãéîãêîãêíãêîãéîãèîãêîãéîãéîãêîãëíãëìãìëãìëäíéäìêäìëãìëãëëãììãëíãêíãëíäíçéΧܐMà•Là–Cà˜=ޘ=ڒ;Ä|-¥^—V ¶‡>êêÄêìÍÝŁ©†g u£u±„µ†»Ž¿‘¾’¾”Ƙșƚɚ˛͜˛ɛ˛˛əΜ̛ʛȚ´¤„¬„²„đ˖Л͜ԤߵéÌ[íیéÎÚ´gʗJǍDКPרZƐK·F¦:ŒbvIk>[*LLGA>CBHr3—J ¯bÀq'Ãu+҇CÛ¡Sç¸ièÀrìÊzíчíՈî׏îٓîՈî׉íÑ~íÔ~í؈îڐîۏëÄqڃ#Êk +¾g +Ásä±PìÈfíÅcå®Bç¨5æ¦2ݙ+ՇՉà˜*Ô¡9ѬL¿›:Ä¡FÄ£N©†(¡$¤$¬‰7 P·šG®>¯=±C®<©‡9¦…6{- z+´‘B±>£{(¦|*·Ž7›q‡Rq9m7p8n:m:rCwHqBvDJ +†RŠSˆRŒb+§‘bØǨïç×îêÜîëÙîéÓíåÑìâÍíàÎêàÌÞӼ˾ Ì¿ŸÑ¤ξ¢È¶˜È·”Å´Í¸—Æ´âË­ãÊ­äÊ«äÌ­ãÉ©ÜÁžàÁØº“ؼ—Ù»›Ö·•Ö·—Ù»›Õ¸—Ôµ•Ë¨‡À–€ÅŒÌ©Ê¥‰ÄŸ~Ğ€Á›ƒ·‘w×­ëÒ¶æÝÇäáÈãåÍäãÊëͳߩŽÏ•|ɐtʐ{Ǎu¿‰l±|`“pP‡jB”{[½¢€ØÁžą̈êÏ­íÒ°îÔµîÓ´îÕ¸îÒµîÔ·îÓ¶îÒµîÖ¹íÞÄäîåãîçéì×íçÍèíÙãêíãéîãèîãéîãêíãêíãêíãéîãéîãéîãéîãéîãêîãëíãììãìëäíéäíéåíéæíçãíêãìêäíéäíêãìëãìëãëìäîâèÑ،Bޕ=ݖ:ݕ<ْ8ӊ.¾r»o´mˌHéä¿äî×êëÉÙÀ…®3y«¹ŠºŽÀ’ė¿•Ř̝Ν͞ɜĘ¯™}¹’Ï¡ Ó ОϟϝџĔ¶Ž´Œ½¾‹¿ŠƖϢ߾UëÓoìݕîЊáºgçÁqéÃqå¿sëǀçÄ|êÁvðӋð֎êȂٳfÕI¬~4‚Sh4J<ACM#_4o8x3‡;@”D ‘>¥R Âp$Ռ=ޝNä®aì¸kè·jê»mæ­Zê®]é½hîÍwîֈï،î҄æ¶Y܆$ÍrÁe +µ^ؖ0âµIêÄ]ä±Dê³Aå¬>ãªBà¥7ä­Eê¸NêÇcÛ¾`¸•7Å£EÀœ?¿›>¨‹5¥†- €.À Q´—H«Š;¸˜L¨‹=¦‡:§ˆ;¬?œ{,—u(¦„8°Œ?¢|'£y(®†3£x ˆR j5i4k4e2l;p@qAk;qA{G K„R$ yL¬–mÏ»•Û˲ßÔ¾éÝÉîæÓîëÖîìØíèÔîçÓìâËëÞÉå×ÂáÓ¹ãÔ¼ÕÈ®¾­ˆª—{©—v§•n°˜rÛäÜÄ¥àɨàÈ©ÝÄ£Ù¼™Ö¸’Õ·’Õ¶”ÓµÔ¶’Ö·“غ–Ú¾™Øº—Ö´Ê¥ÎªˆÔ±”ѲÏ­‹Ï®É§†Áœ|Õª‡ëƦéÑ»åÝÈãäÑæàÉ뾝ӛ{̓zȎvǍu¼„hµ€g•nIŠlK˜Y°¡×Å¥èÑ°êÓ°íѲîÕ·îÖ¸í׺îÔ·î׺îÒµîÓµîÔ¶î×»íâÆèíÛåîâéìØéíÚãíèãêîãéîãéîãêíãêîãêíãëîãéîãêîãéîãéîãêîãêîãëìãììäìêåíèåíèåîçæíæçîæåíçåíæäíèäíèãìêãëëæîà澊֍D؎:ْ9Ԍ3א7Ս3΅+ˁ)É~*֐Fëà²åíÑçíÓéíÑçÚ¬ØÄx¢,½—½”ĚȔΟ̟Ò£Ò¦ΠĘ³{€o©…ƗНÑ џÒ¡Пר ̛ΜțĖ¾“ ¾Ÿ,Ô½fçԆïá¡ìӌéʂêÇ{ëË}îאîّîݗîٕîޚîەíâîݙíݙî׌îԊï֊ä´bLJ@J K DF"V2oA p?t;K~:l.l+z2£H¹ZÃn*Çv.¿gË{/ҋ?Ì~1ÄmԌ?â®Xæ»`ܱRåº_å®KԁËr »]¾e͇߯Iæ»Tâ°Dç´Eé¹Lê¹Lè¶Hê·Kè¸Pß¹SÓ°Pº—9½›?¾š@È¡G°6©Š3§‡0»›J­9·—H¼T¬Œ9¼Q¬<¥†:˜y#|,§†7°Ž@œy)›t$Ÿu,¦y+ˆVa/Y+c2_0h8n<c4g7q> +wDnA¡€U«‚ÖÚÖǛ×ȧÝδÛ̳ÞзäÙÃíæÓîëÚíîÞííßííÝîçØîâÎìäÐçÜÇ̼ž¤s—„d“b™…`Ö¿¢×¿£àƧàÄ£Þǥؾ™Ù¾šÖº•Õº•Ö»–Ù¾™Ú¿›ÝŸàŸáÄ âÅ¡Û½™ÜÀšàÄ¡ÞÀœÞÁ¡Ü¿¡Ö´’Ç¡{Ö«ŒëÆ®ê͵ç×¾åÞÉìͷݨÐ™}̑wɎv…l­|YšsPqK’yUµ yÝÍ«ìÛÀîÝ¿îÛ»îÛ»îÚ¼íÛ½íÙ½î׺îÔ¸îÓ¶îÔ·îÖµíÙ¾íáËéíÕçíÞæîÜãìêãêîãëîãêîãëíãêíãêíãëíãêîãêîãéîãéîãëîãêîãëîãìíäíìäíéæíççîæèîäêîâèîãèíäèîäæíæäíèäíéãìêéíÛ庋т@ӈ5Ӊ0ԉ2Ԍ1Պ1Ӈ/΂)ˀ.ՑBìÙ¥èêÌéêÐéíÐæîÚäìæèå¿èڑսfή4Ϊ˥ѥҦ΢ɚŖ¨‡€q…¶×ϟӤҢѡ +եӨϩ"Ï­9Ø»SÙÅiåՊíâ£îâ¢ì֍ëЉìӊîܕîגîܗíޘîݗîߞîàŸíߜíߝîàíޛîܖîܖíߙîڐí΁ê¾n؟U‰P?DI'[5m>j3v?w@ Z"W _(y5‰2™G ¡P‘C”B¤Q¢L›A¨PÁjÎ#Æώ0ڛ:׉ÏyÉp ÍṽاAâ¸Pç¼VëÁWê¿Ræ²G֝/á§=à®EسUÌ«OÉ«T¸—<̧QɧTѳ^æW»šM³’A¶˜H»œO¦‰6®‹7Ä¥T»œNŸ0›{,¢‚3©‰;¦†6¢1£|*™q!¤€1†ZZ*V&W)Z)b0c5a0^0^2K&H+‘zKË·ŒÕĔ×ŝØÉ©ÙʬÙˬÜÍ´ßѸàÒºêÜÉíçÖíîâêîâëíáíëÛîíÚîçÓÙÊ®»©«šv•‚dzZÛǧÕÁ¦áȦáÇ£áȦàÈ£áÇ¢àşÞßÝßâÇ¢äʦç̨éϬè˨èÍ©ìÔ²êѬç˨êαëͲèÈ®áÀ§ÄŸØ«Œé͸çѽå×ÄäÙÆëÁ¦à«Ñ™z͑vˊu¹iŸuR“rH”yR­–yØãîàÄîãÇíâÆëäËìàÃìßÃíÙ½îØ»îØ»îÓµîÔµîÓµîÕ´îÚ¿íèÔéíÚæîáãíçãêîãêíãëîãëíãëíãëíãëíãêîãêîãéîãëíãêîãëíãíìãíëäíêäíéæîæèîäèîäèîåéîãêîáéîâèîãæîäåíæåíçäíééëÕÙ©pÍ;х/Ӈ*Ӈ,Ջ/Ӌ+ԉ/΄%̀+Ռ:í՞ëéÊëèÇíèÇìéÈêìÌèíÏäïÚììÆêã«èٔåӌãÅkàÄHÚ¾HÖ·6ί;¤’'¨“(Á¥5¼¢+Ï°5Ö¶0ßÂOæËbêÏuëׄëݒëä¥íæ±îæ²îá¬ëՕäÁpãÂdëÊuîאîܓîàîá íâ îàíâ¢íâ¢íá¡íàžîàîޛîޗíޛíޙîّîٓîڔîӆëºi½ƒ9T*??I&\3i2g2f.Y UUV `"i(u0w-v,v,u,x,ƒ4F§Q«Z¹vä¥Dߕ.؇Ô~рӏ*؞=â±Mè¼Wê¿Zà²LÛ¤:؝2Õ 8Õ¢=Ò«JήUÍ­Q¾›D¾›@Í®\ϳaƧU´•D°‘<¿ŸRÌ®Y²”E¼œKÅ¥S®<¨ˆ:°I¥„4©Š=­A§ƒ6§ƒ-¶<¶A‘c],L!O!U%Y-W+M!E <39 Y?±vηÔĞÖÆ¥ØÈ©ÛÌ°ÝϵßзàкâÒ¾æÙÅëãÍìîÞêîãêîáèíåìíßèÛ½ÑÀž·¥€¯œ{¢ŒkèÖ¼æÓ¸çÒ²çѯæЯçÒ°èÑ®èЮçέêаéϯíÕµìÓ¶íÔ¹îÓ¸íÕ¹îÞÀî×ÁîÑ´îѼîͳëÄ­Û´•Àœzج‹èÓÂåÖÄäÞÆæÛÄêÔ¸îȩ䥊ّtɃh°x^›yT¢ˆb± ~ÕÂ¥ëÚ¿îäÊíäÈëçËéçÐéæÌêãÉìÝÂíÚÀî×»îÕ¹îÒµîÔ¸îÚÁìèÓçîáãíèãëìãêîãêíãêíãëíãëíãëíãìíãëíãêíãêîãëíãëíãëíãíëãëíãìëãíêæîæçîäéîãêîâéîáéîâêîàéîáèîãçîãæîääíåäíçêêÑØ£lÉz4ц2҇(Ԉ.Ԍ-Ӌ,ԋ-҈+Ѕ*Վ6íʑìåÄìåÁìæÂíä½íã¼íä»îåºíçÀìêÀëìÆëìÅéíÁëê¹êìÀäגè֕èä¹ìè»êá¬íå²íæ²ìè²íëµìê·ìê¾ëç¹ëà®éٝåҐÞÅ|Û¹fß²Vã±WëÈsîۑîݗîݕíâ íâ¡íàžíã£ìå§ìä¥íã£ìã¡íàíàíޗîߙíݖî؏îۑíݖîтë¾iЅ)v<>=BM$\+^)a&WX TUWV]"l)i%f"k%k'n'u-Š;ŽEϘ9ޛ9܊'لËnÂhÄm ÆsÄv ӑ+æµUé¿]צ<Ι.ʗ2Ò¤CʤHÀ›@º—Aµ“<­8¾ RË­\αc¾QÀ RÍ°cÂ¥Q½ŸO¼œMÀ¡P¯@­B©ˆ=°@­Ž9¨†5©†7¨„2¹‘B±ˆ>_K<C >B!D!6.139D)|e8ÀªÓŸÔàØÇ©×Ç©Û̳ÝÍ·ßϸáÒ½äÔÁâÖ¿ëàÍëîééíçéîåíìÝçÜÀϾ¹¤·Ÿ¯›rîÞÅìÙÀîÛÄìؾíÛ¿íؽíÙ¿íÙ¿îÛÀîÛÁîÛ¾îÛ¿îؽîÕ½îÓ»îдíØÇîÔ¿îÉ­ëĬ껡箏ͤ»ž{Þ·˜æ×ÀãâÌãêÓãìÓãêÔæÚÂí·˜æ•{Ɋj³‡c±˜q¿¯ŽßÓ°ìßÁîäÊíäËíåÉëæÊêèÌëåËêäÉìáÅíÜÀíÚ¾íÚÄíÜÂëåÊæîÙäîæãííãìíãëíãêîãêîãêîãëíãììãììãëíãëíãëíãëíãëìãììãììãììäìêåíéæîæçîåéîâéîâêîàëîàëîßéîàêîßéîàèîâçîäåîåäíæìëÔ˔[Éy7Ԉ9ӊ+ш*Ԋ)҉+Ӊ-΄%х)҈0ìŊíã¿ìæÁìäÀîàºîà·îß·îß´î߶îܯîß±íܧíÜ¥íÞªîã¸ß­UàŽ +êè¬íä¾ìà´ìݯìÚ¥ìÖ¢éЖçјâȈßÄ~Ù¾zÒ³cÖªRן8ä¯FíÌuîхîۓíâŸîàšîޙíã íâ íã¢îàžíá ìæ§ìä¤ìä¢ìâ íâ¡îà›íáœîݕíޖíߘîۑîՄâ®U¹kW'<9:AL!['j1d+SOMPTZ_!c!g&g%h%h!h!v/‹Bë³\҃Õ}Îr ÍtÂj¾f¸c·eÁiÅ|å·Uß°MΞ7ɘ8ѨJÇ¢K¸—>¾N¹™Gµ”FعrÙ»nÓ´b¸˜H¼›Mɪ[Á¢[´™J¹›Kº›L¯C´•HªŠ>¹™K´“B¶”J¾›M£€0¥~0žt%„X8)'--,-132;"=&X:Ÿ†YÊ·ÒœÕƧÖǨÚ˱Ú̱ÜÍ´ßϺáѼáÖ¿åÖ¿íëÝêîéìîäëãÍßеIJŽ»¨ƒ¸£´ŸwîßÆîßÅîÝÃîÞÅîÝÅîÝÂîÞÃîÞÅîßÇîÜÃîÜ¿îÙ½îÕ¹îϳîÊ­îƧîÊ°íÀªç¹£ãçÛâäÝꤍƣ‚½¥‚äÆ£ãçÑãìÙãíÖãëÑãèÐçØÁìÁ¥é®‘Ò¨„ˬŒÞÀžéÚ¸îèÉìêÎíèÎíãÇíâÆíâÇëæÊëãÈêäÉìàÄìÝÅëßÃéèÑçìÙãîáãìèãêíãêíãêìãêíãêíãéîãëíãììãëíãëíãëíãììãëíãìëãììãìëãìíäìêäíëæîéèîæèîäêîàëîßëíÞëîÞëîÞìîÞëîÞêîßéîàçîãåîååîåíéÎNJQÉ{6҆3ԋ+ԋ-҉)ӈ(Ї$φ$Ѓ%υ.ê¸qíß²ìãÃíá½îà¼îßµîܳîݳîÛ®îÚ®íØ©ì՛êҘìіìҘã¤Aëƒèª:æϗä˓ãɏàƇàćßÁ…Ùºx׶kÒ²dÏ­`̟LҚ9à—'ã’êÂJîօîá™îߛîáŸíâŸíàžîݚîߞíáŸíâ¡íâ£îà›íâžíáŸíàíâžîߚîݖíݖíޖîۓìÉuՖHœQ ?664=Db/vA +h3X&NMMWZ!]!c"f%f#f#h%i%j(y0ç«\؉ÖxËmÄh»]µ_³c³_ºfºn ½|¬p ¶‡Á–9ϪOşFãLªŒ;©‹;¿UÔ¶nµ”B¼œEˬ]Ê©]½žH¬@¸œOÀ¢Q»Mç]§`ɪe»M»™L±?µ”Eª‰=¬ˆ=©9xP/"%-,17: ?'I'U*tD ˆ`¸¤kι‹ÒÀÖŤÔŤØÊ­ÝζÞηÞÒ¹ßÒ»ãÙ¾ìæÒëîãîëØéÞÆØǯ¬‡»§ƒ¶£‚´œvîÞÇîÞÄîßÇîÞÆîÜÆîÚÃîÚÂíÝÅíÚÄîÕ¼îÑ·î˯îÉ°íÀ¥î½ î¾¢í«챠æijãêëãäã黧ǯÊ²êÕ¶ãîÝãîÙãèÐäâÅæÜÃé×»ê×¼îѳíÍ°íÔºíÜ¿ëäÇêêÎëèÌëåÉíâÅíâÆíáÅëáÆëâÈëâÉëäÎééÖãîáãíèãììãëíãìíãëíãëíãììãëíãêíãéíãëíãëíãëìãììãíêãíêãììãìëãíêãíêãíëäíéæîçéîåêîãëîàëîÞëîÝíìÛìíÛíìÛìíÛëîÝëíÝêîßçîáçîàåîãìâÅȋQÊz0҈/ч*Ԋ-ԋ-ӈ+҅$σӄ%Չ.è°bîܯíá¾íà¹îÞ¸îÜ´îÜ·îÙ¯îÙ«îשí×¥ëӝèϘêїèϒâ¡=ìÝwêÂdàɋáƋÞ†ÞÇۼ}ÚºwÔ±hЭdÍ SϘ>ٚ2ݖ!èäêÈUîߛíá¡íâŸîášì֏îܜíâ¥íâ¢íâ¢íà¢îܚîߜîߜíáŸíàšìӌîِîِîڎîԈé³[Åt#ƒ9@48:L$[.yBD +i5X%PNKOTZa#h&f#g%i'e#g){7ޜEޕ&ÍwÄiÀd·\³]°\­Z¬Z®\µe¯p«yÌ¥IÌ­P½š?×¹g´˜C£„-µ”FÃ¥Y´”F·šL¹˜E¼M³•A¼žO¹šO¼ŸR·›Rɬd´”K¸šM³’J¯Cœ{+¥ƒ6«Š;«ˆ:¯†>wL.*((+/3H*Q+c;l9E‡N‡P¤IÅ®€Í¾”Ï»˜ÓžÓŨ×ȯÜͶÚζßѺãÖÀíé×ëîåííÛìäÍ×˭ʶ™Æ³–ñ“º©ˆíÝÇíÝÇíÜÇíÚÆíÔ»î͵í͹îÈ´íÄ®íÀ¬ì±˜ì¯–í¹¦îÄ°î̱ìÒ¶èÛÃéßËäæÔãîäæßÎæϵʱÌµ˜ëÖ¶âëØãáÍæиê̱êÒ¶èÚ¿çÜÁêÝÁêÝÃéßÄêâÆéâÆèæÌëâÆíàÂíßÁíÞÁíàÃëâÈëãÅéêÒåîãäíèãëìãëìãììãëíãëîãëíãëíãëíãëìãëíãëíãëîãëíãììãíëãîèãíéãíêãíêãíêãíëåîéæíççîãêîáêîàìîÝííÛííÛííÚíìÚíë×ííÙìíÙëîÝêîÝéîáçîàæîäíßÀƅAÎ*ц.х)ф'Є!ф%ς!τӅ"х(ã¤SíÒ îÞ¶îܲîݵîܲîÙ¬îÚ­î׫íרíاëÑ¢èϚçΑè͔àŸ=è}ês܂!æʊßÄ߀ݽ~Õ¶sسlÑ«^ʤVȚHΗDæ·\ޜ#æ…í†ê’ê݆îà›íâ íܙîٖíٕîߛîàŸîá¡îàŸíâŸíß íàžîޘîؑí֎îّîۏîۑíЄà›DªVt/L#R)^-p9}E SžZ‹Ke.W&QLMORW^ b#d#e%h'd b$ˆE ٕ5׋#Ì{ ÈoÂf¾b¶_°[®[­[¯\µgºˆ ¾š6¿œ@±‘2˧NÝÀmÝÃs½›H¶•H¿¡RĨR̯Z©‡/¯‘CÍ®bÈ«\¸›J¶šM¼ŸT²•Iµ•J­A©‹A¤†7™x*¯D¢}/©…3ª|1mF +)-/49!B#S-o;}B„IŽPQŒRT ˜b#¶•bij†Ë¸É·ŽÎ¿›ÒÂ¥ÖƪØÈ­ÛͯãÖ¿íëÛêîäëîäíîàèÞÅàÕ¹ÞÔ½ÜÍ´×É«îγìÒ¸ìÒ¹îÆ°í¾¢í»¡ìµ›é­—ç©™å¥•ä¢‹â¨ëØÂæêâäíçåîÜãîàãèíãçîçíÞìáÇÌ·œ¼ŸƒÏµžçÄ¥é̳컥뻞ëŦéÒ·èØ¿éÙ¾éÚ¿êÜÂêÚÀëÚ¿ìÝÀëÞÃëÞÅíÞÃíÝÄíÞÅêæËèéÓåíßãíéãêîãêîãëîãêîãììãëíãëíãìíãëîãëîãìíãëîãìíãìíãíìãíëãíëãîéãíëãíéãíéãíéåîçåíççîäêîáëîáìíÝìîÜíëØìîÜíìÙíìØîëØìíÚìíÚëíÛêîÜèîàåîáæïáíۼͅLÍ}0Í-̀%σ'υ#΅Ӈ&҄"тЄ(ܖAíʇîÚªîÞ±îܳîÙ¯íجíתìÔ§ìÔ¤ìÔ¢êÓ¤éϚéΕçɖå¦Ièwêqßhá•1àÃܾyظuÕµqÓ«eЪ`΢WƘIÓ¡QìËzâ­=ä‚êê†å éÎhîà™íà£ìã¥îàžíדíâ¢íá¡íã£íâ£íã¤íá£îݘîݗíáœíá›íߙîڎîÍ{ԓ<ŽF|:EˆH‘P—R¢YVŸY‹Pd/V$TPTUVW_"a#b d#e%e#` ¡YÔ|Ìk Ò~ÁlÈnºb¾k½m´^¶\ºeÃsƘ5ÓµZ°“;°Ž:ÕµhØ»lÄ¥]·–H°EÁ¤Tдdαaµ•B¦‹>¼žM´–G³”EÁ Q¾¢Q©A¸˜L©‹<±‘@«Œ=®B²F©„9¬†9 t+Z8=%B&M)[/m7s;D…FŠKŽNŒPŽRQT‘W “f!³iÅ´‹É·•Í½›Ì¸–м™Ð½ ×ɯéÞÄíîÜëîáëîãîìÛéÞÆçÛÄçÛÆç×Äåٿ꾨îË´íç⩎赘赘߫ß§•Ý¦•Õ£‹Ü­’æééëÞãâîããíåèèéíäæéíêìçéßÅѸ–º–w»›|ʪŽå´œî­šíª˜îºŸì̯êÔ¸ëÔ¹ìÒ¸ìÒ¶ìÓ¹íÑ·íÒ¸í×¼íØ¿ìßÇíàÅíáÊéêÓåíØãîæãëíãëîãêîãêîãêîãëîãììãìíãëíãëíãìíãëíãëíãìíãëíãììãíëãìëãíéãíêãíêäíéåíèäîèåíççîäéîâêîßìíÛìíÜìíÛíìÙîìÙíë×îë×íìØííÚëíÜëîÜèîßçîàæîßæîâì×½Èx=Ìz1Ë}/Î'ш*֊-҆$Ԉ'Չ(Ӈ*҆)׋0ç«YîϖîØ©îÚªíשíרîרîÖ¨ìѝìОêϙêΗçɑç˖ã«Nçtëoæhæmߕ/߶kÔµoÔ²hÒ«aË£YʝSƔ@Ó HîÎwçÄaä|ê|íì}æŠåÒiíäªëè­ìç«ìå©ìå§íä¨ìä¤íä¥ìå¨ìå§ìä¥íޜîݗîޘíߙîڑè¶`Ãt‹DMœX žY œWžV  V ¢]žYMh1W%V"W[#WV]"c$g%d"e$d$a"\–N Ág½]ÆjÁgÀhÄoÄr½g¸c¸aÀdÉ{ʝ7ЯT¤„)·—Bΰ_À¡N°C¤„2¿žTÁ£ZÑ´jÏ®aª‹;¡„7¨‰8§‰:­;¢„0Æ©Z­’D³–G´–FÀ¢T¯Ž@¶–I¯A¬Š;´’F›t+K*Y3uC ƒI ‡I ƒE~A‡EˆGŒMŒLŒLŒPŽRSŽSŽR¥z;¬zÇ·Ç¶ŽÊ¶’ɹ–ÔĬçÜÊíçÒííáìîâíîßíæÒäÛÅãÙÂæÚÃãÙ¿â×¾êɱîÞÅéáÈëçÎìåÉæ̮ۿ ×»šÑ³—Òµ–Ô»ŸáͶíîÜæçìãäíçêäìæËîáÅÞϯη—Æ¡†À–w½›|èŠÔ¢‹îž”í¨˜íÁªìʲì϶íδîδîͳîζîÏ´îѸî×¹ìÞÁëäËéëÓåïÝäîæãìíãëîãêíãêîãêîãëîãëíãëíãëíãìíãììãëíãêîãìíãëíãìíãìíãìëãìëãíêãíêãíéãíéäíêçîæçíåçîåèîãëîÞìíÞìíÝíìÚíëÙíëØîëØíìØíìÙíëØìíÛëíÜêîßéîÜæîáåîáæîáíÔ·Äq/Î}3Պ6ԉ,Ԍ,؍,َ.׌*؎(ԉ&֋)ֆ(á•<è·líϛíפìÔ¥íÓ¤ìÔ¤ìÒ¡ìПëΜé͗çʕæȍäȑݦLìwëlêiênãrá‹ݶOÒ¬^Ч[Ë¢WƛKɏ3Þ§EïÏtíՁÞ|ìyí{ízêpêŽ çá‡íã¢ìå¦íã¥ìæ¨ìç«íå¨íã¥íä¤ìä¥ìã¥îݜîړîݕíݕíЃי?£R†@N UU–T•Y šY§a¢Z ’M w>O#S%U$Z&\&["^$f(k+k*h(d%] `#€=¹c·\·[¿gÀgÃp»f¾h·c¸cÃnͅ$Σ@Á¢H£…-ãM®>›x#¤†8«ŽCŦ]¶•G¿£]µ–C­Ž:¨‡8µ”C·™KÃ¥T¢‡6¤\ºP­D³•H»šM¤„4´“D €2Ÿ}/²ŽB‘k!A#U/qC…QŽO‡C„A„D‹JŒKPŽO‘RQ‹OŽR’T—\µ“X½­Æ¹‘̽–ÕǪæØÅîçÑîíÜííßííÞííÞêÞÌâØÁá×½ã×ÀâÖ¿àÕ¾ëÝÂëíáãæìãäîëíáãÛÀÖƬѾŸÎ¾¢Ê¼ŸÕÄ¥åÕ¾éáÈîíØêíÜëÝÆèÈ«àÀžÛ¾šÓ³“Î¥‹Â“|¯‘|©”|¾–‚Տऋ뽠뼣íÇ°îɵîÌ·íξíѾíØÄìàÍéèÓæìØåîßäîããíêãìëãëíãëíãêíãêîãêîãêîãëîãìíãìíãêîãìíãëîãìíãëíãììãìíãììãììãììãíêãíêãíêäíéçîæçîåçîäéîâëîßíîÜííÛííÛííÛíìÙííÛííÛííÚîìØìíÛìíÚëîÜéîßèîáæîâæîßçîßéαÆx:у2֌2ُ.ّ.ܒ+ے+ޒ-ܑ,ߑ1َ.Ո,ى0׌:ݧeèǍêϑëΘëΜë͚ëϜé̖è˕è˕è˔âǐåµ]ésëiêgímíséjã~Ü©4˦SÉ VŘD̑7á¥FìÍvíߑ܎ëuëuìwënì}ë–åÏyéç©ìå«ìã¦ìæ¨ìã¦íâ¤íá ëç§ìâ¥î٘îړîߘîܗíӆ̑6•N|9‹W¾=à¸kìˀêÉyز`œ?aˆG€Bm8†Y€OP"GS ]$i)o.q/p.o(h&c%n-±d ±\µ^·e±]Âv ¼j»j·dÁfÂr̅ Ï¡D¿¥Jª‹5Ç¥P²‘BŸ}-¦†<­G¨‰=·œRÇ«bµ—G¶˜I ‚/¯?°‘G³•G©<ºšQ½ŸU°•KºšNºœL°’=±‘?šx%©†8©ˆ;vU?!B"L(i@…MŽLNŽNŒNMŠKN‘R‰LˆLŠOR’V•e »¤qĺ‹ÙͦêܾíçÒîêÕîìÙííÜîíÜíéØã×¾ÞÓ¹ßÔ¼áÖ¿àÔ½áÕ¿æܾêëæâäïçéêêåËÛϯÒÀ¡Ò¼žÐºÑ»ŸáÇ©ì׺íØ¿íÝÀèάåä侠æÀà¼™Õ³•Äš|¤~e‚v]e«Œp¸Œk¼–tŞ}Õ©‡Ý¯’á·šëèîѹíàÆèêØåîãäîåãíçãîæãíéãíéãìëãììãìíãëíãëíãëíãëîãìîãëíãëíãëíãëíãëíãìîãìíãìíãìíãìíãìëãíëãíêãíëåîççîæçîäçîäèîâéîáëîÞíìÛííÝíìÜíìÚìíÜíìÛíìÚííÛíìÛìíÜëîÝêîÞêîÝèíÞåîâæîàæïáèʪÇy8Մ/َ3ې1ܓ0ܒ,ے*ڑ)ُ(ً%؉(؉/؇+Îz%¼p'̔Qá¶nåÁêˑé̔é̑é͒çʐçʑåɏãŋëÂrãxëkìhëgìlîqëlßsٛ'É EÙHÁ‰1Џ%îÉpî܊àš.ëmëpìzësîyësãç¤1íËoìٔíä¡ìå¥ìå§íã¡ìå¥íã¤îޞîޘíàšî،èÂk½#†ĶYïІêÌ~èҍìܖêËxèÇvçÅpåÀiÉ KI‹Q¹‡6¼‚1pAQ.oG `5a._,_'g-o.g'h'c%ª^ ²Z®[°a®_µhµiÄt¿s +¹hÇŝ׬MÇ«S¢ƒ*¢J¾ŸJ™{"£ƒ2§‰;ª‹A¾¢\É­^¿ŸMäV³”F´—J°‘G°’K®E¹™N±’E¯ŽDªŒ<¾ Q®:©ˆ:•t)Ÿ}3¦3jHB&H(H"P)j9‚EO‘SP’QPPQQPŽSUŽR‰R¤†GØϧêÞÃîèÓîèÔîê×îëØîìÚîíÛëáÎÜ̲ÝÓ¹ÝÔ»ÝÓ½ÝÒºÝÔ¼éÑ°îåÉíî×îáËåѺßťܾžÛ½ Ý»žß½žäħëÆ©ìħ黣躞乚쾣麜æɦÞа™„_‚kGh]BƒtX¥Šh£Šfª“x­“m¹štÁ¥‚Í·œèʲîÞÆíêÕèîãåîçãíèãîéãíçãíëãíëãììãììãììãêíãëíãêîãëîãëíãëîãëíãëîãìîãìíãëíãìíãëìãëìãììãíëãìëãíêæíçæîçèîãéîâèîâéîáëîÞëîÞíìÛíìÜíìÛíìÜîëØîìÙííÚíìÚìîÝëîÝêîÞéîàèîàéíÝçîáåîâçïàåĞÆy5Ѓ/ԉ/Ӈ+҆(ԍ$׍%؋)ֆӃсӁ#ÑÐ}"´f¦a€;ӜTÚ§gä¸}ß½}ãŁæljänjäNjãƃæÃáŽímìjìeìjînínìnâoԑ"À–=¿‹0ؚ/îÏvîۋݫBåiêgìnìqërìrízìwí¥ä¯Cã¼ièԊæՊåՎíâŸìáœíãîá™îܒìÊpà£FÃ1ì΃éËêÊ|ì΀îЀéۓìÍ}éÊwèÈqçÅjà½bâ½_¯€&º*¬k‰OŒU©n*¥m)¤q+~QDF"R"X#c(k+¢S +¸` ¨U¦V¨X©XªZ±c¹m ²c»j +½wÝ´UÅ©QĤT¼JÈ©S§‡9¦‡>¦…8ª‹@Â¥^¾ŸUÀžOÅ¥YÁ¡S·šL§‰8§‹9·–G«H«‹A³“J 6°“D¼›L¤„7‘n©…=›r'[1Q,O,N(O+S,yH’U“TRŽOQQP’S’SV’W“W“W •dÚƗíâËëáÍîèÔîèÓîê×îìÙîíÙêâÍÙÌ´ÛÒ¼ÚиÜÒ¼ÜÒºÛӹ㹟㿥éÆ®èÅ­êÇ°éÁªä¾¥à¹¢à¸¡à¶¡ä¸žè¸ ä²™ä¯›Ù¦‹Û®’í¬”è èÞ¾îò✑q‚w[tkQ¦wª‘w¥v¨•y´ Ê·™ÔÈ«ãÙÅëßÌîéÖîì×íìÝëîáéîãæîåäîåãîéãíëãììãëíãëíãêíãêîãêîãêîãêîãëîãêîãëîãëîãëîãëîãìîãìîãìíãìíãíëäíéäíèçîåçîåéîâéîâêîåëîßëîàììÝîëÛíìÜííÝííÜíëÛííÝíìÜìíÜìîÝêíßêîàèîãæîâçîâäîäåîÞåïá⾘Ât5π1Ѕ/ф*х&ЄЅ Є!ӃЁÏÏ~ÌyÌx¼h¦X +¢^¹q.Á=ņDÓ¡_ϟWÛ¬iÚ³pß·{á·vàº~ç°MêvímíiîiìhíkîlìlãmхÀ‡ã¡8îÉqîԆâ·Jåjëhëlìlíoëoìpìoê€ì¹Hã¼gåÀuá½näÁpäÂqçÅsã¿gçÃmêÅoà§GӒ6î̀ë́êË~ëуíЁíÑ~ìÎ~êËvéÇqéÊrèÇnäÃhãÄbܯL«p˜RMŸ_¯l»w'¾2±r"†Mo<Y'IK P#z@©X¦U¤S¤R£R£R§U¬]±]ºeЈ#Þ¯PÁ¡IÁ£P·žL»L¥…6¯E¼žZ´—P¯‘B¯‘B¶˜I´—H£V¦ˆ8¤„/¨Š9¯’B¤ˆA°•Kª‹=’q%Ÿ}0¥„6–u)™u%§€0‰]W/M,N,Q,P-m?Wš]”U“RQ‘SR“U’TQ‘V•Z‘T•U •Z¥CãË£Ö îâÌíèÔîêÙîëØîéÕíçÓÜÓ½Øλ×θÚÑ»ÚкÛѼ׭’ยฝพ㹣⷟߲œÛ²›Ö®•Ò¦Í …Èœ{ր¸Žv¤‚_ϏuäDzãæßãèæééÞ¥ˆn•i©”}Ê«‘·†½©”Ǹ¡ÝÍ´éÛÇíæÍîë×îëÖîì×îëÖíìÛîíÜííÞêîáçîäãíçãíéãìíãëìãëîãëîãêîãêîãêîãêîãêîãëîãëîãëîãìîãëîãëíãìíãììãííåîêåíéçîèèîæéîâêîâêîâëîßëîâííÝííÝíìÜíìÜíìÝìíÝìíÞííÞìíßìíßëîáêîßéîáèîãæîããîæäîååîáèîàܵ‡Ãv4҄3҇2҇)ч&ӆ(΃!΁ Ì}ЁÏÌ|ÌwÊsÄpÂn¬] +œX «gºx3¹y3·w-º~4À‚6Ć>ǍBÎ@̒Bá +íníhìeíeíeíjînípãgÙvֈìºTìÍsïÏrÝfèdçfëmëlëkêjìtí|ì¨+â»kà»kã¾oåÁmçÄoçÆuåÁjå»[à©Fä¦BìÅjêÍzì̀ìÌìÎ~êÊyëÌ|ëÌzëËxéÈmêÇnéÄeèÅfãÀXØ­?Õ¤7ªg°c °d ´mµm²k¦^ +¥_£X¡REAq;y>¥V¢R¢RŸP¡OžJ¨S®]³]º^Ð}ߧKÀžE»œF·™G¾£X©Š@ª‹@Á£[½S£[¶™IƧVĤU¾žK³–F±’A·œP¢8¢ƒ3­D¥ƒ3•s!•t"z)Ÿ{)´‡:Ÿmk?J(J+K*K)l;ŠO›\ `šZ–V”T–V”U—W”X’U“V—X•W”U•X—aŝfÔ¼ëßÇîèÔîê×îëÚîëÕîéÔÞÓ»ÖͲ×ζ×Í·×͵×ʹâ‡Ó±šÉ¬”ΩÊ¢ŽÇ§—Þ…·—~³–}«p¤‰q¢~a«z`ŒiI†`DÖynãÕºãâðãê×䩛©|fº•€×­›Ì¬•Ê· ÖÊ´çÛÉíåÐîêÙîìØîíÛííÙîíÜííÝîíÜííÝííÜîíÜëîâèîåæîèäíëãìíãìíãêîãêîãêîãéîãéîãêîãëîãìîãìîãííãííãìíãììãíëãîìåíçèîåéîæêîâéîåêîáëîáìîàëíàíìÜîëÚîêÙíìÜííÝíìÜìíÞìîßëîáëîáëîãéîáèîâèîääîæåîäåîäåîãéïÝÚ¯ƒÂt3Ђ2Є*І(҉)Ӈ(Ѕ σ"τӄӄ҃ҁÑÍ|ËvÉp²^šSž[ ¥e±o'²q'·w&¶x(·v(³t±sÁwêtílíhîeíbídíhíjínâdÝuå¢"ç»Nì×}Úuècèdèfëoègégíyíxëˆê¹QäÁoå¾gçÀhçÁgçÂjå¼^Þ¬Gؕ0ç®LíÏ|êËzëÍ{ìÏëÌzêÊvëËxìÌyêÉuéÈméÈpèÁbæÁ\ã¸Lß±>ب8¿ˆ#³l·k ¶m¶m±g°e®d²eª\ ­_ ªa §`§]ª[£UœLOœMŸP£Tª[³a»b Åfϔ6³4¶˜Eɯ`ÚÁpÓ¹p«C»šO®>¼žX¼ŸP̱dÒ¶mʨ[¸™J¾ S°’J¢‚;§‹D¬F¢‚3™z.8¨‹=¡{&œr#ˆZV.I*J(P*k<ŒL˜W™Y™Y›\™Y˜X–V˜X™Z˜[š]–Y—Z˜[™Z¡f +¨k¤u+ϸ‘äÜÆìâÐîéÕîéÖîéÕîèÔßÕ¿ÕÉ°×̵Õ̵ÚѺ×η¢t¢‡u¦”w©˜|¹ªàà×ÙÓ은®Ÿ…µ§‰§’s¢vW¦gM‡\;V=ÒjS䴈ããÐãçÂ罦ڮŠåº¡îƳÝįå×ÅìäÐîèÔîêÓîêÖîì×íìØîìÙíîÜîíÝîíÝííÝîìÚííÞíîÞìîàëîãéîææíëäëíãìíãéîãêîãêîãëîãííæîêçîêèîéçíéåíìåíëåîëåíêæîçèîçêîäêîäëîáëîáìîàëîàìíàìíßíìÜíìÛíëÛíìÜííßìíßìíÞëîáêîáëîâêîàèîâæîææîåäîæäíæåîääîåéíÚרwÂq.Ë}*σ/Ӊ.׌/׋,֌'Պ)ԇ&ӄԅсӄՅҁÎ|ÍyËu½k­] ¦X›S›W ›Y¡e¥g¨m¤k¦n×zîoìfíkìeîgífíeílïräjÙrç¤)êÅUޟ%â^ébëgêléiêcíqìtìx㎠é½\ã½bæ½dç½eâ»Zá´LÞ¨Aך5îÊrêÊuêÈréؓëÍìÍzìÍzìÌzêËvéÊrçÄgèÄgåÀ[èÂ[ÞµFÛ°=צ1ԟ7³m¼n»p¹n¶k­e ¬f¯e¯g­b¯c ­c®a «] QœKžLŸOœL¥V¨Z´e³^µ[ю4¶”7¯Ž7ΰ\×¼ißÄw¸U¾ ZÁ¢V¼X±–M¸žVÀ¥_¢ƒ5¶–D»K¯‘Gªˆ@¬ŽEÁ¢Z­Œ@¡4¨‹@«‹:ª-˜l~QT-S+d4zE”V™Yš[š[›\›[›[™ZšZ_š[›^™]™\š]š^¦hªp«rªr"¾•Q×ƞçÝÁíçÑîë×îêÖîéÕéáÌåÚÇäÚÇçÝÌåÛÉåÛʞ“v–‰lœ‘tž’sż£ëêìéê枧ÓÄ«Ý̶̳š©}a“\=X:ˆT6ÁmTé’zãѼãïäãäÌæçÔæáÍäãÕîâÍîêÕîéÖîêÕîêÕîëÖîìØîìÙîìØííÛîíÞííÜîíÛîíÛîíÜîíÞîíÜíîßíîßëîäèîéåíìäíîäëíäííæîêêîæëîãìíãìîâëíâëîâêîäêíäêîåèîæêîãêîâìíàìîßìíßìîÞìîßííÜíìÙîë×íëÚíìÙìíßíìÝìíÞìîáêîãêîãéîäéîåçîèæíæäíçãíèãîçäîååîäéíÝӟjÃm'Ê|0ӈ3Ӌ/ӌ+Ԋ$ԋ$Ԉ'ЃρρՆ"Շ#҂ЀÒπÏ{Ñ#Éw¿m¸f®aR”MŽO…N‚L‰O™Tësîjígíeìdîeîfídîiì{éjÙmæ¥ì½5ÛcãVé[êlíqêkéiìoìqæ™ ç .ç¾dã·[à´Yß²VÛ¬Eؤ=âµQëÊoêÉsëËvíËzìÍyìÌwíÑ}íÏêÊråÄeäÁZä¼Sà¸Lã»O߶Há¾MÚ»UÔ 3¼|¼o¾p¹o¹j»n¸k³f ±e ±e °d ¬a­b­_ QžLO˜H˜K¤T¨Z¬\­\³bÁ$½•>²“>Æ¥VÌ°dдkºžS¹PÍ°l¼ž[gŽx,­?¶–GɨZË­aºžUª@¶”G¸—K²’FµA®ˆ5§„4¦~'Xb8Y1sA“Y›^ \Ÿ_ž]]ž]ž`œ]–X_˜[—[˜\—[›^š]£h¯q´vµw"²t"«r%έs×̬çßÆíçÐíçÓîéÕîéÙîè×îç×îè×íæÕîçÖ¹¬Á²•È½ ¼²šÛÕÅååæææèßÛÌÜ˱à˲ػ¡´‡m—eFŒgD£€^ß·–åÝÃãéëãçîãåìããçãæêãìèçîáëîÝìíÚíìÚîíÙîíÙîìÙîíÙííÜîíÝííÝííÜîíÜîíÝîíÝííÞííÞîíßííàíîâìîæëîåêîçëîçëîäìîãììáìíâìíàìîáìíÞìîàíìÜìîßííÝìíßìîßííßííÞíîÜííÛíîÛííÛîíÚîíÙîëÖíìØíìÛííÝìíÞëîáëîãêîåèîæçîççîçæîçåíèãíèäîçãíèäîçäîåëì×˚c¾l)Ë|0Ѕ.Є+҈*υ&φ#΂ ΁Ì΀Շ"ֈ$׋'ۍ(ݍ-Ն&ӂ!҂!т!΀ÈzÁqÄpÀp¹h ¯c§\£[ XÒníiíkígìcîdîbîcîdísì}éhãsá’áƒæVçWèbêjêiçfìoëmêˆé”ã›.à®MÞ­HÛªFÝ©CØ¢;éÂbéÆlêÉtëÎzëËtëÊsëËuìâ–îÒçÅiæÄgäÀZâ¸Hß´DÛ±AÝ°Aש8Û¶EÒ¡5¿‚¸l +¶l ¶k¹l»n¼o·l´i ´h±e¬a¬`¬a§\—HœNšMžO¢TŸQ¤T§W±a »{¾˜B¦†4»™LÄ£V½œM°’F²•J¼œQ½¡[¹ŸV¦Š9¤…5¶•K«ˆ:º™KºS²’Hº˜P§‹A£5®…3žy-Ÿy(‰b d9rAV bž\ ] ] _£b _ž_Ÿ_š^›]›]_œ^œ^ž`™]¥m ¯s²u²v²v¶x!³t"¶„;ÒĐÔ˱çßÌìæÕíèÒîè×íèÖîêÚîéØîêÙîéس˜ÔÄ­Ôǫ̽ ØйéééããâææàÚ˶ÛÆ­Ô¹›Ï­’̧‰Ö¸—éÖ»ééÕãìêãåîããêããããããããâããåãåìäéìæìçéîéëîåííÞííÚííÝíîÞííÝíîßííÝííßíîÞíîßííàííáìíãíîâííâìíâìîåìíäííâìîãíîâìîãëíäíîáììßíìÛíëÛîëÛîê×íèÔîëÙîëÙîíÜîì×îíÚííÚîîÛîíÚîíÚîíØîë×íëØììÞìíßëíàêîãéîåéîåèîççîçæîææíçæîæäíèäîçäîæäîæäîåêêÓ͒bÆw5Î{-Ì(̀(Ѕ,̓$ц&ԉ(ч ЄԈ֋&ڋ(؊&܎+ڌ)ڌ+ً*׈&؈&؍1և&т!Ì{ÉzÆtÃoÄqÆrÁpÆpãmëhîjîiífìcíbíeîiê€ê{êgévé€âZæSå\èeêiêhêjísìqç¡ ãƒäž+Ù¦9ئ@ן9֞2ëÃeêÅkçÂgêÆpëÉpíÌxêËrêÑåÄeæÃ]ä¿[å¿Xß·HÜ°Aܯ=Ù©4á²?Ô¤1Λ-Ŋ$´i¦aµk µj µj ¹l¸kµj ¶k ¶j ¶j µg +µg ®a•EEH˜M˜P©^¥W¢O­]¿|"­‰0£„0½žJ¿ŸHÀŸH°@²”D¾žSŦXÌ®^½N¯Aª‰:—t¦†7·˜P®A¶•J 6zU“o\yLzE|GP£a¥c¡a]¢`Ÿ_\ž]^ŸaŸa_œ^›^›]™[ž_¦j¯t³v´w²w³x±w®r¬pàZÎÅ ÙѼëãËìçÐîèÖîèÔîêÚîéÙîè×îéظ¦Œ¼ª—ö¢È¼ Çº¤ßÜÕããåäàÖÞ̳ç̼ëÔÁìÚ¿êâÇçêØäîããîèãìëãçìãåëããçããæããããããããâããëäåíäêíåëíéîéìîßìîáííßííßìîàíîßííàíîáìîâííãíîàìîâìîäìîåíîäëîåëîæííãìîçìîäëîèìîçíîãîëÜîëÜîéÖîê×îèÕîèÕîçÓîèÕîêÕîìÚîëÖîíÛîìÚîíÚîìØîìÚíëØííÝìíÝëíàëîáêîãéîåèîææîèæîèçîéçîæäîçäíèåîååîääîååîäëéÊɉWÆw3Î4Ӈ3Ԋ2Ѕ+ӊ+Ԋ-Є%ԇ(҇$֋&ڐ.܎,׈&ڌ'ً'ً'ۍ)؊&ً(؉&Շ"т!҃#Ï~Í|ÈvÈwÃuÇxÁvØzìiíhìgìeìeìbîeîhíoêoêtê{êgælâMçRç`éeçcèhêmëqë}êˆà€Ù¡*Ô 7ԛ.Ԝ.ìÄfêÄdêÄiêÅmìÇoéÇmêÇhæÃcèÄdå¾Xæ¿Yá¹P߶MÙ¬=Ø©7Ó¥2Ô§9Θ&˕(ƌ&´oµq ·l»n¸l +¹q½qÀs¾r½p½o¼n¹l·i  Q‰@ŒD‘HH™PœQ P«]À{ °ˆ/«‹9µ’?»›JÈ«[°‘Dš|+¿ŸXÕ¸r³•F§‡4©‰:¯Ž@£€/šx(¥ƒ3²–I­=_GwS™pwNˆR–T¡`£c¦e¤d¢b¦e¨f£c£d¥d£bŸ`¡dŸa¢dš]š^š`¬o®r ²u²s³w²y³y·{"²v­p¬y,Ñ»‹ÔʱàÖ¿íåÑíæÔîçÖîè×îèÖîêØîéÖ´¤ˆ£’y¬¡Àµ™½¯š¿¯žÍ¿ªàϾëØ¿íâÒçéÛãîßãîæãíèãíåãîÞãîããîêãíìãììãéíãäìããêããæããçããêãäíãæîåëêèíçêíáëîáëîåëîäìîäìîåíîãìîäìîãìîãìîäëîçëîæëîæìîåëîæëîæëîçìîåìîäííâîìÞîêÛîêÛîê×îèÔîçÓîçÔíåÑíäÍíåÎîçÑîéÓîìÙîíØîìÙîë×íìÚîëÙìíÝííÜëîáêîâéîæéîåæîéçîçæîèæîéæîæãîçäîæåîæåîäæîãåîãíæÆąMÉ{9φ3ӈ0Ӊ0ӈ/Ӊ-̓%Є$ς"҅%Ӈ&ф#Ӆ%Ն$ԅ!؉$؊&؉&ً'׉&Ԅ ҂Շ%Ԅև$҃ԃ ÑË|Ë{ É}Ì}äuë`íeífíeìaîeìbëcêfç} ãy +ìoèáPåOãYéeéfçcëléoélèä}و ֖ϖ*В#è¼YèÀ]èÁaéÄeçÂdéÄcçÂ`åÁ[çÁ`æ½Wã¹QÝ´FÙ¨<Ø©;Ó¡2Õ£6Í¥:Ì 6Ƒ'ċ#»rÁp Âp¿p»n½q¿pÀt¿q¿s»o¼m¿q¼m²aŽAˆA†<ŽD’J”LšO¤W½y±†.±=«ˆ9¿ŸK³“F®ŽCªŒA½ŸT½žS¥‡: /£ƒ3¦†2°@­Cª@µ—H“r%9!fCwRxJ›^¥a¦d¤d¦f©g§g§f¥e§g a¦eŸaŸaŸ` a¡d¥g™Z£i®r ¯t²w¸|´z³x¸| ¶z³x±u«o¹OÔÇ©ÛнìãÑíåÔîçÖîèÖîçÕíè×íèÖʹ¢µ¤‹¥š‰·©•Èº¨ÐÆ°ÝÓÄéÞÇîèÙîëØëîßæîâãíêãìéãîâãîæãîããîèãîèãîêãíêãêîãçîãäíããéããêããëãäíãåîäìëéîåéíèêîæêîçëîäêîçëîåëîåëîåëîæêîèêîéêîéëîçêîèêîçêîéêîèìîåíîáîìÞîëÚîè×îéÖîèÓîæÓîæÔíäÓíäÎíãÍíäÎìãÌíçÎîêÒîíÕîìÕîìÕîë×îìØííÛëíàëîâêîäéîæèîæçîçæîêåîêæîéæîåæîäæîäæîäæîãæîáçîàî⿽}CÅw5Ѓ4х0Ї.ч-҇+ˁ Ế!͂΂ Є%ц"Ӆ&ӄ$Ё ԅ#ֆ"َ)և$Ն$Ն"Շ"֊$ӈ$Ն#ԅ Ն ԇуÍ} ÌÓ{éiígêbíeídìbí^ë^èVèWë]ê}ä†ã]ÜIÞPècëkæaèdéhéiéáqÞgÙoÎ ȆéµPå¶Né¿Yç¾ZéÀ[ä¼UåºXä»UäºUâ¸Qâ¶Nà´LÝ´Má¿`äÆoéÍræËsèÊqÞ¾b߸Xɏ5ÃoÃd Èn¿l¿q¼pÀsÀr ½n ºl»nºm¼o¹j¬] ŒA…9ƒ:‰@’JG—P­f°+»•I¨‡5¬Œ5¬Œ;²“Aµ”BÆ£T¾œQ²“GÀ›L¦…6³Œ9¶Ž<ɧ^­‹<™w bE9 f;H¡_§d©fªgªf¨dªh®l¨i¢c£d¢b¤f¤e a£dŸ_§f£g¦hªm°r µw¾‚ ³v²w¶y·{¶{"»~%³w"¶z(¬q&Ê®yÕ˯ëâÒíæÕíæÕíè×íèÖîé×íèÖÕīϹžÇµŸÅ¸§ÔÈ°âØÆìäÔîèÙîëÜîìÜíìÞìîãçíæãíéãîåãîããîããîããîæãîçãîêãíçãëíãéíãæîããíããìããìãäîãçîäêìæíééîçéîééíèêîçëîåéîæêîæèîèèíêéîêéîéëîèêîééîéëîåìîãííâîëÛîéÖîêÖîèÕîéÖîæÓîçÔíåÒíæÐíäÍìâÌìâËìãÌíãÊíæÏîëÕîìÔîìÖîìØîì×ìîÝíîàëîâêîäéîãéîãçîææîçæîçæîææîæåîååîåæîâçîãèîßèîßìß¿¹}AÅv6Ì1Ë~.́2ˁ'ˀ"́%̀$É~Ê ̓%Ѕ'́"΁ ς!Ѓ"ЁӃԆ&Ո&х ԇ(؋+Ո,Ӈ(҆%х#Ѕ ΁ρ΀ÏՀÞsìfê`íaëbìaì_ë`çWæRåPéYèbã`ÜOÝMäVécæeã_çgëpêƒ àhÞdÛfÝnÌyá¤8ä­@å²JåµJæµLæ¶Nä´MãµOå·Oä²KÞ±Jâ»YçÈpäÆoêÑëԄéÎyéÏzêÎzæÊtçÌuèËsê½g֍3Äu»o ºn ¸l·kºo ºm ½p¹l ¸k »l¸j©Zƒ:x1{4‚<†?ŽH¥Y ·‚/¬‹=¥‚7Å¥R¶–A±”H¸šKȟT½šN»ŸP¿šK¶•G´<µ‰/§#”kuVX4{Jœ_©g§f«k¬k¬i«hªg­j¯l©f©f§f¦d§e¤e£g d¡b§f±s ¯q +°u±r ±u²u°s °t±u³w°v³v´y!²u#²u#´ƒ<ÖÕéâËìãÏìåÓîçÖîèÖîéÓíèÔ×Ƨá϶âÓ¸ãØÄéàÊìãÐîèÕîêØîëÛîëÚîìÜíìÜéîáåîååîãäîáäîáãîâãîäãîäãîçãîåãíìãêîãéîãçîããíãäîãåîãçîãçîãéîãëíåíëæíéäíëèîéçîêçíëèíëçíìèîëéîêéîééîéëîéìîäííáîëÝíè×îèÕîæÒîèÔîæÒîèÔíåÒíäÎìâÌíãÍëâÍìãËìâËíãÍíäÌïçÌîåÊíèÒìëÙëåÑéãÍæÙÅæÞÊèãÓæåØæéàæïàçòåæòçåòèæðåäîäçîãæîáçîáæîÞçîÜëÞ¹³v4Äw5Èz,̀1Ë/ʀ&̀%É}#É|$ˀ ΁$х(Є'ф)ς"΂$у%Յ%ӄ$ԅ$ӆ#Ԉ$Պ*֊)ӈ#ӈ'х#στЅρЁуЀÒ|ègêbê_ê]îfíaë_æYâQåRáOáRæYâXØGÞOçbègå^ædërådÞ`àcÚ^ÞeÙká‘$Ü¡-ã©>ä¬Bä¬?ã®Aà®Fâ¯Fà­BÜ©Dæ¿_êÍwäÇrçÊuéÌxéÌxéÌwèÍxéÌwèËwæÊuèÌwçÌvæËsåÃiН9¹u ¸n »o »q +¼q ºl ¸k ¹k ·h +·h +šOx5n+q.w4…=‰D•M®lµ‹:¼˜H̪Z¿žMÄ£VÉ©X½˜H·–HáR»›I´•F­‡0Šc +xKjBh?‡Q¢d£c®j®k­h­k¬m®j«hªi¨j¬i¥e¥eªg±n³s¯r¬o«mµw´tµu ·z­q +²vµz¶x±t±u²w³x³x´y#®v!¯w$«q!Ü\çÞÂìäÒíåÓíæÑîéÔîéÕíèÒÞиçÜÉîëÖííâííàîëÜîêÛîêÜîéÛîêÙîëÙííÝëîßèîãæîãèîàçîßçîàæîáãîããîèãîèãíìãìíãêîãèîãçîãæîãèîãçîãæîãçîãæîãéîãèîãêîãêîãìíäìîåìíçíìæíìèíëéîëëîæíîâîìÛîìÚîèÔîçÓîçÒíåÒíåÐîçÓîæÒîæÓíåÎíäÎìáËëâÊìáÈëáËìÝÈ津݆yÞpfÕmbÒi^ÆVHËaP¼PA¿PB»Q@¼PB¾_RºdJÁn]Âxd¿…mʝˆÓ·¢ééÚæóáæîàæîßæîÞëضµt8Ãw5É{1΂3̀*́/̀.́)Ë~'΂*ρ%Є,ф)ς%ς$ρ$Ђ$ӂ!ֆ(Ӈ'Ԉ-Ѕ!цՊ*Ԋ#҆#ф$́Ѕч ЃρÊ}ÈyÍ{Ûuébìaìdë`íaìaê^äRâKãNâNãQÛIÙJÜNßYåcåaåbæiägÞ]ädÚYÛ_Ý`Úpْ!ޞ,ߝ*ߞ,à¥3Û¡5Ú¡3Þ£<ã»[äÅgåÈpãÈrèËtæÉtèÍzéÍ|èÍzêÍ{çÊuçÍwèËvëËuéÍwèÌváÄdܸVÕ¥D¶u Âv¿q Àq½p½n»m »m‘Ep0d+^&c)s6y:…@¡W ®w!Á›DÅ¡P¹™EáQÀœFµ’:°’@µ–Hª‡/¯2Œd b?c=€NŸ_«g©f©h¯j­i¬g¯k¬i©fªg©f«i«h¦c§g¬iºw ºx ½{ºx ºw +ºx ·v +·u ¸y²t ´wµy³w¶zµx²wµ{²vµz´x#¯u «s¦x1åÖ¸ìçÓìäÏíåÑíèÓíçÒíçÒçÝÂîéØíîáéîéèíéëîåííâîêÜîêØîêÖîêÖííÚìîÛëîßéîáéîàêíÝêîÝéîßæîàäîäãîéãíêãììãìíãêîãéîãêîãëíãêíãéîãçîãæîãçîãèîãéîãëíãêîãêîãìîåíëåíìæíëèîçìîâííÝîë×îèÔíçÑîèÒíæÑîçÐíäÍíäÎîæÑîåÐìâÌëâÌìãÌëáÊëáÊíàËàˆßa\á`XÞ\VÚ\PÏUIÊ]IÆUF¾P9¸N8ºM9´E2®A-°H0²I5ºRA±K2ªE.±M;®J8¾wXÔ·—êîÓæõÝçÖ°­r7Åz;Ê6Ђ1ф0σ.Ԇ5Є/ф/ρ-҅/҃.Ӆ.ӄ,Ђ)҆,Ѓ(҃,Ђ/Є#Ԉ'Є$ӆ,҆%ӈ"҇'ς ΂́΄Ђρ΀ ρ Ѓ Ó~ßdëaêbìbíaí_éZãNåNâLàLâPßM×CÓEÞRÞTçcäbädäcädâdßdÖY×V×XÚ| ד۔(ڗ#ؕ&ܗ,ؔ(â±HãÃdåÆläÉsæÉwçËtçËyèÍ}éÎ}éÎéÎêÐ~çÌzêÏzèÌxéÍyçÊtãÆmßÀaÞ½]â¸S͐$»rÃ}»p¼n ½p¶k ¢X ‹Dl+Y)LAb/9ŽE [ª{&Á SÆ¢M½™BºŽ9ª{%Ÿu }"˜k “ih@uE˜\³n ®h°l¯k²n³m ®j®j­kªk«i¨e¨d¨e¨f¨dªe©i·s +¾~¼~¼~½}»|½¸z¹{¶w µx·z·y·y´xµx³v¸zµy·x ²t¬oªo'¼œdêàÃìäÑìæÒìæÒíæÑíèÔíäÈìíÝêîåéîéèíìçíìéîêííáîìÜîë×îìÛíìÜííÝìîÞêîàêîàëîÞëíÝéîßéîßèîàæîããîçãîçãíëãíìãíìãëîãìíãìíãìíãëíãêîãéîãêîãêîãéîãêîãëîãìîæîêèîçëîäìíßííÝîëÛîëÙîæÔîåÒíãÏíäÐíåÏíåÏíäÎíæÐíåÎíãÍìäÎìãÌìãËìãË橚á`bâZWã^Và_TÔXFÉS=ÀP=»K:»N8¶K8³I6²I0¬B(¬D(«B*­D,¨>*«?+±D1´J1°M/±M.®L-ŁYÙ«†¶tȦQЍIщ?ы?ъ>͆6Ή9Ή=͇;͈>͈:Ї?ՋAӐJ՜Yâ­háU׈@҄0҃*ӆ*ӆ1،2Ӈ(҅%σ σ̀ρÎ~ЁЁ҄҃фØ{ä^ëeê]ì\ì]ë_çSàIàJÞKàNàKØDÐ@ÔFÙMÛRàWâ^çoàdábß`ÙZÓNÕTÖ_ÔrՄ ӈЇЅؚ/ä¾YæÅhãÄkæÖ£æÉuéÌ}çÌzèÌ{çÌzéÏ}èÌ{èÍ{çËuèÍ|êÎ{êÍxéÐ{èÏxãÅ]ݾYÙ·NÙ°@ã¾VíÅd՛7ÃyÄy½r¶i¹jœOt0K24])ƒ@›P f™G·7£y#˜dt?|FZ4i=yEWªj´j¹n³m ·m ¶r ·s +¶o °n³m®k«g«h§e©h¨jªiªh©fªk¹y ¿~¾€¾€¿‚¿€½½¶w ¸y¸z¹{¹z´u³s°s³v¶x¸y´wµw°p©i$˜j)ØÉ íåÔíçÓìæÑíçÒîèÓíêÑëîäêîèéîéèíëèîëçíìéîëëîäìíãíìàííÞîíÝìîßëîáëîßëîÞìíÜìîÜëíÝêîßéîáåîããîèãîëãîêãìíãìîãìîãëíãìíãëíãêîãëìäìíãëíãèîãêîäìíäîèçîæêîâìíÞíìÜíëÚîêÚîèÖîäÑîäÏíâÌíáÏíãÌìãÍíåÏíåÏíäÏíäÎîåÐîÜÅîàËêƹáYUãTPèc]ß]TáaPÖ_LÇO;ÃO>¾L:·G/¶J3¯E0­B+©>#ªB(²F/³I5®D5ªA(¬?,±F7®O4°G(µC%¸G$½Y:Ý pà°zß­uÞ®sâ¸}ãº㼁è‰éőêʖíÏ¢îѤïÕªîÔ¤ðÔ¢çµ~ã–_âXމPۍLօ=Ԇ,҅+Ӈ+ф%΀!ς#Ѓ#ӆ&҅$ӄӃρσ҇ӇԆÙwä]ë_é[ê]ê_é[âKàIßMÝLßOØGÍ<ÔEÒCÖGÚNßXåxáaÝ[âeÚ[ÑQÒRÐOÛ^ÑcÏuÎ} Íæ»YæÅiäÄhçÆqèÉsèÏèè³è́æÊ}çÌ}èÍæËzçËyçÊtçÉxéËyçËuíցëߊäÈiàÄaÞ¼TÛ±DݵLÒ 8ˀÉÈ{Ãvºm ¶i´h¬^ ‡KZ'<0Cs=–Y ¹%¥z"‹c pAY+P%j;ŒQªf¯j ´p ²g µdÁ|³l²o +´q ·o²k®j®i­j«g­jªj«m«k©j©lªkµx ¾}¿¿¿‚Á¿}¼º{»}ºx¶yµw²u¯r ­q ¬p ´x°t¯t©n¨l§l œ\¤‚LëãÆîçÔîéÑíæÏíéÔíîÞëîèéîééîêçíëçíìçííæìíçíìçîëêîèìíâíîßííÞëîàìíßìíÜííÜìîÝëîÝêîßèîàèîâåîåãíêãíëãìíãìíãëîãëîãëíãëíãëíãììãìíãêíãëíãíçäîäéíÜéíáììÝíëÙîê×íé×îèÕîåÐîäÏíâÍíáËëâÊìãÍíãÎíåÐîæÕíåÏíåÌä·¤âƒv됆éooì^]ë`Xß[Ná^OÞ`OÌW?ÄQ7ÂP9·O0µK/²H,³L0«H(´K)¶L.±G#±I0±J.¬E*«B)µP9±O6³J+®C&¬?È{MÞ®wÙ«tÜ­tß±{߶€áºƒã¼…äÀŽçŚêÊ îЫíÔ±îÔ°îӬ踊ލ]â[ߋTå’^àWۊKҀ6т.ф*σ(҇+ф)֊,Ԉ'ٍ1ٌ+׌%҅ԉ، ֊ڍًÙjçWé\é^ê`é^åLàHÚIÚHÝQÝQÒFË?Í>ÔCÔFÙLãdådâcàbß`ÐPÏPÏOÕUÖUÉXÄkڗ3å¿^ãÀdéÉnéÉsêÌzëá¤éٚéҌæË}æËyåÉxçÉxæÊtåÈqåÈråÇqçÊtéҁéÏtçÊoãÂ^á¾YÞ¹OÙ¯JΗ1́ʀÉ~Æ|Ãw¼o¶g°a¨`œUy=X$;/Q(‹R}JW/\2l>ŒU£d¯i¯dª[¤U®[Îã©:Á„±n¯m²j´k«k­j«h¬i®k¯kªkªl«l§e¨j³v¾|½¼}·w¹{º{¶y²v³u¯r¬oªn ¬o¥i¢g¡e d¢f ¤g¡b +œ`˜] “W‰Y½¬íæÐìæÎîéÑíêÒìîãëîâéîêèíêèîëæììæìíæíìçíìçíìæíìéîèìîåìíàìíÛìîßííÛìíÛìíÜëîÞêîßéîßèîáçîãäíèãíêãíëãìîãìîãìîãëîãìíãìíãìíãìíãììãîëãíáäëàçëÚêëÙëëÙíêÖîèÓîçÒîæÑíäÏíàËíàÊíàÌíßÊìãÌíâÌîåÐîåÒîæÐèÀ¨ç„tîopîeeìd`æSRçUKÐSCÖXEÑO8ÇT/Ä|CΊR¿|?¸i9´N(¶K)­D&¬?¹M(¡1¦7¬9£0¥-¢3§7%Ÿ1Ÿ1¯P,à­yÞ²zÞ°zÜ®wݳ€áºˆß¸„Ἄ໏äÁ˜êǟìÍ©íÓ±íÏ­íɟޓfäbå‘bä_ã‘_â[â[ފQÔ;΁/͂*ф+ӆ0Պ.֌/؋.َ.׌,׎-֌&Ո ؎#ؑ!ّ"؂ÞVçWç]é_é]êZÝJÛKÚKÚLÙPÔMÊ?Í@Ë>Ï>ÒBÖIßVçjÝ\àeØZÉHÎMÑMÖTÐU·_å³NçÂaåÃjéÉrëÍ|éË~êρëÛ êґèÌ|äÈvæËxæÇväÇrãÆsâÆsäÇqåÈrëÓ|æÆjâ¿dß¿Zß¼WÚ³MÕ­EМ3Њ#΄΄#̀¿r»l¶i´f +ª`©^¦_“Pj7A#9E J&i7•V b«g¬d¤Z¨WªV°`̄Ü¡4å»Mã¶L®p±m²r ­k¯k¬j¦gªl«j¨g¦gªk¢dªj¦h¨k¯q °r +­r «n¨i©i¬kªj©i¨f¦h§i b£g  bžabŸc` ˜Z›` •X‘VxH€b/ìâ¿íéÏîêÔîêÓìîáéîééîêéîêèíìçíìæííæííçííæííæìëåììèíêëîäíîßííßíîÜìîÝìîÞëîßêîßéîáéîáæîãåîåäîèãíéãîìãííãìîãìîãìîãíîãìîãîìãîëãíåãìããêÝåëÝèëÛëè×íèÔîçÓîçÒîäÏîãÍíàËìÞÉíßÊìßÊìßÊîãÍíäÏíåÏîåÐå‡yêreëfdë\TÙM@ÇI>ÎUC·B*¿J3ÉU8Ü bϜV¾y9¹t5ōJÀw<¡E›1+ ’%‰Š˜ •  „ƒ~}זiÚ®uÜ®vÚ«wÞ²€ß·‡âº‰â»ŠàºŽâ½åÀ—æ™êÇ£ìΫëǤ丑ۉeá‰dâbâŽ]ã‘_ã’cáZàˆS݈NҀ@ς1ц.ԉ3Ռ.֎0َ1֊*ِ0ؑ0׍(֌%؎$֍ڒ$ۑ!ÖeßVâXäZå[ç[ÞMÙJØFØGÕMÕQËBÄ7É;Ê7Í=Ï?ÚGáVäjánØXÏNÍJÈEÒRÕUÖ{ å¹VãÀ`åÄpçÊtçÈwèËzçËéË|é̓çÉ}åÇväÅtãÅvâÆoäÆtãÅsáÅnçÆqéÈsáÂeÞ¾[Ý»UÙ±LÕ®IÓªEҟ8Ӎ'Ј$υ#̓ Ãu¼n¶h ²gµe²f«d¤_¤a +“Rv@vCR£`¨f²h¸mºlÈ{±`©V©YÅ~â²Cä½RçÅ\Ò¨@­q°q²q®lªl«m¨j©jªj©i§g¥h¤g¨j¨k¨k©k¤g£f©l¥k©k¥e¥e¡cžaŸc›^š`™]•[™_›b •\’Y “Y•Z“Y†O‰`*èرîéÑîëÔîëÖëîæêîçêîééîêçíëèîëçííçíìçíìæíìæìëåìíäëíçíêêîèìíáííáìîßëîàëîßëíÞëîßêîàèîâæîãåîããîèãîêãîëãíìãíîãíîãíîãîîãîíãîìãîéãíäãêÝãêÜèéÙëëØìé×íæÓîçÑîäÏîâÍìßÊìßÊëÞÆìàÈíàËíãÍîãÏïáÈ곗ìxhëneça^ßTFÂH2¹H5³T3²M,°H*ѐWÙª_³h'²Q»\0™C c!´u8q¤U}!‚‚‹”(Š„{“>!ⴄخwÚ®yÛ±}Þµ‚ḋ住็ỏ従çßèÅ£ëÉ£éÆ£êǤߨ‡Ü‰aâ‰e݆aá‹_ãeç—læ˜eލYߐ\܊UÏ}8Ђ+Ԋ2׌4֌1Ӌ,Ӌ,ؐ,Ս*؏*ڒ*ۓ*ؐ&ڑ#ؒ"؉Ô]ÙRÔNä[æ^ßSÛNÖFÔEÓDÕIÉ>Â6Å9Ç9Æ;È<Î?ØIß`âeÚWÔQÎHÍIÍJÖZá™0äºVçÅiæÆpèÇséÈtèÉvéÉwåÇsåÈtäÆtæÈtãÅtáÂqàÃoãÃnâÂkâÁkâÃläÃiß½]áÄaÛ´PׯJÕ¯JѨDΝ4ϊ"ъ$Ї"ˁ!Ávºq ·l µj¹j¹p³m ±j ¯k ±k ¯i ®j ²n¸w¾{Éx ӎԕ%ŇÀƒ¿{Âݬ;ã¼LèÆ[ìÎkíØuŚ2¬k®mªl¬mªi¦f¤d¦f¨g¤c¢b¢a¥g¢g¡e¡a‡%±m £_—`–]–\›^˜Z‘XT˜\“Y“YŽT‘W‘U“[‘W ’X‘W ‘YŒU‘t;ïéÄîçÌîêÓîêÓéîåèîæêîçéîçèíëèíêèíëèíêæíìçìëæììæììåììäëíçíëêîçìîãíîÜìíÞëîßëíßëîÞëîÞéîàçîáåîâåîããîããîèãíëãîíãîîãîîãîíãîíãíìãîíãíéãìããëÝæëÙêêÕëéÖîéÕîäÐîäÏíàËíáÊíàÊìÝÅíÞÂíݾîÛ¿çµ æˆrî€jëycèlXØXLÄL;±G(­A ЌUТdÕ§dЧ_Ö«^Ñ£W·s1‹.r€>“V‰@Ó¡bÀ’MpŒ ¨A˜7’ ŒŒŽԋdÜ®zÙªwÚ®{ܲെ⺌⽒æÁ“ä™å˜ë˦ì̪ì˪îήéƣՐu݄d܂^߆cãŽdè—pè—sã”i؅SބRåŽb܎VÈw0҄3ԋ:Ԋ2ӊ+؏1ݕ7ؐ0׎-ޘ5ܗ.ܔ)ؓ ܔ$ږ"Ùv ÔRÚOßTè^ç[ÝQ×GÕFÓGÐIÇB¼1¾5Â;Ã8Ä8Ç;Ë?ÓIÚVÚWÚWÐLËFÌEËWé°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Ϙ0Ҋ#ψ̄͂¾xÁy¾t½t Àv¿uÂx»t·sºt»vÀzŁǀЈښ*äµMá¸Ná·FÖ¨6ܪ5߬<à·Kå¾RêÈ^ëÌlêÑtåËj«y¥g£e¡a£c¢b¥c¢daža¡f·€"¿0ǟ:Õ1žd e Þ£?χ­k ”[•\™_–\‘[‘X”[•\W‰QUWŒW Y +‹SŠS‹S„N ’t:éÛ¶êÖ³ìãÆíéÒéîåçîéêîçéíèéîèèíêèíêçíëæìëæìëæíëåìíæìíæììåììçíìéîéëîãíîàííÛëîÞëíÞëîàêîßêîßçîâæîâæîããîäãîæãíåãíæãíåãìâãìåãíäãíêãîçãìäãìßãêÚæêÙëèÕíéÔîæÑîåÎîàÉîÙÈîѼí̬íÇ£íÀä›zßuaÊQ6ÀH/ÀG,¸>)ÅM8ÂL.·F#²CޙdΝWÊ ZÎ¥\Ш]ѦYΠP̚L•Ux4¿‚A†L¨yCêÊwÈEÓ^0ÂMºX*¢E“& +œ% ›1è³|â·}Ú­sàµ~Û±|å”åěäÁ—ã”æÆ éÉ¥ëÌ©íϬîÒ³êÞÁîΫ麝ډoÕ|Y߆f܆dä’kç–sÏsOÊb<Ñg5á„Zà’cՃU҃DבHזL֕FדCە;ܖ9ۓ7ܔ4ߘ0ޖ'ãš3à™+ߗ*ޗ ÌaÙOÛRâZå\ÝRÙGÕFÓGÎGÆ@¾9¯+À=¿7Á7À2È:Ë>ÔIØUÖQÓOÐJËFÖvå¶MèÂ]èÅiæÅnèÆqéÈsèÇvåÅuäÅwãÂnß½iÞ¼fݾfá¿iß¾gà¾dà¾bÙº[ÚµRÙ²MÖ°HÖ­KÓ©EÓ©EÕ¬GФCƆÉɁÆ}Ãz¿wÁxÂ|Àx¾v¾v¾w¶r ·p¸uºuËxхב#ԓ!è»Mß´Mà¶JݳCã¼OÝ´Cã»Oã½TèÁVéÄXæÃ^çÏrêÏoÓ¯Kža£d¨m ¤i ´~Î)ʝ9ÞµSãÀbðÓxíÎqìÍqíÎrëÊiîÍp§{Ö®Oß©@ڗ0¤jU‘YWUTUV‹VˆTˆR‹U‰S‰R‰RŠS…M ƒM +”o7µ‘fƙtåѳîêÖèîãéîæéîçéîèèíéèîéèíéçíêçíêèíêåììæììæíìæííæììæììæììèíìêîäëîßìíÛìíÝìíÝëîÞêíßéîßèíàèíßåîßäìßäíÞäëÜãëÛãêØãëßãìàãìâãìâãíåãíßãíÝåéØéèÔíèÓîåÐîàÇíͱîÆ­îˬéÛÑ{`ºC.¸;"¾9¾< Å?$º: º9 º7³5·;ÒlHÔyOÁe8¥d&ŽK!¦o2˟SǜN̟G¸†5ǐ?¤H}8–?Ù©V»WÈW¼Z$¯U"®M½f;ɋYâµzÜ­tÚ«r㷂幆çŗæŘæ—èśéÉ êÊ¢éȦíÍ­ì˨îÍ©ìÍ©èĠ秋â’vã‹oãlç–rì¢~ÉkJÅ[;ÎrIä‘nâ–q܉dá“iæ¤vç¯{ìÀ‡ë¿|ç¯cܙBݕ7ޖ9ߗ4ޗ/âœ3ߚ/ݗ,ܗ$â“ÍSØKÞPáVßVÜPÖHÓFÑFÉD½8³/¯.¿>½8À3À3Ã7Å<ÍMØYÜXÐKËGå—1æµHçÁ`èÃiçÄiçÄlæÃkäÃlåÃoãÁlÞ»fÝ»eà½gá¿jß¼bÛº^ܹ\Û¶YسVØ°L×­HÓ¬FѧIÐ¥CÒ¥@ѪE˝>½}!Áu¾w¾v½t¼s¶n´n·q ´k³k¯i¯h¬e­aÁtޕ-؜6Þ©?ß²Kà¶Gà·KáºQãºLâ»JÞ¶Lå¾Uâ¼UèÃ\æÁWëËeçÍoêÏpçËlϞ7Ý =Þ§<é¸Lå»Oç¿WèÅ_ëËlìÐuìÏtëÌsëÊpêÊsëÉmçÅaìÒxͧOéÈjß³R«sŒSVU‹UŒVXWŒVˆSW‹UƒN„O‰UˆSŠVŠUa'ªŠXÖÁœëáÉíèÒéîåéîåèîèèíééîèèíéèîéèíéçíêæìëæììåììæíìåììåìíåìíæììäëíåììéîæëîáìíÞëîàêîÞëíàëîßëíÞêìÜêìÚéêÛéêÙéèØçêÙåëÚäêÛãêÜãëÜãìÞãìÝãíÞãìÜãëÛèèÔìçÓîåÑíÑ´í¿—ìÁ›ê›鷔½[Cµ7 º;%·4!³0­2²6¶8µ2³3³4°1¯/¬0š6v3id p=µ‡EΠSÏ¥OͤNÞ®^ܯ]»ˆ4șF”T °c&›>ºi=è¶|åÁˆà»~á´zݲw⺁㼆åÑâÀäÁéƚêřêØ´éÆ¢ëÉ©íË«íЭîǧ䪊݋lۂg݀dãˆjâlâkދbáh݊fތfáŽk܋_ք]؂YÒzRËuEێRޘTߛVޛDޘ8à™7äŸ6âž5äŸ5áœ2ޘ&ä¡+ׅÓNßLÞQÞVÚOÙJÔGÑEÉA¿;µ6©*°3¾=ÆFÅDÔTÛ\ÝfänßiÖZÈHæ£1å³Iå»YåÂgåÂjäÁläÃmäÃgá¿dá¿iܺdØ·^ÚµZÛ¸_Û·YØ´U×´XÙ´YÛ³R׬IÐ¥AЦBÍ¡?Í¡<Ò¤@ЪLÙ?³w¹rºu °o +·q²m²m¬k¬hªcªe©g«g°fЂݗ.ç²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 ŽXŒT‰T‰V‰UWŽUŒUŽX Y ‰S‰S‹UŠUŠU‰T…Rd+«“dȼžìäËíçÐéîåéîæèîçéîèèîééíéèíëéîéçíìçíêæììçíìæííæííåìíçíìåìíåìíäëíæííçîêêîäêîãìíßëíÞëìÜëìÙìé×íçÖìéÖìèÔëéÖéé×èêØçêÙåìÚäìÛäìÚãíÞãîßãíÞäìØåê×èéÕíܽ췙ꥃ栃ֈm³@'¸7¹8µ9½S0Ó`֐mã{Ð{\¦,ª*©)¯2±5”7 u;m5ŒY`3pFb2¨y*½:À™AÚAȗEžiŸfŸiz@ fh#ŸY!ÞªsäŠæōà´xã¹{æÀ„忇߸~à¹~⻃ἉêȚéË¡êɤëÊ©éÌ«ìƧ؍t܁jÚzbÞycâƒhæ‹nâ‹k܃e܃a܆cފf݈hۇg܋cԃ_Ñ}XÐ|RÎoHÉi@؇TÑ}DݔLà Qä£Gãž6ã¢9å£>âž6á)׊ä‹Ò\ØOÙNÜRÝSÙLÓHÏDÍIÍLÊQÒ\ÖdÚhÜjãpÞhÝ`Þ`Ü^Ýbáeßoè©0è¹Ná¹Vâ½Zà»_ß½aß»`Þ¹^Û´YÙ´[ص\Ø´ZÕ¯PׯVÓ®UײV×±TÖ±TÒªHÒ¦DΟ:Р;ț5˝8Ï£DƝ;Á–;«n ±n +­l«n «j©i¦h£c£d¨g§c£d§eЅ"ޝ7à°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şC[ WŽVŠUŠVˆS‡R‰QˆQ‰R‰Q‹RŠS +‰Q‰Q ‡P +ƒN‡P‘f5±—r¼«‰êäÆíèÑèîæçîéçîééíèéíééîèèíéèíéçíëèíéçíëåìíçìëæììæìëåëíåëìäëíäëíåëìåììåíêçîçêíãìíÞììÙìëØíé×ìêØíêÖìçÖìê×ëêÚéìÚèìÜèíÝäîßäîâãîâãîããîâäêÔ籜à}斅랃äoÃ\Bµ7#¼2¸-»>#ÅjBâžnì̞轍㵊ӏl¿X7©2¦-¬4Š- j2j5k5Y,ŠdYn:¥x¡x¬)­‚)¸‹5Á“<·Š1±-h1™eY¨p8¸y>Ú¨jß²qß°váº}羆⻃ݺ|Ý´zÞ¹…Ý·„éȚìÍ©ìˬíÑ°ïճ䲐ێsØbÚy`Þ{cá‚eçoâŠl܃d݆g߇fމi܈kå—y܋lڈh؇eÏ}TÇe<ÀZ-És>Çs>Év:â£`ڑ;ߖ1ޗ1ە.ِ(׏ۆ áoãhÞ_Ü]ÚXß`ÞZâfâháiØdØcÚeÚgÙeÛfÝdßbÛ[ÙQÛR×SÞZÞ]Øhå–#ß 0á®FÝ°OÙ°SØ®PÙ°WÙ°VײYسZرVÖ¯TØ°XÔ¬RÔªOÕªNÒ§E΢@Ë ?˝:ʜ7Ƙ2Ï£CΪSÁœ@¹5¢i £d¤e¢c¦g ¢c¢cŸ`¢c b›^¡aφæ­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˜fŽWYŒSŠVŠTŠU‹SˆQ‹U U ‰S†P I‚M …UŽY%ˆ_+¨_¾­ßÖ¹ìæÎíçÒçíæèîèæîéèíééíçèíéèîéèíëçíëéîéèíêçíìæííæíìçíìåìíæííåììæììæíëæìëåíìçîéçîèéîåêîâêîßéîâéîàéîàéîßéíßéìÝêìÛèîÝçîàåîãäîãäîããðäæϼÙ{qÔe\Úc_Ü`_ßtdÄ[E»A1¶5 ²4·;À`?ٜhã­亏嵊幑ÊyVÁc:Ä`:¹P0‡) +r1f4e4[*[1uKÁšDÆ£I»—<½žC›u x#°ˆ/¶Š7É£JşHª.“hƒS {Ci)ŋQÚ¢hØ¡iÚ¡lϑZӝpÞ¯{⼈ܷá¿ŠèË¡ìͦíϯíаä£翚湛ৃфhÏy[Ýa߃j؀c܀a܂cڃdވg܊jásڋh؊dρYÌvRÍnM»V5»a9ÈyIÃn1ٔW͂9Ղ%Ӆ(Ӆ"уÏ}Ò×wÜgãbábábà_Þ[ÛWãbâfÛcÞcÝaÚ_ÝdÚaØ]Ú_ØZÖOÓFÓJÔIØMÜXÝaÚiᏠ֟3ئCÖªLÖªOجOÕ©RÖ¬PÓ¨LÔ©RÏ£IÒ§JϤIÏ¢HФLƙ8ɛ6Ɣ0Ɣ/˝8ϨOϬUÀ—?¼‹:¡e ¤d ¢c¥e +¡b¡b£d¢c a b¢b˃á¦:íÈcëÇdêËkëÈkéÈhèÇlëÈgèÃcæ½Yß´LÜ®=Ô¢1͛%Ñ¡,Ý°?߸HæÁ[äÁZåÃ\åÅbÛ¹[äÄ`Ý»\Ï¢>ܱLá½XêÇkìÍoêÏrëÎvèÎvÞº^Ô§?ק@Ñ¡8Ñ ;Í¢;ݱMâ¼_ìÒ~åÍ‹U‰Q‡PƒR‚V†S ŒZd•p0œv9¨ƒM²•bºœiȬÖŜÞÒ´âؾçßÆíçÔîëÖíè×îê×èîäéîæéîåéíééîèéîèèíêéîéèîìèíëèîëçíìèíëçíìæííæììæìíæíëèíêæíêæîêæíêæíéèîçèîæéîåèîçèîççîèæîéäíêåîìæîææîãåîäçîâæîâæîâæïâáîÒkbÜcaÙ^WÔONÌC;Â@-µ>%µ4"¯4³E*´L$½c9֋_٘oٟuᴊܯ‚Ì{ZÉuPÈiFÆcBÂfA›K k.[,T.V/a9yU †g—v}"¥Š0«‰,œm¦y©|µ1³‰1¼9¯|5Ÿl$ΚbВ_Ҍ_ЄSÒNÊzIÆvHÁlJ̈́]å²~߸ƒä—çŞêʧêʬèãçğìÆ¡çÛ軓榌ݒqۇiۀcØx\×~\ڄ`ތfá’rߎrۈkۋkæ vԂ^ÈhC¿[7­M+Ë{HÄp6ÊyDՋKÈv"ÈyË|ÉyÌzÊ{΍/áºbÛbßaÞZÜWÚTÝTÜTÛ]Þ`Ý^Þ_Ü_Ú`Ü^Ú\ÙZÜ\ÕSÐDÏDÐDÑEÏGÝYÛZØcڀי*ї0Ñ ;ΠDТDÏ¢?Í¢AÑ£NÒ£FѤG̞@˞>ɚ>ŕ5’.ď-ē3Ë ĮPЭY¾—>¹‡0¤e¤c ¢c ¥f £d +¥f ¢b¡a¢b¦dÉ~æª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͜4˜2Ο7ÕªIׯLÚ°KÙ­JàºYɤN³’G¼œUÅ©nɳ}Õōá˛áÏ çÛ¬êáºìäÃíçËïëÐïíÖðïØîëÔîìÖîìÖîêÖîëÙîë×îéÓîëÖèîåéîåèîçêîæéîèèíééîééíèéíèéîéèîêèíêèîëèíééíèèíêèíêèíééíéèîèèîçèîçèîæéîäéîåèîæèîææîéæîèåíèäíêãíëäìëåíéåíèçîåæîäæîâçÜËÏrkÙa`ÕVLÎMAÄ?5ÇL6º@)¼>&µ1®3»W1¶W.¼V7ÁdBǂVÙ¤r庋ΑaÏ}TÍvVÊjOÃeCÄf@Âa@¼hG‰C])S0[=mI¬‹;–ru}[‹k—n”i n±„,º‹:¦u)̟aÒ¬nÕ§mԘhԑa҉UÑMÎyKÆm?ÄlG¿hCÁnHٓk踎㼐äÀœæžéÄ¢èĝèÀ™æÀœÝ²ˆÃ}YԂ]àl݈gڃgã”uۊiڇcފoۇjنgهhՄbىcÉmI»Y7ªJ(¹d4¾j2»e1Ås5½m%¿q%Âu)Àt%½r¾p×Ƌá½{ºYÓaÛ[ÙVÛTÚMØK×IÙTÜ`ß_ØZÙ`×ZÚ^ÖVÖVÐRÏNÎDÏBËAÏAÒDÙQÖVÑRÎe ҇Γ7ɗ9Ǘ7Ǘ;ʛ?ɗ>ʛAŖ<Ș=‘5ē:Ŕ7¿2½Œ1À’:É¥TÌ­Tѳ_»˜A¸Š7¤e ¤e¨i¥f ¥f ¥f ¥f¥g ¥fÁsáš4éºUÓ¤?æ¿^çÄkåÀ_å¾ZêÄbéÇhêÊnçÆgÒ¨DÕ¥;Ø«<׬:Ú«=Ó¢.ק6Úª:Ø«AÞ¶OäÅ^ëÍnéËlêÌqí؀äÈkÒ©Fß¹Vß¿_Ü·TݵSÒ«BÕ­GܵQã¾iéÉmß·OÔ©E×­JÖ¬Hà·QÙµUïéµðëÄíìÂëÞ¦ïì¸ìâ«îìÇîêÐîéÑîêÓîêÓîéÓîêÓîëÓîêÓîêÔîëÔíéÔíèÓíçÒíçÒìæÑìåÐéîâèîåéîçêîæèíééîèéíèéíèéîçéîèéíèèíèéîèéíéèîèéíèéîçéîçéîåéîçéîäéîåêîäéîåéîæéîåçîèçíéçîèçíçæîæåíçåîçåíéåíèæîçæîåèðáÛ ßldÕWMÖRHØ`YÌYJÅH2½>(¶6²1²2·D'¶Y.¹b?֔m䲄㹎渏ÉxOÏyUÏ]ÈsTÊoQÃd:ÆdBÃgEÅfJ²Z7€ER*«…CÖ¯]µ5«!}Z |VoI„TˆUÁ—Mؽ‚çʔë̘åđҢmԗfא_׎[ԈUсRÇvFÆrIÀlFº]7´R0ÉuQ䯃ܲ„ํçÁ™çžëŤ幘井єoÎvZ×w_Õy]Õ{_Ôz]Õb؃f؂iكgՁeوj҃fՅjÊuV¶V9«D(¯Q.Àd8¾d-¿f0¶d#´e°e³d²e¯féõÙåÝ©»ŒP¤kQDŽ1Èo¾X ¹C¸;º>¾=ÂFÑNÖVÔTÔNÛVÖT×TÚ[ÓRÑKÐDÌBÍDÎAÓI×SÍPËJÂWÅ~Nj7ō8Ő8ő;Đ6Ƒ8Ï6¿‹3Ê2¾ˆ*ºƒ)¶+¸ˆ9áÉŧYÖ¸iÕ¼oδj»•J b¡c ¦h¥fªk¨h¦i¥g­j ß¡?ì½]Ú®NéÇfçÅkèÇqÕ­NæÃbàºYåÁbèÄbäÀ`à¹Và¸SÛ±CÕª9Ø©8Ú«9Ú¬@Λ(¹~ ר?èÊgåÆbçÍrëÒ|êÒ|ìÔyʧEرHѦ=˚4Ô§EÓ¨DÕ®GÞ¼]æÅiã¾_ɘ/Ñ¡:Ô«FÞ¸[Û³MçהîíÑæà³Ú½jæÃfäÄrâº_äͅïëÌîéÔíéÔîéÕîêÕîéÖíéÒíèÒîéÓíèÑíçÒìåÐìäÏìåÐìäÏìäÏéîâéîãéîåéîäëîåéîçêîçéîèéîçéîééîçêîçéîçêîçêîåêîæëîâêîæëîãêîäëîãêîäéîäêîäêîäéîåèîçèîæèîççîçæîçæîåæîæåíæçîææíåæîäëèØËn_×]YÔ^PØe[Ç[FÁM5Ã>%¼8#´4"°/¬0°>&»fB㩁䲌繎êÁœÌ‹mËsWÍuZەxىrՁcÑyVÉpGÅiFÈiIÍtOÌxLÁz@»„;­{)º’<ʟH´‹.ŞDǞK²ƒ-®~,Ù±râŕìÝ°è˚ݼ‰á¸†Ñ—lԎ]֌\׎^ԅ[҅W΃VÆwV´X9µS4·T8ÃjQ㭅޴‡å¿˜çÁ™à¶ŽÞ²‰Ü®…Ü®ˆÕšyÄrRÐtXÓy]Ôy]Ñz]Ô}aÒ{bÔ}bÓ|cԀgՅoՇqՇh±R7©?*¬N.¯]4¾d7½`3½c2·c*®c­b­dĉHéîÆéëÊéíÏçðâèïàêõáêùàëöÛêìÊâàÀÞÙµÜѧÛɜֿƒÕ¶tÓªcϗXВOыBÒ{,ËiÃWÁPÁ@ÁAÂCÅAÌMÎUÇKÀ>¶Hºiº~&»&¸‚-·,¼†0´}$³z#´z ±x«q”Sâӕèڜ̭gؾtßɋéØ¡º”P¥g¥e§i§g¤d ¢h¥j̔7Տ*ê½_êÈqçÄeèÃaèÇmèÇqæÂfåÂdݹWæÁeçÂdìÊjâºTÙ¯GØ®=ݱ@Λ&Ö§5Ü®>Ȕ#Ċ¼‚ßµIãÃ_åÇgäÈgìÒwìÔ~Ö³W¼‹ Ő)Ɣ1Ò£@Ö«MØ°NÖ°LÔ¬NÕ­JŘ0Õ¬BãÁXܹTÜÆxäݪ×ň׵iâ»_éÃiéÇoæ¾^ä¹YæÉ|îéÎîéÒíçÒîéÔíçÑíçÒíçÒëäÏíæÒìæÑëäÏêãÎéáÌëãÎëâÍèîâèîäéîåéîåëîäêîåêîæêîæêîçéîçêîçêîæëîåêîæëîäëîäëîäìîâëîäìîâêîäêîäéîäéîæèîåèîæèîçèîèèîæéîäéîãèîæèîåéîãçîåèîãéîäܹ§ÖgYÚleÉdM¹R5ÂH0½D.»;!¶5!¯/­.®4¬<"ÊyUݦ{䰉䰄蹔ˈdÉjMÊkQÕdՀfÐ~^؆^ÎvLÍqSËrMÍvPÍqKÑ{Jºd*¤S«aµ‚2È¢I³‰3¦{%“f«x/ǑXæɚëá¼ë̚éɚêǛԛn҉^Ӊ[҈ZՊ`цYЃXÊyV¹c<¯D%»R:ºYC°bE絆۰†×§„Ü­„ݯ‰Ý´à³’ẕ侗ÅwWÔy^Òx[ÍtYÎuZÑz[Ív\Ô|cՀfքjÐ}bÌw_¾bBŸ9 @"§V0ºh=»\5¶Y2¯Z%µl.ªbªa‚AêКæЛåΝáʔã̗á̘åÒ¢äÏ£èÖªêØ©êÝ®ìß²ëâ¹ëå¾ìå¼ëå¿éëÒéíÔçïØæñÔæõàçôÚèïÐãáÂßÒ¨âΡյÍ¢gȊHÅv-ºc °N£Oªa¬h¥h¬r!°s#®q±t ªq"¡e‰@i& òôÃÖ€ÞĂÛÁæӝîݬ®‹L¦q/«q,°|6¹ˆC¾“JÁ WÞ±Yϒ,æ®JìÆeêÉnâº^æ½\çÄdçÆjéÈqéÉnçÆpåÁbçÇjêÅdä¿Xß·Pß´HÚ¯?Ù¬<Ú¬5Ù©1ܬ9¿‹˔"Ù«8Þ´JÒ¦9â¼Rà¾YëÎtÛ¼]Ê 6Ț1Ô¨BתEÛµSÚ²N×­HØ°QÞ·TΣ<àºTâÁbéݐëæ°ÙÀwȝ?Ñ«SæÄjâ¾dçÆkèÅiëÈnëÅiíâµíèÑìæÐíæÑíçÓíèÓíçÒíæÑìäÏìçÒëäÏìåÏìäÏéâÍêâÍéîáêîàêîãëîáìîâëîäêîäêîæëîçëîçêîçêîèëîçëîæìîâìîâëîãìîáìîâëîãìîãëîäìîäêîåèîèéîåèîçéîæèîçêîäéîåèîæéîäèîæèîãèîãèóíӖƒÚsd»Q?·?(¼>'¼<(¹:&³6"­.®-¯.§+°K/ڜwá«~௅ޫ~⫆ÄxZËnSÎu\ՄeÒ~`քcԂ\Ö]ÃfKÊuRÌvPÊkAËj@Ìo@®T­N ™Q¤r*—o‘fŠVÀ–XÁ‰KñÕ¢ìØ©ëʝæēì̟Ԛiш\ӈ^҈[Պ_πSÂmCÃlKÁmF¢6¾V>ÃmL«^AªQ4á£~Ø¥}Õ¢xÚ©ƒÝ²ŽÞ¶•â¼šàº—×£ƒÇs]Ït[ÇjOÈnZËpSÎw]ÉhRËnZËqdÈjQÈoTÄmS’2˜3˜B(ºiD³Q/­S2«S$«Z(¯d%¬b!³o.æďØÀˆ×½…×¼„Ö»†×¼‡Õ¹†Ù¾Ø¾ŒÕ»ˆÜÚÀÛÁ•ßǙÜĘßɝâË¡âʚéÔ¤éÓ èÖ¦ìÞ±êß³êá±ìá¶ëä»ìåÀêêÂëîÈêòÎêôÖåðÚäéáãèØäæÏãݳÔ̘Ӿ‰Ê®w¿œ]¯O‘^)ŽV:ÓĚîç²ÏµmâȃÛÁƒçÕ¢åשáÔ¤æ×­ë߶ëåÀíêÏíîÑîëÃșEà£@ìÃdçÁaêÇfèÇgá¼`éÇlèÅièÆnéÈnçÆlèÄláÀfèÄaçÁ]â»XÞ´GܳBÞ¶FÜ°=Ù­7Ν'Ú¦/Ó¥3Ò¦5Ô©;“&ǚ*çÆaëÌtàÂhЭHÓ«FׯHÔ¦EÔ«HÕ¬HÓ©FÛ±MÓ¨EÝ»^äÆeǝ8ė<šCŚ>Ò¨MáÀfçÅlåÃmèÆlçÆgèÅcêÅaäÄrïéÎíéÔîéÔíèÔîèÓîéÕîéÔìæÒíèÓíæÑíèÓìåÐìäÏëäÏëîàêîàëîâëîâìîáìîãëîãìîâëîäëîãìîäìîâìîáíîàìîãìîâíîáìîâìîãëîãìîãëîäëîãëîäéîåéîçêîæéîæéîæéîåéîäêîâéîâéîãéîâéîáëëÜՊ€Ðo[±A'¸;+´:#¸;*³4%±.²1 ¬(±0"¡5%鰐٣|اyìˤêě㮊ÅxZÄeJÈmQۇkÐx[Óy\Òx^ÏvUÊmIÏsOÌmDËj@ÍmDÀa4¼c:®V(§PžK šM ŸUœPšG ݪtìПëÑ£ëÌ çǗçÀ•ÐŽf҆^҅\҅Y֋]ˀXµd>ÅuMÆnH ;¬I-·\D½fMÄ^MÂYGܑo՝sÚ«†Ý±ß´•ß·•Ýº—Þº™Ô¢ƒÃwYÀhPÃkUÄkPÁeQÀfN¼`JÃkV½bFÁfGÂgN™9$‘,–8!®U;¬L1­K% E¨R)¯c%¯g(«e(Ý‹ؽ…Ó¸ƒÔ¹‡Ô¸…Ô¸†Ð´‚Ó¶…ÖºˆÕ¹ˆÖ»‰×½ŽÚÁ”ÛÁ‘ÜÔ׾ÙÀ×¼‹ÚÁ‹×¿†ÜĐÜ’ÜďÜǐÞɖá˛â͙ãΜãРåÒ¥ëØ«ìÜ®ëã¹ìá¾ëæÅéá¾ëäÁêçÍéëÍêîÏíòÏï÷ÔîõÎíëÀåØ¡Ê°oÝljÛ‡æÕ¤åÖ¨êð×éîßèîáéîáéîÝêðÜ̯mڝ<êÀbêÇiìËoëÍvíÍxëÊsêÉpëÊnéÈpéÇqæÃlçÈlçÆmçÂ_êÆ`ä¾\ß·NáºQØ®AÕ¨7Ò¡/º„ Ô¡0Ò§9Ù²Eà¼VÁ•&³†Ó´TáÇlåÈmܸaƜ?Ð¥CЦHÔ¬MΤF×­JÏ©GáÐ|Ó´^¾‘+Ɨ1ț4Ó¬KÕ­Oض^ݺ[ܶTéÈoéÈuçÄjåÄgåÃfâ¼eçܳîêØîéÕíêÖíêÕîèÓîêÕíèÓíçÒíçÑîèÔìæÑíçÑëåÏêíßëîâëîáëîàìîáìîâìîáëîâëîâìîáíîßíîàíîàìîàìîáìîâìîâëîãìîâëîãëîäëîãëîäêîæëîäêîåêîæëîãëîãêîãéîãèîãêîâêîâéîãéïß⹡ڊpÀZJ®:#°6'±8#·;-´5+°,¯)². ¦)ˀi廓ߩ…՝y߯Šß¶ˆå¼•é³‰Ï„ZÈqTËqVÏvZÐuXÓyZÎqMÍqKÏuOÍpGÉh=Êk@ÎmEÆd7Äm5»W+¶O·T"³O"­I©G罌îÛ­íÓ¢å•߸ŠÛ­|̃WՄVЀTؙpß®‰à¥€Ú¡x͋bÃjM£5¦?"±P4Ã[=É`FÍ\EÄT?ڑjÚ©€Ü¬ŠÛ²Žà¶“ܵ’ܺ–Ú³Ìs·dS·`Iº^F¿bLÁiUµZJ´WF¾_I·]D¹ZD¦D2&“0˜=¡E&¢A<§R,¯c)®c)ªb+Ùµ‚×¹ÔµƒÐµƒÕµ„Ѷ„Ó¸†ÒµƒÑµ‚Ò¶„Ò·ƒÖ¿×¾‘Ø¿ŒÖ¼‹Õ»‰Õ»ŠÖ¼ŒÖ¾‡Ö¾†×¾ˆÕ½†×¾ˆÕ¼ƒÓ»…Ô¿‹×ŒÖÁ‹ÝǒÝȕßǖâ̙áʚãʙàʛãΛâ͛äΝçÒ¢éÕ¥éÕ¦ëÜ®ëÚ¨ê֣˯qÓ½yÜȍßȒãÓ¢çÙ«èïÛéîâéíáéîáéîÜÖÏ£ÁŠ/ì¼\íÐyîÒ}îÐ{íÐ{íÐ}íÏ{èÇlܸ^éÇqèÆmæÄlÝ»WäÂ^â¼WëÉfå¿VÚ°?à·HݶCÛ±?Ú¬;½ƒ +Ν*à·Kâ½TåÁXÞ·Gͧ;äÃ]àÅcèÐvéÌrƟ=º‹"Í¥@ϦDÓ¨IÕ²Nîæ¡éޙś6Ƙ/Ì 8ݶLâÁaäÃiصXæÅhèÉièÆkèÈoäÁeåÂgçÄiæÁfãÅzîëÓîêÖîéÕîêÖîéÕîêÖîéÔíèÔíéÕîéÖíèÔìæÔìåÓëîÞìíÝìíßííßíîßìîàíîàííÞìîáíîàííßíîâìîáìîáëîâìîáëîâëîãëîãëîãëîäìîãëîäëîäëîäëîäëîäëîãëîãëîåëîáëîáêîâëîáìïßâγڢ‚Óˆi²N6­8#¬2"®4 °4$¬2 ¬/­0²4"¥>,ïÁšâ²‚ݨƒÝ¨…ìß潑աtÚ¤vܦvЎkÇjPÑxZÐvVÍpNÍpRËpSÍtTÐxNÆh>Èb;ÀX3¾Y(¿`+¼Z+¶L¸Q'´O³K¨Jð˝íàµèȜ⺑ޯˆØ›pˈZшUӏi㼒٩ƒÑ‹eՖiØ¢uЋjœ;¯F&ÎmGÇcAÁT:¼D+²=$«<&âžÛ¯ŒÚ°ŽÛ±ŒÙ²‘Ú¶“Õ©ˆÑ¡€¿f«T;°R:°N:µQ=µXE®P>®P<°U?³UC§I4w‡* ”7—C'‘5‡, };]-¬f/©g/Õ­|Ö¶„вβÒ³ƒÑ°€ÒµƒÐ´ƒÐ³ƒÎ¯~д€Ñµ„ϳƒÐµÒ¶…Òµ‚Ô¹†Ò¹„Óº„ÔºˆÓ»„Ô»„Ѹ‚з}×¾‰Ðº†Ó½ˆÔ¿‰ØŽÚÀŒÚÁÙÀÜ‘ÚŒÝđÞēÛŔÛŏÞɔÞɓäΛäϛäЛÖÁŠ¿˜WÛˆÚčßɓãÒ¡éßµéïÜêîáêíàéíãíòṌ9؜9ìÊjìËvíÏyìÎyíÏzíÐ}ëÊwèÆnçÅnéÈsçÅjäÁeäÃiß»^çÃcçÂcáºRÔ¥2Ý°<á¸IݳCݲ?ϟ)Ú­4ã¹Dà¶Eå¾Râ»PåÀVåÁ\çÈléËoæÊmßÁbØ2Ş5È <–1Ò®OÛÂoŕ4Í¡<دIâºSä½WåÁ\çÅgæÄgåÅmèÈmêÍvèÇpæÅjåÁhãÁ^æÁ\Þ³OïêÊîê×îêØíéÔîêÖíéÖíéÔìèÕíè×íèÕìçÓëåÒëãÏëîáííÞííÝííÞîíÞíîßíîßíîãìíâííãìîãìîäëîåìîáëîäìîâìîâëîäëîãêîåëîãëîãìîáêîäìîäëîãëîãìîâêîäëîâëîáìîàëîáìîÞíîÚæдٞ€Ös·bD¨6'°4%°7&¬0"«-®.!­0#ª.姉轒ߪܟvÛ£zß®‡ëÛ漑ڥ{ыfޞuԇbÏuXÐsPÐqPÔwZØ~bڃf×\Åg<Â_8Âa8½U#¸S#·P*¿S.¸L#´K!¶F»W3ðݶçÑ«ãÁ•Û±ƒÈdƈ\Еoɍ_ొä˜ӚsхaЈ]ޜtߝzÄoKÐjDÒiKÊfLÍeEÏdAÊU?µ>0¥>/ܝ‚Ù«‹Ý²ŽÕ«‹×¬‹Ù¬‹É™uŎq¬cP©O8£K0°U@§L7¯U@§M5­T>ªN:§L4q"„1Œ9$/XH‹Z1žf6¥m:˧u׸†Ó´ƒÏ±€Î¬|Юί~ѵƒÐ±€Ï°€Ï²‚αÍ­~ή€Ï²„Ï´~δ€Ò¹‡Ó¹‡Ò·…ϵ‚еƒÐµƒÓ¹‡Ð¼‡Ñ»ˆÔ½‰Õ½‹×½‹Õ»ŠÖ¼‹×½Œ×¾ŒÚÀ×½ŒÚÜÑÚÐØđÞǏßȑÝǐÙÎɯu¯Nß͙ØÁ‰àɓäÒ¢ìéËèîßëîáêîáíòåĵ€ÁŒ.ä¬HéÆgêÈnà»`ëÉqìÌzìÍyéÉuæÆrëÉsæÄlÝ·]æÁiæÅoâ¿aä¼XèÂcã½YÀŽݳFãºLâºJÞµCÚ­;à´CÝ°7à²Cã¼QáºPà»RèÃ\æÂ`èÈdêÌjêÎo¾—3»’)±…­¯€‘(Ñ 6جEá¹Oâ»Vá¹SäÀZçÃ`èÉméÉnäÃiéËséËuåÆpÞ¹bå¿bß¹Wä¼]êß°îéÙíêÕîêÖíèÖíé×íèÔìçÕíæÓîéÔìçÒìçÒìæÑìíÞìíÝíîßîìÜíîÞííßíîàííâëîæíîãìîãëîåìîäëîäìîãëîãëîåëîãëîåëîãìîâìîâìîãìîâìîáìîáëîâìîâëîãìîàìîàëîáíîàíîÜéàËÓ²Û¤…Ù“zچo¯<,¯7'¬7«-#®,%­-­+ÃcNìÁ ç±á˜xØ`Ô|[â¥켑Ⳇߥ€ÞyԕjՐeÎzZØ_Ö[ÓyW×}`ÑwYá“tÎtPËlFÖ|[¿Y2¨B 8¬7»O.±K#Â]2½a>ì˦ãÁ—Ù«}͙i¿zRÚ¢€ÒŸyÕ¦æʫدƒÁsGË{S¶`6®Q3¹X>ÊnLÌnDÆa7ÊcCր\ÔzTËgKÅ^DÃbKÁeMؘ{Ó¤€Ù«Ó¤…Ö§…Ê›z¿m¿„p L;¥L-©Q7 F8£H5¥I9¨N8 D1§K3rc aqŒB%µxT›_@ŒQ,‰U'‹Z0½šgÔ³„Ñ°Ì«{Ï®~έÏ®̯Ì®~ͯ€Î¯‚ΰ„Ì®ͯˬγ‚Ô»…ˬxË®}ȬzË°~Ï´‚Ѷ„Ï´Ó¸‡Ð¶„ϵ„Ó¹‡Ñ¶„Ö»ŠÒ·†Ó¹‡Ö¼Š×½‹Ø¿‹Ù¿ØÀ×¿ŽØ¿ŽØ¿ŠÜƑ×ÁÕ½†À¥k¬ˆJÜǐԿ‰ÙËàÏ ëæÈíëÔîïßìîßÖͧ±†.ҕ5åºYéÈiêËsìÍvëËxëÍ|ìÌ{ãÂnäÂkèÆpéÇrêÈsèÆpåÃièÆnåÀaèÄaèÃa¾Ù¯Jâ¸NÞµDá¹Hܯ=Þ²AØ©4Ú®9ݵBâ»Lâ½MÛ²FÞ¸QãÁZæÈiêÏrÚ¼_¨{±ƒ¸‰ʛ*Ó¤7ש;Ú©DÝ°Iß³LݳKÞ¸Qá»UéÅkëËpìÌréÌwâÁdß¾]æÃmäÁfçÄ`å½^ëܪíèÖíèÔíéÕíèÕìçÒíèÓíèÖìèÓîéÕíèÓëäÐìçÒìíÞìíÜííÞíîßíîàìîáìîäëîçìîäëîæëîçìîåìîäìîãìîâìîáìîâìîãëîãëîãìîáíîàíîàìîâìîãëîäëîãëîãìîßìîáëîâìîßëîÞêä΄iEݨˆã³Þ›€Ñn\¾O6©9"·M2¥/#©(ª+©)﹖罒ߗuÎlIÐbKÏdWÎkNՀZã™tޕrҋdь_̈́ZÎXÌuSÌuS×}`؁dـdւdփ`ÌrGÑyPÅh;½_6¬D!«<%©:!¶M+Ã_8Àc7쿒ׯΙlƆ`ɅbÚ©Ö©…áĢ߻”ˇ_¯O(¹`DºeB±R4¸P5ÏpG܇[Å`3ºS1¼Z@ÉjLËmLÍlI×kËq\·\B΍uÓ¤…Ñ¡Ïœ|ȕx½‰n²yc·rY›C.¡J7’7(˜70—70«]GÆzcÈr`¯`Jx2Tc +q +y (ˆ4%–R3£j<½’cÑ°Í«|ɨyʧx̪{Í«}ˬÊª|ɧxÉ©zŦ{Ç©}Ê«€È¬Ĩuº”^¢rÊ®}Ê®~˯γ‚̱Í²Ͳ‚ж‡Ò¸ˆÐ´…ϳƒÐ³„Ò¸‡Ñ·ƒÒ¸†Ö»ŠÕ¼ŠÙÀÕ¾ŒÕ½Œ×¾‹Óº~Ôº~ж}δ|¼¡h®‹IܾÍ°qÍ»…Ϲ´ q¼«Ï¿œáÔ¨ªˆ>¿‹,ߞ<â±RçÆjìÍ|éÉvëÌyæÃwìЀá¿mãÀléÈsèÈsêÊväÂnçÄnãÀhܳNâ¼YéÄbà¸Tå¾Vã¼TÞ·HݵCÝ°<Ú°<׬7Õ§0Ù¬:á¸Kݲ@˙,Ì¡9äÁ^ãÆdèËpçÍoÙ3¼Ž!ə'Ò¢3О,Ò¡0Ӟ-Û¬9Û«<Þ¯AÛ¯>áºPåÃdéÈméÊpèÇoݺYãÁbãÀbâ¿bäÃ`æ¿açԟíèÕíçÔìçÒíèÖìæÔíèÔíè×ëåÒìèÖëåÔíéÔìæÓíîàìîáìîãíîãííâìîäìîäëîåëîæëîåìîäìîäííáìîäìîáíîáìîâëîåíîâíîáíîàíîàíîàìîáìîáëîãêîäëîäëîàëîàëîáìîáíãənJǖw͇o寓ËydÍfWÎcO¬B*¦;!§1¤$¨)"Èm^븎ߕyËaJÄT:Î`EÎdLÌeGÏkNÆcCÕwUÑzQ̀V΁^Ð^ÌvVÑZԂ`Ò]ےr̀XËyVÐ\Í|[Ԁ`ÀiDáœtã }ÅwQ£;©:¦;ڞuÑ¡r˓gÅ~X֝~åğêË£àǤګŠ‘0ªC-µX?·d@²V5ÐmK܁Ráˆ[½P&¿M+¹N+ÒqT¼T3Ú~\Ów[ÂcE£4$¦B8¿g˜|ɗzős´~c¦oY«vW–K;1-Œ,!’2(¹eOÂo]²WD‘%ºcO€8&a +ry} } w ŽG/ª|UÌ¥‚ʦ~Ç¥xɧxÈ¥y̦wÌ£zÖo»ˆ\”kÅ v›r v¿¤x½£rÀ£o§wÇ«xƪy̱Ê®|˯yβË°ϲÍ²€Ïµ‚ϲ€Ï²ƒÐµ…еƒÓ¸‡Ò¶†Ô¾ŒÖºˆÙ¿ŠÖ½ŒÖ»‡Ðµ{Ç«mѸ}̱x»žb¯‹F½Ÿ]Æ©k¶Ÿi²˜h³žm°m±žj’n)±‚0ŏ-Ü¡>ä¼_éÊséÉuêÉrëËwëÍ~éËyâÃrêÊyéËvéÉsß»bÕ®Zá¾gëÊnÞ·QçÂ`èÄbéÆdèÂ^ã¼Sç¾Oà·EÞµ>ß´@Öª5˜²±…ʟ/˚*Õ¬IæÆgáÃ`äÄdÞ¼^É¢?¿͞/Р3ϟ0͚%ѝ#Õ¤0Ñ¡)Ô +Ú©6Þ³IáÀ]Þº]åÃfãÁdçÇmçÆjâÀbäÃhæÃcåÀ\áȇîéÖíçÒíéÔíèÓíéÔíèÔîê×íèÕîê×îêÖíèÖíè×ìîâëîæìîåëîçìîäìîåìîæìîæìîåíîäíîáíîàîîßîíàíîßíîáëîãëîåëîâìîáìîàííßìîáíîàìîãìîàìîãëîâëîàìîßìîáìåб‰dƐjڔ{¼gPבxÈo^ÏjZÃQD¸M=¦<&¨2"¢$"ﲘ⢃È`KÇVCÄTAÊ[DÍ_FÌgMÑlTÉ`GÎfO»R?ËlSӁbхaâ˜xàžv鮋墁魆媅⪇嵕ݟ{͆_ä¥zØ rښrߝw³X9Ÿ=ÁkDÚ¡|ΝpȐj¿nP孈çʨåɤӮ…c–.’ ®M4»dB¸_:Ô{TÇc8¹K ºI ºR0ÙXÃW;¬;)¸M4¢4¤<)œ-'Ÿ1&©UDƒrË¡Át´ƒd£oPfO‘J8‡2)—@9¶_O 5-†‰ŒŠ…Ár`] j svyu †4(¥sPˤßwÀ™rºˆ^£eA›K%“8•8”9”<–<œD%¦]@«rTÁ˜rĤw¿¢p¼ŸoħxĦvÅ«yÆ­|Ƭ{Ȭy˯~Ë°Ë°~ϱÎ±€Ð³ƒÐµ‚Ѷ„Ó¶†Õ¹‰Ô¹„Ô·ƒÔ¸…Ô¹„Õº…Ó·‚Ñ´€Ë®x·—X¯‡F¶—T¤i¡‰P«’Y¬—b«˜e¢ŠN¡q!´†&ѕ2å¬KèÄhéÉqæÆiçÈtêËzíЄìςèÈwëÊuíÎ{Ú²Tʛ:Ó©MëÊrëÌtéÈjæÃaèÅdéÅdèÅaâ»LÜ´=ß´>Ù¬5Т-Õ§4¨w +‹WšlׯCݵOãÀ^ãÃ_äÄcÛ»WЭEʝ3¾$͜0Ξ.Ο+Ϟ+Ó¢,Ö¨4Õ¤-Ô£,Ö¥6Ú­Bà¸Sß¼YèÅièÆkíÑwèÉmåÃgåÅiæÀ^åÀ[àÇ~îìÔîêØîêÖîë×îêÖîë×íéÔîêÕíê×îêÕîêØîêØëîãëîæëîæëîçìîåìîäìîåìîæìîåíîâíîÞîíÝííÝîîÞìîâìîâìîâëîåìîâìîâìîàìîáìîáíîáíîàìîàëîãìîßìîßíîßêà˙lNœ`D՘}Æxe¹]DÏ`ÎrVÑfVÄRFµG:¬?/£.±]H稍ÊhUÆTIÅO>ÇQEÈYFÌ\EËeOÍaNÇXEÅXC»L9½F2Øx^؈jÐ]âuÒ~YÊ`AÔw[׆fَmٝwڝzÚ zীߥ|Ü¢wÞ¥}Ý {⦀٠yß©†Óu·mR™)¦B1²^N¯YI¾x^­Y;£?#“(‘'¸T:ÆqLÂc:µK$¹I#¬E²L(×{T»M*·P:´B0¤:¬J5š4)™/!¯TGªf[ªgXĐr²†m¥sXŽQ8ŠB/¢XG2"w€{€„†„¬XK‚9)c nvws…*(]IÛw¸lž\>š:"“0“+¡5—,“& " ”'–(•*—2Ž9œc?²‹_¹žv¼¡w¹ oÀ¥vÅ©{©}Å©~É­€Ë­Ë°ƒË®ˬ~ϲ‚ΰÐ³‚ѲƒÔµÕ·‚Ñ´ƒÔ·†Ñ¶Óµ€ÔµƒÏ³~Ë®v²N°‰F¼™Z±“V™€Iª”\©•Xª”X ‡E™lʗ>Ȅ%å°LèÇlëÐ|íÒ~î׌íӈíՍéÌ~çÅséÇqæÄpÁ’3’5çÃléÊsëËqëÊoéÉlçÇfëÍmêÇaÔ©7ݳBܳBÕ¨1ש4ϟ-ŒX‰Y³Ù±IÚ·Oà½YâÀZáÂ]Ô³QϬL³„¼Ž$Ö+Р2Ϟ-Ñ£0ب:Ú«<ب8ب9Ø©:Ú¯?߶OåÂ\èÇgçÅgêÉnìÍtëÌsåÄjâ¼Vç¿[âňîìÙîëØîìÙîë×îëØîìÙîêÛîéÙîëÙîëÚîêÚîêØìîãëîåíîäìîäìîåìîäìîæëîçíîäíîâîîßîíÜîíÝíîÞíîàìîáìîãëîäëîäìîâíîáìîáëîâíîáìîâìîâëîâíîáìîáèäСyX£iE©mN⧗Ão^¾aEÑu_ÉhUÎgYÇWDÂRGµH2*¦4%塂ËkPÌXJÇQEÆN?ÄK:ÆQ=ÉZCÑbMË]GÌXAÇT>¼H0¼?-ÁK7ÊcFÏnRÇcGÄ]AÉ[CÈ\HËcL¿aDÊyTזr֛qੀà¨Þ©Þª‚Ú y۟zҗrΐqюl’!œ )–‡ ªJ7¼cJ¦B&®G2Ÿ8ԁT¶V)¶N'¶P)¯M%¸X,ÈnC¬L#¿ZAª?+§=$¥@-™3!—(žD5©aZw ¸xb°„i«{a‡O1™Q@})r tr t v€„ƒªVI’L?b f qqrƒ(&žVHµqX’2–0Œ%Š#Ÿ7#®Q5—,’! ‘"“(Ž" +‘&Ž$'Œ+7¢iD±’l¯“e¸šj´˜fº¡x»¢{À¦}Ū{Ũzƪ{ͬ}ˬ{ϯ|έ}Ô³‚Я{Ñ°|Ôµ‚Ó²Ï¯{Ò±~Ю{Ï®yÇ©q­‹L¨…>¡>š{:ƒf-’zJ¤ŒS¥H®“MÁ—@Н8²k +à¤AïÑwìÒî֋íՊíЄéÌëπٶcÛ¶]Ø°Z½3ܶ[éÊqìÍtíÍuçÆhëÈjéÈièÅaçÂ[Ú®=ä»Hà¶FÛ«7Ò¡+Ú®;¼ɜ-Õ¦7áºPâ½Vá¿ZáÀYݾUÏ­GÆ£CÄ >Å :—.Ǚ,Ó£4Ô¥5Þ±CÙª;Ú­;Ù©8Û¬;Ú«;á¶HàºQæÃ`æÅhèÈlëÌwèÇræÅlá»XãºYعzïîÚîìÙîìØîìÚîìÙîìÙîëÚîíÜîìÙîìÚîìÚîëÜìîâíîâíîåíîãíîãíîãìîäìîäìîäîíàîìÞîìÚîíÛíîàíîàëîäëîãìîâìîâìîáìîàìîâìîâìîâìîâëîãíîáíîÞéâ͏f=O&ƒR)“_<Ú¦ÏzdÌmVÙ~mÉeTÊdUÉ[NÉ[MÂVB•ÂcNքrÍYJÆP@ÃK7ÂH5ÄL8ÄP>ÉZAÉZBÉ[DÇW@ÀJ7ÀB.¶6 »>0¼H-ÆU:ÌZCÉZDÃR:ÄO=ÅR<ÌmPÄvP͈e֙yܤ|ݨ|଄߫„Þ¦~Ú¦}µsS†,ÆmV£* ¯;3­80­9/¢,“‰–+´J<ÃdPÄwTÒxN°O"®H½`7¼Y6ºX4ÊpK©H$ªA&¡9š0-“* ‰!Ž7%™S>mj¼Šv­cŽXB…<,m o i hm s y{}‘:6¥]Y] ` mom|#!„*'ƒŠŠ#¬L4ªQ?•(‹#& ’(Ž! # ŠŠ!Œ (Œ2K(²Ž`­–i¯•f´™k´œtºžv¾Ÿq¿¢mÂ¥vȨt̪wέ{Ï®~ѯ€Ð­zЮ{Ï­zͬxάyÏ®yЯ{̬xãkª‡Hª8—t)aG.;'A,D-œ},Ê¡<Õ¢1¶l +ߨGíÌqíсíՈîԉë΁í҆í҆ë́ìЀåÅ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»‘)ț2Ο0Õ¥9Ú¬<Ý°?Þ²@Ù¨5Ý®>Ü®=Û®=ܵKâ½XçÃbéÇièÉmäÄjß¼`à¼\àºSÕ¹pðîÚîíÚîìÚîíÛîìÙîíÛîíÜîíÚîíÚîìÙîìÚîìØíîáìîäìîäíîäíîâîîâìîäíîäìîäíîàîëÜîíÝíîàìîáìîâìîâìîâëîâìîâíîáìîáëîâìîâìîáëîãìîãëîãêæÐhP4f@pD yQ/¯ƒ^ԕqÒz[ÐqXÖ~iÇbRÃ^PÉ\MÉZK¹H5™ÖxhÎhWÂL@ÃK>½I6¾H5ÄQDÉ[HÎ]FË\IË^IÊWEÁJ9¿F.·6&³='ÉU=ÌX>ÇS:ÊS@ÃN7ÃN8¿L4Ê]H҄k؟z᳎ޮ‹à­ˆã¯å²Œä°Œæ´Ø ~†(®>1µ?/·90°90ª62«8/¡."™(“ ‰ ‡ݔr¿b7¶T)·T*¾_4¾b4ÓvP¸[1ªF!“2•0,$‚~€$‰<1`V v;2´‡rŸlN†P/Xg +e l f + m +sv81?7j\gmpts„ŠŒ%‹ Ž"š/!3’% ‘$!!" Š ‡ ‡ +(Œ.‘I)¯“hª’e¯•h±–o³–l»žq½ m¿žoÄ¥qÈ©yˬ|Я~Ï®~Ï­|άzÍ©zͪv˪vË«sΫvƨtÀžc¦„A«ƒ7”s+eI +8'9+Z@ Šh˦H׫BÞ¯@¿}å²SëÊqíрîԄíӉìЂíӇëІé͂éÎ~ΩUׯVåÅrëÌxëÍwéÈiêÉfçÃfçÂbåÀXäÀVáºJà¹Kã»Oà¸GÞµEÚ²BƓ(Η%ק8Ù®>Þ³KÞ·HáÀUÙ¸TÕµWÙ¼_ßÃbçÌqŞ4Ŗ/͟6΢4Ó§<Ö¨:ب;Û®=ܯ>Û±AÚ°AÛ³Dá¹Sä¿]åÀ_ëÇfߺXÞ¶UÝ·RߺP׺sððàîìÚîìÛííÝîíÛîíÝíîßîíÛîíÜîíÚîíÛîìÙìîàíîáìîäíîãíîãìîäíîäìîåìîãííàîíàíîãëîæëîæìîâëîãëîãìîãëîãìîáìîâìîâëîâëîâëîãëîåìèÖ^C U3R3 Q2 M2 ¨‚WٞxÊ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_՚tݬ‰ã¹šá°á­‡à­…᪃ߨ„Ô›wŽ/ºSB¸G:¸=0¯6,«72©9/¦5,¤6,¤4*”'ŽªH5¿`9¼\3²S-Ãd:Ái9´R*¶Q4¢H(3 ‡%yonrv+!R L <uF>¯€gšbDW_hdcjl m +x†0*›M:oT +Xnrpvw„Šš2"#"Ž" Œ$¸n)š2 !‹ ‰…†!†&‚%…+ “X4¬‘c«’g¬’f£†Vµ—n¸œl¹šoÀŸl̤wȤwÏ«{ΧvÏ©uÊ£oÆ¢sƤsÇ¥sɨpɦnÃ¥pº˜^¡|8Ÿz-Šh ?-0)„`­€$Ê ?ܳNÛ¯FÙ«:Б/ã¨BìÊlíÐ~î҃íӉí֊íӋì҅åÈ{ëÍ~Ò¬WÔªOçÇrèÈrëÍxåÄfÚ°KÒ¤Fà¹Tâ¸Jâ»Ná¼KâºKÚ°Cá¹KݳBÔ¦4³º‡ ש5Ò¤4Û±?Þ¶HáÀYغUÜÁaÛÃeàÄdëÐvÔ±P´†ȝ5Ѧ;Õ©Dש;Ú«<ج<Ö§8Ú¬=Ùª?ݲIá¹RåÀ_èÅeäÀ]â½W߸NÞµLá¸NÙÁƒîîÜîíÛîíÝîíÛîíÝîìÞîíÜîíÜîíÝîíÛîìÚîìÙìíáìîàëîåìîåìîäìîçìîåìîäíîäíîâìîåìîãìîæìîåìîâìîáëîâëîäìîäëîãìîãìîáìîãìîáìîáìè׋hLxO$uJk<j<_1¹ŽmÚ§~É~\ÀfI§>.®=+²C6ºI9ÀM7¨(³;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ࣁ߰Œßµ‹ã·‹â´‹ß«„â¯†í¿•é«{äŸx¬S=°B3ª1#§3-¦6,¥6-¥6,¤8-¥7* 4%§;)»W0¼Z9Äi?¿c;®T+®L/Ÿ?!”:#Š+turh a i]E 84-h:0iI”T1†U(”`0‘b3ŠT#u8ah r†5,šZNifP dg j l s x  ‚ ‡ ‹! +((“3éîî´|`7#•6!-ƒ‚„…) €%€+ œoJ¢d¢Š`§Šb©f·‘d¹‰f¸zO³i<«X+«Z2§T+¦T*±]1NJcǝqÀl»hÁj»™g±U z6žv)uV1~]™n·…!ß¹TÝ´L׫DÔ§=ȍ!ß¡;ç¿Zà·\ã¾jéÉyìπíԌíՊí҇ìфìπ߽cçÆpèÇqêËuʟB·ƒÍ¡8â¼Wã¼Sá¹OݶFÛ²Bá¸Oä½QÞ¯AÚ­;‘Ѥ4Ï£5Ϥ3Ú°?߶IæÄZåÈeåÉiÝ¿^àÄbëÑtìÒ{º‘*ƙ1Ï¡6Õª@ج?Ô¦6×­AØ­=×­<ݳGà¸RݶQá»UèÆcåÄgà¹TÞ¶PݱJÚ­@ÕºlëéËîîÚîíÜîíÝîíÛîìÚîíÛîíÜîîÝîíÝîìÚîíÙìîáíîáëîãìîäëîæìîæìîåìîåìîåìîæìîåìîåëîæìîåìîäíîáìîáìîâíîáìîáìîáíîßíîãìîåíëוwV‡X5rGzJ{F{DU/Ù¤‚µuRÂXюj±R>¨<0¬;1ÁWE¯7-ž£/ª@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ߞy߶‹ä½’èÁžè¬ŠÚˆhÛ}WÙuMè¤zïƜާ˃_ªE4 4(£5,¦8.«A1¨=-¥<-¾]B´N*¯M)½b9Àc=«Q*¥I'”4‡,‚%j f _Z X + \B540,(ƒW+s9—r/Žf ‘i&ƒ]‡[~Mad|2(”THgcY cgg jo ru z +… €‹#Ž'¤`Fß̼ƞÊ˜ƒÒ¢Œ… ~€‚!%{$ z7Ÿ†_Ÿ‡_¤Œc›hH–A›7¢9£3¦;§:¥8¥6¨6£9¦L-±pJ›l½—f·•dª‡L£{6™p%b@xX•h®„/˚<à·Xá¹RÛ¯GÓ§<̛1ȇã°JØ®SÞ¸^ݹdæÃyçɀíфîՊìЀíӄá¾kß»fëÍ{ëËu½8ºŠ,â»^èÆgçÁ[å½TÙ¯>á¸Ká·NÞ´EܱBÓ¤1Ѥ6Ù®EÖ«;Ø­=Û²Dß·HéÉ[çÈ_æÆaâÂ`âÂcéÊjîÖ|Ì©Gǜ4Ò¢5Ô¨=Ú°CÛ«A׫AÚ¯?ت;ݲFá¹Qå¾XáºQä¾Yâ»Vß·SÝ´RÞ­BÚ¨:Ę;ΰsððÙîíÝíîÞîíÜîíÜîîÝîìÛííÜîìÙîíÛîìÚíîàìîàíîáìîäìîäíîâëîåìîåíîãìîæìîãìîäíîãíîãííàìîßííÞíîáííâíîßíîßìîäìíãîîÞ»˜v°zN­uK¢e7¡^)œ^-˜^'®m?µxI ]6°kBÀ{Y¸hO¦;-§4,´I9œ(– ˜) 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ۏnܓsÕr[Ì^AØlLÛmKÝmNß`ã¥{뽎ç洊ʁe£7*¨=/¦=-§@-§=/°J/®I'±M(¸W*®Q,ªT,˜=-|u a [ Q L +K +J +:722+l@”m0…bzT“mwQ{T}U}TŒ[s5v3 ]Ke^ g"T [ \ +b +d +i msv}}€‰-˜G!Ò¡xгØ¦ˆ½ˆf _F}|‚+ z% +r%ˆX7ž‡[‡W,ˆ/™.£.¢2¨4©0¨.ª5¢/ ¢. ¢- ¥7¢=K(³€M³Y§…Dœp*“k!bB•dŸh ½‘:Ò¬QسVå¿[Ú±AÕ©<Ò¤8ŀÞ¤=ݳUá½gÞ½fâÆtíхìЃíԆìЀìπìÎ|ìÎzíÏ{éÉtÕ±VÙµXçÁfçÅdä¾Sã»RáºLâ¼Nà¸Oà¸L΢4ŔĔ ×­>Û²=Û±?à·FÛ°=à¹HæÄSæÆ`æÇgäÅdêÌlìÔvìÐs¾•+Ï¡7Õ«FÙ°D×­@Ó£6Ù®<Ô¨6à³E߶Iæ½RáºNã¼UݳHÛ±DÙ¯Dܧ9Õ¦;Ę?ƧeïîÛîíÜîíÜîîÝîîÜîíÛîíÚîìÛîíÚîìÚîíÛìîàìîâìîâíîßìîâííáìíáìîäíîãìîäìîäííâíîâííàíîàîîÞíîßìîàííÞíîàíîßìíàïïß \•d7¨h?¦h9¶wBµv@¸sE®m8ƁO•Z&N%ŽI©d?µpNªP=«?1®?5 (œ%“"¸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à›n崈٤xØ¡u£<&°=2¨9.ª@.ªA2¶V<®F'ªE&³U.®M(£F$3Œ.zn Z S L +I +C +?;745W-…Z{SzW¬@]}VX|W{R…\ ‡X§sIŽP6aZ ][S +R \ ^ d lnsxv'€; ŠKŽO]Zœn3¢zAu0* uzyz#z&s g( +’nH{,Ž+ —)¤,ª5¬5¥*¥+¥-¢*£, ¨1¥7£3ª;Ÿ6›H¤m8˜s+‰^|P ¨mƀ͞<Ï¥DجHʚ+Ο.Ò¥;Ò¢:Á€ؔ0ä»^çÄoêÌzìрîԇîՉëπìÏéÍzêÊuìÍxìÌwéÊséËpéÉoæÄdá¾[ä½Væ¾Xâ»NåÀNæÁXçÁZÜ´HÁÏܱ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џ2Æ¡DʱqíìÕîìÛîíÛîìÛîîÜîíÛîëØîìÙîëØîìÙîìÙìîàíîßìîàííÞíîàíîßîíÜíîßîíßííàíîßííàííÞîíßííÝíîßíîÞíîàíîßííÞîíÛòðޑx[xK(zN(~KˆQ’W#šZ%˜`(ža(Ÿ^.Ÿ\*©j7©g7®h@ܚs¿mX±Q>²E5©;-œ+³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Έ`ƂRɂ\£4%«7(«=-­=)¸Q9¼_8´N'´X:±Z9¦G›=’4‰*v +a O + M +K C? ;976@|O_ ~UyTŒk[vSyW{X|W–u#}Y~Z"i*_W +S +VS +JR V [ ` d jv; Žb"†\„^¥†“d/„T&zGyC +zF +xE €GŠNˆK‹G!¦]4½qLҀb¸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)¶@»R-Í|Uחl³Z>¤1³D,¶C,³D-³K4´O.¯J$¹[=¨J0§B%˜9Š.€"r Z L JB A@>;::e3U‚Y}[yWŠiwUvTxVyXtR‡h‘p#yUi1WR R S I >KNP +Z \ o5€[}Xl#tSwVuStRqOqP rQvV ˆ_wA k'hnjV= ]‚ £)¡&¢(§3§5¨2¥-— ‹™ ¡& £(ž$ž% š!˜!–'1K +¸Œ8Ɨ>ʛ7˚5ʓ,ɗ'˝-ɗ)Ē(˗*¾xޛ8éÀaéÅoéÉuíÏ}ëÏ}åÇväÃoëÏ~ìÐ}êÊuëÊwèÊræÅeçÆeܵQ̚*Õ¨<à¸Là·Iå¾RçÄ_æÀYâ½RäÀWæÂ\Þ·PÕª9Ò¥.̜,Ù¬<Ø°<ݵBÝ·Dà½Já½Kã½JãÀSÞºMʟ3̟2У7Ù®CÝ°FܳDÞ´CÞ´Eç¼Oå¾RâºNâºPá´KÑ¡3ҝ0ΈÓ¤BͯbÆ­uñïØîîÝîìÜîíÚîëØîíÛîëÖîíÚîìØîë×îêÖííÝíîÞíîÞííÞîíÜîíÝííÞííÜííÜîíÜîìÛîìÛîíÜííÝíîÞíîÝííÝîìÝííÝñðÞº¡€£rC§rD¦n8¥l6¤l3­q9¤k/£n2œ`,•\&—Y-©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*¹@#²=µ?%·P-ӅaÇ{\¶_?ž.¬=0Å[AÊ\EÈZGÃU>³J+¶P0¨F,§B%¢>'™7/…#t \LM +B>A@<? IxD T~W¢ƒ0ŠivUuTwVxVtRyVwS‘oqOi:WS UP +]($; A@G + K + TX%}]wOxV ´™SmMjOjLlNiJlNlNsU zZa"mBm+^U> W} ‘˜'£* +¢1£. +š& –"¡'¦+ & œ%$ œ" —"“( +‹,œ]&ʜMə>̚7͞9ʘ3Ŕ+Ǚ/Ȗ)ÁŽÀŒµt Èxä¬LìÊsìÍyíÏ~î҃êÌ{æÇqëËyéÊuéÊvìÌxèÇmçÄdå¿Yá¹SÛ±KáºTå¾Wä½QáºNá¸RåÁ[èÆ^äÀYß»Q×­BÕ¥7Ó¨9¿ŽС3Ú¬;Ú¯=á·Gß·Gá¼Oã¼PàºMß¾Rà¾SѪ?¿“,Ò¤:Ò¦;Ù¯AÚ³Bà·HãºKæ¾QèÂUáµFá·HܯBÙ¦7ӓ$ÆʤQǪ^±‘O‡xTòñãîìÞîìÛîìÙîìÙîíÚîìØîë×îìÙíêÖííÜííÝííÞíîàíîßîíÝîíÝíîÞííÜîíÛîëÚîëÚîìÛíîÞîíÛîíÝííÞíîÞñò⤐oqI}KƒQ#_/ŠW#˜`+š`.¡i5˒g䳊䷇ҌjÆoRÇjNÄmWޚÉ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£5¬<(­A)«N:¤A5’Ÿ·C8Ã[CË^GÒ^NË[DÂQ8µI- <" :œ= §Q3›C0Ž-(‰*(†/(‰6*w!NAAUS[a, ~N€WvR«Ž=pNuTsRpNnLsRsPzWtQnIh@X)Q QN VU+9 :<B ]-\jJlJxX |bsSiNfIfHdEdHfGnPyV }[x\xUU&Q2 Kv‰ "¦1%¢* .¡,œ*§.¥+§+©.£( ¡% #  $˜!‘#‰&‚/ΘXʛEɘ;̝=ϛ7Ɣ&ē&ʛ.ə.¶„¥q µj օ&ç´Rä¼_ëÌwëÏ{ëÎyéÎxëÐ|ëÏ}èÌväÄbäÂ^èÃ^æ¿XáºPâ»RãºQà¹Nà¹Oâ¼R߸OâºSåÁZã¿Xà¼RÞ·N×®HÒ¦;̛*Õ¥5ש8ܲAá¹Jä¿Rã¼OÙ²A߸LÛ¶EåÃZæÄ^Ȝ6Μ+ש:׬<ݳEá¹KÞ´Eã·Hà²Bâ³Dâ³HÛ©:֟0э Α-Ì«`Ê®iš>|]ñðàîìÞîíÜîìÙîíÚîë×îìÙîëØîëØîê×íìÜíîßííßííÞìîàíîßííßíîÞîíÞîìßîìÜîíÛííÝîíÜííÝîíÝííßññ妍oc7k8 +n>m=rAwD~FFÔ¨zÛ±Œã¾–æÁ–Í‹kºW=ÀR7·T9ÊmVÊr`¶LA©++š ª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ª.°B&Ÿ7ž@%}‹ ˆ ŽŸ"µ?5½RCÆWFÎ^NÍ^FÇTAÅR;®F/³X@™;+Œ#€{}t q TK Q bs1(m,l4{N }WxTpOuTsRsRoNpPoOrRwWwWrNfDT,JPK O`*#V-$+ 7 8[4€]…k'rTsUv[hMeJdH_CbGbF`EcDsT +z\oPtYuXG%4 Hk|Š ‹•#™(¡.ª:#°7"·G/¦-¥)£%¥' «/ $ ”Ž‡&‚ •IșHș?ŕ4Ő*¿‹ʟ7Ì :Ǘ0žn +\“X½k ׍*æµ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Ɩ&Ñ£4Ö§7Ú°?âºOåÁXÜ´EÓ¨2Ш1ݸKåÃ\êËdݹSē%О1Ú¬<ß³Aä¹Iá¶Eà³AÝ­=ب9Ù¤6ן4Е)Ãx Ï¢HĬcêdnV¯¢„ïïÞîìÞîìÝîíÛîìÜîíÚîìØîë×îìÙîë×íìÝííÝîíÜíîÞííÝííÞííßíîÞîìÜîíÜîíÛîìÜîíÛîìÛíîÝííàïðæÙÁ¥Ô rЏ`Ɉ]²zLžc4ŒNˆQ w=˜V-·{Qß±â½šÝ§ƒ¯N5ÅcQÈkTÈiQ«@+¥6,²@:¯81¢7-&ºPGÅVKÁMD¾C?¸><µ:9±81«0-­16½KM½LKÄMMÀJD½KA³I@£9+ž4%/%›) ¾F4ÂI@ÀK9ÈT=ÃT>ÆWHË[KÊZFÈXCÅR<¾F0»A1®/¦% œ ž#±J-—6 qx† } | •±9/¼K:ÅRFÉWHÏ]JÇTC´H1™+ˆ„‚‚|ysn a `^_~-&y8"m7 yMyRqM¨amLsSqQqQoOqQqQwWvWoOjGT/HH MOPoB;,(-J,rX b#rR pS nSdHdHjNaFdIaEbFbF]BdInPoQvXvXJ+; es‚ ‡ Š + ›+¨<#¶G,¼M0·L0§;µE"§, ¦*ž"š!&ˆ#u"º‹EŚA½/œ.Á*ǝ9¼“1ŸwƒVŽ`†]¨qÀs ܖ4ç»XèÂ^ìÎqèÉmà¾VÖ¨DÙ§AÛ¬AÙ¬EݱIá¹LàºO߶KßµGÚ¯DÔ¦A͝8Ĕ(ė.Ó§AݵQæÀ_á¹Uá¸KÚ°CΠ5͞.Ñ¡0Ú¯=à¸KÜ´GÓ¨8Ȝ)Ò§6á½PäÄ]éÎjæÊeǝ7Ϟ/Ù§7ب:ܬAÚ¥3Ù¢1Þ¦8Û 4ړ*Љ"¿wɑ>Ī_Á§_»¡ZQ7Á¶˜îíÚîëÚîéÚîìÜîëØîíÚîìÙîêÖîêÖîëØíìÜíìÜííÞíîßíîßííÞîìÜîíÝííßííáîìÛîìÜííÜîíÛîíÜïïà϶›Á_ŏXӖfӓcі`טbښdє^āT½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”%Ÿ.µ60½E<ÁI<ÅTDÊ[OÌ[LÉUCÁQ8ºD5·<2³2)©+¢" ›–#¡:$¤>+«H9‚!‚v +v ¡2.¹B;ÄI<ÉVA¿XB¢/#Šˆ‡†ƒxrng co$$n"lx8$qA vPqNpOxWsTnRpQqPkOjKmOpRuY ‹ofI[9D@ LTQKO&$'"9 \CkL kM +fIpU gLgNdKaFaE[>^B^B_D`EiMmQtVtS pQK#Rbt{ † ‰ #“%¤3 ­A%Ý£‰ã¿¨à±ÁL-¦'œ™•‹Š!xŽV§{%¦y"µˆ*¶Š#¹‘0´Œ$œqyOc»•<©"­tË á¡EëºRëÂXêÇiëÇh˜8½‚ɐ*͘5Ò¡:Ú±Jß·RÞ´OݲEΠ7½Ž$²´²‚¶†!¿Œ$Ö¬NÚ®OÕ©CΡ8Ϥ5С3Ö¦9ج?Ø­>Ù®<Ô¨7Ê -Ч:åÄ^æÆ`êÎkèÉbݽYΠ6Õ 2՞/Ӛ.Ў Ԉ х̄Ë~»qÉ2ƦZ¿¨_©e§“TK7ÕͲîìØîìÝîëÛîìÜîìØîëØîìÚîìØîëØîë×îíÜííÝíîßííÞííÝííÞîíÛíìÜîìÛîíÜíîÞîíÜîíÜîíÜïðàÉ´yHm8p=}FŠS%—_-Ÿf3¶}LȆW¯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•.!”%”$’ š!·>0½J=ÃM:ÅS?ÂRBÁM=»B1µ:/®2*Ÿ!— “!™3!œ9,ž4!ž0!-%y |{j +ˆ ·81ÀM=½]KŽ&ŒŒŒŠ…ˆ†‡„}wrf ]cihj +s@ wSrPrQvSvUnOrQkMiLgGhHjMjNçOwX +aC D? GG Y(%KR'!E## Q8Y<\@_EjOkQgPeIbF`E]A\A_D^CaFeInPtW pSmM +dBN\mw{ { … Š“š(,§=%¸L3ÀF+¢# ž +š“Ž ˆ}t8 x*°‹9¶”@—nŽe£€‚]±‡-ɛDʟGÁ—>©yº|Ҋ,ݔ'ì¹Næ¼Zâ¼eÚ­LƓ-³z¼ˆ"Ɠ,Ȕ-˛/ש@Ó¢2ǔ(žožp§x r«{¬|·‰*Á/Ǜ4΢<Ó¦=̟0ש7Ò¢/Õ¨9ت5Þ´BܶCÚµEÞ»TçÃ[ëËeæÇcäÁ_Ò 5ɉɁ¼w·m²f±o¬e²n½†3ÀœLǯgïl¼¦h\FTEÝÕ»îìØîìÙîìØîìÙîëØîê×îëÙîëÖîêÖîëÖîìÛîìÚîìÛííÝííÞííÝíîÞîìÛîíÝîíßîíÝííÝíîßïïÞν¨wI*O*i=`2 h9l9 k:m9 }< I1¬L5:(¯P@Îu\ÆfP¶K=¬:4²H<³L@¯E4´PF¤0'µE<¸O@­@8®I:°L<«F<ž8.•) ¶PB½aK±\F¬P=¬K8ª@:²Q>±T@£>0¢:,˜,$'’)!‘(š.$‘'“§0$¸C:¼E>ÄVI½NC¹E>³8,©-˜’“-¡B.•*‘!˜&Ÿ3'‘&Ž%&Ž'!‘1.˜7-v +£?8£P>v#‚‹‰Š‡‡‡†~yqh akks$i!nBtQrNoNuRoNoOnNhIeHdHeHgLhN¢ˆ1’u&K3> 7 6 += T#Q"K?@/C,R8X>]BcIkNmRcJ`F]B\A^B]AaE_DcFkLmRiMlN +dD_9Q`gpnx€ +‡ ‹ “# ›)ž,! ˜# — ™ ”‘Œxb#žw,µEjZ:T:$Žu-É¡JÉ LϨQسb®&¢p¿$ׅà˜.æ¬JפFÏ¢B׫KÕ¨DɟCƘ5Ɠ*ɗ-Ó¥=Ñ£:دE•c~N›l˜l£t´‡(·ˆ'º‹,»Œ$½‹#À&Ñ¡6Ø©9̜*̟,Ó¤/Ø«7߶Jß·KÞ¹Já½PèÇ`èÊhÛºX¢b³fžQT¤]£cªp +©r ´ º‘7¿¡NÀ©\¾©c¨”R6$k[2äÝÇîêÚîìÙîëÙîëÜîìØîë×íëØîë×îë×íéÕîìÙîìÜííÜííÜîìÚííÝîíÜîìÛîíÝííÝîíÞííÝïðàЯ}P0€M'K)‹U*ŠT(‚NrAvDŠD$žE' 3%›3%£@5¸\K®H4´E5¾`M©@0¦6*¡, £2«@7¯A7®?4¤8+©:5¦;,§;-©A6«O:¶S>°F<¥H8«O>¡<,›+0)²_G±WAŸ9,™-•(—-#˜1&•*$£F:–?)…ž&&¬54¶C@¸F>·@7¶>8ª)(Š+ž<(’$‘#Š!ž9*<0†!‹$—90©MA¥E4œ6-*#uo ~‰ŽŠ‰Œ!ˆ‰€~zvqk x4"g\ nArMpMrPqPrQlNmOhKeIbGcIfLgL´›GmR J470 +3 +9C X+P ?1 0 <#O:S;Y@bFhMjQaI]E^CZ@]B^C`E_EeJeIgLmQoR kM`;X0K T_ioxw}Œ! +’’# ›)œ'–# +•# +‘"Œ!¡R*ºˆT‘e2¯Q¼›ZÅ¥]µ—K¾ Q®—KÌ«UϦT¶Ž?»‘B”j ˆV‡c•i¾„%Տ(Ԇ#ݗ9á°OÛ±Ráº^éÒáÀfæ¿_å¾[á¹ZéÆfá¿]Ǟ=zQ²ˆ3”k ­‚!¶ˆ%´†*®&µ„#¸†¸‡ Ț1Ñ£3Ö¤4Ô¤0Ô¦4Ñ¡0Ú­?߶Lâ¼Râ¿VçÇcçÈeèËh¨o ¦_Ÿ[¡d¦lªq¬«…%¬‹/¬7·žR¼¨b´Ÿ]U;E0‡vMèâÍîëÜîêÚîìØîìÚîëØîêÖîêÖîë×îê×îê×îìØîëÙíìÜííÝííÜîìÜîíÛííÝííÞîìàííÞîïßÛË·¦rO¡k@X-…S+‚K ‚F†ER(£Q4¨Q9¤D' =%9/ž9+¥4+¬9/°A5¬D/­?,¦4%£2®O4¸ZJ°F9«:0²G:©>3£7&¦;#«K5¦A0 1)³NB¥-ž;.”, ’*‘'’(#˜2/½p^›I.„¨4.¬;/±B8µD9§6/ž)"¯F9¶[I“3$”' Œƒ˜;-‡&ˆ!…"§SA´aT‹%(ƒ„ƒ‰Œ‹ŒŽ ‹Ž"…ˆ!~yqlnu%†B.f) +j@lCpLmLnNqPtTjJfIcFbD`FiMnR‚d`G B/303 +: @ @ +@rM$`>. 6G0R8X?[B\CZB^D\D]B]A\@]C_DbF`EaFbGhLpY pYaD^9N%@LUajry†‰!…#0¦X.Á{PӛjềéЗì՗ïÞ¡ïߤïàœíԊî؊ïیîٍï؊îÔ}ìЂæъֻo­Š=sW +tQ ’lÒªOèÀg֟BԜ=ÙªLß·Zܺ]çÄjçÁeéÃgêÇlÚ±RײWßÁjܽjåÈv˪X³7®„(­„*³†-¬~!¬„&»'ɜ1Ôª<ب9Úª:Û±@Ü´FÙ±EÚ±Hß·Oã½UäÃaåÆièÌsάNgc¦r ©}¬ƒ$¨ƒ&«‡,»žK¹O¶žX±[”{AV5R5›Šbŵ™ìçÎïìØîêÚîêÙîëÛíêÙîëÚîêØîë×îë×îìÛííÜííÝîíÝííÝíìÛííÜîìÚîíÜííÝîíÜÛÍ´¿ˆaΓfNJ`Ç^ŌbŌ^§c>—O*¯X4¬K1¥I6Ÿ>-š8&²QH³QD¬>4²I5©:.©3#£1#ž/!º\J¾nZ³YL§E4¨?.²M?ªF6¤9*¥A,¯]H±RD¤@1 <)›6!–,&”/#œ6)œ7%œ6(¤B3—2$•+ ‘)Ž$'#²ZN¨Q=Ž6–9'* 2*³A7¯?=¨51 2(²O>–/†‚‰›82•;1’:*}}|Š!"‹(¶eWƒ„…ƒˆŒ‹Ž!‹Ž ‹#‹$%‘"-Œ"|omg f G*r7 h?oFmGkHpM}a“{+pNfHdGaE`DhL{`{_T?>,0((. 1 / :mN*fK':/9#F/N5Q:T=T<V<ZB^B[?Z?^B^BaFbGbFcHfKiNsWfKaAT1<= EQ [fj€-®g>Ȕe㹄ñ͕ïԙí۟íÝ¢ïߥîâ¨ðç®ñéªñã¤æÉŕDĖL´„;»ŒDÖª_åÆxìà—ìéªìë¬ïé©à̇¢~+qJtM¸—Gîà“ïã–íՃåÍ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·‹*¤s§|¤|¨†'¢‚(³’@¸žM¶žS¹¡[fMC#P5T:Œ{L­žz¶¤†ÓÈ¥èàÊðèÔîéÔîêÕîêØîêÕîìØîêÖíìÚîìÛíìÜíìÚîíÜîíÜíîÞíìÜîíÙîíÜÞÖÃ];—c8§kE±wSˆ\ȋ^ªlC¦]D¢R3³^C²VF¤G6§K?¦D6¤G3«KBÀ`SµX>¤90¥2(ž*$œ0(ºXG¥E8 8.›4$ªF4¨<0«C5©C5­P>¸hY²[L¤@2¨D7—0!$ š8.A2›5)œ4-–/)“*—/'š3,–0)˜2-¡A7."“4 ”6&”1 “!#¤78­B>§>3“*“!……€“4,‘84~ }t t €›=7‚ %„†€ƒ‚ˆ"#$#$#Œ#Ž$(“%*)-“11‡)!~!zmm—L6r7lFlGkFnKpN”y,‡q*jOfMgIaF`JbKqY ~c K5=-1!!"# 7X6nJpMQ/@$2"4&<+G5G3H5N9U?ZAW>ZA]A\D`EbF`E^DaFiNnR +pSbCW7C/ +5EG {@&ƜtïΞïÛ¥ïߤðâ«ïá«ìݦæ̎âÄήq¹’W¨|Bšb*ŠW™Z§b–U§v5Ï«mëՑïæ¦îæ¨íê¬ëë¬ìë­íë®ïäžÓºmžwwF–hܾqïæîæíçŸîã˜î؋æËzæÉyçˁԮ_Ò¨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˜n•sšv©ˆ,²–G²—K»£X³žY£JL2F.I2_K‰uF¯ ©ž~§›t° {¾¯‘ßÔ»îéÒíéÕîêÖîéÕîê×îêÖíëÚîìÚííÝîìÜîëÚîìÚîíÛîíÜÖÏ»pN.‚_=Šb>~R/k=‚F#¡X9¯eLŸO;­SAž@0›A/¥Q<·^M¢D7¹iYÄwfÁdT¼^P£;1¤/$ª90¹TDªA1¢<1 1'š1&;.£>2 ;1š6/;+¥G5¥H9¦@6£?6*!%#Ž-#œ@/ ?1ªNB¤D:—1&ž80¦A<™0,—,$‘*"Ž& ‰(+*ˆ%$}š6.²MF›."–,Œ!†ƒ€… |~xu ~‡'$‚$|€€ƒˆŒ"”!)‘!$Š#Œ!‹$Š"Œ$'Œ#'‰%2+€& ƒ#‚( w"u%C(o1mElGlHlJoNy\ƒr5gMfLdG_HbHeOzb`LK68(* !2\;„c&Œl$j#‹h#‘o$xX qR ^EK5=(C-K6J5P;S=V>W?W>ZBY@^CZ@hOcGhMiNoS gJT8J(" 'xO0ϪƒñÖ¥ïÛ«ïÔ¡áđөr¸€O¨n2¸‚EËMŒK¿¤~°˜g‡[&²„M̯vÙ³væҘïߤîä¥îê«îç¦îæ§îèªîé«íé©íêªîé«îë­îë§ïä™Ý¿g°2¦v*½•FÛ»qåÌîá—îã˜íäšíݗîՉɢJ͟SϪ^ãÅwâÃwäÆ{äÆzèÊáÃtãÅpäÆqäÂmÞ¼cÛ²QدFÚ²FݵKà¸Qà¼Tá½VáÀ[áÀ[æÆhæÉoéÐvåÌxÛÁm›t—s¡+ª1³”E²“G«F´œXu^'6!8'E0eS†sE°œwª—o¨˜o«šy¬œz¯|àÕ¾îèÙíéÕîêÖîêÖîé×îëÛííÝííÜíìÜîìÚîêÖîìØÛÔÂl@"qI#tP.rE%tE"‹K.«`K´mO¥[I›D.š:'“6#œG2¶cPžB0¿sX¬\DÁ[K¶S>±G8§5, + +¦:-²N@¦F8ž4%š5%ž9*¡:/•-'œ5,´SB½aK©J5ž8/•.++"Œ%‚!˜=) G5–7/Œ(˜4&Ÿ:/‘,#’,#“, š8-•)%…!‹*†$!›>;®IB¨?: :7&#‚Š)#ˆ*)‚‚!ƒ'#~#twz‡4&ty~~{„„‰Œ”"+˜'/Ž#Š ‰‡!ˆ "‹!'Š"*Š('Ž/-ƒ""|z…0Š?"l1lDmHlHmJlMØÒ»ãàÏeIdGaF_HdNdNƒl%T@F27&) +>% +iH}Z€_ +a ˆd¨Œ?¯–Esƒc }\‚c +kPW:J5E0J8K6O:T=T;U=X>]E`GaFcHfIgKcHdLX9K)H- ™uNǘpÀ‘c¥k=‘S%‡OŒR(d9ď_Ó¬rãʼnæ͑éҗéå½ëÞ¢ïä¬ðé¯íì·íì³îé¬îâ¡éҋß„âĂê֐îޚîܚîޜè֑æЋæʄڱdà¼uì҈ðâ›ðäîߘçՌÞÂpϪSÒ«^ÞÄxì،òãšðیéÊ~ß¿xßÂvàÁuæÇ}äÆ{åÇ{çÈ{äÈxàÂkà½bß¼aâ»[Ü´M߶MÞ³MݵHÚ°H߸Pà»SäÁ]èËoêÎvêÏ}êЂãÌzÉ®VŸ~(»žO§V¸›Nµ•L…@³šV@.&1 6&hQ$‰qEšsH {K­•j©™v¨˜xª™z¬œ€ÛѸîéÕîéÖîéÕîéØíëÛíìÛíìÚîêØíìÙíë×áÙŅcD‚U2‰W0“^7–R4¬eN¦WC³lQă`œM9˜@)™;)™A,œG5˜<)žI3¶cK´UC¾[J²UC¥9*¨;0¬H:¤?.¥?0¤D4¦C2§C4;)ž8$—-™3&3(š5$“.–+!”/'–1.–2)‘'“1'•6%)†&‘0¡B0¥E=™4.–1, A4±[P*#˜7)’4$¦NF±WNŸ?2¡?6ˆ%'€‰!Š/%….%) …%!|…**|#wu‚!!ssy{|€‚„‰  &‘"(*Š #Œ#‰#ˆ!‰!#Š")Š')‘6+‹-)„## }x}$Œ>+h5 f@hDpKoOkN¿µÞÚÑjN _B`G\CcKeMs[N87*0%%<) _G uW ~[ˆf~]ˆgr"™{)¹K£‰<‰e„d|]xXiKM3A/G3N9O:R<ZD[AbKhKbGcHhJcG`BJ3H&[4p?yC”f?©|VßvÝÀíئïá³ïêºëì»ëí½ëí½ìí»ìî»íì·ðí·íé´ðê´îà¡ä˄ǘMÁŠD¯p*°u.¹6ΛRÒ¢Y֞T¿8š[ŸbʔH̕Fɏ>Î8˛KˤUЪXÔ®[×½kàÁnãÁvײf½Ž;‚Wb@X<x^#׺qäÇzäÆyåÈæÊ|áÁsàÃrãÅrà¾fß»_Ú²QÛ´LÛ±KÚ°JÓ¤6׬?߸Qß¿ZåÄ`çÈjêÎvêЁìӉßÄtÝÂpĤSÖ½rѺu±—N«O¤ŽQ‰u73!/!7#0"jY)p[0iNi8Ÿ„T©˜q¦”w£–y©›³§‹éáÅíçÒíèÔîé×îé×íêØíêÖîë×îì×åáʌeFH#ƒH&§iI¸p]­aH³hT¸kZ­_I§X?¢N<ª[?œA*¡M6¢H8D1©RD¼pcÐj¯H<°PB¡4)«B<¨JAªF=ªP>¦H9¨E8£@3Ÿ81ž:*˜2)Ÿ>-•+—1“.!œ:8š72”2-”2(”,(Ž'"‰'!*&+"Ž,"Œ+"—72–4+–1*š81.&4$­UD²]N¼kZž=3—:/†&&|‚’4-–<,ˆ,#€!|zxvvz}$otz{|„„†‹!!"† ‰ #‡ "†!„ ‡ !‡""•77‹,&}ƒ%"‚!€"€!sŠA)e4fAiFiFiLoQ×͝§”YiK_D[BYAaIbH]GJ57),#$O< iP zXƒa  €1ÖÊ£„b +‚e‡e ”v ØÁs“rˆj ‚b„b^qPS8@/@/G3J4O<X?]DdN bFeJbG^DL.dF•q?ÁžiãÒìÚ©ðæ´ïê¸íë»ëìºêì¿êíÀìî¹íí·ííÀíç´è֛ԲvǦjœn2¤j1¥i,¥c"­o,£eЗOˆ?¨o(™W“O  ^¤^™U‘L N ¤g&¯w2»{2Ô¥Qà»iåÃpéӃè҄áÃuÖ¯g»ŽB·ˆ>ª|-„QY2, hOçϋéІâÄ|ãÆwãÄvàÃrÞ¿gâÂjÛ¹[Õ¯JÙ®HײGÚ´MÒ¨=Ð¥8Ø­Cá¿YäÂ]æÇkêÎyêЀëчàÅuÚÀlÊ«[Õ¼pÕ¼u¦ŒE«‘R›ˆNWC0 7%8$?,lZ*P=YAsX(‹yJ™ˆ_Ÿi¤•v§—w§š|˾ïéÓíçÕîèÖîëØîéÕîêÕíëÙèáÈ£rM«jF²jH§]BªbL³jS¯dY®bR«YL¶n\¨[JÂ{h·mS¼n\£PA¦TE±_JºaQÂwa±XH©<0¤7+¥80 .$ž2(»XR´]K¡>+¢?.™3# <-¥C6¤B7¬RA©Q8.¤J?£UB0%’0*“2&’-$‰'"Œ'%Œ,!’.#’-%+!•4*(•1)’.%“2'¨Q;”<%„(~‰% y|}ƒ&„(|}€" } vu|Œ/+‡)-mx|z~~„ƒ„€|ƒ‚:;’55}~ ~ ~$‚)!x!x._)hBhFjHmLoS~^~afJ`F]EY@X@_IU?B.4"&&\D +oQa +~^ +‡fлuœ(…d „b†e”u“s‹kŠgˆc…b„aoON7>.>.E1L7P;W@V@ZBZAY@ˆj+Ó¹zèєðã­ðè²îç°îê»ïä«ïæ°ìèµíå´ëÞ§æΘϰu»ŽPªq?–`(‘UŠU¥Kr<±LÀ‘UÁOĞj²‹E©q(¯w4©x1µ„=»HŘRÓ®pܺ{ãdžâāݼ{Ò­kº‡?·€5±{)¼.Ö RÛ¯`á¾oçË~ïޕîߙíߙíڕçянx¨’N—~;âˊîߚîܖḉâÄxáÂpá¿iâÂlÛº_Ø®NФ>ѪBܱQÒ¨FÒ¨BÚ²Lß»XáÀ]äÆmèËvê΁ì҈èτàɀ̰hÒ½w͵qŸ…F©Q|i0;#=%@*6E+eQ!XFaM#‚pA‰zL‘‚V˜‰`šŠcœ‰`¢“p´§ˆîçÐìåÐîêÕîêÙîéÕîëÖàÖÁ˜cGœS1¢ZA›NC¦YO·scœN8ŸQB¡YE¯cQµnV½ue­cT¸u\ʈu´iXÄud¸_M¸VF§C4 82 9.©B3ž0)Ÿ2'°L<¦J9¨J<ž<,¥C1¡@/¢>/–3&¦D8•3 &”3)­gP•?0•3(˜2$•3*)&‡$#† ,$, Œ(Œ)‹*’.“.%,#–5-“3)Œ-~{…! {|vxy{uurtq|.1ƒ" v|y~‚‚„~€~€|“87….*y}~ ƒ$ƒ&!$ y!0!a, aA gCgFmOqU oS +fKbH\BYAV>S<U>F4>,0,fMrW}^a +_„b‹jŽm „e„c‡eŽl‰fl‡d„b…b~[wWF4:.?-D2B/K:L6Q;`FºŸféӕîۛÜŸ–_¬‰Sª†MžqA’Y/’Y6‘X1‹R)‚M†Qj2³‰QÒ­sãʒêÛ¤íâ­îèµîê´îì·îë´îé°íç°íç­ðê¨íä©îåªîæ¬ïç«îé¬íí²ìé®íë±íë°íê®îé¬íâðáŸëԍڷfÔ§W͚MÁ?·€7¼‰4Ô®_èЎïߚîäŸïå¤ðä¢ðà›îáŸîáîãŸîáì֍áÅqáÀjãÁjܺaÞ¶U·‰ «¿“3ΤFÒ­LÕ¬KݹWà¾]åÈtæË{é́ëӊéщÝǀγj̳mǬg¬JŸ‡ER= B-K1J.M0YCaO!fU&iY*wi7’W’€V’‚X“„Y›‹a›j©žìãËìåÏîêÕîëÙîìÖëçϐcFŠL0ŽE.ªdN®hY²jU¡QD¤Q@šG=QE¡XN³se®j\³mb¥_L´lc§QFªOD²TM¶\N¹]L¡;1¦F9£E5¥=6§>3¨B4 C5—9'?-¡>0›=,·cO¡O8˜3!™0#'–7+¡E4›;-¢F2šA0—F74&‚#%—E3‘3)’.$‰)‹-%.!–5-,&1+…"y{€! tqqrtrstutu†•:/‚‚‚†ƒ…„‚ƒ"~~!}~‚#"…+)y!~$%|%!‚$‡&%‚#'z/^*d? +c>gDiLjLjKaEaCY?T=T=S=K8=06&'4'eI rQxV`_}]„b‡dˆg…b†b†bƒa†e…cˆeˆdˆe†emV?/8(;,;*?/@,eKÒ¹ê֗îޤ¥eP(;88D^-…V0ªRÍ©xÞȎïá©ìéµíì»ëïÁèïÃêí¿éîÂèîÀêí½éî¼êíºëìµëê®ìé«ìì°ëì²êí¹êíºëì¶ìì´êí¶ëíµìì³ìì²ëí´ëì³ìì±íè¨îã¡îæŸïã›îè¦ïæ¢éؒäÉ}ܹmØ´nʦZÔ¯[æ͆ìڏïäšíäœîâîãŸíä¡îã íڔåÉßÂqÛ¹_Õ¯NÑ­I¸Œ*¨{¸Œ&×®Pܹ\ݾ[ÞÀbäÇtâÈ{êЅë҉êӌÝÅzÀ¦ZƬj¹V¢ŠEaJ4 :&<#;$A)]L aO"hV)o_1q\*ŠxK’€YŽ~TW—ˆ]gŸ“pçßÉìåÐîèÔîêØíèϗoTˆF'”@)œB0°\F¯bH›O4£UL¥TK•G==3Ž>;žSPšOD»ti›JA«`W¨RL¤@;²^LٙŒ¥J<§F?¦LI¥NG ?8¢?7¥C7ž@-›:0š;.˜7(¯ZI½uZ´mM9#8#–=(¦W@“=+LJo·y[±pW˜V@x%„'ˆ:'‡H*–O7“I7„.$’8-1(‘3(–6,€||} vlklrtoqsusyA@•B9†(‰%%……!† † Š$$ˆ# †# Š('‡$‡&!‡%#‚|}/*†. vx€"#Ž3)„, ‡2+t-e.`6a9eAhJiKdFaC_BZ?V=]CX?B-8*.!" 9,fGtU|Z‡e^ƒ`ƒ`„bˆeˆf†dˆg‡f…b…d„aŽhŠgˆd‰h +kM5$7"4#3#wa+Þɏîáªîâ¨îá­¸•Z_5 jDhHˆi7À¦pæÒ¡íâ´íëºìî½êî¿êîÁéîÃèíÃèîÃèîÂæîÄèîÃêî»êí¼ëí¹ëí¶ëí¶ìì´ìì´éîµëí³ìí´êî¸êí¶êí¶ëî·ëí¶ëíµìì°ëì±ìí³ìì±ìì¯ìë¯íëªíé¨íé§íêªíê©îç¥íè¦îç£íã ǟѱdΤYÔ­_ãÇxíޔîä îå¢íâîâ›ïޔèÍ|Õ±[ѪQÜ»eàÀiØ·aϪRÖ³ZÝ»bÞ¾f×·aáÁnåÉ~é΄êЇëӍàȃֽq¹œT«•Kxc"1A.E-5 .6&\L^P"hX*n[+q^+|j9Ž|PV”„Y•†[˜‰a¤—uìäÌêâÍîéÔíèÓÕ£†°_F¡J3˜<,´ZU­ZG¬U@°bS SF‰;6u%#gc fdhfdl')ª_Q´aSºidµaX£H@·bZ¹bS¹\Y´ZR¦L5—:+©NC¤K=°[KÄv^´\B¢D+—?,ˆ9'x0³{h½Žn½‹k³€fUF|1$’>4¨fR§pR°x[ŋpÉn‡6 ‚"*(‘+'ƒ…'%# "„'$xuokils|+"qtqtuy£[M¢L=‹-$‹*(…""ƒ"!1(%'”2-“4+,),#Ž+!Š+‡*ƒ"!# }€"…-$}#{"&„)!ˆ/#…1%ƒ2"„1"…<#p1_7a<cCkM gLgH`AX<[BT9W?R8:)-   <, eInQyY€_€_…bˆfˆeˆfŠhŒlŽk +†c„cƒ_…bŠd‹iˆgm˜|"H0'6#šƒNëÜ¥ïé³ìç´ìèµëê¸îä¯á˖Üčèӝîå´íí¾êîÁéîÀêî¿éîÀèîÄèîÃèîÄçîÄèîÃçîÃëí½ìì»ëí¼æìÊæîÆéî¿ìí¸ìì·ìíµëî¶êî·ëí¶ìíµëí¶êí¶ììµêí¹ìí´ìì­îì«îé­ìë¯ìì±ìë¯îê©íç¢íè¢íé¦íê©ìè¦íé¨îè©íç§îå¤îä¢îݙåϊټwÊ¥\Ù¹qìۙïáŸîàîà—îâ˜ì׌âÇxàÃràÃsßÁrâÂqáÂráÁläÇpãÅuà¿jáÅræÉ}æ̂ëҏæ͈Թl­ŽB“{2K6@,nRc+sR\6J1q`.]Mk[-nZ)ra0yh7Š|OŽR”…X“‚W›‹j§˜yçÝÃêáËëåϼˆožI=¨MD¨LB—80ž=7œA5¡J:ˆ:)ƒ9,kh^Y`c[Y_]ii…1.ϒ‹Âxm®aO¼ja±d_Í •·rZžJ: F2®]J«[D¬X@¼dE²[D„3”N9ŒK1£eGÀ“z¼’vº‹n²l‰RBw*#†+'L:¹|cÎrϚwԙu¬eC¡J6˜@;‰-+~|~ xz ptlitoz(%y*$spprv/)Á„n­^N•7,‘21Š)'„&#‹))’0+•90”0,‘.'›?.ŸF<›EB‰4-‡3,~&!z %!w €'€)#‡3-+#’A1•I;K;„9,t!u+e.`6a<cDiKfI_AZ<U=O5P3@*-&  /%^AoKvT{X\€^†d‡fŠh‹k +”sȱl™{!†b…a…b„cŠg‰f’s…e cG0!ìrðß¡íç®ìéµêê·êì¹êìºéí¼êí¼êì»éí¾éî¾éîÀéíÀèîÀéîÁêî¼éí¿èîÃèðÃèðÃìîºíê³íá¥èԔã̏ç՚çؚèҔæˑæɎç̊åʆæΌæҐèՓëٔéۚæ֒èՖâāأZđHʙQãÃ~ìݘê֏áÆwÛ·gä¸kéÃyíԋïä îã¡îå ïâ™ïߘîޖïà›ïáœïã¢ìڕßÁxÒ±aÕ·jؽxÚ¿tÝÂyêՏíڕãÊ|ãÅsåÆuäÄqÞÀiåÉyçË|èÍ|åÊxåÈzç̂ḉé·çψÛÀv¯‘@pR>(B/€^Žf#Œ_ |NoLxa+_QiW'nZ'uc6rc5…vK‹{P€VW›h²¤‡ëâËéá˺…s›@6<;•1.–60§KC¡E<F=‰7&u&t+$gkUN\ad"\^Wecbk"% TM¶kb¼qeǁz෠˗z±fT¯QA®_N¤O9¿sZ­[F’@,«mU«k^–Y<M0ŸhL¥vY›cK}@(t3s&‰=2ŒD5¡_TÀ„l¼_Ηq¿ƒg—I6w$kw}xqnp|()w)#ihrv&%lijnt!q?0·wh¼rd—<.50--Š+&Œ)&”4/“<3‘:2žH=µk^ºrf»ud·zc®qZ¯k]K=x) u‚$ƒ( ƒ-'|'H5’J>F={+#kg b![,]:[<gK oR]@Y=N5J0=&/%   #V<kErPtRzY`†a‰g‰h +‹j +‹hÛִɹl „,ƒ\‚a„b„b‹i ŠiŒlwWŸˆDêכíæ¯ëë¶ëë´éí»éì¹êì¹èí»æîÁèí½èí¿èí¿êí½êï¿éï½êî¹ëê°ìâ¨êݦâńڳqجhâ»{Ù²pÒ¤bÌ aÚ°wÙ²rÍ¡`ƊW¹v?ÁŠCׯoÞ»zÛ»tßÁ{ßÁ|áÄ}áÃ~ß¾xÞ»yØ®kÕ®mدfßÄzè΀â¿qΣTÁŽC±l!©Z¸y$ΘMÚ²bݹiΞIϒA½{-»1ΠNÝ·kâÄwæ̈́޾mÜÀpÇ£W¤y-¬”NxV~` ¦ŒFÆ©[ÝÀráÁnÝ¿iåÇvçÊ}æÊwÒ±XâÅoåÈ~äʀéΈèϊã˃Ȯar+`CxV”i"a‘e$Š`!yVyZ#fU$kY)o^.ra3tc3{i?Š|RŽT“ƒ\–‡eÊÀ£èßÈéá̗:1š<1ž;2”/0¡F4¢K9¯cT™O›QJµua̞|¶z`y*rjrxvnhnz(&t#qv' s$m!hloq w&$t'YK«gY£WJ–B8Š3(Œ.,~%€,!90‡<.F3“E>—M?ŒA7D/‘J5°jT±t\±o\¢^K€3+‚&ƒ&w Š8-:'u,!r#dr'|:)q4Z/R4Z;eG^?Y9R9C*9"-$   B4 fDpLtQzT~[„b‡dŠg ‰g‹g¦ƒ"º¤Q×͆Šgƒ`€_‰gŠh ƒe +…d€a åΎîã¨ëê¸êì¼êì»éí¾éí½èí½èí¾èî¿êî½èï¿ëêµìâ¦éԖæă޳qà±pÛ©fÖ¤`רdâºwé΍ìÛ ïÞ¥ì͚è͖è͐äɊܰvǓT¬f)ȓPã‡ìғìؘïá£ïä©îæ©îå¦ïæªîé¬îë­ïç¦íè«ïè«íè¥íæ£íàšíܙæܴ̂mÒ¥\č@¾ˆ5º€0¹+¾…9ǖRË£XÍ¥YË VÔ¨^âÀwÞ¼pîáëé²êã°íîƖ|8^@ +;$N6¨IàÄváÃsäÅuæÉxÔ°[ͧRعbåÈ}åˀæ˄êЋëӍã̂зjjH +Š_¡o(\‹]”f(o0eTi[,l[*p]/s`3uc6wf<ŠyT€W’VšŒjäÝÅéáÊêâ̽ka™<5¥C6¡E>B5›B2žR=t%qjgkmi]]d!g$"a [^[P P RUt-+›RJ°aYªbWʈ{¢R?Ʉoß®•¤P7¾w`ªmPċl»‰iu.n&X e^ [Z_r3+ªqf“Q:‹?/|,(—NAµrUžU;…6"gnqxuqlolmn s$}1,z2/ƒC7z3.p!v" x##{.'—TGŽ@2‹>-0&p"m!h{.&y0%y6*{7#H7O7‚7(~0'u-„;)«iR®gRw5)g"|+$x$z*#}1)5+0(}1$j|6(‹J3ƒQ2oC!L+W9 W6U4K.@&1,&#  + :+\>hDoJyOyT^„a…c‡d‰cŠc‹e‡c†d…b„a^ˆh„duWѶhïà ëé±êìºêì¼èí¾èí¾çîÀéí¼êí¹êë¯êٛá¹|МVˎJÖ£`͙U¼~<·w5½|CĐPÍ aÕªhتlÒ£`ēU¾‰TÁXË¢iØ´|Ùµ€Ñ¬pÉ `ȜZΤbÌ _˝`˝XʝWТ[Ô§bʞZË YÍ¡XÙ­eäÁ|ëϊæȁèÂwêӎïáŸîç£îéªîâ¢îߘíݕëؑìۖîߜîâ îâ íá¡îàžíߟîå¦îå¥îçªçêÃåëÎèèÂèؕÓÁ{¨E|e! †>ÝÁsܾjÞ¿oâÆtÝ¿mÝÀrÝÀqåÉ}ç̂ç̂èτì҉äÉ|ؽpŠj™n”c‡Z}M +‰\"˜y?\JcY+k[)p_1p^1t`5xh>€qF€V•€W¥“oæÞÈèàÊêâ̤`R›H>š>4¢JC¢HB¤HAªUJx"€-%on!‚6/mq%'e`i"8;p*,b "_n-+WNQ T\p,+•IA¥WP¶nf­cK«cK¿v^¶m]ʘyčqĎp‹F4k$b"m,)>8m.-b^Wc }<4ƒ@+t&jQCD+“F/¨jOls w" x suo},#€7,}-0y)(p#s" s)"†D:;7x'€+(Œ?:‰>1€5)}-h ` +_daq)!l%n.!z7%˜_K•ZJ„>)ƒ:'ŽH3z3 5(‹E1l'g!l"4)w-egd\[fo-$s0!c,P! +T-S,F'7 ,)%   +L6 +a=mItJuP}Y[€]^…^Še +j Šh„aƒa…bƒb€^yW¸›Lïà¢ìé²êì·éí¹éí¼èí¼éí¾éî½ìå­çƋӗTă?Á;Ø¢]Ú­f¿„?”Q”Y ³GÒ­sä͒åϙëԝèҙìÙ¤íà¨îã¯íç´êìÀçïÇéïÅìí¼íì¸îë³íæ«íã­íà©îÝ£íٚëԖäNJ׺yέiϧ`˛S΢YɒH«f!žS¾v4їQÛ¯eåÂxëגïå¢îãŸîæ£îå¥îè«îèªíéªîç©îç©îä¥îèªíé«îçªîèªîç¨æéÁæîÃíâ îۘßʃä̃áÉ{çρßÀpà¿kâÅwåʁé˃æɁé̂çˁè΃êІâÉ}ÜÁsªˆ=›m"¦x*›m"™i'¦{=q4ZIl\,r_/m[.p_/ra4tf7yj8‘€V—‡bº¬‘æÝÇéàÈêâ˖RG<3’9/¤XBJ>ŸD?§UN˜H8‡4(’;0 NE“GK‰@7ŒK¶‰p’UBˆ>+†;)}6(n#{.‰<.„90r't%{/$s+!j#_e!Z +S `_RKFC?.'&%     8& ]8a;oDtKzQ~W€[‚_ƒ_‚^‰e +‡a~[€]~\}\~_˜x"éՐîç¬êì¶êí¹ëí¾éí»êì¹íê·æ̏¿…?·d&Ãx2ΐGɒK¾€: ^¯u-×­qæҞíé²ëì¼êîÀêí¿êíÂëîÁêîÂèîÄéíÂèîÅæîÇæîÉèîÇèîÁêî¾êíºëí¹êí¹ëíµëì´ìí¶ìë³ëìµìì·îã¦íܙíܕíܕèщ͢[˜`رná½wÙ³lÍ¢SΜQ͟TäÃyî׋îܖîáŸîç¦íè¬îç«îæªîæ§îçªîæ¨íè©îä¦îã¥îâ¤íé°êéµîàœîߙîܘêՎêՏæֳͅ_Û·gæÊçˀãÆ{çÊåÉ~åÊ~ëшãˀؽmÃ¥WƒZ˜k!—d™i"šu1Œu9aSm\-mZ*pa3r`3uc8q_2yd8|R•†eÊÁ§èâÉéàÊéà˄1*‹4+Š5&šF3˜=0™=0¡GAŸM?¨_H¦ZCŸSB¬la¯zh¦r_r5-j &x14t/*‚E8t4-WZ\ XWN H +J ]‘90”=1šK@“F0˜=/’E1¨p_™bUv:*i+c#ad^f#`^XZ`s1%‡K=`Q£bR¶zhªlZžaJs2!\ mtpv#„51‡94…40ƒ/*€-&}+*z*&2)‚7-‡>78,3%s!m"\[U +Q U ^b Zg$l("{7/’ZG‹L<ŠG6z0t/%gu(‰<1|.'w&w&q"h ag!b^^b^P H < 4-) "        +%I/_:f<lDsLzP}Y~Z|X|X{T[{Y\^_…c ÛÂxîá›êì¶ëïºîå®êԚàÀ„Ù«o´|A‰B…7“C ’E +¤`#’R ´w8Ø°qìÞ¥íè°ëí¹éî¿êîÀçîÍéîÁèîÄéîÄéíÃéîÄéîÂéîÂéîÃääâæìÔéî¾éí½êíºêî»êíºëíºêí»ëíºëí¸êí¸ëí·ìì²ìê¯îç¬îæ¦íè¬îå¨îç©îè¬íé­íç«íߙàÂ|Á‘F͛Oש\ǖFÁ?ݳjåÄíהîà îè©îèªîæ§îä¦îã¥îä¦îå¦íä©îä¥îá íޙíݜìۓíٖéՍÛÀqÒ§Sà»hâÄtãÆ{äÈ|äÇ|äÇ|çË~ÞÂoÔ¹cؼn~[|P mAtG|Y„p3hX'kZ,m[,p_1o^0ta5sc9zg?…uO™oàØ¿êàÌëâÍêá̈*'‘6(;-—C2¦K?¾o^­XO›F;§^E J8²gWºŠr·o§ucB@r++u*&r(%f "i)!a ZUWYPR M U o†0,”C=œNA¢H@u&|5-u-+h#!h%$f!!p+*g]o,*n),g!#aX_“TK£ne—\O™^R aY–VP„F2` Y monw%†6/HAŠ71’@5@5„31{.+ƒ4.2,}0-m ddU P Q +S S Xah$i)!m,'i%l$ q0$h%i"}7)gco%€2)x)!|,%x)"y+#q%ao%#t.(k&$cbe!q0(f+M; / "     + +?)P1Z7d@kEnGwPxTzT{VyTyUxV|Y|Z{Y¶•Kïà£íèªíç°Ñ³xžh2KC¯m5µ|G¤g.³~C™e&ÀkÖ³uàDŽíÞ¢ìî¿êí¿êíÀêî¿éîÁèìÓãâææíßæîËéíÃéíÃèîÄéîÂêìÁéîÁäé×æíËéî½éî¼êî¼êíºéî¼ëí¹ëí¹éî¼ëíºëí¹ëí¸êíºìì·íë²íë´íê³ììµìëµëì·íë²ìë±ìê±îç«ìۚíٖçӋԯj¯v-¢cžZ¤dËAرjåɁîÞ îã¥îä¨îã¨îã¥îå¦îä¦îà¢îà íܛîݚíۗë֌àÇz¦~0¿’Eݳ_äÅxäÆwãÇxåÈ{æË{ßÄuÞÃväÉ}¯“CpJd9mHnWj/k]-k\.n].oa1rb3ud;wfAxgDˆuP²§ŠçàÉéàÈêâÍëã΍4'š?1©UGžH8 A8ªLC B8 N;¦`I‰70£bT®xd’WL}@5c!|;6u((s++b"r0-p+*a OQd40NVMH [ p$•F;®bLK?hn$p(#m*&k+'c" m-)l(#q.+n,(l)*k()_$c%!g&#ƒCBŠMG’RL‘OEš\O‹M>x6(\RZk o w&…6.™PH“J9™H<¥[H”M:5.4,3!r`^V O O SXa]e$$f&!\#a$s5&h%i!j$_bdbaiw)&|+*z%$~,)x(&{*,z+&q($t+*s//k&#e`e!`#XE 9 +.$ + +   ! $ %J-G)N/U5d=lDkDtMvQwRxUwSvSvPuQŽk éҔîç­ëÞ x<`5 b+€= ¸‚PåȓìØ¥éךíݦêØ¡éåºìì¾ëí¿éîÃéíÂèîÅèîÅêîÁéîÃäåãããääåææíÞèîÁéíÂêìÁèîÄèîÈçîÊèîÂéî¿éí»êî¼êí½ëì¹êîºëíºëì¸ìí¸ëí¹ëí¹êíºêíºìì·ìë¶ìë¶ìì¶ìì·ëì·ìì¸ìëµëì³íë±íë°íê¯îê¬íèªîç§èՓ׼w¶F­z9¯w2¯|3¸}5čBجcéАîæªîæªîã¥îã§îâ¤îáŸîߝîݛíۙìؓëՈ¢3T,—n!ɤQÛ¼iàÀráÃtßÂtçË|ãÉ}æ̓ßÇ{“p#{LŒf&‡m/tc&iX'n]1o]0td9rb6p`9yfA{jK’†hèßÂæÝÄéáÈëâÍëäϚKB›C;<0H;¡G@Ÿ?;«OC¨YGƒ."il' t3+\Q U!‚HDn',f!#h%'h#']WY!T< NNE E W gšN;žH?‘;7fo!dp.)p.*d"l,'m2(n2'o3)s36v76EF£rnj74n//ŽPF‘UG’L>‰G:€B8q1(L +L P k')y*${(#Œ95ŸZM“I9›O?¬cV“I=…6/}/#s&~2-d_WS ]ˆMD`g(]c m-)x<3t7,|;5l("j' ebch i _S +Yx(,‰1.0/„-)…+)†*'m# z1-l))p+&e\VWTQKD8 +5>$$ +'& * +  E,qYFuS;a7J"B(K+Y6c>f@hEkFmKkHoKoLpLlGгmîߥîè­·“THSŽd-ß¿ˆíá¨ëí¾êí¿ëí»êî¿ëí¿êîÀéîÀéîÂèîÄçîÆèîÅçîÇåíÏèîÃéíÆçîÉçêÐåéÔêíÁêíÁêíÁèîÅçîÆæîËéîÂêî¿êí½ëíºëìºëì¸ëíµëí·ìë²íë±ëìµìí¶ëí·ëí¹ëì¸ëì·ëì·ëî¹ëí¹ëí·ëí¸ìì¶ìì¶ìë´ìë±íê°íê°íé­îé«îèªîå©ìܛèғèӕæώ޻sÑ­bœGʗSáÃ|ïë±ìÝ îã§îä¥îã£îàîà íݜíڗéՍеhjJ X7pK¨ƒ5Ó¬]Þ½mãÇ|àÅwÝÂuâǁã̅˫`“j“m*‹o7iW lZ+hY,u^3m^4wd9ve>{i?“ˆiá׿èàÈéàÈêâÊëãËêãͦaS™A7¡J;¯YSÄoj«YJ—?'5%{#rd[SS W}C>j+,X\"XSSZ Y" NLSK `Tc„4!¡E5´aSw lk!o.(x7/j)"v91s9-d*t8,k.*x;2–a\¤xjm52v77ƒC@~?8{5*€=1p+%f%!O K + +K +\ˆ?4ˆ?4?;ŸQJŠ5+£YH¡_N”H>‡9*z.:%q)"fa\`m.%l,%b% YTh.!~E;@6~:2v/-m##dbebk#k!!dNM^‰4/8:–?;Ž;3w%#[[ Zo(#k#k'%h&"^WRPC = + = +E7 +- / 61 / +_C2†^M…QHs:*h,V# EI%P-V1Y7[:_>_;aAcChI`C~Cé՗íæ«ñ讘o2c-´‹QêÚ ëì»êîÀêí¿éî¾èîÁèîÃèîÁçîÄçîÅèîÅçîÅæîÇæîÈåîÈåíËçîÃèîÁèîÄéî¿êí¼êí½êíÁêí¿ëí¾ãåâèíÈéî¿ëí·ìí´ëì²ëë±ëë±ìê­ìê­íèªíé¬íé«ìê®ëë³ëì´ìì³íë°ëìµìì¶ëí¹ìì·ìëµìí¶ììµëí¸ìì³íê°íë°íê°íé®îè«íê­íé¬îçªîæ©îæªîä§îá¢ìٗ߾zÒ«bɖLÕ¤]åǂëؗïá¢íà¡îߝíߟíڙìוâɀ¥…7Y8Q1aA€\­…3Ö°cßÄuؾvÖ½tØÁyÒµkœw+’s.ˆo4jV$iW&l^/p]3tc9vd9tP¦›wÝÔºäÛÄêàÊêâËéáÊêáÌêãÍ OE¬QD¦C?½TR³\PŸMA{!s q^R RSRp/*m1*YOLOMTZWXVW]R hšS@¤F7¶`V—J9r$a h$r5*ŠNFu51q3'o2)e)!i,#l-(m5,ˆME‰SEl4&‰OFy=6<8|<6r4)[M L + +N + +Z„B5 bZŒ<2—<<–C<°iVªj[£[I=/‹C4…I6]`^\d(g#!d#!Zb'!j.%~A;A6y1.l!r,$q)&fc`bn&q'"P F G O r(&Š9>›CC‘==z*&]S N + Xcq')p,&t3+j$]MG? @ @8 +6 4 +;;@P,c2l0%j/!h.b-G=D"I&K,P2T6V7X8Y8Y8[A Ó¹~îß©íç±îç²Ú½…×¹}ïå¯ëìºëí½éîÀéîÁèîÃèîÅèîÄæîÇèîÅçîÆçîÆçîÆæîÈçîÆçîÇçîÆçîÄçîÄéîÁèîÁéî¿êí½ìë±íè¬ìê¶âåáìë²ìê¯ìê¯ìé¬íé¬íé«ìêªíç¥íè§íç¤íç¡íæ¡íæ¤íç¦íé­íë°îê¯íë°îè¬îê­íë±íì³íì²íë´íë·îê¶ïê²íë¯íé¬íê¬îè¬íé¯îé°îç¬îç«îç­íå«îæ¨îæªîä¦íà ÜÀvÏ©`¹JÉ¡^ßÀyíڔîޛíܜíۙìדçЉԺnnQ;%F-H-W9­…?ÞºoÜÃzÞÇ{ÞÆÊ°h˜y4’s.‰q4lY%iX'n_1sa6te<„uJÞÕºàÕ¼ßÕ¼ãÚÂèàÈêãÍéáÈêáÍéàË´IEËNPÛSTÏNP F4’7)ƒ&"†:/ŽI9€=1j+#NI LMx<<Š27ƒ/-dS + L CL ^q,&t,(k%a#SF +? C< 8 +7 5=83 L \+i3$k7%g3 d/X% 62??#E*E)G+J.K.L.Œk8ðÞ©íä¯íæ´ìê¸ìé¶ìì¼êí¿ëí¼ëí¼éíÁèíÄèîÂçîÆçîÅçîÇçîÆèîÅçîÇæîÈæîÉçîÇæîÈçîÆèíÅçîÇèîÅéîÃëë´íç®îá çåÑéé¿íâžíã›íà›íߗíޕîߙî۔íٔìԌîܕë֍é̓å½tÜ®hÙ§`ׯiÛ¶qÝ·yܵsÔ¨eÜ°kçąíיê֖ìÜ£åˎݸ~ܵræǁäÅ}èÆçƀîהîܛíޛîâ¤îâ¨îä­îæ©îæ«îã§îã¦íà¡íݘäЎ˪f¤z-Á›Qã̃îۚëۛìٖè҉ÛÀu¥‡<<%A(7%6(cCÆ¢]Ú¾rÝÅ|âɈ̲oŒr,~f#€j0jW"kY'oa2sc6wg@–‹eà×½á×¼ßÖ¼äÛÃëâËéàÈêãËêáÌêáÌÎ[]åOZîV`ØDG™3)žM9¶|c±~f¬za¦v_“cMb%_#!SYj21WWK NMLKMY!o3'u1%fL S r5#°fS F>›JAu-j :0”_HMAŠF=‹ICs6&k/*y81{?2‡N=‚H=i'%l+(‰N?¶p=4€?;q40`"H F F +K f ŒC; ZRA:Ž404.‘4.—E:…8&€8-da^`\]]^f'%m,*h'$s3*~E7^!\]]`z1-p'k'k#ZB += + +> + +> + H b0.=5‰74†1/r"W N I C=M_a$UWTH QQT"\*!W(=8 + <n@6c3 ]*e2c/b.`+W&B-7<>">"A&C'C%È­vïÞ¨íå³ìéµëê¶ëë¹êìºëë¸êë´êí¼éîÀèîÄçîÆçîÆæîÆçîÅçîÆçîÅçîÄæîÉæîÇçîÇçîÅéîÅéîÃéîÆëðÂìâ¦æώ޺wϨdÓ»Ì®uÒ YÙ«`Ù¤ZÚª`ت[Ô¢T̛OƐK͗TÓ£ZØ«`Ï¢W¾‘Kº…F¿ƒ=ƍF˘PÔ¤_Π[͟YǕUÏNº‰N¾‹OÁŠH»…D­s0·ƒB̟\̞ZɐKňD½‚>…@ÊEnjG˛VÓ°så̉ïÞ¤ïå§îå¦îá£îà îàŸêڙàʁġU»‘DÒ³ié֑ì؏éԍÝÆz¹TS6<%2#-4_(Ï­hÛ¾uØÁ€ÖÀ~•~U,HN[)"wHAm5!u(nQa!‚C3¨UOŠ.(…43v,'o+$o)$gp*#ŠH;~3+€C6€I<•[LƒM>h1#g,%t75C4’VJ‚@7š\Q€D>f+)N F + +D +H N j""…1*…0*‡/(Š3+•>4“4.3/1!‡A6dT [][[Y[_Xc&!k-#n0(]aU \m##j akr-"K +? +> < ; C f#"}.+Œ55„0)‚00‡75gR O?96> H V VYc&€F7‚O?{J;q@.])L +DJe1)Y%M`-c-e.h/h/g/Q(7++-02L2èÏ¢íß®íå³ìéµëëºêì¼êì¾ìêµìé±éî¾éîÀçîÄæîÅçîÄçîÅèîÄæîÅæîÇæîÇæîÇæîÇçîÆçîÅêîÀëç®éӖá»vўVÑ X°~<À—^©{?¸‰LÕ«eåÄåǂç̉äˉßÅ{Þ½tܽwÞ½|äÃ}ëэíٖë۟ëؘêٚëۛìݝìá¤íâ¤ìߣìߤåΒÜÁ‰ØµzѪiܼ~ÜÀ€ãΎëؚè՘æ΍áÁÖ´s–V²z;šV‹J‘T›c´BΪlçϊíޚîá£îâ£îá¢íݜìܙßȂ»›T Rä̈́éԌá̃˴kxW[9T2S3J.I*‘o-Ë®jʲu· b˜C„p6sa,l\-iW&n`1pa4sc:÷“ÞÔ»à×¾àÖ½æÝÅëãËéáÉêáÉêâÊéáÉÔtfØrhÉ\PÇPI¡<.´aKŠlÀ‰o¸c³€d£nZh'`e)"_$"MQQNMK HKa/)„WH†T@m-S U{9->5”6562†81ku0(?3l$!q.+y4.~7,u3,y;1’bKk8'e'!v:4ŒQO•UOŠHHŽMJ‹NG€D<]SK I +LRw..ˆ1.Š/-‹,(‘80Œ70Š3+72{+ s*{5+d!_!YZYVYWYa#d&"n1)dbadfchr+[@ = +; +? += +F b$|0-ˆ65‰72-,†83w&&o \A:677? HFUg%u7,p5*[ UF C C +B= +E [)j/%i-o3$o3$q6's;'m8'Q"7+% t^;ëÕ¦îà«íæ±ìéµéì»êì¼êìºëë¸éíºèîÂçîÄäîÊåîÇåîÈçîÅåîÉæîÈåîÉæîÈçîÇéî¿ëë·ëߣåÁתcÓ£^ܳvâƉçϑçҗêלå΋ã̃ìԍë֓ì֑îà íá éԎåÆ~êՒíܘîâ¢îç«íê±íê³íé²íê³ìë¶íë·íë·ìì¸ìë¸îéµíé´îç±îã«îã«îå©îæ¬îä©íé°îç¬îæ«îä§îâ¥ëÜ¡æғÙÀÉ«kǧm²K–e&•]$®€>Ò¯hæҒë۞íá¤íß íÞ îߤêؘ˲i¾œSÝÁvâ̄ÚÄyt/^8Y5T2T6Q2W6tWqQfLP7‰q9r]'lZ+m[*m]/ra5|pLÑƦßÖ¼ß×¼áؾæÝÅéáÉêáÉéàÈêâÊêáÊÂ\MÊr`ÙuoÏVM³C5¢H3ŸO8¤_F˜^D{A-[VYVUSRMI J +HF R yL=–lU‰YHF Ep7*—RGšD<;8‘22z,!}5"PA„?5~4'x2%;3x3&c ‡LDŒW@f, e)"¨pcƒNCr.-|<=€E?‚D@l*)M +RT URdŠ63Ž><‹8100Š/'–;3‹.+Š2*‡2&~1!t+z4(e#cg%c%!^[UU]j*,q3-†GBˆB;u'"l gn!q+d#F @ @ ? A ? ? d#%|/2}/0ƒ4/…72„20†32‡15~.4_F > +:8< <9<D I E +B +D +I I C +G L `#_(l."i)n,!o,s1"s1 u/$m/`&Y$D 3¬fìרîÞªíæ²ëéµëë»ëë¹èí¿éí½èî½èîÂæîÆåîÉäîÌæîÉäîËåîÉæîÇæîÇèîÁëì¼ìԕݫg֙W̖Sâ¼yê֛îçµîêµîäªìٜäńܫfΏI̅BÁ~:ǀ;ΓKÕ£Y½€:´k#ą=ŐHÎ¥`à¿zíٜîè­íë¯ìë³ìë´ìë¶ìëµíëµìë¶ìëµíë³íë³íêµíê¶íê¶íè³íêµîéµîé²îê³ìì¶íí¸íê³íê²îå¯íá¨ëã©êܟãˊֺ{βtÓ®j׶qÞăÞŀéюé֖ëݝéؔâφ˫[¹ŽBÔ¶jÜÈ}²ž`?&56"="B(I-E,M1P2V: ”v?s[$iZ(kZ&n`0tb6{nFÙѲàÕ»âؾà×½êáÉèßÇêáÊéàÈêâÊéâÉ°IB¶^TÁcW±KC¨M; L7„*t&^ JPRP Ua%"ZS= +C +T +H C tD0“eN’_KY%L +c&‡A/‡8)¥TIš>41+v*‡?0‘UH8-ˆA0ŠM=n-#h+%y=/ˆKAx:.n-*‚D:s2!t5(|B5‚L=‰P@€A1aI L QN ^z-"…4-@7¢TA1*Ž1+Œ)$›>=Ž3-Œ2$‰D*p%k%!j&'ˆKEp-(n11b QPQm6,‰KHy54~64|*'nmhhTH A C +D +A C ? +Eq/*w)"y)"s't0#„4/‡3836ˆ66//p"#R F @ +< +;:89< ;? > +B KUY_h!h"cgj l&t(x1'}6*s*t+"n$h%f/Õ¸ì×¥îà«íå³ìéµëë¹éí½èí¿éí¼èîÀèîÂçîÄäîËäíÍåîÌåîÉåîÉæîÇèí·ìٖã¼xЕMʊCסZçˋïæ«íâ«éϓá±oΖRÁ{4¿p0ƀ>͓TϕUϕRϟ[×¥bÎF°y7¯v0±{1«v/©m'ªp+¾‚DÔ ]à¾xîܝîå¨îé¬íë°íê¯ìê±íëµíê³ìê³íê³ìì·íê¶íë¸íêµîéµíé¶íé´ìì¹ëí½ììºíé´íê¶îç²îé´îä¯îä©îá¦ìà¤íߣí۟æ͐ØÀ~ЭbЬaήaѨ\Ì¥YȤQ¿ŽC¨{1ؼsλwaG ?#30-+*/3V?‘u>q_(jY'jX$n^/wf9ŠzVÝÓ¸àÖ½âØÀá׿éáÉêâÊêâÊéàÉéáÉêâÊ£C:¢C8›N8C:=1‰9)|+n#j'S +Xb'WP TWVS^%h*d*c2&‹VE‚F-\!K +k-&…;.‚3+:0šC?›?8—B1o q)!|;-l-l+r5)n."u;+t5)o.'v43x85ƒE<{>1†H?ŽSK¢maŽPAl"W K I +M_u%#ˆ8-žNJ­fU©^K˜@7š@7—8,™=8’<3œP=•P?|.%‚<5‘QOq0(k($aP QP O^d!bknlf U M +C A F H G HNSZ w31}5.w*%v*%†K>?E G B CJ +M _f$i$c_ ` fgj!r%w0"‚:-Š@0“S@…L7R3ŒZ;ÝÀ–ëÕ¥îá¬íçµëé¶ëëºéí½éí½éîÀæíÁèîÂçîÅäíÉãíÍäîËäîËæîÅìæ©æÀxæ³mã¶nÝ´læÁxàµnاiÖ¨pÓ¥e¹}=ºw6¨a'±m/Ö¥iëϑìߪîá¨íå¯ìæ­îè°ìÞ¡ë؝ëÛ éٜê؛áʆҳtĕW¹@¾{=¹x:̟^Þ½|ëӏîàŸîåªîé¯íê³íë·íê¶íë·íë·íë¸íë²íé°îê°íë±ìì¹ëì¾ìë¸îê³íé¶îé¯îæªîç¬îå«îæ®îç­îåªîá§íÞ¡ëڜäϊӷmÆ SÚ­`Ы_Ó´g¢p"‰V ¬†CÕÀx‡g&f:_6K'91+(+P?f4l[(iW'lZ*o`/ub7œ‹fáÖ»áÖ¾äÚÂãÚÀçÞÆéáËêßÉëãÍéáÉêâʞP7˜<1žM<¤`Nƒ6#…7,„9'e!OX W a"VWVYR ^ Xl+a$[XI O i)z1#‚4%Œ91“<1§TQFF˜>9t)]$n1$g$m-v7)s5$p1%s1(h&#i('h%%i''{;<ŽOC²yg–^Im+ [XP]dv&'–AA‘=7“D<¡XF·pZ›B;§VJH5ŸA:œE@ŸJEŒ:0€0'L@q*!`ZUUZSWl*s0#ghp)„9(t&kZ ZZV[]`an'(h hu*&|-%u*"4+~*%Š11‰-/Š,-ˆ*)‡)'ƒ)-y)kW S S R + YY ]nr%r*!k#q$r#s%k!ca ggilo"{,$‹@,‡J3™gF«_æǞìÖ¥îà¨íæ±ìè³êëºèí¾éî¾èîÃêí½èîÂåîÈåîÊåíËäîÊçïÆëܞأXÈ~4ϑIÚ¥]ɓIʍH»q2ÜÆ°æéÝçƈڮxççÆçפèіíå±ëíÀëíÀëíÀëíÁêîÂëí¿ëí¿ìì½ìí¿ìì¼ìî¾íìºìç´íá¨çҗկr¯u:¶€AđKƓS˞bÓ±såʍìٚïå¨îç°îë¹íë¶ìë·íë¸íë¸íê·íì¹ìí½ìì¾íê¶íê·íêµîç±îç±îæ¯îå®îå«îè®îè®îä©íá¥íà£ìߢì۝êٖìܙäáÌäéÜÒ¶išk ‘]Ä¥`šƒBj?{G €IF^3G(68%ZGta0q_5m]2l[0td8wgA¯ ‚ßÕ¸â×½äØÂåÜÄêáÉéàÈèàÈèßÇëãËêâÊ¡X?Ž7+•E8¥aQB35$‚8,g(Qbs)#p#$_V[]Rf'%o/-dV^k#k(x,}2'…6/Š9*“=0•;3§PL§SP™83|3)Y'f)j&o(u5%„D5w60x93m5&k3'e*!g&n((y/(w4(d!X `ff„>2ˆ:/y•5:”;<•>7žL@°`P G3¯fS•F+‘7/–97‘3-‹+(€$ƒ8.o'`^SR[ZQ +Z[]f„:/Š=0Œ>/ƒ/$~.#y+k"m(jebl!!l#q)#k!mq$v(v&>6‚/'30”6:“55Ž.///53‡)-…('€pjmx"#{"|'&}(#†/$Š8/„0)‚)'|%{%^ Vg!d hhkip 5#|3“Q<ªsQâƔìÕ¥îÞ§îä®ìê·êì»éì¼êíÀêî½èî½éî¿çîÄæîÅèïÀëë±èɈӛT²Z¯P ªO¦R¦_·z6à¸}éá±ãåçìë»ìèµéêÊëëÂëîÅêîÄêîÂêíÂéîÂêîÃëíÁêíÂëîÁëí¿êíÁêí¿ëíÀëí¿ëí¿ìì¼ìê¸ìã¬æԖèԖëՙãljӮrØW¼‰L»ŒMÍ£eäŌíÞ©îæ­íê·íê¸íë¹íë¸íë·ìì¹íê·íë¸îê¶îè³îæ°îç±îå°îä®îæ­îå­îç®îæ«îåªíá¦îá¤îã©íå§íë¯æëÉãæÕìâ£Õ»q®ˆ= z3œƒ?V4pB xC}D…Ni5R1D.gU&r`.n`1o_5o`2sa4q^5Á´šàÕ»â׿âØÀæÝÃéàÉëãÊéáÊëâÊêâÊéáÉ£_G„9"ˆ;%„;+€5"x, z/&k&bk"w-.t)'j!ar.-l,$o,)‚<9ŽK>ŒJ7|>&<(†’u1L1\2c7j< o: l; +Z2M4 +ta5uc3tb4r_4sb5ue7wd9ΨâؼáÖ½ãÚÃæÝÄèàÇêáÊëãÎéàÉêãËêâˑM6…E2d u%|/"q!t#jd h!{20n(n!o#|21s**v.)…>8WE£ePœ\G’I8Œ<+†4$–J6£MG¢S@•A2‘<6’<0D< F;‹4+‹:1~2(l n!s't&z) <,D0‡5&v( `Q M M + In0+ºƒqµ€l—[K¦aQ˜75™>5›@7 C6—6/™94œ8/¬YLµdU­aN³_Q¤Q? L<—?2•A3–F7—F;˜E@Œ2.Š11‰74~,"|("~%‰41AAœIO¦TP›B@‹%$‹#Ž..£KC¨YGI=‰2(*(†01‰:/…97ifgj nr"oy"~':1™F58+/+Ž-,ˆ'%--/.‹+)ˆ*'Š-*0-Œ/+‡*'Š-)†,+†,)…*)†-*‹4,ˆ3%’7,‰2"€*V Objq!t&q# t! s%w.m* ‘T+⿈êӘîÛ¢îã¬íè®ëëµêì¹èí½êí½ëë¶ìå§ìٕà®eÅ{9ŸF +¢S¿‚>Û³wéΓìÞ£ìè±êîÁéîÄèîÅèîÈçîÉèîÉèîÉêîÆéîÈéîÇéîÇéîÅêîÄéîÃéîÂéîÅéîÃéîÄêíÂëîÁêîÂêîÂëíÁìí¿ëîÀëì¼ëí¼ììºíì¹ììºíê·íë¸íê·îé²îä©êלßƉŜ]¶…F˚Z×­käŅíߤíé±îé´íêµîç²îæ°îå¯îæ¯îå¯îä®îã«îæªîä«îä¬îè¯îè«íä¦íà¡íà¤îã¤íè¬æçÓâä×íé¨ëܗÝ˂ÔÀ{š~?T: +Q.`3e8h5 `7 b>V7 t_1qa/uc7p^2tc5wf;zi=ÝеáÖ¾äØÀáØÁãÚÁâØÀåÜÄêáÊêâÍêâÍêâ̈?#y4%q/%n!x( mb]U J€>1m&|2%w0%}5+|8.{/.Œ<:©jV©oV¥gO¨cJA/@+¢YE²ia›L>’<(–@6šK?’9/˜@6“<1”>5;3Ž:)~)w$x#{"„*~*iTI L + L LL + +I<{@0[ +f!¡WA›6/˜<6§[J¨UCœA2–5*˜0%²[I«UH¤K=›>1§HE¦NDœK;—?6—?:–=9’:642“7872‹5.Ž2/”:3œ@;’;:Ž03).*%‰("Ž)'/,>6žB:™A8›D7‰+,53Œ;0‡:1z0)t**m""m!!hnnu# }&“51ªZJ¡UEŽ4#3-‹/)3+Œ,+Š-'‰-%‰,%‹-)ˆ-"‹.(Ž0.Ž45†-)‡0&–<2•=2—C2”;.‘9+7&{5x@B$n& n&u)x.{1o*i* c*‹V,Þ½‚éϖîÜ¢îâ¬ìè²ìê´ëì¸êí»ëì»íӑæ»qїR¤T—@žQÔ£dë՘íë»êíÃéîÂèîÅèîÈæîÉèîÈçîÉçîÊèîÈèîÈèîÈèîÉêîÆèîÇéîÆéîÆéîÇêîÃêîÂéîÃéîÄêîÂëíÀëíÁêíÁëí¿ëíÀëíÀëì½ìì»ìì»ììºììºìë¹ìí»ììºìë¹íë¶îè°íå¯ëà¦àˎѱwɛ[ƖTÍ£`ãʊîà¦îä¨îå­îä­îä®îä­îä­îä®îå¯îå«îåªîä©îåªîè®îç­îã¦îâ¦îå§åíÇãäØåêÍíàžéٛâϏÜʄƯkcLB&d;d;g= gAnBhF€j5q`/td5tb5tc5td7‰xLÝѱàÕ¼ãÙÁá×¾áØÀãÙÁæÝÅåÜÄëãÎëãÌêâÍ|2j!i$j l[B 3 /R(„L>k(u.t,$ƒ=6ŽJ;„60–A:«bL­oW§cS TBR@¥`I­eSšH>‘=3•A8«ZM‘B3”<3—C<•>4©WKžK:ž@7œC>9)†0'|$…/"r +`O K W\YYz;0z4,v("x-#ŸQ;•5)•6.±dMƂe·fNœ<-›5"“+%*%‘/+•/*˜21’4/•<1¢NB¢RLšB6’56‘98•:8++,$™3:B=˜C7¦UK£OF¦ZP¤\U~5,z* o&b"b!]#l&‚:.…0(ƒ1(~/&x)"v(!v+'o"o%emq$~*ˆ3+ªaK°qX¥_E QB—<4/#Œ-)1'1)Ž0'Š,#Ž0&2(Ž0&‰(#“5.™@0C2ŸE6¡L:S=†9$„6 €8!i+}I(K$L%|E$‰T.W+‰V*ˆ^3˜k7¤x@Õ³xäʔîÙ¡îáªíæ²ìé³ëë¸ëì¸êՒڡZÂz9¢I’:§c!Ö©nîߪêðÄéîÄèîÅèîÆçîÉçîÊèîÊçîÉæîÌçîÊçîÊéîÈèîÉèîÉçîÉèîÈèîÈéîÇéîÇêíÄéîÄéîÄéîÄêíÁêíÂëíÀêîÂëíÀëí¿ëí¿ìì¾ìí»ììºììºìíºíì¹íë¸ìì¹ìì¹íë·îéµíè´îé³îä¬îã¨ç֙àɌֹyÓ±mÞ½væˆê֗ìÜ¡îá«îå«îä®îä­îå«îæ¬îã©îä©îåªîè­îé¯îã¥îã¨ìé«ââíããâäéÍëܚéٚâώÝʋÕ€†o2=!S0W1W0T/^: kQtCqa4td5r_5ve7rb6ŸdâÖ´àÖ¼âÚÀâÙÁãÚÂäÛÃåÜÄåÜÃçßÈêáÌëãÎieX P D ,& *9\.ˆG;w2*t,#w0€6+J8ŽG6›LDŸG:“H7”G:–D>žJ@¬`N¥[J˜I6˜E6žJ?œG5?,˜F;”A7–?3¦SD®_JŸE9™0,)ƒ%†+%‹1+ƒ)‚5#u'm}-&…4/”JAž^PŒG@‰<6”D8—E6•A-•<2—9, H9²^M³\G´[I¥G.œ=+.,1$1(‡*"˜=9­^S·ia–<,–<4ª[Tºn_ŸI@¨PI¹je­[WŽ;3‚?:f$YL= 764446Qr&#v"t$#v$#lq#q#t&hgky%ƒ1 ¬`C¸}\µyY«fH›F54(’4)1%4(2'‡+‰-!‰-!„'•71¤E7žI3¡J8šK7D4e([ +[c`$d:yL!‹]0Š[/’e3‘f3›rD–rA’l4l1Ϋoàćíٞíà¨íä¬íæ¯íè°ïâ¢Þ¢W³f™I4­bã·sîå©ëí½èîÅçîÇçîÇçîÈçîÇèîÊæîËèîÉèîÉçîÉèîÊçîÊèîÈçîÊçîËéîÇèîÇéîÈéîÆéîÇêîÂéîÃêîÄêîÂëîÀëíÀëíÀëí¿ìì½ìí¾ëì¾ììºììºíì¹ìë¹íë¸íë¸ìë¹íë·íë·íê¶íë³íé²îé³îç­îç¬îæªîà£èԒãƂӬd¸ŒHÁ¡báʉîá©îä±îá¬îâ«îä®îâ«îä«îä©îå©îç­îä§íã¥íê¬ãäåãäÖãçÐëá£ç֔àΊÝʍá؂FC-N5Z=W8X9Q7kV)‚n=we2r`4r`3n]/vc8¬yãÖ»âÙ¾ÞÕ»ãÚÂäÚÂãÙÀåÜÄåÜÅåÜÅéáËêâËw0c 9 *+4=C <E Y#v@2F<˜YCŽN:‚<2L=UK<+—@-?0–@8•>1œG;©^M©^M¢PB I<šE1«`Q¥XJ™F=—F7ŸM?œIA¤NA<.‹*"‰)‹1"ˆ*#0$–E1”E6~'…)#Š*(’33ODž^LV@–G;‘=.–;,œD:š<4™B7 M;§R<¯[F­U@¨N6¥M5š>/š<)œ<(™@,¶kWÁugªUD¢P;®_L¸m[¦[KD6ˆB9r-)U?632226 6 2:>@ H +Vk#(ba# {31okof_ k y',¢P@¶wY¸~]¹|\°rV§\J7'‘7(6*Š1"‡/"‡-&‡+!‰& D?ŸD3šD1{+d L JUVV\% U( +„X(‹a1”g6”f2–m7f3g2‚^'pR½šdÞÀ€ëҔîݦíã¬îã«îè¬åÂz½s*”?†1®eà¹qíåªêî¾éîÁéîÅçîÇçîÈçîÇçîËçîËçîÊæîÌèîÉçîËçîÊæîÌçîËæîÍçîËéîÈèîÈèîÇèîÈéîÇéîÇêîÄëíÁêîÁëîÀìí¿ëí¾ëí¿ìí½ìì½ìí¾íë¸ìí»íë¸íë¸íì¹íê·ììºíë¸íê¶îé´íé³îé³íé°îè¯îç®îæ¬îä«îä©íÞ¡âdž°‚>€H ºŒFæϋíà£îãªîâ¨îâ¤íâ§íá©íá¥îä§îã§îã¥îä¦îå§ìë¯åì¿êí³íښåґÜɆáБÝ̎«•`N9gXwd%^HL2W< qZ/vd7r`2ra4tb6tc5vc9¿´’áÖ¼áÖ¼áØ¿äÛÂãÚÂåÜÄæÜÆäÛÆåÛÆêâÌêáÍSD88R'V- S( S.O,K' ^8 žvX©ya nVœjN†?5´oh™RBˆ:)™B4šI9”@7“@/žL:¦ZC­cN«bP¨]O¨`H›N>œH>£RA¡WC¡T>•?5§VG­TF˜8-“8'”8)’5,4-‘8*5*Œ3*†,*…%%‹(&“>1–F>¡MBšA4”?-•B2G:¬\M¦\HžL9žK9¢Q9 M5§Q9£P8š@4«PA¨D;Ÿ=5¥XF›MBŒ4$œWAŒD7y* l]I E B ;8878 858 +5 7 D D +I N ZX1Rq.!x**q#o"giq p A0±qS·€]¹~]±wV³sXšR:‰9(5)Š4'‹3*Š1%Œ-!•6+—A5‡?$s+X GIIWU`!Z(L^1’f3”h4’e3™n8–l7‘k3Ša)‰d.¨ƒKÙµuäȇí؞îߦíã«êחʐI=~+›Tݳlìã£ìí½éîÃèîÃéîÅèîÆçîÈæîÉçîÉçîËæîÌçîÊçîÊçîÌæîÍåîÏåîÎæîÎæîÎèîËèîÉéîÇêîÆéîÆêîÄëíÂêîÁêîÁëí¾ëíÀìí¾ìì¼íì»ìì½ììºíì»ììºíë¸ìì¹íê¶íë¸íê·îêµîë²íë´îè¯íé±íè¯îæ­îè®íç¯îæ­îå«îãªíÝ¡ÙÄ e½šWÙ¿yçҏë۝îà£íß¡îá¥îá¥íâ¤îã¥îä§îã¤íà¢îä¥îå¦ìë°îé¨ìڙâΏÜʈàΏÞ͎¬–^”;:.#•<,£R;œH8š@6Œ59#£P=®\@¨M4®UC§P=˜=.”6/Š'$~"tY +^c]` _[N QOC ; ;8 < ; 9 88 +; +@ C F G Uc3 +" :{4)z. t&t'u)m n!}-‹@&›R6›N3O5«eJ§cG?)4&‹2&Š3)Š0&‘8+—>3q.@8:9;=FOSHT+PŠ\#_)”k8•j/”h/—k1˜l,—k0¥{<Ê©dßÁ|êѓîÚ îݢߺvNx&‚5»‰Eëܞëì¼êîÁéíÀèîÀèîÂèîÆèîÇçîÉæîÉæîËèîÊçîÊæîÌæîÎåîÎäîÐãíÓåîÎäíÑåîÏèîÊèîÈèîÈêîÅêíÁêîÁìí¾ìì¾ëí¿ìì½ìì»íë¸íë¼íëºíë¹íë·íê·íë¸îêµîé´íê¶îé³íêµíé³íé°îç®îæ­îæ­íç®îæ­îç®îå©îå¬îã¨îä¨íÞ¡åѓãϏÞDŽҹtÔ¸sçғìݟîá¤îä§îä¦îä¦íä§îá£íà¡îâ¤îâ£îå¦íߞéؗß΍ÜʉÝ̏ßΐš†L1!A(X2X0[/bCta3p_2ta6ud8q`2q_2s`5—ŒjÜÓ´áؽà׿ãÚÅåÜÆãÚÄãÚÄçÞÉêáÌëâÍêâÍS) X1Y.c6f8e:h9wI(€S2‡^>¶’wzQ7ŠZ=–`?¥eQ’?:;3—G<¥[J¨YB£Q>¢P?–E6@27#•8'•>2›F6—F3“?3‘=&•>(˜B.¢I5¤S=³nU¿~g²mQŒ@%”7.”?(›H2Ž4(›A6“8,‘7' PC‰6)Ž7-˜D:›I;Ž1-‘6&9%‹6#”:5•?,”A.•H3ˆ<*~-ƒ1Œ<&—D/—9/Š+$ƒ1)@1 H +]aY Y U WL C ;> ? ? = ; >@ B? @ @ H +g%{/,@ $ +% ? `(„;1‡9,‚7)x(x'z(|*~,~),<(“C-’;,‘:.‘9,:*•@4˜G2€5'A156615:L#V)e=mFpGwL|Qˆ_*–l3•j/”j2–i.o1›o/¸“RÓ±mìϑî֛ïٛ·ŠFn'q(ž_âńíé¸êí¿êîÂéîÃéîÃèíÃèîÅèîÇçîÈæîÊæîÊæîÌçîËæîÌåîÏäíÑäíÒäìØãìÙäìÕãíÖãíÔäíÑçîÌéîÇêîÄêîÃëí¿ìí¾íì¼íê¹íç°îè°îê¸îë¹îé·îé¶îè±îè²îè±îç³îé³îç²îæ±îç°îç­îè¯îæ­îè¯îä«îæ­îå¬îæ«îä¨îå©îå«îãªîà¥îà¥éٙ׾{³ŠAšYáʆîݞîã¥îã¥îä¦íà¢íà ìݝíߟíß íݞéؔäӐßˋß͌Ý̎Üʎ‘{H-/>(C&H,aG{i8we6sa3sb3r`4sa0p_2vi>ȼœáؾâØÀâÙÃãÙÃãÚÃæÝÆæÜÅëâÍêâÍêâÍi;[2U.N)R)M*]6oE#sE$…Z:¡ƒ^c>sB„E"”I2G8ŽG:–H;D-‹1$‰4'‘4%’6)˜E3’8$—<)¨ZJ¬^TœQ?¨`NžN7 L8—E0žK3ªR>¡L6¤W@ŸZCx.l„1 §S=›J8“F1VG’J?­dR¢YE˜D;’:2 K?¤ZG²jQ¯gOªbI”H=q"^\XVU` l%y,ƒ0}%u$2 0 >IPRXSH @ +B B A ? ? RYOFI +[ k*x2"p+>% +))5u4&”J<C8†2)/€/"{+v'u& {)})ˆ3"‡0’@*Œ@+’@,D3{< T ;6;=9?I# S1 ^5 j?qGqHqJsJsFnC qJ}V‡^"Ša$ˆ`"Œbœs3Ä¡[âăìҔçϒŠ\#Ux0ƝZíß©ìë»ëí¾éíÂèîÅèîÃèîÄèîÅèîÆèîÆæîÊèîÉçîÊçîÊæîÍãíÑäíÒãëØãìØãìØãì×äêÜãëÚãìÖåîÏéïÅêëºíæ³ëÞ¤íÞ¤êԖâĂßÁ‡Ý½}ß¿}àĆâāçʋæɌéΐèѕê՛é֜ëٝîà¡îߢíã¦îâ¦îâ§îä®îå¯îä©îç¬îä¨îã¨îãªîâ¨îâ§îá¨îã©íà¤é؜ʮn¨x5Ê XêӐíܞíß¡ìݟìܞëۚìޞëܛêٔç֕çՔâѐÜˊÝ̋ÛʊÓÍ|f6''05!8$`L ud3ud5s`4tb4xe9sc6vd9tb4hÝÔ¹âÙÀäÛÆäÛÄãÚÄæÞÈéâÍêáÍëãÍëãÎj?#`8]3_3[5 Y0a;]5P,yU.`@L)kBvD"t=r< ”^D„9.Œ:&Œ/Ž4&›C8•A7•?0–A4’>2’>3“A-¡RB¢UD¨YB®[H«S?¡D7š3'™3(ŸC9†2+Y3Q ”C.…9•\<Ɩ|¿{·za¯lNªaL¨XJ±bPL7ˆ@,‚6(x,"a \ XXUP TY\ +^ f!r(v: +  " ) 0I +Ze"^RVNNrA.}E3v9%n7'm2%j'k&s)€@(e- + *< ?E+h/e-y6 9!…:5‡;+70‰;#>&‹7 ™U;‘V9|? _+ MF??L$X- a3 ^1 \1`9 b9d: pHqHoJwQyPpG nHuN}T}UyR|V{Vž|>Ô³xåȎ޿pE MŠR åɑíè·ìë¹ëí»ëí»éîÂêìÁèîÄèîÄçîÅèîÅéîÅèîÇèîÅçîÈæîÍæîÍäìÔåíÓãíÖäì×ãëÚãëÚæëÈìç¸ìØ¢æƈߵuÝ©lҗ\¿ˆH¿ƒF²p3¯t0°u5µx5³x5¸{9ÆDÁ‡G¼‚EÀ‡JČJƒPϗTʗSΧaѱjáăæ͈é՗íÞ£íÜ¢îã¤íâ£îá¥íß¡îâ¥îâ¦îß¡îá¤íÞ¡íÝ¡åҕͯkË©aâǀê֖íܞì۝ëښì۝êؘéחè֔ãҐâёßΎÚɇÜˊÛɎ̷ƒmS )+218%eR'pa/o_4r`3ue7xhU4 S1 S2 U2S/V.e:|B-Š='8"–H1˜G0§]G˜H1žL5–G5~-$“@+šM6¡P<K6£R>£R>›>5 ?8¦K?˜@1|#2 $ >S9@yL.¤wT¥rV‹O2ŽK4z1!l$g i dY W TX[ [ [ [XY[ W\ +t)A   ' +% ,'5I Zg'z4%t,#k#s,›dD›^G•M8TFŠ>&|0#ƒ5*‘?/w:%> 28C$ c0I! +49OS& ^-n1r4s3†B%y9j0r9!`1U' Z. d5^1`6f9j;k=o@o=rBq?sCzHyL yLzLƒY}SxO{Q{R{Q}U}V|VsJ +{W½™_à‚ϭhZ4U&·ŒRí؜îè´ìê·ëí»ìì¹êíÁéîÂêíÂèîÅèîÄèîÅèîÅéîÅéîÈèîÉæîÌåîÎäíÏãíÓæîÍèíÉéæ´ì՞äµ|ɌQƈPҖ[סgÙ§pÙ§nÔ¨rͤfΤgÒ­lάkϯtÔ®nÖ±qØ´tÔ¯nЧdÏ¢dțXǚbőY¶y8¥m+±u6²q0­x1¿ŠFÍ¥dÜ¿yáʆêՓíÜ¡íß îß îÞ¢îߢîâ£íߢíÞ ì۝éՖãёèЊéԔèԕëؗëזé֙ê֘æԓæԓäҐáБÜʋÙȆÙljÖņµŸeP; /8; : =&p]3m_.m\1sb4uc5td8tc8vc:ua7WÙдâÙÂãÙÄäÛÆæÞÉæÝÈéáËéáËêâÎéâÍV6U6T2L*P1K,Q0 _;^8X6 W5V3V4X6Y7W3b7`2\%W d-t8z9$†:"9 ‚0"„4"‡6%ƒ3)|, },w r"~0“@&¥V>ŽB)Z . )JY"[$ 9:FFCBLP +W[ XTRd f_ ajo*j+ ^^\Xp*M ( D Q\+P$ +<<LR NQc%{6)€=/„B*£[BšR5•B-”D.’E(Œ?-‡?.m)NP& I"D$? 9?"A&E$-*/2:F#@E M$L$N' +V,S) Z1b7o?!n@uH#wJ&wGr@rAyJ!~N$€P"„S(O"Q O!‡X"•e%•h(’f&”g*…Xˆ\‡]†[ƒ[XvO œu2Í©g˪fg9 +vD×¹€ïà¦îå°íé´íë·ëë¼ëí»êí¼êí¿êí¿éîÂéíÂèîÂéîÄéîÄèîÈçîÊçîËèïËëé¹î٘å¹xؗXÇ~Cђ\åÑ£ëáºëäºëêÅíè½ìéºíæ¶ìâ¯íâ«íá¬íà«íâªîâ¬îá¦ìߧíà¦íÞ¤ìÛ¡éٜè؝ãϖÝĄմvË£cƜ[¸L°€A§r2­v.¸€;NЪkâÂ}êюìڜìܝí۝ìޞìܟì۝îÝ êؙêזé՗âЎáɆéӑê֙äҎæԔäӑàΌß͋×ƄÕ€Ô‚ҿ„ŽzC0%*>"B$@&N6vc=m^.l]0yg:wf8wh/8\- b,Y%LLN@647<@? FS[ f k#jm z/…<ˆG'v,u#p q"€0&R/ R" ^#a&a)]'^(Y%W" T Y [!We(n/€:{9€;I&‰I ‚C{>{?€H!ƒK!~Eh7a3 U/ R. H&?0@' 8<#B(I, I- H- K/ K+ K+ M/ Q1 Y5_7mDpD tH#xI&yL$wHzH}Q'€U(€U%„V$~P‚T …X"Ža%–e&™i)˜j-žq5›o6žq2—j+•j,”h)c$ƒ\…ZµKâa‘f-­…IäΏîÝ¥îä±îçµíê¶ìê»ëì»ììºêí¾ëíÃëíÀìë·êí½êíÁêîÀêîÃëìÀìç±îВä®jϐHՔOá±uìä·äéßããíãâîããíãèáèíÔêîÉëîÃíì¼îê¹íê¸îé¶îç²îæ°îç°îä­îæ¬îæ«îâ§îãªîã©îä­ïá©ìݦìܟç֛ãϔàȉԶrÅ \­…<©s-¦n%³z5ǏIÓ¬dÞŃé՗ëڛì۝ì۟ì۟êٛêٚéחãώжkâÅãЈåӑäӔáΌáΌÕÀÔāп|ν}¼§o`L&*E*I)F(X@s`9iZ.m\/p_1td6xi>vh9{j?}kG¢•xÙиà׿áÙÃâÚÄåÝÇãÜÆäÝÇçßÊêâÍêäÏU9Z<U7S5N1 +V6O1 O4 S4 X5 [8W6 U3 +U2 \9[2W2T/Y2]5c9e:a5f5g3d'yA&p;i&m'b Z \ t$t(‡D7N 54_3uB wD&v@"n6s6h-^$MEGKLMN Ta&o+y/z-z*†;&šR3 _@Š;…&"„*z%MR|?v9t5o0 k1 f- h/ i/ i2\)[%^+i4`(g. f. k4zF€P ~P#X+’X,R$R$ŠM#…K ‚Gv@sAnBe<[9W3 +W3 L- +G,G+H-I0 +E*G-H.I.M2T4T5 T8 X6Z7kCmGzO)tL$wO#{Q{P }R"ƒU‡Z&Š`#’i-–i*d#—k.œl1p8›j)žq2žr3r2˜n-—l.b%f(º˜^ÁžbϲsæϒîÚ îà©íã­íç²íé¹ìë¼ìë¼ëì¾ëëÀêԘãºwíґëå¬êîºìê·ìۚå¶iՎCْJä¸uîÛ ëîÅããìããîããäããéããëåëÙéíÎëë¿ìæ³îç°íãªíäªïæ«îä¨îå­îå¬îå­îç­îäªîæ­îå«îã©îä©îä«îä©íâ§îâ§íߤíߥêٛåԕßʊѸuɪf¿˜U±}7¨n'®€?ʟ_ؾwâΌë؟ê؛éחéטèՕåҒвlǞVÜāáВßΑÜˊÖŃÒÁνyͺ}Á¬r•AV@ 2#4K.V2 N0 _Gp_1k]-o_1sa5tb4wg;zj;‡wO¯¤„ÙÏ´ßÖ½à׿áØÂáÚÄâÚÅãÛÅâÚÆæßËçàËéáÍkJaC Y< +V: U4Y;Q2 T6 Z5 +lBcCU:R0 S1 W5T1U5U7S0 T1b7c5d9g7_,Z'^.^,j1g+g(b# k"Š>2ŽF9Z#69Ap<|F$ƒK(ŠL(†K A~>x9r:n6h2 f/ _( Z_$ V ]!d$ h*h+ k-p/q0q0f% d%a# f$e"a&x9‰BŽF!ŒE‰B‡C‹I‰E‡G„Dq4 b+[*_+f2b1f6 e6 b4 W,^3d6 +l<}GK‚L†P&‚M„K {I}L |GvBoAoDpG#lE d;a5X6Z4 [5 Q6O3U7Y7 U8 O5S:P2 [;Z8a=c=iCnF{S Y'†^#Ša)Žf-”k1˜j,—k*—l1šj.–i*›n, s3˜l*›p.Ÿt2šn-’e ƒY›u;½ _Õ»€çˎìמíݧîâ¬îæ±íç·ìêºíëºìë¸íê·çˎΚTÙ§]ë̃îّéÌ}ܪWΈ4â¯dë΋ìç®ëíÂéîÍãëÛäçàãçáæêÔéß°åØ©Ú¸}Ø®pȞ_˜]É ^ʦhÑ·uÝÃ}è̎è֘ìÞ¡îá¥îå¬îå©îã¬îå¬îãªîä«îå¬îã¨îâ§íà¥îá¦íà¦íߣëܟé؟æԗß΍϶w¿šS¦s6œe%¦u1º”LÑ´qÞʊåӓæՕèԕéؖÙÅ°ˆ<À¡_×ŌÕŅԿ|Ò¿~ϼ{ɵyÀ¬l¬—ZsVŠm5@'9"O/W7Z@iR#jZ*iZ+l[.q`/we5vh4“XÒÆ£ÞÓµÝÔºàÖ½ßÖ½à׿ãÚÃáÙÃáÙÄáÚÅäÜÉæßÉéáΉ\!€Yƒ`&ˆa'…ZvJpJ^<Z8 oG!gF[>Z8a@U5N.N5Q6[9\<h?j?k@l@_5 X,[.V) +a/ a.e/m4s4|='\'7 7 ;I j:h9yF%G%~C~D}E‚F{<}:€?€A}>€Aq2f- a&_%_&V U$JLT$QMQ!`(]$]'g0 p6}B‡KŠKŽNŽMMŽM’Q’R ‡G~DzCw@o< m;c3b5\1X.Y,]2 \0Y2U1]5`9mAuF{K$…T,‰V(€N~N#ŠX.„S*~M!€Q!}O~Q%vJmFnIoKf>b@T4V8_?Y8R3 +X8 `>^>fCpJsLnHtM‰b1‚^*d+Žd)Žd,a(Ša)“e+–p3“m,g$–k*–k+h'‹f#d'§ƒCΫlàÀ‚éҘìØ î߬îã±îå´íè¸íé·ìë·íê¶îâ«éՙéχçÉzà³dۜHˀ)֔?çÌ{îá¡íä«êߣê֜è̋åÀÛ«kȉLÚpæÕ­Q|5q.x4s8 {> …P—e'±v:»‰Iȝ]Ú³pæʈéՖêۜîâ¬îã­íá©îâªîá©îã«íà¤íà¤íߣíÞ£íߣìÝ¡ê۟êٞé؛ÚȊҴv»—\¢o.ŒYc#°IØ‚âюçՕé֘ãЎ¼ V¦‰HÁ®rκ|ѺvȳqdzpÀªt°ša€j.vZ&‹s;:$V5\6_>kNva-m['hY'm]+sa0ve6ylA‘mÛÒ°ÞÖ¹à×½ßÖ¼áØ¿àÙÁàÙÁáØÂãÚÅäÜÇæÞËäÜÇçà˕e$‡Z’`#Ž_!h(c%Žb(“e0ˆ^(Z&~V#xR"hB[9 U5_BkI gC[9 `=b:h@oEtIrGp@m?j?i8h6e1c1Z( O;6BGT.j@i>l@vD"sD`5c6zE‹O#ŠG!†D…C†F~@|@|AƒH „C|>w9f-^+N!S$U%R%X) X*P"OW+X-].e3p9 ‚E‰O‡OQR”U!–T•T#ˆL‡N†N~H|HvCg7b3`.[6 Q/N,I+T/Z3`8 +j=k9c;b; +qAuH‰X'ƒS†V'ˆU'Š[(ŒY'}P„W$…Z*ƒZ'S#xNoImFuMc? `@cBbA_?kIlIlGfDdB nIoHqKxQY#yR{UŠa*“l0g*f&“k*h'Žg&e%…^Šb"´ŽPÒ±vàȈéѓì× îݧîã¯îå¯íç®íé³íê´íé²îç°íݛߺfʊ;Áx$¹k Ä|"اSÚ¯f×£]ʖLą>¹o1³f&¨Y›SµPàÐ|< u4 +f.Z+X%_%c#`#i(w3‰C–W­r4»ŒGȤ\Ý¿äЍìڛëܞìÞ¤íݦíÞ§íߥíߣìÜ ìÝ¡ìÜ¡ëÜ¡ìÛ ê؟è֟ãӒÚȇеt§ŠDmA lA¦„DÕĉáӛäҖÝɈ͸s§ŠHœ‚=¶ aɳ{Ä°o¹¥h¬’X’zES7 y`0\GD+fAmEiEqQ#q[,iU#m[*n\(rb/uf8zkG°¤‚ßÔ¹ÞÕºÞÕ¼ÞÔ»âÙÁãÙÃáÙÁßÕ¿âÙÃâÙÃçÞÉåÜÇæÝȺ‘L±ŒG¢{;e+‹e%Šc&a&“f+–i,“l.žq<uC•k6ˆ`){V$uP}S&qJ^@dAqHlBrKnGg=j<oDoEwJ}KsCi?g:f9_6W1[1 +U-Q+Z1 g=l@i9c9c:f7yFxC…J#€HzEyEzB~D‹LŠO!ŽNŽOŽN ˆH‹KDyAs;e1^*Q"KD;!@&H(K,O-Y2]3d9 +t> u> ~I†N‹PˆOŠTƒM€J~HJ|HK{Ek=_9W0V/Z2]6f= n>f: [1V+W/`7 a;]4lB|K|L‰X#‹[-Ž_,Œ[*ŠX(…U!Q…Y#…Y(U#wLvMvKnIgB dA b@_= gEuSjHkGnIsOsLlB sL W„[ƒZ‡]•j)‘j)Žg&Œe#Žf&h'’k1¸•\ϱpáĄæΐíØ¡îÛ îáªîä§íç­îæ­îåªîß âÂrLj6¼iªV ­\ ¬[ +®`¯a«[ «\¯eºx<ƑRÕ©kÖ²vÒ®x̦u˦pÄ h³–\®ŠUª†TŸyAŸo:c%‡V„N@ ‚B~3€9‘O ¨eºˆ?Ыg×¼uäБè֖éٛê۟ìÛ£ëÜ ëÛ ê۞éٜêڞéؚè؛æԗàΎßώ̵q‘umCf@f>d9 a7 Y1\6 ]4 +a6 c7 _4 Z2 Z3 +X-]-r? ~D€G†P“S!—W&–U!–RœW œU—V—W!“U ”WY*ƒJv@d8X,W/Q*E$DGL'IG!M%Q%Y1b4b5f8sA +~IOŒX"V ‡RƒO†SNsD sFi=h> +j: h; ]2Z.[0[0]6 +^5a8 d; d;i< m@wJ‚T‚S„V…U‡X †U!…T †U!„S R!†W#xJtJqHkC qJtOyR|UvRySqI gC oNwRxSxS ~X[‚Zˆa‹b$e'‹d"|X|[µ“PÓ´v݃å͏ìՖî۞îá£îãªîä«íޜãÀuȍ<¯a¥K›B H—N¦b·t%ō=Ф_سsã̎êØ ìÞ§íá¬íá­îà®ëݨìÝ©çÔ¢èԞâ̖ÜɐÞǐԽ‚ηyȬi¡]º˜V¥y0 f(ŽM J‘H¡\¶u-ēKѨ`Û¼wâʆáΐãҔéכé؜é؞ç֚æՙç՛åԘàϏßώÚƇ¹¤k~d$~d&µž\нʵ{ʶxDZr¸¥eŒl-j/¢OŸ‹R‚j5L<+2%C.d= yJyIzM`5u^0mZ,hW&hW'lY)p_1vd7zm?ËÁšàÕ·ÜÔ´ßÖ½âØÀâÚÁâÙÁãÙÁäÛÇâÙÁáØÂãÙÅãÙÈâÙÃÁ—KƝW̤^Ï«lÑ°lÒ²kØ»sÚ»xѬfƟY½˜Q´’Nª†Cžr.—e#^#˜g(¤q/¤r6¢p3Ÿl.šh'‘b ŠY„X|ReB iC f> +nFrHj=nC}RwLpGoHrItKmFmFi@a: X3 W4 +Y3 W2U0L+B%M.\4 +h;e4 +l=vFv@ r={Bw@‰M’R ’V%—\)d- h2Ÿf5¤g8Ÿ`+—W‘S‘TTIr9p=p> +k=^3c8b5b8i; +c3Z-_3k: q?yG…O‰R…OV‹UƒOKyGvBvEyHxFsCj; `4i=i> h9e9a6b6a:mClA mElC mC vIzNzQ€TŠ\&‰_'^+‰Y%‰Z"ˆ\‚W€X{P‚Uˆ^#ƒ\$‡^&€XvNwQ~Z%yUvR€[!Z‚^!‡a&„^$„^'YwO[7pP²”\Ì®lÞńæ͏êՙíݧîߥíܝâÂw͗S¯i#–H—A¡T +¹y2əSÖ´râÅ}èьëڜìá¬îä¬îè¶îèµíè¸îæ´îæ´îæ·îåµîä´îå³îâ°íߪîß©ìܦíÞ¦êÚ¢æՙâВÜLjӺxÇ©c¾›UµƒF¥n*™UžWªf%³|5½KÄ [Ò²tÞÅåӛæӛå՝åԚäҘâјâϒßˌÛȈÕÁŒÀ¨n¶¢iƳx¿¨b¦ŒLµœcéo³bˆi8zZ$”x>|h4E9 )!0!G1 gBi> lA|O„d3u_-oX)mX)iV&n\+p^0vd7rHÕË©ÞÔ¹ß×»á×¾à×¾âÙÁá׿ãÚÁäÚÂâÙÄá×ÂäÚÅá×ÃáØÃÈ¡UÑ«e×µm׺vÕ¹t×¹pÒ²jÕµoÕ¶kÓ´mÖµnЭgͪdÑ®kÈ \¹Q¨{8«x/£q+¤p) n+¤q,¨v1¦q,Ÿk'—e#_‡Y~SV ~OoEjBk@sIhA nEvJrKrHlFmFnEe@`A[8Q2U4M0J.K+K,L.P/V4U1P,T1g<l@uFvI{O!€K~J€O‰T%’Y&•W#–Z$”W –U ¡[)¡\,–W!TŽTŠR‚O~G{@ +|FyEu? wAzEwBq<n:s>{GzE|G€K|GzGuCuCuDwDtCsDsCtByH}KzIxHvCq@j@ +qDmElDg?f< h?oGrIuMvNV €V#‚X$ˆ_+Žc,“h1d%Œ`"‘f/’i-”l6—o6‘h/“i/‘h0”l3f/‹d*Šc&ˆb Šc#‡a!€Z|XzW{TnGW8sS¹˜[дrÜÁ~èВëԞìÚ¡ëҐɗM¯o,UŠ>˜Q ŖMÚÂ}çՖíÝ¥îà¨îæ±îæ³îå²îæ´îçµîé·îçµíç¹îæ·îæ¶îä´îåµîä²îä´îä³îà¬îá­îà¬íݨíÞ§íݦêÚ èםèכà͒Úƈζuµ˜RhF ~?€G ŒRžk1¼™^ÚɑßЕäіãєàϏßΑÜˊØƅ×ąÕ‰κ˶|È´z®•P}\`)ªV«“V…g.dE nZ(E3 +! !5"=%A)O2 N1\;kJmV#gT&jX+gY(n\-r`3vg:”‰dØϲÝÕ»àÖ¼ßÖ¼à×¾ÞÕ¼áØÀâÙÁâÙÁáØÀáØÃâÙÄâÙÄâÙÄΩ`ЭcÓ´o׸uݾzÙ»xÕ¶nÏ®jέgÕ´nÔµqήgÏ­gÑ­hÑ­gЪ`Í¥YЧ\Ϧ_ÙO³ˆA¦{1ªz6§s0©s0Ÿn$ n)Ÿk-—f%”c"—e&b"ˆ^TUsMcB b;kCzS uOqJtL{T'oN#iFgFeDb? d?b?Q2K3F.I/G-B'K0P1T3X4 Q.R0b7 f; d; +^4 e: l?}J„H‹K‘W"‘RŽP•V#‘U’Z"‘X ”\ ”[#X#…OIIFyA yAt=q:u<vA yD yE r? m< q?sAr@p?sCyH}LP~MƒQ…QƒOˆQ#Ž^0ŠV"QyLpC h; +c7i>oGpHrJqIxMtKvI}O}TWg(™r4žvAœt;šr7Ÿw;œs8—o1u9 v5w8—p3•n.–o/’k*Žg%ˆa XxQzUpKfF +[<€a'·˜VÔ·oÜÂãˊçБۺs¼y6˜O ŠBŠB·…BáĀìݤíà§íà¦îá©îä®îæ¯îä­îå®îå´îæ±îæ°îæ´îå³îáªîå²íã°îã±îâ«îä°îâ­îá«îáªíݦíà©íݦìÝ¥êڟêÛ éמç՜ãҗÞȊ¼˜RƒN`(K X#^-•n<̵~Þ̏ÜʍÝ̎Ûʉ×ņÙȈÕÅÓ‚Ѿ‚л‚κ~įs¬•XqMc<’wA›„KxVL7<.- ' &0$>';$:";";"G0V?mS#iW)iW*jX)kY+q_2zj<Ÿ‘jÛÒµÞÕ¼ÜÓ¸áؾâÙÁäÚÂáØÀâÙÁãÚÂà׿à×ÀâÙÂãÚÁãÚÂÈ£^̨cЮhѯlÕ²sÖµs×·qΪe̦_ЬdÓ±k̦_̤ZϨ_ЩaÔ®eЪ^Ω]Ï©_Õ®eزiÑ©]Ì RϤ[ØR·‹A°…<ªx3Ÿo)Ÿn&¢q1Ÿl+œm+—d%c$†^!‡_ …\„[|VxPxOyP|R†_-~XsMe?rLxN!mFhG`B_?Z9 W7 \< b?_; \7 [8a< c@gBa; b< _; b?V3 Z4 Y1a7d; i= k< +zD†O‘Z%['•a+’Z&˜`,™^*™X#S‡Q…N|IxG n=n8rAvCxD o? k: o=sAo@m< o>p@tEzGyGxGzG†SˆV!‰Z%ˆX!ˆS…T‡UƒPyGyJxJvInBpEsFn?j@uJyN|T€YŒe$‘i-‘g(–l.—n2šr6”i)˜n2¡w7¥z<œt4šu4šo.›q1žv7•m-“h,Žc$Žd)„[„[ €\ kJ‡d&¸™TÈ®nÙ¿€×½~”N¢[‰D‚>›ZΦgêӓíܤíÞ¥îâ¨íà¦îã¬îâªîã¬îã¬îä®îå´îã¯îä°îä°îã°îá®îã°îà«íߨíߪîߨìݦíߦíà¥íÞ¢ëÛ ì۟ëڝêٞé؜é؜åҔãіѶwi'V$6/@‰e.Æ°uÙƋÚnjÙƌÔÄ×ĈÓÀ€Î½{λ|Ì´wÉ®oĪi½§m«“Yƒ`+lJ†p1…r9K7/!;,3&:%S9 ^DW8 +N4F,C(A(H. +U>hS%iV(iW*jX+p]0r`3td9©ŸuÜÔ´ßÕ¼ÞÕ»ßÖ¼âØ¿ãÙ¿á׿áØÀãÚÁáØÀáØ¿áØÀá׿ãÚÂÊ¡bɟZÈ [Ñ°iέiϬhÇ£[Ȧ^Ë¥\ʤ_Ì©eśVÌ£X̦^Ë©]Ñ«`Ñ«\Î¥ZÏ©]Õ®gÖ°iÖ®cϧ]Ö°kÕ¯fÕ¬aÕ­]Ó­_É¡]ÚYº“S²€A¢m.i#“f d#c"™j'p,“h&‘e$Š_„YƒY †]"‹`'†[#ˆ\%€Y#wP vLtOtP}T$uLgA bChDiB jFiEiCnHqLhBkDmHc@Q0I,L,V2`9 a: Z4 V,_4\6 d>xN‹W'‘[)—\.])“]$ŽVY[!ŠWŠV„PƒKJwAp?k=o>p@m< i8f; d9 n@wEr?o?n>sEtE xH}L}K~KJƒOK…NŠUˆS‚O~K|KtC tH +vKzN}S}S†]#‰`&‰a#‡\„\"…`#‹b%c*‘h'™o0›q3žt5œq1œr7šo6™n0œp6™o5šp4”i*’g-—o9ˆ`*~U‰e*³‘VƧgË­k­z:ƒAv4‚A¤n1Ô¸{é՝ëٟìܟíݤíݤíߪíÞ¤íÞ¤îà¨íߨîà©íß©îàªíàªîá¬íߪîÞ¨íÞ©íÞ©íß©ìݦíݧìܤìÜ¥íܦêØ¡é֝êלê֛è֝è֚åҖà͐Ø„¦ˆKU+2 %9ˆj7ƲzÔ¿„ÖÁÓ¿‚Ô¿ƒÒ½~͸zɲvÈ°pìn¿¥j¸ž_µœb¤‰O•y?|]&yc*J=)+8%=)X;lCwR%uS)lKcDZ?Z?[AdK&iT'kW+kX-lY0n]4rb7te=º°ÞÕ¹ÞÕºàÖ½á×¾ÞÕ¼àÖ½áØÀãÚÂãÚÁáØ¿âÙÁßÖ½äÚÂãÚ°‡G¶I³J¼šSº˜R¾™OÞXßTƟV½•M¿—O½•K¾—LÊ¢[Ï©bɤXϧ^Ô­fÏ©`Õ®fÒ®eÑ®fº•Oº?̝OȟVË¢S׫]á»uߺrÛ¹pÔ¬dΣ^ȜSÀ˜M»“O§}=k"žk œl!—h"—j'›o(˜j)žs8e*”f+œm1“l.U#zP€X {U}V‡]!~SfCg@kFoJnLlFnJoIlFjDjHZ; S7P4L1V3W5Y4 S1X4S1Q,M-N-W3 +]9oB|K‡T‹SX!“["ŽY ŒUŽY%[!’Z!‹R‚NMJzItGnAh:d:a5h8f9e9 +`4 g:i< f: j? j> j= +n>n? xI„N‰RŒU!ŠRŽVŽXˆT‰U†S‹YƒR€SS‚S„X‚YY~YX …]'‡_$h1g2‘j0•m4’i3‘h.“k/–n6—o5˜p9•l0”j1r6žs9a(|T!„]+¨†Hº˜Xšl)l4b%{=¢m,Ù¿ƒåҙé՝èԙëÙ¢éÙ¥ëÙ¡ìÚ¥íÝ©íܧíÞ¨íݦíݨíÞ§ìÞ©íݧìÜ£íݦìÜ¥ëÛ¤ëÚ£ìܤëÛ¤ìÛ£êÙ£êØ éØ éןäӖåәäҙæҗâΑÜȌÙĈ±–^`?0#;!”yHDZxϸ€Î·}ͺË·‚DZwůtÀ©jº£d²œ_¬˜_ª’\„Kœ~Bu8nRD0!-!B+_=rK|R'{T0sN oK!eEkLkS'kS-hQ&fT)jV,j[.m]1qa5wg?Æ»˜ÝÔ¶à×¼àÖ½ßÖ¼ßÖ½ßÖ½à×ÀâÙÁâÙÁáØÀâØÁãÚÂâÙÁáØë„D²‰O«„D§>¥>©€>·ŒK¸”K—MŜUÀ›R¿›S»—R¾™VÁXÄ£Zá\Ñ­jѬcÔ¯bѬaѬ`Ъ`ƟSȝNŚOË£UÏ¥WÕ¨\Õ«]Ч\Ò§^ÓªaÑ©_Òª`Ñ­aÔ¬eÉ¡YÀ’I±„8§z2¤{3t,”i ‘b%d&™o6r5•m4•j1Žd*”g+‰a%}V}VWxUpJzRV+yS%vOwOqLfDiHhH[: W;_< aAaA_=T8 +T5U9 +X7 V3U3Q0M-K,K*V4 +`8 +i= sF|J|K~H{KƒS„Q‡R‡RˆS"…S#P ‚R!~NxJ#vJ!nCl=c4 ]2[3]1b8_9 _6 ^6 b: b8 a6b7oBsBuG}K„M…OˆT†UŠWŽYŠY!YŒZ#ˆVƒP~P€RxKxIwI€TƒX†]&‡^!‡`%Šb&f*f,d*d(“k4“j0”i-–o1 x8˜l0‘h1|T{Q’l0‚WV)Ha0q2ʱ{ÙĊá̗æΕäЛèӟèԞêסêÖ£ëÙ¦ìÙ¥ìÚ¦ëÙ¦ìÛ¤ëÙ¢ìÚ¢ëÚ¢ëÚ¢êØ ëÚ¢éלèםé֞éםç՝ç֝åӗäҖâΒáϒá͑ßːÝɌÚƈҾ¿¦k~^&> 4[E¤ŽYÇ°vîxƯzÆ°x¿©m¿ªoº£l²—^¥X¤‰OžƒN™N”yE†n/eP7)*=%L.^>gCkM!kN"lKjL!kPnU+iT+dS'bR$gV)gV+o^2qa6~nJÐƪßÕºß×½ßÖ¿á׿ßÖ½ßÖ¾âÙÁãÚÂäÛÂâÙÂáØÂâÙÄãÚÄãÚŘp7¡t:®‚F¥Dt8šo.’i&šs0œs,¬„>Àž`àa¿™T¾—T½—V¹“P¸LµO¼—SĝUˤ^ѪaÓ¯cЩ`Î¥XϧZϦYϦYÕª[ɟQƜQʞTÌ¢Yͤ[ȟUÊ¢WÍ¢UΤUÒ¨[Ñ¥[Î¥XЧ^̤YË¥Z½–S°†Iª>¤y8 u7œr1œp,›m-“f&‰\ˆ^‹`%„Zƒ[!†Z!U{S~V {SwOgDlKiJ[< _CpLuNvR€['vX#nMdD _>b; \6\:X6 T3O-J,Q-J-Q0c8 c:d6h<j: oAoBuGtFzMxN~R O!P"„R%O!€Q%~LuEl@j=e: a8 ]3_5 Z1Y2^4Y0[3W/T-Y1`5b5f7 +m@ }M€K„R"ŒZ'\"Ž[ˆTƒQ~LyJvGqB vF}RV€X |T€Y!…\&„[$‚Y †\#d.Že(“i-“k-“l,“m.”l0Œd&vNfC ^==7O&Šj2¿¢pͲ}Ï·}ÙÁˆÝňÝȊâʎæϕçҜæҝè՟çԝé֟é՝ê× êןé՞ëØ è՛èԙçӘåѕæҗãϓâєâΑã͏à͐âϖßʎÛȌÝɎØćÕÁÐº|ìt§T‚i,r] ’{D±š]¼¥p¿¨r½£lº`´^©–Y©”^¢‡R–D‘z@q9‡n7t](M:0!)#.!4$8&E0I3S9 Q=T=S<W>\CfO#eQ%hT)cP%fW*fV*p]5rb:†wRÔ˯ÞÕ·ßÖ¼àÖ¾ß×¾âÙÀà׿ãÚÂäÛÃâØÀâØÁáØÂãÚÄãÚÄáØŽf0™s<™r;¤‚N¢J™s:›x9“g+žr2¤}5¨‡D²K´M¶P³I»”L·“L®ŒD³ŒG¼•RÜTěRŞUË¥ZƝOΦXͤZѨ[ЩYЧ[Ш\ΧXÌ£VǞSÉ SÊ¢UͤSÎ¥UѦUÉ¡OШUÓ§UÒ§TÏ©[ͧ]Ñ«dͨcÍ©aÆ¡Y¶”Kª…C£|6šl.•c'c!–k0—j*œl(¡r0Ÿm+–f&“b!’e#X}T sNfHW; +`D oKtNsPyOtUqNlHiCe>eCfAa>gC_?Z8 Q.G-F,H1P1R1S1W4U0[6 ^6 Z3Z1d<i?l@tGxJ{N$}O$Q$xIxGxHwIvFtCqBk< b6Y-P+M*I(E"E%K)K'N*Q,W1 +\4 f;tH€R‚S€P‚N‚QP‚R~PT!€R ‚S"U$}T!U VƒZ%}SW†Z$†\$‹b.‹b+Žf-Šd+h2†`+|XdCW7 8(8eO¡‡Q·–\£nÅ©ḻrÓ´vØÁƒÛÄàʔá̓ãʎåЕåИåҙåіåҖåїåіäѕåіãДäДâΒâΑÝɍá͐ÝLJÝɍÜNjØăÛĆÔÀÒ½‚Ï»€Î¸}Å®u»Ÿh«•]§V«’[²š^µœe°™`´™^¨R ŠKŸ‚JxCq?„l/zb%rUZ?C-'# 8![; lH jDmB [9[8U4R5P7Q:B'A'@(G-V>`M!aO#gX-jZ.hX.jZ1qc=ŽdÕͲÝÕ·ßÕ½ÞÖ½à׿âØÀáØ¿à׿âÙÁà×ÁãÚÄà×Àà×Áß×ÁàØÃW6 eGwV'Ši<’n5–p5¦G¥N¤~Iª‡J¨„Lž{C¦K¥‚B©„D¬‡D§€:¦>±G¹•OÁœYŸYÉ£[ǟYØQŜSɟS̤XΦXÑ©YΧUÓ«XÓ«ZЧ]Î¥XΣPÌ LÊ¡PƛIŗEĜIÉ¢QƝLƝOĝPÀ˜MÁ˜RÉ¡\ͬdÊ©gÆ¢YÁœV·’J¹N®„Bœs-p*œl)™f%œg&¥o&ªv/®y0n&–g)’c!‚Y^A aD jE uQ|X!{Y$uV pRjHdAeBeCa?c@cAgEpHkD`>Y; +U9 Q2J.Q0Q0L,P0R1Q-R0U4 +Z3 +Y3 +Y3 ^5 c;i>j>mBqEvFuG}LzGzLwIwGnAf>`7 \7M+H&G'E$@$A%@&F+A(J/U8P/Q/d>iAoF{P&yO|R!R!…V!€VƒY#~X €W!|S!{R!{O€T{RzPR ‚V…]%Z%~W$|V#yU!oJM/*$>+u\+–v<¢„K°Y¶ši¿¡kÇ«pϳsÒ·{Õ¾|ÚÇÛÍáȊâʐà̏áΑâΙáΒà͑â͒áΑßˏÞʎÞʍÜȊÙƉØƋׄ×ÆÓÀ‚Ѿ€Ñ¼|ͶxɲzÄ­wªv»£l³f°šg«“[®’W«X¤‹N£…N–}H•{EŒuB‚f4y_,cPQ9 <'/ '6V;zT‰\_‹X\‰Xˆ[‰]zQmG d@Z:L2K4J2ZEeU)bR%hW+hX+j[2n_5vf=œmÛÑ·ÜÓ¹ÞÕ»áØÀâØÀáØÀáØ¿âØÀà×ÀáØÂãÚÄà׿á×ÀáÚÄäÜÆK1E*B&J2\< tN#Tb,›wIœx@•tB‹i6‡c.€\'Žk8šv@u3•l.št0­ˆIµP³‹K¹“P·‘Qº“UÜYÉ¡X̤U̦XΦXÌ£TÏ¥XÌ¢TȞTÎ¥[ШYÒ¥UѦVȞPǜKƞKÊ¡SϨ`ÚLÛLÈ¢UƟPΧ[Ϊ^ÛSȟTǟUÁ—R¿™UÛSÚRÌ¥^ȞZ¶‹Jª€?¦x2§u3®|:¥q*¢k, m-£r3“d%‹`#c)Š`%ˆ`$‡`'Šb&Œd'ŠYƒ[€\uNfFhFjHiGpMqNpMlFgE`> ^; +]; +_?^< X7Q3N.Q.S0T1X3 +X0W0V0 X. `7 `6 g=lAf; tGpDrFpBuGvGvHpAl@h= `8 [7 V0T-@$>#9$4"7"4$5#5!7";'B-N3 O4Z<kDvJsIS"U"~V#|U!}T'zMxNtMtKtKuNW vOqKtOpLsNeEG,(%@%X: pN €b2–v?¤‚F°ŽW¹œeÀ¡bÃ¥iÆ­q͵€Ó¹zÕ»{ÙÁ‚ÛņÞɔ×ĆÛNJÞʊÛNjÙŅÛƅÙŇׂҾÒ¿†Ð¼|͸w˶xdzuÅ®kÇ«pÁ¦m»¢j¸Ÿjµ›c°”Y¨X§‹Yž„M™€E—zDr<Šm6za&rY$`JI60!('.#D0hL"†g3•j3`)a‘`#–c&œh#žl'œk*™f&‘a"b"c%„[„]"~d.m[+dS%fT'hU*gY,jY1p`;qc@£—wÙжÞÖ¼ÝÓ»ÞÕ¼áØÂà׿à׿á׿áØÀáØÂáÙÃáÚÃâÚÅãÛÆäÝÇ_@_=U3 O3 N0U6U5 [<sQ%vU _.‚\)‚^,„_,…b0’n:›u<“l0“h(£|<©‚Ežx@v8žx9 y=¤}>®„EĜYĝVͧ]ͧ^ʟTɜRÛRÁ™MȞQÊ¡SÊ£TϨYЧTÍ¥RШWÓ¬`Ï©\Ë¢UЩ[Ъ^×µkÑ«bɟTЩ`ЩaШašSÁ˜SÙPÌ VÓ§\Ð¥]ϧ^˟UěP¸H»ŽF¶‚>¯|7¬w2«r-£o)¥q. n(ª{6«|8¤v1›o-ši(–e!“f%ƒ\vOyW€WW~X"|RxPsJvLqFpC pGjDlCsNwR pJgAhCb: [8 U1Q0Q.O.S0T0 \6 \5 ]5 [2`5 +a6 a7 +e<pCqCl?lBk@h; h=d9b7_7Z1 M*F,D)>'5- /"0"1$0"2&;(B,G-K.Y5 `: gDkGrKnEpJrJsKsKqJySsMqHlCoFqJmKiAR1F.D)C'I+I/]? wTˆi5’u:¥‚A«Q´”W¾¢iÆ©tÇ­sɱtе~ѶÒº}Ò¹~Ô¾~ѽ€Ô¾€Ô¼}Ò»„Ë·|̶{ȱwɯtÆ­tçj¾¤i½¢cº`®’T¯’Y®ŽQ¨‰N¡„DœD—{F‘w?‹p:Šg0~^lO[BA+,"-E1 R8 mOyW‹g-—r6‘g4‚W‹\“b ˜e ˜f!—e—g™f"žk-›h*žl-žp4Ÿ{E{h:eS'dR$dV'jV+k\0tc;thH¶®ÞÕ»ßÕ¼ßÖ½à×¾à×¾à׿âØÀâÚÃáØÃáØÃÞÖÀãÛÅåÝÈåÞÈçßÉrM0mJ&pI$eAc<U8 L0K1 +H/Z>bI"gJqX,pQ$uQV'ƒ\%…`#•n6£|?§}B¡u7›t5œr3§}<«‚C¤~=¢|=¥}9­ˆAº‘G×R½’G½“I¿–MěPÁ˜MŞSÈ¡WÉ SÈ¢WÍ©\Ñ©^Ó¬bÔ®eÓ«bÕ¯hÙ¸oÕ±iÑ©cΦ`Ï¥\Ñ©`ЪbÉ¢^É¡\Φ[Ò¦YΡUÓ¦_ׯdÖ¯eÔ¬cÒ¥^Ñ¢[Ï¢YʛRË¡XĖM¾ˆB±z4®y4­{2§t+¦v/n*Ÿm+˜i(Ža!‰`#…\‡ZŽb’d$Ž`ˆZ€SvQV$‚W‚Z&‚Z(ˆ`.c4ˆ`*‡Z'„[$„^+…W$xNpNeD`=Q3Q/Q/W3 _8 X3X3Y2Y2Y3W0Y1\4\6 +^7a:a8e;c9a6b8g;e:c:^7U2 +Q/J)F'B$9%5%7"9'<(9$;(A)C+G+N0 Q1Q0\8 `=b=eAfA rM"rJjBlCmFrGwN vN"pHuJiBa@V5K0B(H.L0\? tU‡c,™zB ‚H¨ŠI³”]·š`¿žd¿¢j¾¥gĨn§jƪnÄ©oÆ«r¨oĨk¿¢d»žc·Ÿk³˜_µ–_²•`§Q¨ŠUŸ„K›|E˜y?”v6Žo3Šn-„g)z\sUgHM8;&(#(4H0\=jGyQ V‚]%˜w:™t=‰`$Š_‹_‹^Œ_^‘_“`•d$”c$™h+šl1™r?t^.^R#dS#cS%dV'l[3pb:sfEÊÀžÜÔ¶à×½ßÖ¼à×¾ßÖ½áØÀâØÂá×ÁäÛÆäÜÇäÝÈäÜÇæÞÈæÞÊçßÊ{^7`9uL+oI!mFmIhFdGS5N2 I0E-E.V>X>[=oT%rPzW%‡f/‘l;–m4•i,™n4¤{B¤G¦E²Sª†D©€=žu0¤}8µ‹H¼–Q¹•R¸J´ŽJ¾•N½’M¼‘K½“MƞSÈ¢YȦ^Ï­b̪_Ô´jܼrÕ´kɤ\Ê¥[É¢VÊ£[Ì£\È¡VÙOÊ¡WÒªbϧ[Ò¥\Þ·nà»rÕ®fϦaÒ¦XÏ Y̞UΡXУYÔ SРYɚS¿“H¸‹Aª}1¨y0Ÿj$œi™i›i!ši)•h)•h-–h*—k*•j)†WyP{R{Rƒ\+ˆ_/Œc0“f1“i2a%‡^#†\$a,`,‘g3a,€UuKd< +f= +b>`:_9 +[7 [5[4X0V/Y2W1T/S,T0T2S/V/ W0 X2 _7e9c9b7b7a8b5e9g<a7Q2 Q/ P3O0 I+ +E*H, K- K-M0 K.K/L-M/F*M/V4 Z7_>\:a=fAmE!sG|R+yP+vL"wO'rL"mG lGd@]<M.H+K+U0]: oNƒf)“r6{= }?©‰MªŽQ°–\¶–a´”Y·`¯“X¬‘V¯“\¦Q¥‰V¤‰P¢…Qœ€H˜zG”w@”x:‰m3‡h6a*|^&vX!jO^C S5@'5*,3#=(K0I.K.W<cA +c= jCrKrK„](Žf/…^…]ƒ[ƒTˆ[Š\‡T{JN RŠW^&Ži0kSbS$bT$eU(fW)jZ-l`:znKÑɤÝÔ¸ÞÕ¼ÝÔ¼ßÖ¾áØÀà×ÂãÛÅãÚÆäÜÆäÝÇæÞÉæÞÈæßÊæÞÉäÜÇu_<ŠoNuX5nP+qP/}X2wO(kI hG_>T8Q4T5P5N4 J2 O5X?bHX=W<^AhIuT*ƒ]3l:”n?£~K©ƒK¯‰P«„D¦>·ŒL¹’Wº•U·ŽN´‹L´‹I¼”P¾–K¿”H½”HÁ™L½—HÀ–GŞQÉ£Yϧ^Ó®cȨaʧaÑ«cɤ^Ȥ\ƞUÊ£ZÇ WǞV×NǛPÏ¥ZÕ«^Õ«`Ð¥\ΦYÒ¨]Ê¡XÁ˜LȚPȕH̞MÏ¢RÖ¯`ݸi×°aΤZЦ[Ì£Z¿“I³ƒ6©z4Ÿp+–i*•g'šg%n'šk#_Š]!‹^'‡Z€VyQƒX‡_&‡\#X€WX#…\'Œa/‰^)‰['U vKvJlBb;^7Z5X5 W5_<Y3`9 ]7 Y5 U2S0O/K+L+I&M*L,T/T0 T/ a6a:c:c;iAhAe<d;b<b9a=a>]9\:Z9Q2 R3U3 T6O2 H,H.I,L1T4P0 +P0 S2 ^;b?hCrH!oIqK$oIqHrIqIpFnEa9]3P*P+J*P0[: fDsR €a&‹k1rA•t@›yA”t<˜xC–yCs?•tCŽo>†k5‚f1‚d-z\(u\)iPjM^?S5L0E)=&;$:E+K/]=c? +`= bCjFb:a8a=fB a< +`<c= a;dAmIqNwK rHtK R‚U‚RyK|M +N …UŽa'Šk4nW"bQ#_Q cU&hW,i\2l_8…xUÒɤÛÒ¶ÜÓ¹à×¾âÙÁãÛÅåÝÈãÜÅäÜÇåÝÈæÞÉåÞÈæßÊåÜÈäÝÇåÝȤ—~”‡q~qWvfHucI…kFƒb;†f?|^6xR0oM2dEc?^?T6O3Q1Q6O7I0 I1 I3 J1 N5 ^AfF kJ|W%h0›qA›r9Ÿx8£}@¡~A°ŽN®‰J³‹K¶OÀ–WÁ™T¿—MÙPȞT¼“G¼’F½”H¿—M™QÀ—MŚUǟZͤ_ʨbà\¾™S¹“J¾šTĜV™U¾˜RÀ•HėNŗNŘIȝTЧZÓ«bÒª_Ò«gÌ W”GĔDÑ¥^Õ­bÓªZׯcÞ¹hã½tã½rßµdѨVŝQėR·ŒE®7¨w2¤v5œl)œm'r3™m*–j(Œb"‰[ˆZ!†Y „Xƒ[&T!rFo@ oEzOvIrHuLxNsKrJsImEoDj> d: b;b;_9 ^9Y6 W4S1 O-J, H)G*K- N,L*M+W3 \6\5b:a<`6c;b=c=gAkI'oK)kDkI$gDeFd@a=\:S1 P1 N.U8R4 O1 P2 E*I-M1S3 T4Y7]:`=iFlDjEoGpHqHoFlFe>]7 P/K,L*L-K.V:Z;_@Z? aEfHiMbF`GX<T: P5F-A)?%47259F.Y< +fG rRxQU‰_!†Z€V€SuI +vLiD nD lE c=`;^6`8a;`:_7f<nBtFxIxK +vI}O {M zM†Zƒf1gOaQ#^NfU#fX)iZ1h[5“‡gØͱÞÕ¹ÞÔ½à×¾äÛÅãÙÄäÜÆåÝÈåÝÈäÝÈäÜÇåÝÈæÞÉåÞÈäÜÇäÝÇ×Í´ÓË°ÍëƼ£©ŸƒžpˆwRƒpQjM‹pT‰nQ„eFuT4qQ5kH(b@b>\>V:L5 F0 +H4D,G3K7D. D1 +Q7cFrV(~Y-ˆe1‘l9“l=’k6Ÿz@°ˆJ³ŒK¼“PÁ™UŜSˤ\È¡WśP™QšWÁ•R¹L²‰EºQÁ™T¼”NšSÀVŸZ¾šO¾šS¿—Qº’M¿–O¼“H¹EÁ–OƟQΡVФ[Ψ]Φ^Ò¨fѨbШ^Ôª`Óª_ЧZ΢UÏ¢SÙ±cܵiÙ°aâ¹gå¿iâ»kà»hÓ«V׬YÚ´oÖ°kĚR·Š?¦z4 r6œm%–l'™n*–j+’e'Œ`‰[ˆ[QqG nE uLvJvI€X%„[$Œc-ˆ_(ˆa)‰`*ˆ_'UtKnDa9 f?d=b>W6 Q2 T4 O1J+M/ V4 V3 R. +O-S0 W3 W3 V2 T0U0 U2 N+ Y5`;hEqJ%mGqI%qI(uO+tN)nGjE nD#kD%b?a=\>T7M/I, +M0K/ K/ N/ +L/ P2 W6Z6 \;Z8a>dBkGnGoH!pGpDpFe;^8U/T1R0H)J)H)D)>#A'>#<$9657#3=$<C&L-O+P/]> lI|RWŠ]$‰Z#„YˆZ‹\‹Z‡X‹Z…V€QN O +xN +mIvGg:g<j?h>i>qDtGyL uHvJyL +lClB ySt]*cP^MdR!_Q&hX,jZ0m^5š‘r×γÜÒ·ßÖ¾áØÀãÚÃäÝÆåÝÈäÜÇäÝÆçßÌåÝÈåÞÈåÝÈåÝÈäÝÇèàËÙϸØϸ×θÖÍ·ÖγÕ̵Ö͵ƾ©´­–©›~–…kŠq^|gK}iGx\5wY;wZ6jHiE Y=U:R;H1G3C1F1F1B- B0 A+S9_Cx[2pM{OŠ\*–i+œp3¢x6³‹L³ŒI»’P¾•QÀ–LÙVÀ–UÀ™X—V¸ŽK»•Sµ‘P·”M¯‹D¸”M¹•Lº–MÜTÀœV½˜PÀ—PÁ˜Q½•N¾•OŝVƝUÈ XШ_Ô©]ѧbÏ¥`Ì£XΦZÒ©]Ó©\Ñ¥WÏ¢MÓ©UÝ»lܸnÛ°_׫Wß´_å¾jä»gà¶gÛ·jãÁyæÂvá½sÜ·pѨf—P¿•V³‰H¯…Hžu.œn)œg*šh&•f%_%Š^!‡W!„W‚W€X{SxOoKpIuKrIzRtLtJyR%}V$‚]'xSeA^9 Y6 V6Y4P0X8 W2 +V2 S0Y6 ^:Z6V2 +S. T0N*L( N+T3_:[8]8a<lI(jB!lI$pG#nG#nI$oI!nHhCa@^<\8X6T3 S2 +J.Q2 N/O0Q1S2 Q0V6 Z6 ]7 `<b>d<g=h>d:h=jAh< e<j@e?`; Y4 Z6 +T/S1Q.L,H(I,P0P/V3R1W3a9 +f? c:e; oEvJ~N|MP‡XƒVˆY†X‰YŠ[‰XˆZˆZ‹W[‹\†Y‡Y‚R |LyJtK wL }O €S R}K{KvFl> +a8nGiS aOcR&_P aR$`P#hX+l^5©¡ƒÙÒµÝÔºÞÕ½ãÚÃãÛÄäÝÅäÜÈäÜÇäÜÇåÝÈåÞËäÜÆäÜÇäÜÇåÝÈãÛÆÖͳ×δ×ͲÖͲØε×δÙε×θ×йÙÏ»Õ̵ÍĬĸž®¡ˆŸt‡t]{gLv^9u^;v]\:b?jGyU&~W!‰`"g(Ÿo5¡v7¤{:¬‚E²‡I½“[×^¾“N¶‹KµŽL²ŒH°G¶Lº–Oµ‘F±„:µC·D¾•KÁ˜Q¾“MÙVÛT¿–OÀ™VɞU΢UÌ£UÍ£WÑ¥WÎ¥XÐ¥T΢QÍ¡OʝHʜIΣSÔª]Ù±_Ö¬ZÛ±^à¹iÚ°aÕ°`ܶeà¹lâ¾låÄséˁéÆzæÃyß¼qÖ°jÕ°kÔ°gÓªaÎ¥]»G¦t/£p0žo2—j(•g!Ž`"‰_ …_"SsNmGe=h? d? +b> kHsNyQwPyT!sM mGiCa;^7 Y7Y8 [:W4 T2 T1T2 +Y5U1 V2 +Y5 X3S/ J+K,R0P/Q2U4R0T1S2Y8bAa@jG"iFhEcBbAa=dA^:^<\:\:T1 P/K*J,K)T2 Y2\5 [4 +Z1 \5]5Z3 +_6Y0^6`6 d7 b8 `6 d;f;e;e=f<d9e;b8 `8 a9 a8 a8 a8`8a8 h=c8c:k@rGzKxJ€O€QRQ…U…W‹Y_‰\‹]ŒZŠY‰V‡V‰Y\^Ž]Š[Ž^”dšm(˜gd‰[{P iB `9gFiP_M]LeR&_P!cS%m]1rb=·®’ÛÒ¹ÝÕ¾ÞÕ¾ßÕ¿áÙÂäÝÇäÜÈãÛÆæßÉæÞÉäÝÉåÞÈâÚÅçßÊåÝÉäÜÇØζÙкÙϸÙй×ͼ×͵ÙлÙйÙкØκÙйÙϺÙкÚмÕ˶ÏŮĹ¥µ«ž”v‰x`}qUua>nV5iW8bR6XB&]B%^DT<M2 K0 I1 F1 F2 H3 D. G.P5 T9 `BhH€X"ˆ^)’j.šm7m5«}F¹ŒS·J´ŠJ»Q·M¸ŽK»“LÁV¿šP°Š<¬†<®„@±ŠA²‰B¯‡@·ŽI¼˜Q¸”M¶’L»•PÚRǞWǞWÉ TÊ SȟRË¢WË¡QÌ QΣWÏ¢QÔ©\׫]ÖªYÕªZÖ¯cÕ«ZЪXÑ¥Q×®]Õ¯\Ü·câÁrçÄxæÃyá¾oݸoÜ·oâ¾tæÃyåÅ}åÃã¾xÕ¬gȝY²†<¨y6œk0”l+šp,™o,šs0•l-‡^%|TqGg> `?hEb< kBoJuQ"}V&ƒ^+xRlFlHpN pNb@T5 J/O0T0[8\9W5W4S4L0N.N/Q3I.L1H- D( A* +B( +H, O3P4V5]<aA!`CdBiE`?[:bAfAdBS2 K*L,L*R*U1U1 T0 +T,Q. +S, U- +U, S. +R+R,O+V0Q,S1 X2Y7 `9_:a<`5 c5 d7 f8a3 +e7e8 c7 d8 a5_3]3a6j@o@ +o@xE +vB{G LN ‚O ˆT ]‹Z``ŠY‰V…R ‰VŒY[^“b™fl"¤t)£t)žn(˜h a†W}SpMdOaQ#`O"aO"dT(eV,h[-ugB¿µ˜ÞÕ»ÝÔ¾ÞÕ¼àØÂâÚÅãÜÆâÛÅäÛÇåÞÈåÝÉæÞÈåÞÈäÜÇåÝÈãÛÆäÜÈàÖÀÜÒ¾ÞÔÂÜÑÀÜÒÃÚѼØλØμÙÏ»Úн×̺ØιØ϶ÛϼØλÙйØηØϺÓ˱Õ˳ÌìÀ¶ž©œ…œq„z_sbEiO6iO*cK*fI-Y=\< V5P1M1 I. I0A- D/K4P4O3hE}_,†b1Š^,Ža(¡{E­ˆK²ŒO°ˆN¯…H³‹J½–U¾™Y¼—Rµ’K²ŽI±‹M´‘M±ˆF¥{8§8­…>°‰D¯‰C¬…D´Gº‘O¿—RƝVǞU™NÀ™LŝQɟOÈ QÊ£TÉ NШWÖ¬_Ò©YÖ®^׬X×®]ѪXÕ°_׳aÖ²]ÚµhÙµeÙµhܸnܸoß¼rãÁwâ¿wá¿wâ¿wæÃzåÁyݹvÔ®pĞZ´Š?­„Aª„?¨}<¦}:u,f$‡Z#RW#‚[#}VnGjEkDmGvN}PyOoJlIsOxSvQfER8 O3Y9 b>`=V4T3 T4K/J,M.L/L0J.I. H, F+ @& A(<#<& @( D+ J/ U8V7Y9\:\9d@gD!_>c@mF`;Y6X0 R,S.W3S. P,O*S. V1 Y1 V0 N+I)I)E(I+F%H,N/ +Q0 O-T. +X1 ]2 _5]4a6 d7 +d7 f: e9`5f; +e9f;j=j<h9j;n@rAsDsCzI‡TˆU‹\Z‹Y‰VˆT‹XˆU ‹Y]‘\šgl m$ m' q*Ÿp&™i˜f'’g&]%gS%]N!\N"^R$aQ$fX/i[.}pNËÁ¦ÜÔ»ÞÖÂà׿àØÃßØÂãÜÆäÜÇãÜÆãÚÅãÜÆåÞÈâÛÅæÝÈäÜÇäÜÇãÛÆáØÂßÕÂàÖÄá×ÁÞÖÄÞÔÀÝÓÁÜÓÁÚÑ»ÚкÜÓ¿ÙÏ·ÚѸØη×ͶØδÚѹÛѺÚÒ¹ÙйÙÏ»ÛÒ¼ÚѺØζÑɳŻ¤·¨ŸsŒ}g{lRp[AkO6mM8jG-c?!Z7_D#T2N2M5G,C-S4 [:a@iHtJ!‚]1d7—n9œuBžxE˜r?›r6®>µŒF¹K¸ŽQ»‘T»˜X¶”R¦~>¢{6¨ƒ=¬†A²ŠE¨ƒ?¨8®…>©:²ŠF»•P¾•K»’H½•I¾–K¾–JÁ˜N¿”I½’DÚKÏ¢UФVÓ©XÔ«XÖ²aÙ¶hݾpàÀuß½sزiÕ±eÔ¯g×±kÙ´mܺpß¾vàÀwß¾wâÀuäÁ{à»tÞ¸yÙ³oЩ_É¡ZÌ¥_ěR¿•S³‹Dª9¨z@šr7™p3›r2e$‚UxOsOrMtKqHf? +]= hEnExQ{U#€W$sQrQoImH kD iAgCf? V7L0K0M.H, F* +I.H/ H- B+ B(A):%<';%?'?%E, E+ F+ +N1N0W7X7jCtJ!wN%mDe=b:Z4V0 U,U- +X/ +[2\5_4\1 X1 U. S/Q-J)E%G%E(E)G(H(D$H)K+L*S-X1[1]4c; +^3d: d8e8g8h9k;j9j9l;n;o<n=p={I€M †RˆQ ‹XŠX \\`–f™gžk"l j›hœi"›h!šg#–f%“b"^#bS![M [O%[P&^O#cS(hV.ˆ|ZÓ̶ÛÓ¼ßÖÁÝÕ¿ÞÕ¼ß×ÂáÚÃâÚÅâÚÄäÜÉäÜÅäÛÅãÜÆáÚÄäÜÇåÝÈäÜÆãÚÄá×Åá×ÅáÙÃá×ÄâØÇÞÔÂàÕÄàÕÃâ×Åà×ÃÞÔ¿ÛÒ»ÙϹÙϹÙкÚкÚѽÙÏ»ÚÑ»ÞÔÀÛѼÚÑ»ÙϺÝÓ¾ÚѺÚѹ×ζÕÌ·Îíº¯—§™•ƒn~kTv`KrXa=oK"yT$‚Y(‚["Žb$–k,™l'q-¢x=±‰R¹O¼”T¸“T¸‘Q¸“T¸‘PµŽLªƒC¬ˆDµM¶K´‘N¸’M¯†>¬†=«ˆ?±ŒDµ“I¸“H¹’K¹’G¾—O¾”JÀ˜N̦ZÕ¯^Ö²aÓ²fΪ_ͧbÕ³lÕ´kÖ¶k×´kÕ±kÑ­dÕ°gÚµkÙ¶l×°hزeÛ·kÛµiزlÚ¶nÙ±kЩ`Ô®cØ´hÖ°mΧdǞVęYĝ]À˜S¹I¿“R¬€@’a†Yˆ]&†YƒVvStQsKpIwO€X!‰`$‹a%Š[„SxJnEqJrIqJ%Y7K. Q3Y8`@U6 L/D. I/ H0I1I/ G/ ?&>);%:%?%?&D+ +B)B&D* C) P1 a>a<e>d=e?f?_<_5[5Y3Y/ X0 ^3b6e8b6c7`6 ]2 W,T+K)I+H)H*I'G(C'H&J%J&M*O+P*R,U/[3b7_4f6f6i9k:j:k;l;l<i7uB{FN †S ‡S Ž]‘]‘`”c˜g"œi ¡l#¢o%¦r(Ÿkšf™f!—f!–e%•d$€Z ^MWMZM&ZN$cV1bV,lZ2šŒqÓË®ÞÕºÝÔ¼ß×Áà×ÃÞÖÁÝ×¾áÙÄåÝÈãÜÆáÙÂãÜÅäÜÆâÚÄãÛÆâÚÅäÝÈãÚÅäÙÈãÙÈàÕÄãØÇãÙÇãØÇá×ÅàÖÄâØÆâÙÆáØÃáØÃâÙÄßÖÀÜÓ½ÝÔ¾ÜÓ½ÜÓ½ÚѺÙϹÚйÛÒºÚÑ»ØϹÚѺÚÑ»ØθØιÜпÜÒÀÚÑ»×͸ÒÇ´Á¸¡¯¤™Šn‡s\€hM{`GgN,qU6aFP4 L2J4J3H*Q4P8N7 \<gCwS|U„U Š`*’i)›s:u5§z@²„K¸ŽO½“VºQ³‰J·N³O·“R¸”Qµ‘P¯G«„:£5›v+v%¨‡>°‹A²ŽE´E¶F¸Fº‘Kº’FŝQÏ©YÖ³`Ñ«`É£^ͧaƟXÏ­dײk׶n×µiÓ°eЫ`Õ°dÔªaѨ_Î¥W˟VƚRěQÏ¥bЧbЧ^Õ±fݹmâÀsÚ¶kÕ­bϦ_̤bʟ^ɜWĖN½’G³…?¦t2¦w.¦u:œl.ˆ_%‚TTƒY‡`Ša‰`"…\ƒXyNpIsJlF iFY9T5 U3a=gBnGnJ!cCW:N4 Q6P5 N5L0 C,?'>'='A+ +D- F- B*?(;!?&qAwE~L‚P …R ‰V‹W\\•d!—aœi!£n)¢p( l%œh#œi*—g%–d&”e&vT^NZN#[N(\O)`S.cV5j^<¥›‚ÖδÜÓ¹ßÕ¼ÚÒ¸ÜÔ¾ÝÕ¿ÝÕ¿ß×ÂáÙÄâÚÄâÚÅàÙÃãÚÃâÚÃâÛÇàÙÃâÚÄäÚÅåÚÉãÙÈâÙÅâØÆäÙÈáØÅá×ÅàÖÅá×Åá×ÄâØÄáØÃá×Âà×ÁÝÔ¾à×ÂâÙÃà×ÁÜÓ¾ßÖÀÛÒ»ÛÑ»ÚкØйÚѹÙ϶ÜÒ½ÚÑ»ÛпÝÒÂÛѼÜÒ¾Ö͹ÚÑ»ØϹØηÕ˵ù£¶§’§˜’bƒnKrZ7sZ=jT5`D'_B&\B$P6L4M0 P1L3Q;b?kHpGzR&„](“f,—l8£{B«ƒI¶ˆM¶Q´N½™Z½š[¸”V¸P³ŽM®†A¦}3s'q%›s& v+Ÿw/¦€:­‰A²‹D¶‘N½“H¼’F½–IœMÌ©\ЯdÖ´lÕ´lÕ³jÒ®dÑ­c×µmÖµpÔ±jÓ¬gÓ«gÒªcͦ^ɟY¿•O¾•OśUË¢YШ^Ô©_Ö¬^Û²hØ´iܶh߶nÝ·rÔ©iǛUĕQǗQ’LGțQǜTÁ’G´‡>ª|6Ÿp,˜j"“c‹[ …Y‰]€X…Z!yQuNnHgD_>R4P3W; dBoLvQwT$jIeE`>eCbBhEX7P1 Q3 +K/J/ G.G.E+ B*:"58#;#<#<#?&>"C&G(N- R1V1W1U/W0V0 Y3X0 +X0 V1 \7`:j;sA"o?h:m<sAh9]0 \/]0 Y/Y-Y,[0[0\1`1a2]._0b3i7i7j8p@tD +l;n>sCxH |J †PˆT‹Y‹XŒZ‹X’_’`–ešg"–d ”b‘^“`"“d'Že-uY#YLVKZN#]Q(_S+_R/i]9°¥ÚÑ»ÜÒºÜÒºÜÓ¾ÛÓ½ÛÓ¾ÝÕ¾ÝÕ¿ß×ÂáÙÄáÙÃâÚÅáÚÄàØÂß×ÂáÙÄâÚÅäÙÇãÙÇâ×ÆáÖÅãÙÈäÙÈãØÇãÙÈãØÆâØÆäÙÉá×ÅáÖÄßÖÁßÖÀáØÀà×ÁâÙÄáØÂãÚÄà×ÁâÙÄßÖÀáÖÅÞÔÀÝÔ¾ÜÓ½ÚÑ»ÜÒ¼ØκÚѺÛÒ¼ÚмÙϼÙϺÝÓ½ÜÒ½ÝÔ¾ÛÓ½ßÖÀÚѺÖͳÌÁ¦À´™³£‰›†kza‚oOvd=w[7iM'gO#\DI5K4R7 Y?]AaBpN${U"ƒa-ƒ\*Œc3‘h3™l:§~E¯ˆG²ŽOº’Q·‘Qµ‘L³J²ŽJ¬‰C«ˆG©„?¥}9t1™p0¥}:«ƒCº“M½–LÇ¥Y¾—Hº“H›QPÊ¥\ЬbÓ¬eѬeÏ©^زjÓ±iЬbË£^Å£\ɤ[Ì¥aÛSÁ™TÁ˜TÁ˜OƝTȟVË¢XÒ¥]Í¥]Í¡Uѧ]Ó§aÕ­hׯkÑ©bȟUǜR–QėOÏ£Yש^Ô§ZÒ£UÏ R͞T’G¼†?¸„;«x7§v4£u0¡q.g&c$ƒWwNqKaA aB aB +gDnGqKuOrMtLqKrKsLsLtM vP$pJlG`<P3Q6L1C)@'C* :"9"7#6 8#<&8">%B(C'M+L, M- L+ M-Q. Q- N. H*F)M/ X3a7c:b8j<sD!rCj<l<p@sAj< f7h7j:d3d5`0]/d2g4j8g5i7p>p@l<g6l<qAwFN…TˆWˆW‹ZZ^Ž]‘a•c]‡U‡S‚P„["€^'hQ#[M!ZN$]P*[O(cU/dX2rgDÁ¶¢ÚкÛÒ¹ÝÔ¼ÛÓ½ÚÒ¼ÛÓ½ÛÓ½ÝÕÀß×ÁàØÂâÚÅáÙÃáÚÄß×ÂàØÃáÙÄâÚÄäÛÉãØÇãØÈäÚÉâØÆåÚÉãØÆãÙÇãØÇäÚÅâÙÅâØÅãÙÅãÚÅáØÃá×ÁâÙÃäÛÆá×ÂäÛÅâÙÄâÙÃáØÃáØÂáØÂà×Âà×ÂßÖÀà×ÁÝÕ¾ÝÔ¾ÛѽÚмÛÒ¼ÛÒ¼ÙкÜÒ¼ÞÕ¿ÝÔ¾ÜÒ½ÛÓ»ÝÓ¼ÝÔ¼ÛѹÜÓ»ÚкÐƪ囸«‘¤”{–†mqMt`>fR7cJ-]G W?K8P=M8U:fM(tV-pO%qN wM†]&g.–p8¨{=¦y>¥x9«ƒ@°ˆC¯‡D®†G­‡G®‰I¥=¦~=¥{5¤;¦‚;¬‰Bµ“I¹”I½šUÁVÀ›SÀœT¾šR¾›SÇ£`Ê¥\É¢VÈ£WÊ¥YŜPÁ™O¾˜RşWʟWÉ Yǟ[śWśUÀ•OŘOřOĖM™N™NŚOШ_ÔªaѧYË£VÎ¥[Ë UÈ¡SÍ¢UÔ¨`Ó¦\Ó¦]Ù¬aØ©Yب[Ö¥VΟKҝRÓ¡ZΛNʕJŕL¿‹=º‡?©z9’g!†]†V…Z„Y€SwPyM|R~U{QyOtIuJvLuNvNoIlEjHgEiL!hM$gL$_BY=[@F.:&6";(8$8#9#<%C&D(B(@%@&H+J, G)F)F(I)K* Q- T. Y2X0 ]4b5c7n;uByEvFq?q= o9 i8l= i9i6k9l: i9k8g4h8h7k9k9n=pBtE +uG}O}RS…Y‹\†V†ZŠ]Ž`“c#Œ\‚RzMtMqS#gO!\J\Q']J&ZO&ZM(aT/ulIÊÀ§ÙÑ»ÛѺÛÒºÙѼÜÔ¾ÚÒ¼ÜÔ¾ÝÔ¾ÜÓ¼ÞÖÁáÙÃàØÃàÙÃáÙÃáÙÃàØÃÞ×ÁäÙÈãØÇäÙÈãÙÈåÚÉäÚÈäÚÉâØÇãÚÅâØÃãÚÂâÙÃà×ÁãÚÄãÙÄãÚÅãÚÅãÙÄãÚÅäÛÅâÙÃà×Âá×ÂäÛÆäÛÅâÙÄà×ÁäÛÅáØÃáØÂá×ÅàÖÅá×ÅàÕÄÞÓÂÝÔ¾ÙϹÝÓ¾ÛÒ¼ÚлÝÔ¾ÜÓ»ÜÓ»ÜÒºÞÔ½ÜÓºÚѸÛÒ¹ÝÔ»ÜÒºÓʳËÀ¥¾´›¬ž…ŸtoNsc>gZ9gT&hR([DX>]<E5 +V9W:b?qHyS$‡^'‹]!”e-™n.¡v5¥y7§|8®=®„A­†A¨€@ {4¦‚:¤:¥ƒ<¦‚;¬ˆB²F½šX¿›S»—K¾™T½›X¾œ\¼˜P¾šQ¾›U¾™P¼•Mº’Iº‘I»“IÀ”IǙPƝZƙTřRÀ˜NÀ–KÁ•JÁK¾‘CÁ”AǘJË RΟRʝOΣTÒ¦XÐ¥TÑ¥WÔ¨ZÔ¨[Ó¥]Ô¦^Õ§]Õ¦[Ö¨ZÚ­aÚ­_ß±bÜ®eÚ«^بVبYÖ§XÔ£VǘGÁ’E¾ŽA»Œ?²„<©y1›l&`!ŠY‰\‡X }T~SuLxM|QyRpIaAmCnMwY.{a7‚g;€b2uS*tR'qQ#\BI4 D2 H1 E-A*;'@(@'>%<%;%8"9 =%?%?%B(C'E)H*P- R0 R. Q,U. X4 a4 q9t>t=vAu=v<u>uCs? r8wA uA vB s>s>m=i9f5m;p@q? i<g= oG qHoFwOvNtLtNyQ€[ˆ^„XvL +tItOiP#bN"[IXJ"^Q-_R-]R'e[2ˆbÌæÙ϶ÚиÚзÙÒ¹ÝÕ¿ÜÓ¾ÛÓ½ÚÒ¼ÛÒ¼ÞÖÁáÙÃâÚÄâÚÅà×ÀâÚÆàØÂàØÃæÛÉãØÇãØÇäÙÈäÙÈçÝËåÚÈâ×ÇâØÄá×ÅäÚÈâØÄãÚÅãÚÅâÙÃãÙÄãÚÄâØÄäÜÆåÜÆãÙÄäÛÆãÚÄãÚÅãÚÄãÚÅâÙÃáÙÃâØÃâÙÃâÙÃßÕÁâ×Æá×ÅâØÄá×ÂâÙÃßÖÁßÕÀÞÕ¾ÛÒ»ÝÓ»ÞÕ½ÛÒºÞÔ½ÞÔ½ÜÒ»ÞÕ½ÝÔ¼ÛиÞÓ»ÜÔ¸ÚÒ¹ÜÒºÖ̲ÑÇ°¿¶œ³¬‘ž’s~]„qDxa>oU.ZI%ZAY@Y;]=dAkGqNyU„](‰_)šr8šp0¡y7¡t3¢x5¥|=¦€>¥>¢}:£~7 {4§>®ŒI³‘M®I¯‹G±K´‘P±N«‡D·’Q¶”O·“O³M²F´ŒF°‡A¦}9­…@µ‹K­‚?µ‹I»’L¿”I¾“G¿‘H¾‘FÁ“GØEʜMɜPʞTϤWÐ¥ZΣV̝L͟RΠXΟVÒ¤\Ó¥\̞U̝PÏ¡RÙ¬`ܱ^àµgÞ´fݱ^Ú­`שYÓ£QÔ¥RϟKʛJțJəJȚP¾‘D½F¸ŠH¤x3 o,Žb#S|QW€V}WsMa<e@ fFhLwX"‚^.…a.‚]-Z(~\'jKaGX>]CY?O5P:O8F-@*C, +A*?) @*=#=&8 <$=$@'B'G+I,L+H(G'J)P- V.U. a5b5 i8 n9l5o< t?r;wB {GyBzD +}HvE zHxGwEtD j<e;e= mFiA +kBlFjDiA hA h@ qFtNnH_;`?^E`N$ZK#YO#WJ"ZM(^Q+\P(cW/”‹nÔÍ´ØϹÚѹØϵÙйÚÒ½ÛÒ½ÛÒ¼ÛÓ¾ÝÕÀß×Áß×Áà×ÂàÙÃß×ÃßØÅÝÕÁàÙÆäÚÈãÙÈäÙÈäÙÈãÙÇâØÆâØÇãØÇåÛÊäÙÉäÚÉãÙÈàÖÁáØÂãÙÄãÚÅáØÂâØÁåÛÇâØÈäÛÆâÙÄåÛÆãÚÆáØÂáØÃåÜÇãÚÇâÚÆäÚÆáØÄáÖÅáÖÅâÙÃãÚÅáØÂâÙÃà×ÂáØÂãÚÅâÙÄßÖÀßÖÀà×ÁßÕÀßÖÀÜÓ½ÞÕ¿à×ÁÛÒºÝÓ½ÝÓ½ÛÒ½ÜÓ½ßÖÀÝÔ¿ÜÔ½ÛÒ»×δÖγǻŸ¶©§–}“„b‡rW}b@mY6gM)aD^@gMgM!\=hFqO‚[$ƒ^&Žf0•j2”h1v9¥?¦=£z9žx6¤~>¨„A²K«ˆF§ƒA¨ƒB¨„@£~6 ~;Ÿy7§ƒ?­ˆA°L¯ŒK¬‡E¨„>£~:¤~<¡x6¦}<ªA±ŽLº’NÀ•L¾‘H¿‘C¾A¸‹<À>ĘJƜSÊ YË¢XΣVɜJʟLƙI˜JΟTΠM˜LɚIȘG̝NΠMÒ¥QÔ¦SФQΡMУPÒ¥SѤPÒ¡N˘Hœ@ĔA”EǚLǚNŘP¿“J¹‰A¯B«<Ÿr0•j*Š^Š]~VtMvMrH nLoGuMrKvO{V#xSrLjIqMoIiEbE\@[<X:V8 Q7 P5 P7U9P5 C+@(=#?#@&A(?%D*B(A'?%?#C&D%E(F&S/X.Z/[/^1g7l:vAwAyA zD}HƒJ‚JGJ‚R{M|MwMxLrHrJrLqKjEhA a9 g: f? `< Q2O2T<YHVG YM"^Q,_R/ZN)]Q+dW2£™xÐÉ«ÔÌ´ØÏ·ØϵÛÓ½ÙѼÙÑ»ÛÔºÛÓ¾ÞÖÀß×ÂàØÃß×ÁÝÖÀß×ÂàÙÂÞÖÀß×ÂâØÇãÙÇãÙÇäÙÈãØÇäÙÈäÙÈâ×ÆáÖÅäÚÅâÙÄäÛÆãÛÅâÙÄâØÃâÙÃâÙÂáÙÂãÚÄâØÅãÙÅäÚÅäÛÆåÛÇåÜÆäÛÇãÙÄåÛÇâÚÆåÜÆãÚÅâÙÃãÙÇäÛÅäÛÆäÛÆâÙÄâÙÄåÛÆäÛÆãÚÄâÙÄãÚÅåÜÇäÚÅãÚÅáØÃâÙÃßÖÁÝÔ¾ßÖÁÝÓ»ÝÔ¾ÞÕ¿ÜÒ½ßÖÀÞÕ¿ßÖ¾ßÖÀÜÓ¼ÜÓºá×ÂÛÒ¹×δÍĪ¿³”³§Š£”uŒ}U|i=yb0sa=^F!ZCcEdAeDkErI‚X(i8™r7Ÿv8¡w3 w7£}=¨‚A«†D«ˆG¦=¤}=¤€<¤~7žv4t5—q-žy4¢};ª„E£~<¦‚<¨‚B¥C¤=©€@©€@¤€AµN¼“P¼’L¾•I½•I´‡<·‰6®„2³‰@´‡A¿“JřRŗKɜJʞOǗHʛMТSÏ¡LʛNǕFœCƗMŕGǘIəJǛLȜN•EŖGʙGǗFǘDƕC“I¾B»ŽA»ŽB¹‹?Á’IÖQ¼’H»K±ˆC²…@­~8©z/¡t,˜k#b„WRRzRƒY‡\"„^%…YV!…V…UzLmG ^=^>fClHpN!cJaEeK^CR6 L4 N5 +O4P4L3 E+>&>%>%>%9<";:< C$K%N&N)Q)X-V*[0 `3 e5d6 g9 pA{IxCƒO…R!†V#S!†Y&†X †X ˆ^$…^Œf/…a+|T"nKnMlIc; T6K1P7 UDXHWK [N)]P-^P+`T,g]7³ª‡ÒɪØϸÙиÙѸÙѹÙѼØкØѹÚÓ»ÝÕÀÞÖÁßØÂÞÖÁÞÖÀÞ×ÀàØÃáØÃß×Áâ×ÆàÖÄâ×ÆáÖÅâ×ÇãÙÈãÙÈâØÆà×ÃâØÃáØÂáØÂáØÃâØÅäÙÇãÙÅãÚÄâØÇâØÇãÙÅäÛÆâÙÂâØÃäÛÅæÝÇåÜÆäÛÅäÛÆåÛÈãÛÆãÚÄâØÃãÚÆâÙÃáØÃãÚÄâÙÄãÚÅãÚÅäÛÅäÛÆåÜÆäÛÆæÝÇäÛÆæÝÇæÝÇåÜÆäÜÅãÚÅãÙÄßÖÁà×ÁÞÕÀßÕÀßÖÁàÕ¾ßÔ½ÞÔ¿ÛÒ¹ÝÔ»ßÖ½à×½ÜÓºßÖ¾àÖ¾ßÖ½ÚѸÒʭȾŸ·ªƒœp‰yYyjGqY1mP&cM ]C^= d?nM%[+‡\'“h/—p9›s5 y8 ~>¨ƒH©~?§~@¬=¨:£~8žy6šu/–p-šu3›v8Ÿ{=¤~;§A¦‚A¦‚A¦€A¦=£>­ˆG¯‹KµŽF·‘F½–Jº‘D»‘A´=­ƒ7«5¯€5«8±ƒ=µ‹>ºD¾DƖJ͞U͛KƖE’E¾C·†:»‹:À‘BǛLəJƗGĔGÀC¹‰:¾‹7À‘;ɛHÔB»Œ8¹Œ>¯3³ƒ8´‚:°=°„7½BÔLǚTǙS¿‘G¹ŒB³†=¸ˆ:´‚3°~5¦v4žt1o,l'Ÿp-œn(žn,›l)˜f(‘b ˆ\ |TxQuLvQrMkLhImLiIfGjJkJa@W;W; X<F.?'>&A(B(;#<"78<"@#A$D$F%F'K)J)L)N,Q/P.X7 _5`5 h=uGwIO"€T$ƒS!ŒY"a(’h/“k2j0Œc+Šb.[&X#pKjE`AX@WFTHXL#ZM&\O)\O,bU/xmN½¸ÕÌ°ØиÖηØγÙÒ¹×зÚÒ¼ØкÚÒ¼ÞÖÀß×ÁÝÕÀáÙÃÞÖÀß×Àß×ÂÝÕÀÜÔÁâØÆá×ÆâØÆáØÅá×Ãá×Åá×ÅãÚÅá×ÂãÙÆá×Äâ×ÄâÙÃâØÄãÙÄäÛÆáØÂáØÂãÚÅáØÄáØÂâÚÄâÙÃâÙÃãÚÄáØÃâÙÄãÚÅãÚÄâØÆáØÂãÚÅäÚÇäÛÆåÛÇãÚÄãÚÅäÛÅâÙÃåÜÆãÚÄåÜÇæÝÇåÜÇæÝÈçÞÉåÜÇèÞÊæÝÈåÜÆäÜÆåÜÆäÛÆäÛÅâÙÄáÙÃà×ÁßÖÁà×ÂßÕ¿ÞÕ¼àÖ¿ßÖ¾ÝÕ¾àÖ¿âÙÀÞÕ¼àÖ¾àÖ½ÞÕ¼ÝÔºÛÑ·ÔÈ®ËÀ¨½²•¤šr’†`tLmY1eO*bP$`HiJlJoL€V'‡`.•m3–n/šn0£w<©B«@¨;­„A¨=Ÿy7x8—s2šv7w8¡z= {>Ÿ{> x=œx9£@¤B§„D«„D©„<¤ƒ;ª‚6ºE¼”H²ˆ?«5ª€4©}6£w0¨z2«}4©{3·ˆ>¹ŠBÁ“IėL¼E·‰Dµ†;­/³†3¶ˆ2½Ž?Á’DĔGǗKÁ“B¼‹6º‰6¿‘?ŖCŕDÓCÁA¼‰?²ƒ6©y/«}-´†9ÔIțPÍ [ʛSŗIȘNϟ[əGʚFșIʚQŕHÁ’A½‹B°4©x/§v.¥r(¦r+ o,žl'™j%Ž`‚VxRsMnMlJiElHzS"xTuOkHsNvPbCO7 R7 Z<R5 P4 P8 C/ +:(@(B(E+H*H*G*G)M,L-I*G*I(J*K(O+O*X2b9h= h?qE{LƒX#„W!ˆ_(c0b.Ša-‹`+‚X!~M|NqI`HTCUJWJ"ZO$ZM(^R-`R,‚xXÿ§Õ̳ÖεÖκÚкÙлÙÑ»×ϺÚÒ¼ÛÓ½ÝÕÀÝÕ¿ÝÕÂÞÖÁÝÕÂß×ÄÝÕÀß×ÃÝÕ¿áÖÄßÔÃÞÔÂà×ÄáØÂà×ÄáÖÅá×Ãá×ÂßÖÁáÙÃãÚÅà×ÂãÚÅäÛÅåÜÆáØÃâÙÃáØÃâÙÃáØÁáØÃâÙÄãÙÄãÙÄäÛÆäÛÆãÚÅãÚÄâØÄãÙÇäÚÇåÚÈäÚÈãÙÈæÜÈãØÆãÙÈçÝÉäÛÆãÚÄåÜÆåÜÇæÝÇèßÊæÝÈçÞÈæÝÈäÛÄãÚÅåÛÆãÛÆäÛÅåÜÇäÜÆçÜÊãÚÇãÚÅäÛÅáØÃà×ÂàÖÁà×Áà×Áà×ÂÞÕ¿ÞÕ¼á×¾ßÖ¾ßÕ¿ÞÕ½ÝÔ¼ÞÔ¼ßÖ½ÜÓ¹ÛÓµÕϵÌĬº±–®¢ˆ›‹k‡xTp_5jV.gP(eEdDxR|RR!‹]*`&–h,žn4žq5¦|?¤}@£{;§D¤GŸw;Ÿw;—n3št8šr6šs:›u< |B£{Bx:›w5šu.—r)¥~8­…;ª‚8ª€6ª7¦~5¬ƒ8«€:¨|9¤x3¨}8ª€:¬‚6·ˆAµˆ=¯†@¯8©y,°€6¯6µ†;·ˆ=¿’D»C½=¾Ž=À?¿‘=Ŕ@ƕCǗIÓAŗI•C¼ŽC«‚4±6»Œ@ƙK˞T͞U͞R͞SƕJΝNÑ¡Oש_ש`Ù¬^Û­`Ù®ZЦW˞Nº‡5ºƒ/¶ƒ6·…=°6¬|1ªx2žm!—j&Œc!e,‚^&~X!{S|R|S|U€W%ƒX ƒUzUqKqK"hFhFoNdB`CR;R8 S7 S8N4 H*I+H-G*H+H+E'E&I'A$E'G%O.Y5\6[8 [7b; hBnFqKwOwPyO!€S |P{L{R vT!fMUFWJ$VI"YK&YL'\P*_R-’‡lɨ×͵Ö϶ØÑ»Ùз×к×ϹÙÑ»ØлÛÓ½ÜÔ¾ÜÔ¾ÞÖÁß×Âß×ÂÜÔÀÞÖÄÝÕÁÛÓ½ÜÓ¾ßÔÃßÕÃàÖÄàÖÃÝÒÀßÕÃá×ÅàÖÄÝÓ¿â×Åà×ÂÞÔ¿á×ÃáØÃãÚÅäÛÅâØÃãÚÅâØÄà×ÃáØÃßÖÁâÙÃà×ÃâØÃäÚÄãÚÅâØÃâÙÄãÚÅá×ÄãÚÅæÛÊäÙÈæÛÊåÛÉäÚÈæÜÊåÜÉäÛÆæÝÇæÝÇçÞÊæÜÈæÝÆæÝÈæÝÈæÝÈãÛÅåÛÆåÛÉæÝÈçÞÈåÜÇåÜÇäÚÆäÛÅçÞÉæÝÇâÙÄåÜÇåÜÇäÛÅâØÃâÙÃàÖ¿ßÖ¿àØÀâØÂà׿ßÖ¾á×ÀáØ¿áÙÀßÖ¿ßÖ¾ÞÕ¾ÝÓ»ÜÒ½ÔʱÐūúž¶ª™ŒmˆyQxc6jY-jN d?iEtMyO†Y$‡]'‘d.˜k4œo3¥zC¨}C©€E§€C¤|A y>v:u9žw8Ÿz:žw7œv7šu4–q+”n+žu/£z2£{.¥|4¨‚9¦‚:¯†=²‡C¨‚A¥v-¦|6¡w0žo#£t,¤w.ª8¬‚5«€3±†>²‡A¶‹A¹Š=»‹@¼Œ@À“DĔDÓCƗFəHȗCĖHƘJʞPǜNęM¼D¹‰>¸Š9·‰<”EĔI˛KÒ¤UÖ©[Ò¥S׫XØ«WТPÒ¤Uت^Ü°_Ú¯`Ö¬YϞJɗAœ>ǖEɘG̛LʙMœH»‰;³4¨z2£u3›r,—m.“f#‹[…WˆZ!Š\&‰[„XS€V#qIpJmHmJjElLwW#rRgGZ8 Y8 \@R8V9P2L4 E*B%D(K+N.H)N.O0P1M-R0T3U3 X5 Y7 b> [: a=b=gClIoQ#mT&fM"YHXK#XG\J'[N*_S5dY4šŽnÔÊ°Õ̲ÕͳÔ̶ØÏ·ØѹÛÓ½ÛÓ½ÜÔÁÜÔ¿ÞÖÀÞÖÂÝÕÁÝÕ¿ß×ÂÝÕÀß×ÄÞÖÂÝÕ¿ÝÓÂÝÒÀÝÓÂÞÓÁÞÔÁÝÓÀßÔÃÝÒÁÝÓÀÝÔÀÜÒ¿ßÖÀÞÔ¾ßÖÁß×ÀßÕÂßÕÃßÕÂãÙÇãØÇâ×Æá×Âà×ÀàÖÁàÖÂáØÃáØÂãÚÄãÙÄãÚÅáØÄâÙÃãÚÄãÙÈäÚÉåÚÉåÛÈæÝÈåÛÇåÛÈæÝÈåÛÆçÞÉæÝÈèßÊåÝÅåÜÆçÝÉçÞÉæÝÈæÝÈäÜÆçÝÌçÞÉæÝÇåÜÆåÜÆåÜÇåÜÇæÞÈæÝÇæÜÊåÛÈæÛÊæÜÈæÝÈãÚÅæÝÇäÛÇäÛÆáØÃâÙÃàÖÁá×ÃàÖÁÝÔ¿à×ÁßÖÁÞÕ¿ßÕÀÛÓ¾ÝÔ¼ßÕÀÞÔ¿ÔʲÐƨƼž³®§žx‹€]wh=cO$cJgGiEpH|Q ‚X‹b,“g/›o;¦zHŸ{E¢z@œs9œt:›t:žv:žw:Ÿw<œv7—p.—q.“n(˜s+ y/£}8§ƒ>¦‚>©ƒA°‰H©„B¡|:žw4št.›q.—n+˜n)Ÿu0¥{-«5°…:¸ŠD¿HÀ’GÓG“C“DțMȚI̞N˝MʝIǚLƛLřIƙGǚH¾”H¿‘D½ŽD»Ž>¼‹?½A¿<˚KÓ¤TتVßµ_ß·^Û°_Ï¢NѤPÓ¤RÔ¥RÔ¤PÑ¡N͞K̝G˙FΞKÓ¥QРNÓ¤QÓ£OÔ§UУUʛL¼A¶‹J°;£q.•f!—i'—h)“c ^ˆXƒZyPuMqKnNqM['Ži0†d/xU"aDgLnT&wY2nP&bES8 +L.F.L4X:O0K-F(F+F(G,J.K-O/N-R1P/S2U3Y8 Z8 `?dJ`N"aN#XGRBSEXL)YN+^S3gZ:ª¢ˆÎÅ©×δÕÌ´ÖιÚÒ¼ÛÓ½ÜÔ¾ÛÓ¾ÜÔÁÞÖÁÞÖÁÜÔ¾ÞÖÂÝÕÁß×ÄÞÖÃÞ×ÄÞÕÀß×ÂÛѼÜÒ¿ÜÒ¿ÝÒ¿ÞÓÁÝÒÀÜÑÀÜÑÀÜѾÛÒ½ÜÒ¿ßÔÃßÖÀßÔÂàÕÄàÖÄàÔÄàÖÅá×ÆãØÇá×ÅãØÇâØÇá×ÅàÕÃáÖÄâØÆÞÔÀáØÂâÙÅãÙÄãÚÄãÚÄäÚÈçÝÊæÛÊåÛÇæÜÇçÞÉäÛÆæÝÇæÜÈåÜÇæÝÉèßÉåÜÇæÝÈçÞÉèßÉçÞÉèßÉæÜÇèßËéáËåÜÇæÝÈçÞÊåÜÆèßÊæÜÊæÜËèÝÌçÝÌçÜËéßÎèÞÌæÜÉæÝÈæÝÈåÜÇæÝÈãÚÅåÜÆãÚÄâÙÂá×ÂàÖÁáØÃà×ÁàÖÂßÖÀÞÔ¿ÝÔ¾ÞÔ¾ÝÓ½ÜÓ¼ÝÓ¾ÛÔ¹×έÐɬŻ ¬¢}Ž„]ndɘFÓ¤S׬Wݳ`Û®_Ù­YÖ©VÖ©VÚ©XÑ£OΚDȖAÁ‘;Ŕ@ĔA͜HÑ£PÔ§SÚ­[Ù¯^Ø­]Û±cÙ®^×­\Ô©]Í£YțRŗNÁ’H¿F¶G±ˆBª9Ÿo)šp1“g.šo6žx@¡|Cžw<¢|H¡I™vA‰k:y['pQtPvUƒf2†j2i4ˆb0~Y*sM'hB^>[<V9S2Q2S1\8Y8 +U5N0O4S6U: +X=aI`L VH"UH!WI&XL*ZO1_T6znQ¿¶™Õ˱Ô˳ÕÍ·Ô̶ÝÕÁÜÔÁÛÓÀÞÖÁÞÖÀÜÔÂÜÔ¾ÞÖÂÜÔ¿ÜÕÂß×ÄÞÖÃß×Äß×ÃÞÖÃÝÒÂßÔÂÛÒ½ÞÓÂßÔÂÞÔÂàÕÄßÕÀÝÓ¾ÝÓÀßÔÂÝÓ¿áØÂá×Äá×Åá×ÆäÚÈãÙÈâØÅãØÇäÚÉäÚÈäÚÈæÛÊåÚÉæÛËæÛÊäÚÇãÚÆãØÈæÛÉåÚÉæÜËçÝËçÜËçÝÌèÝÍçÝËæÛÉåÚÉåÜÊæÝÉçÞÈçÞÊéßÍæÛÉæÛÉæÝÇéáÍçÞÉçÞÉçÝÊçÝËçÝËæÝÊèßÌéßÌçÞÌçÞÍæÞÌçàÍèàÏçßÍèßÍèÞÌçÝÊèßÊçÞÉåÜÇèßÊçÞÈçÞÉçÞÉæÞÉæÞÉåÜÇæÝÈåÜÇäÛÆåÜÅæÝÇãÚÅäØÂâØÂáØÀâÙÄâÙÁÞÕ½ÜÓ»ÛѺÙзÓɯÔ˲ÚÒ½äÚÃãÛÃÞÖ¿ØйÑƬÈÁ¨¶¯ —s„[ˆvRya;w]4sS'ƒW)_/b-Žc+–j2žu=Ÿx> y;¡x9Ÿv:žu8w7œu6v9œu8˜r1™r6™s5w7žv9œv8¦„B«†G¨‚<¤;¤:«†<²‰>²ˆ:¶‹@”JțRʝMɝKÁ‘@½B·‹<¾BǚLÎ¥TͤVƜRÙNÀ“F½‘C¹Œ=»?¼Œ:º@»?À‘CÓEƕE̞PРNÒ¥RÓ©TÙ¯^Û¯\Û°[Û±cÙ«ZÖªWÔ¥QÏ M˛F̜GПHÓ¤QÒ¢PÔ¤RÖ©VÔ­`×°^Ù®_Ö¯dÕ­dÓª`ÓªaѨaˤ[ΧaÊ£\ƝSřQ–S¿H³‡Fª„Bª€D«|<ª=¥~@˜s5Œk5|^%}[Ši6‘t:™zFŸ€C˜x7k2ƒ^(uO kEjEbA_A]; +Y8gBnGc? +W8 J/I0L1U=W?[GZHRCUH"UH"XK)[N._T5‹‚dƼ¡ÓÊ°ÕÌ´ÒʲØкØйÛÓ¿ÛÓ¿ÜÕ½ÜÔ¾ÜÔ¾ÞÖÀÝÕÀÚÒ¼ÛÓ½ÝÕÀÞØ¿ÜÔÁÝÕÂÝÕÃàÕÄÞÓÃà×ÂßÖÃàÖÄàÕÄàÖÃàÕÃâ×ÆáØÆàÕÄÝÔ½áØÃãØÇàÖÄá×ÅãÙÇåÚÉäÚÈåÚÉäÙÈâØÆåÚÉçÞÌèÞÌçÝÌçÞËæÞÈèßÌçÝËçßÌèÝÌçÝÌéßÍçÝÌçÝËæÜËçÞÌæÛÊèÞÍçÜÊåÝËçÜÊæÝËçßÌæÞËåÝÉéßÊêàÏéàËèÞÊèßËéßÍéßÍéÞÍèÞÌèÞÍéàÎèßÍéàÎèÞÍêáÏéáÏèÞÍèÝÌèÞÍéßÌéàËèßÊçÞÈçÞÉèßÊéàÌçÞÊéàËæÝÈæÝÉèßËèÞËçÝÈåÜÇéàËæÝÈåÜÇåÜÇãÚÄâÙÄàÖ¿ßÕ¿ÜÒ»ØεÔʯÕ˱ßÖ¿çÝÈæÜÇãÙÃàÙÅßÖ¾ÞÔ¿ÜÔºØϵÑÈ«Å»¡»´—©Ÿ’‡bjC{d@}_6ƒ_,ˆ_,”l;›r9œs7Ÿt5›s7u9¡x=¡z;¤}=£z?¢z>u6Ÿw8Ÿv6t9Ÿy9 z:¢{>¥|=¦}9¦|8ª;±ˆA´‹B¸C»‘F¾F¿‘H¾E¹‹>ºŒ=²„0»ŠAÀ•Kϧ[Ò¨\Ê¡T˜P–KÖFÀD¿‘CÓC¾Ž@Á‘B¾Ž>‘BÀ@Á’>ƗAțKÑ¢QÕ©VתSתVÙ­[Ù¯Yܱ\Û°^Ú°\תT׫YÔ¦TѤQÕ¨XÔ¨VÓ¨XÖª]Ö¬_Ö«^Ö¬bÑ©_Òª_Ö­dÕ«dÒªbШ`Í¥^̤ZÍ£[ЧcÍ¥]ϧb̤_ǙW»‰F¶„@¬{3Ÿt,–j+g$Žd˜r5¢~F£D£B•r.Œf*}WwQrJoHkE jD dCoHTxSrM\< P5O3U;U=V>bK]IQEPBVF!VJ&YL,\P3šŽqÎĨÒÊ®ÕδÕͶ×ϹÛÓ¾ÛÓÁÛÓ¾ÝÕÃÜÔÁÞÖÂÝÕÂÛÓ½ÝÕÂÚÓ¾ÛÓ¿ÛÓ¼ÝÕÁÜÔÂÞÖÁáØÃáÖÄá×ÅáØÄáÖÅãØÇá×ÄâØÄãØÇãØÇäÚÉá×ÆäÙÇãÙÈäÙÈãÙÈãØÇäÙÈåÛÉæÜÊåÛÉæÛÊèÞÌèÞÍçÝÌæÜËéÞÍçÞÌèÞÍéàÎéßÎèáÍèÞÌèÞÍéàÎèßÌèÞÍçàÍçßÍéàÌåÝÇæÞËæÞÌæàÌçÞÍéáÎèßÍêâÎéßÍéßÏéßÍéáÌêáÌëãÏêáÏéàÎëâÑéßÍéßÎéàÏéßÎéßÎéàÏéßÎéáÌéßÎéàÏèßÌêâÍéàÊêáÍéàÍêàÏéßÍéßÍéßÌéßÍçÞÌéàÌçÞÊæÞÈæÝÈæÜÇçÞÈæÞÈåÜÈåÜÇãÚÄßÖ¿à×ÁÝÔ¾×ζÕ̵ãÙÅèßÊæÝÇáØÀãÙÃÞÕ½ÞÓÀÞÕÂßÕ¿ÜÒ¹ß×½ÝÔ»ÙÑ·Óʮ̧À¶˜´¨‰¬™uŸ‡e™V–xG•t=o8—p:’f.˜k3žq8£u:¤x>©~C¥z<¨}?¡v7¤y= x<œv7›u0r3¤z8¦}6¥~9©;¶‹A·‰>ºŒC¼ŽD·‹A¶‡;·‡9®3²…5¶ˆ;Á•IÊ¡VÔ¨ZË£UÉ¢UƜP–IÁ”E“JƙKǚLƖJÖHÁ‘B“C“BÓB¾@¾?̛LÒ¥NÖ§WѦUÔ§VÑ¥]Ó§VØ«[Ø­\Ù­XجWØ«WÚ­ZÖ«W×­ZØ­^Ø­]Ö­^Ö­aÒª]ѧ\̟TФVϦ^ͤ[Ê¡WÊ¡WÊ Wϧ^Õ­dÕ­bÕ®eÓ«`Ò¦_ʜTÁ’Hºˆ?¶…?¬{2§{:£y3£x6 {7 |<”k'Œe'ƒY„^#|TwOpJjGqM}W$‚Y%|TwSgH\<U5 X=[A]DbK aK L=OCSE VL*_S6bW9¤š‚ÏƱÓ̱ÖÍ·ÓË´ÜÔÀÚÒ½ÜÔÀÜÔÁÛÓÀÛÓÀÝÕÁÝÕÀß×ÁÞÖÀÛÓ½ÜÔ¿ÝÕ¿ÜÔ¿ÝÕÂàØÆàÖÆâØÇáÖÅáÖÅâØÇâ×ÆãØÆãØÇãØÇâ×ÆäÙÈåÛÉäÚÈåÚÉãÙÇåÚÉäÚÉåÚÉäÚÈåÛÊäÜÊåÚÉåÞËäÝÊèàÍæßÌèàÎåÞËèàÎèàÏèßÍèßÍèáÏæßÌèàÎêàÏéßÎéáÏçàÍçàÍéáÏéâÏéáÏèàÌèàÍèàÍèàÊçßËêàÏêàÌèáËêâÎéàÌêâÐëäÑêáÎëâÐèáÏéáÏèàÎçàÍéâÐéáÏèàÍèßÍêàÎéàÎêàÏêâÍèßÊéáÊêâÌéàËêàÍêáÍéáÌêáËëâÌèßËèßÊéàÌèßÊçßÊèßÊçÞÉèÞËåÜÆáÙÃâÙÃâÙÃßÖ¿ÚмÚмåÜËêàÏéàÍæÜÊäÚÈâÙÃàÖÄâÙÆÞÔ¾ÜÓ¹ß×½ÜÔ»ÝÔ»ßÕ½âÙÁà׿ß×¾ÚзÕ˱ͨø™¹«†§”h ‰_‘wI“r>Žm9–n:žu@¥|HŸw;¥|C¢{C§}C§~C¥{?¡w8¤z:¦|=§{9§|<¦z9®ƒ@°„<±ƒ8¶‡?·ˆ@µ†=·‡<´‡<´ˆ<¸‹;ºŠ>¾•JțPƜOÉ¡VǞSěQ—K¿’E•GǗKǙMǙOĕJ×J¿’C½Aº>»@»A½=Á“H•HÀ‘GĖK•EǘH͞RÖ©[Ú¯[Û¯_Ù­XÛ¯ZÚ¯[Þ´cܳcÙ²bÚ³hÕ­bΤZË¢WÉ QШ\Î¥]Ë¢ZÉ UȞTʟUÍ¥[Ó¬dÖ®eÓ«bѧ\Ó©`Î¥\̟SśQĘN»’I³‰<´†=­7¯ƒ:¦{3šp'˜n#–k-”k,‰_~UzSzS€X€W~VwPnKb?fEfEdEZFgO ZGL=PE$SF%VK(YL-laC§¢‹ÒμÔ˲ÕÍ·ÖθÙѼÙÑ¿ÛÓÀÛÓÀÝÕÂÛÓÀÝÕÂÜÔÁÛÓ¿ÞÖÃÜÔÀÞ×ÅÝÕÃÜÔ¿ÞÖÁßØÂáØÆßÖÄÜÒÁÜÑÀßÖÃáÙÇáÙÇàÖÄâØÇäÚÉâÙÇæÜËäÛÉäÚÉåÜÊäÜÊãÛÉåÜÊãÛÉçàÍåÞËçÞËåÝÊæßÌèáÍèàÎæÞËçàÌçàÎèáÎçàÍéáÎéâÏêâÐèâÏèßÍèàÍéâÏèáÎéâÏçßÍèàÎèáÎéâÏéâÐçàÍéáÎéáÏéâÏèàÍçßËêâÐêãÐéáÏêãÑëäÒëãÑêäÑéâÏéâÒêäÑéáÏêãÐêãÑéßÍëáÏéàÎëâÑëãÎêáËëãÏêàÐêáÐêàÐéáÏëâÍêáÏéßÎéàÏéßÎéßÎéßÎéàÌéßËéàÏçÝÉæÝÇæÜÇäÛÆáØÃÝÓ¾ÝÔ¹ÜÒ¿èàÌìäÑëäÎêâÌèÞÉåÜÆãØÆàØÁáØÀÜÓ»àÖ½ÞÕ¾ÞÕ½ßÖ¿âÙÂãÙÂáØÀâÙÁà׿à׿âÙÄßÖ¼ÚÒ¶Òɮǽœ¾±®Ÿz£l–Yœ|NšzF |D§J§~H¨€F©EªE¨~A¯‚Fª€B¤x7¦y9¦y;¨|8ª~8¯ƒ:³„<³†?¯…:´Š?²ˆ=µŠ=ºD¼‘G½FÁ—LÁ—LÁ–L×P¼L¿‘G½C’H•KĖL”JÀ‘G”IĕKÀ’F½ŽD½@¼A¾ŽC·‰;´†9·ˆ=³…2±‚-¹‹?¾’@ʞNʞKФQÛ±]Ù±_Ù°`×®_ׯbرeÚ³iÔ«bÑ©aѪ_Ñ«`Ѩ_ͤZË¢VȟS˞RÊ¡WѪ`Ô­dÒª`ϧZѨ^Ó­`Î¥ZѨ_Ш]Ñ©ZÊ¡SË¡VĚOĚS•N¹D¶ŒA«{5°€B¤w3 u1™n)‘e …^ˆ_$‚Z~XsIlJjIiH`BdJiT%YIRCPC"SF%VK*^R4ocF³ª”Ó̸Ó˶ÕͶØоÜÔÁÚÒ¿ÙѾÜÔÀÛÓÁÜÔÂÝÕÃÛÓÀÛÓÀÜÔÂÜÔÂÜÔÁß×ÅàØÅÝÕÂßÖÄà×ÃÛÒ¾¿µÊ½­ß×ÅàØÆâÚÇâÛÅáÚÇâÛÉáÜÉâÛÈäÜÊæßÌåÞÊæÞÌæÞËäÜÉäÛÈæÞËäÝÊäÝÊçßÌçàÍæÞËèáÎãÜÊåÝËæÞÌèàÍéáÏëãÑçáÍéâÏéâÏêâÐèáÎéáÏèáÎèàÎêãÑéáÏçàÍëåÓêãÐêãÑçàÍèàÎèàÏëäÓêâÐëäÑëäÒêâÐêãÐëäÒêãÐêãÑëåÒêãÒêãÑëåÒëåÖêâÐéàÎêáÐêáÏëâÐëâÍêãÎêáÏëâÍêàÏëáÐëáÐêàÏéßÎêáÐêáÐéßÍëâÐéàÎéáÏêâÐéàÏèÝÌèàÎçÞÉäÛÆäÚÉßÖÀÝÔ¾ßÕÁêâÎìåÐëâÐëâÎéáÌèßÌèßÊäÛÅãÙÄãÚÅãÚÄãÚÅáØÃÞÕÀß×Âà׿à×ÁáØÂá׿áØÀçÝÇäÛÄáØÀáØÀáØÁÞÕºØγÑʮɾ¡À²‘³¦ƒª–n£d¤†X¥T£„R§G«H¬‚H¨|?§y<¥x;¨y:¤s2£u/ª~9ª~5©|:§{9«<¯„?­ƒ9²‰E¸ŽK¶ŒGµ‹E·Cº‘HºE´‰?´ŠAºD¸ŽC¼ŽC»ŒB½Cº‹A¿FÀ’HÀ’E½A”G¾‘E¿•J¹C¶‰9²„6²„7«~-®‚2²‡4º;Á”?ŖDΡOѬ]ΧVÍ¥XÒª[Щ]Ó¬bѪaÔ®g׳hÓ­dÓªfÌ¥[ͤZȟUȞTϧ\ÓªaШ\Ì£UÎ¥\ϧ[Òª]Óª^Ш[Ñ©^Òª`ÓªaÔ«bÕ®fÔ¬bÑ©_Ñ©_Ê¡VÙP¿–J½“I¼ŽI¸ŽB±‡A§}>Ÿw6–p&j'‡[‚[ tTrRsR%tT&pV&WFI;QDRE#[N.\N.zoS¾µšÓ˱ÕÍ·ÕÍ·ÙѼÜÔÂÜÔ½ÚÒ¾ÜÕÂÝÕÂÚÒ¾ÛÓ¾ÝÕÂÝÕÂÜÔÁÚÒ¿ÞÖÄÝÕÀÜÕ¿ÞÖÂàØÅßÖÁÏǵž”~¾²žÞÖÃâÙÆàÙÆáÙÄãÛÉâÚÇäÛÉåÜËãÜÉåÝÊåÝËçßÍæßÌäÜÊäÜÊæÞËæÞËæßÌæßÌãÛÈåÝËèáÏæßÍçßÍçàÎçßÌèáÎéáÏèáÐéãÒéáÐëäÒëäÑêäÑèâÏêâÐêäÑêãÑêãÑëäÑêâÐèáÎèàÍêâÐéâÐêãÑêãÒéâÌêãÏëãÑêãÐêäÑìäÒìæÔêãÑëåÑëäÒêâÐëåÔëãÒëâÑëâÑëãÒìãÑìäÏëâÏêßÎêàÏëàÐìäÓêãÑêâÐêâÐëäÑêãÑêãÐèáÎéáÎéâÐéâÐçßËæÞÌçßÌèàËæÝÈäÛÈà×ÁÞÕÁà×ÃêáËëäÑìäÓëâÐëáÎéàÍèßËæÝÈåÜÇåÛÆæÝÈåÜÆâÙÄâØÃáØÁà׿âØÀáØÃá×Âá×ÁäÛÃâÙÃáØÃáØÂáØÃãÚÄãÚÄà×Áà×Âá×ÂÝÕ»ØеÒɮʺ™Â¯Œ«œv¬[©‡U¨‚W¢xA¢w<¨~D¥x?¡s7¢r4¦x@¨z;¬|;§{=§|;©|<§{:¨}=ª~A«€@©?µŠHµ‰F¹K¶‹G°…>°†<²‡@²‡>±†;°„9²‚8¯„9µŒ@¸ŒB»DÁ”H–I˜NÙN¿‘B»@¹ŠA¹Š=µˆ8½C¼A¾C¾@ŕG̟VÊ TǜOÌ£YͦXͦYÈ Uɦ[Ñ©]Ó«dЩfΨaÑ©^Ê¡RɟSͤZͤWÎ¥XË¡UË¢T̤VÌ£VѨ[Ѫ^Ñ©ZÑ©[Ѩ[Õ¬`Õ­bÒ«aÖ®a×±bر_Õ®^Ì¥SϤSɝMȟTƞXěQÁšS¹K­‰K¤~7›r0”p6k9‹j:€g1pZ(WGMCPCWK'SG&\M.…}gÄ»¢ÕÌ´×ϹÖθØлÚÒ¾ÜÔÁÜÔÁÝÔÁÝÕÃÛÓÁÚÒ¿ÝÕÃÞÖÃÞÖÂÜÔ¿ÞÖÃÝÕÀÛÔ»ÞÖÂÞÖÁÞÖ¼¬”šŠqøŸà×ÅâÚÇàØÄáØÂãÛÈãÜÉãÛÈäÜÊäÝÊåÞËãÛÉçàÌäÝËåÜËäÜÊæÞÌæÝËäÝÉæÞËçßÌäÝÊæÞËçßÍçàÍæÞÍçàÎèàÎéáÐêâÒèàÑëãÔéáÐéâÐéàÐèáÏèáÎçßÍêãÑéáÏëäÑìæÓêâÐèâÏéâÒêäÔëäÑêãÑêãÏëåÓêãÑêâÏëãÑêãÐëåÓêãÐëäÒéâÐëåÓêäÑìäÒìåÓëäÒêãÑëäÓëãÒëâÑìâÑëãÒêäÑëäÑêãÑëãÑëäÓëäÑéãÐëåÓêâÐéâÏêãÐéâÐèáÎëãÑèßÌéßËæÝÈãÚÄãÙÄßÖÀâÙÃëãÎîèÖìåÑìäÒëâÏêàÍêàÏèßËçÞÈæÜÉåÛÇãÚÅäÛÆäÛÅåÜÆãÚÄåÜÆäÚÅãÙÄãÚÅãÚÅãÚÄãÚÄâØÂáÖÀà×ÀâÙÂÞÔ¾áÖÀâØÁæÚÄæÜÅãÙ¿äÙÀâؼÜѸÕÉ©ÎÁžÆ·–¼ª€³—k¥Š\~M™s<›r=£sB¨x@«|=ª}>«~=©{>¬€A©}>¨}>¦{;¨|=©~=°>«~<¥y7¥y6ª~<¬B«?®ƒ:¯ƒ7­„8³‰?°†;³‰>°‡;¶Œ@¼‘H»‘G¿“GÖL¾’GºŽC»C¼DÁ’H˜HØMÙN™OÛOŚMÀ—IŜRÉ QǝVŚU˜PÊ¡Wʤ\ͤ`Ì¢^ɟYȞUÉ¡YË¢WͤVË¢XÉ RȟSǝRÉ RÎ¥Wϧ]Ѩ\Î¥VΩZΧYΩ[Ϩ]Ô«bÔ«[Ø®b×±_Ö¯]Õ«]Ó¨ZÓ§\Ò¨\̤WϨdΨcÆ `ĚZ´I±‹Q¯‰T¦…N—{Jq[+SFNEPCSH#UJ+]P4ˆ~fÄ» ×ζ×ϹØкÚÒ¾ÞÖÃÞÖÃÛÕÅÜÔÄÝÕÂÜÔÃÞÖÂÜÔÂÜÔÁÞÖÂÞÖÄß×ÂÞÖÀÝÕÀàØÂÜÔ¾×Ì´«™€œŽvÎçàØÃáÙÅáÙÇáÙÆãÛÈãÛÈãÛÉâÛÈæÞËäÝÊäÜÉäÝÊæÞËæÝËçßÌåÝËåÞËæÝËæßÌæÞÌèàÎçßÍçßÌæßÎçàÐåßÏçßÏçßÏçàÐçàÑêãÓèáÑéâÓçàÐêãÔçàÎêâÐéáÏëäÑêâÐéâÏêãÐêâÐèáÏìæÓìåÓëåÒêãÑëåÓêäÑìåÓêãÑëåÓëãÑêäÒëäÑëåÒêäÒìæÔìæÔêãÐìåÓìæÔëäÒìäÒìåÓëåÒêãÐëäÒìåÓìåÓëäÑéãÐëåÓêãÑëãÑêãÎêâÐèáÎéãÐêâÐéàÏéßÎêáÏéàÊæÝÈâÙÃãÙÄá×ÄìåÐíçÔìäÔìãÒêáÐëâÎéÞÎèßÊæÝÉçÞÊçÞÉæÝÈæÝÇåÜÇäÛÆæÝÇãÚÅãÙÄãÚÅäÚÅäÛÆãÛÅáØÀâØÀà׿ßÖ½ßÖ½ßÖ¾áÖ¼ãÙÂãÚÂåÜÄãÚÁçÞÅåÜÅãÛÂæÝÆäÛÃåÜÄÜÓ¼ÕͳËģķ”¸¬ƒ­št«Šc¥Q¥zH¦yE©{@«}Aª|A¬C«~B£w:¦x<£v7¡t6£w7p0žr1¢v4¦w4¨}9­:­ƒ7­ƒ7±‡<³‰@²‡=®„8«‚6¯†9¶ŠE¶ŒA¸@»G»G·@»‘F¾•IÁ—N˜MÁ–KĚPƞQ˜LÀ•I¿•JÁ‘HÀ–KØRÚPǞWÈ¡ZÌ¢^Ê¡WƜSĝRǞSǞQŜQǝNěKěLÚLÙPȝPË¡WÇ TÌ£XË¢VÊ¡UË¢WË¢WΧ\ЩZÒª_Ô¬_×®aÖ®bØ­cÕ¬bÕ¬`Ô¯g×®kЯmÑ®qͪmɤeÅ£`Ÿa¹—[ž‚Ks[+XDTG"TH TG#YJ'eU9šŠqÌìÔͳ×ϹÚѼÚÒ¿ÜÔÀÞÖÃÞÖÂÜÔÂÜÔÁÝÕÂÝÖÃÛÓÁÝÕÂÞÖÄÜÔÂÜÔÁÞÖÀàØÂÝÕ¿ÛӾʾ¥›y¤–}ÓË­ÞÖÂÞÖÄàÙÆàØÅáÙÇâÚÈâÚÈåÝËåÝÊåÝÊæÞËåÝÎæÞËåÞËäÜÊäÝÊæÞËæÞËæÞËçàÍçàÏåÞÌçßÍçàÍçàÐäÞÎçßÏæßÏéáÑèàÐèáÑêáÒéâÒêâÒêâÓéáÑêãÑëäÒêâÐéáÏêãÒéâÒêãÐéâÓëåÔêäÓêãÑëäÕìæØìåÕêäÓìåÕêãÑëäÑìåÓêâÐìåÓìåÓìåÓìåÓìåÓìåÓìæÔéâÐêäÑìçÕìåÓëåÒêãÒëäÔìæÖëäÔëåÒëåÑëäÒëäÒéâÏêãÐëäÑëäÑéâÐêáÏêáÐéàÏèÞÌçÝÍåÚÈáØÂåÜÈíåÒíçÖíåÔìãÒëãÑêáÏêàÏèÞÎèàÊéßËèÞÍçÞÌæÝÈæÝÇåÜÇãÚÄãÚÄãÙÃåÜÆäÛÅåÛÆãÚÄâÙÃáØÃâÙÂà×Àá×ÂãÚÄßÖ½âØÀàÖ¾ãÚÃâÙÃãÙÃáØÁãÙÃãÚÂäÛÄåÜÇåÜÃâØÁßÕ½ßÖÁÙÓ¼ØϯÏšȺ–¿­‰¼¢}²•i«ƒT |R¤}M¦{C¦zA¥yD¢t<¢v;žp5p2n1 s2£w5©~:©=¬€:ª}7²‰@²Š?±ˆ?ª€5¬7§|1¬‚8ª}7¯„8­‚=³ˆ@´Š=³Š?·D»’D½“I¾”J¾“G¾”F¿•JÀ•J¾’G½’G¾”H¾”KÀ—OěWÊ£_É¡^É WśRĜSȟTǝSȞSŜNŜQÀ›MÁ–HÁ“G¿’DÁ–LśOǞSǞSȜOƛLƜOÊ£UͤSͤQУOѨWЩTÒªZÓ«^ϨYÕ®eÙµpÖµrÓ±pÍ«h˧dɧeÄ¢d¸™_œ€EoX'YJRGOCWI%^M,kZ:£–|ÎÅ°ÕÍ·Õ͹ØмÚÒ»ÝÕÂÜÔÁÜÔÀÜÔÁÜÔÁÜÔÁÜÔÂÞÖÃÛÓÁÝÔÂàØÅß×ÃÞÖÁÞÖÁÞÖÀÞÖÁ½³Ÿƒh¯ „ÒÉ°ÞÖÀàØÃÞÖÄáÙÇâÚÇãÛÉäÝËãÜÊãÜÉäÜÉäÜËæÞÊåÝËåÝÌâÚÈäÝÉæÞÌæÞÌåÞÍåÞÍæÞÎçßÏåÝÌçßÎèàÐæßÏéáÑçàÐçßÏçàÐéáÑèàÐéâÓéãÐêâÏéâÏéâÐéáÎëâÏêäÐêãÑêâÐéâÏëåÕëäÕëåÔêãÕêãÓëåÕíçØìæÖìæÖíèÖíçÔêãÐëäÑìæÓìæÓëåÓëåÒëåÒìåÓìçÔëåÓêãÑëåÓëåÒìåÓìåÓìæÓìäÕìåÖëåÕëäÕìåÖêäÔëäÔëäÑëäÒìæÓëæÓêâÏéáÏçàËçÞÉæÜËæÝÇãÚÅæÞÈìåÔîè×íåÔëâÑëáÐëáÐèÞÌèÞÏêáÍéàËéßÍåÜÉæÝÈçÝÉæÜËäÙÇæÜÈäÛÅäÛÅæÜÇãÚÅåÜÆãÚÅáØÃãÚÅâÙÄãÛÅâÙÄâÙÄâØÃá×Âá×ÂäÚÅãÚÄá×ÀáØÃãÚÃãÙÄáØÃâÙÂâÙÁáÙÂßÖ¾áØÃà׿à×½áÙ»ßÖ»ÚеÔÉ­Ñ£Ÿ™´¦‚µ›w¨ŒcŸ…ZŸ{O˜p>›s=¡s<¦x;¤u:¨|=¬?§|:ª~<¨{:©z7­ƒ@®„A©}6ª:¨|5¤y3§|8¥y1§{3¨|5¬9®…=¯…>¸E¶B¹C¶‹?¹ŽC¸AºŒAÁ’H¾“I¿”M¼’M»“N½•QěWÜTÛRÁ˜O¿–MšP›QŚQśPęN›N¾•H¼“JºEÀ•K×MÁ˜HƚOÖIŘIŘNǛOʜNȟPȞOË¢W̤VÎ¥XͤVÓ­bÕ¯j×±nÖ¶rÕ´pͧaÈ£_Ê£cÄ a¶—]—x=kW$VJTJ"SG!UH"`T6l_H±¦×εØк×ϹÙѺÛÓÀÛÔÁÜÔÁÛÓÀÛÓÀÝÕÃÝÕÂÜÔÁÞÖÃÜÔÁÙѾÝÕÁÞÖÄß×ÃÝÕ¿ÝÕÂÜÔÁ«žŠm²¢ˆÛÓ¼ÝÕÃÞÖÀß×ÄàØÃß×ÃáÙÆãÛÉåÝÌãÛÊäÜÌåÝÍãÜÌäÜÊäÜÌåÝÌãÛÉæÝËåÞËçßÎæÞÏäÜÊæÞÎçÞÎçßÏæÞÏåÝÍèàÐçàÐæÞÎèàÐèáÑèáÒêâÒëãÓêãÒèáÏçßÍêãÐéâÏéáÏéâÐëäÒêãÐëãÓìåÔëäÔëäÓëåÕêãÔìæÖëåÔìæÓëåÒìæÓêäÐëåÒìåÓëåÓëåÓëäÒìæÓëäÑêäÑëãÐëäÑêâÐêäÑêäÒêãÒéãÒéãÓëåÕëåÕëåÕëäÔëäÔëãÔëäÔëãÒëäÑëãÓêãÏèàÊæÞÈèàÌèßÊæÝÇäÛÆèÞËíåÕíæÔëãÒìäÒêâÐéßÎèÞÌèÞÌèßËèßËçÝËèÞÍåÛÇæÝÈèßÉåÜÇåÜÇçÞÉãÚÅäÛÆæÝÇæÝÇçÞÉåÜÆäÛÆäÛÆåÜÇãÚÅäÛÅäÛÆäÛÆâÙÃâÙÄãÙÄäÛÅãÚÅåÛÆãÚÅåÛÆãÛÆâÙÃáØÃãÚÅãÚÅà×ÀãÚÃáؾäÛÄäÛÃäÛÁâؾá×¾ÜÔ·ØÏ°Ñƨŷ”»¬„¹¥|ª’f§ˆXœM¦„P±†L³‡M¯‚D­D¨x=¥y5£w9¡u6p. s1¢v2§~;¦z6©}:§{8ª~;ª~;ª~;¯‚;¯‡?µŒE¸C¹F¬‚7¯ƒ>±‚8·‰>¶ŠC¿–OšV¹L¼“N¿–PĞWÞUÀ—P¿—Q»•IÀ™Q¿—KšO»“F¾™NĝUÚRÁ˜N¾”J™O˜K¿’D™KĚNÁ™LØK¾“DÁ“IÕIŚMƚPŚQƜNȟSЩeЫfέkΪfÌ¥`Ê£`É¥eÅ¡c²”YzFkS#ZN#\P)XK%[O&_S.ynQ¸®’×εÖÏ·×иÙѼÛÓ¿ÜÔÂÜÔÁÝÕÃÝÕÃÜÔÁÜÔÂÝÕÃÛÓ¿ÝÕÂÜÔÀÚÒ¼ÝÕ¿ÝÕÀÜÔ¿ÝÕÀÛÓ¾›yŽ€j·©ÜÕÀÝÕÁàØÅß×ÅàÙÆáÙÆáÙÆáÙÈãÜÉâÚÇåÞÌäÝÌäÜÊäÜÉåÝËåÝÊçàÍåÞËæÝËæÞÌåÝËèáÐçàÍåÝÊèáÍçßÏçßÏåÝÍçßÏãÛËæßÏêâÒèáÑéâÒéáÑéâÒèáÑèàÎèáÎéâÏëãÐêãÐéâÐëäÔêâÓìåÕêãÓëäÕêâÓëåÕìæÕìæÖêãÓìåÕìåÖìåÔéâÏêäÒëåÓëäÒëåÒìäÒëæÖìåÖëåÕëäÑëåÓëäÖêãÔêäÔëäÕëäÔëãÓêäÔëäÔëäÔêãÓëåÒëåÓëåÒëäÒëäÒêâÏêâÍéàÍçáÐçÝÊæÝÇçÝÈéàÌìäÓíæ×ìäÑêâÐëâÑëáÏéßÎéßÎêßÎèÞÍéßÎèÞÍèÞÍéÞÍéÞÌæÜÌèÞÌèßÌèÝËæÝÉæÜÇçÝÉéàËçÞÉçÞÉçÞÈçÝÊæÜÈèßÉæÝÈèÞÍæÝÊåÜÇåÛÇåÛÇæÜÉæÜÉäÛÅæÜËçÝÊåÜÄåÜÆæÜÈæÝÈäÛÅãÚÅäÛÃâÙÂãÚÂâØÀåÛÄãÙÁäÛÃâØÀâØ¿áÙÀÝÔº×αÕˮʽ›Á¶·¨‚³œq°Žd´Š^§„K¬G¤{A£w9›m/›m2™k-šl/šm/£v8¢x6©}=¨}:ª;©}:¯‚<°ˆA·ŒJ¶ŒFµŒF°ˆA¨:§{8¬6¯…A¶ŒH´K¹M¶I¹K»”R¾šSŜV¿šT¿šV½™RÀœRÁT»–O¿šRÀœTUşWÈ¢ZÁ™MšOĝUÆ¡XÉ¡YÈ¢XěLśPÁ“H¾Aº@½“I³ŒD¹’IºGĚYÈ¢`ˤfÈ¥`ǞZȞXŤcÇ¥h³•Z‰tAfT#\M_Q$_R%^R%hX/‚xYúœÕ̳ØйÖжÚÒ¾ÜÔ¿ÛÓÀÜÔÂÝÕÆÜÔÂÝÕÂÛÓÀÞÖÄÝÕÂÝÕÁÝÕ¾ÝÕ¿ÜÔ¿ÜÔ¾ÞÖÀÝÖÀÞÖÀ‘‡q„uø§ÚÒ¾ÝÕÂàØÅÞ×Äß×ÄàØÅàØÆâÚÇâÚÇãÛÈãÜÉæÞËåÝÊäÜÉåÝÍåÝËåÝÊåÞÌåÝÌäÜÍçàÏçßÎæÞÏåÝÎçßÏéáÑçàÐçàÐåÞÍåÝÍèàÐèáÑèáÑçàÐëâÑéâÐéáÏêãÑçàÌéáÏéâÏèáÏèáÎéâÑêãÔêäÔêäÔëãÔìåÕéâÒìæ×ëåÔëäÔëåÕìåÔëåÓêãÐëäÒêãÑìåÒêãÑëåÓëåÓëãÑêãÑêãÑêäÓêâÒëäÔêãÔêãÔéâÒéáÐêäÔêäÔêãÒêãÔìæÕêäÓëåÒëäÑëäÒëãÑéàÎéàÏèàÍéßÎçÞÉæÝÇéàÎìäÓíåÔìäÓìäÓìâÔìäÔëâÒêàÏéßÍëáÐéàÐêàÐêàÏèÞÍèßÍéßÎéßÍçÝÍéáÐèÞÌçÝÌéßÍéßÏèßÍèÞÍéßÍéßÍëáÏèÞÍèÞÍéßÎéàÏêàÏéßÎéßÎéàÌæÜÉêàÍèÞÍçÝËèÞÍèßÌèÞÍçÞÉçÞÈæÝÇæÝÇãÚÃãÚÃåÜÆåÜÅäÛÃäÛÆåÜÄâÙÁâÙÁåÛÃáØ¿äÛÅâØÁßÖ½ÚÒ¸Óɮ˽žÃ±Žº«}²ŸyªŒ]£€I—uAzDœs8—o6q6œn/¢w9¡w8¤x9£y9£y:ªA°ˆC°‡E²ŠD´‹I­†Aª<¨€;¬‚A¯‡D¶N²‹K³‰H¬C±†I°ŠL¶‘Sº•P¼—S½šW¿›SžVÄ¡]Á\žZ¿œV¿šTÀœVÈ£\Ä¡X˨_ʧaʧ`̪cË©c˨_É¢YšO½‘F¼’G¸E¶B²ˆ<°†;³Š@¸•N™Sǟ\ĚXÀ›ZÇ£jÆ¥i¬‘S‹t:gV!dT'eR(cU(eZ-jY1‘†kÇ¿¤ØжÖ϶ÖÏ´ÙѼÛÓ¿ÛÓ¿ÜÔÀÝÕÂÝÕÂÛÓÁÛÓÀÜÔÁÝÕÃÞÖÃÝÕ¿ÜÔ¾ÜÔ¾ÝÕÀÜÔ¾ÜÕ¿ÝÕ¿€o’†rÍ®ÝÕ¿ÞÖÄß×ÄßØÅáÙÆß×ÅâÛÈãÚÉãÜÉäÜÊåÝÎãÛËäÜÉäÜËãÜËäÜÊäÜÍäÝÍäÝÊæÞÌäÜÊèàÎæßÏæÞÍæßÍçßÎèßÐçßÏçÞÏæßÏæßÏèàÐçßÐéâÒçàÐéâÑêãÑèáÎèàÏéâÏêãÑèáÎæßÌçßÏéâÑëäÔëãÓëåÕêâÓëäÔêäÔëåÕêãÓìåÕêãÒêãÒêãÒëäÓëåÕêãÓêãÒëäÓêãÑêãÓêãÑëåÒëäÑëäÑêãÓêãÒéâÏêâÒéâÒëäÔëåÕëåÕëåÕéâÓëåÒêãÑéâÐëäÒëãÑëâÏëâÏëâÏéßÌèàËèßÉèßÌìãÒíåÔíäÓìãÓìãÒìãÓìãÒëâÒìãÓëâÓêáÑêãÓêâÎêâÑéâÐëãÑèáÎêâÐéâÐéàÏéáÎéßÏêàÏêáÏéáÏêâÐéßÎêàÎèßÍèßÎêáÐëâÑëáÐéßÍêàÏêàÏéßÎêàÎéÞÍêàÏçÝÌêàÏèÞÍéßÌéàÍèßÍçÞÉçÞÉéàÊæÞÈåÜÆäÚÄáØÃâÙÃâÙÁãÚÁâÙÁãÚÂâÙÁåÜÅãÚÄãÚÁãÚÄãÚÄÞÕ¾ÚÑ·ÑÉ­Ðæĸ˜»®‰¯¥z©aŸ‡Z›{LŸwE§~I¦|D¡x=Ÿt6Ÿu9¡w9¤y:¨~>«>©|>­ƒC©€<©€;ª‚>µŒJ³K®‹I®‡D¬ƒC§A¤~=®‡D·M¸‘Mº“L´E¼™Q¿›UŸ\¿œU½šS¿›U¾›Sß[àXÆ¢Z̨b˨dʦ`ʧ_Ì©bÉ¢[ŝRÜQ¿—O¿™R¾—P¹H³‰@­ˆ@´ŽGµE¹’N¼“O¿œZÄ¢j£k«‘Xj3jVhS"gU,hW,fY/o\;¢˜~ÎÄ«ØзÖ϶ØкÚÒ¼ÝÕÀÝÕ¾ÜÔ¾ÜÔ¿ÜÔÀÜÔÀÜÔÀÜÔÀÜÔÂÜÕÀÞÖÁÛÓ¾ÛÓ¾ÞÖÁÜÔ¾ÝÕ¿ÜÔÀ‹|k™ŠwÒȶÜÔÀÝÕÁÞÖÄßØÅß×ÄáÙÆáÙÆâÛÉãÜÉãÛÉäÜÌãÛÊãÛÊåÞÎåÞÎäÜÌäÝÊäÝÊäÜÉåÝÊçßÍæÞËåÞËçßÌæÞÍçàÐçàÐèáÑæßÏæÞÎçßÏçßÏèáÑéáÓçàÐéâÑèáÎéâÏéáÍçàÎêâÐêâÐçÞÌçàËéâÏêãÒéâÓëäÔêãÓêãÓêãÓêãÔêãÓëäÔëäÔêäÔëåÕêãÓêãÔìæÖêäÕëåÕëåÕëåÕêâÑìæÔëäÒéãÐëäÔêâÒéâÑéâÒçàÍéâÑëäÔëäÔêãÔëäÔêãÐêãÐëâÒëâÐëâÐíåÑéàÊêâÍéáÌéàËçßÊêâÌìäÓìåÔìãÒìãÒíäÓíåÓëâÑëâÑëãÐìäÐìäÓìãÒëäÑëãÔëãÑêâÐéâÎëãÑêãÑêãÑéáÐèáÎêáÏëãÑêãÑèáÎêãÑéáÍæáÐéãÐéâÐëâÑêãÐéâÑêãÑêâÐéáÏêâÒêâÐçàÐéàÏêáÐéßÎéàÏêáÐêáÏêâÎéàËëãÍêáÎêâÌêáÌåÜÇäÛÅåÜÇåÜÆäÚÅäÛÄäÛÃåÛÆãÚÅåÜÅçÞÆèßÉèßÊçÝÈçÞÉâÙÅÞÔ¼ÞÓ¸ÓȪÏßƻ™¾´·¦±šqªZ¥ƒM zCzJ¤|H¦{@¥z?¤y=¦y?¢w<¥z<¨}@¦{?«C°ˆI°ŒQ¯ŠM®ƒE©ƒC¨F®‡I­‰Eµ‹L±ˆC°…?®ˆB³D¹’L»˜QÁ›X¿›ZÀœX¿›W¼šUÀžV `ß^Ä \Å¡YßYÇ£]ŜSƝUÁ˜OÁWşX¾•L½•Kº‘KµJ­ˆC´ŽH¾•PÁŸ]ÁŸdÁ£jª’Y€l1hSjV"q[0iV,m]0|jE´©ÔÌ°Ùϸ×зÚÒ»ØкÞÖÂÛÓ¿ÜÔ¿ÛÓÁÝÕÂÜÔÃÜÔ¾ÜÔ¿ÛÓ¿ÝÔÁÝÕ¿ÚÒ¼ÝÕ¿ÜÔ¿ß×ÃÜÔÁÜÔÁ‰|iž’}ÔɲÛÔÁß×ÅàØÅß×ÅÞ×ÂàÙÆãÛÈáÙÇâÚÇãÜÉãÛÊáÙÉãÛÊäÜÍåÝÍãÜÌäÝÊåÝÊåÞËãÛÊåÞÍåÝÊåÞËçßÌçàÍéáÐæßÎæÝÎåÞÎèàÐçßÏçßÏèáÑéáÒéâÑèáÑèâÓêáÏçàËéâÎèáÎéâÏèàÍéâÎéáÑéâÒéâÒèáÒêâÓëäÔëäÕëäÔêäÔéâÒéâÒèàÐêãÓêãÑêãÐëäÓìæÖëäÔëäÔëãÔêâÑëåÓìåÒêãÐëãÓêãÑêãÑéâÓéâÑéâÏêãÑêãÒêãÓêâÐéáÎêâÐëáÐêàÏêâÎéßÍêáÌéàËéáËéáËéàÊèàËíç×ìåÔíåÔíåÓìåÔìäÒëâÑêáÐêáÑëäÒëåÒëãÑêãÑëäÑëäÓëäÓêãÐéâÏéâÏêãÐèàÎèáÎêãÐêãÑêãÎéâÐéâÏéâÐéâÏèàÎêâÐêäÒêãÑêäÔèáÐéâÒéâÒéáÏêãÓèáÐéáÑéáÑêâÐëåÒëãÒêâÑëâÑêáÏëãÐëáÐëàÏêßÎèßËçÞÉçÞÉæÝÇäÛÆäÛÅãÚÅåÜÆäÛÅæÝÇçÞÉçÞÉçÝÈèßÍèßÊèàÊçÞÉçÜÈäÚÅäÛÃâÙÁÜÓ»ÚгÏũȺ’ñ„¾¦}¨˜pªc£„Q£N§€M¤}L¨~I£zA©D¦}E§~G©€E¦~G¬…N²ŠM¬†H®…L´ŠW±‹K³ŠI®ˆC©ƒ=ª€8¥y3¯„B®ˆF´ŒI¸•U¹•RµK¶ŠG´‹G¹’U»•UÀ›Z½˜VžYŸYÆ Z½šU¹”O¿–O½™PĜRÚQ¼”J¶‘L³ŒG¶M¼˜X¿ aÄ e»žfœ‡M{c'lY"iY%l\.q_6p`5‹}\Ä»¢ÕÏ´ØθÙÒºÙÒºØкÛÓ¾ÜÔ¾ÝÕÀÝÕÂÜÔÁÜÔÁÚÒ¾ÚÒ¼ÚÒÀÞÖÃÜÔÂÜÔ¿ÝÕÁÝÕÁÜÔÀÝÕÀÜÔ¿Š}kª Ö̶ÜÔ¿ÝÕÁÞ×Äß×ÅàØÄáØÆâÚÇãÛÈãÜËâÛÊãÜËãÚËãÛÌäÜÊåÞÎãÛËäÝËäÜÉåÝÊåÝËáÚÇçßÌäÜÉåÞËçßÌçßÍäÝÍåÝÍçßÏæßÏçßÏéáÑçáÑèßÏèàÍéáÏçàÍéâÏçßÍèáÎèáÎéâÏèáÎéâÒéáÑèáÑêäÔêãÔéâÓëåÔéáÐìåÕëåÕëäÔéáÏëãÑêãÐêãÑëåÒëåÒìæÓêãÑêãÑéâÐêãÒëäÕêâÐêãÑêãÐéáÏèáÎèàÎêâÐèßÍéâÏéâÐéáÐêáÐéàÎêáÐêáÏçÝÌèßËéàËèßÊçÞÉæÝÇåÜÆçÞÉëãÏíæÕíçÖìäÓìæÔëãÒëäÕëãÓêáÒèßÏéãÒëäÕéáÑéâÒëåÕëåÔëäÔêãÐëäÒéâÐèáÎêãÐéâÏéâÐêâÐçàÎéâÏêâÑèáÐçàÍèàÎêãÒìåÔëäÔéâÑìåÔëäÓêãÒéâÑèáÐéâÑêâÒéâÑéâÐëäÒëåÕêãÑëãÑêâÑëâÒìãÒêáÐéáËêáÐçÞÍæÝÉæÝÊçÝÊèÞÌæÛÊãØÅæÜÊåÜÇåÜÆæÝÇçÞÈèßÉéàËèßÉéàÊçÞÉåÜÇåÜÃçÞÈäÛÃãÚÂåÜÄãÚÂßÖ»ØϵÑƪÊÁ¤À±‘¼©‰²œuª‘i¤bž„X§†L¬‰W©„M¥}D¤~H¦H®ˆN©‚G©F¬†K³M¶Q´O¯ŠG­„@§{:£y9¢z8ªƒ>°ŒJ³N¯K¯‰G­ˆH´‘Pº–V¼—W¼–W»–VŸ^Á]º•Q±ŽL°ŠB¶“OÀ›RœXº–P³L¶P·•TÀžeÀ¡d¿ f·œg™…Osa+jZ(m\/l[-m\1xi=¢•vÏÅ©×ζÚк×Ï·ÚÓ»ÜÔ¿ÝÕ¿ÙѽÞÖÃÝÕÂÜÔ¿ÛÓÀÛÓÀÛÓÀÜÔÀÜÔÀÛÓ½ÝÕÀß×ÁÝÕÀÜÔ¿ÛÓ¿ÝÕÁ‡|k´©—ÙѽÜÔÁÝÕÄáÙÆâÚÈàØÆâÛÈàØÅãÛÉâÚÇãÛËäÜÌãÜÌáÙÉãÜËåÜÌäÝÎäÛÌåÝÍäÜÊæÝËäÝÊåÝËäÜÊæßÌæßÌæÞÌãÝÏåÞÎæÞÏèáÏçßÏèàÐçàÐéáÎçßÍçàÍéâÏèàÍèàÎèáÎëãÑèáÎçàÎéâÐèâÐêãÓêâÑèáÍêâÒêâÑêãÑêãÐëäÒêäÑéáÏéãÐèâÏëäÑéâÏéâÏéáÏêâÎéáÏëãÐéáÐêáÏëãÑêâÐêâÏéáÎçßÍèàÎèßÌèàÎèàÎéâÐèáÎéßÎçÞÍçÝËéßÎèÝËèÞÌåÝÇæÝÇâÚÄäÛÆåÜÇäÛÅèàÉìæÔíæÕìäÒëåÓëäÒëåÓêãÔéâÐëäÑêäÑëãÑéâÏëåÒëäÒëåÒëäÑëåÒëäÕêãÓêâÒéáÒéáÑéâÐçàÍèàÏèàÑéâÐéâÒêãÑéáÒêãÓëãÔëäÖêãÔéãÓëäÔéáÒêâÓêâÒéãÓêãÓêâÒéâÓêãÓëäÒëäÑêãÐêäÑëäÔêâÑëâÑêáÏèÞÌéÞÍçÝÌèÞÌçÝËèÞÌéÞÍæÜËçÝËæÛËæÜËæÜËæÜËéáÌèÞËèàËéàËçÞÉæÝÈæÝÆäÛÆäÛÅäÛÂåÜÃäÛÃäÛÅäÜÆãÚÃâÙÃßÖ½ÙϹÎŪǽ ½±—º«Š¯žv®›p¥_¨‹`¢‚S¨N«ˆN¬…N«„O®‰N±PµV¶“X·’T¶P¯‡I¥|?¥}>¨>ªƒG¯ˆP±‹R²ŽP±P¶’W½š[º—V·•Tº“U¹•T»˜V¹•Q¬‰H®ŠG´‘P¼—Yº•V·ŽL°‹I°ŠI´‘P¹™[¼a³—]¯•\—Jo`.hY*m\1p_3sc:†xP»±Ž×αÛѸÚѸ×ϸÚÓ»ÛÓ¾ÜÔ¿ÝÕÀÝÕÁÝÕÂÚÒÁÝÔ¿ÚÒ¾ÜÕÀÛÓÁÝÕÁÛÓÁÜÔÀÜÔÁß×ÄÜÔÀÞÖÂÝÕŠ|eÁ¸ØÓ¾ÜÔÁÝÕÃÝÕÃÞÖÃáÙÉáØÆáÙÆâÚÇáÙÆàØÈâÚÊáÚÊãÛËãÜËãÜËäÝÍæÞÍäÝËåÝÊæÞËåÝÊåÝÊåÞËåÜÊæßÌåÝÊåÞÌåÞÎãÛËèáÑçßÐçßÏäÜËçàÎèàÎçàÍèàÎçßÍèáÎèáÎçßÍéáÏçßÌèáÎêâÐéâÏçàÎèáÎèáÏéáÐèáÎéâÏéâÒìãÒèáÏéáÏèàÍêâÐéâÐèàÎéâÎéáÎçÞÌëáÐêáÐéàÎéàÎêáÐèßÎèÞÍèÝÌèßÎçÝËåÚÉèÞÍæÜÊçÜËæÜËæÛÊåÛÉåÚÉåÛÊãÚÆäÛÆãÙÅàÖÂà×ÂßÔÁâØÄéßÍíæÖíæÖíäÓëäÑêãÐêäÑêâÐéâÏéâÏêãÐêãÐêâÐëäÑëãÑêãÐëãÑêâÏêâÐéáÏêâÏéáÏéáÎçßÍéáÐèáÍèáÐêãÔçáÒéâÑëãÔéáÒêâÒêãÖëäÕêãÔêãÓêãÓéâÓëäÔêãÔéáÒéáÒéâÒëãÔéâÓëäÔëåÓëãÑëâÑìäÕìãÓêáÐéàÏçÝÌêàÏèßÎèÞÍèßÍçÝËæÛÊæÜËäÛÉèÞÌçÝËéàÍéÞÍéàÊéàËéáËæÝÈæÝÇæÝÈäÛÆåÜÄãÚÃäÛÆåÜÇåÜÇåÜÇäÛÅäÛÆæÝÅåÜÇåÛÆäÛÅáØÃÚÑ·ÓʯËÁ¤É¼½¬‡¸¡z¹¡y¬˜n¬”i±’h®Œ[­ŠU²ŽV·“Zº—_¹•`´X¬‡P«†N«…Q­‡R§J­†Q³TµW¹”\º–X»—Y¸–V¶“S¸•T²N´‘O°K±ŒK®‹K±M±L²L¦ƒB©ˆG¬ŒQ±”]´™c­’_§WŽyAp`0k]-k\0m^2vg>¢“oÍæÙϵÛÒ¹ÜÒºÙÓºÙÒ»ÜÔ¼ÝÕ½ÛÓ¾ÛÓ½ÜÔ¾ÝÕ¿ÜÔ¾ÙѽÚÒ¾ÜÔ¿ÛÓ¿ÚÒ¿ÛÓÀÝÕÂÞÖÃÞÖÄÜÔÃÝÕē…qɾ¦ÚÔÀÛÒ½ÝÕÂß×Åß×Äß×ÄàØÅàØÅâÛÇáÙÆáÚÇß×ÅãÛËâÛËâÚÇãÛËäÜÌçßÎåÝÊãÚÈæÞËâÛÈãÜÈäÛÉåÝÊäÜÊæÞÌâÚÈãÜÊåÝËæßÍèàÎäÝÊãÜÉæÞËèàÍæÞËåÝËèàÎçßÌçàÍèßÍçßÍèàÑèàÌçàÐéáÎçßÍçàÍçßÌçßËçßÍçßÍéáÎæßÌèáÎçßÍèàÎéáÎçßÍçßÍçßÍæÝËçÝËæÜÊèßËæÜÈèßÌçÞÉçÝÉèÞËæÛÉæÜÊãØÇãÚÅæÛÊåÚÉçÜÍæÛËåÚÉäÙÈåÚÉåÚÉåÜÆäÛÅáØÃâÙÃà×ÁßÔÃßÔÂçßËìäÔëäÓëãÒëäÒêâÐéáÏéáÎéáÏêãÐèáÏèáÏéâÐêãÑêâÑéáÏèáÏéáÏèàÎèáÎéáÏèáÐçßÍèáÑêãÓêâÓëãÓêãÔèâÓëäÔêãÓèáÑéãÓëäÔêãÓêãÓêäÔëãÔëäÔéâÒëåÕêäÔêâÓêãÒçàÏçáÑêãÓëåÔëåÔéâÑëäÔëäÒéáÏêâÐçßÌçÞÌéáÏèàÎçÞÌçÜÌåÚÉçÝËæÜÊèÞÌêàÍèàËèßÏèßÍéàÊéàËèßÉéàËäÛÆæÝÈåÜÇäÛÆäÛÆãØÇãØÇåÚÈãÙÇäÚÉâÙÅäÛÅäÛÄæÝÈåÛÅåÜÅäÚÃâÙÀàÖ¿ÛÒ·ÚѸÑƪÍæɿ Æ¹”ñ·¢v·¢w®—l²˜n±”e®‘a³‘_°Z²\¯ŒY¯‹V­ŠT®ŠT±V´W·“Y¶‘V²ŽR²ŽR±ŽO¯ŒN­ŠJ®ŒO±ŽN¬‹N«ˆI¤€=¦‚>¡?¡„E¦‰N¨ŒV¨[ ‰Tœ‡Rˆq8o^+l^.qb4ue<…yQ¹°Ô̱ÛÒ¹Ù϶ÙÑ·ÚÓ¹ÙѼÚÒ»ÛÓ½ÛÓ½ÜÔ¾ÜÔ½ÚÒ¿ÜÔ¿ÛÓ½ÚÒ½ÜÔÀÜÔÁÜÔÂÛÓ¿ÜÔÁÜÔÁÜÔÂÞÖÄÜÒېzÒÈ´ÜÓÂÜÕÁÞÖÃÝÕÃÞÖÄàØÅß×Äß×ÅàØÆãÛÉàØÅáÙÆáÙÆàØÆãÚÇß×ÅâÚÈäÜÉâÚÈäÜÉäÝËâÚÈäÜÊãÛÈãÛÈåÞÊáÙÇãÛÈãÛÉâÛÈäÜÊæßÌäÜÊæÞËâÛÈåÝÊæÞÌèáÎçßÍäÜÊæÞËçàÍåÝËæÞËåÞÌåÝËäÝÊåÞËæÞËåÝÉåÜÉçÝËæÝÌçßÌèÞÍçÜËæÛÊæÜËçÝËåÛÊæÝÇäÛÅãÚÄãÙÄãÚÅâÙÃäÛÆäÚÇåÝÇäÛÆåÜÆæÝÉåÚÉåÛÊãÙÈãØÆæÛÊãÙÇåÚÉåÛÉåÛÉçÞÌåÜÇäÛÆåÜÇäÛÅáØÃÝÔ¿ÝÒÁá×ÄåÝËìæÕìæÓìâÑèáÎéâÏéâÐèàÎèàÍèàÎèàÎèßÍçàÎçßÌêãÐçàÎèàÎèàÎéâÏèàÎæßÌêâÐèàÎèàÏéâÒêãÓêäÓêâÒëäÔëäÕéâÒèàÐéâÑêãÔêâÔèãÕêãÓêäÔêäÔêãÓêãÔêãÓêãÓèàÐêãÔéàÑëåÕêäÔëäÕëåÕéâÒêâÒêâÐéâÐçàÑçàÎéáÑèàÏæßÍåÜÊêßÎèàÎåÜÊéÞÍéßÎéßÎêáÐêàÎêàÏêàÎèßÌèßÌçÞÉèßËçÝÉæÝÈãÙÈäÙÈäÙÈãÙÇãÙÇäÙÈåÚÉãØÇãÙÅåÜÆâÙÄäÛÆâÙÄãÚÆçÞÈåÜÇäÛÂçÞÆæÝÅäÛÃÝÓ¹ÛÒºÔɪÌÚɽšÀ°†¹¨|´¤±œu«•k¨Ž`¬bªZ¯X²Z°Y­ŒT±ŽU¬‡N«ˆM¬‰Q¯ŒRª‡I¨„H¬ŠQ¯P¯S©ˆE£>¢{<Ÿz;£C£†L¥‰T ‡Y¡‰Zœ†V€h1m])l]-qd;xh>£˜rÈ ×βÚÑ·ÙзØÒ¸ÙÓºÜÔ¾ÜÔ¾ÛÓ½ÝÕ¿ÞÖÄÛÓ¾ÞÖÀÞÖÃÜÔÀÜÔÂÚÒ¿ÜÔÁÛÓÀÜÔÁÛÓÁÜÔÀÞÖÃÚÒ¿ÛÓ¿­¡†ÖεÜÔÁÝÕÂÜÔÁß×ÄàØÇÞ×ÄßÖÄß×ÅáÙÇàÙÆáÙÇß×Äß×ÇàØÆáÙÇâÚÈâÛÊãÛÈãÛÈâÚÇâÚÉâÛÈâÛÇãÛÉáÙÇãÛÉâÚÇáØÅãÜÉâÚÇãÛÉãÛÈâÛÈáÚÇæÜÊãÚÈæÝËåÜÊåÝËåÝÊäÜÉåÝËäÝÊãÜÉåÝÊäÜÉäÜÊåÝÊåÞÉãÛÇàÖÅåÚÈäÙÈæÜÊåÚÈäÚÉãÚÈåÛÉäÚÉäÙÈâØÇâØÆãØÇâØÆãØÈãØÇãØÇâØÄåÜÇâÙÄâÙÃáØÃãÚÆäÚÇåÛÈâØÆäÚÉäÚÉæÛÊåÚÉäÚÈåÛÉäÚÉæÜÊäÛÆâÙÄßÕÃßÔÁÜÒÁÝÓÁçÝÍíåÖëåÓìäÒêãÓéâÑçàÏçàÏçßÍèàÎçàÍçßÌæÞÌåÞËæàÍçàÍçàÍæÞÌæÞËçàÍèàÎèàÍèáÎçàÎéáÏèáÐêâÐêäÔêãÓìåÕêãÓèáÑêãÓéáÓêâÔêâÒèáÒëäÕéáÑëäÔêâÓëäÔêãÔéâÒéâÒéáÒéáÒëäÔëåÕêãÓëäÔêãÓêãÓèáÒèáÐèàÑèàÐèßÎåÞÌæßÌåÞËèßÌèßÍçÞÌçÝÌêàÏêàÏêàÎèßÍêàÏêàÏèÝÌéßÍæÜËèÞÍåÚÉçÜËæÛÊãÙÇäÚÉåÛÉãÙÈâØÆãÙÈâØÆâØÅâÙÄáØÂâÙÃãÚÄäÛÃãÚÃãÚÃåÜÆåÜÄæÝÅæÝÅåÜÄãÚÂáØ¿ßÕ½ÙжÓÉ°Í¥;Â¶”¹¬²¡|«˜n©‘d¯”j¯”f©_ª\¨ˆT§ˆR«ŠX®S©ˆL§ƒK­ŒQ³’T°W¬ŽQ©ˆK§†M ~D£„J¡…M¢‰R£^‡Y”Qi9o_-pe7reC•‰hĺœØѶÙѹØÓ¸ÚÔ¹ÛÓ»ÚÒ¼ÝÕ¿ÝÕ¿ÜÔ¾ÜÔ¾ÛÓÁÝÕÁÛÓÀÞÖÁÚÒÀÛÓÀÚÒÀÝÕÂÛÓÁÜÔÂÛÔÀÚÓÂÜÔÄÛÓÁØн¾¯“Ù϶ÞÖÃÝÖÂÞÖÄÝÕÃÜÔÁÞÖÄß×ÅàØÅàØÅàØÆâÙÆáÙÆàÙÆâÛÈâÚÈãÛËâÚÉâÛÊáÙÉáÙÉâÚÊâÚÈàØÆáÙÉâÚÇáÙÆß×ÄáÙÇâÚÇàÙÆáÙÇâØÇãÙÈäÚÈæÛÊåÚÉåÚÉãÚÆâÚÇâÛÈãÛÊãÛÊâÚÈâÚÈÞÖÅâÛÊâÚÈâÛÈáÙÆáÙÆà×ÅãØÇáÖÅãÙÆáØÅäÙÈãÙÊáÖÆá×Æá×ÆäÙÈâ×ÆâØÇâÙÄäÚÅãÚÆàÖÃâÙÅá×ÃáØÃãÚÄäÛÅãÚÄäÛÅäÛÅåÛÊæÜËçÜËçÜËæÜËéÞÍæÛÉæÛËåÛÊæÛÉâÙÅá×ÃßÕÁÝÒÁßÕÄæÝÌìäÕëåÔêäÑêãÒçßÏçàÍçàÎèàÍåÝËæßÌæßÌæßÌäÝÊåÞËçàÍçßÌåÝËæßÍæßÌêâÐéâÏèàÎèáÏèàÑèáÑêâÓéâÒëäÕéâÒéáÒéáÐëäÔêãÓêãÓëäÔëãÔêãÔéâÒéâÒéáÑéâÒéâÑêãÔéâÒêãÓêãÓêãÔìæÖëãÔëåÕêâÓêãÓéãÓéáÒèáÑçàÐèàÐçßÏåÞÎçßÎèàÏåÝËæÝÌêÞÍéßÎêáÏêáÐêàÏéßÎéßÎèßÍéÞÍçÝÌçÝÌçÝËæÛÊæÜÊäÙÈåÜÊãØÇãÙÈåÛÉäÚÈåÛÇäÙÈäÙÈâÙÃãÙÄâØÃãÚÅãÚÅáØÃâØÃâÙÄâÙÄãÚÂäÛÃæÝÇãÚÄâÙÁà×ÁáÙÄà×¾ÞÕ¹ÜÒº×δÎŦɺŸ½±”¾±”·¦¯žw­—o§f¦‹]¢‡Y¨ŒZ©ŠVªŠU¨‰O©‹P¯Y©‹T¨ˆO¦‡P¢ƒI€K›~K¢…S¢‰Yž†[“~Nwf7o_4rf>†z]¶ªÓɯØÒ¹ÙÒ¹ÛÔºÛÓ»ÜÔ½ÛÔ¼ÜÔ¿ÜÔ¾ÝÕ¿ÝÕ¿ß×ÁÜÔÃÜÔ¿ÚÒ¼ÛÓ¾ÛÓÀÙѾÝÕÂÛÓ¿ÝÖÅÛÕÄÛÔÄÛÓÀÙÑ¿ÝÕÄÊÁ§ÚÒºÛÓÀÝÕÂÞÖÃÝÕÂÞÖÄß×ÄÝÕÃÞ×Äß×ÄàØÅß×ÅàØÅáØÆß×ÅàÙÆàØÇàÙÇãÛÉáÙÇâÛÉáÚÇáÙÆáÙÆáÙÇàØÅß×ÄÞÖÃÞÖÂáØÅâ×ÅáÖÄáÖÅàÕÃá×ÄáÖÅáØÂâÙÅâØÅâØÆß×ÅàØÆàØÅâÚÇàØÆàØÅàØÆàØÆàØÅàÙÅâÚÈáØÆàÖÄâØÆãØÇáÖÅáÖÄáÖÅàÖÃßÔÃâØÅâ×ÅäÚÈãØÇãÙÅãÙÅãÚÄãÚÆâØÅâØÄãÙÄãÚÄâÙÂäÛÆåÜÈæÝÉæÜÈäÚÉåÛÉæÜÊæÜÊçÝËçÝËæÛÊæÜÊäÚÉäÛÅãÚÆà×ÃÝÔÂÝÕÄæßÍëåÕëäÔëåÒéáÒéáÑçßÏçßÍãÛÊæßÌåÝÊæßÍåÝËåÞËäÝÊåÝËæÞËæÞËæßÏæàÎèàÎèáÐèáÐéáÑçßÏèàÐéáÑèàÐèàÐéâÒéâÒêâÓêãÓëäÔëäÔëãÕêäÕêäÔêãÓêãÔéáÒéâÑéâÒèáÑæÞÎéâÒèàÑêâÒëåÔëäÔêãÓêãÔéâÒéâÒéáÑèàÑèáÑèáÑçàÐçßÏæßÏéáÑçàÎèáÏèàÏêàÏéàÎêàÎëâÑéàÎêàÏéßÍçÝÌçÞÌåÞËæÝËäÜÊäÜÉåÝÊäÜÊâÛÈâÚÈäÙÈäÚÉæÜËåÛÉãÚÄãÙÄãÚÅâÙÃáØÃáØÂáØÃáØÂâÙÃãÚÅâÙÃâÙÁà×Àà×ÂàÖÁâØÃà×ÁáØÂá×Âà×ÁßÖ¿ÝÕ¼ÛÒ¹ÛÒ¹ØεÒäͼ–ĵ˜Ã²–¹¨ˆ±¢€µ£}¬˜q¦‘e¡ˆYŸ„W ‡XžƒN¡…PLš}Iš|J™~Nž…U–L”~M‡qIwe9rf=ˆzV¬¦ŠÍÄ­ÙѸÙÒ¹ÙѼÚÒ»ÛÓ¾ÚÒ¼ÞÖÀÜÔÀÞÖÁÝÕÃÝÕ¿ÛÓ¾ÞÖÀÛÓ½ÜÔ¿ÛÓÀÚÒ¾ÙѼÚÒ¿ÛÒ¾ØÒÃÙÒÃÜÕÅÜÔÃÝÕÅÜÔ \ No newline at end of file diff --git a/ffmpeg/tests/tiny_psnr.c b/ffmpeg/tests/tiny_psnr.c index 6da177a..b35ed81 100644 --- a/ffmpeg/tests/tiny_psnr.c +++ b/ffmpeg/tests/tiny_psnr.c @@ -180,8 +180,7 @@ static int run_psnr(FILE *f[2], int len, int shift, int skip_bytes) 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); diff --git a/ffmpeg/tests/utils.c b/ffmpeg/tests/utils.c index e8ef06f..dde6e03 100644 --- a/ffmpeg/tests/utils.c +++ b/ffmpeg/tests/utils.c @@ -35,12 +35,12 @@ } 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; @@ -104,7 +104,7 @@ static void rgb24_to_yuv420p(unsigned char *lum, unsigned char *cb, #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; diff --git a/ffmpeg/tools/crypto_bench.c b/ffmpeg/tools/crypto_bench.c index 0f62068..6037ead 100644 --- a/ffmpeg/tools/crypto_bench.c +++ b/ffmpeg/tools/crypto_bench.c @@ -75,6 +75,7 @@ struct hash_impl { #include "libavutil/sha512.h" #include "libavutil/ripemd.h" #include "libavutil/aes.h" +#include "libavutil/cast5.h" #define IMPL_USE_lavu IMPL_USE @@ -111,6 +112,16 @@ static void run_lavu_aes128(uint8_t *output, 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 ***************************************************************************/ @@ -121,6 +132,7 @@ static void run_lavu_aes128(uint8_t *output, #include #include #include +#include #define DEFINE_CRYPTO_WRAPPER(suffix, function) \ static void run_crypto_ ## suffix(uint8_t *output, \ @@ -147,6 +159,17 @@ static void run_crypto_aes128(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 */ @@ -183,6 +206,16 @@ static void run_gcrypt_aes128(uint8_t *output, 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 */ @@ -224,6 +257,17 @@ static void run_tomcrypt_aes128(uint8_t *output, 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 */ @@ -306,6 +350,7 @@ struct hash_impl implementations[] = { "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) diff --git a/ffmpeg/tools/ffhash.c b/ffmpeg/tools/ffhash.c index a9f71c2..6942527 100644 --- a/ffmpeg/tools/ffhash.c +++ b/ffmpeg/tools/ffhash.c @@ -94,9 +94,10 @@ static int check(char *file) 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) diff --git a/ffmpeg/tools/ismindex.c b/ffmpeg/tools/ismindex.c index d66a389..3e53046 100644 --- a/ffmpeg/tools/ismindex.c +++ b/ffmpeg/tools/ismindex.c @@ -50,6 +50,7 @@ #include "cmdutils.h" #include "libavformat/avformat.h" +#include "libavformat/isom.h" #include "libavformat/os_support.h" #include "libavutil/intreadwrite.h" #include "libavutil/mathematics.h" @@ -226,6 +227,94 @@ fail: 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; @@ -254,6 +343,8 @@ static int read_tfra(struct Tracks *tracks, int start_index, AVIOContext *f) 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); @@ -272,9 +363,41 @@ static int read_tfra(struct Tracks *tracks, int start_index, AVIOContext *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: @@ -526,6 +649,7 @@ static void print_track_chunks(FILE *out, struct Tracks *tracks, int main, const char *type) { int i, j; + int64_t pos = 0; struct Track *track = tracks->tracks[main]; int should_print_time_mismatch = 1; @@ -545,8 +669,14 @@ static void print_track_chunks(FILE *out, struct Tracks *tracks, int main, } } } - fprintf(out, "\t\t\n", + fprintf(out, "\t\toffsets[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"); } } diff --git a/ffmpeg/tools/sidxindex.c b/ffmpeg/tools/sidxindex.c new file mode 100644 index 0000000..202d2f0 --- /dev/null +++ b/ffmpeg/tools/sidxindex.c @@ -0,0 +1,411 @@ +/* + * 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 +#include + +#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, "\n"); + fprintf(out, "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\n"); + + + for (set = 0; set < nb_sets; set++) { + if (nb_tracks[set] == 0) + continue; + fprintf(out, "\t\t\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\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\tname, 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\n", channels); + fprintf(out, "\t\t\t\t%s\n", first_track->name); + fprintf(out, "\t\t\t\t\n", first_track->sidx_start, first_track->sidx_start + first_track->sidx_length - 1); + fprintf(out, "\t\t\t\n"); + i = j; + } + fprintf(out, "\t\t\n"); + } + fprintf(out, "\t\n"); + fprintf(out, "\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; +} diff --git a/scripts/ffmpeg-config b/scripts/ffmpeg-config index b98d545..bcac715 100755 --- a/scripts/ffmpeg-config +++ b/scripts/ffmpeg-config @@ -6,10 +6,10 @@ BUILD="$(pwd)" 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